velxio/frontend/src/simulation/parts/LogicGateParts.ts

309 lines
11 KiB
TypeScript
Raw Normal View History

/**
* LogicGateParts.ts Simulation logic for logic gate components.
*
* All gates listen to their input pins via pinManager.onPinChange,
* compute the boolean output, and drive the Y pin accordingly.
*
* 2-input gates: A, B Y
* NOT gate: A Y
*/
import { PartSimulationRegistry } from './PartSimulationRegistry';
import type { PartSimulationLogic } from './PartSimulationRegistry';
// ─── Helper ───────────────────────────────────────────────────────────────────
function twoInputGate(compute: (a: boolean, b: boolean) => boolean): PartSimulationLogic {
return {
feat(sim): Phase 5 — migrate every logic-gate handler to PinResolver twoInputGate (AND/NAND/OR/NOR/XOR/XNOR), nInputGate (3/4-input AND/OR/ NAND/NOR), edgeTriggeredFF (D/T/JK), and the standalone NOT gate all now prefer PinResolver input subscriptions. Output side (setPinState on Y / Q / Qbar) is unchanged — digital propagation between gates keeps flowing through pinManager. Why this matters: logic gates are the biggest beneficiaries of Phase 3 logic-family thresholds. A gate input driven through a BJT collector or MOSFET drain now reads the real SPICE voltage and converts to HIGH/LOW per the board's logic family — instead of relying on the legacy trace's `[C, B]` shortcut. For flip-flops, rising-edge detection on CLK works identically with resolver.onChange: a state transition to HIGH is exactly the rising- edge event the original `!prevClk && s` was watching for. All migrated handlers fall back to the legacy pinManager.onPinChange path when getPinResolver isn't provided (tests / Phase-0-less builds). Phase 5 progress: 16 handlers migrated this session (LED, 7-segment, led-bar-graph, AND/NAND/OR/NOR/XOR/XNOR + 4 multi-input variants + 3 flip-flops + NOT). Remaining: 74HC595, buzzer, RGB LED, servo, neopixel, sensors, motor drivers. Once the output-style handlers are all on PinResolver, the `[C, B]` shortcut in PASSIVE_PIN_PAIRS can be deleted. 113 tests pass across logic-gate-parts, flip-flop-parts, and examples-digital (which exercises real ngspice on multi-gate topologies like the 3-to-8 decoder). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-15 23:19:00 +07:00
attachEvents: (element, simulator, getPin, _componentId, getPinResolver) => {
const pinY = getPin('Y');
feat(sim): Phase 5 — migrate every logic-gate handler to PinResolver twoInputGate (AND/NAND/OR/NOR/XOR/XNOR), nInputGate (3/4-input AND/OR/ NAND/NOR), edgeTriggeredFF (D/T/JK), and the standalone NOT gate all now prefer PinResolver input subscriptions. Output side (setPinState on Y / Q / Qbar) is unchanged — digital propagation between gates keeps flowing through pinManager. Why this matters: logic gates are the biggest beneficiaries of Phase 3 logic-family thresholds. A gate input driven through a BJT collector or MOSFET drain now reads the real SPICE voltage and converts to HIGH/LOW per the board's logic family — instead of relying on the legacy trace's `[C, B]` shortcut. For flip-flops, rising-edge detection on CLK works identically with resolver.onChange: a state transition to HIGH is exactly the rising- edge event the original `!prevClk && s` was watching for. All migrated handlers fall back to the legacy pinManager.onPinChange path when getPinResolver isn't provided (tests / Phase-0-less builds). Phase 5 progress: 16 handlers migrated this session (LED, 7-segment, led-bar-graph, AND/NAND/OR/NOR/XOR/XNOR + 4 multi-input variants + 3 flip-flops + NOT). Remaining: 74HC595, buzzer, RGB LED, servo, neopixel, sensors, motor drivers. Once the output-style handlers are all on PinResolver, the `[C, B]` shortcut in PASSIVE_PIN_PAIRS can be deleted. 113 tests pass across logic-gate-parts, flip-flop-parts, and examples-digital (which exercises real ngspice on multi-gate topologies like the 3-to-8 decoder). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-15 23:19:00 +07:00
if (pinY === null) return () => {};
// Phase 5 migration: prefer the PinResolver path so gate inputs
// downstream of an active device (e.g. a sensor through a
// transistor) read via SPICE thresholds + the board logic family
// (Phase 3) instead of relying on direct pinManager state.
// The output side keeps using setPinState — digital propagation
// between gates is still pinManager's job.
const useResolver = typeof getPinResolver === 'function';
let stateA = false;
let stateB = false;
const update = () => simulator.setPinState(pinY, compute(stateA, stateB));
feat(sim): Phase 5 — migrate every logic-gate handler to PinResolver twoInputGate (AND/NAND/OR/NOR/XOR/XNOR), nInputGate (3/4-input AND/OR/ NAND/NOR), edgeTriggeredFF (D/T/JK), and the standalone NOT gate all now prefer PinResolver input subscriptions. Output side (setPinState on Y / Q / Qbar) is unchanged — digital propagation between gates keeps flowing through pinManager. Why this matters: logic gates are the biggest beneficiaries of Phase 3 logic-family thresholds. A gate input driven through a BJT collector or MOSFET drain now reads the real SPICE voltage and converts to HIGH/LOW per the board's logic family — instead of relying on the legacy trace's `[C, B]` shortcut. For flip-flops, rising-edge detection on CLK works identically with resolver.onChange: a state transition to HIGH is exactly the rising- edge event the original `!prevClk && s` was watching for. All migrated handlers fall back to the legacy pinManager.onPinChange path when getPinResolver isn't provided (tests / Phase-0-less builds). Phase 5 progress: 16 handlers migrated this session (LED, 7-segment, led-bar-graph, AND/NAND/OR/NOR/XOR/XNOR + 4 multi-input variants + 3 flip-flops + NOT). Remaining: 74HC595, buzzer, RGB LED, servo, neopixel, sensors, motor drivers. Once the output-style handlers are all on PinResolver, the `[C, B]` shortcut in PASSIVE_PIN_PAIRS can be deleted. 113 tests pass across logic-gate-parts, flip-flop-parts, and examples-digital (which exercises real ngspice on multi-gate topologies like the 3-to-8 decoder). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-15 23:19:00 +07:00
const unsubs: Array<() => void> = [];
if (useResolver) {
const resA = getPinResolver!('A');
const resB = getPinResolver!('B');
if (!resA || !resB) return () => {};
stateA = resA.getCurrentState() === 'HIGH';
stateB = resB.getCurrentState() === 'HIGH';
unsubs.push(
resA.onChange((state) => {
stateA = state === 'HIGH';
update();
}),
resB.onChange((state) => {
stateB = state === 'HIGH';
update();
}),
);
} else {
const pinA = getPin('A');
const pinB = getPin('B');
if (pinA === null || pinB === null) return () => {};
unsubs.push(
simulator.pinManager.onPinChange(pinA, (_: number, s: boolean) => {
stateA = s;
update();
}),
simulator.pinManager.onPinChange(pinB, (_: number, s: boolean) => {
stateB = s;
update();
}),
);
}
update(); // Drive Y immediately with initial state
return () => unsubs.forEach((u) => u());
},
};
}
// ─── AND ──────────────────────────────────────────────────────────────────────
PartSimulationRegistry.register(
'logic-gate-and',
twoInputGate((a, b) => a && b),
);
// ─── NAND ─────────────────────────────────────────────────────────────────────
PartSimulationRegistry.register(
'logic-gate-nand',
twoInputGate((a, b) => !(a && b)),
);
// ─── OR ───────────────────────────────────────────────────────────────────────
PartSimulationRegistry.register(
'logic-gate-or',
twoInputGate((a, b) => a || b),
);
// ─── NOR ──────────────────────────────────────────────────────────────────────
PartSimulationRegistry.register(
'logic-gate-nor',
twoInputGate((a, b) => !(a || b)),
);
// ─── XOR ──────────────────────────────────────────────────────────────────────
PartSimulationRegistry.register(
'logic-gate-xor',
twoInputGate((a, b) => a !== b),
);
feat: expand SPICE component catalog (fases 9 + 10) Adds 44 SPICE mappers, 58 custom metadata entries, and 12 visual Web Components covering logic gates, transistors, op-amps, regulators, sources, electromechanical parts and integrated-circuit packaging. Fase 9 — component catalog expansion ------------------------------------ - 7 logic gates (AND/OR/NAND/NOR/XOR/XNOR + NOT) as SPICE B-sources - 8 multi-input gates (AND/OR/NAND/NOR with 3 and 4 inputs) - 9 transistors: 5 BJTs (incl. PNP 2N3906/BC557) + 4 MOSFETs (incl. P-channel IRF9540/FQP27P06). NMOS refactored from Level=3 W=0.1 (hangs ngspice) to Level=1 with sane W/L - 5 op-amps: LM358, LM741, TL072, LM324 with per-chip saturation rails + opamp-ideal - 4 linear regulators (7805, 7812, 7905, LM317) with dropout - 3 batteries (9V, AA, coin-cell) with realistic ESR - Signal generator (sine / square / DC) - 2 Schottky diodes (1N5817, 1N5819) + photodiode (lux-driven current source) Fase 10 — electromechanical + ICs --------------------------------- - Relay (SPDT): coil + L + S-switch with native hysteresis + flyback diode, inverted-control trick for the NC contact - Optocouplers 4N25 and PC817 (LED + CCCS with CTR=0.5 / 1.0) - 7 74HC ICs as DIP-14 packages emitting 4 or 6 B-sources per component (first mapper pattern emitting multiple device cards) - 3 flip-flops (D, T, JK) — digital-sim only (edge detection is not representable in ngspice .op) - L293D dual H-bridge motor driver Infrastructure -------------- - scripts/component-overrides.json gains a _customComponents[] array that lets new Velxio-only parts survive metadata regeneration (previously applyOverrides() could only patch wokwi-elements components that had already been scanned) - scripts/generate-component-metadata.ts injects custom entries before the patch loop - New ComponentCategory values: 'logic', 'analog', 'electromech' - frontend/src/components/DynamicComponent.tsx PASSIVE tracing extended from just ['resistor','resistor-us'] to 9 two-terminal passives with per-part pin name maps - New CI workflow test-circuit.yml runs the sandbox on push/PR - frontend-tests.yml regenerates metadata and fails if committed JSON is stale - Documented 2 new ngspice gotchas in circuit-emulation-gotchas.md: unicode in netlist titles silently hangs the parser, and MOSFET Level=3 + W=0.1m causes .op to hang - 164/164 sandbox tests passing in ~9 s (was 88 pre-fase-9) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-16 06:44:18 +07:00
// ─── XNOR ─────────────────────────────────────────────────────────────────────
PartSimulationRegistry.register(
'logic-gate-xnor',
twoInputGate((a, b) => a === b),
);
feat: expand SPICE component catalog (fases 9 + 10) Adds 44 SPICE mappers, 58 custom metadata entries, and 12 visual Web Components covering logic gates, transistors, op-amps, regulators, sources, electromechanical parts and integrated-circuit packaging. Fase 9 — component catalog expansion ------------------------------------ - 7 logic gates (AND/OR/NAND/NOR/XOR/XNOR + NOT) as SPICE B-sources - 8 multi-input gates (AND/OR/NAND/NOR with 3 and 4 inputs) - 9 transistors: 5 BJTs (incl. PNP 2N3906/BC557) + 4 MOSFETs (incl. P-channel IRF9540/FQP27P06). NMOS refactored from Level=3 W=0.1 (hangs ngspice) to Level=1 with sane W/L - 5 op-amps: LM358, LM741, TL072, LM324 with per-chip saturation rails + opamp-ideal - 4 linear regulators (7805, 7812, 7905, LM317) with dropout - 3 batteries (9V, AA, coin-cell) with realistic ESR - Signal generator (sine / square / DC) - 2 Schottky diodes (1N5817, 1N5819) + photodiode (lux-driven current source) Fase 10 — electromechanical + ICs --------------------------------- - Relay (SPDT): coil + L + S-switch with native hysteresis + flyback diode, inverted-control trick for the NC contact - Optocouplers 4N25 and PC817 (LED + CCCS with CTR=0.5 / 1.0) - 7 74HC ICs as DIP-14 packages emitting 4 or 6 B-sources per component (first mapper pattern emitting multiple device cards) - 3 flip-flops (D, T, JK) — digital-sim only (edge detection is not representable in ngspice .op) - L293D dual H-bridge motor driver Infrastructure -------------- - scripts/component-overrides.json gains a _customComponents[] array that lets new Velxio-only parts survive metadata regeneration (previously applyOverrides() could only patch wokwi-elements components that had already been scanned) - scripts/generate-component-metadata.ts injects custom entries before the patch loop - New ComponentCategory values: 'logic', 'analog', 'electromech' - frontend/src/components/DynamicComponent.tsx PASSIVE tracing extended from just ['resistor','resistor-us'] to 9 two-terminal passives with per-part pin name maps - New CI workflow test-circuit.yml runs the sandbox on push/PR - frontend-tests.yml regenerates metadata and fails if committed JSON is stale - Documented 2 new ngspice gotchas in circuit-emulation-gotchas.md: unicode in netlist titles silently hangs the parser, and MOSFET Level=3 + W=0.1m causes .op to hang - 164/164 sandbox tests passing in ~9 s (was 88 pre-fase-9) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-16 06:44:18 +07:00
// ─── Multi-input gates (3 / 4 inputs) ─────────────────────────────────────────
function nInputGate(
inputNames: string[],
compute: (inputs: boolean[]) => boolean,
): PartSimulationLogic {
return {
feat(sim): Phase 5 — migrate every logic-gate handler to PinResolver twoInputGate (AND/NAND/OR/NOR/XOR/XNOR), nInputGate (3/4-input AND/OR/ NAND/NOR), edgeTriggeredFF (D/T/JK), and the standalone NOT gate all now prefer PinResolver input subscriptions. Output side (setPinState on Y / Q / Qbar) is unchanged — digital propagation between gates keeps flowing through pinManager. Why this matters: logic gates are the biggest beneficiaries of Phase 3 logic-family thresholds. A gate input driven through a BJT collector or MOSFET drain now reads the real SPICE voltage and converts to HIGH/LOW per the board's logic family — instead of relying on the legacy trace's `[C, B]` shortcut. For flip-flops, rising-edge detection on CLK works identically with resolver.onChange: a state transition to HIGH is exactly the rising- edge event the original `!prevClk && s` was watching for. All migrated handlers fall back to the legacy pinManager.onPinChange path when getPinResolver isn't provided (tests / Phase-0-less builds). Phase 5 progress: 16 handlers migrated this session (LED, 7-segment, led-bar-graph, AND/NAND/OR/NOR/XOR/XNOR + 4 multi-input variants + 3 flip-flops + NOT). Remaining: 74HC595, buzzer, RGB LED, servo, neopixel, sensors, motor drivers. Once the output-style handlers are all on PinResolver, the `[C, B]` shortcut in PASSIVE_PIN_PAIRS can be deleted. 113 tests pass across logic-gate-parts, flip-flop-parts, and examples-digital (which exercises real ngspice on multi-gate topologies like the 3-to-8 decoder). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-15 23:19:00 +07:00
attachEvents: (element, simulator, getPin, _componentId, getPinResolver) => {
feat: expand SPICE component catalog (fases 9 + 10) Adds 44 SPICE mappers, 58 custom metadata entries, and 12 visual Web Components covering logic gates, transistors, op-amps, regulators, sources, electromechanical parts and integrated-circuit packaging. Fase 9 — component catalog expansion ------------------------------------ - 7 logic gates (AND/OR/NAND/NOR/XOR/XNOR + NOT) as SPICE B-sources - 8 multi-input gates (AND/OR/NAND/NOR with 3 and 4 inputs) - 9 transistors: 5 BJTs (incl. PNP 2N3906/BC557) + 4 MOSFETs (incl. P-channel IRF9540/FQP27P06). NMOS refactored from Level=3 W=0.1 (hangs ngspice) to Level=1 with sane W/L - 5 op-amps: LM358, LM741, TL072, LM324 with per-chip saturation rails + opamp-ideal - 4 linear regulators (7805, 7812, 7905, LM317) with dropout - 3 batteries (9V, AA, coin-cell) with realistic ESR - Signal generator (sine / square / DC) - 2 Schottky diodes (1N5817, 1N5819) + photodiode (lux-driven current source) Fase 10 — electromechanical + ICs --------------------------------- - Relay (SPDT): coil + L + S-switch with native hysteresis + flyback diode, inverted-control trick for the NC contact - Optocouplers 4N25 and PC817 (LED + CCCS with CTR=0.5 / 1.0) - 7 74HC ICs as DIP-14 packages emitting 4 or 6 B-sources per component (first mapper pattern emitting multiple device cards) - 3 flip-flops (D, T, JK) — digital-sim only (edge detection is not representable in ngspice .op) - L293D dual H-bridge motor driver Infrastructure -------------- - scripts/component-overrides.json gains a _customComponents[] array that lets new Velxio-only parts survive metadata regeneration (previously applyOverrides() could only patch wokwi-elements components that had already been scanned) - scripts/generate-component-metadata.ts injects custom entries before the patch loop - New ComponentCategory values: 'logic', 'analog', 'electromech' - frontend/src/components/DynamicComponent.tsx PASSIVE tracing extended from just ['resistor','resistor-us'] to 9 two-terminal passives with per-part pin name maps - New CI workflow test-circuit.yml runs the sandbox on push/PR - frontend-tests.yml regenerates metadata and fails if committed JSON is stale - Documented 2 new ngspice gotchas in circuit-emulation-gotchas.md: unicode in netlist titles silently hangs the parser, and MOSFET Level=3 + W=0.1m causes .op to hang - 164/164 sandbox tests passing in ~9 s (was 88 pre-fase-9) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-16 06:44:18 +07:00
const pinY = getPin('Y');
feat(sim): Phase 5 — migrate every logic-gate handler to PinResolver twoInputGate (AND/NAND/OR/NOR/XOR/XNOR), nInputGate (3/4-input AND/OR/ NAND/NOR), edgeTriggeredFF (D/T/JK), and the standalone NOT gate all now prefer PinResolver input subscriptions. Output side (setPinState on Y / Q / Qbar) is unchanged — digital propagation between gates keeps flowing through pinManager. Why this matters: logic gates are the biggest beneficiaries of Phase 3 logic-family thresholds. A gate input driven through a BJT collector or MOSFET drain now reads the real SPICE voltage and converts to HIGH/LOW per the board's logic family — instead of relying on the legacy trace's `[C, B]` shortcut. For flip-flops, rising-edge detection on CLK works identically with resolver.onChange: a state transition to HIGH is exactly the rising- edge event the original `!prevClk && s` was watching for. All migrated handlers fall back to the legacy pinManager.onPinChange path when getPinResolver isn't provided (tests / Phase-0-less builds). Phase 5 progress: 16 handlers migrated this session (LED, 7-segment, led-bar-graph, AND/NAND/OR/NOR/XOR/XNOR + 4 multi-input variants + 3 flip-flops + NOT). Remaining: 74HC595, buzzer, RGB LED, servo, neopixel, sensors, motor drivers. Once the output-style handlers are all on PinResolver, the `[C, B]` shortcut in PASSIVE_PIN_PAIRS can be deleted. 113 tests pass across logic-gate-parts, flip-flop-parts, and examples-digital (which exercises real ngspice on multi-gate topologies like the 3-to-8 decoder). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-15 23:19:00 +07:00
if (pinY === null) return () => {};
feat: expand SPICE component catalog (fases 9 + 10) Adds 44 SPICE mappers, 58 custom metadata entries, and 12 visual Web Components covering logic gates, transistors, op-amps, regulators, sources, electromechanical parts and integrated-circuit packaging. Fase 9 — component catalog expansion ------------------------------------ - 7 logic gates (AND/OR/NAND/NOR/XOR/XNOR + NOT) as SPICE B-sources - 8 multi-input gates (AND/OR/NAND/NOR with 3 and 4 inputs) - 9 transistors: 5 BJTs (incl. PNP 2N3906/BC557) + 4 MOSFETs (incl. P-channel IRF9540/FQP27P06). NMOS refactored from Level=3 W=0.1 (hangs ngspice) to Level=1 with sane W/L - 5 op-amps: LM358, LM741, TL072, LM324 with per-chip saturation rails + opamp-ideal - 4 linear regulators (7805, 7812, 7905, LM317) with dropout - 3 batteries (9V, AA, coin-cell) with realistic ESR - Signal generator (sine / square / DC) - 2 Schottky diodes (1N5817, 1N5819) + photodiode (lux-driven current source) Fase 10 — electromechanical + ICs --------------------------------- - Relay (SPDT): coil + L + S-switch with native hysteresis + flyback diode, inverted-control trick for the NC contact - Optocouplers 4N25 and PC817 (LED + CCCS with CTR=0.5 / 1.0) - 7 74HC ICs as DIP-14 packages emitting 4 or 6 B-sources per component (first mapper pattern emitting multiple device cards) - 3 flip-flops (D, T, JK) — digital-sim only (edge detection is not representable in ngspice .op) - L293D dual H-bridge motor driver Infrastructure -------------- - scripts/component-overrides.json gains a _customComponents[] array that lets new Velxio-only parts survive metadata regeneration (previously applyOverrides() could only patch wokwi-elements components that had already been scanned) - scripts/generate-component-metadata.ts injects custom entries before the patch loop - New ComponentCategory values: 'logic', 'analog', 'electromech' - frontend/src/components/DynamicComponent.tsx PASSIVE tracing extended from just ['resistor','resistor-us'] to 9 two-terminal passives with per-part pin name maps - New CI workflow test-circuit.yml runs the sandbox on push/PR - frontend-tests.yml regenerates metadata and fails if committed JSON is stale - Documented 2 new ngspice gotchas in circuit-emulation-gotchas.md: unicode in netlist titles silently hangs the parser, and MOSFET Level=3 + W=0.1m causes .op to hang - 164/164 sandbox tests passing in ~9 s (was 88 pre-fase-9) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-16 06:44:18 +07:00
feat(sim): Phase 5 — migrate every logic-gate handler to PinResolver twoInputGate (AND/NAND/OR/NOR/XOR/XNOR), nInputGate (3/4-input AND/OR/ NAND/NOR), edgeTriggeredFF (D/T/JK), and the standalone NOT gate all now prefer PinResolver input subscriptions. Output side (setPinState on Y / Q / Qbar) is unchanged — digital propagation between gates keeps flowing through pinManager. Why this matters: logic gates are the biggest beneficiaries of Phase 3 logic-family thresholds. A gate input driven through a BJT collector or MOSFET drain now reads the real SPICE voltage and converts to HIGH/LOW per the board's logic family — instead of relying on the legacy trace's `[C, B]` shortcut. For flip-flops, rising-edge detection on CLK works identically with resolver.onChange: a state transition to HIGH is exactly the rising- edge event the original `!prevClk && s` was watching for. All migrated handlers fall back to the legacy pinManager.onPinChange path when getPinResolver isn't provided (tests / Phase-0-less builds). Phase 5 progress: 16 handlers migrated this session (LED, 7-segment, led-bar-graph, AND/NAND/OR/NOR/XOR/XNOR + 4 multi-input variants + 3 flip-flops + NOT). Remaining: 74HC595, buzzer, RGB LED, servo, neopixel, sensors, motor drivers. Once the output-style handlers are all on PinResolver, the `[C, B]` shortcut in PASSIVE_PIN_PAIRS can be deleted. 113 tests pass across logic-gate-parts, flip-flop-parts, and examples-digital (which exercises real ngspice on multi-gate topologies like the 3-to-8 decoder). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-15 23:19:00 +07:00
const useResolver = typeof getPinResolver === 'function';
feat: expand SPICE component catalog (fases 9 + 10) Adds 44 SPICE mappers, 58 custom metadata entries, and 12 visual Web Components covering logic gates, transistors, op-amps, regulators, sources, electromechanical parts and integrated-circuit packaging. Fase 9 — component catalog expansion ------------------------------------ - 7 logic gates (AND/OR/NAND/NOR/XOR/XNOR + NOT) as SPICE B-sources - 8 multi-input gates (AND/OR/NAND/NOR with 3 and 4 inputs) - 9 transistors: 5 BJTs (incl. PNP 2N3906/BC557) + 4 MOSFETs (incl. P-channel IRF9540/FQP27P06). NMOS refactored from Level=3 W=0.1 (hangs ngspice) to Level=1 with sane W/L - 5 op-amps: LM358, LM741, TL072, LM324 with per-chip saturation rails + opamp-ideal - 4 linear regulators (7805, 7812, 7905, LM317) with dropout - 3 batteries (9V, AA, coin-cell) with realistic ESR - Signal generator (sine / square / DC) - 2 Schottky diodes (1N5817, 1N5819) + photodiode (lux-driven current source) Fase 10 — electromechanical + ICs --------------------------------- - Relay (SPDT): coil + L + S-switch with native hysteresis + flyback diode, inverted-control trick for the NC contact - Optocouplers 4N25 and PC817 (LED + CCCS with CTR=0.5 / 1.0) - 7 74HC ICs as DIP-14 packages emitting 4 or 6 B-sources per component (first mapper pattern emitting multiple device cards) - 3 flip-flops (D, T, JK) — digital-sim only (edge detection is not representable in ngspice .op) - L293D dual H-bridge motor driver Infrastructure -------------- - scripts/component-overrides.json gains a _customComponents[] array that lets new Velxio-only parts survive metadata regeneration (previously applyOverrides() could only patch wokwi-elements components that had already been scanned) - scripts/generate-component-metadata.ts injects custom entries before the patch loop - New ComponentCategory values: 'logic', 'analog', 'electromech' - frontend/src/components/DynamicComponent.tsx PASSIVE tracing extended from just ['resistor','resistor-us'] to 9 two-terminal passives with per-part pin name maps - New CI workflow test-circuit.yml runs the sandbox on push/PR - frontend-tests.yml regenerates metadata and fails if committed JSON is stale - Documented 2 new ngspice gotchas in circuit-emulation-gotchas.md: unicode in netlist titles silently hangs the parser, and MOSFET Level=3 + W=0.1m causes .op to hang - 164/164 sandbox tests passing in ~9 s (was 88 pre-fase-9) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-16 06:44:18 +07:00
const states = inputNames.map(() => false);
const update = () => simulator.setPinState(pinY, compute(states));
feat(sim): Phase 5 — migrate every logic-gate handler to PinResolver twoInputGate (AND/NAND/OR/NOR/XOR/XNOR), nInputGate (3/4-input AND/OR/ NAND/NOR), edgeTriggeredFF (D/T/JK), and the standalone NOT gate all now prefer PinResolver input subscriptions. Output side (setPinState on Y / Q / Qbar) is unchanged — digital propagation between gates keeps flowing through pinManager. Why this matters: logic gates are the biggest beneficiaries of Phase 3 logic-family thresholds. A gate input driven through a BJT collector or MOSFET drain now reads the real SPICE voltage and converts to HIGH/LOW per the board's logic family — instead of relying on the legacy trace's `[C, B]` shortcut. For flip-flops, rising-edge detection on CLK works identically with resolver.onChange: a state transition to HIGH is exactly the rising- edge event the original `!prevClk && s` was watching for. All migrated handlers fall back to the legacy pinManager.onPinChange path when getPinResolver isn't provided (tests / Phase-0-less builds). Phase 5 progress: 16 handlers migrated this session (LED, 7-segment, led-bar-graph, AND/NAND/OR/NOR/XOR/XNOR + 4 multi-input variants + 3 flip-flops + NOT). Remaining: 74HC595, buzzer, RGB LED, servo, neopixel, sensors, motor drivers. Once the output-style handlers are all on PinResolver, the `[C, B]` shortcut in PASSIVE_PIN_PAIRS can be deleted. 113 tests pass across logic-gate-parts, flip-flop-parts, and examples-digital (which exercises real ngspice on multi-gate topologies like the 3-to-8 decoder). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-15 23:19:00 +07:00
const unsubs: Array<() => void> = [];
if (useResolver) {
const resolvers = inputNames.map((n) => getPinResolver!(n));
if (resolvers.some((r) => r === null)) return () => {};
resolvers.forEach((r, i) => {
states[i] = r!.getCurrentState() === 'HIGH';
unsubs.push(
r!.onChange((state) => {
states[i] = state === 'HIGH';
update();
}),
);
});
} else {
const inputPins = inputNames.map((n) => getPin(n));
if (inputPins.some((p) => p === null)) return () => {};
inputPins.forEach((p, i) => {
unsubs.push(
simulator.pinManager.onPinChange(p!, (_: number, s: boolean) => {
states[i] = s;
update();
}),
);
});
}
feat: expand SPICE component catalog (fases 9 + 10) Adds 44 SPICE mappers, 58 custom metadata entries, and 12 visual Web Components covering logic gates, transistors, op-amps, regulators, sources, electromechanical parts and integrated-circuit packaging. Fase 9 — component catalog expansion ------------------------------------ - 7 logic gates (AND/OR/NAND/NOR/XOR/XNOR + NOT) as SPICE B-sources - 8 multi-input gates (AND/OR/NAND/NOR with 3 and 4 inputs) - 9 transistors: 5 BJTs (incl. PNP 2N3906/BC557) + 4 MOSFETs (incl. P-channel IRF9540/FQP27P06). NMOS refactored from Level=3 W=0.1 (hangs ngspice) to Level=1 with sane W/L - 5 op-amps: LM358, LM741, TL072, LM324 with per-chip saturation rails + opamp-ideal - 4 linear regulators (7805, 7812, 7905, LM317) with dropout - 3 batteries (9V, AA, coin-cell) with realistic ESR - Signal generator (sine / square / DC) - 2 Schottky diodes (1N5817, 1N5819) + photodiode (lux-driven current source) Fase 10 — electromechanical + ICs --------------------------------- - Relay (SPDT): coil + L + S-switch with native hysteresis + flyback diode, inverted-control trick for the NC contact - Optocouplers 4N25 and PC817 (LED + CCCS with CTR=0.5 / 1.0) - 7 74HC ICs as DIP-14 packages emitting 4 or 6 B-sources per component (first mapper pattern emitting multiple device cards) - 3 flip-flops (D, T, JK) — digital-sim only (edge detection is not representable in ngspice .op) - L293D dual H-bridge motor driver Infrastructure -------------- - scripts/component-overrides.json gains a _customComponents[] array that lets new Velxio-only parts survive metadata regeneration (previously applyOverrides() could only patch wokwi-elements components that had already been scanned) - scripts/generate-component-metadata.ts injects custom entries before the patch loop - New ComponentCategory values: 'logic', 'analog', 'electromech' - frontend/src/components/DynamicComponent.tsx PASSIVE tracing extended from just ['resistor','resistor-us'] to 9 two-terminal passives with per-part pin name maps - New CI workflow test-circuit.yml runs the sandbox on push/PR - frontend-tests.yml regenerates metadata and fails if committed JSON is stale - Documented 2 new ngspice gotchas in circuit-emulation-gotchas.md: unicode in netlist titles silently hangs the parser, and MOSFET Level=3 + W=0.1m causes .op to hang - 164/164 sandbox tests passing in ~9 s (was 88 pre-fase-9) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-16 06:44:18 +07:00
update();
feat(sim): Phase 5 — migrate every logic-gate handler to PinResolver twoInputGate (AND/NAND/OR/NOR/XOR/XNOR), nInputGate (3/4-input AND/OR/ NAND/NOR), edgeTriggeredFF (D/T/JK), and the standalone NOT gate all now prefer PinResolver input subscriptions. Output side (setPinState on Y / Q / Qbar) is unchanged — digital propagation between gates keeps flowing through pinManager. Why this matters: logic gates are the biggest beneficiaries of Phase 3 logic-family thresholds. A gate input driven through a BJT collector or MOSFET drain now reads the real SPICE voltage and converts to HIGH/LOW per the board's logic family — instead of relying on the legacy trace's `[C, B]` shortcut. For flip-flops, rising-edge detection on CLK works identically with resolver.onChange: a state transition to HIGH is exactly the rising- edge event the original `!prevClk && s` was watching for. All migrated handlers fall back to the legacy pinManager.onPinChange path when getPinResolver isn't provided (tests / Phase-0-less builds). Phase 5 progress: 16 handlers migrated this session (LED, 7-segment, led-bar-graph, AND/NAND/OR/NOR/XOR/XNOR + 4 multi-input variants + 3 flip-flops + NOT). Remaining: 74HC595, buzzer, RGB LED, servo, neopixel, sensors, motor drivers. Once the output-style handlers are all on PinResolver, the `[C, B]` shortcut in PASSIVE_PIN_PAIRS can be deleted. 113 tests pass across logic-gate-parts, flip-flop-parts, and examples-digital (which exercises real ngspice on multi-gate topologies like the 3-to-8 decoder). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-15 23:19:00 +07:00
return () => unsubs.forEach((u) => u());
feat: expand SPICE component catalog (fases 9 + 10) Adds 44 SPICE mappers, 58 custom metadata entries, and 12 visual Web Components covering logic gates, transistors, op-amps, regulators, sources, electromechanical parts and integrated-circuit packaging. Fase 9 — component catalog expansion ------------------------------------ - 7 logic gates (AND/OR/NAND/NOR/XOR/XNOR + NOT) as SPICE B-sources - 8 multi-input gates (AND/OR/NAND/NOR with 3 and 4 inputs) - 9 transistors: 5 BJTs (incl. PNP 2N3906/BC557) + 4 MOSFETs (incl. P-channel IRF9540/FQP27P06). NMOS refactored from Level=3 W=0.1 (hangs ngspice) to Level=1 with sane W/L - 5 op-amps: LM358, LM741, TL072, LM324 with per-chip saturation rails + opamp-ideal - 4 linear regulators (7805, 7812, 7905, LM317) with dropout - 3 batteries (9V, AA, coin-cell) with realistic ESR - Signal generator (sine / square / DC) - 2 Schottky diodes (1N5817, 1N5819) + photodiode (lux-driven current source) Fase 10 — electromechanical + ICs --------------------------------- - Relay (SPDT): coil + L + S-switch with native hysteresis + flyback diode, inverted-control trick for the NC contact - Optocouplers 4N25 and PC817 (LED + CCCS with CTR=0.5 / 1.0) - 7 74HC ICs as DIP-14 packages emitting 4 or 6 B-sources per component (first mapper pattern emitting multiple device cards) - 3 flip-flops (D, T, JK) — digital-sim only (edge detection is not representable in ngspice .op) - L293D dual H-bridge motor driver Infrastructure -------------- - scripts/component-overrides.json gains a _customComponents[] array that lets new Velxio-only parts survive metadata regeneration (previously applyOverrides() could only patch wokwi-elements components that had already been scanned) - scripts/generate-component-metadata.ts injects custom entries before the patch loop - New ComponentCategory values: 'logic', 'analog', 'electromech' - frontend/src/components/DynamicComponent.tsx PASSIVE tracing extended from just ['resistor','resistor-us'] to 9 two-terminal passives with per-part pin name maps - New CI workflow test-circuit.yml runs the sandbox on push/PR - frontend-tests.yml regenerates metadata and fails if committed JSON is stale - Documented 2 new ngspice gotchas in circuit-emulation-gotchas.md: unicode in netlist titles silently hangs the parser, and MOSFET Level=3 + W=0.1m causes .op to hang - 164/164 sandbox tests passing in ~9 s (was 88 pre-fase-9) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-16 06:44:18 +07:00
},
};
}
const allTrue = (xs: boolean[]) => xs.every(Boolean);
const anyTrue = (xs: boolean[]) => xs.some(Boolean);
const notAll = (xs: boolean[]) => !allTrue(xs);
const notAny = (xs: boolean[]) => !anyTrue(xs);
feat: expand SPICE component catalog (fases 9 + 10) Adds 44 SPICE mappers, 58 custom metadata entries, and 12 visual Web Components covering logic gates, transistors, op-amps, regulators, sources, electromechanical parts and integrated-circuit packaging. Fase 9 — component catalog expansion ------------------------------------ - 7 logic gates (AND/OR/NAND/NOR/XOR/XNOR + NOT) as SPICE B-sources - 8 multi-input gates (AND/OR/NAND/NOR with 3 and 4 inputs) - 9 transistors: 5 BJTs (incl. PNP 2N3906/BC557) + 4 MOSFETs (incl. P-channel IRF9540/FQP27P06). NMOS refactored from Level=3 W=0.1 (hangs ngspice) to Level=1 with sane W/L - 5 op-amps: LM358, LM741, TL072, LM324 with per-chip saturation rails + opamp-ideal - 4 linear regulators (7805, 7812, 7905, LM317) with dropout - 3 batteries (9V, AA, coin-cell) with realistic ESR - Signal generator (sine / square / DC) - 2 Schottky diodes (1N5817, 1N5819) + photodiode (lux-driven current source) Fase 10 — electromechanical + ICs --------------------------------- - Relay (SPDT): coil + L + S-switch with native hysteresis + flyback diode, inverted-control trick for the NC contact - Optocouplers 4N25 and PC817 (LED + CCCS with CTR=0.5 / 1.0) - 7 74HC ICs as DIP-14 packages emitting 4 or 6 B-sources per component (first mapper pattern emitting multiple device cards) - 3 flip-flops (D, T, JK) — digital-sim only (edge detection is not representable in ngspice .op) - L293D dual H-bridge motor driver Infrastructure -------------- - scripts/component-overrides.json gains a _customComponents[] array that lets new Velxio-only parts survive metadata regeneration (previously applyOverrides() could only patch wokwi-elements components that had already been scanned) - scripts/generate-component-metadata.ts injects custom entries before the patch loop - New ComponentCategory values: 'logic', 'analog', 'electromech' - frontend/src/components/DynamicComponent.tsx PASSIVE tracing extended from just ['resistor','resistor-us'] to 9 two-terminal passives with per-part pin name maps - New CI workflow test-circuit.yml runs the sandbox on push/PR - frontend-tests.yml regenerates metadata and fails if committed JSON is stale - Documented 2 new ngspice gotchas in circuit-emulation-gotchas.md: unicode in netlist titles silently hangs the parser, and MOSFET Level=3 + W=0.1m causes .op to hang - 164/164 sandbox tests passing in ~9 s (was 88 pre-fase-9) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-16 06:44:18 +07:00
// ─── Flip-flops (edge-triggered, digital-sim only) ────────────────────────────
// SPICE mode cannot simulate real edge detection at DC; these components are
// therefore digital-only and do not emit a SPICE mapper.
//
// Each FF samples its data inputs on the rising edge of CLK. Q and Qbar are
// driven synchronously.
function edgeTriggeredFF(
dataPins: string[],
initial: boolean,
sample: (state: boolean, inputs: boolean[]) => boolean,
): PartSimulationLogic {
return {
feat(sim): Phase 5 — migrate every logic-gate handler to PinResolver twoInputGate (AND/NAND/OR/NOR/XOR/XNOR), nInputGate (3/4-input AND/OR/ NAND/NOR), edgeTriggeredFF (D/T/JK), and the standalone NOT gate all now prefer PinResolver input subscriptions. Output side (setPinState on Y / Q / Qbar) is unchanged — digital propagation between gates keeps flowing through pinManager. Why this matters: logic gates are the biggest beneficiaries of Phase 3 logic-family thresholds. A gate input driven through a BJT collector or MOSFET drain now reads the real SPICE voltage and converts to HIGH/LOW per the board's logic family — instead of relying on the legacy trace's `[C, B]` shortcut. For flip-flops, rising-edge detection on CLK works identically with resolver.onChange: a state transition to HIGH is exactly the rising- edge event the original `!prevClk && s` was watching for. All migrated handlers fall back to the legacy pinManager.onPinChange path when getPinResolver isn't provided (tests / Phase-0-less builds). Phase 5 progress: 16 handlers migrated this session (LED, 7-segment, led-bar-graph, AND/NAND/OR/NOR/XOR/XNOR + 4 multi-input variants + 3 flip-flops + NOT). Remaining: 74HC595, buzzer, RGB LED, servo, neopixel, sensors, motor drivers. Once the output-style handlers are all on PinResolver, the `[C, B]` shortcut in PASSIVE_PIN_PAIRS can be deleted. 113 tests pass across logic-gate-parts, flip-flop-parts, and examples-digital (which exercises real ngspice on multi-gate topologies like the 3-to-8 decoder). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-15 23:19:00 +07:00
attachEvents: (element, simulator, getPin, _componentId, getPinResolver) => {
feat: expand SPICE component catalog (fases 9 + 10) Adds 44 SPICE mappers, 58 custom metadata entries, and 12 visual Web Components covering logic gates, transistors, op-amps, regulators, sources, electromechanical parts and integrated-circuit packaging. Fase 9 — component catalog expansion ------------------------------------ - 7 logic gates (AND/OR/NAND/NOR/XOR/XNOR + NOT) as SPICE B-sources - 8 multi-input gates (AND/OR/NAND/NOR with 3 and 4 inputs) - 9 transistors: 5 BJTs (incl. PNP 2N3906/BC557) + 4 MOSFETs (incl. P-channel IRF9540/FQP27P06). NMOS refactored from Level=3 W=0.1 (hangs ngspice) to Level=1 with sane W/L - 5 op-amps: LM358, LM741, TL072, LM324 with per-chip saturation rails + opamp-ideal - 4 linear regulators (7805, 7812, 7905, LM317) with dropout - 3 batteries (9V, AA, coin-cell) with realistic ESR - Signal generator (sine / square / DC) - 2 Schottky diodes (1N5817, 1N5819) + photodiode (lux-driven current source) Fase 10 — electromechanical + ICs --------------------------------- - Relay (SPDT): coil + L + S-switch with native hysteresis + flyback diode, inverted-control trick for the NC contact - Optocouplers 4N25 and PC817 (LED + CCCS with CTR=0.5 / 1.0) - 7 74HC ICs as DIP-14 packages emitting 4 or 6 B-sources per component (first mapper pattern emitting multiple device cards) - 3 flip-flops (D, T, JK) — digital-sim only (edge detection is not representable in ngspice .op) - L293D dual H-bridge motor driver Infrastructure -------------- - scripts/component-overrides.json gains a _customComponents[] array that lets new Velxio-only parts survive metadata regeneration (previously applyOverrides() could only patch wokwi-elements components that had already been scanned) - scripts/generate-component-metadata.ts injects custom entries before the patch loop - New ComponentCategory values: 'logic', 'analog', 'electromech' - frontend/src/components/DynamicComponent.tsx PASSIVE tracing extended from just ['resistor','resistor-us'] to 9 two-terminal passives with per-part pin name maps - New CI workflow test-circuit.yml runs the sandbox on push/PR - frontend-tests.yml regenerates metadata and fails if committed JSON is stale - Documented 2 new ngspice gotchas in circuit-emulation-gotchas.md: unicode in netlist titles silently hangs the parser, and MOSFET Level=3 + W=0.1m causes .op to hang - 164/164 sandbox tests passing in ~9 s (was 88 pre-fase-9) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-16 06:44:18 +07:00
const qPin = getPin('Q');
const qbarPin = getPin('Qbar');
feat(sim): Phase 5 — migrate every logic-gate handler to PinResolver twoInputGate (AND/NAND/OR/NOR/XOR/XNOR), nInputGate (3/4-input AND/OR/ NAND/NOR), edgeTriggeredFF (D/T/JK), and the standalone NOT gate all now prefer PinResolver input subscriptions. Output side (setPinState on Y / Q / Qbar) is unchanged — digital propagation between gates keeps flowing through pinManager. Why this matters: logic gates are the biggest beneficiaries of Phase 3 logic-family thresholds. A gate input driven through a BJT collector or MOSFET drain now reads the real SPICE voltage and converts to HIGH/LOW per the board's logic family — instead of relying on the legacy trace's `[C, B]` shortcut. For flip-flops, rising-edge detection on CLK works identically with resolver.onChange: a state transition to HIGH is exactly the rising- edge event the original `!prevClk && s` was watching for. All migrated handlers fall back to the legacy pinManager.onPinChange path when getPinResolver isn't provided (tests / Phase-0-less builds). Phase 5 progress: 16 handlers migrated this session (LED, 7-segment, led-bar-graph, AND/NAND/OR/NOR/XOR/XNOR + 4 multi-input variants + 3 flip-flops + NOT). Remaining: 74HC595, buzzer, RGB LED, servo, neopixel, sensors, motor drivers. Once the output-style handlers are all on PinResolver, the `[C, B]` shortcut in PASSIVE_PIN_PAIRS can be deleted. 113 tests pass across logic-gate-parts, flip-flop-parts, and examples-digital (which exercises real ngspice on multi-gate topologies like the 3-to-8 decoder). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-15 23:19:00 +07:00
if (qPin === null || qbarPin === null) return () => {};
feat: expand SPICE component catalog (fases 9 + 10) Adds 44 SPICE mappers, 58 custom metadata entries, and 12 visual Web Components covering logic gates, transistors, op-amps, regulators, sources, electromechanical parts and integrated-circuit packaging. Fase 9 — component catalog expansion ------------------------------------ - 7 logic gates (AND/OR/NAND/NOR/XOR/XNOR + NOT) as SPICE B-sources - 8 multi-input gates (AND/OR/NAND/NOR with 3 and 4 inputs) - 9 transistors: 5 BJTs (incl. PNP 2N3906/BC557) + 4 MOSFETs (incl. P-channel IRF9540/FQP27P06). NMOS refactored from Level=3 W=0.1 (hangs ngspice) to Level=1 with sane W/L - 5 op-amps: LM358, LM741, TL072, LM324 with per-chip saturation rails + opamp-ideal - 4 linear regulators (7805, 7812, 7905, LM317) with dropout - 3 batteries (9V, AA, coin-cell) with realistic ESR - Signal generator (sine / square / DC) - 2 Schottky diodes (1N5817, 1N5819) + photodiode (lux-driven current source) Fase 10 — electromechanical + ICs --------------------------------- - Relay (SPDT): coil + L + S-switch with native hysteresis + flyback diode, inverted-control trick for the NC contact - Optocouplers 4N25 and PC817 (LED + CCCS with CTR=0.5 / 1.0) - 7 74HC ICs as DIP-14 packages emitting 4 or 6 B-sources per component (first mapper pattern emitting multiple device cards) - 3 flip-flops (D, T, JK) — digital-sim only (edge detection is not representable in ngspice .op) - L293D dual H-bridge motor driver Infrastructure -------------- - scripts/component-overrides.json gains a _customComponents[] array that lets new Velxio-only parts survive metadata regeneration (previously applyOverrides() could only patch wokwi-elements components that had already been scanned) - scripts/generate-component-metadata.ts injects custom entries before the patch loop - New ComponentCategory values: 'logic', 'analog', 'electromech' - frontend/src/components/DynamicComponent.tsx PASSIVE tracing extended from just ['resistor','resistor-us'] to 9 two-terminal passives with per-part pin name maps - New CI workflow test-circuit.yml runs the sandbox on push/PR - frontend-tests.yml regenerates metadata and fails if committed JSON is stale - Documented 2 new ngspice gotchas in circuit-emulation-gotchas.md: unicode in netlist titles silently hangs the parser, and MOSFET Level=3 + W=0.1m causes .op to hang - 164/164 sandbox tests passing in ~9 s (was 88 pre-fase-9) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-16 06:44:18 +07:00
feat(sim): Phase 5 — migrate every logic-gate handler to PinResolver twoInputGate (AND/NAND/OR/NOR/XOR/XNOR), nInputGate (3/4-input AND/OR/ NAND/NOR), edgeTriggeredFF (D/T/JK), and the standalone NOT gate all now prefer PinResolver input subscriptions. Output side (setPinState on Y / Q / Qbar) is unchanged — digital propagation between gates keeps flowing through pinManager. Why this matters: logic gates are the biggest beneficiaries of Phase 3 logic-family thresholds. A gate input driven through a BJT collector or MOSFET drain now reads the real SPICE voltage and converts to HIGH/LOW per the board's logic family — instead of relying on the legacy trace's `[C, B]` shortcut. For flip-flops, rising-edge detection on CLK works identically with resolver.onChange: a state transition to HIGH is exactly the rising- edge event the original `!prevClk && s` was watching for. All migrated handlers fall back to the legacy pinManager.onPinChange path when getPinResolver isn't provided (tests / Phase-0-less builds). Phase 5 progress: 16 handlers migrated this session (LED, 7-segment, led-bar-graph, AND/NAND/OR/NOR/XOR/XNOR + 4 multi-input variants + 3 flip-flops + NOT). Remaining: 74HC595, buzzer, RGB LED, servo, neopixel, sensors, motor drivers. Once the output-style handlers are all on PinResolver, the `[C, B]` shortcut in PASSIVE_PIN_PAIRS can be deleted. 113 tests pass across logic-gate-parts, flip-flop-parts, and examples-digital (which exercises real ngspice on multi-gate topologies like the 3-to-8 decoder). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-15 23:19:00 +07:00
const useResolver = typeof getPinResolver === 'function';
feat: expand SPICE component catalog (fases 9 + 10) Adds 44 SPICE mappers, 58 custom metadata entries, and 12 visual Web Components covering logic gates, transistors, op-amps, regulators, sources, electromechanical parts and integrated-circuit packaging. Fase 9 — component catalog expansion ------------------------------------ - 7 logic gates (AND/OR/NAND/NOR/XOR/XNOR + NOT) as SPICE B-sources - 8 multi-input gates (AND/OR/NAND/NOR with 3 and 4 inputs) - 9 transistors: 5 BJTs (incl. PNP 2N3906/BC557) + 4 MOSFETs (incl. P-channel IRF9540/FQP27P06). NMOS refactored from Level=3 W=0.1 (hangs ngspice) to Level=1 with sane W/L - 5 op-amps: LM358, LM741, TL072, LM324 with per-chip saturation rails + opamp-ideal - 4 linear regulators (7805, 7812, 7905, LM317) with dropout - 3 batteries (9V, AA, coin-cell) with realistic ESR - Signal generator (sine / square / DC) - 2 Schottky diodes (1N5817, 1N5819) + photodiode (lux-driven current source) Fase 10 — electromechanical + ICs --------------------------------- - Relay (SPDT): coil + L + S-switch with native hysteresis + flyback diode, inverted-control trick for the NC contact - Optocouplers 4N25 and PC817 (LED + CCCS with CTR=0.5 / 1.0) - 7 74HC ICs as DIP-14 packages emitting 4 or 6 B-sources per component (first mapper pattern emitting multiple device cards) - 3 flip-flops (D, T, JK) — digital-sim only (edge detection is not representable in ngspice .op) - L293D dual H-bridge motor driver Infrastructure -------------- - scripts/component-overrides.json gains a _customComponents[] array that lets new Velxio-only parts survive metadata regeneration (previously applyOverrides() could only patch wokwi-elements components that had already been scanned) - scripts/generate-component-metadata.ts injects custom entries before the patch loop - New ComponentCategory values: 'logic', 'analog', 'electromech' - frontend/src/components/DynamicComponent.tsx PASSIVE tracing extended from just ['resistor','resistor-us'] to 9 two-terminal passives with per-part pin name maps - New CI workflow test-circuit.yml runs the sandbox on push/PR - frontend-tests.yml regenerates metadata and fails if committed JSON is stale - Documented 2 new ngspice gotchas in circuit-emulation-gotchas.md: unicode in netlist titles silently hangs the parser, and MOSFET Level=3 + W=0.1m causes .op to hang - 164/164 sandbox tests passing in ~9 s (was 88 pre-fase-9) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-16 06:44:18 +07:00
let prevClk = false;
let q = initial;
const dataStates = dataPins.map(() => false);
const emit = () => {
simulator.setPinState(qPin, q);
simulator.setPinState(qbarPin, !q);
};
feat(sim): Phase 5 — migrate every logic-gate handler to PinResolver twoInputGate (AND/NAND/OR/NOR/XOR/XNOR), nInputGate (3/4-input AND/OR/ NAND/NOR), edgeTriggeredFF (D/T/JK), and the standalone NOT gate all now prefer PinResolver input subscriptions. Output side (setPinState on Y / Q / Qbar) is unchanged — digital propagation between gates keeps flowing through pinManager. Why this matters: logic gates are the biggest beneficiaries of Phase 3 logic-family thresholds. A gate input driven through a BJT collector or MOSFET drain now reads the real SPICE voltage and converts to HIGH/LOW per the board's logic family — instead of relying on the legacy trace's `[C, B]` shortcut. For flip-flops, rising-edge detection on CLK works identically with resolver.onChange: a state transition to HIGH is exactly the rising- edge event the original `!prevClk && s` was watching for. All migrated handlers fall back to the legacy pinManager.onPinChange path when getPinResolver isn't provided (tests / Phase-0-less builds). Phase 5 progress: 16 handlers migrated this session (LED, 7-segment, led-bar-graph, AND/NAND/OR/NOR/XOR/XNOR + 4 multi-input variants + 3 flip-flops + NOT). Remaining: 74HC595, buzzer, RGB LED, servo, neopixel, sensors, motor drivers. Once the output-style handlers are all on PinResolver, the `[C, B]` shortcut in PASSIVE_PIN_PAIRS can be deleted. 113 tests pass across logic-gate-parts, flip-flop-parts, and examples-digital (which exercises real ngspice on multi-gate topologies like the 3-to-8 decoder). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-15 23:19:00 +07:00
const unsubs: Array<() => void> = [];
if (useResolver) {
const resClk = getPinResolver!('CLK');
const resData = dataPins.map((n) => getPinResolver!(n));
if (!resClk || resData.some((r) => r === null)) return () => {};
prevClk = resClk.getCurrentState() === 'HIGH';
resData.forEach((r, i) => {
dataStates[i] = r!.getCurrentState() === 'HIGH';
});
unsubs.push(
resClk.onChange((state) => {
const s = state === 'HIGH';
if (!prevClk && s) {
q = sample(q, dataStates);
emit();
}
prevClk = s;
}),
);
resData.forEach((r, i) => {
unsubs.push(
r!.onChange((state) => {
dataStates[i] = state === 'HIGH';
}),
);
});
} else {
const clkPin = getPin('CLK');
const dataPinIds = dataPins.map((n) => getPin(n));
if (clkPin === null || dataPinIds.some((p) => p === null)) return () => {};
unsubs.push(
simulator.pinManager.onPinChange(clkPin, (_: number, s: boolean) => {
if (!prevClk && s) {
q = sample(q, dataStates);
emit();
}
prevClk = s;
}),
);
dataPinIds.forEach((p, i) => {
unsubs.push(
simulator.pinManager.onPinChange(p!, (_: number, s: boolean) => {
dataStates[i] = s;
}),
);
});
}
feat: expand SPICE component catalog (fases 9 + 10) Adds 44 SPICE mappers, 58 custom metadata entries, and 12 visual Web Components covering logic gates, transistors, op-amps, regulators, sources, electromechanical parts and integrated-circuit packaging. Fase 9 — component catalog expansion ------------------------------------ - 7 logic gates (AND/OR/NAND/NOR/XOR/XNOR + NOT) as SPICE B-sources - 8 multi-input gates (AND/OR/NAND/NOR with 3 and 4 inputs) - 9 transistors: 5 BJTs (incl. PNP 2N3906/BC557) + 4 MOSFETs (incl. P-channel IRF9540/FQP27P06). NMOS refactored from Level=3 W=0.1 (hangs ngspice) to Level=1 with sane W/L - 5 op-amps: LM358, LM741, TL072, LM324 with per-chip saturation rails + opamp-ideal - 4 linear regulators (7805, 7812, 7905, LM317) with dropout - 3 batteries (9V, AA, coin-cell) with realistic ESR - Signal generator (sine / square / DC) - 2 Schottky diodes (1N5817, 1N5819) + photodiode (lux-driven current source) Fase 10 — electromechanical + ICs --------------------------------- - Relay (SPDT): coil + L + S-switch with native hysteresis + flyback diode, inverted-control trick for the NC contact - Optocouplers 4N25 and PC817 (LED + CCCS with CTR=0.5 / 1.0) - 7 74HC ICs as DIP-14 packages emitting 4 or 6 B-sources per component (first mapper pattern emitting multiple device cards) - 3 flip-flops (D, T, JK) — digital-sim only (edge detection is not representable in ngspice .op) - L293D dual H-bridge motor driver Infrastructure -------------- - scripts/component-overrides.json gains a _customComponents[] array that lets new Velxio-only parts survive metadata regeneration (previously applyOverrides() could only patch wokwi-elements components that had already been scanned) - scripts/generate-component-metadata.ts injects custom entries before the patch loop - New ComponentCategory values: 'logic', 'analog', 'electromech' - frontend/src/components/DynamicComponent.tsx PASSIVE tracing extended from just ['resistor','resistor-us'] to 9 two-terminal passives with per-part pin name maps - New CI workflow test-circuit.yml runs the sandbox on push/PR - frontend-tests.yml regenerates metadata and fails if committed JSON is stale - Documented 2 new ngspice gotchas in circuit-emulation-gotchas.md: unicode in netlist titles silently hangs the parser, and MOSFET Level=3 + W=0.1m causes .op to hang - 164/164 sandbox tests passing in ~9 s (was 88 pre-fase-9) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-16 06:44:18 +07:00
emit(); // Drive initial Q / Qbar
feat(sim): Phase 5 — migrate every logic-gate handler to PinResolver twoInputGate (AND/NAND/OR/NOR/XOR/XNOR), nInputGate (3/4-input AND/OR/ NAND/NOR), edgeTriggeredFF (D/T/JK), and the standalone NOT gate all now prefer PinResolver input subscriptions. Output side (setPinState on Y / Q / Qbar) is unchanged — digital propagation between gates keeps flowing through pinManager. Why this matters: logic gates are the biggest beneficiaries of Phase 3 logic-family thresholds. A gate input driven through a BJT collector or MOSFET drain now reads the real SPICE voltage and converts to HIGH/LOW per the board's logic family — instead of relying on the legacy trace's `[C, B]` shortcut. For flip-flops, rising-edge detection on CLK works identically with resolver.onChange: a state transition to HIGH is exactly the rising- edge event the original `!prevClk && s` was watching for. All migrated handlers fall back to the legacy pinManager.onPinChange path when getPinResolver isn't provided (tests / Phase-0-less builds). Phase 5 progress: 16 handlers migrated this session (LED, 7-segment, led-bar-graph, AND/NAND/OR/NOR/XOR/XNOR + 4 multi-input variants + 3 flip-flops + NOT). Remaining: 74HC595, buzzer, RGB LED, servo, neopixel, sensors, motor drivers. Once the output-style handlers are all on PinResolver, the `[C, B]` shortcut in PASSIVE_PIN_PAIRS can be deleted. 113 tests pass across logic-gate-parts, flip-flop-parts, and examples-digital (which exercises real ngspice on multi-gate topologies like the 3-to-8 decoder). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-15 23:19:00 +07:00
return () => unsubs.forEach((u) => u());
feat: expand SPICE component catalog (fases 9 + 10) Adds 44 SPICE mappers, 58 custom metadata entries, and 12 visual Web Components covering logic gates, transistors, op-amps, regulators, sources, electromechanical parts and integrated-circuit packaging. Fase 9 — component catalog expansion ------------------------------------ - 7 logic gates (AND/OR/NAND/NOR/XOR/XNOR + NOT) as SPICE B-sources - 8 multi-input gates (AND/OR/NAND/NOR with 3 and 4 inputs) - 9 transistors: 5 BJTs (incl. PNP 2N3906/BC557) + 4 MOSFETs (incl. P-channel IRF9540/FQP27P06). NMOS refactored from Level=3 W=0.1 (hangs ngspice) to Level=1 with sane W/L - 5 op-amps: LM358, LM741, TL072, LM324 with per-chip saturation rails + opamp-ideal - 4 linear regulators (7805, 7812, 7905, LM317) with dropout - 3 batteries (9V, AA, coin-cell) with realistic ESR - Signal generator (sine / square / DC) - 2 Schottky diodes (1N5817, 1N5819) + photodiode (lux-driven current source) Fase 10 — electromechanical + ICs --------------------------------- - Relay (SPDT): coil + L + S-switch with native hysteresis + flyback diode, inverted-control trick for the NC contact - Optocouplers 4N25 and PC817 (LED + CCCS with CTR=0.5 / 1.0) - 7 74HC ICs as DIP-14 packages emitting 4 or 6 B-sources per component (first mapper pattern emitting multiple device cards) - 3 flip-flops (D, T, JK) — digital-sim only (edge detection is not representable in ngspice .op) - L293D dual H-bridge motor driver Infrastructure -------------- - scripts/component-overrides.json gains a _customComponents[] array that lets new Velxio-only parts survive metadata regeneration (previously applyOverrides() could only patch wokwi-elements components that had already been scanned) - scripts/generate-component-metadata.ts injects custom entries before the patch loop - New ComponentCategory values: 'logic', 'analog', 'electromech' - frontend/src/components/DynamicComponent.tsx PASSIVE tracing extended from just ['resistor','resistor-us'] to 9 two-terminal passives with per-part pin name maps - New CI workflow test-circuit.yml runs the sandbox on push/PR - frontend-tests.yml regenerates metadata and fails if committed JSON is stale - Documented 2 new ngspice gotchas in circuit-emulation-gotchas.md: unicode in netlist titles silently hangs the parser, and MOSFET Level=3 + W=0.1m causes .op to hang - 164/164 sandbox tests passing in ~9 s (was 88 pre-fase-9) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-16 06:44:18 +07:00
},
};
}
// D flip-flop: Q ← D on rising CLK
PartSimulationRegistry.register(
'flip-flop-d',
edgeTriggeredFF(['D'], false, (_q, [d]) => d),
);
feat: expand SPICE component catalog (fases 9 + 10) Adds 44 SPICE mappers, 58 custom metadata entries, and 12 visual Web Components covering logic gates, transistors, op-amps, regulators, sources, electromechanical parts and integrated-circuit packaging. Fase 9 — component catalog expansion ------------------------------------ - 7 logic gates (AND/OR/NAND/NOR/XOR/XNOR + NOT) as SPICE B-sources - 8 multi-input gates (AND/OR/NAND/NOR with 3 and 4 inputs) - 9 transistors: 5 BJTs (incl. PNP 2N3906/BC557) + 4 MOSFETs (incl. P-channel IRF9540/FQP27P06). NMOS refactored from Level=3 W=0.1 (hangs ngspice) to Level=1 with sane W/L - 5 op-amps: LM358, LM741, TL072, LM324 with per-chip saturation rails + opamp-ideal - 4 linear regulators (7805, 7812, 7905, LM317) with dropout - 3 batteries (9V, AA, coin-cell) with realistic ESR - Signal generator (sine / square / DC) - 2 Schottky diodes (1N5817, 1N5819) + photodiode (lux-driven current source) Fase 10 — electromechanical + ICs --------------------------------- - Relay (SPDT): coil + L + S-switch with native hysteresis + flyback diode, inverted-control trick for the NC contact - Optocouplers 4N25 and PC817 (LED + CCCS with CTR=0.5 / 1.0) - 7 74HC ICs as DIP-14 packages emitting 4 or 6 B-sources per component (first mapper pattern emitting multiple device cards) - 3 flip-flops (D, T, JK) — digital-sim only (edge detection is not representable in ngspice .op) - L293D dual H-bridge motor driver Infrastructure -------------- - scripts/component-overrides.json gains a _customComponents[] array that lets new Velxio-only parts survive metadata regeneration (previously applyOverrides() could only patch wokwi-elements components that had already been scanned) - scripts/generate-component-metadata.ts injects custom entries before the patch loop - New ComponentCategory values: 'logic', 'analog', 'electromech' - frontend/src/components/DynamicComponent.tsx PASSIVE tracing extended from just ['resistor','resistor-us'] to 9 two-terminal passives with per-part pin name maps - New CI workflow test-circuit.yml runs the sandbox on push/PR - frontend-tests.yml regenerates metadata and fails if committed JSON is stale - Documented 2 new ngspice gotchas in circuit-emulation-gotchas.md: unicode in netlist titles silently hangs the parser, and MOSFET Level=3 + W=0.1m causes .op to hang - 164/164 sandbox tests passing in ~9 s (was 88 pre-fase-9) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-16 06:44:18 +07:00
// T flip-flop: Q ← Q ⊕ T on rising CLK (toggle when T=1)
PartSimulationRegistry.register(
'flip-flop-t',
edgeTriggeredFF(['T'], false, (q, [t]) => (t ? !q : q)),
);
feat: expand SPICE component catalog (fases 9 + 10) Adds 44 SPICE mappers, 58 custom metadata entries, and 12 visual Web Components covering logic gates, transistors, op-amps, regulators, sources, electromechanical parts and integrated-circuit packaging. Fase 9 — component catalog expansion ------------------------------------ - 7 logic gates (AND/OR/NAND/NOR/XOR/XNOR + NOT) as SPICE B-sources - 8 multi-input gates (AND/OR/NAND/NOR with 3 and 4 inputs) - 9 transistors: 5 BJTs (incl. PNP 2N3906/BC557) + 4 MOSFETs (incl. P-channel IRF9540/FQP27P06). NMOS refactored from Level=3 W=0.1 (hangs ngspice) to Level=1 with sane W/L - 5 op-amps: LM358, LM741, TL072, LM324 with per-chip saturation rails + opamp-ideal - 4 linear regulators (7805, 7812, 7905, LM317) with dropout - 3 batteries (9V, AA, coin-cell) with realistic ESR - Signal generator (sine / square / DC) - 2 Schottky diodes (1N5817, 1N5819) + photodiode (lux-driven current source) Fase 10 — electromechanical + ICs --------------------------------- - Relay (SPDT): coil + L + S-switch with native hysteresis + flyback diode, inverted-control trick for the NC contact - Optocouplers 4N25 and PC817 (LED + CCCS with CTR=0.5 / 1.0) - 7 74HC ICs as DIP-14 packages emitting 4 or 6 B-sources per component (first mapper pattern emitting multiple device cards) - 3 flip-flops (D, T, JK) — digital-sim only (edge detection is not representable in ngspice .op) - L293D dual H-bridge motor driver Infrastructure -------------- - scripts/component-overrides.json gains a _customComponents[] array that lets new Velxio-only parts survive metadata regeneration (previously applyOverrides() could only patch wokwi-elements components that had already been scanned) - scripts/generate-component-metadata.ts injects custom entries before the patch loop - New ComponentCategory values: 'logic', 'analog', 'electromech' - frontend/src/components/DynamicComponent.tsx PASSIVE tracing extended from just ['resistor','resistor-us'] to 9 two-terminal passives with per-part pin name maps - New CI workflow test-circuit.yml runs the sandbox on push/PR - frontend-tests.yml regenerates metadata and fails if committed JSON is stale - Documented 2 new ngspice gotchas in circuit-emulation-gotchas.md: unicode in netlist titles silently hangs the parser, and MOSFET Level=3 + W=0.1m causes .op to hang - 164/164 sandbox tests passing in ~9 s (was 88 pre-fase-9) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-16 06:44:18 +07:00
// JK flip-flop:
// J=0, K=0 → hold
// J=1, K=0 → set (Q=1)
// J=0, K=1 → reset (Q=0)
// J=1, K=1 → toggle
PartSimulationRegistry.register(
'flip-flop-jk',
feat: expand SPICE component catalog (fases 9 + 10) Adds 44 SPICE mappers, 58 custom metadata entries, and 12 visual Web Components covering logic gates, transistors, op-amps, regulators, sources, electromechanical parts and integrated-circuit packaging. Fase 9 — component catalog expansion ------------------------------------ - 7 logic gates (AND/OR/NAND/NOR/XOR/XNOR + NOT) as SPICE B-sources - 8 multi-input gates (AND/OR/NAND/NOR with 3 and 4 inputs) - 9 transistors: 5 BJTs (incl. PNP 2N3906/BC557) + 4 MOSFETs (incl. P-channel IRF9540/FQP27P06). NMOS refactored from Level=3 W=0.1 (hangs ngspice) to Level=1 with sane W/L - 5 op-amps: LM358, LM741, TL072, LM324 with per-chip saturation rails + opamp-ideal - 4 linear regulators (7805, 7812, 7905, LM317) with dropout - 3 batteries (9V, AA, coin-cell) with realistic ESR - Signal generator (sine / square / DC) - 2 Schottky diodes (1N5817, 1N5819) + photodiode (lux-driven current source) Fase 10 — electromechanical + ICs --------------------------------- - Relay (SPDT): coil + L + S-switch with native hysteresis + flyback diode, inverted-control trick for the NC contact - Optocouplers 4N25 and PC817 (LED + CCCS with CTR=0.5 / 1.0) - 7 74HC ICs as DIP-14 packages emitting 4 or 6 B-sources per component (first mapper pattern emitting multiple device cards) - 3 flip-flops (D, T, JK) — digital-sim only (edge detection is not representable in ngspice .op) - L293D dual H-bridge motor driver Infrastructure -------------- - scripts/component-overrides.json gains a _customComponents[] array that lets new Velxio-only parts survive metadata regeneration (previously applyOverrides() could only patch wokwi-elements components that had already been scanned) - scripts/generate-component-metadata.ts injects custom entries before the patch loop - New ComponentCategory values: 'logic', 'analog', 'electromech' - frontend/src/components/DynamicComponent.tsx PASSIVE tracing extended from just ['resistor','resistor-us'] to 9 two-terminal passives with per-part pin name maps - New CI workflow test-circuit.yml runs the sandbox on push/PR - frontend-tests.yml regenerates metadata and fails if committed JSON is stale - Documented 2 new ngspice gotchas in circuit-emulation-gotchas.md: unicode in netlist titles silently hangs the parser, and MOSFET Level=3 + W=0.1m causes .op to hang - 164/164 sandbox tests passing in ~9 s (was 88 pre-fase-9) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-16 06:44:18 +07:00
edgeTriggeredFF(['J', 'K'], false, (q, [j, k]) => {
if (j && k) return !q;
if (j) return true;
if (k) return false;
return q;
}),
);
PartSimulationRegistry.register('logic-gate-and-3', nInputGate(['A', 'B', 'C'], allTrue));
PartSimulationRegistry.register('logic-gate-or-3', nInputGate(['A', 'B', 'C'], anyTrue));
PartSimulationRegistry.register('logic-gate-nand-3', nInputGate(['A', 'B', 'C'], notAll));
PartSimulationRegistry.register('logic-gate-nor-3', nInputGate(['A', 'B', 'C'], notAny));
PartSimulationRegistry.register('logic-gate-and-4', nInputGate(['A', 'B', 'C', 'D'], allTrue));
PartSimulationRegistry.register('logic-gate-or-4', nInputGate(['A', 'B', 'C', 'D'], anyTrue));
feat: expand SPICE component catalog (fases 9 + 10) Adds 44 SPICE mappers, 58 custom metadata entries, and 12 visual Web Components covering logic gates, transistors, op-amps, regulators, sources, electromechanical parts and integrated-circuit packaging. Fase 9 — component catalog expansion ------------------------------------ - 7 logic gates (AND/OR/NAND/NOR/XOR/XNOR + NOT) as SPICE B-sources - 8 multi-input gates (AND/OR/NAND/NOR with 3 and 4 inputs) - 9 transistors: 5 BJTs (incl. PNP 2N3906/BC557) + 4 MOSFETs (incl. P-channel IRF9540/FQP27P06). NMOS refactored from Level=3 W=0.1 (hangs ngspice) to Level=1 with sane W/L - 5 op-amps: LM358, LM741, TL072, LM324 with per-chip saturation rails + opamp-ideal - 4 linear regulators (7805, 7812, 7905, LM317) with dropout - 3 batteries (9V, AA, coin-cell) with realistic ESR - Signal generator (sine / square / DC) - 2 Schottky diodes (1N5817, 1N5819) + photodiode (lux-driven current source) Fase 10 — electromechanical + ICs --------------------------------- - Relay (SPDT): coil + L + S-switch with native hysteresis + flyback diode, inverted-control trick for the NC contact - Optocouplers 4N25 and PC817 (LED + CCCS with CTR=0.5 / 1.0) - 7 74HC ICs as DIP-14 packages emitting 4 or 6 B-sources per component (first mapper pattern emitting multiple device cards) - 3 flip-flops (D, T, JK) — digital-sim only (edge detection is not representable in ngspice .op) - L293D dual H-bridge motor driver Infrastructure -------------- - scripts/component-overrides.json gains a _customComponents[] array that lets new Velxio-only parts survive metadata regeneration (previously applyOverrides() could only patch wokwi-elements components that had already been scanned) - scripts/generate-component-metadata.ts injects custom entries before the patch loop - New ComponentCategory values: 'logic', 'analog', 'electromech' - frontend/src/components/DynamicComponent.tsx PASSIVE tracing extended from just ['resistor','resistor-us'] to 9 two-terminal passives with per-part pin name maps - New CI workflow test-circuit.yml runs the sandbox on push/PR - frontend-tests.yml regenerates metadata and fails if committed JSON is stale - Documented 2 new ngspice gotchas in circuit-emulation-gotchas.md: unicode in netlist titles silently hangs the parser, and MOSFET Level=3 + W=0.1m causes .op to hang - 164/164 sandbox tests passing in ~9 s (was 88 pre-fase-9) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-16 06:44:18 +07:00
PartSimulationRegistry.register('logic-gate-nand-4', nInputGate(['A', 'B', 'C', 'D'], notAll));
PartSimulationRegistry.register('logic-gate-nor-4', nInputGate(['A', 'B', 'C', 'D'], notAny));
feat: expand SPICE component catalog (fases 9 + 10) Adds 44 SPICE mappers, 58 custom metadata entries, and 12 visual Web Components covering logic gates, transistors, op-amps, regulators, sources, electromechanical parts and integrated-circuit packaging. Fase 9 — component catalog expansion ------------------------------------ - 7 logic gates (AND/OR/NAND/NOR/XOR/XNOR + NOT) as SPICE B-sources - 8 multi-input gates (AND/OR/NAND/NOR with 3 and 4 inputs) - 9 transistors: 5 BJTs (incl. PNP 2N3906/BC557) + 4 MOSFETs (incl. P-channel IRF9540/FQP27P06). NMOS refactored from Level=3 W=0.1 (hangs ngspice) to Level=1 with sane W/L - 5 op-amps: LM358, LM741, TL072, LM324 with per-chip saturation rails + opamp-ideal - 4 linear regulators (7805, 7812, 7905, LM317) with dropout - 3 batteries (9V, AA, coin-cell) with realistic ESR - Signal generator (sine / square / DC) - 2 Schottky diodes (1N5817, 1N5819) + photodiode (lux-driven current source) Fase 10 — electromechanical + ICs --------------------------------- - Relay (SPDT): coil + L + S-switch with native hysteresis + flyback diode, inverted-control trick for the NC contact - Optocouplers 4N25 and PC817 (LED + CCCS with CTR=0.5 / 1.0) - 7 74HC ICs as DIP-14 packages emitting 4 or 6 B-sources per component (first mapper pattern emitting multiple device cards) - 3 flip-flops (D, T, JK) — digital-sim only (edge detection is not representable in ngspice .op) - L293D dual H-bridge motor driver Infrastructure -------------- - scripts/component-overrides.json gains a _customComponents[] array that lets new Velxio-only parts survive metadata regeneration (previously applyOverrides() could only patch wokwi-elements components that had already been scanned) - scripts/generate-component-metadata.ts injects custom entries before the patch loop - New ComponentCategory values: 'logic', 'analog', 'electromech' - frontend/src/components/DynamicComponent.tsx PASSIVE tracing extended from just ['resistor','resistor-us'] to 9 two-terminal passives with per-part pin name maps - New CI workflow test-circuit.yml runs the sandbox on push/PR - frontend-tests.yml regenerates metadata and fails if committed JSON is stale - Documented 2 new ngspice gotchas in circuit-emulation-gotchas.md: unicode in netlist titles silently hangs the parser, and MOSFET Level=3 + W=0.1m causes .op to hang - 164/164 sandbox tests passing in ~9 s (was 88 pre-fase-9) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-16 06:44:18 +07:00
// ─── NOT (inverter) ───────────────────────────────────────────────────────────
PartSimulationRegistry.register('logic-gate-not', {
feat(sim): Phase 5 — migrate every logic-gate handler to PinResolver twoInputGate (AND/NAND/OR/NOR/XOR/XNOR), nInputGate (3/4-input AND/OR/ NAND/NOR), edgeTriggeredFF (D/T/JK), and the standalone NOT gate all now prefer PinResolver input subscriptions. Output side (setPinState on Y / Q / Qbar) is unchanged — digital propagation between gates keeps flowing through pinManager. Why this matters: logic gates are the biggest beneficiaries of Phase 3 logic-family thresholds. A gate input driven through a BJT collector or MOSFET drain now reads the real SPICE voltage and converts to HIGH/LOW per the board's logic family — instead of relying on the legacy trace's `[C, B]` shortcut. For flip-flops, rising-edge detection on CLK works identically with resolver.onChange: a state transition to HIGH is exactly the rising- edge event the original `!prevClk && s` was watching for. All migrated handlers fall back to the legacy pinManager.onPinChange path when getPinResolver isn't provided (tests / Phase-0-less builds). Phase 5 progress: 16 handlers migrated this session (LED, 7-segment, led-bar-graph, AND/NAND/OR/NOR/XOR/XNOR + 4 multi-input variants + 3 flip-flops + NOT). Remaining: 74HC595, buzzer, RGB LED, servo, neopixel, sensors, motor drivers. Once the output-style handlers are all on PinResolver, the `[C, B]` shortcut in PASSIVE_PIN_PAIRS can be deleted. 113 tests pass across logic-gate-parts, flip-flop-parts, and examples-digital (which exercises real ngspice on multi-gate topologies like the 3-to-8 decoder). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-15 23:19:00 +07:00
attachEvents: (element, simulator, getPin, _componentId, getPinResolver) => {
const pinY = getPin('Y');
feat(sim): Phase 5 — migrate every logic-gate handler to PinResolver twoInputGate (AND/NAND/OR/NOR/XOR/XNOR), nInputGate (3/4-input AND/OR/ NAND/NOR), edgeTriggeredFF (D/T/JK), and the standalone NOT gate all now prefer PinResolver input subscriptions. Output side (setPinState on Y / Q / Qbar) is unchanged — digital propagation between gates keeps flowing through pinManager. Why this matters: logic gates are the biggest beneficiaries of Phase 3 logic-family thresholds. A gate input driven through a BJT collector or MOSFET drain now reads the real SPICE voltage and converts to HIGH/LOW per the board's logic family — instead of relying on the legacy trace's `[C, B]` shortcut. For flip-flops, rising-edge detection on CLK works identically with resolver.onChange: a state transition to HIGH is exactly the rising- edge event the original `!prevClk && s` was watching for. All migrated handlers fall back to the legacy pinManager.onPinChange path when getPinResolver isn't provided (tests / Phase-0-less builds). Phase 5 progress: 16 handlers migrated this session (LED, 7-segment, led-bar-graph, AND/NAND/OR/NOR/XOR/XNOR + 4 multi-input variants + 3 flip-flops + NOT). Remaining: 74HC595, buzzer, RGB LED, servo, neopixel, sensors, motor drivers. Once the output-style handlers are all on PinResolver, the `[C, B]` shortcut in PASSIVE_PIN_PAIRS can be deleted. 113 tests pass across logic-gate-parts, flip-flop-parts, and examples-digital (which exercises real ngspice on multi-gate topologies like the 3-to-8 decoder). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-15 23:19:00 +07:00
if (pinY === null) return () => {};
if (typeof getPinResolver === 'function') {
const resA = getPinResolver('A');
if (!resA) return () => {};
simulator.setPinState(pinY, resA.getCurrentState() !== 'HIGH');
return resA.onChange((state) => {
simulator.setPinState(pinY, state !== 'HIGH');
});
}
feat(sim): Phase 5 — migrate every logic-gate handler to PinResolver twoInputGate (AND/NAND/OR/NOR/XOR/XNOR), nInputGate (3/4-input AND/OR/ NAND/NOR), edgeTriggeredFF (D/T/JK), and the standalone NOT gate all now prefer PinResolver input subscriptions. Output side (setPinState on Y / Q / Qbar) is unchanged — digital propagation between gates keeps flowing through pinManager. Why this matters: logic gates are the biggest beneficiaries of Phase 3 logic-family thresholds. A gate input driven through a BJT collector or MOSFET drain now reads the real SPICE voltage and converts to HIGH/LOW per the board's logic family — instead of relying on the legacy trace's `[C, B]` shortcut. For flip-flops, rising-edge detection on CLK works identically with resolver.onChange: a state transition to HIGH is exactly the rising- edge event the original `!prevClk && s` was watching for. All migrated handlers fall back to the legacy pinManager.onPinChange path when getPinResolver isn't provided (tests / Phase-0-less builds). Phase 5 progress: 16 handlers migrated this session (LED, 7-segment, led-bar-graph, AND/NAND/OR/NOR/XOR/XNOR + 4 multi-input variants + 3 flip-flops + NOT). Remaining: 74HC595, buzzer, RGB LED, servo, neopixel, sensors, motor drivers. Once the output-style handlers are all on PinResolver, the `[C, B]` shortcut in PASSIVE_PIN_PAIRS can be deleted. 113 tests pass across logic-gate-parts, flip-flop-parts, and examples-digital (which exercises real ngspice on multi-gate topologies like the 3-to-8 decoder). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-15 23:19:00 +07:00
const pinA = getPin('A');
if (pinA === null) return () => {};
const unsub = simulator.pinManager.onPinChange(pinA, (_: number, s: boolean) => {
simulator.setPinState(pinY, !s);
});
simulator.setPinState(pinY, true); // NOT LOW = HIGH (initial LOW input → HIGH output)
return unsub;
},
});