@tscircuit/schematic-viewer 2.0.45 → 2.0.47

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.
@@ -0,0 +1,26 @@
1
+ # Created using @tscircuit/plop (npm install -g @tscircuit/plop)
2
+ name: Format Check
3
+
4
+ on:
5
+ push:
6
+ branches: [main]
7
+ pull_request:
8
+ branches: [main]
9
+
10
+ jobs:
11
+ format-check:
12
+ runs-on: ubuntu-latest
13
+
14
+ steps:
15
+ - uses: actions/checkout@v4
16
+
17
+ - name: Setup bun
18
+ uses: oven-sh/setup-bun@v2
19
+ with:
20
+ bun-version: latest
21
+
22
+ - name: Install dependencies
23
+ run: bun install
24
+
25
+ - name: Run format check
26
+ run: bun run format:check
package/dist/index.js CHANGED
@@ -848,7 +848,7 @@ import { su as su5 } from "@tscircuit/soup-util";
848
848
  // package.json
849
849
  var package_default = {
850
850
  name: "@tscircuit/schematic-viewer",
851
- version: "2.0.44",
851
+ version: "2.0.46",
852
852
  main: "dist/index.js",
853
853
  type: "module",
854
854
  scripts: {
@@ -1789,6 +1789,7 @@ import {
1789
1789
  } from "react";
1790
1790
  import { Fragment as Fragment2, jsx as jsx9 } from "react/jsx-runtime";
1791
1791
  var MouseTrackerContext = createContext(null);
1792
+ var DRAG_THRESHOLD_PX = 5;
1792
1793
  var boundsAreEqual = (a, b) => {
1793
1794
  if (!a && !b) return true;
1794
1795
  if (!a || !b) return false;
@@ -1803,7 +1804,8 @@ var MouseTracker = ({ children }) => {
1803
1804
  pointer: null,
1804
1805
  boundingBoxes: /* @__PURE__ */ new Map(),
1805
1806
  hoveringIds: /* @__PURE__ */ new Set(),
1806
- subscribers: /* @__PURE__ */ new Set()
1807
+ subscribers: /* @__PURE__ */ new Set(),
1808
+ mouseDownPosition: null
1807
1809
  });
1808
1810
  const notifySubscribers = useCallback3(() => {
1809
1811
  for (const callback of storeRef.current.subscribers) {
@@ -1878,10 +1880,28 @@ var MouseTracker = ({ children }) => {
1878
1880
  const handlePointerLeave = () => {
1879
1881
  if (storeRef.current.pointer === null) return;
1880
1882
  storeRef.current.pointer = null;
1883
+ storeRef.current.mouseDownPosition = null;
1881
1884
  updateHovering();
1882
1885
  };
1886
+ const handleMouseDown = (event) => {
1887
+ storeRef.current.mouseDownPosition = {
1888
+ x: event.clientX,
1889
+ y: event.clientY
1890
+ };
1891
+ };
1883
1892
  const handleClick = (event) => {
1884
1893
  const { clientX, clientY } = event;
1894
+ const mouseDownPos = storeRef.current.mouseDownPosition;
1895
+ if (mouseDownPos) {
1896
+ const distance = Math.sqrt(
1897
+ Math.pow(clientX - mouseDownPos.x, 2) + Math.pow(clientY - mouseDownPos.y, 2)
1898
+ );
1899
+ if (distance > DRAG_THRESHOLD_PX) {
1900
+ storeRef.current.mouseDownPosition = null;
1901
+ return;
1902
+ }
1903
+ }
1904
+ storeRef.current.mouseDownPosition = null;
1885
1905
  for (const registration of storeRef.current.boundingBoxes.values()) {
1886
1906
  const bounds = registration.bounds;
1887
1907
  if (!bounds) continue;
@@ -1902,6 +1922,7 @@ var MouseTracker = ({ children }) => {
1902
1922
  window.addEventListener("pointerleave", handlePointerLeave);
1903
1923
  window.addEventListener("pointercancel", handlePointerLeave);
1904
1924
  window.addEventListener("blur", handlePointerLeave);
1925
+ window.addEventListener("mousedown", handleMouseDown, { passive: true });
1905
1926
  window.addEventListener("click", handleClick, { passive: true });
1906
1927
  return () => {
1907
1928
  window.removeEventListener("pointermove", handlePointerPosition);
@@ -1910,6 +1931,7 @@ var MouseTracker = ({ children }) => {
1910
1931
  window.removeEventListener("pointerleave", handlePointerLeave);
1911
1932
  window.removeEventListener("pointercancel", handlePointerLeave);
1912
1933
  window.removeEventListener("blur", handlePointerLeave);
1934
+ window.removeEventListener("mousedown", handleMouseDown);
1913
1935
  window.removeEventListener("click", handleClick);
1914
1936
  };
1915
1937
  }, [updateHovering]);
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","../lib/components/MouseTracker.tsx","../lib/components/SchematicComponentMouseTarget.tsx","../lib/hooks/useMouseEventsOverBoundingBox.ts"],"sourcesContent":["import {\n convertCircuitJsonToSchematicSvg,\n type ColorOverrides,\n} from \"circuit-to-svg\"\nimport { su } from \"@tscircuit/soup-util\"\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 { useCallback, 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\"\nimport { MouseTracker } from \"./MouseTracker\"\nimport { SchematicComponentMouseTarget } from \"./SchematicComponentMouseTarget\"\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 onSchematicComponentClicked?: (options: {\n schematicComponentId: string\n event: MouseEvent\n }) => void\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 onSchematicComponentClicked,\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 [isHoveringClickableComponent, setIsHoveringClickableComponent] =\n useState(false)\n const hoveringComponentsRef = useRef<Set<string>>(new Set())\n\n const handleComponentHoverChange = useCallback(\n (componentId: string, isHovering: boolean) => {\n if (isHovering) {\n hoveringComponentsRef.current.add(componentId)\n } else {\n hoveringComponentsRef.current.delete(componentId)\n }\n setIsHoveringClickableComponent(hoveringComponentsRef.current.size > 0)\n },\n [],\n )\n const svgDivRef = useRef<HTMLDivElement>(null)\n const touchStartRef = useRef<{ x: number; y: number } | null>(null)\n\n const schematicComponentIds = useMemo(() => {\n try {\n return (\n su(circuitJson)\n .schematic_component?.list()\n ?.map((component) => component.schematic_component_id as string) ?? []\n )\n } catch (err) {\n console.error(\"Failed to derive schematic component ids\", err)\n return []\n }\n }, [circuitJsonKey, circuitJson])\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 className={\n onSchematicComponentClicked\n ? \"schematic-component-clickable\"\n : undefined\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 <MouseTracker>\n {onSchematicComponentClicked && (\n <style>\n {`.schematic-component-clickable [data-schematic-component-id]:hover { cursor: pointer !important; }`}\n </style>\n )}\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 : isHoveringClickableComponent && onSchematicComponentClicked\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 {onSchematicComponentClicked &&\n schematicComponentIds.map((componentId) => (\n <SchematicComponentMouseTarget\n key={componentId}\n componentId={componentId}\n svgDivRef={svgDivRef}\n containerRef={containerRef}\n showOutline={true}\n circuitJsonKey={circuitJsonKey}\n onHoverChange={handleComponentHoverChange}\n onComponentClick={(id, event) => {\n onSchematicComponentClicked?.({\n schematicComponentId: id,\n event,\n })\n }}\n />\n ))}\n {svgDiv}\n </div>\n </MouseTracker>\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 schematicComponentHoverOutline: 47,\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.44\",\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 &times;\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","import {\n createContext,\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useRef,\n type ReactNode,\n} from \"react\"\n\nexport interface BoundingBoxBounds {\n minX: number\n maxX: number\n minY: number\n maxY: number\n}\n\ninterface BoundingBoxRegistration {\n bounds: BoundingBoxBounds | null\n onClick?: ((event: MouseEvent) => void) | undefined\n}\n\nexport interface MouseTrackerContextValue {\n registerBoundingBox: (\n id: string,\n registration: BoundingBoxRegistration,\n ) => void\n updateBoundingBox: (id: string, registration: BoundingBoxRegistration) => void\n unregisterBoundingBox: (id: string) => void\n subscribe: (listener: () => void) => () => void\n isHovering: (id: string) => boolean\n}\n\nexport const MouseTrackerContext =\n createContext<MouseTrackerContextValue | null>(null)\n\nconst boundsAreEqual = (\n a: BoundingBoxBounds | null | undefined,\n b: BoundingBoxBounds | null | undefined,\n) => {\n if (!a && !b) return true\n if (!a || !b) return false\n return (\n a.minX === b.minX &&\n a.maxX === b.maxX &&\n a.minY === b.minY &&\n a.maxY === b.maxY\n )\n}\n\nexport const MouseTracker = ({ children }: { children: ReactNode }) => {\n const existingContext = useContext(MouseTrackerContext)\n\n if (existingContext) {\n return <>{children}</>\n }\n\n const storeRef = useRef({\n pointer: null as { x: number; y: number } | null,\n boundingBoxes: new Map<string, BoundingBoxRegistration>(),\n hoveringIds: new Set<string>(),\n subscribers: new Set<() => void>(),\n })\n\n const notifySubscribers = useCallback(() => {\n for (const callback of storeRef.current.subscribers) {\n callback()\n }\n }, [])\n\n const updateHovering = useCallback(() => {\n const pointer = storeRef.current.pointer\n const newHovering = new Set<string>()\n\n if (pointer) {\n for (const [id, registration] of storeRef.current.boundingBoxes) {\n const bounds = registration.bounds\n if (!bounds) continue\n if (\n pointer.x >= bounds.minX &&\n pointer.x <= bounds.maxX &&\n pointer.y >= bounds.minY &&\n pointer.y <= bounds.maxY\n ) {\n newHovering.add(id)\n }\n }\n }\n\n const prevHovering = storeRef.current.hoveringIds\n if (\n newHovering.size === prevHovering.size &&\n [...newHovering].every((id) => prevHovering.has(id))\n ) {\n return\n }\n\n storeRef.current.hoveringIds = newHovering\n notifySubscribers()\n }, [notifySubscribers])\n\n const registerBoundingBox = useCallback(\n (id: string, registration: BoundingBoxRegistration) => {\n storeRef.current.boundingBoxes.set(id, registration)\n updateHovering()\n },\n [updateHovering],\n )\n\n const updateBoundingBox = useCallback(\n (id: string, registration: BoundingBoxRegistration) => {\n const existing = storeRef.current.boundingBoxes.get(id)\n if (\n existing &&\n boundsAreEqual(existing.bounds, registration.bounds) &&\n existing.onClick === registration.onClick\n ) {\n return\n }\n storeRef.current.boundingBoxes.set(id, registration)\n updateHovering()\n },\n [updateHovering],\n )\n\n const unregisterBoundingBox = useCallback(\n (id: string) => {\n const removed = storeRef.current.boundingBoxes.delete(id)\n if (removed) {\n updateHovering()\n }\n },\n [updateHovering],\n )\n\n const subscribe = useCallback((listener: () => void) => {\n storeRef.current.subscribers.add(listener)\n return () => {\n storeRef.current.subscribers.delete(listener)\n }\n }, [])\n\n const isHovering = useCallback((id: string) => {\n return storeRef.current.hoveringIds.has(id)\n }, [])\n\n useEffect(() => {\n const handlePointerPosition = (event: PointerEvent | MouseEvent) => {\n const { clientX, clientY } = event\n const pointer = storeRef.current.pointer\n if (pointer && pointer.x === clientX && pointer.y === clientY) {\n return\n }\n storeRef.current.pointer = { x: clientX, y: clientY }\n updateHovering()\n }\n\n const handlePointerLeave = () => {\n if (storeRef.current.pointer === null) return\n storeRef.current.pointer = null\n updateHovering()\n }\n\n const handleClick = (event: MouseEvent) => {\n const { clientX, clientY } = event\n for (const registration of storeRef.current.boundingBoxes.values()) {\n const bounds = registration.bounds\n if (!bounds) continue\n if (\n clientX >= bounds.minX &&\n clientX <= bounds.maxX &&\n clientY >= bounds.minY &&\n clientY <= bounds.maxY\n ) {\n registration.onClick?.(event)\n }\n }\n }\n\n window.addEventListener(\"pointermove\", handlePointerPosition, {\n passive: true,\n })\n window.addEventListener(\"pointerdown\", handlePointerPosition, {\n passive: true,\n })\n window.addEventListener(\"pointerup\", handlePointerPosition, {\n passive: true,\n })\n window.addEventListener(\"pointerleave\", handlePointerLeave)\n window.addEventListener(\"pointercancel\", handlePointerLeave)\n window.addEventListener(\"blur\", handlePointerLeave)\n window.addEventListener(\"click\", handleClick, { passive: true })\n\n return () => {\n window.removeEventListener(\"pointermove\", handlePointerPosition)\n window.removeEventListener(\"pointerdown\", handlePointerPosition)\n window.removeEventListener(\"pointerup\", handlePointerPosition)\n window.removeEventListener(\"pointerleave\", handlePointerLeave)\n window.removeEventListener(\"pointercancel\", handlePointerLeave)\n window.removeEventListener(\"blur\", handlePointerLeave)\n window.removeEventListener(\"click\", handleClick)\n }\n }, [updateHovering])\n\n const value = useMemo<MouseTrackerContextValue>(\n () => ({\n registerBoundingBox,\n updateBoundingBox,\n unregisterBoundingBox,\n subscribe,\n isHovering,\n }),\n [\n registerBoundingBox,\n updateBoundingBox,\n unregisterBoundingBox,\n subscribe,\n isHovering,\n ],\n )\n\n return (\n <MouseTrackerContext.Provider value={value}>\n {children}\n </MouseTrackerContext.Provider>\n )\n}\n","import { useCallback, useEffect, useRef, useState } from \"react\"\nimport { useMouseEventsOverBoundingBox } from \"../hooks/useMouseEventsOverBoundingBox\"\nimport type { BoundingBoxBounds } from \"./MouseTracker\"\nimport { zIndexMap } from \"../utils/z-index-map\"\n\ninterface RelativeRect {\n left: number\n top: number\n width: number\n height: number\n}\n\ninterface Measurement {\n bounds: BoundingBoxBounds\n rect: RelativeRect\n}\n\nconst areMeasurementsEqual = (a: Measurement | null, b: Measurement | null) => {\n if (!a && !b) return true\n if (!a || !b) return false\n return (\n Math.abs(a.bounds.minX - b.bounds.minX) < 0.5 &&\n Math.abs(a.bounds.maxX - b.bounds.maxX) < 0.5 &&\n Math.abs(a.bounds.minY - b.bounds.minY) < 0.5 &&\n Math.abs(a.bounds.maxY - b.bounds.maxY) < 0.5 &&\n Math.abs(a.rect.left - b.rect.left) < 0.5 &&\n Math.abs(a.rect.top - b.rect.top) < 0.5 &&\n Math.abs(a.rect.width - b.rect.width) < 0.5 &&\n Math.abs(a.rect.height - b.rect.height) < 0.5\n )\n}\n\ninterface Props {\n componentId: string\n svgDivRef: React.RefObject<HTMLDivElement | null>\n containerRef: React.RefObject<HTMLDivElement | null>\n onComponentClick?: (componentId: string, event: MouseEvent) => void\n onHoverChange?: (componentId: string, isHovering: boolean) => void\n showOutline: boolean\n circuitJsonKey: string\n}\n\nexport const SchematicComponentMouseTarget = ({\n componentId,\n svgDivRef,\n containerRef,\n onComponentClick,\n onHoverChange,\n showOutline,\n circuitJsonKey,\n}: Props) => {\n const [measurement, setMeasurement] = useState<Measurement | null>(null)\n const frameRef = useRef<number | null>(null)\n\n const measure = useCallback(() => {\n frameRef.current = null\n const svgDiv = svgDivRef.current\n const container = containerRef.current\n if (!svgDiv || !container) {\n setMeasurement((prev) => (prev ? null : prev))\n return\n }\n const element = svgDiv.querySelector<SVGGraphicsElement | HTMLElement>(\n `[data-schematic-component-id=\"${componentId}\"]`,\n )\n if (!element) {\n setMeasurement((prev) => (prev ? null : prev))\n return\n }\n\n const elementRect = element.getBoundingClientRect()\n const containerRect = container.getBoundingClientRect()\n\n const nextMeasurement: Measurement = {\n bounds: {\n minX: elementRect.left,\n maxX: elementRect.right,\n minY: elementRect.top,\n maxY: elementRect.bottom,\n },\n rect: {\n left: elementRect.left - containerRect.left,\n top: elementRect.top - containerRect.top,\n width: elementRect.width,\n height: elementRect.height,\n },\n }\n\n setMeasurement((prev) =>\n areMeasurementsEqual(prev, nextMeasurement) ? prev : nextMeasurement,\n )\n }, [componentId, containerRef, svgDivRef])\n\n const scheduleMeasure = useCallback(() => {\n if (frameRef.current !== null) return\n frameRef.current = window.requestAnimationFrame(measure)\n }, [measure])\n\n useEffect(() => {\n scheduleMeasure()\n }, [scheduleMeasure, circuitJsonKey])\n\n useEffect(() => {\n scheduleMeasure()\n const svgDiv = svgDivRef.current\n const container = containerRef.current\n if (!svgDiv || !container) return\n\n const resizeObserver =\n typeof ResizeObserver !== \"undefined\"\n ? new ResizeObserver(() => {\n scheduleMeasure()\n })\n : null\n resizeObserver?.observe(container)\n resizeObserver?.observe(svgDiv)\n\n const mutationObserver =\n typeof MutationObserver !== \"undefined\"\n ? new MutationObserver(() => {\n scheduleMeasure()\n })\n : null\n mutationObserver?.observe(svgDiv, {\n attributes: true,\n attributeFilter: [\"style\", \"transform\"],\n subtree: true,\n childList: true,\n })\n\n window.addEventListener(\"scroll\", scheduleMeasure, true)\n window.addEventListener(\"resize\", scheduleMeasure)\n\n return () => {\n resizeObserver?.disconnect()\n mutationObserver?.disconnect()\n window.removeEventListener(\"scroll\", scheduleMeasure, true)\n window.removeEventListener(\"resize\", scheduleMeasure)\n if (frameRef.current !== null) {\n cancelAnimationFrame(frameRef.current)\n frameRef.current = null\n }\n }\n }, [scheduleMeasure, svgDivRef, containerRef])\n\n const handleClick = useCallback(\n (event: MouseEvent) => {\n if (onComponentClick) {\n onComponentClick(componentId, event)\n }\n },\n [componentId, onComponentClick],\n )\n\n const bounds = measurement?.bounds ?? null\n\n const { hovering } = useMouseEventsOverBoundingBox({\n bounds,\n onClick: onComponentClick ? handleClick : undefined,\n })\n\n // Notify parent of hover state changes\n useEffect(() => {\n if (onHoverChange) {\n onHoverChange(componentId, hovering)\n }\n }, [hovering, componentId, onHoverChange])\n\n if (!measurement || !hovering || !showOutline) {\n return null\n }\n\n const rect = measurement.rect\n\n return (\n <div\n style={{\n position: \"absolute\",\n left: rect.left,\n top: rect.top,\n width: rect.width,\n height: rect.height,\n border: \"1.5px solid rgba(51, 153, 255, 0.9)\",\n pointerEvents: \"none\",\n zIndex: zIndexMap.schematicComponentHoverOutline,\n }}\n />\n )\n}\n","import {\n useContext,\n useEffect,\n useId,\n useMemo,\n useRef,\n useSyncExternalStore,\n} from \"react\"\nimport {\n MouseTrackerContext,\n type BoundingBoxBounds,\n} from \"../components/MouseTracker\"\n\ninterface UseMouseEventsOverBoundingBoxOptions {\n bounds: BoundingBoxBounds | null\n onClick?: (event: MouseEvent) => void\n}\n\nexport const useMouseEventsOverBoundingBox = (\n options: UseMouseEventsOverBoundingBoxOptions,\n) => {\n const context = useContext(MouseTrackerContext)\n\n if (!context) {\n throw new Error(\n \"useMouseEventsOverBoundingBox must be used within a MouseTracker\",\n )\n }\n\n const id = useId()\n const latestOptionsRef = useRef(options)\n latestOptionsRef.current = options\n\n const handleClick = useMemo(\n () => (event: MouseEvent) => {\n latestOptionsRef.current.onClick?.(event)\n },\n [],\n )\n\n useEffect(() => {\n context.registerBoundingBox(id, {\n bounds: latestOptionsRef.current.bounds,\n onClick: latestOptionsRef.current.onClick ? handleClick : undefined,\n })\n return () => {\n context.unregisterBoundingBox(id)\n }\n }, [context, handleClick, id])\n\n useEffect(() => {\n context.updateBoundingBox(id, {\n bounds: latestOptionsRef.current.bounds,\n onClick: latestOptionsRef.current.onClick ? handleClick : undefined,\n })\n }, [\n context,\n handleClick,\n id,\n options.bounds?.minX,\n options.bounds?.maxX,\n options.bounds?.minY,\n options.bounds?.maxY,\n options.onClick,\n ])\n\n const hovering = useSyncExternalStore(\n context.subscribe,\n () => context.isHovering(id),\n () => false,\n )\n\n return { hovering }\n}\n"],"mappings":"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","names":["su","useEffect","useRef","su","useEffect","su","useCallback","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","useCallback","useEffect","useMemo","useRef","Fragment","jsx","useCallback","useEffect","useRef","useState","useContext","useEffect","useMemo","useRef","useContext","useRef","useMemo","useEffect","jsx","useState","useRef","useCallback","useEffect","jsx","jsxs","debug","useState","circuitJson","useMemo","useEffect","useRef","useCallback","su"]}
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","../lib/components/MouseTracker.tsx","../lib/components/SchematicComponentMouseTarget.tsx","../lib/hooks/useMouseEventsOverBoundingBox.ts"],"sourcesContent":["import {\n convertCircuitJsonToSchematicSvg,\n type ColorOverrides,\n} from \"circuit-to-svg\"\nimport { su } from \"@tscircuit/soup-util\"\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 { useCallback, 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\"\nimport { MouseTracker } from \"./MouseTracker\"\nimport { SchematicComponentMouseTarget } from \"./SchematicComponentMouseTarget\"\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 onSchematicComponentClicked?: (options: {\n schematicComponentId: string\n event: MouseEvent\n }) => void\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 onSchematicComponentClicked,\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 [isHoveringClickableComponent, setIsHoveringClickableComponent] =\n useState(false)\n const hoveringComponentsRef = useRef<Set<string>>(new Set())\n\n const handleComponentHoverChange = useCallback(\n (componentId: string, isHovering: boolean) => {\n if (isHovering) {\n hoveringComponentsRef.current.add(componentId)\n } else {\n hoveringComponentsRef.current.delete(componentId)\n }\n setIsHoveringClickableComponent(hoveringComponentsRef.current.size > 0)\n },\n [],\n )\n const svgDivRef = useRef<HTMLDivElement>(null)\n const touchStartRef = useRef<{ x: number; y: number } | null>(null)\n\n const schematicComponentIds = useMemo(() => {\n try {\n return (\n su(circuitJson)\n .schematic_component?.list()\n ?.map((component) => component.schematic_component_id as string) ?? []\n )\n } catch (err) {\n console.error(\"Failed to derive schematic component ids\", err)\n return []\n }\n }, [circuitJsonKey, circuitJson])\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 className={\n onSchematicComponentClicked\n ? \"schematic-component-clickable\"\n : undefined\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 <MouseTracker>\n {onSchematicComponentClicked && (\n <style>\n {`.schematic-component-clickable [data-schematic-component-id]:hover { cursor: pointer !important; }`}\n </style>\n )}\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 : isHoveringClickableComponent && onSchematicComponentClicked\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 {onSchematicComponentClicked &&\n schematicComponentIds.map((componentId) => (\n <SchematicComponentMouseTarget\n key={componentId}\n componentId={componentId}\n svgDivRef={svgDivRef}\n containerRef={containerRef}\n showOutline={true}\n circuitJsonKey={circuitJsonKey}\n onHoverChange={handleComponentHoverChange}\n onComponentClick={(id, event) => {\n onSchematicComponentClicked?.({\n schematicComponentId: id,\n event,\n })\n }}\n />\n ))}\n {svgDiv}\n </div>\n </MouseTracker>\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 schematicComponentHoverOutline: 47,\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.46\",\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 &times;\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","import {\n createContext,\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useRef,\n type ReactNode,\n} from \"react\"\n\nexport interface BoundingBoxBounds {\n minX: number\n maxX: number\n minY: number\n maxY: number\n}\n\ninterface BoundingBoxRegistration {\n bounds: BoundingBoxBounds | null\n onClick?: ((event: MouseEvent) => void) | undefined\n}\n\nexport interface MouseTrackerContextValue {\n registerBoundingBox: (\n id: string,\n registration: BoundingBoxRegistration,\n ) => void\n updateBoundingBox: (id: string, registration: BoundingBoxRegistration) => void\n unregisterBoundingBox: (id: string) => void\n subscribe: (listener: () => void) => () => void\n isHovering: (id: string) => boolean\n}\n\nexport const MouseTrackerContext =\n createContext<MouseTrackerContextValue | null>(null)\n\nconst DRAG_THRESHOLD_PX = 5\n\nconst boundsAreEqual = (\n a: BoundingBoxBounds | null | undefined,\n b: BoundingBoxBounds | null | undefined,\n) => {\n if (!a && !b) return true\n if (!a || !b) return false\n return (\n a.minX === b.minX &&\n a.maxX === b.maxX &&\n a.minY === b.minY &&\n a.maxY === b.maxY\n )\n}\n\nexport const MouseTracker = ({ children }: { children: ReactNode }) => {\n const existingContext = useContext(MouseTrackerContext)\n\n if (existingContext) {\n return <>{children}</>\n }\n\n const storeRef = useRef({\n pointer: null as { x: number; y: number } | null,\n boundingBoxes: new Map<string, BoundingBoxRegistration>(),\n hoveringIds: new Set<string>(),\n subscribers: new Set<() => void>(),\n mouseDownPosition: null as { x: number; y: number } | null,\n })\n\n const notifySubscribers = useCallback(() => {\n for (const callback of storeRef.current.subscribers) {\n callback()\n }\n }, [])\n\n const updateHovering = useCallback(() => {\n const pointer = storeRef.current.pointer\n const newHovering = new Set<string>()\n\n if (pointer) {\n for (const [id, registration] of storeRef.current.boundingBoxes) {\n const bounds = registration.bounds\n if (!bounds) continue\n if (\n pointer.x >= bounds.minX &&\n pointer.x <= bounds.maxX &&\n pointer.y >= bounds.minY &&\n pointer.y <= bounds.maxY\n ) {\n newHovering.add(id)\n }\n }\n }\n\n const prevHovering = storeRef.current.hoveringIds\n if (\n newHovering.size === prevHovering.size &&\n [...newHovering].every((id) => prevHovering.has(id))\n ) {\n return\n }\n\n storeRef.current.hoveringIds = newHovering\n notifySubscribers()\n }, [notifySubscribers])\n\n const registerBoundingBox = useCallback(\n (id: string, registration: BoundingBoxRegistration) => {\n storeRef.current.boundingBoxes.set(id, registration)\n updateHovering()\n },\n [updateHovering],\n )\n\n const updateBoundingBox = useCallback(\n (id: string, registration: BoundingBoxRegistration) => {\n const existing = storeRef.current.boundingBoxes.get(id)\n if (\n existing &&\n boundsAreEqual(existing.bounds, registration.bounds) &&\n existing.onClick === registration.onClick\n ) {\n return\n }\n storeRef.current.boundingBoxes.set(id, registration)\n updateHovering()\n },\n [updateHovering],\n )\n\n const unregisterBoundingBox = useCallback(\n (id: string) => {\n const removed = storeRef.current.boundingBoxes.delete(id)\n if (removed) {\n updateHovering()\n }\n },\n [updateHovering],\n )\n\n const subscribe = useCallback((listener: () => void) => {\n storeRef.current.subscribers.add(listener)\n return () => {\n storeRef.current.subscribers.delete(listener)\n }\n }, [])\n\n const isHovering = useCallback((id: string) => {\n return storeRef.current.hoveringIds.has(id)\n }, [])\n\n useEffect(() => {\n const handlePointerPosition = (event: PointerEvent | MouseEvent) => {\n const { clientX, clientY } = event\n const pointer = storeRef.current.pointer\n if (pointer && pointer.x === clientX && pointer.y === clientY) {\n return\n }\n storeRef.current.pointer = { x: clientX, y: clientY }\n updateHovering()\n }\n\n const handlePointerLeave = () => {\n if (storeRef.current.pointer === null) return\n storeRef.current.pointer = null\n storeRef.current.mouseDownPosition = null\n updateHovering()\n }\n\n const handleMouseDown = (event: MouseEvent) => {\n storeRef.current.mouseDownPosition = {\n x: event.clientX,\n y: event.clientY,\n }\n }\n\n const handleClick = (event: MouseEvent) => {\n const { clientX, clientY } = event\n const mouseDownPos = storeRef.current.mouseDownPosition\n\n // Check if this was a drag (movement > threshold)\n if (mouseDownPos) {\n const distance = Math.sqrt(\n Math.pow(clientX - mouseDownPos.x, 2) +\n Math.pow(clientY - mouseDownPos.y, 2),\n )\n if (distance > DRAG_THRESHOLD_PX) {\n // This was a drag, not a click - don't trigger onClick\n storeRef.current.mouseDownPosition = null\n return\n }\n }\n\n storeRef.current.mouseDownPosition = null\n\n for (const registration of storeRef.current.boundingBoxes.values()) {\n const bounds = registration.bounds\n if (!bounds) continue\n if (\n clientX >= bounds.minX &&\n clientX <= bounds.maxX &&\n clientY >= bounds.minY &&\n clientY <= bounds.maxY\n ) {\n registration.onClick?.(event)\n }\n }\n }\n\n window.addEventListener(\"pointermove\", handlePointerPosition, {\n passive: true,\n })\n window.addEventListener(\"pointerdown\", handlePointerPosition, {\n passive: true,\n })\n window.addEventListener(\"pointerup\", handlePointerPosition, {\n passive: true,\n })\n window.addEventListener(\"pointerleave\", handlePointerLeave)\n window.addEventListener(\"pointercancel\", handlePointerLeave)\n window.addEventListener(\"blur\", handlePointerLeave)\n window.addEventListener(\"mousedown\", handleMouseDown, { passive: true })\n window.addEventListener(\"click\", handleClick, { passive: true })\n\n return () => {\n window.removeEventListener(\"pointermove\", handlePointerPosition)\n window.removeEventListener(\"pointerdown\", handlePointerPosition)\n window.removeEventListener(\"pointerup\", handlePointerPosition)\n window.removeEventListener(\"pointerleave\", handlePointerLeave)\n window.removeEventListener(\"pointercancel\", handlePointerLeave)\n window.removeEventListener(\"blur\", handlePointerLeave)\n window.removeEventListener(\"mousedown\", handleMouseDown)\n window.removeEventListener(\"click\", handleClick)\n }\n }, [updateHovering])\n\n const value = useMemo<MouseTrackerContextValue>(\n () => ({\n registerBoundingBox,\n updateBoundingBox,\n unregisterBoundingBox,\n subscribe,\n isHovering,\n }),\n [\n registerBoundingBox,\n updateBoundingBox,\n unregisterBoundingBox,\n subscribe,\n isHovering,\n ],\n )\n\n return (\n <MouseTrackerContext.Provider value={value}>\n {children}\n </MouseTrackerContext.Provider>\n )\n}\n","import { useCallback, useEffect, useRef, useState } from \"react\"\nimport { useMouseEventsOverBoundingBox } from \"../hooks/useMouseEventsOverBoundingBox\"\nimport type { BoundingBoxBounds } from \"./MouseTracker\"\nimport { zIndexMap } from \"../utils/z-index-map\"\n\ninterface RelativeRect {\n left: number\n top: number\n width: number\n height: number\n}\n\ninterface Measurement {\n bounds: BoundingBoxBounds\n rect: RelativeRect\n}\n\nconst areMeasurementsEqual = (a: Measurement | null, b: Measurement | null) => {\n if (!a && !b) return true\n if (!a || !b) return false\n return (\n Math.abs(a.bounds.minX - b.bounds.minX) < 0.5 &&\n Math.abs(a.bounds.maxX - b.bounds.maxX) < 0.5 &&\n Math.abs(a.bounds.minY - b.bounds.minY) < 0.5 &&\n Math.abs(a.bounds.maxY - b.bounds.maxY) < 0.5 &&\n Math.abs(a.rect.left - b.rect.left) < 0.5 &&\n Math.abs(a.rect.top - b.rect.top) < 0.5 &&\n Math.abs(a.rect.width - b.rect.width) < 0.5 &&\n Math.abs(a.rect.height - b.rect.height) < 0.5\n )\n}\n\ninterface Props {\n componentId: string\n svgDivRef: React.RefObject<HTMLDivElement | null>\n containerRef: React.RefObject<HTMLDivElement | null>\n onComponentClick?: (componentId: string, event: MouseEvent) => void\n onHoverChange?: (componentId: string, isHovering: boolean) => void\n showOutline: boolean\n circuitJsonKey: string\n}\n\nexport const SchematicComponentMouseTarget = ({\n componentId,\n svgDivRef,\n containerRef,\n onComponentClick,\n onHoverChange,\n showOutline,\n circuitJsonKey,\n}: Props) => {\n const [measurement, setMeasurement] = useState<Measurement | null>(null)\n const frameRef = useRef<number | null>(null)\n\n const measure = useCallback(() => {\n frameRef.current = null\n const svgDiv = svgDivRef.current\n const container = containerRef.current\n if (!svgDiv || !container) {\n setMeasurement((prev) => (prev ? null : prev))\n return\n }\n const element = svgDiv.querySelector<SVGGraphicsElement | HTMLElement>(\n `[data-schematic-component-id=\"${componentId}\"]`,\n )\n if (!element) {\n setMeasurement((prev) => (prev ? null : prev))\n return\n }\n\n const elementRect = element.getBoundingClientRect()\n const containerRect = container.getBoundingClientRect()\n\n const nextMeasurement: Measurement = {\n bounds: {\n minX: elementRect.left,\n maxX: elementRect.right,\n minY: elementRect.top,\n maxY: elementRect.bottom,\n },\n rect: {\n left: elementRect.left - containerRect.left,\n top: elementRect.top - containerRect.top,\n width: elementRect.width,\n height: elementRect.height,\n },\n }\n\n setMeasurement((prev) =>\n areMeasurementsEqual(prev, nextMeasurement) ? prev : nextMeasurement,\n )\n }, [componentId, containerRef, svgDivRef])\n\n const scheduleMeasure = useCallback(() => {\n if (frameRef.current !== null) return\n frameRef.current = window.requestAnimationFrame(measure)\n }, [measure])\n\n useEffect(() => {\n scheduleMeasure()\n }, [scheduleMeasure, circuitJsonKey])\n\n useEffect(() => {\n scheduleMeasure()\n const svgDiv = svgDivRef.current\n const container = containerRef.current\n if (!svgDiv || !container) return\n\n const resizeObserver =\n typeof ResizeObserver !== \"undefined\"\n ? new ResizeObserver(() => {\n scheduleMeasure()\n })\n : null\n resizeObserver?.observe(container)\n resizeObserver?.observe(svgDiv)\n\n const mutationObserver =\n typeof MutationObserver !== \"undefined\"\n ? new MutationObserver(() => {\n scheduleMeasure()\n })\n : null\n mutationObserver?.observe(svgDiv, {\n attributes: true,\n attributeFilter: [\"style\", \"transform\"],\n subtree: true,\n childList: true,\n })\n\n window.addEventListener(\"scroll\", scheduleMeasure, true)\n window.addEventListener(\"resize\", scheduleMeasure)\n\n return () => {\n resizeObserver?.disconnect()\n mutationObserver?.disconnect()\n window.removeEventListener(\"scroll\", scheduleMeasure, true)\n window.removeEventListener(\"resize\", scheduleMeasure)\n if (frameRef.current !== null) {\n cancelAnimationFrame(frameRef.current)\n frameRef.current = null\n }\n }\n }, [scheduleMeasure, svgDivRef, containerRef])\n\n const handleClick = useCallback(\n (event: MouseEvent) => {\n if (onComponentClick) {\n onComponentClick(componentId, event)\n }\n },\n [componentId, onComponentClick],\n )\n\n const bounds = measurement?.bounds ?? null\n\n const { hovering } = useMouseEventsOverBoundingBox({\n bounds,\n onClick: onComponentClick ? handleClick : undefined,\n })\n\n // Notify parent of hover state changes\n useEffect(() => {\n if (onHoverChange) {\n onHoverChange(componentId, hovering)\n }\n }, [hovering, componentId, onHoverChange])\n\n if (!measurement || !hovering || !showOutline) {\n return null\n }\n\n const rect = measurement.rect\n\n return (\n <div\n style={{\n position: \"absolute\",\n left: rect.left,\n top: rect.top,\n width: rect.width,\n height: rect.height,\n border: \"1.5px solid rgba(51, 153, 255, 0.9)\",\n pointerEvents: \"none\",\n zIndex: zIndexMap.schematicComponentHoverOutline,\n }}\n />\n )\n}\n","import {\n useContext,\n useEffect,\n useId,\n useMemo,\n useRef,\n useSyncExternalStore,\n} from \"react\"\nimport {\n MouseTrackerContext,\n type BoundingBoxBounds,\n} from \"../components/MouseTracker\"\n\ninterface UseMouseEventsOverBoundingBoxOptions {\n bounds: BoundingBoxBounds | null\n onClick?: (event: MouseEvent) => void\n}\n\nexport const useMouseEventsOverBoundingBox = (\n options: UseMouseEventsOverBoundingBoxOptions,\n) => {\n const context = useContext(MouseTrackerContext)\n\n if (!context) {\n throw new Error(\n \"useMouseEventsOverBoundingBox must be used within a MouseTracker\",\n )\n }\n\n const id = useId()\n const latestOptionsRef = useRef(options)\n latestOptionsRef.current = options\n\n const handleClick = useMemo(\n () => (event: MouseEvent) => {\n latestOptionsRef.current.onClick?.(event)\n },\n [],\n )\n\n useEffect(() => {\n context.registerBoundingBox(id, {\n bounds: latestOptionsRef.current.bounds,\n onClick: latestOptionsRef.current.onClick ? handleClick : undefined,\n })\n return () => {\n context.unregisterBoundingBox(id)\n }\n }, [context, handleClick, id])\n\n useEffect(() => {\n context.updateBoundingBox(id, {\n bounds: latestOptionsRef.current.bounds,\n onClick: latestOptionsRef.current.onClick ? handleClick : undefined,\n })\n }, [\n context,\n handleClick,\n id,\n options.bounds?.minX,\n options.bounds?.maxX,\n options.bounds?.minY,\n options.bounds?.maxY,\n options.onClick,\n ])\n\n const hovering = useSyncExternalStore(\n context.subscribe,\n () => context.isHovering(id),\n () => false,\n )\n\n return { hovering }\n}\n"],"mappings":"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","names":["su","useEffect","useRef","su","useEffect","su","useCallback","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","useCallback","useEffect","useMemo","useRef","Fragment","jsx","useCallback","useEffect","useRef","useState","useContext","useEffect","useMemo","useRef","useContext","useRef","useMemo","useEffect","jsx","useState","useRef","useCallback","useEffect","jsx","jsxs","debug","useState","circuitJson","useMemo","useEffect","useRef","useCallback","su"]}
@@ -34,6 +34,8 @@ export interface MouseTrackerContextValue {
34
34
  export const MouseTrackerContext =
35
35
  createContext<MouseTrackerContextValue | null>(null)
36
36
 
37
+ const DRAG_THRESHOLD_PX = 5
38
+
37
39
  const boundsAreEqual = (
38
40
  a: BoundingBoxBounds | null | undefined,
39
41
  b: BoundingBoxBounds | null | undefined,
@@ -60,6 +62,7 @@ export const MouseTracker = ({ children }: { children: ReactNode }) => {
60
62
  boundingBoxes: new Map<string, BoundingBoxRegistration>(),
61
63
  hoveringIds: new Set<string>(),
62
64
  subscribers: new Set<() => void>(),
65
+ mouseDownPosition: null as { x: number; y: number } | null,
63
66
  })
64
67
 
65
68
  const notifySubscribers = useCallback(() => {
@@ -158,11 +161,36 @@ export const MouseTracker = ({ children }: { children: ReactNode }) => {
158
161
  const handlePointerLeave = () => {
159
162
  if (storeRef.current.pointer === null) return
160
163
  storeRef.current.pointer = null
164
+ storeRef.current.mouseDownPosition = null
161
165
  updateHovering()
162
166
  }
163
167
 
168
+ const handleMouseDown = (event: MouseEvent) => {
169
+ storeRef.current.mouseDownPosition = {
170
+ x: event.clientX,
171
+ y: event.clientY,
172
+ }
173
+ }
174
+
164
175
  const handleClick = (event: MouseEvent) => {
165
176
  const { clientX, clientY } = event
177
+ const mouseDownPos = storeRef.current.mouseDownPosition
178
+
179
+ // Check if this was a drag (movement > threshold)
180
+ if (mouseDownPos) {
181
+ const distance = Math.sqrt(
182
+ Math.pow(clientX - mouseDownPos.x, 2) +
183
+ Math.pow(clientY - mouseDownPos.y, 2),
184
+ )
185
+ if (distance > DRAG_THRESHOLD_PX) {
186
+ // This was a drag, not a click - don't trigger onClick
187
+ storeRef.current.mouseDownPosition = null
188
+ return
189
+ }
190
+ }
191
+
192
+ storeRef.current.mouseDownPosition = null
193
+
166
194
  for (const registration of storeRef.current.boundingBoxes.values()) {
167
195
  const bounds = registration.bounds
168
196
  if (!bounds) continue
@@ -189,6 +217,7 @@ export const MouseTracker = ({ children }: { children: ReactNode }) => {
189
217
  window.addEventListener("pointerleave", handlePointerLeave)
190
218
  window.addEventListener("pointercancel", handlePointerLeave)
191
219
  window.addEventListener("blur", handlePointerLeave)
220
+ window.addEventListener("mousedown", handleMouseDown, { passive: true })
192
221
  window.addEventListener("click", handleClick, { passive: true })
193
222
 
194
223
  return () => {
@@ -198,6 +227,7 @@ export const MouseTracker = ({ children }: { children: ReactNode }) => {
198
227
  window.removeEventListener("pointerleave", handlePointerLeave)
199
228
  window.removeEventListener("pointercancel", handlePointerLeave)
200
229
  window.removeEventListener("blur", handlePointerLeave)
230
+ window.removeEventListener("mousedown", handleMouseDown)
201
231
  window.removeEventListener("click", handleClick)
202
232
  }
203
233
  }, [updateHovering])
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tscircuit/schematic-viewer",
3
- "version": "2.0.45",
3
+ "version": "2.0.47",
4
4
  "main": "dist/index.js",
5
5
  "type": "module",
6
6
  "scripts": {