Input port rendering on standard gates and components read srcGate.value
to determine active state, but for multi-output gates (BUS_OUT, COMPONENT)
.value only holds port 0's value. Connections from port N>0 always showed
port 0's state visually despite working correctly at the logic level.
Extract getSourcePortValue() helper that checks outputValues[fromPort]
for multi-output sources, and apply it consistently across all three
input port renderers (drawGate, drawBusGate, drawComponentGate).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The label lookup in drawComponentGate read from gate.component (potentially
stale copy) while gateOutputCount read from state.customComponents (updated
definition), causing a mismatch — fewer ports but old outputIds, so the
first (deleted) output's label was shown instead of the surviving one.
Three fixes:
- renderer: use customComponents as authoritative source for label lookup
- saveLoad: re-link gate.component refs to customComponents after loading
- components: update existing instances even when a "new" component
overwrites an existing definition with the same name
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
BUS_IN has input pins only (left side), BUS_OUT has output pins
only (right side). No internal connections between them — BUS_OUT
reads values directly from its paired BUS_IN via busPairId. The
bus cable between them is purely visual, representing the grouped
signal bundle.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Click and drag on empty space to draw a selection rectangle. Gates
inside the box get selected (cyan dashed outline). Drag any selected
gate to move all of them together. Delete/Backspace removes all
selected gates and their connections. Escape clears the selection.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Instead of a single pass-through gate, shift+drag now creates two
BUS terminals (IN and OUT) connected by a thick bus cable. Internal
connections between terminals are hidden and rendered as a single
cable with /N notation and a diagonal slash. Each terminal is a
thin cyan bar that can be moved independently.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Hold Shift and drag across wires to create a BUS gate that groups
them together. The cut line shows a live preview with wire count.
BUS gates are pass-through (each input maps to its output) and
render as a thin cyan bar with ports on each side.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Show input/output labels next to ports on custom component chips,
and persist internal gate state between evaluations so latches and
flip-flops retain their values correctly.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Major fixes for custom components when used in the main circuit:
- Add outputValues[] array for multi-output component gates, so each
output port carries its own independent value
- readSourcePort() reads the correct port value from source gates
instead of always reading gate.value
- evaluateComponent() now uses iterative fixed-point evaluation
(matching main evaluateAll) instead of a simple 10-pass loop
- Store inputIds/outputIds in component definition for consistent
port-to-gate mapping across save/load
- Renderer reads per-port values for connection color and port glow
- Added debug logs for component save and evaluation
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Double-click any INPUT, OUTPUT, or CLOCK gate to assign a custom label.
Labels are shown inside the gate and used in waveform viewer instead of
generic IN_0/OUT_0 names. Example circuits now ship with meaningful
labels (S, R, D, EN, Q, Q̅, CLK).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Redesigned toolbar with I/O, Gates, and Components sections
- Component editor: sub-canvas mode to design reusable chips
- Save/Cancel with main circuit state preservation
- Components persist in localStorage
- Custom components render as purple chips with dynamic I/O ports
- Component evaluation simulates internal circuit as black box
- Toolbar height increased to 56px for section labels
- All height references updated consistently
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Puzzle panel now shifts canvas and waveform viewer right (340px) instead of
overlapping them, using body class toggle and CSS transitions
- Canvas resize accounts for sidebar width
- Progress (completed/unlocked levels, custom components) persists in localStorage
- Level cards refresh on each panel open to reflect current progress
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>