@genart-dev/components 0.1.0

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.
package/dist/index.js ADDED
@@ -0,0 +1,3963 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __export = (target, all) => {
3
+ for (var name in all)
4
+ __defProp(target, name, { get: all[name], enumerable: true });
5
+ };
6
+
7
+ // src/components/js/index.ts
8
+ var js_exports = {};
9
+ __export(js_exports, {
10
+ animation: () => animation_default,
11
+ boids: () => boids_default,
12
+ canvasUtils: () => canvas_utils_default,
13
+ color: () => color_default,
14
+ colorAdvanced: () => color_advanced_default,
15
+ curl: () => curl_default,
16
+ distribution: () => distribution_default,
17
+ distributionAdvanced: () => distribution_advanced_default,
18
+ dla: () => dla_default,
19
+ easing: () => easing_default,
20
+ flowField: () => flow_field_default,
21
+ grid: () => grid_default,
22
+ gridAdvanced: () => grid_advanced_default,
23
+ lSystem: () => l_system_default,
24
+ math: () => math_default,
25
+ mathAdvanced: () => math_advanced_default,
26
+ matrix: () => matrix_default,
27
+ noise2d: () => noise_2d_default,
28
+ noise3d: () => noise_3d_default,
29
+ noise4d: () => noise_4d_default,
30
+ particle: () => particle_default,
31
+ particleForces: () => particle_forces_default,
32
+ physicsRk4: () => physics_rk4_default,
33
+ physicsSpring: () => physics_spring_default,
34
+ physicsVerlet: () => physics_verlet_default,
35
+ prng: () => prng_default,
36
+ prngUtils: () => prng_utils_default,
37
+ quadtree: () => quadtree_default,
38
+ reactionDiffusion: () => reaction_diffusion_default,
39
+ shape: () => shape_default,
40
+ shapeAdvanced: () => shape_advanced_default,
41
+ spatialHash: () => spatial_hash_default,
42
+ svgPath: () => svg_path_default,
43
+ turtle: () => turtle_default,
44
+ vector: () => vector_default,
45
+ wave: () => wave_default,
46
+ worley: () => worley_default
47
+ });
48
+
49
+ // src/components/js/prng.ts
50
+ var prng = {
51
+ name: "prng",
52
+ version: "1.0.0",
53
+ category: "randomness",
54
+ target: "js",
55
+ renderers: [],
56
+ code: `function mulberry32(a) {
57
+ return function() {
58
+ a |= 0; a = a + 0x6D2B79F5 | 0;
59
+ var t = Math.imul(a ^ a >>> 15, 1 | a);
60
+ t = t + Math.imul(t ^ t >>> 7, 61 | t) ^ t;
61
+ return ((t ^ t >>> 14) >>> 0) / 4294967296;
62
+ };
63
+ }
64
+
65
+ function sfc32(a, b, c, d) {
66
+ return function() {
67
+ a |= 0; b |= 0; c |= 0; d |= 0;
68
+ var t = (a + b | 0) + d | 0;
69
+ d = d + 1 | 0; a = b ^ (b >>> 9);
70
+ b = c + (c << 3) | 0; c = (c << 21 | c >>> 11);
71
+ c = c + t | 0;
72
+ return (t >>> 0) / 4294967296;
73
+ };
74
+ }
75
+ `,
76
+ exports: ["mulberry32", "sfc32"],
77
+ dependencies: [],
78
+ description: "Seeded pseudo-random number generators (mulberry32, sfc32).",
79
+ usage: `### prng \u2014 Seeded PRNGs
80
+
81
+ \`\`\`js
82
+ const rng = mulberry32(state.SEED);
83
+ rng(); // \u2192 0.0\u20131.0
84
+ \`\`\`
85
+
86
+ - **mulberry32(seed)** \u2014 fast 32-bit PRNG, good for most use cases
87
+ - **sfc32(a, b, c, d)** \u2014 higher quality, 4 seeds, passes PractRand
88
+ `
89
+ };
90
+ var prng_default = prng;
91
+
92
+ // src/components/js/prng-utils.ts
93
+ var prngUtils = {
94
+ name: "prng-utils",
95
+ version: "1.0.0",
96
+ category: "randomness",
97
+ target: "js",
98
+ renderers: [],
99
+ code: `function randomInt(rng, min, max) {
100
+ return Math.floor(rng() * (max - min + 1)) + min;
101
+ }
102
+
103
+ function randomFloat(rng, min, max) {
104
+ return rng() * (max - min) + min;
105
+ }
106
+
107
+ function randomGaussian(rng) {
108
+ var u = 0, v = 0;
109
+ while (u === 0) u = rng();
110
+ while (v === 0) v = rng();
111
+ return Math.sqrt(-2.0 * Math.log(u)) * Math.cos(2.0 * Math.PI * v);
112
+ }
113
+
114
+ function randomChoice(rng, arr) {
115
+ return arr[Math.floor(rng() * arr.length)];
116
+ }
117
+
118
+ function shuffle(rng, arr) {
119
+ var a = arr.slice();
120
+ for (var i = a.length - 1; i > 0; i--) {
121
+ var j = Math.floor(rng() * (i + 1));
122
+ var tmp = a[i]; a[i] = a[j]; a[j] = tmp;
123
+ }
124
+ return a;
125
+ }
126
+
127
+ function weightedChoice(rng, items, weights) {
128
+ var total = 0;
129
+ for (var i = 0; i < weights.length; i++) total += weights[i];
130
+ var r = rng() * total;
131
+ for (var i = 0; i < items.length; i++) {
132
+ r -= weights[i];
133
+ if (r <= 0) return items[i];
134
+ }
135
+ return items[items.length - 1];
136
+ }
137
+ `,
138
+ exports: ["randomInt", "randomFloat", "randomGaussian", "randomChoice", "shuffle", "weightedChoice"],
139
+ dependencies: ["prng"],
140
+ description: "RNG convenience wrappers (randomInt, randomFloat, shuffle, etc.).",
141
+ usage: `### prng-utils \u2014 RNG Convenience Wrappers
142
+
143
+ \`\`\`js
144
+ const rng = mulberry32(state.SEED);
145
+ randomInt(rng, 1, 10); // \u2192 integer in [1, 10]
146
+ randomFloat(rng, -1, 1); // \u2192 float in [-1, 1)
147
+ randomGaussian(rng); // \u2192 normally distributed float
148
+ randomChoice(rng, ['a','b']); // \u2192 random element
149
+ shuffle(rng, [1,2,3,4]); // \u2192 shuffled copy
150
+ \`\`\`
151
+ `
152
+ };
153
+ var prng_utils_default = prngUtils;
154
+
155
+ // src/components/js/noise-2d.ts
156
+ var noise2d = {
157
+ name: "noise-2d",
158
+ version: "1.0.0",
159
+ category: "noise",
160
+ target: "js",
161
+ renderers: [],
162
+ code: `function perlin2D(rng) {
163
+ var perm = new Uint8Array(512);
164
+ for (var i = 0; i < 256; i++) perm[i] = i;
165
+ for (var i = 255; i > 0; i--) {
166
+ var j = Math.floor(rng() * (i + 1));
167
+ var tmp = perm[i]; perm[i] = perm[j]; perm[j] = tmp;
168
+ }
169
+ for (var i = 0; i < 256; i++) perm[256 + i] = perm[i];
170
+ function fade(t) { return t * t * t * (t * (t * 6 - 15) + 10); }
171
+ function grad(hash, x, y) {
172
+ var h = hash & 3;
173
+ return ((h & 1) ? -x : x) + ((h & 2) ? -y : y);
174
+ }
175
+ return function(x, y) {
176
+ var xi = Math.floor(x) & 255, yi = Math.floor(y) & 255;
177
+ var xf = x - Math.floor(x), yf = y - Math.floor(y);
178
+ var u = fade(xf), v = fade(yf);
179
+ var a0 = perm[xi] + yi, a1 = perm[xi + 1] + yi;
180
+ var aa = grad(perm[a0], xf, yf), ba = grad(perm[a1], xf - 1, yf);
181
+ var ab = grad(perm[a0 + 1], xf, yf - 1), bb = grad(perm[a1 + 1], xf - 1, yf - 1);
182
+ var x1 = aa + u * (ba - aa), x2 = ab + u * (bb - ab);
183
+ return (x1 + v * (x2 - x1) + 1) / 2;
184
+ };
185
+ }
186
+
187
+ function simplex2D(rng) {
188
+ var perm = new Uint8Array(512);
189
+ for (var i = 0; i < 256; i++) perm[i] = i;
190
+ for (var i = 255; i > 0; i--) {
191
+ var j = Math.floor(rng() * (i + 1));
192
+ var tmp = perm[i]; perm[i] = perm[j]; perm[j] = tmp;
193
+ }
194
+ for (var i = 0; i < 256; i++) perm[256 + i] = perm[i];
195
+ var grad2 = [[1,1],[-1,1],[1,-1],[-1,-1],[1,0],[-1,0],[0,1],[0,-1]];
196
+ var F2 = 0.5 * (Math.sqrt(3) - 1), G2 = (3 - Math.sqrt(3)) / 6;
197
+ return function(x, y) {
198
+ var s = (x + y) * F2;
199
+ var i = Math.floor(x + s), j = Math.floor(y + s);
200
+ var t = (i + j) * G2;
201
+ var x0 = x - (i - t), y0 = y - (j - t);
202
+ var i1 = x0 > y0 ? 1 : 0, j1 = x0 > y0 ? 0 : 1;
203
+ var x1 = x0 - i1 + G2, y1 = y0 - j1 + G2;
204
+ var x2 = x0 - 1 + 2 * G2, y2 = y0 - 1 + 2 * G2;
205
+ var ii = i & 255, jj = j & 255;
206
+ function contrib(gx, gy, px, py) {
207
+ var t2 = 0.5 - px * px - py * py;
208
+ if (t2 < 0) return 0;
209
+ t2 *= t2;
210
+ return t2 * t2 * (gx * px + gy * py);
211
+ }
212
+ var g0 = grad2[perm[ii + perm[jj]] & 7];
213
+ var g1 = grad2[perm[ii + i1 + perm[jj + j1]] & 7];
214
+ var g2 = grad2[perm[ii + 1 + perm[jj + 1]] & 7];
215
+ return 0.5 + 35 * (contrib(g0[0], g0[1], x0, y0) + contrib(g1[0], g1[1], x1, y1) + contrib(g2[0], g2[1], x2, y2));
216
+ };
217
+ }
218
+
219
+ function valueNoise2D(rng) {
220
+ var values = new Float64Array(256);
221
+ for (var i = 0; i < 256; i++) values[i] = rng();
222
+ function hash(x, y) {
223
+ return values[((x * 374761393 + y * 668265263) & 0x7fffffff) % 256];
224
+ }
225
+ return function(x, y) {
226
+ var ix = Math.floor(x), iy = Math.floor(y);
227
+ var fx = x - ix, fy = y - iy;
228
+ fx = fx * fx * (3 - 2 * fx);
229
+ fy = fy * fy * (3 - 2 * fy);
230
+ var a = hash(ix, iy), b = hash(ix + 1, iy);
231
+ var c = hash(ix, iy + 1), d = hash(ix + 1, iy + 1);
232
+ return a + fx * (b - a) + fy * (c - a) + fx * fy * (a - b - c + d);
233
+ };
234
+ }
235
+
236
+ function fbm2D(noiseFn, octaves, lacunarity, gain) {
237
+ octaves = octaves || 6; lacunarity = lacunarity || 2; gain = gain || 0.5;
238
+ return function(x, y) {
239
+ var val = 0, amp = 1, freq = 1, mx = 0;
240
+ for (var o = 0; o < octaves; o++) {
241
+ val += amp * noiseFn(x * freq, y * freq);
242
+ mx += amp;
243
+ amp *= gain;
244
+ freq *= lacunarity;
245
+ }
246
+ return val / mx;
247
+ };
248
+ }
249
+ `,
250
+ exports: ["perlin2D", "simplex2D", "valueNoise2D", "fbm2D"],
251
+ dependencies: ["prng"],
252
+ description: "2D noise functions (Perlin, simplex, value) and fBm.",
253
+ usage: `### noise-2d \u2014 2D Noise Functions
254
+
255
+ \`\`\`js
256
+ var rng = mulberry32(state.SEED);
257
+ var noise = perlin2D(rng);
258
+ noise(x * 0.01, y * 0.01); // \u2192 0.0\u20131.0
259
+
260
+ var fbm = fbm2D(noise, 6, 2, 0.5);
261
+ fbm(x * 0.01, y * 0.01); // \u2192 fractal noise
262
+ \`\`\`
263
+ `
264
+ };
265
+ var noise_2d_default = noise2d;
266
+
267
+ // src/components/js/noise-3d.ts
268
+ var noise3d = {
269
+ name: "noise-3d",
270
+ version: "1.0.0",
271
+ category: "noise",
272
+ target: "js",
273
+ renderers: [],
274
+ code: `function perlin3D(rng) {
275
+ var perm = new Uint8Array(512);
276
+ for (var i = 0; i < 256; i++) perm[i] = i;
277
+ for (var i = 255; i > 0; i--) {
278
+ var j = Math.floor(rng() * (i + 1));
279
+ var tmp = perm[i]; perm[i] = perm[j]; perm[j] = tmp;
280
+ }
281
+ for (var i = 0; i < 256; i++) perm[256 + i] = perm[i];
282
+ function fade(t) { return t * t * t * (t * (t * 6 - 15) + 10); }
283
+ function grad(hash, x, y, z) {
284
+ var h = hash & 15;
285
+ var u = h < 8 ? x : y;
286
+ var v = h < 4 ? y : (h === 12 || h === 14 ? x : z);
287
+ return ((h & 1) ? -u : u) + ((h & 2) ? -v : v);
288
+ }
289
+ return function(x, y, z) {
290
+ var xi = Math.floor(x) & 255, yi = Math.floor(y) & 255, zi = Math.floor(z) & 255;
291
+ var xf = x - Math.floor(x), yf = y - Math.floor(y), zf = z - Math.floor(z);
292
+ var u = fade(xf), v = fade(yf), w = fade(zf);
293
+ var a = perm[xi]+yi, aa = perm[a]+zi, ab = perm[a+1]+zi;
294
+ var b = perm[xi+1]+yi, ba = perm[b]+zi, bb = perm[b+1]+zi;
295
+ return (
296
+ lerp(
297
+ lerp(lerp(grad(perm[aa],xf,yf,zf), grad(perm[ba],xf-1,yf,zf),u),
298
+ lerp(grad(perm[ab],xf,yf-1,zf), grad(perm[bb],xf-1,yf-1,zf),u),v),
299
+ lerp(lerp(grad(perm[aa+1],xf,yf,zf-1), grad(perm[ba+1],xf-1,yf,zf-1),u),
300
+ lerp(grad(perm[ab+1],xf,yf-1,zf-1), grad(perm[bb+1],xf-1,yf-1,zf-1),u),v),
301
+ w) + 1) / 2;
302
+ };
303
+ function lerp(a, b, t) { return a + t * (b - a); }
304
+ }
305
+
306
+ function simplex3D(rng) {
307
+ var perm = new Uint8Array(512);
308
+ for (var i = 0; i < 256; i++) perm[i] = i;
309
+ for (var i = 255; i > 0; i--) {
310
+ var j = Math.floor(rng() * (i + 1));
311
+ var tmp = perm[i]; perm[i] = perm[j]; perm[j] = tmp;
312
+ }
313
+ for (var i = 0; i < 256; i++) perm[256 + i] = perm[i];
314
+ var grad3 = [[1,1,0],[-1,1,0],[1,-1,0],[-1,-1,0],[1,0,1],[-1,0,1],[1,0,-1],[-1,0,-1],[0,1,1],[0,-1,1],[0,1,-1],[0,-1,-1]];
315
+ var F3 = 1/3, G3 = 1/6;
316
+ return function(x, y, z) {
317
+ var s = (x+y+z)*F3;
318
+ var i=Math.floor(x+s), j=Math.floor(y+s), k=Math.floor(z+s);
319
+ var t = (i+j+k)*G3;
320
+ var x0=x-(i-t), y0=y-(j-t), z0=z-(k-t);
321
+ var i1,j1,k1,i2,j2,k2;
322
+ if (x0>=y0) { if (y0>=z0) {i1=1;j1=0;k1=0;i2=1;j2=1;k2=0;} else if (x0>=z0) {i1=1;j1=0;k1=0;i2=1;j2=0;k2=1;} else {i1=0;j1=0;k1=1;i2=1;j2=0;k2=1;} }
323
+ else { if (y0<z0) {i1=0;j1=0;k1=1;i2=0;j2=1;k2=1;} else if (x0<z0) {i1=0;j1=1;k1=0;i2=0;j2=1;k2=1;} else {i1=0;j1=1;k1=0;i2=1;j2=1;k2=0;} }
324
+ var x1=x0-i1+G3, y1=y0-j1+G3, z1=z0-k1+G3;
325
+ var x2=x0-i2+2*G3, y2=y0-j2+2*G3, z2=z0-k2+2*G3;
326
+ var x3=x0-1+3*G3, y3=y0-1+3*G3, z3=z0-1+3*G3;
327
+ var ii=i&255, jj=j&255, kk=k&255;
328
+ function c(g, px, py, pz) { var t2=0.6-px*px-py*py-pz*pz; return t2<0?0:(t2*=t2, t2*t2*(g[0]*px+g[1]*py+g[2]*pz)); }
329
+ var n = c(grad3[perm[ii+perm[jj+perm[kk]]]%12], x0,y0,z0) + c(grad3[perm[ii+i1+perm[jj+j1+perm[kk+k1]]]%12], x1,y1,z1) + c(grad3[perm[ii+i2+perm[jj+j2+perm[kk+k2]]]%12], x2,y2,z2) + c(grad3[perm[ii+1+perm[jj+1+perm[kk+1]]]%12], x3,y3,z3);
330
+ return 0.5 + 16 * n;
331
+ };
332
+ }
333
+
334
+ function fbm3D(noiseFn, octaves, lacunarity, gain) {
335
+ octaves = octaves || 6; lacunarity = lacunarity || 2; gain = gain || 0.5;
336
+ return function(x, y, z) {
337
+ var val = 0, amp = 1, freq = 1, mx = 0;
338
+ for (var o = 0; o < octaves; o++) {
339
+ val += amp * noiseFn(x * freq, y * freq, z * freq);
340
+ mx += amp; amp *= gain; freq *= lacunarity;
341
+ }
342
+ return val / mx;
343
+ };
344
+ }
345
+ `,
346
+ exports: ["perlin3D", "simplex3D", "fbm3D"],
347
+ dependencies: ["prng"],
348
+ description: "3D noise functions (Perlin, simplex) and fBm.",
349
+ usage: `### noise-3d \u2014 3D Noise Functions
350
+
351
+ \`\`\`js
352
+ var noise = perlin3D(rng);
353
+ noise(x, y, z); // \u2192 0.0\u20131.0
354
+ var fbm = fbm3D(noise, 6);
355
+ \`\`\`
356
+ `
357
+ };
358
+ var noise_3d_default = noise3d;
359
+
360
+ // src/components/js/noise-4d.ts
361
+ var noise4d = {
362
+ name: "noise-4d",
363
+ version: "1.0.0",
364
+ category: "noise",
365
+ target: "js",
366
+ renderers: [],
367
+ code: `function simplex4D(rng) {
368
+ var perm = new Uint8Array(512);
369
+ for (var i = 0; i < 256; i++) perm[i] = i;
370
+ for (var i = 255; i > 0; i--) {
371
+ var j = Math.floor(rng() * (i + 1));
372
+ var tmp = perm[i]; perm[i] = perm[j]; perm[j] = tmp;
373
+ }
374
+ for (var i = 0; i < 256; i++) perm[256 + i] = perm[i];
375
+ var grad4 = [[0,1,1,1],[0,1,1,-1],[0,1,-1,1],[0,1,-1,-1],[0,-1,1,1],[0,-1,1,-1],[0,-1,-1,1],[0,-1,-1,-1],
376
+ [1,0,1,1],[1,0,1,-1],[1,0,-1,1],[1,0,-1,-1],[-1,0,1,1],[-1,0,1,-1],[-1,0,-1,1],[-1,0,-1,-1],
377
+ [1,1,0,1],[1,1,0,-1],[1,-1,0,1],[1,-1,0,-1],[-1,1,0,1],[-1,1,0,-1],[-1,-1,0,1],[-1,-1,0,-1],
378
+ [1,1,1,0],[1,1,-1,0],[1,-1,1,0],[1,-1,-1,0],[-1,1,1,0],[-1,1,-1,0],[-1,-1,1,0],[-1,-1,-1,0]];
379
+ var F4 = (Math.sqrt(5) - 1) / 4, G4 = (5 - Math.sqrt(5)) / 20;
380
+ return function(x, y, z, w) {
381
+ var s = (x+y+z+w) * F4;
382
+ var i=Math.floor(x+s), j=Math.floor(y+s), k=Math.floor(z+s), l=Math.floor(w+s);
383
+ var t = (i+j+k+l) * G4;
384
+ var x0=x-(i-t), y0=y-(j-t), z0=z-(k-t), w0=w-(l-t);
385
+ var rankx=0,ranky=0,rankz=0,rankw=0;
386
+ if(x0>y0)rankx++;else ranky++;
387
+ if(x0>z0)rankx++;else rankz++;
388
+ if(x0>w0)rankx++;else rankw++;
389
+ if(y0>z0)ranky++;else rankz++;
390
+ if(y0>w0)ranky++;else rankw++;
391
+ if(z0>w0)rankz++;else rankw++;
392
+ var i1=rankx>=3?1:0,j1=ranky>=3?1:0,k1=rankz>=3?1:0,l1=rankw>=3?1:0;
393
+ var i2=rankx>=2?1:0,j2=ranky>=2?1:0,k2=rankz>=2?1:0,l2=rankw>=2?1:0;
394
+ var i3=rankx>=1?1:0,j3=ranky>=1?1:0,k3=rankz>=1?1:0,l3=rankw>=1?1:0;
395
+ var x1=x0-i1+G4,y1=y0-j1+G4,z1=z0-k1+G4,w1=w0-l1+G4;
396
+ var x2=x0-i2+2*G4,y2=y0-j2+2*G4,z2=z0-k2+2*G4,w2=w0-l2+2*G4;
397
+ var x3=x0-i3+3*G4,y3=y0-j3+3*G4,z3=z0-k3+3*G4,w3=w0-l3+3*G4;
398
+ var x4=x0-1+4*G4,y4=y0-1+4*G4,z4=z0-1+4*G4,w4=w0-1+4*G4;
399
+ var ii=i&255,jj=j&255,kk=k&255,ll=l&255;
400
+ function c(g,px,py,pz,pw){var t2=0.6-px*px-py*py-pz*pz-pw*pw;return t2<0?0:(t2*=t2,t2*t2*(g[0]*px+g[1]*py+g[2]*pz+g[3]*pw));}
401
+ var n = c(grad4[perm[ii+perm[jj+perm[kk+perm[ll]]]]&31],x0,y0,z0,w0)
402
+ + c(grad4[perm[ii+i1+perm[jj+j1+perm[kk+k1+perm[ll+l1]]]]&31],x1,y1,z1,w1)
403
+ + c(grad4[perm[ii+i2+perm[jj+j2+perm[kk+k2+perm[ll+l2]]]]&31],x2,y2,z2,w2)
404
+ + c(grad4[perm[ii+i3+perm[jj+j3+perm[kk+k3+perm[ll+l3]]]]&31],x3,y3,z3,w3)
405
+ + c(grad4[perm[ii+1+perm[jj+1+perm[kk+1+perm[ll+1]]]]&31],x4,y4,z4,w4);
406
+ return 0.5 + 13.5 * n;
407
+ };
408
+ }
409
+ `,
410
+ exports: ["simplex4D"],
411
+ dependencies: ["prng"],
412
+ description: "4D simplex noise for loopable animations.",
413
+ usage: `### noise-4d \u2014 4D Simplex Noise
414
+
415
+ \`\`\`js
416
+ var noise = simplex4D(rng);
417
+ // Loopable: map time to a circle in 4D
418
+ var nx = noise(x, y, Math.cos(t) * r, Math.sin(t) * r);
419
+ \`\`\`
420
+ `
421
+ };
422
+ var noise_4d_default = noise4d;
423
+
424
+ // src/components/js/worley.ts
425
+ var worley = {
426
+ name: "worley",
427
+ version: "1.0.0",
428
+ category: "noise",
429
+ target: "js",
430
+ renderers: [],
431
+ code: `function worley2D(rng) {
432
+ var cache = {};
433
+ function cellPoint(ix, iy) {
434
+ var key = ix + ',' + iy;
435
+ if (!cache[key]) {
436
+ var a = ix * 374761393 + iy * 668265263;
437
+ a = (a ^ (a >> 13)) * 1274126177;
438
+ var seed = ((a ^ (a >> 16)) >>> 0);
439
+ var r = mulberry32(seed ^ Math.floor(rng() * 0x7fffffff));
440
+ cache[key] = [ix + r(), iy + r()];
441
+ }
442
+ return cache[key];
443
+ }
444
+ return function(x, y) {
445
+ var ix = Math.floor(x), iy = Math.floor(y);
446
+ var minDist = 1e10;
447
+ for (var dx = -1; dx <= 1; dx++) {
448
+ for (var dy = -1; dy <= 1; dy++) {
449
+ var p = cellPoint(ix + dx, iy + dy);
450
+ var d = (x - p[0]) * (x - p[0]) + (y - p[1]) * (y - p[1]);
451
+ if (d < minDist) minDist = d;
452
+ }
453
+ }
454
+ return Math.sqrt(minDist);
455
+ };
456
+ }
457
+
458
+ function worley3D(rng) {
459
+ var cache = {};
460
+ function cellPoint(ix, iy, iz) {
461
+ var key = ix + ',' + iy + ',' + iz;
462
+ if (!cache[key]) {
463
+ var a = ix * 374761393 + iy * 668265263 + iz * 1274126177;
464
+ a = (a ^ (a >> 13)) * 1103515245;
465
+ var seed = ((a ^ (a >> 16)) >>> 0);
466
+ var r = mulberry32(seed ^ Math.floor(rng() * 0x7fffffff));
467
+ cache[key] = [ix + r(), iy + r(), iz + r()];
468
+ }
469
+ return cache[key];
470
+ }
471
+ return function(x, y, z) {
472
+ var ix = Math.floor(x), iy = Math.floor(y), iz = Math.floor(z);
473
+ var minDist = 1e10;
474
+ for (var dx = -1; dx <= 1; dx++)
475
+ for (var dy = -1; dy <= 1; dy++)
476
+ for (var dz = -1; dz <= 1; dz++) {
477
+ var p = cellPoint(ix + dx, iy + dy, iz + dz);
478
+ var d = (x-p[0])*(x-p[0]) + (y-p[1])*(y-p[1]) + (z-p[2])*(z-p[2]);
479
+ if (d < minDist) minDist = d;
480
+ }
481
+ return Math.sqrt(minDist);
482
+ };
483
+ }
484
+ `,
485
+ exports: ["worley2D", "worley3D"],
486
+ dependencies: ["prng"],
487
+ description: "Worley/cellular noise (2D and 3D).",
488
+ usage: `### worley \u2014 Cellular Noise
489
+
490
+ \`\`\`js
491
+ var w = worley2D(rng);
492
+ w(x * 5, y * 5); // \u2192 distance to nearest cell point
493
+ \`\`\`
494
+ `
495
+ };
496
+ var worley_default = worley;
497
+
498
+ // src/components/js/curl.ts
499
+ var curl = {
500
+ name: "curl",
501
+ version: "1.0.0",
502
+ category: "noise",
503
+ target: "js",
504
+ renderers: [],
505
+ code: `function curlNoise2D(noiseFn, eps) {
506
+ eps = eps || 0.001;
507
+ return function(x, y) {
508
+ var dndx = (noiseFn(x + eps, y) - noiseFn(x - eps, y)) / (2 * eps);
509
+ var dndy = (noiseFn(x, y + eps) - noiseFn(x, y - eps)) / (2 * eps);
510
+ return [dndy, -dndx];
511
+ };
512
+ }
513
+
514
+ function curlNoise3D(noiseFnX, noiseFnY, noiseFnZ, eps) {
515
+ eps = eps || 0.001;
516
+ return function(x, y, z) {
517
+ var dzdy = (noiseFnZ(x, y + eps, z) - noiseFnZ(x, y - eps, z)) / (2 * eps);
518
+ var dydz = (noiseFnY(x, y, z + eps) - noiseFnY(x, y, z - eps)) / (2 * eps);
519
+ var dxdz = (noiseFnX(x, y, z + eps) - noiseFnX(x, y, z - eps)) / (2 * eps);
520
+ var dzdx = (noiseFnZ(x + eps, y, z) - noiseFnZ(x - eps, y, z)) / (2 * eps);
521
+ var dydx = (noiseFnY(x + eps, y, z) - noiseFnY(x - eps, y, z)) / (2 * eps);
522
+ var dxdy = (noiseFnX(x, y + eps, z) - noiseFnX(x, y - eps, z)) / (2 * eps);
523
+ return [dzdy - dydz, dxdz - dzdx, dydx - dxdy];
524
+ };
525
+ }
526
+ `,
527
+ exports: ["curlNoise2D", "curlNoise3D"],
528
+ dependencies: ["noise-2d", "noise-3d"],
529
+ description: "Curl noise for divergence-free flow fields.",
530
+ usage: `### curl \u2014 Curl Noise
531
+
532
+ \`\`\`js
533
+ var noise = perlin2D(rng);
534
+ var curl = curlNoise2D(noise);
535
+ var [vx, vy] = curl(x, y); // divergence-free velocity
536
+ \`\`\`
537
+ `
538
+ };
539
+ var curl_default = curl;
540
+
541
+ // src/components/js/math.ts
542
+ var math = {
543
+ name: "math",
544
+ version: "1.0.0",
545
+ category: "math",
546
+ target: "js",
547
+ renderers: [],
548
+ code: `function lerp(a, b, t) { return a + t * (b - a); }
549
+ function clamp(v, lo, hi) { return v < lo ? lo : v > hi ? hi : v; }
550
+ function clamp01(v) { return v < 0 ? 0 : v > 1 ? 1 : v; }
551
+ function remap(v, inLo, inHi, outLo, outHi) {
552
+ return outLo + (v - inLo) / (inHi - inLo) * (outHi - outLo);
553
+ }
554
+ function smoothstep(edge0, edge1, x) {
555
+ var t = clamp((x - edge0) / (edge1 - edge0), 0, 1);
556
+ return t * t * (3 - 2 * t);
557
+ }
558
+ function inverseLerp(a, b, v) { return (v - a) / (b - a); }
559
+ function mod(a, n) { return ((a % n) + n) % n; }
560
+ function fract(x) { return x - Math.floor(x); }
561
+ function sign0(x) { return x > 0 ? 1 : x < 0 ? -1 : 0; }
562
+ function step(edge, x) { return x < edge ? 0 : 1; }
563
+ `,
564
+ exports: ["lerp", "clamp", "clamp01", "remap", "smoothstep", "inverseLerp", "mod", "fract", "sign0", "step"],
565
+ dependencies: [],
566
+ description: "Core math utilities (lerp, clamp, smoothstep, remap, etc.).",
567
+ usage: `### math \u2014 Core Math Utilities
568
+
569
+ \`\`\`js
570
+ lerp(0, 100, 0.5); // \u2192 50
571
+ clamp(1.5, 0, 1); // \u2192 1
572
+ smoothstep(0, 1, 0.5); // \u2192 0.5 (S-curve)
573
+ remap(0.5, 0, 1, -10, 10); // \u2192 0
574
+ \`\`\`
575
+ `
576
+ };
577
+ var math_default = math;
578
+
579
+ // src/components/js/math-advanced.ts
580
+ var mathAdvanced = {
581
+ name: "math-advanced",
582
+ version: "1.0.0",
583
+ category: "math",
584
+ target: "js",
585
+ renderers: [],
586
+ code: `var PHI = (1 + Math.sqrt(5)) / 2;
587
+ var goldenRatio = PHI;
588
+
589
+ function bezierPoint(a, b, c, d, t) {
590
+ var t2 = t * t, t3 = t2 * t;
591
+ var mt = 1 - t, mt2 = mt * mt, mt3 = mt2 * mt;
592
+ return mt3 * a + 3 * mt2 * t * b + 3 * mt * t2 * c + t3 * d;
593
+ }
594
+
595
+ function catmullRom(p0, p1, p2, p3, t) {
596
+ var t2 = t * t, t3 = t2 * t;
597
+ return 0.5 * ((2 * p1) + (-p0 + p2) * t +
598
+ (2 * p0 - 5 * p1 + 4 * p2 - p3) * t2 +
599
+ (-p0 + 3 * p1 - 3 * p2 + p3) * t3);
600
+ }
601
+
602
+ function springDamper(current, target, velocity, stiffness, damping, dt) {
603
+ var force = -stiffness * (current - target) - damping * velocity;
604
+ velocity += force * dt;
605
+ current += velocity * dt;
606
+ return { value: current, velocity: velocity };
607
+ }
608
+
609
+ function exponentialDecay(value, target, rate, dt) {
610
+ return target + (value - target) * Math.exp(-rate * dt);
611
+ }
612
+ `,
613
+ exports: ["bezierPoint", "catmullRom", "springDamper", "exponentialDecay", "goldenRatio", "PHI"],
614
+ dependencies: ["math"],
615
+ description: "Advanced interpolation and constants (Bezier, Catmull-Rom, spring, PHI).",
616
+ usage: `### math-advanced \u2014 Advanced Interpolation
617
+
618
+ \`\`\`js
619
+ bezierPoint(0, 0.5, 0.5, 1, t); // cubic Bezier
620
+ catmullRom(p0, p1, p2, p3, t); // Catmull-Rom spline
621
+ springDamper(pos, target, vel, 100, 10, dt);
622
+ exponentialDecay(current, target, 5, dt);
623
+ PHI; // \u2192 1.618...
624
+ \`\`\`
625
+ `
626
+ };
627
+ var math_advanced_default = mathAdvanced;
628
+
629
+ // src/components/js/easing.ts
630
+ var easing = {
631
+ name: "easing",
632
+ version: "1.0.0",
633
+ category: "easing",
634
+ target: "js",
635
+ renderers: [],
636
+ code: `function easeInQuad(t) { return t * t; }
637
+ function easeOutQuad(t) { return t * (2 - t); }
638
+ function easeInOutQuad(t) { return t < 0.5 ? 2 * t * t : -1 + (4 - 2 * t) * t; }
639
+ function easeInCubic(t) { return t * t * t; }
640
+ function easeOutCubic(t) { var u = 1 - t; return 1 - u * u * u; }
641
+ function easeInOutCubic(t) {
642
+ return t < 0.5 ? 4 * t * t * t : 1 - Math.pow(-2 * t + 2, 3) / 2;
643
+ }
644
+ function easeInOutSine(t) { return -(Math.cos(Math.PI * t) - 1) / 2; }
645
+ function easeInExpo(t) { return t === 0 ? 0 : Math.pow(2, 10 * t - 10); }
646
+ function easeOutExpo(t) { return t === 1 ? 1 : 1 - Math.pow(2, -10 * t); }
647
+ function easeOutElastic(t) {
648
+ if (t === 0 || t === 1) return t;
649
+ return Math.pow(2, -10 * t) * Math.sin((t * 10 - 0.75) * (2 * Math.PI / 3)) + 1;
650
+ }
651
+ function easeOutBounce(t) {
652
+ if (t < 1 / 2.75) return 7.5625 * t * t;
653
+ if (t < 2 / 2.75) { t -= 1.5 / 2.75; return 7.5625 * t * t + 0.75; }
654
+ if (t < 2.5 / 2.75) { t -= 2.25 / 2.75; return 7.5625 * t * t + 0.9375; }
655
+ t -= 2.625 / 2.75; return 7.5625 * t * t + 0.984375;
656
+ }
657
+ function spring(t, freq, decay) {
658
+ freq = freq || 4; decay = decay || 4;
659
+ return 1 - Math.exp(-decay * t) * Math.cos(freq * Math.PI * t);
660
+ }
661
+ `,
662
+ exports: [
663
+ "easeInQuad",
664
+ "easeOutQuad",
665
+ "easeInOutQuad",
666
+ "easeInCubic",
667
+ "easeOutCubic",
668
+ "easeInOutCubic",
669
+ "easeInOutSine",
670
+ "easeInExpo",
671
+ "easeOutExpo",
672
+ "easeOutElastic",
673
+ "easeOutBounce",
674
+ "spring"
675
+ ],
676
+ dependencies: [],
677
+ description: "Easing functions for smooth animations (0\u21921 domain).",
678
+ usage: `### easing \u2014 Easing Functions
679
+
680
+ \`\`\`js
681
+ easeInOutCubic(t); // smooth S-curve
682
+ easeOutElastic(t); // springy overshoot
683
+ easeOutBounce(t); // bouncing effect
684
+ spring(t, 4, 4); // damped spring
685
+ \`\`\`
686
+ `
687
+ };
688
+ var easing_default = easing;
689
+
690
+ // src/components/js/color.ts
691
+ var color = {
692
+ name: "color",
693
+ version: "1.0.0",
694
+ category: "color",
695
+ target: "js",
696
+ renderers: [],
697
+ code: `function hexToRgb(hex) {
698
+ var n = parseInt(hex.charAt(0) === '#' ? hex.slice(1) : hex, 16);
699
+ return [(n >> 16) & 255, (n >> 8) & 255, n & 255];
700
+ }
701
+
702
+ function rgbToHex(r, g, b) {
703
+ return '#' + ((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1);
704
+ }
705
+
706
+ function hslToRgb(h, s, l) {
707
+ h = h / 360; s = s / 100; l = l / 100;
708
+ if (s === 0) { var v = Math.round(l * 255); return [v, v, v]; }
709
+ function hue2rgb(p, q, t) {
710
+ if (t < 0) t += 1; if (t > 1) t -= 1;
711
+ if (t < 1/6) return p + (q - p) * 6 * t;
712
+ if (t < 1/2) return q;
713
+ if (t < 2/3) return p + (q - p) * (2/3 - t) * 6;
714
+ return p;
715
+ }
716
+ var q = l < 0.5 ? l * (1 + s) : l + s - l * s;
717
+ var p = 2 * l - q;
718
+ return [
719
+ Math.round(hue2rgb(p, q, h + 1/3) * 255),
720
+ Math.round(hue2rgb(p, q, h) * 255),
721
+ Math.round(hue2rgb(p, q, h - 1/3) * 255)
722
+ ];
723
+ }
724
+
725
+ function rgbToHsl(r, g, b) {
726
+ r /= 255; g /= 255; b /= 255;
727
+ var max = Math.max(r, g, b), min = Math.min(r, g, b);
728
+ var h = 0, s = 0, l = (max + min) / 2;
729
+ if (max !== min) {
730
+ var d = max - min;
731
+ s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
732
+ if (max === r) h = ((g - b) / d + (g < b ? 6 : 0)) / 6;
733
+ else if (max === g) h = ((b - r) / d + 2) / 6;
734
+ else h = ((r - g) / d + 4) / 6;
735
+ }
736
+ return [Math.round(h * 360), Math.round(s * 100), Math.round(l * 100)];
737
+ }
738
+
739
+ function lerpColor(c1, c2, t) {
740
+ var a = hexToRgb(c1), b = hexToRgb(c2);
741
+ return rgbToHex(
742
+ Math.round(a[0] + (b[0] - a[0]) * t),
743
+ Math.round(a[1] + (b[1] - a[1]) * t),
744
+ Math.round(a[2] + (b[2] - a[2]) * t)
745
+ );
746
+ }
747
+
748
+ function contrastRatio(hex1, hex2) {
749
+ function luminance(hex) {
750
+ var rgb = hexToRgb(hex).map(function(c) {
751
+ c = c / 255;
752
+ return c <= 0.03928 ? c / 12.92 : Math.pow((c + 0.055) / 1.055, 2.4);
753
+ });
754
+ return 0.2126 * rgb[0] + 0.7152 * rgb[1] + 0.0722 * rgb[2];
755
+ }
756
+ var l1 = luminance(hex1), l2 = luminance(hex2);
757
+ var lighter = Math.max(l1, l2), darker = Math.min(l1, l2);
758
+ return (lighter + 0.05) / (darker + 0.05);
759
+ }
760
+ `,
761
+ exports: ["hexToRgb", "rgbToHex", "hslToRgb", "rgbToHsl", "lerpColor", "contrastRatio"],
762
+ dependencies: [],
763
+ description: "Color space conversion (hex, RGB, HSL) and utilities.",
764
+ usage: `### color \u2014 Color Space Conversion
765
+
766
+ \`\`\`js
767
+ hexToRgb('#ff0000'); // \u2192 [255, 0, 0]
768
+ rgbToHex(255, 128, 0); // \u2192 '#ff8000'
769
+ hslToRgb(200, 80, 50); // \u2192 [r, g, b]
770
+ lerpColor('#000', '#fff', 0.5);
771
+ contrastRatio('#000', '#fff'); // \u2192 21
772
+ \`\`\`
773
+ `
774
+ };
775
+ var color_default = color;
776
+
777
+ // src/components/js/color-advanced.ts
778
+ var colorAdvanced = {
779
+ name: "color-advanced",
780
+ version: "1.0.0",
781
+ category: "color",
782
+ target: "js",
783
+ renderers: [],
784
+ code: `function rgbToOklab(r, g, b) {
785
+ r /= 255; g /= 255; b /= 255;
786
+ var lr = r > 0.04045 ? Math.pow((r + 0.055) / 1.055, 2.4) : r / 12.92;
787
+ var lg = g > 0.04045 ? Math.pow((g + 0.055) / 1.055, 2.4) : g / 12.92;
788
+ var lb = b > 0.04045 ? Math.pow((b + 0.055) / 1.055, 2.4) : b / 12.92;
789
+ var l = Math.cbrt(0.4122214708 * lr + 0.5363325363 * lg + 0.0514459929 * lb);
790
+ var m = Math.cbrt(0.2119034982 * lr + 0.6806995451 * lg + 0.1073969566 * lb);
791
+ var s = Math.cbrt(0.0883024619 * lr + 0.2817188376 * lg + 0.6299787005 * lb);
792
+ return [
793
+ 0.2104542553 * l + 0.7936177850 * m - 0.0040720468 * s,
794
+ 1.9779984951 * l - 2.4285922050 * m + 0.4505937099 * s,
795
+ 0.0259040371 * l + 0.7827717662 * m - 0.8086757660 * s
796
+ ];
797
+ }
798
+
799
+ function oklabToRgb(L, a, b) {
800
+ var l = L + 0.3963377774 * a + 0.2158037573 * b;
801
+ var m = L - 0.1055613458 * a - 0.0638541728 * b;
802
+ var s = L - 0.0894841775 * a - 1.2914855480 * b;
803
+ l = l * l * l; m = m * m * m; s = s * s * s;
804
+ var r = +4.0767416621 * l - 3.3077115913 * m + 0.2309699292 * s;
805
+ var g = -1.2684380046 * l + 2.6097574011 * m - 0.3413193965 * s;
806
+ var bl = -0.0041960863 * l - 0.7034186147 * m + 1.7076147010 * s;
807
+ function toSrgb(c) {
808
+ c = c > 0.0031308 ? 1.055 * Math.pow(c, 1 / 2.4) - 0.055 : 12.92 * c;
809
+ return Math.max(0, Math.min(255, Math.round(c * 255)));
810
+ }
811
+ return [toSrgb(r), toSrgb(g), toSrgb(bl)];
812
+ }
813
+
814
+ function rgbToOklch(r, g, b) {
815
+ var lab = rgbToOklab(r, g, b);
816
+ var C = Math.sqrt(lab[1] * lab[1] + lab[2] * lab[2]);
817
+ var h = Math.atan2(lab[2], lab[1]) * 180 / Math.PI;
818
+ if (h < 0) h += 360;
819
+ return [lab[0], C, h];
820
+ }
821
+
822
+ function oklchToRgb(L, C, h) {
823
+ var rad = h * Math.PI / 180;
824
+ return oklabToRgb(L, C * Math.cos(rad), C * Math.sin(rad));
825
+ }
826
+
827
+ function lerpOklab(c1, c2, t) {
828
+ var a = rgbToOklab(c1[0], c1[1], c1[2]);
829
+ var b = rgbToOklab(c2[0], c2[1], c2[2]);
830
+ return oklabToRgb(
831
+ a[0] + (b[0] - a[0]) * t,
832
+ a[1] + (b[1] - a[1]) * t,
833
+ a[2] + (b[2] - a[2]) * t
834
+ );
835
+ }
836
+
837
+ function palette(colors, t) {
838
+ t = Math.max(0, Math.min(1, t)) * (colors.length - 1);
839
+ var i = Math.floor(t);
840
+ var f = t - i;
841
+ if (i >= colors.length - 1) return colors[colors.length - 1];
842
+ return lerpOklab(colors[i], colors[i + 1], f);
843
+ }
844
+
845
+ function complementary(r, g, b) {
846
+ return [255 - r, 255 - g, 255 - b];
847
+ }
848
+
849
+ function triadic(h, s, l) {
850
+ return [
851
+ [h, s, l],
852
+ [(h + 120) % 360, s, l],
853
+ [(h + 240) % 360, s, l]
854
+ ];
855
+ }
856
+
857
+ function analogous(h, s, l, angle) {
858
+ angle = angle || 30;
859
+ return [
860
+ [(h - angle + 360) % 360, s, l],
861
+ [h, s, l],
862
+ [(h + angle) % 360, s, l]
863
+ ];
864
+ }
865
+ `,
866
+ exports: ["oklabToRgb", "rgbToOklab", "oklchToRgb", "rgbToOklch", "lerpOklab", "palette", "complementary", "triadic", "analogous"],
867
+ dependencies: ["color"],
868
+ description: "Perceptual color spaces (OKLab, OKLCh) and color harmony.",
869
+ usage: `### color-advanced \u2014 Perceptual Color & Harmony
870
+
871
+ \`\`\`js
872
+ var lab = rgbToOklab(255, 128, 0);
873
+ var rgb = oklabToRgb(lab[0], lab[1], lab[2]);
874
+ lerpOklab([255,0,0], [0,0,255], 0.5); // perceptually uniform blend
875
+ palette([[255,0,0],[0,255,0],[0,0,255]], 0.5); // palette sampling
876
+ triadic(200, 80, 50); // three equidistant hues
877
+ \`\`\`
878
+ `
879
+ };
880
+ var color_advanced_default = colorAdvanced;
881
+
882
+ // src/components/js/vector.ts
883
+ var vector = {
884
+ name: "vector",
885
+ version: "1.0.0",
886
+ category: "vector",
887
+ target: "js",
888
+ renderers: [],
889
+ code: `function vec2(x, y) { return [x, y]; }
890
+ function vec3(x, y, z) { return [x, y, z]; }
891
+
892
+ function add(a, b) {
893
+ var r = new Array(a.length);
894
+ for (var i = 0; i < a.length; i++) r[i] = a[i] + b[i];
895
+ return r;
896
+ }
897
+
898
+ function sub(a, b) {
899
+ var r = new Array(a.length);
900
+ for (var i = 0; i < a.length; i++) r[i] = a[i] - b[i];
901
+ return r;
902
+ }
903
+
904
+ function mul(a, s) {
905
+ var r = new Array(a.length);
906
+ for (var i = 0; i < a.length; i++) r[i] = a[i] * s;
907
+ return r;
908
+ }
909
+
910
+ function div(a, s) {
911
+ var r = new Array(a.length);
912
+ for (var i = 0; i < a.length; i++) r[i] = a[i] / s;
913
+ return r;
914
+ }
915
+
916
+ function dot(a, b) {
917
+ var s = 0;
918
+ for (var i = 0; i < a.length; i++) s += a[i] * b[i];
919
+ return s;
920
+ }
921
+
922
+ function cross(a, b) {
923
+ return [
924
+ a[1] * b[2] - a[2] * b[1],
925
+ a[2] * b[0] - a[0] * b[2],
926
+ a[0] * b[1] - a[1] * b[0]
927
+ ];
928
+ }
929
+
930
+ function length(a) {
931
+ var s = 0;
932
+ for (var i = 0; i < a.length; i++) s += a[i] * a[i];
933
+ return Math.sqrt(s);
934
+ }
935
+
936
+ function normalize(a) {
937
+ var len = length(a);
938
+ return len === 0 ? a : div(a, len);
939
+ }
940
+
941
+ function distance(a, b) { return length(sub(a, b)); }
942
+
943
+ function reflect(v, n) {
944
+ var d = 2 * dot(v, n);
945
+ return sub(v, mul(n, d));
946
+ }
947
+
948
+ function rotate2D(v, angle) {
949
+ var c = Math.cos(angle), s = Math.sin(angle);
950
+ return [v[0] * c - v[1] * s, v[0] * s + v[1] * c];
951
+ }
952
+ `,
953
+ exports: ["vec2", "vec3", "add", "sub", "mul", "div", "dot", "cross", "normalize", "length", "distance", "reflect", "rotate2D"],
954
+ dependencies: [],
955
+ description: "Lightweight vector math using plain arrays.",
956
+ usage: `### vector \u2014 Vector Math
957
+
958
+ \`\`\`js
959
+ var a = vec2(1, 0), b = vec2(0, 1);
960
+ add(a, b); // \u2192 [1, 1]
961
+ normalize(a); // \u2192 [1, 0]
962
+ distance(a, b); // \u2192 1.414...
963
+ rotate2D(a, Math.PI / 2);
964
+ \`\`\`
965
+ `
966
+ };
967
+ var vector_default = vector;
968
+
969
+ // src/components/js/matrix.ts
970
+ var matrix = {
971
+ name: "matrix",
972
+ version: "1.0.0",
973
+ category: "vector",
974
+ target: "js",
975
+ renderers: [],
976
+ code: `function mat2(a, b, c, d) { return [a, b, c, d]; }
977
+ function mat3(m00, m01, m02, m10, m11, m12, m20, m21, m22) {
978
+ return [m00, m01, m02, m10, m11, m12, m20, m21, m22];
979
+ }
980
+ function mat4(m00,m01,m02,m03,m10,m11,m12,m13,m20,m21,m22,m23,m30,m31,m32,m33) {
981
+ return [m00,m01,m02,m03,m10,m11,m12,m13,m20,m21,m22,m23,m30,m31,m32,m33];
982
+ }
983
+
984
+ function multiply(a, b, n) {
985
+ var r = new Array(n * n);
986
+ for (var i = 0; i < n; i++)
987
+ for (var j = 0; j < n; j++) {
988
+ var s = 0;
989
+ for (var k = 0; k < n; k++) s += a[i * n + k] * b[k * n + j];
990
+ r[i * n + j] = s;
991
+ }
992
+ return r;
993
+ }
994
+
995
+ function transpose(m, n) {
996
+ var r = new Array(n * n);
997
+ for (var i = 0; i < n; i++)
998
+ for (var j = 0; j < n; j++) r[j * n + i] = m[i * n + j];
999
+ return r;
1000
+ }
1001
+
1002
+ function inverse(m) {
1003
+ var a=m[0],b=m[1],c=m[2],d=m[3],e=m[4],f=m[5],g=m[6],h=m[7],i=m[8],j=m[9],k=m[10],l=m[11],n=m[12],o=m[13],p=m[14],q=m[15];
1004
+ var kpol=k*q-l*p, jpom=j*q-l*o, jpon=j*p-k*o, ipol=i*q-l*n, ipon=i*p-k*n, iomn=i*o-j*n;
1005
+ var det = a*(f*kpol-g*jpom+h*jpon) - b*(e*kpol-g*ipol+h*ipon) + c*(e*jpom-f*ipol+h*iomn) - d*(e*jpon-f*ipon+g*iomn);
1006
+ if (det === 0) return null;
1007
+ var id = 1/det;
1008
+ return [
1009
+ (f*kpol-g*jpom+h*jpon)*id, -(b*kpol-c*jpom+d*jpon)*id, (b*(g*q-h*p)-c*(f*q-h*o)+d*(f*p-g*o))*id, -(b*(g*l-h*k)-c*(f*l-h*j)+d*(f*k-g*j))*id,
1010
+ -(e*kpol-g*ipol+h*ipon)*id, (a*kpol-c*ipol+d*ipon)*id, -(a*(g*q-h*p)-c*(e*q-h*n)+d*(e*p-g*n))*id, (a*(g*l-h*k)-c*(e*l-h*i)+d*(e*k-g*i))*id,
1011
+ (e*jpom-f*ipol+h*iomn)*id, -(a*jpom-b*ipol+d*iomn)*id, (a*(f*q-h*o)-b*(e*q-h*n)+d*(e*o-f*n))*id, -(a*(f*l-h*j)-b*(e*l-h*i)+d*(e*j-f*i))*id,
1012
+ -(e*jpon-f*ipon+g*iomn)*id, (a*jpon-b*ipon+c*iomn)*id, -(a*(f*p-g*o)-b*(e*p-g*n)+c*(e*o-f*n))*id, (a*(f*k-g*j)-b*(e*k-g*i)+c*(e*j-f*i))*id
1013
+ ];
1014
+ }
1015
+
1016
+ function rotationMatrix(axis, angle) {
1017
+ var c = Math.cos(angle), s = Math.sin(angle), t = 1 - c;
1018
+ var x = axis[0], y = axis[1], z = axis[2];
1019
+ return [
1020
+ t*x*x+c, t*x*y-s*z, t*x*z+s*y, 0,
1021
+ t*x*y+s*z, t*y*y+c, t*y*z-s*x, 0,
1022
+ t*x*z-s*y, t*y*z+s*x, t*z*z+c, 0,
1023
+ 0, 0, 0, 1
1024
+ ];
1025
+ }
1026
+
1027
+ function projectionMatrix(fov, aspect, near, far) {
1028
+ var f = 1 / Math.tan(fov / 2);
1029
+ var nf = 1 / (near - far);
1030
+ return [
1031
+ f/aspect, 0, 0, 0,
1032
+ 0, f, 0, 0,
1033
+ 0, 0, (far+near)*nf, -1,
1034
+ 0, 0, 2*far*near*nf, 0
1035
+ ];
1036
+ }
1037
+ `,
1038
+ exports: ["mat2", "mat3", "mat4", "multiply", "inverse", "transpose", "rotationMatrix", "projectionMatrix"],
1039
+ dependencies: ["vector"],
1040
+ description: "Matrix math for 2D/3D transforms and projections.",
1041
+ usage: `### matrix \u2014 Matrix Math
1042
+
1043
+ \`\`\`js
1044
+ var rot = rotationMatrix([0,1,0], Math.PI/4);
1045
+ var proj = projectionMatrix(Math.PI/3, 16/9, 0.1, 100);
1046
+ var result = multiply(proj, rot, 4);
1047
+ \`\`\`
1048
+ `
1049
+ };
1050
+ var matrix_default = matrix;
1051
+
1052
+ // src/components/js/grid.ts
1053
+ var grid = {
1054
+ name: "grid",
1055
+ version: "1.0.0",
1056
+ category: "grid",
1057
+ target: "js",
1058
+ renderers: [],
1059
+ code: `function marchingSquares(field, cols, rows, threshold) {
1060
+ var segments = [];
1061
+ function val(x, y) { return field[y * cols + x] >= threshold ? 1 : 0; }
1062
+ function interp(a, b, va, vb) {
1063
+ var dv = vb - va;
1064
+ return dv === 0 ? 0.5 : (threshold - va) / dv;
1065
+ }
1066
+ for (var y = 0; y < rows - 1; y++) {
1067
+ for (var x = 0; x < cols - 1; x++) {
1068
+ var v00 = field[y * cols + x], v10 = field[y * cols + x + 1];
1069
+ var v01 = field[(y+1) * cols + x], v11 = field[(y+1) * cols + x + 1];
1070
+ var code = val(x,y) | (val(x+1,y)<<1) | (val(x,y+1)<<2) | (val(x+1,y+1)<<3);
1071
+ if (code === 0 || code === 15) continue;
1072
+ var top = [x + interp(v00, v10, v00, v10), y];
1073
+ var bottom = [x + interp(v01, v11, v01, v11), y + 1];
1074
+ var left = [x, y + interp(v00, v01, v00, v01)];
1075
+ var right = [x + 1, y + interp(v10, v11, v10, v11)];
1076
+ if (code===1||code===14) segments.push([top, left]);
1077
+ else if (code===2||code===13) segments.push([top, right]);
1078
+ else if (code===3||code===12) segments.push([left, right]);
1079
+ else if (code===4||code===11) segments.push([left, bottom]);
1080
+ else if (code===6||code===9) segments.push([top, bottom]);
1081
+ else if (code===7||code===8) segments.push([right, bottom]);
1082
+ else if (code===5) { segments.push([top, left]); segments.push([right, bottom]); }
1083
+ else if (code===10) { segments.push([top, right]); segments.push([left, bottom]); }
1084
+ }
1085
+ }
1086
+ return segments;
1087
+ }
1088
+
1089
+ function floodFill(grid, cols, rows, startX, startY, fillVal) {
1090
+ var target = grid[startY * cols + startX];
1091
+ if (target === fillVal) return grid;
1092
+ var result = grid.slice();
1093
+ var stack = [[startX, startY]];
1094
+ while (stack.length > 0) {
1095
+ var p = stack.pop();
1096
+ var px = p[0], py = p[1];
1097
+ if (px < 0 || px >= cols || py < 0 || py >= rows) continue;
1098
+ if (result[py * cols + px] !== target) continue;
1099
+ result[py * cols + px] = fillVal;
1100
+ stack.push([px+1,py],[px-1,py],[px,py+1],[px,py-1]);
1101
+ }
1102
+ return result;
1103
+ }
1104
+
1105
+ function bresenhamLine(x0, y0, x1, y1) {
1106
+ var points = [];
1107
+ var dx = Math.abs(x1 - x0), dy = Math.abs(y1 - y0);
1108
+ var sx = x0 < x1 ? 1 : -1, sy = y0 < y1 ? 1 : -1;
1109
+ var err = dx - dy;
1110
+ while (true) {
1111
+ points.push([x0, y0]);
1112
+ if (x0 === x1 && y0 === y1) break;
1113
+ var e2 = 2 * err;
1114
+ if (e2 > -dy) { err -= dy; x0 += sx; }
1115
+ if (e2 < dx) { err += dx; y0 += sy; }
1116
+ }
1117
+ return points;
1118
+ }
1119
+
1120
+ function cellularAutomaton(grid, cols, rows, ruleFn) {
1121
+ var next = new Array(cols * rows);
1122
+ for (var y = 0; y < rows; y++) {
1123
+ for (var x = 0; x < cols; x++) {
1124
+ var neighbors = 0;
1125
+ for (var dy = -1; dy <= 1; dy++)
1126
+ for (var dx = -1; dx <= 1; dx++) {
1127
+ if (dx === 0 && dy === 0) continue;
1128
+ var nx = (x + dx + cols) % cols, ny = (y + dy + rows) % rows;
1129
+ neighbors += grid[ny * cols + nx] ? 1 : 0;
1130
+ }
1131
+ next[y * cols + x] = ruleFn(grid[y * cols + x], neighbors);
1132
+ }
1133
+ }
1134
+ return next;
1135
+ }
1136
+ `,
1137
+ exports: ["marchingSquares", "floodFill", "bresenhamLine", "cellularAutomaton"],
1138
+ dependencies: [],
1139
+ description: "Grid/heightmap algorithms (marching squares, flood fill, Bresenham).",
1140
+ usage: `### grid \u2014 Grid Algorithms
1141
+
1142
+ \`\`\`js
1143
+ var segs = marchingSquares(heightmap, 100, 100, 0.5);
1144
+ var filled = floodFill(grid, w, h, 0, 0, 1);
1145
+ var line = bresenhamLine(0, 0, 10, 7);
1146
+ var next = cellularAutomaton(grid, w, h, function(cell, n) {
1147
+ return n === 3 || (cell && n === 2) ? 1 : 0; // Game of Life
1148
+ });
1149
+ \`\`\`
1150
+ `
1151
+ };
1152
+ var grid_default = grid;
1153
+
1154
+ // src/components/js/grid-advanced.ts
1155
+ var gridAdvanced = {
1156
+ name: "grid-advanced",
1157
+ version: "1.0.0",
1158
+ category: "grid",
1159
+ target: "js",
1160
+ renderers: [],
1161
+ code: `function marchingCubes(field, nx, ny, nz, threshold) {
1162
+ var vertices = [];
1163
+ function val(x, y, z) { return field[z * ny * nx + y * nx + x]; }
1164
+ function interp3(p1, p2, v1, v2) {
1165
+ if (Math.abs(v1 - v2) < 1e-6) return p1;
1166
+ var t = (threshold - v1) / (v2 - v1);
1167
+ return [p1[0]+(p2[0]-p1[0])*t, p1[1]+(p2[1]-p1[1])*t, p1[2]+(p2[2]-p1[2])*t];
1168
+ }
1169
+ for (var z = 0; z < nz-1; z++)
1170
+ for (var y = 0; y < ny-1; y++)
1171
+ for (var x = 0; x < nx-1; x++) {
1172
+ var v = [val(x,y,z),val(x+1,y,z),val(x+1,y+1,z),val(x,y+1,z),
1173
+ val(x,y,z+1),val(x+1,y,z+1),val(x+1,y+1,z+1),val(x,y+1,z+1)];
1174
+ var code = 0;
1175
+ for (var i = 0; i < 8; i++) if (v[i] >= threshold) code |= (1 << i);
1176
+ if (code === 0 || code === 255) continue;
1177
+ var corners = [[x,y,z],[x+1,y,z],[x+1,y+1,z],[x,y+1,z],[x,y,z+1],[x+1,y,z+1],[x+1,y+1,z+1],[x,y+1,z+1]];
1178
+ var edges = [[0,1],[1,2],[2,3],[3,0],[4,5],[5,6],[6,7],[7,4],[0,4],[1,5],[2,6],[3,7]];
1179
+ for (var i = 0; i < edges.length; i++) {
1180
+ var e = edges[i];
1181
+ if ((code & (1<<e[0])) !== (code & (1<<e[1])))
1182
+ vertices.push(interp3(corners[e[0]], corners[e[1]], v[e[0]], v[e[1]]));
1183
+ }
1184
+ }
1185
+ return vertices;
1186
+ }
1187
+
1188
+ function diamondSquare(size, rng, roughness) {
1189
+ var n = size;
1190
+ var grid = new Float64Array(n * n);
1191
+ grid[0] = rng(); grid[n-1] = rng(); grid[(n-1)*n] = rng(); grid[(n-1)*n+n-1] = rng();
1192
+ var step = n - 1, scale = roughness;
1193
+ while (step > 1) {
1194
+ var half = step / 2;
1195
+ for (var y = 0; y < n-1; y += step)
1196
+ for (var x = 0; x < n-1; x += step) {
1197
+ var avg = (grid[y*n+x]+grid[y*n+x+step]+grid[(y+step)*n+x]+grid[(y+step)*n+x+step])/4;
1198
+ grid[(y+half)*n+x+half] = avg + (rng()-0.5)*scale;
1199
+ }
1200
+ for (var y = 0; y < n; y += half)
1201
+ for (var x = (y % step === 0 ? half : 0); x < n; x += step) {
1202
+ var sum = 0, cnt = 0;
1203
+ if (y-half>=0){sum+=grid[(y-half)*n+x];cnt++;}
1204
+ if (y+half<n){sum+=grid[(y+half)*n+x];cnt++;}
1205
+ if (x-half>=0){sum+=grid[y*n+x-half];cnt++;}
1206
+ if (x+half<n){sum+=grid[y*n+x+half];cnt++;}
1207
+ grid[y*n+x] = sum/cnt + (rng()-0.5)*scale;
1208
+ }
1209
+ step = half; scale *= 0.5;
1210
+ }
1211
+ return grid;
1212
+ }
1213
+
1214
+ function waveCollapse(tileCount, cols, rows, adjacency, rng) {
1215
+ var grid = new Array(cols * rows);
1216
+ for (var i = 0; i < grid.length; i++) {
1217
+ grid[i] = new Array(tileCount);
1218
+ for (var t = 0; t < tileCount; t++) grid[i][t] = true;
1219
+ }
1220
+ function entropy(cell) {
1221
+ var c = 0;
1222
+ for (var t = 0; t < tileCount; t++) if (cell[t]) c++;
1223
+ return c;
1224
+ }
1225
+ function collapse() {
1226
+ var minE = tileCount + 1, idx = -1;
1227
+ for (var i = 0; i < grid.length; i++) {
1228
+ var e = entropy(grid[i]);
1229
+ if (e > 1 && e < minE) { minE = e; idx = i; }
1230
+ }
1231
+ if (idx === -1) return false;
1232
+ var options = [];
1233
+ for (var t = 0; t < tileCount; t++) if (grid[idx][t]) options.push(t);
1234
+ var pick = options[Math.floor(rng() * options.length)];
1235
+ for (var t = 0; t < tileCount; t++) grid[idx][t] = (t === pick);
1236
+ propagate(idx);
1237
+ return true;
1238
+ }
1239
+ function propagate(idx) {
1240
+ var stack = [idx];
1241
+ while (stack.length > 0) {
1242
+ var ci = stack.pop();
1243
+ var cx = ci % cols, cy = Math.floor(ci / cols);
1244
+ var dirs = [[1,0],[-1,0],[0,1],[0,-1]];
1245
+ for (var d = 0; d < 4; d++) {
1246
+ var nx = cx+dirs[d][0], ny = cy+dirs[d][1];
1247
+ if (nx<0||nx>=cols||ny<0||ny>=rows) continue;
1248
+ var ni = ny*cols+nx;
1249
+ var changed = false;
1250
+ for (var t = 0; t < tileCount; t++) {
1251
+ if (!grid[ni][t]) continue;
1252
+ var valid = false;
1253
+ for (var s = 0; s < tileCount; s++) {
1254
+ if (grid[ci][s] && adjacency[s] && adjacency[s][d] && adjacency[s][d].indexOf(t) >= 0) { valid = true; break; }
1255
+ }
1256
+ if (!valid) { grid[ni][t] = false; changed = true; }
1257
+ }
1258
+ if (changed) stack.push(ni);
1259
+ }
1260
+ }
1261
+ }
1262
+ while (collapse()) {}
1263
+ var result = new Array(cols * rows);
1264
+ for (var i = 0; i < grid.length; i++) {
1265
+ for (var t = 0; t < tileCount; t++) if (grid[i][t]) { result[i] = t; break; }
1266
+ }
1267
+ return result;
1268
+ }
1269
+ `,
1270
+ exports: ["marchingCubes", "diamondSquare", "waveCollapse"],
1271
+ dependencies: ["prng", "grid"],
1272
+ description: "Advanced grid generation (marching cubes, diamond-square, WFC).",
1273
+ usage: `### grid-advanced \u2014 Advanced Grid Generation
1274
+
1275
+ \`\`\`js
1276
+ var terrain = diamondSquare(129, rng, 1.0);
1277
+ var verts = marchingCubes(field, 32, 32, 32, 0.5);
1278
+ var tiles = waveCollapse(4, 20, 20, adjacencyRules, rng);
1279
+ \`\`\`
1280
+ `
1281
+ };
1282
+ var grid_advanced_default = gridAdvanced;
1283
+
1284
+ // src/components/js/particle.ts
1285
+ var particle = {
1286
+ name: "particle",
1287
+ version: "1.0.0",
1288
+ category: "particle",
1289
+ target: "js",
1290
+ renderers: [],
1291
+ code: `function createParticleSystem(maxParticles) {
1292
+ return {
1293
+ particles: [],
1294
+ maxParticles: maxParticles || 1000,
1295
+ time: 0
1296
+ };
1297
+ }
1298
+
1299
+ function emitParticle(system, x, y, vx, vy, life) {
1300
+ if (system.particles.length >= system.maxParticles) return null;
1301
+ var p = { x: x, y: y, vx: vx || 0, vy: vy || 0, ax: 0, ay: 0, life: life || 1, maxLife: life || 1, age: 0 };
1302
+ system.particles.push(p);
1303
+ return p;
1304
+ }
1305
+
1306
+ function updateParticles(system, dt) {
1307
+ dt = dt || 1/60;
1308
+ system.time += dt;
1309
+ for (var i = system.particles.length - 1; i >= 0; i--) {
1310
+ var p = system.particles[i];
1311
+ p.vx += p.ax * dt; p.vy += p.ay * dt;
1312
+ p.x += p.vx * dt; p.y += p.vy * dt;
1313
+ p.ax = 0; p.ay = 0;
1314
+ p.age += dt; p.life -= dt;
1315
+ if (p.life <= 0) system.particles.splice(i, 1);
1316
+ }
1317
+ return system;
1318
+ }
1319
+
1320
+ function applyForce(particle, fx, fy) {
1321
+ particle.ax += fx;
1322
+ particle.ay += fy;
1323
+ }
1324
+
1325
+ function particleAge(particle) {
1326
+ return particle.age / particle.maxLife;
1327
+ }
1328
+ `,
1329
+ exports: ["createParticleSystem", "updateParticles", "emitParticle", "applyForce", "particleAge"],
1330
+ dependencies: ["vector"],
1331
+ description: "Renderer-agnostic particle system state management.",
1332
+ usage: `### particle \u2014 Particle System
1333
+
1334
+ \`\`\`js
1335
+ var sys = createParticleSystem(500);
1336
+ emitParticle(sys, x, y, vx, vy, 2.0);
1337
+ updateParticles(sys, dt);
1338
+ sys.particles.forEach(function(p) {
1339
+ applyForce(p, 0, 9.8); // gravity
1340
+ var t = particleAge(p); // 0\u21921 normalized age
1341
+ });
1342
+ \`\`\`
1343
+ `
1344
+ };
1345
+ var particle_default = particle;
1346
+
1347
+ // src/components/js/particle-forces.ts
1348
+ var particleForces = {
1349
+ name: "particle-forces",
1350
+ version: "1.0.0",
1351
+ category: "particle",
1352
+ target: "js",
1353
+ renderers: [],
1354
+ code: `function gravityForce(p, gx, gy) {
1355
+ p.ax += gx || 0;
1356
+ p.ay += gy || 9.8;
1357
+ }
1358
+
1359
+ function attractorForce(p, ax, ay, strength) {
1360
+ var dx = ax - p.x, dy = ay - p.y;
1361
+ var d = Math.sqrt(dx * dx + dy * dy) + 0.01;
1362
+ var f = strength / (d * d);
1363
+ p.ax += dx / d * f;
1364
+ p.ay += dy / d * f;
1365
+ }
1366
+
1367
+ function vortexForce(p, cx, cy, strength) {
1368
+ var dx = p.x - cx, dy = p.y - cy;
1369
+ var d = Math.sqrt(dx * dx + dy * dy) + 0.01;
1370
+ var f = strength / d;
1371
+ p.ax += -dy / d * f;
1372
+ p.ay += dx / d * f;
1373
+ }
1374
+
1375
+ function dragForce(p, coefficient) {
1376
+ coefficient = coefficient || 0.01;
1377
+ var speed = Math.sqrt(p.vx * p.vx + p.vy * p.vy);
1378
+ if (speed > 0) {
1379
+ var drag = coefficient * speed;
1380
+ p.ax -= p.vx / speed * drag;
1381
+ p.ay -= p.vy / speed * drag;
1382
+ }
1383
+ }
1384
+
1385
+ function turbulenceForce(p, noiseFn, scale, strength) {
1386
+ var angle = noiseFn(p.x * scale, p.y * scale) * Math.PI * 4;
1387
+ p.ax += Math.cos(angle) * strength;
1388
+ p.ay += Math.sin(angle) * strength;
1389
+ }
1390
+
1391
+ function boundaryForce(p, minX, minY, maxX, maxY, strength) {
1392
+ strength = strength || 10;
1393
+ var margin = 20;
1394
+ if (p.x < minX + margin) p.ax += strength * (1 - (p.x - minX) / margin);
1395
+ if (p.x > maxX - margin) p.ax -= strength * (1 - (maxX - p.x) / margin);
1396
+ if (p.y < minY + margin) p.ay += strength * (1 - (p.y - minY) / margin);
1397
+ if (p.y > maxY - margin) p.ay -= strength * (1 - (maxY - p.y) / margin);
1398
+ }
1399
+ `,
1400
+ exports: ["gravityForce", "attractorForce", "vortexForce", "dragForce", "turbulenceForce", "boundaryForce"],
1401
+ dependencies: ["particle", "vector"],
1402
+ description: "Common particle force functions (gravity, attractor, vortex, drag).",
1403
+ usage: `### particle-forces \u2014 Force Functions
1404
+
1405
+ \`\`\`js
1406
+ sys.particles.forEach(function(p) {
1407
+ gravityForce(p, 0, 9.8);
1408
+ attractorForce(p, cx, cy, 100);
1409
+ dragForce(p, 0.02);
1410
+ boundaryForce(p, 0, 0, width, height);
1411
+ });
1412
+ \`\`\`
1413
+ `
1414
+ };
1415
+ var particle_forces_default = particleForces;
1416
+
1417
+ // src/components/js/shape.ts
1418
+ var shape = {
1419
+ name: "shape",
1420
+ version: "1.0.0",
1421
+ category: "geometry",
1422
+ target: "js",
1423
+ renderers: [],
1424
+ code: `function regularPolygon(cx, cy, radius, sides) {
1425
+ var pts = [];
1426
+ for (var i = 0; i < sides; i++) {
1427
+ var a = (i / sides) * Math.PI * 2 - Math.PI / 2;
1428
+ pts.push([cx + Math.cos(a) * radius, cy + Math.sin(a) * radius]);
1429
+ }
1430
+ return pts;
1431
+ }
1432
+
1433
+ function star(cx, cy, outerR, innerR, points) {
1434
+ var pts = [];
1435
+ for (var i = 0; i < points * 2; i++) {
1436
+ var a = (i / (points * 2)) * Math.PI * 2 - Math.PI / 2;
1437
+ var r = i % 2 === 0 ? outerR : innerR;
1438
+ pts.push([cx + Math.cos(a) * r, cy + Math.sin(a) * r]);
1439
+ }
1440
+ return pts;
1441
+ }
1442
+
1443
+ function spiral(cx, cy, startR, endR, turns, segments) {
1444
+ var pts = [];
1445
+ for (var i = 0; i <= segments; i++) {
1446
+ var t = i / segments;
1447
+ var angle = t * turns * Math.PI * 2;
1448
+ var r = startR + (endR - startR) * t;
1449
+ pts.push([cx + Math.cos(angle) * r, cy + Math.sin(angle) * r]);
1450
+ }
1451
+ return pts;
1452
+ }
1453
+
1454
+ function lissajous(cx, cy, a, b, kx, ky, delta, segments) {
1455
+ var pts = [];
1456
+ for (var i = 0; i <= segments; i++) {
1457
+ var t = (i / segments) * Math.PI * 2;
1458
+ pts.push([cx + a * Math.sin(kx * t + delta), cy + b * Math.sin(ky * t)]);
1459
+ }
1460
+ return pts;
1461
+ }
1462
+
1463
+ function superellipse(cx, cy, rx, ry, n, segments) {
1464
+ var pts = [];
1465
+ for (var i = 0; i <= segments; i++) {
1466
+ var a = (i / segments) * Math.PI * 2;
1467
+ var ca = Math.cos(a), sa = Math.sin(a);
1468
+ var x = Math.pow(Math.abs(ca), 2/n) * rx * (ca >= 0 ? 1 : -1);
1469
+ var y = Math.pow(Math.abs(sa), 2/n) * ry * (sa >= 0 ? 1 : -1);
1470
+ pts.push([cx + x, cy + y]);
1471
+ }
1472
+ return pts;
1473
+ }
1474
+
1475
+ function heart(cx, cy, size, segments) {
1476
+ var pts = [];
1477
+ for (var i = 0; i <= segments; i++) {
1478
+ var t = (i / segments) * Math.PI * 2;
1479
+ var x = 16 * Math.pow(Math.sin(t), 3);
1480
+ var y = -(13 * Math.cos(t) - 5 * Math.cos(2*t) - 2 * Math.cos(3*t) - Math.cos(4*t));
1481
+ pts.push([cx + x * size / 16, cy + y * size / 16]);
1482
+ }
1483
+ return pts;
1484
+ }
1485
+ `,
1486
+ exports: ["regularPolygon", "star", "spiral", "lissajous", "superellipse", "heart"],
1487
+ dependencies: ["math"],
1488
+ description: "Parametric shape generators returning point arrays.",
1489
+ usage: `### shape \u2014 Parametric Shapes
1490
+
1491
+ \`\`\`js
1492
+ regularPolygon(cx, cy, 50, 6); // hexagon
1493
+ star(cx, cy, 50, 25, 5); // 5-point star
1494
+ spiral(cx, cy, 10, 100, 5, 200);
1495
+ heart(cx, cy, 40, 100);
1496
+ \`\`\`
1497
+ `
1498
+ };
1499
+ var shape_default = shape;
1500
+
1501
+ // src/components/js/shape-advanced.ts
1502
+ var shapeAdvanced = {
1503
+ name: "shape-advanced",
1504
+ version: "1.0.0",
1505
+ category: "geometry",
1506
+ target: "js",
1507
+ renderers: [],
1508
+ code: `function chaikinSmooth(points, iterations) {
1509
+ iterations = iterations || 3;
1510
+ var pts = points;
1511
+ for (var iter = 0; iter < iterations; iter++) {
1512
+ var next = [];
1513
+ for (var i = 0; i < pts.length - 1; i++) {
1514
+ var a = pts[i], b = pts[i+1];
1515
+ next.push([a[0]*0.75 + b[0]*0.25, a[1]*0.75 + b[1]*0.25]);
1516
+ next.push([a[0]*0.25 + b[0]*0.75, a[1]*0.25 + b[1]*0.75]);
1517
+ }
1518
+ pts = next;
1519
+ }
1520
+ return pts;
1521
+ }
1522
+
1523
+ function subdivideCurve(points, iterations) {
1524
+ iterations = iterations || 1;
1525
+ var pts = points;
1526
+ for (var iter = 0; iter < iterations; iter++) {
1527
+ var next = [pts[0]];
1528
+ for (var i = 0; i < pts.length - 1; i++) {
1529
+ var mid = [(pts[i][0]+pts[i+1][0])/2, (pts[i][1]+pts[i+1][1])/2];
1530
+ next.push(mid);
1531
+ next.push(pts[i+1]);
1532
+ }
1533
+ pts = next;
1534
+ }
1535
+ return pts;
1536
+ }
1537
+
1538
+ function offsetPath(points, dist) {
1539
+ var result = [];
1540
+ for (var i = 0; i < points.length; i++) {
1541
+ var prev = points[(i-1+points.length)%points.length];
1542
+ var curr = points[i];
1543
+ var next = points[(i+1)%points.length];
1544
+ var dx1 = curr[0]-prev[0], dy1 = curr[1]-prev[1];
1545
+ var dx2 = next[0]-curr[0], dy2 = next[1]-curr[1];
1546
+ var len1 = Math.sqrt(dx1*dx1+dy1*dy1) || 1;
1547
+ var len2 = Math.sqrt(dx2*dx2+dy2*dy2) || 1;
1548
+ var nx = (-(dy1/len1 + dy2/len2))/2, ny = ((dx1/len1 + dx2/len2))/2;
1549
+ var nl = Math.sqrt(nx*nx+ny*ny) || 1;
1550
+ result.push([curr[0]+nx/nl*dist, curr[1]+ny/nl*dist]);
1551
+ }
1552
+ return result;
1553
+ }
1554
+
1555
+ function convexHull(points) {
1556
+ var pts = points.slice().sort(function(a,b) { return a[0]-b[0] || a[1]-b[1]; });
1557
+ function cross(O,A,B) { return (A[0]-O[0])*(B[1]-O[1])-(A[1]-O[1])*(B[0]-O[0]); }
1558
+ var lower = [];
1559
+ for (var i = 0; i < pts.length; i++) {
1560
+ while (lower.length >= 2 && cross(lower[lower.length-2], lower[lower.length-1], pts[i]) <= 0) lower.pop();
1561
+ lower.push(pts[i]);
1562
+ }
1563
+ var upper = [];
1564
+ for (var i = pts.length - 1; i >= 0; i--) {
1565
+ while (upper.length >= 2 && cross(upper[upper.length-2], upper[upper.length-1], pts[i]) <= 0) upper.pop();
1566
+ upper.push(pts[i]);
1567
+ }
1568
+ return lower.slice(0, -1).concat(upper.slice(0, -1));
1569
+ }
1570
+
1571
+ function delaunay(points) {
1572
+ var n = points.length;
1573
+ if (n < 3) return [];
1574
+ var ids = new Array(n);
1575
+ for (var i = 0; i < n; i++) ids[i] = i;
1576
+ ids.sort(function(a,b) { return points[a][0]-points[b][0] || points[a][1]-points[b][1]; });
1577
+ var triangles = [];
1578
+ function circumscribed(ax,ay,bx,by,cx,cy,px,py) {
1579
+ var dx=ax-px,dy=ay-py,ex=bx-px,ey=by-py,fx=cx-px,fy=cy-py;
1580
+ var ap=dx*dx+dy*dy,bp=ex*ex+ey*ey,cp=fx*fx+fy*fy;
1581
+ return dx*(ey*cp-bp*fy)-dy*(ex*cp-bp*fx)+ap*(ex*fy-ey*fx) > 0;
1582
+ }
1583
+ var st = [[-1e6,-1e6],[1e6,-1e6],[0,1e6]];
1584
+ triangles.push([n,n+1,n+2]);
1585
+ var all = points.concat(st);
1586
+ for (var i = 0; i < n; i++) {
1587
+ var pi = ids[i], px = all[pi][0], py = all[pi][1];
1588
+ var edges = [], bad = [];
1589
+ for (var j = 0; j < triangles.length; j++) {
1590
+ var t = triangles[j];
1591
+ if (circumscribed(all[t[0]][0],all[t[0]][1],all[t[1]][0],all[t[1]][1],all[t[2]][0],all[t[2]][1],px,py)) {
1592
+ bad.push(j);
1593
+ edges.push([t[0],t[1]],[t[1],t[2]],[t[2],t[0]]);
1594
+ }
1595
+ }
1596
+ for (var j = bad.length-1; j >= 0; j--) triangles.splice(bad[j],1);
1597
+ var unique = [];
1598
+ for (var j = 0; j < edges.length; j++) {
1599
+ var dup = false;
1600
+ for (var k = 0; k < edges.length; k++) {
1601
+ if (j !== k && edges[j][0]===edges[k][1] && edges[j][1]===edges[k][0]) { dup = true; break; }
1602
+ }
1603
+ if (!dup) unique.push(edges[j]);
1604
+ }
1605
+ for (var j = 0; j < unique.length; j++) triangles.push([unique[j][0], unique[j][1], pi]);
1606
+ }
1607
+ return triangles.filter(function(t) { return t[0] < n && t[1] < n && t[2] < n; });
1608
+ }
1609
+
1610
+ function voronoi(points, width, height, resolution) {
1611
+ resolution = resolution || 1;
1612
+ var cols = Math.ceil(width/resolution), rows = Math.ceil(height/resolution);
1613
+ var cells = new Int32Array(cols * rows);
1614
+ for (var y = 0; y < rows; y++)
1615
+ for (var x = 0; x < cols; x++) {
1616
+ var px = x * resolution, py = y * resolution;
1617
+ var minD = Infinity, minI = 0;
1618
+ for (var i = 0; i < points.length; i++) {
1619
+ var dx = px - points[i][0], dy = py - points[i][1];
1620
+ var d = dx*dx + dy*dy;
1621
+ if (d < minD) { minD = d; minI = i; }
1622
+ }
1623
+ cells[y * cols + x] = minI;
1624
+ }
1625
+ return { cells: cells, cols: cols, rows: rows };
1626
+ }
1627
+ `,
1628
+ exports: ["chaikinSmooth", "subdivideCurve", "offsetPath", "convexHull", "delaunay", "voronoi"],
1629
+ dependencies: ["vector", "shape"],
1630
+ description: "Computational geometry (Chaikin, convex hull, Delaunay, Voronoi).",
1631
+ usage: `### shape-advanced \u2014 Computational Geometry
1632
+
1633
+ \`\`\`js
1634
+ var smooth = chaikinSmooth(points, 3);
1635
+ var hull = convexHull(points);
1636
+ var tris = delaunay(points);
1637
+ var v = voronoi(points, 800, 600);
1638
+ \`\`\`
1639
+ `
1640
+ };
1641
+ var shape_advanced_default = shapeAdvanced;
1642
+
1643
+ // src/components/js/distribution.ts
1644
+ var distribution = {
1645
+ name: "distribution",
1646
+ version: "1.0.0",
1647
+ category: "distribution",
1648
+ target: "js",
1649
+ renderers: [],
1650
+ code: `function poissonDisk(rng, width, height, minDist, maxAttempts) {
1651
+ maxAttempts = maxAttempts || 30;
1652
+ var cellSize = minDist / Math.SQRT2;
1653
+ var cols = Math.ceil(width / cellSize), rows = Math.ceil(height / cellSize);
1654
+ var grid = new Array(cols * rows).fill(-1);
1655
+ var points = [], active = [];
1656
+ function addPoint(x, y) {
1657
+ var i = points.length;
1658
+ points.push([x, y]);
1659
+ active.push(i);
1660
+ var gx = Math.floor(x / cellSize), gy = Math.floor(y / cellSize);
1661
+ grid[gy * cols + gx] = i;
1662
+ }
1663
+ addPoint(rng() * width, rng() * height);
1664
+ while (active.length > 0) {
1665
+ var ri = Math.floor(rng() * active.length);
1666
+ var pi = active[ri], p = points[pi];
1667
+ var found = false;
1668
+ for (var attempt = 0; attempt < maxAttempts; attempt++) {
1669
+ var angle = rng() * Math.PI * 2;
1670
+ var dist = minDist + rng() * minDist;
1671
+ var nx = p[0] + Math.cos(angle) * dist, ny = p[1] + Math.sin(angle) * dist;
1672
+ if (nx < 0 || nx >= width || ny < 0 || ny >= height) continue;
1673
+ var gx = Math.floor(nx / cellSize), gy = Math.floor(ny / cellSize);
1674
+ var ok = true;
1675
+ for (var dy = -2; dy <= 2 && ok; dy++)
1676
+ for (var dx = -2; dx <= 2 && ok; dx++) {
1677
+ var cx = gx + dx, cy = gy + dy;
1678
+ if (cx < 0 || cx >= cols || cy < 0 || cy >= rows) continue;
1679
+ var ci = grid[cy * cols + cx];
1680
+ if (ci >= 0) {
1681
+ var cp = points[ci];
1682
+ var d2 = (nx-cp[0])*(nx-cp[0]) + (ny-cp[1])*(ny-cp[1]);
1683
+ if (d2 < minDist * minDist) ok = false;
1684
+ }
1685
+ }
1686
+ if (ok) { addPoint(nx, ny); found = true; break; }
1687
+ }
1688
+ if (!found) active.splice(ri, 1);
1689
+ }
1690
+ return points;
1691
+ }
1692
+
1693
+ function jitteredGrid(rng, width, height, cellSize, jitter) {
1694
+ jitter = jitter || 0.5;
1695
+ var pts = [];
1696
+ for (var y = cellSize/2; y < height; y += cellSize)
1697
+ for (var x = cellSize/2; x < width; x += cellSize)
1698
+ pts.push([x + (rng()-0.5)*cellSize*jitter, y + (rng()-0.5)*cellSize*jitter]);
1699
+ return pts;
1700
+ }
1701
+
1702
+ function haltonSequence(n, base1, base2) {
1703
+ base1 = base1 || 2; base2 = base2 || 3;
1704
+ function halton(i, base) {
1705
+ var f = 1, r = 0;
1706
+ while (i > 0) { f /= base; r += f * (i % base); i = Math.floor(i / base); }
1707
+ return r;
1708
+ }
1709
+ var pts = [];
1710
+ for (var i = 0; i < n; i++) pts.push([halton(i+1, base1), halton(i+1, base2)]);
1711
+ return pts;
1712
+ }
1713
+
1714
+ function uniformOnSphere(rng) {
1715
+ var u = rng(), v = rng();
1716
+ var theta = 2 * Math.PI * u;
1717
+ var phi = Math.acos(2 * v - 1);
1718
+ return [Math.sin(phi)*Math.cos(theta), Math.sin(phi)*Math.sin(theta), Math.cos(phi)];
1719
+ }
1720
+
1721
+ function gaussianCluster(rng, cx, cy, stddev, count) {
1722
+ var pts = [];
1723
+ for (var i = 0; i < count; i++) {
1724
+ var u1 = rng(), u2 = rng();
1725
+ var r = Math.sqrt(-2 * Math.log(u1 || 1e-10));
1726
+ var theta = 2 * Math.PI * u2;
1727
+ pts.push([cx + r * Math.cos(theta) * stddev, cy + r * Math.sin(theta) * stddev]);
1728
+ }
1729
+ return pts;
1730
+ }
1731
+ `,
1732
+ exports: ["poissonDisk", "jitteredGrid", "haltonSequence", "uniformOnSphere", "gaussianCluster"],
1733
+ dependencies: ["prng"],
1734
+ description: "Point distribution algorithms (Poisson disk, Halton, jittered grid).",
1735
+ usage: `### distribution \u2014 Point Distributions
1736
+
1737
+ \`\`\`js
1738
+ var pts = poissonDisk(rng, 800, 600, 20);
1739
+ var grid = jitteredGrid(rng, 800, 600, 40, 0.5);
1740
+ var halton = haltonSequence(100, 2, 3);
1741
+ var sphere = uniformOnSphere(rng);
1742
+ \`\`\`
1743
+ `
1744
+ };
1745
+ var distribution_default = distribution;
1746
+
1747
+ // src/components/js/distribution-advanced.ts
1748
+ var distributionAdvanced = {
1749
+ name: "distribution-advanced",
1750
+ version: "1.0.0",
1751
+ category: "distribution",
1752
+ target: "js",
1753
+ renderers: [],
1754
+ code: `function blueNoise(rng, width, height, count) {
1755
+ var pts = poissonDisk(rng, width, height, Math.sqrt(width * height / count));
1756
+ return pts.slice(0, count);
1757
+ }
1758
+
1759
+ function lloydRelaxation(points, width, height, iterations) {
1760
+ var pts = points.map(function(p) { return [p[0], p[1]]; });
1761
+ for (var iter = 0; iter < iterations; iter++) {
1762
+ var v = voronoi(pts, width, height, 2);
1763
+ var sums = new Array(pts.length);
1764
+ var counts = new Array(pts.length);
1765
+ for (var i = 0; i < pts.length; i++) { sums[i] = [0, 0]; counts[i] = 0; }
1766
+ for (var y = 0; y < v.rows; y++)
1767
+ for (var x = 0; x < v.cols; x++) {
1768
+ var ci = v.cells[y * v.cols + x];
1769
+ sums[ci][0] += x * 2; sums[ci][1] += y * 2;
1770
+ counts[ci]++;
1771
+ }
1772
+ for (var i = 0; i < pts.length; i++) {
1773
+ if (counts[i] > 0) {
1774
+ pts[i] = [sums[i][0] / counts[i], sums[i][1] / counts[i]];
1775
+ }
1776
+ }
1777
+ }
1778
+ return pts;
1779
+ }
1780
+
1781
+ function fibonacciSphere(n) {
1782
+ var pts = [];
1783
+ var goldenAngle = Math.PI * (3 - Math.sqrt(5));
1784
+ for (var i = 0; i < n; i++) {
1785
+ var y = 1 - (i / (n - 1)) * 2;
1786
+ var radius = Math.sqrt(1 - y * y);
1787
+ var theta = goldenAngle * i;
1788
+ pts.push([Math.cos(theta) * radius, y, Math.sin(theta) * radius]);
1789
+ }
1790
+ return pts;
1791
+ }
1792
+
1793
+ function uniformOnDisk(rng, count) {
1794
+ var pts = [];
1795
+ for (var i = 0; i < count; i++) {
1796
+ var r = Math.sqrt(rng());
1797
+ var theta = rng() * Math.PI * 2;
1798
+ pts.push([r * Math.cos(theta), r * Math.sin(theta)]);
1799
+ }
1800
+ return pts;
1801
+ }
1802
+
1803
+ function stratifiedSample(rng, width, height, nx, ny) {
1804
+ var pts = [];
1805
+ var cw = width / nx, ch = height / ny;
1806
+ for (var y = 0; y < ny; y++)
1807
+ for (var x = 0; x < nx; x++)
1808
+ pts.push([x * cw + rng() * cw, y * ch + rng() * ch]);
1809
+ return pts;
1810
+ }
1811
+ `,
1812
+ exports: ["blueNoise", "lloydRelaxation", "fibonacciSphere", "uniformOnDisk", "stratifiedSample"],
1813
+ dependencies: ["prng", "distribution"],
1814
+ description: "Advanced spatial sampling (blue noise, Lloyd, Fibonacci sphere).",
1815
+ usage: `### distribution-advanced \u2014 Advanced Sampling
1816
+
1817
+ \`\`\`js
1818
+ var pts = blueNoise(rng, 800, 600, 200);
1819
+ var relaxed = lloydRelaxation(pts, 800, 600, 5);
1820
+ var sphere = fibonacciSphere(100);
1821
+ var disk = uniformOnDisk(rng, 50);
1822
+ \`\`\`
1823
+ `
1824
+ };
1825
+ var distribution_advanced_default = distributionAdvanced;
1826
+
1827
+ // src/components/js/physics-spring.ts
1828
+ var physicsSpring = {
1829
+ name: "physics-spring",
1830
+ version: "1.0.0",
1831
+ category: "physics",
1832
+ target: "js",
1833
+ renderers: [],
1834
+ code: `function createSpring(restLength, stiffness, damping) {
1835
+ return { restLength: restLength, stiffness: stiffness || 100, damping: damping || 5 };
1836
+ }
1837
+
1838
+ function springSystem(points, springs) {
1839
+ return { points: points, springs: springs };
1840
+ }
1841
+
1842
+ function springStep(system, dt) {
1843
+ dt = dt || 1/60;
1844
+ for (var i = 0; i < system.springs.length; i++) {
1845
+ var s = system.springs[i];
1846
+ var a = system.points[s.a], b = system.points[s.b];
1847
+ var dx = b.x - a.x, dy = b.y - a.y;
1848
+ var dist = Math.sqrt(dx * dx + dy * dy) || 0.001;
1849
+ var force = s.stiffness * (dist - s.restLength);
1850
+ var dvx = b.vx - a.vx, dvy = b.vy - a.vy;
1851
+ var dampF = s.damping * (dvx * dx + dvy * dy) / dist;
1852
+ var fx = (force + dampF) * dx / dist;
1853
+ var fy = (force + dampF) * dy / dist;
1854
+ a.vx += fx * dt; a.vy += fy * dt;
1855
+ b.vx -= fx * dt; b.vy -= fy * dt;
1856
+ }
1857
+ for (var i = 0; i < system.points.length; i++) {
1858
+ var p = system.points[i];
1859
+ if (p.fixed) continue;
1860
+ p.x += p.vx * dt; p.y += p.vy * dt;
1861
+ }
1862
+ }
1863
+
1864
+ function dampedHarmonic(x, v, target, stiffness, damping, dt) {
1865
+ var force = -stiffness * (x - target) - damping * v;
1866
+ v += force * dt;
1867
+ x += v * dt;
1868
+ return { x: x, v: v };
1869
+ }
1870
+ `,
1871
+ exports: ["springSystem", "springStep", "createSpring", "dampedHarmonic"],
1872
+ dependencies: ["vector"],
1873
+ description: "Spring-based physics simulation.",
1874
+ usage: `### physics-spring \u2014 Spring Physics
1875
+
1876
+ \`\`\`js
1877
+ var points = [{x:0,y:0,vx:0,vy:0,fixed:true}, {x:100,y:0,vx:0,vy:0}];
1878
+ var springs = [{a:0, b:1, restLength:50, stiffness:100, damping:5}];
1879
+ var sys = springSystem(points, springs);
1880
+ springStep(sys, 1/60);
1881
+ \`\`\`
1882
+ `
1883
+ };
1884
+ var physics_spring_default = physicsSpring;
1885
+
1886
+ // src/components/js/physics-verlet.ts
1887
+ var physicsVerlet = {
1888
+ name: "physics-verlet",
1889
+ version: "1.0.0",
1890
+ category: "physics",
1891
+ target: "js",
1892
+ renderers: [],
1893
+ code: `function verletSystem(points) {
1894
+ return {
1895
+ points: points.map(function(p) {
1896
+ return { x: p.x, y: p.y, px: p.x, py: p.y, ax: 0, ay: 0, fixed: p.fixed || false };
1897
+ }),
1898
+ constraints: []
1899
+ };
1900
+ }
1901
+
1902
+ function verletStep(system, dt) {
1903
+ dt = dt || 1/60;
1904
+ var dt2 = dt * dt;
1905
+ for (var i = 0; i < system.points.length; i++) {
1906
+ var p = system.points[i];
1907
+ if (p.fixed) continue;
1908
+ var nx = 2 * p.x - p.px + p.ax * dt2;
1909
+ var ny = 2 * p.y - p.py + p.ay * dt2;
1910
+ p.px = p.x; p.py = p.y;
1911
+ p.x = nx; p.y = ny;
1912
+ p.ax = 0; p.ay = 0;
1913
+ }
1914
+ solveConstraints(system, 3);
1915
+ }
1916
+
1917
+ function addConstraint(system, a, b, restLength) {
1918
+ system.constraints.push({
1919
+ a: a, b: b,
1920
+ restLength: restLength !== undefined ? restLength :
1921
+ Math.sqrt(Math.pow(system.points[a].x - system.points[b].x, 2) + Math.pow(system.points[a].y - system.points[b].y, 2))
1922
+ });
1923
+ }
1924
+
1925
+ function solveConstraints(system, iterations) {
1926
+ iterations = iterations || 3;
1927
+ for (var iter = 0; iter < iterations; iter++) {
1928
+ for (var i = 0; i < system.constraints.length; i++) {
1929
+ var c = system.constraints[i];
1930
+ var a = system.points[c.a], b = system.points[c.b];
1931
+ var dx = b.x - a.x, dy = b.y - a.y;
1932
+ var dist = Math.sqrt(dx * dx + dy * dy) || 0.001;
1933
+ var diff = (c.restLength - dist) / dist * 0.5;
1934
+ var ox = dx * diff, oy = dy * diff;
1935
+ if (!a.fixed) { a.x -= ox; a.y -= oy; }
1936
+ if (!b.fixed) { b.x += ox; b.y += oy; }
1937
+ }
1938
+ }
1939
+ }
1940
+ `,
1941
+ exports: ["verletSystem", "verletStep", "addConstraint", "solveConstraints"],
1942
+ dependencies: ["vector"],
1943
+ description: "Verlet integration with distance constraints.",
1944
+ usage: `### physics-verlet \u2014 Verlet Integration
1945
+
1946
+ \`\`\`js
1947
+ var sys = verletSystem([{x:0,y:0,fixed:true},{x:50,y:0},{x:100,y:0}]);
1948
+ addConstraint(sys, 0, 1); addConstraint(sys, 1, 2);
1949
+ sys.points[2].ay = 98; // gravity
1950
+ verletStep(sys, 1/60);
1951
+ \`\`\`
1952
+ `
1953
+ };
1954
+ var physics_verlet_default = physicsVerlet;
1955
+
1956
+ // src/components/js/physics-rk4.ts
1957
+ var physicsRk4 = {
1958
+ name: "physics-rk4",
1959
+ version: "1.0.0",
1960
+ category: "physics",
1961
+ target: "js",
1962
+ renderers: [],
1963
+ code: `function rk4Step(state, derivsFn, dt) {
1964
+ var n = state.length;
1965
+ var k1 = derivsFn(state);
1966
+ var s2 = new Array(n);
1967
+ for (var i = 0; i < n; i++) s2[i] = state[i] + k1[i] * dt / 2;
1968
+ var k2 = derivsFn(s2);
1969
+ var s3 = new Array(n);
1970
+ for (var i = 0; i < n; i++) s3[i] = state[i] + k2[i] * dt / 2;
1971
+ var k3 = derivsFn(s3);
1972
+ var s4 = new Array(n);
1973
+ for (var i = 0; i < n; i++) s4[i] = state[i] + k3[i] * dt;
1974
+ var k4 = derivsFn(s4);
1975
+ var result = new Array(n);
1976
+ for (var i = 0; i < n; i++)
1977
+ result[i] = state[i] + (k1[i] + 2*k2[i] + 2*k3[i] + k4[i]) * dt / 6;
1978
+ return result;
1979
+ }
1980
+
1981
+ function rk4System(initialState, derivsFn, dt, steps) {
1982
+ var state = initialState.slice();
1983
+ var trajectory = [state.slice()];
1984
+ for (var s = 0; s < steps; s++) {
1985
+ state = rk4Step(state, derivsFn, dt);
1986
+ trajectory.push(state.slice());
1987
+ }
1988
+ return trajectory;
1989
+ }
1990
+
1991
+ function lorenzAttractor(sigma, rho, beta) {
1992
+ sigma = sigma || 10; rho = rho || 28; beta = beta || 8/3;
1993
+ return function(state) {
1994
+ return [
1995
+ sigma * (state[1] - state[0]),
1996
+ state[0] * (rho - state[2]) - state[1],
1997
+ state[0] * state[1] - beta * state[2]
1998
+ ];
1999
+ };
2000
+ }
2001
+
2002
+ function phasePortrait(derivsFn, xRange, yRange, gridSize) {
2003
+ var arrows = [];
2004
+ var dx = (xRange[1] - xRange[0]) / gridSize;
2005
+ var dy = (yRange[1] - yRange[0]) / gridSize;
2006
+ for (var i = 0; i <= gridSize; i++) {
2007
+ for (var j = 0; j <= gridSize; j++) {
2008
+ var x = xRange[0] + i * dx, y = yRange[0] + j * dy;
2009
+ var d = derivsFn([x, y]);
2010
+ arrows.push({ x: x, y: y, dx: d[0], dy: d[1] });
2011
+ }
2012
+ }
2013
+ return arrows;
2014
+ }
2015
+ `,
2016
+ exports: ["rk4Step", "rk4System", "lorenzAttractor", "phasePortrait"],
2017
+ dependencies: ["vector"],
2018
+ description: "Runge-Kutta integration and common ODEs (Lorenz attractor).",
2019
+ usage: `### physics-rk4 \u2014 RK4 Integration
2020
+
2021
+ \`\`\`js
2022
+ var lorenz = lorenzAttractor(10, 28, 8/3);
2023
+ var traj = rk4System([1,1,1], lorenz, 0.01, 5000);
2024
+ \`\`\`
2025
+ `
2026
+ };
2027
+ var physics_rk4_default = physicsRk4;
2028
+
2029
+ // src/components/js/flow-field.ts
2030
+ var flowField = {
2031
+ name: "flow-field",
2032
+ version: "1.0.0",
2033
+ category: "pattern",
2034
+ target: "js",
2035
+ renderers: [],
2036
+ code: `function createFlowField(cols, rows, angleFn) {
2037
+ var field = new Float64Array(cols * rows);
2038
+ for (var y = 0; y < rows; y++)
2039
+ for (var x = 0; x < cols; x++)
2040
+ field[y * cols + x] = angleFn(x, y);
2041
+ return { field: field, cols: cols, rows: rows };
2042
+ }
2043
+
2044
+ function flowFromNoise(noiseFn, cols, rows, scale) {
2045
+ return createFlowField(cols, rows, function(x, y) {
2046
+ return noiseFn(x * scale, y * scale) * Math.PI * 4;
2047
+ });
2048
+ }
2049
+
2050
+ function flowFromFunction(fn, cols, rows) {
2051
+ return createFlowField(cols, rows, fn);
2052
+ }
2053
+
2054
+ function traceStreamline(field, startX, startY, cellSize, steps, stepSize) {
2055
+ stepSize = stepSize || 1;
2056
+ var pts = [[startX, startY]];
2057
+ var x = startX, y = startY;
2058
+ for (var i = 0; i < steps; i++) {
2059
+ var gx = Math.floor(x / cellSize), gy = Math.floor(y / cellSize);
2060
+ if (gx < 0 || gx >= field.cols || gy < 0 || gy >= field.rows) break;
2061
+ var angle = field.field[gy * field.cols + gx];
2062
+ x += Math.cos(angle) * stepSize;
2063
+ y += Math.sin(angle) * stepSize;
2064
+ pts.push([x, y]);
2065
+ }
2066
+ return pts;
2067
+ }
2068
+ `,
2069
+ exports: ["createFlowField", "traceStreamline", "flowFromNoise", "flowFromFunction"],
2070
+ dependencies: ["noise-2d", "vector"],
2071
+ description: "Flow field generation and streamline tracing.",
2072
+ usage: `### flow-field \u2014 Flow Fields
2073
+
2074
+ \`\`\`js
2075
+ var field = flowFromNoise(perlin2D(rng), 80, 60, 0.03);
2076
+ var line = traceStreamline(field, startX, startY, 10, 200, 1);
2077
+ \`\`\`
2078
+ `
2079
+ };
2080
+ var flow_field_default = flowField;
2081
+
2082
+ // src/components/js/l-system.ts
2083
+ var lSystem = {
2084
+ name: "l-system",
2085
+ version: "1.0.0",
2086
+ category: "pattern",
2087
+ target: "js",
2088
+ renderers: [],
2089
+ code: `function createLSystem(axiom, rules) {
2090
+ return { axiom: axiom, rules: rules, current: axiom };
2091
+ }
2092
+
2093
+ function iterateLSystem(system, iterations) {
2094
+ var str = system.current;
2095
+ for (var iter = 0; iter < iterations; iter++) {
2096
+ var next = '';
2097
+ for (var i = 0; i < str.length; i++) {
2098
+ var ch = str[i];
2099
+ next += system.rules[ch] !== undefined ? system.rules[ch] : ch;
2100
+ }
2101
+ str = next;
2102
+ }
2103
+ system.current = str;
2104
+ return str;
2105
+ }
2106
+
2107
+ function turtleInterpret(str, stepLength, angleDeg) {
2108
+ var x = 0, y = 0, angle = -90;
2109
+ var rad = angleDeg * Math.PI / 180;
2110
+ var path = [[x, y]];
2111
+ var stack = [];
2112
+ for (var i = 0; i < str.length; i++) {
2113
+ var ch = str[i];
2114
+ if (ch === 'F' || ch === 'G') {
2115
+ x += Math.cos(angle * Math.PI / 180) * stepLength;
2116
+ y += Math.sin(angle * Math.PI / 180) * stepLength;
2117
+ path.push([x, y]);
2118
+ } else if (ch === 'f') {
2119
+ x += Math.cos(angle * Math.PI / 180) * stepLength;
2120
+ y += Math.sin(angle * Math.PI / 180) * stepLength;
2121
+ path.push(null);
2122
+ path.push([x, y]);
2123
+ } else if (ch === '+') { angle += angleDeg; }
2124
+ else if (ch === '-') { angle -= angleDeg; }
2125
+ else if (ch === '[') { stack.push({ x: x, y: y, angle: angle }); }
2126
+ else if (ch === ']') {
2127
+ var s = stack.pop();
2128
+ x = s.x; y = s.y; angle = s.angle;
2129
+ path.push(null);
2130
+ path.push([x, y]);
2131
+ }
2132
+ }
2133
+ return path;
2134
+ }
2135
+ `,
2136
+ exports: ["createLSystem", "iterateLSystem", "turtleInterpret"],
2137
+ dependencies: ["math"],
2138
+ description: "L-system grammar iteration and turtle graphics interpretation.",
2139
+ usage: `### l-system \u2014 L-Systems
2140
+
2141
+ \`\`\`js
2142
+ var sys = createLSystem('F', { 'F': 'F[+F]F[-F]F' });
2143
+ var str = iterateLSystem(sys, 4);
2144
+ var path = turtleInterpret(str, 5, 25.7);
2145
+ \`\`\`
2146
+ `
2147
+ };
2148
+ var l_system_default = lSystem;
2149
+
2150
+ // src/components/js/reaction-diffusion.ts
2151
+ var reactionDiffusion = {
2152
+ name: "reaction-diffusion",
2153
+ version: "1.0.0",
2154
+ category: "pattern",
2155
+ target: "js",
2156
+ renderers: [],
2157
+ code: `function createGrayScottGrid(cols, rows) {
2158
+ var a = new Float64Array(cols * rows).fill(1);
2159
+ var b = new Float64Array(cols * rows).fill(0);
2160
+ return { a: a, b: b, cols: cols, rows: rows };
2161
+ }
2162
+
2163
+ function grayScottStep(grid, feed, kill, dA, dB, dt) {
2164
+ feed = feed || 0.037; kill = kill || 0.06;
2165
+ dA = dA || 1.0; dB = dB || 0.5; dt = dt || 1.0;
2166
+ var cols = grid.cols, rows = grid.rows;
2167
+ var a = grid.a, b = grid.b;
2168
+ var na = new Float64Array(cols * rows);
2169
+ var nb = new Float64Array(cols * rows);
2170
+ for (var y = 0; y < rows; y++) {
2171
+ for (var x = 0; x < cols; x++) {
2172
+ var i = y * cols + x;
2173
+ var up = ((y-1+rows)%rows)*cols+x, dn = ((y+1)%rows)*cols+x;
2174
+ var lt = y*cols+(x-1+cols)%cols, rt = y*cols+(x+1)%cols;
2175
+ var lapA = a[up]+a[dn]+a[lt]+a[rt]-4*a[i];
2176
+ var lapB = b[up]+b[dn]+b[lt]+b[rt]-4*b[i];
2177
+ var abb = a[i] * b[i] * b[i];
2178
+ na[i] = a[i] + (dA * lapA - abb + feed * (1 - a[i])) * dt;
2179
+ nb[i] = b[i] + (dB * lapB + abb - (kill + feed) * b[i]) * dt;
2180
+ }
2181
+ }
2182
+ grid.a = na; grid.b = nb;
2183
+ return grid;
2184
+ }
2185
+
2186
+ function turingPattern(cols, rows, steps, feed, kill, rng) {
2187
+ var grid = createGrayScottGrid(cols, rows);
2188
+ var cx = cols/2, cy = rows/2, r = Math.min(cols, rows)/6;
2189
+ for (var y = Math.floor(cy-r); y <= Math.ceil(cy+r); y++)
2190
+ for (var x = Math.floor(cx-r); x <= Math.ceil(cx+r); x++)
2191
+ if ((x-cx)*(x-cx)+(y-cy)*(y-cy) < r*r) {
2192
+ var i = y * cols + x;
2193
+ grid.b[i] = 1;
2194
+ if (rng) { grid.a[i] += (rng()-0.5)*0.01; grid.b[i] += (rng()-0.5)*0.01; }
2195
+ }
2196
+ for (var s = 0; s < steps; s++) grayScottStep(grid, feed, kill);
2197
+ return grid;
2198
+ }
2199
+ `,
2200
+ exports: ["grayScottStep", "createGrayScottGrid", "turingPattern"],
2201
+ dependencies: [],
2202
+ description: "Reaction-diffusion simulation (Gray-Scott model).",
2203
+ usage: `### reaction-diffusion \u2014 Gray-Scott
2204
+
2205
+ \`\`\`js
2206
+ var grid = createGrayScottGrid(200, 200);
2207
+ // seed center region with chemical B
2208
+ for (var s = 0; s < 5000; s++) grayScottStep(grid, 0.037, 0.06);
2209
+ // grid.b contains the pattern
2210
+ \`\`\`
2211
+ `
2212
+ };
2213
+ var reaction_diffusion_default = reactionDiffusion;
2214
+
2215
+ // src/components/js/dla.ts
2216
+ var dla = {
2217
+ name: "dla",
2218
+ version: "1.0.0",
2219
+ category: "pattern",
2220
+ target: "js",
2221
+ renderers: [],
2222
+ code: `function diffusionLimitedAggregation(rng, width, height, seedCount, walkerCount, stickiness) {
2223
+ stickiness = stickiness || 1;
2224
+ var grid = new Uint8Array(width * height);
2225
+ for (var i = 0; i < seedCount; i++) {
2226
+ var sx = Math.floor(width / 2 + (rng() - 0.5) * 10);
2227
+ var sy = Math.floor(height / 2 + (rng() - 0.5) * 10);
2228
+ if (sx >= 0 && sx < width && sy >= 0 && sy < height) grid[sy * width + sx] = 1;
2229
+ }
2230
+ var attached = [];
2231
+ for (var y = 0; y < height; y++)
2232
+ for (var x = 0; x < width; x++)
2233
+ if (grid[y * width + x]) attached.push([x, y]);
2234
+
2235
+ for (var w = 0; w < walkerCount; w++) {
2236
+ var wx = Math.floor(rng() * width), wy = Math.floor(rng() * height);
2237
+ var stuck = false;
2238
+ for (var step = 0; step < 10000 && !stuck; step++) {
2239
+ wx += Math.round(rng() * 2 - 1);
2240
+ wy += Math.round(rng() * 2 - 1);
2241
+ if (wx < 0 || wx >= width || wy < 0 || wy >= height) {
2242
+ wx = Math.floor(rng() * width);
2243
+ wy = Math.floor(rng() * height);
2244
+ continue;
2245
+ }
2246
+ for (var dx = -1; dx <= 1 && !stuck; dx++)
2247
+ for (var dy = -1; dy <= 1 && !stuck; dy++) {
2248
+ var nx = wx + dx, ny = wy + dy;
2249
+ if (nx >= 0 && nx < width && ny >= 0 && ny < height && grid[ny * width + nx]) {
2250
+ if (rng() < stickiness) {
2251
+ grid[wy * width + wx] = 1;
2252
+ attached.push([wx, wy]);
2253
+ stuck = true;
2254
+ }
2255
+ }
2256
+ }
2257
+ }
2258
+ }
2259
+ return { grid: grid, points: attached, width: width, height: height };
2260
+ }
2261
+
2262
+ function dlaStep(state, rng, walkers, stickiness) {
2263
+ walkers = walkers || 100;
2264
+ stickiness = stickiness || 1;
2265
+ var w = state.width, h = state.height, grid = state.grid;
2266
+ for (var i = 0; i < walkers; i++) {
2267
+ var wx = Math.floor(rng() * w), wy = Math.floor(rng() * h);
2268
+ for (var step = 0; step < 500; step++) {
2269
+ wx += Math.round(rng() * 2 - 1);
2270
+ wy += Math.round(rng() * 2 - 1);
2271
+ if (wx < 0 || wx >= w || wy < 0 || wy >= h) break;
2272
+ var hasN = false;
2273
+ for (var dx = -1; dx <= 1 && !hasN; dx++)
2274
+ for (var dy = -1; dy <= 1 && !hasN; dy++) {
2275
+ var nx = wx + dx, ny = wy + dy;
2276
+ if (nx >= 0 && nx < w && ny >= 0 && ny < h && grid[ny * w + nx]) hasN = true;
2277
+ }
2278
+ if (hasN && rng() < stickiness) {
2279
+ grid[wy * w + wx] = 1;
2280
+ state.points.push([wx, wy]);
2281
+ break;
2282
+ }
2283
+ }
2284
+ }
2285
+ return state;
2286
+ }
2287
+ `,
2288
+ exports: ["diffusionLimitedAggregation", "dlaStep"],
2289
+ dependencies: ["prng"],
2290
+ description: "Diffusion-limited aggregation (DLA) pattern generation.",
2291
+ usage: `### dla \u2014 Diffusion-Limited Aggregation
2292
+
2293
+ \`\`\`js
2294
+ var state = diffusionLimitedAggregation(rng, 400, 400, 1, 5000, 0.8);
2295
+ // state.grid \u2014 occupancy grid
2296
+ // state.points \u2014 attached point coordinates
2297
+ \`\`\`
2298
+ `
2299
+ };
2300
+ var dla_default = dla;
2301
+
2302
+ // src/components/js/boids.ts
2303
+ var boids = {
2304
+ name: "boids",
2305
+ version: "1.0.0",
2306
+ category: "particle",
2307
+ target: "js",
2308
+ renderers: [],
2309
+ code: `function createBoidSystem(count, rng, width, height) {
2310
+ var boids = [];
2311
+ for (var i = 0; i < count; i++) {
2312
+ var angle = rng() * Math.PI * 2;
2313
+ var speed = 1 + rng() * 2;
2314
+ boids.push({
2315
+ x: rng() * width, y: rng() * height,
2316
+ vx: Math.cos(angle) * speed, vy: Math.sin(angle) * speed
2317
+ });
2318
+ }
2319
+ return { boids: boids, width: width, height: height };
2320
+ }
2321
+
2322
+ function separationForce(boid, neighbors, sepDist) {
2323
+ var sx = 0, sy = 0;
2324
+ for (var i = 0; i < neighbors.length; i++) {
2325
+ var dx = boid.x - neighbors[i].x, dy = boid.y - neighbors[i].y;
2326
+ var d = Math.sqrt(dx*dx + dy*dy);
2327
+ if (d > 0 && d < sepDist) { sx += dx / d; sy += dy / d; }
2328
+ }
2329
+ return [sx, sy];
2330
+ }
2331
+
2332
+ function alignmentForce(boid, neighbors) {
2333
+ if (neighbors.length === 0) return [0, 0];
2334
+ var ax = 0, ay = 0;
2335
+ for (var i = 0; i < neighbors.length; i++) {
2336
+ ax += neighbors[i].vx; ay += neighbors[i].vy;
2337
+ }
2338
+ return [(ax / neighbors.length - boid.vx) * 0.1, (ay / neighbors.length - boid.vy) * 0.1];
2339
+ }
2340
+
2341
+ function cohesionForce(boid, neighbors) {
2342
+ if (neighbors.length === 0) return [0, 0];
2343
+ var cx = 0, cy = 0;
2344
+ for (var i = 0; i < neighbors.length; i++) {
2345
+ cx += neighbors[i].x; cy += neighbors[i].y;
2346
+ }
2347
+ return [(cx / neighbors.length - boid.x) * 0.005, (cy / neighbors.length - boid.y) * 0.005];
2348
+ }
2349
+
2350
+ function updateBoids(system, perception, sepDist, maxSpeed) {
2351
+ perception = perception || 50; sepDist = sepDist || 25; maxSpeed = maxSpeed || 4;
2352
+ for (var i = 0; i < system.boids.length; i++) {
2353
+ var b = system.boids[i];
2354
+ var neighbors = [];
2355
+ for (var j = 0; j < system.boids.length; j++) {
2356
+ if (i === j) continue;
2357
+ var dx = system.boids[j].x - b.x, dy = system.boids[j].y - b.y;
2358
+ if (dx*dx + dy*dy < perception * perception) neighbors.push(system.boids[j]);
2359
+ }
2360
+ var sep = separationForce(b, neighbors, sepDist);
2361
+ var ali = alignmentForce(b, neighbors);
2362
+ var coh = cohesionForce(b, neighbors);
2363
+ b.vx += sep[0] * 0.15 + ali[0] + coh[0];
2364
+ b.vy += sep[1] * 0.15 + ali[1] + coh[1];
2365
+ var spd = Math.sqrt(b.vx*b.vx + b.vy*b.vy);
2366
+ if (spd > maxSpeed) { b.vx = b.vx/spd*maxSpeed; b.vy = b.vy/spd*maxSpeed; }
2367
+ b.x += b.vx; b.y += b.vy;
2368
+ if (b.x < 0) b.x += system.width;
2369
+ if (b.x > system.width) b.x -= system.width;
2370
+ if (b.y < 0) b.y += system.height;
2371
+ if (b.y > system.height) b.y -= system.height;
2372
+ }
2373
+ }
2374
+ `,
2375
+ exports: ["createBoidSystem", "updateBoids", "separationForce", "alignmentForce", "cohesionForce"],
2376
+ dependencies: ["vector"],
2377
+ description: "Boid flocking algorithm (separation, alignment, cohesion).",
2378
+ usage: `### boids \u2014 Flocking Algorithm
2379
+
2380
+ \`\`\`js
2381
+ var sys = createBoidSystem(200, rng, width, height);
2382
+ updateBoids(sys, 50, 25, 4);
2383
+ sys.boids.forEach(function(b) { drawBoid(b); });
2384
+ \`\`\`
2385
+ `
2386
+ };
2387
+ var boids_default = boids;
2388
+
2389
+ // src/components/js/wave.ts
2390
+ var wave = {
2391
+ name: "wave",
2392
+ version: "1.0.0",
2393
+ category: "animation",
2394
+ target: "js",
2395
+ renderers: [],
2396
+ code: `function sineWave(t, freq, amp, phase) {
2397
+ return (amp || 1) * Math.sin(2 * Math.PI * (freq || 1) * t + (phase || 0));
2398
+ }
2399
+
2400
+ function squareWave(t, freq) {
2401
+ return Math.sin(2 * Math.PI * (freq || 1) * t) >= 0 ? 1 : -1;
2402
+ }
2403
+
2404
+ function sawtoothWave(t, freq) {
2405
+ var p = t * (freq || 1);
2406
+ return 2 * (p - Math.floor(p + 0.5));
2407
+ }
2408
+
2409
+ function triangleWave(t, freq) {
2410
+ var p = t * (freq || 1);
2411
+ return 4 * Math.abs(p - Math.floor(p + 0.75) + 0.25) - 1;
2412
+ }
2413
+
2414
+ function waveSum(waveFns, t) {
2415
+ var sum = 0;
2416
+ for (var i = 0; i < waveFns.length; i++) sum += waveFns[i](t);
2417
+ return sum;
2418
+ }
2419
+
2420
+ function standingWave(x, t, freq, wavelength) {
2421
+ return Math.sin(2 * Math.PI * x / (wavelength || 1)) * Math.cos(2 * Math.PI * (freq || 1) * t);
2422
+ }
2423
+ `,
2424
+ exports: ["sineWave", "squareWave", "sawtoothWave", "triangleWave", "waveSum", "standingWave"],
2425
+ dependencies: ["math"],
2426
+ description: "Periodic wave functions (sine, square, sawtooth, triangle).",
2427
+ usage: `### wave \u2014 Wave Functions
2428
+
2429
+ \`\`\`js
2430
+ sineWave(t, 2, 1, 0); // 2 Hz sine
2431
+ squareWave(t, 1); // 1 Hz square
2432
+ triangleWave(t, 0.5); // 0.5 Hz triangle
2433
+ standingWave(x, t, 1, 100);
2434
+ \`\`\`
2435
+ `
2436
+ };
2437
+ var wave_default = wave;
2438
+
2439
+ // src/components/js/animation.ts
2440
+ var animation = {
2441
+ name: "animation",
2442
+ version: "1.0.0",
2443
+ category: "animation",
2444
+ target: "js",
2445
+ renderers: [],
2446
+ code: `function pingPong(t) {
2447
+ t = t % 2;
2448
+ return t <= 1 ? t : 2 - t;
2449
+ }
2450
+
2451
+ function loop(t, duration) {
2452
+ return (t % duration) / duration;
2453
+ }
2454
+
2455
+ function oscillate(t, min, max, freq) {
2456
+ return min + (max - min) * 0.5 * (1 + Math.sin(2 * Math.PI * (freq || 1) * t));
2457
+ }
2458
+
2459
+ function stagger(index, total, duration, offset) {
2460
+ offset = offset || 0.1;
2461
+ return Math.max(0, Math.min(1, (duration - index * offset) / (duration - (total-1) * offset)));
2462
+ }
2463
+
2464
+ function timeline(t, keyframes) {
2465
+ for (var i = 0; i < keyframes.length - 1; i++) {
2466
+ var a = keyframes[i], b = keyframes[i+1];
2467
+ if (t >= a.t && t <= b.t) {
2468
+ var p = (t - a.t) / (b.t - a.t);
2469
+ if (b.ease) p = b.ease(p);
2470
+ return a.value + (b.value - a.value) * p;
2471
+ }
2472
+ }
2473
+ return keyframes[keyframes.length - 1].value;
2474
+ }
2475
+
2476
+ function sequence(t, segments) {
2477
+ var totalDuration = 0;
2478
+ for (var i = 0; i < segments.length; i++) totalDuration += segments[i].duration;
2479
+ t = t % totalDuration;
2480
+ var elapsed = 0;
2481
+ for (var i = 0; i < segments.length; i++) {
2482
+ if (t < elapsed + segments[i].duration) {
2483
+ var local = (t - elapsed) / segments[i].duration;
2484
+ return segments[i].fn(local);
2485
+ }
2486
+ elapsed += segments[i].duration;
2487
+ }
2488
+ return segments[segments.length - 1].fn(1);
2489
+ }
2490
+ `,
2491
+ exports: ["pingPong", "loop", "oscillate", "stagger", "timeline", "sequence"],
2492
+ dependencies: ["math", "easing"],
2493
+ description: "Animation timing utilities (ping-pong, stagger, timeline, sequence).",
2494
+ usage: `### animation \u2014 Timing Utilities
2495
+
2496
+ \`\`\`js
2497
+ pingPong(t); // 0\u21921\u21920\u21921...
2498
+ loop(t, 5); // repeats every 5 seconds
2499
+ oscillate(t, 0, 100, 2); // bounces 0\u2194100 at 2 Hz
2500
+ timeline(t, [
2501
+ { t: 0, value: 0 },
2502
+ { t: 1, value: 100, ease: easeInOutCubic },
2503
+ { t: 2, value: 50 }
2504
+ ]);
2505
+ \`\`\`
2506
+ `
2507
+ };
2508
+ var animation_default = animation;
2509
+
2510
+ // src/components/js/quadtree.ts
2511
+ var quadtree = {
2512
+ name: "quadtree",
2513
+ version: "1.0.0",
2514
+ category: "data-structure",
2515
+ target: "js",
2516
+ renderers: [],
2517
+ code: `function createQuadTree(x, y, w, h, capacity) {
2518
+ return { x: x, y: y, w: w, h: h, capacity: capacity || 4, points: [], children: null };
2519
+ }
2520
+
2521
+ function insertPoint(qt, px, py, data) {
2522
+ if (px < qt.x || px >= qt.x + qt.w || py < qt.y || py >= qt.y + qt.h) return false;
2523
+ if (qt.points.length < qt.capacity && !qt.children) {
2524
+ qt.points.push({ x: px, y: py, data: data });
2525
+ return true;
2526
+ }
2527
+ if (!qt.children) {
2528
+ var hw = qt.w/2, hh = qt.h/2;
2529
+ qt.children = [
2530
+ createQuadTree(qt.x, qt.y, hw, hh, qt.capacity),
2531
+ createQuadTree(qt.x+hw, qt.y, hw, hh, qt.capacity),
2532
+ createQuadTree(qt.x, qt.y+hh, hw, hh, qt.capacity),
2533
+ createQuadTree(qt.x+hw, qt.y+hh, hw, hh, qt.capacity)
2534
+ ];
2535
+ for (var i = 0; i < qt.points.length; i++) {
2536
+ var p = qt.points[i];
2537
+ for (var c = 0; c < 4; c++) if (insertPoint(qt.children[c], p.x, p.y, p.data)) break;
2538
+ }
2539
+ qt.points = [];
2540
+ }
2541
+ for (var c = 0; c < 4; c++) if (insertPoint(qt.children[c], px, py, data)) return true;
2542
+ return false;
2543
+ }
2544
+
2545
+ function queryRange(qt, rx, ry, rw, rh) {
2546
+ var found = [];
2547
+ if (qt.x + qt.w < rx || qt.x > rx + rw || qt.y + qt.h < ry || qt.y > ry + rh) return found;
2548
+ for (var i = 0; i < qt.points.length; i++) {
2549
+ var p = qt.points[i];
2550
+ if (p.x >= rx && p.x <= rx + rw && p.y >= ry && p.y <= ry + rh) found.push(p);
2551
+ }
2552
+ if (qt.children) {
2553
+ for (var c = 0; c < 4; c++) found = found.concat(queryRange(qt.children[c], rx, ry, rw, rh));
2554
+ }
2555
+ return found;
2556
+ }
2557
+
2558
+ function queryRadius(qt, cx, cy, r) {
2559
+ var found = [];
2560
+ var r2 = r * r;
2561
+ function search(node) {
2562
+ if (cx - r > node.x + node.w || cx + r < node.x || cy - r > node.y + node.h || cy + r < node.y) return;
2563
+ for (var i = 0; i < node.points.length; i++) {
2564
+ var p = node.points[i];
2565
+ var dx = p.x - cx, dy = p.y - cy;
2566
+ if (dx*dx + dy*dy <= r2) found.push(p);
2567
+ }
2568
+ if (node.children) for (var c = 0; c < 4; c++) search(node.children[c]);
2569
+ }
2570
+ search(qt);
2571
+ return found;
2572
+ }
2573
+ `,
2574
+ exports: ["createQuadTree", "insertPoint", "queryRange", "queryRadius"],
2575
+ dependencies: [],
2576
+ description: "Quadtree spatial index for efficient neighbor queries.",
2577
+ usage: `### quadtree \u2014 Spatial Index
2578
+
2579
+ \`\`\`js
2580
+ var qt = createQuadTree(0, 0, 800, 600, 8);
2581
+ points.forEach(function(p) { insertPoint(qt, p.x, p.y, p); });
2582
+ var nearby = queryRadius(qt, mouseX, mouseY, 50);
2583
+ \`\`\`
2584
+ `
2585
+ };
2586
+ var quadtree_default = quadtree;
2587
+
2588
+ // src/components/js/spatial-hash.ts
2589
+ var spatialHash = {
2590
+ name: "spatial-hash",
2591
+ version: "1.0.0",
2592
+ category: "data-structure",
2593
+ target: "js",
2594
+ renderers: [],
2595
+ code: `function createSpatialHash(cellSize) {
2596
+ return { cellSize: cellSize, cells: {} };
2597
+ }
2598
+
2599
+ function insertCell(hash, x, y, data) {
2600
+ var cx = Math.floor(x / hash.cellSize);
2601
+ var cy = Math.floor(y / hash.cellSize);
2602
+ var key = cx + ',' + cy;
2603
+ if (!hash.cells[key]) hash.cells[key] = [];
2604
+ hash.cells[key].push({ x: x, y: y, data: data });
2605
+ }
2606
+
2607
+ function queryNearby(hash, x, y, radius) {
2608
+ var cs = hash.cellSize;
2609
+ var minCx = Math.floor((x - radius) / cs);
2610
+ var maxCx = Math.floor((x + radius) / cs);
2611
+ var minCy = Math.floor((y - radius) / cs);
2612
+ var maxCy = Math.floor((y + radius) / cs);
2613
+ var r2 = radius * radius;
2614
+ var results = [];
2615
+ for (var cy = minCy; cy <= maxCy; cy++) {
2616
+ for (var cx = minCx; cx <= maxCx; cx++) {
2617
+ var cell = hash.cells[cx + ',' + cy];
2618
+ if (!cell) continue;
2619
+ for (var i = 0; i < cell.length; i++) {
2620
+ var p = cell[i];
2621
+ var dx = p.x - x, dy = p.y - y;
2622
+ if (dx * dx + dy * dy <= r2) results.push(p);
2623
+ }
2624
+ }
2625
+ }
2626
+ return results;
2627
+ }
2628
+ `,
2629
+ exports: ["createSpatialHash", "insertCell", "queryNearby"],
2630
+ dependencies: [],
2631
+ description: "Grid-based spatial hashing for fast neighbor lookups.",
2632
+ usage: `### spatial-hash \u2014 Spatial Hashing
2633
+
2634
+ \`\`\`js
2635
+ var hash = createSpatialHash(50);
2636
+ points.forEach(function(p) { insertCell(hash, p.x, p.y, p); });
2637
+ var nearby = queryNearby(hash, x, y, 100);
2638
+ \`\`\`
2639
+ `
2640
+ };
2641
+ var spatial_hash_default = spatialHash;
2642
+
2643
+ // src/components/js/turtle.ts
2644
+ var turtle = {
2645
+ name: "turtle",
2646
+ version: "1.0.0",
2647
+ category: "geometry",
2648
+ target: "js",
2649
+ renderers: [],
2650
+ code: `function createTurtle(x, y, angle) {
2651
+ return { x: x || 0, y: y || 0, angle: angle || 0, pen: true, path: [[x || 0, y || 0]] };
2652
+ }
2653
+
2654
+ function forward(t, dist) {
2655
+ var rad = t.angle * Math.PI / 180;
2656
+ t.x += Math.cos(rad) * dist;
2657
+ t.y += Math.sin(rad) * dist;
2658
+ if (t.pen) t.path.push([t.x, t.y]);
2659
+ return t;
2660
+ }
2661
+
2662
+ function turn(t, degrees) {
2663
+ t.angle += degrees;
2664
+ return t;
2665
+ }
2666
+
2667
+ function penUp(t) {
2668
+ t.pen = false;
2669
+ return t;
2670
+ }
2671
+
2672
+ function penDown(t) {
2673
+ t.pen = true;
2674
+ t.path.push(null);
2675
+ t.path.push([t.x, t.y]);
2676
+ return t;
2677
+ }
2678
+
2679
+ function getPath(t) {
2680
+ return t.path;
2681
+ }
2682
+ `,
2683
+ exports: ["createTurtle", "forward", "turn", "penUp", "penDown", "getPath"],
2684
+ dependencies: ["vector"],
2685
+ description: "Turtle graphics state machine for path generation.",
2686
+ usage: `### turtle \u2014 Turtle Graphics
2687
+
2688
+ \`\`\`js
2689
+ var t = createTurtle(400, 300, 0);
2690
+ for (var i = 0; i < 360; i++) { forward(t, 2); turn(t, 1); }
2691
+ var path = getPath(t); // circle-like path
2692
+ \`\`\`
2693
+ `
2694
+ };
2695
+ var turtle_default = turtle;
2696
+
2697
+ // src/components/js/svg-path.ts
2698
+ var svgPath = {
2699
+ name: "svg-path",
2700
+ version: "1.0.0",
2701
+ category: "geometry",
2702
+ target: "js",
2703
+ renderers: [],
2704
+ code: `function pathFromPoints(points, closed) {
2705
+ if (!points.length) return '';
2706
+ var d = 'M ' + points[0][0] + ' ' + points[0][1];
2707
+ for (var i = 1; i < points.length; i++) {
2708
+ if (points[i] === null) {
2709
+ if (i + 1 < points.length && points[i + 1]) {
2710
+ d += ' M ' + points[i + 1][0] + ' ' + points[i + 1][1];
2711
+ i++;
2712
+ }
2713
+ } else {
2714
+ d += ' L ' + points[i][0] + ' ' + points[i][1];
2715
+ }
2716
+ }
2717
+ if (closed) d += ' Z';
2718
+ return d;
2719
+ }
2720
+
2721
+ function arcPath(cx, cy, r, startAngle, endAngle) {
2722
+ var x1 = cx + r * Math.cos(startAngle), y1 = cy + r * Math.sin(startAngle);
2723
+ var x2 = cx + r * Math.cos(endAngle), y2 = cy + r * Math.sin(endAngle);
2724
+ var largeArc = Math.abs(endAngle - startAngle) > Math.PI ? 1 : 0;
2725
+ return 'M ' + x1 + ' ' + y1 + ' A ' + r + ' ' + r + ' 0 ' + largeArc + ' 1 ' + x2 + ' ' + y2;
2726
+ }
2727
+
2728
+ function bezierPath(points) {
2729
+ if (points.length < 4) return pathFromPoints(points);
2730
+ var d = 'M ' + points[0][0] + ' ' + points[0][1];
2731
+ for (var i = 1; i + 2 < points.length; i += 3) {
2732
+ d += ' C ' + points[i][0] + ' ' + points[i][1] + ', ' +
2733
+ points[i+1][0] + ' ' + points[i+1][1] + ', ' +
2734
+ points[i+2][0] + ' ' + points[i+2][1];
2735
+ }
2736
+ return d;
2737
+ }
2738
+
2739
+ function closePath(d) { return d + ' Z'; }
2740
+
2741
+ function pathToString(segments) {
2742
+ return segments.join(' ');
2743
+ }
2744
+ `,
2745
+ exports: ["pathFromPoints", "arcPath", "bezierPath", "closePath", "pathToString"],
2746
+ dependencies: [],
2747
+ description: "SVG path string builders (points to path, arcs, bezier curves).",
2748
+ usage: `### svg-path \u2014 SVG Path Builders
2749
+
2750
+ \`\`\`js
2751
+ var d = pathFromPoints(points, true); // closed polygon
2752
+ var arc = arcPath(100, 100, 50, 0, Math.PI);
2753
+ var curve = bezierPath(controlPoints);
2754
+ \`\`\`
2755
+ `
2756
+ };
2757
+ var svg_path_default = svgPath;
2758
+
2759
+ // src/components/js/canvas-utils.ts
2760
+ var canvasUtils = {
2761
+ name: "canvas-utils",
2762
+ version: "1.0.0",
2763
+ category: "imaging",
2764
+ target: "js",
2765
+ renderers: [],
2766
+ code: `function pixelAt(imageData, x, y) {
2767
+ var i = (y * imageData.width + x) * 4;
2768
+ return [imageData.data[i], imageData.data[i+1], imageData.data[i+2], imageData.data[i+3]];
2769
+ }
2770
+
2771
+ function setPixelAt(imageData, x, y, r, g, b, a) {
2772
+ var i = (y * imageData.width + x) * 4;
2773
+ imageData.data[i] = r; imageData.data[i+1] = g;
2774
+ imageData.data[i+2] = b; imageData.data[i+3] = a !== undefined ? a : 255;
2775
+ }
2776
+
2777
+ function forEachPixel(imageData, fn) {
2778
+ for (var y = 0; y < imageData.height; y++)
2779
+ for (var x = 0; x < imageData.width; x++) {
2780
+ var i = (y * imageData.width + x) * 4;
2781
+ fn(x, y, imageData.data[i], imageData.data[i+1], imageData.data[i+2], imageData.data[i+3], i);
2782
+ }
2783
+ }
2784
+
2785
+ function convolve3x3(imageData, kernel) {
2786
+ var w = imageData.width, h = imageData.height;
2787
+ var src = new Uint8ClampedArray(imageData.data);
2788
+ for (var y = 1; y < h-1; y++)
2789
+ for (var x = 1; x < w-1; x++) {
2790
+ var r=0,g=0,b=0;
2791
+ for (var ky = -1; ky <= 1; ky++)
2792
+ for (var kx = -1; kx <= 1; kx++) {
2793
+ var i = ((y+ky)*w+(x+kx))*4;
2794
+ var k = kernel[(ky+1)*3+(kx+1)];
2795
+ r += src[i]*k; g += src[i+1]*k; b += src[i+2]*k;
2796
+ }
2797
+ var oi = (y*w+x)*4;
2798
+ imageData.data[oi] = Math.max(0,Math.min(255,r));
2799
+ imageData.data[oi+1] = Math.max(0,Math.min(255,g));
2800
+ imageData.data[oi+2] = Math.max(0,Math.min(255,b));
2801
+ }
2802
+ }
2803
+
2804
+ function threshold(imageData, level) {
2805
+ for (var i = 0; i < imageData.data.length; i += 4) {
2806
+ var v = (imageData.data[i]*0.299 + imageData.data[i+1]*0.587 + imageData.data[i+2]*0.114) >= level ? 255 : 0;
2807
+ imageData.data[i] = imageData.data[i+1] = imageData.data[i+2] = v;
2808
+ }
2809
+ }
2810
+
2811
+ function dither(imageData) {
2812
+ var w = imageData.width, h = imageData.height;
2813
+ var buf = new Float64Array(w * h);
2814
+ for (var i = 0; i < buf.length; i++)
2815
+ buf[i] = imageData.data[i*4]*0.299 + imageData.data[i*4+1]*0.587 + imageData.data[i*4+2]*0.114;
2816
+ for (var y = 0; y < h; y++)
2817
+ for (var x = 0; x < w; x++) {
2818
+ var old = buf[y*w+x];
2819
+ var nw = old < 128 ? 0 : 255;
2820
+ buf[y*w+x] = nw;
2821
+ var err = old - nw;
2822
+ if (x+1<w) buf[y*w+x+1] += err*7/16;
2823
+ if (y+1<h) {
2824
+ if (x>0) buf[(y+1)*w+x-1] += err*3/16;
2825
+ buf[(y+1)*w+x] += err*5/16;
2826
+ if (x+1<w) buf[(y+1)*w+x+1] += err/16;
2827
+ }
2828
+ }
2829
+ for (var i = 0; i < buf.length; i++) {
2830
+ var v = Math.max(0, Math.min(255, Math.round(buf[i])));
2831
+ imageData.data[i*4] = imageData.data[i*4+1] = imageData.data[i*4+2] = v;
2832
+ }
2833
+ }
2834
+ `,
2835
+ exports: ["pixelAt", "setPixelAt", "forEachPixel", "convolve3x3", "threshold", "dither"],
2836
+ dependencies: [],
2837
+ description: "ImageData pixel manipulation (read, write, convolve, dither).",
2838
+ usage: `### canvas-utils \u2014 Pixel Manipulation
2839
+
2840
+ \`\`\`js
2841
+ var px = pixelAt(imageData, x, y); // [r, g, b, a]
2842
+ setPixelAt(imageData, x, y, 255, 0, 0);
2843
+ convolve3x3(imageData, [0,-1,0,-1,5,-1,0,-1,0]); // sharpen
2844
+ threshold(imageData, 128);
2845
+ dither(imageData); // Floyd-Steinberg
2846
+ \`\`\`
2847
+ `
2848
+ };
2849
+ var canvas_utils_default = canvasUtils;
2850
+
2851
+ // src/components/glsl/index.ts
2852
+ var glsl_exports = {};
2853
+ __export(glsl_exports, {
2854
+ glslBlend: () => blend_default,
2855
+ glslColor: () => color_default2,
2856
+ glslCurl: () => curl_default2,
2857
+ glslDomain: () => domain_default,
2858
+ glslEasing: () => easing_default2,
2859
+ glslGradient: () => gradient_default,
2860
+ glslLighting: () => lighting_default,
2861
+ glslMath: () => math_default2,
2862
+ glslNoise: () => noise_default,
2863
+ glslNoise3d: () => noise_3d_default2,
2864
+ glslNoise4d: () => noise_4d_default2,
2865
+ glslPattern: () => pattern_default,
2866
+ glslPost: () => post_default,
2867
+ glslRay: () => ray_default,
2868
+ glslSdf: () => sdf_default,
2869
+ glslSdf3d: () => sdf_3d_default,
2870
+ glslShape: () => shape_default2,
2871
+ glslTransform: () => transform_default
2872
+ });
2873
+
2874
+ // src/components/glsl/noise.ts
2875
+ var glslNoise = {
2876
+ name: "glsl-noise",
2877
+ version: "1.0.0",
2878
+ category: "noise",
2879
+ target: "glsl",
2880
+ renderers: [],
2881
+ code: `float hash(vec2 p) {
2882
+ return fract(sin(dot(p, vec2(127.1, 311.7))) * 43758.5453);
2883
+ }
2884
+
2885
+ float noise(vec2 p) {
2886
+ vec2 i = floor(p);
2887
+ vec2 f = fract(p);
2888
+ f = f * f * (3.0 - 2.0 * f);
2889
+ float a = hash(i);
2890
+ float b = hash(i + vec2(1.0, 0.0));
2891
+ float c = hash(i + vec2(0.0, 1.0));
2892
+ float d = hash(i + vec2(1.0, 1.0));
2893
+ return mix(mix(a, b, f.x), mix(c, d, f.x), f.y);
2894
+ }
2895
+
2896
+ float fbm(vec2 p, int octaves) {
2897
+ float val = 0.0, amp = 0.5;
2898
+ for (int i = 0; i < 8; i++) {
2899
+ if (i >= octaves) break;
2900
+ val += amp * noise(p);
2901
+ p *= 2.0;
2902
+ amp *= 0.5;
2903
+ }
2904
+ return val;
2905
+ }
2906
+
2907
+ float voronoi(vec2 p) {
2908
+ vec2 n = floor(p);
2909
+ vec2 f = fract(p);
2910
+ float minDist = 1.0;
2911
+ for (int j = -1; j <= 1; j++) {
2912
+ for (int i = -1; i <= 1; i++) {
2913
+ vec2 g = vec2(float(i), float(j));
2914
+ vec2 o = vec2(hash(n + g), hash(n + g + vec2(37.0, 17.0)));
2915
+ vec2 diff = g + o - f;
2916
+ minDist = min(minDist, dot(diff, diff));
2917
+ }
2918
+ }
2919
+ return sqrt(minDist);
2920
+ }
2921
+ `,
2922
+ exports: ["hash", "noise", "fbm", "voronoi"],
2923
+ dependencies: [],
2924
+ description: "Standard GLSL noise stack (hash, value noise, fBm, Voronoi).",
2925
+ usage: `### glsl-noise \u2014 GLSL Noise
2926
+
2927
+ \`\`\`glsl
2928
+ float n = noise(uv * 10.0);
2929
+ float f = fbm(uv * 5.0, 6);
2930
+ float v = voronoi(uv * 8.0);
2931
+ \`\`\`
2932
+ `
2933
+ };
2934
+ var noise_default = glslNoise;
2935
+
2936
+ // src/components/glsl/noise-3d.ts
2937
+ var glslNoise3d = {
2938
+ name: "glsl-noise-3d",
2939
+ version: "1.0.0",
2940
+ category: "noise",
2941
+ target: "glsl",
2942
+ renderers: [],
2943
+ code: `float hash3(vec3 p) {
2944
+ p = fract(p * vec3(443.897, 441.423, 437.195));
2945
+ p += dot(p, p.yzx + 19.19);
2946
+ return fract((p.x + p.y) * p.z);
2947
+ }
2948
+
2949
+ float noise3(vec3 p) {
2950
+ vec3 i = floor(p);
2951
+ vec3 f = fract(p);
2952
+ f = f * f * (3.0 - 2.0 * f);
2953
+ float a = hash3(i);
2954
+ float b = hash3(i + vec3(1.0, 0.0, 0.0));
2955
+ float c = hash3(i + vec3(0.0, 1.0, 0.0));
2956
+ float d = hash3(i + vec3(1.0, 1.0, 0.0));
2957
+ float e = hash3(i + vec3(0.0, 0.0, 1.0));
2958
+ float f2 = hash3(i + vec3(1.0, 0.0, 1.0));
2959
+ float g = hash3(i + vec3(0.0, 1.0, 1.0));
2960
+ float h = hash3(i + vec3(1.0, 1.0, 1.0));
2961
+ float x1 = mix(mix(a, b, f.x), mix(c, d, f.x), f.y);
2962
+ float x2 = mix(mix(e, f2, f.x), mix(g, h, f.x), f.y);
2963
+ return mix(x1, x2, f.z);
2964
+ }
2965
+
2966
+ float fbm3(vec3 p, int octaves) {
2967
+ float val = 0.0, amp = 0.5;
2968
+ for (int i = 0; i < 8; i++) {
2969
+ if (i >= octaves) break;
2970
+ val += amp * noise3(p);
2971
+ p *= 2.0;
2972
+ amp *= 0.5;
2973
+ }
2974
+ return val;
2975
+ }
2976
+ `,
2977
+ exports: ["hash3", "noise3", "fbm3"],
2978
+ dependencies: [],
2979
+ description: "3D GLSL noise (hash, value noise, fBm).",
2980
+ usage: `### glsl-noise-3d \u2014 3D Noise
2981
+
2982
+ \`\`\`glsl
2983
+ float n = noise3(vec3(uv * 5.0, u_time));
2984
+ float f = fbm3(vec3(uv * 3.0, u_time * 0.5), 6);
2985
+ \`\`\`
2986
+ `
2987
+ };
2988
+ var noise_3d_default2 = glslNoise3d;
2989
+
2990
+ // src/components/glsl/noise-4d.ts
2991
+ var glslNoise4d = {
2992
+ name: "glsl-noise-4d",
2993
+ version: "1.0.0",
2994
+ category: "noise",
2995
+ target: "glsl",
2996
+ renderers: [],
2997
+ code: `float noise4(vec4 p) {
2998
+ vec4 i = floor(p);
2999
+ vec4 f = fract(p);
3000
+ f = f * f * (3.0 - 2.0 * f);
3001
+ float h1 = fract(sin(dot(i, vec4(127.1,311.7,269.5,183.3))) * 43758.5453);
3002
+ float h2 = fract(sin(dot(i + vec4(1,0,0,0), vec4(127.1,311.7,269.5,183.3))) * 43758.5453);
3003
+ float h3 = fract(sin(dot(i + vec4(0,1,0,0), vec4(127.1,311.7,269.5,183.3))) * 43758.5453);
3004
+ float h4 = fract(sin(dot(i + vec4(1,1,0,0), vec4(127.1,311.7,269.5,183.3))) * 43758.5453);
3005
+ float h5 = fract(sin(dot(i + vec4(0,0,1,0), vec4(127.1,311.7,269.5,183.3))) * 43758.5453);
3006
+ float h6 = fract(sin(dot(i + vec4(1,0,1,0), vec4(127.1,311.7,269.5,183.3))) * 43758.5453);
3007
+ float h7 = fract(sin(dot(i + vec4(0,1,1,0), vec4(127.1,311.7,269.5,183.3))) * 43758.5453);
3008
+ float h8 = fract(sin(dot(i + vec4(1,1,1,0), vec4(127.1,311.7,269.5,183.3))) * 43758.5453);
3009
+ float h9 = fract(sin(dot(i + vec4(0,0,0,1), vec4(127.1,311.7,269.5,183.3))) * 43758.5453);
3010
+ float h10 = fract(sin(dot(i + vec4(1,0,0,1), vec4(127.1,311.7,269.5,183.3))) * 43758.5453);
3011
+ float h11 = fract(sin(dot(i + vec4(0,1,0,1), vec4(127.1,311.7,269.5,183.3))) * 43758.5453);
3012
+ float h12 = fract(sin(dot(i + vec4(1,1,0,1), vec4(127.1,311.7,269.5,183.3))) * 43758.5453);
3013
+ float h13 = fract(sin(dot(i + vec4(0,0,1,1), vec4(127.1,311.7,269.5,183.3))) * 43758.5453);
3014
+ float h14 = fract(sin(dot(i + vec4(1,0,1,1), vec4(127.1,311.7,269.5,183.3))) * 43758.5453);
3015
+ float h15 = fract(sin(dot(i + vec4(0,1,1,1), vec4(127.1,311.7,269.5,183.3))) * 43758.5453);
3016
+ float h16 = fract(sin(dot(i + vec4(1,1,1,1), vec4(127.1,311.7,269.5,183.3))) * 43758.5453);
3017
+ float x1 = mix(mix(h1,h2,f.x), mix(h3,h4,f.x), f.y);
3018
+ float x2 = mix(mix(h5,h6,f.x), mix(h7,h8,f.x), f.y);
3019
+ float x3 = mix(mix(h9,h10,f.x), mix(h11,h12,f.x), f.y);
3020
+ float x4 = mix(mix(h13,h14,f.x), mix(h15,h16,f.x), f.y);
3021
+ return mix(mix(x1,x2,f.z), mix(x3,x4,f.z), f.w);
3022
+ }
3023
+
3024
+ float fbm4(vec4 p, int octaves) {
3025
+ float val = 0.0, amp = 0.5;
3026
+ for (int i = 0; i < 8; i++) {
3027
+ if (i >= octaves) break;
3028
+ val += amp * noise4(p);
3029
+ p *= 2.0;
3030
+ amp *= 0.5;
3031
+ }
3032
+ return val;
3033
+ }
3034
+ `,
3035
+ exports: ["noise4", "fbm4"],
3036
+ dependencies: [],
3037
+ description: "4D GLSL noise for loopable animations.",
3038
+ usage: `### glsl-noise-4d \u2014 4D Noise
3039
+
3040
+ \`\`\`glsl
3041
+ float n = noise4(vec4(uv * 5.0, cos(t) * r, sin(t) * r));
3042
+ \`\`\`
3043
+ `
3044
+ };
3045
+ var noise_4d_default2 = glslNoise4d;
3046
+
3047
+ // src/components/glsl/curl.ts
3048
+ var glslCurl = {
3049
+ name: "glsl-curl",
3050
+ version: "1.0.0",
3051
+ category: "noise",
3052
+ target: "glsl",
3053
+ renderers: [],
3054
+ code: `vec2 curlNoise(vec2 p) {
3055
+ float eps = 0.001;
3056
+ float n1 = noise(p + vec2(eps, 0.0));
3057
+ float n2 = noise(p - vec2(eps, 0.0));
3058
+ float n3 = noise(p + vec2(0.0, eps));
3059
+ float n4 = noise(p - vec2(0.0, eps));
3060
+ float dndx = (n1 - n2) / (2.0 * eps);
3061
+ float dndy = (n3 - n4) / (2.0 * eps);
3062
+ return vec2(dndy, -dndx);
3063
+ }
3064
+ `,
3065
+ exports: ["curlNoise"],
3066
+ dependencies: ["glsl-noise"],
3067
+ description: "GLSL curl noise for divergence-free flow.",
3068
+ usage: `### glsl-curl \u2014 Curl Noise
3069
+
3070
+ \`\`\`glsl
3071
+ vec2 flow = curlNoise(uv * 5.0);
3072
+ \`\`\`
3073
+ `
3074
+ };
3075
+ var curl_default2 = glslCurl;
3076
+
3077
+ // src/components/glsl/sdf.ts
3078
+ var glslSdf = {
3079
+ name: "glsl-sdf",
3080
+ version: "1.0.0",
3081
+ category: "sdf",
3082
+ target: "glsl",
3083
+ renderers: [],
3084
+ code: `float sdCircle(vec2 p, float r) {
3085
+ return length(p) - r;
3086
+ }
3087
+
3088
+ float sdBox(vec2 p, vec2 b) {
3089
+ vec2 d = abs(p) - b;
3090
+ return length(max(d, 0.0)) + min(max(d.x, d.y), 0.0);
3091
+ }
3092
+
3093
+ float sdLine(vec2 p, vec2 a, vec2 b) {
3094
+ vec2 pa = p - a, ba = b - a;
3095
+ float h = clamp(dot(pa, ba) / dot(ba, ba), 0.0, 1.0);
3096
+ return length(pa - ba * h);
3097
+ }
3098
+
3099
+ float sdPolygon(vec2 p, vec2 v[8], int n) {
3100
+ float d = dot(p - v[0], p - v[0]);
3101
+ float s = 1.0;
3102
+ for (int i = 0, j = n - 1; i < 8; j = i, i++) {
3103
+ if (i >= n) break;
3104
+ vec2 e = v[j] - v[i];
3105
+ vec2 w = p - v[i];
3106
+ vec2 b = w - e * clamp(dot(w, e) / dot(e, e), 0.0, 1.0);
3107
+ d = min(d, dot(b, b));
3108
+ bvec3 cond = bvec3(p.y >= v[i].y, p.y < v[j].y, e.x * w.y > e.y * w.x);
3109
+ if (all(cond) || all(not(cond))) s *= -1.0;
3110
+ }
3111
+ return s * sqrt(d);
3112
+ }
3113
+
3114
+ float sdRing(vec2 p, float r, float thickness) {
3115
+ return abs(length(p) - r) - thickness;
3116
+ }
3117
+
3118
+ float opUnion(float d1, float d2) { return min(d1, d2); }
3119
+ float opSubtract(float d1, float d2) { return max(-d1, d2); }
3120
+ float opIntersect(float d1, float d2) { return max(d1, d2); }
3121
+ float opSmooth(float d1, float d2, float k) {
3122
+ float h = clamp(0.5 + 0.5 * (d2 - d1) / k, 0.0, 1.0);
3123
+ return mix(d2, d1, h) - k * h * (1.0 - h);
3124
+ }
3125
+ `,
3126
+ exports: ["sdCircle", "sdBox", "sdLine", "sdPolygon", "sdRing", "opUnion", "opSubtract", "opIntersect", "opSmooth"],
3127
+ dependencies: [],
3128
+ description: "2D signed distance functions and CSG operations.",
3129
+ usage: `### glsl-sdf \u2014 2D SDF
3130
+
3131
+ \`\`\`glsl
3132
+ float d = sdCircle(uv - 0.5, 0.2);
3133
+ d = opSmooth(d, sdBox(uv - vec2(0.7), vec2(0.1)), 0.05);
3134
+ vec3 col = mix(vec3(1), vec3(0), smoothstep(0.0, 0.01, d));
3135
+ \`\`\`
3136
+ `
3137
+ };
3138
+ var sdf_default = glslSdf;
3139
+
3140
+ // src/components/glsl/sdf-3d.ts
3141
+ var glslSdf3d = {
3142
+ name: "glsl-sdf-3d",
3143
+ version: "1.0.0",
3144
+ category: "sdf",
3145
+ target: "glsl",
3146
+ renderers: [],
3147
+ code: `float sdSphere(vec3 p, float r) { return length(p) - r; }
3148
+
3149
+ float sdBox3(vec3 p, vec3 b) {
3150
+ vec3 d = abs(p) - b;
3151
+ return length(max(d, 0.0)) + min(max(d.x, max(d.y, d.z)), 0.0);
3152
+ }
3153
+
3154
+ float sdCylinder(vec3 p, float h, float r) {
3155
+ vec2 d = abs(vec2(length(p.xz), p.y)) - vec2(r, h);
3156
+ return min(max(d.x, d.y), 0.0) + length(max(d, 0.0));
3157
+ }
3158
+
3159
+ float sdTorus(vec3 p, vec2 t) {
3160
+ vec2 q = vec2(length(p.xz) - t.x, p.y);
3161
+ return length(q) - t.y;
3162
+ }
3163
+
3164
+ float opUnion3(float d1, float d2) { return min(d1, d2); }
3165
+ float opSmooth3(float d1, float d2, float k) {
3166
+ float h = clamp(0.5 + 0.5 * (d2 - d1) / k, 0.0, 1.0);
3167
+ return mix(d2, d1, h) - k * h * (1.0 - h);
3168
+ }
3169
+
3170
+ vec3 opRepeat(vec3 p, vec3 c) {
3171
+ return mod(p + 0.5 * c, c) - 0.5 * c;
3172
+ }
3173
+ `,
3174
+ exports: ["sdSphere", "sdBox3", "sdCylinder", "sdTorus", "opUnion3", "opSmooth3", "opRepeat"],
3175
+ dependencies: [],
3176
+ description: "3D SDF primitives (sphere, box, cylinder, torus) and operations.",
3177
+ usage: `### glsl-sdf-3d \u2014 3D SDF
3178
+
3179
+ \`\`\`glsl
3180
+ float d = sdSphere(p, 1.0);
3181
+ d = opSmooth3(d, sdBox3(p - vec3(1.5, 0, 0), vec3(0.5)), 0.2);
3182
+ \`\`\`
3183
+ `
3184
+ };
3185
+ var sdf_3d_default = glslSdf3d;
3186
+
3187
+ // src/components/glsl/color.ts
3188
+ var glslColor = {
3189
+ name: "glsl-color",
3190
+ version: "1.0.0",
3191
+ category: "color",
3192
+ target: "glsl",
3193
+ renderers: [],
3194
+ code: `vec3 rgb2hsv(vec3 c) {
3195
+ vec4 K = vec4(0.0, -1.0/3.0, 2.0/3.0, -1.0);
3196
+ vec4 p = mix(vec4(c.bg, K.wz), vec4(c.gb, K.xy), step(c.b, c.g));
3197
+ vec4 q = mix(vec4(p.xyw, c.r), vec4(c.r, p.yzx), step(p.x, c.r));
3198
+ float d = q.x - min(q.w, q.y);
3199
+ float e = 1.0e-10;
3200
+ return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);
3201
+ }
3202
+
3203
+ vec3 hsv2rgb(vec3 c) {
3204
+ vec4 K = vec4(1.0, 2.0/3.0, 1.0/3.0, 3.0);
3205
+ vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www);
3206
+ return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y);
3207
+ }
3208
+
3209
+ vec3 rgb2hsl(vec3 c) {
3210
+ float maxC = max(c.r, max(c.g, c.b));
3211
+ float minC = min(c.r, min(c.g, c.b));
3212
+ float l = (maxC + minC) * 0.5;
3213
+ if (maxC == minC) return vec3(0.0, 0.0, l);
3214
+ float d = maxC - minC;
3215
+ float s = l > 0.5 ? d / (2.0 - maxC - minC) : d / (maxC + minC);
3216
+ float h;
3217
+ if (maxC == c.r) h = (c.g - c.b) / d + (c.g < c.b ? 6.0 : 0.0);
3218
+ else if (maxC == c.g) h = (c.b - c.r) / d + 2.0;
3219
+ else h = (c.r - c.g) / d + 4.0;
3220
+ h /= 6.0;
3221
+ return vec3(h, s, l);
3222
+ }
3223
+
3224
+ vec3 hsl2rgb(vec3 c) {
3225
+ if (c.y == 0.0) return vec3(c.z);
3226
+ float q = c.z < 0.5 ? c.z * (1.0 + c.y) : c.z + c.y - c.z * c.y;
3227
+ float p = 2.0 * c.z - q;
3228
+ vec3 t = vec3(c.x + 1.0/3.0, c.x, c.x - 1.0/3.0);
3229
+ t = fract(t);
3230
+ vec3 r;
3231
+ for (int i = 0; i < 3; i++) {
3232
+ float ti = i == 0 ? t.x : (i == 1 ? t.y : t.z);
3233
+ float v;
3234
+ if (ti < 1.0/6.0) v = p + (q - p) * 6.0 * ti;
3235
+ else if (ti < 0.5) v = q;
3236
+ else if (ti < 2.0/3.0) v = p + (q - p) * (2.0/3.0 - ti) * 6.0;
3237
+ else v = p;
3238
+ if (i == 0) r.x = v;
3239
+ else if (i == 1) r.y = v;
3240
+ else r.z = v;
3241
+ }
3242
+ return r;
3243
+ }
3244
+
3245
+ vec3 rgb2oklab(vec3 c) {
3246
+ float l = 0.4122214708 * c.r + 0.5363325363 * c.g + 0.0514459929 * c.b;
3247
+ float m = 0.2119034982 * c.r + 0.6806995451 * c.g + 0.1073969566 * c.b;
3248
+ float s = 0.0883024619 * c.r + 0.2817188376 * c.g + 0.6299787005 * c.b;
3249
+ l = pow(l, 1.0/3.0); m = pow(m, 1.0/3.0); s = pow(s, 1.0/3.0);
3250
+ return vec3(
3251
+ 0.2104542553*l + 0.7936177850*m - 0.0040720468*s,
3252
+ 1.9779984951*l - 2.4285922050*m + 0.4505937099*s,
3253
+ 0.0259040371*l + 0.7827717662*m - 0.8086757660*s
3254
+ );
3255
+ }
3256
+
3257
+ vec3 oklab2rgb(vec3 lab) {
3258
+ float l = lab.x + 0.3963377774*lab.y + 0.2158037573*lab.z;
3259
+ float m = lab.x - 0.1055613458*lab.y - 0.0638541728*lab.z;
3260
+ float s = lab.x - 0.0894841775*lab.y - 1.2914855480*lab.z;
3261
+ l=l*l*l; m=m*m*m; s=s*s*s;
3262
+ return vec3(
3263
+ 4.0767416621*l - 3.3077115913*m + 0.2309699292*s,
3264
+ -1.2684380046*l + 2.6097574011*m - 0.3413193965*s,
3265
+ -0.0041960863*l - 0.7034186147*m + 1.7076147010*s
3266
+ );
3267
+ }
3268
+
3269
+ vec3 posterize(vec3 c, float levels) {
3270
+ return floor(c * levels + 0.5) / levels;
3271
+ }
3272
+
3273
+ vec3 quantize(vec3 c, float steps) {
3274
+ return floor(c * steps) / steps;
3275
+ }
3276
+ `,
3277
+ exports: ["rgb2hsv", "hsv2rgb", "rgb2hsl", "hsl2rgb", "rgb2oklab", "oklab2rgb", "posterize", "quantize"],
3278
+ dependencies: [],
3279
+ description: "GLSL color space conversions (HSV, HSL, OKLab) and quantization.",
3280
+ usage: `### glsl-color \u2014 Color Spaces
3281
+
3282
+ \`\`\`glsl
3283
+ vec3 hsv = rgb2hsv(color);
3284
+ hsv.x += 0.1; // hue shift
3285
+ color = hsv2rgb(hsv);
3286
+ color = posterize(color, 4.0);
3287
+ \`\`\`
3288
+ `
3289
+ };
3290
+ var color_default2 = glslColor;
3291
+
3292
+ // src/components/glsl/pattern.ts
3293
+ var glslPattern = {
3294
+ name: "glsl-pattern",
3295
+ version: "1.0.0",
3296
+ category: "pattern",
3297
+ target: "glsl",
3298
+ renderers: [],
3299
+ code: `float truchet(vec2 uv, float scale) {
3300
+ vec2 id = floor(uv * scale);
3301
+ vec2 f = fract(uv * scale);
3302
+ float r = hash(id);
3303
+ if (r > 0.5) f.x = 1.0 - f.x;
3304
+ float d1 = length(f) - 0.5;
3305
+ float d2 = length(f - 1.0) - 0.5;
3306
+ return min(abs(d1), abs(d2));
3307
+ }
3308
+
3309
+ float checkerboard(vec2 uv, float scale) {
3310
+ vec2 c = floor(uv * scale);
3311
+ return mod(c.x + c.y, 2.0);
3312
+ }
3313
+
3314
+ vec2 hexGrid(vec2 uv) {
3315
+ vec2 s = vec2(1.0, 1.7320508);
3316
+ vec2 a = mod(uv, s) - s * 0.5;
3317
+ vec2 b = mod(uv - s * 0.5, s) - s * 0.5;
3318
+ return dot(a, a) < dot(b, b) ? a : b;
3319
+ }
3320
+
3321
+ float voronoiEdges(vec2 uv, float scale) {
3322
+ vec2 p = uv * scale;
3323
+ vec2 n = floor(p);
3324
+ vec2 f = fract(p);
3325
+ float md = 8.0;
3326
+ for (int j = -1; j <= 1; j++)
3327
+ for (int i = -1; i <= 1; i++) {
3328
+ vec2 g = vec2(float(i), float(j));
3329
+ vec2 o = vec2(hash(n + g), hash(n + g + vec2(37.0)));
3330
+ vec2 r = g + o - f;
3331
+ md = min(md, dot(r, r));
3332
+ }
3333
+ return sqrt(md);
3334
+ }
3335
+
3336
+ float stripes(vec2 uv, float freq, float angle) {
3337
+ float c = cos(angle), s = sin(angle);
3338
+ float t = uv.x * c + uv.y * s;
3339
+ return 0.5 + 0.5 * sin(t * freq * 6.28318);
3340
+ }
3341
+
3342
+ float dots(vec2 uv, float scale, float radius) {
3343
+ vec2 f = fract(uv * scale) - 0.5;
3344
+ return smoothstep(radius, radius - 0.01, length(f));
3345
+ }
3346
+ `,
3347
+ exports: ["truchet", "checkerboard", "hexGrid", "voronoiEdges", "stripes", "dots"],
3348
+ dependencies: ["glsl-noise"],
3349
+ description: "Tiling and pattern functions (truchet, hex grid, stripes, dots).",
3350
+ usage: `### glsl-pattern \u2014 Patterns
3351
+
3352
+ \`\`\`glsl
3353
+ float t = truchet(uv, 10.0);
3354
+ float c = checkerboard(uv, 8.0);
3355
+ float s = stripes(uv, 20.0, 0.785);
3356
+ \`\`\`
3357
+ `
3358
+ };
3359
+ var pattern_default = glslPattern;
3360
+
3361
+ // src/components/glsl/transform.ts
3362
+ var glslTransform = {
3363
+ name: "glsl-transform",
3364
+ version: "1.0.0",
3365
+ category: "transform",
3366
+ target: "glsl",
3367
+ renderers: [],
3368
+ code: `vec2 rotate2D(vec2 p, float angle) {
3369
+ float c = cos(angle), s = sin(angle);
3370
+ return vec2(p.x * c - p.y * s, p.x * s + p.y * c);
3371
+ }
3372
+
3373
+ vec2 scale2D(vec2 p, vec2 s) { return p / s; }
3374
+ vec2 translate2D(vec2 p, vec2 t) { return p - t; }
3375
+
3376
+ vec2 kaleidoscope(vec2 p, float segments) {
3377
+ float angle = atan(p.y, p.x);
3378
+ float r = length(p);
3379
+ float seg = 6.28318 / segments;
3380
+ angle = mod(angle, seg);
3381
+ if (angle > seg * 0.5) angle = seg - angle;
3382
+ return vec2(cos(angle), sin(angle)) * r;
3383
+ }
3384
+
3385
+ vec2 polarCoords(vec2 p) {
3386
+ return vec2(length(p), atan(p.y, p.x));
3387
+ }
3388
+
3389
+ vec2 fishEye(vec2 uv, float strength) {
3390
+ vec2 c = uv - 0.5;
3391
+ float r = length(c);
3392
+ float bind = sqrt(dot(vec2(0.5), vec2(0.5)));
3393
+ vec2 nuv = c / bind;
3394
+ nuv *= 1.0 - strength + strength * r;
3395
+ return nuv * bind + 0.5;
3396
+ }
3397
+
3398
+ vec2 ripple(vec2 uv, vec2 center, float freq, float amp, float time) {
3399
+ vec2 d = uv - center;
3400
+ float r = length(d);
3401
+ float offset = sin(r * freq - time) * amp;
3402
+ return uv + normalize(d) * offset;
3403
+ }
3404
+ `,
3405
+ exports: ["rotate2D", "scale2D", "translate2D", "kaleidoscope", "polarCoords", "fishEye", "ripple"],
3406
+ dependencies: [],
3407
+ description: "UV coordinate transformations (rotate, kaleidoscope, fisheye, ripple).",
3408
+ usage: `### glsl-transform \u2014 UV Transforms
3409
+
3410
+ \`\`\`glsl
3411
+ vec2 p = rotate2D(uv - 0.5, u_time) + 0.5;
3412
+ p = kaleidoscope(p - 0.5, 6.0);
3413
+ p = fishEye(uv, 0.5);
3414
+ \`\`\`
3415
+ `
3416
+ };
3417
+ var transform_default = glslTransform;
3418
+
3419
+ // src/components/glsl/math.ts
3420
+ var glslMath = {
3421
+ name: "glsl-math",
3422
+ version: "1.0.0",
3423
+ category: "math",
3424
+ target: "glsl",
3425
+ renderers: [],
3426
+ code: `float remap(float value, float inMin, float inMax, float outMin, float outMax) {
3427
+ return outMin + (value - inMin) / (inMax - inMin) * (outMax - outMin);
3428
+ }
3429
+
3430
+ float mod289(float x) { return x - floor(x * (1.0 / 289.0)) * 289.0; }
3431
+
3432
+ float inverseLerp(float a, float b, float v) { return (v - a) / (b - a); }
3433
+
3434
+ float smoothmin(float a, float b, float k) {
3435
+ float h = max(k - abs(a - b), 0.0) / k;
3436
+ return min(a, b) - h * h * h * k * (1.0 / 6.0);
3437
+ }
3438
+
3439
+ float bias(float x, float b) {
3440
+ return x / ((1.0 / b - 2.0) * (1.0 - x) + 1.0);
3441
+ }
3442
+
3443
+ float gain(float x, float g) {
3444
+ if (x < 0.5) return bias(x * 2.0, g) * 0.5;
3445
+ return bias(x * 2.0 - 1.0, 1.0 - g) * 0.5 + 0.5;
3446
+ }
3447
+ `,
3448
+ exports: ["remap", "mod289", "inverseLerp", "smoothmin", "bias", "gain"],
3449
+ dependencies: [],
3450
+ description: "GLSL math utilities (remap, smoothmin, bias, gain).",
3451
+ usage: `### glsl-math \u2014 GLSL Math
3452
+
3453
+ \`\`\`glsl
3454
+ float v = remap(x, 0.0, 1.0, -1.0, 1.0);
3455
+ float s = smoothmin(d1, d2, 0.1);
3456
+ float b = bias(x, 0.3);
3457
+ \`\`\`
3458
+ `
3459
+ };
3460
+ var math_default2 = glslMath;
3461
+
3462
+ // src/components/glsl/easing.ts
3463
+ var glslEasing = {
3464
+ name: "glsl-easing",
3465
+ version: "1.0.0",
3466
+ category: "easing",
3467
+ target: "glsl",
3468
+ renderers: [],
3469
+ code: `float easeInQuad(float t) { return t * t; }
3470
+ float easeOutQuad(float t) { return t * (2.0 - t); }
3471
+ float easeInOutCubic(float t) {
3472
+ return t < 0.5 ? 4.0 * t * t * t : 1.0 - pow(-2.0 * t + 2.0, 3.0) / 2.0;
3473
+ }
3474
+ float easeOutElastic(float t) {
3475
+ if (t == 0.0 || t == 1.0) return t;
3476
+ return pow(2.0, -10.0 * t) * sin((t * 10.0 - 0.75) * (6.28318 / 3.0)) + 1.0;
3477
+ }
3478
+ float easeOutBounce(float t) {
3479
+ if (t < 1.0 / 2.75) return 7.5625 * t * t;
3480
+ if (t < 2.0 / 2.75) { t -= 1.5 / 2.75; return 7.5625 * t * t + 0.75; }
3481
+ if (t < 2.5 / 2.75) { t -= 2.25 / 2.75; return 7.5625 * t * t + 0.9375; }
3482
+ t -= 2.625 / 2.75; return 7.5625 * t * t + 0.984375;
3483
+ }
3484
+ `,
3485
+ exports: ["easeInQuad", "easeOutQuad", "easeInOutCubic", "easeOutElastic", "easeOutBounce"],
3486
+ dependencies: [],
3487
+ description: "Easing functions in GLSL.",
3488
+ usage: `### glsl-easing \u2014 GLSL Easing
3489
+
3490
+ \`\`\`glsl
3491
+ float t = easeInOutCubic(progress);
3492
+ float e = easeOutElastic(progress);
3493
+ \`\`\`
3494
+ `
3495
+ };
3496
+ var easing_default2 = glslEasing;
3497
+
3498
+ // src/components/glsl/blend.ts
3499
+ var glslBlend = {
3500
+ name: "glsl-blend",
3501
+ version: "1.0.0",
3502
+ category: "color",
3503
+ target: "glsl",
3504
+ renderers: [],
3505
+ code: `vec3 blendMultiply(vec3 base, vec3 blend) { return base * blend; }
3506
+ vec3 blendScreen(vec3 base, vec3 blend) { return 1.0 - (1.0 - base) * (1.0 - blend); }
3507
+ vec3 blendOverlay(vec3 base, vec3 blend) {
3508
+ return vec3(
3509
+ base.r < 0.5 ? 2.0 * base.r * blend.r : 1.0 - 2.0 * (1.0 - base.r) * (1.0 - blend.r),
3510
+ base.g < 0.5 ? 2.0 * base.g * blend.g : 1.0 - 2.0 * (1.0 - base.g) * (1.0 - blend.g),
3511
+ base.b < 0.5 ? 2.0 * base.b * blend.b : 1.0 - 2.0 * (1.0 - base.b) * (1.0 - blend.b)
3512
+ );
3513
+ }
3514
+ vec3 blendSoftLight(vec3 base, vec3 blend) {
3515
+ return mix(
3516
+ sqrt(base) * (2.0 * blend - 1.0) + 2.0 * base * (1.0 - blend),
3517
+ 2.0 * base * blend + base * base * (1.0 - 2.0 * blend),
3518
+ step(vec3(0.5), blend)
3519
+ );
3520
+ }
3521
+ vec3 blendAdd(vec3 base, vec3 blend) { return min(base + blend, vec3(1.0)); }
3522
+ `,
3523
+ exports: ["blendMultiply", "blendScreen", "blendOverlay", "blendSoftLight", "blendAdd"],
3524
+ dependencies: [],
3525
+ description: "Photoshop-style blend modes in GLSL.",
3526
+ usage: `### glsl-blend \u2014 Blend Modes
3527
+
3528
+ \`\`\`glsl
3529
+ vec3 result = blendOverlay(base, overlay);
3530
+ result = blendScreen(result, glow);
3531
+ \`\`\`
3532
+ `
3533
+ };
3534
+ var blend_default = glslBlend;
3535
+
3536
+ // src/components/glsl/lighting.ts
3537
+ var glslLighting = {
3538
+ name: "glsl-lighting",
3539
+ version: "1.0.0",
3540
+ category: "pattern",
3541
+ target: "glsl",
3542
+ renderers: [],
3543
+ code: `float lambertian(vec3 normal, vec3 lightDir) {
3544
+ return max(dot(normalize(normal), normalize(lightDir)), 0.0);
3545
+ }
3546
+
3547
+ float phong(vec3 normal, vec3 lightDir, vec3 viewDir, float shininess) {
3548
+ vec3 n = normalize(normal);
3549
+ vec3 l = normalize(lightDir);
3550
+ vec3 r = reflect(-l, n);
3551
+ float diff = max(dot(n, l), 0.0);
3552
+ float spec = pow(max(dot(normalize(viewDir), r), 0.0), shininess);
3553
+ return diff + spec;
3554
+ }
3555
+
3556
+ vec3 normalFromHeight(sampler2D tex, vec2 uv, float strength) {
3557
+ float eps = 1.0 / 512.0;
3558
+ float h = texture2D(tex, uv).r;
3559
+ float hx = texture2D(tex, uv + vec2(eps, 0.0)).r;
3560
+ float hy = texture2D(tex, uv + vec2(0.0, eps)).r;
3561
+ return normalize(vec3((h - hx) * strength, (h - hy) * strength, 1.0));
3562
+ }
3563
+
3564
+ float ambientOcclusion(vec2 uv, float radius, float intensity) {
3565
+ float ao = 0.0;
3566
+ for (int i = 0; i < 4; i++) {
3567
+ float angle = float(i) * 1.5708;
3568
+ vec2 offset = vec2(cos(angle), sin(angle)) * radius;
3569
+ ao += smoothstep(0.0, 1.0, length(offset));
3570
+ }
3571
+ return 1.0 - (ao / 4.0) * intensity;
3572
+ }
3573
+ `,
3574
+ exports: ["phong", "lambertian", "normalFromHeight", "ambientOcclusion"],
3575
+ dependencies: [],
3576
+ description: "Basic GLSL lighting models (Phong, Lambertian, normal mapping).",
3577
+ usage: `### glsl-lighting \u2014 Lighting
3578
+
3579
+ \`\`\`glsl
3580
+ float diff = lambertian(normal, lightPos - fragPos);
3581
+ float lit = phong(normal, lightDir, viewDir, 32.0);
3582
+ vec3 n = normalFromHeight(heightMap, uv, 2.0);
3583
+ \`\`\`
3584
+ `
3585
+ };
3586
+ var lighting_default = glslLighting;
3587
+
3588
+ // src/components/glsl/ray.ts
3589
+ var glslRay = {
3590
+ name: "glsl-ray",
3591
+ version: "1.0.0",
3592
+ category: "sdf",
3593
+ target: "glsl",
3594
+ renderers: [],
3595
+ code: `float rayMarch(vec3 ro, vec3 rd, float maxDist, int maxSteps) {
3596
+ float t = 0.0;
3597
+ for (int i = 0; i < 256; i++) {
3598
+ if (i >= maxSteps) break;
3599
+ vec3 p = ro + rd * t;
3600
+ float d = sdSphere(p, 1.0);
3601
+ if (d < 0.001 || t > maxDist) break;
3602
+ t += d;
3603
+ }
3604
+ return t;
3605
+ }
3606
+
3607
+ vec3 estimateNormal(vec3 p) {
3608
+ float eps = 0.001;
3609
+ return normalize(vec3(
3610
+ sdSphere(p + vec3(eps,0,0), 1.0) - sdSphere(p - vec3(eps,0,0), 1.0),
3611
+ sdSphere(p + vec3(0,eps,0), 1.0) - sdSphere(p - vec3(0,eps,0), 1.0),
3612
+ sdSphere(p + vec3(0,0,eps), 1.0) - sdSphere(p - vec3(0,0,eps), 1.0)
3613
+ ));
3614
+ }
3615
+
3616
+ float softShadow(vec3 ro, vec3 rd, float mint, float maxt, float k) {
3617
+ float res = 1.0;
3618
+ float t = mint;
3619
+ for (int i = 0; i < 64; i++) {
3620
+ float h = sdSphere(ro + rd * t, 1.0);
3621
+ res = min(res, k * h / t);
3622
+ t += clamp(h, 0.02, 0.1);
3623
+ if (h < 0.001 || t > maxt) break;
3624
+ }
3625
+ return clamp(res, 0.0, 1.0);
3626
+ }
3627
+
3628
+ float ambientOcclusion3D(vec3 p, vec3 n) {
3629
+ float occ = 0.0;
3630
+ float sca = 1.0;
3631
+ for (int i = 0; i < 5; i++) {
3632
+ float h = 0.01 + 0.12 * float(i);
3633
+ float d = sdSphere(p + n * h, 1.0);
3634
+ occ += (h - d) * sca;
3635
+ sca *= 0.95;
3636
+ }
3637
+ return clamp(1.0 - 3.0 * occ, 0.0, 1.0);
3638
+ }
3639
+ `,
3640
+ exports: ["rayMarch", "estimateNormal", "softShadow", "ambientOcclusion3D"],
3641
+ dependencies: ["glsl-sdf-3d"],
3642
+ description: "Raymarching utilities (march, normals, soft shadows, AO).",
3643
+ usage: `### glsl-ray \u2014 Raymarching
3644
+
3645
+ \`\`\`glsl
3646
+ float t = rayMarch(ro, rd, 100.0, 128);
3647
+ if (t < 100.0) {
3648
+ vec3 p = ro + rd * t;
3649
+ vec3 n = estimateNormal(p);
3650
+ float shadow = softShadow(p, lightDir, 0.02, 10.0, 8.0);
3651
+ }
3652
+ \`\`\`
3653
+ `
3654
+ };
3655
+ var ray_default = glslRay;
3656
+
3657
+ // src/components/glsl/post.ts
3658
+ var glslPost = {
3659
+ name: "glsl-post",
3660
+ version: "1.0.0",
3661
+ category: "imaging",
3662
+ target: "glsl",
3663
+ renderers: [],
3664
+ code: `float vignette(vec2 uv, float intensity) {
3665
+ vec2 d = uv - 0.5;
3666
+ return 1.0 - dot(d, d) * intensity;
3667
+ }
3668
+
3669
+ vec3 chromaticAberration(sampler2D tex, vec2 uv, float offset) {
3670
+ float r = texture2D(tex, uv + vec2(offset, 0.0)).r;
3671
+ float g = texture2D(tex, uv).g;
3672
+ float b = texture2D(tex, uv - vec2(offset, 0.0)).b;
3673
+ return vec3(r, g, b);
3674
+ }
3675
+
3676
+ float filmGrain(vec2 uv, float time, float intensity) {
3677
+ return (hash(uv * 1000.0 + time) - 0.5) * intensity;
3678
+ }
3679
+
3680
+ vec3 bloom(sampler2D tex, vec2 uv, float threshold, float intensity) {
3681
+ vec3 col = texture2D(tex, uv).rgb;
3682
+ vec3 bright = max(col - vec3(threshold), vec3(0.0));
3683
+ vec3 blur = vec3(0.0);
3684
+ for (int i = -2; i <= 2; i++)
3685
+ for (int j = -2; j <= 2; j++)
3686
+ blur += max(texture2D(tex, uv + vec2(float(i), float(j)) * 0.003).rgb - vec3(threshold), vec3(0.0));
3687
+ blur /= 25.0;
3688
+ return col + blur * intensity;
3689
+ }
3690
+
3691
+ vec3 sharpen(sampler2D tex, vec2 uv, float strength) {
3692
+ vec2 px = vec2(1.0) / vec2(textureSize(tex, 0));
3693
+ vec3 col = texture2D(tex, uv).rgb * (1.0 + 4.0 * strength);
3694
+ col -= texture2D(tex, uv + vec2(px.x, 0.0)).rgb * strength;
3695
+ col -= texture2D(tex, uv - vec2(px.x, 0.0)).rgb * strength;
3696
+ col -= texture2D(tex, uv + vec2(0.0, px.y)).rgb * strength;
3697
+ col -= texture2D(tex, uv - vec2(0.0, px.y)).rgb * strength;
3698
+ return col;
3699
+ }
3700
+ `,
3701
+ exports: ["vignette", "chromaticAberration", "filmGrain", "bloom", "sharpen"],
3702
+ dependencies: ["glsl-noise"],
3703
+ description: "Post-processing effects (vignette, chromatic aberration, grain, bloom).",
3704
+ usage: `### glsl-post \u2014 Post Processing
3705
+
3706
+ \`\`\`glsl
3707
+ color *= vignette(uv, 2.0);
3708
+ color += filmGrain(uv, u_time, 0.05);
3709
+ color = bloom(tex, uv, 0.8, 1.5);
3710
+ \`\`\`
3711
+ `
3712
+ };
3713
+ var post_default = glslPost;
3714
+
3715
+ // src/components/glsl/shape.ts
3716
+ var glslShape = {
3717
+ name: "glsl-shape",
3718
+ version: "1.0.0",
3719
+ category: "geometry",
3720
+ target: "glsl",
3721
+ renderers: [],
3722
+ code: `float polygon(vec2 p, int sides, float radius) {
3723
+ float a = atan(p.y, p.x);
3724
+ float seg = 6.28318 / float(sides);
3725
+ float d = cos(floor(0.5 + a / seg) * seg - a) * length(p);
3726
+ return d - radius;
3727
+ }
3728
+
3729
+ float star(vec2 p, int points, float outer, float inner) {
3730
+ float a = atan(p.y, p.x);
3731
+ float seg = 3.14159 / float(points);
3732
+ a = mod(a, 2.0 * seg) - seg;
3733
+ float r = length(p);
3734
+ float d1 = r * cos(a) - outer;
3735
+ float d2 = r * cos(a - seg) - inner;
3736
+ return max(d1, d2);
3737
+ }
3738
+
3739
+ float roundedRect(vec2 p, vec2 size, float radius) {
3740
+ vec2 d = abs(p) - size + radius;
3741
+ return length(max(d, 0.0)) + min(max(d.x, d.y), 0.0) - radius;
3742
+ }
3743
+
3744
+ float ring(vec2 p, float radius, float thickness) {
3745
+ return abs(length(p) - radius) - thickness;
3746
+ }
3747
+
3748
+ float arc(vec2 p, float radius, float angle, float thickness) {
3749
+ float a = atan(p.y, p.x);
3750
+ float ha = angle * 0.5;
3751
+ float d = abs(length(p) - radius) - thickness;
3752
+ float angDist = abs(mod(a + 3.14159, 6.28318) - 3.14159);
3753
+ return max(d, angDist - ha);
3754
+ }
3755
+
3756
+ float line(vec2 p, vec2 a, vec2 b, float thickness) {
3757
+ vec2 pa = p - a, ba = b - a;
3758
+ float h = clamp(dot(pa, ba) / dot(ba, ba), 0.0, 1.0);
3759
+ return length(pa - ba * h) - thickness;
3760
+ }
3761
+ `,
3762
+ exports: ["polygon", "star", "roundedRect", "ring", "arc", "line"],
3763
+ dependencies: ["glsl-sdf"],
3764
+ description: "2D shape rendering via SDF (polygon, star, rounded rect, ring).",
3765
+ usage: `### glsl-shape \u2014 2D Shapes
3766
+
3767
+ \`\`\`glsl
3768
+ float d = polygon(uv - 0.5, 6, 0.3);
3769
+ d = min(d, star(uv - vec2(0.7, 0.5), 5, 0.2, 0.1));
3770
+ d = min(d, roundedRect(uv - vec2(0.3, 0.7), vec2(0.1), 0.02));
3771
+ vec3 col = mix(vec3(1), vec3(0), smoothstep(0.0, 0.01, d));
3772
+ \`\`\`
3773
+ `
3774
+ };
3775
+ var shape_default2 = glslShape;
3776
+
3777
+ // src/components/glsl/domain.ts
3778
+ var glslDomain = {
3779
+ name: "glsl-domain",
3780
+ version: "1.0.0",
3781
+ category: "transform",
3782
+ target: "glsl",
3783
+ renderers: [],
3784
+ code: `vec2 domainWarp(vec2 p, float strength) {
3785
+ float n1 = noise(p);
3786
+ float n2 = noise(p + vec2(5.2, 1.3));
3787
+ return p + vec2(n1, n2) * strength;
3788
+ }
3789
+
3790
+ vec2 domainRepeat(vec2 p, vec2 period) {
3791
+ return mod(p + period * 0.5, period) - period * 0.5;
3792
+ }
3793
+
3794
+ vec2 domainTwist(vec2 p, float amount) {
3795
+ float angle = p.y * amount;
3796
+ float c = cos(angle), s = sin(angle);
3797
+ return vec2(p.x * c - p.y * s, p.x * s + p.y * c);
3798
+ }
3799
+
3800
+ vec2 domainFold(vec2 p, vec2 axis) {
3801
+ float d = dot(p, normalize(axis));
3802
+ if (d < 0.0) p -= 2.0 * d * normalize(axis);
3803
+ return p;
3804
+ }
3805
+ `,
3806
+ exports: ["domainWarp", "domainRepeat", "domainTwist", "domainFold"],
3807
+ dependencies: ["glsl-noise"],
3808
+ description: "Domain manipulation (warp, repeat, twist, fold).",
3809
+ usage: `### glsl-domain \u2014 Domain Manipulation
3810
+
3811
+ \`\`\`glsl
3812
+ vec2 p = domainWarp(uv * 5.0, 0.3);
3813
+ p = domainRepeat(p, vec2(2.0));
3814
+ p = domainTwist(p, 1.5);
3815
+ \`\`\`
3816
+ `
3817
+ };
3818
+ var domain_default = glslDomain;
3819
+
3820
+ // src/components/glsl/gradient.ts
3821
+ var glslGradient = {
3822
+ name: "glsl-gradient",
3823
+ version: "1.0.0",
3824
+ category: "color",
3825
+ target: "glsl",
3826
+ renderers: [],
3827
+ code: `vec3 linearGradient(vec2 uv, vec3 c1, vec3 c2, float angle) {
3828
+ float c = cos(angle), s = sin(angle);
3829
+ float t = clamp(uv.x * c + uv.y * s, 0.0, 1.0);
3830
+ return mix(c1, c2, t);
3831
+ }
3832
+
3833
+ vec3 radialGradient(vec2 uv, vec3 c1, vec3 c2, vec2 center, float radius) {
3834
+ float t = clamp(length(uv - center) / radius, 0.0, 1.0);
3835
+ return mix(c1, c2, t);
3836
+ }
3837
+
3838
+ vec3 angularGradient(vec2 uv, vec3 c1, vec3 c2, vec2 center) {
3839
+ float angle = atan(uv.y - center.y, uv.x - center.x);
3840
+ float t = (angle + 3.14159) / 6.28318;
3841
+ return mix(c1, c2, t);
3842
+ }
3843
+
3844
+ vec3 conicGradient(vec2 uv, vec3 colors[4], vec2 center) {
3845
+ float angle = atan(uv.y - center.y, uv.x - center.x);
3846
+ float t = (angle + 3.14159) / 6.28318;
3847
+ float segment = t * 4.0;
3848
+ int i = int(floor(segment));
3849
+ float f = fract(segment);
3850
+ if (i >= 3) return mix(colors[3], colors[0], f);
3851
+ return mix(colors[i], colors[i + 1], f);
3852
+ }
3853
+
3854
+ vec3 paletteGradient(float t, vec3 a, vec3 b, vec3 c, vec3 d) {
3855
+ return a + b * cos(6.28318 * (c * t + d));
3856
+ }
3857
+ `,
3858
+ exports: ["linearGradient", "radialGradient", "angularGradient", "conicGradient", "paletteGradient"],
3859
+ dependencies: [],
3860
+ description: "Gradient generation (linear, radial, angular, palette).",
3861
+ usage: `### glsl-gradient \u2014 Gradients
3862
+
3863
+ \`\`\`glsl
3864
+ vec3 g = linearGradient(uv, vec3(1,0,0), vec3(0,0,1), 0.0);
3865
+ vec3 r = radialGradient(uv, vec3(1), vec3(0), vec2(0.5), 0.5);
3866
+ // Iq-style cosine palette
3867
+ vec3 p = paletteGradient(t, vec3(0.5), vec3(0.5), vec3(1), vec3(0,0.33,0.67));
3868
+ \`\`\`
3869
+ `
3870
+ };
3871
+ var gradient_default = glslGradient;
3872
+
3873
+ // src/registry.ts
3874
+ var COMPONENT_REGISTRY = Object.fromEntries(
3875
+ [...Object.values(js_exports), ...Object.values(glsl_exports)].map((c) => [c.name, c])
3876
+ );
3877
+
3878
+ // src/resolver.ts
3879
+ var RENDERER_TARGET = {
3880
+ p5: "js",
3881
+ three: "js",
3882
+ canvas2d: "js",
3883
+ svg: "js",
3884
+ glsl: "glsl"
3885
+ };
3886
+ function resolveComponents(components, renderer) {
3887
+ const target = RENDERER_TARGET[renderer];
3888
+ const allNames = /* @__PURE__ */ new Set();
3889
+ const stack = Object.keys(components);
3890
+ while (stack.length > 0) {
3891
+ const name = stack.pop();
3892
+ if (allNames.has(name)) continue;
3893
+ const entry = COMPONENT_REGISTRY[name];
3894
+ if (!entry) {
3895
+ throw new Error(`Unknown component: "${name}"`);
3896
+ }
3897
+ if (entry.target !== target) {
3898
+ throw new Error(
3899
+ `Component "${name}" has target "${entry.target}" but renderer "${renderer}" requires target "${target}"`
3900
+ );
3901
+ }
3902
+ if (entry.renderers.length > 0 && !entry.renderers.includes(renderer)) {
3903
+ throw new Error(
3904
+ `Component "${name}" is not compatible with renderer "${renderer}". Compatible: ${entry.renderers.join(", ")}`
3905
+ );
3906
+ }
3907
+ allNames.add(name);
3908
+ for (const dep of entry.dependencies) {
3909
+ if (!allNames.has(dep)) {
3910
+ stack.push(dep);
3911
+ }
3912
+ }
3913
+ }
3914
+ const sorted = [];
3915
+ const visited = /* @__PURE__ */ new Set();
3916
+ const visiting = /* @__PURE__ */ new Set();
3917
+ function visit(name) {
3918
+ if (visited.has(name)) return;
3919
+ if (visiting.has(name)) {
3920
+ throw new Error(`Circular dependency detected involving component "${name}"`);
3921
+ }
3922
+ visiting.add(name);
3923
+ const entry = COMPONENT_REGISTRY[name];
3924
+ for (const dep of entry.dependencies) {
3925
+ if (allNames.has(dep)) {
3926
+ visit(dep);
3927
+ }
3928
+ }
3929
+ visiting.delete(name);
3930
+ visited.add(name);
3931
+ sorted.push(name);
3932
+ }
3933
+ for (const name of allNames) {
3934
+ visit(name);
3935
+ }
3936
+ const exportNames = /* @__PURE__ */ new Map();
3937
+ for (const name of sorted) {
3938
+ const entry = COMPONENT_REGISTRY[name];
3939
+ for (const exp of entry.exports) {
3940
+ const existing = exportNames.get(exp);
3941
+ if (existing) {
3942
+ throw new Error(
3943
+ `Export collision: "${exp}" is exported by both "${existing}" and "${name}"`
3944
+ );
3945
+ }
3946
+ exportNames.set(exp, name);
3947
+ }
3948
+ }
3949
+ return sorted.map((name) => {
3950
+ const entry = COMPONENT_REGISTRY[name];
3951
+ return {
3952
+ name: entry.name,
3953
+ version: entry.version,
3954
+ code: entry.code,
3955
+ exports: entry.exports
3956
+ };
3957
+ });
3958
+ }
3959
+ export {
3960
+ COMPONENT_REGISTRY,
3961
+ resolveComponents
3962
+ };
3963
+ //# sourceMappingURL=index.js.map