@tscircuit/3d-viewer 0.0.611 → 0.0.613
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +2322 -1334
- package/package.json +7 -6
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,
|
|
288
|
-
const lengthSquared = x * x + y * y +
|
|
287
|
+
let [x, y, z27] = axis;
|
|
288
|
+
const lengthSquared = x * x + y * y + z27 * z27;
|
|
289
289
|
if (Math.abs(lengthSquared) < EPS3) {
|
|
290
290
|
return identity(out);
|
|
291
291
|
}
|
|
292
292
|
const len = 1 / Math.sqrt(lengthSquared);
|
|
293
293
|
x *= len;
|
|
294
294
|
y *= len;
|
|
295
|
-
|
|
295
|
+
z27 *= 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 +
|
|
301
|
-
out[2] =
|
|
300
|
+
out[1] = y * x * t + z27 * s;
|
|
301
|
+
out[2] = z27 * x * t - y * s;
|
|
302
302
|
out[3] = 0;
|
|
303
|
-
out[4] = x * y * t -
|
|
303
|
+
out[4] = x * y * t - z27 * s;
|
|
304
304
|
out[5] = y * y * t + c;
|
|
305
|
-
out[6] =
|
|
305
|
+
out[6] = z27 * y * t + x * s;
|
|
306
306
|
out[7] = 0;
|
|
307
|
-
out[8] = x *
|
|
308
|
-
out[9] = y *
|
|
309
|
-
out[10] =
|
|
307
|
+
out[8] = x * z27 * t + y * s;
|
|
308
|
+
out[9] = y * z27 * t - x * s;
|
|
309
|
+
out[10] = z27 * z27 * t + c;
|
|
310
310
|
out[11] = 0;
|
|
311
311
|
out[12] = 0;
|
|
312
312
|
out[13] = 0;
|
|
@@ -560,8 +560,8 @@ var require_distance = __commonJS({
|
|
|
560
560
|
var distance6 = (a, b) => {
|
|
561
561
|
const x = b[0] - a[0];
|
|
562
562
|
const y = b[1] - a[1];
|
|
563
|
-
const
|
|
564
|
-
return Math.sqrt(x * x + y * y +
|
|
563
|
+
const z27 = b[2] - a[2];
|
|
564
|
+
return Math.sqrt(x * x + y * y + z27 * z27);
|
|
565
565
|
};
|
|
566
566
|
module.exports = distance6;
|
|
567
567
|
}
|
|
@@ -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,
|
|
612
|
+
var fromValues = (x, y, z27) => {
|
|
613
613
|
const out = create();
|
|
614
614
|
out[0] = x;
|
|
615
615
|
out[1] = y;
|
|
616
|
-
out[2] =
|
|
616
|
+
out[2] = z27;
|
|
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,
|
|
627
|
+
var fromVector2 = (out, vector, z27 = 0) => {
|
|
628
628
|
out[0] = vector[0];
|
|
629
629
|
out[1] = vector[1];
|
|
630
|
-
out[2] =
|
|
630
|
+
out[2] = z27;
|
|
631
631
|
return out;
|
|
632
632
|
};
|
|
633
633
|
module.exports = fromVector2;
|
|
@@ -641,8 +641,8 @@ var require_length = __commonJS({
|
|
|
641
641
|
var length83 = (vector) => {
|
|
642
642
|
const x = vector[0];
|
|
643
643
|
const y = vector[1];
|
|
644
|
-
const
|
|
645
|
-
return Math.sqrt(x * x + y * y +
|
|
644
|
+
const z27 = vector[2];
|
|
645
|
+
return Math.sqrt(x * x + y * y + z27 * z27);
|
|
646
646
|
};
|
|
647
647
|
module.exports = length83;
|
|
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
|
|
729
|
-
let len = x * x + y * y +
|
|
728
|
+
const z27 = vector[2];
|
|
729
|
+
let len = x * x + y * y + z27 * z27;
|
|
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] =
|
|
735
|
+
out[2] = z27 * 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
|
|
860
|
-
return x * x + y * y +
|
|
859
|
+
const z27 = b[2] - a[2];
|
|
860
|
+
return x * x + y * y + z27 * z27;
|
|
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
|
|
874
|
-
return x * x + y * y +
|
|
873
|
+
const z27 = vector[2];
|
|
874
|
+
return x * x + y * y + z27 * z27;
|
|
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
|
|
911
|
-
let w = matrix[3] * x + matrix[7] * y + matrix[11] *
|
|
910
|
+
const z27 = vector[2];
|
|
911
|
+
let w = matrix[3] * x + matrix[7] * y + matrix[11] * z27 + matrix[15];
|
|
912
912
|
w = w || 1;
|
|
913
|
-
out[0] = (matrix[0] * x + matrix[4] * y + matrix[8] *
|
|
914
|
-
out[1] = (matrix[1] * x + matrix[5] * y + matrix[9] *
|
|
915
|
-
out[2] = (matrix[2] * x + matrix[6] * y + matrix[10] *
|
|
913
|
+
out[0] = (matrix[0] * x + matrix[4] * y + matrix[8] * z27 + matrix[12]) / w;
|
|
914
|
+
out[1] = (matrix[1] * x + matrix[5] * y + matrix[9] * z27 + matrix[13]) / w;
|
|
915
|
+
out[2] = (matrix[2] * x + matrix[6] * y + matrix[10] * z27 + 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
|
|
1118
|
-
const d = x * matrix[2] + y * matrix[6] +
|
|
1117
|
+
const z27 = matrix[0] * matrix[5] - matrix[4] * matrix[1];
|
|
1118
|
+
const d = x * matrix[2] + y * matrix[6] + z27 * 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,
|
|
1221
|
-
const lengthSquared = x * x + y * y +
|
|
1220
|
+
let [x, y, z27] = axis;
|
|
1221
|
+
const lengthSquared = x * x + y * y + z27 * z27;
|
|
1222
1222
|
if (Math.abs(lengthSquared) < EPS3) {
|
|
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
|
-
|
|
1228
|
+
z27 *= 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 +
|
|
1246
|
-
const b02 =
|
|
1247
|
-
const b10 = x * y * t -
|
|
1245
|
+
const b01 = y * x * t + z27 * s;
|
|
1246
|
+
const b02 = z27 * x * t - y * s;
|
|
1247
|
+
const b10 = x * y * t - z27 * s;
|
|
1248
1248
|
const b11 = y * y * t + c;
|
|
1249
|
-
const b12 =
|
|
1250
|
-
const b20 = x *
|
|
1251
|
-
const b21 = y *
|
|
1252
|
-
const b22 =
|
|
1249
|
+
const b12 = z27 * y * t + x * s;
|
|
1250
|
+
const b20 = x * z27 * t + y * s;
|
|
1251
|
+
const b21 = y * z27 * t - x * s;
|
|
1252
|
+
const b22 = z27 * z27 * 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
|
|
1404
|
+
const z27 = 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] *
|
|
1414
|
-
out[9] = matrix[9] *
|
|
1415
|
-
out[10] = matrix[10] *
|
|
1416
|
-
out[11] = matrix[11] *
|
|
1413
|
+
out[8] = matrix[8] * z27;
|
|
1414
|
+
out[9] = matrix[9] * z27;
|
|
1415
|
+
out[10] = matrix[10] * z27;
|
|
1416
|
+
out[11] = matrix[11] * z27;
|
|
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
|
|
1470
|
+
const z27 = 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] *
|
|
1485
|
-
out[13] = matrix[1] * x + matrix[5] * y + matrix[9] *
|
|
1486
|
-
out[14] = matrix[2] * x + matrix[6] * y + matrix[10] *
|
|
1487
|
-
out[15] = matrix[3] * x + matrix[7] * y + matrix[11] *
|
|
1484
|
+
out[12] = matrix[0] * x + matrix[4] * y + matrix[8] * z27 + matrix[12];
|
|
1485
|
+
out[13] = matrix[1] * x + matrix[5] * y + matrix[9] * z27 + matrix[13];
|
|
1486
|
+
out[14] = matrix[2] * x + matrix[6] * y + matrix[10] * z27 + matrix[14];
|
|
1487
|
+
out[15] = matrix[3] * x + matrix[7] * y + matrix[11] * z27 + 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 *
|
|
1514
|
-
out[13] = a01 * x + a11 * y + a21 *
|
|
1515
|
-
out[14] = a02 * x + a12 * y + a22 *
|
|
1516
|
-
out[15] = a03 * x + a13 * y + a23 *
|
|
1513
|
+
out[12] = a00 * x + a10 * y + a20 * z27 + matrix[12];
|
|
1514
|
+
out[13] = a01 * x + a11 * y + a21 * z27 + matrix[13];
|
|
1515
|
+
out[14] = a02 * x + a12 * y + a22 * z27 + matrix[14];
|
|
1516
|
+
out[15] = a03 * x + a13 * y + a23 * z27 + matrix[15];
|
|
1517
1517
|
}
|
|
1518
1518
|
return out;
|
|
1519
1519
|
};
|
|
@@ -2351,7 +2351,7 @@ var require_validate = __commonJS({
|
|
|
2351
2351
|
var vec2 = require_vec2();
|
|
2352
2352
|
var isA = require_isA();
|
|
2353
2353
|
var toOutlines = require_toOutlines();
|
|
2354
|
-
var
|
|
2354
|
+
var validate2 = (object) => {
|
|
2355
2355
|
if (!isA(object)) {
|
|
2356
2356
|
throw new Error("invalid geom2 structure");
|
|
2357
2357
|
}
|
|
@@ -2365,7 +2365,7 @@ var require_validate = __commonJS({
|
|
|
2365
2365
|
throw new Error(`geom2 invalid transforms ${object.transforms}`);
|
|
2366
2366
|
}
|
|
2367
2367
|
};
|
|
2368
|
-
module.exports =
|
|
2368
|
+
module.exports = validate2;
|
|
2369
2369
|
}
|
|
2370
2370
|
});
|
|
2371
2371
|
|
|
@@ -2616,9 +2616,9 @@ var require_HalfEdge = __commonJS({
|
|
|
2616
2616
|
var distance6 = require_distance();
|
|
2617
2617
|
var squaredDistance = require_squaredDistance();
|
|
2618
2618
|
var HalfEdge = class {
|
|
2619
|
-
constructor(vertex,
|
|
2619
|
+
constructor(vertex, face2) {
|
|
2620
2620
|
this.vertex = vertex;
|
|
2621
|
-
this.face =
|
|
2621
|
+
this.face = face2;
|
|
2622
2622
|
this.next = null;
|
|
2623
2623
|
this.prev = null;
|
|
2624
2624
|
this.opposite = null;
|
|
@@ -2844,16 +2844,16 @@ var require_Face = __commonJS({
|
|
|
2844
2844
|
return indices;
|
|
2845
2845
|
}
|
|
2846
2846
|
static createTriangle(v0, v1, v2, minArea = 0) {
|
|
2847
|
-
const
|
|
2848
|
-
const e0 = new HalfEdge(v0,
|
|
2849
|
-
const e1 = new HalfEdge(v1,
|
|
2850
|
-
const e2 = new HalfEdge(v2,
|
|
2847
|
+
const face2 = new _Face();
|
|
2848
|
+
const e0 = new HalfEdge(v0, face2);
|
|
2849
|
+
const e1 = new HalfEdge(v1, face2);
|
|
2850
|
+
const e2 = new HalfEdge(v2, face2);
|
|
2851
2851
|
e0.next = e2.prev = e1;
|
|
2852
2852
|
e1.next = e0.prev = e2;
|
|
2853
2853
|
e2.next = e1.prev = e0;
|
|
2854
|
-
|
|
2855
|
-
|
|
2856
|
-
return
|
|
2854
|
+
face2.edge = e0;
|
|
2855
|
+
face2.computeNormalAndCentroid(minArea);
|
|
2856
|
+
return face2;
|
|
2857
2857
|
}
|
|
2858
2858
|
};
|
|
2859
2859
|
module.exports = {
|
|
@@ -2899,14 +2899,14 @@ var require_QuickHull = __commonJS({
|
|
|
2899
2899
|
this.discardedFaces = [];
|
|
2900
2900
|
this.vertexPointIndices = [];
|
|
2901
2901
|
}
|
|
2902
|
-
addVertexToFace(vertex,
|
|
2903
|
-
vertex.face =
|
|
2904
|
-
if (!
|
|
2902
|
+
addVertexToFace(vertex, face2) {
|
|
2903
|
+
vertex.face = face2;
|
|
2904
|
+
if (!face2.outside) {
|
|
2905
2905
|
this.claimed.add(vertex);
|
|
2906
2906
|
} else {
|
|
2907
|
-
this.claimed.insertBefore(
|
|
2907
|
+
this.claimed.insertBefore(face2.outside, vertex);
|
|
2908
2908
|
}
|
|
2909
|
-
|
|
2909
|
+
face2.outside = vertex;
|
|
2910
2910
|
}
|
|
2911
2911
|
/**
|
|
2912
2912
|
* Removes `vertex` for the `claimed` list of vertices, it also makes sure
|
|
@@ -2916,12 +2916,12 @@ var require_QuickHull = __commonJS({
|
|
|
2916
2916
|
* @param {Vertex} vertex
|
|
2917
2917
|
* @param {Face} face
|
|
2918
2918
|
*/
|
|
2919
|
-
removeVertexFromFace(vertex,
|
|
2920
|
-
if (vertex ===
|
|
2921
|
-
if (vertex.next && vertex.next.face ===
|
|
2922
|
-
|
|
2919
|
+
removeVertexFromFace(vertex, face2) {
|
|
2920
|
+
if (vertex === face2.outside) {
|
|
2921
|
+
if (vertex.next && vertex.next.face === face2) {
|
|
2922
|
+
face2.outside = vertex.next;
|
|
2923
2923
|
} else {
|
|
2924
|
-
|
|
2924
|
+
face2.outside = null;
|
|
2925
2925
|
}
|
|
2926
2926
|
}
|
|
2927
2927
|
this.claimed.remove(vertex);
|
|
@@ -2934,15 +2934,15 @@ var require_QuickHull = __commonJS({
|
|
|
2934
2934
|
* @return {Vertex|undefined} If face had visible vertices returns
|
|
2935
2935
|
* `face.outside`, otherwise undefined
|
|
2936
2936
|
*/
|
|
2937
|
-
removeAllVerticesFromFace(
|
|
2938
|
-
if (
|
|
2939
|
-
let end =
|
|
2940
|
-
while (end.next && end.next.face ===
|
|
2937
|
+
removeAllVerticesFromFace(face2) {
|
|
2938
|
+
if (face2.outside) {
|
|
2939
|
+
let end = face2.outside;
|
|
2940
|
+
while (end.next && end.next.face === face2) {
|
|
2941
2941
|
end = end.next;
|
|
2942
2942
|
}
|
|
2943
|
-
this.claimed.removeChain(
|
|
2943
|
+
this.claimed.removeChain(face2.outside, end);
|
|
2944
2944
|
end.next = null;
|
|
2945
|
-
return
|
|
2945
|
+
return face2.outside;
|
|
2946
2946
|
}
|
|
2947
2947
|
}
|
|
2948
2948
|
/**
|
|
@@ -2959,8 +2959,8 @@ var require_QuickHull = __commonJS({
|
|
|
2959
2959
|
* @param {Face} face
|
|
2960
2960
|
* @param {Face} [absorbingFace]
|
|
2961
2961
|
*/
|
|
2962
|
-
deleteFaceVertices(
|
|
2963
|
-
const faceVertices = this.removeAllVerticesFromFace(
|
|
2962
|
+
deleteFaceVertices(face2, absorbingFace) {
|
|
2963
|
+
const faceVertices = this.removeAllVerticesFromFace(face2);
|
|
2964
2964
|
if (faceVertices) {
|
|
2965
2965
|
if (!absorbingFace) {
|
|
2966
2966
|
this.unclaimed.addAll(faceVertices);
|
|
@@ -2991,12 +2991,12 @@ var require_QuickHull = __commonJS({
|
|
|
2991
2991
|
let maxDistance = this.tolerance;
|
|
2992
2992
|
let maxFace;
|
|
2993
2993
|
for (let i = 0; i < newFaces.length; i += 1) {
|
|
2994
|
-
const
|
|
2995
|
-
if (
|
|
2996
|
-
const dist =
|
|
2994
|
+
const face2 = newFaces[i];
|
|
2995
|
+
if (face2.mark === VISIBLE) {
|
|
2996
|
+
const dist = face2.distanceToPlane(vertex.point);
|
|
2997
2997
|
if (dist > maxDistance) {
|
|
2998
2998
|
maxDistance = dist;
|
|
2999
|
-
maxFace =
|
|
2999
|
+
maxFace = face2;
|
|
3000
3000
|
}
|
|
3001
3001
|
if (maxDistance > 1e3 * this.tolerance) {
|
|
3002
3002
|
break;
|
|
@@ -3142,9 +3142,9 @@ var require_QuickHull = __commonJS({
|
|
|
3142
3142
|
reindexFaceAndVertices() {
|
|
3143
3143
|
const activeFaces = [];
|
|
3144
3144
|
for (let i = 0; i < this.faces.length; i += 1) {
|
|
3145
|
-
const
|
|
3146
|
-
if (
|
|
3147
|
-
activeFaces.push(
|
|
3145
|
+
const face2 = this.faces[i];
|
|
3146
|
+
if (face2.mark === VISIBLE) {
|
|
3147
|
+
activeFaces.push(face2);
|
|
3148
3148
|
}
|
|
3149
3149
|
}
|
|
3150
3150
|
this.faces = activeFaces;
|
|
@@ -3205,12 +3205,12 @@ var require_QuickHull = __commonJS({
|
|
|
3205
3205
|
* @param {HalfEdge[]} horizon - The edges that form part of the horizon in
|
|
3206
3206
|
* ccw order
|
|
3207
3207
|
*/
|
|
3208
|
-
computeHorizon(eyePoint, crossEdge,
|
|
3209
|
-
this.deleteFaceVertices(
|
|
3210
|
-
|
|
3208
|
+
computeHorizon(eyePoint, crossEdge, face2, horizon) {
|
|
3209
|
+
this.deleteFaceVertices(face2);
|
|
3210
|
+
face2.mark = DELETED;
|
|
3211
3211
|
let edge;
|
|
3212
3212
|
if (!crossEdge) {
|
|
3213
|
-
edge = crossEdge =
|
|
3213
|
+
edge = crossEdge = face2.getEdge(0);
|
|
3214
3214
|
} else {
|
|
3215
3215
|
edge = crossEdge.next;
|
|
3216
3216
|
}
|
|
@@ -3236,14 +3236,14 @@ var require_QuickHull = __commonJS({
|
|
|
3236
3236
|
* @return {HalfEdge} The half edge whose vertex is the eyeVertex
|
|
3237
3237
|
*/
|
|
3238
3238
|
addAdjoiningFace(eyeVertex, horizonEdge) {
|
|
3239
|
-
const
|
|
3239
|
+
const face2 = Face.createTriangle(
|
|
3240
3240
|
eyeVertex,
|
|
3241
3241
|
horizonEdge.tail(),
|
|
3242
3242
|
horizonEdge.head()
|
|
3243
3243
|
);
|
|
3244
|
-
this.faces.push(
|
|
3245
|
-
|
|
3246
|
-
return
|
|
3244
|
+
this.faces.push(face2);
|
|
3245
|
+
face2.getEdge(-1).setOpposite(horizonEdge.opposite);
|
|
3246
|
+
return face2.getEdge(0);
|
|
3247
3247
|
}
|
|
3248
3248
|
/**
|
|
3249
3249
|
* Adds horizon.length faces to the hull, each face will be 'linked' with the
|
|
@@ -3318,12 +3318,12 @@ var require_QuickHull = __commonJS({
|
|
|
3318
3318
|
* @param {number} mergeType - Either MERGE_NON_CONVEX_WRT_LARGER_FACE or
|
|
3319
3319
|
* MERGE_NON_CONVEX
|
|
3320
3320
|
*/
|
|
3321
|
-
doAdjacentMerge(
|
|
3322
|
-
let edge =
|
|
3321
|
+
doAdjacentMerge(face2, mergeType) {
|
|
3322
|
+
let edge = face2.edge;
|
|
3323
3323
|
let convex = true;
|
|
3324
3324
|
let it = 0;
|
|
3325
3325
|
do {
|
|
3326
|
-
if (it >=
|
|
3326
|
+
if (it >= face2.nVertices) {
|
|
3327
3327
|
throw Error("merge recursion limit exceeded");
|
|
3328
3328
|
}
|
|
3329
3329
|
const oppositeFace = edge.opposite.face;
|
|
@@ -3333,7 +3333,7 @@ var require_QuickHull = __commonJS({
|
|
|
3333
3333
|
merge = true;
|
|
3334
3334
|
}
|
|
3335
3335
|
} else {
|
|
3336
|
-
if (
|
|
3336
|
+
if (face2.area > oppositeFace.area) {
|
|
3337
3337
|
if (this.oppositeFaceDistance(edge) > -this.tolerance) {
|
|
3338
3338
|
merge = true;
|
|
3339
3339
|
} else if (this.oppositeFaceDistance(edge.opposite) > -this.tolerance) {
|
|
@@ -3348,17 +3348,17 @@ var require_QuickHull = __commonJS({
|
|
|
3348
3348
|
}
|
|
3349
3349
|
}
|
|
3350
3350
|
if (merge) {
|
|
3351
|
-
const discardedFaces =
|
|
3351
|
+
const discardedFaces = face2.mergeAdjacentFaces(edge, []);
|
|
3352
3352
|
for (let i = 0; i < discardedFaces.length; i += 1) {
|
|
3353
|
-
this.deleteFaceVertices(discardedFaces[i],
|
|
3353
|
+
this.deleteFaceVertices(discardedFaces[i], face2);
|
|
3354
3354
|
}
|
|
3355
3355
|
return true;
|
|
3356
3356
|
}
|
|
3357
3357
|
edge = edge.next;
|
|
3358
3358
|
it += 1;
|
|
3359
|
-
} while (edge !==
|
|
3359
|
+
} while (edge !== face2.edge);
|
|
3360
3360
|
if (!convex) {
|
|
3361
|
-
|
|
3361
|
+
face2.mark = NON_CONVEX;
|
|
3362
3362
|
}
|
|
3363
3363
|
return false;
|
|
3364
3364
|
}
|
|
@@ -3387,17 +3387,17 @@ var require_QuickHull = __commonJS({
|
|
|
3387
3387
|
this.computeHorizon(eyeVertex.point, null, eyeVertex.face, horizon);
|
|
3388
3388
|
this.addNewFaces(eyeVertex, horizon);
|
|
3389
3389
|
for (let i = 0; i < this.newFaces.length; i += 1) {
|
|
3390
|
-
const
|
|
3391
|
-
if (
|
|
3392
|
-
while (this.doAdjacentMerge(
|
|
3390
|
+
const face2 = this.newFaces[i];
|
|
3391
|
+
if (face2.mark === VISIBLE) {
|
|
3392
|
+
while (this.doAdjacentMerge(face2, MERGE_NON_CONVEX_WRT_LARGER_FACE)) {
|
|
3393
3393
|
}
|
|
3394
3394
|
}
|
|
3395
3395
|
}
|
|
3396
3396
|
for (let i = 0; i < this.newFaces.length; i += 1) {
|
|
3397
|
-
const
|
|
3398
|
-
if (
|
|
3399
|
-
|
|
3400
|
-
while (this.doAdjacentMerge(
|
|
3397
|
+
const face2 = this.newFaces[i];
|
|
3398
|
+
if (face2.mark === NON_CONVEX) {
|
|
3399
|
+
face2.mark = VISIBLE;
|
|
3400
|
+
while (this.doAdjacentMerge(face2, MERGE_NON_CONVEX)) {
|
|
3401
3401
|
}
|
|
3402
3402
|
}
|
|
3403
3403
|
}
|
|
@@ -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,
|
|
3586
|
+
var fromValues = (x, y, z27, w) => {
|
|
3587
3587
|
const out = create();
|
|
3588
3588
|
out[0] = x;
|
|
3589
3589
|
out[1] = y;
|
|
3590
|
-
out[2] =
|
|
3590
|
+
out[2] = z27;
|
|
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
|
|
3749
|
-
return vec3.fromValues(x, y,
|
|
3748
|
+
const z27 = point[2] - a * plane[2];
|
|
3749
|
+
return vec3.fromValues(x, y, z27);
|
|
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,
|
|
4054
|
-
out[0] = matrix[0] * x + matrix[4] * y + matrix[8] *
|
|
4055
|
-
out[1] = matrix[1] * x + matrix[5] * y + matrix[9] *
|
|
4056
|
-
out[2] = matrix[2] * x + matrix[6] * y + matrix[10] *
|
|
4057
|
-
out[3] = matrix[3] * x + matrix[7] * y + matrix[11] *
|
|
4053
|
+
const [x, y, z27, w] = vector;
|
|
4054
|
+
out[0] = matrix[0] * x + matrix[4] * y + matrix[8] * z27 + matrix[12] * w;
|
|
4055
|
+
out[1] = matrix[1] * x + matrix[5] * y + matrix[9] * z27 + matrix[13] * w;
|
|
4056
|
+
out[2] = matrix[2] * x + matrix[6] * y + matrix[10] * z27 + matrix[14] * w;
|
|
4057
|
+
out[3] = matrix[3] * x + matrix[7] * y + matrix[11] * z27 + 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
|
|
4120
|
-
out[3] = Math.sqrt(x * x + y * y +
|
|
4119
|
+
const z27 = out[2] - maxz[2];
|
|
4120
|
+
out[3] = Math.sqrt(x * x + y * y + z27 * z27);
|
|
4121
4121
|
cache.set(polygon2, out);
|
|
4122
4122
|
return out;
|
|
4123
4123
|
};
|
|
@@ -4200,7 +4200,7 @@ var require_validate2 = __commonJS({
|
|
|
4200
4200
|
var isConvex = require_isConvex();
|
|
4201
4201
|
var measureArea = require_measureArea();
|
|
4202
4202
|
var plane = require_plane2();
|
|
4203
|
-
var
|
|
4203
|
+
var validate2 = (object) => {
|
|
4204
4204
|
if (!isA(object)) {
|
|
4205
4205
|
throw new Error("invalid poly3 structure");
|
|
4206
4206
|
}
|
|
@@ -4233,7 +4233,7 @@ var require_validate2 = __commonJS({
|
|
|
4233
4233
|
});
|
|
4234
4234
|
}
|
|
4235
4235
|
};
|
|
4236
|
-
module.exports =
|
|
4236
|
+
module.exports = validate2;
|
|
4237
4237
|
}
|
|
4238
4238
|
});
|
|
4239
4239
|
|
|
@@ -4274,8 +4274,8 @@ var require_fromPointsConvex = __commonJS({
|
|
|
4274
4274
|
throw new Error("the given points must be an array");
|
|
4275
4275
|
}
|
|
4276
4276
|
const faces = quickhull(uniquePoints, { skipTriangulation: true });
|
|
4277
|
-
const polygons = faces.map((
|
|
4278
|
-
const vertices =
|
|
4277
|
+
const polygons = faces.map((face2) => {
|
|
4278
|
+
const vertices = face2.map((index2) => uniquePoints[index2]);
|
|
4279
4279
|
return poly3.create(vertices);
|
|
4280
4280
|
});
|
|
4281
4281
|
return create(polygons);
|
|
@@ -4552,7 +4552,7 @@ var require_validate3 = __commonJS({
|
|
|
4552
4552
|
"use strict";
|
|
4553
4553
|
var poly3 = require_poly3();
|
|
4554
4554
|
var isA = require_isA3();
|
|
4555
|
-
var
|
|
4555
|
+
var validate2 = (object) => {
|
|
4556
4556
|
if (!isA(object)) {
|
|
4557
4557
|
throw new Error("invalid geom3 structure");
|
|
4558
4558
|
}
|
|
@@ -4586,7 +4586,7 @@ var require_validate3 = __commonJS({
|
|
|
4586
4586
|
${nonManifold.join("\n")}`);
|
|
4587
4587
|
}
|
|
4588
4588
|
};
|
|
4589
|
-
module.exports =
|
|
4589
|
+
module.exports = validate2;
|
|
4590
4590
|
}
|
|
4591
4591
|
});
|
|
4592
4592
|
|
|
@@ -5146,7 +5146,7 @@ var require_validate4 = __commonJS({
|
|
|
5146
5146
|
"use strict";
|
|
5147
5147
|
var vec2 = require_vec2();
|
|
5148
5148
|
var isA = require_isA4();
|
|
5149
|
-
var
|
|
5149
|
+
var validate2 = (object) => {
|
|
5150
5150
|
if (!isA(object)) {
|
|
5151
5151
|
throw new Error("invalid path2 structure");
|
|
5152
5152
|
}
|
|
@@ -5166,7 +5166,7 @@ var require_validate4 = __commonJS({
|
|
|
5166
5166
|
throw new Error(`path2 invalid transforms ${object.transforms}`);
|
|
5167
5167
|
}
|
|
5168
5168
|
};
|
|
5169
|
-
module.exports =
|
|
5169
|
+
module.exports = validate2;
|
|
5170
5170
|
}
|
|
5171
5171
|
});
|
|
5172
5172
|
|
|
@@ -5816,17 +5816,17 @@ var require_lengths = __commonJS({
|
|
|
5816
5816
|
"node_modules/@jscad/modeling/src/curves/bezier/lengths.js"(exports, module) {
|
|
5817
5817
|
"use strict";
|
|
5818
5818
|
var valueAt = require_valueAt();
|
|
5819
|
-
var
|
|
5819
|
+
var lengths3 = (segments, bezier) => {
|
|
5820
5820
|
let sum = 0;
|
|
5821
|
-
const
|
|
5821
|
+
const lengths4 = [0];
|
|
5822
5822
|
let previous = valueAt(0, bezier);
|
|
5823
5823
|
for (let index2 = 1; index2 <= segments; index2++) {
|
|
5824
5824
|
const current = valueAt(index2 / segments, bezier);
|
|
5825
5825
|
sum += distanceBetween(current, previous);
|
|
5826
|
-
|
|
5826
|
+
lengths4.push(sum);
|
|
5827
5827
|
previous = current;
|
|
5828
5828
|
}
|
|
5829
|
-
return
|
|
5829
|
+
return lengths4;
|
|
5830
5830
|
};
|
|
5831
5831
|
var distanceBetween = (a, b) => {
|
|
5832
5832
|
if (Number.isFinite(a) && Number.isFinite(b)) {
|
|
@@ -5844,7 +5844,7 @@ var require_lengths = __commonJS({
|
|
|
5844
5844
|
throw new Error("The operands must be of the same type, either number or array.");
|
|
5845
5845
|
}
|
|
5846
5846
|
};
|
|
5847
|
-
module.exports =
|
|
5847
|
+
module.exports = lengths3;
|
|
5848
5848
|
}
|
|
5849
5849
|
});
|
|
5850
5850
|
|
|
@@ -5852,8 +5852,8 @@ var require_lengths = __commonJS({
|
|
|
5852
5852
|
var require_length3 = __commonJS({
|
|
5853
5853
|
"node_modules/@jscad/modeling/src/curves/bezier/length.js"(exports, module) {
|
|
5854
5854
|
"use strict";
|
|
5855
|
-
var
|
|
5856
|
-
var length83 = (segments, bezier) =>
|
|
5855
|
+
var lengths3 = require_lengths();
|
|
5856
|
+
var length83 = (segments, bezier) => lengths3(segments, bezier)[segments];
|
|
5857
5857
|
module.exports = length83;
|
|
5858
5858
|
}
|
|
5859
5859
|
});
|
|
@@ -5862,14 +5862,14 @@ var require_length3 = __commonJS({
|
|
|
5862
5862
|
var require_arcLengthToT = __commonJS({
|
|
5863
5863
|
"node_modules/@jscad/modeling/src/curves/bezier/arcLengthToT.js"(exports, module) {
|
|
5864
5864
|
"use strict";
|
|
5865
|
-
var
|
|
5865
|
+
var lengths3 = require_lengths();
|
|
5866
5866
|
var arcLengthToT = (options, bezier) => {
|
|
5867
5867
|
const defaults2 = {
|
|
5868
5868
|
distance: 0,
|
|
5869
5869
|
segments: 100
|
|
5870
5870
|
};
|
|
5871
5871
|
const { distance: distance6, segments } = Object.assign({}, defaults2, options);
|
|
5872
|
-
const arcLengths =
|
|
5872
|
+
const arcLengths = lengths3(segments, bezier);
|
|
5873
5873
|
let startIndex = 0;
|
|
5874
5874
|
let endIndex = segments;
|
|
5875
5875
|
while (startIndex <= endIndex) {
|
|
@@ -7354,7 +7354,7 @@ var require_circle = __commonJS({
|
|
|
7354
7354
|
var { TAU } = require_constants();
|
|
7355
7355
|
var ellipse3 = require_ellipse();
|
|
7356
7356
|
var { isGTE } = require_commonChecks();
|
|
7357
|
-
var
|
|
7357
|
+
var circle2 = (options) => {
|
|
7358
7358
|
const defaults2 = {
|
|
7359
7359
|
center: [0, 0],
|
|
7360
7360
|
radius: 1,
|
|
@@ -7367,7 +7367,7 @@ var require_circle = __commonJS({
|
|
|
7367
7367
|
radius = [radius, radius];
|
|
7368
7368
|
return ellipse3({ center, radius, startAngle, endAngle, segments });
|
|
7369
7369
|
};
|
|
7370
|
-
module.exports =
|
|
7370
|
+
module.exports = circle2;
|
|
7371
7371
|
}
|
|
7372
7372
|
});
|
|
7373
7373
|
|
|
@@ -7682,15 +7682,15 @@ var require_polyhedron = __commonJS({
|
|
|
7682
7682
|
points.forEach((point, i) => {
|
|
7683
7683
|
if (!isNumberArray(point, 3)) throw new Error(`point ${i} must be an array of X, Y, Z values`);
|
|
7684
7684
|
});
|
|
7685
|
-
faces.forEach((
|
|
7686
|
-
if (
|
|
7687
|
-
if (!isNumberArray(
|
|
7685
|
+
faces.forEach((face2, i) => {
|
|
7686
|
+
if (face2.length < 3) throw new Error(`face ${i} must contain 3 or more indexes`);
|
|
7687
|
+
if (!isNumberArray(face2, face2.length)) throw new Error(`face ${i} must be an array of numbers`);
|
|
7688
7688
|
});
|
|
7689
7689
|
if (orientation2 !== "outward") {
|
|
7690
|
-
faces.forEach((
|
|
7690
|
+
faces.forEach((face2) => face2.reverse());
|
|
7691
7691
|
}
|
|
7692
|
-
const polygons = faces.map((
|
|
7693
|
-
const polygon2 = poly3.create(
|
|
7692
|
+
const polygons = faces.map((face2, findex) => {
|
|
7693
|
+
const polygon2 = poly3.create(face2.map((pindex) => points[pindex]));
|
|
7694
7694
|
if (colors2 && colors2[findex]) polygon2.color = colors2[findex];
|
|
7695
7695
|
return polygon2;
|
|
7696
7696
|
});
|
|
@@ -9594,7 +9594,7 @@ var require_torus = __commonJS({
|
|
|
9594
9594
|
var extrudeRotate = require_extrudeRotate();
|
|
9595
9595
|
var { rotate: rotate2 } = require_rotate3();
|
|
9596
9596
|
var { translate: translate6 } = require_translate2();
|
|
9597
|
-
var
|
|
9597
|
+
var circle2 = require_circle();
|
|
9598
9598
|
var { isGT, isGTE } = require_commonChecks();
|
|
9599
9599
|
var torus = (options) => {
|
|
9600
9600
|
const defaults2 = {
|
|
@@ -9614,7 +9614,7 @@ var require_torus = __commonJS({
|
|
|
9614
9614
|
if (!isGTE(startAngle, 0)) throw new Error("startAngle must be positive");
|
|
9615
9615
|
if (!isGT(outerRotation, 0)) throw new Error("outerRotation must be greater than zero");
|
|
9616
9616
|
if (innerRadius >= outerRadius) throw new Error("inner circle is too large to rotate about the outer circle");
|
|
9617
|
-
let innerCircle =
|
|
9617
|
+
let innerCircle = circle2({ radius: innerRadius, segments: innerSegments });
|
|
9618
9618
|
if (innerRotation !== 0) {
|
|
9619
9619
|
innerCircle = rotate2([0, 0, innerRotation], innerCircle);
|
|
9620
9620
|
}
|
|
@@ -9694,10 +9694,10 @@ var require_triangle2 = __commonJS({
|
|
|
9694
9694
|
const b = c / Math.sin(C) * Math.sin(B);
|
|
9695
9695
|
return createTriangle(A, B, C, a, b, c);
|
|
9696
9696
|
};
|
|
9697
|
-
var solveSSS = (
|
|
9698
|
-
const a =
|
|
9699
|
-
const b =
|
|
9700
|
-
const c =
|
|
9697
|
+
var solveSSS = (lengths3) => {
|
|
9698
|
+
const a = lengths3[1];
|
|
9699
|
+
const b = lengths3[2];
|
|
9700
|
+
const c = lengths3[0];
|
|
9701
9701
|
if (a + b <= c || b + c <= a || c + a <= b) {
|
|
9702
9702
|
throw new Error("SSS triangle is incorrect, as the longest side is longer than the sum of the other sides");
|
|
9703
9703
|
}
|
|
@@ -10056,11 +10056,11 @@ var require_areAllShapesTheSameType = __commonJS({
|
|
|
10056
10056
|
var path2 = require_path2();
|
|
10057
10057
|
var areAllShapesTheSameType = (shapes) => {
|
|
10058
10058
|
let previousType;
|
|
10059
|
-
for (const
|
|
10059
|
+
for (const shape2 of shapes) {
|
|
10060
10060
|
let currentType = 0;
|
|
10061
|
-
if (geom2.isA(
|
|
10062
|
-
if (geom3.isA(
|
|
10063
|
-
if (path2.isA(
|
|
10061
|
+
if (geom2.isA(shape2)) currentType = 1;
|
|
10062
|
+
if (geom3.isA(shape2)) currentType = 2;
|
|
10063
|
+
if (path2.isA(shape2)) currentType = 3;
|
|
10064
10064
|
if (previousType && currentType !== previousType) return false;
|
|
10065
10065
|
previousType = currentType;
|
|
10066
10066
|
}
|
|
@@ -11309,8 +11309,8 @@ var require_hullPoints3 = __commonJS({
|
|
|
11309
11309
|
var quickhull = require_quickhull();
|
|
11310
11310
|
var hullPoints3 = (uniquePoints) => {
|
|
11311
11311
|
const faces = quickhull(uniquePoints, { skipTriangulation: true });
|
|
11312
|
-
const polygons = faces.map((
|
|
11313
|
-
const vertices =
|
|
11312
|
+
const polygons = faces.map((face2) => {
|
|
11313
|
+
const vertices = face2.map((index2) => uniquePoints[index2]);
|
|
11314
11314
|
return poly3.create(vertices);
|
|
11315
11315
|
});
|
|
11316
11316
|
return polygons;
|
|
@@ -13770,10 +13770,10 @@ var require_dist = __commonJS({
|
|
|
13770
13770
|
})
|
|
13771
13771
|
},
|
|
13772
13772
|
colors: {
|
|
13773
|
-
colorize: (color,
|
|
13773
|
+
colorize: (color, shape2) => ({
|
|
13774
13774
|
type: "colorize",
|
|
13775
13775
|
color,
|
|
13776
|
-
shape
|
|
13776
|
+
shape: shape2
|
|
13777
13777
|
})
|
|
13778
13778
|
},
|
|
13779
13779
|
primitives: {
|
|
@@ -13803,32 +13803,32 @@ var require_dist = __commonJS({
|
|
|
13803
13803
|
})
|
|
13804
13804
|
},
|
|
13805
13805
|
transforms: {
|
|
13806
|
-
rotate: (angles,
|
|
13806
|
+
rotate: (angles, shape2) => ({
|
|
13807
13807
|
type: "rotate",
|
|
13808
13808
|
angles,
|
|
13809
|
-
shape
|
|
13809
|
+
shape: shape2
|
|
13810
13810
|
}),
|
|
13811
|
-
scale: (factors,
|
|
13811
|
+
scale: (factors, shape2) => ({
|
|
13812
13812
|
type: "scale",
|
|
13813
13813
|
factors,
|
|
13814
|
-
shape
|
|
13814
|
+
shape: shape2
|
|
13815
13815
|
}),
|
|
13816
|
-
translate: (vector,
|
|
13816
|
+
translate: (vector, shape2) => ({
|
|
13817
13817
|
type: "translate",
|
|
13818
13818
|
vector,
|
|
13819
|
-
shape
|
|
13819
|
+
shape: shape2
|
|
13820
13820
|
})
|
|
13821
13821
|
},
|
|
13822
13822
|
extrusions: {
|
|
13823
|
-
extrudeLinear: (options,
|
|
13823
|
+
extrudeLinear: (options, shape2) => ({
|
|
13824
13824
|
type: "extrudeLinear",
|
|
13825
13825
|
options,
|
|
13826
|
-
shape
|
|
13826
|
+
shape: shape2
|
|
13827
13827
|
}),
|
|
13828
|
-
extrudeRotate: (options,
|
|
13828
|
+
extrudeRotate: (options, shape2) => ({
|
|
13829
13829
|
type: "extrudeRotate",
|
|
13830
13830
|
options,
|
|
13831
|
-
shape
|
|
13831
|
+
shape: shape2
|
|
13832
13832
|
})
|
|
13833
13833
|
},
|
|
13834
13834
|
maths: {
|
|
@@ -13837,8 +13837,8 @@ var require_dist = __commonJS({
|
|
|
13837
13837
|
fromValues: (x, y) => [x, y]
|
|
13838
13838
|
},
|
|
13839
13839
|
vec3: {
|
|
13840
|
-
create: (x, y,
|
|
13841
|
-
fromValues: (x, y,
|
|
13840
|
+
create: (x, y, z27) => [x, y, z27],
|
|
13841
|
+
fromValues: (x, y, z27) => [x, y, z27]
|
|
13842
13842
|
}
|
|
13843
13843
|
},
|
|
13844
13844
|
geometries: {
|
|
@@ -13862,17 +13862,17 @@ var require_dist = __commonJS({
|
|
|
13862
13862
|
}
|
|
13863
13863
|
},
|
|
13864
13864
|
measurements: {
|
|
13865
|
-
measureBoundingBox: (
|
|
13865
|
+
measureBoundingBox: (shape2) => ({
|
|
13866
13866
|
type: "measureBoundingBox",
|
|
13867
|
-
shape
|
|
13867
|
+
shape: shape2
|
|
13868
13868
|
}),
|
|
13869
|
-
measureArea: (
|
|
13869
|
+
measureArea: (shape2) => ({
|
|
13870
13870
|
type: "measureArea",
|
|
13871
|
-
shape
|
|
13871
|
+
shape: shape2
|
|
13872
13872
|
}),
|
|
13873
|
-
measureVolume: (
|
|
13873
|
+
measureVolume: (shape2) => ({
|
|
13874
13874
|
type: "measureVolume",
|
|
13875
|
-
shape
|
|
13875
|
+
shape: shape2
|
|
13876
13876
|
})
|
|
13877
13877
|
},
|
|
13878
13878
|
utils: {
|
|
@@ -13880,77 +13880,77 @@ var require_dist = __commonJS({
|
|
|
13880
13880
|
radToDeg: (radians) => radians * 180 / Math.PI
|
|
13881
13881
|
}
|
|
13882
13882
|
};
|
|
13883
|
-
var executeJscadOperations3 = (
|
|
13883
|
+
var executeJscadOperations3 = (jscad5, operation) => {
|
|
13884
13884
|
if (Array.isArray(operation) && operation.length === 1) {
|
|
13885
|
-
return executeJscadOperations3(
|
|
13885
|
+
return executeJscadOperations3(jscad5, operation[0]);
|
|
13886
13886
|
}
|
|
13887
13887
|
if (Array.isArray(operation)) {
|
|
13888
13888
|
throw new Error(
|
|
13889
13889
|
`executeJscadOperations currently doesn't support Array<JscadOperation>, try adding a root union or or executing each element individually`
|
|
13890
13890
|
);
|
|
13891
13891
|
}
|
|
13892
|
-
const recurse = (op) => executeJscadOperations3(
|
|
13892
|
+
const recurse = (op) => executeJscadOperations3(jscad5, op);
|
|
13893
13893
|
const { type, ...params } = operation;
|
|
13894
13894
|
switch (type) {
|
|
13895
13895
|
case "intersect":
|
|
13896
|
-
return
|
|
13896
|
+
return jscad5.booleans.intersect(...operation.shapes.map(recurse));
|
|
13897
13897
|
case "subtract":
|
|
13898
|
-
return
|
|
13898
|
+
return jscad5.booleans.subtract(...operation.shapes.map(recurse));
|
|
13899
13899
|
case "union":
|
|
13900
|
-
return
|
|
13900
|
+
return jscad5.booleans.union(...operation.shapes.map(recurse));
|
|
13901
13901
|
case "hull":
|
|
13902
|
-
return
|
|
13902
|
+
return jscad5.hulls.hull(...operation.shapes.map(recurse));
|
|
13903
13903
|
case "hullChain":
|
|
13904
|
-
return
|
|
13904
|
+
return jscad5.hulls.hullChain(...operation.shapes.map(recurse));
|
|
13905
13905
|
case "colorize":
|
|
13906
|
-
return
|
|
13906
|
+
return jscad5.colors.colorize(operation.color, recurse(operation.shape));
|
|
13907
13907
|
case "cube":
|
|
13908
|
-
return
|
|
13908
|
+
return jscad5.primitives.cube(params);
|
|
13909
13909
|
case "sphere":
|
|
13910
|
-
return
|
|
13910
|
+
return jscad5.primitives.sphere(params);
|
|
13911
13911
|
case "cylinder":
|
|
13912
|
-
return
|
|
13912
|
+
return jscad5.primitives.cylinder(params);
|
|
13913
13913
|
case "polygon":
|
|
13914
|
-
return
|
|
13914
|
+
return jscad5.primitives.polygon(params);
|
|
13915
13915
|
case "cuboid":
|
|
13916
|
-
return
|
|
13916
|
+
return jscad5.primitives.cuboid(params);
|
|
13917
13917
|
case "roundedCuboid":
|
|
13918
|
-
return
|
|
13918
|
+
return jscad5.primitives.roundedCuboid(params);
|
|
13919
13919
|
case "rotate":
|
|
13920
|
-
return
|
|
13920
|
+
return jscad5.transforms.rotate(operation.angles, recurse(operation.shape));
|
|
13921
13921
|
case "scale":
|
|
13922
|
-
return
|
|
13922
|
+
return jscad5.transforms.scale(operation.factors, recurse(operation.shape));
|
|
13923
13923
|
case "translate":
|
|
13924
|
-
return
|
|
13924
|
+
return jscad5.transforms.translate(
|
|
13925
13925
|
operation.vector,
|
|
13926
13926
|
recurse(operation.shape)
|
|
13927
13927
|
);
|
|
13928
13928
|
case "extrudeLinear":
|
|
13929
|
-
return
|
|
13929
|
+
return jscad5.extrusions.extrudeLinear(
|
|
13930
13930
|
operation.options,
|
|
13931
13931
|
recurse(operation.shape)
|
|
13932
13932
|
);
|
|
13933
13933
|
case "extrudeRotate":
|
|
13934
|
-
return
|
|
13934
|
+
return jscad5.extrusions.extrudeRotate(
|
|
13935
13935
|
operation.options,
|
|
13936
13936
|
recurse(operation.shape)
|
|
13937
13937
|
);
|
|
13938
13938
|
case "createGeom2":
|
|
13939
|
-
return
|
|
13939
|
+
return jscad5.geometries.geom2.create(operation.points);
|
|
13940
13940
|
case "createGeom3":
|
|
13941
|
-
return
|
|
13941
|
+
return jscad5.geometries.geom3.create(operation.polygons);
|
|
13942
13942
|
case "createPath2":
|
|
13943
|
-
return
|
|
13943
|
+
return jscad5.geometries.path2.create(operation.points);
|
|
13944
13944
|
case "measureBoundingBox":
|
|
13945
|
-
return
|
|
13945
|
+
return jscad5.measurements.measureBoundingBox(recurse(operation.shape));
|
|
13946
13946
|
case "measureArea":
|
|
13947
|
-
return
|
|
13947
|
+
return jscad5.measurements.measureArea(recurse(operation.shape));
|
|
13948
13948
|
case "measureVolume":
|
|
13949
|
-
return
|
|
13949
|
+
return jscad5.measurements.measureVolume(recurse(operation.shape));
|
|
13950
13950
|
case "degToRad":
|
|
13951
|
-
return
|
|
13951
|
+
return jscad5.utils.degToRad(operation.degrees);
|
|
13952
13952
|
case "radToDeg":
|
|
13953
|
-
return
|
|
13953
|
+
return jscad5.utils.radToDeg(operation.radians);
|
|
13954
13954
|
default:
|
|
13955
13955
|
if (operation.type === void 0) {
|
|
13956
13956
|
throw new Error(
|
|
@@ -14789,15 +14789,8 @@ var Html = ({ children, position, style }) => {
|
|
|
14789
14789
|
return portal;
|
|
14790
14790
|
};
|
|
14791
14791
|
|
|
14792
|
-
// node_modules/@tscircuit/
|
|
14793
|
-
import {
|
|
14794
|
-
length as length82
|
|
14795
|
-
} from "circuit-json";
|
|
14796
|
-
import { length } from "circuit-json";
|
|
14797
|
-
import { z as z3 } from "zod";
|
|
14792
|
+
// node_modules/@tscircuit/modelprinter/index.js
|
|
14798
14793
|
import { z as z2 } from "zod";
|
|
14799
|
-
import { z } from "zod";
|
|
14800
|
-
import { z as z4 } from "zod";
|
|
14801
14794
|
|
|
14802
14795
|
// node_modules/@tscircuit/mm/dist/index.js
|
|
14803
14796
|
var unitToMm = {
|
|
@@ -14810,6 +14803,11 @@ var unitToMm = {
|
|
|
14810
14803
|
ft: 304.8,
|
|
14811
14804
|
feet: 304.8
|
|
14812
14805
|
};
|
|
14806
|
+
var mmNumberFormatter = new Intl.NumberFormat("en-US", {
|
|
14807
|
+
useGrouping: false,
|
|
14808
|
+
notation: "standard",
|
|
14809
|
+
maximumFractionDigits: 12
|
|
14810
|
+
});
|
|
14813
14811
|
var mm = (n) => {
|
|
14814
14812
|
let unit = typeof n === "number" ? "mm" : n.replace(/^[^a-zA-Z]+/g, "").toLowerCase();
|
|
14815
14813
|
if (!unit)
|
|
@@ -14820,15 +14818,958 @@ var mm = (n) => {
|
|
|
14820
14818
|
}
|
|
14821
14819
|
throw new Error(`Unsupported unit: ${unit}`);
|
|
14822
14820
|
};
|
|
14823
|
-
|
|
14821
|
+
|
|
14822
|
+
// node_modules/@tscircuit/modelprinter/index.js
|
|
14823
|
+
import { z } from "zod";
|
|
14824
|
+
import { z as z3 } from "zod";
|
|
14825
|
+
import { z as z5 } from "zod";
|
|
14826
|
+
import { z as z4 } from "zod";
|
|
14827
|
+
var modelLengthSchema = z.union([z.number(), z.string()]).transform((value, context) => {
|
|
14828
|
+
try {
|
|
14829
|
+
const parsed = mm(value);
|
|
14830
|
+
if (!Number.isFinite(parsed)) throw new Error("Length is not finite");
|
|
14831
|
+
return parsed;
|
|
14832
|
+
} catch {
|
|
14833
|
+
context.addIssue({
|
|
14834
|
+
code: "custom",
|
|
14835
|
+
message: `Invalid model length: ${String(value)}`
|
|
14836
|
+
});
|
|
14837
|
+
return z.NEVER;
|
|
14838
|
+
}
|
|
14839
|
+
});
|
|
14840
|
+
var positiveModelLengthSchema = modelLengthSchema.refine(
|
|
14841
|
+
(value) => value > 0,
|
|
14842
|
+
"Length must be greater than zero"
|
|
14843
|
+
);
|
|
14844
|
+
var nonnegativeModelLengthSchema = modelLengthSchema.refine(
|
|
14845
|
+
(value) => value >= 0,
|
|
14846
|
+
"Length cannot be negative"
|
|
14847
|
+
);
|
|
14848
|
+
var nemaSizeSchema = z2.union([
|
|
14849
|
+
z2.literal(8),
|
|
14850
|
+
z2.literal(17),
|
|
14851
|
+
z2.literal(23)
|
|
14852
|
+
]);
|
|
14853
|
+
var nemaMotorDimensions = {
|
|
14854
|
+
8: {
|
|
14855
|
+
bodyWidth: 20.3,
|
|
14856
|
+
bodyLength: 33,
|
|
14857
|
+
mountingHoleSpacing: 16,
|
|
14858
|
+
mountingHoleDiameter: 2,
|
|
14859
|
+
mountingHoleDepth: 2,
|
|
14860
|
+
mountingHoleThrough: false,
|
|
14861
|
+
pilotDiameter: 15,
|
|
14862
|
+
pilotLength: 1.5,
|
|
14863
|
+
shaftDiameter: 4,
|
|
14864
|
+
shaftLength: 15,
|
|
14865
|
+
shaftShape: "round",
|
|
14866
|
+
shaftFlatDepth: 0.5,
|
|
14867
|
+
shaftFlatLength: 10,
|
|
14868
|
+
shaftFlatAngle: 0,
|
|
14869
|
+
frontCapLength: 3.5,
|
|
14870
|
+
rearCapLength: 3.5,
|
|
14871
|
+
faceCornerChamfer: 0.5,
|
|
14872
|
+
bodyCornerChamfer: 3
|
|
14873
|
+
},
|
|
14874
|
+
17: {
|
|
14875
|
+
bodyWidth: 42.3,
|
|
14876
|
+
bodyLength: 38,
|
|
14877
|
+
mountingHoleSpacing: 31,
|
|
14878
|
+
mountingHoleDiameter: 3,
|
|
14879
|
+
mountingHoleDepth: 4.5,
|
|
14880
|
+
mountingHoleThrough: false,
|
|
14881
|
+
pilotDiameter: 22,
|
|
14882
|
+
pilotLength: 2,
|
|
14883
|
+
shaftDiameter: 5,
|
|
14884
|
+
shaftLength: 24,
|
|
14885
|
+
shaftShape: "d",
|
|
14886
|
+
shaftFlatDepth: 0.5,
|
|
14887
|
+
shaftFlatLength: 15,
|
|
14888
|
+
shaftFlatAngle: 0,
|
|
14889
|
+
frontCapLength: 5,
|
|
14890
|
+
rearCapLength: 5,
|
|
14891
|
+
faceCornerChamfer: 3,
|
|
14892
|
+
bodyCornerChamfer: 6
|
|
14893
|
+
},
|
|
14894
|
+
23: {
|
|
14895
|
+
bodyWidth: 56.4,
|
|
14896
|
+
bodyLength: 51,
|
|
14897
|
+
mountingHoleSpacing: 47.14,
|
|
14898
|
+
mountingHoleDiameter: 5,
|
|
14899
|
+
mountingHoleDepth: 5,
|
|
14900
|
+
mountingHoleThrough: true,
|
|
14901
|
+
pilotDiameter: 38.1,
|
|
14902
|
+
pilotLength: 1.6,
|
|
14903
|
+
shaftDiameter: 6.35,
|
|
14904
|
+
shaftLength: 20.6,
|
|
14905
|
+
shaftShape: "d",
|
|
14906
|
+
shaftFlatDepth: 0.5,
|
|
14907
|
+
shaftFlatLength: 15,
|
|
14908
|
+
shaftFlatAngle: 0,
|
|
14909
|
+
frontCapLength: 5,
|
|
14910
|
+
rearCapLength: 5,
|
|
14911
|
+
faceCornerChamfer: 2,
|
|
14912
|
+
bodyCornerChamfer: 15
|
|
14913
|
+
}
|
|
14914
|
+
};
|
|
14915
|
+
var shape = {
|
|
14916
|
+
nemaSize: nemaSizeSchema,
|
|
14917
|
+
bodyWidth: positiveModelLengthSchema.optional(),
|
|
14918
|
+
bodyLength: positiveModelLengthSchema.optional(),
|
|
14919
|
+
mountingHoleSpacing: positiveModelLengthSchema.optional(),
|
|
14920
|
+
mountingHoleDiameter: positiveModelLengthSchema.optional(),
|
|
14921
|
+
mountingHoleDepth: positiveModelLengthSchema.optional(),
|
|
14922
|
+
mountingHoleThrough: z2.boolean().optional(),
|
|
14923
|
+
pilotDiameter: positiveModelLengthSchema.optional(),
|
|
14924
|
+
pilotLength: positiveModelLengthSchema.optional(),
|
|
14925
|
+
/** Distance from mounting face Z=0 to shaft tip, including pilot height. */
|
|
14926
|
+
shaftLength: positiveModelLengthSchema.optional(),
|
|
14927
|
+
shaftDiameter: positiveModelLengthSchema.optional(),
|
|
14928
|
+
shaftShape: z2.enum(["round", "d"]).optional(),
|
|
14929
|
+
/** Radial material removed from the +X side before rotation. */
|
|
14930
|
+
shaftFlatDepth: nonnegativeModelLengthSchema.optional(),
|
|
14931
|
+
/** Flat extends back from the tip; leaves a round shoulder above the pilot. */
|
|
14932
|
+
shaftFlatLength: nonnegativeModelLengthSchema.optional(),
|
|
14933
|
+
/** Degrees around +Z, counterclockwise; zero puts the flat on +X. */
|
|
14934
|
+
shaftFlatAngle: z2.number().finite().optional(),
|
|
14935
|
+
frontCapLength: positiveModelLengthSchema.optional(),
|
|
14936
|
+
rearCapLength: positiveModelLengthSchema.optional(),
|
|
14937
|
+
faceCornerChamfer: nonnegativeModelLengthSchema.optional(),
|
|
14938
|
+
bodyCornerChamfer: nonnegativeModelLengthSchema.optional()
|
|
14939
|
+
};
|
|
14940
|
+
var resolve = (p) => {
|
|
14941
|
+
const d = nemaMotorDimensions[p.nemaSize];
|
|
14942
|
+
return {
|
|
14943
|
+
nemaSize: p.nemaSize,
|
|
14944
|
+
bodyWidth: p.bodyWidth ?? d.bodyWidth,
|
|
14945
|
+
bodyLength: p.bodyLength ?? d.bodyLength,
|
|
14946
|
+
mountingHoleSpacing: p.mountingHoleSpacing ?? d.mountingHoleSpacing,
|
|
14947
|
+
mountingHoleDiameter: p.mountingHoleDiameter ?? d.mountingHoleDiameter,
|
|
14948
|
+
mountingHoleDepth: p.mountingHoleDepth ?? d.mountingHoleDepth,
|
|
14949
|
+
mountingHoleThrough: p.mountingHoleThrough ?? d.mountingHoleThrough,
|
|
14950
|
+
pilotDiameter: p.pilotDiameter ?? d.pilotDiameter,
|
|
14951
|
+
pilotLength: p.pilotLength ?? d.pilotLength,
|
|
14952
|
+
shaftDiameter: p.shaftDiameter ?? d.shaftDiameter,
|
|
14953
|
+
shaftLength: p.shaftLength ?? d.shaftLength,
|
|
14954
|
+
shaftShape: p.shaftShape ?? d.shaftShape,
|
|
14955
|
+
shaftFlatDepth: p.shaftFlatDepth ?? d.shaftFlatDepth,
|
|
14956
|
+
shaftFlatLength: p.shaftFlatLength ?? d.shaftFlatLength,
|
|
14957
|
+
shaftFlatAngle: p.shaftFlatAngle ?? d.shaftFlatAngle,
|
|
14958
|
+
frontCapLength: p.frontCapLength ?? d.frontCapLength,
|
|
14959
|
+
rearCapLength: p.rearCapLength ?? d.rearCapLength,
|
|
14960
|
+
faceCornerChamfer: p.faceCornerChamfer ?? d.faceCornerChamfer,
|
|
14961
|
+
bodyCornerChamfer: p.bodyCornerChamfer ?? d.bodyCornerChamfer
|
|
14962
|
+
};
|
|
14963
|
+
};
|
|
14964
|
+
var validate = (p, ctx) => {
|
|
14965
|
+
const issue = (message) => ctx.addIssue({ code: "custom", message });
|
|
14966
|
+
const r = p.mountingHoleDiameter / 2;
|
|
14967
|
+
if (p.frontCapLength + p.rearCapLength >= p.bodyLength)
|
|
14968
|
+
issue("End caps must leave a positive body length");
|
|
14969
|
+
if (p.faceCornerChamfer >= p.bodyWidth / 2 || p.bodyCornerChamfer >= p.bodyWidth / 2)
|
|
14970
|
+
issue("Chamfer must be smaller than half the body width");
|
|
14971
|
+
if (p.mountingHoleSpacing + 2 * r >= p.bodyWidth || p.bodyWidth - p.faceCornerChamfer - p.mountingHoleSpacing <= r * Math.SQRT2)
|
|
14972
|
+
issue("Mounting holes must fit entirely inside the front face");
|
|
14973
|
+
if (p.pilotDiameter >= p.bodyWidth || p.pilotDiameter <= p.shaftDiameter)
|
|
14974
|
+
issue(
|
|
14975
|
+
"Pilot diameter must exceed the shaft diameter and fit inside the face"
|
|
14976
|
+
);
|
|
14977
|
+
if (p.mountingHoleSpacing / Math.SQRT2 <= p.pilotDiameter / 2 + r)
|
|
14978
|
+
issue("Mounting holes must clear the pilot");
|
|
14979
|
+
if (!p.mountingHoleThrough && p.mountingHoleDepth >= p.frontCapLength)
|
|
14980
|
+
issue("Blind mounting hole depth must be less than the front cap length");
|
|
14981
|
+
if (p.mountingHoleThrough && p.bodyWidth - p.bodyCornerChamfer - p.mountingHoleSpacing >= -r * Math.SQRT2)
|
|
14982
|
+
issue("Body and rear cap must clear through mounting holes");
|
|
14983
|
+
if (p.shaftLength <= p.pilotLength)
|
|
14984
|
+
issue("Shaft tip must extend beyond the pilot");
|
|
14985
|
+
if (p.shaftShape === "d" && (p.shaftFlatDepth <= 0 || p.shaftFlatDepth >= p.shaftDiameter / 2 || p.shaftFlatLength <= 0 || p.shaftFlatLength > p.shaftLength - p.pilotLength))
|
|
14986
|
+
issue(
|
|
14987
|
+
"D flat must have positive depth less than the shaft radius and fit above the pilot"
|
|
14988
|
+
);
|
|
14989
|
+
};
|
|
14990
|
+
var nemaMotorModelPropsSchema = z2.object(shape).strict().transform(resolve).superRefine(validate);
|
|
14991
|
+
var nemaMotorModelDefinitionSchema = z2.object({ fn: z2.literal("nema"), ...shape }).strict().transform(({ fn, ...props }) => ({ fn, ...resolve(props) })).superRefine(validate);
|
|
14992
|
+
var holePosition = {
|
|
14993
|
+
panel: z3.enum(["base", "left", "right"]),
|
|
14994
|
+
/** Panel-local mm, centered on its straight section: u along its length,
|
|
14995
|
+
* v along the sheet width. Side-panel u increases upward. */
|
|
14996
|
+
u: modelLengthSchema,
|
|
14997
|
+
v: modelLengthSchema
|
|
14998
|
+
};
|
|
14999
|
+
var sheetMetalHoleSchema = z3.discriminatedUnion("shape", [
|
|
15000
|
+
z3.object({
|
|
15001
|
+
...holePosition,
|
|
15002
|
+
shape: z3.literal("round"),
|
|
15003
|
+
diameter: positiveModelLengthSchema
|
|
15004
|
+
}).strict(),
|
|
15005
|
+
z3.object({
|
|
15006
|
+
...holePosition,
|
|
15007
|
+
shape: z3.literal("slot"),
|
|
15008
|
+
length: positiveModelLengthSchema,
|
|
15009
|
+
width: positiveModelLengthSchema,
|
|
15010
|
+
axis: z3.enum(["u", "v"]).default("v")
|
|
15011
|
+
}).strict()
|
|
15012
|
+
]);
|
|
15013
|
+
var sheetMetalShape = {
|
|
15014
|
+
profile: z3.enum(["plate", "angle", "channel"]).default("plate"),
|
|
15015
|
+
width: positiveModelLengthSchema,
|
|
15016
|
+
/** Straight base length between bend tangencies, not overall width. */
|
|
15017
|
+
baseLength: positiveModelLengthSchema,
|
|
15018
|
+
/** Straight flange length above the bend tangent. */
|
|
15019
|
+
flangeHeight: positiveModelLengthSchema.default(12),
|
|
15020
|
+
thickness: positiveModelLengthSchema.default(1),
|
|
15021
|
+
insideBendRadius: positiveModelLengthSchema.default(1),
|
|
15022
|
+
holes: z3.array(sheetMetalHoleSchema).max(100).default([])
|
|
15023
|
+
};
|
|
15024
|
+
var sheetMetalModelPropsSchema = z3.object(sheetMetalShape).strict();
|
|
15025
|
+
var sheetMetalModelDefinitionSchema = z3.object({ fn: z3.literal("sheetmetal"), ...sheetMetalShape }).strict();
|
|
15026
|
+
var hexSocketBoltDimensions = {
|
|
15027
|
+
M2: {
|
|
15028
|
+
diameter: 2,
|
|
15029
|
+
threadPitch: 0.4,
|
|
15030
|
+
headDiameter: 3.8,
|
|
15031
|
+
headHeight: 2,
|
|
15032
|
+
socketWidth: 1.5,
|
|
15033
|
+
socketDepth: 1
|
|
15034
|
+
},
|
|
15035
|
+
"M2.5": {
|
|
15036
|
+
diameter: 2.5,
|
|
15037
|
+
threadPitch: 0.45,
|
|
15038
|
+
headDiameter: 4.5,
|
|
15039
|
+
headHeight: 2.5,
|
|
15040
|
+
socketWidth: 2,
|
|
15041
|
+
socketDepth: 1.1
|
|
15042
|
+
},
|
|
15043
|
+
M3: {
|
|
15044
|
+
diameter: 3,
|
|
15045
|
+
threadPitch: 0.5,
|
|
15046
|
+
headDiameter: 5.5,
|
|
15047
|
+
headHeight: 3,
|
|
15048
|
+
socketWidth: 2.5,
|
|
15049
|
+
socketDepth: 1.3
|
|
15050
|
+
},
|
|
15051
|
+
M4: {
|
|
15052
|
+
diameter: 4,
|
|
15053
|
+
threadPitch: 0.7,
|
|
15054
|
+
headDiameter: 7,
|
|
15055
|
+
headHeight: 4,
|
|
15056
|
+
socketWidth: 3,
|
|
15057
|
+
socketDepth: 2
|
|
15058
|
+
},
|
|
15059
|
+
M5: {
|
|
15060
|
+
diameter: 5,
|
|
15061
|
+
threadPitch: 0.8,
|
|
15062
|
+
headDiameter: 8.5,
|
|
15063
|
+
headHeight: 5,
|
|
15064
|
+
socketWidth: 4,
|
|
15065
|
+
socketDepth: 2.5
|
|
15066
|
+
},
|
|
15067
|
+
M6: {
|
|
15068
|
+
diameter: 6,
|
|
15069
|
+
threadPitch: 1,
|
|
15070
|
+
headDiameter: 10,
|
|
15071
|
+
headHeight: 6,
|
|
15072
|
+
socketWidth: 5,
|
|
15073
|
+
socketDepth: 3
|
|
15074
|
+
},
|
|
15075
|
+
M8: {
|
|
15076
|
+
diameter: 8,
|
|
15077
|
+
threadPitch: 1.25,
|
|
15078
|
+
headDiameter: 13,
|
|
15079
|
+
headHeight: 8,
|
|
15080
|
+
socketWidth: 6,
|
|
15081
|
+
socketDepth: 4
|
|
15082
|
+
},
|
|
15083
|
+
M10: {
|
|
15084
|
+
diameter: 10,
|
|
15085
|
+
threadPitch: 1.5,
|
|
15086
|
+
headDiameter: 16,
|
|
15087
|
+
headHeight: 10,
|
|
15088
|
+
socketWidth: 8,
|
|
15089
|
+
socketDepth: 5
|
|
15090
|
+
},
|
|
15091
|
+
M12: {
|
|
15092
|
+
diameter: 12,
|
|
15093
|
+
threadPitch: 1.75,
|
|
15094
|
+
headDiameter: 18,
|
|
15095
|
+
headHeight: 12,
|
|
15096
|
+
socketWidth: 10,
|
|
15097
|
+
socketDepth: 6
|
|
15098
|
+
}
|
|
15099
|
+
};
|
|
15100
|
+
var metricBoltSizeSchema = z4.enum([
|
|
15101
|
+
"M2",
|
|
15102
|
+
"M2.5",
|
|
15103
|
+
"M3",
|
|
15104
|
+
"M4",
|
|
15105
|
+
"M5",
|
|
15106
|
+
"M6",
|
|
15107
|
+
"M8",
|
|
15108
|
+
"M10",
|
|
15109
|
+
"M12"
|
|
15110
|
+
]);
|
|
15111
|
+
var hexSocketBoltModelPropsShape = {
|
|
15112
|
+
metricSize: metricBoltSizeSchema,
|
|
15113
|
+
/** Length under the head, excluding the head itself. */
|
|
15114
|
+
length: positiveModelLengthSchema,
|
|
15115
|
+
showThreads: z4.boolean().default(true)
|
|
15116
|
+
};
|
|
15117
|
+
var hexSocketBoltModelPropsSchema = z4.object(hexSocketBoltModelPropsShape).strict();
|
|
15118
|
+
var hexSocketBoltModelDefinitionSchema = z4.object({
|
|
15119
|
+
fn: z4.literal("hexsocketbolt"),
|
|
15120
|
+
...hexSocketBoltModelPropsShape
|
|
15121
|
+
}).strict();
|
|
15122
|
+
var flexScreenOrientationSchema = z5.enum([
|
|
15123
|
+
"sitsFlat",
|
|
15124
|
+
"sitsFlatBelowBoard",
|
|
15125
|
+
"foldedToFaceAboveBoard",
|
|
15126
|
+
"foldedToFaceBelowBoard",
|
|
15127
|
+
"foldedToRightAngleAboveBoard",
|
|
15128
|
+
"foldedToRightAngleBelowBoard"
|
|
15129
|
+
]);
|
|
15130
|
+
var positiveFiniteNumberSchema = z5.number().finite().positive();
|
|
15131
|
+
var aspectRatioStringSchema = z5.string().refine((value) => {
|
|
15132
|
+
const parts = value.split(":");
|
|
15133
|
+
if (parts.length !== 2) return false;
|
|
15134
|
+
const width10 = Number(parts[0]);
|
|
15135
|
+
const height10 = Number(parts[1]);
|
|
15136
|
+
return Number.isFinite(width10) && Number.isFinite(height10) && width10 > 0 && height10 > 0;
|
|
15137
|
+
}, 'Aspect ratio must look like "16:9"').transform((value) => value);
|
|
15138
|
+
var flexScreenAspectRatioSchema = z5.union([
|
|
15139
|
+
positiveFiniteNumberSchema,
|
|
15140
|
+
aspectRatioStringSchema,
|
|
15141
|
+
z5.tuple([positiveFiniteNumberSchema, positiveFiniteNumberSchema])
|
|
15142
|
+
]);
|
|
15143
|
+
var modelPointSchema = z5.object({
|
|
15144
|
+
x: modelLengthSchema.optional(),
|
|
15145
|
+
y: modelLengthSchema.optional(),
|
|
15146
|
+
z: modelLengthSchema.optional()
|
|
15147
|
+
}).strict();
|
|
15148
|
+
var rotationValueSchema = z5.union([z5.number().finite(), z5.string().min(1)]);
|
|
15149
|
+
var modelRotationSchema = z5.tuple([
|
|
15150
|
+
rotationValueSchema,
|
|
15151
|
+
rotationValueSchema,
|
|
15152
|
+
rotationValueSchema
|
|
15153
|
+
]);
|
|
15154
|
+
var orientationShortcutKeys = [
|
|
15155
|
+
"sitsFlat",
|
|
15156
|
+
"sitsFlatBelowBoard",
|
|
15157
|
+
"foldedToFaceAboveBoard",
|
|
15158
|
+
"foldedToFaceBelowBoard",
|
|
15159
|
+
"foldsAboveBoard",
|
|
15160
|
+
"foldsBelowBoard",
|
|
15161
|
+
"foldedToRightAngleAboveBoard",
|
|
15162
|
+
"foldedToRightAngleBelowBoard"
|
|
15163
|
+
];
|
|
15164
|
+
var flexScreenModelPropsShape = {
|
|
15165
|
+
width: positiveModelLengthSchema.optional(),
|
|
15166
|
+
height: positiveModelLengthSchema.optional(),
|
|
15167
|
+
diagonal: positiveModelLengthSchema.optional(),
|
|
15168
|
+
aspectRatio: flexScreenAspectRatioSchema.optional(),
|
|
15169
|
+
ratio: flexScreenAspectRatioSchema.optional(),
|
|
15170
|
+
defaultDiagonal: positiveModelLengthSchema.optional(),
|
|
15171
|
+
orientation: flexScreenOrientationSchema.optional(),
|
|
15172
|
+
sitsFlat: z5.boolean().optional(),
|
|
15173
|
+
sitsFlatBelowBoard: z5.boolean().optional(),
|
|
15174
|
+
foldedToFaceAboveBoard: z5.boolean().optional(),
|
|
15175
|
+
foldedToFaceBelowBoard: z5.boolean().optional(),
|
|
15176
|
+
foldsAboveBoard: z5.boolean().optional(),
|
|
15177
|
+
foldsBelowBoard: z5.boolean().optional(),
|
|
15178
|
+
foldedToRightAngleAboveBoard: z5.boolean().optional(),
|
|
15179
|
+
foldedToRightAngleBelowBoard: z5.boolean().optional(),
|
|
15180
|
+
screenThickness: positiveModelLengthSchema.optional(),
|
|
15181
|
+
bezelInset: nonnegativeModelLengthSchema.optional(),
|
|
15182
|
+
bezelDepth: positiveModelLengthSchema.optional(),
|
|
15183
|
+
activeAreaWidth: positiveModelLengthSchema.optional(),
|
|
15184
|
+
activeAreaHeight: positiveModelLengthSchema.optional(),
|
|
15185
|
+
screenColor: z5.string().min(1).optional(),
|
|
15186
|
+
bezelColor: z5.string().min(1).optional(),
|
|
15187
|
+
showScreen: z5.boolean().optional(),
|
|
15188
|
+
flexCableLength: positiveModelLengthSchema.optional(),
|
|
15189
|
+
flexCableWidth: positiveModelLengthSchema.optional(),
|
|
15190
|
+
flexCableThickness: positiveModelLengthSchema.optional(),
|
|
15191
|
+
flexCableColor: z5.string().min(1).optional(),
|
|
15192
|
+
conductorCount: z5.number().int().positive().optional(),
|
|
15193
|
+
conductorPitch: positiveModelLengthSchema.optional(),
|
|
15194
|
+
conductorWidth: positiveModelLengthSchema.optional(),
|
|
15195
|
+
conductorThickness: positiveModelLengthSchema.optional(),
|
|
15196
|
+
conductorColor: z5.string().min(1).optional(),
|
|
15197
|
+
cableEdgeMargin: nonnegativeModelLengthSchema.optional(),
|
|
15198
|
+
exposedContactLength: nonnegativeModelLengthSchema.optional(),
|
|
15199
|
+
showConductors: z5.boolean().optional(),
|
|
15200
|
+
showFlexCable: z5.boolean().optional(),
|
|
15201
|
+
showStiffeners: z5.boolean().optional(),
|
|
15202
|
+
stiffenerLength: nonnegativeModelLengthSchema.optional(),
|
|
15203
|
+
stiffenerThickness: positiveModelLengthSchema.optional(),
|
|
15204
|
+
stiffenerColor: z5.string().min(1).optional(),
|
|
15205
|
+
bendRadius: positiveModelLengthSchema.optional(),
|
|
15206
|
+
bendSegments: z5.number().int().min(2).optional(),
|
|
15207
|
+
rightAngleVerticalLead: nonnegativeModelLengthSchema.optional(),
|
|
15208
|
+
distanceAboveBoard: nonnegativeModelLengthSchema.optional(),
|
|
15209
|
+
distanceBelowBoard: nonnegativeModelLengthSchema.optional(),
|
|
15210
|
+
foldDistanceFromConnector: nonnegativeModelLengthSchema.optional(),
|
|
15211
|
+
foldOutset: positiveModelLengthSchema.optional(),
|
|
15212
|
+
foldSegments: z5.number().int().min(4).optional(),
|
|
15213
|
+
screenGap: nonnegativeModelLengthSchema.optional(),
|
|
15214
|
+
boardTopZ: modelLengthSchema.optional(),
|
|
15215
|
+
boardThickness: positiveModelLengthSchema.optional(),
|
|
15216
|
+
boardClearance: nonnegativeModelLengthSchema.optional(),
|
|
15217
|
+
cableStartX: modelLengthSchema.optional(),
|
|
15218
|
+
cableStartY: modelLengthSchema.optional(),
|
|
15219
|
+
cableStartZ: modelLengthSchema.optional(),
|
|
15220
|
+
cableLateralOffset: modelLengthSchema.optional(),
|
|
15221
|
+
screenOffset: modelPointSchema.optional(),
|
|
15222
|
+
screenRotation: modelRotationSchema.optional(),
|
|
15223
|
+
rotation: modelRotationSchema.optional(),
|
|
15224
|
+
offset: modelPointSchema.optional()
|
|
15225
|
+
};
|
|
15226
|
+
var addOrientationShortcutIssue = (props, addIssue) => {
|
|
15227
|
+
const selectedShortcuts = orientationShortcutKeys.filter(
|
|
15228
|
+
(key) => props[key] === true
|
|
15229
|
+
);
|
|
15230
|
+
if (selectedShortcuts.length > 1) addIssue(selectedShortcuts[1]);
|
|
15231
|
+
};
|
|
15232
|
+
var flexScreenModelPropsSchema = z5.object(flexScreenModelPropsShape).strict().superRefine((props, context) => {
|
|
15233
|
+
addOrientationShortcutIssue(props, (path) => {
|
|
15234
|
+
context.addIssue({
|
|
15235
|
+
code: "custom",
|
|
15236
|
+
message: "Only one FlexScreen orientation shortcut can be true",
|
|
15237
|
+
path: [path]
|
|
15238
|
+
});
|
|
15239
|
+
});
|
|
15240
|
+
});
|
|
15241
|
+
var flexScreenModelDefinitionSchema = z5.object({
|
|
15242
|
+
fn: z5.literal("flexscreen"),
|
|
15243
|
+
...flexScreenModelPropsShape
|
|
15244
|
+
}).strict().superRefine((model, context) => {
|
|
15245
|
+
addOrientationShortcutIssue(model, (path) => {
|
|
15246
|
+
context.addIssue({
|
|
15247
|
+
code: "custom",
|
|
15248
|
+
message: "Only one FlexScreen orientation shortcut can be true",
|
|
15249
|
+
path: [path]
|
|
15250
|
+
});
|
|
15251
|
+
});
|
|
15252
|
+
});
|
|
15253
|
+
var modelDefinitionSchema = z5.union([
|
|
15254
|
+
nemaMotorModelDefinitionSchema,
|
|
15255
|
+
sheetMetalModelDefinitionSchema,
|
|
15256
|
+
flexScreenModelDefinitionSchema,
|
|
15257
|
+
hexSocketBoltModelDefinitionSchema
|
|
15258
|
+
]);
|
|
15259
|
+
function splitModelStringTokens(value) {
|
|
15260
|
+
const tokens = [];
|
|
15261
|
+
let depth = 0;
|
|
15262
|
+
let start = 0;
|
|
15263
|
+
for (let index2 = 0; index2 < value.length; index2++) {
|
|
15264
|
+
const character = value[index2];
|
|
15265
|
+
if (character === "(") depth++;
|
|
15266
|
+
if (character === ")") depth--;
|
|
15267
|
+
if (depth < 0 || depth > 1) throw new Error("Invalid feature parentheses");
|
|
15268
|
+
if (character === "_" && depth === 0) {
|
|
15269
|
+
tokens.push(value.slice(start, index2));
|
|
15270
|
+
start = index2 + 1;
|
|
15271
|
+
}
|
|
15272
|
+
}
|
|
15273
|
+
if (depth !== 0) throw new Error("Unclosed feature parentheses");
|
|
15274
|
+
tokens.push(value.slice(start));
|
|
15275
|
+
if (tokens.some((token) => !token))
|
|
15276
|
+
throw new Error("Model strings cannot contain empty tokens");
|
|
15277
|
+
return tokens;
|
|
15278
|
+
}
|
|
15279
|
+
var parsePart = (part) => {
|
|
15280
|
+
const match = part.match(/^([a-zA-Z]+)([\(\d\.\+\-].*)?$/);
|
|
15281
|
+
if (!match?.[1]) return void 0;
|
|
15282
|
+
return {
|
|
15283
|
+
fn: match[1].toLowerCase(),
|
|
15284
|
+
value: match[2]
|
|
15285
|
+
};
|
|
15286
|
+
};
|
|
15287
|
+
var parseModelStringParams = (definition) => {
|
|
15288
|
+
const normalizedDefinition = definition.trim();
|
|
15289
|
+
if (!normalizedDefinition) throw new Error("Model string cannot be empty");
|
|
15290
|
+
const parts = splitModelStringTokens(normalizedDefinition);
|
|
15291
|
+
const firstPart = parts[0];
|
|
15292
|
+
const first = parsePart(firstPart);
|
|
15293
|
+
const params = {};
|
|
15294
|
+
const fn = first?.fn ?? firstPart.toLowerCase();
|
|
15295
|
+
params[fn] = true;
|
|
15296
|
+
params.fn = fn;
|
|
15297
|
+
if (first?.value) {
|
|
15298
|
+
const numericValue = Number.parseFloat(first.value);
|
|
15299
|
+
if (Number.isFinite(numericValue)) params.num_pins = numericValue;
|
|
15300
|
+
}
|
|
15301
|
+
for (const part of parts.slice(1)) {
|
|
15302
|
+
if (!part) throw new Error("Model strings cannot contain empty tokens");
|
|
15303
|
+
const parsed = parsePart(part);
|
|
15304
|
+
if (!parsed) throw new Error(`Invalid model string token "${part}"`);
|
|
15305
|
+
params[parsed.fn] = parsed.value ?? true;
|
|
15306
|
+
}
|
|
15307
|
+
params.string = normalizedDefinition;
|
|
15308
|
+
return params;
|
|
15309
|
+
};
|
|
15310
|
+
var lengths = {
|
|
15311
|
+
l: "bodyLength",
|
|
15312
|
+
length: "bodyLength",
|
|
15313
|
+
bodylength: "bodyLength",
|
|
15314
|
+
bodywidth: "bodyWidth",
|
|
15315
|
+
shaftlength: "shaftLength",
|
|
15316
|
+
shaftdiameter: "shaftDiameter",
|
|
15317
|
+
flatdepth: "shaftFlatDepth",
|
|
15318
|
+
flatlength: "shaftFlatLength",
|
|
15319
|
+
holespacing: "mountingHoleSpacing",
|
|
15320
|
+
holediameter: "mountingHoleDiameter",
|
|
15321
|
+
holedepth: "mountingHoleDepth",
|
|
15322
|
+
pilotdiameter: "pilotDiameter",
|
|
15323
|
+
pilotlength: "pilotLength",
|
|
15324
|
+
frontcap: "frontCapLength",
|
|
15325
|
+
rearcap: "rearCapLength",
|
|
15326
|
+
facechamfer: "faceCornerChamfer",
|
|
15327
|
+
bodychamfer: "bodyCornerChamfer"
|
|
15328
|
+
};
|
|
15329
|
+
function parseNemaMotorModelParams(raw) {
|
|
15330
|
+
const tokens = raw.string.split("_");
|
|
15331
|
+
const match = tokens[0]?.match(/^nema(8|17|23)$/i);
|
|
15332
|
+
if (!match) throw new Error("Expected nema8, nema17 or nema23");
|
|
15333
|
+
const props = {
|
|
15334
|
+
fn: "nema",
|
|
15335
|
+
nemaSize: Number(match[1])
|
|
15336
|
+
};
|
|
15337
|
+
for (const token of tokens.slice(1)) {
|
|
15338
|
+
const match2 = token.match(/^([a-z]+)(.*)$/i);
|
|
15339
|
+
if (!match2) throw new Error(`Invalid NEMA token "${token}"`);
|
|
15340
|
+
const name = match2[1].toLowerCase(), value = match2[2];
|
|
15341
|
+
let property, parsed;
|
|
15342
|
+
if (name in lengths) {
|
|
15343
|
+
property = lengths[name];
|
|
15344
|
+
parsed = value;
|
|
15345
|
+
} else if (name === "flatangle") {
|
|
15346
|
+
property = "shaftFlatAngle";
|
|
15347
|
+
if (!/^[+-]?(?:\d+(?:\.\d*)?|\.\d+)(?:deg)?$/i.test(value))
|
|
15348
|
+
throw new Error("flatangle requires a numeric angle in degrees");
|
|
15349
|
+
parsed = Number(value.replace(/deg$/i, ""));
|
|
15350
|
+
} else if (["round", "dshaft", "throughholes", "blindholes"].includes(name)) {
|
|
15351
|
+
if (value) throw new Error(`NEMA flag "${name}" does not accept a value`);
|
|
15352
|
+
property = name === "round" || name === "dshaft" ? "shaftShape" : "mountingHoleThrough";
|
|
15353
|
+
parsed = name === "round" ? "round" : name === "dshaft" ? "d" : name === "throughholes";
|
|
15354
|
+
} else throw new Error(`Unknown NEMA motor token "${token}"`);
|
|
15355
|
+
if (property in props)
|
|
15356
|
+
throw new Error(`NEMA property "${property}" is set more than once`);
|
|
15357
|
+
props[property] = parsed;
|
|
15358
|
+
}
|
|
15359
|
+
return nemaMotorModelDefinitionSchema.parse(props);
|
|
15360
|
+
}
|
|
15361
|
+
function parseSheetMetalFeature(feature, profile) {
|
|
15362
|
+
const match = feature.match(/^(hole|slot)[1-9]\d*\(([^()]+)\)$/);
|
|
15363
|
+
if (!match) throw new Error(`Invalid sheet metal feature "${feature}"`);
|
|
15364
|
+
const kind = match[1];
|
|
15365
|
+
const values = {};
|
|
15366
|
+
for (const token of match[2].split("_")) {
|
|
15367
|
+
const parameter = token.match(
|
|
15368
|
+
/^(leftofcenter|rightofcenter|abovecenter|belowcenter|r|d|l|w)([0-9.].*)$/
|
|
15369
|
+
);
|
|
15370
|
+
const key = parameter?.[1] ?? token;
|
|
15371
|
+
if (key in values) throw new Error(`Duplicate ${key} in ${feature}`);
|
|
15372
|
+
values[key] = parameter?.[2] ?? "";
|
|
15373
|
+
}
|
|
15374
|
+
const allowed = /* @__PURE__ */ new Set([
|
|
15375
|
+
"bottomface",
|
|
15376
|
+
"angledface",
|
|
15377
|
+
"leftface",
|
|
15378
|
+
"rightface",
|
|
15379
|
+
"leftofcenter",
|
|
15380
|
+
"rightofcenter",
|
|
15381
|
+
"abovecenter",
|
|
15382
|
+
"belowcenter",
|
|
15383
|
+
...kind === "hole" ? ["r", "d"] : ["l", "w", "horizontal", "vertical"]
|
|
15384
|
+
]);
|
|
15385
|
+
for (const key of Object.keys(values)) {
|
|
15386
|
+
if (!allowed.has(key)) throw new Error(`Unknown ${key} in ${feature}`);
|
|
15387
|
+
}
|
|
15388
|
+
const faces = ["bottomface", "angledface", "leftface", "rightface"].filter(
|
|
15389
|
+
(face22) => face22 in values
|
|
15390
|
+
);
|
|
15391
|
+
if (faces.length !== 1)
|
|
15392
|
+
throw new Error(`Specify exactly one face in ${feature}`);
|
|
15393
|
+
const face2 = faces[0];
|
|
15394
|
+
if (face2 === "angledface" && profile !== "angle" || ["leftface", "rightface"].includes(face2) && profile !== "channel")
|
|
15395
|
+
throw new Error(`No ${face2} on ${profile}`);
|
|
15396
|
+
for (const [a, b] of [
|
|
15397
|
+
["leftofcenter", "rightofcenter"],
|
|
15398
|
+
["abovecenter", "belowcenter"],
|
|
15399
|
+
["horizontal", "vertical"],
|
|
15400
|
+
["r", "d"]
|
|
15401
|
+
]) {
|
|
15402
|
+
if (a in values && b in values)
|
|
15403
|
+
throw new Error(`Conflicting ${a} and ${b} in ${feature}`);
|
|
15404
|
+
}
|
|
15405
|
+
const distance6 = (key) => key in values ? positiveModelLengthSchema.parse(values[key]) : 0;
|
|
15406
|
+
const horizontal = distance6("rightofcenter") - distance6("leftofcenter");
|
|
15407
|
+
const vertical = distance6("abovecenter") - distance6("belowcenter");
|
|
15408
|
+
const panel = face2 === "bottomface" ? "base" : face2 === "leftface" ? "left" : "right";
|
|
15409
|
+
const position = {
|
|
15410
|
+
panel,
|
|
15411
|
+
u: panel === "base" ? horizontal : vertical,
|
|
15412
|
+
v: panel === "base" ? vertical : horizontal * (panel === "left" ? -1 : 1)
|
|
15413
|
+
};
|
|
15414
|
+
if (kind === "hole") {
|
|
15415
|
+
if (!("r" in values) && !("d" in values))
|
|
15416
|
+
throw new Error(`Hole requires r or d in ${feature}`);
|
|
15417
|
+
return sheetMetalHoleSchema.parse({
|
|
15418
|
+
...position,
|
|
15419
|
+
shape: "round",
|
|
15420
|
+
diameter: "r" in values ? 2 * distance6("r") : distance6("d")
|
|
15421
|
+
});
|
|
15422
|
+
}
|
|
15423
|
+
if (!("l" in values) || !("w" in values))
|
|
15424
|
+
throw new Error(`Slot requires l and w in ${feature}`);
|
|
15425
|
+
const length83 = distance6("l"), width10 = distance6("w");
|
|
15426
|
+
if (length83 < width10) throw new Error("Slot length must be at least its width");
|
|
15427
|
+
return sheetMetalHoleSchema.parse({
|
|
15428
|
+
...position,
|
|
15429
|
+
shape: "slot",
|
|
15430
|
+
length: length83,
|
|
15431
|
+
width: width10,
|
|
15432
|
+
axis: panel === "base" === !("vertical" in values) ? "u" : "v"
|
|
15433
|
+
});
|
|
15434
|
+
}
|
|
15435
|
+
var lengths2 = {
|
|
15436
|
+
w: "width",
|
|
15437
|
+
l: "baseLength",
|
|
15438
|
+
h: "flangeHeight",
|
|
15439
|
+
t: "thickness",
|
|
15440
|
+
r: "insideBendRadius"
|
|
15441
|
+
};
|
|
15442
|
+
function parseSheetMetalModelParams(raw) {
|
|
15443
|
+
const props = {};
|
|
15444
|
+
const tokens = splitModelStringTokens(raw.string);
|
|
15445
|
+
if (tokens[0] !== "sheetmetal") throw new Error("Expected sheetmetal");
|
|
15446
|
+
const features = [];
|
|
15447
|
+
const featureNames = /* @__PURE__ */ new Set();
|
|
15448
|
+
for (const token of tokens.slice(1)) {
|
|
15449
|
+
if (/^(hole|slot)[1-9]\d*\(/.test(token)) {
|
|
15450
|
+
const name = token.slice(0, token.indexOf("("));
|
|
15451
|
+
if (featureNames.has(name)) throw new Error(`Duplicate feature "${name}"`);
|
|
15452
|
+
featureNames.add(name);
|
|
15453
|
+
features.push(token);
|
|
15454
|
+
continue;
|
|
15455
|
+
}
|
|
15456
|
+
if (["plate", "angle", "channel"].includes(token)) {
|
|
15457
|
+
if (props.profile) throw new Error("Duplicate sheet metal profile");
|
|
15458
|
+
props.profile = token;
|
|
15459
|
+
continue;
|
|
15460
|
+
}
|
|
15461
|
+
const key = lengths2[token[0]];
|
|
15462
|
+
if (!key || token.length < 2)
|
|
15463
|
+
throw new Error(`Unknown sheet metal token "${token}"`);
|
|
15464
|
+
if (key in props) throw new Error(`Duplicate sheet metal property "${key}"`);
|
|
15465
|
+
props[key] = token.slice(1);
|
|
15466
|
+
}
|
|
15467
|
+
const definition = sheetMetalModelDefinitionSchema.parse({
|
|
15468
|
+
fn: "sheetmetal",
|
|
15469
|
+
...props
|
|
15470
|
+
});
|
|
15471
|
+
definition.holes = features.map(
|
|
15472
|
+
(feature) => parseSheetMetalFeature(feature, definition.profile)
|
|
15473
|
+
);
|
|
15474
|
+
return definition;
|
|
15475
|
+
}
|
|
15476
|
+
var parseHexSocketBoltModelParams = (raw) => {
|
|
15477
|
+
if (raw.fn !== "hexsocketbolt") {
|
|
15478
|
+
throw new Error(`Expected hexsocketbolt params, got "${raw.fn}"`);
|
|
15479
|
+
}
|
|
15480
|
+
const tokens = raw.string.split("_");
|
|
15481
|
+
if (tokens[0]?.toLowerCase() !== "hexsocketbolt") {
|
|
15482
|
+
throw new Error(
|
|
15483
|
+
"The hexsocketbolt function does not accept an inline value"
|
|
15484
|
+
);
|
|
15485
|
+
}
|
|
15486
|
+
const seen = /* @__PURE__ */ new Set();
|
|
15487
|
+
for (const token of tokens.slice(1)) {
|
|
15488
|
+
const name = token.match(/^[a-z]+/i)?.[0]?.toLowerCase();
|
|
15489
|
+
if (name && seen.has(name))
|
|
15490
|
+
throw new Error(`Duplicate bolt token "${name}"`);
|
|
15491
|
+
if (name) seen.add(name);
|
|
15492
|
+
}
|
|
15493
|
+
const props = {};
|
|
15494
|
+
for (const [token, value] of Object.entries(raw)) {
|
|
15495
|
+
if (["fn", "string", "hexsocketbolt"].includes(token)) continue;
|
|
15496
|
+
let property;
|
|
15497
|
+
let parsed = value;
|
|
15498
|
+
if (token === "m") {
|
|
15499
|
+
property = "metricSize";
|
|
15500
|
+
parsed = `M${String(value)}`;
|
|
15501
|
+
} else if (token === "l" || token === "length") {
|
|
15502
|
+
property = "length";
|
|
15503
|
+
} else if (token === "threads" || token === "nothreads") {
|
|
15504
|
+
if (value !== true)
|
|
15505
|
+
throw new Error(`Bolt token "${token}" does not accept a value`);
|
|
15506
|
+
property = "showThreads";
|
|
15507
|
+
parsed = token === "threads";
|
|
15508
|
+
} else {
|
|
15509
|
+
throw new Error(
|
|
15510
|
+
`Unknown hex socket bolt model token "${token}${String(value)}"`
|
|
15511
|
+
);
|
|
15512
|
+
}
|
|
15513
|
+
if (property in props)
|
|
15514
|
+
throw new Error(`Bolt property "${property}" is set more than once`);
|
|
15515
|
+
props[property] = parsed;
|
|
15516
|
+
}
|
|
15517
|
+
return hexSocketBoltModelDefinitionSchema.parse({
|
|
15518
|
+
fn: "hexsocketbolt",
|
|
15519
|
+
...props
|
|
15520
|
+
});
|
|
15521
|
+
};
|
|
15522
|
+
var orientationTokens = {
|
|
15523
|
+
sitsflat: "sitsFlat",
|
|
15524
|
+
sitsflatbelow: "sitsFlatBelowBoard",
|
|
15525
|
+
sitsflatbelowboard: "sitsFlatBelowBoard",
|
|
15526
|
+
foldsabove: "foldedToFaceAboveBoard",
|
|
15527
|
+
foldsaboveboard: "foldedToFaceAboveBoard",
|
|
15528
|
+
foldedtofaceaboveboard: "foldedToFaceAboveBoard",
|
|
15529
|
+
foldsbelow: "foldedToFaceBelowBoard",
|
|
15530
|
+
foldsbelowboard: "foldedToFaceBelowBoard",
|
|
15531
|
+
foldedtofacebelowboard: "foldedToFaceBelowBoard",
|
|
15532
|
+
rightangleabove: "foldedToRightAngleAboveBoard",
|
|
15533
|
+
rightangleaboveboard: "foldedToRightAngleAboveBoard",
|
|
15534
|
+
foldedtorightangleaboveboard: "foldedToRightAngleAboveBoard",
|
|
15535
|
+
rightanglebelow: "foldedToRightAngleBelowBoard",
|
|
15536
|
+
rightanglebelowboard: "foldedToRightAngleBelowBoard",
|
|
15537
|
+
foldedtorightanglebelowboard: "foldedToRightAngleBelowBoard"
|
|
15538
|
+
};
|
|
15539
|
+
var lengthProperties = {
|
|
15540
|
+
width: ["width", "w"],
|
|
15541
|
+
height: ["height", "h"],
|
|
15542
|
+
diagonal: ["diagonal", "diag", "d"],
|
|
15543
|
+
defaultDiagonal: ["defaultdiagonal", "defaultdiag"],
|
|
15544
|
+
screenThickness: ["screenthickness"],
|
|
15545
|
+
bezelInset: ["bezelinset"],
|
|
15546
|
+
bezelDepth: ["bezeldepth"],
|
|
15547
|
+
activeAreaWidth: ["activeareawidth", "activew"],
|
|
15548
|
+
activeAreaHeight: ["activeareaheight", "activeh"],
|
|
15549
|
+
flexCableLength: ["flexcablelength", "flexlength", "flex"],
|
|
15550
|
+
flexCableWidth: ["flexcablewidth", "flexwidth"],
|
|
15551
|
+
flexCableThickness: ["flexcablethickness", "flexthickness"],
|
|
15552
|
+
conductorPitch: ["conductorpitch"],
|
|
15553
|
+
conductorWidth: ["conductorwidth"],
|
|
15554
|
+
conductorThickness: ["conductorthickness"],
|
|
15555
|
+
cableEdgeMargin: ["cableedgemargin", "edgemargin"],
|
|
15556
|
+
exposedContactLength: ["exposedcontactlength", "contactlength"],
|
|
15557
|
+
stiffenerLength: ["stiffenerlength"],
|
|
15558
|
+
stiffenerThickness: ["stiffenerthickness"],
|
|
15559
|
+
bendRadius: ["bendradius"],
|
|
15560
|
+
rightAngleVerticalLead: ["rightangleverticallead", "verticallead"],
|
|
15561
|
+
distanceAboveBoard: ["distanceaboveboard", "distanceabove"],
|
|
15562
|
+
distanceBelowBoard: ["distancebelowboard", "distancebelow"],
|
|
15563
|
+
foldDistanceFromConnector: [
|
|
15564
|
+
"folddistancefromconnector",
|
|
15565
|
+
"folddistance",
|
|
15566
|
+
"foldstart"
|
|
15567
|
+
],
|
|
15568
|
+
foldOutset: ["foldoutset", "outset"],
|
|
15569
|
+
screenGap: ["screengap"],
|
|
15570
|
+
boardTopZ: ["boardtopz"],
|
|
15571
|
+
boardThickness: ["boardthickness"],
|
|
15572
|
+
boardClearance: ["boardclearance"],
|
|
15573
|
+
cableStartX: ["cablestartx"],
|
|
15574
|
+
cableStartY: ["cablestarty"],
|
|
15575
|
+
cableStartZ: ["cablestartz"],
|
|
15576
|
+
cableLateralOffset: ["cablelateraloffset", "lateraloffset"]
|
|
15577
|
+
};
|
|
15578
|
+
var lengthTokenToProperty = Object.fromEntries(
|
|
15579
|
+
Object.entries(lengthProperties).flatMap(
|
|
15580
|
+
([property, tokens]) => tokens.map((token) => [token, property])
|
|
15581
|
+
)
|
|
15582
|
+
);
|
|
15583
|
+
var integerTokenToProperty = {
|
|
15584
|
+
conductorcount: "conductorCount",
|
|
15585
|
+
conductors: "conductorCount",
|
|
15586
|
+
bendsegments: "bendSegments",
|
|
15587
|
+
foldsegments: "foldSegments"
|
|
15588
|
+
};
|
|
15589
|
+
var booleanTokens = {
|
|
15590
|
+
showscreen: ["showScreen", true],
|
|
15591
|
+
hidescreen: ["showScreen", false],
|
|
15592
|
+
showflex: ["showFlexCable", true],
|
|
15593
|
+
hideflex: ["showFlexCable", false],
|
|
15594
|
+
showconductors: ["showConductors", true],
|
|
15595
|
+
hideconductors: ["showConductors", false],
|
|
15596
|
+
showstiffeners: ["showStiffeners", true],
|
|
15597
|
+
hidestiffeners: ["showStiffeners", false]
|
|
15598
|
+
};
|
|
15599
|
+
var colorProperties = {
|
|
15600
|
+
screencolor: "screenColor",
|
|
15601
|
+
bezelcolor: "bezelColor",
|
|
15602
|
+
flexcolor: "flexCableColor",
|
|
15603
|
+
conductorcolor: "conductorColor",
|
|
15604
|
+
stiffenercolor: "stiffenerColor"
|
|
15605
|
+
};
|
|
15606
|
+
var parseAspectRatio = (value) => {
|
|
15607
|
+
const normalized = String(value).toLowerCase().replace("x", ":");
|
|
15608
|
+
if (normalized.includes(":")) {
|
|
15609
|
+
const [width10, height10, extra] = normalized.split(":");
|
|
15610
|
+
const numericWidth = Number(width10);
|
|
15611
|
+
const numericHeight = Number(height10);
|
|
15612
|
+
if (extra !== void 0 || !Number.isFinite(numericWidth) || !Number.isFinite(numericHeight) || numericWidth <= 0 || numericHeight <= 0) {
|
|
15613
|
+
throw new Error(`Invalid FlexScreen aspect ratio "${String(value)}"`);
|
|
15614
|
+
}
|
|
15615
|
+
return `${numericWidth}:${numericHeight}`;
|
|
15616
|
+
}
|
|
15617
|
+
const numeric = Number(normalized);
|
|
15618
|
+
if (!Number.isFinite(numeric) || numeric <= 0) {
|
|
15619
|
+
throw new Error(`Invalid FlexScreen aspect ratio "${String(value)}"`);
|
|
15620
|
+
}
|
|
15621
|
+
return numeric;
|
|
15622
|
+
};
|
|
15623
|
+
var unwrapFunctionValue = (value, token) => {
|
|
15624
|
+
if (typeof value !== "string" || !/^\(.+\)$/.test(value)) {
|
|
15625
|
+
throw new Error(`FlexScreen token "${token}" requires a value in (...)`);
|
|
15626
|
+
}
|
|
15627
|
+
return value.slice(1, -1);
|
|
15628
|
+
};
|
|
15629
|
+
var assertBareToken = (value, token) => {
|
|
15630
|
+
if (value !== true) {
|
|
15631
|
+
throw new Error(`FlexScreen token "${token}" does not accept a value`);
|
|
15632
|
+
}
|
|
15633
|
+
};
|
|
15634
|
+
var parseFlexScreenModelParams = (rawParams) => {
|
|
15635
|
+
if (rawParams.fn !== "flexscreen") {
|
|
15636
|
+
throw new Error(`Expected FlexScreen params, got "${rawParams.fn}"`);
|
|
15637
|
+
}
|
|
15638
|
+
const props = {};
|
|
15639
|
+
let orientation2;
|
|
15640
|
+
let relativeDistance;
|
|
15641
|
+
for (const [token, value] of Object.entries(rawParams)) {
|
|
15642
|
+
if (token === "fn" || token === "string" || token === "flexscreen") {
|
|
15643
|
+
continue;
|
|
15644
|
+
}
|
|
15645
|
+
const tokenOrientation = orientationTokens[token];
|
|
15646
|
+
if (tokenOrientation) {
|
|
15647
|
+
assertBareToken(value, token);
|
|
15648
|
+
if (orientation2 && orientation2 !== tokenOrientation) {
|
|
15649
|
+
throw new Error(
|
|
15650
|
+
"A FlexScreen model string can only set one orientation"
|
|
15651
|
+
);
|
|
15652
|
+
}
|
|
15653
|
+
orientation2 = tokenOrientation;
|
|
15654
|
+
props.orientation = tokenOrientation;
|
|
15655
|
+
continue;
|
|
15656
|
+
}
|
|
15657
|
+
if (token in booleanTokens) {
|
|
15658
|
+
assertBareToken(value, token);
|
|
15659
|
+
const [property, enabled] = booleanTokens[token];
|
|
15660
|
+
props[property] = enabled;
|
|
15661
|
+
continue;
|
|
15662
|
+
}
|
|
15663
|
+
const colorProperty = colorProperties[token];
|
|
15664
|
+
if (colorProperty) {
|
|
15665
|
+
props[colorProperty] = unwrapFunctionValue(value, token);
|
|
15666
|
+
continue;
|
|
15667
|
+
}
|
|
15668
|
+
if (token === "ratio") {
|
|
15669
|
+
props.aspectRatio = parseAspectRatio(value);
|
|
15670
|
+
continue;
|
|
15671
|
+
}
|
|
15672
|
+
const lengthProperty = lengthTokenToProperty[token];
|
|
15673
|
+
if (lengthProperty) {
|
|
15674
|
+
props[lengthProperty] = value;
|
|
15675
|
+
continue;
|
|
15676
|
+
}
|
|
15677
|
+
if (token === "distance") {
|
|
15678
|
+
relativeDistance = value;
|
|
15679
|
+
continue;
|
|
15680
|
+
}
|
|
15681
|
+
const integerProperty = integerTokenToProperty[token];
|
|
15682
|
+
if (integerProperty) {
|
|
15683
|
+
const parsed = Number(value);
|
|
15684
|
+
if (!Number.isInteger(parsed) || parsed < 1) {
|
|
15685
|
+
throw new Error(
|
|
15686
|
+
`Invalid positive integer in FlexScreen token "${token}${String(value)}"`
|
|
15687
|
+
);
|
|
15688
|
+
}
|
|
15689
|
+
props[integerProperty] = parsed;
|
|
15690
|
+
continue;
|
|
15691
|
+
}
|
|
15692
|
+
throw new Error(`Unknown FlexScreen model token "${token}${String(value)}"`);
|
|
15693
|
+
}
|
|
15694
|
+
if (relativeDistance !== void 0) {
|
|
15695
|
+
if (orientation2 === "foldedToFaceAboveBoard") {
|
|
15696
|
+
props.distanceAboveBoard = relativeDistance;
|
|
15697
|
+
} else if (orientation2 === "foldedToFaceBelowBoard") {
|
|
15698
|
+
props.distanceBelowBoard = relativeDistance;
|
|
15699
|
+
} else {
|
|
15700
|
+
throw new Error(
|
|
15701
|
+
'The "distance" token requires foldsabove or foldsbelow; use distanceabove or distancebelow for an explicit side'
|
|
15702
|
+
);
|
|
15703
|
+
}
|
|
15704
|
+
}
|
|
15705
|
+
return flexScreenModelDefinitionSchema.parse({ fn: "flexscreen", ...props });
|
|
15706
|
+
};
|
|
15707
|
+
var modelFunctions = {
|
|
15708
|
+
nema: parseNemaMotorModelParams,
|
|
15709
|
+
sheetmetal: parseSheetMetalModelParams,
|
|
15710
|
+
flexscreen: parseFlexScreenModelParams,
|
|
15711
|
+
hexsocketbolt: parseHexSocketBoltModelParams
|
|
15712
|
+
};
|
|
15713
|
+
var modelParamsToJson = (params) => {
|
|
15714
|
+
const modelFunction = modelFunctions[params.fn];
|
|
15715
|
+
if (modelFunction) {
|
|
15716
|
+
return modelFunction(params);
|
|
15717
|
+
}
|
|
15718
|
+
throw new Error(`Unsupported modelprinter function "${params.fn}"`);
|
|
15719
|
+
};
|
|
15720
|
+
var string = (value) => {
|
|
15721
|
+
const params = parseModelStringParams(value);
|
|
15722
|
+
return {
|
|
15723
|
+
params: () => params,
|
|
15724
|
+
json: () => modelParamsToJson(params)
|
|
15725
|
+
};
|
|
15726
|
+
};
|
|
15727
|
+
var modelprinter = {
|
|
15728
|
+
string,
|
|
15729
|
+
getModelNames: () => Object.keys(modelFunctions)
|
|
15730
|
+
};
|
|
15731
|
+
var mp = modelprinter;
|
|
15732
|
+
|
|
15733
|
+
// node_modules/@tscircuit/footprinter/dist/index.js
|
|
15734
|
+
import {
|
|
15735
|
+
length as length82
|
|
15736
|
+
} from "circuit-json";
|
|
15737
|
+
import { length } from "circuit-json";
|
|
15738
|
+
import { z as z32 } from "zod";
|
|
15739
|
+
import { z as z22 } from "zod";
|
|
15740
|
+
import { z as z6 } from "zod";
|
|
15741
|
+
import { z as z42 } from "zod";
|
|
15742
|
+
|
|
15743
|
+
// node_modules/@tscircuit/footprinter/node_modules/@tscircuit/mm/dist/index.js
|
|
15744
|
+
var unitToMm2 = {
|
|
15745
|
+
in: 25.4,
|
|
15746
|
+
inch: 25.4,
|
|
15747
|
+
mil: 0.0254,
|
|
15748
|
+
mm: 1,
|
|
15749
|
+
m: 1e3,
|
|
15750
|
+
cm: 10,
|
|
15751
|
+
ft: 304.8,
|
|
15752
|
+
feet: 304.8
|
|
15753
|
+
};
|
|
15754
|
+
var mm2 = (n) => {
|
|
15755
|
+
let unit = typeof n === "number" ? "mm" : n.replace(/^[^a-zA-Z]+/g, "").toLowerCase();
|
|
15756
|
+
if (!unit)
|
|
15757
|
+
unit = "mm";
|
|
15758
|
+
const val = typeof n === "number" ? n : Number.parseFloat(n.split(unit)[0]);
|
|
15759
|
+
if (unit in unitToMm2) {
|
|
15760
|
+
return val * unitToMm2[unit];
|
|
15761
|
+
}
|
|
15762
|
+
throw new Error(`Unsupported unit: ${unit}`);
|
|
15763
|
+
};
|
|
15764
|
+
var mm_default = mm2;
|
|
14824
15765
|
|
|
14825
15766
|
// node_modules/@tscircuit/footprinter/dist/index.js
|
|
14826
15767
|
import {
|
|
14827
15768
|
length as length2
|
|
14828
15769
|
} from "circuit-json";
|
|
14829
|
-
import { z as
|
|
15770
|
+
import { z as z52 } from "zod";
|
|
14830
15771
|
import { distance, length as length3 } from "circuit-json";
|
|
14831
|
-
import { z as
|
|
15772
|
+
import { z as z62 } from "zod";
|
|
14832
15773
|
import {
|
|
14833
15774
|
length as length4
|
|
14834
15775
|
} from "circuit-json";
|
|
@@ -14871,7 +15812,7 @@ import {
|
|
|
14871
15812
|
} from "circuit-json";
|
|
14872
15813
|
import { z as z21 } from "zod";
|
|
14873
15814
|
import { length as length19 } from "circuit-json";
|
|
14874
|
-
import { z as
|
|
15815
|
+
import { z as z222 } from "zod";
|
|
14875
15816
|
import { length as length20 } from "circuit-json";
|
|
14876
15817
|
import { z as z23 } from "zod";
|
|
14877
15818
|
import { z as z24 } from "zod";
|
|
@@ -14892,7 +15833,7 @@ import {
|
|
|
14892
15833
|
length as length26
|
|
14893
15834
|
} from "circuit-json";
|
|
14894
15835
|
import { z as z31 } from "zod";
|
|
14895
|
-
import { z as
|
|
15836
|
+
import { z as z322 } from "zod";
|
|
14896
15837
|
import { length as length27 } from "circuit-json";
|
|
14897
15838
|
import {
|
|
14898
15839
|
length as length28
|
|
@@ -14947,7 +15888,7 @@ import { z as z50 } from "zod";
|
|
|
14947
15888
|
import { length as length44 } from "circuit-json";
|
|
14948
15889
|
import { z as z51 } from "zod";
|
|
14949
15890
|
import { length as length45 } from "circuit-json";
|
|
14950
|
-
import { z as
|
|
15891
|
+
import { z as z522 } from "zod";
|
|
14951
15892
|
import { length as length46 } from "circuit-json";
|
|
14952
15893
|
import { z as z53 } from "zod";
|
|
14953
15894
|
import { length as length47 } from "circuit-json";
|
|
@@ -14968,7 +15909,7 @@ import { z as z60 } from "zod";
|
|
|
14968
15909
|
import { length as length53 } from "circuit-json";
|
|
14969
15910
|
import { z as z61 } from "zod";
|
|
14970
15911
|
import { length as length54 } from "circuit-json";
|
|
14971
|
-
import { z as
|
|
15912
|
+
import { z as z622 } from "zod";
|
|
14972
15913
|
import { length as length55 } from "circuit-json";
|
|
14973
15914
|
import { z as z63 } from "zod";
|
|
14974
15915
|
import { length as length56 } from "circuit-json";
|
|
@@ -15172,7 +16113,7 @@ var silkscreenRef = (x, y, font_size) => {
|
|
|
15172
16113
|
anchor_alignment: "center"
|
|
15173
16114
|
};
|
|
15174
16115
|
};
|
|
15175
|
-
var function_call =
|
|
16116
|
+
var function_call = z6.string().or(z6.array(z6.any())).transform((a) => {
|
|
15176
16117
|
if (Array.isArray(a)) return a;
|
|
15177
16118
|
if (a.startsWith("(") && a.endsWith(")")) {
|
|
15178
16119
|
a = a.slice(1, -1);
|
|
@@ -15181,32 +16122,32 @@ var function_call = z.string().or(z.array(z.any())).transform((a) => {
|
|
|
15181
16122
|
const numVal = Number(v);
|
|
15182
16123
|
return isNaN(numVal) ? v : numVal;
|
|
15183
16124
|
});
|
|
15184
|
-
}).pipe(
|
|
15185
|
-
var horizontalSide =
|
|
15186
|
-
var verticalSide =
|
|
15187
|
-
var horizontalAlignment =
|
|
15188
|
-
var verticalAlignment =
|
|
16125
|
+
}).pipe(z6.array(z6.string().or(z6.number())));
|
|
16126
|
+
var horizontalSide = z22.enum(["leftside", "rightside"]);
|
|
16127
|
+
var verticalSide = z22.enum(["topside", "bottomside"]);
|
|
16128
|
+
var horizontalAlignment = z22.enum(["left", "right"]);
|
|
16129
|
+
var verticalAlignment = z22.enum(["top", "bottom"]);
|
|
15189
16130
|
var pin1_location = function_call.pipe(
|
|
15190
|
-
|
|
15191
|
-
|
|
15192
|
-
|
|
16131
|
+
z22.union([
|
|
16132
|
+
z22.tuple([horizontalSide, verticalAlignment]),
|
|
16133
|
+
z22.tuple([verticalSide, horizontalAlignment])
|
|
15193
16134
|
])
|
|
15194
16135
|
);
|
|
15195
|
-
var base_def =
|
|
15196
|
-
norefdes:
|
|
15197
|
-
invert:
|
|
16136
|
+
var base_def = z32.object({
|
|
16137
|
+
norefdes: z32.boolean().optional().describe("disable reference designator label"),
|
|
16138
|
+
invert: z32.boolean().optional().describe(
|
|
15198
16139
|
"install the part backwards: for a pin header, the LONG pins pass through the board instead of the short ones. It does not change which side of the board the part is on \u2014 that is the component's `layer`"
|
|
15199
16140
|
),
|
|
15200
|
-
faceup:
|
|
16141
|
+
faceup: z32.boolean().optional().describe(
|
|
15201
16142
|
"DEPRECATED, and a no-op for through-hole parts. It meant 'the male pin header should face upwards, out of the top layer', which is what a correctly mounted header does by default; its other effect was to delete the pins below the board, leaving a through-hole part that cannot be soldered into its own plated holes. Use `layer` for which side of the board a part is on, and `invert` to install it backwards"
|
|
15202
16143
|
),
|
|
15203
|
-
nosilkscreen:
|
|
16144
|
+
nosilkscreen: z32.boolean().optional().describe("omit all silkscreen elements from the footprint"),
|
|
15204
16145
|
rounded: length.refine((radius) => radius >= 0, {
|
|
15205
16146
|
message: "rounded radius must be non-negative"
|
|
15206
16147
|
}).optional().describe("corner radius applied to all rectangular copper pads"),
|
|
15207
16148
|
pin1location: pin1_location.optional().describe("rotate the footprint to place pin 1 on a requested side"),
|
|
15208
|
-
cathodepin:
|
|
15209
|
-
anodepin:
|
|
16149
|
+
cathodepin: z32.coerce.number().pipe(z32.union([z32.literal(1), z32.literal(2)])).optional().describe("identify which diode pad is the cathode"),
|
|
16150
|
+
anodepin: z32.coerce.number().pipe(z32.union([z32.literal(1), z32.literal(2)])).optional().describe("identify which diode pad is the anode")
|
|
15210
16151
|
});
|
|
15211
16152
|
var platedhole = (pn, x, y, id, od) => {
|
|
15212
16153
|
return {
|
|
@@ -15215,8 +16156,8 @@ var platedhole = (pn, x, y, id, od) => {
|
|
|
15215
16156
|
shape: "circle",
|
|
15216
16157
|
x,
|
|
15217
16158
|
y,
|
|
15218
|
-
hole_diameter:
|
|
15219
|
-
outer_diameter:
|
|
16159
|
+
hole_diameter: mm2(id),
|
|
16160
|
+
outer_diameter: mm2(od),
|
|
15220
16161
|
pcb_port_id: "",
|
|
15221
16162
|
layers: ["top", "bottom"],
|
|
15222
16163
|
port_hints: [pn.toString()]
|
|
@@ -15240,11 +16181,11 @@ var platedHoleWithRectPad = (options) => {
|
|
|
15240
16181
|
shape: "circular_hole_with_rect_pad",
|
|
15241
16182
|
x,
|
|
15242
16183
|
y,
|
|
15243
|
-
hole_diameter:
|
|
16184
|
+
hole_diameter: mm2(holeDiameter),
|
|
15244
16185
|
hole_shape: "circle",
|
|
15245
16186
|
pad_shape: "rect",
|
|
15246
|
-
rect_pad_width:
|
|
15247
|
-
rect_pad_height:
|
|
16187
|
+
rect_pad_width: mm2(rectPadWidth),
|
|
16188
|
+
rect_pad_height: mm2(rectPadHeight),
|
|
15248
16189
|
...rectBorderRadius !== void 0 && {
|
|
15249
16190
|
rect_border_radius: rectBorderRadius
|
|
15250
16191
|
},
|
|
@@ -15364,17 +16305,17 @@ function convertMilToMm(value) {
|
|
|
15364
16305
|
}
|
|
15365
16306
|
return Number(value);
|
|
15366
16307
|
}
|
|
15367
|
-
var lengthInMm =
|
|
16308
|
+
var lengthInMm = z42.union([z42.string(), z42.number()]).transform((val) => convertMilToMm(val));
|
|
15368
16309
|
var extendDipDef = (newDefaults) => base_def.extend({
|
|
15369
|
-
fn:
|
|
15370
|
-
num_pins:
|
|
15371
|
-
wide:
|
|
15372
|
-
narrow:
|
|
16310
|
+
fn: z42.string(),
|
|
16311
|
+
num_pins: z42.number().optional().default(6),
|
|
16312
|
+
wide: z42.boolean().optional(),
|
|
16313
|
+
narrow: z42.boolean().optional(),
|
|
15373
16314
|
w: lengthInMm.optional(),
|
|
15374
16315
|
p: lengthInMm.default(newDefaults.p ?? "2.54mm"),
|
|
15375
16316
|
id: lengthInMm.optional(),
|
|
15376
16317
|
od: lengthInMm.optional(),
|
|
15377
|
-
nosquareplating:
|
|
16318
|
+
nosquareplating: z42.boolean().optional().default(false).describe("do not use rectangular pad for pin 1")
|
|
15378
16319
|
}).transform((v) => {
|
|
15379
16320
|
if (!v.id && !v.od) {
|
|
15380
16321
|
if (Math.abs(v.p - 1.27) < 0.01) {
|
|
@@ -15554,8 +16495,8 @@ var silkscreenpath = (route, options = {}) => {
|
|
|
15554
16495
|
};
|
|
15555
16496
|
};
|
|
15556
16497
|
var dpak_def = base_def.extend({
|
|
15557
|
-
fn:
|
|
15558
|
-
num_pins:
|
|
16498
|
+
fn: z52.string(),
|
|
16499
|
+
num_pins: z52.union([z52.literal(3), z52.literal(6)]).default(3),
|
|
15559
16500
|
p: length2.default("2.29mm").describe("pitch between adjacent lead positions"),
|
|
15560
16501
|
pw: length2.default("1.6mm").describe("lead pad width along the pin column"),
|
|
15561
16502
|
pl: length2.default("3mm").describe("lead pad length toward the package"),
|
|
@@ -15564,7 +16505,7 @@ var dpak_def = base_def.extend({
|
|
|
15564
16505
|
span: length2.default("6.85mm").describe("center-to-center distance from the leads to the tab"),
|
|
15565
16506
|
w: length2.default("6.6mm").describe("package body width"),
|
|
15566
16507
|
h: length2.default("6.5mm").describe("package body height"),
|
|
15567
|
-
string:
|
|
16508
|
+
string: z52.string().optional()
|
|
15568
16509
|
});
|
|
15569
16510
|
var d2pakDefaults = {
|
|
15570
16511
|
p: "2.54mm",
|
|
@@ -15838,9 +16779,9 @@ var createCourtyardRect = (width10, height10) => ({
|
|
|
15838
16779
|
layer: "top"
|
|
15839
16780
|
});
|
|
15840
16781
|
var passive_def = base_def.extend({
|
|
15841
|
-
fn:
|
|
15842
|
-
string:
|
|
15843
|
-
tht:
|
|
16782
|
+
fn: z62.string().optional(),
|
|
16783
|
+
string: z62.string().optional(),
|
|
16784
|
+
tht: z62.boolean(),
|
|
15844
16785
|
p: length3.optional(),
|
|
15845
16786
|
pw: length3.optional(),
|
|
15846
16787
|
ph: length3.optional(),
|
|
@@ -15850,9 +16791,9 @@ var passive_def = base_def.extend({
|
|
|
15850
16791
|
h: length3.optional(),
|
|
15851
16792
|
cyw: length3.optional().describe("courtyard width"),
|
|
15852
16793
|
cyh: length3.optional().describe("courtyard height"),
|
|
15853
|
-
nonpolarized:
|
|
15854
|
-
textbottom:
|
|
15855
|
-
roundedPads:
|
|
16794
|
+
nonpolarized: z62.boolean().optional(),
|
|
16795
|
+
textbottom: z62.boolean().optional(),
|
|
16796
|
+
roundedPads: z62.boolean().optional()
|
|
15856
16797
|
});
|
|
15857
16798
|
var passive = (params) => {
|
|
15858
16799
|
let {
|
|
@@ -17818,16 +18759,16 @@ var mlp = (parameters) => {
|
|
|
17818
18759
|
return quad(parameters);
|
|
17819
18760
|
};
|
|
17820
18761
|
var ssop_def = base_def.extend({
|
|
17821
|
-
fn:
|
|
17822
|
-
num_pins:
|
|
18762
|
+
fn: z222.string(),
|
|
18763
|
+
num_pins: z222.number().optional().default(8),
|
|
17823
18764
|
w: length19.default(length19.parse("3.9mm")),
|
|
17824
18765
|
p: length19.default(length19.parse("1.27mm")),
|
|
17825
18766
|
pw: length19.optional(),
|
|
17826
18767
|
pl: length19.optional(),
|
|
17827
|
-
legsoutside:
|
|
18768
|
+
legsoutside: z222.boolean().optional().default(false),
|
|
17828
18769
|
thermalpad: dim2d.optional(),
|
|
17829
18770
|
...thermalPadOffsetFields,
|
|
17830
|
-
silkscreen_stroke_width:
|
|
18771
|
+
silkscreen_stroke_width: z222.number().optional().default(0.1)
|
|
17831
18772
|
}).transform((v) => {
|
|
17832
18773
|
if (v.pw == null && v.pl == null) {
|
|
17833
18774
|
v.pw = length19.parse("0.51mm");
|
|
@@ -19377,13 +20318,13 @@ var sot723WithoutParsing = (parameters) => {
|
|
|
19377
20318
|
return pads;
|
|
19378
20319
|
};
|
|
19379
20320
|
var sod_def = base_def.extend({
|
|
19380
|
-
fn:
|
|
19381
|
-
num_pins:
|
|
19382
|
-
w:
|
|
19383
|
-
h:
|
|
19384
|
-
pl:
|
|
19385
|
-
pw:
|
|
19386
|
-
p:
|
|
20321
|
+
fn: z322.string(),
|
|
20322
|
+
num_pins: z322.literal(2).default(2),
|
|
20323
|
+
w: z322.string().default("2.36mm"),
|
|
20324
|
+
h: z322.string().default("1.22mm"),
|
|
20325
|
+
pl: z322.string().default("0.9mm"),
|
|
20326
|
+
pw: z322.string().default("1.2mm"),
|
|
20327
|
+
p: z322.string().default("3.30mm")
|
|
19387
20328
|
});
|
|
19388
20329
|
var sod123 = (raw_params) => {
|
|
19389
20330
|
const parameters = sod_def.parse(raw_params);
|
|
@@ -21067,8 +22008,8 @@ var pad_def = base_def.extend({
|
|
|
21067
22008
|
});
|
|
21068
22009
|
var pad = (params) => {
|
|
21069
22010
|
const { w, h: h2 } = params;
|
|
21070
|
-
const width10 =
|
|
21071
|
-
const height10 =
|
|
22011
|
+
const width10 = mm2(w);
|
|
22012
|
+
const height10 = mm2(h2);
|
|
21072
22013
|
return {
|
|
21073
22014
|
circuitJson: [
|
|
21074
22015
|
rectpad(1, 0, 0, width10, height10),
|
|
@@ -21084,10 +22025,10 @@ var platedHolePill = (pn, x, y, holeDiameter, outerWidth, outerHeight) => {
|
|
|
21084
22025
|
shape: "pill",
|
|
21085
22026
|
x,
|
|
21086
22027
|
y,
|
|
21087
|
-
outer_width:
|
|
21088
|
-
outer_height:
|
|
21089
|
-
hole_width:
|
|
21090
|
-
hole_height:
|
|
22028
|
+
outer_width: mm2(outerWidth),
|
|
22029
|
+
outer_height: mm2(outerHeight),
|
|
22030
|
+
hole_width: mm2(holeDiameter),
|
|
22031
|
+
hole_height: mm2(holeDiameter),
|
|
21091
22032
|
pcb_port_id: "",
|
|
21092
22033
|
layers: ["top", "bottom"],
|
|
21093
22034
|
port_hints: [pn.toString()],
|
|
@@ -22011,13 +22952,13 @@ var sodWithoutParsing8 = (parameters) => {
|
|
|
22011
22952
|
return pads;
|
|
22012
22953
|
};
|
|
22013
22954
|
var sod123FL_def = base_def.extend({
|
|
22014
|
-
fn:
|
|
22015
|
-
num_pins:
|
|
22016
|
-
w:
|
|
22017
|
-
h:
|
|
22018
|
-
pl:
|
|
22019
|
-
pw:
|
|
22020
|
-
p:
|
|
22955
|
+
fn: z522.string(),
|
|
22956
|
+
num_pins: z522.literal(2).default(2),
|
|
22957
|
+
w: z522.string().default("4.4mm"),
|
|
22958
|
+
h: z522.string().default("2.1mm"),
|
|
22959
|
+
pl: z522.string().default("0.91mm"),
|
|
22960
|
+
pw: z522.string().default("1.22mm"),
|
|
22961
|
+
p: z522.string().default("3.146mm")
|
|
22021
22962
|
});
|
|
22022
22963
|
var sod123fl = (raw_params) => {
|
|
22023
22964
|
const parameters = sod123FL_def.parse(raw_params);
|
|
@@ -22599,9 +23540,9 @@ var to220f = (raw_params) => {
|
|
|
22599
23540
|
i + 1,
|
|
22600
23541
|
x,
|
|
22601
23542
|
holeY,
|
|
22602
|
-
|
|
22603
|
-
|
|
22604
|
-
|
|
23543
|
+
mm2(parameters.id),
|
|
23544
|
+
mm2(parameters.od),
|
|
23545
|
+
mm2(parameters.ph)
|
|
22605
23546
|
);
|
|
22606
23547
|
}
|
|
22607
23548
|
);
|
|
@@ -22970,13 +23911,13 @@ var microMelfWithoutParsing = (parameters) => {
|
|
|
22970
23911
|
return pads;
|
|
22971
23912
|
};
|
|
22972
23913
|
var sma_def = base_def.extend({
|
|
22973
|
-
fn:
|
|
22974
|
-
num_pins:
|
|
22975
|
-
w:
|
|
22976
|
-
h:
|
|
22977
|
-
pl:
|
|
22978
|
-
pw:
|
|
22979
|
-
p:
|
|
23914
|
+
fn: z622.string(),
|
|
23915
|
+
num_pins: z622.literal(2).default(2),
|
|
23916
|
+
w: z622.string().default("7.10mm"),
|
|
23917
|
+
h: z622.string().default("3.40mm"),
|
|
23918
|
+
pl: z622.string().default("2.50mm"),
|
|
23919
|
+
pw: z622.string().default("1.80mm"),
|
|
23920
|
+
p: z622.string().default("4.00mm")
|
|
22980
23921
|
});
|
|
22981
23922
|
var sma = (raw_params) => {
|
|
22982
23923
|
const parameters = sma_def.parse(raw_params);
|
|
@@ -26335,40 +27276,40 @@ var smtpad_def = base_def.extend({
|
|
|
26335
27276
|
size: length73.optional(),
|
|
26336
27277
|
string: z85.string().optional()
|
|
26337
27278
|
}).transform((v) => {
|
|
26338
|
-
let
|
|
26339
|
-
if (v.circle)
|
|
26340
|
-
if (v.square)
|
|
26341
|
-
if (v.rect)
|
|
26342
|
-
if (v.pill)
|
|
27279
|
+
let shape2 = "rect";
|
|
27280
|
+
if (v.circle) shape2 = "circle";
|
|
27281
|
+
if (v.square) shape2 = "square";
|
|
27282
|
+
if (v.rect) shape2 = "rect";
|
|
27283
|
+
if (v.pill) shape2 = "pill";
|
|
26343
27284
|
let radius;
|
|
26344
27285
|
let width10;
|
|
26345
27286
|
let height10;
|
|
26346
|
-
if (
|
|
26347
|
-
if (v.r !== void 0) radius =
|
|
26348
|
-
else if (v.pr !== void 0) radius =
|
|
26349
|
-
else if (v.radius !== void 0) radius =
|
|
26350
|
-
else if (v.d !== void 0) radius =
|
|
26351
|
-
else if (v.pd !== void 0) radius =
|
|
26352
|
-
else if (v.diameter !== void 0) radius =
|
|
26353
|
-
else radius =
|
|
27287
|
+
if (shape2 === "circle") {
|
|
27288
|
+
if (v.r !== void 0) radius = mm2(v.r);
|
|
27289
|
+
else if (v.pr !== void 0) radius = mm2(v.pr);
|
|
27290
|
+
else if (v.radius !== void 0) radius = mm2(v.radius);
|
|
27291
|
+
else if (v.d !== void 0) radius = mm2(v.d) / 2;
|
|
27292
|
+
else if (v.pd !== void 0) radius = mm2(v.pd) / 2;
|
|
27293
|
+
else if (v.diameter !== void 0) radius = mm2(v.diameter) / 2;
|
|
27294
|
+
else radius = mm2("1mm") / 2;
|
|
26354
27295
|
} else {
|
|
26355
|
-
if (v.w !== void 0) width10 =
|
|
26356
|
-
else if (v.pw !== void 0) width10 =
|
|
26357
|
-
else if (v.width !== void 0) width10 =
|
|
26358
|
-
else if (v.s !== void 0) width10 =
|
|
26359
|
-
else if (v.size !== void 0) width10 =
|
|
26360
|
-
else width10 =
|
|
26361
|
-
if (v.h !== void 0) height10 =
|
|
26362
|
-
else if (v.ph !== void 0) height10 =
|
|
26363
|
-
else if (v.height !== void 0) height10 =
|
|
26364
|
-
else if (
|
|
26365
|
-
else if (
|
|
27296
|
+
if (v.w !== void 0) width10 = mm2(v.w);
|
|
27297
|
+
else if (v.pw !== void 0) width10 = mm2(v.pw);
|
|
27298
|
+
else if (v.width !== void 0) width10 = mm2(v.width);
|
|
27299
|
+
else if (v.s !== void 0) width10 = mm2(v.s);
|
|
27300
|
+
else if (v.size !== void 0) width10 = mm2(v.size);
|
|
27301
|
+
else width10 = mm2("1mm");
|
|
27302
|
+
if (v.h !== void 0) height10 = mm2(v.h);
|
|
27303
|
+
else if (v.ph !== void 0) height10 = mm2(v.ph);
|
|
27304
|
+
else if (v.height !== void 0) height10 = mm2(v.height);
|
|
27305
|
+
else if (shape2 === "square") height10 = width10;
|
|
27306
|
+
else if (shape2 === "rect")
|
|
26366
27307
|
height10 = width10;
|
|
26367
|
-
else height10 =
|
|
27308
|
+
else height10 = mm2("1mm");
|
|
26368
27309
|
}
|
|
26369
27310
|
return {
|
|
26370
27311
|
fn: v.fn,
|
|
26371
|
-
shape,
|
|
27312
|
+
shape: shape2,
|
|
26372
27313
|
radius,
|
|
26373
27314
|
width: width10,
|
|
26374
27315
|
height: height10
|
|
@@ -26376,13 +27317,13 @@ var smtpad_def = base_def.extend({
|
|
|
26376
27317
|
});
|
|
26377
27318
|
var smtpad = (raw_params) => {
|
|
26378
27319
|
const params = smtpad_def.parse(raw_params);
|
|
26379
|
-
const { shape, radius, width: width10, height: height10 } = params;
|
|
27320
|
+
const { shape: shape2, radius, width: width10, height: height10 } = params;
|
|
26380
27321
|
let pad2;
|
|
26381
27322
|
let silkscreenOffset;
|
|
26382
|
-
if (
|
|
27323
|
+
if (shape2 === "circle") {
|
|
26383
27324
|
pad2 = circlepad(1, { x: 0, y: 0, radius });
|
|
26384
27325
|
silkscreenOffset = radius + 0.5;
|
|
26385
|
-
} else if (
|
|
27326
|
+
} else if (shape2 === "pill") {
|
|
26386
27327
|
pad2 = pillpad(1, 0, 0, width10, height10);
|
|
26387
27328
|
silkscreenOffset = Math.max(width10, height10) / 2 + 0.5;
|
|
26388
27329
|
} else {
|
|
@@ -26763,14 +27704,14 @@ var platedhole_def = base_def.extend({
|
|
|
26763
27704
|
squarepad: z90.boolean().optional().default(false)
|
|
26764
27705
|
}).transform((v) => {
|
|
26765
27706
|
let holeD;
|
|
26766
|
-
if (v.d !== void 0) holeD =
|
|
26767
|
-
else if (v.hd !== void 0) holeD =
|
|
26768
|
-
else if (v.r !== void 0) holeD =
|
|
26769
|
-
else if (v.hr !== void 0) holeD =
|
|
26770
|
-
else holeD =
|
|
27707
|
+
if (v.d !== void 0) holeD = mm2(v.d);
|
|
27708
|
+
else if (v.hd !== void 0) holeD = mm2(v.hd);
|
|
27709
|
+
else if (v.r !== void 0) holeD = mm2(v.r) * 2;
|
|
27710
|
+
else if (v.hr !== void 0) holeD = mm2(v.hr) * 2;
|
|
27711
|
+
else holeD = mm2("1mm");
|
|
26771
27712
|
let padD;
|
|
26772
|
-
if (v.pd !== void 0) padD =
|
|
26773
|
-
else if (v.pr !== void 0) padD =
|
|
27713
|
+
if (v.pd !== void 0) padD = mm2(v.pd);
|
|
27714
|
+
else if (v.pr !== void 0) padD = mm2(v.pr) * 2;
|
|
26774
27715
|
else padD = holeD * (1.5 / 1);
|
|
26775
27716
|
return {
|
|
26776
27717
|
fn: v.fn,
|
|
@@ -28269,7 +29210,7 @@ var applyPin1Location = (elements, pin1Location) => {
|
|
|
28269
29210
|
var clampRadius = (radius, width10, height10) => Math.min(radius, width10 / 2, height10 / 2);
|
|
28270
29211
|
var applyRounded = (elements, rounded) => {
|
|
28271
29212
|
if (rounded === void 0) return elements;
|
|
28272
|
-
const radius =
|
|
29213
|
+
const radius = mm2(rounded);
|
|
28273
29214
|
if (!Number.isFinite(radius) || radius < 0) {
|
|
28274
29215
|
throw new Error(
|
|
28275
29216
|
`rounded radius must be a non-negative length, got "${rounded}"`
|
|
@@ -28437,425 +29378,551 @@ footprinter.string = string2;
|
|
|
28437
29378
|
footprinter.getFootprintNames = getFootprintNames;
|
|
28438
29379
|
var fp = footprinter;
|
|
28439
29380
|
|
|
28440
|
-
// node_modules
|
|
28441
|
-
var
|
|
28442
|
-
in: 25.4,
|
|
28443
|
-
inch: 25.4,
|
|
28444
|
-
mil: 0.0254,
|
|
28445
|
-
mm: 1,
|
|
28446
|
-
m: 1e3,
|
|
28447
|
-
cm: 10,
|
|
28448
|
-
ft: 304.8,
|
|
28449
|
-
feet: 304.8
|
|
28450
|
-
};
|
|
28451
|
-
var mmNumberFormatter = new Intl.NumberFormat("en-US", {
|
|
28452
|
-
useGrouping: false,
|
|
28453
|
-
notation: "standard",
|
|
28454
|
-
maximumFractionDigits: 12
|
|
28455
|
-
});
|
|
28456
|
-
var mm2 = (n) => {
|
|
28457
|
-
let unit = typeof n === "number" ? "mm" : n.replace(/^[^a-zA-Z]+/g, "").toLowerCase();
|
|
28458
|
-
if (!unit)
|
|
28459
|
-
unit = "mm";
|
|
28460
|
-
const val = typeof n === "number" ? n : Number.parseFloat(n.split(unit)[0]);
|
|
28461
|
-
if (unit in unitToMm2) {
|
|
28462
|
-
return val * unitToMm2[unit];
|
|
28463
|
-
}
|
|
28464
|
-
throw new Error(`Unsupported unit: ${unit}`);
|
|
28465
|
-
};
|
|
29381
|
+
// node_modules/jscad-electronics/dist/vanilla.js
|
|
29382
|
+
var import_modeling = __toESM(require_src(), 1);
|
|
28466
29383
|
|
|
28467
|
-
// node_modules
|
|
28468
|
-
|
|
28469
|
-
var
|
|
28470
|
-
|
|
28471
|
-
|
|
28472
|
-
|
|
28473
|
-
|
|
28474
|
-
|
|
28475
|
-
|
|
28476
|
-
|
|
28477
|
-
|
|
28478
|
-
|
|
28479
|
-
|
|
29384
|
+
// node_modules/earcut/src/earcut.js
|
|
29385
|
+
var steiners = /* @__PURE__ */ new Set();
|
|
29386
|
+
var filteredOut = false;
|
|
29387
|
+
function earcut(data, holeIndices, dim = 2) {
|
|
29388
|
+
const hasHoles = holeIndices && holeIndices.length;
|
|
29389
|
+
const outerLen = hasHoles ? holeIndices[0] * dim : data.length;
|
|
29390
|
+
if (steiners.size) steiners.clear();
|
|
29391
|
+
let outerNode = linkedList(data, 0, outerLen, dim, true);
|
|
29392
|
+
const triangles = [];
|
|
29393
|
+
if (!outerNode || outerNode.next === outerNode.prev) return triangles;
|
|
29394
|
+
let minX = 0, minY = 0, invSize = 0;
|
|
29395
|
+
if (hasHoles) outerNode = eliminateHoles(data, holeIndices, outerNode, dim);
|
|
29396
|
+
if (data.length > 80 * dim) {
|
|
29397
|
+
minX = data[0];
|
|
29398
|
+
minY = data[1];
|
|
29399
|
+
let maxX = minX;
|
|
29400
|
+
let maxY = minY;
|
|
29401
|
+
for (let i = dim; i < outerLen; i += dim) {
|
|
29402
|
+
const x = data[i];
|
|
29403
|
+
const y = data[i + 1];
|
|
29404
|
+
if (x < minX) minX = x;
|
|
29405
|
+
if (y < minY) minY = y;
|
|
29406
|
+
if (x > maxX) maxX = x;
|
|
29407
|
+
if (y > maxY) maxY = y;
|
|
29408
|
+
}
|
|
29409
|
+
invSize = Math.max(maxX - minX, maxY - minY);
|
|
29410
|
+
invSize = invSize !== 0 ? 32767 / invSize : 0;
|
|
28480
29411
|
}
|
|
28481
|
-
|
|
28482
|
-
|
|
28483
|
-
|
|
28484
|
-
|
|
28485
|
-
|
|
28486
|
-
|
|
28487
|
-
|
|
28488
|
-
|
|
28489
|
-
);
|
|
28490
|
-
var flexScreenOrientationSchema = z27.enum([
|
|
28491
|
-
"sitsFlat",
|
|
28492
|
-
"sitsFlatBelowBoard",
|
|
28493
|
-
"foldedToFaceAboveBoard",
|
|
28494
|
-
"foldedToFaceBelowBoard",
|
|
28495
|
-
"foldedToRightAngleAboveBoard",
|
|
28496
|
-
"foldedToRightAngleBelowBoard"
|
|
28497
|
-
]);
|
|
28498
|
-
var positiveFiniteNumberSchema = z27.number().finite().positive();
|
|
28499
|
-
var aspectRatioStringSchema = z27.string().refine((value) => {
|
|
28500
|
-
const parts = value.split(":");
|
|
28501
|
-
if (parts.length !== 2) return false;
|
|
28502
|
-
const width10 = Number(parts[0]);
|
|
28503
|
-
const height10 = Number(parts[1]);
|
|
28504
|
-
return Number.isFinite(width10) && Number.isFinite(height10) && width10 > 0 && height10 > 0;
|
|
28505
|
-
}, 'Aspect ratio must look like "16:9"').transform((value) => value);
|
|
28506
|
-
var flexScreenAspectRatioSchema = z27.union([
|
|
28507
|
-
positiveFiniteNumberSchema,
|
|
28508
|
-
aspectRatioStringSchema,
|
|
28509
|
-
z27.tuple([positiveFiniteNumberSchema, positiveFiniteNumberSchema])
|
|
28510
|
-
]);
|
|
28511
|
-
var modelPointSchema = z27.object({
|
|
28512
|
-
x: modelLengthSchema.optional(),
|
|
28513
|
-
y: modelLengthSchema.optional(),
|
|
28514
|
-
z: modelLengthSchema.optional()
|
|
28515
|
-
}).strict();
|
|
28516
|
-
var rotationValueSchema = z27.union([z27.number().finite(), z27.string().min(1)]);
|
|
28517
|
-
var modelRotationSchema = z27.tuple([
|
|
28518
|
-
rotationValueSchema,
|
|
28519
|
-
rotationValueSchema,
|
|
28520
|
-
rotationValueSchema
|
|
28521
|
-
]);
|
|
28522
|
-
var orientationShortcutKeys = [
|
|
28523
|
-
"sitsFlat",
|
|
28524
|
-
"sitsFlatBelowBoard",
|
|
28525
|
-
"foldedToFaceAboveBoard",
|
|
28526
|
-
"foldedToFaceBelowBoard",
|
|
28527
|
-
"foldsAboveBoard",
|
|
28528
|
-
"foldsBelowBoard",
|
|
28529
|
-
"foldedToRightAngleAboveBoard",
|
|
28530
|
-
"foldedToRightAngleBelowBoard"
|
|
28531
|
-
];
|
|
28532
|
-
var flexScreenModelPropsShape = {
|
|
28533
|
-
width: positiveModelLengthSchema.optional(),
|
|
28534
|
-
height: positiveModelLengthSchema.optional(),
|
|
28535
|
-
diagonal: positiveModelLengthSchema.optional(),
|
|
28536
|
-
aspectRatio: flexScreenAspectRatioSchema.optional(),
|
|
28537
|
-
ratio: flexScreenAspectRatioSchema.optional(),
|
|
28538
|
-
defaultDiagonal: positiveModelLengthSchema.optional(),
|
|
28539
|
-
orientation: flexScreenOrientationSchema.optional(),
|
|
28540
|
-
sitsFlat: z27.boolean().optional(),
|
|
28541
|
-
sitsFlatBelowBoard: z27.boolean().optional(),
|
|
28542
|
-
foldedToFaceAboveBoard: z27.boolean().optional(),
|
|
28543
|
-
foldedToFaceBelowBoard: z27.boolean().optional(),
|
|
28544
|
-
foldsAboveBoard: z27.boolean().optional(),
|
|
28545
|
-
foldsBelowBoard: z27.boolean().optional(),
|
|
28546
|
-
foldedToRightAngleAboveBoard: z27.boolean().optional(),
|
|
28547
|
-
foldedToRightAngleBelowBoard: z27.boolean().optional(),
|
|
28548
|
-
screenThickness: positiveModelLengthSchema.optional(),
|
|
28549
|
-
bezelInset: nonnegativeModelLengthSchema.optional(),
|
|
28550
|
-
bezelDepth: positiveModelLengthSchema.optional(),
|
|
28551
|
-
activeAreaWidth: positiveModelLengthSchema.optional(),
|
|
28552
|
-
activeAreaHeight: positiveModelLengthSchema.optional(),
|
|
28553
|
-
screenColor: z27.string().min(1).optional(),
|
|
28554
|
-
bezelColor: z27.string().min(1).optional(),
|
|
28555
|
-
showScreen: z27.boolean().optional(),
|
|
28556
|
-
flexCableLength: positiveModelLengthSchema.optional(),
|
|
28557
|
-
flexCableWidth: positiveModelLengthSchema.optional(),
|
|
28558
|
-
flexCableThickness: positiveModelLengthSchema.optional(),
|
|
28559
|
-
flexCableColor: z27.string().min(1).optional(),
|
|
28560
|
-
conductorCount: z27.number().int().positive().optional(),
|
|
28561
|
-
conductorPitch: positiveModelLengthSchema.optional(),
|
|
28562
|
-
conductorWidth: positiveModelLengthSchema.optional(),
|
|
28563
|
-
conductorThickness: positiveModelLengthSchema.optional(),
|
|
28564
|
-
conductorColor: z27.string().min(1).optional(),
|
|
28565
|
-
cableEdgeMargin: nonnegativeModelLengthSchema.optional(),
|
|
28566
|
-
exposedContactLength: nonnegativeModelLengthSchema.optional(),
|
|
28567
|
-
showConductors: z27.boolean().optional(),
|
|
28568
|
-
showFlexCable: z27.boolean().optional(),
|
|
28569
|
-
showStiffeners: z27.boolean().optional(),
|
|
28570
|
-
stiffenerLength: nonnegativeModelLengthSchema.optional(),
|
|
28571
|
-
stiffenerThickness: positiveModelLengthSchema.optional(),
|
|
28572
|
-
stiffenerColor: z27.string().min(1).optional(),
|
|
28573
|
-
bendRadius: positiveModelLengthSchema.optional(),
|
|
28574
|
-
bendSegments: z27.number().int().min(2).optional(),
|
|
28575
|
-
rightAngleVerticalLead: nonnegativeModelLengthSchema.optional(),
|
|
28576
|
-
distanceAboveBoard: nonnegativeModelLengthSchema.optional(),
|
|
28577
|
-
distanceBelowBoard: nonnegativeModelLengthSchema.optional(),
|
|
28578
|
-
foldDistanceFromConnector: nonnegativeModelLengthSchema.optional(),
|
|
28579
|
-
foldOutset: positiveModelLengthSchema.optional(),
|
|
28580
|
-
foldSegments: z27.number().int().min(4).optional(),
|
|
28581
|
-
screenGap: nonnegativeModelLengthSchema.optional(),
|
|
28582
|
-
boardTopZ: modelLengthSchema.optional(),
|
|
28583
|
-
boardThickness: positiveModelLengthSchema.optional(),
|
|
28584
|
-
boardClearance: nonnegativeModelLengthSchema.optional(),
|
|
28585
|
-
cableStartX: modelLengthSchema.optional(),
|
|
28586
|
-
cableStartY: modelLengthSchema.optional(),
|
|
28587
|
-
cableStartZ: modelLengthSchema.optional(),
|
|
28588
|
-
cableLateralOffset: modelLengthSchema.optional(),
|
|
28589
|
-
screenOffset: modelPointSchema.optional(),
|
|
28590
|
-
screenRotation: modelRotationSchema.optional(),
|
|
28591
|
-
rotation: modelRotationSchema.optional(),
|
|
28592
|
-
offset: modelPointSchema.optional()
|
|
28593
|
-
};
|
|
28594
|
-
var addOrientationShortcutIssue = (props, addIssue) => {
|
|
28595
|
-
const selectedShortcuts = orientationShortcutKeys.filter(
|
|
28596
|
-
(key) => props[key] === true
|
|
28597
|
-
);
|
|
28598
|
-
if (selectedShortcuts.length > 1) addIssue(selectedShortcuts[1]);
|
|
28599
|
-
};
|
|
28600
|
-
var flexScreenModelPropsSchema = z27.object(flexScreenModelPropsShape).strict().superRefine((props, context) => {
|
|
28601
|
-
addOrientationShortcutIssue(props, (path) => {
|
|
28602
|
-
context.addIssue({
|
|
28603
|
-
code: "custom",
|
|
28604
|
-
message: "Only one FlexScreen orientation shortcut can be true",
|
|
28605
|
-
path: [path]
|
|
28606
|
-
});
|
|
28607
|
-
});
|
|
28608
|
-
});
|
|
28609
|
-
var flexScreenModelDefinitionSchema = z27.object({
|
|
28610
|
-
fn: z27.literal("flexscreen"),
|
|
28611
|
-
...flexScreenModelPropsShape
|
|
28612
|
-
}).strict().superRefine((model, context) => {
|
|
28613
|
-
addOrientationShortcutIssue(model, (path) => {
|
|
28614
|
-
context.addIssue({
|
|
28615
|
-
code: "custom",
|
|
28616
|
-
message: "Only one FlexScreen orientation shortcut can be true",
|
|
28617
|
-
path: [path]
|
|
28618
|
-
});
|
|
28619
|
-
});
|
|
28620
|
-
});
|
|
28621
|
-
var parsePart = (part) => {
|
|
28622
|
-
const match = part.match(/^([a-zA-Z]+)([\(\d\.\+\-].*)?$/);
|
|
28623
|
-
if (!match?.[1]) return void 0;
|
|
28624
|
-
return {
|
|
28625
|
-
fn: match[1].toLowerCase(),
|
|
28626
|
-
value: match[2]
|
|
28627
|
-
};
|
|
28628
|
-
};
|
|
28629
|
-
var parseModelStringParams = (definition) => {
|
|
28630
|
-
const normalizedDefinition = definition.trim();
|
|
28631
|
-
if (!normalizedDefinition) throw new Error("Model string cannot be empty");
|
|
28632
|
-
const parts = normalizedDefinition.split("_");
|
|
28633
|
-
const firstPart = parts[0];
|
|
28634
|
-
const first = parsePart(firstPart);
|
|
28635
|
-
const params = {};
|
|
28636
|
-
const fn = first?.fn ?? firstPart.toLowerCase();
|
|
28637
|
-
params[fn] = true;
|
|
28638
|
-
params.fn = fn;
|
|
28639
|
-
if (first?.value) {
|
|
28640
|
-
const numericValue = Number.parseFloat(first.value);
|
|
28641
|
-
if (Number.isFinite(numericValue)) params.num_pins = numericValue;
|
|
29412
|
+
earcutLinked(outerNode, triangles, minX, minY, invSize);
|
|
29413
|
+
return triangles;
|
|
29414
|
+
}
|
|
29415
|
+
function linkedList(data, start, end, dim, clockwise) {
|
|
29416
|
+
let last = null;
|
|
29417
|
+
if (clockwise === signedArea(data, start, end, dim) > 0) {
|
|
29418
|
+
for (let i = start; i < end; i += dim) last = insertNode(i / dim | 0, data[i], data[i + 1], last);
|
|
29419
|
+
} else {
|
|
29420
|
+
for (let i = end - dim; i >= start; i -= dim) last = insertNode(i / dim | 0, data[i], data[i + 1], last);
|
|
28642
29421
|
}
|
|
28643
|
-
|
|
28644
|
-
|
|
28645
|
-
|
|
28646
|
-
if (!parsed) throw new Error(`Invalid model string token "${part}"`);
|
|
28647
|
-
params[parsed.fn] = parsed.value ?? true;
|
|
29422
|
+
if (last && equals(last, last.next)) {
|
|
29423
|
+
removeNode(last);
|
|
29424
|
+
last = last.next;
|
|
28648
29425
|
}
|
|
28649
|
-
|
|
28650
|
-
|
|
28651
|
-
|
|
28652
|
-
|
|
28653
|
-
|
|
28654
|
-
|
|
28655
|
-
|
|
28656
|
-
|
|
28657
|
-
|
|
28658
|
-
|
|
28659
|
-
|
|
28660
|
-
|
|
28661
|
-
|
|
28662
|
-
|
|
28663
|
-
|
|
28664
|
-
|
|
28665
|
-
|
|
28666
|
-
|
|
28667
|
-
|
|
28668
|
-
}
|
|
28669
|
-
|
|
28670
|
-
|
|
28671
|
-
|
|
28672
|
-
|
|
28673
|
-
|
|
28674
|
-
|
|
28675
|
-
|
|
28676
|
-
|
|
28677
|
-
|
|
28678
|
-
|
|
28679
|
-
|
|
28680
|
-
|
|
28681
|
-
|
|
28682
|
-
|
|
28683
|
-
|
|
28684
|
-
|
|
28685
|
-
|
|
28686
|
-
|
|
28687
|
-
|
|
28688
|
-
|
|
28689
|
-
|
|
28690
|
-
|
|
28691
|
-
|
|
28692
|
-
|
|
28693
|
-
|
|
28694
|
-
|
|
28695
|
-
|
|
28696
|
-
|
|
28697
|
-
|
|
28698
|
-
foldOutset: ["foldoutset", "outset"],
|
|
28699
|
-
screenGap: ["screengap"],
|
|
28700
|
-
boardTopZ: ["boardtopz"],
|
|
28701
|
-
boardThickness: ["boardthickness"],
|
|
28702
|
-
boardClearance: ["boardclearance"],
|
|
28703
|
-
cableStartX: ["cablestartx"],
|
|
28704
|
-
cableStartY: ["cablestarty"],
|
|
28705
|
-
cableStartZ: ["cablestartz"],
|
|
28706
|
-
cableLateralOffset: ["cablelateraloffset", "lateraloffset"]
|
|
28707
|
-
};
|
|
28708
|
-
var lengthTokenToProperty = Object.fromEntries(
|
|
28709
|
-
Object.entries(lengthProperties).flatMap(
|
|
28710
|
-
([property, tokens]) => tokens.map((token) => [token, property])
|
|
28711
|
-
)
|
|
28712
|
-
);
|
|
28713
|
-
var integerTokenToProperty = {
|
|
28714
|
-
conductorcount: "conductorCount",
|
|
28715
|
-
conductors: "conductorCount",
|
|
28716
|
-
bendsegments: "bendSegments",
|
|
28717
|
-
foldsegments: "foldSegments"
|
|
28718
|
-
};
|
|
28719
|
-
var booleanTokens = {
|
|
28720
|
-
showscreen: ["showScreen", true],
|
|
28721
|
-
hidescreen: ["showScreen", false],
|
|
28722
|
-
showflex: ["showFlexCable", true],
|
|
28723
|
-
hideflex: ["showFlexCable", false],
|
|
28724
|
-
showconductors: ["showConductors", true],
|
|
28725
|
-
hideconductors: ["showConductors", false],
|
|
28726
|
-
showstiffeners: ["showStiffeners", true],
|
|
28727
|
-
hidestiffeners: ["showStiffeners", false]
|
|
28728
|
-
};
|
|
28729
|
-
var colorProperties = {
|
|
28730
|
-
screencolor: "screenColor",
|
|
28731
|
-
bezelcolor: "bezelColor",
|
|
28732
|
-
flexcolor: "flexCableColor",
|
|
28733
|
-
conductorcolor: "conductorColor",
|
|
28734
|
-
stiffenercolor: "stiffenerColor"
|
|
28735
|
-
};
|
|
28736
|
-
var parseAspectRatio = (value) => {
|
|
28737
|
-
const normalized = String(value).toLowerCase().replace("x", ":");
|
|
28738
|
-
if (normalized.includes(":")) {
|
|
28739
|
-
const [width10, height10, extra] = normalized.split(":");
|
|
28740
|
-
const numericWidth = Number(width10);
|
|
28741
|
-
const numericHeight = Number(height10);
|
|
28742
|
-
if (extra !== void 0 || !Number.isFinite(numericWidth) || !Number.isFinite(numericHeight) || numericWidth <= 0 || numericHeight <= 0) {
|
|
28743
|
-
throw new Error(`Invalid FlexScreen aspect ratio "${String(value)}"`);
|
|
29426
|
+
return last;
|
|
29427
|
+
}
|
|
29428
|
+
function filterPoints(start, end = start) {
|
|
29429
|
+
const full = end === start;
|
|
29430
|
+
let p = start, again;
|
|
29431
|
+
do {
|
|
29432
|
+
again = false;
|
|
29433
|
+
if (p !== p.next && (steiners.size === 0 || !steiners.has(p)) && (equals(p, p.next) || area(p.prev, p, p.next) === 0)) {
|
|
29434
|
+
if (full || p === end) end = p.prev;
|
|
29435
|
+
filteredOut = true;
|
|
29436
|
+
removeNode(p);
|
|
29437
|
+
p = p.prev;
|
|
29438
|
+
again = true;
|
|
29439
|
+
} else if (full || p !== end) {
|
|
29440
|
+
p = p.next;
|
|
29441
|
+
again = !full;
|
|
29442
|
+
}
|
|
29443
|
+
} while (again || p !== end);
|
|
29444
|
+
return end;
|
|
29445
|
+
}
|
|
29446
|
+
function earcutLinked(ear, triangles, minX, minY, invSize) {
|
|
29447
|
+
if (invSize) indexCurve(ear, minX, minY, invSize);
|
|
29448
|
+
let stop = ear, cured = false;
|
|
29449
|
+
while (ear.prev !== ear.next) {
|
|
29450
|
+
const prev = ear.prev;
|
|
29451
|
+
const next = ear.next;
|
|
29452
|
+
if (area(prev, ear, next) < 0 && (invSize ? isEarHashed(ear, minX, minY, invSize) : isEar(ear))) {
|
|
29453
|
+
triangles.push(prev.i, ear.i, next.i);
|
|
29454
|
+
removeNode(ear);
|
|
29455
|
+
ear = next;
|
|
29456
|
+
stop = next;
|
|
29457
|
+
continue;
|
|
29458
|
+
}
|
|
29459
|
+
ear = next;
|
|
29460
|
+
if (ear === stop) {
|
|
29461
|
+
filteredOut = false;
|
|
29462
|
+
ear = filterPoints(ear);
|
|
29463
|
+
if (filteredOut) {
|
|
29464
|
+
stop = ear;
|
|
29465
|
+
continue;
|
|
29466
|
+
}
|
|
29467
|
+
if (!cured) {
|
|
29468
|
+
ear = cureLocalIntersections(ear, triangles);
|
|
29469
|
+
stop = ear;
|
|
29470
|
+
cured = true;
|
|
29471
|
+
continue;
|
|
29472
|
+
}
|
|
29473
|
+
splitEarcut(ear, triangles, minX, minY, invSize);
|
|
29474
|
+
break;
|
|
28744
29475
|
}
|
|
28745
|
-
return `${numericWidth}:${numericHeight}`;
|
|
28746
|
-
}
|
|
28747
|
-
const numeric = Number(normalized);
|
|
28748
|
-
if (!Number.isFinite(numeric) || numeric <= 0) {
|
|
28749
|
-
throw new Error(`Invalid FlexScreen aspect ratio "${String(value)}"`);
|
|
28750
29476
|
}
|
|
28751
|
-
|
|
28752
|
-
|
|
28753
|
-
|
|
28754
|
-
|
|
28755
|
-
|
|
29477
|
+
}
|
|
29478
|
+
function isEar(ear) {
|
|
29479
|
+
const a = ear.prev, b = ear, c = ear.next, ax = a.x, bx = b.x, cx = c.x, ay = a.y, by = b.y, cy = c.y, x0 = Math.min(ax, bx, cx), y0 = Math.min(ay, by, cy), x1 = Math.max(ax, bx, cx), y1 = Math.max(ay, by, cy);
|
|
29480
|
+
let p = c.next;
|
|
29481
|
+
while (p !== a) {
|
|
29482
|
+
if (p.x >= x0 && p.x <= x1 && p.y >= y0 && p.y <= y1 && !(ax === p.x && ay === p.y) && pointInTriangle(ax, ay, bx, by, cx, cy, p.x, p.y) && area(p.prev, p, p.next) >= 0) return false;
|
|
29483
|
+
p = p.next;
|
|
28756
29484
|
}
|
|
28757
|
-
return
|
|
28758
|
-
}
|
|
28759
|
-
|
|
28760
|
-
|
|
28761
|
-
|
|
29485
|
+
return true;
|
|
29486
|
+
}
|
|
29487
|
+
function isEarHashed(ear, minX, minY, invSize) {
|
|
29488
|
+
const a = ear.prev, b = ear, c = ear.next, ax = a.x, bx = b.x, cx = c.x, ay = a.y, by = b.y, cy = c.y, x0 = Math.min(ax, bx, cx), y0 = Math.min(ay, by, cy), x1 = Math.max(ax, bx, cx), y1 = Math.max(ay, by, cy), minZ = zOrder(x0, y0, minX, minY, invSize), maxZ = zOrder(x1, y1, minX, minY, invSize);
|
|
29489
|
+
let p = ear.prevZ;
|
|
29490
|
+
while (p && p.z >= minZ) {
|
|
29491
|
+
if (p.x >= x0 && p.x <= x1 && p.y >= y0 && p.y <= y1 && p !== c && !(ax === p.x && ay === p.y) && pointInTriangle(ax, ay, bx, by, cx, cy, p.x, p.y) && area(p.prev, p, p.next) >= 0) return false;
|
|
29492
|
+
p = p.prevZ;
|
|
28762
29493
|
}
|
|
28763
|
-
|
|
28764
|
-
|
|
28765
|
-
|
|
28766
|
-
|
|
29494
|
+
let n = ear.nextZ;
|
|
29495
|
+
while (n && n.z <= maxZ) {
|
|
29496
|
+
if (n.x >= x0 && n.x <= x1 && n.y >= y0 && n.y <= y1 && n !== c && !(ax === n.x && ay === n.y) && pointInTriangle(ax, ay, bx, by, cx, cy, n.x, n.y) && area(n.prev, n, n.next) >= 0) return false;
|
|
29497
|
+
n = n.nextZ;
|
|
28767
29498
|
}
|
|
28768
|
-
|
|
28769
|
-
|
|
28770
|
-
|
|
28771
|
-
|
|
28772
|
-
|
|
28773
|
-
|
|
29499
|
+
return true;
|
|
29500
|
+
}
|
|
29501
|
+
function cureLocalIntersections(start, triangles) {
|
|
29502
|
+
let p = start;
|
|
29503
|
+
let cured = false;
|
|
29504
|
+
do {
|
|
29505
|
+
const a = p.prev, b = p.next.next;
|
|
29506
|
+
if (intersects(a, p, p.next, b, false) && locallyInside(a, b) && locallyInside(b, a)) {
|
|
29507
|
+
triangles.push(a.i, p.i, b.i);
|
|
29508
|
+
removeNode(p);
|
|
29509
|
+
removeNode(p.next);
|
|
29510
|
+
p = start = b;
|
|
29511
|
+
cured = true;
|
|
28774
29512
|
}
|
|
28775
|
-
|
|
28776
|
-
|
|
28777
|
-
|
|
28778
|
-
|
|
28779
|
-
|
|
28780
|
-
|
|
28781
|
-
|
|
29513
|
+
p = p.next;
|
|
29514
|
+
} while (p !== start);
|
|
29515
|
+
return cured ? filterPoints(p) : p;
|
|
29516
|
+
}
|
|
29517
|
+
function splitEarcut(start, triangles, minX, minY, invSize) {
|
|
29518
|
+
let a = start;
|
|
29519
|
+
do {
|
|
29520
|
+
let b = a.next.next;
|
|
29521
|
+
while (b !== a.prev) {
|
|
29522
|
+
if (a.i !== b.i && isValidDiagonal(a, b)) {
|
|
29523
|
+
let c = splitPolygon(a, b);
|
|
29524
|
+
a = filterPoints(a, a.next);
|
|
29525
|
+
c = filterPoints(c, c.next);
|
|
29526
|
+
earcutLinked(a, triangles, minX, minY, invSize);
|
|
29527
|
+
earcutLinked(c, triangles, minX, minY, invSize);
|
|
29528
|
+
return;
|
|
28782
29529
|
}
|
|
28783
|
-
|
|
28784
|
-
props.orientation = tokenOrientation;
|
|
28785
|
-
continue;
|
|
28786
|
-
}
|
|
28787
|
-
if (token in booleanTokens) {
|
|
28788
|
-
assertBareToken(value, token);
|
|
28789
|
-
const [property, enabled] = booleanTokens[token];
|
|
28790
|
-
props[property] = enabled;
|
|
28791
|
-
continue;
|
|
28792
|
-
}
|
|
28793
|
-
const colorProperty = colorProperties[token];
|
|
28794
|
-
if (colorProperty) {
|
|
28795
|
-
props[colorProperty] = unwrapFunctionValue(value, token);
|
|
28796
|
-
continue;
|
|
28797
|
-
}
|
|
28798
|
-
if (token === "ratio") {
|
|
28799
|
-
props.aspectRatio = parseAspectRatio(value);
|
|
28800
|
-
continue;
|
|
28801
|
-
}
|
|
28802
|
-
const lengthProperty = lengthTokenToProperty[token];
|
|
28803
|
-
if (lengthProperty) {
|
|
28804
|
-
props[lengthProperty] = value;
|
|
28805
|
-
continue;
|
|
28806
|
-
}
|
|
28807
|
-
if (token === "distance") {
|
|
28808
|
-
relativeDistance = value;
|
|
28809
|
-
continue;
|
|
29530
|
+
b = b.next;
|
|
28810
29531
|
}
|
|
28811
|
-
|
|
28812
|
-
|
|
28813
|
-
|
|
28814
|
-
|
|
28815
|
-
|
|
28816
|
-
|
|
28817
|
-
|
|
29532
|
+
a = a.next;
|
|
29533
|
+
} while (a !== start);
|
|
29534
|
+
}
|
|
29535
|
+
var indexActive = false;
|
|
29536
|
+
function eliminateHoles(data, holeIndices, outerNode, dim) {
|
|
29537
|
+
const queue = [];
|
|
29538
|
+
for (let i = 0, len = holeIndices.length; i < len; i++) {
|
|
29539
|
+
const start = holeIndices[i] * dim;
|
|
29540
|
+
const end = i < len - 1 ? holeIndices[i + 1] * dim : data.length;
|
|
29541
|
+
const list = (
|
|
29542
|
+
/** @type {Node} */
|
|
29543
|
+
linkedList(data, start, end, dim, false)
|
|
29544
|
+
);
|
|
29545
|
+
if (list === list.next) steiners.add(list);
|
|
29546
|
+
queue.push(getLeftmost(list));
|
|
29547
|
+
}
|
|
29548
|
+
queue.sort(compareXYSlope);
|
|
29549
|
+
buildBlockIndex(data.length / dim, holeIndices.length);
|
|
29550
|
+
indexSegment(outerNode, outerNode);
|
|
29551
|
+
indexActive = true;
|
|
29552
|
+
for (let i = 0; i < queue.length; i++) {
|
|
29553
|
+
outerNode = eliminateHole(queue[i], outerNode);
|
|
29554
|
+
}
|
|
29555
|
+
indexActive = false;
|
|
29556
|
+
return filterPoints(outerNode);
|
|
29557
|
+
}
|
|
29558
|
+
function compareXYSlope(a, b) {
|
|
29559
|
+
return a.x - b.x || a.y - b.y || (a.next.y - a.y) / (a.next.x - a.x) - (b.next.y - b.y) / (b.next.x - b.x);
|
|
29560
|
+
}
|
|
29561
|
+
function eliminateHole(hole, outerNode) {
|
|
29562
|
+
const bridge = findHoleBridge(hole, outerNode);
|
|
29563
|
+
if (!bridge) {
|
|
29564
|
+
return outerNode;
|
|
29565
|
+
}
|
|
29566
|
+
const bridgeReverse = splitPolygon(bridge, hole);
|
|
29567
|
+
const bridge2 = bridgeReverse.next;
|
|
29568
|
+
indexSegment(bridge, bridge2.next);
|
|
29569
|
+
filterPoints(bridgeReverse, bridgeReverse.next);
|
|
29570
|
+
return filterPoints(bridge, bridge.next);
|
|
29571
|
+
}
|
|
29572
|
+
var K = 16;
|
|
29573
|
+
var blockBBox = new Float64Array(0);
|
|
29574
|
+
var numBlocks = 0;
|
|
29575
|
+
var blockHead = [];
|
|
29576
|
+
var blockStop = [];
|
|
29577
|
+
function buildBlockIndex(maxNodes, numHoles) {
|
|
29578
|
+
const maxBlocks = Math.ceil((maxNodes + 2 * numHoles) / K) + numHoles + 2;
|
|
29579
|
+
if (blockBBox.length < maxBlocks * 4) blockBBox = new Float64Array(maxBlocks * 4);
|
|
29580
|
+
numBlocks = 0;
|
|
29581
|
+
}
|
|
29582
|
+
function indexSegment(head, stop) {
|
|
29583
|
+
let p = head;
|
|
29584
|
+
do {
|
|
29585
|
+
const b = numBlocks++;
|
|
29586
|
+
blockHead[b] = p;
|
|
29587
|
+
let minX = p.x, minY = p.y, maxX = p.x, maxY = p.y;
|
|
29588
|
+
let k = 0;
|
|
29589
|
+
do {
|
|
29590
|
+
const c = p.next;
|
|
29591
|
+
p.z = b;
|
|
29592
|
+
if (c.x < minX) minX = c.x;
|
|
29593
|
+
if (c.x > maxX) maxX = c.x;
|
|
29594
|
+
if (c.y < minY) minY = c.y;
|
|
29595
|
+
if (c.y > maxY) maxY = c.y;
|
|
29596
|
+
p = c;
|
|
29597
|
+
} while (++k < K && p !== stop);
|
|
29598
|
+
blockStop[b] = p;
|
|
29599
|
+
const g = b * 4;
|
|
29600
|
+
blockBBox[g] = minX;
|
|
29601
|
+
blockBBox[g + 1] = minY;
|
|
29602
|
+
blockBBox[g + 2] = maxX;
|
|
29603
|
+
blockBBox[g + 3] = maxY;
|
|
29604
|
+
} while (p !== stop);
|
|
29605
|
+
}
|
|
29606
|
+
function growBlock(head, tail) {
|
|
29607
|
+
const g = head.z * 4;
|
|
29608
|
+
if (tail.x < blockBBox[g]) blockBBox[g] = tail.x;
|
|
29609
|
+
if (tail.y < blockBBox[g + 1]) blockBBox[g + 1] = tail.y;
|
|
29610
|
+
if (tail.x > blockBBox[g + 2]) blockBBox[g + 2] = tail.x;
|
|
29611
|
+
if (tail.y > blockBBox[g + 3]) blockBBox[g + 3] = tail.y;
|
|
29612
|
+
}
|
|
29613
|
+
function liveBlockStop(b) {
|
|
29614
|
+
let stop = blockStop[b];
|
|
29615
|
+
while (stop.prev.next !== stop) stop = stop.next;
|
|
29616
|
+
blockStop[b] = stop;
|
|
29617
|
+
return stop;
|
|
29618
|
+
}
|
|
29619
|
+
function liveBlockHead(b) {
|
|
29620
|
+
let head = blockHead[b];
|
|
29621
|
+
while (head.prev.next !== head) head = head.next;
|
|
29622
|
+
blockHead[b] = head;
|
|
29623
|
+
return head;
|
|
29624
|
+
}
|
|
29625
|
+
function findHoleBridge(hole, outerNode) {
|
|
29626
|
+
let p = outerNode;
|
|
29627
|
+
const hx = hole.x;
|
|
29628
|
+
const hy = hole.y;
|
|
29629
|
+
let qx = -Infinity;
|
|
29630
|
+
let m;
|
|
29631
|
+
if (equals(hole, p)) return p;
|
|
29632
|
+
for (let b = 0, g = 0; b < numBlocks; b++, g += 4) {
|
|
29633
|
+
if (hy < blockBBox[g + 1] || hy > blockBBox[g + 3] || blockBBox[g] > hx || blockBBox[g + 2] <= qx) continue;
|
|
29634
|
+
const stop = liveBlockStop(b);
|
|
29635
|
+
p = liveBlockHead(b);
|
|
29636
|
+
do {
|
|
29637
|
+
if (p.prev.next === p) {
|
|
29638
|
+
if (equals(hole, p.next)) return p.next;
|
|
29639
|
+
else if (hy <= p.y && hy >= p.next.y && p.next.y !== p.y) {
|
|
29640
|
+
const x = p.x + (hy - p.y) * (p.next.x - p.x) / (p.next.y - p.y);
|
|
29641
|
+
if (x <= hx && x > qx) {
|
|
29642
|
+
qx = x;
|
|
29643
|
+
m = p.x < p.next.x ? p : p.next;
|
|
29644
|
+
if (x === hx) return m;
|
|
29645
|
+
}
|
|
29646
|
+
}
|
|
28818
29647
|
}
|
|
28819
|
-
|
|
29648
|
+
p = p.next;
|
|
29649
|
+
} while (p !== stop);
|
|
29650
|
+
}
|
|
29651
|
+
if (!m) return null;
|
|
29652
|
+
const mx = m.x;
|
|
29653
|
+
const my = m.y;
|
|
29654
|
+
const tminY = Math.min(hy, my);
|
|
29655
|
+
const tmaxY = Math.max(hy, my);
|
|
29656
|
+
let tanMin = Infinity;
|
|
29657
|
+
for (let b = 0, g = 0; b < numBlocks; b++, g += 4) {
|
|
29658
|
+
if (blockBBox[g + 2] < mx || blockBBox[g] > hx || blockBBox[g + 3] < tminY || blockBBox[g + 1] > tmaxY) continue;
|
|
29659
|
+
const stop = liveBlockStop(b);
|
|
29660
|
+
p = liveBlockHead(b);
|
|
29661
|
+
do {
|
|
29662
|
+
if (p.prev.next === p && hx >= p.x && p.x >= mx && hx !== p.x && // skip dead nodes
|
|
29663
|
+
pointInTriangle(hy < my ? hx : qx, hy, mx, my, hy < my ? qx : hx, hy, p.x, p.y)) {
|
|
29664
|
+
const tan = Math.abs(hy - p.y) / (hx - p.x);
|
|
29665
|
+
if ((locallyInside(p, hole) || p.y === hy && p.next.y === hy && p.next.x > hx) && (tan < tanMin || tan === tanMin && (p.x > m.x || p.x === m.x && sectorContainsSector(m, p)))) {
|
|
29666
|
+
m = p;
|
|
29667
|
+
tanMin = tan;
|
|
29668
|
+
}
|
|
29669
|
+
}
|
|
29670
|
+
p = p.next;
|
|
29671
|
+
} while (p !== stop);
|
|
29672
|
+
}
|
|
29673
|
+
return m;
|
|
29674
|
+
}
|
|
29675
|
+
function sectorContainsSector(m, p) {
|
|
29676
|
+
return area(m.prev, m, p.prev) < 0 && area(p.next, m, m.next) < 0;
|
|
29677
|
+
}
|
|
29678
|
+
var sortArr = [];
|
|
29679
|
+
var sortBuf = [];
|
|
29680
|
+
var zArr = new Uint32Array(0);
|
|
29681
|
+
var zBuf = new Uint32Array(0);
|
|
29682
|
+
var counts = new Uint32Array(256);
|
|
29683
|
+
function indexCurve(start, minX, minY, invSize) {
|
|
29684
|
+
let p = start;
|
|
29685
|
+
let n = 0;
|
|
29686
|
+
do {
|
|
29687
|
+
p.z = zOrder(p.x, p.y, minX, minY, invSize);
|
|
29688
|
+
sortArr[n++] = p;
|
|
29689
|
+
p = p.next;
|
|
29690
|
+
} while (p !== start);
|
|
29691
|
+
sortNodes(n);
|
|
29692
|
+
let prev = null;
|
|
29693
|
+
for (let i = 0; i < n; i++) {
|
|
29694
|
+
const node = sortArr[i];
|
|
29695
|
+
node.prevZ = prev;
|
|
29696
|
+
if (prev) prev.nextZ = node;
|
|
29697
|
+
prev = node;
|
|
29698
|
+
}
|
|
29699
|
+
prev.nextZ = null;
|
|
29700
|
+
sortArr.fill(
|
|
29701
|
+
/** @type {Node} */
|
|
29702
|
+
/** @type {unknown} */
|
|
29703
|
+
null,
|
|
29704
|
+
0,
|
|
29705
|
+
n
|
|
29706
|
+
);
|
|
29707
|
+
sortBuf.fill(
|
|
29708
|
+
/** @type {Node} */
|
|
29709
|
+
/** @type {unknown} */
|
|
29710
|
+
null,
|
|
29711
|
+
0,
|
|
29712
|
+
n
|
|
29713
|
+
);
|
|
29714
|
+
}
|
|
29715
|
+
function sortNodes(n) {
|
|
29716
|
+
if (n <= 32) {
|
|
29717
|
+
for (let i = 1; i < n; i++) {
|
|
29718
|
+
const node = sortArr[i], z27 = node.z;
|
|
29719
|
+
let j = i - 1;
|
|
29720
|
+
while (j >= 0 && sortArr[j].z > z27) {
|
|
29721
|
+
sortArr[j + 1] = sortArr[j];
|
|
29722
|
+
j--;
|
|
29723
|
+
}
|
|
29724
|
+
sortArr[j + 1] = node;
|
|
29725
|
+
}
|
|
29726
|
+
return;
|
|
29727
|
+
}
|
|
29728
|
+
if (zArr.length < n) {
|
|
29729
|
+
zArr = new Uint32Array(n);
|
|
29730
|
+
zBuf = new Uint32Array(n);
|
|
29731
|
+
sortBuf = new Array(n);
|
|
29732
|
+
}
|
|
29733
|
+
for (let i = 0; i < n; i++) zArr[i] = sortArr[i].z;
|
|
29734
|
+
radixPass(n, sortArr, zArr, sortBuf, zBuf, 0);
|
|
29735
|
+
radixPass(n, sortBuf, zBuf, sortArr, zArr, 8);
|
|
29736
|
+
radixPass(n, sortArr, zArr, sortBuf, zBuf, 16);
|
|
29737
|
+
radixPass(n, sortBuf, zBuf, sortArr, zArr, 24);
|
|
29738
|
+
}
|
|
29739
|
+
function radixPass(n, src, srcZ, dst, dstZ, shift4) {
|
|
29740
|
+
counts.fill(0);
|
|
29741
|
+
for (let i = 0; i < n; i++) counts[srcZ[i] >>> shift4 & 255]++;
|
|
29742
|
+
let sum = 0;
|
|
29743
|
+
for (let b = 0; b < 256; b++) {
|
|
29744
|
+
const c = counts[b];
|
|
29745
|
+
counts[b] = sum;
|
|
29746
|
+
sum += c;
|
|
29747
|
+
}
|
|
29748
|
+
for (let i = 0; i < n; i++) {
|
|
29749
|
+
const z27 = srcZ[i];
|
|
29750
|
+
const pos = counts[z27 >>> shift4 & 255]++;
|
|
29751
|
+
dst[pos] = src[i];
|
|
29752
|
+
dstZ[pos] = z27;
|
|
29753
|
+
}
|
|
29754
|
+
}
|
|
29755
|
+
function zOrder(x, y, minX, minY, invSize) {
|
|
29756
|
+
x = (x - minX) * invSize | 0;
|
|
29757
|
+
y = (y - minY) * invSize | 0;
|
|
29758
|
+
x = (x | x << 8) & 16711935;
|
|
29759
|
+
x = (x | x << 4) & 252645135;
|
|
29760
|
+
x = (x | x << 2) & 858993459;
|
|
29761
|
+
x = (x | x << 1) & 1431655765;
|
|
29762
|
+
y = (y | y << 8) & 16711935;
|
|
29763
|
+
y = (y | y << 4) & 252645135;
|
|
29764
|
+
y = (y | y << 2) & 858993459;
|
|
29765
|
+
y = (y | y << 1) & 1431655765;
|
|
29766
|
+
return x | y << 1;
|
|
29767
|
+
}
|
|
29768
|
+
function getLeftmost(start) {
|
|
29769
|
+
let p = start, leftmost = start;
|
|
29770
|
+
do {
|
|
29771
|
+
if (p.x < leftmost.x || p.x === leftmost.x && p.y < leftmost.y) leftmost = p;
|
|
29772
|
+
p = p.next;
|
|
29773
|
+
} while (p !== start);
|
|
29774
|
+
return leftmost;
|
|
29775
|
+
}
|
|
29776
|
+
function pointInTriangle(ax, ay, bx, by, cx, cy, px, py) {
|
|
29777
|
+
return (cx - px) * (ay - py) >= (ax - px) * (cy - py) && (ax - px) * (by - py) >= (bx - px) * (ay - py) && (bx - px) * (cy - py) >= (cx - px) * (by - py);
|
|
29778
|
+
}
|
|
29779
|
+
function isValidDiagonal(a, b) {
|
|
29780
|
+
const zeroLength = equals(a, b) && area(a.prev, a, a.next) > 0 && area(b.prev, b, b.next) > 0;
|
|
29781
|
+
return a.next.i !== b.i && (zeroLength || locallyInside(a, b) && locallyInside(b, a) && // // locally visible
|
|
29782
|
+
(area(a.prev, a, b.prev) !== 0 || area(a, b.prev, b) !== 0)) && // no opposite-facing sectors
|
|
29783
|
+
!intersectsPolygon(a, b) && (zeroLength || middleInside(a, b));
|
|
29784
|
+
}
|
|
29785
|
+
function area(p, q, r) {
|
|
29786
|
+
return (q.y - p.y) * (r.x - q.x) - (q.x - p.x) * (r.y - q.y);
|
|
29787
|
+
}
|
|
29788
|
+
function equals(p1, p2) {
|
|
29789
|
+
return p1.x === p2.x && p1.y === p2.y;
|
|
29790
|
+
}
|
|
29791
|
+
function intersects(p1, q1, p2, q2, includeBoundary = true) {
|
|
29792
|
+
const o1 = area(p1, q1, p2);
|
|
29793
|
+
const o2 = area(p1, q1, q2);
|
|
29794
|
+
const o3 = area(p2, q2, p1);
|
|
29795
|
+
const o4 = area(p2, q2, q1);
|
|
29796
|
+
if ((o1 > 0 && o2 < 0 || o1 < 0 && o2 > 0) && (o3 > 0 && o4 < 0 || o3 < 0 && o4 > 0)) return true;
|
|
29797
|
+
if (!includeBoundary) return false;
|
|
29798
|
+
if (o1 === 0 && onSegment(p1, p2, q1)) return true;
|
|
29799
|
+
if (o2 === 0 && onSegment(p1, q2, q1)) return true;
|
|
29800
|
+
if (o3 === 0 && onSegment(p2, p1, q2)) return true;
|
|
29801
|
+
if (o4 === 0 && onSegment(p2, q1, q2)) return true;
|
|
29802
|
+
return false;
|
|
29803
|
+
}
|
|
29804
|
+
function onSegment(p, q, r) {
|
|
29805
|
+
return q.x <= Math.max(p.x, r.x) && q.x >= Math.min(p.x, r.x) && q.y <= Math.max(p.y, r.y) && q.y >= Math.min(p.y, r.y);
|
|
29806
|
+
}
|
|
29807
|
+
function intersectsPolygon(a, b) {
|
|
29808
|
+
const minX = Math.min(a.x, b.x);
|
|
29809
|
+
const maxX = Math.max(a.x, b.x);
|
|
29810
|
+
const minY = Math.min(a.y, b.y);
|
|
29811
|
+
const maxY = Math.max(a.y, b.y);
|
|
29812
|
+
let p = a;
|
|
29813
|
+
do {
|
|
29814
|
+
const n = p.next;
|
|
29815
|
+
if (p.x > maxX && n.x > maxX || p.x < minX && n.x < minX || p.y > maxY && n.y > maxY || p.y < minY && n.y < minY) {
|
|
29816
|
+
p = n;
|
|
28820
29817
|
continue;
|
|
28821
29818
|
}
|
|
28822
|
-
|
|
29819
|
+
if (p.i !== a.i && n.i !== a.i && p.i !== b.i && n.i !== b.i && intersects(p, n, a, b)) return true;
|
|
29820
|
+
p = n;
|
|
29821
|
+
} while (p !== a);
|
|
29822
|
+
return false;
|
|
29823
|
+
}
|
|
29824
|
+
function locallyInside(a, b) {
|
|
29825
|
+
return area(a.prev, a, a.next) < 0 ? area(a, b, a.next) >= 0 && area(a, a.prev, b) >= 0 : area(a, b, a.prev) < 0 || area(a, a.next, b) < 0;
|
|
29826
|
+
}
|
|
29827
|
+
function middleInside(a, b) {
|
|
29828
|
+
let p = a;
|
|
29829
|
+
let inside = false;
|
|
29830
|
+
const px = (a.x + b.x) / 2;
|
|
29831
|
+
const py = (a.y + b.y) / 2;
|
|
29832
|
+
do {
|
|
29833
|
+
const n = p.next;
|
|
29834
|
+
if (p.y > py !== n.y > py && px < (n.x - p.x) * (py - p.y) / (n.y - p.y) + p.x)
|
|
29835
|
+
inside = !inside;
|
|
29836
|
+
p = n;
|
|
29837
|
+
} while (p !== a);
|
|
29838
|
+
return inside;
|
|
29839
|
+
}
|
|
29840
|
+
function splitPolygon(a, b) {
|
|
29841
|
+
const a2 = createNode(a.i, a.x, a.y), b2 = createNode(b.i, b.x, b.y), an = a.next, bp = b.prev;
|
|
29842
|
+
a.next = b;
|
|
29843
|
+
b.prev = a;
|
|
29844
|
+
a2.next = an;
|
|
29845
|
+
an.prev = a2;
|
|
29846
|
+
b2.next = a2;
|
|
29847
|
+
a2.prev = b2;
|
|
29848
|
+
bp.next = b2;
|
|
29849
|
+
b2.prev = bp;
|
|
29850
|
+
return b2;
|
|
29851
|
+
}
|
|
29852
|
+
function insertNode(i, x, y, last) {
|
|
29853
|
+
const p = createNode(i, x, y);
|
|
29854
|
+
if (!last) {
|
|
29855
|
+
p.prev = p;
|
|
29856
|
+
p.next = p;
|
|
29857
|
+
} else {
|
|
29858
|
+
p.next = last.next;
|
|
29859
|
+
p.prev = last;
|
|
29860
|
+
last.next.prev = p;
|
|
29861
|
+
last.next = p;
|
|
28823
29862
|
}
|
|
28824
|
-
|
|
28825
|
-
|
|
28826
|
-
|
|
28827
|
-
|
|
28828
|
-
|
|
28829
|
-
|
|
28830
|
-
|
|
28831
|
-
|
|
28832
|
-
|
|
29863
|
+
return p;
|
|
29864
|
+
}
|
|
29865
|
+
function removeNode(p) {
|
|
29866
|
+
p.next.prev = p.prev;
|
|
29867
|
+
p.prev.next = p.next;
|
|
29868
|
+
if (p.prevZ) p.prevZ.nextZ = p.nextZ;
|
|
29869
|
+
if (p.nextZ) p.nextZ.prevZ = p.prevZ;
|
|
29870
|
+
if (indexActive) growBlock(p.prev, p.next);
|
|
29871
|
+
}
|
|
29872
|
+
function createNode(i, x, y) {
|
|
29873
|
+
return (
|
|
29874
|
+
/** @type {Node} */
|
|
29875
|
+
/** @type {unknown} */
|
|
29876
|
+
{
|
|
29877
|
+
i,
|
|
29878
|
+
// vertex index in coordinates array
|
|
29879
|
+
x,
|
|
29880
|
+
y,
|
|
29881
|
+
// vertex coordinates
|
|
29882
|
+
prev: null,
|
|
29883
|
+
// previous and next vertex nodes in a polygon ring
|
|
29884
|
+
next: null,
|
|
29885
|
+
z: 0,
|
|
29886
|
+
// z-order curve value; doubles as owning block in the hole-bridge index during eliminateHoles
|
|
29887
|
+
prevZ: null,
|
|
29888
|
+
// previous and next nodes in z-order
|
|
29889
|
+
nextZ: null
|
|
28833
29890
|
}
|
|
29891
|
+
);
|
|
29892
|
+
}
|
|
29893
|
+
function signedArea(data, start, end, dim) {
|
|
29894
|
+
let sum = 0;
|
|
29895
|
+
for (let i = start, j = end - dim; i < end; i += dim) {
|
|
29896
|
+
sum += (data[j] - data[i]) * (data[i + 1] + data[j + 1]);
|
|
29897
|
+
j = i;
|
|
28834
29898
|
}
|
|
28835
|
-
return
|
|
28836
|
-
}
|
|
28837
|
-
|
|
28838
|
-
|
|
29899
|
+
return sum;
|
|
29900
|
+
}
|
|
29901
|
+
|
|
29902
|
+
// node_modules/jscad-electronics/dist/vanilla.js
|
|
29903
|
+
var import_modeling2 = __toESM(require_src(), 1);
|
|
29904
|
+
|
|
29905
|
+
// node_modules/jscad-electronics/node_modules/@tscircuit/mm/dist/index.js
|
|
29906
|
+
var unitToMm3 = {
|
|
29907
|
+
in: 25.4,
|
|
29908
|
+
inch: 25.4,
|
|
29909
|
+
mil: 0.0254,
|
|
29910
|
+
mm: 1,
|
|
29911
|
+
m: 1e3,
|
|
29912
|
+
cm: 10,
|
|
29913
|
+
ft: 304.8,
|
|
29914
|
+
feet: 304.8
|
|
28839
29915
|
};
|
|
28840
|
-
var
|
|
28841
|
-
|
|
28842
|
-
if (
|
|
28843
|
-
|
|
29916
|
+
var mm3 = (n) => {
|
|
29917
|
+
let unit = typeof n === "number" ? "mm" : n.replace(/^[^a-zA-Z]+/g, "").toLowerCase();
|
|
29918
|
+
if (!unit)
|
|
29919
|
+
unit = "mm";
|
|
29920
|
+
const val = typeof n === "number" ? n : Number.parseFloat(n.split(unit)[0]);
|
|
29921
|
+
if (unit in unitToMm3) {
|
|
29922
|
+
return val * unitToMm3[unit];
|
|
28844
29923
|
}
|
|
28845
|
-
throw new Error(`Unsupported
|
|
28846
|
-
};
|
|
28847
|
-
var string = (value) => {
|
|
28848
|
-
const params = parseModelStringParams(value);
|
|
28849
|
-
return {
|
|
28850
|
-
params: () => params,
|
|
28851
|
-
json: () => modelParamsToJson(params)
|
|
28852
|
-
};
|
|
28853
|
-
};
|
|
28854
|
-
var modelprinter = {
|
|
28855
|
-
string,
|
|
28856
|
-
getModelNames: () => Object.keys(modelFunctions)
|
|
29924
|
+
throw new Error(`Unsupported unit: ${unit}`);
|
|
28857
29925
|
};
|
|
28858
|
-
var mp = modelprinter;
|
|
28859
29926
|
|
|
28860
29927
|
// node_modules/jscad-electronics/dist/vanilla.js
|
|
28861
29928
|
import {
|
|
@@ -28895,6 +29962,7 @@ var Colorize = /* @__PURE__ */ Symbol("Colorize");
|
|
|
28895
29962
|
var Polygon = /* @__PURE__ */ Symbol("Polygon");
|
|
28896
29963
|
var ExtrudeLinear = /* @__PURE__ */ Symbol("ExtrudeLinear");
|
|
28897
29964
|
var RoundedCylinder = /* @__PURE__ */ Symbol("RoundedCylinder");
|
|
29965
|
+
var Custom = /* @__PURE__ */ Symbol("Custom");
|
|
28898
29966
|
var Fragment2 = Fragment;
|
|
28899
29967
|
var jsx3 = (type, props, _key) => h(type, props);
|
|
28900
29968
|
var jsxs = (type, props, _key) => h(type, props);
|
|
@@ -28985,6 +30053,363 @@ var FootprintPlatedHole = ({
|
|
|
28985
30053
|
}
|
|
28986
30054
|
throw new Error("Shape not supported: " + hole.shape);
|
|
28987
30055
|
};
|
|
30056
|
+
var createHexSocketBoltMesh = (input) => {
|
|
30057
|
+
const props = hexSocketBoltModelPropsSchema.parse(input);
|
|
30058
|
+
const {
|
|
30059
|
+
diameter,
|
|
30060
|
+
threadPitch: pitch,
|
|
30061
|
+
headDiameter,
|
|
30062
|
+
headHeight,
|
|
30063
|
+
socketWidth,
|
|
30064
|
+
socketDepth
|
|
30065
|
+
} = hexSocketBoltDimensions[props.metricSize];
|
|
30066
|
+
const { length: length83, showThreads } = props;
|
|
30067
|
+
const segments = 96;
|
|
30068
|
+
const steps = Math.max(2, Math.ceil(length83 / pitch * 24));
|
|
30069
|
+
if (steps > 24e3)
|
|
30070
|
+
throw new Error(
|
|
30071
|
+
"Bolt length exceeds mesh resolution limit (1000 thread turns)"
|
|
30072
|
+
);
|
|
30073
|
+
const positions = [];
|
|
30074
|
+
const indices = [];
|
|
30075
|
+
const radius = diameter / 2;
|
|
30076
|
+
const depth = pitch * 0.61343;
|
|
30077
|
+
const bevel = Math.min(0.2, headHeight * 0.08);
|
|
30078
|
+
const tipBevel = Math.min(pitch * 0.6, length83 / 3);
|
|
30079
|
+
const ring = (z27, radiusAt) => {
|
|
30080
|
+
const start = positions.length / 3;
|
|
30081
|
+
for (let i = 0; i < segments; i++) {
|
|
30082
|
+
const angle = i * Math.PI * 2 / segments;
|
|
30083
|
+
const r = radiusAt(angle);
|
|
30084
|
+
positions.push(r * Math.cos(angle), r * Math.sin(angle), z27);
|
|
30085
|
+
}
|
|
30086
|
+
return start;
|
|
30087
|
+
};
|
|
30088
|
+
const connect = (a, b) => {
|
|
30089
|
+
for (let i = 0; i < segments; i++) {
|
|
30090
|
+
const next = (i + 1) % segments;
|
|
30091
|
+
indices.push(a + i, a + next, b + next, a + i, b + next, b + i);
|
|
30092
|
+
}
|
|
30093
|
+
};
|
|
30094
|
+
const cap2 = (start, z27, upward) => {
|
|
30095
|
+
const center = positions.length / 3;
|
|
30096
|
+
positions.push(0, 0, z27);
|
|
30097
|
+
for (let i = 0; i < segments; i++) {
|
|
30098
|
+
const a = start + i;
|
|
30099
|
+
const b = start + (i + 1) % segments;
|
|
30100
|
+
indices.push(center, upward ? a : b, upward ? b : a);
|
|
30101
|
+
}
|
|
30102
|
+
};
|
|
30103
|
+
let previous = -1;
|
|
30104
|
+
for (let step = 0; step <= steps; step++) {
|
|
30105
|
+
const z27 = -length83 + length83 * step / steps;
|
|
30106
|
+
const current = ring(z27, (angle) => {
|
|
30107
|
+
const phase = ((z27 / pitch - angle / (2 * Math.PI)) % 1 + 1) % 1;
|
|
30108
|
+
const distance22 = Math.min(phase, 1 - phase);
|
|
30109
|
+
const groove = Math.min(
|
|
30110
|
+
depth,
|
|
30111
|
+
Math.max(0, (distance22 - 1 / 16) * pitch * Math.sqrt(3))
|
|
30112
|
+
);
|
|
30113
|
+
const endRamp = Math.min(
|
|
30114
|
+
1,
|
|
30115
|
+
(z27 + length83) / tipBevel,
|
|
30116
|
+
-z27 / Math.min(pitch / 2, length83 / 3)
|
|
30117
|
+
);
|
|
30118
|
+
const tipCut = tipBevel * Math.max(0, 1 - (z27 + length83) / tipBevel);
|
|
30119
|
+
return radius - (showThreads ? groove * endRamp : 0) - tipCut;
|
|
30120
|
+
});
|
|
30121
|
+
if (previous < 0) cap2(current, z27, false);
|
|
30122
|
+
else connect(previous, current);
|
|
30123
|
+
previous = current;
|
|
30124
|
+
}
|
|
30125
|
+
const addRing = (z27, radiusAt) => {
|
|
30126
|
+
const current = ring(z27, radiusAt);
|
|
30127
|
+
connect(previous, current);
|
|
30128
|
+
previous = current;
|
|
30129
|
+
};
|
|
30130
|
+
addRing(0, () => headDiameter / 2 - bevel);
|
|
30131
|
+
addRing(bevel, () => headDiameter / 2);
|
|
30132
|
+
addRing(headHeight - bevel, () => headDiameter / 2);
|
|
30133
|
+
addRing(headHeight, () => headDiameter / 2 - bevel);
|
|
30134
|
+
const hexRadius = (angle, acrossFlats) => acrossFlats / 2 / Math.cos((angle + Math.PI / 6) % (Math.PI / 3) - Math.PI / 6);
|
|
30135
|
+
addRing(headHeight, (angle) => hexRadius(angle, socketWidth + bevel));
|
|
30136
|
+
addRing(headHeight - bevel / 2, (angle) => hexRadius(angle, socketWidth));
|
|
30137
|
+
addRing(headHeight - socketDepth, (angle) => hexRadius(angle, socketWidth));
|
|
30138
|
+
cap2(previous, headHeight - socketDepth, true);
|
|
30139
|
+
return { positions, indices };
|
|
30140
|
+
};
|
|
30141
|
+
function indexedMeshToGeom3(mesh) {
|
|
30142
|
+
const polygons = [];
|
|
30143
|
+
for (let i = 0; i < mesh.indices.length; i += 3)
|
|
30144
|
+
polygons.push(
|
|
30145
|
+
mesh.indices.slice(i, i + 3).map((index2) => [
|
|
30146
|
+
mesh.positions[index2 * 3],
|
|
30147
|
+
mesh.positions[index2 * 3 + 1],
|
|
30148
|
+
mesh.positions[index2 * 3 + 2]
|
|
30149
|
+
])
|
|
30150
|
+
);
|
|
30151
|
+
return import_modeling.default.geometries.geom3.fromPoints(polygons);
|
|
30152
|
+
}
|
|
30153
|
+
function createHexSocketBoltGeom(input) {
|
|
30154
|
+
return indexedMeshToGeom3(createHexSocketBoltMesh(input));
|
|
30155
|
+
}
|
|
30156
|
+
function HexSocketBolt({
|
|
30157
|
+
color = "#737e8f",
|
|
30158
|
+
...props
|
|
30159
|
+
}) {
|
|
30160
|
+
return /* @__PURE__ */ jsx3(Colorize, { color, children: /* @__PURE__ */ jsx3(Custom, { geometry: createHexSocketBoltGeom(props) }) });
|
|
30161
|
+
}
|
|
30162
|
+
function holeOutline(hole) {
|
|
30163
|
+
const radius = (hole.shape === "round" ? hole.diameter : hole.width) / 2;
|
|
30164
|
+
const straight = hole.shape === "slot" ? (hole.length - hole.width) / 2 : 0;
|
|
30165
|
+
if (straight < 0) throw new Error("Slot length must be at least its width");
|
|
30166
|
+
return Array.from({ length: 64 }, (_, i) => {
|
|
30167
|
+
if (hole.shape === "round") {
|
|
30168
|
+
const angle2 = i * Math.PI / 32;
|
|
30169
|
+
return {
|
|
30170
|
+
u: hole.u + radius * Math.cos(angle2),
|
|
30171
|
+
v: hole.v + radius * Math.sin(angle2)
|
|
30172
|
+
};
|
|
30173
|
+
}
|
|
30174
|
+
const half = i < 32 ? 1 : -1;
|
|
30175
|
+
const angle = -Math.PI / 2 + (i < 32 ? i : i - 32) * Math.PI / 31 + (i < 32 ? 0 : Math.PI);
|
|
30176
|
+
const along = half * straight + radius * Math.cos(angle);
|
|
30177
|
+
const across = radius * Math.sin(angle);
|
|
30178
|
+
return hole.shape === "slot" && hole.axis === "v" ? { u: hole.u - across, v: hole.v + along } : { u: hole.u + along, v: hole.v + across };
|
|
30179
|
+
});
|
|
30180
|
+
}
|
|
30181
|
+
function createSheetMetalMesh(input) {
|
|
30182
|
+
const props = sheetMetalModelPropsSchema.parse(input);
|
|
30183
|
+
const { width: width10, baseLength, flangeHeight, thickness, profile } = props;
|
|
30184
|
+
const radius = props.insideBendRadius + thickness / 2;
|
|
30185
|
+
const positions = [];
|
|
30186
|
+
const indices = [];
|
|
30187
|
+
const addTriangle = (vertices, reverse = false) => {
|
|
30188
|
+
const start = positions.length / 3;
|
|
30189
|
+
for (const vertex of vertices) positions.push(...vertex);
|
|
30190
|
+
indices.push(start, start + (reverse ? 2 : 1), start + (reverse ? 1 : 2));
|
|
30191
|
+
};
|
|
30192
|
+
const addQuad = (vertices, reverse = false) => {
|
|
30193
|
+
addTriangle([vertices[0], vertices[1], vertices[2]], reverse);
|
|
30194
|
+
addTriangle([vertices[0], vertices[2], vertices[3]], reverse);
|
|
30195
|
+
};
|
|
30196
|
+
const panels = profile === "plate" ? ["base"] : profile === "angle" ? ["base", "right"] : ["base", "left", "right"];
|
|
30197
|
+
for (const hole of props.holes) {
|
|
30198
|
+
if (!panels.includes(hole.panel))
|
|
30199
|
+
throw new Error(`No ${hole.panel} panel on ${profile}`);
|
|
30200
|
+
}
|
|
30201
|
+
for (const panel of panels) {
|
|
30202
|
+
const length83 = panel === "base" ? baseLength : flangeHeight;
|
|
30203
|
+
const holes = props.holes.filter((hole) => hole.panel === panel).map(holeOutline);
|
|
30204
|
+
const bounds = holes.map((outline2) => ({
|
|
30205
|
+
minU: Math.min(...outline2.map((p) => p.u)),
|
|
30206
|
+
maxU: Math.max(...outline2.map((p) => p.u)),
|
|
30207
|
+
minV: Math.min(...outline2.map((p) => p.v)),
|
|
30208
|
+
maxV: Math.max(...outline2.map((p) => p.v))
|
|
30209
|
+
}));
|
|
30210
|
+
for (const [i, box] of bounds.entries()) {
|
|
30211
|
+
if (box.minU <= -length83 / 2 || box.maxU >= length83 / 2 || box.minV <= -width10 / 2 || box.maxV >= width10 / 2)
|
|
30212
|
+
throw new Error(`Hole crosses ${panel} panel edge or bend tangent`);
|
|
30213
|
+
for (const previous of bounds.slice(0, i))
|
|
30214
|
+
if (box.minU <= previous.maxU && box.maxU >= previous.minU && box.minV <= previous.maxV && box.maxV >= previous.minV)
|
|
30215
|
+
throw new Error("Hole bounding boxes must not overlap");
|
|
30216
|
+
}
|
|
30217
|
+
const outline = [
|
|
30218
|
+
{ u: -length83 / 2, v: -width10 / 2 },
|
|
30219
|
+
{ u: length83 / 2, v: -width10 / 2 },
|
|
30220
|
+
{ u: length83 / 2, v: width10 / 2 },
|
|
30221
|
+
{ u: -length83 / 2, v: width10 / 2 }
|
|
30222
|
+
];
|
|
30223
|
+
const loops = [outline, ...holes.map((hole) => [...hole].reverse())];
|
|
30224
|
+
const points = loops.flat();
|
|
30225
|
+
const starts = holes.map((_, i) => 4 + i * 64);
|
|
30226
|
+
const triangles = earcut(
|
|
30227
|
+
points.flatMap((p) => [p.u, p.v]),
|
|
30228
|
+
starts
|
|
30229
|
+
);
|
|
30230
|
+
const project = (point, offset4) => panel === "base" ? [point.u, point.v, offset4] : [
|
|
30231
|
+
(panel === "left" ? -1 : 1) * (baseLength / 2 + radius - offset4),
|
|
30232
|
+
point.v,
|
|
30233
|
+
radius + flangeHeight / 2 + point.u
|
|
30234
|
+
];
|
|
30235
|
+
const reverse = panel === "left";
|
|
30236
|
+
for (let i = 0; i < triangles.length; i += 3) {
|
|
30237
|
+
const face2 = triangles.slice(i, i + 3).map((index2) => points[index2]);
|
|
30238
|
+
addTriangle(
|
|
30239
|
+
face2.map((p) => project(p, thickness / 2)),
|
|
30240
|
+
reverse
|
|
30241
|
+
);
|
|
30242
|
+
addTriangle(
|
|
30243
|
+
face2.map((p) => project(p, -thickness / 2)),
|
|
30244
|
+
!reverse
|
|
30245
|
+
);
|
|
30246
|
+
}
|
|
30247
|
+
for (const [loopIndex, loop] of loops.entries())
|
|
30248
|
+
for (let i = 0; i < loop.length; i++) {
|
|
30249
|
+
const a = loop[i], b = loop[(i + 1) % loop.length];
|
|
30250
|
+
if (loopIndex === 0 && a.u === b.u && (panel === "base" && (a.u > 0 && profile !== "plate" || a.u < 0 && profile === "channel") || panel !== "base" && a.u < 0))
|
|
30251
|
+
continue;
|
|
30252
|
+
addQuad(
|
|
30253
|
+
[
|
|
30254
|
+
project(a, -thickness / 2),
|
|
30255
|
+
project(b, -thickness / 2),
|
|
30256
|
+
project(b, thickness / 2),
|
|
30257
|
+
project(a, thickness / 2)
|
|
30258
|
+
],
|
|
30259
|
+
reverse
|
|
30260
|
+
);
|
|
30261
|
+
}
|
|
30262
|
+
}
|
|
30263
|
+
const sides2 = profile === "plate" ? [] : profile === "angle" ? [1] : [-1, 1];
|
|
30264
|
+
for (const side of sides2) {
|
|
30265
|
+
const project = (angle, crossSection) => {
|
|
30266
|
+
const r = radius - crossSection.offset;
|
|
30267
|
+
return [
|
|
30268
|
+
side * (baseLength / 2 + r * Math.sin(angle)),
|
|
30269
|
+
crossSection.y,
|
|
30270
|
+
radius - r * Math.cos(angle)
|
|
30271
|
+
];
|
|
30272
|
+
};
|
|
30273
|
+
for (let i = 0; i < 32; i++) {
|
|
30274
|
+
const a = i * Math.PI / 64, b = (i + 1) * Math.PI / 64;
|
|
30275
|
+
for (const offset4 of [-thickness / 2, thickness / 2]) {
|
|
30276
|
+
addQuad(
|
|
30277
|
+
[
|
|
30278
|
+
project(a, { y: -width10 / 2, offset: offset4 }),
|
|
30279
|
+
project(b, { y: -width10 / 2, offset: offset4 }),
|
|
30280
|
+
project(b, { y: width10 / 2, offset: offset4 }),
|
|
30281
|
+
project(a, { y: width10 / 2, offset: offset4 })
|
|
30282
|
+
],
|
|
30283
|
+
offset4 < 0 !== side < 0
|
|
30284
|
+
);
|
|
30285
|
+
}
|
|
30286
|
+
for (const y of [-width10 / 2, width10 / 2]) {
|
|
30287
|
+
addQuad(
|
|
30288
|
+
[
|
|
30289
|
+
project(a, { y, offset: -thickness / 2 }),
|
|
30290
|
+
project(b, { y, offset: -thickness / 2 }),
|
|
30291
|
+
project(b, { y, offset: thickness / 2 }),
|
|
30292
|
+
project(a, { y, offset: thickness / 2 })
|
|
30293
|
+
],
|
|
30294
|
+
y > 0 !== side < 0
|
|
30295
|
+
);
|
|
30296
|
+
}
|
|
30297
|
+
}
|
|
30298
|
+
}
|
|
30299
|
+
return { positions, indices };
|
|
30300
|
+
}
|
|
30301
|
+
function createSheetMetalGeom(input) {
|
|
30302
|
+
return indexedMeshToGeom3(createSheetMetalMesh(input));
|
|
30303
|
+
}
|
|
30304
|
+
function SheetMetal({ color = "#737e8f", ...props }) {
|
|
30305
|
+
return /* @__PURE__ */ jsx3(Colorize, { color, children: /* @__PURE__ */ jsx3(Custom, { geometry: createSheetMetalGeom(props) }) });
|
|
30306
|
+
}
|
|
30307
|
+
var resolveNemaMotorProps = nemaMotorModelPropsSchema.parse.bind(
|
|
30308
|
+
nemaMotorModelPropsSchema
|
|
30309
|
+
);
|
|
30310
|
+
var circle = (radius, x = 0, y = 0) => Array.from({ length: 96 }, (_, i) => [
|
|
30311
|
+
x + radius * Math.cos(i * Math.PI / 48),
|
|
30312
|
+
y + radius * Math.sin(i * Math.PI / 48)
|
|
30313
|
+
]);
|
|
30314
|
+
var face = (width10, chamfer) => {
|
|
30315
|
+
const h2 = width10 / 2, c = chamfer;
|
|
30316
|
+
if (c === 0)
|
|
30317
|
+
return [
|
|
30318
|
+
[-h2, -h2],
|
|
30319
|
+
[h2, -h2],
|
|
30320
|
+
[h2, h2],
|
|
30321
|
+
[-h2, h2]
|
|
30322
|
+
];
|
|
30323
|
+
return [
|
|
30324
|
+
[-h2 + c, -h2],
|
|
30325
|
+
[h2 - c, -h2],
|
|
30326
|
+
[h2, -h2 + c],
|
|
30327
|
+
[h2, h2 - c],
|
|
30328
|
+
[h2 - c, h2],
|
|
30329
|
+
[-h2 + c, h2],
|
|
30330
|
+
[-h2, h2 - c],
|
|
30331
|
+
[-h2, -h2 + c]
|
|
30332
|
+
];
|
|
30333
|
+
};
|
|
30334
|
+
function createNemaMotorSections(input) {
|
|
30335
|
+
const p = resolveNemaMotorProps(input);
|
|
30336
|
+
const sections = [];
|
|
30337
|
+
const add = (name, outline, zMin, zMax, holes2 = []) => {
|
|
30338
|
+
if (zMax > zMin) sections.push({ name, outline, holes: holes2, zMin, zMax });
|
|
30339
|
+
};
|
|
30340
|
+
const front = face(p.bodyWidth, p.faceCornerChamfer);
|
|
30341
|
+
const core = face(p.bodyWidth, p.bodyCornerChamfer);
|
|
30342
|
+
const h2 = p.mountingHoleSpacing / 2;
|
|
30343
|
+
const centers = [
|
|
30344
|
+
[-h2, -h2],
|
|
30345
|
+
[h2, -h2],
|
|
30346
|
+
[h2, h2],
|
|
30347
|
+
[-h2, h2]
|
|
30348
|
+
];
|
|
30349
|
+
const holes = centers.map(
|
|
30350
|
+
([x, y]) => circle(p.mountingHoleDiameter / 2, x, y)
|
|
30351
|
+
);
|
|
30352
|
+
const holeDepth = p.mountingHoleThrough ? p.frontCapLength : p.mountingHoleDepth;
|
|
30353
|
+
add("frontCap", front, -holeDepth, 0, holes);
|
|
30354
|
+
add("frontCap", front, -p.frontCapLength, -holeDepth);
|
|
30355
|
+
add("body", core, -p.bodyLength + p.rearCapLength, -p.frontCapLength);
|
|
30356
|
+
add(
|
|
30357
|
+
"rearCap",
|
|
30358
|
+
p.mountingHoleThrough ? core : front,
|
|
30359
|
+
-p.bodyLength,
|
|
30360
|
+
-p.bodyLength + p.rearCapLength
|
|
30361
|
+
);
|
|
30362
|
+
add("pilot", circle(p.pilotDiameter / 2), 0, p.pilotLength);
|
|
30363
|
+
const r = p.shaftDiameter / 2;
|
|
30364
|
+
const round2 = circle(r);
|
|
30365
|
+
if (p.shaftShape === "round")
|
|
30366
|
+
add("shaft", round2, p.pilotLength, p.shaftLength);
|
|
30367
|
+
else {
|
|
30368
|
+
const cut = r - p.shaftFlatDepth;
|
|
30369
|
+
const angle = Math.acos(cut / r);
|
|
30370
|
+
const profile = Array.from({ length: 97 }, (_, i) => {
|
|
30371
|
+
const a = angle + (2 * Math.PI - 2 * angle) * i / 96;
|
|
30372
|
+
return [r * Math.cos(a), r * Math.sin(a)];
|
|
30373
|
+
});
|
|
30374
|
+
const rotation = p.shaftFlatAngle * Math.PI / 180;
|
|
30375
|
+
const d = profile.map(([x, y]) => [
|
|
30376
|
+
x * Math.cos(rotation) - y * Math.sin(rotation),
|
|
30377
|
+
x * Math.sin(rotation) + y * Math.cos(rotation)
|
|
30378
|
+
]);
|
|
30379
|
+
add("shaft", round2, p.pilotLength, p.shaftLength - p.shaftFlatLength);
|
|
30380
|
+
add("shaft", d, p.shaftLength - p.shaftFlatLength, p.shaftLength);
|
|
30381
|
+
}
|
|
30382
|
+
return sections;
|
|
30383
|
+
}
|
|
30384
|
+
function NemaMotor({
|
|
30385
|
+
bodyColor = "#242830",
|
|
30386
|
+
capColor = "#aeb5bd",
|
|
30387
|
+
shaftColor = "#b8bec6",
|
|
30388
|
+
...props
|
|
30389
|
+
}) {
|
|
30390
|
+
return /* @__PURE__ */ jsx3(Fragment2, { children: createNemaMotorSections(props).map((section, index2) => {
|
|
30391
|
+
const outline = import_modeling2.default.geometries.geom2.fromPoints(section.outline);
|
|
30392
|
+
const profile = section.holes.length ? import_modeling2.default.booleans.subtract(
|
|
30393
|
+
outline,
|
|
30394
|
+
...section.holes.map((h2) => import_modeling2.default.geometries.geom2.fromPoints(h2))
|
|
30395
|
+
) : outline;
|
|
30396
|
+
const geometry = import_modeling2.default.transforms.translate(
|
|
30397
|
+
[0, 0, section.zMin],
|
|
30398
|
+
import_modeling2.default.extrusions.extrudeLinear(
|
|
30399
|
+
{ height: section.zMax - section.zMin },
|
|
30400
|
+
profile
|
|
30401
|
+
)
|
|
30402
|
+
);
|
|
30403
|
+
return /* @__PURE__ */ jsx3(
|
|
30404
|
+
Colorize,
|
|
30405
|
+
{
|
|
30406
|
+
color: section.name === "body" ? bodyColor : section.name === "shaft" ? shaftColor : capColor,
|
|
30407
|
+
children: /* @__PURE__ */ jsx3(Custom, { geometry })
|
|
30408
|
+
},
|
|
30409
|
+
`${section.name}-${index2}`
|
|
30410
|
+
);
|
|
30411
|
+
}) });
|
|
30412
|
+
}
|
|
28988
30413
|
function LGA(p) {
|
|
28989
30414
|
for (const k of [
|
|
28990
30415
|
"bodyWidth",
|
|
@@ -29167,7 +30592,7 @@ function createDualRowGullWing(p) {
|
|
|
29167
30592
|
]);
|
|
29168
30593
|
}
|
|
29169
30594
|
points.push([root, midZ]);
|
|
29170
|
-
const section = ([x,
|
|
30595
|
+
const section = ([x, z27]) => /* @__PURE__ */ jsx3(Translate, { offset: { x: side * x, y, z: z27 }, children: /* @__PURE__ */ jsx3(Cuboid, { size: [slice, leadWidth, leadThickness] }) });
|
|
29171
30596
|
return /* @__PURE__ */ jsx3(Union, { children: points.slice(1).map((point, i) => /* @__PURE__ */ jsxs(Hull, { children: [
|
|
29172
30597
|
section(points[i]),
|
|
29173
30598
|
section(point)
|
|
@@ -29423,10 +30848,10 @@ var svgPathPoints = normalizeOnY([
|
|
|
29423
30848
|
]);
|
|
29424
30849
|
var DIP_PIN_HEIGHT = 5.47;
|
|
29425
30850
|
var heightAboveSurface = 0.5;
|
|
29426
|
-
var DipPinLeg = ({ x, y, z:
|
|
30851
|
+
var DipPinLeg = ({ x, y, z: z27 }) => {
|
|
29427
30852
|
const isRotated = x > 0;
|
|
29428
30853
|
return /* @__PURE__ */ jsxs(Fragment2, { children: [
|
|
29429
|
-
/* @__PURE__ */ jsx3(Translate, { offset: { x: x + 0.25 / 2, y, z:
|
|
30854
|
+
/* @__PURE__ */ jsx3(Translate, { offset: { x: x + 0.25 / 2, y, z: z27 }, children: /* @__PURE__ */ jsx3(Rotate, { rotation: ["-90deg", 0, "90deg"], children: /* @__PURE__ */ jsx3(ExtrudeLinear, { height: 0.25, children: /* @__PURE__ */ jsx3(
|
|
29430
30855
|
Polygon,
|
|
29431
30856
|
{
|
|
29432
30857
|
points: svgPathPoints.slice().reverse().map((p) => [p.x, p.y])
|
|
@@ -29438,7 +30863,7 @@ var DipPinLeg = ({ x, y, z: z42 }) => {
|
|
|
29438
30863
|
offset: {
|
|
29439
30864
|
x,
|
|
29440
30865
|
y: y + (isRotated ? 1 : -1),
|
|
29441
|
-
z:
|
|
30866
|
+
z: z27
|
|
29442
30867
|
},
|
|
29443
30868
|
children: /* @__PURE__ */ jsx3(Rotate, { rotation: ["-90deg", "90deg", isRotated ? "180deg" : "0deg"], children: /* @__PURE__ */ jsx3(ExtrudeLinear, { height: 2, children: /* @__PURE__ */ jsx3(
|
|
29444
30869
|
Polygon,
|
|
@@ -29723,6 +31148,64 @@ var A0603 = ({ color = "#333" }) => {
|
|
|
29723
31148
|
)
|
|
29724
31149
|
] });
|
|
29725
31150
|
};
|
|
31151
|
+
var smdLedDimensions = {
|
|
31152
|
+
"0402": { length: 1, width: 0.5, height: 0.5, terminalLength: 0.2 },
|
|
31153
|
+
"0603": { length: 1.62, width: 0.8, height: 0.615, terminalLength: 0.21 },
|
|
31154
|
+
"0805": { length: 2, width: 1.25, height: 0.75, terminalLength: 0.35 }
|
|
31155
|
+
};
|
|
31156
|
+
function SmdLED({
|
|
31157
|
+
footprint,
|
|
31158
|
+
color = "#ffe8a0"
|
|
31159
|
+
}) {
|
|
31160
|
+
const p = smdLedDimensions[footprint];
|
|
31161
|
+
if (footprint === "0603")
|
|
31162
|
+
return /* @__PURE__ */ jsxs(Fragment2, { children: [
|
|
31163
|
+
/* @__PURE__ */ jsx3(Colorize, { color: "#f0eee7", children: /* @__PURE__ */ jsx3(
|
|
31164
|
+
RoundedCuboid,
|
|
31165
|
+
{
|
|
31166
|
+
size: [1.2, 0.79, 0.6],
|
|
31167
|
+
roundRadius: 0.02,
|
|
31168
|
+
center: [0, 0, 0.31]
|
|
31169
|
+
}
|
|
31170
|
+
) }),
|
|
31171
|
+
/* @__PURE__ */ jsx3(Colorize, { color: "#c7c9ca", children: [-1, 1].map((sign) => /* @__PURE__ */ jsx3(
|
|
31172
|
+
Cuboid,
|
|
31173
|
+
{
|
|
31174
|
+
size: [0.21, 0.8, 0.22],
|
|
31175
|
+
center: [sign * 0.705, 0, 0.11]
|
|
31176
|
+
},
|
|
31177
|
+
sign
|
|
31178
|
+
)) }),
|
|
31179
|
+
/* @__PURE__ */ jsx3(Colorize, { color, children: /* @__PURE__ */ jsx3(Cuboid, { size: [0.72, 0.52, 0.01], center: [0, 0, 0.61] }) })
|
|
31180
|
+
] });
|
|
31181
|
+
const terminalThickness = Math.min(0.1, p.height / 4);
|
|
31182
|
+
const apertureHeight = 0.02;
|
|
31183
|
+
return /* @__PURE__ */ jsxs(Fragment2, { children: [
|
|
31184
|
+
/* @__PURE__ */ jsx3(Colorize, { color: "#f0eee7", children: /* @__PURE__ */ jsx3(Translate, { z: (p.height + terminalThickness - apertureHeight) / 2, children: /* @__PURE__ */ jsx3(
|
|
31185
|
+
Cuboid,
|
|
31186
|
+
{
|
|
31187
|
+
size: [
|
|
31188
|
+
p.length,
|
|
31189
|
+
p.width,
|
|
31190
|
+
p.height - terminalThickness - apertureHeight
|
|
31191
|
+
]
|
|
31192
|
+
}
|
|
31193
|
+
) }) }),
|
|
31194
|
+
/* @__PURE__ */ jsx3(Colorize, { color: "#c7c9ca", children: [-1, 1].map((sign) => /* @__PURE__ */ jsx3(
|
|
31195
|
+
Translate,
|
|
31196
|
+
{
|
|
31197
|
+
offset: [
|
|
31198
|
+
sign * (p.length - p.terminalLength) / 2,
|
|
31199
|
+
0,
|
|
31200
|
+
terminalThickness / 2
|
|
31201
|
+
],
|
|
31202
|
+
children: /* @__PURE__ */ jsx3(Cuboid, { size: [p.terminalLength, p.width, terminalThickness] })
|
|
31203
|
+
},
|
|
31204
|
+
sign
|
|
31205
|
+
)) }),
|
|
31206
|
+
/* @__PURE__ */ jsx3(Colorize, { color, children: /* @__PURE__ */ jsx3(Translate, { z: p.height - apertureHeight / 2, children: /* @__PURE__ */ jsx3(Cuboid, { size: [p.length * 0.45, p.width * 0.65, apertureHeight] }) }) })
|
|
31207
|
+
] });
|
|
31208
|
+
}
|
|
29726
31209
|
var fullLength3 = 2;
|
|
29727
31210
|
var width3 = 1.25;
|
|
29728
31211
|
var height3 = 0.55;
|
|
@@ -30012,7 +31495,7 @@ var PinRow = ({
|
|
|
30012
31495
|
const xoff = -((pinsPerRow - 1) / 2) * pitch;
|
|
30013
31496
|
const throughHole = !smd && !rightangle;
|
|
30014
31497
|
const flipped = throughHole ? !invert : Boolean(invert);
|
|
30015
|
-
const flipZ = (
|
|
31498
|
+
const flipZ = (z27) => flipped ? -z27 + bodyHeight : z27;
|
|
30016
31499
|
return /* @__PURE__ */ jsx3(Fragment2, { children: Array.from({ length: numberOfPins }, (_, i) => {
|
|
30017
31500
|
const row = Math.floor(i / pinsPerRow);
|
|
30018
31501
|
const col = i % pinsPerRow;
|
|
@@ -30743,7 +32226,7 @@ var A2512 = ({ color = "#333" }) => {
|
|
|
30743
32226
|
var FemaleHeader = ({
|
|
30744
32227
|
x,
|
|
30745
32228
|
y,
|
|
30746
|
-
z:
|
|
32229
|
+
z: z27 = 0,
|
|
30747
32230
|
pitch = 2.54,
|
|
30748
32231
|
legsLength = 3,
|
|
30749
32232
|
innerDiameter = 0.945,
|
|
@@ -30758,8 +32241,8 @@ var FemaleHeader = ({
|
|
|
30758
32241
|
const socketEntryWidth = socketWidth * 1.8;
|
|
30759
32242
|
const socketEntryHeight = Math.min(bodyHeight * 0.18, pitch * 0.24);
|
|
30760
32243
|
const socketDepth = bodyHeight + 0.1;
|
|
30761
|
-
const socketCenterZ = flipZ(
|
|
30762
|
-
const socketEntryBaseZ =
|
|
32244
|
+
const socketCenterZ = flipZ(z27 + socketDepth / 2);
|
|
32245
|
+
const socketEntryBaseZ = z27 + bodyHeight - socketEntryHeight;
|
|
30763
32246
|
const gapWidth = pinThickness * 1.6;
|
|
30764
32247
|
return /* @__PURE__ */ jsxs(Fragment2, { children: [
|
|
30765
32248
|
/* @__PURE__ */ jsx3(Colorize, { color: "#1a1a1a", children: /* @__PURE__ */ jsxs(Subtract, { children: [
|
|
@@ -30768,7 +32251,7 @@ var FemaleHeader = ({
|
|
|
30768
32251
|
{
|
|
30769
32252
|
color: "#000",
|
|
30770
32253
|
size: [bodyLength10, bodyWidth, bodyHeight],
|
|
30771
|
-
center: [x, y, flipZ(
|
|
32254
|
+
center: [x, y, flipZ(z27 + bodyHeight / 2)]
|
|
30772
32255
|
}
|
|
30773
32256
|
),
|
|
30774
32257
|
/* @__PURE__ */ jsx3(
|
|
@@ -30790,7 +32273,7 @@ var FemaleHeader = ({
|
|
|
30790
32273
|
Cuboid,
|
|
30791
32274
|
{
|
|
30792
32275
|
size: [socketEntryWidth, socketEntryWidth, 0.01],
|
|
30793
|
-
center: [x, y, flipZ(
|
|
32276
|
+
center: [x, y, flipZ(z27 + bodyHeight)]
|
|
30794
32277
|
}
|
|
30795
32278
|
)
|
|
30796
32279
|
] })
|
|
@@ -30802,7 +32285,7 @@ var FemaleHeader = ({
|
|
|
30802
32285
|
{
|
|
30803
32286
|
color: "silver",
|
|
30804
32287
|
size: [pinThickness, pinThickness, legsLength * 0.9],
|
|
30805
|
-
center: [x, y, flipZ(
|
|
32288
|
+
center: [x, y, flipZ(z27 + -legsLength / 2 * 0.9)]
|
|
30806
32289
|
}
|
|
30807
32290
|
),
|
|
30808
32291
|
/* @__PURE__ */ jsx3(
|
|
@@ -30810,7 +32293,7 @@ var FemaleHeader = ({
|
|
|
30810
32293
|
{
|
|
30811
32294
|
color: "silver",
|
|
30812
32295
|
size: [pinThickness / 1.8, pinThickness / 1.8, legsLength],
|
|
30813
|
-
center: [x, y, flipZ(
|
|
32296
|
+
center: [x, y, flipZ(z27 + -legsLength / 2)]
|
|
30814
32297
|
}
|
|
30815
32298
|
)
|
|
30816
32299
|
] }),
|
|
@@ -30819,7 +32302,7 @@ var FemaleHeader = ({
|
|
|
30819
32302
|
{
|
|
30820
32303
|
color: "silver",
|
|
30821
32304
|
size: [gapWidth, gapWidth, gapWidth * 0.5],
|
|
30822
|
-
center: [x, y, flipZ(
|
|
32305
|
+
center: [x, y, flipZ(z27 + gapWidth / 2 * 0.5)]
|
|
30823
32306
|
}
|
|
30824
32307
|
)
|
|
30825
32308
|
] })
|
|
@@ -30837,7 +32320,7 @@ var FemaleHeaderRow = ({
|
|
|
30837
32320
|
const pinsPerRow = Math.ceil(numberOfPins / rows);
|
|
30838
32321
|
const rowSpacing = 2.54;
|
|
30839
32322
|
const xoff = -((pinsPerRow - 1) / 2) * pitch;
|
|
30840
|
-
const flipZ = (
|
|
32323
|
+
const flipZ = (z27) => invert ? -z27 + bodyHeight : z27;
|
|
30841
32324
|
return /* @__PURE__ */ jsx3(Fragment2, { children: Array.from({ length: numberOfPins }, (_, i) => {
|
|
30842
32325
|
const row = Math.floor(i / pinsPerRow);
|
|
30843
32326
|
const col = i % pinsPerRow;
|
|
@@ -32227,13 +33710,13 @@ function createPhysicalLqfp(p) {
|
|
|
32227
33710
|
]);
|
|
32228
33711
|
}
|
|
32229
33712
|
points.push([root, midZ]);
|
|
32230
|
-
const section = ([x,
|
|
33713
|
+
const section = ([x, z27]) => /* @__PURE__ */ jsx3(
|
|
32231
33714
|
Translate,
|
|
32232
33715
|
{
|
|
32233
33716
|
offset: {
|
|
32234
33717
|
x: horizontal ? sign * x : along,
|
|
32235
33718
|
y: horizontal ? along : sign * x,
|
|
32236
|
-
z:
|
|
33719
|
+
z: z27
|
|
32237
33720
|
},
|
|
32238
33721
|
children: /* @__PURE__ */ jsx3(
|
|
32239
33722
|
Cuboid,
|
|
@@ -34064,7 +35547,7 @@ var MountedPcbModule = ({
|
|
|
34064
35547
|
shortSidePinLength,
|
|
34065
35548
|
longSidePinLength,
|
|
34066
35549
|
bodyHeight: pinBodyHeight,
|
|
34067
|
-
flipZ: (
|
|
35550
|
+
flipZ: (z27) => z27
|
|
34068
35551
|
},
|
|
34069
35552
|
`pin-3d-${index2}`
|
|
34070
35553
|
));
|
|
@@ -34073,7 +35556,7 @@ var MountedPcbModule = ({
|
|
|
34073
35556
|
{
|
|
34074
35557
|
x: pin.x,
|
|
34075
35558
|
y: pin.y,
|
|
34076
|
-
flipZ: (
|
|
35559
|
+
flipZ: (z27) => -z27
|
|
34077
35560
|
},
|
|
34078
35561
|
`female-pin-3d-${index2}`
|
|
34079
35562
|
));
|
|
@@ -34603,7 +36086,7 @@ function isJstShFootprint(footprint) {
|
|
|
34603
36086
|
const p = fp.string(footprint).json();
|
|
34604
36087
|
if (p.fn !== "jst") return false;
|
|
34605
36088
|
return Boolean(
|
|
34606
|
-
p.sh || p.smd && Math.abs(
|
|
36089
|
+
p.sh || p.smd && Math.abs(mm3(p.p) - 1) < 0.01 && Math.abs(mm3(p.mpx ?? 0) - (p.num_pins - 1 + 2.6)) < 0.15 && Math.abs(mm3(p.mpy ?? 0) - 2.525) < 0.15
|
|
34607
36090
|
);
|
|
34608
36091
|
}
|
|
34609
36092
|
var JstSh = ({ footprint = "jst6_sh" }) => {
|
|
@@ -34724,7 +36207,7 @@ var getRoundedRectProfile = ({
|
|
|
34724
36207
|
length: length83,
|
|
34725
36208
|
radius,
|
|
34726
36209
|
height: height10,
|
|
34727
|
-
z:
|
|
36210
|
+
z: z27
|
|
34728
36211
|
}) => {
|
|
34729
36212
|
const x = width10 / 2 - radius;
|
|
34730
36213
|
const y = length83 / 2 - radius;
|
|
@@ -34736,11 +36219,11 @@ var getRoundedRectProfile = ({
|
|
|
34736
36219
|
].map(([cornerX, cornerY], index2) => /* @__PURE__ */ jsx3(
|
|
34737
36220
|
Cylinder,
|
|
34738
36221
|
{
|
|
34739
|
-
center: [cornerX, cornerY,
|
|
36222
|
+
center: [cornerX, cornerY, z27 + height10 / 2],
|
|
34740
36223
|
height: height10,
|
|
34741
36224
|
radius
|
|
34742
36225
|
},
|
|
34743
|
-
`${
|
|
36226
|
+
`${z27}-${index2}`
|
|
34744
36227
|
));
|
|
34745
36228
|
};
|
|
34746
36229
|
var Crystal = ({
|
|
@@ -36718,6 +38201,18 @@ var Footprinter3d = ({ footprint }) => {
|
|
|
36718
38201
|
if (mp.getModelNames().includes(modelFn)) {
|
|
36719
38202
|
const model = mp.string(footprint).json();
|
|
36720
38203
|
switch (model.fn) {
|
|
38204
|
+
case "nema": {
|
|
38205
|
+
const { fn, ...props } = model;
|
|
38206
|
+
return /* @__PURE__ */ jsx3(NemaMotor, { ...props });
|
|
38207
|
+
}
|
|
38208
|
+
case "hexsocketbolt": {
|
|
38209
|
+
const { fn, ...props } = model;
|
|
38210
|
+
return /* @__PURE__ */ jsx3(HexSocketBolt, { ...props });
|
|
38211
|
+
}
|
|
38212
|
+
case "sheetmetal": {
|
|
38213
|
+
const { fn, ...props } = model;
|
|
38214
|
+
return /* @__PURE__ */ jsx3(SheetMetal, { ...props });
|
|
38215
|
+
}
|
|
36721
38216
|
case "flexscreen": {
|
|
36722
38217
|
const { fn: _, ...flexScreenProps } = model;
|
|
36723
38218
|
return /* @__PURE__ */ jsx3(FlexScreen, { ...flexScreenProps });
|
|
@@ -36743,7 +38238,7 @@ var Footprinter3d = ({ footprint }) => {
|
|
|
36743
38238
|
const color = colorMatch ? colorMatch[1] : void 0;
|
|
36744
38239
|
const dim = (value, fallback) => {
|
|
36745
38240
|
if (value === void 0 || value === null) return fallback;
|
|
36746
|
-
const parsed =
|
|
38241
|
+
const parsed = mm3(value);
|
|
36747
38242
|
return Number.isFinite(parsed) ? parsed : fallback;
|
|
36748
38243
|
};
|
|
36749
38244
|
const bodyModel = renderFootprinterBodyModel(fpJson);
|
|
@@ -36848,7 +38343,8 @@ var Footprinter3d = ({ footprint }) => {
|
|
|
36848
38343
|
}
|
|
36849
38344
|
);
|
|
36850
38345
|
}
|
|
36851
|
-
case "pinrow":
|
|
38346
|
+
case "pinrow":
|
|
38347
|
+
case "headermodule": {
|
|
36852
38348
|
const rowsMatch = footprint.match(/_rows(\d+)/);
|
|
36853
38349
|
const rows = rowsMatch && rowsMatch[1] ? parseInt(rowsMatch[1], 10) : 1;
|
|
36854
38350
|
if (fpJson.male)
|
|
@@ -36884,6 +38380,12 @@ var Footprinter3d = ({ footprint }) => {
|
|
|
36884
38380
|
);
|
|
36885
38381
|
case "led5050":
|
|
36886
38382
|
return /* @__PURE__ */ jsx3(Led5050, { color });
|
|
38383
|
+
case "led": {
|
|
38384
|
+
const imperial = String(fpJson.imperial);
|
|
38385
|
+
if (imperial === "0402" || imperial === "0603" || imperial === "0805")
|
|
38386
|
+
return /* @__PURE__ */ jsx3(SmdLED, { footprint: imperial, color });
|
|
38387
|
+
break;
|
|
38388
|
+
}
|
|
36887
38389
|
case "cap": {
|
|
36888
38390
|
switch (fpJson.imperial) {
|
|
36889
38391
|
case "0402":
|
|
@@ -37361,8 +38863,8 @@ var Footprinter3d = ({ footprint }) => {
|
|
|
37361
38863
|
return /* @__PURE__ */ jsx3(A2512, { color });
|
|
37362
38864
|
}
|
|
37363
38865
|
if ((fpJson.fn === "res" || fpJson.fn === "cap") && fpJson.p !== void 0 && fpJson.ph !== void 0) {
|
|
37364
|
-
const padPitch =
|
|
37365
|
-
const padHeight =
|
|
38866
|
+
const padPitch = mm3(fpJson.p);
|
|
38867
|
+
const padHeight = mm3(fpJson.ph);
|
|
37366
38868
|
if (Number.isFinite(padPitch) && Number.isFinite(padHeight)) {
|
|
37367
38869
|
return /* @__PURE__ */ jsx3(
|
|
37368
38870
|
ParametricChip,
|
|
@@ -37452,6 +38954,9 @@ function renderNode(node, colorCtx, renderCtx) {
|
|
|
37452
38954
|
else geom = hulls.hull(geoms);
|
|
37453
38955
|
return [{ geom, color: colorCtx }];
|
|
37454
38956
|
}
|
|
38957
|
+
if (type === Custom) {
|
|
38958
|
+
return [{ geom: props.geometry, color: colorCtx }];
|
|
38959
|
+
}
|
|
37455
38960
|
if (type === Polygon) {
|
|
37456
38961
|
const points = props?.points ?? [];
|
|
37457
38962
|
const g2 = geometries.geom2.fromPoints(points);
|
|
@@ -37512,8 +39017,8 @@ function renderNode(node, colorCtx, renderCtx) {
|
|
|
37512
39017
|
}
|
|
37513
39018
|
return (children ?? []).flatMap((c) => renderNode(c, colorCtx, renderCtx));
|
|
37514
39019
|
}
|
|
37515
|
-
function render(root,
|
|
37516
|
-
const geometries = renderNode(root, void 0, { jscad:
|
|
39020
|
+
function render(root, jscad32) {
|
|
39021
|
+
const geometries = renderNode(root, void 0, { jscad: jscad32 });
|
|
37517
39022
|
return { geometries };
|
|
37518
39023
|
}
|
|
37519
39024
|
function convertCSGToThreeGeom(csg) {
|
|
@@ -37592,9 +39097,9 @@ function convertCSGToThreeGeom(csg) {
|
|
|
37592
39097
|
console.error("Invalid CSG object: neither polygons nor sides found");
|
|
37593
39098
|
return new BufferGeometry();
|
|
37594
39099
|
}
|
|
37595
|
-
function getJscadModelForFootprint(footprint,
|
|
39100
|
+
function getJscadModelForFootprint(footprint, jscad32) {
|
|
37596
39101
|
const vnode = h(Footprinter3d, { footprint });
|
|
37597
|
-
return render(vnode,
|
|
39102
|
+
return render(vnode, jscad32);
|
|
37598
39103
|
}
|
|
37599
39104
|
|
|
37600
39105
|
// src/three-components/FootprinterModel.tsx
|
|
@@ -38197,7 +39702,7 @@ function GltfModel({
|
|
|
38197
39702
|
|
|
38198
39703
|
// src/three-components/JscadModel.tsx
|
|
38199
39704
|
var import_jscad_planner = __toESM(require_dist(), 1);
|
|
38200
|
-
var
|
|
39705
|
+
var import_modeling3 = __toESM(require_src(), 1);
|
|
38201
39706
|
import * as THREE11 from "three";
|
|
38202
39707
|
import { useState as useState6, useEffect as useEffect9 } from "react";
|
|
38203
39708
|
import { jsx as jsx8 } from "react/jsx-runtime";
|
|
@@ -38218,7 +39723,7 @@ var JscadModel = ({
|
|
|
38218
39723
|
}) => {
|
|
38219
39724
|
const [mesh, setMesh] = useState6(null);
|
|
38220
39725
|
useEffect9(() => {
|
|
38221
|
-
const jscadObject = (0, import_jscad_planner.executeJscadOperations)(
|
|
39726
|
+
const jscadObject = (0, import_jscad_planner.executeJscadOperations)(import_modeling3.default, jscadPlan);
|
|
38222
39727
|
if (!jscadObject || !jscadObject.polygons && !jscadObject.sides) {
|
|
38223
39728
|
setMesh(null);
|
|
38224
39729
|
return;
|
|
@@ -38597,12 +40102,12 @@ async function convertStepUrlToGlb(stepUrl) {
|
|
|
38597
40102
|
}
|
|
38598
40103
|
const group = occtMeshesToGroup(result.meshes);
|
|
38599
40104
|
const exporter = new GLTFExporter();
|
|
38600
|
-
const glb = await new Promise((
|
|
40105
|
+
const glb = await new Promise((resolve2, reject) => {
|
|
38601
40106
|
exporter.parse(
|
|
38602
40107
|
group,
|
|
38603
40108
|
(output) => {
|
|
38604
40109
|
if (output instanceof ArrayBuffer) {
|
|
38605
|
-
|
|
40110
|
+
resolve2(output);
|
|
38606
40111
|
} else {
|
|
38607
40112
|
reject(new Error("GLTFExporter did not return binary output"));
|
|
38608
40113
|
}
|
|
@@ -38782,9 +40287,9 @@ var StepModel = ({
|
|
|
38782
40287
|
// src/utils/cad-model-loader-transform.ts
|
|
38783
40288
|
import * as THREE13 from "three";
|
|
38784
40289
|
function applyCoordinateTransform(point, config) {
|
|
38785
|
-
let { x, y, z:
|
|
40290
|
+
let { x, y, z: z27 } = point;
|
|
38786
40291
|
if (config.axisMapping) {
|
|
38787
|
-
const original = { x, y, z:
|
|
40292
|
+
const original = { x, y, z: z27 };
|
|
38788
40293
|
if (config.axisMapping.x) {
|
|
38789
40294
|
x = getAxisValue(original, config.axisMapping.x);
|
|
38790
40295
|
}
|
|
@@ -38792,30 +40297,30 @@ function applyCoordinateTransform(point, config) {
|
|
|
38792
40297
|
y = getAxisValue(original, config.axisMapping.y);
|
|
38793
40298
|
}
|
|
38794
40299
|
if (config.axisMapping.z) {
|
|
38795
|
-
|
|
40300
|
+
z27 = getAxisValue(original, config.axisMapping.z);
|
|
38796
40301
|
}
|
|
38797
40302
|
}
|
|
38798
40303
|
x *= config.flipX ?? 1;
|
|
38799
40304
|
y *= config.flipY ?? 1;
|
|
38800
|
-
|
|
40305
|
+
z27 *= config.flipZ ?? 1;
|
|
38801
40306
|
if (config.rotation) {
|
|
38802
40307
|
if (config.rotation.x) {
|
|
38803
40308
|
const rad = config.rotation.x * Math.PI / 180;
|
|
38804
40309
|
const cos = Math.cos(rad);
|
|
38805
40310
|
const sin = Math.sin(rad);
|
|
38806
|
-
const newY = y * cos -
|
|
38807
|
-
const newZ = y * sin +
|
|
40311
|
+
const newY = y * cos - z27 * sin;
|
|
40312
|
+
const newZ = y * sin + z27 * cos;
|
|
38808
40313
|
y = newY;
|
|
38809
|
-
|
|
40314
|
+
z27 = newZ;
|
|
38810
40315
|
}
|
|
38811
40316
|
if (config.rotation.y) {
|
|
38812
40317
|
const rad = config.rotation.y * Math.PI / 180;
|
|
38813
40318
|
const cos = Math.cos(rad);
|
|
38814
40319
|
const sin = Math.sin(rad);
|
|
38815
|
-
const newX = x * cos +
|
|
38816
|
-
const newZ = -x * sin +
|
|
40320
|
+
const newX = x * cos + z27 * sin;
|
|
40321
|
+
const newZ = -x * sin + z27 * cos;
|
|
38817
40322
|
x = newX;
|
|
38818
|
-
|
|
40323
|
+
z27 = newZ;
|
|
38819
40324
|
}
|
|
38820
40325
|
if (config.rotation.z) {
|
|
38821
40326
|
const rad = config.rotation.z * Math.PI / 180;
|
|
@@ -38827,7 +40332,7 @@ function applyCoordinateTransform(point, config) {
|
|
|
38827
40332
|
y = newY;
|
|
38828
40333
|
}
|
|
38829
40334
|
}
|
|
38830
|
-
return { x, y, z:
|
|
40335
|
+
return { x, y, z: z27 };
|
|
38831
40336
|
}
|
|
38832
40337
|
function getAxisValue(original, mapping) {
|
|
38833
40338
|
switch (mapping) {
|
|
@@ -39383,7 +40888,7 @@ import * as THREE25 from "three";
|
|
|
39383
40888
|
// package.json
|
|
39384
40889
|
var package_default = {
|
|
39385
40890
|
name: "@tscircuit/3d-viewer",
|
|
39386
|
-
version: "0.0.
|
|
40891
|
+
version: "0.0.612",
|
|
39387
40892
|
repository: {
|
|
39388
40893
|
type: "git",
|
|
39389
40894
|
url: "https://github.com/tscircuit/3d-viewer"
|
|
@@ -39451,6 +40956,7 @@ var package_default = {
|
|
|
39451
40956
|
"@tscircuit/core": "^0.0.1972",
|
|
39452
40957
|
"@tscircuit/props": "^0.0.666",
|
|
39453
40958
|
"@tscircuit/solver-utils": "^0.0.4",
|
|
40959
|
+
"@types/debug": "^4.1.13",
|
|
39454
40960
|
"@types/jsdom": "^21.1.7",
|
|
39455
40961
|
"@types/react": "19",
|
|
39456
40962
|
"@types/react-dom": "19",
|
|
@@ -39459,7 +40965,7 @@ var package_default = {
|
|
|
39459
40965
|
"bun-match-svg": "^0.0.9",
|
|
39460
40966
|
"bun-types": "1.2.1",
|
|
39461
40967
|
debug: "^4.4.0",
|
|
39462
|
-
"jscad-electronics": "^0.0.
|
|
40968
|
+
"jscad-electronics": "^0.0.182",
|
|
39463
40969
|
"jscad-planner": "^0.0.13",
|
|
39464
40970
|
jsdom: "^26.0.0",
|
|
39465
40971
|
"manifold-3d": "^3.2.1",
|
|
@@ -39472,11 +40978,11 @@ var package_default = {
|
|
|
39472
40978
|
vite: "^7.1.5",
|
|
39473
40979
|
"vite-tsconfig-paths": "^4.3.2",
|
|
39474
40980
|
"circuit-json-to-gltf": "0.0.129",
|
|
39475
|
-
|
|
39476
|
-
|
|
40981
|
+
zod: "^3.25.67",
|
|
40982
|
+
"@tscircuit/modelprinter": "^0.0.4"
|
|
39477
40983
|
},
|
|
39478
|
-
|
|
39479
|
-
|
|
40984
|
+
engines: {
|
|
40985
|
+
node: "24.x"
|
|
39480
40986
|
}
|
|
39481
40987
|
};
|
|
39482
40988
|
|
|
@@ -39587,11 +41093,11 @@ var CameraControllerProvider = ({ children, defaultTarget, initialCameraPosition
|
|
|
39587
41093
|
new THREE15.Euler(0, 0, 0)
|
|
39588
41094
|
);
|
|
39589
41095
|
const baseDistance = useMemo11(() => {
|
|
39590
|
-
const [x, y,
|
|
41096
|
+
const [x, y, z27] = initialCameraPosition ?? [5, -5, 5];
|
|
39591
41097
|
const distance6 = Math.hypot(
|
|
39592
41098
|
x - defaultTarget.x,
|
|
39593
41099
|
y - defaultTarget.y,
|
|
39594
|
-
|
|
41100
|
+
z27 - defaultTarget.z
|
|
39595
41101
|
);
|
|
39596
41102
|
return distance6 > 0 ? distance6 : 5;
|
|
39597
41103
|
}, [initialCameraPosition, defaultTarget]);
|
|
@@ -40640,37 +42146,37 @@ var createRoundedRectangleShape = (width10, height10, radius) => {
|
|
|
40640
42146
|
const halfWidth = width10 / 2;
|
|
40641
42147
|
const halfHeight = height10 / 2;
|
|
40642
42148
|
const safeRadius = Math.min(radius, halfWidth, halfHeight);
|
|
40643
|
-
const
|
|
40644
|
-
|
|
40645
|
-
|
|
40646
|
-
|
|
42149
|
+
const shape2 = new THREE23.Shape();
|
|
42150
|
+
shape2.moveTo(-halfWidth + safeRadius, -halfHeight);
|
|
42151
|
+
shape2.lineTo(halfWidth - safeRadius, -halfHeight);
|
|
42152
|
+
shape2.quadraticCurveTo(
|
|
40647
42153
|
halfWidth,
|
|
40648
42154
|
-halfHeight,
|
|
40649
42155
|
halfWidth,
|
|
40650
42156
|
-halfHeight + safeRadius
|
|
40651
42157
|
);
|
|
40652
|
-
|
|
40653
|
-
|
|
42158
|
+
shape2.lineTo(halfWidth, halfHeight - safeRadius);
|
|
42159
|
+
shape2.quadraticCurveTo(
|
|
40654
42160
|
halfWidth,
|
|
40655
42161
|
halfHeight,
|
|
40656
42162
|
halfWidth - safeRadius,
|
|
40657
42163
|
halfHeight
|
|
40658
42164
|
);
|
|
40659
|
-
|
|
40660
|
-
|
|
42165
|
+
shape2.lineTo(-halfWidth + safeRadius, halfHeight);
|
|
42166
|
+
shape2.quadraticCurveTo(
|
|
40661
42167
|
-halfWidth,
|
|
40662
42168
|
halfHeight,
|
|
40663
42169
|
-halfWidth,
|
|
40664
42170
|
halfHeight - safeRadius
|
|
40665
42171
|
);
|
|
40666
|
-
|
|
40667
|
-
|
|
42172
|
+
shape2.lineTo(-halfWidth, -halfHeight + safeRadius);
|
|
42173
|
+
shape2.quadraticCurveTo(
|
|
40668
42174
|
-halfWidth,
|
|
40669
42175
|
-halfHeight,
|
|
40670
42176
|
-halfWidth + safeRadius,
|
|
40671
42177
|
-halfHeight
|
|
40672
42178
|
);
|
|
40673
|
-
return
|
|
42179
|
+
return shape2;
|
|
40674
42180
|
};
|
|
40675
42181
|
var createRoundedPrismGeometry = (width10, height10, depth, radius) => {
|
|
40676
42182
|
return createPrismGeometryFromShape(
|
|
@@ -40678,8 +42184,8 @@ var createRoundedPrismGeometry = (width10, height10, depth, radius) => {
|
|
|
40678
42184
|
depth
|
|
40679
42185
|
);
|
|
40680
42186
|
};
|
|
40681
|
-
var createPrismGeometryFromShape = (
|
|
40682
|
-
const geometry = new THREE23.ExtrudeGeometry(
|
|
42187
|
+
var createPrismGeometryFromShape = (shape2, depth) => {
|
|
42188
|
+
const geometry = new THREE23.ExtrudeGeometry(shape2, {
|
|
40683
42189
|
depth,
|
|
40684
42190
|
bevelEnabled: false,
|
|
40685
42191
|
curveSegments: 24
|
|
@@ -41292,11 +42798,11 @@ var createBoardGeomWithOutline = (board, depth = 1.2, options = {}) => {
|
|
|
41292
42798
|
if (arePointsClockwise(outlineVec2)) {
|
|
41293
42799
|
outlineVec2 = outlineVec2.reverse();
|
|
41294
42800
|
}
|
|
41295
|
-
let
|
|
42801
|
+
let shape2 = (0, import_primitives.polygon)({ points: outlineVec2 });
|
|
41296
42802
|
if (xyOutset !== 0) {
|
|
41297
|
-
|
|
42803
|
+
shape2 = (0, import_expansions.expand)({ delta: xyOutset, corners: "edge" }, shape2);
|
|
41298
42804
|
}
|
|
41299
|
-
let boardGeom = (0, import_extrusions.extrudeLinear)({ height: depth },
|
|
42805
|
+
let boardGeom = (0, import_extrusions.extrudeLinear)({ height: depth }, shape2);
|
|
41300
42806
|
boardGeom = (0, import_transforms.translate)([0, 0, -depth / 2], boardGeom);
|
|
41301
42807
|
return boardGeom;
|
|
41302
42808
|
};
|
|
@@ -41619,19 +43125,19 @@ var platedHole = (plated_hole, ctx, options = {}) => {
|
|
|
41619
43125
|
const holeWidth = plated_hole.hole_width || 0;
|
|
41620
43126
|
const holeHeight = plated_hole.hole_height || 0;
|
|
41621
43127
|
const copperBody = (() => {
|
|
41622
|
-
const
|
|
43128
|
+
const circle2 = (0, import_primitives4.cylinder)({
|
|
41623
43129
|
center: [0, 0, 0],
|
|
41624
43130
|
radius: 1,
|
|
41625
43131
|
height: copperFillHeight,
|
|
41626
43132
|
segments: 64
|
|
41627
43133
|
// High segment count for smooth ellipse
|
|
41628
43134
|
});
|
|
41629
|
-
const scaled = (0, import_transforms3.scale)([outerWidth / 2, outerHeight / 2, 1],
|
|
43135
|
+
const scaled = (0, import_transforms3.scale)([outerWidth / 2, outerHeight / 2, 1], circle2);
|
|
41630
43136
|
return (0, import_transforms4.translate)([plated_hole.x, plated_hole.y, 0], scaled);
|
|
41631
43137
|
})();
|
|
41632
43138
|
const copperSolid = maybeClip(copperBody, clipGeom);
|
|
41633
43139
|
const drill = (() => {
|
|
41634
|
-
const
|
|
43140
|
+
const circle2 = (0, import_primitives4.cylinder)({
|
|
41635
43141
|
center: [0, 0, 0],
|
|
41636
43142
|
radius: 1,
|
|
41637
43143
|
height: throughDrillHeight,
|
|
@@ -41640,7 +43146,7 @@ var platedHole = (plated_hole, ctx, options = {}) => {
|
|
|
41640
43146
|
});
|
|
41641
43147
|
const scaled = (0, import_transforms3.scale)(
|
|
41642
43148
|
[Math.max(holeWidth / 2, 0.01), Math.max(holeHeight / 2, 0.01), 1],
|
|
41643
|
-
|
|
43149
|
+
circle2
|
|
41644
43150
|
);
|
|
41645
43151
|
return (0, import_transforms4.translate)([plated_hole.x, plated_hole.y, 0], scaled);
|
|
41646
43152
|
})();
|
|
@@ -42732,7 +44238,7 @@ var useBoardGeomBuilder = (circuitJson) => {
|
|
|
42732
44238
|
while (!isDone && !isCancelled) {
|
|
42733
44239
|
isDone = builder.step(1);
|
|
42734
44240
|
if (!isDone) {
|
|
42735
|
-
await new Promise((
|
|
44241
|
+
await new Promise((resolve2) => setTimeout(resolve2, 0));
|
|
42736
44242
|
}
|
|
42737
44243
|
}
|
|
42738
44244
|
if (!isCancelled) {
|
|
@@ -45619,524 +47125,6 @@ var CadViewerJscad = forwardRef3(
|
|
|
45619
47125
|
}
|
|
45620
47126
|
);
|
|
45621
47127
|
|
|
45622
|
-
// node_modules/earcut/src/earcut.js
|
|
45623
|
-
var steiners = /* @__PURE__ */ new Set();
|
|
45624
|
-
var filteredOut = false;
|
|
45625
|
-
function earcut(data, holeIndices, dim = 2) {
|
|
45626
|
-
const hasHoles = holeIndices && holeIndices.length;
|
|
45627
|
-
const outerLen = hasHoles ? holeIndices[0] * dim : data.length;
|
|
45628
|
-
if (steiners.size) steiners.clear();
|
|
45629
|
-
let outerNode = linkedList(data, 0, outerLen, dim, true);
|
|
45630
|
-
const triangles = [];
|
|
45631
|
-
if (!outerNode || outerNode.next === outerNode.prev) return triangles;
|
|
45632
|
-
let minX = 0, minY = 0, invSize = 0;
|
|
45633
|
-
if (hasHoles) outerNode = eliminateHoles(data, holeIndices, outerNode, dim);
|
|
45634
|
-
if (data.length > 80 * dim) {
|
|
45635
|
-
minX = data[0];
|
|
45636
|
-
minY = data[1];
|
|
45637
|
-
let maxX = minX;
|
|
45638
|
-
let maxY = minY;
|
|
45639
|
-
for (let i = dim; i < outerLen; i += dim) {
|
|
45640
|
-
const x = data[i];
|
|
45641
|
-
const y = data[i + 1];
|
|
45642
|
-
if (x < minX) minX = x;
|
|
45643
|
-
if (y < minY) minY = y;
|
|
45644
|
-
if (x > maxX) maxX = x;
|
|
45645
|
-
if (y > maxY) maxY = y;
|
|
45646
|
-
}
|
|
45647
|
-
invSize = Math.max(maxX - minX, maxY - minY);
|
|
45648
|
-
invSize = invSize !== 0 ? 32767 / invSize : 0;
|
|
45649
|
-
}
|
|
45650
|
-
earcutLinked(outerNode, triangles, minX, minY, invSize);
|
|
45651
|
-
return triangles;
|
|
45652
|
-
}
|
|
45653
|
-
function linkedList(data, start, end, dim, clockwise) {
|
|
45654
|
-
let last = null;
|
|
45655
|
-
if (clockwise === signedArea(data, start, end, dim) > 0) {
|
|
45656
|
-
for (let i = start; i < end; i += dim) last = insertNode(i / dim | 0, data[i], data[i + 1], last);
|
|
45657
|
-
} else {
|
|
45658
|
-
for (let i = end - dim; i >= start; i -= dim) last = insertNode(i / dim | 0, data[i], data[i + 1], last);
|
|
45659
|
-
}
|
|
45660
|
-
if (last && equals(last, last.next)) {
|
|
45661
|
-
removeNode(last);
|
|
45662
|
-
last = last.next;
|
|
45663
|
-
}
|
|
45664
|
-
return last;
|
|
45665
|
-
}
|
|
45666
|
-
function filterPoints(start, end = start) {
|
|
45667
|
-
const full = end === start;
|
|
45668
|
-
let p = start, again;
|
|
45669
|
-
do {
|
|
45670
|
-
again = false;
|
|
45671
|
-
if (p !== p.next && (steiners.size === 0 || !steiners.has(p)) && (equals(p, p.next) || area(p.prev, p, p.next) === 0)) {
|
|
45672
|
-
if (full || p === end) end = p.prev;
|
|
45673
|
-
filteredOut = true;
|
|
45674
|
-
removeNode(p);
|
|
45675
|
-
p = p.prev;
|
|
45676
|
-
again = true;
|
|
45677
|
-
} else if (full || p !== end) {
|
|
45678
|
-
p = p.next;
|
|
45679
|
-
again = !full;
|
|
45680
|
-
}
|
|
45681
|
-
} while (again || p !== end);
|
|
45682
|
-
return end;
|
|
45683
|
-
}
|
|
45684
|
-
function earcutLinked(ear, triangles, minX, minY, invSize) {
|
|
45685
|
-
if (invSize) indexCurve(ear, minX, minY, invSize);
|
|
45686
|
-
let stop = ear, cured = false;
|
|
45687
|
-
while (ear.prev !== ear.next) {
|
|
45688
|
-
const prev = ear.prev;
|
|
45689
|
-
const next = ear.next;
|
|
45690
|
-
if (area(prev, ear, next) < 0 && (invSize ? isEarHashed(ear, minX, minY, invSize) : isEar(ear))) {
|
|
45691
|
-
triangles.push(prev.i, ear.i, next.i);
|
|
45692
|
-
removeNode(ear);
|
|
45693
|
-
ear = next;
|
|
45694
|
-
stop = next;
|
|
45695
|
-
continue;
|
|
45696
|
-
}
|
|
45697
|
-
ear = next;
|
|
45698
|
-
if (ear === stop) {
|
|
45699
|
-
filteredOut = false;
|
|
45700
|
-
ear = filterPoints(ear);
|
|
45701
|
-
if (filteredOut) {
|
|
45702
|
-
stop = ear;
|
|
45703
|
-
continue;
|
|
45704
|
-
}
|
|
45705
|
-
if (!cured) {
|
|
45706
|
-
ear = cureLocalIntersections(ear, triangles);
|
|
45707
|
-
stop = ear;
|
|
45708
|
-
cured = true;
|
|
45709
|
-
continue;
|
|
45710
|
-
}
|
|
45711
|
-
splitEarcut(ear, triangles, minX, minY, invSize);
|
|
45712
|
-
break;
|
|
45713
|
-
}
|
|
45714
|
-
}
|
|
45715
|
-
}
|
|
45716
|
-
function isEar(ear) {
|
|
45717
|
-
const a = ear.prev, b = ear, c = ear.next, ax = a.x, bx = b.x, cx = c.x, ay = a.y, by = b.y, cy = c.y, x0 = Math.min(ax, bx, cx), y0 = Math.min(ay, by, cy), x1 = Math.max(ax, bx, cx), y1 = Math.max(ay, by, cy);
|
|
45718
|
-
let p = c.next;
|
|
45719
|
-
while (p !== a) {
|
|
45720
|
-
if (p.x >= x0 && p.x <= x1 && p.y >= y0 && p.y <= y1 && !(ax === p.x && ay === p.y) && pointInTriangle(ax, ay, bx, by, cx, cy, p.x, p.y) && area(p.prev, p, p.next) >= 0) return false;
|
|
45721
|
-
p = p.next;
|
|
45722
|
-
}
|
|
45723
|
-
return true;
|
|
45724
|
-
}
|
|
45725
|
-
function isEarHashed(ear, minX, minY, invSize) {
|
|
45726
|
-
const a = ear.prev, b = ear, c = ear.next, ax = a.x, bx = b.x, cx = c.x, ay = a.y, by = b.y, cy = c.y, x0 = Math.min(ax, bx, cx), y0 = Math.min(ay, by, cy), x1 = Math.max(ax, bx, cx), y1 = Math.max(ay, by, cy), minZ = zOrder(x0, y0, minX, minY, invSize), maxZ = zOrder(x1, y1, minX, minY, invSize);
|
|
45727
|
-
let p = ear.prevZ;
|
|
45728
|
-
while (p && p.z >= minZ) {
|
|
45729
|
-
if (p.x >= x0 && p.x <= x1 && p.y >= y0 && p.y <= y1 && p !== c && !(ax === p.x && ay === p.y) && pointInTriangle(ax, ay, bx, by, cx, cy, p.x, p.y) && area(p.prev, p, p.next) >= 0) return false;
|
|
45730
|
-
p = p.prevZ;
|
|
45731
|
-
}
|
|
45732
|
-
let n = ear.nextZ;
|
|
45733
|
-
while (n && n.z <= maxZ) {
|
|
45734
|
-
if (n.x >= x0 && n.x <= x1 && n.y >= y0 && n.y <= y1 && n !== c && !(ax === n.x && ay === n.y) && pointInTriangle(ax, ay, bx, by, cx, cy, n.x, n.y) && area(n.prev, n, n.next) >= 0) return false;
|
|
45735
|
-
n = n.nextZ;
|
|
45736
|
-
}
|
|
45737
|
-
return true;
|
|
45738
|
-
}
|
|
45739
|
-
function cureLocalIntersections(start, triangles) {
|
|
45740
|
-
let p = start;
|
|
45741
|
-
let cured = false;
|
|
45742
|
-
do {
|
|
45743
|
-
const a = p.prev, b = p.next.next;
|
|
45744
|
-
if (intersects(a, p, p.next, b, false) && locallyInside(a, b) && locallyInside(b, a)) {
|
|
45745
|
-
triangles.push(a.i, p.i, b.i);
|
|
45746
|
-
removeNode(p);
|
|
45747
|
-
removeNode(p.next);
|
|
45748
|
-
p = start = b;
|
|
45749
|
-
cured = true;
|
|
45750
|
-
}
|
|
45751
|
-
p = p.next;
|
|
45752
|
-
} while (p !== start);
|
|
45753
|
-
return cured ? filterPoints(p) : p;
|
|
45754
|
-
}
|
|
45755
|
-
function splitEarcut(start, triangles, minX, minY, invSize) {
|
|
45756
|
-
let a = start;
|
|
45757
|
-
do {
|
|
45758
|
-
let b = a.next.next;
|
|
45759
|
-
while (b !== a.prev) {
|
|
45760
|
-
if (a.i !== b.i && isValidDiagonal(a, b)) {
|
|
45761
|
-
let c = splitPolygon(a, b);
|
|
45762
|
-
a = filterPoints(a, a.next);
|
|
45763
|
-
c = filterPoints(c, c.next);
|
|
45764
|
-
earcutLinked(a, triangles, minX, minY, invSize);
|
|
45765
|
-
earcutLinked(c, triangles, minX, minY, invSize);
|
|
45766
|
-
return;
|
|
45767
|
-
}
|
|
45768
|
-
b = b.next;
|
|
45769
|
-
}
|
|
45770
|
-
a = a.next;
|
|
45771
|
-
} while (a !== start);
|
|
45772
|
-
}
|
|
45773
|
-
var indexActive = false;
|
|
45774
|
-
function eliminateHoles(data, holeIndices, outerNode, dim) {
|
|
45775
|
-
const queue = [];
|
|
45776
|
-
for (let i = 0, len = holeIndices.length; i < len; i++) {
|
|
45777
|
-
const start = holeIndices[i] * dim;
|
|
45778
|
-
const end = i < len - 1 ? holeIndices[i + 1] * dim : data.length;
|
|
45779
|
-
const list = (
|
|
45780
|
-
/** @type {Node} */
|
|
45781
|
-
linkedList(data, start, end, dim, false)
|
|
45782
|
-
);
|
|
45783
|
-
if (list === list.next) steiners.add(list);
|
|
45784
|
-
queue.push(getLeftmost(list));
|
|
45785
|
-
}
|
|
45786
|
-
queue.sort(compareXYSlope);
|
|
45787
|
-
buildBlockIndex(data.length / dim, holeIndices.length);
|
|
45788
|
-
indexSegment(outerNode, outerNode);
|
|
45789
|
-
indexActive = true;
|
|
45790
|
-
for (let i = 0; i < queue.length; i++) {
|
|
45791
|
-
outerNode = eliminateHole(queue[i], outerNode);
|
|
45792
|
-
}
|
|
45793
|
-
indexActive = false;
|
|
45794
|
-
return filterPoints(outerNode);
|
|
45795
|
-
}
|
|
45796
|
-
function compareXYSlope(a, b) {
|
|
45797
|
-
return a.x - b.x || a.y - b.y || (a.next.y - a.y) / (a.next.x - a.x) - (b.next.y - b.y) / (b.next.x - b.x);
|
|
45798
|
-
}
|
|
45799
|
-
function eliminateHole(hole, outerNode) {
|
|
45800
|
-
const bridge = findHoleBridge(hole, outerNode);
|
|
45801
|
-
if (!bridge) {
|
|
45802
|
-
return outerNode;
|
|
45803
|
-
}
|
|
45804
|
-
const bridgeReverse = splitPolygon(bridge, hole);
|
|
45805
|
-
const bridge2 = bridgeReverse.next;
|
|
45806
|
-
indexSegment(bridge, bridge2.next);
|
|
45807
|
-
filterPoints(bridgeReverse, bridgeReverse.next);
|
|
45808
|
-
return filterPoints(bridge, bridge.next);
|
|
45809
|
-
}
|
|
45810
|
-
var K = 16;
|
|
45811
|
-
var blockBBox = new Float64Array(0);
|
|
45812
|
-
var numBlocks = 0;
|
|
45813
|
-
var blockHead = [];
|
|
45814
|
-
var blockStop = [];
|
|
45815
|
-
function buildBlockIndex(maxNodes, numHoles) {
|
|
45816
|
-
const maxBlocks = Math.ceil((maxNodes + 2 * numHoles) / K) + numHoles + 2;
|
|
45817
|
-
if (blockBBox.length < maxBlocks * 4) blockBBox = new Float64Array(maxBlocks * 4);
|
|
45818
|
-
numBlocks = 0;
|
|
45819
|
-
}
|
|
45820
|
-
function indexSegment(head, stop) {
|
|
45821
|
-
let p = head;
|
|
45822
|
-
do {
|
|
45823
|
-
const b = numBlocks++;
|
|
45824
|
-
blockHead[b] = p;
|
|
45825
|
-
let minX = p.x, minY = p.y, maxX = p.x, maxY = p.y;
|
|
45826
|
-
let k = 0;
|
|
45827
|
-
do {
|
|
45828
|
-
const c = p.next;
|
|
45829
|
-
p.z = b;
|
|
45830
|
-
if (c.x < minX) minX = c.x;
|
|
45831
|
-
if (c.x > maxX) maxX = c.x;
|
|
45832
|
-
if (c.y < minY) minY = c.y;
|
|
45833
|
-
if (c.y > maxY) maxY = c.y;
|
|
45834
|
-
p = c;
|
|
45835
|
-
} while (++k < K && p !== stop);
|
|
45836
|
-
blockStop[b] = p;
|
|
45837
|
-
const g = b * 4;
|
|
45838
|
-
blockBBox[g] = minX;
|
|
45839
|
-
blockBBox[g + 1] = minY;
|
|
45840
|
-
blockBBox[g + 2] = maxX;
|
|
45841
|
-
blockBBox[g + 3] = maxY;
|
|
45842
|
-
} while (p !== stop);
|
|
45843
|
-
}
|
|
45844
|
-
function growBlock(head, tail) {
|
|
45845
|
-
const g = head.z * 4;
|
|
45846
|
-
if (tail.x < blockBBox[g]) blockBBox[g] = tail.x;
|
|
45847
|
-
if (tail.y < blockBBox[g + 1]) blockBBox[g + 1] = tail.y;
|
|
45848
|
-
if (tail.x > blockBBox[g + 2]) blockBBox[g + 2] = tail.x;
|
|
45849
|
-
if (tail.y > blockBBox[g + 3]) blockBBox[g + 3] = tail.y;
|
|
45850
|
-
}
|
|
45851
|
-
function liveBlockStop(b) {
|
|
45852
|
-
let stop = blockStop[b];
|
|
45853
|
-
while (stop.prev.next !== stop) stop = stop.next;
|
|
45854
|
-
blockStop[b] = stop;
|
|
45855
|
-
return stop;
|
|
45856
|
-
}
|
|
45857
|
-
function liveBlockHead(b) {
|
|
45858
|
-
let head = blockHead[b];
|
|
45859
|
-
while (head.prev.next !== head) head = head.next;
|
|
45860
|
-
blockHead[b] = head;
|
|
45861
|
-
return head;
|
|
45862
|
-
}
|
|
45863
|
-
function findHoleBridge(hole, outerNode) {
|
|
45864
|
-
let p = outerNode;
|
|
45865
|
-
const hx = hole.x;
|
|
45866
|
-
const hy = hole.y;
|
|
45867
|
-
let qx = -Infinity;
|
|
45868
|
-
let m;
|
|
45869
|
-
if (equals(hole, p)) return p;
|
|
45870
|
-
for (let b = 0, g = 0; b < numBlocks; b++, g += 4) {
|
|
45871
|
-
if (hy < blockBBox[g + 1] || hy > blockBBox[g + 3] || blockBBox[g] > hx || blockBBox[g + 2] <= qx) continue;
|
|
45872
|
-
const stop = liveBlockStop(b);
|
|
45873
|
-
p = liveBlockHead(b);
|
|
45874
|
-
do {
|
|
45875
|
-
if (p.prev.next === p) {
|
|
45876
|
-
if (equals(hole, p.next)) return p.next;
|
|
45877
|
-
else if (hy <= p.y && hy >= p.next.y && p.next.y !== p.y) {
|
|
45878
|
-
const x = p.x + (hy - p.y) * (p.next.x - p.x) / (p.next.y - p.y);
|
|
45879
|
-
if (x <= hx && x > qx) {
|
|
45880
|
-
qx = x;
|
|
45881
|
-
m = p.x < p.next.x ? p : p.next;
|
|
45882
|
-
if (x === hx) return m;
|
|
45883
|
-
}
|
|
45884
|
-
}
|
|
45885
|
-
}
|
|
45886
|
-
p = p.next;
|
|
45887
|
-
} while (p !== stop);
|
|
45888
|
-
}
|
|
45889
|
-
if (!m) return null;
|
|
45890
|
-
const mx = m.x;
|
|
45891
|
-
const my = m.y;
|
|
45892
|
-
const tminY = Math.min(hy, my);
|
|
45893
|
-
const tmaxY = Math.max(hy, my);
|
|
45894
|
-
let tanMin = Infinity;
|
|
45895
|
-
for (let b = 0, g = 0; b < numBlocks; b++, g += 4) {
|
|
45896
|
-
if (blockBBox[g + 2] < mx || blockBBox[g] > hx || blockBBox[g + 3] < tminY || blockBBox[g + 1] > tmaxY) continue;
|
|
45897
|
-
const stop = liveBlockStop(b);
|
|
45898
|
-
p = liveBlockHead(b);
|
|
45899
|
-
do {
|
|
45900
|
-
if (p.prev.next === p && hx >= p.x && p.x >= mx && hx !== p.x && // skip dead nodes
|
|
45901
|
-
pointInTriangle(hy < my ? hx : qx, hy, mx, my, hy < my ? qx : hx, hy, p.x, p.y)) {
|
|
45902
|
-
const tan = Math.abs(hy - p.y) / (hx - p.x);
|
|
45903
|
-
if ((locallyInside(p, hole) || p.y === hy && p.next.y === hy && p.next.x > hx) && (tan < tanMin || tan === tanMin && (p.x > m.x || p.x === m.x && sectorContainsSector(m, p)))) {
|
|
45904
|
-
m = p;
|
|
45905
|
-
tanMin = tan;
|
|
45906
|
-
}
|
|
45907
|
-
}
|
|
45908
|
-
p = p.next;
|
|
45909
|
-
} while (p !== stop);
|
|
45910
|
-
}
|
|
45911
|
-
return m;
|
|
45912
|
-
}
|
|
45913
|
-
function sectorContainsSector(m, p) {
|
|
45914
|
-
return area(m.prev, m, p.prev) < 0 && area(p.next, m, m.next) < 0;
|
|
45915
|
-
}
|
|
45916
|
-
var sortArr = [];
|
|
45917
|
-
var sortBuf = [];
|
|
45918
|
-
var zArr = new Uint32Array(0);
|
|
45919
|
-
var zBuf = new Uint32Array(0);
|
|
45920
|
-
var counts = new Uint32Array(256);
|
|
45921
|
-
function indexCurve(start, minX, minY, invSize) {
|
|
45922
|
-
let p = start;
|
|
45923
|
-
let n = 0;
|
|
45924
|
-
do {
|
|
45925
|
-
p.z = zOrder(p.x, p.y, minX, minY, invSize);
|
|
45926
|
-
sortArr[n++] = p;
|
|
45927
|
-
p = p.next;
|
|
45928
|
-
} while (p !== start);
|
|
45929
|
-
sortNodes(n);
|
|
45930
|
-
let prev = null;
|
|
45931
|
-
for (let i = 0; i < n; i++) {
|
|
45932
|
-
const node = sortArr[i];
|
|
45933
|
-
node.prevZ = prev;
|
|
45934
|
-
if (prev) prev.nextZ = node;
|
|
45935
|
-
prev = node;
|
|
45936
|
-
}
|
|
45937
|
-
prev.nextZ = null;
|
|
45938
|
-
sortArr.fill(
|
|
45939
|
-
/** @type {Node} */
|
|
45940
|
-
/** @type {unknown} */
|
|
45941
|
-
null,
|
|
45942
|
-
0,
|
|
45943
|
-
n
|
|
45944
|
-
);
|
|
45945
|
-
sortBuf.fill(
|
|
45946
|
-
/** @type {Node} */
|
|
45947
|
-
/** @type {unknown} */
|
|
45948
|
-
null,
|
|
45949
|
-
0,
|
|
45950
|
-
n
|
|
45951
|
-
);
|
|
45952
|
-
}
|
|
45953
|
-
function sortNodes(n) {
|
|
45954
|
-
if (n <= 32) {
|
|
45955
|
-
for (let i = 1; i < n; i++) {
|
|
45956
|
-
const node = sortArr[i], z42 = node.z;
|
|
45957
|
-
let j = i - 1;
|
|
45958
|
-
while (j >= 0 && sortArr[j].z > z42) {
|
|
45959
|
-
sortArr[j + 1] = sortArr[j];
|
|
45960
|
-
j--;
|
|
45961
|
-
}
|
|
45962
|
-
sortArr[j + 1] = node;
|
|
45963
|
-
}
|
|
45964
|
-
return;
|
|
45965
|
-
}
|
|
45966
|
-
if (zArr.length < n) {
|
|
45967
|
-
zArr = new Uint32Array(n);
|
|
45968
|
-
zBuf = new Uint32Array(n);
|
|
45969
|
-
sortBuf = new Array(n);
|
|
45970
|
-
}
|
|
45971
|
-
for (let i = 0; i < n; i++) zArr[i] = sortArr[i].z;
|
|
45972
|
-
radixPass(n, sortArr, zArr, sortBuf, zBuf, 0);
|
|
45973
|
-
radixPass(n, sortBuf, zBuf, sortArr, zArr, 8);
|
|
45974
|
-
radixPass(n, sortArr, zArr, sortBuf, zBuf, 16);
|
|
45975
|
-
radixPass(n, sortBuf, zBuf, sortArr, zArr, 24);
|
|
45976
|
-
}
|
|
45977
|
-
function radixPass(n, src, srcZ, dst, dstZ, shift4) {
|
|
45978
|
-
counts.fill(0);
|
|
45979
|
-
for (let i = 0; i < n; i++) counts[srcZ[i] >>> shift4 & 255]++;
|
|
45980
|
-
let sum = 0;
|
|
45981
|
-
for (let b = 0; b < 256; b++) {
|
|
45982
|
-
const c = counts[b];
|
|
45983
|
-
counts[b] = sum;
|
|
45984
|
-
sum += c;
|
|
45985
|
-
}
|
|
45986
|
-
for (let i = 0; i < n; i++) {
|
|
45987
|
-
const z42 = srcZ[i];
|
|
45988
|
-
const pos = counts[z42 >>> shift4 & 255]++;
|
|
45989
|
-
dst[pos] = src[i];
|
|
45990
|
-
dstZ[pos] = z42;
|
|
45991
|
-
}
|
|
45992
|
-
}
|
|
45993
|
-
function zOrder(x, y, minX, minY, invSize) {
|
|
45994
|
-
x = (x - minX) * invSize | 0;
|
|
45995
|
-
y = (y - minY) * invSize | 0;
|
|
45996
|
-
x = (x | x << 8) & 16711935;
|
|
45997
|
-
x = (x | x << 4) & 252645135;
|
|
45998
|
-
x = (x | x << 2) & 858993459;
|
|
45999
|
-
x = (x | x << 1) & 1431655765;
|
|
46000
|
-
y = (y | y << 8) & 16711935;
|
|
46001
|
-
y = (y | y << 4) & 252645135;
|
|
46002
|
-
y = (y | y << 2) & 858993459;
|
|
46003
|
-
y = (y | y << 1) & 1431655765;
|
|
46004
|
-
return x | y << 1;
|
|
46005
|
-
}
|
|
46006
|
-
function getLeftmost(start) {
|
|
46007
|
-
let p = start, leftmost = start;
|
|
46008
|
-
do {
|
|
46009
|
-
if (p.x < leftmost.x || p.x === leftmost.x && p.y < leftmost.y) leftmost = p;
|
|
46010
|
-
p = p.next;
|
|
46011
|
-
} while (p !== start);
|
|
46012
|
-
return leftmost;
|
|
46013
|
-
}
|
|
46014
|
-
function pointInTriangle(ax, ay, bx, by, cx, cy, px, py) {
|
|
46015
|
-
return (cx - px) * (ay - py) >= (ax - px) * (cy - py) && (ax - px) * (by - py) >= (bx - px) * (ay - py) && (bx - px) * (cy - py) >= (cx - px) * (by - py);
|
|
46016
|
-
}
|
|
46017
|
-
function isValidDiagonal(a, b) {
|
|
46018
|
-
const zeroLength = equals(a, b) && area(a.prev, a, a.next) > 0 && area(b.prev, b, b.next) > 0;
|
|
46019
|
-
return a.next.i !== b.i && (zeroLength || locallyInside(a, b) && locallyInside(b, a) && // // locally visible
|
|
46020
|
-
(area(a.prev, a, b.prev) !== 0 || area(a, b.prev, b) !== 0)) && // no opposite-facing sectors
|
|
46021
|
-
!intersectsPolygon(a, b) && (zeroLength || middleInside(a, b));
|
|
46022
|
-
}
|
|
46023
|
-
function area(p, q, r) {
|
|
46024
|
-
return (q.y - p.y) * (r.x - q.x) - (q.x - p.x) * (r.y - q.y);
|
|
46025
|
-
}
|
|
46026
|
-
function equals(p1, p2) {
|
|
46027
|
-
return p1.x === p2.x && p1.y === p2.y;
|
|
46028
|
-
}
|
|
46029
|
-
function intersects(p1, q1, p2, q2, includeBoundary = true) {
|
|
46030
|
-
const o1 = area(p1, q1, p2);
|
|
46031
|
-
const o2 = area(p1, q1, q2);
|
|
46032
|
-
const o3 = area(p2, q2, p1);
|
|
46033
|
-
const o4 = area(p2, q2, q1);
|
|
46034
|
-
if ((o1 > 0 && o2 < 0 || o1 < 0 && o2 > 0) && (o3 > 0 && o4 < 0 || o3 < 0 && o4 > 0)) return true;
|
|
46035
|
-
if (!includeBoundary) return false;
|
|
46036
|
-
if (o1 === 0 && onSegment2(p1, p2, q1)) return true;
|
|
46037
|
-
if (o2 === 0 && onSegment2(p1, q2, q1)) return true;
|
|
46038
|
-
if (o3 === 0 && onSegment2(p2, p1, q2)) return true;
|
|
46039
|
-
if (o4 === 0 && onSegment2(p2, q1, q2)) return true;
|
|
46040
|
-
return false;
|
|
46041
|
-
}
|
|
46042
|
-
function onSegment2(p, q, r) {
|
|
46043
|
-
return q.x <= Math.max(p.x, r.x) && q.x >= Math.min(p.x, r.x) && q.y <= Math.max(p.y, r.y) && q.y >= Math.min(p.y, r.y);
|
|
46044
|
-
}
|
|
46045
|
-
function intersectsPolygon(a, b) {
|
|
46046
|
-
const minX = Math.min(a.x, b.x);
|
|
46047
|
-
const maxX = Math.max(a.x, b.x);
|
|
46048
|
-
const minY = Math.min(a.y, b.y);
|
|
46049
|
-
const maxY = Math.max(a.y, b.y);
|
|
46050
|
-
let p = a;
|
|
46051
|
-
do {
|
|
46052
|
-
const n = p.next;
|
|
46053
|
-
if (p.x > maxX && n.x > maxX || p.x < minX && n.x < minX || p.y > maxY && n.y > maxY || p.y < minY && n.y < minY) {
|
|
46054
|
-
p = n;
|
|
46055
|
-
continue;
|
|
46056
|
-
}
|
|
46057
|
-
if (p.i !== a.i && n.i !== a.i && p.i !== b.i && n.i !== b.i && intersects(p, n, a, b)) return true;
|
|
46058
|
-
p = n;
|
|
46059
|
-
} while (p !== a);
|
|
46060
|
-
return false;
|
|
46061
|
-
}
|
|
46062
|
-
function locallyInside(a, b) {
|
|
46063
|
-
return area(a.prev, a, a.next) < 0 ? area(a, b, a.next) >= 0 && area(a, a.prev, b) >= 0 : area(a, b, a.prev) < 0 || area(a, a.next, b) < 0;
|
|
46064
|
-
}
|
|
46065
|
-
function middleInside(a, b) {
|
|
46066
|
-
let p = a;
|
|
46067
|
-
let inside = false;
|
|
46068
|
-
const px = (a.x + b.x) / 2;
|
|
46069
|
-
const py = (a.y + b.y) / 2;
|
|
46070
|
-
do {
|
|
46071
|
-
const n = p.next;
|
|
46072
|
-
if (p.y > py !== n.y > py && px < (n.x - p.x) * (py - p.y) / (n.y - p.y) + p.x)
|
|
46073
|
-
inside = !inside;
|
|
46074
|
-
p = n;
|
|
46075
|
-
} while (p !== a);
|
|
46076
|
-
return inside;
|
|
46077
|
-
}
|
|
46078
|
-
function splitPolygon(a, b) {
|
|
46079
|
-
const a2 = createNode(a.i, a.x, a.y), b2 = createNode(b.i, b.x, b.y), an = a.next, bp = b.prev;
|
|
46080
|
-
a.next = b;
|
|
46081
|
-
b.prev = a;
|
|
46082
|
-
a2.next = an;
|
|
46083
|
-
an.prev = a2;
|
|
46084
|
-
b2.next = a2;
|
|
46085
|
-
a2.prev = b2;
|
|
46086
|
-
bp.next = b2;
|
|
46087
|
-
b2.prev = bp;
|
|
46088
|
-
return b2;
|
|
46089
|
-
}
|
|
46090
|
-
function insertNode(i, x, y, last) {
|
|
46091
|
-
const p = createNode(i, x, y);
|
|
46092
|
-
if (!last) {
|
|
46093
|
-
p.prev = p;
|
|
46094
|
-
p.next = p;
|
|
46095
|
-
} else {
|
|
46096
|
-
p.next = last.next;
|
|
46097
|
-
p.prev = last;
|
|
46098
|
-
last.next.prev = p;
|
|
46099
|
-
last.next = p;
|
|
46100
|
-
}
|
|
46101
|
-
return p;
|
|
46102
|
-
}
|
|
46103
|
-
function removeNode(p) {
|
|
46104
|
-
p.next.prev = p.prev;
|
|
46105
|
-
p.prev.next = p.next;
|
|
46106
|
-
if (p.prevZ) p.prevZ.nextZ = p.nextZ;
|
|
46107
|
-
if (p.nextZ) p.nextZ.prevZ = p.prevZ;
|
|
46108
|
-
if (indexActive) growBlock(p.prev, p.next);
|
|
46109
|
-
}
|
|
46110
|
-
function createNode(i, x, y) {
|
|
46111
|
-
return (
|
|
46112
|
-
/** @type {Node} */
|
|
46113
|
-
/** @type {unknown} */
|
|
46114
|
-
{
|
|
46115
|
-
i,
|
|
46116
|
-
// vertex index in coordinates array
|
|
46117
|
-
x,
|
|
46118
|
-
y,
|
|
46119
|
-
// vertex coordinates
|
|
46120
|
-
prev: null,
|
|
46121
|
-
// previous and next vertex nodes in a polygon ring
|
|
46122
|
-
next: null,
|
|
46123
|
-
z: 0,
|
|
46124
|
-
// z-order curve value; doubles as owning block in the hole-bridge index during eliminateHoles
|
|
46125
|
-
prevZ: null,
|
|
46126
|
-
// previous and next nodes in z-order
|
|
46127
|
-
nextZ: null
|
|
46128
|
-
}
|
|
46129
|
-
);
|
|
46130
|
-
}
|
|
46131
|
-
function signedArea(data, start, end, dim) {
|
|
46132
|
-
let sum = 0;
|
|
46133
|
-
for (let i = start, j = end - dim; i < end; i += dim) {
|
|
46134
|
-
sum += (data[j] - data[i]) * (data[i + 1] + data[j + 1]);
|
|
46135
|
-
j = i;
|
|
46136
|
-
}
|
|
46137
|
-
return sum;
|
|
46138
|
-
}
|
|
46139
|
-
|
|
46140
47128
|
// node_modules/@tscircuit/flex-utils/dist/index.js
|
|
46141
47129
|
var EPS = 1e-7;
|
|
46142
47130
|
function createPcbFold(records, thickness) {
|
|
@@ -46313,7 +47301,7 @@ function foldSurfaceMesh(mesh, fold) {
|
|
|
46313
47301
|
};
|
|
46314
47302
|
const triangles = [];
|
|
46315
47303
|
for (const triangle of mesh.triangles) {
|
|
46316
|
-
const
|
|
47304
|
+
const face2 = triangle.pcbFace ?? (triangle.normal.z > 0.8 ? "top" : triangle.normal.z < -0.8 ? "bottom" : "side");
|
|
46317
47305
|
let polygons = [
|
|
46318
47306
|
triangle.vertices.map((p, index2) => ({
|
|
46319
47307
|
p,
|
|
@@ -46356,7 +47344,7 @@ function foldSurfaceMesh(mesh, fold) {
|
|
|
46356
47344
|
...triangle,
|
|
46357
47345
|
vertices,
|
|
46358
47346
|
normal: { x: n.x / l, y: n.y / l, z: n.z / l },
|
|
46359
|
-
pcbFace:
|
|
47347
|
+
pcbFace: face2,
|
|
46360
47348
|
uvs: verts.map(({ uv }) => uv)
|
|
46361
47349
|
});
|
|
46362
47350
|
}
|
|
@@ -46370,12 +47358,12 @@ var axes = [
|
|
|
46370
47358
|
{ x: 0, y: 0, z: 1 }
|
|
46371
47359
|
];
|
|
46372
47360
|
function rotateVector(v, degrees) {
|
|
46373
|
-
const [x, y,
|
|
47361
|
+
const [x, y, z27] = [degrees.x, degrees.y, degrees.z].map(
|
|
46374
47362
|
(a2) => a2 * Math.PI / 180
|
|
46375
47363
|
);
|
|
46376
47364
|
const a = {
|
|
46377
|
-
x: Math.cos(
|
|
46378
|
-
y: Math.sin(
|
|
47365
|
+
x: Math.cos(z27) * v.x - Math.sin(z27) * v.y,
|
|
47366
|
+
y: Math.sin(z27) * v.x + Math.cos(z27) * v.y,
|
|
46379
47367
|
z: v.z
|
|
46380
47368
|
};
|
|
46381
47369
|
const b = {
|
|
@@ -47195,8 +48183,8 @@ function processPlatedHolesForManifold(Manifold, CrossSection, circuitJson, pcbT
|
|
|
47195
48183
|
depth,
|
|
47196
48184
|
sizeDelta = 0
|
|
47197
48185
|
}) => {
|
|
47198
|
-
const
|
|
47199
|
-
if (
|
|
48186
|
+
const shape2 = ph.shape;
|
|
48187
|
+
if (shape2 !== "hole_with_polygon_pad") {
|
|
47200
48188
|
return null;
|
|
47201
48189
|
}
|
|
47202
48190
|
const padOutline = ph.pad_outline;
|
|
@@ -56711,7 +57699,7 @@ function createGeometryFromPolygons(polygons) {
|
|
|
56711
57699
|
}
|
|
56712
57700
|
|
|
56713
57701
|
// src/utils/render-component.tsx
|
|
56714
|
-
var
|
|
57702
|
+
var import_modeling4 = __toESM(require_src(), 1);
|
|
56715
57703
|
var import_jscad_planner2 = __toESM(require_dist(), 1);
|
|
56716
57704
|
var jscadModeling2 = __toESM(require_src(), 1);
|
|
56717
57705
|
import * as THREE57 from "three";
|
|
@@ -56774,7 +57762,7 @@ async function renderComponent(component, scene) {
|
|
|
56774
57762
|
}
|
|
56775
57763
|
if (component.model_jscad) {
|
|
56776
57764
|
const jscadObject = (0, import_jscad_planner2.executeJscadOperations)(
|
|
56777
|
-
|
|
57765
|
+
import_modeling4.default,
|
|
56778
57766
|
component.model_jscad
|
|
56779
57767
|
);
|
|
56780
57768
|
if (jscadObject && (jscadObject.polygons || jscadObject.sides)) {
|
|
@@ -56996,7 +57984,7 @@ function useExportGltfUrl(options = {}) {
|
|
|
56996
57984
|
function useParser(options = {}) {
|
|
56997
57985
|
const exporter = useMemo34(() => new GLTFExporter3(), []);
|
|
56998
57986
|
return (instance) => {
|
|
56999
|
-
const { promise, resolve, reject } = Promise.withResolvers();
|
|
57987
|
+
const { promise, resolve: resolve2, reject } = Promise.withResolvers();
|
|
57000
57988
|
exporter.parse(
|
|
57001
57989
|
instance,
|
|
57002
57990
|
(gltf) => {
|
|
@@ -57005,7 +57993,7 @@ function useParser(options = {}) {
|
|
|
57005
57993
|
[gltf instanceof ArrayBuffer ? gltf : JSON.stringify(gltf)],
|
|
57006
57994
|
{ type: `model/${type}` }
|
|
57007
57995
|
);
|
|
57008
|
-
|
|
57996
|
+
resolve2(URL.createObjectURL(blob));
|
|
57009
57997
|
},
|
|
57010
57998
|
reject,
|
|
57011
57999
|
options
|