@tscircuit/matchpack 0.0.22 → 0.0.23

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 CHANGED
@@ -175,6 +175,30 @@ type OutputLayout = {
175
175
  groupPlacements: Record<GroupId, Placement>;
176
176
  };
177
177
 
178
+ declare class AlignPowerGroundRowsSolver extends BaseSolver {
179
+ inputProblem: InputProblem;
180
+ inputLayout: OutputLayout;
181
+ outputLayout: OutputLayout | null;
182
+ constructor(params: {
183
+ inputProblem: InputProblem;
184
+ inputLayout: OutputLayout;
185
+ });
186
+ _step(): void;
187
+ private isPowerGroundNet;
188
+ private getPinNetIds;
189
+ private getAlignmentGroupId;
190
+ private getAlignmentGroups;
191
+ private alignGroup;
192
+ private createAlignedLayout;
193
+ visualize(): GraphicsObject;
194
+ getConstructorParams(): [
195
+ {
196
+ inputProblem: InputProblem;
197
+ inputLayout: OutputLayout;
198
+ }
199
+ ];
200
+ }
201
+
178
202
  /**
179
203
  * Packs components within a single partition to create an optimal internal layout.
180
204
  * Uses a packing algorithm to arrange chips and their connections within the partition.
@@ -266,6 +290,7 @@ declare class LayoutPipelineSolver extends BaseSolver {
266
290
  chipPartitionsSolver?: ChipPartitionsSolver;
267
291
  packInnerPartitionsSolver?: PackInnerPartitionsSolver;
268
292
  partitionPackingSolver?: PartitionPackingSolver;
293
+ alignPowerGroundRowsSolver?: AlignPowerGroundRowsSolver;
269
294
  startTimeOfPhase: Record<string, number>;
270
295
  endTimeOfPhase: Record<string, number>;
271
296
  timeSpentOnPhase: Record<string, number>;
@@ -274,7 +299,7 @@ declare class LayoutPipelineSolver extends BaseSolver {
274
299
  inputProblem: InputProblem;
275
300
  chipPartitions?: ChipPartitionsSolver["partitions"];
276
301
  packedPartitions?: PackedPartition[];
277
- pipelineDef: (PipelineStep<typeof IdentifyDecouplingCapsSolver> | PipelineStep<typeof ChipPartitionsSolver> | PipelineStep<typeof PackInnerPartitionsSolver> | PipelineStep<typeof PartitionPackingSolver>)[];
302
+ pipelineDef: (PipelineStep<typeof IdentifyDecouplingCapsSolver> | PipelineStep<typeof ChipPartitionsSolver> | PipelineStep<typeof PackInnerPartitionsSolver> | PipelineStep<typeof PartitionPackingSolver> | PipelineStep<typeof AlignPowerGroundRowsSolver>)[];
278
303
  constructor(inputProblem: InputProblem);
279
304
  currentPipelineStepIndex: number;
280
305
  _step(): void;
package/dist/index.js CHANGED
@@ -712,6 +712,136 @@ ${group.decouplingCapGroupId}`;
712
712
  }
713
713
  };
714
714
 
715
+ // lib/solvers/AlignPowerGroundRowsSolver/AlignPowerGroundRowsSolver.ts
716
+ var AlignPowerGroundRowsSolver = class extends BaseSolver {
717
+ inputProblem;
718
+ inputLayout;
719
+ outputLayout = null;
720
+ constructor(params) {
721
+ super();
722
+ this.inputProblem = params.inputProblem;
723
+ this.inputLayout = params.inputLayout;
724
+ }
725
+ _step() {
726
+ this.outputLayout = this.createAlignedLayout() ?? this.inputLayout;
727
+ this.solved = true;
728
+ }
729
+ isPowerGroundNet(netId) {
730
+ const net = this.inputProblem.netMap[netId];
731
+ return net?.isPositiveVoltageSource === true || net?.isGround === true;
732
+ }
733
+ getPinNetIds(pinId) {
734
+ const netIds = [];
735
+ for (const [connKey, connected] of Object.entries(
736
+ this.inputProblem.netConnMap
737
+ )) {
738
+ if (!connected) continue;
739
+ if (!connKey.startsWith(`${pinId}-`)) continue;
740
+ netIds.push(connKey.slice(pinId.length + 1));
741
+ }
742
+ return netIds;
743
+ }
744
+ getAlignmentGroupId(chip) {
745
+ if (chip.fixedPosition || chip.pins.length !== 2) return null;
746
+ const signalNetIds = /* @__PURE__ */ new Set();
747
+ let connectedPowerGroundPinCount = 0;
748
+ for (const pinId of chip.pins) {
749
+ const pinNetIds = this.getPinNetIds(pinId);
750
+ if (pinNetIds.length === 0) return null;
751
+ let pinHasPowerGroundNet = false;
752
+ for (const netId of pinNetIds) {
753
+ if (this.isPowerGroundNet(netId)) {
754
+ pinHasPowerGroundNet = true;
755
+ } else {
756
+ signalNetIds.add(netId);
757
+ }
758
+ }
759
+ if (pinHasPowerGroundNet) connectedPowerGroundPinCount++;
760
+ }
761
+ if (connectedPowerGroundPinCount === 0) return null;
762
+ if (signalNetIds.size === 0) return "power-ground";
763
+ if (signalNetIds.size === 1) return `signal:${[...signalNetIds][0]}`;
764
+ return null;
765
+ }
766
+ getAlignmentGroups() {
767
+ const chipIds = Object.keys(this.inputProblem.chipMap);
768
+ if (chipIds.length < 2) return null;
769
+ const groupMap = /* @__PURE__ */ new Map();
770
+ for (const chipId of chipIds) {
771
+ const chip = this.inputProblem.chipMap[chipId];
772
+ if (!chip) return null;
773
+ if (!this.inputLayout.chipPlacements[chipId]) return null;
774
+ const groupId = this.getAlignmentGroupId(chip);
775
+ if (!groupId) return null;
776
+ const groupChipIds = groupMap.get(groupId) ?? [];
777
+ groupChipIds.push(chipId);
778
+ groupMap.set(groupId, groupChipIds);
779
+ }
780
+ return [...groupMap.values()].map((groupChipIds) => ({
781
+ chipIds: groupChipIds.sort(
782
+ (chipIdA, chipIdB) => this.inputLayout.chipPlacements[chipIdA].x - this.inputLayout.chipPlacements[chipIdB].x
783
+ )
784
+ }));
785
+ }
786
+ alignGroup(chipPlacements, chipIds) {
787
+ if (chipIds.length < 2) return;
788
+ let cursorX = 0;
789
+ const rowY = chipIds.reduce(
790
+ (sum, chipId) => sum + this.inputLayout.chipPlacements[chipId].y,
791
+ 0
792
+ ) / chipIds.length;
793
+ const rowCenterX = chipIds.reduce(
794
+ (sum, chipId) => sum + this.inputLayout.chipPlacements[chipId].x,
795
+ 0
796
+ ) / chipIds.length;
797
+ for (const chipId of chipIds) {
798
+ const chip = this.inputProblem.chipMap[chipId];
799
+ const originalPlacement = this.inputLayout.chipPlacements[chipId];
800
+ const isRotated = originalPlacement.ccwRotationDegrees === 90 || originalPlacement.ccwRotationDegrees === 270;
801
+ const width = isRotated ? chip.size.y : chip.size.x;
802
+ const x = cursorX + width / 2;
803
+ chipPlacements[chipId] = {
804
+ x,
805
+ y: rowY,
806
+ ccwRotationDegrees: originalPlacement.ccwRotationDegrees
807
+ };
808
+ cursorX += width + this.inputProblem.partitionGap;
809
+ }
810
+ const rowWidth = cursorX - this.inputProblem.partitionGap;
811
+ for (const chipId of chipIds) {
812
+ chipPlacements[chipId].x += rowCenterX - rowWidth / 2;
813
+ }
814
+ }
815
+ createAlignedLayout() {
816
+ const groups = this.getAlignmentGroups();
817
+ if (!groups) return null;
818
+ const chipPlacements = {
819
+ ...this.inputLayout.chipPlacements
820
+ };
821
+ for (const group of groups) {
822
+ this.alignGroup(chipPlacements, group.chipIds);
823
+ }
824
+ return {
825
+ chipPlacements,
826
+ groupPlacements: { ...this.inputLayout.groupPlacements }
827
+ };
828
+ }
829
+ visualize() {
830
+ return visualizeInputProblem(
831
+ this.inputProblem,
832
+ this.outputLayout ?? this.inputLayout
833
+ );
834
+ }
835
+ getConstructorParams() {
836
+ return [
837
+ {
838
+ inputProblem: this.inputProblem,
839
+ inputLayout: this.inputLayout
840
+ }
841
+ ];
842
+ }
843
+ };
844
+
715
845
  // lib/solvers/PackInnerPartitionsSolver/SingleInnerPartitionPackingSolver.ts
716
846
  import { PackSolver2 } from "calculate-packing";
717
847
 
@@ -1369,6 +1499,7 @@ var LayoutPipelineSolver = class extends BaseSolver {
1369
1499
  chipPartitionsSolver;
1370
1500
  packInnerPartitionsSolver;
1371
1501
  partitionPackingSolver;
1502
+ alignPowerGroundRowsSolver;
1372
1503
  startTimeOfPhase;
1373
1504
  endTimeOfPhase;
1374
1505
  timeSpentOnPhase;
@@ -1431,6 +1562,16 @@ var LayoutPipelineSolver = class extends BaseSolver {
1431
1562
  onSolved: (_solver) => {
1432
1563
  }
1433
1564
  }
1565
+ ),
1566
+ definePipelineStep(
1567
+ "alignPowerGroundRowsSolver",
1568
+ AlignPowerGroundRowsSolver,
1569
+ () => [
1570
+ {
1571
+ inputProblem: this.inputProblem,
1572
+ inputLayout: this.partitionPackingSolver.finalLayout
1573
+ }
1574
+ ]
1434
1575
  )
1435
1576
  ];
1436
1577
  constructor(inputProblem) {
@@ -1483,6 +1624,9 @@ var LayoutPipelineSolver = class extends BaseSolver {
1483
1624
  visualize() {
1484
1625
  if (!this.solved && this.activeSubSolver)
1485
1626
  return this.activeSubSolver.visualize();
1627
+ if (this.solved && this.alignPowerGroundRowsSolver?.solved) {
1628
+ return this.alignPowerGroundRowsSolver.visualize();
1629
+ }
1486
1630
  if (this.solved && this.partitionPackingSolver?.solved) {
1487
1631
  return this.partitionPackingSolver.visualize();
1488
1632
  }
@@ -1490,6 +1634,7 @@ var LayoutPipelineSolver = class extends BaseSolver {
1490
1634
  const chipPartitionsViz = this.chipPartitionsSolver?.visualize();
1491
1635
  const packInnerPartitionsViz = this.packInnerPartitionsSolver?.visualize();
1492
1636
  const partitionPackingViz = this.partitionPackingSolver?.visualize();
1637
+ const alignPowerGroundRowsViz = this.alignPowerGroundRowsSolver?.visualize();
1493
1638
  const basicLayout = doBasicInputProblemLayout(this.inputProblem);
1494
1639
  const inputViz = visualizeInputProblem(this.inputProblem, basicLayout);
1495
1640
  const visualizations = [
@@ -1497,7 +1642,8 @@ var LayoutPipelineSolver = class extends BaseSolver {
1497
1642
  identifyDecouplingCapsViz,
1498
1643
  chipPartitionsViz,
1499
1644
  packInnerPartitionsViz,
1500
- partitionPackingViz
1645
+ partitionPackingViz,
1646
+ alignPowerGroundRowsViz
1501
1647
  ].filter(Boolean).map((viz, stepIndex) => {
1502
1648
  for (const rect of viz.rects ?? []) {
1503
1649
  rect.step = stepIndex;
@@ -1533,6 +1679,9 @@ var LayoutPipelineSolver = class extends BaseSolver {
1533
1679
  if (this.activeSubSolver) {
1534
1680
  return this.activeSubSolver.preview();
1535
1681
  }
1682
+ if (this.alignPowerGroundRowsSolver?.solved) {
1683
+ return this.alignPowerGroundRowsSolver.visualize();
1684
+ }
1536
1685
  if (this.partitionPackingSolver?.solved) {
1537
1686
  return this.partitionPackingSolver.visualize();
1538
1687
  }
@@ -1613,7 +1762,9 @@ var LayoutPipelineSolver = class extends BaseSolver {
1613
1762
  );
1614
1763
  }
1615
1764
  let finalLayout;
1616
- if (this.partitionPackingSolver?.solved && this.partitionPackingSolver.finalLayout) {
1765
+ if (this.alignPowerGroundRowsSolver?.solved && this.alignPowerGroundRowsSolver.outputLayout) {
1766
+ finalLayout = this.alignPowerGroundRowsSolver.outputLayout;
1767
+ } else if (this.partitionPackingSolver?.solved && this.partitionPackingSolver.finalLayout) {
1617
1768
  finalLayout = this.partitionPackingSolver.finalLayout;
1618
1769
  } else {
1619
1770
  throw new Error(
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@tscircuit/matchpack",
3
3
  "main": "dist/index.js",
4
4
  "type": "module",
5
- "version": "0.0.22",
5
+ "version": "0.0.23",
6
6
  "files": [
7
7
  "dist"
8
8
  ],
@@ -28,7 +28,7 @@
28
28
  "graphics-debug": "^0.0.95",
29
29
  "react-cosmos": "^7.3.0",
30
30
  "react-cosmos-plugin-vite": "^7.3.0",
31
- "tscircuit": "^0.0.1887",
31
+ "tscircuit": "^0.0.1891",
32
32
  "tsup": "^8.5.1",
33
33
  "circuit-to-svg": "^0.0.351"
34
34
  },