jscad-electronics 0.0.232 → 0.0.234

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 CHANGED
@@ -748,7 +748,7 @@ var Crystal = ({
748
748
  ] });
749
749
  };
750
750
 
751
- // .model-contracts/generations/324045ff5a8d957b84ad80e3a428461bb10e4259-v2/node_modules/zod/v3/external.js
751
+ // .model-contracts/generations/7589222ca6923bdb21f6d28a9083a9e802799a62-v2/node_modules/zod/v3/external.js
752
752
  var external_exports = {};
753
753
  __export(external_exports, {
754
754
  BRAND: () => BRAND,
@@ -860,7 +860,7 @@ __export(external_exports, {
860
860
  void: () => voidType
861
861
  });
862
862
 
863
- // .model-contracts/generations/324045ff5a8d957b84ad80e3a428461bb10e4259-v2/node_modules/zod/v3/helpers/util.js
863
+ // .model-contracts/generations/7589222ca6923bdb21f6d28a9083a9e802799a62-v2/node_modules/zod/v3/helpers/util.js
864
864
  var util;
865
865
  (function(util2) {
866
866
  util2.assertEqual = (_) => {
@@ -994,7 +994,7 @@ var getParsedType = (data) => {
994
994
  }
995
995
  };
996
996
 
997
- // .model-contracts/generations/324045ff5a8d957b84ad80e3a428461bb10e4259-v2/node_modules/zod/v3/ZodError.js
997
+ // .model-contracts/generations/7589222ca6923bdb21f6d28a9083a9e802799a62-v2/node_modules/zod/v3/ZodError.js
998
998
  var ZodIssueCode = util.arrayToEnum([
999
999
  "invalid_type",
1000
1000
  "invalid_literal",
@@ -1112,7 +1112,7 @@ ZodError.create = (issues) => {
1112
1112
  return error;
1113
1113
  };
1114
1114
 
1115
- // .model-contracts/generations/324045ff5a8d957b84ad80e3a428461bb10e4259-v2/node_modules/zod/v3/locales/en.js
1115
+ // .model-contracts/generations/7589222ca6923bdb21f6d28a9083a9e802799a62-v2/node_modules/zod/v3/locales/en.js
1116
1116
  var errorMap = (issue, _ctx) => {
1117
1117
  let message;
1118
1118
  switch (issue.code) {
@@ -1215,7 +1215,7 @@ var errorMap = (issue, _ctx) => {
1215
1215
  };
1216
1216
  var en_default = errorMap;
1217
1217
 
1218
- // .model-contracts/generations/324045ff5a8d957b84ad80e3a428461bb10e4259-v2/node_modules/zod/v3/errors.js
1218
+ // .model-contracts/generations/7589222ca6923bdb21f6d28a9083a9e802799a62-v2/node_modules/zod/v3/errors.js
1219
1219
  var overrideErrorMap = en_default;
1220
1220
  function setErrorMap(map) {
1221
1221
  overrideErrorMap = map;
@@ -1224,7 +1224,7 @@ function getErrorMap() {
1224
1224
  return overrideErrorMap;
1225
1225
  }
1226
1226
 
1227
- // .model-contracts/generations/324045ff5a8d957b84ad80e3a428461bb10e4259-v2/node_modules/zod/v3/helpers/parseUtil.js
1227
+ // .model-contracts/generations/7589222ca6923bdb21f6d28a9083a9e802799a62-v2/node_modules/zod/v3/helpers/parseUtil.js
1228
1228
  var makeIssue = (params) => {
1229
1229
  const { data, path, errorMaps, issueData } = params;
1230
1230
  const fullPath = [...path, ...issueData.path || []];
@@ -1334,14 +1334,14 @@ var isDirty = (x) => x.status === "dirty";
1334
1334
  var isValid = (x) => x.status === "valid";
1335
1335
  var isAsync = (x) => typeof Promise !== "undefined" && x instanceof Promise;
1336
1336
 
1337
- // .model-contracts/generations/324045ff5a8d957b84ad80e3a428461bb10e4259-v2/node_modules/zod/v3/helpers/errorUtil.js
1337
+ // .model-contracts/generations/7589222ca6923bdb21f6d28a9083a9e802799a62-v2/node_modules/zod/v3/helpers/errorUtil.js
1338
1338
  var errorUtil;
1339
1339
  (function(errorUtil2) {
1340
1340
  errorUtil2.errToObj = (message) => typeof message === "string" ? { message } : message || {};
1341
1341
  errorUtil2.toString = (message) => typeof message === "string" ? message : message?.message;
1342
1342
  })(errorUtil || (errorUtil = {}));
1343
1343
 
1344
- // .model-contracts/generations/324045ff5a8d957b84ad80e3a428461bb10e4259-v2/node_modules/zod/v3/types.js
1344
+ // .model-contracts/generations/7589222ca6923bdb21f6d28a9083a9e802799a62-v2/node_modules/zod/v3/types.js
1345
1345
  var ParseInputLazyPath = class {
1346
1346
  constructor(parent, value, path, key) {
1347
1347
  this._cachedPath = [];
@@ -4789,7 +4789,7 @@ var coerce = {
4789
4789
  };
4790
4790
  var NEVER = INVALID;
4791
4791
 
4792
- // .model-contracts/generations/324045ff5a8d957b84ad80e3a428461bb10e4259-v2/node_modules/@tscircuit/mm/dist/index.js
4792
+ // .model-contracts/generations/7589222ca6923bdb21f6d28a9083a9e802799a62-v2/node_modules/@tscircuit/mm/dist/index.js
4793
4793
  var unitToMm = {
4794
4794
  in: 25.4,
4795
4795
  inch: 25.4,
@@ -4816,9 +4816,9 @@ var mm = (n) => {
4816
4816
  throw new Error(`Unsupported unit: ${unit}`);
4817
4817
  };
4818
4818
 
4819
- // .model-contracts/generations/324045ff5a8d957b84ad80e3a428461bb10e4259-v2/index.js
4819
+ // .model-contracts/generations/7589222ca6923bdb21f6d28a9083a9e802799a62-v2/index.js
4820
4820
  function normalizeNemaMotorModelString(value) {
4821
- if (!/^nema(?:8|17|23)(?:_|$)/i.test(value)) return value;
4821
+ if (!/^nema(?:8|17|23|34)(?:_|$)/i.test(value)) return value;
4822
4822
  return value.replace(/(^|_)jst([0-9]+)_(ph|sh)(?=_|$)/gi, "$1jst$3$2").replace(/(^|_)jst[_-](ph|sh)[_-]([0-9]+)(?=_|$)/gi, "$1jst$2$3").replace(/(^|_)none(?=_|$)/gi, "$1nowires").replace(/(^|_)stubs(?=_|$)/gi, "$1wirestubs");
4823
4823
  }
4824
4824
  function splitModelStringTokens(value) {
@@ -5507,7 +5507,8 @@ var hexSocketBoltModelDefinitionSchema = external_exports.object({
5507
5507
  var nemaSizeSchema = external_exports.union([
5508
5508
  external_exports.literal(8),
5509
5509
  external_exports.literal(17),
5510
- external_exports.literal(23)
5510
+ external_exports.literal(23),
5511
+ external_exports.literal(34)
5511
5512
  ]);
5512
5513
  var nemaMotorDimensions = {
5513
5514
  8: {
@@ -5575,6 +5576,31 @@ var nemaMotorDimensions = {
5575
5576
  rearCapLength: 5,
5576
5577
  faceCornerChamfer: 2,
5577
5578
  bodyCornerChamfer: 15
5579
+ },
5580
+ 34: {
5581
+ // Illustrative rear details; independent of the mounting flange.
5582
+ backFaceHoleSpacing: 40,
5583
+ rearCornerChamfer: 24,
5584
+ backFaceScrewSize: "M5",
5585
+ backFaceHoleDepth: 6,
5586
+ bodyWidth: 86,
5587
+ bodyLength: 80,
5588
+ mountingHoleSpacing: 69.6,
5589
+ mountingHoleDiameter: 6.5,
5590
+ mountingHoleDepth: 10,
5591
+ mountingHoleThrough: true,
5592
+ pilotDiameter: 73,
5593
+ pilotLength: 1.6,
5594
+ shaftDiameter: 14,
5595
+ shaftLength: 32,
5596
+ shaftShape: "round",
5597
+ shaftFlatDepth: 0.5,
5598
+ shaftFlatLength: 15,
5599
+ shaftFlatAngle: 0,
5600
+ frontCapLength: 10,
5601
+ rearCapLength: 8,
5602
+ faceCornerChamfer: 2,
5603
+ bodyCornerChamfer: 24
5578
5604
  }
5579
5605
  };
5580
5606
  var shape3 = {
@@ -5613,7 +5639,10 @@ var shape3 = {
5613
5639
  frontCapLength: positiveModelLengthSchema.optional(),
5614
5640
  rearCapLength: positiveModelLengthSchema.optional(),
5615
5641
  faceCornerChamfer: nonnegativeModelLengthSchema.optional(),
5616
- bodyCornerChamfer: nonnegativeModelLengthSchema.optional()
5642
+ bodyCornerChamfer: nonnegativeModelLengthSchema.optional(),
5643
+ /** Rear outline is independent of the front mounting flange. */
5644
+ rearCornerChamfer: nonnegativeModelLengthSchema.optional(),
5645
+ cornerProfile: external_exports.enum(["chamfered", "stepped"]).optional()
5617
5646
  };
5618
5647
  var resolve = (p) => {
5619
5648
  const d = nemaMotorDimensions[p.nemaSize];
@@ -5622,12 +5651,12 @@ var resolve = (p) => {
5622
5651
  return {
5623
5652
  nemaSize: p.nemaSize,
5624
5653
  wireConnection: p.wireConnection ?? "stubs",
5625
- wireSideAngle: ((p.wireSideAngle ?? 0) % 360 + 360) % 360,
5626
- wireLength: p.wireLength ?? 6,
5627
- wireDiameter: p.wireDiameter ?? 1.2,
5654
+ wireSideAngle: ((p.wireSideAngle ?? (p.nemaSize === 34 ? 90 : 0)) % 360 + 360) % 360,
5655
+ wireLength: p.wireLength ?? (p.nemaSize === 34 ? 25 : 6),
5656
+ wireDiameter: p.wireDiameter ?? (p.nemaSize === 34 ? 2 : 1.2),
5628
5657
  wireCount: p.wireCount ?? 4,
5629
- backFace: p.backFace ?? "screws",
5630
- backFaceHoleSpacing: p.backFaceHoleSpacing ?? p.mountingHoleSpacing ?? d.mountingHoleSpacing,
5658
+ backFace: p.backFace ?? (p.nemaSize === 34 ? "plain" : "screws"),
5659
+ backFaceHoleSpacing: p.backFaceHoleSpacing ?? ("backFaceHoleSpacing" in d ? d.backFaceHoleSpacing : p.mountingHoleSpacing ?? d.mountingHoleSpacing),
5631
5660
  backFaceHoleDiameter: p.backFaceHoleDiameter ?? screw.diameter,
5632
5661
  backFaceHoleDepth: p.backFaceHoleDepth ?? d.backFaceHoleDepth,
5633
5662
  backFaceScrewSize,
@@ -5648,17 +5677,23 @@ var resolve = (p) => {
5648
5677
  frontCapLength: p.frontCapLength ?? d.frontCapLength,
5649
5678
  rearCapLength: p.rearCapLength ?? d.rearCapLength,
5650
5679
  faceCornerChamfer: p.faceCornerChamfer ?? d.faceCornerChamfer,
5651
- bodyCornerChamfer: p.bodyCornerChamfer ?? d.bodyCornerChamfer
5680
+ bodyCornerChamfer: p.bodyCornerChamfer ?? d.bodyCornerChamfer,
5681
+ ...p.nemaSize === 34 || p.cornerProfile !== void 0 ? { cornerProfile: p.cornerProfile ?? "stepped" } : {},
5682
+ ..."rearCornerChamfer" in d || p.rearCornerChamfer !== void 0 ? {
5683
+ rearCornerChamfer: p.rearCornerChamfer ?? ("rearCornerChamfer" in d ? d.rearCornerChamfer : p.faceCornerChamfer ?? d.faceCornerChamfer)
5684
+ } : {}
5652
5685
  };
5653
5686
  };
5654
5687
  var validate3 = (p, ctx) => {
5655
5688
  const issue = (message) => ctx.addIssue({ code: "custom", message });
5689
+ const rearChamfer = p.rearCornerChamfer ?? (p.backFace === "plain" && p.mountingHoleThrough ? p.bodyCornerChamfer : p.faceCornerChamfer);
5690
+ const rearEdge = p.cornerProfile === "stepped" ? rearChamfer / Math.SQRT2 : rearChamfer;
5656
5691
  if (p.backFace !== "plain") {
5657
5692
  const screw = hexSocketBoltDimensions[p.backFaceScrewSize];
5658
5693
  const radius = (p.backFace === "screws" ? Math.max(p.backFaceHoleDiameter, screw.headDiameter) : p.backFaceHoleDiameter) / 2;
5659
5694
  if (p.backFaceHoleSpacing <= 2 * radius)
5660
5695
  issue("Rear holes and screw heads must not overlap each other");
5661
- if (p.backFaceHoleSpacing + 2 * radius >= p.bodyWidth || p.bodyWidth - p.faceCornerChamfer - p.backFaceHoleSpacing <= radius * Math.SQRT2)
5696
+ if (p.backFaceHoleSpacing + 2 * radius >= p.bodyWidth || (p.cornerProfile === "stepped" ? p.backFaceHoleSpacing + 2 * radius >= p.bodyWidth - 2 * rearEdge : p.bodyWidth - rearChamfer - p.backFaceHoleSpacing <= radius * Math.SQRT2))
5662
5697
  issue("Rear holes and screw heads must fit entirely inside the rear face");
5663
5698
  if (p.backFaceHoleDepth >= p.rearCapLength)
5664
5699
  issue("Rear hole depth must be less than the rear cap length");
@@ -5666,18 +5701,18 @@ var validate3 = (p, ctx) => {
5666
5701
  issue("Rear holes must accommodate the screw diameter");
5667
5702
  }
5668
5703
  if (p.wireConnection === "stubs") {
5669
- if (p.wireDiameter * p.wireCount * 1.5 > p.bodyWidth - 2 * p.faceCornerChamfer)
5704
+ if (p.wireDiameter * p.wireCount * 1.5 > p.bodyWidth - 2 * rearEdge)
5670
5705
  issue("Wire bundle must fit on the cap side");
5671
5706
  if (p.wireDiameter >= p.rearCapLength)
5672
5707
  issue("Wire diameter must fit within the rear cap");
5673
5708
  }
5674
5709
  const connector = getJstMotorConnector(p.wireConnection);
5675
- if (connector && p.bodyWidth - 2 * p.faceCornerChamfer < connector.bodyWidth)
5710
+ if (connector && p.bodyWidth - 2 * rearEdge < connector.bodyWidth)
5676
5711
  issue("JST header must fit on the motor side");
5677
5712
  const r = p.mountingHoleDiameter / 2;
5678
5713
  if (p.frontCapLength + p.rearCapLength >= p.bodyLength)
5679
5714
  issue("End caps must leave a positive body length");
5680
- if (p.faceCornerChamfer >= p.bodyWidth / 2 || p.bodyCornerChamfer >= p.bodyWidth / 2)
5715
+ if (p.faceCornerChamfer >= p.bodyWidth / 2 || p.bodyCornerChamfer >= p.bodyWidth / 2 || rearChamfer >= p.bodyWidth / 2)
5681
5716
  issue("Chamfer must be smaller than half the body width");
5682
5717
  if (p.mountingHoleSpacing + 2 * r >= p.bodyWidth || p.bodyWidth - p.faceCornerChamfer - p.mountingHoleSpacing <= r * Math.SQRT2)
5683
5718
  issue("Mounting holes must fit entirely inside the front face");
@@ -5689,7 +5724,7 @@ var validate3 = (p, ctx) => {
5689
5724
  issue("Mounting holes must clear the pilot");
5690
5725
  if (!p.mountingHoleThrough && p.mountingHoleDepth >= p.frontCapLength)
5691
5726
  issue("Blind mounting hole depth must be less than the front cap length");
5692
- if (p.mountingHoleThrough && p.bodyWidth - p.bodyCornerChamfer - p.mountingHoleSpacing >= -r * Math.SQRT2)
5727
+ if (p.mountingHoleThrough && (p.cornerProfile === "stepped" ? p.bodyWidth / 2 - p.bodyCornerChamfer / Math.SQRT2 + Math.min(4, p.bodyCornerChamfer / Math.SQRT2 / 4) >= p.mountingHoleSpacing / 2 - r : p.bodyWidth - p.bodyCornerChamfer - p.mountingHoleSpacing >= -r * Math.SQRT2))
5693
5728
  issue("Body must clear through front mounting holes");
5694
5729
  if (p.shaftLength <= p.pilotLength)
5695
5730
  issue("Shaft tip must extend beyond the pilot");
@@ -5722,12 +5757,13 @@ var lengths2 = {
5722
5757
  frontcap: "frontCapLength",
5723
5758
  rearcap: "rearCapLength",
5724
5759
  facechamfer: "faceCornerChamfer",
5725
- bodychamfer: "bodyCornerChamfer"
5760
+ bodychamfer: "bodyCornerChamfer",
5761
+ rearchamfer: "rearCornerChamfer"
5726
5762
  };
5727
5763
  function parseNemaMotorModelParams(raw) {
5728
5764
  const tokens = normalizeNemaMotorModelString(raw.string).split("_");
5729
- const match = tokens[0]?.match(/^nema(8|17|23)$/i);
5730
- if (!match) throw new Error("Expected nema8, nema17 or nema23");
5765
+ const match = tokens[0]?.match(/^nema(8|17|23|34)$/i);
5766
+ if (!match) throw new Error("Expected nema8, nema17, nema23 or nema34");
5731
5767
  const props = {
5732
5768
  fn: "nema",
5733
5769
  nemaSize: Number(match[1])
@@ -5750,6 +5786,10 @@ function parseNemaMotorModelParams(raw) {
5750
5786
  throw new Error(`Invalid wire connection token "${token}"`);
5751
5787
  property = "wireConnection";
5752
5788
  parsed = isJst ? `jst-${name.slice(3)}-${value}` : name === "nowires" ? "none" : "stubs";
5789
+ } else if (name === "stepped" || name === "chamfered") {
5790
+ if (value) throw new Error(`NEMA flag "${name}" does not accept a value`);
5791
+ property = "cornerProfile";
5792
+ parsed = name;
5753
5793
  } else if (name === "wirecount") {
5754
5794
  property = "wireCount";
5755
5795
  if (!/^\d+$/.test(value)) throw new Error("wirecount requires an integer");
@@ -12360,10 +12400,32 @@ function getNemaMotorReferencePoints(input) {
12360
12400
  const p = nemaMotorModelPropsSchema.parse(input);
12361
12401
  const radians = p.wireSideAngle * Math.PI / 180;
12362
12402
  const x = Math.cos(radians), y = Math.sin(radians);
12363
- const radius = Math.min(
12403
+ let radius = Math.min(
12364
12404
  p.bodyWidth / 2 / Math.max(Math.abs(x), Math.abs(y)),
12365
12405
  (p.bodyWidth - p.faceCornerChamfer) / (Math.abs(x) + Math.abs(y))
12366
12406
  );
12407
+ if (p.nemaSize === 34 && p.cornerProfile === "stepped") {
12408
+ const h = p.bodyWidth / 2, c = p.bodyCornerChamfer / Math.SQRT2, r = Math.min(4, c / 4);
12409
+ const contains = (distance2) => {
12410
+ const a = Math.abs(distance2 * x), b = Math.abs(distance2 * y);
12411
+ if (a > h || b > h) return false;
12412
+ if (c === 0) return true;
12413
+ if (a > h - c && b > h - c)
12414
+ return a <= h - c + r && b <= h - c + r && Math.hypot(a - (h - c + r), b - (h - c + r)) >= r;
12415
+ if (b > h - r && a > h - c - r)
12416
+ return Math.hypot(a - (h - c - r), b - (h - r)) <= r;
12417
+ if (a > h - r && b > h - c - r)
12418
+ return Math.hypot(a - (h - r), b - (h - c - r)) <= r;
12419
+ return true;
12420
+ };
12421
+ let low = 0, high = p.bodyWidth;
12422
+ for (let i = 0; i < 50; i++) {
12423
+ const mid = (low + high) / 2;
12424
+ if (contains(mid)) low = mid;
12425
+ else high = mid;
12426
+ }
12427
+ radius = low;
12428
+ }
12367
12429
  const flatRadians = p.shaftFlatAngle * Math.PI / 180;
12368
12430
  return {
12369
12431
  frontface: {
@@ -12382,7 +12444,7 @@ function getNemaMotorReferencePoints(input) {
12382
12444
  position: {
12383
12445
  x: radius * x,
12384
12446
  y: radius * y,
12385
- z: -p.bodyLength + p.rearCapLength / 2
12447
+ z: p.nemaSize === 34 ? -p.bodyLength + p.rearCapLength + 3 : -p.bodyLength + p.rearCapLength / 2
12386
12448
  },
12387
12449
  direction: { x, y, z: 0 }
12388
12450
  },
@@ -16537,11 +16599,66 @@ function register71(registry2) {
16537
16599
  registry2.register(model71);
16538
16600
  }
16539
16601
 
16602
+ // lib/utils/nemaMotorAssemblyGeometry.ts
16603
+ import jscad6 from "@jscad/modeling";
16604
+ function nema34AssemblyCenters(p) {
16605
+ const edge = p.bodyWidth / 2;
16606
+ return [-1, 1].flatMap(
16607
+ (side) => [-1, 1].map(
16608
+ (end) => [side * (edge - 3.5), end * p.bodyWidth * 0.26]
16609
+ )
16610
+ );
16611
+ }
16612
+ function cutNema34FrontRecesses(geometry, p) {
16613
+ return jscad6.booleans.subtract(
16614
+ geometry,
16615
+ ...nema34AssemblyCenters(p).flatMap(([x, y]) => [
16616
+ jscad6.primitives.cylinder({
16617
+ radius: 1.6,
16618
+ height: p.frontCapLength + 0.2,
16619
+ center: [x, y, -p.frontCapLength / 2],
16620
+ segments: 32
16621
+ }),
16622
+ jscad6.primitives.cylinder({
16623
+ radius: 5,
16624
+ height: Math.min(4, p.frontCapLength / 2) + 0.1,
16625
+ center: [
16626
+ Math.sign(x) * p.bodyWidth / 2,
16627
+ y,
16628
+ -Math.min(4, p.frontCapLength / 2) / 2 + 0.05
16629
+ ],
16630
+ segments: 48
16631
+ })
16632
+ ])
16633
+ );
16634
+ }
16635
+ function createNema34FrontScrews(p) {
16636
+ const head = jscad6.booleans.subtract(
16637
+ jscad6.primitives.ellipsoid({
16638
+ radius: [3.2, 3.2, 1.5],
16639
+ center: [0, 0, -1.8],
16640
+ segments: 32
16641
+ }),
16642
+ ...[
16643
+ [3.7, 0.8, 1.1],
16644
+ [0.8, 3.7, 1.1]
16645
+ ].map(
16646
+ (size) => jscad6.primitives.cuboid({
16647
+ size,
16648
+ center: [0, 0, -0.8]
16649
+ })
16650
+ )
16651
+ );
16652
+ return nema34AssemblyCenters(p).map(
16653
+ ([x, y]) => jscad6.transforms.translate([x, y, 0], head)
16654
+ );
16655
+ }
16656
+
16540
16657
  // lib/NemaMotor.tsx
16541
- import jscad7 from "@jscad/modeling";
16658
+ import jscad8 from "@jscad/modeling";
16542
16659
 
16543
16660
  // lib/utils/nemaMotorWireGeometry.ts
16544
- import jscad6 from "@jscad/modeling";
16661
+ import jscad7 from "@jscad/modeling";
16545
16662
 
16546
16663
  // lib/utils/nemaMotorParameters.ts
16547
16664
  var resolveNemaMotorProps = nemaMotorModelPropsSchema.parse.bind(nemaMotorModelPropsSchema);
@@ -16552,9 +16669,9 @@ function createNemaMotorWireGeometry(input) {
16552
16669
  if (p.wireConnection === "none") return [];
16553
16670
  const { position } = getNemaMotorReferencePoints(p).wireside;
16554
16671
  const angle = p.wireSideAngle * Math.PI / 180;
16555
- const place = (geometry) => jscad6.transforms.translate(
16672
+ const place = (geometry) => jscad7.transforms.translate(
16556
16673
  [position.x, position.y, position.z],
16557
- jscad6.transforms.rotateZ(angle, geometry)
16674
+ jscad7.transforms.rotateZ(angle, geometry)
16558
16675
  );
16559
16676
  if (p.wireConnection === "stubs") {
16560
16677
  const colors = [
@@ -16567,18 +16684,18 @@ function createNemaMotorWireGeometry(input) {
16567
16684
  "#ce7432",
16568
16685
  "#803e91"
16569
16686
  ];
16570
- return Array.from({ length: p.wireCount }, (_, i) => ({
16687
+ const wires = Array.from({ length: p.wireCount }, (_, i) => ({
16571
16688
  color: colors[i],
16572
16689
  geometry: place(
16573
- jscad6.transforms.translate(
16690
+ jscad7.transforms.translate(
16574
16691
  [
16575
16692
  (p.wireLength - 0.15) / 2,
16576
16693
  (i - (p.wireCount - 1) / 2) * p.wireDiameter * 1.5,
16577
16694
  0
16578
16695
  ],
16579
- jscad6.transforms.rotateY(
16696
+ jscad7.transforms.rotateY(
16580
16697
  Math.PI / 2,
16581
- jscad6.primitives.cylinder({
16698
+ jscad7.primitives.cylinder({
16582
16699
  height: p.wireLength + 0.15,
16583
16700
  radius: p.wireDiameter / 2,
16584
16701
  segments: 24
@@ -16587,18 +16704,31 @@ function createNemaMotorWireGeometry(input) {
16587
16704
  )
16588
16705
  )
16589
16706
  }));
16707
+ if (p.nemaSize === 34)
16708
+ wires.unshift({
16709
+ color: "#252830",
16710
+ geometry: place(
16711
+ jscad7.primitives.roundedCuboid({
16712
+ size: [3, p.wireCount * p.wireDiameter * 1.5 + 3, 6],
16713
+ center: [0.8, 0, 0],
16714
+ roundRadius: 1,
16715
+ segments: 24
16716
+ })
16717
+ )
16718
+ });
16719
+ return wires;
16590
16720
  }
16591
16721
  const connector = getJstMotorConnector(p.wireConnection);
16592
16722
  const { pinCount, pitch, bodyWidth, bodyHeight, matingDepth } = connector;
16593
16723
  const wall = pitch === 2 ? 0.6 : 0.3;
16594
16724
  const contactLength = pitch === 2 ? 3.4 : 2.4;
16595
16725
  const contactSize = pitch === 2 ? 0.5 : 0.3;
16596
- const shell = jscad6.booleans.subtract(
16597
- jscad6.primitives.cuboid({
16726
+ const shell = jscad7.booleans.subtract(
16727
+ jscad7.primitives.cuboid({
16598
16728
  size: [matingDepth + 0.1, bodyWidth, bodyHeight],
16599
16729
  center: [(matingDepth - 0.1) / 2, 0, 0]
16600
16730
  }),
16601
- jscad6.primitives.cuboid({
16731
+ jscad7.primitives.cuboid({
16602
16732
  size: [matingDepth - 0.5, bodyWidth - 2 * wall, bodyHeight - 2 * wall],
16603
16733
  center: [matingDepth / 2 + 0.55, 0, 0]
16604
16734
  })
@@ -16608,7 +16738,7 @@ function createNemaMotorWireGeometry(input) {
16608
16738
  ...Array.from({ length: pinCount }, (_, i) => ({
16609
16739
  color: "#b8bec6",
16610
16740
  geometry: place(
16611
- jscad6.primitives.cuboid({
16741
+ jscad7.primitives.cuboid({
16612
16742
  size: [contactLength, contactSize, contactSize],
16613
16743
  center: [contactLength / 2, (i - (pinCount - 1) / 2) * pitch, 0]
16614
16744
  })
@@ -16642,14 +16772,59 @@ var face = (width10, chamfer) => {
16642
16772
  [-h, -h + c]
16643
16773
  ];
16644
16774
  };
16775
+ var roundedFace = (width10, radius) => {
16776
+ if (radius === 0) return face(width10, 0);
16777
+ const center = width10 / 2 - radius;
16778
+ return [0, 1, 2, 3].flatMap(
16779
+ (corner) => Array.from({ length: 13 }, (_, i) => {
16780
+ const angle = i * Math.PI / 24, rotation = corner * Math.PI / 2;
16781
+ const x = center + radius * Math.cos(angle), y = center + radius * Math.sin(angle);
16782
+ return [
16783
+ x * Math.cos(rotation) - y * Math.sin(rotation),
16784
+ x * Math.sin(rotation) + y * Math.cos(rotation)
16785
+ ];
16786
+ })
16787
+ );
16788
+ };
16789
+ var steppedFace = (width10, chamfer) => {
16790
+ if (chamfer === 0) return face(width10, 0);
16791
+ const h = width10 / 2, c = chamfer / Math.SQRT2, r = Math.min(4, c / 4);
16792
+ const corner = [];
16793
+ const arc = (x, y, from, to) => {
16794
+ for (let i = 0; i <= 12; i++) {
16795
+ const a = (from + (to - from) * i / 12) * Math.PI / 180;
16796
+ corner.push([x + r * Math.cos(a), y + r * Math.sin(a)]);
16797
+ }
16798
+ };
16799
+ arc(h - c - r, h - r, 90, 0);
16800
+ arc(h - c + r, h - c + r, 180, 270);
16801
+ arc(h - r, h - c - r, 90, 0);
16802
+ return [0, 1, 2, 3].flatMap(
16803
+ (i) => corner.map(([x, y]) => {
16804
+ const a = -i * Math.PI / 2;
16805
+ return [
16806
+ x * Math.cos(a) - y * Math.sin(a),
16807
+ x * Math.sin(a) + y * Math.cos(a)
16808
+ ];
16809
+ })
16810
+ ).reverse();
16811
+ };
16645
16812
  function createNemaMotorSections(input) {
16646
16813
  const p = resolveNemaMotorProps(input);
16647
16814
  const sections = [];
16648
16815
  const add = (name, outline, zMin, zMax, holes2 = []) => {
16649
16816
  if (zMax > zMin) sections.push({ name, outline, holes: holes2, zMin, zMax });
16650
16817
  };
16651
- const front = face(p.bodyWidth, p.faceCornerChamfer);
16652
- const core = face(p.bodyWidth, p.bodyCornerChamfer);
16818
+ const front = (p.nemaSize === 34 ? roundedFace : face)(
16819
+ p.bodyWidth,
16820
+ p.faceCornerChamfer
16821
+ );
16822
+ const profile6 = p.cornerProfile === "stepped" ? steppedFace : face;
16823
+ const core = profile6(p.bodyWidth, p.bodyCornerChamfer);
16824
+ const rear = profile6(
16825
+ p.bodyWidth,
16826
+ p.rearCornerChamfer ?? (p.backFace === "plain" && p.mountingHoleThrough ? p.bodyCornerChamfer : p.faceCornerChamfer)
16827
+ );
16653
16828
  const h = p.mountingHoleSpacing / 2;
16654
16829
  const centers = [
16655
16830
  [-h, -h],
@@ -16665,12 +16840,7 @@ function createNemaMotorSections(input) {
16665
16840
  add("frontCap", front, -p.frontCapLength, -holeDepth);
16666
16841
  add("body", core, -p.bodyLength + p.rearCapLength, -p.frontCapLength);
16667
16842
  if (p.backFace === "plain") {
16668
- add(
16669
- "rearCap",
16670
- p.mountingHoleThrough ? core : front,
16671
- -p.bodyLength,
16672
- -p.bodyLength + p.rearCapLength
16673
- );
16843
+ add("rearCap", rear, -p.bodyLength, -p.bodyLength + p.rearCapLength);
16674
16844
  } else {
16675
16845
  const halfPitch = p.backFaceHoleSpacing / 2;
16676
16846
  const rearHoles = [-halfPitch, halfPitch].flatMap(
@@ -16680,14 +16850,14 @@ function createNemaMotorSections(input) {
16680
16850
  );
16681
16851
  add(
16682
16852
  "rearCap",
16683
- front,
16853
+ rear,
16684
16854
  -p.bodyLength,
16685
16855
  -p.bodyLength + p.backFaceHoleDepth,
16686
16856
  rearHoles
16687
16857
  );
16688
16858
  add(
16689
16859
  "rearCap",
16690
- front,
16860
+ rear,
16691
16861
  -p.bodyLength + p.backFaceHoleDepth,
16692
16862
  -p.bodyLength + p.rearCapLength
16693
16863
  );
@@ -16700,12 +16870,12 @@ function createNemaMotorSections(input) {
16700
16870
  else {
16701
16871
  const cut = r - p.shaftFlatDepth;
16702
16872
  const angle = Math.acos(cut / r);
16703
- const profile6 = Array.from({ length: 97 }, (_, i) => {
16873
+ const profile7 = Array.from({ length: 97 }, (_, i) => {
16704
16874
  const a = angle + (2 * Math.PI - 2 * angle) * i / 96;
16705
16875
  return [r * Math.cos(a), r * Math.sin(a)];
16706
16876
  });
16707
16877
  const rotation = p.shaftFlatAngle * Math.PI / 180;
16708
- const d = profile6.map(([x, y]) => [
16878
+ const d = profile7.map(([x, y]) => [
16709
16879
  x * Math.cos(rotation) - y * Math.sin(rotation),
16710
16880
  x * Math.sin(rotation) + y * Math.cos(rotation)
16711
16881
  ]);
@@ -16718,7 +16888,7 @@ function createNemaMotorSections(input) {
16718
16888
  // lib/NemaMotor.tsx
16719
16889
  import { Colorize as Colorize30, Custom as Custom22 } from "jscad-fiber";
16720
16890
  import { Fragment as Fragment17, jsx as jsx61, jsxs as jsxs17 } from "react/jsx-runtime";
16721
- var generalize3 = jscad7.modifiers.generalize;
16891
+ var generalize3 = jscad8.modifiers.generalize;
16722
16892
  function NemaMotor({
16723
16893
  bodyColor = "#242830",
16724
16894
  capColor = "#aeb5bd",
@@ -16727,7 +16897,7 @@ function NemaMotor({
16727
16897
  ...props
16728
16898
  }) {
16729
16899
  const p = resolveNemaMotorProps(props);
16730
- const screw = p.backFace === "screws" ? jscad7.transforms.rotateX(
16900
+ const screw = p.backFace === "screws" ? jscad8.transforms.rotateX(
16731
16901
  Math.PI,
16732
16902
  createHexSocketBoltGeom({
16733
16903
  metricSize: p.backFaceScrewSize,
@@ -16738,18 +16908,20 @@ function NemaMotor({
16738
16908
  const halfPitch = p.backFaceHoleSpacing / 2;
16739
16909
  return /* @__PURE__ */ jsxs17(Fragment17, { children: [
16740
16910
  createNemaMotorSections(p).map((section, index) => {
16741
- const outline = jscad7.geometries.geom2.fromPoints(section.outline);
16742
- const profile6 = section.holes.length ? jscad7.booleans.subtract(
16911
+ const outline = jscad8.geometries.geom2.fromPoints(section.outline);
16912
+ const profile6 = section.holes.length ? jscad8.booleans.subtract(
16743
16913
  outline,
16744
- ...section.holes.map((h) => jscad7.geometries.geom2.fromPoints(h))
16914
+ ...section.holes.map((h) => jscad8.geometries.geom2.fromPoints(h))
16745
16915
  ) : outline;
16746
- const geometry = jscad7.transforms.translate(
16916
+ let geometry = jscad8.transforms.translate(
16747
16917
  [0, 0, section.zMin],
16748
- jscad7.extrusions.extrudeLinear(
16918
+ jscad8.extrusions.extrudeLinear(
16749
16919
  { height: section.zMax - section.zMin },
16750
16920
  profile6
16751
16921
  )
16752
16922
  );
16923
+ if (p.nemaSize === 34 && section.name === "frontCap")
16924
+ geometry = cutNema34FrontRecesses(geometry, p);
16753
16925
  return /* @__PURE__ */ jsx61(
16754
16926
  Colorize30,
16755
16927
  {
@@ -16769,6 +16941,15 @@ function NemaMotor({
16769
16941
  },
16770
16942
  `wire-${index}`
16771
16943
  )),
16944
+ p.nemaSize === 34 && createNema34FrontScrews(p).map((geometry, index) => /* @__PURE__ */ jsx61(
16945
+ Colorize30,
16946
+ {
16947
+ material: componentMaterials.steel,
16948
+ color: screwColor,
16949
+ children: /* @__PURE__ */ jsx61(Custom22, { geometry: generalize3({ simplify: true }, geometry) })
16950
+ },
16951
+ `front-screw-${index}`
16952
+ )),
16772
16953
  screw && [-halfPitch, halfPitch].flatMap(
16773
16954
  (x) => [-halfPitch, halfPitch].map((y) => /* @__PURE__ */ jsx61(
16774
16955
  Colorize30,
@@ -16778,7 +16959,7 @@ function NemaMotor({
16778
16959
  children: /* @__PURE__ */ jsx61(
16779
16960
  Custom22,
16780
16961
  {
16781
- geometry: jscad7.transforms.translate(
16962
+ geometry: jscad8.transforms.translate(
16782
16963
  [x, y, -p.bodyLength],
16783
16964
  generalize3({ simplify: true }, screw)
16784
16965
  )
@@ -16793,6 +16974,7 @@ function NemaMotor({
16793
16974
  var NEMA8 = (props) => /* @__PURE__ */ jsx61(NemaMotor, { ...props, nemaSize: 8 });
16794
16975
  var NEMA17 = (props) => /* @__PURE__ */ jsx61(NemaMotor, { ...props, nemaSize: 17 });
16795
16976
  var NEMA23 = (props) => /* @__PURE__ */ jsx61(NemaMotor, { ...props, nemaSize: 23 });
16977
+ var NEMA34 = (props) => /* @__PURE__ */ jsx61(NemaMotor, { ...props, nemaSize: 34 });
16796
16978
 
16797
16979
  // lib/models/nema/register.tsx
16798
16980
  import { jsx as jsx62 } from "react/jsx-runtime";
@@ -17176,7 +17358,7 @@ function register74(registry2) {
17176
17358
  import { Colorize as Colorize33, Custom as Custom25 } from "jscad-fiber";
17177
17359
 
17178
17360
  // lib/models/perforatedsheet/geometry.ts
17179
- import jscad8 from "@jscad/modeling";
17361
+ import jscad9 from "@jscad/modeling";
17180
17362
  var {
17181
17363
  booleans,
17182
17364
  primitives: primitives3,
@@ -17184,7 +17366,7 @@ var {
17184
17366
  geometries: geometries3,
17185
17367
  modifiers: modifiers3,
17186
17368
  measurements: measurements3
17187
- } = jscad8;
17369
+ } = jscad9;
17188
17370
  var generalize4 = modifiers3.generalize;
17189
17371
  var { subtract } = booleans;
17190
17372
  var { rectangle: rectangle3, roundedRectangle: roundedRectangle3, circle: circle2 } = primitives3;
@@ -17342,8 +17524,8 @@ function register76(registry2) {
17342
17524
  import { Colorize as Colorize35, Custom as Custom27 } from "jscad-fiber";
17343
17525
 
17344
17526
  // lib/models/pushfitplug/geometry.ts
17345
- import jscad9 from "@jscad/modeling";
17346
- var { primitives: primitives4, extrusions: extrusions4, geometries: geometries4, modifiers: modifiers4, measurements: measurements4 } = jscad9;
17527
+ import jscad10 from "@jscad/modeling";
17528
+ var { primitives: primitives4, extrusions: extrusions4, geometries: geometries4, modifiers: modifiers4, measurements: measurements4 } = jscad10;
17347
17529
  var generalize5 = modifiers4.generalize;
17348
17530
  var { rectangle: rectangle4, roundedRectangle: roundedRectangle4, polygon: polygon3 } = primitives4;
17349
17531
  function createPushFitPlugGeom(input) {
@@ -17419,8 +17601,8 @@ function register77(registry2) {
17419
17601
  import { Colorize as Colorize36, Custom as Custom28 } from "jscad-fiber";
17420
17602
 
17421
17603
  // lib/models/rectangularbar/geometry.ts
17422
- import jscad10 from "@jscad/modeling";
17423
- var { primitives: primitives5, extrusions: extrusions5, geometries: geometries5, modifiers: modifiers5, measurements: measurements5 } = jscad10;
17604
+ import jscad11 from "@jscad/modeling";
17605
+ var { primitives: primitives5, extrusions: extrusions5, geometries: geometries5, modifiers: modifiers5, measurements: measurements5 } = jscad11;
17424
17606
  var generalize6 = modifiers5.generalize;
17425
17607
  var { rectangle: rectangle5, roundedRectangle: roundedRectangle5 } = primitives5;
17426
17608
  var profile4 = (shape44, height10) => extrusions5.extrudeLinear({ height: height10 }, shape44);
@@ -17607,7 +17789,7 @@ function register79(registry2) {
17607
17789
  import { Colorize as Colorize38, Custom as Custom30 } from "jscad-fiber";
17608
17790
 
17609
17791
  // lib/models/rectangulartube/geometry.ts
17610
- import jscad11 from "@jscad/modeling";
17792
+ import jscad12 from "@jscad/modeling";
17611
17793
  var {
17612
17794
  booleans: booleans2,
17613
17795
  primitives: primitives6,
@@ -17615,7 +17797,7 @@ var {
17615
17797
  geometries: geometries6,
17616
17798
  modifiers: modifiers6,
17617
17799
  measurements: measurements6
17618
- } = jscad11;
17800
+ } = jscad12;
17619
17801
  var generalize7 = modifiers6.generalize;
17620
17802
  var { subtract: subtract2 } = booleans2;
17621
17803
  var { rectangle: rectangle6, roundedRectangle: roundedRectangle6 } = primitives6;
@@ -18658,7 +18840,7 @@ function register91(registry2) {
18658
18840
  import { Colorize as Colorize50, Custom as Custom42 } from "jscad-fiber";
18659
18841
 
18660
18842
  // lib/models/tslotcoverstrip/geometry.ts
18661
- import jscad14 from "@jscad/modeling";
18843
+ import jscad15 from "@jscad/modeling";
18662
18844
  var {
18663
18845
  primitives: primitives7,
18664
18846
  extrusions: extrusions7,
@@ -18666,7 +18848,7 @@ var {
18666
18848
  geometries: geometries7,
18667
18849
  modifiers: modifiers7,
18668
18850
  measurements: measurements7
18669
- } = jscad14;
18851
+ } = jscad15;
18670
18852
  var generalize8 = modifiers7.generalize;
18671
18853
  function createTSlotCoverStripGeom(input) {
18672
18854
  const p = tSlotCoverStripModelPropsSchema.parse(input);
@@ -27597,6 +27779,7 @@ export {
27597
27779
  MountedPcbModule,
27598
27780
  NEMA17,
27599
27781
  NEMA23,
27782
+ NEMA34,
27600
27783
  NEMA8,
27601
27784
  NemaMotor,
27602
27785
  NylonLockNut,