@rosalana/sandbox 0.1.0 → 0.2.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.es.js CHANGED
@@ -1,9 +1,9 @@
1
- var D = Object.defineProperty;
2
- var N = (u, e, n) => e in u ? D(u, e, { enumerable: !0, configurable: !0, writable: !0, value: n }) : u[e] = n;
3
- var a = (u, e, n) => N(u, typeof e != "symbol" ? e + "" : e, n);
4
- class x {
5
- constructor(e, n, t, i) {
6
- this.target = e, this.type = n, this.listener = t, this.options = i, this.target.addEventListener(
1
+ var N = Object.defineProperty;
2
+ var G = (u, e, t) => e in u ? N(u, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : u[e] = t;
3
+ var o = (u, e, t) => G(u, typeof e != "symbol" ? e + "" : e, t);
4
+ class b {
5
+ constructor(e, t, n, i) {
6
+ this.target = e, this.type = t, this.listener = n, this.options = i, this.target.addEventListener(
7
7
  this.type,
8
8
  this.listener,
9
9
  this.options
@@ -16,23 +16,23 @@ class x {
16
16
  this.options
17
17
  );
18
18
  }
19
- static on(e, n, t, i) {
20
- return e.addEventListener(n, t, i), () => e.removeEventListener(n, t, i);
19
+ static on(e, t, n, i) {
20
+ return e.addEventListener(t, n, i), () => e.removeEventListener(t, n, i);
21
21
  }
22
22
  }
23
23
  class h extends Error {
24
- constructor(n, t) {
25
- super(n);
26
- a(this, "name", "SandboxError");
27
- this.code = t;
24
+ constructor(t, n) {
25
+ super(t);
26
+ o(this, "name", "SandboxError");
27
+ this.code = n;
28
28
  }
29
29
  }
30
- class z extends h {
30
+ class W extends h {
31
31
  constructor() {
32
32
  super("WebGL is not supported in this browser.", "CONTEXT_ERROR");
33
33
  }
34
34
  }
35
- class de extends h {
35
+ class ve extends h {
36
36
  constructor() {
37
37
  super(
38
38
  "Failed to create WebGL context. The GPU may be unavailable.",
@@ -40,72 +40,72 @@ class de extends h {
40
40
  );
41
41
  }
42
42
  }
43
- class G extends h {
44
- constructor(e, n) {
43
+ class z extends h {
44
+ constructor(e, t) {
45
45
  super(
46
- `Vertex and fragment shader WebGL versions do not match (${e} vs ${n})`,
46
+ `Vertex and fragment shader WebGL versions do not match (${e} vs ${t})`,
47
47
  "VALIDATION_ERROR"
48
- ), this.vertexVersion = e, this.fragmentVersion = n;
48
+ ), this.vertexVersion = e, this.fragmentVersion = t;
49
49
  }
50
50
  }
51
51
  class _ extends h {
52
- constructor(n, t, i) {
52
+ constructor(t, n, i) {
53
53
  const r = _.parseErrorLines(i), s = r.length > 0 ? ` at line(s): ${r.join(", ")}` : "";
54
54
  super(
55
- `${n} shader compilation failed${s}
55
+ `${t} shader compilation failed${s}
56
56
 
57
57
  ${i}`,
58
58
  "SHADER_ERROR"
59
59
  );
60
- a(this, "lines");
61
- this.shaderType = n, this.source = t, this.infoLog = i, this.lines = r;
60
+ o(this, "lines");
61
+ this.shaderType = t, this.source = n, this.infoLog = i, this.lines = r;
62
62
  }
63
- static parseErrorLines(n) {
64
- const t = [
63
+ static parseErrorLines(t) {
64
+ const n = [
65
65
  /ERROR:\s*\d*:(\d+)/g,
66
66
  /(\d+):(\d+)\(\d+\):/g,
67
67
  /^(\d+):/gm
68
68
  ], i = /* @__PURE__ */ new Set();
69
- for (const r of t) {
69
+ for (const r of n) {
70
70
  let s;
71
- for (; (s = r.exec(n)) !== null; ) {
72
- const o = parseInt(s[1], 10);
73
- o > 0 && i.add(o);
71
+ for (; (s = r.exec(t)) !== null; ) {
72
+ const a = parseInt(s[1], 10);
73
+ a > 0 && i.add(a);
74
74
  }
75
75
  }
76
76
  return [...i].sort((r, s) => r - s);
77
77
  }
78
78
  }
79
- class C extends h {
80
- constructor(e, n, t, i) {
79
+ class U extends h {
80
+ constructor(e, t, n, i) {
81
81
  super(
82
- `The shader ${e} "${n}" has type "${i}" but expected "${t}"`,
82
+ `The shader ${e} "${t}" has type "${i}" but expected "${n}"`,
83
83
  "SHADER_ERROR"
84
- ), this.requirement = e, this.name = n, this.expectedType = t, this.actualType = i;
84
+ ), this.requirement = e, this.name = t, this.expectedType = n, this.actualType = i;
85
85
  }
86
86
  }
87
- class W extends h {
87
+ class H extends h {
88
88
  constructor() {
89
89
  super("Shader source does not contain any function.", "SHADER_ERROR");
90
90
  }
91
91
  }
92
92
  class q extends h {
93
- constructor(e, n) {
93
+ constructor(e, t) {
94
94
  super(
95
- `Syntax error in shader import statement at line ${e}: ${n}`,
95
+ `Syntax error in shader import statement at line ${e}: ${t}`,
96
96
  "SHADER_ERROR"
97
- ), this.line = e, this.details = n;
97
+ ), this.line = e, this.details = t;
98
98
  }
99
99
  }
100
- class H extends h {
101
- constructor(e, n) {
100
+ class j extends h {
101
+ constructor(e, t) {
102
102
  super(
103
- `Duplicate import name "${e}" found at line ${n}. Each import must have a unique name.`,
103
+ `Duplicate import name "${e}" found at line ${t}. Each import must have a unique name.`,
104
104
  "SHADER_ERROR"
105
- ), this.name = e, this.line = n;
105
+ ), this.name = e, this.line = t;
106
106
  }
107
107
  }
108
- class j extends h {
108
+ class X extends h {
109
109
  constructor(e) {
110
110
  super(
111
111
  `Can not find module '${e}'. Check if it is defined before usage or if the name is correct.`,
@@ -114,11 +114,11 @@ class j extends h {
114
114
  }
115
115
  }
116
116
  class Y extends h {
117
- constructor(e, n) {
117
+ constructor(e, t) {
118
118
  super(
119
- `Method '${n}' not found in shader module '${e}'. Check if the method is defined in the module source code or if the name is correct.`,
119
+ `Method '${t}' not found in shader module '${e}'. Check if the method is defined in the module source code or if the name is correct.`,
120
120
  "MODULE_ERROR"
121
- ), this.moduleName = e, this.methodName = n;
121
+ ), this.moduleName = e, this.methodName = t;
122
122
  }
123
123
  }
124
124
  class K extends h {
@@ -129,7 +129,7 @@ class K extends h {
129
129
  ), this.moduleName = e;
130
130
  }
131
131
  }
132
- class X extends h {
132
+ class Q extends h {
133
133
  constructor(e) {
134
134
  super(
135
135
  `Name 'default' is reserved and cannot be used as a function name in module '${e}'.`,
@@ -137,7 +137,7 @@ class X extends h {
137
137
  ), this.moduleName = e;
138
138
  }
139
139
  }
140
- class Q extends h {
140
+ class J extends h {
141
141
  constructor(e) {
142
142
  super(
143
143
  `Module name '${e}' is not allowed. Module names cannot be 'sandbox' or start with 'sandbox/'.`,
@@ -145,7 +145,7 @@ class Q extends h {
145
145
  ), this.moduleName = e;
146
146
  }
147
147
  }
148
- class J extends h {
148
+ class Z extends h {
149
149
  constructor(e) {
150
150
  super(
151
151
  `Module '${e}' is already defined. Overwriting existing modules is not allowed.`,
@@ -153,64 +153,84 @@ class J extends h {
153
153
  ), this.moduleName = e;
154
154
  }
155
155
  }
156
- class Z extends h {
157
- constructor(e, n, t) {
156
+ class ee extends h {
157
+ constructor(e, t, n) {
158
158
  super(
159
- `Uniform '${t}' mentioned for function '${n}' of module '${e}' was not found among the module's declared uniforms. Check if the uniform is declared in the module source code or if the name is correct.`,
159
+ `Uniform '${n}' mentioned for function '${t}' of module '${e}' was not found among the module's declared uniforms. Check if the uniform is declared in the module source code or if the name is correct.`,
160
160
  "MODULE_ERROR"
161
- ), this.moduleName = e, this.functionName = n, this.uniformName = t;
161
+ ), this.moduleName = e, this.functionName = t, this.uniformName = n;
162
162
  }
163
163
  }
164
- class ee extends h {
165
- constructor(e, n) {
164
+ class te extends h {
165
+ constructor(e, t) {
166
166
  super(
167
- `Uniform '${n}' mentioned for function '${e}' was not imported from any module. Check if the function is imported from the correct module and if the uniform is declared in that module's source code with the correct name.`,
167
+ `Uniform '${t}' mentioned for function '${e}' was not imported from any module. Check if the function is imported from the correct module and if the uniform is declared in that module's source code with the correct name.`,
168
168
  "MODULE_ERROR"
169
- ), this.functionName = e, this.uniformName = n;
169
+ ), this.functionName = e, this.uniformName = t;
170
170
  }
171
171
  }
172
172
  class ne extends h {
173
- constructor(e, n) {
173
+ constructor(e, t) {
174
174
  super(
175
- `Mention '${e}' called in function '${n}' could not be replaced with the corresponding uniform reference. There might be an issue with the compilation process because the referenced uniform was not found among the shader requirements. Try use a different name for uniforms you want to mention in functions or check if the uniform is properly declared and mentioned in the module source code.`,
175
+ `Mention '${e}' called in function '${t}' could not be replaced with the corresponding uniform reference. There might be an issue with the compilation process because the referenced uniform was not found among the shader requirements. Try use a different name for uniforms you want to mention in functions or check if the uniform is properly declared and mentioned in the module source code.`,
176
176
  "MODULE_ERROR"
177
- ), this.mentionName = e, this.calledInFunction = n;
177
+ ), this.mentionName = e, this.calledInFunction = t;
178
178
  }
179
179
  }
180
- class R extends h {
180
+ class S extends h {
181
181
  constructor(e) {
182
182
  super(`Shader program linking failed
183
183
 
184
184
  ${e}`, "PROGRAM_ERROR"), this.infoLog = e;
185
185
  }
186
186
  }
187
- class te extends h {
187
+ class ge extends h {
188
+ constructor(t) {
189
+ super(
190
+ `Failed to create WebGL texture for "${t}".`,
191
+ "TEXTURE_ERROR"
192
+ );
193
+ o(this, "name", "SandboxTextureCreationError");
194
+ this.textureName = t;
195
+ }
196
+ }
197
+ class xe extends h {
198
+ constructor(t, n) {
199
+ super(
200
+ `Cannot bind texture "${t}": all ${n} texture units are in use.`,
201
+ "TEXTURE_ERROR"
202
+ );
203
+ o(this, "name", "SandboxTextureUnitLimitError");
204
+ this.textureName = t, this.maxUnits = n;
205
+ }
206
+ }
207
+ class ie extends h {
188
208
  constructor(e) {
189
209
  super(`Error in onLoad callback: ${e}`, "UNKNOWN_ERROR");
190
210
  }
191
211
  }
192
- class ie extends h {
193
- constructor(e, n) {
194
- super(`Error in onBefore/onAfter hook callback with ID ${e}: ${n}`, "UNKNOWN_ERROR");
212
+ class re extends h {
213
+ constructor(e, t) {
214
+ super(`Error in onBefore/onAfter hook callback with ID ${e}: ${t}`, "UNKNOWN_ERROR");
195
215
  }
196
216
  }
197
- class re {
217
+ class se {
198
218
  constructor() {
199
219
  /** Total elapsed time in seconds */
200
- a(this, "time", 0);
220
+ o(this, "time", 0);
201
221
  /** Delta time since last frame in seconds */
202
- a(this, "delta", 0);
222
+ o(this, "delta", 0);
203
223
  /** Frame counter */
204
- a(this, "frame", 0);
224
+ o(this, "frame", 0);
205
225
  /** Is clock running */
206
- a(this, "running", !1);
226
+ o(this, "running", !1);
207
227
  /** Smoothed frames per second */
208
- a(this, "fps", 0);
209
- a(this, "startTime", 0);
210
- a(this, "lastTime", 0);
211
- a(this, "rafId", null);
212
- a(this, "callback", null);
213
- a(this, "maxFps", 0);
228
+ o(this, "fps", 0);
229
+ o(this, "startTime", 0);
230
+ o(this, "lastTime", 0);
231
+ o(this, "rafId", null);
232
+ o(this, "callback", null);
233
+ o(this, "maxFps", 0);
214
234
  this.loop = this.loop.bind(this);
215
235
  }
216
236
  /**
@@ -219,8 +239,8 @@ class re {
219
239
  start(e) {
220
240
  if (this.running) return this;
221
241
  this.callback = e, this.running = !0;
222
- const n = performance.now();
223
- return this.frame === 0 ? this.startTime = n : this.startTime = n - this.time * 1e3, this.lastTime = n, this.rafId = requestAnimationFrame(this.loop), this;
242
+ const t = performance.now();
243
+ return this.frame === 0 ? this.startTime = t : this.startTime = t - this.time * 1e3, this.lastTime = t, this.rafId = requestAnimationFrame(this.loop), this;
224
244
  }
225
245
  /**
226
246
  * Stop the animation loop.
@@ -278,29 +298,29 @@ class re {
278
298
  loop(e) {
279
299
  if (!this.running) return;
280
300
  if (this.maxFps > 0) {
281
- const t = 1e3 / this.maxFps;
282
- if (e - this.lastTime < t) {
301
+ const n = 1e3 / this.maxFps;
302
+ if (e - this.lastTime < n) {
283
303
  this.rafId = requestAnimationFrame(this.loop);
284
304
  return;
285
305
  }
286
306
  }
287
307
  this.delta = (e - this.lastTime) / 1e3, this.lastTime = e;
288
- const n = this.delta > 0 ? 1 / this.delta : 0;
289
- this.fps = this.fps * 0.95 + n * 0.05, this.time = (e - this.startTime) / 1e3, this.frame++, this.callback && this.callback(this.getState()), this.rafId = requestAnimationFrame(this.loop);
308
+ const t = this.delta > 0 ? 1 / this.delta : 0;
309
+ this.fps = this.fps * 0.95 + t * 0.05, this.time = (e - this.startTime) / 1e3, this.frame++, this.callback && this.callback(this.getState()), this.rafId = requestAnimationFrame(this.loop);
290
310
  }
291
311
  }
292
- class A {
312
+ class k {
293
313
  constructor(e) {
294
- a(this, "gl");
295
- a(this, "vao", null);
296
- a(this, "vbo", null);
297
- a(this, "ibo", null);
298
- a(this, "vertexCount", 0);
299
- a(this, "indexCount", 0);
300
- a(this, "useIndices", !1);
314
+ o(this, "gl");
315
+ o(this, "vao", null);
316
+ o(this, "vbo", null);
317
+ o(this, "ibo", null);
318
+ o(this, "vertexCount", 0);
319
+ o(this, "indexCount", 0);
320
+ o(this, "useIndices", !1);
301
321
  // WebGL1 VAO extension (if available)
302
- a(this, "vaoExt", null);
303
- a(this, "isWebGL2");
322
+ o(this, "vaoExt", null);
323
+ o(this, "isWebGL2");
304
324
  this.gl = e, this.isWebGL2 = e instanceof WebGL2RenderingContext, this.isWebGL2 || (this.vaoExt = e.getExtension("OES_vertex_array_object"));
305
325
  }
306
326
  /**
@@ -308,7 +328,7 @@ class A {
308
328
  * This is the most common use case for shader effects.
309
329
  */
310
330
  static fullscreenQuad(e) {
311
- const n = new A(e), t = new Float32Array([
331
+ const t = new k(e), n = new Float32Array([
312
332
  // position texcoord
313
333
  -1,
314
334
  -1,
@@ -340,33 +360,33 @@ class A {
340
360
  3
341
361
  // second triangle
342
362
  ]);
343
- return n.setup(t, i), n;
363
+ return t.setup(n, i), t;
344
364
  }
345
365
  /**
346
366
  * Setup geometry from vertex and index data.
347
367
  */
348
- setup(e, n) {
349
- const t = this.gl;
350
- return this.createVAO(), this.bindVAO(), this.vbo = t.createBuffer(), t.bindBuffer(t.ARRAY_BUFFER, this.vbo), t.bufferData(t.ARRAY_BUFFER, e, t.STATIC_DRAW), this.vertexCount = e.length / 4, n && (this.ibo = t.createBuffer(), t.bindBuffer(t.ELEMENT_ARRAY_BUFFER, this.ibo), t.bufferData(t.ELEMENT_ARRAY_BUFFER, n, t.STATIC_DRAW), this.indexCount = n.length, this.useIndices = !0), this.unbindVAO(), this;
368
+ setup(e, t) {
369
+ const n = this.gl;
370
+ return this.createVAO(), this.bindVAO(), this.vbo = n.createBuffer(), n.bindBuffer(n.ARRAY_BUFFER, this.vbo), n.bufferData(n.ARRAY_BUFFER, e, n.STATIC_DRAW), this.vertexCount = e.length / 4, t && (this.ibo = n.createBuffer(), n.bindBuffer(n.ELEMENT_ARRAY_BUFFER, this.ibo), n.bufferData(n.ELEMENT_ARRAY_BUFFER, t, n.STATIC_DRAW), this.indexCount = t.length, this.useIndices = !0), this.unbindVAO(), this;
351
371
  }
352
372
  /**
353
373
  * Link vertex attributes to shader program.
354
374
  * Call this after compiling shaders.
355
375
  */
356
376
  linkAttributes(e) {
357
- const n = this.gl;
358
- this.bindVAO(), n.bindBuffer(n.ARRAY_BUFFER, this.vbo);
359
- const t = 4 * Float32Array.BYTES_PER_ELEMENT, i = this.getPositionLocation(e);
360
- i >= 0 && (n.enableVertexAttribArray(i), n.vertexAttribPointer(i, 2, n.FLOAT, !1, t, 0));
377
+ const t = this.gl;
378
+ this.bindVAO(), t.bindBuffer(t.ARRAY_BUFFER, this.vbo);
379
+ const n = 4 * Float32Array.BYTES_PER_ELEMENT, i = this.getPositionLocation(e);
380
+ i >= 0 && (t.enableVertexAttribArray(i), t.vertexAttribPointer(i, 2, t.FLOAT, !1, n, 0));
361
381
  const r = this.getTexcoordLocation(e);
362
- return r >= 0 && (n.enableVertexAttribArray(r), n.vertexAttribPointer(
382
+ return r >= 0 && (t.enableVertexAttribArray(r), t.vertexAttribPointer(
363
383
  r,
364
384
  2,
365
- n.FLOAT,
385
+ t.FLOAT,
366
386
  !1,
367
- t,
387
+ n,
368
388
  2 * Float32Array.BYTES_PER_ELEMENT
369
- )), this.useIndices && n.bindBuffer(n.ELEMENT_ARRAY_BUFFER, this.ibo), this.unbindVAO(), this;
389
+ )), this.useIndices && t.bindBuffer(t.ELEMENT_ARRAY_BUFFER, this.ibo), this.unbindVAO(), this;
370
390
  }
371
391
  /**
372
392
  * Bind geometry for rendering.
@@ -399,16 +419,16 @@ class A {
399
419
  * Tries common naming conventions.
400
420
  */
401
421
  getPositionLocation(e) {
402
- let n = e.getAttribLocation("a_position");
403
- return n >= 0 || (n = e.getAttribLocation("aPosition"), n >= 0) || (n = e.getAttribLocation("position"), n >= 0) ? n : -1;
422
+ let t = e.getAttribLocation("a_position");
423
+ return t >= 0 || (t = e.getAttribLocation("aPosition"), t >= 0) || (t = e.getAttribLocation("position"), t >= 0) ? t : -1;
404
424
  }
405
425
  /**
406
426
  * Get texcoord attribute location.
407
427
  * Tries common naming conventions.
408
428
  */
409
429
  getTexcoordLocation(e) {
410
- let n = e.getAttribLocation("a_texcoord");
411
- return n >= 0 || (n = e.getAttribLocation("aTexCoord"), n >= 0) || (n = e.getAttribLocation("texcoord"), n >= 0) || (n = e.getAttribLocation("a_uv"), n >= 0) ? n : -1;
430
+ let t = e.getAttribLocation("a_texcoord");
431
+ return t >= 0 || (t = e.getAttribLocation("aTexCoord"), t >= 0) || (t = e.getAttribLocation("texcoord"), t >= 0) || (t = e.getAttribLocation("a_uv"), t >= 0) ? t : -1;
412
432
  }
413
433
  // ============================================================================
414
434
  // VAO helpers (handle WebGL1 vs WebGL2 differences)
@@ -426,12 +446,12 @@ class A {
426
446
  this.vao && (this.isWebGL2 ? this.gl.deleteVertexArray(this.vao) : this.vaoExt && this.vaoExt.deleteVertexArrayOES(this.vao), this.vao = null);
427
447
  }
428
448
  }
429
- class se {
449
+ class oe {
430
450
  constructor(e) {
431
- a(this, "gl");
432
- a(this, "program", null);
433
- a(this, "vertexShader", null);
434
- a(this, "fragmentShader", null);
451
+ o(this, "gl");
452
+ o(this, "program", null);
453
+ o(this, "vertexShader", null);
454
+ o(this, "fragmentShader", null);
435
455
  this.gl = e;
436
456
  }
437
457
  /**
@@ -439,8 +459,8 @@ class se {
439
459
  * @throws ShaderCompilationError if compilation fails
440
460
  * @throws ProgramLinkError if linking fails
441
461
  */
442
- compile(e, n) {
443
- return this.destroy(), this.vertexShader = this.compileShader("vertex", e), this.fragmentShader = this.compileShader("fragment", n), this.linkProgram(), this;
462
+ compile(e, t) {
463
+ return this.destroy(), this.vertexShader = this.compileShader("vertex", e), this.fragmentShader = this.compileShader("fragment", t), this.linkProgram(), this;
444
464
  }
445
465
  /**
446
466
  * Bind this program for rendering.
@@ -477,17 +497,17 @@ class se {
477
497
  * Compile a single shader.
478
498
  * @throws ShaderCompilationError if compilation fails
479
499
  */
480
- compileShader(e, n) {
481
- const t = this.gl, i = e === "vertex" ? t.VERTEX_SHADER : t.FRAGMENT_SHADER, r = t.createShader(i);
500
+ compileShader(e, t) {
501
+ const n = this.gl, i = e === "vertex" ? n.VERTEX_SHADER : n.FRAGMENT_SHADER, r = n.createShader(i);
482
502
  if (!r)
483
503
  throw new _(
484
504
  e,
485
- n,
505
+ t,
486
506
  "Failed to create shader object"
487
507
  );
488
- if (t.shaderSource(r, n), t.compileShader(r), !t.getShaderParameter(r, t.COMPILE_STATUS)) {
489
- const o = t.getShaderInfoLog(r) || "Unknown error";
490
- throw t.deleteShader(r), new _(e, n, o);
508
+ if (n.shaderSource(r, t), n.compileShader(r), !n.getShaderParameter(r, n.COMPILE_STATUS)) {
509
+ const a = n.getShaderInfoLog(r) || "Unknown error";
510
+ throw n.deleteShader(r), new _(e, t, a);
491
511
  }
492
512
  return r;
493
513
  }
@@ -498,29 +518,29 @@ class se {
498
518
  linkProgram() {
499
519
  const e = this.gl;
500
520
  if (!this.vertexShader || !this.fragmentShader)
501
- throw new R("Shaders not compiled");
502
- const n = e.createProgram();
503
- if (!n)
504
- throw new R("Failed to create program object");
505
- if (e.attachShader(n, this.vertexShader), e.attachShader(n, this.fragmentShader), e.linkProgram(n), !e.getProgramParameter(n, e.LINK_STATUS)) {
506
- const i = e.getProgramInfoLog(n) || "Unknown error";
507
- throw e.deleteProgram(n), new R(i);
521
+ throw new S("Shaders not compiled");
522
+ const t = e.createProgram();
523
+ if (!t)
524
+ throw new S("Failed to create program object");
525
+ if (e.attachShader(t, this.vertexShader), e.attachShader(t, this.fragmentShader), e.linkProgram(t), !e.getProgramParameter(t, e.LINK_STATUS)) {
526
+ const i = e.getProgramInfoLog(t) || "Unknown error";
527
+ throw e.deleteProgram(t), new S(i);
508
528
  }
509
- this.program = n;
529
+ this.program = t;
510
530
  }
511
531
  }
512
- class k {
513
- constructor(e, n) {
514
- a(this, "name");
515
- a(this, "method");
516
- a(this, "isArray");
517
- a(this, "isMatrix");
518
- a(this, "location", null);
519
- a(this, "locationResolved", !1);
520
- a(this, "value");
521
- this.name = e, this.value = n;
522
- const t = k.inferMethodInfo(n);
523
- this.method = t.method, this.isArray = t.isArray, this.isMatrix = t.isMatrix;
532
+ class M {
533
+ constructor(e, t) {
534
+ o(this, "name");
535
+ o(this, "method");
536
+ o(this, "isArray");
537
+ o(this, "isMatrix");
538
+ o(this, "location", null);
539
+ o(this, "locationResolved", !1);
540
+ o(this, "value");
541
+ this.name = e, this.value = t;
542
+ const n = M.inferMethodInfo(t);
543
+ this.method = n.method, this.isArray = n.isArray, this.isMatrix = n.isMatrix;
524
544
  }
525
545
  /**
526
546
  * Infer WebGL method and metadata from value type.
@@ -532,9 +552,9 @@ class k {
532
552
  return { method: "uniform1f", isArray: !1, isMatrix: !1 };
533
553
  if (!Array.isArray(e))
534
554
  return { method: "uniform1f", isArray: !1, isMatrix: !1 };
535
- const n = e.length, t = e[0];
536
- if (Array.isArray(t))
537
- switch (t.length) {
555
+ const t = e.length, n = e[0];
556
+ if (Array.isArray(n))
557
+ switch (n.length) {
538
558
  case 2:
539
559
  return { method: "uniform2fv", isArray: !0, isMatrix: !1 };
540
560
  case 3:
@@ -544,7 +564,7 @@ class k {
544
564
  default:
545
565
  return { method: "uniform1fv", isArray: !0, isMatrix: !1 };
546
566
  }
547
- switch (n) {
567
+ switch (t) {
548
568
  case 2:
549
569
  return { method: "uniform2fv", isArray: !1, isMatrix: !1 };
550
570
  case 3:
@@ -563,8 +583,8 @@ class k {
563
583
  * Resolve and cache uniform location from program.
564
584
  * Returns null if uniform doesn't exist (optimized out by compiler, etc.)
565
585
  */
566
- resolveLocation(e, n) {
567
- return this.locationResolved || (this.location = e.getUniformLocation(n, this.name), this.locationResolved = !0), this.location;
586
+ resolveLocation(e, t) {
587
+ return this.locationResolved || (this.location = e.getUniformLocation(t, this.name), this.locationResolved = !0), this.location;
568
588
  }
569
589
  /**
570
590
  * Invalidate cached location (call when program changes).
@@ -589,9 +609,9 @@ class k {
589
609
  * @param gl - WebGL context
590
610
  * @param program - Current WebGL program (for location resolution)
591
611
  */
592
- upload(e, n) {
593
- const t = this.resolveLocation(e, n);
594
- if (t === null)
612
+ upload(e, t) {
613
+ const n = this.resolveLocation(e, t);
614
+ if (n === null)
595
615
  return;
596
616
  const i = this.value;
597
617
  let r;
@@ -599,38 +619,38 @@ class k {
599
619
  i.flat()
600
620
  ) : r = new Float32Array(i), this.method) {
601
621
  case "uniform1f":
602
- e.uniform1f(t, r);
622
+ e.uniform1f(n, r);
603
623
  break;
604
624
  case "uniform1i":
605
- e.uniform1i(t, r);
625
+ e.uniform1i(n, r);
606
626
  break;
607
627
  case "uniform1fv":
608
- e.uniform1fv(t, r);
628
+ e.uniform1fv(n, r);
609
629
  break;
610
630
  case "uniform2fv":
611
- e.uniform2fv(t, r);
631
+ e.uniform2fv(n, r);
612
632
  break;
613
633
  case "uniform3fv":
614
- e.uniform3fv(t, r);
634
+ e.uniform3fv(n, r);
615
635
  break;
616
636
  case "uniform4fv":
617
- e.uniform4fv(t, r);
637
+ e.uniform4fv(n, r);
618
638
  break;
619
639
  case "uniformMatrix2fv":
620
- e.uniformMatrix2fv(t, !1, r);
640
+ e.uniformMatrix2fv(n, !1, r);
621
641
  break;
622
642
  case "uniformMatrix3fv":
623
- e.uniformMatrix3fv(t, !1, r);
643
+ e.uniformMatrix3fv(n, !1, r);
624
644
  break;
625
645
  case "uniformMatrix4fv":
626
- e.uniformMatrix4fv(t, !1, r);
646
+ e.uniformMatrix4fv(n, !1, r);
627
647
  break;
628
648
  }
629
649
  }
630
650
  }
631
- class w {
651
+ class E {
632
652
  constructor(e) {
633
- a(this, "parsed", null);
653
+ o(this, "parsed", null);
634
654
  this.source = e;
635
655
  }
636
656
  /**
@@ -638,11 +658,11 @@ class w {
638
658
  */
639
659
  parse() {
640
660
  if (this.parsed) return this.parsed;
641
- const e = this.detectVersion(), n = this.detectImports(), t = this.detectUniforms(), i = this.detectFunctions(t);
661
+ const e = this.detectVersion(), t = this.detectImports(), n = this.detectUniforms(), i = this.detectFunctions(n);
642
662
  return this.parsed = {
643
663
  version: e,
644
- imports: n,
645
- uniforms: t,
664
+ imports: t,
665
+ uniforms: n,
646
666
  functions: i
647
667
  };
648
668
  }
@@ -668,17 +688,17 @@ class w {
668
688
  return /^\s*#version\s+300\s+es/m.test(this.source) ? 2 : 1;
669
689
  }
670
690
  detectImports() {
671
- const e = /^[ \t]*#import\s+(\w+)(?:\s+as\s+(\w+))?\s+from\s+["'](.+)["']/gm, n = /^[ \t]*[^\w\s]?import\b/gm, t = [], i = /* @__PURE__ */ new Set();
672
- let r, s = 1, o = 0;
691
+ const e = /^[ \t]*#import\s+(\w+)(?:\s+as\s+(\w+))?\s+from\s+["'](.+)["']/gm, t = /^[ \t]*[^\w\s]?import\b/gm, n = [], i = /* @__PURE__ */ new Set();
692
+ let r, s = 1, a = 0;
673
693
  for (; (r = e.exec(this.source)) !== null; ) {
674
- s += (this.source.substring(o, r.index).match(/\n/g) || []).length, o = r.index, i.add(s);
694
+ s += (this.source.substring(a, r.index).match(/\n/g) || []).length, a = r.index, i.add(s);
675
695
  const f = r[1], c = r[2] || r[1], m = r[3];
676
- if (t.some((p) => p.alias === c))
677
- throw new H(c, s);
678
- t.push({ name: f, alias: c, module: m, line: s });
696
+ if (n.some((p) => p.alias === c))
697
+ throw new j(c, s);
698
+ n.push({ name: f, alias: c, module: m, line: s });
679
699
  }
680
700
  let l;
681
- for (; (l = n.exec(this.source)) !== null; ) {
701
+ for (; (l = t.exec(this.source)) !== null; ) {
682
702
  const f = (this.source.substring(0, l.index).match(/\n/g) || []).length + 1;
683
703
  if (i.has(f)) continue;
684
704
  const c = this.source.split(`
@@ -688,12 +708,12 @@ class w {
688
708
  this.diagnoseImport(c)
689
709
  );
690
710
  }
691
- return t;
711
+ return n;
692
712
  }
693
713
  diagnoseImport(e) {
694
- const n = e.match(/^([^\w\s])import\b/);
695
- if (n && n[1] !== "#")
696
- return `Invalid prefix '${n[1]}'. Expected: #import <function> from '<module>'`;
714
+ const t = e.match(/^([^\w\s])import\b/);
715
+ if (t && t[1] !== "#")
716
+ return `Invalid prefix '${t[1]}'. Expected: #import <function> from '<module>'`;
697
717
  if (/^import\b/.test(e))
698
718
  return "Missing '#' prefix. Expected: #import <function> from '<module>'";
699
719
  if (/^#import\s+from\b/.test(e))
@@ -703,65 +723,65 @@ class w {
703
723
  if (/^#import\s+\w+\s+as\s*$/.test(e) || /^#import\s+\w+\s+as\s+from\b/.test(e))
704
724
  return `Missing alias name after 'as'. Expected: #import ${e.split(/\s+/)[1]} as <alias> from '<module>'`;
705
725
  if (/^#import\s+\w+\s+as\s+\w+\s*$/.test(e)) {
706
- const t = e.split(/\s+/);
707
- return `Missing 'from' clause. Expected: #import ${t[1]} as ${t[3]} from '<module>'`;
726
+ const n = e.split(/\s+/);
727
+ return `Missing 'from' clause. Expected: #import ${n[1]} as ${n[3]} from '<module>'`;
708
728
  }
709
729
  if (/^#import\s+\w+(?:\s+as\s+\w+)?\s+from\s+\w+/.test(e)) {
710
- const t = e.match(/from\s+(\S+)/);
711
- return `Module name must be quoted. Expected: from '${t == null ? void 0 : t[1]}'`;
730
+ const n = e.match(/from\s+(\S+)/);
731
+ return `Module name must be quoted. Expected: from '${n == null ? void 0 : n[1]}'`;
712
732
  }
713
733
  return "Invalid syntax. Expected: #import <function> from '<module>'";
714
734
  }
715
735
  detectUniforms() {
716
- const e = /^[ \t]*uniform\s+(?:(?:highp|mediump|lowp)\s+)?(\w+)\s+(\w+)(?:\[(\d+)\])?\s*;/gm, n = [];
717
- let t, i = 1, r = 0;
718
- for (; (t = e.exec(this.source)) !== null; ) {
719
- i += (this.source.substring(r, t.index).match(/\n/g) || []).length, r = t.index;
720
- const s = t[1], o = t[2], l = t[3] ? parseInt(t[3], 10) : void 0;
721
- n.push({ name: o, type: s, line: i, arrayNum: l });
736
+ const e = /^[ \t]*uniform\s+(?:(?:highp|mediump|lowp)\s+)?(\w+)\s+(\w+)(?:\[(\d+)\])?\s*;/gm, t = [];
737
+ let n, i = 1, r = 0;
738
+ for (; (n = e.exec(this.source)) !== null; ) {
739
+ i += (this.source.substring(r, n.index).match(/\n/g) || []).length, r = n.index;
740
+ const s = n[1], a = n[2], l = n[3] ? parseInt(n[3], 10) : void 0;
741
+ t.push({ name: a, type: s, line: i, arrayNum: l });
722
742
  }
723
- return n;
743
+ return t;
724
744
  }
725
745
  detectFunctions(e) {
726
- const n = [], t = "void|float|int|uint|bool|vec[234]|ivec[234]|uvec[234]|bvec[234]|mat[234](?:x[234])?|sampler2D|samplerCube|sampler3D|sampler2DArray", i = new RegExp(
727
- `^[ \\t]*(${t})\\s+(\\w+)\\s*\\(([^)]*)\\)\\s*\\{`,
746
+ const t = [], n = "void|float|int|uint|bool|vec[234]|ivec[234]|uvec[234]|bvec[234]|mat[234](?:x[234])?|sampler2D|samplerCube|sampler3D|sampler2DArray", i = new RegExp(
747
+ `^[ \\t]*(${n})\\s+(\\w+)\\s*\\(([^)]*)\\)\\s*\\{`,
728
748
  "gm"
729
749
  );
730
750
  let r;
731
751
  for (; (r = i.exec(this.source)) !== null; ) {
732
- const s = r[1], o = r[2], l = r[3].trim(), f = r.index, c = (this.source.substring(0, f).match(/\n/g) || []).length + 1, m = this.source.indexOf("{", f), p = this.findClosingBrace(this.source, m);
752
+ const s = r[1], a = r[2], l = r[3].trim(), f = r.index, c = (this.source.substring(0, f).match(/\n/g) || []).length + 1, m = this.source.indexOf("{", f), p = this.findClosingBrace(this.source, m);
733
753
  if (p === -1) continue;
734
- const g = this.source.slice(m, p + 1), T = this.parseParams(l), I = this.findFunctionCalls(g), P = this.findUniformCalls(g, e), B = this.findMentionCalls(g);
735
- n.push({
736
- name: o,
754
+ const g = this.source.slice(m, p + 1), P = this.parseParams(l), $ = this.findFunctionCalls(g), D = this.findUniformCalls(g, e), B = this.findMentionCalls(g);
755
+ t.push({
756
+ name: a,
737
757
  type: s,
738
- params: T,
758
+ params: P,
739
759
  body: g,
740
- dependencies: [...I, ...P, ...B],
760
+ dependencies: [...$, ...D, ...B],
741
761
  line: c
742
762
  });
743
763
  }
744
- return n;
764
+ return t;
745
765
  }
746
766
  parseParams(e) {
747
767
  if (!e.trim()) return [];
748
- const n = [], t = e.split(",");
749
- for (const i of t) {
768
+ const t = [], n = e.split(",");
769
+ for (const i of n) {
750
770
  const r = i.trim();
751
771
  if (!r) continue;
752
- const o = r.replace(/\b(in|out|inout|const|highp|mediump|lowp)\b\s*/g, "").trim().match(/^(\w+)\s+(\w+)(?:\[\d*\])?$/);
753
- o && n.push({
754
- type: o[1],
755
- name: o[2]
772
+ const a = r.replace(/\b(in|out|inout|const|highp|mediump|lowp)\b\s*/g, "").trim().match(/^(\w+)\s+(\w+)(?:\[\d*\])?$/);
773
+ a && t.push({
774
+ type: a[1],
775
+ name: a[2]
756
776
  });
757
777
  }
758
- return n;
778
+ return t;
759
779
  }
760
- findClosingBrace(e, n) {
761
- let t = 0, i = !1, r = !1, s = !1, o = !1;
762
- for (let l = n; l < e.length; l++) {
780
+ findClosingBrace(e, t) {
781
+ let n = 0, i = !1, r = !1, s = !1, a = !1;
782
+ for (let l = t; l < e.length; l++) {
763
783
  const f = e[l], c = e[l + 1], m = e[l - 1];
764
- if (!r && !o && f === "/" && c === "/") {
784
+ if (!r && !a && f === "/" && c === "/") {
765
785
  s = !0;
766
786
  continue;
767
787
  }
@@ -771,22 +791,22 @@ class w {
771
791
  continue;
772
792
  }
773
793
  if (!r && !s && f === "/" && c === "*") {
774
- o = !0, l++;
794
+ a = !0, l++;
775
795
  continue;
776
796
  }
777
- if (o && f === "*" && c === "/") {
778
- o = !1, l++;
797
+ if (a && f === "*" && c === "/") {
798
+ a = !1, l++;
779
799
  continue;
780
800
  }
781
- if (!(s || o)) {
801
+ if (!(s || a)) {
782
802
  if (f === '"' && m !== "\\") {
783
803
  r = !r;
784
804
  continue;
785
805
  }
786
806
  if (!r) {
787
807
  if (f === "{")
788
- t++, i = !0;
789
- else if (f === "}" && (t--, i && t === 0))
808
+ n++, i = !0;
809
+ else if (f === "}" && (n--, i && n === 0))
790
810
  return l;
791
811
  }
792
812
  }
@@ -794,7 +814,7 @@ class w {
794
814
  return -1;
795
815
  }
796
816
  findFunctionCalls(e) {
797
- const n = [], t = /* @__PURE__ */ new Set([
817
+ const t = [], n = /* @__PURE__ */ new Set([
798
818
  "if",
799
819
  "else",
800
820
  "for",
@@ -810,56 +830,56 @@ class w {
810
830
  let r;
811
831
  for (; (r = i.exec(e)) !== null; ) {
812
832
  const s = r[1];
813
- t.has(s) || n.push({
833
+ n.has(s) || t.push({
814
834
  name: s,
815
835
  type: "function",
816
836
  index: r.index
817
837
  });
818
838
  }
819
- return n;
839
+ return t;
820
840
  }
821
- findUniformCalls(e, n) {
822
- const t = [];
823
- for (const i of n) {
841
+ findUniformCalls(e, t) {
842
+ const n = [];
843
+ for (const i of t) {
824
844
  const r = new RegExp(`\\b${i.name}\\b`, "g");
825
845
  let s;
826
846
  for (; (s = r.exec(e)) !== null; )
827
- t.push({
847
+ n.push({
828
848
  name: i.name,
829
849
  type: "uniform",
830
850
  index: s.index
831
851
  });
832
852
  }
833
- return t;
853
+ return n;
834
854
  }
835
855
  findMentionCalls(e) {
836
- const n = [], t = /@(\w+)\.([a-zA-Z_]\w*)/g;
856
+ const t = [], n = /@(\w+)\.([a-zA-Z_]\w*)/g;
837
857
  let i;
838
- for (; (i = t.exec(e)) !== null; ) {
858
+ for (; (i = n.exec(e)) !== null; ) {
839
859
  const r = i[1], s = i[2];
840
- n.push({
860
+ t.push({
841
861
  name: `${r}.${s}`,
842
862
  type: "mention",
843
863
  index: i.index
844
864
  });
845
865
  }
846
- return n;
866
+ return t;
847
867
  }
848
868
  }
849
869
  class F {
850
870
  constructor(e) {
851
871
  /** Flag to track if the shader has been compiled */
852
- a(this, "isCompiled", !1);
872
+ o(this, "isCompiled", !1);
853
873
  /** Original and compiled shader parsers */
854
- a(this, "original");
874
+ o(this, "original");
855
875
  /** Compiled parser will be updated with rewritten source after processing imports */
856
- a(this, "compiled");
876
+ o(this, "compiled");
857
877
  /** Collected requirements from imports */
858
- a(this, "requirements", {
878
+ o(this, "requirements", {
859
879
  uniforms: /* @__PURE__ */ new Map(),
860
880
  functions: /* @__PURE__ */ new Map()
861
881
  });
862
- this.original = new w(e), this.compiled = new w(e);
882
+ this.original = new E(e), this.compiled = new E(e);
863
883
  }
864
884
  /**
865
885
  * Detect WebGL version from shader source
@@ -890,13 +910,13 @@ class F {
890
910
  * Process all #import directives
891
911
  */
892
912
  processImports() {
893
- const e = this.original.parse(), n = e.functions.flatMap((t) => t.dependencies.filter((i) => i.type === "mention").map((i) => ({
913
+ const e = this.original.parse(), t = e.functions.flatMap((n) => n.dependencies.filter((i) => i.type === "mention").map((i) => ({
894
914
  name: i.name.split(".")[0],
895
915
  uniform: i.name.split(".")[1]
896
916
  })));
897
- for (const t of e.imports) {
898
- const i = b.resolve(t.module), r = i.extract(t.name);
899
- let s = n.filter(
917
+ for (const n of e.imports) {
918
+ const i = w.resolve(n.module), r = i.extract(n.name);
919
+ let s = t.filter(
900
920
  (l) => l.name === r.function.name
901
921
  );
902
922
  if (s.length > 0) {
@@ -909,82 +929,82 @@ class F {
909
929
  r.dependencies.uniforms.some(
910
930
  (p) => p.name === c.name
911
931
  ) || r.dependencies.uniforms.push(c);
912
- const m = n.indexOf(f);
913
- return m > -1 && n.splice(m, 1), !1;
932
+ const m = t.indexOf(f);
933
+ return m > -1 && t.splice(m, 1), !1;
914
934
  }
915
935
  return !0;
916
936
  }), s.length > 0)
917
- throw new Z(
918
- t.module,
937
+ throw new ee(
938
+ n.module,
919
939
  r.function.name,
920
940
  s[0].uniform
921
941
  );
922
942
  }
923
- const o = i.copy();
924
- this.processExtraction(r, t.alias, o.options), y.merge(t.module, o);
943
+ const a = i.copy();
944
+ this.processExtraction(r, n.alias, a.options), y.merge(n.module, a);
925
945
  }
926
- if (n.length > 0)
927
- throw new ee(
928
- n[0].name,
929
- n[0].uniform
946
+ if (t.length > 0)
947
+ throw new te(
948
+ t[0].name,
949
+ t[0].uniform
930
950
  );
931
951
  }
932
952
  /**
933
953
  * Process an extraction: rewrite names and collect as requirements
934
954
  */
935
- processExtraction(e, n, t = {}) {
936
- const i = e.function, r = Math.random().toString(36).substring(2, 8), s = `${n}_${r}`;
955
+ processExtraction(e, t, n = {}) {
956
+ const i = e.function, r = Math.random().toString(36).substring(2, 8), s = `${t}_${r}`;
937
957
  for (let l = e.dependencies.functions.length - 1; l >= 0; l--) {
938
- const f = e.dependencies.functions[l], c = this.rewriteFunction(f, n, {
958
+ const f = e.dependencies.functions[l], c = this.rewriteFunction(f, t, {
939
959
  uniforms: e.dependencies.uniforms,
940
960
  functions: e.dependencies.functions,
941
961
  unique: s
942
962
  });
943
963
  this.requirements.functions.set(c.name, c);
944
964
  }
945
- const o = this.rewriteFunction(i, n, {
965
+ const a = this.rewriteFunction(i, t, {
946
966
  uniforms: e.dependencies.uniforms,
947
967
  functions: e.dependencies.functions,
948
968
  rename: !0,
949
969
  unique: s
950
970
  });
951
- this.requirements.functions.set(o.name, o);
971
+ this.requirements.functions.set(a.name, a);
952
972
  for (const l of e.dependencies.uniforms) {
953
- if (E.has(l.name)) continue;
973
+ if (R.has(l.name)) continue;
954
974
  const f = {
955
975
  ...l,
956
976
  name: `${s}_${l.name}${l.arrayNum ? `[${l.arrayNum}]` : ""}`
957
977
  };
958
- if (t[i.name]) {
959
- const c = Object.entries(t[i.name]).find(
978
+ if (n[i.name]) {
979
+ const c = Object.entries(n[i.name]).find(
960
980
  ([m, p]) => p.uniform === l.name
961
981
  );
962
982
  c && (c[1].uniform = `${s}_${l.name}`);
963
983
  }
964
984
  this.requirements.uniforms.set(f.name, f);
965
985
  }
966
- t[i.name] && n !== i.name && (t[n] = t[i.name], delete t[i.name]);
986
+ n[i.name] && t !== i.name && (n[t] = n[i.name], delete n[i.name]);
967
987
  }
968
988
  /**
969
989
  * Rewrite a function: namespace all uniform and helper function references
970
990
  */
971
- rewriteFunction(e, n, t = { rename: !1, uniforms: [], functions: [], unique: "" }) {
972
- const i = new Set(t.uniforms.map((c) => c.name)), r = new Set(t.functions.map((c) => c.name)), s = [], o = t.unique ? t.unique : n;
991
+ rewriteFunction(e, t, n = { rename: !1, uniforms: [], functions: [], unique: "" }) {
992
+ const i = new Set(n.uniforms.map((c) => c.name)), r = new Set(n.functions.map((c) => c.name)), s = [], a = n.unique ? n.unique : t;
973
993
  for (const c of e.dependencies)
974
994
  if (c.index !== void 0)
975
995
  if (c.type === "uniform" && i.has(c.name)) {
976
- if (E.has(c.name)) continue;
996
+ if (R.has(c.name)) continue;
977
997
  s.push({
978
998
  index: c.index,
979
999
  oldText: c.name,
980
- newText: `${o}_${c.name}`
1000
+ newText: `${a}_${c.name}`
981
1001
  });
982
1002
  } else c.type === "function" && r.has(c.name) && s.push({
983
1003
  index: c.index,
984
1004
  oldText: c.name,
985
- newText: `${o}_${c.name}`
1005
+ newText: `${a}_${c.name}`
986
1006
  });
987
- const l = this.applyRewrites(e.body, s), f = t.rename ? n : `${o}_${e.name}`;
1007
+ const l = this.applyRewrites(e.body, s), f = n.rename ? t : `${a}_${e.name}`;
988
1008
  return {
989
1009
  ...e,
990
1010
  name: f,
@@ -994,10 +1014,10 @@ class F {
994
1014
  /**
995
1015
  * Apply rewrite operations to a string, processing from end to start
996
1016
  */
997
- applyRewrites(e, n) {
998
- const t = [...n].sort((r, s) => s.index - r.index);
1017
+ applyRewrites(e, t) {
1018
+ const n = [...t].sort((r, s) => s.index - r.index);
999
1019
  let i = e;
1000
- for (const r of t)
1020
+ for (const r of n)
1001
1021
  i = i.slice(0, r.index) + r.newText + i.slice(r.index + r.oldText.length);
1002
1022
  return i;
1003
1023
  }
@@ -1006,53 +1026,53 @@ class F {
1006
1026
  */
1007
1027
  build() {
1008
1028
  const e = this.original.parse();
1009
- let n = this.original.source;
1010
- n = this.removeImportLines(n, e);
1011
- const t = this.findInsertionPointForUniforms(n), i = this.generateUniformsCode();
1012
- i && (n = n.slice(0, t) + i + `
1013
- ` + n.slice(t));
1014
- const r = this.findInsertionPointForFunctions(n), s = this.generateFunctionCode();
1015
- return s && (n = n.slice(0, r) + s + n.slice(r)), n = n.replace(/\n{3,}/g, `
1016
-
1017
- `), n = this.replaceMentions(n, e), n;
1018
- }
1019
- replaceMentions(e, n) {
1020
- let t = e;
1021
- const i = n.functions.filter(
1029
+ let t = this.original.source;
1030
+ t = this.removeImportLines(t, e);
1031
+ const n = this.findInsertionPointForUniforms(t), i = this.generateUniformsCode();
1032
+ i && (t = t.slice(0, n) + i + `
1033
+ ` + t.slice(n));
1034
+ const r = this.findInsertionPointForFunctions(t), s = this.generateFunctionCode();
1035
+ return s && (t = t.slice(0, r) + s + t.slice(r)), t = t.replace(/\n{3,}/g, `
1036
+
1037
+ `), t = this.replaceMentions(t, e), t;
1038
+ }
1039
+ replaceMentions(e, t) {
1040
+ let n = e;
1041
+ const i = t.functions.filter(
1022
1042
  (r) => r.dependencies.some((s) => s.type === "mention")
1023
1043
  );
1024
1044
  for (const r of i) {
1025
- const s = r.dependencies.filter((o) => o.type === "mention");
1026
- for (const o of s) {
1027
- const l = o.name.split("."), f = new RegExp(`\\b${l[0]}_(\\w+)_${l[1]}\\b`, "g"), c = this.requirements.uniforms.keys().find((p) => {
1045
+ const s = r.dependencies.filter((a) => a.type === "mention");
1046
+ for (const a of s) {
1047
+ const l = a.name.split("."), f = new RegExp(`\\b${l[0]}_(\\w+)_${l[1]}\\b`, "g"), c = this.requirements.uniforms.keys().find((p) => {
1028
1048
  var g;
1029
1049
  return ((g = p.match(f)) == null ? void 0 : g[0]) === p;
1030
1050
  });
1031
1051
  if (!c)
1032
1052
  throw new ne(
1033
- o.name,
1053
+ a.name,
1034
1054
  r.name
1035
1055
  );
1036
- const m = new RegExp(`@\\b${o.name}\\b`, "g");
1037
- t = t.replace(m, c);
1056
+ const m = new RegExp(`@\\b${a.name}\\b`, "g");
1057
+ n = n.replace(m, c);
1038
1058
  }
1039
1059
  }
1040
- return t;
1060
+ return n;
1041
1061
  }
1042
1062
  /**
1043
1063
  * Remove #import lines from shader source
1044
1064
  */
1045
- removeImportLines(e, n) {
1046
- const t = e.split(`
1047
- `), i = new Set(n.imports.map((r) => r.line));
1048
- return t.filter((r, s) => {
1049
- const o = i.has(s + 1);
1050
- if (!o && r.trim() === "" && s > 0) {
1065
+ removeImportLines(e, t) {
1066
+ const n = e.split(`
1067
+ `), i = new Set(t.imports.map((r) => r.line));
1068
+ return n.filter((r, s) => {
1069
+ const a = i.has(s + 1);
1070
+ if (!a && r.trim() === "" && s > 0) {
1051
1071
  const l = s - 1;
1052
1072
  if (i.has(l + 1))
1053
1073
  return !1;
1054
1074
  }
1055
- return !o;
1075
+ return !a;
1056
1076
  }).join(`
1057
1077
  `);
1058
1078
  }
@@ -1060,48 +1080,48 @@ class F {
1060
1080
  * Find insertion point for uniforms (after existing uniforms)
1061
1081
  */
1062
1082
  findInsertionPointForUniforms(e) {
1063
- const n = new w(e).parse(), t = n.uniforms.find(
1064
- (o) => o.line === Math.max(...n.uniforms.map((l) => l.line ?? 0))
1083
+ const t = new E(e).parse(), n = t.uniforms.find(
1084
+ (a) => a.line === Math.max(...t.uniforms.map((l) => l.line ?? 0))
1065
1085
  ), i = e.split(`
1066
1086
  `);
1067
1087
  let r = 0;
1068
- if (t && t.line)
1069
- r = t.line;
1088
+ if (n && n.line)
1089
+ r = n.line;
1070
1090
  else
1071
- for (let o = 0; o < i.length; o++) {
1072
- const l = i[o].trim();
1091
+ for (let a = 0; a < i.length; a++) {
1092
+ const l = i[a].trim();
1073
1093
  if (l.startsWith("#version")) {
1074
- r = o + 1;
1094
+ r = a + 1;
1075
1095
  continue;
1076
1096
  }
1077
1097
  if (l.startsWith("precision ")) {
1078
- r = o + 1;
1098
+ r = a + 1;
1079
1099
  continue;
1080
1100
  }
1081
1101
  if (l === "" || l.startsWith("//")) {
1082
- r === o && (r = o + 1);
1102
+ r === a && (r = a + 1);
1083
1103
  continue;
1084
1104
  }
1085
1105
  break;
1086
1106
  }
1087
1107
  let s = 0;
1088
- for (let o = 0; o < r; o++)
1089
- s += i[o].length + 1;
1108
+ for (let a = 0; a < r; a++)
1109
+ s += i[a].length + 1;
1090
1110
  return s;
1091
1111
  }
1092
1112
  findInsertionPointForFunctions(e) {
1093
- const n = new w(e).parse(), t = n.functions.find(
1094
- (o) => o.line === Math.min(...n.functions.map((l) => l.line ?? 1 / 0))
1113
+ const t = new E(e).parse(), n = t.functions.find(
1114
+ (a) => a.line === Math.min(...t.functions.map((l) => l.line ?? 1 / 0))
1095
1115
  ), i = e.split(`
1096
1116
  `);
1097
1117
  let r = 0;
1098
- if (t && t.line)
1099
- r = t.line - 2;
1118
+ if (n && n.line)
1119
+ r = n.line - 2;
1100
1120
  else
1101
- throw new W();
1121
+ throw new H();
1102
1122
  let s = 0;
1103
- for (let o = 0; o < r; o++)
1104
- s += i[o].length + 1;
1123
+ for (let a = 0; a < r; a++)
1124
+ s += i[a].length + 1;
1105
1125
  return s;
1106
1126
  }
1107
1127
  /**
@@ -1110,8 +1130,8 @@ class F {
1110
1130
  generateUniformsCode() {
1111
1131
  const e = [];
1112
1132
  if (this.requirements.uniforms.size > 0)
1113
- for (const n of this.checkUniformsPresence())
1114
- e.push(`uniform ${n.type} ${n.name};`);
1133
+ for (const t of this.checkUniformsPresence())
1134
+ e.push(`uniform ${t.type} ${t.name};`);
1115
1135
  return e.length === 0 ? "" : e.join(`
1116
1136
  `) + `
1117
1137
  `;
@@ -1122,10 +1142,10 @@ class F {
1122
1142
  generateFunctionCode() {
1123
1143
  const e = [];
1124
1144
  if (this.requirements.functions.size > 0)
1125
- for (const n of this.checkFunctionsPresence()) {
1126
- const t = n.params.map((i) => `${i.type} ${i.name}`).join(", ");
1145
+ for (const t of this.checkFunctionsPresence()) {
1146
+ const n = t.params.map((i) => `${i.type} ${i.name}`).join(", ");
1127
1147
  e.push(`
1128
- ${n.type} ${n.name}(${t}) ${n.body}`);
1148
+ ${t.type} ${t.name}(${n}) ${t.body}`);
1129
1149
  }
1130
1150
  return e.length === 0 ? "" : e.join(`
1131
1151
  `) + `
@@ -1135,91 +1155,91 @@ ${n.type} ${n.name}(${t}) ${n.body}`);
1135
1155
  * Check which required uniforms are missing from the original shader
1136
1156
  */
1137
1157
  checkUniformsPresence() {
1138
- const e = this.original.parse(), n = [], t = this.requirements.uniforms;
1139
- for (const [i, r] of t) {
1140
- const s = e.uniforms.find((o) => o.name === i);
1158
+ const e = this.original.parse(), t = [], n = this.requirements.uniforms;
1159
+ for (const [i, r] of n) {
1160
+ const s = e.uniforms.find((a) => a.name === i);
1141
1161
  if (!s) {
1142
- n.push(r);
1162
+ t.push(r);
1143
1163
  continue;
1144
1164
  }
1145
1165
  if (s.type !== r.type)
1146
- throw new C(
1166
+ throw new U(
1147
1167
  "uniform",
1148
1168
  i,
1149
1169
  r.type,
1150
1170
  s.type
1151
1171
  );
1152
1172
  }
1153
- return n;
1173
+ return t;
1154
1174
  }
1155
1175
  /**
1156
1176
  * Check which required functions are missing from the original shader
1157
1177
  */
1158
1178
  checkFunctionsPresence() {
1159
- const e = this.original.parse(), n = [], t = this.requirements.functions;
1160
- for (const [i, r] of t) {
1161
- const s = e.functions.find((o) => o.name === i);
1179
+ const e = this.original.parse(), t = [], n = this.requirements.functions;
1180
+ for (const [i, r] of n) {
1181
+ const s = e.functions.find((a) => a.name === i);
1162
1182
  if (!s) {
1163
- n.push(r);
1183
+ t.push(r);
1164
1184
  continue;
1165
1185
  }
1166
1186
  if (s.type !== r.type)
1167
- throw new C(
1187
+ throw new U(
1168
1188
  "function",
1169
1189
  i,
1170
1190
  r.type,
1171
1191
  s.type
1172
1192
  );
1173
1193
  }
1174
- return n;
1194
+ return t;
1175
1195
  }
1176
1196
  }
1177
1197
  class v extends F {
1178
- constructor(n, t, i = {}) {
1179
- super(t);
1180
- a(this, "name");
1181
- a(this, "options", {});
1182
- this.name = n, this.options = this.resolveOptions(i);
1183
- }
1184
- resolveOptions(n) {
1185
- if (!(n != null && n.default)) return n || {};
1186
- const t = this.original.parse(), i = n.default;
1187
- for (const r of t.functions)
1198
+ constructor(t, n, i = {}) {
1199
+ super(n);
1200
+ o(this, "name");
1201
+ o(this, "options", {});
1202
+ this.name = t, this.options = this.resolveOptions(i);
1203
+ }
1204
+ resolveOptions(t) {
1205
+ if (!(t != null && t.default)) return t || {};
1206
+ const n = this.original.parse(), i = t.default;
1207
+ for (const r of n.functions)
1188
1208
  if (!(r.name === "main" || r.name === "default"))
1189
- if (n[r.name]) {
1190
- const s = n[r.name];
1191
- for (const o in i)
1192
- o in s || (s[o] = i[o]);
1209
+ if (t[r.name]) {
1210
+ const s = t[r.name];
1211
+ for (const a in i)
1212
+ a in s || (s[a] = i[a]);
1193
1213
  } else
1194
- n[r.name] = { ...i };
1195
- return delete n.default, n || {};
1214
+ t[r.name] = { ...i };
1215
+ return delete t.default, t || {};
1196
1216
  }
1197
1217
  /**
1198
1218
  * Define a module with given name and source, and register it
1199
1219
  */
1200
- static define(n) {
1201
- const { name: t, source: i, options: r } = n;
1202
- if (t === "sandbox" || t.startsWith("sandbox/"))
1203
- throw new Q(t);
1204
- const s = new v(t, i, r);
1205
- if (b.has(t))
1206
- throw new J(t);
1207
- return b.register(t, s), s;
1220
+ static define(t) {
1221
+ const { name: n, source: i, options: r } = t;
1222
+ if (n === "sandbox" || n.startsWith("sandbox/"))
1223
+ throw new J(n);
1224
+ const s = new v(n, i, r);
1225
+ if (w.has(n))
1226
+ throw new Z(n);
1227
+ return w.register(n, s), s;
1208
1228
  }
1209
1229
  /**
1210
1230
  * Resolve a module by name from the registry, throwing an error if not found
1211
1231
  */
1212
- static resolve(n) {
1213
- return b.resolve(n);
1232
+ static resolve(t) {
1233
+ return w.resolve(t);
1214
1234
  }
1215
1235
  /**
1216
1236
  * Create a copy of the module. To unplug references to the original object.
1217
1237
  * Used when copying module to the runtime registry to allow independent runtime changes to options without affecting the original module definition.
1218
1238
  */
1219
- copy(n = "original") {
1239
+ copy(t = "original") {
1220
1240
  return new v(
1221
1241
  this.name,
1222
- this[n].source,
1242
+ this[t].source,
1223
1243
  JSON.parse(JSON.stringify(this.options))
1224
1244
  );
1225
1245
  }
@@ -1227,14 +1247,14 @@ class v extends F {
1227
1247
  * Merge options from another module into this one, without affecting the original module definition.
1228
1248
  * Used when merging imported modules into the runtime registry.
1229
1249
  */
1230
- merge(n) {
1250
+ merge(t) {
1231
1251
  this.options = this.options || {};
1232
- const t = this.getDefinition().uniforms.map((i) => i.name);
1233
- for (const [i, r] of Object.entries(n.options ?? {}))
1252
+ const n = this.getDefinition().uniforms.map((i) => i.name);
1253
+ for (const [i, r] of Object.entries(t.options ?? {}))
1234
1254
  if (!this.options[i]) this.options[i] = r;
1235
1255
  else
1236
- for (const [s, o] of Object.entries(r))
1237
- t.includes(o.uniform) || (this.options[i][s] = o);
1256
+ for (const [s, a] of Object.entries(r))
1257
+ n.includes(a.uniform) || (this.options[i][s] = a);
1238
1258
  }
1239
1259
  /**
1240
1260
  * Get the module definition
@@ -1242,34 +1262,34 @@ class v extends F {
1242
1262
  getDefinition() {
1243
1263
  return this.compile(), {
1244
1264
  name: this.name,
1245
- methods: this.compiled.parse().functions.map((n) => n.name).filter((n) => n !== "main" && n !== "default"),
1246
- uniforms: this.compiled.parse().uniforms.map((n) => ({ name: n.name, type: n.type })),
1265
+ methods: this.compiled.parse().functions.map((t) => t.name).filter((t) => t !== "main" && t !== "default"),
1266
+ uniforms: this.compiled.parse().uniforms.map((t) => ({ name: t.name, type: t.type })),
1247
1267
  options: this.options
1248
1268
  };
1249
1269
  }
1250
1270
  /**
1251
1271
  * Extract a method with all its dependencies
1252
1272
  */
1253
- extract(n) {
1254
- if (this.compile(), n === "main")
1273
+ extract(t) {
1274
+ if (this.compile(), t === "main")
1255
1275
  throw new K(this.name);
1256
- if (n === "default")
1257
- throw new X(this.name);
1258
- const t = this.compiled.parse(), i = t.functions.find((o) => o.name === n);
1276
+ if (t === "default")
1277
+ throw new Q(this.name);
1278
+ const n = this.compiled.parse(), i = n.functions.find((a) => a.name === t);
1259
1279
  if (!i)
1260
- throw new Y(this.name, n);
1280
+ throw new Y(this.name, t);
1261
1281
  const r = /* @__PURE__ */ new Map(), s = /* @__PURE__ */ new Map();
1262
1282
  return this.collectDependencies({
1263
1283
  current: i,
1264
1284
  scope: {
1265
- functions: t.functions,
1266
- uniforms: t.uniforms
1285
+ functions: n.functions,
1286
+ uniforms: n.uniforms
1267
1287
  },
1268
1288
  collected: {
1269
1289
  functions: r,
1270
1290
  uniforms: s
1271
1291
  },
1272
- visited: /* @__PURE__ */ new Set([n])
1292
+ visited: /* @__PURE__ */ new Set([t])
1273
1293
  }), {
1274
1294
  function: i,
1275
1295
  dependencies: {
@@ -1281,36 +1301,36 @@ class v extends F {
1281
1301
  /**
1282
1302
  * Recursively collect all function and uniform dependencies
1283
1303
  */
1284
- collectDependencies(n) {
1285
- for (const t of n.current.dependencies)
1286
- if (t.type === "function") {
1287
- if (n.visited.has(t.name)) continue;
1288
- const i = n.scope.functions.find((r) => r.name === t.name);
1289
- i && (n.visited.add(t.name), n.collected.functions.set(t.name, i), this.collectDependencies({
1304
+ collectDependencies(t) {
1305
+ for (const n of t.current.dependencies)
1306
+ if (n.type === "function") {
1307
+ if (t.visited.has(n.name)) continue;
1308
+ const i = t.scope.functions.find((r) => r.name === n.name);
1309
+ i && (t.visited.add(n.name), t.collected.functions.set(n.name, i), this.collectDependencies({
1290
1310
  current: i,
1291
1311
  scope: {
1292
- functions: n.scope.functions,
1293
- uniforms: n.scope.uniforms
1312
+ functions: t.scope.functions,
1313
+ uniforms: t.scope.uniforms
1294
1314
  },
1295
1315
  collected: {
1296
- functions: n.collected.functions,
1297
- uniforms: n.collected.uniforms
1316
+ functions: t.collected.functions,
1317
+ uniforms: t.collected.uniforms
1298
1318
  },
1299
- visited: n.visited
1319
+ visited: t.visited
1300
1320
  }));
1301
- } else if (t.type === "uniform") {
1302
- const i = n.scope.uniforms.find(
1303
- (r) => r.name === t.name
1321
+ } else if (n.type === "uniform") {
1322
+ const i = t.scope.uniforms.find(
1323
+ (r) => r.name === n.name
1304
1324
  );
1305
- i && !n.collected.uniforms.has(t.name) && n.collected.uniforms.set(t.name, i);
1325
+ i && !t.collected.uniforms.has(n.name) && t.collected.uniforms.set(n.name, i);
1306
1326
  }
1307
1327
  }
1308
1328
  }
1309
1329
  class V {
1310
1330
  constructor(e = []) {
1311
- a(this, "modules", /* @__PURE__ */ new Map());
1312
- e.forEach((n) => {
1313
- this.register(n.name, n);
1331
+ o(this, "modules", /* @__PURE__ */ new Map());
1332
+ e.forEach((t) => {
1333
+ this.register(t.name, t);
1314
1334
  });
1315
1335
  }
1316
1336
  /**
@@ -1335,14 +1355,14 @@ class V {
1335
1355
  */
1336
1356
  defaults() {
1337
1357
  const e = {};
1338
- return this.modules.forEach((n) => {
1339
- const t = n.getDefinition();
1340
- if (t.options)
1341
- for (const i in t.options) {
1342
- const r = t.options[i];
1358
+ return this.modules.forEach((t) => {
1359
+ const n = t.getDefinition();
1360
+ if (n.options)
1361
+ for (const i in n.options) {
1362
+ const r = n.options[i];
1343
1363
  for (const s in r) {
1344
- const o = r[s];
1345
- o.default !== void 0 && !t.uniforms.map((l) => l.name).includes(o.uniform) && (e[o.uniform] = o.default);
1364
+ const a = r[s];
1365
+ a.default !== void 0 && !n.uniforms.map((l) => l.name).includes(a.uniform) && (e[a.uniform] = a.default);
1346
1366
  }
1347
1367
  }
1348
1368
  }), e;
@@ -1351,33 +1371,33 @@ class V {
1351
1371
  * Resolve the options from the module definitions for a given function name.
1352
1372
  */
1353
1373
  resolveOptions(e) {
1354
- for (const n of this.modules.values())
1355
- if (n.options && n.options[e])
1356
- return n.options[e];
1374
+ for (const t of this.modules.values())
1375
+ if (t.options && t.options[e])
1376
+ return t.options[e];
1357
1377
  return null;
1358
1378
  }
1359
1379
  /**
1360
1380
  * Register a new module in the registry.
1361
1381
  */
1362
- register(e, n) {
1363
- this.modules.set(e, n);
1382
+ register(e, t) {
1383
+ this.modules.set(e, t);
1364
1384
  }
1365
1385
  /**
1366
1386
  * Merge a module into the registry. If a module with the same name already exists, options will be merged together.
1367
1387
  */
1368
- merge(e, n) {
1369
- if (!this.modules.has(e)) return this.register(e, n);
1370
- const t = this.modules.get(e);
1371
- t.merge(n), this.modules.set(e, t);
1388
+ merge(e, t) {
1389
+ if (!this.modules.has(e)) return this.register(e, t);
1390
+ const n = this.modules.get(e);
1391
+ n.merge(t), this.modules.set(e, n);
1372
1392
  }
1373
1393
  /**
1374
1394
  * Resolve a module by name. Throws an error if the module is not found.
1375
1395
  */
1376
1396
  resolve(e) {
1377
- const n = this.modules.get(e);
1378
- if (!n)
1379
- throw new j(e);
1380
- return n;
1397
+ const t = this.modules.get(e);
1398
+ if (!t)
1399
+ throw new X(e);
1400
+ return t;
1381
1401
  }
1382
1402
  /**
1383
1403
  * Check if a module exists in the registry by name.
@@ -1401,8 +1421,8 @@ class V {
1401
1421
  * Load multiple modules into the registry at once.
1402
1422
  */
1403
1423
  load(e) {
1404
- e.forEach((n) => {
1405
- this.register(n.name, n);
1424
+ e.forEach((t) => {
1425
+ this.register(t.name, t);
1406
1426
  });
1407
1427
  }
1408
1428
  /**
@@ -1412,7 +1432,7 @@ class V {
1412
1432
  this.modules.clear();
1413
1433
  }
1414
1434
  }
1415
- const oe = `// ─── Constants ──────────────────────────────────────────────
1435
+ const ae = `// ─── Constants ──────────────────────────────────────────────
1416
1436
 
1417
1437
  const float PI = 3.14159265359;
1418
1438
  const float TAU = 6.28318530718;
@@ -1621,7 +1641,7 @@ vec2 voronoi(vec2 p) {
1621
1641
  }
1622
1642
 
1623
1643
  void main() {}
1624
- `, ae = `/**
1644
+ `, le = `/**
1625
1645
  * Hex integer to RGB.
1626
1646
  * Usage: hex(0xFF6600) → orange
1627
1647
  */
@@ -1720,7 +1740,7 @@ vec3 iridescent(vec2 uv, float time, float speed) {
1720
1740
  }
1721
1741
 
1722
1742
  void main() {}
1723
- `, le = `// ─── Time Shapers ──────────────────────────────────────────
1743
+ `, ce = `// ─── Time Shapers ──────────────────────────────────────────
1724
1744
  // Convert raw time (u_time) to normalized 0–1 range.
1725
1745
  // Output feeds directly into easing functions.
1726
1746
 
@@ -1842,7 +1862,7 @@ float teleport(float t) {
1842
1862
  }
1843
1863
 
1844
1864
  void main() {}
1845
- `, ce = `#import hash from 'sandbox'
1865
+ `, ue = `#import hash from 'sandbox'
1846
1866
  #import noise from 'sandbox'
1847
1867
  #import fbm from 'sandbox'
1848
1868
  #import voronoi from 'sandbox'
@@ -2037,7 +2057,7 @@ vec2 cells(vec2 uv, float intensity) {
2037
2057
  }
2038
2058
 
2039
2059
  void main() {}
2040
- `, ue = `#import hash from 'sandbox'
2060
+ `, fe = `#import hash from 'sandbox'
2041
2061
 
2042
2062
  uniform float u_intensity;
2043
2063
 
@@ -2224,11 +2244,11 @@ vec3 arcade(vec3 color, vec2 uv, float intensity) {
2224
2244
  }
2225
2245
 
2226
2246
  void main() {}
2227
- `, b = new V([
2228
- new v("sandbox", oe),
2229
- new v("sandbox/colors", ae),
2230
- new v("sandbox/time", le),
2231
- new v("sandbox/effects", ce, {
2247
+ `, w = new V([
2248
+ new v("sandbox", ae),
2249
+ new v("sandbox/colors", le),
2250
+ new v("sandbox/time", ce),
2251
+ new v("sandbox/effects", ue, {
2232
2252
  default: {
2233
2253
  intensity: { uniform: "u_intensity", default: 1 }
2234
2254
  },
@@ -2278,7 +2298,7 @@ void main() {}
2278
2298
  intensity: { uniform: "u_intensity", default: 1 }
2279
2299
  }
2280
2300
  }),
2281
- new v("sandbox/filters", ue, {
2301
+ new v("sandbox/filters", fe, {
2282
2302
  default: {
2283
2303
  intensity: { uniform: "u_intensity", default: 1 }
2284
2304
  },
@@ -2307,18 +2327,18 @@ void main() {}
2307
2327
  intensity: { uniform: "u_intensity", default: 0.5 }
2308
2328
  }
2309
2329
  })
2310
- ]), y = new V(), E = /* @__PURE__ */ new Map([
2330
+ ]), y = new V(), R = /* @__PURE__ */ new Map([
2311
2331
  ["u_resolution", "vec2"],
2312
2332
  ["u_time", "float"],
2313
2333
  ["u_delta", "float"],
2314
2334
  ["u_mouse", "vec2"],
2315
2335
  ["u_frame", "int"]
2316
2336
  ]);
2317
- class fe {
2337
+ class he {
2318
2338
  constructor(e) {
2319
- a(this, "gl");
2320
- a(this, "program", null);
2321
- a(this, "uniforms", /* @__PURE__ */ new Map());
2339
+ o(this, "gl");
2340
+ o(this, "program", null);
2341
+ o(this, "uniforms", /* @__PURE__ */ new Map());
2322
2342
  this.gl = e;
2323
2343
  }
2324
2344
  /**
@@ -2327,32 +2347,32 @@ class fe {
2327
2347
  */
2328
2348
  attachProgram(e) {
2329
2349
  this.program = e;
2330
- for (const n of this.uniforms.values())
2331
- n.invalidateLocation();
2350
+ for (const t of this.uniforms.values())
2351
+ t.invalidateLocation();
2332
2352
  return this;
2333
2353
  }
2334
2354
  /**
2335
2355
  * Set a uniform value.
2336
2356
  * Creates the uniform if it doesn't exist, updates if it does.
2337
2357
  */
2338
- set(e, n) {
2339
- const t = this.uniforms.get(e);
2340
- return t ? t.setValue(n) : this.uniforms.set(e, new k(e, n)), this;
2358
+ set(e, t) {
2359
+ const n = this.uniforms.get(e);
2360
+ return n ? n.setValue(t) : this.uniforms.set(e, new M(e, t)), this;
2341
2361
  }
2342
2362
  /**
2343
2363
  * Set multiple uniforms at once.
2344
2364
  */
2345
2365
  setMany(e) {
2346
- for (const [n, t] of Object.entries(e))
2347
- this.set(n, t);
2366
+ for (const [t, n] of Object.entries(e))
2367
+ this.set(t, n);
2348
2368
  return this;
2349
2369
  }
2350
2370
  /**
2351
2371
  * Get current uniform value.
2352
2372
  */
2353
2373
  get(e) {
2354
- var n;
2355
- return (n = this.uniforms.get(e)) == null ? void 0 : n.getValue();
2374
+ var t;
2375
+ return (t = this.uniforms.get(e)) == null ? void 0 : t.getValue();
2356
2376
  }
2357
2377
  /**
2358
2378
  * Check if uniform exists.
@@ -2381,10 +2401,10 @@ class fe {
2381
2401
  * Upload only built-in uniforms (u_resolution, u_time, u_delta, u_mouse, u_frame).
2382
2402
  * Call this every frame with current values.
2383
2403
  */
2384
- uploadBuiltIns(e, n, t) {
2385
- if (this.set("u_resolution", n), this.set("u_time", e.time), this.set("u_delta", e.delta), this.set("u_mouse", t), this.set("u_frame", e.frame), !this.program)
2404
+ uploadBuiltIns(e, t, n) {
2405
+ if (this.set("u_resolution", t), this.set("u_time", e.time), this.set("u_delta", e.delta), this.set("u_mouse", n), this.set("u_frame", e.frame), !this.program)
2386
2406
  return this;
2387
- for (const i of E.keys()) {
2407
+ for (const i of R.keys()) {
2388
2408
  const r = this.uniforms.get(i);
2389
2409
  r && r.upload(this.gl, this.program);
2390
2410
  }
@@ -2415,17 +2435,217 @@ class fe {
2415
2435
  return this.uniforms.size;
2416
2436
  }
2417
2437
  }
2418
- class O {
2438
+ class x {
2439
+ constructor(e, t, n, i) {
2440
+ o(this, "name");
2441
+ o(this, "gl");
2442
+ o(this, "texture", null);
2443
+ o(this, "location", null);
2444
+ o(this, "locationResolved", !1);
2445
+ o(this, "source");
2446
+ o(this, "options");
2447
+ o(this, "dynamicOverride");
2448
+ o(this, "needsUpload", !0);
2449
+ o(this, "needsReupload", !1);
2450
+ this.gl = e, this.name = t, this.source = n, this.dynamicOverride = i == null ? void 0 : i.dynamic, this.options = x.resolveOptions(n, i), this.needsReupload = this.options.dynamic;
2451
+ }
2452
+ /**
2453
+ * Update the texture source.
2454
+ * Marks texture for re-upload on next bind.
2455
+ * Respects the original `dynamic` option if explicitly set, otherwise re-infers from source type.
2456
+ */
2457
+ setSource(e) {
2458
+ this.source = e, this.needsUpload = !0, this.needsReupload = this.dynamicOverride ?? x.isDynamicSource(e);
2459
+ }
2460
+ /**
2461
+ * Resolve and cache uniform location from program.
2462
+ * Returns null if the sampler uniform doesn't exist in the shader.
2463
+ */
2464
+ resolveLocation(e, t) {
2465
+ return this.locationResolved || (this.location = e.getUniformLocation(t, this.name), this.locationResolved = !0), this.location;
2466
+ }
2467
+ /**
2468
+ * Invalidate cached location (call when program changes).
2469
+ */
2470
+ invalidateLocation() {
2471
+ this.location = null, this.locationResolved = !1;
2472
+ }
2473
+ /**
2474
+ * Bind texture to a texture unit and set the sampler uniform.
2475
+ * @param program - Current WebGL program (for location resolution)
2476
+ * @param unit - Texture unit index (0, 1, 2, ...)
2477
+ */
2478
+ upload(e, t) {
2479
+ const n = this.gl, i = this.resolveLocation(n, e);
2480
+ if (i !== null) {
2481
+ if (!this.texture) {
2482
+ if (this.texture = n.createTexture(), !this.texture) return;
2483
+ this.needsUpload = !0;
2484
+ }
2485
+ n.activeTexture(n.TEXTURE0 + t), n.bindTexture(n.TEXTURE_2D, this.texture), (this.needsUpload || this.needsReupload) && (this.uploadPixels(), this.needsUpload = !1), n.uniform1i(i, t);
2486
+ }
2487
+ }
2488
+ /**
2489
+ * Cleanup WebGL texture resource.
2490
+ */
2491
+ destroy() {
2492
+ this.texture && (this.gl.deleteTexture(this.texture), this.texture = null), this.location = null, this.locationResolved = !1;
2493
+ }
2494
+ /**
2495
+ * Upload pixel data from source and apply texture parameters.
2496
+ */
2497
+ uploadPixels() {
2498
+ const e = this.gl;
2499
+ e.pixelStorei(e.UNPACK_FLIP_Y_WEBGL, this.options.flipY), e.texImage2D(
2500
+ e.TEXTURE_2D,
2501
+ 0,
2502
+ e.RGBA,
2503
+ e.RGBA,
2504
+ e.UNSIGNED_BYTE,
2505
+ this.source
2506
+ ), this.applyParameters();
2507
+ }
2508
+ /**
2509
+ * Apply texture wrap and filter parameters.
2510
+ */
2511
+ applyParameters() {
2512
+ const e = this.gl;
2513
+ e.texParameteri(
2514
+ e.TEXTURE_2D,
2515
+ e.TEXTURE_WRAP_S,
2516
+ x.resolveWrap(e, this.options.wrapS)
2517
+ ), e.texParameteri(
2518
+ e.TEXTURE_2D,
2519
+ e.TEXTURE_WRAP_T,
2520
+ x.resolveWrap(e, this.options.wrapT)
2521
+ ), e.texParameteri(
2522
+ e.TEXTURE_2D,
2523
+ e.TEXTURE_MIN_FILTER,
2524
+ this.options.minFilter === "nearest" ? e.NEAREST : e.LINEAR
2525
+ ), e.texParameteri(
2526
+ e.TEXTURE_2D,
2527
+ e.TEXTURE_MAG_FILTER,
2528
+ this.options.magFilter === "nearest" ? e.NEAREST : e.LINEAR
2529
+ );
2530
+ }
2531
+ /**
2532
+ * Resolve wrap mode string to WebGL constant.
2533
+ */
2534
+ static resolveWrap(e, t) {
2535
+ switch (t) {
2536
+ case "repeat":
2537
+ return e.REPEAT;
2538
+ case "mirror":
2539
+ return e.MIRRORED_REPEAT;
2540
+ case "clamp":
2541
+ default:
2542
+ return e.CLAMP_TO_EDGE;
2543
+ }
2544
+ }
2545
+ /**
2546
+ * Resolve texture options with defaults.
2547
+ */
2548
+ static resolveOptions(e, t) {
2549
+ const n = (t == null ? void 0 : t.wrap) ?? "clamp";
2550
+ return {
2551
+ wrap: n,
2552
+ wrapS: (t == null ? void 0 : t.wrapS) ?? n,
2553
+ wrapT: (t == null ? void 0 : t.wrapT) ?? n,
2554
+ minFilter: (t == null ? void 0 : t.minFilter) ?? "linear",
2555
+ magFilter: (t == null ? void 0 : t.magFilter) ?? "linear",
2556
+ flipY: (t == null ? void 0 : t.flipY) ?? !0,
2557
+ dynamic: (t == null ? void 0 : t.dynamic) ?? x.isDynamicSource(e)
2558
+ };
2559
+ }
2560
+ /**
2561
+ * Check if a source is dynamic (needs re-upload every frame).
2562
+ */
2563
+ static isDynamicSource(e) {
2564
+ return e instanceof HTMLVideoElement;
2565
+ }
2566
+ }
2567
+ class me {
2568
+ constructor(e) {
2569
+ o(this, "gl");
2570
+ o(this, "program", null);
2571
+ o(this, "textures", /* @__PURE__ */ new Map());
2572
+ this.gl = e;
2573
+ }
2574
+ /**
2575
+ * Attach to a WebGL program.
2576
+ * Invalidates all cached locations since they're program-specific.
2577
+ */
2578
+ attachProgram(e) {
2579
+ this.program = e;
2580
+ for (const t of this.textures.values())
2581
+ t.invalidateLocation();
2582
+ return this;
2583
+ }
2584
+ /**
2585
+ * Set a texture.
2586
+ * Creates the texture entry if it doesn't exist, updates source if it does.
2587
+ */
2588
+ set(e, t, n) {
2589
+ const i = this.textures.get(e);
2590
+ return i ? i.setSource(t) : this.textures.set(e, new x(this.gl, e, t, n)), this;
2591
+ }
2592
+ /**
2593
+ * Get a texture by name.
2594
+ */
2595
+ get(e) {
2596
+ return this.textures.get(e);
2597
+ }
2598
+ /**
2599
+ * Check if a texture exists.
2600
+ */
2601
+ has(e) {
2602
+ return this.textures.has(e);
2603
+ }
2604
+ /**
2605
+ * Remove a texture and free its GPU resources.
2606
+ */
2607
+ delete(e) {
2608
+ const t = this.textures.get(e);
2609
+ return t ? (t.destroy(), this.textures.delete(e)) : !1;
2610
+ }
2611
+ /**
2612
+ * Upload all textures to their respective texture units.
2613
+ * Units are assigned sequentially (0, 1, 2, ...).
2614
+ */
2615
+ uploadAll() {
2616
+ if (!this.program)
2617
+ return this;
2618
+ let e = 0;
2619
+ for (const t of this.textures.values())
2620
+ t.upload(this.program, e), e++;
2621
+ return this;
2622
+ }
2623
+ /**
2624
+ * Get texture count.
2625
+ */
2626
+ get size() {
2627
+ return this.textures.size;
2628
+ }
2629
+ /**
2630
+ * Cleanup all textures.
2631
+ */
2632
+ destroy() {
2633
+ for (const e of this.textures.values())
2634
+ e.destroy();
2635
+ this.textures.clear(), this.program = null;
2636
+ }
2637
+ }
2638
+ class L {
2419
2639
  constructor() {
2420
- a(this, "hooks", /* @__PURE__ */ new Map());
2640
+ o(this, "hooks", /* @__PURE__ */ new Map());
2421
2641
  }
2422
2642
  id() {
2423
2643
  return Math.random().toString(36).substring(2, 10);
2424
2644
  }
2425
2645
  /** Add a new hook, returns a removal function */
2426
2646
  add(e) {
2427
- const n = this.id();
2428
- return this.hooks.set(n, e), () => this.remove(n);
2647
+ const t = this.id();
2648
+ return this.hooks.set(t, e), () => this.remove(t);
2429
2649
  }
2430
2650
  /** Remove a hook by its ID */
2431
2651
  remove(e) {
@@ -2433,12 +2653,12 @@ class O {
2433
2653
  }
2434
2654
  /** Run all hooks with the given state */
2435
2655
  run(e) {
2436
- for (const [n, t] of this.hooks)
2656
+ for (const [t, n] of this.hooks)
2437
2657
  try {
2438
- t(e) === !1 && this.remove(n);
2658
+ n(e) === !1 && this.remove(t);
2439
2659
  } catch (i) {
2440
- throw new ie(
2441
- n,
2660
+ throw new re(
2661
+ t,
2442
2662
  i instanceof Error ? i.message : String(i)
2443
2663
  );
2444
2664
  }
@@ -2447,29 +2667,30 @@ class O {
2447
2667
  this.hooks.clear();
2448
2668
  }
2449
2669
  }
2450
- class M {
2451
- constructor(e, n) {
2452
- a(this, "canvas");
2453
- a(this, "gl");
2454
- a(this, "options");
2455
- a(this, "onBeforeHooks", new O());
2456
- a(this, "onAfterHooks", new O());
2457
- a(this, "_program");
2458
- a(this, "_geometry");
2459
- a(this, "_uniforms");
2460
- a(this, "_clock");
2461
- a(this, "_resolution", [1, 1]);
2462
- a(this, "_mouse", [0, 0]);
2463
- a(this, "_version", 1);
2464
- a(this, "playing", !1);
2465
- this.canvas = e, this.options = n, this.gl = this.initContext(), this.enableExtensions(), this._program = new se(this.gl), this._geometry = A.fullscreenQuad(this.gl), this._uniforms = new fe(this.gl), this._clock = new re(), this.options.fps && this._clock.setMaxFps(this.options.fps), this.options.onBeforeRender && this.onBeforeHooks.add(this.options.onBeforeRender), this.options.onAfterRender && this.onAfterHooks.add(this.options.onAfterRender), this.onRender = this.onRender.bind(this);
2670
+ class T {
2671
+ constructor(e, t) {
2672
+ o(this, "canvas");
2673
+ o(this, "gl");
2674
+ o(this, "options");
2675
+ o(this, "onBeforeHooks", new L());
2676
+ o(this, "onAfterHooks", new L());
2677
+ o(this, "_program");
2678
+ o(this, "_geometry");
2679
+ o(this, "_uniforms");
2680
+ o(this, "_textures");
2681
+ o(this, "_clock");
2682
+ o(this, "_resolution", [1, 1]);
2683
+ o(this, "_mouse", [0, 0]);
2684
+ o(this, "_version", 1);
2685
+ o(this, "playing", !1);
2686
+ this.canvas = e, this.options = t, this.gl = this.initContext(), this.enableExtensions(), this._program = new oe(this.gl), this._geometry = k.fullscreenQuad(this.gl), this._uniforms = new he(this.gl), this._textures = new me(this.gl), this._clock = new se(), this.options.fps && this._clock.setMaxFps(this.options.fps), this.options.onBeforeRender && this.onBeforeHooks.add(this.options.onBeforeRender), this.options.onAfterRender && this.onAfterHooks.add(this.options.onAfterRender), this.onRender = this.onRender.bind(this);
2466
2687
  }
2467
2688
  /**
2468
2689
  * Factory method to create and setup WebGL instance.
2469
2690
  */
2470
- static setup(e, n) {
2471
- const t = new M(e, n);
2472
- return n.vertex && n.fragment && t.shader(n.vertex, n.fragment), n.uniforms && t._uniforms.setMany(n.uniforms), y.isEmpty() || t._uniforms.setMany(y.defaults()), t;
2691
+ static setup(e, t) {
2692
+ const n = new T(e, t);
2693
+ return t.vertex && t.fragment && n.shader(t.vertex, t.fragment), t.uniforms && n._uniforms.setMany(t.uniforms), t.textures && n.texturesFromSchema(t.textures), y.isEmpty() || n._uniforms.setMany(y.defaults()), n;
2473
2694
  }
2474
2695
  /**
2475
2696
  * Initialize WebGL context.
@@ -2483,13 +2704,13 @@ class M {
2483
2704
  alpha: !0,
2484
2705
  depth: !1,
2485
2706
  stencil: !1
2486
- }, n = this.canvas.getContext("webgl2", e);
2487
- if (n)
2488
- return this._version = 2, n;
2489
- const t = this.canvas.getContext("webgl", e);
2707
+ }, t = this.canvas.getContext("webgl2", e);
2490
2708
  if (t)
2491
- return this._version = 1, t;
2492
- const i = new z();
2709
+ return this._version = 2, t;
2710
+ const n = this.canvas.getContext("webgl", e);
2711
+ if (n)
2712
+ return this._version = 1, n;
2713
+ const i = new W();
2493
2714
  throw this.options.onError(i), i;
2494
2715
  }
2495
2716
  /**
@@ -2501,8 +2722,8 @@ class M {
2501
2722
  /**
2502
2723
  * Set viewport dimensions.
2503
2724
  */
2504
- viewport(e, n, t, i) {
2505
- return this.canvas.width = t, this.canvas.height = i, this.gl.viewport(e, n, t, i), this._resolution = [t, i], this;
2725
+ viewport(e, t, n, i) {
2726
+ return this.canvas.width = n, this.canvas.height = i, this.gl.viewport(e, t, n, i), this._resolution = [n, i], this;
2506
2727
  }
2507
2728
  /**
2508
2729
  * Set the clock time
@@ -2513,14 +2734,14 @@ class M {
2513
2734
  /**
2514
2735
  * Update mouse position.
2515
2736
  */
2516
- mouse(e, n) {
2517
- return this._mouse = [e, n], this;
2737
+ mouse(e, t) {
2738
+ return this._mouse = [e, t], this;
2518
2739
  }
2519
2740
  /**
2520
2741
  * Set a uniform value.
2521
2742
  */
2522
- uniform(e, n) {
2523
- return this._uniforms.set(e, n), this;
2743
+ uniform(e, t) {
2744
+ return this._uniforms.set(e, t), this;
2524
2745
  }
2525
2746
  /**
2526
2747
  * Set multiple uniforms.
@@ -2534,29 +2755,54 @@ class M {
2534
2755
  getUniform(e) {
2535
2756
  return this._uniforms.get(e);
2536
2757
  }
2758
+ /**
2759
+ * Set a texture.
2760
+ */
2761
+ texture(e, t, n) {
2762
+ return this._textures.set(e, t, n), this;
2763
+ }
2764
+ /**
2765
+ * Set multiple textures from a schema.
2766
+ */
2767
+ texturesFromSchema(e) {
2768
+ for (const [t, n] of Object.entries(e))
2769
+ if (n instanceof HTMLImageElement || n instanceof HTMLCanvasElement || n instanceof HTMLVideoElement || n instanceof ImageBitmap || n instanceof ImageData || n instanceof OffscreenCanvas)
2770
+ this._textures.set(t, n);
2771
+ else {
2772
+ const { source: i, ...r } = n;
2773
+ this._textures.set(t, i, r);
2774
+ }
2775
+ return this;
2776
+ }
2777
+ /**
2778
+ * Remove a texture.
2779
+ */
2780
+ removeTexture(e) {
2781
+ return this._textures.delete(e), this;
2782
+ }
2537
2783
  /**
2538
2784
  * Compile and link shaders.
2539
2785
  * Errors are handled via onError callback, never thrown.
2540
2786
  */
2541
- shader(e, n) {
2787
+ shader(e, t) {
2542
2788
  try {
2543
- if (y.clear(), e.version() !== n.version())
2544
- throw new G(
2789
+ if (y.clear(), e.version() !== t.version())
2790
+ throw new z(
2545
2791
  e.version(),
2546
- n.version()
2792
+ t.version()
2547
2793
  );
2548
- this._program.compile(e.source(), n.compile()), this._version = n.version(), this._geometry.linkAttributes(this._program);
2549
- const t = this._program.getProgram();
2550
- t && this._uniforms.attachProgram(t);
2794
+ this._program.compile(e.source(), t.compile()), this._version = t.version(), this._geometry.linkAttributes(this._program);
2795
+ const n = this._program.getProgram();
2796
+ n && (this._uniforms.attachProgram(n), this._textures.attachProgram(n));
2551
2797
  try {
2552
2798
  this.options.onLoad();
2553
2799
  } catch (i) {
2554
- throw new te(
2800
+ throw new ie(
2555
2801
  i instanceof Error ? i.message : String(i)
2556
2802
  );
2557
2803
  }
2558
- } catch (t) {
2559
- t instanceof h && this.options.onError(t);
2804
+ } catch (n) {
2805
+ n instanceof h && this.options.onError(n);
2560
2806
  }
2561
2807
  return this;
2562
2808
  }
@@ -2574,14 +2820,14 @@ class M {
2574
2820
  const e = this._clock.getState();
2575
2821
  try {
2576
2822
  this.onBeforeHooks.run(e);
2577
- } catch (n) {
2578
- n instanceof h && this.options.onError(n);
2823
+ } catch (t) {
2824
+ t instanceof h && this.options.onError(t);
2579
2825
  }
2580
2826
  this.playing = !1, this._clock.stop();
2581
2827
  try {
2582
2828
  this.onAfterHooks.run(e);
2583
- } catch (n) {
2584
- n instanceof h && this.options.onError(n);
2829
+ } catch (t) {
2830
+ t instanceof h && this.options.onError(t);
2585
2831
  }
2586
2832
  return this;
2587
2833
  }
@@ -2613,34 +2859,34 @@ class M {
2613
2859
  * Cleanup all resources.
2614
2860
  */
2615
2861
  destroy() {
2616
- this.pause(), this._clock.destroy(), this._geometry.destroy(), this._program.destroy(), this._uniforms.destroy(), this.onAfterHooks.destroy(), this.onBeforeHooks.destroy(), y.clear();
2862
+ this.pause(), this._clock.destroy(), this._geometry.destroy(), this._program.destroy(), this._uniforms.destroy(), this._textures.destroy(), this.onAfterHooks.destroy(), this.onBeforeHooks.destroy(), y.clear();
2617
2863
  }
2618
2864
  /**
2619
2865
  * Internal render callback.
2620
2866
  */
2621
2867
  onRender(e) {
2622
- const n = this.gl;
2868
+ const t = this.gl;
2623
2869
  try {
2624
2870
  this.onBeforeHooks.run(e);
2625
- } catch (t) {
2626
- t instanceof h && this.options.onError(t);
2871
+ } catch (n) {
2872
+ n instanceof h && this.options.onError(n);
2627
2873
  }
2628
- n.clearColor(0, 0, 0, 0), n.clear(n.COLOR_BUFFER_BIT), this._program.use(), this._uniforms.uploadBuiltIns(e, this._resolution, this._mouse), this._uniforms.uploadAll(), this._geometry.bind(), this._geometry.draw();
2874
+ t.clearColor(0, 0, 0, 0), t.clear(t.COLOR_BUFFER_BIT), this._program.use(), this._uniforms.uploadBuiltIns(e, this._resolution, this._mouse), this._uniforms.uploadAll(), this._textures.uploadAll(), this._geometry.bind(), this._geometry.draw();
2629
2875
  try {
2630
2876
  this.onAfterHooks.run(e);
2631
- } catch (t) {
2632
- t instanceof h && this.options.onError(t);
2877
+ } catch (n) {
2878
+ n instanceof h && this.options.onError(n);
2633
2879
  }
2634
2880
  }
2635
2881
  }
2636
2882
  class d extends F {
2637
2883
  constructor(e) {
2638
- super(e), E.forEach((n, t) => {
2639
- this.requirements.uniforms.set(t, { name: t, type: n, line: 0 });
2884
+ super(e), R.forEach((t, n) => {
2885
+ this.requirements.uniforms.set(n, { name: n, type: t, line: 0 });
2640
2886
  });
2641
2887
  }
2642
2888
  }
2643
- const S = `#ifdef GL_ES
2889
+ const A = `#ifdef GL_ES
2644
2890
  precision mediump float;
2645
2891
  #endif
2646
2892
 
@@ -2653,7 +2899,7 @@ void main() {
2653
2899
  v_texcoord = a_texcoord;
2654
2900
  gl_Position = vec4(a_position, 0.0, 1.0);
2655
2901
  }
2656
- `, L = `#ifdef GL_ES
2902
+ `, O = `#ifdef GL_ES
2657
2903
  precision mediump float;
2658
2904
  #endif
2659
2905
 
@@ -2667,7 +2913,7 @@ void main() {
2667
2913
  vec3 color = vec3(uv.x, uv.y, 0.5 + 0.5 * sin(u_time));
2668
2914
  gl_FragColor = vec4(color, 1.0);
2669
2915
  }
2670
- `, U = `#version 300 es
2916
+ `, C = `#version 300 es
2671
2917
 
2672
2918
  in vec2 a_position;
2673
2919
  in vec2 a_texcoord;
@@ -2677,7 +2923,7 @@ out vec2 v_texcoord;
2677
2923
  void main() {
2678
2924
  v_texcoord = a_texcoord;
2679
2925
  gl_Position = vec4(a_position, 0.0, 1.0);
2680
- }`, he = `#version 300 es
2926
+ }`, de = `#version 300 es
2681
2927
  precision highp float;
2682
2928
 
2683
2929
  uniform vec2 u_resolution;
@@ -2692,21 +2938,21 @@ void main() {
2692
2938
  vec3 color = vec3(uv.x, uv.y, 0.5 + 0.5 * sin(u_time));
2693
2939
  fragColor = vec4(color, 1.0);
2694
2940
  }`;
2695
- class $ {
2696
- constructor(e, n) {
2941
+ class I {
2942
+ constructor(e, t) {
2697
2943
  /** Active event listeners */
2698
- a(this, "listeners", []);
2944
+ o(this, "listeners", []);
2699
2945
  /** HTML canvas element */
2700
- a(this, "canvasEl");
2946
+ o(this, "canvasEl");
2701
2947
  /** Resolved options */
2702
- a(this, "options");
2948
+ o(this, "options");
2703
2949
  /** WebGL engine */
2704
- a(this, "engine");
2950
+ o(this, "engine");
2705
2951
  /** User sets custom vertex shader */
2706
- a(this, "usingCustomVertex", !1);
2707
- if (this.canvasEl = e, this.options = this.resolveOptions(n), this.engine = M.setup(this.canvasEl, this.options), this.setupListeners(), this.setViewport(), this.options.modules)
2708
- for (const [t, i] of Object.entries(this.options.modules))
2709
- this.module(t, i);
2952
+ o(this, "usingCustomVertex", !1);
2953
+ if (this.canvasEl = e, this.options = this.resolveOptions(t), this.engine = T.setup(this.canvasEl, this.options), this.setupListeners(), this.setViewport(), this.options.modules)
2954
+ for (const [n, i] of Object.entries(this.options.modules))
2955
+ this.module(n, i);
2710
2956
  this.options.autoplay && this.play();
2711
2957
  }
2712
2958
  /**
@@ -2727,8 +2973,8 @@ class $ {
2727
2973
  * autoplay: true,
2728
2974
  * });
2729
2975
  */
2730
- static create(e, n) {
2731
- return new $(e, n);
2976
+ static create(e, t) {
2977
+ return new I(e, t);
2732
2978
  }
2733
2979
  /**
2734
2980
  * Define a shader module that can be imported in shader source with `#import <function> from "module_name"`.
@@ -2740,14 +2986,14 @@ class $ {
2740
2986
  * // myFunc();
2741
2987
  * // }
2742
2988
  */
2743
- static defineModule(e, n, t = {}) {
2744
- v.define({ name: e, source: n, options: t });
2989
+ static defineModule(e, t, n = {}) {
2990
+ v.define({ name: e, source: t, options: n });
2745
2991
  }
2746
2992
  /**
2747
2993
  * Get the list of available shader modules that can be used with `#import` in shader source.
2748
2994
  */
2749
2995
  static availableModules() {
2750
- return b.available();
2996
+ return w.available();
2751
2997
  }
2752
2998
  /**
2753
2999
  * Compile a shader source with Sandbox's shader preprocessor and return the final GLSL code.
@@ -2757,9 +3003,9 @@ class $ {
2757
3003
  return new d(e).compile();
2758
3004
  }
2759
3005
  resolveOptions(e) {
2760
- const n = {
2761
- vertex: new d(S),
2762
- fragment: new d(L),
3006
+ const t = {
3007
+ vertex: new d(A),
3008
+ fragment: new d(O),
2763
3009
  autoplay: !0,
2764
3010
  pauseWhenHidden: !0,
2765
3011
  dpr: "auto",
@@ -2779,45 +3025,46 @@ You can handle errors programmatically by providing an onError callback to suppr
2779
3025
  onBeforeRender: null,
2780
3026
  onAfterRender: null,
2781
3027
  uniforms: {},
2782
- modules: {}
3028
+ modules: {},
3029
+ textures: {}
2783
3030
  };
2784
3031
  if (e != null && e.vertex && (this.usingCustomVertex = !0), e != null && e.vertex && !(e != null && e.fragment)) {
2785
- n.vertex = new d(e.vertex);
2786
- const s = n.vertex.version();
2787
- n.fragment = new d(s === 2 ? he : L);
3032
+ t.vertex = new d(e.vertex);
3033
+ const s = t.vertex.version();
3034
+ t.fragment = new d(s === 2 ? de : O);
2788
3035
  }
2789
3036
  if (e != null && e.fragment && !(e != null && e.vertex)) {
2790
- n.fragment = new d(e.fragment);
2791
- const s = n.fragment.version();
2792
- n.vertex = new d(s === 2 ? U : S);
3037
+ t.fragment = new d(e.fragment);
3038
+ const s = t.fragment.version();
3039
+ t.vertex = new d(s === 2 ? C : A);
2793
3040
  }
2794
- e != null && e.vertex && (e != null && e.fragment) && (n.vertex = new d(e.vertex), n.fragment = new d(e.fragment));
2795
- const { vertex: t, fragment: i, ...r } = e || {};
2796
- return { ...n, ...r };
3041
+ e != null && e.vertex && (e != null && e.fragment) && (t.vertex = new d(e.vertex), t.fragment = new d(e.fragment));
3042
+ const { vertex: n, fragment: i, ...r } = e || {};
3043
+ return { ...t, ...r };
2797
3044
  }
2798
3045
  setupListeners() {
2799
3046
  this.listeners.push(
2800
3047
  // Window resize
2801
- x.on(window, "resize", () => {
3048
+ b.on(window, "resize", () => {
2802
3049
  this.setViewport();
2803
3050
  }),
2804
3051
  // Canvas resize
2805
- x.on(this.canvasEl, "resize", () => {
3052
+ b.on(this.canvasEl, "resize", () => {
2806
3053
  this.setViewport();
2807
3054
  }),
2808
3055
  // Visibility check on scroll
2809
3056
  (() => {
2810
3057
  let e = !1;
2811
- return x.on(document, "scroll", (n) => {
3058
+ return b.on(document, "scroll", (t) => {
2812
3059
  this.options.pauseWhenHidden && (this.isInViewport() ? e && !this.isPlaying() && (this.play(), e = !1) : this.isPlaying() && (this.pause(), e = !0));
2813
3060
  });
2814
3061
  })(),
2815
3062
  // Mouse tracking
2816
- x.on(document, "mousemove", (e) => {
3063
+ b.on(document, "mousemove", (e) => {
2817
3064
  this.setMouse(e.clientX || e.pageX, e.clientY || e.pageY);
2818
3065
  }),
2819
3066
  // Touch tracking
2820
- x.on(document, "touchmove", (e) => {
3067
+ b.on(document, "touchmove", (e) => {
2821
3068
  e.touches.length > 0 && this.setMouse(e.touches[0].clientX, e.touches[0].clientY);
2822
3069
  })
2823
3070
  );
@@ -2826,21 +3073,21 @@ You can handle errors programmatically by providing an onError callback to suppr
2826
3073
  this.listeners.forEach((e) => e()), this.listeners = [];
2827
3074
  }
2828
3075
  setViewport() {
2829
- const e = this.options.dpr === "auto" ? Math.min(2, window.devicePixelRatio || 1) : this.options.dpr, n = this.canvasEl.clientWidth || this.canvasEl.width || 1, t = this.canvasEl.clientHeight || this.canvasEl.height || 1;
3076
+ const e = this.options.dpr === "auto" ? Math.min(2, window.devicePixelRatio || 1) : this.options.dpr, t = this.canvasEl.clientWidth || this.canvasEl.width || 1, n = this.canvasEl.clientHeight || this.canvasEl.height || 1;
2830
3077
  this.engine.viewport(
2831
3078
  0,
2832
3079
  0,
2833
- Math.max(1, Math.floor(n * e)),
2834
- Math.max(1, Math.floor(t * e))
3080
+ Math.max(1, Math.floor(t * e)),
3081
+ Math.max(1, Math.floor(n * e))
2835
3082
  );
2836
3083
  }
2837
3084
  isInViewport() {
2838
3085
  const e = this.canvasEl.getBoundingClientRect();
2839
3086
  return e.bottom >= 0 && e.right >= 0 && e.top <= (window.innerHeight || document.documentElement.clientHeight) && e.left <= (window.innerWidth || document.documentElement.clientWidth);
2840
3087
  }
2841
- setMouse(e, n) {
2842
- const t = this.canvasEl.getBoundingClientRect();
2843
- e >= t.left && e <= t.right && n >= t.top && n <= t.bottom && this.engine.mouse(e - t.left, n - t.top);
3088
+ setMouse(e, t) {
3089
+ const n = this.canvasEl.getBoundingClientRect();
3090
+ e >= n.left && e <= n.right && t >= n.top && t <= n.bottom && this.engine.mouse(e - n.left, t - n.top);
2844
3091
  }
2845
3092
  /**
2846
3093
  * Set a single uniform value with type checking.
@@ -2849,8 +3096,8 @@ You can handle errors programmatically by providing an onError callback to suppr
2849
3096
  * sandbox.setUniform<number>("u_time", 1.5);
2850
3097
  * sandbox.setUniform<Vec3[]>("u_colors", [[1, 0, 0], [0, 1, 0]]);
2851
3098
  */
2852
- setUniform(e, n) {
2853
- return this.engine.uniform(e, n), this;
3099
+ setUniform(e, t) {
3100
+ return this.engine.uniform(e, t), this;
2854
3101
  }
2855
3102
  /**
2856
3103
  * Set multiple uniforms at once with type checking.
@@ -2875,13 +3122,41 @@ You can handle errors programmatically by providing an onError callback to suppr
2875
3122
  getUniform(e) {
2876
3123
  return this.engine.getUniform(e);
2877
3124
  }
3125
+ /**
3126
+ * Set a texture for a sampler2D uniform.
3127
+ * @example
3128
+ * sandbox.setTexture("u_texture", imageElement);
3129
+ * sandbox.setTexture("u_texture", imageElement, { wrap: "repeat" });
3130
+ */
3131
+ setTexture(e, t, n) {
3132
+ return this.engine.texture(e, t, n), this;
3133
+ }
3134
+ /**
3135
+ * Set multiple textures at once.
3136
+ * @example
3137
+ * sandbox.setTextures({
3138
+ * u_texture: imageElement,
3139
+ * u_detail: { source: detailImg, wrap: "repeat" },
3140
+ * });
3141
+ */
3142
+ setTextures(e) {
3143
+ return this.engine.texturesFromSchema(e), this;
3144
+ }
3145
+ /**
3146
+ * Remove a texture and free its GPU resources.
3147
+ * @example
3148
+ * sandbox.removeTexture("u_texture");
3149
+ */
3150
+ removeTexture(e) {
3151
+ return this.engine.removeTexture(e), this;
3152
+ }
2878
3153
  /**
2879
3154
  * Update shaders.
2880
3155
  * @example
2881
3156
  * sandbox.setShader(vertexSource, fragmentSource);
2882
3157
  */
2883
- setShader(e, n) {
2884
- return this.options.vertex = new d(e), this.options.fragment = new d(n), this.usingCustomVertex = !0, this.engine.shader(this.options.vertex, this.options.fragment), this;
3158
+ setShader(e, t) {
3159
+ return this.options.vertex = new d(e), this.options.fragment = new d(t), this.usingCustomVertex = !0, this.engine.shader(this.options.vertex, this.options.fragment), this;
2885
3160
  }
2886
3161
  /**
2887
3162
  * Update only fragment shader (uses default vertex).
@@ -2889,9 +3164,9 @@ You can handle errors programmatically by providing an onError callback to suppr
2889
3164
  * sandbox.setFragment(fragmentSource);
2890
3165
  */
2891
3166
  setFragment(e) {
2892
- const n = new d(e), t = n.version(), i = this.options.vertex.version();
2893
- return this.options.fragment = n, t !== i && (this.usingCustomVertex || (this.options.vertex = new d(
2894
- t === 2 ? U : S
3167
+ const t = new d(e), n = t.version(), i = this.options.vertex.version();
3168
+ return this.options.fragment = t, n !== i && (this.usingCustomVertex || (this.options.vertex = new d(
3169
+ n === 2 ? C : A
2895
3170
  ))), this.engine.shader(this.options.vertex, this.options.fragment), this;
2896
3171
  }
2897
3172
  /**
@@ -2919,22 +3194,22 @@ You can handle errors programmatically by providing an onError callback to suppr
2919
3194
  /**
2920
3195
  * Add a runtime render hook.
2921
3196
  */
2922
- hook(e, n = "before") {
2923
- return n === "before" ? this.engine.onBeforeHooks.add(e) : this.engine.onAfterHooks.add(e);
3197
+ hook(e, t = "before") {
3198
+ return t === "before" ? this.engine.onBeforeHooks.add(e) : this.engine.onAfterHooks.add(e);
2924
3199
  }
2925
3200
  /**
2926
3201
  * Runtime configure the module behavior
2927
3202
  * @example
2928
3203
  * sandbox.module("my_module", { intensity: 0.5 });
2929
3204
  */
2930
- module(e, n) {
2931
- const t = y.resolveOptions(e);
2932
- if (!t)
3205
+ module(e, t) {
3206
+ const n = y.resolveOptions(e);
3207
+ if (!n)
2933
3208
  return console.warn(
2934
3209
  `Sandbox: Counld not find options for '${e}' function. Make sure you used the correct imported name and the module is currently in use by the shader.`
2935
3210
  ), this;
2936
- for (const [i, r] of Object.entries(n)) {
2937
- const s = t[i];
3211
+ for (const [i, r] of Object.entries(t)) {
3212
+ const s = n[i];
2938
3213
  if (!s) {
2939
3214
  console.warn(
2940
3215
  `Sandbox: Option '${i}' not found for function '${e}'. Make sure to check available options with Sandbox.availableModules() and provide the correct option name.`
@@ -2967,8 +3242,8 @@ You can handle errors programmatically by providing an onError callback to suppr
2967
3242
  * Pause animation loop at specific time (in seconds).
2968
3243
  */
2969
3244
  pauseAt(e) {
2970
- const n = this.hook((t) => {
2971
- t.time >= e && (n(), this.pause());
3245
+ const t = this.hook((n) => {
3246
+ n.time >= e && (t(), this.pause());
2972
3247
  }, "after");
2973
3248
  return this;
2974
3249
  }
@@ -3018,6 +3293,57 @@ You can handle errors programmatically by providing an onError callback to suppr
3018
3293
  get canvas() {
3019
3294
  return this.canvasEl;
3020
3295
  }
3296
+ /**
3297
+ * Export current frame as a data URL string.
3298
+ * Requires `preserveDrawingBuffer: true` if called while playing.
3299
+ * @example
3300
+ * const url = sandbox.renderAt(1.5).exportAsURL("image/png");
3301
+ */
3302
+ exportAsURL(e = "image/png", t) {
3303
+ return this.canvas.toDataURL(e, t);
3304
+ }
3305
+ /**
3306
+ * Export current frame as a Blob.
3307
+ * Requires `preserveDrawingBuffer: true` if called while playing.
3308
+ * @example
3309
+ * const blob = await sandbox.renderAt(1.5).exportAsBlob("image/png");
3310
+ */
3311
+ exportAsBlob(e = "image/png", t) {
3312
+ return new Promise((n, i) => {
3313
+ this.canvas.toBlob(
3314
+ (r) => {
3315
+ r ? n(r) : i(new Error("Failed to create blob from canvas."));
3316
+ },
3317
+ e,
3318
+ t
3319
+ );
3320
+ });
3321
+ }
3322
+ /**
3323
+ * Export current frame as an HTMLImageElement.
3324
+ * Requires `preserveDrawingBuffer: true` if called while playing.
3325
+ * @example
3326
+ * const img = sandbox.renderAt(1.5).exportAsImage("image/png");
3327
+ * img.onload = () => document.body.appendChild(img);
3328
+ */
3329
+ exportAsImage(e = "image/png", t) {
3330
+ const n = new Image();
3331
+ return n.src = this.exportAsURL(e, t), n;
3332
+ }
3333
+ /**
3334
+ * Capture the canvas as a MediaStream for video calls or recording.
3335
+ * @example
3336
+ * // WebRTC video call
3337
+ * const stream = sandbox.stream(30);
3338
+ * peerConnection.addTrack(stream.getVideoTracks()[0], stream);
3339
+ *
3340
+ * @example
3341
+ * // Record to video file
3342
+ * const recorder = new MediaRecorder(sandbox.stream(30));
3343
+ */
3344
+ stream(e) {
3345
+ return this.canvasEl.captureStream(e);
3346
+ }
3021
3347
  /**
3022
3348
  * Destroy sandbox and release all resources.
3023
3349
  * @example
@@ -3030,26 +3356,28 @@ You can handle errors programmatically by providing an onError callback to suppr
3030
3356
  }
3031
3357
  }
3032
3358
  export {
3033
- $ as Sandbox,
3034
- X as SandboxAttemptedToImportDefaultFunctionError,
3359
+ I as Sandbox,
3360
+ Q as SandboxAttemptedToImportDefaultFunctionError,
3035
3361
  K as SandboxAttemptedToImportMainFunctionError,
3036
- de as SandboxContextCreationError,
3362
+ ve as SandboxContextCreationError,
3037
3363
  h as SandboxError,
3038
- Q as SandboxForbiddenModuleNameError,
3364
+ J as SandboxForbiddenModuleNameError,
3039
3365
  _ as SandboxGLSLShaderCompilationError,
3040
3366
  ne as SandboxMentionCouldNotBeReplacedError,
3041
- ee as SandboxMentionFunctionNotFoundError,
3042
- Z as SandboxMentionUniformNotFoundError,
3367
+ te as SandboxMentionFunctionNotFoundError,
3368
+ ee as SandboxMentionUniformNotFoundError,
3043
3369
  Y as SandboxModuleMethodNotFoundError,
3044
- j as SandboxModuleNotFoundError,
3045
- ie as SandboxOnHookCallbackError,
3046
- te as SandboxOnLoadCallbackError,
3047
- J as SandboxOverwriteModuleError,
3048
- R as SandboxProgramError,
3049
- H as SandboxShaderDuplicateImportNameError,
3370
+ X as SandboxModuleNotFoundError,
3371
+ re as SandboxOnHookCallbackError,
3372
+ ie as SandboxOnLoadCallbackError,
3373
+ Z as SandboxOverwriteModuleError,
3374
+ S as SandboxProgramError,
3375
+ j as SandboxShaderDuplicateImportNameError,
3050
3376
  q as SandboxShaderImportSyntaxError,
3051
- C as SandboxShaderRequirementMismatchError,
3052
- G as SandboxShaderVersionMismatchError,
3053
- W as SandboxShaderWithoutFunctionError,
3054
- z as SandboxWebGLNotSupportedError
3377
+ U as SandboxShaderRequirementMismatchError,
3378
+ z as SandboxShaderVersionMismatchError,
3379
+ H as SandboxShaderWithoutFunctionError,
3380
+ ge as SandboxTextureCreationError,
3381
+ xe as SandboxTextureUnitLimitError,
3382
+ W as SandboxWebGLNotSupportedError
3055
3383
  };