@tscircuit/footprinter 0.0.299 → 0.0.301

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -24,6 +24,7 @@ __export(fn_exports, {
24
24
  micromelf: () => micromelf,
25
25
  minimelf: () => minimelf,
26
26
  mlp: () => mlp,
27
+ mountedpcbmodule: () => mountedpcbmodule,
27
28
  ms012: () => ms012,
28
29
  ms013: () => ms013,
29
30
  msop: () => msop,
@@ -5086,14 +5087,14 @@ var sot89_3 = (parameters) => {
5086
5087
  const pads = [];
5087
5088
  const padGap = Number.parseFloat(parameters.p);
5088
5089
  const padWidth = Number.parseFloat(parameters.pw);
5089
- const length58 = Number.parseFloat(parameters.w);
5090
+ const length59 = Number.parseFloat(parameters.w);
5090
5091
  const padHeight = Number.parseFloat(parameters.pl);
5091
5092
  const centerExtra = 0.175;
5092
5093
  const outerPadXShift = (padHeight - (padHeight + centerExtra)) / 2;
5093
5094
  pads.push(
5094
- rectpad(1, -length58 / 2 + outerPadXShift, padGap, padHeight, padWidth),
5095
- rectpad(2, -length58 / 2, 0, padHeight + centerExtra, padWidth),
5096
- rectpad(3, -length58 / 2 + outerPadXShift, -padGap, padHeight, padWidth)
5095
+ rectpad(1, -length59 / 2 + outerPadXShift, padGap, padHeight, padWidth),
5096
+ rectpad(2, -length59 / 2, 0, padHeight + centerExtra, padWidth),
5097
+ rectpad(3, -length59 / 2 + outerPadXShift, -padGap, padHeight, padWidth)
5097
5098
  );
5098
5099
  const silkscreenRefText = silkscreenRef(0, 0, 0.3);
5099
5100
  const width = Number.parseFloat(parameters.w) / 2 - 1;
@@ -5133,7 +5134,7 @@ var sot89_5 = (parameters) => {
5133
5134
  const pads = [];
5134
5135
  const padGap = Number.parseFloat(parameters.p);
5135
5136
  const padWidth = Number.parseFloat(parameters.pw);
5136
- const length58 = Number.parseFloat(parameters.w);
5137
+ const length59 = Number.parseFloat(parameters.w);
5137
5138
  pads.push(
5138
5139
  rectpad(1, -1.85, -1.5, 1.5, 0.7),
5139
5140
  rectpad(2, -1.85, 1.5, 1.5, 0.7),
@@ -8308,17 +8309,277 @@ var m2host = (raw_params) => {
8308
8309
  };
8309
8310
  };
8310
8311
 
8311
- // src/fn/to92l.ts
8312
+ // src/fn/mountedpcbmodule.ts
8313
+ import { length as length58 } from "circuit-json";
8312
8314
  import { z as z76 } from "zod";
8313
- var to92l_def = base_def.extend({
8315
+ var mountedpcbmodule_def = base_def.extend({
8314
8316
  fn: z76.string(),
8315
- num_pins: z76.number().default(3),
8316
- inline: z76.boolean().default(false),
8317
- p: z76.string().default("1.27mm"),
8318
- id: z76.string().default("0.75mm"),
8319
- od: z76.string().default("1.3mm"),
8320
- w: z76.string().default("4.8mm"),
8321
- h: z76.string().default("4.0mm")
8317
+ numPins: z76.number().optional().default(0),
8318
+ rows: z76.union([z76.string(), z76.number()]).transform((val) => Number(val)).optional().default(1).describe("number of rows"),
8319
+ p: length58.default("2.54mm").describe("pitch"),
8320
+ id: length58.default("1.0mm").describe("inner diameter"),
8321
+ od: length58.default("1.5mm").describe("outer diameter"),
8322
+ male: z76.boolean().optional().describe("the module uses male headers"),
8323
+ female: z76.boolean().optional().describe("the module uses female headers"),
8324
+ smd: z76.boolean().optional().describe("surface mount device"),
8325
+ pinlabeltextalignleft: z76.boolean().optional().default(false),
8326
+ pinlabeltextaligncenter: z76.boolean().optional().default(false),
8327
+ pinlabeltextalignright: z76.boolean().optional().default(false),
8328
+ pinlabelverticallyinverted: z76.boolean().optional().default(false),
8329
+ pinlabelorthogonal: z76.boolean().optional().default(false),
8330
+ nopinlabels: z76.boolean().optional().default(false).describe("omit silkscreen pin labels"),
8331
+ doublesidedpinlabel: z76.boolean().optional().default(false).describe("add silkscreen pins in top and bottom layers"),
8332
+ bottomsidepinlabel: z76.boolean().optional().default(false).describe(
8333
+ "place the silkscreen reference text on the bottom layer instead of top"
8334
+ ),
8335
+ pinRowSide: z76.enum(["left", "right", "top", "bottom"]).optional().default("left"),
8336
+ pinrowleft: z76.boolean().optional().default(false),
8337
+ pinrowright: z76.boolean().optional().default(false),
8338
+ pinrowtop: z76.boolean().optional().default(false),
8339
+ pinrowbottom: z76.boolean().optional().default(false),
8340
+ width: length58.optional(),
8341
+ height: length58.optional(),
8342
+ pinRowHoleEdgeToEdgeDist: length58.default("2mm"),
8343
+ holes: z76.union([z76.string(), z76.array(z76.string())]).optional().transform((val) => {
8344
+ if (!val) return val;
8345
+ if (Array.isArray(val)) return val;
8346
+ if (val.startsWith("(") && val.endsWith(")")) {
8347
+ return val.slice(1, -1).split(",").map((s) => s.trim());
8348
+ }
8349
+ return [val];
8350
+ }),
8351
+ holeXDist: length58.optional(),
8352
+ holeYDist: length58.optional(),
8353
+ holeInset: length58.default("1mm"),
8354
+ pinrow: z76.union([z76.string(), z76.number()]).optional(),
8355
+ usbposition: z76.enum(["left", "right", "top", "bottom"]).optional().default("left"),
8356
+ usbleft: z76.boolean().optional().default(false),
8357
+ usbtop: z76.boolean().optional().default(false),
8358
+ usbright: z76.boolean().optional().default(false),
8359
+ usbbottom: z76.boolean().optional().default(false),
8360
+ usbtype: z76.enum(["micro", "c"]).optional(),
8361
+ usbmicro: z76.boolean().optional().default(false),
8362
+ usbc: z76.boolean().optional().default(false)
8363
+ }).transform((data) => {
8364
+ const pinlabelAnchorSide = determinePinlabelAnchorSide(data);
8365
+ let pinRowSide = data.pinRowSide;
8366
+ if (data.pinrowleft) pinRowSide = "left";
8367
+ if (data.pinrowright) pinRowSide = "right";
8368
+ if (data.pinrowtop) pinRowSide = "top";
8369
+ if (data.pinrowbottom) pinRowSide = "bottom";
8370
+ let usbposition = data.usbposition;
8371
+ if (data.usbleft) usbposition = "left";
8372
+ if (data.usbtop) usbposition = "top";
8373
+ if (data.usbright) usbposition = "right";
8374
+ if (data.usbbottom) usbposition = "bottom";
8375
+ let usbtype = data.usbtype;
8376
+ if (data.usbmicro) usbtype = "micro";
8377
+ if (data.usbc) usbtype = "c";
8378
+ if (data.pinrow !== void 0) {
8379
+ data.numPins = Number(data.pinrow);
8380
+ }
8381
+ const numPinsPerRow = Math.ceil(data.numPins / data.rows);
8382
+ let calculatedWidth;
8383
+ let calculatedHeight;
8384
+ if (pinRowSide === "left" || pinRowSide === "right") {
8385
+ calculatedWidth = (data.rows - 1) * data.p + 2 * data.pinRowHoleEdgeToEdgeDist;
8386
+ calculatedHeight = (numPinsPerRow - 1) * data.p + 2 * data.pinRowHoleEdgeToEdgeDist;
8387
+ } else {
8388
+ calculatedHeight = (data.rows - 1) * data.p + 2 * data.pinRowHoleEdgeToEdgeDist;
8389
+ calculatedWidth = (numPinsPerRow - 1) * data.p + 2 * data.pinRowHoleEdgeToEdgeDist;
8390
+ }
8391
+ if (data.numPins === 0) {
8392
+ calculatedWidth = 10;
8393
+ calculatedHeight = 10;
8394
+ }
8395
+ return {
8396
+ ...data,
8397
+ pinlabelAnchorSide,
8398
+ pinRowSide,
8399
+ male: data.male ?? !data.female,
8400
+ female: data.female ?? false,
8401
+ width: data.width ?? calculatedWidth,
8402
+ height: data.height ?? calculatedHeight
8403
+ };
8404
+ }).superRefine((data, ctx) => {
8405
+ if (data.male && data.female) {
8406
+ ctx.addIssue({
8407
+ code: z76.ZodIssueCode.custom,
8408
+ message: "'male' and 'female' cannot both be true; it should be male or female.",
8409
+ path: ["male", "female"]
8410
+ });
8411
+ }
8412
+ });
8413
+ var mountedpcbmodule = (raw_params) => {
8414
+ const parameters = mountedpcbmodule_def.parse(raw_params);
8415
+ const {
8416
+ p,
8417
+ id,
8418
+ od,
8419
+ rows,
8420
+ numPins,
8421
+ pinlabelAnchorSide,
8422
+ pinlabelverticallyinverted,
8423
+ pinlabelorthogonal,
8424
+ pinlabeltextalignleft,
8425
+ pinlabeltextalignright,
8426
+ nopinlabels,
8427
+ doublesidedpinlabel,
8428
+ bottomsidepinlabel,
8429
+ pinRowSide,
8430
+ width,
8431
+ height,
8432
+ pinRowHoleEdgeToEdgeDist,
8433
+ holes,
8434
+ holeXDist,
8435
+ holeYDist,
8436
+ holeInset
8437
+ } = parameters;
8438
+ let pinlabelTextAlign = "center";
8439
+ if (pinlabeltextalignleft) pinlabelTextAlign = "left";
8440
+ else if (pinlabeltextalignright) pinlabelTextAlign = "right";
8441
+ const elements = [];
8442
+ const pinSpacing = p;
8443
+ let pinStartX = 0;
8444
+ let pinStartY = 0;
8445
+ let pinDirectionX = 0;
8446
+ let pinDirectionY = 0;
8447
+ let rowDirectionX = 0;
8448
+ let rowDirectionY = 0;
8449
+ const numPinsPerRow = Math.ceil(numPins / rows);
8450
+ if (pinRowSide === "left" || pinRowSide === "right") {
8451
+ pinStartX = pinRowSide === "left" ? -width / 2 + pinRowHoleEdgeToEdgeDist : width / 2 - pinRowHoleEdgeToEdgeDist;
8452
+ pinStartY = (numPinsPerRow - 1) / 2 * pinSpacing;
8453
+ pinDirectionX = 0;
8454
+ pinDirectionY = -pinSpacing;
8455
+ rowDirectionX = pinRowSide === "left" ? pinSpacing : -pinSpacing;
8456
+ rowDirectionY = 0;
8457
+ } else {
8458
+ pinStartX = -(numPinsPerRow - 1) / 2 * pinSpacing;
8459
+ pinStartY = pinRowSide === "top" ? height / 2 - pinRowHoleEdgeToEdgeDist : -height / 2 + pinRowHoleEdgeToEdgeDist;
8460
+ pinDirectionX = pinSpacing;
8461
+ pinDirectionY = 0;
8462
+ rowDirectionX = 0;
8463
+ rowDirectionY = pinRowSide === "top" ? -pinSpacing : pinSpacing;
8464
+ }
8465
+ let pinNumber = 1;
8466
+ for (let row = 0; row < rows && pinNumber <= numPins; row++) {
8467
+ for (let col = 0; col < numPinsPerRow && pinNumber <= numPins; col++) {
8468
+ const xoff = pinStartX + col * pinDirectionX + row * rowDirectionX;
8469
+ const yoff = pinStartY + col * pinDirectionY + row * rowDirectionY;
8470
+ if (parameters.smd) {
8471
+ elements.push(
8472
+ rectpad(pinNumber, xoff, yoff, parameters.od, parameters.od)
8473
+ );
8474
+ } else {
8475
+ if (pinNumber === 1) {
8476
+ elements.push(
8477
+ platedHoleWithRectPad({
8478
+ pn: pinNumber,
8479
+ x: xoff,
8480
+ y: yoff,
8481
+ holeDiameter: id,
8482
+ rectPadWidth: od,
8483
+ rectPadHeight: od
8484
+ })
8485
+ );
8486
+ } else {
8487
+ elements.push(platedhole(pinNumber, xoff, yoff, id, od));
8488
+ }
8489
+ }
8490
+ if (!nopinlabels) {
8491
+ const anchor_x = xoff + (pinRowSide === "left" ? -od : pinRowSide === "right" ? od : 0);
8492
+ const anchor_y = yoff + (pinRowSide === "top" ? od : pinRowSide === "bottom" ? -od : 0);
8493
+ if (!bottomsidepinlabel) {
8494
+ elements.push(
8495
+ silkscreenPin({
8496
+ fs: od / 5,
8497
+ pn: pinNumber,
8498
+ anchor_x,
8499
+ anchor_y,
8500
+ anchorplacement: pinlabelAnchorSide,
8501
+ textalign: pinlabelTextAlign,
8502
+ orthogonal: pinlabelorthogonal,
8503
+ verticallyinverted: pinlabelverticallyinverted,
8504
+ layer: "top"
8505
+ })
8506
+ );
8507
+ }
8508
+ if (doublesidedpinlabel || bottomsidepinlabel) {
8509
+ elements.push(
8510
+ silkscreenPin({
8511
+ fs: od / 5,
8512
+ pn: pinNumber,
8513
+ anchor_x,
8514
+ anchor_y,
8515
+ anchorplacement: pinlabelAnchorSide,
8516
+ textalign: pinlabelTextAlign,
8517
+ orthogonal: pinlabelorthogonal,
8518
+ verticallyinverted: pinlabelverticallyinverted,
8519
+ layer: "bottom"
8520
+ })
8521
+ );
8522
+ }
8523
+ }
8524
+ pinNumber++;
8525
+ }
8526
+ }
8527
+ if (holes) {
8528
+ for (const pos of holes) {
8529
+ let hx = 0;
8530
+ let hy = 0;
8531
+ if (pos === "topleft") {
8532
+ hx = -width / 2 + holeInset;
8533
+ hy = height / 2 - holeInset;
8534
+ } else if (pos === "topright") {
8535
+ hx = width / 2 - holeInset;
8536
+ hy = height / 2 - holeInset;
8537
+ } else if (pos === "bottomleft") {
8538
+ hx = -width / 2 + holeInset;
8539
+ hy = -height / 2 + holeInset;
8540
+ } else if (pos === "bottomright") {
8541
+ hx = width / 2 - holeInset;
8542
+ hy = -height / 2 + holeInset;
8543
+ } else if (pos === "center") {
8544
+ hx = 0;
8545
+ hy = 0;
8546
+ }
8547
+ if (holeXDist !== void 0) hx += holeXDist;
8548
+ if (holeYDist !== void 0) hy += holeYDist;
8549
+ elements.push(
8550
+ platedhole(numPins + holes.indexOf(pos) + 1, hx, hy, id, od)
8551
+ );
8552
+ }
8553
+ }
8554
+ if (!parameters.nosilkscreen) {
8555
+ const outline = [
8556
+ { x: -width / 2, y: -height / 2 },
8557
+ { x: width / 2, y: -height / 2 },
8558
+ { x: width / 2, y: height / 2 },
8559
+ { x: -width / 2, y: height / 2 },
8560
+ { x: -width / 2, y: -height / 2 }
8561
+ ];
8562
+ elements.push(silkscreenpath(outline, { stroke_width: 0.1, layer: "top" }));
8563
+ }
8564
+ const refText = silkscreenRef(0, height / 2 + 1, 0.5);
8565
+ elements.push(refText);
8566
+ return {
8567
+ circuitJson: elements,
8568
+ parameters
8569
+ };
8570
+ };
8571
+
8572
+ // src/fn/to92l.ts
8573
+ import { z as z77 } from "zod";
8574
+ var to92l_def = base_def.extend({
8575
+ fn: z77.string(),
8576
+ num_pins: z77.number().default(3),
8577
+ inline: z77.boolean().default(false),
8578
+ p: z77.string().default("1.27mm"),
8579
+ id: z77.string().default("0.75mm"),
8580
+ od: z77.string().default("1.3mm"),
8581
+ w: z77.string().default("4.8mm"),
8582
+ h: z77.string().default("4.0mm")
8322
8583
  });
8323
8584
  var to92l = (raw_params) => {
8324
8585
  const parameters = to92l_def.parse(raw_params);