@tscircuit/core 0.0.1022 → 0.0.1024

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.
Files changed (3) hide show
  1. package/dist/index.d.ts +1660 -267
  2. package/dist/index.js +589 -490
  3. package/package.json +3 -3
package/dist/index.js CHANGED
@@ -41,6 +41,7 @@ __export(components_exports, {
41
41
  Keepout: () => Keepout,
42
42
  Led: () => Led,
43
43
  Mosfet: () => Mosfet,
44
+ MountedBoard: () => MountedBoard,
44
45
  Net: () => Net,
45
46
  NetLabel: () => NetLabel,
46
47
  NormalComponent: () => NormalComponent3,
@@ -116,6 +117,7 @@ import { DefaultEventPriority } from "react-reconciler/constants.js";
116
117
  import Debug from "debug";
117
118
  var debug = Debug("tscircuit:renderable");
118
119
  var orderedRenderPhases = [
120
+ "RenderIsolatedSubcircuits",
119
121
  "ReactSubtreesRender",
120
122
  "InflateSubcircuitCircuitJson",
121
123
  "SourceNameDuplicateComponentRemoval",
@@ -171,6 +173,7 @@ var renderPhaseIndexMap = new Map(
171
173
  orderedRenderPhases.map((phase, index) => [phase, index])
172
174
  );
173
175
  var asyncPhaseDependencies = {
176
+ InflateSubcircuitCircuitJson: ["RenderIsolatedSubcircuits"],
174
177
  PcbFootprintLayout: ["PcbFootprintStringRender"],
175
178
  PcbComponentSizeCalculation: ["PcbFootprintStringRender"],
176
179
  PcbLayout: ["PcbFootprintStringRender"],
@@ -950,7 +953,7 @@ var PrimitiveComponent2 = class extends Renderable {
950
953
  * components share the same names) unless you explicitly break out some ports
951
954
  */
952
955
  get isSubcircuit() {
953
- return Boolean(this.props.subcircuit) || this.lowercaseComponentName === "group" && this?.parent?.isRoot;
956
+ return Boolean(this.props.subcircuit) || this.lowercaseComponentName === "group" && this?.parent?.isRootCircuit;
954
957
  }
955
958
  get isGroup() {
956
959
  return this.lowercaseComponentName === "group";
@@ -10282,7 +10285,7 @@ var TscircuitAutorouter = class {
10282
10285
  import {
10283
10286
  distance as distance8
10284
10287
  } from "circuit-json";
10285
- import Debug13 from "debug";
10288
+ import Debug14 from "debug";
10286
10289
  import "zod";
10287
10290
 
10288
10291
  // lib/components/primitive-components/TraceHint.ts
@@ -14648,76 +14651,490 @@ function addPortIdsToTracesAtJumperPads(segments, db) {
14648
14651
  return result;
14649
14652
  }
14650
14653
 
14651
- // lib/components/primitive-components/Group/Group.ts
14652
- var Group6 = class extends NormalComponent3 {
14653
- pcb_group_id = null;
14654
- schematic_group_id = null;
14655
- subcircuit_id = null;
14656
- _hasStartedAsyncAutorouting = false;
14657
- _isInflatedFromCircuitJson = false;
14658
- _normalComponentNameMap = null;
14654
+ // lib/IsolatedCircuit.ts
14655
+ import { su as su5 } from "@tscircuit/circuit-json-util";
14656
+ import Debug13 from "debug";
14657
+ import { isValidElement as isValidElement2 } from "react";
14658
+ import { identity as identity4 } from "transformation-matrix";
14659
+
14660
+ // package.json
14661
+ var package_default = {
14662
+ name: "@tscircuit/core",
14663
+ type: "module",
14664
+ version: "0.0.1023",
14665
+ types: "dist/index.d.ts",
14666
+ main: "dist/index.js",
14667
+ module: "dist/index.js",
14668
+ exports: {
14669
+ ".": {
14670
+ import: "./dist/index.js",
14671
+ types: "./dist/index.d.ts"
14672
+ }
14673
+ },
14674
+ files: [
14675
+ "dist"
14676
+ ],
14677
+ repository: {
14678
+ type: "git",
14679
+ url: "https://github.com/tscircuit/core"
14680
+ },
14681
+ scripts: {
14682
+ build: "tsup-node index.ts --format esm --dts",
14683
+ format: "biome format . --write",
14684
+ "measure-bundle": "howfat -r table .",
14685
+ "pkg-pr-new-release": "bunx pkg-pr-new publish --comment=off --peerDeps",
14686
+ "smoke-test:dist": "bun run scripts/smoke-tests/test-dist-simple-circuit.tsx",
14687
+ "build:benchmarking": "bun build --experimental-html ./benchmarking/website/index.html --outdir ./benchmarking-dist",
14688
+ "build:benchmarking:watch": `chokidar "./{benchmarking,lib}/**/*.{ts,tsx}" -c 'bun build --experimental-html ./benchmarking/website/index.html --outdir ./benchmarking-dist'`,
14689
+ "start:benchmarking": 'concurrently "bun run build:benchmarking:watch" "live-server ./benchmarking-dist"',
14690
+ "generate-test-plan": "bun run scripts/generate-test-plan.ts"
14691
+ },
14692
+ devDependencies: {
14693
+ "@biomejs/biome": "^1.8.3",
14694
+ "@resvg/resvg-js": "^2.6.2",
14695
+ "@tscircuit/alphabet": "0.0.18",
14696
+ "@tscircuit/capacity-autorouter": "^0.0.264",
14697
+ "@tscircuit/checks": "^0.0.88",
14698
+ "@tscircuit/circuit-json-util": "^0.0.77",
14699
+ "@tscircuit/common": "^0.0.20",
14700
+ "@tscircuit/copper-pour-solver": "^0.0.20",
14701
+ "@tscircuit/footprinter": "^0.0.288",
14702
+ "@tscircuit/infgrid-ijump-astar": "^0.0.35",
14703
+ "@tscircuit/log-soup": "^1.0.2",
14704
+ "@tscircuit/matchpack": "^0.0.16",
14705
+ "@tscircuit/math-utils": "^0.0.29",
14706
+ "@tscircuit/miniflex": "^0.0.4",
14707
+ "@tscircuit/ngspice-spice-engine": "^0.0.8",
14708
+ "@tscircuit/props": "^0.0.471",
14709
+ "@tscircuit/schematic-match-adapt": "^0.0.16",
14710
+ "@tscircuit/schematic-trace-solver": "^v0.0.45",
14711
+ "@tscircuit/solver-utils": "^0.0.3",
14712
+ "@tscircuit/soup-util": "^0.0.41",
14713
+ "@types/bun": "^1.2.16",
14714
+ "@types/debug": "^4.1.12",
14715
+ "@types/react": "^19.1.8",
14716
+ "@types/react-dom": "^19.1.6",
14717
+ "@types/react-reconciler": "^0.28.9",
14718
+ "bpc-graph": "^0.0.57",
14719
+ "bun-match-svg": "0.0.12",
14720
+ "calculate-elbow": "^0.0.12",
14721
+ "chokidar-cli": "^3.0.0",
14722
+ "circuit-json": "^0.0.378",
14723
+ "circuit-json-to-bpc": "^0.0.13",
14724
+ "circuit-json-to-connectivity-map": "^0.0.23",
14725
+ "circuit-json-to-gltf": "^0.0.62",
14726
+ "circuit-json-to-simple-3d": "^0.0.9",
14727
+ "circuit-json-to-spice": "^0.0.33",
14728
+ "circuit-to-svg": "^0.0.327",
14729
+ concurrently: "^9.1.2",
14730
+ "connectivity-map": "^1.0.0",
14731
+ debug: "^4.3.6",
14732
+ "eecircuit-engine": "^1.5.6",
14733
+ flatbush: "^4.5.0",
14734
+ "graphics-debug": "^0.0.60",
14735
+ howfat: "^0.3.8",
14736
+ "live-server": "^1.2.2",
14737
+ "looks-same": "^9.0.1",
14738
+ minicssgrid: "^0.0.9",
14739
+ "pkg-pr-new": "^0.0.37",
14740
+ poppygl: "^0.0.16",
14741
+ react: "^19.1.0",
14742
+ "react-dom": "^19.1.0",
14743
+ "schematic-symbols": "^0.0.208",
14744
+ spicey: "^0.0.14",
14745
+ "ts-expect": "^1.3.0",
14746
+ tsup: "^8.2.4"
14747
+ },
14748
+ peerDependencies: {
14749
+ "@tscircuit/capacity-autorouter": "*",
14750
+ "@tscircuit/checks": "*",
14751
+ "@tscircuit/circuit-json-util": "*",
14752
+ "@tscircuit/footprinter": "*",
14753
+ "@tscircuit/infgrid-ijump-astar": "*",
14754
+ "@tscircuit/math-utils": "*",
14755
+ "@tscircuit/props": "*",
14756
+ "@tscircuit/schematic-match-adapt": "*",
14757
+ "circuit-json-to-bpc": "*",
14758
+ "bpc-graph": "*",
14759
+ "@tscircuit/matchpack": "*",
14760
+ "circuit-json": "*",
14761
+ "circuit-json-to-connectivity-map": "*",
14762
+ "schematic-symbols": "*",
14763
+ typescript: "^5.0.0"
14764
+ },
14765
+ dependencies: {
14766
+ "@flatten-js/core": "^1.6.2",
14767
+ "@lume/kiwi": "^0.4.3",
14768
+ "calculate-packing": "0.0.68",
14769
+ "css-select": "5.1.0",
14770
+ "format-si-unit": "^0.0.3",
14771
+ nanoid: "^5.0.7",
14772
+ "performance-now": "^2.1.0",
14773
+ "react-reconciler": "^0.32.0",
14774
+ "svg-path-commander": "^2.1.11",
14775
+ "transformation-matrix": "^2.16.1",
14776
+ zod: "^3.25.67"
14777
+ }
14778
+ };
14779
+
14780
+ // lib/IsolatedCircuit.ts
14781
+ var IsolatedCircuit = class {
14782
+ firstChild = null;
14783
+ children;
14784
+ db;
14785
+ root = null;
14786
+ isRootCircuit = false;
14787
+ _schematicDisabledOverride;
14788
+ get schematicDisabled() {
14789
+ if (this._schematicDisabledOverride !== void 0) {
14790
+ return this._schematicDisabledOverride;
14791
+ }
14792
+ if (this.platform?.schematicDisabled !== void 0) {
14793
+ return this.platform.schematicDisabled;
14794
+ }
14795
+ const board = this._getBoard();
14796
+ return board?._parsedProps?.schematicDisabled ?? false;
14797
+ }
14798
+ set schematicDisabled(value) {
14799
+ this._schematicDisabledOverride = value;
14800
+ }
14801
+ pcbDisabled = false;
14802
+ pcbRoutingDisabled = false;
14803
+ _featureMspSchematicTraceRouting = true;
14659
14804
  /**
14660
- * Returns a cached map of component names to NormalComponent instances within this subcircuit.
14661
- * The map is built lazily on first access and cached for subsequent calls.
14805
+ * The IsolatedCircuit name is usually set by the platform, it's not required but
14806
+ * if supplied can identify the circuit in certain effects, e.g. it is passed
14807
+ * as the display_name parameter for autorouting effects.
14662
14808
  */
14663
- getNormalComponentNameMap() {
14664
- if (this._normalComponentNameMap) {
14665
- return this._normalComponentNameMap;
14666
- }
14667
- const nameMap = /* @__PURE__ */ new Map();
14668
- const collectNamedComponents = (component) => {
14669
- if (component._isNormalComponent && component.name) {
14670
- const componentsWithSameName = nameMap.get(component.name);
14671
- if (componentsWithSameName) {
14672
- componentsWithSameName.push(component);
14673
- } else {
14674
- nameMap.set(component.name, [component]);
14675
- }
14676
- }
14677
- for (const child of component.children) {
14678
- if (!child.isSubcircuit) collectNamedComponents(child);
14679
- }
14680
- };
14681
- for (const child of this.children) {
14682
- if (!child.isSubcircuit) collectNamedComponents(child);
14809
+ name;
14810
+ platform;
14811
+ /**
14812
+ * Optional URL pointing to where this project is hosted or documented.
14813
+ * When provided it is stored in the source_project_metadata.project_url field
14814
+ * of the generated Circuit JSON.
14815
+ */
14816
+ projectUrl;
14817
+ _hasRenderedAtleastOnce = false;
14818
+ _asyncEffectIdsByPhase = /* @__PURE__ */ new Map();
14819
+ _asyncEffectPhaseById = /* @__PURE__ */ new Map();
14820
+ constructor({
14821
+ platform,
14822
+ projectUrl
14823
+ } = {}) {
14824
+ this.children = [];
14825
+ this.db = su5([]);
14826
+ this.platform = platform;
14827
+ this.projectUrl = projectUrl;
14828
+ this.pcbDisabled = platform?.pcbDisabled ?? false;
14829
+ this.root = this;
14830
+ }
14831
+ add(componentOrElm) {
14832
+ let component;
14833
+ if (isValidElement2(componentOrElm)) {
14834
+ component = createInstanceFromReactElement(componentOrElm);
14835
+ } else {
14836
+ component = componentOrElm;
14683
14837
  }
14684
- this._normalComponentNameMap = nameMap;
14685
- return nameMap;
14838
+ this.children.push(component);
14686
14839
  }
14687
- _asyncAutoroutingResult = null;
14688
- get config() {
14689
- return {
14690
- zodProps: groupProps,
14691
- componentName: "Group"
14840
+ setPlatform(platform) {
14841
+ this.platform = {
14842
+ ...this.platform,
14843
+ ...platform
14692
14844
  };
14693
14845
  }
14694
- doInitialSourceGroupRender() {
14695
- const { db } = this.root;
14696
- const hasExplicitName = typeof this._parsedProps.name === "string" && this._parsedProps.name.length > 0;
14697
- const source_group = db.source_group.insert({
14698
- name: this.name,
14699
- is_subcircuit: this.isSubcircuit,
14700
- was_automatically_named: !hasExplicitName
14701
- });
14702
- this.source_group_id = source_group.source_group_id;
14703
- if (this.isSubcircuit) {
14704
- this.subcircuit_id = `subcircuit_${source_group.source_group_id}`;
14705
- db.source_group.update(source_group.source_group_id, {
14706
- subcircuit_id: this.subcircuit_id
14707
- });
14846
+ /**
14847
+ * Get the main board for this Circuit.
14848
+ */
14849
+ _getBoard() {
14850
+ const directBoard = this.children.find((c) => c.componentName === "Board");
14851
+ if (directBoard) {
14852
+ return directBoard;
14708
14853
  }
14854
+ return void 0;
14709
14855
  }
14710
- doInitialSourceRender() {
14711
- const { db } = this.root;
14712
- for (const child of this.children) {
14713
- db.source_component.update(child.source_component_id, {
14714
- source_group_id: this.source_group_id
14715
- });
14856
+ _guessRootComponent() {
14857
+ if (this.firstChild) return;
14858
+ if (this.children.length === 0) {
14859
+ throw new Error(
14860
+ "Not able to guess root component: IsolatedCircuit has no children (use circuit.add(...))"
14861
+ );
14716
14862
  }
14717
- }
14718
- doInitialSourceParentAttachment() {
14719
- const { db } = this.root;
14720
- const parentGroup = this.parent?.getGroup?.();
14863
+ const panels = this.children.filter(
14864
+ (child) => child.lowercaseComponentName === "panel"
14865
+ );
14866
+ if (panels.length > 1) {
14867
+ throw new Error("Only one <panel> is allowed per circuit");
14868
+ }
14869
+ if (panels.length === 1) {
14870
+ if (this.children.length !== 1) {
14871
+ throw new Error("<panel> must be the root element of the circuit");
14872
+ }
14873
+ this.firstChild = panels[0];
14874
+ return;
14875
+ }
14876
+ if (this.children.length === 1 && this.children[0].isGroup) {
14877
+ this.firstChild = this.children[0];
14878
+ return;
14879
+ }
14880
+ const group = new Group6({ subcircuit: true });
14881
+ group.parent = this;
14882
+ group.addAll(this.children);
14883
+ this.children = [group];
14884
+ this.firstChild = group;
14885
+ }
14886
+ render() {
14887
+ if (!this.firstChild) {
14888
+ this._guessRootComponent();
14889
+ }
14890
+ const { firstChild, db } = this;
14891
+ if (!firstChild) throw new Error("IsolatedCircuit has no root component");
14892
+ firstChild.parent = this;
14893
+ firstChild.runRenderCycle();
14894
+ this._hasRenderedAtleastOnce = true;
14895
+ }
14896
+ async renderUntilSettled() {
14897
+ const existing = this.db.source_project_metadata.list()?.[0];
14898
+ if (!existing) {
14899
+ this.db.source_project_metadata.insert({
14900
+ software_used_string: `@tscircuit/core@${this.getCoreVersion()}`,
14901
+ ...this.projectUrl ? { project_url: this.projectUrl } : {}
14902
+ });
14903
+ }
14904
+ this.render();
14905
+ while (this._hasIncompleteAsyncEffects()) {
14906
+ await new Promise((resolve) => setTimeout(resolve, 100));
14907
+ this.render();
14908
+ }
14909
+ this.emit("renderComplete");
14910
+ }
14911
+ _hasIncompleteAsyncEffects() {
14912
+ if (this._asyncEffectPhaseById.size > 0) return true;
14913
+ return this.children.some((child) => child._hasIncompleteAsyncEffects());
14914
+ }
14915
+ _hasIncompleteAsyncEffectsForPhase(phase) {
14916
+ return (this._asyncEffectIdsByPhase.get(phase)?.size ?? 0) > 0;
14917
+ }
14918
+ getCircuitJson() {
14919
+ if (!this._hasRenderedAtleastOnce) this.render();
14920
+ return this.db.toArray();
14921
+ }
14922
+ toJson() {
14923
+ return this.getCircuitJson();
14924
+ }
14925
+ async getSvg(options) {
14926
+ const circuitToSvg = await import("circuit-to-svg").catch((e) => {
14927
+ throw new Error(
14928
+ `To use circuit.getSvg, you must install the "circuit-to-svg" package.
14929
+
14930
+ "${e.message}"`
14931
+ );
14932
+ });
14933
+ if (options.view === "pcb") {
14934
+ return circuitToSvg.convertCircuitJsonToPcbSvg(this.getCircuitJson());
14935
+ }
14936
+ if (options.view === "schematic") {
14937
+ return circuitToSvg.convertCircuitJsonToSchematicSvg(
14938
+ this.getCircuitJson()
14939
+ );
14940
+ }
14941
+ throw new Error(`Invalid view: ${options.view}`);
14942
+ }
14943
+ getCoreVersion() {
14944
+ const [major, minor, patch] = package_default.version.split(".").map(Number);
14945
+ return `${major}.${minor}.${patch + 1}`;
14946
+ }
14947
+ async preview(previewNameOrOpts) {
14948
+ const previewOpts = typeof previewNameOrOpts === "object" ? previewNameOrOpts : { previewName: previewNameOrOpts };
14949
+ throw new Error("project.preview is not yet implemented");
14950
+ }
14951
+ computeSchematicGlobalTransform() {
14952
+ return identity4();
14953
+ }
14954
+ _computePcbGlobalTransformBeforeLayout() {
14955
+ return identity4();
14956
+ }
14957
+ selectAll(selector) {
14958
+ this._guessRootComponent();
14959
+ return this.firstChild?.selectAll(selector) ?? [];
14960
+ }
14961
+ selectOne(selector, opts) {
14962
+ this._guessRootComponent();
14963
+ return this.firstChild?.selectOne(selector, opts) ?? null;
14964
+ }
14965
+ _eventListeners = {};
14966
+ emit(event, ...args) {
14967
+ if (event === "asyncEffect:start") {
14968
+ this._registerAsyncEffectStart(args[0]);
14969
+ } else if (event === "asyncEffect:end") {
14970
+ this._registerAsyncEffectEnd(args[0]);
14971
+ }
14972
+ if (!this._eventListeners[event]) return;
14973
+ for (const listener of this._eventListeners[event]) {
14974
+ listener(...args);
14975
+ }
14976
+ }
14977
+ on(event, listener) {
14978
+ if (!this._eventListeners[event]) {
14979
+ this._eventListeners[event] = [];
14980
+ }
14981
+ this._eventListeners[event].push(listener);
14982
+ }
14983
+ removeListener(event, listener) {
14984
+ if (!this._eventListeners[event]) return;
14985
+ this._eventListeners[event] = this._eventListeners[event].filter(
14986
+ (l) => l !== listener
14987
+ );
14988
+ }
14989
+ enableDebug(debug11) {
14990
+ if (typeof debug11 === "string") {
14991
+ Debug13.enable(debug11);
14992
+ } else if (debug11 === null || debug11 === false) {
14993
+ Debug13.disable();
14994
+ }
14995
+ }
14996
+ getClientOrigin() {
14997
+ if (typeof window !== "undefined" && window.location) {
14998
+ return window.location.origin;
14999
+ }
15000
+ if (typeof self !== "undefined" && self.location) {
15001
+ return self.location.origin;
15002
+ }
15003
+ return "";
15004
+ }
15005
+ _registerAsyncEffectStart(payload) {
15006
+ if (!payload?.asyncEffectId || !payload.phase) return;
15007
+ const { asyncEffectId, phase } = payload;
15008
+ const existingPhase = this._asyncEffectPhaseById.get(asyncEffectId);
15009
+ if (existingPhase && existingPhase !== phase) {
15010
+ this._asyncEffectIdsByPhase.get(existingPhase)?.delete(asyncEffectId);
15011
+ }
15012
+ if (!this._asyncEffectIdsByPhase.has(phase)) {
15013
+ this._asyncEffectIdsByPhase.set(phase, /* @__PURE__ */ new Set());
15014
+ }
15015
+ this._asyncEffectIdsByPhase.get(phase).add(asyncEffectId);
15016
+ this._asyncEffectPhaseById.set(asyncEffectId, phase);
15017
+ }
15018
+ _registerAsyncEffectEnd(payload) {
15019
+ if (!payload?.asyncEffectId) return;
15020
+ const { asyncEffectId } = payload;
15021
+ const phase = this._asyncEffectPhaseById.get(asyncEffectId) ?? payload.phase;
15022
+ if (phase) {
15023
+ const phaseSet = this._asyncEffectIdsByPhase.get(phase);
15024
+ phaseSet?.delete(asyncEffectId);
15025
+ if (phaseSet && phaseSet.size === 0) {
15026
+ this._asyncEffectIdsByPhase.delete(phase);
15027
+ }
15028
+ }
15029
+ this._asyncEffectPhaseById.delete(asyncEffectId);
15030
+ }
15031
+ };
15032
+
15033
+ // lib/components/primitive-components/Group/Group_doInitialRenderIsolatedSubcircuits.ts
15034
+ function Group_doInitialRenderIsolatedSubcircuits(group) {
15035
+ if (!group._isIsolatedSubcircuit) return;
15036
+ if (!group.root) return;
15037
+ const parentRoot = group.root;
15038
+ const isolatedCircuit = new IsolatedCircuit({
15039
+ platform: {
15040
+ ...parentRoot.platform,
15041
+ pcbDisabled: parentRoot.pcbDisabled,
15042
+ schematicDisabled: parentRoot.schematicDisabled
15043
+ }
15044
+ });
15045
+ const childrenSnapshot = [...group.children];
15046
+ for (const child of childrenSnapshot) {
15047
+ isolatedCircuit.add(child);
15048
+ }
15049
+ group._queueAsyncEffect("render-isolated-subcircuit", async () => {
15050
+ await isolatedCircuit.renderUntilSettled();
15051
+ group.children = [];
15052
+ group._normalComponentNameMap = null;
15053
+ group._isolatedCircuitJson = isolatedCircuit.getCircuitJson();
15054
+ });
15055
+ }
15056
+
15057
+ // lib/components/primitive-components/Group/Group.ts
15058
+ var Group6 = class extends NormalComponent3 {
15059
+ pcb_group_id = null;
15060
+ schematic_group_id = null;
15061
+ subcircuit_id = null;
15062
+ _hasStartedAsyncAutorouting = false;
15063
+ _isInflatedFromCircuitJson = false;
15064
+ _isolatedCircuitJson = null;
15065
+ get _isIsolatedSubcircuit() {
15066
+ return Boolean(this._parsedProps._subcircuitCachingEnabled);
15067
+ }
15068
+ _normalComponentNameMap = null;
15069
+ /**
15070
+ * Returns a cached map of component names to NormalComponent instances within this subcircuit.
15071
+ * The map is built lazily on first access and cached for subsequent calls.
15072
+ */
15073
+ getNormalComponentNameMap() {
15074
+ if (this._normalComponentNameMap) {
15075
+ return this._normalComponentNameMap;
15076
+ }
15077
+ const nameMap = /* @__PURE__ */ new Map();
15078
+ const collectNamedComponents = (component) => {
15079
+ if (component._isNormalComponent && component.name) {
15080
+ const componentsWithSameName = nameMap.get(component.name);
15081
+ if (componentsWithSameName) {
15082
+ componentsWithSameName.push(component);
15083
+ } else {
15084
+ nameMap.set(component.name, [component]);
15085
+ }
15086
+ }
15087
+ for (const child of component.children) {
15088
+ if (!child.isSubcircuit) collectNamedComponents(child);
15089
+ }
15090
+ };
15091
+ for (const child of this.children) {
15092
+ if (!child.isSubcircuit) collectNamedComponents(child);
15093
+ }
15094
+ this._normalComponentNameMap = nameMap;
15095
+ return nameMap;
15096
+ }
15097
+ _asyncAutoroutingResult = null;
15098
+ get config() {
15099
+ return {
15100
+ zodProps: groupProps,
15101
+ componentName: "Group"
15102
+ };
15103
+ }
15104
+ runRenderPhaseForChildren(phase) {
15105
+ if (this._isIsolatedSubcircuit && !this._isInflatedFromCircuitJson) return;
15106
+ super.runRenderPhaseForChildren(phase);
15107
+ }
15108
+ doInitialRenderIsolatedSubcircuits() {
15109
+ Group_doInitialRenderIsolatedSubcircuits(this);
15110
+ }
15111
+ doInitialSourceGroupRender() {
15112
+ const { db } = this.root;
15113
+ const hasExplicitName = typeof this._parsedProps.name === "string" && this._parsedProps.name.length > 0;
15114
+ const source_group = db.source_group.insert({
15115
+ name: this.name,
15116
+ is_subcircuit: this.isSubcircuit,
15117
+ was_automatically_named: !hasExplicitName
15118
+ });
15119
+ this.source_group_id = source_group.source_group_id;
15120
+ if (this.isSubcircuit) {
15121
+ this.subcircuit_id = `subcircuit_${source_group.source_group_id}`;
15122
+ db.source_group.update(source_group.source_group_id, {
15123
+ subcircuit_id: this.subcircuit_id
15124
+ });
15125
+ }
15126
+ }
15127
+ doInitialSourceRender() {
15128
+ const { db } = this.root;
15129
+ for (const child of this.children) {
15130
+ db.source_component.update(child.source_component_id, {
15131
+ source_group_id: this.source_group_id
15132
+ });
15133
+ }
15134
+ }
15135
+ doInitialSourceParentAttachment() {
15136
+ const { db } = this.root;
15137
+ const parentGroup = this.parent?.getGroup?.();
14721
15138
  if (parentGroup?.source_group_id) {
14722
15139
  db.source_group.update(this.source_group_id, {
14723
15140
  parent_source_group_id: parentGroup.source_group_id
@@ -14879,14 +15296,14 @@ var Group6 = class extends NormalComponent3 {
14879
15296
  return false;
14880
15297
  }
14881
15298
  _hasTracesToRoute() {
14882
- const debug11 = Debug13("tscircuit:core:_hasTracesToRoute");
15299
+ const debug11 = Debug14("tscircuit:core:_hasTracesToRoute");
14883
15300
  const traces = this.selectAll("trace");
14884
15301
  debug11(`[${this.getString()}] has ${traces.length} traces to route`);
14885
15302
  return traces.length > 0;
14886
15303
  }
14887
15304
  async _runEffectMakeHttpAutoroutingRequest() {
14888
15305
  const { db } = this.root;
14889
- const debug11 = Debug13("tscircuit:core:_runEffectMakeHttpAutoroutingRequest");
15306
+ const debug11 = Debug14("tscircuit:core:_runEffectMakeHttpAutoroutingRequest");
14890
15307
  const props = this._parsedProps;
14891
15308
  const autorouterConfig = this._getAutorouterConfig();
14892
15309
  const serverUrl = autorouterConfig.serverUrl;
@@ -15009,7 +15426,7 @@ var Group6 = class extends NormalComponent3 {
15009
15426
  async _runLocalAutorouting() {
15010
15427
  const { db } = this.root;
15011
15428
  const props = this._parsedProps;
15012
- const debug11 = Debug13("tscircuit:core:_runLocalAutorouting");
15429
+ const debug11 = Debug14("tscircuit:core:_runLocalAutorouting");
15013
15430
  debug11(`[${this.getString()}] starting local autorouting`);
15014
15431
  const autorouterConfig = this._getAutorouterConfig();
15015
15432
  const isLaserPrefabPreset = this._isLaserPrefabAutorouter(autorouterConfig);
@@ -15145,7 +15562,7 @@ var Group6 = class extends NormalComponent3 {
15145
15562
  }
15146
15563
  }
15147
15564
  doInitialPcbTraceRender() {
15148
- const debug11 = Debug13("tscircuit:core:doInitialPcbTraceRender");
15565
+ const debug11 = Debug14("tscircuit:core:doInitialPcbTraceRender");
15149
15566
  if (!this.isSubcircuit) return;
15150
15567
  if (this.root?.pcbDisabled) return;
15151
15568
  if (this.getInheritedProperty("routingDisabled")) return;
@@ -15167,7 +15584,7 @@ var Group6 = class extends NormalComponent3 {
15167
15584
  Group_doInitialSchematicTraceRender(this);
15168
15585
  }
15169
15586
  updatePcbTraceRender() {
15170
- const debug11 = Debug13("tscircuit:core:updatePcbTraceRender");
15587
+ const debug11 = Debug14("tscircuit:core:updatePcbTraceRender");
15171
15588
  debug11(`[${this.getString()}] updating...`);
15172
15589
  if (!this.isSubcircuit) return;
15173
15590
  if (this._isInflatedFromCircuitJson) return;
@@ -15599,7 +16016,7 @@ import { cju } from "@tscircuit/circuit-json-util";
15599
16016
  // lib/components/primitive-components/Group/Subcircuit/inflators/inflatePcbBoard.ts
15600
16017
  function inflatePcbBoard(pcbBoard, inflatorContext) {
15601
16018
  const { subcircuit } = inflatorContext;
15602
- if (subcircuit.lowercaseComponentName === "board") {
16019
+ if (subcircuit.lowercaseComponentName === "board" || subcircuit.lowercaseComponentName === "mountedboard") {
15603
16020
  return;
15604
16021
  }
15605
16022
  if (subcircuit.parent?.lowercaseComponentName === "board") {
@@ -17050,18 +17467,106 @@ var Board = class extends Group6 {
17050
17467
  }
17051
17468
  };
17052
17469
 
17053
- // lib/components/normal-components/Panel.ts
17054
- import { panelProps } from "@tscircuit/props";
17055
- import { distance as distance12 } from "circuit-json";
17056
-
17057
- // lib/components/normal-components/Subpanel.ts
17058
- import { subpanelProps } from "@tscircuit/props";
17059
- import { distance as distance11 } from "circuit-json";
17470
+ // lib/components/normal-components/MountedBoard.ts
17471
+ import { mountedboardProps } from "@tscircuit/props";
17060
17472
 
17061
- // lib/utils/panels/generate-panel-tabs-and-mouse-bites.ts
17062
- import * as Flatten from "@flatten-js/core";
17063
- import { point as point5, Polygon as Polygon3 } from "@flatten-js/core";
17064
- var DEFAULT_TAB_LENGTH = 5;
17473
+ // lib/components/primitive-components/Group/Subcircuit/Subcircuit.ts
17474
+ import "@tscircuit/props";
17475
+ var Subcircuit = class extends Group6 {
17476
+ constructor(props) {
17477
+ super({
17478
+ ...props,
17479
+ // @ts-ignore
17480
+ subcircuit: true
17481
+ });
17482
+ }
17483
+ /**
17484
+ * During this phase, we inflate the subcircuit circuit json into class
17485
+ * instances
17486
+ *
17487
+ * When subcircuit's define circuitJson, it's basically the same as having
17488
+ * a tree of components. All the data from circuit json has to be converted
17489
+ * into props for the tree of components
17490
+ *
17491
+ * We do this in two phases:
17492
+ * - Create the components
17493
+ * - Create the groups
17494
+ * - Add components to groups in the appropriate hierarchy
17495
+ */
17496
+ doInitialInflateSubcircuitCircuitJson() {
17497
+ const isolatedJson = this._isolatedCircuitJson;
17498
+ if (isolatedJson) {
17499
+ this._isInflatedFromCircuitJson = true;
17500
+ this._isolatedCircuitJson = null;
17501
+ inflateCircuitJson(this, isolatedJson, []);
17502
+ return;
17503
+ }
17504
+ const { circuitJson, children } = this._parsedProps;
17505
+ if (circuitJson) {
17506
+ this._isInflatedFromCircuitJson = true;
17507
+ }
17508
+ inflateCircuitJson(this, circuitJson, children);
17509
+ }
17510
+ };
17511
+
17512
+ // lib/components/normal-components/MountedBoard.ts
17513
+ var MountedBoard = class extends Subcircuit {
17514
+ pcb_board_id = null;
17515
+ constructor(props) {
17516
+ super(props);
17517
+ }
17518
+ get config() {
17519
+ return {
17520
+ componentName: "MountedBoard",
17521
+ zodProps: mountedboardProps
17522
+ };
17523
+ }
17524
+ doInitialPcbComponentRender() {
17525
+ if (this.root?.pcbDisabled) return;
17526
+ const { db } = this.root;
17527
+ const { _parsedProps: props } = this;
17528
+ const globalPos = this._getGlobalPcbPositionBeforeLayout();
17529
+ const pcb_board = db.pcb_board.insert({
17530
+ center: { x: globalPos.x, y: globalPos.y },
17531
+ width: props.width ?? 0,
17532
+ height: props.height ?? 0,
17533
+ is_mounted_to_carrier_board: true
17534
+ });
17535
+ this.pcb_board_id = pcb_board.pcb_board_id;
17536
+ }
17537
+ doInitialPcbBoardAutoSize() {
17538
+ if (!this.pcb_board_id || !this.root) return;
17539
+ const carrierBoardId = this._findCarrierBoardId();
17540
+ if (carrierBoardId) {
17541
+ this.root.db.pcb_board.update(this.pcb_board_id, {
17542
+ carrier_pcb_board_id: carrierBoardId
17543
+ });
17544
+ }
17545
+ }
17546
+ _findCarrierBoardId() {
17547
+ let current = this.parent;
17548
+ while (current) {
17549
+ if (current instanceof Board) {
17550
+ return current.pcb_board_id;
17551
+ }
17552
+ current = current.parent;
17553
+ }
17554
+ return null;
17555
+ }
17556
+ };
17557
+
17558
+ // lib/components/normal-components/Panel.ts
17559
+ import { panelProps } from "@tscircuit/props";
17560
+ import { distance as distance12 } from "circuit-json";
17561
+
17562
+ // lib/components/normal-components/Subpanel.ts
17563
+ import { subpanelProps } from "@tscircuit/props";
17564
+ import { distance as distance11 } from "circuit-json";
17565
+
17566
+ // lib/utils/panels/generate-panel-tabs-and-mouse-bites.ts
17567
+ import * as Flatten from "@flatten-js/core";
17568
+ import { point as point5, Polygon as Polygon3 } from "@flatten-js/core";
17569
+ var DEFAULT_TAB_LENGTH = 5;
17065
17570
  var DEFAULT_TAB_WIDTH = 2;
17066
17571
  var generateCutoutsAndMousebitesForOutline = (outline, options) => {
17067
17572
  const {
@@ -19233,38 +19738,6 @@ var PcbNoteDimension = class extends PrimitiveComponent2 {
19233
19738
  }
19234
19739
  };
19235
19740
 
19236
- // lib/components/primitive-components/Group/Subcircuit/Subcircuit.ts
19237
- import "@tscircuit/props";
19238
- var Subcircuit = class extends Group6 {
19239
- constructor(props) {
19240
- super({
19241
- ...props,
19242
- // @ts-ignore
19243
- subcircuit: true
19244
- });
19245
- }
19246
- /**
19247
- * During this phase, we inflate the subcircuit circuit json into class
19248
- * instances
19249
- *
19250
- * When subcircuit's define circuitJson, it's basically the same as having
19251
- * a tree of components. All the data from circuit json has to be converted
19252
- * into props for the tree of components
19253
- *
19254
- * We do this in two phases:
19255
- * - Create the components
19256
- * - Create the groups
19257
- * - Add components to groups in the appropriate hierarchy
19258
- */
19259
- doInitialInflateSubcircuitCircuitJson() {
19260
- const { circuitJson, children } = this._parsedProps;
19261
- if (circuitJson) {
19262
- this._isInflatedFromCircuitJson = true;
19263
- }
19264
- inflateCircuitJson(this, circuitJson, children);
19265
- }
19266
- };
19267
-
19268
19741
  // lib/components/primitive-components/Breakout/Breakout.ts
19269
19742
  import "@tscircuit/props";
19270
19743
  var Breakout = class extends Group6 {
@@ -19399,7 +19872,7 @@ var BreakoutPoint = class extends PrimitiveComponent2 {
19399
19872
  import { netLabelProps } from "@tscircuit/props";
19400
19873
  import {
19401
19874
  applyToPoint as applyToPoint17,
19402
- identity as identity4,
19875
+ identity as identity5,
19403
19876
  translate as translate8
19404
19877
  } from "transformation-matrix";
19405
19878
  import { calculateElbow as calculateElbow2 } from "calculate-elbow";
@@ -19450,7 +19923,7 @@ var NetLabel = class extends PrimitiveComponent2 {
19450
19923
  if (connectedPorts.length > 0) {
19451
19924
  const portPos = connectedPorts[0]._getGlobalSchematicPositionBeforeLayout();
19452
19925
  const parentCenter = applyToPoint17(
19453
- this.parent?.computeSchematicGlobalTransform?.() ?? identity4(),
19926
+ this.parent?.computeSchematicGlobalTransform?.() ?? identity5(),
19454
19927
  { x: 0, y: 0 }
19455
19928
  );
19456
19929
  return translate8(portPos.x - parentCenter.x, portPos.y - parentCenter.y);
@@ -22256,384 +22729,9 @@ var VoltageProbe = class extends PrimitiveComponent2 {
22256
22729
  }
22257
22730
  };
22258
22731
 
22259
- // lib/IsolatedCircuit.ts
22260
- import { su as su5 } from "@tscircuit/circuit-json-util";
22261
- import Debug14 from "debug";
22262
- import { isValidElement as isValidElement2 } from "react";
22263
- import { identity as identity5 } from "transformation-matrix";
22264
-
22265
- // package.json
22266
- var package_default = {
22267
- name: "@tscircuit/core",
22268
- type: "module",
22269
- version: "0.0.1021",
22270
- types: "dist/index.d.ts",
22271
- main: "dist/index.js",
22272
- module: "dist/index.js",
22273
- exports: {
22274
- ".": {
22275
- import: "./dist/index.js",
22276
- types: "./dist/index.d.ts"
22277
- }
22278
- },
22279
- files: [
22280
- "dist"
22281
- ],
22282
- repository: {
22283
- type: "git",
22284
- url: "https://github.com/tscircuit/core"
22285
- },
22286
- scripts: {
22287
- build: "tsup-node index.ts --format esm --dts",
22288
- format: "biome format . --write",
22289
- "measure-bundle": "howfat -r table .",
22290
- "pkg-pr-new-release": "bunx pkg-pr-new publish --comment=off --peerDeps",
22291
- "smoke-test:dist": "bun run scripts/smoke-tests/test-dist-simple-circuit.tsx",
22292
- "build:benchmarking": "bun build --experimental-html ./benchmarking/website/index.html --outdir ./benchmarking-dist",
22293
- "build:benchmarking:watch": `chokidar "./{benchmarking,lib}/**/*.{ts,tsx}" -c 'bun build --experimental-html ./benchmarking/website/index.html --outdir ./benchmarking-dist'`,
22294
- "start:benchmarking": 'concurrently "bun run build:benchmarking:watch" "live-server ./benchmarking-dist"',
22295
- "generate-test-plan": "bun run scripts/generate-test-plan.ts"
22296
- },
22297
- devDependencies: {
22298
- "@biomejs/biome": "^1.8.3",
22299
- "@resvg/resvg-js": "^2.6.2",
22300
- "@tscircuit/alphabet": "0.0.18",
22301
- "@tscircuit/capacity-autorouter": "^0.0.264",
22302
- "@tscircuit/checks": "^0.0.88",
22303
- "@tscircuit/circuit-json-util": "^0.0.77",
22304
- "@tscircuit/common": "^0.0.20",
22305
- "@tscircuit/copper-pour-solver": "^0.0.20",
22306
- "@tscircuit/footprinter": "^0.0.288",
22307
- "@tscircuit/infgrid-ijump-astar": "^0.0.35",
22308
- "@tscircuit/log-soup": "^1.0.2",
22309
- "@tscircuit/matchpack": "^0.0.16",
22310
- "@tscircuit/math-utils": "^0.0.29",
22311
- "@tscircuit/miniflex": "^0.0.4",
22312
- "@tscircuit/ngspice-spice-engine": "^0.0.8",
22313
- "@tscircuit/props": "^0.0.470",
22314
- "@tscircuit/schematic-match-adapt": "^0.0.16",
22315
- "@tscircuit/schematic-trace-solver": "^v0.0.45",
22316
- "@tscircuit/solver-utils": "^0.0.3",
22317
- "@tscircuit/soup-util": "^0.0.41",
22318
- "@types/bun": "^1.2.16",
22319
- "@types/debug": "^4.1.12",
22320
- "@types/react": "^19.1.8",
22321
- "@types/react-dom": "^19.1.6",
22322
- "@types/react-reconciler": "^0.28.9",
22323
- "bpc-graph": "^0.0.57",
22324
- "bun-match-svg": "0.0.12",
22325
- "calculate-elbow": "^0.0.12",
22326
- "chokidar-cli": "^3.0.0",
22327
- "circuit-json": "^0.0.376",
22328
- "circuit-json-to-bpc": "^0.0.13",
22329
- "circuit-json-to-connectivity-map": "^0.0.23",
22330
- "circuit-json-to-gltf": "^0.0.62",
22331
- "circuit-json-to-simple-3d": "^0.0.9",
22332
- "circuit-json-to-spice": "^0.0.33",
22333
- "circuit-to-svg": "^0.0.327",
22334
- concurrently: "^9.1.2",
22335
- "connectivity-map": "^1.0.0",
22336
- debug: "^4.3.6",
22337
- "eecircuit-engine": "^1.5.6",
22338
- flatbush: "^4.5.0",
22339
- "graphics-debug": "^0.0.60",
22340
- howfat: "^0.3.8",
22341
- "live-server": "^1.2.2",
22342
- "looks-same": "^9.0.1",
22343
- minicssgrid: "^0.0.9",
22344
- "pkg-pr-new": "^0.0.37",
22345
- poppygl: "^0.0.16",
22346
- react: "^19.1.0",
22347
- "react-dom": "^19.1.0",
22348
- "schematic-symbols": "^0.0.208",
22349
- spicey: "^0.0.14",
22350
- "ts-expect": "^1.3.0",
22351
- tsup: "^8.2.4"
22352
- },
22353
- peerDependencies: {
22354
- "@tscircuit/capacity-autorouter": "*",
22355
- "@tscircuit/checks": "*",
22356
- "@tscircuit/circuit-json-util": "*",
22357
- "@tscircuit/footprinter": "*",
22358
- "@tscircuit/infgrid-ijump-astar": "*",
22359
- "@tscircuit/math-utils": "*",
22360
- "@tscircuit/props": "*",
22361
- "@tscircuit/schematic-match-adapt": "*",
22362
- "circuit-json-to-bpc": "*",
22363
- "bpc-graph": "*",
22364
- "@tscircuit/matchpack": "*",
22365
- "circuit-json": "*",
22366
- "circuit-json-to-connectivity-map": "*",
22367
- "schematic-symbols": "*",
22368
- typescript: "^5.0.0"
22369
- },
22370
- dependencies: {
22371
- "@flatten-js/core": "^1.6.2",
22372
- "@lume/kiwi": "^0.4.3",
22373
- "calculate-packing": "0.0.68",
22374
- "css-select": "5.1.0",
22375
- "format-si-unit": "^0.0.3",
22376
- nanoid: "^5.0.7",
22377
- "performance-now": "^2.1.0",
22378
- "react-reconciler": "^0.32.0",
22379
- "svg-path-commander": "^2.1.11",
22380
- "transformation-matrix": "^2.16.1",
22381
- zod: "^3.25.67"
22382
- }
22383
- };
22384
-
22385
- // lib/IsolatedCircuit.ts
22386
- var IsolatedCircuit = class {
22387
- firstChild = null;
22388
- children;
22389
- db;
22390
- root = null;
22391
- isRoot = false;
22392
- _schematicDisabledOverride;
22393
- get schematicDisabled() {
22394
- if (this._schematicDisabledOverride !== void 0) {
22395
- return this._schematicDisabledOverride;
22396
- }
22397
- const board = this._getBoard();
22398
- return board?._parsedProps?.schematicDisabled ?? false;
22399
- }
22400
- set schematicDisabled(value) {
22401
- this._schematicDisabledOverride = value;
22402
- }
22403
- pcbDisabled = false;
22404
- pcbRoutingDisabled = false;
22405
- _featureMspSchematicTraceRouting = true;
22406
- /**
22407
- * The IsolatedCircuit name is usually set by the platform, it's not required but
22408
- * if supplied can identify the circuit in certain effects, e.g. it is passed
22409
- * as the display_name parameter for autorouting effects.
22410
- */
22411
- name;
22412
- platform;
22413
- /**
22414
- * Optional URL pointing to where this project is hosted or documented.
22415
- * When provided it is stored in the source_project_metadata.project_url field
22416
- * of the generated Circuit JSON.
22417
- */
22418
- projectUrl;
22419
- _hasRenderedAtleastOnce = false;
22420
- _asyncEffectIdsByPhase = /* @__PURE__ */ new Map();
22421
- _asyncEffectPhaseById = /* @__PURE__ */ new Map();
22422
- constructor({
22423
- platform,
22424
- projectUrl
22425
- } = {}) {
22426
- this.children = [];
22427
- this.db = su5([]);
22428
- this.platform = platform;
22429
- this.projectUrl = projectUrl;
22430
- this.pcbDisabled = platform?.pcbDisabled ?? false;
22431
- }
22432
- add(componentOrElm) {
22433
- let component;
22434
- if (isValidElement2(componentOrElm)) {
22435
- component = createInstanceFromReactElement(componentOrElm);
22436
- } else {
22437
- component = componentOrElm;
22438
- }
22439
- this.children.push(component);
22440
- }
22441
- setPlatform(platform) {
22442
- this.platform = {
22443
- ...this.platform,
22444
- ...platform
22445
- };
22446
- }
22447
- /**
22448
- * Get the main board for this Circuit.
22449
- */
22450
- _getBoard() {
22451
- const directBoard = this.children.find((c) => c.componentName === "Board");
22452
- if (directBoard) {
22453
- return directBoard;
22454
- }
22455
- return void 0;
22456
- }
22457
- _guessRootComponent() {
22458
- if (this.firstChild) return;
22459
- if (this.children.length === 0) {
22460
- throw new Error(
22461
- "Not able to guess root component: IsolatedCircuit has no children (use circuit.add(...))"
22462
- );
22463
- }
22464
- const panels = this.children.filter(
22465
- (child) => child.lowercaseComponentName === "panel"
22466
- );
22467
- if (panels.length > 1) {
22468
- throw new Error("Only one <panel> is allowed per circuit");
22469
- }
22470
- if (panels.length === 1) {
22471
- if (this.children.length !== 1) {
22472
- throw new Error("<panel> must be the root element of the circuit");
22473
- }
22474
- this.firstChild = panels[0];
22475
- return;
22476
- }
22477
- if (this.children.length === 1 && this.children[0].isGroup) {
22478
- this.firstChild = this.children[0];
22479
- return;
22480
- }
22481
- const group = new Group6({ subcircuit: true });
22482
- group.parent = this;
22483
- group.addAll(this.children);
22484
- this.children = [group];
22485
- this.firstChild = group;
22486
- }
22487
- render() {
22488
- if (!this.firstChild) {
22489
- this._guessRootComponent();
22490
- }
22491
- const { firstChild, db } = this;
22492
- if (!firstChild) throw new Error("IsolatedCircuit has no root component");
22493
- firstChild.parent = this;
22494
- firstChild.runRenderCycle();
22495
- this._hasRenderedAtleastOnce = true;
22496
- }
22497
- async renderUntilSettled() {
22498
- const existing = this.db.source_project_metadata.list()?.[0];
22499
- if (!existing) {
22500
- this.db.source_project_metadata.insert({
22501
- software_used_string: `@tscircuit/core@${this.getCoreVersion()}`,
22502
- ...this.projectUrl ? { project_url: this.projectUrl } : {}
22503
- });
22504
- }
22505
- this.render();
22506
- while (this._hasIncompleteAsyncEffects()) {
22507
- await new Promise((resolve) => setTimeout(resolve, 100));
22508
- this.render();
22509
- }
22510
- this.emit("renderComplete");
22511
- }
22512
- _hasIncompleteAsyncEffects() {
22513
- if (this._asyncEffectPhaseById.size > 0) return true;
22514
- return this.children.some((child) => child._hasIncompleteAsyncEffects());
22515
- }
22516
- _hasIncompleteAsyncEffectsForPhase(phase) {
22517
- return (this._asyncEffectIdsByPhase.get(phase)?.size ?? 0) > 0;
22518
- }
22519
- getCircuitJson() {
22520
- if (!this._hasRenderedAtleastOnce) this.render();
22521
- return this.db.toArray();
22522
- }
22523
- toJson() {
22524
- return this.getCircuitJson();
22525
- }
22526
- async getSvg(options) {
22527
- const circuitToSvg = await import("circuit-to-svg").catch((e) => {
22528
- throw new Error(
22529
- `To use circuit.getSvg, you must install the "circuit-to-svg" package.
22530
-
22531
- "${e.message}"`
22532
- );
22533
- });
22534
- if (options.view === "pcb") {
22535
- return circuitToSvg.convertCircuitJsonToPcbSvg(this.getCircuitJson());
22536
- }
22537
- if (options.view === "schematic") {
22538
- return circuitToSvg.convertCircuitJsonToSchematicSvg(
22539
- this.getCircuitJson()
22540
- );
22541
- }
22542
- throw new Error(`Invalid view: ${options.view}`);
22543
- }
22544
- getCoreVersion() {
22545
- const [major, minor, patch] = package_default.version.split(".").map(Number);
22546
- return `${major}.${minor}.${patch + 1}`;
22547
- }
22548
- async preview(previewNameOrOpts) {
22549
- const previewOpts = typeof previewNameOrOpts === "object" ? previewNameOrOpts : { previewName: previewNameOrOpts };
22550
- throw new Error("project.preview is not yet implemented");
22551
- }
22552
- computeSchematicGlobalTransform() {
22553
- return identity5();
22554
- }
22555
- _computePcbGlobalTransformBeforeLayout() {
22556
- return identity5();
22557
- }
22558
- selectAll(selector) {
22559
- this._guessRootComponent();
22560
- return this.firstChild?.selectAll(selector) ?? [];
22561
- }
22562
- selectOne(selector, opts) {
22563
- this._guessRootComponent();
22564
- return this.firstChild?.selectOne(selector, opts) ?? null;
22565
- }
22566
- _eventListeners = {};
22567
- emit(event, ...args) {
22568
- if (event === "asyncEffect:start") {
22569
- this._registerAsyncEffectStart(args[0]);
22570
- } else if (event === "asyncEffect:end") {
22571
- this._registerAsyncEffectEnd(args[0]);
22572
- }
22573
- if (!this._eventListeners[event]) return;
22574
- for (const listener of this._eventListeners[event]) {
22575
- listener(...args);
22576
- }
22577
- }
22578
- on(event, listener) {
22579
- if (!this._eventListeners[event]) {
22580
- this._eventListeners[event] = [];
22581
- }
22582
- this._eventListeners[event].push(listener);
22583
- }
22584
- removeListener(event, listener) {
22585
- if (!this._eventListeners[event]) return;
22586
- this._eventListeners[event] = this._eventListeners[event].filter(
22587
- (l) => l !== listener
22588
- );
22589
- }
22590
- enableDebug(debug11) {
22591
- if (typeof debug11 === "string") {
22592
- Debug14.enable(debug11);
22593
- } else if (debug11 === null || debug11 === false) {
22594
- Debug14.disable();
22595
- }
22596
- }
22597
- getClientOrigin() {
22598
- if (typeof window !== "undefined" && window.location) {
22599
- return window.location.origin;
22600
- }
22601
- if (typeof self !== "undefined" && self.location) {
22602
- return self.location.origin;
22603
- }
22604
- return "";
22605
- }
22606
- _registerAsyncEffectStart(payload) {
22607
- if (!payload?.asyncEffectId || !payload.phase) return;
22608
- const { asyncEffectId, phase } = payload;
22609
- const existingPhase = this._asyncEffectPhaseById.get(asyncEffectId);
22610
- if (existingPhase && existingPhase !== phase) {
22611
- this._asyncEffectIdsByPhase.get(existingPhase)?.delete(asyncEffectId);
22612
- }
22613
- if (!this._asyncEffectIdsByPhase.has(phase)) {
22614
- this._asyncEffectIdsByPhase.set(phase, /* @__PURE__ */ new Set());
22615
- }
22616
- this._asyncEffectIdsByPhase.get(phase).add(asyncEffectId);
22617
- this._asyncEffectPhaseById.set(asyncEffectId, phase);
22618
- }
22619
- _registerAsyncEffectEnd(payload) {
22620
- if (!payload?.asyncEffectId) return;
22621
- const { asyncEffectId } = payload;
22622
- const phase = this._asyncEffectPhaseById.get(asyncEffectId) ?? payload.phase;
22623
- if (phase) {
22624
- const phaseSet = this._asyncEffectIdsByPhase.get(phase);
22625
- phaseSet?.delete(asyncEffectId);
22626
- if (phaseSet && phaseSet.size === 0) {
22627
- this._asyncEffectIdsByPhase.delete(phase);
22628
- }
22629
- }
22630
- this._asyncEffectPhaseById.delete(asyncEffectId);
22631
- }
22632
- };
22633
-
22634
22732
  // lib/RootCircuit.ts
22635
22733
  var RootCircuit = class extends IsolatedCircuit {
22636
- isRoot = true;
22734
+ isRootCircuit = true;
22637
22735
  constructor({
22638
22736
  platform,
22639
22737
  projectUrl
@@ -22888,6 +22986,7 @@ export {
22888
22986
  Keepout,
22889
22987
  Led,
22890
22988
  Mosfet,
22989
+ MountedBoard,
22891
22990
  Net,
22892
22991
  NetLabel,
22893
22992
  NormalComponent3 as NormalComponent,