@vib3code/sdk 2.0.1

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 (258) hide show
  1. package/CHANGELOG.md +118 -0
  2. package/DOCS/BLUEPRINT_EXECUTION_PLAN_2026-01-07.md +34 -0
  3. package/DOCS/CI_TESTING.md +38 -0
  4. package/DOCS/CLI_ONBOARDING.md +75 -0
  5. package/DOCS/CONTROL_REFERENCE.md +64 -0
  6. package/DOCS/DEV_TRACK_ANALYSIS.md +77 -0
  7. package/DOCS/DEV_TRACK_PLAN_2026-01-07.md +42 -0
  8. package/DOCS/DEV_TRACK_SESSION_2026-01-31.md +220 -0
  9. package/DOCS/ENV_SETUP.md +189 -0
  10. package/DOCS/EXPORT_FORMATS.md +417 -0
  11. package/DOCS/GPU_DISPOSAL_GUIDE.md +21 -0
  12. package/DOCS/LICENSING_TIERS.md +275 -0
  13. package/DOCS/MASTER_PLAN_2026-01-31.md +570 -0
  14. package/DOCS/OBS_SETUP_GUIDE.md +98 -0
  15. package/DOCS/PROJECT_SETUP.md +66 -0
  16. package/DOCS/RENDERER_LIFECYCLE.md +40 -0
  17. package/DOCS/REPO_MANIFEST.md +121 -0
  18. package/DOCS/SESSION_014_PLAN.md +195 -0
  19. package/DOCS/SESSION_LOG_2026-01-07.md +56 -0
  20. package/DOCS/STRATEGIC_BLUEPRINT_2026-01-07.md +72 -0
  21. package/DOCS/SYSTEM_AUDIT_2026-01-30.md +738 -0
  22. package/DOCS/SYSTEM_INVENTORY.md +520 -0
  23. package/DOCS/TELEMETRY_EXPORTS.md +34 -0
  24. package/DOCS/WEBGPU_STATUS.md +38 -0
  25. package/DOCS/XR_BENCHMARKS.md +608 -0
  26. package/LICENSE +21 -0
  27. package/README.md +426 -0
  28. package/docs/.nojekyll +0 -0
  29. package/docs/01-dissolution_of_euclidean_hegemony.html +346 -0
  30. package/docs/02-hyperspatial_ego_death.html +346 -0
  31. package/docs/03-post_cartesian_sublime.html +346 -0
  32. package/docs/04-crystalline_void_meditation.html +346 -0
  33. package/docs/05-quantum_decoherence_ballet.html +346 -0
  34. package/docs/06-dissolution_of_euclidean_hegemony.html +346 -0
  35. package/docs/07-hyperspatial_ego_death.html +346 -0
  36. package/docs/08-post_cartesian_sublime.html +346 -0
  37. package/docs/09-crystalline_void_meditation.html +346 -0
  38. package/docs/10-quantum_decoherence_ballet.html +346 -0
  39. package/docs/11-dissolution_of_euclidean_hegemony.html +346 -0
  40. package/docs/12-hyperspatial_ego_death.html +346 -0
  41. package/docs/13-post_cartesian_sublime.html +346 -0
  42. package/docs/index.html +794 -0
  43. package/docs/test-hub.html +441 -0
  44. package/docs/url-state.js +102 -0
  45. package/docs/vib3-exports/01-quantum-quantum-tetrahedron-lattice.html +489 -0
  46. package/docs/vib3-exports/02-quantum-quantum-hypersphere-matrix.html +489 -0
  47. package/docs/vib3-exports/03-quantum-quantum-hypertetra-fractal.html +489 -0
  48. package/docs/vib3-exports/04-faceted-faceted-crystal-structure.html +407 -0
  49. package/docs/vib3-exports/05-faceted-faceted-klein-bottle.html +407 -0
  50. package/docs/vib3-exports/06-faceted-faceted-hypertetra-torus.html +407 -0
  51. package/docs/vib3-exports/07-holographic-holographic-wave-field.html +457 -0
  52. package/docs/vib3-exports/08-holographic-holographic-hypersphere-sphere.html +457 -0
  53. package/docs/vib3-exports/09-holographic-holographic-hypertetra-crystal.html +457 -0
  54. package/docs/vib3-exports/index.html +238 -0
  55. package/docs/webgpu-live.html +702 -0
  56. package/package.json +367 -0
  57. package/src/advanced/AIPresetGenerator.js +777 -0
  58. package/src/advanced/MIDIController.js +703 -0
  59. package/src/advanced/OffscreenWorker.js +1051 -0
  60. package/src/advanced/WebGPUCompute.js +1051 -0
  61. package/src/advanced/WebXRRenderer.js +680 -0
  62. package/src/agent/cli/AgentCLI.js +615 -0
  63. package/src/agent/cli/index.js +14 -0
  64. package/src/agent/index.js +73 -0
  65. package/src/agent/mcp/MCPServer.js +950 -0
  66. package/src/agent/mcp/index.js +9 -0
  67. package/src/agent/mcp/tools.js +548 -0
  68. package/src/agent/telemetry/EventStream.js +669 -0
  69. package/src/agent/telemetry/Instrumentation.js +618 -0
  70. package/src/agent/telemetry/TelemetryExporters.js +427 -0
  71. package/src/agent/telemetry/TelemetryService.js +464 -0
  72. package/src/agent/telemetry/index.js +52 -0
  73. package/src/benchmarks/BenchmarkRunner.js +381 -0
  74. package/src/benchmarks/MetricsCollector.js +299 -0
  75. package/src/benchmarks/index.js +9 -0
  76. package/src/benchmarks/scenes.js +259 -0
  77. package/src/cli/index.js +675 -0
  78. package/src/config/ApiConfig.js +88 -0
  79. package/src/core/CanvasManager.js +217 -0
  80. package/src/core/ErrorReporter.js +117 -0
  81. package/src/core/ParameterMapper.js +333 -0
  82. package/src/core/Parameters.js +396 -0
  83. package/src/core/RendererContracts.js +200 -0
  84. package/src/core/UnifiedResourceManager.js +370 -0
  85. package/src/core/VIB3Engine.js +636 -0
  86. package/src/core/renderers/FacetedRendererAdapter.js +32 -0
  87. package/src/core/renderers/HolographicRendererAdapter.js +29 -0
  88. package/src/core/renderers/QuantumRendererAdapter.js +29 -0
  89. package/src/core/renderers/RendererLifecycleManager.js +63 -0
  90. package/src/creative/ColorPresetsSystem.js +980 -0
  91. package/src/creative/ParameterTimeline.js +1061 -0
  92. package/src/creative/PostProcessingPipeline.js +1113 -0
  93. package/src/creative/TransitionAnimator.js +683 -0
  94. package/src/export/CSSExporter.js +226 -0
  95. package/src/export/CardGeneratorBase.js +279 -0
  96. package/src/export/ExportManager.js +580 -0
  97. package/src/export/FacetedCardGenerator.js +279 -0
  98. package/src/export/HolographicCardGenerator.js +543 -0
  99. package/src/export/LottieExporter.js +552 -0
  100. package/src/export/QuantumCardGenerator.js +315 -0
  101. package/src/export/SVGExporter.js +519 -0
  102. package/src/export/ShaderExporter.js +903 -0
  103. package/src/export/TradingCardGenerator.js +3055 -0
  104. package/src/export/TradingCardManager.js +181 -0
  105. package/src/export/VIB3PackageExporter.js +559 -0
  106. package/src/export/index.js +14 -0
  107. package/src/export/systems/TradingCardSystemFaceted.js +494 -0
  108. package/src/export/systems/TradingCardSystemHolographic.js +452 -0
  109. package/src/export/systems/TradingCardSystemQuantum.js +411 -0
  110. package/src/faceted/FacetedSystem.js +963 -0
  111. package/src/features/CollectionManager.js +433 -0
  112. package/src/gallery/CollectionManager.js +240 -0
  113. package/src/gallery/GallerySystem.js +485 -0
  114. package/src/geometry/GeometryFactory.js +314 -0
  115. package/src/geometry/GeometryLibrary.js +72 -0
  116. package/src/geometry/buffers/BufferBuilder.js +338 -0
  117. package/src/geometry/buffers/index.js +18 -0
  118. package/src/geometry/generators/Crystal.js +420 -0
  119. package/src/geometry/generators/Fractal.js +298 -0
  120. package/src/geometry/generators/KleinBottle.js +197 -0
  121. package/src/geometry/generators/Sphere.js +192 -0
  122. package/src/geometry/generators/Tesseract.js +160 -0
  123. package/src/geometry/generators/Tetrahedron.js +225 -0
  124. package/src/geometry/generators/Torus.js +304 -0
  125. package/src/geometry/generators/Wave.js +341 -0
  126. package/src/geometry/index.js +142 -0
  127. package/src/geometry/warp/HypersphereCore.js +211 -0
  128. package/src/geometry/warp/HypertetraCore.js +386 -0
  129. package/src/geometry/warp/index.js +57 -0
  130. package/src/holograms/HolographicVisualizer.js +1073 -0
  131. package/src/holograms/RealHolographicSystem.js +966 -0
  132. package/src/holograms/variantRegistry.js +69 -0
  133. package/src/integrations/FigmaPlugin.js +854 -0
  134. package/src/integrations/OBSMode.js +754 -0
  135. package/src/integrations/ThreeJsPackage.js +660 -0
  136. package/src/integrations/TouchDesignerExport.js +552 -0
  137. package/src/integrations/frameworks/Vib3React.js +591 -0
  138. package/src/integrations/frameworks/Vib3Svelte.js +654 -0
  139. package/src/integrations/frameworks/Vib3Vue.js +628 -0
  140. package/src/llm/LLMParameterInterface.js +240 -0
  141. package/src/llm/LLMParameterUI.js +577 -0
  142. package/src/math/Mat4x4.js +708 -0
  143. package/src/math/Projection.js +341 -0
  144. package/src/math/Rotor4D.js +637 -0
  145. package/src/math/Vec4.js +476 -0
  146. package/src/math/constants.js +164 -0
  147. package/src/math/index.js +68 -0
  148. package/src/math/projections.js +54 -0
  149. package/src/math/rotations.js +196 -0
  150. package/src/quantum/QuantumEngine.js +906 -0
  151. package/src/quantum/QuantumVisualizer.js +1103 -0
  152. package/src/reactivity/ReactivityConfig.js +499 -0
  153. package/src/reactivity/ReactivityManager.js +586 -0
  154. package/src/reactivity/SpatialInputSystem.js +1783 -0
  155. package/src/reactivity/index.js +93 -0
  156. package/src/render/CommandBuffer.js +465 -0
  157. package/src/render/MultiCanvasBridge.js +340 -0
  158. package/src/render/RenderCommand.js +514 -0
  159. package/src/render/RenderResourceRegistry.js +523 -0
  160. package/src/render/RenderState.js +552 -0
  161. package/src/render/RenderTarget.js +512 -0
  162. package/src/render/ShaderLoader.js +253 -0
  163. package/src/render/ShaderProgram.js +599 -0
  164. package/src/render/UnifiedRenderBridge.js +496 -0
  165. package/src/render/backends/WebGLBackend.js +1108 -0
  166. package/src/render/backends/WebGPUBackend.js +1409 -0
  167. package/src/render/commands/CommandBufferExecutor.js +607 -0
  168. package/src/render/commands/RenderCommandBuffer.js +661 -0
  169. package/src/render/commands/index.js +17 -0
  170. package/src/render/index.js +367 -0
  171. package/src/scene/Disposable.js +498 -0
  172. package/src/scene/MemoryPool.js +618 -0
  173. package/src/scene/Node4D.js +697 -0
  174. package/src/scene/ResourceManager.js +599 -0
  175. package/src/scene/Scene4D.js +540 -0
  176. package/src/scene/index.js +98 -0
  177. package/src/schemas/error.schema.json +84 -0
  178. package/src/schemas/extension.schema.json +88 -0
  179. package/src/schemas/index.js +214 -0
  180. package/src/schemas/parameters.schema.json +142 -0
  181. package/src/schemas/tool-pack.schema.json +44 -0
  182. package/src/schemas/tool-response.schema.json +127 -0
  183. package/src/shaders/common/fullscreen.vert.glsl +5 -0
  184. package/src/shaders/common/fullscreen.vert.wgsl +17 -0
  185. package/src/shaders/common/geometry24.glsl +65 -0
  186. package/src/shaders/common/geometry24.wgsl +54 -0
  187. package/src/shaders/common/rotation4d.glsl +85 -0
  188. package/src/shaders/common/rotation4d.wgsl +86 -0
  189. package/src/shaders/common/uniforms.glsl +44 -0
  190. package/src/shaders/common/uniforms.wgsl +48 -0
  191. package/src/shaders/faceted/faceted.frag.glsl +129 -0
  192. package/src/shaders/faceted/faceted.frag.wgsl +164 -0
  193. package/src/shaders/holographic/holographic.frag.glsl +406 -0
  194. package/src/shaders/holographic/holographic.frag.wgsl +185 -0
  195. package/src/shaders/quantum/quantum.frag.glsl +513 -0
  196. package/src/shaders/quantum/quantum.frag.wgsl +361 -0
  197. package/src/testing/ParallelTestFramework.js +519 -0
  198. package/src/testing/__snapshots__/exportFormats.test.js.snap +24 -0
  199. package/src/testing/exportFormats.test.js +8 -0
  200. package/src/testing/projections.test.js +14 -0
  201. package/src/testing/rotations.test.js +37 -0
  202. package/src/ui/InteractivityMenu.js +516 -0
  203. package/src/ui/StatusManager.js +96 -0
  204. package/src/ui/adaptive/renderers/webgpu/BufferLayout.ts +252 -0
  205. package/src/ui/adaptive/renderers/webgpu/PolytopeInstanceBuffer.ts +144 -0
  206. package/src/ui/adaptive/renderers/webgpu/TripleBufferedUniform.ts +170 -0
  207. package/src/ui/adaptive/renderers/webgpu/WebGPURenderer.ts +735 -0
  208. package/src/ui/adaptive/renderers/webgpu/index.ts +112 -0
  209. package/src/variations/VariationManager.js +431 -0
  210. package/src/viewer/AudioReactivity.js +505 -0
  211. package/src/viewer/CardBending.js +481 -0
  212. package/src/viewer/GalleryUI.js +832 -0
  213. package/src/viewer/ReactivityManager.js +590 -0
  214. package/src/viewer/TradingCardExporter.js +600 -0
  215. package/src/viewer/ViewerPortal.js +374 -0
  216. package/src/viewer/index.js +12 -0
  217. package/src/wasm/WasmLoader.js +296 -0
  218. package/src/wasm/index.js +132 -0
  219. package/tools/agentic/mcpTools.js +88 -0
  220. package/tools/cli/agent-cli.js +92 -0
  221. package/tools/export/formats.js +24 -0
  222. package/tools/math/rotation-baseline.mjs +64 -0
  223. package/tools/shader-sync-verify.js +937 -0
  224. package/tools/telemetry/manifestPipeline.js +141 -0
  225. package/tools/telemetry/telemetryEvents.js +35 -0
  226. package/types/adaptive-sdk.d.ts +185 -0
  227. package/types/advanced/AIPresetGenerator.d.ts +81 -0
  228. package/types/advanced/MIDIController.d.ts +100 -0
  229. package/types/advanced/OffscreenWorker.d.ts +82 -0
  230. package/types/advanced/WebGPUCompute.d.ts +52 -0
  231. package/types/advanced/WebXRRenderer.d.ts +77 -0
  232. package/types/advanced/index.d.ts +46 -0
  233. package/types/core/ErrorReporter.d.ts +50 -0
  234. package/types/core/VIB3Engine.d.ts +204 -0
  235. package/types/creative/ColorPresetsSystem.d.ts +91 -0
  236. package/types/creative/ParameterTimeline.d.ts +74 -0
  237. package/types/creative/PostProcessingPipeline.d.ts +109 -0
  238. package/types/creative/TransitionAnimator.d.ts +71 -0
  239. package/types/creative/index.d.ts +35 -0
  240. package/types/integrations/FigmaPlugin.d.ts +46 -0
  241. package/types/integrations/OBSMode.d.ts +74 -0
  242. package/types/integrations/ThreeJsPackage.d.ts +62 -0
  243. package/types/integrations/TouchDesignerExport.d.ts +36 -0
  244. package/types/integrations/Vib3React.d.ts +74 -0
  245. package/types/integrations/Vib3Svelte.d.ts +63 -0
  246. package/types/integrations/Vib3Vue.d.ts +55 -0
  247. package/types/integrations/index.d.ts +52 -0
  248. package/types/reactivity/SpatialInputSystem.d.ts +173 -0
  249. package/types/reactivity/index.d.ts +394 -0
  250. package/types/render/CommandBuffer.d.ts +169 -0
  251. package/types/render/RenderCommand.d.ts +312 -0
  252. package/types/render/RenderState.d.ts +279 -0
  253. package/types/render/RenderTarget.d.ts +254 -0
  254. package/types/render/ShaderProgram.d.ts +277 -0
  255. package/types/render/UnifiedRenderBridge.d.ts +143 -0
  256. package/types/render/WebGLBackend.d.ts +168 -0
  257. package/types/render/WebGPUBackend.d.ts +186 -0
  258. package/types/render/index.d.ts +141 -0
@@ -0,0 +1,499 @@
1
+ /**
2
+ * VIB3+ ReactivityConfig
3
+ *
4
+ * Unified configuration schema for all reactivity inputs:
5
+ * - Audio frequency band mappings
6
+ * - Device tilt/gyroscope mappings
7
+ * - Mouse/touch/click interaction modes
8
+ *
9
+ * This config is exported with VIB3Package for portable behavior.
10
+ */
11
+
12
+ /**
13
+ * Valid parameter names that can be targeted by reactivity
14
+ */
15
+ export const TARGETABLE_PARAMETERS = [
16
+ 'rot4dXY', 'rot4dXZ', 'rot4dYZ', // 3D rotations
17
+ 'rot4dXW', 'rot4dYW', 'rot4dZW', // 4D rotations
18
+ 'gridDensity', 'morphFactor', 'chaos', 'speed',
19
+ 'hue', 'intensity', 'saturation', 'dimension',
20
+ 'geometry'
21
+ ];
22
+
23
+ /**
24
+ * Audio band names
25
+ */
26
+ export const AUDIO_BANDS = ['bass', 'mid', 'high'];
27
+
28
+ /**
29
+ * Reactivity blend modes
30
+ */
31
+ export const BLEND_MODES = ['add', 'multiply', 'replace', 'max', 'min'];
32
+
33
+ /**
34
+ * Interaction modes for different input types
35
+ */
36
+ export const INTERACTION_MODES = {
37
+ mouse: ['rotation', 'velocity', 'shimmer', 'attract', 'repel', 'none'],
38
+ click: ['burst', 'blast', 'ripple', 'pulse', 'none'],
39
+ scroll: ['cycle', 'wave', 'sweep', 'zoom', 'morph', 'none']
40
+ };
41
+
42
+ /**
43
+ * Default ReactivityConfig
44
+ */
45
+ export const DEFAULT_REACTIVITY_CONFIG = {
46
+ version: '1.0',
47
+
48
+ audio: {
49
+ enabled: false,
50
+ globalSensitivity: 1.0,
51
+ smoothing: 0.8,
52
+ bands: {
53
+ bass: {
54
+ enabled: true,
55
+ sensitivity: 1.5,
56
+ frequencyRange: [20, 250],
57
+ targets: [
58
+ { param: 'morphFactor', weight: 0.8, mode: 'add' },
59
+ { param: 'intensity', weight: 0.3, mode: 'multiply' }
60
+ ]
61
+ },
62
+ mid: {
63
+ enabled: true,
64
+ sensitivity: 1.0,
65
+ frequencyRange: [250, 2000],
66
+ targets: [
67
+ { param: 'chaos', weight: 0.5, mode: 'add' }
68
+ ]
69
+ },
70
+ high: {
71
+ enabled: true,
72
+ sensitivity: 0.8,
73
+ frequencyRange: [2000, 20000],
74
+ targets: [
75
+ { param: 'speed', weight: 0.4, mode: 'add' },
76
+ { param: 'hue', weight: 15, mode: 'add' }
77
+ ]
78
+ }
79
+ }
80
+ },
81
+
82
+ tilt: {
83
+ enabled: false,
84
+ sensitivity: 1.0,
85
+ smoothing: 0.1,
86
+ dramaticMode: false,
87
+ calibrated: false,
88
+ calibrationOffset: { alpha: 0, beta: 0, gamma: 0 },
89
+ mappings: {
90
+ // Device axis -> rotation parameter
91
+ alpha: { target: 'rot4dXY', scale: 0.006, clamp: [-3.14, 3.14] },
92
+ beta: { target: 'rot4dXW', scale: 0.01, clamp: [-1.5, 1.5] },
93
+ gamma: { target: 'rot4dYW', scale: 0.015, clamp: [-1.5, 1.5] }
94
+ },
95
+ dramaticMappings: {
96
+ // 8x more sensitive for dramatic mode
97
+ alpha: { target: 'rot4dXY', scale: 0.048, clamp: [-6.28, 6.28] },
98
+ beta: { target: 'rot4dXW', scale: 0.08, clamp: [-6.0, 6.0] },
99
+ gamma: { target: 'rot4dYW', scale: 0.12, clamp: [-6.0, 6.0] }
100
+ }
101
+ },
102
+
103
+ interaction: {
104
+ enabled: true,
105
+
106
+ mouse: {
107
+ enabled: true,
108
+ mode: 'rotation',
109
+ sensitivity: 1.0,
110
+ smoothing: 0.15,
111
+ targets: ['rot4dXY', 'rot4dYZ'],
112
+ invertX: false,
113
+ invertY: false
114
+ },
115
+
116
+ click: {
117
+ enabled: true,
118
+ mode: 'burst',
119
+ intensity: 1.0,
120
+ decay: 0.92,
121
+ target: 'morphFactor',
122
+ maxValue: 2.0
123
+ },
124
+
125
+ scroll: {
126
+ enabled: true,
127
+ mode: 'cycle',
128
+ sensitivity: 1.0,
129
+ target: 'geometry',
130
+ wrap: true,
131
+ step: 1
132
+ },
133
+
134
+ touch: {
135
+ enabled: true,
136
+ multiTouchEnabled: true,
137
+ pinchZoom: { enabled: true, target: 'dimension', sensitivity: 0.01 },
138
+ twoFingerRotate: { enabled: true, target: 'rot4dZW', sensitivity: 0.02 },
139
+ swipeGestures: true
140
+ }
141
+ }
142
+ };
143
+
144
+ /**
145
+ * ReactivityConfig class
146
+ * Manages, validates, and serializes reactivity configuration
147
+ */
148
+ export class ReactivityConfig {
149
+ constructor(config = null) {
150
+ this.config = this.deepClone(DEFAULT_REACTIVITY_CONFIG);
151
+
152
+ if (config) {
153
+ this.merge(config);
154
+ }
155
+ }
156
+
157
+ /**
158
+ * Deep clone an object
159
+ */
160
+ deepClone(obj) {
161
+ return JSON.parse(JSON.stringify(obj));
162
+ }
163
+
164
+ /**
165
+ * Merge partial config into current config
166
+ */
167
+ merge(partialConfig) {
168
+ this.deepMerge(this.config, partialConfig);
169
+ return this;
170
+ }
171
+
172
+ /**
173
+ * Deep merge source into target
174
+ */
175
+ deepMerge(target, source) {
176
+ for (const key in source) {
177
+ if (source[key] && typeof source[key] === 'object' && !Array.isArray(source[key])) {
178
+ if (!target[key]) target[key] = {};
179
+ this.deepMerge(target[key], source[key]);
180
+ } else {
181
+ target[key] = source[key];
182
+ }
183
+ }
184
+ }
185
+
186
+ /**
187
+ * Validate the configuration
188
+ * @returns {{ valid: boolean, errors: string[] }}
189
+ */
190
+ validate() {
191
+ const errors = [];
192
+
193
+ // Validate audio config
194
+ if (this.config.audio) {
195
+ const audio = this.config.audio;
196
+
197
+ if (typeof audio.globalSensitivity !== 'number' ||
198
+ audio.globalSensitivity < 0 || audio.globalSensitivity > 10) {
199
+ errors.push('audio.globalSensitivity must be a number between 0 and 10');
200
+ }
201
+
202
+ for (const band of AUDIO_BANDS) {
203
+ if (audio.bands && audio.bands[band]) {
204
+ const bandConfig = audio.bands[band];
205
+
206
+ if (bandConfig.targets) {
207
+ for (const target of bandConfig.targets) {
208
+ if (!TARGETABLE_PARAMETERS.includes(target.param)) {
209
+ errors.push(`audio.bands.${band}.targets: invalid parameter "${target.param}"`);
210
+ }
211
+ if (!BLEND_MODES.includes(target.mode)) {
212
+ errors.push(`audio.bands.${band}.targets: invalid mode "${target.mode}"`);
213
+ }
214
+ }
215
+ }
216
+ }
217
+ }
218
+ }
219
+
220
+ // Validate tilt config
221
+ if (this.config.tilt) {
222
+ const tilt = this.config.tilt;
223
+
224
+ if (typeof tilt.sensitivity !== 'number' ||
225
+ tilt.sensitivity < 0.1 || tilt.sensitivity > 10) {
226
+ errors.push('tilt.sensitivity must be a number between 0.1 and 10');
227
+ }
228
+
229
+ if (tilt.mappings) {
230
+ for (const axis of ['alpha', 'beta', 'gamma']) {
231
+ if (tilt.mappings[axis] && tilt.mappings[axis].target) {
232
+ if (!TARGETABLE_PARAMETERS.includes(tilt.mappings[axis].target)) {
233
+ errors.push(`tilt.mappings.${axis}.target: invalid parameter`);
234
+ }
235
+ }
236
+ }
237
+ }
238
+ }
239
+
240
+ // Validate interaction config
241
+ if (this.config.interaction) {
242
+ const interaction = this.config.interaction;
243
+
244
+ if (interaction.mouse && interaction.mouse.mode) {
245
+ if (!INTERACTION_MODES.mouse.includes(interaction.mouse.mode)) {
246
+ errors.push(`interaction.mouse.mode: invalid mode "${interaction.mouse.mode}"`);
247
+ }
248
+ }
249
+
250
+ if (interaction.click && interaction.click.mode) {
251
+ if (!INTERACTION_MODES.click.includes(interaction.click.mode)) {
252
+ errors.push(`interaction.click.mode: invalid mode "${interaction.click.mode}"`);
253
+ }
254
+ }
255
+
256
+ if (interaction.scroll && interaction.scroll.mode) {
257
+ if (!INTERACTION_MODES.scroll.includes(interaction.scroll.mode)) {
258
+ errors.push(`interaction.scroll.mode: invalid mode "${interaction.scroll.mode}"`);
259
+ }
260
+ }
261
+ }
262
+
263
+ return {
264
+ valid: errors.length === 0,
265
+ errors
266
+ };
267
+ }
268
+
269
+ // ==================== GETTERS ====================
270
+
271
+ /**
272
+ * Get full config
273
+ */
274
+ getConfig() {
275
+ return this.deepClone(this.config);
276
+ }
277
+
278
+ /**
279
+ * Get audio config
280
+ */
281
+ getAudioConfig() {
282
+ return this.deepClone(this.config.audio);
283
+ }
284
+
285
+ /**
286
+ * Get tilt config
287
+ */
288
+ getTiltConfig() {
289
+ return this.deepClone(this.config.tilt);
290
+ }
291
+
292
+ /**
293
+ * Get interaction config
294
+ */
295
+ getInteractionConfig() {
296
+ return this.deepClone(this.config.interaction);
297
+ }
298
+
299
+ // ==================== SETTERS ====================
300
+
301
+ /**
302
+ * Enable/disable audio reactivity
303
+ */
304
+ setAudioEnabled(enabled) {
305
+ this.config.audio.enabled = !!enabled;
306
+ return this;
307
+ }
308
+
309
+ /**
310
+ * Set audio band configuration
311
+ */
312
+ setAudioBand(band, config) {
313
+ if (!AUDIO_BANDS.includes(band)) {
314
+ throw new Error(`Invalid audio band: ${band}`);
315
+ }
316
+ this.deepMerge(this.config.audio.bands[band], config);
317
+ return this;
318
+ }
319
+
320
+ /**
321
+ * Add a target to an audio band
322
+ */
323
+ addAudioTarget(band, param, weight = 1.0, mode = 'add') {
324
+ if (!AUDIO_BANDS.includes(band)) {
325
+ throw new Error(`Invalid audio band: ${band}`);
326
+ }
327
+ if (!TARGETABLE_PARAMETERS.includes(param)) {
328
+ throw new Error(`Invalid parameter: ${param}`);
329
+ }
330
+ if (!BLEND_MODES.includes(mode)) {
331
+ throw new Error(`Invalid blend mode: ${mode}`);
332
+ }
333
+
334
+ this.config.audio.bands[band].targets.push({ param, weight, mode });
335
+ return this;
336
+ }
337
+
338
+ /**
339
+ * Clear all targets from an audio band
340
+ */
341
+ clearAudioTargets(band) {
342
+ if (!AUDIO_BANDS.includes(band)) {
343
+ throw new Error(`Invalid audio band: ${band}`);
344
+ }
345
+ this.config.audio.bands[band].targets = [];
346
+ return this;
347
+ }
348
+
349
+ /**
350
+ * Enable/disable tilt reactivity
351
+ */
352
+ setTiltEnabled(enabled) {
353
+ this.config.tilt.enabled = !!enabled;
354
+ return this;
355
+ }
356
+
357
+ /**
358
+ * Set tilt dramatic mode
359
+ */
360
+ setTiltDramaticMode(enabled) {
361
+ this.config.tilt.dramaticMode = !!enabled;
362
+ return this;
363
+ }
364
+
365
+ /**
366
+ * Set tilt sensitivity
367
+ */
368
+ setTiltSensitivity(sensitivity) {
369
+ this.config.tilt.sensitivity = Math.max(0.1, Math.min(10, sensitivity));
370
+ return this;
371
+ }
372
+
373
+ /**
374
+ * Set tilt axis mapping
375
+ */
376
+ setTiltMapping(axis, target, scale, clamp = null) {
377
+ if (!['alpha', 'beta', 'gamma'].includes(axis)) {
378
+ throw new Error(`Invalid axis: ${axis}`);
379
+ }
380
+ if (!TARGETABLE_PARAMETERS.includes(target)) {
381
+ throw new Error(`Invalid parameter: ${target}`);
382
+ }
383
+
384
+ this.config.tilt.mappings[axis] = {
385
+ target,
386
+ scale,
387
+ clamp: clamp || [-6.28, 6.28]
388
+ };
389
+ return this;
390
+ }
391
+
392
+ /**
393
+ * Enable/disable interaction
394
+ */
395
+ setInteractionEnabled(enabled) {
396
+ this.config.interaction.enabled = !!enabled;
397
+ return this;
398
+ }
399
+
400
+ /**
401
+ * Set mouse interaction mode
402
+ */
403
+ setMouseMode(mode, options = {}) {
404
+ if (!INTERACTION_MODES.mouse.includes(mode)) {
405
+ throw new Error(`Invalid mouse mode: ${mode}`);
406
+ }
407
+ this.config.interaction.mouse.mode = mode;
408
+ this.deepMerge(this.config.interaction.mouse, options);
409
+ return this;
410
+ }
411
+
412
+ /**
413
+ * Set click interaction mode
414
+ */
415
+ setClickMode(mode, options = {}) {
416
+ if (!INTERACTION_MODES.click.includes(mode)) {
417
+ throw new Error(`Invalid click mode: ${mode}`);
418
+ }
419
+ this.config.interaction.click.mode = mode;
420
+ this.deepMerge(this.config.interaction.click, options);
421
+ return this;
422
+ }
423
+
424
+ /**
425
+ * Set scroll interaction mode
426
+ */
427
+ setScrollMode(mode, options = {}) {
428
+ if (!INTERACTION_MODES.scroll.includes(mode)) {
429
+ throw new Error(`Invalid scroll mode: ${mode}`);
430
+ }
431
+ this.config.interaction.scroll.mode = mode;
432
+ this.deepMerge(this.config.interaction.scroll, options);
433
+ return this;
434
+ }
435
+
436
+ // ==================== SERIALIZATION ====================
437
+
438
+ /**
439
+ * Export to JSON
440
+ */
441
+ toJSON() {
442
+ return JSON.stringify(this.config, null, 2);
443
+ }
444
+
445
+ /**
446
+ * Import from JSON
447
+ */
448
+ static fromJSON(json) {
449
+ const parsed = typeof json === 'string' ? JSON.parse(json) : json;
450
+ return new ReactivityConfig(parsed);
451
+ }
452
+
453
+ /**
454
+ * Export minimal config (only non-default values)
455
+ */
456
+ toMinimalJSON() {
457
+ const minimal = {};
458
+ const defaults = DEFAULT_REACTIVITY_CONFIG;
459
+
460
+ // Only include values that differ from defaults
461
+ this.extractDifferences(this.config, defaults, minimal);
462
+
463
+ return JSON.stringify(minimal, null, 2);
464
+ }
465
+
466
+ /**
467
+ * Extract differences between current and default config
468
+ */
469
+ extractDifferences(current, defaults, result) {
470
+ for (const key in current) {
471
+ if (typeof current[key] === 'object' && !Array.isArray(current[key])) {
472
+ const subResult = {};
473
+ this.extractDifferences(current[key], defaults[key] || {}, subResult);
474
+ if (Object.keys(subResult).length > 0) {
475
+ result[key] = subResult;
476
+ }
477
+ } else if (JSON.stringify(current[key]) !== JSON.stringify(defaults[key])) {
478
+ result[key] = current[key];
479
+ }
480
+ }
481
+ }
482
+
483
+ /**
484
+ * Create a copy
485
+ */
486
+ clone() {
487
+ return new ReactivityConfig(this.config);
488
+ }
489
+
490
+ /**
491
+ * Reset to defaults
492
+ */
493
+ reset() {
494
+ this.config = this.deepClone(DEFAULT_REACTIVITY_CONFIG);
495
+ return this;
496
+ }
497
+ }
498
+
499
+ export default ReactivityConfig;