jscad-electronics 0.0.233 → 0.0.235

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/324045ff5a8d957b84ad80e3a428461bb10e4259-v2/node_modules/zod/v3/external.js
27
+ // .model-contracts/generations/344775224814556adaec789fbc570ee91a9e4064-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/324045ff5a8d957b84ad80e3a428461bb10e4259-v2/node_modules/zod/v3/helpers/util.js
139
+ // .model-contracts/generations/344775224814556adaec789fbc570ee91a9e4064-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/324045ff5a8d957b84ad80e3a428461bb10e4259-v2/node_modules/zod/v3/ZodError.js
273
+ // .model-contracts/generations/344775224814556adaec789fbc570ee91a9e4064-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/324045ff5a8d957b84ad80e3a428461bb10e4259-v2/node_modules/zod/v3/locales/en.js
391
+ // .model-contracts/generations/344775224814556adaec789fbc570ee91a9e4064-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/324045ff5a8d957b84ad80e3a428461bb10e4259-v2/node_modules/zod/v3/errors.js
494
+ // .model-contracts/generations/344775224814556adaec789fbc570ee91a9e4064-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/324045ff5a8d957b84ad80e3a428461bb10e4259-v2/node_modules/zod/v3/helpers/parseUtil.js
503
+ // .model-contracts/generations/344775224814556adaec789fbc570ee91a9e4064-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/324045ff5a8d957b84ad80e3a428461bb10e4259-v2/node_modules/zod/v3/helpers/errorUtil.js
613
+ // .model-contracts/generations/344775224814556adaec789fbc570ee91a9e4064-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/324045ff5a8d957b84ad80e3a428461bb10e4259-v2/node_modules/zod/v3/types.js
620
+ // .model-contracts/generations/344775224814556adaec789fbc570ee91a9e4064-v2/node_modules/zod/v3/types.js
621
621
  var ParseInputLazyPath = class {
622
622
  constructor(parent, value, path, key) {
623
623
  this._cachedPath = [];
@@ -2402,9 +2402,9 @@ var ZodObject = class _ZodObject extends ZodType {
2402
2402
  _getCached() {
2403
2403
  if (this._cached !== null)
2404
2404
  return this._cached;
2405
- const shape44 = this._def.shape();
2406
- const keys = util.objectKeys(shape44);
2407
- this._cached = { shape: shape44, keys };
2405
+ const shape46 = this._def.shape();
2406
+ const keys = util.objectKeys(shape46);
2407
+ this._cached = { shape: shape46, keys };
2408
2408
  return this._cached;
2409
2409
  }
2410
2410
  _parse(input) {
@@ -2419,7 +2419,7 @@ var ZodObject = class _ZodObject extends ZodType {
2419
2419
  return INVALID;
2420
2420
  }
2421
2421
  const { status, ctx } = this._processInputParams(input);
2422
- const { shape: shape44, keys: shapeKeys } = this._getCached();
2422
+ const { shape: shape46, keys: shapeKeys } = this._getCached();
2423
2423
  const extraKeys = [];
2424
2424
  if (!(this._def.catchall instanceof ZodNever && this._def.unknownKeys === "strip")) {
2425
2425
  for (const key in ctx.data) {
@@ -2430,7 +2430,7 @@ var ZodObject = class _ZodObject extends ZodType {
2430
2430
  }
2431
2431
  const pairs = [];
2432
2432
  for (const key of shapeKeys) {
2433
- const keyValidator = shape44[key];
2433
+ const keyValidator = shape46[key];
2434
2434
  const value = ctx.data[key];
2435
2435
  pairs.push({
2436
2436
  key: { status: "valid", value: key },
@@ -2636,27 +2636,27 @@ var ZodObject = class _ZodObject extends ZodType {
2636
2636
  });
2637
2637
  }
2638
2638
  pick(mask) {
2639
- const shape44 = {};
2639
+ const shape46 = {};
2640
2640
  for (const key of util.objectKeys(mask)) {
2641
2641
  if (mask[key] && this.shape[key]) {
2642
- shape44[key] = this.shape[key];
2642
+ shape46[key] = this.shape[key];
2643
2643
  }
2644
2644
  }
2645
2645
  return new _ZodObject({
2646
2646
  ...this._def,
2647
- shape: () => shape44
2647
+ shape: () => shape46
2648
2648
  });
2649
2649
  }
2650
2650
  omit(mask) {
2651
- const shape44 = {};
2651
+ const shape46 = {};
2652
2652
  for (const key of util.objectKeys(this.shape)) {
2653
2653
  if (!mask[key]) {
2654
- shape44[key] = this.shape[key];
2654
+ shape46[key] = this.shape[key];
2655
2655
  }
2656
2656
  }
2657
2657
  return new _ZodObject({
2658
2658
  ...this._def,
2659
- shape: () => shape44
2659
+ shape: () => shape46
2660
2660
  });
2661
2661
  }
2662
2662
  /**
@@ -2703,27 +2703,27 @@ var ZodObject = class _ZodObject extends ZodType {
2703
2703
  return createZodEnum(util.objectKeys(this.shape));
2704
2704
  }
2705
2705
  };
2706
- ZodObject.create = (shape44, params) => {
2706
+ ZodObject.create = (shape46, params) => {
2707
2707
  return new ZodObject({
2708
- shape: () => shape44,
2708
+ shape: () => shape46,
2709
2709
  unknownKeys: "strip",
2710
2710
  catchall: ZodNever.create(),
2711
2711
  typeName: ZodFirstPartyTypeKind.ZodObject,
2712
2712
  ...processCreateParams(params)
2713
2713
  });
2714
2714
  };
2715
- ZodObject.strictCreate = (shape44, params) => {
2715
+ ZodObject.strictCreate = (shape46, params) => {
2716
2716
  return new ZodObject({
2717
- shape: () => shape44,
2717
+ shape: () => shape46,
2718
2718
  unknownKeys: "strict",
2719
2719
  catchall: ZodNever.create(),
2720
2720
  typeName: ZodFirstPartyTypeKind.ZodObject,
2721
2721
  ...processCreateParams(params)
2722
2722
  });
2723
2723
  };
2724
- ZodObject.lazycreate = (shape44, params) => {
2724
+ ZodObject.lazycreate = (shape46, params) => {
2725
2725
  return new ZodObject({
2726
- shape: shape44,
2726
+ shape: shape46,
2727
2727
  unknownKeys: "strip",
2728
2728
  catchall: ZodNever.create(),
2729
2729
  typeName: ZodFirstPartyTypeKind.ZodObject,
@@ -4065,7 +4065,7 @@ var coerce = {
4065
4065
  };
4066
4066
  var NEVER = INVALID;
4067
4067
 
4068
- // .model-contracts/generations/324045ff5a8d957b84ad80e3a428461bb10e4259-v2/node_modules/@tscircuit/mm/dist/index.js
4068
+ // .model-contracts/generations/344775224814556adaec789fbc570ee91a9e4064-v2/node_modules/@tscircuit/mm/dist/index.js
4069
4069
  var unitToMm = {
4070
4070
  in: 25.4,
4071
4071
  inch: 25.4,
@@ -4092,9 +4092,9 @@ var mm = (n) => {
4092
4092
  throw new Error(`Unsupported unit: ${unit}`);
4093
4093
  };
4094
4094
 
4095
- // .model-contracts/generations/324045ff5a8d957b84ad80e3a428461bb10e4259-v2/index.js
4095
+ // .model-contracts/generations/344775224814556adaec789fbc570ee91a9e4064-v2/index.js
4096
4096
  function normalizeNemaMotorModelString(value) {
4097
- if (!/^nema(?:8|17|23)(?:_|$)/i.test(value)) return value;
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");
4099
4099
  }
4100
4100
  function splitModelStringTokens(value) {
@@ -4178,55 +4178,55 @@ var stringFlags = {
4178
4178
  male: "threadgender(male)"
4179
4179
  };
4180
4180
  var omittedStringFlags = ["righthanded", "male"];
4181
- function defineModel(model502) {
4182
- return model502;
4181
+ function defineModel(model522) {
4182
+ return model522;
4183
4183
  }
4184
4184
  var ModelRegistry = class {
4185
4185
  models = /* @__PURE__ */ new Map();
4186
- register(model502) {
4187
- if (typeof model502.name !== "string" || !/^[a-z]+$/.test(model502.name)) {
4186
+ register(model522) {
4187
+ if (typeof model522.name !== "string" || !/^[a-z]+$/.test(model522.name)) {
4188
4188
  throw new Error("Model names must contain only lowercase letters");
4189
4189
  }
4190
- if (this.models.has(model502.name)) {
4190
+ if (this.models.has(model522.name)) {
4191
4191
  throw new Error(
4192
- `Modelprinter function "${model502.name}" is already registered`
4192
+ `Modelprinter function "${model522.name}" is already registered`
4193
4193
  );
4194
4194
  }
4195
- if (model502.normalizeString !== void 0 && typeof model502.normalizeString !== "function")
4195
+ if (model522.normalizeString !== void 0 && typeof model522.normalizeString !== "function")
4196
4196
  throw new Error("Model string normalizer must be a function");
4197
- this.models.set(model502.name, {
4198
- name: model502.name,
4199
- schema: model502.schema,
4200
- parse: model502.parse,
4201
- normalizeString: model502.normalizeString
4197
+ this.models.set(model522.name, {
4198
+ name: model522.name,
4199
+ schema: model522.schema,
4200
+ parse: model522.parse,
4201
+ normalizeString: model522.normalizeString
4202
4202
  });
4203
4203
  }
4204
4204
  getModelNames() {
4205
4205
  return [...this.models.keys()];
4206
4206
  }
4207
4207
  normalize(params) {
4208
- const model502 = this.models.get(params.fn);
4209
- if (!model502?.normalizeString) return params;
4210
- const value = model502.normalizeString(params.string);
4208
+ const model522 = this.models.get(params.fn);
4209
+ if (!model522?.normalizeString) return params;
4210
+ const value = model522.normalizeString(params.string);
4211
4211
  if (typeof value !== "string")
4212
- throw new Error(`Normalizer for "${model502.name}" must return a string`);
4212
+ throw new Error(`Normalizer for "${model522.name}" must return a string`);
4213
4213
  if (value === params.string) return params;
4214
4214
  const normalized = parseModelStringParams(value);
4215
- if (normalized.fn !== model502.name)
4215
+ if (normalized.fn !== model522.name)
4216
4216
  throw new Error(
4217
- `Normalizer for "${model502.name}" must preserve the model name`
4217
+ `Normalizer for "${model522.name}" must preserve the model name`
4218
4218
  );
4219
4219
  return normalized;
4220
4220
  }
4221
4221
  parse(params) {
4222
- const model502 = this.models.get(params.fn);
4223
- if (!model502) {
4222
+ const model522 = this.models.get(params.fn);
4223
+ if (!model522) {
4224
4224
  throw new Error(`Unsupported modelprinter function "${params.fn}"`);
4225
4225
  }
4226
- const definition = model502.parse(params);
4227
- if (definition === null || typeof definition !== "object" || Array.isArray(definition) || definition.fn !== model502.name) {
4226
+ const definition = model522.parse(params);
4227
+ if (definition === null || typeof definition !== "object" || Array.isArray(definition) || definition.fn !== model522.name) {
4228
4228
  throw new Error(
4229
- `Parser for "${model502.name}" must return a model with fn "${model502.name}"`
4229
+ `Parser for "${model522.name}" must return a model with fn "${model522.name}"`
4230
4230
  );
4231
4231
  }
4232
4232
  return definition;
@@ -4783,7 +4783,8 @@ var hexSocketBoltModelDefinitionSchema = external_exports.object({
4783
4783
  var nemaSizeSchema = external_exports.union([
4784
4784
  external_exports.literal(8),
4785
4785
  external_exports.literal(17),
4786
- external_exports.literal(23)
4786
+ external_exports.literal(23),
4787
+ external_exports.literal(34)
4787
4788
  ]);
4788
4789
  var nemaMotorDimensions = {
4789
4790
  8: {
@@ -4851,6 +4852,31 @@ var nemaMotorDimensions = {
4851
4852
  rearCapLength: 5,
4852
4853
  faceCornerChamfer: 2,
4853
4854
  bodyCornerChamfer: 15
4855
+ },
4856
+ 34: {
4857
+ // Illustrative rear details; independent of the mounting flange.
4858
+ backFaceHoleSpacing: 40,
4859
+ rearCornerChamfer: 24,
4860
+ backFaceScrewSize: "M5",
4861
+ backFaceHoleDepth: 6,
4862
+ bodyWidth: 86,
4863
+ bodyLength: 80,
4864
+ mountingHoleSpacing: 69.6,
4865
+ mountingHoleDiameter: 6.5,
4866
+ mountingHoleDepth: 10,
4867
+ mountingHoleThrough: true,
4868
+ pilotDiameter: 73,
4869
+ pilotLength: 1.6,
4870
+ shaftDiameter: 14,
4871
+ shaftLength: 32,
4872
+ shaftShape: "round",
4873
+ shaftFlatDepth: 0.5,
4874
+ shaftFlatLength: 15,
4875
+ shaftFlatAngle: 0,
4876
+ frontCapLength: 10,
4877
+ rearCapLength: 8,
4878
+ faceCornerChamfer: 2,
4879
+ bodyCornerChamfer: 24
4854
4880
  }
4855
4881
  };
4856
4882
  var shape3 = {
@@ -4889,7 +4915,10 @@ var shape3 = {
4889
4915
  frontCapLength: positiveModelLengthSchema.optional(),
4890
4916
  rearCapLength: positiveModelLengthSchema.optional(),
4891
4917
  faceCornerChamfer: nonnegativeModelLengthSchema.optional(),
4892
- bodyCornerChamfer: nonnegativeModelLengthSchema.optional()
4918
+ bodyCornerChamfer: nonnegativeModelLengthSchema.optional(),
4919
+ /** Rear outline is independent of the front mounting flange. */
4920
+ rearCornerChamfer: nonnegativeModelLengthSchema.optional(),
4921
+ cornerProfile: external_exports.enum(["chamfered", "stepped"]).optional()
4893
4922
  };
4894
4923
  var resolve = (p) => {
4895
4924
  const d = nemaMotorDimensions[p.nemaSize];
@@ -4898,12 +4927,12 @@ var resolve = (p) => {
4898
4927
  return {
4899
4928
  nemaSize: p.nemaSize,
4900
4929
  wireConnection: p.wireConnection ?? "stubs",
4901
- wireSideAngle: ((p.wireSideAngle ?? 0) % 360 + 360) % 360,
4902
- wireLength: p.wireLength ?? 6,
4903
- wireDiameter: p.wireDiameter ?? 1.2,
4930
+ wireSideAngle: ((p.wireSideAngle ?? (p.nemaSize === 34 ? 90 : 0)) % 360 + 360) % 360,
4931
+ wireLength: p.wireLength ?? (p.nemaSize === 34 ? 25 : 6),
4932
+ wireDiameter: p.wireDiameter ?? (p.nemaSize === 34 ? 2 : 1.2),
4904
4933
  wireCount: p.wireCount ?? 4,
4905
- backFace: p.backFace ?? "screws",
4906
- backFaceHoleSpacing: p.backFaceHoleSpacing ?? p.mountingHoleSpacing ?? d.mountingHoleSpacing,
4934
+ backFace: p.backFace ?? (p.nemaSize === 34 ? "plain" : "screws"),
4935
+ backFaceHoleSpacing: p.backFaceHoleSpacing ?? ("backFaceHoleSpacing" in d ? d.backFaceHoleSpacing : p.mountingHoleSpacing ?? d.mountingHoleSpacing),
4907
4936
  backFaceHoleDiameter: p.backFaceHoleDiameter ?? screw.diameter,
4908
4937
  backFaceHoleDepth: p.backFaceHoleDepth ?? d.backFaceHoleDepth,
4909
4938
  backFaceScrewSize,
@@ -4924,17 +4953,23 @@ var resolve = (p) => {
4924
4953
  frontCapLength: p.frontCapLength ?? d.frontCapLength,
4925
4954
  rearCapLength: p.rearCapLength ?? d.rearCapLength,
4926
4955
  faceCornerChamfer: p.faceCornerChamfer ?? d.faceCornerChamfer,
4927
- bodyCornerChamfer: p.bodyCornerChamfer ?? d.bodyCornerChamfer
4956
+ bodyCornerChamfer: p.bodyCornerChamfer ?? d.bodyCornerChamfer,
4957
+ ...p.nemaSize === 34 || p.cornerProfile !== void 0 ? { cornerProfile: p.cornerProfile ?? "stepped" } : {},
4958
+ ..."rearCornerChamfer" in d || p.rearCornerChamfer !== void 0 ? {
4959
+ rearCornerChamfer: p.rearCornerChamfer ?? ("rearCornerChamfer" in d ? d.rearCornerChamfer : p.faceCornerChamfer ?? d.faceCornerChamfer)
4960
+ } : {}
4928
4961
  };
4929
4962
  };
4930
4963
  var validate3 = (p, ctx) => {
4931
4964
  const issue = (message) => ctx.addIssue({ code: "custom", message });
4965
+ const rearChamfer = p.rearCornerChamfer ?? (p.backFace === "plain" && p.mountingHoleThrough ? p.bodyCornerChamfer : p.faceCornerChamfer);
4966
+ const rearEdge = p.cornerProfile === "stepped" ? rearChamfer / Math.SQRT2 : rearChamfer;
4932
4967
  if (p.backFace !== "plain") {
4933
4968
  const screw = hexSocketBoltDimensions[p.backFaceScrewSize];
4934
4969
  const radius = (p.backFace === "screws" ? Math.max(p.backFaceHoleDiameter, screw.headDiameter) : p.backFaceHoleDiameter) / 2;
4935
4970
  if (p.backFaceHoleSpacing <= 2 * radius)
4936
4971
  issue("Rear holes and screw heads must not overlap each other");
4937
- if (p.backFaceHoleSpacing + 2 * radius >= p.bodyWidth || p.bodyWidth - p.faceCornerChamfer - p.backFaceHoleSpacing <= radius * Math.SQRT2)
4972
+ 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))
4938
4973
  issue("Rear holes and screw heads must fit entirely inside the rear face");
4939
4974
  if (p.backFaceHoleDepth >= p.rearCapLength)
4940
4975
  issue("Rear hole depth must be less than the rear cap length");
@@ -4942,18 +4977,18 @@ var validate3 = (p, ctx) => {
4942
4977
  issue("Rear holes must accommodate the screw diameter");
4943
4978
  }
4944
4979
  if (p.wireConnection === "stubs") {
4945
- if (p.wireDiameter * p.wireCount * 1.5 > p.bodyWidth - 2 * p.faceCornerChamfer)
4980
+ if (p.wireDiameter * p.wireCount * 1.5 > p.bodyWidth - 2 * rearEdge)
4946
4981
  issue("Wire bundle must fit on the cap side");
4947
4982
  if (p.wireDiameter >= p.rearCapLength)
4948
4983
  issue("Wire diameter must fit within the rear cap");
4949
4984
  }
4950
4985
  const connector = getJstMotorConnector(p.wireConnection);
4951
- if (connector && p.bodyWidth - 2 * p.faceCornerChamfer < connector.bodyWidth)
4986
+ if (connector && p.bodyWidth - 2 * rearEdge < connector.bodyWidth)
4952
4987
  issue("JST header must fit on the motor side");
4953
4988
  const r = p.mountingHoleDiameter / 2;
4954
4989
  if (p.frontCapLength + p.rearCapLength >= p.bodyLength)
4955
4990
  issue("End caps must leave a positive body length");
4956
- if (p.faceCornerChamfer >= p.bodyWidth / 2 || p.bodyCornerChamfer >= p.bodyWidth / 2)
4991
+ if (p.faceCornerChamfer >= p.bodyWidth / 2 || p.bodyCornerChamfer >= p.bodyWidth / 2 || rearChamfer >= p.bodyWidth / 2)
4957
4992
  issue("Chamfer must be smaller than half the body width");
4958
4993
  if (p.mountingHoleSpacing + 2 * r >= p.bodyWidth || p.bodyWidth - p.faceCornerChamfer - p.mountingHoleSpacing <= r * Math.SQRT2)
4959
4994
  issue("Mounting holes must fit entirely inside the front face");
@@ -4965,7 +5000,7 @@ var validate3 = (p, ctx) => {
4965
5000
  issue("Mounting holes must clear the pilot");
4966
5001
  if (!p.mountingHoleThrough && p.mountingHoleDepth >= p.frontCapLength)
4967
5002
  issue("Blind mounting hole depth must be less than the front cap length");
4968
- if (p.mountingHoleThrough && p.bodyWidth - p.bodyCornerChamfer - p.mountingHoleSpacing >= -r * Math.SQRT2)
5003
+ 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))
4969
5004
  issue("Body must clear through front mounting holes");
4970
5005
  if (p.shaftLength <= p.pilotLength)
4971
5006
  issue("Shaft tip must extend beyond the pilot");
@@ -4998,12 +5033,13 @@ var lengths2 = {
4998
5033
  frontcap: "frontCapLength",
4999
5034
  rearcap: "rearCapLength",
5000
5035
  facechamfer: "faceCornerChamfer",
5001
- bodychamfer: "bodyCornerChamfer"
5036
+ bodychamfer: "bodyCornerChamfer",
5037
+ rearchamfer: "rearCornerChamfer"
5002
5038
  };
5003
5039
  function parseNemaMotorModelParams(raw) {
5004
5040
  const tokens = normalizeNemaMotorModelString(raw.string).split("_");
5005
- const match = tokens[0]?.match(/^nema(8|17|23)$/i);
5006
- if (!match) throw new Error("Expected nema8, nema17 or nema23");
5041
+ const match = tokens[0]?.match(/^nema(8|17|23|34)$/i);
5042
+ if (!match) throw new Error("Expected nema8, nema17, nema23 or nema34");
5007
5043
  const props = {
5008
5044
  fn: "nema",
5009
5045
  nemaSize: Number(match[1])
@@ -5026,6 +5062,10 @@ function parseNemaMotorModelParams(raw) {
5026
5062
  throw new Error(`Invalid wire connection token "${token}"`);
5027
5063
  property = "wireConnection";
5028
5064
  parsed = isJst ? `jst-${name.slice(3)}-${value}` : name === "nowires" ? "none" : "stubs";
5065
+ } else if (name === "stepped" || name === "chamfered") {
5066
+ if (value) throw new Error(`NEMA flag "${name}" does not accept a value`);
5067
+ property = "cornerProfile";
5068
+ parsed = name;
5029
5069
  } else if (name === "wirecount") {
5030
5070
  property = "wireCount";
5031
5071
  if (!/^\d+$/.test(value)) throw new Error("wirecount requires an integer");
@@ -5155,12 +5195,12 @@ function parseSheetMetalFeature(feature, profile6) {
5155
5195
  }
5156
5196
  if (!("l" in values) || !("w" in values))
5157
5197
  throw new Error(`Slot requires l and w in ${feature}`);
5158
- const length29 = distance2("l"), width10 = distance2("w");
5159
- if (length29 < width10) throw new Error("Slot length must be at least its width");
5198
+ const length30 = distance2("l"), width10 = distance2("w");
5199
+ if (length30 < width10) throw new Error("Slot length must be at least its width");
5160
5200
  return sheetMetalHoleSchema.parse({
5161
5201
  ...position,
5162
5202
  shape: "slot",
5163
- length: length29,
5203
+ length: length30,
5164
5204
  width: width10,
5165
5205
  axis: panel === "base" === !("vertical" in values) ? "u" : "v"
5166
5206
  });
@@ -5363,9 +5403,9 @@ var flexScreenModelPropsSchema = external_exports.object(flexScreenModelPropsSha
5363
5403
  var flexScreenModelDefinitionSchema = external_exports.object({
5364
5404
  fn: external_exports.literal("flexscreen"),
5365
5405
  ...flexScreenModelPropsShape
5366
- }).strict().superRefine((model502, context) => {
5367
- validateTailLengths(model502, context);
5368
- addOrientationShortcutIssue(model502, (path) => {
5406
+ }).strict().superRefine((model522, context) => {
5407
+ validateTailLengths(model522, context);
5408
+ addOrientationShortcutIssue(model522, (path) => {
5369
5409
  context.addIssue({
5370
5410
  code: "custom",
5371
5411
  message: "Only one FlexScreen orientation shortcut can be true",
@@ -6994,8 +7034,8 @@ function getCompressionSpringCenterlinePoint(input, turn) {
6994
7034
  const radius = (props.outerDiameter - props.wireDiameter) / 2;
6995
7035
  const pitch = (props.freeLength - 2 * props.wireDiameter) / props.activeTurns;
6996
7036
  const phase = (props.hand === "right" ? 1 : -1) * 2 * Math.PI * (turn % 1);
6997
- const z54 = turn <= 1 ? props.wireDiameter * turn : turn >= props.totalTurns - 1 ? props.freeLength - props.wireDiameter * (props.totalTurns - turn) : props.wireDiameter + pitch * (turn - 1);
6998
- return { x: radius * Math.cos(phase), y: radius * Math.sin(phase), z: z54 };
7037
+ const z56 = turn <= 1 ? props.wireDiameter * turn : turn >= props.totalTurns - 1 ? props.freeLength - props.wireDiameter * (props.totalTurns - turn) : props.wireDiameter + pitch * (turn - 1);
7038
+ return { x: radius * Math.cos(phase), y: radius * Math.sin(phase), z: z56 };
6999
7039
  }
7000
7040
  function parseCompressionSpringModelParams(raw) {
7001
7041
  const tokens = splitModelStringTokens(
@@ -9446,6 +9486,94 @@ var model29 = defineModel({
9446
9486
  function register29(registry2) {
9447
9487
  registry2.register(model29);
9448
9488
  }
9489
+ var shape24 = {
9490
+ width: positiveGearLengthSchema,
9491
+ height: positiveGearLengthSchema,
9492
+ thickness: positiveGearLengthSchema,
9493
+ length: positiveGearLengthSchema,
9494
+ innerRadius: nonnegativeGearLengthSchema,
9495
+ holeCount: external_exports.number().finite().int().min(1).max(256),
9496
+ holeDiameter: positiveGearLengthSchema,
9497
+ pitch: positiveGearLengthSchema,
9498
+ endOffset: positiveGearLengthSchema,
9499
+ legOffset: positiveGearLengthSchema
9500
+ };
9501
+ function validate23(p, context) {
9502
+ const issue = (message, path) => context.addIssue({ code: "custom", message, path: [path] });
9503
+ const largestDimension = Math.max(
9504
+ ...Object.values(p).filter(
9505
+ (value) => typeof value === "number"
9506
+ )
9507
+ );
9508
+ if (!Number.isFinite((4 * largestDimension) ** 3)) {
9509
+ issue(
9510
+ "Dimensions must permit finite derived coordinates and volume",
9511
+ "width"
9512
+ );
9513
+ return;
9514
+ }
9515
+ if (p.innerRadius + p.thickness >= Math.min(p.width, p.height))
9516
+ issue("The bend must leave a straight portion on both legs", "innerRadius");
9517
+ if (p.legOffset - p.holeDiameter / 2 <= p.innerRadius + p.thickness)
9518
+ issue("Leg holes must lie wholly beyond the bend tangents", "legOffset");
9519
+ if (p.legOffset + p.holeDiameter / 2 >= Math.min(p.width, p.height))
9520
+ issue("Leg holes must leave material at both free edges", "legOffset");
9521
+ if (p.pitch <= p.holeDiameter && p.holeCount > 1)
9522
+ issue("Hole pitch must leave material between consecutive holes", "pitch");
9523
+ if (p.endOffset <= p.holeDiameter / 2)
9524
+ issue(
9525
+ "The first hole must leave material at the first cut end",
9526
+ "endOffset"
9527
+ );
9528
+ if (p.endOffset + (p.holeCount - 1) * p.pitch + p.holeDiameter / 2 >= p.length)
9529
+ issue("The last hole must leave material at the far cut end", "length");
9530
+ }
9531
+ var perforatedAngleModelPropsSchema = external_exports.object(shape24).strict().superRefine(validate23);
9532
+ var perforatedAngleModelDefinitionSchema = external_exports.object({ fn: external_exports.literal("perforatedangle"), ...shape24 }).strict().superRefine(validate23);
9533
+ var aliases8 = {
9534
+ w: "width",
9535
+ h: "height",
9536
+ t: "thickness",
9537
+ l: "length",
9538
+ innerr: "innerRadius",
9539
+ holes: "holeCount",
9540
+ hole: "holeDiameter",
9541
+ pitch: "pitch",
9542
+ end: "endOffset",
9543
+ legoffset: "legOffset",
9544
+ width: "width",
9545
+ height: "height",
9546
+ thickness: "thickness",
9547
+ length: "length",
9548
+ innerradius: "innerRadius",
9549
+ holecount: "holeCount",
9550
+ holediameter: "holeDiameter",
9551
+ endoffset: "endOffset"
9552
+ };
9553
+ function parsePerforatedAngleModelParams(raw) {
9554
+ const [name, ...tokens] = splitModelStringTokens(raw.string);
9555
+ if (raw.fn !== "perforatedangle" || name?.toLowerCase() !== "perforatedangle")
9556
+ throw new Error("Expected perforatedangle without inline values");
9557
+ const props = { fn: "perforatedangle" };
9558
+ for (const token of tokens) {
9559
+ const [key, value] = parseGearToken(token);
9560
+ if (!Object.hasOwn(aliases8, key) || !value)
9561
+ throw new Error(`Unknown or malformed perforatedangle token "${token}"`);
9562
+ const property = aliases8[key];
9563
+ if (Object.hasOwn(props, property))
9564
+ throw new Error(`Repeated perforatedangle property "${property}"`);
9565
+ props[property] = ["holeCount"].includes(property) ? parseGearInteger(value, property) : value;
9566
+ }
9567
+ return perforatedAngleModelDefinitionSchema.parse(props);
9568
+ }
9569
+ var model30 = defineModel({
9570
+ name: "perforatedangle",
9571
+ schema: perforatedAngleModelDefinitionSchema,
9572
+ parse: parsePerforatedAngleModelParams
9573
+ });
9574
+ function register30(registry2) {
9575
+ registry2.register(model30);
9576
+ }
9449
9577
  var length15 = external_exports.union([
9450
9578
  external_exports.number(),
9451
9579
  external_exports.string().regex(/^[+]?(?:\d+(?:\.\d*)?|\.\d+)(?:mm|cm|m|in|inch|mil|ft|feet)?$/i).transform((value) => value.toLowerCase())
@@ -9458,7 +9586,7 @@ var nonnegativeLength4 = length15.refine(
9458
9586
  (value) => value >= 0,
9459
9587
  "Length cannot be negative"
9460
9588
  );
9461
- var shape24 = {
9589
+ var shape25 = {
9462
9590
  length: positiveLength10,
9463
9591
  width: positiveLength10,
9464
9592
  thickness: positiveLength10,
@@ -9469,7 +9597,7 @@ var shape24 = {
9469
9597
  edgeY: positiveLength10,
9470
9598
  stagger: nonnegativeLength4.default(0)
9471
9599
  };
9472
- function validate23(p, context) {
9600
+ function validate24(p, context) {
9473
9601
  if (p.holeDiameter >= Math.min(p.pitchX, p.pitchY))
9474
9602
  context.addIssue({
9475
9603
  code: "custom",
@@ -9496,9 +9624,9 @@ function validate23(p, context) {
9496
9624
  message: "Invalid perforatedsheet dimensions: constraint 5"
9497
9625
  });
9498
9626
  }
9499
- var perforatedSheetModelPropsSchema = external_exports.object(shape24).strict().superRefine(validate23);
9500
- var perforatedSheetModelDefinitionSchema = external_exports.object({ fn: external_exports.literal("perforatedsheet"), ...shape24 }).strict().superRefine(validate23);
9501
- var aliases8 = {
9627
+ var perforatedSheetModelPropsSchema = external_exports.object(shape25).strict().superRefine(validate24);
9628
+ var perforatedSheetModelDefinitionSchema = external_exports.object({ fn: external_exports.literal("perforatedsheet"), ...shape25 }).strict().superRefine(validate24);
9629
+ var aliases9 = {
9502
9630
  l: "length",
9503
9631
  w: "width",
9504
9632
  t: "thickness",
@@ -9522,22 +9650,22 @@ function parsePerforatedSheetModelParams(raw) {
9522
9650
  const match = token.match(/^([a-z]+)(.*)$/i);
9523
9651
  const key = match?.[1]?.toLowerCase();
9524
9652
  const value = match?.[2];
9525
- if (!key || !Object.hasOwn(aliases8, key) || !value)
9653
+ if (!key || !Object.hasOwn(aliases9, key) || !value)
9526
9654
  throw new Error(`Unknown or malformed perforatedsheet token "${token}"`);
9527
- const property = aliases8[key];
9655
+ const property = aliases9[key];
9528
9656
  if (Object.hasOwn(props, property))
9529
9657
  throw new Error(`Duplicate perforatedsheet property "${property}"`);
9530
9658
  props[property] = value;
9531
9659
  }
9532
9660
  return perforatedSheetModelDefinitionSchema.parse(props);
9533
9661
  }
9534
- var model30 = defineModel({
9662
+ var model31 = defineModel({
9535
9663
  name: "perforatedsheet",
9536
9664
  schema: perforatedSheetModelDefinitionSchema,
9537
9665
  parse: parsePerforatedSheetModelParams
9538
9666
  });
9539
- function register30(registry2) {
9540
- registry2.register(model30);
9667
+ function register31(registry2) {
9668
+ registry2.register(model31);
9541
9669
  }
9542
9670
  var stringFlags10 = {
9543
9671
  plainclosed: "style(plainclosed)"
@@ -9548,7 +9676,7 @@ var length16 = external_exports.union([
9548
9676
  external_exports.string().regex(/^[+-]?(?:\d+(?:\.\d*)?|\.\d+)(?:mm|cm|m|in|inch|mil|ft|feet)?$/i).transform((value) => value.toLowerCase())
9549
9677
  ]).pipe(modelLengthSchema);
9550
9678
  var positiveLength11 = length16.refine((value) => value > 0);
9551
- var shape25 = {
9679
+ var shape26 = {
9552
9680
  innerDiameter: positiveLength11,
9553
9681
  outerDiameter: positiveLength11,
9554
9682
  /** Overall end-plane distance, including the chamfers. */
@@ -9557,7 +9685,7 @@ var shape25 = {
9557
9685
  /** Equal axial/radial setbacks of all four 45-degree bore/outside rim chamfers. */
9558
9686
  edgeChamfer: length16.refine((value) => value >= 0).default(0)
9559
9687
  };
9560
- function validate24(props, context) {
9688
+ function validate25(props, context) {
9561
9689
  if (props.outerDiameter <= props.innerDiameter)
9562
9690
  context.addIssue({
9563
9691
  code: "custom",
@@ -9577,8 +9705,8 @@ function validate24(props, context) {
9577
9705
  message: "The two end chamfers must leave positive straight bore length"
9578
9706
  });
9579
9707
  }
9580
- var plainBushingModelPropsSchema = external_exports.object(shape25).strict().superRefine(validate24);
9581
- var plainBushingModelDefinitionSchema = external_exports.object({ fn: external_exports.literal("plainbushing"), ...shape25 }).strict().superRefine(validate24);
9708
+ var plainBushingModelPropsSchema = external_exports.object(shape26).strict().superRefine(validate25);
9709
+ var plainBushingModelDefinitionSchema = external_exports.object({ fn: external_exports.literal("plainbushing"), ...shape26 }).strict().superRefine(validate25);
9582
9710
  function getPlainBushingDimensions(input) {
9583
9711
  const props = plainBushingModelPropsSchema.parse(input);
9584
9712
  return {
@@ -9631,7 +9759,7 @@ function parsePlainBushingModelParams(raw) {
9631
9759
  }
9632
9760
  return plainBushingModelDefinitionSchema.parse(props);
9633
9761
  }
9634
- var model31 = defineModel({
9762
+ var model32 = defineModel({
9635
9763
  name: "plainbushing",
9636
9764
  schema: plainBushingModelDefinitionSchema,
9637
9765
  parse: parsePlainBushingModelParams,
@@ -9642,8 +9770,8 @@ var model31 = defineModel({
9642
9770
  omittedStringFlags10
9643
9771
  )
9644
9772
  });
9645
- function register31(registry2) {
9646
- registry2.register(model31);
9773
+ function register32(registry2) {
9774
+ registry2.register(model32);
9647
9775
  }
9648
9776
  var length17 = external_exports.union([
9649
9777
  external_exports.number(),
@@ -9653,13 +9781,13 @@ var positiveLength12 = length17.refine(
9653
9781
  (value) => value > 0,
9654
9782
  "Length must be positive"
9655
9783
  );
9656
- var shape26 = {
9784
+ var shape27 = {
9657
9785
  tubeDiameter: positiveLength12,
9658
9786
  length: positiveLength12,
9659
9787
  headDiameter: positiveLength12,
9660
9788
  headThickness: positiveLength12
9661
9789
  };
9662
- function validate25(p, context) {
9790
+ function validate26(p, context) {
9663
9791
  if (p.headDiameter <= p.tubeDiameter)
9664
9792
  context.addIssue({
9665
9793
  code: "custom",
@@ -9671,9 +9799,9 @@ function validate25(p, context) {
9671
9799
  message: "Invalid pushfitplug dimensions: constraint 2"
9672
9800
  });
9673
9801
  }
9674
- var pushFitPlugModelPropsSchema = external_exports.object(shape26).strict().superRefine(validate25);
9675
- var pushFitPlugModelDefinitionSchema = external_exports.object({ fn: external_exports.literal("pushfitplug"), ...shape26 }).strict().superRefine(validate25);
9676
- var aliases9 = {
9802
+ var pushFitPlugModelPropsSchema = external_exports.object(shape27).strict().superRefine(validate26);
9803
+ var pushFitPlugModelDefinitionSchema = external_exports.object({ fn: external_exports.literal("pushfitplug"), ...shape27 }).strict().superRefine(validate26);
9804
+ var aliases10 = {
9677
9805
  tubeod: "tubeDiameter",
9678
9806
  l: "length",
9679
9807
  headod: "headDiameter",
@@ -9692,22 +9820,22 @@ function parsePushFitPlugModelParams(raw) {
9692
9820
  const match = token.match(/^([a-z]+)(.*)$/i);
9693
9821
  const key = match?.[1]?.toLowerCase();
9694
9822
  const value = match?.[2];
9695
- if (!key || !Object.hasOwn(aliases9, key) || !value)
9823
+ if (!key || !Object.hasOwn(aliases10, key) || !value)
9696
9824
  throw new Error(`Unknown or malformed pushfitplug token "${token}"`);
9697
- const property = aliases9[key];
9825
+ const property = aliases10[key];
9698
9826
  if (Object.hasOwn(props, property))
9699
9827
  throw new Error(`Duplicate pushfitplug property "${property}"`);
9700
9828
  props[property] = value;
9701
9829
  }
9702
9830
  return pushFitPlugModelDefinitionSchema.parse(props);
9703
9831
  }
9704
- var model32 = defineModel({
9832
+ var model33 = defineModel({
9705
9833
  name: "pushfitplug",
9706
9834
  schema: pushFitPlugModelDefinitionSchema,
9707
9835
  parse: parsePushFitPlugModelParams
9708
9836
  });
9709
- function register32(registry2) {
9710
- registry2.register(model32);
9837
+ function register33(registry2) {
9838
+ registry2.register(model33);
9711
9839
  }
9712
9840
  var length18 = external_exports.union([
9713
9841
  external_exports.number(),
@@ -9721,22 +9849,22 @@ var nonnegativeLength5 = length18.refine(
9721
9849
  (value) => value >= 0,
9722
9850
  "Length cannot be negative"
9723
9851
  );
9724
- var shape27 = {
9852
+ var shape28 = {
9725
9853
  width: positiveLength13,
9726
9854
  height: positiveLength13,
9727
9855
  length: positiveLength13,
9728
9856
  cornerRadius: nonnegativeLength5.default(0)
9729
9857
  };
9730
- function validate26(p, context) {
9858
+ function validate27(p, context) {
9731
9859
  if (p.cornerRadius * 2 >= Math.min(p.width, p.height))
9732
9860
  context.addIssue({
9733
9861
  code: "custom",
9734
9862
  message: "Invalid rectangularbar dimensions: constraint 1"
9735
9863
  });
9736
9864
  }
9737
- var rectangularBarModelPropsSchema = external_exports.object(shape27).strict().superRefine(validate26);
9738
- var rectangularBarModelDefinitionSchema = external_exports.object({ fn: external_exports.literal("rectangularbar"), ...shape27 }).strict().superRefine(validate26);
9739
- var aliases10 = {
9865
+ var rectangularBarModelPropsSchema = external_exports.object(shape28).strict().superRefine(validate27);
9866
+ var rectangularBarModelDefinitionSchema = external_exports.object({ fn: external_exports.literal("rectangularbar"), ...shape28 }).strict().superRefine(validate27);
9867
+ var aliases11 = {
9740
9868
  w: "width",
9741
9869
  h: "height",
9742
9870
  l: "length",
@@ -9755,22 +9883,22 @@ function parseRectangularBarModelParams(raw) {
9755
9883
  const match = token.match(/^([a-z]+)(.*)$/i);
9756
9884
  const key = match?.[1]?.toLowerCase();
9757
9885
  const value = match?.[2];
9758
- if (!key || !Object.hasOwn(aliases10, key) || !value)
9886
+ if (!key || !Object.hasOwn(aliases11, key) || !value)
9759
9887
  throw new Error(`Unknown or malformed rectangularbar token "${token}"`);
9760
- const property = aliases10[key];
9888
+ const property = aliases11[key];
9761
9889
  if (Object.hasOwn(props, property))
9762
9890
  throw new Error(`Duplicate rectangularbar property "${property}"`);
9763
9891
  props[property] = value;
9764
9892
  }
9765
9893
  return rectangularBarModelDefinitionSchema.parse(props);
9766
9894
  }
9767
- var model33 = defineModel({
9895
+ var model34 = defineModel({
9768
9896
  name: "rectangularbar",
9769
9897
  schema: rectangularBarModelDefinitionSchema,
9770
9898
  parse: parseRectangularBarModelParams
9771
9899
  });
9772
- function register33(registry2) {
9773
- registry2.register(model33);
9900
+ function register34(registry2) {
9901
+ registry2.register(model34);
9774
9902
  }
9775
9903
  var length19 = external_exports.union([
9776
9904
  external_exports.number(),
@@ -9787,7 +9915,7 @@ var nonnegativeLength6 = length19.refine(
9787
9915
  (value) => value >= 0,
9788
9916
  "Length cannot be negative"
9789
9917
  );
9790
- var shape28 = {
9918
+ var shape29 = {
9791
9919
  width: positiveLength14,
9792
9920
  height: positiveLength14,
9793
9921
  border: positiveLength14,
@@ -9795,7 +9923,7 @@ var shape28 = {
9795
9923
  cornerRadius: nonnegativeLength6.default(0),
9796
9924
  flatFrame: external_exports.literal(true).default(true)
9797
9925
  };
9798
- function validate27(p, context) {
9926
+ function validate28(p, context) {
9799
9927
  const issue = (message, path) => context.addIssue({ code: "custom", message, path: [path] });
9800
9928
  if (2 * p.border >= Math.min(p.width, p.height))
9801
9929
  issue(
@@ -9812,8 +9940,8 @@ function validate27(p, context) {
9812
9940
  ))
9813
9941
  issue("Dimensions exceed finite derived geometry limits", "width");
9814
9942
  }
9815
- var rectangularGasketModelPropsSchema = external_exports.object(shape28).strict().superRefine(validate27);
9816
- var rectangularGasketModelDefinitionSchema = external_exports.object({ fn: external_exports.literal("rectangulargasket"), ...shape28 }).strict().superRefine(validate27);
9943
+ var rectangularGasketModelPropsSchema = external_exports.object(shape29).strict().superRefine(validate28);
9944
+ var rectangularGasketModelDefinitionSchema = external_exports.object({ fn: external_exports.literal("rectangulargasket"), ...shape29 }).strict().superRefine(validate28);
9817
9945
  function getRectangularGasketDimensions(input) {
9818
9946
  const p = rectangularGasketModelPropsSchema.parse(input);
9819
9947
  return {
@@ -9875,13 +10003,13 @@ function parseRectangularGasketModelParams(raw) {
9875
10003
  }
9876
10004
  return rectangularGasketModelDefinitionSchema.parse(props);
9877
10005
  }
9878
- var model34 = defineModel({
10006
+ var model35 = defineModel({
9879
10007
  name: "rectangulargasket",
9880
10008
  schema: rectangularGasketModelDefinitionSchema,
9881
10009
  parse: parseRectangularGasketModelParams
9882
10010
  });
9883
- function register34(registry2) {
9884
- registry2.register(model34);
10011
+ function register35(registry2) {
10012
+ registry2.register(model35);
9885
10013
  }
9886
10014
  var length20 = external_exports.union([
9887
10015
  external_exports.number(),
@@ -9895,7 +10023,7 @@ var nonnegativeLength7 = length20.refine(
9895
10023
  (value) => value >= 0,
9896
10024
  "Length cannot be negative"
9897
10025
  );
9898
- var shape29 = {
10026
+ var shape30 = {
9899
10027
  width: positiveLength15,
9900
10028
  height: positiveLength15,
9901
10029
  wallThickness: positiveLength15,
@@ -9903,7 +10031,7 @@ var shape29 = {
9903
10031
  outerRadius: nonnegativeLength7.default(0),
9904
10032
  innerRadius: nonnegativeLength7.default(0)
9905
10033
  };
9906
- function validate28(p, context) {
10034
+ function validate29(p, context) {
9907
10035
  if (2 * p.wallThickness >= Math.min(p.width, p.height))
9908
10036
  context.addIssue({
9909
10037
  code: "custom",
@@ -9925,9 +10053,9 @@ function validate28(p, context) {
9925
10053
  message: "Invalid rectangulartube dimensions: constraint 4"
9926
10054
  });
9927
10055
  }
9928
- var rectangularTubeModelPropsSchema = external_exports.object(shape29).strict().superRefine(validate28);
9929
- var rectangularTubeModelDefinitionSchema = external_exports.object({ fn: external_exports.literal("rectangulartube"), ...shape29 }).strict().superRefine(validate28);
9930
- var aliases11 = {
10056
+ var rectangularTubeModelPropsSchema = external_exports.object(shape30).strict().superRefine(validate29);
10057
+ var rectangularTubeModelDefinitionSchema = external_exports.object({ fn: external_exports.literal("rectangulartube"), ...shape30 }).strict().superRefine(validate29);
10058
+ var aliases12 = {
9931
10059
  w: "width",
9932
10060
  h: "height",
9933
10061
  wall: "wallThickness",
@@ -9950,22 +10078,22 @@ function parseRectangularTubeModelParams(raw) {
9950
10078
  const match = token.match(/^([a-z]+)(.*)$/i);
9951
10079
  const key = match?.[1]?.toLowerCase();
9952
10080
  const value = match?.[2];
9953
- if (!key || !Object.hasOwn(aliases11, key) || !value)
10081
+ if (!key || !Object.hasOwn(aliases12, key) || !value)
9954
10082
  throw new Error(`Unknown or malformed rectangulartube token "${token}"`);
9955
- const property = aliases11[key];
10083
+ const property = aliases12[key];
9956
10084
  if (Object.hasOwn(props, property))
9957
10085
  throw new Error(`Duplicate rectangulartube property "${property}"`);
9958
10086
  props[property] = value;
9959
10087
  }
9960
10088
  return rectangularTubeModelDefinitionSchema.parse(props);
9961
10089
  }
9962
- var model35 = defineModel({
10090
+ var model36 = defineModel({
9963
10091
  name: "rectangulartube",
9964
10092
  schema: rectangularTubeModelDefinitionSchema,
9965
10093
  parse: parseRectangularTubeModelParams
9966
10094
  });
9967
- function register35(registry2) {
9968
- registry2.register(model35);
10095
+ function register36(registry2) {
10096
+ registry2.register(model36);
9969
10097
  }
9970
10098
  var stringFlags11 = {
9971
10099
  setscrew: "mount(setscrew)",
@@ -9985,7 +10113,7 @@ var nonnegative4 = length21.refine(
9985
10113
  (value) => value >= 0,
9986
10114
  "Length cannot be negative"
9987
10115
  );
9988
- var shape30 = {
10116
+ var shape31 = {
9989
10117
  boreDiameter: positive5,
9990
10118
  outerDiameter: positive5,
9991
10119
  boreBDiameter: positive5.optional(),
@@ -10010,7 +10138,7 @@ function resolve6(props) {
10010
10138
  screwAngle: (props.screwAngle % 360 + 360) % 360
10011
10139
  };
10012
10140
  }
10013
- function validate29(props, context) {
10141
+ function validate30(props, context) {
10014
10142
  const p = resolve6(props);
10015
10143
  const issue = (message) => context.addIssue({ code: "custom", message });
10016
10144
  const diameter = hexSocketBoltDimensions[p.metricSize].diameter;
@@ -10034,8 +10162,8 @@ function validate29(props, context) {
10034
10162
  if (p.length - 2 * p.screwEndOffset <= diameter)
10035
10163
  issue("Each end must have a separate, nonintersecting screw-hole plane");
10036
10164
  }
10037
- var rigidCouplerModelPropsSchema = external_exports.object(shape30).strict().superRefine(validate29).transform(resolve6);
10038
- var rigidCouplerModelDefinitionSchema = external_exports.object({ fn: external_exports.literal("rigidcoupler"), ...shape30 }).strict().superRefine(validate29).transform((props) => ({ fn: props.fn, ...resolve6(props) }));
10165
+ var rigidCouplerModelPropsSchema = external_exports.object(shape31).strict().superRefine(validate30).transform(resolve6);
10166
+ var rigidCouplerModelDefinitionSchema = external_exports.object({ fn: external_exports.literal("rigidcoupler"), ...shape31 }).strict().superRefine(validate30).transform((props) => ({ fn: props.fn, ...resolve6(props) }));
10039
10167
  function getRigidCouplerDimensions(input) {
10040
10168
  const p = rigidCouplerModelPropsSchema.parse(input);
10041
10169
  const threadDiameter = hexSocketBoltDimensions[p.metricSize].diameter;
@@ -10135,7 +10263,7 @@ function parseRigidCouplerModelParams(raw) {
10135
10263
  ...props
10136
10264
  });
10137
10265
  }
10138
- var model36 = defineModel({
10266
+ var model37 = defineModel({
10139
10267
  name: "rigidcoupler",
10140
10268
  schema: rigidCouplerModelDefinitionSchema,
10141
10269
  parse: parseRigidCouplerModelParams,
@@ -10146,8 +10274,8 @@ var model36 = defineModel({
10146
10274
  omittedStringFlags11
10147
10275
  )
10148
10276
  });
10149
- function register36(registry2) {
10150
- registry2.register(model36);
10277
+ function register37(registry2) {
10278
+ registry2.register(model37);
10151
10279
  }
10152
10280
  var positiveLength16 = external_exports.union([
10153
10281
  external_exports.number(),
@@ -10204,7 +10332,7 @@ var setscrewDimensions = {
10204
10332
  }
10205
10333
  };
10206
10334
  var setscrewMetricSizeSchema = external_exports.enum(["M3", "M4", "M5", "M6"]);
10207
- var shape31 = {
10335
+ var shape32 = {
10208
10336
  iso4029: external_exports.literal(true).default(true),
10209
10337
  metricSize: setscrewMetricSizeSchema,
10210
10338
  length: positiveLength16,
@@ -10223,7 +10351,7 @@ var shape31 = {
10223
10351
  threadRootDiameter: positiveLength16.optional(),
10224
10352
  threadPitchDiameter: positiveLength16.optional()
10225
10353
  };
10226
- var validate30 = (props, context) => {
10354
+ var validate31 = (props, context) => {
10227
10355
  const dimensions5 = setscrewDimensions[props.metricSize];
10228
10356
  for (const key of Object.keys(dimensions5)) {
10229
10357
  if (props[key] !== void 0 && Math.abs(props[key] - dimensions5[key]) > 1e-9)
@@ -10240,9 +10368,9 @@ var validate30 = (props, context) => {
10240
10368
  message: "Length must leave material between fixed end features"
10241
10369
  });
10242
10370
  };
10243
- var setscrewModelPropsSchema = external_exports.object(shape31).strict().superRefine(validate30).transform((props) => ({ ...props, ...setscrewDimensions[props.metricSize] }));
10244
- var setscrewModelDefinitionSchema = external_exports.object({ fn: external_exports.literal("setscrew"), ...shape31 }).strict().superRefine(validate30).transform((props) => ({ ...props, ...setscrewDimensions[props.metricSize] }));
10245
- var aliases12 = {
10371
+ var setscrewModelPropsSchema = external_exports.object(shape32).strict().superRefine(validate31).transform((props) => ({ ...props, ...setscrewDimensions[props.metricSize] }));
10372
+ var setscrewModelDefinitionSchema = external_exports.object({ fn: external_exports.literal("setscrew"), ...shape32 }).strict().superRefine(validate31).transform((props) => ({ ...props, ...setscrewDimensions[props.metricSize] }));
10373
+ var aliases13 = {
10246
10374
  m: "metricSize",
10247
10375
  metricsize: "metricSize",
10248
10376
  l: "length",
@@ -10291,7 +10419,7 @@ function parseSetScrewModelParams(raw) {
10291
10419
  property = flags6[key];
10292
10420
  parsed = !["righthanded", "nothreads"].includes(key);
10293
10421
  } else {
10294
- property = aliases12[key] ?? "";
10422
+ property = aliases13[key] ?? "";
10295
10423
  if (!property || !value)
10296
10424
  throw new Error(`Unknown or missing setscrew token ${token}`);
10297
10425
  if (property === "metricSize") {
@@ -10314,13 +10442,13 @@ function parseSetScrewModelParams(raw) {
10314
10442
  }
10315
10443
  return setscrewModelDefinitionSchema.parse({ fn: "setscrew", ...props });
10316
10444
  }
10317
- var model37 = defineModel({
10445
+ var model38 = defineModel({
10318
10446
  name: "setscrew",
10319
10447
  schema: setscrewModelDefinitionSchema,
10320
10448
  parse: parseSetScrewModelParams
10321
10449
  });
10322
- function register37(registry2) {
10323
- registry2.register(model37);
10450
+ function register38(registry2) {
10451
+ registry2.register(model38);
10324
10452
  }
10325
10453
  var stringFlags12 = {
10326
10454
  setscrew: "mount(setscrew)",
@@ -10340,7 +10468,7 @@ var nonnegative5 = length22.refine(
10340
10468
  (value) => value >= 0,
10341
10469
  "Length cannot be negative"
10342
10470
  );
10343
- var shape32 = {
10471
+ var shape33 = {
10344
10472
  boreDiameter: positive6,
10345
10473
  outerDiameter: positive6,
10346
10474
  width: positive6,
@@ -10362,7 +10490,7 @@ function resolve7(props) {
10362
10490
  screwAngle: (props.screwAngle % 360 + 360) % 360
10363
10491
  };
10364
10492
  }
10365
- function validate31(props, context) {
10493
+ function validate32(props, context) {
10366
10494
  const p = resolve7(props);
10367
10495
  const issue = (message) => context.addIssue({ code: "custom", message });
10368
10496
  const diameter = hexSocketBoltDimensions[p.metricSize].diameter;
@@ -10379,8 +10507,8 @@ function validate31(props, context) {
10379
10507
  if (p.screwZ - diameter / 2 <= p.chamfer || p.screwZ + diameter / 2 >= p.width - p.chamfer)
10380
10508
  issue("Screw hole must clear both end faces and chamfers");
10381
10509
  }
10382
- var shaftCollarModelPropsSchema = external_exports.object(shape32).strict().superRefine(validate31).transform(resolve7);
10383
- var shaftCollarModelDefinitionSchema = external_exports.object({ fn: external_exports.literal("shaftcollar"), ...shape32 }).strict().superRefine(validate31).transform((props) => ({ fn: props.fn, ...resolve7(props) }));
10510
+ var shaftCollarModelPropsSchema = external_exports.object(shape33).strict().superRefine(validate32).transform(resolve7);
10511
+ var shaftCollarModelDefinitionSchema = external_exports.object({ fn: external_exports.literal("shaftcollar"), ...shape33 }).strict().superRefine(validate32).transform((props) => ({ fn: props.fn, ...resolve7(props) }));
10384
10512
  function getShaftCollarDimensions(input) {
10385
10513
  const p = shaftCollarModelPropsSchema.parse(input);
10386
10514
  const threadDiameter = hexSocketBoltDimensions[p.metricSize].diameter;
@@ -10454,7 +10582,7 @@ function parseShaftCollarModelParams(raw) {
10454
10582
  }
10455
10583
  return shaftCollarModelDefinitionSchema.parse({ fn: "shaftcollar", ...props });
10456
10584
  }
10457
- var model38 = defineModel({
10585
+ var model39 = defineModel({
10458
10586
  name: "shaftcollar",
10459
10587
  schema: shaftCollarModelDefinitionSchema,
10460
10588
  parse: parseShaftCollarModelParams,
@@ -10465,10 +10593,10 @@ var model38 = defineModel({
10465
10593
  omittedStringFlags12
10466
10594
  )
10467
10595
  });
10468
- function register38(registry2) {
10469
- registry2.register(model38);
10596
+ function register39(registry2) {
10597
+ registry2.register(model39);
10470
10598
  }
10471
- var shape33 = {
10599
+ var shape34 = {
10472
10600
  width: positiveGearLengthSchema,
10473
10601
  height: positiveGearLengthSchema,
10474
10602
  thickness: positiveGearLengthSchema,
@@ -10480,7 +10608,7 @@ var shape33 = {
10480
10608
  pitch: positiveGearLengthSchema,
10481
10609
  endOffset: positiveGearLengthSchema
10482
10610
  };
10483
- function validate32(p, context) {
10611
+ function validate33(p, context) {
10484
10612
  const issue = (message, path) => context.addIssue({ code: "custom", message, path: [path] });
10485
10613
  const largestDimension = Math.max(
10486
10614
  ...Object.values(p).filter(
@@ -10512,9 +10640,9 @@ function validate32(p, context) {
10512
10640
  if (p.endOffset + (p.slotCount - 1) * p.pitch + p.slotLength / 2 >= p.length)
10513
10641
  issue("The last slot must leave material at the far cut end", "length");
10514
10642
  }
10515
- var slottedChannelModelPropsSchema = external_exports.object(shape33).strict().superRefine(validate32);
10516
- var slottedChannelModelDefinitionSchema = external_exports.object({ fn: external_exports.literal("slottedchannel"), ...shape33 }).strict().superRefine(validate32);
10517
- var aliases13 = {
10643
+ var slottedChannelModelPropsSchema = external_exports.object(shape34).strict().superRefine(validate33);
10644
+ var slottedChannelModelDefinitionSchema = external_exports.object({ fn: external_exports.literal("slottedchannel"), ...shape34 }).strict().superRefine(validate33);
10645
+ var aliases14 = {
10518
10646
  w: "width",
10519
10647
  h: "height",
10520
10648
  t: "thickness",
@@ -10542,22 +10670,22 @@ function parseSlottedChannelModelParams(raw) {
10542
10670
  const props = { fn: "slottedchannel" };
10543
10671
  for (const token of tokens) {
10544
10672
  const [key, value] = parseGearToken(token);
10545
- if (!Object.hasOwn(aliases13, key) || !value)
10673
+ if (!Object.hasOwn(aliases14, key) || !value)
10546
10674
  throw new Error(`Unknown or malformed slottedchannel token "${token}"`);
10547
- const property = aliases13[key];
10675
+ const property = aliases14[key];
10548
10676
  if (Object.hasOwn(props, property))
10549
10677
  throw new Error(`Repeated slottedchannel property "${property}"`);
10550
10678
  props[property] = ["slotCount"].includes(property) ? parseGearInteger(value, property) : value;
10551
10679
  }
10552
10680
  return slottedChannelModelDefinitionSchema.parse(props);
10553
10681
  }
10554
- var model39 = defineModel({
10682
+ var model40 = defineModel({
10555
10683
  name: "slottedchannel",
10556
10684
  schema: slottedChannelModelDefinitionSchema,
10557
10685
  parse: parseSlottedChannelModelParams
10558
10686
  });
10559
- function register39(registry2) {
10560
- registry2.register(model39);
10687
+ function register40(registry2) {
10688
+ registry2.register(model40);
10561
10689
  }
10562
10690
  var length23 = external_exports.union([
10563
10691
  external_exports.number(),
@@ -10567,7 +10695,7 @@ var positiveLength17 = length23.refine(
10567
10695
  (value) => value > 0,
10568
10696
  "Length must be positive"
10569
10697
  );
10570
- var shape34 = {
10698
+ var shape35 = {
10571
10699
  innerDiameter: positiveLength17,
10572
10700
  outerDiameter: positiveLength17,
10573
10701
  /** End-plane distance, including the rim chamfers. */
@@ -10576,7 +10704,7 @@ var shape34 = {
10576
10704
  /** Equal axial/radial setbacks at all four 45-degree rims. */
10577
10705
  chamfer: length23.refine((value) => value >= 0, "Chamfer cannot be negative").default(0)
10578
10706
  };
10579
- function validate33(props, context) {
10707
+ function validate34(props, context) {
10580
10708
  if (props.outerDiameter <= props.innerDiameter)
10581
10709
  context.addIssue({
10582
10710
  code: "custom",
@@ -10596,9 +10724,9 @@ function validate33(props, context) {
10596
10724
  message: "Chamfers must leave positive straight bore length"
10597
10725
  });
10598
10726
  }
10599
- var spacerModelPropsSchema = external_exports.object(shape34).strict().superRefine(validate33);
10600
- var spacerModelDefinitionSchema = external_exports.object({ fn: external_exports.literal("spacer"), ...shape34 }).strict().superRefine(validate33);
10601
- var aliases14 = {
10727
+ var spacerModelPropsSchema = external_exports.object(shape35).strict().superRefine(validate34);
10728
+ var spacerModelDefinitionSchema = external_exports.object({ fn: external_exports.literal("spacer"), ...shape35 }).strict().superRefine(validate34);
10729
+ var aliases15 = {
10602
10730
  id: "innerDiameter",
10603
10731
  innerdiameter: "innerDiameter",
10604
10732
  od: "outerDiameter",
@@ -10622,8 +10750,8 @@ function parseSpacerModelParams(raw) {
10622
10750
  if (key === "round" && value === "") {
10623
10751
  property = "round";
10624
10752
  parsed = true;
10625
- } else if (key && Object.hasOwn(aliases14, key) && value) {
10626
- property = aliases14[key];
10753
+ } else if (key && Object.hasOwn(aliases15, key) && value) {
10754
+ property = aliases15[key];
10627
10755
  parsed = value;
10628
10756
  } else throw new Error(`Unknown or malformed spacer token "${token}"`);
10629
10757
  if (Object.hasOwn(props, property))
@@ -10632,13 +10760,13 @@ function parseSpacerModelParams(raw) {
10632
10760
  }
10633
10761
  return spacerModelDefinitionSchema.parse(props);
10634
10762
  }
10635
- var model40 = defineModel({
10763
+ var model41 = defineModel({
10636
10764
  name: "spacer",
10637
10765
  schema: spacerModelDefinitionSchema,
10638
10766
  parse: parseSpacerModelParams
10639
10767
  });
10640
- function register40(registry2) {
10641
- registry2.register(model40);
10768
+ function register41(registry2) {
10769
+ registry2.register(model41);
10642
10770
  }
10643
10771
  var length24 = external_exports.union([
10644
10772
  external_exports.number(),
@@ -10655,7 +10783,7 @@ var nonnegativeLength8 = length24.refine(
10655
10783
  (value) => value >= 0,
10656
10784
  "Length cannot be negative"
10657
10785
  );
10658
- var shape35 = {
10786
+ var shape36 = {
10659
10787
  panelHoleDiameter: positiveLength18,
10660
10788
  innerDiameter: positiveLength18,
10661
10789
  outerDiameter: positiveLength18,
@@ -10664,7 +10792,7 @@ var shape35 = {
10664
10792
  grooveDepth: positiveLength18,
10665
10793
  splitWidth: positiveLength18
10666
10794
  };
10667
- function validate34(p, context) {
10795
+ function validate35(p, context) {
10668
10796
  const issue = (message, path) => context.addIssue({ code: "custom", message, path: [path] });
10669
10797
  if (p.innerDiameter >= p.panelHoleDiameter || p.panelHoleDiameter >= p.outerDiameter)
10670
10798
  issue(
@@ -10699,8 +10827,8 @@ function validate34(p, context) {
10699
10827
  "panelHoleDiameter"
10700
10828
  );
10701
10829
  }
10702
- var splitGrommetModelPropsSchema = external_exports.object(shape35).strict().superRefine(validate34);
10703
- var splitGrommetModelDefinitionSchema = external_exports.object({ fn: external_exports.literal("splitgrommet"), ...shape35 }).strict().superRefine(validate34);
10830
+ var splitGrommetModelPropsSchema = external_exports.object(shape36).strict().superRefine(validate35);
10831
+ var splitGrommetModelDefinitionSchema = external_exports.object({ fn: external_exports.literal("splitgrommet"), ...shape36 }).strict().superRefine(validate35);
10704
10832
  function getSplitGrommetDimensions(input) {
10705
10833
  const p = splitGrommetModelPropsSchema.parse(input);
10706
10834
  return {
@@ -10767,13 +10895,13 @@ function parseSplitGrommetModelParams(raw) {
10767
10895
  }
10768
10896
  return splitGrommetModelDefinitionSchema.parse(props);
10769
10897
  }
10770
- var model41 = defineModel({
10898
+ var model42 = defineModel({
10771
10899
  name: "splitgrommet",
10772
10900
  schema: splitGrommetModelDefinitionSchema,
10773
10901
  parse: parseSplitGrommetModelParams
10774
10902
  });
10775
- function register41(registry2) {
10776
- registry2.register(model41);
10903
+ function register42(registry2) {
10904
+ registry2.register(model42);
10777
10905
  }
10778
10906
  var length25 = external_exports.union([
10779
10907
  external_exports.number(),
@@ -10783,7 +10911,7 @@ var positiveLength19 = length25.refine(
10783
10911
  (value) => value > 0,
10784
10912
  "Length must be positive"
10785
10913
  );
10786
- var shape36 = {
10914
+ var shape37 = {
10787
10915
  innerDiameter: positiveLength19,
10788
10916
  outerDiameter: positiveLength19,
10789
10917
  /** Axial thickness of the rectangular radial/vertical section. */
@@ -10794,7 +10922,7 @@ var shape36 = {
10794
10922
  rectangular: external_exports.literal(true).default(true),
10795
10923
  leftHanded: external_exports.boolean().default(false)
10796
10924
  };
10797
- function validate35(p, context) {
10925
+ function validate36(p, context) {
10798
10926
  if (p.innerDiameter >= p.outerDiameter)
10799
10927
  context.addIssue({
10800
10928
  code: "custom",
@@ -10807,8 +10935,8 @@ function validate35(p, context) {
10807
10935
  message: "The washer envelope and volume must remain finite"
10808
10936
  });
10809
10937
  }
10810
- var splitWasherModelPropsSchema = external_exports.object(shape36).strict().superRefine(validate35);
10811
- var splitWasherModelDefinitionSchema = external_exports.object({ fn: external_exports.literal("splitwasher"), ...shape36 }).strict().superRefine(validate35);
10938
+ var splitWasherModelPropsSchema = external_exports.object(shape37).strict().superRefine(validate36);
10939
+ var splitWasherModelDefinitionSchema = external_exports.object({ fn: external_exports.literal("splitwasher"), ...shape37 }).strict().superRefine(validate36);
10812
10940
  var lengths18 = {
10813
10941
  id: "innerDiameter",
10814
10942
  innerdiameter: "innerDiameter",
@@ -10853,13 +10981,13 @@ function parseSplitWasherModelParams(raw) {
10853
10981
  }
10854
10982
  return splitWasherModelDefinitionSchema.parse(props);
10855
10983
  }
10856
- var model42 = defineModel({
10984
+ var model43 = defineModel({
10857
10985
  name: "splitwasher",
10858
10986
  schema: splitWasherModelDefinitionSchema,
10859
10987
  parse: parseSplitWasherModelParams
10860
10988
  });
10861
- function register42(registry2) {
10862
- registry2.register(model42);
10989
+ function register43(registry2) {
10990
+ registry2.register(model43);
10863
10991
  }
10864
10992
  var length26 = external_exports.union([
10865
10993
  external_exports.number(),
@@ -10893,7 +11021,7 @@ var threadedRodMetricSizeSchema = external_exports.enum([
10893
11021
  "M16",
10894
11022
  "M20"
10895
11023
  ]);
10896
- var shape37 = {
11024
+ var shape38 = {
10897
11025
  metricSize: threadedRodMetricSizeSchema,
10898
11026
  /** Overall end-plane distance, including terminal chamfers. */
10899
11027
  length: positiveLength20,
@@ -10908,7 +11036,7 @@ function resolve8(props) {
10908
11036
  threadPitch: props.threadPitch ?? threadedRodCoarsePitches[props.metricSize]
10909
11037
  };
10910
11038
  }
10911
- function validate36(props, context) {
11039
+ function validate37(props, context) {
10912
11040
  const diameter = Number(props.metricSize.slice(1));
10913
11041
  const pitch = resolve8(props).threadPitch;
10914
11042
  if (diameter - 1.226869 * pitch <= 0)
@@ -10924,8 +11052,8 @@ function validate36(props, context) {
10924
11052
  message: "Chamfer must leave flat end faces and separate end chamfers"
10925
11053
  });
10926
11054
  }
10927
- var threadedRodModelPropsSchema = external_exports.object(shape37).strict().superRefine(validate36).transform(resolve8);
10928
- var threadedRodModelDefinitionSchema = external_exports.object({ fn: external_exports.literal("threadedrod"), ...shape37 }).strict().superRefine(validate36).transform((model502) => ({ fn: model502.fn, ...resolve8(model502) }));
11055
+ var threadedRodModelPropsSchema = external_exports.object(shape38).strict().superRefine(validate37).transform(resolve8);
11056
+ var threadedRodModelDefinitionSchema = external_exports.object({ fn: external_exports.literal("threadedrod"), ...shape38 }).strict().superRefine(validate37).transform((model522) => ({ fn: model522.fn, ...resolve8(model522) }));
10929
11057
  function getThreadedRodDimensions(input) {
10930
11058
  const props = threadedRodModelPropsSchema.parse(input);
10931
11059
  const diameter = Number(props.metricSize.slice(1));
@@ -10993,21 +11121,21 @@ function normalizeThreadedRodModelString(value) {
10993
11121
  return [lower === "lefthanded" ? lower : token];
10994
11122
  }).join("_");
10995
11123
  }
10996
- var model43 = defineModel({
11124
+ var model44 = defineModel({
10997
11125
  name: "threadedrod",
10998
11126
  schema: threadedRodModelDefinitionSchema,
10999
11127
  parse: parseThreadedRodModelParams,
11000
11128
  normalizeString: normalizeThreadedRodModelString
11001
11129
  });
11002
- function register43(registry2) {
11003
- registry2.register(model43);
11130
+ function register44(registry2) {
11131
+ registry2.register(model44);
11004
11132
  }
11005
11133
  var length27 = external_exports.union([
11006
11134
  external_exports.number(),
11007
11135
  external_exports.string().regex(/^[+-]?(?:\d+(?:\.\d*)?|\.\d+)(?:mm|cm|m|in|inch|mil|ft|feet)?$/i).transform((value) => value.toLowerCase())
11008
11136
  ]).pipe(modelLengthSchema);
11009
11137
  var positive7 = length27.refine((value) => value > 0, "Length must be positive");
11010
- var shape38 = {
11138
+ var shape39 = {
11011
11139
  outerDiameter: positive7.default(8),
11012
11140
  wireDiameter: positive7.default(0.8),
11013
11141
  /** Fractional turns set the relative leg direction. */
@@ -11021,7 +11149,7 @@ var shape38 = {
11021
11149
  function normalize7(p) {
11022
11150
  return { ...p, pitch: p.pitch ?? p.wireDiameter * 1.25 };
11023
11151
  }
11024
- function validate37(p, context) {
11152
+ function validate38(p, context) {
11025
11153
  if (p.outerDiameter < 3 * p.wireDiameter)
11026
11154
  context.addIssue({
11027
11155
  code: "custom",
@@ -11043,8 +11171,8 @@ function validate37(p, context) {
11043
11171
  message: "Spring dimensions must remain finite"
11044
11172
  });
11045
11173
  }
11046
- var torsionSpringModelPropsSchema = external_exports.object(shape38).strict().superRefine(validate37).transform(normalize7);
11047
- var torsionSpringModelDefinitionSchema = external_exports.object({ fn: external_exports.literal("torsionspring"), ...shape38 }).strict().superRefine(validate37).transform((p) => ({ ...normalize7(p), fn: p.fn }));
11174
+ var torsionSpringModelPropsSchema = external_exports.object(shape39).strict().superRefine(validate38).transform(normalize7);
11175
+ var torsionSpringModelDefinitionSchema = external_exports.object({ fn: external_exports.literal("torsionspring"), ...shape39 }).strict().superRefine(validate38).transform((p) => ({ ...normalize7(p), fn: p.fn }));
11048
11176
  function getTorsionSpringDimensions(input) {
11049
11177
  const p = torsionSpringModelPropsSchema.parse(input);
11050
11178
  const meanRadius = (p.outerDiameter - p.wireDiameter) / 2;
@@ -11129,13 +11257,13 @@ function parseTorsionSpringModelParams(raw) {
11129
11257
  }
11130
11258
  return torsionSpringModelDefinitionSchema.parse(props);
11131
11259
  }
11132
- var model44 = defineModel({
11260
+ var model45 = defineModel({
11133
11261
  name: "torsionspring",
11134
11262
  schema: torsionSpringModelDefinitionSchema,
11135
11263
  parse: parseTorsionSpringModelParams
11136
11264
  });
11137
- function register44(registry2) {
11138
- registry2.register(model44);
11265
+ function register45(registry2) {
11266
+ registry2.register(model45);
11139
11267
  }
11140
11268
  var length28 = external_exports.union([
11141
11269
  external_exports.number(),
@@ -11149,7 +11277,7 @@ var nonnegativeLength10 = length28.refine(
11149
11277
  (value) => value >= 0,
11150
11278
  "Length cannot be negative"
11151
11279
  );
11152
- var shape39 = {
11280
+ var shape40 = {
11153
11281
  length: positiveLength21,
11154
11282
  width: positiveLength21,
11155
11283
  thickness: positiveLength21,
@@ -11159,7 +11287,7 @@ var shape39 = {
11159
11287
  barbHeight: positiveLength21.default(0.5),
11160
11288
  tee: external_exports.literal(true).default(true)
11161
11289
  };
11162
- function validate38(p, context) {
11290
+ function validate39(p, context) {
11163
11291
  const span = Math.max(p.width, p.length, p.thickness + p.stemHeight);
11164
11292
  if (!Number.isFinite(span ** 3))
11165
11293
  context.addIssue({
@@ -11185,9 +11313,9 @@ function validate38(p, context) {
11185
11313
  message: "Retention bead height must leave a positive narrow stem section"
11186
11314
  });
11187
11315
  }
11188
- var tSlotCoverStripModelPropsSchema = external_exports.object(shape39).strict().superRefine(validate38);
11189
- var tSlotCoverStripModelDefinitionSchema = external_exports.object({ fn: external_exports.literal("tslotcoverstrip"), ...shape39 }).strict().superRefine(validate38);
11190
- var aliases15 = {
11316
+ var tSlotCoverStripModelPropsSchema = external_exports.object(shape40).strict().superRefine(validate39);
11317
+ var tSlotCoverStripModelDefinitionSchema = external_exports.object({ fn: external_exports.literal("tslotcoverstrip"), ...shape40 }).strict().superRefine(validate39);
11318
+ var aliases16 = {
11191
11319
  l: "length",
11192
11320
  length: "length",
11193
11321
  w: "width",
@@ -11234,27 +11362,27 @@ function parseTSlotCoverStripModelParams(raw) {
11234
11362
  if (value.toLowerCase() !== `(${literal})`)
11235
11363
  throw new Error(`Expected tslotcoverstrip ${key}(${literal})`);
11236
11364
  assign(property, true);
11237
- } else if (Object.hasOwn(aliases15, key) && value) {
11238
- const property = aliases15[key];
11365
+ } else if (Object.hasOwn(aliases16, key) && value) {
11366
+ const property = aliases16[key];
11239
11367
  assign(property, property === "pinCount" ? Number(value) : value);
11240
11368
  } else
11241
11369
  throw new Error(`Unknown or malformed tslotcoverstrip token "${token}"`);
11242
11370
  }
11243
11371
  return tSlotCoverStripModelDefinitionSchema.parse(props);
11244
11372
  }
11245
- var model45 = defineModel({
11373
+ var model46 = defineModel({
11246
11374
  name: "tslotcoverstrip",
11247
11375
  schema: tSlotCoverStripModelDefinitionSchema,
11248
11376
  parse: parseTSlotCoverStripModelParams
11249
11377
  });
11250
- function register45(registry2) {
11251
- registry2.register(model45);
11378
+ function register46(registry2) {
11379
+ registry2.register(model46);
11252
11380
  }
11253
11381
  var stringFlags13 = {
11254
11382
  fourtsolid: "profile(fourtsolid)"
11255
11383
  };
11256
11384
  var omittedStringFlags13 = [];
11257
- var shape40 = {
11385
+ var shape41 = {
11258
11386
  width: positiveGearLengthSchema.default(20),
11259
11387
  height: positiveGearLengthSchema.default(20),
11260
11388
  length: positiveGearLengthSchema.default(100),
@@ -11267,7 +11395,7 @@ var shape40 = {
11267
11395
  boreDiameter: nonnegativeGearLengthSchema.default(0),
11268
11396
  cornerRadius: nonnegativeGearLengthSchema.default(0)
11269
11397
  };
11270
- function validate39(props, context) {
11398
+ function validate40(props, context) {
11271
11399
  const issue = (message, path) => context.addIssue({ code: "custom", message, path: [path] });
11272
11400
  const halfSize = Math.min(props.width, props.height) / 2;
11273
11401
  const depth = props.lipThickness + props.pocketDepth;
@@ -11295,8 +11423,8 @@ function validate39(props, context) {
11295
11423
  "boreDiameter"
11296
11424
  );
11297
11425
  }
11298
- var tSlotExtrusionModelPropsSchema = external_exports.object(shape40).strict().superRefine(validate39);
11299
- var tSlotExtrusionModelDefinitionSchema = external_exports.object({ fn: external_exports.literal("tslotextrusion"), ...shape40 }).strict().superRefine(validate39);
11426
+ var tSlotExtrusionModelPropsSchema = external_exports.object(shape41).strict().superRefine(validate40);
11427
+ var tSlotExtrusionModelDefinitionSchema = external_exports.object({ fn: external_exports.literal("tslotextrusion"), ...shape41 }).strict().superRefine(validate40);
11300
11428
  var lengths21 = {
11301
11429
  w: "width",
11302
11430
  width: "width",
@@ -11341,7 +11469,7 @@ function parseTSlotExtrusionModelParams(raw) {
11341
11469
  }
11342
11470
  return tSlotExtrusionModelDefinitionSchema.parse(props);
11343
11471
  }
11344
- var model46 = defineModel({
11472
+ var model47 = defineModel({
11345
11473
  name: "tslotextrusion",
11346
11474
  schema: tSlotExtrusionModelDefinitionSchema,
11347
11475
  parse: parseTSlotExtrusionModelParams,
@@ -11352,14 +11480,14 @@ var model46 = defineModel({
11352
11480
  omittedStringFlags13
11353
11481
  )
11354
11482
  });
11355
- function register46(registry2) {
11356
- registry2.register(model46);
11483
+ function register47(registry2) {
11484
+ registry2.register(model47);
11357
11485
  }
11358
11486
  var stringFlags14 = {
11359
11487
  righttriangle: "shape(righttriangle)"
11360
11488
  };
11361
11489
  var omittedStringFlags14 = [];
11362
- var shape41 = {
11490
+ var shape42 = {
11363
11491
  width: positiveGearLengthSchema.default(40),
11364
11492
  height: positiveGearLengthSchema.default(40),
11365
11493
  thickness: positiveGearLengthSchema.default(4),
@@ -11372,22 +11500,22 @@ var shape41 = {
11372
11500
  /** Ligament between each slot and its parallel outer plate edge. */
11373
11501
  edgeMargin: positiveGearLengthSchema.default(1)
11374
11502
  };
11375
- function validate40(props, context) {
11503
+ function validate41(props, context) {
11376
11504
  const issue = (message, path) => context.addIssue({ code: "custom", message, path: [path] });
11377
- const [width10, length29] = props.slot;
11378
- if (length29 < width10) {
11505
+ const [width10, length30] = props.slot;
11506
+ if (length30 < width10) {
11379
11507
  issue("Slot length must be at least its width", "slot");
11380
11508
  return;
11381
11509
  }
11382
11510
  const radius = width10 / 2;
11383
- const halfStraight = (length29 - width10) / 2;
11511
+ const halfStraight = (length30 - width10) / 2;
11384
11512
  const inset = props.edgeMargin + radius;
11385
11513
  const [x, y] = props.centers;
11386
11514
  if (!Number.isFinite(inset)) {
11387
11515
  issue("Derived slot centers must be finite", "edgeMargin");
11388
11516
  return;
11389
11517
  }
11390
- if (x <= length29 / 2 || y <= length29 / 2)
11518
+ if (x <= length30 / 2 || y <= length30 / 2)
11391
11519
  issue("Slots must leave material at the right-angle corner", "centers");
11392
11520
  const normalRatio = Math.min(props.width, props.height) / Math.max(props.width, props.height);
11393
11521
  const capSupport = radius / Math.min(props.width, props.height) * Math.hypot(1, normalRatio);
@@ -11403,18 +11531,18 @@ function validate40(props, context) {
11403
11531
  if (Math.hypot(dx, dy) <= width10)
11404
11532
  issue("The two slots must retain a positive separating ligament", "centers");
11405
11533
  }
11406
- var tSlotGussetModelPropsSchema = external_exports.object(shape41).strict().superRefine(validate40);
11407
- var tSlotGussetModelDefinitionSchema = external_exports.object({ fn: external_exports.literal("tslotgusset"), ...shape41 }).strict().superRefine(validate40);
11534
+ var tSlotGussetModelPropsSchema = external_exports.object(shape42).strict().superRefine(validate41);
11535
+ var tSlotGussetModelDefinitionSchema = external_exports.object({ fn: external_exports.literal("tslotgusset"), ...shape42 }).strict().superRefine(validate41);
11408
11536
  function getTSlotGussetMountingSlots(input = {}) {
11409
11537
  const props = tSlotGussetModelPropsSchema.parse(input);
11410
- const [width10, length29] = props.slot;
11538
+ const [width10, length30] = props.slot;
11411
11539
  const inset = props.edgeMargin + width10 / 2;
11412
11540
  return [
11413
11541
  {
11414
11542
  center: { x: props.centers[0], y: inset, z: 0 },
11415
11543
  orientation: 0,
11416
11544
  width: width10,
11417
- length: length29,
11545
+ length: length30,
11418
11546
  depth: props.thickness,
11419
11547
  direction: { x: 0, y: 0, z: 1 }
11420
11548
  },
@@ -11422,7 +11550,7 @@ function getTSlotGussetMountingSlots(input = {}) {
11422
11550
  center: { x: inset, y: props.centers[1], z: 0 },
11423
11551
  orientation: 90,
11424
11552
  width: width10,
11425
- length: length29,
11553
+ length: length30,
11426
11554
  depth: props.thickness,
11427
11555
  direction: { x: 0, y: 0, z: 1 }
11428
11556
  }
@@ -11469,7 +11597,7 @@ function parseTSlotGussetModelParams(raw) {
11469
11597
  }
11470
11598
  return tSlotGussetModelDefinitionSchema.parse(props);
11471
11599
  }
11472
- var model47 = defineModel({
11600
+ var model48 = defineModel({
11473
11601
  name: "tslotgusset",
11474
11602
  schema: tSlotGussetModelDefinitionSchema,
11475
11603
  parse: parseTSlotGussetModelParams,
@@ -11480,10 +11608,10 @@ var model47 = defineModel({
11480
11608
  omittedStringFlags14
11481
11609
  )
11482
11610
  });
11483
- function register47(registry2) {
11484
- registry2.register(model47);
11611
+ function register48(registry2) {
11612
+ registry2.register(model48);
11485
11613
  }
11486
- var shape42 = {
11614
+ var shape43 = {
11487
11615
  width: positiveGearLengthSchema.default(20),
11488
11616
  /** Equal leg extents from the virtual intersection of the inside flats. */
11489
11617
  legLength: positiveGearLengthSchema.default(40),
@@ -11495,7 +11623,7 @@ var shape42 = {
11495
11623
  holeOffset: positiveGearLengthSchema.default(20),
11496
11624
  bendRadius: nonnegativeGearLengthSchema.default(0)
11497
11625
  };
11498
- function validate41(props, context) {
11626
+ function validate42(props, context) {
11499
11627
  const issue = (message, path) => context.addIssue({ code: "custom", message, path: [path] });
11500
11628
  if (!Number.isFinite(props.bendRadius + props.thickness)) {
11501
11629
  issue("Outside bend radius must be finite", "bendRadius");
@@ -11513,8 +11641,8 @@ function validate41(props, context) {
11513
11641
  if (props.holeOffset + radius >= props.legLength)
11514
11642
  issue("Holes must leave material at the free leg ends", "holeOffset");
11515
11643
  }
11516
- var tSlotInsideCornerModelPropsSchema = external_exports.object(shape42).strict().superRefine(validate41);
11517
- var tSlotInsideCornerModelDefinitionSchema = external_exports.object({ fn: external_exports.literal("tslotinsidecorner"), ...shape42 }).strict().superRefine(validate41);
11644
+ var tSlotInsideCornerModelPropsSchema = external_exports.object(shape43).strict().superRefine(validate42);
11645
+ var tSlotInsideCornerModelDefinitionSchema = external_exports.object({ fn: external_exports.literal("tslotinsidecorner"), ...shape43 }).strict().superRefine(validate42);
11518
11646
  var lengths23 = {
11519
11647
  w: "width",
11520
11648
  width: "width",
@@ -11552,15 +11680,109 @@ function parseTSlotInsideCornerModelParams(raw) {
11552
11680
  }
11553
11681
  return tSlotInsideCornerModelDefinitionSchema.parse(props);
11554
11682
  }
11555
- var model48 = defineModel({
11683
+ var model49 = defineModel({
11556
11684
  name: "tslotinsidecorner",
11557
11685
  schema: tSlotInsideCornerModelDefinitionSchema,
11558
11686
  parse: parseTSlotInsideCornerModelParams
11559
11687
  });
11560
- function register48(registry2) {
11561
- registry2.register(model48);
11688
+ function register49(registry2) {
11689
+ registry2.register(model49);
11562
11690
  }
11563
- var shape43 = {
11691
+ var length29 = external_exports.union([
11692
+ external_exports.number().finite(),
11693
+ external_exports.string().regex(/^[+-]?(?:\d+(?:\.\d*)?|\.\d+)(?:mm|cm|m|in|inch|mil|ft|feet)?$/i)
11694
+ ]).pipe(modelLengthSchema);
11695
+ var positiveLength22 = length29.refine(
11696
+ (value) => value > 0,
11697
+ "Length must be positive"
11698
+ );
11699
+ var shape44 = {
11700
+ groundPitch: positiveLength22.default(3),
11701
+ groundPadWidth: positiveLength22.default(2.2),
11702
+ groundPadHeight: positiveLength22.default(1.1),
11703
+ signalPadWidth: positiveLength22.default(1.5),
11704
+ signalPadHeight: positiveLength22.default(1.1),
11705
+ signalPadX: length29.refine((value) => value < 0, "Signal pad must lie on the -X side").default(-1.25)
11706
+ };
11707
+ var uflModelPropsSchema = external_exports.object(shape44).strict();
11708
+ var uflModelDefinitionSchema = external_exports.object({ fn: external_exports.literal("ufl"), ...shape44 }).strict();
11709
+ function getUflDimensions(input = {}) {
11710
+ const p = uflModelPropsSchema.parse(input);
11711
+ const minX = Math.min(
11712
+ -p.groundPadWidth / 2,
11713
+ p.signalPadX - p.signalPadWidth / 2
11714
+ );
11715
+ const maxX = Math.max(
11716
+ p.groundPadWidth / 2,
11717
+ p.signalPadX + p.signalPadWidth / 2
11718
+ );
11719
+ const bodyCenterX = -(minX + maxX) / 2;
11720
+ const groundDepth = Math.min(p.groundPadHeight, 0.3);
11721
+ const signalDepth = Math.min(p.signalPadWidth, 0.3);
11722
+ return {
11723
+ ...p,
11724
+ bodyCenterX,
11725
+ baseWidth: 2.6,
11726
+ baseLength: 2.6,
11727
+ baseHeight: 0.35,
11728
+ height: 1.25,
11729
+ shellOuterDiameter: 2,
11730
+ // The catalog calls out the envelope; internal contacts are simplified
11731
+ // visual geometry rather than additional mating-tolerance promises.
11732
+ shellInnerDiameter: 1.5,
11733
+ dielectricHeight: 0.85,
11734
+ centerPinDiameter: 0.5,
11735
+ centerPinHeight: 1.15,
11736
+ terminalThickness: 0.1,
11737
+ groundTerminalWidth: Math.min(p.groundPadWidth, 1.8),
11738
+ groundTerminalDepth: groundDepth,
11739
+ groundTerminalX: bodyCenterX,
11740
+ groundTerminalY: (p.groundPitch - groundDepth) / 2,
11741
+ signalTerminalWidth: signalDepth,
11742
+ signalTerminalHeight: Math.min(p.signalPadHeight, 0.6),
11743
+ signalTerminalX: p.signalPadX - signalDepth / 2 + bodyCenterX,
11744
+ rearTabX: 1.4 + bodyCenterX,
11745
+ rearTabWidth: 0.3,
11746
+ rearTabHeight: 0.6,
11747
+ bottomZ: 0,
11748
+ topZ: 1.25
11749
+ };
11750
+ }
11751
+ var aliases17 = {
11752
+ p: "groundPitch",
11753
+ pw: "groundPadWidth",
11754
+ ph: "groundPadHeight",
11755
+ signalw: "signalPadWidth",
11756
+ signalh: "signalPadHeight",
11757
+ signalx: "signalPadX"
11758
+ };
11759
+ function parseUflModelParams(raw) {
11760
+ const [name, ...tokens] = splitModelStringTokens(raw.string);
11761
+ if (raw.fn !== "ufl" || !/^ufl(?:3)?$/i.test(name ?? ""))
11762
+ throw new Error("Expected a three-terminal ufl receptacle");
11763
+ const props = { fn: "ufl" };
11764
+ for (const token of tokens) {
11765
+ const match = token.match(/^([a-z]+)(.*)$/i);
11766
+ const key = match?.[1]?.toLowerCase();
11767
+ const value = match?.[2];
11768
+ if (!key || !Object.hasOwn(aliases17, key) || !value)
11769
+ throw new Error(`Unknown or malformed ufl token "${token}"`);
11770
+ const property = aliases17[key];
11771
+ if (Object.hasOwn(props, property))
11772
+ throw new Error(`Duplicate ufl property "${property}"`);
11773
+ props[property] = value;
11774
+ }
11775
+ return uflModelDefinitionSchema.parse(props);
11776
+ }
11777
+ var model50 = defineModel({
11778
+ name: "ufl",
11779
+ schema: uflModelDefinitionSchema,
11780
+ parse: parseUflModelParams
11781
+ });
11782
+ function register50(registry2) {
11783
+ registry2.register(model50);
11784
+ }
11785
+ var shape45 = {
11564
11786
  height: positiveGearLengthSchema,
11565
11787
  upperWidth: positiveGearLengthSchema,
11566
11788
  lowerWidth: positiveGearLengthSchema,
@@ -11568,7 +11790,7 @@ var shape43 = {
11568
11790
  bendRadius: nonnegativeGearLengthSchema,
11569
11791
  length: positiveGearLengthSchema
11570
11792
  };
11571
- function validate42(p, context) {
11793
+ function validate43(p, context) {
11572
11794
  const issue = (message, path) => context.addIssue({ code: "custom", message, path: [path] });
11573
11795
  const largestDimension = Math.max(
11574
11796
  ...Object.values(p).filter(
@@ -11592,9 +11814,9 @@ function validate42(p, context) {
11592
11814
  if (!Number.isFinite(p.upperWidth + p.lowerWidth - p.thickness))
11593
11815
  issue("The combined section width must be finite", "upperWidth");
11594
11816
  }
11595
- var zeeBarModelPropsSchema = external_exports.object(shape43).strict().superRefine(validate42);
11596
- var zeeBarModelDefinitionSchema = external_exports.object({ fn: external_exports.literal("zeebar"), ...shape43 }).strict().superRefine(validate42);
11597
- var aliases16 = {
11817
+ var zeeBarModelPropsSchema = external_exports.object(shape45).strict().superRefine(validate43);
11818
+ var zeeBarModelDefinitionSchema = external_exports.object({ fn: external_exports.literal("zeebar"), ...shape45 }).strict().superRefine(validate43);
11819
+ var aliases18 = {
11598
11820
  h: "height",
11599
11821
  upperw: "upperWidth",
11600
11822
  lowerw: "lowerWidth",
@@ -11615,31 +11837,53 @@ function parseZeeBarModelParams(raw) {
11615
11837
  const props = { fn: "zeebar" };
11616
11838
  for (const token of tokens) {
11617
11839
  const [key, value] = parseGearToken(token);
11618
- if (!Object.hasOwn(aliases16, key) || !value)
11840
+ if (!Object.hasOwn(aliases18, key) || !value)
11619
11841
  throw new Error(`Unknown or malformed zeebar token "${token}"`);
11620
- const property = aliases16[key];
11842
+ const property = aliases18[key];
11621
11843
  if (Object.hasOwn(props, property))
11622
11844
  throw new Error(`Repeated zeebar property "${property}"`);
11623
11845
  props[property] = value;
11624
11846
  }
11625
11847
  return zeeBarModelDefinitionSchema.parse(props);
11626
11848
  }
11627
- var model49 = defineModel({
11849
+ var model51 = defineModel({
11628
11850
  name: "zeebar",
11629
11851
  schema: zeeBarModelDefinitionSchema,
11630
11852
  parse: parseZeeBarModelParams
11631
11853
  });
11632
- function register49(registry2) {
11633
- registry2.register(model49);
11854
+ function register51(registry2) {
11855
+ registry2.register(model51);
11634
11856
  }
11635
11857
  function getNemaMotorReferencePoints(input) {
11636
11858
  const p = nemaMotorModelPropsSchema.parse(input);
11637
11859
  const radians = p.wireSideAngle * Math.PI / 180;
11638
11860
  const x = Math.cos(radians), y = Math.sin(radians);
11639
- const radius = Math.min(
11861
+ let radius = Math.min(
11640
11862
  p.bodyWidth / 2 / Math.max(Math.abs(x), Math.abs(y)),
11641
11863
  (p.bodyWidth - p.faceCornerChamfer) / (Math.abs(x) + Math.abs(y))
11642
11864
  );
11865
+ if (p.nemaSize === 34 && p.cornerProfile === "stepped") {
11866
+ const h2 = p.bodyWidth / 2, c = p.bodyCornerChamfer / Math.SQRT2, r = Math.min(4, c / 4);
11867
+ const contains = (distance2) => {
11868
+ const a = Math.abs(distance2 * x), b = Math.abs(distance2 * y);
11869
+ if (a > h2 || b > h2) return false;
11870
+ if (c === 0) return true;
11871
+ if (a > h2 - c && b > h2 - c)
11872
+ return a <= h2 - c + r && b <= h2 - c + r && Math.hypot(a - (h2 - c + r), b - (h2 - c + r)) >= r;
11873
+ if (b > h2 - r && a > h2 - c - r)
11874
+ return Math.hypot(a - (h2 - c - r), b - (h2 - r)) <= r;
11875
+ if (a > h2 - r && b > h2 - c - r)
11876
+ return Math.hypot(a - (h2 - r), b - (h2 - c - r)) <= r;
11877
+ return true;
11878
+ };
11879
+ let low = 0, high = p.bodyWidth;
11880
+ for (let i = 0; i < 50; i++) {
11881
+ const mid = (low + high) / 2;
11882
+ if (contains(mid)) low = mid;
11883
+ else high = mid;
11884
+ }
11885
+ radius = low;
11886
+ }
11643
11887
  const flatRadians = p.shaftFlatAngle * Math.PI / 180;
11644
11888
  return {
11645
11889
  frontface: {
@@ -11658,7 +11902,7 @@ function getNemaMotorReferencePoints(input) {
11658
11902
  position: {
11659
11903
  x: radius * x,
11660
11904
  y: radius * y,
11661
- z: -p.bodyLength + p.rearCapLength / 2
11905
+ z: p.nemaSize === 34 ? -p.bodyLength + p.rearCapLength + 3 : -p.bodyLength + p.rearCapLength / 2
11662
11906
  },
11663
11907
  direction: { x, y, z: 0 }
11664
11908
  },
@@ -11725,7 +11969,9 @@ var modelDefinitionSchema = external_exports.union([
11725
11969
  model46.schema,
11726
11970
  model47.schema,
11727
11971
  model48.schema,
11728
- model49.schema
11972
+ model49.schema,
11973
+ model50.schema,
11974
+ model51.schema
11729
11975
  ]);
11730
11976
  function registerAllModels(registry2) {
11731
11977
  register(registry2);
@@ -11777,6 +12023,8 @@ function registerAllModels(registry2) {
11777
12023
  register47(registry2);
11778
12024
  register48(registry2);
11779
12025
  register49(registry2);
12026
+ register50(registry2);
12027
+ register51(registry2);
11780
12028
  }
11781
12029
  var registry = new ModelRegistry();
11782
12030
  registerAllModels(registry);
@@ -11959,24 +12207,24 @@ var FootprintPlatedHole = ({
11959
12207
  };
11960
12208
 
11961
12209
  // lib/model-registry.ts
11962
- function defineModelRenderer(model98) {
11963
- return model98;
12210
+ function defineModelRenderer(model102) {
12211
+ return model102;
11964
12212
  }
11965
12213
  var ModelRendererRegistry = class {
11966
12214
  models = /* @__PURE__ */ new Map();
11967
- register(model98) {
11968
- if (typeof model98.name !== "string" || !/^[a-z]+$/.test(model98.name)) {
12215
+ register(model102) {
12216
+ if (typeof model102.name !== "string" || !/^[a-z]+$/.test(model102.name)) {
11969
12217
  throw new Error(
11970
12218
  "Model renderer names must contain only lowercase letters"
11971
12219
  );
11972
12220
  }
11973
- if (this.models.has(model98.name)) {
11974
- throw new Error(`Model renderer "${model98.name}" is already registered`);
12221
+ if (this.models.has(model102.name)) {
12222
+ throw new Error(`Model renderer "${model102.name}" is already registered`);
11975
12223
  }
11976
- if (model98.pads !== "none" && model98.pads !== "footprinter") {
12224
+ if (model102.pads !== "none" && model102.pads !== "footprinter") {
11977
12225
  throw new Error('Model renderer pads must be "none" or "footprinter"');
11978
12226
  }
11979
- const { name, schema, render: render2, pads } = model98;
12227
+ const { name, schema, render: render2, pads } = model102;
11980
12228
  this.models.set(name, {
11981
12229
  name,
11982
12230
  schema,
@@ -12007,7 +12255,7 @@ import jscad from "@jscad/modeling";
12007
12255
  var { primitives, extrusions, geometries, modifiers, measurements } = jscad;
12008
12256
  var generalize = modifiers.generalize;
12009
12257
  var { rectangle, roundedRectangle, polygon } = primitives;
12010
- var profile = (shape44, height10) => extrusions.extrudeLinear({ height: height10 }, shape44);
12258
+ var profile = (shape46, height10) => extrusions.extrudeLinear({ height: height10 }, shape46);
12011
12259
  function filletProfile(points, radii, width10, height10) {
12012
12260
  const outline = [];
12013
12261
  for (let i = 0; i < points.length; i++) {
@@ -12102,14 +12350,14 @@ function AngleBar({ color = "#929da9", ...props }) {
12102
12350
  }
12103
12351
 
12104
12352
  // lib/models/anglebar/register.tsx
12105
- var model50 = defineModelRenderer({
12353
+ var model52 = defineModelRenderer({
12106
12354
  name: "anglebar",
12107
12355
  schema: angleBarModelDefinitionSchema,
12108
12356
  render: ({ fn, ...props }) => /* @__PURE__ */ jsx(AngleBar, { ...props }),
12109
12357
  pads: "none"
12110
12358
  });
12111
- function register50(registry2) {
12112
- registry2.register(model50);
12359
+ function register52(registry2) {
12360
+ registry2.register(model52);
12113
12361
  }
12114
12362
 
12115
12363
  // lib/mechanical/indexedMeshToGeom3.ts
@@ -12240,7 +12488,7 @@ function createBallBearingMesh(input = {}, options = {}) {
12240
12488
  if (face2 === "open") continue;
12241
12489
  const t = d.closureThickness;
12242
12490
  const ri = d.innerRaceOuterRadius, ro = d.outerRaceInnerRadius;
12243
- const shape44 = face2 === "shielded" ? [
12491
+ const shape46 = face2 === "shielded" ? [
12244
12492
  [ro, 0],
12245
12493
  [ro, t * 0.45],
12246
12494
  [ri, t * 0.45],
@@ -12253,7 +12501,7 @@ function createBallBearingMesh(input = {}, options = {}) {
12253
12501
  [ri + 0.15 * (ro - ri), 0.5 * t],
12254
12502
  [ro - 0.15 * (ro - ri), 0.5 * t]
12255
12503
  ];
12256
- const profile6 = sign === -1 ? shape44 : shape44.map(([r, z]) => [r, d.width - z]).reverse();
12504
+ const profile6 = sign === -1 ? shape46 : shape46.map(([r, z]) => [r, d.width - z]).reverse();
12257
12505
  parts.push({
12258
12506
  name: `${face2} ${sign < 0 ? "lower" : "upper"}`,
12259
12507
  color: face2 === "sealed" ? "#252a30" : "#b5bbc3",
@@ -12377,14 +12625,14 @@ function BallBearing({ color, ...props }) {
12377
12625
  }
12378
12626
 
12379
12627
  // lib/models/ballbearing/register.tsx
12380
- var model51 = defineModelRenderer({
12628
+ var model53 = defineModelRenderer({
12381
12629
  name: "ballbearing",
12382
12630
  schema: ballBearingModelDefinitionSchema,
12383
12631
  render: ({ fn, ...props }) => /* @__PURE__ */ jsx(BallBearing, { ...props }),
12384
12632
  pads: "none"
12385
12633
  });
12386
- function register51(registry2) {
12387
- registry2.register(model51);
12634
+ function register53(registry2) {
12635
+ registry2.register(model53);
12388
12636
  }
12389
12637
 
12390
12638
  // lib/models/balltransferunit/mesh.ts
@@ -12633,14 +12881,14 @@ function BallTransferUnit({ color, ...props }) {
12633
12881
  }
12634
12882
 
12635
12883
  // lib/models/balltransferunit/register.tsx
12636
- var model52 = defineModelRenderer({
12884
+ var model54 = defineModelRenderer({
12637
12885
  name: "balltransferunit",
12638
12886
  schema: ballTransferUnitModelDefinitionSchema,
12639
12887
  render: ({ fn, ...props }) => /* @__PURE__ */ jsx(BallTransferUnit, { ...props }),
12640
12888
  pads: "none"
12641
12889
  });
12642
- function register52(registry2) {
12643
- registry2.register(model52);
12890
+ function register54(registry2) {
12891
+ registry2.register(model54);
12644
12892
  }
12645
12893
 
12646
12894
  // lib/models/buttonscrew/mesh.ts
@@ -12760,14 +13008,14 @@ function ButtonScrew({ color = "#737e8f", ...props }) {
12760
13008
  }
12761
13009
 
12762
13010
  // lib/models/buttonscrew/register.tsx
12763
- var model53 = defineModelRenderer({
13011
+ var model55 = defineModelRenderer({
12764
13012
  name: "buttonscrew",
12765
13013
  schema: buttonScrewModelDefinitionSchema,
12766
13014
  render: ({ fn, ...props }) => /* @__PURE__ */ jsx(ButtonScrew, { ...props }),
12767
13015
  pads: "none"
12768
13016
  });
12769
- function register53(registry2) {
12770
- registry2.register(model53);
13017
+ function register55(registry2) {
13018
+ registry2.register(model55);
12771
13019
  }
12772
13020
 
12773
13021
  // lib/models/cablegrommet/mesh.ts
@@ -12835,14 +13083,14 @@ function CableGrommet({
12835
13083
  }
12836
13084
 
12837
13085
  // lib/models/cablegrommet/register.tsx
12838
- var model54 = defineModelRenderer({
13086
+ var model56 = defineModelRenderer({
12839
13087
  name: "cablegrommet",
12840
13088
  schema: cableGrommetModelDefinitionSchema,
12841
13089
  render: ({ fn, ...props }) => /* @__PURE__ */ jsx(CableGrommet, { ...props }),
12842
13090
  pads: "none"
12843
13091
  });
12844
- function register54(registry2) {
12845
- registry2.register(model54);
13092
+ function register56(registry2) {
13093
+ registry2.register(model56);
12846
13094
  }
12847
13095
 
12848
13096
  // lib/models/channelbar/geometry.ts
@@ -12850,7 +13098,7 @@ import jscad3 from "@jscad/modeling";
12850
13098
  var { primitives: primitives2, extrusions: extrusions2, geometries: geometries2, modifiers: modifiers2, measurements: measurements2 } = jscad3;
12851
13099
  var generalize2 = modifiers2.generalize;
12852
13100
  var { rectangle: rectangle2, roundedRectangle: roundedRectangle2, polygon: polygon2 } = primitives2;
12853
- var profile2 = (shape44, height10) => extrusions2.extrudeLinear({ height: height10 }, shape44);
13101
+ var profile2 = (shape46, height10) => extrusions2.extrudeLinear({ height: height10 }, shape46);
12854
13102
  function filletProfile2(points, radii, width10, height10) {
12855
13103
  const outline = [];
12856
13104
  for (let i = 0; i < points.length; i++) {
@@ -12956,14 +13204,14 @@ function ChannelBar({ color = "#929da9", ...props }) {
12956
13204
  }
12957
13205
 
12958
13206
  // lib/models/channelbar/register.tsx
12959
- var model55 = defineModelRenderer({
13207
+ var model57 = defineModelRenderer({
12960
13208
  name: "channelbar",
12961
13209
  schema: channelBarModelDefinitionSchema,
12962
13210
  render: ({ fn, ...props }) => /* @__PURE__ */ jsx(ChannelBar, { ...props }),
12963
13211
  pads: "none"
12964
13212
  });
12965
- function register55(registry2) {
12966
- registry2.register(model55);
13213
+ function register57(registry2) {
13214
+ registry2.register(model57);
12967
13215
  }
12968
13216
 
12969
13217
  // lib/models/clampingshaftcollar/mesh.ts
@@ -12991,9 +13239,9 @@ function createAnnularSleeve({
12991
13239
  outerRadius,
12992
13240
  boreARadius,
12993
13241
  boreBRadius = boreARadius,
12994
- length: length29,
13242
+ length: length30,
12995
13243
  chamfer,
12996
- stepZ = length29 / 2
13244
+ stepZ = length30 / 2
12997
13245
  }) {
12998
13246
  const halfAngle = Math.PI / bodySegments;
12999
13247
  const cosine = Math.cos(halfAngle);
@@ -13004,10 +13252,10 @@ function createAnnularSleeve({
13004
13252
  const raw = [
13005
13253
  [0, outerRadius - chamfer, false],
13006
13254
  [chamfer, outerRadius, false],
13007
- [length29 - chamfer, outerRadius, false],
13008
- [length29, outerRadius - chamfer, false],
13009
- [length29, boreBRadius + chamfer, true],
13010
- [length29 - chamfer, boreBRadius, true],
13255
+ [length30 - chamfer, outerRadius, false],
13256
+ [length30, outerRadius - chamfer, false],
13257
+ [length30, boreBRadius + chamfer, true],
13258
+ [length30 - chamfer, boreBRadius, true],
13011
13259
  [stepZ, boreBRadius, true],
13012
13260
  [stepZ, boreARadius, true],
13013
13261
  [chamfer, boreARadius, true],
@@ -13257,14 +13505,14 @@ function ClampingShaftCollar({
13257
13505
  }
13258
13506
 
13259
13507
  // lib/models/clampingshaftcollar/register.tsx
13260
- var model56 = defineModelRenderer({
13508
+ var model58 = defineModelRenderer({
13261
13509
  name: "clampingshaftcollar",
13262
13510
  schema: clampingShaftCollarModelDefinitionSchema,
13263
13511
  render: ({ fn, ...props }) => /* @__PURE__ */ jsx(ClampingShaftCollar, { ...props }),
13264
13512
  pads: "none"
13265
13513
  });
13266
- function register56(registry2) {
13267
- registry2.register(model56);
13514
+ function register58(registry2) {
13515
+ registry2.register(model58);
13268
13516
  }
13269
13517
 
13270
13518
  // lib/mechanical/clip-mesh-to-z-range.ts
@@ -13460,14 +13708,14 @@ function CompressionSpring({
13460
13708
  }
13461
13709
 
13462
13710
  // lib/models/compressionspring/register.tsx
13463
- var model57 = defineModelRenderer({
13711
+ var model59 = defineModelRenderer({
13464
13712
  name: "compressionspring",
13465
13713
  schema: compressionSpringModelDefinitionSchema,
13466
13714
  render: ({ fn, ...props }) => /* @__PURE__ */ jsx(CompressionSpring, { ...props }),
13467
13715
  pads: "none"
13468
13716
  });
13469
- function register57(registry2) {
13470
- registry2.register(model57);
13717
+ function register59(registry2) {
13718
+ registry2.register(model59);
13471
13719
  }
13472
13720
 
13473
13721
  // lib/models/dowelpin/mesh.ts
@@ -13518,14 +13766,14 @@ function DowelPin({ color = "#929da9", ...props }) {
13518
13766
  }
13519
13767
 
13520
13768
  // lib/models/dowelpin/register.tsx
13521
- var model58 = defineModelRenderer({
13769
+ var model60 = defineModelRenderer({
13522
13770
  name: "dowelpin",
13523
13771
  schema: dowelPinModelDefinitionSchema,
13524
13772
  render: ({ fn, ...props }) => /* @__PURE__ */ jsx(DowelPin, { ...props }),
13525
13773
  pads: "none"
13526
13774
  });
13527
- function register58(registry2) {
13528
- registry2.register(model58);
13775
+ function register60(registry2) {
13776
+ registry2.register(model60);
13529
13777
  }
13530
13778
 
13531
13779
  // lib/models/femalestandoff/mesh.ts
@@ -13627,14 +13875,14 @@ function FemaleStandoff({
13627
13875
  }
13628
13876
 
13629
13877
  // lib/models/femalestandoff/register.tsx
13630
- var model59 = defineModelRenderer({
13878
+ var model61 = defineModelRenderer({
13631
13879
  name: "femalestandoff",
13632
13880
  schema: femaleStandoffModelDefinitionSchema,
13633
13881
  render: ({ fn, ...props }) => /* @__PURE__ */ jsx(FemaleStandoff, { ...props }),
13634
13882
  pads: "none"
13635
13883
  });
13636
- function register59(registry2) {
13637
- registry2.register(model59);
13884
+ function register61(registry2) {
13885
+ registry2.register(model61);
13638
13886
  }
13639
13887
 
13640
13888
  // lib/models/flangebolt/mesh.ts
@@ -13781,14 +14029,14 @@ function FlangeBolt({ color = "#737e8f", ...props }) {
13781
14029
  }
13782
14030
 
13783
14031
  // lib/models/flangebolt/register.tsx
13784
- var model60 = defineModelRenderer({
14032
+ var model62 = defineModelRenderer({
13785
14033
  name: "flangebolt",
13786
14034
  schema: flangeboltModelDefinitionSchema,
13787
14035
  render: ({ fn, ...props }) => /* @__PURE__ */ jsx(FlangeBolt, { ...props }),
13788
14036
  pads: "none"
13789
14037
  });
13790
- function register60(registry2) {
13791
- registry2.register(model60);
14038
+ function register62(registry2) {
14039
+ registry2.register(model62);
13792
14040
  }
13793
14041
 
13794
14042
  // lib/models/flangedbushing/mesh.ts
@@ -13837,14 +14085,14 @@ function FlangedBushing({
13837
14085
  }
13838
14086
 
13839
14087
  // lib/models/flangedbushing/register.tsx
13840
- var model61 = defineModelRenderer({
14088
+ var model63 = defineModelRenderer({
13841
14089
  name: "flangedbushing",
13842
14090
  schema: flangedBushingModelDefinitionSchema,
13843
14091
  render: ({ fn, ...props }) => /* @__PURE__ */ jsx(FlangedBushing, { ...props }),
13844
14092
  pads: "none"
13845
14093
  });
13846
- function register61(registry2) {
13847
- registry2.register(model61);
14094
+ function register63(registry2) {
14095
+ registry2.register(model63);
13848
14096
  }
13849
14097
 
13850
14098
  // lib/models/flangenut/mesh.ts
@@ -13950,14 +14198,14 @@ function FlangeNut({ color = "#737e8f", ...props }) {
13950
14198
  }
13951
14199
 
13952
14200
  // lib/models/flangenut/register.tsx
13953
- var model62 = defineModelRenderer({
14201
+ var model64 = defineModelRenderer({
13954
14202
  name: "flangenut",
13955
14203
  schema: flangeNutModelDefinitionSchema,
13956
14204
  render: ({ fn, ...props }) => /* @__PURE__ */ jsx(FlangeNut, { ...props }),
13957
14205
  pads: "none"
13958
14206
  });
13959
- function register62(registry2) {
13960
- registry2.register(model62);
14207
+ function register64(registry2) {
14208
+ registry2.register(model64);
13961
14209
  }
13962
14210
 
13963
14211
  // lib/models/flatheadscrew/mesh.ts
@@ -14084,14 +14332,14 @@ function FlatHeadScrew({
14084
14332
  }
14085
14333
 
14086
14334
  // lib/models/flatheadscrew/register.tsx
14087
- var model63 = defineModelRenderer({
14335
+ var model65 = defineModelRenderer({
14088
14336
  name: "flatheadscrew",
14089
14337
  schema: flatHeadScrewModelDefinitionSchema,
14090
14338
  render: ({ fn, ...props }) => /* @__PURE__ */ jsx(FlatHeadScrew, { ...props }),
14091
14339
  pads: "none"
14092
14340
  });
14093
- function register63(registry2) {
14094
- registry2.register(model63);
14341
+ function register65(registry2) {
14342
+ registry2.register(model65);
14095
14343
  }
14096
14344
 
14097
14345
  // lib/Screen.tsx
@@ -14766,14 +15014,14 @@ var FlexScreen = (props) => {
14766
15014
  };
14767
15015
 
14768
15016
  // lib/models/flexscreen/register.tsx
14769
- var model64 = defineModelRenderer({
15017
+ var model66 = defineModelRenderer({
14770
15018
  name: "flexscreen",
14771
15019
  schema: flexScreenModelDefinitionSchema,
14772
15020
  render: ({ fn, ...props }) => /* @__PURE__ */ jsx(FlexScreen, { ...props }),
14773
15021
  pads: "footprinter"
14774
15022
  });
14775
- function register64(registry2) {
14776
- registry2.register(model64);
15023
+ function register66(registry2) {
15024
+ registry2.register(model66);
14777
15025
  }
14778
15026
 
14779
15027
  // lib/models/heatsetinsert/mesh.ts
@@ -14858,14 +15106,14 @@ function HeatSetInsert({
14858
15106
  }
14859
15107
 
14860
15108
  // lib/models/heatsetinsert/register.tsx
14861
- var model65 = defineModelRenderer({
15109
+ var model67 = defineModelRenderer({
14862
15110
  name: "heatsetinsert",
14863
15111
  schema: heatSetInsertModelDefinitionSchema,
14864
15112
  render: ({ fn, ...props }) => /* @__PURE__ */ jsx(HeatSetInsert, { ...props }),
14865
15113
  pads: "none"
14866
15114
  });
14867
- function register65(registry2) {
14868
- registry2.register(model65);
15115
+ function register67(registry2) {
15116
+ registry2.register(model67);
14869
15117
  }
14870
15118
 
14871
15119
  // lib/mechanical/spur-gear-mesh.ts
@@ -15058,14 +15306,14 @@ function HelicalGear({ color = "#737e8f", ...props }) {
15058
15306
  }
15059
15307
 
15060
15308
  // lib/models/helicalgear/register.tsx
15061
- var model66 = defineModelRenderer({
15309
+ var model68 = defineModelRenderer({
15062
15310
  name: "helicalgear",
15063
15311
  schema: helicalGearModelDefinitionSchema,
15064
15312
  render: ({ fn, ...props }) => /* @__PURE__ */ jsx(HelicalGear, { ...props }),
15065
15313
  pads: "none"
15066
15314
  });
15067
- function register66(registry2) {
15068
- registry2.register(model66);
15315
+ function register68(registry2) {
15316
+ registry2.register(model68);
15069
15317
  }
15070
15318
 
15071
15319
  // lib/models/hexbolt/mesh.ts
@@ -15200,14 +15448,14 @@ function HexBolt({ color = "#737e8f", ...props }) {
15200
15448
  }
15201
15449
 
15202
15450
  // lib/models/hexbolt/register.tsx
15203
- var model67 = defineModelRenderer({
15451
+ var model69 = defineModelRenderer({
15204
15452
  name: "hexbolt",
15205
15453
  schema: hexBoltModelDefinitionSchema,
15206
15454
  render: ({ fn, ...props }) => /* @__PURE__ */ jsx(HexBolt, { ...props }),
15207
15455
  pads: "none"
15208
15456
  });
15209
- function register67(registry2) {
15210
- registry2.register(model67);
15457
+ function register69(registry2) {
15458
+ registry2.register(model69);
15211
15459
  }
15212
15460
 
15213
15461
  // lib/models/hexnut/mesh.ts
@@ -15326,14 +15574,14 @@ function HexNut({ color = "#737e8f", ...props }) {
15326
15574
  }
15327
15575
 
15328
15576
  // lib/models/hexnut/register.tsx
15329
- var model68 = defineModelRenderer({
15577
+ var model70 = defineModelRenderer({
15330
15578
  name: "hexnut",
15331
15579
  schema: hexNutModelDefinitionSchema,
15332
15580
  render: ({ fn, ...props }) => /* @__PURE__ */ jsx(HexNut, { ...props }),
15333
15581
  pads: "none"
15334
15582
  });
15335
- function register68(registry2) {
15336
- registry2.register(model68);
15583
+ function register70(registry2) {
15584
+ registry2.register(model70);
15337
15585
  }
15338
15586
 
15339
15587
  // lib/mechanical/hex-socket-bolt-mesh.ts
@@ -15347,9 +15595,9 @@ var createHexSocketBoltMesh = (input) => {
15347
15595
  socketWidth,
15348
15596
  socketDepth
15349
15597
  } = hexSocketBoltDimensions[props.metricSize];
15350
- const { length: length29, showThreads } = props;
15598
+ const { length: length30, showThreads } = props;
15351
15599
  const segments = 96;
15352
- const steps = showThreads ? Math.max(2, Math.ceil(length29 / pitch * 24)) : 2;
15600
+ const steps = showThreads ? Math.max(2, Math.ceil(length30 / pitch * 24)) : 2;
15353
15601
  if (steps > 24e3)
15354
15602
  throw new Error(
15355
15603
  "Bolt length exceeds mesh resolution limit (1000 thread turns)"
@@ -15359,7 +15607,7 @@ var createHexSocketBoltMesh = (input) => {
15359
15607
  const radius = diameter / 2;
15360
15608
  const depth = pitch * 0.61343;
15361
15609
  const bevel = Math.min(0.2, headHeight * 0.08);
15362
- const tipBevel = Math.min(pitch * 0.6, length29 / 3);
15610
+ const tipBevel = Math.min(pitch * 0.6, length30 / 3);
15363
15611
  const ring = (z, radiusAt) => {
15364
15612
  const start = positions.length / 3;
15365
15613
  for (let i = 0; i < segments; i++) {
@@ -15387,8 +15635,8 @@ var createHexSocketBoltMesh = (input) => {
15387
15635
  let previous = -1;
15388
15636
  const shaftLevels = showThreads ? Array.from(
15389
15637
  { length: steps + 1 },
15390
- (_, step) => -length29 + length29 * step / steps
15391
- ) : [-length29, -length29 + tipBevel, 0];
15638
+ (_, step) => -length30 + length30 * step / steps
15639
+ ) : [-length30, -length30 + tipBevel, 0];
15392
15640
  for (const z of shaftLevels) {
15393
15641
  const current = ring(z, (angle) => {
15394
15642
  const phase = ((z / pitch - angle / (2 * Math.PI)) % 1 + 1) % 1;
@@ -15399,10 +15647,10 @@ var createHexSocketBoltMesh = (input) => {
15399
15647
  );
15400
15648
  const endRamp = Math.min(
15401
15649
  1,
15402
- (z + length29) / tipBevel,
15403
- -z / Math.min(pitch / 2, length29 / 3)
15650
+ (z + length30) / tipBevel,
15651
+ -z / Math.min(pitch / 2, length30 / 3)
15404
15652
  );
15405
- const tipCut = tipBevel * Math.max(0, 1 - (z + length29) / tipBevel);
15653
+ const tipCut = tipBevel * Math.max(0, 1 - (z + length30) / tipBevel);
15406
15654
  return radius - (showThreads ? groove * endRamp : 0) - tipCut;
15407
15655
  });
15408
15656
  if (previous < 0) cap2(current, z, false);
@@ -15438,14 +15686,14 @@ function HexSocketBolt({
15438
15686
  }
15439
15687
 
15440
15688
  // lib/models/hexsocketbolt/register.tsx
15441
- var model69 = defineModelRenderer({
15689
+ var model71 = defineModelRenderer({
15442
15690
  name: "hexsocketbolt",
15443
15691
  schema: hexSocketBoltModelDefinitionSchema,
15444
15692
  render: ({ fn, ...props }) => /* @__PURE__ */ jsx(HexSocketBolt, { ...props }),
15445
15693
  pads: "none"
15446
15694
  });
15447
- function register69(registry2) {
15448
- registry2.register(model69);
15695
+ function register71(registry2) {
15696
+ registry2.register(model71);
15449
15697
  }
15450
15698
 
15451
15699
  // lib/models/hollowpositioningarmtube/mesh.ts
@@ -15558,14 +15806,14 @@ function HollowPositioningArmTube({
15558
15806
  }
15559
15807
 
15560
15808
  // lib/models/hollowpositioningarmtube/register.tsx
15561
- var model70 = defineModelRenderer({
15809
+ var model72 = defineModelRenderer({
15562
15810
  name: "hollowpositioningarmtube",
15563
15811
  schema: hollowPositioningArmTubeModelDefinitionSchema,
15564
15812
  render: ({ fn, ...props }) => /* @__PURE__ */ jsx(HollowPositioningArmTube, { ...props }),
15565
15813
  pads: "none"
15566
15814
  });
15567
- function register70(registry2) {
15568
- registry2.register(model70);
15815
+ function register72(registry2) {
15816
+ registry2.register(model72);
15569
15817
  }
15570
15818
 
15571
15819
  // lib/models/malefemalestandoff/mesh.ts
@@ -15697,21 +15945,76 @@ function MaleFemaleStandoff({
15697
15945
  }
15698
15946
 
15699
15947
  // lib/models/malefemalestandoff/register.tsx
15700
- var model71 = defineModelRenderer({
15948
+ var model73 = defineModelRenderer({
15701
15949
  name: "malefemalestandoff",
15702
15950
  schema: maleFemaleStandoffModelDefinitionSchema,
15703
15951
  render: ({ fn, ...props }) => /* @__PURE__ */ jsx(MaleFemaleStandoff, { ...props }),
15704
15952
  pads: "none"
15705
15953
  });
15706
- function register71(registry2) {
15707
- registry2.register(model71);
15954
+ function register73(registry2) {
15955
+ registry2.register(model73);
15956
+ }
15957
+
15958
+ // lib/utils/nemaMotorAssemblyGeometry.ts
15959
+ import jscad6 from "@jscad/modeling";
15960
+ function nema34AssemblyCenters(p) {
15961
+ const edge = p.bodyWidth / 2;
15962
+ return [-1, 1].flatMap(
15963
+ (side) => [-1, 1].map(
15964
+ (end) => [side * (edge - 3.5), end * p.bodyWidth * 0.26]
15965
+ )
15966
+ );
15967
+ }
15968
+ function cutNema34FrontRecesses(geometry, p) {
15969
+ return jscad6.booleans.subtract(
15970
+ geometry,
15971
+ ...nema34AssemblyCenters(p).flatMap(([x, y]) => [
15972
+ jscad6.primitives.cylinder({
15973
+ radius: 1.6,
15974
+ height: p.frontCapLength + 0.2,
15975
+ center: [x, y, -p.frontCapLength / 2],
15976
+ segments: 32
15977
+ }),
15978
+ jscad6.primitives.cylinder({
15979
+ radius: 5,
15980
+ height: Math.min(4, p.frontCapLength / 2) + 0.1,
15981
+ center: [
15982
+ Math.sign(x) * p.bodyWidth / 2,
15983
+ y,
15984
+ -Math.min(4, p.frontCapLength / 2) / 2 + 0.05
15985
+ ],
15986
+ segments: 48
15987
+ })
15988
+ ])
15989
+ );
15990
+ }
15991
+ function createNema34FrontScrews(p) {
15992
+ const head = jscad6.booleans.subtract(
15993
+ jscad6.primitives.ellipsoid({
15994
+ radius: [3.2, 3.2, 1.5],
15995
+ center: [0, 0, -1.8],
15996
+ segments: 32
15997
+ }),
15998
+ ...[
15999
+ [3.7, 0.8, 1.1],
16000
+ [0.8, 3.7, 1.1]
16001
+ ].map(
16002
+ (size) => jscad6.primitives.cuboid({
16003
+ size,
16004
+ center: [0, 0, -0.8]
16005
+ })
16006
+ )
16007
+ );
16008
+ return nema34AssemblyCenters(p).map(
16009
+ ([x, y]) => jscad6.transforms.translate([x, y, 0], head)
16010
+ );
15708
16011
  }
15709
16012
 
15710
16013
  // lib/NemaMotor.tsx
15711
- import jscad7 from "@jscad/modeling";
16014
+ import jscad8 from "@jscad/modeling";
15712
16015
 
15713
16016
  // lib/utils/nemaMotorWireGeometry.ts
15714
- import jscad6 from "@jscad/modeling";
16017
+ import jscad7 from "@jscad/modeling";
15715
16018
 
15716
16019
  // lib/utils/nemaMotorParameters.ts
15717
16020
  var resolveNemaMotorProps = nemaMotorModelPropsSchema.parse.bind(nemaMotorModelPropsSchema);
@@ -15722,9 +16025,9 @@ function createNemaMotorWireGeometry(input) {
15722
16025
  if (p.wireConnection === "none") return [];
15723
16026
  const { position } = getNemaMotorReferencePoints(p).wireside;
15724
16027
  const angle = p.wireSideAngle * Math.PI / 180;
15725
- const place = (geometry) => jscad6.transforms.translate(
16028
+ const place = (geometry) => jscad7.transforms.translate(
15726
16029
  [position.x, position.y, position.z],
15727
- jscad6.transforms.rotateZ(angle, geometry)
16030
+ jscad7.transforms.rotateZ(angle, geometry)
15728
16031
  );
15729
16032
  if (p.wireConnection === "stubs") {
15730
16033
  const colors = [
@@ -15737,18 +16040,18 @@ function createNemaMotorWireGeometry(input) {
15737
16040
  "#ce7432",
15738
16041
  "#803e91"
15739
16042
  ];
15740
- return Array.from({ length: p.wireCount }, (_, i) => ({
16043
+ const wires = Array.from({ length: p.wireCount }, (_, i) => ({
15741
16044
  color: colors[i],
15742
16045
  geometry: place(
15743
- jscad6.transforms.translate(
16046
+ jscad7.transforms.translate(
15744
16047
  [
15745
16048
  (p.wireLength - 0.15) / 2,
15746
16049
  (i - (p.wireCount - 1) / 2) * p.wireDiameter * 1.5,
15747
16050
  0
15748
16051
  ],
15749
- jscad6.transforms.rotateY(
16052
+ jscad7.transforms.rotateY(
15750
16053
  Math.PI / 2,
15751
- jscad6.primitives.cylinder({
16054
+ jscad7.primitives.cylinder({
15752
16055
  height: p.wireLength + 0.15,
15753
16056
  radius: p.wireDiameter / 2,
15754
16057
  segments: 24
@@ -15757,18 +16060,31 @@ function createNemaMotorWireGeometry(input) {
15757
16060
  )
15758
16061
  )
15759
16062
  }));
16063
+ if (p.nemaSize === 34)
16064
+ wires.unshift({
16065
+ color: "#252830",
16066
+ geometry: place(
16067
+ jscad7.primitives.roundedCuboid({
16068
+ size: [3, p.wireCount * p.wireDiameter * 1.5 + 3, 6],
16069
+ center: [0.8, 0, 0],
16070
+ roundRadius: 1,
16071
+ segments: 24
16072
+ })
16073
+ )
16074
+ });
16075
+ return wires;
15760
16076
  }
15761
16077
  const connector = getJstMotorConnector(p.wireConnection);
15762
16078
  const { pinCount, pitch, bodyWidth, bodyHeight, matingDepth } = connector;
15763
16079
  const wall = pitch === 2 ? 0.6 : 0.3;
15764
16080
  const contactLength = pitch === 2 ? 3.4 : 2.4;
15765
16081
  const contactSize = pitch === 2 ? 0.5 : 0.3;
15766
- const shell = jscad6.booleans.subtract(
15767
- jscad6.primitives.cuboid({
16082
+ const shell = jscad7.booleans.subtract(
16083
+ jscad7.primitives.cuboid({
15768
16084
  size: [matingDepth + 0.1, bodyWidth, bodyHeight],
15769
16085
  center: [(matingDepth - 0.1) / 2, 0, 0]
15770
16086
  }),
15771
- jscad6.primitives.cuboid({
16087
+ jscad7.primitives.cuboid({
15772
16088
  size: [matingDepth - 0.5, bodyWidth - 2 * wall, bodyHeight - 2 * wall],
15773
16089
  center: [matingDepth / 2 + 0.55, 0, 0]
15774
16090
  })
@@ -15778,7 +16094,7 @@ function createNemaMotorWireGeometry(input) {
15778
16094
  ...Array.from({ length: pinCount }, (_, i) => ({
15779
16095
  color: "#b8bec6",
15780
16096
  geometry: place(
15781
- jscad6.primitives.cuboid({
16097
+ jscad7.primitives.cuboid({
15782
16098
  size: [contactLength, contactSize, contactSize],
15783
16099
  center: [contactLength / 2, (i - (pinCount - 1) / 2) * pitch, 0]
15784
16100
  })
@@ -15812,14 +16128,59 @@ var face = (width10, chamfer) => {
15812
16128
  [-h2, -h2 + c]
15813
16129
  ];
15814
16130
  };
16131
+ var roundedFace = (width10, radius) => {
16132
+ if (radius === 0) return face(width10, 0);
16133
+ const center = width10 / 2 - radius;
16134
+ return [0, 1, 2, 3].flatMap(
16135
+ (corner) => Array.from({ length: 13 }, (_, i) => {
16136
+ const angle = i * Math.PI / 24, rotation = corner * Math.PI / 2;
16137
+ const x = center + radius * Math.cos(angle), y = center + radius * Math.sin(angle);
16138
+ return [
16139
+ x * Math.cos(rotation) - y * Math.sin(rotation),
16140
+ x * Math.sin(rotation) + y * Math.cos(rotation)
16141
+ ];
16142
+ })
16143
+ );
16144
+ };
16145
+ var steppedFace = (width10, chamfer) => {
16146
+ if (chamfer === 0) return face(width10, 0);
16147
+ const h2 = width10 / 2, c = chamfer / Math.SQRT2, r = Math.min(4, c / 4);
16148
+ const corner = [];
16149
+ const arc = (x, y, from, to) => {
16150
+ for (let i = 0; i <= 12; i++) {
16151
+ const a = (from + (to - from) * i / 12) * Math.PI / 180;
16152
+ corner.push([x + r * Math.cos(a), y + r * Math.sin(a)]);
16153
+ }
16154
+ };
16155
+ arc(h2 - c - r, h2 - r, 90, 0);
16156
+ arc(h2 - c + r, h2 - c + r, 180, 270);
16157
+ arc(h2 - r, h2 - c - r, 90, 0);
16158
+ return [0, 1, 2, 3].flatMap(
16159
+ (i) => corner.map(([x, y]) => {
16160
+ const a = -i * Math.PI / 2;
16161
+ return [
16162
+ x * Math.cos(a) - y * Math.sin(a),
16163
+ x * Math.sin(a) + y * Math.cos(a)
16164
+ ];
16165
+ })
16166
+ ).reverse();
16167
+ };
15815
16168
  function createNemaMotorSections(input) {
15816
16169
  const p = resolveNemaMotorProps(input);
15817
16170
  const sections = [];
15818
16171
  const add = (name, outline, zMin, zMax, holes2 = []) => {
15819
16172
  if (zMax > zMin) sections.push({ name, outline, holes: holes2, zMin, zMax });
15820
16173
  };
15821
- const front = face(p.bodyWidth, p.faceCornerChamfer);
15822
- const core = face(p.bodyWidth, p.bodyCornerChamfer);
16174
+ const front = (p.nemaSize === 34 ? roundedFace : face)(
16175
+ p.bodyWidth,
16176
+ p.faceCornerChamfer
16177
+ );
16178
+ const profile6 = p.cornerProfile === "stepped" ? steppedFace : face;
16179
+ const core = profile6(p.bodyWidth, p.bodyCornerChamfer);
16180
+ const rear = profile6(
16181
+ p.bodyWidth,
16182
+ p.rearCornerChamfer ?? (p.backFace === "plain" && p.mountingHoleThrough ? p.bodyCornerChamfer : p.faceCornerChamfer)
16183
+ );
15823
16184
  const h2 = p.mountingHoleSpacing / 2;
15824
16185
  const centers = [
15825
16186
  [-h2, -h2],
@@ -15835,12 +16196,7 @@ function createNemaMotorSections(input) {
15835
16196
  add("frontCap", front, -p.frontCapLength, -holeDepth);
15836
16197
  add("body", core, -p.bodyLength + p.rearCapLength, -p.frontCapLength);
15837
16198
  if (p.backFace === "plain") {
15838
- add(
15839
- "rearCap",
15840
- p.mountingHoleThrough ? core : front,
15841
- -p.bodyLength,
15842
- -p.bodyLength + p.rearCapLength
15843
- );
16199
+ add("rearCap", rear, -p.bodyLength, -p.bodyLength + p.rearCapLength);
15844
16200
  } else {
15845
16201
  const halfPitch = p.backFaceHoleSpacing / 2;
15846
16202
  const rearHoles = [-halfPitch, halfPitch].flatMap(
@@ -15850,14 +16206,14 @@ function createNemaMotorSections(input) {
15850
16206
  );
15851
16207
  add(
15852
16208
  "rearCap",
15853
- front,
16209
+ rear,
15854
16210
  -p.bodyLength,
15855
16211
  -p.bodyLength + p.backFaceHoleDepth,
15856
16212
  rearHoles
15857
16213
  );
15858
16214
  add(
15859
16215
  "rearCap",
15860
- front,
16216
+ rear,
15861
16217
  -p.bodyLength + p.backFaceHoleDepth,
15862
16218
  -p.bodyLength + p.rearCapLength
15863
16219
  );
@@ -15870,12 +16226,12 @@ function createNemaMotorSections(input) {
15870
16226
  else {
15871
16227
  const cut = r - p.shaftFlatDepth;
15872
16228
  const angle = Math.acos(cut / r);
15873
- const profile6 = Array.from({ length: 97 }, (_, i) => {
16229
+ const profile7 = Array.from({ length: 97 }, (_, i) => {
15874
16230
  const a = angle + (2 * Math.PI - 2 * angle) * i / 96;
15875
16231
  return [r * Math.cos(a), r * Math.sin(a)];
15876
16232
  });
15877
16233
  const rotation = p.shaftFlatAngle * Math.PI / 180;
15878
- const d = profile6.map(([x, y]) => [
16234
+ const d = profile7.map(([x, y]) => [
15879
16235
  x * Math.cos(rotation) - y * Math.sin(rotation),
15880
16236
  x * Math.sin(rotation) + y * Math.cos(rotation)
15881
16237
  ]);
@@ -15886,7 +16242,7 @@ function createNemaMotorSections(input) {
15886
16242
  }
15887
16243
 
15888
16244
  // lib/NemaMotor.tsx
15889
- var generalize3 = jscad7.modifiers.generalize;
16245
+ var generalize3 = jscad8.modifiers.generalize;
15890
16246
  function NemaMotor({
15891
16247
  bodyColor = "#242830",
15892
16248
  capColor = "#aeb5bd",
@@ -15895,7 +16251,7 @@ function NemaMotor({
15895
16251
  ...props
15896
16252
  }) {
15897
16253
  const p = resolveNemaMotorProps(props);
15898
- const screw = p.backFace === "screws" ? jscad7.transforms.rotateX(
16254
+ const screw = p.backFace === "screws" ? jscad8.transforms.rotateX(
15899
16255
  Math.PI,
15900
16256
  createHexSocketBoltGeom({
15901
16257
  metricSize: p.backFaceScrewSize,
@@ -15906,18 +16262,20 @@ function NemaMotor({
15906
16262
  const halfPitch = p.backFaceHoleSpacing / 2;
15907
16263
  return /* @__PURE__ */ jsxs(Fragment2, { children: [
15908
16264
  createNemaMotorSections(p).map((section, index) => {
15909
- const outline = jscad7.geometries.geom2.fromPoints(section.outline);
15910
- const profile6 = section.holes.length ? jscad7.booleans.subtract(
16265
+ const outline = jscad8.geometries.geom2.fromPoints(section.outline);
16266
+ const profile6 = section.holes.length ? jscad8.booleans.subtract(
15911
16267
  outline,
15912
- ...section.holes.map((h2) => jscad7.geometries.geom2.fromPoints(h2))
16268
+ ...section.holes.map((h2) => jscad8.geometries.geom2.fromPoints(h2))
15913
16269
  ) : outline;
15914
- const geometry = jscad7.transforms.translate(
16270
+ let geometry = jscad8.transforms.translate(
15915
16271
  [0, 0, section.zMin],
15916
- jscad7.extrusions.extrudeLinear(
16272
+ jscad8.extrusions.extrudeLinear(
15917
16273
  { height: section.zMax - section.zMin },
15918
16274
  profile6
15919
16275
  )
15920
16276
  );
16277
+ if (p.nemaSize === 34 && section.name === "frontCap")
16278
+ geometry = cutNema34FrontRecesses(geometry, p);
15921
16279
  return /* @__PURE__ */ jsx(
15922
16280
  Colorize,
15923
16281
  {
@@ -15937,6 +16295,15 @@ function NemaMotor({
15937
16295
  },
15938
16296
  `wire-${index}`
15939
16297
  )),
16298
+ p.nemaSize === 34 && createNema34FrontScrews(p).map((geometry, index) => /* @__PURE__ */ jsx(
16299
+ Colorize,
16300
+ {
16301
+ material: componentMaterials.steel,
16302
+ color: screwColor,
16303
+ children: /* @__PURE__ */ jsx(Custom, { geometry: generalize3({ simplify: true }, geometry) })
16304
+ },
16305
+ `front-screw-${index}`
16306
+ )),
15940
16307
  screw && [-halfPitch, halfPitch].flatMap(
15941
16308
  (x) => [-halfPitch, halfPitch].map((y) => /* @__PURE__ */ jsx(
15942
16309
  Colorize,
@@ -15946,7 +16313,7 @@ function NemaMotor({
15946
16313
  children: /* @__PURE__ */ jsx(
15947
16314
  Custom,
15948
16315
  {
15949
- geometry: jscad7.transforms.translate(
16316
+ geometry: jscad8.transforms.translate(
15950
16317
  [x, y, -p.bodyLength],
15951
16318
  generalize3({ simplify: true }, screw)
15952
16319
  )
@@ -15961,16 +16328,17 @@ function NemaMotor({
15961
16328
  var NEMA8 = (props) => /* @__PURE__ */ jsx(NemaMotor, { ...props, nemaSize: 8 });
15962
16329
  var NEMA17 = (props) => /* @__PURE__ */ jsx(NemaMotor, { ...props, nemaSize: 17 });
15963
16330
  var NEMA23 = (props) => /* @__PURE__ */ jsx(NemaMotor, { ...props, nemaSize: 23 });
16331
+ var NEMA34 = (props) => /* @__PURE__ */ jsx(NemaMotor, { ...props, nemaSize: 34 });
15964
16332
 
15965
16333
  // lib/models/nema/register.tsx
15966
- var model72 = defineModelRenderer({
16334
+ var model74 = defineModelRenderer({
15967
16335
  name: "nema",
15968
16336
  schema: nemaMotorModelDefinitionSchema,
15969
16337
  render: ({ fn, ...props }) => /* @__PURE__ */ jsx(NemaMotor, { ...props }),
15970
16338
  pads: "none"
15971
16339
  });
15972
- function register72(registry2) {
15973
- registry2.register(model72);
16340
+ function register74(registry2) {
16341
+ registry2.register(model74);
15974
16342
  }
15975
16343
 
15976
16344
  // lib/models/nylonlocknut/mesh.ts
@@ -16106,14 +16474,14 @@ function NylonLockNut({
16106
16474
  }
16107
16475
 
16108
16476
  // lib/models/nylonlocknut/register.tsx
16109
- var model73 = defineModelRenderer({
16477
+ var model75 = defineModelRenderer({
16110
16478
  name: "nylonlocknut",
16111
16479
  schema: nylonLockNutModelDefinitionSchema,
16112
16480
  render: ({ fn, ...props }) => /* @__PURE__ */ jsx(NylonLockNut, { ...props }),
16113
16481
  pads: "none"
16114
16482
  });
16115
- function register73(registry2) {
16116
- registry2.register(model73);
16483
+ function register75(registry2) {
16484
+ registry2.register(model75);
16117
16485
  }
16118
16486
 
16119
16487
  // lib/models/panscrew/mesh.ts
@@ -16319,18 +16687,123 @@ function PanScrew({ color = "#737e8f", ...props }) {
16319
16687
  }
16320
16688
 
16321
16689
  // lib/models/panscrew/register.tsx
16322
- var model74 = defineModelRenderer({
16690
+ var model76 = defineModelRenderer({
16323
16691
  name: "panscrew",
16324
16692
  schema: panScrewModelDefinitionSchema,
16325
16693
  render: ({ fn, ...props }) => /* @__PURE__ */ jsx(PanScrew, { ...props }),
16326
16694
  pads: "none"
16327
16695
  });
16328
- function register74(registry2) {
16329
- registry2.register(model74);
16696
+ function register76(registry2) {
16697
+ registry2.register(model76);
16698
+ }
16699
+
16700
+ // lib/models/perforatedangle/mesh.ts
16701
+ function quarterBend(radius, thickness) {
16702
+ const outer = radius + thickness;
16703
+ const center = outer;
16704
+ const points = [];
16705
+ for (let step = 0; step <= 48; step++) {
16706
+ const angle = Math.PI + step * Math.PI / 96;
16707
+ points.push(
16708
+ step === 0 ? [0, center] : step === 48 ? [center, 0] : [
16709
+ center + outer * Math.cos(angle),
16710
+ center + outer * Math.sin(angle)
16711
+ ]
16712
+ );
16713
+ }
16714
+ if (radius === 0) points.push([center, center]);
16715
+ else
16716
+ for (let step = 0; step <= 48; step++) {
16717
+ const angle = 3 * Math.PI / 2 - step * Math.PI / 96;
16718
+ points.push(
16719
+ step === 0 ? [center, thickness] : step === 48 ? [thickness, center] : [
16720
+ center + radius * Math.cos(angle),
16721
+ center + radius * Math.sin(angle)
16722
+ ]
16723
+ );
16724
+ }
16725
+ return points;
16726
+ }
16727
+ function createPerforatedAngleMesh(input) {
16728
+ const p = perforatedAngleModelPropsSchema.parse(input);
16729
+ const {
16730
+ width: w,
16731
+ height: h2,
16732
+ thickness: t,
16733
+ length: l,
16734
+ innerRadius: r,
16735
+ holeCount,
16736
+ holeDiameter,
16737
+ pitch,
16738
+ endOffset,
16739
+ legOffset
16740
+ } = p;
16741
+ const tangent = r + t;
16742
+ const panel = (end) => [
16743
+ [tangent, 0],
16744
+ [end, 0],
16745
+ [end, l],
16746
+ [tangent, l]
16747
+ ];
16748
+ const holes = Array.from(
16749
+ { length: holeCount },
16750
+ (_, i) => circularProfile(legOffset, endOffset + i * pitch, holeDiameter / 2)
16751
+ );
16752
+ const mesh = joinProfileMeshes([
16753
+ extrudePlanarProfile({
16754
+ outer: panel(w),
16755
+ holes,
16756
+ start: 0,
16757
+ end: t,
16758
+ project: (u, v, d) => [u, d, v],
16759
+ reverse: true,
16760
+ skipWall: (a, b) => a[0] === tangent && b[0] === tangent
16761
+ }),
16762
+ extrudePlanarProfile({
16763
+ outer: panel(h2),
16764
+ holes,
16765
+ start: 0,
16766
+ end: t,
16767
+ project: (u, v, d) => [d, u, v],
16768
+ skipWall: (a, b) => a[0] === tangent && b[0] === tangent
16769
+ }),
16770
+ extrudePlanarProfile({
16771
+ outer: quarterBend(r, t),
16772
+ start: 0,
16773
+ end: l,
16774
+ skipWall: (a, b) => a[0] === tangent && b[0] === tangent || a[1] === tangent && b[1] === tangent
16775
+ })
16776
+ ]);
16777
+ mesh.positions = mesh.positions.map(
16778
+ (value, index) => value - (index % 3 === 0 ? w / 2 : index % 3 === 1 ? h2 / 2 : 0)
16779
+ );
16780
+ return mesh;
16781
+ }
16782
+
16783
+ // lib/models/perforatedangle/PerforatedAngle.tsx
16784
+ function createPerforatedAngleGeom(input) {
16785
+ return indexedMeshToGeom3(createPerforatedAngleMesh(input));
16786
+ }
16787
+ function PerforatedAngle({
16788
+ color = "#8995a3",
16789
+ ...props
16790
+ }) {
16791
+ return /* @__PURE__ */ jsx(Colorize, { color, children: /* @__PURE__ */ jsx(Custom, { geometry: createPerforatedAngleGeom(props) }) });
16792
+ }
16793
+
16794
+ // lib/models/perforatedangle/register.tsx
16795
+ var model77 = defineModelRenderer({
16796
+ name: "perforatedangle",
16797
+ schema: perforatedAngleModelDefinitionSchema,
16798
+ render: ({ fn, ...props }) => /* @__PURE__ */ jsx(PerforatedAngle, { ...props }),
16799
+ pads: "none"
16800
+ });
16801
+ function register77(registry2) {
16802
+ registry2.register(model77);
16330
16803
  }
16331
16804
 
16332
16805
  // lib/models/perforatedsheet/geometry.ts
16333
- import jscad8 from "@jscad/modeling";
16806
+ import jscad9 from "@jscad/modeling";
16334
16807
  var {
16335
16808
  booleans,
16336
16809
  primitives: primitives3,
@@ -16338,11 +16811,11 @@ var {
16338
16811
  geometries: geometries3,
16339
16812
  modifiers: modifiers3,
16340
16813
  measurements: measurements3
16341
- } = jscad8;
16814
+ } = jscad9;
16342
16815
  var generalize4 = modifiers3.generalize;
16343
16816
  var { subtract } = booleans;
16344
16817
  var { rectangle: rectangle3, roundedRectangle: roundedRectangle3, circle: circle2 } = primitives3;
16345
- var profile3 = (shape44, height10) => extrusions3.extrudeLinear({ height: height10 }, shape44);
16818
+ var profile3 = (shape46, height10) => extrusions3.extrudeLinear({ height: height10 }, shape46);
16346
16819
  function perforated(p) {
16347
16820
  const holes = [];
16348
16821
  const rows = Math.floor((p.width - 2 * p.edgeY) / p.pitchY + 1 + 1e-10);
@@ -16412,14 +16885,14 @@ function PerforatedSheet({
16412
16885
  }
16413
16886
 
16414
16887
  // lib/models/perforatedsheet/register.tsx
16415
- var model75 = defineModelRenderer({
16888
+ var model78 = defineModelRenderer({
16416
16889
  name: "perforatedsheet",
16417
16890
  schema: perforatedSheetModelDefinitionSchema,
16418
16891
  render: ({ fn, ...props }) => /* @__PURE__ */ jsx(PerforatedSheet, { ...props }),
16419
16892
  pads: "none"
16420
16893
  });
16421
- function register75(registry2) {
16422
- registry2.register(model75);
16894
+ function register78(registry2) {
16895
+ registry2.register(model78);
16423
16896
  }
16424
16897
 
16425
16898
  // lib/models/plainbushing/mesh.ts
@@ -16475,19 +16948,19 @@ function PlainBushing({
16475
16948
  }
16476
16949
 
16477
16950
  // lib/models/plainbushing/register.tsx
16478
- var model76 = defineModelRenderer({
16951
+ var model79 = defineModelRenderer({
16479
16952
  name: "plainbushing",
16480
16953
  schema: plainBushingModelDefinitionSchema,
16481
16954
  render: ({ fn, ...props }) => /* @__PURE__ */ jsx(PlainBushing, { ...props }),
16482
16955
  pads: "none"
16483
16956
  });
16484
- function register76(registry2) {
16485
- registry2.register(model76);
16957
+ function register79(registry2) {
16958
+ registry2.register(model79);
16486
16959
  }
16487
16960
 
16488
16961
  // lib/models/pushfitplug/geometry.ts
16489
- import jscad9 from "@jscad/modeling";
16490
- var { primitives: primitives4, extrusions: extrusions4, geometries: geometries4, modifiers: modifiers4, measurements: measurements4 } = jscad9;
16962
+ import jscad10 from "@jscad/modeling";
16963
+ var { primitives: primitives4, extrusions: extrusions4, geometries: geometries4, modifiers: modifiers4, measurements: measurements4 } = jscad10;
16491
16964
  var generalize5 = modifiers4.generalize;
16492
16965
  var { rectangle: rectangle4, roundedRectangle: roundedRectangle4, polygon: polygon3 } = primitives4;
16493
16966
  function createPushFitPlugGeom(input) {
@@ -16547,22 +17020,22 @@ function PushFitPlug({ color = "#929da9", ...props }) {
16547
17020
  }
16548
17021
 
16549
17022
  // lib/models/pushfitplug/register.tsx
16550
- var model77 = defineModelRenderer({
17023
+ var model80 = defineModelRenderer({
16551
17024
  name: "pushfitplug",
16552
17025
  schema: pushFitPlugModelDefinitionSchema,
16553
17026
  render: ({ fn, ...props }) => /* @__PURE__ */ jsx(PushFitPlug, { ...props }),
16554
17027
  pads: "none"
16555
17028
  });
16556
- function register77(registry2) {
16557
- registry2.register(model77);
17029
+ function register80(registry2) {
17030
+ registry2.register(model80);
16558
17031
  }
16559
17032
 
16560
17033
  // lib/models/rectangularbar/geometry.ts
16561
- import jscad10 from "@jscad/modeling";
16562
- var { primitives: primitives5, extrusions: extrusions5, geometries: geometries5, modifiers: modifiers5, measurements: measurements5 } = jscad10;
17034
+ import jscad11 from "@jscad/modeling";
17035
+ var { primitives: primitives5, extrusions: extrusions5, geometries: geometries5, modifiers: modifiers5, measurements: measurements5 } = jscad11;
16563
17036
  var generalize6 = modifiers5.generalize;
16564
17037
  var { rectangle: rectangle5, roundedRectangle: roundedRectangle5 } = primitives5;
16565
- var profile4 = (shape44, height10) => extrusions5.extrudeLinear({ height: height10 }, shape44);
17038
+ var profile4 = (shape46, height10) => extrusions5.extrudeLinear({ height: height10 }, shape46);
16566
17039
  var roundedRect = (width10, height10, radius) => radius ? roundedRectangle5({
16567
17040
  size: [width10, height10],
16568
17041
  roundRadius: radius,
@@ -16616,14 +17089,14 @@ function RectangularBar({
16616
17089
  }
16617
17090
 
16618
17091
  // lib/models/rectangularbar/register.tsx
16619
- var model78 = defineModelRenderer({
17092
+ var model81 = defineModelRenderer({
16620
17093
  name: "rectangularbar",
16621
17094
  schema: rectangularBarModelDefinitionSchema,
16622
17095
  render: ({ fn, ...props }) => /* @__PURE__ */ jsx(RectangularBar, { ...props }),
16623
17096
  pads: "none"
16624
17097
  });
16625
- function register78(registry2) {
16626
- registry2.register(model78);
17098
+ function register81(registry2) {
17099
+ registry2.register(model81);
16627
17100
  }
16628
17101
 
16629
17102
  // lib/models/rectangulargasket/geometry.ts
@@ -16637,7 +17110,7 @@ function retainCapSeams(mesh, tolerance) {
16637
17110
  const origin = positions.slice(a * 3, a * 3 + 3);
16638
17111
  const delta = positions.slice(b * 3, b * 3 + 3).map((x, axis) => x - origin[axis]);
16639
17112
  const lengthSquared = delta.reduce((sum, x) => sum + x * x, 0);
16640
- const length29 = Math.sqrt(lengthSquared);
17113
+ const length30 = Math.sqrt(lengthSquared);
16641
17114
  const intermediate = [];
16642
17115
  for (let id = 0; id < count; id++) {
16643
17116
  if (id === a || id === b) continue;
@@ -16646,7 +17119,7 @@ function retainCapSeams(mesh, tolerance) {
16646
17119
  (sum, x, axis) => sum + (x - origin[axis]) * delta[axis],
16647
17120
  0
16648
17121
  ) / lengthSquared;
16649
- if (t * length29 <= tolerance || (1 - t) * length29 <= tolerance) continue;
17122
+ if (t * length30 <= tolerance || (1 - t) * length30 <= tolerance) continue;
16650
17123
  if (Math.hypot(
16651
17124
  ...point.map((x, axis) => x - origin[axis] - t * delta[axis])
16652
17125
  ) <= tolerance)
@@ -16725,18 +17198,18 @@ function RectangularGasket({
16725
17198
  }
16726
17199
 
16727
17200
  // lib/models/rectangulargasket/register.tsx
16728
- var model79 = defineModelRenderer({
17201
+ var model82 = defineModelRenderer({
16729
17202
  name: "rectangulargasket",
16730
17203
  schema: rectangularGasketModelDefinitionSchema,
16731
17204
  render: ({ fn, ...props }) => /* @__PURE__ */ jsx(RectangularGasket, { ...props }),
16732
17205
  pads: "none"
16733
17206
  });
16734
- function register79(registry2) {
16735
- registry2.register(model79);
17207
+ function register82(registry2) {
17208
+ registry2.register(model82);
16736
17209
  }
16737
17210
 
16738
17211
  // lib/models/rectangulartube/geometry.ts
16739
- import jscad11 from "@jscad/modeling";
17212
+ import jscad12 from "@jscad/modeling";
16740
17213
  var {
16741
17214
  booleans: booleans2,
16742
17215
  primitives: primitives6,
@@ -16744,11 +17217,11 @@ var {
16744
17217
  geometries: geometries6,
16745
17218
  modifiers: modifiers6,
16746
17219
  measurements: measurements6
16747
- } = jscad11;
17220
+ } = jscad12;
16748
17221
  var generalize7 = modifiers6.generalize;
16749
17222
  var { subtract: subtract2 } = booleans2;
16750
17223
  var { rectangle: rectangle6, roundedRectangle: roundedRectangle6 } = primitives6;
16751
- var profile5 = (shape44, height10) => extrusions6.extrudeLinear({ height: height10 }, shape44);
17224
+ var profile5 = (shape46, height10) => extrusions6.extrudeLinear({ height: height10 }, shape46);
16752
17225
  var roundedRect2 = (width10, height10, radius) => radius ? roundedRectangle6({
16753
17226
  size: [width10, height10],
16754
17227
  roundRadius: radius,
@@ -16812,14 +17285,14 @@ function RectangularTube({
16812
17285
  }
16813
17286
 
16814
17287
  // lib/models/rectangulartube/register.tsx
16815
- var model80 = defineModelRenderer({
17288
+ var model83 = defineModelRenderer({
16816
17289
  name: "rectangulartube",
16817
17290
  schema: rectangularTubeModelDefinitionSchema,
16818
17291
  render: ({ fn, ...props }) => /* @__PURE__ */ jsx(RectangularTube, { ...props }),
16819
17292
  pads: "none"
16820
17293
  });
16821
- function register80(registry2) {
16822
- registry2.register(model80);
17294
+ function register83(registry2) {
17295
+ registry2.register(model83);
16823
17296
  }
16824
17297
 
16825
17298
  // lib/models/rigidcoupler/mesh.ts
@@ -16856,14 +17329,14 @@ function RigidCoupler({
16856
17329
  }
16857
17330
 
16858
17331
  // lib/models/rigidcoupler/register.tsx
16859
- var model81 = defineModelRenderer({
17332
+ var model84 = defineModelRenderer({
16860
17333
  name: "rigidcoupler",
16861
17334
  schema: rigidCouplerModelDefinitionSchema,
16862
17335
  render: ({ fn, ...props }) => /* @__PURE__ */ jsx(RigidCoupler, { ...props }),
16863
17336
  pads: "none"
16864
17337
  });
16865
- function register81(registry2) {
16866
- registry2.register(model81);
17338
+ function register84(registry2) {
17339
+ registry2.register(model84);
16867
17340
  }
16868
17341
 
16869
17342
  // lib/models/setscrew/mesh.ts
@@ -16978,14 +17451,14 @@ function SetScrew({ color = "#737e8f", ...props }) {
16978
17451
  }
16979
17452
 
16980
17453
  // lib/models/setscrew/register.tsx
16981
- var model82 = defineModelRenderer({
17454
+ var model85 = defineModelRenderer({
16982
17455
  name: "setscrew",
16983
17456
  schema: setscrewModelDefinitionSchema,
16984
17457
  render: ({ fn, ...props }) => /* @__PURE__ */ jsx(SetScrew, { ...props }),
16985
17458
  pads: "none"
16986
17459
  });
16987
- function register82(registry2) {
16988
- registry2.register(model82);
17460
+ function register85(registry2) {
17461
+ registry2.register(model85);
16989
17462
  }
16990
17463
 
16991
17464
  // lib/models/shaftcollar/mesh.ts
@@ -17017,14 +17490,14 @@ function ShaftCollar({ color = "#737e8f", ...props }) {
17017
17490
  }
17018
17491
 
17019
17492
  // lib/models/shaftcollar/register.tsx
17020
- var model83 = defineModelRenderer({
17493
+ var model86 = defineModelRenderer({
17021
17494
  name: "shaftcollar",
17022
17495
  schema: shaftCollarModelDefinitionSchema,
17023
17496
  render: ({ fn, ...props }) => /* @__PURE__ */ jsx(ShaftCollar, { ...props }),
17024
17497
  pads: "none"
17025
17498
  });
17026
- function register83(registry2) {
17027
- registry2.register(model83);
17499
+ function register86(registry2) {
17500
+ registry2.register(model86);
17028
17501
  }
17029
17502
 
17030
17503
  // lib/mechanical/sheet-metal-mesh.ts
@@ -17069,7 +17542,7 @@ function createSheetMetalMesh(input) {
17069
17542
  throw new Error(`No ${hole.panel} panel on ${profile6}`);
17070
17543
  }
17071
17544
  for (const panel of panels) {
17072
- const length29 = panel === "base" ? baseLength : flangeHeight;
17545
+ const length30 = panel === "base" ? baseLength : flangeHeight;
17073
17546
  const holes = props.holes.filter((hole) => hole.panel === panel).map(holeOutline);
17074
17547
  const bounds = holes.map((outline2) => ({
17075
17548
  minU: Math.min(...outline2.map((p) => p.u)),
@@ -17078,17 +17551,17 @@ function createSheetMetalMesh(input) {
17078
17551
  maxV: Math.max(...outline2.map((p) => p.v))
17079
17552
  }));
17080
17553
  for (const [i, box] of bounds.entries()) {
17081
- if (box.minU <= -length29 / 2 || box.maxU >= length29 / 2 || box.minV <= -width10 / 2 || box.maxV >= width10 / 2)
17554
+ if (box.minU <= -length30 / 2 || box.maxU >= length30 / 2 || box.minV <= -width10 / 2 || box.maxV >= width10 / 2)
17082
17555
  throw new Error(`Hole crosses ${panel} panel edge or bend tangent`);
17083
17556
  for (const previous of bounds.slice(0, i))
17084
17557
  if (box.minU <= previous.maxU && box.maxU >= previous.minU && box.minV <= previous.maxV && box.maxV >= previous.minV)
17085
17558
  throw new Error("Hole bounding boxes must not overlap");
17086
17559
  }
17087
17560
  const outline = [
17088
- { u: -length29 / 2, v: -width10 / 2 },
17089
- { u: length29 / 2, v: -width10 / 2 },
17090
- { u: length29 / 2, v: width10 / 2 },
17091
- { u: -length29 / 2, v: width10 / 2 }
17561
+ { u: -length30 / 2, v: -width10 / 2 },
17562
+ { u: length30 / 2, v: -width10 / 2 },
17563
+ { u: length30 / 2, v: width10 / 2 },
17564
+ { u: -length30 / 2, v: width10 / 2 }
17092
17565
  ];
17093
17566
  const loops = [outline, ...holes.map((hole) => [...hole].reverse())];
17094
17567
  const points = loops.flat();
@@ -17178,18 +17651,18 @@ function SheetMetal({ color = "#737e8f", ...props }) {
17178
17651
  }
17179
17652
 
17180
17653
  // lib/models/sheetmetal/register.tsx
17181
- var model84 = defineModelRenderer({
17654
+ var model87 = defineModelRenderer({
17182
17655
  name: "sheetmetal",
17183
17656
  schema: sheetMetalModelDefinitionSchema,
17184
17657
  render: ({ fn, ...props }) => /* @__PURE__ */ jsx(SheetMetal, { ...props }),
17185
17658
  pads: "none"
17186
17659
  });
17187
- function register84(registry2) {
17188
- registry2.register(model84);
17660
+ function register87(registry2) {
17661
+ registry2.register(model87);
17189
17662
  }
17190
17663
 
17191
17664
  // lib/models/slottedchannel/mesh.ts
17192
- function quarterBend(radius, thickness) {
17665
+ function quarterBend2(radius, thickness) {
17193
17666
  const outer = radius + thickness;
17194
17667
  const center = outer;
17195
17668
  const points = [];
@@ -17215,9 +17688,9 @@ function quarterBend(radius, thickness) {
17215
17688
  }
17216
17689
  return points;
17217
17690
  }
17218
- function obround(center, width10, length29) {
17219
- if (length29 === width10) return circularProfile(0, center, width10 / 2);
17220
- const r = width10 / 2, straight = (length29 - width10) / 2;
17691
+ function obround(center, width10, length30) {
17692
+ if (length30 === width10) return circularProfile(0, center, width10 / 2);
17693
+ const r = width10 / 2, straight = (length30 - width10) / 2;
17221
17694
  const points = [];
17222
17695
  for (let step = 0; step <= 48; step++) {
17223
17696
  const angle = step * Math.PI / 48;
@@ -17254,7 +17727,7 @@ function createSlottedChannelMesh(input) {
17254
17727
  [h2, l],
17255
17728
  [tangent, l]
17256
17729
  ];
17257
- const bend = quarterBend(r, t);
17730
+ const bend = quarterBend2(r, t);
17258
17731
  const mesh = joinProfileMeshes([
17259
17732
  extrudePlanarProfile({
17260
17733
  outer: [
@@ -17317,14 +17790,14 @@ function SlottedChannel({
17317
17790
  }
17318
17791
 
17319
17792
  // lib/models/slottedchannel/register.tsx
17320
- var model85 = defineModelRenderer({
17793
+ var model88 = defineModelRenderer({
17321
17794
  name: "slottedchannel",
17322
17795
  schema: slottedChannelModelDefinitionSchema,
17323
17796
  render: ({ fn, ...props }) => /* @__PURE__ */ jsx(SlottedChannel, { ...props }),
17324
17797
  pads: "none"
17325
17798
  });
17326
- function register85(registry2) {
17327
- registry2.register(model85);
17799
+ function register88(registry2) {
17800
+ registry2.register(model88);
17328
17801
  }
17329
17802
 
17330
17803
  // lib/models/spacer/mesh.ts
@@ -17347,14 +17820,14 @@ function Spacer({ color = "#a18450", ...props }) {
17347
17820
  }
17348
17821
 
17349
17822
  // lib/models/spacer/register.tsx
17350
- var model86 = defineModelRenderer({
17823
+ var model89 = defineModelRenderer({
17351
17824
  name: "spacer",
17352
17825
  schema: spacerModelDefinitionSchema,
17353
17826
  render: ({ fn, ...props }) => /* @__PURE__ */ jsx(Spacer, { ...props }),
17354
17827
  pads: "none"
17355
17828
  });
17356
- function register86(registry2) {
17357
- registry2.register(model86);
17829
+ function register89(registry2) {
17830
+ registry2.register(model89);
17358
17831
  }
17359
17832
 
17360
17833
  // lib/models/splitgrommet/geometry.ts
@@ -17436,14 +17909,14 @@ function SplitGrommet({
17436
17909
  }
17437
17910
 
17438
17911
  // lib/models/splitgrommet/register.tsx
17439
- var model87 = defineModelRenderer({
17912
+ var model90 = defineModelRenderer({
17440
17913
  name: "splitgrommet",
17441
17914
  schema: splitGrommetModelDefinitionSchema,
17442
17915
  render: ({ fn, ...props }) => /* @__PURE__ */ jsx(SplitGrommet, { ...props }),
17443
17916
  pads: "none"
17444
17917
  });
17445
- function register87(registry2) {
17446
- registry2.register(model87);
17918
+ function register90(registry2) {
17919
+ registry2.register(model90);
17447
17920
  }
17448
17921
 
17449
17922
  // lib/models/splitwasher/mesh.ts
@@ -17506,14 +17979,14 @@ function SplitWasher({ color = "#929ba6", ...props }) {
17506
17979
  }
17507
17980
 
17508
17981
  // lib/models/splitwasher/register.tsx
17509
- var model88 = defineModelRenderer({
17982
+ var model91 = defineModelRenderer({
17510
17983
  name: "splitwasher",
17511
17984
  schema: splitWasherModelDefinitionSchema,
17512
17985
  render: ({ fn, ...props }) => /* @__PURE__ */ jsx(SplitWasher, { ...props }),
17513
17986
  pads: "none"
17514
17987
  });
17515
- function register88(registry2) {
17516
- registry2.register(model88);
17988
+ function register91(registry2) {
17989
+ registry2.register(model91);
17517
17990
  }
17518
17991
 
17519
17992
  // lib/SpurGear.tsx
@@ -17525,14 +17998,14 @@ function SpurGear({ color = "#737e8f", ...props }) {
17525
17998
  }
17526
17999
 
17527
18000
  // lib/models/spurgear/register.tsx
17528
- var model89 = defineModelRenderer({
18001
+ var model92 = defineModelRenderer({
17529
18002
  name: "spurgear",
17530
18003
  schema: spurGearModelDefinitionSchema,
17531
18004
  render: ({ fn, ...props }) => /* @__PURE__ */ jsx(SpurGear, { ...props }),
17532
18005
  pads: "none"
17533
18006
  });
17534
- function register89(registry2) {
17535
- registry2.register(model89);
18007
+ function register92(registry2) {
18008
+ registry2.register(model92);
17536
18009
  }
17537
18010
 
17538
18011
  // lib/models/threadedrod/mesh.ts
@@ -17622,14 +18095,14 @@ function ThreadedRod({ color = "#737e8f", ...props }) {
17622
18095
  }
17623
18096
 
17624
18097
  // lib/models/threadedrod/register.tsx
17625
- var model90 = defineModelRenderer({
18098
+ var model93 = defineModelRenderer({
17626
18099
  name: "threadedrod",
17627
18100
  schema: threadedRodModelDefinitionSchema,
17628
18101
  render: ({ fn, ...props }) => /* @__PURE__ */ jsx(ThreadedRod, { ...props }),
17629
18102
  pads: "none"
17630
18103
  });
17631
- function register90(registry2) {
17632
- registry2.register(model90);
18104
+ function register93(registry2) {
18105
+ registry2.register(model93);
17633
18106
  }
17634
18107
 
17635
18108
  // lib/models/torsionspring/mesh.ts
@@ -17718,18 +18191,18 @@ function TorsionSpring({
17718
18191
  }
17719
18192
 
17720
18193
  // lib/models/torsionspring/register.tsx
17721
- var model91 = defineModelRenderer({
18194
+ var model94 = defineModelRenderer({
17722
18195
  name: "torsionspring",
17723
18196
  schema: torsionSpringModelDefinitionSchema,
17724
18197
  render: ({ fn, ...props }) => /* @__PURE__ */ jsx(TorsionSpring, { ...props }),
17725
18198
  pads: "none"
17726
18199
  });
17727
- function register91(registry2) {
17728
- registry2.register(model91);
18200
+ function register94(registry2) {
18201
+ registry2.register(model94);
17729
18202
  }
17730
18203
 
17731
18204
  // lib/models/tslotcoverstrip/geometry.ts
17732
- import jscad14 from "@jscad/modeling";
18205
+ import jscad15 from "@jscad/modeling";
17733
18206
  var {
17734
18207
  primitives: primitives7,
17735
18208
  extrusions: extrusions7,
@@ -17737,7 +18210,7 @@ var {
17737
18210
  geometries: geometries7,
17738
18211
  modifiers: modifiers7,
17739
18212
  measurements: measurements7
17740
- } = jscad14;
18213
+ } = jscad15;
17741
18214
  var generalize8 = modifiers7.generalize;
17742
18215
  function createTSlotCoverStripGeom(input) {
17743
18216
  const p = tSlotCoverStripModelPropsSchema.parse(input);
@@ -17808,20 +18281,20 @@ function TSlotCoverStrip({
17808
18281
  }
17809
18282
 
17810
18283
  // lib/models/tslotcoverstrip/register.tsx
17811
- var model92 = defineModelRenderer({
18284
+ var model95 = defineModelRenderer({
17812
18285
  name: "tslotcoverstrip",
17813
18286
  schema: tSlotCoverStripModelDefinitionSchema,
17814
18287
  render: ({ fn, ...props }) => /* @__PURE__ */ jsx(TSlotCoverStrip, { ...props }),
17815
18288
  pads: "none"
17816
18289
  });
17817
- function register92(registry2) {
17818
- registry2.register(model92);
18290
+ function register95(registry2) {
18291
+ registry2.register(model95);
17819
18292
  }
17820
18293
 
17821
18294
  // lib/models/tslotextrusion/mesh.ts
17822
18295
  function createTSlotExtrusionMesh(input = {}) {
17823
18296
  const props = tSlotExtrusionModelPropsSchema.parse(input);
17824
- const { width: width10, height: height10, length: length29, cornerRadius, lipThickness, pocketDepth } = props;
18297
+ const { width: width10, height: height10, length: length30, cornerRadius, lipThickness, pocketDepth } = props;
17825
18298
  const slot = props.slotWidth / 2;
17826
18299
  const pocket = props.pocketWidth / 2;
17827
18300
  const depth = lipThickness + pocketDepth;
@@ -17858,7 +18331,7 @@ function createTSlotExtrusionMesh(input = {}) {
17858
18331
  outer,
17859
18332
  holes: props.boreDiameter > 0 ? [circularProfile(0, 0, props.boreDiameter / 2)] : [],
17860
18333
  start: 0,
17861
- end: length29
18334
+ end: length30
17862
18335
  });
17863
18336
  }
17864
18337
 
@@ -17874,14 +18347,14 @@ function TSlotExtrusion({
17874
18347
  }
17875
18348
 
17876
18349
  // lib/models/tslotextrusion/register.tsx
17877
- var model93 = defineModelRenderer({
18350
+ var model96 = defineModelRenderer({
17878
18351
  name: "tslotextrusion",
17879
18352
  schema: tSlotExtrusionModelDefinitionSchema,
17880
18353
  render: ({ fn, ...props }) => /* @__PURE__ */ jsx(TSlotExtrusion, { ...props }),
17881
18354
  pads: "none"
17882
18355
  });
17883
- function register93(registry2) {
17884
- registry2.register(model93);
18356
+ function register96(registry2) {
18357
+ registry2.register(model96);
17885
18358
  }
17886
18359
 
17887
18360
  // lib/models/tslotgusset/mesh.ts
@@ -17927,14 +18400,14 @@ function TSlotGusset({ color = "#8995a3", ...props }) {
17927
18400
  }
17928
18401
 
17929
18402
  // lib/models/tslotgusset/register.tsx
17930
- var model94 = defineModelRenderer({
18403
+ var model97 = defineModelRenderer({
17931
18404
  name: "tslotgusset",
17932
18405
  schema: tSlotGussetModelDefinitionSchema,
17933
18406
  render: ({ fn, ...props }) => /* @__PURE__ */ jsx(TSlotGusset, { ...props }),
17934
18407
  pads: "none"
17935
18408
  });
17936
- function register94(registry2) {
17937
- registry2.register(model94);
18409
+ function register97(registry2) {
18410
+ registry2.register(model97);
17938
18411
  }
17939
18412
 
17940
18413
  // lib/models/tslotinsidecorner/mesh.ts
@@ -18008,14 +18481,124 @@ function TSlotInsideCorner({
18008
18481
  }
18009
18482
 
18010
18483
  // lib/models/tslotinsidecorner/register.tsx
18011
- var model95 = defineModelRenderer({
18484
+ var model98 = defineModelRenderer({
18012
18485
  name: "tslotinsidecorner",
18013
18486
  schema: tSlotInsideCornerModelDefinitionSchema,
18014
18487
  render: ({ fn, ...props }) => /* @__PURE__ */ jsx(TSlotInsideCorner, { ...props }),
18015
18488
  pads: "none"
18016
18489
  });
18017
- function register95(registry2) {
18018
- registry2.register(model95);
18490
+ function register98(registry2) {
18491
+ registry2.register(model98);
18492
+ }
18493
+
18494
+ // lib/models/ufl/geometry.ts
18495
+ import jscad16 from "@jscad/modeling";
18496
+ function createUflGeometries(input = {}) {
18497
+ const d = getUflDimensions(input);
18498
+ const { booleans: booleans4, primitives: primitives8 } = jscad16;
18499
+ const silver = "#bcbfc3";
18500
+ const dielectric = "#eee9d5";
18501
+ const gold = "#d9b45b";
18502
+ const plateThickness = 0.05;
18503
+ const shellHeight = d.height - d.baseHeight;
18504
+ const cylinder = (diameter, bottom, top) => primitives8.cylinder({
18505
+ radius: diameter / 2,
18506
+ height: top - bottom,
18507
+ center: [d.bodyCenterX, 0, (bottom + top) / 2],
18508
+ segments: 48
18509
+ });
18510
+ const terminal = (size, x, y) => primitives8.cuboid({ size, center: [x, y, d.terminalThickness / 2] });
18511
+ return [
18512
+ {
18513
+ geom: primitives8.cuboid({
18514
+ size: [d.baseWidth, d.baseLength, d.baseHeight - plateThickness],
18515
+ center: [d.bodyCenterX, 0, (d.baseHeight - plateThickness) / 2]
18516
+ }),
18517
+ color: dielectric
18518
+ },
18519
+ {
18520
+ geom: booleans4.subtract(
18521
+ primitives8.cuboid({
18522
+ size: [d.baseWidth, d.baseLength, plateThickness],
18523
+ center: [d.bodyCenterX, 0, d.baseHeight - plateThickness / 2]
18524
+ }),
18525
+ cylinder(d.shellInnerDiameter, 0, d.baseHeight + plateThickness)
18526
+ ),
18527
+ color: silver
18528
+ },
18529
+ {
18530
+ geom: booleans4.subtract(
18531
+ cylinder(
18532
+ d.shellOuterDiameter,
18533
+ d.baseHeight,
18534
+ d.baseHeight + shellHeight
18535
+ ),
18536
+ cylinder(
18537
+ d.shellInnerDiameter,
18538
+ d.baseHeight - plateThickness,
18539
+ d.height + plateThickness
18540
+ )
18541
+ ),
18542
+ color: silver
18543
+ },
18544
+ {
18545
+ geom: cylinder(d.shellInnerDiameter, d.baseHeight, d.dielectricHeight),
18546
+ color: dielectric
18547
+ },
18548
+ {
18549
+ geom: cylinder(d.centerPinDiameter, d.baseHeight, d.centerPinHeight),
18550
+ color: gold
18551
+ },
18552
+ {
18553
+ geom: terminal(
18554
+ [d.groundTerminalWidth, d.groundTerminalDepth, d.terminalThickness],
18555
+ d.groundTerminalX,
18556
+ d.groundTerminalY
18557
+ ),
18558
+ color: silver
18559
+ },
18560
+ {
18561
+ geom: terminal(
18562
+ [d.signalTerminalWidth, d.signalTerminalHeight, d.terminalThickness],
18563
+ d.signalTerminalX,
18564
+ 0
18565
+ ),
18566
+ color: gold
18567
+ },
18568
+ {
18569
+ geom: terminal(
18570
+ [d.groundTerminalWidth, d.groundTerminalDepth, d.terminalThickness],
18571
+ d.groundTerminalX,
18572
+ -d.groundTerminalY
18573
+ ),
18574
+ color: silver
18575
+ },
18576
+ {
18577
+ // Retention tab opposite the signal contact; not a fourth PCB terminal.
18578
+ geom: terminal(
18579
+ [d.rearTabWidth, d.rearTabHeight, d.terminalThickness],
18580
+ d.rearTabX,
18581
+ 0
18582
+ ),
18583
+ color: silver
18584
+ }
18585
+ ];
18586
+ }
18587
+
18588
+ // lib/models/ufl/Ufl.tsx
18589
+ function Ufl(props) {
18590
+ return /* @__PURE__ */ jsx(Fragment2, { children: createUflGeometries(props).map(({ geom, color }, index) => /* @__PURE__ */ jsx(Colorize, { color, children: /* @__PURE__ */ jsx(Custom, { geometry: geom }) }, index)) });
18591
+ }
18592
+
18593
+ // lib/models/ufl/register.tsx
18594
+ var model99 = defineModelRenderer({
18595
+ name: "ufl",
18596
+ schema: uflModelDefinitionSchema,
18597
+ render: ({ fn, ...props }) => /* @__PURE__ */ jsx(Ufl, { ...props }),
18598
+ pads: "footprinter"
18599
+ });
18600
+ function register99(registry2) {
18601
+ registry2.register(model99);
18019
18602
  }
18020
18603
 
18021
18604
  // lib/mechanical/worm-gear-mesh.ts
@@ -18200,14 +18783,14 @@ function WormGear({ color = "#737e8f", ...props }) {
18200
18783
  }
18201
18784
 
18202
18785
  // lib/models/wormgear/register.tsx
18203
- var model96 = defineModelRenderer({
18786
+ var model100 = defineModelRenderer({
18204
18787
  name: "wormgear",
18205
18788
  schema: wormGearModelDefinitionSchema,
18206
18789
  render: ({ fn, ...props }) => /* @__PURE__ */ jsx(WormGear, { ...props }),
18207
18790
  pads: "none"
18208
18791
  });
18209
- function register96(registry2) {
18210
- registry2.register(model96);
18792
+ function register100(registry2) {
18793
+ registry2.register(model100);
18211
18794
  }
18212
18795
 
18213
18796
  // lib/models/zeebar/mesh.ts
@@ -18278,20 +18861,18 @@ function ZeeBar({ color = "#8995a3", ...props }) {
18278
18861
  }
18279
18862
 
18280
18863
  // lib/models/zeebar/register.tsx
18281
- var model97 = defineModelRenderer({
18864
+ var model101 = defineModelRenderer({
18282
18865
  name: "zeebar",
18283
18866
  schema: zeeBarModelDefinitionSchema,
18284
18867
  render: ({ fn, ...props }) => /* @__PURE__ */ jsx(ZeeBar, { ...props }),
18285
18868
  pads: "none"
18286
18869
  });
18287
- function register97(registry2) {
18288
- registry2.register(model97);
18870
+ function register101(registry2) {
18871
+ registry2.register(model101);
18289
18872
  }
18290
18873
 
18291
18874
  // lib/generated/model-renderers.ts
18292
18875
  function registerAllModelRenderers(registry2) {
18293
- register50(registry2);
18294
- register51(registry2);
18295
18876
  register52(registry2);
18296
18877
  register53(registry2);
18297
18878
  register54(registry2);
@@ -18338,6 +18919,10 @@ function registerAllModelRenderers(registry2) {
18338
18919
  register95(registry2);
18339
18920
  register96(registry2);
18340
18921
  register97(registry2);
18922
+ register98(registry2);
18923
+ register99(registry2);
18924
+ register100(registry2);
18925
+ register101(registry2);
18341
18926
  }
18342
18927
 
18343
18928
  // lib/default-model-registry.ts
@@ -18679,7 +19264,7 @@ import { fp as fp10 } from "@tscircuit/footprinter";
18679
19264
  var ChipBody = ({
18680
19265
  center,
18681
19266
  width: width10,
18682
- length: length29,
19267
+ length: length30,
18683
19268
  height: height10,
18684
19269
  heightAboveSurface: heightAboveSurface2 = 0.15,
18685
19270
  color = "#555",
@@ -18696,24 +19281,24 @@ var ChipBody = ({
18696
19281
  }) => {
18697
19282
  const straightHeight = height10 * straightHeightRatio;
18698
19283
  const taperHeight = height10 - straightHeight;
18699
- const taperInset = Math.min(width10, length29) * taperRatio;
19284
+ const taperInset = Math.min(width10, length30) * taperRatio;
18700
19285
  const faceWidth = Math.max(width10 - taperInset, width10 * faceRatio);
18701
- const faceLength = Math.max(length29 - taperInset, length29 * faceRatio);
18702
- const defaultNotchRadius = Math.min(width10, length29) * 0.12;
19286
+ const faceLength = Math.max(length30 - taperInset, length30 * faceRatio);
19287
+ const defaultNotchRadius = Math.min(width10, length30) * 0.12;
18703
19288
  const actualNotchRadius = notchRadius ?? defaultNotchRadius;
18704
19289
  const defaultNotchPosition = {
18705
19290
  x: 0,
18706
- y: length29 / 2 - actualNotchRadius * 0.25,
19291
+ y: length30 / 2 - actualNotchRadius * 0.25,
18707
19292
  z: height10
18708
19293
  };
18709
19294
  const actualNotchPosition = notchPosition ?? defaultNotchPosition;
18710
19295
  const body = /* @__PURE__ */ jsxs(Union, { children: [
18711
19296
  /* @__PURE__ */ jsxs(Hull, { children: [
18712
19297
  /* @__PURE__ */ jsx(Translate, { z: 5e-3, children: /* @__PURE__ */ jsx(Cuboid, { size: [faceWidth, faceLength, 0.01] }) }),
18713
- /* @__PURE__ */ jsx(Translate, { z: straightHeight, children: /* @__PURE__ */ jsx(Cuboid, { size: [width10, length29, 0.01] }) })
19298
+ /* @__PURE__ */ jsx(Translate, { z: straightHeight, children: /* @__PURE__ */ jsx(Cuboid, { size: [width10, length30, 0.01] }) })
18714
19299
  ] }),
18715
19300
  /* @__PURE__ */ jsxs(Hull, { children: [
18716
- /* @__PURE__ */ jsx(Translate, { z: straightHeight, children: /* @__PURE__ */ jsx(Cuboid, { size: [width10, length29, 0.01] }) }),
19301
+ /* @__PURE__ */ jsx(Translate, { z: straightHeight, children: /* @__PURE__ */ jsx(Cuboid, { size: [width10, length30, 0.01] }) }),
18717
19302
  /* @__PURE__ */ jsx(Translate, { z: straightHeight + taperHeight, children: /* @__PURE__ */ jsx(Cuboid, { size: [faceWidth, faceLength, 0.01] }) })
18718
19303
  ] })
18719
19304
  ] });
@@ -18730,7 +19315,7 @@ var ChipBody = ({
18730
19315
  let finalBody = body;
18731
19316
  if (chamferSize > 0) {
18732
19317
  const xOffset = width10 / 2;
18733
- const yOffset = length29 / 2;
19318
+ const yOffset = length30 / 2;
18734
19319
  finalBody = /* @__PURE__ */ jsxs(Subtract, { children: [
18735
19320
  body,
18736
19321
  chamferCutout(xOffset, yOffset),
@@ -18760,8 +19345,8 @@ function getExpandedStroke(strokeInput, width10) {
18760
19345
  function getNormal(p1, p2) {
18761
19346
  const dx = p2.x - p1.x;
18762
19347
  const dy = p2.y - p1.y;
18763
- const length29 = Math.sqrt(dx * dx + dy * dy);
18764
- return { x: -dy / length29, y: dx / length29 };
19348
+ const length30 = Math.sqrt(dx * dx + dy * dy);
19349
+ return { x: -dy / length30, y: dx / length30 };
18765
19350
  }
18766
19351
  function addPoint(point, normal, factor) {
18767
19352
  const newPoint = {
@@ -20429,11 +21014,11 @@ var FemaleHeaderRow = ({
20429
21014
  // lib/PushButton.tsx
20430
21015
  var PushButton = ({
20431
21016
  width: width10,
20432
- length: length29,
21017
+ length: length30,
20433
21018
  innerDiameter = 1
20434
21019
  }) => {
20435
21020
  const bodyWidth = width10;
20436
- const bodyLength10 = length29;
21021
+ const bodyLength10 = length30;
20437
21022
  const bodyHeight = width10 * 0.7;
20438
21023
  const legWidth = innerDiameter / 2.5;
20439
21024
  return /* @__PURE__ */ jsxs(Fragment2, { children: [
@@ -24367,12 +24952,12 @@ var JstSh = ({ footprint = "jst6_sh" }) => {
24367
24952
  };
24368
24953
 
24369
24954
  // lib/Crystal.tsx
24370
- var getTerminalPoints = ([centerX, centerY], width10, length29, chamfer, isPinOne) => {
24955
+ var getTerminalPoints = ([centerX, centerY], width10, length30, chamfer, isPinOne) => {
24371
24956
  const xDirection = Math.sign(centerX);
24372
24957
  const yDirection = Math.sign(centerY);
24373
24958
  const halfWidth = width10 / 2;
24374
- const halfLength = length29 / 2;
24375
- const innerChamfer = isPinOne ? Math.min(0.32, length29 * 0.36) : 0;
24959
+ const halfLength = length30 / 2;
24960
+ const innerChamfer = isPinOne ? Math.min(0.32, length30 * 0.36) : 0;
24376
24961
  const outerChamfer = Math.min(chamfer, halfWidth, halfLength);
24377
24962
  const points = [
24378
24963
  [-halfWidth, -halfLength],
@@ -24392,13 +24977,13 @@ var getTerminalPoints = ([centerX, centerY], width10, length29, chamfer, isPinOn
24392
24977
  };
24393
24978
  var getRoundedRectProfile = ({
24394
24979
  width: width10,
24395
- length: length29,
24980
+ length: length30,
24396
24981
  radius,
24397
24982
  height: height10,
24398
24983
  z
24399
24984
  }) => {
24400
24985
  const x = width10 / 2 - radius;
24401
- const y = length29 / 2 - radius;
24986
+ const y = length30 / 2 - radius;
24402
24987
  return [
24403
24988
  [-x, -y],
24404
24989
  [x, -y],
@@ -24542,12 +25127,12 @@ var FPC = ({
24542
25127
  const contactRows = Array.from({ length: pinCount }, (_, index) => {
24543
25128
  const isUpperRow = staggered && index % 2 === 1 !== reverse;
24544
25129
  const y = staggered ? isUpperRow ? rowPitch / 2 : -rowPitch / 2 : 0;
24545
- const length29 = isUpperRow ? topPadLength : bottomPadLength;
25130
+ const length30 = isUpperRow ? topPadLength : bottomPadLength;
24546
25131
  return {
24547
25132
  index,
24548
25133
  x: contactStartX + index * pitch,
24549
25134
  y,
24550
- length: length29
25135
+ length: length30
24551
25136
  };
24552
25137
  });
24553
25138
  const contactMaxY = Math.max(
@@ -25099,7 +25684,7 @@ var Led2835 = ({
25099
25684
  };
25100
25685
 
25101
25686
  // lib/RJ45.tsx
25102
- var range2 = (length29) => Array.from({ length: length29 }, (_, index) => index);
25687
+ var range2 = (length30) => Array.from({ length: length30 }, (_, index) => index);
25103
25688
  var RJ45 = ({
25104
25689
  bodyWidth = 16.26,
25105
25690
  bodyDepth = 15.88,
@@ -25919,10 +26504,10 @@ var SOT143 = ({ footprint = "sot143" }) => {
25919
26504
  var Footprinter3d = ({ footprint }) => {
25920
26505
  const modelFn = mp.string(footprint.split("_", 1)[0]).params().fn;
25921
26506
  if (mp.getModelNames().includes(modelFn)) {
25922
- const model98 = mp.string(footprint).json();
25923
- const renderer = modelRendererRegistry.get(model98.fn);
26507
+ const model102 = mp.string(footprint).json();
26508
+ const renderer = modelRendererRegistry.get(model102.fn);
25924
26509
  if (renderer) {
25925
- return renderer.render(model98);
26510
+ return renderer.render(model102);
25926
26511
  }
25927
26512
  }
25928
26513
  let normalizedFootprint = footprint;
@@ -26755,8 +27340,8 @@ function renderNode(node, colorCtx, renderCtx) {
26755
27340
  }
26756
27341
  return (children ?? []).flatMap((c) => renderNode(c, colorCtx, renderCtx));
26757
27342
  }
26758
- function render(root, jscad15) {
26759
- const geometries8 = renderNode(root, void 0, { jscad: jscad15 });
27343
+ function render(root, jscad17) {
27344
+ const geometries8 = renderNode(root, void 0, { jscad: jscad17 });
26760
27345
  return {
26761
27346
  geometries: geometries8.map(
26762
27347
  (entry) => entry.material ? { ...entry, geom: { ...entry.geom, material: entry.material } } : entry
@@ -26848,24 +27433,24 @@ function convertCSGToThreeGeom(csg) {
26848
27433
  }
26849
27434
 
26850
27435
  // lib/vanilla/index.ts
26851
- function getJscadModelForFootprint(footprint, jscad15) {
27436
+ function getJscadModelForFootprint(footprint, jscad17) {
26852
27437
  const vnode = h(Footprinter3d, { footprint });
26853
- return render(vnode, jscad15);
27438
+ return render(vnode, jscad17);
26854
27439
  }
26855
- function getJscadModelForFootprintWithPads(footprint, jscad15) {
27440
+ function getJscadModelForFootprintWithPads(footprint, jscad17) {
26856
27441
  const vnode = h(
26857
27442
  Fragment,
26858
27443
  {},
26859
27444
  h(Footprinter3d, { footprint }),
26860
27445
  h(ExtrudedPads, { footprint })
26861
27446
  );
26862
- return render(vnode, jscad15);
27447
+ return render(vnode, jscad17);
26863
27448
  }
26864
- function createJSCADRenderer(jscad15) {
27449
+ function createJSCADRenderer(jscad17) {
26865
27450
  function createJSCADRoot(container) {
26866
27451
  return {
26867
27452
  render(element) {
26868
- const { geometries: geometries8 } = render(element, jscad15);
27453
+ const { geometries: geometries8 } = render(element, jscad17);
26869
27454
  container.splice(0, container.length, ...geometries8);
26870
27455
  }
26871
27456
  };
@@ -26897,10 +27482,12 @@ export {
26897
27482
  MaleFemaleStandoff,
26898
27483
  NEMA17,
26899
27484
  NEMA23,
27485
+ NEMA34,
26900
27486
  NEMA8,
26901
27487
  NemaMotor,
26902
27488
  NylonLockNut,
26903
27489
  PanScrew,
27490
+ PerforatedAngle,
26904
27491
  PerforatedSheet,
26905
27492
  PlainBushing,
26906
27493
  PushFitPlug,
@@ -26922,6 +27509,7 @@ export {
26922
27509
  TSlotInsideCorner,
26923
27510
  ThreadedRod,
26924
27511
  TorsionSpring,
27512
+ Ufl,
26925
27513
  WormGear,
26926
27514
  ZeeBar,
26927
27515
  convertCSGToThreeGeom,
@@ -26974,6 +27562,8 @@ export {
26974
27562
  createNylonLockNutMeshes,
26975
27563
  createPanScrewGeom,
26976
27564
  createPanScrewMesh,
27565
+ createPerforatedAngleGeom,
27566
+ createPerforatedAngleMesh,
26977
27567
  createPerforatedSheetGeom,
26978
27568
  createPerforatedSheetMesh,
26979
27569
  createPlainBushingGeom,
@@ -27016,6 +27606,7 @@ export {
27016
27606
  createThreadedRodMesh,
27017
27607
  createTorsionSpringGeom,
27018
27608
  createTorsionSpringMesh,
27609
+ createUflGeometries,
27019
27610
  createWormGearGeom,
27020
27611
  createWormGearMesh,
27021
27612
  createZeeBarGeom,