jscad-electronics 0.0.209 → 0.0.211

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/cables.d.ts CHANGED
@@ -57,7 +57,7 @@ declare function createCableMeshes({ definition, path, radialSegments, startPin1
57
57
  definition: CableGeometryDefinition;
58
58
  path: CablePoint[];
59
59
  radialSegments?: number;
60
- /** Directions from connector center toward pin 1 (local -X), in circuit-world XYZ (+Z up), no translation. */
60
+ /** Connector center toward pin 1 (local -X), in right-handed world XYZ, +Z up; directions, no translation. */
61
61
  startPin1Side?: CablePoint;
62
62
  endPin1Side?: CablePoint;
63
63
  }): CableMesh[];
package/dist/cables.js CHANGED
@@ -574,6 +574,36 @@ function createConnectorMeshes({
574
574
  return meshes;
575
575
  }
576
576
 
577
+ // lib/cables/create-bundle-fanout-path.ts
578
+ function createBundleFanoutPath(path) {
579
+ const originalDistances = [0];
580
+ for (let index = 1; index < path.length; index++)
581
+ originalDistances.push(
582
+ originalDistances[index - 1] + Math.hypot(...subtract(path[index], path[index - 1]))
583
+ );
584
+ const length = originalDistances.at(-1);
585
+ const endLength = Math.min(20, length / 3);
586
+ const samples = [...originalDistances, length / 2];
587
+ for (let step = 0; step <= 10; step++) {
588
+ const distance = endLength * step / 10;
589
+ samples.push(distance, length - distance);
590
+ }
591
+ const distances = samples.sort((a, b) => a - b).filter(
592
+ (distance, index, sorted) => index === 0 || distance - sorted[index - 1] > 1e-9
593
+ );
594
+ let segment = 0;
595
+ const sampledPath = distances.map((distance) => {
596
+ while (segment < path.length - 2 && distance > originalDistances[segment + 1])
597
+ segment++;
598
+ const progress = (distance - originalDistances[segment]) / (originalDistances[segment + 1] - originalDistances[segment]);
599
+ return add(
600
+ path[segment],
601
+ scale(subtract(path[segment + 1], path[segment]), progress)
602
+ );
603
+ });
604
+ return { path: sampledPath, distances, length, endLength };
605
+ }
606
+
577
607
  // lib/cables/sweep-round-cable.ts
578
608
  function sweepRoundCable({
579
609
  frames,
@@ -662,7 +692,7 @@ function validateCableDefinition(definition) {
662
692
  connector.bodyWidth - (connector.bodyHeight + (pinCount - 1) * pitch)
663
693
  ) > 1e-6 || connector.contactDepth >= connector.bodyDepth || connector.contactDepth <= connector.diameter / 2)
664
694
  throw new Error("Bullet contact must fit inside its cylindrical body");
665
- if (pinCount === 1 && (definition.crossSection.kind !== "round_jacket" || definition.crossSection.diameter > connector.bodyHeight) || pinCount > 1 && (definition.crossSection.kind !== "wire_bundle" || definition.crossSection.wires.length !== pinCount || definition.crossSection.wirePitch !== pitch || definition.crossSection.wires.some(
695
+ if (pinCount === 1 && (definition.crossSection.kind !== "round_jacket" || definition.crossSection.diameter > connector.bodyHeight) || pinCount > 1 && (definition.crossSection.kind !== "wire_bundle" || definition.crossSection.wires.length !== pinCount || definition.crossSection.wires.some(
666
696
  (wire) => wire.diameter > connector.bodyHeight
667
697
  )))
668
698
  throw new Error(
@@ -688,6 +718,8 @@ function validateCableDefinition(definition) {
688
718
  for (const connector of [definition.connectorA, definition.connectorB]) {
689
719
  if (!("pinCount" in connector) || (connector.pinCount ?? 1) !== crossSection.wires.length)
690
720
  throw new Error("Bundle wire count must match connector contact count");
721
+ if ("pitch" in connector && crossSection.wires.some((wire) => wire.diameter > connector.pitch))
722
+ throw new Error("Insulated wires must fit each connector pitch");
691
723
  }
692
724
  }
693
725
  }
@@ -701,12 +733,13 @@ function createCableMeshes({
701
733
  validateCableDefinition(definition);
702
734
  if (!Number.isInteger(radialSegments) || radialSegments < 8 || radialSegments > 128)
703
735
  throw new Error("radialSegments must be an integer from 8 to 128");
704
- const frames = createCablePathFrames(path, {
705
- startPin1Side,
706
- endPin1Side
707
- });
736
+ const frames = createCablePathFrames(path, { startPin1Side, endPin1Side });
708
737
  const crossSection = definition.crossSection;
709
738
  const jacketDiameter = crossSection.kind === "round_jacket" ? crossSection.diameter : void 0;
739
+ const pitchA = "pitch" in definition.connectorA ? definition.connectorA.pitch : void 0;
740
+ const pitchB = "pitch" in definition.connectorB ? definition.connectorB.pitch : void 0;
741
+ const fanout = pitchA !== pitchB && crossSection.kind === "wire_bundle" ? createBundleFanoutPath(path) : void 0;
742
+ const fanoutFrames = fanout ? createCablePathFrames(fanout.path, { startPin1Side, endPin1Side }) : frames;
710
743
  const meshes = crossSection.kind === "round_jacket" ? [
711
744
  sweepRoundCable({
712
745
  frames,
@@ -715,16 +748,41 @@ function createCableMeshes({
715
748
  color: parseCableColor(crossSection.color),
716
749
  name: "jacket"
717
750
  })
718
- ] : crossSection.wires.map(
719
- (wire, index) => sweepRoundCable({
720
- frames,
751
+ ] : crossSection.wires.map((wire, index) => {
752
+ const contactOffset = index - (crossSection.wires.length - 1) / 2;
753
+ const compactPitch = Math.min(
754
+ crossSection.wirePitch,
755
+ pitchA ?? crossSection.wirePitch,
756
+ pitchB ?? crossSection.wirePitch,
757
+ 1.2 * Math.max(...crossSection.wires.map((wire2) => wire2.diameter))
758
+ );
759
+ const smoothstep = (progress) => progress * progress * (3 - 2 * progress);
760
+ const wireFrames = fanout ? createCablePathFrames(
761
+ fanoutFrames.map((frame, pathIndex) => {
762
+ const distance = fanout.distances[pathIndex];
763
+ const start = 1 - smoothstep(Math.min(1, distance / fanout.endLength));
764
+ const end = 1 - smoothstep(
765
+ Math.min(
766
+ 1,
767
+ (fanout.length - distance) / fanout.endLength
768
+ )
769
+ );
770
+ const pitch = compactPitch + ((pitchA ?? crossSection.wirePitch) - compactPitch) * start + ((pitchB ?? crossSection.wirePitch) - compactPitch) * end;
771
+ return add(
772
+ frame.point,
773
+ scale(frame.normal, contactOffset * pitch)
774
+ );
775
+ })
776
+ ) : frames;
777
+ return sweepRoundCable({
778
+ frames: wireFrames,
721
779
  diameter: wire.diameter,
722
- offset: (index - (crossSection.wires.length - 1) / 2) * crossSection.wirePitch,
780
+ offset: (fanout ? 0 : contactOffset) * crossSection.wirePitch,
723
781
  radialSegments,
724
782
  color: parseCableColor(wire.color),
725
783
  name: `wire-${index + 1}`
726
- })
727
- );
784
+ });
785
+ });
728
786
  for (const [index, connector] of [
729
787
  definition.connectorA,
730
788
  definition.connectorB
@@ -1 +1 @@
1
- {"version":3,"sources":["../lib/cables/bullet-meshes.ts","../lib/materials.ts","../lib/cables/geometry-to-mesh.ts","../lib/cables/path-frames.ts","../lib/cables/connector-meshes.ts","../lib/cables/sweep-round-cable.ts","../lib/cables/create-cable-meshes.ts"],"sourcesContent":["import jscad from \"@jscad/modeling\"\nimport { componentMaterials } from \"../materials\"\nimport { geometryToCableMesh } from \"./geometry-to-mesh\"\nimport type { CableConnectorSpec, CableMesh } from \"./types\"\n\n/** Right-handed connector-local mm: mating tip/mouth at z=0, +Z to wire exit.\n * Female socket is hollow; male contact has a rounded tip and spring slots.\n */\nexport function createBulletMeshes(\n connector: Extract<\n CableConnectorSpec,\n { kind: \"bullet_male\" | \"bullet_female\" }\n >,\n): CableMesh[] {\n const { cylinder, sphere, cuboid } = jscad.primitives\n const { subtract, union } = jscad.booleans\n const { diameter, contactDepth, bodyDepth, kind } = connector\n const bodyWidth = connector.bodyHeight\n const radius = diameter / 2\n let contact =\n kind === \"bullet_male\"\n ? union(\n sphere({ radius, center: [0, 0, radius], segments: 32 }),\n cylinder({\n radius,\n height: contactDepth - radius,\n center: [0, 0, (contactDepth + radius) / 2],\n segments: 32,\n }),\n )\n : subtract(\n cylinder({\n radius: bodyWidth / 2,\n height: contactDepth,\n center: [0, 0, contactDepth / 2],\n segments: 32,\n }),\n cylinder({\n radius,\n height: contactDepth - diameter / 4 + 0.1,\n center: [0, 0, (contactDepth - diameter / 4 - 0.1) / 2],\n segments: 32,\n }),\n )\n if (kind === \"bullet_male\") {\n contact = subtract(\n contact,\n cuboid({\n size: [diameter + 0.2, diameter * 0.08, contactDepth * 0.65],\n center: [0, 0, contactDepth * 0.45],\n }),\n cuboid({\n size: [diameter * 0.08, diameter + 0.2, contactDepth * 0.65],\n center: [0, 0, contactDepth * 0.45],\n }),\n )\n }\n const cupDepth = bodyDepth - contactDepth\n const solderCup = subtract(\n cylinder({\n radius: bodyWidth / 2,\n height: cupDepth,\n center: [0, 0, contactDepth + cupDepth / 2],\n segments: 32,\n }),\n cylinder({\n radius: radius * 0.75,\n height: cupDepth * 0.8 + 0.1,\n center: [0, 0, bodyDepth - cupDepth * 0.4 + 0.05],\n segments: 32,\n }),\n )\n const contactMeshes = [\n geometryToCableMesh({\n geometry: contact,\n material: componentMaterials.goldContact,\n color: [0.83, 0.64, 0.22, 1],\n name: kind === \"bullet_male\" ? \"bullet-pin\" : \"bullet-socket\",\n }),\n geometryToCableMesh({\n geometry: solderCup,\n material: componentMaterials.goldContact,\n color: [0.83, 0.64, 0.22, 1],\n name: \"solder-cup\",\n }),\n ]\n const pinCount = connector.pinCount ?? 1\n return Array.from({ length: pinCount }, (_, index) => {\n const offset = (index - (pinCount - 1) / 2) * (connector.pitch ?? bodyWidth)\n return contactMeshes.map((mesh) => ({\n ...mesh,\n name: pinCount === 1 ? mesh.name : `${mesh.name}-${index + 1}`,\n // Local +X is the cable frame's normal, paired with sweepRoundCable.offset.\n positions: mesh.positions.map((coordinate, coordinateIndex) =>\n coordinateIndex % 3 === 0 ? coordinate + offset : coordinate,\n ),\n }))\n }).flat()\n}\n","/** Approximate visual finishes, not measured optical properties. */\nexport const componentMaterials = {\n moldedPlastic: { metalness: 0, roughness: 0.7 },\n rubber: { metalness: 0, roughness: 0.9 },\n sleeve: { metalness: 0, roughness: 0.45 },\n tinnedLead: { metalness: 0.8, roughness: 0.55 },\n goldContact: { metalness: 1, roughness: 0.25 },\n copper: { metalness: 1, roughness: 0.35 },\n brushedMetal: { metalness: 1, roughness: 0.4 },\n steel: { metalness: 1, roughness: 0.25 },\n} as const\n","import jscad from \"@jscad/modeling\"\nimport type { Geom3 } from \"@jscad/modeling/src/geometries/geom3\"\nimport type { CableMesh, CableColor, CableFrame, CablePoint } from \"./types\"\nimport { add, scale } from \"./path-frames\"\n\ntype VertexKey = string\n\nexport function geometryToCableMesh({\n geometry,\n color,\n name,\n material,\n}: {\n geometry: Geom3\n color: CableColor\n name: string\n material?: CableMesh[\"material\"]\n}): CableMesh {\n const triangles = jscad.geometries.geom3.toPolygons(geometry)\n const positions: number[] = []\n const indices: number[] = []\n const vertices = new Map<VertexKey, number>()\n for (const triangle of triangles) {\n const polygonIndices: number[] = []\n for (const point of triangle.vertices) {\n const key = point.map((coordinate) => coordinate.toFixed(8)).join(\",\")\n let index = vertices.get(key)\n if (index === undefined) {\n index = positions.length / 3\n positions.push(...point)\n vertices.set(key, index)\n }\n polygonIndices.push(index)\n }\n // JSCAD CSG polygons are convex, so a fan preserves their outward winding.\n for (let side = 1; side < polygonIndices.length - 1; side++) {\n indices.push(\n polygonIndices[0]!,\n polygonIndices[side]!,\n polygonIndices[side + 1]!,\n )\n }\n }\n return { name, positions, indices, color, material, smooth: false }\n}\n\nexport function placeConnectorMesh({\n mesh,\n frame,\n wireExitDepth,\n isEnd,\n}: {\n mesh: CableMesh\n frame: CableFrame\n wireExitDepth: number\n isEnd: boolean\n}): CableMesh {\n const tangent = scale(frame.tangent, isEnd ? -1 : 1)\n const binormal: CablePoint = isEnd\n ? scale(frame.binormal, -1)\n : frame.binormal\n const origin = add(frame.point, scale(tangent, -wireExitDepth))\n const positions: number[] = []\n for (let index = 0; index < mesh.positions.length; index += 3) {\n positions.push(\n ...add(\n origin,\n add(\n add(\n scale(frame.normal, mesh.positions[index]!),\n scale(binormal, mesh.positions[index + 1]!),\n ),\n scale(tangent, mesh.positions[index + 2]!),\n ),\n ),\n )\n }\n return { ...mesh, positions }\n}\n","import type { CableFrame, CablePoint } from \"./types\"\n\nexport const add = (a: CablePoint, b: CablePoint): CablePoint => [\n a[0] + b[0],\n a[1] + b[1],\n a[2] + b[2],\n]\nexport const subtract = (a: CablePoint, b: CablePoint): CablePoint => [\n a[0] - b[0],\n a[1] - b[1],\n a[2] - b[2],\n]\nexport const scale = (point: CablePoint, factor: number): CablePoint => [\n point[0] * factor,\n point[1] * factor,\n point[2] * factor,\n]\nexport const dot = (a: CablePoint, b: CablePoint) =>\n a[0] * b[0] + a[1] * b[1] + a[2] * b[2]\nexport const cross = (a: CablePoint, b: CablePoint): CablePoint => [\n a[1] * b[2] - a[2] * b[1],\n a[2] * b[0] - a[0] * b[2],\n a[0] * b[1] - a[1] * b[0],\n]\nexport function normalize(point: CablePoint): CablePoint {\n const length = Math.hypot(...point)\n if (length < 1e-10)\n throw new Error(\n \"Cable path must not contain coincident points or a reversing tangent\",\n )\n return scale(point, 1 / length)\n}\n\n/** Pin 1 sides point from the connector center toward its first contact\n * (connector-local -X), expressed as directions (no\n * translation) in right-handed world XYZ, +Z up. Path points are mm in that\n * same frame. Parallel transport preserves legacy roll when no directions\n * are supplied; two constrained ends distribute twist by path arc length.\n */\nexport function createCablePathFrames(\n path: CablePoint[],\n {\n startPin1Side,\n endPin1Side,\n }: {\n startPin1Side?: CablePoint\n endPin1Side?: CablePoint\n } = {},\n): CableFrame[] {\n if (\n path.length < 2 ||\n path.some((point) => point.length !== 3 || !point.every(Number.isFinite))\n ) {\n throw new Error(\"Cable path needs at least two finite 3D points\")\n }\n const segments = path\n .slice(1)\n .map((point, index) => normalize(subtract(point, path[index]!)))\n const tangents = path.map((_, index) =>\n index === 0\n ? segments[0]!\n : index === path.length - 1\n ? segments.at(-1)!\n : normalize(add(segments[index - 1]!, segments[index]!)),\n )\n const initialUp: CablePoint =\n Math.abs(tangents[0]![2]) > 0.95 ? [0, 1, 0] : [0, 0, 1]\n const endpointNormal = (pin1Side: CablePoint, tangent: CablePoint) => {\n if (\n pin1Side.length !== 3 ||\n !pin1Side.every(Number.isFinite) ||\n Math.hypot(...pin1Side) < 1e-10\n )\n throw new Error(\"Connector pin 1 side must be a finite nonzero vector\")\n const normal = scale(normalize(pin1Side), -1)\n if (Math.abs(dot(normal, tangent)) > 1e-5)\n throw new Error(\n \"Connector pin 1 side must be perpendicular to its path tangent\",\n )\n return normalize(subtract(normal, scale(tangent, dot(normal, tangent))))\n }\n let normal = startPin1Side\n ? endpointNormal(startPin1Side, tangents[0]!)\n : normalize(cross(initialUp, tangents[0]!))\n const frames = tangents.map((tangent, index) => {\n if (index > 0) {\n const previousTangent = tangents[index - 1]!\n const axis = cross(previousTangent, tangent)\n const sine = Math.hypot(...axis)\n const cosine = Math.max(-1, Math.min(1, dot(previousTangent, tangent)))\n if (sine > 1e-10) {\n const unitAxis = scale(axis, 1 / sine)\n normal = normalize(\n add(\n add(scale(normal, cosine), scale(cross(unitAxis, normal), sine)),\n scale(unitAxis, dot(unitAxis, normal) * (1 - cosine)),\n ),\n )\n }\n }\n return {\n point: path[index]!,\n tangent,\n normal,\n binormal: normalize(cross(tangent, normal)),\n }\n })\n if (!endPin1Side) return frames\n const last = frames.at(-1)!\n const endNormal = endpointNormal(endPin1Side, last.tangent)\n const twist = Math.atan2(\n dot(last.tangent, cross(last.normal, endNormal)),\n dot(last.normal, endNormal),\n )\n const distances = [0]\n for (let index = 1; index < path.length; index++)\n distances.push(\n distances[index - 1]! +\n Math.hypot(...subtract(path[index]!, path[index - 1]!)),\n )\n return frames.map((frame, index) => {\n const angle =\n twist * (startPin1Side ? distances[index]! / distances.at(-1)! : 1)\n const normal = normalize(\n add(\n scale(frame.normal, Math.cos(angle)),\n scale(frame.binormal, Math.sin(angle)),\n ),\n )\n return {\n ...frame,\n normal,\n binormal: normalize(cross(frame.tangent, normal)),\n }\n })\n}\n","import { createBulletMeshes } from \"./bullet-meshes\"\nimport { componentMaterials } from \"../materials\"\nimport jscad from \"@jscad/modeling\"\nimport { geometryToCableMesh } from \"./geometry-to-mesh\"\nimport type {\n CableColor,\n CableConnectorSpec,\n CableMesh,\n CablePoint,\n} from \"./types\"\n\nconst { cuboid, roundedCuboid, cylinder, roundedRectangle, polygon, sphere } =\n jscad.primitives\nconst { extrudeLinear } = jscad.extrusions\nconst { translate, rotateY } = jscad.transforms\nconst { subtract, union } = jscad.booleans\nconst plastic: CableColor = [0.055, 0.07, 0.09, 1]\nconst housing: CableColor = [0.86, 0.84, 0.75, 1]\nconst metal: CableColor = [0.6, 0.64, 0.7, 1]\nconst brass: CableColor = [0.66, 0.46, 0.18, 1]\n\nexport function connectorWireExitDepth(connector: CableConnectorSpec): number {\n if (connector.kind === \"usb_c_plug\")\n return connector.shellDepth + connector.bodyDepth\n if (connector.kind === \"nema_5_15p\") return 19.05 + connector.bodyDepth\n return connector.bodyDepth\n}\n\nfunction createJstMeshes(\n connector: Extract<\n CableConnectorSpec,\n { kind: \"jst_sh_housing\" | \"jst_ph_housing\" }\n >,\n): CableMesh[] {\n const {\n bodyWidth: width,\n bodyHeight: height,\n bodyDepth: depth,\n pinCount,\n pitch,\n } = connector\n const opening = pitch === 1 ? 0.55 : 1.05\n const holes = Array.from({ length: pinCount }, (_, index) => {\n const x = (index - (pinCount - 1) / 2) * pitch\n return cuboid({\n size: [opening, opening * 1.35, depth - 0.6],\n center: [x, 0, (depth - 0.6) / 2 - 0.02],\n })\n })\n const backHoles = Array.from({ length: pinCount }, (_, index) =>\n cylinder({\n radius: pitch * 0.34,\n height: 1.3,\n segments: 16,\n center: [(index - (pinCount - 1) / 2) * pitch, 0, depth - 0.5],\n }),\n )\n const latchCut = cuboid({\n size: [width * 0.45, 0.5, depth * 0.5],\n center: [0, height / 2, depth * 0.65],\n })\n const body = subtract(\n roundedCuboid({\n size: [width, height, depth],\n center: [0, 0, depth / 2],\n roundRadius: 0.1,\n segments: 8,\n }),\n ...holes,\n ...backHoles,\n latchCut,\n ...Array.from({ length: pinCount }, (_, index) =>\n cuboid({\n size: [opening * 0.8, height * 0.7, depth * 0.24],\n center: [(index - (pinCount - 1) / 2) * pitch, height / 2, depth * 0.7],\n }),\n ),\n )\n const contacts = Array.from({ length: pinCount }, (_, index) => {\n const x = (index - (pinCount - 1) / 2) * pitch\n return geometryToCableMesh({\n material: componentMaterials.goldContact,\n name: `contact-${index + 1}`,\n color: metal,\n geometry: subtract(\n cuboid({\n size: [opening * 0.92, opening * 1.25, depth * 0.65],\n center: [x, 0, depth * 0.45],\n }),\n cuboid({\n size: [\n opening * 0.92 - 0.12,\n opening * 1.25 - 0.12,\n depth * 0.65 + 0.2,\n ],\n center: [x, 0, depth * 0.45],\n }),\n ),\n })\n })\n return [\n geometryToCableMesh({ geometry: body, color: housing, name: \"housing\" }),\n ...contacts,\n ]\n}\n\nfunction createUsbMeshes(\n connector: Extract<CableConnectorSpec, { kind: \"usb_c_plug\" }>,\n): CableMesh[] {\n const {\n shellWidth,\n shellHeight,\n shellDepth,\n bodyWidth,\n bodyHeight,\n bodyDepth,\n } = connector\n const shell = subtract(\n extrudeLinear(\n { height: shellDepth },\n roundedRectangle({\n size: [shellWidth, shellHeight],\n roundRadius: shellHeight / 2 - 0.02,\n segments: 32,\n }),\n ),\n translate(\n [0, 0, -0.1],\n extrudeLinear(\n { height: shellDepth + 0.2 },\n roundedRectangle({\n size: [shellWidth - 0.4, shellHeight - 0.4],\n roundRadius: (shellHeight - 0.4) / 2 - 0.02,\n segments: 32,\n }),\n ),\n ),\n )\n const liner = subtract(\n extrudeLinear(\n { height: shellDepth },\n roundedRectangle({\n size: [shellWidth - 0.41, shellHeight - 0.41],\n roundRadius: 0.85,\n segments: 32,\n }),\n ),\n translate(\n [0, 0, -0.1],\n extrudeLinear(\n { height: shellDepth - 0.3 },\n roundedRectangle({\n size: [shellWidth - 0.8, shellHeight - 0.8],\n roundRadius: 0.65,\n segments: 32,\n }),\n ),\n ),\n )\n const body = roundedCuboid({\n size: [bodyWidth, bodyHeight, bodyDepth],\n center: [0, 0, shellDepth + bodyDepth / 2],\n roundRadius: Math.min(1.3, bodyHeight / 4),\n segments: 16,\n })\n const contacts = Array.from({ length: 24 }, (_, index) =>\n cuboid({\n size: [0.22, 0.08, 3.5],\n center: [((index % 12) - 5.5) * 0.5, index < 12 ? 0.77 : -0.77, 2.6],\n }),\n )\n return [\n geometryToCableMesh({ geometry: body, color: plastic, name: \"overmold\" }),\n geometryToCableMesh({\n geometry: shell,\n color: metal,\n material: componentMaterials.brushedMetal,\n name: \"shell\",\n }),\n geometryToCableMesh({\n geometry: liner,\n color: [0.025, 0.026, 0.03, 1],\n name: \"liner\",\n }),\n ...contacts.map((geometry, index) =>\n geometryToCableMesh({\n geometry,\n color: brass,\n material: componentMaterials.goldContact,\n name: `contact-${index + 1}`,\n }),\n ),\n ]\n}\n\nfunction createMainsMeshes(connector: CableConnectorSpec): CableMesh[] {\n const { bodyWidth, bodyHeight, bodyDepth, kind } = connector\n const faceDepth = kind === \"nema_5_15p\" ? 19.05 : 0\n let body = roundedCuboid({\n size: [bodyWidth, bodyHeight, bodyDepth],\n center: [0, 0, faceDepth + bodyDepth / 2],\n roundRadius: 2,\n segments: 16,\n })\n if (kind === \"nema_5_15p\") {\n const blades = [-6.35, 6.35].map((x) => {\n const blade = cuboid({\n size: [1.524, 6.35, 15.875],\n center: [x, 2.7, 19.05 - 15.875 / 2],\n })\n const hole = translate(\n [x, 2.7, 7.3],\n rotateY(\n Math.PI / 2,\n cylinder({ radius: 1.1, height: 3, segments: 20 }),\n ),\n )\n return subtract(blade, hole)\n })\n const ground = union(\n cylinder({\n radius: 2.38125,\n height: 19.05 - 2.38125,\n center: [0, -9.20625, (19.05 + 2.38125) / 2],\n segments: 32,\n }),\n sphere({ radius: 2.38125, center: [0, -9.20625, 2.38125], segments: 32 }),\n )\n return [\n geometryToCableMesh({\n geometry: body,\n color: plastic,\n name: \"plug-body\",\n }),\n ...blades.map((geometry, index) =>\n geometryToCableMesh({\n geometry,\n color: brass,\n material: componentMaterials.goldContact,\n name: `blade-${index + 1}`,\n }),\n ),\n geometryToCableMesh({\n geometry: ground,\n color: brass,\n material: componentMaterials.goldContact,\n name: \"ground-pin\",\n }),\n ]\n }\n const recess = translate(\n [0, 0, -0.1],\n extrudeLinear(\n { height: 3.2 },\n polygon({\n points: [\n [-9, -6],\n [9, -6],\n [9, 2],\n [5, 6],\n [-5, 6],\n [-9, 2],\n ],\n }),\n ),\n )\n const sockets: CablePoint[] = [\n [-4.4, -1.8, 8],\n [4.4, -1.8, 8],\n [0, 3.1, 8],\n ]\n body = subtract(\n body,\n recess,\n ...sockets.map((center) => cuboid({ size: [2.3, 3.4, 16.2], center })),\n )\n return [\n geometryToCableMesh({\n geometry: body,\n color: plastic,\n name: \"appliance-body\",\n }),\n ...sockets.map(([x, y], index) =>\n geometryToCableMesh({\n geometry: cuboid({ size: [0.15, 2.8, 6], center: [x - 1.05, y, 7.8] }),\n color: brass,\n material: componentMaterials.goldContact,\n name: `socket-contact-${index + 1}`,\n }),\n ),\n ]\n}\n\nexport function createConnectorMeshes({\n connector,\n jacketDiameter,\n}: { connector: CableConnectorSpec; jacketDiameter?: number }): CableMesh[] {\n const meshes =\n connector.kind === \"usb_c_plug\"\n ? createUsbMeshes(connector)\n : connector.kind === \"bullet_male\" || connector.kind === \"bullet_female\"\n ? createBulletMeshes(connector)\n : connector.kind === \"jst_sh_housing\" ||\n connector.kind === \"jst_ph_housing\"\n ? createJstMeshes(connector)\n : createMainsMeshes(connector)\n if (\n jacketDiameter !== undefined &&\n connector.kind !== \"bullet_male\" &&\n connector.kind !== \"bullet_female\"\n ) {\n const exit = connectorWireExitDepth(connector)\n const boot = union(\n cylinder({\n radius: jacketDiameter / 2 + 0.15,\n height: 5,\n center: [0, 0, exit + 2.5],\n segments: 32,\n }),\n ...Array.from({ length: 7 }, (_, index) =>\n cylinder({\n radius: jacketDiameter / 2 + 0.8 - index * 0.06,\n height: 0.28,\n center: [0, 0, exit + 0.4 + index * 0.7],\n segments: 32,\n }),\n ),\n )\n meshes.push(\n geometryToCableMesh({\n geometry: boot,\n color: plastic,\n name: \"strain-relief\",\n }),\n )\n }\n return meshes\n}\n","import { add, scale } from \"./path-frames\"\nimport type { CableFrame, CableMesh, CableColor } from \"./types\"\n\n/** Closed indexed sweep around a supplied centerline; this does not choose a route. */\nexport function sweepRoundCable({\n frames,\n diameter,\n offset = 0,\n radialSegments,\n color,\n name,\n}: {\n frames: CableFrame[]\n diameter: number\n offset?: number\n radialSegments: number\n color: CableColor\n name: string\n}): CableMesh {\n const positions: number[] = []\n const indices: number[] = []\n for (const frame of frames) {\n const center = add(frame.point, scale(frame.normal, offset))\n for (let side = 0; side < radialSegments; side++) {\n const angle = (side * Math.PI * 2) / radialSegments\n positions.push(\n ...add(\n center,\n add(\n scale(frame.normal, (diameter * Math.cos(angle)) / 2),\n scale(frame.binormal, (diameter * Math.sin(angle)) / 2),\n ),\n ),\n )\n }\n }\n for (let ring = 0; ring < frames.length - 1; ring++) {\n for (let side = 0; side < radialSegments; side++) {\n const a = ring * radialSegments + side\n const b = ring * radialSegments + ((side + 1) % radialSegments)\n const c = a + radialSegments\n const d = b + radialSegments\n indices.push(a, b, c, b, d, c)\n }\n }\n const startCenter = positions.length / 3\n positions.push(...add(frames[0]!.point, scale(frames[0]!.normal, offset)))\n const endCenter = positions.length / 3\n positions.push(\n ...add(frames.at(-1)!.point, scale(frames.at(-1)!.normal, offset)),\n )\n const lastRing = (frames.length - 1) * radialSegments\n for (let side = 0; side < radialSegments; side++) {\n const next = (side + 1) % radialSegments\n indices.push(\n startCenter,\n next,\n side,\n endCenter,\n lastRing + side,\n lastRing + next,\n )\n }\n return { name, positions, indices, color, smooth: true }\n}\n","import {\n createConnectorMeshes,\n connectorWireExitDepth,\n} from \"./connector-meshes\"\nimport { placeConnectorMesh } from \"./geometry-to-mesh\"\nimport { createCablePathFrames } from \"./path-frames\"\nimport { sweepRoundCable } from \"./sweep-round-cable\"\nimport type {\n CableColor,\n CableGeometryDefinition,\n CableMesh,\n CablePoint,\n} from \"./types\"\n\nfunction parseCableColor(color: string): CableColor {\n if (!/^#[a-f\\d]{6}$/i.test(color))\n throw new Error(\"Cable colors must be six-digit hex strings\")\n return [\n parseInt(color.slice(1, 3), 16) / 255,\n parseInt(color.slice(3, 5), 16) / 255,\n parseInt(color.slice(5, 7), 16) / 255,\n 1,\n ]\n}\n\nfunction validateCableDefinition(definition: CableGeometryDefinition) {\n for (const connector of [definition.connectorA, definition.connectorB]) {\n const dimensions = [\n connector.bodyWidth,\n connector.bodyHeight,\n connector.bodyDepth,\n ]\n if (connector.kind === \"usb_c_plug\")\n dimensions.push(\n connector.shellWidth,\n connector.shellHeight,\n connector.shellDepth,\n )\n if (\n connector.kind === \"bullet_male\" ||\n connector.kind === \"bullet_female\"\n ) {\n const pinCount = connector.pinCount ?? 1\n const pitch = connector.pitch ?? connector.bodyHeight\n dimensions.push(connector.diameter, connector.contactDepth, pitch)\n if (\n !Number.isInteger(pinCount) ||\n pinCount < 1 ||\n pinCount > 16 ||\n connector.bodyHeight <= connector.diameter ||\n pitch < connector.bodyHeight ||\n Math.abs(\n connector.bodyWidth - (connector.bodyHeight + (pinCount - 1) * pitch),\n ) > 1e-6 ||\n connector.contactDepth >= connector.bodyDepth ||\n connector.contactDepth <= connector.diameter / 2\n )\n throw new Error(\"Bullet contact must fit inside its cylindrical body\")\n if (\n (pinCount === 1 &&\n (definition.crossSection.kind !== \"round_jacket\" ||\n definition.crossSection.diameter > connector.bodyHeight)) ||\n (pinCount > 1 &&\n (definition.crossSection.kind !== \"wire_bundle\" ||\n definition.crossSection.wires.length !== pinCount ||\n definition.crossSection.wirePitch !== pitch ||\n definition.crossSection.wires.some(\n (wire) => wire.diameter > connector.bodyHeight,\n )))\n )\n throw new Error(\n \"Bullet cables require one insulated wire per contact that fits its solder cup\",\n )\n }\n if (\n dimensions.some(\n (dimension) => !Number.isFinite(dimension) || dimension <= 0,\n )\n )\n throw new Error(\"Connector dimensions must be finite and positive\")\n if (\n (connector.kind === \"jst_sh_housing\" ||\n connector.kind === \"jst_ph_housing\") &&\n (!Number.isInteger(connector.pinCount) ||\n connector.pinCount < 2 ||\n !Number.isFinite(connector.pitch) ||\n connector.pitch <= 0)\n )\n throw new Error(\n \"JST connectors need a positive pitch and at least two contacts\",\n )\n }\n const crossSection = definition.crossSection\n const diameters =\n crossSection.kind === \"round_jacket\"\n ? [crossSection.diameter]\n : crossSection.wires.map((wire) => wire.diameter)\n if (\n diameters.length === 0 ||\n diameters.some((diameter) => !Number.isFinite(diameter) || diameter <= 0)\n )\n throw new Error(\"Cable diameters must be finite and positive\")\n if (crossSection.kind === \"wire_bundle\") {\n if (\n !Number.isFinite(crossSection.wirePitch) ||\n crossSection.wires.some((wire) => wire.diameter > crossSection.wirePitch)\n )\n throw new Error(\"Insulated bundle wires must not overlap\")\n for (const connector of [definition.connectorA, definition.connectorB]) {\n if (\n !(\"pinCount\" in connector) ||\n (connector.pinCount ?? 1) !== crossSection.wires.length\n )\n throw new Error(\"Bundle wire count must match connector contact count\")\n }\n }\n}\n\n/** Mesh generation only. Path samples are already resolved in world millimeters, +Z up. */\nexport function createCableMeshes({\n definition,\n path,\n radialSegments = 24,\n startPin1Side,\n endPin1Side,\n}: {\n definition: CableGeometryDefinition\n path: CablePoint[]\n radialSegments?: number\n /** Directions from connector center toward pin 1 (local -X), in circuit-world XYZ (+Z up), no translation. */\n startPin1Side?: CablePoint\n endPin1Side?: CablePoint\n}): CableMesh[] {\n validateCableDefinition(definition)\n if (\n !Number.isInteger(radialSegments) ||\n radialSegments < 8 ||\n radialSegments > 128\n )\n throw new Error(\"radialSegments must be an integer from 8 to 128\")\n const frames = createCablePathFrames(path, {\n startPin1Side,\n endPin1Side,\n })\n const crossSection = definition.crossSection\n const jacketDiameter =\n crossSection.kind === \"round_jacket\" ? crossSection.diameter : undefined\n const meshes =\n crossSection.kind === \"round_jacket\"\n ? [\n sweepRoundCable({\n frames,\n diameter: crossSection.diameter,\n radialSegments,\n color: parseCableColor(crossSection.color),\n name: \"jacket\",\n }),\n ]\n : crossSection.wires.map((wire, index) =>\n sweepRoundCable({\n frames,\n diameter: wire.diameter,\n offset:\n (index - (crossSection.wires.length - 1) / 2) *\n crossSection.wirePitch,\n radialSegments,\n color: parseCableColor(wire.color),\n name: `wire-${index + 1}`,\n }),\n )\n for (const [index, connector] of [\n definition.connectorA,\n definition.connectorB,\n ].entries()) {\n const frame = index === 0 ? frames[0]! : frames.at(-1)!\n const parts = createConnectorMeshes({ connector, jacketDiameter })\n meshes.push(\n ...parts.map((mesh) =>\n placeConnectorMesh({\n mesh: { ...mesh, name: `${index === 0 ? \"A\" : \"B\"}-${mesh.name}` },\n frame,\n isEnd: index === 1,\n wireExitDepth: connectorWireExitDepth(connector),\n }),\n ),\n )\n }\n return meshes\n}\n"],"mappings":"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","names":["jscad","normal","cylinder","sphere","cuboid","jscad","subtract","union","jscad","jscad","subtract"]}
1
+ {"version":3,"sources":["../lib/cables/bullet-meshes.ts","../lib/materials.ts","../lib/cables/geometry-to-mesh.ts","../lib/cables/path-frames.ts","../lib/cables/connector-meshes.ts","../lib/cables/create-bundle-fanout-path.ts","../lib/cables/sweep-round-cable.ts","../lib/cables/create-cable-meshes.ts"],"sourcesContent":["import jscad from \"@jscad/modeling\"\nimport { componentMaterials } from \"../materials\"\nimport { geometryToCableMesh } from \"./geometry-to-mesh\"\nimport type { CableConnectorSpec, CableMesh } from \"./types\"\n\n/** Right-handed connector-local mm: mating tip/mouth at z=0, +Z to wire exit.\n * Female socket is hollow; male contact has a rounded tip and spring slots.\n */\nexport function createBulletMeshes(\n connector: Extract<\n CableConnectorSpec,\n { kind: \"bullet_male\" | \"bullet_female\" }\n >,\n): CableMesh[] {\n const { cylinder, sphere, cuboid } = jscad.primitives\n const { subtract, union } = jscad.booleans\n const { diameter, contactDepth, bodyDepth, kind } = connector\n const bodyWidth = connector.bodyHeight\n const radius = diameter / 2\n let contact =\n kind === \"bullet_male\"\n ? union(\n sphere({ radius, center: [0, 0, radius], segments: 32 }),\n cylinder({\n radius,\n height: contactDepth - radius,\n center: [0, 0, (contactDepth + radius) / 2],\n segments: 32,\n }),\n )\n : subtract(\n cylinder({\n radius: bodyWidth / 2,\n height: contactDepth,\n center: [0, 0, contactDepth / 2],\n segments: 32,\n }),\n cylinder({\n radius,\n height: contactDepth - diameter / 4 + 0.1,\n center: [0, 0, (contactDepth - diameter / 4 - 0.1) / 2],\n segments: 32,\n }),\n )\n if (kind === \"bullet_male\") {\n contact = subtract(\n contact,\n cuboid({\n size: [diameter + 0.2, diameter * 0.08, contactDepth * 0.65],\n center: [0, 0, contactDepth * 0.45],\n }),\n cuboid({\n size: [diameter * 0.08, diameter + 0.2, contactDepth * 0.65],\n center: [0, 0, contactDepth * 0.45],\n }),\n )\n }\n const cupDepth = bodyDepth - contactDepth\n const solderCup = subtract(\n cylinder({\n radius: bodyWidth / 2,\n height: cupDepth,\n center: [0, 0, contactDepth + cupDepth / 2],\n segments: 32,\n }),\n cylinder({\n radius: radius * 0.75,\n height: cupDepth * 0.8 + 0.1,\n center: [0, 0, bodyDepth - cupDepth * 0.4 + 0.05],\n segments: 32,\n }),\n )\n const contactMeshes = [\n geometryToCableMesh({\n geometry: contact,\n material: componentMaterials.goldContact,\n color: [0.83, 0.64, 0.22, 1],\n name: kind === \"bullet_male\" ? \"bullet-pin\" : \"bullet-socket\",\n }),\n geometryToCableMesh({\n geometry: solderCup,\n material: componentMaterials.goldContact,\n color: [0.83, 0.64, 0.22, 1],\n name: \"solder-cup\",\n }),\n ]\n const pinCount = connector.pinCount ?? 1\n return Array.from({ length: pinCount }, (_, index) => {\n const offset = (index - (pinCount - 1) / 2) * (connector.pitch ?? bodyWidth)\n return contactMeshes.map((mesh) => ({\n ...mesh,\n name: pinCount === 1 ? mesh.name : `${mesh.name}-${index + 1}`,\n // Local +X is the cable frame's normal, paired with sweepRoundCable.offset.\n positions: mesh.positions.map((coordinate, coordinateIndex) =>\n coordinateIndex % 3 === 0 ? coordinate + offset : coordinate,\n ),\n }))\n }).flat()\n}\n","/** Approximate visual finishes, not measured optical properties. */\nexport const componentMaterials = {\n moldedPlastic: { metalness: 0, roughness: 0.7 },\n rubber: { metalness: 0, roughness: 0.9 },\n sleeve: { metalness: 0, roughness: 0.45 },\n tinnedLead: { metalness: 0.8, roughness: 0.55 },\n goldContact: { metalness: 1, roughness: 0.25 },\n copper: { metalness: 1, roughness: 0.35 },\n brushedMetal: { metalness: 1, roughness: 0.4 },\n steel: { metalness: 1, roughness: 0.25 },\n} as const\n","import jscad from \"@jscad/modeling\"\nimport type { Geom3 } from \"@jscad/modeling/src/geometries/geom3\"\nimport type { CableMesh, CableColor, CableFrame, CablePoint } from \"./types\"\nimport { add, scale } from \"./path-frames\"\n\ntype VertexKey = string\n\nexport function geometryToCableMesh({\n geometry,\n color,\n name,\n material,\n}: {\n geometry: Geom3\n color: CableColor\n name: string\n material?: CableMesh[\"material\"]\n}): CableMesh {\n const triangles = jscad.geometries.geom3.toPolygons(geometry)\n const positions: number[] = []\n const indices: number[] = []\n const vertices = new Map<VertexKey, number>()\n for (const triangle of triangles) {\n const polygonIndices: number[] = []\n for (const point of triangle.vertices) {\n const key = point.map((coordinate) => coordinate.toFixed(8)).join(\",\")\n let index = vertices.get(key)\n if (index === undefined) {\n index = positions.length / 3\n positions.push(...point)\n vertices.set(key, index)\n }\n polygonIndices.push(index)\n }\n // JSCAD CSG polygons are convex, so a fan preserves their outward winding.\n for (let side = 1; side < polygonIndices.length - 1; side++) {\n indices.push(\n polygonIndices[0]!,\n polygonIndices[side]!,\n polygonIndices[side + 1]!,\n )\n }\n }\n return { name, positions, indices, color, material, smooth: false }\n}\n\nexport function placeConnectorMesh({\n mesh,\n frame,\n wireExitDepth,\n isEnd,\n}: {\n mesh: CableMesh\n frame: CableFrame\n wireExitDepth: number\n isEnd: boolean\n}): CableMesh {\n const tangent = scale(frame.tangent, isEnd ? -1 : 1)\n const binormal: CablePoint = isEnd\n ? scale(frame.binormal, -1)\n : frame.binormal\n const origin = add(frame.point, scale(tangent, -wireExitDepth))\n const positions: number[] = []\n for (let index = 0; index < mesh.positions.length; index += 3) {\n positions.push(\n ...add(\n origin,\n add(\n add(\n scale(frame.normal, mesh.positions[index]!),\n scale(binormal, mesh.positions[index + 1]!),\n ),\n scale(tangent, mesh.positions[index + 2]!),\n ),\n ),\n )\n }\n return { ...mesh, positions }\n}\n","import type { CableFrame, CablePoint } from \"./types\"\n\nexport const add = (a: CablePoint, b: CablePoint): CablePoint => [\n a[0] + b[0],\n a[1] + b[1],\n a[2] + b[2],\n]\nexport const subtract = (a: CablePoint, b: CablePoint): CablePoint => [\n a[0] - b[0],\n a[1] - b[1],\n a[2] - b[2],\n]\nexport const scale = (point: CablePoint, factor: number): CablePoint => [\n point[0] * factor,\n point[1] * factor,\n point[2] * factor,\n]\nexport const dot = (a: CablePoint, b: CablePoint) =>\n a[0] * b[0] + a[1] * b[1] + a[2] * b[2]\nexport const cross = (a: CablePoint, b: CablePoint): CablePoint => [\n a[1] * b[2] - a[2] * b[1],\n a[2] * b[0] - a[0] * b[2],\n a[0] * b[1] - a[1] * b[0],\n]\nexport function normalize(point: CablePoint): CablePoint {\n const length = Math.hypot(...point)\n if (length < 1e-10)\n throw new Error(\n \"Cable path must not contain coincident points or a reversing tangent\",\n )\n return scale(point, 1 / length)\n}\n\n/** Pin 1 sides point from the connector center toward its first contact\n * (connector-local -X), expressed as directions (no\n * translation) in right-handed world XYZ, +Z up. Path points are mm in that\n * same frame. Parallel transport preserves legacy roll when no directions\n * are supplied; two constrained ends distribute twist by path arc length.\n */\nexport function createCablePathFrames(\n path: CablePoint[],\n {\n startPin1Side,\n endPin1Side,\n }: {\n startPin1Side?: CablePoint\n endPin1Side?: CablePoint\n } = {},\n): CableFrame[] {\n if (\n path.length < 2 ||\n path.some((point) => point.length !== 3 || !point.every(Number.isFinite))\n ) {\n throw new Error(\"Cable path needs at least two finite 3D points\")\n }\n const segments = path\n .slice(1)\n .map((point, index) => normalize(subtract(point, path[index]!)))\n const tangents = path.map((_, index) =>\n index === 0\n ? segments[0]!\n : index === path.length - 1\n ? segments.at(-1)!\n : normalize(add(segments[index - 1]!, segments[index]!)),\n )\n const initialUp: CablePoint =\n Math.abs(tangents[0]![2]) > 0.95 ? [0, 1, 0] : [0, 0, 1]\n const endpointNormal = (pin1Side: CablePoint, tangent: CablePoint) => {\n if (\n pin1Side.length !== 3 ||\n !pin1Side.every(Number.isFinite) ||\n Math.hypot(...pin1Side) < 1e-10\n )\n throw new Error(\"Connector pin 1 side must be a finite nonzero vector\")\n const normal = scale(normalize(pin1Side), -1)\n if (Math.abs(dot(normal, tangent)) > 1e-5)\n throw new Error(\n \"Connector pin 1 side must be perpendicular to its path tangent\",\n )\n return normalize(subtract(normal, scale(tangent, dot(normal, tangent))))\n }\n let normal = startPin1Side\n ? endpointNormal(startPin1Side, tangents[0]!)\n : normalize(cross(initialUp, tangents[0]!))\n const frames = tangents.map((tangent, index) => {\n if (index > 0) {\n const previousTangent = tangents[index - 1]!\n const axis = cross(previousTangent, tangent)\n const sine = Math.hypot(...axis)\n const cosine = Math.max(-1, Math.min(1, dot(previousTangent, tangent)))\n if (sine > 1e-10) {\n const unitAxis = scale(axis, 1 / sine)\n normal = normalize(\n add(\n add(scale(normal, cosine), scale(cross(unitAxis, normal), sine)),\n scale(unitAxis, dot(unitAxis, normal) * (1 - cosine)),\n ),\n )\n }\n }\n return {\n point: path[index]!,\n tangent,\n normal,\n binormal: normalize(cross(tangent, normal)),\n }\n })\n if (!endPin1Side) return frames\n const last = frames.at(-1)!\n const endNormal = endpointNormal(endPin1Side, last.tangent)\n const twist = Math.atan2(\n dot(last.tangent, cross(last.normal, endNormal)),\n dot(last.normal, endNormal),\n )\n const distances = [0]\n for (let index = 1; index < path.length; index++)\n distances.push(\n distances[index - 1]! +\n Math.hypot(...subtract(path[index]!, path[index - 1]!)),\n )\n return frames.map((frame, index) => {\n const angle =\n twist * (startPin1Side ? distances[index]! / distances.at(-1)! : 1)\n const normal = normalize(\n add(\n scale(frame.normal, Math.cos(angle)),\n scale(frame.binormal, Math.sin(angle)),\n ),\n )\n return {\n ...frame,\n normal,\n binormal: normalize(cross(frame.tangent, normal)),\n }\n })\n}\n","import { createBulletMeshes } from \"./bullet-meshes\"\nimport { componentMaterials } from \"../materials\"\nimport jscad from \"@jscad/modeling\"\nimport { geometryToCableMesh } from \"./geometry-to-mesh\"\nimport type {\n CableColor,\n CableConnectorSpec,\n CableMesh,\n CablePoint,\n} from \"./types\"\n\nconst { cuboid, roundedCuboid, cylinder, roundedRectangle, polygon, sphere } =\n jscad.primitives\nconst { extrudeLinear } = jscad.extrusions\nconst { translate, rotateY } = jscad.transforms\nconst { subtract, union } = jscad.booleans\nconst plastic: CableColor = [0.055, 0.07, 0.09, 1]\nconst housing: CableColor = [0.86, 0.84, 0.75, 1]\nconst metal: CableColor = [0.6, 0.64, 0.7, 1]\nconst brass: CableColor = [0.66, 0.46, 0.18, 1]\n\nexport function connectorWireExitDepth(connector: CableConnectorSpec): number {\n if (connector.kind === \"usb_c_plug\")\n return connector.shellDepth + connector.bodyDepth\n if (connector.kind === \"nema_5_15p\") return 19.05 + connector.bodyDepth\n return connector.bodyDepth\n}\n\nfunction createJstMeshes(\n connector: Extract<\n CableConnectorSpec,\n { kind: \"jst_sh_housing\" | \"jst_ph_housing\" }\n >,\n): CableMesh[] {\n const {\n bodyWidth: width,\n bodyHeight: height,\n bodyDepth: depth,\n pinCount,\n pitch,\n } = connector\n const opening = pitch === 1 ? 0.55 : 1.05\n const holes = Array.from({ length: pinCount }, (_, index) => {\n const x = (index - (pinCount - 1) / 2) * pitch\n return cuboid({\n size: [opening, opening * 1.35, depth - 0.6],\n center: [x, 0, (depth - 0.6) / 2 - 0.02],\n })\n })\n const backHoles = Array.from({ length: pinCount }, (_, index) =>\n cylinder({\n radius: pitch * 0.34,\n height: 1.3,\n segments: 16,\n center: [(index - (pinCount - 1) / 2) * pitch, 0, depth - 0.5],\n }),\n )\n const latchCut = cuboid({\n size: [width * 0.45, 0.5, depth * 0.5],\n center: [0, height / 2, depth * 0.65],\n })\n const body = subtract(\n roundedCuboid({\n size: [width, height, depth],\n center: [0, 0, depth / 2],\n roundRadius: 0.1,\n segments: 8,\n }),\n ...holes,\n ...backHoles,\n latchCut,\n ...Array.from({ length: pinCount }, (_, index) =>\n cuboid({\n size: [opening * 0.8, height * 0.7, depth * 0.24],\n center: [(index - (pinCount - 1) / 2) * pitch, height / 2, depth * 0.7],\n }),\n ),\n )\n const contacts = Array.from({ length: pinCount }, (_, index) => {\n const x = (index - (pinCount - 1) / 2) * pitch\n return geometryToCableMesh({\n material: componentMaterials.goldContact,\n name: `contact-${index + 1}`,\n color: metal,\n geometry: subtract(\n cuboid({\n size: [opening * 0.92, opening * 1.25, depth * 0.65],\n center: [x, 0, depth * 0.45],\n }),\n cuboid({\n size: [\n opening * 0.92 - 0.12,\n opening * 1.25 - 0.12,\n depth * 0.65 + 0.2,\n ],\n center: [x, 0, depth * 0.45],\n }),\n ),\n })\n })\n return [\n geometryToCableMesh({ geometry: body, color: housing, name: \"housing\" }),\n ...contacts,\n ]\n}\n\nfunction createUsbMeshes(\n connector: Extract<CableConnectorSpec, { kind: \"usb_c_plug\" }>,\n): CableMesh[] {\n const {\n shellWidth,\n shellHeight,\n shellDepth,\n bodyWidth,\n bodyHeight,\n bodyDepth,\n } = connector\n const shell = subtract(\n extrudeLinear(\n { height: shellDepth },\n roundedRectangle({\n size: [shellWidth, shellHeight],\n roundRadius: shellHeight / 2 - 0.02,\n segments: 32,\n }),\n ),\n translate(\n [0, 0, -0.1],\n extrudeLinear(\n { height: shellDepth + 0.2 },\n roundedRectangle({\n size: [shellWidth - 0.4, shellHeight - 0.4],\n roundRadius: (shellHeight - 0.4) / 2 - 0.02,\n segments: 32,\n }),\n ),\n ),\n )\n const liner = subtract(\n extrudeLinear(\n { height: shellDepth },\n roundedRectangle({\n size: [shellWidth - 0.41, shellHeight - 0.41],\n roundRadius: 0.85,\n segments: 32,\n }),\n ),\n translate(\n [0, 0, -0.1],\n extrudeLinear(\n { height: shellDepth - 0.3 },\n roundedRectangle({\n size: [shellWidth - 0.8, shellHeight - 0.8],\n roundRadius: 0.65,\n segments: 32,\n }),\n ),\n ),\n )\n const body = roundedCuboid({\n size: [bodyWidth, bodyHeight, bodyDepth],\n center: [0, 0, shellDepth + bodyDepth / 2],\n roundRadius: Math.min(1.3, bodyHeight / 4),\n segments: 16,\n })\n const contacts = Array.from({ length: 24 }, (_, index) =>\n cuboid({\n size: [0.22, 0.08, 3.5],\n center: [((index % 12) - 5.5) * 0.5, index < 12 ? 0.77 : -0.77, 2.6],\n }),\n )\n return [\n geometryToCableMesh({ geometry: body, color: plastic, name: \"overmold\" }),\n geometryToCableMesh({\n geometry: shell,\n color: metal,\n material: componentMaterials.brushedMetal,\n name: \"shell\",\n }),\n geometryToCableMesh({\n geometry: liner,\n color: [0.025, 0.026, 0.03, 1],\n name: \"liner\",\n }),\n ...contacts.map((geometry, index) =>\n geometryToCableMesh({\n geometry,\n color: brass,\n material: componentMaterials.goldContact,\n name: `contact-${index + 1}`,\n }),\n ),\n ]\n}\n\nfunction createMainsMeshes(connector: CableConnectorSpec): CableMesh[] {\n const { bodyWidth, bodyHeight, bodyDepth, kind } = connector\n const faceDepth = kind === \"nema_5_15p\" ? 19.05 : 0\n let body = roundedCuboid({\n size: [bodyWidth, bodyHeight, bodyDepth],\n center: [0, 0, faceDepth + bodyDepth / 2],\n roundRadius: 2,\n segments: 16,\n })\n if (kind === \"nema_5_15p\") {\n const blades = [-6.35, 6.35].map((x) => {\n const blade = cuboid({\n size: [1.524, 6.35, 15.875],\n center: [x, 2.7, 19.05 - 15.875 / 2],\n })\n const hole = translate(\n [x, 2.7, 7.3],\n rotateY(\n Math.PI / 2,\n cylinder({ radius: 1.1, height: 3, segments: 20 }),\n ),\n )\n return subtract(blade, hole)\n })\n const ground = union(\n cylinder({\n radius: 2.38125,\n height: 19.05 - 2.38125,\n center: [0, -9.20625, (19.05 + 2.38125) / 2],\n segments: 32,\n }),\n sphere({ radius: 2.38125, center: [0, -9.20625, 2.38125], segments: 32 }),\n )\n return [\n geometryToCableMesh({\n geometry: body,\n color: plastic,\n name: \"plug-body\",\n }),\n ...blades.map((geometry, index) =>\n geometryToCableMesh({\n geometry,\n color: brass,\n material: componentMaterials.goldContact,\n name: `blade-${index + 1}`,\n }),\n ),\n geometryToCableMesh({\n geometry: ground,\n color: brass,\n material: componentMaterials.goldContact,\n name: \"ground-pin\",\n }),\n ]\n }\n const recess = translate(\n [0, 0, -0.1],\n extrudeLinear(\n { height: 3.2 },\n polygon({\n points: [\n [-9, -6],\n [9, -6],\n [9, 2],\n [5, 6],\n [-5, 6],\n [-9, 2],\n ],\n }),\n ),\n )\n const sockets: CablePoint[] = [\n [-4.4, -1.8, 8],\n [4.4, -1.8, 8],\n [0, 3.1, 8],\n ]\n body = subtract(\n body,\n recess,\n ...sockets.map((center) => cuboid({ size: [2.3, 3.4, 16.2], center })),\n )\n return [\n geometryToCableMesh({\n geometry: body,\n color: plastic,\n name: \"appliance-body\",\n }),\n ...sockets.map(([x, y], index) =>\n geometryToCableMesh({\n geometry: cuboid({ size: [0.15, 2.8, 6], center: [x - 1.05, y, 7.8] }),\n color: brass,\n material: componentMaterials.goldContact,\n name: `socket-contact-${index + 1}`,\n }),\n ),\n ]\n}\n\nexport function createConnectorMeshes({\n connector,\n jacketDiameter,\n}: { connector: CableConnectorSpec; jacketDiameter?: number }): CableMesh[] {\n const meshes =\n connector.kind === \"usb_c_plug\"\n ? createUsbMeshes(connector)\n : connector.kind === \"bullet_male\" || connector.kind === \"bullet_female\"\n ? createBulletMeshes(connector)\n : connector.kind === \"jst_sh_housing\" ||\n connector.kind === \"jst_ph_housing\"\n ? createJstMeshes(connector)\n : createMainsMeshes(connector)\n if (\n jacketDiameter !== undefined &&\n connector.kind !== \"bullet_male\" &&\n connector.kind !== \"bullet_female\"\n ) {\n const exit = connectorWireExitDepth(connector)\n const boot = union(\n cylinder({\n radius: jacketDiameter / 2 + 0.15,\n height: 5,\n center: [0, 0, exit + 2.5],\n segments: 32,\n }),\n ...Array.from({ length: 7 }, (_, index) =>\n cylinder({\n radius: jacketDiameter / 2 + 0.8 - index * 0.06,\n height: 0.28,\n center: [0, 0, exit + 0.4 + index * 0.7],\n segments: 32,\n }),\n ),\n )\n meshes.push(\n geometryToCableMesh({\n geometry: boot,\n color: plastic,\n name: \"strain-relief\",\n }),\n )\n }\n return meshes\n}\n","import { add, scale, subtract } from \"./path-frames\"\nimport type { CablePoint } from \"./types\"\n\n/** Add sweep samples on the supplied world-mm polyline, without changing its\n * route. End transitions occupy at most 20 mm each; short cables retain a\n * compact middle third. Sampling the transitions also supports two-point paths.\n */\nexport function createBundleFanoutPath(path: CablePoint[]) {\n const originalDistances = [0]\n for (let index = 1; index < path.length; index++)\n originalDistances.push(\n originalDistances[index - 1]! +\n Math.hypot(...subtract(path[index]!, path[index - 1]!)),\n )\n const length = originalDistances.at(-1)!\n const endLength = Math.min(20, length / 3)\n const samples = [...originalDistances, length / 2]\n for (let step = 0; step <= 10; step++) {\n const distance = (endLength * step) / 10\n samples.push(distance, length - distance)\n }\n const distances = samples\n .sort((a, b) => a - b)\n .filter(\n (distance, index, sorted) =>\n index === 0 || distance - sorted[index - 1]! > 1e-9,\n )\n let segment = 0\n const sampledPath = distances.map((distance): CablePoint => {\n while (\n segment < path.length - 2 &&\n distance > originalDistances[segment + 1]!\n )\n segment++\n const progress =\n (distance - originalDistances[segment]!) /\n (originalDistances[segment + 1]! - originalDistances[segment]!)\n return add(\n path[segment]!,\n scale(subtract(path[segment + 1]!, path[segment]!), progress),\n )\n })\n return { path: sampledPath, distances, length, endLength }\n}\n","import { add, scale } from \"./path-frames\"\nimport type { CableFrame, CableMesh, CableColor } from \"./types\"\n\n/** Closed indexed sweep around a supplied centerline; this does not choose a route. */\nexport function sweepRoundCable({\n frames,\n diameter,\n offset = 0,\n radialSegments,\n color,\n name,\n}: {\n frames: CableFrame[]\n diameter: number\n offset?: number\n radialSegments: number\n color: CableColor\n name: string\n}): CableMesh {\n const positions: number[] = []\n const indices: number[] = []\n for (const frame of frames) {\n const center = add(frame.point, scale(frame.normal, offset))\n for (let side = 0; side < radialSegments; side++) {\n const angle = (side * Math.PI * 2) / radialSegments\n positions.push(\n ...add(\n center,\n add(\n scale(frame.normal, (diameter * Math.cos(angle)) / 2),\n scale(frame.binormal, (diameter * Math.sin(angle)) / 2),\n ),\n ),\n )\n }\n }\n for (let ring = 0; ring < frames.length - 1; ring++) {\n for (let side = 0; side < radialSegments; side++) {\n const a = ring * radialSegments + side\n const b = ring * radialSegments + ((side + 1) % radialSegments)\n const c = a + radialSegments\n const d = b + radialSegments\n indices.push(a, b, c, b, d, c)\n }\n }\n const startCenter = positions.length / 3\n positions.push(...add(frames[0]!.point, scale(frames[0]!.normal, offset)))\n const endCenter = positions.length / 3\n positions.push(\n ...add(frames.at(-1)!.point, scale(frames.at(-1)!.normal, offset)),\n )\n const lastRing = (frames.length - 1) * radialSegments\n for (let side = 0; side < radialSegments; side++) {\n const next = (side + 1) % radialSegments\n indices.push(\n startCenter,\n next,\n side,\n endCenter,\n lastRing + side,\n lastRing + next,\n )\n }\n return { name, positions, indices, color, smooth: true }\n}\n","import {\n createConnectorMeshes,\n connectorWireExitDepth,\n} from \"./connector-meshes\"\nimport { placeConnectorMesh } from \"./geometry-to-mesh\"\nimport { add, scale, createCablePathFrames } from \"./path-frames\"\nimport { createBundleFanoutPath } from \"./create-bundle-fanout-path\"\nimport { sweepRoundCable } from \"./sweep-round-cable\"\nimport type {\n CableColor,\n CableGeometryDefinition,\n CableMesh,\n CablePoint,\n} from \"./types\"\n\nfunction parseCableColor(color: string): CableColor {\n if (!/^#[a-f\\d]{6}$/i.test(color))\n throw new Error(\"Cable colors must be six-digit hex strings\")\n return [\n parseInt(color.slice(1, 3), 16) / 255,\n parseInt(color.slice(3, 5), 16) / 255,\n parseInt(color.slice(5, 7), 16) / 255,\n 1,\n ]\n}\n\nfunction validateCableDefinition(definition: CableGeometryDefinition) {\n for (const connector of [definition.connectorA, definition.connectorB]) {\n const dimensions = [\n connector.bodyWidth,\n connector.bodyHeight,\n connector.bodyDepth,\n ]\n if (connector.kind === \"usb_c_plug\")\n dimensions.push(\n connector.shellWidth,\n connector.shellHeight,\n connector.shellDepth,\n )\n if (\n connector.kind === \"bullet_male\" ||\n connector.kind === \"bullet_female\"\n ) {\n const pinCount = connector.pinCount ?? 1\n const pitch = connector.pitch ?? connector.bodyHeight\n dimensions.push(connector.diameter, connector.contactDepth, pitch)\n if (\n !Number.isInteger(pinCount) ||\n pinCount < 1 ||\n pinCount > 16 ||\n connector.bodyHeight <= connector.diameter ||\n pitch < connector.bodyHeight ||\n Math.abs(\n connector.bodyWidth - (connector.bodyHeight + (pinCount - 1) * pitch),\n ) > 1e-6 ||\n connector.contactDepth >= connector.bodyDepth ||\n connector.contactDepth <= connector.diameter / 2\n )\n throw new Error(\"Bullet contact must fit inside its cylindrical body\")\n if (\n (pinCount === 1 &&\n (definition.crossSection.kind !== \"round_jacket\" ||\n definition.crossSection.diameter > connector.bodyHeight)) ||\n (pinCount > 1 &&\n (definition.crossSection.kind !== \"wire_bundle\" ||\n definition.crossSection.wires.length !== pinCount ||\n definition.crossSection.wires.some(\n (wire) => wire.diameter > connector.bodyHeight,\n )))\n )\n throw new Error(\n \"Bullet cables require one insulated wire per contact that fits its solder cup\",\n )\n }\n if (\n dimensions.some(\n (dimension) => !Number.isFinite(dimension) || dimension <= 0,\n )\n )\n throw new Error(\"Connector dimensions must be finite and positive\")\n if (\n (connector.kind === \"jst_sh_housing\" ||\n connector.kind === \"jst_ph_housing\") &&\n (!Number.isInteger(connector.pinCount) ||\n connector.pinCount < 2 ||\n !Number.isFinite(connector.pitch) ||\n connector.pitch <= 0)\n )\n throw new Error(\n \"JST connectors need a positive pitch and at least two contacts\",\n )\n }\n const crossSection = definition.crossSection\n const diameters =\n crossSection.kind === \"round_jacket\"\n ? [crossSection.diameter]\n : crossSection.wires.map((wire) => wire.diameter)\n if (\n diameters.length === 0 ||\n diameters.some((diameter) => !Number.isFinite(diameter) || diameter <= 0)\n )\n throw new Error(\"Cable diameters must be finite and positive\")\n if (crossSection.kind === \"wire_bundle\") {\n if (\n !Number.isFinite(crossSection.wirePitch) ||\n crossSection.wires.some((wire) => wire.diameter > crossSection.wirePitch)\n )\n throw new Error(\"Insulated bundle wires must not overlap\")\n for (const connector of [definition.connectorA, definition.connectorB]) {\n if (\n !(\"pinCount\" in connector) ||\n (connector.pinCount ?? 1) !== crossSection.wires.length\n )\n throw new Error(\"Bundle wire count must match connector contact count\")\n if (\n \"pitch\" in connector &&\n crossSection.wires.some((wire) => wire.diameter > connector.pitch)\n )\n throw new Error(\"Insulated wires must fit each connector pitch\")\n }\n }\n}\n\n/** Mesh generation only. Path samples are already resolved in world millimeters, +Z up. */\nexport function createCableMeshes({\n definition,\n path,\n radialSegments = 24,\n startPin1Side,\n endPin1Side,\n}: {\n definition: CableGeometryDefinition\n path: CablePoint[]\n radialSegments?: number\n /** Connector center toward pin 1 (local -X), in right-handed world XYZ, +Z up; directions, no translation. */\n startPin1Side?: CablePoint\n endPin1Side?: CablePoint\n}): CableMesh[] {\n validateCableDefinition(definition)\n if (\n !Number.isInteger(radialSegments) ||\n radialSegments < 8 ||\n radialSegments > 128\n )\n throw new Error(\"radialSegments must be an integer from 8 to 128\")\n const frames = createCablePathFrames(path, { startPin1Side, endPin1Side })\n const crossSection = definition.crossSection\n const jacketDiameter =\n crossSection.kind === \"round_jacket\" ? crossSection.diameter : undefined\n // Endpoint pitches are connector-local mm. Offset along transported normals\n // in the same right-handed +Z-up world frame as the supplied centerline.\n // Keep the middle compact; widen only near the connector wire exits.\n const pitchA =\n \"pitch\" in definition.connectorA ? definition.connectorA.pitch : undefined\n const pitchB =\n \"pitch\" in definition.connectorB ? definition.connectorB.pitch : undefined\n const fanout =\n pitchA !== pitchB && crossSection.kind === \"wire_bundle\"\n ? createBundleFanoutPath(path)\n : undefined\n const fanoutFrames = fanout\n ? createCablePathFrames(fanout.path, { startPin1Side, endPin1Side })\n : frames\n const meshes =\n crossSection.kind === \"round_jacket\"\n ? [\n sweepRoundCable({\n frames,\n diameter: crossSection.diameter,\n radialSegments,\n color: parseCableColor(crossSection.color),\n name: \"jacket\",\n }),\n ]\n : crossSection.wires.map((wire, index) => {\n const contactOffset = index - (crossSection.wires.length - 1) / 2\n // 20% clearance around the thickest insulated wire, capped by the\n // declared bundle and both connector pitches to prevent overlap.\n const compactPitch = Math.min(\n crossSection.wirePitch,\n pitchA ?? crossSection.wirePitch,\n pitchB ?? crossSection.wirePitch,\n 1.2 * Math.max(...crossSection.wires.map((wire) => wire.diameter)),\n )\n const smoothstep = (progress: number) =>\n progress * progress * (3 - 2 * progress)\n const wireFrames = fanout\n ? createCablePathFrames(\n fanoutFrames.map((frame, pathIndex) => {\n const distance = fanout.distances[pathIndex]!\n const start =\n 1 - smoothstep(Math.min(1, distance / fanout.endLength))\n const end =\n 1 -\n smoothstep(\n Math.min(\n 1,\n (fanout.length - distance) / fanout.endLength,\n ),\n )\n const pitch =\n compactPitch +\n ((pitchA ?? crossSection.wirePitch) - compactPitch) *\n start +\n ((pitchB ?? crossSection.wirePitch) - compactPitch) * end\n return add(\n frame.point,\n scale(frame.normal, contactOffset * pitch),\n )\n }),\n )\n : frames\n return sweepRoundCable({\n frames: wireFrames,\n diameter: wire.diameter,\n offset: (fanout ? 0 : contactOffset) * crossSection.wirePitch,\n radialSegments,\n color: parseCableColor(wire.color),\n name: `wire-${index + 1}`,\n })\n })\n for (const [index, connector] of [\n definition.connectorA,\n definition.connectorB,\n ].entries()) {\n const frame = index === 0 ? frames[0]! : frames.at(-1)!\n const parts = createConnectorMeshes({ connector, jacketDiameter })\n meshes.push(\n ...parts.map((mesh) =>\n placeConnectorMesh({\n mesh: { ...mesh, name: `${index === 0 ? \"A\" : \"B\"}-${mesh.name}` },\n frame,\n isEnd: index === 1,\n wireExitDepth: connectorWireExitDepth(connector),\n }),\n ),\n )\n }\n return meshes\n}\n"],"mappings":";AAAA,OAAOA,YAAW;;;ACCX,IAAM,qBAAqB;AAAA,EAChC,eAAe,EAAE,WAAW,GAAG,WAAW,IAAI;AAAA,EAC9C,QAAQ,EAAE,WAAW,GAAG,WAAW,IAAI;AAAA,EACvC,QAAQ,EAAE,WAAW,GAAG,WAAW,KAAK;AAAA,EACxC,YAAY,EAAE,WAAW,KAAK,WAAW,KAAK;AAAA,EAC9C,aAAa,EAAE,WAAW,GAAG,WAAW,KAAK;AAAA,EAC7C,QAAQ,EAAE,WAAW,GAAG,WAAW,KAAK;AAAA,EACxC,cAAc,EAAE,WAAW,GAAG,WAAW,IAAI;AAAA,EAC7C,OAAO,EAAE,WAAW,GAAG,WAAW,KAAK;AACzC;;;ACVA,OAAO,WAAW;;;ACEX,IAAM,MAAM,CAAC,GAAe,MAA8B;AAAA,EAC/D,EAAE,CAAC,IAAI,EAAE,CAAC;AAAA,EACV,EAAE,CAAC,IAAI,EAAE,CAAC;AAAA,EACV,EAAE,CAAC,IAAI,EAAE,CAAC;AACZ;AACO,IAAM,WAAW,CAAC,GAAe,MAA8B;AAAA,EACpE,EAAE,CAAC,IAAI,EAAE,CAAC;AAAA,EACV,EAAE,CAAC,IAAI,EAAE,CAAC;AAAA,EACV,EAAE,CAAC,IAAI,EAAE,CAAC;AACZ;AACO,IAAM,QAAQ,CAAC,OAAmB,WAA+B;AAAA,EACtE,MAAM,CAAC,IAAI;AAAA,EACX,MAAM,CAAC,IAAI;AAAA,EACX,MAAM,CAAC,IAAI;AACb;AACO,IAAM,MAAM,CAAC,GAAe,MACjC,EAAE,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC;AACjC,IAAM,QAAQ,CAAC,GAAe,MAA8B;AAAA,EACjE,EAAE,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC;AAAA,EACxB,EAAE,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC;AAAA,EACxB,EAAE,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC;AAC1B;AACO,SAAS,UAAU,OAA+B;AACvD,QAAM,SAAS,KAAK,MAAM,GAAG,KAAK;AAClC,MAAI,SAAS;AACX,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AACF,SAAO,MAAM,OAAO,IAAI,MAAM;AAChC;AAQO,SAAS,sBACd,MACA;AAAA,EACE;AAAA,EACA;AACF,IAGI,CAAC,GACS;AACd,MACE,KAAK,SAAS,KACd,KAAK,KAAK,CAAC,UAAU,MAAM,WAAW,KAAK,CAAC,MAAM,MAAM,OAAO,QAAQ,CAAC,GACxE;AACA,UAAM,IAAI,MAAM,gDAAgD;AAAA,EAClE;AACA,QAAM,WAAW,KACd,MAAM,CAAC,EACP,IAAI,CAAC,OAAO,UAAU,UAAU,SAAS,OAAO,KAAK,KAAK,CAAE,CAAC,CAAC;AACjE,QAAM,WAAW,KAAK;AAAA,IAAI,CAAC,GAAG,UAC5B,UAAU,IACN,SAAS,CAAC,IACV,UAAU,KAAK,SAAS,IACtB,SAAS,GAAG,EAAE,IACd,UAAU,IAAI,SAAS,QAAQ,CAAC,GAAI,SAAS,KAAK,CAAE,CAAC;AAAA,EAC7D;AACA,QAAM,YACJ,KAAK,IAAI,SAAS,CAAC,EAAG,CAAC,CAAC,IAAI,OAAO,CAAC,GAAG,GAAG,CAAC,IAAI,CAAC,GAAG,GAAG,CAAC;AACzD,QAAM,iBAAiB,CAAC,UAAsB,YAAwB;AACpE,QACE,SAAS,WAAW,KACpB,CAAC,SAAS,MAAM,OAAO,QAAQ,KAC/B,KAAK,MAAM,GAAG,QAAQ,IAAI;AAE1B,YAAM,IAAI,MAAM,sDAAsD;AACxE,UAAMC,UAAS,MAAM,UAAU,QAAQ,GAAG,EAAE;AAC5C,QAAI,KAAK,IAAI,IAAIA,SAAQ,OAAO,CAAC,IAAI;AACnC,YAAM,IAAI;AAAA,QACR;AAAA,MACF;AACF,WAAO,UAAU,SAASA,SAAQ,MAAM,SAAS,IAAIA,SAAQ,OAAO,CAAC,CAAC,CAAC;AAAA,EACzE;AACA,MAAI,SAAS,gBACT,eAAe,eAAe,SAAS,CAAC,CAAE,IAC1C,UAAU,MAAM,WAAW,SAAS,CAAC,CAAE,CAAC;AAC5C,QAAM,SAAS,SAAS,IAAI,CAAC,SAAS,UAAU;AAC9C,QAAI,QAAQ,GAAG;AACb,YAAM,kBAAkB,SAAS,QAAQ,CAAC;AAC1C,YAAM,OAAO,MAAM,iBAAiB,OAAO;AAC3C,YAAM,OAAO,KAAK,MAAM,GAAG,IAAI;AAC/B,YAAM,SAAS,KAAK,IAAI,IAAI,KAAK,IAAI,GAAG,IAAI,iBAAiB,OAAO,CAAC,CAAC;AACtE,UAAI,OAAO,OAAO;AAChB,cAAM,WAAW,MAAM,MAAM,IAAI,IAAI;AACrC,iBAAS;AAAA,UACP;AAAA,YACE,IAAI,MAAM,QAAQ,MAAM,GAAG,MAAM,MAAM,UAAU,MAAM,GAAG,IAAI,CAAC;AAAA,YAC/D,MAAM,UAAU,IAAI,UAAU,MAAM,KAAK,IAAI,OAAO;AAAA,UACtD;AAAA,QACF;AAAA,MACF;AAAA,IACF;AACA,WAAO;AAAA,MACL,OAAO,KAAK,KAAK;AAAA,MACjB;AAAA,MACA;AAAA,MACA,UAAU,UAAU,MAAM,SAAS,MAAM,CAAC;AAAA,IAC5C;AAAA,EACF,CAAC;AACD,MAAI,CAAC,YAAa,QAAO;AACzB,QAAM,OAAO,OAAO,GAAG,EAAE;AACzB,QAAM,YAAY,eAAe,aAAa,KAAK,OAAO;AAC1D,QAAM,QAAQ,KAAK;AAAA,IACjB,IAAI,KAAK,SAAS,MAAM,KAAK,QAAQ,SAAS,CAAC;AAAA,IAC/C,IAAI,KAAK,QAAQ,SAAS;AAAA,EAC5B;AACA,QAAM,YAAY,CAAC,CAAC;AACpB,WAAS,QAAQ,GAAG,QAAQ,KAAK,QAAQ;AACvC,cAAU;AAAA,MACR,UAAU,QAAQ,CAAC,IACjB,KAAK,MAAM,GAAG,SAAS,KAAK,KAAK,GAAI,KAAK,QAAQ,CAAC,CAAE,CAAC;AAAA,IAC1D;AACF,SAAO,OAAO,IAAI,CAAC,OAAO,UAAU;AAClC,UAAM,QACJ,SAAS,gBAAgB,UAAU,KAAK,IAAK,UAAU,GAAG,EAAE,IAAK;AACnE,UAAMA,UAAS;AAAA,MACb;AAAA,QACE,MAAM,MAAM,QAAQ,KAAK,IAAI,KAAK,CAAC;AAAA,QACnC,MAAM,MAAM,UAAU,KAAK,IAAI,KAAK,CAAC;AAAA,MACvC;AAAA,IACF;AACA,WAAO;AAAA,MACL,GAAG;AAAA,MACH,QAAAA;AAAA,MACA,UAAU,UAAU,MAAM,MAAM,SAASA,OAAM,CAAC;AAAA,IAClD;AAAA,EACF,CAAC;AACH;;;ADhIO,SAAS,oBAAoB;AAAA,EAClC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAKc;AACZ,QAAM,YAAY,MAAM,WAAW,MAAM,WAAW,QAAQ;AAC5D,QAAM,YAAsB,CAAC;AAC7B,QAAM,UAAoB,CAAC;AAC3B,QAAM,WAAW,oBAAI,IAAuB;AAC5C,aAAW,YAAY,WAAW;AAChC,UAAM,iBAA2B,CAAC;AAClC,eAAW,SAAS,SAAS,UAAU;AACrC,YAAM,MAAM,MAAM,IAAI,CAAC,eAAe,WAAW,QAAQ,CAAC,CAAC,EAAE,KAAK,GAAG;AACrE,UAAI,QAAQ,SAAS,IAAI,GAAG;AAC5B,UAAI,UAAU,QAAW;AACvB,gBAAQ,UAAU,SAAS;AAC3B,kBAAU,KAAK,GAAG,KAAK;AACvB,iBAAS,IAAI,KAAK,KAAK;AAAA,MACzB;AACA,qBAAe,KAAK,KAAK;AAAA,IAC3B;AAEA,aAAS,OAAO,GAAG,OAAO,eAAe,SAAS,GAAG,QAAQ;AAC3D,cAAQ;AAAA,QACN,eAAe,CAAC;AAAA,QAChB,eAAe,IAAI;AAAA,QACnB,eAAe,OAAO,CAAC;AAAA,MACzB;AAAA,IACF;AAAA,EACF;AACA,SAAO,EAAE,MAAM,WAAW,SAAS,OAAO,UAAU,QAAQ,MAAM;AACpE;AAEO,SAAS,mBAAmB;AAAA,EACjC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAKc;AACZ,QAAM,UAAU,MAAM,MAAM,SAAS,QAAQ,KAAK,CAAC;AACnD,QAAM,WAAuB,QACzB,MAAM,MAAM,UAAU,EAAE,IACxB,MAAM;AACV,QAAM,SAAS,IAAI,MAAM,OAAO,MAAM,SAAS,CAAC,aAAa,CAAC;AAC9D,QAAM,YAAsB,CAAC;AAC7B,WAAS,QAAQ,GAAG,QAAQ,KAAK,UAAU,QAAQ,SAAS,GAAG;AAC7D,cAAU;AAAA,MACR,GAAG;AAAA,QACD;AAAA,QACA;AAAA,UACE;AAAA,YACE,MAAM,MAAM,QAAQ,KAAK,UAAU,KAAK,CAAE;AAAA,YAC1C,MAAM,UAAU,KAAK,UAAU,QAAQ,CAAC,CAAE;AAAA,UAC5C;AAAA,UACA,MAAM,SAAS,KAAK,UAAU,QAAQ,CAAC,CAAE;AAAA,QAC3C;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACA,SAAO,EAAE,GAAG,MAAM,UAAU;AAC9B;;;AFtEO,SAAS,mBACd,WAIa;AACb,QAAM,EAAE,UAAAC,WAAU,QAAAC,SAAQ,QAAAC,QAAO,IAAIC,OAAM;AAC3C,QAAM,EAAE,UAAAC,WAAU,OAAAC,OAAM,IAAIF,OAAM;AAClC,QAAM,EAAE,UAAU,cAAc,WAAW,KAAK,IAAI;AACpD,QAAM,YAAY,UAAU;AAC5B,QAAM,SAAS,WAAW;AAC1B,MAAI,UACF,SAAS,gBACLE;AAAA,IACEJ,QAAO,EAAE,QAAQ,QAAQ,CAAC,GAAG,GAAG,MAAM,GAAG,UAAU,GAAG,CAAC;AAAA,IACvDD,UAAS;AAAA,MACP;AAAA,MACA,QAAQ,eAAe;AAAA,MACvB,QAAQ,CAAC,GAAG,IAAI,eAAe,UAAU,CAAC;AAAA,MAC1C,UAAU;AAAA,IACZ,CAAC;AAAA,EACH,IACAI;AAAA,IACEJ,UAAS;AAAA,MACP,QAAQ,YAAY;AAAA,MACpB,QAAQ;AAAA,MACR,QAAQ,CAAC,GAAG,GAAG,eAAe,CAAC;AAAA,MAC/B,UAAU;AAAA,IACZ,CAAC;AAAA,IACDA,UAAS;AAAA,MACP;AAAA,MACA,QAAQ,eAAe,WAAW,IAAI;AAAA,MACtC,QAAQ,CAAC,GAAG,IAAI,eAAe,WAAW,IAAI,OAAO,CAAC;AAAA,MACtD,UAAU;AAAA,IACZ,CAAC;AAAA,EACH;AACN,MAAI,SAAS,eAAe;AAC1B,cAAUI;AAAA,MACR;AAAA,MACAF,QAAO;AAAA,QACL,MAAM,CAAC,WAAW,KAAK,WAAW,MAAM,eAAe,IAAI;AAAA,QAC3D,QAAQ,CAAC,GAAG,GAAG,eAAe,IAAI;AAAA,MACpC,CAAC;AAAA,MACDA,QAAO;AAAA,QACL,MAAM,CAAC,WAAW,MAAM,WAAW,KAAK,eAAe,IAAI;AAAA,QAC3D,QAAQ,CAAC,GAAG,GAAG,eAAe,IAAI;AAAA,MACpC,CAAC;AAAA,IACH;AAAA,EACF;AACA,QAAM,WAAW,YAAY;AAC7B,QAAM,YAAYE;AAAA,IAChBJ,UAAS;AAAA,MACP,QAAQ,YAAY;AAAA,MACpB,QAAQ;AAAA,MACR,QAAQ,CAAC,GAAG,GAAG,eAAe,WAAW,CAAC;AAAA,MAC1C,UAAU;AAAA,IACZ,CAAC;AAAA,IACDA,UAAS;AAAA,MACP,QAAQ,SAAS;AAAA,MACjB,QAAQ,WAAW,MAAM;AAAA,MACzB,QAAQ,CAAC,GAAG,GAAG,YAAY,WAAW,MAAM,IAAI;AAAA,MAChD,UAAU;AAAA,IACZ,CAAC;AAAA,EACH;AACA,QAAM,gBAAgB;AAAA,IACpB,oBAAoB;AAAA,MAClB,UAAU;AAAA,MACV,UAAU,mBAAmB;AAAA,MAC7B,OAAO,CAAC,MAAM,MAAM,MAAM,CAAC;AAAA,MAC3B,MAAM,SAAS,gBAAgB,eAAe;AAAA,IAChD,CAAC;AAAA,IACD,oBAAoB;AAAA,MAClB,UAAU;AAAA,MACV,UAAU,mBAAmB;AAAA,MAC7B,OAAO,CAAC,MAAM,MAAM,MAAM,CAAC;AAAA,MAC3B,MAAM;AAAA,IACR,CAAC;AAAA,EACH;AACA,QAAM,WAAW,UAAU,YAAY;AACvC,SAAO,MAAM,KAAK,EAAE,QAAQ,SAAS,GAAG,CAAC,GAAG,UAAU;AACpD,UAAM,UAAU,SAAS,WAAW,KAAK,MAAM,UAAU,SAAS;AAClE,WAAO,cAAc,IAAI,CAAC,UAAU;AAAA,MAClC,GAAG;AAAA,MACH,MAAM,aAAa,IAAI,KAAK,OAAO,GAAG,KAAK,IAAI,IAAI,QAAQ,CAAC;AAAA;AAAA,MAE5D,WAAW,KAAK,UAAU;AAAA,QAAI,CAAC,YAAY,oBACzC,kBAAkB,MAAM,IAAI,aAAa,SAAS;AAAA,MACpD;AAAA,IACF,EAAE;AAAA,EACJ,CAAC,EAAE,KAAK;AACV;;;AIhGA,OAAOM,YAAW;AASlB,IAAM,EAAE,QAAQ,eAAe,UAAU,kBAAkB,SAAS,OAAO,IACzEC,OAAM;AACR,IAAM,EAAE,cAAc,IAAIA,OAAM;AAChC,IAAM,EAAE,WAAW,QAAQ,IAAIA,OAAM;AACrC,IAAM,EAAE,UAAAC,WAAU,MAAM,IAAID,OAAM;AAClC,IAAM,UAAsB,CAAC,OAAO,MAAM,MAAM,CAAC;AACjD,IAAM,UAAsB,CAAC,MAAM,MAAM,MAAM,CAAC;AAChD,IAAM,QAAoB,CAAC,KAAK,MAAM,KAAK,CAAC;AAC5C,IAAM,QAAoB,CAAC,MAAM,MAAM,MAAM,CAAC;AAEvC,SAAS,uBAAuB,WAAuC;AAC5E,MAAI,UAAU,SAAS;AACrB,WAAO,UAAU,aAAa,UAAU;AAC1C,MAAI,UAAU,SAAS,aAAc,QAAO,QAAQ,UAAU;AAC9D,SAAO,UAAU;AACnB;AAEA,SAAS,gBACP,WAIa;AACb,QAAM;AAAA,IACJ,WAAW;AAAA,IACX,YAAY;AAAA,IACZ,WAAW;AAAA,IACX;AAAA,IACA;AAAA,EACF,IAAI;AACJ,QAAM,UAAU,UAAU,IAAI,OAAO;AACrC,QAAM,QAAQ,MAAM,KAAK,EAAE,QAAQ,SAAS,GAAG,CAAC,GAAG,UAAU;AAC3D,UAAM,KAAK,SAAS,WAAW,KAAK,KAAK;AACzC,WAAO,OAAO;AAAA,MACZ,MAAM,CAAC,SAAS,UAAU,MAAM,QAAQ,GAAG;AAAA,MAC3C,QAAQ,CAAC,GAAG,IAAI,QAAQ,OAAO,IAAI,IAAI;AAAA,IACzC,CAAC;AAAA,EACH,CAAC;AACD,QAAM,YAAY,MAAM;AAAA,IAAK,EAAE,QAAQ,SAAS;AAAA,IAAG,CAAC,GAAG,UACrD,SAAS;AAAA,MACP,QAAQ,QAAQ;AAAA,MAChB,QAAQ;AAAA,MACR,UAAU;AAAA,MACV,QAAQ,EAAE,SAAS,WAAW,KAAK,KAAK,OAAO,GAAG,QAAQ,GAAG;AAAA,IAC/D,CAAC;AAAA,EACH;AACA,QAAM,WAAW,OAAO;AAAA,IACtB,MAAM,CAAC,QAAQ,MAAM,KAAK,QAAQ,GAAG;AAAA,IACrC,QAAQ,CAAC,GAAG,SAAS,GAAG,QAAQ,IAAI;AAAA,EACtC,CAAC;AACD,QAAM,OAAOC;AAAA,IACX,cAAc;AAAA,MACZ,MAAM,CAAC,OAAO,QAAQ,KAAK;AAAA,MAC3B,QAAQ,CAAC,GAAG,GAAG,QAAQ,CAAC;AAAA,MACxB,aAAa;AAAA,MACb,UAAU;AAAA,IACZ,CAAC;AAAA,IACD,GAAG;AAAA,IACH,GAAG;AAAA,IACH;AAAA,IACA,GAAG,MAAM;AAAA,MAAK,EAAE,QAAQ,SAAS;AAAA,MAAG,CAAC,GAAG,UACtC,OAAO;AAAA,QACL,MAAM,CAAC,UAAU,KAAK,SAAS,KAAK,QAAQ,IAAI;AAAA,QAChD,QAAQ,EAAE,SAAS,WAAW,KAAK,KAAK,OAAO,SAAS,GAAG,QAAQ,GAAG;AAAA,MACxE,CAAC;AAAA,IACH;AAAA,EACF;AACA,QAAM,WAAW,MAAM,KAAK,EAAE,QAAQ,SAAS,GAAG,CAAC,GAAG,UAAU;AAC9D,UAAM,KAAK,SAAS,WAAW,KAAK,KAAK;AACzC,WAAO,oBAAoB;AAAA,MACzB,UAAU,mBAAmB;AAAA,MAC7B,MAAM,WAAW,QAAQ,CAAC;AAAA,MAC1B,OAAO;AAAA,MACP,UAAUA;AAAA,QACR,OAAO;AAAA,UACL,MAAM,CAAC,UAAU,MAAM,UAAU,MAAM,QAAQ,IAAI;AAAA,UACnD,QAAQ,CAAC,GAAG,GAAG,QAAQ,IAAI;AAAA,QAC7B,CAAC;AAAA,QACD,OAAO;AAAA,UACL,MAAM;AAAA,YACJ,UAAU,OAAO;AAAA,YACjB,UAAU,OAAO;AAAA,YACjB,QAAQ,OAAO;AAAA,UACjB;AAAA,UACA,QAAQ,CAAC,GAAG,GAAG,QAAQ,IAAI;AAAA,QAC7B,CAAC;AAAA,MACH;AAAA,IACF,CAAC;AAAA,EACH,CAAC;AACD,SAAO;AAAA,IACL,oBAAoB,EAAE,UAAU,MAAM,OAAO,SAAS,MAAM,UAAU,CAAC;AAAA,IACvE,GAAG;AAAA,EACL;AACF;AAEA,SAAS,gBACP,WACa;AACb,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,IAAI;AACJ,QAAM,QAAQA;AAAA,IACZ;AAAA,MACE,EAAE,QAAQ,WAAW;AAAA,MACrB,iBAAiB;AAAA,QACf,MAAM,CAAC,YAAY,WAAW;AAAA,QAC9B,aAAa,cAAc,IAAI;AAAA,QAC/B,UAAU;AAAA,MACZ,CAAC;AAAA,IACH;AAAA,IACA;AAAA,MACE,CAAC,GAAG,GAAG,IAAI;AAAA,MACX;AAAA,QACE,EAAE,QAAQ,aAAa,IAAI;AAAA,QAC3B,iBAAiB;AAAA,UACf,MAAM,CAAC,aAAa,KAAK,cAAc,GAAG;AAAA,UAC1C,cAAc,cAAc,OAAO,IAAI;AAAA,UACvC,UAAU;AAAA,QACZ,CAAC;AAAA,MACH;AAAA,IACF;AAAA,EACF;AACA,QAAM,QAAQA;AAAA,IACZ;AAAA,MACE,EAAE,QAAQ,WAAW;AAAA,MACrB,iBAAiB;AAAA,QACf,MAAM,CAAC,aAAa,MAAM,cAAc,IAAI;AAAA,QAC5C,aAAa;AAAA,QACb,UAAU;AAAA,MACZ,CAAC;AAAA,IACH;AAAA,IACA;AAAA,MACE,CAAC,GAAG,GAAG,IAAI;AAAA,MACX;AAAA,QACE,EAAE,QAAQ,aAAa,IAAI;AAAA,QAC3B,iBAAiB;AAAA,UACf,MAAM,CAAC,aAAa,KAAK,cAAc,GAAG;AAAA,UAC1C,aAAa;AAAA,UACb,UAAU;AAAA,QACZ,CAAC;AAAA,MACH;AAAA,IACF;AAAA,EACF;AACA,QAAM,OAAO,cAAc;AAAA,IACzB,MAAM,CAAC,WAAW,YAAY,SAAS;AAAA,IACvC,QAAQ,CAAC,GAAG,GAAG,aAAa,YAAY,CAAC;AAAA,IACzC,aAAa,KAAK,IAAI,KAAK,aAAa,CAAC;AAAA,IACzC,UAAU;AAAA,EACZ,CAAC;AACD,QAAM,WAAW,MAAM;AAAA,IAAK,EAAE,QAAQ,GAAG;AAAA,IAAG,CAAC,GAAG,UAC9C,OAAO;AAAA,MACL,MAAM,CAAC,MAAM,MAAM,GAAG;AAAA,MACtB,QAAQ,EAAG,QAAQ,KAAM,OAAO,KAAK,QAAQ,KAAK,OAAO,OAAO,GAAG;AAAA,IACrE,CAAC;AAAA,EACH;AACA,SAAO;AAAA,IACL,oBAAoB,EAAE,UAAU,MAAM,OAAO,SAAS,MAAM,WAAW,CAAC;AAAA,IACxE,oBAAoB;AAAA,MAClB,UAAU;AAAA,MACV,OAAO;AAAA,MACP,UAAU,mBAAmB;AAAA,MAC7B,MAAM;AAAA,IACR,CAAC;AAAA,IACD,oBAAoB;AAAA,MAClB,UAAU;AAAA,MACV,OAAO,CAAC,OAAO,OAAO,MAAM,CAAC;AAAA,MAC7B,MAAM;AAAA,IACR,CAAC;AAAA,IACD,GAAG,SAAS;AAAA,MAAI,CAAC,UAAU,UACzB,oBAAoB;AAAA,QAClB;AAAA,QACA,OAAO;AAAA,QACP,UAAU,mBAAmB;AAAA,QAC7B,MAAM,WAAW,QAAQ,CAAC;AAAA,MAC5B,CAAC;AAAA,IACH;AAAA,EACF;AACF;AAEA,SAAS,kBAAkB,WAA4C;AACrE,QAAM,EAAE,WAAW,YAAY,WAAW,KAAK,IAAI;AACnD,QAAM,YAAY,SAAS,eAAe,QAAQ;AAClD,MAAI,OAAO,cAAc;AAAA,IACvB,MAAM,CAAC,WAAW,YAAY,SAAS;AAAA,IACvC,QAAQ,CAAC,GAAG,GAAG,YAAY,YAAY,CAAC;AAAA,IACxC,aAAa;AAAA,IACb,UAAU;AAAA,EACZ,CAAC;AACD,MAAI,SAAS,cAAc;AACzB,UAAM,SAAS,CAAC,OAAO,IAAI,EAAE,IAAI,CAAC,MAAM;AACtC,YAAM,QAAQ,OAAO;AAAA,QACnB,MAAM,CAAC,OAAO,MAAM,MAAM;AAAA,QAC1B,QAAQ,CAAC,GAAG,KAAK,QAAQ,SAAS,CAAC;AAAA,MACrC,CAAC;AACD,YAAM,OAAO;AAAA,QACX,CAAC,GAAG,KAAK,GAAG;AAAA,QACZ;AAAA,UACE,KAAK,KAAK;AAAA,UACV,SAAS,EAAE,QAAQ,KAAK,QAAQ,GAAG,UAAU,GAAG,CAAC;AAAA,QACnD;AAAA,MACF;AACA,aAAOA,UAAS,OAAO,IAAI;AAAA,IAC7B,CAAC;AACD,UAAM,SAAS;AAAA,MACb,SAAS;AAAA,QACP,QAAQ;AAAA,QACR,QAAQ,QAAQ;AAAA,QAChB,QAAQ,CAAC,GAAG,WAAW,QAAQ,WAAW,CAAC;AAAA,QAC3C,UAAU;AAAA,MACZ,CAAC;AAAA,MACD,OAAO,EAAE,QAAQ,SAAS,QAAQ,CAAC,GAAG,UAAU,OAAO,GAAG,UAAU,GAAG,CAAC;AAAA,IAC1E;AACA,WAAO;AAAA,MACL,oBAAoB;AAAA,QAClB,UAAU;AAAA,QACV,OAAO;AAAA,QACP,MAAM;AAAA,MACR,CAAC;AAAA,MACD,GAAG,OAAO;AAAA,QAAI,CAAC,UAAU,UACvB,oBAAoB;AAAA,UAClB;AAAA,UACA,OAAO;AAAA,UACP,UAAU,mBAAmB;AAAA,UAC7B,MAAM,SAAS,QAAQ,CAAC;AAAA,QAC1B,CAAC;AAAA,MACH;AAAA,MACA,oBAAoB;AAAA,QAClB,UAAU;AAAA,QACV,OAAO;AAAA,QACP,UAAU,mBAAmB;AAAA,QAC7B,MAAM;AAAA,MACR,CAAC;AAAA,IACH;AAAA,EACF;AACA,QAAM,SAAS;AAAA,IACb,CAAC,GAAG,GAAG,IAAI;AAAA,IACX;AAAA,MACE,EAAE,QAAQ,IAAI;AAAA,MACd,QAAQ;AAAA,QACN,QAAQ;AAAA,UACN,CAAC,IAAI,EAAE;AAAA,UACP,CAAC,GAAG,EAAE;AAAA,UACN,CAAC,GAAG,CAAC;AAAA,UACL,CAAC,GAAG,CAAC;AAAA,UACL,CAAC,IAAI,CAAC;AAAA,UACN,CAAC,IAAI,CAAC;AAAA,QACR;AAAA,MACF,CAAC;AAAA,IACH;AAAA,EACF;AACA,QAAM,UAAwB;AAAA,IAC5B,CAAC,MAAM,MAAM,CAAC;AAAA,IACd,CAAC,KAAK,MAAM,CAAC;AAAA,IACb,CAAC,GAAG,KAAK,CAAC;AAAA,EACZ;AACA,SAAOA;AAAA,IACL;AAAA,IACA;AAAA,IACA,GAAG,QAAQ,IAAI,CAAC,WAAW,OAAO,EAAE,MAAM,CAAC,KAAK,KAAK,IAAI,GAAG,OAAO,CAAC,CAAC;AAAA,EACvE;AACA,SAAO;AAAA,IACL,oBAAoB;AAAA,MAClB,UAAU;AAAA,MACV,OAAO;AAAA,MACP,MAAM;AAAA,IACR,CAAC;AAAA,IACD,GAAG,QAAQ;AAAA,MAAI,CAAC,CAAC,GAAG,CAAC,GAAG,UACtB,oBAAoB;AAAA,QAClB,UAAU,OAAO,EAAE,MAAM,CAAC,MAAM,KAAK,CAAC,GAAG,QAAQ,CAAC,IAAI,MAAM,GAAG,GAAG,EAAE,CAAC;AAAA,QACrE,OAAO;AAAA,QACP,UAAU,mBAAmB;AAAA,QAC7B,MAAM,kBAAkB,QAAQ,CAAC;AAAA,MACnC,CAAC;AAAA,IACH;AAAA,EACF;AACF;AAEO,SAAS,sBAAsB;AAAA,EACpC;AAAA,EACA;AACF,GAA4E;AAC1E,QAAM,SACJ,UAAU,SAAS,eACf,gBAAgB,SAAS,IACzB,UAAU,SAAS,iBAAiB,UAAU,SAAS,kBACrD,mBAAmB,SAAS,IAC5B,UAAU,SAAS,oBACjB,UAAU,SAAS,mBACnB,gBAAgB,SAAS,IACzB,kBAAkB,SAAS;AACrC,MACE,mBAAmB,UACnB,UAAU,SAAS,iBACnB,UAAU,SAAS,iBACnB;AACA,UAAM,OAAO,uBAAuB,SAAS;AAC7C,UAAM,OAAO;AAAA,MACX,SAAS;AAAA,QACP,QAAQ,iBAAiB,IAAI;AAAA,QAC7B,QAAQ;AAAA,QACR,QAAQ,CAAC,GAAG,GAAG,OAAO,GAAG;AAAA,QACzB,UAAU;AAAA,MACZ,CAAC;AAAA,MACD,GAAG,MAAM;AAAA,QAAK,EAAE,QAAQ,EAAE;AAAA,QAAG,CAAC,GAAG,UAC/B,SAAS;AAAA,UACP,QAAQ,iBAAiB,IAAI,MAAM,QAAQ;AAAA,UAC3C,QAAQ;AAAA,UACR,QAAQ,CAAC,GAAG,GAAG,OAAO,MAAM,QAAQ,GAAG;AAAA,UACvC,UAAU;AAAA,QACZ,CAAC;AAAA,MACH;AAAA,IACF;AACA,WAAO;AAAA,MACL,oBAAoB;AAAA,QAClB,UAAU;AAAA,QACV,OAAO;AAAA,QACP,MAAM;AAAA,MACR,CAAC;AAAA,IACH;AAAA,EACF;AACA,SAAO;AACT;;;AC1UO,SAAS,uBAAuB,MAAoB;AACzD,QAAM,oBAAoB,CAAC,CAAC;AAC5B,WAAS,QAAQ,GAAG,QAAQ,KAAK,QAAQ;AACvC,sBAAkB;AAAA,MAChB,kBAAkB,QAAQ,CAAC,IACzB,KAAK,MAAM,GAAG,SAAS,KAAK,KAAK,GAAI,KAAK,QAAQ,CAAC,CAAE,CAAC;AAAA,IAC1D;AACF,QAAM,SAAS,kBAAkB,GAAG,EAAE;AACtC,QAAM,YAAY,KAAK,IAAI,IAAI,SAAS,CAAC;AACzC,QAAM,UAAU,CAAC,GAAG,mBAAmB,SAAS,CAAC;AACjD,WAAS,OAAO,GAAG,QAAQ,IAAI,QAAQ;AACrC,UAAM,WAAY,YAAY,OAAQ;AACtC,YAAQ,KAAK,UAAU,SAAS,QAAQ;AAAA,EAC1C;AACA,QAAM,YAAY,QACf,KAAK,CAAC,GAAG,MAAM,IAAI,CAAC,EACpB;AAAA,IACC,CAAC,UAAU,OAAO,WAChB,UAAU,KAAK,WAAW,OAAO,QAAQ,CAAC,IAAK;AAAA,EACnD;AACF,MAAI,UAAU;AACd,QAAM,cAAc,UAAU,IAAI,CAAC,aAAyB;AAC1D,WACE,UAAU,KAAK,SAAS,KACxB,WAAW,kBAAkB,UAAU,CAAC;AAExC;AACF,UAAM,YACH,WAAW,kBAAkB,OAAO,MACpC,kBAAkB,UAAU,CAAC,IAAK,kBAAkB,OAAO;AAC9D,WAAO;AAAA,MACL,KAAK,OAAO;AAAA,MACZ,MAAM,SAAS,KAAK,UAAU,CAAC,GAAI,KAAK,OAAO,CAAE,GAAG,QAAQ;AAAA,IAC9D;AAAA,EACF,CAAC;AACD,SAAO,EAAE,MAAM,aAAa,WAAW,QAAQ,UAAU;AAC3D;;;ACvCO,SAAS,gBAAgB;AAAA,EAC9B;AAAA,EACA;AAAA,EACA,SAAS;AAAA,EACT;AAAA,EACA;AAAA,EACA;AACF,GAOc;AACZ,QAAM,YAAsB,CAAC;AAC7B,QAAM,UAAoB,CAAC;AAC3B,aAAW,SAAS,QAAQ;AAC1B,UAAM,SAAS,IAAI,MAAM,OAAO,MAAM,MAAM,QAAQ,MAAM,CAAC;AAC3D,aAAS,OAAO,GAAG,OAAO,gBAAgB,QAAQ;AAChD,YAAM,QAAS,OAAO,KAAK,KAAK,IAAK;AACrC,gBAAU;AAAA,QACR,GAAG;AAAA,UACD;AAAA,UACA;AAAA,YACE,MAAM,MAAM,QAAS,WAAW,KAAK,IAAI,KAAK,IAAK,CAAC;AAAA,YACpD,MAAM,MAAM,UAAW,WAAW,KAAK,IAAI,KAAK,IAAK,CAAC;AAAA,UACxD;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACA,WAAS,OAAO,GAAG,OAAO,OAAO,SAAS,GAAG,QAAQ;AACnD,aAAS,OAAO,GAAG,OAAO,gBAAgB,QAAQ;AAChD,YAAM,IAAI,OAAO,iBAAiB;AAClC,YAAM,IAAI,OAAO,kBAAmB,OAAO,KAAK;AAChD,YAAM,IAAI,IAAI;AACd,YAAM,IAAI,IAAI;AACd,cAAQ,KAAK,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC;AAAA,IAC/B;AAAA,EACF;AACA,QAAM,cAAc,UAAU,SAAS;AACvC,YAAU,KAAK,GAAG,IAAI,OAAO,CAAC,EAAG,OAAO,MAAM,OAAO,CAAC,EAAG,QAAQ,MAAM,CAAC,CAAC;AACzE,QAAM,YAAY,UAAU,SAAS;AACrC,YAAU;AAAA,IACR,GAAG,IAAI,OAAO,GAAG,EAAE,EAAG,OAAO,MAAM,OAAO,GAAG,EAAE,EAAG,QAAQ,MAAM,CAAC;AAAA,EACnE;AACA,QAAM,YAAY,OAAO,SAAS,KAAK;AACvC,WAAS,OAAO,GAAG,OAAO,gBAAgB,QAAQ;AAChD,UAAM,QAAQ,OAAO,KAAK;AAC1B,YAAQ;AAAA,MACN;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,WAAW;AAAA,MACX,WAAW;AAAA,IACb;AAAA,EACF;AACA,SAAO,EAAE,MAAM,WAAW,SAAS,OAAO,QAAQ,KAAK;AACzD;;;ACjDA,SAAS,gBAAgB,OAA2B;AAClD,MAAI,CAAC,iBAAiB,KAAK,KAAK;AAC9B,UAAM,IAAI,MAAM,4CAA4C;AAC9D,SAAO;AAAA,IACL,SAAS,MAAM,MAAM,GAAG,CAAC,GAAG,EAAE,IAAI;AAAA,IAClC,SAAS,MAAM,MAAM,GAAG,CAAC,GAAG,EAAE,IAAI;AAAA,IAClC,SAAS,MAAM,MAAM,GAAG,CAAC,GAAG,EAAE,IAAI;AAAA,IAClC;AAAA,EACF;AACF;AAEA,SAAS,wBAAwB,YAAqC;AACpE,aAAW,aAAa,CAAC,WAAW,YAAY,WAAW,UAAU,GAAG;AACtE,UAAM,aAAa;AAAA,MACjB,UAAU;AAAA,MACV,UAAU;AAAA,MACV,UAAU;AAAA,IACZ;AACA,QAAI,UAAU,SAAS;AACrB,iBAAW;AAAA,QACT,UAAU;AAAA,QACV,UAAU;AAAA,QACV,UAAU;AAAA,MACZ;AACF,QACE,UAAU,SAAS,iBACnB,UAAU,SAAS,iBACnB;AACA,YAAM,WAAW,UAAU,YAAY;AACvC,YAAM,QAAQ,UAAU,SAAS,UAAU;AAC3C,iBAAW,KAAK,UAAU,UAAU,UAAU,cAAc,KAAK;AACjE,UACE,CAAC,OAAO,UAAU,QAAQ,KAC1B,WAAW,KACX,WAAW,MACX,UAAU,cAAc,UAAU,YAClC,QAAQ,UAAU,cAClB,KAAK;AAAA,QACH,UAAU,aAAa,UAAU,cAAc,WAAW,KAAK;AAAA,MACjE,IAAI,QACJ,UAAU,gBAAgB,UAAU,aACpC,UAAU,gBAAgB,UAAU,WAAW;AAE/C,cAAM,IAAI,MAAM,qDAAqD;AACvE,UACG,aAAa,MACX,WAAW,aAAa,SAAS,kBAChC,WAAW,aAAa,WAAW,UAAU,eAChD,WAAW,MACT,WAAW,aAAa,SAAS,iBAChC,WAAW,aAAa,MAAM,WAAW,YACzC,WAAW,aAAa,MAAM;AAAA,QAC5B,CAAC,SAAS,KAAK,WAAW,UAAU;AAAA,MACtC;AAEJ,cAAM,IAAI;AAAA,UACR;AAAA,QACF;AAAA,IACJ;AACA,QACE,WAAW;AAAA,MACT,CAAC,cAAc,CAAC,OAAO,SAAS,SAAS,KAAK,aAAa;AAAA,IAC7D;AAEA,YAAM,IAAI,MAAM,kDAAkD;AACpE,SACG,UAAU,SAAS,oBAClB,UAAU,SAAS,sBACpB,CAAC,OAAO,UAAU,UAAU,QAAQ,KACnC,UAAU,WAAW,KACrB,CAAC,OAAO,SAAS,UAAU,KAAK,KAChC,UAAU,SAAS;AAErB,YAAM,IAAI;AAAA,QACR;AAAA,MACF;AAAA,EACJ;AACA,QAAM,eAAe,WAAW;AAChC,QAAM,YACJ,aAAa,SAAS,iBAClB,CAAC,aAAa,QAAQ,IACtB,aAAa,MAAM,IAAI,CAAC,SAAS,KAAK,QAAQ;AACpD,MACE,UAAU,WAAW,KACrB,UAAU,KAAK,CAAC,aAAa,CAAC,OAAO,SAAS,QAAQ,KAAK,YAAY,CAAC;AAExE,UAAM,IAAI,MAAM,6CAA6C;AAC/D,MAAI,aAAa,SAAS,eAAe;AACvC,QACE,CAAC,OAAO,SAAS,aAAa,SAAS,KACvC,aAAa,MAAM,KAAK,CAAC,SAAS,KAAK,WAAW,aAAa,SAAS;AAExE,YAAM,IAAI,MAAM,yCAAyC;AAC3D,eAAW,aAAa,CAAC,WAAW,YAAY,WAAW,UAAU,GAAG;AACtE,UACE,EAAE,cAAc,eACf,UAAU,YAAY,OAAO,aAAa,MAAM;AAEjD,cAAM,IAAI,MAAM,sDAAsD;AACxE,UACE,WAAW,aACX,aAAa,MAAM,KAAK,CAAC,SAAS,KAAK,WAAW,UAAU,KAAK;AAEjE,cAAM,IAAI,MAAM,+CAA+C;AAAA,IACnE;AAAA,EACF;AACF;AAGO,SAAS,kBAAkB;AAAA,EAChC;AAAA,EACA;AAAA,EACA,iBAAiB;AAAA,EACjB;AAAA,EACA;AACF,GAOgB;AACd,0BAAwB,UAAU;AAClC,MACE,CAAC,OAAO,UAAU,cAAc,KAChC,iBAAiB,KACjB,iBAAiB;AAEjB,UAAM,IAAI,MAAM,iDAAiD;AACnE,QAAM,SAAS,sBAAsB,MAAM,EAAE,eAAe,YAAY,CAAC;AACzE,QAAM,eAAe,WAAW;AAChC,QAAM,iBACJ,aAAa,SAAS,iBAAiB,aAAa,WAAW;AAIjE,QAAM,SACJ,WAAW,WAAW,aAAa,WAAW,WAAW,QAAQ;AACnE,QAAM,SACJ,WAAW,WAAW,aAAa,WAAW,WAAW,QAAQ;AACnE,QAAM,SACJ,WAAW,UAAU,aAAa,SAAS,gBACvC,uBAAuB,IAAI,IAC3B;AACN,QAAM,eAAe,SACjB,sBAAsB,OAAO,MAAM,EAAE,eAAe,YAAY,CAAC,IACjE;AACJ,QAAM,SACJ,aAAa,SAAS,iBAClB;AAAA,IACE,gBAAgB;AAAA,MACd;AAAA,MACA,UAAU,aAAa;AAAA,MACvB;AAAA,MACA,OAAO,gBAAgB,aAAa,KAAK;AAAA,MACzC,MAAM;AAAA,IACR,CAAC;AAAA,EACH,IACA,aAAa,MAAM,IAAI,CAAC,MAAM,UAAU;AACtC,UAAM,gBAAgB,SAAS,aAAa,MAAM,SAAS,KAAK;AAGhE,UAAM,eAAe,KAAK;AAAA,MACxB,aAAa;AAAA,MACb,UAAU,aAAa;AAAA,MACvB,UAAU,aAAa;AAAA,MACvB,MAAM,KAAK,IAAI,GAAG,aAAa,MAAM,IAAI,CAACC,UAASA,MAAK,QAAQ,CAAC;AAAA,IACnE;AACA,UAAM,aAAa,CAAC,aAClB,WAAW,YAAY,IAAI,IAAI;AACjC,UAAM,aAAa,SACf;AAAA,MACE,aAAa,IAAI,CAAC,OAAO,cAAc;AACrC,cAAM,WAAW,OAAO,UAAU,SAAS;AAC3C,cAAM,QACJ,IAAI,WAAW,KAAK,IAAI,GAAG,WAAW,OAAO,SAAS,CAAC;AACzD,cAAM,MACJ,IACA;AAAA,UACE,KAAK;AAAA,YACH;AAAA,aACC,OAAO,SAAS,YAAY,OAAO;AAAA,UACtC;AAAA,QACF;AACF,cAAM,QACJ,iBACE,UAAU,aAAa,aAAa,gBACpC,UACA,UAAU,aAAa,aAAa,gBAAgB;AACxD,eAAO;AAAA,UACL,MAAM;AAAA,UACN,MAAM,MAAM,QAAQ,gBAAgB,KAAK;AAAA,QAC3C;AAAA,MACF,CAAC;AAAA,IACH,IACA;AACJ,WAAO,gBAAgB;AAAA,MACrB,QAAQ;AAAA,MACR,UAAU,KAAK;AAAA,MACf,SAAS,SAAS,IAAI,iBAAiB,aAAa;AAAA,MACpD;AAAA,MACA,OAAO,gBAAgB,KAAK,KAAK;AAAA,MACjC,MAAM,QAAQ,QAAQ,CAAC;AAAA,IACzB,CAAC;AAAA,EACH,CAAC;AACP,aAAW,CAAC,OAAO,SAAS,KAAK;AAAA,IAC/B,WAAW;AAAA,IACX,WAAW;AAAA,EACb,EAAE,QAAQ,GAAG;AACX,UAAM,QAAQ,UAAU,IAAI,OAAO,CAAC,IAAK,OAAO,GAAG,EAAE;AACrD,UAAM,QAAQ,sBAAsB,EAAE,WAAW,eAAe,CAAC;AACjE,WAAO;AAAA,MACL,GAAG,MAAM;AAAA,QAAI,CAAC,SACZ,mBAAmB;AAAA,UACjB,MAAM,EAAE,GAAG,MAAM,MAAM,GAAG,UAAU,IAAI,MAAM,GAAG,IAAI,KAAK,IAAI,GAAG;AAAA,UACjE;AAAA,UACA,OAAO,UAAU;AAAA,UACjB,eAAe,uBAAuB,SAAS;AAAA,QACjD,CAAC;AAAA,MACH;AAAA,IACF;AAAA,EACF;AACA,SAAO;AACT;","names":["jscad","normal","cylinder","sphere","cuboid","jscad","subtract","union","jscad","jscad","subtract","wire"]}
package/dist/index.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
2
  import { AnyCircuitElement, PcbSmtPad, PcbPlatedHole } from 'circuit-json';
3
3
  import * as _jscad_modeling_src_geometries_types from '@jscad/modeling/src/geometries/types';
4
- import { ButtonScrewModelPropsInput, CableGrommetModelPropsInput, ClampingShaftCollarModelPropsInput, CompressionSpringModelPropsInput, FlangedBushingModelPropsInput, FlatHeadScrewModelPropsInput, SpurGearModelPropsInput, HelicalGearModelPropsInput, HexBoltModelPropsInput, HexNutModelPropsInput, HexSocketBoltModelPropsInput, NemaMotorModelPropsInput, PanScrewModelPropsInput, PlainBushingModelPropsInput, RigidCouplerModelPropsInput, ShaftCollarModelPropsInput, SheetMetalModelPropsInput, ThreadedRodModelPropsInput, TSlotExtrusionModelPropsInput, TSlotGussetModelPropsInput, TSlotInsideCornerModelPropsInput, WormGearModelPropsInput } from '@tscircuit/modelprinter';
4
+ import { BallBearingModelPropsInput, ButtonScrewModelPropsInput, CableGrommetModelPropsInput, ClampingShaftCollarModelPropsInput, CompressionSpringModelPropsInput, FlangedBushingModelPropsInput, FlatHeadScrewModelPropsInput, SpurGearModelPropsInput, HelicalGearModelPropsInput, HexBoltModelPropsInput, HexNutModelPropsInput, HexSocketBoltModelPropsInput, NemaMotorModelPropsInput, PanScrewModelPropsInput, PlainBushingModelPropsInput, RigidCouplerModelPropsInput, ShaftCollarModelPropsInput, SheetMetalModelPropsInput, ThreadedRodModelPropsInput, TSlotExtrusionModelPropsInput, TSlotGussetModelPropsInput, TSlotInsideCornerModelPropsInput, WormGearModelPropsInput } from '@tscircuit/modelprinter';
5
5
 
6
6
  declare const A01005: ({ color }: {
7
7
  color?: string | undefined;
@@ -1226,6 +1226,35 @@ declare const MelfResistor: ({ size, footprint, }: {
1226
1226
  footprint?: string;
1227
1227
  }) => react_jsx_runtime.JSX.Element;
1228
1228
 
1229
+ interface BallBearingMeshPart {
1230
+ name: string;
1231
+ color: string;
1232
+ mesh: {
1233
+ positions: number[];
1234
+ indices: number[];
1235
+ };
1236
+ /** Only rolling elements have centers/radii; useful to inspect nominal contact. */
1237
+ center?: [number, number, number];
1238
+ radius?: number;
1239
+ }
1240
+ interface BallBearingMesh {
1241
+ positions: number[];
1242
+ indices: number[];
1243
+ parts: BallBearingMeshPart[];
1244
+ }
1245
+ type BallBearingMeshOptions = {
1246
+ segments?: number;
1247
+ };
1248
+ /** ISO/de-facto envelope, nominal grooved races/balls/cage, and independently selected faces. */
1249
+ declare function createBallBearingMesh(input?: BallBearingModelPropsInput, options?: BallBearingMeshOptions): BallBearingMesh;
1250
+
1251
+ type BallBearingProps = BallBearingModelPropsInput & {
1252
+ color?: string;
1253
+ };
1254
+ declare function createBallBearingGeom(input?: BallBearingModelPropsInput): _jscad_modeling_src_geometries_types.Geom3;
1255
+ /** Separately colored physical parts retain their individual closed surfaces. */
1256
+ declare function BallBearing({ color, ...props }: BallBearingProps): react_jsx_runtime.JSX.Element;
1257
+
1229
1258
  /** Indexed counterclockwise triangles in millimeters. */
1230
1259
  interface ButtonScrewMesh {
1231
1260
  positions: number[];
@@ -1713,4 +1742,4 @@ type WormGearProps = WormGearModelPropsInput & {
1713
1742
  declare function createWormGearGeom(input: WormGearModelPropsInput): _jscad_modeling_src_geometries_types.Geom3;
1714
1743
  declare function WormGear({ color, ...props }: WormGearProps): react_jsx_runtime.JSX.Element;
1715
1744
 
1716
- export { A01005, A0201, A0402, A0603, A0805, A1206, A1210, A2010, A2512, AxialCapacitor, BGA, ButtonScrew, type ButtonScrewMesh, type ButtonScrewMeshOptions, type ButtonScrewProps, CableGrommet, type CableGrommetMesh, type CableGrommetMeshOptions, type CableGrommetProps, CeramicChipAntenna, ChipBody, type ChipBodyProps, ClampingShaftCollar, type ClampingShaftCollarMesh, type ClampingShaftCollarProps, CompressionSpring, type CompressionSpringMesh, type CompressionSpringMeshOptions, type CompressionSpringProps, Crystal, type CrystalProps, DFN, DO219AD, type DO219ADProps, DPAK, type DPAKProps, Display, ElectrolyticCapacitor, type ElectrolyticCapacitorProps, ExtrudedPads, FPC, type FPCProps, FemaleHeader, FemaleHeaderRow, FlangedBushing, type FlangedBushingMesh, type FlangedBushingProps, FlatHeadScrew, type FlatHeadScrewMesh, type FlatHeadScrewMeshOptions, type FlatHeadScrewProps, FlexScreen, type FlexScreenAspectRatio, type FlexScreenOrientation, type FlexScreenProps, FootprintPad, FootprintPlatedHole, Footprinter3d, GullWingBody, type GullWingBodyProps, HC49, type HC49Props, HelicalGear, type HelicalGearMesh, type HelicalGearProps, HexBolt, type HexBoltMesh, type HexBoltMeshOptions, type HexBoltProps, HexNut, type HexNutMesh, type HexNutMeshOptions, type HexNutProps, HexSocketBolt, type HexSocketBoltMesh, type HexSocketBoltProps, JSTPH2_0mm, JSTXH2_5mm, type JSTXH2_5mmProps, JSTZH1_5mm, JstSh, LGA, type LGAProps, LQFP, type LQFPProps, Led2835, type Led2835Props, Led5050, type Led5050Props, MELF, type MELFProps, MINIMELF, type MINIMELFProps, MS012, MS013, MSOP, type MSOPProps, MelfResistor, type MelfResistorSize, MicroMELF, type MicroMELFProps, MountedPcbModule, NEMA17, NEMA23, NEMA8, type NemaFrameMotorProps, NemaMotor, type NemaMotorProps, PanScrew, type PanScrewMesh, type PanScrewMeshOptions, type PanScrewProps, PinHeader, PinRow, PlainBushing, type PlainBushingMesh, type PlainBushingProps, Potentiometer, type PotentiometerLead, type PotentiometerProps, QFN, type QFNProps, QFP, RJ45, type RJ45Props, type ResolvedFlexScreenSize, RigidCoupler, type RigidCouplerMesh, type RigidCouplerProps, SMA, SMB, SMC, SMF, SOD123, SOD123F, SOD123FL, type SOD123Props, SOD123W, type SOD123WProps, SOD128, SOD323, SOD323F, SOD323FL, SOD323HE, type SOD323HEProps, SOD523, SOD723, SOD882, SOD923, SOIC, type SOICProps, SOT143, SOT223, type SOT223Props, SOT233P, SOT23W, SOT323, SOT363, SOT457, SOT563, SOT723, SOT886, SOT89, type SOT89Props, SOT963, SSOP, type SSOPProps, Screen, type ScreenProps, ShaftCollar, type ShaftCollarMesh, type ShaftCollarProps, SheetMetal, type SheetMetalMesh, type SheetMetalProps, SmdChipLead, type SmdChipLeadProps, SmdLED, type SmdLeadPad, type SmdLedSize, SmdPinHeader, type SmdPinHeaderProps, SmdPushButton, type SmdPushButtonProps, SmdSlideSwitch, SpurGear, type SpurGearMesh, type SpurGearProps, StampBoard, TO220, type TO220Lead, type TO220Props, TO277, type TO277Props, TO92, type TO92Lead, type TO92Props, TQFP, TSlotExtrusion, type TSlotExtrusionMesh, type TSlotExtrusionProps, TSlotGusset, type TSlotGussetMesh, type TSlotGussetProps, TSlotInsideCorner, type TSlotInsideCornerMesh, type TSlotInsideCornerProps, TantalumCapacitor, type TantalumCase, ThreadedRod, type ThreadedRodMesh, type ThreadedRodMeshOptions, type ThreadedRodProps, Tssop, type TssopProps, TwoPadCrystal, type TwoPadCrystalPackage, UsbCMidmount, VSSOP, WormGear, type WormGearMesh, type WormGearProps, createButtonScrewGeom, createButtonScrewMesh, createCableGrommetGeom, createCableGrommetMesh, createClampingShaftCollarGeom, createClampingShaftCollarMesh, createCompressionSpringGeom, createCompressionSpringMesh, createFlangedBushingGeom, createFlangedBushingMesh, createFlatHeadScrewGeom, createFlatHeadScrewMesh, createHelicalGearGeom, createHelicalGearMesh, createHexBoltGeom, createHexBoltMesh, createHexNutGeom, createHexNutMesh, createHexSocketBoltGeom, createHexSocketBoltMesh, createPanScrewGeom, createPanScrewMesh, createPlainBushingGeom, createPlainBushingMesh, createRigidCouplerGeom, createRigidCouplerMesh, createShaftCollarGeom, createShaftCollarMesh, createSheetMetalGeom, createSheetMetalMesh, createSpurGearGeom, createSpurGearMesh, createTSlotExtrusionGeom, createTSlotExtrusionMesh, createTSlotGussetGeom, createTSlotGussetMesh, createTSlotInsideCornerGeom, createTSlotInsideCornerMesh, createThreadedRodGeom, createThreadedRodMesh, createWormGearGeom, createWormGearMesh, isJstShFootprint, melfResistorSizes, resolveFlexScreenSize, smdLedDimensions, tantalumCases, twoPadCrystalPackages };
1745
+ export { A01005, A0201, A0402, A0603, A0805, A1206, A1210, A2010, A2512, AxialCapacitor, BGA, BallBearing, type BallBearingMesh, type BallBearingMeshOptions, type BallBearingMeshPart, type BallBearingProps, ButtonScrew, type ButtonScrewMesh, type ButtonScrewMeshOptions, type ButtonScrewProps, CableGrommet, type CableGrommetMesh, type CableGrommetMeshOptions, type CableGrommetProps, CeramicChipAntenna, ChipBody, type ChipBodyProps, ClampingShaftCollar, type ClampingShaftCollarMesh, type ClampingShaftCollarProps, CompressionSpring, type CompressionSpringMesh, type CompressionSpringMeshOptions, type CompressionSpringProps, Crystal, type CrystalProps, DFN, DO219AD, type DO219ADProps, DPAK, type DPAKProps, Display, ElectrolyticCapacitor, type ElectrolyticCapacitorProps, ExtrudedPads, FPC, type FPCProps, FemaleHeader, FemaleHeaderRow, FlangedBushing, type FlangedBushingMesh, type FlangedBushingProps, FlatHeadScrew, type FlatHeadScrewMesh, type FlatHeadScrewMeshOptions, type FlatHeadScrewProps, FlexScreen, type FlexScreenAspectRatio, type FlexScreenOrientation, type FlexScreenProps, FootprintPad, FootprintPlatedHole, Footprinter3d, GullWingBody, type GullWingBodyProps, HC49, type HC49Props, HelicalGear, type HelicalGearMesh, type HelicalGearProps, HexBolt, type HexBoltMesh, type HexBoltMeshOptions, type HexBoltProps, HexNut, type HexNutMesh, type HexNutMeshOptions, type HexNutProps, HexSocketBolt, type HexSocketBoltMesh, type HexSocketBoltProps, JSTPH2_0mm, JSTXH2_5mm, type JSTXH2_5mmProps, JSTZH1_5mm, JstSh, LGA, type LGAProps, LQFP, type LQFPProps, Led2835, type Led2835Props, Led5050, type Led5050Props, MELF, type MELFProps, MINIMELF, type MINIMELFProps, MS012, MS013, MSOP, type MSOPProps, MelfResistor, type MelfResistorSize, MicroMELF, type MicroMELFProps, MountedPcbModule, NEMA17, NEMA23, NEMA8, type NemaFrameMotorProps, NemaMotor, type NemaMotorProps, PanScrew, type PanScrewMesh, type PanScrewMeshOptions, type PanScrewProps, PinHeader, PinRow, PlainBushing, type PlainBushingMesh, type PlainBushingProps, Potentiometer, type PotentiometerLead, type PotentiometerProps, QFN, type QFNProps, QFP, RJ45, type RJ45Props, type ResolvedFlexScreenSize, RigidCoupler, type RigidCouplerMesh, type RigidCouplerProps, SMA, SMB, SMC, SMF, SOD123, SOD123F, SOD123FL, type SOD123Props, SOD123W, type SOD123WProps, SOD128, SOD323, SOD323F, SOD323FL, SOD323HE, type SOD323HEProps, SOD523, SOD723, SOD882, SOD923, SOIC, type SOICProps, SOT143, SOT223, type SOT223Props, SOT233P, SOT23W, SOT323, SOT363, SOT457, SOT563, SOT723, SOT886, SOT89, type SOT89Props, SOT963, SSOP, type SSOPProps, Screen, type ScreenProps, ShaftCollar, type ShaftCollarMesh, type ShaftCollarProps, SheetMetal, type SheetMetalMesh, type SheetMetalProps, SmdChipLead, type SmdChipLeadProps, SmdLED, type SmdLeadPad, type SmdLedSize, SmdPinHeader, type SmdPinHeaderProps, SmdPushButton, type SmdPushButtonProps, SmdSlideSwitch, SpurGear, type SpurGearMesh, type SpurGearProps, StampBoard, TO220, type TO220Lead, type TO220Props, TO277, type TO277Props, TO92, type TO92Lead, type TO92Props, TQFP, TSlotExtrusion, type TSlotExtrusionMesh, type TSlotExtrusionProps, TSlotGusset, type TSlotGussetMesh, type TSlotGussetProps, TSlotInsideCorner, type TSlotInsideCornerMesh, type TSlotInsideCornerProps, TantalumCapacitor, type TantalumCase, ThreadedRod, type ThreadedRodMesh, type ThreadedRodMeshOptions, type ThreadedRodProps, Tssop, type TssopProps, TwoPadCrystal, type TwoPadCrystalPackage, UsbCMidmount, VSSOP, WormGear, type WormGearMesh, type WormGearProps, createBallBearingGeom, createBallBearingMesh, createButtonScrewGeom, createButtonScrewMesh, createCableGrommetGeom, createCableGrommetMesh, createClampingShaftCollarGeom, createClampingShaftCollarMesh, createCompressionSpringGeom, createCompressionSpringMesh, createFlangedBushingGeom, createFlangedBushingMesh, createFlatHeadScrewGeom, createFlatHeadScrewMesh, createHelicalGearGeom, createHelicalGearMesh, createHexBoltGeom, createHexBoltMesh, createHexNutGeom, createHexNutMesh, createHexSocketBoltGeom, createHexSocketBoltMesh, createPanScrewGeom, createPanScrewMesh, createPlainBushingGeom, createPlainBushingMesh, createRigidCouplerGeom, createRigidCouplerMesh, createShaftCollarGeom, createShaftCollarMesh, createSheetMetalGeom, createSheetMetalMesh, createSpurGearGeom, createSpurGearMesh, createTSlotExtrusionGeom, createTSlotExtrusionMesh, createTSlotGussetGeom, createTSlotGussetMesh, createTSlotInsideCornerGeom, createTSlotInsideCornerMesh, createThreadedRodGeom, createThreadedRodMesh, createWormGearGeom, createWormGearMesh, isJstShFootprint, melfResistorSizes, resolveFlexScreenSize, smdLedDimensions, tantalumCases, twoPadCrystalPackages };