@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,937 @@
1
+ /**
2
+ * VIB3+ Shader Sync Verification Tool
3
+ * Ensures uniform consistency across all visualization systems
4
+ *
5
+ * Usage:
6
+ * Node.js (static analysis):
7
+ * node tools/shader-sync-verify.js
8
+ *
9
+ * Browser console (runtime):
10
+ * import { ShaderSyncVerifier } from './tools/shader-sync-verify.js';
11
+ * const verifier = new ShaderSyncVerifier();
12
+ * verifier.runFullAudit();
13
+ *
14
+ * This tool parses GLSL and WGSL shader source to extract uniform declarations,
15
+ * then compares across the Quantum, Faceted, and Holographic systems to flag
16
+ * missing, mismatched, or extra uniforms relative to the VIB3+ standard set.
17
+ */
18
+
19
+ // ---------------------------------------------------------------------------
20
+ // ShaderSyncVerifier
21
+ // ---------------------------------------------------------------------------
22
+
23
+ export class ShaderSyncVerifier {
24
+ constructor() {
25
+ /**
26
+ * The canonical VIB3+ uniform contract.
27
+ * Every system MUST declare the "required" set.
28
+ * "recommended" uniforms enable full audio/interaction reactivity.
29
+ * "optional" uniforms are system-specific extensions.
30
+ */
31
+ this.STANDARD_UNIFORMS = {
32
+ required: [
33
+ 'u_time', 'u_resolution', 'u_geometry',
34
+ 'u_rot4dXY', 'u_rot4dXZ', 'u_rot4dYZ',
35
+ 'u_rot4dXW', 'u_rot4dYW', 'u_rot4dZW',
36
+ 'u_gridDensity', 'u_morphFactor', 'u_chaos',
37
+ 'u_speed', 'u_hue', 'u_intensity', 'u_dimension'
38
+ ],
39
+ recommended: [
40
+ 'u_saturation', 'u_mouseIntensity', 'u_clickIntensity',
41
+ 'u_bass', 'u_mid', 'u_high'
42
+ ],
43
+ optional: [
44
+ 'u_mouse', 'u_roleIntensity', 'u_layerScale',
45
+ 'u_layerOpacity', 'u_layerColor', 'u_densityMult', 'u_speedMult'
46
+ ]
47
+ };
48
+
49
+ /** Map of system name -> { glslUniforms, wgslUniforms, sources } */
50
+ this.systems = new Map();
51
+ }
52
+
53
+ // -----------------------------------------------------------------------
54
+ // GLSL uniform parser
55
+ // -----------------------------------------------------------------------
56
+
57
+ /**
58
+ * Parse GLSL source code and extract all uniform declarations.
59
+ * Handles `uniform float u_foo;`, `uniform vec2 u_bar;`, etc.
60
+ * Returns an array of { name, type, qualifiers } objects.
61
+ *
62
+ * @param {string} source - GLSL shader source code
63
+ * @returns {{ name: string, type: string, qualifiers: string }[]}
64
+ */
65
+ parseGLSLUniforms(source) {
66
+ if (!source || typeof source !== 'string') return [];
67
+
68
+ const uniforms = [];
69
+ // Match: uniform <optional qualifiers> <type> <name> ;
70
+ // Handles optional precision qualifiers like `uniform highp float u_time;`
71
+ const uniformRegex = /uniform\s+((?:(?:lowp|mediump|highp)\s+)?)(float|int|bool|[ui]?vec[234]|mat[234](?:x[234])?|sampler(?:2D|3D|Cube))\s+(\w+)\s*;/g;
72
+
73
+ let match;
74
+ while ((match = uniformRegex.exec(source)) !== null) {
75
+ uniforms.push({
76
+ name: match[3],
77
+ type: match[2],
78
+ qualifiers: match[1].trim() || ''
79
+ });
80
+ }
81
+
82
+ return uniforms;
83
+ }
84
+
85
+ // -----------------------------------------------------------------------
86
+ // WGSL uniform parser
87
+ // -----------------------------------------------------------------------
88
+
89
+ /**
90
+ * Parse WGSL source code and extract struct fields used as uniforms.
91
+ * Looks for a struct definition (typically VIB3Uniforms) bound via
92
+ * `@group(0) @binding(0) var<uniform>`, then extracts its fields.
93
+ *
94
+ * Returns an array of { name, type } objects with names prefixed by `u_`
95
+ * so they can be compared against the GLSL convention. Padding fields
96
+ * (names starting with `_`) are excluded.
97
+ *
98
+ * @param {string} source - WGSL shader source code
99
+ * @returns {{ name: string, type: string }[]}
100
+ */
101
+ parseWGSLUniforms(source) {
102
+ if (!source || typeof source !== 'string') return [];
103
+
104
+ const uniforms = [];
105
+
106
+ // Step 1 - Find the struct name referenced by the uniform binding
107
+ const bindingRegex = /@group\s*\(\s*0\s*\)\s*@binding\s*\(\s*0\s*\)\s*var\s*<\s*uniform\s*>\s*\w+\s*:\s*(\w+)\s*;/;
108
+ const bindingMatch = bindingRegex.exec(source);
109
+ const structName = bindingMatch ? bindingMatch[1] : 'VIB3Uniforms';
110
+
111
+ // Step 2 - Extract the struct body
112
+ const structRegex = new RegExp(
113
+ `struct\\s+${structName}\\s*\\{([^}]+)\\}`,
114
+ 's'
115
+ );
116
+ const structMatch = structRegex.exec(source);
117
+ if (!structMatch) return uniforms;
118
+
119
+ const body = structMatch[1];
120
+
121
+ // Step 3 - Parse each field: name: type,
122
+ // Use a non-greedy type match that stops at comma, semicolon, or newline
123
+ const fieldRegex = /(\w+)\s*:\s*([^,}\n]+)/g;
124
+ let fieldMatch;
125
+ while ((fieldMatch = fieldRegex.exec(body)) !== null) {
126
+ const fieldName = fieldMatch[1].trim();
127
+ const fieldType = fieldMatch[2].trim().replace(/,\s*$/, '');
128
+
129
+ // Skip padding fields
130
+ if (fieldName.startsWith('_')) continue;
131
+
132
+ // Convert WGSL field name to u_ prefix for comparison
133
+ const uniformName = this._wgslFieldToUniform(fieldName);
134
+ uniforms.push({ name: uniformName, type: fieldType });
135
+ }
136
+
137
+ return uniforms;
138
+ }
139
+
140
+ /**
141
+ * Convert a WGSL struct field name to the GLSL u_ convention.
142
+ * e.g. "time" -> "u_time", "rot4dXY" -> "u_rot4dXY"
143
+ * @private
144
+ */
145
+ _wgslFieldToUniform(fieldName) {
146
+ if (fieldName.startsWith('u_')) return fieldName;
147
+ return 'u_' + fieldName;
148
+ }
149
+
150
+ // -----------------------------------------------------------------------
151
+ // System registration
152
+ // -----------------------------------------------------------------------
153
+
154
+ /**
155
+ * Register a visualization system's shader sources for verification.
156
+ *
157
+ * @param {string} name - System name (e.g. 'quantum', 'faceted', 'holographic')
158
+ * @param {object} sources
159
+ * @param {string} [sources.glslVertex] - GLSL vertex shader source
160
+ * @param {string} [sources.glslFragment] - GLSL fragment shader source
161
+ * @param {string} [sources.wgslVertex] - WGSL vertex shader source
162
+ * @param {string} [sources.wgslFragment] - WGSL fragment shader source
163
+ */
164
+ registerSystem(name, sources = {}) {
165
+ const glslUniforms = [
166
+ ...this.parseGLSLUniforms(sources.glslVertex || ''),
167
+ ...this.parseGLSLUniforms(sources.glslFragment || '')
168
+ ];
169
+
170
+ // Deduplicate by name (vertex + fragment may both declare same uniform)
171
+ const glslMap = new Map();
172
+ for (const u of glslUniforms) {
173
+ if (!glslMap.has(u.name)) glslMap.set(u.name, u);
174
+ }
175
+
176
+ const wgslUniforms = [
177
+ ...this.parseWGSLUniforms(sources.wgslVertex || ''),
178
+ ...this.parseWGSLUniforms(sources.wgslFragment || '')
179
+ ];
180
+ const wgslMap = new Map();
181
+ for (const u of wgslUniforms) {
182
+ if (!wgslMap.has(u.name)) wgslMap.set(u.name, u);
183
+ }
184
+
185
+ this.systems.set(name, {
186
+ glslUniforms: glslMap,
187
+ wgslUniforms: wgslMap,
188
+ sources
189
+ });
190
+ }
191
+
192
+ // -----------------------------------------------------------------------
193
+ // Verification
194
+ // -----------------------------------------------------------------------
195
+
196
+ /**
197
+ * Run verification across all registered systems.
198
+ *
199
+ * @returns {{
200
+ * systems: Object.<string, {
201
+ * glslUniforms: string[],
202
+ * wgslUniforms: string[],
203
+ * missingRequired: string[],
204
+ * missingRecommended: string[],
205
+ * extraUniforms: string[],
206
+ * glslWgslMismatch: { glslOnly: string[], wgslOnly: string[] }
207
+ * }>,
208
+ * crossSystemMismatch: { uniform: string, presentIn: string[], missingFrom: string[] }[],
209
+ * summary: string,
210
+ * passed: boolean
211
+ * }}
212
+ */
213
+ verify() {
214
+ const allRequired = new Set(this.STANDARD_UNIFORMS.required);
215
+ const allRecommended = new Set(this.STANDARD_UNIFORMS.recommended);
216
+ const allOptional = new Set(this.STANDARD_UNIFORMS.optional);
217
+ const allKnown = new Set([...allRequired, ...allRecommended, ...allOptional]);
218
+
219
+ const systemResults = {};
220
+ let overallPassed = true;
221
+
222
+ for (const [name, data] of this.systems) {
223
+ const glslNames = new Set(data.glslUniforms.keys());
224
+ const wgslNames = new Set(data.wgslUniforms.keys());
225
+ const allNames = new Set([...glslNames, ...wgslNames]);
226
+
227
+ // Required uniforms missing from GLSL fragment
228
+ const missingRequired = [...allRequired].filter(u => !glslNames.has(u));
229
+
230
+ // Recommended uniforms missing from GLSL fragment
231
+ const missingRecommended = [...allRecommended].filter(u => !glslNames.has(u));
232
+
233
+ // Extra uniforms not in any standard category
234
+ const extraUniforms = [...allNames].filter(u => !allKnown.has(u));
235
+
236
+ // GLSL vs WGSL mismatch (if both backends exist)
237
+ const glslOnly = [...glslNames].filter(u => wgslNames.size > 0 && !wgslNames.has(u));
238
+ const wgslOnly = [...wgslNames].filter(u => glslNames.size > 0 && !glslNames.has(u));
239
+
240
+ if (missingRequired.length > 0) overallPassed = false;
241
+
242
+ systemResults[name] = {
243
+ glslUniforms: [...glslNames].sort(),
244
+ wgslUniforms: [...wgslNames].sort(),
245
+ missingRequired,
246
+ missingRecommended,
247
+ extraUniforms,
248
+ glslWgslMismatch: { glslOnly, wgslOnly }
249
+ };
250
+ }
251
+
252
+ // Cross-system comparison: check which required/recommended uniforms
253
+ // are present in some systems but missing from others
254
+ const systemNames = [...this.systems.keys()];
255
+ const crossSystemMismatch = [];
256
+
257
+ const checkSet = [...allRequired, ...allRecommended];
258
+ for (const uniform of checkSet) {
259
+ const presentIn = [];
260
+ const missingFrom = [];
261
+
262
+ for (const sysName of systemNames) {
263
+ const data = this.systems.get(sysName);
264
+ const glslNames = new Set(data.glslUniforms.keys());
265
+ if (glslNames.has(uniform)) {
266
+ presentIn.push(sysName);
267
+ } else {
268
+ missingFrom.push(sysName);
269
+ }
270
+ }
271
+
272
+ if (presentIn.length > 0 && missingFrom.length > 0) {
273
+ crossSystemMismatch.push({ uniform, presentIn, missingFrom });
274
+ }
275
+ }
276
+
277
+ if (crossSystemMismatch.length > 0) overallPassed = false;
278
+
279
+ // Build summary
280
+ const summaryLines = [];
281
+ summaryLines.push(`VIB3+ Shader Sync Verification Report`);
282
+ summaryLines.push(`Systems checked: ${systemNames.join(', ')}`);
283
+ summaryLines.push(`Overall status: ${overallPassed ? 'PASSED' : 'FAILED'}`);
284
+ summaryLines.push('');
285
+
286
+ for (const [sysName, result] of Object.entries(systemResults)) {
287
+ summaryLines.push(`[${sysName}]`);
288
+ summaryLines.push(` GLSL uniforms: ${result.glslUniforms.length}`);
289
+ summaryLines.push(` WGSL uniforms: ${result.wgslUniforms.length}`);
290
+ if (result.missingRequired.length > 0) {
291
+ summaryLines.push(` MISSING REQUIRED: ${result.missingRequired.join(', ')}`);
292
+ }
293
+ if (result.missingRecommended.length > 0) {
294
+ summaryLines.push(` Missing recommended: ${result.missingRecommended.join(', ')}`);
295
+ }
296
+ if (result.extraUniforms.length > 0) {
297
+ summaryLines.push(` Extra (system-specific): ${result.extraUniforms.join(', ')}`);
298
+ }
299
+ if (result.glslWgslMismatch.glslOnly.length > 0) {
300
+ summaryLines.push(` GLSL only (no WGSL): ${result.glslWgslMismatch.glslOnly.join(', ')}`);
301
+ }
302
+ if (result.glslWgslMismatch.wgslOnly.length > 0) {
303
+ summaryLines.push(` WGSL only (no GLSL): ${result.glslWgslMismatch.wgslOnly.join(', ')}`);
304
+ }
305
+ summaryLines.push('');
306
+ }
307
+
308
+ if (crossSystemMismatch.length > 0) {
309
+ summaryLines.push('[Cross-System Inconsistencies]');
310
+ for (const m of crossSystemMismatch) {
311
+ summaryLines.push(` ${m.uniform}: present in [${m.presentIn.join(', ')}], missing from [${m.missingFrom.join(', ')}]`);
312
+ }
313
+ summaryLines.push('');
314
+ }
315
+
316
+ return {
317
+ systems: systemResults,
318
+ crossSystemMismatch,
319
+ summary: summaryLines.join('\n'),
320
+ passed: overallPassed
321
+ };
322
+ }
323
+
324
+ // -----------------------------------------------------------------------
325
+ // Console report
326
+ // -----------------------------------------------------------------------
327
+
328
+ /**
329
+ * Print a colour-coded report to the console.
330
+ * Works in both Node.js (ANSI codes) and browser (console.log styles).
331
+ */
332
+ printReport() {
333
+ const report = this.verify();
334
+ const isBrowser = typeof window !== 'undefined';
335
+
336
+ if (isBrowser) {
337
+ this._printBrowserReport(report);
338
+ } else {
339
+ this._printNodeReport(report);
340
+ }
341
+
342
+ return report;
343
+ }
344
+
345
+ /** @private */
346
+ _printBrowserReport(report) {
347
+ const headerStyle = 'font-weight:bold;font-size:14px;color:#64ff96;';
348
+ const sysStyle = 'font-weight:bold;font-size:12px;color:#00bfff;';
349
+ const okStyle = 'color:#64ff96;';
350
+ const warnStyle = 'color:#ffa500;';
351
+ const errStyle = 'color:#ff4444;font-weight:bold;';
352
+ const dimStyle = 'color:#888;';
353
+
354
+ console.log('%c=== VIB3+ Shader Sync Verification ===', headerStyle);
355
+ console.log('%cSystems: %s', dimStyle, [...this.systems.keys()].join(', '));
356
+ console.log(
357
+ `%c${report.passed ? 'PASSED' : 'FAILED'}`,
358
+ report.passed ? okStyle : errStyle
359
+ );
360
+
361
+ for (const [sysName, result] of Object.entries(report.systems)) {
362
+ console.log('%c--- %s ---', sysStyle, sysName);
363
+ console.log('%cGLSL uniforms (%d): %s', dimStyle,
364
+ result.glslUniforms.length, result.glslUniforms.join(', '));
365
+ console.log('%cWGSL uniforms (%d): %s', dimStyle,
366
+ result.wgslUniforms.length, result.wgslUniforms.join(', '));
367
+
368
+ if (result.missingRequired.length > 0) {
369
+ console.log('%cMISSING REQUIRED: %s', errStyle,
370
+ result.missingRequired.join(', '));
371
+ } else {
372
+ console.log('%cAll required uniforms present', okStyle);
373
+ }
374
+
375
+ if (result.missingRecommended.length > 0) {
376
+ console.log('%cMissing recommended: %s', warnStyle,
377
+ result.missingRecommended.join(', '));
378
+ }
379
+
380
+ if (result.extraUniforms.length > 0) {
381
+ console.log('%cExtra (system-specific): %s', dimStyle,
382
+ result.extraUniforms.join(', '));
383
+ }
384
+
385
+ if (result.glslWgslMismatch.glslOnly.length > 0) {
386
+ console.log('%cGLSL only (no WGSL): %s', warnStyle,
387
+ result.glslWgslMismatch.glslOnly.join(', '));
388
+ }
389
+ if (result.glslWgslMismatch.wgslOnly.length > 0) {
390
+ console.log('%cWGSL only (no GLSL): %s', warnStyle,
391
+ result.glslWgslMismatch.wgslOnly.join(', '));
392
+ }
393
+ }
394
+
395
+ if (report.crossSystemMismatch.length > 0) {
396
+ console.log('%c--- Cross-System Inconsistencies ---', errStyle);
397
+ for (const m of report.crossSystemMismatch) {
398
+ console.log(
399
+ '%c %s: present in [%s], missing from [%s]',
400
+ warnStyle, m.uniform,
401
+ m.presentIn.join(', '), m.missingFrom.join(', ')
402
+ );
403
+ }
404
+ }
405
+ }
406
+
407
+ /** @private */
408
+ _printNodeReport(report) {
409
+ const R = '\x1b[31m'; // red
410
+ const G = '\x1b[32m'; // green
411
+ const Y = '\x1b[33m'; // yellow
412
+ const C = '\x1b[36m'; // cyan
413
+ const D = '\x1b[90m'; // dim
414
+ const B = '\x1b[1m'; // bold
415
+ const X = '\x1b[0m'; // reset
416
+
417
+ console.log(`${B}${G}=== VIB3+ Shader Sync Verification ===${X}`);
418
+ console.log(`${D}Systems: ${[...this.systems.keys()].join(', ')}${X}`);
419
+ console.log(
420
+ report.passed
421
+ ? `${B}${G}PASSED${X}`
422
+ : `${B}${R}FAILED${X}`
423
+ );
424
+ console.log('');
425
+
426
+ for (const [sysName, result] of Object.entries(report.systems)) {
427
+ console.log(`${B}${C}--- ${sysName} ---${X}`);
428
+ console.log(`${D} GLSL uniforms (${result.glslUniforms.length}): ${result.glslUniforms.join(', ')}${X}`);
429
+ console.log(`${D} WGSL uniforms (${result.wgslUniforms.length}): ${result.wgslUniforms.join(', ')}${X}`);
430
+
431
+ if (result.missingRequired.length > 0) {
432
+ console.log(`${R} MISSING REQUIRED: ${result.missingRequired.join(', ')}${X}`);
433
+ } else {
434
+ console.log(`${G} All required uniforms present${X}`);
435
+ }
436
+
437
+ if (result.missingRecommended.length > 0) {
438
+ console.log(`${Y} Missing recommended: ${result.missingRecommended.join(', ')}${X}`);
439
+ }
440
+
441
+ if (result.extraUniforms.length > 0) {
442
+ console.log(`${D} Extra (system-specific): ${result.extraUniforms.join(', ')}${X}`);
443
+ }
444
+
445
+ if (result.glslWgslMismatch.glslOnly.length > 0) {
446
+ console.log(`${Y} GLSL only (no WGSL): ${result.glslWgslMismatch.glslOnly.join(', ')}${X}`);
447
+ }
448
+ if (result.glslWgslMismatch.wgslOnly.length > 0) {
449
+ console.log(`${Y} WGSL only (no GLSL): ${result.glslWgslMismatch.wgslOnly.join(', ')}${X}`);
450
+ }
451
+ console.log('');
452
+ }
453
+
454
+ if (report.crossSystemMismatch.length > 0) {
455
+ console.log(`${B}${R}--- Cross-System Inconsistencies ---${X}`);
456
+ for (const m of report.crossSystemMismatch) {
457
+ console.log(
458
+ `${Y} ${m.uniform}: present in [${m.presentIn.join(', ')}], missing from [${m.missingFrom.join(', ')}]${X}`
459
+ );
460
+ }
461
+ console.log('');
462
+ }
463
+ }
464
+
465
+ // -----------------------------------------------------------------------
466
+ // Runtime verification (browser only - live WebGL programs)
467
+ // -----------------------------------------------------------------------
468
+
469
+ /**
470
+ * Verify a live WebGL program's active uniforms against the standard set.
471
+ * Call from browser console after shaders are compiled and linked.
472
+ *
473
+ * @param {WebGLRenderingContext|WebGL2RenderingContext} gl - GL context
474
+ * @param {WebGLProgram} program - Compiled and linked shader program
475
+ * @param {string} [systemName='unknown'] - Name for reporting
476
+ * @returns {{ activeUniforms: string[], missingRequired: string[], missingRecommended: string[], passed: boolean }}
477
+ */
478
+ verifyRuntime(gl, program, systemName = 'unknown') {
479
+ if (!gl || !program) {
480
+ console.error('ShaderSyncVerifier.verifyRuntime: gl and program are required');
481
+ return { activeUniforms: [], missingRequired: [], missingRecommended: [], passed: false };
482
+ }
483
+
484
+ const numUniforms = gl.getProgramParameter(program, gl.ACTIVE_UNIFORMS);
485
+ const activeUniforms = [];
486
+
487
+ for (let i = 0; i < numUniforms; i++) {
488
+ const info = gl.getActiveUniform(program, i);
489
+ if (info) {
490
+ activeUniforms.push(info.name);
491
+ }
492
+ }
493
+
494
+ const activeSet = new Set(activeUniforms);
495
+
496
+ const missingRequired = this.STANDARD_UNIFORMS.required.filter(
497
+ u => !activeSet.has(u)
498
+ );
499
+ const missingRecommended = this.STANDARD_UNIFORMS.recommended.filter(
500
+ u => !activeSet.has(u)
501
+ );
502
+
503
+ const passed = missingRequired.length === 0;
504
+
505
+ // Console output
506
+ const isBrowser = typeof window !== 'undefined';
507
+ if (isBrowser) {
508
+ const style = passed
509
+ ? 'color:#64ff96;font-weight:bold;'
510
+ : 'color:#ff4444;font-weight:bold;';
511
+ console.log(`%cRuntime verification [${systemName}]: ${passed ? 'PASSED' : 'FAILED'}`, style);
512
+ console.log(` Active uniforms (${activeUniforms.length}):`, activeUniforms.sort().join(', '));
513
+ if (missingRequired.length > 0) {
514
+ console.log('%c MISSING REQUIRED: ' + missingRequired.join(', '), 'color:#ff4444;');
515
+ }
516
+ if (missingRecommended.length > 0) {
517
+ console.log('%c Missing recommended: ' + missingRecommended.join(', '), 'color:#ffa500;');
518
+ }
519
+ } else {
520
+ console.log(`Runtime verification [${systemName}]: ${passed ? 'PASSED' : 'FAILED'}`);
521
+ console.log(` Active uniforms (${activeUniforms.length}):`, activeUniforms.sort().join(', '));
522
+ if (missingRequired.length > 0) {
523
+ console.log(' MISSING REQUIRED:', missingRequired.join(', '));
524
+ }
525
+ if (missingRecommended.length > 0) {
526
+ console.log(' Missing recommended:', missingRecommended.join(', '));
527
+ }
528
+ }
529
+
530
+ return { activeUniforms, missingRequired, missingRecommended, passed };
531
+ }
532
+
533
+ // -----------------------------------------------------------------------
534
+ // Static analysis (no GL context needed)
535
+ // -----------------------------------------------------------------------
536
+
537
+ /**
538
+ * Analyse a single shader source without instantiating a verifier.
539
+ *
540
+ * @param {string} source - Shader source code (GLSL or WGSL)
541
+ * @param {'glsl'|'wgsl'} [language='glsl'] - Shader language
542
+ * @returns {{ uniforms: { name: string, type: string }[], language: string }}
543
+ */
544
+ static analyzeSource(source, language = 'glsl') {
545
+ const verifier = new ShaderSyncVerifier();
546
+ let uniforms;
547
+
548
+ if (language === 'wgsl') {
549
+ uniforms = verifier.parseWGSLUniforms(source);
550
+ } else {
551
+ uniforms = verifier.parseGLSLUniforms(source);
552
+ }
553
+
554
+ return { uniforms, language };
555
+ }
556
+ }
557
+
558
+
559
+ // ---------------------------------------------------------------------------
560
+ // Embedded shader sources for the three active VIB3+ systems
561
+ // ---------------------------------------------------------------------------
562
+ // These are extracted from the inline GLSL in each system's .js file so the
563
+ // tool can run as a standalone Node.js script without a browser.
564
+ // ---------------------------------------------------------------------------
565
+
566
+ /**
567
+ * Quantum system GLSL fragment shader uniforms (from QuantumVisualizer.js).
568
+ * The shader is defined inline in initShaders().
569
+ */
570
+ const QUANTUM_GLSL_FRAGMENT = `
571
+ precision highp float;
572
+ uniform vec2 u_resolution;
573
+ uniform float u_time;
574
+ uniform vec2 u_mouse;
575
+ uniform float u_geometry;
576
+ uniform float u_gridDensity;
577
+ uniform float u_morphFactor;
578
+ uniform float u_chaos;
579
+ uniform float u_speed;
580
+ uniform float u_hue;
581
+ uniform float u_intensity;
582
+ uniform float u_saturation;
583
+ uniform float u_dimension;
584
+ uniform float u_rot4dXY;
585
+ uniform float u_rot4dXZ;
586
+ uniform float u_rot4dYZ;
587
+ uniform float u_rot4dXW;
588
+ uniform float u_rot4dYW;
589
+ uniform float u_rot4dZW;
590
+ uniform float u_mouseIntensity;
591
+ uniform float u_clickIntensity;
592
+ uniform float u_roleIntensity;
593
+ void main() { gl_FragColor = vec4(0.0); }
594
+ `;
595
+
596
+ /**
597
+ * Faceted system GLSL fragment shader uniforms (from FacetedSystem.js).
598
+ */
599
+ const FACETED_GLSL_FRAGMENT = `
600
+ precision highp float;
601
+ uniform float u_time;
602
+ uniform vec2 u_resolution;
603
+ uniform float u_geometry;
604
+ uniform float u_rot4dXY;
605
+ uniform float u_rot4dXZ;
606
+ uniform float u_rot4dYZ;
607
+ uniform float u_rot4dXW;
608
+ uniform float u_rot4dYW;
609
+ uniform float u_rot4dZW;
610
+ uniform float u_dimension;
611
+ uniform float u_gridDensity;
612
+ uniform float u_morphFactor;
613
+ uniform float u_chaos;
614
+ uniform float u_hue;
615
+ uniform float u_intensity;
616
+ uniform float u_saturation;
617
+ uniform float u_speed;
618
+ uniform float u_mouseIntensity;
619
+ uniform float u_clickIntensity;
620
+ uniform float u_bass;
621
+ uniform float u_mid;
622
+ uniform float u_high;
623
+ void main() { gl_FragColor = vec4(0.0); }
624
+ `;
625
+
626
+ /**
627
+ * Faceted system WGSL fragment shader (from FacetedSystem.js inline).
628
+ */
629
+ const FACETED_WGSL_FRAGMENT = `
630
+ struct VIB3Uniforms {
631
+ time: f32,
632
+ _pad0: f32,
633
+ resolution: vec2<f32>,
634
+ geometry: f32,
635
+ rot4dXY: f32,
636
+ rot4dXZ: f32,
637
+ rot4dYZ: f32,
638
+ rot4dXW: f32,
639
+ rot4dYW: f32,
640
+ rot4dZW: f32,
641
+ dimension: f32,
642
+ gridDensity: f32,
643
+ morphFactor: f32,
644
+ chaos: f32,
645
+ speed: f32,
646
+ hue: f32,
647
+ intensity: f32,
648
+ saturation: f32,
649
+ mouseIntensity: f32,
650
+ clickIntensity: f32,
651
+ bass: f32,
652
+ mid: f32,
653
+ high: f32,
654
+ layerScale: f32,
655
+ layerOpacity: f32,
656
+ _pad1: f32,
657
+ layerColor: vec3<f32>,
658
+ densityMult: f32,
659
+ speedMult: f32,
660
+ _pad2: vec3<f32>,
661
+ };
662
+ @group(0) @binding(0) var<uniform> u: VIB3Uniforms;
663
+ `;
664
+
665
+ /**
666
+ * Holographic system GLSL fragment shader uniforms (from HolographicVisualizer.js).
667
+ * This system uses non-standard names for several uniforms.
668
+ */
669
+ const HOLOGRAPHIC_GLSL_FRAGMENT = `
670
+ precision highp float;
671
+ uniform vec2 u_resolution;
672
+ uniform float u_time;
673
+ uniform vec2 u_mouse;
674
+ uniform float u_geometry;
675
+ uniform float u_density;
676
+ uniform float u_speed;
677
+ uniform vec3 u_color;
678
+ uniform float u_intensity;
679
+ uniform float u_roleDensity;
680
+ uniform float u_roleSpeed;
681
+ uniform float u_colorShift;
682
+ uniform float u_chaosIntensity;
683
+ uniform float u_mouseIntensity;
684
+ uniform float u_clickIntensity;
685
+ uniform float u_densityVariation;
686
+ uniform float u_geometryType;
687
+ uniform float u_chaos;
688
+ uniform float u_morph;
689
+ uniform float u_touchMorph;
690
+ uniform float u_touchChaos;
691
+ uniform float u_scrollParallax;
692
+ uniform float u_gridDensityShift;
693
+ uniform float u_colorScrollShift;
694
+ uniform float u_audioDensityBoost;
695
+ uniform float u_audioMorphBoost;
696
+ uniform float u_audioSpeedBoost;
697
+ uniform float u_audioChaosBoost;
698
+ uniform float u_audioColorShift;
699
+ uniform float u_rot4dXY;
700
+ uniform float u_rot4dXZ;
701
+ uniform float u_rot4dYZ;
702
+ uniform float u_rot4dXW;
703
+ uniform float u_rot4dYW;
704
+ uniform float u_rot4dZW;
705
+ void main() { gl_FragColor = vec4(0.0); }
706
+ `;
707
+
708
+ /**
709
+ * Holographic system WGSL fragment shader (from holographic.frag.wgsl).
710
+ */
711
+ const HOLOGRAPHIC_WGSL_FRAGMENT = `
712
+ struct VIB3Uniforms {
713
+ time: f32,
714
+ _pad0: f32,
715
+ resolution: vec2<f32>,
716
+ geometry: f32,
717
+ rot4dXY: f32,
718
+ rot4dXZ: f32,
719
+ rot4dYZ: f32,
720
+ rot4dXW: f32,
721
+ rot4dYW: f32,
722
+ rot4dZW: f32,
723
+ dimension: f32,
724
+ gridDensity: f32,
725
+ morphFactor: f32,
726
+ chaos: f32,
727
+ speed: f32,
728
+ hue: f32,
729
+ intensity: f32,
730
+ saturation: f32,
731
+ mouseIntensity: f32,
732
+ clickIntensity: f32,
733
+ bass: f32,
734
+ mid: f32,
735
+ high: f32,
736
+ layerScale: f32,
737
+ layerOpacity: f32,
738
+ _pad1: f32,
739
+ layerColor: vec3<f32>,
740
+ densityMult: f32,
741
+ speedMult: f32,
742
+ _pad2: vec3<f32>,
743
+ };
744
+ @group(0) @binding(0) var<uniform> u: VIB3Uniforms;
745
+ `;
746
+
747
+ /**
748
+ * Quantum system WGSL fragment shader (from quantum.frag.wgsl).
749
+ */
750
+ const QUANTUM_WGSL_FRAGMENT = `
751
+ struct VIB3Uniforms {
752
+ time: f32,
753
+ _pad0: f32,
754
+ resolution: vec2<f32>,
755
+ geometry: f32,
756
+ rot4dXY: f32,
757
+ rot4dXZ: f32,
758
+ rot4dYZ: f32,
759
+ rot4dXW: f32,
760
+ rot4dYW: f32,
761
+ rot4dZW: f32,
762
+ dimension: f32,
763
+ gridDensity: f32,
764
+ morphFactor: f32,
765
+ chaos: f32,
766
+ speed: f32,
767
+ hue: f32,
768
+ intensity: f32,
769
+ saturation: f32,
770
+ mouseIntensity: f32,
771
+ clickIntensity: f32,
772
+ bass: f32,
773
+ mid: f32,
774
+ high: f32,
775
+ layerScale: f32,
776
+ layerOpacity: f32,
777
+ _pad1: f32,
778
+ layerColor: vec3<f32>,
779
+ densityMult: f32,
780
+ speedMult: f32,
781
+ _pad2: vec3<f32>,
782
+ };
783
+ @group(0) @binding(0) var<uniform> u: VIB3Uniforms;
784
+ `;
785
+
786
+
787
+ // ---------------------------------------------------------------------------
788
+ // runFullAudit - registers all 3 systems and runs verification
789
+ // ---------------------------------------------------------------------------
790
+
791
+ /**
792
+ * Register all three VIB3+ visualization systems and run a full audit.
793
+ * Returns the verification report object and prints to console.
794
+ *
795
+ * @returns {{ systems: object, crossSystemMismatch: object[], summary: string, passed: boolean }}
796
+ */
797
+ export function runFullAudit() {
798
+ const verifier = new ShaderSyncVerifier();
799
+
800
+ // Register Quantum system
801
+ verifier.registerSystem('quantum', {
802
+ glslFragment: QUANTUM_GLSL_FRAGMENT,
803
+ wgslFragment: QUANTUM_WGSL_FRAGMENT
804
+ });
805
+
806
+ // Register Faceted system
807
+ verifier.registerSystem('faceted', {
808
+ glslFragment: FACETED_GLSL_FRAGMENT,
809
+ wgslFragment: FACETED_WGSL_FRAGMENT
810
+ });
811
+
812
+ // Register Holographic system
813
+ verifier.registerSystem('holographic', {
814
+ glslFragment: HOLOGRAPHIC_GLSL_FRAGMENT,
815
+ wgslFragment: HOLOGRAPHIC_WGSL_FRAGMENT
816
+ });
817
+
818
+ const report = verifier.printReport();
819
+
820
+ // Generate the uniform matrix table
821
+ _printUniformMatrix(verifier, report);
822
+
823
+ return report;
824
+ }
825
+
826
+
827
+ /**
828
+ * Print a matrix showing which uniforms are present in which systems.
829
+ * @private
830
+ */
831
+ function _printUniformMatrix(verifier, report) {
832
+ const isBrowser = typeof window !== 'undefined';
833
+
834
+ // Collect every uniform name across all systems
835
+ const allUniforms = new Set();
836
+ for (const result of Object.values(report.systems)) {
837
+ for (const u of result.glslUniforms) allUniforms.add(u);
838
+ for (const u of result.wgslUniforms) allUniforms.add(u);
839
+ }
840
+ // Also include standard uniforms even if missing everywhere
841
+ for (const u of verifier.STANDARD_UNIFORMS.required) allUniforms.add(u);
842
+ for (const u of verifier.STANDARD_UNIFORMS.recommended) allUniforms.add(u);
843
+
844
+ const sortedUniforms = [...allUniforms].sort();
845
+ const systemNames = Object.keys(report.systems);
846
+
847
+ // Categorize
848
+ const requiredSet = new Set(verifier.STANDARD_UNIFORMS.required);
849
+ const recommendedSet = new Set(verifier.STANDARD_UNIFORMS.recommended);
850
+
851
+ if (isBrowser) {
852
+ console.log('%c=== Uniform Coverage Matrix ===', 'font-weight:bold;font-size:12px;color:#64ff96;');
853
+ console.table(
854
+ sortedUniforms.reduce((table, uniform) => {
855
+ const row = { uniform, category: requiredSet.has(uniform) ? 'required' : (recommendedSet.has(uniform) ? 'recommended' : 'extra') };
856
+ for (const sysName of systemNames) {
857
+ const result = report.systems[sysName];
858
+ const inGlsl = result.glslUniforms.includes(uniform);
859
+ const inWgsl = result.wgslUniforms.includes(uniform);
860
+ if (inGlsl && inWgsl) row[sysName] = 'GLSL+WGSL';
861
+ else if (inGlsl) row[sysName] = 'GLSL';
862
+ else if (inWgsl) row[sysName] = 'WGSL';
863
+ else row[sysName] = '---';
864
+ }
865
+ table.push(row);
866
+ return table;
867
+ }, [])
868
+ );
869
+ } else {
870
+ const G = '\x1b[32m';
871
+ const Y = '\x1b[33m';
872
+ const R = '\x1b[31m';
873
+ const D = '\x1b[90m';
874
+ const B = '\x1b[1m';
875
+ const X = '\x1b[0m';
876
+
877
+ console.log(`\n${B}${G}=== Uniform Coverage Matrix ===${X}\n`);
878
+
879
+ // Header
880
+ const nameCol = 28;
881
+ const catCol = 14;
882
+ const sysCol = 16;
883
+
884
+ let header = 'Uniform'.padEnd(nameCol) + 'Category'.padEnd(catCol);
885
+ for (const sysName of systemNames) {
886
+ header += sysName.padEnd(sysCol);
887
+ }
888
+ console.log(`${B}${header}${X}`);
889
+ console.log('-'.repeat(nameCol + catCol + sysCol * systemNames.length));
890
+
891
+ for (const uniform of sortedUniforms) {
892
+ const category = requiredSet.has(uniform) ? 'required'
893
+ : (recommendedSet.has(uniform) ? 'recommended' : 'extra');
894
+
895
+ let line = uniform.padEnd(nameCol);
896
+
897
+ if (category === 'required') line += `${R}${category.padEnd(catCol)}${X}`;
898
+ else if (category === 'recommended') line += `${Y}${category.padEnd(catCol)}${X}`;
899
+ else line += `${D}${category.padEnd(catCol)}${X}`;
900
+
901
+ for (const sysName of systemNames) {
902
+ const result = report.systems[sysName];
903
+ const inGlsl = result.glslUniforms.includes(uniform);
904
+ const inWgsl = result.wgslUniforms.includes(uniform);
905
+
906
+ let cell;
907
+ if (inGlsl && inWgsl) cell = `${G}GLSL+WGSL${X}`;
908
+ else if (inGlsl) cell = `${Y}GLSL${X}`;
909
+ else if (inWgsl) cell = `${Y}WGSL${X}`;
910
+ else cell = `${R}---${X}`;
911
+
912
+ // Pad accounting for ANSI codes
913
+ const visibleLen = cell.replace(/\x1b\[\d+m/g, '').length;
914
+ line += cell + ' '.repeat(Math.max(0, sysCol - visibleLen));
915
+ }
916
+
917
+ console.log(line);
918
+ }
919
+ console.log('');
920
+ }
921
+ }
922
+
923
+
924
+ // ---------------------------------------------------------------------------
925
+ // CLI entry point (Node.js)
926
+ // ---------------------------------------------------------------------------
927
+
928
+ const isNodeMain = typeof process !== 'undefined'
929
+ && typeof process.argv !== 'undefined'
930
+ && process.argv[1]
931
+ && (process.argv[1].endsWith('shader-sync-verify.js')
932
+ || process.argv[1].endsWith('shader-sync-verify'));
933
+
934
+ if (isNodeMain) {
935
+ const report = runFullAudit();
936
+ process.exit(report.passed ? 0 : 1);
937
+ }