@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 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
- export { type CircuitJsonInputUtilObjects, type CircuitJsonOps, type CircuitJsonUtilObjects, type CircuitJsonUtilOptions, type GetCircuitJsonUtilFn, type GetIndexedCircuitJsonUtilFn, type IndexedCircuitJsonUtilOptions, type SubtreeOptions, applySelector, applySelectorAST, buildSubtree, cju, cjuIndexed, directionToVec, findBoundsAndCenter, getBoundsOfPcbElements, getElementById, getElementId, getPrimaryId, getReadableNameForElement, getReadableNameForPcbPort, getReadableNameForPcbSmtpad, getReadableNameForPcbTrace, oppositeDirection, oppositeSide, repositionPcbComponentTo, rotateClockwise, rotateCounterClockwise, rotateDirection, su, transformPCBElement, transformPCBElements, transformSchematicElement, transformSchematicElements, vecToDirection };
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
- return null;
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
- return { x: 0, y: 1 };
764
- else if (direction === "down")
765
- return { x: 0, y: -1 };
766
- else if (direction === "left")
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
- y = 0;
776
- if (y > x)
777
- x = 0;
778
- if (x > 0 && y === 0)
779
- return "right";
780
- else if (x < 0 && y === 0)
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
- return "right";
792
- else if (direction === "right")
793
- return "down";
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
- return "left";
803
- else if (direction === "left")
804
- return "down";
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
- return "down";
825
- else if (direction === "down")
826
- return "up";
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
- return "bottom";
836
- else if (sideOrDir === "bottom" || sideOrDir === "down")
837
- return "top";
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.54",
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"