@tscircuit/3d-viewer 0.0.596 → 0.0.598

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 +2509 -461
  2. package/package.json +2 -2
package/dist/index.js CHANGED
@@ -284,29 +284,29 @@ var require_fromRotation = __commonJS({
284
284
  var { sin, cos } = require_trigonometry();
285
285
  var identity = require_identity();
286
286
  var fromRotation = (out, rad, axis) => {
287
- let [x, y, z21] = axis;
288
- const lengthSquared = x * x + y * y + z21 * z21;
287
+ let [x, y, z22] = axis;
288
+ const lengthSquared = x * x + y * y + z22 * z22;
289
289
  if (Math.abs(lengthSquared) < EPS) {
290
290
  return identity(out);
291
291
  }
292
292
  const len = 1 / Math.sqrt(lengthSquared);
293
293
  x *= len;
294
294
  y *= len;
295
- z21 *= len;
295
+ z22 *= len;
296
296
  const s = sin(rad);
297
297
  const c = cos(rad);
298
298
  const t = 1 - c;
299
299
  out[0] = x * x * t + c;
300
- out[1] = y * x * t + z21 * s;
301
- out[2] = z21 * x * t - y * s;
300
+ out[1] = y * x * t + z22 * s;
301
+ out[2] = z22 * x * t - y * s;
302
302
  out[3] = 0;
303
- out[4] = x * y * t - z21 * s;
303
+ out[4] = x * y * t - z22 * s;
304
304
  out[5] = y * y * t + c;
305
- out[6] = z21 * y * t + x * s;
305
+ out[6] = z22 * y * t + x * s;
306
306
  out[7] = 0;
307
- out[8] = x * z21 * t + y * s;
308
- out[9] = y * z21 * t - x * s;
309
- out[10] = z21 * z21 * t + c;
307
+ out[8] = x * z22 * t + y * s;
308
+ out[9] = y * z22 * t - x * s;
309
+ out[10] = z22 * z22 * t + c;
310
310
  out[11] = 0;
311
311
  out[12] = 0;
312
312
  out[13] = 0;
@@ -557,13 +557,13 @@ var require_cross = __commonJS({
557
557
  var require_distance = __commonJS({
558
558
  "node_modules/@jscad/modeling/src/maths/vec3/distance.js"(exports, module) {
559
559
  "use strict";
560
- var distance5 = (a, b) => {
560
+ var distance6 = (a, b) => {
561
561
  const x = b[0] - a[0];
562
562
  const y = b[1] - a[1];
563
- const z21 = b[2] - a[2];
564
- return Math.sqrt(x * x + y * y + z21 * z21);
563
+ const z22 = b[2] - a[2];
564
+ return Math.sqrt(x * x + y * y + z22 * z22);
565
565
  };
566
- module.exports = distance5;
566
+ module.exports = distance6;
567
567
  }
568
568
  });
569
569
 
@@ -609,11 +609,11 @@ var require_fromValues2 = __commonJS({
609
609
  "node_modules/@jscad/modeling/src/maths/vec3/fromValues.js"(exports, module) {
610
610
  "use strict";
611
611
  var create = require_create2();
612
- var fromValues = (x, y, z21) => {
612
+ var fromValues = (x, y, z22) => {
613
613
  const out = create();
614
614
  out[0] = x;
615
615
  out[1] = y;
616
- out[2] = z21;
616
+ out[2] = z22;
617
617
  return out;
618
618
  };
619
619
  module.exports = fromValues;
@@ -624,10 +624,10 @@ var require_fromValues2 = __commonJS({
624
624
  var require_fromVec2 = __commonJS({
625
625
  "node_modules/@jscad/modeling/src/maths/vec3/fromVec2.js"(exports, module) {
626
626
  "use strict";
627
- var fromVector2 = (out, vector, z21 = 0) => {
627
+ var fromVector2 = (out, vector, z22 = 0) => {
628
628
  out[0] = vector[0];
629
629
  out[1] = vector[1];
630
- out[2] = z21;
630
+ out[2] = z22;
631
631
  return out;
632
632
  };
633
633
  module.exports = fromVector2;
@@ -641,8 +641,8 @@ var require_length = __commonJS({
641
641
  var length64 = (vector) => {
642
642
  const x = vector[0];
643
643
  const y = vector[1];
644
- const z21 = vector[2];
645
- return Math.sqrt(x * x + y * y + z21 * z21);
644
+ const z22 = vector[2];
645
+ return Math.sqrt(x * x + y * y + z22 * z22);
646
646
  };
647
647
  module.exports = length64;
648
648
  }
@@ -725,14 +725,14 @@ var require_normalize = __commonJS({
725
725
  var normalize = (out, vector) => {
726
726
  const x = vector[0];
727
727
  const y = vector[1];
728
- const z21 = vector[2];
729
- let len = x * x + y * y + z21 * z21;
728
+ const z22 = vector[2];
729
+ let len = x * x + y * y + z22 * z22;
730
730
  if (len > 0) {
731
731
  len = 1 / Math.sqrt(len);
732
732
  }
733
733
  out[0] = x * len;
734
734
  out[1] = y * len;
735
- out[2] = z21 * len;
735
+ out[2] = z22 * len;
736
736
  return out;
737
737
  };
738
738
  module.exports = normalize;
@@ -856,8 +856,8 @@ var require_squaredDistance = __commonJS({
856
856
  var squaredDistance = (a, b) => {
857
857
  const x = b[0] - a[0];
858
858
  const y = b[1] - a[1];
859
- const z21 = b[2] - a[2];
860
- return x * x + y * y + z21 * z21;
859
+ const z22 = b[2] - a[2];
860
+ return x * x + y * y + z22 * z22;
861
861
  };
862
862
  module.exports = squaredDistance;
863
863
  }
@@ -870,8 +870,8 @@ var require_squaredLength = __commonJS({
870
870
  var squaredLength = (vector) => {
871
871
  const x = vector[0];
872
872
  const y = vector[1];
873
- const z21 = vector[2];
874
- return x * x + y * y + z21 * z21;
873
+ const z22 = vector[2];
874
+ return x * x + y * y + z22 * z22;
875
875
  };
876
876
  module.exports = squaredLength;
877
877
  }
@@ -907,12 +907,12 @@ var require_transform = __commonJS({
907
907
  var transform = (out, vector, matrix) => {
908
908
  const x = vector[0];
909
909
  const y = vector[1];
910
- const z21 = vector[2];
911
- let w = matrix[3] * x + matrix[7] * y + matrix[11] * z21 + matrix[15];
910
+ const z22 = vector[2];
911
+ let w = matrix[3] * x + matrix[7] * y + matrix[11] * z22 + matrix[15];
912
912
  w = w || 1;
913
- out[0] = (matrix[0] * x + matrix[4] * y + matrix[8] * z21 + matrix[12]) / w;
914
- out[1] = (matrix[1] * x + matrix[5] * y + matrix[9] * z21 + matrix[13]) / w;
915
- out[2] = (matrix[2] * x + matrix[6] * y + matrix[10] * z21 + matrix[14]) / w;
913
+ out[0] = (matrix[0] * x + matrix[4] * y + matrix[8] * z22 + matrix[12]) / w;
914
+ out[1] = (matrix[1] * x + matrix[5] * y + matrix[9] * z22 + matrix[13]) / w;
915
+ out[2] = (matrix[2] * x + matrix[6] * y + matrix[10] * z22 + matrix[14]) / w;
916
916
  return out;
917
917
  };
918
918
  module.exports = transform;
@@ -1114,8 +1114,8 @@ var require_isMirroring = __commonJS({
1114
1114
  var isMirroring = (matrix) => {
1115
1115
  const x = matrix[4] * matrix[9] - matrix[8] * matrix[5];
1116
1116
  const y = matrix[8] * matrix[1] - matrix[0] * matrix[9];
1117
- const z21 = matrix[0] * matrix[5] - matrix[4] * matrix[1];
1118
- const d = x * matrix[2] + y * matrix[6] + z21 * matrix[10];
1117
+ const z22 = matrix[0] * matrix[5] - matrix[4] * matrix[1];
1118
+ const d = x * matrix[2] + y * matrix[6] + z22 * matrix[10];
1119
1119
  return d < 0;
1120
1120
  };
1121
1121
  module.exports = isMirroring;
@@ -1217,15 +1217,15 @@ var require_rotate = __commonJS({
1217
1217
  var { sin, cos } = require_trigonometry();
1218
1218
  var copy = require_copy();
1219
1219
  var rotate2 = (out, matrix, radians, axis) => {
1220
- let [x, y, z21] = axis;
1221
- const lengthSquared = x * x + y * y + z21 * z21;
1220
+ let [x, y, z22] = axis;
1221
+ const lengthSquared = x * x + y * y + z22 * z22;
1222
1222
  if (Math.abs(lengthSquared) < EPS) {
1223
1223
  return copy(out, matrix);
1224
1224
  }
1225
1225
  const len = 1 / Math.sqrt(lengthSquared);
1226
1226
  x *= len;
1227
1227
  y *= len;
1228
- z21 *= len;
1228
+ z22 *= len;
1229
1229
  const s = sin(radians);
1230
1230
  const c = cos(radians);
1231
1231
  const t = 1 - c;
@@ -1242,14 +1242,14 @@ var require_rotate = __commonJS({
1242
1242
  const a22 = matrix[10];
1243
1243
  const a23 = matrix[11];
1244
1244
  const b00 = x * x * t + c;
1245
- const b01 = y * x * t + z21 * s;
1246
- const b02 = z21 * x * t - y * s;
1247
- const b10 = x * y * t - z21 * s;
1245
+ const b01 = y * x * t + z22 * s;
1246
+ const b02 = z22 * x * t - y * s;
1247
+ const b10 = x * y * t - z22 * s;
1248
1248
  const b11 = y * y * t + c;
1249
- const b12 = z21 * y * t + x * s;
1250
- const b20 = x * z21 * t + y * s;
1251
- const b21 = y * z21 * t - x * s;
1252
- const b22 = z21 * z21 * t + c;
1249
+ const b12 = z22 * y * t + x * s;
1250
+ const b20 = x * z22 * t + y * s;
1251
+ const b21 = y * z22 * t - x * s;
1252
+ const b22 = z22 * z22 * t + c;
1253
1253
  out[0] = a00 * b00 + a10 * b01 + a20 * b02;
1254
1254
  out[1] = a01 * b00 + a11 * b01 + a21 * b02;
1255
1255
  out[2] = a02 * b00 + a12 * b01 + a22 * b02;
@@ -1401,7 +1401,7 @@ var require_scale2 = __commonJS({
1401
1401
  var scale2 = (out, matrix, dimensions) => {
1402
1402
  const x = dimensions[0];
1403
1403
  const y = dimensions[1];
1404
- const z21 = dimensions[2];
1404
+ const z22 = dimensions[2];
1405
1405
  out[0] = matrix[0] * x;
1406
1406
  out[1] = matrix[1] * x;
1407
1407
  out[2] = matrix[2] * x;
@@ -1410,10 +1410,10 @@ var require_scale2 = __commonJS({
1410
1410
  out[5] = matrix[5] * y;
1411
1411
  out[6] = matrix[6] * y;
1412
1412
  out[7] = matrix[7] * y;
1413
- out[8] = matrix[8] * z21;
1414
- out[9] = matrix[9] * z21;
1415
- out[10] = matrix[10] * z21;
1416
- out[11] = matrix[11] * z21;
1413
+ out[8] = matrix[8] * z22;
1414
+ out[9] = matrix[9] * z22;
1415
+ out[10] = matrix[10] * z22;
1416
+ out[11] = matrix[11] * z22;
1417
1417
  out[12] = matrix[12];
1418
1418
  out[13] = matrix[13];
1419
1419
  out[14] = matrix[14];
@@ -1467,7 +1467,7 @@ var require_translate = __commonJS({
1467
1467
  var translate6 = (out, matrix, offsets) => {
1468
1468
  const x = offsets[0];
1469
1469
  const y = offsets[1];
1470
- const z21 = offsets[2];
1470
+ const z22 = offsets[2];
1471
1471
  let a00;
1472
1472
  let a01;
1473
1473
  let a02;
@@ -1481,10 +1481,10 @@ var require_translate = __commonJS({
1481
1481
  let a22;
1482
1482
  let a23;
1483
1483
  if (matrix === out) {
1484
- out[12] = matrix[0] * x + matrix[4] * y + matrix[8] * z21 + matrix[12];
1485
- out[13] = matrix[1] * x + matrix[5] * y + matrix[9] * z21 + matrix[13];
1486
- out[14] = matrix[2] * x + matrix[6] * y + matrix[10] * z21 + matrix[14];
1487
- out[15] = matrix[3] * x + matrix[7] * y + matrix[11] * z21 + matrix[15];
1484
+ out[12] = matrix[0] * x + matrix[4] * y + matrix[8] * z22 + matrix[12];
1485
+ out[13] = matrix[1] * x + matrix[5] * y + matrix[9] * z22 + matrix[13];
1486
+ out[14] = matrix[2] * x + matrix[6] * y + matrix[10] * z22 + matrix[14];
1487
+ out[15] = matrix[3] * x + matrix[7] * y + matrix[11] * z22 + matrix[15];
1488
1488
  } else {
1489
1489
  a00 = matrix[0];
1490
1490
  a01 = matrix[1];
@@ -1510,10 +1510,10 @@ var require_translate = __commonJS({
1510
1510
  out[9] = a21;
1511
1511
  out[10] = a22;
1512
1512
  out[11] = a23;
1513
- out[12] = a00 * x + a10 * y + a20 * z21 + matrix[12];
1514
- out[13] = a01 * x + a11 * y + a21 * z21 + matrix[13];
1515
- out[14] = a02 * x + a12 * y + a22 * z21 + matrix[14];
1516
- out[15] = a03 * x + a13 * y + a23 * z21 + matrix[15];
1513
+ out[12] = a00 * x + a10 * y + a20 * z22 + matrix[12];
1514
+ out[13] = a01 * x + a11 * y + a21 * z22 + matrix[13];
1515
+ out[14] = a02 * x + a12 * y + a22 * z22 + matrix[14];
1516
+ out[15] = a03 * x + a13 * y + a23 * z22 + matrix[15];
1517
1517
  }
1518
1518
  return out;
1519
1519
  };
@@ -1685,12 +1685,12 @@ var require_cross2 = __commonJS({
1685
1685
  var require_distance2 = __commonJS({
1686
1686
  "node_modules/@jscad/modeling/src/maths/vec2/distance.js"(exports, module) {
1687
1687
  "use strict";
1688
- var distance5 = (a, b) => {
1688
+ var distance6 = (a, b) => {
1689
1689
  const x = b[0] - a[0];
1690
1690
  const y = b[1] - a[1];
1691
1691
  return Math.sqrt(x * x + y * y);
1692
1692
  };
1693
- module.exports = distance5;
1693
+ module.exports = distance6;
1694
1694
  }
1695
1695
  });
1696
1696
 
@@ -2613,7 +2613,7 @@ var require_Vertex = __commonJS({
2613
2613
  var require_HalfEdge = __commonJS({
2614
2614
  "node_modules/@jscad/modeling/src/operations/hulls/quickhull/HalfEdge.js"(exports, module) {
2615
2615
  "use strict";
2616
- var distance5 = require_distance();
2616
+ var distance6 = require_distance();
2617
2617
  var squaredDistance = require_squaredDistance();
2618
2618
  var HalfEdge = class {
2619
2619
  constructor(vertex, face) {
@@ -2631,7 +2631,7 @@ var require_HalfEdge = __commonJS({
2631
2631
  }
2632
2632
  length() {
2633
2633
  if (this.tail()) {
2634
- return distance5(
2634
+ return distance6(
2635
2635
  this.tail().point,
2636
2636
  this.head().point
2637
2637
  );
@@ -2968,8 +2968,8 @@ var require_QuickHull = __commonJS({
2968
2968
  let nextVertex;
2969
2969
  for (let vertex = faceVertices; vertex; vertex = nextVertex) {
2970
2970
  nextVertex = vertex.next;
2971
- const distance5 = absorbingFace.distanceToPlane(vertex.point);
2972
- if (distance5 > this.tolerance) {
2971
+ const distance6 = absorbingFace.distanceToPlane(vertex.point);
2972
+ if (distance6 > this.tolerance) {
2973
2973
  this.addVertexToFace(vertex, absorbingFace);
2974
2974
  } else {
2975
2975
  this.unclaimed.add(vertex);
@@ -3056,9 +3056,9 @@ var require_QuickHull = __commonJS({
3056
3056
  let maxDistance = 0;
3057
3057
  let indexMax = 0;
3058
3058
  for (i = 0; i < 3; i += 1) {
3059
- const distance5 = max2[i].point[i] - min2[i].point[i];
3060
- if (distance5 > maxDistance) {
3061
- maxDistance = distance5;
3059
+ const distance6 = max2[i].point[i] - min2[i].point[i];
3060
+ if (distance6 > maxDistance) {
3061
+ maxDistance = distance6;
3062
3062
  indexMax = i;
3063
3063
  }
3064
3064
  }
@@ -3068,13 +3068,13 @@ var require_QuickHull = __commonJS({
3068
3068
  for (i = 0; i < this.vertices.length; i += 1) {
3069
3069
  const vertex = this.vertices[i];
3070
3070
  if (vertex !== v0 && vertex !== v1) {
3071
- const distance5 = pointLineDistance(
3071
+ const distance6 = pointLineDistance(
3072
3072
  vertex.point,
3073
3073
  v0.point,
3074
3074
  v1.point
3075
3075
  );
3076
- if (distance5 > maxDistance) {
3077
- maxDistance = distance5;
3076
+ if (distance6 > maxDistance) {
3077
+ maxDistance = distance6;
3078
3078
  v2 = vertex;
3079
3079
  }
3080
3080
  }
@@ -3085,9 +3085,9 @@ var require_QuickHull = __commonJS({
3085
3085
  for (i = 0; i < this.vertices.length; i += 1) {
3086
3086
  const vertex = this.vertices[i];
3087
3087
  if (vertex !== v0 && vertex !== v1 && vertex !== v2) {
3088
- const distance5 = Math.abs(dot(normal, vertex.point) - distPO);
3089
- if (distance5 > maxDistance) {
3090
- maxDistance = distance5;
3088
+ const distance6 = Math.abs(dot(normal, vertex.point) - distPO);
3089
+ if (distance6 > maxDistance) {
3090
+ maxDistance = distance6;
3091
3091
  v3 = vertex;
3092
3092
  }
3093
3093
  }
@@ -3127,9 +3127,9 @@ var require_QuickHull = __commonJS({
3127
3127
  maxDistance = this.tolerance;
3128
3128
  let maxFace;
3129
3129
  for (j = 0; j < 4; j += 1) {
3130
- const distance5 = faces[j].distanceToPlane(vertex.point);
3131
- if (distance5 > maxDistance) {
3132
- maxDistance = distance5;
3130
+ const distance6 = faces[j].distanceToPlane(vertex.point);
3131
+ if (distance6 > maxDistance) {
3132
+ maxDistance = distance6;
3133
3133
  maxFace = faces[j];
3134
3134
  }
3135
3135
  }
@@ -3185,9 +3185,9 @@ var require_QuickHull = __commonJS({
3185
3185
  let maxDistance = 0;
3186
3186
  const eyeFace = this.claimed.first().face;
3187
3187
  for (vertex = eyeFace.outside; vertex && vertex.face === eyeFace; vertex = vertex.next) {
3188
- const distance5 = eyeFace.distanceToPlane(vertex.point);
3189
- if (distance5 > maxDistance) {
3190
- maxDistance = distance5;
3188
+ const distance6 = eyeFace.distanceToPlane(vertex.point);
3189
+ if (distance6 > maxDistance) {
3190
+ maxDistance = distance6;
3191
3191
  eyeVertex = vertex;
3192
3192
  }
3193
3193
  }
@@ -3583,11 +3583,11 @@ var require_fromValues4 = __commonJS({
3583
3583
  "node_modules/@jscad/modeling/src/maths/vec4/fromValues.js"(exports, module) {
3584
3584
  "use strict";
3585
3585
  var create = require_create7();
3586
- var fromValues = (x, y, z21, w) => {
3586
+ var fromValues = (x, y, z22, w) => {
3587
3587
  const out = create();
3588
3588
  out[0] = x;
3589
3589
  out[1] = y;
3590
- out[2] = z21;
3590
+ out[2] = z22;
3591
3591
  out[3] = w;
3592
3592
  return out;
3593
3593
  };
@@ -3745,8 +3745,8 @@ var require_projectionOfPoint = __commonJS({
3745
3745
  const a = point[0] * plane[0] + point[1] * plane[1] + point[2] * plane[2] - plane[3];
3746
3746
  const x = point[0] - a * plane[0];
3747
3747
  const y = point[1] - a * plane[1];
3748
- const z21 = point[2] - a * plane[2];
3749
- return vec3.fromValues(x, y, z21);
3748
+ const z22 = point[2] - a * plane[2];
3749
+ return vec3.fromValues(x, y, z22);
3750
3750
  };
3751
3751
  module.exports = projectionOfPoint;
3752
3752
  }
@@ -4050,11 +4050,11 @@ var require_transform5 = __commonJS({
4050
4050
  "node_modules/@jscad/modeling/src/maths/vec4/transform.js"(exports, module) {
4051
4051
  "use strict";
4052
4052
  var transform = (out, vector, matrix) => {
4053
- const [x, y, z21, w] = vector;
4054
- out[0] = matrix[0] * x + matrix[4] * y + matrix[8] * z21 + matrix[12] * w;
4055
- out[1] = matrix[1] * x + matrix[5] * y + matrix[9] * z21 + matrix[13] * w;
4056
- out[2] = matrix[2] * x + matrix[6] * y + matrix[10] * z21 + matrix[14] * w;
4057
- out[3] = matrix[3] * x + matrix[7] * y + matrix[11] * z21 + matrix[15] * w;
4053
+ const [x, y, z22, w] = vector;
4054
+ out[0] = matrix[0] * x + matrix[4] * y + matrix[8] * z22 + matrix[12] * w;
4055
+ out[1] = matrix[1] * x + matrix[5] * y + matrix[9] * z22 + matrix[13] * w;
4056
+ out[2] = matrix[2] * x + matrix[6] * y + matrix[10] * z22 + matrix[14] * w;
4057
+ out[3] = matrix[3] * x + matrix[7] * y + matrix[11] * z22 + matrix[15] * w;
4058
4058
  return out;
4059
4059
  };
4060
4060
  module.exports = transform;
@@ -4116,8 +4116,8 @@ var require_measureBoundingSphere = __commonJS({
4116
4116
  out[2] = (minz[2] + maxz[2]) * 0.5;
4117
4117
  const x = out[0] - maxx[0];
4118
4118
  const y = out[1] - maxy[1];
4119
- const z21 = out[2] - maxz[2];
4120
- out[3] = Math.sqrt(x * x + y * y + z21 * z21);
4119
+ const z22 = out[2] - maxz[2];
4120
+ out[3] = Math.sqrt(x * x + y * y + z22 * z22);
4121
4121
  cache.set(polygon2, out);
4122
4122
  return out;
4123
4123
  };
@@ -4433,8 +4433,8 @@ var require_isConvex2 = __commonJS({
4433
4433
  const plane = poly3.plane(polygons[i]);
4434
4434
  for (let j = 0; j < vertices.length; j++) {
4435
4435
  const v = vertices[j];
4436
- const distance5 = vec3.dot(plane, v) - plane[3];
4437
- if (distance5 > EPS) {
4436
+ const distance6 = vec3.dot(plane, v) - plane[3];
4437
+ if (distance6 > EPS) {
4438
4438
  return false;
4439
4439
  }
4440
4440
  }
@@ -5868,13 +5868,13 @@ var require_arcLengthToT = __commonJS({
5868
5868
  distance: 0,
5869
5869
  segments: 100
5870
5870
  };
5871
- const { distance: distance5, segments } = Object.assign({}, defaults, options);
5871
+ const { distance: distance6, segments } = Object.assign({}, defaults, options);
5872
5872
  const arcLengths = lengths(segments, bezier);
5873
5873
  let startIndex = 0;
5874
5874
  let endIndex = segments;
5875
5875
  while (startIndex <= endIndex) {
5876
5876
  const middleIndex = Math.floor(startIndex + (endIndex - startIndex) / 2);
5877
- const diff = arcLengths[middleIndex] - distance5;
5877
+ const diff = arcLengths[middleIndex] - distance6;
5878
5878
  if (diff < 0) {
5879
5879
  startIndex = middleIndex + 1;
5880
5880
  } else if (diff > 0) {
@@ -5885,13 +5885,13 @@ var require_arcLengthToT = __commonJS({
5885
5885
  }
5886
5886
  }
5887
5887
  const targetIndex = endIndex;
5888
- if (arcLengths[targetIndex] === distance5) {
5888
+ if (arcLengths[targetIndex] === distance6) {
5889
5889
  return targetIndex / segments;
5890
5890
  }
5891
5891
  const lengthBefore = arcLengths[targetIndex];
5892
5892
  const lengthAfter = arcLengths[targetIndex + 1];
5893
5893
  const segmentLength = lengthAfter - lengthBefore;
5894
- const segmentFraction = (distance5 - lengthBefore) / segmentLength;
5894
+ const segmentFraction = (distance6 - lengthBefore) / segmentLength;
5895
5895
  return (targetIndex + segmentFraction) / segments;
5896
5896
  };
5897
5897
  module.exports = arcLengthToT;
@@ -6141,9 +6141,9 @@ var require_distanceToPoint = __commonJS({
6141
6141
  "use strict";
6142
6142
  var vec2 = require_vec2();
6143
6143
  var distanceToPoint = (line, point) => {
6144
- let distance5 = vec2.dot(point, line);
6145
- distance5 = Math.abs(distance5 - line[2]);
6146
- return distance5;
6144
+ let distance6 = vec2.dot(point, line);
6145
+ distance6 = Math.abs(distance6 - line[2]);
6146
+ return distance6;
6147
6147
  };
6148
6148
  module.exports = distanceToPoint;
6149
6149
  }
@@ -6167,10 +6167,10 @@ var require_fromPoints6 = __commonJS({
6167
6167
  const vector = vec2.subtract(vec2.create(), point2, point1);
6168
6168
  vec2.normal(vector, vector);
6169
6169
  vec2.normalize(vector, vector);
6170
- const distance5 = vec2.dot(point1, vector);
6170
+ const distance6 = vec2.dot(point1, vector);
6171
6171
  out[0] = vector[0];
6172
6172
  out[1] = vector[1];
6173
- out[2] = distance5;
6173
+ out[2] = distance6;
6174
6174
  return out;
6175
6175
  };
6176
6176
  module.exports = fromPoints;
@@ -6312,8 +6312,8 @@ var require_reverse3 = __commonJS({
6312
6312
  var fromValues = require_fromValues5();
6313
6313
  var reverse = (out, line) => {
6314
6314
  const normal = vec2.negate(vec2.create(), line);
6315
- const distance5 = -line[2];
6316
- return copy(out, fromValues(normal[0], normal[1], distance5));
6315
+ const distance6 = -line[2];
6316
+ return copy(out, fromValues(normal[0], normal[1], distance6));
6317
6317
  };
6318
6318
  module.exports = reverse;
6319
6319
  }
@@ -8399,13 +8399,13 @@ var require_calculatePlane = __commonJS({
8399
8399
  const midpoint2 = edges.reduce((point, edge) => vec3.add(vec3.create(), point, edge[0]), vec3.create());
8400
8400
  vec3.scale(midpoint2, midpoint2, 1 / edges.length);
8401
8401
  let farthestEdge;
8402
- let distance5 = 0;
8402
+ let distance6 = 0;
8403
8403
  edges.forEach((edge) => {
8404
8404
  if (!vec3.equals(edge[0], edge[1])) {
8405
8405
  const d = vec3.squaredDistance(midpoint2, edge[0]);
8406
- if (d > distance5) {
8406
+ if (d > distance6) {
8407
8407
  farthestEdge = edge;
8408
- distance5 = d;
8408
+ distance6 = d;
8409
8409
  }
8410
8410
  }
8411
8411
  });
@@ -9253,9 +9253,9 @@ var require_repair = __commonJS({
9253
9253
  let bestReplacement;
9254
9254
  missingOut.forEach((key2) => {
9255
9255
  const v2 = vertexMap.get(key2);
9256
- const distance5 = vec3.distance(v1, v2);
9257
- if (distance5 < bestDistance) {
9258
- bestDistance = distance5;
9256
+ const distance6 = vec3.distance(v1, v2);
9257
+ if (distance6 < bestDistance) {
9258
+ bestDistance = distance6;
9259
9259
  bestReplacement = v2;
9260
9260
  }
9261
9261
  });
@@ -13837,8 +13837,8 @@ var require_dist = __commonJS({
13837
13837
  fromValues: (x, y) => [x, y]
13838
13838
  },
13839
13839
  vec3: {
13840
- create: (x, y, z21) => [x, y, z21],
13841
- fromValues: (x, y, z21) => [x, y, z21]
13840
+ create: (x, y, z22) => [x, y, z22],
13841
+ fromValues: (x, y, z22) => [x, y, z22]
13842
13842
  }
13843
13843
  },
13844
13844
  geometries: {
@@ -25795,6 +25795,426 @@ footprinter.string = string2;
25795
25795
  footprinter.getFootprintNames = getFootprintNames;
25796
25796
  var fp = footprinter;
25797
25797
 
25798
+ // node_modules/@tscircuit/modelprinter/node_modules/@tscircuit/mm/dist/index.js
25799
+ var unitToMm2 = {
25800
+ in: 25.4,
25801
+ inch: 25.4,
25802
+ mil: 0.0254,
25803
+ mm: 1,
25804
+ m: 1e3,
25805
+ cm: 10,
25806
+ ft: 304.8,
25807
+ feet: 304.8
25808
+ };
25809
+ var mmNumberFormatter = new Intl.NumberFormat("en-US", {
25810
+ useGrouping: false,
25811
+ notation: "standard",
25812
+ maximumFractionDigits: 12
25813
+ });
25814
+ var mm2 = (n) => {
25815
+ let unit = typeof n === "number" ? "mm" : n.replace(/^[^a-zA-Z]+/g, "").toLowerCase();
25816
+ if (!unit)
25817
+ unit = "mm";
25818
+ const val = typeof n === "number" ? n : Number.parseFloat(n.split(unit)[0]);
25819
+ if (unit in unitToMm2) {
25820
+ return val * unitToMm2[unit];
25821
+ }
25822
+ throw new Error(`Unsupported unit: ${unit}`);
25823
+ };
25824
+
25825
+ // node_modules/@tscircuit/modelprinter/dist/index.js
25826
+ import { z as z21 } from "zod";
25827
+ var modelLengthSchema = z21.union([z21.number(), z21.string()]).transform((value, context) => {
25828
+ try {
25829
+ const parsed = mm2(value);
25830
+ if (!Number.isFinite(parsed)) throw new Error("Length is not finite");
25831
+ return parsed;
25832
+ } catch {
25833
+ context.addIssue({
25834
+ code: "custom",
25835
+ message: `Invalid model length: ${String(value)}`
25836
+ });
25837
+ return z21.NEVER;
25838
+ }
25839
+ });
25840
+ var positiveModelLengthSchema = modelLengthSchema.refine(
25841
+ (value) => value > 0,
25842
+ "Length must be greater than zero"
25843
+ );
25844
+ var nonnegativeModelLengthSchema = modelLengthSchema.refine(
25845
+ (value) => value >= 0,
25846
+ "Length cannot be negative"
25847
+ );
25848
+ var flexScreenOrientationSchema = z21.enum([
25849
+ "sitsFlat",
25850
+ "sitsFlatBelowBoard",
25851
+ "foldedToFaceAboveBoard",
25852
+ "foldedToFaceBelowBoard",
25853
+ "foldedToRightAngleAboveBoard",
25854
+ "foldedToRightAngleBelowBoard"
25855
+ ]);
25856
+ var positiveFiniteNumberSchema = z21.number().finite().positive();
25857
+ var aspectRatioStringSchema = z21.string().refine((value) => {
25858
+ const parts = value.split(":");
25859
+ if (parts.length !== 2) return false;
25860
+ const width10 = Number(parts[0]);
25861
+ const height10 = Number(parts[1]);
25862
+ return Number.isFinite(width10) && Number.isFinite(height10) && width10 > 0 && height10 > 0;
25863
+ }, 'Aspect ratio must look like "16:9"').transform((value) => value);
25864
+ var flexScreenAspectRatioSchema = z21.union([
25865
+ positiveFiniteNumberSchema,
25866
+ aspectRatioStringSchema,
25867
+ z21.tuple([positiveFiniteNumberSchema, positiveFiniteNumberSchema])
25868
+ ]);
25869
+ var modelPointSchema = z21.object({
25870
+ x: modelLengthSchema.optional(),
25871
+ y: modelLengthSchema.optional(),
25872
+ z: modelLengthSchema.optional()
25873
+ }).strict();
25874
+ var rotationValueSchema = z21.union([z21.number().finite(), z21.string().min(1)]);
25875
+ var modelRotationSchema = z21.tuple([
25876
+ rotationValueSchema,
25877
+ rotationValueSchema,
25878
+ rotationValueSchema
25879
+ ]);
25880
+ var orientationShortcutKeys = [
25881
+ "sitsFlat",
25882
+ "sitsFlatBelowBoard",
25883
+ "foldedToFaceAboveBoard",
25884
+ "foldedToFaceBelowBoard",
25885
+ "foldsAboveBoard",
25886
+ "foldsBelowBoard",
25887
+ "foldedToRightAngleAboveBoard",
25888
+ "foldedToRightAngleBelowBoard"
25889
+ ];
25890
+ var flexScreenModelPropsShape = {
25891
+ width: positiveModelLengthSchema.optional(),
25892
+ height: positiveModelLengthSchema.optional(),
25893
+ diagonal: positiveModelLengthSchema.optional(),
25894
+ aspectRatio: flexScreenAspectRatioSchema.optional(),
25895
+ ratio: flexScreenAspectRatioSchema.optional(),
25896
+ defaultDiagonal: positiveModelLengthSchema.optional(),
25897
+ orientation: flexScreenOrientationSchema.optional(),
25898
+ sitsFlat: z21.boolean().optional(),
25899
+ sitsFlatBelowBoard: z21.boolean().optional(),
25900
+ foldedToFaceAboveBoard: z21.boolean().optional(),
25901
+ foldedToFaceBelowBoard: z21.boolean().optional(),
25902
+ foldsAboveBoard: z21.boolean().optional(),
25903
+ foldsBelowBoard: z21.boolean().optional(),
25904
+ foldedToRightAngleAboveBoard: z21.boolean().optional(),
25905
+ foldedToRightAngleBelowBoard: z21.boolean().optional(),
25906
+ screenThickness: positiveModelLengthSchema.optional(),
25907
+ bezelInset: nonnegativeModelLengthSchema.optional(),
25908
+ bezelDepth: positiveModelLengthSchema.optional(),
25909
+ activeAreaWidth: positiveModelLengthSchema.optional(),
25910
+ activeAreaHeight: positiveModelLengthSchema.optional(),
25911
+ screenColor: z21.string().min(1).optional(),
25912
+ bezelColor: z21.string().min(1).optional(),
25913
+ showScreen: z21.boolean().optional(),
25914
+ flexCableLength: positiveModelLengthSchema.optional(),
25915
+ flexCableWidth: positiveModelLengthSchema.optional(),
25916
+ flexCableThickness: positiveModelLengthSchema.optional(),
25917
+ flexCableColor: z21.string().min(1).optional(),
25918
+ conductorCount: z21.number().int().positive().optional(),
25919
+ conductorPitch: positiveModelLengthSchema.optional(),
25920
+ conductorWidth: positiveModelLengthSchema.optional(),
25921
+ conductorThickness: positiveModelLengthSchema.optional(),
25922
+ conductorColor: z21.string().min(1).optional(),
25923
+ cableEdgeMargin: nonnegativeModelLengthSchema.optional(),
25924
+ exposedContactLength: nonnegativeModelLengthSchema.optional(),
25925
+ showConductors: z21.boolean().optional(),
25926
+ showFlexCable: z21.boolean().optional(),
25927
+ showStiffeners: z21.boolean().optional(),
25928
+ stiffenerLength: nonnegativeModelLengthSchema.optional(),
25929
+ stiffenerThickness: positiveModelLengthSchema.optional(),
25930
+ stiffenerColor: z21.string().min(1).optional(),
25931
+ bendRadius: positiveModelLengthSchema.optional(),
25932
+ bendSegments: z21.number().int().min(2).optional(),
25933
+ rightAngleVerticalLead: nonnegativeModelLengthSchema.optional(),
25934
+ distanceAboveBoard: nonnegativeModelLengthSchema.optional(),
25935
+ distanceBelowBoard: nonnegativeModelLengthSchema.optional(),
25936
+ foldDistanceFromConnector: nonnegativeModelLengthSchema.optional(),
25937
+ foldOutset: positiveModelLengthSchema.optional(),
25938
+ foldSegments: z21.number().int().min(4).optional(),
25939
+ screenGap: nonnegativeModelLengthSchema.optional(),
25940
+ boardTopZ: modelLengthSchema.optional(),
25941
+ boardThickness: positiveModelLengthSchema.optional(),
25942
+ boardClearance: nonnegativeModelLengthSchema.optional(),
25943
+ cableStartX: modelLengthSchema.optional(),
25944
+ cableStartY: modelLengthSchema.optional(),
25945
+ cableStartZ: modelLengthSchema.optional(),
25946
+ cableLateralOffset: modelLengthSchema.optional(),
25947
+ screenOffset: modelPointSchema.optional(),
25948
+ screenRotation: modelRotationSchema.optional(),
25949
+ rotation: modelRotationSchema.optional(),
25950
+ offset: modelPointSchema.optional()
25951
+ };
25952
+ var addOrientationShortcutIssue = (props, addIssue) => {
25953
+ const selectedShortcuts = orientationShortcutKeys.filter(
25954
+ (key) => props[key] === true
25955
+ );
25956
+ if (selectedShortcuts.length > 1) addIssue(selectedShortcuts[1]);
25957
+ };
25958
+ var flexScreenModelPropsSchema = z21.object(flexScreenModelPropsShape).strict().superRefine((props, context) => {
25959
+ addOrientationShortcutIssue(props, (path) => {
25960
+ context.addIssue({
25961
+ code: "custom",
25962
+ message: "Only one FlexScreen orientation shortcut can be true",
25963
+ path: [path]
25964
+ });
25965
+ });
25966
+ });
25967
+ var flexScreenModelDefinitionSchema = z21.object({
25968
+ fn: z21.literal("flexscreen"),
25969
+ ...flexScreenModelPropsShape
25970
+ }).strict().superRefine((model, context) => {
25971
+ addOrientationShortcutIssue(model, (path) => {
25972
+ context.addIssue({
25973
+ code: "custom",
25974
+ message: "Only one FlexScreen orientation shortcut can be true",
25975
+ path: [path]
25976
+ });
25977
+ });
25978
+ });
25979
+ var parsePart = (part) => {
25980
+ const match = part.match(/^([a-zA-Z]+)([\(\d\.\+\-].*)?$/);
25981
+ if (!match?.[1]) return void 0;
25982
+ return {
25983
+ fn: match[1].toLowerCase(),
25984
+ value: match[2]
25985
+ };
25986
+ };
25987
+ var parseModelStringParams = (definition) => {
25988
+ const normalizedDefinition = definition.trim();
25989
+ if (!normalizedDefinition) throw new Error("Model string cannot be empty");
25990
+ const parts = normalizedDefinition.split("_");
25991
+ const firstPart = parts[0];
25992
+ const first = parsePart(firstPart);
25993
+ const params = {};
25994
+ const fn = first?.fn ?? firstPart.toLowerCase();
25995
+ params[fn] = true;
25996
+ params.fn = fn;
25997
+ if (first?.value) {
25998
+ const numericValue = Number.parseFloat(first.value);
25999
+ if (Number.isFinite(numericValue)) params.num_pins = numericValue;
26000
+ }
26001
+ for (const part of parts.slice(1)) {
26002
+ if (!part) throw new Error("Model strings cannot contain empty tokens");
26003
+ const parsed = parsePart(part);
26004
+ if (!parsed) throw new Error(`Invalid model string token "${part}"`);
26005
+ params[parsed.fn] = parsed.value ?? true;
26006
+ }
26007
+ params.string = normalizedDefinition;
26008
+ return params;
26009
+ };
26010
+ var orientationTokens = {
26011
+ sitsflat: "sitsFlat",
26012
+ sitsflatbelow: "sitsFlatBelowBoard",
26013
+ sitsflatbelowboard: "sitsFlatBelowBoard",
26014
+ foldsabove: "foldedToFaceAboveBoard",
26015
+ foldsaboveboard: "foldedToFaceAboveBoard",
26016
+ foldedtofaceaboveboard: "foldedToFaceAboveBoard",
26017
+ foldsbelow: "foldedToFaceBelowBoard",
26018
+ foldsbelowboard: "foldedToFaceBelowBoard",
26019
+ foldedtofacebelowboard: "foldedToFaceBelowBoard",
26020
+ rightangleabove: "foldedToRightAngleAboveBoard",
26021
+ rightangleaboveboard: "foldedToRightAngleAboveBoard",
26022
+ foldedtorightangleaboveboard: "foldedToRightAngleAboveBoard",
26023
+ rightanglebelow: "foldedToRightAngleBelowBoard",
26024
+ rightanglebelowboard: "foldedToRightAngleBelowBoard",
26025
+ foldedtorightanglebelowboard: "foldedToRightAngleBelowBoard"
26026
+ };
26027
+ var lengthProperties = {
26028
+ width: ["width", "w"],
26029
+ height: ["height", "h"],
26030
+ diagonal: ["diagonal", "diag", "d"],
26031
+ defaultDiagonal: ["defaultdiagonal", "defaultdiag"],
26032
+ screenThickness: ["screenthickness"],
26033
+ bezelInset: ["bezelinset"],
26034
+ bezelDepth: ["bezeldepth"],
26035
+ activeAreaWidth: ["activeareawidth", "activew"],
26036
+ activeAreaHeight: ["activeareaheight", "activeh"],
26037
+ flexCableLength: ["flexcablelength", "flexlength", "flex"],
26038
+ flexCableWidth: ["flexcablewidth", "flexwidth"],
26039
+ flexCableThickness: ["flexcablethickness", "flexthickness"],
26040
+ conductorPitch: ["conductorpitch"],
26041
+ conductorWidth: ["conductorwidth"],
26042
+ conductorThickness: ["conductorthickness"],
26043
+ cableEdgeMargin: ["cableedgemargin", "edgemargin"],
26044
+ exposedContactLength: ["exposedcontactlength", "contactlength"],
26045
+ stiffenerLength: ["stiffenerlength"],
26046
+ stiffenerThickness: ["stiffenerthickness"],
26047
+ bendRadius: ["bendradius"],
26048
+ rightAngleVerticalLead: ["rightangleverticallead", "verticallead"],
26049
+ distanceAboveBoard: ["distanceaboveboard", "distanceabove"],
26050
+ distanceBelowBoard: ["distancebelowboard", "distancebelow"],
26051
+ foldDistanceFromConnector: [
26052
+ "folddistancefromconnector",
26053
+ "folddistance",
26054
+ "foldstart"
26055
+ ],
26056
+ foldOutset: ["foldoutset", "outset"],
26057
+ screenGap: ["screengap"],
26058
+ boardTopZ: ["boardtopz"],
26059
+ boardThickness: ["boardthickness"],
26060
+ boardClearance: ["boardclearance"],
26061
+ cableStartX: ["cablestartx"],
26062
+ cableStartY: ["cablestarty"],
26063
+ cableStartZ: ["cablestartz"],
26064
+ cableLateralOffset: ["cablelateraloffset", "lateraloffset"]
26065
+ };
26066
+ var lengthTokenToProperty = Object.fromEntries(
26067
+ Object.entries(lengthProperties).flatMap(
26068
+ ([property, tokens]) => tokens.map((token) => [token, property])
26069
+ )
26070
+ );
26071
+ var integerTokenToProperty = {
26072
+ conductorcount: "conductorCount",
26073
+ conductors: "conductorCount",
26074
+ bendsegments: "bendSegments",
26075
+ foldsegments: "foldSegments"
26076
+ };
26077
+ var booleanTokens = {
26078
+ showscreen: ["showScreen", true],
26079
+ hidescreen: ["showScreen", false],
26080
+ showflex: ["showFlexCable", true],
26081
+ hideflex: ["showFlexCable", false],
26082
+ showconductors: ["showConductors", true],
26083
+ hideconductors: ["showConductors", false],
26084
+ showstiffeners: ["showStiffeners", true],
26085
+ hidestiffeners: ["showStiffeners", false]
26086
+ };
26087
+ var colorProperties = {
26088
+ screencolor: "screenColor",
26089
+ bezelcolor: "bezelColor",
26090
+ flexcolor: "flexCableColor",
26091
+ conductorcolor: "conductorColor",
26092
+ stiffenercolor: "stiffenerColor"
26093
+ };
26094
+ var parseAspectRatio = (value) => {
26095
+ const normalized = String(value).toLowerCase().replace("x", ":");
26096
+ if (normalized.includes(":")) {
26097
+ const [width10, height10, extra] = normalized.split(":");
26098
+ const numericWidth = Number(width10);
26099
+ const numericHeight = Number(height10);
26100
+ if (extra !== void 0 || !Number.isFinite(numericWidth) || !Number.isFinite(numericHeight) || numericWidth <= 0 || numericHeight <= 0) {
26101
+ throw new Error(`Invalid FlexScreen aspect ratio "${String(value)}"`);
26102
+ }
26103
+ return `${numericWidth}:${numericHeight}`;
26104
+ }
26105
+ const numeric = Number(normalized);
26106
+ if (!Number.isFinite(numeric) || numeric <= 0) {
26107
+ throw new Error(`Invalid FlexScreen aspect ratio "${String(value)}"`);
26108
+ }
26109
+ return numeric;
26110
+ };
26111
+ var unwrapFunctionValue = (value, token) => {
26112
+ if (typeof value !== "string" || !/^\(.+\)$/.test(value)) {
26113
+ throw new Error(`FlexScreen token "${token}" requires a value in (...)`);
26114
+ }
26115
+ return value.slice(1, -1);
26116
+ };
26117
+ var assertBareToken = (value, token) => {
26118
+ if (value !== true) {
26119
+ throw new Error(`FlexScreen token "${token}" does not accept a value`);
26120
+ }
26121
+ };
26122
+ var parseFlexScreenModelParams = (rawParams) => {
26123
+ if (rawParams.fn !== "flexscreen") {
26124
+ throw new Error(`Expected FlexScreen params, got "${rawParams.fn}"`);
26125
+ }
26126
+ const props = {};
26127
+ let orientation2;
26128
+ let relativeDistance;
26129
+ for (const [token, value] of Object.entries(rawParams)) {
26130
+ if (token === "fn" || token === "string" || token === "flexscreen") {
26131
+ continue;
26132
+ }
26133
+ const tokenOrientation = orientationTokens[token];
26134
+ if (tokenOrientation) {
26135
+ assertBareToken(value, token);
26136
+ if (orientation2 && orientation2 !== tokenOrientation) {
26137
+ throw new Error(
26138
+ "A FlexScreen model string can only set one orientation"
26139
+ );
26140
+ }
26141
+ orientation2 = tokenOrientation;
26142
+ props.orientation = tokenOrientation;
26143
+ continue;
26144
+ }
26145
+ if (token in booleanTokens) {
26146
+ assertBareToken(value, token);
26147
+ const [property, enabled] = booleanTokens[token];
26148
+ props[property] = enabled;
26149
+ continue;
26150
+ }
26151
+ const colorProperty = colorProperties[token];
26152
+ if (colorProperty) {
26153
+ props[colorProperty] = unwrapFunctionValue(value, token);
26154
+ continue;
26155
+ }
26156
+ if (token === "ratio") {
26157
+ props.aspectRatio = parseAspectRatio(value);
26158
+ continue;
26159
+ }
26160
+ const lengthProperty = lengthTokenToProperty[token];
26161
+ if (lengthProperty) {
26162
+ props[lengthProperty] = value;
26163
+ continue;
26164
+ }
26165
+ if (token === "distance") {
26166
+ relativeDistance = value;
26167
+ continue;
26168
+ }
26169
+ const integerProperty = integerTokenToProperty[token];
26170
+ if (integerProperty) {
26171
+ const parsed = Number(value);
26172
+ if (!Number.isInteger(parsed) || parsed < 1) {
26173
+ throw new Error(
26174
+ `Invalid positive integer in FlexScreen token "${token}${String(value)}"`
26175
+ );
26176
+ }
26177
+ props[integerProperty] = parsed;
26178
+ continue;
26179
+ }
26180
+ throw new Error(`Unknown FlexScreen model token "${token}${String(value)}"`);
26181
+ }
26182
+ if (relativeDistance !== void 0) {
26183
+ if (orientation2 === "foldedToFaceAboveBoard") {
26184
+ props.distanceAboveBoard = relativeDistance;
26185
+ } else if (orientation2 === "foldedToFaceBelowBoard") {
26186
+ props.distanceBelowBoard = relativeDistance;
26187
+ } else {
26188
+ throw new Error(
26189
+ 'The "distance" token requires foldsabove or foldsbelow; use distanceabove or distancebelow for an explicit side'
26190
+ );
26191
+ }
26192
+ }
26193
+ return flexScreenModelDefinitionSchema.parse({ fn: "flexscreen", ...props });
26194
+ };
26195
+ var modelFunctions = {
26196
+ flexscreen: parseFlexScreenModelParams
26197
+ };
26198
+ var modelParamsToJson = (params) => {
26199
+ const modelFunction = modelFunctions[params.fn];
26200
+ if (modelFunction) {
26201
+ return modelFunction(params);
26202
+ }
26203
+ throw new Error(`Unsupported modelprinter function "${params.fn}"`);
26204
+ };
26205
+ var string = (value) => {
26206
+ const params = parseModelStringParams(value);
26207
+ return {
26208
+ params: () => params,
26209
+ json: () => modelParamsToJson(params)
26210
+ };
26211
+ };
26212
+ var modelprinter = {
26213
+ string,
26214
+ getModelNames: () => Object.keys(modelFunctions)
26215
+ };
26216
+ var mp = modelprinter;
26217
+
25798
26218
  // node_modules/jscad-electronics/dist/vanilla.js
25799
26219
  import {
25800
26220
  BufferAttribute,
@@ -26075,10 +26495,10 @@ var svgPathPoints = normalizeOnY([
26075
26495
  ]);
26076
26496
  var DIP_PIN_HEIGHT = 5.47;
26077
26497
  var heightAboveSurface = 0.5;
26078
- var DipPinLeg = ({ x, y, z: z21 }) => {
26498
+ var DipPinLeg = ({ x, y, z: z22 }) => {
26079
26499
  const isRotated = x > 0;
26080
26500
  return /* @__PURE__ */ jsxs(Fragment2, { children: [
26081
- /* @__PURE__ */ jsx2(Translate, { offset: { x: x + 0.25 / 2, y, z: z21 }, children: /* @__PURE__ */ jsx2(Rotate, { rotation: ["-90deg", 0, "90deg"], children: /* @__PURE__ */ jsx2(ExtrudeLinear, { height: 0.25, children: /* @__PURE__ */ jsx2(
26501
+ /* @__PURE__ */ jsx2(Translate, { offset: { x: x + 0.25 / 2, y, z: z22 }, children: /* @__PURE__ */ jsx2(Rotate, { rotation: ["-90deg", 0, "90deg"], children: /* @__PURE__ */ jsx2(ExtrudeLinear, { height: 0.25, children: /* @__PURE__ */ jsx2(
26082
26502
  Polygon,
26083
26503
  {
26084
26504
  points: svgPathPoints.slice().reverse().map((p) => [p.x, p.y])
@@ -26090,7 +26510,7 @@ var DipPinLeg = ({ x, y, z: z21 }) => {
26090
26510
  offset: {
26091
26511
  x,
26092
26512
  y: y + (isRotated ? 1 : -1),
26093
- z: z21
26513
+ z: z22
26094
26514
  },
26095
26515
  children: /* @__PURE__ */ jsx2(Rotate, { rotation: ["-90deg", "90deg", isRotated ? "180deg" : "0deg"], children: /* @__PURE__ */ jsx2(ExtrudeLinear, { height: 2, children: /* @__PURE__ */ jsx2(
26096
26516
  Polygon,
@@ -26561,6 +26981,7 @@ var getLeadWidth = (pinCount, width10) => {
26561
26981
  return 0.25;
26562
26982
  }
26563
26983
  };
26984
+ var PIN_METAL_COLOR = "#c0c0c0";
26564
26985
  var PinHeader = ({
26565
26986
  x,
26566
26987
  y,
@@ -26571,7 +26992,6 @@ var PinHeader = ({
26571
26992
  bodyLength: bodyLength10 = 2.54,
26572
26993
  bodyWidth = 2.54,
26573
26994
  flipZ,
26574
- faceup,
26575
26995
  smd,
26576
26996
  rightangle
26577
26997
  }) => {
@@ -26584,7 +27004,7 @@ var PinHeader = ({
26584
27004
  center: [x, y, flipZ(bodyHeight / 2)]
26585
27005
  }
26586
27006
  ) }),
26587
- !faceup && /* @__PURE__ */ jsx2(Colorize, { color: "gold", children: smd ? /* @__PURE__ */ jsx2(
27007
+ /* @__PURE__ */ jsx2(Colorize, { color: PIN_METAL_COLOR, children: smd ? /* @__PURE__ */ jsx2(
26588
27008
  SmdChipLead,
26589
27009
  {
26590
27010
  rotation: -Math.PI / 2,
@@ -26603,7 +27023,7 @@ var PinHeader = ({
26603
27023
  /* @__PURE__ */ jsx2(
26604
27024
  Cuboid,
26605
27025
  {
26606
- color: "gold",
27026
+ color: PIN_METAL_COLOR,
26607
27027
  size: [pinThickness, pinThickness, shortSidePinLength * 0.9],
26608
27028
  center: [x, y, flipZ(bodyHeight * 0.9 + bodyHeight / 2)]
26609
27029
  }
@@ -26611,7 +27031,7 @@ var PinHeader = ({
26611
27031
  /* @__PURE__ */ jsx2(
26612
27032
  Cuboid,
26613
27033
  {
26614
- color: "gold",
27034
+ color: PIN_METAL_COLOR,
26615
27035
  size: [
26616
27036
  pinThickness / 1.8,
26617
27037
  pinThickness / 1.8,
@@ -26621,11 +27041,11 @@ var PinHeader = ({
26621
27041
  }
26622
27042
  )
26623
27043
  ] }) }),
26624
- /* @__PURE__ */ jsx2(Colorize, { color: "gold", children: /* @__PURE__ */ jsx2(Translate, { y: rightangle ? -3.9 : 0, z: rightangle ? 1 : 0, children: /* @__PURE__ */ jsx2(Rotate, { rotation: rightangle ? [-Math.PI / 2, 0, 0] : [0, 0, 0], children: /* @__PURE__ */ jsxs(Hull, { children: [
27044
+ /* @__PURE__ */ jsx2(Colorize, { color: PIN_METAL_COLOR, children: /* @__PURE__ */ jsx2(Translate, { y: rightangle ? -3.9 : 0, z: rightangle ? 1 : 0, children: /* @__PURE__ */ jsx2(Rotate, { rotation: rightangle ? [-Math.PI / 2, 0, 0] : [0, 0, 0], children: /* @__PURE__ */ jsxs(Hull, { children: [
26625
27045
  /* @__PURE__ */ jsx2(
26626
27046
  Cuboid,
26627
27047
  {
26628
- color: "gold",
27048
+ color: PIN_METAL_COLOR,
26629
27049
  size: [pinThickness, pinThickness, longSidePinLength * 0.9],
26630
27050
  center: [x, y, flipZ(-longSidePinLength / 2 * 0.9)]
26631
27051
  }
@@ -26633,7 +27053,7 @@ var PinHeader = ({
26633
27053
  /* @__PURE__ */ jsx2(
26634
27054
  Cuboid,
26635
27055
  {
26636
- color: "gold",
27056
+ color: PIN_METAL_COLOR,
26637
27057
  size: [
26638
27058
  pinThickness / 1.8,
26639
27059
  pinThickness / 1.8,
@@ -26650,7 +27070,6 @@ var PinRow = ({
26650
27070
  pitch = 2.54,
26651
27071
  longSidePinLength = 6,
26652
27072
  invert,
26653
- faceup,
26654
27073
  rows = 1,
26655
27074
  smd,
26656
27075
  rightangle
@@ -26661,8 +27080,9 @@ var PinRow = ({
26661
27080
  const rowSpacing = 2.54;
26662
27081
  const shortSidePinLength = 3;
26663
27082
  const xoff = -((pinsPerRow - 1) / 2) * pitch;
26664
- const zOffset = !smd && !rightangle ? -bodyHeight - 1.6 : 0;
26665
- const flipZ = (z21) => (invert || faceup ? -z21 + bodyHeight : z21) + zOffset;
27083
+ const throughHole = !smd && !rightangle;
27084
+ const flipped = throughHole ? !invert : Boolean(invert);
27085
+ const flipZ = (z22) => flipped ? -z22 + bodyHeight : z22;
26666
27086
  return /* @__PURE__ */ jsx2(Fragment2, { children: Array.from({ length: numberOfPins }, (_, i) => {
26667
27087
  const row = Math.floor(i / pinsPerRow);
26668
27088
  const col = i % pinsPerRow;
@@ -26678,7 +27098,6 @@ var PinRow = ({
26678
27098
  longSidePinLength,
26679
27099
  bodyHeight,
26680
27100
  flipZ,
26681
- faceup,
26682
27101
  smd,
26683
27102
  rightangle
26684
27103
  },
@@ -26946,6 +27365,82 @@ var SOT235 = () => {
26946
27365
  ] });
26947
27366
  };
26948
27367
  var SOT_235_default = SOT235;
27368
+ var SOT233P = ({
27369
+ fullWidth = 2.9,
27370
+ fullLength: fullLength10 = 2.8,
27371
+ color
27372
+ } = {}) => {
27373
+ const bodyWidth = 1.3;
27374
+ const bodyLength10 = 2.9;
27375
+ const bodyHeight = 1.1;
27376
+ const leadWidth = 0.4;
27377
+ const leadThickness = 0.15;
27378
+ const leadHeight = 0.95;
27379
+ const padContactLength = 0.4;
27380
+ const padThickness = leadThickness / 2;
27381
+ const extendedBodyDistance = (fullWidth - bodyWidth) / 2 + 0.3;
27382
+ return /* @__PURE__ */ jsxs(Fragment2, { children: [
27383
+ /* @__PURE__ */ jsx2(
27384
+ SmdChipLead,
27385
+ {
27386
+ position: {
27387
+ x: -fullWidth / 2,
27388
+ y: 0.95,
27389
+ z: padThickness
27390
+ },
27391
+ width: leadWidth,
27392
+ thickness: leadThickness,
27393
+ padContactLength,
27394
+ bodyDistance: extendedBodyDistance,
27395
+ height: leadHeight
27396
+ },
27397
+ 1
27398
+ ),
27399
+ /* @__PURE__ */ jsx2(
27400
+ SmdChipLead,
27401
+ {
27402
+ position: {
27403
+ x: -fullWidth / 2,
27404
+ y: -0.95,
27405
+ z: padThickness
27406
+ },
27407
+ width: leadWidth,
27408
+ thickness: leadThickness,
27409
+ padContactLength,
27410
+ bodyDistance: extendedBodyDistance,
27411
+ height: leadHeight
27412
+ },
27413
+ 2
27414
+ ),
27415
+ /* @__PURE__ */ jsx2(
27416
+ SmdChipLead,
27417
+ {
27418
+ rotation: Math.PI,
27419
+ position: {
27420
+ x: fullWidth / 2,
27421
+ y: 0,
27422
+ z: padThickness
27423
+ },
27424
+ width: leadWidth,
27425
+ thickness: leadThickness,
27426
+ padContactLength,
27427
+ bodyDistance: extendedBodyDistance,
27428
+ height: leadHeight
27429
+ },
27430
+ 3
27431
+ ),
27432
+ /* @__PURE__ */ jsx2(
27433
+ ChipBody,
27434
+ {
27435
+ center: { x: 0, y: 0, z: 0 },
27436
+ width: bodyWidth,
27437
+ length: bodyLength10,
27438
+ height: bodyHeight,
27439
+ color
27440
+ }
27441
+ )
27442
+ ] });
27443
+ };
26949
27444
  var SOT23W = ({ fullWidth = 2.9, fullLength: fullLength10 = 2.8 }) => {
26950
27445
  const bodyWidth = 1.92;
26951
27446
  const bodyLength10 = 2.9;
@@ -27220,7 +27715,7 @@ var A2512 = ({ color = "#333" }) => {
27220
27715
  var FemaleHeader = ({
27221
27716
  x,
27222
27717
  y,
27223
- z: z21 = 0,
27718
+ z: z22 = 0,
27224
27719
  pitch = 2.54,
27225
27720
  legsLength = 3,
27226
27721
  innerDiameter = 0.945,
@@ -27235,8 +27730,8 @@ var FemaleHeader = ({
27235
27730
  const socketEntryWidth = socketWidth * 1.8;
27236
27731
  const socketEntryHeight = Math.min(bodyHeight * 0.18, pitch * 0.24);
27237
27732
  const socketDepth = bodyHeight + 0.1;
27238
- const socketCenterZ = flipZ(z21 + socketDepth / 2);
27239
- const socketEntryBaseZ = z21 + bodyHeight - socketEntryHeight;
27733
+ const socketCenterZ = flipZ(z22 + socketDepth / 2);
27734
+ const socketEntryBaseZ = z22 + bodyHeight - socketEntryHeight;
27240
27735
  const gapWidth = pinThickness * 1.6;
27241
27736
  return /* @__PURE__ */ jsxs(Fragment2, { children: [
27242
27737
  /* @__PURE__ */ jsx2(Colorize, { color: "#1a1a1a", children: /* @__PURE__ */ jsxs(Subtract, { children: [
@@ -27245,7 +27740,7 @@ var FemaleHeader = ({
27245
27740
  {
27246
27741
  color: "#000",
27247
27742
  size: [bodyLength10, bodyWidth, bodyHeight],
27248
- center: [x, y, flipZ(z21 + bodyHeight / 2)]
27743
+ center: [x, y, flipZ(z22 + bodyHeight / 2)]
27249
27744
  }
27250
27745
  ),
27251
27746
  /* @__PURE__ */ jsx2(
@@ -27267,7 +27762,7 @@ var FemaleHeader = ({
27267
27762
  Cuboid,
27268
27763
  {
27269
27764
  size: [socketEntryWidth, socketEntryWidth, 0.01],
27270
- center: [x, y, flipZ(z21 + bodyHeight)]
27765
+ center: [x, y, flipZ(z22 + bodyHeight)]
27271
27766
  }
27272
27767
  )
27273
27768
  ] })
@@ -27279,7 +27774,7 @@ var FemaleHeader = ({
27279
27774
  {
27280
27775
  color: "silver",
27281
27776
  size: [pinThickness, pinThickness, legsLength * 0.9],
27282
- center: [x, y, flipZ(z21 + -legsLength / 2 * 0.9)]
27777
+ center: [x, y, flipZ(z22 + -legsLength / 2 * 0.9)]
27283
27778
  }
27284
27779
  ),
27285
27780
  /* @__PURE__ */ jsx2(
@@ -27287,7 +27782,7 @@ var FemaleHeader = ({
27287
27782
  {
27288
27783
  color: "silver",
27289
27784
  size: [pinThickness / 1.8, pinThickness / 1.8, legsLength],
27290
- center: [x, y, flipZ(z21 + -legsLength / 2)]
27785
+ center: [x, y, flipZ(z22 + -legsLength / 2)]
27291
27786
  }
27292
27787
  )
27293
27788
  ] }),
@@ -27296,7 +27791,7 @@ var FemaleHeader = ({
27296
27791
  {
27297
27792
  color: "silver",
27298
27793
  size: [gapWidth, gapWidth, gapWidth * 0.5],
27299
- center: [x, y, flipZ(z21 + gapWidth / 2 * 0.5)]
27794
+ center: [x, y, flipZ(z22 + gapWidth / 2 * 0.5)]
27300
27795
  }
27301
27796
  )
27302
27797
  ] })
@@ -27314,7 +27809,7 @@ var FemaleHeaderRow = ({
27314
27809
  const pinsPerRow = Math.ceil(numberOfPins / rows);
27315
27810
  const rowSpacing = 2.54;
27316
27811
  const xoff = -((pinsPerRow - 1) / 2) * pitch;
27317
- const flipZ = (z21) => invert ? -z21 + bodyHeight : z21;
27812
+ const flipZ = (z22) => invert ? -z22 + bodyHeight : z22;
27318
27813
  return /* @__PURE__ */ jsx2(Fragment2, { children: Array.from({ length: numberOfPins }, (_, i) => {
27319
27814
  const row = Math.floor(i / pinsPerRow);
27320
27815
  const col = i % pinsPerRow;
@@ -27815,8 +28310,8 @@ var SMA = () => {
27815
28310
  ] });
27816
28311
  };
27817
28312
  var SMB = () => {
27818
- const bodyWidth = 4.4;
27819
- const bodyLength10 = 3.4;
28313
+ const bodyWidth = 4.6;
28314
+ const bodyLength10 = 4;
27820
28315
  const bodyHeight = 2.3;
27821
28316
  const padWidth = 1.45;
27822
28317
  const padThickness = 0.12;
@@ -28086,162 +28581,164 @@ var SOD123FL = () => {
28086
28581
  )
28087
28582
  ] });
28088
28583
  };
28089
- var SOD123W = () => {
28090
- const fullWidth = 2.6;
28091
- const bodyLength10 = 1.7;
28584
+ var SOD123W = ({
28585
+ bodyWidth = 2.6,
28586
+ bodyLength: bodyLength10 = 1.7,
28587
+ bodyHeight = 1
28588
+ } = {}) => {
28589
+ const fullWidth = bodyWidth;
28590
+ const padWidth = bodyLength10 * 0.53;
28591
+ const padLength = bodyWidth * 0.35;
28592
+ const padThickness = 0.2;
28593
+ const leftPadCenterX = -(fullWidth / 2 - 0.075);
28594
+ const rightPadCenterX = fullWidth / 2 - 0.075;
28595
+ const taperOffset = 0.4;
28596
+ const lowerTaperOffset = 0.1;
28597
+ const straightHeight = bodyHeight * 0.2;
28598
+ return /* @__PURE__ */ jsxs(Fragment2, { children: [
28599
+ /* @__PURE__ */ jsx2(
28600
+ Cuboid,
28601
+ {
28602
+ color: "#ccc",
28603
+ size: [padLength, padWidth, padThickness],
28604
+ center: [leftPadCenterX, 0, padThickness / 2]
28605
+ }
28606
+ ),
28607
+ /* @__PURE__ */ jsx2(
28608
+ Cuboid,
28609
+ {
28610
+ color: "#ccc",
28611
+ size: [padLength, padWidth, padThickness],
28612
+ center: [rightPadCenterX, 0, padThickness / 2]
28613
+ }
28614
+ ),
28615
+ /* @__PURE__ */ jsx2(Colorize, { color: "#222", children: /* @__PURE__ */ jsxs(Union, { children: [
28616
+ /* @__PURE__ */ jsxs(Hull, { children: [
28617
+ /* @__PURE__ */ jsx2(Translate, { z: straightHeight, children: /* @__PURE__ */ jsx2(
28618
+ Cuboid,
28619
+ {
28620
+ size: [
28621
+ fullWidth - lowerTaperOffset / 2,
28622
+ bodyLength10 - lowerTaperOffset / 2,
28623
+ 0.01
28624
+ ]
28625
+ }
28626
+ ) }),
28627
+ /* @__PURE__ */ jsx2(Translate, { z: 0.01, children: /* @__PURE__ */ jsx2(
28628
+ Cuboid,
28629
+ {
28630
+ size: [
28631
+ fullWidth - lowerTaperOffset,
28632
+ bodyLength10 - lowerTaperOffset,
28633
+ 0.01
28634
+ ]
28635
+ }
28636
+ ) })
28637
+ ] }),
28638
+ /* @__PURE__ */ jsxs(Hull, { children: [
28639
+ /* @__PURE__ */ jsx2(Translate, { z: straightHeight, children: /* @__PURE__ */ jsx2(Cuboid, { size: [fullWidth, bodyLength10, 0.01] }) }),
28640
+ /* @__PURE__ */ jsx2(Translate, { z: bodyHeight, children: /* @__PURE__ */ jsx2(
28641
+ Cuboid,
28642
+ {
28643
+ size: [fullWidth - taperOffset, bodyLength10 - taperOffset, 0.01]
28644
+ }
28645
+ ) })
28646
+ ] })
28647
+ ] }) }),
28648
+ /* @__PURE__ */ jsx2(
28649
+ Cuboid,
28650
+ {
28651
+ color: "#777",
28652
+ size: [padThickness * 2.7, bodyLength10 - taperOffset, 0.02],
28653
+ center: [leftPadCenterX + taperOffset, 0, bodyHeight]
28654
+ }
28655
+ )
28656
+ ] });
28657
+ };
28658
+ var SOD123 = ({
28659
+ fullWidth = 3.7,
28660
+ fullLength: fullLength10 = 1.55
28661
+ } = {}) => {
28662
+ const bodyWidth = fullWidth - 1;
28663
+ const bodyLength10 = fullLength10;
28664
+ const packageHeight = 1.175;
28665
+ const bodyStandoff = 0.1;
28666
+ const bodyHeight = packageHeight - bodyStandoff;
28667
+ const leadWidth = 0.55;
28668
+ const leadThickness = 0.12;
28669
+ const leadHeight = 0.35;
28670
+ const bodyDistance = (fullWidth - bodyWidth) / 2;
28671
+ const padContactLength = 0.25;
28672
+ const leadCurveLength = 0.2;
28673
+ return /* @__PURE__ */ jsxs(Fragment2, { children: [
28674
+ /* @__PURE__ */ jsx2(
28675
+ SmdChipLead,
28676
+ {
28677
+ position: {
28678
+ x: -fullWidth / 2,
28679
+ y: 0,
28680
+ z: leadThickness / 2
28681
+ },
28682
+ width: leadWidth,
28683
+ thickness: leadThickness,
28684
+ padContactLength,
28685
+ bodyDistance,
28686
+ curveLength: leadCurveLength,
28687
+ height: leadHeight
28688
+ }
28689
+ ),
28690
+ /* @__PURE__ */ jsx2(
28691
+ SmdChipLead,
28692
+ {
28693
+ rotation: Math.PI,
28694
+ position: {
28695
+ x: fullWidth / 2,
28696
+ y: 0,
28697
+ z: leadThickness / 2
28698
+ },
28699
+ width: leadWidth,
28700
+ thickness: leadThickness,
28701
+ padContactLength,
28702
+ bodyDistance,
28703
+ curveLength: leadCurveLength,
28704
+ height: leadHeight
28705
+ }
28706
+ ),
28707
+ /* @__PURE__ */ jsx2(
28708
+ ChipBody,
28709
+ {
28710
+ center: { x: 0, y: 0, z: 0 },
28711
+ width: bodyWidth,
28712
+ length: bodyLength10,
28713
+ height: bodyHeight,
28714
+ heightAboveSurface: bodyStandoff,
28715
+ includeNotch: false,
28716
+ color: "#222",
28717
+ taperRatio: 0.06,
28718
+ straightHeightRatio: 0.6
28719
+ }
28720
+ ),
28721
+ /* @__PURE__ */ jsx2(
28722
+ Cuboid,
28723
+ {
28724
+ color: "#777",
28725
+ size: [0.45, bodyLength10 - 0.15, 0.02],
28726
+ center: [-bodyWidth / 4, 0, packageHeight]
28727
+ }
28728
+ )
28729
+ ] });
28730
+ };
28731
+ var SOD128 = () => {
28732
+ const fullWidth = 3.8;
28733
+ const bodyLength10 = 2.5;
28092
28734
  const bodyHeight = 1;
28093
- const padWidth = 0.9;
28735
+ const padWidth = 1.75;
28094
28736
  const padLength = 0.9;
28095
28737
  const padThickness = 0.2;
28096
28738
  const leftPadCenterX = -(fullWidth / 2 - 0.075);
28097
28739
  const rightPadCenterX = fullWidth / 2 - 0.075;
28098
28740
  const taperOffset = 0.4;
28099
- const lowerTaperOffset = 0.1;
28100
- const straightHeight = bodyHeight * 0.2;
28101
- return /* @__PURE__ */ jsxs(Fragment2, { children: [
28102
- /* @__PURE__ */ jsx2(
28103
- Cuboid,
28104
- {
28105
- color: "#ccc",
28106
- size: [padLength, padWidth, padThickness],
28107
- center: [leftPadCenterX, 0, padThickness / 2]
28108
- }
28109
- ),
28110
- /* @__PURE__ */ jsx2(
28111
- Cuboid,
28112
- {
28113
- color: "#ccc",
28114
- size: [padLength, padWidth, padThickness],
28115
- center: [rightPadCenterX, 0, padThickness / 2]
28116
- }
28117
- ),
28118
- /* @__PURE__ */ jsx2(Colorize, { color: "#222", children: /* @__PURE__ */ jsxs(Union, { children: [
28119
- /* @__PURE__ */ jsxs(Hull, { children: [
28120
- /* @__PURE__ */ jsx2(Translate, { z: straightHeight, children: /* @__PURE__ */ jsx2(
28121
- Cuboid,
28122
- {
28123
- size: [
28124
- fullWidth - lowerTaperOffset / 2,
28125
- bodyLength10 - lowerTaperOffset / 2,
28126
- 0.01
28127
- ]
28128
- }
28129
- ) }),
28130
- /* @__PURE__ */ jsx2(Translate, { z: 0.01, children: /* @__PURE__ */ jsx2(
28131
- Cuboid,
28132
- {
28133
- size: [
28134
- fullWidth - lowerTaperOffset,
28135
- bodyLength10 - lowerTaperOffset,
28136
- 0.01
28137
- ]
28138
- }
28139
- ) })
28140
- ] }),
28141
- /* @__PURE__ */ jsxs(Hull, { children: [
28142
- /* @__PURE__ */ jsx2(Translate, { z: straightHeight, children: /* @__PURE__ */ jsx2(Cuboid, { size: [fullWidth, bodyLength10, 0.01] }) }),
28143
- /* @__PURE__ */ jsx2(Translate, { z: bodyHeight, children: /* @__PURE__ */ jsx2(
28144
- Cuboid,
28145
- {
28146
- size: [fullWidth - taperOffset, bodyLength10 - taperOffset, 0.01]
28147
- }
28148
- ) })
28149
- ] })
28150
- ] }) }),
28151
- /* @__PURE__ */ jsx2(
28152
- Cuboid,
28153
- {
28154
- color: "#777",
28155
- size: [padThickness * 2.7, bodyLength10 - taperOffset, 0.02],
28156
- center: [leftPadCenterX + taperOffset, 0, bodyHeight]
28157
- }
28158
- )
28159
- ] });
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
- };
28234
- var SOD128 = () => {
28235
- const fullWidth = 3.8;
28236
- const bodyLength10 = 2.5;
28237
- const bodyHeight = 1;
28238
- const padWidth = 1.75;
28239
- const padLength = 0.9;
28240
- const padThickness = 0.2;
28241
- const leftPadCenterX = -(fullWidth / 2 - 0.075);
28242
- const rightPadCenterX = fullWidth / 2 - 0.075;
28243
- const taperOffset = 0.4;
28244
- const lowerTaperOffset = 0.05;
28741
+ const lowerTaperOffset = 0.05;
28245
28742
  const straightHeight = bodyHeight * 0.2;
28246
28743
  return /* @__PURE__ */ jsxs(Fragment2, { children: [
28247
28744
  /* @__PURE__ */ jsx2(
@@ -28345,17 +28842,19 @@ var SOD923 = () => {
28345
28842
  ] }) })
28346
28843
  ] });
28347
28844
  };
28348
- var SOT223 = () => {
28349
- const fullWidth = 6.6;
28350
- const bodyWidth = 3.5;
28351
- const bodyLength10 = 6.5;
28352
- const bodyHeight = 1.7;
28353
- const leadWidth = 0.7;
28354
- const leftLeadWidth = 3;
28845
+ var SOT223 = ({
28846
+ fullWidth = 6.6,
28847
+ bodyWidth = 3.5,
28848
+ bodyLength: bodyLength10 = 6.5,
28849
+ bodyHeight = 1.7,
28850
+ leadWidth = 0.7,
28851
+ tabLeadWidth = 3,
28852
+ padPitch = 2.3,
28853
+ leadHeight = 0.75
28854
+ } = {}) => {
28855
+ const leftLeadWidth = tabLeadWidth;
28355
28856
  const leadThickness = 0.25;
28356
- const leadHeight = 0.75;
28357
28857
  const padContactLength = 0.5;
28358
- const padPitch = 2.3;
28359
28858
  const extendedBodyDistance = fullWidth - bodyWidth;
28360
28859
  return /* @__PURE__ */ jsxs(Fragment2, { children: [
28361
28860
  /* @__PURE__ */ jsx2(
@@ -29187,78 +29686,67 @@ var MS013 = ({
29187
29686
  )
29188
29687
  ] });
29189
29688
  };
29190
- var TO220 = () => {
29191
- const fullLength10 = 20;
29192
- const bodyLength10 = 9.9;
29193
- const bodyHeight = 4.5;
29194
- const zOffset = 1;
29195
- const padWidth = 9.9;
29196
- const padLength = 6.5;
29197
- const padThickness = 1.3;
29198
- const padHoleDiameter = 3;
29199
- const prongWidth = 0.81;
29200
- const prongLength = 16;
29201
- const prongHeight = 0.5;
29202
- const prongPitch = 2.7;
29203
- const bodyWidth = padWidth;
29204
- const bodyFrontX = fullLength10 - bodyLength10 / 2;
29205
- const bodyBackX = fullLength10 + bodyLength10 / 2;
29206
- const prongCenterX = bodyFrontX - prongLength / 2;
29207
- const padCenterX = bodyBackX + padLength / 2;
29208
- return /* @__PURE__ */ jsx2(Translate, { center: [0, 0, zOffset], children: /* @__PURE__ */ jsxs(Fragment2, { children: [
29209
- /* @__PURE__ */ jsxs(Rotate, { rotation: [0, 55, -55], children: [
29210
- /* @__PURE__ */ jsxs(Subtract, { children: [
29211
- /* @__PURE__ */ jsx2(
29212
- Cuboid,
29213
- {
29214
- color: "#ccc",
29215
- size: [padLength + 0.1, padWidth, padThickness],
29216
- center: [padCenterX, 0, padThickness - 2]
29217
- }
29218
- ),
29219
- /* @__PURE__ */ jsx2(
29220
- Cylinder,
29221
- {
29222
- color: "black",
29223
- center: [padCenterX, 0, padThickness - 2],
29224
- radius: padHoleDiameter / 2,
29225
- height: padThickness * 1.2
29226
- }
29227
- )
29228
- ] }),
29229
- /* @__PURE__ */ jsx2(Colorize, { color: "#222", children: /* @__PURE__ */ jsx2(
29230
- ChipBody,
29689
+ var TO220_DEFAULT_LEADS = [
29690
+ { x: -2.54, y: -1 },
29691
+ { x: 0, y: -1 },
29692
+ { x: 2.54, y: -1 }
29693
+ ];
29694
+ var TO220 = ({
29695
+ mouldedTab = false,
29696
+ leads = TO220_DEFAULT_LEADS,
29697
+ bodyWidth = 10,
29698
+ bodyThickness = 4.5,
29699
+ bodyHeight = 9.2,
29700
+ tabHeight = 6.4,
29701
+ tabThickness = 1.4,
29702
+ mountingHoleDiameter = 3.6,
29703
+ standoff = 3,
29704
+ leadLength = 3,
29705
+ bodyColor = "#222",
29706
+ tabColor = "#ccc",
29707
+ leadColor = "#d4b106"
29708
+ } = {}) => {
29709
+ const centerX = leads.reduce((sum, lead) => sum + lead.x, 0) / leads.length;
29710
+ const centerY = leads.reduce((sum, lead) => sum + lead.y, 0) / leads.length;
29711
+ const bodyBottom = standoff;
29712
+ const bodyTop = bodyBottom + bodyHeight;
29713
+ const tabTop = bodyTop + tabHeight;
29714
+ const tabY = centerY + (bodyThickness - tabThickness) / 2;
29715
+ const holeZ = tabTop - Math.max(mountingHoleDiameter * 0.8, 2.6);
29716
+ const leadWidth = 0.8;
29717
+ const leadThickness = 0.5;
29718
+ return /* @__PURE__ */ jsxs(Fragment2, { children: [
29719
+ /* @__PURE__ */ jsx2(Colorize, { color: bodyColor, children: /* @__PURE__ */ jsx2(
29720
+ Cuboid,
29721
+ {
29722
+ size: [bodyWidth, bodyThickness, bodyHeight],
29723
+ center: [centerX, centerY, bodyBottom + bodyHeight / 2]
29724
+ }
29725
+ ) }),
29726
+ /* @__PURE__ */ jsx2(Colorize, { color: mouldedTab ? bodyColor : tabColor, children: /* @__PURE__ */ jsxs(Subtract, { children: [
29727
+ /* @__PURE__ */ jsx2(
29728
+ Cuboid,
29231
29729
  {
29232
- width: bodyWidth,
29233
- length: bodyLength10,
29234
- height: bodyHeight,
29235
- center: { x: fullLength10, y: 0, z: -2.4 },
29236
- includeNotch: false,
29237
- straightHeightRatio: 0.3,
29238
- taperRatio: 0.04,
29239
- heightAboveSurface: 1
29730
+ size: [bodyWidth, tabThickness, tabHeight],
29731
+ center: [centerX, tabY, bodyTop + tabHeight / 2]
29240
29732
  }
29241
- ) })
29242
- ] }),
29243
- /* @__PURE__ */ jsx2(Rotate, { rotation: [0, 55, 55], children: Array.from({ length: 3 }).map((_, i) => {
29244
- const x = prongCenterX;
29245
- const y = (i - 1) * prongPitch;
29246
- const z21 = -prongHeight - 0.6;
29247
- return /* @__PURE__ */ jsxs(Colorize, { color: "gold", children: [
29248
- /* @__PURE__ */ jsxs(Hull, { children: [
29249
- /* @__PURE__ */ jsx2(Translate, { center: [bodyFrontX - bodyHeight / 2 + 0.1, y, z21], children: /* @__PURE__ */ jsx2(Cuboid, { size: [bodyHeight, prongWidth + 1, prongHeight] }) }),
29250
- /* @__PURE__ */ jsx2(
29251
- Translate,
29252
- {
29253
- center: [bodyFrontX - bodyHeight / 2 - 1 + 0.1, y, z21],
29254
- children: /* @__PURE__ */ jsx2(Cuboid, { size: [bodyHeight, prongWidth, prongHeight] })
29255
- }
29256
- )
29257
- ] }),
29258
- /* @__PURE__ */ jsx2(Translate, { center: [x, y, z21], children: /* @__PURE__ */ jsx2(Cuboid, { size: [prongLength + 0.1, prongWidth, prongHeight] }) })
29259
- ] }, `prong-${i}`);
29260
- }) })
29261
- ] }) });
29733
+ ),
29734
+ /* @__PURE__ */ jsx2(Rotate, { rotation: ["90deg", 0, 0], children: /* @__PURE__ */ jsx2(Translate, { center: [centerX, holeZ, -tabY], children: /* @__PURE__ */ jsx2(
29735
+ Cylinder,
29736
+ {
29737
+ radius: mountingHoleDiameter / 2,
29738
+ height: tabThickness * 3
29739
+ }
29740
+ ) }) })
29741
+ ] }) }),
29742
+ leads.map((lead) => /* @__PURE__ */ jsx2(Colorize, { color: leadColor, children: /* @__PURE__ */ jsx2(
29743
+ Cuboid,
29744
+ {
29745
+ size: [leadWidth, leadThickness, standoff + leadLength],
29746
+ center: [lead.x, lead.y, (standoff - leadLength) / 2]
29747
+ }
29748
+ ) }, `lead-${lead.x}-${lead.y}`))
29749
+ ] });
29262
29750
  };
29263
29751
  var SOT457 = () => {
29264
29752
  const fullWidth = 2.8;
@@ -29450,39 +29938,95 @@ var SOT963 = () => {
29450
29938
  })
29451
29939
  ] });
29452
29940
  };
29453
- var TO92 = () => {
29454
- const bodyRadius = 2.4;
29455
- const bodyHeight = 4.5;
29456
- const flatCut = 1.1;
29941
+ var TO92_DEFAULT_LEADS = [
29942
+ { x: -1.27, y: 0.98 },
29943
+ { x: 0, y: 2.25 },
29944
+ { x: 1.27, y: 0.98 }
29945
+ ];
29946
+ var splitOuterLeads = (leads) => {
29947
+ let outer = [leads[0], leads[leads.length - 1]];
29948
+ let best = -1;
29949
+ for (let i = 0; i < leads.length; i++) {
29950
+ for (let j = i + 1; j < leads.length; j++) {
29951
+ const separation = Math.hypot(
29952
+ leads[i].x - leads[j].x,
29953
+ leads[i].y - leads[j].y
29954
+ );
29955
+ if (separation > best) {
29956
+ best = separation;
29957
+ outer = [leads[i], leads[j]];
29958
+ }
29959
+ }
29960
+ }
29961
+ return { outer, separation: best };
29962
+ };
29963
+ var TO92 = ({
29964
+ bodyDiameter = 4.8,
29965
+ bodyHeight = 4.5,
29966
+ flatCut = 1.1,
29967
+ leads = TO92_DEFAULT_LEADS,
29968
+ standoff = 1.5,
29969
+ leadLength = 3,
29970
+ bodyColor = "#222"
29971
+ } = {}) => {
29972
+ const bodyRadius = bodyDiameter / 2;
29457
29973
  const legWidth = 0.4;
29458
29974
  const legThickness = 0.25;
29459
- const bodyZ = bodyHeight / 2;
29460
- const bodyColor = "#222";
29461
- const leadLength = 0.43;
29462
- const leadTipSize = [leadLength, legWidth, 1.32];
29463
- const leadSmallSize = [
29464
- leadLength,
29975
+ const { outer, separation } = splitOuterLeads(leads);
29976
+ const [first, last] = outer;
29977
+ const bodyCenter = {
29978
+ x: (first.x + last.x) / 2,
29979
+ y: (first.y + last.y) / 2
29980
+ };
29981
+ const axisLength = Math.max(separation, 1e-3);
29982
+ const axis = {
29983
+ x: (last.x - first.x) / axisLength,
29984
+ y: (last.y - first.y) / axisLength
29985
+ };
29986
+ const exitPitch = separation / 2;
29987
+ const exitFor = (index2) => {
29988
+ const offset4 = (index2 - (leads.length - 1) / 2) * exitPitch;
29989
+ return {
29990
+ x: bodyCenter.x + axis.x * offset4,
29991
+ y: bodyCenter.y + axis.y * offset4
29992
+ };
29993
+ };
29994
+ const leadSize = [
29995
+ legThickness,
29465
29996
  legWidth,
29466
29997
  legThickness
29467
29998
  ];
29468
- const leadTipPos1 = [0, 0, -0.66];
29469
- const leadMidPosA = [0, 0, -1.32];
29470
- const leadMidPosB = [0, 1.28, -2.72];
29471
- const leadTipPos2 = [0, 1.28, -8.9];
29472
- const sideLeadZ = -7.5;
29473
- return /* @__PURE__ */ jsxs(Translate, { center: [0, 1, 10.5], children: [
29999
+ return /* @__PURE__ */ jsxs(Fragment2, { children: [
29474
30000
  /* @__PURE__ */ jsx2(Colorize, { color: bodyColor, children: /* @__PURE__ */ jsxs(Subtract, { children: [
29475
- /* @__PURE__ */ jsx2(Translate, { center: [0, 0, bodyZ], children: /* @__PURE__ */ jsx2(Cylinder, { radius: bodyRadius, height: bodyHeight }) }),
29476
- /* @__PURE__ */ jsx2(Translate, { center: [0, -(bodyRadius - flatCut / 2), bodyZ], children: /* @__PURE__ */ jsx2(Cuboid, { size: [bodyRadius * 2, flatCut, bodyHeight + 0.2] }) })
30001
+ /* @__PURE__ */ jsx2(
30002
+ Translate,
30003
+ {
30004
+ center: [bodyCenter.x, bodyCenter.y, standoff + bodyHeight / 2],
30005
+ children: /* @__PURE__ */ jsx2(Cylinder, { radius: bodyRadius, height: bodyHeight })
30006
+ }
30007
+ ),
30008
+ /* @__PURE__ */ jsx2(
30009
+ Translate,
30010
+ {
30011
+ center: [
30012
+ bodyCenter.x,
30013
+ bodyCenter.y - (bodyRadius - flatCut / 2),
30014
+ standoff + bodyHeight / 2
30015
+ ],
30016
+ children: /* @__PURE__ */ jsx2(Cuboid, { size: [bodyRadius * 2, flatCut, bodyHeight + 0.2] })
30017
+ }
30018
+ )
29477
30019
  ] }) }),
29478
- /* @__PURE__ */ jsx2(Translate, { center: leadTipPos1, children: /* @__PURE__ */ jsx2(Cuboid, { size: leadTipSize }) }),
29479
- /* @__PURE__ */ jsxs(Hull, { children: [
29480
- /* @__PURE__ */ jsx2(Translate, { center: leadMidPosA, children: /* @__PURE__ */ jsx2(Cuboid, { size: leadSmallSize }) }),
29481
- /* @__PURE__ */ jsx2(Translate, { center: leadMidPosB, children: /* @__PURE__ */ jsx2(Cuboid, { size: leadSmallSize }) })
29482
- ] }),
29483
- /* @__PURE__ */ jsx2(Translate, { center: leadTipPos2, children: /* @__PURE__ */ jsx2(Cuboid, { size: [leadLength, legWidth, 12.2] }) }),
29484
- /* @__PURE__ */ jsx2(Translate, { center: [1.3, 0, sideLeadZ], children: /* @__PURE__ */ jsx2(Cuboid, { size: [leadLength, legWidth, 15] }) }),
29485
- /* @__PURE__ */ jsx2(Translate, { center: [-1.3, 0, sideLeadZ], children: /* @__PURE__ */ jsx2(Cuboid, { size: [leadLength, legWidth, 15] }) })
30020
+ leads.map((lead, index2) => {
30021
+ const exit = exitFor(index2);
30022
+ return /* @__PURE__ */ jsxs(Translate, { center: [0, 0, 0], children: [
30023
+ /* @__PURE__ */ jsxs(Hull, { children: [
30024
+ /* @__PURE__ */ jsx2(Translate, { center: [lead.x, lead.y, 0], children: /* @__PURE__ */ jsx2(Cuboid, { size: leadSize }) }),
30025
+ /* @__PURE__ */ jsx2(Translate, { center: [exit.x, exit.y, standoff], children: /* @__PURE__ */ jsx2(Cuboid, { size: leadSize }) })
30026
+ ] }),
30027
+ /* @__PURE__ */ jsx2(Translate, { center: [lead.x, lead.y, -leadLength / 2], children: /* @__PURE__ */ jsx2(Cuboid, { size: [legThickness, legWidth, leadLength] }) })
30028
+ ] }, `lead-${lead.x}-${lead.y}`);
30029
+ })
29486
30030
  ] });
29487
30031
  };
29488
30032
  var SOT363 = () => {
@@ -29672,8 +30216,8 @@ var SOT886 = () => {
29672
30216
  };
29673
30217
  var SOD323 = () => {
29674
30218
  const fullWidth = 2.5;
29675
- const bodyLength10 = 1.25;
29676
- const bodyWidth = 1.7;
30219
+ const bodyLength10 = 1.4;
30220
+ const bodyWidth = 1.8;
29677
30221
  const bodyHeight = 0.95;
29678
30222
  const leadWidth = 0.3;
29679
30223
  const leadThickness = 0.175;
@@ -30232,7 +30776,7 @@ var MountedPcbModule = ({
30232
30776
  shortSidePinLength,
30233
30777
  longSidePinLength,
30234
30778
  bodyHeight: pinBodyHeight,
30235
- flipZ: (z21) => z21
30779
+ flipZ: (z22) => z22
30236
30780
  },
30237
30781
  `pin-3d-${index2}`
30238
30782
  ));
@@ -30241,7 +30785,7 @@ var MountedPcbModule = ({
30241
30785
  {
30242
30786
  x: pin.x,
30243
30787
  y: pin.y,
30244
- flipZ: (z21) => -z21
30788
+ flipZ: (z22) => -z22
30245
30789
  },
30246
30790
  `female-pin-3d-${index2}`
30247
30791
  ));
@@ -30464,6 +31008,309 @@ var JSTZH1_5mm = ({
30464
31008
  })
30465
31009
  ] });
30466
31010
  };
31011
+ var JSTPH2_0mm = ({
31012
+ numPins = 2,
31013
+ showPins = true,
31014
+ showFootprint = true,
31015
+ bodyColor = "#f5f5f5",
31016
+ pinColor = "#635959"
31017
+ }) => {
31018
+ const pitch = 2;
31019
+ const bodyHeight = 6;
31020
+ const bodyDepth = 4.5;
31021
+ const wallThickness = 0.5;
31022
+ const hollowHeight = bodyHeight * 0.6;
31023
+ const pinTailLength = 3.4;
31024
+ const pinTop = 5.5;
31025
+ const pinThickness = 0.5;
31026
+ const pinLength = pinTailLength + pinTop;
31027
+ const bodyWidth = (numPins - 1) * pitch + 3.9;
31028
+ const startX = -((numPins - 1) * pitch) / 2;
31029
+ const latchWindowWidth = 1;
31030
+ const latchWindowHeight = 1.8;
31031
+ const latchWindowInset = 0.7;
31032
+ const topReliefWidth = 0.8;
31033
+ const topReliefDepth = 0.65;
31034
+ return /* @__PURE__ */ jsxs(Fragment2, { children: [
31035
+ /* @__PURE__ */ jsx2(Translate, { offset: [0, 0, bodyHeight], children: /* @__PURE__ */ jsx2(Rotate, { angles: [Math.PI, 0, 0], children: /* @__PURE__ */ jsx2(Colorize, { color: bodyColor, children: /* @__PURE__ */ jsxs(Subtract, { children: [
31036
+ /* @__PURE__ */ jsx2(
31037
+ Cuboid,
31038
+ {
31039
+ size: [bodyWidth, bodyDepth, bodyHeight],
31040
+ center: [0, 0, bodyHeight / 2]
31041
+ }
31042
+ ),
31043
+ /* @__PURE__ */ jsx2(
31044
+ Cuboid,
31045
+ {
31046
+ size: [
31047
+ bodyWidth - wallThickness * 2,
31048
+ bodyDepth - wallThickness * 2,
31049
+ hollowHeight
31050
+ ],
31051
+ center: [0, 0, hollowHeight / 2]
31052
+ }
31053
+ ),
31054
+ /* @__PURE__ */ jsx2(
31055
+ Cuboid,
31056
+ {
31057
+ size: [bodyWidth, bodyDepth / 3, hollowHeight],
31058
+ center: [0, 0, hollowHeight / 6]
31059
+ }
31060
+ ),
31061
+ /* @__PURE__ */ jsx2(
31062
+ Cuboid,
31063
+ {
31064
+ size: [
31065
+ bodyWidth - wallThickness * 2,
31066
+ wallThickness / 2,
31067
+ hollowHeight
31068
+ ],
31069
+ center: [
31070
+ 0,
31071
+ bodyDepth / 2 - wallThickness / 4,
31072
+ hollowHeight / 2
31073
+ ]
31074
+ }
31075
+ ),
31076
+ /* @__PURE__ */ jsx2(
31077
+ Cuboid,
31078
+ {
31079
+ size: [
31080
+ bodyWidth - wallThickness * 2,
31081
+ wallThickness / 2,
31082
+ hollowHeight
31083
+ ],
31084
+ center: [
31085
+ 0,
31086
+ -bodyDepth / 2 + wallThickness / 4,
31087
+ hollowHeight / 2
31088
+ ]
31089
+ }
31090
+ ),
31091
+ /* @__PURE__ */ jsx2(
31092
+ Cuboid,
31093
+ {
31094
+ size: [
31095
+ latchWindowWidth,
31096
+ bodyDepth + wallThickness,
31097
+ latchWindowHeight
31098
+ ],
31099
+ center: [-bodyWidth / 2 + latchWindowInset, 0, bodyHeight / 2]
31100
+ }
31101
+ ),
31102
+ /* @__PURE__ */ jsx2(
31103
+ Cuboid,
31104
+ {
31105
+ size: [
31106
+ latchWindowWidth,
31107
+ bodyDepth + wallThickness,
31108
+ latchWindowHeight
31109
+ ],
31110
+ center: [bodyWidth / 2 - latchWindowInset, 0, bodyHeight / 2]
31111
+ }
31112
+ ),
31113
+ /* @__PURE__ */ jsx2(
31114
+ Cuboid,
31115
+ {
31116
+ size: [wallThickness * 3, topReliefWidth, topReliefDepth],
31117
+ center: [-bodyWidth / 2, 0, topReliefDepth / 2]
31118
+ }
31119
+ ),
31120
+ /* @__PURE__ */ jsx2(Translate, { offset: [-bodyWidth / 2, 0, topReliefDepth], children: /* @__PURE__ */ jsx2(Rotate, { angles: [0, Math.PI / 2, 0], children: /* @__PURE__ */ jsx2(
31121
+ Cylinder,
31122
+ {
31123
+ height: wallThickness * 3,
31124
+ radius: topReliefWidth / 2
31125
+ }
31126
+ ) }) }),
31127
+ /* @__PURE__ */ jsx2(
31128
+ Cuboid,
31129
+ {
31130
+ size: [wallThickness * 3, topReliefWidth, topReliefDepth],
31131
+ center: [bodyWidth / 2, 0, topReliefDepth / 2]
31132
+ }
31133
+ ),
31134
+ /* @__PURE__ */ jsx2(Translate, { offset: [bodyWidth / 2, 0, topReliefDepth], children: /* @__PURE__ */ jsx2(Rotate, { angles: [0, Math.PI / 2, 0], children: /* @__PURE__ */ jsx2(
31135
+ Cylinder,
31136
+ {
31137
+ height: wallThickness * 3,
31138
+ radius: topReliefWidth / 2
31139
+ }
31140
+ ) }) })
31141
+ ] }) }) }) }),
31142
+ showPins && Array.from({ length: numPins }).map((_, i) => /* @__PURE__ */ jsx2(Colorize, { color: pinColor, children: /* @__PURE__ */ jsx2(
31143
+ Cuboid,
31144
+ {
31145
+ size: [pinThickness, pinThickness, pinLength],
31146
+ center: [startX + i * pitch, 0, (pinTop - pinTailLength) / 2]
31147
+ }
31148
+ ) }, i)),
31149
+ showFootprint && Array.from({ length: numPins }).map((_, i) => {
31150
+ const isPin1 = i === 0;
31151
+ const hole = isPin1 ? {
31152
+ type: "pcb_plated_hole",
31153
+ pcb_plated_hole_id: `jstph_${i}`,
31154
+ shape: "circular_hole_with_rect_pad",
31155
+ x: startX + i * pitch,
31156
+ y: 0,
31157
+ hole_diameter: 0.73,
31158
+ rect_pad_width: 1.2,
31159
+ rect_pad_height: 1.2,
31160
+ hole_shape: "circle",
31161
+ pad_shape: "rect",
31162
+ layers: ["top", "bottom"],
31163
+ port_hints: [`${i + 1}`]
31164
+ } : {
31165
+ type: "pcb_plated_hole",
31166
+ pcb_plated_hole_id: `jstph_${i}`,
31167
+ shape: "pill",
31168
+ x: startX + i * pitch,
31169
+ y: 0,
31170
+ hole_height: 0.73,
31171
+ hole_width: 0.73,
31172
+ outer_height: 1.2,
31173
+ outer_width: 1.2,
31174
+ layers: ["top", "bottom"],
31175
+ port_hints: [`${i + 1}`]
31176
+ };
31177
+ return /* @__PURE__ */ jsx2(
31178
+ FootprintPlatedHole,
31179
+ {
31180
+ hole,
31181
+ isPin1
31182
+ },
31183
+ `footprint_${i}`
31184
+ );
31185
+ })
31186
+ ] });
31187
+ };
31188
+ var JSTXH2_5mm = ({
31189
+ numPins = 4,
31190
+ showPins = true,
31191
+ showFootprint = true,
31192
+ bodyColor = "#f8fafc",
31193
+ // Natural white PA 66 nylon housing per spec
31194
+ pinColor = "#635959"
31195
+ // Tin-plated metallic gray posts
31196
+ }) => {
31197
+ const pitch = 2.5;
31198
+ const bodyHeight = 7;
31199
+ const bodyDepth = 5.75;
31200
+ const wallThickness = 0.85;
31201
+ const floorThickness = 1.65;
31202
+ const hollowHeight = bodyHeight - floorThickness;
31203
+ const pinLength = 8.75;
31204
+ const bodyWidth = (numPins - 1) * pitch + 4.9;
31205
+ const startX = -((numPins - 1) * pitch) / 2;
31206
+ const keySlotWidth = 0.8;
31207
+ const keySlotDepth = wallThickness + 0.2;
31208
+ const keySlotHeight = 3.5;
31209
+ const keySlotX = bodyWidth / 2 - 1.3;
31210
+ const lockNotchWidth = Math.min(
31211
+ bodyWidth - 3.4,
31212
+ Math.max(3, (numPins - 1) * pitch * 0.4 + 2.2)
31213
+ );
31214
+ const lockNotchHeight = 2.4;
31215
+ return /* @__PURE__ */ jsxs(Fragment2, { children: [
31216
+ /* @__PURE__ */ jsx2(Translate, { offset: [0, 0, bodyHeight / 2], children: /* @__PURE__ */ jsx2(Colorize, { color: bodyColor, children: /* @__PURE__ */ jsxs(Subtract, { children: [
31217
+ /* @__PURE__ */ jsx2(Cuboid, { size: [bodyWidth, bodyDepth, bodyHeight] }),
31218
+ /* @__PURE__ */ jsx2(Translate, { offset: [0, 0, (bodyHeight - hollowHeight) / 2 + 0.1], children: /* @__PURE__ */ jsx2(
31219
+ Cuboid,
31220
+ {
31221
+ size: [
31222
+ bodyWidth - wallThickness * 2,
31223
+ bodyDepth - wallThickness * 2,
31224
+ hollowHeight + 0.2
31225
+ ]
31226
+ }
31227
+ ) }),
31228
+ /* @__PURE__ */ jsx2(
31229
+ Translate,
31230
+ {
31231
+ offset: [
31232
+ 0,
31233
+ -bodyDepth / 2 + wallThickness / 2,
31234
+ bodyHeight / 2 - lockNotchHeight / 2 + 0.1
31235
+ ],
31236
+ children: /* @__PURE__ */ jsx2(
31237
+ Cuboid,
31238
+ {
31239
+ size: [
31240
+ lockNotchWidth,
31241
+ wallThickness + 0.2,
31242
+ lockNotchHeight + 0.2
31243
+ ]
31244
+ }
31245
+ )
31246
+ }
31247
+ ),
31248
+ /* @__PURE__ */ jsx2(
31249
+ Translate,
31250
+ {
31251
+ offset: [
31252
+ -keySlotX,
31253
+ -bodyDepth / 2 + wallThickness / 2,
31254
+ bodyHeight / 2 - keySlotHeight / 2 + 0.1
31255
+ ],
31256
+ children: /* @__PURE__ */ jsx2(
31257
+ Cuboid,
31258
+ {
31259
+ size: [keySlotWidth, keySlotDepth, keySlotHeight + 0.2]
31260
+ }
31261
+ )
31262
+ }
31263
+ ),
31264
+ /* @__PURE__ */ jsx2(
31265
+ Translate,
31266
+ {
31267
+ offset: [
31268
+ keySlotX,
31269
+ -bodyDepth / 2 + wallThickness / 2,
31270
+ bodyHeight / 2 - keySlotHeight / 2 + 0.1
31271
+ ],
31272
+ children: /* @__PURE__ */ jsx2(
31273
+ Cuboid,
31274
+ {
31275
+ size: [keySlotWidth, keySlotDepth, keySlotHeight + 0.2]
31276
+ }
31277
+ )
31278
+ }
31279
+ ),
31280
+ Array.from({ length: numPins }).map((_, i) => /* @__PURE__ */ jsx2(
31281
+ Translate,
31282
+ {
31283
+ offset: [
31284
+ startX + i * pitch,
31285
+ -bodyDepth / 2 + 0.3,
31286
+ -bodyHeight / 2 + 0.25
31287
+ ],
31288
+ children: /* @__PURE__ */ jsx2(Cuboid, { size: [1, 0.8, 0.5] })
31289
+ },
31290
+ `vent_${i}`
31291
+ ))
31292
+ ] }) }) }),
31293
+ showPins && Array.from({ length: numPins }).map((_, i) => /* @__PURE__ */ jsx2(Colorize, { color: pinColor, children: /* @__PURE__ */ jsx2(Translate, { offset: [startX + i * pitch, 0, pinLength / 2 - 3.4], children: /* @__PURE__ */ jsx2(Cuboid, { size: [0.64, 0.64, pinLength] }) }) }, i)),
31294
+ showFootprint && (() => {
31295
+ try {
31296
+ const circuitJson = fp.string(`jst${numPins}_xh`).circuitJson();
31297
+ const platedHoles = circuitJson.filter(
31298
+ (e) => e.type === "pcb_plated_hole"
31299
+ );
31300
+ return platedHoles.map((hole, i) => /* @__PURE__ */ jsx2(
31301
+ FootprintPlatedHole,
31302
+ {
31303
+ hole,
31304
+ isPin1: i === 0
31305
+ },
31306
+ `footprint_${i}`
31307
+ ));
31308
+ } catch {
31309
+ return null;
31310
+ }
31311
+ })()
31312
+ ] });
31313
+ };
30467
31314
  var getTerminalPoints = ([centerX, centerY], width10, length64, chamfer, isPinOne) => {
30468
31315
  const xDirection = Math.sign(centerX);
30469
31316
  const yDirection = Math.sign(centerY);
@@ -30492,7 +31339,7 @@ var getRoundedRectProfile = ({
30492
31339
  length: length64,
30493
31340
  radius,
30494
31341
  height: height10,
30495
- z: z21
31342
+ z: z22
30496
31343
  }) => {
30497
31344
  const x = width10 / 2 - radius;
30498
31345
  const y = length64 / 2 - radius;
@@ -30504,11 +31351,11 @@ var getRoundedRectProfile = ({
30504
31351
  ].map(([cornerX, cornerY], index2) => /* @__PURE__ */ jsx2(
30505
31352
  Cylinder,
30506
31353
  {
30507
- center: [cornerX, cornerY, z21 + height10 / 2],
31354
+ center: [cornerX, cornerY, z22 + height10 / 2],
30508
31355
  height: height10,
30509
31356
  radius
30510
31357
  },
30511
- `${z21}-${index2}`
31358
+ `${z22}-${index2}`
30512
31359
  ));
30513
31360
  };
30514
31361
  var Crystal = ({
@@ -30931,6 +31778,76 @@ var SmdPinHeader = ({
30931
31778
  ] }, index2);
30932
31779
  }) });
30933
31780
  };
31781
+ var getPlatedHoleCenters = (footprint) => {
31782
+ const elements = fp.string(footprint).circuitJson();
31783
+ return elements.filter(
31784
+ (element) => element.type === "pcb_plated_hole" && Number.isFinite(element.x) && Number.isFinite(element.y)
31785
+ ).map((element) => ({
31786
+ x: element.x,
31787
+ y: element.y,
31788
+ pin: element.port_hints?.[0]
31789
+ }));
31790
+ };
31791
+ var getSmtPadRects = (footprint) => {
31792
+ const elements = fp.string(footprint).circuitJson();
31793
+ return elements.filter(
31794
+ (element) => element.type === "pcb_smtpad" && element.shape === "rect" && Number.isFinite(element.x) && Number.isFinite(element.y)
31795
+ ).map((element) => ({
31796
+ x: element.x,
31797
+ y: element.y,
31798
+ width: element.width ?? 0.4,
31799
+ height: element.height ?? 0.4,
31800
+ pin: element.port_hints?.[0]
31801
+ }));
31802
+ };
31803
+ var GullWingBody = ({
31804
+ bodyWidth,
31805
+ bodyLength: bodyLength10,
31806
+ bodyHeight = 1,
31807
+ pads,
31808
+ leadThickness = 0.15,
31809
+ leadHeightRatio = 0.75
31810
+ }) => {
31811
+ const centerX = pads.reduce((sum, pad2) => sum + pad2.x, 0) / (pads.length || 1);
31812
+ const centerY = pads.reduce((sum, pad2) => sum + pad2.y, 0) / (pads.length || 1);
31813
+ const leadHeight = bodyHeight * leadHeightRatio;
31814
+ return /* @__PURE__ */ jsxs(Fragment2, { children: [
31815
+ /* @__PURE__ */ jsx2(
31816
+ ChipBody,
31817
+ {
31818
+ center: { x: centerX, y: centerY, z: 0 },
31819
+ width: bodyWidth,
31820
+ length: bodyLength10,
31821
+ height: bodyHeight
31822
+ }
31823
+ ),
31824
+ pads.map((pad2) => {
31825
+ const padWidth = pad2.width ?? 0.4;
31826
+ const padLength = pad2.height ?? 0.4;
31827
+ const side = pad2.x >= centerX ? 1 : -1;
31828
+ const outerX = pad2.x + side * padWidth / 2;
31829
+ const run = Math.max(Math.abs(outerX - centerX) - bodyWidth / 2, 0.1);
31830
+ const overlap = Math.min(0.15, bodyWidth * 0.15);
31831
+ return /* @__PURE__ */ jsx2(
31832
+ SmdChipLead,
31833
+ {
31834
+ rotation: side > 0 ? Math.PI : 0,
31835
+ position: {
31836
+ x: outerX,
31837
+ y: pad2.y,
31838
+ z: leadThickness / 2
31839
+ },
31840
+ width: padLength,
31841
+ thickness: leadThickness,
31842
+ padContactLength: padWidth * 0.6,
31843
+ bodyDistance: run + overlap,
31844
+ height: leadHeight
31845
+ },
31846
+ `lead-${pad2.x}-${pad2.y}`
31847
+ );
31848
+ })
31849
+ ] });
31850
+ };
30934
31851
  var ParametricChip = ({
30935
31852
  padPitch,
30936
31853
  padHeight,
@@ -31046,6 +31963,55 @@ var Led5050 = ({
31046
31963
  )
31047
31964
  ] });
31048
31965
  };
31966
+ var Led2835 = ({
31967
+ bodyWidth = 3.5,
31968
+ bodyLength: bodyLength10 = 2.8,
31969
+ bodyHeight = 0.8,
31970
+ color = "#ffe08a",
31971
+ bodyColor = "#f2f2f2",
31972
+ padColor = "#cccccc",
31973
+ pad1X = -0.9,
31974
+ pad1Width = 2.2,
31975
+ pad2X = 1.375,
31976
+ pad2Width = 1.25,
31977
+ padLength = 2.2
31978
+ } = {}) => {
31979
+ const padThickness = 0.1;
31980
+ const lensHeight = 0.15;
31981
+ const bodyCenterX = (pad1X + pad2X) / 2;
31982
+ const lensWidth = bodyWidth * 0.55;
31983
+ const lensLength = bodyLength10 * 0.55;
31984
+ return /* @__PURE__ */ jsxs(Fragment2, { children: [
31985
+ [
31986
+ { x: pad1X, w: pad1Width, key: "pad-1" },
31987
+ { x: pad2X, w: pad2Width, key: "pad-2" }
31988
+ ].map(({ x, w, key }) => /* @__PURE__ */ jsx2(Colorize, { color: padColor, children: /* @__PURE__ */ jsx2(
31989
+ Cuboid,
31990
+ {
31991
+ size: [w, padLength, padThickness],
31992
+ center: [x, 0, padThickness / 2]
31993
+ }
31994
+ ) }, key)),
31995
+ /* @__PURE__ */ jsx2(Colorize, { color: bodyColor, children: /* @__PURE__ */ jsx2(
31996
+ Cuboid,
31997
+ {
31998
+ size: [bodyWidth, bodyLength10, bodyHeight],
31999
+ center: [bodyCenterX, 0, padThickness + bodyHeight / 2]
32000
+ }
32001
+ ) }),
32002
+ /* @__PURE__ */ jsx2(Colorize, { color, children: /* @__PURE__ */ jsx2(
32003
+ Cuboid,
32004
+ {
32005
+ size: [lensWidth, lensLength, lensHeight],
32006
+ center: [
32007
+ bodyCenterX,
32008
+ 0,
32009
+ padThickness + bodyHeight + lensHeight / 2 - 0.05
32010
+ ]
32011
+ }
32012
+ ) })
32013
+ ] });
32014
+ };
31049
32015
  var range2 = (length64) => Array.from({ length: length64 }, (_, index2) => index2);
31050
32016
  var RJ45 = ({
31051
32017
  bodyWidth = 16.26,
@@ -31280,16 +32246,898 @@ var RJ45 = ({
31280
32246
  ] })
31281
32247
  ] });
31282
32248
  };
32249
+ var DPAK = ({
32250
+ bodyWidth = 6.1,
32251
+ bodyLength: bodyLength10 = 6.5,
32252
+ bodyHeight = 2.3,
32253
+ tabWidth = 6.2,
32254
+ tabLength = 5.8,
32255
+ span = 6.85,
32256
+ pitch = 2.29,
32257
+ leadWidth = 0.9,
32258
+ leadContactLength = 1.5,
32259
+ color = "#222",
32260
+ tabColor = "#cccccc",
32261
+ leadColor = "#cccccc"
32262
+ }) => {
32263
+ const tabThickness = 0.5;
32264
+ const tabCenterX = span / 2;
32265
+ const leadPadX = -span / 2;
32266
+ const bodyCenterX = tabCenterX + (tabWidth - bodyWidth) / 2;
32267
+ const bodyFrontX = bodyCenterX - bodyWidth / 2;
32268
+ const leadZ = tabThickness / 2;
32269
+ const leadThickness = 0.4;
32270
+ return /* @__PURE__ */ jsxs(Fragment2, { children: [
32271
+ /* @__PURE__ */ jsx2(Colorize, { color: tabColor, children: /* @__PURE__ */ jsx2(
32272
+ Cuboid,
32273
+ {
32274
+ size: [tabWidth, tabLength, tabThickness],
32275
+ center: [tabCenterX, 0, tabThickness / 2]
32276
+ }
32277
+ ) }),
32278
+ /* @__PURE__ */ jsx2(Colorize, { color, children: /* @__PURE__ */ jsx2(
32279
+ Cuboid,
32280
+ {
32281
+ size: [bodyWidth, bodyLength10, bodyHeight],
32282
+ center: [bodyCenterX, 0, tabThickness + bodyHeight / 2]
32283
+ }
32284
+ ) }),
32285
+ [-1, 1].map((side) => {
32286
+ return /* @__PURE__ */ jsxs(Colorize, { color: leadColor, children: [
32287
+ /* @__PURE__ */ jsx2(
32288
+ Cuboid,
32289
+ {
32290
+ size: [leadContactLength, leadWidth, leadThickness],
32291
+ center: [
32292
+ leadPadX + leadContactLength / 2,
32293
+ side * pitch,
32294
+ leadThickness / 2
32295
+ ]
32296
+ }
32297
+ ),
32298
+ /* @__PURE__ */ jsxs(Hull, { children: [
32299
+ /* @__PURE__ */ jsx2(
32300
+ Cuboid,
32301
+ {
32302
+ size: [0.1, leadWidth, leadThickness],
32303
+ center: [
32304
+ leadPadX + leadContactLength,
32305
+ side * pitch,
32306
+ leadThickness / 2
32307
+ ]
32308
+ }
32309
+ ),
32310
+ /* @__PURE__ */ jsx2(
32311
+ Cuboid,
32312
+ {
32313
+ size: [0.1, leadWidth, leadThickness],
32314
+ center: [bodyFrontX, side * pitch, leadZ + tabThickness / 2]
32315
+ }
32316
+ )
32317
+ ] })
32318
+ ] }, `lead-${side}`);
32319
+ })
32320
+ ] });
32321
+ };
32322
+ var ElectrolyticCapacitor = ({
32323
+ diameter = 6.3,
32324
+ heightToDiameterRatio = 1.4,
32325
+ height: height10 = diameter * heightToDiameterRatio,
32326
+ leadPitch = 2.5,
32327
+ leadDiameter = 0.6,
32328
+ leadLength = 3,
32329
+ sleeveColor = "#1b2a6b",
32330
+ baseColor = "#1a1a1a"
32331
+ }) => {
32332
+ const radius = diameter / 2;
32333
+ const baseHeight = Math.min(1, diameter * 0.12);
32334
+ const canHeight = Math.max(height10 - baseHeight, 0.1);
32335
+ const canBottom = baseHeight;
32336
+ const canTop = canBottom + canHeight;
32337
+ const grooveWidth = Math.max(diameter * 0.06, 0.2);
32338
+ const grooveDepth = 0.3;
32339
+ return /* @__PURE__ */ jsxs(Fragment2, { children: [
32340
+ /* @__PURE__ */ jsx2(Colorize, { color: baseColor, children: /* @__PURE__ */ jsx2(
32341
+ Cylinder,
32342
+ {
32343
+ radius: radius - 0.05,
32344
+ height: baseHeight,
32345
+ center: [0, 0, baseHeight / 2]
32346
+ }
32347
+ ) }),
32348
+ /* @__PURE__ */ jsx2(Colorize, { color: sleeveColor, children: /* @__PURE__ */ jsxs(Subtract, { children: [
32349
+ /* @__PURE__ */ jsx2(
32350
+ RoundedCylinder,
32351
+ {
32352
+ radius,
32353
+ height: canHeight,
32354
+ roundRadius: Math.min(0.3, radius * 0.15),
32355
+ center: [0, 0, canBottom + canHeight / 2]
32356
+ }
32357
+ ),
32358
+ /* @__PURE__ */ jsx2(
32359
+ Cuboid,
32360
+ {
32361
+ size: [diameter, grooveWidth, grooveDepth * 2],
32362
+ center: [0, 0, canTop]
32363
+ }
32364
+ ),
32365
+ /* @__PURE__ */ jsx2(
32366
+ Cuboid,
32367
+ {
32368
+ size: [grooveWidth, diameter, grooveDepth * 2],
32369
+ center: [0, 0, canTop]
32370
+ }
32371
+ )
32372
+ ] }) }),
32373
+ [-1, 1].map((side) => /* @__PURE__ */ jsx2(Colorize, { color: "#c0c0c0", children: /* @__PURE__ */ jsx2(
32374
+ Cylinder,
32375
+ {
32376
+ radius: leadDiameter / 2,
32377
+ height: leadLength + baseHeight,
32378
+ center: [side * leadPitch / 2, 0, (baseHeight - leadLength) / 2]
32379
+ }
32380
+ ) }, `lead-${side}`))
32381
+ ] });
32382
+ };
32383
+ var Potentiometer = ({
32384
+ bodyWidth = 5.35,
32385
+ bodyLength: bodyLength10 = 14,
32386
+ bodyHeight = 4,
32387
+ bodyCenterX = bodyWidth / 2,
32388
+ adjusterDiameter = Math.min(bodyWidth, bodyLength10) * 0.55,
32389
+ shaftDiameter = 0,
32390
+ shaftHeight = 0,
32391
+ leads = [],
32392
+ leadDiameter = 0.6,
32393
+ leadLength = 3,
32394
+ bodyColor = "#1f4fa3",
32395
+ adjusterColor = "#d8d8d8"
32396
+ }) => {
32397
+ const adjusterHeight = 0.8;
32398
+ const adjusterZ = bodyHeight + adjusterHeight / 2;
32399
+ const slotWidth = Math.max(adjusterDiameter * 0.16, 0.3);
32400
+ return /* @__PURE__ */ jsxs(Fragment2, { children: [
32401
+ /* @__PURE__ */ jsx2(Colorize, { color: bodyColor, children: /* @__PURE__ */ jsx2(
32402
+ Cuboid,
32403
+ {
32404
+ size: [bodyWidth, bodyLength10, bodyHeight],
32405
+ center: [bodyCenterX, 0, bodyHeight / 2]
32406
+ }
32407
+ ) }),
32408
+ /* @__PURE__ */ jsx2(Colorize, { color: adjusterColor, children: /* @__PURE__ */ jsxs(Subtract, { children: [
32409
+ /* @__PURE__ */ jsx2(
32410
+ Cylinder,
32411
+ {
32412
+ radius: adjusterDiameter / 2,
32413
+ height: adjusterHeight,
32414
+ center: [bodyCenterX, 0, adjusterZ]
32415
+ }
32416
+ ),
32417
+ /* @__PURE__ */ jsx2(
32418
+ Cuboid,
32419
+ {
32420
+ size: [adjusterDiameter, slotWidth, adjusterHeight * 0.6],
32421
+ center: [bodyCenterX, 0, adjusterZ + adjusterHeight / 2]
32422
+ }
32423
+ )
32424
+ ] }) }),
32425
+ shaftHeight > 0 && shaftDiameter > 0 ? /* @__PURE__ */ jsx2(Colorize, { color: adjusterColor, children: /* @__PURE__ */ jsx2(
32426
+ Cylinder,
32427
+ {
32428
+ radius: shaftDiameter / 2,
32429
+ height: shaftHeight,
32430
+ center: [bodyCenterX, 0, bodyHeight + shaftHeight / 2]
32431
+ }
32432
+ ) }) : null,
32433
+ leads.map((lead) => /* @__PURE__ */ jsx2(Colorize, { color: "#c0c0c0", children: /* @__PURE__ */ jsx2(
32434
+ Cylinder,
32435
+ {
32436
+ radius: leadDiameter / 2,
32437
+ height: bodyHeight / 2 + leadLength,
32438
+ center: [lead.x, lead.y, (bodyHeight / 2 - leadLength) / 2]
32439
+ }
32440
+ ) }, `lead-${lead.x}-${lead.y}`))
32441
+ ] });
32442
+ };
32443
+ var SmdPushButton = ({
32444
+ bodyWidth = 2.9,
32445
+ bodyLength: bodyLength10 = 3,
32446
+ bodyHeight = 1.4,
32447
+ actuatorDiameter = 1.5,
32448
+ actuatorHeight = 0.5,
32449
+ padSpanX = 4.2,
32450
+ padSpanY = 2.15,
32451
+ padWidth = 1.05,
32452
+ padLength = 0.7,
32453
+ bodyColor = "#2b2b2b",
32454
+ actuatorColor = "#d9d9d9",
32455
+ leadColor = "#cccccc"
32456
+ }) => {
32457
+ const leadThickness = 0.15;
32458
+ return /* @__PURE__ */ jsxs(Fragment2, { children: [
32459
+ /* @__PURE__ */ jsx2(Colorize, { color: bodyColor, children: /* @__PURE__ */ jsx2(
32460
+ Cuboid,
32461
+ {
32462
+ size: [bodyWidth, bodyLength10, bodyHeight],
32463
+ center: [0, 0, bodyHeight / 2]
32464
+ }
32465
+ ) }),
32466
+ /* @__PURE__ */ jsx2(Colorize, { color: actuatorColor, children: /* @__PURE__ */ jsx2(
32467
+ Cylinder,
32468
+ {
32469
+ radius: actuatorDiameter / 2,
32470
+ height: actuatorHeight,
32471
+ center: [0, 0, bodyHeight + actuatorHeight / 2]
32472
+ }
32473
+ ) }),
32474
+ [-1, 1].flatMap(
32475
+ (sx) => [-1, 1].map((sy) => /* @__PURE__ */ jsx2(Colorize, { color: leadColor, children: /* @__PURE__ */ jsx2(
32476
+ Cuboid,
32477
+ {
32478
+ size: [padWidth, padLength, leadThickness],
32479
+ center: [
32480
+ sx * padSpanX / 2,
32481
+ sy * padSpanY / 2,
32482
+ leadThickness / 2
32483
+ ]
32484
+ }
32485
+ ) }, `lead-${sx}-${sy}`))
32486
+ )
32487
+ ] });
32488
+ };
32489
+ var SOT563 = ({ fullWidth = 1.94, fullLength: fullLength10 = 1.6 }) => {
32490
+ const bodyWidth = 1.2;
32491
+ const bodyLength10 = 1.6;
32492
+ const bodyHeight = 0.55;
32493
+ const leadWidth = 0.3;
32494
+ const leadLength = 0.67;
32495
+ const leadHeight = 0.13;
32496
+ const leadSpacing = 0.5;
32497
+ const bodyZOffset = -0.4;
32498
+ return /* @__PURE__ */ jsxs(Fragment2, { children: [
32499
+ /* @__PURE__ */ jsx2(Rotate, { rotation: [45 * Math.PI, 0, 0], children: /* @__PURE__ */ jsx2(Translate, { center: [0, 0, bodyZOffset], children: /* @__PURE__ */ jsx2(Colorize, { color: "grey", children: /* @__PURE__ */ jsx2(Cuboid, { size: [bodyWidth, bodyLength10, bodyHeight] }) }) }) }),
32500
+ [-1, 0, 1].flatMap((yOffset, index2) => [
32501
+ // Left lead
32502
+ /* @__PURE__ */ jsx2(
32503
+ Translate,
32504
+ {
32505
+ center: [
32506
+ -bodyWidth / 2 - 0.03,
32507
+ yOffset * leadSpacing,
32508
+ leadHeight / 2
32509
+ ],
32510
+ children: /* @__PURE__ */ jsx2(Cuboid, { size: [leadLength, leadWidth, leadHeight] })
32511
+ },
32512
+ `left-${index2}`
32513
+ ),
32514
+ // Right lead
32515
+ /* @__PURE__ */ jsx2(
32516
+ Translate,
32517
+ {
32518
+ center: [bodyWidth / 2 + 0.03, yOffset * leadSpacing, leadHeight / 2],
32519
+ children: /* @__PURE__ */ jsx2(Cuboid, { size: [leadLength, leadWidth, leadHeight] })
32520
+ },
32521
+ `right-${index2}`
32522
+ )
32523
+ ])
32524
+ ] });
32525
+ };
32526
+ var BGA = ({
32527
+ packageWidth = 10,
32528
+ packageLength = 10,
32529
+ packageHeight = 1.2,
32530
+ standoffHeight = 0.2,
32531
+ ballPitch = 0.8,
32532
+ ballDiameter = 0.5,
32533
+ ballRows = 8,
32534
+ ballColumns = 8,
32535
+ missingBalls = [],
32536
+ footprintString
32537
+ }) => {
32538
+ const bodyHeight = packageHeight - standoffHeight;
32539
+ const bodyOffset = standoffHeight + bodyHeight / 2;
32540
+ const ballOffset = Math.max(standoffHeight / 2, ballDiameter / 2);
32541
+ const ballsSoup = footprintString ? fp.string(footprintString).circuitJson() : null;
32542
+ return /* @__PURE__ */ jsxs(Fragment2, { children: [
32543
+ /* @__PURE__ */ jsx2(Translate, { z: bodyOffset, children: /* @__PURE__ */ jsx2(Colorize, { color: "#555", children: /* @__PURE__ */ jsx2(Cuboid, { size: [packageWidth, packageLength, bodyHeight] }) }) }),
32544
+ !footprintString && Array.from({ length: ballRows * ballColumns }).map((_, index2) => {
32545
+ if (missingBalls.includes(index2 + 1)) return null;
32546
+ const row = Math.floor(index2 / ballColumns);
32547
+ const col = index2 % ballColumns;
32548
+ const x = (col - (ballColumns - 1) / 2) * ballPitch;
32549
+ const y = (row - (ballRows - 1) / 2) * ballPitch;
32550
+ return /* @__PURE__ */ jsx2(Translate, { x, y, z: ballOffset, children: /* @__PURE__ */ jsx2(Sphere, { radius: ballDiameter / 2 }) }, index2);
32551
+ }),
32552
+ ballsSoup && ballsSoup.map((elm, index2) => {
32553
+ if (elm.type === "pcb_smtpad") {
32554
+ return /* @__PURE__ */ jsx2(
32555
+ Translate,
32556
+ {
32557
+ x: elm.x,
32558
+ y: elm.y,
32559
+ z: ballOffset,
32560
+ children: /* @__PURE__ */ jsx2(Sphere, { radius: ballDiameter / 2 })
32561
+ },
32562
+ index2
32563
+ );
32564
+ }
32565
+ return null;
32566
+ })
32567
+ ] });
32568
+ };
32569
+ var DEFAULT_ASPECT_RATIO = 16 / 9;
32570
+ var DEFAULT_DIAGONAL = 40;
32571
+ var EPSILON = 1e-6;
32572
+ var assertPositive = (name, value) => {
32573
+ if (!Number.isFinite(value) || value <= 0) {
32574
+ throw new Error(`${name} must be a finite number greater than zero`);
32575
+ }
32576
+ };
32577
+ var resolveAspectRatio = (value) => {
32578
+ if (value === void 0) return DEFAULT_ASPECT_RATIO;
32579
+ if (typeof value === "number") {
32580
+ assertPositive("aspectRatio", value);
32581
+ return value;
32582
+ }
32583
+ if (typeof value !== "string") {
32584
+ const [ratioWidth2, ratioHeight2] = value;
32585
+ assertPositive("aspectRatio width", ratioWidth2);
32586
+ assertPositive("aspectRatio height", ratioHeight2);
32587
+ return ratioWidth2 / ratioHeight2;
32588
+ }
32589
+ const parts = value.split(":");
32590
+ if (parts.length !== 2) {
32591
+ throw new Error('aspectRatio must look like "16:9"');
32592
+ }
32593
+ const ratioWidth = Number(parts[0]);
32594
+ const ratioHeight = Number(parts[1]);
32595
+ assertPositive("aspectRatio width", ratioWidth);
32596
+ assertPositive("aspectRatio height", ratioHeight);
32597
+ return ratioWidth / ratioHeight;
32598
+ };
32599
+ var resolveFlexScreenSize = ({
32600
+ width: width10,
32601
+ height: height10,
32602
+ diagonal,
32603
+ aspectRatio,
32604
+ ratio,
32605
+ defaultDiagonal = DEFAULT_DIAGONAL
32606
+ }) => {
32607
+ const resolvedRatio = resolveAspectRatio(aspectRatio ?? ratio);
32608
+ if (width10 !== void 0) assertPositive("width", width10);
32609
+ if (height10 !== void 0) assertPositive("height", height10);
32610
+ if (diagonal !== void 0) assertPositive("diagonal", diagonal);
32611
+ assertPositive("defaultDiagonal", defaultDiagonal);
32612
+ let resolvedWidth;
32613
+ let resolvedHeight;
32614
+ if (width10 !== void 0 && height10 !== void 0) {
32615
+ resolvedWidth = width10;
32616
+ resolvedHeight = height10;
32617
+ } else if (diagonal !== void 0 && width10 !== void 0) {
32618
+ if (width10 >= diagonal) {
32619
+ throw new Error("width must be smaller than diagonal");
32620
+ }
32621
+ resolvedWidth = width10;
32622
+ resolvedHeight = Math.sqrt(diagonal ** 2 - width10 ** 2);
32623
+ } else if (diagonal !== void 0 && height10 !== void 0) {
32624
+ if (height10 >= diagonal) {
32625
+ throw new Error("height must be smaller than diagonal");
32626
+ }
32627
+ resolvedWidth = Math.sqrt(diagonal ** 2 - height10 ** 2);
32628
+ resolvedHeight = height10;
32629
+ } else if (width10 !== void 0) {
32630
+ resolvedWidth = width10;
32631
+ resolvedHeight = width10 / resolvedRatio;
32632
+ } else if (height10 !== void 0) {
32633
+ resolvedWidth = height10 * resolvedRatio;
32634
+ resolvedHeight = height10;
32635
+ } else {
32636
+ const resolvedDiagonal = diagonal ?? defaultDiagonal;
32637
+ resolvedHeight = resolvedDiagonal / Math.sqrt(resolvedRatio ** 2 + 1);
32638
+ resolvedWidth = resolvedHeight * resolvedRatio;
32639
+ }
32640
+ return {
32641
+ width: resolvedWidth,
32642
+ height: resolvedHeight,
32643
+ diagonal: Math.hypot(resolvedWidth, resolvedHeight),
32644
+ aspectRatio: resolvedWidth / resolvedHeight
32645
+ };
32646
+ };
32647
+ var resolveOrientation = (props) => {
32648
+ const shortcuts = [
32649
+ ["sitsFlat", props.sitsFlat],
32650
+ ["sitsFlatBelowBoard", props.sitsFlatBelowBoard],
32651
+ ["foldedToFaceAboveBoard", props.foldedToFaceAboveBoard],
32652
+ ["foldedToFaceBelowBoard", props.foldedToFaceBelowBoard],
32653
+ ["foldedToFaceAboveBoard", props.foldsAboveBoard],
32654
+ ["foldedToFaceBelowBoard", props.foldsBelowBoard],
32655
+ ["foldedToRightAngleAboveBoard", props.foldedToRightAngleAboveBoard],
32656
+ ["foldedToRightAngleBelowBoard", props.foldedToRightAngleBelowBoard]
32657
+ ].filter((entry) => entry[1]);
32658
+ if (shortcuts.length > 1) {
32659
+ throw new Error(
32660
+ "Only one FlexScreen boolean orientation shortcut can be true"
32661
+ );
32662
+ }
32663
+ return shortcuts[0]?.[0] ?? props.orientation ?? "sitsFlat";
32664
+ };
32665
+ var distance4 = (a, b) => Math.hypot(b[0] - a[0], b[1] - a[1], b[2] - a[2]);
32666
+ var interpolate = (a, b, progress) => [
32667
+ a[0] + (b[0] - a[0]) * progress,
32668
+ a[1] + (b[1] - a[1]) * progress,
32669
+ a[2] + (b[2] - a[2]) * progress
32670
+ ];
32671
+ var getPathDistances = (points) => {
32672
+ const distances = [0];
32673
+ for (let index2 = 1; index2 < points.length; index2 += 1) {
32674
+ distances.push(
32675
+ distances[index2 - 1] + distance4(points[index2 - 1], points[index2])
32676
+ );
32677
+ }
32678
+ return distances;
32679
+ };
32680
+ var pointAtDistance = (points, distances, targetDistance) => {
32681
+ if (targetDistance <= 0) return points[0];
32682
+ const totalLength = distances.at(-1);
32683
+ if (targetDistance >= totalLength) return points.at(-1);
32684
+ for (let index2 = 1; index2 < points.length; index2 += 1) {
32685
+ if (distances[index2] >= targetDistance) {
32686
+ const segmentStart = distances[index2 - 1];
32687
+ const segmentLength = distances[index2] - segmentStart;
32688
+ return interpolate(
32689
+ points[index2 - 1],
32690
+ points[index2],
32691
+ (targetDistance - segmentStart) / segmentLength
32692
+ );
32693
+ }
32694
+ }
32695
+ return points.at(-1);
32696
+ };
32697
+ var slicePath = (points, startDistance, endDistance) => {
32698
+ const distances = getPathDistances(points);
32699
+ const totalLength = distances.at(-1);
32700
+ const safeStart = Math.max(0, Math.min(startDistance, totalLength));
32701
+ const safeEnd = Math.max(safeStart, Math.min(endDistance, totalLength));
32702
+ const result = [pointAtDistance(points, distances, safeStart)];
32703
+ for (let index2 = 1; index2 < points.length - 1; index2 += 1) {
32704
+ if (distances[index2] > safeStart && distances[index2] < safeEnd) {
32705
+ result.push(points[index2]);
32706
+ }
32707
+ }
32708
+ result.push(pointAtDistance(points, distances, safeEnd));
32709
+ return result;
32710
+ };
32711
+ var createFlatPath = (start, flexCableLength) => [
32712
+ start,
32713
+ [start[0], start[1] + flexCableLength, start[2]]
32714
+ ];
32715
+ var createFoldedPath = ({
32716
+ start,
32717
+ endZ,
32718
+ flexCableLength,
32719
+ foldDistanceFromConnector,
32720
+ foldOutset,
32721
+ foldSegments
32722
+ }) => {
32723
+ const points = [start];
32724
+ const foldStart = [
32725
+ start[0],
32726
+ start[1] + foldDistanceFromConnector,
32727
+ start[2]
32728
+ ];
32729
+ if (foldDistanceFromConnector > EPSILON) points.push(foldStart);
32730
+ for (let index2 = 1; index2 <= foldSegments; index2 += 1) {
32731
+ const angle = Math.PI * index2 / foldSegments;
32732
+ points.push([
32733
+ start[0],
32734
+ foldStart[1] + foldOutset * Math.sin(angle),
32735
+ start[2] + (endZ - start[2]) * (1 - Math.cos(angle)) / 2
32736
+ ]);
32737
+ }
32738
+ const minimumLength = getPathDistances(points).at(-1);
32739
+ if (minimumLength > flexCableLength + EPSILON) {
32740
+ throw new Error(
32741
+ `flexCableLength must be at least ${minimumLength.toFixed(2)} for this 180-degree fold`
32742
+ );
32743
+ }
32744
+ const tailLength = Math.max(0, flexCableLength - minimumLength);
32745
+ if (tailLength > EPSILON) {
32746
+ const foldEnd = points.at(-1);
32747
+ points.push([foldEnd[0], foldEnd[1] - tailLength, foldEnd[2]]);
32748
+ }
32749
+ return points;
32750
+ };
32751
+ var createRightAnglePath = ({
32752
+ start,
32753
+ flexCableLength,
32754
+ bendRadius,
32755
+ bendSegments,
32756
+ verticalLead,
32757
+ direction
32758
+ }) => {
32759
+ const bendLengthPerRadius = 2 * bendSegments * Math.sin(Math.PI / (4 * bendSegments));
32760
+ const resolvedRadius = Math.min(
32761
+ bendRadius,
32762
+ flexCableLength / bendLengthPerRadius
32763
+ );
32764
+ const bendLength = resolvedRadius * bendLengthPerRadius;
32765
+ const remainingLength = Math.max(0, flexCableLength - bendLength);
32766
+ const resolvedVerticalLead = Math.min(verticalLead, remainingLength * 0.45);
32767
+ const horizontalLength = remainingLength - resolvedVerticalLead;
32768
+ const points = [start];
32769
+ if (horizontalLength > EPSILON) {
32770
+ points.push([start[0], start[1] + horizontalLength, start[2]]);
32771
+ }
32772
+ for (let index2 = 1; index2 <= bendSegments; index2 += 1) {
32773
+ const angle = Math.PI / 2 * index2 / bendSegments;
32774
+ points.push([
32775
+ start[0],
32776
+ start[1] + horizontalLength + resolvedRadius * Math.sin(angle),
32777
+ start[2] + direction * resolvedRadius * (1 - Math.cos(angle))
32778
+ ]);
32779
+ }
32780
+ if (resolvedVerticalLead > EPSILON) {
32781
+ const arcEnd = points.at(-1);
32782
+ points.push([
32783
+ arcEnd[0],
32784
+ arcEnd[1],
32785
+ arcEnd[2] + direction * resolvedVerticalLead
32786
+ ]);
32787
+ }
32788
+ return points;
32789
+ };
32790
+ var CableStrip = ({
32791
+ points,
32792
+ width: width10,
32793
+ thickness,
32794
+ color,
32795
+ acrossOffset = 0,
32796
+ normalOffset = 0,
32797
+ overlap = 0.03
32798
+ }) => /* @__PURE__ */ jsx2(Colorize, { color, children: points.slice(1).map((point, index2) => {
32799
+ const previous = points[index2];
32800
+ const dx = point[0] - previous[0];
32801
+ const dy = point[1] - previous[1];
32802
+ const dz = point[2] - previous[2];
32803
+ const segmentLength = Math.hypot(dx, dy, dz);
32804
+ if (segmentLength < EPSILON) return null;
32805
+ const pitch = Math.asin(dz / segmentLength);
32806
+ const yaw = Math.atan2(-dx, dy);
32807
+ const midpoint2 = [
32808
+ (previous[0] + point[0]) / 2,
32809
+ (previous[1] + point[1]) / 2,
32810
+ (previous[2] + point[2]) / 2
32811
+ ];
32812
+ const roundRadius = Math.max(
32813
+ 1e-3,
32814
+ Math.min(width10, thickness, segmentLength) / 2 - 1e-3
32815
+ );
32816
+ return /* @__PURE__ */ jsx2(Translate, { offset: midpoint2, children: /* @__PURE__ */ jsx2(Rotate, { rotation: [pitch, 0, yaw], children: /* @__PURE__ */ jsx2(
32817
+ RoundedCuboid,
32818
+ {
32819
+ size: [width10, segmentLength + overlap, thickness],
32820
+ center: [acrossOffset, 0, normalOffset],
32821
+ roundRadius
32822
+ }
32823
+ ) }) }, `${index2}:${midpoint2.join(":")}`);
32824
+ }) });
32825
+ var FlexScreen = (props) => {
32826
+ const {
32827
+ width: width10,
32828
+ height: height10,
32829
+ diagonal,
32830
+ aspectRatio,
32831
+ ratio,
32832
+ defaultDiagonal,
32833
+ screenThickness = 1.2,
32834
+ bezelInset = 2,
32835
+ bezelDepth = 0.65,
32836
+ activeAreaWidth,
32837
+ activeAreaHeight,
32838
+ screenColor = "#071b24",
32839
+ bezelColor = "#15181d",
32840
+ showScreen = true,
32841
+ flexCableLength = 28,
32842
+ flexCableThickness = 0.18,
32843
+ flexCableColor = "#d79528",
32844
+ conductorCount = 8,
32845
+ conductorPitch,
32846
+ conductorWidth,
32847
+ conductorThickness = 0.035,
32848
+ conductorColor = "#8c4a18",
32849
+ cableEdgeMargin = 0.6,
32850
+ exposedContactLength = 2.4,
32851
+ showConductors = true,
32852
+ showFlexCable = true,
32853
+ showStiffeners = true,
32854
+ stiffenerLength = 3,
32855
+ stiffenerThickness = 0.16,
32856
+ stiffenerColor = "#416bb3",
32857
+ bendRadius = 3,
32858
+ bendSegments = 10,
32859
+ rightAngleVerticalLead = 3,
32860
+ distanceAboveBoard = 7,
32861
+ distanceBelowBoard = 7,
32862
+ foldDistanceFromConnector = 7,
32863
+ foldOutset = 4,
32864
+ foldSegments = 18,
32865
+ screenGap = 0.08,
32866
+ boardTopZ = 0,
32867
+ boardThickness = 1.6,
32868
+ boardClearance = 0.15,
32869
+ cableStartX = 0,
32870
+ cableStartY = 0,
32871
+ cableStartZ,
32872
+ cableLateralOffset = 0,
32873
+ screenOffset,
32874
+ screenRotation,
32875
+ rotation = [0, 0, 0],
32876
+ offset: offset4
32877
+ } = props;
32878
+ const size4 = resolveFlexScreenSize({
32879
+ width: width10,
32880
+ height: height10,
32881
+ diagonal,
32882
+ aspectRatio,
32883
+ ratio,
32884
+ defaultDiagonal
32885
+ });
32886
+ const orientation2 = resolveOrientation(props);
32887
+ const belowBoard = orientation2 === "sitsFlatBelowBoard" || orientation2 === "foldedToFaceBelowBoard" || orientation2 === "foldedToRightAngleBelowBoard";
32888
+ const foldedFace = orientation2 === "foldedToFaceAboveBoard" || orientation2 === "foldedToFaceBelowBoard";
32889
+ const rightAngle = orientation2 === "foldedToRightAngleAboveBoard" || orientation2 === "foldedToRightAngleBelowBoard";
32890
+ assertPositive("screenThickness", screenThickness);
32891
+ assertPositive("flexCableLength", flexCableLength);
32892
+ assertPositive("flexCableThickness", flexCableThickness);
32893
+ assertPositive("conductorThickness", conductorThickness);
32894
+ assertPositive("bendRadius", bendRadius);
32895
+ assertPositive("foldOutset", foldOutset);
32896
+ assertPositive("boardThickness", boardThickness);
32897
+ if (showStiffeners) assertPositive("stiffenerThickness", stiffenerThickness);
32898
+ if (!Number.isInteger(conductorCount) || conductorCount < 1) {
32899
+ throw new Error("conductorCount must be a positive integer");
32900
+ }
32901
+ if (!Number.isInteger(bendSegments) || bendSegments < 2) {
32902
+ throw new Error("bendSegments must be an integer of at least 2");
32903
+ }
32904
+ if (!Number.isInteger(foldSegments) || foldSegments < 4) {
32905
+ throw new Error("foldSegments must be an integer of at least 4");
32906
+ }
32907
+ if (boardClearance < 0 || screenGap < 0 || cableEdgeMargin < 0 || exposedContactLength < 0 || stiffenerLength < 0 || rightAngleVerticalLead < 0 || distanceAboveBoard < 0 || distanceBelowBoard < 0 || foldDistanceFromConnector < 0) {
32908
+ throw new Error(
32909
+ "clearances, margins, contact lengths, and lead lengths cannot be negative"
32910
+ );
32911
+ }
32912
+ const resolvedCableWidth = props.flexCableWidth ?? Math.min(12, Math.max(5, size4.width * 0.3));
32913
+ assertPositive("flexCableWidth", resolvedCableWidth);
32914
+ const usableCableWidth = resolvedCableWidth - cableEdgeMargin * 2;
32915
+ if (usableCableWidth <= 0) {
32916
+ throw new Error("cableEdgeMargin leaves no usable flex cable width");
32917
+ }
32918
+ const resolvedConductorPitch = conductorPitch ?? (conductorCount === 1 ? 0 : usableCableWidth / conductorCount);
32919
+ if (conductorCount > 1 && (!Number.isFinite(resolvedConductorPitch) || resolvedConductorPitch <= 0)) {
32920
+ throw new Error("conductorPitch must be greater than zero");
32921
+ }
32922
+ const resolvedConductorWidth = conductorWidth ?? (conductorCount === 1 ? Math.min(usableCableWidth, resolvedCableWidth * 0.45) : resolvedConductorPitch * 0.48);
32923
+ assertPositive("conductorWidth", resolvedConductorWidth);
32924
+ const conductorSpan = (conductorCount - 1) * resolvedConductorPitch + resolvedConductorWidth;
32925
+ if (conductorSpan > usableCableWidth + EPSILON) {
32926
+ throw new Error(
32927
+ "conductorPitch and conductorWidth do not fit inside the flex cable margins"
32928
+ );
32929
+ }
32930
+ const cableStartsBelowBoard = belowBoard && !foldedFace;
32931
+ const defaultCableZ = cableStartsBelowBoard ? boardTopZ - boardThickness - boardClearance - flexCableThickness / 2 : boardTopZ + boardClearance + flexCableThickness / 2;
32932
+ const start = [
32933
+ cableStartX + cableLateralOffset,
32934
+ cableStartY,
32935
+ cableStartZ ?? defaultCableZ
32936
+ ];
32937
+ const direction = belowBoard ? -1 : 1;
32938
+ const foldedScreenBackZ = orientation2 === "foldedToFaceAboveBoard" ? boardTopZ + distanceAboveBoard : boardTopZ - boardThickness - distanceBelowBoard;
32939
+ const foldedCableEndZ = orientation2 === "foldedToFaceAboveBoard" ? foldedScreenBackZ - screenGap - flexCableThickness / 2 : foldedScreenBackZ + screenGap + flexCableThickness / 2;
32940
+ const path = foldedFace ? createFoldedPath({
32941
+ start,
32942
+ endZ: foldedCableEndZ,
32943
+ flexCableLength,
32944
+ foldDistanceFromConnector,
32945
+ foldOutset,
32946
+ foldSegments
32947
+ }) : rightAngle ? createRightAnglePath({
32948
+ start,
32949
+ flexCableLength,
32950
+ bendRadius,
32951
+ bendSegments,
32952
+ verticalLead: rightAngleVerticalLead,
32953
+ direction
32954
+ }) : createFlatPath(start, flexCableLength);
32955
+ const totalCableLength = getPathDistances(path).at(-1);
32956
+ const contactLength = Math.min(
32957
+ Math.max(0, exposedContactLength),
32958
+ totalCableLength / 2
32959
+ );
32960
+ const resolvedStiffenerLength = Math.min(
32961
+ Math.max(0, stiffenerLength),
32962
+ totalCableLength / 2
32963
+ );
32964
+ const startContacts = slicePath(path, 0, contactLength);
32965
+ const endContacts = slicePath(
32966
+ path,
32967
+ totalCableLength - contactLength,
32968
+ totalCableLength
32969
+ );
32970
+ const startStiffener = slicePath(path, 0, resolvedStiffenerLength);
32971
+ const endStiffener = slicePath(
32972
+ path,
32973
+ totalCableLength - resolvedStiffenerLength,
32974
+ totalCableLength
32975
+ );
32976
+ const pathEnd = path.at(-1);
32977
+ let presetScreenRotation;
32978
+ let screenCenter;
32979
+ if (orientation2 === "sitsFlat") {
32980
+ presetScreenRotation = [0, 0, 0];
32981
+ screenCenter = [
32982
+ pathEnd[0],
32983
+ pathEnd[1] + size4.height / 2,
32984
+ pathEnd[2] + flexCableThickness / 2 + screenGap
32985
+ ];
32986
+ } else if (orientation2 === "sitsFlatBelowBoard") {
32987
+ presetScreenRotation = [0, Math.PI, 0];
32988
+ screenCenter = [
32989
+ pathEnd[0],
32990
+ pathEnd[1] + size4.height / 2,
32991
+ pathEnd[2] - flexCableThickness / 2 - screenGap
32992
+ ];
32993
+ } else if (orientation2 === "foldedToFaceAboveBoard") {
32994
+ presetScreenRotation = [0, 0, 0];
32995
+ screenCenter = [pathEnd[0], pathEnd[1] - size4.height / 2, foldedScreenBackZ];
32996
+ } else if (orientation2 === "foldedToFaceBelowBoard") {
32997
+ presetScreenRotation = [0, Math.PI, 0];
32998
+ screenCenter = [pathEnd[0], pathEnd[1] - size4.height / 2, foldedScreenBackZ];
32999
+ } else if (orientation2 === "foldedToRightAngleAboveBoard") {
33000
+ presetScreenRotation = [Math.PI / 2, 0, 0];
33001
+ screenCenter = [
33002
+ pathEnd[0],
33003
+ pathEnd[1] - flexCableThickness / 2 - screenGap,
33004
+ pathEnd[2] + size4.height / 2
33005
+ ];
33006
+ } else {
33007
+ presetScreenRotation = [-Math.PI / 2, 0, 0];
33008
+ screenCenter = [
33009
+ pathEnd[0],
33010
+ pathEnd[1] + flexCableThickness / 2 + screenGap,
33011
+ pathEnd[2] - size4.height / 2
33012
+ ];
33013
+ }
33014
+ screenCenter = [
33015
+ screenCenter[0] + (screenOffset?.x ?? 0),
33016
+ screenCenter[1] + (screenOffset?.y ?? 0),
33017
+ screenCenter[2] + (screenOffset?.z ?? 0)
33018
+ ];
33019
+ const conductorOffsets = Array.from(
33020
+ { length: conductorCount },
33021
+ (_, index2) => conductorCount === 1 ? 0 : (index2 - (conductorCount - 1) / 2) * resolvedConductorPitch
33022
+ );
33023
+ const conductorNormalOffset = (flexCableThickness + conductorThickness) / 2;
33024
+ const stiffenerNormalOffset = -(flexCableThickness + stiffenerThickness) / 2;
33025
+ const assembly = /* @__PURE__ */ jsxs(Fragment2, { children: [
33026
+ showFlexCable && /* @__PURE__ */ jsx2(
33027
+ CableStrip,
33028
+ {
33029
+ points: path,
33030
+ width: resolvedCableWidth,
33031
+ thickness: flexCableThickness,
33032
+ color: flexCableColor
33033
+ }
33034
+ ),
33035
+ showFlexCable && showStiffeners && resolvedStiffenerLength > EPSILON && /* @__PURE__ */ jsxs(Fragment2, { children: [
33036
+ /* @__PURE__ */ jsx2(
33037
+ CableStrip,
33038
+ {
33039
+ points: startStiffener,
33040
+ width: resolvedCableWidth,
33041
+ thickness: stiffenerThickness,
33042
+ color: stiffenerColor,
33043
+ normalOffset: stiffenerNormalOffset
33044
+ }
33045
+ ),
33046
+ /* @__PURE__ */ jsx2(
33047
+ CableStrip,
33048
+ {
33049
+ points: endStiffener,
33050
+ width: resolvedCableWidth,
33051
+ thickness: stiffenerThickness,
33052
+ color: stiffenerColor,
33053
+ normalOffset: stiffenerNormalOffset
33054
+ }
33055
+ )
33056
+ ] }),
33057
+ showFlexCable && showConductors && contactLength > EPSILON && conductorOffsets.map((acrossOffset, index2) => /* @__PURE__ */ jsxs(Fragment2, { children: [
33058
+ /* @__PURE__ */ jsx2(
33059
+ CableStrip,
33060
+ {
33061
+ points: startContacts,
33062
+ width: resolvedConductorWidth,
33063
+ thickness: conductorThickness,
33064
+ color: conductorColor,
33065
+ acrossOffset,
33066
+ normalOffset: conductorNormalOffset
33067
+ }
33068
+ ),
33069
+ /* @__PURE__ */ jsx2(
33070
+ CableStrip,
33071
+ {
33072
+ points: endContacts,
33073
+ width: resolvedConductorWidth,
33074
+ thickness: conductorThickness,
33075
+ color: conductorColor,
33076
+ acrossOffset,
33077
+ normalOffset: conductorNormalOffset
33078
+ }
33079
+ )
33080
+ ] }, `conductor:${index2}`)),
33081
+ showScreen && /* @__PURE__ */ jsx2(Translate, { offset: screenCenter, children: /* @__PURE__ */ jsx2(Rotate, { rotation: screenRotation ?? presetScreenRotation, children: /* @__PURE__ */ jsx2(
33082
+ Screen,
33083
+ {
33084
+ width: size4.width,
33085
+ height: size4.height,
33086
+ thickness: screenThickness,
33087
+ bezelInset,
33088
+ bezelDepth,
33089
+ screenWidth: activeAreaWidth,
33090
+ screenHeight: activeAreaHeight,
33091
+ screenColor,
33092
+ bezelColor
33093
+ }
33094
+ ) }) })
33095
+ ] });
33096
+ return /* @__PURE__ */ jsx2(
33097
+ Translate,
33098
+ {
33099
+ offset: {
33100
+ x: offset4?.x ?? 0,
33101
+ y: offset4?.y ?? 0,
33102
+ z: offset4?.z ?? 0
33103
+ },
33104
+ children: /* @__PURE__ */ jsx2(Translate, { offset: start, children: /* @__PURE__ */ jsx2(Rotate, { rotation, children: /* @__PURE__ */ jsx2(Translate, { offset: [-start[0], -start[1], -start[2]], children: assembly }) }) })
33105
+ }
33106
+ );
33107
+ };
31283
33108
  var Footprinter3d = ({ footprint }) => {
33109
+ const modelFn = mp.string(footprint.split("_", 1)[0]).params().fn;
33110
+ if (mp.getModelNames().includes(modelFn)) {
33111
+ const model = mp.string(footprint).json();
33112
+ switch (model.fn) {
33113
+ case "flexscreen": {
33114
+ const { fn: _, ...flexScreenProps } = model;
33115
+ return /* @__PURE__ */ jsx2(FlexScreen, { ...flexScreenProps });
33116
+ }
33117
+ }
33118
+ }
31284
33119
  let normalizedFootprint = footprint;
31285
33120
  if (footprint.startsWith("jstzh1_5mm")) {
31286
33121
  const pinMatch = footprint.match(/jstzh1_5mm(\d+)?/);
31287
33122
  const numPins = pinMatch && pinMatch[1] ? pinMatch[1] : "7";
31288
33123
  normalizedFootprint = `zh${numPins}`;
33124
+ } else if (footprint.startsWith("jstph2_0mm")) {
33125
+ const pinMatch = footprint.match(/jstph2_0mm(\d+)?/);
33126
+ const numPins = pinMatch && pinMatch[1] ? pinMatch[1] : "2";
33127
+ normalizedFootprint = `jst${numPins}_ph`;
33128
+ } else if (footprint.startsWith("jstxh2_5mm")) {
33129
+ const pinMatch = footprint.match(/jstxh2_5mm(\d+)?/);
33130
+ const numPins = pinMatch && pinMatch[1] ? pinMatch[1] : "2";
33131
+ normalizedFootprint = `jst${numPins}_xh`;
31289
33132
  }
31290
33133
  const fpJson = fp.string(normalizedFootprint).json();
31291
33134
  const colorMatch = footprint.match(/_color\(([^)]+)\)/);
31292
33135
  const color = colorMatch ? colorMatch[1] : void 0;
33136
+ const dim = (value, fallback) => {
33137
+ if (value === void 0 || value === null) return fallback;
33138
+ const parsed = mm(value);
33139
+ return Number.isFinite(parsed) ? parsed : fallback;
33140
+ };
31293
33141
  switch (fpJson.fn) {
31294
33142
  case "crystal":
31295
33143
  return /* @__PURE__ */ jsx2(
@@ -31400,7 +33248,6 @@ var Footprinter3d = ({ footprint }) => {
31400
33248
  numberOfPins: fpJson.num_pins,
31401
33249
  pitch: fpJson.p,
31402
33250
  invert: fpJson.invert,
31403
- faceup: fpJson.faceup,
31404
33251
  rows,
31405
33252
  smd: fpJson.smd || fpJson.surface_mount,
31406
33253
  rightangle: fpJson.rightangle
@@ -31450,8 +33297,47 @@ var Footprinter3d = ({ footprint }) => {
31450
33297
  }
31451
33298
  break;
31452
33299
  }
31453
- case "sot235":
33300
+ case "sot23":
33301
+ switch (fpJson.num_pins) {
33302
+ case 3:
33303
+ return /* @__PURE__ */ jsx2(SOT233P, { color });
33304
+ case 5:
33305
+ return /* @__PURE__ */ jsx2(SOT_235_default, {});
33306
+ }
33307
+ break;
33308
+ case "sot25":
31454
33309
  return /* @__PURE__ */ jsx2(SOT_235_default, {});
33310
+ case "sot":
33311
+ case "sot343": {
33312
+ const isSc70 = fpJson.fn === "sot343";
33313
+ return /* @__PURE__ */ jsx2(
33314
+ GullWingBody,
33315
+ {
33316
+ pads: getSmtPadRects(normalizedFootprint),
33317
+ bodyWidth: isSc70 ? 1.25 : 1.6,
33318
+ bodyLength: isSc70 ? 2 : 2.9,
33319
+ bodyHeight: isSc70 ? 1.1 : 1.3
33320
+ }
33321
+ );
33322
+ }
33323
+ case "sot563":
33324
+ return /* @__PURE__ */ jsx2(SOT563, {});
33325
+ case "sot89": {
33326
+ const padSpan = dim(fpJson.w, 4.2);
33327
+ return /* @__PURE__ */ jsx2(
33328
+ SOT223,
33329
+ {
33330
+ fullWidth: padSpan,
33331
+ bodyWidth: padSpan * 0.6,
33332
+ bodyLength: dim(fpJson.h, 4.8) * 0.94,
33333
+ bodyHeight: 1.5,
33334
+ leadWidth: dim(fpJson.pw, 0.48),
33335
+ tabLeadWidth: dim(fpJson.pw, 0.48) * 2,
33336
+ padPitch: dim(fpJson.p, 1.5),
33337
+ leadHeight: 0.66
33338
+ }
33339
+ );
33340
+ }
31455
33341
  case "sot457":
31456
33342
  return /* @__PURE__ */ jsx2(SOT457, {});
31457
33343
  case "sot223":
@@ -31483,6 +33369,12 @@ var Footprinter3d = ({ footprint }) => {
31483
33369
  if (fpJson.zh) {
31484
33370
  return /* @__PURE__ */ jsx2(JSTZH1_5mm, { numPins: fpJson.num_pins });
31485
33371
  }
33372
+ if (fpJson.ph) {
33373
+ return /* @__PURE__ */ jsx2(JSTPH2_0mm, { numPins: fpJson.num_pins });
33374
+ }
33375
+ if (fpJson.xh) {
33376
+ return /* @__PURE__ */ jsx2(JSTXH2_5mm, { numPins: fpJson.num_pins });
33377
+ }
31486
33378
  break;
31487
33379
  case "fpc":
31488
33380
  return /* @__PURE__ */ jsx2(
@@ -31529,6 +33421,8 @@ var Footprinter3d = ({ footprint }) => {
31529
33421
  }
31530
33422
  );
31531
33423
  case "soic":
33424
+ case "sop8":
33425
+ case "ssop":
31532
33426
  return /* @__PURE__ */ jsx2(
31533
33427
  SOIC,
31534
33428
  {
@@ -31539,6 +33433,80 @@ var Footprinter3d = ({ footprint }) => {
31539
33433
  bodyWidth: fpJson.w
31540
33434
  }
31541
33435
  );
33436
+ case "son":
33437
+ case "wson":
33438
+ case "vson": {
33439
+ const bodyWidth = fpJson.fn === "vson" ? dim(fpJson.grid?.x, 3) : dim(fpJson.w, 3);
33440
+ const bodyLength10 = fpJson.fn === "vson" ? dim(fpJson.grid?.y, 3) : dim(fpJson.h, 3);
33441
+ const thermalPadWidth = dim(fpJson.epw, 0);
33442
+ const thermalPadLength = dim(fpJson.eph, 0);
33443
+ const padLength = fpJson.pl !== void 0 ? dim(fpJson.pl, 0) : void 0;
33444
+ const padWidth = fpJson.pw !== void 0 ? dim(fpJson.pw, 0) : void 0;
33445
+ const signalPads = getSmtPadRects(normalizedFootprint).filter(
33446
+ (pad2) => Number(pad2.pin ?? 0) <= fpJson.num_pins
33447
+ );
33448
+ const distinct = (values) => new Set(values.map((value) => value.toFixed(3))).size;
33449
+ const rowsAlongY = signalPads.length > 2 && distinct(signalPads.map((pad2) => pad2.y)) === 2 && distinct(signalPads.map((pad2) => pad2.x)) > 2;
33450
+ const dfn2 = /* @__PURE__ */ jsx2(
33451
+ DFN,
33452
+ {
33453
+ num_pins: fpJson.num_pins,
33454
+ bodyWidth: rowsAlongY ? bodyLength10 : bodyWidth,
33455
+ bodyLength: rowsAlongY ? bodyWidth : bodyLength10,
33456
+ pitch: dim(fpJson.p, 0.5),
33457
+ padLength,
33458
+ padWidth,
33459
+ thermalPadSize: fpJson.ep && thermalPadWidth > 0 && thermalPadLength > 0 ? {
33460
+ width: rowsAlongY ? thermalPadLength : thermalPadWidth,
33461
+ length: rowsAlongY ? thermalPadWidth : thermalPadLength
33462
+ } : void 0
33463
+ }
33464
+ );
33465
+ return rowsAlongY ? /* @__PURE__ */ jsx2(Rotate, { rotation: [0, 0, "90deg"], children: dfn2 }) : dfn2;
33466
+ }
33467
+ case "mlp":
33468
+ case "lga":
33469
+ case "quad": {
33470
+ if (fpJson.legsoutside) {
33471
+ return /* @__PURE__ */ jsx2(
33472
+ QFP,
33473
+ {
33474
+ pinCount: fpJson.num_pins,
33475
+ pitch: dim(fpJson.p, 0.5),
33476
+ leadWidth: dim(fpJson.pw, 0.25),
33477
+ padContactLength: dim(fpJson.pl, 0.25),
33478
+ bodyWidth: dim(fpJson.w, 6)
33479
+ }
33480
+ );
33481
+ }
33482
+ return /* @__PURE__ */ jsx2(
33483
+ qfn_default,
33484
+ {
33485
+ num_pins: fpJson.num_pins,
33486
+ bodyWidth: dim(fpJson.w, 6),
33487
+ bodyLength: dim(fpJson.h, 6),
33488
+ pitch: dim(fpJson.p, 0.5),
33489
+ padLength: dim(fpJson.pl, 0.25),
33490
+ padWidth: dim(fpJson.pw, 0.25)
33491
+ }
33492
+ );
33493
+ }
33494
+ case "bga": {
33495
+ const pitch = dim(fpJson.p, 0.8);
33496
+ const columns = fpJson.grid?.x ?? 8;
33497
+ const rows = fpJson.grid?.y ?? 8;
33498
+ return /* @__PURE__ */ jsx2(
33499
+ BGA,
33500
+ {
33501
+ ballPitch: pitch,
33502
+ ballColumns: columns,
33503
+ ballRows: rows,
33504
+ ballDiameter: pitch * 0.625,
33505
+ packageWidth: columns * pitch,
33506
+ packageLength: rows * pitch
33507
+ }
33508
+ );
33509
+ }
31542
33510
  case "sod523":
31543
33511
  return /* @__PURE__ */ jsx2(SOD523, {});
31544
33512
  case "sod723":
@@ -31561,10 +33529,70 @@ var Footprinter3d = ({ footprint }) => {
31561
33529
  return /* @__PURE__ */ jsx2(SOD123FL, {});
31562
33530
  case "sod123w":
31563
33531
  return /* @__PURE__ */ jsx2(SOD123W, {});
33532
+ case "sod110":
33533
+ return /* @__PURE__ */ jsx2(SOD123W, { bodyWidth: 2.1, bodyLength: 1.4 });
31564
33534
  case "sod128":
31565
33535
  return /* @__PURE__ */ jsx2(SOD128, {});
31566
33536
  case "sod323":
31567
33537
  return /* @__PURE__ */ jsx2(SOD323, {});
33538
+ case "sod323w":
33539
+ return /* @__PURE__ */ jsx2(SOD323, {});
33540
+ case "sod80":
33541
+ return /* @__PURE__ */ jsx2(MINIMELF, {});
33542
+ case "sod882d":
33543
+ return /* @__PURE__ */ jsx2(SOD882, {});
33544
+ case "smbf":
33545
+ return /* @__PURE__ */ jsx2(SMB, {});
33546
+ case "led2835":
33547
+ return /* @__PURE__ */ jsx2(
33548
+ Led2835,
33549
+ {
33550
+ color,
33551
+ bodyWidth: dim(fpJson.w, 3.5),
33552
+ bodyLength: dim(fpJson.h, 2.8),
33553
+ pad1X: dim(fpJson.p1x, -0.9),
33554
+ pad1Width: dim(fpJson.p1w, 2.2),
33555
+ pad2X: dim(fpJson.p2x, 1.375),
33556
+ pad2Width: dim(fpJson.p2w, 1.25),
33557
+ padLength: dim(fpJson.ph, 2.2)
33558
+ }
33559
+ );
33560
+ case "electrolytic":
33561
+ case "radial": {
33562
+ const pitch = dim(fpJson.p, 2.5);
33563
+ const namedDiameter = footprint.match(/_d([\d.]+)/);
33564
+ const diameter = fpJson.d !== void 0 ? dim(fpJson.d, pitch * 2) : namedDiameter ? Number(namedDiameter[1]) : pitch * 2;
33565
+ return /* @__PURE__ */ jsx2(ElectrolyticCapacitor, { diameter, leadPitch: pitch });
33566
+ }
33567
+ case "potentiometer":
33568
+ return /* @__PURE__ */ jsx2(
33569
+ Potentiometer,
33570
+ {
33571
+ bodyWidth: dim(fpJson.w, 5.35),
33572
+ bodyLength: dim(fpJson.ca, 14),
33573
+ bodyHeight: dim(fpJson.h, 4),
33574
+ leads: getPlatedHoleCenters(normalizedFootprint)
33575
+ }
33576
+ );
33577
+ case "smdpushbutton":
33578
+ return /* @__PURE__ */ jsx2(
33579
+ SmdPushButton,
33580
+ {
33581
+ padSpanX: dim(fpJson.px, 4.2),
33582
+ padSpanY: dim(fpJson.py, 2.15),
33583
+ padWidth: dim(fpJson.pw, 1.05),
33584
+ padLength: dim(fpJson.ph, 0.7)
33585
+ }
33586
+ );
33587
+ case "breakoutheaders": {
33588
+ const pitch = dim(fpJson.p, 2.54);
33589
+ const halfWidth = dim(fpJson.w, 10) / 2;
33590
+ const sides2 = [
33591
+ { x: -halfWidth, pins: fpJson.left ?? 0, key: "left" },
33592
+ { x: halfWidth, pins: fpJson.right ?? 0, key: "right" }
33593
+ ];
33594
+ return /* @__PURE__ */ jsx2(Fragment2, { children: sides2.filter(({ pins }) => pins > 0).map(({ x, pins, key }) => /* @__PURE__ */ jsx2(Translate, { center: [x, 0, 0], children: /* @__PURE__ */ jsx2(Rotate, { rotation: [0, 0, "90deg"], children: /* @__PURE__ */ jsx2(PinRow, { numberOfPins: pins, pitch }) }) }, key)) });
33595
+ }
31568
33596
  case "sod923":
31569
33597
  return /* @__PURE__ */ jsx2(SOD923, {});
31570
33598
  case "hc49":
@@ -31598,9 +33626,50 @@ var Footprinter3d = ({ footprint }) => {
31598
33626
  case "sot723":
31599
33627
  return /* @__PURE__ */ jsx2(SOT723, {});
31600
33628
  case "to220":
31601
- return /* @__PURE__ */ jsx2(TO220, {});
33629
+ return /* @__PURE__ */ jsx2(TO220, { leads: getPlatedHoleCenters(normalizedFootprint) });
33630
+ case "to220f":
33631
+ return /* @__PURE__ */ jsx2(TO220, { mouldedTab: true, leads: getPlatedHoleCenters(normalizedFootprint) });
31602
33632
  case "to92":
31603
- return /* @__PURE__ */ jsx2(TO92, {});
33633
+ return /* @__PURE__ */ jsx2(TO92, { leads: getPlatedHoleCenters(normalizedFootprint) });
33634
+ case "to92l":
33635
+ case "to92s": {
33636
+ const across = dim(fpJson.w, 4.8);
33637
+ const along = dim(fpJson.h, 4);
33638
+ const diameter = Math.max(across, along);
33639
+ return /* @__PURE__ */ jsx2(
33640
+ TO92,
33641
+ {
33642
+ bodyDiameter: diameter,
33643
+ flatCut: Math.max(diameter - Math.min(across, along), 0.4),
33644
+ leads: getPlatedHoleCenters(normalizedFootprint)
33645
+ }
33646
+ );
33647
+ }
33648
+ case "to252":
33649
+ case "dpak":
33650
+ case "to263":
33651
+ case "d2pak": {
33652
+ const isD2Pak = fpJson.fn === "to263" || fpJson.fn === "d2pak";
33653
+ const tabWidth = dim(fpJson.tabw, isD2Pak ? 8.38 : 6.2);
33654
+ const tabLength = Math.min(
33655
+ dim(fpJson.tabh, isD2Pak ? 10 : 5.8),
33656
+ isD2Pak ? 10 : 6.5
33657
+ );
33658
+ return /* @__PURE__ */ jsx2(
33659
+ DPAK,
33660
+ {
33661
+ bodyWidth: tabWidth,
33662
+ bodyLength: dim(fpJson.w, isD2Pak ? 10.1 : 6.6),
33663
+ bodyHeight: isD2Pak ? 4.4 : 2.3,
33664
+ tabWidth,
33665
+ tabLength,
33666
+ span: dim(fpJson.span, isD2Pak ? 10.21 : 6.85),
33667
+ pitch: dim(fpJson.p, isD2Pak ? 2.54 : 2.29),
33668
+ leadWidth: dim(fpJson.pw, 1.5),
33669
+ leadContactLength: dim(fpJson.pl, 3)
33670
+ }
33671
+ );
33672
+ }
31604
33673
  case "stampboard":
31605
33674
  case "stampreceiver":
31606
33675
  return /* @__PURE__ */ jsx2(
@@ -33089,9 +35158,9 @@ var StepModel = ({
33089
35158
  // src/utils/cad-model-loader-transform.ts
33090
35159
  import * as THREE11 from "three";
33091
35160
  function applyCoordinateTransform(point, config) {
33092
- let { x, y, z: z21 } = point;
35161
+ let { x, y, z: z22 } = point;
33093
35162
  if (config.axisMapping) {
33094
- const original = { x, y, z: z21 };
35163
+ const original = { x, y, z: z22 };
33095
35164
  if (config.axisMapping.x) {
33096
35165
  x = getAxisValue(original, config.axisMapping.x);
33097
35166
  }
@@ -33099,30 +35168,30 @@ function applyCoordinateTransform(point, config) {
33099
35168
  y = getAxisValue(original, config.axisMapping.y);
33100
35169
  }
33101
35170
  if (config.axisMapping.z) {
33102
- z21 = getAxisValue(original, config.axisMapping.z);
35171
+ z22 = getAxisValue(original, config.axisMapping.z);
33103
35172
  }
33104
35173
  }
33105
35174
  x *= config.flipX ?? 1;
33106
35175
  y *= config.flipY ?? 1;
33107
- z21 *= config.flipZ ?? 1;
35176
+ z22 *= config.flipZ ?? 1;
33108
35177
  if (config.rotation) {
33109
35178
  if (config.rotation.x) {
33110
35179
  const rad = config.rotation.x * Math.PI / 180;
33111
35180
  const cos = Math.cos(rad);
33112
35181
  const sin = Math.sin(rad);
33113
- const newY = y * cos - z21 * sin;
33114
- const newZ = y * sin + z21 * cos;
35182
+ const newY = y * cos - z22 * sin;
35183
+ const newZ = y * sin + z22 * cos;
33115
35184
  y = newY;
33116
- z21 = newZ;
35185
+ z22 = newZ;
33117
35186
  }
33118
35187
  if (config.rotation.y) {
33119
35188
  const rad = config.rotation.y * Math.PI / 180;
33120
35189
  const cos = Math.cos(rad);
33121
35190
  const sin = Math.sin(rad);
33122
- const newX = x * cos + z21 * sin;
33123
- const newZ = -x * sin + z21 * cos;
35191
+ const newX = x * cos + z22 * sin;
35192
+ const newZ = -x * sin + z22 * cos;
33124
35193
  x = newX;
33125
- z21 = newZ;
35194
+ z22 = newZ;
33126
35195
  }
33127
35196
  if (config.rotation.z) {
33128
35197
  const rad = config.rotation.z * Math.PI / 180;
@@ -33134,7 +35203,7 @@ function applyCoordinateTransform(point, config) {
33134
35203
  y = newY;
33135
35204
  }
33136
35205
  }
33137
- return { x, y, z: z21 };
35206
+ return { x, y, z: z22 };
33138
35207
  }
33139
35208
  function getAxisValue(original, mapping) {
33140
35209
  switch (mapping) {
@@ -33696,7 +35765,7 @@ import * as THREE23 from "three";
33696
35765
  // package.json
33697
35766
  var package_default = {
33698
35767
  name: "@tscircuit/3d-viewer",
33699
- version: "0.0.595",
35768
+ version: "0.0.597",
33700
35769
  repository: {
33701
35770
  type: "git",
33702
35771
  url: "https://github.com/tscircuit/3d-viewer"
@@ -33761,7 +35830,7 @@ var package_default = {
33761
35830
  "bun-match-svg": "^0.0.9",
33762
35831
  "bun-types": "1.2.1",
33763
35832
  debug: "^4.4.0",
33764
- "jscad-electronics": "^0.0.146",
35833
+ "jscad-electronics": "^0.0.159",
33765
35834
  "jscad-planner": "^0.0.13",
33766
35835
  jsdom: "^26.0.0",
33767
35836
  "manifold-3d": "^3.2.1",
@@ -33883,13 +35952,13 @@ var CameraControllerProvider = ({ children, defaultTarget, initialCameraPosition
33883
35952
  new THREE13.Euler(0, 0, 0)
33884
35953
  );
33885
35954
  const baseDistance = useMemo10(() => {
33886
- const [x, y, z21] = initialCameraPosition ?? [5, -5, 5];
33887
- const distance5 = Math.hypot(
35955
+ const [x, y, z22] = initialCameraPosition ?? [5, -5, 5];
35956
+ const distance6 = Math.hypot(
33888
35957
  x - defaultTarget.x,
33889
35958
  y - defaultTarget.y,
33890
- z21 - defaultTarget.z
35959
+ z22 - defaultTarget.z
33891
35960
  );
33892
- return distance5 > 0 ? distance5 : 5;
35961
+ return distance6 > 0 ? distance6 : 5;
33893
35962
  }, [initialCameraPosition, defaultTarget]);
33894
35963
  const getPresetConfig = useCallback4(
33895
35964
  (preset) => {
@@ -33900,13 +35969,13 @@ var CameraControllerProvider = ({ children, defaultTarget, initialCameraPosition
33900
35969
  ];
33901
35970
  const camera = mainCameraRef.current;
33902
35971
  const controls = controlsRef.current;
33903
- let distance5 = baseDistance;
35972
+ let distance6 = baseDistance;
33904
35973
  if (camera && controls) {
33905
- distance5 = camera.position.distanceTo(controls.target);
35974
+ distance6 = camera.position.distanceTo(controls.target);
33906
35975
  }
33907
35976
  switch (preset) {
33908
35977
  case "Top Center Angled": {
33909
- const angledOffset = distance5 / Math.sqrt(2);
35978
+ const angledOffset = distance6 / Math.sqrt(2);
33910
35979
  return {
33911
35980
  position: [
33912
35981
  defaultTarget.x,
@@ -33922,7 +35991,7 @@ var CameraControllerProvider = ({ children, defaultTarget, initialCameraPosition
33922
35991
  position: [
33923
35992
  defaultTarget.x,
33924
35993
  defaultTarget.y,
33925
- defaultTarget.z + distance5
35994
+ defaultTarget.z + distance6
33926
35995
  ],
33927
35996
  target: targetVector,
33928
35997
  up: [0, 0, 1]
@@ -33930,9 +35999,9 @@ var CameraControllerProvider = ({ children, defaultTarget, initialCameraPosition
33930
35999
  case "Top Left Corner":
33931
36000
  return {
33932
36001
  position: [
33933
- defaultTarget.x - distance5 * 0.6,
33934
- defaultTarget.y - distance5 * 0.6,
33935
- defaultTarget.z + distance5 * 0.6
36002
+ defaultTarget.x - distance6 * 0.6,
36003
+ defaultTarget.y - distance6 * 0.6,
36004
+ defaultTarget.z + distance6 * 0.6
33936
36005
  ],
33937
36006
  target: targetVector,
33938
36007
  up: [0, 0, 1]
@@ -33940,9 +36009,9 @@ var CameraControllerProvider = ({ children, defaultTarget, initialCameraPosition
33940
36009
  case "Top Right Corner":
33941
36010
  return {
33942
36011
  position: [
33943
- defaultTarget.x + distance5 * 0.6,
33944
- defaultTarget.y - distance5 * 0.6,
33945
- defaultTarget.z + distance5 * 0.6
36012
+ defaultTarget.x + distance6 * 0.6,
36013
+ defaultTarget.y - distance6 * 0.6,
36014
+ defaultTarget.z + distance6 * 0.6
33946
36015
  ],
33947
36016
  target: targetVector,
33948
36017
  up: [0, 0, 1]
@@ -33950,7 +36019,7 @@ var CameraControllerProvider = ({ children, defaultTarget, initialCameraPosition
33950
36019
  case "Left Sideview":
33951
36020
  return {
33952
36021
  position: [
33953
- defaultTarget.x - distance5,
36022
+ defaultTarget.x - distance6,
33954
36023
  defaultTarget.y,
33955
36024
  defaultTarget.z
33956
36025
  ],
@@ -33960,7 +36029,7 @@ var CameraControllerProvider = ({ children, defaultTarget, initialCameraPosition
33960
36029
  case "Right Sideview":
33961
36030
  return {
33962
36031
  position: [
33963
- defaultTarget.x + distance5,
36032
+ defaultTarget.x + distance6,
33964
36033
  defaultTarget.y,
33965
36034
  defaultTarget.z
33966
36035
  ],
@@ -33971,7 +36040,7 @@ var CameraControllerProvider = ({ children, defaultTarget, initialCameraPosition
33971
36040
  return {
33972
36041
  position: [
33973
36042
  defaultTarget.x,
33974
- defaultTarget.y - distance5,
36043
+ defaultTarget.y - distance6,
33975
36044
  defaultTarget.z
33976
36045
  ],
33977
36046
  target: targetVector,
@@ -34768,13 +36837,13 @@ import { useEffect as useEffect18, useRef as useRef7 } from "react";
34768
36837
  import * as THREE20 from "three";
34769
36838
  import { Text as TroikaText } from "troika-three-text";
34770
36839
  import { jsx as jsx14 } from "react/jsx-runtime";
34771
- function computePointInFront(rotationVector, distance5) {
36840
+ function computePointInFront(rotationVector, distance6) {
34772
36841
  const quaternion = new THREE20.Quaternion().setFromEuler(
34773
36842
  new THREE20.Euler(rotationVector.x, rotationVector.y, rotationVector.z)
34774
36843
  );
34775
36844
  const forwardVector = new THREE20.Vector3(0, 0, 1);
34776
36845
  forwardVector.applyQuaternion(quaternion);
34777
- const result = forwardVector.multiplyScalar(distance5);
36846
+ const result = forwardVector.multiplyScalar(distance6);
34778
36847
  return result;
34779
36848
  }
34780
36849
  var OrientationCubeCanvas = () => {
@@ -35264,13 +37333,13 @@ var fitCameraToBounds = (camera, controls, bounds, padding = 1.18) => {
35264
37333
  const radius = Math.max(Math.hypot(width10, height10, depth) / 2, 1);
35265
37334
  const previousTarget = controls?.target ?? new THREE22.Vector3();
35266
37335
  const direction = new THREE22.Vector3(0, -0.75, 0.9).normalize();
35267
- let distance5 = Math.max(camera.position.distanceTo(previousTarget), 5);
37336
+ let distance6 = Math.max(camera.position.distanceTo(previousTarget), 5);
35268
37337
  if (camera instanceof THREE22.PerspectiveCamera) {
35269
37338
  const verticalFov = THREE22.MathUtils.degToRad(camera.fov);
35270
37339
  const horizontalFov = 2 * Math.atan(Math.tan(verticalFov / 2) * camera.aspect);
35271
37340
  const limitingFov = Math.min(verticalFov, horizontalFov);
35272
- distance5 = radius * padding / Math.sin(limitingFov / 2);
35273
- camera.far = Math.max(camera.far, distance5 + radius * padding * 3);
37341
+ distance6 = radius * padding / Math.sin(limitingFov / 2);
37342
+ camera.far = Math.max(camera.far, distance6 + radius * padding * 3);
35274
37343
  camera.updateProjectionMatrix();
35275
37344
  } else if (camera instanceof THREE22.OrthographicCamera) {
35276
37345
  const halfViewWidth = Math.abs(camera.right - camera.left) / 2;
@@ -35279,17 +37348,17 @@ var fitCameraToBounds = (camera, controls, bounds, padding = 1.18) => {
35279
37348
  halfViewWidth / (radius * padding),
35280
37349
  halfViewHeight / (radius * padding)
35281
37350
  );
35282
- distance5 = Math.max(distance5, radius * padding * 2);
37351
+ distance6 = Math.max(distance6, radius * padding * 2);
35283
37352
  camera.updateProjectionMatrix();
35284
37353
  }
35285
- camera.position.copy(center).addScaledVector(direction, distance5);
37354
+ camera.position.copy(center).addScaledVector(direction, distance6);
35286
37355
  camera.lookAt(center);
35287
37356
  camera.updateMatrixWorld();
35288
37357
  if (controls) {
35289
37358
  controls.target.copy(center);
35290
37359
  controls.update();
35291
37360
  }
35292
- return { center, radius, distance: distance5 };
37361
+ return { center, radius, distance: distance6 };
35293
37362
  };
35294
37363
 
35295
37364
  // src/three-components/reference-object.tsx
@@ -49432,27 +51501,6 @@ var CadViewerInner = (props) => {
49432
51501
  referenceObject
49433
51502
  }
49434
51503
  ),
49435
- /* @__PURE__ */ jsxs11(
49436
- "div",
49437
- {
49438
- style: {
49439
- position: "absolute",
49440
- right: 8,
49441
- top: 8,
49442
- background: "#222",
49443
- color: "#fff",
49444
- padding: "2px 8px",
49445
- borderRadius: 4,
49446
- fontSize: 12,
49447
- opacity: 0.7,
49448
- userSelect: "none"
49449
- },
49450
- children: [
49451
- "Engine: ",
49452
- /* @__PURE__ */ jsx37("b", { children: engine === "jscad" ? "JSCAD" : "Manifold" })
49453
- ]
49454
- }
49455
- ),
49456
51504
  menuVisible && /* @__PURE__ */ jsx37(
49457
51505
  ContextMenu,
49458
51506
  {