simple-circuit-engine 0.0.11 → 0.0.12

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 (141) hide show
  1. package/AGENTS.md +10 -7
  2. package/CLAUDE.md +4 -6
  3. package/README.md +5 -2
  4. package/dist/core/index.d.ts +0 -1
  5. package/dist/core/index.js +74 -2114
  6. package/dist/core/setup.d.ts +17 -0
  7. package/dist/core/simulation/CircuitRunner.d.ts +176 -0
  8. package/dist/core/simulation/DirtyTracker.d.ts +87 -0
  9. package/dist/core/simulation/EventQueue.d.ts +68 -0
  10. package/dist/core/simulation/StateManager.d.ts +100 -0
  11. package/dist/core/simulation/behaviors/BehaviorRegistry.d.ts +70 -0
  12. package/dist/core/simulation/behaviors/ComponentBehavior.d.ts +53 -0
  13. package/dist/core/simulation/behaviors/basic/BatteryBehavior.d.ts +14 -0
  14. package/dist/core/simulation/behaviors/basic/ClockBehavior.d.ts +24 -0
  15. package/dist/core/simulation/behaviors/basic/DoubleThrowSwitchBehavior.d.ts +33 -0
  16. package/dist/core/simulation/behaviors/basic/LightbulbBehavior.d.ts +23 -0
  17. package/dist/core/simulation/behaviors/basic/RectangleLEDBehavior.d.ts +24 -0
  18. package/dist/core/simulation/behaviors/basic/RelayBehavior.d.ts +33 -0
  19. package/dist/core/simulation/behaviors/basic/SmallLEDBehavior.d.ts +24 -0
  20. package/dist/core/simulation/behaviors/basic/SwitchBehavior.d.ts +33 -0
  21. package/dist/core/simulation/behaviors/basic/index.d.ts +20 -0
  22. package/dist/core/simulation/behaviors/gates/InverterBehavior.d.ts +29 -0
  23. package/dist/core/simulation/behaviors/gates/Nand4GateBehavior.d.ts +18 -0
  24. package/dist/core/simulation/behaviors/gates/Nand8GateBehavior.d.ts +18 -0
  25. package/dist/core/simulation/behaviors/gates/NandGateBehavior.d.ts +28 -0
  26. package/dist/core/simulation/behaviors/gates/Nor4GateBehavior.d.ts +18 -0
  27. package/dist/core/simulation/behaviors/gates/Nor8GateBehavior.d.ts +18 -0
  28. package/dist/core/simulation/behaviors/gates/NorGateBehavior.d.ts +22 -0
  29. package/dist/core/simulation/behaviors/gates/Xor4GateBehavior.d.ts +18 -0
  30. package/dist/core/simulation/behaviors/gates/Xor8GateBehavior.d.ts +18 -0
  31. package/dist/core/simulation/behaviors/gates/XorGateBehavior.d.ts +22 -0
  32. package/dist/core/simulation/behaviors/gates/index.d.ts +34 -0
  33. package/dist/core/simulation/behaviors/index.d.ts +24 -0
  34. package/dist/core/simulation/behaviors/types.d.ts +101 -0
  35. package/dist/core/simulation/index.d.ts +18 -0
  36. package/dist/core/simulation/states/ComponentState.d.ts +57 -0
  37. package/dist/core/simulation/states/SimulationState.d.ts +46 -0
  38. package/dist/core/simulation/states/basic/BatteryState.d.ts +16 -0
  39. package/dist/core/simulation/states/basic/ClockState.d.ts +16 -0
  40. package/dist/core/simulation/states/basic/DoubleThrowSwitchState.d.ts +21 -0
  41. package/dist/core/simulation/states/basic/LightbulbState.d.ts +21 -0
  42. package/dist/core/simulation/states/basic/RectangleLEDState.d.ts +9 -0
  43. package/dist/core/simulation/states/basic/RelayState.d.ts +25 -0
  44. package/dist/core/simulation/states/basic/SmallLEDState.d.ts +21 -0
  45. package/dist/core/simulation/states/basic/SwitchState.d.ts +25 -0
  46. package/dist/core/simulation/states/gates/InverterState.d.ts +17 -0
  47. package/dist/core/simulation/states/gates/Nand4GateState.d.ts +10 -0
  48. package/dist/core/simulation/states/gates/Nand8GateState.d.ts +10 -0
  49. package/dist/core/simulation/states/gates/NandGateState.d.ts +16 -0
  50. package/dist/core/simulation/states/gates/Nor4GateState.d.ts +10 -0
  51. package/dist/core/simulation/states/gates/Nor8GateState.d.ts +10 -0
  52. package/dist/core/simulation/states/gates/NorGateState.d.ts +10 -0
  53. package/dist/core/simulation/states/gates/Xor4GateState.d.ts +10 -0
  54. package/dist/core/simulation/states/gates/Xor8GateState.d.ts +10 -0
  55. package/dist/core/simulation/states/gates/XorGateState.d.ts +10 -0
  56. package/dist/core/simulation/states/gates/index.d.ts +25 -0
  57. package/dist/core/simulation/states/index.d.ts +26 -0
  58. package/dist/core/simulation/states/types.d.ts +32 -0
  59. package/dist/core/simulation/types.d.ts +155 -0
  60. package/dist/core/topology/Circuit.d.ts +420 -0
  61. package/dist/core/topology/CircuitMetadata.d.ts +24 -0
  62. package/dist/core/topology/CircuitOptions.d.ts +14 -0
  63. package/dist/core/topology/Component.d.ts +152 -0
  64. package/dist/core/topology/ENode.d.ts +200 -0
  65. package/dist/core/topology/Wire.d.ts +130 -0
  66. package/dist/core/topology/delays.d.ts +52 -0
  67. package/dist/core/topology/index.d.ts +14 -0
  68. package/dist/core/topology/types.d.ts +175 -0
  69. package/dist/core/utils/CameraOptions.d.ts +83 -0
  70. package/dist/core/utils/MemoizeDecorator.d.ts +9 -0
  71. package/dist/core/utils/Position.d.ts +166 -0
  72. package/dist/core/utils/Position3D.d.ts +77 -0
  73. package/dist/core/utils/Rotation.d.ts +82 -0
  74. package/dist/core/utils/index.d.ts +24 -0
  75. package/dist/core/utils/types.d.ts +35 -0
  76. package/dist/core-Bjta9Y7_.js +2707 -0
  77. package/dist/core-Bjta9Y7_.js.map +1 -0
  78. package/dist/index.d.ts +13 -6306
  79. package/dist/index.js +117 -110
  80. package/dist/scene/CircuitEngine.d.ts +270 -0
  81. package/dist/scene/index.d.ts +0 -1
  82. package/dist/scene/index.js +43 -39
  83. package/dist/scene/setup.d.ts +18 -0
  84. package/dist/scene/shared/AbstractCircuitController.d.ts +211 -0
  85. package/dist/scene/shared/BranchingPointVisualFactory.d.ts +70 -0
  86. package/dist/scene/shared/EventEmitter.d.ts +92 -0
  87. package/dist/scene/shared/HoverManager.d.ts +151 -0
  88. package/dist/scene/shared/SelectionManager.d.ts +159 -0
  89. package/dist/scene/shared/WireVisualManager.d.ts +242 -0
  90. package/dist/scene/shared/components/ComponentVisualFactory.d.ts +438 -0
  91. package/dist/scene/shared/components/DefaultVisualFactory.d.ts +51 -0
  92. package/dist/scene/shared/components/FactoryRegistry.d.ts +84 -0
  93. package/dist/scene/shared/components/GroupedFactoryRegistry.d.ts +153 -0
  94. package/dist/scene/shared/components/basic/BatteryVisualFactory.d.ts +13 -0
  95. package/dist/scene/shared/components/basic/ClockVisualFactory.d.ts +79 -0
  96. package/dist/scene/shared/components/basic/DoubleThrowSwitchVisualFactory.d.ts +87 -0
  97. package/dist/scene/shared/components/basic/LabelVisualFactory.d.ts +148 -0
  98. package/dist/scene/shared/components/basic/LightbulbVisualFactory.d.ts +72 -0
  99. package/dist/scene/shared/components/basic/RectangleLEDVisualFactory.d.ts +86 -0
  100. package/dist/scene/shared/components/basic/RelayVisualFactory.d.ts +92 -0
  101. package/dist/scene/shared/components/basic/SmallLEDVisualFactory.d.ts +86 -0
  102. package/dist/scene/shared/components/basic/SwitchVisualFactory.d.ts +85 -0
  103. package/dist/scene/shared/components/gates/InverterVisualFactory.d.ts +104 -0
  104. package/dist/scene/shared/components/gates/Nand4GateVisualFactory.d.ts +27 -0
  105. package/dist/scene/shared/components/gates/Nand8GateVisualFactory.d.ts +27 -0
  106. package/dist/scene/shared/components/gates/NandGateVisualFactory.d.ts +101 -0
  107. package/dist/scene/shared/components/gates/Nor4GateVisualFactory.d.ts +27 -0
  108. package/dist/scene/shared/components/gates/Nor8GateVisualFactory.d.ts +27 -0
  109. package/dist/scene/shared/components/gates/NorGateVisualFactory.d.ts +101 -0
  110. package/dist/scene/shared/components/gates/Xor4GateVisualFactory.d.ts +29 -0
  111. package/dist/scene/shared/components/gates/Xor8GateVisualFactory.d.ts +29 -0
  112. package/dist/scene/shared/components/gates/XorGateVisualFactory.d.ts +103 -0
  113. package/dist/scene/shared/components/index.d.ts +29 -0
  114. package/dist/scene/shared/components/types.d.ts +43 -0
  115. package/dist/scene/shared/types.d.ts +476 -0
  116. package/dist/scene/shared/utils/CameraUtils.d.ts +23 -0
  117. package/dist/scene/shared/utils/ColorUtils.d.ts +26 -0
  118. package/dist/scene/shared/utils/ControlsUtils.d.ts +8 -0
  119. package/dist/scene/shared/utils/GeometryUtils.d.ts +261 -0
  120. package/dist/scene/shared/utils/LayerConstants.d.ts +40 -0
  121. package/dist/scene/shared/utils/LightingUtils.d.ts +31 -0
  122. package/dist/scene/shared/utils/MaterialUtils.d.ts +73 -0
  123. package/dist/scene/shared/utils/Options.d.ts +16 -0
  124. package/dist/scene/simulation/CircuitRunnerController.d.ts +227 -0
  125. package/dist/scene/static/CircuitController.d.ts +227 -0
  126. package/dist/scene/static/CircuitWriter.d.ts +146 -0
  127. package/dist/scene/static/PinTooltipWidget.d.ts +26 -0
  128. package/dist/scene/static/tools/BuildTool.d.ts +286 -0
  129. package/dist/scene/static/tools/ComponentPickerWidget.d.ts +82 -0
  130. package/dist/scene/static/tools/ConfigPanelWidget.d.ts +93 -0
  131. package/dist/scene/static/tools/MultiSelectTool.d.ts +265 -0
  132. package/dist/scene-CVsDdySt.js +7357 -0
  133. package/dist/scene-CVsDdySt.js.map +1 -0
  134. package/package.json +24 -25
  135. package/dist/CircuitRunner-BQQlhwjD.js +0 -1981
  136. package/dist/CircuitRunner-BQQlhwjD.js.map +0 -1
  137. package/dist/core/index.js.map +0 -1
  138. package/dist/index.js.map +0 -1
  139. package/dist/scene/index.js.map +0 -1
  140. package/dist/setup-CIq_kgaw.js +0 -10230
  141. package/dist/setup-CIq_kgaw.js.map +0 -1
@@ -0,0 +1,51 @@
1
+ import { ComponentVisualFactoryBase } from './ComponentVisualFactory';
2
+ import { Component } from '../../../core/index.ts';
3
+ import { ConfigFormDefinition } from '../types';
4
+ import * as THREE from 'three';
5
+ /**
6
+ * Default Visual factory for not yet defined components
7
+ *
8
+ * Creates:
9
+ * - Box squared mesh (white)
10
+ * - Component hitbox for raycasting
11
+ *
12
+ * This default visual is pinless no matter the component definition.
13
+ */
14
+ export declare class DefaultVisualFactory extends ComponentVisualFactoryBase {
15
+ createVisual(component: Component): THREE.Object3D;
16
+ /**
17
+ * Get config form definition (T028)
18
+ * Returns form for Cube (color) - RectangleLED uses SmallLEDVisualFactory
19
+ *
20
+ * @returns Form definition with color field for Cube
21
+ */
22
+ getConfigFormDefinition(): ConfigFormDefinition | null;
23
+ /**
24
+ * Map core config to form data (T028)
25
+ * Converts hex/preset strings to hex values for color picker
26
+ *
27
+ * @param config - Core component config
28
+ * @returns Form data with hex color string
29
+ */
30
+ mapCoreConfigToForm(config: Map<string, string>): Map<string, any>;
31
+ /**
32
+ * Map form data to core config (T028)
33
+ * Converts hex colors to preset names if they match, otherwise keeps hex
34
+ *
35
+ * @param formData - Form data with hex color string
36
+ * @returns Core config with hex or preset name string
37
+ */
38
+ mapFormToCoreConfig(formData: Map<string, any>): Map<string, string>;
39
+ /**
40
+ * Update visual from configuration (T023)
41
+ * Updates Cube/RectangleLED color based on color config
42
+ *
43
+ * @param object3D - The Object3D created by createVisual()
44
+ * @param config - Component configuration map
45
+ *
46
+ * @remarks
47
+ * Updates the box mesh color if 'color' config exists
48
+ * Supports both hex colors and color presets
49
+ */
50
+ updateFromConfiguration(object3D: THREE.Object3D, config: Map<string, string>): void;
51
+ }
@@ -0,0 +1,84 @@
1
+ import { ComponentType } from '../../../core/index.ts';
2
+ import { AnimationContext } from '../types';
3
+ import { IComponentVisualFactory, IFactoryRegistry } from './ComponentVisualFactory';
4
+ /**
5
+ * Registry mapping ComponentType to ComponentVisualFactory
6
+ *
7
+ * Provides type-safe registration and retrieval with automatic fallback.
8
+ * Supports both function-based (legacy) and class-based (new) factories.
9
+ * Thread-safe for read operations (get/has), write operations should be
10
+ * performed during initialization.
11
+ *
12
+ * @example
13
+ * ```typescript
14
+ * const registry = new FactoryRegistry(new DefaultVisualFactory());
15
+ * registry.register(ComponentType.Battery, new BatteryVisualFactory());
16
+ * registry.register(ComponentType.LED, new SmallLEDVisualFactory());
17
+ *
18
+ * const factory = registry.get(ComponentType.Battery); // Returns BatteryVisualFactory
19
+ * const unknown = registry.get(ComponentType.Unknown); // Returns fallback
20
+ * const mesh = factory.createVisual(component);
21
+ * ```
22
+ */
23
+ export declare class FactoryRegistry implements IFactoryRegistry {
24
+ private factories;
25
+ private fallbackFactory;
26
+ /**
27
+ * Create a new factory registry
28
+ *
29
+ * @param fallbackFactory - Factory to use for unregistered component types
30
+ * @throws {TypeError} If fallbackFactory is null or undefined
31
+ */
32
+ constructor(fallbackFactory: IComponentVisualFactory);
33
+ /**
34
+ * Register a visual factory for a specific component type
35
+ *
36
+ * @param type - Component type identifier
37
+ * @param factory - Factory (class instance or function) to create visuals for this type
38
+ * @throws {TypeError} If type is empty/whitespace or factory is null/undefined
39
+ * @returns This FactoryRegistry instance (for chaining)
40
+ */
41
+ register(type: ComponentType, factory: IComponentVisualFactory): FactoryRegistry;
42
+ /**
43
+ * Retrieve the factory for a component type
44
+ *
45
+ * @param type - Component type identifier
46
+ * @returns Factory (fallback factory if type not registered)
47
+ *
48
+ * @remarks
49
+ * This method NEVER returns null/undefined. If the type is not registered,
50
+ * the fallback factory provided in the constructor is returned.
51
+ */
52
+ get(type: ComponentType): IComponentVisualFactory;
53
+ /**
54
+ * Check if a factory is registered for a component type
55
+ *
56
+ * @param type - Component type identifier
57
+ * @returns true if explicitly registered, false if would use fallback
58
+ */
59
+ has(type: ComponentType): boolean;
60
+ /**
61
+ * Get the fallback factory used for unregistered types
62
+ */
63
+ getFallbackFactory(): IComponentVisualFactory;
64
+ /**
65
+ * Unregister a factory for a component type
66
+ *
67
+ * @param type - Component type identifier
68
+ * @returns true if factory was registered and removed, false otherwise
69
+ *
70
+ * @remarks
71
+ * After unregistering, get() will return the fallback factory for this type.
72
+ */
73
+ unregister(type: ComponentType): boolean;
74
+ /**
75
+ * Get all registered component types
76
+ *
77
+ * @returns Array of ComponentType values that have registered factories
78
+ */
79
+ getRegisteredTypes(): ComponentType[];
80
+ /**
81
+ * Fan out animation context to all registered factories and the fallback.
82
+ */
83
+ setAnimationContext(ctx: AnimationContext | null): void;
84
+ }
@@ -0,0 +1,153 @@
1
+ import { ComponentType } from '../../../core/index.ts';
2
+ import { AnimationContext } from '../types.js';
3
+ import { IComponentVisualFactory, IFactoryRegistry } from './ComponentVisualFactory.js';
4
+ /**
5
+ * Describes a named group of component types
6
+ */
7
+ export interface ComponentGroup {
8
+ readonly id: string;
9
+ readonly label: string;
10
+ }
11
+ /**
12
+ * Builder interface for adding components to a group.
13
+ * Used as the callback parameter type in addGroup().
14
+ *
15
+ * @example
16
+ * ```typescript
17
+ * registry.addGroup('basic', 'Basic Components', (group: IComponentGroupBuilder) => {
18
+ * group
19
+ * .add(ComponentType.Battery, new BatteryVisualFactory())
20
+ * .add(ComponentType.Switch, new SwitchVisualFactory());
21
+ * });
22
+ * ```
23
+ */
24
+ export interface IComponentGroupBuilder {
25
+ add(type: ComponentType, factory: IComponentVisualFactory): IComponentGroupBuilder;
26
+ }
27
+ /**
28
+ * Extended registry interface with grouping support.
29
+ *
30
+ * Adds group management on top of the basic factory retrieval,
31
+ * allowing client UIs to build organized component palettes.
32
+ */
33
+ export interface IGroupedFactoryRegistry {
34
+ addGroup(id: string, label: string, builderCallback: (group: IComponentGroupBuilder) => void): IGroupedFactoryRegistry;
35
+ get(type: ComponentType): IComponentVisualFactory;
36
+ has(type: ComponentType): boolean;
37
+ getFallbackFactory(): IComponentVisualFactory;
38
+ getGroups(): ComponentGroup[];
39
+ getGroupOf(type: ComponentType): ComponentGroup | undefined;
40
+ getRegisteredTypes(groupId?: string): ComponentType[];
41
+ unregister(type: ComponentType): boolean;
42
+ }
43
+ /**
44
+ * Factory registry with named group support.
45
+ *
46
+ * Implements both IFactoryRegistry (backward compat) and IGroupedFactoryRegistry.
47
+ * Components may only be registered inside a group context via addGroup().
48
+ *
49
+ * Group insertion order is preserved (Map maintains insertion order).
50
+ * Duplicate group ids merge their components; the label from the first
51
+ * registration is preserved.
52
+ *
53
+ * @example
54
+ * ```typescript
55
+ * const registry = new GroupedFactoryRegistry(new DefaultVisualFactory())
56
+ * .addGroup('basic', 'Basic Components', group => group
57
+ * .add(ComponentType.Battery, new BatteryVisualFactory())
58
+ * .add(ComponentType.Switch, new SwitchVisualFactory())
59
+ * )
60
+ * .addGroup('outputs', 'Output Components', group => group
61
+ * .add(ComponentType.Lightbulb, new LightbulbVisualFactory())
62
+ * );
63
+ *
64
+ * registry.getGroups(); // [{ id: 'basic', ... }, { id: 'outputs', ... }]
65
+ * registry.getGroupOf(ComponentType.Battery); // { id: 'basic', label: 'Basic Components' }
66
+ * registry.getRegisteredTypes('basic'); // [ComponentType.Battery, ComponentType.Switch]
67
+ * registry.get(ComponentType.Battery); // BatteryVisualFactory instance
68
+ * ```
69
+ */
70
+ export declare class GroupedFactoryRegistry implements IFactoryRegistry, IGroupedFactoryRegistry {
71
+ private readonly _factories;
72
+ private readonly _fallbackFactory;
73
+ private readonly _groups;
74
+ private readonly _typeToGroupId;
75
+ /**
76
+ * Create a new grouped factory registry.
77
+ *
78
+ * @param fallbackFactory - Factory to use for unregistered component types
79
+ * @throws {TypeError} If fallbackFactory is null or undefined
80
+ */
81
+ constructor(fallbackFactory: IComponentVisualFactory);
82
+ /**
83
+ * Add a named group and register component factories within it.
84
+ *
85
+ * If a group with the same id already exists, the new components are merged
86
+ * into it and the original label is preserved.
87
+ *
88
+ * @param id - Unique group identifier
89
+ * @param label - Human-readable group display name
90
+ * @param builderCallback - Callback receiving a builder for adding components
91
+ * @throws {TypeError} If id or label is empty/whitespace
92
+ * @returns this (for chaining)
93
+ */
94
+ addGroup(id: string, label: string, builderCallback: (group: IComponentGroupBuilder) => void): this;
95
+ /**
96
+ * Retrieve the factory for a component type.
97
+ *
98
+ * @returns Factory, or the fallback factory if type not registered.
99
+ * Never returns null or undefined.
100
+ */
101
+ get(type: ComponentType): IComponentVisualFactory;
102
+ /**
103
+ * Check if a factory is registered for a component type.
104
+ *
105
+ * @returns true if explicitly registered, false if would use fallback
106
+ */
107
+ has(type: ComponentType): boolean;
108
+ /**
109
+ * Get the fallback factory used for unregistered types.
110
+ */
111
+ getFallbackFactory(): IComponentVisualFactory;
112
+ /**
113
+ * Get all defined groups in insertion order.
114
+ *
115
+ * @returns New array of ComponentGroup objects (safe to mutate)
116
+ */
117
+ getGroups(): ComponentGroup[];
118
+ /**
119
+ * Get the group a component type belongs to.
120
+ *
121
+ * @param type - Component type to look up
122
+ * @returns ComponentGroup, or undefined if type is not registered
123
+ */
124
+ getGroupOf(type: ComponentType): ComponentGroup | undefined;
125
+ /**
126
+ * Get registered component types, optionally filtered by group.
127
+ *
128
+ * @param groupId - If provided, returns only types in that group
129
+ * @returns New array of ComponentType values (safe to mutate).
130
+ * Returns empty array if groupId is unknown.
131
+ */
132
+ getRegisteredTypes(groupId?: string): ComponentType[];
133
+ /**
134
+ * Unregister a factory for a component type.
135
+ *
136
+ * The type is removed from its group's list and from the reverse lookup.
137
+ * The group record itself is preserved even if it becomes empty.
138
+ *
139
+ * @param type - Component type to remove
140
+ * @returns true if factory was registered and removed, false otherwise
141
+ */
142
+ unregister(type: ComponentType): boolean;
143
+ /**
144
+ * Fan out animation context to all registered factories and the fallback.
145
+ */
146
+ setAnimationContext(ctx: AnimationContext | null): void;
147
+ /**
148
+ * Not supported. Use addGroup() to register components within a named group.
149
+ *
150
+ * @throws {Error} Always throws
151
+ */
152
+ register(_type: ComponentType, _factory: IComponentVisualFactory): IFactoryRegistry;
153
+ }
@@ -0,0 +1,13 @@
1
+ import { ComponentVisualFactoryBase } from '../ComponentVisualFactory';
2
+ import { Component } from '../../../../core/index.ts';
3
+ import { VisualContext } from '../../types';
4
+ import * as THREE from 'three';
5
+ /**
6
+ * Visual factory for Battery components
7
+ */
8
+ export declare class BatteryVisualFactory extends ComponentVisualFactoryBase {
9
+ private readonly BATTERY_GEOMETRY;
10
+ constructor();
11
+ createVisual(component: Component, context: VisualContext): THREE.Object3D;
12
+ private createPinsVisual;
13
+ }
@@ -0,0 +1,79 @@
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 Clock
7
+ */
8
+ export declare class ClockVisualFactory extends ComponentVisualFactoryBase {
9
+ /** Shared Clock envelope geometry */
10
+ private readonly ENVELOPE_GEOMETRY;
11
+ /** Shared Clock hand geometry */
12
+ private readonly HAND_GEOMETRY;
13
+ /** Shared Clock area geometry */
14
+ private readonly AREA_GEOMETRY;
15
+ private readonly RED_AREA_MAT;
16
+ private readonly BLUE_AREA_MAT;
17
+ private readonly HIGH_TICK_ROTATION;
18
+ private readonly LOW_TICK_ROTATION;
19
+ constructor();
20
+ createVisual(component: Component, context: VisualContext): THREE.Object3D;
21
+ private createPinsVisual;
22
+ private createHandGroup;
23
+ /**
24
+ * Get config form definition for Clock
25
+ *
26
+ * @param config - config
27
+ * @returns Form definition
28
+ */
29
+ getConfigFormDefinition(_config?: Map<string, string>): ConfigFormDefinition | null;
30
+ /**
31
+ * Map core config to form data
32
+ *
33
+ * @param config - Core component config
34
+ * @returns Form data
35
+ */
36
+ mapCoreConfigToForm(config: Map<string, string>): Map<string, any>;
37
+ /**
38
+ * Map form data to core config
39
+ *
40
+ * @param formData - Form data
41
+ * @returns Core config
42
+ */
43
+ mapFormToCoreConfig(formData: Map<string, any>): Map<string, string>;
44
+ updateFromConfiguration(object3D: THREE.Object3D, config: Map<string, string>): void;
45
+ /**
46
+ * Update Clock animation based on simulation state.
47
+ *
48
+ * When state is non-null: animates hand rotation toward the current state's target.
49
+ * If the state has a planned transition (hasExpiration), creates a smooth animation
50
+ * from the current visual rotation to the target using Three.js AnimationMixer.
51
+ * Otherwise snaps to the target position.
52
+ *
53
+ * When state is null (leaving simulation): stops all animations, cleans up mixer,
54
+ * and resets hand to config-based default rotation.
55
+ *
56
+ * @param object3D - The Object3D created by createVisual()
57
+ * @param state - The Clock's current simulation state, or null to reset
58
+ */
59
+ updateAnimation(object3D: THREE.Object3D, state: ComponentState | null): void;
60
+ /**
61
+ * Create a smooth animation from current hand rotation to targetRotation
62
+ */
63
+ private _animateHand;
64
+ /**
65
+ * Stop all animations, clean up mixer, and reset hand to config-based default rotation.
66
+ */
67
+ private _cleanupMixer;
68
+ private getStateRotation;
69
+ /**
70
+ * Find the hand group mesh within the component group
71
+ *
72
+ * @param object3D - The Object3D group created by createVisual()
73
+ * @returns The hand mesh if found, null otherwise
74
+ *
75
+ * @remarks
76
+ * Searches for a mesh with userData.part === 'hand'
77
+ */
78
+ private findHandGroup;
79
+ }
@@ -0,0 +1,87 @@
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 DoubleThrowSwitch (SPDT) components
7
+ *
8
+ * Creates:
9
+ * - Input1 pin group
10
+ * - Input2 pin group
11
+ * - Output pin group
12
+ * - Contactor (box, rotatable for animation)
13
+ * - Component hitbox for raycasting
14
+ *
15
+ * Animation:
16
+ * - Smooth rotation of contactor between input1/input2 via AnimationMixer
17
+ * - Contactor material color reflects output pin state (voltage/current)
18
+ * - Supports mid-transition interruption (re-toggle during transition)
19
+ */
20
+ export declare class DoubleThrowSwitchVisualFactory extends ComponentVisualFactoryBase {
21
+ /** Rotation for switch connected to input1 */
22
+ private readonly INPUT1_ROTATION;
23
+ /** Rotation for switch connected to input2 */
24
+ private readonly INPUT2_ROTATION;
25
+ private readonly CONTACTOR_GEOMETRY;
26
+ /** Contactor color when output has both voltage and current */
27
+ private readonly COLOR_VOLTAGE_CURRENT;
28
+ /** Contactor color when output has current only */
29
+ private readonly COLOR_CURRENT;
30
+ /** Contactor color when output has voltage only */
31
+ private readonly COLOR_VOLTAGE;
32
+ /** Contactor color when output has neither */
33
+ private readonly COLOR_NONE;
34
+ constructor();
35
+ createVisual(component: Component, context: VisualContext): THREE.Object3D;
36
+ private createPinsVisual;
37
+ /**
38
+ * Get config form definition for DoubleThrowSwitch
39
+ *
40
+ * @returns Form definition with initialState, transitionSpan and size
41
+ */
42
+ getConfigFormDefinition(): ConfigFormDefinition | null;
43
+ /**
44
+ * Map core config to form data
45
+ * Converts "input1"/"input2" strings to boolean
46
+ */
47
+ mapCoreConfigToForm(config: Map<string, string>): Map<string, any>;
48
+ /**
49
+ * Map form data to core config
50
+ * Converts boolean to "input1"/"input2" strings
51
+ */
52
+ mapFormToCoreConfig(formData: Map<string, any>): Map<string, string>;
53
+ updateFromConfiguration(object3D: THREE.Object3D, config: Map<string, string>): void;
54
+ /**
55
+ * Update switch animation based on simulation state.
56
+ *
57
+ * - null state / no context: cleanup mixer, reset to config default
58
+ * - paused/initial + transitional: snap to start rotation
59
+ * - paused/initial + stable: snap to state rotation
60
+ * - playing + transitional: smooth rotation animation
61
+ * - playing + stable: snap to final rotation, cleanup mixer
62
+ */
63
+ updateAnimation(object3D: THREE.Object3D, state: ComponentState | null): void;
64
+ /** Maps stable state → target rotation */
65
+ private _getStateRotation;
66
+ /** Maps transitional state → the rotation it came FROM */
67
+ private _getStartRotation;
68
+ /**
69
+ * Create smooth rotation + color animations for transitional states.
70
+ * Rotation clip: current → target state rotation (persists across updateAnimation calls)
71
+ * Color clip: current contactor color → white (stopped on next updateAnimation so pin state takes over)
72
+ */
73
+ private _animateContactor;
74
+ /**
75
+ * Stop the color fade animation so _updateContactorColor can set color from pin state.
76
+ */
77
+ private _stopColorAnimation;
78
+ /**
79
+ * Stop all animations, clean up mixer, reset to config default rotation.
80
+ */
81
+ private _cleanupMixer;
82
+ private _ensureClonedMaterial;
83
+ private _restoreSharedMaterial;
84
+ private _updateContactorColor;
85
+ private findContactorGroup;
86
+ private _findContactorMesh;
87
+ }
@@ -0,0 +1,148 @@
1
+ import { ComponentVisualFactoryBase } from '../ComponentVisualFactory';
2
+ import { Component } from '../../../../core/index.ts';
3
+ import { ConfigFormDefinition, VisualContext } from '../../types';
4
+ import * as THREE from 'three';
5
+ /**
6
+ * Visual factory for Label components
7
+ *
8
+ * Creates:
9
+ * - Text mesh using CanvasTexture for stencil/technical font styling
10
+ * - Component hitbox for raycasting
11
+ * - No pin groups (Label has zero pins)
12
+ *
13
+ * Configuration:
14
+ * - text: Display text content (max 64 characters, default "Label")
15
+ * - size: Scale multiplier (1-10, default 1)
16
+ *
17
+ * @example
18
+ * ```typescript
19
+ * const factory = new LabelVisualFactory();
20
+ * const visual = factory.createVisual(labelComponent);
21
+ * scene.add(visual);
22
+ *
23
+ * // Update text
24
+ * const newConfig = new Map([['text', 'Power Supply'], ['size', '2']]);
25
+ * factory.updateFromConfiguration(visual, newConfig);
26
+ * ```
27
+ */
28
+ export declare class LabelVisualFactory extends ComponentVisualFactoryBase {
29
+ /** Maximum text length in characters */
30
+ private static readonly MAX_TEXT_LENGTH;
31
+ /** Font family for technical/stencil aesthetic */
32
+ private static readonly FONT_FAMILY;
33
+ /** Text color (dark gray for readability) */
34
+ private static readonly TEXT_COLOR;
35
+ /** Hover text color (blue tint matching other components) */
36
+ private static readonly HOVER_COLOR;
37
+ /** Selection text color (orange tint matching other components) */
38
+ private static readonly SELECTION_COLOR;
39
+ /** Base font size in pixels */
40
+ private static readonly BASE_FONT_SIZE;
41
+ /** Padding around text in pixels */
42
+ private static readonly PADDING;
43
+ constructor();
44
+ createVisual(component: Component, _context: VisualContext): THREE.Object3D;
45
+ /**
46
+ * Create a canvas with rendered text
47
+ *
48
+ * @param text - Text to render (truncated to MAX_TEXT_LENGTH)
49
+ * @returns HTMLCanvasElement with rendered text
50
+ */
51
+ private createTextCanvas;
52
+ /**
53
+ * Create a text mesh using CanvasTexture
54
+ *
55
+ * @param text - Text to display
56
+ * @returns THREE.Mesh with text texture
57
+ */
58
+ private createTextMesh;
59
+ /**
60
+ * Find the text mesh within the component group
61
+ *
62
+ * @param object3D - The component group
63
+ * @returns The text mesh or null if not found
64
+ */
65
+ private findTextMesh;
66
+ /**
67
+ * Normalize display text by truncating and providing default
68
+ * @param text
69
+ * @private
70
+ */
71
+ private normalizeDisplayText;
72
+ /**
73
+ * Update the text mesh with new text content
74
+ *
75
+ * Resizes canvas and geometry to fit the new text, then redraws.
76
+ *
77
+ * @param mesh - The text mesh to update
78
+ * @param text - New text content
79
+ * @param group - The parent group containing the hitbox to update
80
+ */
81
+ private updateTextMesh;
82
+ /**
83
+ * Update visual based on Label configuration
84
+ *
85
+ * @param object3D - The component group
86
+ * @param config - Configuration map with text and size
87
+ */
88
+ updateFromConfiguration(object3D: THREE.Object3D, config: Map<string, string>): void;
89
+ /**
90
+ * Get config form definition for Label component
91
+ *
92
+ * @returns Form definition with text and size fields
93
+ */
94
+ getConfigFormDefinition(): ConfigFormDefinition;
95
+ /**
96
+ * Map core config to form data
97
+ *
98
+ * @param config - Core config from Component.config
99
+ * @returns Form data with appropriate types
100
+ */
101
+ mapCoreConfigToForm(config: Map<string, string>): Map<string, any>;
102
+ /**
103
+ * Map form data back to core config
104
+ *
105
+ * @param formData - Form data from UI
106
+ * @returns Core config with string values
107
+ */
108
+ mapFormToCoreConfig(formData: Map<string, any>): Map<string, string>;
109
+ /**
110
+ * Apply hover visual effect to the Label
111
+ *
112
+ * Changes text color to hover color (blue) by redrawing the canvas.
113
+ *
114
+ * @param object3D - The component group
115
+ */
116
+ applyHover(object3D: THREE.Object3D): void;
117
+ /**
118
+ * Remove hover visual effect from the Label
119
+ *
120
+ * Restores text color to default by redrawing the canvas.
121
+ *
122
+ * @param object3D - The component group
123
+ */
124
+ removeHover(object3D: THREE.Object3D): void;
125
+ /**
126
+ * Apply selection visual effect to the Label
127
+ *
128
+ * Changes text color to selection color (orange) by redrawing the canvas.
129
+ *
130
+ * @param object3D - The component group
131
+ */
132
+ applySelection(object3D: THREE.Object3D): void;
133
+ /**
134
+ * Remove selection visual effect from the Label
135
+ *
136
+ * Restores text color based on hover state.
137
+ *
138
+ * @param object3D - The component group
139
+ */
140
+ removeSelection(object3D: THREE.Object3D): void;
141
+ /**
142
+ * Redraw the text canvas with a specific color
143
+ *
144
+ * @param object3D - The component group
145
+ * @param color - The CSS color string to use
146
+ */
147
+ private redrawTextWithColor;
148
+ }
@@ -0,0 +1,72 @@
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 Lightbulb components
7
+ * Animation:
8
+ * - Smooth emissive glow transition when Lightbulb lights up or turns off
9
+ * - Uses AnimationMixer with material property tracks (emissive, opacity)
10
+ * - Clones shared GLASS material per-instance during simulation for independent animation
11
+ */
12
+ export declare class LightbulbVisualFactory extends ComponentVisualFactoryBase {
13
+ /** Lightbulb lit color (yellow glow) */
14
+ private readonly BULB_LIT_COLOR;
15
+ /** Lightbulb lit emissive intensity */
16
+ private readonly BULB_LIT_INTENSITY;
17
+ /** Lightbulb unlit opacity */
18
+ private readonly BULB_UNLIT_OPACITY;
19
+ private readonly BASE_GEOMETRY;
20
+ private readonly BULB_GEOMETRY;
21
+ /** Yellow in normalized RGB for ColorKeyframeTrack */
22
+ private readonly LIT_RGB;
23
+ /** Black in normalized RGB for ColorKeyframeTrack */
24
+ private readonly UNLIT_RGB;
25
+ constructor();
26
+ createVisual(component: Component, context: VisualContext): THREE.Object3D;
27
+ private createPinsVisual;
28
+ /**
29
+ * Get config form definition for Lightbulb
30
+ *
31
+ * @returns Form definition with size
32
+ */
33
+ getConfigFormDefinition(): ConfigFormDefinition | null;
34
+ mapCoreConfigToForm(config: Map<string, string>): Map<string, any>;
35
+ /**
36
+ * Map form data to core config
37
+ *
38
+ * @param formData - Form data with size
39
+ * @returns Core config with string size
40
+ */
41
+ mapFormToCoreConfig(formData: Map<string, any>): Map<string, string>;
42
+ updateFromConfiguration(object3D: THREE.Object3D, config: Map<string, string>): void;
43
+ /**
44
+ * Update Lightbulb animation based on simulation state.
45
+ *
46
+ * - null state / no context: restore shared material, cleanup mixer
47
+ * - paused/initial: snap to target state
48
+ * - playing + transitional (goingOn/goingOff): smooth material animation
49
+ * - playing + stable (on/off): snap to final state
50
+ */
51
+ updateAnimation(object3D: THREE.Object3D, state: ComponentState | null): void;
52
+ /**
53
+ * Clone the shared GLASS material for independent per-instance animation.
54
+ * No-op if already cloned.
55
+ */
56
+ private _ensureClonedMaterial;
57
+ /**
58
+ * Dispose the per-instance clone and restore the shared GLASS.NORMAL material.
59
+ * No-op if not cloned.
60
+ */
61
+ private _restoreSharedMaterial;
62
+ private _snapToState;
63
+ /**
64
+ * Create a smooth material animation for goingOn / goingOff transitions.
65
+ */
66
+ private _animateBulb;
67
+ /**
68
+ * Stop all animations, clean up mixer.
69
+ */
70
+ private _cleanupMixer;
71
+ private findBulbMesh;
72
+ }