@tscircuit/circuit-json-util 0.0.75 → 0.0.76
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.js +16 -5
- package/dist/index.js.map +1 -1
- package/package.json +4 -2
package/dist/index.js
CHANGED
|
@@ -1446,7 +1446,9 @@ var repositionPcbComponentTo = (circuitJson, pcb_component_id, newCenter) => {
|
|
|
1446
1446
|
import { translate as translate2 } from "transformation-matrix";
|
|
1447
1447
|
var findAllDescendantGroupIds = (circuitJson, parentGroupId) => {
|
|
1448
1448
|
const childGroupIds = [];
|
|
1449
|
-
const directChildren = circuitJson.filter(
|
|
1449
|
+
const directChildren = circuitJson.filter(
|
|
1450
|
+
(elm) => elm.type === "source_group" && elm.parent_source_group_id === parentGroupId
|
|
1451
|
+
).map((elm) => elm.source_group_id);
|
|
1450
1452
|
childGroupIds.push(...directChildren);
|
|
1451
1453
|
for (const childId of directChildren) {
|
|
1452
1454
|
childGroupIds.push(...findAllDescendantGroupIds(circuitJson, childId));
|
|
@@ -1454,10 +1456,15 @@ var findAllDescendantGroupIds = (circuitJson, parentGroupId) => {
|
|
|
1454
1456
|
return childGroupIds;
|
|
1455
1457
|
};
|
|
1456
1458
|
var repositionPcbGroupTo = (circuitJson, source_group_id, newCenter) => {
|
|
1457
|
-
const allGroupIds = [
|
|
1459
|
+
const allGroupIds = [
|
|
1460
|
+
source_group_id,
|
|
1461
|
+
...findAllDescendantGroupIds(circuitJson, source_group_id)
|
|
1462
|
+
];
|
|
1458
1463
|
const allGroupElements = /* @__PURE__ */ new Set();
|
|
1459
1464
|
for (const groupId of allGroupIds) {
|
|
1460
|
-
const groupElements = buildSubtree(circuitJson, {
|
|
1465
|
+
const groupElements = buildSubtree(circuitJson, {
|
|
1466
|
+
source_group_id: groupId
|
|
1467
|
+
});
|
|
1461
1468
|
groupElements.forEach((elm) => allGroupElements.add(elm));
|
|
1462
1469
|
}
|
|
1463
1470
|
const portIds = Array.from(allGroupElements).filter((e) => e.type === "pcb_port").map((e) => e.pcb_port_id);
|
|
@@ -1476,7 +1483,9 @@ var repositionPcbGroupTo = (circuitJson, source_group_id, newCenter) => {
|
|
|
1476
1483
|
return false;
|
|
1477
1484
|
});
|
|
1478
1485
|
additionalTraces.forEach((trace) => allGroupElements.add(trace));
|
|
1479
|
-
const pcbElements = Array.from(allGroupElements).filter(
|
|
1486
|
+
const pcbElements = Array.from(allGroupElements).filter(
|
|
1487
|
+
(elm) => elm.type.startsWith("pcb_")
|
|
1488
|
+
);
|
|
1480
1489
|
if (pcbElements.length === 0) return;
|
|
1481
1490
|
const { center: currentCenter } = findBoundsAndCenter(pcbElements);
|
|
1482
1491
|
const dx = newCenter.x - currentCenter.x;
|
|
@@ -1669,7 +1678,9 @@ var getCircuitJsonTree = (circuitJson, opts) => {
|
|
|
1669
1678
|
rootGroupId = lastGroupId;
|
|
1670
1679
|
}
|
|
1671
1680
|
if (!rootGroupId) {
|
|
1672
|
-
console.warn(
|
|
1681
|
+
console.warn(
|
|
1682
|
+
"No valid root group found, returning tree without sourceGroup"
|
|
1683
|
+
);
|
|
1673
1684
|
return {
|
|
1674
1685
|
nodeType: "group",
|
|
1675
1686
|
childNodes: [],
|
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","../lib/reposition-pcb-group.ts","../lib/reposition-schematic-component.ts","../lib/reposition-schematic-group.ts","../lib/getCircuitJsonTree.ts","../lib/getStringFromCircuitJsonTree.ts","../lib/get-minimum-flex-container.ts","../lib/get-element-render-layers.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 const anyElm = elm as any\n anyElm.route = (anyElm.route ?? []).map((rp: any) => {\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 if (Array.isArray(anyElm.junctions)) {\n anyElm.junctions = anyElm.junctions.map((j: any) => {\n const tp = applyToPoint(matrix, j) as { x: number; y: number }\n j.x = tp.x\n j.y = tp.y\n return j\n })\n }\n if (Array.isArray(anyElm.edges)) {\n anyElm.edges = anyElm.edges.map((e: any) => {\n e.from = applyToPoint(matrix, e.from)\n e.to = applyToPoint(matrix, e.to)\n return e\n })\n }\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 const tsr = decomposeTSR(matrix)\n const flipPadWidthHeight =\n Math.round(tsr.rotation.angle / (Math.PI / 2)) % 2 === 1\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\n // Handle polygon-shaped SMT pads with points array\n if (\n elm.type === \"pcb_smtpad\" &&\n elm.shape === \"polygon\" &&\n Array.isArray(elm.points)\n ) {\n elm.points = elm.points.map((point: any) => {\n const tp = applyToPoint(matrix, { x: point.x, y: point.y })\n return {\n x: tp.x,\n y: tp.y,\n }\n })\n }\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 ) {\n elm.center = applyToPoint(matrix, elm.center)\n } else if (elm.type === \"pcb_component\") {\n elm.center = applyToPoint(matrix, elm.center)\n elm.rotation = elm.rotation + (tsr.rotation.angle / Math.PI) * 180\n elm.rotation = elm.rotation % 360\n if (flipPadWidthHeight) {\n ;[elm.width, elm.height] = [elm.height, elm.width]\n }\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 quarterTurns = Math.round(tsr.rotation.angle / (Math.PI / 2))\n const flipPadWidthHeight = Math.abs(quarterTurns) % 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 case \"silkscreenpath\":\n return \"pcb_silkscreen_path\"\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 = pcbPort.pcb_component_id\n ? cju(soup).pcb_component.get(pcbPort.pcb_component_id)\n : undefined\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 = pcbPort.pcb_component_id\n ? cju(soup).pcb_component.get(pcbPort.pcb_component_id)\n : undefined\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 // Handle polygon-shaped SMT pads with points array\n if (\n elm.type === \"pcb_smtpad\" &&\n elm.shape === \"polygon\" &&\n Array.isArray(elm.points)\n ) {\n for (const point of elm.points) {\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 continue\n }\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(\n (elm) => elm.type.startsWith(\"pcb_\") || elm.type.startsWith(\"schematic_\"),\n )\n .concat(\n elements\n .filter(\n (elm) => elm.type === \"pcb_trace\" || elm.type === \"schematic_trace\",\n )\n // @ts-ignore\n .flatMap((elm: any) => 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 { AnyCircuitElement } from \"circuit-json\"\nimport { buildSubtree } from \"./subtree\"\nimport { findBoundsAndCenter } from \"./find-bounds-and-center\"\nimport { transformPCBElements } from \"./transform-soup-elements\"\nimport { translate } from \"transformation-matrix\"\n\nconst findAllDescendantGroupIds = (\n circuitJson: AnyCircuitElement[],\n parentGroupId: string,\n): string[] => {\n const childGroupIds: string[] = []\n const directChildren = circuitJson\n .filter((elm) => elm.type === \"source_group\" && (elm as any).parent_source_group_id === parentGroupId)\n .map((elm) => (elm as any).source_group_id)\n \n childGroupIds.push(...directChildren)\n \n // Recursively find descendants of child groups\n for (const childId of directChildren) {\n childGroupIds.push(...findAllDescendantGroupIds(circuitJson, childId))\n }\n \n return childGroupIds\n}\n\nexport const repositionPcbGroupTo = (\n circuitJson: AnyCircuitElement[],\n source_group_id: string,\n newCenter: { x: number; y: number },\n) => {\n // Find all descendant group IDs\n const allGroupIds = [source_group_id, ...findAllDescendantGroupIds(circuitJson, source_group_id)]\n \n // Get all elements for each group (including the main group and its descendants)\n const allGroupElements = new Set<AnyCircuitElement>()\n \n for (const groupId of allGroupIds) {\n const groupElements = buildSubtree(circuitJson, { source_group_id: groupId })\n groupElements.forEach(elm => allGroupElements.add(elm))\n }\n \n // Get all port IDs from elements in the group\n const portIds = Array.from(allGroupElements)\n .filter((e) => e.type === \"pcb_port\")\n .map((e) => (e as any).pcb_port_id)\n \n // Find additional traces that connect to these ports (buildSubtree might miss these)\n const additionalTraces = circuitJson.filter((elm) => {\n if (elm.type !== \"pcb_trace\") return false\n if (allGroupElements.has(elm)) return false // already included\n \n const anyElm: any = elm\n \n // Check direct port connections\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 \n // Check route point connections\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 \n return false\n })\n \n // Add additional traces to the elements to move\n additionalTraces.forEach(trace => allGroupElements.add(trace))\n \n // Filter to only PCB elements that can be repositioned\n const pcbElements = Array.from(allGroupElements).filter((elm) => elm.type.startsWith(\"pcb_\"))\n \n if (pcbElements.length === 0) return\n \n // Calculate current bounds and center of the group\n const { center: currentCenter } = findBoundsAndCenter(pcbElements)\n \n // Calculate translation needed\n const dx = newCenter.x - currentCenter.x\n const dy = newCenter.y - currentCenter.y\n \n // Create translation matrix\n const matrix = translate(dx, dy)\n \n // Apply transformation to all PCB elements in the group\n transformPCBElements(pcbElements, matrix)\n}","import type { AnyCircuitElement } from \"circuit-json\"\nimport { transformSchematicElements } from \"./transform-soup-elements\"\nimport { translate } from \"transformation-matrix\"\n\nexport const repositionSchematicComponentTo = (\n circuitJson: AnyCircuitElement[],\n schematic_component_id: string,\n newCenter: { x: number; y: number },\n) => {\n const schematicComponent = circuitJson.find(\n (e) =>\n e.type === \"schematic_component\" &&\n (e as any).schematic_component_id === schematic_component_id,\n )\n if (!schematicComponent) return\n\n const currentCenter =\n \"center\" in schematicComponent\n ? (schematicComponent as any).center\n : { x: (schematicComponent as any).x, y: (schematicComponent 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 === \"schematic_port\" &&\n (e as any).schematic_component_id === schematic_component_id,\n )\n .map((e) => (e as any).schematic_port_id)\n\n const elementsToMove = circuitJson.filter((elm) => {\n if (elm === schematicComponent) return true\n const anyElm: any = elm\n if (anyElm.schematic_component_id === schematic_component_id) return true\n if (\n Array.isArray(anyElm.schematic_component_ids) &&\n anyElm.schematic_component_ids.includes(schematic_component_id)\n )\n return true\n if (anyElm.schematic_port_id && portIds.includes(anyElm.schematic_port_id))\n return true\n if (\n Array.isArray(anyElm.schematic_port_ids) &&\n anyElm.schematic_port_ids.some((id: string) => portIds.includes(id))\n )\n return true\n if (\n anyElm.start_schematic_port_id &&\n portIds.includes(anyElm.start_schematic_port_id)\n )\n return true\n if (\n anyElm.end_schematic_port_id &&\n portIds.includes(anyElm.end_schematic_port_id)\n )\n return true\n if (\n Array.isArray(anyElm.route) &&\n anyElm.route.some(\n (pt: any) =>\n (pt.start_schematic_port_id &&\n portIds.includes(pt.start_schematic_port_id)) ||\n (pt.end_schematic_port_id &&\n portIds.includes(pt.end_schematic_port_id)),\n )\n )\n return true\n return false\n })\n\n const matrix = translate(dx, dy)\n transformSchematicElements(elementsToMove, matrix)\n}\n","import type { AnyCircuitElement } from \"circuit-json\"\nimport { buildSubtree } from \"./subtree\"\nimport { findBoundsAndCenter } from \"./find-bounds-and-center\"\nimport { transformSchematicElements } from \"./transform-soup-elements\"\nimport { translate } from \"transformation-matrix\"\n\nconst findAllDescendantGroupIds = (\n circuitJson: AnyCircuitElement[],\n parentGroupId: string,\n): string[] => {\n const childGroupIds: string[] = []\n const directChildren = circuitJson\n .filter(\n (elm) =>\n elm.type === \"source_group\" &&\n (elm as any).parent_source_group_id === parentGroupId,\n )\n .map((elm) => (elm as any).source_group_id)\n\n childGroupIds.push(...directChildren)\n\n for (const childId of directChildren) {\n childGroupIds.push(...findAllDescendantGroupIds(circuitJson, childId))\n }\n\n return childGroupIds\n}\n\nexport const repositionSchematicGroupTo = (\n circuitJson: AnyCircuitElement[],\n source_group_id: string,\n newCenter: { x: number; y: number },\n) => {\n const allGroupIds = [\n source_group_id,\n ...findAllDescendantGroupIds(circuitJson, source_group_id),\n ]\n\n const allGroupElements = new Set<AnyCircuitElement>()\n\n for (const groupId of allGroupIds) {\n const groupElements = buildSubtree(circuitJson, {\n source_group_id: groupId,\n })\n groupElements.forEach((elm) => allGroupElements.add(elm))\n }\n\n const portIds = Array.from(allGroupElements)\n .filter((e) => e.type === \"schematic_port\")\n .map((e) => (e as any).schematic_port_id)\n\n const additionalTraces = circuitJson.filter((elm) => {\n if (elm.type !== \"schematic_trace\") return false\n if (allGroupElements.has(elm)) return false\n\n const anyElm: any = elm\n\n if (\n anyElm.start_schematic_port_id &&\n portIds.includes(anyElm.start_schematic_port_id)\n )\n return true\n if (\n anyElm.end_schematic_port_id &&\n portIds.includes(anyElm.end_schematic_port_id)\n )\n return true\n if (\n Array.isArray(anyElm.route) &&\n anyElm.route.some(\n (pt: any) =>\n (pt.start_schematic_port_id &&\n portIds.includes(pt.start_schematic_port_id)) ||\n (pt.end_schematic_port_id &&\n portIds.includes(pt.end_schematic_port_id)),\n )\n )\n return true\n\n return false\n })\n\n additionalTraces.forEach((trace) => allGroupElements.add(trace))\n\n const schematicElements = Array.from(allGroupElements).filter((elm) =>\n elm.type.startsWith(\"schematic_\"),\n )\n if (schematicElements.length === 0) return\n\n const { center: currentCenter } = findBoundsAndCenter(schematicElements)\n\n const dx = newCenter.x - currentCenter.x\n const dy = newCenter.y - currentCenter.y\n\n const matrix = translate(dx, dy)\n\n transformSchematicElements(schematicElements, 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 // Get all source group IDs present in the circuit JSON\n const existingGroupIds = new Set<string>()\n for (const elm of circuitJson) {\n if (elm.type === \"source_group\") {\n existingGroupIds.add(elm.source_group_id)\n }\n }\n\n // Find orphaned groups (groups whose parent is not in the circuit JSON)\n const orphanedGroups: string[] = []\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 \n // If parent doesn't exist in circuit JSON, this is an orphaned group\n if (!existingGroupIds.has(parentId)) {\n orphanedGroups.push(childId)\n // Treat orphaned groups as root-level groups\n if (!groupChildMap.has(childId)) {\n groupChildMap.set(childId, [])\n }\n } else {\n // Normal parent-child relationship\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\n // Ensure that every source_group, including root-level groups that have no parent,\n // is present in the groupChildMap. This guarantees that even standalone boards\n // (with no nested groups) are processed and appear at the top of the tree.\n for (const elm of circuitJson) {\n if (elm.type === \"source_group\" && !groupChildMap.has(elm.source_group_id)) {\n groupChildMap.set(elm.source_group_id, [])\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: [\n ...circuitJson.filter(\n (e) =>\n e.type === \"pcb_component\" &&\n e.source_component_id ===\n (elm as SourceComponentBase).source_component_id,\n ),\n ], // TODO populate\n } as CircuitJsonTreeNode\n }),\n ],\n }\n\n groupNodes.set(nextGroupId, node)\n lastGroupId = nextGroupId\n }\n\n if (!lastGroupId) {\n console.warn(\"No groups were processed, returning tree without sourceGroup\")\n return {\n nodeType: \"group\",\n childNodes: [], // TODO populate\n otherChildElements: circuitJson,\n }\n }\n\n // Determine which group to return as root\n let rootGroupId: string | null = null\n if (opts && opts.source_group_id !== undefined) {\n // Use explicitly specified group\n rootGroupId = opts.source_group_id\n } else if (orphanedGroups.length > 0) {\n // Use the first orphaned group as root (most likely scenario when filtering circuit JSON)\n rootGroupId = orphanedGroups[0]!\n } else {\n // Fall back to the last processed group (typically the top-level parent)\n rootGroupId = lastGroupId as string | null\n }\n\n if (!rootGroupId) {\n console.warn(\"No valid root group found, returning tree without sourceGroup\")\n return {\n nodeType: \"group\",\n childNodes: [], \n otherChildElements: circuitJson,\n }\n }\n\n return groupNodes.get(rootGroupId)!\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","export type Size = { width: number; height: number }\n\nimport type { FlexBoxOptions } from \"@tscircuit/miniflex\"\n/**\n * Compute the smallest possible dimensions (width & height) for a flex container\n * so that **all** children fit without overflowing _before_ any flex grow / shrink\n * is applied. This is a very lightweight approximation – it only considers the\n * children's explicit `width`/`height` (or `flexBasis`) plus the configured gaps\n * and the main-axis stacking rules derived from the flex direction.\n *\n * This function purposely does **not** try to implement the full flexbox sizing\n * algorithm – we only need a quick estimate so that `RootFlexBox` can be\n * instantiated even when the user did not provide explicit dimensions for the\n * container (e.g. when laying out PCB components directly on the board level\n * instead of inside a sub-circuit).\n */\nexport function getMinimumFlexContainer(\n children: Array<{ width: number; height: number }>,\n options: FlexBoxOptions = {},\n): Size {\n if (children.length === 0) return { width: 0, height: 0 }\n\n const direction = options.direction ?? \"row\"\n const columnGap = options.columnGap ?? 0\n const rowGap = options.rowGap ?? 0\n\n // Flexbox main-axis / cross-axis mapping --------------------------------\n const isRowDirection = direction === \"row\" || direction === \"row-reverse\"\n\n if (isRowDirection) {\n // Main-axis horizontally stacks children\n const totalChildWidth = children.reduce((sum, c) => sum + c.width, 0)\n const width = totalChildWidth + columnGap * Math.max(0, children.length - 1)\n\n const height = children.reduce((max, c) => Math.max(max, c.height), 0)\n return { width, height }\n } else {\n // Column direction – stack vertically\n const totalChildHeight = children.reduce((sum, c) => sum + c.height, 0)\n const height = totalChildHeight + rowGap * Math.max(0, children.length - 1)\n\n const width = children.reduce((max, c) => Math.max(max, c.width), 0)\n return { width, height }\n }\n}\n","import type { AnyCircuitElement, PcbRenderLayer } from \"circuit-json\"\n\nexport function getElementRenderLayers(\n element: AnyCircuitElement,\n): PcbRenderLayer[] {\n // Copper elements (pads, traces, copper pour, copper text)\n if (element.type === \"pcb_smtpad\") {\n const layer = element.layer\n return [`${layer}_copper` as PcbRenderLayer]\n }\n\n if (element.type === \"pcb_trace\") {\n // Traces can span multiple layers, return all layers from route\n if (!element.route || !Array.isArray(element.route)) return []\n const layers = new Set<PcbRenderLayer>()\n for (const point of element.route) {\n if (\"layer\" in point && point.layer) {\n layers.add(`${point.layer}_copper` as PcbRenderLayer)\n }\n }\n return Array.from(layers)\n }\n\n if (element.type === \"pcb_copper_pour\") {\n const layer = element.layer\n return [`${layer}_copper` as PcbRenderLayer]\n }\n\n if (element.type === \"pcb_copper_text\") {\n const layer = element.layer\n return [`${layer}_copper` as PcbRenderLayer]\n }\n\n // Silkscreen elements\n if (\n element.type === \"pcb_silkscreen_text\" ||\n element.type === \"pcb_silkscreen_rect\" ||\n element.type === \"pcb_silkscreen_circle\" ||\n element.type === \"pcb_silkscreen_line\" ||\n element.type === \"pcb_silkscreen_path\"\n ) {\n const layer = element.layer\n return [`${layer}_silkscreen` as PcbRenderLayer]\n }\n\n // Fabrication note elements\n if (\n element.type === \"pcb_fabrication_note_text\" ||\n element.type === \"pcb_fabrication_note_rect\" ||\n element.type === \"pcb_fabrication_note_path\"\n ) {\n const layer = element.layer\n return [`${layer}_fabrication_note` as PcbRenderLayer]\n }\n\n // Elements without layer filtering (always drawn)\n // These include: pcb_board, pcb_hole, pcb_plated_hole, pcb_via, pcb_cutout,\n // pcb_note_rect, pcb_note_path, pcb_note_text, pcb_note_line, pcb_note_dimension\n return []\n}"],"mappings":"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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,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;AACxD;AAEO,IAAM,uBAAuB,CAAC,OAAsC;AACzE,MAAI;AAAA,IACF;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,IAA+D;AAAA,IAC7D,GAAG;AAAA,IACH,GAAI,GAAW;AAAA,IACf,GAAI,GAAW;AAAA,IACf,GAAI,GAAW;AAAA,EACjB;AAEA,MACE,GAAG,OAAO,UACV,GAAG,OAAO,UACV,GAAG,OAAO,UACV,GAAG,OAAO,QACV;AACA,SAAK,GAAG,KAAK,GAAG,MAAM;AACtB,SAAK,GAAG,KAAK,GAAG,MAAM;AACtB,YAAQ,KAAK,IAAI,GAAG,KAAK,GAAG,EAAE;AAC9B,aAAS,KAAK,IAAI,GAAG,KAAK,GAAG,EAAE;AAAA,EACjC;AAEA,MAAI,GAAG,UAAU,MAAM,QAAQ,GAAG,MAAM,KAAK,GAAG,OAAO,SAAS,GAAG;AACjE,UAAM,UAAU,GAAG,OAAO,IAAI,CAAC,UAAyB,MAAM,CAAC;AAC/D,UAAM,UAAU,GAAG,OAAO,IAAI,CAAC,UAAyB,MAAM,CAAC;AAE/D,UAAM,OAAO,KAAK,IAAI,GAAG,OAAO;AAChC,UAAM,OAAO,KAAK,IAAI,GAAG,OAAO;AAChC,UAAM,OAAO,KAAK,IAAI,GAAG,OAAO;AAChC,UAAM,OAAO,KAAK,IAAI,GAAG,OAAO;AAEhC,SAAK,OAAO,QAAQ;AACpB,SAAK,OAAO,QAAQ;AACpB,YAAQ,OAAO;AACf,aAAS,OAAO;AAAA,EAClB;AAEA,QAAM,QAAQ,GAAG,QAAQ,GAAG,QAAQ,GAAG,QAAQ,QAAQ,GAAG,QAAQ,QAAQ;AAC1E,QAAM,UAAU;AAEhB,MAAI,MAAM,UAAa,MAAM,OAAW,QAAO;AAE/C,MAAI,UAAU,QAAW;AACvB,QAAI,oBAAoB,IAAI;AAC1B,cAAQ,GAAG;AACX,eAAS,GAAG;AAAA,IACd;AAAA,EACF;AAEA,MAAI,UAAU,UAAa,WAAW,QAAW;AAC/C,YAAQ;AACR,aAAS;AAAA,EACX;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,UACE,oBACE,WAAY,GAAW,QAAQ,KAAK,IAAI,oBAAoB,MAC9D,IAAI,CAAC,KAAK;AAAA,EACd;AACF;;;AC5LO,IAAM,WAAW,CAAI,UAAsC,QAAQ,KAAK;;;ACIxE,IAAM,sBAAsB,CACjC,aACwE;AACxE,QAAM,eAAe,SAClB;AAAA,IACC,CAAC,QAAQ,IAAI,KAAK,WAAW,MAAM,KAAK,IAAI,KAAK,WAAW,YAAY;AAAA,EAC1E,EACC;AAAA,IACC,SACG;AAAA,MACC,CAAC,QAAQ,IAAI,SAAS,eAAe,IAAI,SAAS;AAAA,IACpD,EAEC,QAAQ,CAAC,QAAa,IAAI,KAAK;AAAA,EACpC,EACC,IAAI,CAAC,QAAQ,qBAAqB,GAAG,CAAC,EACtC,OAAO,QAAQ;AAElB,MAAI,aAAa,WAAW;AAC1B,WAAO,EAAE,QAAQ,EAAE,GAAG,GAAG,GAAG,EAAE,GAAG,OAAO,GAAG,QAAQ,EAAE;AAEvD,MAAI,OAAO,aAAa,CAAC,EAAG,IAAI,aAAa,CAAC,EAAG,QAAQ;AACzD,MAAI,OAAO,aAAa,CAAC,EAAG,IAAI,aAAa,CAAC,EAAG,QAAQ;AACzD,MAAI,OAAO,aAAa,CAAC,EAAG,IAAI,aAAa,CAAC,EAAG,SAAS;AAC1D,MAAI,OAAO,aAAa,CAAC,EAAG,IAAI,aAAa,CAAC,EAAG,SAAS;AAE1D,aAAW,OAAO,aAAa,MAAM,CAAC,GAAG;AACvC,WAAO,KAAK,IAAI,MAAM,IAAI,IAAI,IAAI,QAAQ,CAAC;AAC3C,WAAO,KAAK,IAAI,MAAM,IAAI,IAAI,IAAI,QAAQ,CAAC;AAC3C,WAAO,KAAK,IAAI,MAAM,IAAI,IAAI,IAAI,SAAS,CAAC;AAC5C,WAAO,KAAK,IAAI,MAAM,IAAI,IAAI,IAAI,SAAS,CAAC;AAAA,EAC9C;AAEA,QAAM,QAAQ,OAAO;AACrB,QAAM,SAAS,OAAO;AACtB,QAAM,SAAS,EAAE,GAAG,OAAO,QAAQ,GAAG,GAAG,OAAO,SAAS,EAAE;AAE3D,SAAO,EAAE,QAAQ,OAAO,OAAO;AACjC;;;ACxCO,IAAM,eAAe,CAAC,YAAuC;AAElE,SAAO,QAAQ,GAAG,QAAQ,IAAI,KAAK;AACrC;;;ACHA,SAAS,iBAAiB;AAEnB,IAAM,2BAA2B,CACtC,aACA,kBACA,cACG;AACH,QAAM,eAAe,YAAY;AAAA,IAC/B,CAAC,MACC,EAAE,SAAS,mBACV,EAAU,qBAAqB;AAAA,EACpC;AACA,MAAI,CAAC,aAAc;AAEnB,QAAM,gBACJ,YAAY,eACP,aAAqB,SACtB,EAAE,GAAI,aAAqB,GAAG,GAAI,aAAqB,EAAE;AAE/D,QAAM,KAAK,UAAU,IAAI,cAAc;AACvC,QAAM,KAAK,UAAU,IAAI,cAAc;AAEvC,QAAM,UAAU,YACb;AAAA,IACC,CAAC,MACC,EAAE,SAAS,cACV,EAAU,qBAAqB;AAAA,EACpC,EACC,IAAI,CAAC,MAAO,EAAU,WAAW;AAEpC,QAAM,iBAAiB,YAAY,OAAO,CAAC,QAAQ;AACjD,QAAI,QAAQ,aAAc,QAAO;AACjC,UAAM,SAAc;AACpB,QAAI,OAAO,qBAAqB,iBAAkB,QAAO;AACzD,QACE,MAAM,QAAQ,OAAO,iBAAiB,KACtC,OAAO,kBAAkB,SAAS,gBAAgB;AAElD,aAAO;AACT,QAAI,OAAO,eAAe,QAAQ,SAAS,OAAO,WAAW,EAAG,QAAO;AACvE,QACE,MAAM,QAAQ,OAAO,YAAY,KACjC,OAAO,aAAa,KAAK,CAAC,OAAe,QAAQ,SAAS,EAAE,CAAC;AAE7D,aAAO;AACT,QAAI,OAAO,qBAAqB,QAAQ,SAAS,OAAO,iBAAiB;AACvE,aAAO;AACT,QAAI,OAAO,mBAAmB,QAAQ,SAAS,OAAO,eAAe;AACnE,aAAO;AACT,QACE,MAAM,QAAQ,OAAO,KAAK,KAC1B,OAAO,MAAM;AAAA,MACX,CAAC,OACE,GAAG,qBAAqB,QAAQ,SAAS,GAAG,iBAAiB,KAC7D,GAAG,mBAAmB,QAAQ,SAAS,GAAG,eAAe;AAAA,IAC9D;AAEA,aAAO;AACT,WAAO;AAAA,EACT,CAAC;AAED,QAAM,SAAS,UAAU,IAAI,EAAE;AAC/B,uBAAqB,gBAAgB,MAAM;AAC7C;;;AC7DA,SAAS,aAAAE,kBAAiB;AAE1B,IAAM,4BAA4B,CAChC,aACA,kBACa;AACb,QAAM,gBAA0B,CAAC;AACjC,QAAM,iBAAiB,YACpB,OAAO,CAAC,QAAQ,IAAI,SAAS,kBAAmB,IAAY,2BAA2B,aAAa,EACpG,IAAI,CAAC,QAAS,IAAY,eAAe;AAE5C,gBAAc,KAAK,GAAG,cAAc;AAGpC,aAAW,WAAW,gBAAgB;AACpC,kBAAc,KAAK,GAAG,0BAA0B,aAAa,OAAO,CAAC;AAAA,EACvE;AAEA,SAAO;AACT;AAEO,IAAM,uBAAuB,CAClC,aACA,iBACA,cACG;AAEH,QAAM,cAAc,CAAC,iBAAiB,GAAG,0BAA0B,aAAa,eAAe,CAAC;AAGhG,QAAM,mBAAmB,oBAAI,IAAuB;AAEpD,aAAW,WAAW,aAAa;AACjC,UAAM,gBAAgB,aAAa,aAAa,EAAE,iBAAiB,QAAQ,CAAC;AAC5E,kBAAc,QAAQ,SAAO,iBAAiB,IAAI,GAAG,CAAC;AAAA,EACxD;AAGA,QAAM,UAAU,MAAM,KAAK,gBAAgB,EACxC,OAAO,CAAC,MAAM,EAAE,SAAS,UAAU,EACnC,IAAI,CAAC,MAAO,EAAU,WAAW;AAGpC,QAAM,mBAAmB,YAAY,OAAO,CAAC,QAAQ;AACnD,QAAI,IAAI,SAAS,YAAa,QAAO;AACrC,QAAI,iBAAiB,IAAI,GAAG,EAAG,QAAO;AAEtC,UAAM,SAAc;AAGpB,QAAI,OAAO,qBAAqB,QAAQ,SAAS,OAAO,iBAAiB;AACvE,aAAO;AACT,QAAI,OAAO,mBAAmB,QAAQ,SAAS,OAAO,eAAe;AACnE,aAAO;AAGT,QACE,MAAM,QAAQ,OAAO,KAAK,KAC1B,OAAO,MAAM;AAAA,MACX,CAAC,OACE,GAAG,qBAAqB,QAAQ,SAAS,GAAG,iBAAiB,KAC7D,GAAG,mBAAmB,QAAQ,SAAS,GAAG,eAAe;AAAA,IAC9D;AAEA,aAAO;AAET,WAAO;AAAA,EACT,CAAC;AAGD,mBAAiB,QAAQ,WAAS,iBAAiB,IAAI,KAAK,CAAC;AAG7D,QAAM,cAAc,MAAM,KAAK,gBAAgB,EAAE,OAAO,CAAC,QAAQ,IAAI,KAAK,WAAW,MAAM,CAAC;AAE5F,MAAI,YAAY,WAAW,EAAG;AAG9B,QAAM,EAAE,QAAQ,cAAc,IAAI,oBAAoB,WAAW;AAGjE,QAAM,KAAK,UAAU,IAAI,cAAc;AACvC,QAAM,KAAK,UAAU,IAAI,cAAc;AAGvC,QAAM,SAASA,WAAU,IAAI,EAAE;AAG/B,uBAAqB,aAAa,MAAM;AAC1C;;;AC3FA,SAAS,aAAAC,kBAAiB;AAEnB,IAAM,iCAAiC,CAC5C,aACA,wBACA,cACG;AACH,QAAM,qBAAqB,YAAY;AAAA,IACrC,CAAC,MACC,EAAE,SAAS,yBACV,EAAU,2BAA2B;AAAA,EAC1C;AACA,MAAI,CAAC,mBAAoB;AAEzB,QAAM,gBACJ,YAAY,qBACP,mBAA2B,SAC5B,EAAE,GAAI,mBAA2B,GAAG,GAAI,mBAA2B,EAAE;AAE3E,QAAM,KAAK,UAAU,IAAI,cAAc;AACvC,QAAM,KAAK,UAAU,IAAI,cAAc;AAEvC,QAAM,UAAU,YACb;AAAA,IACC,CAAC,MACC,EAAE,SAAS,oBACV,EAAU,2BAA2B;AAAA,EAC1C,EACC,IAAI,CAAC,MAAO,EAAU,iBAAiB;AAE1C,QAAM,iBAAiB,YAAY,OAAO,CAAC,QAAQ;AACjD,QAAI,QAAQ,mBAAoB,QAAO;AACvC,UAAM,SAAc;AACpB,QAAI,OAAO,2BAA2B,uBAAwB,QAAO;AACrE,QACE,MAAM,QAAQ,OAAO,uBAAuB,KAC5C,OAAO,wBAAwB,SAAS,sBAAsB;AAE9D,aAAO;AACT,QAAI,OAAO,qBAAqB,QAAQ,SAAS,OAAO,iBAAiB;AACvE,aAAO;AACT,QACE,MAAM,QAAQ,OAAO,kBAAkB,KACvC,OAAO,mBAAmB,KAAK,CAAC,OAAe,QAAQ,SAAS,EAAE,CAAC;AAEnE,aAAO;AACT,QACE,OAAO,2BACP,QAAQ,SAAS,OAAO,uBAAuB;AAE/C,aAAO;AACT,QACE,OAAO,yBACP,QAAQ,SAAS,OAAO,qBAAqB;AAE7C,aAAO;AACT,QACE,MAAM,QAAQ,OAAO,KAAK,KAC1B,OAAO,MAAM;AAAA,MACX,CAAC,OACE,GAAG,2BACF,QAAQ,SAAS,GAAG,uBAAuB,KAC5C,GAAG,yBACF,QAAQ,SAAS,GAAG,qBAAqB;AAAA,IAC/C;AAEA,aAAO;AACT,WAAO;AAAA,EACT,CAAC;AAED,QAAM,SAASA,WAAU,IAAI,EAAE;AAC/B,6BAA2B,gBAAgB,MAAM;AACnD;;;ACtEA,SAAS,aAAAC,kBAAiB;AAE1B,IAAMC,6BAA4B,CAChC,aACA,kBACa;AACb,QAAM,gBAA0B,CAAC;AACjC,QAAM,iBAAiB,YACpB;AAAA,IACC,CAAC,QACC,IAAI,SAAS,kBACZ,IAAY,2BAA2B;AAAA,EAC5C,EACC,IAAI,CAAC,QAAS,IAAY,eAAe;AAE5C,gBAAc,KAAK,GAAG,cAAc;AAEpC,aAAW,WAAW,gBAAgB;AACpC,kBAAc,KAAK,GAAGA,2BAA0B,aAAa,OAAO,CAAC;AAAA,EACvE;AAEA,SAAO;AACT;AAEO,IAAM,6BAA6B,CACxC,aACA,iBACA,cACG;AACH,QAAM,cAAc;AAAA,IAClB;AAAA,IACA,GAAGA,2BAA0B,aAAa,eAAe;AAAA,EAC3D;AAEA,QAAM,mBAAmB,oBAAI,IAAuB;AAEpD,aAAW,WAAW,aAAa;AACjC,UAAM,gBAAgB,aAAa,aAAa;AAAA,MAC9C,iBAAiB;AAAA,IACnB,CAAC;AACD,kBAAc,QAAQ,CAAC,QAAQ,iBAAiB,IAAI,GAAG,CAAC;AAAA,EAC1D;AAEA,QAAM,UAAU,MAAM,KAAK,gBAAgB,EACxC,OAAO,CAAC,MAAM,EAAE,SAAS,gBAAgB,EACzC,IAAI,CAAC,MAAO,EAAU,iBAAiB;AAE1C,QAAM,mBAAmB,YAAY,OAAO,CAAC,QAAQ;AACnD,QAAI,IAAI,SAAS,kBAAmB,QAAO;AAC3C,QAAI,iBAAiB,IAAI,GAAG,EAAG,QAAO;AAEtC,UAAM,SAAc;AAEpB,QACE,OAAO,2BACP,QAAQ,SAAS,OAAO,uBAAuB;AAE/C,aAAO;AACT,QACE,OAAO,yBACP,QAAQ,SAAS,OAAO,qBAAqB;AAE7C,aAAO;AACT,QACE,MAAM,QAAQ,OAAO,KAAK,KAC1B,OAAO,MAAM;AAAA,MACX,CAAC,OACE,GAAG,2BACF,QAAQ,SAAS,GAAG,uBAAuB,KAC5C,GAAG,yBACF,QAAQ,SAAS,GAAG,qBAAqB;AAAA,IAC/C;AAEA,aAAO;AAET,WAAO;AAAA,EACT,CAAC;AAED,mBAAiB,QAAQ,CAAC,UAAU,iBAAiB,IAAI,KAAK,CAAC;AAE/D,QAAM,oBAAoB,MAAM,KAAK,gBAAgB,EAAE;AAAA,IAAO,CAAC,QAC7D,IAAI,KAAK,WAAW,YAAY;AAAA,EAClC;AACA,MAAI,kBAAkB,WAAW,EAAG;AAEpC,QAAM,EAAE,QAAQ,cAAc,IAAI,oBAAoB,iBAAiB;AAEvE,QAAM,KAAK,UAAU,IAAI,cAAc;AACvC,QAAM,KAAK,UAAU,IAAI,cAAc;AAEvC,QAAM,SAASD,WAAU,IAAI,EAAE;AAE/B,6BAA2B,mBAAmB,MAAM;AACtD;;;AC9EO,IAAM,qBAAqB,CAChC,aACA,SAGwB;AAIxB,QAAM,gBAAoD,oBAAI,IAAI;AAGlE,QAAM,mBAAmB,oBAAI,IAAY;AACzC,aAAW,OAAO,aAAa;AAC7B,QAAI,IAAI,SAAS,gBAAgB;AAC/B,uBAAiB,IAAI,IAAI,eAAe;AAAA,IAC1C;AAAA,EACF;AAGA,QAAM,iBAA2B,CAAC;AAElC,aAAW,OAAO,aAAa;AAC7B,QAAI,IAAI,SAAS,kBAAkB,IAAI,wBAAwB;AAC7D,YAAM,WAAW,IAAI;AACrB,YAAM,UAAU,IAAI;AAGpB,UAAI,CAAC,iBAAiB,IAAI,QAAQ,GAAG;AACnC,uBAAe,KAAK,OAAO;AAE3B,YAAI,CAAC,cAAc,IAAI,OAAO,GAAG;AAC/B,wBAAc,IAAI,SAAS,CAAC,CAAC;AAAA,QAC/B;AAAA,MACF,OAAO;AAEL,cAAM,WAAW,cAAc,IAAI,QAAQ,KAAK,CAAC;AACjD,iBAAS,KAAK,OAAO;AACrB,sBAAc,IAAI,UAAU,QAAQ;AACpC,YAAI,CAAC,cAAc,IAAI,OAAO,GAAG;AAC/B,wBAAc,IAAI,SAAS,CAAC,CAAC;AAAA,QAC/B;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAKA,aAAW,OAAO,aAAa;AAC7B,QAAI,IAAI,SAAS,kBAAkB,CAAC,cAAc,IAAI,IAAI,eAAe,GAAG;AAC1E,oBAAc,IAAI,IAAI,iBAAiB,CAAC,CAAC;AAAA,IAC3C;AAAA,EACF;AAEA,QAAM,aAAa,oBAAI,IAAkC;AAEzD,QAAM,iBAAiB,MAAM;AAC3B,eAAW,CAAC,UAAU,QAAQ,KAAK,eAAe;AAChD,UAAI,WAAW,IAAI,QAAQ,EAAG;AAC9B,UAAI,SAAS,MAAM,CAAC,YAAY,WAAW,IAAI,OAAO,CAAC,GAAG;AACxD,eAAO;AAAA,MACT;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAIA,MAAI,cAA8B;AAClC,SAAO,MAAM;AACX,UAAM,cAAc,eAAe;AACnC,QAAI,CAAC,YAAa;AAElB,UAAM,cAAc,YAAY;AAAA,MAC9B,CAAC,QACC,IAAI,SAAS,kBAAkB,IAAI,oBAAoB;AAAA,IAC3D;AAGA,UAAM,OAA4B;AAAA,MAChC,UAAU;AAAA,MACV;AAAA,MACA,oBAAoB,CAAC;AAAA,MACrB,YAAY;AAAA,QACV,GAAI,cACD,IAAI,WAAW,GACd,IAAI,CAAC,YAAY,WAAW,IAAI,OAAO,CAAE,KAAK,CAAC;AAAA,QACnD,GAAG,YACA;AAAA,UACC,CAAC,QACC,IAAI,SAAS,sBACb,IAAI,oBAAoB;AAAA,QAC5B,EACC,IAAI,CAAC,QAAQ;AACZ,iBAAO;AAAA,YACL,UAAU;AAAA,YACV,iBAAiB;AAAA,YACjB,YAAY,CAAC;AAAA,YACb,oBAAoB;AAAA,cAClB,GAAG,YAAY;AAAA,gBACb,CAAC,MACC,EAAE,SAAS,mBACX,EAAE,wBACC,IAA4B;AAAA,cACnC;AAAA,YACF;AAAA;AAAA,UACF;AAAA,QACF,CAAC;AAAA,MACL;AAAA,IACF;AAEA,eAAW,IAAI,aAAa,IAAI;AAChC,kBAAc;AAAA,EAChB;AAEA,MAAI,CAAC,aAAa;AAChB,YAAQ,KAAK,8DAA8D;AAC3E,WAAO;AAAA,MACL,UAAU;AAAA,MACV,YAAY,CAAC;AAAA;AAAA,MACb,oBAAoB;AAAA,IACtB;AAAA,EACF;AAGA,MAAI,cAA6B;AACjC,MAAI,QAAQ,KAAK,oBAAoB,QAAW;AAE9C,kBAAc,KAAK;AAAA,EACrB,WAAW,eAAe,SAAS,GAAG;AAEpC,kBAAc,eAAe,CAAC;AAAA,EAChC,OAAO;AAEL,kBAAc;AAAA,EAChB;AAEA,MAAI,CAAC,aAAa;AAChB,YAAQ,KAAK,+DAA+D;AAC5E,WAAO;AAAA,MACL,UAAU;AAAA,MACV,YAAY,CAAC;AAAA,MACb,oBAAoB;AAAA,IACtB;AAAA,EACF;AAEA,SAAO,WAAW,IAAI,WAAW;AACnC;;;ACrKO,IAAM,+BAA+B,CAC1C,iBACA,SAAS,MACE;AACX,MAAI,gBAAgB,aAAa,aAAa;AAC5C,WAAO,GAAG,IAAI,OAAO,MAAM,CAAC,GAAG,gBAAgB,iBAAiB,QAAQ,gBAAgB,iBAAiB,mBAAmB;AAAA,EAC9H;AACA,QAAM,QAAQ,CAAC;AAEf,QAAM;AAAA,IACJ,GAAG,IAAI,OAAO,MAAM,CAAC,GAAG,gBAAgB,aAAa,QAAQ,gBAAgB,aAAa,eAAe;AAAA,EAC3G;AACA,aAAW,SAAS,gBAAgB,YAAY;AAC9C,UAAM,KAAK,6BAA6B,OAAO,SAAS,CAAC,CAAC;AAAA,EAC5D;AACA,SAAO,MAAM,KAAK,IAAI;AACxB;;;ACFO,SAAS,wBACd,UACA,UAA0B,CAAC,GACrB;AACN,MAAI,SAAS,WAAW,EAAG,QAAO,EAAE,OAAO,GAAG,QAAQ,EAAE;AAExD,QAAM,YAAY,QAAQ,aAAa;AACvC,QAAM,YAAY,QAAQ,aAAa;AACvC,QAAM,SAAS,QAAQ,UAAU;AAGjC,QAAM,iBAAiB,cAAc,SAAS,cAAc;AAE5D,MAAI,gBAAgB;AAElB,UAAM,kBAAkB,SAAS,OAAO,CAAC,KAAK,MAAM,MAAM,EAAE,OAAO,CAAC;AACpE,UAAM,QAAQ,kBAAkB,YAAY,KAAK,IAAI,GAAG,SAAS,SAAS,CAAC;AAE3E,UAAM,SAAS,SAAS,OAAO,CAAC,KAAK,MAAM,KAAK,IAAI,KAAK,EAAE,MAAM,GAAG,CAAC;AACrE,WAAO,EAAE,OAAO,OAAO;AAAA,EACzB,OAAO;AAEL,UAAM,mBAAmB,SAAS,OAAO,CAAC,KAAK,MAAM,MAAM,EAAE,QAAQ,CAAC;AACtE,UAAM,SAAS,mBAAmB,SAAS,KAAK,IAAI,GAAG,SAAS,SAAS,CAAC;AAE1E,UAAM,QAAQ,SAAS,OAAO,CAAC,KAAK,MAAM,KAAK,IAAI,KAAK,EAAE,KAAK,GAAG,CAAC;AACnE,WAAO,EAAE,OAAO,OAAO;AAAA,EACzB;AACF;;;AC1CO,SAAS,uBACd,SACkB;AAElB,MAAI,QAAQ,SAAS,cAAc;AACjC,UAAM,QAAQ,QAAQ;AACtB,WAAO,CAAC,GAAG,KAAK,SAA2B;AAAA,EAC7C;AAEA,MAAI,QAAQ,SAAS,aAAa;AAEhC,QAAI,CAAC,QAAQ,SAAS,CAAC,MAAM,QAAQ,QAAQ,KAAK,EAAG,QAAO,CAAC;AAC7D,UAAM,SAAS,oBAAI,IAAoB;AACvC,eAAW,SAAS,QAAQ,OAAO;AACjC,UAAI,WAAW,SAAS,MAAM,OAAO;AACnC,eAAO,IAAI,GAAG,MAAM,KAAK,SAA2B;AAAA,MACtD;AAAA,IACF;AACA,WAAO,MAAM,KAAK,MAAM;AAAA,EAC1B;AAEA,MAAI,QAAQ,SAAS,mBAAmB;AACtC,UAAM,QAAQ,QAAQ;AACtB,WAAO,CAAC,GAAG,KAAK,SAA2B;AAAA,EAC7C;AAEA,MAAI,QAAQ,SAAS,mBAAmB;AACtC,UAAM,QAAQ,QAAQ;AACtB,WAAO,CAAC,GAAG,KAAK,SAA2B;AAAA,EAC7C;AAGA,MACE,QAAQ,SAAS,yBACjB,QAAQ,SAAS,yBACjB,QAAQ,SAAS,2BACjB,QAAQ,SAAS,yBACjB,QAAQ,SAAS,uBACjB;AACA,UAAM,QAAQ,QAAQ;AACtB,WAAO,CAAC,GAAG,KAAK,aAA+B;AAAA,EACjD;AAGA,MACE,QAAQ,SAAS,+BACjB,QAAQ,SAAS,+BACjB,QAAQ,SAAS,6BACjB;AACA,UAAM,QAAQ,QAAQ;AACtB,WAAO,CAAC,GAAG,KAAK,mBAAqC;AAAA,EACvD;AAKA,SAAO,CAAC;AACV;","names":["su","Soup","joiner","translate","translate","translate","findAllDescendantGroupIds"]}
|
|
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/reposition-pcb-group.ts","../lib/reposition-schematic-component.ts","../lib/reposition-schematic-group.ts","../lib/getCircuitJsonTree.ts","../lib/getStringFromCircuitJsonTree.ts","../lib/get-minimum-flex-container.ts","../lib/get-element-render-layers.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 const anyElm = elm as any\n anyElm.route = (anyElm.route ?? []).map((rp: any) => {\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 if (Array.isArray(anyElm.junctions)) {\n anyElm.junctions = anyElm.junctions.map((j: any) => {\n const tp = applyToPoint(matrix, j) as { x: number; y: number }\n j.x = tp.x\n j.y = tp.y\n return j\n })\n }\n if (Array.isArray(anyElm.edges)) {\n anyElm.edges = anyElm.edges.map((e: any) => {\n e.from = applyToPoint(matrix, e.from)\n e.to = applyToPoint(matrix, e.to)\n return e\n })\n }\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 const tsr = decomposeTSR(matrix)\n const flipPadWidthHeight =\n Math.round(tsr.rotation.angle / (Math.PI / 2)) % 2 === 1\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\n // Handle polygon-shaped SMT pads with points array\n if (\n elm.type === \"pcb_smtpad\" &&\n elm.shape === \"polygon\" &&\n Array.isArray(elm.points)\n ) {\n elm.points = elm.points.map((point: any) => {\n const tp = applyToPoint(matrix, { x: point.x, y: point.y })\n return {\n x: tp.x,\n y: tp.y,\n }\n })\n }\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 ) {\n elm.center = applyToPoint(matrix, elm.center)\n } else if (elm.type === \"pcb_component\") {\n elm.center = applyToPoint(matrix, elm.center)\n elm.rotation = elm.rotation + (tsr.rotation.angle / Math.PI) * 180\n elm.rotation = elm.rotation % 360\n if (flipPadWidthHeight) {\n ;[elm.width, elm.height] = [elm.height, elm.width]\n }\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 quarterTurns = Math.round(tsr.rotation.angle / (Math.PI / 2))\n const flipPadWidthHeight = Math.abs(quarterTurns) % 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`] &&\n 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 case \"silkscreenpath\":\n return \"pcb_silkscreen_path\"\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 = pcbPort.pcb_component_id\n ? cju(soup).pcb_component.get(pcbPort.pcb_component_id)\n : undefined\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 = pcbPort.pcb_component_id\n ? cju(soup).pcb_component.get(pcbPort.pcb_component_id)\n : undefined\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 // Handle polygon-shaped SMT pads with points array\n if (\n elm.type === \"pcb_smtpad\" &&\n elm.shape === \"polygon\" &&\n Array.isArray(elm.points)\n ) {\n for (const point of elm.points) {\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 continue\n }\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(\n (elm) => elm.type.startsWith(\"pcb_\") || elm.type.startsWith(\"schematic_\"),\n )\n .concat(\n elements\n .filter(\n (elm) => elm.type === \"pcb_trace\" || elm.type === \"schematic_trace\",\n )\n // @ts-ignore\n .flatMap((elm: any) => 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 { AnyCircuitElement } from \"circuit-json\"\nimport { buildSubtree } from \"./subtree\"\nimport { findBoundsAndCenter } from \"./find-bounds-and-center\"\nimport { transformPCBElements } from \"./transform-soup-elements\"\nimport { translate } from \"transformation-matrix\"\n\nconst findAllDescendantGroupIds = (\n circuitJson: AnyCircuitElement[],\n parentGroupId: string,\n): string[] => {\n const childGroupIds: string[] = []\n const directChildren = circuitJson\n .filter(\n (elm) =>\n elm.type === \"source_group\" &&\n (elm as any).parent_source_group_id === parentGroupId,\n )\n .map((elm) => (elm as any).source_group_id)\n\n childGroupIds.push(...directChildren)\n\n // Recursively find descendants of child groups\n for (const childId of directChildren) {\n childGroupIds.push(...findAllDescendantGroupIds(circuitJson, childId))\n }\n\n return childGroupIds\n}\n\nexport const repositionPcbGroupTo = (\n circuitJson: AnyCircuitElement[],\n source_group_id: string,\n newCenter: { x: number; y: number },\n) => {\n // Find all descendant group IDs\n const allGroupIds = [\n source_group_id,\n ...findAllDescendantGroupIds(circuitJson, source_group_id),\n ]\n\n // Get all elements for each group (including the main group and its descendants)\n const allGroupElements = new Set<AnyCircuitElement>()\n\n for (const groupId of allGroupIds) {\n const groupElements = buildSubtree(circuitJson, {\n source_group_id: groupId,\n })\n groupElements.forEach((elm) => allGroupElements.add(elm))\n }\n\n // Get all port IDs from elements in the group\n const portIds = Array.from(allGroupElements)\n .filter((e) => e.type === \"pcb_port\")\n .map((e) => (e as any).pcb_port_id)\n\n // Find additional traces that connect to these ports (buildSubtree might miss these)\n const additionalTraces = circuitJson.filter((elm) => {\n if (elm.type !== \"pcb_trace\") return false\n if (allGroupElements.has(elm)) return false // already included\n\n const anyElm: any = elm\n\n // Check direct port connections\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\n // Check route point connections\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\n return false\n })\n\n // Add additional traces to the elements to move\n additionalTraces.forEach((trace) => allGroupElements.add(trace))\n\n // Filter to only PCB elements that can be repositioned\n const pcbElements = Array.from(allGroupElements).filter((elm) =>\n elm.type.startsWith(\"pcb_\"),\n )\n\n if (pcbElements.length === 0) return\n\n // Calculate current bounds and center of the group\n const { center: currentCenter } = findBoundsAndCenter(pcbElements)\n\n // Calculate translation needed\n const dx = newCenter.x - currentCenter.x\n const dy = newCenter.y - currentCenter.y\n\n // Create translation matrix\n const matrix = translate(dx, dy)\n\n // Apply transformation to all PCB elements in the group\n transformPCBElements(pcbElements, matrix)\n}\n","import type { AnyCircuitElement } from \"circuit-json\"\nimport { transformSchematicElements } from \"./transform-soup-elements\"\nimport { translate } from \"transformation-matrix\"\n\nexport const repositionSchematicComponentTo = (\n circuitJson: AnyCircuitElement[],\n schematic_component_id: string,\n newCenter: { x: number; y: number },\n) => {\n const schematicComponent = circuitJson.find(\n (e) =>\n e.type === \"schematic_component\" &&\n (e as any).schematic_component_id === schematic_component_id,\n )\n if (!schematicComponent) return\n\n const currentCenter =\n \"center\" in schematicComponent\n ? (schematicComponent as any).center\n : { x: (schematicComponent as any).x, y: (schematicComponent 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 === \"schematic_port\" &&\n (e as any).schematic_component_id === schematic_component_id,\n )\n .map((e) => (e as any).schematic_port_id)\n\n const elementsToMove = circuitJson.filter((elm) => {\n if (elm === schematicComponent) return true\n const anyElm: any = elm\n if (anyElm.schematic_component_id === schematic_component_id) return true\n if (\n Array.isArray(anyElm.schematic_component_ids) &&\n anyElm.schematic_component_ids.includes(schematic_component_id)\n )\n return true\n if (anyElm.schematic_port_id && portIds.includes(anyElm.schematic_port_id))\n return true\n if (\n Array.isArray(anyElm.schematic_port_ids) &&\n anyElm.schematic_port_ids.some((id: string) => portIds.includes(id))\n )\n return true\n if (\n anyElm.start_schematic_port_id &&\n portIds.includes(anyElm.start_schematic_port_id)\n )\n return true\n if (\n anyElm.end_schematic_port_id &&\n portIds.includes(anyElm.end_schematic_port_id)\n )\n return true\n if (\n Array.isArray(anyElm.route) &&\n anyElm.route.some(\n (pt: any) =>\n (pt.start_schematic_port_id &&\n portIds.includes(pt.start_schematic_port_id)) ||\n (pt.end_schematic_port_id &&\n portIds.includes(pt.end_schematic_port_id)),\n )\n )\n return true\n return false\n })\n\n const matrix = translate(dx, dy)\n transformSchematicElements(elementsToMove, matrix)\n}\n","import type { AnyCircuitElement } from \"circuit-json\"\nimport { buildSubtree } from \"./subtree\"\nimport { findBoundsAndCenter } from \"./find-bounds-and-center\"\nimport { transformSchematicElements } from \"./transform-soup-elements\"\nimport { translate } from \"transformation-matrix\"\n\nconst findAllDescendantGroupIds = (\n circuitJson: AnyCircuitElement[],\n parentGroupId: string,\n): string[] => {\n const childGroupIds: string[] = []\n const directChildren = circuitJson\n .filter(\n (elm) =>\n elm.type === \"source_group\" &&\n (elm as any).parent_source_group_id === parentGroupId,\n )\n .map((elm) => (elm as any).source_group_id)\n\n childGroupIds.push(...directChildren)\n\n for (const childId of directChildren) {\n childGroupIds.push(...findAllDescendantGroupIds(circuitJson, childId))\n }\n\n return childGroupIds\n}\n\nexport const repositionSchematicGroupTo = (\n circuitJson: AnyCircuitElement[],\n source_group_id: string,\n newCenter: { x: number; y: number },\n) => {\n const allGroupIds = [\n source_group_id,\n ...findAllDescendantGroupIds(circuitJson, source_group_id),\n ]\n\n const allGroupElements = new Set<AnyCircuitElement>()\n\n for (const groupId of allGroupIds) {\n const groupElements = buildSubtree(circuitJson, {\n source_group_id: groupId,\n })\n groupElements.forEach((elm) => allGroupElements.add(elm))\n }\n\n const portIds = Array.from(allGroupElements)\n .filter((e) => e.type === \"schematic_port\")\n .map((e) => (e as any).schematic_port_id)\n\n const additionalTraces = circuitJson.filter((elm) => {\n if (elm.type !== \"schematic_trace\") return false\n if (allGroupElements.has(elm)) return false\n\n const anyElm: any = elm\n\n if (\n anyElm.start_schematic_port_id &&\n portIds.includes(anyElm.start_schematic_port_id)\n )\n return true\n if (\n anyElm.end_schematic_port_id &&\n portIds.includes(anyElm.end_schematic_port_id)\n )\n return true\n if (\n Array.isArray(anyElm.route) &&\n anyElm.route.some(\n (pt: any) =>\n (pt.start_schematic_port_id &&\n portIds.includes(pt.start_schematic_port_id)) ||\n (pt.end_schematic_port_id &&\n portIds.includes(pt.end_schematic_port_id)),\n )\n )\n return true\n\n return false\n })\n\n additionalTraces.forEach((trace) => allGroupElements.add(trace))\n\n const schematicElements = Array.from(allGroupElements).filter((elm) =>\n elm.type.startsWith(\"schematic_\"),\n )\n if (schematicElements.length === 0) return\n\n const { center: currentCenter } = findBoundsAndCenter(schematicElements)\n\n const dx = newCenter.x - currentCenter.x\n const dy = newCenter.y - currentCenter.y\n\n const matrix = translate(dx, dy)\n\n transformSchematicElements(schematicElements, 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 // Get all source group IDs present in the circuit JSON\n const existingGroupIds = new Set<string>()\n for (const elm of circuitJson) {\n if (elm.type === \"source_group\") {\n existingGroupIds.add(elm.source_group_id)\n }\n }\n\n // Find orphaned groups (groups whose parent is not in the circuit JSON)\n const orphanedGroups: string[] = []\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\n // If parent doesn't exist in circuit JSON, this is an orphaned group\n if (!existingGroupIds.has(parentId)) {\n orphanedGroups.push(childId)\n // Treat orphaned groups as root-level groups\n if (!groupChildMap.has(childId)) {\n groupChildMap.set(childId, [])\n }\n } else {\n // Normal parent-child relationship\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\n // Ensure that every source_group, including root-level groups that have no parent,\n // is present in the groupChildMap. This guarantees that even standalone boards\n // (with no nested groups) are processed and appear at the top of the tree.\n for (const elm of circuitJson) {\n if (\n elm.type === \"source_group\" &&\n !groupChildMap.has(elm.source_group_id)\n ) {\n groupChildMap.set(elm.source_group_id, [])\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: [\n ...circuitJson.filter(\n (e) =>\n e.type === \"pcb_component\" &&\n e.source_component_id ===\n (elm as SourceComponentBase).source_component_id,\n ),\n ], // TODO populate\n } as CircuitJsonTreeNode\n }),\n ],\n }\n\n groupNodes.set(nextGroupId, node)\n lastGroupId = nextGroupId\n }\n\n if (!lastGroupId) {\n console.warn(\"No groups were processed, returning tree without sourceGroup\")\n return {\n nodeType: \"group\",\n childNodes: [], // TODO populate\n otherChildElements: circuitJson,\n }\n }\n\n // Determine which group to return as root\n let rootGroupId: string | null = null\n if (opts && opts.source_group_id !== undefined) {\n // Use explicitly specified group\n rootGroupId = opts.source_group_id\n } else if (orphanedGroups.length > 0) {\n // Use the first orphaned group as root (most likely scenario when filtering circuit JSON)\n rootGroupId = orphanedGroups[0]!\n } else {\n // Fall back to the last processed group (typically the top-level parent)\n rootGroupId = lastGroupId as string | null\n }\n\n if (!rootGroupId) {\n console.warn(\n \"No valid root group found, returning tree without sourceGroup\",\n )\n return {\n nodeType: \"group\",\n childNodes: [],\n otherChildElements: circuitJson,\n }\n }\n\n return groupNodes.get(rootGroupId)!\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","export type Size = { width: number; height: number }\n\nimport type { FlexBoxOptions } from \"@tscircuit/miniflex\"\n/**\n * Compute the smallest possible dimensions (width & height) for a flex container\n * so that **all** children fit without overflowing _before_ any flex grow / shrink\n * is applied. This is a very lightweight approximation – it only considers the\n * children's explicit `width`/`height` (or `flexBasis`) plus the configured gaps\n * and the main-axis stacking rules derived from the flex direction.\n *\n * This function purposely does **not** try to implement the full flexbox sizing\n * algorithm – we only need a quick estimate so that `RootFlexBox` can be\n * instantiated even when the user did not provide explicit dimensions for the\n * container (e.g. when laying out PCB components directly on the board level\n * instead of inside a sub-circuit).\n */\nexport function getMinimumFlexContainer(\n children: Array<{ width: number; height: number }>,\n options: FlexBoxOptions = {},\n): Size {\n if (children.length === 0) return { width: 0, height: 0 }\n\n const direction = options.direction ?? \"row\"\n const columnGap = options.columnGap ?? 0\n const rowGap = options.rowGap ?? 0\n\n // Flexbox main-axis / cross-axis mapping --------------------------------\n const isRowDirection = direction === \"row\" || direction === \"row-reverse\"\n\n if (isRowDirection) {\n // Main-axis horizontally stacks children\n const totalChildWidth = children.reduce((sum, c) => sum + c.width, 0)\n const width = totalChildWidth + columnGap * Math.max(0, children.length - 1)\n\n const height = children.reduce((max, c) => Math.max(max, c.height), 0)\n return { width, height }\n } else {\n // Column direction – stack vertically\n const totalChildHeight = children.reduce((sum, c) => sum + c.height, 0)\n const height = totalChildHeight + rowGap * Math.max(0, children.length - 1)\n\n const width = children.reduce((max, c) => Math.max(max, c.width), 0)\n return { width, height }\n }\n}\n","import type { AnyCircuitElement, PcbRenderLayer } from \"circuit-json\"\n\nexport function getElementRenderLayers(\n element: AnyCircuitElement,\n): PcbRenderLayer[] {\n // Copper elements (pads, traces, copper pour, copper text)\n if (element.type === \"pcb_smtpad\") {\n const layer = element.layer\n return [`${layer}_copper` as PcbRenderLayer]\n }\n\n if (element.type === \"pcb_trace\") {\n // Traces can span multiple layers, return all layers from route\n if (!element.route || !Array.isArray(element.route)) return []\n const layers = new Set<PcbRenderLayer>()\n for (const point of element.route) {\n if (\"layer\" in point && point.layer) {\n layers.add(`${point.layer}_copper` as PcbRenderLayer)\n }\n }\n return Array.from(layers)\n }\n\n if (element.type === \"pcb_copper_pour\") {\n const layer = element.layer\n return [`${layer}_copper` as PcbRenderLayer]\n }\n\n if (element.type === \"pcb_copper_text\") {\n const layer = element.layer\n return [`${layer}_copper` as PcbRenderLayer]\n }\n\n // Silkscreen elements\n if (\n element.type === \"pcb_silkscreen_text\" ||\n element.type === \"pcb_silkscreen_rect\" ||\n element.type === \"pcb_silkscreen_circle\" ||\n element.type === \"pcb_silkscreen_line\" ||\n element.type === \"pcb_silkscreen_path\"\n ) {\n const layer = element.layer\n return [`${layer}_silkscreen` as PcbRenderLayer]\n }\n\n // Fabrication note elements\n if (\n element.type === \"pcb_fabrication_note_text\" ||\n element.type === \"pcb_fabrication_note_rect\" ||\n element.type === \"pcb_fabrication_note_path\"\n ) {\n const layer = element.layer\n return [`${layer}_fabrication_note` as PcbRenderLayer]\n }\n\n // Elements without layer filtering (always drawn)\n // These include: pcb_board, pcb_hole, pcb_plated_hole, pcb_via, pcb_cutout,\n // pcb_note_rect, pcb_note_path, pcb_note_text, pcb_note_line, pcb_note_dimension\n return []\n}\n"],"mappings":"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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,CAAC,WAAW,WAAW,WAAW,WAAW,SA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","names":["su","Soup","joiner","translate","translate","translate","findAllDescendantGroupIds"]}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tscircuit/circuit-json-util",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.0.
|
|
4
|
+
"version": "0.0.76",
|
|
5
5
|
"description": "Utility library for working with tscircuit circuit json",
|
|
6
6
|
"files": [
|
|
7
7
|
"dist"
|
|
@@ -11,7 +11,9 @@
|
|
|
11
11
|
"test": "bun test",
|
|
12
12
|
"prepublish": "npm run build",
|
|
13
13
|
"build": "tsup-node ./index.ts --format esm --dts --sourcemap",
|
|
14
|
-
"benchmark": "bun run lib/benchmarks/su-benchmark.ts"
|
|
14
|
+
"benchmark": "bun run lib/benchmarks/su-benchmark.ts",
|
|
15
|
+
"format": "biome format . --write",
|
|
16
|
+
"format:check": "biome format ."
|
|
15
17
|
},
|
|
16
18
|
"keywords": [],
|
|
17
19
|
"author": "",
|