@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,433 @@
1
+ /**
2
+ * Collection Manager - Auto-discovery system for JSON collections
3
+ * Scans collections/ folder for JSON files and loads them automatically
4
+ */
5
+ export class CollectionManager {
6
+ constructor() {
7
+ this.collections = new Map();
8
+ this.baseCollectionPath = './collections/';
9
+ this.loadingPromises = new Map();
10
+ }
11
+
12
+ /**
13
+ * Auto-discover and load all JSON collections from collections/ folder AND localStorage
14
+ * FIXED: Now checks both file-based and localStorage saved variations
15
+ */
16
+ async autoDiscoverCollections() {
17
+ console.log('🔍 Auto-discovering collections in collections/ folder AND localStorage...');
18
+
19
+ try {
20
+ // Method 1: Load known files first
21
+ const knownFiles = ['base-variations.json'];
22
+ const loadPromises = [];
23
+
24
+ for (const filename of knownFiles) {
25
+ loadPromises.push(
26
+ this.loadCollection(filename).catch(() => null)
27
+ );
28
+ }
29
+
30
+ // Wait for known files to load
31
+ await Promise.all(loadPromises);
32
+
33
+ // Method 2: CRITICAL FIX - Load user-saved variations from localStorage
34
+ await this.loadUserSavedVariations();
35
+
36
+ console.log(`✅ Auto-discovery complete: ${this.collections.size} collections loaded`);
37
+ console.log('📁 Includes both file-based and localStorage user variations');
38
+
39
+ return Array.from(this.collections.values());
40
+
41
+ } catch (error) {
42
+ console.error('❌ Collections auto-discovery error:', error);
43
+ // Still try to load localStorage variations even if file loading fails
44
+ await this.loadUserSavedVariations();
45
+ return Array.from(this.collections.values());
46
+ }
47
+ }
48
+
49
+ /**
50
+ * Load a specific collection from the collections/ folder
51
+ */
52
+ async loadCollection(filename) {
53
+ const fullPath = this.baseCollectionPath + filename;
54
+
55
+ // Avoid duplicate loading
56
+ if (this.loadingPromises.has(filename)) {
57
+ return this.loadingPromises.get(filename);
58
+ }
59
+
60
+ const loadPromise = this.fetchCollectionFile(fullPath, filename);
61
+ this.loadingPromises.set(filename, loadPromise);
62
+
63
+ try {
64
+ const collection = await loadPromise;
65
+ this.collections.set(filename, collection);
66
+ console.log(`📋 Loaded collection: ${collection.name} (${collection.variations.length} variations)`);
67
+ return collection;
68
+ } catch (error) {
69
+ console.log(`📁 Collection ${filename} not available (this is normal for user files)`);
70
+ this.loadingPromises.delete(filename);
71
+ throw error;
72
+ }
73
+ }
74
+
75
+ /**
76
+ * Fetch and parse a collection file
77
+ */
78
+ async fetchCollectionFile(fullPath, filename) {
79
+ const response = await fetch(fullPath);
80
+ if (!response.ok) {
81
+ throw new Error(`HTTP ${response.status}: ${response.statusText}`);
82
+ }
83
+
84
+ const data = await response.json();
85
+
86
+ // Validate collection format
87
+ if (!data.type || data.type !== 'holographic-collection') {
88
+ throw new Error('Invalid collection format: missing type');
89
+ }
90
+
91
+ if (!data.variations || !Array.isArray(data.variations)) {
92
+ throw new Error('Invalid collection format: missing variations array');
93
+ }
94
+
95
+ // Add metadata
96
+ data.filename = filename;
97
+ data.loadedAt = new Date().toISOString();
98
+
99
+ return data;
100
+ }
101
+
102
+ /**
103
+ * Get all loaded collections
104
+ */
105
+ getAllCollections() {
106
+ return Array.from(this.collections.values());
107
+ }
108
+
109
+ /**
110
+ * Get a specific collection by filename
111
+ */
112
+ getCollection(filename) {
113
+ return this.collections.get(filename);
114
+ }
115
+
116
+ /**
117
+ * Get all variations from all collections (flattened)
118
+ */
119
+ getAllVariations() {
120
+ const allVariations = [];
121
+ let currentId = 0;
122
+
123
+ for (const collection of this.collections.values()) {
124
+ for (const variation of collection.variations) {
125
+ allVariations.push({
126
+ ...variation,
127
+ id: currentId++,
128
+ collectionName: collection.name,
129
+ collectionFilename: collection.filename,
130
+ isFromCollection: true
131
+ });
132
+ }
133
+ }
134
+
135
+ return allVariations;
136
+ }
137
+
138
+ /**
139
+ * Save a new collection or append to existing user collection
140
+ */
141
+ async saveCollection(collection, filename) {
142
+ // Validate filename
143
+ if (!filename.endsWith('.json')) {
144
+ filename += '.json';
145
+ }
146
+
147
+ let formattedCollection;
148
+
149
+ // Check if we're appending to an existing user collection
150
+ const existingCollection = this.collections.get(filename);
151
+ if (existingCollection && filename.includes('user-custom-')) {
152
+ // Append to existing collection
153
+ const newVariations = [...existingCollection.variations, ...collection.variations];
154
+
155
+ // Update IDs to be sequential
156
+ newVariations.forEach((variation, index) => {
157
+ variation.id = index;
158
+ });
159
+
160
+ formattedCollection = {
161
+ ...existingCollection,
162
+ totalVariations: newVariations.length,
163
+ variations: newVariations,
164
+ updated: new Date().toISOString()
165
+ };
166
+
167
+ console.log(`📝 Appending to existing collection: ${existingCollection.name}`);
168
+ } else {
169
+ // Create new collection
170
+ formattedCollection = {
171
+ name: collection.name || 'Unnamed Collection',
172
+ description: collection.description || '',
173
+ version: '1.0',
174
+ type: 'holographic-collection',
175
+ profileName: collection.profileName || 'VIB34D System',
176
+ totalVariations: collection.variations.length,
177
+ created: new Date().toISOString(),
178
+ variations: collection.variations
179
+ };
180
+ }
181
+
182
+ // Convert to JSON
183
+ const jsonData = JSON.stringify(formattedCollection, null, 2);
184
+
185
+ // Create download (since we can't write directly to collections/)
186
+ const blob = new Blob([jsonData], { type: 'application/json' });
187
+ const url = URL.createObjectURL(blob);
188
+ const link = document.createElement('a');
189
+ link.href = url;
190
+ link.download = filename;
191
+ document.body.appendChild(link);
192
+ link.click();
193
+ document.body.removeChild(link);
194
+ URL.revokeObjectURL(url);
195
+
196
+ console.log(`💾 Collection saved: ${filename}`);
197
+ console.log(`📁 To use: Move ${filename} to collections/ folder and refresh gallery`);
198
+
199
+ // Update our internal collection if it exists
200
+ if (existingCollection) {
201
+ this.collections.set(filename, formattedCollection);
202
+ }
203
+
204
+ return formattedCollection;
205
+ }
206
+
207
+ /**
208
+ * Create a collection from custom variations
209
+ */
210
+ createCustomCollection(customVariations, name) {
211
+ const collection = {
212
+ name: name || `Custom Collection ${new Date().toLocaleDateString()}`,
213
+ description: 'User-created custom holographic variations',
214
+ version: '1.0',
215
+ type: 'holographic-collection',
216
+ profileName: 'Active Holographic Systems',
217
+ totalVariations: customVariations.length,
218
+ created: new Date().toISOString(),
219
+ variations: customVariations.map((cv, index) => ({
220
+ id: index,
221
+ name: cv.name || `Custom Variation ${index + 1}`,
222
+ isCustom: true,
223
+ parameters: {
224
+ geometryType: cv.params.geometry,
225
+ density: cv.params.density,
226
+ speed: cv.params.speed,
227
+ chaos: cv.params.chaos,
228
+ morph: cv.params.morph,
229
+ hue: cv.params.hue,
230
+ saturation: cv.params.saturation,
231
+ intensity: cv.params.intensity
232
+ }
233
+ }))
234
+ };
235
+
236
+ return collection;
237
+ }
238
+
239
+ /**
240
+ * CRITICAL FIX: Load user-saved variations from localStorage (UnifiedSaveManager storage)
241
+ * This bridges the gap between save system and gallery system
242
+ */
243
+ async loadUserSavedVariations() {
244
+ try {
245
+ // Check UnifiedSaveManager storage keys
246
+ const unifiedVariationsKey = 'vib34d-unified-variations';
247
+ const unifiedCollectionsKey = 'vib34d-unified-collections';
248
+
249
+ console.log('🔍 DIAGNOSTIC: Checking localStorage for user variations...');
250
+ console.log('🔍 Looking for keys:', unifiedVariationsKey, unifiedCollectionsKey);
251
+
252
+ // DIAGNOSTIC: Check what's actually in localStorage
253
+ const allKeys = Object.keys(localStorage).filter(k => k.includes('vib34d'));
254
+ console.log('🔍 All VIB34D localStorage keys found:', allKeys);
255
+
256
+ // Load unified variations
257
+ const storedVariations = localStorage.getItem(unifiedVariationsKey);
258
+ console.log('🔍 Raw variations data length:', storedVariations ? storedVariations.length : 'NULL');
259
+
260
+ if (storedVariations) {
261
+ const variations = JSON.parse(storedVariations);
262
+ console.log(`🔵 Found ${variations.length} user-saved variations in localStorage`);
263
+ console.log('🔍 First variation sample:', variations[0]);
264
+
265
+ if (variations.length > 0) {
266
+ // Group variations by date for tabs
267
+ const variationsByDate = {};
268
+ variations.forEach(variation => {
269
+ const date = new Date(variation.timestamp || variation.created || Date.now());
270
+ const dateKey = date.toISOString().split('T')[0]; // YYYY-MM-DD
271
+ const displayDate = date.toLocaleDateString('en-US', {
272
+ weekday: 'short',
273
+ year: 'numeric',
274
+ month: 'short',
275
+ day: 'numeric'
276
+ });
277
+
278
+ if (!variationsByDate[dateKey]) {
279
+ variationsByDate[dateKey] = {
280
+ displayDate,
281
+ variations: []
282
+ };
283
+ }
284
+ variationsByDate[dateKey].variations.push(variation);
285
+ });
286
+
287
+ // Create a unified collection with date-based organization
288
+ const userCollection = {
289
+ name: `User Saved Variations (${variations.length})`,
290
+ description: `Custom variations saved by user - organized by date`,
291
+ version: '1.0',
292
+ type: 'holographic-collection',
293
+ profileName: 'VIB34D User',
294
+ totalVariations: variations.length,
295
+ variationsByDate: variationsByDate, // Add date organization
296
+ created: new Date().toISOString(),
297
+ filename: 'user-saved-localStorage.json',
298
+ loadedAt: new Date().toISOString(),
299
+ variations: variations.map((variation, index) => ({
300
+ id: index + 100, // Start user variations at ID 100+
301
+ name: variation.name || `User Variation ${index + 1}`,
302
+ isCustom: true,
303
+ globalId: variation.id,
304
+ system: variation.system || 'faceted',
305
+ parameters: this.normalizeParameters(variation.parameters || {})
306
+ }))
307
+ };
308
+
309
+ // Add to collections
310
+ this.collections.set('user-saved-localStorage.json', userCollection);
311
+ console.log(`✅ Added user collection: ${userCollection.name}`);
312
+ } else {
313
+ console.log('⚠️ No variations found in parsed data - creating empty collection');
314
+ }
315
+ } else {
316
+ console.log('⚠️ No stored variations found in localStorage - this is normal for first-time users');
317
+ // Create a demo collection to prevent "No Collections Found" error
318
+ const demoCollection = {
319
+ name: 'Welcome to VIB34D Gallery (Demo)',
320
+ description: 'Save your first variation using the 💾 Save to Gallery button!',
321
+ version: '1.0',
322
+ type: 'holographic-collection',
323
+ profileName: 'VIB34D System',
324
+ totalVariations: 1,
325
+ created: new Date().toISOString(),
326
+ filename: 'demo-welcome.json',
327
+ loadedAt: new Date().toISOString(),
328
+ variations: [{
329
+ id: 0,
330
+ name: 'Demo - Save Your First!',
331
+ isDemo: true,
332
+ system: 'faceted',
333
+ parameters: {
334
+ geometryType: 1,
335
+ density: 25,
336
+ speed: 1.0,
337
+ chaos: 0.2,
338
+ morph: 0.5,
339
+ hue: 240,
340
+ saturation: 0.8,
341
+ intensity: 0.6,
342
+ rot4dXW: 0,
343
+ rot4dYW: 0,
344
+ rot4dZW: 0,
345
+ dimension: 3.8
346
+ }
347
+ }]
348
+ };
349
+ this.collections.set('demo-welcome.json', demoCollection);
350
+ console.log('✅ Added demo welcome collection');
351
+ }
352
+
353
+ // Load unified collections
354
+ const storedCollections = localStorage.getItem(unifiedCollectionsKey);
355
+ if (storedCollections) {
356
+ try {
357
+ const collectionsArray = JSON.parse(storedCollections);
358
+ console.log(`🔵 Found ${collectionsArray.length} user collections in localStorage`);
359
+
360
+ collectionsArray.forEach(([filename, collection]) => {
361
+ if (collection && collection.variations) {
362
+ // Ensure proper formatting
363
+ collection.filename = filename;
364
+ collection.loadedAt = new Date().toISOString();
365
+
366
+ // Normalize variation IDs to avoid conflicts
367
+ collection.variations.forEach((variation, index) => {
368
+ if (!variation.globalId) {
369
+ variation.globalId = `USER-${Date.now()}-${index}`;
370
+ }
371
+ });
372
+
373
+ this.collections.set(filename, collection);
374
+ console.log(`✅ Added localStorage collection: ${collection.name}`);
375
+ }
376
+ });
377
+ } catch (collectionsError) {
378
+ console.warn('⚠️ Error parsing stored collections:', collectionsError);
379
+ }
380
+ }
381
+
382
+ console.log(`📊 Total collections after localStorage load: ${this.collections.size}`);
383
+
384
+ } catch (error) {
385
+ console.error('❌ Error loading user-saved variations from localStorage:', error);
386
+ }
387
+ }
388
+
389
+ /**
390
+ * Normalize parameters to match expected gallery format
391
+ */
392
+ normalizeParameters(params) {
393
+ // Convert between different parameter formats
394
+ const normalized = {
395
+ geometryType: params.geometry || params.geometryType || 0,
396
+ density: params.gridDensity || params.density || 10,
397
+ speed: params.speed || 1.0,
398
+ chaos: params.chaos || 0,
399
+ morph: params.morphFactor || params.morph || 0,
400
+ hue: params.hue || 200,
401
+ saturation: params.saturation || 0.8,
402
+ intensity: params.intensity || 0.5,
403
+ // 4D rotation parameters
404
+ rot4dXW: params.rot4dXW || 0,
405
+ rot4dYW: params.rot4dYW || 0,
406
+ rot4dZW: params.rot4dZW || 0,
407
+ dimension: params.dimension || 3.8
408
+ };
409
+
410
+ return normalized;
411
+ }
412
+
413
+ /**
414
+ * Get collection statistics
415
+ */
416
+ getStatistics() {
417
+ const collections = Array.from(this.collections.values());
418
+ const stats = {
419
+ totalCollections: collections.length,
420
+ totalVariations: collections.reduce((sum, c) => sum + c.variations.length, 0),
421
+ customCollections: collections.filter(c => c.name.includes('User') || c.name.includes('Custom')).length,
422
+ baseCollections: collections.filter(c => c.name.includes('Base')).length,
423
+ collections: collections.map(c => ({
424
+ name: c.name,
425
+ filename: c.filename,
426
+ variationCount: c.variations.length,
427
+ created: c.created
428
+ }))
429
+ };
430
+
431
+ return stats;
432
+ }
433
+ }
@@ -0,0 +1,240 @@
1
+ /**
2
+ * Collection Manager - Auto-discovery system for JSON collections
3
+ * Scans collections/ folder for JSON files and loads them automatically
4
+ */
5
+ export class CollectionManager {
6
+ constructor() {
7
+ this.collections = new Map();
8
+ this.baseCollectionPath = './collections/';
9
+ this.loadingPromises = new Map();
10
+ }
11
+
12
+ /**
13
+ * Auto-discover and load all JSON collections from collections/ folder
14
+ */
15
+ async autoDiscoverCollections() {
16
+ console.log('🔍 Auto-discovering collections...');
17
+
18
+ // List of known collection files to try loading
19
+ const knownCollections = [
20
+ 'base-variations.json',
21
+ 'community-favorites.json',
22
+ 'dual-geometry-experiments.json',
23
+ 'holographic-gemstones.json',
24
+ 'special-variations.json',
25
+ 'geometric-dreams.json',
26
+ 'experimental-forms.json',
27
+ 'paul-custom-pack.json',
28
+ 'custom-variations.json'
29
+ ];
30
+
31
+ const loadPromises = knownCollections.map(filename =>
32
+ this.loadCollection(filename).catch(err => {
33
+ // Silently fail for missing files
34
+ console.log(`📁 Collection not found: ${filename}`);
35
+ return null;
36
+ })
37
+ );
38
+
39
+ // Also try to load any user-custom files with date pattern
40
+ const datePattern = /user-custom-\d{4}-\d{2}-\d{2}\.json$/;
41
+ for (let i = 0; i < 10; i++) {
42
+ const date = new Date();
43
+ date.setDate(date.getDate() - i);
44
+ const dateStr = date.toISOString().split('T')[0];
45
+ const filename = `user-custom-${dateStr}.json`;
46
+ loadPromises.push(
47
+ this.loadCollection(filename).catch(() => null)
48
+ );
49
+ }
50
+
51
+ const results = await Promise.allSettled(loadPromises);
52
+ const loadedCount = results.filter(r => r.status === 'fulfilled' && r.value).length;
53
+
54
+ console.log(`✅ Auto-discovery complete: ${loadedCount} collections loaded`);
55
+ return Array.from(this.collections.values());
56
+ }
57
+
58
+ /**
59
+ * Load a specific collection from the collections/ folder
60
+ */
61
+ async loadCollection(filename) {
62
+ const fullPath = this.baseCollectionPath + filename;
63
+
64
+ // Avoid duplicate loading
65
+ if (this.loadingPromises.has(filename)) {
66
+ return this.loadingPromises.get(filename);
67
+ }
68
+
69
+ const loadPromise = this.fetchCollectionFile(fullPath, filename);
70
+ this.loadingPromises.set(filename, loadPromise);
71
+
72
+ try {
73
+ const collection = await loadPromise;
74
+ this.collections.set(filename, collection);
75
+ console.log(`📋 Loaded collection: ${collection.name} (${collection.variations.length} variations)`);
76
+ return collection;
77
+ } catch (error) {
78
+ console.warn(`❌ Failed to load collection ${filename}:`, error.message);
79
+ this.loadingPromises.delete(filename);
80
+ throw error;
81
+ }
82
+ }
83
+
84
+ /**
85
+ * Fetch and parse a collection file
86
+ */
87
+ async fetchCollectionFile(fullPath, filename) {
88
+ const response = await fetch(fullPath);
89
+ if (!response.ok) {
90
+ throw new Error(`HTTP ${response.status}: ${response.statusText}`);
91
+ }
92
+
93
+ const data = await response.json();
94
+
95
+ // Validate collection format
96
+ if (!data.type || data.type !== 'holographic-collection') {
97
+ throw new Error('Invalid collection format: missing type');
98
+ }
99
+
100
+ if (!data.variations || !Array.isArray(data.variations)) {
101
+ throw new Error('Invalid collection format: missing variations array');
102
+ }
103
+
104
+ // Add metadata
105
+ data.filename = filename;
106
+ data.loadedAt = new Date().toISOString();
107
+
108
+ return data;
109
+ }
110
+
111
+ /**
112
+ * Get all loaded collections
113
+ */
114
+ getAllCollections() {
115
+ return Array.from(this.collections.values());
116
+ }
117
+
118
+ /**
119
+ * Get a specific collection by filename
120
+ */
121
+ getCollection(filename) {
122
+ return this.collections.get(filename);
123
+ }
124
+
125
+ /**
126
+ * Get all variations from all collections (flattened)
127
+ */
128
+ getAllVariations() {
129
+ const allVariations = [];
130
+ let currentId = 0;
131
+
132
+ for (const collection of this.collections.values()) {
133
+ for (const variation of collection.variations) {
134
+ allVariations.push({
135
+ ...variation,
136
+ id: currentId++,
137
+ collectionName: collection.name,
138
+ collectionFilename: collection.filename,
139
+ isFromCollection: true
140
+ });
141
+ }
142
+ }
143
+
144
+ return allVariations;
145
+ }
146
+
147
+ /**
148
+ * Save a new collection to the collections/ folder
149
+ */
150
+ async saveCollection(collection, filename) {
151
+ // Validate filename
152
+ if (!filename.endsWith('.json')) {
153
+ filename += '.json';
154
+ }
155
+
156
+ // Ensure proper collection format
157
+ const formattedCollection = {
158
+ name: collection.name || 'Unnamed Collection',
159
+ description: collection.description || '',
160
+ version: '1.0',
161
+ type: 'holographic-collection',
162
+ profileName: collection.profileName || 'Active Holographic Systems',
163
+ totalVariations: collection.variations.length,
164
+ created: new Date().toISOString(),
165
+ variations: collection.variations
166
+ };
167
+
168
+ // Convert to JSON
169
+ const jsonData = JSON.stringify(formattedCollection, null, 2);
170
+
171
+ // Create download (since we can't write directly to collections/)
172
+ const blob = new Blob([jsonData], { type: 'application/json' });
173
+ const url = URL.createObjectURL(blob);
174
+ const link = document.createElement('a');
175
+ link.href = url;
176
+ link.download = filename;
177
+ document.body.appendChild(link);
178
+ link.click();
179
+ document.body.removeChild(link);
180
+ URL.revokeObjectURL(url);
181
+
182
+ console.log(`💾 Collection saved: ${filename}`);
183
+ console.log(`📁 To use: Move ${filename} to collections/ folder and refresh`);
184
+
185
+ return formattedCollection;
186
+ }
187
+
188
+ /**
189
+ * Create a collection from custom variations
190
+ */
191
+ createCustomCollection(customVariations, name) {
192
+ const collection = {
193
+ name: name || `Custom Collection ${new Date().toLocaleDateString()}`,
194
+ description: 'User-created custom holographic variations',
195
+ version: '1.0',
196
+ type: 'holographic-collection',
197
+ profileName: 'Active Holographic Systems',
198
+ totalVariations: customVariations.length,
199
+ created: new Date().toISOString(),
200
+ variations: customVariations.map((cv, index) => ({
201
+ id: index,
202
+ name: cv.name || `Custom Variation ${index + 1}`,
203
+ isCustom: true,
204
+ parameters: {
205
+ geometryType: cv.params.geometry,
206
+ density: cv.params.density,
207
+ speed: cv.params.speed,
208
+ chaos: cv.params.chaos,
209
+ morph: cv.params.morph,
210
+ hue: cv.params.hue,
211
+ saturation: cv.params.saturation,
212
+ intensity: cv.params.intensity
213
+ }
214
+ }))
215
+ };
216
+
217
+ return collection;
218
+ }
219
+
220
+ /**
221
+ * Get collection statistics
222
+ */
223
+ getStatistics() {
224
+ const collections = Array.from(this.collections.values());
225
+ const stats = {
226
+ totalCollections: collections.length,
227
+ totalVariations: collections.reduce((sum, c) => sum + c.variations.length, 0),
228
+ customCollections: collections.filter(c => c.name.includes('Custom')).length,
229
+ baseCollections: collections.filter(c => c.name.includes('Base')).length,
230
+ collections: collections.map(c => ({
231
+ name: c.name,
232
+ filename: c.filename,
233
+ variationCount: c.variations.length,
234
+ created: c.created
235
+ }))
236
+ };
237
+
238
+ return stats;
239
+ }
240
+ }