@tscircuit/schematic-viewer 2.0.91 → 2.0.92

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 CHANGED
@@ -1,3 +1,179 @@
1
+ // lib/components/StyleAnalysisDialog.tsx
2
+ import * as Dialog from "@radix-ui/react-dialog";
3
+
4
+ // lib/utils/load-style-analyzer.ts
5
+ var STYLE_ANALYZER_URL = "https://jscdn.tscircuit.com/@tscircuit/circuit-json-schematic-placement-analysis/latest/dist/browser.js";
6
+ var styleAnalyzerLoader = {
7
+ async load() {
8
+ const analyzer = await import(
9
+ /* @vite-ignore */
10
+ /* webpackIgnore: true */
11
+ STYLE_ANALYZER_URL
12
+ );
13
+ if (typeof analyzer.createSchematicPlacementIssueArtifacts !== "function") {
14
+ throw new Error(
15
+ "The style analyzer module does not export its analysis function."
16
+ );
17
+ }
18
+ return analyzer;
19
+ }
20
+ };
21
+
22
+ // lib/components/StyleAnalysisDialog.tsx
23
+ import { useEffect, useState } from "react";
24
+
25
+ // lib/utils/z-index-map.ts
26
+ var zIndexMap = {
27
+ contextMenu: 110,
28
+ styleAnalysis: 120,
29
+ viewMenu: 55,
30
+ viewMenuIcon: 48,
31
+ clickToInteractOverlay: 100,
32
+ schematicComponentDetailsTooltip: 105,
33
+ schematicComponentHoverOutline: 47,
34
+ schematicPortHoverOutline: 48,
35
+ schematicSearch: 101
36
+ };
37
+
38
+ // lib/components/StyleAnalysisDialog.tsx
39
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
40
+ var StyleAnalysisDialog = ({
41
+ circuitJson,
42
+ onClose
43
+ }) => {
44
+ const [state, setState] = useState({ status: "loading" });
45
+ useEffect(() => {
46
+ let cancelled = false;
47
+ const timer = window.setTimeout(async () => {
48
+ try {
49
+ const { createSchematicPlacementIssueArtifacts } = await styleAnalyzerLoader.load();
50
+ if (cancelled) return;
51
+ const artifacts = createSchematicPlacementIssueArtifacts(circuitJson);
52
+ if (!cancelled) setState({ status: "complete", artifacts });
53
+ } catch (error) {
54
+ if (!cancelled) {
55
+ setState({
56
+ status: "error",
57
+ message: error instanceof Error ? error.message : String(error)
58
+ });
59
+ }
60
+ }
61
+ }, 0);
62
+ return () => {
63
+ cancelled = true;
64
+ window.clearTimeout(timer);
65
+ };
66
+ }, [circuitJson]);
67
+ return /* @__PURE__ */ jsx(Dialog.Root, { open: true, onOpenChange: (open) => !open && onClose(), children: /* @__PURE__ */ jsxs(Dialog.Portal, { children: [
68
+ /* @__PURE__ */ jsx(
69
+ Dialog.Overlay,
70
+ {
71
+ style: {
72
+ position: "fixed",
73
+ inset: 0,
74
+ background: "#0008",
75
+ zIndex: zIndexMap.styleAnalysis
76
+ }
77
+ }
78
+ ),
79
+ /* @__PURE__ */ jsxs(
80
+ Dialog.Content,
81
+ {
82
+ style: {
83
+ position: "fixed",
84
+ top: "5vh",
85
+ left: "50%",
86
+ transform: "translateX(-50%)",
87
+ width: "min(1000px, 94vw)",
88
+ maxHeight: "90vh",
89
+ overflowY: "auto",
90
+ boxSizing: "border-box",
91
+ padding: 24,
92
+ borderRadius: 12,
93
+ background: "#fafafa",
94
+ color: "#171717",
95
+ fontFamily: "system-ui, sans-serif",
96
+ boxShadow: "0 20px 60px #0005",
97
+ zIndex: zIndexMap.styleAnalysis
98
+ },
99
+ children: [
100
+ /* @__PURE__ */ jsxs(
101
+ "div",
102
+ {
103
+ style: {
104
+ display: "flex",
105
+ alignItems: "center",
106
+ justifyContent: "space-between",
107
+ gap: 16
108
+ },
109
+ children: [
110
+ /* @__PURE__ */ jsx(Dialog.Title, { style: { margin: 0, fontSize: 22 }, children: "Style Analysis" }),
111
+ /* @__PURE__ */ jsx(Dialog.Close, { style: { cursor: "pointer", padding: "6px 12px" }, children: "Close" })
112
+ ]
113
+ }
114
+ ),
115
+ /* @__PURE__ */ jsx(Dialog.Description, { style: { color: "#525252" }, children: "Placement and style issues across all schematic sheets. Each image highlights one issue with its description below." }),
116
+ state.status === "loading" && /* @__PURE__ */ jsx("p", { role: "status", children: "Running style analysis\u2026" }),
117
+ state.status === "error" && /* @__PURE__ */ jsxs("p", { role: "alert", children: [
118
+ "Style analysis failed: ",
119
+ state.message
120
+ ] }),
121
+ state.status === "complete" && /* @__PURE__ */ jsxs(Fragment, { children: [
122
+ /* @__PURE__ */ jsx("p", { role: "status", children: state.artifacts.length === 0 ? "No style issues found." : `${state.artifacts.length} style ${state.artifacts.length === 1 ? "issue" : "issues"} found.` }),
123
+ state.artifacts.map((artifact) => /* @__PURE__ */ jsxs(
124
+ "section",
125
+ {
126
+ style: {
127
+ marginTop: 24,
128
+ border: "1px solid #ddd",
129
+ borderRadius: 8,
130
+ overflow: "hidden",
131
+ background: "white"
132
+ },
133
+ children: [
134
+ /* @__PURE__ */ jsxs("h3", { style: { margin: 16, fontSize: 16 }, children: [
135
+ artifact.issueIndex + 1,
136
+ ".",
137
+ " ",
138
+ artifact.issue.lineItemType.replace(
139
+ /([a-z])([A-Z])/g,
140
+ "$1 $2"
141
+ ),
142
+ artifact.schematicSheetId && /* @__PURE__ */ jsxs(
143
+ "small",
144
+ {
145
+ style: {
146
+ display: "block",
147
+ marginTop: 4,
148
+ color: "#525252"
149
+ },
150
+ children: [
151
+ "Sheet: ",
152
+ artifact.schematicSheetId
153
+ ]
154
+ }
155
+ )
156
+ ] }),
157
+ /* @__PURE__ */ jsx(
158
+ "img",
159
+ {
160
+ src: `data:image/svg+xml;charset=utf-8,${encodeURIComponent(artifact.content)}`,
161
+ alt: artifact.descriptionXml,
162
+ loading: "lazy",
163
+ style: { display: "block", width: "100%", height: "auto" }
164
+ }
165
+ )
166
+ ]
167
+ },
168
+ artifact.issueIndex
169
+ ))
170
+ ] })
171
+ ]
172
+ }
173
+ )
174
+ ] }) });
175
+ };
176
+
1
177
  // lib/components/SchematicViewer.tsx
2
178
  import { su as su4 } from "@tscircuit/soup-util";
3
179
  import {
@@ -44,7 +220,7 @@ var setStoredString = (key, value) => {
44
220
  };
45
221
 
46
222
  // lib/hooks/useSchematicGroupsOverlay.ts
47
- import { useEffect } from "react";
223
+ import { useEffect as useEffect2 } from "react";
48
224
  import { su } from "@tscircuit/soup-util";
49
225
  var GROUP_COLORS = [
50
226
  "#8B0000",
@@ -70,7 +246,7 @@ var GROUP_COLORS = [
70
246
  ];
71
247
  var useSchematicGroupsOverlay = (options) => {
72
248
  const { svgDivRef, circuitJson, circuitJsonKey, showGroups } = options;
73
- useEffect(() => {
249
+ useEffect2(() => {
74
250
  if (svgDivRef.current) {
75
251
  const existingOverlays = svgDivRef.current.querySelectorAll(
76
252
  ".schematic-group-overlay"
@@ -313,7 +489,7 @@ function calculateGroupBounds(components, svg) {
313
489
 
314
490
  // lib/hooks/useSchematicNetHover.ts
315
491
  import { su as su2 } from "@tscircuit/soup-util";
316
- import { useEffect as useEffect2 } from "react";
492
+ import { useEffect as useEffect3 } from "react";
317
493
  var FADED_CLASS = "sch-net-faded";
318
494
  var TRACE_SELECTOR = "g.trace[data-subcircuit-connectivity-map-key], g.trace-overlays[data-subcircuit-connectivity-map-key]";
319
495
  var NET_LABEL_SELECTOR = "[data-schematic-net-label-id]";
@@ -323,7 +499,7 @@ var useSchematicNetHover = ({
323
499
  circuitJsonKey,
324
500
  enabled
325
501
  }) => {
326
- useEffect2(() => {
502
+ useEffect3(() => {
327
503
  const svgDiv = svgDivRef.current;
328
504
  if (!enabled || !svgDiv) return;
329
505
  const { componentIdToKeys, netLabelIdToKey } = buildNetRegistry(circuitJson);
@@ -431,7 +607,7 @@ function buildNetRegistry(circuitJson) {
431
607
  }
432
608
 
433
609
  // lib/hooks/useSchematicSearch.ts
434
- import { useCallback as useCallback2, useEffect as useEffect3, useMemo, useRef, useState } from "react";
610
+ import { useCallback as useCallback2, useEffect as useEffect4, useMemo, useRef, useState as useState2 } from "react";
435
611
  import { fromString } from "transformation-matrix";
436
612
 
437
613
  // lib/utils/get-schematic-search-results.ts
@@ -637,8 +813,8 @@ var useSchematicSearch = ({
637
813
  setSvgToScreenProjection,
638
814
  setIsInteractionEnabled
639
815
  }) => {
640
- const [searchQuery, setSearchQuery] = useState("");
641
- const [pendingSearchResult, setPendingSearchResult] = useState(null);
816
+ const [searchQuery, setSearchQuery] = useState2("");
817
+ const [pendingSearchResult, setPendingSearchResult] = useState2(null);
642
818
  const searchAnimationTimerRef = useRef(
643
819
  null
644
820
  );
@@ -733,7 +909,7 @@ var useSchematicSearch = ({
733
909
  );
734
910
  }
735
911
  }, [svgDivRef]);
736
- useEffect3(() => {
912
+ useEffect4(() => {
737
913
  if (!pendingSearchResult || !svgString) return;
738
914
  const frame = requestAnimationFrame(() => {
739
915
  if (focusSearchResult(pendingSearchResult)) {
@@ -742,11 +918,11 @@ var useSchematicSearch = ({
742
918
  });
743
919
  return () => cancelAnimationFrame(frame);
744
920
  }, [focusSearchResult, pendingSearchResult, svgString]);
745
- useEffect3(() => {
921
+ useEffect4(() => {
746
922
  if (searchQuery) return;
747
923
  svgDivRef.current?.querySelectorAll(".schematic-search-match").forEach((element) => element.classList.remove("schematic-search-match"));
748
924
  }, [searchQuery, svgDivRef]);
749
- useEffect3(
925
+ useEffect4(
750
926
  () => () => {
751
927
  if (searchAnimationTimerRef.current) {
752
928
  clearTimeout(searchAnimationTimerRef.current);
@@ -771,16 +947,16 @@ var enableDebug = () => {
771
947
  };
772
948
 
773
949
  // lib/components/SchematicViewer.tsx
774
- import { useCallback as useCallback7, useEffect as useEffect11, useMemo as useMemo6, useRef as useRef8, useState as useState8 } from "react";
950
+ import { useCallback as useCallback7, useEffect as useEffect12, useMemo as useMemo6, useRef as useRef8, useState as useState9 } from "react";
775
951
  import { toString as transformToString } from "transformation-matrix";
776
952
  import { useMouseMatrixTransform } from "use-mouse-matrix-transform";
777
953
 
778
954
  // lib/hooks/use-resize-handling.ts
779
- import { useEffect as useEffect4, useState as useState2 } from "react";
955
+ import { useEffect as useEffect5, useState as useState3 } from "react";
780
956
  var useResizeHandling = (containerRef) => {
781
- const [containerWidth, setContainerWidth] = useState2(0);
782
- const [containerHeight, setContainerHeight] = useState2(0);
783
- useEffect4(() => {
957
+ const [containerWidth, setContainerWidth] = useState3(0);
958
+ const [containerHeight, setContainerHeight] = useState3(0);
959
+ useEffect5(() => {
784
960
  if (!containerRef.current) return;
785
961
  const updateDimensions = () => {
786
962
  const rect = containerRef.current?.getBoundingClientRect();
@@ -800,12 +976,12 @@ var useResizeHandling = (containerRef) => {
800
976
  };
801
977
 
802
978
  // lib/hooks/useContextMenu.ts
803
- import { useCallback as useCallback3, useEffect as useEffect5, useRef as useRef2, useState as useState3 } from "react";
979
+ import { useCallback as useCallback3, useEffect as useEffect6, useRef as useRef2, useState as useState4 } from "react";
804
980
  var LONG_PRESS_DURATION_MS = 600;
805
981
  var MOVEMENT_THRESHOLD_PX = 10;
806
982
  var useContextMenu = ({ containerRef }) => {
807
- const [menuVisible, setMenuVisible] = useState3(false);
808
- const [menuPos, setMenuPos] = useState3({ x: 0, y: 0 });
983
+ const [menuVisible, setMenuVisible] = useState4(false);
984
+ const [menuPos, setMenuPos] = useState4({ x: 0, y: 0 });
809
985
  const menuRef = useRef2(null);
810
986
  const interactionOriginRef = useRef2(null);
811
987
  const longPressTimeoutRef = useRef2(null);
@@ -880,7 +1056,7 @@ var useContextMenu = ({ containerRef }) => {
880
1056
  if (isInRadixPortal) return;
881
1057
  setMenuVisible(false);
882
1058
  }, []);
883
- useEffect5(() => {
1059
+ useEffect6(() => {
884
1060
  if (!menuVisible) return;
885
1061
  document.addEventListener("mousedown", handleClickAway);
886
1062
  document.addEventListener("touchstart", handleClickAway);
@@ -889,7 +1065,7 @@ var useContextMenu = ({ containerRef }) => {
889
1065
  document.removeEventListener("touchstart", handleClickAway);
890
1066
  };
891
1067
  }, [handleClickAway, menuVisible]);
892
- useEffect5(() => clearLongPressTimeout, [clearLongPressTimeout]);
1068
+ useEffect6(() => clearLongPressTimeout, [clearLongPressTimeout]);
893
1069
  return {
894
1070
  menuVisible,
895
1071
  menuPos,
@@ -1067,28 +1243,16 @@ var getFootprintPreviewUrl = (footprintPreviewCircuitJson, viewBox) => {
1067
1243
  return url.toString();
1068
1244
  };
1069
1245
 
1070
- // lib/utils/z-index-map.ts
1071
- var zIndexMap = {
1072
- contextMenu: 110,
1073
- viewMenu: 55,
1074
- viewMenuIcon: 48,
1075
- clickToInteractOverlay: 100,
1076
- schematicComponentDetailsTooltip: 105,
1077
- schematicComponentHoverOutline: 47,
1078
- schematicPortHoverOutline: 48,
1079
- schematicSearch: 101
1080
- };
1081
-
1082
1246
  // lib/components/MouseTracker.tsx
1083
1247
  import {
1084
1248
  createContext,
1085
1249
  useCallback as useCallback4,
1086
1250
  useContext,
1087
- useEffect as useEffect6,
1251
+ useEffect as useEffect7,
1088
1252
  useMemo as useMemo2,
1089
1253
  useRef as useRef3
1090
1254
  } from "react";
1091
- import { Fragment, jsx } from "react/jsx-runtime";
1255
+ import { Fragment as Fragment2, jsx as jsx2 } from "react/jsx-runtime";
1092
1256
  var MouseTrackerContext = createContext(null);
1093
1257
  var DRAG_THRESHOLD_PX = 5;
1094
1258
  var boundsAreEqual = (a, b) => {
@@ -1099,9 +1263,9 @@ var boundsAreEqual = (a, b) => {
1099
1263
  var MouseTracker = ({ children }) => {
1100
1264
  const existingContext = useContext(MouseTrackerContext);
1101
1265
  if (existingContext) {
1102
- return /* @__PURE__ */ jsx(Fragment, { children });
1266
+ return /* @__PURE__ */ jsx2(Fragment2, { children });
1103
1267
  }
1104
- return /* @__PURE__ */ jsx(MouseTrackerProvider, { children });
1268
+ return /* @__PURE__ */ jsx2(MouseTrackerProvider, { children });
1105
1269
  };
1106
1270
  var MouseTrackerProvider = ({ children }) => {
1107
1271
  const storeRef = useRef3({
@@ -1171,7 +1335,7 @@ var MouseTrackerProvider = ({ children }) => {
1171
1335
  const isHovering = useCallback4((id) => {
1172
1336
  return storeRef.current.hoveringIds.has(id);
1173
1337
  }, []);
1174
- useEffect6(() => {
1338
+ useEffect7(() => {
1175
1339
  const handlePointerPosition = (event) => {
1176
1340
  const { clientX, clientY } = event;
1177
1341
  const pointer = storeRef.current.pointer;
@@ -1255,12 +1419,12 @@ var MouseTrackerProvider = ({ children }) => {
1255
1419
  isHovering
1256
1420
  ]
1257
1421
  );
1258
- return /* @__PURE__ */ jsx(MouseTrackerContext.Provider, { value, children });
1422
+ return /* @__PURE__ */ jsx2(MouseTrackerContext.Provider, { value, children });
1259
1423
  };
1260
1424
 
1261
1425
  // lib/components/SchematicComponentDetailsTooltip.tsx
1262
1426
  import { useMemo as useMemo3 } from "react";
1263
- import { jsx as jsx2, jsxs } from "react/jsx-runtime";
1427
+ import { jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
1264
1428
  var detailLabelStyle = {
1265
1429
  color: "#64748b",
1266
1430
  fontFamily: 'ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", monospace',
@@ -1292,7 +1456,7 @@ var SchematicComponentDetailsTooltip = ({
1292
1456
  ) : void 0,
1293
1457
  [footprintPreviewCircuitJson, footprintPreviewViewBox]
1294
1458
  );
1295
- return /* @__PURE__ */ jsxs(
1459
+ return /* @__PURE__ */ jsxs2(
1296
1460
  "dialog",
1297
1461
  {
1298
1462
  open: true,
@@ -1324,7 +1488,7 @@ var SchematicComponentDetailsTooltip = ({
1324
1488
  onMouseDown: (event) => event.stopPropagation(),
1325
1489
  onClick: (event) => event.stopPropagation(),
1326
1490
  children: [
1327
- /* @__PURE__ */ jsxs(
1491
+ /* @__PURE__ */ jsxs2(
1328
1492
  "dl",
1329
1493
  {
1330
1494
  style: {
@@ -1335,9 +1499,9 @@ var SchematicComponentDetailsTooltip = ({
1335
1499
  padding: "8px"
1336
1500
  },
1337
1501
  children: [
1338
- infoEntries.map((entry) => /* @__PURE__ */ jsxs("div", { style: { display: "contents" }, children: [
1339
- /* @__PURE__ */ jsx2("dt", { style: detailLabelStyle, children: entry.label }),
1340
- /* @__PURE__ */ jsx2(
1502
+ infoEntries.map((entry) => /* @__PURE__ */ jsxs2("div", { style: { display: "contents" }, children: [
1503
+ /* @__PURE__ */ jsx3("dt", { style: detailLabelStyle, children: entry.label }),
1504
+ /* @__PURE__ */ jsx3(
1341
1505
  "dd",
1342
1506
  {
1343
1507
  style: {
@@ -1353,9 +1517,9 @@ var SchematicComponentDetailsTooltip = ({
1353
1517
  }
1354
1518
  )
1355
1519
  ] }, entry.key)),
1356
- supplierPartNumberEntries.map((entry) => /* @__PURE__ */ jsxs("div", { style: { display: "contents" }, children: [
1357
- /* @__PURE__ */ jsx2("dt", { style: detailLabelStyle, children: entry.label }),
1358
- /* @__PURE__ */ jsx2(
1520
+ supplierPartNumberEntries.map((entry) => /* @__PURE__ */ jsxs2("div", { style: { display: "contents" }, children: [
1521
+ /* @__PURE__ */ jsx3("dt", { style: detailLabelStyle, children: entry.label }),
1522
+ /* @__PURE__ */ jsx3(
1359
1523
  "dd",
1360
1524
  {
1361
1525
  style: {
@@ -1366,9 +1530,9 @@ var SchematicComponentDetailsTooltip = ({
1366
1530
  lineHeight: 1.45,
1367
1531
  overflowWrap: "anywhere"
1368
1532
  },
1369
- children: entry.links.map((link, index) => /* @__PURE__ */ jsxs("span", { children: [
1533
+ children: entry.links.map((link, index) => /* @__PURE__ */ jsxs2("span", { children: [
1370
1534
  index > 0 && ", ",
1371
- /* @__PURE__ */ jsx2(
1535
+ /* @__PURE__ */ jsx3(
1372
1536
  "a",
1373
1537
  {
1374
1538
  href: link.href,
@@ -1382,9 +1546,9 @@ var SchematicComponentDetailsTooltip = ({
1382
1546
  }
1383
1547
  )
1384
1548
  ] }, entry.key)),
1385
- footprinterString && /* @__PURE__ */ jsxs("div", { style: { display: "contents" }, children: [
1386
- /* @__PURE__ */ jsx2("dt", { style: detailLabelStyle, children: "footprint" }),
1387
- /* @__PURE__ */ jsx2(
1549
+ footprinterString && /* @__PURE__ */ jsxs2("div", { style: { display: "contents" }, children: [
1550
+ /* @__PURE__ */ jsx3("dt", { style: detailLabelStyle, children: "footprint" }),
1551
+ /* @__PURE__ */ jsx3(
1388
1552
  "dd",
1389
1553
  {
1390
1554
  style: {
@@ -1403,7 +1567,7 @@ var SchematicComponentDetailsTooltip = ({
1403
1567
  ]
1404
1568
  }
1405
1569
  ),
1406
- footprintPreviewUrl && /* @__PURE__ */ jsx2("div", { style: { padding: "0 4px 4px" }, children: /* @__PURE__ */ jsx2(
1570
+ footprintPreviewUrl && /* @__PURE__ */ jsx3("div", { style: { padding: "0 4px 4px" }, children: /* @__PURE__ */ jsx3(
1407
1571
  "div",
1408
1572
  {
1409
1573
  style: {
@@ -1413,7 +1577,7 @@ var SchematicComponentDetailsTooltip = ({
1413
1577
  borderRadius: "2px",
1414
1578
  background: "#f8fafc"
1415
1579
  },
1416
- children: /* @__PURE__ */ jsx2(
1580
+ children: /* @__PURE__ */ jsx3(
1417
1581
  "img",
1418
1582
  {
1419
1583
  src: footprintPreviewUrl,
@@ -1436,12 +1600,12 @@ var SchematicComponentDetailsTooltip = ({
1436
1600
  };
1437
1601
 
1438
1602
  // lib/components/SchematicComponentMouseTarget.tsx
1439
- import { useCallback as useCallback5, useEffect as useEffect8, useRef as useRef5, useState as useState4 } from "react";
1603
+ import { useCallback as useCallback5, useEffect as useEffect9, useRef as useRef5, useState as useState5 } from "react";
1440
1604
 
1441
1605
  // lib/hooks/useMouseEventsOverBoundingBox.ts
1442
1606
  import {
1443
1607
  useContext as useContext2,
1444
- useEffect as useEffect7,
1608
+ useEffect as useEffect8,
1445
1609
  useId,
1446
1610
  useMemo as useMemo4,
1447
1611
  useRef as useRef4,
@@ -1463,7 +1627,7 @@ var useMouseEventsOverBoundingBox = (options) => {
1463
1627
  },
1464
1628
  []
1465
1629
  );
1466
- useEffect7(() => {
1630
+ useEffect8(() => {
1467
1631
  context.registerBoundingBox(id, {
1468
1632
  bounds: latestOptionsRef.current.bounds,
1469
1633
  onClick: latestOptionsRef.current.onClick ? handleClick : void 0
@@ -1472,7 +1636,7 @@ var useMouseEventsOverBoundingBox = (options) => {
1472
1636
  context.unregisterBoundingBox(id);
1473
1637
  };
1474
1638
  }, [context, handleClick, id]);
1475
- useEffect7(() => {
1639
+ useEffect8(() => {
1476
1640
  context.updateBoundingBox(id, {
1477
1641
  bounds: latestOptionsRef.current.bounds,
1478
1642
  onClick: latestOptionsRef.current.onClick ? handleClick : void 0
@@ -1496,7 +1660,7 @@ var useMouseEventsOverBoundingBox = (options) => {
1496
1660
  };
1497
1661
 
1498
1662
  // lib/components/SchematicComponentMouseTarget.tsx
1499
- import { jsx as jsx3 } from "react/jsx-runtime";
1663
+ import { jsx as jsx4 } from "react/jsx-runtime";
1500
1664
  var areMeasurementsEqual = (a, b) => {
1501
1665
  if (!a && !b) return true;
1502
1666
  if (!a || !b) return false;
@@ -1511,7 +1675,7 @@ var SchematicComponentMouseTarget = ({
1511
1675
  showOutline,
1512
1676
  circuitJsonKey
1513
1677
  }) => {
1514
- const [measurement, setMeasurement] = useState4(null);
1678
+ const [measurement, setMeasurement] = useState5(null);
1515
1679
  const frameRef = useRef5(null);
1516
1680
  const measure = useCallback5(() => {
1517
1681
  frameRef.current = null;
@@ -1552,10 +1716,10 @@ var SchematicComponentMouseTarget = ({
1552
1716
  if (frameRef.current !== null) return;
1553
1717
  frameRef.current = window.requestAnimationFrame(measure);
1554
1718
  }, [measure]);
1555
- useEffect8(() => {
1719
+ useEffect9(() => {
1556
1720
  scheduleMeasure();
1557
1721
  }, [scheduleMeasure, circuitJsonKey]);
1558
- useEffect8(() => {
1722
+ useEffect9(() => {
1559
1723
  scheduleMeasure();
1560
1724
  const svgDiv = svgDivRef.current;
1561
1725
  const container = containerRef.current;
@@ -1600,7 +1764,7 @@ var SchematicComponentMouseTarget = ({
1600
1764
  bounds,
1601
1765
  onClick: onComponentClick ? handleClick : void 0
1602
1766
  });
1603
- useEffect8(() => {
1767
+ useEffect9(() => {
1604
1768
  if (onHoverChange) {
1605
1769
  onHoverChange(componentId, hovering);
1606
1770
  }
@@ -1609,7 +1773,7 @@ var SchematicComponentMouseTarget = ({
1609
1773
  return null;
1610
1774
  }
1611
1775
  const rect = measurement.rect;
1612
- return /* @__PURE__ */ jsx3(
1776
+ return /* @__PURE__ */ jsx4(
1613
1777
  "div",
1614
1778
  {
1615
1779
  style: {
@@ -1627,8 +1791,8 @@ var SchematicComponentMouseTarget = ({
1627
1791
  };
1628
1792
 
1629
1793
  // lib/components/SchematicPortMouseTarget.tsx
1630
- import { useCallback as useCallback6, useEffect as useEffect9, useRef as useRef6, useState as useState5 } from "react";
1631
- import { Fragment as Fragment2, jsx as jsx4, jsxs as jsxs2 } from "react/jsx-runtime";
1794
+ import { useCallback as useCallback6, useEffect as useEffect10, useRef as useRef6, useState as useState6 } from "react";
1795
+ import { Fragment as Fragment3, jsx as jsx5, jsxs as jsxs3 } from "react/jsx-runtime";
1632
1796
  var areMeasurementsEqual2 = (a, b) => {
1633
1797
  if (!a && !b) return true;
1634
1798
  if (!a || !b) return false;
@@ -1644,7 +1808,7 @@ var SchematicPortMouseTarget = ({
1644
1808
  showOutline,
1645
1809
  circuitJsonKey
1646
1810
  }) => {
1647
- const [measurement, setMeasurement] = useState5(null);
1811
+ const [measurement, setMeasurement] = useState6(null);
1648
1812
  const frameRef = useRef6(null);
1649
1813
  const measure = useCallback6(() => {
1650
1814
  frameRef.current = null;
@@ -1686,10 +1850,10 @@ var SchematicPortMouseTarget = ({
1686
1850
  if (frameRef.current !== null) return;
1687
1851
  frameRef.current = window.requestAnimationFrame(measure);
1688
1852
  }, [measure]);
1689
- useEffect9(() => {
1853
+ useEffect10(() => {
1690
1854
  scheduleMeasure();
1691
1855
  }, [scheduleMeasure, circuitJsonKey]);
1692
- useEffect9(() => {
1856
+ useEffect10(() => {
1693
1857
  scheduleMeasure();
1694
1858
  const svgDiv = svgDivRef.current;
1695
1859
  const container = containerRef.current;
@@ -1734,7 +1898,7 @@ var SchematicPortMouseTarget = ({
1734
1898
  bounds,
1735
1899
  onClick: onPortClick ? handleClick : void 0
1736
1900
  });
1737
- useEffect9(() => {
1901
+ useEffect10(() => {
1738
1902
  if (onHoverChange) {
1739
1903
  onHoverChange(portId, hovering);
1740
1904
  }
@@ -1743,8 +1907,8 @@ var SchematicPortMouseTarget = ({
1743
1907
  return null;
1744
1908
  }
1745
1909
  const rect = measurement.rect;
1746
- return /* @__PURE__ */ jsxs2(Fragment2, { children: [
1747
- /* @__PURE__ */ jsx4(
1910
+ return /* @__PURE__ */ jsxs3(Fragment3, { children: [
1911
+ /* @__PURE__ */ jsx5(
1748
1912
  "div",
1749
1913
  {
1750
1914
  style: {
@@ -1762,7 +1926,7 @@ var SchematicPortMouseTarget = ({
1762
1926
  }
1763
1927
  }
1764
1928
  ),
1765
- hovering && portLabel && /* @__PURE__ */ jsx4(
1929
+ hovering && portLabel && /* @__PURE__ */ jsx5(
1766
1930
  "div",
1767
1931
  {
1768
1932
  style: {
@@ -1787,15 +1951,15 @@ var SchematicPortMouseTarget = ({
1787
1951
  };
1788
1952
 
1789
1953
  // lib/components/SchematicSearch.tsx
1790
- import { useEffect as useEffect10, useRef as useRef7, useState as useState6 } from "react";
1954
+ import { useEffect as useEffect11, useRef as useRef7, useState as useState7 } from "react";
1791
1955
 
1792
1956
  // lib/components/SchematicSearchIcons.tsx
1793
- import { jsx as jsx5, jsxs as jsxs3 } from "react/jsx-runtime";
1957
+ import { jsx as jsx6, jsxs as jsxs4 } from "react/jsx-runtime";
1794
1958
  var Icon = ({
1795
1959
  children,
1796
1960
  size,
1797
1961
  strokeWidth
1798
- }) => /* @__PURE__ */ jsx5(
1962
+ }) => /* @__PURE__ */ jsx6(
1799
1963
  "svg",
1800
1964
  {
1801
1965
  width: size,
@@ -1810,31 +1974,31 @@ var Icon = ({
1810
1974
  children
1811
1975
  }
1812
1976
  );
1813
- var SearchIcon = (props) => /* @__PURE__ */ jsxs3(Icon, { ...props, children: [
1814
- /* @__PURE__ */ jsx5("circle", { cx: "11", cy: "11", r: "8" }),
1815
- /* @__PURE__ */ jsx5("path", { d: "m21 21-4.34-4.34" })
1977
+ var SearchIcon = (props) => /* @__PURE__ */ jsxs4(Icon, { ...props, children: [
1978
+ /* @__PURE__ */ jsx6("circle", { cx: "11", cy: "11", r: "8" }),
1979
+ /* @__PURE__ */ jsx6("path", { d: "m21 21-4.34-4.34" })
1816
1980
  ] });
1817
- var CloseIcon = (props) => /* @__PURE__ */ jsxs3(Icon, { ...props, children: [
1818
- /* @__PURE__ */ jsx5("path", { d: "M18 6 6 18" }),
1819
- /* @__PURE__ */ jsx5("path", { d: "m6 6 12 12" })
1981
+ var CloseIcon = (props) => /* @__PURE__ */ jsxs4(Icon, { ...props, children: [
1982
+ /* @__PURE__ */ jsx6("path", { d: "M18 6 6 18" }),
1983
+ /* @__PURE__ */ jsx6("path", { d: "m6 6 12 12" })
1820
1984
  ] });
1821
- var ComponentIcon = (props) => /* @__PURE__ */ jsxs3(Icon, { ...props, children: [
1822
- /* @__PURE__ */ jsx5("rect", { x: "4", y: "4", width: "16", height: "16", rx: "2" }),
1823
- /* @__PURE__ */ jsx5("rect", { x: "8", y: "8", width: "8", height: "8", rx: "1" }),
1824
- /* @__PURE__ */ jsx5("path", { d: "M7 2v2M12 2v2M17 2v2M7 20v2M12 20v2M17 20v2M2 7h2M2 12h2M2 17h2M20 7h2M20 12h2M20 17h2" })
1985
+ var ComponentIcon = (props) => /* @__PURE__ */ jsxs4(Icon, { ...props, children: [
1986
+ /* @__PURE__ */ jsx6("rect", { x: "4", y: "4", width: "16", height: "16", rx: "2" }),
1987
+ /* @__PURE__ */ jsx6("rect", { x: "8", y: "8", width: "8", height: "8", rx: "1" }),
1988
+ /* @__PURE__ */ jsx6("path", { d: "M7 2v2M12 2v2M17 2v2M7 20v2M12 20v2M17 20v2M2 7h2M2 12h2M2 17h2M20 7h2M20 12h2M20 17h2" })
1825
1989
  ] });
1826
- var NetIcon = (props) => /* @__PURE__ */ jsxs3(Icon, { ...props, children: [
1827
- /* @__PURE__ */ jsx5("path", { d: "M15 6a9 9 0 0 0-9 9V3" }),
1828
- /* @__PURE__ */ jsx5("circle", { cx: "18", cy: "6", r: "3" }),
1829
- /* @__PURE__ */ jsx5("circle", { cx: "6", cy: "18", r: "3" })
1990
+ var NetIcon = (props) => /* @__PURE__ */ jsxs4(Icon, { ...props, children: [
1991
+ /* @__PURE__ */ jsx6("path", { d: "M15 6a9 9 0 0 0-9 9V3" }),
1992
+ /* @__PURE__ */ jsx6("circle", { cx: "18", cy: "6", r: "3" }),
1993
+ /* @__PURE__ */ jsx6("circle", { cx: "6", cy: "18", r: "3" })
1830
1994
  ] });
1831
- var EnterIcon = (props) => /* @__PURE__ */ jsxs3(Icon, { ...props, children: [
1832
- /* @__PURE__ */ jsx5("path", { d: "M20 4v7a4 4 0 0 1-4 4H4" }),
1833
- /* @__PURE__ */ jsx5("path", { d: "m9 10-5 5 5 5" })
1995
+ var EnterIcon = (props) => /* @__PURE__ */ jsxs4(Icon, { ...props, children: [
1996
+ /* @__PURE__ */ jsx6("path", { d: "M20 4v7a4 4 0 0 1-4 4H4" }),
1997
+ /* @__PURE__ */ jsx6("path", { d: "m9 10-5 5 5 5" })
1834
1998
  ] });
1835
1999
 
1836
2000
  // lib/components/SchematicSearch.tsx
1837
- import { Fragment as Fragment3, jsx as jsx6, jsxs as jsxs4 } from "react/jsx-runtime";
2001
+ import { Fragment as Fragment4, jsx as jsx7, jsxs as jsxs5 } from "react/jsx-runtime";
1838
2002
  var HighlightedSearchText = ({
1839
2003
  text,
1840
2004
  query
@@ -1850,7 +2014,7 @@ var HighlightedSearchText = ({
1850
2014
  parts.push(text.slice(cursor, matchIndex));
1851
2015
  }
1852
2016
  parts.push(
1853
- /* @__PURE__ */ jsx6("strong", { style: { fontWeight: 700 }, children: text.slice(matchIndex, matchIndex + normalizedQuery.length) }, `${matchIndex}-${cursor}`)
2017
+ /* @__PURE__ */ jsx7("strong", { style: { fontWeight: 700 }, children: text.slice(matchIndex, matchIndex + normalizedQuery.length) }, `${matchIndex}-${cursor}`)
1854
2018
  );
1855
2019
  cursor = matchIndex + normalizedQuery.length;
1856
2020
  matchIndex = normalizedText.indexOf(normalizedQuery, cursor);
@@ -1872,13 +2036,13 @@ var SchematicSearch = ({
1872
2036
  onSelect,
1873
2037
  viewerContainerRef
1874
2038
  }) => {
1875
- const [isOpen, setIsOpen] = useState6(false);
1876
- const [activeResultId, setActiveResultId] = useState6(null);
1877
- const [hoveredResultId, setHoveredResultId] = useState6(null);
2039
+ const [isOpen, setIsOpen] = useState7(false);
2040
+ const [activeResultId, setActiveResultId] = useState7(null);
2041
+ const [hoveredResultId, setHoveredResultId] = useState7(null);
1878
2042
  const inputRef = useRef7(null);
1879
2043
  const resultsListRef = useRef7(null);
1880
2044
  const shortcutLabel = getShortcutLabel();
1881
- useEffect10(() => {
2045
+ useEffect11(() => {
1882
2046
  setActiveResultId((currentId) => {
1883
2047
  if (results.some((result) => result.target.id === currentId)) {
1884
2048
  return currentId;
@@ -1886,11 +2050,11 @@ var SchematicSearch = ({
1886
2050
  return results.find((result) => result.kind === "component")?.target.id ?? results[0]?.target.id ?? null;
1887
2051
  });
1888
2052
  }, [results]);
1889
- useEffect10(() => {
2053
+ useEffect11(() => {
1890
2054
  if (!activeResultId) return;
1891
2055
  resultsListRef.current?.querySelector(`[data-search-result-id="${activeResultId}"]`)?.scrollIntoView({ behavior: "smooth", block: "nearest" });
1892
2056
  }, [activeResultId]);
1893
- useEffect10(() => {
2057
+ useEffect11(() => {
1894
2058
  const handleSearchShortcut = (event) => {
1895
2059
  if (event.key === "Escape" && isOpen) {
1896
2060
  event.preventDefault();
@@ -1991,8 +2155,8 @@ var SchematicSearch = ({
1991
2155
  };
1992
2156
  const renderResultSection = (title, sectionResults) => {
1993
2157
  if (sectionResults.length === 0) return null;
1994
- return /* @__PURE__ */ jsxs4("section", { children: [
1995
- /* @__PURE__ */ jsx6(
2158
+ return /* @__PURE__ */ jsxs5("section", { children: [
2159
+ /* @__PURE__ */ jsx7(
1996
2160
  "div",
1997
2161
  {
1998
2162
  style: {
@@ -2012,16 +2176,16 @@ var SchematicSearch = ({
2012
2176
  const hovering = result.target.id === hoveredResultId;
2013
2177
  let resultBackground = "#ffffff";
2014
2178
  if (hovering || active) resultBackground = "#f1f3f5";
2015
- let resultIcon = /* @__PURE__ */ jsx6(NetIcon, { size: 15, strokeWidth: 1.8 });
2179
+ let resultIcon = /* @__PURE__ */ jsx7(NetIcon, { size: 15, strokeWidth: 1.8 });
2016
2180
  if (result.kind === "component") {
2017
- resultIcon = /* @__PURE__ */ jsx6(ComponentIcon, { size: 15, strokeWidth: 1.8 });
2181
+ resultIcon = /* @__PURE__ */ jsx7(ComponentIcon, { size: 15, strokeWidth: 1.8 });
2018
2182
  }
2019
2183
  const selectResult = () => {
2020
2184
  inputRef.current?.blur();
2021
2185
  setActiveResultId(result.target.id);
2022
2186
  onSelect(result);
2023
2187
  };
2024
- return /* @__PURE__ */ jsxs4(
2188
+ return /* @__PURE__ */ jsxs5(
2025
2189
  "button",
2026
2190
  {
2027
2191
  type: "button",
@@ -2047,7 +2211,7 @@ var SchematicSearch = ({
2047
2211
  textAlign: "left"
2048
2212
  },
2049
2213
  children: [
2050
- /* @__PURE__ */ jsx6(
2214
+ /* @__PURE__ */ jsx7(
2051
2215
  "span",
2052
2216
  {
2053
2217
  style: {
@@ -2064,8 +2228,8 @@ var SchematicSearch = ({
2064
2228
  children: resultIcon
2065
2229
  }
2066
2230
  ),
2067
- /* @__PURE__ */ jsxs4("span", { style: { minWidth: 0, flex: 1 }, children: [
2068
- /* @__PURE__ */ jsx6(
2231
+ /* @__PURE__ */ jsxs5("span", { style: { minWidth: 0, flex: 1 }, children: [
2232
+ /* @__PURE__ */ jsx7(
2069
2233
  "span",
2070
2234
  {
2071
2235
  style: {
@@ -2077,10 +2241,10 @@ var SchematicSearch = ({
2077
2241
  textOverflow: "ellipsis",
2078
2242
  whiteSpace: "nowrap"
2079
2243
  },
2080
- children: /* @__PURE__ */ jsx6(HighlightedSearchText, { text: result.label, query })
2244
+ children: /* @__PURE__ */ jsx7(HighlightedSearchText, { text: result.label, query })
2081
2245
  }
2082
2246
  ),
2083
- result.detail && /* @__PURE__ */ jsx6(
2247
+ result.detail && /* @__PURE__ */ jsx7(
2084
2248
  "span",
2085
2249
  {
2086
2250
  style: {
@@ -2096,7 +2260,7 @@ var SchematicSearch = ({
2096
2260
  children: result.detail
2097
2261
  }
2098
2262
  ),
2099
- result.schematicSheetName && /* @__PURE__ */ jsxs4(
2263
+ result.schematicSheetName && /* @__PURE__ */ jsxs5(
2100
2264
  "span",
2101
2265
  {
2102
2266
  style: {
@@ -2116,7 +2280,7 @@ var SchematicSearch = ({
2116
2280
  }
2117
2281
  )
2118
2282
  ] }),
2119
- active && /* @__PURE__ */ jsx6(
2283
+ active && /* @__PURE__ */ jsx7(
2120
2284
  "span",
2121
2285
  {
2122
2286
  title: "Press Enter to open",
@@ -2126,7 +2290,7 @@ var SchematicSearch = ({
2126
2290
  fontSize: "17px",
2127
2291
  lineHeight: 1
2128
2292
  },
2129
- children: /* @__PURE__ */ jsx6(EnterIcon, { size: 14, strokeWidth: 1.8 })
2293
+ children: /* @__PURE__ */ jsx7(EnterIcon, { size: 14, strokeWidth: 1.8 })
2130
2294
  }
2131
2295
  )
2132
2296
  ]
@@ -2136,7 +2300,7 @@ var SchematicSearch = ({
2136
2300
  })
2137
2301
  ] });
2138
2302
  };
2139
- return /* @__PURE__ */ jsx6(
2303
+ return /* @__PURE__ */ jsx7(
2140
2304
  "div",
2141
2305
  {
2142
2306
  "data-schematic-search": true,
@@ -2149,7 +2313,7 @@ var SchematicSearch = ({
2149
2313
  zIndex: zIndexMap.schematicSearch,
2150
2314
  fontFamily: '-apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif'
2151
2315
  },
2152
- children: !isOpen ? /* @__PURE__ */ jsx6(
2316
+ children: !isOpen ? /* @__PURE__ */ jsx7(
2153
2317
  "button",
2154
2318
  {
2155
2319
  type: "button",
@@ -2180,9 +2344,9 @@ var SchematicSearch = ({
2180
2344
  cursor: "pointer",
2181
2345
  boxShadow: "0 2px 4px rgba(0,0,0,0.1)"
2182
2346
  },
2183
- children: /* @__PURE__ */ jsx6(SearchIcon, { size: 16, strokeWidth: 2 })
2347
+ children: /* @__PURE__ */ jsx7(SearchIcon, { size: 16, strokeWidth: 2 })
2184
2348
  }
2185
- ) : /* @__PURE__ */ jsxs4(
2349
+ ) : /* @__PURE__ */ jsxs5(
2186
2350
  "div",
2187
2351
  {
2188
2352
  onKeyDown: handleSearchKeyDown,
@@ -2195,7 +2359,7 @@ var SchematicSearch = ({
2195
2359
  boxShadow: "0 2px 4px rgba(0,0,0,0.1)"
2196
2360
  },
2197
2361
  children: [
2198
- /* @__PURE__ */ jsxs4(
2362
+ /* @__PURE__ */ jsxs5(
2199
2363
  "div",
2200
2364
  {
2201
2365
  style: {
@@ -2208,8 +2372,8 @@ var SchematicSearch = ({
2208
2372
  borderBottom: searchHeaderBorder
2209
2373
  },
2210
2374
  children: [
2211
- /* @__PURE__ */ jsx6(SearchIcon, { size: 15, strokeWidth: 2 }),
2212
- /* @__PURE__ */ jsx6(
2375
+ /* @__PURE__ */ jsx7(SearchIcon, { size: 15, strokeWidth: 2 }),
2376
+ /* @__PURE__ */ jsx7(
2213
2377
  "input",
2214
2378
  {
2215
2379
  ref: inputRef,
@@ -2229,7 +2393,7 @@ var SchematicSearch = ({
2229
2393
  }
2230
2394
  }
2231
2395
  ),
2232
- query && results.length > 0 ? /* @__PURE__ */ jsx6(
2396
+ query && results.length > 0 ? /* @__PURE__ */ jsx7(
2233
2397
  "span",
2234
2398
  {
2235
2399
  style: {
@@ -2240,7 +2404,7 @@ var SchematicSearch = ({
2240
2404
  },
2241
2405
  children: resultCountLabel
2242
2406
  }
2243
- ) : /* @__PURE__ */ jsx6(
2407
+ ) : /* @__PURE__ */ jsx7(
2244
2408
  "kbd",
2245
2409
  {
2246
2410
  style: {
@@ -2257,7 +2421,7 @@ var SchematicSearch = ({
2257
2421
  children: shortcutLabel
2258
2422
  }
2259
2423
  ),
2260
- isOpen && /* @__PURE__ */ jsx6(
2424
+ isOpen && /* @__PURE__ */ jsx7(
2261
2425
  "button",
2262
2426
  {
2263
2427
  type: "button",
@@ -2280,13 +2444,13 @@ var SchematicSearch = ({
2280
2444
  padding: 0,
2281
2445
  lineHeight: 1
2282
2446
  },
2283
- children: /* @__PURE__ */ jsx6(CloseIcon, { size: 16, strokeWidth: 2 })
2447
+ children: /* @__PURE__ */ jsx7(CloseIcon, { size: 16, strokeWidth: 2 })
2284
2448
  }
2285
2449
  )
2286
2450
  ]
2287
2451
  }
2288
2452
  ),
2289
- query && /* @__PURE__ */ jsx6(
2453
+ query && /* @__PURE__ */ jsx7(
2290
2454
  "div",
2291
2455
  {
2292
2456
  ref: resultsListRef,
@@ -2301,7 +2465,7 @@ var SchematicSearch = ({
2301
2465
  },
2302
2466
  onWheel: (event) => event.stopPropagation(),
2303
2467
  onTouchMove: (event) => event.stopPropagation(),
2304
- children: results.length === 0 ? /* @__PURE__ */ jsx6(
2468
+ children: results.length === 0 ? /* @__PURE__ */ jsx7(
2305
2469
  "div",
2306
2470
  {
2307
2471
  style: {
@@ -2311,7 +2475,7 @@ var SchematicSearch = ({
2311
2475
  },
2312
2476
  children: "No matching components or nets"
2313
2477
  }
2314
- ) : /* @__PURE__ */ jsxs4(Fragment3, { children: [
2478
+ ) : /* @__PURE__ */ jsxs5(Fragment4, { children: [
2315
2479
  renderResultSection("components", componentResults),
2316
2480
  renderResultSection("nets", netResults)
2317
2481
  ] })
@@ -2325,9 +2489,9 @@ var SchematicSearch = ({
2325
2489
  };
2326
2490
 
2327
2491
  // lib/components/SchematicSheetSelector.tsx
2328
- import { useState as useState7 } from "react";
2492
+ import { useState as useState8 } from "react";
2329
2493
  import * as DropdownMenu from "@radix-ui/react-dropdown-menu";
2330
- import { Fragment as Fragment4, jsx as jsx7, jsxs as jsxs5 } from "react/jsx-runtime";
2494
+ import { Fragment as Fragment5, jsx as jsx8, jsxs as jsxs6 } from "react/jsx-runtime";
2331
2495
  var FONT_FAMILY = 'system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif';
2332
2496
  var contentStyles = {
2333
2497
  backgroundColor: "#ffffff",
@@ -2377,7 +2541,7 @@ var MENU_CSS = `
2377
2541
  .sv-sheet-chevron { transition: transform 0.2s ease; }
2378
2542
  [data-state="open"] > .sv-sheet-chevron { transform: rotate(180deg); }
2379
2543
  `;
2380
- var CheckIcon = () => /* @__PURE__ */ jsx7(
2544
+ var CheckIcon = () => /* @__PURE__ */ jsx8(
2381
2545
  "svg",
2382
2546
  {
2383
2547
  width: "14",
@@ -2389,10 +2553,10 @@ var CheckIcon = () => /* @__PURE__ */ jsx7(
2389
2553
  strokeLinecap: "round",
2390
2554
  strokeLinejoin: "round",
2391
2555
  "aria-hidden": "true",
2392
- children: /* @__PURE__ */ jsx7("path", { d: "M20 6 9 17l-5-5" })
2556
+ children: /* @__PURE__ */ jsx8("path", { d: "M20 6 9 17l-5-5" })
2393
2557
  }
2394
2558
  );
2395
- var ChevronDownIcon = ({ className }) => /* @__PURE__ */ jsx7(
2559
+ var ChevronDownIcon = ({ className }) => /* @__PURE__ */ jsx8(
2396
2560
  "svg",
2397
2561
  {
2398
2562
  className,
@@ -2406,7 +2570,7 @@ var ChevronDownIcon = ({ className }) => /* @__PURE__ */ jsx7(
2406
2570
  strokeLinejoin: "round",
2407
2571
  style: { opacity: 0.6, flexShrink: 0 },
2408
2572
  "aria-hidden": "true",
2409
- children: /* @__PURE__ */ jsx7("path", { d: "m6 9 6 6 6-6" })
2573
+ children: /* @__PURE__ */ jsx8("path", { d: "m6 9 6 6 6-6" })
2410
2574
  }
2411
2575
  );
2412
2576
  var SchematicSheetSelector = ({
@@ -2414,16 +2578,16 @@ var SchematicSheetSelector = ({
2414
2578
  selectedSheetId,
2415
2579
  onSelectSheet
2416
2580
  }) => {
2417
- const [open, setOpen] = useState7(false);
2581
+ const [open, setOpen] = useState8(false);
2418
2582
  if (sheets.length <= 1) return null;
2419
2583
  const selectedSheet = sheets.find(
2420
2584
  (s) => s.schematic_sheet_id === selectedSheetId
2421
2585
  );
2422
2586
  const selectedLabel = selectedSheet?.name ?? "Select sheet";
2423
- return /* @__PURE__ */ jsxs5(Fragment4, { children: [
2424
- /* @__PURE__ */ jsx7("style", { children: MENU_CSS }),
2425
- /* @__PURE__ */ jsxs5(DropdownMenu.Root, { open, onOpenChange: setOpen, modal: false, children: [
2426
- /* @__PURE__ */ jsx7(DropdownMenu.Trigger, { asChild: true, children: /* @__PURE__ */ jsxs5(
2587
+ return /* @__PURE__ */ jsxs6(Fragment5, { children: [
2588
+ /* @__PURE__ */ jsx8("style", { children: MENU_CSS }),
2589
+ /* @__PURE__ */ jsxs6(DropdownMenu.Root, { open, onOpenChange: setOpen, modal: false, children: [
2590
+ /* @__PURE__ */ jsx8(DropdownMenu.Trigger, { asChild: true, children: /* @__PURE__ */ jsxs6(
2427
2591
  "button",
2428
2592
  {
2429
2593
  type: "button",
@@ -2448,13 +2612,13 @@ var SchematicSheetSelector = ({
2448
2612
  fontFamily: FONT_FAMILY
2449
2613
  },
2450
2614
  children: [
2451
- /* @__PURE__ */ jsx7("span", { style: { color: "#888888", flexShrink: 0 }, children: "Sheet:" }),
2452
- /* @__PURE__ */ jsx7("span", { style: { ...ellipsisStyles, minWidth: 0 }, children: selectedLabel }),
2453
- /* @__PURE__ */ jsx7(ChevronDownIcon, { className: "sv-sheet-chevron" })
2615
+ /* @__PURE__ */ jsx8("span", { style: { color: "#888888", flexShrink: 0 }, children: "Sheet:" }),
2616
+ /* @__PURE__ */ jsx8("span", { style: { ...ellipsisStyles, minWidth: 0 }, children: selectedLabel }),
2617
+ /* @__PURE__ */ jsx8(ChevronDownIcon, { className: "sv-sheet-chevron" })
2454
2618
  ]
2455
2619
  }
2456
2620
  ) }),
2457
- /* @__PURE__ */ jsx7(DropdownMenu.Portal, { children: /* @__PURE__ */ jsx7(
2621
+ /* @__PURE__ */ jsx8(DropdownMenu.Portal, { children: /* @__PURE__ */ jsx8(
2458
2622
  DropdownMenu.Content,
2459
2623
  {
2460
2624
  style: contentStyles,
@@ -2464,7 +2628,7 @@ var SchematicSheetSelector = ({
2464
2628
  collisionPadding: 10,
2465
2629
  children: sheets.map((sheet) => {
2466
2630
  const selected = sheet.schematic_sheet_id === selectedSheetId;
2467
- return /* @__PURE__ */ jsxs5(
2631
+ return /* @__PURE__ */ jsxs6(
2468
2632
  DropdownMenu.Item,
2469
2633
  {
2470
2634
  className: "sv-sheet-item",
@@ -2476,8 +2640,8 @@ var SchematicSheetSelector = ({
2476
2640
  setOpen(false);
2477
2641
  },
2478
2642
  children: [
2479
- /* @__PURE__ */ jsx7("span", { style: iconSlotStyles, children: selected && /* @__PURE__ */ jsx7(CheckIcon, {}) }),
2480
- /* @__PURE__ */ jsx7("span", { style: { ...ellipsisStyles, minWidth: 0 }, children: sheet.name })
2643
+ /* @__PURE__ */ jsx8("span", { style: iconSlotStyles, children: selected && /* @__PURE__ */ jsx8(CheckIcon, {}) }),
2644
+ /* @__PURE__ */ jsx8("span", { style: { ...ellipsisStyles, minWidth: 0 }, children: sheet.name })
2481
2645
  ]
2482
2646
  },
2483
2647
  sheet.schematic_sheet_id
@@ -2497,7 +2661,7 @@ import { useMemo as useMemo5 } from "react";
2497
2661
  // package.json
2498
2662
  var package_default = {
2499
2663
  name: "@tscircuit/schematic-viewer",
2500
- version: "2.0.90",
2664
+ version: "2.0.91",
2501
2665
  repository: {
2502
2666
  type: "git",
2503
2667
  url: "https://github.com/tscircuit/schematic-viewer"
@@ -2532,13 +2696,15 @@ var package_default = {
2532
2696
  semver: "^7.7.2",
2533
2697
  tscircuit: "^0.0.2460",
2534
2698
  tsup: "^8.3.5",
2535
- vite: "^6.0.3"
2699
+ vite: "^6.0.3",
2700
+ "@tscircuit/circuit-json-schematic-placement-analysis": "https://codeload.github.com/tscircuit/circuit-json-schematic-placement-analysis/tar.gz/refs/heads/main"
2536
2701
  },
2537
2702
  peerDependencies: {
2538
2703
  typescript: "^5.0.0",
2539
2704
  tscircuit: "*"
2540
2705
  },
2541
2706
  dependencies: {
2707
+ "@radix-ui/react-dialog": "^1.1.23",
2542
2708
  "@radix-ui/react-dropdown-menu": "^2.1.16",
2543
2709
  "@tscircuit/circuit-json-util": "^0.0.108",
2544
2710
  "circuit-json": "^0.0.479",
@@ -2551,7 +2717,7 @@ var package_default = {
2551
2717
  };
2552
2718
 
2553
2719
  // lib/components/ViewMenu.tsx
2554
- import { jsx as jsx8, jsxs as jsxs6 } from "react/jsx-runtime";
2720
+ import { jsx as jsx9, jsxs as jsxs7 } from "react/jsx-runtime";
2555
2721
  var FONT_FAMILY2 = 'system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif';
2556
2722
  var contentStyles2 = {
2557
2723
  backgroundColor: "#262626",
@@ -2600,7 +2766,7 @@ var HIGHLIGHT_CSS = `
2600
2766
  .sv-vm-item:hover:not([data-disabled]) { background-color: #404040; }
2601
2767
  .sv-vm-item[data-disabled] { opacity: 0.45; cursor: not-allowed; }
2602
2768
  `;
2603
- var CheckIcon2 = () => /* @__PURE__ */ jsx8(
2769
+ var CheckIcon2 = () => /* @__PURE__ */ jsx9(
2604
2770
  "svg",
2605
2771
  {
2606
2772
  width: "14",
@@ -2612,7 +2778,7 @@ var CheckIcon2 = () => /* @__PURE__ */ jsx8(
2612
2778
  strokeLinecap: "round",
2613
2779
  strokeLinejoin: "round",
2614
2780
  "aria-hidden": "true",
2615
- children: /* @__PURE__ */ jsx8("path", { d: "M20 6 9 17l-5-5" })
2781
+ children: /* @__PURE__ */ jsx9("path", { d: "M20 6 9 17l-5-5" })
2616
2782
  }
2617
2783
  );
2618
2784
  var ViewMenu = ({
@@ -2621,6 +2787,7 @@ var ViewMenu = ({
2621
2787
  menuRef,
2622
2788
  menuPos,
2623
2789
  onOpenChange,
2790
+ onRunStyleAnalysis,
2624
2791
  showGroups,
2625
2792
  onToggleGroups,
2626
2793
  showGrid,
@@ -2663,7 +2830,7 @@ var ViewMenu = ({
2663
2830
  return false;
2664
2831
  }
2665
2832
  }, [circuitJsonKey]);
2666
- return /* @__PURE__ */ jsx8(
2833
+ return /* @__PURE__ */ jsx9(
2667
2834
  "div",
2668
2835
  {
2669
2836
  ref: menuRef,
@@ -2674,9 +2841,9 @@ var ViewMenu = ({
2674
2841
  width: 0,
2675
2842
  height: 0
2676
2843
  },
2677
- children: /* @__PURE__ */ jsxs6(DropdownMenu2.Root, { open: true, onOpenChange, modal: false, children: [
2678
- /* @__PURE__ */ jsx8(DropdownMenu2.Trigger, { asChild: true, children: /* @__PURE__ */ jsx8("div", { style: { position: "absolute", width: 1, height: 1 } }) }),
2679
- /* @__PURE__ */ jsx8(DropdownMenu2.Portal, { children: /* @__PURE__ */ jsxs6(
2844
+ children: /* @__PURE__ */ jsxs7(DropdownMenu2.Root, { open: true, onOpenChange, modal: false, children: [
2845
+ /* @__PURE__ */ jsx9(DropdownMenu2.Trigger, { asChild: true, children: /* @__PURE__ */ jsx9("div", { style: { position: "absolute", width: 1, height: 1 } }) }),
2846
+ /* @__PURE__ */ jsx9(DropdownMenu2.Portal, { children: /* @__PURE__ */ jsxs7(
2680
2847
  DropdownMenu2.Content,
2681
2848
  {
2682
2849
  style: contentStyles2,
@@ -2685,8 +2852,8 @@ var ViewMenu = ({
2685
2852
  collisionPadding: 10,
2686
2853
  avoidCollisions: true,
2687
2854
  children: [
2688
- /* @__PURE__ */ jsx8("style", { children: HIGHLIGHT_CSS }),
2689
- /* @__PURE__ */ jsxs6(
2855
+ /* @__PURE__ */ jsx9("style", { children: HIGHLIGHT_CSS }),
2856
+ /* @__PURE__ */ jsxs7(
2690
2857
  DropdownMenu2.Item,
2691
2858
  {
2692
2859
  className: "sv-vm-item",
@@ -2699,12 +2866,12 @@ var ViewMenu = ({
2699
2866
  if (hasPorts) onTogglePorts(!showPorts);
2700
2867
  },
2701
2868
  children: [
2702
- /* @__PURE__ */ jsx8("span", { style: iconSlotStyles2, children: showPorts && /* @__PURE__ */ jsx8(CheckIcon2, {}) }),
2703
- /* @__PURE__ */ jsx8("span", { children: "Show Schematic Ports" })
2869
+ /* @__PURE__ */ jsx9("span", { style: iconSlotStyles2, children: showPorts && /* @__PURE__ */ jsx9(CheckIcon2, {}) }),
2870
+ /* @__PURE__ */ jsx9("span", { children: "Show Schematic Ports" })
2704
2871
  ]
2705
2872
  }
2706
2873
  ),
2707
- /* @__PURE__ */ jsxs6(
2874
+ /* @__PURE__ */ jsxs7(
2708
2875
  DropdownMenu2.Item,
2709
2876
  {
2710
2877
  className: "sv-vm-item",
@@ -2717,12 +2884,12 @@ var ViewMenu = ({
2717
2884
  if (hasGroups) onToggleGroups(!showGroups);
2718
2885
  },
2719
2886
  children: [
2720
- /* @__PURE__ */ jsx8("span", { style: iconSlotStyles2, children: showGroups && /* @__PURE__ */ jsx8(CheckIcon2, {}) }),
2721
- /* @__PURE__ */ jsx8("span", { children: "View Schematic Groups" })
2887
+ /* @__PURE__ */ jsx9("span", { style: iconSlotStyles2, children: showGroups && /* @__PURE__ */ jsx9(CheckIcon2, {}) }),
2888
+ /* @__PURE__ */ jsx9("span", { children: "View Schematic Groups" })
2722
2889
  ]
2723
2890
  }
2724
2891
  ),
2725
- /* @__PURE__ */ jsxs6(
2892
+ /* @__PURE__ */ jsxs7(
2726
2893
  DropdownMenu2.Item,
2727
2894
  {
2728
2895
  className: "sv-vm-item",
@@ -2733,12 +2900,12 @@ var ViewMenu = ({
2733
2900
  onToggleGrid(!showGrid);
2734
2901
  },
2735
2902
  children: [
2736
- /* @__PURE__ */ jsx8("span", { style: iconSlotStyles2, children: showGrid && /* @__PURE__ */ jsx8(CheckIcon2, {}) }),
2737
- /* @__PURE__ */ jsx8("span", { children: "Show Grid" })
2903
+ /* @__PURE__ */ jsx9("span", { style: iconSlotStyles2, children: showGrid && /* @__PURE__ */ jsx9(CheckIcon2, {}) }),
2904
+ /* @__PURE__ */ jsx9("span", { children: "Show Grid" })
2738
2905
  ]
2739
2906
  }
2740
2907
  ),
2741
- /* @__PURE__ */ jsxs6(
2908
+ /* @__PURE__ */ jsxs7(
2742
2909
  DropdownMenu2.CheckboxItem,
2743
2910
  {
2744
2911
  className: "sv-vm-item",
@@ -2747,13 +2914,26 @@ var ViewMenu = ({
2747
2914
  onCheckedChange: onToggleWarnings,
2748
2915
  onSelect: (event) => event.preventDefault(),
2749
2916
  children: [
2750
- /* @__PURE__ */ jsx8("span", { style: iconSlotStyles2, children: /* @__PURE__ */ jsx8(DropdownMenu2.ItemIndicator, { children: /* @__PURE__ */ jsx8(CheckIcon2, {}) }) }),
2751
- /* @__PURE__ */ jsx8("span", { children: "Show Warnings" })
2917
+ /* @__PURE__ */ jsx9("span", { style: iconSlotStyles2, children: /* @__PURE__ */ jsx9(DropdownMenu2.ItemIndicator, { children: /* @__PURE__ */ jsx9(CheckIcon2, {}) }) }),
2918
+ /* @__PURE__ */ jsx9("span", { children: "Show Warnings" })
2752
2919
  ]
2753
2920
  }
2754
2921
  ),
2755
- /* @__PURE__ */ jsx8(DropdownMenu2.Separator, { style: separatorStyles }),
2756
- /* @__PURE__ */ jsxs6(
2922
+ /* @__PURE__ */ jsx9(DropdownMenu2.Separator, { style: separatorStyles }),
2923
+ /* @__PURE__ */ jsxs7(
2924
+ DropdownMenu2.Item,
2925
+ {
2926
+ className: "sv-vm-item",
2927
+ style: itemStyles2,
2928
+ onSelect: onRunStyleAnalysis,
2929
+ children: [
2930
+ /* @__PURE__ */ jsx9("span", { style: iconSlotStyles2 }),
2931
+ /* @__PURE__ */ jsx9("span", { children: "Run Style Analysis" })
2932
+ ]
2933
+ }
2934
+ ),
2935
+ /* @__PURE__ */ jsx9(DropdownMenu2.Separator, { style: separatorStyles }),
2936
+ /* @__PURE__ */ jsxs7(
2757
2937
  "div",
2758
2938
  {
2759
2939
  style: {
@@ -2779,7 +2959,7 @@ var ViewMenu = ({
2779
2959
  };
2780
2960
 
2781
2961
  // lib/components/SchematicViewer.tsx
2782
- import { jsx as jsx9, jsxs as jsxs7 } from "react/jsx-runtime";
2962
+ import { jsx as jsx10, jsxs as jsxs8 } from "react/jsx-runtime";
2783
2963
  var SchematicViewer = ({
2784
2964
  circuitJson,
2785
2965
  containerStyle,
@@ -2817,7 +2997,7 @@ var SchematicViewer = ({
2817
2997
  }, [circuitJsonKey]);
2818
2998
  const hasMultipleSheets = schematicSheets.length > 1;
2819
2999
  const defaultSheetId = schematicSheets[0]?.schematic_sheet_id;
2820
- const [selectedSheetId, setSelectedSheetId] = useState8(
3000
+ const [selectedSheetId, setSelectedSheetId] = useState9(
2821
3001
  () => {
2822
3002
  const stored = getStoredString(STORAGE_KEYS.SELECTED_SCHEMATIC_SHEET);
2823
3003
  if (stored && schematicSheets.some((s) => s.schematic_sheet_id === stored)) {
@@ -2826,7 +3006,7 @@ var SchematicViewer = ({
2826
3006
  return defaultSheetId;
2827
3007
  }
2828
3008
  );
2829
- useEffect11(() => {
3009
+ useEffect12(() => {
2830
3010
  const stillExists = selectedSheetId !== void 0 && schematicSheets.some((s) => s.schematic_sheet_id === selectedSheetId);
2831
3011
  if (!stillExists) {
2832
3012
  setSelectedSheetId(defaultSheetId);
@@ -2841,27 +3021,28 @@ var SchematicViewer = ({
2841
3021
  },
2842
3022
  [onSchematicSheetChange]
2843
3023
  );
2844
- const [showGridInternal, setShowGridInternal] = useState8(false);
2845
- const [showWarnings, setShowWarnings] = useState8(false);
3024
+ const [showGridInternal, setShowGridInternal] = useState9(false);
3025
+ const [analysisCircuitJson, setAnalysisCircuitJson] = useState9(null);
3026
+ const [showWarnings, setShowWarnings] = useState9(false);
2846
3027
  const showGrid = debugGrid || showGridInternal;
2847
- const [isInteractionEnabled, setIsInteractionEnabled] = useState8(
3028
+ const [isInteractionEnabled, setIsInteractionEnabled] = useState9(
2848
3029
  !clickToInteractEnabled
2849
3030
  );
2850
- const [showSchematicGroups, setShowSchematicGroups] = useState8(() => {
3031
+ const [showSchematicGroups, setShowSchematicGroups] = useState9(() => {
2851
3032
  if (disableGroups) return false;
2852
3033
  return getStoredBoolean(STORAGE_KEYS.IS_SHOWING_SCHEMATIC_GROUPS, false);
2853
3034
  });
2854
- const [showSchematicPortsInternal, setShowSchematicPortsInternal] = useState8(
3035
+ const [showSchematicPortsInternal, setShowSchematicPortsInternal] = useState9(
2855
3036
  () => showSchematicPorts ?? getStoredBoolean(STORAGE_KEYS.IS_SHOWING_SCHEMATIC_PORTS, false)
2856
3037
  );
2857
- useEffect11(() => {
3038
+ useEffect12(() => {
2858
3039
  if (showSchematicPorts !== void 0) {
2859
3040
  setShowSchematicPortsInternal(showSchematicPorts);
2860
3041
  }
2861
3042
  }, [showSchematicPorts]);
2862
- const [isHoveringClickableComponent, setIsHoveringClickableComponent] = useState8(false);
3043
+ const [isHoveringClickableComponent, setIsHoveringClickableComponent] = useState9(false);
2863
3044
  const hoveringComponentsRef = useRef8(/* @__PURE__ */ new Set());
2864
- const [selectedSchematicComponent, setSelectedSchematicComponent] = useState8(null);
3045
+ const [selectedSchematicComponent, setSelectedSchematicComponent] = useState9(null);
2865
3046
  const handleComponentHoverChange = useCallback7(
2866
3047
  (componentId, isHovering) => {
2867
3048
  if (isHovering) {
@@ -2873,7 +3054,7 @@ var SchematicViewer = ({
2873
3054
  },
2874
3055
  []
2875
3056
  );
2876
- const [isHoveringClickablePort, setIsHoveringClickablePort] = useState8(false);
3057
+ const [isHoveringClickablePort, setIsHoveringClickablePort] = useState9(false);
2877
3058
  const hoveringPortsRef = useRef8(/* @__PURE__ */ new Set());
2878
3059
  const handlePortHoverChange = useCallback7(
2879
3060
  (portId, isHovering) => {
@@ -3023,10 +3204,10 @@ var SchematicViewer = ({
3023
3204
  },
3024
3205
  [containerRef, onSchematicComponentClicked]
3025
3206
  );
3026
- useEffect11(() => {
3207
+ useEffect12(() => {
3027
3208
  setSelectedSchematicComponent(null);
3028
3209
  }, [circuitJsonKey, activeSheetId]);
3029
- useEffect11(() => {
3210
+ useEffect12(() => {
3030
3211
  if (!selectedSchematicComponent) return;
3031
3212
  const handleKeyDown = (event) => {
3032
3213
  if (event.key === "Escape") {
@@ -3109,7 +3290,7 @@ var SchematicViewer = ({
3109
3290
  enabled: netHoverHighlightEnabled
3110
3291
  });
3111
3292
  const svgDiv = useMemo6(
3112
- () => /* @__PURE__ */ jsx9(
3293
+ () => /* @__PURE__ */ jsx10(
3113
3294
  "div",
3114
3295
  {
3115
3296
  ref: svgDivRef,
@@ -3123,10 +3304,10 @@ var SchematicViewer = ({
3123
3304
  ),
3124
3305
  [svgString, isInteractionEnabled, clickToInteractEnabled]
3125
3306
  );
3126
- return /* @__PURE__ */ jsxs7(MouseTracker, { children: [
3127
- netHoverHighlightEnabled && /* @__PURE__ */ jsx9("style", { children: `.sch-net-faded { opacity: 0.35; }
3307
+ return /* @__PURE__ */ jsxs8(MouseTracker, { children: [
3308
+ netHoverHighlightEnabled && /* @__PURE__ */ jsx10("style", { children: `.sch-net-faded { opacity: 0.35; }
3128
3309
  svg :is(g.trace, g.trace-overlays, g[data-schematic-component-id], [data-schematic-net-label-id]) { transition: opacity 0.12s ease-in-out; }` }),
3129
- searchEnabled && /* @__PURE__ */ jsx9("style", { children: `.schematic-search-match text,
3310
+ searchEnabled && /* @__PURE__ */ jsx10("style", { children: `.schematic-search-match text,
3130
3311
  text.schematic-search-match {
3131
3312
  fill: #ff00d4 !important;
3132
3313
  }
@@ -3142,9 +3323,9 @@ var SchematicViewer = ({
3142
3323
  flex-direction: column;
3143
3324
  }
3144
3325
  }` }),
3145
- /* @__PURE__ */ jsx9("style", { children: ".schematic-component-clickable [data-schematic-component-id]:hover { cursor: pointer !important; }" }),
3146
- onSchematicPortClicked && /* @__PURE__ */ jsx9("style", { children: "[data-schematic-port-id]:hover { cursor: pointer !important; }" }),
3147
- /* @__PURE__ */ jsxs7(
3326
+ /* @__PURE__ */ jsx10("style", { children: ".schematic-component-clickable [data-schematic-component-id]:hover { cursor: pointer !important; }" }),
3327
+ onSchematicPortClicked && /* @__PURE__ */ jsx10("style", { children: "[data-schematic-port-id]:hover { cursor: pointer !important; }" }),
3328
+ /* @__PURE__ */ jsxs8(
3148
3329
  "div",
3149
3330
  {
3150
3331
  ref: containerRef,
@@ -3179,7 +3360,7 @@ var SchematicViewer = ({
3179
3360
  },
3180
3361
  onTouchCancel: contextMenuEventHandlers.onTouchCancel,
3181
3362
  children: [
3182
- !isInteractionEnabled && clickToInteractEnabled && /* @__PURE__ */ jsx9(
3363
+ !isInteractionEnabled && clickToInteractEnabled && /* @__PURE__ */ jsx10(
3183
3364
  "div",
3184
3365
  {
3185
3366
  onClick: (e) => {
@@ -3198,7 +3379,7 @@ var SchematicViewer = ({
3198
3379
  pointerEvents: "all",
3199
3380
  touchAction: "pan-x pan-y pinch-zoom"
3200
3381
  },
3201
- children: /* @__PURE__ */ jsx9(
3382
+ children: /* @__PURE__ */ jsx10(
3202
3383
  "div",
3203
3384
  {
3204
3385
  style: {
@@ -3215,7 +3396,14 @@ var SchematicViewer = ({
3215
3396
  )
3216
3397
  }
3217
3398
  ),
3218
- menuVisible && /* @__PURE__ */ jsx9(
3399
+ analysisCircuitJson && /* @__PURE__ */ jsx10(
3400
+ StyleAnalysisDialog,
3401
+ {
3402
+ circuitJson: analysisCircuitJson,
3403
+ onClose: () => setAnalysisCircuitJson(null)
3404
+ }
3405
+ ),
3406
+ menuVisible && /* @__PURE__ */ jsx10(
3219
3407
  ViewMenu,
3220
3408
  {
3221
3409
  circuitJson,
@@ -3223,6 +3411,10 @@ var SchematicViewer = ({
3223
3411
  menuRef,
3224
3412
  menuPos,
3225
3413
  onOpenChange: setMenuVisible,
3414
+ onRunStyleAnalysis: () => {
3415
+ setMenuVisible(false);
3416
+ setAnalysisCircuitJson(structuredClone(circuitJson));
3417
+ },
3226
3418
  showPorts: showSchematicPortsInternal,
3227
3419
  onTogglePorts: (value) => {
3228
3420
  setShowSchematicPortsInternal(value);
@@ -3244,7 +3436,7 @@ var SchematicViewer = ({
3244
3436
  onToggleGrid: setShowGridInternal
3245
3437
  }
3246
3438
  ),
3247
- /* @__PURE__ */ jsxs7(
3439
+ /* @__PURE__ */ jsxs8(
3248
3440
  "div",
3249
3441
  {
3250
3442
  className: "schematic-viewer-toolbar",
@@ -3258,7 +3450,7 @@ var SchematicViewer = ({
3258
3450
  zIndex: zIndexMap.schematicSearch
3259
3451
  },
3260
3452
  children: [
3261
- /* @__PURE__ */ jsx9(
3453
+ /* @__PURE__ */ jsx10(
3262
3454
  SchematicSheetSelector,
3263
3455
  {
3264
3456
  sheets: schematicSheets,
@@ -3266,7 +3458,7 @@ var SchematicViewer = ({
3266
3458
  onSelectSheet: handleSelectSheet
3267
3459
  }
3268
3460
  ),
3269
- searchEnabled && /* @__PURE__ */ jsx9(
3461
+ searchEnabled && /* @__PURE__ */ jsx10(
3270
3462
  SchematicSearch,
3271
3463
  {
3272
3464
  query: searchQuery,
@@ -3280,7 +3472,7 @@ var SchematicViewer = ({
3280
3472
  ]
3281
3473
  }
3282
3474
  ),
3283
- schematicComponentIds.map((componentId) => /* @__PURE__ */ jsx9(
3475
+ schematicComponentIds.map((componentId) => /* @__PURE__ */ jsx10(
3284
3476
  SchematicComponentMouseTarget,
3285
3477
  {
3286
3478
  componentId,
@@ -3294,7 +3486,7 @@ var SchematicViewer = ({
3294
3486
  componentId
3295
3487
  )),
3296
3488
  svgDiv,
3297
- selectedComponentDetails && componentTooltipLayout && /* @__PURE__ */ jsx9(
3489
+ selectedComponentDetails && componentTooltipLayout && /* @__PURE__ */ jsx10(
3298
3490
  SchematicComponentDetailsTooltip,
3299
3491
  {
3300
3492
  sourceComponent: selectedComponentDetails.sourceComponent,
@@ -3304,7 +3496,7 @@ var SchematicViewer = ({
3304
3496
  ...componentTooltipLayout
3305
3497
  }
3306
3498
  ),
3307
- showSchematicPortsInternal && schematicPortsInfo.map(({ portId, label }) => /* @__PURE__ */ jsx9(
3499
+ showSchematicPortsInternal && schematicPortsInfo.map(({ portId, label }) => /* @__PURE__ */ jsx10(
3308
3500
  SchematicPortMouseTarget,
3309
3501
  {
3310
3502
  portId,
@@ -3334,7 +3526,7 @@ import {
3334
3526
  convertCircuitJsonToSchematicSimulationSvg,
3335
3527
  convertCircuitJsonToSimulationGraphSvg
3336
3528
  } from "circuit-to-svg";
3337
- import { useEffect as useEffect12, useMemo as useMemo7, useRef as useRef9, useState as useState10 } from "react";
3529
+ import { useEffect as useEffect13, useMemo as useMemo7, useRef as useRef9, useState as useState11 } from "react";
3338
3530
  import { toString as transformToString2 } from "transformation-matrix";
3339
3531
  import { useMouseMatrixTransform as useMouseMatrixTransform2 } from "use-mouse-matrix-transform";
3340
3532
 
@@ -3352,8 +3544,8 @@ var getAnalogSimulationBackgroundColor = (simulationSvg, colorOverrides) => getR
3352
3544
 
3353
3545
  // lib/components/AnalogSimulationSelector.tsx
3354
3546
  import * as DropdownMenu3 from "@radix-ui/react-dropdown-menu";
3355
- import { useState as useState9 } from "react";
3356
- import { Fragment as Fragment5, jsx as jsx10, jsxs as jsxs8 } from "react/jsx-runtime";
3547
+ import { useState as useState10 } from "react";
3548
+ import { Fragment as Fragment6, jsx as jsx11, jsxs as jsxs9 } from "react/jsx-runtime";
3357
3549
  var FONT_FAMILY3 = 'system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif';
3358
3550
  var contentStyles3 = {
3359
3551
  backgroundColor: "#ffffff",
@@ -3403,7 +3595,7 @@ var MENU_CSS2 = `
3403
3595
  .sv-simulation-chevron { transition: transform 0.2s ease; }
3404
3596
  [data-state="open"] > .sv-simulation-chevron { transform: rotate(180deg); }
3405
3597
  `;
3406
- var CheckIcon3 = () => /* @__PURE__ */ jsx10(
3598
+ var CheckIcon3 = () => /* @__PURE__ */ jsx11(
3407
3599
  "svg",
3408
3600
  {
3409
3601
  width: "14",
@@ -3415,10 +3607,10 @@ var CheckIcon3 = () => /* @__PURE__ */ jsx10(
3415
3607
  strokeLinecap: "round",
3416
3608
  strokeLinejoin: "round",
3417
3609
  "aria-hidden": "true",
3418
- children: /* @__PURE__ */ jsx10("path", { d: "M20 6 9 17l-5-5" })
3610
+ children: /* @__PURE__ */ jsx11("path", { d: "M20 6 9 17l-5-5" })
3419
3611
  }
3420
3612
  );
3421
- var ChevronDownIcon2 = ({ className }) => /* @__PURE__ */ jsx10(
3613
+ var ChevronDownIcon2 = ({ className }) => /* @__PURE__ */ jsx11(
3422
3614
  "svg",
3423
3615
  {
3424
3616
  className,
@@ -3432,7 +3624,7 @@ var ChevronDownIcon2 = ({ className }) => /* @__PURE__ */ jsx10(
3432
3624
  strokeLinejoin: "round",
3433
3625
  style: { opacity: 0.6, flexShrink: 0 },
3434
3626
  "aria-hidden": "true",
3435
- children: /* @__PURE__ */ jsx10("path", { d: "m6 9 6 6 6-6" })
3627
+ children: /* @__PURE__ */ jsx11("path", { d: "m6 9 6 6 6-6" })
3436
3628
  }
3437
3629
  );
3438
3630
  var getSimulationLabels = (simulations) => {
@@ -3451,17 +3643,17 @@ var AnalogSimulationSelector = ({
3451
3643
  selectedSimulationExperimentId,
3452
3644
  onSelectSimulation
3453
3645
  }) => {
3454
- const [open, setOpen] = useState9(false);
3646
+ const [open, setOpen] = useState10(false);
3455
3647
  if (simulations.length <= 1) return null;
3456
3648
  const simulationLabels = getSimulationLabels(simulations);
3457
3649
  const selectedSimulation = simulationLabels.find(
3458
3650
  ({ simulation }) => simulation.simulation_experiment_id === selectedSimulationExperimentId
3459
3651
  );
3460
3652
  const selectedLabel = selectedSimulation?.label ?? "Select simulation";
3461
- return /* @__PURE__ */ jsxs8(Fragment5, { children: [
3462
- /* @__PURE__ */ jsx10("style", { children: MENU_CSS2 }),
3463
- /* @__PURE__ */ jsxs8(DropdownMenu3.Root, { open, onOpenChange: setOpen, modal: false, children: [
3464
- /* @__PURE__ */ jsx10(DropdownMenu3.Trigger, { asChild: true, children: /* @__PURE__ */ jsxs8(
3653
+ return /* @__PURE__ */ jsxs9(Fragment6, { children: [
3654
+ /* @__PURE__ */ jsx11("style", { children: MENU_CSS2 }),
3655
+ /* @__PURE__ */ jsxs9(DropdownMenu3.Root, { open, onOpenChange: setOpen, modal: false, children: [
3656
+ /* @__PURE__ */ jsx11(DropdownMenu3.Trigger, { asChild: true, children: /* @__PURE__ */ jsxs9(
3465
3657
  "button",
3466
3658
  {
3467
3659
  type: "button",
@@ -3488,13 +3680,13 @@ var AnalogSimulationSelector = ({
3488
3680
  zIndex: zIndexMap.viewMenuIcon
3489
3681
  },
3490
3682
  children: [
3491
- /* @__PURE__ */ jsx10("span", { style: { color: "#888888", flexShrink: 0 }, children: "Simulation:" }),
3492
- /* @__PURE__ */ jsx10("span", { style: { ...ellipsisStyles2, minWidth: 0 }, children: selectedLabel }),
3493
- /* @__PURE__ */ jsx10(ChevronDownIcon2, { className: "sv-simulation-chevron" })
3683
+ /* @__PURE__ */ jsx11("span", { style: { color: "#888888", flexShrink: 0 }, children: "Simulation:" }),
3684
+ /* @__PURE__ */ jsx11("span", { style: { ...ellipsisStyles2, minWidth: 0 }, children: selectedLabel }),
3685
+ /* @__PURE__ */ jsx11(ChevronDownIcon2, { className: "sv-simulation-chevron" })
3494
3686
  ]
3495
3687
  }
3496
3688
  ) }),
3497
- /* @__PURE__ */ jsx10(DropdownMenu3.Portal, { children: /* @__PURE__ */ jsx10(
3689
+ /* @__PURE__ */ jsx11(DropdownMenu3.Portal, { children: /* @__PURE__ */ jsx11(
3498
3690
  DropdownMenu3.Content,
3499
3691
  {
3500
3692
  style: contentStyles3,
@@ -3504,7 +3696,7 @@ var AnalogSimulationSelector = ({
3504
3696
  collisionPadding: 10,
3505
3697
  children: simulationLabels.map(({ simulation, label }) => {
3506
3698
  const selected = simulation.simulation_experiment_id === selectedSimulationExperimentId;
3507
- return /* @__PURE__ */ jsxs8(
3699
+ return /* @__PURE__ */ jsxs9(
3508
3700
  DropdownMenu3.Item,
3509
3701
  {
3510
3702
  className: "sv-simulation-item",
@@ -3516,8 +3708,8 @@ var AnalogSimulationSelector = ({
3516
3708
  setOpen(false);
3517
3709
  },
3518
3710
  children: [
3519
- /* @__PURE__ */ jsx10("span", { style: iconSlotStyles3, children: selected && /* @__PURE__ */ jsx10(CheckIcon3, {}) }),
3520
- /* @__PURE__ */ jsx10("span", { style: { ...ellipsisStyles2, minWidth: 0 }, children: label })
3711
+ /* @__PURE__ */ jsx11("span", { style: iconSlotStyles3, children: selected && /* @__PURE__ */ jsx11(CheckIcon3, {}) }),
3712
+ /* @__PURE__ */ jsx11("span", { style: { ...ellipsisStyles2, minWidth: 0 }, children: label })
3521
3713
  ]
3522
3714
  },
3523
3715
  simulation.simulation_experiment_id
@@ -3530,7 +3722,7 @@ var AnalogSimulationSelector = ({
3530
3722
  };
3531
3723
 
3532
3724
  // lib/components/AnalogSimulationViewer.tsx
3533
- import { jsx as jsx11, jsxs as jsxs9 } from "react/jsx-runtime";
3725
+ import { jsx as jsx12, jsxs as jsxs10 } from "react/jsx-runtime";
3534
3726
  var DEFAULT_RENDER_WIDTH = 1200;
3535
3727
  var DEFAULT_COMBINED_RENDER_ASPECT_RATIO = 1;
3536
3728
  var DEFAULT_GRAPH_ONLY_RENDER_ASPECT_RATIO = 2;
@@ -3545,16 +3737,16 @@ var AnalogSimulationViewer = ({
3545
3737
  onSimulationChange,
3546
3738
  acSweepView = "magnitude"
3547
3739
  }) => {
3548
- const [circuitJson, setCircuitJson] = useState10(null);
3549
- const [isLoading, setIsLoading] = useState10(true);
3550
- const [error, setError] = useState10(null);
3551
- const [svgObjectUrl, setSvgObjectUrl] = useState10(null);
3740
+ const [circuitJson, setCircuitJson] = useState11(null);
3741
+ const [isLoading, setIsLoading] = useState11(true);
3742
+ const [error, setError] = useState11(null);
3743
+ const [svgObjectUrl, setSvgObjectUrl] = useState11(null);
3552
3744
  const containerRef = useRef9(null);
3553
3745
  const imgRef = useRef9(null);
3554
3746
  const { containerWidth } = useResizeHandling(
3555
3747
  containerRef
3556
3748
  );
3557
- const [isDragging, setIsDragging] = useState10(false);
3749
+ const [isDragging, setIsDragging] = useState11(false);
3558
3750
  const {
3559
3751
  ref: transformRef,
3560
3752
  cancelDrag: _cancelDrag,
@@ -3570,7 +3762,7 @@ var AnalogSimulationViewer = ({
3570
3762
  const renderAspectRatio = width && height ? width / height : defaultRenderAspectRatio;
3571
3763
  const effectiveWidth = width || (height ? height * renderAspectRatio : containerWidth) || DEFAULT_RENDER_WIDTH;
3572
3764
  const effectiveHeight = height || effectiveWidth / renderAspectRatio;
3573
- useEffect12(() => {
3765
+ useEffect13(() => {
3574
3766
  setIsLoading(true);
3575
3767
  setError(null);
3576
3768
  setCircuitJson(inputCircuitJson);
@@ -3582,11 +3774,11 @@ var AnalogSimulationViewer = ({
3582
3774
  (element) => element.type === "simulation_experiment"
3583
3775
  );
3584
3776
  }, [circuitJson]);
3585
- const [selectedSimulationExperimentId, setSelectedSimulationExperimentId] = useState10(null);
3777
+ const [selectedSimulationExperimentId, setSelectedSimulationExperimentId] = useState11(null);
3586
3778
  const simulationExperimentId = (selectedSimulationExperimentId && simulationExperiments.some(
3587
3779
  (simulation) => simulation.simulation_experiment_id === selectedSimulationExperimentId
3588
3780
  ) ? selectedSimulationExperimentId : simulationExperiments[0]?.simulation_experiment_id) ?? null;
3589
- useEffect12(() => {
3781
+ useEffect13(() => {
3590
3782
  if (simulationExperimentId !== selectedSimulationExperimentId) {
3591
3783
  setSelectedSimulationExperimentId(simulationExperimentId);
3592
3784
  }
@@ -3623,7 +3815,7 @@ var AnalogSimulationViewer = ({
3623
3815
  simulationExperimentId,
3624
3816
  acSweepView
3625
3817
  ]);
3626
- useEffect12(() => {
3818
+ useEffect13(() => {
3627
3819
  if (!simulationSvg) {
3628
3820
  setSvgObjectUrl(null);
3629
3821
  return;
@@ -3649,7 +3841,7 @@ var AnalogSimulationViewer = ({
3649
3841
  const handleTouchStart = (_e) => {
3650
3842
  setIsDragging(true);
3651
3843
  };
3652
- useEffect12(() => {
3844
+ useEffect13(() => {
3653
3845
  const handleMouseUp = () => {
3654
3846
  setIsDragging(false);
3655
3847
  };
@@ -3664,7 +3856,7 @@ var AnalogSimulationViewer = ({
3664
3856
  };
3665
3857
  }, []);
3666
3858
  if (isLoading) {
3667
- return /* @__PURE__ */ jsx11(
3859
+ return /* @__PURE__ */ jsx12(
3668
3860
  "div",
3669
3861
  {
3670
3862
  style: {
@@ -3684,7 +3876,7 @@ var AnalogSimulationViewer = ({
3684
3876
  );
3685
3877
  }
3686
3878
  if (error) {
3687
- return /* @__PURE__ */ jsx11(
3879
+ return /* @__PURE__ */ jsx12(
3688
3880
  "div",
3689
3881
  {
3690
3882
  style: {
@@ -3699,15 +3891,15 @@ var AnalogSimulationViewer = ({
3699
3891
  ...containerStyle
3700
3892
  },
3701
3893
  className,
3702
- children: /* @__PURE__ */ jsxs9("div", { style: { textAlign: "center", padding: "20px" }, children: [
3703
- /* @__PURE__ */ jsx11("div", { style: { fontWeight: "bold", marginBottom: "8px" }, children: "Circuit Conversion Error" }),
3704
- /* @__PURE__ */ jsx11("div", { style: { fontSize: "14px" }, children: error })
3894
+ children: /* @__PURE__ */ jsxs10("div", { style: { textAlign: "center", padding: "20px" }, children: [
3895
+ /* @__PURE__ */ jsx12("div", { style: { fontWeight: "bold", marginBottom: "8px" }, children: "Circuit Conversion Error" }),
3896
+ /* @__PURE__ */ jsx12("div", { style: { fontSize: "14px" }, children: error })
3705
3897
  ] })
3706
3898
  }
3707
3899
  );
3708
3900
  }
3709
3901
  if (!simulationSvg) {
3710
- return /* @__PURE__ */ jsxs9(
3902
+ return /* @__PURE__ */ jsxs10(
3711
3903
  "div",
3712
3904
  {
3713
3905
  style: {
@@ -3723,11 +3915,11 @@ var AnalogSimulationViewer = ({
3723
3915
  },
3724
3916
  className,
3725
3917
  children: [
3726
- /* @__PURE__ */ jsx11("div", { style: { fontSize: "16px", color: "#475569", fontWeight: 500 }, children: "No Simulation Found" }),
3727
- /* @__PURE__ */ jsxs9("div", { style: { fontSize: "14px", color: "#64748b" }, children: [
3918
+ /* @__PURE__ */ jsx12("div", { style: { fontSize: "16px", color: "#475569", fontWeight: 500 }, children: "No Simulation Found" }),
3919
+ /* @__PURE__ */ jsxs10("div", { style: { fontSize: "14px", color: "#64748b" }, children: [
3728
3920
  "Use",
3729
3921
  " ",
3730
- /* @__PURE__ */ jsx11(
3922
+ /* @__PURE__ */ jsx12(
3731
3923
  "code",
3732
3924
  {
3733
3925
  style: {
@@ -3747,7 +3939,7 @@ var AnalogSimulationViewer = ({
3747
3939
  }
3748
3940
  );
3749
3941
  }
3750
- return /* @__PURE__ */ jsxs9(
3942
+ return /* @__PURE__ */ jsxs10(
3751
3943
  "div",
3752
3944
  {
3753
3945
  ref: (node) => {
@@ -3766,7 +3958,7 @@ var AnalogSimulationViewer = ({
3766
3958
  onMouseDown: handleMouseDown,
3767
3959
  onTouchStart: handleTouchStart,
3768
3960
  children: [
3769
- /* @__PURE__ */ jsx11(
3961
+ /* @__PURE__ */ jsx12(
3770
3962
  AnalogSimulationSelector,
3771
3963
  {
3772
3964
  simulations: simulationExperiments,
@@ -3774,7 +3966,7 @@ var AnalogSimulationViewer = ({
3774
3966
  onSelectSimulation: handleSelectSimulation
3775
3967
  }
3776
3968
  ),
3777
- svgObjectUrl ? /* @__PURE__ */ jsx11(
3969
+ svgObjectUrl ? /* @__PURE__ */ jsx12(
3778
3970
  "img",
3779
3971
  {
3780
3972
  ref: imgRef,
@@ -3788,7 +3980,7 @@ var AnalogSimulationViewer = ({
3788
3980
  objectFit: "contain"
3789
3981
  }
3790
3982
  }
3791
- ) : /* @__PURE__ */ jsx11(
3983
+ ) : /* @__PURE__ */ jsx12(
3792
3984
  "div",
3793
3985
  {
3794
3986
  style: {