@tscircuit/core 0.0.872 → 0.0.873
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.d.ts +15 -0
- package/dist/index.js +101 -66
- package/package.json +2 -2
package/dist/index.d.ts
CHANGED
|
@@ -3240,6 +3240,11 @@ declare class Panel extends Group<typeof panelProps> {
|
|
|
3240
3240
|
height: zod.ZodEffects<zod.ZodUnion<[zod.ZodString, zod.ZodNumber]>, number, string | number>;
|
|
3241
3241
|
children: zod.ZodOptional<zod.ZodAny>;
|
|
3242
3242
|
noSolderMask: zod.ZodOptional<zod.ZodBoolean>;
|
|
3243
|
+
panelizationMethod: zod.ZodOptional<zod.ZodEnum<["tab-routing", "none"]>>;
|
|
3244
|
+
boardGap: zod.ZodOptional<zod.ZodEffects<zod.ZodUnion<[zod.ZodString, zod.ZodNumber]>, number, string | number>>;
|
|
3245
|
+
tabWidth: zod.ZodOptional<zod.ZodEffects<zod.ZodUnion<[zod.ZodString, zod.ZodNumber]>, number, string | number>>;
|
|
3246
|
+
tabLength: zod.ZodOptional<zod.ZodEffects<zod.ZodUnion<[zod.ZodString, zod.ZodNumber]>, number, string | number>>;
|
|
3247
|
+
mouseBites: zod.ZodOptional<zod.ZodBoolean>;
|
|
3243
3248
|
}, "strip", zod.ZodTypeAny, {
|
|
3244
3249
|
width: number;
|
|
3245
3250
|
height: number;
|
|
@@ -3484,6 +3489,11 @@ declare class Panel extends Group<typeof panelProps> {
|
|
|
3484
3489
|
schPack?: boolean | undefined;
|
|
3485
3490
|
schMatchAdapt?: boolean | undefined;
|
|
3486
3491
|
noSolderMask?: boolean | undefined;
|
|
3492
|
+
panelizationMethod?: "none" | "tab-routing" | undefined;
|
|
3493
|
+
boardGap?: number | undefined;
|
|
3494
|
+
tabWidth?: number | undefined;
|
|
3495
|
+
tabLength?: number | undefined;
|
|
3496
|
+
mouseBites?: boolean | undefined;
|
|
3487
3497
|
}, {
|
|
3488
3498
|
width: string | number;
|
|
3489
3499
|
height: string | number;
|
|
@@ -3730,6 +3740,11 @@ declare class Panel extends Group<typeof panelProps> {
|
|
|
3730
3740
|
schPack?: boolean | undefined;
|
|
3731
3741
|
schMatchAdapt?: boolean | undefined;
|
|
3732
3742
|
noSolderMask?: boolean | undefined;
|
|
3743
|
+
panelizationMethod?: "none" | "tab-routing" | undefined;
|
|
3744
|
+
boardGap?: string | number | undefined;
|
|
3745
|
+
tabWidth?: string | number | undefined;
|
|
3746
|
+
tabLength?: string | number | undefined;
|
|
3747
|
+
mouseBites?: boolean | undefined;
|
|
3733
3748
|
}>;
|
|
3734
3749
|
};
|
|
3735
3750
|
get isGroup(): boolean;
|
package/dist/index.js
CHANGED
|
@@ -14333,14 +14333,9 @@ import { panelProps } from "@tscircuit/props";
|
|
|
14333
14333
|
import { distance as distance9 } from "circuit-json";
|
|
14334
14334
|
|
|
14335
14335
|
// lib/utils/panels/generate-panel-tabs-and-mouse-bites.ts
|
|
14336
|
-
var
|
|
14337
|
-
|
|
14338
|
-
|
|
14339
|
-
TAB_TO_SPACE_RATIO: 5,
|
|
14340
|
-
MOUSE_BITE_DIAMETER: 0.2,
|
|
14341
|
-
MOUSE_BITE_SPACING: 0.1,
|
|
14342
|
-
MOUSE_BITES_PER_GAP: 5
|
|
14343
|
-
};
|
|
14336
|
+
var DEFAULT_PANEL_MARGIN = 5;
|
|
14337
|
+
var DEFAULT_TAB_LENGTH = 5;
|
|
14338
|
+
var DEFAULT_TAB_WIDTH = 2;
|
|
14344
14339
|
function rectanglesOverlap(rect1, rect2) {
|
|
14345
14340
|
const r1Left = rect1.center.x - rect1.width / 2;
|
|
14346
14341
|
const r1Right = rect1.center.x + rect1.width / 2;
|
|
@@ -14363,7 +14358,12 @@ function pointOverlapsRectangle(point, radius, rect) {
|
|
|
14363
14358
|
const distanceY = point.y - closestY;
|
|
14364
14359
|
return distanceX * distanceX + distanceY * distanceY <= radius * radius;
|
|
14365
14360
|
}
|
|
14366
|
-
function generateTabsForEdge(
|
|
14361
|
+
function generateTabsForEdge({
|
|
14362
|
+
board,
|
|
14363
|
+
edge,
|
|
14364
|
+
otherBoards,
|
|
14365
|
+
options
|
|
14366
|
+
}) {
|
|
14367
14367
|
const tabs = [];
|
|
14368
14368
|
if (!board.width || !board.height) return tabs;
|
|
14369
14369
|
const boardLeft = board.center.x - board.width / 2;
|
|
@@ -14382,9 +14382,15 @@ function generateTabsForEdge(board, edge, existingTabs, otherBoards) {
|
|
|
14382
14382
|
isHorizontal = false;
|
|
14383
14383
|
edgeCenter = edge === "right" ? boardRight : boardLeft;
|
|
14384
14384
|
}
|
|
14385
|
-
const totalTabWidth =
|
|
14386
|
-
|
|
14387
|
-
|
|
14385
|
+
const totalTabWidth = options.tabLength;
|
|
14386
|
+
let fixedSpacing = options.boardGap;
|
|
14387
|
+
if (options.mouseBites) {
|
|
14388
|
+
const mouseBiteDiameter = options.tabWidth * 0.45;
|
|
14389
|
+
const mouseBiteSpacing = mouseBiteDiameter * 0.1;
|
|
14390
|
+
const mouseBitesPerGap = Math.max(2, Math.ceil(options.tabLength / 2));
|
|
14391
|
+
const minSpacingForMouseBites = mouseBitesPerGap * mouseBiteDiameter + (mouseBitesPerGap - 1) * mouseBiteSpacing;
|
|
14392
|
+
fixedSpacing = minSpacingForMouseBites * 1.1;
|
|
14393
|
+
}
|
|
14388
14394
|
let numTabs = Math.floor(
|
|
14389
14395
|
(edgeLength - fixedSpacing) / (totalTabWidth + fixedSpacing)
|
|
14390
14396
|
);
|
|
@@ -14409,13 +14415,13 @@ function generateTabsForEdge(board, edge, existingTabs, otherBoards) {
|
|
|
14409
14415
|
axisStart = Math.max(axisStart, boardStart);
|
|
14410
14416
|
axisEnd = Math.min(axisEnd, boardEnd);
|
|
14411
14417
|
if (isCornerTab) {
|
|
14412
|
-
if (isFirstTab) axisStart -=
|
|
14413
|
-
if (isLastTab) axisEnd +=
|
|
14418
|
+
if (isFirstTab) axisStart -= options.tabWidth;
|
|
14419
|
+
if (isLastTab) axisEnd += options.tabWidth;
|
|
14414
14420
|
}
|
|
14415
14421
|
if (axisEnd <= axisStart) continue;
|
|
14416
14422
|
const axisCenterOffset = (axisStart + axisEnd) / 2;
|
|
14417
14423
|
const axisLength = axisEnd - axisStart;
|
|
14418
|
-
const crossAxisOffset = edge === "top" || edge === "right" ?
|
|
14424
|
+
const crossAxisOffset = edge === "top" || edge === "right" ? options.tabWidth / 2 : -options.tabWidth / 2;
|
|
14419
14425
|
const tabCenter = isHorizontal ? {
|
|
14420
14426
|
x: board.center.x + axisCenterOffset,
|
|
14421
14427
|
y: edgeCenter + crossAxisOffset
|
|
@@ -14423,8 +14429,8 @@ function generateTabsForEdge(board, edge, existingTabs, otherBoards) {
|
|
|
14423
14429
|
x: edgeCenter + crossAxisOffset,
|
|
14424
14430
|
y: board.center.y + axisCenterOffset
|
|
14425
14431
|
};
|
|
14426
|
-
const tabWidth = isHorizontal ? axisLength :
|
|
14427
|
-
const tabHeight = isHorizontal ?
|
|
14432
|
+
const tabWidth = isHorizontal ? axisLength : options.tabWidth;
|
|
14433
|
+
const tabHeight = isHorizontal ? options.tabWidth : axisLength;
|
|
14428
14434
|
const newTab = {
|
|
14429
14435
|
center: tabCenter,
|
|
14430
14436
|
width: tabWidth,
|
|
@@ -14449,7 +14455,13 @@ function generateTabsForEdge(board, edge, existingTabs, otherBoards) {
|
|
|
14449
14455
|
}
|
|
14450
14456
|
return tabs;
|
|
14451
14457
|
}
|
|
14452
|
-
function generateMouseBitesForEdge(
|
|
14458
|
+
function generateMouseBitesForEdge({
|
|
14459
|
+
board,
|
|
14460
|
+
edge,
|
|
14461
|
+
edgeTabs,
|
|
14462
|
+
allBoards,
|
|
14463
|
+
options
|
|
14464
|
+
}) {
|
|
14453
14465
|
const mouseBites = [];
|
|
14454
14466
|
if (edgeTabs.length === 0) return mouseBites;
|
|
14455
14467
|
if (!board.width || !board.height) return mouseBites;
|
|
@@ -14458,8 +14470,11 @@ function generateMouseBitesForEdge(board, edge, edgeTabs, allTabs, allBoards, ex
|
|
|
14458
14470
|
const boardBottom = board.center.y - board.height / 2;
|
|
14459
14471
|
const boardTop = board.center.y + board.height / 2;
|
|
14460
14472
|
const isHorizontal = edge === "top" || edge === "bottom";
|
|
14473
|
+
const mouseBiteDiameter = options.tabWidth * 0.45;
|
|
14474
|
+
const mouseBiteSpacing = mouseBiteDiameter * 0.1;
|
|
14475
|
+
const mouseBitesPerGap = Math.max(2, Math.ceil(options.tabLength / 2));
|
|
14461
14476
|
let mouseBitePosition;
|
|
14462
|
-
const radius =
|
|
14477
|
+
const radius = mouseBiteDiameter / 2;
|
|
14463
14478
|
if (edge === "top") {
|
|
14464
14479
|
mouseBitePosition = boardTop;
|
|
14465
14480
|
} else if (edge === "bottom") {
|
|
@@ -14489,14 +14504,14 @@ function generateMouseBitesForEdge(board, edge, edgeTabs, allTabs, allBoards, ex
|
|
|
14489
14504
|
gapEnd = tab2.center.y - tab2.height / 2;
|
|
14490
14505
|
}
|
|
14491
14506
|
const gapLength = gapEnd - gapStart;
|
|
14492
|
-
const totalMouseBiteWidth =
|
|
14493
|
-
const totalSpacing = (
|
|
14507
|
+
const totalMouseBiteWidth = mouseBitesPerGap * mouseBiteDiameter;
|
|
14508
|
+
const totalSpacing = (mouseBitesPerGap - 1) * mouseBiteSpacing;
|
|
14494
14509
|
if (gapLength < totalMouseBiteWidth + totalSpacing) continue;
|
|
14495
14510
|
const gapCenter = (gapStart + gapEnd) / 2;
|
|
14496
|
-
for (let j = 0; j <
|
|
14497
|
-
const posOffset = (j - (
|
|
14511
|
+
for (let j = 0; j < mouseBitesPerGap; j++) {
|
|
14512
|
+
const posOffset = (j - (mouseBitesPerGap - 1) / 2) * (mouseBiteDiameter + mouseBiteSpacing);
|
|
14498
14513
|
const newMouseBite = isHorizontal ? { x: gapCenter + posOffset, y: mouseBitePosition } : { x: mouseBitePosition, y: gapCenter + posOffset };
|
|
14499
|
-
const radius2 =
|
|
14514
|
+
const radius2 = mouseBiteDiameter / 2;
|
|
14500
14515
|
let overlapsBoard = false;
|
|
14501
14516
|
for (const otherBoard of allBoards) {
|
|
14502
14517
|
if (!otherBoard.width || !otherBoard.height) continue;
|
|
@@ -14516,45 +14531,50 @@ function generateMouseBitesForEdge(board, edge, edgeTabs, allTabs, allBoards, ex
|
|
|
14516
14531
|
}
|
|
14517
14532
|
return mouseBites;
|
|
14518
14533
|
}
|
|
14519
|
-
function generatePanelTabsAndMouseBites(boards) {
|
|
14534
|
+
function generatePanelTabsAndMouseBites(boards, options) {
|
|
14520
14535
|
const allTabCutouts = [];
|
|
14521
14536
|
const allMouseBites = [];
|
|
14522
14537
|
for (let boardIndex = 0; boardIndex < boards.length; boardIndex++) {
|
|
14523
14538
|
const board = boards[boardIndex];
|
|
14524
14539
|
const otherBoards = boards.filter((_, i) => i !== boardIndex);
|
|
14525
14540
|
for (const edge of ["top", "bottom", "left", "right"]) {
|
|
14526
|
-
const edgeTabs = generateTabsForEdge(
|
|
14527
|
-
board,
|
|
14528
|
-
edge,
|
|
14529
|
-
allTabCutouts,
|
|
14530
|
-
otherBoards
|
|
14531
|
-
);
|
|
14532
|
-
allTabCutouts.push(...edgeTabs);
|
|
14533
|
-
const edgeMouseBites = generateMouseBitesForEdge(
|
|
14541
|
+
const edgeTabs = generateTabsForEdge({
|
|
14534
14542
|
board,
|
|
14535
14543
|
edge,
|
|
14536
|
-
edgeTabs,
|
|
14537
|
-
allTabCutouts,
|
|
14538
14544
|
otherBoards,
|
|
14539
|
-
|
|
14540
|
-
);
|
|
14541
|
-
|
|
14545
|
+
options
|
|
14546
|
+
});
|
|
14547
|
+
allTabCutouts.push(...edgeTabs);
|
|
14548
|
+
if (options.mouseBites) {
|
|
14549
|
+
const edgeMouseBites = generateMouseBitesForEdge({
|
|
14550
|
+
board,
|
|
14551
|
+
edge,
|
|
14552
|
+
edgeTabs,
|
|
14553
|
+
allBoards: otherBoards,
|
|
14554
|
+
options
|
|
14555
|
+
});
|
|
14556
|
+
allMouseBites.push(...edgeMouseBites);
|
|
14557
|
+
}
|
|
14542
14558
|
}
|
|
14543
14559
|
}
|
|
14544
|
-
const tabCutouts = allTabCutouts.map((tab, index) =>
|
|
14545
|
-
|
|
14546
|
-
|
|
14547
|
-
|
|
14548
|
-
|
|
14549
|
-
|
|
14550
|
-
|
|
14551
|
-
|
|
14552
|
-
|
|
14560
|
+
const tabCutouts = allTabCutouts.map((tab, index) => {
|
|
14561
|
+
const tabWidthDimension = Math.min(tab.width, tab.height);
|
|
14562
|
+
return {
|
|
14563
|
+
type: "pcb_cutout",
|
|
14564
|
+
pcb_cutout_id: `panel_tab_${index}`,
|
|
14565
|
+
shape: "rect",
|
|
14566
|
+
center: tab.center,
|
|
14567
|
+
width: tab.width,
|
|
14568
|
+
height: tab.height,
|
|
14569
|
+
corner_radius: tabWidthDimension / 2
|
|
14570
|
+
};
|
|
14571
|
+
});
|
|
14572
|
+
const mouseBiteDiameter = options.tabWidth * 0.45;
|
|
14553
14573
|
const mouseBiteHoles = allMouseBites.map((bite, index) => ({
|
|
14554
14574
|
type: "pcb_hole",
|
|
14555
14575
|
pcb_hole_id: `panel_mouse_bite_${index}`,
|
|
14556
14576
|
hole_shape: "circle",
|
|
14557
|
-
hole_diameter:
|
|
14577
|
+
hole_diameter: mouseBiteDiameter,
|
|
14558
14578
|
x: bite.x,
|
|
14559
14579
|
y: bite.y
|
|
14560
14580
|
}));
|
|
@@ -14600,6 +14620,8 @@ var Panel = class extends Group6 {
|
|
|
14600
14620
|
(b) => b.props.pcbX === void 0 && b.props.pcbY === void 0
|
|
14601
14621
|
);
|
|
14602
14622
|
if (unpositionedBoards.length > 0 && !hasAnyPositionedBoards) {
|
|
14623
|
+
const tabWidth = this._parsedProps.tabWidth ?? DEFAULT_TAB_WIDTH;
|
|
14624
|
+
const boardGap = this._parsedProps.boardGap ?? tabWidth;
|
|
14603
14625
|
const gridCols = Math.ceil(Math.sqrt(unpositionedBoards.length));
|
|
14604
14626
|
const gridRows = Math.ceil(unpositionedBoards.length / gridCols);
|
|
14605
14627
|
const colWidths = Array(gridCols).fill(0);
|
|
@@ -14613,17 +14635,17 @@ var Panel = class extends Group6 {
|
|
|
14613
14635
|
colWidths[col] = Math.max(colWidths[col], pcbBoard.width);
|
|
14614
14636
|
rowHeights[row] = Math.max(rowHeights[row], pcbBoard.height);
|
|
14615
14637
|
});
|
|
14616
|
-
const totalGridWidth = colWidths.reduce((a, b) => a + b, 0) + (gridCols > 1 ? (gridCols - 1) *
|
|
14617
|
-
const totalGridHeight = rowHeights.reduce((a, b) => a + b, 0) + (gridRows > 1 ? (gridRows - 1) *
|
|
14638
|
+
const totalGridWidth = colWidths.reduce((a, b) => a + b, 0) + (gridCols > 1 ? (gridCols - 1) * boardGap : 0);
|
|
14639
|
+
const totalGridHeight = rowHeights.reduce((a, b) => a + b, 0) + (gridRows > 1 ? (gridRows - 1) * boardGap : 0);
|
|
14618
14640
|
const startX = -totalGridWidth / 2;
|
|
14619
14641
|
const startY = -totalGridHeight / 2;
|
|
14620
14642
|
const rowYOffsets = [startY];
|
|
14621
14643
|
for (let i = 0; i < gridRows - 1; i++) {
|
|
14622
|
-
rowYOffsets.push(rowYOffsets[i] + rowHeights[i] +
|
|
14644
|
+
rowYOffsets.push(rowYOffsets[i] + rowHeights[i] + boardGap);
|
|
14623
14645
|
}
|
|
14624
14646
|
const colXOffsets = [startX];
|
|
14625
14647
|
for (let i = 0; i < gridCols - 1; i++) {
|
|
14626
|
-
colXOffsets.push(colXOffsets[i] + colWidths[i] +
|
|
14648
|
+
colXOffsets.push(colXOffsets[i] + colWidths[i] + boardGap);
|
|
14627
14649
|
}
|
|
14628
14650
|
unpositionedBoards.forEach((board, i) => {
|
|
14629
14651
|
const col = i % gridCols;
|
|
@@ -14657,9 +14679,8 @@ var Panel = class extends Group6 {
|
|
|
14657
14679
|
if (isFinite(minX)) {
|
|
14658
14680
|
const boundsWidth = maxX - minX;
|
|
14659
14681
|
const boundsHeight = maxY - minY;
|
|
14660
|
-
const
|
|
14661
|
-
const
|
|
14662
|
-
const newPanelHeight = boundsHeight + 2 * margin;
|
|
14682
|
+
const newPanelWidth = boundsWidth + 2 * DEFAULT_PANEL_MARGIN;
|
|
14683
|
+
const newPanelHeight = boundsHeight + 2 * DEFAULT_PANEL_MARGIN;
|
|
14663
14684
|
db.pcb_panel.update(this.pcb_panel_id, {
|
|
14664
14685
|
width: newPanelWidth,
|
|
14665
14686
|
height: newPanelHeight
|
|
@@ -14667,15 +14688,29 @@ var Panel = class extends Group6 {
|
|
|
14667
14688
|
}
|
|
14668
14689
|
}
|
|
14669
14690
|
if (this._tabsAndMouseBitesGenerated) return;
|
|
14670
|
-
const
|
|
14671
|
-
const
|
|
14672
|
-
if (
|
|
14673
|
-
|
|
14674
|
-
|
|
14675
|
-
|
|
14676
|
-
|
|
14677
|
-
|
|
14678
|
-
|
|
14691
|
+
const props = this._parsedProps;
|
|
14692
|
+
const panelizationMethod = props.panelizationMethod ?? "tab-routing";
|
|
14693
|
+
if (panelizationMethod !== "none") {
|
|
14694
|
+
const childBoardIds = childBoardInstances.map((c) => c.pcb_board_id).filter((id) => !!id);
|
|
14695
|
+
const boardsInPanel = db.pcb_board.list().filter((b) => childBoardIds.includes(b.pcb_board_id));
|
|
14696
|
+
if (boardsInPanel.length === 0) return;
|
|
14697
|
+
const tabWidth = props.tabWidth ?? DEFAULT_TAB_WIDTH;
|
|
14698
|
+
const boardGap = props.boardGap ?? tabWidth;
|
|
14699
|
+
const { tabCutouts, mouseBiteHoles } = generatePanelTabsAndMouseBites(
|
|
14700
|
+
boardsInPanel,
|
|
14701
|
+
{
|
|
14702
|
+
boardGap,
|
|
14703
|
+
tabWidth,
|
|
14704
|
+
tabLength: props.tabLength ?? DEFAULT_TAB_LENGTH,
|
|
14705
|
+
mouseBites: props.mouseBites ?? true
|
|
14706
|
+
}
|
|
14707
|
+
);
|
|
14708
|
+
for (const tabCutout of tabCutouts) {
|
|
14709
|
+
db.pcb_cutout.insert(tabCutout);
|
|
14710
|
+
}
|
|
14711
|
+
for (const mouseBiteHole of mouseBiteHoles) {
|
|
14712
|
+
db.pcb_hole.insert(mouseBiteHole);
|
|
14713
|
+
}
|
|
14679
14714
|
}
|
|
14680
14715
|
this._tabsAndMouseBitesGenerated = true;
|
|
14681
14716
|
}
|
|
@@ -18493,7 +18528,7 @@ import { identity as identity6 } from "transformation-matrix";
|
|
|
18493
18528
|
var package_default = {
|
|
18494
18529
|
name: "@tscircuit/core",
|
|
18495
18530
|
type: "module",
|
|
18496
|
-
version: "0.0.
|
|
18531
|
+
version: "0.0.872",
|
|
18497
18532
|
types: "dist/index.d.ts",
|
|
18498
18533
|
main: "dist/index.js",
|
|
18499
18534
|
module: "dist/index.js",
|
|
@@ -18537,7 +18572,7 @@ var package_default = {
|
|
|
18537
18572
|
"@tscircuit/math-utils": "^0.0.29",
|
|
18538
18573
|
"@tscircuit/miniflex": "^0.0.4",
|
|
18539
18574
|
"@tscircuit/ngspice-spice-engine": "^0.0.3",
|
|
18540
|
-
"@tscircuit/props": "^0.0.
|
|
18575
|
+
"@tscircuit/props": "^0.0.409",
|
|
18541
18576
|
"@tscircuit/schematic-autolayout": "^0.0.6",
|
|
18542
18577
|
"@tscircuit/schematic-match-adapt": "^0.0.16",
|
|
18543
18578
|
"@tscircuit/schematic-trace-solver": "^v0.0.45",
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tscircuit/core",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.0.
|
|
4
|
+
"version": "0.0.873",
|
|
5
5
|
"types": "dist/index.d.ts",
|
|
6
6
|
"main": "dist/index.js",
|
|
7
7
|
"module": "dist/index.js",
|
|
@@ -45,7 +45,7 @@
|
|
|
45
45
|
"@tscircuit/math-utils": "^0.0.29",
|
|
46
46
|
"@tscircuit/miniflex": "^0.0.4",
|
|
47
47
|
"@tscircuit/ngspice-spice-engine": "^0.0.3",
|
|
48
|
-
"@tscircuit/props": "^0.0.
|
|
48
|
+
"@tscircuit/props": "^0.0.409",
|
|
49
49
|
"@tscircuit/schematic-autolayout": "^0.0.6",
|
|
50
50
|
"@tscircuit/schematic-match-adapt": "^0.0.16",
|
|
51
51
|
"@tscircuit/schematic-trace-solver": "^v0.0.45",
|