@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,754 @@
1
+ /**
2
+ * VIB3+ OBS Transparent Background Mode
3
+ *
4
+ * Configures the VIB3+ engine for optimal capture in OBS Studio, either as
5
+ * a Browser Source with transparent background or as a Window Capture target.
6
+ *
7
+ * OBS Browser Sources support alpha transparency via CSS `background: transparent`
8
+ * and WebGL premultiplied alpha. This module sets up all canvases and the engine
9
+ * for seamless overlay compositing in OBS.
10
+ *
11
+ * Usage:
12
+ * import { Vib3OBSMode } from './integrations/OBSMode.js';
13
+ * const obsMode = new Vib3OBSMode(engine);
14
+ * obsMode.enable();
15
+ *
16
+ * // Generate OBS browser source URL with parameters:
17
+ * const url = Vib3OBSMode.generateBrowserSourceURL({
18
+ * system: 'quantum', geometry: 12, hue: 270
19
+ * });
20
+ *
21
+ * @module Vib3OBSMode
22
+ * @version 1.0.0
23
+ * @license All Rights Reserved - Clear Seas Solutions LLC
24
+ */
25
+
26
+ /**
27
+ * Default OBS configuration recommendations.
28
+ * @constant {Object}
29
+ */
30
+ const DEFAULT_OBS_CONFIG = {
31
+ /** Browser source width in pixels */
32
+ width: 1920,
33
+ /** Browser source height in pixels */
34
+ height: 1080,
35
+ /** Frames per second */
36
+ fps: 60,
37
+ /** Custom CSS to inject into the browser source */
38
+ css: 'body { background: transparent !important; overflow: hidden; margin: 0; padding: 0; }',
39
+ /** Whether to shut down the source when not visible */
40
+ shutdownWhenHidden: false,
41
+ /** Whether to refresh the browser when the scene becomes active */
42
+ refreshOnActivate: false,
43
+ /** Hardware acceleration */
44
+ hardwareAcceleration: true
45
+ };
46
+
47
+ /**
48
+ * Canvas IDs used by the holographic 5-layer system.
49
+ * @constant {string[]}
50
+ */
51
+ const HOLOGRAPHIC_CANVAS_IDS = [
52
+ 'background-canvas',
53
+ 'shadow-canvas',
54
+ 'content-canvas',
55
+ 'highlight-canvas',
56
+ 'accent-canvas'
57
+ ];
58
+
59
+ /**
60
+ * Valid capture modes for OBS.
61
+ * @constant {string[]}
62
+ */
63
+ const CAPTURE_MODES = ['browser-source', 'window-capture'];
64
+
65
+ /**
66
+ * Valid VIB3 parameter names accepted in URL query strings.
67
+ * @constant {string[]}
68
+ */
69
+ const URL_PARAM_NAMES = [
70
+ 'system', 'geometry', 'hue', 'saturation', 'intensity', 'speed',
71
+ 'gridDensity', 'morphFactor', 'chaos', 'dimension',
72
+ 'rot4dXY', 'rot4dXZ', 'rot4dYZ', 'rot4dXW', 'rot4dYW', 'rot4dZW'
73
+ ];
74
+
75
+ /**
76
+ * OBS integration mode for VIB3+ visualization engine.
77
+ *
78
+ * Provides methods to configure the engine for OBS capture, manage
79
+ * transparent backgrounds, hide UI elements, and generate browser
80
+ * source URLs with embedded parameters.
81
+ *
82
+ * @class
83
+ */
84
+ export class Vib3OBSMode {
85
+ /**
86
+ * Create an OBS mode controller for a VIB3Engine instance.
87
+ *
88
+ * @param {import('../core/VIB3Engine.js').VIB3Engine} engine - The VIB3 engine instance
89
+ * @param {object} [options={}] - OBS mode options
90
+ * @param {string} [options.captureMode='browser-source'] - Capture mode: 'browser-source' | 'window-capture'
91
+ * @param {boolean} [options.hideUI=true] - Whether to hide UI elements when enabled
92
+ * @param {boolean} [options.autoResize=true] - Automatically resize canvases to fill viewport
93
+ */
94
+ constructor(engine, options = {}) {
95
+ /**
96
+ * The VIB3Engine instance being controlled.
97
+ * @type {import('../core/VIB3Engine.js').VIB3Engine}
98
+ */
99
+ this.engine = engine;
100
+
101
+ /**
102
+ * Whether transparent background mode is currently active.
103
+ * @type {boolean}
104
+ */
105
+ this.transparentMode = false;
106
+
107
+ /**
108
+ * OBS capture mode.
109
+ * @type {string}
110
+ */
111
+ this.captureMode = options.captureMode || 'browser-source';
112
+ if (!CAPTURE_MODES.includes(this.captureMode)) {
113
+ console.warn(`[Vib3OBSMode] Unknown capture mode "${this.captureMode}", defaulting to "browser-source"`);
114
+ this.captureMode = 'browser-source';
115
+ }
116
+
117
+ /**
118
+ * Whether to hide UI elements when OBS mode is enabled.
119
+ * @type {boolean}
120
+ */
121
+ this.hideUI = options.hideUI !== false;
122
+
123
+ /**
124
+ * Whether to automatically resize canvases to fill the viewport.
125
+ * @type {boolean}
126
+ */
127
+ this.autoResize = options.autoResize !== false;
128
+
129
+ /**
130
+ * List of UI element selectors to hide/show.
131
+ * @type {string[]}
132
+ * @private
133
+ */
134
+ this._uiSelectors = [
135
+ '#controls-panel', '#control-panel', '.controls',
136
+ '#gallery-modal', '.gallery-modal',
137
+ '#toolbar', '.toolbar',
138
+ '#debug-panel', '.debug-panel',
139
+ '#mobile-debug', '.mobile-debug',
140
+ 'header', 'footer', 'nav',
141
+ '.vib3-ui', '#vib3-ui'
142
+ ];
143
+
144
+ /**
145
+ * Stored original styles for restoration on disable.
146
+ * @type {Map<Element, object>}
147
+ * @private
148
+ */
149
+ this._originalStyles = new Map();
150
+
151
+ /**
152
+ * Resize observer for auto-resize mode.
153
+ * @type {ResizeObserver|null}
154
+ * @private
155
+ */
156
+ this._resizeObserver = null;
157
+
158
+ /**
159
+ * Bound resize handler reference for cleanup.
160
+ * @type {Function|null}
161
+ * @private
162
+ */
163
+ this._resizeHandler = null;
164
+ }
165
+
166
+ /**
167
+ * Enable OBS capture mode.
168
+ *
169
+ * This method:
170
+ * - Sets transparent background on the document body
171
+ * - Configures all VIB3 canvases for premultiplied alpha
172
+ * - Hides all UI elements (if hideUI is true)
173
+ * - Sets up auto-resize to fill the browser viewport
174
+ * - Disables unnecessary visual effects (scrollbars, selection, etc.)
175
+ * - Applies capture-mode-specific optimizations
176
+ *
177
+ * @returns {boolean} Whether OBS mode was successfully enabled
178
+ */
179
+ enable() {
180
+ if (this.transparentMode) {
181
+ console.warn('[Vib3OBSMode] Already enabled');
182
+ return true;
183
+ }
184
+
185
+ try {
186
+ // Store and modify body styles
187
+ this._storeAndApplyBodyStyles();
188
+
189
+ // Configure canvases for transparency
190
+ this._configureCanvases();
191
+
192
+ // Hide UI elements
193
+ if (this.hideUI) {
194
+ this._hideUIElements();
195
+ }
196
+
197
+ // Set up auto-resize
198
+ if (this.autoResize) {
199
+ this._setupAutoResize();
200
+ }
201
+
202
+ // Apply capture-mode-specific settings
203
+ if (this.captureMode === 'browser-source') {
204
+ this._configureBrowserSource();
205
+ } else {
206
+ this._configureWindowCapture();
207
+ }
208
+
209
+ this.transparentMode = true;
210
+ console.log(`[Vib3OBSMode] Enabled (mode: ${this.captureMode})`);
211
+ return true;
212
+ } catch (err) {
213
+ console.error('[Vib3OBSMode] Failed to enable:', err);
214
+ return false;
215
+ }
216
+ }
217
+
218
+ /**
219
+ * Disable OBS capture mode and restore original state.
220
+ *
221
+ * Restores all modified styles, shows hidden UI elements,
222
+ * removes resize observers, and resets canvas configurations.
223
+ *
224
+ * @returns {boolean} Whether OBS mode was successfully disabled
225
+ */
226
+ disable() {
227
+ if (!this.transparentMode) {
228
+ console.warn('[Vib3OBSMode] Already disabled');
229
+ return true;
230
+ }
231
+
232
+ try {
233
+ // Restore body styles
234
+ this._restoreBodyStyles();
235
+
236
+ // Show hidden UI elements
237
+ this._showUIElements();
238
+
239
+ // Remove auto-resize
240
+ this._teardownAutoResize();
241
+
242
+ // Restore original styles from stored map
243
+ for (const [element, styles] of this._originalStyles) {
244
+ if (element && element.parentNode) {
245
+ Object.assign(element.style, styles);
246
+ }
247
+ }
248
+ this._originalStyles.clear();
249
+
250
+ this.transparentMode = false;
251
+ console.log('[Vib3OBSMode] Disabled');
252
+ return true;
253
+ } catch (err) {
254
+ console.error('[Vib3OBSMode] Failed to disable:', err);
255
+ return false;
256
+ }
257
+ }
258
+
259
+ /**
260
+ * Returns recommended OBS settings for capturing VIB3+ visualizations.
261
+ *
262
+ * The returned object includes settings for both Browser Source and
263
+ * Window Capture modes, along with scene composition tips.
264
+ *
265
+ * @returns {object} OBS configuration recommendations
266
+ */
267
+ getOBSConfig() {
268
+ const baseConfig = { ...DEFAULT_OBS_CONFIG };
269
+
270
+ return {
271
+ browserSource: {
272
+ ...baseConfig,
273
+ url: Vib3OBSMode.generateBrowserSourceURL(
274
+ this.engine ? {
275
+ system: this.engine.getCurrentSystem(),
276
+ ...this.engine.getAllParameters()
277
+ } : {}
278
+ ),
279
+ description: 'Add as Browser Source in OBS for transparent overlay',
280
+ setup: [
281
+ '1. Add a new Browser Source in OBS',
282
+ '2. Set the URL to the generated browser source URL',
283
+ `3. Set width to ${baseConfig.width} and height to ${baseConfig.height}`,
284
+ `4. Set FPS to ${baseConfig.fps}`,
285
+ '5. Add Custom CSS: ' + baseConfig.css,
286
+ '6. Enable "Shutdown source when not visible" for performance',
287
+ '7. Ensure "Hardware acceleration" is checked'
288
+ ]
289
+ },
290
+ windowCapture: {
291
+ description: 'Capture the browser window running VIB3+',
292
+ setup: [
293
+ '1. Open VIB3+ in a dedicated browser window',
294
+ '2. Enable OBS mode in the VIB3+ UI or via URL parameter (?obs=1)',
295
+ '3. Add a Window Capture source in OBS',
296
+ '4. Select the VIB3+ browser window',
297
+ '5. Use a Color Key or Chroma Key filter to remove the background',
298
+ '6. Alternatively, use "Window Capture (Xcomposite)" on Linux for alpha support'
299
+ ],
300
+ chromaKeySettings: {
301
+ keyColorType: 'Custom',
302
+ keyColor: '#000000',
303
+ similarity: 40,
304
+ smoothness: 80,
305
+ keyColorSpillReduction: 100
306
+ }
307
+ },
308
+ performanceTips: [
309
+ 'Use 1080p resolution for best performance/quality balance',
310
+ 'Reduce gridDensity below 30 for complex geometries',
311
+ 'Disable audio reactivity if not needed (saves CPU)',
312
+ 'Use "faceted" system for lowest GPU usage',
313
+ 'Use "quantum" system for most visual impact',
314
+ 'Close developer tools and other browser tabs',
315
+ 'Ensure hardware acceleration is enabled in the browser'
316
+ ],
317
+ sceneComposition: [
318
+ 'Place VIB3+ source above your camera/game capture',
319
+ 'Use "Screen" or "Add" blending mode for glowing effects',
320
+ 'Use low intensity (0.3-0.5) for subtle overlays',
321
+ 'Use high intensity (0.8-1.0) for full-screen backgrounds',
322
+ 'Combine with OBS Move Transition for animated scene switches'
323
+ ]
324
+ };
325
+ }
326
+
327
+ /**
328
+ * Check if OBS mode is currently enabled.
329
+ * @returns {boolean}
330
+ */
331
+ isEnabled() {
332
+ return this.transparentMode;
333
+ }
334
+
335
+ /**
336
+ * Get the current capture mode.
337
+ * @returns {string} 'browser-source' or 'window-capture'
338
+ */
339
+ getCaptureMode() {
340
+ return this.captureMode;
341
+ }
342
+
343
+ /**
344
+ * Switch capture mode while OBS mode is active.
345
+ * @param {string} mode - 'browser-source' or 'window-capture'
346
+ */
347
+ setCaptureMode(mode) {
348
+ if (!CAPTURE_MODES.includes(mode)) {
349
+ console.warn(`[Vib3OBSMode] Unknown capture mode: ${mode}`);
350
+ return;
351
+ }
352
+ const wasEnabled = this.transparentMode;
353
+ if (wasEnabled) this.disable();
354
+ this.captureMode = mode;
355
+ if (wasEnabled) this.enable();
356
+ }
357
+
358
+ // ========================================================================
359
+ // Static Methods
360
+ // ========================================================================
361
+
362
+ /**
363
+ * Generate a URL with query parameters for OBS Browser Source.
364
+ *
365
+ * The URL includes all specified VIB3 parameters as query string values,
366
+ * plus the `obs=1` flag to auto-enable OBS mode on load.
367
+ *
368
+ * @param {object} [params={}] - VIB3 parameter overrides
369
+ * @param {string} [params.system] - Visualization system
370
+ * @param {number} [params.geometry] - Geometry index (0-23)
371
+ * @param {number} [params.hue] - Color hue (0-360)
372
+ * @param {number} [params.saturation] - Saturation (0-1)
373
+ * @param {number} [params.intensity] - Intensity (0-1)
374
+ * @param {number} [params.speed] - Animation speed (0.1-3)
375
+ * @param {number} [params.gridDensity] - Pattern density (4-100)
376
+ * @param {number} [params.morphFactor] - Morph factor (0-2)
377
+ * @param {number} [params.chaos] - Chaos level (0-1)
378
+ * @param {number} [params.dimension] - Projection distance (3.0-4.5)
379
+ * @param {number} [params.rot4dXY] - XY rotation (radians)
380
+ * @param {number} [params.rot4dXZ] - XZ rotation (radians)
381
+ * @param {number} [params.rot4dYZ] - YZ rotation (radians)
382
+ * @param {number} [params.rot4dXW] - XW rotation (radians)
383
+ * @param {number} [params.rot4dYW] - YW rotation (radians)
384
+ * @param {number} [params.rot4dZW] - ZW rotation (radians)
385
+ * @param {string} [baseURL] - Base URL (defaults to current page or a placeholder)
386
+ * @returns {string} Complete URL with query parameters
387
+ * @example
388
+ * const url = Vib3OBSMode.generateBrowserSourceURL({
389
+ * system: 'quantum',
390
+ * geometry: 12,
391
+ * hue: 270,
392
+ * intensity: 0.8
393
+ * });
394
+ * // => "https://your-site.com/vib3/?obs=1&system=quantum&geometry=12&hue=270&intensity=0.8"
395
+ */
396
+ static generateBrowserSourceURL(params = {}, baseURL) {
397
+ // Determine base URL
398
+ let base;
399
+ if (baseURL) {
400
+ base = baseURL;
401
+ } else if (typeof window !== 'undefined' && window.location) {
402
+ base = window.location.origin + window.location.pathname;
403
+ } else {
404
+ base = 'https://your-vib3-deployment.com/';
405
+ }
406
+
407
+ // Build query string
408
+ const queryParts = ['obs=1'];
409
+
410
+ for (const key of URL_PARAM_NAMES) {
411
+ if (key in params && params[key] !== undefined && params[key] !== null) {
412
+ const value = params[key];
413
+ // Sanitize: only allow alphanumeric, dots, hyphens, and underscores
414
+ const sanitized = String(value).replace(/[^a-zA-Z0-9.\-_]/g, '');
415
+ if (sanitized.length > 0 && sanitized.length <= 50) {
416
+ queryParts.push(`${encodeURIComponent(key)}=${encodeURIComponent(sanitized)}`);
417
+ }
418
+ }
419
+ }
420
+
421
+ // Ensure base URL ends cleanly
422
+ const cleanBase = base.endsWith('/') ? base.slice(0, -1) : base;
423
+ return `${cleanBase}?${queryParts.join('&')}`;
424
+ }
425
+
426
+ /**
427
+ * Parse VIB3 parameters from a URL query string.
428
+ *
429
+ * Useful for initializing the engine from an OBS browser source URL.
430
+ *
431
+ * @param {string} [queryString] - URL query string (defaults to window.location.search)
432
+ * @returns {{ obs: boolean, params: object }} Parsed OBS flag and VIB3 parameters
433
+ * @example
434
+ * const { obs, params } = Vib3OBSMode.parseURLParams();
435
+ * if (obs) {
436
+ * obsMode.enable();
437
+ * engine.setParameters(params);
438
+ * }
439
+ */
440
+ static parseURLParams(queryString) {
441
+ const search = queryString || (typeof window !== 'undefined' ? window.location.search : '');
442
+ const urlParams = new URLSearchParams(search);
443
+
444
+ const obs = urlParams.get('obs') === '1';
445
+ const params = {};
446
+
447
+ for (const key of URL_PARAM_NAMES) {
448
+ const raw = urlParams.get(key);
449
+ if (raw !== null) {
450
+ if (key === 'system') {
451
+ // String parameter - validate against allowed systems
452
+ const sanitized = raw.replace(/[^a-zA-Z]/g, '').toLowerCase();
453
+ if (['quantum', 'faceted', 'holographic'].includes(sanitized)) {
454
+ params.system = sanitized;
455
+ }
456
+ } else {
457
+ // Numeric parameter - parse and validate
458
+ const value = parseFloat(raw);
459
+ if (Number.isFinite(value)) {
460
+ params[key] = value;
461
+ }
462
+ }
463
+ }
464
+ }
465
+
466
+ return { obs, params };
467
+ }
468
+
469
+ /**
470
+ * Returns the list of valid URL parameter names.
471
+ * @returns {string[]}
472
+ */
473
+ static getURLParamNames() {
474
+ return [...URL_PARAM_NAMES];
475
+ }
476
+
477
+ /**
478
+ * Returns the list of valid capture modes.
479
+ * @returns {string[]}
480
+ */
481
+ static getCaptureModes() {
482
+ return [...CAPTURE_MODES];
483
+ }
484
+
485
+ // ========================================================================
486
+ // Private Methods
487
+ // ========================================================================
488
+
489
+ /**
490
+ * Store original body styles and apply OBS transparent styles.
491
+ * @private
492
+ */
493
+ _storeAndApplyBodyStyles() {
494
+ if (typeof document === 'undefined') return;
495
+
496
+ const body = document.body;
497
+ const html = document.documentElement;
498
+
499
+ // Store originals
500
+ this._originalBodyStyles = {
501
+ background: body.style.background,
502
+ backgroundColor: body.style.backgroundColor,
503
+ overflow: body.style.overflow,
504
+ margin: body.style.margin,
505
+ padding: body.style.padding,
506
+ userSelect: body.style.userSelect,
507
+ cursor: body.style.cursor
508
+ };
509
+ this._originalHtmlStyles = {
510
+ background: html.style.background,
511
+ backgroundColor: html.style.backgroundColor,
512
+ overflow: html.style.overflow
513
+ };
514
+
515
+ // Apply transparent styles
516
+ body.style.background = 'transparent';
517
+ body.style.backgroundColor = 'transparent';
518
+ body.style.overflow = 'hidden';
519
+ body.style.margin = '0';
520
+ body.style.padding = '0';
521
+ body.style.userSelect = 'none';
522
+ body.style.cursor = 'none';
523
+
524
+ html.style.background = 'transparent';
525
+ html.style.backgroundColor = 'transparent';
526
+ html.style.overflow = 'hidden';
527
+ }
528
+
529
+ /**
530
+ * Restore original body styles.
531
+ * @private
532
+ */
533
+ _restoreBodyStyles() {
534
+ if (typeof document === 'undefined') return;
535
+
536
+ const body = document.body;
537
+ const html = document.documentElement;
538
+
539
+ if (this._originalBodyStyles) {
540
+ Object.assign(body.style, this._originalBodyStyles);
541
+ this._originalBodyStyles = null;
542
+ }
543
+ if (this._originalHtmlStyles) {
544
+ Object.assign(html.style, this._originalHtmlStyles);
545
+ this._originalHtmlStyles = null;
546
+ }
547
+ }
548
+
549
+ /**
550
+ * Configure all VIB3 canvases for transparent rendering.
551
+ * @private
552
+ */
553
+ _configureCanvases() {
554
+ if (typeof document === 'undefined') return;
555
+
556
+ // Find all VIB3 canvases
557
+ const canvasIds = [...HOLOGRAPHIC_CANVAS_IDS];
558
+ const allCanvases = document.querySelectorAll('canvas');
559
+
560
+ allCanvases.forEach(canvas => {
561
+ // Store original styles
562
+ this._originalStyles.set(canvas, {
563
+ background: canvas.style.background,
564
+ backgroundColor: canvas.style.backgroundColor
565
+ });
566
+
567
+ // Set transparent background
568
+ canvas.style.background = 'transparent';
569
+ canvas.style.backgroundColor = 'transparent';
570
+ });
571
+
572
+ // Also handle the main container
573
+ const container = document.getElementById('vib3-container');
574
+ if (container) {
575
+ this._originalStyles.set(container, {
576
+ background: container.style.background,
577
+ backgroundColor: container.style.backgroundColor
578
+ });
579
+ container.style.background = 'transparent';
580
+ container.style.backgroundColor = 'transparent';
581
+ }
582
+ }
583
+
584
+ /**
585
+ * Hide all UI elements.
586
+ * @private
587
+ */
588
+ _hideUIElements() {
589
+ if (typeof document === 'undefined') return;
590
+
591
+ for (const selector of this._uiSelectors) {
592
+ try {
593
+ const elements = document.querySelectorAll(selector);
594
+ elements.forEach(el => {
595
+ if (!this._originalStyles.has(el)) {
596
+ this._originalStyles.set(el, {
597
+ display: el.style.display,
598
+ visibility: el.style.visibility,
599
+ opacity: el.style.opacity
600
+ });
601
+ }
602
+ el.style.display = 'none';
603
+ });
604
+ } catch (e) {
605
+ // Selector might be invalid; skip silently
606
+ }
607
+ }
608
+ }
609
+
610
+ /**
611
+ * Show all previously hidden UI elements.
612
+ * @private
613
+ */
614
+ _showUIElements() {
615
+ if (typeof document === 'undefined') return;
616
+
617
+ for (const selector of this._uiSelectors) {
618
+ try {
619
+ const elements = document.querySelectorAll(selector);
620
+ elements.forEach(el => {
621
+ const original = this._originalStyles.get(el);
622
+ if (original) {
623
+ el.style.display = original.display || '';
624
+ el.style.visibility = original.visibility || '';
625
+ el.style.opacity = original.opacity || '';
626
+ }
627
+ });
628
+ } catch (e) {
629
+ // Skip invalid selectors
630
+ }
631
+ }
632
+ }
633
+
634
+ /**
635
+ * Set up automatic canvas resizing to fill the viewport.
636
+ * @private
637
+ */
638
+ _setupAutoResize() {
639
+ if (typeof window === 'undefined') return;
640
+
641
+ this._resizeHandler = () => {
642
+ const container = document.getElementById('vib3-container');
643
+ if (container) {
644
+ container.style.width = '100vw';
645
+ container.style.height = '100vh';
646
+ container.style.position = 'fixed';
647
+ container.style.top = '0';
648
+ container.style.left = '0';
649
+ }
650
+ };
651
+
652
+ window.addEventListener('resize', this._resizeHandler);
653
+ this._resizeHandler(); // Apply immediately
654
+ }
655
+
656
+ /**
657
+ * Remove auto-resize handlers.
658
+ * @private
659
+ */
660
+ _teardownAutoResize() {
661
+ if (typeof window === 'undefined') return;
662
+
663
+ if (this._resizeHandler) {
664
+ window.removeEventListener('resize', this._resizeHandler);
665
+ this._resizeHandler = null;
666
+ }
667
+
668
+ if (this._resizeObserver) {
669
+ this._resizeObserver.disconnect();
670
+ this._resizeObserver = null;
671
+ }
672
+ }
673
+
674
+ /**
675
+ * Apply Browser Source-specific optimizations.
676
+ * @private
677
+ */
678
+ _configureBrowserSource() {
679
+ if (typeof document === 'undefined') return;
680
+
681
+ // Prevent right-click context menu (distracting in OBS)
682
+ this._contextMenuHandler = (e) => e.preventDefault();
683
+ document.addEventListener('contextmenu', this._contextMenuHandler);
684
+
685
+ // Prevent text selection highlighting
686
+ document.body.style.webkitUserSelect = 'none';
687
+ document.body.style.userSelect = 'none';
688
+
689
+ // Disable scrolling
690
+ document.body.style.overflow = 'hidden';
691
+ document.documentElement.style.overflow = 'hidden';
692
+
693
+ // Add a meta tag to hint to the browser source that this supports transparency
694
+ const existingMeta = document.querySelector('meta[name="vib3-obs-mode"]');
695
+ if (!existingMeta) {
696
+ const meta = document.createElement('meta');
697
+ meta.name = 'vib3-obs-mode';
698
+ meta.content = 'transparent';
699
+ document.head.appendChild(meta);
700
+ this._obsMeta = meta;
701
+ }
702
+ }
703
+
704
+ /**
705
+ * Apply Window Capture-specific optimizations.
706
+ * @private
707
+ */
708
+ _configureWindowCapture() {
709
+ if (typeof document === 'undefined') return;
710
+
711
+ // For window capture, we use a solid black background
712
+ // that can be chroma-keyed in OBS
713
+ document.body.style.background = '#000000';
714
+ document.body.style.backgroundColor = '#000000';
715
+ document.documentElement.style.background = '#000000';
716
+
717
+ // Set window title for easy identification in OBS
718
+ if (typeof document !== 'undefined') {
719
+ this._originalTitle = document.title;
720
+ document.title = 'VIB3+ [OBS Capture]';
721
+ }
722
+ }
723
+
724
+ /**
725
+ * Clean up and destroy the OBS mode instance.
726
+ * Call this when the engine is being destroyed.
727
+ */
728
+ destroy() {
729
+ if (this.transparentMode) {
730
+ this.disable();
731
+ }
732
+
733
+ // Remove context menu handler
734
+ if (this._contextMenuHandler && typeof document !== 'undefined') {
735
+ document.removeEventListener('contextmenu', this._contextMenuHandler);
736
+ this._contextMenuHandler = null;
737
+ }
738
+
739
+ // Remove OBS meta tag
740
+ if (this._obsMeta && this._obsMeta.parentNode) {
741
+ this._obsMeta.parentNode.removeChild(this._obsMeta);
742
+ this._obsMeta = null;
743
+ }
744
+
745
+ // Restore window title
746
+ if (this._originalTitle && typeof document !== 'undefined') {
747
+ document.title = this._originalTitle;
748
+ this._originalTitle = null;
749
+ }
750
+
751
+ this._originalStyles.clear();
752
+ this.engine = null;
753
+ }
754
+ }