simple-circuit-engine 0.0.12 → 0.0.14

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.
Files changed (99) hide show
  1. package/AGENTS.md +9 -6
  2. package/CLAUDE.md +2 -0
  3. package/README.md +8 -8
  4. package/dist/core/index.js +109 -74
  5. package/dist/core/setup.d.ts +18 -0
  6. package/dist/core/simulation/behaviors/arithmetic/AdderBehavior.d.ts +28 -0
  7. package/dist/core/simulation/behaviors/arithmetic/ArithmeticBehaviorMixin.d.ts +63 -0
  8. package/dist/core/simulation/behaviors/arithmetic/EightBitAdderBehavior.d.ts +51 -0
  9. package/dist/core/simulation/behaviors/arithmetic/EightBitOnesComplementBehavior.d.ts +29 -0
  10. package/dist/core/simulation/behaviors/arithmetic/HalfAdderBehavior.d.ts +22 -0
  11. package/dist/core/simulation/behaviors/arithmetic/index.d.ts +7 -0
  12. package/dist/core/simulation/behaviors/index.d.ts +14 -0
  13. package/dist/core/simulation/behaviors/interface/EightInputBehavior.d.ts +9 -0
  14. package/dist/core/simulation/behaviors/interface/EightLightBehavior.d.ts +9 -0
  15. package/dist/core/simulation/behaviors/interface/FourInputBehavior.d.ts +9 -0
  16. package/dist/core/simulation/behaviors/interface/FourLightBehavior.d.ts +9 -0
  17. package/dist/core/simulation/behaviors/interface/InputBehaviorMixin.d.ts +37 -0
  18. package/dist/core/simulation/behaviors/interface/LightBehaviorMixin.d.ts +60 -0
  19. package/dist/core/simulation/behaviors/interface/OneInputBehavior.d.ts +9 -0
  20. package/dist/core/simulation/behaviors/interface/OneLightBehavior.d.ts +9 -0
  21. package/dist/core/simulation/behaviors/interface/TwoInputBehavior.d.ts +9 -0
  22. package/dist/core/simulation/behaviors/interface/TwoLightBehavior.d.ts +9 -0
  23. package/dist/core/simulation/behaviors/interface/index.d.ts +0 -0
  24. package/dist/core/simulation/states/arithmetic/AdderState.d.ts +16 -0
  25. package/dist/core/simulation/states/arithmetic/ArithmeticState.d.ts +53 -0
  26. package/dist/core/simulation/states/arithmetic/EightBitAdderState.d.ts +25 -0
  27. package/dist/core/simulation/states/arithmetic/EightBitOnesComplementState.d.ts +18 -0
  28. package/dist/core/simulation/states/arithmetic/HalfAdderState.d.ts +16 -0
  29. package/dist/core/simulation/states/arithmetic/index.d.ts +7 -0
  30. package/dist/core/simulation/states/index.d.ts +15 -0
  31. package/dist/core/simulation/states/interface/EightInputState.d.ts +6 -0
  32. package/dist/core/simulation/states/interface/EightLightState.d.ts +6 -0
  33. package/dist/core/simulation/states/interface/FourInputState.d.ts +6 -0
  34. package/dist/core/simulation/states/interface/FourLightState.d.ts +6 -0
  35. package/dist/core/simulation/states/interface/InputState.d.ts +45 -0
  36. package/dist/core/simulation/states/interface/LightState.d.ts +54 -0
  37. package/dist/core/simulation/states/interface/OneInputState.d.ts +6 -0
  38. package/dist/core/simulation/states/interface/OneLightState.d.ts +6 -0
  39. package/dist/core/simulation/states/interface/TwoInputState.d.ts +6 -0
  40. package/dist/core/simulation/states/interface/TwoLightState.d.ts +6 -0
  41. package/dist/core/simulation/types.d.ts +10 -2
  42. package/dist/core/topology/Component.d.ts +6 -1
  43. package/dist/core/topology/ENode.d.ts +7 -2
  44. package/dist/core/topology/index.d.ts +2 -0
  45. package/dist/core/topology/networkTraversal.d.ts +50 -0
  46. package/dist/core/topology/types.d.ts +31 -6
  47. package/dist/core-HH6iRWtB.js +4671 -0
  48. package/dist/core-HH6iRWtB.js.map +1 -0
  49. package/dist/i18n/index.d.ts +1158 -0
  50. package/dist/i18n/locales/en.json.d.ts +366 -0
  51. package/dist/i18n/locales/fr.json.d.ts +366 -0
  52. package/dist/index.d.ts +1 -0
  53. package/dist/index.js +172 -118
  54. package/dist/scene/CircuitEngine.d.ts +49 -4
  55. package/dist/scene/index.d.ts +6 -2
  56. package/dist/scene/index.js +62 -45
  57. package/dist/scene/setup.d.ts +18 -0
  58. package/dist/scene/shared/AbstractCircuitController.d.ts +11 -3
  59. package/dist/scene/shared/HoverManager.d.ts +15 -0
  60. package/dist/scene/shared/components/arithmetic/AdderVisualFactory.d.ts +54 -0
  61. package/dist/scene/shared/components/arithmetic/EightBitAdderVisualFactory.d.ts +45 -0
  62. package/dist/scene/shared/components/arithmetic/EightBitOnesComplementVisualFactory.d.ts +63 -0
  63. package/dist/scene/shared/components/arithmetic/HalfAdderVisualFactory.d.ts +55 -0
  64. package/dist/scene/shared/components/arithmetic/index.d.ts +4 -0
  65. package/dist/scene/shared/components/index.d.ts +14 -0
  66. package/dist/scene/shared/components/interface/EightInputVisualFactory.d.ts +15 -0
  67. package/dist/scene/shared/components/interface/EightLightVisualFactory.d.ts +15 -0
  68. package/dist/scene/shared/components/interface/FourInputVisualFactory.d.ts +15 -0
  69. package/dist/scene/shared/components/interface/FourLightVisualFactory.d.ts +15 -0
  70. package/dist/scene/shared/components/interface/InputVisualFactoryBase.d.ts +50 -0
  71. package/dist/scene/shared/components/interface/LightVisualFactoryBase.d.ts +46 -0
  72. package/dist/scene/shared/components/interface/OneInputVisualFactory.d.ts +15 -0
  73. package/dist/scene/shared/components/interface/OneLightVisualFactory.d.ts +15 -0
  74. package/dist/scene/shared/components/interface/TwoInputVisualFactory.d.ts +15 -0
  75. package/dist/scene/shared/components/interface/TwoLightVisualFactory.d.ts +15 -0
  76. package/dist/scene/shared/types.d.ts +34 -4
  77. package/dist/scene/shared/utils/ControlsUtils.d.ts +1 -1
  78. package/dist/scene/shared/utils/GeometryUtils.d.ts +111 -0
  79. package/dist/scene/static/CircuitController.d.ts +13 -1
  80. package/dist/scene/static/tools/BuildTool.d.ts +81 -0
  81. package/dist/scene/static/tools/ComponentPickerWidget.d.ts +7 -0
  82. package/dist/scene/static/tools/ConfigPanelWidget.d.ts +14 -0
  83. package/dist/scene/static/tools/MultiWiringPlacement.d.ts +40 -0
  84. package/dist/scene/widgets/HelpWidget.d.ts +13 -0
  85. package/dist/scene/widgets/ModeWidget.d.ts +16 -0
  86. package/dist/scene/widgets/MultiWiringWidget.d.ts +21 -0
  87. package/dist/scene/{static → widgets}/PinTooltipWidget.d.ts +7 -1
  88. package/dist/scene/widgets/SimulationPlayerWidget.d.ts +62 -0
  89. package/dist/scene/widgets/ToolsWidget.d.ts +18 -0
  90. package/dist/scene/widgets/WidgetsManager.d.ts +65 -0
  91. package/dist/scene/widgets/assets/icons.d.ts +20 -0
  92. package/dist/scene/widgets/index.d.ts +9 -0
  93. package/dist/scene/widgets/styles.d.ts +33 -0
  94. package/dist/{scene-CVsDdySt.js → scene-C1xhdw_B.js} +3993 -772
  95. package/dist/scene-C1xhdw_B.js.map +1 -0
  96. package/package.json +14 -9
  97. package/dist/core-Bjta9Y7_.js +0 -2707
  98. package/dist/core-Bjta9Y7_.js.map +0 -1
  99. package/dist/scene-CVsDdySt.js.map +0 -1
@@ -25,8 +25,10 @@ import * as THREE from 'three';
25
25
  *
26
26
  * @example
27
27
  * ```typescript
28
+ * const renderer = new THREE.WebGLRenderer({ antialias: true });
28
29
  * const engine = new CircuitEngine(factoryRegistry, behaviorRegistry);
29
- * engine.initialize(container);
30
+ * engine.initialize(container, renderer);
31
+ * container.appendChild(renderer.domElement);
30
32
  * engine.setCircuit(circuit);
31
33
  *
32
34
  * // Edit mode (default)
@@ -49,11 +51,13 @@ export declare class CircuitEngine extends EventEmitter<CircuitEngineEventMap> {
49
51
  private _editController;
50
52
  private _simulationController;
51
53
  private _mode;
54
+ private _multiWiring;
52
55
  private _initialized;
53
56
  private _options;
54
57
  private _disposed;
55
58
  private _editControllerCleanup;
56
59
  private _simulationControllerCleanup;
60
+ private _widgetsManager;
57
61
  /**
58
62
  * Create a new CircuitEngine instance.
59
63
  *
@@ -71,15 +75,20 @@ export declare class CircuitEngine extends EventEmitter<CircuitEngineEventMap> {
71
75
  */
72
76
  get isDisposed(): boolean;
73
77
  /**
74
- * Initialize the engine with a DOM container.
78
+ * Initialize the engine with a DOM container and a WebGLRenderer.
75
79
  * Creates shared Three.js resources and both controllers.
76
80
  *
77
- * @param container - HTMLElement to mount the scene
81
+ * The caller owns the renderer and its canvas; the engine binds MapControls
82
+ * to `renderer.domElement` (not the container) so DOM overlays such as the
83
+ * integrated widgets can receive pointer events normally.
84
+ *
85
+ * @param container - HTMLElement to mount the scene (used for bounds, mouse tracking, widget overlay)
86
+ * @param renderer - WebGLRenderer owned by the consumer. Its canvas (`renderer.domElement`) is used for pointer input.
78
87
  * @param options - Configuration options
79
88
  * @throws {TypeError} If container is not a valid HTMLElement
80
89
  * @throws {Error} If already initialized
81
90
  */
82
- initialize(container: HTMLElement, options?: EngineOptions): void;
91
+ initialize(container: HTMLElement, renderer: THREE.WebGLRenderer, options?: EngineOptions): void;
83
92
  /**
84
93
  * Create shared resources for both controllers.
85
94
  */
@@ -102,6 +111,19 @@ export declare class CircuitEngine extends EventEmitter<CircuitEngineEventMap> {
102
111
  * Current operating mode
103
112
  */
104
113
  get mode(): EngineMode;
114
+ /**
115
+ * Refresh all scene widgets to display strings in the given language.
116
+ *
117
+ * Does NOT change the consumer's i18next instance — the caller must have
118
+ * already called `i18next.changeLanguage(lng)` before invoking this. This
119
+ * method only signals the scene to re-read translations for currently-open
120
+ * widgets (pin tooltip, component picker, config panel).
121
+ *
122
+ * Safe to call at any point in the engine lifecycle after `initialize()`.
123
+ *
124
+ * @param lng - Target language code (e.g., 'en', 'fr')
125
+ */
126
+ setLanguage(lng: string): void;
105
127
  /**
106
128
  * Switch between edit and simulation modes.
107
129
  *
@@ -161,6 +183,17 @@ export declare class CircuitEngine extends EventEmitter<CircuitEngineEventMap> {
161
183
  * @throws {Error} If not in edit mode
162
184
  */
163
185
  setEditModeEnabled(enabled: boolean): void;
186
+ /**
187
+ * Whether the multi-wiring flag is currently enabled.
188
+ * Wiring tools may use it to create several wires per pull (semantics handled
189
+ * by the tools; the engine only owns the flag and forwards changes).
190
+ */
191
+ get multiWiring(): boolean;
192
+ /**
193
+ * Toggle the multi-wiring flag and forward to the edit controller.
194
+ * Emits `multiWiringChanged` once on transition.
195
+ */
196
+ setMultiWiring(value: boolean): void;
164
197
  /**
165
198
  * Start automatic simulation playback.
166
199
  *
@@ -185,6 +218,18 @@ export declare class CircuitEngine extends EventEmitter<CircuitEngineEventMap> {
185
218
  * @throws {Error} If not in simulation mode
186
219
  */
187
220
  stop(): void;
221
+ /**
222
+ * Request help for the current mode. Emits `helpRequested` with the active
223
+ * mode as payload; consumers decide how to render help (modal, sidebar, etc.).
224
+ *
225
+ * @example
226
+ * ```typescript
227
+ * engine.on('helpRequested', ({ mode }) => {
228
+ * openHelpDialog(mode);
229
+ * });
230
+ * ```
231
+ */
232
+ requestHelp(): void;
188
233
  /**
189
234
  * Check if simulation is currently playing
190
235
  */
@@ -11,9 +11,11 @@
11
11
  * ```typescript
12
12
  * import { CircuitController, FactoryRegistry } from 'simple-circuit-controller/scene';
13
13
  *
14
+ * const renderer = new THREE.WebGLRenderer({ antialias: true });
14
15
  * const registry = new FactoryRegistry(defaultFactory);
15
16
  * const controller = new CircuitController(registry);
16
- * controller.initialize(container);
17
+ * controller.initialize(container, renderer);
18
+ * container.appendChild(renderer.domElement);
17
19
  * controller.setCircuit(circuit);
18
20
  * ```
19
21
  */
@@ -21,6 +23,8 @@ export { CircuitEngine } from './CircuitEngine';
21
23
  export { CircuitController } from './static/CircuitController';
22
24
  export { CircuitRunnerController } from './simulation/CircuitRunnerController';
23
25
  export type { AbstractCircuitController } from './shared/AbstractCircuitController';
26
+ export { WidgetsManager } from './widgets';
27
+ export type { IEngineForWidgets } from './widgets';
24
28
  export { BuildTool } from './static/tools/BuildTool';
25
29
  export { MultiSelectTool } from './static/tools/MultiSelectTool';
26
30
  export { ComponentPickerWidget, BRANCHING_POINT_SENTINEL, } from './static/tools/ComponentPickerWidget';
@@ -40,4 +44,4 @@ export * from './shared/types';
40
44
  export { HitboxLayers } from './shared/utils/LayerConstants';
41
45
  export type { HitboxLayerValue } from './shared/utils/LayerConstants';
42
46
  export * from './shared/utils/Options';
43
- export { registerBasicComponentsFactories, registerGatesComponentsFactories } from './setup';
47
+ export { registerBasicComponentsFactories, registerGatesComponentsFactories, registerArithmeticComponentsFactories, registerInterfaceComponentsFactories } from './setup';
@@ -1,47 +1,64 @@
1
- import { A as s, B as t, C as r, D as o, E as i, F as e, H as l, I as c, L as u, M as n, N as y, O as F, P as V, R as C, S as g, T as p, U as G, V as N, W as m, _ as M, a as L, b as R, c as S, d as T, f as d, g as E, h as b, i as h, j as B, k as I, l as D, m as O, n as P, o as w, p as A, r as H, s as W, t as _, u as f, v as k, w as v, x, y as X, z as j } from "../scene-CVsDdySt.js";
1
+ import { $ as t, A as s, B as r, C as i, D as o, E as e, F as l, G as c, H as u, I as n, J as y, K as F, L as V, M as g, N as p, O as C, P as h, Q as m, R as d, S as G, T as L, U as I, V as N, W as E, X as M, Y as B, Z as T, _ as A, a as O, at as R, b as S, c as b, d as w, et as f, f as D, g as H, h as P, i as W, it as X, j as _, k, l as v, m as x, n as j, nt as q, o as z, ot as J, p as K, q as Q, r as U, rt as Y, s as Z, st as $, t as aa, tt as ta, u as sa, v as ra, w as ia, x as oa, y as ea, z as la } from "../scene-C1xhdw_B.js";
2
2
  export {
3
- G as BRANCHING_POINT_SENTINEL,
4
- x as BatteryVisualFactory,
5
- c as BranchingPointVisualFactory,
6
- l as BuildTool,
7
- p as CMP_MATERIALS,
8
- B as CircuitController,
9
- I as CircuitEngine,
10
- s as CircuitRunnerController,
11
- j as CircuitWriter,
12
- A as ClockVisualFactory,
13
- i as CmpMatCategory,
14
- o as CmpMatType,
15
- F as CmpMatVariant,
16
- m as ComponentPickerWidget,
17
- r as DefaultVisualFactory,
18
- O as DoubleThrowSwitchVisualFactory,
19
- v as FactoryRegistry,
20
- g as GroupedFactoryRegistry,
21
- C as HitboxLayers,
22
- u as HoverManager,
23
- d as InverterVisualFactory,
24
- R as LabelVisualFactory,
25
- X as LightbulbVisualFactory,
26
- N as MultiSelectTool,
27
- f as Nand4GateVisualFactory,
28
- D as Nand8GateVisualFactory,
29
- T as NandGateVisualFactory,
30
- W as Nor4GateVisualFactory,
31
- w as Nor8GateVisualFactory,
32
- S as NorGateVisualFactory,
33
- k as RectangleLEDVisualFactory,
34
- M as RelayVisualFactory,
35
- t as SelectionManager,
36
- E as SmallLEDVisualFactory,
37
- b as SwitchVisualFactory,
38
- e as WireVisualManager,
39
- h as Xor4GateVisualFactory,
40
- H as Xor8GateVisualFactory,
41
- L as XorGateVisualFactory,
42
- n as controllerOptions,
43
- y as engineOptions,
44
- V as mapControlsOptions,
45
- _ as registerBasicComponentsFactories,
46
- P as registerGatesComponentsFactories
3
+ A as AdderVisualFactory,
4
+ J as BRANCHING_POINT_SENTINEL,
5
+ V as BatteryVisualFactory,
6
+ t as BranchingPointVisualFactory,
7
+ R as BuildTool,
8
+ N as CMP_MATERIALS,
9
+ y as CircuitController,
10
+ c as CircuitEngine,
11
+ Q as CircuitRunnerController,
12
+ q as CircuitWriter,
13
+ k as ClockVisualFactory,
14
+ u as CmpMatCategory,
15
+ I as CmpMatType,
16
+ E as CmpMatVariant,
17
+ $ as ComponentPickerWidget,
18
+ la as DefaultVisualFactory,
19
+ s as DoubleThrowSwitchVisualFactory,
20
+ H as EightBitAdderVisualFactory,
21
+ P as EightBitOnesComplementVisualFactory,
22
+ sa as EightInputVisualFactory,
23
+ O as EightLightVisualFactory,
24
+ r as FactoryRegistry,
25
+ w as FourInputVisualFactory,
26
+ z as FourLightVisualFactory,
27
+ d as GroupedFactoryRegistry,
28
+ ra as HalfAdderVisualFactory,
29
+ ta as HitboxLayers,
30
+ f as HoverManager,
31
+ x as InputVisualFactoryBase,
32
+ C as InverterVisualFactory,
33
+ n as LabelVisualFactory,
34
+ v as LightVisualFactoryBase,
35
+ l as LightbulbVisualFactory,
36
+ X as MultiSelectTool,
37
+ e as Nand4GateVisualFactory,
38
+ L as Nand8GateVisualFactory,
39
+ o as NandGateVisualFactory,
40
+ i as Nor4GateVisualFactory,
41
+ G as Nor8GateVisualFactory,
42
+ ia as NorGateVisualFactory,
43
+ K as OneInputVisualFactory,
44
+ b as OneLightVisualFactory,
45
+ h as RectangleLEDVisualFactory,
46
+ p as RelayVisualFactory,
47
+ Y as SelectionManager,
48
+ g as SmallLEDVisualFactory,
49
+ _ as SwitchVisualFactory,
50
+ D as TwoInputVisualFactory,
51
+ Z as TwoLightVisualFactory,
52
+ F as WidgetsManager,
53
+ m as WireVisualManager,
54
+ S as Xor4GateVisualFactory,
55
+ ea as Xor8GateVisualFactory,
56
+ oa as XorGateVisualFactory,
57
+ B as controllerOptions,
58
+ M as engineOptions,
59
+ T as mapControlsOptions,
60
+ aa as registerArithmeticComponentsFactories,
61
+ j as registerBasicComponentsFactories,
62
+ U as registerGatesComponentsFactories,
63
+ W as registerInterfaceComponentsFactories
47
64
  };
@@ -16,3 +16,21 @@ export declare function registerBasicComponentsFactories(registry: IGroupedFacto
16
16
  * @returns The input registry for chaining
17
17
  */
18
18
  export declare function registerGatesComponentsFactories(registry: IGroupedFactoryRegistry): IGroupedFactoryRegistry;
19
+ /**
20
+ * Register all arithmetic components visual factories in the arithmetic group
21
+ * Arithmetic components are : HalfAdder
22
+ * @public
23
+ * @param registry - A grouped factory registry to populate
24
+ * @returns The input registry for chaining
25
+ */
26
+ export declare function registerArithmeticComponentsFactories(registry: IGroupedFactoryRegistry): IGroupedFactoryRegistry;
27
+ /**
28
+ * Register all interface components visual factories in the interface group.
29
+ * Interface components are:
30
+ * - inputs: OneInput, TwoInput, FourInput, EightInput
31
+ * - lights: OneLight, TwoLight, FourLight, EightLight
32
+ * @public
33
+ * @param registry - A grouped factory registry to populate
34
+ * @returns The input registry for chaining
35
+ */
36
+ export declare function registerInterfaceComponentsFactories(registry: IGroupedFactoryRegistry): IGroupedFactoryRegistry;
@@ -32,6 +32,7 @@ import * as THREE from 'three';
32
32
  */
33
33
  export declare abstract class AbstractCircuitController extends EventEmitter<ControllerEventMap> {
34
34
  protected _container: HTMLElement | null;
35
+ protected _renderer: THREE.WebGLRenderer | null;
35
36
  protected _scene: THREE.Scene | null;
36
37
  protected _grid: THREE.GridHelper | null;
37
38
  protected _camera: THREE.PerspectiveCamera | null;
@@ -69,18 +70,19 @@ export declare abstract class AbstractCircuitController extends EventEmitter<Con
69
70
  protected get grid(): THREE.GridHelper | null;
70
71
  protected set grid(grid: THREE.GridHelper);
71
72
  /**
72
- * Initialize the controller with a DOM container.
73
+ * Initialize the controller with a DOM container and a WebGLRenderer.
73
74
  * Creates scene, camera, lights, MapControls, and HoverManager.
74
75
  *
75
76
  * When sharedResources were provided in constructor, uses those instead
76
77
  * of creating new resources. This enables the CircuitEngine facade pattern.
77
78
  *
78
- * @param container - HTMLElement to attach scene to
79
+ * @param container - HTMLElement to attach scene to (bounds, hover, mouse tracking)
80
+ * @param renderer - WebGLRenderer owned by the consumer; `renderer.domElement` is what MapControls binds to
79
81
  * @param options - Optional configuration
80
82
  * @throws {TypeError} If container is not a valid HTMLElement
81
83
  * @throws {Error} If already initialized
82
84
  */
83
- initialize(container: HTMLElement, options?: ControllerOptions): void;
85
+ initialize(container: HTMLElement, renderer: THREE.WebGLRenderer, options?: ControllerOptions): void;
84
86
  /**
85
87
  * Hook for subclasses to perform additional initialization.
86
88
  * Called after base initialization but before emitting 'ready'.
@@ -129,6 +131,12 @@ export declare abstract class AbstractCircuitController extends EventEmitter<Con
129
131
  * Get the current circuit being visualized
130
132
  */
131
133
  getCircuit(): Circuit | null;
134
+ /**
135
+ * Refresh any user-visible strings in owned widgets after the consumer has
136
+ * switched i18next to a new language. Default is a no-op for controllers
137
+ * that own no translated widgets.
138
+ */
139
+ setLanguage(_lng: string): void;
132
140
  protected abstract onSetCircuit(): void;
133
141
  /**
134
142
  * Loads a new circuit to visualize or null for clearing the scene
@@ -55,6 +55,21 @@ export declare class HoverManager {
55
55
  * @param normalizedY - Mouse Y in normalized HTML container coordinates [-1, 1]
56
56
  */
57
57
  updateFromMouse(normalizedX: number, normalizedY: number): void;
58
+ /**
59
+ * Raycast against the descendants of the given component object3D at the
60
+ * last known mouse position and return all `userData.part` strings that
61
+ * are currently hit.
62
+ *
63
+ * Useful when a click on a component hitbox needs to be refined to a
64
+ * specific sub-part (e.g. one switch among many in a multi-input
65
+ * component). Unlike priority hover detection this method ignores hitbox
66
+ * layers and walks the full sub-tree.
67
+ *
68
+ * @param componentObject3D - Root object of the component to introspect
69
+ * @returns De-duplicated `part` strings hit, in raycast order. Empty if
70
+ * no annotated mesh is under the cursor.
71
+ */
72
+ getHoveredComponentParts(componentObject3D: THREE.Object3D): string[];
58
73
  /**
59
74
  * Force update hover state at current mouse position
60
75
  *
@@ -0,0 +1,54 @@
1
+ import { ComponentVisualFactoryBase } from '../ComponentVisualFactory';
2
+ import { Component, ComponentState } from '../../../../core/index.ts';
3
+ import { ConfigFormDefinition, VisualContext } from '../../types';
4
+ import * as THREE from 'three';
5
+ /**
6
+ * Visual factory for Adder components.
7
+ *
8
+ * Creates:
9
+ * - An `envelope` rectangular frame (EmptyRectangleGeometry)
10
+ * - A horizontal `separator` box dividing upper/lower chambers
11
+ * - A `sumFiller` (RectangleWithNailGeometry) in the upper chamber;
12
+ * its material is animated blue↔red following the sum output state
13
+ * - A `plus` box inside the sumFiller (visual cue)
14
+ * - A `carryFiller` (RectangleWithNailGeometry) box in the lower chamber; its material is animated
15
+ * blue↔red following the carry output state
16
+ * - pin groups for vcc, inputA, inputB, sum, carry, gnd
17
+ *
18
+ * Animation:
19
+ * - sumFiller ↔ blue/red based on sum output (current/next state)
20
+ * - carryFiller ↔ blue/red based on carry output (current/next state)
21
+ */
22
+ export declare class AdderVisualFactory extends ComponentVisualFactoryBase {
23
+ private readonly ENVELOPE_GEOM;
24
+ /** Horizontal separator splitting upper/lower chambers at Z=0 */
25
+ private readonly SEPARATOR_GEOM;
26
+ private readonly SEPARATOR_SIDE_GEOM;
27
+ private readonly CELL_FILLER_GEOM;
28
+ /** Small box inside sumFiller (visual cue for the XOR "+") */
29
+ private readonly PLUS_GEOM;
30
+ protected readonly FILLER_COLOR_HIGH: THREE.Color;
31
+ protected readonly FILLER_COLOR_LOW: THREE.Color;
32
+ protected readonly FILLER_EMISSIVE_HIGH_INTENSITY = 0.5;
33
+ protected readonly FILLER_EMISSIVE_LOW_INTENSITY = 0.2;
34
+ constructor();
35
+ createVisual(component: Component, context: VisualContext): THREE.Object3D;
36
+ protected createPinsVisual(component: Component, context: VisualContext, group: THREE.Group): void;
37
+ getConfigFormDefinition(config?: Map<string, string>): ConfigFormDefinition | null;
38
+ mapCoreConfigToForm(config: Map<string, string>): Map<string, any>;
39
+ mapFormToCoreConfig(formData: Map<string, any>): Map<string, string>;
40
+ updateAnimation(object3D: THREE.Object3D, state: ComponentState | null): void;
41
+ private _setFillerColor;
42
+ private _ensureClonedFillerMaterial;
43
+ private _restoreSharedFillerMaterial;
44
+ private _cleanupMixer;
45
+ /**
46
+ * Animate sumFiller and carryFiller fill colors over the transition span.
47
+ * Builds a single AnimationClip with up to two target tracks per filler
48
+ * (color, emissive, emissiveIntensity) — only for fillers whose value changes.
49
+ */
50
+ private _animateFillers;
51
+ private _pushFillerTracks;
52
+ /** Find a child mesh by its userData.part name */
53
+ protected findPartMesh(object3D: THREE.Object3D, part: string): THREE.Mesh | null;
54
+ }
@@ -0,0 +1,45 @@
1
+ import { ComponentVisualFactoryBase } from '../ComponentVisualFactory';
2
+ import { Component, ComponentState } from '../../../../core/index.ts';
3
+ import { ConfigFormDefinition, VisualContext } from '../../types';
4
+ import * as THREE from 'three';
5
+ /**
6
+ * Visual factory for EightBitAdder components.
7
+ *
8
+ * Creates:
9
+ * - An `envelope` frame (KuKoGeometry)
10
+ * - A vertical `separator` dividing carry/sum cells
11
+ * - 7 horizontal separators dividing ith cells
12
+ * - 16 cells carry i / sum i representing state
13
+ * cells materials are animated blue↔red following the component state
14
+ * - pin groups for vcc, 2*8 inputs, 8*sums, carryIn, carryOut and gnd
15
+ *
16
+ */
17
+ export declare class EightBitAdderVisualFactory extends ComponentVisualFactoryBase {
18
+ private readonly ENVELOPE_GEOM;
19
+ private readonly VERTICAL_SEPARATOR_GEOM;
20
+ private readonly HORIZONTAL_SEPARATOR_GEOM;
21
+ private readonly CELL_FILLER_GEOM;
22
+ protected readonly FILLER_COLOR_HIGH: THREE.Color;
23
+ protected readonly FILLER_COLOR_LOW: THREE.Color;
24
+ protected readonly FILLER_EMISSIVE_HIGH_INTENSITY = 0.5;
25
+ protected readonly FILLER_EMISSIVE_LOW_INTENSITY = 0.2;
26
+ constructor();
27
+ createVisual(component: Component, context: VisualContext): THREE.Object3D;
28
+ protected createPinsVisual(component: Component, context: VisualContext, group: THREE.Group): void;
29
+ getConfigFormDefinition(config?: Map<string, string>): ConfigFormDefinition | null;
30
+ mapCoreConfigToForm(config: Map<string, string>): Map<string, any>;
31
+ mapFormToCoreConfig(formData: Map<string, any>): Map<string, string>;
32
+ updateAnimation(object3D: THREE.Object3D, state: ComponentState | null): void;
33
+ private _setCellColor;
34
+ private _ensureClonedMaterial;
35
+ private _restoreSharedMaterial;
36
+ private _cleanupMixer;
37
+ /** Collect all 16 cell meshes with their state bit position. */
38
+ private _findCellMeshes;
39
+ /**
40
+ * Animate the 16 cells over the transition span.
41
+ * Builds a single AnimationClip with tracks only for cells whose bit changes.
42
+ */
43
+ private _animateCells;
44
+ private _pushCellTracks;
45
+ }
@@ -0,0 +1,63 @@
1
+ import { ComponentVisualFactoryBase } from '../ComponentVisualFactory';
2
+ import { Component, ComponentState } from '../../../../core/index.ts';
3
+ import { ConfigFormDefinition, VisualContext } from '../../types';
4
+ import * as THREE from 'three';
5
+ /**
6
+ * Visual factory for EightBitOnesComplement components.
7
+ *
8
+ * Creates:
9
+ * - An `envelope` frame (EmptyRectangleGeometry)
10
+ * - A vertical `separator` dividing flag area / outputs cells
11
+ * - 7 horizontal separators dividing ith cells
12
+ * - 2 rectangles with nail filler, 3 animated box geometry and 2 filler boxes for flag area
13
+ * - 8 cells outputs i representing output state
14
+ * cells materials are animated blue↔red following the component state
15
+ * - pin groups for vcc, 8 inputs, 8*outputs and gnd
16
+ *
17
+ */
18
+ export declare class EightBitOnesComplementVisualFactory extends ComponentVisualFactoryBase {
19
+ private readonly ENVELOPE_GEOM;
20
+ private readonly VERTICAL_SEPARATOR_GEOM;
21
+ private readonly HORIZONTAL_SEPARATOR_GEOM;
22
+ private readonly CELL_FILLER_GEOM;
23
+ private readonly INDICATOR_MINUS_GEOM;
24
+ private readonly INDICATOR_PLUS_GEOM;
25
+ private readonly INDICATOR_FILLER_GEOM;
26
+ protected readonly FILLER_COLOR_HIGH: THREE.Color;
27
+ protected readonly FILLER_COLOR_LOW: THREE.Color;
28
+ protected readonly FILLER_COLOR_NEUTRAL: THREE.Color;
29
+ protected readonly FILLER_EMISSIVE_BLACK: THREE.Color;
30
+ protected readonly FILLER_EMISSIVE_HIGH_INTENSITY = 0.5;
31
+ protected readonly FILLER_EMISSIVE_LOW_INTENSITY = 0.2;
32
+ protected readonly FILLER_EMISSIVE_NEUTRAL_INTENSITY = 0;
33
+ constructor();
34
+ createVisual(component: Component, context: VisualContext): THREE.Object3D;
35
+ protected createPinsVisual(component: Component, context: VisualContext, group: THREE.Group): void;
36
+ getConfigFormDefinition(config?: Map<string, string>): ConfigFormDefinition | null;
37
+ mapCoreConfigToForm(config: Map<string, string>): Map<string, any>;
38
+ mapFormToCoreConfig(formData: Map<string, any>): Map<string, string>;
39
+ updateAnimation(object3D: THREE.Object3D, state: ComponentState | null): void;
40
+ /**
41
+ * Resolve the target color state for a cell given its kind and the bit value:
42
+ * - `output`: high→red, low→blue
43
+ * - `minus`: high→blue, low→red (inverted vs output — blue minus = complement active)
44
+ * - `plus`: high→white (blends with envelope, hiding the +), low→red
45
+ */
46
+ private _cellTarget;
47
+ private _setCellColor;
48
+ private _ensureClonedMaterial;
49
+ private _restoreSharedMaterial;
50
+ private _cleanupMixer;
51
+ /**
52
+ * Collect all animated cells (8 outputs + minus + 2 plus parts).
53
+ * Output cells read bits 0–7; the three indicator cells all read bit 8
54
+ * (the invert flag) but render it with different color rules.
55
+ */
56
+ private _findCellMeshes;
57
+ /**
58
+ * Animate all cells over the transition span.
59
+ * Builds a single AnimationClip with tracks only for cells whose bit changes.
60
+ */
61
+ private _animateCells;
62
+ private _pushCellTracks;
63
+ }
@@ -0,0 +1,55 @@
1
+ import { ComponentVisualFactoryBase } from '../ComponentVisualFactory';
2
+ import { Component, ComponentState } from '../../../../core/index.ts';
3
+ import { ConfigFormDefinition, VisualContext } from '../../types';
4
+ import * as THREE from 'three';
5
+ /**
6
+ * Visual factory for Half Adder components.
7
+ *
8
+ * Creates:
9
+ * - An `envelope` rectangular frame (EmptyRectangleGeometry)
10
+ * - A horizontal `separator` box dividing upper/lower chambers
11
+ * - A `sumFiller` (RectangleWithNailGeometry) in the upper chamber;
12
+ * its material is animated blue↔red following the sum output state
13
+ * - A `halfPlus` small box inside the sumFiller (visual cue)
14
+ * - A `carryFiller` box in the lower chamber; its material is animated
15
+ * blue↔red following the carry output state
16
+ * - pin groups for vcc, inputA, inputB, sum, carry, gnd
17
+ *
18
+ * Animation:
19
+ * - sumFiller ↔ blue/red based on sum output (current/next state)
20
+ * - carryFiller ↔ blue/red based on carry output (current/next state)
21
+ */
22
+ export declare class HalfAdderVisualFactory extends ComponentVisualFactoryBase {
23
+ private readonly ENVELOPE_GEOM;
24
+ /** Horizontal separator splitting upper/lower chambers at Z=0 */
25
+ private readonly SEPARATOR_GEOM;
26
+ private readonly SEPARATOR_SIDE_GEOM;
27
+ private readonly SUM_FILLER_GEOM;
28
+ /** Small box inside sumFiller (visual cue for the XOR "+") */
29
+ private readonly HALF_PLUS_GEOM;
30
+ private readonly CARRY_FILLER_GEOM;
31
+ protected readonly FILLER_COLOR_HIGH: THREE.Color;
32
+ protected readonly FILLER_COLOR_LOW: THREE.Color;
33
+ protected readonly FILLER_EMISSIVE_HIGH_INTENSITY = 0.5;
34
+ protected readonly FILLER_EMISSIVE_LOW_INTENSITY = 0.2;
35
+ constructor();
36
+ createVisual(component: Component, context: VisualContext): THREE.Object3D;
37
+ protected createPinsVisual(component: Component, context: VisualContext, group: THREE.Group): void;
38
+ getConfigFormDefinition(config?: Map<string, string>): ConfigFormDefinition | null;
39
+ mapCoreConfigToForm(config: Map<string, string>): Map<string, any>;
40
+ mapFormToCoreConfig(formData: Map<string, any>): Map<string, string>;
41
+ updateAnimation(object3D: THREE.Object3D, state: ComponentState | null): void;
42
+ private _setFillerColor;
43
+ private _ensureClonedFillerMaterial;
44
+ private _restoreSharedFillerMaterial;
45
+ private _cleanupMixer;
46
+ /**
47
+ * Animate sumFiller and carryFiller fill colors over the transition span.
48
+ * Builds a single AnimationClip with up to two target tracks per filler
49
+ * (color, emissive, emissiveIntensity) — only for fillers whose value changes.
50
+ */
51
+ private _animateFillers;
52
+ private _pushFillerTracks;
53
+ /** Find a child mesh by its userData.part name */
54
+ protected findPartMesh(object3D: THREE.Object3D, part: string): THREE.Mesh | null;
55
+ }
@@ -0,0 +1,4 @@
1
+ export { AdderVisualFactory } from './AdderVisualFactory';
2
+ export { HalfAdderVisualFactory } from './HalfAdderVisualFactory';
3
+ export { EightBitAdderVisualFactory } from './EightBitAdderVisualFactory';
4
+ export { EightBitOnesComplementVisualFactory } from './EightBitOnesComplementVisualFactory';
@@ -27,3 +27,17 @@ export { Nor8GateVisualFactory } from './gates/Nor8GateVisualFactory';
27
27
  export { XorGateVisualFactory } from './gates/XorGateVisualFactory';
28
28
  export { Xor4GateVisualFactory } from './gates/Xor4GateVisualFactory';
29
29
  export { Xor8GateVisualFactory } from './gates/Xor8GateVisualFactory';
30
+ export { HalfAdderVisualFactory } from './arithmetic/HalfAdderVisualFactory';
31
+ export { AdderVisualFactory } from './arithmetic/AdderVisualFactory';
32
+ export { EightBitAdderVisualFactory } from './arithmetic/EightBitAdderVisualFactory';
33
+ export { EightBitOnesComplementVisualFactory } from './arithmetic/EightBitOnesComplementVisualFactory';
34
+ export { InputVisualFactoryBase } from './interface/InputVisualFactoryBase';
35
+ export { OneInputVisualFactory } from './interface/OneInputVisualFactory';
36
+ export { TwoInputVisualFactory } from './interface/TwoInputVisualFactory';
37
+ export { FourInputVisualFactory } from './interface/FourInputVisualFactory';
38
+ export { EightInputVisualFactory } from './interface/EightInputVisualFactory';
39
+ export { LightVisualFactoryBase } from './interface/LightVisualFactoryBase';
40
+ export { OneLightVisualFactory } from './interface/OneLightVisualFactory';
41
+ export { TwoLightVisualFactory } from './interface/TwoLightVisualFactory';
42
+ export { FourLightVisualFactory } from './interface/FourLightVisualFactory';
43
+ export { EightLightVisualFactory } from './interface/EightLightVisualFactory';
@@ -0,0 +1,15 @@
1
+ import { Component } from '../../../../core/index.ts';
2
+ import { VisualContext } from '../../types';
3
+ import { InputVisualFactoryBase } from './InputVisualFactoryBase';
4
+ import * as THREE from 'three';
5
+ /** Visual factory for the EightInput component (eight-switch user input). */
6
+ export declare class EightInputVisualFactory extends InputVisualFactoryBase {
7
+ protected readonly bitCount = 8;
8
+ protected readonly holePositions: Array<{
9
+ x: number;
10
+ y: number;
11
+ }>;
12
+ protected readonly envelopeHeight = 8.4;
13
+ constructor();
14
+ createVisual(component: Component, context: VisualContext): THREE.Object3D;
15
+ }
@@ -0,0 +1,15 @@
1
+ import { Component } from '../../../../core/index.ts';
2
+ import { VisualContext } from '../../types';
3
+ import { LightVisualFactoryBase } from './LightVisualFactoryBase';
4
+ import * as THREE from 'three';
5
+ /** Visual factory for the EightLight component (eight-light input mirror). */
6
+ export declare class EightLightVisualFactory extends LightVisualFactoryBase {
7
+ protected readonly bitCount = 8;
8
+ protected readonly holePositions: Array<{
9
+ x: number;
10
+ y: number;
11
+ }>;
12
+ protected readonly envelopeHeight = 8.4;
13
+ constructor();
14
+ createVisual(component: Component, context: VisualContext): THREE.Object3D;
15
+ }
@@ -0,0 +1,15 @@
1
+ import { Component } from '../../../../core/index.ts';
2
+ import { VisualContext } from '../../types';
3
+ import { InputVisualFactoryBase } from './InputVisualFactoryBase';
4
+ import * as THREE from 'three';
5
+ /** Visual factory for the FourInput component (four-switch user input). */
6
+ export declare class FourInputVisualFactory extends InputVisualFactoryBase {
7
+ protected readonly bitCount = 4;
8
+ protected readonly holePositions: Array<{
9
+ x: number;
10
+ y: number;
11
+ }>;
12
+ protected readonly envelopeHeight = 4.4;
13
+ constructor();
14
+ createVisual(component: Component, context: VisualContext): THREE.Object3D;
15
+ }
@@ -0,0 +1,15 @@
1
+ import { Component } from '../../../../core/index.ts';
2
+ import { VisualContext } from '../../types';
3
+ import { LightVisualFactoryBase } from './LightVisualFactoryBase';
4
+ import * as THREE from 'three';
5
+ /** Visual factory for the FourLight component (four-light input mirror). */
6
+ export declare class FourLightVisualFactory extends LightVisualFactoryBase {
7
+ protected readonly bitCount = 4;
8
+ protected readonly holePositions: Array<{
9
+ x: number;
10
+ y: number;
11
+ }>;
12
+ protected readonly envelopeHeight = 4.4;
13
+ constructor();
14
+ createVisual(component: Component, context: VisualContext): THREE.Object3D;
15
+ }