jscad-electronics 0.0.237 → 0.0.238

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/e80fbad5260b66fd00b4ab7513941eadd9b0b17b-v2/node_modules/zod/v3/external.js
751
+ // .model-contracts/generations/ad649bc7a403a3e6e9b12ce32ac0b3d0fa61c6bf-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/e80fbad5260b66fd00b4ab7513941eadd9b0b17b-v2/node_modules/zod/v3/helpers/util.js
863
+ // .model-contracts/generations/ad649bc7a403a3e6e9b12ce32ac0b3d0fa61c6bf-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/e80fbad5260b66fd00b4ab7513941eadd9b0b17b-v2/node_modules/zod/v3/ZodError.js
997
+ // .model-contracts/generations/ad649bc7a403a3e6e9b12ce32ac0b3d0fa61c6bf-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/e80fbad5260b66fd00b4ab7513941eadd9b0b17b-v2/node_modules/zod/v3/locales/en.js
1115
+ // .model-contracts/generations/ad649bc7a403a3e6e9b12ce32ac0b3d0fa61c6bf-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/e80fbad5260b66fd00b4ab7513941eadd9b0b17b-v2/node_modules/zod/v3/errors.js
1218
+ // .model-contracts/generations/ad649bc7a403a3e6e9b12ce32ac0b3d0fa61c6bf-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/e80fbad5260b66fd00b4ab7513941eadd9b0b17b-v2/node_modules/zod/v3/helpers/parseUtil.js
1227
+ // .model-contracts/generations/ad649bc7a403a3e6e9b12ce32ac0b3d0fa61c6bf-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/e80fbad5260b66fd00b4ab7513941eadd9b0b17b-v2/node_modules/zod/v3/helpers/errorUtil.js
1337
+ // .model-contracts/generations/ad649bc7a403a3e6e9b12ce32ac0b3d0fa61c6bf-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/e80fbad5260b66fd00b4ab7513941eadd9b0b17b-v2/node_modules/zod/v3/types.js
1344
+ // .model-contracts/generations/ad649bc7a403a3e6e9b12ce32ac0b3d0fa61c6bf-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/e80fbad5260b66fd00b4ab7513941eadd9b0b17b-v2/node_modules/@tscircuit/mm/dist/index.js
4792
+ // .model-contracts/generations/ad649bc7a403a3e6e9b12ce32ac0b3d0fa61c6bf-v2/node_modules/@tscircuit/mm/dist/index.js
4793
4793
  var unitToMm = {
4794
4794
  in: 25.4,
4795
4795
  inch: 25.4,
@@ -4816,7 +4816,7 @@ var mm = (n) => {
4816
4816
  throw new Error(`Unsupported unit: ${unit}`);
4817
4817
  };
4818
4818
 
4819
- // .model-contracts/generations/e80fbad5260b66fd00b4ab7513941eadd9b0b17b-v2/index.js
4819
+ // .model-contracts/generations/ad649bc7a403a3e6e9b12ce32ac0b3d0fa61c6bf-v2/index.js
4820
4820
  function normalizeNemaMotorModelString(value) {
4821
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");
@@ -5371,6 +5371,76 @@ var jstMotorWireConnectionSchema = external_exports.string().refine((value) => {
5371
5371
  const connector = getJstMotorConnector(value);
5372
5372
  return connector !== void 0 && connector.pinCount >= 2 && connector.pinCount <= connector.maxPinCount;
5373
5373
  }, "Expected jst-ph-N (2\u201316 pins) or jst-sh-N (2\u201315 pins)");
5374
+ function isInsideNemaFace(x, y, p) {
5375
+ const h = p.width / 2;
5376
+ x = Math.abs(x);
5377
+ y = Math.abs(y);
5378
+ if (x > h || y > h) return false;
5379
+ const chamfer = p.chamfer;
5380
+ if (!p.stepped) return x + y <= 2 * h - chamfer;
5381
+ const c = chamfer / Math.SQRT2;
5382
+ if (c === 0) return true;
5383
+ const recess = p.recessRadius;
5384
+ const fillet = p.filletRadius;
5385
+ const k = h - c + recess;
5386
+ if (x > h - c && y > h - c)
5387
+ return x <= k && y <= k && Math.hypot(x - k, y - k) >= recess;
5388
+ if (y > h - fillet && x > h - c - fillet)
5389
+ return Math.hypot(x - (h - c - fillet), y - (h - fillet)) <= fillet;
5390
+ if (x > h - fillet && y > h - c - fillet)
5391
+ return Math.hypot(x - (h - fillet), y - (h - c - fillet)) <= fillet;
5392
+ return true;
5393
+ }
5394
+ var segmentDistance = (x, y, ax, ay, bx, by) => {
5395
+ const dx = bx - ax;
5396
+ const dy = by - ay;
5397
+ const t = Math.max(
5398
+ 0,
5399
+ Math.min(1, ((x - ax) * dx + (y - ay) * dy) / (dx * dx + dy * dy || 1))
5400
+ );
5401
+ return Math.hypot(x - ax - t * dx, y - ay - t * dy);
5402
+ };
5403
+ var arcDistance = (x, y, cx, cy, r, start, end) => {
5404
+ const angle = (Math.atan2(y - cy, x - cx) + 2 * Math.PI) % (2 * Math.PI);
5405
+ if (angle >= start && angle <= end)
5406
+ return Math.abs(Math.hypot(x - cx, y - cy) - r);
5407
+ return Math.min(
5408
+ Math.hypot(x - cx - r * Math.cos(start), y - cy - r * Math.sin(start)),
5409
+ Math.hypot(x - cx - r * Math.cos(end), y - cy - r * Math.sin(end))
5410
+ );
5411
+ };
5412
+ var boundaryDistance = (x, y, p) => {
5413
+ const h = p.width / 2;
5414
+ x = Math.abs(x);
5415
+ y = Math.abs(y);
5416
+ const chamfer = p.chamfer;
5417
+ if (!p.stepped || chamfer === 0)
5418
+ return Math.min(
5419
+ Math.abs(h - x),
5420
+ Math.abs(h - y),
5421
+ Math.abs(2 * h - chamfer - x - y) / Math.SQRT2
5422
+ );
5423
+ const c = chamfer / Math.SQRT2;
5424
+ const recess = p.recessRadius;
5425
+ const fillet = p.filletRadius;
5426
+ const a = h - c - fillet;
5427
+ const k = h - c + recess;
5428
+ return Math.min(
5429
+ segmentDistance(x, y, -a, h, a, h),
5430
+ segmentDistance(x, y, h, -a, h, a),
5431
+ segmentDistance(x, y, h - c, h - fillet, h - c, k),
5432
+ segmentDistance(x, y, k, h - c, h - fillet, h - c),
5433
+ arcDistance(x, y, a, h - fillet, fillet, 0, Math.PI / 2),
5434
+ arcDistance(x, y, k, k, recess, Math.PI, 3 * Math.PI / 2),
5435
+ arcDistance(x, y, h - fillet, a, fillet, 0, Math.PI / 2)
5436
+ );
5437
+ };
5438
+ function fitsNemaCircle(x, y, radius, p) {
5439
+ return isInsideNemaFace(x, y, p) && boundaryDistance(x, y, p) > radius;
5440
+ }
5441
+ function clearsNemaCircle(x, y, radius, p) {
5442
+ return !isInsideNemaFace(x, y, p) && boundaryDistance(x, y, p) > radius;
5443
+ }
5374
5444
  var hexSocketBoltDimensions = {
5375
5445
  M2: {
5376
5446
  diameter: 2,
@@ -5521,7 +5591,15 @@ var nemaMotorDimensions = {
5521
5591
  bodyCornerChamfer: 6
5522
5592
  },
5523
5593
  23: {
5524
- backFaceScrewSize: "M4",
5594
+ // Representative side-tab rear pattern from STEPPERONLINE's ST-M10 adapter.
5595
+ // The adapter's R5/R2.5 profile is a visual reference, not a frame guarantee:
5596
+ // https://www.omc-stepperonline.com/image/catalog/dimensions/ST-M10_Dimension.svg
5597
+ backFaceHoleSpacing: 50,
5598
+ backFaceHoleSpacingY: 32,
5599
+ rearCornerChamfer: 9 * Math.SQRT2,
5600
+ rearCornerRecessRadius: 5,
5601
+ rearCornerFilletRadius: 2.5,
5602
+ backFaceScrewSize: "M3",
5525
5603
  backFaceHoleDepth: 4.5,
5526
5604
  bodyWidth: 56.4,
5527
5605
  bodyLength: 51,
@@ -5541,7 +5619,10 @@ var nemaMotorDimensions = {
5541
5619
  frontCapLength: 5,
5542
5620
  rearCapLength: 5,
5543
5621
  faceCornerChamfer: 2,
5544
- bodyCornerChamfer: 15
5622
+ bodyCornerChamfer: 9 * Math.SQRT2,
5623
+ bodyCornerRecessRadius: 5,
5624
+ bodyCornerFilletRadius: 2.5,
5625
+ chamferedBodyCornerChamfer: 15
5545
5626
  },
5546
5627
  34: {
5547
5628
  // Illustrative rear details; independent of the mounting flange.
@@ -5577,6 +5658,9 @@ var shape3 = {
5577
5658
  backFaceHoles: external_exports.boolean().optional(),
5578
5659
  backFaceScrews: external_exports.boolean().optional(),
5579
5660
  backFaceHoleSpacing: positiveModelLengthSchema.optional(),
5661
+ /** Axis overrides; the legacy scalar still sets a square pattern when supplied. */
5662
+ backFaceHoleSpacingX: positiveModelLengthSchema.optional(),
5663
+ backFaceHoleSpacingY: positiveModelLengthSchema.optional(),
5580
5664
  backFaceHoleDiameter: positiveModelLengthSchema.optional(),
5581
5665
  backFaceHoleDepth: positiveModelLengthSchema.optional(),
5582
5666
  backFaceScrewSize: metricBoltSizeSchema.optional(),
@@ -5613,8 +5697,14 @@ var shape3 = {
5613
5697
  rearCapLength: positiveModelLengthSchema.optional(),
5614
5698
  faceCornerChamfer: nonnegativeModelLengthSchema.optional(),
5615
5699
  bodyCornerChamfer: nonnegativeModelLengthSchema.optional(),
5700
+ bodyCornerRecessRadius: nonnegativeModelLengthSchema.optional(),
5701
+ bodyCornerFilletRadius: nonnegativeModelLengthSchema.optional(),
5616
5702
  /** Rear outline is independent of the front mounting flange. */
5617
5703
  rearCornerChamfer: nonnegativeModelLengthSchema.optional(),
5704
+ rearCornerRecessRadius: nonnegativeModelLengthSchema.optional(),
5705
+ rearCornerFilletRadius: nonnegativeModelLengthSchema.optional(),
5706
+ rearChamfered: external_exports.boolean().optional(),
5707
+ rearStepped: external_exports.boolean().optional(),
5618
5708
  chamfered: external_exports.boolean().optional(),
5619
5709
  stepped: external_exports.boolean().optional()
5620
5710
  };
@@ -5639,7 +5729,11 @@ var resolve = (p, ctx) => {
5639
5729
  );
5640
5730
  const corner = select(
5641
5731
  ["chamfered", "stepped"],
5642
- p.nemaSize === 34 ? "stepped" : "chamfered"
5732
+ p.nemaSize === 23 || p.nemaSize === 34 ? "stepped" : "chamfered"
5733
+ );
5734
+ const rearCorner = select(
5735
+ ["rearChamfered", "rearStepped"],
5736
+ p.chamfered === true ? "rearChamfered" : p.nemaSize === 23 || corner === "stepped" ? "rearStepped" : "rearChamfered"
5643
5737
  );
5644
5738
  const wireSpecified = p.noWires !== void 0 || p.wireStubs !== void 0 || p.wireConnection !== void 0;
5645
5739
  const wireSelections = Number(p.noWires === true) + Number(p.wireStubs === true) + Number(p.wireConnection !== void 0);
@@ -5649,8 +5743,13 @@ var resolve = (p, ctx) => {
5649
5743
  message: "Select exactly one of noWires, wireStubs or a JST wireConnection"
5650
5744
  });
5651
5745
  const d = nemaMotorDimensions[p.nemaSize];
5746
+ const bodyCornerChamfer = p.bodyCornerChamfer ?? (corner === "chamfered" && "chamferedBodyCornerChamfer" in d ? d.chamferedBodyCornerChamfer : d.bodyCornerChamfer);
5747
+ const defaultBodyRadius = Math.min(4, bodyCornerChamfer / Math.SQRT2 / 4);
5652
5748
  const backFaceScrewSize = p.backFaceScrewSize ?? d.backFaceScrewSize;
5653
5749
  const screw = hexSocketBoltDimensions[backFaceScrewSize];
5750
+ const backFaceHoleSpacing = p.backFaceHoleSpacing ?? ("backFaceHoleSpacing" in d ? d.backFaceHoleSpacing : p.mountingHoleSpacing ?? d.mountingHoleSpacing);
5751
+ const rearCornerChamfer = p.rearCornerChamfer ?? (p.nemaSize === 23 && rearCorner === "rearChamfered" ? p.faceCornerChamfer ?? d.faceCornerChamfer : "rearCornerChamfer" in d ? d.rearCornerChamfer : back === "backFacePlain" && (p.mountingHoleThrough ?? d.mountingHoleThrough) ? p.bodyCornerChamfer ?? d.bodyCornerChamfer : p.faceCornerChamfer ?? d.faceCornerChamfer);
5752
+ const defaultRearRadius = Math.min(4, rearCornerChamfer / Math.SQRT2 / 4);
5654
5753
  return {
5655
5754
  nemaSize: p.nemaSize,
5656
5755
  noWires: p.noWires === true,
@@ -5663,7 +5762,9 @@ var resolve = (p, ctx) => {
5663
5762
  backFacePlain: back === "backFacePlain",
5664
5763
  backFaceHoles: back === "backFaceHoles",
5665
5764
  backFaceScrews: back === "backFaceScrews",
5666
- backFaceHoleSpacing: p.backFaceHoleSpacing ?? ("backFaceHoleSpacing" in d ? d.backFaceHoleSpacing : p.mountingHoleSpacing ?? d.mountingHoleSpacing),
5765
+ backFaceHoleSpacing,
5766
+ backFaceHoleSpacingX: p.backFaceHoleSpacingX ?? backFaceHoleSpacing,
5767
+ backFaceHoleSpacingY: p.backFaceHoleSpacingY ?? p.backFaceHoleSpacing ?? ("backFaceHoleSpacingY" in d ? d.backFaceHoleSpacingY : backFaceHoleSpacing),
5667
5768
  backFaceHoleDiameter: p.backFaceHoleDiameter ?? screw.diameter,
5668
5769
  backFaceHoleDepth: p.backFaceHoleDepth ?? d.backFaceHoleDepth,
5669
5770
  backFaceScrewSize,
@@ -5685,24 +5786,43 @@ var resolve = (p, ctx) => {
5685
5786
  frontCapLength: p.frontCapLength ?? d.frontCapLength,
5686
5787
  rearCapLength: p.rearCapLength ?? d.rearCapLength,
5687
5788
  faceCornerChamfer: p.faceCornerChamfer ?? d.faceCornerChamfer,
5688
- bodyCornerChamfer: p.bodyCornerChamfer ?? d.bodyCornerChamfer,
5789
+ bodyCornerChamfer,
5790
+ bodyCornerRecessRadius: p.bodyCornerRecessRadius ?? ("bodyCornerRecessRadius" in d ? d.bodyCornerRecessRadius : defaultBodyRadius),
5791
+ bodyCornerFilletRadius: p.bodyCornerFilletRadius ?? ("bodyCornerFilletRadius" in d ? d.bodyCornerFilletRadius : defaultBodyRadius),
5689
5792
  chamfered: corner === "chamfered",
5690
5793
  stepped: corner === "stepped",
5691
- ..."rearCornerChamfer" in d || p.rearCornerChamfer !== void 0 ? {
5692
- rearCornerChamfer: p.rearCornerChamfer ?? ("rearCornerChamfer" in d ? d.rearCornerChamfer : p.faceCornerChamfer ?? d.faceCornerChamfer)
5693
- } : {}
5794
+ rearCornerChamfer,
5795
+ rearStepped: rearCorner === "rearStepped",
5796
+ rearChamfered: rearCorner === "rearChamfered",
5797
+ rearCornerRecessRadius: p.rearCornerRecessRadius ?? ("rearCornerRecessRadius" in d ? d.rearCornerRecessRadius : defaultRearRadius),
5798
+ rearCornerFilletRadius: p.rearCornerFilletRadius ?? ("rearCornerFilletRadius" in d ? d.rearCornerFilletRadius : defaultRearRadius)
5694
5799
  };
5695
5800
  };
5696
5801
  var validate3 = (p, ctx) => {
5697
5802
  const issue = (message) => ctx.addIssue({ code: "custom", message });
5803
+ if (p.stepped && p.bodyCornerRecessRadius + p.bodyCornerFilletRadius > p.bodyCornerChamfer / Math.SQRT2)
5804
+ issue("Body recess and fillet radii must fit within the corner shoulder");
5698
5805
  const rearChamfer = p.rearCornerChamfer ?? (p.backFacePlain && p.mountingHoleThrough ? p.bodyCornerChamfer : p.faceCornerChamfer);
5699
- const rearEdge = p.stepped ? rearChamfer / Math.SQRT2 : rearChamfer;
5806
+ const rearEdge = p.rearStepped ? rearChamfer / Math.SQRT2 : rearChamfer;
5807
+ if (p.rearStepped && p.rearCornerRecessRadius + p.rearCornerFilletRadius > rearEdge)
5808
+ issue("Rear recess and fillet radii must fit within the corner shoulder");
5700
5809
  if (!p.backFacePlain) {
5701
5810
  const screw = hexSocketBoltDimensions[p.backFaceScrewSize];
5702
5811
  const radius = (p.backFaceScrews ? Math.max(p.backFaceHoleDiameter, screw.headDiameter) : p.backFaceHoleDiameter) / 2;
5703
- if (p.backFaceHoleSpacing <= 2 * radius)
5812
+ if (p.backFaceHoleSpacingX <= 2 * radius || p.backFaceHoleSpacingY <= 2 * radius)
5704
5813
  issue("Rear holes and screw heads must not overlap each other");
5705
- if (p.backFaceHoleSpacing + 2 * radius >= p.bodyWidth || (p.stepped ? p.backFaceHoleSpacing + 2 * radius >= p.bodyWidth - 2 * rearEdge : p.bodyWidth - rearChamfer - p.backFaceHoleSpacing <= radius * Math.SQRT2))
5814
+ if (!fitsNemaCircle(
5815
+ p.backFaceHoleSpacingX / 2,
5816
+ p.backFaceHoleSpacingY / 2,
5817
+ radius,
5818
+ {
5819
+ width: p.bodyWidth,
5820
+ chamfer: p.rearCornerChamfer,
5821
+ stepped: p.rearStepped,
5822
+ recessRadius: p.rearCornerRecessRadius,
5823
+ filletRadius: p.rearCornerFilletRadius
5824
+ }
5825
+ ))
5706
5826
  issue("Rear holes and screw heads must fit entirely inside the rear face");
5707
5827
  if (p.backFaceHoleDepth >= p.rearCapLength)
5708
5828
  issue("Rear hole depth must be less than the rear cap length");
@@ -5733,7 +5853,13 @@ var validate3 = (p, ctx) => {
5733
5853
  issue("Mounting holes must clear the pilot");
5734
5854
  if (!p.mountingHoleThrough && p.mountingHoleDepth >= p.frontCapLength)
5735
5855
  issue("Blind mounting hole depth must be less than the front cap length");
5736
- if (p.mountingHoleThrough && (p.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))
5856
+ if (p.mountingHoleThrough && !clearsNemaCircle(p.mountingHoleSpacing / 2, p.mountingHoleSpacing / 2, r, {
5857
+ width: p.bodyWidth,
5858
+ chamfer: p.bodyCornerChamfer,
5859
+ stepped: p.stepped,
5860
+ recessRadius: p.bodyCornerRecessRadius,
5861
+ filletRadius: p.bodyCornerFilletRadius
5862
+ }))
5737
5863
  issue("Body must clear through front mounting holes");
5738
5864
  if (p.shaftLength <= p.pilotLength)
5739
5865
  issue("Shaft tip must extend beyond the pilot");
@@ -5752,6 +5878,8 @@ var lengths2 = {
5752
5878
  bodylength: "bodyLength",
5753
5879
  bodywidth: "bodyWidth",
5754
5880
  backholespacing: "backFaceHoleSpacing",
5881
+ backholespacingx: "backFaceHoleSpacingX",
5882
+ backholespacingy: "backFaceHoleSpacingY",
5755
5883
  backholediameter: "backFaceHoleDiameter",
5756
5884
  backholedepth: "backFaceHoleDepth",
5757
5885
  shaftlength: "shaftLength",
@@ -5767,7 +5895,11 @@ var lengths2 = {
5767
5895
  rearcap: "rearCapLength",
5768
5896
  facechamfer: "faceCornerChamfer",
5769
5897
  bodychamfer: "bodyCornerChamfer",
5770
- rearchamfer: "rearCornerChamfer"
5898
+ bodyrecess: "bodyCornerRecessRadius",
5899
+ bodyfillet: "bodyCornerFilletRadius",
5900
+ rearchamfer: "rearCornerChamfer",
5901
+ rearrecess: "rearCornerRecessRadius",
5902
+ rearfillet: "rearCornerFilletRadius"
5771
5903
  };
5772
5904
  var flags = {
5773
5905
  backfaceplain: "backFacePlain",
@@ -5779,6 +5911,8 @@ var flags = {
5779
5911
  dshaft: "dShaft",
5780
5912
  chamfered: "chamfered",
5781
5913
  stepped: "stepped",
5914
+ rearstepped: "rearStepped",
5915
+ rearchamfered: "rearChamfered",
5782
5916
  nowires: "noWires",
5783
5917
  wirestubs: "wireStubs"
5784
5918
  };
@@ -12768,24 +12902,24 @@ function getNemaMotorReferencePoints(input) {
12768
12902
  p.bodyWidth / 2 / Math.max(Math.abs(x), Math.abs(y)),
12769
12903
  (p.bodyWidth - p.faceCornerChamfer) / (Math.abs(x) + Math.abs(y))
12770
12904
  );
12771
- if (p.nemaSize === 34 && p.stepped) {
12772
- const h = p.bodyWidth / 2, c = p.bodyCornerChamfer / Math.SQRT2, r = Math.min(4, c / 4);
12773
- const contains = (distance2) => {
12774
- const a = Math.abs(distance2 * x), b = Math.abs(distance2 * y);
12775
- if (a > h || b > h) return false;
12776
- if (c === 0) return true;
12777
- if (a > h - c && b > h - c)
12778
- return a <= h - c + r && b <= h - c + r && Math.hypot(a - (h - c + r), b - (h - c + r)) >= r;
12779
- if (b > h - r && a > h - c - r)
12780
- return Math.hypot(a - (h - c - r), b - (h - r)) <= r;
12781
- if (a > h - r && b > h - c - r)
12782
- return Math.hypot(a - (h - r), b - (h - c - r)) <= r;
12783
- return true;
12905
+ if (p.nemaSize !== 34 || p.stepped) {
12906
+ const profile6 = p.nemaSize === 34 ? {
12907
+ width: p.bodyWidth,
12908
+ chamfer: p.bodyCornerChamfer,
12909
+ stepped: p.stepped,
12910
+ recessRadius: p.bodyCornerRecessRadius,
12911
+ filletRadius: p.bodyCornerFilletRadius
12912
+ } : {
12913
+ width: p.bodyWidth,
12914
+ chamfer: p.rearCornerChamfer,
12915
+ stepped: p.rearStepped,
12916
+ recessRadius: p.rearCornerRecessRadius,
12917
+ filletRadius: p.rearCornerFilletRadius
12784
12918
  };
12785
12919
  let low = 0, high = p.bodyWidth;
12786
12920
  for (let i = 0; i < 50; i++) {
12787
12921
  const mid = (low + high) / 2;
12788
- if (contains(mid)) low = mid;
12922
+ if (isInsideNemaFace(mid * x, mid * y, profile6)) low = mid;
12789
12923
  else high = mid;
12790
12924
  }
12791
12925
  radius = low;
@@ -17401,19 +17535,25 @@ var roundedFace = (width10, radius) => {
17401
17535
  })
17402
17536
  );
17403
17537
  };
17404
- var steppedFace = (width10, chamfer) => {
17538
+ var steppedFace = (width10, chamfer, recessRadius, filletRadius) => {
17405
17539
  if (chamfer === 0) return face(width10, 0);
17406
17540
  const h = width10 / 2, c = chamfer / Math.SQRT2, r = Math.min(4, c / 4);
17407
17541
  const corner = [];
17408
- const arc = (x, y, from, to) => {
17542
+ const arc = (x, y, radius, from, to) => {
17543
+ if (radius === 0) {
17544
+ corner.push([x, y]);
17545
+ return;
17546
+ }
17409
17547
  for (let i = 0; i <= 12; i++) {
17410
17548
  const a = (from + (to - from) * i / 12) * Math.PI / 180;
17411
- corner.push([x + r * Math.cos(a), y + r * Math.sin(a)]);
17549
+ corner.push([x + radius * Math.cos(a), y + radius * Math.sin(a)]);
17412
17550
  }
17413
17551
  };
17414
- arc(h - c - r, h - r, 90, 0);
17415
- arc(h - c + r, h - c + r, 180, 270);
17416
- arc(h - r, h - c - r, 90, 0);
17552
+ const convex = filletRadius ?? r;
17553
+ const concave = recessRadius ?? r;
17554
+ arc(h - c - convex, h - convex, convex, 90, 0);
17555
+ arc(h - c + concave, h - c + concave, concave, 180, 270);
17556
+ arc(h - convex, h - c - convex, convex, 90, 0);
17417
17557
  return [0, 1, 2, 3].flatMap(
17418
17558
  (i) => corner.map(([x, y]) => {
17419
17559
  const a = -i * Math.PI / 2;
@@ -17434,12 +17574,18 @@ function createNemaMotorSections(input) {
17434
17574
  p.bodyWidth,
17435
17575
  p.faceCornerChamfer
17436
17576
  );
17437
- const profile6 = p.stepped ? steppedFace : face;
17438
- const core = profile6(p.bodyWidth, p.bodyCornerChamfer);
17439
- const rear = profile6(
17577
+ const core = p.stepped ? steppedFace(
17440
17578
  p.bodyWidth,
17441
- p.rearCornerChamfer ?? (p.backFacePlain && p.mountingHoleThrough ? p.bodyCornerChamfer : p.faceCornerChamfer)
17442
- );
17579
+ p.bodyCornerChamfer,
17580
+ p.bodyCornerRecessRadius,
17581
+ p.bodyCornerFilletRadius
17582
+ ) : face(p.bodyWidth, p.bodyCornerChamfer);
17583
+ const rear = p.rearStepped ? steppedFace(
17584
+ p.bodyWidth,
17585
+ p.rearCornerChamfer,
17586
+ p.rearCornerRecessRadius,
17587
+ p.rearCornerFilletRadius
17588
+ ) : face(p.bodyWidth, p.rearCornerChamfer);
17443
17589
  const h = p.mountingHoleSpacing / 2;
17444
17590
  const centers = [
17445
17591
  [-h, -h],
@@ -17457,9 +17603,10 @@ function createNemaMotorSections(input) {
17457
17603
  if (p.backFacePlain) {
17458
17604
  add("rearCap", rear, -p.bodyLength, -p.bodyLength + p.rearCapLength);
17459
17605
  } else {
17460
- const halfPitch = p.backFaceHoleSpacing / 2;
17461
- const rearHoles = [-halfPitch, halfPitch].flatMap(
17462
- (x) => [-halfPitch, halfPitch].map(
17606
+ const halfPitchX = p.backFaceHoleSpacingX / 2;
17607
+ const halfPitchY = p.backFaceHoleSpacingY / 2;
17608
+ const rearHoles = [-halfPitchX, halfPitchX].flatMap(
17609
+ (x) => [-halfPitchY, halfPitchY].map(
17463
17610
  (y) => circle(p.backFaceHoleDiameter / 2, x, y)
17464
17611
  )
17465
17612
  );
@@ -17484,12 +17631,12 @@ function createNemaMotorSections(input) {
17484
17631
  else {
17485
17632
  const cut = r - p.shaftFlatDepth;
17486
17633
  const angle = Math.acos(cut / r);
17487
- const profile7 = Array.from({ length: 97 }, (_, i) => {
17634
+ const profile6 = Array.from({ length: 97 }, (_, i) => {
17488
17635
  const a = angle + (2 * Math.PI - 2 * angle) * i / 96;
17489
17636
  return [r * Math.cos(a), r * Math.sin(a)];
17490
17637
  });
17491
17638
  const rotation = p.shaftFlatAngle * Math.PI / 180;
17492
- const d = profile7.map(([x, y]) => [
17639
+ const d = profile6.map(([x, y]) => [
17493
17640
  x * Math.cos(rotation) - y * Math.sin(rotation),
17494
17641
  x * Math.sin(rotation) + y * Math.cos(rotation)
17495
17642
  ]);
@@ -17519,7 +17666,8 @@ function NemaMotor({
17519
17666
  showThreads: false
17520
17667
  })
17521
17668
  ) : void 0;
17522
- const halfPitch = p.backFaceHoleSpacing / 2;
17669
+ const halfPitchX = p.backFaceHoleSpacingX / 2;
17670
+ const halfPitchY = p.backFaceHoleSpacingY / 2;
17523
17671
  return /* @__PURE__ */ jsxs17(Fragment17, { children: [
17524
17672
  createNemaMotorSections(p).map((section, index) => {
17525
17673
  const outline = jscad9.geometries.geom2.fromPoints(section.outline);
@@ -17564,8 +17712,8 @@ function NemaMotor({
17564
17712
  },
17565
17713
  `front-screw-${index}`
17566
17714
  )),
17567
- screw && [-halfPitch, halfPitch].flatMap(
17568
- (x) => [-halfPitch, halfPitch].map((y) => /* @__PURE__ */ jsx67(
17715
+ screw && [-halfPitchX, halfPitchX].flatMap(
17716
+ (x) => [-halfPitchY, halfPitchY].map((y) => /* @__PURE__ */ jsx67(
17569
17717
  Colorize33,
17570
17718
  {
17571
17719
  material: componentMaterials.steel,