biscuitboard 1.0.5 → 1.0.6

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/README.md CHANGED
@@ -308,18 +308,17 @@ bun test tests/feather-clad.test.tsx
308
308
  [`BreadboardClad`](./lib/breadboard-clad.tsx) is a laser-routable 75 mm x
309
309
  55 mm plug-in prototyping board. It provides 210 individually routable female
310
310
  header sockets labeled A1 through J21, with the standard 2.54 mm terminal pitch
311
- and a 7.62 mm DIP channel. Four 21-pin power/header rails run along the top and
312
- bottom. Unlike a solderless breadboard, none of these sockets are connected in
313
- groups: the consuming tscircuit design defines every connection, allowing the
314
- corresponding copper traces to be laser cut for a particular circuit.
315
-
316
- The 162 assignable prefabricated vias have 0.3 mm holes and 0.6 mm pads. A
317
- single 21-via row sits between each power-header pair and its neighboring
318
- terminal field, while two 21-via rows run through the central DIP channel. A
319
- single-via-wide outer field runs beyond the headers on all four sides. The
320
- socket grids themselves remain clear.
321
- `BreadboardTerminalHeaders` exposes terminal aliases such as `A1` and `J21`;
322
- `BreadboardPowerHeader` exposes `COL1` through `COL21`. The bare preview is in
311
+ and a 7.62 mm DIP channel. Unlike a solderless breadboard, none of these
312
+ sockets are connected in groups: the consuming tscircuit design defines every
313
+ connection, allowing the corresponding copper traces to be laser cut for a
314
+ particular circuit.
315
+
316
+ The 148 assignable prefabricated vias have 0.3 mm holes and 0.6 mm pads. Two
317
+ 21-via rows sit beyond the terminal fields, two 21-via rows run through the
318
+ central DIP channel, and four two-via-wide L-shaped corner fields provide 64
319
+ additional vias. The socket grid remains clear.
320
+ `BreadboardTerminalHeaders` exposes terminal aliases such as `A1` and `J21`.
321
+ The bare preview is in
323
322
  [`examples/breadboard-clad.tsx`](./examples/breadboard-clad.tsx).
324
323
 
325
324
  ```sh
package/dist/npm.cjs CHANGED
@@ -785,15 +785,18 @@ __export(npm_exports, {
785
785
  BREADBOARD_CLAD_WIDTH: () => BREADBOARD_CLAD_WIDTH,
786
786
  BREADBOARD_COLUMN_COUNT: () => BREADBOARD_COLUMN_COUNT,
787
787
  BREADBOARD_COLUMN_XS: () => BREADBOARD_COLUMN_XS,
788
+ BREADBOARD_CORNER_VIA_ARM_WIDTH: () => BREADBOARD_CORNER_VIA_ARM_WIDTH,
789
+ BREADBOARD_CORNER_VIA_POSITIONS: () => BREADBOARD_CORNER_VIA_POSITIONS,
790
+ BREADBOARD_CORNER_VIA_SPACING: () => BREADBOARD_CORNER_VIA_SPACING,
791
+ BREADBOARD_CORNER_VIA_X_INNER_OFFSET: () => BREADBOARD_CORNER_VIA_X_INNER_OFFSET,
792
+ BREADBOARD_CORNER_VIA_X_OUTER_OFFSET: () => BREADBOARD_CORNER_VIA_X_OUTER_OFFSET,
793
+ BREADBOARD_CORNER_VIA_X_OUTWARD_SHIFT: () => BREADBOARD_CORNER_VIA_X_OUTWARD_SHIFT,
794
+ BREADBOARD_CORNER_VIA_Y_INNER_OFFSET: () => BREADBOARD_CORNER_VIA_Y_INNER_OFFSET,
795
+ BREADBOARD_CORNER_VIA_Y_OUTER_OFFSET: () => BREADBOARD_CORNER_VIA_Y_OUTER_OFFSET,
788
796
  BREADBOARD_HEADER_HOLE_DIAMETER: () => BREADBOARD_HEADER_HOLE_DIAMETER,
789
797
  BREADBOARD_HEADER_PAD_DIAMETER: () => BREADBOARD_HEADER_PAD_DIAMETER,
790
798
  BREADBOARD_HEADER_PITCH: () => BREADBOARD_HEADER_PITCH,
791
799
  BREADBOARD_MOUNTING_HOLE_DIAMETER: () => BREADBOARD_MOUNTING_HOLE_DIAMETER,
792
- BREADBOARD_OUTER_VERTICAL_VIA_YS: () => BREADBOARD_OUTER_VERTICAL_VIA_YS,
793
- BREADBOARD_OUTER_VIA_COLUMN_XS: () => BREADBOARD_OUTER_VIA_COLUMN_XS,
794
- BREADBOARD_OUTER_VIA_ROW_YS: () => BREADBOARD_OUTER_VIA_ROW_YS,
795
- BREADBOARD_POWER_HEADER_POSITIONS: () => BREADBOARD_POWER_HEADER_POSITIONS,
796
- BREADBOARD_POWER_RAILS: () => BREADBOARD_POWER_RAILS,
797
800
  BREADBOARD_TERMINAL_HEADER_POSITIONS: () => BREADBOARD_TERMINAL_HEADER_POSITIONS,
798
801
  BREADBOARD_TERMINAL_ROW_LABELS: () => BREADBOARD_TERMINAL_ROW_LABELS,
799
802
  BREADBOARD_TERMINAL_ROW_YS: () => BREADBOARD_TERMINAL_ROW_YS,
@@ -803,7 +806,6 @@ __export(npm_exports, {
803
806
  BoosterPackLeftHeader: () => BoosterPackLeftHeader,
804
807
  BoosterPackRightHeader: () => BoosterPackRightHeader,
805
808
  BreadboardClad: () => BreadboardClad,
806
- BreadboardPowerHeader: () => BreadboardPowerHeader,
807
809
  BreadboardTerminalHeaders: () => BreadboardTerminalHeaders,
808
810
  CLAD_40X40_EDGE_MOUNTING_HOLE_INSET: () => CLAD_40X40_EDGE_MOUNTING_HOLE_INSET,
809
811
  CLAD_40X40_HEIGHT: () => CLAD_40X40_HEIGHT,
@@ -15587,8 +15589,13 @@ var BREADBOARD_CLAD_VIA_ROW_YS = [
15587
15589
  BREADBOARD_HEADER_PITCH / 2,
15588
15590
  16.51
15589
15591
  ];
15590
- var BREADBOARD_OUTER_VIA_ROW_YS = [-24.13, 24.13];
15591
- var BREADBOARD_OUTER_VIA_COLUMN_XS = [-27.94, 27.94];
15592
+ var BREADBOARD_CORNER_VIA_SPACING = 1.3;
15593
+ var BREADBOARD_CORNER_VIA_ARM_WIDTH = 1.3;
15594
+ var BREADBOARD_CORNER_VIA_X_INNER_OFFSET = 27;
15595
+ var BREADBOARD_CORNER_VIA_X_OUTER_OFFSET = 32.2;
15596
+ var BREADBOARD_CORNER_VIA_Y_INNER_OFFSET = 21;
15597
+ var BREADBOARD_CORNER_VIA_Y_OUTER_OFFSET = 26.2;
15598
+ var BREADBOARD_CORNER_VIA_X_OUTWARD_SHIFT = 3.9;
15592
15599
  var BREADBOARD_MOUNTING_HOLE_DIAMETER = 2.2;
15593
15600
  var BREADBOARD_CLAD_EDGE_CLEARANCE = 0.2;
15594
15601
  var BREADBOARD_CLAD_EDGE_CLEARANCE_VALIDATION_TOLERANCE = 1e-3;
@@ -15606,16 +15613,18 @@ var BREADBOARD_TERMINAL_ROW_LABELS = [
15606
15613
  "J"
15607
15614
  ];
15608
15615
  var roundCoordinate3 = (value) => Math.round(value * 1e6) / 1e6;
15616
+ var createPitchedRange = (start, end) => Array.from(
15617
+ {
15618
+ length: Math.round((end - start) / BREADBOARD_CORNER_VIA_SPACING) + 1
15619
+ },
15620
+ (_, index) => roundCoordinate3(start + index * BREADBOARD_CORNER_VIA_SPACING)
15621
+ );
15609
15622
  var BREADBOARD_COLUMN_XS = Array.from(
15610
15623
  { length: BREADBOARD_COLUMN_COUNT },
15611
15624
  (_, index) => roundCoordinate3(
15612
15625
  (index - (BREADBOARD_COLUMN_COUNT - 1) / 2) * BREADBOARD_HEADER_PITCH
15613
15626
  )
15614
15627
  );
15615
- var BREADBOARD_OUTER_VERTICAL_VIA_YS = Array.from(
15616
- { length: 18 },
15617
- (_, index) => roundCoordinate3(-21.59 + index * BREADBOARD_CLAD_VIA_PITCH)
15618
- );
15619
15628
  var BREADBOARD_TERMINAL_ROW_YS = Object.fromEntries(
15620
15629
  BREADBOARD_TERMINAL_ROW_LABELS.map((label, index) => {
15621
15630
  const bankIndex = index < 5 ? index : index - 5;
@@ -15632,32 +15641,61 @@ var BREADBOARD_TERMINAL_HEADER_POSITIONS = BREADBOARD_TERMINAL_ROW_LABELS.flatMa
15632
15641
  y: BREADBOARD_TERMINAL_ROW_YS[row]
15633
15642
  }))
15634
15643
  );
15635
- var BREADBOARD_POWER_RAILS = [
15636
- { id: "topPositive", label: "+", y: 21.59 },
15637
- { id: "topNegative", label: "-", y: 19.05 },
15638
- { id: "bottomPositive", label: "+", y: -19.05 },
15639
- { id: "bottomNegative", label: "-", y: -21.59 }
15640
- ];
15641
- var BREADBOARD_POWER_HEADER_POSITIONS = BREADBOARD_POWER_RAILS.flatMap(
15642
- (rail) => BREADBOARD_COLUMN_XS.map((x, columnIndex) => ({
15643
- rail: rail.id,
15644
- pin: columnIndex + 1,
15645
- label: `${rail.id}${columnIndex + 1}`,
15646
- column: columnIndex + 1,
15647
- x,
15648
- y: rail.y
15649
- }))
15644
+ var cornerViaAxisX = createPitchedRange(
15645
+ BREADBOARD_CORNER_VIA_X_INNER_OFFSET,
15646
+ BREADBOARD_CORNER_VIA_X_OUTER_OFFSET
15647
+ );
15648
+ var cornerViaAxisY = createPitchedRange(
15649
+ BREADBOARD_CORNER_VIA_Y_INNER_OFFSET,
15650
+ BREADBOARD_CORNER_VIA_Y_OUTER_OFFSET
15651
+ );
15652
+ var cornerViaArmAxisX = createPitchedRange(
15653
+ BREADBOARD_CORNER_VIA_X_INNER_OFFSET,
15654
+ BREADBOARD_CORNER_VIA_X_INNER_OFFSET + BREADBOARD_CORNER_VIA_ARM_WIDTH
15655
+ );
15656
+ var cornerViaArmAxisY = createPitchedRange(
15657
+ BREADBOARD_CORNER_VIA_Y_INNER_OFFSET,
15658
+ BREADBOARD_CORNER_VIA_Y_INNER_OFFSET + BREADBOARD_CORNER_VIA_ARM_WIDTH
15659
+ );
15660
+ var createCornerViaPositions = (xSign, ySign, xOutwardShift = 0) => {
15661
+ const shiftedCornerViaAxisX = cornerViaAxisX.map(
15662
+ (x) => roundCoordinate3(x + xOutwardShift)
15663
+ );
15664
+ const shiftedCornerViaArmAxisX = cornerViaArmAxisX.map(
15665
+ (x) => roundCoordinate3(x + xOutwardShift)
15666
+ );
15667
+ const horizontalArm = shiftedCornerViaAxisX.flatMap(
15668
+ (x) => cornerViaArmAxisY.map((y) => ({ x: x * xSign, y: y * ySign }))
15669
+ );
15670
+ const verticalArm = shiftedCornerViaArmAxisX.flatMap(
15671
+ (x) => cornerViaAxisY.map((y) => ({ x: x * xSign, y: y * ySign }))
15672
+ );
15673
+ return Array.from(
15674
+ new Map(
15675
+ [...horizontalArm, ...verticalArm].map((point) => [
15676
+ `${point.x},${point.y}`,
15677
+ point
15678
+ ])
15679
+ ).values()
15680
+ );
15681
+ };
15682
+ var BREADBOARD_CORNER_VIA_POSITIONS = [
15683
+ [-1, -1],
15684
+ [-1, 1],
15685
+ [1, -1],
15686
+ [1, 1]
15687
+ ].flatMap(
15688
+ ([xSign, ySign]) => createCornerViaPositions(
15689
+ xSign,
15690
+ ySign,
15691
+ xSign === -1 || ySign === -1 ? BREADBOARD_CORNER_VIA_X_OUTWARD_SHIFT : 0
15692
+ )
15650
15693
  );
15651
15694
  var BREADBOARD_CLAD_VIA_POSITIONS = [
15652
15695
  ...BREADBOARD_CLAD_VIA_ROW_YS.flatMap(
15653
15696
  (y) => BREADBOARD_COLUMN_XS.map((x) => ({ x, y }))
15654
15697
  ),
15655
- ...BREADBOARD_OUTER_VIA_ROW_YS.flatMap(
15656
- (y) => BREADBOARD_COLUMN_XS.map((x) => ({ x, y }))
15657
- ),
15658
- ...BREADBOARD_OUTER_VIA_COLUMN_XS.flatMap(
15659
- (x) => BREADBOARD_OUTER_VERTICAL_VIA_YS.map((y) => ({ x, y }))
15660
- )
15698
+ ...BREADBOARD_CORNER_VIA_POSITIONS
15661
15699
  ];
15662
15700
  var terminalPinLabels = Object.fromEntries(
15663
15701
  BREADBOARD_TERMINAL_HEADER_POSITIONS.map((position) => [
@@ -15665,16 +15703,9 @@ var terminalPinLabels = Object.fromEntries(
15665
15703
  [position.label]
15666
15704
  ])
15667
15705
  );
15668
- var powerPinLabels = Object.fromEntries(
15669
- BREADBOARD_COLUMN_XS.map((_, index) => [
15670
- `pin${index + 1}`,
15671
- [`COL${index + 1}`]
15672
- ])
15673
- );
15674
15706
  var terminalPinNames = BREADBOARD_TERMINAL_HEADER_POSITIONS.map(
15675
15707
  (position) => `pin${position.pin}`
15676
15708
  );
15677
- var powerPinNames = BREADBOARD_COLUMN_XS.map((_, index) => `pin${index + 1}`);
15678
15709
  var BreadboardTerminalHeaderFootprint = () => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("footprint", { insertionDirection: "from_above", children: BREADBOARD_TERMINAL_HEADER_POSITIONS.map((position) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react4.Fragment, { children: position.pin === 1 ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
15679
15710
  "platedhole",
15680
15711
  {
@@ -15697,26 +15728,6 @@ var BreadboardTerminalHeaderFootprint = () => /* @__PURE__ */ (0, import_jsx_run
15697
15728
  pcbY: position.y
15698
15729
  }
15699
15730
  ) }, `terminal-${position.label}`)) });
15700
- var BreadboardPowerHeaderFootprint = () => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("footprint", { insertionDirection: "from_above", children: BREADBOARD_COLUMN_XS.map((x, index) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react4.Fragment, { children: index === 0 ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
15701
- "platedhole",
15702
- {
15703
- portHints: [`pin${index + 1}`],
15704
- shape: "circular_hole_with_rect_pad",
15705
- holeDiameter: `${BREADBOARD_HEADER_HOLE_DIAMETER}mm`,
15706
- rectPadWidth: `${BREADBOARD_HEADER_PAD_DIAMETER}mm`,
15707
- rectPadHeight: `${BREADBOARD_HEADER_PAD_DIAMETER}mm`,
15708
- pcbX: x
15709
- }
15710
- ) : /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
15711
- "platedhole",
15712
- {
15713
- portHints: [`pin${index + 1}`],
15714
- shape: "circle",
15715
- holeDiameter: `${BREADBOARD_HEADER_HOLE_DIAMETER}mm`,
15716
- outerDiameter: `${BREADBOARD_HEADER_PAD_DIAMETER}mm`,
15717
- pcbX: x
15718
- }
15719
- ) }, `power-pin-${index + 1}`)) });
15720
15731
  var BreadboardTerminalHeaders = (props) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
15721
15732
  "connector",
15722
15733
  {
@@ -15727,20 +15738,6 @@ var BreadboardTerminalHeaders = (props) => /* @__PURE__ */ (0, import_jsx_runtim
15727
15738
  ...props
15728
15739
  }
15729
15740
  );
15730
- var BreadboardPowerHeader = ({
15731
- rail,
15732
- ...props
15733
- }) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
15734
- "connector",
15735
- {
15736
- pinLabels: powerPinLabels,
15737
- manufacturerPartNumber: "GENERIC-BREADBOARD-1X21-FEMALE-2.54MM",
15738
- footprint: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(BreadboardPowerHeaderFootprint, {}),
15739
- noSchematicRepresentation: true,
15740
- pcbY: BREADBOARD_POWER_RAILS.find((candidate) => candidate.id === rail).y,
15741
- ...props
15742
- }
15743
- );
15744
15741
  var BreadboardClad = ({
15745
15742
  children,
15746
15743
  autorouter,
@@ -15789,14 +15786,6 @@ var BreadboardClad = ({
15789
15786
  noConnect: headerNoConnects?.terminals ?? (markHeadersNoConnect ? terminalPinNames : void 0)
15790
15787
  }
15791
15788
  ),
15792
- BREADBOARD_POWER_RAILS.map((rail) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react4.Fragment, { children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
15793
- BreadboardPowerHeader,
15794
- {
15795
- rail: rail.id,
15796
- name: `J_${rail.id.replace(/([A-Z])/g, "_$1").toUpperCase()}`,
15797
- noConnect: headerNoConnects?.[rail.id] ?? (markHeadersNoConnect ? powerPinNames : void 0)
15798
- }
15799
- ) }, rail.id)),
15800
15789
  [1, 5, 10, 15, 20, BREADBOARD_COLUMN_COUNT].map((column) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react4.Fragment, { children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
15801
15790
  "silkscreentext",
15802
15791
  {
@@ -16498,15 +16487,18 @@ var XiaoCladWithPerforatedPinHeaders = ({
16498
16487
  BREADBOARD_CLAD_WIDTH,
16499
16488
  BREADBOARD_COLUMN_COUNT,
16500
16489
  BREADBOARD_COLUMN_XS,
16490
+ BREADBOARD_CORNER_VIA_ARM_WIDTH,
16491
+ BREADBOARD_CORNER_VIA_POSITIONS,
16492
+ BREADBOARD_CORNER_VIA_SPACING,
16493
+ BREADBOARD_CORNER_VIA_X_INNER_OFFSET,
16494
+ BREADBOARD_CORNER_VIA_X_OUTER_OFFSET,
16495
+ BREADBOARD_CORNER_VIA_X_OUTWARD_SHIFT,
16496
+ BREADBOARD_CORNER_VIA_Y_INNER_OFFSET,
16497
+ BREADBOARD_CORNER_VIA_Y_OUTER_OFFSET,
16501
16498
  BREADBOARD_HEADER_HOLE_DIAMETER,
16502
16499
  BREADBOARD_HEADER_PAD_DIAMETER,
16503
16500
  BREADBOARD_HEADER_PITCH,
16504
16501
  BREADBOARD_MOUNTING_HOLE_DIAMETER,
16505
- BREADBOARD_OUTER_VERTICAL_VIA_YS,
16506
- BREADBOARD_OUTER_VIA_COLUMN_XS,
16507
- BREADBOARD_OUTER_VIA_ROW_YS,
16508
- BREADBOARD_POWER_HEADER_POSITIONS,
16509
- BREADBOARD_POWER_RAILS,
16510
16502
  BREADBOARD_TERMINAL_HEADER_POSITIONS,
16511
16503
  BREADBOARD_TERMINAL_ROW_LABELS,
16512
16504
  BREADBOARD_TERMINAL_ROW_YS,
@@ -16516,7 +16508,6 @@ var XiaoCladWithPerforatedPinHeaders = ({
16516
16508
  BoosterPackLeftHeader,
16517
16509
  BoosterPackRightHeader,
16518
16510
  BreadboardClad,
16519
- BreadboardPowerHeader,
16520
16511
  BreadboardTerminalHeaders,
16521
16512
  CLAD_40X40_EDGE_MOUNTING_HOLE_INSET,
16522
16513
  CLAD_40X40_HEIGHT,