@tscircuit/circuit-json-util 0.0.54 → 0.0.56
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 +20 -2
- package/dist/index.js +137 -114
- package/dist/index.js.map +1 -1
- package/package.json +2 -1
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { AnyCircuitElement, AnyCircuitElementInput } from 'circuit-json';
|
|
1
|
+
import { AnyCircuitElement, AnyCircuitElementInput, SourceGroup, SourceComponentBase } from 'circuit-json';
|
|
2
2
|
import { Matrix } from 'transformation-matrix';
|
|
3
3
|
import * as parsel from 'parsel-js';
|
|
4
4
|
|
|
@@ -6017,4 +6017,22 @@ declare const repositionPcbComponentTo: (circuitJson: AnyCircuitElement[], pcb_c
|
|
|
6017
6017
|
y: number;
|
|
6018
6018
|
}) => void;
|
|
6019
6019
|
|
|
6020
|
-
|
|
6020
|
+
/**
|
|
6021
|
+
* A tree of circuit elements. This is often used for layout because you want
|
|
6022
|
+
* to consider only the top-level elements of a group for layout (child groups
|
|
6023
|
+
* move together)
|
|
6024
|
+
*/
|
|
6025
|
+
interface CircuitJsonTreeNode {
|
|
6026
|
+
nodeType: "group" | "component";
|
|
6027
|
+
sourceGroup?: SourceGroup;
|
|
6028
|
+
sourceComponent?: SourceComponentBase;
|
|
6029
|
+
childNodes: Array<CircuitJsonTreeNode>;
|
|
6030
|
+
otherChildElements: Array<AnyCircuitElement>;
|
|
6031
|
+
}
|
|
6032
|
+
declare const getCircuitJsonTree: (circuitJson: AnyCircuitElement[], opts?: {
|
|
6033
|
+
source_group_id?: string;
|
|
6034
|
+
}) => CircuitJsonTreeNode;
|
|
6035
|
+
|
|
6036
|
+
declare const getStringFromCircuitJsonTree: (circuitJsonTree: CircuitJsonTreeNode, indent?: number) => string;
|
|
6037
|
+
|
|
6038
|
+
export { type CircuitJsonInputUtilObjects, type CircuitJsonOps, type CircuitJsonTreeNode, type CircuitJsonUtilObjects, type CircuitJsonUtilOptions, type GetCircuitJsonUtilFn, type GetIndexedCircuitJsonUtilFn, type IndexedCircuitJsonUtilOptions, type SubtreeOptions, applySelector, applySelectorAST, buildSubtree, cju, cjuIndexed, directionToVec, findBoundsAndCenter, getBoundsOfPcbElements, getCircuitJsonTree, getElementById, getElementId, getPrimaryId, getReadableNameForElement, getReadableNameForPcbPort, getReadableNameForPcbSmtpad, getReadableNameForPcbTrace, getStringFromCircuitJsonTree, oppositeDirection, oppositeSide, repositionPcbComponentTo, rotateClockwise, rotateCounterClockwise, rotateDirection, su, transformPCBElement, transformPCBElements, transformSchematicElement, transformSchematicElements, vecToDirection };
|
package/dist/index.js
CHANGED
|
@@ -3,8 +3,7 @@ import * as Soup from "circuit-json";
|
|
|
3
3
|
|
|
4
4
|
// lib/subtree.ts
|
|
5
5
|
function connect(map, a, b) {
|
|
6
|
-
if (!a || !b)
|
|
7
|
-
return;
|
|
6
|
+
if (!a || !b) return;
|
|
8
7
|
let setA = map.get(a);
|
|
9
8
|
if (!setA) {
|
|
10
9
|
setA = /* @__PURE__ */ new Set();
|
|
@@ -19,8 +18,7 @@ function connect(map, a, b) {
|
|
|
19
18
|
setB.add(a);
|
|
20
19
|
}
|
|
21
20
|
function buildSubtree(soup, opts) {
|
|
22
|
-
if (!opts.subcircuit_id && !opts.source_group_id)
|
|
23
|
-
return [...soup];
|
|
21
|
+
if (!opts.subcircuit_id && !opts.source_group_id) return [...soup];
|
|
24
22
|
const idMap = /* @__PURE__ */ new Map();
|
|
25
23
|
for (const elm of soup) {
|
|
26
24
|
const idVal = elm[`${elm.type}_id`];
|
|
@@ -32,8 +30,7 @@ function buildSubtree(soup, opts) {
|
|
|
32
30
|
for (const elm of soup) {
|
|
33
31
|
const entries = Object.entries(elm);
|
|
34
32
|
for (const [key, val] of entries) {
|
|
35
|
-
if (key === "parent_source_group_id")
|
|
36
|
-
continue;
|
|
33
|
+
if (key === "parent_source_group_id") continue;
|
|
37
34
|
if (key.endsWith("_id") && typeof val === "string") {
|
|
38
35
|
const other = idMap.get(val);
|
|
39
36
|
connect(adj, elm, other);
|
|
@@ -60,8 +57,7 @@ function buildSubtree(soup, opts) {
|
|
|
60
57
|
while (queue.length > 0) {
|
|
61
58
|
const elm = queue.shift();
|
|
62
59
|
const neighbors = adj.get(elm);
|
|
63
|
-
if (!neighbors)
|
|
64
|
-
continue;
|
|
60
|
+
if (!neighbors) continue;
|
|
65
61
|
for (const n of neighbors) {
|
|
66
62
|
if (!included.has(n)) {
|
|
67
63
|
included.add(n);
|
|
@@ -85,8 +81,7 @@ var cju = (circuitJsonInput, options = {}) => {
|
|
|
85
81
|
for (const elm of circuitJson) {
|
|
86
82
|
const type = elm.type;
|
|
87
83
|
const idVal = elm[`${type}_id`];
|
|
88
|
-
if (!idVal)
|
|
89
|
-
continue;
|
|
84
|
+
if (!idVal) continue;
|
|
90
85
|
const idNum = Number.parseInt(idVal.split("_").pop());
|
|
91
86
|
if (!Number.isNaN(idNum)) {
|
|
92
87
|
internalStore.counts[type] = Math.max(
|
|
@@ -130,8 +125,7 @@ var cju = (circuitJsonInput, options = {}) => {
|
|
|
130
125
|
const joiner = circuitJson.find(
|
|
131
126
|
(e) => e.type === join_type && e[join_key] === using[join_key]
|
|
132
127
|
);
|
|
133
|
-
if (!joiner)
|
|
134
|
-
return null;
|
|
128
|
+
if (!joiner) return null;
|
|
135
129
|
return circuitJson.find(
|
|
136
130
|
(e) => e.type === component_type && e[`${component_type}_id`] === joiner[`${component_type}_id`]
|
|
137
131
|
);
|
|
@@ -169,8 +163,7 @@ var cju = (circuitJsonInput, options = {}) => {
|
|
|
169
163
|
const elm = circuitJson.find(
|
|
170
164
|
(e) => e[`${component_type}_id`] === id
|
|
171
165
|
);
|
|
172
|
-
if (!elm)
|
|
173
|
-
return;
|
|
166
|
+
if (!elm) return;
|
|
174
167
|
circuitJson.splice(circuitJson.indexOf(elm), 1);
|
|
175
168
|
internalStore.editCount++;
|
|
176
169
|
},
|
|
@@ -178,8 +171,7 @@ var cju = (circuitJsonInput, options = {}) => {
|
|
|
178
171
|
const elm = circuitJson.find(
|
|
179
172
|
(e) => e.type === component_type && e[`${component_type}_id`] === id
|
|
180
173
|
);
|
|
181
|
-
if (!elm)
|
|
182
|
-
return null;
|
|
174
|
+
if (!elm) return null;
|
|
183
175
|
Object.assign(elm, newProps);
|
|
184
176
|
internalStore.editCount++;
|
|
185
177
|
return elm;
|
|
@@ -194,15 +186,12 @@ var cju = (circuitJsonInput, options = {}) => {
|
|
|
194
186
|
const source_component = circuitJson.find(
|
|
195
187
|
(e) => e.type === "source_component" && e.name === component_name
|
|
196
188
|
);
|
|
197
|
-
if (!source_component)
|
|
198
|
-
return null;
|
|
189
|
+
if (!source_component) return null;
|
|
199
190
|
const source_port = circuitJson.find(
|
|
200
191
|
(e) => e.type === "source_port" && e.source_component_id === source_component.source_component_id && (e.name === port_selector || (e.port_hints ?? []).includes(port_selector))
|
|
201
192
|
);
|
|
202
|
-
if (!source_port)
|
|
203
|
-
|
|
204
|
-
if (component_type === "source_port")
|
|
205
|
-
return source_port;
|
|
193
|
+
if (!source_port) return null;
|
|
194
|
+
if (component_type === "source_port") return source_port;
|
|
206
195
|
if (component_type === "pcb_port") {
|
|
207
196
|
return circuitJson.find(
|
|
208
197
|
(e) => e.type === "pcb_port" && e.source_port_id === source_port.source_port_id
|
|
@@ -241,8 +230,7 @@ var cjuIndexed = (soup, options = {}) => {
|
|
|
241
230
|
for (const elm of soup) {
|
|
242
231
|
const type = elm.type;
|
|
243
232
|
const idVal = elm[`${type}_id`];
|
|
244
|
-
if (!idVal)
|
|
245
|
-
continue;
|
|
233
|
+
if (!idVal) continue;
|
|
246
234
|
const idNum = Number.parseInt(idVal.split("_").pop() || "");
|
|
247
235
|
if (!Number.isNaN(idNum)) {
|
|
248
236
|
internalStore.counts[type] = Math.max(
|
|
@@ -367,8 +355,7 @@ var cjuIndexed = (soup, options = {}) => {
|
|
|
367
355
|
if (relationMap) {
|
|
368
356
|
const relatedElements = relationMap.get(using[join_key]) || [];
|
|
369
357
|
const joiner2 = relatedElements.find((e) => e.type === join_type);
|
|
370
|
-
if (!joiner2)
|
|
371
|
-
return null;
|
|
358
|
+
if (!joiner2) return null;
|
|
372
359
|
const joinerId = joiner2[`${component_type}_id`];
|
|
373
360
|
if (indexConfig.byId && internalStore.indexes.byId) {
|
|
374
361
|
return internalStore.indexes.byId.get(
|
|
@@ -389,8 +376,7 @@ var cjuIndexed = (soup, options = {}) => {
|
|
|
389
376
|
const joiner = soup.find(
|
|
390
377
|
(e) => e.type === join_type && e[join_key] === using[join_key]
|
|
391
378
|
);
|
|
392
|
-
if (!joiner)
|
|
393
|
-
return null;
|
|
379
|
+
if (!joiner) return null;
|
|
394
380
|
return soup.find(
|
|
395
381
|
(e) => e.type === component_type && e[`${component_type}_id`] === joiner[`${component_type}_id`]
|
|
396
382
|
) || null;
|
|
@@ -529,8 +515,7 @@ var cjuIndexed = (soup, options = {}) => {
|
|
|
529
515
|
} else {
|
|
530
516
|
elm = soup.find((e) => e[`${component_type}_id`] === id);
|
|
531
517
|
}
|
|
532
|
-
if (!elm)
|
|
533
|
-
return;
|
|
518
|
+
if (!elm) return;
|
|
534
519
|
const elmIndex = soup.indexOf(elm);
|
|
535
520
|
if (elmIndex >= 0) {
|
|
536
521
|
soup.splice(elmIndex, 1);
|
|
@@ -607,8 +592,7 @@ var cjuIndexed = (soup, options = {}) => {
|
|
|
607
592
|
(e) => e.type === component_type && e[`${component_type}_id`] === id
|
|
608
593
|
);
|
|
609
594
|
}
|
|
610
|
-
if (!elm)
|
|
611
|
-
return null;
|
|
595
|
+
if (!elm) return null;
|
|
612
596
|
if (indexConfig.byRelation && internalStore.indexes.byRelation) {
|
|
613
597
|
const elementEntries = Object.entries(elm);
|
|
614
598
|
for (const [key, value] of elementEntries) {
|
|
@@ -724,13 +708,11 @@ var cjuIndexed = (soup, options = {}) => {
|
|
|
724
708
|
const source_component = soup.find(
|
|
725
709
|
(e) => e.type === "source_component" && e.name === component_name
|
|
726
710
|
);
|
|
727
|
-
if (!source_component)
|
|
728
|
-
return null;
|
|
711
|
+
if (!source_component) return null;
|
|
729
712
|
const source_port = soup.find(
|
|
730
713
|
(e) => e.type === "source_port" && e.source_component_id === source_component.source_component_id && (e.name === port_selector || (e.port_hints ?? []).includes(port_selector))
|
|
731
714
|
);
|
|
732
|
-
if (!source_port)
|
|
733
|
-
return null;
|
|
715
|
+
if (!source_port) return null;
|
|
734
716
|
if (component_type === "source_port")
|
|
735
717
|
return source_port;
|
|
736
718
|
if (component_type === "pcb_port") {
|
|
@@ -759,53 +741,33 @@ import { applyToPoint, decomposeTSR } from "transformation-matrix";
|
|
|
759
741
|
|
|
760
742
|
// lib/direction-to-vec.ts
|
|
761
743
|
var directionToVec = (direction) => {
|
|
762
|
-
if (direction === "up")
|
|
763
|
-
|
|
764
|
-
else if (direction === "
|
|
765
|
-
|
|
766
|
-
else
|
|
767
|
-
return { x: -1, y: 0 };
|
|
768
|
-
else if (direction === "right")
|
|
769
|
-
return { x: 1, y: 0 };
|
|
770
|
-
else
|
|
771
|
-
throw new Error("Invalid direction");
|
|
744
|
+
if (direction === "up") return { x: 0, y: 1 };
|
|
745
|
+
else if (direction === "down") return { x: 0, y: -1 };
|
|
746
|
+
else if (direction === "left") return { x: -1, y: 0 };
|
|
747
|
+
else if (direction === "right") return { x: 1, y: 0 };
|
|
748
|
+
else throw new Error("Invalid direction");
|
|
772
749
|
};
|
|
773
750
|
var vecToDirection = ({ x, y }) => {
|
|
774
|
-
if (x > y)
|
|
775
|
-
|
|
776
|
-
if (
|
|
777
|
-
|
|
778
|
-
if (x
|
|
779
|
-
|
|
780
|
-
else
|
|
781
|
-
return "left";
|
|
782
|
-
else if (x === 0 && y > 0)
|
|
783
|
-
return "up";
|
|
784
|
-
else if (x === 0 && y < 0)
|
|
785
|
-
return "down";
|
|
786
|
-
else
|
|
787
|
-
throw new Error(`Invalid vector for direction conversion (${x}, ${y})`);
|
|
751
|
+
if (x > y) y = 0;
|
|
752
|
+
if (y > x) x = 0;
|
|
753
|
+
if (x > 0 && y === 0) return "right";
|
|
754
|
+
else if (x < 0 && y === 0) return "left";
|
|
755
|
+
else if (x === 0 && y > 0) return "up";
|
|
756
|
+
else if (x === 0 && y < 0) return "down";
|
|
757
|
+
else throw new Error(`Invalid vector for direction conversion (${x}, ${y})`);
|
|
788
758
|
};
|
|
789
759
|
var rotateClockwise = (direction) => {
|
|
790
|
-
if (direction === "up")
|
|
791
|
-
|
|
792
|
-
else if (direction === "
|
|
793
|
-
|
|
794
|
-
else if (direction === "down")
|
|
795
|
-
return "left";
|
|
796
|
-
else if (direction === "left")
|
|
797
|
-
return "up";
|
|
760
|
+
if (direction === "up") return "right";
|
|
761
|
+
else if (direction === "right") return "down";
|
|
762
|
+
else if (direction === "down") return "left";
|
|
763
|
+
else if (direction === "left") return "up";
|
|
798
764
|
throw new Error(`Invalid direction: ${direction}`);
|
|
799
765
|
};
|
|
800
766
|
var rotateCounterClockwise = (direction) => {
|
|
801
|
-
if (direction === "up")
|
|
802
|
-
|
|
803
|
-
else if (direction === "
|
|
804
|
-
|
|
805
|
-
else if (direction === "down")
|
|
806
|
-
return "right";
|
|
807
|
-
else if (direction === "right")
|
|
808
|
-
return "up";
|
|
767
|
+
if (direction === "up") return "left";
|
|
768
|
+
else if (direction === "left") return "down";
|
|
769
|
+
else if (direction === "down") return "right";
|
|
770
|
+
else if (direction === "right") return "up";
|
|
809
771
|
throw new Error(`Invalid direction: ${direction}`);
|
|
810
772
|
};
|
|
811
773
|
var rotateDirection = (direction, num90DegreeClockwiseTurns) => {
|
|
@@ -820,25 +782,17 @@ var rotateDirection = (direction, num90DegreeClockwiseTurns) => {
|
|
|
820
782
|
return direction;
|
|
821
783
|
};
|
|
822
784
|
var oppositeDirection = (direction) => {
|
|
823
|
-
if (direction === "up")
|
|
824
|
-
|
|
825
|
-
else if (direction === "
|
|
826
|
-
|
|
827
|
-
else if (direction === "left")
|
|
828
|
-
return "right";
|
|
829
|
-
else if (direction === "right")
|
|
830
|
-
return "left";
|
|
785
|
+
if (direction === "up") return "down";
|
|
786
|
+
else if (direction === "down") return "up";
|
|
787
|
+
else if (direction === "left") return "right";
|
|
788
|
+
else if (direction === "right") return "left";
|
|
831
789
|
throw new Error(`Invalid direction: ${direction}`);
|
|
832
790
|
};
|
|
833
791
|
var oppositeSide = (sideOrDir) => {
|
|
834
|
-
if (sideOrDir === "top" || sideOrDir === "up")
|
|
835
|
-
|
|
836
|
-
else if (sideOrDir === "
|
|
837
|
-
|
|
838
|
-
else if (sideOrDir === "left")
|
|
839
|
-
return "right";
|
|
840
|
-
else if (sideOrDir === "right")
|
|
841
|
-
return "left";
|
|
792
|
+
if (sideOrDir === "top" || sideOrDir === "up") return "bottom";
|
|
793
|
+
else if (sideOrDir === "bottom" || sideOrDir === "down") return "top";
|
|
794
|
+
else if (sideOrDir === "left") return "right";
|
|
795
|
+
else if (sideOrDir === "right") return "left";
|
|
842
796
|
throw new Error(`Invalid sideOrDir: ${sideOrDir}`);
|
|
843
797
|
};
|
|
844
798
|
|
|
@@ -963,6 +917,7 @@ var applySelectorAST = (elements, selectorAST) => {
|
|
|
963
917
|
case "complex": {
|
|
964
918
|
switch (selectorAST.combinator) {
|
|
965
919
|
case " ":
|
|
920
|
+
// TODO technically should do a deep search
|
|
966
921
|
case ">": {
|
|
967
922
|
const { left, right } = selectorAST;
|
|
968
923
|
if (left.type === "class" || left.type === "type") {
|
|
@@ -1050,16 +1005,13 @@ function getReadableNameForPcbTrace(soup, pcb_trace_id) {
|
|
|
1050
1005
|
}
|
|
1051
1006
|
function getComponentAndPortInfo(pcb_port_id) {
|
|
1052
1007
|
const pcbPort = cju(soup).pcb_port.get(pcb_port_id);
|
|
1053
|
-
if (!pcbPort)
|
|
1054
|
-
return null;
|
|
1008
|
+
if (!pcbPort) return null;
|
|
1055
1009
|
const pcbComponent = cju(soup).pcb_component.get(pcbPort.pcb_component_id);
|
|
1056
|
-
if (!pcbComponent)
|
|
1057
|
-
return null;
|
|
1010
|
+
if (!pcbComponent) return null;
|
|
1058
1011
|
const sourceComponent = cju(soup).source_component.get(
|
|
1059
1012
|
pcbComponent.source_component_id
|
|
1060
1013
|
);
|
|
1061
|
-
if (!sourceComponent)
|
|
1062
|
-
return null;
|
|
1014
|
+
if (!sourceComponent) return null;
|
|
1063
1015
|
const sourcePort = cju(soup).source_port.get(pcbPort.source_port_id);
|
|
1064
1016
|
const portHint = sourcePort?.port_hints ? sourcePort.port_hints[1] : "";
|
|
1065
1017
|
return {
|
|
@@ -1121,8 +1073,7 @@ function getReadableNameForPcbSmtpad(soup, pcb_smtpad_id) {
|
|
|
1121
1073
|
var getReadableNameForElement = (soup, elm) => {
|
|
1122
1074
|
if (typeof elm === "string") {
|
|
1123
1075
|
const elmObj = getElementById(soup, elm);
|
|
1124
|
-
if (!elmObj)
|
|
1125
|
-
`unknown (could not find element with id ${elm})`;
|
|
1076
|
+
if (!elmObj) `unknown (could not find element with id ${elm})`;
|
|
1126
1077
|
return getReadableNameForElement(soup, elmObj);
|
|
1127
1078
|
}
|
|
1128
1079
|
switch (elm.type) {
|
|
@@ -1146,8 +1097,7 @@ var getBoundsOfPcbElements = (elements) => {
|
|
|
1146
1097
|
let maxX = Number.NEGATIVE_INFINITY;
|
|
1147
1098
|
let maxY = Number.NEGATIVE_INFINITY;
|
|
1148
1099
|
for (const elm of elements) {
|
|
1149
|
-
if (!elm.type.startsWith("pcb_"))
|
|
1150
|
-
continue;
|
|
1100
|
+
if (!elm.type.startsWith("pcb_")) continue;
|
|
1151
1101
|
let centerX;
|
|
1152
1102
|
let centerY;
|
|
1153
1103
|
let width;
|
|
@@ -1202,8 +1152,7 @@ var getBoundsOfPcbElements = (elements) => {
|
|
|
1202
1152
|
// lib/utils/string-hash.ts
|
|
1203
1153
|
function stringHash(str) {
|
|
1204
1154
|
let hash = 0;
|
|
1205
|
-
if (str.length == 0)
|
|
1206
|
-
return hash;
|
|
1155
|
+
if (str.length == 0) return hash;
|
|
1207
1156
|
for (var i = 0; i < str.length; i++) {
|
|
1208
1157
|
var char = str.charCodeAt(i);
|
|
1209
1158
|
hash = (hash << 5) - hash + char;
|
|
@@ -1347,8 +1296,7 @@ var getDebugLayoutObject = (lo) => {
|
|
|
1347
1296
|
}
|
|
1348
1297
|
const title = lo.text || lo.name || lo.source?.text || lo.source?.name || "?";
|
|
1349
1298
|
const content = lo;
|
|
1350
|
-
if (x === void 0 || y === void 0)
|
|
1351
|
-
return null;
|
|
1299
|
+
if (x === void 0 || y === void 0) return null;
|
|
1352
1300
|
if (width === void 0) {
|
|
1353
1301
|
if ("outer_diameter" in lo) {
|
|
1354
1302
|
width = lo.outer_diameter;
|
|
@@ -1407,8 +1355,7 @@ var repositionPcbComponentTo = (circuitJson, pcb_component_id, newCenter) => {
|
|
|
1407
1355
|
const pcbComponent = circuitJson.find(
|
|
1408
1356
|
(e) => e.type === "pcb_component" && e.pcb_component_id === pcb_component_id
|
|
1409
1357
|
);
|
|
1410
|
-
if (!pcbComponent)
|
|
1411
|
-
return;
|
|
1358
|
+
if (!pcbComponent) return;
|
|
1412
1359
|
const currentCenter = "center" in pcbComponent ? pcbComponent.center : { x: pcbComponent.x, y: pcbComponent.y };
|
|
1413
1360
|
const dx = newCenter.x - currentCenter.x;
|
|
1414
1361
|
const dy = newCenter.y - currentCenter.y;
|
|
@@ -1416,15 +1363,12 @@ var repositionPcbComponentTo = (circuitJson, pcb_component_id, newCenter) => {
|
|
|
1416
1363
|
(e) => e.type === "pcb_port" && e.pcb_component_id === pcb_component_id
|
|
1417
1364
|
).map((e) => e.pcb_port_id);
|
|
1418
1365
|
const elementsToMove = circuitJson.filter((elm) => {
|
|
1419
|
-
if (elm === pcbComponent)
|
|
1420
|
-
return true;
|
|
1366
|
+
if (elm === pcbComponent) return true;
|
|
1421
1367
|
const anyElm = elm;
|
|
1422
|
-
if (anyElm.pcb_component_id === pcb_component_id)
|
|
1423
|
-
return true;
|
|
1368
|
+
if (anyElm.pcb_component_id === pcb_component_id) return true;
|
|
1424
1369
|
if (Array.isArray(anyElm.pcb_component_ids) && anyElm.pcb_component_ids.includes(pcb_component_id))
|
|
1425
1370
|
return true;
|
|
1426
|
-
if (anyElm.pcb_port_id && portIds.includes(anyElm.pcb_port_id))
|
|
1427
|
-
return true;
|
|
1371
|
+
if (anyElm.pcb_port_id && portIds.includes(anyElm.pcb_port_id)) return true;
|
|
1428
1372
|
if (Array.isArray(anyElm.pcb_port_ids) && anyElm.pcb_port_ids.some((id) => portIds.includes(id)))
|
|
1429
1373
|
return true;
|
|
1430
1374
|
if (anyElm.start_pcb_port_id && portIds.includes(anyElm.start_pcb_port_id))
|
|
@@ -1440,6 +1384,83 @@ var repositionPcbComponentTo = (circuitJson, pcb_component_id, newCenter) => {
|
|
|
1440
1384
|
const matrix = translate(dx, dy);
|
|
1441
1385
|
transformPCBElements(elementsToMove, matrix);
|
|
1442
1386
|
};
|
|
1387
|
+
|
|
1388
|
+
// lib/getCircuitJsonTree.ts
|
|
1389
|
+
var getCircuitJsonTree = (circuitJson, opts) => {
|
|
1390
|
+
const groupChildMap = /* @__PURE__ */ new Map();
|
|
1391
|
+
for (const elm of circuitJson) {
|
|
1392
|
+
if (elm.type === "source_group" && elm.parent_source_group_id) {
|
|
1393
|
+
const parentId = elm.parent_source_group_id;
|
|
1394
|
+
const childId = elm.source_group_id;
|
|
1395
|
+
const children = groupChildMap.get(parentId) ?? [];
|
|
1396
|
+
children.push(childId);
|
|
1397
|
+
groupChildMap.set(parentId, children);
|
|
1398
|
+
if (!groupChildMap.has(childId)) {
|
|
1399
|
+
groupChildMap.set(childId, []);
|
|
1400
|
+
}
|
|
1401
|
+
}
|
|
1402
|
+
}
|
|
1403
|
+
const groupNodes = /* @__PURE__ */ new Map();
|
|
1404
|
+
const getNextGroupId = () => {
|
|
1405
|
+
for (const [parentId, children] of groupChildMap) {
|
|
1406
|
+
if (groupNodes.has(parentId)) continue;
|
|
1407
|
+
if (children.every((childId) => groupNodes.has(childId))) {
|
|
1408
|
+
return parentId;
|
|
1409
|
+
}
|
|
1410
|
+
}
|
|
1411
|
+
return null;
|
|
1412
|
+
};
|
|
1413
|
+
let lastGroupId = null;
|
|
1414
|
+
while (true) {
|
|
1415
|
+
const nextGroupId = getNextGroupId();
|
|
1416
|
+
if (!nextGroupId) break;
|
|
1417
|
+
const sourceGroup = circuitJson.find(
|
|
1418
|
+
(elm) => elm.type === "source_group" && elm.source_group_id === nextGroupId
|
|
1419
|
+
);
|
|
1420
|
+
const node = {
|
|
1421
|
+
nodeType: "group",
|
|
1422
|
+
sourceGroup,
|
|
1423
|
+
otherChildElements: [],
|
|
1424
|
+
childNodes: [
|
|
1425
|
+
...groupChildMap.get(nextGroupId)?.map((childId) => groupNodes.get(childId)) ?? [],
|
|
1426
|
+
...circuitJson.filter(
|
|
1427
|
+
(elm) => elm.type === "source_component" && elm.source_group_id === nextGroupId
|
|
1428
|
+
).map((elm) => {
|
|
1429
|
+
return {
|
|
1430
|
+
nodeType: "component",
|
|
1431
|
+
sourceComponent: elm,
|
|
1432
|
+
childNodes: [],
|
|
1433
|
+
otherChildElements: []
|
|
1434
|
+
// TODO
|
|
1435
|
+
};
|
|
1436
|
+
})
|
|
1437
|
+
]
|
|
1438
|
+
};
|
|
1439
|
+
groupNodes.set(nextGroupId, node);
|
|
1440
|
+
lastGroupId = nextGroupId;
|
|
1441
|
+
}
|
|
1442
|
+
if (!lastGroupId) {
|
|
1443
|
+
throw new Error(
|
|
1444
|
+
"Could not compute circuit tree because no groups were processed"
|
|
1445
|
+
);
|
|
1446
|
+
}
|
|
1447
|
+
return groupNodes.get(opts?.source_group_id ?? lastGroupId);
|
|
1448
|
+
};
|
|
1449
|
+
|
|
1450
|
+
// lib/getStringFromCircuitJsonTree.ts
|
|
1451
|
+
var getStringFromCircuitJsonTree = (circuitJsonTree, indent = 0) => {
|
|
1452
|
+
if (circuitJsonTree.nodeType === "component") {
|
|
1453
|
+
return `${" ".repeat(indent)}${circuitJsonTree.sourceComponent?.name ?? circuitJsonTree.sourceComponent?.source_component_id}`;
|
|
1454
|
+
}
|
|
1455
|
+
const lines = [];
|
|
1456
|
+
lines.push(
|
|
1457
|
+
`${" ".repeat(indent)}${circuitJsonTree.sourceGroup?.name ?? circuitJsonTree.sourceGroup?.source_group_id}`
|
|
1458
|
+
);
|
|
1459
|
+
for (const child of circuitJsonTree.childNodes) {
|
|
1460
|
+
lines.push(getStringFromCircuitJsonTree(child, indent + 2));
|
|
1461
|
+
}
|
|
1462
|
+
return lines.join("\n");
|
|
1463
|
+
};
|
|
1443
1464
|
export {
|
|
1444
1465
|
applySelector,
|
|
1445
1466
|
applySelectorAST,
|
|
@@ -1449,6 +1470,7 @@ export {
|
|
|
1449
1470
|
directionToVec,
|
|
1450
1471
|
findBoundsAndCenter,
|
|
1451
1472
|
getBoundsOfPcbElements,
|
|
1473
|
+
getCircuitJsonTree,
|
|
1452
1474
|
getElementById,
|
|
1453
1475
|
getElementId,
|
|
1454
1476
|
getPrimaryId,
|
|
@@ -1456,6 +1478,7 @@ export {
|
|
|
1456
1478
|
getReadableNameForPcbPort,
|
|
1457
1479
|
getReadableNameForPcbSmtpad,
|
|
1458
1480
|
getReadableNameForPcbTrace,
|
|
1481
|
+
getStringFromCircuitJsonTree,
|
|
1459
1482
|
oppositeDirection,
|
|
1460
1483
|
oppositeSide,
|
|
1461
1484
|
repositionPcbComponentTo,
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../lib/cju.ts","../lib/subtree.ts","../lib/cju-indexed.ts","../lib/transform-soup-elements.ts","../lib/direction-to-vec.ts","../lib/apply-selector.ts","../lib/convert-abbreviation-to-soup-element-type.ts","../lib/get-element-id.ts","../lib/get-element-by-id.ts","../lib/readable-name-functions/get-readable-name-for-pcb-trace.ts","../lib/readable-name-functions/get-readable-name-for-pcb-port.ts","../lib/readable-name-functions/get-readable-name-for-pcb-smtpad.ts","../lib/readable-name-functions/get-readable-name-for-element.ts","../lib/get-bounds-of-pcb-elements.ts","../lib/utils/string-hash.ts","../lib/utils/get-layout-debug-object.ts","../lib/utils/is-truthy.ts","../lib/find-bounds-and-center.ts","../lib/get-primary-id.ts","../lib/reposition-pcb-component.ts"],"sourcesContent":["import type {\n AnyCircuitElement,\n AnyCircuitElementInput,\n SourceComponentBase,\n SourcePort,\n} from \"circuit-json\"\nimport * as Soup from \"circuit-json\"\nimport type { SubtreeOptions } from \"./subtree\"\nimport { buildSubtree } from \"./subtree\"\n\nexport type CircuitJsonOps<\n K extends AnyCircuitElement[\"type\"],\n T extends AnyCircuitElement | AnyCircuitElementInput,\n> = {\n get: (id: string) => Extract<T, { type: K }> | null\n select: (selector: string) => Extract<T, { type: K }> | null\n getWhere: (where: any) => Extract<T, { type: K }> | null\n getUsing: (using: {\n [key: `${string}_id`]: string\n }) => Extract<T, { type: K }> | null\n insert: (\n elm: Omit<Extract<T, { type: K }>, \"type\" | `${K}_id`>,\n ) => Extract<T, { type: K }>\n update: (\n id: string,\n newProps: Partial<Extract<T, { type: K }>>,\n ) => Extract<T, { type: K }>\n delete: (id: string) => void\n list: (where?: any) => Extract<T, { type: K }>[]\n}\n\nexport type CircuitJsonUtilObjects = {\n [K in AnyCircuitElement[\"type\"]]: CircuitJsonOps<K, AnyCircuitElement>\n} & {\n subtree: (where?: any) => CircuitJsonUtilObjects\n toArray: () => AnyCircuitElement[]\n editCount: number\n}\nexport type CircuitJsonInputUtilObjects = {\n [K in AnyCircuitElementInput[\"type\"]]: CircuitJsonOps<\n K,\n AnyCircuitElementInput\n >\n}\n\nexport type CircuitJsonUtilOptions = {\n validateInserts?: boolean\n}\n\nexport type GetCircuitJsonUtilFn = ((\n soup: AnyCircuitElement[],\n options?: CircuitJsonUtilOptions,\n) => CircuitJsonUtilObjects) & {\n unparsed: (soup: AnyCircuitElementInput[]) => CircuitJsonInputUtilObjects\n}\n\ninterface InternalStore {\n counts: Record<string, number>\n editCount: number\n}\n\nexport const cju: GetCircuitJsonUtilFn = ((\n circuitJsonInput: any[],\n options: CircuitJsonUtilOptions = {},\n) => {\n const circuitJson = circuitJsonInput as AnyCircuitElement[]\n let internalStore: InternalStore = (circuitJson as any)._internal_store\n if (!internalStore) {\n internalStore = {\n counts: {},\n editCount: 0,\n } as InternalStore\n ;(circuitJson as any)._internal_store = internalStore\n\n // Initialize counts\n for (const elm of circuitJson) {\n const type = elm.type\n const idVal = (elm as any)[`${type}_id`]\n if (!idVal) continue\n const idNum = Number.parseInt(idVal.split(\"_\").pop())\n if (!Number.isNaN(idNum)) {\n internalStore.counts[type] = Math.max(\n internalStore.counts[type] ?? 0,\n idNum,\n )\n }\n }\n }\n const su = new Proxy(\n {},\n {\n get: (proxy_target: any, prop: string) => {\n if (prop === \"toArray\") {\n return () => {\n ;(circuitJson as any).editCount = internalStore.editCount\n return circuitJson\n }\n }\n if (prop === \"editCount\") {\n return internalStore.editCount\n }\n\n if (prop === \"subtree\") {\n return (opts: SubtreeOptions) =>\n cju(buildSubtree(circuitJson, opts), options)\n }\n\n const component_type = prop\n\n return {\n get: (id: string) =>\n circuitJson.find(\n (e: any) =>\n e.type === component_type && e[`${component_type}_id`] === id,\n ),\n getUsing: (using: any) => {\n const keys = Object.keys(using)\n if (keys.length !== 1) {\n throw new Error(\n \"getUsing requires exactly one key, e.g. { pcb_component_id }\",\n )\n }\n const join_key = keys[0] as string\n const join_type = join_key.replace(\"_id\", \"\")\n const joiner: any = circuitJson.find(\n (e: any) =>\n e.type === join_type && e[join_key] === using[join_key],\n )\n if (!joiner) return null\n return circuitJson.find(\n (e: any) =>\n e.type === component_type &&\n e[`${component_type}_id`] === joiner[`${component_type}_id`],\n )\n },\n getWhere: (where: any) => {\n const keys = Object.keys(where)\n return circuitJson.find(\n (e: any) =>\n e.type === component_type &&\n keys.every((key) => e[key] === where[key]),\n )\n },\n list: (where?: any) => {\n const keys = !where ? [] : Object.keys(where)\n return circuitJson.filter(\n (e: any) =>\n e.type === component_type &&\n keys.every((key) => e[key] === where[key]),\n )\n },\n insert: (elm: any) => {\n internalStore.counts[component_type] ??= -1\n internalStore.counts[component_type]++\n const index = internalStore.counts[component_type]\n const newElm = {\n type: component_type,\n [`${component_type}_id`]: `${component_type}_${index}`,\n ...elm,\n }\n\n if (options.validateInserts) {\n const parser =\n (Soup as any)[component_type] ?? Soup.any_soup_element\n parser.parse(newElm)\n }\n\n circuitJson.push(newElm)\n internalStore.editCount++\n return newElm\n },\n delete: (id: string) => {\n const elm = circuitJson.find(\n (e) => (e as any)[`${component_type}_id`] === id,\n )\n if (!elm) return\n circuitJson.splice(circuitJson.indexOf(elm), 1)\n internalStore.editCount++\n },\n update: (id: string, newProps: any) => {\n const elm = circuitJson.find(\n (e) =>\n e.type === component_type &&\n (e as any)[`${component_type}_id`] === id,\n )\n if (!elm) return null\n Object.assign(elm, newProps)\n internalStore.editCount++\n return elm\n },\n select: (selector: string) => {\n // TODO when applySelector is isolated we can use it, until then we\n // do a poor man's selector implementation for two common cases\n if (component_type === \"source_component\") {\n return circuitJson.find(\n (e) =>\n e.type === \"source_component\" &&\n e.name === selector.replace(/\\./g, \"\"),\n )\n } else if (\n component_type === \"pcb_port\" ||\n component_type === \"source_port\" ||\n component_type === \"schematic_port\"\n ) {\n const [component_name, port_selector] = selector\n .replace(/\\./g, \"\")\n .split(/[\\s\\>]+/)\n const source_component = circuitJson.find(\n (e) =>\n e.type === \"source_component\" && e.name === component_name,\n ) as SourceComponentBase\n if (!source_component) return null\n const source_port = circuitJson.find(\n (e) =>\n e.type === \"source_port\" &&\n e.source_component_id ===\n source_component.source_component_id &&\n (e.name === port_selector ||\n (e.port_hints ?? []).includes(port_selector!)),\n ) as SourcePort\n if (!source_port) return null\n if (component_type === \"source_port\") return source_port\n\n if (component_type === \"pcb_port\") {\n return circuitJson.find(\n (e) =>\n e.type === \"pcb_port\" &&\n e.source_port_id === source_port.source_port_id,\n )\n } else if (component_type === \"schematic_port\") {\n return circuitJson.find(\n (e) =>\n e.type === \"schematic_port\" &&\n e.source_port_id === source_port.source_port_id,\n )\n }\n }\n },\n }\n },\n },\n )\n\n return su\n}) as any\ncju.unparsed = cju as any\n\nexport const su = cju\n\nexport default cju\n","import type { AnyCircuitElement } from \"circuit-json\"\n\nexport type SubtreeOptions = {\n subcircuit_id?: string\n source_group_id?: string\n}\n\nfunction connect(\n map: Map<AnyCircuitElement, Set<AnyCircuitElement>>,\n a: AnyCircuitElement | undefined,\n b: AnyCircuitElement | undefined,\n) {\n if (!a || !b) return\n let setA = map.get(a)\n if (!setA) {\n setA = new Set()\n map.set(a, setA)\n }\n setA.add(b)\n let setB = map.get(b)\n if (!setB) {\n setB = new Set()\n map.set(b, setB)\n }\n setB.add(a)\n}\n\nexport function buildSubtree(\n soup: AnyCircuitElement[],\n opts: SubtreeOptions,\n): AnyCircuitElement[] {\n if (!opts.subcircuit_id && !opts.source_group_id) return [...soup]\n\n const idMap = new Map<string, AnyCircuitElement>()\n for (const elm of soup) {\n const idVal = (elm as any)[`${elm.type}_id`]\n if (typeof idVal === \"string\") {\n idMap.set(idVal, elm)\n }\n }\n\n const adj = new Map<AnyCircuitElement, Set<AnyCircuitElement>>()\n for (const elm of soup) {\n const entries = Object.entries(elm as any)\n for (const [key, val] of entries) {\n if (key === \"parent_source_group_id\") continue\n if (key.endsWith(\"_id\") && typeof val === \"string\") {\n const other = idMap.get(val)\n connect(adj, elm, other)\n } else if (key.endsWith(\"_ids\") && Array.isArray(val)) {\n for (const v of val) {\n if (typeof v === \"string\") {\n const other = idMap.get(v)\n connect(adj, elm, other)\n }\n }\n }\n }\n }\n\n const queue: AnyCircuitElement[] = []\n const included = new Set<AnyCircuitElement>()\n\n for (const elm of soup) {\n if (\n (opts.subcircuit_id &&\n (elm as any).subcircuit_id === opts.subcircuit_id) ||\n (opts.source_group_id &&\n ((elm as any).source_group_id === opts.source_group_id ||\n (Array.isArray((elm as any).member_source_group_ids) &&\n (elm as any).member_source_group_ids.includes(\n opts.source_group_id,\n ))))\n ) {\n queue.push(elm)\n included.add(elm)\n }\n }\n\n while (queue.length > 0) {\n const elm = queue.shift()!\n const neighbors = adj.get(elm)\n if (!neighbors) continue\n for (const n of neighbors) {\n if (!included.has(n)) {\n included.add(n)\n queue.push(n)\n }\n }\n }\n\n return soup.filter((e) => included.has(e))\n}\n","import type {\n AnyCircuitElement,\n AnyCircuitElementInput,\n SourceComponentBase,\n SourcePort,\n} from \"circuit-json\"\nimport * as Soup from \"circuit-json\"\nimport type {\n CircuitJsonOps,\n CircuitJsonUtilObjects as CircuitJsonUtilObjects,\n CircuitJsonInputUtilObjects as CircuitJsonInputUtilObjects,\n} from \"./cju\"\n\nexport type IndexedCircuitJsonUtilOptions = {\n validateInserts?: boolean\n indexConfig?: {\n // Enable specific indexes for faster lookups\n byId?: boolean\n byType?: boolean\n byRelation?: boolean\n bySubcircuit?: boolean\n byCustomField?: string[]\n }\n}\n\nexport type GetIndexedCircuitJsonUtilFn = ((\n soup: AnyCircuitElement[],\n options?: IndexedCircuitJsonUtilOptions,\n) => CircuitJsonUtilObjects) & {\n unparsed: (soup: AnyCircuitElementInput[]) => CircuitJsonInputUtilObjects\n}\n\ninterface InternalStore {\n counts: Record<string, number>\n editCount: number\n // Indexes for faster lookups\n indexes: {\n byId?: Map<string, AnyCircuitElement>\n byType?: Map<string, AnyCircuitElement[]>\n // Maps relation fields (like component_id) to elements\n byRelation?: Map<string, Map<string, AnyCircuitElement[]>>\n // Maps subcircuit_id to elements\n bySubcircuit?: Map<string, AnyCircuitElement[]>\n // Custom field indexes\n byCustomField?: Map<string, Map<string, AnyCircuitElement[]>>\n }\n}\n\n// Creates a unique key for the ID index\nfunction createIdKey(element: AnyCircuitElement): string {\n const type = element.type\n return `${type}:${(element as any)[`${type}_id`]}`\n}\n\nexport const cjuIndexed: GetIndexedCircuitJsonUtilFn = ((\n soup: AnyCircuitElement[],\n options: IndexedCircuitJsonUtilOptions = {},\n) => {\n let internalStore: InternalStore = (soup as any)._internal_store_indexed\n\n if (!internalStore) {\n internalStore = {\n counts: {},\n editCount: 0,\n indexes: {},\n } as InternalStore\n\n // Initialize counts\n for (const elm of soup) {\n const type = elm.type\n const idVal = (elm as any)[`${type}_id`]\n if (!idVal) continue\n const idNum = Number.parseInt(idVal.split(\"_\").pop() || \"\")\n if (!Number.isNaN(idNum)) {\n internalStore.counts[type] = Math.max(\n internalStore.counts[type] ?? 0,\n idNum,\n )\n }\n }\n\n // Build indexes\n const indexConfig = options.indexConfig || {}\n const indexes = internalStore.indexes\n\n // Reset indexes before rebuilding\n if (indexConfig.byId) {\n indexes.byId = new Map()\n }\n\n if (indexConfig.byType) {\n indexes.byType = new Map()\n }\n\n if (indexConfig.byRelation) {\n indexes.byRelation = new Map()\n }\n\n if (indexConfig.bySubcircuit) {\n indexes.bySubcircuit = new Map()\n }\n\n if (indexConfig.byCustomField && indexConfig.byCustomField.length > 0) {\n indexes.byCustomField = new Map()\n for (const field of indexConfig.byCustomField) {\n indexes.byCustomField.set(field, new Map())\n }\n }\n\n // Build indexes\n for (const element of soup) {\n // Index by ID\n if (indexConfig.byId) {\n const idKey = createIdKey(element)\n indexes.byId!.set(idKey, element)\n }\n\n // Index by type\n if (indexConfig.byType) {\n const elementsOfType = indexes.byType!.get(element.type) || []\n elementsOfType.push(element)\n indexes.byType!.set(element.type, elementsOfType)\n }\n\n // Index by relation fields (fields ending with _id)\n if (indexConfig.byRelation) {\n const elementEntries = Object.entries(element)\n for (const [key, value] of elementEntries) {\n if (\n key.endsWith(\"_id\") &&\n key !== `${element.type}_id` &&\n typeof value === \"string\"\n ) {\n const relationTypeMap = indexes.byRelation!.get(key) || new Map()\n const relatedElements = relationTypeMap.get(value as string) || []\n relatedElements.push(element)\n relationTypeMap.set(value as string, relatedElements)\n indexes.byRelation!.set(key, relationTypeMap)\n }\n }\n }\n\n // Index by subcircuit_id\n if (indexConfig.bySubcircuit && \"subcircuit_id\" in element) {\n const subcircuitId = (element as any).subcircuit_id\n if (subcircuitId && typeof subcircuitId === \"string\") {\n const subcircuitElements =\n indexes.bySubcircuit!.get(subcircuitId) || []\n subcircuitElements.push(element)\n indexes.bySubcircuit!.set(subcircuitId, subcircuitElements)\n }\n }\n\n // Index by custom fields\n if (indexConfig.byCustomField && indexes.byCustomField) {\n for (const field of indexConfig.byCustomField) {\n if (field in element) {\n const fieldValue = (element as any)[field]\n if (\n fieldValue !== undefined &&\n (typeof fieldValue === \"string\" || typeof fieldValue === \"number\")\n ) {\n const fieldValueStr = String(fieldValue)\n const fieldMap = indexes.byCustomField.get(field)!\n const elementsWithFieldValue = fieldMap.get(fieldValueStr) || []\n elementsWithFieldValue.push(element)\n fieldMap.set(fieldValueStr, elementsWithFieldValue)\n }\n }\n }\n }\n }\n // Store internal state\n ;(soup as any)._internal_store_indexed = internalStore\n }\n\n const suIndexed = new Proxy(\n {},\n {\n get: (proxy_target: any, prop: string) => {\n if (prop === \"toArray\") {\n return () => {\n ;(soup as any).editCount = internalStore.editCount\n return soup\n }\n }\n if (prop === \"editCount\") {\n return internalStore.editCount\n }\n\n const component_type = prop\n\n return {\n get: (id: string) => {\n const indexConfig = options.indexConfig || {}\n\n // Use ID index if available\n if (indexConfig.byId && internalStore.indexes.byId) {\n return (\n (internalStore.indexes.byId.get(\n `${component_type}:${id}`,\n ) as Extract<\n AnyCircuitElement,\n { type: typeof component_type }\n >) || null\n )\n }\n\n // Use type index if available\n if (indexConfig.byType && internalStore.indexes.byType) {\n const elementsOfType =\n internalStore.indexes.byType.get(component_type) || []\n return (\n (elementsOfType.find(\n (e: any) => e[`${component_type}_id`] === id,\n ) as Extract<\n AnyCircuitElement,\n { type: typeof component_type }\n >) || null\n )\n }\n\n // Fallback to regular search\n return (\n (soup.find(\n (e: any) =>\n e.type === component_type && e[`${component_type}_id`] === id,\n ) as Extract<\n AnyCircuitElement,\n { type: typeof component_type }\n >) || null\n )\n },\n\n getUsing: (using: any) => {\n const indexConfig = options.indexConfig || {}\n const keys = Object.keys(using)\n\n if (keys.length !== 1) {\n throw new Error(\n \"getUsing requires exactly one key, e.g. { pcb_component_id }\",\n )\n }\n\n const join_key = keys[0] as string\n const join_type = join_key.replace(\"_id\", \"\")\n\n // Use relation index if available\n if (indexConfig.byRelation && internalStore.indexes.byRelation) {\n const relationMap = internalStore.indexes.byRelation.get(join_key)\n if (relationMap) {\n const relatedElements = relationMap.get(using[join_key]) || []\n const joiner = relatedElements.find((e) => e.type === join_type)\n\n if (!joiner) return null\n\n // Now find the element of component_type with matching ID\n const joinerId =\n joiner[`${component_type}_id` as keyof typeof joiner]\n\n if (indexConfig.byId && internalStore.indexes.byId) {\n return (\n (internalStore.indexes.byId.get(\n `${component_type}:${joinerId}`,\n ) as Extract<\n AnyCircuitElement,\n { type: typeof component_type }\n >) || null\n )\n }\n\n if (indexConfig.byType && internalStore.indexes.byType) {\n const elementsOfType =\n internalStore.indexes.byType.get(component_type) || []\n return (\n (elementsOfType.find(\n (e: any) => e[`${component_type}_id`] === joinerId,\n ) as Extract<\n AnyCircuitElement,\n { type: typeof component_type }\n >) || null\n )\n }\n\n return (\n (soup.find(\n (e: any) =>\n e.type === component_type &&\n e[`${component_type}_id`] === joinerId,\n ) as Extract<\n AnyCircuitElement,\n { type: typeof component_type }\n >) || null\n )\n }\n }\n\n // Fallback to regular approach\n const joiner: any = soup.find(\n (e: any) =>\n e.type === join_type && e[join_key] === using[join_key],\n )\n\n if (!joiner) return null\n\n return (\n (soup.find(\n (e: any) =>\n e.type === component_type &&\n e[`${component_type}_id`] === joiner[`${component_type}_id`],\n ) as Extract<\n AnyCircuitElement,\n { type: typeof component_type }\n >) || null\n )\n },\n\n getWhere: (where: any) => {\n const indexConfig = options.indexConfig || {}\n const keys = Object.keys(where)\n\n // If we're looking by a single property and it's indexed as a custom field\n if (\n keys.length === 1 &&\n indexConfig.byCustomField &&\n internalStore.indexes.byCustomField\n ) {\n const field = keys[0]\n const fieldMap = internalStore.indexes.byCustomField.get(field!)\n\n if (fieldMap) {\n const fieldValue = String(where[field!])\n const elementsWithFieldValue = fieldMap.get(fieldValue) || []\n\n return (\n (elementsWithFieldValue.find(\n (e: any) => e.type === component_type,\n ) as Extract<\n AnyCircuitElement,\n { type: typeof component_type }\n >) || null\n )\n }\n }\n\n // If we're looking by subcircuit_id and it's indexed\n if (\n \"subcircuit_id\" in where &&\n indexConfig.bySubcircuit &&\n internalStore.indexes.bySubcircuit\n ) {\n const subcircuitId = where.subcircuit_id\n const subcircuitElements =\n internalStore.indexes.bySubcircuit.get(subcircuitId) || []\n\n return (\n (subcircuitElements.find(\n (e: any) =>\n e.type === component_type &&\n keys.every((key) => e[key] === where[key]),\n ) as Extract<\n AnyCircuitElement,\n { type: typeof component_type }\n >) || null\n )\n }\n\n // Use type index if available to reduce search space\n if (indexConfig.byType && internalStore.indexes.byType) {\n const elementsOfType =\n internalStore.indexes.byType.get(component_type) || []\n\n return (\n (elementsOfType.find((e: any) =>\n keys.every((key) => e[key] === where[key]),\n ) as Extract<\n AnyCircuitElement,\n { type: typeof component_type }\n >) || null\n )\n }\n\n // Fallback to regular approach\n return (\n (soup.find(\n (e: any) =>\n e.type === component_type &&\n keys.every((key) => e[key] === where[key]),\n ) as Extract<\n AnyCircuitElement,\n { type: typeof component_type }\n >) || null\n )\n },\n\n list: (where?: any) => {\n const indexConfig = options.indexConfig || {}\n const keys = !where ? [] : Object.keys(where)\n\n // If no filters, just return all elements of this type using the type index\n if (\n keys.length === 0 &&\n indexConfig.byType &&\n internalStore.indexes.byType\n ) {\n return (internalStore.indexes.byType.get(component_type) ||\n []) as Extract<\n AnyCircuitElement,\n { type: typeof component_type }\n >[]\n }\n\n // If filtering by subcircuit_id and it's the only filter\n if (\n keys.length === 1 &&\n keys[0] === \"subcircuit_id\" &&\n indexConfig.bySubcircuit &&\n internalStore.indexes.bySubcircuit\n ) {\n const subcircuitId = where.subcircuit_id\n const subcircuitElements =\n internalStore.indexes.bySubcircuit.get(subcircuitId) || []\n\n return subcircuitElements.filter(\n (e: any) => e.type === component_type,\n ) as Extract<AnyCircuitElement, { type: typeof component_type }>[]\n }\n\n // Start with all elements of this type to reduce search space\n let elementsToFilter: AnyCircuitElement[]\n\n if (indexConfig.byType && internalStore.indexes.byType) {\n elementsToFilter =\n internalStore.indexes.byType.get(component_type) || []\n } else {\n elementsToFilter = soup.filter((e) => e.type === component_type)\n }\n\n // Apply remaining filters\n if (keys.length > 0) {\n return elementsToFilter.filter((e: any) =>\n keys.every((key) => e[key] === where[key]),\n ) as Extract<AnyCircuitElement, { type: typeof component_type }>[]\n }\n\n return elementsToFilter as Extract<\n AnyCircuitElement,\n { type: typeof component_type }\n >[]\n },\n\n insert: (elm: any) => {\n internalStore.counts[component_type] ??= -1\n internalStore.counts[component_type]++\n const index = internalStore.counts[component_type]\n const newElm = {\n type: component_type,\n [`${component_type}_id`]: `${component_type}_${index}`,\n ...elm,\n }\n\n if (options.validateInserts) {\n const parser =\n (Soup as any)[component_type] ?? Soup.any_soup_element\n parser.parse(newElm)\n }\n\n soup.push(newElm)\n internalStore.editCount++\n\n // Update indexes with the new element\n const indexConfig = options.indexConfig || {}\n\n // Update ID index\n if (indexConfig.byId && internalStore.indexes.byId) {\n const idKey = createIdKey(newElm)\n internalStore.indexes.byId.set(idKey, newElm)\n }\n\n // Update type index\n if (indexConfig.byType && internalStore.indexes.byType) {\n const elementsOfType =\n internalStore.indexes.byType.get(component_type) || []\n elementsOfType.push(newElm)\n internalStore.indexes.byType.set(component_type, elementsOfType)\n }\n\n // Update relation index\n if (indexConfig.byRelation && internalStore.indexes.byRelation) {\n const elementEntries = Object.entries(newElm)\n for (const [key, value] of elementEntries) {\n if (\n key.endsWith(\"_id\") &&\n key !== `${newElm.type}_id` &&\n typeof value === \"string\"\n ) {\n const relationTypeMap =\n internalStore.indexes.byRelation.get(key) || new Map()\n const relatedElements =\n relationTypeMap.get(value as string) || []\n relatedElements.push(newElm)\n relationTypeMap.set(value as string, relatedElements)\n internalStore.indexes.byRelation.set(key, relationTypeMap)\n }\n }\n }\n\n // Update subcircuit index\n if (\n indexConfig.bySubcircuit &&\n internalStore.indexes.bySubcircuit &&\n \"subcircuit_id\" in newElm\n ) {\n const subcircuitId = (newElm as any).subcircuit_id\n if (subcircuitId && typeof subcircuitId === \"string\") {\n const subcircuitElements =\n internalStore.indexes.bySubcircuit.get(subcircuitId) || []\n subcircuitElements.push(newElm)\n internalStore.indexes.bySubcircuit.set(\n subcircuitId,\n subcircuitElements,\n )\n }\n }\n\n // Update custom field indexes\n if (\n indexConfig.byCustomField &&\n internalStore.indexes.byCustomField\n ) {\n for (const field of indexConfig.byCustomField) {\n if (field in newElm) {\n const fieldValue = (newElm as any)[field]\n if (\n fieldValue !== undefined &&\n (typeof fieldValue === \"string\" ||\n typeof fieldValue === \"number\")\n ) {\n const fieldValueStr = String(fieldValue)\n const fieldMap =\n internalStore.indexes.byCustomField.get(field)!\n const elementsWithFieldValue =\n fieldMap.get(fieldValueStr) || []\n elementsWithFieldValue.push(newElm)\n fieldMap.set(fieldValueStr, elementsWithFieldValue)\n }\n }\n }\n }\n\n return newElm\n },\n\n delete: (id: string) => {\n const indexConfig = options.indexConfig || {}\n let elm: AnyCircuitElement | undefined\n\n // Find the element to delete\n if (indexConfig.byId && internalStore.indexes.byId) {\n elm = internalStore.indexes.byId.get(`${component_type}:${id}`)\n } else if (indexConfig.byType && internalStore.indexes.byType) {\n const elementsOfType =\n internalStore.indexes.byType.get(component_type) || []\n elm = elementsOfType.find(\n (e: any) => e[`${component_type}_id`] === id,\n )\n } else {\n elm = soup.find((e) => (e as any)[`${component_type}_id`] === id)\n }\n\n if (!elm) return\n\n // Remove from array\n const elmIndex = soup.indexOf(elm)\n if (elmIndex >= 0) {\n soup.splice(elmIndex, 1)\n internalStore.editCount++\n }\n\n // Remove from indexes\n if (indexConfig.byId && internalStore.indexes.byId) {\n const idKey = createIdKey(elm)\n internalStore.indexes.byId.delete(idKey)\n }\n\n if (indexConfig.byType && internalStore.indexes.byType) {\n const elementsOfType =\n internalStore.indexes.byType.get(component_type) || []\n const filteredElements = elementsOfType.filter(\n (e: any) => e[`${component_type}_id`] !== id,\n )\n internalStore.indexes.byType.set(component_type, filteredElements)\n }\n\n if (indexConfig.byRelation && internalStore.indexes.byRelation) {\n // This is more complex - we need to find and remove from all relation maps\n // where this element appears\n for (const [\n relationKey,\n relationMap,\n ] of internalStore.indexes.byRelation.entries()) {\n for (const [relationValue, elements] of relationMap.entries()) {\n const updatedElements = elements.filter((e) => e !== elm)\n\n if (updatedElements.length === 0) {\n relationMap.delete(relationValue)\n } else {\n relationMap.set(relationValue, updatedElements)\n }\n }\n }\n }\n\n if (\n indexConfig.bySubcircuit &&\n internalStore.indexes.bySubcircuit &&\n \"subcircuit_id\" in elm\n ) {\n const subcircuitId = (elm as any).subcircuit_id\n if (subcircuitId) {\n const subcircuitElements =\n internalStore.indexes.bySubcircuit.get(subcircuitId) || []\n const updatedElements = subcircuitElements.filter(\n (e) => e !== elm,\n )\n\n if (updatedElements.length === 0) {\n internalStore.indexes.bySubcircuit.delete(subcircuitId)\n } else {\n internalStore.indexes.bySubcircuit.set(\n subcircuitId,\n updatedElements,\n )\n }\n }\n }\n\n if (\n indexConfig.byCustomField &&\n internalStore.indexes.byCustomField\n ) {\n for (const fieldMap of internalStore.indexes.byCustomField.values()) {\n for (const [fieldValue, elements] of fieldMap.entries()) {\n const updatedElements = elements.filter((e) => e !== elm)\n\n if (updatedElements.length === 0) {\n fieldMap.delete(fieldValue)\n } else {\n fieldMap.set(fieldValue, updatedElements)\n }\n }\n }\n }\n },\n\n update: (id: string, newProps: any) => {\n const indexConfig = options.indexConfig || {}\n let elm: AnyCircuitElement | undefined | null\n\n // Find the element to update\n if (indexConfig.byId && internalStore.indexes.byId) {\n elm = internalStore.indexes.byId.get(`${component_type}:${id}`)\n } else if (indexConfig.byType && internalStore.indexes.byType) {\n const elementsOfType =\n internalStore.indexes.byType.get(component_type) || []\n elm = elementsOfType.find(\n (e: any) => e[`${component_type}_id`] === id,\n )\n } else {\n elm = soup.find(\n (e) =>\n e.type === component_type &&\n (e as any)[`${component_type}_id`] === id,\n )\n }\n\n if (!elm) return null\n\n // Need to remove from indexes before updating\n if (indexConfig.byRelation && internalStore.indexes.byRelation) {\n // Remove from relation indexes\n const elementEntries = Object.entries(elm)\n for (const [key, value] of elementEntries) {\n if (\n key.endsWith(\"_id\") &&\n key !== `${elm.type}_id` &&\n typeof value === \"string\"\n ) {\n if (key in newProps && newProps[key] !== value) {\n const relationTypeMap =\n internalStore.indexes.byRelation.get(key)\n if (relationTypeMap) {\n const relatedElements =\n relationTypeMap.get(value as string) || []\n const updatedElements = relatedElements.filter(\n (e) => e !== elm,\n )\n\n if (updatedElements.length === 0) {\n relationTypeMap.delete(value as string)\n } else {\n relationTypeMap.set(value as string, updatedElements)\n }\n }\n }\n }\n }\n }\n\n if (\n indexConfig.bySubcircuit &&\n internalStore.indexes.bySubcircuit &&\n \"subcircuit_id\" in elm &&\n \"subcircuit_id\" in newProps\n ) {\n const oldSubcircuitId = (elm as any).subcircuit_id\n const newSubcircuitId = newProps.subcircuit_id\n\n if (oldSubcircuitId !== newSubcircuitId) {\n // Remove from old subcircuit index\n const subcircuitElements =\n internalStore.indexes.bySubcircuit.get(oldSubcircuitId) || []\n const updatedElements = subcircuitElements.filter(\n (e) => e !== elm,\n )\n\n if (updatedElements.length === 0) {\n internalStore.indexes.bySubcircuit.delete(oldSubcircuitId)\n } else {\n internalStore.indexes.bySubcircuit.set(\n oldSubcircuitId,\n updatedElements,\n )\n }\n }\n }\n\n if (\n indexConfig.byCustomField &&\n internalStore.indexes.byCustomField\n ) {\n for (const field of indexConfig.byCustomField) {\n if (\n field in elm &&\n field in newProps &&\n (elm as any)[field] !== newProps[field]\n ) {\n const fieldMap =\n internalStore.indexes.byCustomField.get(field)\n if (fieldMap) {\n const oldValue = String((elm as any)[field])\n const elements = fieldMap.get(oldValue) || []\n const updatedElements = elements.filter((e) => e !== elm)\n\n if (updatedElements.length === 0) {\n fieldMap.delete(oldValue)\n } else {\n fieldMap.set(oldValue, updatedElements)\n }\n }\n }\n }\n }\n\n // Update the element\n Object.assign(elm, newProps)\n internalStore.editCount++\n\n // Add to indexes with updated values\n if (indexConfig.byRelation && internalStore.indexes.byRelation) {\n const elementEntries = Object.entries(elm)\n for (const [key, value] of elementEntries) {\n if (\n key.endsWith(\"_id\") &&\n key !== `${elm.type}_id` &&\n typeof value === \"string\"\n ) {\n if (key in newProps) {\n const relationTypeMap: any =\n internalStore.indexes.byRelation.get(key) || new Map()\n const relatedElements: any =\n relationTypeMap.get(value as string) || []\n\n if (!relatedElements.includes(elm)) {\n relatedElements.push(elm)\n relationTypeMap.set(value as string, relatedElements)\n internalStore.indexes.byRelation.set(key, relationTypeMap)\n }\n }\n }\n }\n }\n\n if (\n indexConfig.bySubcircuit &&\n internalStore.indexes.bySubcircuit &&\n \"subcircuit_id\" in elm &&\n \"subcircuit_id\" in newProps\n ) {\n const subcircuitId = (elm as any).subcircuit_id\n if (subcircuitId && typeof subcircuitId === \"string\") {\n const subcircuitElements =\n internalStore.indexes.bySubcircuit.get(subcircuitId) || []\n\n if (!subcircuitElements.includes(elm)) {\n subcircuitElements.push(elm)\n internalStore.indexes.bySubcircuit.set(\n subcircuitId,\n subcircuitElements,\n )\n }\n }\n }\n\n if (\n indexConfig.byCustomField &&\n internalStore.indexes.byCustomField\n ) {\n for (const field of indexConfig.byCustomField) {\n if (field in elm && field in newProps) {\n const fieldValue: any = (elm as any)[field]\n if (\n fieldValue !== undefined &&\n (typeof fieldValue === \"string\" ||\n typeof fieldValue === \"number\")\n ) {\n const fieldValueStr = String(fieldValue)\n const fieldMap =\n internalStore.indexes.byCustomField.get(field)!\n const elementsWithFieldValue =\n fieldMap.get(fieldValueStr) || []\n\n if (!elementsWithFieldValue.includes(elm)) {\n elementsWithFieldValue.push(elm)\n fieldMap.set(fieldValueStr, elementsWithFieldValue)\n }\n }\n }\n }\n }\n\n return elm as Extract<\n AnyCircuitElement,\n { type: typeof component_type }\n >\n },\n\n select: (selector: string) => {\n // Selection by selector is specialized enough that we don't use indexes here\n // TODO when applySelector is isolated we can use it, until then we\n // do a poor man's selector implementation for two common cases\n if (component_type === \"source_component\") {\n return (\n (soup.find(\n (e) =>\n e.type === \"source_component\" &&\n e.name === selector.replace(/\\./g, \"\"),\n ) as Extract<\n AnyCircuitElement,\n { type: typeof component_type }\n >) || null\n )\n } else if (\n component_type === \"pcb_port\" ||\n component_type === \"source_port\" ||\n component_type === \"schematic_port\"\n ) {\n const [component_name, port_selector] = selector\n .replace(/\\./g, \"\")\n .split(/[\\s\\>]+/)\n const source_component = soup.find(\n (e) =>\n e.type === \"source_component\" && e.name === component_name,\n ) as SourceComponentBase\n if (!source_component) return null\n const source_port = soup.find(\n (e) =>\n e.type === \"source_port\" &&\n e.source_component_id ===\n source_component.source_component_id &&\n (e.name === port_selector ||\n (e.port_hints ?? []).includes(port_selector!)),\n ) as SourcePort\n if (!source_port) return null\n if (component_type === \"source_port\")\n return source_port as Extract<\n AnyCircuitElement,\n { type: typeof component_type }\n >\n\n if (component_type === \"pcb_port\") {\n return (\n (soup.find(\n (e) =>\n e.type === \"pcb_port\" &&\n e.source_port_id === source_port.source_port_id,\n ) as Extract<\n AnyCircuitElement,\n { type: typeof component_type }\n >) || null\n )\n } else if (component_type === \"schematic_port\") {\n return (\n (soup.find(\n (e) =>\n e.type === \"schematic_port\" &&\n e.source_port_id === source_port.source_port_id,\n ) as Extract<\n AnyCircuitElement,\n { type: typeof component_type }\n >) || null\n )\n }\n }\n\n return null\n },\n }\n },\n },\n )\n\n return suIndexed\n}) as any\n\ncjuIndexed.unparsed = cjuIndexed as any\n\nexport default cjuIndexed\n","import type { AnyCircuitElement } from \"circuit-json\"\nimport { type Matrix, applyToPoint, decomposeTSR } from \"transformation-matrix\"\nimport {\n directionToVec,\n rotateDirection,\n vecToDirection,\n} from \"./direction-to-vec\"\n\nexport const transformSchematicElement = (\n elm: AnyCircuitElement,\n matrix: Matrix,\n) => {\n if (elm.type === \"schematic_component\") {\n // TODO handle rotation\n elm.center = applyToPoint(matrix, elm.center)\n } else if (elm.type === \"schematic_port\") {\n elm.center = applyToPoint(matrix, elm.center)\n\n if (elm.facing_direction) {\n elm.facing_direction = rotateDirection(\n elm.facing_direction,\n -(Math.atan2(matrix.b, matrix.a) / Math.PI) * 2,\n )\n }\n } else if (elm.type === \"schematic_text\") {\n elm.position = applyToPoint(matrix, elm.position)\n // } else if (elm.type === \"schematic_group\") {\n // elm.center = applyToPoint(matrix, elm.center)\n } else if (elm.type === \"schematic_trace\") {\n } else if (elm.type === \"schematic_box\") {\n const { x, y } = applyToPoint(matrix, { x: elm.x, y: elm.y })\n elm.x = x\n elm.y = y\n } else if (elm.type === \"schematic_line\") {\n const { x: x1, y: y1 } = applyToPoint(matrix, { x: elm.x1, y: elm.y1 })\n const { x: x2, y: y2 } = applyToPoint(matrix, { x: elm.x2, y: elm.y2 })\n elm.x1 = x1\n elm.y1 = y1\n elm.x2 = x2\n elm.y2 = y2\n }\n return elm\n}\n\nexport const transformSchematicElements = (\n elms: AnyCircuitElement[],\n matrix: Matrix,\n) => {\n return elms.map((elm) => transformSchematicElement(elm, matrix))\n}\n\nexport const transformPCBElement = (elm: AnyCircuitElement, matrix: Matrix) => {\n if (\n elm.type === \"pcb_plated_hole\" ||\n elm.type === \"pcb_hole\" ||\n elm.type === \"pcb_via\" ||\n elm.type === \"pcb_smtpad\" ||\n elm.type === \"pcb_port\"\n ) {\n const { x, y } = applyToPoint(matrix, {\n x: Number((elm as any).x),\n y: Number((elm as any).y),\n })\n ;(elm as any).x = x\n ;(elm as any).y = y\n } else if (elm.type === \"pcb_keepout\" || elm.type === \"pcb_board\") {\n // TODO adjust size/rotation\n elm.center = applyToPoint(matrix, elm.center)\n } else if (\n elm.type === \"pcb_silkscreen_text\" ||\n elm.type === \"pcb_fabrication_note_text\"\n ) {\n elm.anchor_position = applyToPoint(matrix, elm.anchor_position)\n } else if (\n elm.type === \"pcb_silkscreen_circle\" ||\n elm.type === \"pcb_silkscreen_rect\" ||\n elm.type === \"pcb_component\"\n ) {\n elm.center = applyToPoint(matrix, elm.center)\n } else if (\n elm.type === \"pcb_silkscreen_path\" ||\n elm.type === \"pcb_trace\" ||\n elm.type === \"pcb_fabrication_note_path\"\n ) {\n elm.route = elm.route.map((rp) => {\n const tp = applyToPoint(matrix, rp) as { x: number; y: number }\n rp.x = tp.x\n rp.y = tp.y\n return rp\n })\n } else if (elm.type === \"pcb_silkscreen_line\") {\n const p1 = { x: elm.x1, y: elm.y1 }\n const p2 = { x: elm.x2, y: elm.y2 }\n const p1t = applyToPoint(matrix, p1)\n const p2t = applyToPoint(matrix, p2)\n elm.x1 = p1t.x\n elm.y1 = p1t.y\n elm.x2 = p2t.x\n elm.y2 = p2t.y\n } else if (elm.type === \"cad_component\") {\n const newPos = applyToPoint(matrix, {\n x: elm.position.x,\n y: elm.position.y,\n })\n elm.position.x = newPos.x\n elm.position.y = newPos.y\n }\n return elm\n}\n\nexport const transformPCBElements = (\n elms: AnyCircuitElement[],\n matrix: Matrix,\n) => {\n const tsr = decomposeTSR(matrix)\n const flipPadWidthHeight =\n Math.round(tsr.rotation.angle / (Math.PI / 2)) % 2 === 1\n let transformedElms = elms.map((elm) => transformPCBElement(elm, matrix))\n if (flipPadWidthHeight) {\n transformedElms = transformedElms.map((elm) => {\n if (elm.type === \"pcb_smtpad\" && elm.shape === \"rect\") {\n ;[elm.width, elm.height] = [elm.height, elm.width]\n }\n return elm\n })\n }\n return transformedElms\n}\n","export const directionToVec = (direction: \"up\" | \"down\" | \"left\" | \"right\") => {\n if (direction === \"up\") return { x: 0, y: 1 }\n else if (direction === \"down\") return { x: 0, y: -1 }\n else if (direction === \"left\") return { x: -1, y: 0 }\n else if (direction === \"right\") return { x: 1, y: 0 }\n else throw new Error(\"Invalid direction\")\n}\n\nexport const vecToDirection = ({ x, y }: { x: number; y: number }) => {\n if (x > y) y = 0\n if (y > x) x = 0\n if (x > 0 && y === 0) return \"right\"\n else if (x < 0 && y === 0) return \"left\"\n else if (x === 0 && y > 0) return \"up\"\n else if (x === 0 && y < 0) return \"down\"\n else throw new Error(`Invalid vector for direction conversion (${x}, ${y})`)\n}\n\nexport const rotateClockwise = (\n direction: \"up\" | \"down\" | \"left\" | \"right\"\n) => {\n if (direction === \"up\") return \"right\"\n else if (direction === \"right\") return \"down\"\n else if (direction === \"down\") return \"left\"\n else if (direction === \"left\") return \"up\"\n throw new Error(`Invalid direction: ${direction}`)\n}\n\nexport const rotateCounterClockwise = (\n direction: \"up\" | \"down\" | \"left\" | \"right\"\n) => {\n if (direction === \"up\") return \"left\"\n else if (direction === \"left\") return \"down\"\n else if (direction === \"down\") return \"right\"\n else if (direction === \"right\") return \"up\"\n throw new Error(`Invalid direction: ${direction}`)\n}\n\nexport const rotateDirection = (\n direction: \"up\" | \"down\" | \"left\" | \"right\",\n num90DegreeClockwiseTurns: number\n) => {\n while (num90DegreeClockwiseTurns > 0) {\n direction = rotateClockwise(direction)\n num90DegreeClockwiseTurns--\n }\n while (num90DegreeClockwiseTurns < 0) {\n direction = rotateCounterClockwise(direction)\n num90DegreeClockwiseTurns++\n }\n return direction\n}\n\nexport const oppositeDirection = (\n direction: \"up\" | \"down\" | \"left\" | \"right\"\n) => {\n if (direction === \"up\") return \"down\"\n else if (direction === \"down\") return \"up\"\n else if (direction === \"left\") return \"right\"\n else if (direction === \"right\") return \"left\"\n throw new Error(`Invalid direction: ${direction}`)\n}\n\nexport const oppositeSide = (\n sideOrDir: \"up\" | \"down\" | \"top\" | \"bottom\" | \"left\" | \"right\"\n) => {\n if (sideOrDir === \"top\" || sideOrDir === \"up\") return \"bottom\"\n else if (sideOrDir === \"bottom\" || sideOrDir === \"down\") return \"top\"\n else if (sideOrDir === \"left\") return \"right\"\n else if (sideOrDir === \"right\") return \"left\"\n throw new Error(`Invalid sideOrDir: ${sideOrDir}`)\n}\n","import * as parsel from \"parsel-js\"\nimport { convertAbbrToType } from \"./convert-abbreviation-to-soup-element-type\"\nimport type { AnyCircuitElement } from \"circuit-json\"\n\nconst filterByType = (\n elements: AnyCircuitElement[],\n type: string\n): AnyCircuitElement[] => {\n type = convertAbbrToType(type)\n return elements.filter(\n (elm) => (\"ftype\" in elm && elm.ftype === type) || elm.type === type\n )\n}\n\n/**\n * Filter elements to match the selector, e.g. to access the left port of a\n * resistor you can do \".R1 > port.left\"\n */\nexport const applySelector = (\n elements: AnyCircuitElement[],\n selectorRaw: string\n): AnyCircuitElement[] => {\n const selectorAST = parsel.parse(selectorRaw)\n return applySelectorAST(elements, selectorAST!)\n}\n\nconst doesElmMatchClassName = (elm: AnyCircuitElement, className: string) =>\n (\"name\" in elm && elm.name === className) ||\n (\"port_hints\" in elm && elm.port_hints?.includes(className))\n\nexport const applySelectorAST = (\n elements: AnyCircuitElement[],\n selectorAST: parsel.AST\n): AnyCircuitElement[] => {\n switch (selectorAST.type) {\n case \"complex\": {\n switch (selectorAST.combinator) {\n case \" \": // TODO technically should do a deep search\n case \">\": {\n const { left, right } = selectorAST\n if (left.type === \"class\" || left.type === \"type\") {\n // TODO should also check if content matches any element tags\n let matchElms: AnyCircuitElement[]\n if (left.type === \"class\") {\n matchElms = elements.filter((elm) =>\n doesElmMatchClassName(elm, left.name)\n )\n } else if (left.type === \"type\") {\n matchElms = filterByType(elements, left.name)\n } else {\n matchElms = []\n }\n\n const childrenOfMatchingElms = matchElms.flatMap((matchElm) =>\n elements.filter(\n (elm: any) =>\n elm[`${matchElm.type}_id`] ===\n (matchElm as any)[`${matchElm.type}_id`] && elm !== matchElm\n )\n )\n return applySelectorAST(childrenOfMatchingElms, right)\n } else {\n throw new Error(`unsupported selector type \"${left.type}\" `)\n }\n }\n default: {\n throw new Error(\n `Couldn't apply selector AST for complex combinator \"${selectorAST.combinator}\"`\n )\n }\n }\n return []\n }\n case \"compound\": {\n const conditionsToMatch = selectorAST.list.map((part) => {\n switch (part.type) {\n case \"class\": {\n return (elm: any) => doesElmMatchClassName(elm, part.name)\n }\n case \"type\": {\n const name = convertAbbrToType(part.name)\n return (elm: any) => elm.type === name\n }\n }\n })\n\n return elements.filter((elm) =>\n conditionsToMatch.every((condFn) => condFn?.(elm))\n )\n }\n case \"type\": {\n return filterByType(elements, selectorAST.name) as AnyCircuitElement[]\n }\n case \"class\": {\n return elements.filter((elm) =>\n doesElmMatchClassName(elm, selectorAST.name)\n )\n }\n default: {\n throw new Error(\n `Couldn't apply selector AST for type: \"${\n selectorAST.type\n }\" ${JSON.stringify(selectorAST, null, \" \")}`\n )\n }\n }\n}\n","export const convertAbbrToType = (abbr: string): string => {\n switch (abbr) {\n case \"port\":\n return \"source_port\"\n case \"net\":\n return \"source_net\"\n case \"power\":\n return \"simple_power_source\"\n }\n return abbr\n}\n","import type { AnyCircuitElement } from \"circuit-json\"\n\nexport const getElementId = (elm: AnyCircuitElement): string => {\n const type = elm.type\n const id = (elm as any)[`${type}_id`]\n return id\n}\n","import type { AnyCircuitElement } from \"circuit-json\"\nimport { getElementId } from \"./get-element-id\"\n\nexport const getElementById = (\n soup: AnyCircuitElement[],\n id: string,\n): AnyCircuitElement | null => {\n return soup.find((elm) => getElementId(elm) === id) ?? null\n}\n","import type { AnyCircuitElement } from \"circuit-json\"\nimport { cju } from \"../cju\"\n\nexport function getReadableNameForPcbTrace(\n soup: AnyCircuitElement[],\n pcb_trace_id: string,\n) {\n // Find the pcb_trace object\n const pcbTrace = cju(soup).pcb_trace.get(pcb_trace_id)\n\n if (!pcbTrace) {\n return `trace[${pcb_trace_id}]`\n }\n\n // Get the connected ports\n const connectedPcbPortIds: string[] = pcbTrace.route\n .flatMap((point: any) => [point.start_pcb_port_id, point.end_pcb_port_id])\n .filter(Boolean)\n\n if (connectedPcbPortIds.length === 0) {\n return `trace[${pcb_trace_id}]`\n }\n\n // Function to get component name and port hint\n function getComponentAndPortInfo(pcb_port_id: string) {\n const pcbPort = cju(soup).pcb_port.get(pcb_port_id)\n if (!pcbPort) return null\n\n const pcbComponent = cju(soup).pcb_component.get(pcbPort.pcb_component_id)\n if (!pcbComponent) return null\n const sourceComponent = cju(soup).source_component.get(\n pcbComponent.source_component_id,\n )\n if (!sourceComponent) return null\n\n const sourcePort = cju(soup).source_port.get(pcbPort.source_port_id)\n const portHint = sourcePort?.port_hints ? sourcePort.port_hints[1] : \"\"\n\n return {\n componentName: sourceComponent.name,\n portHint: portHint,\n }\n }\n\n // Generate the readable selector\n const selectorParts = connectedPcbPortIds.map((portId) => {\n const info = getComponentAndPortInfo(portId)\n if (info) {\n return `.${info.componentName} > port.${info.portHint}`\n }\n return `port[${portId}]`\n })\n\n return `trace[${selectorParts.join(\", \")}]`\n}\n","import type { AnyCircuitElement } from \"circuit-json\"\nimport { cju } from \"../cju\"\n\nexport const getReadableNameForPcbPort = (\n soup: AnyCircuitElement[],\n pcb_port_id: string,\n): string => {\n const pcbPort = cju(soup).pcb_port.get(pcb_port_id)\n if (!pcbPort) {\n return `pcb_port[#${pcb_port_id}]`\n }\n\n // Get the component information\n const pcbComponent = cju(soup).pcb_component.get(pcbPort?.pcb_component_id)\n\n if (!pcbComponent) {\n return `pcb_port[#${pcb_port_id}]`\n }\n\n // Get the source component information\n const sourceComponent = cju(soup).source_component.get(\n pcbComponent.source_component_id,\n )\n\n if (!sourceComponent) {\n return `pcb_port[#${pcb_port_id}]`\n }\n\n // Get the source port information\n const sourcePort = cju(soup).source_port.get(pcbPort.source_port_id)\n\n if (!sourcePort) {\n return `pcb_port[#${pcb_port_id}]`\n }\n\n // Determine the pad number or hint\n let padIdentifier: string\n if (sourcePort?.port_hints && sourcePort.port_hints.length > 0) {\n padIdentifier = sourcePort.port_hints[0]!\n } else if (sourcePort.port_hints && sourcePort.port_hints.length > 0) {\n padIdentifier = sourcePort.port_hints[0]!\n } else {\n padIdentifier = pcb_port_id\n }\n\n return `pcb_port[.${sourceComponent.name} > .${padIdentifier}]`\n}\n","import type { AnyCircuitElement } from \"circuit-json\"\nimport { cju } from \"../cju\"\nimport { getReadableNameForPcbPort } from \"./get-readable-name-for-pcb-port\"\n\nexport function getReadableNameForPcbSmtpad(\n soup: AnyCircuitElement[],\n pcb_smtpad_id: string,\n): string {\n // Find the pcb_smtpad object\n const pcbSmtpad = cju(soup).pcb_smtpad.get(pcb_smtpad_id)\n\n if (!pcbSmtpad || !pcbSmtpad.pcb_port_id) {\n return `smtpad[${pcb_smtpad_id}]`\n }\n\n return getReadableNameForPcbPort(soup, pcbSmtpad.pcb_port_id)\n}\n","import type { AnyCircuitElement } from \"circuit-json\"\nimport { getReadableNameForPcbTrace } from \"./get-readable-name-for-pcb-trace\"\nimport { getReadableNameForPcbSmtpad } from \"./get-readable-name-for-pcb-smtpad\"\nimport { getReadableNameForPcbPort } from \"./get-readable-name-for-pcb-port\"\nimport { getElementById } from \"lib/get-element-by-id\"\nimport { getElementId } from \"lib/get-element-id\"\n\nexport const getReadableNameForElement = (\n soup: AnyCircuitElement[],\n elm: AnyCircuitElement | string,\n): string => {\n if (typeof elm === \"string\") {\n const elmObj = getElementById(soup, elm)\n if (!elmObj) `unknown (could not find element with id ${elm})`\n return getReadableNameForElement(soup, elmObj as any)\n }\n switch (elm.type) {\n case \"pcb_port\":\n return getReadableNameForPcbPort(soup, elm.pcb_port_id)\n case \"pcb_smtpad\":\n return getReadableNameForPcbSmtpad(soup, elm.pcb_smtpad_id)\n case \"pcb_trace\":\n return getReadableNameForPcbTrace(soup, elm.pcb_trace_id)\n case \"source_component\":\n return `source_component[${elm.name}]`\n default:\n return `${elm.type}[#${getElementId(elm)}]`\n }\n}\n\nexport {\n getReadableNameForPcbPort,\n getReadableNameForPcbSmtpad,\n getReadableNameForPcbTrace,\n}\n","import type { AnyCircuitElement } from \"circuit-json\"\n\nexport const getBoundsOfPcbElements = (\n elements: AnyCircuitElement[],\n): { minX: number; minY: number; maxX: number; maxY: number } => {\n let minX = Number.POSITIVE_INFINITY\n let minY = Number.POSITIVE_INFINITY\n let maxX = Number.NEGATIVE_INFINITY\n let maxY = Number.NEGATIVE_INFINITY\n\n for (const elm of elements) {\n if (!elm.type.startsWith(\"pcb_\")) continue\n\n let centerX: number | undefined\n let centerY: number | undefined\n\n let width: number | undefined\n let height: number | undefined\n\n if (\"x\" in elm && \"y\" in elm) {\n centerX = Number((elm as any).x)\n centerY = Number((elm as any).y)\n }\n\n if (\"outer_diameter\" in elm) {\n width = Number((elm as any).outer_diameter)\n height = Number((elm as any).outer_diameter)\n }\n\n if (\"width\" in elm) {\n width = Number((elm as any).width)\n }\n\n if (\"height\" in elm) {\n height = Number((elm as any).height)\n }\n\n if (\"center\" in elm) {\n // @ts-ignore\n centerX = elm.center.x\n // @ts-ignore\n centerY = elm.center.y\n }\n\n if (centerX !== undefined && centerY !== undefined) {\n minX = Math.min(minX, centerX)\n minY = Math.min(minY, centerY)\n maxX = Math.max(maxX, centerX)\n maxY = Math.max(maxY, centerY)\n\n if (width !== undefined && height !== undefined) {\n minX = Math.min(minX, centerX - width / 2)\n minY = Math.min(minY, centerY - height / 2)\n maxX = Math.max(maxX, centerX + width / 2)\n maxY = Math.max(maxY, centerY + height / 2)\n }\n\n if (\"radius\" in elm) {\n minX = Math.min(minX, centerX - elm.radius)\n minY = Math.min(minY, centerY - elm.radius)\n maxX = Math.max(maxX, centerX + elm.radius)\n maxY = Math.max(maxY, centerY + elm.radius)\n }\n } else if (elm.type === \"pcb_trace\") {\n for (const point of elm.route) {\n // TODO add trace thickness support\n minX = Math.min(minX, point.x)\n minY = Math.min(minY, point.y)\n maxX = Math.max(maxX, point.x)\n maxY = Math.max(maxY, point.y)\n }\n }\n }\n\n return { minX, minY, maxX, maxY }\n}\n","export function stringHash(str: string) {\n let hash = 0\n if (str.length == 0) return hash\n for (var i = 0; i < str.length; i++) {\n var char = str.charCodeAt(i)\n hash = (hash << 5) - hash + char\n hash = hash & hash // Convert to 32bit integer\n }\n return Math.abs(hash)\n}\n","import { stringHash } from \"./string-hash\"\n\nexport type LayoutDebugObject = {\n x: number\n y: number\n width: number\n height: number\n bg_color: string\n title: string\n content: Object\n secondary?: boolean\n}\n\n/**\n * Vendored from \"nice-color-palettes\" package\n */\nconst nice_color_palettes = [\n [\"#69d2e7\", \"#a7dbd8\", \"#e0e4cc\", \"#f38630\", \"#fa6900\"],\n [\"#fe4365\", \"#fc9d9a\", \"#f9cdad\", \"#c8c8a9\", \"#83af9b\"],\n [\"#ecd078\", \"#d95b43\", \"#c02942\", \"#542437\", \"#53777a\"],\n [\"#556270\", \"#4ecdc4\", \"#c7f464\", \"#ff6b6b\", \"#c44d58\"],\n [\"#774f38\", \"#e08e79\", \"#f1d4af\", \"#ece5ce\", \"#c5e0dc\"],\n [\"#e8ddcb\", \"#cdb380\", \"#036564\", \"#033649\", \"#031634\"],\n [\"#490a3d\", \"#bd1550\", \"#e97f02\", \"#f8ca00\", \"#8a9b0f\"],\n [\"#594f4f\", \"#547980\", \"#45ada8\", \"#9de0ad\", \"#e5fcc2\"],\n [\"#00a0b0\", \"#6a4a3c\", \"#cc333f\", \"#eb6841\", \"#edc951\"],\n [\"#e94e77\", \"#d68189\", \"#c6a49a\", \"#c6e5d9\", \"#f4ead5\"],\n [\"#3fb8af\", \"#7fc7af\", \"#dad8a7\", \"#ff9e9d\", \"#ff3d7f\"],\n [\"#d9ceb2\", \"#948c75\", \"#d5ded9\", \"#7a6a53\", \"#99b2b7\"],\n [\"#ffffff\", \"#cbe86b\", \"#f2e9e1\", \"#1c140d\", \"#cbe86b\"],\n [\"#efffcd\", \"#dce9be\", \"#555152\", \"#2e2633\", \"#99173c\"],\n [\"#343838\", \"#005f6b\", \"#008c9e\", \"#00b4cc\", \"#00dffc\"],\n [\"#413e4a\", \"#73626e\", \"#b38184\", \"#f0b49e\", \"#f7e4be\"],\n [\"#ff4e50\", \"#fc913a\", \"#f9d423\", \"#ede574\", \"#e1f5c4\"],\n [\"#99b898\", \"#fecea8\", \"#ff847c\", \"#e84a5f\", \"#2a363b\"],\n [\"#655643\", \"#80bca3\", \"#f6f7bd\", \"#e6ac27\", \"#bf4d28\"],\n [\"#00a8c6\", \"#40c0cb\", \"#f9f2e7\", \"#aee239\", \"#8fbe00\"],\n [\"#351330\", \"#424254\", \"#64908a\", \"#e8caa4\", \"#cc2a41\"],\n [\"#554236\", \"#f77825\", \"#d3ce3d\", \"#f1efa5\", \"#60b99a\"],\n [\"#5d4157\", \"#838689\", \"#a8caba\", \"#cad7b2\", \"#ebe3aa\"],\n [\"#8c2318\", \"#5e8c6a\", \"#88a65e\", \"#bfb35a\", \"#f2c45a\"],\n [\"#fad089\", \"#ff9c5b\", \"#f5634a\", \"#ed303c\", \"#3b8183\"],\n [\"#ff4242\", \"#f4fad2\", \"#d4ee5e\", \"#e1edb9\", \"#f0f2eb\"],\n [\"#f8b195\", \"#f67280\", \"#c06c84\", \"#6c5b7b\", \"#355c7d\"],\n [\"#d1e751\", \"#ffffff\", \"#000000\", \"#4dbce9\", \"#26ade4\"],\n [\"#1b676b\", \"#519548\", \"#88c425\", \"#bef202\", \"#eafde6\"],\n [\"#5e412f\", \"#fcebb6\", \"#78c0a8\", \"#f07818\", \"#f0a830\"],\n [\"#bcbdac\", \"#cfbe27\", \"#f27435\", \"#f02475\", \"#3b2d38\"],\n [\"#452632\", \"#91204d\", \"#e4844a\", \"#e8bf56\", \"#e2f7ce\"],\n [\"#eee6ab\", \"#c5bc8e\", \"#696758\", \"#45484b\", \"#36393b\"],\n [\"#f0d8a8\", \"#3d1c00\", \"#86b8b1\", \"#f2d694\", \"#fa2a00\"],\n [\"#2a044a\", \"#0b2e59\", \"#0d6759\", \"#7ab317\", \"#a0c55f\"],\n [\"#f04155\", \"#ff823a\", \"#f2f26f\", \"#fff7bd\", \"#95cfb7\"],\n [\"#b9d7d9\", \"#668284\", \"#2a2829\", \"#493736\", \"#7b3b3b\"],\n [\"#bbbb88\", \"#ccc68d\", \"#eedd99\", \"#eec290\", \"#eeaa88\"],\n [\"#b3cc57\", \"#ecf081\", \"#ffbe40\", \"#ef746f\", \"#ab3e5b\"],\n [\"#a3a948\", \"#edb92e\", \"#f85931\", \"#ce1836\", \"#009989\"],\n [\"#300030\", \"#480048\", \"#601848\", \"#c04848\", \"#f07241\"],\n [\"#67917a\", \"#170409\", \"#b8af03\", \"#ccbf82\", \"#e33258\"],\n [\"#aab3ab\", \"#c4cbb7\", \"#ebefc9\", \"#eee0b7\", \"#e8caaf\"],\n [\"#e8d5b7\", \"#0e2430\", \"#fc3a51\", \"#f5b349\", \"#e8d5b9\"],\n [\"#ab526b\", \"#bca297\", \"#c5ceae\", \"#f0e2a4\", \"#f4ebc3\"],\n [\"#607848\", \"#789048\", \"#c0d860\", \"#f0f0d8\", \"#604848\"],\n [\"#b6d8c0\", \"#c8d9bf\", \"#dadabd\", \"#ecdbbc\", \"#fedcba\"],\n [\"#a8e6ce\", \"#dcedc2\", \"#ffd3b5\", \"#ffaaa6\", \"#ff8c94\"],\n [\"#3e4147\", \"#fffedf\", \"#dfba69\", \"#5a2e2e\", \"#2a2c31\"],\n [\"#fc354c\", \"#29221f\", \"#13747d\", \"#0abfbc\", \"#fcf7c5\"],\n [\"#cc0c39\", \"#e6781e\", \"#c8cf02\", \"#f8fcc1\", \"#1693a7\"],\n [\"#1c2130\", \"#028f76\", \"#b3e099\", \"#ffeaad\", \"#d14334\"],\n [\"#a7c5bd\", \"#e5ddcb\", \"#eb7b59\", \"#cf4647\", \"#524656\"],\n [\"#dad6ca\", \"#1bb0ce\", \"#4f8699\", \"#6a5e72\", \"#563444\"],\n [\"#5c323e\", \"#a82743\", \"#e15e32\", \"#c0d23e\", \"#e5f04c\"],\n [\"#edebe6\", \"#d6e1c7\", \"#94c7b6\", \"#403b33\", \"#d3643b\"],\n [\"#fdf1cc\", \"#c6d6b8\", \"#987f69\", \"#e3ad40\", \"#fcd036\"],\n [\"#230f2b\", \"#f21d41\", \"#ebebbc\", \"#bce3c5\", \"#82b3ae\"],\n [\"#b9d3b0\", \"#81bda4\", \"#b28774\", \"#f88f79\", \"#f6aa93\"],\n [\"#3a111c\", \"#574951\", \"#83988e\", \"#bcdea5\", \"#e6f9bc\"],\n [\"#5e3929\", \"#cd8c52\", \"#b7d1a3\", \"#dee8be\", \"#fcf7d3\"],\n [\"#1c0113\", \"#6b0103\", \"#a30006\", \"#c21a01\", \"#f03c02\"],\n [\"#000000\", \"#9f111b\", \"#b11623\", \"#292c37\", \"#cccccc\"],\n [\"#382f32\", \"#ffeaf2\", \"#fcd9e5\", \"#fbc5d8\", \"#f1396d\"],\n [\"#e3dfba\", \"#c8d6bf\", \"#93ccc6\", \"#6cbdb5\", \"#1a1f1e\"],\n [\"#f6f6f6\", \"#e8e8e8\", \"#333333\", \"#990100\", \"#b90504\"],\n [\"#1b325f\", \"#9cc4e4\", \"#e9f2f9\", \"#3a89c9\", \"#f26c4f\"],\n [\"#a1dbb2\", \"#fee5ad\", \"#faca66\", \"#f7a541\", \"#f45d4c\"],\n [\"#c1b398\", \"#605951\", \"#fbeec2\", \"#61a6ab\", \"#accec0\"],\n [\"#5e9fa3\", \"#dcd1b4\", \"#fab87f\", \"#f87e7b\", \"#b05574\"],\n [\"#951f2b\", \"#f5f4d7\", \"#e0dfb1\", \"#a5a36c\", \"#535233\"],\n [\"#8dccad\", \"#988864\", \"#fea6a2\", \"#f9d6ac\", \"#ffe9af\"],\n [\"#2d2d29\", \"#215a6d\", \"#3ca2a2\", \"#92c7a3\", \"#dfece6\"],\n [\"#413d3d\", \"#040004\", \"#c8ff00\", \"#fa023c\", \"#4b000f\"],\n [\"#eff3cd\", \"#b2d5ba\", \"#61ada0\", \"#248f8d\", \"#605063\"],\n [\"#ffefd3\", \"#fffee4\", \"#d0ecea\", \"#9fd6d2\", \"#8b7a5e\"],\n [\"#cfffdd\", \"#b4dec1\", \"#5c5863\", \"#a85163\", \"#ff1f4c\"],\n [\"#9dc9ac\", \"#fffec7\", \"#f56218\", \"#ff9d2e\", \"#919167\"],\n [\"#4e395d\", \"#827085\", \"#8ebe94\", \"#ccfc8e\", \"#dc5b3e\"],\n [\"#a8a7a7\", \"#cc527a\", \"#e8175d\", \"#474747\", \"#363636\"],\n [\"#f8edd1\", \"#d88a8a\", \"#474843\", \"#9d9d93\", \"#c5cfc6\"],\n [\"#046d8b\", \"#309292\", \"#2fb8ac\", \"#93a42a\", \"#ecbe13\"],\n [\"#f38a8a\", \"#55443d\", \"#a0cab5\", \"#cde9ca\", \"#f1edd0\"],\n [\"#a70267\", \"#f10c49\", \"#fb6b41\", \"#f6d86b\", \"#339194\"],\n [\"#ff003c\", \"#ff8a00\", \"#fabe28\", \"#88c100\", \"#00c176\"],\n [\"#ffedbf\", \"#f7803c\", \"#f54828\", \"#2e0d23\", \"#f8e4c1\"],\n [\"#4e4d4a\", \"#353432\", \"#94ba65\", \"#2790b0\", \"#2b4e72\"],\n [\"#0ca5b0\", \"#4e3f30\", \"#fefeeb\", \"#f8f4e4\", \"#a5b3aa\"],\n [\"#4d3b3b\", \"#de6262\", \"#ffb88c\", \"#ffd0b3\", \"#f5e0d3\"],\n [\"#fffbb7\", \"#a6f6af\", \"#66b6ab\", \"#5b7c8d\", \"#4f2958\"],\n [\"#edf6ee\", \"#d1c089\", \"#b3204d\", \"#412e28\", \"#151101\"],\n [\"#9d7e79\", \"#ccac95\", \"#9a947c\", \"#748b83\", \"#5b756c\"],\n [\"#fcfef5\", \"#e9ffe1\", \"#cdcfb7\", \"#d6e6c3\", \"#fafbe3\"],\n [\"#9cddc8\", \"#bfd8ad\", \"#ddd9ab\", \"#f7af63\", \"#633d2e\"],\n [\"#30261c\", \"#403831\", \"#36544f\", \"#1f5f61\", \"#0b8185\"],\n [\"#aaff00\", \"#ffaa00\", \"#ff00aa\", \"#aa00ff\", \"#00aaff\"],\n [\"#d1313d\", \"#e5625c\", \"#f9bf76\", \"#8eb2c5\", \"#615375\"],\n [\"#ffe181\", \"#eee9e5\", \"#fad3b2\", \"#ffba7f\", \"#ff9c97\"],\n [\"#73c8a9\", \"#dee1b6\", \"#e1b866\", \"#bd5532\", \"#373b44\"],\n [\"#805841\", \"#dcf7f3\", \"#fffcdd\", \"#ffd8d8\", \"#f5a2a2\"],\n]\n\nexport const getDebugLayoutObject = (lo: any): LayoutDebugObject | null => {\n let {\n x,\n y,\n width,\n height,\n }: { x: number; y: number; width?: number; height?: number } = {\n ...lo,\n ...(lo as any).size,\n ...(lo as any).center,\n ...(lo as any).position,\n }\n\n if (\n lo.x1 !== undefined &&\n lo.x2 !== undefined &&\n lo.y1 !== undefined &&\n lo.y2 !== undefined\n ) {\n x = (lo.x1 + lo.x2) / 2\n y = (lo.y1 + lo.y2) / 2\n width = Math.abs(lo.x1 - lo.x2)\n height = Math.abs(lo.y1 - lo.y2)\n }\n\n if (lo.points && Array.isArray(lo.points) && lo.points.length > 0) {\n const xCoords = lo.points.map((point: { x: number }) => point.x)\n const yCoords = lo.points.map((point: { y: number }) => point.y)\n \n const minX = Math.min(...xCoords)\n const maxX = Math.max(...xCoords)\n const minY = Math.min(...yCoords)\n const maxY = Math.max(...yCoords)\n \n x = (minX + maxX) / 2\n y = (minY + maxY) / 2\n width = maxX - minX\n height = maxY - minY\n }\n\n const title = lo.text || lo.name || lo.source?.text || lo.source?.name || \"?\"\n const content = lo\n\n if (x === undefined || y === undefined) return null\n\n if (width === undefined) {\n if (\"outer_diameter\" in lo) {\n width = lo.outer_diameter\n height = lo.outer_diameter\n }\n }\n\n if (width === undefined || height === undefined) {\n width = 0.1\n height = 0.1\n }\n\n return {\n x,\n y,\n width,\n height,\n title,\n content,\n bg_color:\n nice_color_palettes[\n stringHash((lo as any).type || title) % nice_color_palettes.length\n ]?.[4] ?? \"#f00\",\n }\n}\n","export const isTruthy = <T>(value: T): value is NonNullable<T> => Boolean(value)\n","import type { AnyCircuitElement } from \"circuit-json\"\nimport { getDebugLayoutObject } from \"./utils/get-layout-debug-object\"\nimport { isTruthy } from \"./utils/is-truthy\"\n\nexport const findBoundsAndCenter = (\n elements: AnyCircuitElement[],\n): { center: { x: number; y: number }; width: number; height: number } => {\n const debugObjects = elements\n .filter((elm) => elm.type.startsWith(\"pcb_\"))\n .concat(\n elements\n .filter((elm) => elm.type === \"pcb_trace\")\n // @ts-ignore\n .flatMap((elm: PcbTrace) => elm.route),\n )\n .map((elm) => getDebugLayoutObject(elm))\n .filter(isTruthy)\n\n if (debugObjects.length === 0)\n return { center: { x: 0, y: 0 }, width: 0, height: 0 }\n\n let minX = debugObjects[0]!.x - debugObjects[0]!.width / 2\n let maxX = debugObjects[0]!.x + debugObjects[0]!.width / 2\n let minY = debugObjects[0]!.y - debugObjects[0]!.height / 2\n let maxY = debugObjects[0]!.y + debugObjects[0]!.height / 2\n\n for (const obj of debugObjects.slice(1)) {\n minX = Math.min(minX, obj.x - obj.width / 2)\n maxX = Math.max(maxX, obj.x + obj.width / 2)\n minY = Math.min(minY, obj.y - obj.height / 2)\n maxY = Math.max(maxY, obj.y + obj.height / 2)\n }\n\n const width = maxX - minX\n const height = maxY - minY\n const center = { x: minX + width / 2, y: minY + height / 2 }\n\n return { center, width, height }\n}\n","import type { AnyCircuitElement } from \"circuit-json\"\n\nexport const getPrimaryId = (element: AnyCircuitElement): string => {\n // @ts-ignore\n return element[`${element.type}_id`]\n}\n","import type { AnyCircuitElement } from \"circuit-json\"\nimport { transformPCBElements } from \"./transform-soup-elements\"\nimport { translate } from \"transformation-matrix\"\n\nexport const repositionPcbComponentTo = (\n circuitJson: AnyCircuitElement[],\n pcb_component_id: string,\n newCenter: { x: number; y: number },\n) => {\n const pcbComponent = circuitJson.find(\n (e) =>\n e.type === \"pcb_component\" &&\n (e as any).pcb_component_id === pcb_component_id,\n )\n if (!pcbComponent) return\n\n const currentCenter =\n \"center\" in pcbComponent\n ? (pcbComponent as any).center\n : { x: (pcbComponent as any).x, y: (pcbComponent as any).y }\n\n const dx = newCenter.x - currentCenter.x\n const dy = newCenter.y - currentCenter.y\n\n const portIds = circuitJson\n .filter(\n (e) =>\n e.type === \"pcb_port\" &&\n (e as any).pcb_component_id === pcb_component_id,\n )\n .map((e) => (e as any).pcb_port_id)\n\n const elementsToMove = circuitJson.filter((elm) => {\n if (elm === pcbComponent) return true\n const anyElm: any = elm\n if (anyElm.pcb_component_id === pcb_component_id) return true\n if (\n Array.isArray(anyElm.pcb_component_ids) &&\n anyElm.pcb_component_ids.includes(pcb_component_id)\n )\n return true\n if (anyElm.pcb_port_id && portIds.includes(anyElm.pcb_port_id)) return true\n if (\n Array.isArray(anyElm.pcb_port_ids) &&\n anyElm.pcb_port_ids.some((id: string) => portIds.includes(id))\n )\n return true\n if (anyElm.start_pcb_port_id && portIds.includes(anyElm.start_pcb_port_id))\n return true\n if (anyElm.end_pcb_port_id && portIds.includes(anyElm.end_pcb_port_id))\n return true\n if (\n Array.isArray(anyElm.route) &&\n anyElm.route.some(\n (pt: any) =>\n (pt.start_pcb_port_id && portIds.includes(pt.start_pcb_port_id)) ||\n (pt.end_pcb_port_id && portIds.includes(pt.end_pcb_port_id)),\n )\n )\n return true\n return false\n })\n\n const matrix = translate(dx, dy)\n transformPCBElements(elementsToMove, matrix)\n}\n"],"mappings":"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W,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD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","names":["su","Soup","joiner"]}
|
|
1
|
+
{"version":3,"sources":["../lib/cju.ts","../lib/subtree.ts","../lib/cju-indexed.ts","../lib/transform-soup-elements.ts","../lib/direction-to-vec.ts","../lib/apply-selector.ts","../lib/convert-abbreviation-to-soup-element-type.ts","../lib/get-element-id.ts","../lib/get-element-by-id.ts","../lib/readable-name-functions/get-readable-name-for-pcb-trace.ts","../lib/readable-name-functions/get-readable-name-for-pcb-port.ts","../lib/readable-name-functions/get-readable-name-for-pcb-smtpad.ts","../lib/readable-name-functions/get-readable-name-for-element.ts","../lib/get-bounds-of-pcb-elements.ts","../lib/utils/string-hash.ts","../lib/utils/get-layout-debug-object.ts","../lib/utils/is-truthy.ts","../lib/find-bounds-and-center.ts","../lib/get-primary-id.ts","../lib/reposition-pcb-component.ts","../lib/getCircuitJsonTree.ts","../lib/getStringFromCircuitJsonTree.ts"],"sourcesContent":["import type {\n AnyCircuitElement,\n AnyCircuitElementInput,\n SourceComponentBase,\n SourcePort,\n} from \"circuit-json\"\nimport * as Soup from \"circuit-json\"\nimport type { SubtreeOptions } from \"./subtree\"\nimport { buildSubtree } from \"./subtree\"\n\nexport type CircuitJsonOps<\n K extends AnyCircuitElement[\"type\"],\n T extends AnyCircuitElement | AnyCircuitElementInput,\n> = {\n get: (id: string) => Extract<T, { type: K }> | null\n select: (selector: string) => Extract<T, { type: K }> | null\n getWhere: (where: any) => Extract<T, { type: K }> | null\n getUsing: (using: {\n [key: `${string}_id`]: string\n }) => Extract<T, { type: K }> | null\n insert: (\n elm: Omit<Extract<T, { type: K }>, \"type\" | `${K}_id`>,\n ) => Extract<T, { type: K }>\n update: (\n id: string,\n newProps: Partial<Extract<T, { type: K }>>,\n ) => Extract<T, { type: K }>\n delete: (id: string) => void\n list: (where?: any) => Extract<T, { type: K }>[]\n}\n\nexport type CircuitJsonUtilObjects = {\n [K in AnyCircuitElement[\"type\"]]: CircuitJsonOps<K, AnyCircuitElement>\n} & {\n subtree: (where?: any) => CircuitJsonUtilObjects\n toArray: () => AnyCircuitElement[]\n editCount: number\n}\nexport type CircuitJsonInputUtilObjects = {\n [K in AnyCircuitElementInput[\"type\"]]: CircuitJsonOps<\n K,\n AnyCircuitElementInput\n >\n}\n\nexport type CircuitJsonUtilOptions = {\n validateInserts?: boolean\n}\n\nexport type GetCircuitJsonUtilFn = ((\n soup: AnyCircuitElement[],\n options?: CircuitJsonUtilOptions,\n) => CircuitJsonUtilObjects) & {\n unparsed: (soup: AnyCircuitElementInput[]) => CircuitJsonInputUtilObjects\n}\n\ninterface InternalStore {\n counts: Record<string, number>\n editCount: number\n}\n\nexport const cju: GetCircuitJsonUtilFn = ((\n circuitJsonInput: any[],\n options: CircuitJsonUtilOptions = {},\n) => {\n const circuitJson = circuitJsonInput as AnyCircuitElement[]\n let internalStore: InternalStore = (circuitJson as any)._internal_store\n if (!internalStore) {\n internalStore = {\n counts: {},\n editCount: 0,\n } as InternalStore\n ;(circuitJson as any)._internal_store = internalStore\n\n // Initialize counts\n for (const elm of circuitJson) {\n const type = elm.type\n const idVal = (elm as any)[`${type}_id`]\n if (!idVal) continue\n const idNum = Number.parseInt(idVal.split(\"_\").pop())\n if (!Number.isNaN(idNum)) {\n internalStore.counts[type] = Math.max(\n internalStore.counts[type] ?? 0,\n idNum,\n )\n }\n }\n }\n const su = new Proxy(\n {},\n {\n get: (proxy_target: any, prop: string) => {\n if (prop === \"toArray\") {\n return () => {\n ;(circuitJson as any).editCount = internalStore.editCount\n return circuitJson\n }\n }\n if (prop === \"editCount\") {\n return internalStore.editCount\n }\n\n if (prop === \"subtree\") {\n return (opts: SubtreeOptions) =>\n cju(buildSubtree(circuitJson, opts), options)\n }\n\n const component_type = prop\n\n return {\n get: (id: string) =>\n circuitJson.find(\n (e: any) =>\n e.type === component_type && e[`${component_type}_id`] === id,\n ),\n getUsing: (using: any) => {\n const keys = Object.keys(using)\n if (keys.length !== 1) {\n throw new Error(\n \"getUsing requires exactly one key, e.g. { pcb_component_id }\",\n )\n }\n const join_key = keys[0] as string\n const join_type = join_key.replace(\"_id\", \"\")\n const joiner: any = circuitJson.find(\n (e: any) =>\n e.type === join_type && e[join_key] === using[join_key],\n )\n if (!joiner) return null\n return circuitJson.find(\n (e: any) =>\n e.type === component_type &&\n e[`${component_type}_id`] === joiner[`${component_type}_id`],\n )\n },\n getWhere: (where: any) => {\n const keys = Object.keys(where)\n return circuitJson.find(\n (e: any) =>\n e.type === component_type &&\n keys.every((key) => e[key] === where[key]),\n )\n },\n list: (where?: any) => {\n const keys = !where ? [] : Object.keys(where)\n return circuitJson.filter(\n (e: any) =>\n e.type === component_type &&\n keys.every((key) => e[key] === where[key]),\n )\n },\n insert: (elm: any) => {\n internalStore.counts[component_type] ??= -1\n internalStore.counts[component_type]++\n const index = internalStore.counts[component_type]\n const newElm = {\n type: component_type,\n [`${component_type}_id`]: `${component_type}_${index}`,\n ...elm,\n }\n\n if (options.validateInserts) {\n const parser =\n (Soup as any)[component_type] ?? Soup.any_soup_element\n parser.parse(newElm)\n }\n\n circuitJson.push(newElm)\n internalStore.editCount++\n return newElm\n },\n delete: (id: string) => {\n const elm = circuitJson.find(\n (e) => (e as any)[`${component_type}_id`] === id,\n )\n if (!elm) return\n circuitJson.splice(circuitJson.indexOf(elm), 1)\n internalStore.editCount++\n },\n update: (id: string, newProps: any) => {\n const elm = circuitJson.find(\n (e) =>\n e.type === component_type &&\n (e as any)[`${component_type}_id`] === id,\n )\n if (!elm) return null\n Object.assign(elm, newProps)\n internalStore.editCount++\n return elm\n },\n select: (selector: string) => {\n // TODO when applySelector is isolated we can use it, until then we\n // do a poor man's selector implementation for two common cases\n if (component_type === \"source_component\") {\n return circuitJson.find(\n (e) =>\n e.type === \"source_component\" &&\n e.name === selector.replace(/\\./g, \"\"),\n )\n } else if (\n component_type === \"pcb_port\" ||\n component_type === \"source_port\" ||\n component_type === \"schematic_port\"\n ) {\n const [component_name, port_selector] = selector\n .replace(/\\./g, \"\")\n .split(/[\\s\\>]+/)\n const source_component = circuitJson.find(\n (e) =>\n e.type === \"source_component\" && e.name === component_name,\n ) as SourceComponentBase\n if (!source_component) return null\n const source_port = circuitJson.find(\n (e) =>\n e.type === \"source_port\" &&\n e.source_component_id ===\n source_component.source_component_id &&\n (e.name === port_selector ||\n (e.port_hints ?? []).includes(port_selector!)),\n ) as SourcePort\n if (!source_port) return null\n if (component_type === \"source_port\") return source_port\n\n if (component_type === \"pcb_port\") {\n return circuitJson.find(\n (e) =>\n e.type === \"pcb_port\" &&\n e.source_port_id === source_port.source_port_id,\n )\n } else if (component_type === \"schematic_port\") {\n return circuitJson.find(\n (e) =>\n e.type === \"schematic_port\" &&\n e.source_port_id === source_port.source_port_id,\n )\n }\n }\n },\n }\n },\n },\n )\n\n return su\n}) as any\ncju.unparsed = cju as any\n\nexport const su = cju\n\nexport default cju\n","import type { AnyCircuitElement } from \"circuit-json\"\n\nexport type SubtreeOptions = {\n subcircuit_id?: string\n source_group_id?: string\n}\n\nfunction connect(\n map: Map<AnyCircuitElement, Set<AnyCircuitElement>>,\n a: AnyCircuitElement | undefined,\n b: AnyCircuitElement | undefined,\n) {\n if (!a || !b) return\n let setA = map.get(a)\n if (!setA) {\n setA = new Set()\n map.set(a, setA)\n }\n setA.add(b)\n let setB = map.get(b)\n if (!setB) {\n setB = new Set()\n map.set(b, setB)\n }\n setB.add(a)\n}\n\nexport function buildSubtree(\n soup: AnyCircuitElement[],\n opts: SubtreeOptions,\n): AnyCircuitElement[] {\n if (!opts.subcircuit_id && !opts.source_group_id) return [...soup]\n\n const idMap = new Map<string, AnyCircuitElement>()\n for (const elm of soup) {\n const idVal = (elm as any)[`${elm.type}_id`]\n if (typeof idVal === \"string\") {\n idMap.set(idVal, elm)\n }\n }\n\n const adj = new Map<AnyCircuitElement, Set<AnyCircuitElement>>()\n for (const elm of soup) {\n const entries = Object.entries(elm as any)\n for (const [key, val] of entries) {\n if (key === \"parent_source_group_id\") continue\n if (key.endsWith(\"_id\") && typeof val === \"string\") {\n const other = idMap.get(val)\n connect(adj, elm, other)\n } else if (key.endsWith(\"_ids\") && Array.isArray(val)) {\n for (const v of val) {\n if (typeof v === \"string\") {\n const other = idMap.get(v)\n connect(adj, elm, other)\n }\n }\n }\n }\n }\n\n const queue: AnyCircuitElement[] = []\n const included = new Set<AnyCircuitElement>()\n\n for (const elm of soup) {\n if (\n (opts.subcircuit_id &&\n (elm as any).subcircuit_id === opts.subcircuit_id) ||\n (opts.source_group_id &&\n ((elm as any).source_group_id === opts.source_group_id ||\n (Array.isArray((elm as any).member_source_group_ids) &&\n (elm as any).member_source_group_ids.includes(\n opts.source_group_id,\n ))))\n ) {\n queue.push(elm)\n included.add(elm)\n }\n }\n\n while (queue.length > 0) {\n const elm = queue.shift()!\n const neighbors = adj.get(elm)\n if (!neighbors) continue\n for (const n of neighbors) {\n if (!included.has(n)) {\n included.add(n)\n queue.push(n)\n }\n }\n }\n\n return soup.filter((e) => included.has(e))\n}\n","import type {\n AnyCircuitElement,\n AnyCircuitElementInput,\n SourceComponentBase,\n SourcePort,\n} from \"circuit-json\"\nimport * as Soup from \"circuit-json\"\nimport type {\n CircuitJsonOps,\n CircuitJsonUtilObjects as CircuitJsonUtilObjects,\n CircuitJsonInputUtilObjects as CircuitJsonInputUtilObjects,\n} from \"./cju\"\n\nexport type IndexedCircuitJsonUtilOptions = {\n validateInserts?: boolean\n indexConfig?: {\n // Enable specific indexes for faster lookups\n byId?: boolean\n byType?: boolean\n byRelation?: boolean\n bySubcircuit?: boolean\n byCustomField?: string[]\n }\n}\n\nexport type GetIndexedCircuitJsonUtilFn = ((\n soup: AnyCircuitElement[],\n options?: IndexedCircuitJsonUtilOptions,\n) => CircuitJsonUtilObjects) & {\n unparsed: (soup: AnyCircuitElementInput[]) => CircuitJsonInputUtilObjects\n}\n\ninterface InternalStore {\n counts: Record<string, number>\n editCount: number\n // Indexes for faster lookups\n indexes: {\n byId?: Map<string, AnyCircuitElement>\n byType?: Map<string, AnyCircuitElement[]>\n // Maps relation fields (like component_id) to elements\n byRelation?: Map<string, Map<string, AnyCircuitElement[]>>\n // Maps subcircuit_id to elements\n bySubcircuit?: Map<string, AnyCircuitElement[]>\n // Custom field indexes\n byCustomField?: Map<string, Map<string, AnyCircuitElement[]>>\n }\n}\n\n// Creates a unique key for the ID index\nfunction createIdKey(element: AnyCircuitElement): string {\n const type = element.type\n return `${type}:${(element as any)[`${type}_id`]}`\n}\n\nexport const cjuIndexed: GetIndexedCircuitJsonUtilFn = ((\n soup: AnyCircuitElement[],\n options: IndexedCircuitJsonUtilOptions = {},\n) => {\n let internalStore: InternalStore = (soup as any)._internal_store_indexed\n\n if (!internalStore) {\n internalStore = {\n counts: {},\n editCount: 0,\n indexes: {},\n } as InternalStore\n\n // Initialize counts\n for (const elm of soup) {\n const type = elm.type\n const idVal = (elm as any)[`${type}_id`]\n if (!idVal) continue\n const idNum = Number.parseInt(idVal.split(\"_\").pop() || \"\")\n if (!Number.isNaN(idNum)) {\n internalStore.counts[type] = Math.max(\n internalStore.counts[type] ?? 0,\n idNum,\n )\n }\n }\n\n // Build indexes\n const indexConfig = options.indexConfig || {}\n const indexes = internalStore.indexes\n\n // Reset indexes before rebuilding\n if (indexConfig.byId) {\n indexes.byId = new Map()\n }\n\n if (indexConfig.byType) {\n indexes.byType = new Map()\n }\n\n if (indexConfig.byRelation) {\n indexes.byRelation = new Map()\n }\n\n if (indexConfig.bySubcircuit) {\n indexes.bySubcircuit = new Map()\n }\n\n if (indexConfig.byCustomField && indexConfig.byCustomField.length > 0) {\n indexes.byCustomField = new Map()\n for (const field of indexConfig.byCustomField) {\n indexes.byCustomField.set(field, new Map())\n }\n }\n\n // Build indexes\n for (const element of soup) {\n // Index by ID\n if (indexConfig.byId) {\n const idKey = createIdKey(element)\n indexes.byId!.set(idKey, element)\n }\n\n // Index by type\n if (indexConfig.byType) {\n const elementsOfType = indexes.byType!.get(element.type) || []\n elementsOfType.push(element)\n indexes.byType!.set(element.type, elementsOfType)\n }\n\n // Index by relation fields (fields ending with _id)\n if (indexConfig.byRelation) {\n const elementEntries = Object.entries(element)\n for (const [key, value] of elementEntries) {\n if (\n key.endsWith(\"_id\") &&\n key !== `${element.type}_id` &&\n typeof value === \"string\"\n ) {\n const relationTypeMap = indexes.byRelation!.get(key) || new Map()\n const relatedElements = relationTypeMap.get(value as string) || []\n relatedElements.push(element)\n relationTypeMap.set(value as string, relatedElements)\n indexes.byRelation!.set(key, relationTypeMap)\n }\n }\n }\n\n // Index by subcircuit_id\n if (indexConfig.bySubcircuit && \"subcircuit_id\" in element) {\n const subcircuitId = (element as any).subcircuit_id\n if (subcircuitId && typeof subcircuitId === \"string\") {\n const subcircuitElements =\n indexes.bySubcircuit!.get(subcircuitId) || []\n subcircuitElements.push(element)\n indexes.bySubcircuit!.set(subcircuitId, subcircuitElements)\n }\n }\n\n // Index by custom fields\n if (indexConfig.byCustomField && indexes.byCustomField) {\n for (const field of indexConfig.byCustomField) {\n if (field in element) {\n const fieldValue = (element as any)[field]\n if (\n fieldValue !== undefined &&\n (typeof fieldValue === \"string\" || typeof fieldValue === \"number\")\n ) {\n const fieldValueStr = String(fieldValue)\n const fieldMap = indexes.byCustomField.get(field)!\n const elementsWithFieldValue = fieldMap.get(fieldValueStr) || []\n elementsWithFieldValue.push(element)\n fieldMap.set(fieldValueStr, elementsWithFieldValue)\n }\n }\n }\n }\n }\n // Store internal state\n ;(soup as any)._internal_store_indexed = internalStore\n }\n\n const suIndexed = new Proxy(\n {},\n {\n get: (proxy_target: any, prop: string) => {\n if (prop === \"toArray\") {\n return () => {\n ;(soup as any).editCount = internalStore.editCount\n return soup\n }\n }\n if (prop === \"editCount\") {\n return internalStore.editCount\n }\n\n const component_type = prop\n\n return {\n get: (id: string) => {\n const indexConfig = options.indexConfig || {}\n\n // Use ID index if available\n if (indexConfig.byId && internalStore.indexes.byId) {\n return (\n (internalStore.indexes.byId.get(\n `${component_type}:${id}`,\n ) as Extract<\n AnyCircuitElement,\n { type: typeof component_type }\n >) || null\n )\n }\n\n // Use type index if available\n if (indexConfig.byType && internalStore.indexes.byType) {\n const elementsOfType =\n internalStore.indexes.byType.get(component_type) || []\n return (\n (elementsOfType.find(\n (e: any) => e[`${component_type}_id`] === id,\n ) as Extract<\n AnyCircuitElement,\n { type: typeof component_type }\n >) || null\n )\n }\n\n // Fallback to regular search\n return (\n (soup.find(\n (e: any) =>\n e.type === component_type && e[`${component_type}_id`] === id,\n ) as Extract<\n AnyCircuitElement,\n { type: typeof component_type }\n >) || null\n )\n },\n\n getUsing: (using: any) => {\n const indexConfig = options.indexConfig || {}\n const keys = Object.keys(using)\n\n if (keys.length !== 1) {\n throw new Error(\n \"getUsing requires exactly one key, e.g. { pcb_component_id }\",\n )\n }\n\n const join_key = keys[0] as string\n const join_type = join_key.replace(\"_id\", \"\")\n\n // Use relation index if available\n if (indexConfig.byRelation && internalStore.indexes.byRelation) {\n const relationMap = internalStore.indexes.byRelation.get(join_key)\n if (relationMap) {\n const relatedElements = relationMap.get(using[join_key]) || []\n const joiner = relatedElements.find((e) => e.type === join_type)\n\n if (!joiner) return null\n\n // Now find the element of component_type with matching ID\n const joinerId =\n joiner[`${component_type}_id` as keyof typeof joiner]\n\n if (indexConfig.byId && internalStore.indexes.byId) {\n return (\n (internalStore.indexes.byId.get(\n `${component_type}:${joinerId}`,\n ) as Extract<\n AnyCircuitElement,\n { type: typeof component_type }\n >) || null\n )\n }\n\n if (indexConfig.byType && internalStore.indexes.byType) {\n const elementsOfType =\n internalStore.indexes.byType.get(component_type) || []\n return (\n (elementsOfType.find(\n (e: any) => e[`${component_type}_id`] === joinerId,\n ) as Extract<\n AnyCircuitElement,\n { type: typeof component_type }\n >) || null\n )\n }\n\n return (\n (soup.find(\n (e: any) =>\n e.type === component_type &&\n e[`${component_type}_id`] === joinerId,\n ) as Extract<\n AnyCircuitElement,\n { type: typeof component_type }\n >) || null\n )\n }\n }\n\n // Fallback to regular approach\n const joiner: any = soup.find(\n (e: any) =>\n e.type === join_type && e[join_key] === using[join_key],\n )\n\n if (!joiner) return null\n\n return (\n (soup.find(\n (e: any) =>\n e.type === component_type &&\n e[`${component_type}_id`] === joiner[`${component_type}_id`],\n ) as Extract<\n AnyCircuitElement,\n { type: typeof component_type }\n >) || null\n )\n },\n\n getWhere: (where: any) => {\n const indexConfig = options.indexConfig || {}\n const keys = Object.keys(where)\n\n // If we're looking by a single property and it's indexed as a custom field\n if (\n keys.length === 1 &&\n indexConfig.byCustomField &&\n internalStore.indexes.byCustomField\n ) {\n const field = keys[0]\n const fieldMap = internalStore.indexes.byCustomField.get(field!)\n\n if (fieldMap) {\n const fieldValue = String(where[field!])\n const elementsWithFieldValue = fieldMap.get(fieldValue) || []\n\n return (\n (elementsWithFieldValue.find(\n (e: any) => e.type === component_type,\n ) as Extract<\n AnyCircuitElement,\n { type: typeof component_type }\n >) || null\n )\n }\n }\n\n // If we're looking by subcircuit_id and it's indexed\n if (\n \"subcircuit_id\" in where &&\n indexConfig.bySubcircuit &&\n internalStore.indexes.bySubcircuit\n ) {\n const subcircuitId = where.subcircuit_id\n const subcircuitElements =\n internalStore.indexes.bySubcircuit.get(subcircuitId) || []\n\n return (\n (subcircuitElements.find(\n (e: any) =>\n e.type === component_type &&\n keys.every((key) => e[key] === where[key]),\n ) as Extract<\n AnyCircuitElement,\n { type: typeof component_type }\n >) || null\n )\n }\n\n // Use type index if available to reduce search space\n if (indexConfig.byType && internalStore.indexes.byType) {\n const elementsOfType =\n internalStore.indexes.byType.get(component_type) || []\n\n return (\n (elementsOfType.find((e: any) =>\n keys.every((key) => e[key] === where[key]),\n ) as Extract<\n AnyCircuitElement,\n { type: typeof component_type }\n >) || null\n )\n }\n\n // Fallback to regular approach\n return (\n (soup.find(\n (e: any) =>\n e.type === component_type &&\n keys.every((key) => e[key] === where[key]),\n ) as Extract<\n AnyCircuitElement,\n { type: typeof component_type }\n >) || null\n )\n },\n\n list: (where?: any) => {\n const indexConfig = options.indexConfig || {}\n const keys = !where ? [] : Object.keys(where)\n\n // If no filters, just return all elements of this type using the type index\n if (\n keys.length === 0 &&\n indexConfig.byType &&\n internalStore.indexes.byType\n ) {\n return (internalStore.indexes.byType.get(component_type) ||\n []) as Extract<\n AnyCircuitElement,\n { type: typeof component_type }\n >[]\n }\n\n // If filtering by subcircuit_id and it's the only filter\n if (\n keys.length === 1 &&\n keys[0] === \"subcircuit_id\" &&\n indexConfig.bySubcircuit &&\n internalStore.indexes.bySubcircuit\n ) {\n const subcircuitId = where.subcircuit_id\n const subcircuitElements =\n internalStore.indexes.bySubcircuit.get(subcircuitId) || []\n\n return subcircuitElements.filter(\n (e: any) => e.type === component_type,\n ) as Extract<AnyCircuitElement, { type: typeof component_type }>[]\n }\n\n // Start with all elements of this type to reduce search space\n let elementsToFilter: AnyCircuitElement[]\n\n if (indexConfig.byType && internalStore.indexes.byType) {\n elementsToFilter =\n internalStore.indexes.byType.get(component_type) || []\n } else {\n elementsToFilter = soup.filter((e) => e.type === component_type)\n }\n\n // Apply remaining filters\n if (keys.length > 0) {\n return elementsToFilter.filter((e: any) =>\n keys.every((key) => e[key] === where[key]),\n ) as Extract<AnyCircuitElement, { type: typeof component_type }>[]\n }\n\n return elementsToFilter as Extract<\n AnyCircuitElement,\n { type: typeof component_type }\n >[]\n },\n\n insert: (elm: any) => {\n internalStore.counts[component_type] ??= -1\n internalStore.counts[component_type]++\n const index = internalStore.counts[component_type]\n const newElm = {\n type: component_type,\n [`${component_type}_id`]: `${component_type}_${index}`,\n ...elm,\n }\n\n if (options.validateInserts) {\n const parser =\n (Soup as any)[component_type] ?? Soup.any_soup_element\n parser.parse(newElm)\n }\n\n soup.push(newElm)\n internalStore.editCount++\n\n // Update indexes with the new element\n const indexConfig = options.indexConfig || {}\n\n // Update ID index\n if (indexConfig.byId && internalStore.indexes.byId) {\n const idKey = createIdKey(newElm)\n internalStore.indexes.byId.set(idKey, newElm)\n }\n\n // Update type index\n if (indexConfig.byType && internalStore.indexes.byType) {\n const elementsOfType =\n internalStore.indexes.byType.get(component_type) || []\n elementsOfType.push(newElm)\n internalStore.indexes.byType.set(component_type, elementsOfType)\n }\n\n // Update relation index\n if (indexConfig.byRelation && internalStore.indexes.byRelation) {\n const elementEntries = Object.entries(newElm)\n for (const [key, value] of elementEntries) {\n if (\n key.endsWith(\"_id\") &&\n key !== `${newElm.type}_id` &&\n typeof value === \"string\"\n ) {\n const relationTypeMap =\n internalStore.indexes.byRelation.get(key) || new Map()\n const relatedElements =\n relationTypeMap.get(value as string) || []\n relatedElements.push(newElm)\n relationTypeMap.set(value as string, relatedElements)\n internalStore.indexes.byRelation.set(key, relationTypeMap)\n }\n }\n }\n\n // Update subcircuit index\n if (\n indexConfig.bySubcircuit &&\n internalStore.indexes.bySubcircuit &&\n \"subcircuit_id\" in newElm\n ) {\n const subcircuitId = (newElm as any).subcircuit_id\n if (subcircuitId && typeof subcircuitId === \"string\") {\n const subcircuitElements =\n internalStore.indexes.bySubcircuit.get(subcircuitId) || []\n subcircuitElements.push(newElm)\n internalStore.indexes.bySubcircuit.set(\n subcircuitId,\n subcircuitElements,\n )\n }\n }\n\n // Update custom field indexes\n if (\n indexConfig.byCustomField &&\n internalStore.indexes.byCustomField\n ) {\n for (const field of indexConfig.byCustomField) {\n if (field in newElm) {\n const fieldValue = (newElm as any)[field]\n if (\n fieldValue !== undefined &&\n (typeof fieldValue === \"string\" ||\n typeof fieldValue === \"number\")\n ) {\n const fieldValueStr = String(fieldValue)\n const fieldMap =\n internalStore.indexes.byCustomField.get(field)!\n const elementsWithFieldValue =\n fieldMap.get(fieldValueStr) || []\n elementsWithFieldValue.push(newElm)\n fieldMap.set(fieldValueStr, elementsWithFieldValue)\n }\n }\n }\n }\n\n return newElm\n },\n\n delete: (id: string) => {\n const indexConfig = options.indexConfig || {}\n let elm: AnyCircuitElement | undefined\n\n // Find the element to delete\n if (indexConfig.byId && internalStore.indexes.byId) {\n elm = internalStore.indexes.byId.get(`${component_type}:${id}`)\n } else if (indexConfig.byType && internalStore.indexes.byType) {\n const elementsOfType =\n internalStore.indexes.byType.get(component_type) || []\n elm = elementsOfType.find(\n (e: any) => e[`${component_type}_id`] === id,\n )\n } else {\n elm = soup.find((e) => (e as any)[`${component_type}_id`] === id)\n }\n\n if (!elm) return\n\n // Remove from array\n const elmIndex = soup.indexOf(elm)\n if (elmIndex >= 0) {\n soup.splice(elmIndex, 1)\n internalStore.editCount++\n }\n\n // Remove from indexes\n if (indexConfig.byId && internalStore.indexes.byId) {\n const idKey = createIdKey(elm)\n internalStore.indexes.byId.delete(idKey)\n }\n\n if (indexConfig.byType && internalStore.indexes.byType) {\n const elementsOfType =\n internalStore.indexes.byType.get(component_type) || []\n const filteredElements = elementsOfType.filter(\n (e: any) => e[`${component_type}_id`] !== id,\n )\n internalStore.indexes.byType.set(component_type, filteredElements)\n }\n\n if (indexConfig.byRelation && internalStore.indexes.byRelation) {\n // This is more complex - we need to find and remove from all relation maps\n // where this element appears\n for (const [\n relationKey,\n relationMap,\n ] of internalStore.indexes.byRelation.entries()) {\n for (const [relationValue, elements] of relationMap.entries()) {\n const updatedElements = elements.filter((e) => e !== elm)\n\n if (updatedElements.length === 0) {\n relationMap.delete(relationValue)\n } else {\n relationMap.set(relationValue, updatedElements)\n }\n }\n }\n }\n\n if (\n indexConfig.bySubcircuit &&\n internalStore.indexes.bySubcircuit &&\n \"subcircuit_id\" in elm\n ) {\n const subcircuitId = (elm as any).subcircuit_id\n if (subcircuitId) {\n const subcircuitElements =\n internalStore.indexes.bySubcircuit.get(subcircuitId) || []\n const updatedElements = subcircuitElements.filter(\n (e) => e !== elm,\n )\n\n if (updatedElements.length === 0) {\n internalStore.indexes.bySubcircuit.delete(subcircuitId)\n } else {\n internalStore.indexes.bySubcircuit.set(\n subcircuitId,\n updatedElements,\n )\n }\n }\n }\n\n if (\n indexConfig.byCustomField &&\n internalStore.indexes.byCustomField\n ) {\n for (const fieldMap of internalStore.indexes.byCustomField.values()) {\n for (const [fieldValue, elements] of fieldMap.entries()) {\n const updatedElements = elements.filter((e) => e !== elm)\n\n if (updatedElements.length === 0) {\n fieldMap.delete(fieldValue)\n } else {\n fieldMap.set(fieldValue, updatedElements)\n }\n }\n }\n }\n },\n\n update: (id: string, newProps: any) => {\n const indexConfig = options.indexConfig || {}\n let elm: AnyCircuitElement | undefined | null\n\n // Find the element to update\n if (indexConfig.byId && internalStore.indexes.byId) {\n elm = internalStore.indexes.byId.get(`${component_type}:${id}`)\n } else if (indexConfig.byType && internalStore.indexes.byType) {\n const elementsOfType =\n internalStore.indexes.byType.get(component_type) || []\n elm = elementsOfType.find(\n (e: any) => e[`${component_type}_id`] === id,\n )\n } else {\n elm = soup.find(\n (e) =>\n e.type === component_type &&\n (e as any)[`${component_type}_id`] === id,\n )\n }\n\n if (!elm) return null\n\n // Need to remove from indexes before updating\n if (indexConfig.byRelation && internalStore.indexes.byRelation) {\n // Remove from relation indexes\n const elementEntries = Object.entries(elm)\n for (const [key, value] of elementEntries) {\n if (\n key.endsWith(\"_id\") &&\n key !== `${elm.type}_id` &&\n typeof value === \"string\"\n ) {\n if (key in newProps && newProps[key] !== value) {\n const relationTypeMap =\n internalStore.indexes.byRelation.get(key)\n if (relationTypeMap) {\n const relatedElements =\n relationTypeMap.get(value as string) || []\n const updatedElements = relatedElements.filter(\n (e) => e !== elm,\n )\n\n if (updatedElements.length === 0) {\n relationTypeMap.delete(value as string)\n } else {\n relationTypeMap.set(value as string, updatedElements)\n }\n }\n }\n }\n }\n }\n\n if (\n indexConfig.bySubcircuit &&\n internalStore.indexes.bySubcircuit &&\n \"subcircuit_id\" in elm &&\n \"subcircuit_id\" in newProps\n ) {\n const oldSubcircuitId = (elm as any).subcircuit_id\n const newSubcircuitId = newProps.subcircuit_id\n\n if (oldSubcircuitId !== newSubcircuitId) {\n // Remove from old subcircuit index\n const subcircuitElements =\n internalStore.indexes.bySubcircuit.get(oldSubcircuitId) || []\n const updatedElements = subcircuitElements.filter(\n (e) => e !== elm,\n )\n\n if (updatedElements.length === 0) {\n internalStore.indexes.bySubcircuit.delete(oldSubcircuitId)\n } else {\n internalStore.indexes.bySubcircuit.set(\n oldSubcircuitId,\n updatedElements,\n )\n }\n }\n }\n\n if (\n indexConfig.byCustomField &&\n internalStore.indexes.byCustomField\n ) {\n for (const field of indexConfig.byCustomField) {\n if (\n field in elm &&\n field in newProps &&\n (elm as any)[field] !== newProps[field]\n ) {\n const fieldMap =\n internalStore.indexes.byCustomField.get(field)\n if (fieldMap) {\n const oldValue = String((elm as any)[field])\n const elements = fieldMap.get(oldValue) || []\n const updatedElements = elements.filter((e) => e !== elm)\n\n if (updatedElements.length === 0) {\n fieldMap.delete(oldValue)\n } else {\n fieldMap.set(oldValue, updatedElements)\n }\n }\n }\n }\n }\n\n // Update the element\n Object.assign(elm, newProps)\n internalStore.editCount++\n\n // Add to indexes with updated values\n if (indexConfig.byRelation && internalStore.indexes.byRelation) {\n const elementEntries = Object.entries(elm)\n for (const [key, value] of elementEntries) {\n if (\n key.endsWith(\"_id\") &&\n key !== `${elm.type}_id` &&\n typeof value === \"string\"\n ) {\n if (key in newProps) {\n const relationTypeMap: any =\n internalStore.indexes.byRelation.get(key) || new Map()\n const relatedElements: any =\n relationTypeMap.get(value as string) || []\n\n if (!relatedElements.includes(elm)) {\n relatedElements.push(elm)\n relationTypeMap.set(value as string, relatedElements)\n internalStore.indexes.byRelation.set(key, relationTypeMap)\n }\n }\n }\n }\n }\n\n if (\n indexConfig.bySubcircuit &&\n internalStore.indexes.bySubcircuit &&\n \"subcircuit_id\" in elm &&\n \"subcircuit_id\" in newProps\n ) {\n const subcircuitId = (elm as any).subcircuit_id\n if (subcircuitId && typeof subcircuitId === \"string\") {\n const subcircuitElements =\n internalStore.indexes.bySubcircuit.get(subcircuitId) || []\n\n if (!subcircuitElements.includes(elm)) {\n subcircuitElements.push(elm)\n internalStore.indexes.bySubcircuit.set(\n subcircuitId,\n subcircuitElements,\n )\n }\n }\n }\n\n if (\n indexConfig.byCustomField &&\n internalStore.indexes.byCustomField\n ) {\n for (const field of indexConfig.byCustomField) {\n if (field in elm && field in newProps) {\n const fieldValue: any = (elm as any)[field]\n if (\n fieldValue !== undefined &&\n (typeof fieldValue === \"string\" ||\n typeof fieldValue === \"number\")\n ) {\n const fieldValueStr = String(fieldValue)\n const fieldMap =\n internalStore.indexes.byCustomField.get(field)!\n const elementsWithFieldValue =\n fieldMap.get(fieldValueStr) || []\n\n if (!elementsWithFieldValue.includes(elm)) {\n elementsWithFieldValue.push(elm)\n fieldMap.set(fieldValueStr, elementsWithFieldValue)\n }\n }\n }\n }\n }\n\n return elm as Extract<\n AnyCircuitElement,\n { type: typeof component_type }\n >\n },\n\n select: (selector: string) => {\n // Selection by selector is specialized enough that we don't use indexes here\n // TODO when applySelector is isolated we can use it, until then we\n // do a poor man's selector implementation for two common cases\n if (component_type === \"source_component\") {\n return (\n (soup.find(\n (e) =>\n e.type === \"source_component\" &&\n e.name === selector.replace(/\\./g, \"\"),\n ) as Extract<\n AnyCircuitElement,\n { type: typeof component_type }\n >) || null\n )\n } else if (\n component_type === \"pcb_port\" ||\n component_type === \"source_port\" ||\n component_type === \"schematic_port\"\n ) {\n const [component_name, port_selector] = selector\n .replace(/\\./g, \"\")\n .split(/[\\s\\>]+/)\n const source_component = soup.find(\n (e) =>\n e.type === \"source_component\" && e.name === component_name,\n ) as SourceComponentBase\n if (!source_component) return null\n const source_port = soup.find(\n (e) =>\n e.type === \"source_port\" &&\n e.source_component_id ===\n source_component.source_component_id &&\n (e.name === port_selector ||\n (e.port_hints ?? []).includes(port_selector!)),\n ) as SourcePort\n if (!source_port) return null\n if (component_type === \"source_port\")\n return source_port as Extract<\n AnyCircuitElement,\n { type: typeof component_type }\n >\n\n if (component_type === \"pcb_port\") {\n return (\n (soup.find(\n (e) =>\n e.type === \"pcb_port\" &&\n e.source_port_id === source_port.source_port_id,\n ) as Extract<\n AnyCircuitElement,\n { type: typeof component_type }\n >) || null\n )\n } else if (component_type === \"schematic_port\") {\n return (\n (soup.find(\n (e) =>\n e.type === \"schematic_port\" &&\n e.source_port_id === source_port.source_port_id,\n ) as Extract<\n AnyCircuitElement,\n { type: typeof component_type }\n >) || null\n )\n }\n }\n\n return null\n },\n }\n },\n },\n )\n\n return suIndexed\n}) as any\n\ncjuIndexed.unparsed = cjuIndexed as any\n\nexport default cjuIndexed\n","import type { AnyCircuitElement } from \"circuit-json\"\nimport { type Matrix, applyToPoint, decomposeTSR } from \"transformation-matrix\"\nimport {\n directionToVec,\n rotateDirection,\n vecToDirection,\n} from \"./direction-to-vec\"\n\nexport const transformSchematicElement = (\n elm: AnyCircuitElement,\n matrix: Matrix,\n) => {\n if (elm.type === \"schematic_component\") {\n // TODO handle rotation\n elm.center = applyToPoint(matrix, elm.center)\n } else if (elm.type === \"schematic_port\") {\n elm.center = applyToPoint(matrix, elm.center)\n\n if (elm.facing_direction) {\n elm.facing_direction = rotateDirection(\n elm.facing_direction,\n -(Math.atan2(matrix.b, matrix.a) / Math.PI) * 2,\n )\n }\n } else if (elm.type === \"schematic_text\") {\n elm.position = applyToPoint(matrix, elm.position)\n // } else if (elm.type === \"schematic_group\") {\n // elm.center = applyToPoint(matrix, elm.center)\n } else if (elm.type === \"schematic_trace\") {\n } else if (elm.type === \"schematic_box\") {\n const { x, y } = applyToPoint(matrix, { x: elm.x, y: elm.y })\n elm.x = x\n elm.y = y\n } else if (elm.type === \"schematic_line\") {\n const { x: x1, y: y1 } = applyToPoint(matrix, { x: elm.x1, y: elm.y1 })\n const { x: x2, y: y2 } = applyToPoint(matrix, { x: elm.x2, y: elm.y2 })\n elm.x1 = x1\n elm.y1 = y1\n elm.x2 = x2\n elm.y2 = y2\n }\n return elm\n}\n\nexport const transformSchematicElements = (\n elms: AnyCircuitElement[],\n matrix: Matrix,\n) => {\n return elms.map((elm) => transformSchematicElement(elm, matrix))\n}\n\nexport const transformPCBElement = (elm: AnyCircuitElement, matrix: Matrix) => {\n if (\n elm.type === \"pcb_plated_hole\" ||\n elm.type === \"pcb_hole\" ||\n elm.type === \"pcb_via\" ||\n elm.type === \"pcb_smtpad\" ||\n elm.type === \"pcb_port\"\n ) {\n const { x, y } = applyToPoint(matrix, {\n x: Number((elm as any).x),\n y: Number((elm as any).y),\n })\n ;(elm as any).x = x\n ;(elm as any).y = y\n } else if (elm.type === \"pcb_keepout\" || elm.type === \"pcb_board\") {\n // TODO adjust size/rotation\n elm.center = applyToPoint(matrix, elm.center)\n } else if (\n elm.type === \"pcb_silkscreen_text\" ||\n elm.type === \"pcb_fabrication_note_text\"\n ) {\n elm.anchor_position = applyToPoint(matrix, elm.anchor_position)\n } else if (\n elm.type === \"pcb_silkscreen_circle\" ||\n elm.type === \"pcb_silkscreen_rect\" ||\n elm.type === \"pcb_component\"\n ) {\n elm.center = applyToPoint(matrix, elm.center)\n } else if (\n elm.type === \"pcb_silkscreen_path\" ||\n elm.type === \"pcb_trace\" ||\n elm.type === \"pcb_fabrication_note_path\"\n ) {\n elm.route = elm.route.map((rp) => {\n const tp = applyToPoint(matrix, rp) as { x: number; y: number }\n rp.x = tp.x\n rp.y = tp.y\n return rp\n })\n } else if (elm.type === \"pcb_silkscreen_line\") {\n const p1 = { x: elm.x1, y: elm.y1 }\n const p2 = { x: elm.x2, y: elm.y2 }\n const p1t = applyToPoint(matrix, p1)\n const p2t = applyToPoint(matrix, p2)\n elm.x1 = p1t.x\n elm.y1 = p1t.y\n elm.x2 = p2t.x\n elm.y2 = p2t.y\n } else if (elm.type === \"cad_component\") {\n const newPos = applyToPoint(matrix, {\n x: elm.position.x,\n y: elm.position.y,\n })\n elm.position.x = newPos.x\n elm.position.y = newPos.y\n }\n return elm\n}\n\nexport const transformPCBElements = (\n elms: AnyCircuitElement[],\n matrix: Matrix,\n) => {\n const tsr = decomposeTSR(matrix)\n const flipPadWidthHeight =\n Math.round(tsr.rotation.angle / (Math.PI / 2)) % 2 === 1\n let transformedElms = elms.map((elm) => transformPCBElement(elm, matrix))\n if (flipPadWidthHeight) {\n transformedElms = transformedElms.map((elm) => {\n if (elm.type === \"pcb_smtpad\" && elm.shape === \"rect\") {\n ;[elm.width, elm.height] = [elm.height, elm.width]\n }\n return elm\n })\n }\n return transformedElms\n}\n","export const directionToVec = (direction: \"up\" | \"down\" | \"left\" | \"right\") => {\n if (direction === \"up\") return { x: 0, y: 1 }\n else if (direction === \"down\") return { x: 0, y: -1 }\n else if (direction === \"left\") return { x: -1, y: 0 }\n else if (direction === \"right\") return { x: 1, y: 0 }\n else throw new Error(\"Invalid direction\")\n}\n\nexport const vecToDirection = ({ x, y }: { x: number; y: number }) => {\n if (x > y) y = 0\n if (y > x) x = 0\n if (x > 0 && y === 0) return \"right\"\n else if (x < 0 && y === 0) return \"left\"\n else if (x === 0 && y > 0) return \"up\"\n else if (x === 0 && y < 0) return \"down\"\n else throw new Error(`Invalid vector for direction conversion (${x}, ${y})`)\n}\n\nexport const rotateClockwise = (\n direction: \"up\" | \"down\" | \"left\" | \"right\"\n) => {\n if (direction === \"up\") return \"right\"\n else if (direction === \"right\") return \"down\"\n else if (direction === \"down\") return \"left\"\n else if (direction === \"left\") return \"up\"\n throw new Error(`Invalid direction: ${direction}`)\n}\n\nexport const rotateCounterClockwise = (\n direction: \"up\" | \"down\" | \"left\" | \"right\"\n) => {\n if (direction === \"up\") return \"left\"\n else if (direction === \"left\") return \"down\"\n else if (direction === \"down\") return \"right\"\n else if (direction === \"right\") return \"up\"\n throw new Error(`Invalid direction: ${direction}`)\n}\n\nexport const rotateDirection = (\n direction: \"up\" | \"down\" | \"left\" | \"right\",\n num90DegreeClockwiseTurns: number\n) => {\n while (num90DegreeClockwiseTurns > 0) {\n direction = rotateClockwise(direction)\n num90DegreeClockwiseTurns--\n }\n while (num90DegreeClockwiseTurns < 0) {\n direction = rotateCounterClockwise(direction)\n num90DegreeClockwiseTurns++\n }\n return direction\n}\n\nexport const oppositeDirection = (\n direction: \"up\" | \"down\" | \"left\" | \"right\"\n) => {\n if (direction === \"up\") return \"down\"\n else if (direction === \"down\") return \"up\"\n else if (direction === \"left\") return \"right\"\n else if (direction === \"right\") return \"left\"\n throw new Error(`Invalid direction: ${direction}`)\n}\n\nexport const oppositeSide = (\n sideOrDir: \"up\" | \"down\" | \"top\" | \"bottom\" | \"left\" | \"right\"\n) => {\n if (sideOrDir === \"top\" || sideOrDir === \"up\") return \"bottom\"\n else if (sideOrDir === \"bottom\" || sideOrDir === \"down\") return \"top\"\n else if (sideOrDir === \"left\") return \"right\"\n else if (sideOrDir === \"right\") return \"left\"\n throw new Error(`Invalid sideOrDir: ${sideOrDir}`)\n}\n","import * as parsel from \"parsel-js\"\nimport { convertAbbrToType } from \"./convert-abbreviation-to-soup-element-type\"\nimport type { AnyCircuitElement } from \"circuit-json\"\n\nconst filterByType = (\n elements: AnyCircuitElement[],\n type: string\n): AnyCircuitElement[] => {\n type = convertAbbrToType(type)\n return elements.filter(\n (elm) => (\"ftype\" in elm && elm.ftype === type) || elm.type === type\n )\n}\n\n/**\n * Filter elements to match the selector, e.g. to access the left port of a\n * resistor you can do \".R1 > port.left\"\n */\nexport const applySelector = (\n elements: AnyCircuitElement[],\n selectorRaw: string\n): AnyCircuitElement[] => {\n const selectorAST = parsel.parse(selectorRaw)\n return applySelectorAST(elements, selectorAST!)\n}\n\nconst doesElmMatchClassName = (elm: AnyCircuitElement, className: string) =>\n (\"name\" in elm && elm.name === className) ||\n (\"port_hints\" in elm && elm.port_hints?.includes(className))\n\nexport const applySelectorAST = (\n elements: AnyCircuitElement[],\n selectorAST: parsel.AST\n): AnyCircuitElement[] => {\n switch (selectorAST.type) {\n case \"complex\": {\n switch (selectorAST.combinator) {\n case \" \": // TODO technically should do a deep search\n case \">\": {\n const { left, right } = selectorAST\n if (left.type === \"class\" || left.type === \"type\") {\n // TODO should also check if content matches any element tags\n let matchElms: AnyCircuitElement[]\n if (left.type === \"class\") {\n matchElms = elements.filter((elm) =>\n doesElmMatchClassName(elm, left.name)\n )\n } else if (left.type === \"type\") {\n matchElms = filterByType(elements, left.name)\n } else {\n matchElms = []\n }\n\n const childrenOfMatchingElms = matchElms.flatMap((matchElm) =>\n elements.filter(\n (elm: any) =>\n elm[`${matchElm.type}_id`] ===\n (matchElm as any)[`${matchElm.type}_id`] && elm !== matchElm\n )\n )\n return applySelectorAST(childrenOfMatchingElms, right)\n } else {\n throw new Error(`unsupported selector type \"${left.type}\" `)\n }\n }\n default: {\n throw new Error(\n `Couldn't apply selector AST for complex combinator \"${selectorAST.combinator}\"`\n )\n }\n }\n return []\n }\n case \"compound\": {\n const conditionsToMatch = selectorAST.list.map((part) => {\n switch (part.type) {\n case \"class\": {\n return (elm: any) => doesElmMatchClassName(elm, part.name)\n }\n case \"type\": {\n const name = convertAbbrToType(part.name)\n return (elm: any) => elm.type === name\n }\n }\n })\n\n return elements.filter((elm) =>\n conditionsToMatch.every((condFn) => condFn?.(elm))\n )\n }\n case \"type\": {\n return filterByType(elements, selectorAST.name) as AnyCircuitElement[]\n }\n case \"class\": {\n return elements.filter((elm) =>\n doesElmMatchClassName(elm, selectorAST.name)\n )\n }\n default: {\n throw new Error(\n `Couldn't apply selector AST for type: \"${\n selectorAST.type\n }\" ${JSON.stringify(selectorAST, null, \" \")}`\n )\n }\n }\n}\n","export const convertAbbrToType = (abbr: string): string => {\n switch (abbr) {\n case \"port\":\n return \"source_port\"\n case \"net\":\n return \"source_net\"\n case \"power\":\n return \"simple_power_source\"\n }\n return abbr\n}\n","import type { AnyCircuitElement } from \"circuit-json\"\n\nexport const getElementId = (elm: AnyCircuitElement): string => {\n const type = elm.type\n const id = (elm as any)[`${type}_id`]\n return id\n}\n","import type { AnyCircuitElement } from \"circuit-json\"\nimport { getElementId } from \"./get-element-id\"\n\nexport const getElementById = (\n soup: AnyCircuitElement[],\n id: string,\n): AnyCircuitElement | null => {\n return soup.find((elm) => getElementId(elm) === id) ?? null\n}\n","import type { AnyCircuitElement } from \"circuit-json\"\nimport { cju } from \"../cju\"\n\nexport function getReadableNameForPcbTrace(\n soup: AnyCircuitElement[],\n pcb_trace_id: string,\n) {\n // Find the pcb_trace object\n const pcbTrace = cju(soup).pcb_trace.get(pcb_trace_id)\n\n if (!pcbTrace) {\n return `trace[${pcb_trace_id}]`\n }\n\n // Get the connected ports\n const connectedPcbPortIds: string[] = pcbTrace.route\n .flatMap((point: any) => [point.start_pcb_port_id, point.end_pcb_port_id])\n .filter(Boolean)\n\n if (connectedPcbPortIds.length === 0) {\n return `trace[${pcb_trace_id}]`\n }\n\n // Function to get component name and port hint\n function getComponentAndPortInfo(pcb_port_id: string) {\n const pcbPort = cju(soup).pcb_port.get(pcb_port_id)\n if (!pcbPort) return null\n\n const pcbComponent = cju(soup).pcb_component.get(pcbPort.pcb_component_id)\n if (!pcbComponent) return null\n const sourceComponent = cju(soup).source_component.get(\n pcbComponent.source_component_id,\n )\n if (!sourceComponent) return null\n\n const sourcePort = cju(soup).source_port.get(pcbPort.source_port_id)\n const portHint = sourcePort?.port_hints ? sourcePort.port_hints[1] : \"\"\n\n return {\n componentName: sourceComponent.name,\n portHint: portHint,\n }\n }\n\n // Generate the readable selector\n const selectorParts = connectedPcbPortIds.map((portId) => {\n const info = getComponentAndPortInfo(portId)\n if (info) {\n return `.${info.componentName} > port.${info.portHint}`\n }\n return `port[${portId}]`\n })\n\n return `trace[${selectorParts.join(\", \")}]`\n}\n","import type { AnyCircuitElement } from \"circuit-json\"\nimport { cju } from \"../cju\"\n\nexport const getReadableNameForPcbPort = (\n soup: AnyCircuitElement[],\n pcb_port_id: string,\n): string => {\n const pcbPort = cju(soup).pcb_port.get(pcb_port_id)\n if (!pcbPort) {\n return `pcb_port[#${pcb_port_id}]`\n }\n\n // Get the component information\n const pcbComponent = cju(soup).pcb_component.get(pcbPort?.pcb_component_id)\n\n if (!pcbComponent) {\n return `pcb_port[#${pcb_port_id}]`\n }\n\n // Get the source component information\n const sourceComponent = cju(soup).source_component.get(\n pcbComponent.source_component_id,\n )\n\n if (!sourceComponent) {\n return `pcb_port[#${pcb_port_id}]`\n }\n\n // Get the source port information\n const sourcePort = cju(soup).source_port.get(pcbPort.source_port_id)\n\n if (!sourcePort) {\n return `pcb_port[#${pcb_port_id}]`\n }\n\n // Determine the pad number or hint\n let padIdentifier: string\n if (sourcePort?.port_hints && sourcePort.port_hints.length > 0) {\n padIdentifier = sourcePort.port_hints[0]!\n } else if (sourcePort.port_hints && sourcePort.port_hints.length > 0) {\n padIdentifier = sourcePort.port_hints[0]!\n } else {\n padIdentifier = pcb_port_id\n }\n\n return `pcb_port[.${sourceComponent.name} > .${padIdentifier}]`\n}\n","import type { AnyCircuitElement } from \"circuit-json\"\nimport { cju } from \"../cju\"\nimport { getReadableNameForPcbPort } from \"./get-readable-name-for-pcb-port\"\n\nexport function getReadableNameForPcbSmtpad(\n soup: AnyCircuitElement[],\n pcb_smtpad_id: string,\n): string {\n // Find the pcb_smtpad object\n const pcbSmtpad = cju(soup).pcb_smtpad.get(pcb_smtpad_id)\n\n if (!pcbSmtpad || !pcbSmtpad.pcb_port_id) {\n return `smtpad[${pcb_smtpad_id}]`\n }\n\n return getReadableNameForPcbPort(soup, pcbSmtpad.pcb_port_id)\n}\n","import type { AnyCircuitElement } from \"circuit-json\"\nimport { getReadableNameForPcbTrace } from \"./get-readable-name-for-pcb-trace\"\nimport { getReadableNameForPcbSmtpad } from \"./get-readable-name-for-pcb-smtpad\"\nimport { getReadableNameForPcbPort } from \"./get-readable-name-for-pcb-port\"\nimport { getElementById } from \"lib/get-element-by-id\"\nimport { getElementId } from \"lib/get-element-id\"\n\nexport const getReadableNameForElement = (\n soup: AnyCircuitElement[],\n elm: AnyCircuitElement | string,\n): string => {\n if (typeof elm === \"string\") {\n const elmObj = getElementById(soup, elm)\n if (!elmObj) `unknown (could not find element with id ${elm})`\n return getReadableNameForElement(soup, elmObj as any)\n }\n switch (elm.type) {\n case \"pcb_port\":\n return getReadableNameForPcbPort(soup, elm.pcb_port_id)\n case \"pcb_smtpad\":\n return getReadableNameForPcbSmtpad(soup, elm.pcb_smtpad_id)\n case \"pcb_trace\":\n return getReadableNameForPcbTrace(soup, elm.pcb_trace_id)\n case \"source_component\":\n return `source_component[${elm.name}]`\n default:\n return `${elm.type}[#${getElementId(elm)}]`\n }\n}\n\nexport {\n getReadableNameForPcbPort,\n getReadableNameForPcbSmtpad,\n getReadableNameForPcbTrace,\n}\n","import type { AnyCircuitElement } from \"circuit-json\"\n\nexport const getBoundsOfPcbElements = (\n elements: AnyCircuitElement[],\n): { minX: number; minY: number; maxX: number; maxY: number } => {\n let minX = Number.POSITIVE_INFINITY\n let minY = Number.POSITIVE_INFINITY\n let maxX = Number.NEGATIVE_INFINITY\n let maxY = Number.NEGATIVE_INFINITY\n\n for (const elm of elements) {\n if (!elm.type.startsWith(\"pcb_\")) continue\n\n let centerX: number | undefined\n let centerY: number | undefined\n\n let width: number | undefined\n let height: number | undefined\n\n if (\"x\" in elm && \"y\" in elm) {\n centerX = Number((elm as any).x)\n centerY = Number((elm as any).y)\n }\n\n if (\"outer_diameter\" in elm) {\n width = Number((elm as any).outer_diameter)\n height = Number((elm as any).outer_diameter)\n }\n\n if (\"width\" in elm) {\n width = Number((elm as any).width)\n }\n\n if (\"height\" in elm) {\n height = Number((elm as any).height)\n }\n\n if (\"center\" in elm) {\n // @ts-ignore\n centerX = elm.center.x\n // @ts-ignore\n centerY = elm.center.y\n }\n\n if (centerX !== undefined && centerY !== undefined) {\n minX = Math.min(minX, centerX)\n minY = Math.min(minY, centerY)\n maxX = Math.max(maxX, centerX)\n maxY = Math.max(maxY, centerY)\n\n if (width !== undefined && height !== undefined) {\n minX = Math.min(minX, centerX - width / 2)\n minY = Math.min(minY, centerY - height / 2)\n maxX = Math.max(maxX, centerX + width / 2)\n maxY = Math.max(maxY, centerY + height / 2)\n }\n\n if (\"radius\" in elm) {\n minX = Math.min(minX, centerX - elm.radius)\n minY = Math.min(minY, centerY - elm.radius)\n maxX = Math.max(maxX, centerX + elm.radius)\n maxY = Math.max(maxY, centerY + elm.radius)\n }\n } else if (elm.type === \"pcb_trace\") {\n for (const point of elm.route) {\n // TODO add trace thickness support\n minX = Math.min(minX, point.x)\n minY = Math.min(minY, point.y)\n maxX = Math.max(maxX, point.x)\n maxY = Math.max(maxY, point.y)\n }\n }\n }\n\n return { minX, minY, maxX, maxY }\n}\n","export function stringHash(str: string) {\n let hash = 0\n if (str.length == 0) return hash\n for (var i = 0; i < str.length; i++) {\n var char = str.charCodeAt(i)\n hash = (hash << 5) - hash + char\n hash = hash & hash // Convert to 32bit integer\n }\n return Math.abs(hash)\n}\n","import { stringHash } from \"./string-hash\"\n\nexport type LayoutDebugObject = {\n x: number\n y: number\n width: number\n height: number\n bg_color: string\n title: string\n content: Object\n secondary?: boolean\n}\n\n/**\n * Vendored from \"nice-color-palettes\" package\n */\nconst nice_color_palettes = [\n [\"#69d2e7\", \"#a7dbd8\", \"#e0e4cc\", \"#f38630\", \"#fa6900\"],\n [\"#fe4365\", \"#fc9d9a\", \"#f9cdad\", \"#c8c8a9\", \"#83af9b\"],\n [\"#ecd078\", \"#d95b43\", \"#c02942\", \"#542437\", \"#53777a\"],\n [\"#556270\", \"#4ecdc4\", \"#c7f464\", \"#ff6b6b\", \"#c44d58\"],\n [\"#774f38\", \"#e08e79\", \"#f1d4af\", \"#ece5ce\", \"#c5e0dc\"],\n [\"#e8ddcb\", \"#cdb380\", \"#036564\", \"#033649\", \"#031634\"],\n [\"#490a3d\", \"#bd1550\", \"#e97f02\", \"#f8ca00\", \"#8a9b0f\"],\n [\"#594f4f\", \"#547980\", \"#45ada8\", \"#9de0ad\", \"#e5fcc2\"],\n [\"#00a0b0\", \"#6a4a3c\", \"#cc333f\", \"#eb6841\", \"#edc951\"],\n [\"#e94e77\", \"#d68189\", \"#c6a49a\", \"#c6e5d9\", \"#f4ead5\"],\n [\"#3fb8af\", \"#7fc7af\", \"#dad8a7\", \"#ff9e9d\", \"#ff3d7f\"],\n [\"#d9ceb2\", \"#948c75\", \"#d5ded9\", \"#7a6a53\", \"#99b2b7\"],\n [\"#ffffff\", \"#cbe86b\", \"#f2e9e1\", \"#1c140d\", \"#cbe86b\"],\n [\"#efffcd\", \"#dce9be\", \"#555152\", \"#2e2633\", \"#99173c\"],\n [\"#343838\", \"#005f6b\", \"#008c9e\", \"#00b4cc\", \"#00dffc\"],\n [\"#413e4a\", \"#73626e\", \"#b38184\", \"#f0b49e\", \"#f7e4be\"],\n [\"#ff4e50\", \"#fc913a\", \"#f9d423\", \"#ede574\", \"#e1f5c4\"],\n [\"#99b898\", \"#fecea8\", \"#ff847c\", \"#e84a5f\", \"#2a363b\"],\n [\"#655643\", \"#80bca3\", \"#f6f7bd\", \"#e6ac27\", \"#bf4d28\"],\n [\"#00a8c6\", \"#40c0cb\", \"#f9f2e7\", \"#aee239\", \"#8fbe00\"],\n [\"#351330\", \"#424254\", \"#64908a\", \"#e8caa4\", \"#cc2a41\"],\n [\"#554236\", \"#f77825\", \"#d3ce3d\", \"#f1efa5\", \"#60b99a\"],\n [\"#5d4157\", \"#838689\", \"#a8caba\", \"#cad7b2\", \"#ebe3aa\"],\n [\"#8c2318\", \"#5e8c6a\", \"#88a65e\", \"#bfb35a\", \"#f2c45a\"],\n [\"#fad089\", \"#ff9c5b\", \"#f5634a\", \"#ed303c\", \"#3b8183\"],\n [\"#ff4242\", \"#f4fad2\", \"#d4ee5e\", \"#e1edb9\", \"#f0f2eb\"],\n [\"#f8b195\", \"#f67280\", \"#c06c84\", \"#6c5b7b\", \"#355c7d\"],\n [\"#d1e751\", \"#ffffff\", \"#000000\", \"#4dbce9\", \"#26ade4\"],\n [\"#1b676b\", \"#519548\", \"#88c425\", \"#bef202\", \"#eafde6\"],\n [\"#5e412f\", \"#fcebb6\", \"#78c0a8\", \"#f07818\", \"#f0a830\"],\n [\"#bcbdac\", \"#cfbe27\", \"#f27435\", \"#f02475\", \"#3b2d38\"],\n [\"#452632\", \"#91204d\", \"#e4844a\", \"#e8bf56\", \"#e2f7ce\"],\n [\"#eee6ab\", \"#c5bc8e\", \"#696758\", \"#45484b\", \"#36393b\"],\n [\"#f0d8a8\", \"#3d1c00\", \"#86b8b1\", \"#f2d694\", \"#fa2a00\"],\n [\"#2a044a\", \"#0b2e59\", \"#0d6759\", \"#7ab317\", \"#a0c55f\"],\n [\"#f04155\", \"#ff823a\", \"#f2f26f\", \"#fff7bd\", \"#95cfb7\"],\n [\"#b9d7d9\", \"#668284\", \"#2a2829\", \"#493736\", \"#7b3b3b\"],\n [\"#bbbb88\", \"#ccc68d\", \"#eedd99\", \"#eec290\", \"#eeaa88\"],\n [\"#b3cc57\", \"#ecf081\", \"#ffbe40\", \"#ef746f\", \"#ab3e5b\"],\n [\"#a3a948\", \"#edb92e\", \"#f85931\", \"#ce1836\", \"#009989\"],\n [\"#300030\", \"#480048\", \"#601848\", \"#c04848\", \"#f07241\"],\n [\"#67917a\", \"#170409\", \"#b8af03\", \"#ccbf82\", \"#e33258\"],\n [\"#aab3ab\", \"#c4cbb7\", \"#ebefc9\", \"#eee0b7\", \"#e8caaf\"],\n [\"#e8d5b7\", \"#0e2430\", \"#fc3a51\", \"#f5b349\", \"#e8d5b9\"],\n [\"#ab526b\", \"#bca297\", \"#c5ceae\", \"#f0e2a4\", \"#f4ebc3\"],\n [\"#607848\", \"#789048\", \"#c0d860\", \"#f0f0d8\", \"#604848\"],\n [\"#b6d8c0\", \"#c8d9bf\", \"#dadabd\", \"#ecdbbc\", \"#fedcba\"],\n [\"#a8e6ce\", \"#dcedc2\", \"#ffd3b5\", \"#ffaaa6\", \"#ff8c94\"],\n [\"#3e4147\", \"#fffedf\", \"#dfba69\", \"#5a2e2e\", \"#2a2c31\"],\n [\"#fc354c\", \"#29221f\", \"#13747d\", \"#0abfbc\", \"#fcf7c5\"],\n [\"#cc0c39\", \"#e6781e\", \"#c8cf02\", \"#f8fcc1\", \"#1693a7\"],\n [\"#1c2130\", \"#028f76\", \"#b3e099\", \"#ffeaad\", \"#d14334\"],\n [\"#a7c5bd\", \"#e5ddcb\", \"#eb7b59\", \"#cf4647\", \"#524656\"],\n [\"#dad6ca\", \"#1bb0ce\", \"#4f8699\", \"#6a5e72\", \"#563444\"],\n [\"#5c323e\", \"#a82743\", \"#e15e32\", \"#c0d23e\", \"#e5f04c\"],\n [\"#edebe6\", \"#d6e1c7\", \"#94c7b6\", \"#403b33\", \"#d3643b\"],\n [\"#fdf1cc\", \"#c6d6b8\", \"#987f69\", \"#e3ad40\", \"#fcd036\"],\n [\"#230f2b\", \"#f21d41\", \"#ebebbc\", \"#bce3c5\", \"#82b3ae\"],\n [\"#b9d3b0\", \"#81bda4\", \"#b28774\", \"#f88f79\", \"#f6aa93\"],\n [\"#3a111c\", \"#574951\", \"#83988e\", \"#bcdea5\", \"#e6f9bc\"],\n [\"#5e3929\", \"#cd8c52\", \"#b7d1a3\", \"#dee8be\", \"#fcf7d3\"],\n [\"#1c0113\", \"#6b0103\", \"#a30006\", \"#c21a01\", \"#f03c02\"],\n [\"#000000\", \"#9f111b\", \"#b11623\", \"#292c37\", \"#cccccc\"],\n [\"#382f32\", \"#ffeaf2\", \"#fcd9e5\", \"#fbc5d8\", \"#f1396d\"],\n [\"#e3dfba\", \"#c8d6bf\", \"#93ccc6\", \"#6cbdb5\", \"#1a1f1e\"],\n [\"#f6f6f6\", \"#e8e8e8\", \"#333333\", \"#990100\", \"#b90504\"],\n [\"#1b325f\", \"#9cc4e4\", \"#e9f2f9\", \"#3a89c9\", \"#f26c4f\"],\n [\"#a1dbb2\", \"#fee5ad\", \"#faca66\", \"#f7a541\", \"#f45d4c\"],\n [\"#c1b398\", \"#605951\", \"#fbeec2\", \"#61a6ab\", \"#accec0\"],\n [\"#5e9fa3\", \"#dcd1b4\", \"#fab87f\", \"#f87e7b\", \"#b05574\"],\n [\"#951f2b\", \"#f5f4d7\", \"#e0dfb1\", \"#a5a36c\", \"#535233\"],\n [\"#8dccad\", \"#988864\", \"#fea6a2\", \"#f9d6ac\", \"#ffe9af\"],\n [\"#2d2d29\", \"#215a6d\", \"#3ca2a2\", \"#92c7a3\", \"#dfece6\"],\n [\"#413d3d\", \"#040004\", \"#c8ff00\", \"#fa023c\", \"#4b000f\"],\n [\"#eff3cd\", \"#b2d5ba\", \"#61ada0\", \"#248f8d\", \"#605063\"],\n [\"#ffefd3\", \"#fffee4\", \"#d0ecea\", \"#9fd6d2\", \"#8b7a5e\"],\n [\"#cfffdd\", \"#b4dec1\", \"#5c5863\", \"#a85163\", \"#ff1f4c\"],\n [\"#9dc9ac\", \"#fffec7\", \"#f56218\", \"#ff9d2e\", \"#919167\"],\n [\"#4e395d\", \"#827085\", \"#8ebe94\", \"#ccfc8e\", \"#dc5b3e\"],\n [\"#a8a7a7\", \"#cc527a\", \"#e8175d\", \"#474747\", \"#363636\"],\n [\"#f8edd1\", \"#d88a8a\", \"#474843\", \"#9d9d93\", \"#c5cfc6\"],\n [\"#046d8b\", \"#309292\", \"#2fb8ac\", \"#93a42a\", \"#ecbe13\"],\n [\"#f38a8a\", \"#55443d\", \"#a0cab5\", \"#cde9ca\", \"#f1edd0\"],\n [\"#a70267\", \"#f10c49\", \"#fb6b41\", \"#f6d86b\", \"#339194\"],\n [\"#ff003c\", \"#ff8a00\", \"#fabe28\", \"#88c100\", \"#00c176\"],\n [\"#ffedbf\", \"#f7803c\", \"#f54828\", \"#2e0d23\", \"#f8e4c1\"],\n [\"#4e4d4a\", \"#353432\", \"#94ba65\", \"#2790b0\", \"#2b4e72\"],\n [\"#0ca5b0\", \"#4e3f30\", \"#fefeeb\", \"#f8f4e4\", \"#a5b3aa\"],\n [\"#4d3b3b\", \"#de6262\", \"#ffb88c\", \"#ffd0b3\", \"#f5e0d3\"],\n [\"#fffbb7\", \"#a6f6af\", \"#66b6ab\", \"#5b7c8d\", \"#4f2958\"],\n [\"#edf6ee\", \"#d1c089\", \"#b3204d\", \"#412e28\", \"#151101\"],\n [\"#9d7e79\", \"#ccac95\", \"#9a947c\", \"#748b83\", \"#5b756c\"],\n [\"#fcfef5\", \"#e9ffe1\", \"#cdcfb7\", \"#d6e6c3\", \"#fafbe3\"],\n [\"#9cddc8\", \"#bfd8ad\", \"#ddd9ab\", \"#f7af63\", \"#633d2e\"],\n [\"#30261c\", \"#403831\", \"#36544f\", \"#1f5f61\", \"#0b8185\"],\n [\"#aaff00\", \"#ffaa00\", \"#ff00aa\", \"#aa00ff\", \"#00aaff\"],\n [\"#d1313d\", \"#e5625c\", \"#f9bf76\", \"#8eb2c5\", \"#615375\"],\n [\"#ffe181\", \"#eee9e5\", \"#fad3b2\", \"#ffba7f\", \"#ff9c97\"],\n [\"#73c8a9\", \"#dee1b6\", \"#e1b866\", \"#bd5532\", \"#373b44\"],\n [\"#805841\", \"#dcf7f3\", \"#fffcdd\", \"#ffd8d8\", \"#f5a2a2\"],\n]\n\nexport const getDebugLayoutObject = (lo: any): LayoutDebugObject | null => {\n let {\n x,\n y,\n width,\n height,\n }: { x: number; y: number; width?: number; height?: number } = {\n ...lo,\n ...(lo as any).size,\n ...(lo as any).center,\n ...(lo as any).position,\n }\n\n if (\n lo.x1 !== undefined &&\n lo.x2 !== undefined &&\n lo.y1 !== undefined &&\n lo.y2 !== undefined\n ) {\n x = (lo.x1 + lo.x2) / 2\n y = (lo.y1 + lo.y2) / 2\n width = Math.abs(lo.x1 - lo.x2)\n height = Math.abs(lo.y1 - lo.y2)\n }\n\n if (lo.points && Array.isArray(lo.points) && lo.points.length > 0) {\n const xCoords = lo.points.map((point: { x: number }) => point.x)\n const yCoords = lo.points.map((point: { y: number }) => point.y)\n \n const minX = Math.min(...xCoords)\n const maxX = Math.max(...xCoords)\n const minY = Math.min(...yCoords)\n const maxY = Math.max(...yCoords)\n \n x = (minX + maxX) / 2\n y = (minY + maxY) / 2\n width = maxX - minX\n height = maxY - minY\n }\n\n const title = lo.text || lo.name || lo.source?.text || lo.source?.name || \"?\"\n const content = lo\n\n if (x === undefined || y === undefined) return null\n\n if (width === undefined) {\n if (\"outer_diameter\" in lo) {\n width = lo.outer_diameter\n height = lo.outer_diameter\n }\n }\n\n if (width === undefined || height === undefined) {\n width = 0.1\n height = 0.1\n }\n\n return {\n x,\n y,\n width,\n height,\n title,\n content,\n bg_color:\n nice_color_palettes[\n stringHash((lo as any).type || title) % nice_color_palettes.length\n ]?.[4] ?? \"#f00\",\n }\n}\n","export const isTruthy = <T>(value: T): value is NonNullable<T> => Boolean(value)\n","import type { AnyCircuitElement } from \"circuit-json\"\nimport { getDebugLayoutObject } from \"./utils/get-layout-debug-object\"\nimport { isTruthy } from \"./utils/is-truthy\"\n\nexport const findBoundsAndCenter = (\n elements: AnyCircuitElement[],\n): { center: { x: number; y: number }; width: number; height: number } => {\n const debugObjects = elements\n .filter((elm) => elm.type.startsWith(\"pcb_\"))\n .concat(\n elements\n .filter((elm) => elm.type === \"pcb_trace\")\n // @ts-ignore\n .flatMap((elm: PcbTrace) => elm.route),\n )\n .map((elm) => getDebugLayoutObject(elm))\n .filter(isTruthy)\n\n if (debugObjects.length === 0)\n return { center: { x: 0, y: 0 }, width: 0, height: 0 }\n\n let minX = debugObjects[0]!.x - debugObjects[0]!.width / 2\n let maxX = debugObjects[0]!.x + debugObjects[0]!.width / 2\n let minY = debugObjects[0]!.y - debugObjects[0]!.height / 2\n let maxY = debugObjects[0]!.y + debugObjects[0]!.height / 2\n\n for (const obj of debugObjects.slice(1)) {\n minX = Math.min(minX, obj.x - obj.width / 2)\n maxX = Math.max(maxX, obj.x + obj.width / 2)\n minY = Math.min(minY, obj.y - obj.height / 2)\n maxY = Math.max(maxY, obj.y + obj.height / 2)\n }\n\n const width = maxX - minX\n const height = maxY - minY\n const center = { x: minX + width / 2, y: minY + height / 2 }\n\n return { center, width, height }\n}\n","import type { AnyCircuitElement } from \"circuit-json\"\n\nexport const getPrimaryId = (element: AnyCircuitElement): string => {\n // @ts-ignore\n return element[`${element.type}_id`]\n}\n","import type { AnyCircuitElement } from \"circuit-json\"\nimport { transformPCBElements } from \"./transform-soup-elements\"\nimport { translate } from \"transformation-matrix\"\n\nexport const repositionPcbComponentTo = (\n circuitJson: AnyCircuitElement[],\n pcb_component_id: string,\n newCenter: { x: number; y: number },\n) => {\n const pcbComponent = circuitJson.find(\n (e) =>\n e.type === \"pcb_component\" &&\n (e as any).pcb_component_id === pcb_component_id,\n )\n if (!pcbComponent) return\n\n const currentCenter =\n \"center\" in pcbComponent\n ? (pcbComponent as any).center\n : { x: (pcbComponent as any).x, y: (pcbComponent as any).y }\n\n const dx = newCenter.x - currentCenter.x\n const dy = newCenter.y - currentCenter.y\n\n const portIds = circuitJson\n .filter(\n (e) =>\n e.type === \"pcb_port\" &&\n (e as any).pcb_component_id === pcb_component_id,\n )\n .map((e) => (e as any).pcb_port_id)\n\n const elementsToMove = circuitJson.filter((elm) => {\n if (elm === pcbComponent) return true\n const anyElm: any = elm\n if (anyElm.pcb_component_id === pcb_component_id) return true\n if (\n Array.isArray(anyElm.pcb_component_ids) &&\n anyElm.pcb_component_ids.includes(pcb_component_id)\n )\n return true\n if (anyElm.pcb_port_id && portIds.includes(anyElm.pcb_port_id)) return true\n if (\n Array.isArray(anyElm.pcb_port_ids) &&\n anyElm.pcb_port_ids.some((id: string) => portIds.includes(id))\n )\n return true\n if (anyElm.start_pcb_port_id && portIds.includes(anyElm.start_pcb_port_id))\n return true\n if (anyElm.end_pcb_port_id && portIds.includes(anyElm.end_pcb_port_id))\n return true\n if (\n Array.isArray(anyElm.route) &&\n anyElm.route.some(\n (pt: any) =>\n (pt.start_pcb_port_id && portIds.includes(pt.start_pcb_port_id)) ||\n (pt.end_pcb_port_id && portIds.includes(pt.end_pcb_port_id)),\n )\n )\n return true\n return false\n })\n\n const matrix = translate(dx, dy)\n transformPCBElements(elementsToMove, matrix)\n}\n","import type {\n AnyCircuitElement,\n SourceComponentBase,\n SourceGroup,\n} from \"circuit-json\"\n\n/**\n * A tree of circuit elements. This is often used for layout because you want\n * to consider only the top-level elements of a group for layout (child groups\n * move together)\n */\nexport interface CircuitJsonTreeNode {\n nodeType: \"group\" | \"component\"\n sourceGroup?: SourceGroup\n sourceComponent?: SourceComponentBase\n childNodes: Array<CircuitJsonTreeNode>\n otherChildElements: Array<AnyCircuitElement>\n}\n\nexport const getCircuitJsonTree = (\n circuitJson: AnyCircuitElement[],\n opts?: {\n source_group_id?: string\n },\n): CircuitJsonTreeNode => {\n type ChildGroupId = string\n type ParentGroupId = string\n type GroupId = string\n const groupChildMap: Map<ParentGroupId, ChildGroupId[]> = new Map()\n\n for (const elm of circuitJson) {\n if (elm.type === \"source_group\" && elm.parent_source_group_id) {\n const parentId = elm.parent_source_group_id\n const childId = elm.source_group_id\n const children = groupChildMap.get(parentId) ?? []\n children.push(childId)\n groupChildMap.set(parentId, children)\n if (!groupChildMap.has(childId)) {\n groupChildMap.set(childId, [])\n }\n }\n }\n\n const groupNodes = new Map<GroupId, CircuitJsonTreeNode>()\n\n const getNextGroupId = () => {\n for (const [parentId, children] of groupChildMap) {\n if (groupNodes.has(parentId)) continue\n if (children.every((childId) => groupNodes.has(childId))) {\n return parentId\n }\n }\n return null\n }\n\n // Compute any node we have the dependencies for until we've computed all of\n // them\n let lastGroupId: GroupId | null = null\n while (true) {\n const nextGroupId = getNextGroupId()\n if (!nextGroupId) break\n\n const sourceGroup = circuitJson.find(\n (elm) =>\n elm.type === \"source_group\" && elm.source_group_id === nextGroupId,\n ) as SourceGroup\n\n // Create the tree node for this group\n const node: CircuitJsonTreeNode = {\n nodeType: \"group\",\n sourceGroup,\n otherChildElements: [],\n childNodes: [\n ...(groupChildMap\n .get(nextGroupId)\n ?.map((childId) => groupNodes.get(childId)!) ?? []),\n ...circuitJson\n .filter(\n (elm) =>\n elm.type === \"source_component\" &&\n elm.source_group_id === nextGroupId,\n )\n .map((elm) => {\n return {\n nodeType: \"component\",\n sourceComponent: elm,\n childNodes: [],\n otherChildElements: [], // TODO\n } as CircuitJsonTreeNode\n }),\n ],\n }\n\n groupNodes.set(nextGroupId, node)\n lastGroupId = nextGroupId\n }\n\n if (!lastGroupId) {\n throw new Error(\n \"Could not compute circuit tree because no groups were processed\",\n )\n }\n\n return groupNodes.get(opts?.source_group_id ?? lastGroupId)!\n}\n","import type { CircuitJsonTreeNode } from \"./getCircuitJsonTree\"\n\nexport const getStringFromCircuitJsonTree = (\n circuitJsonTree: CircuitJsonTreeNode,\n indent = 0,\n): string => {\n if (circuitJsonTree.nodeType === \"component\") {\n return `${\" \".repeat(indent)}${circuitJsonTree.sourceComponent?.name ?? circuitJsonTree.sourceComponent?.source_component_id}`\n }\n const lines = []\n\n lines.push(\n `${\" \".repeat(indent)}${circuitJsonTree.sourceGroup?.name ?? circuitJsonTree.sourceGroup?.source_group_id}`,\n )\n for (const child of circuitJsonTree.childNodes) {\n lines.push(getStringFromCircuitJsonTree(child, indent + 2))\n }\n return lines.join(\"\\n\")\n}\n"],"mappings":"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W,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD,CAAC,WAAW,WAAW,WAAW,WAAW,SAAS;AAAA,EACtD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","names":["su","Soup","joiner"]}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tscircuit/circuit-json-util",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.0.
|
|
4
|
+
"version": "0.0.56",
|
|
5
5
|
"description": "Utility library for working with tscircuit circuit json",
|
|
6
6
|
"files": [
|
|
7
7
|
"dist"
|
|
@@ -28,6 +28,7 @@
|
|
|
28
28
|
"esbuild": "^0.20.2",
|
|
29
29
|
"esbuild-register": "^3.5.0",
|
|
30
30
|
"transformation-matrix": "^2.16.1",
|
|
31
|
+
"tscircuit": "^0.0.562",
|
|
31
32
|
"tsup": "^8.0.2",
|
|
32
33
|
"typescript": "^5.4.5",
|
|
33
34
|
"zod": "^3.23.6"
|