@tscircuit/schematic-viewer 2.0.41 → 2.0.42
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
|
@@ -846,7 +846,7 @@ import { su as su5 } from "@tscircuit/soup-util";
|
|
|
846
846
|
// package.json
|
|
847
847
|
var package_default = {
|
|
848
848
|
name: "@tscircuit/schematic-viewer",
|
|
849
|
-
version: "2.0.
|
|
849
|
+
version: "2.0.41",
|
|
850
850
|
main: "dist/index.js",
|
|
851
851
|
type: "module",
|
|
852
852
|
scripts: {
|
|
@@ -1148,7 +1148,8 @@ var SpicePlot = ({
|
|
|
1148
1148
|
plotData,
|
|
1149
1149
|
nodes,
|
|
1150
1150
|
isLoading,
|
|
1151
|
-
error
|
|
1151
|
+
error,
|
|
1152
|
+
hasRun
|
|
1152
1153
|
}) => {
|
|
1153
1154
|
const yAxisLabel = useMemo2(() => {
|
|
1154
1155
|
const hasVoltage = nodes.some((n) => n.toLowerCase().startsWith("v("));
|
|
@@ -1173,6 +1174,21 @@ var SpicePlot = ({
|
|
|
1173
1174
|
}
|
|
1174
1175
|
);
|
|
1175
1176
|
}
|
|
1177
|
+
if (!hasRun) {
|
|
1178
|
+
return /* @__PURE__ */ jsx7(
|
|
1179
|
+
"div",
|
|
1180
|
+
{
|
|
1181
|
+
style: {
|
|
1182
|
+
height: "300px",
|
|
1183
|
+
width: "100%",
|
|
1184
|
+
display: "flex",
|
|
1185
|
+
alignItems: "center",
|
|
1186
|
+
justifyContent: "center"
|
|
1187
|
+
},
|
|
1188
|
+
children: 'Click "Run" to start the simulation.'
|
|
1189
|
+
}
|
|
1190
|
+
);
|
|
1191
|
+
}
|
|
1176
1192
|
if (error) {
|
|
1177
1193
|
return /* @__PURE__ */ jsxs4(
|
|
1178
1194
|
"div",
|
|
@@ -1294,7 +1310,8 @@ var SpiceSimulationOverlay = ({
|
|
|
1294
1310
|
isLoading,
|
|
1295
1311
|
error,
|
|
1296
1312
|
simOptions,
|
|
1297
|
-
onSimOptionsChange
|
|
1313
|
+
onSimOptionsChange,
|
|
1314
|
+
hasRun
|
|
1298
1315
|
}) => {
|
|
1299
1316
|
const [startTimeDraft, setStartTimeDraft] = useState3(
|
|
1300
1317
|
String(simOptions.startTime)
|
|
@@ -1397,7 +1414,8 @@ var SpiceSimulationOverlay = ({
|
|
|
1397
1414
|
plotData,
|
|
1398
1415
|
nodes: filteredNodes,
|
|
1399
1416
|
isLoading,
|
|
1400
|
-
error
|
|
1417
|
+
error,
|
|
1418
|
+
hasRun
|
|
1401
1419
|
}
|
|
1402
1420
|
) }),
|
|
1403
1421
|
/* @__PURE__ */ jsxs5(
|
|
@@ -1501,7 +1519,7 @@ var SpiceSimulationOverlay = ({
|
|
|
1501
1519
|
backgroundColor: "#f0f0f0",
|
|
1502
1520
|
cursor: "pointer"
|
|
1503
1521
|
},
|
|
1504
|
-
children: "Rerun"
|
|
1522
|
+
children: hasRun ? "Rerun" : "Run"
|
|
1505
1523
|
}
|
|
1506
1524
|
)
|
|
1507
1525
|
] })
|
|
@@ -1807,12 +1825,16 @@ var SchematicViewer = ({
|
|
|
1807
1825
|
spiceSimOptions.startTime,
|
|
1808
1826
|
spiceSimOptions.duration
|
|
1809
1827
|
]);
|
|
1828
|
+
const [hasSpiceSimRun, setHasSpiceSimRun] = useState5(false);
|
|
1829
|
+
useEffect8(() => {
|
|
1830
|
+
setHasSpiceSimRun(false);
|
|
1831
|
+
}, [circuitJsonKey]);
|
|
1810
1832
|
const {
|
|
1811
1833
|
plotData,
|
|
1812
1834
|
nodes,
|
|
1813
1835
|
isLoading: isSpiceSimLoading,
|
|
1814
1836
|
error: spiceSimError
|
|
1815
|
-
} = useSpiceSimulation(spiceString);
|
|
1837
|
+
} = useSpiceSimulation(hasSpiceSimRun ? spiceString : null);
|
|
1816
1838
|
const [editModeEnabled, setEditModeEnabled] = useState5(defaultEditMode);
|
|
1817
1839
|
const [snapToGrid, setSnapToGrid] = useState5(true);
|
|
1818
1840
|
const [isInteractionEnabled, setIsInteractionEnabled] = useState5(
|
|
@@ -2094,7 +2116,11 @@ var SchematicViewer = ({
|
|
|
2094
2116
|
isLoading: isSpiceSimLoading,
|
|
2095
2117
|
error: spiceSimError,
|
|
2096
2118
|
simOptions: spiceSimOptions,
|
|
2097
|
-
onSimOptionsChange:
|
|
2119
|
+
onSimOptionsChange: (options) => {
|
|
2120
|
+
setHasSpiceSimRun(true);
|
|
2121
|
+
setSpiceSimOptions(options);
|
|
2122
|
+
},
|
|
2123
|
+
hasRun: hasSpiceSimRun
|
|
2098
2124
|
}
|
|
2099
2125
|
),
|
|
2100
2126
|
svgDiv
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../lib/components/SchematicViewer.tsx","../lib/hooks/useChangeSchematicComponentLocationsInSvg.ts","../lib/utils/get-component-offset-due-to-events.ts","../lib/hooks/useChangeSchematicTracesForMovedComponents.ts","../lib/hooks/useSchematicGroupsOverlay.ts","../lib/utils/debug.ts","../lib/hooks/use-resize-handling.ts","../lib/hooks/useComponentDragging.ts","../lib/utils/z-index-map.ts","../lib/components/EditIcon.tsx","../lib/components/GridIcon.tsx","../lib/components/ViewMenuIcon.tsx","../lib/components/ViewMenu.tsx","../package.json","../lib/components/SpiceIcon.tsx","../lib/components/SpiceSimulationIcon.tsx","../lib/components/SpicePlot.tsx","../lib/components/SpiceSimulationOverlay.tsx","../lib/hooks/useSpiceSimulation.ts","../lib/workers/spice-simulation.worker.blob.js","../lib/utils/spice-utils.ts","../lib/hooks/useLocalStorage.ts"],"sourcesContent":["import {\n convertCircuitJsonToSchematicSvg,\n type ColorOverrides,\n} from \"circuit-to-svg\"\nimport { useChangeSchematicComponentLocationsInSvg } from \"lib/hooks/useChangeSchematicComponentLocationsInSvg\"\nimport { useChangeSchematicTracesForMovedComponents } from \"lib/hooks/useChangeSchematicTracesForMovedComponents\"\nimport { useSchematicGroupsOverlay } from \"lib/hooks/useSchematicGroupsOverlay\"\nimport { enableDebug } from \"lib/utils/debug\"\nimport { useEffect, useMemo, useRef, useState } from \"react\"\nimport {\n fromString,\n identity,\n toString as transformToString,\n} from \"transformation-matrix\"\nimport { useMouseMatrixTransform } from \"use-mouse-matrix-transform\"\nimport { useResizeHandling } from \"../hooks/use-resize-handling\"\nimport { useComponentDragging } from \"../hooks/useComponentDragging\"\nimport type { ManualEditEvent } from \"../types/edit-events\"\nimport { EditIcon } from \"./EditIcon\"\nimport { GridIcon } from \"./GridIcon\"\nimport { ViewMenuIcon } from \"./ViewMenuIcon\"\nimport { ViewMenu } from \"./ViewMenu\"\nimport type { CircuitJson } from \"circuit-json\"\nimport { SpiceSimulationIcon } from \"./SpiceSimulationIcon\"\nimport { SpiceSimulationOverlay } from \"./SpiceSimulationOverlay\"\nimport { zIndexMap } from \"../utils/z-index-map\"\nimport { useSpiceSimulation } from \"../hooks/useSpiceSimulation\"\nimport { getSpiceFromCircuitJson } from \"../utils/spice-utils\"\nimport { getStoredBoolean, setStoredBoolean } from \"lib/hooks/useLocalStorage\"\n\ninterface Props {\n circuitJson: CircuitJson\n containerStyle?: React.CSSProperties\n editEvents?: ManualEditEvent[]\n onEditEvent?: (event: ManualEditEvent) => void\n defaultEditMode?: boolean\n debugGrid?: boolean\n editingEnabled?: boolean\n debug?: boolean\n clickToInteractEnabled?: boolean\n colorOverrides?: ColorOverrides\n spiceSimulationEnabled?: boolean\n disableGroups?: boolean\n}\n\nexport const SchematicViewer = ({\n circuitJson,\n containerStyle,\n editEvents: unappliedEditEvents = [],\n onEditEvent,\n defaultEditMode = false,\n debugGrid = false,\n editingEnabled = false,\n debug = false,\n clickToInteractEnabled = false,\n colorOverrides,\n spiceSimulationEnabled = false,\n disableGroups = false,\n}: Props) => {\n if (debug) {\n enableDebug()\n }\n const [showSpiceOverlay, setShowSpiceOverlay] = useState(false)\n const [spiceSimOptions, setSpiceSimOptions] = useState({\n showVoltage: true,\n showCurrent: false,\n startTime: 0, // in ms\n duration: 20, // in ms\n })\n\n const getCircuitHash = (circuitJson: CircuitJson) => {\n return `${circuitJson?.length || 0}_${(circuitJson as any)?.editCount || 0}`\n }\n\n const circuitJsonKey = useMemo(\n () => getCircuitHash(circuitJson),\n [circuitJson],\n )\n\n const spiceString = useMemo(() => {\n if (!spiceSimulationEnabled) return null\n try {\n return getSpiceFromCircuitJson(circuitJson, spiceSimOptions)\n } catch (e) {\n console.error(\"Failed to generate SPICE string\", e)\n return null\n }\n }, [\n circuitJsonKey,\n spiceSimulationEnabled,\n spiceSimOptions.startTime,\n spiceSimOptions.duration,\n ])\n\n const {\n plotData,\n nodes,\n isLoading: isSpiceSimLoading,\n error: spiceSimError,\n } = useSpiceSimulation(spiceString)\n\n const [editModeEnabled, setEditModeEnabled] = useState(defaultEditMode)\n const [snapToGrid, setSnapToGrid] = useState(true)\n const [isInteractionEnabled, setIsInteractionEnabled] = useState<boolean>(\n !clickToInteractEnabled,\n )\n const [showViewMenu, setShowViewMenu] = useState(false)\n const [showSchematicGroups, setShowSchematicGroups] = useState(() => {\n if (disableGroups) return false\n return getStoredBoolean(\"schematic_viewer_show_groups\", false)\n })\n const svgDivRef = useRef<HTMLDivElement>(null)\n const touchStartRef = useRef<{ x: number; y: number } | null>(null)\n\n const handleTouchStart = (e: React.TouchEvent) => {\n const touch = e.touches[0]\n touchStartRef.current = {\n x: touch.clientX,\n y: touch.clientY,\n }\n }\n\n const handleTouchEnd = (e: React.TouchEvent) => {\n const touch = e.changedTouches[0]\n const start = touchStartRef.current\n if (!start) return\n\n const deltaX = Math.abs(touch.clientX - start.x)\n const deltaY = Math.abs(touch.clientY - start.y)\n\n if (deltaX < 10 && deltaY < 10) {\n e.preventDefault()\n setIsInteractionEnabled(true)\n }\n\n touchStartRef.current = null\n }\n\n const [internalEditEvents, setInternalEditEvents] = useState<\n ManualEditEvent[]\n >([])\n const circuitJsonRef = useRef<CircuitJson>(circuitJson)\n\n useEffect(() => {\n const circuitHash = getCircuitHash(circuitJson)\n const circuitHashRef = getCircuitHash(circuitJsonRef.current)\n\n if (circuitHash !== circuitHashRef) {\n setInternalEditEvents([])\n circuitJsonRef.current = circuitJson\n }\n }, [circuitJson])\n\n const {\n ref: containerRef,\n cancelDrag,\n transform: svgToScreenProjection,\n } = useMouseMatrixTransform({\n onSetTransform(transform) {\n if (!svgDivRef.current) return\n svgDivRef.current.style.transform = transformToString(transform)\n },\n // @ts-ignore disabled is a valid prop but not typed\n enabled: isInteractionEnabled && !showSpiceOverlay,\n })\n\n const { containerWidth, containerHeight } = useResizeHandling(containerRef)\n const svgString = useMemo(() => {\n if (!containerWidth || !containerHeight) return \"\"\n\n return convertCircuitJsonToSchematicSvg(circuitJson as any, {\n width: containerWidth,\n height: containerHeight || 720,\n grid: !debugGrid\n ? undefined\n : {\n cellSize: 1,\n labelCells: true,\n },\n colorOverrides,\n })\n }, [circuitJsonKey, containerWidth, containerHeight])\n\n const containerBackgroundColor = useMemo(() => {\n const match = svgString.match(\n /<svg[^>]*style=\"[^\"]*background-color:\\s*([^;\\\"]+)/i,\n )\n return match?.[1] ?? \"transparent\"\n }, [svgString])\n\n const realToSvgProjection = useMemo(() => {\n if (!svgString) return identity()\n const transformString = svgString.match(\n /data-real-to-screen-transform=\"([^\"]+)\"/,\n )?.[1]!\n\n try {\n return fromString(transformString)\n } catch (e) {\n console.error(e)\n return identity()\n }\n }, [svgString])\n\n const handleEditEvent = (event: ManualEditEvent) => {\n setInternalEditEvents((prev) => [...prev, event])\n if (onEditEvent) {\n onEditEvent(event)\n }\n }\n\n const editEventsWithUnappliedEditEvents = useMemo(() => {\n return [...unappliedEditEvents, ...internalEditEvents]\n }, [unappliedEditEvents, internalEditEvents])\n\n const {\n handleMouseDown,\n handleTouchStart: handleComponentTouchStart,\n isDragging,\n activeEditEvent,\n } = useComponentDragging({\n onEditEvent: handleEditEvent,\n cancelDrag,\n realToSvgProjection,\n svgToScreenProjection,\n circuitJson,\n editEvents: editEventsWithUnappliedEditEvents,\n enabled: editModeEnabled && isInteractionEnabled && !showSpiceOverlay,\n snapToGrid,\n })\n\n useChangeSchematicComponentLocationsInSvg({\n svgDivRef,\n editEvents: editEventsWithUnappliedEditEvents,\n realToSvgProjection,\n svgToScreenProjection,\n activeEditEvent,\n })\n\n useChangeSchematicTracesForMovedComponents({\n svgDivRef,\n circuitJson,\n activeEditEvent,\n editEvents: editEventsWithUnappliedEditEvents,\n })\n\n // Add group overlays when enabled\n useSchematicGroupsOverlay({\n svgDivRef,\n circuitJson,\n circuitJsonKey,\n showGroups: showSchematicGroups && !disableGroups,\n })\n\n // keep the latest touch handler without re-rendering the svg div\n const handleComponentTouchStartRef = useRef(handleComponentTouchStart)\n useEffect(() => {\n handleComponentTouchStartRef.current = handleComponentTouchStart\n }, [handleComponentTouchStart])\n\n const svgDiv = useMemo(\n () => (\n <div\n ref={svgDivRef}\n style={{\n pointerEvents: clickToInteractEnabled\n ? isInteractionEnabled\n ? \"auto\"\n : \"none\"\n : \"auto\",\n transformOrigin: \"0 0\",\n }}\n onTouchStart={(e) => {\n if (editModeEnabled && isInteractionEnabled && !showSpiceOverlay) {\n handleComponentTouchStartRef.current(e)\n }\n }}\n // biome-ignore lint/security/noDangerouslySetInnerHtml: <explanation>\n dangerouslySetInnerHTML={{ __html: svgString }}\n />\n ),\n [\n svgString,\n isInteractionEnabled,\n clickToInteractEnabled,\n editModeEnabled,\n showSpiceOverlay,\n ],\n )\n\n return (\n <div\n ref={containerRef}\n style={{\n position: \"relative\",\n backgroundColor: containerBackgroundColor,\n overflow: \"hidden\",\n cursor: showSpiceOverlay\n ? \"auto\"\n : isDragging\n ? \"grabbing\"\n : clickToInteractEnabled && !isInteractionEnabled\n ? \"pointer\"\n : \"grab\",\n minHeight: \"300px\",\n ...containerStyle,\n }}\n onWheelCapture={(e) => {\n if (showSpiceOverlay) {\n e.stopPropagation()\n }\n }}\n onMouseDown={(e) => {\n if (clickToInteractEnabled && !isInteractionEnabled) {\n e.preventDefault()\n e.stopPropagation()\n return\n }\n handleMouseDown(e)\n }}\n onMouseDownCapture={(e) => {\n if (clickToInteractEnabled && !isInteractionEnabled) {\n e.preventDefault()\n e.stopPropagation()\n return\n }\n }}\n onTouchStart={(e) => {\n if (showSpiceOverlay) return\n handleTouchStart(e)\n }}\n onTouchEnd={(e) => {\n if (showSpiceOverlay) return\n handleTouchEnd(e)\n }}\n >\n {!isInteractionEnabled && clickToInteractEnabled && (\n <div\n onClick={(e) => {\n e.preventDefault()\n e.stopPropagation()\n setIsInteractionEnabled(true)\n }}\n style={{\n position: \"absolute\",\n inset: 0,\n cursor: \"pointer\",\n zIndex: zIndexMap.clickToInteractOverlay,\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n pointerEvents: \"all\",\n touchAction: \"pan-x pan-y pinch-zoom\",\n }}\n >\n <div\n style={{\n backgroundColor: \"rgba(0, 0, 0, 0.8)\",\n color: \"white\",\n padding: \"12px 24px\",\n borderRadius: \"8px\",\n fontSize: \"16px\",\n fontFamily: \"sans-serif\",\n pointerEvents: \"none\",\n }}\n >\n {typeof window !== \"undefined\" &&\n (\"ontouchstart\" in window || navigator.maxTouchPoints > 0)\n ? \"Touch to Interact\"\n : \"Click to Interact\"}\n </div>\n </div>\n )}\n <ViewMenuIcon\n active={showViewMenu}\n onClick={() => setShowViewMenu(!showViewMenu)}\n />\n {editingEnabled && (\n <EditIcon\n active={editModeEnabled}\n onClick={() => setEditModeEnabled(!editModeEnabled)}\n />\n )}\n {editingEnabled && editModeEnabled && (\n <GridIcon\n active={snapToGrid}\n onClick={() => setSnapToGrid(!snapToGrid)}\n />\n )}\n <ViewMenu\n circuitJson={circuitJson}\n circuitJsonKey={circuitJsonKey}\n isVisible={showViewMenu}\n onClose={() => setShowViewMenu(false)}\n showGroups={showSchematicGroups}\n onToggleGroups={(value) => {\n if (!disableGroups) {\n setShowSchematicGroups(value)\n setStoredBoolean(\"schematic_viewer_show_groups\", value)\n }\n }}\n />\n {spiceSimulationEnabled && (\n <SpiceSimulationIcon onClick={() => setShowSpiceOverlay(true)} />\n )}\n {showSpiceOverlay && (\n <SpiceSimulationOverlay\n spiceString={spiceString}\n onClose={() => setShowSpiceOverlay(false)}\n plotData={plotData}\n nodes={nodes}\n isLoading={isSpiceSimLoading}\n error={spiceSimError}\n simOptions={spiceSimOptions}\n onSimOptionsChange={setSpiceSimOptions}\n />\n )}\n {svgDiv}\n </div>\n )\n}\n","import { su } from \"@tscircuit/soup-util\"\nimport type {\n ManualEditEvent,\n EditSchematicComponentLocationEventWithElement,\n} from \"lib/types/edit-events\"\nimport { type Matrix, compose, applyToPoint } from \"transformation-matrix\"\nimport { useEffect, useRef } from \"react\"\nimport { getComponentOffsetDueToEvents } from \"lib/utils/get-component-offset-due-to-events\"\nimport type { CircuitJson } from \"circuit-json\"\n\n/**\n * This hook automatically applies the edit events to the schematic components\n * inside the svg div.\n *\n * Schematic components are \"<g>\" elements with a \"data-circuit-json-type\"\n * attribute equal to \"schematic_component\", these elements also have a\n * data-schematic-component-id attribute equal to the schematic_component_id\n */\nexport const useChangeSchematicComponentLocationsInSvg = ({\n svgDivRef,\n realToSvgProjection,\n svgToScreenProjection,\n activeEditEvent,\n editEvents,\n}: {\n svgDivRef: React.RefObject<HTMLDivElement | null>\n realToSvgProjection: Matrix\n svgToScreenProjection: Matrix\n activeEditEvent: EditSchematicComponentLocationEventWithElement | null\n editEvents: ManualEditEvent[]\n}) => {\n // Keep track of the last known SVG content\n const lastSvgContentRef = useRef<string | null>(null)\n\n useEffect(() => {\n const svg = svgDivRef.current\n if (!svg) return\n\n // Create a MutationObserver to watch for changes in the div's content\n const observer = new MutationObserver((mutations) => {\n // Check if the SVG content has changed\n const currentSvgContent = svg.innerHTML\n if (currentSvgContent !== lastSvgContentRef.current) {\n lastSvgContentRef.current = currentSvgContent\n\n // Apply the transforms\n applyTransforms()\n }\n })\n\n // Function to apply transforms to components\n const applyTransforms = () => {\n const componentsThatHaveBeenMoved = new Set<string>()\n for (const event of editEvents) {\n if (\n \"edit_event_type\" in event &&\n event.edit_event_type === \"edit_schematic_component_location\"\n ) {\n componentsThatHaveBeenMoved.add(event.schematic_component_id)\n }\n }\n if (activeEditEvent) {\n componentsThatHaveBeenMoved.add(activeEditEvent.schematic_component_id)\n }\n\n // Reset all transforms\n const allComponents = svg.querySelectorAll(\n '[data-circuit-json-type=\"schematic_component\"]',\n )\n\n for (const component of Array.from(allComponents)) {\n const schematic_component_id = component.getAttribute(\n \"data-schematic-component-id\",\n )!\n\n const offsetMm = getComponentOffsetDueToEvents({\n editEvents: [\n ...editEvents,\n ...(activeEditEvent ? [activeEditEvent] : []),\n ],\n schematic_component_id,\n })\n\n const offsetPx = {\n x: offsetMm.x * realToSvgProjection.a,\n y: offsetMm.y * realToSvgProjection.d,\n }\n\n const style: any = (component as any).style\n style.transform = `translate(${offsetPx.x}px, ${offsetPx.y}px)`\n if (\n activeEditEvent?.schematic_component_id === schematic_component_id\n ) {\n style.outline = \"solid 2px rgba(255,0,0,0.5)\"\n style.outlineOffset = \"5px\"\n } else if (style.outline) {\n style.outline = \"\"\n }\n }\n }\n\n // Start observing the div for changes\n observer.observe(svg, {\n childList: true, // Watch for changes to the child elements\n subtree: false, // Watch for changes in the entire subtree\n characterData: false, // Watch for changes to text content\n })\n\n // Apply transforms immediately on mount or when editEvents change\n applyTransforms()\n\n // Cleanup function\n return () => {\n observer.disconnect()\n }\n }, [svgDivRef, editEvents, activeEditEvent]) // Dependencies remain the same\n}\n","import type {\n EditSchematicComponentLocationEvent,\n EditSchematicComponentLocationEventWithElement,\n ManualEditEvent,\n} from \"lib/types/edit-events\"\n\n/**\n * Returns the total offset of a component due to a set of edit events in\n * mm\n */\nexport const getComponentOffsetDueToEvents = ({\n editEvents,\n schematic_component_id,\n}: {\n editEvents: ManualEditEvent[]\n schematic_component_id: string\n}) => {\n const editEventsForComponent: EditSchematicComponentLocationEvent[] =\n editEvents\n .filter(\n (event) =>\n \"schematic_component_id\" in event &&\n event.schematic_component_id === schematic_component_id,\n )\n .filter(\n (event) =>\n \"edit_event_type\" in event &&\n event.edit_event_type === \"edit_schematic_component_location\",\n )\n\n const totalOffsetX = editEventsForComponent.reduce((acc, event) => {\n return acc + event.new_center.x - event.original_center.x\n }, 0)\n\n const totalOffsetY = editEventsForComponent.reduce((acc, event) => {\n return acc + event.new_center.y - event.original_center.y\n }, 0)\n\n return {\n x: totalOffsetX,\n y: totalOffsetY,\n }\n}\n","import { useEffect, useRef } from \"react\"\nimport { su } from \"@tscircuit/soup-util\"\nimport type { ManualEditEvent } from \"../types/edit-events\"\nimport type { CircuitJson } from \"circuit-json\"\n\n/**\n * This hook makes traces dashed when their connected components are being moved\n */\nexport const useChangeSchematicTracesForMovedComponents = ({\n svgDivRef,\n circuitJson,\n activeEditEvent,\n editEvents,\n}: {\n svgDivRef: React.RefObject<HTMLDivElement | null>\n circuitJson: CircuitJson\n activeEditEvent: ManualEditEvent | null\n editEvents: ManualEditEvent[]\n}) => {\n // Keep track of the last known SVG content\n const lastSvgContentRef = useRef<string | null>(null)\n\n useEffect(() => {\n const svg = svgDivRef.current\n if (!svg) return\n\n const updateTraceStyles = () => {\n // Reset all traces to solid\n const allTraces = svg.querySelectorAll(\n '[data-circuit-json-type=\"schematic_trace\"] path',\n )\n\n // Reset all traces to solid\n for (const trace of Array.from(allTraces)) {\n trace.setAttribute(\"stroke-dasharray\", \"0\")\n ;(trace as any).style.animation = \"\"\n }\n\n // If there's an active edit event, make connected traces dashed\n for (const editEvent of [\n ...editEvents,\n ...(activeEditEvent ? [activeEditEvent] : []),\n ]) {\n if (\n \"schematic_component_id\" in editEvent &&\n editEvent.edit_event_type === \"edit_schematic_component_location\"\n ) {\n const sch_component = su(circuitJson).schematic_component.get(\n editEvent.schematic_component_id,\n )\n if (!sch_component) return\n\n const src_ports = su(circuitJson).source_port.list({\n source_component_id: sch_component.source_component_id,\n })\n const src_port_ids = new Set(src_ports.map((sp) => sp.source_port_id))\n const src_traces = su(circuitJson)\n .source_trace.list()\n .filter((st) =>\n st.connected_source_port_ids?.some((spi) =>\n src_port_ids.has(spi),\n ),\n )\n const src_trace_ids = new Set(\n src_traces.map((st) => st.source_trace_id),\n )\n const schematic_traces = su(circuitJson)\n .schematic_trace.list()\n .filter((st) => src_trace_ids.has(st.source_trace_id))\n\n // Make the connected traces dashed\n schematic_traces.forEach((trace) => {\n const traceElements = svg.querySelectorAll(\n `[data-schematic-trace-id=\"${trace.schematic_trace_id}\"] path`,\n )\n for (const traceElement of Array.from(traceElements)) {\n if (traceElement.getAttribute(\"class\")?.includes(\"invisible\"))\n continue\n traceElement.setAttribute(\"stroke-dasharray\", \"20,20\")\n ;(traceElement as any).style.animation =\n \"dash-animation 350ms linear infinite, pulse-animation 900ms linear infinite\"\n\n if (!svg.querySelector(\"style#dash-animation\")) {\n const style = document.createElement(\"style\")\n style.id = \"dash-animation\"\n style.textContent = `\n @keyframes dash-animation {\n to {\n stroke-dashoffset: -40;\n }\n }\n @keyframes pulse-animation {\n 0% { opacity: 0.6; }\n 50% { opacity: 0.2; }\n 100% { opacity: 0.6; }\n }\n `\n svg.appendChild(style)\n }\n }\n })\n }\n }\n }\n\n // Apply styles immediately\n updateTraceStyles()\n\n // Cleanup function\n const observer = new MutationObserver(updateTraceStyles)\n observer.observe(svg, {\n childList: true, // Watch for changes to the child elements\n subtree: false, // Watch for changes in the entire subtree\n characterData: false, // Watch for changes to text content\n })\n\n return () => {\n observer.disconnect()\n }\n }, [svgDivRef, activeEditEvent, circuitJson, editEvents])\n}\n","import { useEffect } from \"react\"\nimport { su } from \"@tscircuit/soup-util\"\nimport type { CircuitJson } from \"circuit-json\"\n\ninterface UseSchematicGroupsOverlayOptions {\n svgDivRef: React.RefObject<HTMLDivElement | null>\n circuitJson: CircuitJson\n circuitJsonKey: string\n showGroups: boolean\n}\n\nconst GROUP_COLORS = [\n \"#8B0000\", // Dark Red\n \"#2F4F4F\", // Dark Slate Gray\n \"#191970\", // Midnight Blue\n \"#006400\", // Dark Green\n \"#FF4500\", // Dark Orange\n \"#800080\", // Purple\n \"#2E8B57\", // Sea Green\n \"#B8860B\", // Dark Goldenrod\n \"#C71585\", // Medium Violet Red\n \"#008B8B\", // Dark Cyan\n]\n\nexport const useSchematicGroupsOverlay = (\n options: UseSchematicGroupsOverlayOptions,\n) => {\n const { svgDivRef, circuitJson, circuitJsonKey, showGroups } = options\n\n useEffect(() => {\n // Always clean up existing overlays first\n if (svgDivRef.current) {\n const existingOverlays = svgDivRef.current.querySelectorAll(\n \".schematic-group-overlay\",\n )\n existingOverlays.forEach((overlay) => overlay.remove())\n }\n\n if (\n !svgDivRef.current ||\n !showGroups ||\n !circuitJson ||\n circuitJson.length === 0\n ) {\n return\n }\n\n // Small delay to ensure SVG is rendered when groups are enabled from localStorage\n const timeoutId = setTimeout(() => {\n if (!svgDivRef.current) return\n\n const svg = svgDivRef.current.querySelector(\"svg\")\n if (!svg) {\n return\n }\n\n const existingOverlays = svg.querySelectorAll(\".schematic-group-overlay\")\n existingOverlays.forEach((overlay) => overlay.remove())\n\n try {\n const sourceGroups =\n su(circuitJson)\n .source_group?.list()\n .filter((x) => !!!x.is_subcircuit) || []\n const schematicComponents =\n su(circuitJson).schematic_component?.list() || []\n\n const sourceGroupHierarchy = new Map<string, string[]>()\n sourceGroups.forEach((group) => {\n const groupWithParent = group as any\n if (groupWithParent.parent_source_group_id) {\n const children =\n sourceGroupHierarchy.get(\n groupWithParent.parent_source_group_id,\n ) || []\n children.push(group.source_group_id)\n sourceGroupHierarchy.set(\n groupWithParent.parent_source_group_id,\n children,\n )\n }\n })\n\n const getAllDescendantSourceGroups = (\n sourceGroupId: string,\n ): string[] => {\n const descendants: string[] = []\n const children = sourceGroupHierarchy.get(sourceGroupId) || []\n for (const child of children) {\n descendants.push(child)\n descendants.push(...getAllDescendantSourceGroups(child))\n }\n return descendants\n }\n\n const getGroupDepthLevel = (sourceGroupId: string): number => {\n const groupWithParent = sourceGroups.find(\n (g) => g.source_group_id === sourceGroupId,\n ) as any\n if (!groupWithParent?.parent_source_group_id) {\n return 0\n }\n return 1 + getGroupDepthLevel(groupWithParent.parent_source_group_id)\n }\n\n const hasMeaningfulGroups =\n sourceGroups.length > 0 &&\n sourceGroups.some((group) => group.name && group.name.trim() !== \"\")\n\n let groupsToRender: Array<{\n id: string\n name: string\n components: any[]\n color: string\n depthLevel: number\n hasChildren: boolean\n sourceGroupId?: string\n }> = []\n\n if (hasMeaningfulGroups) {\n const groupMap = new Map<string, any[]>()\n\n for (const comp of schematicComponents) {\n const sourceComp = su(circuitJson).source_component.get(\n comp.source_component_id,\n )\n if (sourceComp?.source_group_id) {\n if (!groupMap.has(sourceComp.source_group_id)) {\n groupMap.set(sourceComp.source_group_id, [])\n }\n groupMap.get(sourceComp.source_group_id)!.push(comp)\n }\n }\n\n sourceGroups.forEach((group, index) => {\n let groupComponents = groupMap.get(group.source_group_id) || []\n\n const descendantGroups = getAllDescendantSourceGroups(\n group.source_group_id,\n )\n for (const descendantGroupId of descendantGroups) {\n const descendantComponents = groupMap.get(descendantGroupId) || []\n groupComponents = [...groupComponents, ...descendantComponents]\n }\n\n if (groupComponents.length > 0) {\n const depthLevel = getGroupDepthLevel(group.source_group_id)\n const hasChildren =\n getAllDescendantSourceGroups(group.source_group_id).length > 0\n\n if (group.name?.startsWith(\"unnamed_board\")) return\n groupsToRender.push({\n id: group.source_group_id,\n name: group.name || `Group ${index + 1}`,\n components: groupComponents,\n color: GROUP_COLORS[index % GROUP_COLORS.length],\n depthLevel,\n hasChildren,\n sourceGroupId: group.source_group_id,\n })\n }\n })\n }\n // else {\n // const componentTypeGroups = new Map<string, any[]>()\n\n // for (const comp of schematicComponents) {\n // const sourceComp = su(circuitJson).source_component.get(comp.source_component_id)\n // if (sourceComp) {\n // const componentType = sourceComp.ftype || \"other\"\n // if (!componentTypeGroups.has(componentType)) {\n // componentTypeGroups.set(componentType, [])\n // }\n // componentTypeGroups.get(componentType)!.push(comp)\n // }\n // }\n // // groupsToRender = Array.from(componentTypeGroups.entries()).map(\n // // ([type, components], index) => ({\n // // id: `type_${type}`,\n // // name: `${type.charAt(0).toUpperCase() + type.slice(1)}s`,\n // // components,\n // // color: GROUP_COLORS[index % GROUP_COLORS.length],\n // // depthLevel: 0,\n // // hasChildren: false,\n // // }),\n // // )\n // }\n\n const viewBox = svg.viewBox.baseVal\n const svgRect = svg.getBoundingClientRect()\n const scale =\n Math.min(\n svgRect.width / viewBox.width,\n svgRect.height / viewBox.height,\n ) || 1\n\n groupsToRender.sort((a, b) => a.depthLevel - b.depthLevel)\n\n groupsToRender.forEach((group) => {\n if (group.components.length === 0) return\n\n const groupBounds = calculateGroupBounds(group.components, svg)\n if (!groupBounds) return\n\n const basePadding = Math.max(\n 8,\n Math.min(25, 15 / Math.max(scale, 0.3)),\n )\n const hierarchyPadding = group.hasChildren ? basePadding * 0.6 : 0\n const totalPadding = basePadding + hierarchyPadding\n\n const baseStrokeWidth = Math.max(1, 2 / Math.max(scale, 0.5))\n const strokeWidth =\n group.depthLevel === 0 ? baseStrokeWidth : baseStrokeWidth * 0.7\n\n const baseDashSize = Math.max(4, 8 / Math.max(scale, 0.5))\n const dashMultiplier = group.hasChildren ? 1.3 : 1\n const dashSize = baseDashSize * dashMultiplier\n const gapSize = dashSize * 0.5\n\n const groupOverlay = document.createElementNS(\n \"http://www.w3.org/2000/svg\",\n \"rect\",\n )\n groupOverlay.setAttribute(\"class\", \"schematic-group-overlay\")\n groupOverlay.setAttribute(\n \"x\",\n (groupBounds.minX - totalPadding).toString(),\n )\n groupOverlay.setAttribute(\n \"y\",\n (groupBounds.minY - totalPadding).toString(),\n )\n groupOverlay.setAttribute(\n \"width\",\n (groupBounds.maxX - groupBounds.minX + totalPadding * 2).toString(),\n )\n groupOverlay.setAttribute(\n \"height\",\n (groupBounds.maxY - groupBounds.minY + totalPadding * 2).toString(),\n )\n groupOverlay.setAttribute(\"fill\", \"none\")\n groupOverlay.setAttribute(\"stroke\", group.color)\n groupOverlay.setAttribute(\"stroke-width\", strokeWidth.toString())\n groupOverlay.setAttribute(\n \"stroke-dasharray\",\n `${dashSize},${gapSize}`,\n )\n groupOverlay.setAttribute(\"opacity\", \"0.8\")\n groupOverlay.setAttribute(\"rx\", \"0\")\n groupOverlay.setAttribute(\"ry\", \"0\")\n\n const baseFontSize = Math.max(\n 6,\n Math.min(20, 14 / Math.max(scale, 0.2)),\n )\n const fontSizeReduction =\n group.depthLevel === 0 || group.depthLevel === 1\n ? 0\n : group.depthLevel * 0.2\n const fontSize = baseFontSize * (1 - fontSizeReduction)\n\n const labelPadding = Math.max(1, fontSize * 0.2)\n const labelText = group.name\n\n const tempText = document.createElementNS(\n \"http://www.w3.org/2000/svg\",\n \"text\",\n )\n tempText.setAttribute(\"font-size\", fontSize.toString())\n tempText.setAttribute(\"font-family\", \"Arial, sans-serif\")\n tempText.textContent = labelText\n svg.appendChild(tempText)\n const textBBox = tempText.getBBox()\n svg.removeChild(tempText)\n\n const labelWidth = textBBox.width + labelPadding * 2\n const labelHeight = fontSize + labelPadding * 2\n const labelX = groupBounds.minX - totalPadding\n const labelY = groupBounds.minY - totalPadding - labelHeight\n\n const labelBg = document.createElementNS(\n \"http://www.w3.org/2000/svg\",\n \"rect\",\n )\n labelBg.setAttribute(\"class\", \"schematic-group-overlay\")\n labelBg.setAttribute(\"x\", labelX.toString())\n labelBg.setAttribute(\"y\", (labelY - labelHeight).toString())\n labelBg.setAttribute(\"width\", labelWidth.toString())\n labelBg.setAttribute(\"height\", labelHeight.toString())\n labelBg.setAttribute(\"fill\", \"transparent\")\n labelBg.setAttribute(\"rx\", \"0\")\n labelBg.setAttribute(\"ry\", \"0\")\n\n const groupLabel = document.createElementNS(\n \"http://www.w3.org/2000/svg\",\n \"text\",\n )\n groupLabel.setAttribute(\"class\", \"schematic-group-overlay\")\n groupLabel.setAttribute(\"x\", (labelX + labelPadding).toString())\n groupLabel.setAttribute(\n \"y\",\n (labelY + labelHeight - labelPadding).toString(),\n )\n groupLabel.setAttribute(\"fill\", group.color)\n groupLabel.setAttribute(\"font-size\", fontSize.toString())\n groupLabel.setAttribute(\"font-family\", \"Arial, sans-serif\")\n groupLabel.setAttribute(\n \"font-weight\",\n group.depthLevel === 0 ? \"600\" : \"500\",\n )\n groupLabel.setAttribute(\"stroke\", group.color)\n groupLabel.setAttribute(\n \"stroke-width\",\n Math.max(0.2, fontSize * 0.02).toString(),\n )\n groupLabel.textContent = labelText\n\n svg.appendChild(groupOverlay)\n svg.appendChild(labelBg)\n svg.appendChild(groupLabel)\n })\n } catch (error) {\n console.error(\"Error creating group overlays:\", error)\n }\n }, 10) // Small delay to ensure SVG is ready\n\n return () => clearTimeout(timeoutId)\n }, [svgDivRef, circuitJsonKey, showGroups])\n}\n\nfunction calculateGroupBounds(components: any[], svg: SVGElement) {\n let minX = Infinity,\n minY = Infinity,\n maxX = -Infinity,\n maxY = -Infinity\n\n for (const component of components) {\n let componentElement = svg.querySelector(\n `g[data-schematic-component-id=\"${component.schematic_component_id}\"]`,\n )\n\n if (!componentElement) {\n componentElement = svg.querySelector(\n `[data-schematic-component-id=\"${component.schematic_component_id}\"]`,\n )\n }\n\n if (componentElement) {\n const bbox = (componentElement as SVGGraphicsElement).getBBox()\n minX = Math.min(minX, bbox.x)\n minY = Math.min(minY, bbox.y)\n maxX = Math.max(maxX, bbox.x + bbox.width)\n maxY = Math.max(maxY, bbox.y + bbox.height)\n }\n }\n\n if (minX === Infinity) {\n return null\n }\n\n const bounds = { minX, minY, maxX, maxY }\n return bounds\n}\n","import Debug from \"debug\"\n\nexport const debug = Debug(\"schematic-viewer\")\n\nexport const enableDebug = () => {\n Debug.enable(\"schematic-viewer*\")\n}\n\nexport default debug\n","import { useEffect, useState } from \"react\"\n\nexport const useResizeHandling = (\n containerRef: React.RefObject<HTMLElement>,\n) => {\n const [containerWidth, setContainerWidth] = useState(0)\n const [containerHeight, setContainerHeight] = useState(0)\n\n useEffect(() => {\n if (!containerRef.current) return\n\n const updateDimensions = () => {\n const rect = containerRef.current?.getBoundingClientRect()\n setContainerWidth(rect?.width || 0)\n setContainerHeight(rect?.height || 0)\n }\n\n // Set initial dimensions\n updateDimensions()\n\n // Add resize listener\n const resizeObserver = new ResizeObserver(updateDimensions)\n resizeObserver.observe(containerRef.current)\n\n // Fallback to window resize\n window.addEventListener(\"resize\", updateDimensions)\n\n return () => {\n resizeObserver.disconnect()\n window.removeEventListener(\"resize\", updateDimensions)\n }\n }, [])\n\n return { containerWidth, containerHeight }\n}\n","import { su } from \"@tscircuit/soup-util\"\nimport Debug from \"lib/utils/debug\"\nimport { getComponentOffsetDueToEvents } from \"lib/utils/get-component-offset-due-to-events\"\nimport { useCallback, useEffect, useRef, useState } from \"react\"\nimport { type Matrix, compose } from \"transformation-matrix\"\nimport type {\n EditSchematicComponentLocationEventWithElement,\n ManualEditEvent,\n} from \"../types/edit-events\"\n\nconst debug = Debug.extend(\"useComponentDragging\")\n\nexport const useComponentDragging = ({\n onEditEvent,\n editEvents = [],\n circuitJson,\n cancelDrag,\n svgToScreenProjection,\n realToSvgProjection,\n enabled = false,\n snapToGrid = false,\n}: {\n circuitJson: any[]\n editEvents: ManualEditEvent[]\n /** The projection returned from use-mouse-matrix-transform, indicating zoom on svg */\n svgToScreenProjection: Matrix\n /** The projection returned from circuit-to-svg, mm to svg */\n realToSvgProjection: Matrix\n onEditEvent?: (event: ManualEditEvent) => void\n cancelDrag?: () => void\n enabled?: boolean\n snapToGrid?: boolean\n}): {\n handleMouseDown: (e: React.MouseEvent) => void\n handleTouchStart: (e: React.TouchEvent) => void\n isDragging: boolean\n activeEditEvent: EditSchematicComponentLocationEventWithElement | null\n} => {\n const [activeEditEvent, setActiveEditEvent] =\n useState<EditSchematicComponentLocationEventWithElement | null>(null)\n const realToScreenProjection = compose(\n realToSvgProjection,\n svgToScreenProjection,\n )\n\n /**\n * Drag start position in screen space\n */\n const dragStartPosRef = useRef<{\n x: number\n y: number\n } | null>(null)\n\n const activeEditEventRef =\n useRef<EditSchematicComponentLocationEventWithElement | null>(null)\n\n // Store the latest positions of components being tracked\n const componentPositionsRef = useRef<Map<string, { x: number; y: number }>>(\n new Map(),\n )\n\n // Update position map with the latest positions from edit events\n useEffect(() => {\n // Process completed edit events to track latest positions\n editEvents.forEach((event) => {\n if (\n \"edit_event_type\" in event &&\n event.edit_event_type === \"edit_schematic_component_location\" &&\n !event.in_progress\n ) {\n componentPositionsRef.current.set(event.schematic_component_id, {\n ...event.new_center,\n })\n }\n })\n }, [editEvents])\n\n const startDrag = useCallback(\n (clientX: number, clientY: number, target: Element) => {\n if (!enabled) return false\n\n const componentGroup = target.closest(\n '[data-circuit-json-type=\"schematic_component\"]',\n )\n if (!componentGroup) return false\n\n const schematic_component_id = componentGroup.getAttribute(\n \"data-schematic-component-id\",\n )\n if (!schematic_component_id) return false\n\n if (cancelDrag) cancelDrag()\n\n const schematic_component = su(circuitJson).schematic_component.get(\n schematic_component_id,\n )\n if (!schematic_component) return false\n\n dragStartPosRef.current = { x: clientX, y: clientY }\n\n let current_position: { x: number; y: number }\n const trackedPosition = componentPositionsRef.current.get(\n schematic_component_id,\n )\n\n if (trackedPosition) {\n current_position = { ...trackedPosition }\n } else {\n const editEventOffset = getComponentOffsetDueToEvents({\n editEvents,\n schematic_component_id: schematic_component_id,\n })\n\n current_position = {\n x: schematic_component.center.x + editEventOffset.x,\n y: schematic_component.center.y + editEventOffset.y,\n }\n\n componentPositionsRef.current.set(schematic_component_id, {\n ...current_position,\n })\n }\n\n const newEditEvent: EditSchematicComponentLocationEventWithElement = {\n edit_event_id: Math.random().toString(36).substr(2, 9),\n edit_event_type: \"edit_schematic_component_location\",\n schematic_component_id: schematic_component_id,\n original_center: current_position,\n new_center: { ...current_position },\n in_progress: true,\n created_at: Date.now(),\n _element: componentGroup as any,\n }\n\n activeEditEventRef.current = newEditEvent\n setActiveEditEvent(newEditEvent)\n return true\n },\n [cancelDrag, enabled, circuitJson, editEvents],\n )\n\n const handleMouseDown = useCallback(\n (e: React.MouseEvent) => {\n startDrag(e.clientX, e.clientY, e.target as Element)\n },\n [startDrag],\n )\n\n const handleTouchStart = useCallback(\n (e: React.TouchEvent) => {\n if (e.touches.length !== 1) return\n const touch = e.touches[0]\n if (startDrag(touch.clientX, touch.clientY, e.target as Element)) {\n e.preventDefault()\n }\n },\n [startDrag],\n )\n\n const updateDragPosition = useCallback(\n (clientX: number, clientY: number) => {\n if (!activeEditEventRef.current || !dragStartPosRef.current) return\n\n const screenDelta = {\n x: clientX - dragStartPosRef.current.x,\n y: clientY - dragStartPosRef.current.y,\n }\n\n const mmDelta = {\n x: screenDelta.x / realToScreenProjection.a,\n y: screenDelta.y / realToScreenProjection.d,\n }\n\n let newCenter = {\n x: activeEditEventRef.current.original_center.x + mmDelta.x,\n y: activeEditEventRef.current.original_center.y + mmDelta.y,\n }\n if (snapToGrid) {\n const snap = (v: number) => Math.round(v * 10) / 10\n newCenter = { x: snap(newCenter.x), y: snap(newCenter.y) }\n }\n\n const newEditEvent = {\n ...activeEditEventRef.current,\n new_center: newCenter,\n }\n\n activeEditEventRef.current = newEditEvent\n setActiveEditEvent(newEditEvent)\n },\n [realToScreenProjection, snapToGrid],\n )\n\n const handleMouseMove = useCallback(\n (e: MouseEvent) => updateDragPosition(e.clientX, e.clientY),\n [updateDragPosition],\n )\n\n const handleTouchMove = useCallback(\n (e: TouchEvent) => {\n if (e.touches.length !== 1 || !activeEditEventRef.current) return\n e.preventDefault()\n const touch = e.touches[0]\n updateDragPosition(touch.clientX, touch.clientY)\n },\n [updateDragPosition],\n )\n\n const endDrag = useCallback(() => {\n if (!activeEditEventRef.current) return\n const finalEvent = {\n ...activeEditEventRef.current,\n in_progress: false,\n }\n\n componentPositionsRef.current.set(finalEvent.schematic_component_id, {\n ...finalEvent.new_center,\n })\n\n debug(\"endDrag calling onEditEvent with new edit event\", {\n newEditEvent: finalEvent,\n })\n if (onEditEvent) onEditEvent(finalEvent)\n activeEditEventRef.current = null\n dragStartPosRef.current = null\n setActiveEditEvent(null)\n }, [onEditEvent])\n\n const handleMouseUp = useCallback(() => endDrag(), [endDrag])\n const handleTouchEnd = useCallback(() => endDrag(), [endDrag])\n\n useEffect(() => {\n window.addEventListener(\"mousemove\", handleMouseMove)\n window.addEventListener(\"mouseup\", handleMouseUp)\n window.addEventListener(\"touchmove\", handleTouchMove, { passive: false })\n window.addEventListener(\"touchend\", handleTouchEnd)\n return () => {\n window.removeEventListener(\"mousemove\", handleMouseMove)\n window.removeEventListener(\"mouseup\", handleMouseUp)\n window.removeEventListener(\"touchmove\", handleTouchMove)\n window.removeEventListener(\"touchend\", handleTouchEnd)\n }\n }, [handleMouseMove, handleMouseUp, handleTouchMove, handleTouchEnd])\n\n return {\n handleMouseDown,\n handleTouchStart,\n isDragging: !!activeEditEventRef.current,\n activeEditEvent: activeEditEvent,\n }\n}\n","export const zIndexMap = {\n schematicEditIcon: 50,\n schematicGridIcon: 49,\n spiceSimulationIcon: 50,\n viewMenuIcon: 48,\n viewMenu: 55,\n viewMenuBackdrop: 54,\n clickToInteractOverlay: 100,\n}\n","import { zIndexMap } from \"../utils/z-index-map\"\n\nexport const EditIcon = ({\n onClick,\n active,\n}: { onClick: () => void; active: boolean }) => {\n const handleInteraction = (e: React.MouseEvent | React.TouchEvent) => {\n e.preventDefault()\n onClick()\n }\n\n return (\n <div\n onClick={handleInteraction}\n onTouchEnd={handleInteraction}\n style={{\n position: \"absolute\",\n top: \"16px\",\n right: \"64px\",\n backgroundColor: active ? \"#4CAF50\" : \"#fff\",\n color: active ? \"#fff\" : \"#000\",\n padding: \"8px\",\n borderRadius: \"4px\",\n cursor: \"pointer\",\n boxShadow: \"0 2px 4px rgba(0,0,0,0.1)\",\n display: \"flex\",\n alignItems: \"center\",\n gap: \"4px\",\n zIndex: zIndexMap.schematicEditIcon,\n }}\n >\n <svg\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n >\n <path d=\"M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7\" />\n <path d=\"M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z\" />\n </svg>\n </div>\n )\n}\n","import { zIndexMap } from \"../utils/z-index-map\"\n\nexport const GridIcon = ({\n onClick,\n active,\n}: { onClick: () => void; active: boolean }) => {\n const handleInteraction = (e: React.MouseEvent | React.TouchEvent) => {\n e.preventDefault()\n onClick()\n }\n\n return (\n <div\n onClick={handleInteraction}\n onTouchEnd={handleInteraction}\n style={{\n position: \"absolute\",\n top: \"56px\",\n right: \"64px\",\n backgroundColor: active ? \"#4CAF50\" : \"#fff\",\n color: active ? \"#fff\" : \"#000\",\n padding: \"8px\",\n borderRadius: \"4px\",\n cursor: \"pointer\",\n boxShadow: \"0 2px 4px rgba(0,0,0,0.1)\",\n display: \"flex\",\n alignItems: \"center\",\n gap: \"4px\",\n zIndex: zIndexMap.schematicGridIcon,\n }}\n >\n <svg\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n >\n <path d=\"M3 3h7v7H3zM14 3h7v7h-7zM3 14h7v7H3zM14 14h7v7h-7z\" />\n </svg>\n </div>\n )\n}\n","import { zIndexMap } from \"../utils/z-index-map\"\n\nexport const ViewMenuIcon = ({\n onClick,\n active,\n}: { onClick: () => void; active: boolean }) => {\n const handleInteraction = (e: React.MouseEvent | React.TouchEvent) => {\n e.preventDefault()\n onClick()\n }\n\n return (\n <div\n onClick={handleInteraction}\n onTouchEnd={handleInteraction}\n style={{\n position: \"absolute\",\n top: \"16px\",\n right: \"16px\",\n backgroundColor: active ? \"#4CAF50\" : \"#fff\",\n color: active ? \"#fff\" : \"#000\",\n padding: \"8px\",\n borderRadius: \"4px\",\n cursor: \"pointer\",\n boxShadow: \"0 2px 4px rgba(0,0,0,0.1)\",\n display: \"flex\",\n alignItems: \"center\",\n gap: \"4px\",\n zIndex: zIndexMap.viewMenuIcon,\n }}\n >\n <svg\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n >\n <circle cx=\"12\" cy=\"12\" r=\"1\" />\n <circle cx=\"12\" cy=\"5\" r=\"1\" />\n <circle cx=\"12\" cy=\"19\" r=\"1\" />\n </svg>\n </div>\n )\n}\n","import { useMemo } from \"react\"\nimport { su } from \"@tscircuit/soup-util\"\nimport type { CircuitJson } from \"circuit-json\"\nimport { zIndexMap } from \"../utils/z-index-map\"\nimport packageJson from \"../../package.json\"\n\ninterface ViewMenuProps {\n circuitJson: CircuitJson\n circuitJsonKey: string\n isVisible: boolean\n onClose: () => void\n showGroups: boolean\n onToggleGroups: (show: boolean) => void\n}\n\nexport const ViewMenu = ({\n circuitJson,\n circuitJsonKey,\n isVisible,\n onClose,\n showGroups,\n onToggleGroups,\n}: ViewMenuProps) => {\n const hasGroups = useMemo(() => {\n if (!circuitJson || circuitJson.length === 0) return false\n\n try {\n // Check if there are explicit groups\n const sourceGroups = su(circuitJson).source_group?.list() || []\n if (sourceGroups.length > 0) return true\n\n // Check if we can create virtual groups by component type\n const schematicComponents =\n su(circuitJson).schematic_component?.list() || []\n if (schematicComponents.length > 1) {\n const componentTypes = new Set()\n for (const comp of schematicComponents) {\n const sourceComp = su(circuitJson).source_component.get(\n comp.source_component_id,\n )\n if (sourceComp?.ftype) {\n componentTypes.add(sourceComp.ftype)\n }\n }\n return componentTypes.size > 1 // Only show if there are multiple types\n }\n\n return false\n } catch (error) {\n console.error(\"Error checking for groups:\", error)\n return false\n }\n }, [circuitJsonKey])\n\n if (!isVisible) return null\n\n return (\n <>\n {/* Backdrop */}\n <div\n onClick={onClose}\n onTouchEnd={(e) => {\n e.preventDefault()\n onClose()\n }}\n style={{\n position: \"absolute\",\n inset: 0,\n backgroundColor: \"transparent\",\n zIndex: zIndexMap.viewMenuBackdrop,\n }}\n />\n\n {/* Menu */}\n <div\n style={{\n position: \"absolute\",\n top: \"56px\",\n right: \"16px\",\n backgroundColor: \"#ffffff\",\n color: \"#000000\",\n border: \"1px solid #ccc\",\n borderRadius: \"4px\",\n boxShadow: \"0 4px 12px rgba(0,0,0,0.1)\",\n minWidth: \"200px\",\n zIndex: zIndexMap.viewMenu,\n }}\n >\n {/* Groups Toggle Option */}\n <div\n onClick={() => {\n if (hasGroups) {\n onToggleGroups(!showGroups)\n }\n }}\n onTouchEnd={(e) => {\n e.preventDefault()\n if (hasGroups) {\n onToggleGroups(!showGroups)\n }\n }}\n style={{\n padding: \"8px 12px\",\n cursor: hasGroups ? \"pointer\" : \"not-allowed\",\n opacity: hasGroups ? 1 : 0.5,\n fontSize: \"13px\",\n color: \"#000000\",\n fontFamily: \"sans-serif\",\n display: \"flex\",\n alignItems: \"center\",\n gap: \"8px\",\n }}\n onMouseEnter={(e) => {\n if (hasGroups) {\n e.currentTarget.style.backgroundColor = \"#f0f0f0\"\n }\n }}\n onMouseLeave={(e) => {\n if (hasGroups) {\n e.currentTarget.style.backgroundColor = \"transparent\"\n }\n }}\n >\n <div\n style={{\n width: \"16px\",\n height: \"16px\",\n border: \"2px solid #000\",\n borderRadius: \"2px\",\n backgroundColor: \"transparent\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n fontSize: \"10px\",\n fontWeight: \"bold\",\n }}\n >\n {showGroups && \"✓\"}\n </div>\n View Schematic Groups\n </div>\n\n {!hasGroups && (\n <div\n style={{\n padding: \"8px 12px\",\n fontSize: \"11px\",\n color: \"#666\",\n fontStyle: \"italic\",\n }}\n >\n No groups found in this schematic\n </div>\n )}\n\n {/* Version Info */}\n <div\n style={{\n padding: \"4px 8px\",\n fontSize: \"12px\",\n color: \"#999\",\n borderTop: \"1px solid #eee\",\n textAlign: \"center\",\n }}\n >\n v{String(packageJson?.version)}\n </div>\n </div>\n </>\n )\n}\n","{\n \"name\": \"@tscircuit/schematic-viewer\",\n \"version\": \"2.0.40\",\n \"main\": \"dist/index.js\",\n \"type\": \"module\",\n \"scripts\": {\n \"start\": \"cosmos\",\n \"build:webworker\": \"tsup --config tsup-webworker.config.ts\",\n \"build:blob-url\": \"bun scripts/build-worker-blob-url.ts\",\n \"build\": \"bun run build:webworker && bun run build:blob-url && tsup-node ./lib/index.ts --dts --format esm --sourcemap\",\n \"build:site\": \"cosmos-export\",\n \"vercel-build\": \"bun run build:webworker && bun run build:blob-url && bun run build:site\",\n \"format\": \"biome format --write .\",\n \"format:check\": \"biome format .\"\n },\n \"devDependencies\": {\n \"@biomejs/biome\": \"^1.9.4\",\n \"@types/bun\": \"latest\",\n \"@types/debug\": \"^4.1.12\",\n \"@types/react\": \"^19.0.1\",\n \"@types/react-dom\": \"^19.0.2\",\n \"@types/recharts\": \"^2.0.1\",\n \"@vitejs/plugin-react\": \"^4.3.4\",\n \"react\": \"^19.1.0\",\n \"react-cosmos\": \"^6.2.1\",\n \"react-cosmos-plugin-vite\": \"^6.2.0\",\n \"react-dom\": \"^19.1.0\",\n \"react-reconciler\": \"^0.31.0\",\n \"semver\": \"^7.7.2\",\n \"tscircuit\": \"^0.0.611\",\n \"tsup\": \"^8.3.5\",\n \"vite\": \"^6.0.3\"\n },\n \"peerDependencies\": {\n \"typescript\": \"^5.0.0\",\n \"tscircuit\": \"*\"\n },\n \"dependencies\": {\n \"chart.js\": \"^4.5.0\",\n \"circuit-json-to-spice\": \"^0.0.10\",\n \"debug\": \"^4.4.0\",\n \"performance-now\": \"^2.1.0\",\n \"react-chartjs-2\": \"^5.3.0\",\n \"use-mouse-matrix-transform\": \"^1.2.2\"\n }\n}\n","export const SpiceIcon = () => (\n <svg\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <path d=\"M3 12h2.5l2.5-9 4 18 4-9h5.5\" />\n </svg>\n)\n","import { SpiceIcon } from \"./SpiceIcon\"\nimport { zIndexMap } from \"../utils/z-index-map\"\n\nexport const SpiceSimulationIcon = ({\n onClick,\n}: {\n onClick: () => void\n}) => {\n return (\n <div\n onClick={onClick}\n style={{\n position: \"absolute\",\n top: \"16px\",\n right: \"112px\",\n backgroundColor: \"#fff\",\n color: \"#000\",\n padding: \"8px\",\n borderRadius: \"4px\",\n cursor: \"pointer\",\n boxShadow: \"0 2px 4px rgba(0,0,0,0.1)\",\n display: \"flex\",\n alignItems: \"center\",\n gap: \"4px\",\n zIndex: zIndexMap.spiceSimulationIcon,\n }}\n >\n <SpiceIcon />\n </div>\n )\n}\n","import { useMemo } from \"react\"\nimport {\n Chart as ChartJS,\n type ChartOptions,\n CategoryScale,\n LinearScale,\n PointElement,\n LineElement,\n Title,\n Tooltip,\n Legend,\n} from \"chart.js\"\nimport { Line } from \"react-chartjs-2\"\nimport type { PlotPoint } from \"../hooks/useSpiceSimulation\"\n\nChartJS.register(\n CategoryScale,\n LinearScale,\n PointElement,\n LineElement,\n Title,\n Tooltip,\n Legend,\n)\n\nconst colors = [\"#8884d8\", \"#82ca9d\", \"#ffc658\", \"#ff7300\", \"#387908\"]\n\nconst formatTimeWithUnits = (seconds: number) => {\n if (seconds === 0) return \"0s\"\n const absSeconds = Math.abs(seconds)\n\n let unit = \"s\"\n let scale = 1\n if (absSeconds < 1e-12) {\n unit = \"fs\"\n scale = 1e15\n } else if (absSeconds < 1e-9) {\n unit = \"ps\"\n scale = 1e12\n } else if (absSeconds < 1e-6) {\n unit = \"ns\"\n scale = 1e9\n } else if (absSeconds < 1e-3) {\n unit = \"us\"\n scale = 1e6\n } else if (absSeconds < 1) {\n unit = \"ms\"\n scale = 1e3\n }\n\n return `${parseFloat((seconds * scale).toPrecision(3))}${unit}`\n}\n\nexport const SpicePlot = ({\n plotData,\n nodes,\n isLoading,\n error,\n}: {\n plotData: PlotPoint[]\n nodes: string[]\n isLoading: boolean\n error: string | null\n}) => {\n const yAxisLabel = useMemo(() => {\n const hasVoltage = nodes.some((n) => n.toLowerCase().startsWith(\"v(\"))\n const hasCurrent = nodes.some((n) => n.toLowerCase().startsWith(\"i(\"))\n if (hasVoltage && hasCurrent) return \"Value\"\n if (hasVoltage) return \"Voltage (V)\"\n if (hasCurrent) return \"Current (A)\"\n return \"Value\"\n }, [nodes])\n\n if (isLoading) {\n return (\n <div\n style={{\n height: \"300px\",\n width: \"100%\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n }}\n >\n Running simulation...\n </div>\n )\n }\n\n if (error) {\n return (\n <div\n style={{\n height: \"300px\",\n width: \"100%\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n color: \"red\",\n }}\n >\n Error: {error}\n </div>\n )\n }\n\n if (plotData.length === 0) {\n return (\n <div\n style={{\n height: \"300px\",\n width: \"100%\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n }}\n >\n No data to plot. Check simulation output or SPICE netlist.\n </div>\n )\n }\n\n const chartData = {\n datasets: nodes.map((node, i) => ({\n label: node,\n data: plotData.map((p) => ({\n x: Number(p.name),\n y: p[node] as number,\n })),\n borderColor: colors[i % colors.length],\n backgroundColor: colors[i % colors.length],\n fill: false,\n tension: 0.1,\n })),\n }\n\n const options: ChartOptions<\"line\"> = {\n responsive: true,\n maintainAspectRatio: false,\n plugins: {\n legend: {\n position: \"top\" as const,\n labels: {\n font: {\n family: \"sans-serif\",\n },\n },\n },\n title: {\n display: false,\n },\n tooltip: {\n callbacks: {\n title: (tooltipItems) => {\n if (tooltipItems.length > 0) {\n const item = tooltipItems[0]\n return formatTimeWithUnits(item.parsed.x)\n }\n return \"\"\n },\n },\n },\n },\n scales: {\n x: {\n type: \"linear\",\n title: {\n display: true,\n text: \"Time\",\n font: {\n family: \"sans-serif\",\n },\n },\n ticks: {\n callback: (value) => formatTimeWithUnits(value as number),\n font: {\n family: \"sans-serif\",\n },\n },\n },\n y: {\n title: {\n display: true,\n text: yAxisLabel,\n font: {\n family: \"sans-serif\",\n },\n },\n ticks: {\n font: {\n family: \"sans-serif\",\n },\n },\n },\n },\n }\n\n return (\n <div style={{ position: \"relative\", height: \"300px\", width: \"100%\" }}>\n <Line options={options} data={chartData} />\n </div>\n )\n}\n","import { SpicePlot } from \"./SpicePlot\"\nimport type { PlotPoint } from \"../hooks/useSpiceSimulation\"\nimport { useEffect, useState } from \"react\"\n\ninterface SpiceSimulationOverlayProps {\n spiceString: string | null\n onClose: () => void\n plotData: PlotPoint[]\n nodes: string[]\n isLoading: boolean\n error: string | null\n simOptions: {\n showVoltage: boolean\n showCurrent: boolean\n startTime: number\n duration: number\n }\n onSimOptionsChange: (\n options: SpiceSimulationOverlayProps[\"simOptions\"],\n ) => void\n}\n\nexport const SpiceSimulationOverlay = ({\n spiceString,\n onClose,\n plotData,\n nodes,\n isLoading,\n error,\n simOptions,\n onSimOptionsChange,\n}: SpiceSimulationOverlayProps) => {\n const [startTimeDraft, setStartTimeDraft] = useState(\n String(simOptions.startTime),\n )\n const [durationDraft, setDurationDraft] = useState(\n String(simOptions.duration),\n )\n\n useEffect(() => {\n setStartTimeDraft(String(simOptions.startTime))\n setDurationDraft(String(simOptions.duration))\n }, [simOptions.startTime, simOptions.duration])\n\n const handleRerun = () => {\n onSimOptionsChange({\n ...simOptions,\n startTime: Number(startTimeDraft),\n duration: Number(durationDraft),\n })\n }\n\n const filteredNodes = nodes.filter((node) => {\n const isVoltage = node.toLowerCase().startsWith(\"v(\")\n const isCurrent = node.toLowerCase().startsWith(\"i(\")\n if (simOptions.showVoltage && isVoltage) return true\n if (simOptions.showCurrent && isCurrent) return true\n return false\n })\n\n return (\n <div\n style={{\n position: \"fixed\",\n top: 0,\n left: 0,\n right: 0,\n bottom: 0,\n backgroundColor: \"rgba(0, 0, 0, 0.5)\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n zIndex: 1002,\n fontFamily: \"sans-serif\",\n }}\n >\n <div\n style={{\n backgroundColor: \"white\",\n padding: \"24px\",\n borderRadius: \"12px\",\n width: \"90%\",\n maxWidth: \"900px\",\n boxShadow: \"0 4px 20px rgba(0, 0, 0, 0.15)\",\n }}\n >\n <div\n style={{\n display: \"flex\",\n justifyContent: \"space-between\",\n alignItems: \"center\",\n marginBottom: \"24px\",\n borderBottom: \"1px solid #eee\",\n paddingBottom: \"16px\",\n }}\n >\n <h2\n style={{\n margin: 0,\n fontSize: \"22px\",\n fontWeight: 600,\n color: \"#333\",\n }}\n >\n SPICE Simulation\n </h2>\n <button\n onClick={onClose}\n style={{\n background: \"none\",\n border: \"none\",\n fontSize: \"28px\",\n cursor: \"pointer\",\n color: \"#888\",\n padding: 0,\n lineHeight: 1,\n }}\n >\n ×\n </button>\n </div>\n <div>\n <SpicePlot\n plotData={plotData}\n nodes={filteredNodes}\n isLoading={isLoading}\n error={error}\n />\n </div>\n <div\n style={{\n marginTop: \"16px\",\n padding: \"12px\",\n backgroundColor: \"#f7f7f7\",\n borderRadius: \"6px\",\n display: \"flex\",\n flexWrap: \"wrap\",\n gap: \"24px\",\n alignItems: \"center\",\n fontSize: \"14px\",\n }}\n >\n <div style={{ display: \"flex\", gap: \"16px\" }}>\n <label\n style={{ display: \"flex\", alignItems: \"center\", gap: \"6px\" }}\n >\n <input\n type=\"checkbox\"\n checked={simOptions.showVoltage}\n onChange={(e) =>\n onSimOptionsChange({\n ...simOptions,\n showVoltage: e.target.checked,\n })\n }\n />\n Voltage\n </label>\n <label\n style={{ display: \"flex\", alignItems: \"center\", gap: \"6px\" }}\n >\n <input\n type=\"checkbox\"\n checked={simOptions.showCurrent}\n onChange={(e) =>\n onSimOptionsChange({\n ...simOptions,\n showCurrent: e.target.checked,\n })\n }\n />\n Current\n </label>\n </div>\n <div style={{ display: \"flex\", gap: \"16px\", alignItems: \"center\" }}>\n <label htmlFor=\"startTime\">Start Time (ms):</label>\n <input\n id=\"startTime\"\n type=\"number\"\n value={startTimeDraft}\n onChange={(e) => setStartTimeDraft(e.target.value)}\n style={{\n width: \"80px\",\n padding: \"4px 8px\",\n borderRadius: \"4px\",\n border: \"1px solid #ccc\",\n }}\n />\n <label htmlFor=\"duration\">Duration (ms):</label>\n <input\n id=\"duration\"\n type=\"number\"\n value={durationDraft}\n onChange={(e) => setDurationDraft(e.target.value)}\n style={{\n width: \"80px\",\n padding: \"4px 8px\",\n borderRadius: \"4px\",\n border: \"1px solid #ccc\",\n }}\n />\n <button\n onClick={handleRerun}\n style={{\n padding: \"4px 12px\",\n borderRadius: \"4px\",\n border: \"1px solid #ccc\",\n backgroundColor: \"#f0f0f0\",\n cursor: \"pointer\",\n }}\n >\n Rerun\n </button>\n </div>\n </div>\n <div style={{ marginTop: \"24px\" }}>\n <h3\n style={{\n marginTop: 0,\n marginBottom: \"12px\",\n fontSize: \"18px\",\n fontWeight: 600,\n color: \"#333\",\n }}\n >\n SPICE Netlist\n </h3>\n <pre\n style={{\n backgroundColor: \"#fafafa\",\n padding: \"16px\",\n borderRadius: \"6px\",\n maxHeight: \"150px\",\n overflowY: \"auto\",\n border: \"1px solid #eee\",\n color: \"#333\",\n fontSize: \"13px\",\n fontFamily: \"monospace\",\n }}\n >\n {spiceString}\n </pre>\n </div>\n </div>\n </div>\n )\n}\n","import { useState, useEffect } from \"react\"\nimport type * as EecircuitEngine from \"../types/eecircuit-engine\"\n// @ts-ignore\nimport { getSpiceSimulationWorkerBlobUrl } from \"../workers/spice-simulation.worker.blob.js\"\n\n// Types from eecircuit-engine interface\ntype RealDataType = {\n name: string\n type: string\n values: number[]\n}\ntype ComplexNumber = {\n real: number\n img: number\n}\ntype ComplexDataType = {\n name: string\n type: string\n values: ComplexNumber[]\n}\ntype EecEngineResult =\n | {\n header: string\n numVariables: number\n variableNames: string[]\n numPoints: number\n dataType: \"real\"\n data: RealDataType[]\n }\n | {\n header: string\n numVariables: number\n variableNames: string[]\n numPoints: number\n dataType: \"complex\"\n data: ComplexDataType[]\n }\n\nexport interface PlotPoint {\n name: string // time or sweep variable\n [key: string]: number | string\n}\n\nconst parseEecEngineOutput = (\n result: EecEngineResult,\n): { plotData: PlotPoint[]; nodes: string[] } => {\n const columnData: Record<string, number[]> = {}\n\n if (result.dataType === \"real\") {\n result.data.forEach((col) => {\n columnData[col.name] = col.values\n })\n } else if (result.dataType === \"complex\") {\n result.data.forEach((col) => {\n // For now, plot the real part of complex numbers\n columnData[col.name] = col.values.map((v) => v.real)\n })\n } else {\n throw new Error(\"Unsupported data type in simulation result\")\n }\n\n const timeKey = Object.keys(columnData).find(\n (k) => k.toLowerCase() === \"time\" || k.toLowerCase() === \"frequency\",\n )\n if (!timeKey) {\n throw new Error(\"No time or frequency data in simulation result\")\n }\n const timeValues = columnData[timeKey]\n const probedVariables = Object.keys(columnData).filter((k) => k !== timeKey)\n const plotableNodes = probedVariables\n\n const plotData: PlotPoint[] = timeValues.map((t: number, i: number) => {\n const point: PlotPoint = { name: t.toExponential(2) }\n probedVariables.forEach((variable) => {\n point[variable] = columnData[variable][i]\n })\n return point\n })\n\n return { plotData, nodes: plotableNodes }\n}\n\ntype WorkerMessage =\n | {\n type: \"result\"\n result: EecEngineResult\n }\n | { type: \"error\"; error: string }\n\nexport const useSpiceSimulation = (spiceString: string | null) => {\n const [plotData, setPlotData] = useState<PlotPoint[]>([])\n const [nodes, setNodes] = useState<string[]>([])\n const [isLoading, setIsLoading] = useState(true)\n const [error, setError] = useState<string | null>(null)\n\n useEffect(() => {\n if (!spiceString) {\n setIsLoading(false)\n setPlotData([])\n setNodes([])\n setError(null)\n return\n }\n setIsLoading(true)\n setError(null)\n setPlotData([])\n setNodes([])\n\n const workerUrl = getSpiceSimulationWorkerBlobUrl()\n\n if (!workerUrl) {\n setError(\"Could not create SPICE simulation worker.\")\n setIsLoading(false)\n return\n }\n\n const worker = new Worker(workerUrl, { type: \"module\" })\n\n worker.onmessage = (event: MessageEvent<WorkerMessage>) => {\n if (event.data.type === \"result\") {\n try {\n const { plotData: parsedData, nodes: parsedNodes } =\n parseEecEngineOutput(event.data.result)\n setPlotData(parsedData)\n setNodes(parsedNodes)\n } catch (e: any) {\n setError(e.message || \"Failed to parse simulation result\")\n console.error(e)\n }\n } else if (event.data.type === \"error\") {\n setError(event.data.error)\n }\n setIsLoading(false)\n }\n\n worker.onerror = (err) => {\n setError(err.message)\n setIsLoading(false)\n }\n\n worker.postMessage({ spiceString })\n\n return () => {\n worker.terminate()\n }\n }, [spiceString])\n\n return { plotData, nodes, isLoading, error }\n}\n","// This file is generated by scripts/build-worker-blob-url.ts\n// Do not edit this file directly.\n\nconst b64 = \"dmFyIGU9bnVsbCxzPWFzeW5jKCk9Pihhd2FpdCBpbXBvcnQoImh0dHBzOi8vY2RuLmpzZGVsaXZyLm5ldC9ucG0vZWVjaXJjdWl0LWVuZ2luZUAxLjUuMi8rZXNtIikpLlNpbXVsYXRpb24sYz1hc3luYygpPT57aWYoZSYmZS5pc0luaXRpYWxpemVkKCkpcmV0dXJuO2xldCBpPWF3YWl0IHMoKTtlPW5ldyBpLGF3YWl0IGUuc3RhcnQoKX07c2VsZi5vbm1lc3NhZ2U9YXN5bmMgaT0+e3RyeXtpZihhd2FpdCBjKCksIWUpdGhyb3cgbmV3IEVycm9yKCJTaW11bGF0aW9uIG5vdCBpbml0aWFsaXplZCIpO2xldCB0PWkuZGF0YS5zcGljZVN0cmluZyxhPXQubWF0Y2goL3dyZGF0YVxzKyhcUyspXHMrKC4qKS9pKTtpZihhKXtsZXQgbz1gLnByb2JlICR7YVsyXS50cmltKCkuc3BsaXQoL1xzKy8pLmpvaW4oIiAiKX1gO3Q9dC5yZXBsYWNlKC93cmRhdGEuKi9pLG8pfWVsc2UgaWYoIXQubWF0Y2goL1wucHJvYmUvaSkpdGhyb3cgdC5tYXRjaCgvcGxvdFxzKyguKikvaSk/bmV3IEVycm9yKCJUaGUgJ3Bsb3QnIGNvbW1hbmQgaXMgbm90IHN1cHBvcnRlZCBmb3IgZGF0YSBleHRyYWN0aW9uLiBQbGVhc2UgdXNlICd3cmRhdGEgPGZpbGVuYW1lPiA8dmFyMT4gLi4uJyBvciAnLnByb2JlIDx2YXIxPiAuLi4nIGluc3RlYWQuIik6bmV3IEVycm9yKCJObyAnLnByb2JlJyBvciAnd3JkYXRhJyBjb21tYW5kIGZvdW5kIGluIFNQSUNFIGZpbGUuIFVzZSAnd3JkYXRhIDxmaWxlbmFtZT4gPHZhcjE+IC4uLicgdG8gc3BlY2lmeSBvdXRwdXQuIik7ZS5zZXROZXRMaXN0KHQpO2xldCBuPWF3YWl0IGUucnVuU2ltKCk7c2VsZi5wb3N0TWVzc2FnZSh7dHlwZToicmVzdWx0IixyZXN1bHQ6bn0pfWNhdGNoKHQpe3NlbGYucG9zdE1lc3NhZ2Uoe3R5cGU6ImVycm9yIixlcnJvcjp0Lm1lc3NhZ2V9KX19Owo=\";\n\nlet blobUrl = null;\n\nexport const getSpiceSimulationWorkerBlobUrl = () => {\n if (typeof window === \"undefined\") return null;\n if (blobUrl) return blobUrl;\n\n try {\n const blob = new Blob([atob(b64)], { type: \"application/javascript\" });\n blobUrl = URL.createObjectURL(blob);\n return blobUrl;\n } catch (e) {\n console.error(\"Failed to create blob URL for worker\", e);\n return null;\n }\n};\n","import { circuitJsonToSpice } from \"circuit-json-to-spice\"\nimport type { CircuitJson } from \"circuit-json\"\n\nexport interface SpiceSimOptions {\n showVoltage: boolean\n showCurrent: boolean\n startTime: number // in ms\n duration: number // in ms\n}\n\nconst formatSimTime = (seconds: number): string => {\n if (seconds === 0) return \"0\"\n const absSeconds = Math.abs(seconds)\n\n const precision = (v: number) => v.toPrecision(4)\n\n if (absSeconds >= 1) return precision(seconds)\n if (absSeconds >= 1e-3) return `${precision(seconds * 1e3)}m`\n if (absSeconds >= 1e-6) return `${precision(seconds * 1e6)}u`\n if (absSeconds >= 1e-9) return `${precision(seconds * 1e9)}n`\n if (absSeconds >= 1e-12) return `${precision(seconds * 1e12)}p`\n if (absSeconds >= 1e-15) return `${precision(seconds * 1e15)}f`\n\n return seconds.toExponential(3)\n}\n\nexport const getSpiceFromCircuitJson = (\n circuitJson: CircuitJson,\n options?: Partial<SpiceSimOptions>,\n): string => {\n const spiceNetlist = circuitJsonToSpice(circuitJson as any)\n const baseSpiceString = spiceNetlist.toSpiceString()\n\n const lines = baseSpiceString.split(\"\\n\").filter((l) => l.trim() !== \"\")\n const componentLines = lines.filter(\n (l) => !l.startsWith(\"*\") && !l.startsWith(\".\") && l.trim() !== \"\",\n )\n\n const allNodes = new Set<string>()\n const capacitorNodes = new Set<string>()\n const componentNamesToProbeCurrent = new Set<string>()\n\n for (const line of componentLines) {\n const parts = line.trim().split(/\\s+/)\n if (parts.length < 3) continue\n\n const componentName = parts[0]\n const componentType = componentName[0].toUpperCase()\n let nodesOnLine: string[] = []\n\n if ([\"R\", \"C\", \"L\", \"V\", \"I\", \"D\"].includes(componentType)) {\n nodesOnLine = parts.slice(1, 3)\n // Only probe current on voltage sources\n if (componentType === \"V\") {\n componentNamesToProbeCurrent.add(componentName)\n }\n } else if (componentType === \"Q\" && parts.length >= 4) {\n // BJT\n nodesOnLine = parts.slice(1, 4)\n } else if (componentType === \"M\" && parts.length >= 5) {\n // MOSFET\n nodesOnLine = parts.slice(1, 5)\n } else if (componentType === \"X\") {\n // Subcircuit\n // Assume last part is model name, everything in between is a node\n nodesOnLine = parts.slice(1, -1)\n } else {\n continue\n }\n\n nodesOnLine.forEach((node) => allNodes.add(node))\n\n if (componentType === \"C\") {\n nodesOnLine.forEach((node) => capacitorNodes.add(node))\n }\n }\n\n // Do not probe/set IC for ground\n allNodes.delete(\"0\")\n capacitorNodes.delete(\"0\")\n\n const icLines = Array.from(capacitorNodes).map((node) => `.ic V(${node})=0`)\n\n const probes: string[] = []\n const probeVoltages = Array.from(allNodes).map((node) => `V(${node})`)\n probes.push(...probeVoltages)\n const probeCurrents = Array.from(componentNamesToProbeCurrent).map(\n (name) => `I(${name})`,\n )\n probes.push(...probeCurrents)\n\n const probeLine = probes.length > 0 ? `.probe ${probes.join(\" \")}` : \"\"\n\n const tstart_ms = options?.startTime ?? 0\n const duration_ms = options?.duration ?? 20\n const tstart = tstart_ms * 1e-3 // s\n const duration = duration_ms * 1e-3 // s\n\n const tstop = tstart + duration\n const tstep = duration / 50\n const tranLine = `.tran ${formatSimTime(tstep)} ${formatSimTime(\n tstop,\n )} ${formatSimTime(tstart)} UIC`\n\n const endStatement = \".end\"\n const originalLines = baseSpiceString.split(\"\\n\")\n let endIndex = -1\n for (let i = originalLines.length - 1; i >= 0; i--) {\n if (originalLines[i].trim().toLowerCase().startsWith(endStatement)) {\n endIndex = i\n break\n }\n }\n\n const injectionLines = [...icLines, probeLine, tranLine].filter(Boolean)\n\n let finalLines: string[]\n\n if (endIndex !== -1) {\n const beforeEnd = originalLines.slice(0, endIndex)\n const endLineAndAfter = originalLines.slice(endIndex)\n finalLines = [...beforeEnd, ...injectionLines, ...endLineAndAfter]\n } else {\n finalLines = [...originalLines, ...injectionLines, endStatement]\n }\n\n return finalLines.join(\"\\n\")\n}\n","import { useCallback } from \"react\"\n\nexport const STORAGE_KEYS = {\n IS_SHOWING_SCHEMATIC_GROUPS: \"schematic_viewer_show_groups\",\n} as const\n\nexport const getStoredBoolean = (\n key: string,\n defaultValue: boolean,\n): boolean => {\n if (typeof window === \"undefined\") return defaultValue\n try {\n const stored = localStorage.getItem(key)\n return stored !== null ? JSON.parse(stored) : defaultValue\n } catch {\n return defaultValue\n }\n}\n\nexport const setStoredBoolean = (key: string, value: boolean): void => {\n if (typeof window === \"undefined\") return\n try {\n localStorage.setItem(key, JSON.stringify(value))\n } catch {}\n}\n\nexport const useLocalStorage = () => {\n const getBoolean = useCallback(\n (key: string, defaultValue: boolean): boolean => {\n return getStoredBoolean(key, defaultValue)\n },\n [],\n )\n\n const setBoolean = useCallback((key: string, value: boolean): void => {\n setStoredBoolean(key, value)\n }, [])\n\n return {\n getBoolean,\n setBoolean,\n }\n}\n\nexport const useLocalStorageValue = (key: string, defaultValue: boolean) => {\n const { getBoolean, setBoolean } = useLocalStorage()\n\n const getValue = useCallback(() => {\n return getBoolean(key, defaultValue)\n }, [getBoolean, key, defaultValue])\n\n const setValue = useCallback(\n (value: boolean) => {\n setBoolean(key, value)\n },\n [setBoolean, key],\n )\n\n return {\n getValue,\n setValue,\n }\n}\n"],"mappings":"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","names":["useEffect","useRef","su","useEffect","su","useEffect","useMemo","useRef","useState","useEffect","su","useEffect","useRef","useState","compose","debug","su","jsx","jsx","jsxs","su","jsx","jsxs","su","jsx","jsx","useMemo","jsx","jsxs","useEffect","useState","jsx","jsxs","useState","useEffect","useState","useEffect","useCallback","jsx","jsxs","debug","useState","circuitJson","useMemo","useRef","useEffect"]}
|
|
1
|
+
{"version":3,"sources":["../lib/components/SchematicViewer.tsx","../lib/hooks/useChangeSchematicComponentLocationsInSvg.ts","../lib/utils/get-component-offset-due-to-events.ts","../lib/hooks/useChangeSchematicTracesForMovedComponents.ts","../lib/hooks/useSchematicGroupsOverlay.ts","../lib/utils/debug.ts","../lib/hooks/use-resize-handling.ts","../lib/hooks/useComponentDragging.ts","../lib/utils/z-index-map.ts","../lib/components/EditIcon.tsx","../lib/components/GridIcon.tsx","../lib/components/ViewMenuIcon.tsx","../lib/components/ViewMenu.tsx","../package.json","../lib/components/SpiceIcon.tsx","../lib/components/SpiceSimulationIcon.tsx","../lib/components/SpicePlot.tsx","../lib/components/SpiceSimulationOverlay.tsx","../lib/hooks/useSpiceSimulation.ts","../lib/workers/spice-simulation.worker.blob.js","../lib/utils/spice-utils.ts","../lib/hooks/useLocalStorage.ts"],"sourcesContent":["import {\n convertCircuitJsonToSchematicSvg,\n type ColorOverrides,\n} from \"circuit-to-svg\"\nimport { useChangeSchematicComponentLocationsInSvg } from \"lib/hooks/useChangeSchematicComponentLocationsInSvg\"\nimport { useChangeSchematicTracesForMovedComponents } from \"lib/hooks/useChangeSchematicTracesForMovedComponents\"\nimport { useSchematicGroupsOverlay } from \"lib/hooks/useSchematicGroupsOverlay\"\nimport { enableDebug } from \"lib/utils/debug\"\nimport { useEffect, useMemo, useRef, useState } from \"react\"\nimport {\n fromString,\n identity,\n toString as transformToString,\n} from \"transformation-matrix\"\nimport { useMouseMatrixTransform } from \"use-mouse-matrix-transform\"\nimport { useResizeHandling } from \"../hooks/use-resize-handling\"\nimport { useComponentDragging } from \"../hooks/useComponentDragging\"\nimport type { ManualEditEvent } from \"../types/edit-events\"\nimport { EditIcon } from \"./EditIcon\"\nimport { GridIcon } from \"./GridIcon\"\nimport { ViewMenuIcon } from \"./ViewMenuIcon\"\nimport { ViewMenu } from \"./ViewMenu\"\nimport type { CircuitJson } from \"circuit-json\"\nimport { SpiceSimulationIcon } from \"./SpiceSimulationIcon\"\nimport { SpiceSimulationOverlay } from \"./SpiceSimulationOverlay\"\nimport { zIndexMap } from \"../utils/z-index-map\"\nimport { useSpiceSimulation } from \"../hooks/useSpiceSimulation\"\nimport { getSpiceFromCircuitJson } from \"../utils/spice-utils\"\nimport { getStoredBoolean, setStoredBoolean } from \"lib/hooks/useLocalStorage\"\n\ninterface Props {\n circuitJson: CircuitJson\n containerStyle?: React.CSSProperties\n editEvents?: ManualEditEvent[]\n onEditEvent?: (event: ManualEditEvent) => void\n defaultEditMode?: boolean\n debugGrid?: boolean\n editingEnabled?: boolean\n debug?: boolean\n clickToInteractEnabled?: boolean\n colorOverrides?: ColorOverrides\n spiceSimulationEnabled?: boolean\n disableGroups?: boolean\n}\n\nexport const SchematicViewer = ({\n circuitJson,\n containerStyle,\n editEvents: unappliedEditEvents = [],\n onEditEvent,\n defaultEditMode = false,\n debugGrid = false,\n editingEnabled = false,\n debug = false,\n clickToInteractEnabled = false,\n colorOverrides,\n spiceSimulationEnabled = false,\n disableGroups = false,\n}: Props) => {\n if (debug) {\n enableDebug()\n }\n const [showSpiceOverlay, setShowSpiceOverlay] = useState(false)\n const [spiceSimOptions, setSpiceSimOptions] = useState({\n showVoltage: true,\n showCurrent: false,\n startTime: 0, // in ms\n duration: 20, // in ms\n })\n\n const getCircuitHash = (circuitJson: CircuitJson) => {\n return `${circuitJson?.length || 0}_${(circuitJson as any)?.editCount || 0}`\n }\n\n const circuitJsonKey = useMemo(\n () => getCircuitHash(circuitJson),\n [circuitJson],\n )\n\n const spiceString = useMemo(() => {\n if (!spiceSimulationEnabled) return null\n try {\n return getSpiceFromCircuitJson(circuitJson, spiceSimOptions)\n } catch (e) {\n console.error(\"Failed to generate SPICE string\", e)\n return null\n }\n }, [\n circuitJsonKey,\n spiceSimulationEnabled,\n spiceSimOptions.startTime,\n spiceSimOptions.duration,\n ])\n\n const [hasSpiceSimRun, setHasSpiceSimRun] = useState(false)\n\n useEffect(() => {\n setHasSpiceSimRun(false)\n }, [circuitJsonKey])\n\n const {\n plotData,\n nodes,\n isLoading: isSpiceSimLoading,\n error: spiceSimError,\n } = useSpiceSimulation(hasSpiceSimRun ? spiceString : null)\n\n const [editModeEnabled, setEditModeEnabled] = useState(defaultEditMode)\n const [snapToGrid, setSnapToGrid] = useState(true)\n const [isInteractionEnabled, setIsInteractionEnabled] = useState<boolean>(\n !clickToInteractEnabled,\n )\n const [showViewMenu, setShowViewMenu] = useState(false)\n const [showSchematicGroups, setShowSchematicGroups] = useState(() => {\n if (disableGroups) return false\n return getStoredBoolean(\"schematic_viewer_show_groups\", false)\n })\n const svgDivRef = useRef<HTMLDivElement>(null)\n const touchStartRef = useRef<{ x: number; y: number } | null>(null)\n\n const handleTouchStart = (e: React.TouchEvent) => {\n const touch = e.touches[0]\n touchStartRef.current = {\n x: touch.clientX,\n y: touch.clientY,\n }\n }\n\n const handleTouchEnd = (e: React.TouchEvent) => {\n const touch = e.changedTouches[0]\n const start = touchStartRef.current\n if (!start) return\n\n const deltaX = Math.abs(touch.clientX - start.x)\n const deltaY = Math.abs(touch.clientY - start.y)\n\n if (deltaX < 10 && deltaY < 10) {\n e.preventDefault()\n setIsInteractionEnabled(true)\n }\n\n touchStartRef.current = null\n }\n\n const [internalEditEvents, setInternalEditEvents] = useState<\n ManualEditEvent[]\n >([])\n const circuitJsonRef = useRef<CircuitJson>(circuitJson)\n\n useEffect(() => {\n const circuitHash = getCircuitHash(circuitJson)\n const circuitHashRef = getCircuitHash(circuitJsonRef.current)\n\n if (circuitHash !== circuitHashRef) {\n setInternalEditEvents([])\n circuitJsonRef.current = circuitJson\n }\n }, [circuitJson])\n\n const {\n ref: containerRef,\n cancelDrag,\n transform: svgToScreenProjection,\n } = useMouseMatrixTransform({\n onSetTransform(transform) {\n if (!svgDivRef.current) return\n svgDivRef.current.style.transform = transformToString(transform)\n },\n // @ts-ignore disabled is a valid prop but not typed\n enabled: isInteractionEnabled && !showSpiceOverlay,\n })\n\n const { containerWidth, containerHeight } = useResizeHandling(containerRef)\n const svgString = useMemo(() => {\n if (!containerWidth || !containerHeight) return \"\"\n\n return convertCircuitJsonToSchematicSvg(circuitJson as any, {\n width: containerWidth,\n height: containerHeight || 720,\n grid: !debugGrid\n ? undefined\n : {\n cellSize: 1,\n labelCells: true,\n },\n colorOverrides,\n })\n }, [circuitJsonKey, containerWidth, containerHeight])\n\n const containerBackgroundColor = useMemo(() => {\n const match = svgString.match(\n /<svg[^>]*style=\"[^\"]*background-color:\\s*([^;\\\"]+)/i,\n )\n return match?.[1] ?? \"transparent\"\n }, [svgString])\n\n const realToSvgProjection = useMemo(() => {\n if (!svgString) return identity()\n const transformString = svgString.match(\n /data-real-to-screen-transform=\"([^\"]+)\"/,\n )?.[1]!\n\n try {\n return fromString(transformString)\n } catch (e) {\n console.error(e)\n return identity()\n }\n }, [svgString])\n\n const handleEditEvent = (event: ManualEditEvent) => {\n setInternalEditEvents((prev) => [...prev, event])\n if (onEditEvent) {\n onEditEvent(event)\n }\n }\n\n const editEventsWithUnappliedEditEvents = useMemo(() => {\n return [...unappliedEditEvents, ...internalEditEvents]\n }, [unappliedEditEvents, internalEditEvents])\n\n const {\n handleMouseDown,\n handleTouchStart: handleComponentTouchStart,\n isDragging,\n activeEditEvent,\n } = useComponentDragging({\n onEditEvent: handleEditEvent,\n cancelDrag,\n realToSvgProjection,\n svgToScreenProjection,\n circuitJson,\n editEvents: editEventsWithUnappliedEditEvents,\n enabled: editModeEnabled && isInteractionEnabled && !showSpiceOverlay,\n snapToGrid,\n })\n\n useChangeSchematicComponentLocationsInSvg({\n svgDivRef,\n editEvents: editEventsWithUnappliedEditEvents,\n realToSvgProjection,\n svgToScreenProjection,\n activeEditEvent,\n })\n\n useChangeSchematicTracesForMovedComponents({\n svgDivRef,\n circuitJson,\n activeEditEvent,\n editEvents: editEventsWithUnappliedEditEvents,\n })\n\n // Add group overlays when enabled\n useSchematicGroupsOverlay({\n svgDivRef,\n circuitJson,\n circuitJsonKey,\n showGroups: showSchematicGroups && !disableGroups,\n })\n\n // keep the latest touch handler without re-rendering the svg div\n const handleComponentTouchStartRef = useRef(handleComponentTouchStart)\n useEffect(() => {\n handleComponentTouchStartRef.current = handleComponentTouchStart\n }, [handleComponentTouchStart])\n\n const svgDiv = useMemo(\n () => (\n <div\n ref={svgDivRef}\n style={{\n pointerEvents: clickToInteractEnabled\n ? isInteractionEnabled\n ? \"auto\"\n : \"none\"\n : \"auto\",\n transformOrigin: \"0 0\",\n }}\n onTouchStart={(e) => {\n if (editModeEnabled && isInteractionEnabled && !showSpiceOverlay) {\n handleComponentTouchStartRef.current(e)\n }\n }}\n // biome-ignore lint/security/noDangerouslySetInnerHtml: <explanation>\n dangerouslySetInnerHTML={{ __html: svgString }}\n />\n ),\n [\n svgString,\n isInteractionEnabled,\n clickToInteractEnabled,\n editModeEnabled,\n showSpiceOverlay,\n ],\n )\n\n return (\n <div\n ref={containerRef}\n style={{\n position: \"relative\",\n backgroundColor: containerBackgroundColor,\n overflow: \"hidden\",\n cursor: showSpiceOverlay\n ? \"auto\"\n : isDragging\n ? \"grabbing\"\n : clickToInteractEnabled && !isInteractionEnabled\n ? \"pointer\"\n : \"grab\",\n minHeight: \"300px\",\n ...containerStyle,\n }}\n onWheelCapture={(e) => {\n if (showSpiceOverlay) {\n e.stopPropagation()\n }\n }}\n onMouseDown={(e) => {\n if (clickToInteractEnabled && !isInteractionEnabled) {\n e.preventDefault()\n e.stopPropagation()\n return\n }\n handleMouseDown(e)\n }}\n onMouseDownCapture={(e) => {\n if (clickToInteractEnabled && !isInteractionEnabled) {\n e.preventDefault()\n e.stopPropagation()\n return\n }\n }}\n onTouchStart={(e) => {\n if (showSpiceOverlay) return\n handleTouchStart(e)\n }}\n onTouchEnd={(e) => {\n if (showSpiceOverlay) return\n handleTouchEnd(e)\n }}\n >\n {!isInteractionEnabled && clickToInteractEnabled && (\n <div\n onClick={(e) => {\n e.preventDefault()\n e.stopPropagation()\n setIsInteractionEnabled(true)\n }}\n style={{\n position: \"absolute\",\n inset: 0,\n cursor: \"pointer\",\n zIndex: zIndexMap.clickToInteractOverlay,\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n pointerEvents: \"all\",\n touchAction: \"pan-x pan-y pinch-zoom\",\n }}\n >\n <div\n style={{\n backgroundColor: \"rgba(0, 0, 0, 0.8)\",\n color: \"white\",\n padding: \"12px 24px\",\n borderRadius: \"8px\",\n fontSize: \"16px\",\n fontFamily: \"sans-serif\",\n pointerEvents: \"none\",\n }}\n >\n {typeof window !== \"undefined\" &&\n (\"ontouchstart\" in window || navigator.maxTouchPoints > 0)\n ? \"Touch to Interact\"\n : \"Click to Interact\"}\n </div>\n </div>\n )}\n <ViewMenuIcon\n active={showViewMenu}\n onClick={() => setShowViewMenu(!showViewMenu)}\n />\n {editingEnabled && (\n <EditIcon\n active={editModeEnabled}\n onClick={() => setEditModeEnabled(!editModeEnabled)}\n />\n )}\n {editingEnabled && editModeEnabled && (\n <GridIcon\n active={snapToGrid}\n onClick={() => setSnapToGrid(!snapToGrid)}\n />\n )}\n <ViewMenu\n circuitJson={circuitJson}\n circuitJsonKey={circuitJsonKey}\n isVisible={showViewMenu}\n onClose={() => setShowViewMenu(false)}\n showGroups={showSchematicGroups}\n onToggleGroups={(value) => {\n if (!disableGroups) {\n setShowSchematicGroups(value)\n setStoredBoolean(\"schematic_viewer_show_groups\", value)\n }\n }}\n />\n {spiceSimulationEnabled && (\n <SpiceSimulationIcon onClick={() => setShowSpiceOverlay(true)} />\n )}\n {showSpiceOverlay && (\n <SpiceSimulationOverlay\n spiceString={spiceString}\n onClose={() => setShowSpiceOverlay(false)}\n plotData={plotData}\n nodes={nodes}\n isLoading={isSpiceSimLoading}\n error={spiceSimError}\n simOptions={spiceSimOptions}\n onSimOptionsChange={(options) => {\n setHasSpiceSimRun(true)\n setSpiceSimOptions(options)\n }}\n hasRun={hasSpiceSimRun}\n />\n )}\n {svgDiv}\n </div>\n )\n}\n","import { su } from \"@tscircuit/soup-util\"\nimport type {\n ManualEditEvent,\n EditSchematicComponentLocationEventWithElement,\n} from \"lib/types/edit-events\"\nimport { type Matrix, compose, applyToPoint } from \"transformation-matrix\"\nimport { useEffect, useRef } from \"react\"\nimport { getComponentOffsetDueToEvents } from \"lib/utils/get-component-offset-due-to-events\"\nimport type { CircuitJson } from \"circuit-json\"\n\n/**\n * This hook automatically applies the edit events to the schematic components\n * inside the svg div.\n *\n * Schematic components are \"<g>\" elements with a \"data-circuit-json-type\"\n * attribute equal to \"schematic_component\", these elements also have a\n * data-schematic-component-id attribute equal to the schematic_component_id\n */\nexport const useChangeSchematicComponentLocationsInSvg = ({\n svgDivRef,\n realToSvgProjection,\n svgToScreenProjection,\n activeEditEvent,\n editEvents,\n}: {\n svgDivRef: React.RefObject<HTMLDivElement | null>\n realToSvgProjection: Matrix\n svgToScreenProjection: Matrix\n activeEditEvent: EditSchematicComponentLocationEventWithElement | null\n editEvents: ManualEditEvent[]\n}) => {\n // Keep track of the last known SVG content\n const lastSvgContentRef = useRef<string | null>(null)\n\n useEffect(() => {\n const svg = svgDivRef.current\n if (!svg) return\n\n // Create a MutationObserver to watch for changes in the div's content\n const observer = new MutationObserver((mutations) => {\n // Check if the SVG content has changed\n const currentSvgContent = svg.innerHTML\n if (currentSvgContent !== lastSvgContentRef.current) {\n lastSvgContentRef.current = currentSvgContent\n\n // Apply the transforms\n applyTransforms()\n }\n })\n\n // Function to apply transforms to components\n const applyTransforms = () => {\n const componentsThatHaveBeenMoved = new Set<string>()\n for (const event of editEvents) {\n if (\n \"edit_event_type\" in event &&\n event.edit_event_type === \"edit_schematic_component_location\"\n ) {\n componentsThatHaveBeenMoved.add(event.schematic_component_id)\n }\n }\n if (activeEditEvent) {\n componentsThatHaveBeenMoved.add(activeEditEvent.schematic_component_id)\n }\n\n // Reset all transforms\n const allComponents = svg.querySelectorAll(\n '[data-circuit-json-type=\"schematic_component\"]',\n )\n\n for (const component of Array.from(allComponents)) {\n const schematic_component_id = component.getAttribute(\n \"data-schematic-component-id\",\n )!\n\n const offsetMm = getComponentOffsetDueToEvents({\n editEvents: [\n ...editEvents,\n ...(activeEditEvent ? [activeEditEvent] : []),\n ],\n schematic_component_id,\n })\n\n const offsetPx = {\n x: offsetMm.x * realToSvgProjection.a,\n y: offsetMm.y * realToSvgProjection.d,\n }\n\n const style: any = (component as any).style\n style.transform = `translate(${offsetPx.x}px, ${offsetPx.y}px)`\n if (\n activeEditEvent?.schematic_component_id === schematic_component_id\n ) {\n style.outline = \"solid 2px rgba(255,0,0,0.5)\"\n style.outlineOffset = \"5px\"\n } else if (style.outline) {\n style.outline = \"\"\n }\n }\n }\n\n // Start observing the div for changes\n observer.observe(svg, {\n childList: true, // Watch for changes to the child elements\n subtree: false, // Watch for changes in the entire subtree\n characterData: false, // Watch for changes to text content\n })\n\n // Apply transforms immediately on mount or when editEvents change\n applyTransforms()\n\n // Cleanup function\n return () => {\n observer.disconnect()\n }\n }, [svgDivRef, editEvents, activeEditEvent]) // Dependencies remain the same\n}\n","import type {\n EditSchematicComponentLocationEvent,\n EditSchematicComponentLocationEventWithElement,\n ManualEditEvent,\n} from \"lib/types/edit-events\"\n\n/**\n * Returns the total offset of a component due to a set of edit events in\n * mm\n */\nexport const getComponentOffsetDueToEvents = ({\n editEvents,\n schematic_component_id,\n}: {\n editEvents: ManualEditEvent[]\n schematic_component_id: string\n}) => {\n const editEventsForComponent: EditSchematicComponentLocationEvent[] =\n editEvents\n .filter(\n (event) =>\n \"schematic_component_id\" in event &&\n event.schematic_component_id === schematic_component_id,\n )\n .filter(\n (event) =>\n \"edit_event_type\" in event &&\n event.edit_event_type === \"edit_schematic_component_location\",\n )\n\n const totalOffsetX = editEventsForComponent.reduce((acc, event) => {\n return acc + event.new_center.x - event.original_center.x\n }, 0)\n\n const totalOffsetY = editEventsForComponent.reduce((acc, event) => {\n return acc + event.new_center.y - event.original_center.y\n }, 0)\n\n return {\n x: totalOffsetX,\n y: totalOffsetY,\n }\n}\n","import { useEffect, useRef } from \"react\"\nimport { su } from \"@tscircuit/soup-util\"\nimport type { ManualEditEvent } from \"../types/edit-events\"\nimport type { CircuitJson } from \"circuit-json\"\n\n/**\n * This hook makes traces dashed when their connected components are being moved\n */\nexport const useChangeSchematicTracesForMovedComponents = ({\n svgDivRef,\n circuitJson,\n activeEditEvent,\n editEvents,\n}: {\n svgDivRef: React.RefObject<HTMLDivElement | null>\n circuitJson: CircuitJson\n activeEditEvent: ManualEditEvent | null\n editEvents: ManualEditEvent[]\n}) => {\n // Keep track of the last known SVG content\n const lastSvgContentRef = useRef<string | null>(null)\n\n useEffect(() => {\n const svg = svgDivRef.current\n if (!svg) return\n\n const updateTraceStyles = () => {\n // Reset all traces to solid\n const allTraces = svg.querySelectorAll(\n '[data-circuit-json-type=\"schematic_trace\"] path',\n )\n\n // Reset all traces to solid\n for (const trace of Array.from(allTraces)) {\n trace.setAttribute(\"stroke-dasharray\", \"0\")\n ;(trace as any).style.animation = \"\"\n }\n\n // If there's an active edit event, make connected traces dashed\n for (const editEvent of [\n ...editEvents,\n ...(activeEditEvent ? [activeEditEvent] : []),\n ]) {\n if (\n \"schematic_component_id\" in editEvent &&\n editEvent.edit_event_type === \"edit_schematic_component_location\"\n ) {\n const sch_component = su(circuitJson).schematic_component.get(\n editEvent.schematic_component_id,\n )\n if (!sch_component) return\n\n const src_ports = su(circuitJson).source_port.list({\n source_component_id: sch_component.source_component_id,\n })\n const src_port_ids = new Set(src_ports.map((sp) => sp.source_port_id))\n const src_traces = su(circuitJson)\n .source_trace.list()\n .filter((st) =>\n st.connected_source_port_ids?.some((spi) =>\n src_port_ids.has(spi),\n ),\n )\n const src_trace_ids = new Set(\n src_traces.map((st) => st.source_trace_id),\n )\n const schematic_traces = su(circuitJson)\n .schematic_trace.list()\n .filter((st) => src_trace_ids.has(st.source_trace_id))\n\n // Make the connected traces dashed\n schematic_traces.forEach((trace) => {\n const traceElements = svg.querySelectorAll(\n `[data-schematic-trace-id=\"${trace.schematic_trace_id}\"] path`,\n )\n for (const traceElement of Array.from(traceElements)) {\n if (traceElement.getAttribute(\"class\")?.includes(\"invisible\"))\n continue\n traceElement.setAttribute(\"stroke-dasharray\", \"20,20\")\n ;(traceElement as any).style.animation =\n \"dash-animation 350ms linear infinite, pulse-animation 900ms linear infinite\"\n\n if (!svg.querySelector(\"style#dash-animation\")) {\n const style = document.createElement(\"style\")\n style.id = \"dash-animation\"\n style.textContent = `\n @keyframes dash-animation {\n to {\n stroke-dashoffset: -40;\n }\n }\n @keyframes pulse-animation {\n 0% { opacity: 0.6; }\n 50% { opacity: 0.2; }\n 100% { opacity: 0.6; }\n }\n `\n svg.appendChild(style)\n }\n }\n })\n }\n }\n }\n\n // Apply styles immediately\n updateTraceStyles()\n\n // Cleanup function\n const observer = new MutationObserver(updateTraceStyles)\n observer.observe(svg, {\n childList: true, // Watch for changes to the child elements\n subtree: false, // Watch for changes in the entire subtree\n characterData: false, // Watch for changes to text content\n })\n\n return () => {\n observer.disconnect()\n }\n }, [svgDivRef, activeEditEvent, circuitJson, editEvents])\n}\n","import { useEffect } from \"react\"\nimport { su } from \"@tscircuit/soup-util\"\nimport type { CircuitJson } from \"circuit-json\"\n\ninterface UseSchematicGroupsOverlayOptions {\n svgDivRef: React.RefObject<HTMLDivElement | null>\n circuitJson: CircuitJson\n circuitJsonKey: string\n showGroups: boolean\n}\n\nconst GROUP_COLORS = [\n \"#8B0000\", // Dark Red\n \"#2F4F4F\", // Dark Slate Gray\n \"#191970\", // Midnight Blue\n \"#006400\", // Dark Green\n \"#FF4500\", // Dark Orange\n \"#800080\", // Purple\n \"#2E8B57\", // Sea Green\n \"#B8860B\", // Dark Goldenrod\n \"#C71585\", // Medium Violet Red\n \"#008B8B\", // Dark Cyan\n]\n\nexport const useSchematicGroupsOverlay = (\n options: UseSchematicGroupsOverlayOptions,\n) => {\n const { svgDivRef, circuitJson, circuitJsonKey, showGroups } = options\n\n useEffect(() => {\n // Always clean up existing overlays first\n if (svgDivRef.current) {\n const existingOverlays = svgDivRef.current.querySelectorAll(\n \".schematic-group-overlay\",\n )\n existingOverlays.forEach((overlay) => overlay.remove())\n }\n\n if (\n !svgDivRef.current ||\n !showGroups ||\n !circuitJson ||\n circuitJson.length === 0\n ) {\n return\n }\n\n // Small delay to ensure SVG is rendered when groups are enabled from localStorage\n const timeoutId = setTimeout(() => {\n if (!svgDivRef.current) return\n\n const svg = svgDivRef.current.querySelector(\"svg\")\n if (!svg) {\n return\n }\n\n const existingOverlays = svg.querySelectorAll(\".schematic-group-overlay\")\n existingOverlays.forEach((overlay) => overlay.remove())\n\n try {\n const sourceGroups =\n su(circuitJson)\n .source_group?.list()\n .filter((x) => !!!x.is_subcircuit) || []\n const schematicComponents =\n su(circuitJson).schematic_component?.list() || []\n\n const sourceGroupHierarchy = new Map<string, string[]>()\n sourceGroups.forEach((group) => {\n const groupWithParent = group as any\n if (groupWithParent.parent_source_group_id) {\n const children =\n sourceGroupHierarchy.get(\n groupWithParent.parent_source_group_id,\n ) || []\n children.push(group.source_group_id)\n sourceGroupHierarchy.set(\n groupWithParent.parent_source_group_id,\n children,\n )\n }\n })\n\n const getAllDescendantSourceGroups = (\n sourceGroupId: string,\n ): string[] => {\n const descendants: string[] = []\n const children = sourceGroupHierarchy.get(sourceGroupId) || []\n for (const child of children) {\n descendants.push(child)\n descendants.push(...getAllDescendantSourceGroups(child))\n }\n return descendants\n }\n\n const getGroupDepthLevel = (sourceGroupId: string): number => {\n const groupWithParent = sourceGroups.find(\n (g) => g.source_group_id === sourceGroupId,\n ) as any\n if (!groupWithParent?.parent_source_group_id) {\n return 0\n }\n return 1 + getGroupDepthLevel(groupWithParent.parent_source_group_id)\n }\n\n const hasMeaningfulGroups =\n sourceGroups.length > 0 &&\n sourceGroups.some((group) => group.name && group.name.trim() !== \"\")\n\n let groupsToRender: Array<{\n id: string\n name: string\n components: any[]\n color: string\n depthLevel: number\n hasChildren: boolean\n sourceGroupId?: string\n }> = []\n\n if (hasMeaningfulGroups) {\n const groupMap = new Map<string, any[]>()\n\n for (const comp of schematicComponents) {\n const sourceComp = su(circuitJson).source_component.get(\n comp.source_component_id,\n )\n if (sourceComp?.source_group_id) {\n if (!groupMap.has(sourceComp.source_group_id)) {\n groupMap.set(sourceComp.source_group_id, [])\n }\n groupMap.get(sourceComp.source_group_id)!.push(comp)\n }\n }\n\n sourceGroups.forEach((group, index) => {\n let groupComponents = groupMap.get(group.source_group_id) || []\n\n const descendantGroups = getAllDescendantSourceGroups(\n group.source_group_id,\n )\n for (const descendantGroupId of descendantGroups) {\n const descendantComponents = groupMap.get(descendantGroupId) || []\n groupComponents = [...groupComponents, ...descendantComponents]\n }\n\n if (groupComponents.length > 0) {\n const depthLevel = getGroupDepthLevel(group.source_group_id)\n const hasChildren =\n getAllDescendantSourceGroups(group.source_group_id).length > 0\n\n if (group.name?.startsWith(\"unnamed_board\")) return\n groupsToRender.push({\n id: group.source_group_id,\n name: group.name || `Group ${index + 1}`,\n components: groupComponents,\n color: GROUP_COLORS[index % GROUP_COLORS.length],\n depthLevel,\n hasChildren,\n sourceGroupId: group.source_group_id,\n })\n }\n })\n }\n // else {\n // const componentTypeGroups = new Map<string, any[]>()\n\n // for (const comp of schematicComponents) {\n // const sourceComp = su(circuitJson).source_component.get(comp.source_component_id)\n // if (sourceComp) {\n // const componentType = sourceComp.ftype || \"other\"\n // if (!componentTypeGroups.has(componentType)) {\n // componentTypeGroups.set(componentType, [])\n // }\n // componentTypeGroups.get(componentType)!.push(comp)\n // }\n // }\n // // groupsToRender = Array.from(componentTypeGroups.entries()).map(\n // // ([type, components], index) => ({\n // // id: `type_${type}`,\n // // name: `${type.charAt(0).toUpperCase() + type.slice(1)}s`,\n // // components,\n // // color: GROUP_COLORS[index % GROUP_COLORS.length],\n // // depthLevel: 0,\n // // hasChildren: false,\n // // }),\n // // )\n // }\n\n const viewBox = svg.viewBox.baseVal\n const svgRect = svg.getBoundingClientRect()\n const scale =\n Math.min(\n svgRect.width / viewBox.width,\n svgRect.height / viewBox.height,\n ) || 1\n\n groupsToRender.sort((a, b) => a.depthLevel - b.depthLevel)\n\n groupsToRender.forEach((group) => {\n if (group.components.length === 0) return\n\n const groupBounds = calculateGroupBounds(group.components, svg)\n if (!groupBounds) return\n\n const basePadding = Math.max(\n 8,\n Math.min(25, 15 / Math.max(scale, 0.3)),\n )\n const hierarchyPadding = group.hasChildren ? basePadding * 0.6 : 0\n const totalPadding = basePadding + hierarchyPadding\n\n const baseStrokeWidth = Math.max(1, 2 / Math.max(scale, 0.5))\n const strokeWidth =\n group.depthLevel === 0 ? baseStrokeWidth : baseStrokeWidth * 0.7\n\n const baseDashSize = Math.max(4, 8 / Math.max(scale, 0.5))\n const dashMultiplier = group.hasChildren ? 1.3 : 1\n const dashSize = baseDashSize * dashMultiplier\n const gapSize = dashSize * 0.5\n\n const groupOverlay = document.createElementNS(\n \"http://www.w3.org/2000/svg\",\n \"rect\",\n )\n groupOverlay.setAttribute(\"class\", \"schematic-group-overlay\")\n groupOverlay.setAttribute(\n \"x\",\n (groupBounds.minX - totalPadding).toString(),\n )\n groupOverlay.setAttribute(\n \"y\",\n (groupBounds.minY - totalPadding).toString(),\n )\n groupOverlay.setAttribute(\n \"width\",\n (groupBounds.maxX - groupBounds.minX + totalPadding * 2).toString(),\n )\n groupOverlay.setAttribute(\n \"height\",\n (groupBounds.maxY - groupBounds.minY + totalPadding * 2).toString(),\n )\n groupOverlay.setAttribute(\"fill\", \"none\")\n groupOverlay.setAttribute(\"stroke\", group.color)\n groupOverlay.setAttribute(\"stroke-width\", strokeWidth.toString())\n groupOverlay.setAttribute(\n \"stroke-dasharray\",\n `${dashSize},${gapSize}`,\n )\n groupOverlay.setAttribute(\"opacity\", \"0.8\")\n groupOverlay.setAttribute(\"rx\", \"0\")\n groupOverlay.setAttribute(\"ry\", \"0\")\n\n const baseFontSize = Math.max(\n 6,\n Math.min(20, 14 / Math.max(scale, 0.2)),\n )\n const fontSizeReduction =\n group.depthLevel === 0 || group.depthLevel === 1\n ? 0\n : group.depthLevel * 0.2\n const fontSize = baseFontSize * (1 - fontSizeReduction)\n\n const labelPadding = Math.max(1, fontSize * 0.2)\n const labelText = group.name\n\n const tempText = document.createElementNS(\n \"http://www.w3.org/2000/svg\",\n \"text\",\n )\n tempText.setAttribute(\"font-size\", fontSize.toString())\n tempText.setAttribute(\"font-family\", \"Arial, sans-serif\")\n tempText.textContent = labelText\n svg.appendChild(tempText)\n const textBBox = tempText.getBBox()\n svg.removeChild(tempText)\n\n const labelWidth = textBBox.width + labelPadding * 2\n const labelHeight = fontSize + labelPadding * 2\n const labelX = groupBounds.minX - totalPadding\n const labelY = groupBounds.minY - totalPadding - labelHeight\n\n const labelBg = document.createElementNS(\n \"http://www.w3.org/2000/svg\",\n \"rect\",\n )\n labelBg.setAttribute(\"class\", \"schematic-group-overlay\")\n labelBg.setAttribute(\"x\", labelX.toString())\n labelBg.setAttribute(\"y\", (labelY - labelHeight).toString())\n labelBg.setAttribute(\"width\", labelWidth.toString())\n labelBg.setAttribute(\"height\", labelHeight.toString())\n labelBg.setAttribute(\"fill\", \"transparent\")\n labelBg.setAttribute(\"rx\", \"0\")\n labelBg.setAttribute(\"ry\", \"0\")\n\n const groupLabel = document.createElementNS(\n \"http://www.w3.org/2000/svg\",\n \"text\",\n )\n groupLabel.setAttribute(\"class\", \"schematic-group-overlay\")\n groupLabel.setAttribute(\"x\", (labelX + labelPadding).toString())\n groupLabel.setAttribute(\n \"y\",\n (labelY + labelHeight - labelPadding).toString(),\n )\n groupLabel.setAttribute(\"fill\", group.color)\n groupLabel.setAttribute(\"font-size\", fontSize.toString())\n groupLabel.setAttribute(\"font-family\", \"Arial, sans-serif\")\n groupLabel.setAttribute(\n \"font-weight\",\n group.depthLevel === 0 ? \"600\" : \"500\",\n )\n groupLabel.setAttribute(\"stroke\", group.color)\n groupLabel.setAttribute(\n \"stroke-width\",\n Math.max(0.2, fontSize * 0.02).toString(),\n )\n groupLabel.textContent = labelText\n\n svg.appendChild(groupOverlay)\n svg.appendChild(labelBg)\n svg.appendChild(groupLabel)\n })\n } catch (error) {\n console.error(\"Error creating group overlays:\", error)\n }\n }, 10) // Small delay to ensure SVG is ready\n\n return () => clearTimeout(timeoutId)\n }, [svgDivRef, circuitJsonKey, showGroups])\n}\n\nfunction calculateGroupBounds(components: any[], svg: SVGElement) {\n let minX = Infinity,\n minY = Infinity,\n maxX = -Infinity,\n maxY = -Infinity\n\n for (const component of components) {\n let componentElement = svg.querySelector(\n `g[data-schematic-component-id=\"${component.schematic_component_id}\"]`,\n )\n\n if (!componentElement) {\n componentElement = svg.querySelector(\n `[data-schematic-component-id=\"${component.schematic_component_id}\"]`,\n )\n }\n\n if (componentElement) {\n const bbox = (componentElement as SVGGraphicsElement).getBBox()\n minX = Math.min(minX, bbox.x)\n minY = Math.min(minY, bbox.y)\n maxX = Math.max(maxX, bbox.x + bbox.width)\n maxY = Math.max(maxY, bbox.y + bbox.height)\n }\n }\n\n if (minX === Infinity) {\n return null\n }\n\n const bounds = { minX, minY, maxX, maxY }\n return bounds\n}\n","import Debug from \"debug\"\n\nexport const debug = Debug(\"schematic-viewer\")\n\nexport const enableDebug = () => {\n Debug.enable(\"schematic-viewer*\")\n}\n\nexport default debug\n","import { useEffect, useState } from \"react\"\n\nexport const useResizeHandling = (\n containerRef: React.RefObject<HTMLElement>,\n) => {\n const [containerWidth, setContainerWidth] = useState(0)\n const [containerHeight, setContainerHeight] = useState(0)\n\n useEffect(() => {\n if (!containerRef.current) return\n\n const updateDimensions = () => {\n const rect = containerRef.current?.getBoundingClientRect()\n setContainerWidth(rect?.width || 0)\n setContainerHeight(rect?.height || 0)\n }\n\n // Set initial dimensions\n updateDimensions()\n\n // Add resize listener\n const resizeObserver = new ResizeObserver(updateDimensions)\n resizeObserver.observe(containerRef.current)\n\n // Fallback to window resize\n window.addEventListener(\"resize\", updateDimensions)\n\n return () => {\n resizeObserver.disconnect()\n window.removeEventListener(\"resize\", updateDimensions)\n }\n }, [])\n\n return { containerWidth, containerHeight }\n}\n","import { su } from \"@tscircuit/soup-util\"\nimport Debug from \"lib/utils/debug\"\nimport { getComponentOffsetDueToEvents } from \"lib/utils/get-component-offset-due-to-events\"\nimport { useCallback, useEffect, useRef, useState } from \"react\"\nimport { type Matrix, compose } from \"transformation-matrix\"\nimport type {\n EditSchematicComponentLocationEventWithElement,\n ManualEditEvent,\n} from \"../types/edit-events\"\n\nconst debug = Debug.extend(\"useComponentDragging\")\n\nexport const useComponentDragging = ({\n onEditEvent,\n editEvents = [],\n circuitJson,\n cancelDrag,\n svgToScreenProjection,\n realToSvgProjection,\n enabled = false,\n snapToGrid = false,\n}: {\n circuitJson: any[]\n editEvents: ManualEditEvent[]\n /** The projection returned from use-mouse-matrix-transform, indicating zoom on svg */\n svgToScreenProjection: Matrix\n /** The projection returned from circuit-to-svg, mm to svg */\n realToSvgProjection: Matrix\n onEditEvent?: (event: ManualEditEvent) => void\n cancelDrag?: () => void\n enabled?: boolean\n snapToGrid?: boolean\n}): {\n handleMouseDown: (e: React.MouseEvent) => void\n handleTouchStart: (e: React.TouchEvent) => void\n isDragging: boolean\n activeEditEvent: EditSchematicComponentLocationEventWithElement | null\n} => {\n const [activeEditEvent, setActiveEditEvent] =\n useState<EditSchematicComponentLocationEventWithElement | null>(null)\n const realToScreenProjection = compose(\n realToSvgProjection,\n svgToScreenProjection,\n )\n\n /**\n * Drag start position in screen space\n */\n const dragStartPosRef = useRef<{\n x: number\n y: number\n } | null>(null)\n\n const activeEditEventRef =\n useRef<EditSchematicComponentLocationEventWithElement | null>(null)\n\n // Store the latest positions of components being tracked\n const componentPositionsRef = useRef<Map<string, { x: number; y: number }>>(\n new Map(),\n )\n\n // Update position map with the latest positions from edit events\n useEffect(() => {\n // Process completed edit events to track latest positions\n editEvents.forEach((event) => {\n if (\n \"edit_event_type\" in event &&\n event.edit_event_type === \"edit_schematic_component_location\" &&\n !event.in_progress\n ) {\n componentPositionsRef.current.set(event.schematic_component_id, {\n ...event.new_center,\n })\n }\n })\n }, [editEvents])\n\n const startDrag = useCallback(\n (clientX: number, clientY: number, target: Element) => {\n if (!enabled) return false\n\n const componentGroup = target.closest(\n '[data-circuit-json-type=\"schematic_component\"]',\n )\n if (!componentGroup) return false\n\n const schematic_component_id = componentGroup.getAttribute(\n \"data-schematic-component-id\",\n )\n if (!schematic_component_id) return false\n\n if (cancelDrag) cancelDrag()\n\n const schematic_component = su(circuitJson).schematic_component.get(\n schematic_component_id,\n )\n if (!schematic_component) return false\n\n dragStartPosRef.current = { x: clientX, y: clientY }\n\n let current_position: { x: number; y: number }\n const trackedPosition = componentPositionsRef.current.get(\n schematic_component_id,\n )\n\n if (trackedPosition) {\n current_position = { ...trackedPosition }\n } else {\n const editEventOffset = getComponentOffsetDueToEvents({\n editEvents,\n schematic_component_id: schematic_component_id,\n })\n\n current_position = {\n x: schematic_component.center.x + editEventOffset.x,\n y: schematic_component.center.y + editEventOffset.y,\n }\n\n componentPositionsRef.current.set(schematic_component_id, {\n ...current_position,\n })\n }\n\n const newEditEvent: EditSchematicComponentLocationEventWithElement = {\n edit_event_id: Math.random().toString(36).substr(2, 9),\n edit_event_type: \"edit_schematic_component_location\",\n schematic_component_id: schematic_component_id,\n original_center: current_position,\n new_center: { ...current_position },\n in_progress: true,\n created_at: Date.now(),\n _element: componentGroup as any,\n }\n\n activeEditEventRef.current = newEditEvent\n setActiveEditEvent(newEditEvent)\n return true\n },\n [cancelDrag, enabled, circuitJson, editEvents],\n )\n\n const handleMouseDown = useCallback(\n (e: React.MouseEvent) => {\n startDrag(e.clientX, e.clientY, e.target as Element)\n },\n [startDrag],\n )\n\n const handleTouchStart = useCallback(\n (e: React.TouchEvent) => {\n if (e.touches.length !== 1) return\n const touch = e.touches[0]\n if (startDrag(touch.clientX, touch.clientY, e.target as Element)) {\n e.preventDefault()\n }\n },\n [startDrag],\n )\n\n const updateDragPosition = useCallback(\n (clientX: number, clientY: number) => {\n if (!activeEditEventRef.current || !dragStartPosRef.current) return\n\n const screenDelta = {\n x: clientX - dragStartPosRef.current.x,\n y: clientY - dragStartPosRef.current.y,\n }\n\n const mmDelta = {\n x: screenDelta.x / realToScreenProjection.a,\n y: screenDelta.y / realToScreenProjection.d,\n }\n\n let newCenter = {\n x: activeEditEventRef.current.original_center.x + mmDelta.x,\n y: activeEditEventRef.current.original_center.y + mmDelta.y,\n }\n if (snapToGrid) {\n const snap = (v: number) => Math.round(v * 10) / 10\n newCenter = { x: snap(newCenter.x), y: snap(newCenter.y) }\n }\n\n const newEditEvent = {\n ...activeEditEventRef.current,\n new_center: newCenter,\n }\n\n activeEditEventRef.current = newEditEvent\n setActiveEditEvent(newEditEvent)\n },\n [realToScreenProjection, snapToGrid],\n )\n\n const handleMouseMove = useCallback(\n (e: MouseEvent) => updateDragPosition(e.clientX, e.clientY),\n [updateDragPosition],\n )\n\n const handleTouchMove = useCallback(\n (e: TouchEvent) => {\n if (e.touches.length !== 1 || !activeEditEventRef.current) return\n e.preventDefault()\n const touch = e.touches[0]\n updateDragPosition(touch.clientX, touch.clientY)\n },\n [updateDragPosition],\n )\n\n const endDrag = useCallback(() => {\n if (!activeEditEventRef.current) return\n const finalEvent = {\n ...activeEditEventRef.current,\n in_progress: false,\n }\n\n componentPositionsRef.current.set(finalEvent.schematic_component_id, {\n ...finalEvent.new_center,\n })\n\n debug(\"endDrag calling onEditEvent with new edit event\", {\n newEditEvent: finalEvent,\n })\n if (onEditEvent) onEditEvent(finalEvent)\n activeEditEventRef.current = null\n dragStartPosRef.current = null\n setActiveEditEvent(null)\n }, [onEditEvent])\n\n const handleMouseUp = useCallback(() => endDrag(), [endDrag])\n const handleTouchEnd = useCallback(() => endDrag(), [endDrag])\n\n useEffect(() => {\n window.addEventListener(\"mousemove\", handleMouseMove)\n window.addEventListener(\"mouseup\", handleMouseUp)\n window.addEventListener(\"touchmove\", handleTouchMove, { passive: false })\n window.addEventListener(\"touchend\", handleTouchEnd)\n return () => {\n window.removeEventListener(\"mousemove\", handleMouseMove)\n window.removeEventListener(\"mouseup\", handleMouseUp)\n window.removeEventListener(\"touchmove\", handleTouchMove)\n window.removeEventListener(\"touchend\", handleTouchEnd)\n }\n }, [handleMouseMove, handleMouseUp, handleTouchMove, handleTouchEnd])\n\n return {\n handleMouseDown,\n handleTouchStart,\n isDragging: !!activeEditEventRef.current,\n activeEditEvent: activeEditEvent,\n }\n}\n","export const zIndexMap = {\n schematicEditIcon: 50,\n schematicGridIcon: 49,\n spiceSimulationIcon: 50,\n viewMenuIcon: 48,\n viewMenu: 55,\n viewMenuBackdrop: 54,\n clickToInteractOverlay: 100,\n}\n","import { zIndexMap } from \"../utils/z-index-map\"\n\nexport const EditIcon = ({\n onClick,\n active,\n}: { onClick: () => void; active: boolean }) => {\n const handleInteraction = (e: React.MouseEvent | React.TouchEvent) => {\n e.preventDefault()\n onClick()\n }\n\n return (\n <div\n onClick={handleInteraction}\n onTouchEnd={handleInteraction}\n style={{\n position: \"absolute\",\n top: \"16px\",\n right: \"64px\",\n backgroundColor: active ? \"#4CAF50\" : \"#fff\",\n color: active ? \"#fff\" : \"#000\",\n padding: \"8px\",\n borderRadius: \"4px\",\n cursor: \"pointer\",\n boxShadow: \"0 2px 4px rgba(0,0,0,0.1)\",\n display: \"flex\",\n alignItems: \"center\",\n gap: \"4px\",\n zIndex: zIndexMap.schematicEditIcon,\n }}\n >\n <svg\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n >\n <path d=\"M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7\" />\n <path d=\"M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z\" />\n </svg>\n </div>\n )\n}\n","import { zIndexMap } from \"../utils/z-index-map\"\n\nexport const GridIcon = ({\n onClick,\n active,\n}: { onClick: () => void; active: boolean }) => {\n const handleInteraction = (e: React.MouseEvent | React.TouchEvent) => {\n e.preventDefault()\n onClick()\n }\n\n return (\n <div\n onClick={handleInteraction}\n onTouchEnd={handleInteraction}\n style={{\n position: \"absolute\",\n top: \"56px\",\n right: \"64px\",\n backgroundColor: active ? \"#4CAF50\" : \"#fff\",\n color: active ? \"#fff\" : \"#000\",\n padding: \"8px\",\n borderRadius: \"4px\",\n cursor: \"pointer\",\n boxShadow: \"0 2px 4px rgba(0,0,0,0.1)\",\n display: \"flex\",\n alignItems: \"center\",\n gap: \"4px\",\n zIndex: zIndexMap.schematicGridIcon,\n }}\n >\n <svg\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n >\n <path d=\"M3 3h7v7H3zM14 3h7v7h-7zM3 14h7v7H3zM14 14h7v7h-7z\" />\n </svg>\n </div>\n )\n}\n","import { zIndexMap } from \"../utils/z-index-map\"\n\nexport const ViewMenuIcon = ({\n onClick,\n active,\n}: { onClick: () => void; active: boolean }) => {\n const handleInteraction = (e: React.MouseEvent | React.TouchEvent) => {\n e.preventDefault()\n onClick()\n }\n\n return (\n <div\n onClick={handleInteraction}\n onTouchEnd={handleInteraction}\n style={{\n position: \"absolute\",\n top: \"16px\",\n right: \"16px\",\n backgroundColor: active ? \"#4CAF50\" : \"#fff\",\n color: active ? \"#fff\" : \"#000\",\n padding: \"8px\",\n borderRadius: \"4px\",\n cursor: \"pointer\",\n boxShadow: \"0 2px 4px rgba(0,0,0,0.1)\",\n display: \"flex\",\n alignItems: \"center\",\n gap: \"4px\",\n zIndex: zIndexMap.viewMenuIcon,\n }}\n >\n <svg\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n >\n <circle cx=\"12\" cy=\"12\" r=\"1\" />\n <circle cx=\"12\" cy=\"5\" r=\"1\" />\n <circle cx=\"12\" cy=\"19\" r=\"1\" />\n </svg>\n </div>\n )\n}\n","import { useMemo } from \"react\"\nimport { su } from \"@tscircuit/soup-util\"\nimport type { CircuitJson } from \"circuit-json\"\nimport { zIndexMap } from \"../utils/z-index-map\"\nimport packageJson from \"../../package.json\"\n\ninterface ViewMenuProps {\n circuitJson: CircuitJson\n circuitJsonKey: string\n isVisible: boolean\n onClose: () => void\n showGroups: boolean\n onToggleGroups: (show: boolean) => void\n}\n\nexport const ViewMenu = ({\n circuitJson,\n circuitJsonKey,\n isVisible,\n onClose,\n showGroups,\n onToggleGroups,\n}: ViewMenuProps) => {\n const hasGroups = useMemo(() => {\n if (!circuitJson || circuitJson.length === 0) return false\n\n try {\n // Check if there are explicit groups\n const sourceGroups = su(circuitJson).source_group?.list() || []\n if (sourceGroups.length > 0) return true\n\n // Check if we can create virtual groups by component type\n const schematicComponents =\n su(circuitJson).schematic_component?.list() || []\n if (schematicComponents.length > 1) {\n const componentTypes = new Set()\n for (const comp of schematicComponents) {\n const sourceComp = su(circuitJson).source_component.get(\n comp.source_component_id,\n )\n if (sourceComp?.ftype) {\n componentTypes.add(sourceComp.ftype)\n }\n }\n return componentTypes.size > 1 // Only show if there are multiple types\n }\n\n return false\n } catch (error) {\n console.error(\"Error checking for groups:\", error)\n return false\n }\n }, [circuitJsonKey])\n\n if (!isVisible) return null\n\n return (\n <>\n {/* Backdrop */}\n <div\n onClick={onClose}\n onTouchEnd={(e) => {\n e.preventDefault()\n onClose()\n }}\n style={{\n position: \"absolute\",\n inset: 0,\n backgroundColor: \"transparent\",\n zIndex: zIndexMap.viewMenuBackdrop,\n }}\n />\n\n {/* Menu */}\n <div\n style={{\n position: \"absolute\",\n top: \"56px\",\n right: \"16px\",\n backgroundColor: \"#ffffff\",\n color: \"#000000\",\n border: \"1px solid #ccc\",\n borderRadius: \"4px\",\n boxShadow: \"0 4px 12px rgba(0,0,0,0.1)\",\n minWidth: \"200px\",\n zIndex: zIndexMap.viewMenu,\n }}\n >\n {/* Groups Toggle Option */}\n <div\n onClick={() => {\n if (hasGroups) {\n onToggleGroups(!showGroups)\n }\n }}\n onTouchEnd={(e) => {\n e.preventDefault()\n if (hasGroups) {\n onToggleGroups(!showGroups)\n }\n }}\n style={{\n padding: \"8px 12px\",\n cursor: hasGroups ? \"pointer\" : \"not-allowed\",\n opacity: hasGroups ? 1 : 0.5,\n fontSize: \"13px\",\n color: \"#000000\",\n fontFamily: \"sans-serif\",\n display: \"flex\",\n alignItems: \"center\",\n gap: \"8px\",\n }}\n onMouseEnter={(e) => {\n if (hasGroups) {\n e.currentTarget.style.backgroundColor = \"#f0f0f0\"\n }\n }}\n onMouseLeave={(e) => {\n if (hasGroups) {\n e.currentTarget.style.backgroundColor = \"transparent\"\n }\n }}\n >\n <div\n style={{\n width: \"16px\",\n height: \"16px\",\n border: \"2px solid #000\",\n borderRadius: \"2px\",\n backgroundColor: \"transparent\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n fontSize: \"10px\",\n fontWeight: \"bold\",\n }}\n >\n {showGroups && \"✓\"}\n </div>\n View Schematic Groups\n </div>\n\n {!hasGroups && (\n <div\n style={{\n padding: \"8px 12px\",\n fontSize: \"11px\",\n color: \"#666\",\n fontStyle: \"italic\",\n }}\n >\n No groups found in this schematic\n </div>\n )}\n\n {/* Version Info */}\n <div\n style={{\n padding: \"4px 8px\",\n fontSize: \"12px\",\n color: \"#999\",\n borderTop: \"1px solid #eee\",\n textAlign: \"center\",\n }}\n >\n v{String(packageJson?.version)}\n </div>\n </div>\n </>\n )\n}\n","{\n \"name\": \"@tscircuit/schematic-viewer\",\n \"version\": \"2.0.41\",\n \"main\": \"dist/index.js\",\n \"type\": \"module\",\n \"scripts\": {\n \"start\": \"cosmos\",\n \"build:webworker\": \"tsup --config tsup-webworker.config.ts\",\n \"build:blob-url\": \"bun scripts/build-worker-blob-url.ts\",\n \"build\": \"bun run build:webworker && bun run build:blob-url && tsup-node ./lib/index.ts --dts --format esm --sourcemap\",\n \"build:site\": \"cosmos-export\",\n \"vercel-build\": \"bun run build:webworker && bun run build:blob-url && bun run build:site\",\n \"format\": \"biome format --write .\",\n \"format:check\": \"biome format .\"\n },\n \"devDependencies\": {\n \"@biomejs/biome\": \"^1.9.4\",\n \"@types/bun\": \"latest\",\n \"@types/debug\": \"^4.1.12\",\n \"@types/react\": \"^19.0.1\",\n \"@types/react-dom\": \"^19.0.2\",\n \"@types/recharts\": \"^2.0.1\",\n \"@vitejs/plugin-react\": \"^4.3.4\",\n \"react\": \"^19.1.0\",\n \"react-cosmos\": \"^6.2.1\",\n \"react-cosmos-plugin-vite\": \"^6.2.0\",\n \"react-dom\": \"^19.1.0\",\n \"react-reconciler\": \"^0.31.0\",\n \"semver\": \"^7.7.2\",\n \"tscircuit\": \"^0.0.611\",\n \"tsup\": \"^8.3.5\",\n \"vite\": \"^6.0.3\"\n },\n \"peerDependencies\": {\n \"typescript\": \"^5.0.0\",\n \"tscircuit\": \"*\"\n },\n \"dependencies\": {\n \"chart.js\": \"^4.5.0\",\n \"circuit-json-to-spice\": \"^0.0.10\",\n \"debug\": \"^4.4.0\",\n \"performance-now\": \"^2.1.0\",\n \"react-chartjs-2\": \"^5.3.0\",\n \"use-mouse-matrix-transform\": \"^1.2.2\"\n }\n}\n","export const SpiceIcon = () => (\n <svg\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <path d=\"M3 12h2.5l2.5-9 4 18 4-9h5.5\" />\n </svg>\n)\n","import { SpiceIcon } from \"./SpiceIcon\"\nimport { zIndexMap } from \"../utils/z-index-map\"\n\nexport const SpiceSimulationIcon = ({\n onClick,\n}: {\n onClick: () => void\n}) => {\n return (\n <div\n onClick={onClick}\n style={{\n position: \"absolute\",\n top: \"16px\",\n right: \"112px\",\n backgroundColor: \"#fff\",\n color: \"#000\",\n padding: \"8px\",\n borderRadius: \"4px\",\n cursor: \"pointer\",\n boxShadow: \"0 2px 4px rgba(0,0,0,0.1)\",\n display: \"flex\",\n alignItems: \"center\",\n gap: \"4px\",\n zIndex: zIndexMap.spiceSimulationIcon,\n }}\n >\n <SpiceIcon />\n </div>\n )\n}\n","import { useMemo } from \"react\"\nimport {\n Chart as ChartJS,\n type ChartOptions,\n CategoryScale,\n LinearScale,\n PointElement,\n LineElement,\n Title,\n Tooltip,\n Legend,\n} from \"chart.js\"\nimport { Line } from \"react-chartjs-2\"\nimport type { PlotPoint } from \"../hooks/useSpiceSimulation\"\n\nChartJS.register(\n CategoryScale,\n LinearScale,\n PointElement,\n LineElement,\n Title,\n Tooltip,\n Legend,\n)\n\nconst colors = [\"#8884d8\", \"#82ca9d\", \"#ffc658\", \"#ff7300\", \"#387908\"]\n\nconst formatTimeWithUnits = (seconds: number) => {\n if (seconds === 0) return \"0s\"\n const absSeconds = Math.abs(seconds)\n\n let unit = \"s\"\n let scale = 1\n if (absSeconds < 1e-12) {\n unit = \"fs\"\n scale = 1e15\n } else if (absSeconds < 1e-9) {\n unit = \"ps\"\n scale = 1e12\n } else if (absSeconds < 1e-6) {\n unit = \"ns\"\n scale = 1e9\n } else if (absSeconds < 1e-3) {\n unit = \"us\"\n scale = 1e6\n } else if (absSeconds < 1) {\n unit = \"ms\"\n scale = 1e3\n }\n\n return `${parseFloat((seconds * scale).toPrecision(3))}${unit}`\n}\n\nexport const SpicePlot = ({\n plotData,\n nodes,\n isLoading,\n error,\n hasRun,\n}: {\n plotData: PlotPoint[]\n nodes: string[]\n isLoading: boolean\n error: string | null\n hasRun: boolean\n}) => {\n const yAxisLabel = useMemo(() => {\n const hasVoltage = nodes.some((n) => n.toLowerCase().startsWith(\"v(\"))\n const hasCurrent = nodes.some((n) => n.toLowerCase().startsWith(\"i(\"))\n if (hasVoltage && hasCurrent) return \"Value\"\n if (hasVoltage) return \"Voltage (V)\"\n if (hasCurrent) return \"Current (A)\"\n return \"Value\"\n }, [nodes])\n\n if (isLoading) {\n return (\n <div\n style={{\n height: \"300px\",\n width: \"100%\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n }}\n >\n Running simulation...\n </div>\n )\n }\n\n if (!hasRun) {\n return (\n <div\n style={{\n height: \"300px\",\n width: \"100%\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n }}\n >\n Click \"Run\" to start the simulation.\n </div>\n )\n }\n\n if (error) {\n return (\n <div\n style={{\n height: \"300px\",\n width: \"100%\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n color: \"red\",\n }}\n >\n Error: {error}\n </div>\n )\n }\n\n if (plotData.length === 0) {\n return (\n <div\n style={{\n height: \"300px\",\n width: \"100%\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n }}\n >\n No data to plot. Check simulation output or SPICE netlist.\n </div>\n )\n }\n\n const chartData = {\n datasets: nodes.map((node, i) => ({\n label: node,\n data: plotData.map((p) => ({\n x: Number(p.name),\n y: p[node] as number,\n })),\n borderColor: colors[i % colors.length],\n backgroundColor: colors[i % colors.length],\n fill: false,\n tension: 0.1,\n })),\n }\n\n const options: ChartOptions<\"line\"> = {\n responsive: true,\n maintainAspectRatio: false,\n plugins: {\n legend: {\n position: \"top\" as const,\n labels: {\n font: {\n family: \"sans-serif\",\n },\n },\n },\n title: {\n display: false,\n },\n tooltip: {\n callbacks: {\n title: (tooltipItems) => {\n if (tooltipItems.length > 0) {\n const item = tooltipItems[0]\n return formatTimeWithUnits(item.parsed.x)\n }\n return \"\"\n },\n },\n },\n },\n scales: {\n x: {\n type: \"linear\",\n title: {\n display: true,\n text: \"Time\",\n font: {\n family: \"sans-serif\",\n },\n },\n ticks: {\n callback: (value) => formatTimeWithUnits(value as number),\n font: {\n family: \"sans-serif\",\n },\n },\n },\n y: {\n title: {\n display: true,\n text: yAxisLabel,\n font: {\n family: \"sans-serif\",\n },\n },\n ticks: {\n font: {\n family: \"sans-serif\",\n },\n },\n },\n },\n }\n\n return (\n <div style={{ position: \"relative\", height: \"300px\", width: \"100%\" }}>\n <Line options={options} data={chartData} />\n </div>\n )\n}\n","import { SpicePlot } from \"./SpicePlot\"\nimport type { PlotPoint } from \"../hooks/useSpiceSimulation\"\nimport { useEffect, useState } from \"react\"\n\ninterface SpiceSimulationOverlayProps {\n spiceString: string | null\n onClose: () => void\n plotData: PlotPoint[]\n nodes: string[]\n isLoading: boolean\n error: string | null\n simOptions: {\n showVoltage: boolean\n showCurrent: boolean\n startTime: number\n duration: number\n }\n onSimOptionsChange: (\n options: SpiceSimulationOverlayProps[\"simOptions\"],\n ) => void\n hasRun: boolean\n}\n\nexport const SpiceSimulationOverlay = ({\n spiceString,\n onClose,\n plotData,\n nodes,\n isLoading,\n error,\n simOptions,\n onSimOptionsChange,\n hasRun,\n}: SpiceSimulationOverlayProps) => {\n const [startTimeDraft, setStartTimeDraft] = useState(\n String(simOptions.startTime),\n )\n const [durationDraft, setDurationDraft] = useState(\n String(simOptions.duration),\n )\n\n useEffect(() => {\n setStartTimeDraft(String(simOptions.startTime))\n setDurationDraft(String(simOptions.duration))\n }, [simOptions.startTime, simOptions.duration])\n\n const handleRerun = () => {\n onSimOptionsChange({\n ...simOptions,\n startTime: Number(startTimeDraft),\n duration: Number(durationDraft),\n })\n }\n\n const filteredNodes = nodes.filter((node) => {\n const isVoltage = node.toLowerCase().startsWith(\"v(\")\n const isCurrent = node.toLowerCase().startsWith(\"i(\")\n if (simOptions.showVoltage && isVoltage) return true\n if (simOptions.showCurrent && isCurrent) return true\n return false\n })\n\n return (\n <div\n style={{\n position: \"fixed\",\n top: 0,\n left: 0,\n right: 0,\n bottom: 0,\n backgroundColor: \"rgba(0, 0, 0, 0.5)\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n zIndex: 1002,\n fontFamily: \"sans-serif\",\n }}\n >\n <div\n style={{\n backgroundColor: \"white\",\n padding: \"24px\",\n borderRadius: \"12px\",\n width: \"90%\",\n maxWidth: \"900px\",\n boxShadow: \"0 4px 20px rgba(0, 0, 0, 0.15)\",\n }}\n >\n <div\n style={{\n display: \"flex\",\n justifyContent: \"space-between\",\n alignItems: \"center\",\n marginBottom: \"24px\",\n borderBottom: \"1px solid #eee\",\n paddingBottom: \"16px\",\n }}\n >\n <h2\n style={{\n margin: 0,\n fontSize: \"22px\",\n fontWeight: 600,\n color: \"#333\",\n }}\n >\n SPICE Simulation\n </h2>\n <button\n onClick={onClose}\n style={{\n background: \"none\",\n border: \"none\",\n fontSize: \"28px\",\n cursor: \"pointer\",\n color: \"#888\",\n padding: 0,\n lineHeight: 1,\n }}\n >\n ×\n </button>\n </div>\n <div>\n <SpicePlot\n plotData={plotData}\n nodes={filteredNodes}\n isLoading={isLoading}\n error={error}\n hasRun={hasRun}\n />\n </div>\n <div\n style={{\n marginTop: \"16px\",\n padding: \"12px\",\n backgroundColor: \"#f7f7f7\",\n borderRadius: \"6px\",\n display: \"flex\",\n flexWrap: \"wrap\",\n gap: \"24px\",\n alignItems: \"center\",\n fontSize: \"14px\",\n }}\n >\n <div style={{ display: \"flex\", gap: \"16px\" }}>\n <label\n style={{ display: \"flex\", alignItems: \"center\", gap: \"6px\" }}\n >\n <input\n type=\"checkbox\"\n checked={simOptions.showVoltage}\n onChange={(e) =>\n onSimOptionsChange({\n ...simOptions,\n showVoltage: e.target.checked,\n })\n }\n />\n Voltage\n </label>\n <label\n style={{ display: \"flex\", alignItems: \"center\", gap: \"6px\" }}\n >\n <input\n type=\"checkbox\"\n checked={simOptions.showCurrent}\n onChange={(e) =>\n onSimOptionsChange({\n ...simOptions,\n showCurrent: e.target.checked,\n })\n }\n />\n Current\n </label>\n </div>\n <div style={{ display: \"flex\", gap: \"16px\", alignItems: \"center\" }}>\n <label htmlFor=\"startTime\">Start Time (ms):</label>\n <input\n id=\"startTime\"\n type=\"number\"\n value={startTimeDraft}\n onChange={(e) => setStartTimeDraft(e.target.value)}\n style={{\n width: \"80px\",\n padding: \"4px 8px\",\n borderRadius: \"4px\",\n border: \"1px solid #ccc\",\n }}\n />\n <label htmlFor=\"duration\">Duration (ms):</label>\n <input\n id=\"duration\"\n type=\"number\"\n value={durationDraft}\n onChange={(e) => setDurationDraft(e.target.value)}\n style={{\n width: \"80px\",\n padding: \"4px 8px\",\n borderRadius: \"4px\",\n border: \"1px solid #ccc\",\n }}\n />\n <button\n onClick={handleRerun}\n style={{\n padding: \"4px 12px\",\n borderRadius: \"4px\",\n border: \"1px solid #ccc\",\n backgroundColor: \"#f0f0f0\",\n cursor: \"pointer\",\n }}\n >\n {hasRun ? \"Rerun\" : \"Run\"}\n </button>\n </div>\n </div>\n <div style={{ marginTop: \"24px\" }}>\n <h3\n style={{\n marginTop: 0,\n marginBottom: \"12px\",\n fontSize: \"18px\",\n fontWeight: 600,\n color: \"#333\",\n }}\n >\n SPICE Netlist\n </h3>\n <pre\n style={{\n backgroundColor: \"#fafafa\",\n padding: \"16px\",\n borderRadius: \"6px\",\n maxHeight: \"150px\",\n overflowY: \"auto\",\n border: \"1px solid #eee\",\n color: \"#333\",\n fontSize: \"13px\",\n fontFamily: \"monospace\",\n }}\n >\n {spiceString}\n </pre>\n </div>\n </div>\n </div>\n )\n}\n","import { useState, useEffect } from \"react\"\nimport type * as EecircuitEngine from \"../types/eecircuit-engine\"\n// @ts-ignore\nimport { getSpiceSimulationWorkerBlobUrl } from \"../workers/spice-simulation.worker.blob.js\"\n\n// Types from eecircuit-engine interface\ntype RealDataType = {\n name: string\n type: string\n values: number[]\n}\ntype ComplexNumber = {\n real: number\n img: number\n}\ntype ComplexDataType = {\n name: string\n type: string\n values: ComplexNumber[]\n}\ntype EecEngineResult =\n | {\n header: string\n numVariables: number\n variableNames: string[]\n numPoints: number\n dataType: \"real\"\n data: RealDataType[]\n }\n | {\n header: string\n numVariables: number\n variableNames: string[]\n numPoints: number\n dataType: \"complex\"\n data: ComplexDataType[]\n }\n\nexport interface PlotPoint {\n name: string // time or sweep variable\n [key: string]: number | string\n}\n\nconst parseEecEngineOutput = (\n result: EecEngineResult,\n): { plotData: PlotPoint[]; nodes: string[] } => {\n const columnData: Record<string, number[]> = {}\n\n if (result.dataType === \"real\") {\n result.data.forEach((col) => {\n columnData[col.name] = col.values\n })\n } else if (result.dataType === \"complex\") {\n result.data.forEach((col) => {\n // For now, plot the real part of complex numbers\n columnData[col.name] = col.values.map((v) => v.real)\n })\n } else {\n throw new Error(\"Unsupported data type in simulation result\")\n }\n\n const timeKey = Object.keys(columnData).find(\n (k) => k.toLowerCase() === \"time\" || k.toLowerCase() === \"frequency\",\n )\n if (!timeKey) {\n throw new Error(\"No time or frequency data in simulation result\")\n }\n const timeValues = columnData[timeKey]\n const probedVariables = Object.keys(columnData).filter((k) => k !== timeKey)\n const plotableNodes = probedVariables\n\n const plotData: PlotPoint[] = timeValues.map((t: number, i: number) => {\n const point: PlotPoint = { name: t.toExponential(2) }\n probedVariables.forEach((variable) => {\n point[variable] = columnData[variable][i]\n })\n return point\n })\n\n return { plotData, nodes: plotableNodes }\n}\n\ntype WorkerMessage =\n | {\n type: \"result\"\n result: EecEngineResult\n }\n | { type: \"error\"; error: string }\n\nexport const useSpiceSimulation = (spiceString: string | null) => {\n const [plotData, setPlotData] = useState<PlotPoint[]>([])\n const [nodes, setNodes] = useState<string[]>([])\n const [isLoading, setIsLoading] = useState(true)\n const [error, setError] = useState<string | null>(null)\n\n useEffect(() => {\n if (!spiceString) {\n setIsLoading(false)\n setPlotData([])\n setNodes([])\n setError(null)\n return\n }\n setIsLoading(true)\n setError(null)\n setPlotData([])\n setNodes([])\n\n const workerUrl = getSpiceSimulationWorkerBlobUrl()\n\n if (!workerUrl) {\n setError(\"Could not create SPICE simulation worker.\")\n setIsLoading(false)\n return\n }\n\n const worker = new Worker(workerUrl, { type: \"module\" })\n\n worker.onmessage = (event: MessageEvent<WorkerMessage>) => {\n if (event.data.type === \"result\") {\n try {\n const { plotData: parsedData, nodes: parsedNodes } =\n parseEecEngineOutput(event.data.result)\n setPlotData(parsedData)\n setNodes(parsedNodes)\n } catch (e: any) {\n setError(e.message || \"Failed to parse simulation result\")\n console.error(e)\n }\n } else if (event.data.type === \"error\") {\n setError(event.data.error)\n }\n setIsLoading(false)\n }\n\n worker.onerror = (err) => {\n setError(err.message)\n setIsLoading(false)\n }\n\n worker.postMessage({ spiceString })\n\n return () => {\n worker.terminate()\n }\n }, [spiceString])\n\n return { plotData, nodes, isLoading, error }\n}\n","// This file is generated by scripts/build-worker-blob-url.ts\n// Do not edit this file directly.\n\nconst b64 = \"dmFyIGU9bnVsbCxzPWFzeW5jKCk9Pihhd2FpdCBpbXBvcnQoImh0dHBzOi8vY2RuLmpzZGVsaXZyLm5ldC9ucG0vZWVjaXJjdWl0LWVuZ2luZUAxLjUuMi8rZXNtIikpLlNpbXVsYXRpb24sYz1hc3luYygpPT57aWYoZSYmZS5pc0luaXRpYWxpemVkKCkpcmV0dXJuO2xldCBpPWF3YWl0IHMoKTtlPW5ldyBpLGF3YWl0IGUuc3RhcnQoKX07c2VsZi5vbm1lc3NhZ2U9YXN5bmMgaT0+e3RyeXtpZihhd2FpdCBjKCksIWUpdGhyb3cgbmV3IEVycm9yKCJTaW11bGF0aW9uIG5vdCBpbml0aWFsaXplZCIpO2xldCB0PWkuZGF0YS5zcGljZVN0cmluZyxhPXQubWF0Y2goL3dyZGF0YVxzKyhcUyspXHMrKC4qKS9pKTtpZihhKXtsZXQgbz1gLnByb2JlICR7YVsyXS50cmltKCkuc3BsaXQoL1xzKy8pLmpvaW4oIiAiKX1gO3Q9dC5yZXBsYWNlKC93cmRhdGEuKi9pLG8pfWVsc2UgaWYoIXQubWF0Y2goL1wucHJvYmUvaSkpdGhyb3cgdC5tYXRjaCgvcGxvdFxzKyguKikvaSk/bmV3IEVycm9yKCJUaGUgJ3Bsb3QnIGNvbW1hbmQgaXMgbm90IHN1cHBvcnRlZCBmb3IgZGF0YSBleHRyYWN0aW9uLiBQbGVhc2UgdXNlICd3cmRhdGEgPGZpbGVuYW1lPiA8dmFyMT4gLi4uJyBvciAnLnByb2JlIDx2YXIxPiAuLi4nIGluc3RlYWQuIik6bmV3IEVycm9yKCJObyAnLnByb2JlJyBvciAnd3JkYXRhJyBjb21tYW5kIGZvdW5kIGluIFNQSUNFIGZpbGUuIFVzZSAnd3JkYXRhIDxmaWxlbmFtZT4gPHZhcjE+IC4uLicgdG8gc3BlY2lmeSBvdXRwdXQuIik7ZS5zZXROZXRMaXN0KHQpO2xldCBuPWF3YWl0IGUucnVuU2ltKCk7c2VsZi5wb3N0TWVzc2FnZSh7dHlwZToicmVzdWx0IixyZXN1bHQ6bn0pfWNhdGNoKHQpe3NlbGYucG9zdE1lc3NhZ2Uoe3R5cGU6ImVycm9yIixlcnJvcjp0Lm1lc3NhZ2V9KX19Owo=\";\n\nlet blobUrl = null;\n\nexport const getSpiceSimulationWorkerBlobUrl = () => {\n if (typeof window === \"undefined\") return null;\n if (blobUrl) return blobUrl;\n\n try {\n const blob = new Blob([atob(b64)], { type: \"application/javascript\" });\n blobUrl = URL.createObjectURL(blob);\n return blobUrl;\n } catch (e) {\n console.error(\"Failed to create blob URL for worker\", e);\n return null;\n }\n};\n","import { circuitJsonToSpice } from \"circuit-json-to-spice\"\nimport type { CircuitJson } from \"circuit-json\"\n\nexport interface SpiceSimOptions {\n showVoltage: boolean\n showCurrent: boolean\n startTime: number // in ms\n duration: number // in ms\n}\n\nconst formatSimTime = (seconds: number): string => {\n if (seconds === 0) return \"0\"\n const absSeconds = Math.abs(seconds)\n\n const precision = (v: number) => v.toPrecision(4)\n\n if (absSeconds >= 1) return precision(seconds)\n if (absSeconds >= 1e-3) return `${precision(seconds * 1e3)}m`\n if (absSeconds >= 1e-6) return `${precision(seconds * 1e6)}u`\n if (absSeconds >= 1e-9) return `${precision(seconds * 1e9)}n`\n if (absSeconds >= 1e-12) return `${precision(seconds * 1e12)}p`\n if (absSeconds >= 1e-15) return `${precision(seconds * 1e15)}f`\n\n return seconds.toExponential(3)\n}\n\nexport const getSpiceFromCircuitJson = (\n circuitJson: CircuitJson,\n options?: Partial<SpiceSimOptions>,\n): string => {\n const spiceNetlist = circuitJsonToSpice(circuitJson as any)\n const baseSpiceString = spiceNetlist.toSpiceString()\n\n const lines = baseSpiceString.split(\"\\n\").filter((l) => l.trim() !== \"\")\n const componentLines = lines.filter(\n (l) => !l.startsWith(\"*\") && !l.startsWith(\".\") && l.trim() !== \"\",\n )\n\n const allNodes = new Set<string>()\n const capacitorNodes = new Set<string>()\n const componentNamesToProbeCurrent = new Set<string>()\n\n for (const line of componentLines) {\n const parts = line.trim().split(/\\s+/)\n if (parts.length < 3) continue\n\n const componentName = parts[0]\n const componentType = componentName[0].toUpperCase()\n let nodesOnLine: string[] = []\n\n if ([\"R\", \"C\", \"L\", \"V\", \"I\", \"D\"].includes(componentType)) {\n nodesOnLine = parts.slice(1, 3)\n // Only probe current on voltage sources\n if (componentType === \"V\") {\n componentNamesToProbeCurrent.add(componentName)\n }\n } else if (componentType === \"Q\" && parts.length >= 4) {\n // BJT\n nodesOnLine = parts.slice(1, 4)\n } else if (componentType === \"M\" && parts.length >= 5) {\n // MOSFET\n nodesOnLine = parts.slice(1, 5)\n } else if (componentType === \"X\") {\n // Subcircuit\n // Assume last part is model name, everything in between is a node\n nodesOnLine = parts.slice(1, -1)\n } else {\n continue\n }\n\n nodesOnLine.forEach((node) => allNodes.add(node))\n\n if (componentType === \"C\") {\n nodesOnLine.forEach((node) => capacitorNodes.add(node))\n }\n }\n\n // Do not probe/set IC for ground\n allNodes.delete(\"0\")\n capacitorNodes.delete(\"0\")\n\n const icLines = Array.from(capacitorNodes).map((node) => `.ic V(${node})=0`)\n\n const probes: string[] = []\n const probeVoltages = Array.from(allNodes).map((node) => `V(${node})`)\n probes.push(...probeVoltages)\n const probeCurrents = Array.from(componentNamesToProbeCurrent).map(\n (name) => `I(${name})`,\n )\n probes.push(...probeCurrents)\n\n const probeLine = probes.length > 0 ? `.probe ${probes.join(\" \")}` : \"\"\n\n const tstart_ms = options?.startTime ?? 0\n const duration_ms = options?.duration ?? 20\n const tstart = tstart_ms * 1e-3 // s\n const duration = duration_ms * 1e-3 // s\n\n const tstop = tstart + duration\n const tstep = duration / 50\n const tranLine = `.tran ${formatSimTime(tstep)} ${formatSimTime(\n tstop,\n )} ${formatSimTime(tstart)} UIC`\n\n const endStatement = \".end\"\n const originalLines = baseSpiceString.split(\"\\n\")\n let endIndex = -1\n for (let i = originalLines.length - 1; i >= 0; i--) {\n if (originalLines[i].trim().toLowerCase().startsWith(endStatement)) {\n endIndex = i\n break\n }\n }\n\n const injectionLines = [...icLines, probeLine, tranLine].filter(Boolean)\n\n let finalLines: string[]\n\n if (endIndex !== -1) {\n const beforeEnd = originalLines.slice(0, endIndex)\n const endLineAndAfter = originalLines.slice(endIndex)\n finalLines = [...beforeEnd, ...injectionLines, ...endLineAndAfter]\n } else {\n finalLines = [...originalLines, ...injectionLines, endStatement]\n }\n\n return finalLines.join(\"\\n\")\n}\n","import { useCallback } from \"react\"\n\nexport const STORAGE_KEYS = {\n IS_SHOWING_SCHEMATIC_GROUPS: \"schematic_viewer_show_groups\",\n} as const\n\nexport const getStoredBoolean = (\n key: string,\n defaultValue: boolean,\n): boolean => {\n if (typeof window === \"undefined\") return defaultValue\n try {\n const stored = localStorage.getItem(key)\n return stored !== null ? JSON.parse(stored) : defaultValue\n } catch {\n return defaultValue\n }\n}\n\nexport const setStoredBoolean = (key: string, value: boolean): void => {\n if (typeof window === \"undefined\") return\n try {\n localStorage.setItem(key, JSON.stringify(value))\n } catch {}\n}\n\nexport const useLocalStorage = () => {\n const getBoolean = useCallback(\n (key: string, defaultValue: boolean): boolean => {\n return getStoredBoolean(key, defaultValue)\n },\n [],\n )\n\n const setBoolean = useCallback((key: string, value: boolean): void => {\n setStoredBoolean(key, value)\n }, [])\n\n return {\n getBoolean,\n setBoolean,\n }\n}\n\nexport const useLocalStorageValue = (key: string, defaultValue: boolean) => {\n const { getBoolean, setBoolean } = useLocalStorage()\n\n const getValue = useCallback(() => {\n return getBoolean(key, defaultValue)\n }, [getBoolean, key, defaultValue])\n\n const setValue = useCallback(\n (value: boolean) => {\n setBoolean(key, value)\n },\n [setBoolean, key],\n )\n\n return {\n getValue,\n setValue,\n }\n}\n"],"mappings":"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","names":["useEffect","useRef","su","useEffect","su","useEffect","useMemo","useRef","useState","useEffect","su","useEffect","useRef","useState","compose","debug","su","jsx","jsx","jsxs","su","jsx","jsxs","su","jsx","jsx","useMemo","jsx","jsxs","useEffect","useState","jsx","jsxs","useState","useEffect","useState","useEffect","useCallback","jsx","jsxs","debug","useState","circuitJson","useMemo","useEffect","useRef"]}
|
|
@@ -92,12 +92,18 @@ export const SchematicViewer = ({
|
|
|
92
92
|
spiceSimOptions.duration,
|
|
93
93
|
])
|
|
94
94
|
|
|
95
|
+
const [hasSpiceSimRun, setHasSpiceSimRun] = useState(false)
|
|
96
|
+
|
|
97
|
+
useEffect(() => {
|
|
98
|
+
setHasSpiceSimRun(false)
|
|
99
|
+
}, [circuitJsonKey])
|
|
100
|
+
|
|
95
101
|
const {
|
|
96
102
|
plotData,
|
|
97
103
|
nodes,
|
|
98
104
|
isLoading: isSpiceSimLoading,
|
|
99
105
|
error: spiceSimError,
|
|
100
|
-
} = useSpiceSimulation(spiceString)
|
|
106
|
+
} = useSpiceSimulation(hasSpiceSimRun ? spiceString : null)
|
|
101
107
|
|
|
102
108
|
const [editModeEnabled, setEditModeEnabled] = useState(defaultEditMode)
|
|
103
109
|
const [snapToGrid, setSnapToGrid] = useState(true)
|
|
@@ -412,7 +418,11 @@ export const SchematicViewer = ({
|
|
|
412
418
|
isLoading={isSpiceSimLoading}
|
|
413
419
|
error={spiceSimError}
|
|
414
420
|
simOptions={spiceSimOptions}
|
|
415
|
-
onSimOptionsChange={
|
|
421
|
+
onSimOptionsChange={(options) => {
|
|
422
|
+
setHasSpiceSimRun(true)
|
|
423
|
+
setSpiceSimOptions(options)
|
|
424
|
+
}}
|
|
425
|
+
hasRun={hasSpiceSimRun}
|
|
416
426
|
/>
|
|
417
427
|
)}
|
|
418
428
|
{svgDiv}
|
|
@@ -56,11 +56,13 @@ export const SpicePlot = ({
|
|
|
56
56
|
nodes,
|
|
57
57
|
isLoading,
|
|
58
58
|
error,
|
|
59
|
+
hasRun,
|
|
59
60
|
}: {
|
|
60
61
|
plotData: PlotPoint[]
|
|
61
62
|
nodes: string[]
|
|
62
63
|
isLoading: boolean
|
|
63
64
|
error: string | null
|
|
65
|
+
hasRun: boolean
|
|
64
66
|
}) => {
|
|
65
67
|
const yAxisLabel = useMemo(() => {
|
|
66
68
|
const hasVoltage = nodes.some((n) => n.toLowerCase().startsWith("v("))
|
|
@@ -87,6 +89,22 @@ export const SpicePlot = ({
|
|
|
87
89
|
)
|
|
88
90
|
}
|
|
89
91
|
|
|
92
|
+
if (!hasRun) {
|
|
93
|
+
return (
|
|
94
|
+
<div
|
|
95
|
+
style={{
|
|
96
|
+
height: "300px",
|
|
97
|
+
width: "100%",
|
|
98
|
+
display: "flex",
|
|
99
|
+
alignItems: "center",
|
|
100
|
+
justifyContent: "center",
|
|
101
|
+
}}
|
|
102
|
+
>
|
|
103
|
+
Click "Run" to start the simulation.
|
|
104
|
+
</div>
|
|
105
|
+
)
|
|
106
|
+
}
|
|
107
|
+
|
|
90
108
|
if (error) {
|
|
91
109
|
return (
|
|
92
110
|
<div
|
|
@@ -18,6 +18,7 @@ interface SpiceSimulationOverlayProps {
|
|
|
18
18
|
onSimOptionsChange: (
|
|
19
19
|
options: SpiceSimulationOverlayProps["simOptions"],
|
|
20
20
|
) => void
|
|
21
|
+
hasRun: boolean
|
|
21
22
|
}
|
|
22
23
|
|
|
23
24
|
export const SpiceSimulationOverlay = ({
|
|
@@ -29,6 +30,7 @@ export const SpiceSimulationOverlay = ({
|
|
|
29
30
|
error,
|
|
30
31
|
simOptions,
|
|
31
32
|
onSimOptionsChange,
|
|
33
|
+
hasRun,
|
|
32
34
|
}: SpiceSimulationOverlayProps) => {
|
|
33
35
|
const [startTimeDraft, setStartTimeDraft] = useState(
|
|
34
36
|
String(simOptions.startTime),
|
|
@@ -125,6 +127,7 @@ export const SpiceSimulationOverlay = ({
|
|
|
125
127
|
nodes={filteredNodes}
|
|
126
128
|
isLoading={isLoading}
|
|
127
129
|
error={error}
|
|
130
|
+
hasRun={hasRun}
|
|
128
131
|
/>
|
|
129
132
|
</div>
|
|
130
133
|
<div
|
|
@@ -209,7 +212,7 @@ export const SpiceSimulationOverlay = ({
|
|
|
209
212
|
cursor: "pointer",
|
|
210
213
|
}}
|
|
211
214
|
>
|
|
212
|
-
Rerun
|
|
215
|
+
{hasRun ? "Rerun" : "Run"}
|
|
213
216
|
</button>
|
|
214
217
|
</div>
|
|
215
218
|
</div>
|