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/vanilla.js CHANGED
@@ -24,7 +24,7 @@ function h(type, props, ...restChildren) {
24
24
  };
25
25
  }
26
26
 
27
- // .model-contracts/generations/e80fbad5260b66fd00b4ab7513941eadd9b0b17b-v2/node_modules/zod/v3/external.js
27
+ // .model-contracts/generations/ad649bc7a403a3e6e9b12ce32ac0b3d0fa61c6bf-v2/node_modules/zod/v3/external.js
28
28
  var external_exports = {};
29
29
  __export(external_exports, {
30
30
  BRAND: () => BRAND,
@@ -136,7 +136,7 @@ __export(external_exports, {
136
136
  void: () => voidType
137
137
  });
138
138
 
139
- // .model-contracts/generations/e80fbad5260b66fd00b4ab7513941eadd9b0b17b-v2/node_modules/zod/v3/helpers/util.js
139
+ // .model-contracts/generations/ad649bc7a403a3e6e9b12ce32ac0b3d0fa61c6bf-v2/node_modules/zod/v3/helpers/util.js
140
140
  var util;
141
141
  (function(util2) {
142
142
  util2.assertEqual = (_) => {
@@ -270,7 +270,7 @@ var getParsedType = (data) => {
270
270
  }
271
271
  };
272
272
 
273
- // .model-contracts/generations/e80fbad5260b66fd00b4ab7513941eadd9b0b17b-v2/node_modules/zod/v3/ZodError.js
273
+ // .model-contracts/generations/ad649bc7a403a3e6e9b12ce32ac0b3d0fa61c6bf-v2/node_modules/zod/v3/ZodError.js
274
274
  var ZodIssueCode = util.arrayToEnum([
275
275
  "invalid_type",
276
276
  "invalid_literal",
@@ -388,7 +388,7 @@ ZodError.create = (issues) => {
388
388
  return error;
389
389
  };
390
390
 
391
- // .model-contracts/generations/e80fbad5260b66fd00b4ab7513941eadd9b0b17b-v2/node_modules/zod/v3/locales/en.js
391
+ // .model-contracts/generations/ad649bc7a403a3e6e9b12ce32ac0b3d0fa61c6bf-v2/node_modules/zod/v3/locales/en.js
392
392
  var errorMap = (issue, _ctx) => {
393
393
  let message;
394
394
  switch (issue.code) {
@@ -491,7 +491,7 @@ var errorMap = (issue, _ctx) => {
491
491
  };
492
492
  var en_default = errorMap;
493
493
 
494
- // .model-contracts/generations/e80fbad5260b66fd00b4ab7513941eadd9b0b17b-v2/node_modules/zod/v3/errors.js
494
+ // .model-contracts/generations/ad649bc7a403a3e6e9b12ce32ac0b3d0fa61c6bf-v2/node_modules/zod/v3/errors.js
495
495
  var overrideErrorMap = en_default;
496
496
  function setErrorMap(map) {
497
497
  overrideErrorMap = map;
@@ -500,7 +500,7 @@ function getErrorMap() {
500
500
  return overrideErrorMap;
501
501
  }
502
502
 
503
- // .model-contracts/generations/e80fbad5260b66fd00b4ab7513941eadd9b0b17b-v2/node_modules/zod/v3/helpers/parseUtil.js
503
+ // .model-contracts/generations/ad649bc7a403a3e6e9b12ce32ac0b3d0fa61c6bf-v2/node_modules/zod/v3/helpers/parseUtil.js
504
504
  var makeIssue = (params) => {
505
505
  const { data, path, errorMaps, issueData } = params;
506
506
  const fullPath = [...path, ...issueData.path || []];
@@ -610,14 +610,14 @@ var isDirty = (x) => x.status === "dirty";
610
610
  var isValid = (x) => x.status === "valid";
611
611
  var isAsync = (x) => typeof Promise !== "undefined" && x instanceof Promise;
612
612
 
613
- // .model-contracts/generations/e80fbad5260b66fd00b4ab7513941eadd9b0b17b-v2/node_modules/zod/v3/helpers/errorUtil.js
613
+ // .model-contracts/generations/ad649bc7a403a3e6e9b12ce32ac0b3d0fa61c6bf-v2/node_modules/zod/v3/helpers/errorUtil.js
614
614
  var errorUtil;
615
615
  (function(errorUtil2) {
616
616
  errorUtil2.errToObj = (message) => typeof message === "string" ? { message } : message || {};
617
617
  errorUtil2.toString = (message) => typeof message === "string" ? message : message?.message;
618
618
  })(errorUtil || (errorUtil = {}));
619
619
 
620
- // .model-contracts/generations/e80fbad5260b66fd00b4ab7513941eadd9b0b17b-v2/node_modules/zod/v3/types.js
620
+ // .model-contracts/generations/ad649bc7a403a3e6e9b12ce32ac0b3d0fa61c6bf-v2/node_modules/zod/v3/types.js
621
621
  var ParseInputLazyPath = class {
622
622
  constructor(parent, value, path, key) {
623
623
  this._cachedPath = [];
@@ -4065,7 +4065,7 @@ var coerce = {
4065
4065
  };
4066
4066
  var NEVER = INVALID;
4067
4067
 
4068
- // .model-contracts/generations/e80fbad5260b66fd00b4ab7513941eadd9b0b17b-v2/node_modules/@tscircuit/mm/dist/index.js
4068
+ // .model-contracts/generations/ad649bc7a403a3e6e9b12ce32ac0b3d0fa61c6bf-v2/node_modules/@tscircuit/mm/dist/index.js
4069
4069
  var unitToMm = {
4070
4070
  in: 25.4,
4071
4071
  inch: 25.4,
@@ -4092,7 +4092,7 @@ var mm = (n) => {
4092
4092
  throw new Error(`Unsupported unit: ${unit}`);
4093
4093
  };
4094
4094
 
4095
- // .model-contracts/generations/e80fbad5260b66fd00b4ab7513941eadd9b0b17b-v2/index.js
4095
+ // .model-contracts/generations/ad649bc7a403a3e6e9b12ce32ac0b3d0fa61c6bf-v2/index.js
4096
4096
  function normalizeNemaMotorModelString(value) {
4097
4097
  if (!/^nema(?:8|17|23|34)(?:_|$)/i.test(value)) return value;
4098
4098
  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");
@@ -4647,6 +4647,76 @@ var jstMotorWireConnectionSchema = external_exports.string().refine((value) => {
4647
4647
  const connector = getJstMotorConnector(value);
4648
4648
  return connector !== void 0 && connector.pinCount >= 2 && connector.pinCount <= connector.maxPinCount;
4649
4649
  }, "Expected jst-ph-N (2\u201316 pins) or jst-sh-N (2\u201315 pins)");
4650
+ function isInsideNemaFace(x, y, p) {
4651
+ const h2 = p.width / 2;
4652
+ x = Math.abs(x);
4653
+ y = Math.abs(y);
4654
+ if (x > h2 || y > h2) return false;
4655
+ const chamfer = p.chamfer;
4656
+ if (!p.stepped) return x + y <= 2 * h2 - chamfer;
4657
+ const c = chamfer / Math.SQRT2;
4658
+ if (c === 0) return true;
4659
+ const recess = p.recessRadius;
4660
+ const fillet = p.filletRadius;
4661
+ const k = h2 - c + recess;
4662
+ if (x > h2 - c && y > h2 - c)
4663
+ return x <= k && y <= k && Math.hypot(x - k, y - k) >= recess;
4664
+ if (y > h2 - fillet && x > h2 - c - fillet)
4665
+ return Math.hypot(x - (h2 - c - fillet), y - (h2 - fillet)) <= fillet;
4666
+ if (x > h2 - fillet && y > h2 - c - fillet)
4667
+ return Math.hypot(x - (h2 - fillet), y - (h2 - c - fillet)) <= fillet;
4668
+ return true;
4669
+ }
4670
+ var segmentDistance = (x, y, ax, ay, bx, by) => {
4671
+ const dx = bx - ax;
4672
+ const dy = by - ay;
4673
+ const t = Math.max(
4674
+ 0,
4675
+ Math.min(1, ((x - ax) * dx + (y - ay) * dy) / (dx * dx + dy * dy || 1))
4676
+ );
4677
+ return Math.hypot(x - ax - t * dx, y - ay - t * dy);
4678
+ };
4679
+ var arcDistance = (x, y, cx, cy, r, start, end) => {
4680
+ const angle = (Math.atan2(y - cy, x - cx) + 2 * Math.PI) % (2 * Math.PI);
4681
+ if (angle >= start && angle <= end)
4682
+ return Math.abs(Math.hypot(x - cx, y - cy) - r);
4683
+ return Math.min(
4684
+ Math.hypot(x - cx - r * Math.cos(start), y - cy - r * Math.sin(start)),
4685
+ Math.hypot(x - cx - r * Math.cos(end), y - cy - r * Math.sin(end))
4686
+ );
4687
+ };
4688
+ var boundaryDistance = (x, y, p) => {
4689
+ const h2 = p.width / 2;
4690
+ x = Math.abs(x);
4691
+ y = Math.abs(y);
4692
+ const chamfer = p.chamfer;
4693
+ if (!p.stepped || chamfer === 0)
4694
+ return Math.min(
4695
+ Math.abs(h2 - x),
4696
+ Math.abs(h2 - y),
4697
+ Math.abs(2 * h2 - chamfer - x - y) / Math.SQRT2
4698
+ );
4699
+ const c = chamfer / Math.SQRT2;
4700
+ const recess = p.recessRadius;
4701
+ const fillet = p.filletRadius;
4702
+ const a = h2 - c - fillet;
4703
+ const k = h2 - c + recess;
4704
+ return Math.min(
4705
+ segmentDistance(x, y, -a, h2, a, h2),
4706
+ segmentDistance(x, y, h2, -a, h2, a),
4707
+ segmentDistance(x, y, h2 - c, h2 - fillet, h2 - c, k),
4708
+ segmentDistance(x, y, k, h2 - c, h2 - fillet, h2 - c),
4709
+ arcDistance(x, y, a, h2 - fillet, fillet, 0, Math.PI / 2),
4710
+ arcDistance(x, y, k, k, recess, Math.PI, 3 * Math.PI / 2),
4711
+ arcDistance(x, y, h2 - fillet, a, fillet, 0, Math.PI / 2)
4712
+ );
4713
+ };
4714
+ function fitsNemaCircle(x, y, radius, p) {
4715
+ return isInsideNemaFace(x, y, p) && boundaryDistance(x, y, p) > radius;
4716
+ }
4717
+ function clearsNemaCircle(x, y, radius, p) {
4718
+ return !isInsideNemaFace(x, y, p) && boundaryDistance(x, y, p) > radius;
4719
+ }
4650
4720
  var hexSocketBoltDimensions = {
4651
4721
  M2: {
4652
4722
  diameter: 2,
@@ -4797,7 +4867,15 @@ var nemaMotorDimensions = {
4797
4867
  bodyCornerChamfer: 6
4798
4868
  },
4799
4869
  23: {
4800
- backFaceScrewSize: "M4",
4870
+ // Representative side-tab rear pattern from STEPPERONLINE's ST-M10 adapter.
4871
+ // The adapter's R5/R2.5 profile is a visual reference, not a frame guarantee:
4872
+ // https://www.omc-stepperonline.com/image/catalog/dimensions/ST-M10_Dimension.svg
4873
+ backFaceHoleSpacing: 50,
4874
+ backFaceHoleSpacingY: 32,
4875
+ rearCornerChamfer: 9 * Math.SQRT2,
4876
+ rearCornerRecessRadius: 5,
4877
+ rearCornerFilletRadius: 2.5,
4878
+ backFaceScrewSize: "M3",
4801
4879
  backFaceHoleDepth: 4.5,
4802
4880
  bodyWidth: 56.4,
4803
4881
  bodyLength: 51,
@@ -4817,7 +4895,10 @@ var nemaMotorDimensions = {
4817
4895
  frontCapLength: 5,
4818
4896
  rearCapLength: 5,
4819
4897
  faceCornerChamfer: 2,
4820
- bodyCornerChamfer: 15
4898
+ bodyCornerChamfer: 9 * Math.SQRT2,
4899
+ bodyCornerRecessRadius: 5,
4900
+ bodyCornerFilletRadius: 2.5,
4901
+ chamferedBodyCornerChamfer: 15
4821
4902
  },
4822
4903
  34: {
4823
4904
  // Illustrative rear details; independent of the mounting flange.
@@ -4853,6 +4934,9 @@ var shape3 = {
4853
4934
  backFaceHoles: external_exports.boolean().optional(),
4854
4935
  backFaceScrews: external_exports.boolean().optional(),
4855
4936
  backFaceHoleSpacing: positiveModelLengthSchema.optional(),
4937
+ /** Axis overrides; the legacy scalar still sets a square pattern when supplied. */
4938
+ backFaceHoleSpacingX: positiveModelLengthSchema.optional(),
4939
+ backFaceHoleSpacingY: positiveModelLengthSchema.optional(),
4856
4940
  backFaceHoleDiameter: positiveModelLengthSchema.optional(),
4857
4941
  backFaceHoleDepth: positiveModelLengthSchema.optional(),
4858
4942
  backFaceScrewSize: metricBoltSizeSchema.optional(),
@@ -4889,8 +4973,14 @@ var shape3 = {
4889
4973
  rearCapLength: positiveModelLengthSchema.optional(),
4890
4974
  faceCornerChamfer: nonnegativeModelLengthSchema.optional(),
4891
4975
  bodyCornerChamfer: nonnegativeModelLengthSchema.optional(),
4976
+ bodyCornerRecessRadius: nonnegativeModelLengthSchema.optional(),
4977
+ bodyCornerFilletRadius: nonnegativeModelLengthSchema.optional(),
4892
4978
  /** Rear outline is independent of the front mounting flange. */
4893
4979
  rearCornerChamfer: nonnegativeModelLengthSchema.optional(),
4980
+ rearCornerRecessRadius: nonnegativeModelLengthSchema.optional(),
4981
+ rearCornerFilletRadius: nonnegativeModelLengthSchema.optional(),
4982
+ rearChamfered: external_exports.boolean().optional(),
4983
+ rearStepped: external_exports.boolean().optional(),
4894
4984
  chamfered: external_exports.boolean().optional(),
4895
4985
  stepped: external_exports.boolean().optional()
4896
4986
  };
@@ -4915,7 +5005,11 @@ var resolve = (p, ctx) => {
4915
5005
  );
4916
5006
  const corner = select(
4917
5007
  ["chamfered", "stepped"],
4918
- p.nemaSize === 34 ? "stepped" : "chamfered"
5008
+ p.nemaSize === 23 || p.nemaSize === 34 ? "stepped" : "chamfered"
5009
+ );
5010
+ const rearCorner = select(
5011
+ ["rearChamfered", "rearStepped"],
5012
+ p.chamfered === true ? "rearChamfered" : p.nemaSize === 23 || corner === "stepped" ? "rearStepped" : "rearChamfered"
4919
5013
  );
4920
5014
  const wireSpecified = p.noWires !== void 0 || p.wireStubs !== void 0 || p.wireConnection !== void 0;
4921
5015
  const wireSelections = Number(p.noWires === true) + Number(p.wireStubs === true) + Number(p.wireConnection !== void 0);
@@ -4925,8 +5019,13 @@ var resolve = (p, ctx) => {
4925
5019
  message: "Select exactly one of noWires, wireStubs or a JST wireConnection"
4926
5020
  });
4927
5021
  const d = nemaMotorDimensions[p.nemaSize];
5022
+ const bodyCornerChamfer = p.bodyCornerChamfer ?? (corner === "chamfered" && "chamferedBodyCornerChamfer" in d ? d.chamferedBodyCornerChamfer : d.bodyCornerChamfer);
5023
+ const defaultBodyRadius = Math.min(4, bodyCornerChamfer / Math.SQRT2 / 4);
4928
5024
  const backFaceScrewSize = p.backFaceScrewSize ?? d.backFaceScrewSize;
4929
5025
  const screw = hexSocketBoltDimensions[backFaceScrewSize];
5026
+ const backFaceHoleSpacing = p.backFaceHoleSpacing ?? ("backFaceHoleSpacing" in d ? d.backFaceHoleSpacing : p.mountingHoleSpacing ?? d.mountingHoleSpacing);
5027
+ 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);
5028
+ const defaultRearRadius = Math.min(4, rearCornerChamfer / Math.SQRT2 / 4);
4930
5029
  return {
4931
5030
  nemaSize: p.nemaSize,
4932
5031
  noWires: p.noWires === true,
@@ -4939,7 +5038,9 @@ var resolve = (p, ctx) => {
4939
5038
  backFacePlain: back === "backFacePlain",
4940
5039
  backFaceHoles: back === "backFaceHoles",
4941
5040
  backFaceScrews: back === "backFaceScrews",
4942
- backFaceHoleSpacing: p.backFaceHoleSpacing ?? ("backFaceHoleSpacing" in d ? d.backFaceHoleSpacing : p.mountingHoleSpacing ?? d.mountingHoleSpacing),
5041
+ backFaceHoleSpacing,
5042
+ backFaceHoleSpacingX: p.backFaceHoleSpacingX ?? backFaceHoleSpacing,
5043
+ backFaceHoleSpacingY: p.backFaceHoleSpacingY ?? p.backFaceHoleSpacing ?? ("backFaceHoleSpacingY" in d ? d.backFaceHoleSpacingY : backFaceHoleSpacing),
4943
5044
  backFaceHoleDiameter: p.backFaceHoleDiameter ?? screw.diameter,
4944
5045
  backFaceHoleDepth: p.backFaceHoleDepth ?? d.backFaceHoleDepth,
4945
5046
  backFaceScrewSize,
@@ -4961,24 +5062,43 @@ var resolve = (p, ctx) => {
4961
5062
  frontCapLength: p.frontCapLength ?? d.frontCapLength,
4962
5063
  rearCapLength: p.rearCapLength ?? d.rearCapLength,
4963
5064
  faceCornerChamfer: p.faceCornerChamfer ?? d.faceCornerChamfer,
4964
- bodyCornerChamfer: p.bodyCornerChamfer ?? d.bodyCornerChamfer,
5065
+ bodyCornerChamfer,
5066
+ bodyCornerRecessRadius: p.bodyCornerRecessRadius ?? ("bodyCornerRecessRadius" in d ? d.bodyCornerRecessRadius : defaultBodyRadius),
5067
+ bodyCornerFilletRadius: p.bodyCornerFilletRadius ?? ("bodyCornerFilletRadius" in d ? d.bodyCornerFilletRadius : defaultBodyRadius),
4965
5068
  chamfered: corner === "chamfered",
4966
5069
  stepped: corner === "stepped",
4967
- ..."rearCornerChamfer" in d || p.rearCornerChamfer !== void 0 ? {
4968
- rearCornerChamfer: p.rearCornerChamfer ?? ("rearCornerChamfer" in d ? d.rearCornerChamfer : p.faceCornerChamfer ?? d.faceCornerChamfer)
4969
- } : {}
5070
+ rearCornerChamfer,
5071
+ rearStepped: rearCorner === "rearStepped",
5072
+ rearChamfered: rearCorner === "rearChamfered",
5073
+ rearCornerRecessRadius: p.rearCornerRecessRadius ?? ("rearCornerRecessRadius" in d ? d.rearCornerRecessRadius : defaultRearRadius),
5074
+ rearCornerFilletRadius: p.rearCornerFilletRadius ?? ("rearCornerFilletRadius" in d ? d.rearCornerFilletRadius : defaultRearRadius)
4970
5075
  };
4971
5076
  };
4972
5077
  var validate3 = (p, ctx) => {
4973
5078
  const issue = (message) => ctx.addIssue({ code: "custom", message });
5079
+ if (p.stepped && p.bodyCornerRecessRadius + p.bodyCornerFilletRadius > p.bodyCornerChamfer / Math.SQRT2)
5080
+ issue("Body recess and fillet radii must fit within the corner shoulder");
4974
5081
  const rearChamfer = p.rearCornerChamfer ?? (p.backFacePlain && p.mountingHoleThrough ? p.bodyCornerChamfer : p.faceCornerChamfer);
4975
- const rearEdge = p.stepped ? rearChamfer / Math.SQRT2 : rearChamfer;
5082
+ const rearEdge = p.rearStepped ? rearChamfer / Math.SQRT2 : rearChamfer;
5083
+ if (p.rearStepped && p.rearCornerRecessRadius + p.rearCornerFilletRadius > rearEdge)
5084
+ issue("Rear recess and fillet radii must fit within the corner shoulder");
4976
5085
  if (!p.backFacePlain) {
4977
5086
  const screw = hexSocketBoltDimensions[p.backFaceScrewSize];
4978
5087
  const radius = (p.backFaceScrews ? Math.max(p.backFaceHoleDiameter, screw.headDiameter) : p.backFaceHoleDiameter) / 2;
4979
- if (p.backFaceHoleSpacing <= 2 * radius)
5088
+ if (p.backFaceHoleSpacingX <= 2 * radius || p.backFaceHoleSpacingY <= 2 * radius)
4980
5089
  issue("Rear holes and screw heads must not overlap each other");
4981
- 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))
5090
+ if (!fitsNemaCircle(
5091
+ p.backFaceHoleSpacingX / 2,
5092
+ p.backFaceHoleSpacingY / 2,
5093
+ radius,
5094
+ {
5095
+ width: p.bodyWidth,
5096
+ chamfer: p.rearCornerChamfer,
5097
+ stepped: p.rearStepped,
5098
+ recessRadius: p.rearCornerRecessRadius,
5099
+ filletRadius: p.rearCornerFilletRadius
5100
+ }
5101
+ ))
4982
5102
  issue("Rear holes and screw heads must fit entirely inside the rear face");
4983
5103
  if (p.backFaceHoleDepth >= p.rearCapLength)
4984
5104
  issue("Rear hole depth must be less than the rear cap length");
@@ -5009,7 +5129,13 @@ var validate3 = (p, ctx) => {
5009
5129
  issue("Mounting holes must clear the pilot");
5010
5130
  if (!p.mountingHoleThrough && p.mountingHoleDepth >= p.frontCapLength)
5011
5131
  issue("Blind mounting hole depth must be less than the front cap length");
5012
- 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))
5132
+ if (p.mountingHoleThrough && !clearsNemaCircle(p.mountingHoleSpacing / 2, p.mountingHoleSpacing / 2, r, {
5133
+ width: p.bodyWidth,
5134
+ chamfer: p.bodyCornerChamfer,
5135
+ stepped: p.stepped,
5136
+ recessRadius: p.bodyCornerRecessRadius,
5137
+ filletRadius: p.bodyCornerFilletRadius
5138
+ }))
5013
5139
  issue("Body must clear through front mounting holes");
5014
5140
  if (p.shaftLength <= p.pilotLength)
5015
5141
  issue("Shaft tip must extend beyond the pilot");
@@ -5028,6 +5154,8 @@ var lengths2 = {
5028
5154
  bodylength: "bodyLength",
5029
5155
  bodywidth: "bodyWidth",
5030
5156
  backholespacing: "backFaceHoleSpacing",
5157
+ backholespacingx: "backFaceHoleSpacingX",
5158
+ backholespacingy: "backFaceHoleSpacingY",
5031
5159
  backholediameter: "backFaceHoleDiameter",
5032
5160
  backholedepth: "backFaceHoleDepth",
5033
5161
  shaftlength: "shaftLength",
@@ -5043,7 +5171,11 @@ var lengths2 = {
5043
5171
  rearcap: "rearCapLength",
5044
5172
  facechamfer: "faceCornerChamfer",
5045
5173
  bodychamfer: "bodyCornerChamfer",
5046
- rearchamfer: "rearCornerChamfer"
5174
+ bodyrecess: "bodyCornerRecessRadius",
5175
+ bodyfillet: "bodyCornerFilletRadius",
5176
+ rearchamfer: "rearCornerChamfer",
5177
+ rearrecess: "rearCornerRecessRadius",
5178
+ rearfillet: "rearCornerFilletRadius"
5047
5179
  };
5048
5180
  var flags = {
5049
5181
  backfaceplain: "backFacePlain",
@@ -5055,6 +5187,8 @@ var flags = {
5055
5187
  dshaft: "dShaft",
5056
5188
  chamfered: "chamfered",
5057
5189
  stepped: "stepped",
5190
+ rearstepped: "rearStepped",
5191
+ rearchamfered: "rearChamfered",
5058
5192
  nowires: "noWires",
5059
5193
  wirestubs: "wireStubs"
5060
5194
  };
@@ -12044,24 +12178,24 @@ function getNemaMotorReferencePoints(input) {
12044
12178
  p.bodyWidth / 2 / Math.max(Math.abs(x), Math.abs(y)),
12045
12179
  (p.bodyWidth - p.faceCornerChamfer) / (Math.abs(x) + Math.abs(y))
12046
12180
  );
12047
- if (p.nemaSize === 34 && p.stepped) {
12048
- const h2 = p.bodyWidth / 2, c = p.bodyCornerChamfer / Math.SQRT2, r = Math.min(4, c / 4);
12049
- const contains = (distance2) => {
12050
- const a = Math.abs(distance2 * x), b = Math.abs(distance2 * y);
12051
- if (a > h2 || b > h2) return false;
12052
- if (c === 0) return true;
12053
- if (a > h2 - c && b > h2 - c)
12054
- return a <= h2 - c + r && b <= h2 - c + r && Math.hypot(a - (h2 - c + r), b - (h2 - c + r)) >= r;
12055
- if (b > h2 - r && a > h2 - c - r)
12056
- return Math.hypot(a - (h2 - c - r), b - (h2 - r)) <= r;
12057
- if (a > h2 - r && b > h2 - c - r)
12058
- return Math.hypot(a - (h2 - r), b - (h2 - c - r)) <= r;
12059
- return true;
12181
+ if (p.nemaSize !== 34 || p.stepped) {
12182
+ const profile6 = p.nemaSize === 34 ? {
12183
+ width: p.bodyWidth,
12184
+ chamfer: p.bodyCornerChamfer,
12185
+ stepped: p.stepped,
12186
+ recessRadius: p.bodyCornerRecessRadius,
12187
+ filletRadius: p.bodyCornerFilletRadius
12188
+ } : {
12189
+ width: p.bodyWidth,
12190
+ chamfer: p.rearCornerChamfer,
12191
+ stepped: p.rearStepped,
12192
+ recessRadius: p.rearCornerRecessRadius,
12193
+ filletRadius: p.rearCornerFilletRadius
12060
12194
  };
12061
12195
  let low = 0, high = p.bodyWidth;
12062
12196
  for (let i = 0; i < 50; i++) {
12063
12197
  const mid = (low + high) / 2;
12064
- if (contains(mid)) low = mid;
12198
+ if (isInsideNemaFace(mid * x, mid * y, profile6)) low = mid;
12065
12199
  else high = mid;
12066
12200
  }
12067
12201
  radius = low;
@@ -16556,19 +16690,25 @@ var roundedFace = (width10, radius) => {
16556
16690
  })
16557
16691
  );
16558
16692
  };
16559
- var steppedFace = (width10, chamfer) => {
16693
+ var steppedFace = (width10, chamfer, recessRadius, filletRadius) => {
16560
16694
  if (chamfer === 0) return face(width10, 0);
16561
16695
  const h2 = width10 / 2, c = chamfer / Math.SQRT2, r = Math.min(4, c / 4);
16562
16696
  const corner = [];
16563
- const arc = (x, y, from, to) => {
16697
+ const arc = (x, y, radius, from, to) => {
16698
+ if (radius === 0) {
16699
+ corner.push([x, y]);
16700
+ return;
16701
+ }
16564
16702
  for (let i = 0; i <= 12; i++) {
16565
16703
  const a = (from + (to - from) * i / 12) * Math.PI / 180;
16566
- corner.push([x + r * Math.cos(a), y + r * Math.sin(a)]);
16704
+ corner.push([x + radius * Math.cos(a), y + radius * Math.sin(a)]);
16567
16705
  }
16568
16706
  };
16569
- arc(h2 - c - r, h2 - r, 90, 0);
16570
- arc(h2 - c + r, h2 - c + r, 180, 270);
16571
- arc(h2 - r, h2 - c - r, 90, 0);
16707
+ const convex = filletRadius ?? r;
16708
+ const concave = recessRadius ?? r;
16709
+ arc(h2 - c - convex, h2 - convex, convex, 90, 0);
16710
+ arc(h2 - c + concave, h2 - c + concave, concave, 180, 270);
16711
+ arc(h2 - convex, h2 - c - convex, convex, 90, 0);
16572
16712
  return [0, 1, 2, 3].flatMap(
16573
16713
  (i) => corner.map(([x, y]) => {
16574
16714
  const a = -i * Math.PI / 2;
@@ -16589,12 +16729,18 @@ function createNemaMotorSections(input) {
16589
16729
  p.bodyWidth,
16590
16730
  p.faceCornerChamfer
16591
16731
  );
16592
- const profile6 = p.stepped ? steppedFace : face;
16593
- const core = profile6(p.bodyWidth, p.bodyCornerChamfer);
16594
- const rear = profile6(
16732
+ const core = p.stepped ? steppedFace(
16595
16733
  p.bodyWidth,
16596
- p.rearCornerChamfer ?? (p.backFacePlain && p.mountingHoleThrough ? p.bodyCornerChamfer : p.faceCornerChamfer)
16597
- );
16734
+ p.bodyCornerChamfer,
16735
+ p.bodyCornerRecessRadius,
16736
+ p.bodyCornerFilletRadius
16737
+ ) : face(p.bodyWidth, p.bodyCornerChamfer);
16738
+ const rear = p.rearStepped ? steppedFace(
16739
+ p.bodyWidth,
16740
+ p.rearCornerChamfer,
16741
+ p.rearCornerRecessRadius,
16742
+ p.rearCornerFilletRadius
16743
+ ) : face(p.bodyWidth, p.rearCornerChamfer);
16598
16744
  const h2 = p.mountingHoleSpacing / 2;
16599
16745
  const centers = [
16600
16746
  [-h2, -h2],
@@ -16612,9 +16758,10 @@ function createNemaMotorSections(input) {
16612
16758
  if (p.backFacePlain) {
16613
16759
  add("rearCap", rear, -p.bodyLength, -p.bodyLength + p.rearCapLength);
16614
16760
  } else {
16615
- const halfPitch = p.backFaceHoleSpacing / 2;
16616
- const rearHoles = [-halfPitch, halfPitch].flatMap(
16617
- (x) => [-halfPitch, halfPitch].map(
16761
+ const halfPitchX = p.backFaceHoleSpacingX / 2;
16762
+ const halfPitchY = p.backFaceHoleSpacingY / 2;
16763
+ const rearHoles = [-halfPitchX, halfPitchX].flatMap(
16764
+ (x) => [-halfPitchY, halfPitchY].map(
16618
16765
  (y) => circle(p.backFaceHoleDiameter / 2, x, y)
16619
16766
  )
16620
16767
  );
@@ -16639,12 +16786,12 @@ function createNemaMotorSections(input) {
16639
16786
  else {
16640
16787
  const cut = r - p.shaftFlatDepth;
16641
16788
  const angle = Math.acos(cut / r);
16642
- const profile7 = Array.from({ length: 97 }, (_, i) => {
16789
+ const profile6 = Array.from({ length: 97 }, (_, i) => {
16643
16790
  const a = angle + (2 * Math.PI - 2 * angle) * i / 96;
16644
16791
  return [r * Math.cos(a), r * Math.sin(a)];
16645
16792
  });
16646
16793
  const rotation = p.shaftFlatAngle * Math.PI / 180;
16647
- const d = profile7.map(([x, y]) => [
16794
+ const d = profile6.map(([x, y]) => [
16648
16795
  x * Math.cos(rotation) - y * Math.sin(rotation),
16649
16796
  x * Math.sin(rotation) + y * Math.cos(rotation)
16650
16797
  ]);
@@ -16672,7 +16819,8 @@ function NemaMotor({
16672
16819
  showThreads: false
16673
16820
  })
16674
16821
  ) : void 0;
16675
- const halfPitch = p.backFaceHoleSpacing / 2;
16822
+ const halfPitchX = p.backFaceHoleSpacingX / 2;
16823
+ const halfPitchY = p.backFaceHoleSpacingY / 2;
16676
16824
  return /* @__PURE__ */ jsxs(Fragment2, { children: [
16677
16825
  createNemaMotorSections(p).map((section, index) => {
16678
16826
  const outline = jscad9.geometries.geom2.fromPoints(section.outline);
@@ -16717,8 +16865,8 @@ function NemaMotor({
16717
16865
  },
16718
16866
  `front-screw-${index}`
16719
16867
  )),
16720
- screw && [-halfPitch, halfPitch].flatMap(
16721
- (x) => [-halfPitch, halfPitch].map((y) => /* @__PURE__ */ jsx(
16868
+ screw && [-halfPitchX, halfPitchX].flatMap(
16869
+ (x) => [-halfPitchY, halfPitchY].map((y) => /* @__PURE__ */ jsx(
16722
16870
  Colorize,
16723
16871
  {
16724
16872
  material: componentMaterials.steel,