@jayf0x/fluidity-js 0.2.8 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,1945 +1,1477 @@
1
- var mC = Object.defineProperty;
2
- var SC = (e, g, C) => g in e ? mC(e, g, { enumerable: !0, configurable: !0, writable: !0, value: C }) : e[g] = C;
3
- var LI = (e, g, C) => (SC(e, typeof g != "symbol" ? g + "" : g, C), C), fI = (e, g, C) => {
4
- if (!g.has(e))
5
- throw TypeError("Cannot " + C);
1
+ import { forwardRef as e, useEffect as t, useImperativeHandle as n, useRef as r } from "react";
2
+ import { jsx as i } from "react/jsx-runtime";
3
+ //#region src/core/config.ts
4
+ var a = {
5
+ densityDissipation: [.94, 1],
6
+ velocityDissipation: [.9, .999],
7
+ splatRadius: [.001, .04],
8
+ splatForce: [.1, 5],
9
+ specularExp: [.1, 10],
10
+ shine: [0, .15],
11
+ warpStrength: [.001, .1]
6
12
  };
7
- var I = (e, g, C) => (fI(e, g, "read from private field"), C ? C.call(e) : g.get(e)), A = (e, g, C) => {
8
- if (g.has(e))
9
- throw TypeError("Cannot add the same private member more than once");
10
- g instanceof WeakSet ? g.add(e) : g.set(e, C);
11
- }, o = (e, g, C, i) => (fI(e, g, "write to private field"), i ? i.call(e, C) : g.set(e, C), C);
12
- var h = (e, g, C) => (fI(e, g, "access private method"), C);
13
- import { jsx as IC } from "react/jsx-runtime";
14
- import { useRef as Ng, useEffect as lg, forwardRef as CC, useImperativeHandle as iC } from "react";
15
- const BC = {
16
- densityDissipation: [0.94, 1],
17
- velocityDissipation: [0.9, 0.999],
18
- splatRadius: [1e-3, 0.04],
19
- splatForce: [0.1, 5],
20
- specularExp: [0.1, 10],
21
- shine: [0, 0.15],
22
- warpStrength: [1e-3, 0.1]
23
- };
24
- function Eg(e) {
25
- const g = { ...e };
26
- for (const [C, [i, s]] of Object.entries(BC)) {
27
- const t = e[C];
28
- t !== void 0 && t >= 0 && t <= 1 && (g[C] = i + (s - i) * t);
29
- }
30
- return g;
13
+ function o(e) {
14
+ let t = { ...e };
15
+ for (let [n, [r, i]] of Object.entries(a)) {
16
+ let a = e[n];
17
+ a !== void 0 && a >= 0 && a <= 1 && (t[n] = r + (i - r) * a);
18
+ }
19
+ return t;
31
20
  }
32
- const eC = {
33
- densityDissipation: 0.83,
34
- velocityDissipation: 0.91,
35
- pressureIterations: 1,
36
- curl: 0,
37
- splatRadius: 0.1,
38
- splatForce: 0.08,
39
- refraction: 1,
40
- specularExp: 0,
41
- shine: 0,
42
- waterColor: "#000000",
43
- glowColor: "#b3d9ff",
44
- algorithm: "aurora",
45
- warpStrength: 0.04
46
- }, jI = {
47
- ...eC,
48
- densityDissipation: 0.9,
49
- velocityDissipation: 0.9,
50
- pressureIterations: 3,
51
- curl: 0.2,
52
- splatRadius: 0.2,
53
- splatForce: 0.5,
54
- refraction: 0.2,
55
- specularExp: 0.01,
56
- shine: 0.5,
57
- waterColor: "#090017",
58
- glowColor: "#b04721"
59
- }, gI = {
60
- dpr: typeof window < "u" ? 1 / (window.devicePixelRatio || 1) : 1,
61
- sim: 0.5
62
- }, sC = {
63
- backgroundColor: "#0a0a0a",
64
- backgroundSize: "cover",
65
- mouseEnabled: !0,
66
- workerEnabled: !0
67
- }, rg = {
68
- ...sC,
69
- effect: 0,
70
- imageSize: "cover"
71
- }, mg = {
72
- ...sC,
73
- fontSize: 100,
74
- color: "#ffffff",
75
- fontFamily: "sans-serif",
76
- fontWeight: 900
77
- }, nC = {
78
- calm: {
79
- densityDissipation: 0.98,
80
- velocityDissipation: 0.81,
81
- curl: 1e-4,
82
- splatRadius: 0.05,
83
- splatForce: 0.08,
84
- refraction: 0.15,
85
- shine: 0.03,
86
- glowColor: "#99d9ff",
87
- waterColor: "#00050d"
88
- },
89
- sand: {
90
- densityDissipation: 0.95,
91
- velocityDissipation: 0.81,
92
- curl: 1,
93
- splatRadius: 0.23,
94
- splatForce: 0.16,
95
- refraction: 0.8,
96
- specularExp: 0,
97
- shine: 0.33,
98
- glowColor: "#070707",
99
- waterColor: "#735420"
100
- },
101
- wave: {
102
- densityDissipation: 0.9,
103
- velocityDissipation: 0.2,
104
- curl: 0.2,
105
- splatRadius: 0.1,
106
- splatForce: 0.22,
107
- refraction: 0.35,
108
- shine: 0.2,
109
- glowColor: "#80ccff",
110
- waterColor: "#000308"
111
- },
112
- neon: {
113
- densityDissipation: 0.75,
114
- velocityDissipation: 0.3,
115
- curl: 0.05,
116
- splatRadius: 0.18,
117
- splatForce: 0.29,
118
- refraction: 0.25,
119
- specularExp: 0.04,
120
- shine: 0.93,
121
- glowColor: "#ff33cc",
122
- waterColor: "#0d0014"
123
- },
124
- smoke: {
125
- densityDissipation: 0.93,
126
- velocityDissipation: 0.71,
127
- curl: 0.04,
128
- splatRadius: 0.21,
129
- splatForce: 0.14,
130
- refraction: 0.08,
131
- shine: 0,
132
- glowColor: "#808080",
133
- waterColor: "#0f0f0f"
134
- }
21
+ var s = {
22
+ densityDissipation: .83,
23
+ velocityDissipation: .91,
24
+ pressureIterations: 1,
25
+ curl: 0,
26
+ splatRadius: .1,
27
+ splatForce: .08,
28
+ refraction: 1,
29
+ specularExp: 0,
30
+ shine: 0,
31
+ waterColor: "#000000",
32
+ glowColor: "#b3d9ff",
33
+ algorithm: "aurora",
34
+ warpStrength: .04
35
+ }, c = {
36
+ ...s,
37
+ densityDissipation: .9,
38
+ velocityDissipation: .9,
39
+ pressureIterations: 3,
40
+ curl: .2,
41
+ splatRadius: .2,
42
+ splatForce: .5,
43
+ refraction: .2,
44
+ specularExp: .01,
45
+ shine: .5,
46
+ waterColor: "#090017",
47
+ glowColor: "#b04721"
48
+ }, l = {
49
+ dpr: typeof window < "u" ? 1 / (window.devicePixelRatio || 1) : 1,
50
+ sim: .5
51
+ }, u = {
52
+ backgroundColor: "#0a0a0a",
53
+ backgroundSize: "cover",
54
+ mouseEnabled: !0,
55
+ workerEnabled: !0
56
+ }, d = {
57
+ ...u,
58
+ effect: 0,
59
+ imageSize: "cover"
60
+ }, f = {
61
+ ...u,
62
+ fontSize: 100,
63
+ color: "#ffffff",
64
+ fontFamily: "sans-serif",
65
+ fontWeight: 900
66
+ }, p = {
67
+ calm: {
68
+ densityDissipation: .98,
69
+ velocityDissipation: .81,
70
+ curl: 1e-4,
71
+ splatRadius: .05,
72
+ splatForce: .08,
73
+ refraction: .15,
74
+ shine: .03,
75
+ glowColor: "#99d9ff",
76
+ waterColor: "#00050d"
77
+ },
78
+ sand: {
79
+ densityDissipation: .95,
80
+ velocityDissipation: .81,
81
+ curl: 1,
82
+ splatRadius: .23,
83
+ splatForce: .16,
84
+ refraction: .8,
85
+ specularExp: 0,
86
+ shine: .33,
87
+ glowColor: "#070707",
88
+ waterColor: "#735420"
89
+ },
90
+ wave: {
91
+ densityDissipation: .9,
92
+ velocityDissipation: .2,
93
+ curl: .2,
94
+ splatRadius: .1,
95
+ splatForce: .22,
96
+ refraction: .35,
97
+ shine: .2,
98
+ glowColor: "#80ccff",
99
+ waterColor: "#000308"
100
+ },
101
+ neon: {
102
+ densityDissipation: .75,
103
+ velocityDissipation: .3,
104
+ curl: .05,
105
+ splatRadius: .18,
106
+ splatForce: .29,
107
+ refraction: .25,
108
+ specularExp: .04,
109
+ shine: .93,
110
+ glowColor: "#ff33cc",
111
+ waterColor: "#0d0014"
112
+ },
113
+ smoke: {
114
+ densityDissipation: .93,
115
+ velocityDissipation: .71,
116
+ curl: .04,
117
+ splatRadius: .21,
118
+ splatForce: .14,
119
+ refraction: .08,
120
+ shine: 0,
121
+ glowColor: "#808080",
122
+ waterColor: "#0f0f0f"
123
+ }
135
124
  };
136
- function wI(e) {
137
- if (Array.isArray(e))
138
- return e;
139
- const g = e.slice(1, 7);
140
- return g.length === 3 ? [
141
- parseInt(g[0] + g[0], 16) / 255,
142
- parseInt(g[1] + g[1], 16) / 255,
143
- parseInt(g[2] + g[2], 16) / 255
144
- ] : [
145
- parseInt(g.slice(0, 2), 16) / 255,
146
- parseInt(g.slice(2, 4), 16) / 255,
147
- parseInt(g.slice(4, 6), 16) / 255
148
- ];
149
- }
150
- function ZI(e = {}, g, C = eC) {
151
- return { ...g ? { ...C, ...nC[g] } : C, ...e };
152
- }
153
- function II(e, g, C, i, s = "cover") {
154
- let t;
155
- s === "cover" ? t = Math.max(C / e, i / g) : s === "contain" ? t = Math.min(C / e, i / g) : typeof s == "string" && s.endsWith("%") ? t = Math.min(C / e, i / g) * (parseFloat(s) / 100) : typeof s == "string" && s.endsWith("px") ? t = parseFloat(s) / Math.max(e, g) : typeof s == "number" ? t = s : t = Math.max(C / e, i / g);
156
- const l = e * t, u = g * t;
157
- return { x: (C - l) / 2, y: (i - u) / 2, drawW: l, drawH: u };
158
- }
159
- function rC(e, g, C, i, s = null, t = "cover") {
160
- const { text: l, fontSize: u, color: Z, fontFamily: d = "sans-serif", fontWeight: S = 900 } = i, a = new OffscreenCanvas(g, C), c = a.getContext("2d");
161
- ((w) => {
162
- if (s) {
163
- c.clearRect(0, 0, g, C), c.fillStyle = "black", c.fillRect(0, 0, g, C);
164
- const { x: n, y, drawW: v, drawH: Y } = II(
165
- s.width,
166
- s.height,
167
- g,
168
- C,
169
- t
170
- );
171
- c.drawImage(s, n, y, v, Y);
172
- } else
173
- c.fillStyle = "black", c.fillRect(0, 0, g, C);
174
- c.fillStyle = w, c.font = `${S} ${u}px ${d}`, c.textAlign = "center", c.textBaseline = "middle", c.fillText(l, g / 2, C / 2);
175
- })(Z);
176
- const B = uI(e, a);
177
- c.fillStyle = "black", c.fillRect(0, 0, g, C), c.fillStyle = "white", c.font = `${S} ${u}px ${d}`, c.textAlign = "center", c.textBaseline = "middle", c.fillText(l, g / 2, C / 2);
178
- const r = uI(e, a);
179
- return { backgroundTex: B, obstacleTex: r, coverageTex: r };
180
- }
181
- function GC(e, g, C, i, s = 0, t = "cover", l = null, u = "cover") {
182
- const Z = new OffscreenCanvas(C, i), d = Z.getContext("2d"), { x: S, y: a, drawW: c, drawH: m } = II(g.width, g.height, C, i, t);
183
- if (d.clearRect(0, 0, C, i), d.fillStyle = "black", d.fillRect(0, 0, C, i), l) {
184
- const {
185
- x: n,
186
- y,
187
- drawW: v,
188
- drawH: Y
189
- } = II(l.width, l.height, C, i, u);
190
- d.filter = `brightness(${s}) blur(8px)`, d.drawImage(l, n, y, v, Y), d.filter = "none";
191
- }
192
- d.drawImage(g, S, a, c, m);
193
- const B = uI(e, Z);
194
- d.clearRect(0, 0, C, i), d.fillStyle = "black", d.fillRect(0, 0, C, i), d.filter = `brightness(${s}) blur(8px)`, d.drawImage(g, S, a, c, m), d.filter = "none";
195
- const r = uI(e, Z);
196
- d.clearRect(0, 0, C, i), d.fillStyle = "black", d.fillRect(0, 0, C, i), d.fillStyle = "white", d.fillRect(
197
- Math.max(0, S),
198
- Math.max(0, a),
199
- Math.min(c, C - Math.max(0, S)),
200
- Math.min(m, i - Math.max(0, a))
201
- );
202
- const w = uI(e, Z);
203
- return { backgroundTex: B, obstacleTex: r, coverageTex: w };
204
- }
205
- function uI(e, g) {
206
- const C = e.createTexture();
207
- return e.bindTexture(e.TEXTURE_2D, C), e.pixelStorei(e.UNPACK_FLIP_Y_WEBGL, !0), e.texImage2D(e.TEXTURE_2D, 0, e.RGBA, e.RGBA, e.UNSIGNED_BYTE, g), e.texParameteri(e.TEXTURE_2D, e.TEXTURE_MIN_FILTER, e.LINEAR), e.texParameteri(e.TEXTURE_2D, e.TEXTURE_MAG_FILTER, e.LINEAR), e.texParameteri(e.TEXTURE_2D, e.TEXTURE_WRAP_S, e.CLAMP_TO_EDGE), e.texParameteri(e.TEXTURE_2D, e.TEXTURE_WRAP_T, e.CLAMP_TO_EDGE), C;
208
- }
209
- function pC(e, g, C, i, s = null, t = "cover") {
210
- const { text: l, fontSize: u, color: Z, fontFamily: d = "sans-serif", fontWeight: S = 900 } = i, a = new OffscreenCanvas(g, C), c = a.getContext("2d");
211
- ((w) => {
212
- if (s) {
213
- c.clearRect(0, 0, g, C), c.fillStyle = "black", c.fillRect(0, 0, g, C);
214
- const { x: n, y, drawW: v, drawH: Y } = II(
215
- s.width,
216
- s.height,
217
- g,
218
- C,
219
- t
220
- );
221
- c.drawImage(s, n, y, v, Y);
222
- } else
223
- c.fillStyle = "black", c.fillRect(0, 0, g, C);
224
- c.fillStyle = w, c.font = `${S} ${u}px ${d}`, c.textAlign = "center", c.textBaseline = "middle", c.fillText(l, g / 2, C / 2);
225
- })(Z);
226
- const B = aI(e, a, g, C);
227
- c.fillStyle = "black", c.fillRect(0, 0, g, C), c.fillStyle = "white", c.font = `${S} ${u}px ${d}`, c.textAlign = "center", c.textBaseline = "middle", c.fillText(l, g / 2, C / 2);
228
- const r = aI(e, a, g, C);
229
- return {
230
- backgroundTex: B,
231
- backgroundView: B.createView(),
232
- obstacleTex: r,
233
- obstacleView: r.createView(),
234
- coverageTex: r,
235
- coverageView: r.createView(),
236
- sharedCoverage: !0
237
- };
238
- }
239
- function LC(e, g, C, i, s = 0, t = "cover", l = null, u = "cover") {
240
- const Z = new OffscreenCanvas(C, i), d = Z.getContext("2d"), { x: S, y: a, drawW: c, drawH: m } = II(g.width, g.height, C, i, t);
241
- if (d.clearRect(0, 0, C, i), d.fillStyle = "black", d.fillRect(0, 0, C, i), l) {
242
- const { x: n, y, drawW: v, drawH: Y } = II(
243
- l.width,
244
- l.height,
245
- C,
246
- i,
247
- u
248
- );
249
- d.filter = `brightness(${s}) blur(8px)`, d.drawImage(l, n, y, v, Y), d.filter = "none";
250
- }
251
- d.drawImage(g, S, a, c, m);
252
- const B = aI(e, Z, C, i);
253
- d.clearRect(0, 0, C, i), d.fillStyle = "black", d.fillRect(0, 0, C, i), d.filter = `brightness(${s}) blur(8px)`, d.drawImage(g, S, a, c, m), d.filter = "none";
254
- const r = aI(e, Z, C, i);
255
- d.clearRect(0, 0, C, i), d.fillStyle = "black", d.fillRect(0, 0, C, i), d.fillStyle = "white", d.fillRect(Math.max(0, S), Math.max(0, a), Math.min(c, C - Math.max(0, S)), Math.min(m, i - Math.max(0, a)));
256
- const w = aI(e, Z, C, i);
257
- return {
258
- backgroundTex: B,
259
- backgroundView: B.createView(),
260
- obstacleTex: r,
261
- obstacleView: r.createView(),
262
- coverageTex: w,
263
- coverageView: w.createView(),
264
- sharedCoverage: !1
265
- };
266
- }
267
- function aI(e, g, C, i) {
268
- const s = e.createTexture({
269
- size: [C, i],
270
- format: "rgba8unorm",
271
- usage: GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.COPY_DST | GPUTextureUsage.RENDER_ATTACHMENT
272
- });
273
- return e.queue.copyExternalImageToTexture(
274
- { source: g },
275
- { texture: s },
276
- [C, i]
277
- ), s;
278
- }
279
- async function NI(e) {
280
- const g = await fetch(e);
281
- if (!g.ok)
282
- throw new Error(`Failed to fetch image: ${e} (${g.status})`);
283
- const C = await g.blob();
284
- return createImageBitmap(C);
285
- }
286
- const yI = () => {
287
- }, Sg = `precision highp float;
288
- attribute vec2 aPosition;
289
- varying vec2 vUv;
290
- varying vec2 vL; varying vec2 vR; varying vec2 vT; varying vec2 vB;
291
- uniform vec2 texelSize;
292
- void main () {
293
- vUv = aPosition * 0.5 + 0.5;
294
- vL = vUv - vec2(texelSize.x, 0.0);
295
- vR = vUv + vec2(texelSize.x, 0.0);
296
- vT = vUv + vec2(0.0, texelSize.y);
297
- vB = vUv - vec2(0.0, texelSize.y);
298
- gl_Position = vec4(aPosition, 0.0, 1.0);
299
- }`, wC = `precision highp float;
300
- varying vec2 vUv;
301
- uniform sampler2D uVelocity;
302
- uniform sampler2D uSource;
303
- uniform sampler2D uObstacle;
304
- uniform vec2 texelSize;
305
- uniform float dt;
306
- uniform float dissipation;
307
- void main () {
308
- float obs = texture2D(uObstacle, vUv).r;
309
- vec2 coord = vUv - dt * texture2D(uVelocity, vUv).xy * texelSize;
310
- gl_FragColor = dissipation * texture2D(uSource, coord) * (1.0 - obs);
311
- }`, hC = `precision highp float;
312
- varying vec2 vL; varying vec2 vR; varying vec2 vT; varying vec2 vB;
313
- uniform sampler2D uVelocity;
314
- uniform sampler2D uObstacle;
315
- void main () {
316
- float L = texture2D(uVelocity, vL).x * (1.0 - texture2D(uObstacle, vL).r);
317
- float R = texture2D(uVelocity, vR).x * (1.0 - texture2D(uObstacle, vR).r);
318
- float T = texture2D(uVelocity, vT).y * (1.0 - texture2D(uObstacle, vT).r);
319
- float B = texture2D(uVelocity, vB).y * (1.0 - texture2D(uObstacle, vB).r);
320
- gl_FragColor = vec4(0.5 * (R - L + T - B), 0.0, 0.0, 1.0);
321
- }`, bC = `precision highp float;
322
- varying vec2 vUv; varying vec2 vL; varying vec2 vR; varying vec2 vT; varying vec2 vB;
323
- uniform sampler2D uPressure;
324
- uniform sampler2D uDivergence;
325
- uniform sampler2D uObstacle;
326
- void main () {
327
- float C = texture2D(uPressure, vUv).x;
328
- float L = mix(texture2D(uPressure, vL).x, C, texture2D(uObstacle, vL).r);
329
- float R = mix(texture2D(uPressure, vR).x, C, texture2D(uObstacle, vR).r);
330
- float T = mix(texture2D(uPressure, vT).x, C, texture2D(uObstacle, vT).r);
331
- float B = mix(texture2D(uPressure, vB).x, C, texture2D(uObstacle, vB).r);
332
- float div = texture2D(uDivergence, vUv).x;
333
- gl_FragColor = vec4((L + R + B + T - div) * 0.25, 0.0, 0.0, 1.0);
334
- }`, yC = `precision highp float;
335
- varying vec2 vUv; varying vec2 vL; varying vec2 vR; varying vec2 vT; varying vec2 vB;
336
- uniform sampler2D uPressure;
337
- uniform sampler2D uVelocity;
338
- uniform sampler2D uObstacle;
339
- void main () {
340
- float obs = texture2D(uObstacle, vUv).r;
341
- float C = texture2D(uPressure, vUv).x;
342
- float L = mix(texture2D(uPressure, vL).x, C, texture2D(uObstacle, vL).r);
343
- float R = mix(texture2D(uPressure, vR).x, C, texture2D(uObstacle, vR).r);
344
- float T = mix(texture2D(uPressure, vT).x, C, texture2D(uObstacle, vT).r);
345
- float B = mix(texture2D(uPressure, vB).x, C, texture2D(uObstacle, vB).r);
346
- vec2 vel = (texture2D(uVelocity, vUv).xy - vec2(R - L, T - B)) * (1.0 - obs);
347
- gl_FragColor = vec4(vel, 0.0, 1.0);
348
- }`, VC = `precision highp float;
349
- varying vec2 vUv;
350
- uniform sampler2D uTarget;
351
- uniform float aspectRatio;
352
- uniform vec3 color;
353
- uniform vec2 point;
354
- uniform float radius;
355
- void main () {
356
- vec2 p = vUv - point.xy;
357
- p.x *= aspectRatio;
358
- vec3 splat = exp(-dot(p, p) / radius) * color;
359
- gl_FragColor = vec4(texture2D(uTarget, vUv).xyz + splat, 1.0);
360
- }`, KC = `precision highp float;
361
- varying vec2 vL; varying vec2 vR; varying vec2 vT; varying vec2 vB;
362
- uniform sampler2D uVelocity;
363
- void main () {
364
- float L = texture2D(uVelocity, vL).y;
365
- float R = texture2D(uVelocity, vR).y;
366
- float T = texture2D(uVelocity, vT).x;
367
- float B = texture2D(uVelocity, vB).x;
368
- gl_FragColor = vec4(0.5 * (R - L - T + B), 0.0, 0.0, 1.0);
369
- }`, XC = `precision highp float;
370
- varying vec2 vUv; varying vec2 vL; varying vec2 vR; varying vec2 vT; varying vec2 vB;
371
- uniform sampler2D uVelocity;
372
- uniform sampler2D uCurl;
373
- uniform float curl;
374
- uniform float dt;
375
- void main () {
376
- float L = texture2D(uCurl, vL).x;
377
- float R = texture2D(uCurl, vR).x;
378
- float T = texture2D(uCurl, vT).x;
379
- float B = texture2D(uCurl, vB).x;
380
- float C = texture2D(uCurl, vUv).x;
381
- vec2 force = 0.5 * vec2(abs(T) - abs(B), abs(R) - abs(L));
382
- force /= length(force) + 0.0001;
383
- force *= curl * 30.0 * C;
384
- gl_FragColor = vec4(texture2D(uVelocity, vUv).xy + force * dt, 0.0, 1.0);
385
- }`, HC = `precision highp float;
386
- varying vec2 vUv;
387
- uniform sampler2D uTexture;
388
- uniform sampler2D uObstacle;
389
- uniform sampler2D uBackground;
390
- uniform sampler2D uCoverage;
391
- uniform sampler2D uVelocity;
392
- uniform vec2 texelSize;
393
- uniform vec3 uWaterColor;
394
- uniform vec3 uGlowColor;
395
- uniform float uRefraction;
396
- uniform float uSpecularExp;
397
- uniform float uShine;
398
- uniform float uWarpStrength;
399
- uniform int uAlgorithm;
400
- uniform int uEnableAlpha;
401
- void main () {
402
- float obs = texture2D(uObstacle, vUv).r;
403
- float density = max(texture2D(uTexture, vUv).r, 0.0) * (1.0 - obs);
404
- float coverage = texture2D(uCoverage, vUv).r;
405
- float sx = texelSize.x * 6.0, sy = texelSize.y * 6.0;
406
- float d00 = max(texture2D(uTexture, vUv + vec2(-sx, -sy)).r, 0.0);
407
- float d10 = max(texture2D(uTexture, vUv + vec2(0.0, -sy)).r, 0.0);
408
- float d20 = max(texture2D(uTexture, vUv + vec2( sx, -sy)).r, 0.0);
409
- float d01 = max(texture2D(uTexture, vUv + vec2(-sx, 0.0)).r, 0.0);
410
- float d21 = max(texture2D(uTexture, vUv + vec2( sx, 0.0)).r, 0.0);
411
- float d02 = max(texture2D(uTexture, vUv + vec2(-sx, sy)).r, 0.0);
412
- float d12 = max(texture2D(uTexture, vUv + vec2(0.0, sy)).r, 0.0);
413
- float d22 = max(texture2D(uTexture, vUv + vec2( sx, sy)).r, 0.0);
414
- float gx = (d20 + 2.0*d21 + d22) - (d00 + 2.0*d01 + d02);
415
- float gy = (d02 + 2.0*d12 + d22) - (d00 + 2.0*d10 + d20);
416
- vec3 normal = normalize(vec3(gx, gy, 1.2));
417
- vec3 lightDir = normalize(vec3(0.5, 1.0, 0.5));
418
- vec3 halfV = normalize(lightDir + vec3(0.0, 0.0, 1.0));
419
- float specDen = density * min(density * 5.0, 1.0);
420
- float spec = pow(max(dot(normal, halfV), 0.0), uSpecularExp) * uShine * specDen;
421
- vec3 bgRaw = texture2D(uBackground, vUv).rgb;
422
- vec3 bg = mix(uWaterColor, bgRaw, coverage);
423
- vec3 color = bg;
424
- if (uAlgorithm == 1) {
425
- vec2 refrUv = clamp(vUv + normal.xy * uRefraction * density * 3.0, 0.0, 1.0);
426
- vec3 refrBg = mix(uWaterColor, texture2D(uBackground, mix(vUv, refrUv, 1.0 - obs)).rgb, coverage);
427
- color = refrBg + spec * uGlowColor * 2.5;
428
- color = mix(color, bg * 0.6, obs * 0.3);
429
- } else if (uAlgorithm == 2) {
430
- float inkD = min(density * 4.0, 1.0);
431
- vec2 refrUv = clamp(vUv + normal.xy * uRefraction * density * 0.4, 0.0, 1.0);
432
- vec3 refrBg = mix(uWaterColor, texture2D(uBackground, mix(vUv, refrUv, 1.0 - obs)).rgb, coverage);
433
- color = mix(refrBg, uWaterColor + spec * uGlowColor, inkD);
434
- color = mix(color, bg * 0.5, obs * 0.15);
435
- } else if (uAlgorithm == 3) {
436
- vec2 vel = texture2D(uVelocity, vUv).xy;
437
- float velMag = clamp(length(vel) * 20.0, 0.0, 1.0);
438
- vec2 warpUv = clamp(vUv + vel * uWarpStrength, 0.0, 1.0);
439
- vec3 warpBg = mix(uWaterColor, texture2D(uBackground, warpUv).rgb, coverage);
440
- color = mix(bg, warpBg, velMag * (1.0 - obs));
441
- color += spec * uGlowColor * velMag * 1.5;
442
- color += uWaterColor * density * 0.3;
443
- color = mix(color, bg * 0.5, obs * 0.2);
444
- } else if (uAlgorithm == 4) {
445
- vec2 rippleUv = clamp(vUv + normal.xy * uRefraction * density * 6.0, 0.0, 1.0);
446
- vec3 refrBg = mix(uWaterColor, texture2D(uBackground, mix(vUv, rippleUv, 1.0 - obs)).rgb, coverage);
447
- float fresnel = pow(clamp(1.0 - dot(normal, vec3(0.0, 0.0, 1.0)), 0.0, 1.0), 3.0) * density;
448
- color = refrBg;
449
- color += fresnel * uGlowColor * 2.0;
450
- color += spec * uGlowColor * density * 2.0;
451
- color = mix(color, bg * 0.5, obs * 0.2);
452
- } else {
453
- vec2 refrUv = vUv + normal.xy * uRefraction * density;
454
- vec3 refrBg = mix(uWaterColor, texture2D(uBackground, mix(vUv, refrUv, 1.0 - obs)).rgb, coverage);
455
- color = mix(refrBg, uWaterColor, min(density * 1.5, 0.8));
456
- color += spec * uGlowColor;
457
- color = mix(color, bg * 0.5, obs * 0.2);
458
- }
459
- float alpha = clamp(max(density * 1.5, coverage), 0.0, 1.0);
460
- if (uEnableAlpha == 1) {
461
- gl_FragColor = vec4(color * alpha, alpha);
462
- } else {
463
- gl_FragColor = vec4(color, 1.0);
125
+ function m(e) {
126
+ if (Array.isArray(e)) return e;
127
+ let t = e.slice(1, 7);
128
+ return t.length === 3 ? [
129
+ parseInt(t[0] + t[0], 16) / 255,
130
+ parseInt(t[1] + t[1], 16) / 255,
131
+ parseInt(t[2] + t[2], 16) / 255
132
+ ] : [
133
+ parseInt(t.slice(0, 2), 16) / 255,
134
+ parseInt(t.slice(2, 4), 16) / 255,
135
+ parseInt(t.slice(4, 6), 16) / 255
136
+ ];
464
137
  }
465
- }`;
466
- function vC(e, g = !0) {
467
- const C = { alpha: g, depth: !1, stencil: !1, antialias: !0, preserveDrawingBuffer: !1 };
468
- let i = e.getContext("webgl2", C);
469
- const s = !!i;
470
- s || (i = e.getContext("webgl", C), i.getExtension("EXT_color_buffer_half_float"));
471
- const t = s ? null : i.getExtension("OES_texture_half_float"), l = s ? i.HALF_FLOAT : t.HALF_FLOAT_OES;
472
- return i.getExtension("EXT_color_buffer_float"), i.getExtension("OES_texture_half_float_linear"), {
473
- type: s ? "webgl2" : "webgl1",
474
- gl: i,
475
- isWebGL2: s,
476
- ext: {
477
- internalFormat: s ? i.RGBA16F : i.RGBA,
478
- format: i.RGBA,
479
- type: l
480
- }
481
- };
138
+ function h(e = {}, t, n = s) {
139
+ return {
140
+ ...t ? {
141
+ ...n,
142
+ ...p[t]
143
+ } : n,
144
+ ...e
145
+ };
482
146
  }
483
- async function WC(e, g = !0) {
484
- if (typeof navigator > "u" || !navigator.gpu)
485
- return null;
486
- try {
487
- const C = await navigator.gpu.requestAdapter();
488
- if (!C)
489
- return null;
490
- const i = await C.requestDevice(), s = e.getContext("webgpu");
491
- if (!s)
492
- return null;
493
- const t = navigator.gpu.getPreferredCanvasFormat();
494
- return s.configure({ device: i, format: t, alphaMode: g ? "premultiplied" : "opaque" }), { type: "webgpu", adapter: C, device: i, context: s, format: t };
495
- } catch {
496
- return null;
497
- }
147
+ //#endregion
148
+ //#region src/core/textures.ts
149
+ function g(e, t, n, r, i = "cover") {
150
+ let a;
151
+ a = i === "cover" ? Math.max(n / e, r / t) : i === "contain" ? Math.min(n / e, r / t) : typeof i == "string" && i.endsWith("%") ? Math.min(n / e, r / t) * (parseFloat(i) / 100) : typeof i == "string" && i.endsWith("px") ? parseFloat(i) / Math.max(e, t) : typeof i == "number" ? i : Math.max(n / e, r / t);
152
+ let o = e * a, s = t * a;
153
+ return {
154
+ x: (n - o) / 2,
155
+ y: (r - s) / 2,
156
+ drawW: o,
157
+ drawH: s
158
+ };
498
159
  }
499
- class Bg {
500
- constructor(g, C, i) {
501
- LI(this, "program");
502
- LI(this, "uniforms", {});
503
- LI(this, "_gl");
504
- this._gl = g, this.program = g.createProgram(), g.attachShader(this.program, this._compile(g.VERTEX_SHADER, C)), g.attachShader(this.program, this._compile(g.FRAGMENT_SHADER, i)), g.linkProgram(this.program);
505
- const s = g.getProgramParameter(this.program, g.ACTIVE_UNIFORMS);
506
- for (let t = 0; t < s; t++) {
507
- const l = g.getActiveUniform(this.program, t).name;
508
- this.uniforms[l] = g.getUniformLocation(this.program, l);
509
- }
510
- }
511
- _compile(g, C) {
512
- const i = this._gl, s = i.createShader(g);
513
- return i.shaderSource(s, C), i.compileShader(s), s;
514
- }
515
- bind() {
516
- this._gl.useProgram(this.program);
517
- }
518
- dispose() {
519
- this._gl.deleteProgram(this.program);
520
- }
160
+ function _(e, t, n, r, i = null, a = "cover") {
161
+ let { text: o, fontSize: s, color: c, fontFamily: l = "sans-serif", fontWeight: u = 900 } = r, d = new OffscreenCanvas(t, n), f = d.getContext("2d");
162
+ ((e) => {
163
+ if (i) {
164
+ f.clearRect(0, 0, t, n), f.fillStyle = "black", f.fillRect(0, 0, t, n);
165
+ let { x: e, y: r, drawW: o, drawH: s } = g(i.width, i.height, t, n, a);
166
+ f.drawImage(i, e, r, o, s);
167
+ } else f.fillStyle = "black", f.fillRect(0, 0, t, n);
168
+ f.fillStyle = e, f.font = `${u} ${s}px ${l}`, f.textAlign = "center", f.textBaseline = "middle", f.fillText(o, t / 2, n / 2);
169
+ })(c);
170
+ let p = y(e, d);
171
+ f.fillStyle = "black", f.fillRect(0, 0, t, n), f.fillStyle = "white", f.font = `${u} ${s}px ${l}`, f.textAlign = "center", f.textBaseline = "middle", f.fillText(o, t / 2, n / 2);
172
+ let m = y(e, d);
173
+ return {
174
+ backgroundTex: p,
175
+ obstacleTex: m,
176
+ coverageTex: m
177
+ };
521
178
  }
522
- function RC(e) {
523
- return {
524
- advection: new Bg(e, Sg, wC),
525
- divergence: new Bg(e, Sg, hC),
526
- pressure: new Bg(e, Sg, bC),
527
- gradientSubtract: new Bg(e, Sg, yC),
528
- splat: new Bg(e, Sg, VC),
529
- curl: new Bg(e, Sg, KC),
530
- vorticity: new Bg(e, Sg, XC),
531
- display: new Bg(e, Sg, HC)
532
- };
179
+ function v(e, t, n, r, i = 0, a = "cover", o = null, s = "cover") {
180
+ let c = new OffscreenCanvas(n, r), l = c.getContext("2d"), { x: u, y: d, drawW: f, drawH: p } = g(t.width, t.height, n, r, a);
181
+ if (l.clearRect(0, 0, n, r), l.fillStyle = "black", l.fillRect(0, 0, n, r), o) {
182
+ let { x: e, y: t, drawW: a, drawH: c } = g(o.width, o.height, n, r, s);
183
+ l.filter = `brightness(${i}) blur(8px)`, l.drawImage(o, e, t, a, c), l.filter = "none";
184
+ }
185
+ l.drawImage(t, u, d, f, p);
186
+ let m = y(e, c);
187
+ l.clearRect(0, 0, n, r), l.fillStyle = "black", l.fillRect(0, 0, n, r), l.filter = `brightness(${i}) blur(8px)`, l.drawImage(t, u, d, f, p), l.filter = "none";
188
+ let h = y(e, c);
189
+ return l.clearRect(0, 0, n, r), l.fillStyle = "black", l.fillRect(0, 0, n, r), l.fillStyle = "white", l.fillRect(Math.max(0, u), Math.max(0, d), Math.min(f, n - Math.max(0, u)), Math.min(p, r - Math.max(0, d))), {
190
+ backgroundTex: m,
191
+ obstacleTex: h,
192
+ coverageTex: y(e, c)
193
+ };
533
194
  }
534
- function VI(e, g, C, i) {
535
- e.activeTexture(e.TEXTURE0);
536
- const s = e.createTexture();
537
- e.bindTexture(e.TEXTURE_2D, s), e.texParameteri(e.TEXTURE_2D, e.TEXTURE_MIN_FILTER, e.LINEAR), e.texParameteri(e.TEXTURE_2D, e.TEXTURE_MAG_FILTER, e.LINEAR), e.texParameteri(e.TEXTURE_2D, e.TEXTURE_WRAP_S, e.CLAMP_TO_EDGE), e.texParameteri(e.TEXTURE_2D, e.TEXTURE_WRAP_T, e.CLAMP_TO_EDGE), e.texImage2D(e.TEXTURE_2D, 0, g.internalFormat, C, i, 0, g.format, g.type, null);
538
- const t = e.createFramebuffer();
539
- return e.bindFramebuffer(e.FRAMEBUFFER, t), e.framebufferTexture2D(e.FRAMEBUFFER, e.COLOR_ATTACHMENT0, e.TEXTURE_2D, s, 0), { tex: s, fbo: t, width: C, height: i };
195
+ function y(e, t) {
196
+ let n = e.createTexture();
197
+ return e.bindTexture(e.TEXTURE_2D, n), e.pixelStorei(e.UNPACK_FLIP_Y_WEBGL, !0), e.texImage2D(e.TEXTURE_2D, 0, e.RGBA, e.RGBA, e.UNSIGNED_BYTE, t), e.texParameteri(e.TEXTURE_2D, e.TEXTURE_MIN_FILTER, e.LINEAR), e.texParameteri(e.TEXTURE_2D, e.TEXTURE_MAG_FILTER, e.LINEAR), e.texParameteri(e.TEXTURE_2D, e.TEXTURE_WRAP_S, e.CLAMP_TO_EDGE), e.texParameteri(e.TEXTURE_2D, e.TEXTURE_WRAP_T, e.CLAMP_TO_EDGE), n;
540
198
  }
541
- function FI(e, g, C, i) {
542
- let s = VI(e, g, C, i), t = VI(e, g, C, i);
543
- return {
544
- get read() {
545
- return s;
546
- },
547
- get write() {
548
- return t;
549
- },
550
- swap() {
551
- [s, t] = [t, s];
552
- },
553
- dispose() {
554
- e.deleteTexture(s.tex), e.deleteFramebuffer(s.fbo), e.deleteTexture(t.tex), e.deleteFramebuffer(t.fbo);
555
- }
556
- };
199
+ function b(e, t, n, r, i = null, a = "cover") {
200
+ let { text: o, fontSize: s, color: c, fontFamily: l = "sans-serif", fontWeight: u = 900 } = r, d = new OffscreenCanvas(t, n), f = d.getContext("2d");
201
+ ((e) => {
202
+ if (i) {
203
+ f.clearRect(0, 0, t, n), f.fillStyle = "black", f.fillRect(0, 0, t, n);
204
+ let { x: e, y: r, drawW: o, drawH: s } = g(i.width, i.height, t, n, a);
205
+ f.drawImage(i, e, r, o, s);
206
+ } else f.fillStyle = "black", f.fillRect(0, 0, t, n);
207
+ f.fillStyle = e, f.font = `${u} ${s}px ${l}`, f.textAlign = "center", f.textBaseline = "middle", f.fillText(o, t / 2, n / 2);
208
+ })(c);
209
+ let p = S(e, d, t, n);
210
+ f.fillStyle = "black", f.fillRect(0, 0, t, n), f.fillStyle = "white", f.font = `${u} ${s}px ${l}`, f.textAlign = "center", f.textBaseline = "middle", f.fillText(o, t / 2, n / 2);
211
+ let m = S(e, d, t, n);
212
+ return {
213
+ backgroundTex: p,
214
+ backgroundView: p.createView(),
215
+ obstacleTex: m,
216
+ obstacleView: m.createView(),
217
+ coverageTex: m,
218
+ coverageView: m.createView(),
219
+ sharedCoverage: !0
220
+ };
557
221
  }
558
- function UC(e) {
559
- const g = e.createBuffer();
560
- return e.bindBuffer(e.ARRAY_BUFFER, g), e.bufferData(e.ARRAY_BUFFER, new Float32Array([-1, -1, -1, 1, 1, 1, 1, -1]), e.STATIC_DRAW), e.vertexAttribPointer(0, 2, e.FLOAT, !1, 0, 0), e.enableVertexAttribArray(0), function(i) {
561
- e.bindFramebuffer(e.FRAMEBUFFER, i), e.drawArrays(e.TRIANGLE_FAN, 0, 4);
562
- };
222
+ function x(e, t, n, r, i = 0, a = "cover", o = null, s = "cover") {
223
+ let c = new OffscreenCanvas(n, r), l = c.getContext("2d"), { x: u, y: d, drawW: f, drawH: p } = g(t.width, t.height, n, r, a);
224
+ if (l.clearRect(0, 0, n, r), l.fillStyle = "black", l.fillRect(0, 0, n, r), o) {
225
+ let { x: e, y: t, drawW: a, drawH: c } = g(o.width, o.height, n, r, s);
226
+ l.filter = `brightness(${i}) blur(8px)`, l.drawImage(o, e, t, a, c), l.filter = "none";
227
+ }
228
+ l.drawImage(t, u, d, f, p);
229
+ let m = S(e, c, n, r);
230
+ l.clearRect(0, 0, n, r), l.fillStyle = "black", l.fillRect(0, 0, n, r), l.filter = `brightness(${i}) blur(8px)`, l.drawImage(t, u, d, f, p), l.filter = "none";
231
+ let h = S(e, c, n, r);
232
+ l.clearRect(0, 0, n, r), l.fillStyle = "black", l.fillRect(0, 0, n, r), l.fillStyle = "white", l.fillRect(Math.max(0, u), Math.max(0, d), Math.min(f, n - Math.max(0, u)), Math.min(p, r - Math.max(0, d)));
233
+ let _ = S(e, c, n, r);
234
+ return {
235
+ backgroundTex: m,
236
+ backgroundView: m.createView(),
237
+ obstacleTex: h,
238
+ obstacleView: h.createView(),
239
+ coverageTex: _,
240
+ coverageView: _.createView(),
241
+ sharedCoverage: !1
242
+ };
563
243
  }
564
- const yg = `struct VSOut {
565
- @builtin(position) pos : vec4f,
566
- @location(0) uv : vec2f,
567
- @location(1) vL : vec2f,
568
- @location(2) vR : vec2f,
569
- @location(3) vT : vec2f,
570
- @location(4) vB : vec2f,
571
- }`, YC = `${yg}
572
- struct U {
573
- texelSize : vec2f,
574
- dt : f32,
575
- dissipation: f32,
244
+ function S(e, t, n, r) {
245
+ let i = e.createTexture({
246
+ size: [n, r],
247
+ format: "rgba8unorm",
248
+ usage: GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.COPY_DST | GPUTextureUsage.RENDER_ATTACHMENT
249
+ });
250
+ return e.queue.copyExternalImageToTexture({ source: t }, { texture: i }, [n, r]), i;
576
251
  }
577
- @group(0) @binding(0) var<uniform> u : U;
578
- @group(0) @binding(1) var samp : sampler;
579
- @group(0) @binding(2) var uVel : texture_2d<f32>;
580
- @group(0) @binding(3) var uSrc : texture_2d<f32>;
581
- @group(0) @binding(4) var uObs : texture_2d<f32>;
582
- @vertex fn vs(@location(0) a: vec2f) -> VSOut {
583
- var o: VSOut;
584
- o.uv = vec2f(a.x * 0.5 + 0.5, 0.5 - a.y * 0.5);
585
- o.vL = o.uv - vec2f(u.texelSize.x, 0.0);
586
- o.vR = o.uv + vec2f(u.texelSize.x, 0.0);
587
- o.vT = o.uv + vec2f(0.0, u.texelSize.y);
588
- o.vB = o.uv - vec2f(0.0, u.texelSize.y);
589
- o.pos = vec4f(a, 0.0, 1.0);
590
- return o;
252
+ async function C(e) {
253
+ let t = await fetch(e);
254
+ if (!t.ok) throw Error(`Failed to fetch image: ${e} (${t.status})`);
255
+ let n = await t.blob();
256
+ return createImageBitmap(n);
591
257
  }
592
- @fragment fn fs(i: VSOut) -> @location(0) vec4f {
593
- let obs = textureSample(uObs, samp, i.uv).r;
594
- let vel = textureSample(uVel, samp, i.uv).xy;
595
- let coord = i.uv - u.dt * vel * u.texelSize;
596
- let src = textureSample(uSrc, samp, coord);
597
- return u.dissipation * src * (1.0 - obs);
598
- }`, kC = `${yg}
599
- struct U { texelSize: vec2f, _pad: vec2f }
600
- @group(0) @binding(0) var<uniform> u : U;
601
- @group(0) @binding(1) var samp : sampler;
602
- @group(0) @binding(2) var uVel : texture_2d<f32>;
603
- @group(0) @binding(3) var uObs : texture_2d<f32>;
604
- @vertex fn vs(@location(0) a: vec2f) -> VSOut {
605
- var o: VSOut;
606
- o.uv = vec2f(a.x * 0.5 + 0.5, 0.5 - a.y * 0.5);
607
- o.vL = o.uv - vec2f(u.texelSize.x, 0.0);
608
- o.vR = o.uv + vec2f(u.texelSize.x, 0.0);
609
- o.vT = o.uv + vec2f(0.0, u.texelSize.y);
610
- o.vB = o.uv - vec2f(0.0, u.texelSize.y);
611
- o.pos = vec4f(a, 0.0, 1.0);
612
- return o;
258
+ //#endregion
259
+ //#region src/utils/index.ts
260
+ var w = "precision highp float;\n attribute vec2 aPosition;\n varying vec2 vUv;\n varying vec2 vL; varying vec2 vR; varying vec2 vT; varying vec2 vB;\n uniform vec2 texelSize;\n void main () {\n vUv = aPosition * 0.5 + 0.5;\n vL = vUv - vec2(texelSize.x, 0.0);\n vR = vUv + vec2(texelSize.x, 0.0);\n vT = vUv + vec2(0.0, texelSize.y);\n vB = vUv - vec2(0.0, texelSize.y);\n gl_Position = vec4(aPosition, 0.0, 1.0);\n }", T = "precision highp float;\n varying vec2 vUv;\n uniform sampler2D uVelocity;\n uniform sampler2D uSource;\n uniform sampler2D uObstacle;\n uniform vec2 texelSize;\n uniform float dt;\n uniform float dissipation;\n void main () {\n float obs = texture2D(uObstacle, vUv).r;\n vec2 coord = vUv - dt * texture2D(uVelocity, vUv).xy * texelSize;\n \n \n \n gl_FragColor = dissipation * texture2D(uSource, coord) * (1.0 - obs);\n }", E = "precision highp float;\n varying vec2 vL; varying vec2 vR; varying vec2 vT; varying vec2 vB;\n uniform sampler2D uVelocity;\n uniform sampler2D uObstacle;\n void main () {\n float L = texture2D(uVelocity, vL).x * (1.0 - texture2D(uObstacle, vL).r);\n float R = texture2D(uVelocity, vR).x * (1.0 - texture2D(uObstacle, vR).r);\n float T = texture2D(uVelocity, vT).y * (1.0 - texture2D(uObstacle, vT).r);\n float B = texture2D(uVelocity, vB).y * (1.0 - texture2D(uObstacle, vB).r);\n gl_FragColor = vec4(0.5 * (R - L + T - B), 0.0, 0.0, 1.0);\n }", D = "precision highp float;\n varying vec2 vUv; varying vec2 vL; varying vec2 vR; varying vec2 vT; varying vec2 vB;\n uniform sampler2D uPressure;\n uniform sampler2D uDivergence;\n uniform sampler2D uObstacle;\n void main () {\n float C = texture2D(uPressure, vUv).x;\n float L = mix(texture2D(uPressure, vL).x, C, texture2D(uObstacle, vL).r);\n float R = mix(texture2D(uPressure, vR).x, C, texture2D(uObstacle, vR).r);\n float T = mix(texture2D(uPressure, vT).x, C, texture2D(uObstacle, vT).r);\n float B = mix(texture2D(uPressure, vB).x, C, texture2D(uObstacle, vB).r);\n float div = texture2D(uDivergence, vUv).x;\n gl_FragColor = vec4((L + R + B + T - div) * 0.25, 0.0, 0.0, 1.0);\n }", O = "precision highp float;\n varying vec2 vUv; varying vec2 vL; varying vec2 vR; varying vec2 vT; varying vec2 vB;\n uniform sampler2D uPressure;\n uniform sampler2D uVelocity;\n uniform sampler2D uObstacle;\n void main () {\n float obs = texture2D(uObstacle, vUv).r;\n float C = texture2D(uPressure, vUv).x;\n float L = mix(texture2D(uPressure, vL).x, C, texture2D(uObstacle, vL).r);\n float R = mix(texture2D(uPressure, vR).x, C, texture2D(uObstacle, vR).r);\n float T = mix(texture2D(uPressure, vT).x, C, texture2D(uObstacle, vT).r);\n float B = mix(texture2D(uPressure, vB).x, C, texture2D(uObstacle, vB).r);\n vec2 vel = (texture2D(uVelocity, vUv).xy - vec2(R - L, T - B)) * (1.0 - obs);\n gl_FragColor = vec4(vel, 0.0, 1.0);\n }", k = "precision highp float;\n varying vec2 vUv;\n uniform sampler2D uTarget;\n uniform float aspectRatio;\n uniform vec3 color;\n uniform vec2 point;\n uniform float radius;\n void main () {\n vec2 p = vUv - point.xy;\n p.x *= aspectRatio;\n vec3 splat = exp(-dot(p, p) / radius) * color;\n gl_FragColor = vec4(texture2D(uTarget, vUv).xyz + splat, 1.0);\n }", A = "precision highp float;\n varying vec2 vL; varying vec2 vR; varying vec2 vT; varying vec2 vB;\n uniform sampler2D uVelocity;\n void main () {\n float L = texture2D(uVelocity, vL).y;\n float R = texture2D(uVelocity, vR).y;\n float T = texture2D(uVelocity, vT).x;\n float B = texture2D(uVelocity, vB).x;\n gl_FragColor = vec4(0.5 * (R - L - T + B), 0.0, 0.0, 1.0);\n }", j = "precision highp float;\n varying vec2 vUv; varying vec2 vL; varying vec2 vR; varying vec2 vT; varying vec2 vB;\n uniform sampler2D uVelocity;\n uniform sampler2D uCurl;\n uniform float curl;\n uniform float dt;\n void main () {\n float L = texture2D(uCurl, vL).x;\n float R = texture2D(uCurl, vR).x;\n float T = texture2D(uCurl, vT).x;\n float B = texture2D(uCurl, vB).x;\n float C = texture2D(uCurl, vUv).x;\n vec2 force = 0.5 * vec2(abs(T) - abs(B), abs(R) - abs(L));\n force /= length(force) + 0.0001;\n force *= curl * 30.0 * C;\n gl_FragColor = vec4(texture2D(uVelocity, vUv).xy + force * dt, 0.0, 1.0);\n }", M = "precision highp float;\n varying vec2 vUv;\n uniform sampler2D uTexture;\n uniform sampler2D uObstacle;\n uniform sampler2D uBackground;\n uniform sampler2D uCoverage;\n uniform sampler2D uVelocity;\n uniform vec2 texelSize;\n uniform vec3 uWaterColor;\n uniform vec3 uGlowColor;\n uniform float uRefraction;\n uniform float uSpecularExp;\n uniform float uShine;\n uniform float uWarpStrength;\n uniform int uAlgorithm;\n uniform int uEnableAlpha;\n void main () {\n float obs = texture2D(uObstacle, vUv).r;\n \n \n float density = max(texture2D(uTexture, vUv).r, 0.0) * (1.0 - obs);\n float coverage = texture2D(uCoverage, vUv).r;\n \n \n \n \n float sx = texelSize.x * 6.0, sy = texelSize.y * 6.0;\n float d00 = max(texture2D(uTexture, vUv + vec2(-sx, -sy)).r, 0.0);\n float d10 = max(texture2D(uTexture, vUv + vec2(0.0, -sy)).r, 0.0);\n float d20 = max(texture2D(uTexture, vUv + vec2( sx, -sy)).r, 0.0);\n float d01 = max(texture2D(uTexture, vUv + vec2(-sx, 0.0)).r, 0.0);\n float d21 = max(texture2D(uTexture, vUv + vec2( sx, 0.0)).r, 0.0);\n float d02 = max(texture2D(uTexture, vUv + vec2(-sx, sy)).r, 0.0);\n float d12 = max(texture2D(uTexture, vUv + vec2(0.0, sy)).r, 0.0);\n float d22 = max(texture2D(uTexture, vUv + vec2( sx, sy)).r, 0.0);\n float gx = (d20 + 2.0*d21 + d22) - (d00 + 2.0*d01 + d02);\n float gy = (d02 + 2.0*d12 + d22) - (d00 + 2.0*d10 + d20);\n vec3 normal = normalize(vec3(gx, gy, 1.2));\n vec3 lightDir = normalize(vec3(0.5, 1.0, 0.5));\n vec3 halfV = normalize(lightDir + vec3(0.0, 0.0, 1.0));\n \n \n float specDen = density * min(density * 5.0, 1.0);\n float spec = pow(max(dot(normal, halfV), 0.0), uSpecularExp) * uShine * specDen;\n \n \n \n vec3 bgRaw = texture2D(uBackground, vUv).rgb;\n vec3 bg = mix(uWaterColor, bgRaw, coverage);\n vec3 color = bg;\n if (uAlgorithm == 1) {\n \n \n vec2 refrUv = clamp(vUv + normal.xy * uRefraction * density * 3.0, 0.0, 1.0);\n vec3 refrBg = mix(uWaterColor, texture2D(uBackground, mix(vUv, refrUv, 1.0 - obs)).rgb, coverage);\n color = refrBg + spec * uGlowColor * 2.5;\n color = mix(color, bg * 0.6, obs * 0.3);\n } else if (uAlgorithm == 2) {\n \n \n float inkD = min(density * 4.0, 1.0);\n vec2 refrUv = clamp(vUv + normal.xy * uRefraction * density * 0.4, 0.0, 1.0);\n vec3 refrBg = mix(uWaterColor, texture2D(uBackground, mix(vUv, refrUv, 1.0 - obs)).rgb, coverage);\n color = mix(refrBg, uWaterColor + spec * uGlowColor, inkD);\n color = mix(color, bg * 0.5, obs * 0.15);\n } else if (uAlgorithm == 3) {\n \n \n vec2 vel = texture2D(uVelocity, vUv).xy;\n float velMag = clamp(length(vel) * 20.0, 0.0, 1.0);\n vec2 warpUv = clamp(vUv + vel * uWarpStrength, 0.0, 1.0);\n vec3 warpBg = mix(uWaterColor, texture2D(uBackground, warpUv).rgb, coverage);\n color = mix(bg, warpBg, velMag * (1.0 - obs));\n color += spec * uGlowColor * velMag * 1.5;\n color += uWaterColor * density * 0.3;\n color = mix(color, bg * 0.5, obs * 0.2);\n } else if (uAlgorithm == 4) {\n \n \n vec2 rippleUv = clamp(vUv + normal.xy * uRefraction * density * 6.0, 0.0, 1.0);\n vec3 refrBg = mix(uWaterColor, texture2D(uBackground, mix(vUv, rippleUv, 1.0 - obs)).rgb, coverage);\n float fresnel = pow(clamp(1.0 - dot(normal, vec3(0.0, 0.0, 1.0)), 0.0, 1.0), 3.0) * density;\n color = refrBg;\n color += fresnel * uGlowColor * 2.0;\n color += spec * uGlowColor * density * 2.0;\n color = mix(color, bg * 0.5, obs * 0.2);\n } else {\n \n \n vec2 refrUv = vUv + normal.xy * uRefraction * density;\n vec3 refrBg = mix(uWaterColor, texture2D(uBackground, mix(vUv, refrUv, 1.0 - obs)).rgb, coverage);\n color = mix(refrBg, uWaterColor, min(density * 1.5, 0.8));\n color += spec * uGlowColor;\n color = mix(color, bg * 0.5, obs * 0.2);\n }\n \n \n float alpha = clamp(max(density * 1.5, coverage), 0.0, 1.0);\n if (uEnableAlpha == 1) {\n gl_FragColor = vec4(color * alpha, alpha);\n } else {\n gl_FragColor = vec4(color, 1.0);\n }\n }";
261
+ //#endregion
262
+ //#region src/core/gl-utils.ts
263
+ function N(e, t = !0) {
264
+ let n = {
265
+ alpha: t,
266
+ depth: !1,
267
+ stencil: !1,
268
+ antialias: !0,
269
+ preserveDrawingBuffer: !1
270
+ }, r = e.getContext("webgl2", n), i = !!r;
271
+ i || (r = e.getContext("webgl", n), r.getExtension("EXT_color_buffer_half_float"));
272
+ let a = i ? null : r.getExtension("OES_texture_half_float"), o = i ? r.HALF_FLOAT : a.HALF_FLOAT_OES;
273
+ return r.getExtension("EXT_color_buffer_float"), r.getExtension("OES_texture_half_float_linear"), {
274
+ type: i ? "webgl2" : "webgl1",
275
+ gl: r,
276
+ isWebGL2: i,
277
+ ext: {
278
+ internalFormat: i ? r.RGBA16F : r.RGBA,
279
+ format: r.RGBA,
280
+ type: o
281
+ }
282
+ };
613
283
  }
614
- @fragment fn fs(i: VSOut) -> @location(0) vec4f {
615
- let L = textureSample(uVel, samp, i.vL).x * (1.0 - textureSample(uObs, samp, i.vL).r);
616
- let R = textureSample(uVel, samp, i.vR).x * (1.0 - textureSample(uObs, samp, i.vR).r);
617
- let T = textureSample(uVel, samp, i.vT).y * (1.0 - textureSample(uObs, samp, i.vT).r);
618
- let B = textureSample(uVel, samp, i.vB).y * (1.0 - textureSample(uObs, samp, i.vB).r);
619
- return vec4f(0.5 * (R - L + T - B), 0.0, 0.0, 1.0);
620
- }`, MC = `${yg}
621
- struct U { texelSize: vec2f, _pad: vec2f }
622
- @group(0) @binding(0) var<uniform> u : U;
623
- @group(0) @binding(1) var samp : sampler;
624
- @group(0) @binding(2) var uPres: texture_2d<f32>;
625
- @group(0) @binding(3) var uDiv : texture_2d<f32>;
626
- @group(0) @binding(4) var uObs : texture_2d<f32>;
627
- @vertex fn vs(@location(0) a: vec2f) -> VSOut {
628
- var o: VSOut;
629
- o.uv = vec2f(a.x * 0.5 + 0.5, 0.5 - a.y * 0.5);
630
- o.vL = o.uv - vec2f(u.texelSize.x, 0.0);
631
- o.vR = o.uv + vec2f(u.texelSize.x, 0.0);
632
- o.vT = o.uv + vec2f(0.0, u.texelSize.y);
633
- o.vB = o.uv - vec2f(0.0, u.texelSize.y);
634
- o.pos = vec4f(a, 0.0, 1.0);
635
- return o;
284
+ async function P(e, t = !0) {
285
+ if (typeof navigator > "u" || !navigator.gpu) return null;
286
+ try {
287
+ let n = await navigator.gpu.requestAdapter();
288
+ if (!n) return null;
289
+ let r = await n.requestDevice(), i = e.getContext("webgpu");
290
+ if (!i) return null;
291
+ let a = navigator.gpu.getPreferredCanvasFormat();
292
+ return i.configure({
293
+ device: r,
294
+ format: a,
295
+ alphaMode: t ? "premultiplied" : "opaque"
296
+ }), {
297
+ type: "webgpu",
298
+ adapter: n,
299
+ device: r,
300
+ context: i,
301
+ format: a
302
+ };
303
+ } catch {
304
+ return null;
305
+ }
636
306
  }
637
- @fragment fn fs(i: VSOut) -> @location(0) vec4f {
638
- let C = textureSample(uPres, samp, i.uv).x;
639
- let L = mix(textureSample(uPres, samp, i.vL).x, C, textureSample(uObs, samp, i.vL).r);
640
- let R = mix(textureSample(uPres, samp, i.vR).x, C, textureSample(uObs, samp, i.vR).r);
641
- let T = mix(textureSample(uPres, samp, i.vT).x, C, textureSample(uObs, samp, i.vT).r);
642
- let B = mix(textureSample(uPres, samp, i.vB).x, C, textureSample(uObs, samp, i.vB).r);
643
- let dv = textureSample(uDiv, samp, i.uv).x;
644
- return vec4f((L + R + B + T - dv) * 0.25, 0.0, 0.0, 1.0);
645
- }`, xC = `${yg}
646
- struct U { texelSize: vec2f, _pad: vec2f }
647
- @group(0) @binding(0) var<uniform> u : U;
648
- @group(0) @binding(1) var samp : sampler;
649
- @group(0) @binding(2) var uPres: texture_2d<f32>;
650
- @group(0) @binding(3) var uVel : texture_2d<f32>;
651
- @group(0) @binding(4) var uObs : texture_2d<f32>;
652
- @vertex fn vs(@location(0) a: vec2f) -> VSOut {
653
- var o: VSOut;
654
- o.uv = vec2f(a.x * 0.5 + 0.5, 0.5 - a.y * 0.5);
655
- o.vL = o.uv - vec2f(u.texelSize.x, 0.0);
656
- o.vR = o.uv + vec2f(u.texelSize.x, 0.0);
657
- o.vT = o.uv + vec2f(0.0, u.texelSize.y);
658
- o.vB = o.uv - vec2f(0.0, u.texelSize.y);
659
- o.pos = vec4f(a, 0.0, 1.0);
660
- return o;
661
- }
662
- @fragment fn fs(i: VSOut) -> @location(0) vec4f {
663
- let obs = textureSample(uObs, samp, i.uv).r;
664
- let C = textureSample(uPres, samp, i.uv).x;
665
- let L = mix(textureSample(uPres, samp, i.vL).x, C, textureSample(uObs, samp, i.vL).r);
666
- let R = mix(textureSample(uPres, samp, i.vR).x, C, textureSample(uObs, samp, i.vR).r);
667
- let T = mix(textureSample(uPres, samp, i.vT).x, C, textureSample(uObs, samp, i.vT).r);
668
- let B = mix(textureSample(uPres, samp, i.vB).x, C, textureSample(uObs, samp, i.vB).r);
669
- let vel = (textureSample(uVel, samp, i.uv).xy - vec2f(R - L, T - B)) * (1.0 - obs);
670
- return vec4f(vel, 0.0, 1.0);
671
- }`, fC = `${yg}
672
- struct U {
673
- texelSize : vec2f,
674
- aspectRatio: f32,
675
- radius : f32,
676
- color : vec4f,
677
- point : vec2f,
678
- _pad : vec2f,
679
- }
680
- @group(0) @binding(0) var<uniform> u : U;
681
- @group(0) @binding(1) var samp : sampler;
682
- @group(0) @binding(2) var uTgt : texture_2d<f32>;
683
- @vertex fn vs(@location(0) a: vec2f) -> VSOut {
684
- var o: VSOut;
685
- o.uv = vec2f(a.x * 0.5 + 0.5, 0.5 - a.y * 0.5);
686
- o.vL = o.uv - vec2f(u.texelSize.x, 0.0);
687
- o.vR = o.uv + vec2f(u.texelSize.x, 0.0);
688
- o.vT = o.uv + vec2f(0.0, u.texelSize.y);
689
- o.vB = o.uv - vec2f(0.0, u.texelSize.y);
690
- o.pos = vec4f(a, 0.0, 1.0);
691
- return o;
692
- }
693
- @fragment fn fs(i: VSOut) -> @location(0) vec4f {
694
- var p = i.uv - u.point;
695
- p.x *= u.aspectRatio;
696
- let sp = exp(-dot(p, p) / u.radius) * u.color.xyz;
697
- return vec4f(textureSample(uTgt, samp, i.uv).xyz + sp, 1.0);
698
- }`, FC = `${yg}
699
- struct U { texelSize: vec2f, _pad: vec2f }
700
- @group(0) @binding(0) var<uniform> u : U;
701
- @group(0) @binding(1) var samp : sampler;
702
- @group(0) @binding(2) var uVel : texture_2d<f32>;
703
- @vertex fn vs(@location(0) a: vec2f) -> VSOut {
704
- var o: VSOut;
705
- o.uv = vec2f(a.x * 0.5 + 0.5, 0.5 - a.y * 0.5);
706
- o.vL = o.uv - vec2f(u.texelSize.x, 0.0);
707
- o.vR = o.uv + vec2f(u.texelSize.x, 0.0);
708
- o.vT = o.uv + vec2f(0.0, u.texelSize.y);
709
- o.vB = o.uv - vec2f(0.0, u.texelSize.y);
710
- o.pos = vec4f(a, 0.0, 1.0);
711
- return o;
712
- }
713
- @fragment fn fs(i: VSOut) -> @location(0) vec4f {
714
- let L = textureSample(uVel, samp, i.vL).y;
715
- let R = textureSample(uVel, samp, i.vR).y;
716
- let T = textureSample(uVel, samp, i.vT).x;
717
- let B = textureSample(uVel, samp, i.vB).x;
718
- return vec4f(0.5 * (R - L - T + B), 0.0, 0.0, 1.0);
719
- }`, DC = `${yg}
720
- struct U {
721
- texelSize: vec2f,
722
- curl : f32,
723
- dt : f32,
724
- }
725
- @group(0) @binding(0) var<uniform> u : U;
726
- @group(0) @binding(1) var samp : sampler;
727
- @group(0) @binding(2) var uVel : texture_2d<f32>;
728
- @group(0) @binding(3) var uCrl : texture_2d<f32>;
729
- @vertex fn vs(@location(0) a: vec2f) -> VSOut {
730
- var o: VSOut;
731
- o.uv = vec2f(a.x * 0.5 + 0.5, 0.5 - a.y * 0.5);
732
- o.vL = o.uv - vec2f(u.texelSize.x, 0.0);
733
- o.vR = o.uv + vec2f(u.texelSize.x, 0.0);
734
- o.vT = o.uv + vec2f(0.0, u.texelSize.y);
735
- o.vB = o.uv - vec2f(0.0, u.texelSize.y);
736
- o.pos = vec4f(a, 0.0, 1.0);
737
- return o;
738
- }
739
- @fragment fn fs(i: VSOut) -> @location(0) vec4f {
740
- let L = textureSample(uCrl, samp, i.vL).x;
741
- let R = textureSample(uCrl, samp, i.vR).x;
742
- let T = textureSample(uCrl, samp, i.vT).x;
743
- let B = textureSample(uCrl, samp, i.vB).x;
744
- let C = textureSample(uCrl, samp, i.uv).x;
745
- var force = 0.5 * vec2f(abs(T) - abs(B), abs(R) - abs(L));
746
- force /= length(force) + 0.0001;
747
- force *= u.curl * 30.0 * C;
748
- let vel = textureSample(uVel, samp, i.uv).xy + force * u.dt;
749
- return vec4f(vel, 0.0, 1.0);
750
- }`, TC = `${yg}
751
- struct U {
752
- texelSize : vec2f,
753
- refraction : f32,
754
- specularExp : f32,
755
- waterColor : vec4f,
756
- glowColor : vec4f,
757
- shine : f32,
758
- warpStrength: f32,
759
- algorithm : i32,
760
- enableAlpha : i32,
307
+ var F = class {
308
+ program;
309
+ uniforms = {};
310
+ _gl;
311
+ constructor(e, t, n) {
312
+ this._gl = e, this.program = e.createProgram(), e.attachShader(this.program, this._compile(e.VERTEX_SHADER, t)), e.attachShader(this.program, this._compile(e.FRAGMENT_SHADER, n)), e.linkProgram(this.program);
313
+ let r = e.getProgramParameter(this.program, e.ACTIVE_UNIFORMS);
314
+ for (let t = 0; t < r; t++) {
315
+ let n = e.getActiveUniform(this.program, t).name;
316
+ this.uniforms[n] = e.getUniformLocation(this.program, n);
317
+ }
318
+ }
319
+ _compile(e, t) {
320
+ let n = this._gl, r = n.createShader(e);
321
+ return n.shaderSource(r, t), n.compileShader(r), r;
322
+ }
323
+ bind() {
324
+ this._gl.useProgram(this.program);
325
+ }
326
+ dispose() {
327
+ this._gl.deleteProgram(this.program);
328
+ }
329
+ };
330
+ function I(e) {
331
+ return {
332
+ advection: new F(e, w, T),
333
+ divergence: new F(e, w, E),
334
+ pressure: new F(e, w, D),
335
+ gradientSubtract: new F(e, w, O),
336
+ splat: new F(e, w, k),
337
+ curl: new F(e, w, A),
338
+ vorticity: new F(e, w, j),
339
+ display: new F(e, w, M)
340
+ };
761
341
  }
762
- @group(0) @binding(0) var<uniform> u : U;
763
- @group(0) @binding(1) var samp : sampler;
764
- @group(0) @binding(2) var uTex : texture_2d<f32>;
765
- @group(0) @binding(3) var uObs : texture_2d<f32>;
766
- @group(0) @binding(4) var uBg : texture_2d<f32>;
767
- @group(0) @binding(5) var uCov : texture_2d<f32>;
768
- @group(0) @binding(6) var uVel : texture_2d<f32>;
769
- @vertex fn vs(@location(0) a: vec2f) -> VSOut {
770
- var o: VSOut;
771
- o.uv = vec2f(a.x * 0.5 + 0.5, 0.5 - a.y * 0.5);
772
- o.vL = o.uv - vec2f(u.texelSize.x, 0.0);
773
- o.vR = o.uv + vec2f(u.texelSize.x, 0.0);
774
- o.vT = o.uv + vec2f(0.0, u.texelSize.y);
775
- o.vB = o.uv - vec2f(0.0, u.texelSize.y);
776
- o.pos = vec4f(a, 0.0, 1.0);
777
- return o;
342
+ function L(e, t, n, r) {
343
+ e.activeTexture(e.TEXTURE0);
344
+ let i = e.createTexture();
345
+ e.bindTexture(e.TEXTURE_2D, i), e.texParameteri(e.TEXTURE_2D, e.TEXTURE_MIN_FILTER, e.LINEAR), e.texParameteri(e.TEXTURE_2D, e.TEXTURE_MAG_FILTER, e.LINEAR), e.texParameteri(e.TEXTURE_2D, e.TEXTURE_WRAP_S, e.CLAMP_TO_EDGE), e.texParameteri(e.TEXTURE_2D, e.TEXTURE_WRAP_T, e.CLAMP_TO_EDGE), e.texImage2D(e.TEXTURE_2D, 0, t.internalFormat, n, r, 0, t.format, t.type, null);
346
+ let a = e.createFramebuffer();
347
+ return e.bindFramebuffer(e.FRAMEBUFFER, a), e.framebufferTexture2D(e.FRAMEBUFFER, e.COLOR_ATTACHMENT0, e.TEXTURE_2D, i, 0), {
348
+ tex: i,
349
+ fbo: a,
350
+ width: n,
351
+ height: r
352
+ };
778
353
  }
779
- @fragment fn fs(i: VSOut) -> @location(0) vec4f {
780
- let obs = textureSample(uObs, samp, i.uv).r;
781
- let density = max(textureSample(uTex, samp, i.uv).r, 0.0) * (1.0 - obs);
782
- let cov = textureSample(uCov, samp, i.uv).r;
783
- let sx = u.texelSize.x * 6.0;
784
- let sy = u.texelSize.y * 6.0;
785
- let d00 = max(textureSample(uTex, samp, i.uv + vec2f(-sx, -sy)).r, 0.0);
786
- let d10 = max(textureSample(uTex, samp, i.uv + vec2f(0.0, -sy)).r, 0.0);
787
- let d20 = max(textureSample(uTex, samp, i.uv + vec2f( sx, -sy)).r, 0.0);
788
- let d01 = max(textureSample(uTex, samp, i.uv + vec2f(-sx, 0.0)).r, 0.0);
789
- let d21 = max(textureSample(uTex, samp, i.uv + vec2f( sx, 0.0)).r, 0.0);
790
- let d02 = max(textureSample(uTex, samp, i.uv + vec2f(-sx, sy)).r, 0.0);
791
- let d12 = max(textureSample(uTex, samp, i.uv + vec2f(0.0, sy)).r, 0.0);
792
- let d22 = max(textureSample(uTex, samp, i.uv + vec2f( sx, sy)).r, 0.0);
793
- let gx = (d20 + 2.0*d21 + d22) - (d00 + 2.0*d01 + d02);
794
- let gy = (d02 + 2.0*d12 + d22) - (d00 + 2.0*d10 + d20);
795
- let norm = normalize(vec3f(gx, gy, 1.2));
796
- let ldir = normalize(vec3f(0.5, 1.0, 0.5));
797
- let halfV = normalize(ldir + vec3f(0.0, 0.0, 1.0));
798
- let specDen = density * min(density * 5.0, 1.0);
799
- let spec = pow(max(dot(norm, halfV), 0.0), u.specularExp) * u.shine * specDen;
800
- let bgRaw = textureSample(uBg, samp, i.uv).rgb;
801
- let wc = u.waterColor.rgb;
802
- let gc = u.glowColor.rgb;
803
- let bg = mix(wc, bgRaw, cov);
804
- var color = bg;
805
- if (u.algorithm == 1) {
806
- let ruv = clamp(i.uv + norm.xy * u.refraction * density * 3.0, vec2f(0.0), vec2f(1.0));
807
- let rbg = mix(wc, textureSample(uBg, samp, mix(i.uv, ruv, 1.0 - obs)).rgb, cov);
808
- color = rbg + spec * gc * 2.5;
809
- color = mix(color, bg * 0.6, obs * 0.3);
810
- } else if (u.algorithm == 2) {
811
- let inkD = min(density * 4.0, 1.0);
812
- let ruv = clamp(i.uv + norm.xy * u.refraction * density * 0.4, vec2f(0.0), vec2f(1.0));
813
- let rbg = mix(wc, textureSample(uBg, samp, mix(i.uv, ruv, 1.0 - obs)).rgb, cov);
814
- color = mix(rbg, wc + spec * gc, inkD);
815
- color = mix(color, bg * 0.5, obs * 0.15);
816
- } else if (u.algorithm == 3) {
817
- let vel = textureSample(uVel, samp, i.uv).xy;
818
- let velMag = clamp(length(vel) * 20.0, 0.0, 1.0);
819
- let wuv = clamp(i.uv + vel * u.warpStrength, vec2f(0.0), vec2f(1.0));
820
- let wbg = mix(wc, textureSample(uBg, samp, wuv).rgb, cov);
821
- color = mix(bg, wbg, velMag * (1.0 - obs));
822
- color += spec * gc * velMag * 1.5;
823
- color += wc * density * 0.3;
824
- color = mix(color, bg * 0.5, obs * 0.2);
825
- } else if (u.algorithm == 4) {
826
- let ruv = clamp(i.uv + norm.xy * u.refraction * density * 6.0, vec2f(0.0), vec2f(1.0));
827
- let rbg = mix(wc, textureSample(uBg, samp, mix(i.uv, ruv, 1.0 - obs)).rgb, cov);
828
- let fres = pow(clamp(1.0 - dot(norm, vec3f(0.0, 0.0, 1.0)), 0.0, 1.0), 3.0) * density;
829
- color = rbg;
830
- color += fres * gc * 2.0;
831
- color += spec * gc * density * 2.0;
832
- color = mix(color, bg * 0.5, obs * 0.2);
833
- } else {
834
- let ruv = i.uv + norm.xy * u.refraction * density;
835
- let rbg = mix(wc, textureSample(uBg, samp, mix(i.uv, ruv, 1.0 - obs)).rgb, cov);
836
- color = mix(rbg, wc, min(density * 1.5, 0.8));
837
- color += spec * gc;
838
- color = mix(color, bg * 0.5, obs * 0.2);
354
+ function R(e, t, n, r) {
355
+ let i = L(e, t, n, r), a = L(e, t, n, r);
356
+ return {
357
+ get read() {
358
+ return i;
359
+ },
360
+ get write() {
361
+ return a;
362
+ },
363
+ swap() {
364
+ [i, a] = [a, i];
365
+ },
366
+ dispose() {
367
+ e.deleteTexture(i.tex), e.deleteFramebuffer(i.fbo), e.deleteTexture(a.tex), e.deleteFramebuffer(a.fbo);
368
+ }
369
+ };
839
370
  }
840
- let alpha = clamp(max(density * 1.5, cov), 0.0, 1.0);
841
- if (u.enableAlpha == 1) {
842
- return vec4f(color * alpha, alpha);
371
+ function z(e) {
372
+ let t = e.createBuffer();
373
+ return e.bindBuffer(e.ARRAY_BUFFER, t), e.bufferData(e.ARRAY_BUFFER, new Float32Array([
374
+ -1,
375
+ -1,
376
+ -1,
377
+ 1,
378
+ 1,
379
+ 1,
380
+ 1,
381
+ -1
382
+ ]), e.STATIC_DRAW), e.vertexAttribPointer(0, 2, e.FLOAT, !1, 0, 0), e.enableVertexAttribArray(0), function(t) {
383
+ e.bindFramebuffer(e.FRAMEBUFFER, t), e.drawArrays(e.TRIANGLE_FAN, 0, 4);
384
+ };
843
385
  }
844
- return vec4f(color, 1.0);
845
- }`, JC = {
846
- arrayStride: 8,
847
- attributes: [{ shaderLocation: 0, offset: 0, format: "float32x2" }]
848
- }, PI = new Float32Array([
849
- -1,
850
- -1,
851
- -1,
852
- 1,
853
- 1,
854
- -1,
855
- 1,
856
- -1,
857
- -1,
858
- 1,
859
- 1,
860
- 1
386
+ //#endregion
387
+ //#region src/core/wgsl-shaders.ts
388
+ var B = "struct U {\n texelSize : vec2f,\n dt : f32,\n dissipation: f32,\n}\n@group(0) @binding(0) var<uniform> u : U;\n@group(0) @binding(1) var samp : sampler;\n@group(0) @binding(2) var uVel : texture_2d<f32>;\n@group(0) @binding(3) var uSrc : texture_2d<f32>;\n@group(0) @binding(4) var uObs : texture_2d<f32>;\n@vertex fn vs(@location(0) a: vec2f) -> VSOut {\n var o: VSOut;\n o.uv = vec2f(a.x * 0.5 + 0.5, 0.5 - a.y * 0.5);\n o.vL = o.uv - vec2f(u.texelSize.x, 0.0);\n o.vR = o.uv + vec2f(u.texelSize.x, 0.0);\n o.vT = o.uv + vec2f(0.0, u.texelSize.y);\n o.vB = o.uv - vec2f(0.0, u.texelSize.y);\n o.pos = vec4f(a, 0.0, 1.0);\n return o;\n}\n@fragment fn fs(i: VSOut) -> @location(0) vec4f {\n let obs = textureSample(uObs, samp, i.uv).r;\n let vel = textureSample(uVel, samp, i.uv).xy;\n let coord = i.uv - u.dt * vel * u.texelSize;\n let src = textureSample(uSrc, samp, coord);\n return u.dissipation * src * (1.0 - obs);\n}", V = "struct U { texelSize: vec2f, _pad: vec2f }\n@group(0) @binding(0) var<uniform> u : U;\n@group(0) @binding(1) var samp : sampler;\n@group(0) @binding(2) var uVel : texture_2d<f32>;\n@group(0) @binding(3) var uObs : texture_2d<f32>;\n@vertex fn vs(@location(0) a: vec2f) -> VSOut {\n var o: VSOut;\n o.uv = vec2f(a.x * 0.5 + 0.5, 0.5 - a.y * 0.5);\n o.vL = o.uv - vec2f(u.texelSize.x, 0.0);\n o.vR = o.uv + vec2f(u.texelSize.x, 0.0);\n o.vT = o.uv + vec2f(0.0, u.texelSize.y);\n o.vB = o.uv - vec2f(0.0, u.texelSize.y);\n o.pos = vec4f(a, 0.0, 1.0);\n return o;\n}\n@fragment fn fs(i: VSOut) -> @location(0) vec4f {\n let L = textureSample(uVel, samp, i.vL).x * (1.0 - textureSample(uObs, samp, i.vL).r);\n let R = textureSample(uVel, samp, i.vR).x * (1.0 - textureSample(uObs, samp, i.vR).r);\n let T = textureSample(uVel, samp, i.vT).y * (1.0 - textureSample(uObs, samp, i.vT).r);\n let B = textureSample(uVel, samp, i.vB).y * (1.0 - textureSample(uObs, samp, i.vB).r);\n return vec4f(0.5 * (R - L + T - B), 0.0, 0.0, 1.0);\n}", H = "struct U { texelSize: vec2f, _pad: vec2f }\n@group(0) @binding(0) var<uniform> u : U;\n@group(0) @binding(1) var samp : sampler;\n@group(0) @binding(2) var uPres: texture_2d<f32>;\n@group(0) @binding(3) var uDiv : texture_2d<f32>;\n@group(0) @binding(4) var uObs : texture_2d<f32>;\n@vertex fn vs(@location(0) a: vec2f) -> VSOut {\n var o: VSOut;\n o.uv = vec2f(a.x * 0.5 + 0.5, 0.5 - a.y * 0.5);\n o.vL = o.uv - vec2f(u.texelSize.x, 0.0);\n o.vR = o.uv + vec2f(u.texelSize.x, 0.0);\n o.vT = o.uv + vec2f(0.0, u.texelSize.y);\n o.vB = o.uv - vec2f(0.0, u.texelSize.y);\n o.pos = vec4f(a, 0.0, 1.0);\n return o;\n}\n@fragment fn fs(i: VSOut) -> @location(0) vec4f {\n let C = textureSample(uPres, samp, i.uv).x;\n let L = mix(textureSample(uPres, samp, i.vL).x, C, textureSample(uObs, samp, i.vL).r);\n let R = mix(textureSample(uPres, samp, i.vR).x, C, textureSample(uObs, samp, i.vR).r);\n let T = mix(textureSample(uPres, samp, i.vT).x, C, textureSample(uObs, samp, i.vT).r);\n let B = mix(textureSample(uPres, samp, i.vB).x, C, textureSample(uObs, samp, i.vB).r);\n let dv = textureSample(uDiv, samp, i.uv).x;\n return vec4f((L + R + B + T - dv) * 0.25, 0.0, 0.0, 1.0);\n}", U = "struct U { texelSize: vec2f, _pad: vec2f }\n@group(0) @binding(0) var<uniform> u : U;\n@group(0) @binding(1) var samp : sampler;\n@group(0) @binding(2) var uPres: texture_2d<f32>;\n@group(0) @binding(3) var uVel : texture_2d<f32>;\n@group(0) @binding(4) var uObs : texture_2d<f32>;\n@vertex fn vs(@location(0) a: vec2f) -> VSOut {\n var o: VSOut;\n o.uv = vec2f(a.x * 0.5 + 0.5, 0.5 - a.y * 0.5);\n o.vL = o.uv - vec2f(u.texelSize.x, 0.0);\n o.vR = o.uv + vec2f(u.texelSize.x, 0.0);\n o.vT = o.uv + vec2f(0.0, u.texelSize.y);\n o.vB = o.uv - vec2f(0.0, u.texelSize.y);\n o.pos = vec4f(a, 0.0, 1.0);\n return o;\n}\n@fragment fn fs(i: VSOut) -> @location(0) vec4f {\n let obs = textureSample(uObs, samp, i.uv).r;\n let C = textureSample(uPres, samp, i.uv).x;\n let L = mix(textureSample(uPres, samp, i.vL).x, C, textureSample(uObs, samp, i.vL).r);\n let R = mix(textureSample(uPres, samp, i.vR).x, C, textureSample(uObs, samp, i.vR).r);\n let T = mix(textureSample(uPres, samp, i.vT).x, C, textureSample(uObs, samp, i.vT).r);\n let B = mix(textureSample(uPres, samp, i.vB).x, C, textureSample(uObs, samp, i.vB).r);\n let vel = (textureSample(uVel, samp, i.uv).xy - vec2f(R - L, T - B)) * (1.0 - obs);\n return vec4f(vel, 0.0, 1.0);\n}", ee = "struct U {\n texelSize : vec2f,\n aspectRatio: f32,\n radius : f32,\n color : vec4f, \n point : vec2f,\n _pad : vec2f,\n}\n@group(0) @binding(0) var<uniform> u : U;\n@group(0) @binding(1) var samp : sampler;\n@group(0) @binding(2) var uTgt : texture_2d<f32>;\n@vertex fn vs(@location(0) a: vec2f) -> VSOut {\n var o: VSOut;\n o.uv = vec2f(a.x * 0.5 + 0.5, 0.5 - a.y * 0.5);\n o.vL = o.uv - vec2f(u.texelSize.x, 0.0);\n o.vR = o.uv + vec2f(u.texelSize.x, 0.0);\n o.vT = o.uv + vec2f(0.0, u.texelSize.y);\n o.vB = o.uv - vec2f(0.0, u.texelSize.y);\n o.pos = vec4f(a, 0.0, 1.0);\n return o;\n}\n@fragment fn fs(i: VSOut) -> @location(0) vec4f {\n var p = i.uv - u.point;\n p.x *= u.aspectRatio;\n let sp = exp(-dot(p, p) / u.radius) * u.color.xyz;\n return vec4f(textureSample(uTgt, samp, i.uv).xyz + sp, 1.0);\n}", te = "struct U { texelSize: vec2f, _pad: vec2f }\n@group(0) @binding(0) var<uniform> u : U;\n@group(0) @binding(1) var samp : sampler;\n@group(0) @binding(2) var uVel : texture_2d<f32>;\n@vertex fn vs(@location(0) a: vec2f) -> VSOut {\n var o: VSOut;\n o.uv = vec2f(a.x * 0.5 + 0.5, 0.5 - a.y * 0.5);\n o.vL = o.uv - vec2f(u.texelSize.x, 0.0);\n o.vR = o.uv + vec2f(u.texelSize.x, 0.0);\n o.vT = o.uv + vec2f(0.0, u.texelSize.y);\n o.vB = o.uv - vec2f(0.0, u.texelSize.y);\n o.pos = vec4f(a, 0.0, 1.0);\n return o;\n}\n@fragment fn fs(i: VSOut) -> @location(0) vec4f {\n let L = textureSample(uVel, samp, i.vL).y;\n let R = textureSample(uVel, samp, i.vR).y;\n let T = textureSample(uVel, samp, i.vT).x;\n let B = textureSample(uVel, samp, i.vB).x;\n return vec4f(0.5 * (R - L - T + B), 0.0, 0.0, 1.0);\n}", ne = "struct U {\n texelSize: vec2f,\n curl : f32,\n dt : f32,\n}\n@group(0) @binding(0) var<uniform> u : U;\n@group(0) @binding(1) var samp : sampler;\n@group(0) @binding(2) var uVel : texture_2d<f32>;\n@group(0) @binding(3) var uCrl : texture_2d<f32>;\n@vertex fn vs(@location(0) a: vec2f) -> VSOut {\n var o: VSOut;\n o.uv = vec2f(a.x * 0.5 + 0.5, 0.5 - a.y * 0.5);\n o.vL = o.uv - vec2f(u.texelSize.x, 0.0);\n o.vR = o.uv + vec2f(u.texelSize.x, 0.0);\n o.vT = o.uv + vec2f(0.0, u.texelSize.y);\n o.vB = o.uv - vec2f(0.0, u.texelSize.y);\n o.pos = vec4f(a, 0.0, 1.0);\n return o;\n}\n@fragment fn fs(i: VSOut) -> @location(0) vec4f {\n let L = textureSample(uCrl, samp, i.vL).x;\n let R = textureSample(uCrl, samp, i.vR).x;\n let T = textureSample(uCrl, samp, i.vT).x;\n let B = textureSample(uCrl, samp, i.vB).x;\n let C = textureSample(uCrl, samp, i.uv).x;\n var force = 0.5 * vec2f(abs(T) - abs(B), abs(R) - abs(L));\n force /= length(force) + 0.0001;\n force *= u.curl * 30.0 * C;\n let vel = textureSample(uVel, samp, i.uv).xy + force * u.dt;\n return vec4f(vel, 0.0, 1.0);\n}", re = "struct U {\n texelSize : vec2f,\n refraction : f32,\n specularExp : f32,\n waterColor : vec4f,\n glowColor : vec4f,\n shine : f32,\n warpStrength: f32,\n algorithm : i32,\n enableAlpha : i32,\n}\n@group(0) @binding(0) var<uniform> u : U;\n@group(0) @binding(1) var samp : sampler;\n@group(0) @binding(2) var uTex : texture_2d<f32>;\n@group(0) @binding(3) var uObs : texture_2d<f32>;\n@group(0) @binding(4) var uBg : texture_2d<f32>;\n@group(0) @binding(5) var uCov : texture_2d<f32>;\n@group(0) @binding(6) var uVel : texture_2d<f32>;\n@vertex fn vs(@location(0) a: vec2f) -> VSOut {\n var o: VSOut;\n o.uv = vec2f(a.x * 0.5 + 0.5, 0.5 - a.y * 0.5);\n o.vL = o.uv - vec2f(u.texelSize.x, 0.0);\n o.vR = o.uv + vec2f(u.texelSize.x, 0.0);\n o.vT = o.uv + vec2f(0.0, u.texelSize.y);\n o.vB = o.uv - vec2f(0.0, u.texelSize.y);\n o.pos = vec4f(a, 0.0, 1.0);\n return o;\n}\n@fragment fn fs(i: VSOut) -> @location(0) vec4f {\n let obs = textureSample(uObs, samp, i.uv).r;\n let density = max(textureSample(uTex, samp, i.uv).r, 0.0) * (1.0 - obs);\n let cov = textureSample(uCov, samp, i.uv).r;\n let sx = u.texelSize.x * 6.0;\n let sy = u.texelSize.y * 6.0;\n let d00 = max(textureSample(uTex, samp, i.uv + vec2f(-sx, -sy)).r, 0.0);\n let d10 = max(textureSample(uTex, samp, i.uv + vec2f(0.0, -sy)).r, 0.0);\n let d20 = max(textureSample(uTex, samp, i.uv + vec2f( sx, -sy)).r, 0.0);\n let d01 = max(textureSample(uTex, samp, i.uv + vec2f(-sx, 0.0)).r, 0.0);\n let d21 = max(textureSample(uTex, samp, i.uv + vec2f( sx, 0.0)).r, 0.0);\n let d02 = max(textureSample(uTex, samp, i.uv + vec2f(-sx, sy)).r, 0.0);\n let d12 = max(textureSample(uTex, samp, i.uv + vec2f(0.0, sy)).r, 0.0);\n let d22 = max(textureSample(uTex, samp, i.uv + vec2f( sx, sy)).r, 0.0);\n let gx = (d20 + 2.0*d21 + d22) - (d00 + 2.0*d01 + d02);\n let gy = (d02 + 2.0*d12 + d22) - (d00 + 2.0*d10 + d20);\n let norm = normalize(vec3f(gx, gy, 1.2));\n let ldir = normalize(vec3f(0.5, 1.0, 0.5));\n let halfV = normalize(ldir + vec3f(0.0, 0.0, 1.0));\n let specDen = density * min(density * 5.0, 1.0);\n let spec = pow(max(dot(norm, halfV), 0.0), u.specularExp) * u.shine * specDen;\n let bgRaw = textureSample(uBg, samp, i.uv).rgb;\n let wc = u.waterColor.rgb;\n let gc = u.glowColor.rgb;\n let bg = mix(wc, bgRaw, cov);\n var color = bg;\n if (u.algorithm == 1) {\n let ruv = clamp(i.uv + norm.xy * u.refraction * density * 3.0, vec2f(0.0), vec2f(1.0));\n let rbg = mix(wc, textureSample(uBg, samp, mix(i.uv, ruv, 1.0 - obs)).rgb, cov);\n color = rbg + spec * gc * 2.5;\n color = mix(color, bg * 0.6, obs * 0.3);\n } else if (u.algorithm == 2) {\n let inkD = min(density * 4.0, 1.0);\n let ruv = clamp(i.uv + norm.xy * u.refraction * density * 0.4, vec2f(0.0), vec2f(1.0));\n let rbg = mix(wc, textureSample(uBg, samp, mix(i.uv, ruv, 1.0 - obs)).rgb, cov);\n color = mix(rbg, wc + spec * gc, inkD);\n color = mix(color, bg * 0.5, obs * 0.15);\n } else if (u.algorithm == 3) {\n let vel = textureSample(uVel, samp, i.uv).xy;\n let velMag = clamp(length(vel) * 20.0, 0.0, 1.0);\n let wuv = clamp(i.uv + vel * u.warpStrength, vec2f(0.0), vec2f(1.0));\n let wbg = mix(wc, textureSample(uBg, samp, wuv).rgb, cov);\n color = mix(bg, wbg, velMag * (1.0 - obs));\n color += spec * gc * velMag * 1.5;\n color += wc * density * 0.3;\n color = mix(color, bg * 0.5, obs * 0.2);\n } else if (u.algorithm == 4) {\n let ruv = clamp(i.uv + norm.xy * u.refraction * density * 6.0, vec2f(0.0), vec2f(1.0));\n let rbg = mix(wc, textureSample(uBg, samp, mix(i.uv, ruv, 1.0 - obs)).rgb, cov);\n let fres = pow(clamp(1.0 - dot(norm, vec3f(0.0, 0.0, 1.0)), 0.0, 1.0), 3.0) * density;\n color = rbg;\n color += fres * gc * 2.0;\n color += spec * gc * density * 2.0;\n color = mix(color, bg * 0.5, obs * 0.2);\n } else {\n let ruv = i.uv + norm.xy * u.refraction * density;\n let rbg = mix(wc, textureSample(uBg, samp, mix(i.uv, ruv, 1.0 - obs)).rgb, cov);\n color = mix(rbg, wc, min(density * 1.5, 0.8));\n color += spec * gc;\n color = mix(color, bg * 0.5, obs * 0.2);\n }\n let alpha = clamp(max(density * 1.5, cov), 0.0, 1.0);\n if (u.enableAlpha == 1) {\n return vec4f(color * alpha, alpha);\n }\n return vec4f(color, 1.0);\n}", ie = {
389
+ arrayStride: 8,
390
+ attributes: [{
391
+ shaderLocation: 0,
392
+ offset: 0,
393
+ format: "float32x2"
394
+ }]
395
+ }, ae = new Float32Array([
396
+ -1,
397
+ -1,
398
+ -1,
399
+ 1,
400
+ 1,
401
+ -1,
402
+ 1,
403
+ -1,
404
+ -1,
405
+ 1,
406
+ 1,
407
+ 1
861
408
  ]);
862
- function zC(e) {
863
- const g = e.createBuffer({ size: PI.byteLength, usage: GPUBufferUsage.VERTEX | GPUBufferUsage.COPY_DST });
864
- return e.queue.writeBuffer(g, 0, PI), g;
409
+ function oe(e) {
410
+ let t = e.createBuffer({
411
+ size: ae.byteLength,
412
+ usage: GPUBufferUsage.VERTEX | GPUBufferUsage.COPY_DST
413
+ });
414
+ return e.queue.writeBuffer(t, 0, ae), t;
865
415
  }
866
- function KI(e, g, C, i) {
867
- const s = e.createTexture({
868
- size: [C, i],
869
- format: g,
870
- usage: GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.RENDER_ATTACHMENT | GPUTextureUsage.COPY_SRC
871
- });
872
- return { tex: s, view: s.createView(), width: C, height: i };
416
+ function W(e, t, n, r) {
417
+ let i = e.createTexture({
418
+ size: [n, r],
419
+ format: t,
420
+ usage: GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.RENDER_ATTACHMENT | GPUTextureUsage.COPY_SRC
421
+ });
422
+ return {
423
+ tex: i,
424
+ view: i.createView(),
425
+ width: n,
426
+ height: r
427
+ };
873
428
  }
874
- function DI(e, g, C, i) {
875
- let s = KI(e, g, C, i), t = KI(e, g, C, i);
876
- return {
877
- get read() {
878
- return s;
879
- },
880
- get write() {
881
- return t;
882
- },
883
- swap() {
884
- [s, t] = [t, s];
885
- },
886
- dispose() {
887
- s.tex.destroy(), t.tex.destroy();
888
- }
889
- };
429
+ function G(e, t, n, r) {
430
+ let i = W(e, t, n, r), a = W(e, t, n, r);
431
+ return {
432
+ get read() {
433
+ return i;
434
+ },
435
+ get write() {
436
+ return a;
437
+ },
438
+ swap() {
439
+ [i, a] = [a, i];
440
+ },
441
+ dispose() {
442
+ i.tex.destroy(), a.tex.destroy();
443
+ }
444
+ };
890
445
  }
891
- function ng(e, g, C, i) {
892
- const s = e.createShaderModule({ code: g });
893
- return e.createRenderPipeline({
894
- layout: "auto",
895
- vertex: { module: s, entryPoint: "vs", buffers: [JC] },
896
- fragment: { module: s, entryPoint: "fs", targets: [{ format: C, ...i ? { blend: i } : {} }] },
897
- primitive: { topology: "triangle-list" }
898
- });
446
+ function K(e, t, n, r) {
447
+ let i = e.createShaderModule({ code: t });
448
+ return e.createRenderPipeline({
449
+ layout: "auto",
450
+ vertex: {
451
+ module: i,
452
+ entryPoint: "vs",
453
+ buffers: [ie]
454
+ },
455
+ fragment: {
456
+ module: i,
457
+ entryPoint: "fs",
458
+ targets: [{
459
+ format: n,
460
+ ...r ? { blend: r } : {}
461
+ }]
462
+ },
463
+ primitive: { topology: "triangle-list" }
464
+ });
899
465
  }
900
- const QC = {
901
- color: { operation: "add", srcFactor: "one", dstFactor: "zero" },
902
- alpha: { operation: "add", srcFactor: "one", dstFactor: "zero" }
466
+ var se = {
467
+ color: {
468
+ operation: "add",
469
+ srcFactor: "one",
470
+ dstFactor: "zero"
471
+ },
472
+ alpha: {
473
+ operation: "add",
474
+ srcFactor: "one",
475
+ dstFactor: "zero"
476
+ }
903
477
  };
904
- function NC(e, g, C = !0) {
905
- const i = "rgba16float";
906
- return {
907
- advection: ng(e, YC, i),
908
- divergence: ng(e, kC, i),
909
- pressure: ng(e, MC, i),
910
- gradientSubtract: ng(e, xC, i),
911
- splat: ng(e, fC, i),
912
- curl: ng(e, FC, i),
913
- vorticity: ng(e, DC, i),
914
- display: ng(e, TC, g, C ? void 0 : QC)
915
- };
478
+ function ce(e, t, n = !0) {
479
+ let r = "rgba16float";
480
+ return {
481
+ advection: K(e, B, r),
482
+ divergence: K(e, V, r),
483
+ pressure: K(e, H, r),
484
+ gradientSubtract: K(e, U, r),
485
+ splat: K(e, ee, r),
486
+ curl: K(e, te, r),
487
+ vorticity: K(e, ne, r),
488
+ display: K(e, re, t, n ? void 0 : se)
489
+ };
916
490
  }
917
- function EC(e) {
918
- return e.createSampler({ magFilter: "linear", minFilter: "linear", addressModeU: "clamp-to-edge", addressModeV: "clamp-to-edge" });
491
+ function le(e) {
492
+ return e.createSampler({
493
+ magFilter: "linear",
494
+ minFilter: "linear",
495
+ addressModeU: "clamp-to-edge",
496
+ addressModeV: "clamp-to-edge"
497
+ });
919
498
  }
920
- function gg(e, g) {
921
- return e.createBuffer({ size: g, usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST });
499
+ function q(e, t) {
500
+ return e.createBuffer({
501
+ size: t,
502
+ usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST
503
+ });
922
504
  }
923
- function _I(e, g, C, i, s, t) {
924
- const l = new Float32Array([C, i, s, t]);
925
- e.queue.writeBuffer(g, 0, l);
505
+ function ue(e, t, n, r, i, a) {
506
+ let o = new Float32Array([
507
+ n,
508
+ r,
509
+ i,
510
+ a
511
+ ]);
512
+ e.queue.writeBuffer(t, 0, o);
926
513
  }
927
- function hI(e, g, C, i) {
928
- const s = new Float32Array([C, i, 0, 0]);
929
- e.queue.writeBuffer(g, 0, s);
514
+ function J(e, t, n, r) {
515
+ let i = new Float32Array([
516
+ n,
517
+ r,
518
+ 0,
519
+ 0
520
+ ]);
521
+ e.queue.writeBuffer(t, 0, i);
930
522
  }
931
- function OC(e, g, C, i, s, t) {
932
- const l = new Float32Array([C, i, s, t]);
933
- e.queue.writeBuffer(g, 0, l);
523
+ function de(e, t, n, r, i, a) {
524
+ let o = new Float32Array([
525
+ n,
526
+ r,
527
+ i,
528
+ a
529
+ ]);
530
+ e.queue.writeBuffer(t, 0, o);
934
531
  }
935
- function bI(e, g, C, i, s, t, l, u, Z, d, S) {
936
- const a = new Float32Array(12);
937
- a[0] = C, a[1] = i, a[2] = s, a[3] = t, a[4] = l, a[5] = u, a[6] = Z, a[7] = 0, a[8] = d, a[9] = S, a[10] = 0, a[11] = 0, e.queue.writeBuffer(g, 0, a);
532
+ function Y(e, t, n, r, i, a, o, s, c, l, u) {
533
+ let d = /* @__PURE__ */ new Float32Array(12);
534
+ d[0] = n, d[1] = r, d[2] = i, d[3] = a, d[4] = o, d[5] = s, d[6] = c, d[7] = 0, d[8] = l, d[9] = u, d[10] = 0, d[11] = 0, e.queue.writeBuffer(t, 0, d);
938
535
  }
939
- function jC(e, g, C, i, s, t, l, u, Z, d, S, a) {
940
- const c = new Float32Array(16), m = new Int32Array(c.buffer);
941
- c[0] = C, c[1] = i, c[2] = s, c[3] = t, c[4] = l[0], c[5] = l[1], c[6] = l[2], c[7] = 0, c[8] = u[0], c[9] = u[1], c[10] = u[2], c[11] = 0, c[12] = Z, c[13] = d, m[14] = S, m[15] = a ? 1 : 0, e.queue.writeBuffer(g, 0, c);
536
+ function fe(e, t, n, r, i, a, o, s, c, l, u, d) {
537
+ let f = /* @__PURE__ */ new Float32Array(16), p = new Int32Array(f.buffer);
538
+ f[0] = n, f[1] = r, f[2] = i, f[3] = a, f[4] = o[0], f[5] = o[1], f[6] = o[2], f[7] = 0, f[8] = s[0], f[9] = s[1], f[10] = s[2], f[11] = 0, f[12] = c, f[13] = l, p[14] = u, p[15] = +!!d, e.queue.writeBuffer(t, 0, f);
942
539
  }
943
- function O(e, g, C, i, s) {
944
- const t = e.beginRenderPass({
945
- colorAttachments: [{
946
- view: s,
947
- clearValue: [0, 0, 0, 0],
948
- loadOp: "clear",
949
- storeOp: "store"
950
- }]
951
- });
952
- t.setPipeline(g), t.setBindGroup(0, C), t.setVertexBuffer(0, i), t.draw(6), t.end();
540
+ function X(e, t, n, r, i) {
541
+ let a = e.beginRenderPass({ colorAttachments: [{
542
+ view: i,
543
+ clearValue: [
544
+ 0,
545
+ 0,
546
+ 0,
547
+ 0
548
+ ],
549
+ loadOp: "clear",
550
+ storeOp: "store"
551
+ }] });
552
+ a.setPipeline(t), a.setBindGroup(0, n), a.setVertexBuffer(0, r), a.draw(6), a.end();
953
553
  }
954
- function PC(e, g, C, i, s) {
955
- const t = e.beginRenderPass({
956
- colorAttachments: [{
957
- view: s,
958
- clearValue: [0, 0, 0, 0],
959
- loadOp: "clear",
960
- storeOp: "store"
961
- }]
962
- });
963
- t.setPipeline(g), t.setBindGroup(0, C), t.setVertexBuffer(0, i), t.draw(6), t.end();
554
+ function pe(e, t, n, r, i) {
555
+ let a = e.beginRenderPass({ colorAttachments: [{
556
+ view: i,
557
+ clearValue: [
558
+ 0,
559
+ 0,
560
+ 0,
561
+ 0
562
+ ],
563
+ loadOp: "clear",
564
+ storeOp: "store"
565
+ }] });
566
+ a.setPipeline(t), a.setBindGroup(0, n), a.setVertexBuffer(0, r), a.draw(6), a.end();
964
567
  }
965
- const qI = typeof requestAnimationFrame < "u" ? requestAnimationFrame.bind(globalThis) : (e) => setTimeout(e, 1e3 / 60), _C = typeof cancelAnimationFrame < "u" ? cancelAnimationFrame.bind(globalThis) : clearTimeout, cI = 0.016, $I = { standard: 0, glass: 1, ink: 2, aurora: 3, ripple: 4 };
966
- var Vg, j, mI, Kg, Og, M, X, Ig, Cg, ig, og, Q, eg, F, jg, Xg, Pg, x, b, Gg, sg, pg, E, Hg, vg, Wg, Rg, Ug, cg, dg, Yg, kg, Mg, K, H, P, _, D, _g, Ag, N, Lg, ug, L, SI, U, tg, xg, BI, fg, HI, tC, Fg, dI, nI, TI, wg, Qg, Dg, AI, rI, JI, GI, zI, vI, lC, WI, oC, RI, cC, UI, dC, YI, AC;
967
- const EI = class EI {
968
- // ── Constructor ─────────────────────────────────────────────────────────────
969
- constructor(g, C = {}, i = {}, s, t = !0) {
970
- // ---------------------------------------------------------------------------
971
- // Private — GPU initialisation
972
- // ---------------------------------------------------------------------------
973
- A(this, HI);
974
- // ---------------------------------------------------------------------------
975
- // Private — shared helpers
976
- // ---------------------------------------------------------------------------
977
- A(this, Fg);
978
- A(this, nI);
979
- A(this, wg);
980
- A(this, Dg);
981
- A(this, rI);
982
- A(this, GI);
983
- // ---------------------------------------------------------------------------
984
- // Private — frame dispatch
985
- // ---------------------------------------------------------------------------
986
- A(this, vI);
987
- // ---------------------------------------------------------------------------
988
- // Private — WebGPU simulation step
989
- // ---------------------------------------------------------------------------
990
- A(this, WI);
991
- // ---------------------------------------------------------------------------
992
- // Private — WebGPU direct splat
993
- // ---------------------------------------------------------------------------
994
- A(this, RI);
995
- // ---------------------------------------------------------------------------
996
- // Private — WebGL splat
997
- // ---------------------------------------------------------------------------
998
- A(this, UI);
999
- // ---------------------------------------------------------------------------
1000
- // Private — WebGL simulation step (unchanged from original)
1001
- // ---------------------------------------------------------------------------
1002
- A(this, YI);
1003
- A(this, Vg, void 0);
1004
- // ── WebGL path ──────────────────────────────────────────────────────────────
1005
- A(this, j, null);
1006
- A(this, mI, null);
1007
- A(this, Kg, null);
1008
- A(this, Og, null);
1009
- A(this, M, null);
1010
- A(this, X, null);
1011
- A(this, Ig, null);
1012
- A(this, Cg, null);
1013
- A(this, ig, null);
1014
- A(this, og, null);
1015
- A(this, Q, null);
1016
- A(this, eg, null);
1017
- // ── WebGPU path ─────────────────────────────────────────────────────────────
1018
- A(this, F, null);
1019
- A(this, jg, null);
1020
- A(this, Xg, null);
1021
- A(this, Pg, null);
1022
- A(this, x, null);
1023
- A(this, b, null);
1024
- A(this, Gg, null);
1025
- A(this, sg, null);
1026
- A(this, pg, null);
1027
- A(this, E, null);
1028
- // Pre-allocated uniform buffers (sizes: see gpu-utils writeXxx docs)
1029
- // Velocity/density advection use separate buffers — writeBuffer is a queue op;
1030
- // a second write to the same buffer before queue.submit() aliases both passes.
1031
- A(this, Hg, null);
1032
- // 16 bytes velocity advection
1033
- A(this, vg, null);
1034
- // 16 bytes — density advection
1035
- A(this, Wg, null);
1036
- // 16 bytes
1037
- A(this, Rg, null);
1038
- // 16 bytes
1039
- A(this, Ug, null);
1040
- // 16 bytes
1041
- A(this, cg, null);
1042
- // 48 bytes — velocity splat
1043
- A(this, dg, null);
1044
- // 48 bytes — density splat
1045
- A(this, Yg, null);
1046
- // 16 bytes
1047
- A(this, kg, null);
1048
- // 16 bytes
1049
- A(this, Mg, null);
1050
- // 64 bytes
1051
- // ── Shared state ────────────────────────────────────────────────────────────
1052
- A(this, K, 0);
1053
- A(this, H, 0);
1054
- A(this, P, 0);
1055
- A(this, _, 0);
1056
- A(this, D, 1);
1057
- A(this, _g, 1);
1058
- A(this, Ag, 0.5);
1059
- A(this, N, null);
1060
- A(this, Lg, "cover");
1061
- A(this, ug, void 0);
1062
- A(this, L, { x: 0, y: 0, dx: 0, dy: 0, targetX: 0, targetY: 0, moved: !1 });
1063
- A(this, SI, !1);
1064
- A(this, U, null);
1065
- A(this, tg, null);
1066
- A(this, xg, !1);
1067
- A(this, BI, !1);
1068
- A(this, fg, !0);
1069
- if (o(this, Vg, g), o(this, _g, Math.max(0.1, Math.min(1, i.dpr ?? 1))), o(this, Ag, Math.max(0.1, Math.min(1, i.sim ?? 0.5))), o(this, ug, ZI(C)), o(this, fg, t), s)
1070
- o(this, F, s), h(this, HI, tC).call(this, s);
1071
- else {
1072
- const { gl: l, ext: u } = vC(g, t);
1073
- o(this, j, l), o(this, mI, u), o(this, Kg, RC(l)), o(this, Og, UC(l)), l.clearColor(0, 0, 0, t ? 0 : 1);
1074
- }
1075
- }
1076
- /**
1077
- * WebGPU-first factory. Tries WebGPU, falls back to WebGL2 WebGL1.
1078
- * This is the recommended entry point when WebGPU support is desired.
1079
- */
1080
- static async create(g, C = {}, i = {}, s = !0, t = !0) {
1081
- const l = s ? await WC(g, t) : null;
1082
- return new EI(g, C, i, l ?? void 0, t);
1083
- }
1084
- // ---------------------------------------------------------------------------
1085
- // Public API
1086
- // ---------------------------------------------------------------------------
1087
- setTextSource(g) {
1088
- o(this, U, { type: "text", opts: g }), h(this, Fg, dI).call(this), h(this, wg, Qg).call(this), h(this, Dg, AI).call(this);
1089
- }
1090
- async setImageSource(g, C = 0, i = "cover") {
1091
- const s = await NI(g);
1092
- if (I(this, BI)) {
1093
- s.close();
1094
- return;
1095
- }
1096
- o(this, U, { type: "image", bitmap: s, effect: C, size: i }), h(this, Fg, dI).call(this), h(this, wg, Qg).call(this), h(this, Dg, AI).call(this);
1097
- }
1098
- setImageBitmap(g, C = 0, i = "cover") {
1099
- o(this, U, { type: "image", bitmap: g, effect: C, size: i }), h(this, Fg, dI).call(this), h(this, wg, Qg).call(this), h(this, Dg, AI).call(this);
1100
- }
1101
- setBackground(g, C = "cover") {
1102
- I(this, N) && I(this, N) !== g && I(this, N).close(), o(this, N, g), o(this, Lg, C ?? "cover"), I(this, U) && I(this, K) > 0 && I(this, H) > 0 && h(this, wg, Qg).call(this);
1103
- }
1104
- handleMove(g, C, i = 1) {
1105
- if (!I(this, SI)) {
1106
- I(this, L).x = I(this, L).targetX = g, I(this, L).y = I(this, L).targetY = C, o(this, SI, !0);
1107
- return;
1108
- }
1109
- I(this, L).moved = !0, I(this, L).dx = (g - I(this, L).targetX) * i, I(this, L).dy = (C - I(this, L).targetY) * i, I(this, L).targetX = g, I(this, L).targetY = C;
1110
- }
1111
- /**
1112
- * Immediately applies one fluid splat at (x, y) with explicit velocity (vx, vy).
1113
- * Safe to call multiple times per frame — each call writes directly to the FBOs.
1114
- * Designed for programmatic use cases (e.g. particle systems, attractor paths)
1115
- * where you want N independent injection points per frame without flooding the
1116
- * mouse-state machine or the worker message queue.
1117
- */
1118
- splat(g, C, i, s, t = 1) {
1119
- !I(this, xg) || I(this, K) === 0 || (I(this, F) ? h(this, RI, cC).call(this, g, C, i, s, t) : h(this, UI, dC).call(this, g, C, i, s, t));
1120
- }
1121
- updateQuality(g) {
1122
- g.dpr !== void 0 && o(this, _g, Math.max(0.1, Math.min(1, g.dpr))), g.sim !== void 0 && o(this, Ag, Math.max(0.1, Math.min(1, g.sim)));
1123
- }
1124
- resize(g, C, i) {
1125
- if (i !== void 0 ? o(this, D, i) : typeof window < "u" && window.devicePixelRatio && o(this, D, window.devicePixelRatio), g !== void 0 && g > 0) {
1126
- if (C === void 0 || C <= 0)
1127
- return;
1128
- o(this, K, I(this, Vg).width = g), o(this, H, I(this, Vg).height = C), o(this, P, Math.max(1, Math.round(g * I(this, Ag)))), o(this, _, Math.max(1, Math.round(C * I(this, Ag)))), h(this, nI, TI).call(this);
1129
- } else
1130
- h(this, Fg, dI).call(this);
1131
- I(this, U) && h(this, wg, Qg).call(this), h(this, Dg, AI).call(this);
1132
- }
1133
- updateConfig(g) {
1134
- Object.assign(I(this, ug), g);
1135
- }
1136
- destroy() {
1137
- var g, C, i, s, t, l, u, Z, d, S, a;
1138
- if (o(this, BI, !0), this.stop(), h(this, rI, JI).call(this), h(this, GI, zI).call(this), I(this, N) && (I(this, N).close(), o(this, N, null)), I(this, F))
1139
- (g = I(this, Hg)) == null || g.destroy(), (C = I(this, vg)) == null || C.destroy(), (i = I(this, Wg)) == null || i.destroy(), (s = I(this, Rg)) == null || s.destroy(), (t = I(this, Ug)) == null || t.destroy(), (l = I(this, cg)) == null || l.destroy(), (u = I(this, dg)) == null || u.destroy(), (Z = I(this, Yg)) == null || Z.destroy(), (d = I(this, kg)) == null || d.destroy(), (S = I(this, Mg)) == null || S.destroy(), (a = I(this, Xg)) == null || a.destroy(), I(this, F).device.destroy();
1140
- else {
1141
- const c = I(this, j);
1142
- for (const B of Object.values(I(this, Kg)))
1143
- B.dispose();
1144
- const m = c.getExtension("WEBGL_lose_context");
1145
- m == null || m.loseContext();
1146
- }
1147
- }
1148
- // ---------------------------------------------------------------------------
1149
- // Loop control
1150
- // ---------------------------------------------------------------------------
1151
- start() {
1152
- if (I(this, tg) !== null)
1153
- return;
1154
- const g = () => {
1155
- h(this, vI, lC).call(this), o(this, tg, qI(g));
1156
- };
1157
- o(this, tg, qI(g));
1158
- }
1159
- stop() {
1160
- I(this, tg) !== null && (_C(I(this, tg)), o(this, tg, null));
1161
- }
1162
- get isRunning() {
1163
- return I(this, tg) !== null;
1164
- }
1165
- };
1166
- Vg = new WeakMap(), j = new WeakMap(), mI = new WeakMap(), Kg = new WeakMap(), Og = new WeakMap(), M = new WeakMap(), X = new WeakMap(), Ig = new WeakMap(), Cg = new WeakMap(), ig = new WeakMap(), og = new WeakMap(), Q = new WeakMap(), eg = new WeakMap(), F = new WeakMap(), jg = new WeakMap(), Xg = new WeakMap(), Pg = new WeakMap(), x = new WeakMap(), b = new WeakMap(), Gg = new WeakMap(), sg = new WeakMap(), pg = new WeakMap(), E = new WeakMap(), Hg = new WeakMap(), vg = new WeakMap(), Wg = new WeakMap(), Rg = new WeakMap(), Ug = new WeakMap(), cg = new WeakMap(), dg = new WeakMap(), Yg = new WeakMap(), kg = new WeakMap(), Mg = new WeakMap(), K = new WeakMap(), H = new WeakMap(), P = new WeakMap(), _ = new WeakMap(), D = new WeakMap(), _g = new WeakMap(), Ag = new WeakMap(), N = new WeakMap(), Lg = new WeakMap(), ug = new WeakMap(), L = new WeakMap(), SI = new WeakMap(), U = new WeakMap(), tg = new WeakMap(), xg = new WeakMap(), BI = new WeakMap(), fg = new WeakMap(), HI = new WeakSet(), tC = function(g) {
1167
- const { device: C, format: i } = g;
1168
- o(this, jg, NC(C, i, I(this, fg))), o(this, Xg, zC(C)), o(this, Pg, EC(C)), o(this, Hg, gg(C, 16)), o(this, vg, gg(C, 16)), o(this, Wg, gg(C, 16)), o(this, Rg, gg(C, 16)), o(this, Ug, gg(C, 16)), o(this, cg, gg(C, 48)), o(this, dg, gg(C, 48)), o(this, Yg, gg(C, 16)), o(this, kg, gg(C, 16)), o(this, Mg, gg(C, 64));
1169
- }, Fg = new WeakSet(), dI = function() {
1170
- const g = I(this, Vg);
1171
- "clientWidth" in g && g.clientWidth > 0 ? (o(this, D, (typeof window < "u" && window.devicePixelRatio || 1) * I(this, _g)), o(this, K, g.width = Math.round(g.clientWidth * I(this, D))), o(this, H, g.height = Math.round(g.clientHeight * I(this, D)))) : (o(this, K, g.width), o(this, H, g.height)), !(I(this, K) === 0 || I(this, H) === 0) && (o(this, P, Math.max(1, Math.round(I(this, K) * I(this, Ag)))), o(this, _, Math.max(1, Math.round(I(this, H) * I(this, Ag)))), h(this, nI, TI).call(this));
1172
- }, nI = new WeakSet(), TI = function() {
1173
- if (h(this, rI, JI).call(this), I(this, F)) {
1174
- const { device: g } = I(this, F), C = "rgba16float", i = I(this, P), s = I(this, _);
1175
- o(this, x, DI(g, C, i, s)), o(this, b, DI(g, C, i, s)), o(this, sg, DI(g, C, i, s)), o(this, Gg, KI(g, C, i, s)), o(this, pg, KI(g, C, i, s));
1176
- } else {
1177
- const g = I(this, j), C = I(this, mI), i = I(this, P), s = I(this, _);
1178
- o(this, M, FI(g, C, i, s)), o(this, X, FI(g, C, i, s)), o(this, Cg, FI(g, C, i, s)), o(this, Ig, VI(g, C, i, s)), o(this, ig, VI(g, C, i, s));
1179
- }
1180
- }, wg = new WeakSet(), Qg = function() {
1181
- if (!(!I(this, U) || I(this, K) === 0 || I(this, H) === 0)) {
1182
- if (h(this, GI, zI).call(this), I(this, F)) {
1183
- const { device: g } = I(this, F);
1184
- I(this, U).type === "text" ? o(this, E, pC(
1185
- g,
1186
- I(this, K),
1187
- I(this, H),
1188
- I(this, U).opts,
1189
- I(this, N),
1190
- I(this, Lg)
1191
- )) : o(this, E, LC(
1192
- g,
1193
- I(this, U).bitmap,
1194
- I(this, K),
1195
- I(this, H),
1196
- I(this, U).effect,
1197
- I(this, U).size,
1198
- I(this, N),
1199
- I(this, Lg)
1200
- ));
1201
- } else {
1202
- const g = I(this, j);
1203
- if (I(this, U).type === "text") {
1204
- const { backgroundTex: C, obstacleTex: i, coverageTex: s } = rC(
1205
- g,
1206
- I(this, K),
1207
- I(this, H),
1208
- I(this, U).opts,
1209
- I(this, N),
1210
- I(this, Lg)
1211
- );
1212
- o(this, og, C), o(this, Q, i), o(this, eg, s);
1213
- } else {
1214
- const { backgroundTex: C, obstacleTex: i, coverageTex: s } = GC(
1215
- g,
1216
- I(this, U).bitmap,
1217
- I(this, K),
1218
- I(this, H),
1219
- I(this, U).effect,
1220
- I(this, U).size,
1221
- I(this, N),
1222
- I(this, Lg)
1223
- );
1224
- o(this, og, C), o(this, Q, i), o(this, eg, s);
1225
- }
1226
- }
1227
- o(this, xg, !0);
1228
- }
1229
- }, Dg = new WeakSet(), AI = function() {
1230
- I(this, xg) && !this.isRunning && this.start();
1231
- }, rI = new WeakSet(), JI = function() {
1232
- var g, C, i, s, t, l, u, Z;
1233
- if (I(this, F))
1234
- (g = I(this, x)) == null || g.dispose(), (C = I(this, b)) == null || C.dispose(), (i = I(this, sg)) == null || i.dispose(), (s = I(this, Gg)) == null || s.tex.destroy(), (t = I(this, pg)) == null || t.tex.destroy(), o(this, x, o(this, b, o(this, sg, null))), o(this, Gg, o(this, pg, null));
1235
- else {
1236
- const d = I(this, j);
1237
- (l = I(this, M)) == null || l.dispose(), (u = I(this, X)) == null || u.dispose(), (Z = I(this, Cg)) == null || Z.dispose(), I(this, Ig) && (d.deleteTexture(I(this, Ig).tex), d.deleteFramebuffer(I(this, Ig).fbo)), I(this, ig) && (d.deleteTexture(I(this, ig).tex), d.deleteFramebuffer(I(this, ig).fbo)), o(this, M, o(this, X, o(this, Cg, o(this, Ig, o(this, ig, null)))));
1238
- }
1239
- }, GI = new WeakSet(), zI = function() {
1240
- if (I(this, F))
1241
- I(this, E) && (I(this, E).backgroundTex.destroy(), I(this, E).obstacleTex.destroy(), I(this, E).sharedCoverage || I(this, E).coverageTex.destroy(), o(this, E, null));
1242
- else {
1243
- const g = I(this, j);
1244
- I(this, og) && g.deleteTexture(I(this, og)), I(this, Q) && g.deleteTexture(I(this, Q)), I(this, eg) && I(this, eg) !== I(this, Q) && g.deleteTexture(I(this, eg)), o(this, og, o(this, Q, o(this, eg, null)));
1245
- }
1246
- }, vI = new WeakSet(), lC = function() {
1247
- !I(this, xg) || I(this, K) === 0 || (I(this, F) ? h(this, WI, oC).call(this) : h(this, YI, AC).call(this));
1248
- }, WI = new WeakSet(), oC = function() {
1249
- const g = I(this, F), C = g.device, i = I(this, jg), s = I(this, Xg), t = I(this, Pg), l = I(this, ug), u = I(this, E);
1250
- if (!I(this, x) || !I(this, b))
1251
- return;
1252
- I(this, L).x += (I(this, L).targetX - I(this, L).x) * 0.15, I(this, L).y += (I(this, L).targetY - I(this, L).y) * 0.15;
1253
- const Z = I(this, P), d = I(this, _), S = I(this, K), a = I(this, H), c = 1 / Z, m = 1 / d;
1254
- _I(C, I(this, Hg), c, m, cI, l.velocityDissipation), hI(C, I(this, Wg), c, m), hI(C, I(this, Rg), c, m), hI(C, I(this, Ug), c, m), hI(C, I(this, Yg), c, m), OC(C, I(this, kg), c, m, l.curl, cI), jC(
1255
- C,
1256
- I(this, Mg),
1257
- 1 / S,
1258
- 1 / a,
1259
- l.refraction,
1260
- l.specularExp,
1261
- wI(l.waterColor),
1262
- wI(l.glowColor),
1263
- l.shine,
1264
- l.warpStrength ?? 0.015,
1265
- $I[l.algorithm] ?? 0,
1266
- I(this, fg)
1267
- );
1268
- const B = C.createCommandEncoder(), r = (n, y) => C.createBindGroup({ layout: n.getBindGroupLayout(0), entries: y }), w = { binding: 1, resource: t };
1269
- {
1270
- const n = r(i.advection, [
1271
- { binding: 0, resource: { buffer: I(this, Hg) } },
1272
- w,
1273
- { binding: 2, resource: I(this, b).read.view },
1274
- { binding: 3, resource: I(this, b).read.view },
1275
- { binding: 4, resource: u.obstacleView }
1276
- ]);
1277
- O(B, i.advection, n, s, I(this, b).write.view);
1278
- }
1279
- I(this, b).swap();
1280
- {
1281
- _I(C, I(this, vg), c, m, cI, l.densityDissipation);
1282
- const n = r(i.advection, [
1283
- { binding: 0, resource: { buffer: I(this, vg) } },
1284
- w,
1285
- { binding: 2, resource: I(this, b).read.view },
1286
- { binding: 3, resource: I(this, x).read.view },
1287
- { binding: 4, resource: u.obstacleView }
1288
- ]);
1289
- O(B, i.advection, n, s, I(this, x).write.view);
1290
- }
1291
- I(this, x).swap();
1292
- {
1293
- const n = r(i.curl, [
1294
- { binding: 0, resource: { buffer: I(this, Yg) } },
1295
- w,
1296
- { binding: 2, resource: I(this, b).read.view }
1297
- ]);
1298
- O(B, i.curl, n, s, I(this, pg).view);
1299
- }
1300
- {
1301
- const n = r(i.vorticity, [
1302
- { binding: 0, resource: { buffer: I(this, kg) } },
1303
- w,
1304
- { binding: 2, resource: I(this, b).read.view },
1305
- { binding: 3, resource: I(this, pg).view }
1306
- ]);
1307
- O(B, i.vorticity, n, s, I(this, b).write.view);
1308
- }
1309
- if (I(this, b).swap(), I(this, L).moved) {
1310
- const n = I(this, L).x * I(this, D) / S, y = I(this, L).y * I(this, D) / a;
1311
- bI(
1312
- C,
1313
- I(this, cg),
1314
- c,
1315
- m,
1316
- S / a,
1317
- l.splatRadius,
1318
- I(this, L).dx * l.splatForce,
1319
- I(this, L).dy * l.splatForce,
1320
- 0,
1321
- n,
1322
- y
1323
- );
1324
- {
1325
- const v = r(i.splat, [
1326
- { binding: 0, resource: { buffer: I(this, cg) } },
1327
- w,
1328
- { binding: 2, resource: I(this, b).read.view }
1329
- ]);
1330
- O(B, i.splat, v, s, I(this, b).write.view);
1331
- }
1332
- I(this, b).swap(), bI(
1333
- C,
1334
- I(this, dg),
1335
- c,
1336
- m,
1337
- S / a,
1338
- l.splatRadius,
1339
- 1,
1340
- 1,
1341
- 1,
1342
- n,
1343
- y
1344
- );
1345
- {
1346
- const v = r(i.splat, [
1347
- { binding: 0, resource: { buffer: I(this, dg) } },
1348
- w,
1349
- { binding: 2, resource: I(this, x).read.view }
1350
- ]);
1351
- O(B, i.splat, v, s, I(this, x).write.view);
1352
- }
1353
- I(this, x).swap(), I(this, L).moved = !1;
1354
- }
1355
- {
1356
- const n = r(i.divergence, [
1357
- { binding: 0, resource: { buffer: I(this, Wg) } },
1358
- w,
1359
- { binding: 2, resource: I(this, b).read.view },
1360
- { binding: 3, resource: u.obstacleView }
1361
- ]);
1362
- O(B, i.divergence, n, s, I(this, Gg).view);
1363
- }
1364
- for (let n = 0; n < l.pressureIterations; n++) {
1365
- const y = r(i.pressure, [
1366
- { binding: 0, resource: { buffer: I(this, Rg) } },
1367
- w,
1368
- { binding: 2, resource: I(this, sg).read.view },
1369
- { binding: 3, resource: I(this, Gg).view },
1370
- { binding: 4, resource: u.obstacleView }
1371
- ]);
1372
- O(B, i.pressure, y, s, I(this, sg).write.view), I(this, sg).swap();
1373
- }
1374
- {
1375
- const n = r(i.gradientSubtract, [
1376
- { binding: 0, resource: { buffer: I(this, Ug) } },
1377
- w,
1378
- { binding: 2, resource: I(this, sg).read.view },
1379
- { binding: 3, resource: I(this, b).read.view },
1380
- { binding: 4, resource: u.obstacleView }
1381
- ]);
1382
- O(B, i.gradientSubtract, n, s, I(this, b).write.view);
1383
- }
1384
- I(this, b).swap();
1385
- {
1386
- const n = g.context.getCurrentTexture().createView(), y = r(i.display, [
1387
- { binding: 0, resource: { buffer: I(this, Mg) } },
1388
- w,
1389
- { binding: 2, resource: I(this, x).read.view },
1390
- { binding: 3, resource: u.obstacleView },
1391
- { binding: 4, resource: u.backgroundView },
1392
- { binding: 5, resource: u.coverageView },
1393
- { binding: 6, resource: I(this, b).read.view }
1394
- ]);
1395
- PC(B, i.display, y, s, n);
1396
- }
1397
- C.queue.submit([B.finish()]);
1398
- }, RI = new WeakSet(), cC = function(g, C, i, s, t) {
1399
- const u = I(this, F).device, Z = I(this, jg).splat, d = I(this, Xg), S = I(this, Pg), a = I(this, ug), c = I(this, P), m = I(this, _), B = 1 / c, r = 1 / m, w = u.createCommandEncoder(), n = { binding: 1, resource: S }, y = (T) => u.createBindGroup({ layout: Z.getBindGroupLayout(0), entries: T }), v = g * I(this, D) / I(this, K), Y = C * I(this, D) / I(this, H);
1400
- bI(
1401
- u,
1402
- I(this, cg),
1403
- B,
1404
- r,
1405
- I(this, K) / I(this, H),
1406
- a.splatRadius,
1407
- i * a.splatForce * t,
1408
- s * a.splatForce * t,
1409
- 0,
1410
- v,
1411
- Y
1412
- );
1413
- {
1414
- const T = y([
1415
- { binding: 0, resource: { buffer: I(this, cg) } },
1416
- n,
1417
- { binding: 2, resource: I(this, b).read.view }
1418
- ]);
1419
- O(w, Z, T, d, I(this, b).write.view);
1420
- }
1421
- I(this, b).swap(), bI(
1422
- u,
1423
- I(this, dg),
1424
- B,
1425
- r,
1426
- I(this, K) / I(this, H),
1427
- a.splatRadius,
1428
- t,
1429
- t,
1430
- t,
1431
- v,
1432
- Y
1433
- );
1434
- {
1435
- const T = y([
1436
- { binding: 0, resource: { buffer: I(this, dg) } },
1437
- n,
1438
- { binding: 2, resource: I(this, x).read.view }
1439
- ]);
1440
- O(w, Z, T, d, I(this, x).write.view);
1441
- }
1442
- I(this, x).swap(), u.queue.submit([w.finish()]);
1443
- }, UI = new WeakSet(), dC = function(g, C, i, s, t) {
1444
- const l = I(this, j), u = I(this, ug), Z = I(this, Kg).splat, d = I(this, Og);
1445
- l.viewport(0, 0, I(this, P), I(this, _)), Z.bind(), l.uniform1f(Z.uniforms.aspectRatio, I(this, K) / I(this, H)), l.uniform2f(Z.uniforms.point, g * I(this, D) / I(this, K), 1 - C * I(this, D) / I(this, H)), l.uniform1f(Z.uniforms.radius, u.splatRadius), l.uniform1i(Z.uniforms.uTarget, 0), l.activeTexture(l.TEXTURE0), l.bindTexture(l.TEXTURE_2D, I(this, X).read.tex), l.uniform3f(Z.uniforms.color, i * u.splatForce * t, -s * u.splatForce * t, 0), d(I(this, X).write.fbo), I(this, X).swap(), l.activeTexture(l.TEXTURE0), l.bindTexture(l.TEXTURE_2D, I(this, M).read.tex), l.uniform3f(Z.uniforms.color, t, t, t), d(I(this, M).write.fbo), I(this, M).swap();
1446
- }, YI = new WeakSet(), AC = function() {
1447
- if (!I(this, M) || !I(this, X))
1448
- return;
1449
- const g = I(this, j), C = I(this, ug), { advection: i, divergence: s, pressure: t, gradientSubtract: l, splat: u, curl: Z, vorticity: d, display: S } = I(this, Kg);
1450
- I(this, L).x += (I(this, L).targetX - I(this, L).x) * 0.15, I(this, L).y += (I(this, L).targetY - I(this, L).y) * 0.15;
1451
- const a = I(this, P), c = I(this, _), m = I(this, Og);
1452
- g.viewport(0, 0, a, c), i.bind(), g.uniform2f(i.uniforms.texelSize, 1 / a, 1 / c), g.uniform1f(i.uniforms.dt, cI), g.uniform1i(i.uniforms.uObstacle, 0), g.activeTexture(g.TEXTURE0), g.bindTexture(g.TEXTURE_2D, I(this, Q)), g.uniform1f(i.uniforms.dissipation, C.velocityDissipation), g.uniform1i(i.uniforms.uVelocity, 1), g.activeTexture(g.TEXTURE1), g.bindTexture(g.TEXTURE_2D, I(this, X).read.tex), g.uniform1i(i.uniforms.uSource, 1), m(I(this, X).write.fbo), I(this, X).swap(), g.uniform1f(i.uniforms.dissipation, C.densityDissipation), g.uniform1i(i.uniforms.uSource, 2), g.activeTexture(g.TEXTURE2), g.bindTexture(g.TEXTURE_2D, I(this, M).read.tex), m(I(this, M).write.fbo), I(this, M).swap(), Z.bind(), g.uniform2f(Z.uniforms.texelSize, 1 / a, 1 / c), g.uniform1i(Z.uniforms.uVelocity, 0), g.activeTexture(g.TEXTURE0), g.bindTexture(g.TEXTURE_2D, I(this, X).read.tex), m(I(this, ig).fbo), d.bind(), g.uniform2f(d.uniforms.texelSize, 1 / a, 1 / c), g.uniform1f(d.uniforms.curl, C.curl), g.uniform1f(d.uniforms.dt, cI), g.uniform1i(d.uniforms.uVelocity, 0), g.activeTexture(g.TEXTURE0), g.bindTexture(g.TEXTURE_2D, I(this, X).read.tex), g.uniform1i(d.uniforms.uCurl, 1), g.activeTexture(g.TEXTURE1), g.bindTexture(g.TEXTURE_2D, I(this, ig).tex), m(I(this, X).write.fbo), I(this, X).swap(), I(this, L).moved && (u.bind(), g.uniform1f(u.uniforms.aspectRatio, I(this, K) / I(this, H)), g.uniform2f(u.uniforms.point, I(this, L).x * I(this, D) / I(this, K), 1 - I(this, L).y * I(this, D) / I(this, H)), g.uniform1f(u.uniforms.radius, C.splatRadius), g.uniform1i(u.uniforms.uTarget, 0), g.activeTexture(g.TEXTURE0), g.bindTexture(g.TEXTURE_2D, I(this, X).read.tex), g.uniform3f(u.uniforms.color, I(this, L).dx * C.splatForce, -I(this, L).dy * C.splatForce, 0), m(I(this, X).write.fbo), I(this, X).swap(), g.activeTexture(g.TEXTURE0), g.bindTexture(g.TEXTURE_2D, I(this, M).read.tex), g.uniform3f(u.uniforms.color, 1, 1, 1), m(I(this, M).write.fbo), I(this, M).swap(), I(this, L).moved = !1), s.bind(), g.uniform2f(s.uniforms.texelSize, 1 / a, 1 / c), g.uniform1i(s.uniforms.uVelocity, 0), g.activeTexture(g.TEXTURE0), g.bindTexture(g.TEXTURE_2D, I(this, X).read.tex), g.uniform1i(s.uniforms.uObstacle, 1), g.activeTexture(g.TEXTURE1), g.bindTexture(g.TEXTURE_2D, I(this, Q)), m(I(this, Ig).fbo), t.bind(), g.uniform2f(t.uniforms.texelSize, 1 / a, 1 / c), g.uniform1i(t.uniforms.uDivergence, 0), g.activeTexture(g.TEXTURE0), g.bindTexture(g.TEXTURE_2D, I(this, Ig).tex), g.uniform1i(t.uniforms.uObstacle, 1), g.activeTexture(g.TEXTURE1), g.bindTexture(g.TEXTURE_2D, I(this, Q));
1453
- for (let B = 0; B < C.pressureIterations; B++)
1454
- g.uniform1i(t.uniforms.uPressure, 2), g.activeTexture(g.TEXTURE2), g.bindTexture(g.TEXTURE_2D, I(this, Cg).read.tex), m(I(this, Cg).write.fbo), I(this, Cg).swap();
1455
- l.bind(), g.uniform2f(l.uniforms.texelSize, 1 / a, 1 / c), g.uniform1i(l.uniforms.uPressure, 0), g.activeTexture(g.TEXTURE0), g.bindTexture(g.TEXTURE_2D, I(this, Cg).read.tex), g.uniform1i(l.uniforms.uVelocity, 1), g.activeTexture(g.TEXTURE1), g.bindTexture(g.TEXTURE_2D, I(this, X).read.tex), g.uniform1i(l.uniforms.uObstacle, 2), g.activeTexture(g.TEXTURE2), g.bindTexture(g.TEXTURE_2D, I(this, Q)), m(I(this, X).write.fbo), I(this, X).swap(), g.viewport(0, 0, I(this, K), I(this, H)), g.bindFramebuffer(g.FRAMEBUFFER, null), g.clear(g.COLOR_BUFFER_BIT), S.bind(), g.uniform2f(S.uniforms.texelSize, 1 / I(this, K), 1 / I(this, H)), g.uniform3fv(S.uniforms.uWaterColor, wI(C.waterColor)), g.uniform3fv(S.uniforms.uGlowColor, wI(C.glowColor)), g.uniform1f(S.uniforms.uRefraction, C.refraction), g.uniform1f(S.uniforms.uSpecularExp, C.specularExp), g.uniform1f(S.uniforms.uShine, C.shine), g.uniform1f(S.uniforms.uWarpStrength, C.warpStrength ?? 0.015), g.uniform1i(S.uniforms.uAlgorithm, $I[C.algorithm] ?? 0), g.uniform1i(S.uniforms.uEnableAlpha, I(this, fg) ? 1 : 0), g.activeTexture(g.TEXTURE0), g.bindTexture(g.TEXTURE_2D, I(this, M).read.tex), g.activeTexture(g.TEXTURE1), g.bindTexture(g.TEXTURE_2D, I(this, Q)), g.activeTexture(g.TEXTURE2), g.bindTexture(g.TEXTURE_2D, I(this, og)), g.activeTexture(g.TEXTURE3), g.bindTexture(g.TEXTURE_2D, I(this, eg)), g.activeTexture(g.TEXTURE4), g.bindTexture(g.TEXTURE_2D, I(this, X).read.tex), g.uniform1i(S.uniforms.uTexture, 0), g.uniform1i(S.uniforms.uObstacle, 1), g.uniform1i(S.uniforms.uBackground, 2), g.uniform1i(S.uniforms.uCoverage, 3), g.uniform1i(S.uniforms.uVelocity, 4), m(null);
1456
- };
1457
- let XI = EI;
1458
- const uC="var yt = Object.defineProperty;\nvar St = (i, e, r) => e in i ? yt(i, e, { enumerable: !0, configurable: !0, writable: !0, value: r }) : i[e] = r;\nvar ke = (i, e, r) => (St(i, typeof e != \"symbol\" ? e + \"\" : e, r), r), tt = (i, e, r) => {\n if (!e.has(i))\n throw TypeError(\"Cannot \" + r);\n};\nvar t = (i, e, r) => (tt(i, e, \"read from private field\"), r ? r.call(i) : e.get(i)), f = (i, e, r) => {\n if (e.has(i))\n throw TypeError(\"Cannot add the same private member more than once\");\n e instanceof WeakSet ? e.add(i) : e.set(i, r);\n}, l = (i, e, r, s) => (tt(i, e, \"write to private field\"), s ? s.call(i, r) : e.set(i, r), r);\nvar S = (i, e, r) => (tt(i, e, \"access private method\"), r);\nconst xt = {\n densityDissipation: 0.83,\n velocityDissipation: 0.91,\n pressureIterations: 1,\n curl: 0,\n splatRadius: 0.1,\n splatForce: 0.08,\n refraction: 1,\n specularExp: 0,\n shine: 0,\n waterColor: \"#000000\",\n glowColor: \"#b3d9ff\",\n algorithm: \"aurora\",\n warpStrength: 0.04\n};\n({\n ...xt\n});\nconst Rt = {\n calm: {\n densityDissipation: 0.98,\n velocityDissipation: 0.81,\n curl: 1e-4,\n splatRadius: 0.05,\n splatForce: 0.08,\n refraction: 0.15,\n shine: 0.03,\n glowColor: \"#99d9ff\",\n waterColor: \"#00050d\"\n },\n sand: {\n densityDissipation: 0.95,\n velocityDissipation: 0.81,\n curl: 1,\n splatRadius: 0.23,\n splatForce: 0.16,\n refraction: 0.8,\n specularExp: 0,\n shine: 0.33,\n glowColor: \"#070707\",\n waterColor: \"#735420\"\n },\n wave: {\n densityDissipation: 0.9,\n velocityDissipation: 0.2,\n curl: 0.2,\n splatRadius: 0.1,\n splatForce: 0.22,\n refraction: 0.35,\n shine: 0.2,\n glowColor: \"#80ccff\",\n waterColor: \"#000308\"\n },\n neon: {\n densityDissipation: 0.75,\n velocityDissipation: 0.3,\n curl: 0.05,\n splatRadius: 0.18,\n splatForce: 0.29,\n refraction: 0.25,\n specularExp: 0.04,\n shine: 0.93,\n glowColor: \"#ff33cc\",\n waterColor: \"#0d0014\"\n },\n smoke: {\n densityDissipation: 0.93,\n velocityDissipation: 0.71,\n curl: 0.04,\n splatRadius: 0.21,\n splatForce: 0.14,\n refraction: 0.08,\n shine: 0,\n glowColor: \"#808080\",\n waterColor: \"#0f0f0f\"\n }\n};\nfunction Ne(i) {\n if (Array.isArray(i))\n return i;\n const e = i.slice(1, 7);\n return e.length === 3 ? [\n parseInt(e[0] + e[0], 16) / 255,\n parseInt(e[1] + e[1], 16) / 255,\n parseInt(e[2] + e[2], 16) / 255\n ] : [\n parseInt(e.slice(0, 2), 16) / 255,\n parseInt(e.slice(2, 4), 16) / 255,\n parseInt(e.slice(4, 6), 16) / 255\n ];\n}\nfunction wt(i = {}, e, r = xt) {\n return { ...e ? { ...r, ...Rt[e] } : r, ...i };\n}\nconst re = `precision highp float;\nattribute vec2 aPosition;\nvarying vec2 vUv;\nvarying vec2 vL; varying vec2 vR; varying vec2 vT; varying vec2 vB;\nuniform vec2 texelSize;\nvoid main () {\nvUv = aPosition * 0.5 + 0.5;\nvL = vUv - vec2(texelSize.x, 0.0);\nvR = vUv + vec2(texelSize.x, 0.0);\nvT = vUv + vec2(0.0, texelSize.y);\nvB = vUv - vec2(0.0, texelSize.y);\ngl_Position = vec4(aPosition, 0.0, 1.0);\n}`, Et = `precision highp float;\nvarying vec2 vUv;\nuniform sampler2D uVelocity;\nuniform sampler2D uSource;\nuniform sampler2D uObstacle;\nuniform vec2 texelSize;\nuniform float dt;\nuniform float dissipation;\nvoid main () {\nfloat obs = texture2D(uObstacle, vUv).r;\nvec2 coord = vUv - dt * texture2D(uVelocity, vUv).xy * texelSize;\ngl_FragColor = dissipation * texture2D(uSource, coord) * (1.0 - obs);\n}`, Ut = `precision highp float;\nvarying vec2 vL; varying vec2 vR; varying vec2 vT; varying vec2 vB;\nuniform sampler2D uVelocity;\nuniform sampler2D uObstacle;\nvoid main () {\nfloat L = texture2D(uVelocity, vL).x * (1.0 - texture2D(uObstacle, vL).r);\nfloat R = texture2D(uVelocity, vR).x * (1.0 - texture2D(uObstacle, vR).r);\nfloat T = texture2D(uVelocity, vT).y * (1.0 - texture2D(uObstacle, vT).r);\nfloat B = texture2D(uVelocity, vB).y * (1.0 - texture2D(uObstacle, vB).r);\ngl_FragColor = vec4(0.5 * (R - L + T - B), 0.0, 0.0, 1.0);\n}`, Dt = `precision highp float;\nvarying vec2 vUv; varying vec2 vL; varying vec2 vR; varying vec2 vT; varying vec2 vB;\nuniform sampler2D uPressure;\nuniform sampler2D uDivergence;\nuniform sampler2D uObstacle;\nvoid main () {\nfloat C = texture2D(uPressure, vUv).x;\nfloat L = mix(texture2D(uPressure, vL).x, C, texture2D(uObstacle, vL).r);\nfloat R = mix(texture2D(uPressure, vR).x, C, texture2D(uObstacle, vR).r);\nfloat T = mix(texture2D(uPressure, vT).x, C, texture2D(uObstacle, vT).r);\nfloat B = mix(texture2D(uPressure, vB).x, C, texture2D(uObstacle, vB).r);\nfloat div = texture2D(uDivergence, vUv).x;\ngl_FragColor = vec4((L + R + B + T - div) * 0.25, 0.0, 0.0, 1.0);\n}`, _t = `precision highp float;\nvarying vec2 vUv; varying vec2 vL; varying vec2 vR; varying vec2 vT; varying vec2 vB;\nuniform sampler2D uPressure;\nuniform sampler2D uVelocity;\nuniform sampler2D uObstacle;\nvoid main () {\nfloat obs = texture2D(uObstacle, vUv).r;\nfloat C = texture2D(uPressure, vUv).x;\nfloat L = mix(texture2D(uPressure, vL).x, C, texture2D(uObstacle, vL).r);\nfloat R = mix(texture2D(uPressure, vR).x, C, texture2D(uObstacle, vR).r);\nfloat T = mix(texture2D(uPressure, vT).x, C, texture2D(uObstacle, vT).r);\nfloat B = mix(texture2D(uPressure, vB).x, C, texture2D(uObstacle, vB).r);\nvec2 vel = (texture2D(uVelocity, vUv).xy - vec2(R - L, T - B)) * (1.0 - obs);\ngl_FragColor = vec4(vel, 0.0, 1.0);\n}`, Ct = `precision highp float;\nvarying vec2 vUv;\nuniform sampler2D uTarget;\nuniform float aspectRatio;\nuniform vec3 color;\nuniform vec2 point;\nuniform float radius;\nvoid main () {\nvec2 p = vUv - point.xy;\np.x *= aspectRatio;\nvec3 splat = exp(-dot(p, p) / radius) * color;\ngl_FragColor = vec4(texture2D(uTarget, vUv).xyz + splat, 1.0);\n}`, Bt = `precision highp float;\nvarying vec2 vL; varying vec2 vR; varying vec2 vT; varying vec2 vB;\nuniform sampler2D uVelocity;\nvoid main () {\nfloat L = texture2D(uVelocity, vL).y;\nfloat R = texture2D(uVelocity, vR).y;\nfloat T = texture2D(uVelocity, vT).x;\nfloat B = texture2D(uVelocity, vB).x;\ngl_FragColor = vec4(0.5 * (R - L - T + B), 0.0, 0.0, 1.0);\n}`, Ot = `precision highp float;\nvarying vec2 vUv; varying vec2 vL; varying vec2 vR; varying vec2 vT; varying vec2 vB;\nuniform sampler2D uVelocity;\nuniform sampler2D uCurl;\nuniform float curl;\nuniform float dt;\nvoid main () {\nfloat L = texture2D(uCurl, vL).x;\nfloat R = texture2D(uCurl, vR).x;\nfloat T = texture2D(uCurl, vT).x;\nfloat B = texture2D(uCurl, vB).x;\nfloat C = texture2D(uCurl, vUv).x;\nvec2 force = 0.5 * vec2(abs(T) - abs(B), abs(R) - abs(L));\nforce /= length(force) + 0.0001;\nforce *= curl * 30.0 * C;\ngl_FragColor = vec4(texture2D(uVelocity, vUv).xy + force * dt, 0.0, 1.0);\n}`, Vt = `precision highp float;\nvarying vec2 vUv;\nuniform sampler2D uTexture;\nuniform sampler2D uObstacle;\nuniform sampler2D uBackground;\nuniform sampler2D uCoverage;\nuniform sampler2D uVelocity;\nuniform vec2 texelSize;\nuniform vec3 uWaterColor;\nuniform vec3 uGlowColor;\nuniform float uRefraction;\nuniform float uSpecularExp;\nuniform float uShine;\nuniform float uWarpStrength;\nuniform int uAlgorithm;\nuniform int uEnableAlpha;\nvoid main () {\nfloat obs = texture2D(uObstacle, vUv).r;\nfloat density = max(texture2D(uTexture, vUv).r, 0.0) * (1.0 - obs);\nfloat coverage = texture2D(uCoverage, vUv).r;\nfloat sx = texelSize.x * 6.0, sy = texelSize.y * 6.0;\nfloat d00 = max(texture2D(uTexture, vUv + vec2(-sx, -sy)).r, 0.0);\nfloat d10 = max(texture2D(uTexture, vUv + vec2(0.0, -sy)).r, 0.0);\nfloat d20 = max(texture2D(uTexture, vUv + vec2( sx, -sy)).r, 0.0);\nfloat d01 = max(texture2D(uTexture, vUv + vec2(-sx, 0.0)).r, 0.0);\nfloat d21 = max(texture2D(uTexture, vUv + vec2( sx, 0.0)).r, 0.0);\nfloat d02 = max(texture2D(uTexture, vUv + vec2(-sx, sy)).r, 0.0);\nfloat d12 = max(texture2D(uTexture, vUv + vec2(0.0, sy)).r, 0.0);\nfloat d22 = max(texture2D(uTexture, vUv + vec2( sx, sy)).r, 0.0);\nfloat gx = (d20 + 2.0*d21 + d22) - (d00 + 2.0*d01 + d02);\nfloat gy = (d02 + 2.0*d12 + d22) - (d00 + 2.0*d10 + d20);\nvec3 normal = normalize(vec3(gx, gy, 1.2));\nvec3 lightDir = normalize(vec3(0.5, 1.0, 0.5));\nvec3 halfV = normalize(lightDir + vec3(0.0, 0.0, 1.0));\nfloat specDen = density * min(density * 5.0, 1.0);\nfloat spec = pow(max(dot(normal, halfV), 0.0), uSpecularExp) * uShine * specDen;\nvec3 bgRaw = texture2D(uBackground, vUv).rgb;\nvec3 bg = mix(uWaterColor, bgRaw, coverage);\nvec3 color = bg;\nif (uAlgorithm == 1) {\nvec2 refrUv = clamp(vUv + normal.xy * uRefraction * density * 3.0, 0.0, 1.0);\nvec3 refrBg = mix(uWaterColor, texture2D(uBackground, mix(vUv, refrUv, 1.0 - obs)).rgb, coverage);\ncolor = refrBg + spec * uGlowColor * 2.5;\ncolor = mix(color, bg * 0.6, obs * 0.3);\n} else if (uAlgorithm == 2) {\nfloat inkD = min(density * 4.0, 1.0);\nvec2 refrUv = clamp(vUv + normal.xy * uRefraction * density * 0.4, 0.0, 1.0);\nvec3 refrBg = mix(uWaterColor, texture2D(uBackground, mix(vUv, refrUv, 1.0 - obs)).rgb, coverage);\ncolor = mix(refrBg, uWaterColor + spec * uGlowColor, inkD);\ncolor = mix(color, bg * 0.5, obs * 0.15);\n} else if (uAlgorithm == 3) {\nvec2 vel = texture2D(uVelocity, vUv).xy;\nfloat velMag = clamp(length(vel) * 20.0, 0.0, 1.0);\nvec2 warpUv = clamp(vUv + vel * uWarpStrength, 0.0, 1.0);\nvec3 warpBg = mix(uWaterColor, texture2D(uBackground, warpUv).rgb, coverage);\ncolor = mix(bg, warpBg, velMag * (1.0 - obs));\ncolor += spec * uGlowColor * velMag * 1.5;\ncolor += uWaterColor * density * 0.3;\ncolor = mix(color, bg * 0.5, obs * 0.2);\n} else if (uAlgorithm == 4) {\nvec2 rippleUv = clamp(vUv + normal.xy * uRefraction * density * 6.0, 0.0, 1.0);\nvec3 refrBg = mix(uWaterColor, texture2D(uBackground, mix(vUv, rippleUv, 1.0 - obs)).rgb, coverage);\nfloat fresnel = pow(clamp(1.0 - dot(normal, vec3(0.0, 0.0, 1.0)), 0.0, 1.0), 3.0) * density;\ncolor = refrBg;\ncolor += fresnel * uGlowColor * 2.0;\ncolor += spec * uGlowColor * density * 2.0;\ncolor = mix(color, bg * 0.5, obs * 0.2);\n} else {\nvec2 refrUv = vUv + normal.xy * uRefraction * density;\nvec3 refrBg = mix(uWaterColor, texture2D(uBackground, mix(vUv, refrUv, 1.0 - obs)).rgb, coverage);\ncolor = mix(refrBg, uWaterColor, min(density * 1.5, 0.8));\ncolor += spec * uGlowColor;\ncolor = mix(color, bg * 0.5, obs * 0.2);\n}\nfloat alpha = clamp(max(density * 1.5, coverage), 0.0, 1.0);\nif (uEnableAlpha == 1) {\ngl_FragColor = vec4(color * alpha, alpha);\n} else {\ngl_FragColor = vec4(color, 1.0);\n}\n}`;\nfunction Pt(i, e = !0) {\n const r = { alpha: e, depth: !1, stencil: !1, antialias: !0, preserveDrawingBuffer: !1 };\n let s = i.getContext(\"webgl2\", r);\n const o = !!s;\n o || (s = i.getContext(\"webgl\", r), s.getExtension(\"EXT_color_buffer_half_float\"));\n const a = o ? null : s.getExtension(\"OES_texture_half_float\"), u = o ? s.HALF_FLOAT : a.HALF_FLOAT_OES;\n return s.getExtension(\"EXT_color_buffer_float\"), s.getExtension(\"OES_texture_half_float_linear\"), {\n type: o ? \"webgl2\" : \"webgl1\",\n gl: s,\n isWebGL2: o,\n ext: {\n internalFormat: o ? s.RGBA16F : s.RGBA,\n format: s.RGBA,\n type: u\n }\n };\n}\nasync function Ft(i, e = !0) {\n if (typeof navigator > \"u\" || !navigator.gpu)\n return null;\n try {\n const r = await navigator.gpu.requestAdapter();\n if (!r)\n return null;\n const s = await r.requestDevice(), o = i.getContext(\"webgpu\");\n if (!o)\n return null;\n const a = navigator.gpu.getPreferredCanvasFormat();\n return o.configure({ device: s, format: a, alphaMode: e ? \"premultiplied\" : \"opaque\" }), { type: \"webgpu\", adapter: r, device: s, context: o, format: a };\n } catch {\n return null;\n }\n}\nclass ie {\n constructor(e, r, s) {\n ke(this, \"program\");\n ke(this, \"uniforms\", {});\n ke(this, \"_gl\");\n this._gl = e, this.program = e.createProgram(), e.attachShader(this.program, this._compile(e.VERTEX_SHADER, r)), e.attachShader(this.program, this._compile(e.FRAGMENT_SHADER, s)), e.linkProgram(this.program);\n const o = e.getProgramParameter(this.program, e.ACTIVE_UNIFORMS);\n for (let a = 0; a < o; a++) {\n const u = e.getActiveUniform(this.program, a).name;\n this.uniforms[u] = e.getUniformLocation(this.program, u);\n }\n }\n _compile(e, r) {\n const s = this._gl, o = s.createShader(e);\n return s.shaderSource(o, r), s.compileShader(o), o;\n }\n bind() {\n this._gl.useProgram(this.program);\n }\n dispose() {\n this._gl.deleteProgram(this.program);\n }\n}\nfunction Lt(i) {\n return {\n advection: new ie(i, re, Et),\n divergence: new ie(i, re, Ut),\n pressure: new ie(i, re, Dt),\n gradientSubtract: new ie(i, re, _t),\n splat: new ie(i, re, Ct),\n curl: new ie(i, re, Bt),\n vorticity: new ie(i, re, Ot),\n display: new ie(i, re, Vt)\n };\n}\nfunction He(i, e, r, s) {\n i.activeTexture(i.TEXTURE0);\n const o = i.createTexture();\n i.bindTexture(i.TEXTURE_2D, o), i.texParameteri(i.TEXTURE_2D, i.TEXTURE_MIN_FILTER, i.LINEAR), i.texParameteri(i.TEXTURE_2D, i.TEXTURE_MAG_FILTER, i.LINEAR), i.texParameteri(i.TEXTURE_2D, i.TEXTURE_WRAP_S, i.CLAMP_TO_EDGE), i.texParameteri(i.TEXTURE_2D, i.TEXTURE_WRAP_T, i.CLAMP_TO_EDGE), i.texImage2D(i.TEXTURE_2D, 0, e.internalFormat, r, s, 0, e.format, e.type, null);\n const a = i.createFramebuffer();\n return i.bindFramebuffer(i.FRAMEBUFFER, a), i.framebufferTexture2D(i.FRAMEBUFFER, i.COLOR_ATTACHMENT0, i.TEXTURE_2D, o, 0), { tex: o, fbo: a, width: r, height: s };\n}\nfunction rt(i, e, r, s) {\n let o = He(i, e, r, s), a = He(i, e, r, s);\n return {\n get read() {\n return o;\n },\n get write() {\n return a;\n },\n swap() {\n [o, a] = [a, o];\n },\n dispose() {\n i.deleteTexture(o.tex), i.deleteFramebuffer(o.fbo), i.deleteTexture(a.tex), i.deleteFramebuffer(a.fbo);\n }\n };\n}\nfunction At(i) {\n const e = i.createBuffer();\n return i.bindBuffer(i.ARRAY_BUFFER, e), i.bufferData(i.ARRAY_BUFFER, new Float32Array([-1, -1, -1, 1, 1, 1, 1, -1]), i.STATIC_DRAW), i.vertexAttribPointer(0, 2, i.FLOAT, !1, 0, 0), i.enableVertexAttribArray(0), function(s) {\n i.bindFramebuffer(i.FRAMEBUFFER, s), i.drawArrays(i.TRIANGLE_FAN, 0, 4);\n };\n}\nconst le = `struct VSOut {\n@builtin(position) pos : vec4f,\n@location(0) uv : vec2f,\n@location(1) vL : vec2f,\n@location(2) vR : vec2f,\n@location(3) vT : vec2f,\n@location(4) vB : vec2f,\n}`, Xt = `${le}\nstruct U {\ntexelSize : vec2f,\ndt : f32,\ndissipation: f32,\n}\n@group(0) @binding(0) var<uniform> u : U;\n@group(0) @binding(1) var samp : sampler;\n@group(0) @binding(2) var uVel : texture_2d<f32>;\n@group(0) @binding(3) var uSrc : texture_2d<f32>;\n@group(0) @binding(4) var uObs : texture_2d<f32>;\n@vertex fn vs(@location(0) a: vec2f) -> VSOut {\nvar o: VSOut;\no.uv = vec2f(a.x * 0.5 + 0.5, 0.5 - a.y * 0.5);\no.vL = o.uv - vec2f(u.texelSize.x, 0.0);\no.vR = o.uv + vec2f(u.texelSize.x, 0.0);\no.vT = o.uv + vec2f(0.0, u.texelSize.y);\no.vB = o.uv - vec2f(0.0, u.texelSize.y);\no.pos = vec4f(a, 0.0, 1.0);\nreturn o;\n}\n@fragment fn fs(i: VSOut) -> @location(0) vec4f {\nlet obs = textureSample(uObs, samp, i.uv).r;\nlet vel = textureSample(uVel, samp, i.uv).xy;\nlet coord = i.uv - u.dt * vel * u.texelSize;\nlet src = textureSample(uSrc, samp, coord);\nreturn u.dissipation * src * (1.0 - obs);\n}`, zt = `${le}\nstruct U { texelSize: vec2f, _pad: vec2f }\n@group(0) @binding(0) var<uniform> u : U;\n@group(0) @binding(1) var samp : sampler;\n@group(0) @binding(2) var uVel : texture_2d<f32>;\n@group(0) @binding(3) var uObs : texture_2d<f32>;\n@vertex fn vs(@location(0) a: vec2f) -> VSOut {\nvar o: VSOut;\no.uv = vec2f(a.x * 0.5 + 0.5, 0.5 - a.y * 0.5);\no.vL = o.uv - vec2f(u.texelSize.x, 0.0);\no.vR = o.uv + vec2f(u.texelSize.x, 0.0);\no.vT = o.uv + vec2f(0.0, u.texelSize.y);\no.vB = o.uv - vec2f(0.0, u.texelSize.y);\no.pos = vec4f(a, 0.0, 1.0);\nreturn o;\n}\n@fragment fn fs(i: VSOut) -> @location(0) vec4f {\nlet L = textureSample(uVel, samp, i.vL).x * (1.0 - textureSample(uObs, samp, i.vL).r);\nlet R = textureSample(uVel, samp, i.vR).x * (1.0 - textureSample(uObs, samp, i.vR).r);\nlet T = textureSample(uVel, samp, i.vT).y * (1.0 - textureSample(uObs, samp, i.vT).r);\nlet B = textureSample(uVel, samp, i.vB).y * (1.0 - textureSample(uObs, samp, i.vB).r);\nreturn vec4f(0.5 * (R - L + T - B), 0.0, 0.0, 1.0);\n}`, Gt = `${le}\nstruct U { texelSize: vec2f, _pad: vec2f }\n@group(0) @binding(0) var<uniform> u : U;\n@group(0) @binding(1) var samp : sampler;\n@group(0) @binding(2) var uPres: texture_2d<f32>;\n@group(0) @binding(3) var uDiv : texture_2d<f32>;\n@group(0) @binding(4) var uObs : texture_2d<f32>;\n@vertex fn vs(@location(0) a: vec2f) -> VSOut {\nvar o: VSOut;\no.uv = vec2f(a.x * 0.5 + 0.5, 0.5 - a.y * 0.5);\no.vL = o.uv - vec2f(u.texelSize.x, 0.0);\no.vR = o.uv + vec2f(u.texelSize.x, 0.0);\no.vT = o.uv + vec2f(0.0, u.texelSize.y);\no.vB = o.uv - vec2f(0.0, u.texelSize.y);\no.pos = vec4f(a, 0.0, 1.0);\nreturn o;\n}\n@fragment fn fs(i: VSOut) -> @location(0) vec4f {\nlet C = textureSample(uPres, samp, i.uv).x;\nlet L = mix(textureSample(uPres, samp, i.vL).x, C, textureSample(uObs, samp, i.vL).r);\nlet R = mix(textureSample(uPres, samp, i.vR).x, C, textureSample(uObs, samp, i.vR).r);\nlet T = mix(textureSample(uPres, samp, i.vT).x, C, textureSample(uObs, samp, i.vT).r);\nlet B = mix(textureSample(uPres, samp, i.vB).x, C, textureSample(uObs, samp, i.vB).r);\nlet dv = textureSample(uDiv, samp, i.uv).x;\nreturn vec4f((L + R + B + T - dv) * 0.25, 0.0, 0.0, 1.0);\n}`, Mt = `${le}\nstruct U { texelSize: vec2f, _pad: vec2f }\n@group(0) @binding(0) var<uniform> u : U;\n@group(0) @binding(1) var samp : sampler;\n@group(0) @binding(2) var uPres: texture_2d<f32>;\n@group(0) @binding(3) var uVel : texture_2d<f32>;\n@group(0) @binding(4) var uObs : texture_2d<f32>;\n@vertex fn vs(@location(0) a: vec2f) -> VSOut {\nvar o: VSOut;\no.uv = vec2f(a.x * 0.5 + 0.5, 0.5 - a.y * 0.5);\no.vL = o.uv - vec2f(u.texelSize.x, 0.0);\no.vR = o.uv + vec2f(u.texelSize.x, 0.0);\no.vT = o.uv + vec2f(0.0, u.texelSize.y);\no.vB = o.uv - vec2f(0.0, u.texelSize.y);\no.pos = vec4f(a, 0.0, 1.0);\nreturn o;\n}\n@fragment fn fs(i: VSOut) -> @location(0) vec4f {\nlet obs = textureSample(uObs, samp, i.uv).r;\nlet C = textureSample(uPres, samp, i.uv).x;\nlet L = mix(textureSample(uPres, samp, i.vL).x, C, textureSample(uObs, samp, i.vL).r);\nlet R = mix(textureSample(uPres, samp, i.vR).x, C, textureSample(uObs, samp, i.vR).r);\nlet T = mix(textureSample(uPres, samp, i.vT).x, C, textureSample(uObs, samp, i.vT).r);\nlet B = mix(textureSample(uPres, samp, i.vB).x, C, textureSample(uObs, samp, i.vB).r);\nlet vel = (textureSample(uVel, samp, i.uv).xy - vec2f(R - L, T - B)) * (1.0 - obs);\nreturn vec4f(vel, 0.0, 1.0);\n}`, It = `${le}\nstruct U {\ntexelSize : vec2f,\naspectRatio: f32,\nradius : f32,\ncolor : vec4f, \npoint : vec2f,\n_pad : vec2f,\n}\n@group(0) @binding(0) var<uniform> u : U;\n@group(0) @binding(1) var samp : sampler;\n@group(0) @binding(2) var uTgt : texture_2d<f32>;\n@vertex fn vs(@location(0) a: vec2f) -> VSOut {\nvar o: VSOut;\no.uv = vec2f(a.x * 0.5 + 0.5, 0.5 - a.y * 0.5);\no.vL = o.uv - vec2f(u.texelSize.x, 0.0);\no.vR = o.uv + vec2f(u.texelSize.x, 0.0);\no.vT = o.uv + vec2f(0.0, u.texelSize.y);\no.vB = o.uv - vec2f(0.0, u.texelSize.y);\no.pos = vec4f(a, 0.0, 1.0);\nreturn o;\n}\n@fragment fn fs(i: VSOut) -> @location(0) vec4f {\nvar p = i.uv - u.point;\np.x *= u.aspectRatio;\nlet sp = exp(-dot(p, p) / u.radius) * u.color.xyz;\nreturn vec4f(textureSample(uTgt, samp, i.uv).xyz + sp, 1.0);\n}`, Wt = `${le}\nstruct U { texelSize: vec2f, _pad: vec2f }\n@group(0) @binding(0) var<uniform> u : U;\n@group(0) @binding(1) var samp : sampler;\n@group(0) @binding(2) var uVel : texture_2d<f32>;\n@vertex fn vs(@location(0) a: vec2f) -> VSOut {\nvar o: VSOut;\no.uv = vec2f(a.x * 0.5 + 0.5, 0.5 - a.y * 0.5);\no.vL = o.uv - vec2f(u.texelSize.x, 0.0);\no.vR = o.uv + vec2f(u.texelSize.x, 0.0);\no.vT = o.uv + vec2f(0.0, u.texelSize.y);\no.vB = o.uv - vec2f(0.0, u.texelSize.y);\no.pos = vec4f(a, 0.0, 1.0);\nreturn o;\n}\n@fragment fn fs(i: VSOut) -> @location(0) vec4f {\nlet L = textureSample(uVel, samp, i.vL).y;\nlet R = textureSample(uVel, samp, i.vR).y;\nlet T = textureSample(uVel, samp, i.vT).x;\nlet B = textureSample(uVel, samp, i.vB).x;\nreturn vec4f(0.5 * (R - L - T + B), 0.0, 0.0, 1.0);\n}`, kt = `${le}\nstruct U {\ntexelSize: vec2f,\ncurl : f32,\ndt : f32,\n}\n@group(0) @binding(0) var<uniform> u : U;\n@group(0) @binding(1) var samp : sampler;\n@group(0) @binding(2) var uVel : texture_2d<f32>;\n@group(0) @binding(3) var uCrl : texture_2d<f32>;\n@vertex fn vs(@location(0) a: vec2f) -> VSOut {\nvar o: VSOut;\no.uv = vec2f(a.x * 0.5 + 0.5, 0.5 - a.y * 0.5);\no.vL = o.uv - vec2f(u.texelSize.x, 0.0);\no.vR = o.uv + vec2f(u.texelSize.x, 0.0);\no.vT = o.uv + vec2f(0.0, u.texelSize.y);\no.vB = o.uv - vec2f(0.0, u.texelSize.y);\no.pos = vec4f(a, 0.0, 1.0);\nreturn o;\n}\n@fragment fn fs(i: VSOut) -> @location(0) vec4f {\nlet L = textureSample(uCrl, samp, i.vL).x;\nlet R = textureSample(uCrl, samp, i.vR).x;\nlet T = textureSample(uCrl, samp, i.vT).x;\nlet B = textureSample(uCrl, samp, i.vB).x;\nlet C = textureSample(uCrl, samp, i.uv).x;\nvar force = 0.5 * vec2f(abs(T) - abs(B), abs(R) - abs(L));\nforce /= length(force) + 0.0001;\nforce *= u.curl * 30.0 * C;\nlet vel = textureSample(uVel, samp, i.uv).xy + force * u.dt;\nreturn vec4f(vel, 0.0, 1.0);\n}`, Nt = `${le}\nstruct U {\ntexelSize : vec2f,\nrefraction : f32,\nspecularExp : f32,\nwaterColor : vec4f,\nglowColor : vec4f,\nshine : f32,\nwarpStrength: f32,\nalgorithm : i32,\nenableAlpha : i32,\n}\n@group(0) @binding(0) var<uniform> u : U;\n@group(0) @binding(1) var samp : sampler;\n@group(0) @binding(2) var uTex : texture_2d<f32>;\n@group(0) @binding(3) var uObs : texture_2d<f32>;\n@group(0) @binding(4) var uBg : texture_2d<f32>;\n@group(0) @binding(5) var uCov : texture_2d<f32>;\n@group(0) @binding(6) var uVel : texture_2d<f32>;\n@vertex fn vs(@location(0) a: vec2f) -> VSOut {\nvar o: VSOut;\no.uv = vec2f(a.x * 0.5 + 0.5, 0.5 - a.y * 0.5);\no.vL = o.uv - vec2f(u.texelSize.x, 0.0);\no.vR = o.uv + vec2f(u.texelSize.x, 0.0);\no.vT = o.uv + vec2f(0.0, u.texelSize.y);\no.vB = o.uv - vec2f(0.0, u.texelSize.y);\no.pos = vec4f(a, 0.0, 1.0);\nreturn o;\n}\n@fragment fn fs(i: VSOut) -> @location(0) vec4f {\nlet obs = textureSample(uObs, samp, i.uv).r;\nlet density = max(textureSample(uTex, samp, i.uv).r, 0.0) * (1.0 - obs);\nlet cov = textureSample(uCov, samp, i.uv).r;\nlet sx = u.texelSize.x * 6.0;\nlet sy = u.texelSize.y * 6.0;\nlet d00 = max(textureSample(uTex, samp, i.uv + vec2f(-sx, -sy)).r, 0.0);\nlet d10 = max(textureSample(uTex, samp, i.uv + vec2f(0.0, -sy)).r, 0.0);\nlet d20 = max(textureSample(uTex, samp, i.uv + vec2f( sx, -sy)).r, 0.0);\nlet d01 = max(textureSample(uTex, samp, i.uv + vec2f(-sx, 0.0)).r, 0.0);\nlet d21 = max(textureSample(uTex, samp, i.uv + vec2f( sx, 0.0)).r, 0.0);\nlet d02 = max(textureSample(uTex, samp, i.uv + vec2f(-sx, sy)).r, 0.0);\nlet d12 = max(textureSample(uTex, samp, i.uv + vec2f(0.0, sy)).r, 0.0);\nlet d22 = max(textureSample(uTex, samp, i.uv + vec2f( sx, sy)).r, 0.0);\nlet gx = (d20 + 2.0*d21 + d22) - (d00 + 2.0*d01 + d02);\nlet gy = (d02 + 2.0*d12 + d22) - (d00 + 2.0*d10 + d20);\nlet norm = normalize(vec3f(gx, gy, 1.2));\nlet ldir = normalize(vec3f(0.5, 1.0, 0.5));\nlet halfV = normalize(ldir + vec3f(0.0, 0.0, 1.0));\nlet specDen = density * min(density * 5.0, 1.0);\nlet spec = pow(max(dot(norm, halfV), 0.0), u.specularExp) * u.shine * specDen;\nlet bgRaw = textureSample(uBg, samp, i.uv).rgb;\nlet wc = u.waterColor.rgb;\nlet gc = u.glowColor.rgb;\nlet bg = mix(wc, bgRaw, cov);\nvar color = bg;\nif (u.algorithm == 1) {\nlet ruv = clamp(i.uv + norm.xy * u.refraction * density * 3.0, vec2f(0.0), vec2f(1.0));\nlet rbg = mix(wc, textureSample(uBg, samp, mix(i.uv, ruv, 1.0 - obs)).rgb, cov);\ncolor = rbg + spec * gc * 2.5;\ncolor = mix(color, bg * 0.6, obs * 0.3);\n} else if (u.algorithm == 2) {\nlet inkD = min(density * 4.0, 1.0);\nlet ruv = clamp(i.uv + norm.xy * u.refraction * density * 0.4, vec2f(0.0), vec2f(1.0));\nlet rbg = mix(wc, textureSample(uBg, samp, mix(i.uv, ruv, 1.0 - obs)).rgb, cov);\ncolor = mix(rbg, wc + spec * gc, inkD);\ncolor = mix(color, bg * 0.5, obs * 0.15);\n} else if (u.algorithm == 3) {\nlet vel = textureSample(uVel, samp, i.uv).xy;\nlet velMag = clamp(length(vel) * 20.0, 0.0, 1.0);\nlet wuv = clamp(i.uv + vel * u.warpStrength, vec2f(0.0), vec2f(1.0));\nlet wbg = mix(wc, textureSample(uBg, samp, wuv).rgb, cov);\ncolor = mix(bg, wbg, velMag * (1.0 - obs));\ncolor += spec * gc * velMag * 1.5;\ncolor += wc * density * 0.3;\ncolor = mix(color, bg * 0.5, obs * 0.2);\n} else if (u.algorithm == 4) {\nlet ruv = clamp(i.uv + norm.xy * u.refraction * density * 6.0, vec2f(0.0), vec2f(1.0));\nlet rbg = mix(wc, textureSample(uBg, samp, mix(i.uv, ruv, 1.0 - obs)).rgb, cov);\nlet fres = pow(clamp(1.0 - dot(norm, vec3f(0.0, 0.0, 1.0)), 0.0, 1.0), 3.0) * density;\ncolor = rbg;\ncolor += fres * gc * 2.0;\ncolor += spec * gc * density * 2.0;\ncolor = mix(color, bg * 0.5, obs * 0.2);\n} else {\nlet ruv = i.uv + norm.xy * u.refraction * density;\nlet rbg = mix(wc, textureSample(uBg, samp, mix(i.uv, ruv, 1.0 - obs)).rgb, cov);\ncolor = mix(rbg, wc, min(density * 1.5, 0.8));\ncolor += spec * gc;\ncolor = mix(color, bg * 0.5, obs * 0.2);\n}\nlet alpha = clamp(max(density * 1.5, cov), 0.0, 1.0);\nif (u.enableAlpha == 1) {\nreturn vec4f(color * alpha, alpha);\n}\nreturn vec4f(color, 1.0);\n}`, $t = {\n arrayStride: 8,\n attributes: [{ shaderLocation: 0, offset: 0, format: \"float32x2\" }]\n}, lt = new Float32Array([\n -1,\n -1,\n -1,\n 1,\n 1,\n -1,\n 1,\n -1,\n -1,\n 1,\n 1,\n 1\n]);\nfunction qt(i) {\n const e = i.createBuffer({ size: lt.byteLength, usage: GPUBufferUsage.VERTEX | GPUBufferUsage.COPY_DST });\n return i.queue.writeBuffer(e, 0, lt), e;\n}\nfunction Ye(i, e, r, s) {\n const o = i.createTexture({\n size: [r, s],\n format: e,\n usage: GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.RENDER_ATTACHMENT | GPUTextureUsage.COPY_SRC\n });\n return { tex: o, view: o.createView(), width: r, height: s };\n}\nfunction it(i, e, r, s) {\n let o = Ye(i, e, r, s), a = Ye(i, e, r, s);\n return {\n get read() {\n return o;\n },\n get write() {\n return a;\n },\n swap() {\n [o, a] = [a, o];\n },\n dispose() {\n o.tex.destroy(), a.tex.destroy();\n }\n };\n}\nfunction se(i, e, r, s) {\n const o = i.createShaderModule({ code: e });\n return i.createRenderPipeline({\n layout: \"auto\",\n vertex: { module: o, entryPoint: \"vs\", buffers: [$t] },\n fragment: { module: o, entryPoint: \"fs\", targets: [{ format: r, ...s ? { blend: s } : {} }] },\n primitive: { topology: \"triangle-list\" }\n });\n}\nconst Ht = {\n color: { operation: \"add\", srcFactor: \"one\", dstFactor: \"zero\" },\n alpha: { operation: \"add\", srcFactor: \"one\", dstFactor: \"zero\" }\n};\nfunction Yt(i, e, r = !0) {\n const s = \"rgba16float\";\n return {\n advection: se(i, Xt, s),\n divergence: se(i, zt, s),\n pressure: se(i, Gt, s),\n gradientSubtract: se(i, Mt, s),\n splat: se(i, It, s),\n curl: se(i, Wt, s),\n vorticity: se(i, kt, s),\n display: se(i, Nt, e, r ? void 0 : Ht)\n };\n}\nfunction Qt(i) {\n return i.createSampler({ magFilter: \"linear\", minFilter: \"linear\", addressModeU: \"clamp-to-edge\", addressModeV: \"clamp-to-edge\" });\n}\nfunction k(i, e) {\n return i.createBuffer({ size: e, usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST });\n}\nfunction ct(i, e, r, s, o, a) {\n const u = new Float32Array([r, s, o, a]);\n i.queue.writeBuffer(e, 0, u);\n}\nfunction $e(i, e, r, s) {\n const o = new Float32Array([r, s, 0, 0]);\n i.queue.writeBuffer(e, 0, o);\n}\nfunction jt(i, e, r, s, o, a) {\n const u = new Float32Array([r, s, o, a]);\n i.queue.writeBuffer(e, 0, u);\n}\nfunction qe(i, e, r, s, o, a, u, v, p, c, m) {\n const x = new Float32Array(12);\n x[0] = r, x[1] = s, x[2] = o, x[3] = a, x[4] = u, x[5] = v, x[6] = p, x[7] = 0, x[8] = c, x[9] = m, x[10] = 0, x[11] = 0, i.queue.writeBuffer(e, 0, x);\n}\nfunction Kt(i, e, r, s, o, a, u, v, p, c, m, x) {\n const n = new Float32Array(16), d = new Int32Array(n.buffer);\n n[0] = r, n[1] = s, n[2] = o, n[3] = a, n[4] = u[0], n[5] = u[1], n[6] = u[2], n[7] = 0, n[8] = v[0], n[9] = v[1], n[10] = v[2], n[11] = 0, n[12] = p, n[13] = c, d[14] = m, d[15] = x ? 1 : 0, i.queue.writeBuffer(e, 0, n);\n}\nfunction z(i, e, r, s, o) {\n const a = i.beginRenderPass({\n colorAttachments: [{\n view: o,\n clearValue: [0, 0, 0, 0],\n loadOp: \"clear\",\n storeOp: \"store\"\n }]\n });\n a.setPipeline(e), a.setBindGroup(0, r), a.setVertexBuffer(0, s), a.draw(6), a.end();\n}\nfunction Jt(i, e, r, s, o) {\n const a = i.beginRenderPass({\n colorAttachments: [{\n view: o,\n clearValue: [0, 0, 0, 0],\n loadOp: \"clear\",\n storeOp: \"store\"\n }]\n });\n a.setPipeline(e), a.setBindGroup(0, r), a.setVertexBuffer(0, s), a.draw(6), a.end();\n}\nfunction Be(i, e, r, s, o = \"cover\") {\n let a;\n o === \"cover\" ? a = Math.max(r / i, s / e) : o === \"contain\" ? a = Math.min(r / i, s / e) : typeof o == \"string\" && o.endsWith(\"%\") ? a = Math.min(r / i, s / e) * (parseFloat(o) / 100) : typeof o == \"string\" && o.endsWith(\"px\") ? a = parseFloat(o) / Math.max(i, e) : typeof o == \"number\" ? a = o : a = Math.max(r / i, s / e);\n const u = i * a, v = e * a;\n return { x: (r - u) / 2, y: (s - v) / 2, drawW: u, drawH: v };\n}\nfunction Zt(i, e, r, s, o = null, a = \"cover\") {\n const { text: u, fontSize: v, color: p, fontFamily: c = \"sans-serif\", fontWeight: m = 900 } = s, x = new OffscreenCanvas(e, r), n = x.getContext(\"2d\");\n ((D) => {\n if (o) {\n n.clearRect(0, 0, e, r), n.fillStyle = \"black\", n.fillRect(0, 0, e, r);\n const { x: g, y: _, drawW: F, drawH: W } = Be(\n o.width,\n o.height,\n e,\n r,\n a\n );\n n.drawImage(o, g, _, F, W);\n } else\n n.fillStyle = \"black\", n.fillRect(0, 0, e, r);\n n.fillStyle = D, n.font = `${m} ${v}px ${c}`, n.textAlign = \"center\", n.textBaseline = \"middle\", n.fillText(u, e / 2, r / 2);\n })(p);\n const b = Le(i, x);\n n.fillStyle = \"black\", n.fillRect(0, 0, e, r), n.fillStyle = \"white\", n.font = `${m} ${v}px ${c}`, n.textAlign = \"center\", n.textBaseline = \"middle\", n.fillText(u, e / 2, r / 2);\n const y = Le(i, x);\n return { backgroundTex: b, obstacleTex: y, coverageTex: y };\n}\nfunction er(i, e, r, s, o = 0, a = \"cover\", u = null, v = \"cover\") {\n const p = new OffscreenCanvas(r, s), c = p.getContext(\"2d\"), { x: m, y: x, drawW: n, drawH: d } = Be(e.width, e.height, r, s, a);\n if (c.clearRect(0, 0, r, s), c.fillStyle = \"black\", c.fillRect(0, 0, r, s), u) {\n const {\n x: g,\n y: _,\n drawW: F,\n drawH: W\n } = Be(u.width, u.height, r, s, v);\n c.filter = `brightness(${o}) blur(8px)`, c.drawImage(u, g, _, F, W), c.filter = \"none\";\n }\n c.drawImage(e, m, x, n, d);\n const b = Le(i, p);\n c.clearRect(0, 0, r, s), c.fillStyle = \"black\", c.fillRect(0, 0, r, s), c.filter = `brightness(${o}) blur(8px)`, c.drawImage(e, m, x, n, d), c.filter = \"none\";\n const y = Le(i, p);\n c.clearRect(0, 0, r, s), c.fillStyle = \"black\", c.fillRect(0, 0, r, s), c.fillStyle = \"white\", c.fillRect(\n Math.max(0, m),\n Math.max(0, x),\n Math.min(n, r - Math.max(0, m)),\n Math.min(d, s - Math.max(0, x))\n );\n const D = Le(i, p);\n return { backgroundTex: b, obstacleTex: y, coverageTex: D };\n}\nfunction Le(i, e) {\n const r = i.createTexture();\n return i.bindTexture(i.TEXTURE_2D, r), i.pixelStorei(i.UNPACK_FLIP_Y_WEBGL, !0), i.texImage2D(i.TEXTURE_2D, 0, i.RGBA, i.RGBA, i.UNSIGNED_BYTE, e), i.texParameteri(i.TEXTURE_2D, i.TEXTURE_MIN_FILTER, i.LINEAR), i.texParameteri(i.TEXTURE_2D, i.TEXTURE_MAG_FILTER, i.LINEAR), i.texParameteri(i.TEXTURE_2D, i.TEXTURE_WRAP_S, i.CLAMP_TO_EDGE), i.texParameteri(i.TEXTURE_2D, i.TEXTURE_WRAP_T, i.CLAMP_TO_EDGE), r;\n}\nfunction tr(i, e, r, s, o = null, a = \"cover\") {\n const { text: u, fontSize: v, color: p, fontFamily: c = \"sans-serif\", fontWeight: m = 900 } = s, x = new OffscreenCanvas(e, r), n = x.getContext(\"2d\");\n ((D) => {\n if (o) {\n n.clearRect(0, 0, e, r), n.fillStyle = \"black\", n.fillRect(0, 0, e, r);\n const { x: g, y: _, drawW: F, drawH: W } = Be(\n o.width,\n o.height,\n e,\n r,\n a\n );\n n.drawImage(o, g, _, F, W);\n } else\n n.fillStyle = \"black\", n.fillRect(0, 0, e, r);\n n.fillStyle = D, n.font = `${m} ${v}px ${c}`, n.textAlign = \"center\", n.textBaseline = \"middle\", n.fillText(u, e / 2, r / 2);\n })(p);\n const b = Ae(i, x, e, r);\n n.fillStyle = \"black\", n.fillRect(0, 0, e, r), n.fillStyle = \"white\", n.font = `${m} ${v}px ${c}`, n.textAlign = \"center\", n.textBaseline = \"middle\", n.fillText(u, e / 2, r / 2);\n const y = Ae(i, x, e, r);\n return {\n backgroundTex: b,\n backgroundView: b.createView(),\n obstacleTex: y,\n obstacleView: y.createView(),\n coverageTex: y,\n coverageView: y.createView(),\n sharedCoverage: !0\n };\n}\nfunction rr(i, e, r, s, o = 0, a = \"cover\", u = null, v = \"cover\") {\n const p = new OffscreenCanvas(r, s), c = p.getContext(\"2d\"), { x: m, y: x, drawW: n, drawH: d } = Be(e.width, e.height, r, s, a);\n if (c.clearRect(0, 0, r, s), c.fillStyle = \"black\", c.fillRect(0, 0, r, s), u) {\n const { x: g, y: _, drawW: F, drawH: W } = Be(\n u.width,\n u.height,\n r,\n s,\n v\n );\n c.filter = `brightness(${o}) blur(8px)`, c.drawImage(u, g, _, F, W), c.filter = \"none\";\n }\n c.drawImage(e, m, x, n, d);\n const b = Ae(i, p, r, s);\n c.clearRect(0, 0, r, s), c.fillStyle = \"black\", c.fillRect(0, 0, r, s), c.filter = `brightness(${o}) blur(8px)`, c.drawImage(e, m, x, n, d), c.filter = \"none\";\n const y = Ae(i, p, r, s);\n c.clearRect(0, 0, r, s), c.fillStyle = \"black\", c.fillRect(0, 0, r, s), c.fillStyle = \"white\", c.fillRect(Math.max(0, m), Math.max(0, x), Math.min(n, r - Math.max(0, m)), Math.min(d, s - Math.max(0, x)));\n const D = Ae(i, p, r, s);\n return {\n backgroundTex: b,\n backgroundView: b.createView(),\n obstacleTex: y,\n obstacleView: y.createView(),\n coverageTex: D,\n coverageView: D.createView(),\n sharedCoverage: !1\n };\n}\nfunction Ae(i, e, r, s) {\n const o = i.createTexture({\n size: [r, s],\n format: \"rgba8unorm\",\n usage: GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.COPY_DST | GPUTextureUsage.RENDER_ATTACHMENT\n });\n return i.queue.copyExternalImageToTexture(\n { source: e },\n { texture: o },\n [r, s]\n ), o;\n}\nasync function ir(i) {\n const e = await fetch(i);\n if (!e.ok)\n throw new Error(`Failed to fetch image: ${i} (${e.status})`);\n const r = await e.blob();\n return createImageBitmap(r);\n}\nconst ft = typeof requestAnimationFrame < \"u\" ? requestAnimationFrame.bind(globalThis) : (i) => setTimeout(i, 1e3 / 60), sr = typeof cancelAnimationFrame < \"u\" ? cancelAnimationFrame.bind(globalThis) : clearTimeout, Ve = 0.016, vt = { standard: 0, glass: 1, ink: 2, aurora: 3, ripple: 4 };\nvar ce, G, Xe, fe, Ue, B, w, $, q, H, K, L, Y, V, De, ve, _e, O, T, oe, Q, ae, X, xe, me, pe, de, he, J, Z, ge, be, Te, R, U, M, I, P, Ce, ee, A, ue, te, h, ze, C, j, ye, Ge, Se, Qe, mt, Re, Pe, Me, ot, ne, Ee, we, Fe, Ie, at, We, ut, je, pt, Ke, dt, Je, ht, Ze, gt, et, bt;\nconst nt = class nt {\n // ── Constructor ─────────────────────────────────────────────────────────────\n constructor(e, r = {}, s = {}, o, a = !0) {\n // ---------------------------------------------------------------------------\n // Private — GPU initialisation\n // ---------------------------------------------------------------------------\n f(this, Qe);\n // ---------------------------------------------------------------------------\n // Private — shared helpers\n // ---------------------------------------------------------------------------\n f(this, Re);\n f(this, Me);\n f(this, ne);\n f(this, we);\n f(this, Ie);\n f(this, We);\n // ---------------------------------------------------------------------------\n // Private — frame dispatch\n // ---------------------------------------------------------------------------\n f(this, je);\n // ---------------------------------------------------------------------------\n // Private — WebGPU simulation step\n // ---------------------------------------------------------------------------\n f(this, Ke);\n // ---------------------------------------------------------------------------\n // Private — WebGPU direct splat\n // ---------------------------------------------------------------------------\n f(this, Je);\n // ---------------------------------------------------------------------------\n // Private — WebGL splat\n // ---------------------------------------------------------------------------\n f(this, Ze);\n // ---------------------------------------------------------------------------\n // Private — WebGL simulation step (unchanged from original)\n // ---------------------------------------------------------------------------\n f(this, et);\n f(this, ce, void 0);\n // ── WebGL path ──────────────────────────────────────────────────────────────\n f(this, G, null);\n f(this, Xe, null);\n f(this, fe, null);\n f(this, Ue, null);\n f(this, B, null);\n f(this, w, null);\n f(this, $, null);\n f(this, q, null);\n f(this, H, null);\n f(this, K, null);\n f(this, L, null);\n f(this, Y, null);\n // ── WebGPU path ─────────────────────────────────────────────────────────────\n f(this, V, null);\n f(this, De, null);\n f(this, ve, null);\n f(this, _e, null);\n f(this, O, null);\n f(this, T, null);\n f(this, oe, null);\n f(this, Q, null);\n f(this, ae, null);\n f(this, X, null);\n // Pre-allocated uniform buffers (sizes: see gpu-utils writeXxx docs)\n // Velocity/density advection use separate buffers — writeBuffer is a queue op;\n // a second write to the same buffer before queue.submit() aliases both passes.\n f(this, xe, null);\n // 16 bytes — velocity advection\n f(this, me, null);\n // 16 bytes — density advection\n f(this, pe, null);\n // 16 bytes\n f(this, de, null);\n // 16 bytes\n f(this, he, null);\n // 16 bytes\n f(this, J, null);\n // 48 bytes — velocity splat\n f(this, Z, null);\n // 48 bytes — density splat\n f(this, ge, null);\n // 16 bytes\n f(this, be, null);\n // 16 bytes\n f(this, Te, null);\n // 64 bytes\n // ── Shared state ────────────────────────────────────────────────────────────\n f(this, R, 0);\n f(this, U, 0);\n f(this, M, 0);\n f(this, I, 0);\n f(this, P, 1);\n f(this, Ce, 1);\n f(this, ee, 0.5);\n f(this, A, null);\n f(this, ue, \"cover\");\n f(this, te, void 0);\n f(this, h, { x: 0, y: 0, dx: 0, dy: 0, targetX: 0, targetY: 0, moved: !1 });\n f(this, ze, !1);\n f(this, C, null);\n f(this, j, null);\n f(this, ye, !1);\n f(this, Ge, !1);\n f(this, Se, !0);\n if (l(this, ce, e), l(this, Ce, Math.max(0.1, Math.min(1, s.dpr ?? 1))), l(this, ee, Math.max(0.1, Math.min(1, s.sim ?? 0.5))), l(this, te, wt(r)), l(this, Se, a), o)\n l(this, V, o), S(this, Qe, mt).call(this, o);\n else {\n const { gl: u, ext: v } = Pt(e, a);\n l(this, G, u), l(this, Xe, v), l(this, fe, Lt(u)), l(this, Ue, At(u)), u.clearColor(0, 0, 0, a ? 0 : 1);\n }\n }\n /**\n * WebGPU-first factory. Tries WebGPU, falls back to WebGL2 → WebGL1.\n * This is the recommended entry point when WebGPU support is desired.\n */\n static async create(e, r = {}, s = {}, o = !0, a = !0) {\n const u = o ? await Ft(e, a) : null;\n return new nt(e, r, s, u ?? void 0, a);\n }\n // ---------------------------------------------------------------------------\n // Public API\n // ---------------------------------------------------------------------------\n setTextSource(e) {\n l(this, C, { type: \"text\", opts: e }), S(this, Re, Pe).call(this), S(this, ne, Ee).call(this), S(this, we, Fe).call(this);\n }\n async setImageSource(e, r = 0, s = \"cover\") {\n const o = await ir(e);\n if (t(this, Ge)) {\n o.close();\n return;\n }\n l(this, C, { type: \"image\", bitmap: o, effect: r, size: s }), S(this, Re, Pe).call(this), S(this, ne, Ee).call(this), S(this, we, Fe).call(this);\n }\n setImageBitmap(e, r = 0, s = \"cover\") {\n l(this, C, { type: \"image\", bitmap: e, effect: r, size: s }), S(this, Re, Pe).call(this), S(this, ne, Ee).call(this), S(this, we, Fe).call(this);\n }\n setBackground(e, r = \"cover\") {\n t(this, A) && t(this, A) !== e && t(this, A).close(), l(this, A, e), l(this, ue, r ?? \"cover\"), t(this, C) && t(this, R) > 0 && t(this, U) > 0 && S(this, ne, Ee).call(this);\n }\n handleMove(e, r, s = 1) {\n if (!t(this, ze)) {\n t(this, h).x = t(this, h).targetX = e, t(this, h).y = t(this, h).targetY = r, l(this, ze, !0);\n return;\n }\n t(this, h).moved = !0, t(this, h).dx = (e - t(this, h).targetX) * s, t(this, h).dy = (r - t(this, h).targetY) * s, t(this, h).targetX = e, t(this, h).targetY = r;\n }\n /**\n * Immediately applies one fluid splat at (x, y) with explicit velocity (vx, vy).\n * Safe to call multiple times per frame — each call writes directly to the FBOs.\n * Designed for programmatic use cases (e.g. particle systems, attractor paths)\n * where you want N independent injection points per frame without flooding the\n * mouse-state machine or the worker message queue.\n */\n splat(e, r, s, o, a = 1) {\n !t(this, ye) || t(this, R) === 0 || (t(this, V) ? S(this, Je, ht).call(this, e, r, s, o, a) : S(this, Ze, gt).call(this, e, r, s, o, a));\n }\n updateQuality(e) {\n e.dpr !== void 0 && l(this, Ce, Math.max(0.1, Math.min(1, e.dpr))), e.sim !== void 0 && l(this, ee, Math.max(0.1, Math.min(1, e.sim)));\n }\n resize(e, r, s) {\n if (s !== void 0 ? l(this, P, s) : typeof window < \"u\" && window.devicePixelRatio && l(this, P, window.devicePixelRatio), e !== void 0 && e > 0) {\n if (r === void 0 || r <= 0)\n return;\n l(this, R, t(this, ce).width = e), l(this, U, t(this, ce).height = r), l(this, M, Math.max(1, Math.round(e * t(this, ee)))), l(this, I, Math.max(1, Math.round(r * t(this, ee)))), S(this, Me, ot).call(this);\n } else\n S(this, Re, Pe).call(this);\n t(this, C) && S(this, ne, Ee).call(this), S(this, we, Fe).call(this);\n }\n updateConfig(e) {\n Object.assign(t(this, te), e);\n }\n destroy() {\n var e, r, s, o, a, u, v, p, c, m, x;\n if (l(this, Ge, !0), this.stop(), S(this, Ie, at).call(this), S(this, We, ut).call(this), t(this, A) && (t(this, A).close(), l(this, A, null)), t(this, V))\n (e = t(this, xe)) == null || e.destroy(), (r = t(this, me)) == null || r.destroy(), (s = t(this, pe)) == null || s.destroy(), (o = t(this, de)) == null || o.destroy(), (a = t(this, he)) == null || a.destroy(), (u = t(this, J)) == null || u.destroy(), (v = t(this, Z)) == null || v.destroy(), (p = t(this, ge)) == null || p.destroy(), (c = t(this, be)) == null || c.destroy(), (m = t(this, Te)) == null || m.destroy(), (x = t(this, ve)) == null || x.destroy(), t(this, V).device.destroy();\n else {\n const n = t(this, G);\n for (const b of Object.values(t(this, fe)))\n b.dispose();\n const d = n.getExtension(\"WEBGL_lose_context\");\n d == null || d.loseContext();\n }\n }\n // ---------------------------------------------------------------------------\n // Loop control\n // ---------------------------------------------------------------------------\n start() {\n if (t(this, j) !== null)\n return;\n const e = () => {\n S(this, je, pt).call(this), l(this, j, ft(e));\n };\n l(this, j, ft(e));\n }\n stop() {\n t(this, j) !== null && (sr(t(this, j)), l(this, j, null));\n }\n get isRunning() {\n return t(this, j) !== null;\n }\n};\nce = new WeakMap(), G = new WeakMap(), Xe = new WeakMap(), fe = new WeakMap(), Ue = new WeakMap(), B = new WeakMap(), w = new WeakMap(), $ = new WeakMap(), q = new WeakMap(), H = new WeakMap(), K = new WeakMap(), L = new WeakMap(), Y = new WeakMap(), V = new WeakMap(), De = new WeakMap(), ve = new WeakMap(), _e = new WeakMap(), O = new WeakMap(), T = new WeakMap(), oe = new WeakMap(), Q = new WeakMap(), ae = new WeakMap(), X = new WeakMap(), xe = new WeakMap(), me = new WeakMap(), pe = new WeakMap(), de = new WeakMap(), he = new WeakMap(), J = new WeakMap(), Z = new WeakMap(), ge = new WeakMap(), be = new WeakMap(), Te = new WeakMap(), R = new WeakMap(), U = new WeakMap(), M = new WeakMap(), I = new WeakMap(), P = new WeakMap(), Ce = new WeakMap(), ee = new WeakMap(), A = new WeakMap(), ue = new WeakMap(), te = new WeakMap(), h = new WeakMap(), ze = new WeakMap(), C = new WeakMap(), j = new WeakMap(), ye = new WeakMap(), Ge = new WeakMap(), Se = new WeakMap(), Qe = new WeakSet(), mt = function(e) {\n const { device: r, format: s } = e;\n l(this, De, Yt(r, s, t(this, Se))), l(this, ve, qt(r)), l(this, _e, Qt(r)), l(this, xe, k(r, 16)), l(this, me, k(r, 16)), l(this, pe, k(r, 16)), l(this, de, k(r, 16)), l(this, he, k(r, 16)), l(this, J, k(r, 48)), l(this, Z, k(r, 48)), l(this, ge, k(r, 16)), l(this, be, k(r, 16)), l(this, Te, k(r, 64));\n}, Re = new WeakSet(), Pe = function() {\n const e = t(this, ce);\n \"clientWidth\" in e && e.clientWidth > 0 ? (l(this, P, (typeof window < \"u\" && window.devicePixelRatio || 1) * t(this, Ce)), l(this, R, e.width = Math.round(e.clientWidth * t(this, P))), l(this, U, e.height = Math.round(e.clientHeight * t(this, P)))) : (l(this, R, e.width), l(this, U, e.height)), !(t(this, R) === 0 || t(this, U) === 0) && (l(this, M, Math.max(1, Math.round(t(this, R) * t(this, ee)))), l(this, I, Math.max(1, Math.round(t(this, U) * t(this, ee)))), S(this, Me, ot).call(this));\n}, Me = new WeakSet(), ot = function() {\n if (S(this, Ie, at).call(this), t(this, V)) {\n const { device: e } = t(this, V), r = \"rgba16float\", s = t(this, M), o = t(this, I);\n l(this, O, it(e, r, s, o)), l(this, T, it(e, r, s, o)), l(this, Q, it(e, r, s, o)), l(this, oe, Ye(e, r, s, o)), l(this, ae, Ye(e, r, s, o));\n } else {\n const e = t(this, G), r = t(this, Xe), s = t(this, M), o = t(this, I);\n l(this, B, rt(e, r, s, o)), l(this, w, rt(e, r, s, o)), l(this, q, rt(e, r, s, o)), l(this, $, He(e, r, s, o)), l(this, H, He(e, r, s, o));\n }\n}, ne = new WeakSet(), Ee = function() {\n if (!(!t(this, C) || t(this, R) === 0 || t(this, U) === 0)) {\n if (S(this, We, ut).call(this), t(this, V)) {\n const { device: e } = t(this, V);\n t(this, C).type === \"text\" ? l(this, X, tr(\n e,\n t(this, R),\n t(this, U),\n t(this, C).opts,\n t(this, A),\n t(this, ue)\n )) : l(this, X, rr(\n e,\n t(this, C).bitmap,\n t(this, R),\n t(this, U),\n t(this, C).effect,\n t(this, C).size,\n t(this, A),\n t(this, ue)\n ));\n } else {\n const e = t(this, G);\n if (t(this, C).type === \"text\") {\n const { backgroundTex: r, obstacleTex: s, coverageTex: o } = Zt(\n e,\n t(this, R),\n t(this, U),\n t(this, C).opts,\n t(this, A),\n t(this, ue)\n );\n l(this, K, r), l(this, L, s), l(this, Y, o);\n } else {\n const { backgroundTex: r, obstacleTex: s, coverageTex: o } = er(\n e,\n t(this, C).bitmap,\n t(this, R),\n t(this, U),\n t(this, C).effect,\n t(this, C).size,\n t(this, A),\n t(this, ue)\n );\n l(this, K, r), l(this, L, s), l(this, Y, o);\n }\n }\n l(this, ye, !0);\n }\n}, we = new WeakSet(), Fe = function() {\n t(this, ye) && !this.isRunning && this.start();\n}, Ie = new WeakSet(), at = function() {\n var e, r, s, o, a, u, v, p;\n if (t(this, V))\n (e = t(this, O)) == null || e.dispose(), (r = t(this, T)) == null || r.dispose(), (s = t(this, Q)) == null || s.dispose(), (o = t(this, oe)) == null || o.tex.destroy(), (a = t(this, ae)) == null || a.tex.destroy(), l(this, O, l(this, T, l(this, Q, null))), l(this, oe, l(this, ae, null));\n else {\n const c = t(this, G);\n (u = t(this, B)) == null || u.dispose(), (v = t(this, w)) == null || v.dispose(), (p = t(this, q)) == null || p.dispose(), t(this, $) && (c.deleteTexture(t(this, $).tex), c.deleteFramebuffer(t(this, $).fbo)), t(this, H) && (c.deleteTexture(t(this, H).tex), c.deleteFramebuffer(t(this, H).fbo)), l(this, B, l(this, w, l(this, q, l(this, $, l(this, H, null)))));\n }\n}, We = new WeakSet(), ut = function() {\n if (t(this, V))\n t(this, X) && (t(this, X).backgroundTex.destroy(), t(this, X).obstacleTex.destroy(), t(this, X).sharedCoverage || t(this, X).coverageTex.destroy(), l(this, X, null));\n else {\n const e = t(this, G);\n t(this, K) && e.deleteTexture(t(this, K)), t(this, L) && e.deleteTexture(t(this, L)), t(this, Y) && t(this, Y) !== t(this, L) && e.deleteTexture(t(this, Y)), l(this, K, l(this, L, l(this, Y, null)));\n }\n}, je = new WeakSet(), pt = function() {\n !t(this, ye) || t(this, R) === 0 || (t(this, V) ? S(this, Ke, dt).call(this) : S(this, et, bt).call(this));\n}, Ke = new WeakSet(), dt = function() {\n const e = t(this, V), r = e.device, s = t(this, De), o = t(this, ve), a = t(this, _e), u = t(this, te), v = t(this, X);\n if (!t(this, O) || !t(this, T))\n return;\n t(this, h).x += (t(this, h).targetX - t(this, h).x) * 0.15, t(this, h).y += (t(this, h).targetY - t(this, h).y) * 0.15;\n const p = t(this, M), c = t(this, I), m = t(this, R), x = t(this, U), n = 1 / p, d = 1 / c;\n ct(r, t(this, xe), n, d, Ve, u.velocityDissipation), $e(r, t(this, pe), n, d), $e(r, t(this, de), n, d), $e(r, t(this, he), n, d), $e(r, t(this, ge), n, d), jt(r, t(this, be), n, d, u.curl, Ve), Kt(\n r,\n t(this, Te),\n 1 / m,\n 1 / x,\n u.refraction,\n u.specularExp,\n Ne(u.waterColor),\n Ne(u.glowColor),\n u.shine,\n u.warpStrength ?? 0.015,\n vt[u.algorithm] ?? 0,\n t(this, Se)\n );\n const b = r.createCommandEncoder(), y = (g, _) => r.createBindGroup({ layout: g.getBindGroupLayout(0), entries: _ }), D = { binding: 1, resource: a };\n {\n const g = y(s.advection, [\n { binding: 0, resource: { buffer: t(this, xe) } },\n D,\n { binding: 2, resource: t(this, T).read.view },\n { binding: 3, resource: t(this, T).read.view },\n { binding: 4, resource: v.obstacleView }\n ]);\n z(b, s.advection, g, o, t(this, T).write.view);\n }\n t(this, T).swap();\n {\n ct(r, t(this, me), n, d, Ve, u.densityDissipation);\n const g = y(s.advection, [\n { binding: 0, resource: { buffer: t(this, me) } },\n D,\n { binding: 2, resource: t(this, T).read.view },\n { binding: 3, resource: t(this, O).read.view },\n { binding: 4, resource: v.obstacleView }\n ]);\n z(b, s.advection, g, o, t(this, O).write.view);\n }\n t(this, O).swap();\n {\n const g = y(s.curl, [\n { binding: 0, resource: { buffer: t(this, ge) } },\n D,\n { binding: 2, resource: t(this, T).read.view }\n ]);\n z(b, s.curl, g, o, t(this, ae).view);\n }\n {\n const g = y(s.vorticity, [\n { binding: 0, resource: { buffer: t(this, be) } },\n D,\n { binding: 2, resource: t(this, T).read.view },\n { binding: 3, resource: t(this, ae).view }\n ]);\n z(b, s.vorticity, g, o, t(this, T).write.view);\n }\n if (t(this, T).swap(), t(this, h).moved) {\n const g = t(this, h).x * t(this, P) / m, _ = t(this, h).y * t(this, P) / x;\n qe(\n r,\n t(this, J),\n n,\n d,\n m / x,\n u.splatRadius,\n t(this, h).dx * u.splatForce,\n t(this, h).dy * u.splatForce,\n 0,\n g,\n _\n );\n {\n const F = y(s.splat, [\n { binding: 0, resource: { buffer: t(this, J) } },\n D,\n { binding: 2, resource: t(this, T).read.view }\n ]);\n z(b, s.splat, F, o, t(this, T).write.view);\n }\n t(this, T).swap(), qe(\n r,\n t(this, Z),\n n,\n d,\n m / x,\n u.splatRadius,\n 1,\n 1,\n 1,\n g,\n _\n );\n {\n const F = y(s.splat, [\n { binding: 0, resource: { buffer: t(this, Z) } },\n D,\n { binding: 2, resource: t(this, O).read.view }\n ]);\n z(b, s.splat, F, o, t(this, O).write.view);\n }\n t(this, O).swap(), t(this, h).moved = !1;\n }\n {\n const g = y(s.divergence, [\n { binding: 0, resource: { buffer: t(this, pe) } },\n D,\n { binding: 2, resource: t(this, T).read.view },\n { binding: 3, resource: v.obstacleView }\n ]);\n z(b, s.divergence, g, o, t(this, oe).view);\n }\n for (let g = 0; g < u.pressureIterations; g++) {\n const _ = y(s.pressure, [\n { binding: 0, resource: { buffer: t(this, de) } },\n D,\n { binding: 2, resource: t(this, Q).read.view },\n { binding: 3, resource: t(this, oe).view },\n { binding: 4, resource: v.obstacleView }\n ]);\n z(b, s.pressure, _, o, t(this, Q).write.view), t(this, Q).swap();\n }\n {\n const g = y(s.gradientSubtract, [\n { binding: 0, resource: { buffer: t(this, he) } },\n D,\n { binding: 2, resource: t(this, Q).read.view },\n { binding: 3, resource: t(this, T).read.view },\n { binding: 4, resource: v.obstacleView }\n ]);\n z(b, s.gradientSubtract, g, o, t(this, T).write.view);\n }\n t(this, T).swap();\n {\n const g = e.context.getCurrentTexture().createView(), _ = y(s.display, [\n { binding: 0, resource: { buffer: t(this, Te) } },\n D,\n { binding: 2, resource: t(this, O).read.view },\n { binding: 3, resource: v.obstacleView },\n { binding: 4, resource: v.backgroundView },\n { binding: 5, resource: v.coverageView },\n { binding: 6, resource: t(this, T).read.view }\n ]);\n Jt(b, s.display, _, o, g);\n }\n r.queue.submit([b.finish()]);\n}, Je = new WeakSet(), ht = function(e, r, s, o, a) {\n const v = t(this, V).device, p = t(this, De).splat, c = t(this, ve), m = t(this, _e), x = t(this, te), n = t(this, M), d = t(this, I), b = 1 / n, y = 1 / d, D = v.createCommandEncoder(), g = { binding: 1, resource: m }, _ = (Oe) => v.createBindGroup({ layout: p.getBindGroupLayout(0), entries: Oe }), F = e * t(this, P) / t(this, R), W = r * t(this, P) / t(this, U);\n qe(\n v,\n t(this, J),\n b,\n y,\n t(this, R) / t(this, U),\n x.splatRadius,\n s * x.splatForce * a,\n o * x.splatForce * a,\n 0,\n F,\n W\n );\n {\n const Oe = _([\n { binding: 0, resource: { buffer: t(this, J) } },\n g,\n { binding: 2, resource: t(this, T).read.view }\n ]);\n z(D, p, Oe, c, t(this, T).write.view);\n }\n t(this, T).swap(), qe(\n v,\n t(this, Z),\n b,\n y,\n t(this, R) / t(this, U),\n x.splatRadius,\n a,\n a,\n a,\n F,\n W\n );\n {\n const Oe = _([\n { binding: 0, resource: { buffer: t(this, Z) } },\n g,\n { binding: 2, resource: t(this, O).read.view }\n ]);\n z(D, p, Oe, c, t(this, O).write.view);\n }\n t(this, O).swap(), v.queue.submit([D.finish()]);\n}, Ze = new WeakSet(), gt = function(e, r, s, o, a) {\n const u = t(this, G), v = t(this, te), p = t(this, fe).splat, c = t(this, Ue);\n u.viewport(0, 0, t(this, M), t(this, I)), p.bind(), u.uniform1f(p.uniforms.aspectRatio, t(this, R) / t(this, U)), u.uniform2f(p.uniforms.point, e * t(this, P) / t(this, R), 1 - r * t(this, P) / t(this, U)), u.uniform1f(p.uniforms.radius, v.splatRadius), u.uniform1i(p.uniforms.uTarget, 0), u.activeTexture(u.TEXTURE0), u.bindTexture(u.TEXTURE_2D, t(this, w).read.tex), u.uniform3f(p.uniforms.color, s * v.splatForce * a, -o * v.splatForce * a, 0), c(t(this, w).write.fbo), t(this, w).swap(), u.activeTexture(u.TEXTURE0), u.bindTexture(u.TEXTURE_2D, t(this, B).read.tex), u.uniform3f(p.uniforms.color, a, a, a), c(t(this, B).write.fbo), t(this, B).swap();\n}, et = new WeakSet(), bt = function() {\n if (!t(this, B) || !t(this, w))\n return;\n const e = t(this, G), r = t(this, te), { advection: s, divergence: o, pressure: a, gradientSubtract: u, splat: v, curl: p, vorticity: c, display: m } = t(this, fe);\n t(this, h).x += (t(this, h).targetX - t(this, h).x) * 0.15, t(this, h).y += (t(this, h).targetY - t(this, h).y) * 0.15;\n const x = t(this, M), n = t(this, I), d = t(this, Ue);\n e.viewport(0, 0, x, n), s.bind(), e.uniform2f(s.uniforms.texelSize, 1 / x, 1 / n), e.uniform1f(s.uniforms.dt, Ve), e.uniform1i(s.uniforms.uObstacle, 0), e.activeTexture(e.TEXTURE0), e.bindTexture(e.TEXTURE_2D, t(this, L)), e.uniform1f(s.uniforms.dissipation, r.velocityDissipation), e.uniform1i(s.uniforms.uVelocity, 1), e.activeTexture(e.TEXTURE1), e.bindTexture(e.TEXTURE_2D, t(this, w).read.tex), e.uniform1i(s.uniforms.uSource, 1), d(t(this, w).write.fbo), t(this, w).swap(), e.uniform1f(s.uniforms.dissipation, r.densityDissipation), e.uniform1i(s.uniforms.uSource, 2), e.activeTexture(e.TEXTURE2), e.bindTexture(e.TEXTURE_2D, t(this, B).read.tex), d(t(this, B).write.fbo), t(this, B).swap(), p.bind(), e.uniform2f(p.uniforms.texelSize, 1 / x, 1 / n), e.uniform1i(p.uniforms.uVelocity, 0), e.activeTexture(e.TEXTURE0), e.bindTexture(e.TEXTURE_2D, t(this, w).read.tex), d(t(this, H).fbo), c.bind(), e.uniform2f(c.uniforms.texelSize, 1 / x, 1 / n), e.uniform1f(c.uniforms.curl, r.curl), e.uniform1f(c.uniforms.dt, Ve), e.uniform1i(c.uniforms.uVelocity, 0), e.activeTexture(e.TEXTURE0), e.bindTexture(e.TEXTURE_2D, t(this, w).read.tex), e.uniform1i(c.uniforms.uCurl, 1), e.activeTexture(e.TEXTURE1), e.bindTexture(e.TEXTURE_2D, t(this, H).tex), d(t(this, w).write.fbo), t(this, w).swap(), t(this, h).moved && (v.bind(), e.uniform1f(v.uniforms.aspectRatio, t(this, R) / t(this, U)), e.uniform2f(v.uniforms.point, t(this, h).x * t(this, P) / t(this, R), 1 - t(this, h).y * t(this, P) / t(this, U)), e.uniform1f(v.uniforms.radius, r.splatRadius), e.uniform1i(v.uniforms.uTarget, 0), e.activeTexture(e.TEXTURE0), e.bindTexture(e.TEXTURE_2D, t(this, w).read.tex), e.uniform3f(v.uniforms.color, t(this, h).dx * r.splatForce, -t(this, h).dy * r.splatForce, 0), d(t(this, w).write.fbo), t(this, w).swap(), e.activeTexture(e.TEXTURE0), e.bindTexture(e.TEXTURE_2D, t(this, B).read.tex), e.uniform3f(v.uniforms.color, 1, 1, 1), d(t(this, B).write.fbo), t(this, B).swap(), t(this, h).moved = !1), o.bind(), e.uniform2f(o.uniforms.texelSize, 1 / x, 1 / n), e.uniform1i(o.uniforms.uVelocity, 0), e.activeTexture(e.TEXTURE0), e.bindTexture(e.TEXTURE_2D, t(this, w).read.tex), e.uniform1i(o.uniforms.uObstacle, 1), e.activeTexture(e.TEXTURE1), e.bindTexture(e.TEXTURE_2D, t(this, L)), d(t(this, $).fbo), a.bind(), e.uniform2f(a.uniforms.texelSize, 1 / x, 1 / n), e.uniform1i(a.uniforms.uDivergence, 0), e.activeTexture(e.TEXTURE0), e.bindTexture(e.TEXTURE_2D, t(this, $).tex), e.uniform1i(a.uniforms.uObstacle, 1), e.activeTexture(e.TEXTURE1), e.bindTexture(e.TEXTURE_2D, t(this, L));\n for (let b = 0; b < r.pressureIterations; b++)\n e.uniform1i(a.uniforms.uPressure, 2), e.activeTexture(e.TEXTURE2), e.bindTexture(e.TEXTURE_2D, t(this, q).read.tex), d(t(this, q).write.fbo), t(this, q).swap();\n u.bind(), e.uniform2f(u.uniforms.texelSize, 1 / x, 1 / n), e.uniform1i(u.uniforms.uPressure, 0), e.activeTexture(e.TEXTURE0), e.bindTexture(e.TEXTURE_2D, t(this, q).read.tex), e.uniform1i(u.uniforms.uVelocity, 1), e.activeTexture(e.TEXTURE1), e.bindTexture(e.TEXTURE_2D, t(this, w).read.tex), e.uniform1i(u.uniforms.uObstacle, 2), e.activeTexture(e.TEXTURE2), e.bindTexture(e.TEXTURE_2D, t(this, L)), d(t(this, w).write.fbo), t(this, w).swap(), e.viewport(0, 0, t(this, R), t(this, U)), e.bindFramebuffer(e.FRAMEBUFFER, null), e.clear(e.COLOR_BUFFER_BIT), m.bind(), e.uniform2f(m.uniforms.texelSize, 1 / t(this, R), 1 / t(this, U)), e.uniform3fv(m.uniforms.uWaterColor, Ne(r.waterColor)), e.uniform3fv(m.uniforms.uGlowColor, Ne(r.glowColor)), e.uniform1f(m.uniforms.uRefraction, r.refraction), e.uniform1f(m.uniforms.uSpecularExp, r.specularExp), e.uniform1f(m.uniforms.uShine, r.shine), e.uniform1f(m.uniforms.uWarpStrength, r.warpStrength ?? 0.015), e.uniform1i(m.uniforms.uAlgorithm, vt[r.algorithm] ?? 0), e.uniform1i(m.uniforms.uEnableAlpha, t(this, Se) ? 1 : 0), e.activeTexture(e.TEXTURE0), e.bindTexture(e.TEXTURE_2D, t(this, B).read.tex), e.activeTexture(e.TEXTURE1), e.bindTexture(e.TEXTURE_2D, t(this, L)), e.activeTexture(e.TEXTURE2), e.bindTexture(e.TEXTURE_2D, t(this, K)), e.activeTexture(e.TEXTURE3), e.bindTexture(e.TEXTURE_2D, t(this, Y)), e.activeTexture(e.TEXTURE4), e.bindTexture(e.TEXTURE_2D, t(this, w).read.tex), e.uniform1i(m.uniforms.uTexture, 0), e.uniform1i(m.uniforms.uObstacle, 1), e.uniform1i(m.uniforms.uBackground, 2), e.uniform1i(m.uniforms.uCoverage, 3), e.uniform1i(m.uniforms.uVelocity, 4), d(null);\n};\nlet st = nt;\nconst or = () => {\n};\nlet E = null, Tt;\nconst N = new Promise((i) => {\n Tt = i;\n});\nself.onmessage = async (i) => {\n const { type: e, ...r } = i.data;\n try {\n switch (e) {\n case \"init\": {\n const { canvas: s, width: o, height: a, config: u, dpr: v, quality: p, useWebGPU: c, enableAlpha: m } = r;\n s.width = o, s.height = a, E = await st.create(s, u, p ?? {}, c ?? !0, m ?? !0), E.resize(o, a, v || 1), Tt(), self.postMessage({ type: \"ready\" });\n break;\n }\n case \"setTextSource\": {\n if (await N, !E)\n return;\n E.setTextSource(r.opts);\n break;\n }\n case \"setImageSource\": {\n if (await N, !E)\n return;\n await E.setImageSource(\n r.src,\n r.effect,\n r.size\n );\n break;\n }\n case \"setImageBitmap\": {\n if (await N, !E)\n return;\n E.setImageBitmap(\n r.bitmap,\n r.effect,\n r.size\n );\n break;\n }\n case \"setBackground\": {\n if (await N, !E)\n return;\n E.setBackground(r.bitmap, r.size);\n break;\n }\n case \"splat\": {\n if (await N, !E)\n return;\n E.splat(\n r.x,\n r.y,\n r.vx,\n r.vy,\n r.strength ?? 1\n );\n break;\n }\n case \"move\": {\n if (await N, !E)\n return;\n E.handleMove(r.x, r.y, r.strength ?? 1);\n break;\n }\n case \"resize\": {\n if (await N, !E)\n return;\n E.resize(r.width, r.height, r.dpr);\n break;\n }\n case \"updateQuality\": {\n if (await N, !E)\n return;\n E.updateQuality(r.quality);\n break;\n }\n case \"updateConfig\": {\n if (await N, !E)\n return;\n E.updateConfig(r.config);\n break;\n }\n case \"destroy\": {\n await N, E == null || E.destroy(), E = null;\n break;\n }\n default:\n or(\"Unknown message type:\", e);\n }\n } catch (s) {\n self.postMessage({ type: \"error\", message: (s == null ? void 0 : s.message) ?? String(s) });\n }\n};\n", gC = typeof window < "u" && window.Blob && new Blob([uC], { type: "text/javascript;charset=utf-8" });
1459
- function qC() {
1460
- let e;
1461
- try {
1462
- if (e = gC && (window.URL || window.webkitURL).createObjectURL(gC), !e)
1463
- throw "";
1464
- return new Worker(e);
1465
- } catch {
1466
- return new Worker("data:application/javascript;base64," + uC, { type: "module" });
1467
- } finally {
1468
- e && (window.URL || window.webkitURL).revokeObjectURL(e);
1469
- }
568
+ //#endregion
569
+ //#region src/core/simulation.ts
570
+ var me = typeof requestAnimationFrame < "u" ? requestAnimationFrame.bind(globalThis) : (e) => setTimeout(e, 1e3 / 60), he = typeof cancelAnimationFrame < "u" ? cancelAnimationFrame.bind(globalThis) : clearTimeout, Z = .016, ge = {
571
+ standard: 0,
572
+ glass: 1,
573
+ ink: 2,
574
+ aurora: 3,
575
+ ripple: 4
576
+ }, Q = class e {
577
+ #e;
578
+ #t = null;
579
+ #n = null;
580
+ #r = null;
581
+ #i = null;
582
+ #a = null;
583
+ #o = null;
584
+ #s = null;
585
+ #c = null;
586
+ #l = null;
587
+ #u = null;
588
+ #d = null;
589
+ #f = null;
590
+ #p = null;
591
+ #m = null;
592
+ #h = null;
593
+ #g = null;
594
+ #_ = null;
595
+ #v = null;
596
+ #y = null;
597
+ #b = null;
598
+ #x = null;
599
+ #S = null;
600
+ #C = null;
601
+ #w = null;
602
+ #T = null;
603
+ #E = null;
604
+ #D = null;
605
+ #O = null;
606
+ #k = null;
607
+ #A = null;
608
+ #j = null;
609
+ #M = null;
610
+ #N = 0;
611
+ #P = 0;
612
+ #F = 0;
613
+ #I = 0;
614
+ #L = 1;
615
+ #R = 1;
616
+ #z = .5;
617
+ #B = null;
618
+ #V = "cover";
619
+ #H;
620
+ #U = {
621
+ x: 0,
622
+ y: 0,
623
+ dx: 0,
624
+ dy: 0,
625
+ targetX: 0,
626
+ targetY: 0,
627
+ moved: !1
628
+ };
629
+ #W = !1;
630
+ #G = null;
631
+ #K = null;
632
+ #q = !1;
633
+ #J = !1;
634
+ #Y = !0;
635
+ constructor(e, t = {}, n = {}, r, i = !0) {
636
+ if (this.#e = e, this.#R = Math.max(.1, Math.min(1, n.dpr ?? 1)), this.#z = Math.max(.1, Math.min(1, n.sim ?? .5)), this.#H = h(t), this.#Y = i, r) this.#p = r, this.#X(r);
637
+ else {
638
+ let { gl: t, ext: n } = N(e, i);
639
+ this.#t = t, this.#n = n, this.#r = I(t), this.#i = z(t), t.clearColor(0, 0, 0, +!i);
640
+ }
641
+ }
642
+ static async create(t, n = {}, r = {}, i = !0, a = !0) {
643
+ return new e(t, n, r, (i ? await P(t, a) : null) ?? void 0, a);
644
+ }
645
+ setTextSource(e) {
646
+ this.#G = {
647
+ type: "text",
648
+ opts: e
649
+ }, this.#Z(), this.#$(), this.#ee();
650
+ }
651
+ async setImageSource(e, t = 0, n = "cover") {
652
+ let r = await C(e);
653
+ if (this.#J) {
654
+ r.close();
655
+ return;
656
+ }
657
+ this.#G = {
658
+ type: "image",
659
+ bitmap: r,
660
+ effect: t,
661
+ size: n
662
+ }, this.#Z(), this.#$(), this.#ee();
663
+ }
664
+ setImageBitmap(e, t = 0, n = "cover") {
665
+ this.#G = {
666
+ type: "image",
667
+ bitmap: e,
668
+ effect: t,
669
+ size: n
670
+ }, this.#Z(), this.#$(), this.#ee();
671
+ }
672
+ setBackground(e, t = "cover") {
673
+ this.#B && this.#B !== e && this.#B.close(), this.#B = e, this.#V = t ?? "cover", this.#G && this.#N > 0 && this.#P > 0 && this.#$();
674
+ }
675
+ handleMove(e, t, n = 1) {
676
+ if (!this.#W) {
677
+ this.#U.x = this.#U.targetX = e, this.#U.y = this.#U.targetY = t, this.#W = !0;
678
+ return;
679
+ }
680
+ this.#U.moved = !0, this.#U.dx = (e - this.#U.targetX) * n, this.#U.dy = (t - this.#U.targetY) * n, this.#U.targetX = e, this.#U.targetY = t;
681
+ }
682
+ splat(e, t, n, r, i = 1) {
683
+ !this.#q || this.#N === 0 || (this.#p ? this.#ae(e, t, n, r, i) : this.#oe(e, t, n, r, i));
684
+ }
685
+ updateQuality(e) {
686
+ e.dpr !== void 0 && (this.#R = Math.max(.1, Math.min(1, e.dpr))), e.sim !== void 0 && (this.#z = Math.max(.1, Math.min(1, e.sim)));
687
+ }
688
+ resize(e, t, n) {
689
+ if (n === void 0 ? typeof window < "u" && window.devicePixelRatio && (this.#L = window.devicePixelRatio) : this.#L = n, e !== void 0 && e > 0) {
690
+ if (t === void 0 || t <= 0) return;
691
+ this.#N = this.#e.width = e, this.#P = this.#e.height = t, this.#F = Math.max(1, Math.round(e * this.#z)), this.#I = Math.max(1, Math.round(t * this.#z)), this.#Q();
692
+ } else this.#Z();
693
+ this.#G && this.#$(), this.#ee();
694
+ }
695
+ updateConfig(e) {
696
+ Object.assign(this.#H, e);
697
+ }
698
+ destroy() {
699
+ if (this.#J = !0, this.stop(), this.#te(), this.#ne(), this.#B &&= (this.#B.close(), null), this.#p) this.#C?.destroy(), this.#w?.destroy(), this.#T?.destroy(), this.#E?.destroy(), this.#D?.destroy(), this.#O?.destroy(), this.#k?.destroy(), this.#A?.destroy(), this.#j?.destroy(), this.#M?.destroy(), this.#h?.destroy(), this.#p.device.destroy();
700
+ else {
701
+ let e = this.#t;
702
+ for (let e of Object.values(this.#r)) e.dispose();
703
+ e.getExtension("WEBGL_lose_context")?.loseContext();
704
+ }
705
+ }
706
+ start() {
707
+ if (this.#K !== null) return;
708
+ let e = () => {
709
+ this.#re(), this.#K = me(e);
710
+ };
711
+ this.#K = me(e);
712
+ }
713
+ stop() {
714
+ this.#K !== null && (he(this.#K), this.#K = null);
715
+ }
716
+ get isRunning() {
717
+ return this.#K !== null;
718
+ }
719
+ #X(e) {
720
+ let { device: t, format: n } = e;
721
+ this.#m = ce(t, n, this.#Y), this.#h = oe(t), this.#g = le(t), this.#C = q(t, 16), this.#w = q(t, 16), this.#T = q(t, 16), this.#E = q(t, 16), this.#D = q(t, 16), this.#O = q(t, 48), this.#k = q(t, 48), this.#A = q(t, 16), this.#j = q(t, 16), this.#M = q(t, 64);
722
+ }
723
+ #Z() {
724
+ let e = this.#e;
725
+ "clientWidth" in e && e.clientWidth > 0 ? (this.#L = (typeof window < "u" && window.devicePixelRatio || 1) * this.#R, this.#N = e.width = Math.round(e.clientWidth * this.#L), this.#P = e.height = Math.round(e.clientHeight * this.#L)) : (this.#N = e.width, this.#P = e.height), !(this.#N === 0 || this.#P === 0) && (this.#F = Math.max(1, Math.round(this.#N * this.#z)), this.#I = Math.max(1, Math.round(this.#P * this.#z)), this.#Q());
726
+ }
727
+ #Q() {
728
+ if (this.#te(), this.#p) {
729
+ let { device: e } = this.#p, t = "rgba16float", n = this.#F, r = this.#I;
730
+ this.#_ = G(e, t, n, r), this.#v = G(e, t, n, r), this.#b = G(e, t, n, r), this.#y = W(e, t, n, r), this.#x = W(e, t, n, r);
731
+ } else {
732
+ let e = this.#t, t = this.#n, n = this.#F, r = this.#I;
733
+ this.#a = R(e, t, n, r), this.#o = R(e, t, n, r), this.#c = R(e, t, n, r), this.#s = L(e, t, n, r), this.#l = L(e, t, n, r);
734
+ }
735
+ }
736
+ #$() {
737
+ if (!(!this.#G || this.#N === 0 || this.#P === 0)) {
738
+ if (this.#ne(), this.#p) {
739
+ let { device: e } = this.#p;
740
+ this.#G.type === "text" ? this.#S = b(e, this.#N, this.#P, this.#G.opts, this.#B, this.#V) : this.#S = x(e, this.#G.bitmap, this.#N, this.#P, this.#G.effect, this.#G.size, this.#B, this.#V);
741
+ } else {
742
+ let e = this.#t;
743
+ if (this.#G.type === "text") {
744
+ let { backgroundTex: t, obstacleTex: n, coverageTex: r } = _(e, this.#N, this.#P, this.#G.opts, this.#B, this.#V);
745
+ this.#u = t, this.#d = n, this.#f = r;
746
+ } else {
747
+ let { backgroundTex: t, obstacleTex: n, coverageTex: r } = v(e, this.#G.bitmap, this.#N, this.#P, this.#G.effect, this.#G.size, this.#B, this.#V);
748
+ this.#u = t, this.#d = n, this.#f = r;
749
+ }
750
+ }
751
+ this.#q = !0;
752
+ }
753
+ }
754
+ #ee() {
755
+ this.#q && !this.isRunning && this.start();
756
+ }
757
+ #te() {
758
+ if (this.#p) this.#_?.dispose(), this.#v?.dispose(), this.#b?.dispose(), this.#y?.tex.destroy(), this.#x?.tex.destroy(), this.#_ = this.#v = this.#b = null, this.#y = this.#x = null;
759
+ else {
760
+ let e = this.#t;
761
+ this.#a?.dispose(), this.#o?.dispose(), this.#c?.dispose(), this.#s && (e.deleteTexture(this.#s.tex), e.deleteFramebuffer(this.#s.fbo)), this.#l && (e.deleteTexture(this.#l.tex), e.deleteFramebuffer(this.#l.fbo)), this.#a = this.#o = this.#c = this.#s = this.#l = null;
762
+ }
763
+ }
764
+ #ne() {
765
+ if (this.#p) this.#S &&= (this.#S.backgroundTex.destroy(), this.#S.obstacleTex.destroy(), this.#S.sharedCoverage || this.#S.coverageTex.destroy(), null);
766
+ else {
767
+ let e = this.#t;
768
+ this.#u && e.deleteTexture(this.#u), this.#d && e.deleteTexture(this.#d), this.#f && this.#f !== this.#d && e.deleteTexture(this.#f), this.#u = this.#d = this.#f = null;
769
+ }
770
+ }
771
+ #re() {
772
+ !this.#q || this.#N === 0 || (this.#p ? this.#ie() : this.#se());
773
+ }
774
+ #ie() {
775
+ let e = this.#p, t = e.device, n = this.#m, r = this.#h, i = this.#g, a = this.#H, o = this.#S;
776
+ if (!this.#_ || !this.#v) return;
777
+ this.#U.x += (this.#U.targetX - this.#U.x) * .15, this.#U.y += (this.#U.targetY - this.#U.y) * .15;
778
+ let s = this.#F, c = this.#I, l = this.#N, u = this.#P, d = 1 / s, f = 1 / c;
779
+ ue(t, this.#C, d, f, Z, a.velocityDissipation), J(t, this.#T, d, f), J(t, this.#E, d, f), J(t, this.#D, d, f), J(t, this.#A, d, f), de(t, this.#j, d, f, a.curl, Z), fe(t, this.#M, 1 / l, 1 / u, a.refraction, a.specularExp, m(a.waterColor), m(a.glowColor), a.shine, a.warpStrength ?? .015, ge[a.algorithm] ?? 0, this.#Y);
780
+ let p = t.createCommandEncoder(), h = (e, n) => t.createBindGroup({
781
+ layout: e.getBindGroupLayout(0),
782
+ entries: n
783
+ }), g = {
784
+ binding: 1,
785
+ resource: i
786
+ };
787
+ {
788
+ let e = h(n.advection, [
789
+ {
790
+ binding: 0,
791
+ resource: { buffer: this.#C }
792
+ },
793
+ g,
794
+ {
795
+ binding: 2,
796
+ resource: this.#v.read.view
797
+ },
798
+ {
799
+ binding: 3,
800
+ resource: this.#v.read.view
801
+ },
802
+ {
803
+ binding: 4,
804
+ resource: o.obstacleView
805
+ }
806
+ ]);
807
+ X(p, n.advection, e, r, this.#v.write.view);
808
+ }
809
+ this.#v.swap();
810
+ {
811
+ ue(t, this.#w, d, f, Z, a.densityDissipation);
812
+ let e = h(n.advection, [
813
+ {
814
+ binding: 0,
815
+ resource: { buffer: this.#w }
816
+ },
817
+ g,
818
+ {
819
+ binding: 2,
820
+ resource: this.#v.read.view
821
+ },
822
+ {
823
+ binding: 3,
824
+ resource: this.#_.read.view
825
+ },
826
+ {
827
+ binding: 4,
828
+ resource: o.obstacleView
829
+ }
830
+ ]);
831
+ X(p, n.advection, e, r, this.#_.write.view);
832
+ }
833
+ this.#_.swap();
834
+ {
835
+ let e = h(n.curl, [
836
+ {
837
+ binding: 0,
838
+ resource: { buffer: this.#A }
839
+ },
840
+ g,
841
+ {
842
+ binding: 2,
843
+ resource: this.#v.read.view
844
+ }
845
+ ]);
846
+ X(p, n.curl, e, r, this.#x.view);
847
+ }
848
+ {
849
+ let e = h(n.vorticity, [
850
+ {
851
+ binding: 0,
852
+ resource: { buffer: this.#j }
853
+ },
854
+ g,
855
+ {
856
+ binding: 2,
857
+ resource: this.#v.read.view
858
+ },
859
+ {
860
+ binding: 3,
861
+ resource: this.#x.view
862
+ }
863
+ ]);
864
+ X(p, n.vorticity, e, r, this.#v.write.view);
865
+ }
866
+ if (this.#v.swap(), this.#U.moved) {
867
+ let e = this.#U.x * this.#L / l, i = this.#U.y * this.#L / u;
868
+ Y(t, this.#O, d, f, l / u, a.splatRadius, this.#U.dx * a.splatForce, this.#U.dy * a.splatForce, 0, e, i);
869
+ {
870
+ let e = h(n.splat, [
871
+ {
872
+ binding: 0,
873
+ resource: { buffer: this.#O }
874
+ },
875
+ g,
876
+ {
877
+ binding: 2,
878
+ resource: this.#v.read.view
879
+ }
880
+ ]);
881
+ X(p, n.splat, e, r, this.#v.write.view);
882
+ }
883
+ this.#v.swap(), Y(t, this.#k, d, f, l / u, a.splatRadius, 1, 1, 1, e, i);
884
+ {
885
+ let e = h(n.splat, [
886
+ {
887
+ binding: 0,
888
+ resource: { buffer: this.#k }
889
+ },
890
+ g,
891
+ {
892
+ binding: 2,
893
+ resource: this.#_.read.view
894
+ }
895
+ ]);
896
+ X(p, n.splat, e, r, this.#_.write.view);
897
+ }
898
+ this.#_.swap(), this.#U.moved = !1;
899
+ }
900
+ {
901
+ let e = h(n.divergence, [
902
+ {
903
+ binding: 0,
904
+ resource: { buffer: this.#T }
905
+ },
906
+ g,
907
+ {
908
+ binding: 2,
909
+ resource: this.#v.read.view
910
+ },
911
+ {
912
+ binding: 3,
913
+ resource: o.obstacleView
914
+ }
915
+ ]);
916
+ X(p, n.divergence, e, r, this.#y.view);
917
+ }
918
+ for (let e = 0; e < a.pressureIterations; e++) {
919
+ let e = h(n.pressure, [
920
+ {
921
+ binding: 0,
922
+ resource: { buffer: this.#E }
923
+ },
924
+ g,
925
+ {
926
+ binding: 2,
927
+ resource: this.#b.read.view
928
+ },
929
+ {
930
+ binding: 3,
931
+ resource: this.#y.view
932
+ },
933
+ {
934
+ binding: 4,
935
+ resource: o.obstacleView
936
+ }
937
+ ]);
938
+ X(p, n.pressure, e, r, this.#b.write.view), this.#b.swap();
939
+ }
940
+ {
941
+ let e = h(n.gradientSubtract, [
942
+ {
943
+ binding: 0,
944
+ resource: { buffer: this.#D }
945
+ },
946
+ g,
947
+ {
948
+ binding: 2,
949
+ resource: this.#b.read.view
950
+ },
951
+ {
952
+ binding: 3,
953
+ resource: this.#v.read.view
954
+ },
955
+ {
956
+ binding: 4,
957
+ resource: o.obstacleView
958
+ }
959
+ ]);
960
+ X(p, n.gradientSubtract, e, r, this.#v.write.view);
961
+ }
962
+ this.#v.swap();
963
+ {
964
+ let t = e.context.getCurrentTexture().createView(), i = h(n.display, [
965
+ {
966
+ binding: 0,
967
+ resource: { buffer: this.#M }
968
+ },
969
+ g,
970
+ {
971
+ binding: 2,
972
+ resource: this.#_.read.view
973
+ },
974
+ {
975
+ binding: 3,
976
+ resource: o.obstacleView
977
+ },
978
+ {
979
+ binding: 4,
980
+ resource: o.backgroundView
981
+ },
982
+ {
983
+ binding: 5,
984
+ resource: o.coverageView
985
+ },
986
+ {
987
+ binding: 6,
988
+ resource: this.#v.read.view
989
+ }
990
+ ]);
991
+ pe(p, n.display, i, r, t);
992
+ }
993
+ t.queue.submit([p.finish()]);
994
+ }
995
+ #ae(e, t, n, r, i) {
996
+ let a = this.#p.device, o = this.#m.splat, s = this.#h, c = this.#g, l = this.#H, u = this.#F, d = this.#I, f = 1 / u, p = 1 / d, m = a.createCommandEncoder(), h = {
997
+ binding: 1,
998
+ resource: c
999
+ }, g = (e) => a.createBindGroup({
1000
+ layout: o.getBindGroupLayout(0),
1001
+ entries: e
1002
+ }), _ = e * this.#L / this.#N, v = t * this.#L / this.#P;
1003
+ Y(a, this.#O, f, p, this.#N / this.#P, l.splatRadius, n * l.splatForce * i, r * l.splatForce * i, 0, _, v), X(m, o, g([
1004
+ {
1005
+ binding: 0,
1006
+ resource: { buffer: this.#O }
1007
+ },
1008
+ h,
1009
+ {
1010
+ binding: 2,
1011
+ resource: this.#v.read.view
1012
+ }
1013
+ ]), s, this.#v.write.view), this.#v.swap(), Y(a, this.#k, f, p, this.#N / this.#P, l.splatRadius, i, i, i, _, v), X(m, o, g([
1014
+ {
1015
+ binding: 0,
1016
+ resource: { buffer: this.#k }
1017
+ },
1018
+ h,
1019
+ {
1020
+ binding: 2,
1021
+ resource: this.#_.read.view
1022
+ }
1023
+ ]), s, this.#_.write.view), this.#_.swap(), a.queue.submit([m.finish()]);
1024
+ }
1025
+ #oe(e, t, n, r, i) {
1026
+ let a = this.#t, o = this.#H, s = this.#r.splat, c = this.#i;
1027
+ a.viewport(0, 0, this.#F, this.#I), s.bind(), a.uniform1f(s.uniforms.aspectRatio, this.#N / this.#P), a.uniform2f(s.uniforms.point, e * this.#L / this.#N, 1 - t * this.#L / this.#P), a.uniform1f(s.uniforms.radius, o.splatRadius), a.uniform1i(s.uniforms.uTarget, 0), a.activeTexture(a.TEXTURE0), a.bindTexture(a.TEXTURE_2D, this.#o.read.tex), a.uniform3f(s.uniforms.color, n * o.splatForce * i, -r * o.splatForce * i, 0), c(this.#o.write.fbo), this.#o.swap(), a.activeTexture(a.TEXTURE0), a.bindTexture(a.TEXTURE_2D, this.#a.read.tex), a.uniform3f(s.uniforms.color, i, i, i), c(this.#a.write.fbo), this.#a.swap();
1028
+ }
1029
+ #se() {
1030
+ if (!this.#a || !this.#o) return;
1031
+ let e = this.#t, t = this.#H, { advection: n, divergence: r, pressure: i, gradientSubtract: a, splat: o, curl: s, vorticity: c, display: l } = this.#r;
1032
+ this.#U.x += (this.#U.targetX - this.#U.x) * .15, this.#U.y += (this.#U.targetY - this.#U.y) * .15;
1033
+ let u = this.#F, d = this.#I, f = this.#i;
1034
+ e.viewport(0, 0, u, d), n.bind(), e.uniform2f(n.uniforms.texelSize, 1 / u, 1 / d), e.uniform1f(n.uniforms.dt, Z), e.uniform1i(n.uniforms.uObstacle, 0), e.activeTexture(e.TEXTURE0), e.bindTexture(e.TEXTURE_2D, this.#d), e.uniform1f(n.uniforms.dissipation, t.velocityDissipation), e.uniform1i(n.uniforms.uVelocity, 1), e.activeTexture(e.TEXTURE1), e.bindTexture(e.TEXTURE_2D, this.#o.read.tex), e.uniform1i(n.uniforms.uSource, 1), f(this.#o.write.fbo), this.#o.swap(), e.uniform1f(n.uniforms.dissipation, t.densityDissipation), e.uniform1i(n.uniforms.uSource, 2), e.activeTexture(e.TEXTURE2), e.bindTexture(e.TEXTURE_2D, this.#a.read.tex), f(this.#a.write.fbo), this.#a.swap(), s.bind(), e.uniform2f(s.uniforms.texelSize, 1 / u, 1 / d), e.uniform1i(s.uniforms.uVelocity, 0), e.activeTexture(e.TEXTURE0), e.bindTexture(e.TEXTURE_2D, this.#o.read.tex), f(this.#l.fbo), c.bind(), e.uniform2f(c.uniforms.texelSize, 1 / u, 1 / d), e.uniform1f(c.uniforms.curl, t.curl), e.uniform1f(c.uniforms.dt, Z), e.uniform1i(c.uniforms.uVelocity, 0), e.activeTexture(e.TEXTURE0), e.bindTexture(e.TEXTURE_2D, this.#o.read.tex), e.uniform1i(c.uniforms.uCurl, 1), e.activeTexture(e.TEXTURE1), e.bindTexture(e.TEXTURE_2D, this.#l.tex), f(this.#o.write.fbo), this.#o.swap(), this.#U.moved && (o.bind(), e.uniform1f(o.uniforms.aspectRatio, this.#N / this.#P), e.uniform2f(o.uniforms.point, this.#U.x * this.#L / this.#N, 1 - this.#U.y * this.#L / this.#P), e.uniform1f(o.uniforms.radius, t.splatRadius), e.uniform1i(o.uniforms.uTarget, 0), e.activeTexture(e.TEXTURE0), e.bindTexture(e.TEXTURE_2D, this.#o.read.tex), e.uniform3f(o.uniforms.color, this.#U.dx * t.splatForce, -this.#U.dy * t.splatForce, 0), f(this.#o.write.fbo), this.#o.swap(), e.activeTexture(e.TEXTURE0), e.bindTexture(e.TEXTURE_2D, this.#a.read.tex), e.uniform3f(o.uniforms.color, 1, 1, 1), f(this.#a.write.fbo), this.#a.swap(), this.#U.moved = !1), r.bind(), e.uniform2f(r.uniforms.texelSize, 1 / u, 1 / d), e.uniform1i(r.uniforms.uVelocity, 0), e.activeTexture(e.TEXTURE0), e.bindTexture(e.TEXTURE_2D, this.#o.read.tex), e.uniform1i(r.uniforms.uObstacle, 1), e.activeTexture(e.TEXTURE1), e.bindTexture(e.TEXTURE_2D, this.#d), f(this.#s.fbo), i.bind(), e.uniform2f(i.uniforms.texelSize, 1 / u, 1 / d), e.uniform1i(i.uniforms.uDivergence, 0), e.activeTexture(e.TEXTURE0), e.bindTexture(e.TEXTURE_2D, this.#s.tex), e.uniform1i(i.uniforms.uObstacle, 1), e.activeTexture(e.TEXTURE1), e.bindTexture(e.TEXTURE_2D, this.#d);
1035
+ for (let n = 0; n < t.pressureIterations; n++) e.uniform1i(i.uniforms.uPressure, 2), e.activeTexture(e.TEXTURE2), e.bindTexture(e.TEXTURE_2D, this.#c.read.tex), f(this.#c.write.fbo), this.#c.swap();
1036
+ a.bind(), e.uniform2f(a.uniforms.texelSize, 1 / u, 1 / d), e.uniform1i(a.uniforms.uPressure, 0), e.activeTexture(e.TEXTURE0), e.bindTexture(e.TEXTURE_2D, this.#c.read.tex), e.uniform1i(a.uniforms.uVelocity, 1), e.activeTexture(e.TEXTURE1), e.bindTexture(e.TEXTURE_2D, this.#o.read.tex), e.uniform1i(a.uniforms.uObstacle, 2), e.activeTexture(e.TEXTURE2), e.bindTexture(e.TEXTURE_2D, this.#d), f(this.#o.write.fbo), this.#o.swap(), e.viewport(0, 0, this.#N, this.#P), e.bindFramebuffer(e.FRAMEBUFFER, null), e.clear(e.COLOR_BUFFER_BIT), l.bind(), e.uniform2f(l.uniforms.texelSize, 1 / this.#N, 1 / this.#P), e.uniform3fv(l.uniforms.uWaterColor, m(t.waterColor)), e.uniform3fv(l.uniforms.uGlowColor, m(t.glowColor)), e.uniform1f(l.uniforms.uRefraction, t.refraction), e.uniform1f(l.uniforms.uSpecularExp, t.specularExp), e.uniform1f(l.uniforms.uShine, t.shine), e.uniform1f(l.uniforms.uWarpStrength, t.warpStrength ?? .015), e.uniform1i(l.uniforms.uAlgorithm, ge[t.algorithm] ?? 0), e.uniform1i(l.uniforms.uEnableAlpha, +!!this.#Y), e.activeTexture(e.TEXTURE0), e.bindTexture(e.TEXTURE_2D, this.#a.read.tex), e.activeTexture(e.TEXTURE1), e.bindTexture(e.TEXTURE_2D, this.#d), e.activeTexture(e.TEXTURE2), e.bindTexture(e.TEXTURE_2D, this.#u), e.activeTexture(e.TEXTURE3), e.bindTexture(e.TEXTURE_2D, this.#f), e.activeTexture(e.TEXTURE4), e.bindTexture(e.TEXTURE_2D, this.#o.read.tex), e.uniform1i(l.uniforms.uTexture, 0), e.uniform1i(l.uniforms.uObstacle, 1), e.uniform1i(l.uniforms.uBackground, 2), e.uniform1i(l.uniforms.uCoverage, 3), e.uniform1i(l.uniforms.uVelocity, 4), f(null);
1037
+ }
1038
+ }, _e = "const e={densityDissipation:.83,velocityDissipation:.91,pressureIterations:1,curl:0,splatRadius:.1,splatForce:.08,refraction:1,specularExp:0,shine:0,waterColor:`#000000`,glowColor:`#b3d9ff`,algorithm:`aurora`,warpStrength:.04};({...e}),typeof window<`u`&&1/(window.devicePixelRatio||1);const t={backgroundColor:`#0a0a0a`,backgroundSize:`cover`,mouseEnabled:!0,workerEnabled:!0};({...t}),{...t};const n={calm:{densityDissipation:.98,velocityDissipation:.81,curl:1e-4,splatRadius:.05,splatForce:.08,refraction:.15,shine:.03,glowColor:`#99d9ff`,waterColor:`#00050d`},sand:{densityDissipation:.95,velocityDissipation:.81,curl:1,splatRadius:.23,splatForce:.16,refraction:.8,specularExp:0,shine:.33,glowColor:`#070707`,waterColor:`#735420`},wave:{densityDissipation:.9,velocityDissipation:.2,curl:.2,splatRadius:.1,splatForce:.22,refraction:.35,shine:.2,glowColor:`#80ccff`,waterColor:`#000308`},neon:{densityDissipation:.75,velocityDissipation:.3,curl:.05,splatRadius:.18,splatForce:.29,refraction:.25,specularExp:.04,shine:.93,glowColor:`#ff33cc`,waterColor:`#0d0014`},smoke:{densityDissipation:.93,velocityDissipation:.71,curl:.04,splatRadius:.21,splatForce:.14,refraction:.08,shine:0,glowColor:`#808080`,waterColor:`#0f0f0f`}};function r(e){if(Array.isArray(e))return e;let t=e.slice(1,7);return t.length===3?[parseInt(t[0]+t[0],16)/255,parseInt(t[1]+t[1],16)/255,parseInt(t[2]+t[2],16)/255]:[parseInt(t.slice(0,2),16)/255,parseInt(t.slice(2,4),16)/255,parseInt(t.slice(4,6),16)/255]}function i(t={},r,i=e){return{...r?{...i,...n[r]}:i,...t}}const a=`precision highp float;\n attribute vec2 aPosition;\n varying vec2 vUv;\n varying vec2 vL; varying vec2 vR; varying vec2 vT; varying vec2 vB;\n uniform vec2 texelSize;\n void main () {\n vUv = aPosition * 0.5 + 0.5;\n vL = vUv - vec2(texelSize.x, 0.0);\n vR = vUv + vec2(texelSize.x, 0.0);\n vT = vUv + vec2(0.0, texelSize.y);\n vB = vUv - vec2(0.0, texelSize.y);\n gl_Position = vec4(aPosition, 0.0, 1.0);\n }`;function o(e,t=!0){let n={alpha:t,depth:!1,stencil:!1,antialias:!0,preserveDrawingBuffer:!1},r=e.getContext(`webgl2`,n),i=!!r;i||(r=e.getContext(`webgl`,n),r.getExtension(`EXT_color_buffer_half_float`));let a=i?null:r.getExtension(`OES_texture_half_float`),o=i?r.HALF_FLOAT:a.HALF_FLOAT_OES;return r.getExtension(`EXT_color_buffer_float`),r.getExtension(`OES_texture_half_float_linear`),{type:i?`webgl2`:`webgl1`,gl:r,isWebGL2:i,ext:{internalFormat:i?r.RGBA16F:r.RGBA,format:r.RGBA,type:o}}}async function s(e,t=!0){if(typeof navigator>`u`||!navigator.gpu)return null;try{let n=await navigator.gpu.requestAdapter();if(!n)return null;let r=await n.requestDevice(),i=e.getContext(`webgpu`);if(!i)return null;let a=navigator.gpu.getPreferredCanvasFormat();return i.configure({device:r,format:a,alphaMode:t?`premultiplied`:`opaque`}),{type:`webgpu`,adapter:n,device:r,context:i,format:a}}catch{return null}}var c=class{program;uniforms={};_gl;constructor(e,t,n){this._gl=e,this.program=e.createProgram(),e.attachShader(this.program,this._compile(e.VERTEX_SHADER,t)),e.attachShader(this.program,this._compile(e.FRAGMENT_SHADER,n)),e.linkProgram(this.program);let r=e.getProgramParameter(this.program,e.ACTIVE_UNIFORMS);for(let t=0;t<r;t++){let n=e.getActiveUniform(this.program,t).name;this.uniforms[n]=e.getUniformLocation(this.program,n)}}_compile(e,t){let n=this._gl,r=n.createShader(e);return n.shaderSource(r,t),n.compileShader(r),r}bind(){this._gl.useProgram(this.program)}dispose(){this._gl.deleteProgram(this.program)}};function l(e){return{advection:new c(e,a,`precision highp float;\n varying vec2 vUv;\n uniform sampler2D uVelocity;\n uniform sampler2D uSource;\n uniform sampler2D uObstacle;\n uniform vec2 texelSize;\n uniform float dt;\n uniform float dissipation;\n void main () {\n float obs = texture2D(uObstacle, vUv).r;\n vec2 coord = vUv - dt * texture2D(uVelocity, vUv).xy * texelSize;\n \n \n \n gl_FragColor = dissipation * texture2D(uSource, coord) * (1.0 - obs);\n }`),divergence:new c(e,a,`precision highp float;\n varying vec2 vL; varying vec2 vR; varying vec2 vT; varying vec2 vB;\n uniform sampler2D uVelocity;\n uniform sampler2D uObstacle;\n void main () {\n float L = texture2D(uVelocity, vL).x * (1.0 - texture2D(uObstacle, vL).r);\n float R = texture2D(uVelocity, vR).x * (1.0 - texture2D(uObstacle, vR).r);\n float T = texture2D(uVelocity, vT).y * (1.0 - texture2D(uObstacle, vT).r);\n float B = texture2D(uVelocity, vB).y * (1.0 - texture2D(uObstacle, vB).r);\n gl_FragColor = vec4(0.5 * (R - L + T - B), 0.0, 0.0, 1.0);\n }`),pressure:new c(e,a,`precision highp float;\n varying vec2 vUv; varying vec2 vL; varying vec2 vR; varying vec2 vT; varying vec2 vB;\n uniform sampler2D uPressure;\n uniform sampler2D uDivergence;\n uniform sampler2D uObstacle;\n void main () {\n float C = texture2D(uPressure, vUv).x;\n float L = mix(texture2D(uPressure, vL).x, C, texture2D(uObstacle, vL).r);\n float R = mix(texture2D(uPressure, vR).x, C, texture2D(uObstacle, vR).r);\n float T = mix(texture2D(uPressure, vT).x, C, texture2D(uObstacle, vT).r);\n float B = mix(texture2D(uPressure, vB).x, C, texture2D(uObstacle, vB).r);\n float div = texture2D(uDivergence, vUv).x;\n gl_FragColor = vec4((L + R + B + T - div) * 0.25, 0.0, 0.0, 1.0);\n }`),gradientSubtract:new c(e,a,`precision highp float;\n varying vec2 vUv; varying vec2 vL; varying vec2 vR; varying vec2 vT; varying vec2 vB;\n uniform sampler2D uPressure;\n uniform sampler2D uVelocity;\n uniform sampler2D uObstacle;\n void main () {\n float obs = texture2D(uObstacle, vUv).r;\n float C = texture2D(uPressure, vUv).x;\n float L = mix(texture2D(uPressure, vL).x, C, texture2D(uObstacle, vL).r);\n float R = mix(texture2D(uPressure, vR).x, C, texture2D(uObstacle, vR).r);\n float T = mix(texture2D(uPressure, vT).x, C, texture2D(uObstacle, vT).r);\n float B = mix(texture2D(uPressure, vB).x, C, texture2D(uObstacle, vB).r);\n vec2 vel = (texture2D(uVelocity, vUv).xy - vec2(R - L, T - B)) * (1.0 - obs);\n gl_FragColor = vec4(vel, 0.0, 1.0);\n }`),splat:new c(e,a,`precision highp float;\n varying vec2 vUv;\n uniform sampler2D uTarget;\n uniform float aspectRatio;\n uniform vec3 color;\n uniform vec2 point;\n uniform float radius;\n void main () {\n vec2 p = vUv - point.xy;\n p.x *= aspectRatio;\n vec3 splat = exp(-dot(p, p) / radius) * color;\n gl_FragColor = vec4(texture2D(uTarget, vUv).xyz + splat, 1.0);\n }`),curl:new c(e,a,`precision highp float;\n varying vec2 vL; varying vec2 vR; varying vec2 vT; varying vec2 vB;\n uniform sampler2D uVelocity;\n void main () {\n float L = texture2D(uVelocity, vL).y;\n float R = texture2D(uVelocity, vR).y;\n float T = texture2D(uVelocity, vT).x;\n float B = texture2D(uVelocity, vB).x;\n gl_FragColor = vec4(0.5 * (R - L - T + B), 0.0, 0.0, 1.0);\n }`),vorticity:new c(e,a,`precision highp float;\n varying vec2 vUv; varying vec2 vL; varying vec2 vR; varying vec2 vT; varying vec2 vB;\n uniform sampler2D uVelocity;\n uniform sampler2D uCurl;\n uniform float curl;\n uniform float dt;\n void main () {\n float L = texture2D(uCurl, vL).x;\n float R = texture2D(uCurl, vR).x;\n float T = texture2D(uCurl, vT).x;\n float B = texture2D(uCurl, vB).x;\n float C = texture2D(uCurl, vUv).x;\n vec2 force = 0.5 * vec2(abs(T) - abs(B), abs(R) - abs(L));\n force /= length(force) + 0.0001;\n force *= curl * 30.0 * C;\n gl_FragColor = vec4(texture2D(uVelocity, vUv).xy + force * dt, 0.0, 1.0);\n }`),display:new c(e,a,`precision highp float;\n varying vec2 vUv;\n uniform sampler2D uTexture;\n uniform sampler2D uObstacle;\n uniform sampler2D uBackground;\n uniform sampler2D uCoverage;\n uniform sampler2D uVelocity;\n uniform vec2 texelSize;\n uniform vec3 uWaterColor;\n uniform vec3 uGlowColor;\n uniform float uRefraction;\n uniform float uSpecularExp;\n uniform float uShine;\n uniform float uWarpStrength;\n uniform int uAlgorithm;\n uniform int uEnableAlpha;\n void main () {\n float obs = texture2D(uObstacle, vUv).r;\n \n \n float density = max(texture2D(uTexture, vUv).r, 0.0) * (1.0 - obs);\n float coverage = texture2D(uCoverage, vUv).r;\n \n \n \n \n float sx = texelSize.x * 6.0, sy = texelSize.y * 6.0;\n float d00 = max(texture2D(uTexture, vUv + vec2(-sx, -sy)).r, 0.0);\n float d10 = max(texture2D(uTexture, vUv + vec2(0.0, -sy)).r, 0.0);\n float d20 = max(texture2D(uTexture, vUv + vec2( sx, -sy)).r, 0.0);\n float d01 = max(texture2D(uTexture, vUv + vec2(-sx, 0.0)).r, 0.0);\n float d21 = max(texture2D(uTexture, vUv + vec2( sx, 0.0)).r, 0.0);\n float d02 = max(texture2D(uTexture, vUv + vec2(-sx, sy)).r, 0.0);\n float d12 = max(texture2D(uTexture, vUv + vec2(0.0, sy)).r, 0.0);\n float d22 = max(texture2D(uTexture, vUv + vec2( sx, sy)).r, 0.0);\n float gx = (d20 + 2.0*d21 + d22) - (d00 + 2.0*d01 + d02);\n float gy = (d02 + 2.0*d12 + d22) - (d00 + 2.0*d10 + d20);\n vec3 normal = normalize(vec3(gx, gy, 1.2));\n vec3 lightDir = normalize(vec3(0.5, 1.0, 0.5));\n vec3 halfV = normalize(lightDir + vec3(0.0, 0.0, 1.0));\n \n \n float specDen = density * min(density * 5.0, 1.0);\n float spec = pow(max(dot(normal, halfV), 0.0), uSpecularExp) * uShine * specDen;\n \n \n \n vec3 bgRaw = texture2D(uBackground, vUv).rgb;\n vec3 bg = mix(uWaterColor, bgRaw, coverage);\n vec3 color = bg;\n if (uAlgorithm == 1) {\n \n \n vec2 refrUv = clamp(vUv + normal.xy * uRefraction * density * 3.0, 0.0, 1.0);\n vec3 refrBg = mix(uWaterColor, texture2D(uBackground, mix(vUv, refrUv, 1.0 - obs)).rgb, coverage);\n color = refrBg + spec * uGlowColor * 2.5;\n color = mix(color, bg * 0.6, obs * 0.3);\n } else if (uAlgorithm == 2) {\n \n \n float inkD = min(density * 4.0, 1.0);\n vec2 refrUv = clamp(vUv + normal.xy * uRefraction * density * 0.4, 0.0, 1.0);\n vec3 refrBg = mix(uWaterColor, texture2D(uBackground, mix(vUv, refrUv, 1.0 - obs)).rgb, coverage);\n color = mix(refrBg, uWaterColor + spec * uGlowColor, inkD);\n color = mix(color, bg * 0.5, obs * 0.15);\n } else if (uAlgorithm == 3) {\n \n \n vec2 vel = texture2D(uVelocity, vUv).xy;\n float velMag = clamp(length(vel) * 20.0, 0.0, 1.0);\n vec2 warpUv = clamp(vUv + vel * uWarpStrength, 0.0, 1.0);\n vec3 warpBg = mix(uWaterColor, texture2D(uBackground, warpUv).rgb, coverage);\n color = mix(bg, warpBg, velMag * (1.0 - obs));\n color += spec * uGlowColor * velMag * 1.5;\n color += uWaterColor * density * 0.3;\n color = mix(color, bg * 0.5, obs * 0.2);\n } else if (uAlgorithm == 4) {\n \n \n vec2 rippleUv = clamp(vUv + normal.xy * uRefraction * density * 6.0, 0.0, 1.0);\n vec3 refrBg = mix(uWaterColor, texture2D(uBackground, mix(vUv, rippleUv, 1.0 - obs)).rgb, coverage);\n float fresnel = pow(clamp(1.0 - dot(normal, vec3(0.0, 0.0, 1.0)), 0.0, 1.0), 3.0) * density;\n color = refrBg;\n color += fresnel * uGlowColor * 2.0;\n color += spec * uGlowColor * density * 2.0;\n color = mix(color, bg * 0.5, obs * 0.2);\n } else {\n \n \n vec2 refrUv = vUv + normal.xy * uRefraction * density;\n vec3 refrBg = mix(uWaterColor, texture2D(uBackground, mix(vUv, refrUv, 1.0 - obs)).rgb, coverage);\n color = mix(refrBg, uWaterColor, min(density * 1.5, 0.8));\n color += spec * uGlowColor;\n color = mix(color, bg * 0.5, obs * 0.2);\n }\n \n \n float alpha = clamp(max(density * 1.5, coverage), 0.0, 1.0);\n if (uEnableAlpha == 1) {\n gl_FragColor = vec4(color * alpha, alpha);\n } else {\n gl_FragColor = vec4(color, 1.0);\n }\n }`)}}function u(e,t,n,r){e.activeTexture(e.TEXTURE0);let i=e.createTexture();e.bindTexture(e.TEXTURE_2D,i),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MIN_FILTER,e.LINEAR),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MAG_FILTER,e.LINEAR),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_S,e.CLAMP_TO_EDGE),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_T,e.CLAMP_TO_EDGE),e.texImage2D(e.TEXTURE_2D,0,t.internalFormat,n,r,0,t.format,t.type,null);let a=e.createFramebuffer();return e.bindFramebuffer(e.FRAMEBUFFER,a),e.framebufferTexture2D(e.FRAMEBUFFER,e.COLOR_ATTACHMENT0,e.TEXTURE_2D,i,0),{tex:i,fbo:a,width:n,height:r}}function d(e,t,n,r){let i=u(e,t,n,r),a=u(e,t,n,r);return{get read(){return i},get write(){return a},swap(){[i,a]=[a,i]},dispose(){e.deleteTexture(i.tex),e.deleteFramebuffer(i.fbo),e.deleteTexture(a.tex),e.deleteFramebuffer(a.fbo)}}}function f(e){let t=e.createBuffer();return e.bindBuffer(e.ARRAY_BUFFER,t),e.bufferData(e.ARRAY_BUFFER,new Float32Array([-1,-1,-1,1,1,1,1,-1]),e.STATIC_DRAW),e.vertexAttribPointer(0,2,e.FLOAT,!1,0,0),e.enableVertexAttribArray(0),function(t){e.bindFramebuffer(e.FRAMEBUFFER,t),e.drawArrays(e.TRIANGLE_FAN,0,4)}}const p={arrayStride:8,attributes:[{shaderLocation:0,offset:0,format:`float32x2`}]},m=new Float32Array([-1,-1,-1,1,1,-1,1,-1,-1,1,1,1]);function h(e){let t=e.createBuffer({size:m.byteLength,usage:GPUBufferUsage.VERTEX|GPUBufferUsage.COPY_DST});return e.queue.writeBuffer(t,0,m),t}function g(e,t,n,r){let i=e.createTexture({size:[n,r],format:t,usage:GPUTextureUsage.TEXTURE_BINDING|GPUTextureUsage.RENDER_ATTACHMENT|GPUTextureUsage.COPY_SRC});return{tex:i,view:i.createView(),width:n,height:r}}function _(e,t,n,r){let i=g(e,t,n,r),a=g(e,t,n,r);return{get read(){return i},get write(){return a},swap(){[i,a]=[a,i]},dispose(){i.tex.destroy(),a.tex.destroy()}}}function v(e,t,n,r){let i=e.createShaderModule({code:t});return e.createRenderPipeline({layout:`auto`,vertex:{module:i,entryPoint:`vs`,buffers:[p]},fragment:{module:i,entryPoint:`fs`,targets:[{format:n,...r?{blend:r}:{}}]},primitive:{topology:`triangle-list`}})}const y={color:{operation:`add`,srcFactor:`one`,dstFactor:`zero`},alpha:{operation:`add`,srcFactor:`one`,dstFactor:`zero`}};function b(e,t,n=!0){let r=`rgba16float`;return{advection:v(e,`struct U {\n texelSize : vec2f,\n dt : f32,\n dissipation: f32,\n}\n@group(0) @binding(0) var<uniform> u : U;\n@group(0) @binding(1) var samp : sampler;\n@group(0) @binding(2) var uVel : texture_2d<f32>;\n@group(0) @binding(3) var uSrc : texture_2d<f32>;\n@group(0) @binding(4) var uObs : texture_2d<f32>;\n@vertex fn vs(@location(0) a: vec2f) -> VSOut {\n var o: VSOut;\n o.uv = vec2f(a.x * 0.5 + 0.5, 0.5 - a.y * 0.5);\n o.vL = o.uv - vec2f(u.texelSize.x, 0.0);\n o.vR = o.uv + vec2f(u.texelSize.x, 0.0);\n o.vT = o.uv + vec2f(0.0, u.texelSize.y);\n o.vB = o.uv - vec2f(0.0, u.texelSize.y);\n o.pos = vec4f(a, 0.0, 1.0);\n return o;\n}\n@fragment fn fs(i: VSOut) -> @location(0) vec4f {\n let obs = textureSample(uObs, samp, i.uv).r;\n let vel = textureSample(uVel, samp, i.uv).xy;\n let coord = i.uv - u.dt * vel * u.texelSize;\n let src = textureSample(uSrc, samp, coord);\n return u.dissipation * src * (1.0 - obs);\n}`,r),divergence:v(e,`struct U { texelSize: vec2f, _pad: vec2f }\n@group(0) @binding(0) var<uniform> u : U;\n@group(0) @binding(1) var samp : sampler;\n@group(0) @binding(2) var uVel : texture_2d<f32>;\n@group(0) @binding(3) var uObs : texture_2d<f32>;\n@vertex fn vs(@location(0) a: vec2f) -> VSOut {\n var o: VSOut;\n o.uv = vec2f(a.x * 0.5 + 0.5, 0.5 - a.y * 0.5);\n o.vL = o.uv - vec2f(u.texelSize.x, 0.0);\n o.vR = o.uv + vec2f(u.texelSize.x, 0.0);\n o.vT = o.uv + vec2f(0.0, u.texelSize.y);\n o.vB = o.uv - vec2f(0.0, u.texelSize.y);\n o.pos = vec4f(a, 0.0, 1.0);\n return o;\n}\n@fragment fn fs(i: VSOut) -> @location(0) vec4f {\n let L = textureSample(uVel, samp, i.vL).x * (1.0 - textureSample(uObs, samp, i.vL).r);\n let R = textureSample(uVel, samp, i.vR).x * (1.0 - textureSample(uObs, samp, i.vR).r);\n let T = textureSample(uVel, samp, i.vT).y * (1.0 - textureSample(uObs, samp, i.vT).r);\n let B = textureSample(uVel, samp, i.vB).y * (1.0 - textureSample(uObs, samp, i.vB).r);\n return vec4f(0.5 * (R - L + T - B), 0.0, 0.0, 1.0);\n}`,r),pressure:v(e,`struct U { texelSize: vec2f, _pad: vec2f }\n@group(0) @binding(0) var<uniform> u : U;\n@group(0) @binding(1) var samp : sampler;\n@group(0) @binding(2) var uPres: texture_2d<f32>;\n@group(0) @binding(3) var uDiv : texture_2d<f32>;\n@group(0) @binding(4) var uObs : texture_2d<f32>;\n@vertex fn vs(@location(0) a: vec2f) -> VSOut {\n var o: VSOut;\n o.uv = vec2f(a.x * 0.5 + 0.5, 0.5 - a.y * 0.5);\n o.vL = o.uv - vec2f(u.texelSize.x, 0.0);\n o.vR = o.uv + vec2f(u.texelSize.x, 0.0);\n o.vT = o.uv + vec2f(0.0, u.texelSize.y);\n o.vB = o.uv - vec2f(0.0, u.texelSize.y);\n o.pos = vec4f(a, 0.0, 1.0);\n return o;\n}\n@fragment fn fs(i: VSOut) -> @location(0) vec4f {\n let C = textureSample(uPres, samp, i.uv).x;\n let L = mix(textureSample(uPres, samp, i.vL).x, C, textureSample(uObs, samp, i.vL).r);\n let R = mix(textureSample(uPres, samp, i.vR).x, C, textureSample(uObs, samp, i.vR).r);\n let T = mix(textureSample(uPres, samp, i.vT).x, C, textureSample(uObs, samp, i.vT).r);\n let B = mix(textureSample(uPres, samp, i.vB).x, C, textureSample(uObs, samp, i.vB).r);\n let dv = textureSample(uDiv, samp, i.uv).x;\n return vec4f((L + R + B + T - dv) * 0.25, 0.0, 0.0, 1.0);\n}`,r),gradientSubtract:v(e,`struct U { texelSize: vec2f, _pad: vec2f }\n@group(0) @binding(0) var<uniform> u : U;\n@group(0) @binding(1) var samp : sampler;\n@group(0) @binding(2) var uPres: texture_2d<f32>;\n@group(0) @binding(3) var uVel : texture_2d<f32>;\n@group(0) @binding(4) var uObs : texture_2d<f32>;\n@vertex fn vs(@location(0) a: vec2f) -> VSOut {\n var o: VSOut;\n o.uv = vec2f(a.x * 0.5 + 0.5, 0.5 - a.y * 0.5);\n o.vL = o.uv - vec2f(u.texelSize.x, 0.0);\n o.vR = o.uv + vec2f(u.texelSize.x, 0.0);\n o.vT = o.uv + vec2f(0.0, u.texelSize.y);\n o.vB = o.uv - vec2f(0.0, u.texelSize.y);\n o.pos = vec4f(a, 0.0, 1.0);\n return o;\n}\n@fragment fn fs(i: VSOut) -> @location(0) vec4f {\n let obs = textureSample(uObs, samp, i.uv).r;\n let C = textureSample(uPres, samp, i.uv).x;\n let L = mix(textureSample(uPres, samp, i.vL).x, C, textureSample(uObs, samp, i.vL).r);\n let R = mix(textureSample(uPres, samp, i.vR).x, C, textureSample(uObs, samp, i.vR).r);\n let T = mix(textureSample(uPres, samp, i.vT).x, C, textureSample(uObs, samp, i.vT).r);\n let B = mix(textureSample(uPres, samp, i.vB).x, C, textureSample(uObs, samp, i.vB).r);\n let vel = (textureSample(uVel, samp, i.uv).xy - vec2f(R - L, T - B)) * (1.0 - obs);\n return vec4f(vel, 0.0, 1.0);\n}`,r),splat:v(e,`struct U {\n texelSize : vec2f,\n aspectRatio: f32,\n radius : f32,\n color : vec4f, \n point : vec2f,\n _pad : vec2f,\n}\n@group(0) @binding(0) var<uniform> u : U;\n@group(0) @binding(1) var samp : sampler;\n@group(0) @binding(2) var uTgt : texture_2d<f32>;\n@vertex fn vs(@location(0) a: vec2f) -> VSOut {\n var o: VSOut;\n o.uv = vec2f(a.x * 0.5 + 0.5, 0.5 - a.y * 0.5);\n o.vL = o.uv - vec2f(u.texelSize.x, 0.0);\n o.vR = o.uv + vec2f(u.texelSize.x, 0.0);\n o.vT = o.uv + vec2f(0.0, u.texelSize.y);\n o.vB = o.uv - vec2f(0.0, u.texelSize.y);\n o.pos = vec4f(a, 0.0, 1.0);\n return o;\n}\n@fragment fn fs(i: VSOut) -> @location(0) vec4f {\n var p = i.uv - u.point;\n p.x *= u.aspectRatio;\n let sp = exp(-dot(p, p) / u.radius) * u.color.xyz;\n return vec4f(textureSample(uTgt, samp, i.uv).xyz + sp, 1.0);\n}`,r),curl:v(e,`struct U { texelSize: vec2f, _pad: vec2f }\n@group(0) @binding(0) var<uniform> u : U;\n@group(0) @binding(1) var samp : sampler;\n@group(0) @binding(2) var uVel : texture_2d<f32>;\n@vertex fn vs(@location(0) a: vec2f) -> VSOut {\n var o: VSOut;\n o.uv = vec2f(a.x * 0.5 + 0.5, 0.5 - a.y * 0.5);\n o.vL = o.uv - vec2f(u.texelSize.x, 0.0);\n o.vR = o.uv + vec2f(u.texelSize.x, 0.0);\n o.vT = o.uv + vec2f(0.0, u.texelSize.y);\n o.vB = o.uv - vec2f(0.0, u.texelSize.y);\n o.pos = vec4f(a, 0.0, 1.0);\n return o;\n}\n@fragment fn fs(i: VSOut) -> @location(0) vec4f {\n let L = textureSample(uVel, samp, i.vL).y;\n let R = textureSample(uVel, samp, i.vR).y;\n let T = textureSample(uVel, samp, i.vT).x;\n let B = textureSample(uVel, samp, i.vB).x;\n return vec4f(0.5 * (R - L - T + B), 0.0, 0.0, 1.0);\n}`,r),vorticity:v(e,`struct U {\n texelSize: vec2f,\n curl : f32,\n dt : f32,\n}\n@group(0) @binding(0) var<uniform> u : U;\n@group(0) @binding(1) var samp : sampler;\n@group(0) @binding(2) var uVel : texture_2d<f32>;\n@group(0) @binding(3) var uCrl : texture_2d<f32>;\n@vertex fn vs(@location(0) a: vec2f) -> VSOut {\n var o: VSOut;\n o.uv = vec2f(a.x * 0.5 + 0.5, 0.5 - a.y * 0.5);\n o.vL = o.uv - vec2f(u.texelSize.x, 0.0);\n o.vR = o.uv + vec2f(u.texelSize.x, 0.0);\n o.vT = o.uv + vec2f(0.0, u.texelSize.y);\n o.vB = o.uv - vec2f(0.0, u.texelSize.y);\n o.pos = vec4f(a, 0.0, 1.0);\n return o;\n}\n@fragment fn fs(i: VSOut) -> @location(0) vec4f {\n let L = textureSample(uCrl, samp, i.vL).x;\n let R = textureSample(uCrl, samp, i.vR).x;\n let T = textureSample(uCrl, samp, i.vT).x;\n let B = textureSample(uCrl, samp, i.vB).x;\n let C = textureSample(uCrl, samp, i.uv).x;\n var force = 0.5 * vec2f(abs(T) - abs(B), abs(R) - abs(L));\n force /= length(force) + 0.0001;\n force *= u.curl * 30.0 * C;\n let vel = textureSample(uVel, samp, i.uv).xy + force * u.dt;\n return vec4f(vel, 0.0, 1.0);\n}`,r),display:v(e,`struct U {\n texelSize : vec2f,\n refraction : f32,\n specularExp : f32,\n waterColor : vec4f,\n glowColor : vec4f,\n shine : f32,\n warpStrength: f32,\n algorithm : i32,\n enableAlpha : i32,\n}\n@group(0) @binding(0) var<uniform> u : U;\n@group(0) @binding(1) var samp : sampler;\n@group(0) @binding(2) var uTex : texture_2d<f32>;\n@group(0) @binding(3) var uObs : texture_2d<f32>;\n@group(0) @binding(4) var uBg : texture_2d<f32>;\n@group(0) @binding(5) var uCov : texture_2d<f32>;\n@group(0) @binding(6) var uVel : texture_2d<f32>;\n@vertex fn vs(@location(0) a: vec2f) -> VSOut {\n var o: VSOut;\n o.uv = vec2f(a.x * 0.5 + 0.5, 0.5 - a.y * 0.5);\n o.vL = o.uv - vec2f(u.texelSize.x, 0.0);\n o.vR = o.uv + vec2f(u.texelSize.x, 0.0);\n o.vT = o.uv + vec2f(0.0, u.texelSize.y);\n o.vB = o.uv - vec2f(0.0, u.texelSize.y);\n o.pos = vec4f(a, 0.0, 1.0);\n return o;\n}\n@fragment fn fs(i: VSOut) -> @location(0) vec4f {\n let obs = textureSample(uObs, samp, i.uv).r;\n let density = max(textureSample(uTex, samp, i.uv).r, 0.0) * (1.0 - obs);\n let cov = textureSample(uCov, samp, i.uv).r;\n let sx = u.texelSize.x * 6.0;\n let sy = u.texelSize.y * 6.0;\n let d00 = max(textureSample(uTex, samp, i.uv + vec2f(-sx, -sy)).r, 0.0);\n let d10 = max(textureSample(uTex, samp, i.uv + vec2f(0.0, -sy)).r, 0.0);\n let d20 = max(textureSample(uTex, samp, i.uv + vec2f( sx, -sy)).r, 0.0);\n let d01 = max(textureSample(uTex, samp, i.uv + vec2f(-sx, 0.0)).r, 0.0);\n let d21 = max(textureSample(uTex, samp, i.uv + vec2f( sx, 0.0)).r, 0.0);\n let d02 = max(textureSample(uTex, samp, i.uv + vec2f(-sx, sy)).r, 0.0);\n let d12 = max(textureSample(uTex, samp, i.uv + vec2f(0.0, sy)).r, 0.0);\n let d22 = max(textureSample(uTex, samp, i.uv + vec2f( sx, sy)).r, 0.0);\n let gx = (d20 + 2.0*d21 + d22) - (d00 + 2.0*d01 + d02);\n let gy = (d02 + 2.0*d12 + d22) - (d00 + 2.0*d10 + d20);\n let norm = normalize(vec3f(gx, gy, 1.2));\n let ldir = normalize(vec3f(0.5, 1.0, 0.5));\n let halfV = normalize(ldir + vec3f(0.0, 0.0, 1.0));\n let specDen = density * min(density * 5.0, 1.0);\n let spec = pow(max(dot(norm, halfV), 0.0), u.specularExp) * u.shine * specDen;\n let bgRaw = textureSample(uBg, samp, i.uv).rgb;\n let wc = u.waterColor.rgb;\n let gc = u.glowColor.rgb;\n let bg = mix(wc, bgRaw, cov);\n var color = bg;\n if (u.algorithm == 1) {\n let ruv = clamp(i.uv + norm.xy * u.refraction * density * 3.0, vec2f(0.0), vec2f(1.0));\n let rbg = mix(wc, textureSample(uBg, samp, mix(i.uv, ruv, 1.0 - obs)).rgb, cov);\n color = rbg + spec * gc * 2.5;\n color = mix(color, bg * 0.6, obs * 0.3);\n } else if (u.algorithm == 2) {\n let inkD = min(density * 4.0, 1.0);\n let ruv = clamp(i.uv + norm.xy * u.refraction * density * 0.4, vec2f(0.0), vec2f(1.0));\n let rbg = mix(wc, textureSample(uBg, samp, mix(i.uv, ruv, 1.0 - obs)).rgb, cov);\n color = mix(rbg, wc + spec * gc, inkD);\n color = mix(color, bg * 0.5, obs * 0.15);\n } else if (u.algorithm == 3) {\n let vel = textureSample(uVel, samp, i.uv).xy;\n let velMag = clamp(length(vel) * 20.0, 0.0, 1.0);\n let wuv = clamp(i.uv + vel * u.warpStrength, vec2f(0.0), vec2f(1.0));\n let wbg = mix(wc, textureSample(uBg, samp, wuv).rgb, cov);\n color = mix(bg, wbg, velMag * (1.0 - obs));\n color += spec * gc * velMag * 1.5;\n color += wc * density * 0.3;\n color = mix(color, bg * 0.5, obs * 0.2);\n } else if (u.algorithm == 4) {\n let ruv = clamp(i.uv + norm.xy * u.refraction * density * 6.0, vec2f(0.0), vec2f(1.0));\n let rbg = mix(wc, textureSample(uBg, samp, mix(i.uv, ruv, 1.0 - obs)).rgb, cov);\n let fres = pow(clamp(1.0 - dot(norm, vec3f(0.0, 0.0, 1.0)), 0.0, 1.0), 3.0) * density;\n color = rbg;\n color += fres * gc * 2.0;\n color += spec * gc * density * 2.0;\n color = mix(color, bg * 0.5, obs * 0.2);\n } else {\n let ruv = i.uv + norm.xy * u.refraction * density;\n let rbg = mix(wc, textureSample(uBg, samp, mix(i.uv, ruv, 1.0 - obs)).rgb, cov);\n color = mix(rbg, wc, min(density * 1.5, 0.8));\n color += spec * gc;\n color = mix(color, bg * 0.5, obs * 0.2);\n }\n let alpha = clamp(max(density * 1.5, cov), 0.0, 1.0);\n if (u.enableAlpha == 1) {\n return vec4f(color * alpha, alpha);\n }\n return vec4f(color, 1.0);\n}`,t,n?void 0:y)}}function x(e){return e.createSampler({magFilter:`linear`,minFilter:`linear`,addressModeU:`clamp-to-edge`,addressModeV:`clamp-to-edge`})}function S(e,t){return e.createBuffer({size:t,usage:GPUBufferUsage.UNIFORM|GPUBufferUsage.COPY_DST})}function C(e,t,n,r,i,a){let o=new Float32Array([n,r,i,a]);e.queue.writeBuffer(t,0,o)}function w(e,t,n,r){let i=new Float32Array([n,r,0,0]);e.queue.writeBuffer(t,0,i)}function T(e,t,n,r,i,a){let o=new Float32Array([n,r,i,a]);e.queue.writeBuffer(t,0,o)}function E(e,t,n,r,i,a,o,s,c,l,u){let d=new Float32Array(12);d[0]=n,d[1]=r,d[2]=i,d[3]=a,d[4]=o,d[5]=s,d[6]=c,d[7]=0,d[8]=l,d[9]=u,d[10]=0,d[11]=0,e.queue.writeBuffer(t,0,d)}function D(e,t,n,r,i,a,o,s,c,l,u,d){let f=new Float32Array(16),p=new Int32Array(f.buffer);f[0]=n,f[1]=r,f[2]=i,f[3]=a,f[4]=o[0],f[5]=o[1],f[6]=o[2],f[7]=0,f[8]=s[0],f[9]=s[1],f[10]=s[2],f[11]=0,f[12]=c,f[13]=l,p[14]=u,p[15]=+!!d,e.queue.writeBuffer(t,0,f)}function O(e,t,n,r,i){let a=e.beginRenderPass({colorAttachments:[{view:i,clearValue:[0,0,0,0],loadOp:`clear`,storeOp:`store`}]});a.setPipeline(t),a.setBindGroup(0,n),a.setVertexBuffer(0,r),a.draw(6),a.end()}function k(e,t,n,r,i){let a=e.beginRenderPass({colorAttachments:[{view:i,clearValue:[0,0,0,0],loadOp:`clear`,storeOp:`store`}]});a.setPipeline(t),a.setBindGroup(0,n),a.setVertexBuffer(0,r),a.draw(6),a.end()}function A(e,t,n,r,i=`cover`){let a;a=i===`cover`?Math.max(n/e,r/t):i===`contain`?Math.min(n/e,r/t):typeof i==`string`&&i.endsWith(`%`)?Math.min(n/e,r/t)*(parseFloat(i)/100):typeof i==`string`&&i.endsWith(`px`)?parseFloat(i)/Math.max(e,t):typeof i==`number`?i:Math.max(n/e,r/t);let o=e*a,s=t*a;return{x:(n-o)/2,y:(r-s)/2,drawW:o,drawH:s}}function j(e,t,n,r,i=null,a=`cover`){let{text:o,fontSize:s,color:c,fontFamily:l=`sans-serif`,fontWeight:u=900}=r,d=new OffscreenCanvas(t,n),f=d.getContext(`2d`);(e=>{if(i){f.clearRect(0,0,t,n),f.fillStyle=`black`,f.fillRect(0,0,t,n);let{x:e,y:r,drawW:o,drawH:s}=A(i.width,i.height,t,n,a);f.drawImage(i,e,r,o,s)}else f.fillStyle=`black`,f.fillRect(0,0,t,n);f.fillStyle=e,f.font=`${u} ${s}px ${l}`,f.textAlign=`center`,f.textBaseline=`middle`,f.fillText(o,t/2,n/2)})(c);let p=N(e,d);f.fillStyle=`black`,f.fillRect(0,0,t,n),f.fillStyle=`white`,f.font=`${u} ${s}px ${l}`,f.textAlign=`center`,f.textBaseline=`middle`,f.fillText(o,t/2,n/2);let m=N(e,d);return{backgroundTex:p,obstacleTex:m,coverageTex:m}}function M(e,t,n,r,i=0,a=`cover`,o=null,s=`cover`){let c=new OffscreenCanvas(n,r),l=c.getContext(`2d`),{x:u,y:d,drawW:f,drawH:p}=A(t.width,t.height,n,r,a);if(l.clearRect(0,0,n,r),l.fillStyle=`black`,l.fillRect(0,0,n,r),o){let{x:e,y:t,drawW:a,drawH:c}=A(o.width,o.height,n,r,s);l.filter=`brightness(${i}) blur(8px)`,l.drawImage(o,e,t,a,c),l.filter=`none`}l.drawImage(t,u,d,f,p);let m=N(e,c);l.clearRect(0,0,n,r),l.fillStyle=`black`,l.fillRect(0,0,n,r),l.filter=`brightness(${i}) blur(8px)`,l.drawImage(t,u,d,f,p),l.filter=`none`;let h=N(e,c);return l.clearRect(0,0,n,r),l.fillStyle=`black`,l.fillRect(0,0,n,r),l.fillStyle=`white`,l.fillRect(Math.max(0,u),Math.max(0,d),Math.min(f,n-Math.max(0,u)),Math.min(p,r-Math.max(0,d))),{backgroundTex:m,obstacleTex:h,coverageTex:N(e,c)}}function N(e,t){let n=e.createTexture();return e.bindTexture(e.TEXTURE_2D,n),e.pixelStorei(e.UNPACK_FLIP_Y_WEBGL,!0),e.texImage2D(e.TEXTURE_2D,0,e.RGBA,e.RGBA,e.UNSIGNED_BYTE,t),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MIN_FILTER,e.LINEAR),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MAG_FILTER,e.LINEAR),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_S,e.CLAMP_TO_EDGE),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_T,e.CLAMP_TO_EDGE),n}function P(e,t,n,r,i=null,a=`cover`){let{text:o,fontSize:s,color:c,fontFamily:l=`sans-serif`,fontWeight:u=900}=r,d=new OffscreenCanvas(t,n),f=d.getContext(`2d`);(e=>{if(i){f.clearRect(0,0,t,n),f.fillStyle=`black`,f.fillRect(0,0,t,n);let{x:e,y:r,drawW:o,drawH:s}=A(i.width,i.height,t,n,a);f.drawImage(i,e,r,o,s)}else f.fillStyle=`black`,f.fillRect(0,0,t,n);f.fillStyle=e,f.font=`${u} ${s}px ${l}`,f.textAlign=`center`,f.textBaseline=`middle`,f.fillText(o,t/2,n/2)})(c);let p=I(e,d,t,n);f.fillStyle=`black`,f.fillRect(0,0,t,n),f.fillStyle=`white`,f.font=`${u} ${s}px ${l}`,f.textAlign=`center`,f.textBaseline=`middle`,f.fillText(o,t/2,n/2);let m=I(e,d,t,n);return{backgroundTex:p,backgroundView:p.createView(),obstacleTex:m,obstacleView:m.createView(),coverageTex:m,coverageView:m.createView(),sharedCoverage:!0}}function F(e,t,n,r,i=0,a=`cover`,o=null,s=`cover`){let c=new OffscreenCanvas(n,r),l=c.getContext(`2d`),{x:u,y:d,drawW:f,drawH:p}=A(t.width,t.height,n,r,a);if(l.clearRect(0,0,n,r),l.fillStyle=`black`,l.fillRect(0,0,n,r),o){let{x:e,y:t,drawW:a,drawH:c}=A(o.width,o.height,n,r,s);l.filter=`brightness(${i}) blur(8px)`,l.drawImage(o,e,t,a,c),l.filter=`none`}l.drawImage(t,u,d,f,p);let m=I(e,c,n,r);l.clearRect(0,0,n,r),l.fillStyle=`black`,l.fillRect(0,0,n,r),l.filter=`brightness(${i}) blur(8px)`,l.drawImage(t,u,d,f,p),l.filter=`none`;let h=I(e,c,n,r);l.clearRect(0,0,n,r),l.fillStyle=`black`,l.fillRect(0,0,n,r),l.fillStyle=`white`,l.fillRect(Math.max(0,u),Math.max(0,d),Math.min(f,n-Math.max(0,u)),Math.min(p,r-Math.max(0,d)));let g=I(e,c,n,r);return{backgroundTex:m,backgroundView:m.createView(),obstacleTex:h,obstacleView:h.createView(),coverageTex:g,coverageView:g.createView(),sharedCoverage:!1}}function I(e,t,n,r){let i=e.createTexture({size:[n,r],format:`rgba8unorm`,usage:GPUTextureUsage.TEXTURE_BINDING|GPUTextureUsage.COPY_DST|GPUTextureUsage.RENDER_ATTACHMENT});return e.queue.copyExternalImageToTexture({source:t},{texture:i},[n,r]),i}async function L(e){let t=await fetch(e);if(!t.ok)throw Error(`Failed to fetch image: ${e} (${t.status})`);let n=await t.blob();return createImageBitmap(n)}const R=typeof requestAnimationFrame<`u`?requestAnimationFrame.bind(globalThis):e=>setTimeout(e,1e3/60),z=typeof cancelAnimationFrame<`u`?cancelAnimationFrame.bind(globalThis):clearTimeout,B=.016,V={standard:0,glass:1,ink:2,aurora:3,ripple:4};var H=class e{#e;#t=null;#n=null;#r=null;#i=null;#a=null;#o=null;#s=null;#c=null;#l=null;#u=null;#d=null;#f=null;#p=null;#m=null;#h=null;#g=null;#_=null;#v=null;#y=null;#b=null;#x=null;#S=null;#C=null;#w=null;#T=null;#E=null;#D=null;#O=null;#k=null;#A=null;#j=null;#M=null;#N=0;#P=0;#F=0;#I=0;#L=1;#R=1;#z=.5;#B=null;#V=`cover`;#H;#U={x:0,y:0,dx:0,dy:0,targetX:0,targetY:0,moved:!1};#W=!1;#G=null;#K=null;#q=!1;#J=!1;#Y=!0;constructor(e,t={},n={},r,a=!0){if(this.#e=e,this.#R=Math.max(.1,Math.min(1,n.dpr??1)),this.#z=Math.max(.1,Math.min(1,n.sim??.5)),this.#H=i(t),this.#Y=a,r)this.#p=r,this.#X(r);else{let{gl:t,ext:n}=o(e,a);this.#t=t,this.#n=n,this.#r=l(t),this.#i=f(t),t.clearColor(0,0,0,+!a)}}static async create(t,n={},r={},i=!0,a=!0){return new e(t,n,r,(i?await s(t,a):null)??void 0,a)}setTextSource(e){this.#G={type:`text`,opts:e},this.#Z(),this.#$(),this.#ee()}async setImageSource(e,t=0,n=`cover`){let r=await L(e);if(this.#J){r.close();return}this.#G={type:`image`,bitmap:r,effect:t,size:n},this.#Z(),this.#$(),this.#ee()}setImageBitmap(e,t=0,n=`cover`){this.#G={type:`image`,bitmap:e,effect:t,size:n},this.#Z(),this.#$(),this.#ee()}setBackground(e,t=`cover`){this.#B&&this.#B!==e&&this.#B.close(),this.#B=e,this.#V=t??`cover`,this.#G&&this.#N>0&&this.#P>0&&this.#$()}handleMove(e,t,n=1){if(!this.#W){this.#U.x=this.#U.targetX=e,this.#U.y=this.#U.targetY=t,this.#W=!0;return}this.#U.moved=!0,this.#U.dx=(e-this.#U.targetX)*n,this.#U.dy=(t-this.#U.targetY)*n,this.#U.targetX=e,this.#U.targetY=t}splat(e,t,n,r,i=1){!this.#q||this.#N===0||(this.#p?this.#ae(e,t,n,r,i):this.#oe(e,t,n,r,i))}updateQuality(e){e.dpr!==void 0&&(this.#R=Math.max(.1,Math.min(1,e.dpr))),e.sim!==void 0&&(this.#z=Math.max(.1,Math.min(1,e.sim)))}resize(e,t,n){if(n===void 0?typeof window<`u`&&window.devicePixelRatio&&(this.#L=window.devicePixelRatio):this.#L=n,e!==void 0&&e>0){if(t===void 0||t<=0)return;this.#N=this.#e.width=e,this.#P=this.#e.height=t,this.#F=Math.max(1,Math.round(e*this.#z)),this.#I=Math.max(1,Math.round(t*this.#z)),this.#Q()}else this.#Z();this.#G&&this.#$(),this.#ee()}updateConfig(e){Object.assign(this.#H,e)}destroy(){if(this.#J=!0,this.stop(),this.#te(),this.#ne(),this.#B&&=(this.#B.close(),null),this.#p)this.#C?.destroy(),this.#w?.destroy(),this.#T?.destroy(),this.#E?.destroy(),this.#D?.destroy(),this.#O?.destroy(),this.#k?.destroy(),this.#A?.destroy(),this.#j?.destroy(),this.#M?.destroy(),this.#h?.destroy(),this.#p.device.destroy();else{let e=this.#t;for(let e of Object.values(this.#r))e.dispose();e.getExtension(`WEBGL_lose_context`)?.loseContext()}}start(){if(this.#K!==null)return;let e=()=>{this.#re(),this.#K=R(e)};this.#K=R(e)}stop(){this.#K!==null&&(z(this.#K),this.#K=null)}get isRunning(){return this.#K!==null}#X(e){let{device:t,format:n}=e;this.#m=b(t,n,this.#Y),this.#h=h(t),this.#g=x(t),this.#C=S(t,16),this.#w=S(t,16),this.#T=S(t,16),this.#E=S(t,16),this.#D=S(t,16),this.#O=S(t,48),this.#k=S(t,48),this.#A=S(t,16),this.#j=S(t,16),this.#M=S(t,64)}#Z(){let e=this.#e;`clientWidth`in e&&e.clientWidth>0?(this.#L=(typeof window<`u`&&window.devicePixelRatio||1)*this.#R,this.#N=e.width=Math.round(e.clientWidth*this.#L),this.#P=e.height=Math.round(e.clientHeight*this.#L)):(this.#N=e.width,this.#P=e.height),!(this.#N===0||this.#P===0)&&(this.#F=Math.max(1,Math.round(this.#N*this.#z)),this.#I=Math.max(1,Math.round(this.#P*this.#z)),this.#Q())}#Q(){if(this.#te(),this.#p){let{device:e}=this.#p,t=`rgba16float`,n=this.#F,r=this.#I;this.#_=_(e,t,n,r),this.#v=_(e,t,n,r),this.#b=_(e,t,n,r),this.#y=g(e,t,n,r),this.#x=g(e,t,n,r)}else{let e=this.#t,t=this.#n,n=this.#F,r=this.#I;this.#a=d(e,t,n,r),this.#o=d(e,t,n,r),this.#c=d(e,t,n,r),this.#s=u(e,t,n,r),this.#l=u(e,t,n,r)}}#$(){if(!(!this.#G||this.#N===0||this.#P===0)){if(this.#ne(),this.#p){let{device:e}=this.#p;this.#G.type===`text`?this.#S=P(e,this.#N,this.#P,this.#G.opts,this.#B,this.#V):this.#S=F(e,this.#G.bitmap,this.#N,this.#P,this.#G.effect,this.#G.size,this.#B,this.#V)}else{let e=this.#t;if(this.#G.type===`text`){let{backgroundTex:t,obstacleTex:n,coverageTex:r}=j(e,this.#N,this.#P,this.#G.opts,this.#B,this.#V);this.#u=t,this.#d=n,this.#f=r}else{let{backgroundTex:t,obstacleTex:n,coverageTex:r}=M(e,this.#G.bitmap,this.#N,this.#P,this.#G.effect,this.#G.size,this.#B,this.#V);this.#u=t,this.#d=n,this.#f=r}}this.#q=!0}}#ee(){this.#q&&!this.isRunning&&this.start()}#te(){if(this.#p)this.#_?.dispose(),this.#v?.dispose(),this.#b?.dispose(),this.#y?.tex.destroy(),this.#x?.tex.destroy(),this.#_=this.#v=this.#b=null,this.#y=this.#x=null;else{let e=this.#t;this.#a?.dispose(),this.#o?.dispose(),this.#c?.dispose(),this.#s&&(e.deleteTexture(this.#s.tex),e.deleteFramebuffer(this.#s.fbo)),this.#l&&(e.deleteTexture(this.#l.tex),e.deleteFramebuffer(this.#l.fbo)),this.#a=this.#o=this.#c=this.#s=this.#l=null}}#ne(){if(this.#p)this.#S&&=(this.#S.backgroundTex.destroy(),this.#S.obstacleTex.destroy(),this.#S.sharedCoverage||this.#S.coverageTex.destroy(),null);else{let e=this.#t;this.#u&&e.deleteTexture(this.#u),this.#d&&e.deleteTexture(this.#d),this.#f&&this.#f!==this.#d&&e.deleteTexture(this.#f),this.#u=this.#d=this.#f=null}}#re(){!this.#q||this.#N===0||(this.#p?this.#ie():this.#se())}#ie(){let e=this.#p,t=e.device,n=this.#m,i=this.#h,a=this.#g,o=this.#H,s=this.#S;if(!this.#_||!this.#v)return;this.#U.x+=(this.#U.targetX-this.#U.x)*.15,this.#U.y+=(this.#U.targetY-this.#U.y)*.15;let c=this.#F,l=this.#I,u=this.#N,d=this.#P,f=1/c,p=1/l;C(t,this.#C,f,p,B,o.velocityDissipation),w(t,this.#T,f,p),w(t,this.#E,f,p),w(t,this.#D,f,p),w(t,this.#A,f,p),T(t,this.#j,f,p,o.curl,B),D(t,this.#M,1/u,1/d,o.refraction,o.specularExp,r(o.waterColor),r(o.glowColor),o.shine,o.warpStrength??.015,V[o.algorithm]??0,this.#Y);let m=t.createCommandEncoder(),h=(e,n)=>t.createBindGroup({layout:e.getBindGroupLayout(0),entries:n}),g={binding:1,resource:a};{let e=h(n.advection,[{binding:0,resource:{buffer:this.#C}},g,{binding:2,resource:this.#v.read.view},{binding:3,resource:this.#v.read.view},{binding:4,resource:s.obstacleView}]);O(m,n.advection,e,i,this.#v.write.view)}this.#v.swap();{C(t,this.#w,f,p,B,o.densityDissipation);let e=h(n.advection,[{binding:0,resource:{buffer:this.#w}},g,{binding:2,resource:this.#v.read.view},{binding:3,resource:this.#_.read.view},{binding:4,resource:s.obstacleView}]);O(m,n.advection,e,i,this.#_.write.view)}this.#_.swap();{let e=h(n.curl,[{binding:0,resource:{buffer:this.#A}},g,{binding:2,resource:this.#v.read.view}]);O(m,n.curl,e,i,this.#x.view)}{let e=h(n.vorticity,[{binding:0,resource:{buffer:this.#j}},g,{binding:2,resource:this.#v.read.view},{binding:3,resource:this.#x.view}]);O(m,n.vorticity,e,i,this.#v.write.view)}if(this.#v.swap(),this.#U.moved){let e=this.#U.x*this.#L/u,r=this.#U.y*this.#L/d;E(t,this.#O,f,p,u/d,o.splatRadius,this.#U.dx*o.splatForce,this.#U.dy*o.splatForce,0,e,r);{let e=h(n.splat,[{binding:0,resource:{buffer:this.#O}},g,{binding:2,resource:this.#v.read.view}]);O(m,n.splat,e,i,this.#v.write.view)}this.#v.swap(),E(t,this.#k,f,p,u/d,o.splatRadius,1,1,1,e,r);{let e=h(n.splat,[{binding:0,resource:{buffer:this.#k}},g,{binding:2,resource:this.#_.read.view}]);O(m,n.splat,e,i,this.#_.write.view)}this.#_.swap(),this.#U.moved=!1}{let e=h(n.divergence,[{binding:0,resource:{buffer:this.#T}},g,{binding:2,resource:this.#v.read.view},{binding:3,resource:s.obstacleView}]);O(m,n.divergence,e,i,this.#y.view)}for(let e=0;e<o.pressureIterations;e++){let e=h(n.pressure,[{binding:0,resource:{buffer:this.#E}},g,{binding:2,resource:this.#b.read.view},{binding:3,resource:this.#y.view},{binding:4,resource:s.obstacleView}]);O(m,n.pressure,e,i,this.#b.write.view),this.#b.swap()}{let e=h(n.gradientSubtract,[{binding:0,resource:{buffer:this.#D}},g,{binding:2,resource:this.#b.read.view},{binding:3,resource:this.#v.read.view},{binding:4,resource:s.obstacleView}]);O(m,n.gradientSubtract,e,i,this.#v.write.view)}this.#v.swap();{let t=e.context.getCurrentTexture().createView(),r=h(n.display,[{binding:0,resource:{buffer:this.#M}},g,{binding:2,resource:this.#_.read.view},{binding:3,resource:s.obstacleView},{binding:4,resource:s.backgroundView},{binding:5,resource:s.coverageView},{binding:6,resource:this.#v.read.view}]);k(m,n.display,r,i,t)}t.queue.submit([m.finish()])}#ae(e,t,n,r,i){let a=this.#p.device,o=this.#m.splat,s=this.#h,c=this.#g,l=this.#H,u=this.#F,d=this.#I,f=1/u,p=1/d,m=a.createCommandEncoder(),h={binding:1,resource:c},g=e=>a.createBindGroup({layout:o.getBindGroupLayout(0),entries:e}),_=e*this.#L/this.#N,v=t*this.#L/this.#P;E(a,this.#O,f,p,this.#N/this.#P,l.splatRadius,n*l.splatForce*i,r*l.splatForce*i,0,_,v),O(m,o,g([{binding:0,resource:{buffer:this.#O}},h,{binding:2,resource:this.#v.read.view}]),s,this.#v.write.view),this.#v.swap(),E(a,this.#k,f,p,this.#N/this.#P,l.splatRadius,i,i,i,_,v),O(m,o,g([{binding:0,resource:{buffer:this.#k}},h,{binding:2,resource:this.#_.read.view}]),s,this.#_.write.view),this.#_.swap(),a.queue.submit([m.finish()])}#oe(e,t,n,r,i){let a=this.#t,o=this.#H,s=this.#r.splat,c=this.#i;a.viewport(0,0,this.#F,this.#I),s.bind(),a.uniform1f(s.uniforms.aspectRatio,this.#N/this.#P),a.uniform2f(s.uniforms.point,e*this.#L/this.#N,1-t*this.#L/this.#P),a.uniform1f(s.uniforms.radius,o.splatRadius),a.uniform1i(s.uniforms.uTarget,0),a.activeTexture(a.TEXTURE0),a.bindTexture(a.TEXTURE_2D,this.#o.read.tex),a.uniform3f(s.uniforms.color,n*o.splatForce*i,-r*o.splatForce*i,0),c(this.#o.write.fbo),this.#o.swap(),a.activeTexture(a.TEXTURE0),a.bindTexture(a.TEXTURE_2D,this.#a.read.tex),a.uniform3f(s.uniforms.color,i,i,i),c(this.#a.write.fbo),this.#a.swap()}#se(){if(!this.#a||!this.#o)return;let e=this.#t,t=this.#H,{advection:n,divergence:i,pressure:a,gradientSubtract:o,splat:s,curl:c,vorticity:l,display:u}=this.#r;this.#U.x+=(this.#U.targetX-this.#U.x)*.15,this.#U.y+=(this.#U.targetY-this.#U.y)*.15;let d=this.#F,f=this.#I,p=this.#i;e.viewport(0,0,d,f),n.bind(),e.uniform2f(n.uniforms.texelSize,1/d,1/f),e.uniform1f(n.uniforms.dt,B),e.uniform1i(n.uniforms.uObstacle,0),e.activeTexture(e.TEXTURE0),e.bindTexture(e.TEXTURE_2D,this.#d),e.uniform1f(n.uniforms.dissipation,t.velocityDissipation),e.uniform1i(n.uniforms.uVelocity,1),e.activeTexture(e.TEXTURE1),e.bindTexture(e.TEXTURE_2D,this.#o.read.tex),e.uniform1i(n.uniforms.uSource,1),p(this.#o.write.fbo),this.#o.swap(),e.uniform1f(n.uniforms.dissipation,t.densityDissipation),e.uniform1i(n.uniforms.uSource,2),e.activeTexture(e.TEXTURE2),e.bindTexture(e.TEXTURE_2D,this.#a.read.tex),p(this.#a.write.fbo),this.#a.swap(),c.bind(),e.uniform2f(c.uniforms.texelSize,1/d,1/f),e.uniform1i(c.uniforms.uVelocity,0),e.activeTexture(e.TEXTURE0),e.bindTexture(e.TEXTURE_2D,this.#o.read.tex),p(this.#l.fbo),l.bind(),e.uniform2f(l.uniforms.texelSize,1/d,1/f),e.uniform1f(l.uniforms.curl,t.curl),e.uniform1f(l.uniforms.dt,B),e.uniform1i(l.uniforms.uVelocity,0),e.activeTexture(e.TEXTURE0),e.bindTexture(e.TEXTURE_2D,this.#o.read.tex),e.uniform1i(l.uniforms.uCurl,1),e.activeTexture(e.TEXTURE1),e.bindTexture(e.TEXTURE_2D,this.#l.tex),p(this.#o.write.fbo),this.#o.swap(),this.#U.moved&&(s.bind(),e.uniform1f(s.uniforms.aspectRatio,this.#N/this.#P),e.uniform2f(s.uniforms.point,this.#U.x*this.#L/this.#N,1-this.#U.y*this.#L/this.#P),e.uniform1f(s.uniforms.radius,t.splatRadius),e.uniform1i(s.uniforms.uTarget,0),e.activeTexture(e.TEXTURE0),e.bindTexture(e.TEXTURE_2D,this.#o.read.tex),e.uniform3f(s.uniforms.color,this.#U.dx*t.splatForce,-this.#U.dy*t.splatForce,0),p(this.#o.write.fbo),this.#o.swap(),e.activeTexture(e.TEXTURE0),e.bindTexture(e.TEXTURE_2D,this.#a.read.tex),e.uniform3f(s.uniforms.color,1,1,1),p(this.#a.write.fbo),this.#a.swap(),this.#U.moved=!1),i.bind(),e.uniform2f(i.uniforms.texelSize,1/d,1/f),e.uniform1i(i.uniforms.uVelocity,0),e.activeTexture(e.TEXTURE0),e.bindTexture(e.TEXTURE_2D,this.#o.read.tex),e.uniform1i(i.uniforms.uObstacle,1),e.activeTexture(e.TEXTURE1),e.bindTexture(e.TEXTURE_2D,this.#d),p(this.#s.fbo),a.bind(),e.uniform2f(a.uniforms.texelSize,1/d,1/f),e.uniform1i(a.uniforms.uDivergence,0),e.activeTexture(e.TEXTURE0),e.bindTexture(e.TEXTURE_2D,this.#s.tex),e.uniform1i(a.uniforms.uObstacle,1),e.activeTexture(e.TEXTURE1),e.bindTexture(e.TEXTURE_2D,this.#d);for(let n=0;n<t.pressureIterations;n++)e.uniform1i(a.uniforms.uPressure,2),e.activeTexture(e.TEXTURE2),e.bindTexture(e.TEXTURE_2D,this.#c.read.tex),p(this.#c.write.fbo),this.#c.swap();o.bind(),e.uniform2f(o.uniforms.texelSize,1/d,1/f),e.uniform1i(o.uniforms.uPressure,0),e.activeTexture(e.TEXTURE0),e.bindTexture(e.TEXTURE_2D,this.#c.read.tex),e.uniform1i(o.uniforms.uVelocity,1),e.activeTexture(e.TEXTURE1),e.bindTexture(e.TEXTURE_2D,this.#o.read.tex),e.uniform1i(o.uniforms.uObstacle,2),e.activeTexture(e.TEXTURE2),e.bindTexture(e.TEXTURE_2D,this.#d),p(this.#o.write.fbo),this.#o.swap(),e.viewport(0,0,this.#N,this.#P),e.bindFramebuffer(e.FRAMEBUFFER,null),e.clear(e.COLOR_BUFFER_BIT),u.bind(),e.uniform2f(u.uniforms.texelSize,1/this.#N,1/this.#P),e.uniform3fv(u.uniforms.uWaterColor,r(t.waterColor)),e.uniform3fv(u.uniforms.uGlowColor,r(t.glowColor)),e.uniform1f(u.uniforms.uRefraction,t.refraction),e.uniform1f(u.uniforms.uSpecularExp,t.specularExp),e.uniform1f(u.uniforms.uShine,t.shine),e.uniform1f(u.uniforms.uWarpStrength,t.warpStrength??.015),e.uniform1i(u.uniforms.uAlgorithm,V[t.algorithm]??0),e.uniform1i(u.uniforms.uEnableAlpha,+!!this.#Y),e.activeTexture(e.TEXTURE0),e.bindTexture(e.TEXTURE_2D,this.#a.read.tex),e.activeTexture(e.TEXTURE1),e.bindTexture(e.TEXTURE_2D,this.#d),e.activeTexture(e.TEXTURE2),e.bindTexture(e.TEXTURE_2D,this.#u),e.activeTexture(e.TEXTURE3),e.bindTexture(e.TEXTURE_2D,this.#f),e.activeTexture(e.TEXTURE4),e.bindTexture(e.TEXTURE_2D,this.#o.read.tex),e.uniform1i(u.uniforms.uTexture,0),e.uniform1i(u.uniforms.uObstacle,1),e.uniform1i(u.uniforms.uBackground,2),e.uniform1i(u.uniforms.uCoverage,3),e.uniform1i(u.uniforms.uVelocity,4),p(null)}};let U=null,W;const G=new Promise(e=>{W=e});self.onmessage=async e=>{let{type:t,...n}=e.data;try{switch(t){case`init`:{let{canvas:e,width:t,height:r,config:i,dpr:a,quality:o,useWebGPU:s,enableAlpha:c}=n;e.width=t,e.height=r,U=await H.create(e,i,o??{},s??!0,c??!0),U.resize(t,r,a||1),W(),self.postMessage({type:`ready`});break}case`setTextSource`:if(await G,!U)return;U.setTextSource(n.opts);break;case`setImageSource`:if(await G,!U)return;await U.setImageSource(n.src,n.effect,n.size);break;case`setImageBitmap`:if(await G,!U)return;U.setImageBitmap(n.bitmap,n.effect,n.size);break;case`setBackground`:if(await G,!U)return;U.setBackground(n.bitmap,n.size);break;case`splat`:if(await G,!U)return;U.splat(n.x,n.y,n.vx,n.vy,n.strength??1);break;case`move`:if(await G,!U)return;U.handleMove(n.x,n.y,n.strength??1);break;case`resize`:if(await G,!U)return;U.resize(n.width,n.height,n.dpr);break;case`updateQuality`:if(await G,!U)return;U.updateQuality(n.quality);break;case`updateConfig`:if(await G,!U)return;U.updateConfig(n.config);break;case`destroy`:await G,U?.destroy(),U=null;break;default:}}catch(e){self.postMessage({type:`error`,message:e?.message??String(e)})}};", ve = typeof self < "u" && self.Blob && new Blob(["URL.revokeObjectURL(import.meta.url);", _e], { type: "text/javascript;charset=utf-8" });
1039
+ function ye(e) {
1040
+ let t;
1041
+ try {
1042
+ if (t = ve && (self.URL || self.webkitURL).createObjectURL(ve), !t) throw "";
1043
+ let n = new Worker(t, {
1044
+ type: "module",
1045
+ name: e?.name
1046
+ });
1047
+ return n.addEventListener("error", () => {
1048
+ (self.URL || self.webkitURL).revokeObjectURL(t);
1049
+ }), n;
1050
+ } catch {
1051
+ return new Worker("data:text/javascript;charset=utf-8," + encodeURIComponent(_e), {
1052
+ type: "module",
1053
+ name: e?.name
1054
+ });
1055
+ }
1470
1056
  }
1471
- const $C = typeof Worker < "u" && typeof OffscreenCanvas < "u";
1472
- var W, f, qg, $g, Tg, q, ag, hg, bg, pI, QI, kI, aC;
1473
- class gi {
1474
- constructor(g, {
1475
- workerEnabled: C = !0,
1476
- webGPUEnabled: i = !0,
1477
- alphaEnabled: s = !0,
1478
- quality: t = {},
1479
- config: l = {}
1480
- } = {}) {
1481
- // ---------------------------------------------------------------------------
1482
- // Private
1483
- // ---------------------------------------------------------------------------
1484
- /**
1485
- * Main-thread renderer init.
1486
- *
1487
- * When `navigator.gpu` is present we attempt WebGPU asynchronously and
1488
- * queue any source calls that arrive before the init resolves.
1489
- *
1490
- * When `navigator.gpu` is absent we fall back to WebGL synchronously
1491
- * this is the common path in jsdom/test environments and keeps the
1492
- * constructor behaviour synchronous where possible.
1493
- */
1494
- A(this, pI);
1495
- A(this, kI);
1496
- A(this, W, null);
1497
- A(this, f, null);
1498
- A(this, qg, void 0);
1499
- A(this, $g, void 0);
1500
- A(this, Tg, void 0);
1501
- A(this, q, void 0);
1502
- A(this, ag, void 0);
1503
- // Pending source calls queued while WebGPU async init is in progress (main-thread only)
1504
- A(this, hg, null);
1505
- A(this, bg, null);
1506
- o(this, q, Math.max(0.1, Math.min(1, t.dpr ?? 1))), o(this, ag, Math.max(0.1, Math.min(1, t.sim ?? 0.5))), o(this, $g, i), o(this, Tg, s), o(this, qg, C && $C), I(this, qg) ? h(this, kI, aC).call(this, g, l) : h(this, pI, QI).call(this, g, l);
1507
- }
1508
- // ---------------------------------------------------------------------------
1509
- // Source setters
1510
- // ---------------------------------------------------------------------------
1511
- setTextSource(g) {
1512
- I(this, W) ? I(this, W).postMessage({ type: "setTextSource", opts: g }) : I(this, f) ? I(this, f).setTextSource(g) : (o(this, hg, g), o(this, bg, null));
1513
- }
1514
- setImageSource(g, C = rg.effect, i = rg.imageSize) {
1515
- if (I(this, W)) {
1516
- const s = new URL(g, location.href).href;
1517
- I(this, W).postMessage({ type: "setImageSource", src: s, effect: C, size: i });
1518
- } else
1519
- I(this, f) ? I(this, f).setImageSource(g, C, i) : (o(this, bg, { src: g, effect: C, size: i }), o(this, hg, null));
1520
- }
1521
- setBackground(g, C = "cover") {
1522
- var i;
1523
- if (I(this, W)) {
1524
- const s = g ? [g] : [];
1525
- I(this, W).postMessage({ type: "setBackground", bitmap: g ?? null, size: C }, s);
1526
- } else
1527
- (i = I(this, f)) == null || i.setBackground(g ?? null, C);
1528
- }
1529
- // ---------------------------------------------------------------------------
1530
- // Interaction
1531
- // ---------------------------------------------------------------------------
1532
- /**
1533
- * Immediately injects one splat at (x, y) with explicit velocity (vx, vy).
1534
- * Safe to call multiple times per frame. See FluidSimulation.splat for details.
1535
- */
1536
- splat(g, C, i, s, t = 1) {
1537
- I(this, W) ? I(this, W).postMessage({ type: "splat", x: g, y: C, vx: i, vy: s, strength: t }) : I(this, f).splat(g, C, i, s, t);
1538
- }
1539
- handleMove(g, C, i = 1) {
1540
- I(this, W) ? I(this, W).postMessage({ type: "move", x: g, y: C, strength: i }) : I(this, f).handleMove(g, C, i);
1541
- }
1542
- // ---------------------------------------------------------------------------
1543
- // Config + control
1544
- // ---------------------------------------------------------------------------
1545
- updateQuality(g) {
1546
- o(this, q, Math.max(0.1, Math.min(1, g.dpr ?? I(this, q)))), o(this, ag, Math.max(0.1, Math.min(1, g.sim ?? I(this, ag)))), I(this, W) ? I(this, W).postMessage({ type: "updateQuality", quality: { dpr: I(this, q), sim: I(this, ag) } }) : I(this, f).updateQuality(g);
1547
- }
1548
- updateConfig(g) {
1549
- I(this, W) ? I(this, W).postMessage({ type: "updateConfig", config: g }) : I(this, f).updateConfig(g);
1550
- }
1551
- resize(g, C) {
1552
- var s;
1553
- const i = (typeof window < "u" && window.devicePixelRatio || 1) * I(this, q);
1554
- I(this, W) ? I(this, W).postMessage({ type: "resize", width: g, height: C, dpr: i }) : (s = I(this, f)) == null || s.resize(g, C, i);
1555
- }
1556
- destroy() {
1557
- var g;
1558
- if (I(this, W)) {
1559
- const C = I(this, W);
1560
- o(this, W, null), C.postMessage({ type: "destroy" }), setTimeout(() => C.terminate(), 50);
1561
- } else
1562
- (g = I(this, f)) == null || g.destroy(), o(this, f, null);
1563
- }
1564
- }
1565
- W = new WeakMap(), f = new WeakMap(), qg = new WeakMap(), $g = new WeakMap(), Tg = new WeakMap(), q = new WeakMap(), ag = new WeakMap(), hg = new WeakMap(), bg = new WeakMap(), pI = new WeakSet(), QI = function(g, C) {
1566
- const i = { dpr: I(this, q), sim: I(this, ag) };
1567
- I(this, $g) && typeof navigator < "u" && !!navigator.gpu ? XI.create(g, C, i, !0, I(this, Tg)).then((t) => {
1568
- if (o(this, f, t), I(this, hg))
1569
- t.setTextSource(I(this, hg)), o(this, hg, null);
1570
- else if (I(this, bg)) {
1571
- const { src: l, effect: u, size: Z } = I(this, bg);
1572
- t.setImageSource(l, u, Z), o(this, bg, null);
1573
- }
1574
- }).catch((t) => {
1575
- }) : o(this, f, new XI(g, C, i, void 0, I(this, Tg)));
1576
- }, kI = new WeakSet(), aC = function(g, C) {
1577
- const i = (typeof window < "u" && window.devicePixelRatio || 1) * I(this, q), s = Math.round(g.clientWidth * i), t = Math.round(g.clientHeight * i);
1578
- g.width = s, g.height = t;
1579
- let l;
1580
- try {
1581
- l = g.transferControlToOffscreen();
1582
- } catch {
1583
- o(this, qg, !1), h(this, pI, QI).call(this, g, C);
1584
- return;
1585
- }
1586
- const u = o(this, W, new qC());
1587
- u.onerror = (Z) => yI("Worker error:", Z.message), u.onmessage = (Z) => {
1588
- Z.data.type === "error" && yI("Simulation error:", Z.data.message);
1589
- }, u.postMessage(
1590
- {
1591
- type: "init",
1592
- canvas: l,
1593
- width: s,
1594
- height: t,
1595
- config: C,
1596
- dpr: i,
1597
- quality: { dpr: I(this, q), sim: I(this, ag) },
1598
- useWebGPU: I(this, $g),
1599
- enableAlpha: I(this, Tg)
1600
- },
1601
- [l]
1602
- );
1057
+ //#endregion
1058
+ //#region src/fluid-controller.ts
1059
+ var be = typeof Worker < "u" && typeof OffscreenCanvas < "u", xe = class {
1060
+ #e = null;
1061
+ #t = null;
1062
+ #n;
1063
+ #r;
1064
+ #i;
1065
+ #a;
1066
+ #o;
1067
+ #s = null;
1068
+ #c = null;
1069
+ constructor(e, { workerEnabled: t = !0, webGPUEnabled: n = !0, alphaEnabled: r = !0, quality: i = {}, config: a = {} } = {}) {
1070
+ this.#a = Math.max(.1, Math.min(1, i.dpr ?? 1)), this.#o = Math.max(.1, Math.min(1, i.sim ?? .5)), this.#r = n, this.#i = r, this.#n = t && be, this.#n ? this.#u(e, a) : this.#l(e, a);
1071
+ }
1072
+ setTextSource(e) {
1073
+ this.#e ? this.#e.postMessage({
1074
+ type: "setTextSource",
1075
+ opts: e
1076
+ }) : this.#t ? this.#t.setTextSource(e) : (this.#s = e, this.#c = null);
1077
+ }
1078
+ setImageSource(e, t = d.effect, n = d.imageSize) {
1079
+ if (this.#e) {
1080
+ let r = new URL(e, location.href).href;
1081
+ this.#e.postMessage({
1082
+ type: "setImageSource",
1083
+ src: r,
1084
+ effect: t,
1085
+ size: n
1086
+ });
1087
+ } else this.#t ? this.#t.setImageSource(e, t, n) : (this.#c = {
1088
+ src: e,
1089
+ effect: t,
1090
+ size: n
1091
+ }, this.#s = null);
1092
+ }
1093
+ setBackground(e, t = "cover") {
1094
+ if (this.#e) {
1095
+ let n = e ? [e] : [];
1096
+ this.#e.postMessage({
1097
+ type: "setBackground",
1098
+ bitmap: e ?? null,
1099
+ size: t
1100
+ }, n);
1101
+ } else this.#t?.setBackground(e ?? null, t);
1102
+ }
1103
+ splat(e, t, n, r, i = 1) {
1104
+ this.#e ? this.#e.postMessage({
1105
+ type: "splat",
1106
+ x: e,
1107
+ y: t,
1108
+ vx: n,
1109
+ vy: r,
1110
+ strength: i
1111
+ }) : this.#t.splat(e, t, n, r, i);
1112
+ }
1113
+ handleMove(e, t, n = 1) {
1114
+ this.#e ? this.#e.postMessage({
1115
+ type: "move",
1116
+ x: e,
1117
+ y: t,
1118
+ strength: n
1119
+ }) : this.#t.handleMove(e, t, n);
1120
+ }
1121
+ updateQuality(e) {
1122
+ this.#a = Math.max(.1, Math.min(1, e.dpr ?? this.#a)), this.#o = Math.max(.1, Math.min(1, e.sim ?? this.#o)), this.#e ? this.#e.postMessage({
1123
+ type: "updateQuality",
1124
+ quality: {
1125
+ dpr: this.#a,
1126
+ sim: this.#o
1127
+ }
1128
+ }) : this.#t.updateQuality(e);
1129
+ }
1130
+ updateConfig(e) {
1131
+ this.#e ? this.#e.postMessage({
1132
+ type: "updateConfig",
1133
+ config: e
1134
+ }) : this.#t.updateConfig(e);
1135
+ }
1136
+ resize(e, t) {
1137
+ let n = (typeof window < "u" && window.devicePixelRatio || 1) * this.#a;
1138
+ this.#e ? this.#e.postMessage({
1139
+ type: "resize",
1140
+ width: e,
1141
+ height: t,
1142
+ dpr: n
1143
+ }) : this.#t?.resize(e, t, n);
1144
+ }
1145
+ destroy() {
1146
+ if (this.#e) {
1147
+ let e = this.#e;
1148
+ this.#e = null, e.postMessage({ type: "destroy" }), setTimeout(() => e.terminate(), 50);
1149
+ } else this.#t?.destroy(), this.#t = null;
1150
+ }
1151
+ #l(e, t) {
1152
+ let n = {
1153
+ dpr: this.#a,
1154
+ sim: this.#o
1155
+ };
1156
+ this.#r && typeof navigator < "u" && navigator.gpu ? Q.create(e, t, n, !0, this.#i).then((e) => {
1157
+ if (this.#t = e, this.#s) e.setTextSource(this.#s), this.#s = null;
1158
+ else if (this.#c) {
1159
+ let { src: t, effect: n, size: r } = this.#c;
1160
+ e.setImageSource(t, n, r), this.#c = null;
1161
+ }
1162
+ }).catch((e) => {}) : this.#t = new Q(e, t, n, void 0, this.#i);
1163
+ }
1164
+ #u(e, t) {
1165
+ let n = (typeof window < "u" && window.devicePixelRatio || 1) * this.#a, r = Math.round(e.clientWidth * n), i = Math.round(e.clientHeight * n);
1166
+ e.width = r, e.height = i;
1167
+ let a;
1168
+ try {
1169
+ a = e.transferControlToOffscreen();
1170
+ } catch {
1171
+ this.#n = !1, this.#l(e, t);
1172
+ return;
1173
+ }
1174
+ let o = this.#e = new ye();
1175
+ o.onerror = (e) => (e.message, void 0), o.onmessage = (e) => {
1176
+ e.data.type === "error" && e.data.message;
1177
+ }, o.postMessage({
1178
+ type: "init",
1179
+ canvas: a,
1180
+ width: r,
1181
+ height: i,
1182
+ config: t,
1183
+ dpr: n,
1184
+ quality: {
1185
+ dpr: this.#a,
1186
+ sim: this.#o
1187
+ },
1188
+ useWebGPU: this.#r,
1189
+ enableAlpha: this.#i
1190
+ }, [a]);
1191
+ }
1603
1192
  };
1604
- function ZC(e, {
1605
- workerEnabled: g = !0,
1606
- webGPUEnabled: C = !0,
1607
- alphaEnabled: i = !0,
1608
- pixelRatio: s,
1609
- simResolution: t,
1610
- config: l = {}
1611
- } = {}) {
1612
- const u = { dpr: s, sim: t }, Z = Ng(null), d = Ng({ workerEnabled: g, quality: u, config: l }), S = Ng(Math.max(0.1, Math.min(1, s ?? gI.dpr ?? 1))), a = Ng({
1613
- pixelRatio: s,
1614
- simResolution: t
1615
- });
1616
- return lg(() => {
1617
- const c = e.current;
1618
- if (!c)
1619
- return;
1620
- const m = document.createElement("canvas");
1621
- m.id = `fluid_canvas_${Date.now()}`, m.style.cssText = "position:absolute;inset:0;width:100%;height:100%;display:block;", c.appendChild(m);
1622
- const { workerEnabled: B, quality: r, config: w } = d.current, n = (window.devicePixelRatio || 1) * S.current, y = c.getBoundingClientRect(), v = Math.round((y.width || c.clientWidth) * n) || 0, Y = Math.round((y.height || c.clientHeight) * n) || 0;
1623
- v > 0 && (m.width = v, m.height = Y);
1624
- const T = new gi(m, {
1625
- workerEnabled: B,
1626
- webGPUEnabled: C,
1627
- alphaEnabled: i,
1628
- quality: r,
1629
- config: w
1630
- });
1631
- Z.current = T, v > 0 && Y > 0 && T.resize(v, Y);
1632
- const Jg = new ResizeObserver((CI) => {
1633
- for (const iI of CI) {
1634
- const zg = (window.devicePixelRatio || 1) * S.current, { inlineSize: eI, blockSize: sI } = iI.contentBoxSize[0];
1635
- T.resize(Math.round(eI * zg), Math.round(sI * zg));
1636
- }
1637
- });
1638
- return Jg.observe(c), () => {
1639
- Jg.disconnect(), T.destroy(), m.remove(), Z.current = null;
1640
- };
1641
- }, [C, i]), lg(() => {
1642
- S.current = Math.max(0.1, Math.min(1, s ?? gI.dpr ?? 1));
1643
- const c = a.current;
1644
- a.current = { pixelRatio: s, simResolution: t };
1645
- const m = Z.current, B = e.current;
1646
- if (!m || !B || c.pixelRatio === s && c.simResolution === t)
1647
- return;
1648
- m.updateQuality({ dpr: s, sim: t });
1649
- const r = (window.devicePixelRatio || 1) * S.current, w = B.clientWidth, n = B.clientHeight;
1650
- w > 0 && n > 0 && m.resize(Math.round(w * r), Math.round(n * r));
1651
- }, [s, t, C, i]), Z;
1193
+ //#endregion
1194
+ //#region src/react/useFluid.ts
1195
+ function $(e, { workerEnabled: n = !0, webGPUEnabled: i = !0, alphaEnabled: a = !0, pixelRatio: o, simResolution: s, config: c = {} } = {}) {
1196
+ let u = {
1197
+ dpr: o,
1198
+ sim: s
1199
+ }, d = r(null), f = r({
1200
+ workerEnabled: n,
1201
+ quality: u,
1202
+ config: c
1203
+ }), p = r(Math.max(.1, Math.min(1, o ?? l.dpr ?? 1))), m = r({
1204
+ pixelRatio: o,
1205
+ simResolution: s
1206
+ });
1207
+ return t(() => {
1208
+ let t = e.current;
1209
+ if (!t) return;
1210
+ let n = document.createElement("canvas");
1211
+ n.id = `fluid_canvas_${Date.now()}`, n.style.cssText = "position:absolute;inset:0;width:100%;height:100%;display:block;", t.appendChild(n);
1212
+ let { workerEnabled: r, quality: o, config: s } = f.current, c = (window.devicePixelRatio || 1) * p.current, l = t.getBoundingClientRect(), u = Math.round((l.width || t.clientWidth) * c) || 0, m = Math.round((l.height || t.clientHeight) * c) || 0;
1213
+ u > 0 && (n.width = u, n.height = m);
1214
+ let h = new xe(n, {
1215
+ workerEnabled: r,
1216
+ webGPUEnabled: i,
1217
+ alphaEnabled: a,
1218
+ quality: o,
1219
+ config: s
1220
+ });
1221
+ d.current = h, u > 0 && m > 0 && h.resize(u, m);
1222
+ let g = new ResizeObserver((e) => {
1223
+ for (let t of e) {
1224
+ let e = (window.devicePixelRatio || 1) * p.current, { inlineSize: n, blockSize: r } = t.contentBoxSize[0];
1225
+ h.resize(Math.round(n * e), Math.round(r * e));
1226
+ }
1227
+ });
1228
+ return g.observe(t), () => {
1229
+ g.disconnect(), h.destroy(), n.remove(), d.current = null;
1230
+ };
1231
+ }, [i, a]), t(() => {
1232
+ p.current = Math.max(.1, Math.min(1, o ?? l.dpr ?? 1));
1233
+ let t = m.current;
1234
+ m.current = {
1235
+ pixelRatio: o,
1236
+ simResolution: s
1237
+ };
1238
+ let n = d.current, r = e.current;
1239
+ if (!n || !r || t.pixelRatio === o && t.simResolution === s) return;
1240
+ n.updateQuality({
1241
+ dpr: o,
1242
+ sim: s
1243
+ });
1244
+ let i = (window.devicePixelRatio || 1) * p.current, a = r.clientWidth, c = r.clientHeight;
1245
+ a > 0 && c > 0 && n.resize(Math.round(a * i), Math.round(c * i));
1246
+ }, [
1247
+ o,
1248
+ s,
1249
+ i,
1250
+ a
1251
+ ]), d;
1652
1252
  }
1653
- const ei = CC(function({
1654
- text: g,
1655
- fontSize: C = mg.fontSize,
1656
- color: i = mg.color,
1657
- fontFamily: s = mg.fontFamily,
1658
- fontWeight: t = mg.fontWeight,
1659
- className: l,
1660
- style: u,
1661
- preset: Z,
1662
- algorithm: d,
1663
- backgroundColor: S = mg.backgroundColor,
1664
- backgroundSrc: a,
1665
- backgroundSize: c = mg.backgroundSize,
1666
- mouseEnabled: m = mg.mouseEnabled,
1667
- workerEnabled: B = mg.workerEnabled,
1668
- webGPUEnabled: r = !0,
1669
- alphaEnabled: w = !0,
1670
- pixelRatio: n = gI.dpr,
1671
- simResolution: y = gI.sim,
1672
- // FluidConfig flat props
1673
- densityDissipation: v,
1674
- velocityDissipation: Y,
1675
- pressureIterations: T,
1676
- curl: Jg,
1677
- splatRadius: CI,
1678
- splatForce: iI,
1679
- refraction: zg,
1680
- specularExp: eI,
1681
- shine: sI,
1682
- waterColor: MI,
1683
- glowColor: xI,
1684
- warpStrength: tI
1685
- }, lI) {
1686
- const J = Ng(null), oI = Object.fromEntries(
1687
- Object.entries({
1688
- densityDissipation: v,
1689
- velocityDissipation: Y,
1690
- pressureIterations: T,
1691
- curl: Jg,
1692
- splatRadius: CI,
1693
- splatForce: iI,
1694
- refraction: zg,
1695
- specularExp: eI,
1696
- shine: sI,
1697
- waterColor: MI,
1698
- glowColor: xI,
1699
- algorithm: d,
1700
- warpStrength: tI
1701
- }).filter(([, p]) => p !== void 0)
1702
- ), G = ZC(J, {
1703
- workerEnabled: B,
1704
- webGPUEnabled: r,
1705
- alphaEnabled: w,
1706
- pixelRatio: n,
1707
- simResolution: y,
1708
- config: Eg(ZI(oI, Z, jI))
1709
- });
1710
- iC(
1711
- lI,
1712
- () => ({
1713
- reset() {
1714
- var p;
1715
- (p = G.current) == null || p.setTextSource({ text: g, fontSize: C, color: i, fontFamily: s, fontWeight: t });
1716
- },
1717
- move(p, V, k = 1) {
1718
- var R;
1719
- (R = G.current) == null || R.handleMove(p, V, k);
1720
- },
1721
- splat(p, V, k, R, $ = 1) {
1722
- var Zg;
1723
- (Zg = G.current) == null || Zg.splat(p, V, k, R, $);
1724
- },
1725
- updateConfig(p) {
1726
- var V;
1727
- (V = G.current) == null || V.updateConfig(Eg(p));
1728
- }
1729
- }),
1730
- [g, C, i, s, t]
1731
- ), lg(() => {
1732
- var p;
1733
- (p = G.current) == null || p.setTextSource({ text: g, fontSize: C, color: i, fontFamily: s, fontWeight: t });
1734
- }, [g, C, i, s, t, r, w]);
1735
- const z = JSON.stringify(oI);
1736
- return lg(() => {
1737
- var p;
1738
- (p = G.current) == null || p.updateConfig(
1739
- Eg(ZI(oI, Z, jI))
1740
- );
1741
- }, [Z, z, r, w]), lg(() => {
1742
- var V;
1743
- if (!a) {
1744
- (V = G.current) == null || V.setBackground(null);
1745
- return;
1746
- }
1747
- let p = !1;
1748
- return NI(a).then((k) => {
1749
- var R;
1750
- if (p) {
1751
- k.close();
1752
- return;
1753
- }
1754
- (R = G.current) == null || R.setBackground(k, c);
1755
- }).catch((k) => yI()), () => {
1756
- p = !0;
1757
- };
1758
- }, [a, c, r, w]), lg(() => {
1759
- if (!m)
1760
- return;
1761
- const p = J.current;
1762
- if (!p)
1763
- return;
1764
- const V = (R) => {
1765
- var Zg;
1766
- const $ = p.getBoundingClientRect();
1767
- (Zg = G.current) == null || Zg.handleMove(R.clientX - $.left, R.clientY - $.top, 2);
1768
- }, k = (R) => {
1769
- var OI;
1770
- R.preventDefault();
1771
- const $ = p.getBoundingClientRect(), Zg = R.touches[0];
1772
- (OI = G.current) == null || OI.handleMove(Zg.clientX - $.left, Zg.clientY - $.top, 1);
1773
- };
1774
- return p.addEventListener("mousemove", V), p.addEventListener("touchmove", k, { passive: !1 }), () => {
1775
- p.removeEventListener("mousemove", V), p.removeEventListener("touchmove", k);
1776
- };
1777
- }, [m]), /* @__PURE__ */ IC(
1778
- "div",
1779
- {
1780
- ref: J,
1781
- className: l,
1782
- style: {
1783
- position: "relative",
1784
- display: "block",
1785
- width: "100%",
1786
- height: "100%",
1787
- background: S,
1788
- ...u
1789
- }
1790
- }
1791
- );
1792
- }), si = CC(function({
1793
- src: g,
1794
- effect: C = rg.effect,
1795
- imageSize: i = rg.imageSize,
1796
- className: s,
1797
- style: t,
1798
- preset: l,
1799
- algorithm: u,
1800
- backgroundColor: Z = rg.backgroundColor,
1801
- backgroundSrc: d,
1802
- backgroundSize: S = rg.backgroundSize,
1803
- mouseEnabled: a = rg.mouseEnabled,
1804
- workerEnabled: c = rg.workerEnabled,
1805
- webGPUEnabled: m = !0,
1806
- alphaEnabled: B = !0,
1807
- pixelRatio: r = gI.dpr,
1808
- simResolution: w = gI.sim,
1809
- // FluidConfig flat props
1810
- densityDissipation: n,
1811
- velocityDissipation: y,
1812
- pressureIterations: v,
1813
- curl: Y,
1814
- splatRadius: T,
1815
- splatForce: Jg,
1816
- refraction: CI,
1817
- specularExp: iI,
1818
- shine: zg,
1819
- waterColor: eI,
1820
- glowColor: sI,
1821
- warpStrength: MI
1822
- }, xI) {
1823
- const tI = Ng(null), lI = Object.fromEntries(
1824
- Object.entries({
1825
- densityDissipation: n,
1826
- velocityDissipation: y,
1827
- pressureIterations: v,
1828
- curl: Y,
1829
- splatRadius: T,
1830
- splatForce: Jg,
1831
- refraction: CI,
1832
- specularExp: iI,
1833
- shine: zg,
1834
- waterColor: eI,
1835
- glowColor: sI,
1836
- algorithm: u,
1837
- warpStrength: MI
1838
- }).filter(([, G]) => G !== void 0)
1839
- ), J = ZC(tI, {
1840
- workerEnabled: c,
1841
- webGPUEnabled: m,
1842
- alphaEnabled: B,
1843
- pixelRatio: r,
1844
- simResolution: w,
1845
- config: Eg(ZI(lI, l))
1846
- });
1847
- iC(
1848
- xI,
1849
- () => ({
1850
- reset() {
1851
- var G;
1852
- g && ((G = J.current) == null || G.setImageSource(g, C, i));
1853
- },
1854
- move(G, z, p = 1) {
1855
- var V;
1856
- (V = J.current) == null || V.handleMove(G, z, p);
1857
- },
1858
- splat(G, z, p, V, k = 1) {
1859
- var R;
1860
- (R = J.current) == null || R.splat(G, z, p, V, k);
1861
- },
1862
- updateConfig(G) {
1863
- var z;
1864
- (z = J.current) == null || z.updateConfig(Eg(G));
1865
- }
1866
- }),
1867
- [g, C, i]
1868
- ), lg(() => {
1869
- var G;
1870
- g && ((G = J.current) == null || G.setImageSource(g, C, i));
1871
- }, [g, C, i, m, B]);
1872
- const oI = JSON.stringify(lI);
1873
- return lg(() => {
1874
- var G;
1875
- (G = J.current) == null || G.updateConfig(Eg(ZI(lI, l)));
1876
- }, [l, oI, m, B]), lg(() => {
1877
- var z;
1878
- if (!d) {
1879
- (z = J.current) == null || z.setBackground(null);
1880
- return;
1881
- }
1882
- let G = !1;
1883
- return NI(d).then((p) => {
1884
- var V;
1885
- if (G) {
1886
- p.close();
1887
- return;
1888
- }
1889
- (V = J.current) == null || V.setBackground(p, S);
1890
- }).catch((p) => yI()), () => {
1891
- G = !0;
1892
- };
1893
- }, [d, S, m, B]), lg(() => {
1894
- if (!a)
1895
- return;
1896
- const G = tI.current;
1897
- if (!G)
1898
- return;
1899
- const z = (V) => {
1900
- var R;
1901
- const k = G.getBoundingClientRect();
1902
- (R = J.current) == null || R.handleMove(V.clientX - k.left, V.clientY - k.top, 2);
1903
- }, p = (V) => {
1904
- var $;
1905
- V.preventDefault();
1906
- const k = G.getBoundingClientRect(), R = V.touches[0];
1907
- ($ = J.current) == null || $.handleMove(R.clientX - k.left, R.clientY - k.top, 1);
1908
- };
1909
- return G.addEventListener("mousemove", z), G.addEventListener("touchmove", p, { passive: !1 }), () => {
1910
- G.removeEventListener("mousemove", z), G.removeEventListener("touchmove", p);
1911
- };
1912
- }, [a]), /* @__PURE__ */ IC(
1913
- "div",
1914
- {
1915
- ref: tI,
1916
- className: s,
1917
- style: {
1918
- position: "relative",
1919
- display: "block",
1920
- width: "100%",
1921
- height: "100%",
1922
- background: Z,
1923
- ...t
1924
- }
1925
- }
1926
- );
1253
+ //#endregion
1254
+ //#region src/react/FluidText.tsx
1255
+ var Se = e(function({ text: e, fontSize: a = f.fontSize, color: s = f.color, fontFamily: u = f.fontFamily, fontWeight: d = f.fontWeight, className: p, style: m, preset: g, algorithm: _, backgroundColor: v = f.backgroundColor, backgroundSrc: y, backgroundSize: b = f.backgroundSize, mouseEnabled: x = f.mouseEnabled, workerEnabled: S = f.workerEnabled, webGPUEnabled: w = !0, alphaEnabled: T = !0, pixelRatio: E = l.dpr, simResolution: D = l.sim, densityDissipation: O, velocityDissipation: k, pressureIterations: A, curl: j, splatRadius: M, splatForce: N, refraction: P, specularExp: F, shine: I, waterColor: L, glowColor: R, warpStrength: z }, B) {
1256
+ let V = r(null), H = Object.fromEntries(Object.entries({
1257
+ densityDissipation: O,
1258
+ velocityDissipation: k,
1259
+ pressureIterations: A,
1260
+ curl: j,
1261
+ splatRadius: M,
1262
+ splatForce: N,
1263
+ refraction: P,
1264
+ specularExp: F,
1265
+ shine: I,
1266
+ waterColor: L,
1267
+ glowColor: R,
1268
+ algorithm: _,
1269
+ warpStrength: z
1270
+ }).filter(([, e]) => e !== void 0)), U = $(V, {
1271
+ workerEnabled: S,
1272
+ webGPUEnabled: w,
1273
+ alphaEnabled: T,
1274
+ pixelRatio: E,
1275
+ simResolution: D,
1276
+ config: o(h(H, g, c))
1277
+ });
1278
+ return n(B, () => ({
1279
+ reset() {
1280
+ U.current?.setTextSource({
1281
+ text: e,
1282
+ fontSize: a,
1283
+ color: s,
1284
+ fontFamily: u,
1285
+ fontWeight: d
1286
+ });
1287
+ },
1288
+ move(e, t, n = 1) {
1289
+ U.current?.handleMove(e, t, n);
1290
+ },
1291
+ splat(e, t, n, r, i = 1) {
1292
+ U.current?.splat(e, t, n, r, i);
1293
+ },
1294
+ updateConfig(e) {
1295
+ U.current?.updateConfig(o(e));
1296
+ }
1297
+ }), [
1298
+ e,
1299
+ a,
1300
+ s,
1301
+ u,
1302
+ d
1303
+ ]), t(() => {
1304
+ U.current?.setTextSource({
1305
+ text: e,
1306
+ fontSize: a,
1307
+ color: s,
1308
+ fontFamily: u,
1309
+ fontWeight: d
1310
+ });
1311
+ }, [
1312
+ e,
1313
+ a,
1314
+ s,
1315
+ u,
1316
+ d,
1317
+ w,
1318
+ T
1319
+ ]), t(() => {
1320
+ U.current?.updateConfig(o(h(H, g, c)));
1321
+ }, [
1322
+ g,
1323
+ JSON.stringify(H),
1324
+ w,
1325
+ T
1326
+ ]), t(() => {
1327
+ if (!y) {
1328
+ U.current?.setBackground(null);
1329
+ return;
1330
+ }
1331
+ let e = !1;
1332
+ return C(y).then((t) => {
1333
+ if (e) {
1334
+ t.close();
1335
+ return;
1336
+ }
1337
+ U.current?.setBackground(t, b);
1338
+ }).catch((e) => void 0), () => {
1339
+ e = !0;
1340
+ };
1341
+ }, [
1342
+ y,
1343
+ b,
1344
+ w,
1345
+ T
1346
+ ]), t(() => {
1347
+ if (!x) return;
1348
+ let e = V.current;
1349
+ if (!e) return;
1350
+ let t = (t) => {
1351
+ let n = e.getBoundingClientRect();
1352
+ U.current?.handleMove(t.clientX - n.left, t.clientY - n.top, 2);
1353
+ }, n = (t) => {
1354
+ t.preventDefault();
1355
+ let n = e.getBoundingClientRect(), r = t.touches[0];
1356
+ U.current?.handleMove(r.clientX - n.left, r.clientY - n.top, 1);
1357
+ };
1358
+ return e.addEventListener("mousemove", t), e.addEventListener("touchmove", n, { passive: !1 }), () => {
1359
+ e.removeEventListener("mousemove", t), e.removeEventListener("touchmove", n);
1360
+ };
1361
+ }, [x]), /* @__PURE__ */ i("div", {
1362
+ ref: V,
1363
+ className: p,
1364
+ style: {
1365
+ position: "relative",
1366
+ display: "block",
1367
+ width: "100%",
1368
+ height: "100%",
1369
+ background: v,
1370
+ ...m
1371
+ }
1372
+ });
1373
+ }), Ce = e(function({ src: e, effect: a = d.effect, imageSize: s = d.imageSize, className: c, style: u, preset: f, algorithm: p, backgroundColor: m = d.backgroundColor, backgroundSrc: g, backgroundSize: _ = d.backgroundSize, mouseEnabled: v = d.mouseEnabled, workerEnabled: y = d.workerEnabled, webGPUEnabled: b = !0, alphaEnabled: x = !0, pixelRatio: S = l.dpr, simResolution: w = l.sim, densityDissipation: T, velocityDissipation: E, pressureIterations: D, curl: O, splatRadius: k, splatForce: A, refraction: j, specularExp: M, shine: N, waterColor: P, glowColor: F, warpStrength: I }, L) {
1374
+ let R = r(null), z = Object.fromEntries(Object.entries({
1375
+ densityDissipation: T,
1376
+ velocityDissipation: E,
1377
+ pressureIterations: D,
1378
+ curl: O,
1379
+ splatRadius: k,
1380
+ splatForce: A,
1381
+ refraction: j,
1382
+ specularExp: M,
1383
+ shine: N,
1384
+ waterColor: P,
1385
+ glowColor: F,
1386
+ algorithm: p,
1387
+ warpStrength: I
1388
+ }).filter(([, e]) => e !== void 0)), B = $(R, {
1389
+ workerEnabled: y,
1390
+ webGPUEnabled: b,
1391
+ alphaEnabled: x,
1392
+ pixelRatio: S,
1393
+ simResolution: w,
1394
+ config: o(h(z, f))
1395
+ });
1396
+ return n(L, () => ({
1397
+ reset() {
1398
+ e && B.current?.setImageSource(e, a, s);
1399
+ },
1400
+ move(e, t, n = 1) {
1401
+ B.current?.handleMove(e, t, n);
1402
+ },
1403
+ splat(e, t, n, r, i = 1) {
1404
+ B.current?.splat(e, t, n, r, i);
1405
+ },
1406
+ updateConfig(e) {
1407
+ B.current?.updateConfig(o(e));
1408
+ }
1409
+ }), [
1410
+ e,
1411
+ a,
1412
+ s
1413
+ ]), t(() => {
1414
+ e && B.current?.setImageSource(e, a, s);
1415
+ }, [
1416
+ e,
1417
+ a,
1418
+ s,
1419
+ b,
1420
+ x
1421
+ ]), t(() => {
1422
+ B.current?.updateConfig(o(h(z, f)));
1423
+ }, [
1424
+ f,
1425
+ JSON.stringify(z),
1426
+ b,
1427
+ x
1428
+ ]), t(() => {
1429
+ if (!g) {
1430
+ B.current?.setBackground(null);
1431
+ return;
1432
+ }
1433
+ let e = !1;
1434
+ return C(g).then((t) => {
1435
+ if (e) {
1436
+ t.close();
1437
+ return;
1438
+ }
1439
+ B.current?.setBackground(t, _);
1440
+ }).catch((e) => void 0), () => {
1441
+ e = !0;
1442
+ };
1443
+ }, [
1444
+ g,
1445
+ _,
1446
+ b,
1447
+ x
1448
+ ]), t(() => {
1449
+ if (!v) return;
1450
+ let e = R.current;
1451
+ if (!e) return;
1452
+ let t = (t) => {
1453
+ let n = e.getBoundingClientRect();
1454
+ B.current?.handleMove(t.clientX - n.left, t.clientY - n.top, 2);
1455
+ }, n = (t) => {
1456
+ t.preventDefault();
1457
+ let n = e.getBoundingClientRect(), r = t.touches[0];
1458
+ B.current?.handleMove(r.clientX - n.left, r.clientY - n.top, 1);
1459
+ };
1460
+ return e.addEventListener("mousemove", t), e.addEventListener("touchmove", n, { passive: !1 }), () => {
1461
+ e.removeEventListener("mousemove", t), e.removeEventListener("touchmove", n);
1462
+ };
1463
+ }, [v]), /* @__PURE__ */ i("div", {
1464
+ ref: R,
1465
+ className: c,
1466
+ style: {
1467
+ position: "relative",
1468
+ display: "block",
1469
+ width: "100%",
1470
+ height: "100%",
1471
+ background: m,
1472
+ ...u
1473
+ }
1474
+ });
1927
1475
  });
1928
- export {
1929
- eC as DEFAULT_CONFIG,
1930
- jI as DEFAULT_CONFIG_TEXT,
1931
- rg as DEFAULT_PROPS_IMAGE,
1932
- sC as DEFAULT_PROPS_SHARED,
1933
- mg as DEFAULT_PROPS_TEXT,
1934
- gi as FluidController,
1935
- si as FluidImage,
1936
- XI as FluidSimulation,
1937
- ei as FluidText,
1938
- nC as PRESETS,
1939
- BC as PROP_RANGES,
1940
- NI as loadImageBitmap,
1941
- ZI as mergeConfig,
1942
- Eg as normalizeConfig,
1943
- wI as parseColor,
1944
- ZC as useFluid
1945
- };
1476
+ //#endregion
1477
+ export { s as DEFAULT_CONFIG, c as DEFAULT_CONFIG_TEXT, d as DEFAULT_PROPS_IMAGE, u as DEFAULT_PROPS_SHARED, f as DEFAULT_PROPS_TEXT, xe as FluidController, Ce as FluidImage, Q as FluidSimulation, Se as FluidText, p as PRESETS, a as PROP_RANGES, C as loadImageBitmap, h as mergeConfig, o as normalizeConfig, m as parseColor, $ as useFluid };