@tscircuit/core 0.0.1367 → 0.0.1369

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -66742,6 +66742,7 @@ declare class CurrentSource extends NormalComponent<typeof currentSourceProps, "
66742
66742
  }
66743
66743
 
66744
66744
  declare class Ammeter extends NormalComponent<typeof ammeterProps, "pos" | "neg"> {
66745
+ simulation_current_probe_id: string | null;
66745
66746
  get config(): {
66746
66747
  componentName: string;
66747
66748
  schematicSymbolName: BaseSymbolName;
@@ -70109,8 +70110,8 @@ declare class Ammeter extends NormalComponent<typeof ammeterProps, "pos" | "neg"
70109
70110
  color: zod.ZodOptional<zod.ZodString>;
70110
70111
  graphDisplayName: zod.ZodOptional<zod.ZodString>;
70111
70112
  graphCenter: zod.ZodOptional<zod.ZodNumber>;
70112
- graphOffsetDivs: zod.ZodOptional<zod.ZodNumber>;
70113
- graphUnitsPerDiv: zod.ZodOptional<zod.ZodNumber>;
70113
+ graphVerticalOffset: zod.ZodOptional<zod.ZodUnion<[zod.ZodNumber, zod.ZodString]>>;
70114
+ graphCurrentPerDiv: zod.ZodOptional<zod.ZodUnion<[zod.ZodNumber, zod.ZodString]>>;
70114
70115
  }, "strip", zod.ZodTypeAny, {
70115
70116
  name: string;
70116
70117
  connections: Partial<Record<"pin1" | "pin2" | "pos" | "neg", string | readonly string[] | string[]>>;
@@ -70693,8 +70694,8 @@ declare class Ammeter extends NormalComponent<typeof ammeterProps, "pos" | "neg"
70693
70694
  color?: string | undefined;
70694
70695
  graphDisplayName?: string | undefined;
70695
70696
  graphCenter?: number | undefined;
70696
- graphOffsetDivs?: number | undefined;
70697
- graphUnitsPerDiv?: number | undefined;
70697
+ graphVerticalOffset?: string | number | undefined;
70698
+ graphCurrentPerDiv?: string | number | undefined;
70698
70699
  }, {
70699
70700
  name: string;
70700
70701
  connections: Partial<Record<"pin1" | "pin2" | "pos" | "neg", string | readonly string[] | string[]>>;
@@ -71279,8 +71280,8 @@ declare class Ammeter extends NormalComponent<typeof ammeterProps, "pos" | "neg"
71279
71280
  color?: string | undefined;
71280
71281
  graphDisplayName?: string | undefined;
71281
71282
  graphCenter?: number | undefined;
71282
- graphOffsetDivs?: number | undefined;
71283
- graphUnitsPerDiv?: number | undefined;
71283
+ graphVerticalOffset?: string | number | undefined;
71284
+ graphCurrentPerDiv?: string | number | undefined;
71284
71285
  }>;
71285
71286
  sourceFtype: Ftype;
71286
71287
  };
@@ -71289,6 +71290,7 @@ declare class Ammeter extends NormalComponent<typeof ammeterProps, "pos" | "neg"
71289
71290
  initPorts(): void;
71290
71291
  doInitialSourceRender(): void;
71291
71292
  doInitialSimulationRender(): void;
71293
+ doInitialSchematicLayout(): void;
71292
71294
  pos: Port;
71293
71295
  neg: Port;
71294
71296
  }
@@ -77714,6 +77716,7 @@ declare class Footprint extends PrimitiveComponent<typeof footprintProps> {
77714
77716
  componentName: string;
77715
77717
  zodProps: zod.ZodObject<{
77716
77718
  children: zod.ZodOptional<zod.ZodAny>;
77719
+ name: zod.ZodOptional<zod.ZodString>;
77717
77720
  originalLayer: zod.ZodOptional<zod.ZodDefault<zod.ZodEffects<zod.ZodUnion<[zod.ZodEnum<["top", "bottom", "inner1", "inner2", "inner3", "inner4", "inner5", "inner6"]>, zod.ZodObject<{
77718
77721
  name: zod.ZodEnum<["top", "bottom", "inner1", "inner2", "inner3", "inner4", "inner5", "inner6"]>;
77719
77722
  }, "strip", zod.ZodTypeAny, {
@@ -77727,12 +77730,14 @@ declare class Footprint extends PrimitiveComponent<typeof footprintProps> {
77727
77730
  src: zod.ZodOptional<zod.ZodType<_tscircuit_props.FootprintProp, zod.ZodTypeDef, _tscircuit_props.FootprintProp>>;
77728
77731
  insertionDirection: zod.ZodOptional<zod.ZodEnum<["from_above", "from_left", "from_right", "from_front", "from_back"]>>;
77729
77732
  }, "strip", zod.ZodTypeAny, {
77733
+ name?: string | undefined;
77730
77734
  children?: any;
77731
77735
  circuitJson?: any[] | undefined;
77732
77736
  originalLayer?: "top" | "bottom" | "inner1" | "inner2" | "inner3" | "inner4" | "inner5" | "inner6" | undefined;
77733
77737
  src?: _tscircuit_props.FootprintProp | undefined;
77734
77738
  insertionDirection?: "from_above" | "from_left" | "from_right" | "from_front" | "from_back" | undefined;
77735
77739
  }, {
77740
+ name?: string | undefined;
77736
77741
  children?: any;
77737
77742
  circuitJson?: any[] | undefined;
77738
77743
  originalLayer?: "top" | "bottom" | "inner1" | "inner2" | "inner3" | "inner4" | "inner5" | "inner6" | {
@@ -152986,6 +152991,7 @@ declare class AnalogSimulation extends PrimitiveComponent<typeof analogSimulatio
152986
152991
  abstol?: string | number | undefined;
152987
152992
  vntol?: string | number | undefined;
152988
152993
  }>>;
152994
+ graphIndependentAxes: zod.ZodOptional<zod.ZodBoolean>;
152989
152995
  }, "strip", zod.ZodTypeAny, {
152990
152996
  simulationType: "spice_transient_analysis";
152991
152997
  name?: string | undefined;
@@ -152999,6 +153005,7 @@ declare class AnalogSimulation extends PrimitiveComponent<typeof analogSimulatio
152999
153005
  abstol?: string | number | undefined;
153000
153006
  vntol?: string | number | undefined;
153001
153007
  } | undefined;
153008
+ graphIndependentAxes?: boolean | undefined;
153002
153009
  }, {
153003
153010
  name?: string | undefined;
153004
153011
  duration?: string | number | undefined;
@@ -153012,6 +153019,7 @@ declare class AnalogSimulation extends PrimitiveComponent<typeof analogSimulatio
153012
153019
  abstol?: string | number | undefined;
153013
153020
  vntol?: string | number | undefined;
153014
153021
  } | undefined;
153022
+ graphIndependentAxes?: boolean | undefined;
153015
153023
  }>;
153016
153024
  };
153017
153025
  doInitialSimulationRender(): void;
@@ -156390,8 +156398,8 @@ declare class VoltageProbe extends PrimitiveComponent<typeof voltageProbeProps>
156390
156398
  color: z.ZodOptional<z.ZodString>;
156391
156399
  graphDisplayName: z.ZodOptional<z.ZodString>;
156392
156400
  graphCenter: z.ZodOptional<z.ZodNumber>;
156393
- graphOffsetDivs: z.ZodOptional<z.ZodNumber>;
156394
- graphUnitsPerDiv: z.ZodOptional<z.ZodNumber>;
156401
+ graphVerticalOffset: z.ZodOptional<z.ZodUnion<[z.ZodNumber, z.ZodString]>>;
156402
+ graphVoltagePerDiv: z.ZodOptional<z.ZodUnion<[z.ZodNumber, z.ZodString]>>;
156395
156403
  }, "strip", z.ZodTypeAny, {
156396
156404
  connectsTo: string;
156397
156405
  symbol?: _tscircuit_props.SymbolProp | undefined;
@@ -156975,8 +156983,8 @@ declare class VoltageProbe extends PrimitiveComponent<typeof voltageProbeProps>
156975
156983
  referenceTo?: string | undefined;
156976
156984
  graphDisplayName?: string | undefined;
156977
156985
  graphCenter?: number | undefined;
156978
- graphOffsetDivs?: number | undefined;
156979
- graphUnitsPerDiv?: number | undefined;
156986
+ graphVerticalOffset?: string | number | undefined;
156987
+ graphVoltagePerDiv?: string | number | undefined;
156980
156988
  }, {
156981
156989
  connectsTo: string;
156982
156990
  symbol?: _tscircuit_props.SymbolProp | undefined;
@@ -157562,8 +157570,8 @@ declare class VoltageProbe extends PrimitiveComponent<typeof voltageProbeProps>
157562
157570
  referenceTo?: string | undefined;
157563
157571
  graphDisplayName?: string | undefined;
157564
157572
  graphCenter?: number | undefined;
157565
- graphOffsetDivs?: number | undefined;
157566
- graphUnitsPerDiv?: number | undefined;
157573
+ graphVerticalOffset?: string | number | undefined;
157574
+ graphVoltagePerDiv?: string | number | undefined;
157567
157575
  }>;
157568
157576
  };
157569
157577
  doInitialSimulationRender(): void;
package/dist/index.js CHANGED
@@ -5476,6 +5476,14 @@ var Trace3 = class extends PrimitiveComponent2 {
5476
5476
  min_trace_thickness: this._getExplicitTraceThickness()
5477
5477
  });
5478
5478
  this.source_trace_id = trace.source_trace_id;
5479
+ if (!props.name) {
5480
+ db.source_unnamed_trace_warning.insert({
5481
+ message: `${this.getString()} is missing a name. Add a name prop to make the trace easier to identify.`,
5482
+ source_trace_id: trace.source_trace_id,
5483
+ subcircuit_id: this.getSubcircuit()?.subcircuit_id ?? void 0,
5484
+ warning_type: "source_unnamed_trace_warning"
5485
+ });
5486
+ }
5479
5487
  }
5480
5488
  _insertErrorIfTraceIsOutsideBoard(mergedRoute, ports) {
5481
5489
  const { db } = this.root;
@@ -11282,7 +11290,7 @@ var getAllDimensionsForSchematicBox = (params) => {
11282
11290
  x: -sideLengths.bottom / 2 + p.distanceFromOrthogonalEdge,
11283
11291
  len: getLabelLen(p.pinNumber)
11284
11292
  })).filter((p) => p.len > 0);
11285
- const rectsOverlap = (a, b) => Math.min(a.maxX, b.maxX) > Math.max(a.minX, b.minX) && Math.min(a.maxY, b.maxY) > Math.max(a.minY, b.minY);
11293
+ const rectsOverlap2 = (a, b) => Math.min(a.maxX, b.maxX) > Math.max(a.minX, b.minX) && Math.min(a.maxY, b.maxY) > Math.max(a.minY, b.minY);
11286
11294
  const getLeftRect = (label, width) => ({
11287
11295
  minX: -width / 2 + LABEL_EDGE_OFFSET,
11288
11296
  maxX: -width / 2 + LABEL_EDGE_OFFSET + label.len,
@@ -11311,7 +11319,7 @@ var getAllDimensionsForSchematicBox = (params) => {
11311
11319
  let hasTopBottomLabelCollision = false;
11312
11320
  for (const topLabel of topLabels) {
11313
11321
  for (const bottomLabel of bottomLabels) {
11314
- if (rectsOverlap(
11322
+ if (rectsOverlap2(
11315
11323
  getTopRect(topLabel, schHeight),
11316
11324
  getBottomRect(bottomLabel, schHeight)
11317
11325
  )) {
@@ -11328,7 +11336,7 @@ var getAllDimensionsForSchematicBox = (params) => {
11328
11336
  const topRect = getTopRect(topLabel, schHeight);
11329
11337
  for (const leftLabel of leftLabels) {
11330
11338
  const leftRect = getLeftRect(leftLabel, resolvedSchWidth);
11331
- if (rectsOverlap(topRect, leftRect)) {
11339
+ if (rectsOverlap2(topRect, leftRect)) {
11332
11340
  schHeight = Math.max(
11333
11341
  schHeight,
11334
11342
  2 * (leftRect.maxY + LABEL_EDGE_OFFSET + topLabel.len)
@@ -11337,7 +11345,7 @@ var getAllDimensionsForSchematicBox = (params) => {
11337
11345
  }
11338
11346
  for (const rightLabel of rightLabels) {
11339
11347
  const rightRect = getRightRect(rightLabel, resolvedSchWidth);
11340
- if (rectsOverlap(topRect, rightRect)) {
11348
+ if (rectsOverlap2(topRect, rightRect)) {
11341
11349
  schHeight = Math.max(
11342
11350
  schHeight,
11343
11351
  2 * (rightRect.maxY + LABEL_EDGE_OFFSET + topLabel.len)
@@ -11349,7 +11357,7 @@ var getAllDimensionsForSchematicBox = (params) => {
11349
11357
  const bottomRect = getBottomRect(bottomLabel, schHeight);
11350
11358
  for (const leftLabel of leftLabels) {
11351
11359
  const leftRect = getLeftRect(leftLabel, resolvedSchWidth);
11352
- if (rectsOverlap(bottomRect, leftRect)) {
11360
+ if (rectsOverlap2(bottomRect, leftRect)) {
11353
11361
  schHeight = Math.max(
11354
11362
  schHeight,
11355
11363
  2 * (LABEL_EDGE_OFFSET + bottomLabel.len - leftRect.minY)
@@ -11358,7 +11366,7 @@ var getAllDimensionsForSchematicBox = (params) => {
11358
11366
  }
11359
11367
  for (const rightLabel of rightLabels) {
11360
11368
  const rightRect = getRightRect(rightLabel, resolvedSchWidth);
11361
- if (rectsOverlap(bottomRect, rightRect)) {
11369
+ if (rectsOverlap2(bottomRect, rightRect)) {
11362
11370
  schHeight = Math.max(
11363
11371
  schHeight,
11364
11372
  2 * (LABEL_EDGE_OFFSET + bottomLabel.len - rightRect.minY)
@@ -20764,6 +20772,178 @@ var getSpiceyEngine = () => {
20764
20772
  };
20765
20773
  };
20766
20774
 
20775
+ // lib/utils/simulation/parseSimulationGraphValue.ts
20776
+ var SI_PREFIX_MULTIPLIERS = {
20777
+ p: 1e-12,
20778
+ n: 1e-9,
20779
+ u: 1e-6,
20780
+ \u00B5: 1e-6,
20781
+ m: 1e-3,
20782
+ "": 1,
20783
+ k: 1e3,
20784
+ K: 1e3,
20785
+ M: 1e6,
20786
+ G: 1e9
20787
+ };
20788
+ var parseSimulationGraphValue = (value) => {
20789
+ if (value === void 0) return void 0;
20790
+ if (typeof value === "number") return value;
20791
+ const trimmed = value.trim();
20792
+ const match = trimmed.match(
20793
+ /^([+-]?(?:\d+(?:\.\d*)?|\.\d+))\s*([pnumµkKMG]?)/
20794
+ );
20795
+ if (!match) return void 0;
20796
+ const numericValue = Number(match[1]);
20797
+ if (!Number.isFinite(numericValue)) return void 0;
20798
+ return numericValue * (SI_PREFIX_MULTIPLIERS[match[2] ?? ""] ?? 1);
20799
+ };
20800
+
20801
+ // lib/components/primitive-components/Group/getGraphDisplayOverrides.ts
20802
+ var getVoltageProbeGraphDisplayOverrides = (probe) => {
20803
+ const {
20804
+ graphDisplayName,
20805
+ graphCenter,
20806
+ graphVerticalOffset,
20807
+ graphVoltagePerDiv
20808
+ } = probe._parsedProps;
20809
+ return {
20810
+ displayName: graphDisplayName,
20811
+ color: probe.color ?? void 0,
20812
+ center: graphCenter,
20813
+ verticalOffset: parseSimulationGraphValue(graphVerticalOffset),
20814
+ valuePerDiv: parseSimulationGraphValue(graphVoltagePerDiv)
20815
+ };
20816
+ };
20817
+ var getAmmeterGraphDisplayOverrides = (ammeter) => {
20818
+ const {
20819
+ color,
20820
+ graphDisplayName,
20821
+ graphCenter,
20822
+ graphVerticalOffset,
20823
+ graphCurrentPerDiv
20824
+ } = ammeter._parsedProps;
20825
+ return {
20826
+ displayName: graphDisplayName,
20827
+ color,
20828
+ center: graphCenter,
20829
+ verticalOffset: parseSimulationGraphValue(graphVerticalOffset),
20830
+ valuePerDiv: parseSimulationGraphValue(graphCurrentPerDiv)
20831
+ };
20832
+ };
20833
+
20834
+ // lib/components/primitive-components/Group/getFiniteBounds.ts
20835
+ var getFiniteBounds = (values) => {
20836
+ let min = Number.POSITIVE_INFINITY;
20837
+ let max = Number.NEGATIVE_INFINITY;
20838
+ for (const value of values) {
20839
+ if (!Number.isFinite(value)) continue;
20840
+ min = Math.min(min, value);
20841
+ max = Math.max(max, value);
20842
+ }
20843
+ if (min === Number.POSITIVE_INFINITY || max === Number.NEGATIVE_INFINITY) {
20844
+ return null;
20845
+ }
20846
+ return { min, max };
20847
+ };
20848
+
20849
+ // lib/components/primitive-components/Group/getGraphLevels.ts
20850
+ var getGraphLevels = (graph) => graph.type === "simulation_transient_current_graph" ? graph.current_levels : graph.voltage_levels;
20851
+
20852
+ // lib/components/primitive-components/Group/getAutoDisplayScale.ts
20853
+ var DISPLAY_SECTION_HEIGHT_DIVS = 2;
20854
+ var DISPLAY_SECTION_DATA_FILL = 0.8;
20855
+ var getAutoDisplayScale = ({
20856
+ graph,
20857
+ index,
20858
+ graphCount
20859
+ }) => {
20860
+ const bounds = getFiniteBounds(getGraphLevels(graph));
20861
+ if (!bounds) return null;
20862
+ const center = (bounds.min + bounds.max) / 2;
20863
+ const span = bounds.max - bounds.min;
20864
+ const valuePerDiv = span > 0 ? span / (DISPLAY_SECTION_HEIGHT_DIVS * DISPLAY_SECTION_DATA_FILL) : Math.max(Math.abs(center) / 10, Number.EPSILON);
20865
+ return {
20866
+ display_center_value: center,
20867
+ display_center_offset_divs: ((graphCount - 1) / 2 - index) * DISPLAY_SECTION_HEIGHT_DIVS,
20868
+ value_per_div: valuePerDiv
20869
+ };
20870
+ };
20871
+
20872
+ // lib/components/primitive-components/Group/insertIndependentAxisScopeTraces.ts
20873
+ var isDefinedString = (value) => value !== void 0;
20874
+ var getTraceByVoltageProbeId = (traces) => {
20875
+ const traceByVoltageProbeId = /* @__PURE__ */ new Map();
20876
+ for (const trace of traces) {
20877
+ if (trace.simulation_voltage_probe_id) {
20878
+ traceByVoltageProbeId.set(trace.simulation_voltage_probe_id, trace);
20879
+ }
20880
+ }
20881
+ return traceByVoltageProbeId;
20882
+ };
20883
+ var getTraceByCurrentProbeId = (traces) => {
20884
+ const traceByCurrentProbeId = /* @__PURE__ */ new Map();
20885
+ for (const trace of traces) {
20886
+ if (trace.simulation_current_probe_id) {
20887
+ traceByCurrentProbeId.set(trace.simulation_current_probe_id, trace);
20888
+ }
20889
+ }
20890
+ return traceByCurrentProbeId;
20891
+ };
20892
+ var insertIndependentAxisScopeTraces = ({
20893
+ db,
20894
+ graphs,
20895
+ graphDisplayOverridesByProbeId
20896
+ }) => {
20897
+ if (graphs.length === 0) return;
20898
+ const existingScopeTraces = db.simulation_oscilloscope_trace.list();
20899
+ const traceByVoltageProbeId = getTraceByVoltageProbeId(existingScopeTraces);
20900
+ const traceByCurrentProbeId = getTraceByCurrentProbeId(existingScopeTraces);
20901
+ const graphIdsWithTrace = new Set(
20902
+ existingScopeTraces.flatMap((trace) => [
20903
+ trace.simulation_transient_voltage_graph_id,
20904
+ trace.simulation_transient_current_graph_id
20905
+ ]).filter(isDefinedString)
20906
+ );
20907
+ for (const [index, { type, graph }] of graphs.entries()) {
20908
+ const scale2 = getAutoDisplayScale({
20909
+ graph,
20910
+ index,
20911
+ graphCount: graphs.length
20912
+ });
20913
+ if (!scale2) continue;
20914
+ const graphId = type === "voltage" ? graph.simulation_transient_voltage_graph_id : graph.simulation_transient_current_graph_id;
20915
+ if (graphIdsWithTrace.has(graphId)) continue;
20916
+ const sourceProbeId = graph.source_probe_id ?? void 0;
20917
+ const probeTrace = sourceProbeId === void 0 ? void 0 : type === "voltage" ? traceByVoltageProbeId.get(sourceProbeId) : traceByCurrentProbeId.get(sourceProbeId);
20918
+ const overrides = sourceProbeId === void 0 ? void 0 : graphDisplayOverridesByProbeId?.get(sourceProbeId);
20919
+ const valuePerDiv = overrides?.valuePerDiv ?? scale2.value_per_div;
20920
+ const displayCenter = overrides?.center ?? scale2.display_center_value;
20921
+ const displayCenterOffsetDivs = overrides?.verticalOffset !== void 0 && valuePerDiv !== 0 ? overrides.verticalOffset / valuePerDiv : probeTrace?.display_center_offset_divs ?? scale2.display_center_offset_divs;
20922
+ db.simulation_oscilloscope_trace.insert({
20923
+ ...type === "voltage" ? {
20924
+ simulation_transient_voltage_graph_id: graph.simulation_transient_voltage_graph_id,
20925
+ volts_per_div: valuePerDiv
20926
+ } : {
20927
+ simulation_transient_current_graph_id: graph.simulation_transient_current_graph_id,
20928
+ amps_per_div: valuePerDiv
20929
+ },
20930
+ display_name: overrides?.displayName ?? probeTrace?.display_name,
20931
+ color: overrides?.color ?? probeTrace?.color ?? graph.color,
20932
+ display_center_value: displayCenter,
20933
+ display_center_offset_divs: displayCenterOffsetDivs
20934
+ });
20935
+ }
20936
+ };
20937
+
20938
+ // lib/components/primitive-components/Group/isCircuitElementInput.ts
20939
+ var isCircuitElementInput = (element) => Boolean(element && typeof element === "object" && "type" in element);
20940
+
20941
+ // lib/components/primitive-components/Group/isCurrentGraph.ts
20942
+ var isCurrentGraph = (element) => element.type === "simulation_transient_current_graph";
20943
+
20944
+ // lib/components/primitive-components/Group/isVoltageGraph.ts
20945
+ var isVoltageGraph = (element) => element.type === "simulation_transient_voltage_graph";
20946
+
20767
20947
  // lib/components/primitive-components/Group/Group_doInitialSimulationSpiceEngineRender.ts
20768
20948
  var debug11 = Debug13("tscircuit:core:Group_doInitialSimulationSpiceEngineRender");
20769
20949
  function Group_doInitialSimulationSpiceEngineRender(group) {
@@ -20773,6 +20953,7 @@ function Group_doInitialSimulationSpiceEngineRender(group) {
20773
20953
  const analogSims = group.selectAll("analogsimulation");
20774
20954
  if (analogSims.length === 0) return;
20775
20955
  const voltageProbes = group.selectAll("voltageprobe");
20956
+ const ammeters = group.selectAll("ammeter");
20776
20957
  resetSimulationColorState();
20777
20958
  const spiceEngineMap = { ...root.platform?.spiceEngineMap };
20778
20959
  if (!spiceEngineMap.spicey) {
@@ -20796,15 +20977,33 @@ ${spiceString}`);
20796
20977
  graphNameToProbe.set(probe.finalProbeName, probe);
20797
20978
  }
20798
20979
  }
20799
- const voltageProbesById = new Map(
20800
- voltageProbes.filter((probe) => probe.simulation_voltage_probe_id).map((probe) => [probe.simulation_voltage_probe_id, probe])
20801
- );
20802
- const currentProbesById = new Map(
20803
- root.db.simulation_current_probe.list().map((probe) => [probe.simulation_current_probe_id, probe])
20804
- );
20805
- const currentProbesByName = new Map(
20806
- root.db.simulation_current_probe.list().filter((probe) => probe.name).map((probe) => [probe.name, probe])
20807
- );
20980
+ const voltageProbesById = /* @__PURE__ */ new Map();
20981
+ const graphDisplayOverridesByProbeId = /* @__PURE__ */ new Map();
20982
+ for (const probe of voltageProbes) {
20983
+ if (probe.simulation_voltage_probe_id) {
20984
+ voltageProbesById.set(probe.simulation_voltage_probe_id, probe);
20985
+ graphDisplayOverridesByProbeId.set(
20986
+ probe.simulation_voltage_probe_id,
20987
+ getVoltageProbeGraphDisplayOverrides(probe)
20988
+ );
20989
+ }
20990
+ }
20991
+ for (const ammeter of ammeters) {
20992
+ if (ammeter.simulation_current_probe_id) {
20993
+ graphDisplayOverridesByProbeId.set(
20994
+ ammeter.simulation_current_probe_id,
20995
+ getAmmeterGraphDisplayOverrides(ammeter)
20996
+ );
20997
+ }
20998
+ }
20999
+ const currentProbesById = /* @__PURE__ */ new Map();
21000
+ const currentProbesByName = /* @__PURE__ */ new Map();
21001
+ for (const probe of root.db.simulation_current_probe.list()) {
21002
+ currentProbesById.set(probe.simulation_current_probe_id, probe);
21003
+ if (probe.name !== void 0) {
21004
+ currentProbesByName.set(probe.name, probe);
21005
+ }
21006
+ }
20808
21007
  const orderedSimulationProbes = root.db.simulation_voltage_probe.list().filter((probe) => voltageProbesById.has(probe.simulation_voltage_probe_id));
20809
21008
  const graphNamesFromNetlist = getTransientVoltageGraphNamesFromSpiceNetlist(spiceNetlist);
20810
21009
  if (graphNamesFromNetlist.length === orderedSimulationProbes.length) {
@@ -20848,16 +21047,23 @@ ${spiceString}`);
20848
21047
  debug11("No simulation experiment found, skipping result insertion");
20849
21048
  return;
20850
21049
  }
20851
- for (const element of result.simulationResultCircuitJson) {
20852
- if (element.type === "simulation_transient_voltage_graph") {
21050
+ const insertedVoltageGraphs = [];
21051
+ const insertedCurrentGraphs = [];
21052
+ for (const rawElement of result.simulationResultCircuitJson) {
21053
+ if (!isCircuitElementInput(rawElement)) {
21054
+ debug11("Skipping invalid simulation result element");
21055
+ continue;
21056
+ }
21057
+ const element = rawElement;
21058
+ if (isVoltageGraph(element)) {
20853
21059
  element.simulation_experiment_id = simulationExperiment.simulation_experiment_id;
20854
21060
  const probeMatch = element.name ? graphNameToProbe.get(element.name) : void 0;
20855
21061
  if (probeMatch) {
20856
- element.color = probeMatch.color;
20857
- element.source_probe_id = probeMatch.simulation_voltage_probe_id;
21062
+ element.color = probeMatch.color ?? void 0;
21063
+ element.source_probe_id = probeMatch.simulation_voltage_probe_id ?? void 0;
20858
21064
  }
20859
21065
  }
20860
- if (element.type === "simulation_transient_current_graph") {
21066
+ if (isCurrentGraph(element)) {
20861
21067
  element.simulation_experiment_id = simulationExperiment.simulation_experiment_id;
20862
21068
  const probeMatch = (element.source_probe_id ? currentProbesById.get(element.source_probe_id) : void 0) ?? (element.name ? currentProbesByName.get(element.name) : void 0);
20863
21069
  if (probeMatch) {
@@ -20865,17 +21071,27 @@ ${spiceString}`);
20865
21071
  element.source_probe_id = probeMatch.simulation_current_probe_id;
20866
21072
  }
20867
21073
  }
20868
- const elementType = element.type;
20869
- if (elementType && root.db[elementType]) {
20870
- ;
20871
- root.db[elementType].insert(element);
20872
- debug11(`Inserted ${elementType} into database`);
20873
- } else {
20874
- debug11(
20875
- `Warning: Unknown element type ${elementType}, adding to raw db`
20876
- );
20877
- root.db._addElement(element);
21074
+ const insertedElement = root.db.insert(element);
21075
+ if (isVoltageGraph(insertedElement)) {
21076
+ insertedVoltageGraphs.push({
21077
+ type: "voltage",
21078
+ graph: insertedElement
21079
+ });
21080
+ }
21081
+ if (isCurrentGraph(insertedElement)) {
21082
+ insertedCurrentGraphs.push({
21083
+ type: "current",
21084
+ graph: insertedElement
21085
+ });
20878
21086
  }
21087
+ debug11(`Inserted ${element.type} into database`);
21088
+ }
21089
+ if (analogSim._parsedProps.graphIndependentAxes) {
21090
+ insertIndependentAxisScopeTraces({
21091
+ db: root.db,
21092
+ graphs: [...insertedVoltageGraphs, ...insertedCurrentGraphs],
21093
+ graphDisplayOverridesByProbeId
21094
+ });
20879
21095
  }
20880
21096
  group._markDirty("SimulationSpiceEngineRender");
20881
21097
  } catch (error) {
@@ -24359,7 +24575,7 @@ import { identity as identity5 } from "transformation-matrix";
24359
24575
  var package_default = {
24360
24576
  name: "@tscircuit/core",
24361
24577
  type: "module",
24362
- version: "0.0.1366",
24578
+ version: "0.0.1368",
24363
24579
  types: "dist/index.d.ts",
24364
24580
  main: "dist/index.js",
24365
24581
  module: "dist/index.js",
@@ -24408,7 +24624,7 @@ var package_default = {
24408
24624
  "@tscircuit/math-utils": "^0.0.36",
24409
24625
  "@tscircuit/miniflex": "^0.0.4",
24410
24626
  "@tscircuit/ngspice-spice-engine": "^0.0.18",
24411
- "@tscircuit/props": "^0.0.561",
24627
+ "@tscircuit/props": "^0.0.565",
24412
24628
  "@tscircuit/schematic-match-adapt": "^0.0.18",
24413
24629
  "@tscircuit/schematic-trace-solver": "^0.0.72",
24414
24630
  "@tscircuit/solver-utils": "^0.0.16",
@@ -24422,7 +24638,7 @@ var package_default = {
24422
24638
  "bun-match-svg": "0.0.12",
24423
24639
  "calculate-elbow": "^0.0.12",
24424
24640
  "chokidar-cli": "^3.0.0",
24425
- "circuit-json": "^0.0.442",
24641
+ "circuit-json": "^0.0.443",
24426
24642
  "circuit-json-to-bpc": "^0.0.13",
24427
24643
  "circuit-json-to-connectivity-map": "^0.0.23",
24428
24644
  "circuit-json-to-gltf": "^0.0.105",
@@ -27092,7 +27308,158 @@ var CurrentSource = class extends NormalComponent3 {
27092
27308
  // lib/components/normal-components/Ammeter.ts
27093
27309
  import { ammeterProps } from "@tscircuit/props";
27094
27310
  import { symbols as symbols5 } from "schematic-symbols";
27311
+
27312
+ // lib/components/normal-components/Ammeter_doInitialSchematicLayout.ts
27313
+ var PLACEMENT_MARGIN = 0.25;
27314
+ var rectForComponent = (component, margin) => ({
27315
+ left: component.center.x - component.size.width / 2 - margin,
27316
+ right: component.center.x + component.size.width / 2 + margin,
27317
+ bottom: component.center.y - component.size.height / 2 - margin,
27318
+ top: component.center.y + component.size.height / 2 + margin
27319
+ });
27320
+ var rectsOverlap = (a, b) => a.left < b.right && a.right > b.left && a.bottom < b.top && a.top > b.bottom;
27321
+ var getCandidateCenters = ({
27322
+ baseCenter,
27323
+ size
27324
+ }) => {
27325
+ const xStep = size.width + PLACEMENT_MARGIN * 2;
27326
+ const yStep = size.height + PLACEMENT_MARGIN * 2;
27327
+ return [
27328
+ baseCenter,
27329
+ { x: baseCenter.x, y: baseCenter.y + yStep },
27330
+ { x: baseCenter.x, y: baseCenter.y - yStep },
27331
+ { x: baseCenter.x + xStep, y: baseCenter.y },
27332
+ { x: baseCenter.x - xStep, y: baseCenter.y },
27333
+ { x: baseCenter.x + xStep, y: baseCenter.y + yStep },
27334
+ { x: baseCenter.x - xStep, y: baseCenter.y + yStep },
27335
+ { x: baseCenter.x + xStep, y: baseCenter.y - yStep },
27336
+ { x: baseCenter.x - xStep, y: baseCenter.y - yStep },
27337
+ { x: baseCenter.x, y: baseCenter.y + yStep * 2 },
27338
+ { x: baseCenter.x, y: baseCenter.y - yStep * 2 }
27339
+ ];
27340
+ };
27341
+ var getConnectedSchematicPort = ({
27342
+ ammeterSourcePortId,
27343
+ schematicPorts,
27344
+ sourceTraces
27345
+ }) => {
27346
+ for (const sourceTrace of sourceTraces) {
27347
+ if (!sourceTrace.connected_source_port_ids.includes(ammeterSourcePortId)) {
27348
+ continue;
27349
+ }
27350
+ const connectedSourcePortId = sourceTrace.connected_source_port_ids.find(
27351
+ (sourcePortId) => sourcePortId !== ammeterSourcePortId
27352
+ );
27353
+ if (connectedSourcePortId === void 0) continue;
27354
+ const schematicPort = schematicPorts.find(
27355
+ (port) => port.source_port_id === connectedSourcePortId
27356
+ );
27357
+ if (schematicPort) return schematicPort;
27358
+ }
27359
+ return null;
27360
+ };
27361
+ var midpoint = (ports) => ({
27362
+ x: ports.reduce((sum, port) => sum + port.center.x, 0) / ports.length,
27363
+ y: ports.reduce((sum, port) => sum + port.center.y, 0) / ports.length
27364
+ });
27365
+ var shiftAmmeterSchematicElements = ({
27366
+ ammeter,
27367
+ db,
27368
+ oldCenter,
27369
+ newCenter
27370
+ }) => {
27371
+ const schematicComponentId = ammeter.schematic_component_id;
27372
+ if (!schematicComponentId) return;
27373
+ const deltaX = newCenter.x - oldCenter.x;
27374
+ const deltaY = newCenter.y - oldCenter.y;
27375
+ if (deltaX === 0 && deltaY === 0) return;
27376
+ db.schematic_component.update(schematicComponentId, {
27377
+ center: newCenter
27378
+ });
27379
+ for (const port of db.schematic_port.list({
27380
+ schematic_component_id: schematicComponentId
27381
+ })) {
27382
+ db.schematic_port.update(port.schematic_port_id, {
27383
+ center: {
27384
+ x: port.center.x + deltaX,
27385
+ y: port.center.y + deltaY
27386
+ }
27387
+ });
27388
+ }
27389
+ for (const text of db.schematic_text.list({
27390
+ schematic_component_id: schematicComponentId
27391
+ })) {
27392
+ db.schematic_text.update(text.schematic_text_id, {
27393
+ position: {
27394
+ x: text.position.x + deltaX,
27395
+ y: text.position.y + deltaY
27396
+ }
27397
+ });
27398
+ }
27399
+ updateSchematicPrimitivesForLayoutShift({
27400
+ db,
27401
+ schematicComponentId,
27402
+ deltaX,
27403
+ deltaY
27404
+ });
27405
+ };
27406
+ var Ammeter_doInitialSchematicLayout = (ammeter) => {
27407
+ const { root } = ammeter;
27408
+ if (!root || root.schematicDisabled) return;
27409
+ if (!ammeter.schematic_component_id) return;
27410
+ if (ammeter._parsedProps.schX !== void 0 || ammeter._parsedProps.schY !== void 0) {
27411
+ return;
27412
+ }
27413
+ if (ammeter.getGroup()?._getSchematicLayoutMode() !== "relative") return;
27414
+ const { db } = root;
27415
+ const schematicComponent = db.schematic_component.get(
27416
+ ammeter.schematic_component_id
27417
+ );
27418
+ if (!schematicComponent) return;
27419
+ const ammeterSourcePortIds = [
27420
+ ammeter.portMap.pos.source_port_id,
27421
+ ammeter.portMap.neg.source_port_id
27422
+ ].filter(
27423
+ (sourcePortId) => typeof sourcePortId === "string"
27424
+ );
27425
+ if (ammeterSourcePortIds.length === 0) return;
27426
+ const schematicPorts = db.schematic_port.list();
27427
+ const sourceTraces = db.source_trace.list();
27428
+ const connectedSchematicPorts = ammeterSourcePortIds.map(
27429
+ (ammeterSourcePortId) => getConnectedSchematicPort({
27430
+ ammeterSourcePortId,
27431
+ schematicPorts,
27432
+ sourceTraces
27433
+ })
27434
+ ).filter((port) => port !== null);
27435
+ if (connectedSchematicPorts.length === 0) return;
27436
+ const baseCenter = midpoint(connectedSchematicPorts);
27437
+ const obstacles = db.schematic_component.list().filter(
27438
+ (component) => component.schematic_component_id !== schematicComponent.schematic_component_id && !component.is_schematic_group && component.schematic_sheet_id === schematicComponent.schematic_sheet_id
27439
+ ).map((component) => rectForComponent(component, PLACEMENT_MARGIN));
27440
+ const bestCenter = getCandidateCenters({
27441
+ baseCenter,
27442
+ size: schematicComponent.size
27443
+ }).find((candidateCenter) => {
27444
+ const candidateRect = rectForComponent(
27445
+ { ...schematicComponent, center: candidateCenter },
27446
+ PLACEMENT_MARGIN
27447
+ );
27448
+ return !obstacles.some(
27449
+ (obstacle) => rectsOverlap(candidateRect, obstacle)
27450
+ );
27451
+ }) ?? baseCenter;
27452
+ shiftAmmeterSchematicElements({
27453
+ ammeter,
27454
+ db,
27455
+ oldCenter: schematicComponent.center,
27456
+ newCenter: bestCenter
27457
+ });
27458
+ };
27459
+
27460
+ // lib/components/normal-components/Ammeter.ts
27095
27461
  var Ammeter = class extends NormalComponent3 {
27462
+ simulation_current_probe_id = null;
27096
27463
  get config() {
27097
27464
  return {
27098
27465
  componentName: "Ammeter",
@@ -27150,8 +27517,8 @@ var Ammeter = class extends NormalComponent3 {
27150
27517
  color,
27151
27518
  graphDisplayName,
27152
27519
  graphCenter,
27153
- graphOffsetDivs,
27154
- graphUnitsPerDiv
27520
+ graphVerticalOffset,
27521
+ graphCurrentPerDiv
27155
27522
  } = this._parsedProps;
27156
27523
  const posPort = this.portMap.pos;
27157
27524
  const negPort = this.portMap.neg;
@@ -27164,18 +27531,24 @@ var Ammeter = class extends NormalComponent3 {
27164
27531
  subcircuit_id: this.getSubcircuit()?.subcircuit_id ?? void 0,
27165
27532
  color
27166
27533
  });
27167
- const hasGraphDisplayProps = graphDisplayName !== void 0 || graphCenter !== void 0 || graphOffsetDivs !== void 0 || graphUnitsPerDiv !== void 0;
27534
+ this.simulation_current_probe_id = simulation_current_probe_id;
27535
+ const hasGraphDisplayProps = graphDisplayName !== void 0 || graphCenter !== void 0 || graphVerticalOffset !== void 0 || graphCurrentPerDiv !== void 0;
27168
27536
  if (hasGraphDisplayProps) {
27537
+ const graphCurrentPerDivValue = parseSimulationGraphValue(graphCurrentPerDiv);
27538
+ const graphVerticalOffsetValue = parseSimulationGraphValue(graphVerticalOffset);
27169
27539
  db.simulation_oscilloscope_trace.insert({
27170
27540
  simulation_current_probe_id,
27171
27541
  display_name: graphDisplayName,
27172
27542
  color,
27173
27543
  display_center_value: graphCenter,
27174
- display_center_offset_divs: graphOffsetDivs,
27175
- amps_per_div: graphUnitsPerDiv
27544
+ amps_per_div: graphCurrentPerDivValue,
27545
+ display_center_offset_divs: graphVerticalOffsetValue !== void 0 && graphCurrentPerDivValue !== void 0 && graphCurrentPerDivValue !== 0 ? graphVerticalOffsetValue / graphCurrentPerDivValue : void 0
27176
27546
  });
27177
27547
  }
27178
27548
  }
27549
+ doInitialSchematicLayout() {
27550
+ Ammeter_doInitialSchematicLayout(this);
27551
+ }
27179
27552
  pos = this.portMap.pos;
27180
27553
  neg = this.portMap.neg;
27181
27554
  };
@@ -31142,8 +31515,8 @@ var VoltageProbe = class extends PrimitiveComponent2 {
31142
31515
  color,
31143
31516
  graphDisplayName,
31144
31517
  graphCenter,
31145
- graphOffsetDivs,
31146
- graphUnitsPerDiv
31518
+ graphVerticalOffset,
31519
+ graphVoltagePerDiv
31147
31520
  } = this._parsedProps;
31148
31521
  const subcircuit = this.getSubcircuit();
31149
31522
  if (!subcircuit) {
@@ -31221,15 +31594,17 @@ var VoltageProbe = class extends PrimitiveComponent2 {
31221
31594
  color: this.color
31222
31595
  });
31223
31596
  this.simulation_voltage_probe_id = simulation_voltage_probe_id;
31224
- const hasGraphDisplayProps = graphDisplayName !== void 0 || graphCenter !== void 0 || graphOffsetDivs !== void 0 || graphUnitsPerDiv !== void 0;
31597
+ const hasGraphDisplayProps = graphDisplayName !== void 0 || graphCenter !== void 0 || graphVerticalOffset !== void 0 || graphVoltagePerDiv !== void 0;
31225
31598
  if (hasGraphDisplayProps) {
31599
+ const graphVoltagePerDivValue = parseSimulationGraphValue(graphVoltagePerDiv);
31600
+ const graphVerticalOffsetValue = parseSimulationGraphValue(graphVerticalOffset);
31226
31601
  db.simulation_oscilloscope_trace.insert({
31227
31602
  simulation_voltage_probe_id,
31228
31603
  display_name: graphDisplayName,
31229
31604
  color: color ?? void 0,
31230
31605
  display_center_value: graphCenter,
31231
- display_center_offset_divs: graphOffsetDivs,
31232
- volts_per_div: graphUnitsPerDiv
31606
+ volts_per_div: graphVoltagePerDivValue,
31607
+ display_center_offset_divs: graphVerticalOffsetValue !== void 0 && graphVoltagePerDivValue !== void 0 && graphVoltagePerDivValue !== 0 ? graphVerticalOffsetValue / graphVoltagePerDivValue : void 0
31233
31608
  });
31234
31609
  }
31235
31610
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@tscircuit/core",
3
3
  "type": "module",
4
- "version": "0.0.1367",
4
+ "version": "0.0.1369",
5
5
  "types": "dist/index.d.ts",
6
6
  "main": "dist/index.js",
7
7
  "module": "dist/index.js",
@@ -50,7 +50,7 @@
50
50
  "@tscircuit/math-utils": "^0.0.36",
51
51
  "@tscircuit/miniflex": "^0.0.4",
52
52
  "@tscircuit/ngspice-spice-engine": "^0.0.18",
53
- "@tscircuit/props": "^0.0.561",
53
+ "@tscircuit/props": "^0.0.565",
54
54
  "@tscircuit/schematic-match-adapt": "^0.0.18",
55
55
  "@tscircuit/schematic-trace-solver": "^0.0.72",
56
56
  "@tscircuit/solver-utils": "^0.0.16",
@@ -64,7 +64,7 @@
64
64
  "bun-match-svg": "0.0.12",
65
65
  "calculate-elbow": "^0.0.12",
66
66
  "chokidar-cli": "^3.0.0",
67
- "circuit-json": "^0.0.442",
67
+ "circuit-json": "^0.0.443",
68
68
  "circuit-json-to-bpc": "^0.0.13",
69
69
  "circuit-json-to-connectivity-map": "^0.0.23",
70
70
  "circuit-json-to-gltf": "^0.0.105",