@sequenza/workbench 1.0.2

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.
@@ -0,0 +1,2800 @@
1
+ import * as z from "twgl.js";
2
+ import { jsx as n, jsxs as p, Fragment as le } from "react/jsx-runtime";
3
+ import { forwardRef as Ge, useRef as R, useEffect as D, useState as y, useCallback as W, createContext as We, useMemo as Q, useContext as ie } from "react";
4
+ import { Handle as Xe, Position as se, getBezierPath as Ee, BaseEdge as Ye, EdgeLabelRenderer as Ke, ReactFlowProvider as Je, applyNodeChanges as Qe, applyEdgeChanges as Ze, addEdge as _e, useReactFlow as en, ReactFlow as nn, Controls as tn, Panel as fe, getOutgoers as Se, getSimpleBezierPath as on } from "@xyflow/react";
5
+ const ye = (e) => {
6
+ const o = e.replace("#", "");
7
+ return [
8
+ parseInt(o.substring(0, 2), 16),
9
+ parseInt(o.substring(2, 4), 16),
10
+ parseInt(o.substring(4, 6), 16)
11
+ ];
12
+ }, rn = (e, o, r) => {
13
+ const [t, s, l] = ye(e), [a, u, i] = ye(o), m = Math.round(t + (a - t) * r).toString(16).padStart(2, "0"), h = Math.round(s + (u - s) * r).toString(16).padStart(2, "0"), c = Math.round(l + (i - l) * r).toString(16).padStart(2, "0");
14
+ return `#${m}${h}${c}`;
15
+ }, ke = (e, o) => {
16
+ const r = Math.max(0, Math.min(1, o)), t = [...e].sort((i, m) => i.position - m.position);
17
+ if (t.length === 0) return "#000000";
18
+ if (t.length === 1 || r <= t[0].position) return t[0].color;
19
+ if (r >= t[t.length - 1].position)
20
+ return t[t.length - 1].color;
21
+ let s = t[0], l = t[t.length - 1];
22
+ for (let i = 0; i < t.length - 1; i++)
23
+ if (r >= t[i].position && r <= t[i + 1].position) {
24
+ s = t[i], l = t[i + 1];
25
+ break;
26
+ }
27
+ const a = l.position - s.position, u = a === 0 ? 0 : (r - s.position) / a;
28
+ return rn(s.color, l.color, u);
29
+ }, sn = (e) => typeof e == "object" && e !== null && e.type === "texture" && "src" in e, an = (e) => typeof e == "object" && e !== null && e.type === "gradient", ln = `#version 300 es
30
+
31
+ precision highp float;
32
+
33
+ in vec2 position;
34
+ in vec2 texcoord;
35
+
36
+ out vec2 vUv;
37
+
38
+ void main() {
39
+ vUv = vec2(texcoord.x, texcoord.y);
40
+ gl_Position = vec4(position, 0.0, 1.0);
41
+ }
42
+ `;
43
+ class cn {
44
+ programs = {};
45
+ fbos = {};
46
+ renderOrder = [];
47
+ // corresponds with shader id
48
+ dependencyMapping = {};
49
+ quad;
50
+ textures = {};
51
+ textureSrcs = {};
52
+ gradientCanvases = {};
53
+ defaultTexture;
54
+ patch;
55
+ gl;
56
+ uniforms;
57
+ onTextureLoaded;
58
+ error = null;
59
+ constructor(o, r) {
60
+ this.patch = r, this.gl = o, this.defaultTexture = z.createTexture(this.gl, {
61
+ minMag: this.gl.NEAREST,
62
+ wrap: this.gl.CLAMP_TO_EDGE,
63
+ auto: !1
64
+ }), z.setTextureFromArray(
65
+ this.gl,
66
+ this.defaultTexture,
67
+ new Uint8Array([0, 0, 0, 255]),
68
+ {
69
+ width: 1,
70
+ height: 1,
71
+ minMag: this.gl.NEAREST,
72
+ wrap: this.gl.CLAMP_TO_EDGE,
73
+ auto: !1
74
+ }
75
+ );
76
+ let t = !1;
77
+ for (let u = 0; u < r.shaders.length && !t; u++) {
78
+ const i = r.shaders[u];
79
+ if (this.programs[i.id] = z.createProgramInfo(
80
+ this.gl,
81
+ [ln, i.source],
82
+ void 0,
83
+ (m) => {
84
+ const h = m.match(/ERROR:\s*\d+:(\d+):/), c = h ? parseInt(h[1], 10) : 0;
85
+ this.error = { message: m, line: c, shaderName: i.name }, t = !0;
86
+ }
87
+ ), t)
88
+ break;
89
+ this.fbos[i.id] = z.createFramebufferInfo(
90
+ this.gl,
91
+ [
92
+ {
93
+ format: this.gl.RGBA,
94
+ min: this.gl.NEAREST,
95
+ mag: this.gl.NEAREST,
96
+ wrap: this.gl.CLAMP_TO_EDGE,
97
+ auto: !1
98
+ }
99
+ ],
100
+ i.resolution.width,
101
+ i.resolution.height
102
+ );
103
+ }
104
+ this.quad = z.primitives.createXYQuadBufferInfo(this.gl);
105
+ const s = {}, l = {};
106
+ this.uniforms = {};
107
+ for (let u = 0; u < this.patch.shaders.length; u++) {
108
+ const i = this.patch.shaders[u];
109
+ s[i.id] = [], l[i.id] = 0, this.dependencyMapping[i.id] = [], this.uniforms[i.id] = {};
110
+ }
111
+ for (const u of this.patch.connections)
112
+ s[u.from].push(u.to), l[u.to] += 1, this.dependencyMapping[u.to].push({
113
+ input: u.input,
114
+ from: u.from
115
+ });
116
+ const a = [...Object.entries(l)].reduce(
117
+ (u, [i, m]) => m === 0 ? [...u, i] : u,
118
+ []
119
+ );
120
+ for (; a.length > 0; ) {
121
+ const u = a.shift();
122
+ this.renderOrder.push(u);
123
+ for (const i of s[u]) {
124
+ const m = l[i] - 1;
125
+ l[i] = m, m === 0 && a.push(i);
126
+ }
127
+ }
128
+ if (this.renderOrder.length < this.patch.shaders.length)
129
+ throw Error("Cycle detected in graph");
130
+ }
131
+ _getOrCreateTexture(o) {
132
+ if (!this.textures[o]) {
133
+ const r = z.createTexture(this.gl, {
134
+ minMag: this.gl.NEAREST,
135
+ wrap: this.gl.CLAMP_TO_EDGE,
136
+ auto: !1
137
+ });
138
+ z.setTextureFromArray(this.gl, r, new Uint8Array([0, 0, 0, 255]), {
139
+ width: 1,
140
+ height: 1,
141
+ minMag: this.gl.NEAREST,
142
+ wrap: this.gl.CLAMP_TO_EDGE,
143
+ auto: !1
144
+ }), this.textures[o] = r;
145
+ }
146
+ return this.textures[o];
147
+ }
148
+ _updateGradientUniform(o, r) {
149
+ let t = this.gradientCanvases[o];
150
+ t || (t = document.createElement("canvas"), t.width = 256, t.height = 1, this.gradientCanvases[o] = t);
151
+ const s = t.getContext("2d");
152
+ for (let l = 0; l < 256; l++)
153
+ s.fillStyle = ke(r.stops, l / 255), s.fillRect(l, 0, 1, 1);
154
+ return this._updateTextureUniform(o, { type: "texture", src: t });
155
+ }
156
+ _updateTextureUniform(o, r) {
157
+ const t = this._getOrCreateTexture(o), s = r.src;
158
+ if (typeof s == "string") {
159
+ if (this.textureSrcs[o] !== s) {
160
+ this.textureSrcs[o] = s;
161
+ const l = new Image();
162
+ l.onload = () => {
163
+ this.textures[o] === t && (z.setTextureFromElement(this.gl, t, l, {
164
+ minMag: this.gl.NEAREST,
165
+ wrap: this.gl.CLAMP_TO_EDGE,
166
+ auto: !1
167
+ }), this.onTextureLoaded?.());
168
+ }, l.src = s;
169
+ }
170
+ } else
171
+ z.setTextureFromElement(this.gl, t, s, {
172
+ minMag: this.gl.NEAREST,
173
+ wrap: this.gl.CLAMP_TO_EDGE,
174
+ auto: !1
175
+ });
176
+ return t;
177
+ }
178
+ render() {
179
+ if (!this.error)
180
+ for (let o = 0; o < this.renderOrder.length; o++) {
181
+ const r = this.renderOrder[o], t = this.programs[r], s = { ...this.uniforms[r] };
182
+ for (const [l, a] of Object.entries(s))
183
+ sn(a) ? s[l] = this._updateTextureUniform(
184
+ `${r}::${l}`,
185
+ a
186
+ ) : an(a) && (s[l] = this._updateGradientUniform(
187
+ `${r}::${l}`,
188
+ a
189
+ ));
190
+ for (const l of this.dependencyMapping[r])
191
+ s[l.input] = this.fbos[l.from].attachments[0];
192
+ this.gl.useProgram(t.program), o !== this.renderOrder.length - 1 ? z.bindFramebufferInfo(this.gl, this.fbos[r]) : z.bindFramebufferInfo(this.gl, null), z.setUniforms(t, s), z.setBuffersAndAttributes(this.gl, t, this.quad), z.drawBufferInfo(this.gl, this.quad);
193
+ }
194
+ }
195
+ dispose() {
196
+ for (const o of Object.values(this.programs))
197
+ o && o.program && this.gl.deleteProgram(o.program);
198
+ this.programs = {};
199
+ for (const o of Object.values(this.fbos)) {
200
+ for (const r of o.attachments)
201
+ r instanceof WebGLTexture ? this.gl.deleteTexture(r) : r instanceof WebGLRenderbuffer && this.gl.deleteRenderbuffer(r);
202
+ this.gl.deleteFramebuffer(o.framebuffer);
203
+ }
204
+ this.fbos = {};
205
+ for (const o of Object.values(this.textures))
206
+ this.gl.deleteTexture(o);
207
+ this.textures = {}, this.textureSrcs = {}, this.gradientCanvases = {}, this.gl.deleteTexture(this.defaultTexture), this.quad.indices && this.gl.deleteBuffer(this.quad.indices);
208
+ for (const o of Object.values(this.quad.attribs ?? {}))
209
+ o.buffer && this.gl.deleteBuffer(o.buffer);
210
+ }
211
+ }
212
+ const Re = Ge(
213
+ ({ patch: e, uniforms: o, className: r, style: t, width: s = 100, height: l = 100, animate: a, onError: u }, i) => {
214
+ const m = R(null);
215
+ return D(() => {
216
+ if (m.current) {
217
+ const h = m.current.getContext("webgl2", {
218
+ preserveDrawingBuffer: !0
219
+ }), c = new cn(h, e);
220
+ u?.(c.error);
221
+ let f = null;
222
+ const b = () => {
223
+ c.uniforms = o.current, c.render();
224
+ };
225
+ return a ? f = requestAnimationFrame(function C() {
226
+ b(), f = requestAnimationFrame(C);
227
+ }) : (c.onTextureLoaded = b, b()), () => {
228
+ f !== null && cancelAnimationFrame(f), c.dispose();
229
+ };
230
+ }
231
+ }, [e, s, l, a]), /* @__PURE__ */ n(
232
+ "canvas",
233
+ {
234
+ className: `image-crisp ${r ?? ""}`,
235
+ style: t,
236
+ width: s,
237
+ height: l,
238
+ ref: (h) => {
239
+ m.current = h, typeof i == "function" ? i(h) : i && (i.current = h);
240
+ }
241
+ }
242
+ );
243
+ }
244
+ ), T = "([-\\d.]+)", O = "\\s*,\\s*", ae = (e) => {
245
+ const o = [], r = e.source.split(`
246
+ `);
247
+ for (const t of r) {
248
+ const s = t.trim(), l = s.match(
249
+ new RegExp(
250
+ `^uniform\\s+float\\s+(\\w+)\\s*;.*\\/\\/\\s*\\[\\s*${T}${O}${T}${O}${T}\\s*\\]`
251
+ )
252
+ );
253
+ if (l?.[1]) {
254
+ const v = parseFloat(l[2]), E = parseFloat(l[3]), U = parseFloat(l[4]);
255
+ o.push({
256
+ name: l[1],
257
+ type: "float",
258
+ min: v,
259
+ max: E,
260
+ default: U
261
+ });
262
+ continue;
263
+ }
264
+ const a = s.match(
265
+ /^uniform\s+float\s+(\w+)\s*;.*\/\/\s*time\b/
266
+ );
267
+ if (a?.[1]) {
268
+ o.push({ name: a[1], type: "float", special: "time" });
269
+ continue;
270
+ }
271
+ const u = s.match(/^uniform\s+float\s+(\w+)\s*;/);
272
+ if (u?.[1]) {
273
+ o.push({ name: u[1], type: "float" });
274
+ continue;
275
+ }
276
+ const i = s.match(
277
+ new RegExp(
278
+ `^uniform\\s+vec2\\s+(\\w+)\\s*;.*\\/\\/\\s*\\[\\s*${T}${O}${T}\\s*\\]`
279
+ )
280
+ );
281
+ if (i?.[1]) {
282
+ const v = [
283
+ parseFloat(i[2]),
284
+ parseFloat(i[3])
285
+ ];
286
+ o.push({ name: i[1], type: "vec2", default: v });
287
+ continue;
288
+ }
289
+ const m = s.match(
290
+ new RegExp(
291
+ `^uniform\\s+vec3\\s+(\\w+)\\s*;.*\\/\\/\\s*color(?:\\s*\\[\\s*${T}${O}${T}${O}${T}\\s*\\])?`
292
+ )
293
+ );
294
+ if (m?.[1]) {
295
+ const v = m[2] !== void 0 ? [
296
+ parseFloat(m[2]),
297
+ parseFloat(m[3]),
298
+ parseFloat(m[4])
299
+ ] : void 0;
300
+ o.push({
301
+ name: m[1],
302
+ type: "vec3",
303
+ color: !0,
304
+ ...v && { default: v }
305
+ });
306
+ continue;
307
+ }
308
+ const h = s.match(
309
+ new RegExp(
310
+ `^uniform\\s+vec3\\s+(\\w+)\\s*;.*\\/\\/\\s*\\[\\s*${T}${O}${T}${O}${T}\\s*\\]`
311
+ )
312
+ );
313
+ if (h?.[1]) {
314
+ const v = [
315
+ parseFloat(h[2]),
316
+ parseFloat(h[3]),
317
+ parseFloat(h[4])
318
+ ];
319
+ o.push({ name: h[1], type: "vec3", default: v });
320
+ continue;
321
+ }
322
+ const c = s.match(
323
+ new RegExp(
324
+ `^uniform\\s+vec4\\s+(\\w+)\\s*;.*\\/\\/\\s*color(?:\\s*\\[\\s*${T}${O}${T}${O}${T}${O}${T}\\s*\\])?`
325
+ )
326
+ );
327
+ if (c?.[1]) {
328
+ const v = c[2] !== void 0 ? [
329
+ parseFloat(c[2]),
330
+ parseFloat(c[3]),
331
+ parseFloat(c[4]),
332
+ parseFloat(c[5])
333
+ ] : void 0;
334
+ o.push({
335
+ name: c[1],
336
+ type: "vec4",
337
+ color: !0,
338
+ ...v && { default: v }
339
+ });
340
+ continue;
341
+ }
342
+ const f = s.match(
343
+ new RegExp(
344
+ `^uniform\\s+vec4\\s+(\\w+)\\s*;.*\\/\\/\\s*\\[\\s*${T}${O}${T}${O}${T}${O}${T}\\s*\\]`
345
+ )
346
+ );
347
+ if (f?.[1]) {
348
+ const v = [
349
+ parseFloat(f[2]),
350
+ parseFloat(f[3]),
351
+ parseFloat(f[4]),
352
+ parseFloat(f[5])
353
+ ];
354
+ o.push({ name: f[1], type: "vec4", default: v });
355
+ continue;
356
+ }
357
+ const b = s.match(
358
+ /^uniform\s+vec2\s+(\w+)\s*;.*\/\/\s*mouse\b/
359
+ );
360
+ if (b?.[1]) {
361
+ o.push({ name: b[1], type: "vec2", special: "mouse" });
362
+ continue;
363
+ }
364
+ const C = s.match(
365
+ /^uniform\s+vec2\s+(\w+)\s*;.*\/\/\s*resolution\b/
366
+ );
367
+ if (C?.[1]) {
368
+ o.push({ name: C[1], type: "vec2", special: "resolution" });
369
+ continue;
370
+ }
371
+ const N = s.match(/^uniform\s+(vec[234])\s+(\w+)\s*;/);
372
+ if (N) {
373
+ const v = N[1], E = N[2];
374
+ v === "vec2" ? o.push({ name: E, type: "vec2" }) : v === "vec3" ? o.push({ name: E, type: "vec3" }) : v === "vec4" && o.push({ name: E, type: "vec4" });
375
+ continue;
376
+ }
377
+ const F = s.match(
378
+ /^uniform\s+sampler2D\s+(\w+)\s*;(?:.*\/\/\s*(texture|gradient)\b)?/
379
+ );
380
+ if (F?.[1]) {
381
+ const v = F[2], E = v === "texture" ? "texture" : v === "gradient" ? "gradient" : "input";
382
+ o.push({
383
+ name: F[1],
384
+ type: "sampler2D",
385
+ source: E
386
+ });
387
+ }
388
+ }
389
+ return o;
390
+ }, un = `import { RendererComponent, type Uniforms, type Patch } from "@sequenza/lib";
391
+ import "@sequenza/lib/style.css";
392
+ import { useRef } from "react";
393
+
394
+ function SequenzaComponent() {
395
+ const uniformRef = useRef<Record<string, Uniforms>>(getInitialUniforms());
396
+
397
+ return (
398
+ <RendererComponent
399
+ patch={getPatch()}
400
+ uniforms={uniformRef}
401
+ animate={true}
402
+ width={100}
403
+ height={100}
404
+ ></RendererComponent>
405
+ );
406
+ }
407
+
408
+ export default SequenzaComponent;
409
+
410
+ function getInitialUniforms(): Record<string, Uniforms> {
411
+ throw new Error("placeholder for initial uniforms");
412
+ }
413
+
414
+ function getPatch(): Patch {
415
+ throw new Error("placeholder for patch");
416
+ }
417
+ `;
418
+ function dn(e, o) {
419
+ let r = un;
420
+ const t = Object.keys(e).filter((l) => !!o.shaders.find((u) => u.id === l)), s = {};
421
+ for (const l of t)
422
+ s[l] = e[l];
423
+ return r = r.replace(
424
+ 'throw new Error("placeholder for initial uniforms");',
425
+ `return ${JSON.stringify(s, null, 2)};`
426
+ ), r = r.replace(
427
+ 'throw new Error("placeholder for patch");',
428
+ `return ${JSON.stringify(o, null, 2)};`
429
+ ), r;
430
+ }
431
+ const we = 16, Ce = ({ id: e, type: o, position: r }) => {
432
+ const t = o === "source";
433
+ let s;
434
+ return t ? s = "bg-neutral-300 text-neutral-500 hover:border-neutral-500 hover:text-neutral-800 bg-[#78A3C4]" : s = "bg-neutral-300", /* @__PURE__ */ n(
435
+ Xe,
436
+ {
437
+ id: e,
438
+ type: o,
439
+ position: r,
440
+ style: {
441
+ background: "none",
442
+ border: "none",
443
+ width: we,
444
+ height: we
445
+ },
446
+ children: /* @__PURE__ */ n(
447
+ "div",
448
+ {
449
+ className: `absolute inset-0 rounded-full flex items-center justify-center text-xs font-mono leading-none pointer-events-none transition-colors ${s}`
450
+ }
451
+ )
452
+ }
453
+ );
454
+ }, H = ({
455
+ value: e,
456
+ min: o = -1 / 0,
457
+ max: r = 1 / 0,
458
+ step: t = 0.01,
459
+ label: s,
460
+ onChange: l
461
+ }) => {
462
+ const a = R(!1), u = R(0), i = R(0), [m, h] = y(!1), [c, f] = y(""), b = R(null), C = R(null), N = (g) => Math.min(r, Math.max(o, g)), F = W(
463
+ (g) => {
464
+ m || (a.current = !0, u.current = g.clientX, i.current = e, g.preventDefault());
465
+ },
466
+ [e, m]
467
+ );
468
+ D(() => {
469
+ const g = (B) => {
470
+ if (!a.current) return;
471
+ const _ = (B.clientX - u.current) * t;
472
+ l(N(parseFloat((i.current + _).toFixed(6))));
473
+ }, k = () => {
474
+ a.current = !1;
475
+ };
476
+ return window.addEventListener("mousemove", g), window.addEventListener("mouseup", k), () => {
477
+ window.removeEventListener("mousemove", g), window.removeEventListener("mouseup", k);
478
+ };
479
+ }, [t, o, r, l]);
480
+ const v = () => {
481
+ f(String(e)), h(!0), setTimeout(() => b.current?.select(), 0);
482
+ }, E = () => {
483
+ const g = parseFloat(c);
484
+ isNaN(g) || l(N(g)), h(!1);
485
+ }, U = (g) => {
486
+ m || (g.key === "Enter" || g.key === " " ? (g.preventDefault(), f(String(e)), h(!0), setTimeout(() => b.current?.select(), 0)) : g.key === "ArrowRight" || g.key === "ArrowUp" ? (g.preventDefault(), l(N(parseFloat((e + t).toFixed(6))))) : (g.key === "ArrowLeft" || g.key === "ArrowDown") && (g.preventDefault(), l(N(parseFloat((e - t).toFixed(6))))));
487
+ }, S = Number.isInteger(e) ? e.toFixed(1) : e.toFixed(3).replace(/0+$/, "");
488
+ return /* @__PURE__ */ p("div", { className: "flex items-center w-20 relative nodrag", children: [
489
+ s && /* @__PURE__ */ n("span", { className: "absolute left-1 z-10 bg-neutral-200 h-4 w-4 grid place-items-center pointer-events-none rounded-sm", children: /* @__PURE__ */ n("p", { className: "text-[11px] font-mono w-3 text-neutral-500 height-3 leading-0 -translate-y-0.5 translate-x-0.5 ", children: s }) }),
490
+ /* @__PURE__ */ n(
491
+ "div",
492
+ {
493
+ ref: C,
494
+ tabIndex: 0,
495
+ onMouseDown: F,
496
+ onDoubleClick: v,
497
+ onKeyDown: U,
498
+ className: [
499
+ "flex items-center justify-center",
500
+ "rounded overflow-hidden select-none w-full h-6",
501
+ "focus:outline-2 focus:outline-neutral-400 focus:outline-offset-1",
502
+ m ? "cursor-text" : "cursor-ew-resize"
503
+ ].join(" "),
504
+ children: m ? /* @__PURE__ */ n(
505
+ "input",
506
+ {
507
+ ref: b,
508
+ value: c,
509
+ onChange: (g) => f(g.target.value),
510
+ onBlur: E,
511
+ onKeyDown: (g) => {
512
+ g.key === "Enter" && E(), g.key === "Escape" && h(!1);
513
+ },
514
+ className: "outline-none text-neutral-500 text-xs font-mono border-neutral-200 pl-5 rounded-sm text-right w-full h-full bg-white"
515
+ }
516
+ ) : /* @__PURE__ */ n("span", { className: "text-xs font-mono text-neutral-500 pl-5 pointer-events-none border-neutral-200 bg-white rounded-sm w-full h-full flex items-center justify-end px-1", children: /* @__PURE__ */ n("p", { children: S }) })
517
+ }
518
+ )
519
+ ] });
520
+ }, oe = We({
521
+ currentTime: { current: 0 },
522
+ mousePosition: { current: [0, 0] },
523
+ shaders: [],
524
+ patches: {},
525
+ showStats: !1,
526
+ openExportNodeId: null,
527
+ setOpenExportNodeId: () => {
528
+ },
529
+ openPreviewNodeId: null,
530
+ setOpenPreviewNodeId: () => {
531
+ },
532
+ uniforms: { current: {} },
533
+ handleUpdateUniforms: () => {
534
+ },
535
+ handleUpdateNode: (e) => e,
536
+ handleInsertShader: () => {
537
+ }
538
+ }), me = (e) => Math.round(Math.min(1, Math.max(0, e)) * 255).toString(16).padStart(2, "0"), pe = (e) => parseInt(e, 16) / 255, Ue = ([e, o, r]) => `#${me(e)}${me(o)}${me(r)}`, Ie = (e) => [
539
+ pe(e.slice(1, 3)),
540
+ pe(e.slice(3, 5)),
541
+ pe(e.slice(5, 7))
542
+ ], ve = ({ color: e, onChange: o }) => {
543
+ const r = R(null);
544
+ return /* @__PURE__ */ p("div", { className: "relative", children: [
545
+ /* @__PURE__ */ n(
546
+ "button",
547
+ {
548
+ onClick: () => r.current?.click(),
549
+ className: "w-8 h-5.5 rounded border-2 border-neutral-200 cursor-pointer",
550
+ style: { backgroundColor: e },
551
+ title: e
552
+ }
553
+ ),
554
+ /* @__PURE__ */ n(
555
+ "input",
556
+ {
557
+ ref: r,
558
+ type: "color",
559
+ value: e,
560
+ onChange: (t) => o(t.target.value),
561
+ className: "absolute opacity-0 w-0 h-0 pointer-events-none"
562
+ }
563
+ )
564
+ ] });
565
+ }, K = ({ onClick: e }) => /* @__PURE__ */ n(
566
+ "button",
567
+ {
568
+ onClick: e,
569
+ className: "w-6 h-6 flex items-center justify-center text-neutral-400 hover:text-neutral-700 hover:bg-neutral-100 rounded-sm select-none shrink-0",
570
+ title: "Reset to default",
571
+ children: "↺"
572
+ }
573
+ ), fn = ({ name: e, type: o }) => {
574
+ const { showStats: r } = ie(oe);
575
+ return /* @__PURE__ */ p("div", { className: " min-w-40 flex flex-col gap-0.5 items-end", children: [
576
+ /* @__PURE__ */ n("span", { className: "font-mono text-xs text-neutral-900", children: e.replace("u_", "").replaceAll("_", " ").replace(/\b\w/g, (t) => t.toUpperCase()) }),
577
+ r && /* @__PURE__ */ n("span", { className: "font-mono text-[10px] text-neutral-500", children: o })
578
+ ] });
579
+ }, mn = ({ field: e, initialValue: o, handleUpdateUniformField: r }) => {
580
+ const [t, s] = y(o ?? e.default ?? 0), l = (a) => {
581
+ s(a), r(a);
582
+ };
583
+ return /* @__PURE__ */ p("div", { className: "flex items-center ", children: [
584
+ /* @__PURE__ */ n(
585
+ H,
586
+ {
587
+ value: t,
588
+ min: e.min,
589
+ max: e.max,
590
+ step: 0.01,
591
+ onChange: l
592
+ }
593
+ ),
594
+ e.default !== void 0 && /* @__PURE__ */ n(K, { onClick: () => l(e.default) })
595
+ ] });
596
+ }, pn = ({ field: e, initialValue: o, handleUpdateUniformField: r }) => {
597
+ const [t, s] = y(
598
+ o ?? e.default ?? [0, 0]
599
+ ), l = (a, u) => {
600
+ const i = [...t];
601
+ i[a] = u, s(i), r(i);
602
+ };
603
+ return /* @__PURE__ */ p("div", { className: "flex items-center ", children: [
604
+ /* @__PURE__ */ n("div", { className: "flex gap-2 flex-wrap flex-col", children: ["x", "y"].map((a, u) => /* @__PURE__ */ n(
605
+ H,
606
+ {
607
+ label: a,
608
+ value: t[u],
609
+ onChange: (i) => l(u, i)
610
+ },
611
+ a
612
+ )) }),
613
+ e.default !== void 0 && /* @__PURE__ */ n(
614
+ K,
615
+ {
616
+ onClick: () => {
617
+ s(e.default), r(e.default);
618
+ }
619
+ }
620
+ )
621
+ ] });
622
+ }, hn = ({ field: e, initialValue: o, handleUpdateUniformField: r }) => {
623
+ const [t, s] = y(
624
+ o ?? e.default ?? [1, 1, 1]
625
+ ), l = (a) => {
626
+ s(a), r(a);
627
+ };
628
+ return /* @__PURE__ */ p("div", { className: "flex items-center ", children: [
629
+ /* @__PURE__ */ n(
630
+ ve,
631
+ {
632
+ color: Ue(t),
633
+ onChange: (a) => l(Ie(a))
634
+ }
635
+ ),
636
+ e.default !== void 0 && /* @__PURE__ */ n(K, { onClick: () => l(e.default) })
637
+ ] });
638
+ }, vn = ({ field: e, initialValue: o, handleUpdateUniformField: r }) => {
639
+ const [t, s] = y(
640
+ o ?? e.default ?? [1, 1, 1, 1]
641
+ ), [l, a, u, i] = t, m = (h) => {
642
+ s(h), r(h);
643
+ };
644
+ return /* @__PURE__ */ p("div", { className: "flex items-center ", children: [
645
+ /* @__PURE__ */ n(
646
+ ve,
647
+ {
648
+ color: Ue([l, a, u]),
649
+ onChange: (h) => {
650
+ const [c, f, b] = Ie(h);
651
+ m([c, f, b, i]);
652
+ }
653
+ }
654
+ ),
655
+ /* @__PURE__ */ n(
656
+ H,
657
+ {
658
+ label: "a",
659
+ value: i,
660
+ min: 0,
661
+ max: 1,
662
+ step: 0.01,
663
+ onChange: (h) => m([l, a, u, h])
664
+ }
665
+ ),
666
+ e.default !== void 0 && /* @__PURE__ */ n(K, { onClick: () => m(e.default) })
667
+ ] });
668
+ }, gn = ({ field: e, initialValue: o, handleUpdateUniformField: r }) => {
669
+ const [t, s] = y(
670
+ o ?? e.default ?? [0, 0, 0]
671
+ ), l = (a, u) => {
672
+ const i = [...t];
673
+ i[a] = u, s(i), r(i);
674
+ };
675
+ return /* @__PURE__ */ p("div", { className: "flex items-center ", children: [
676
+ /* @__PURE__ */ n("div", { className: "flex flex-col gap-2", children: ["x", "y", "z"].map((a, u) => /* @__PURE__ */ n(
677
+ H,
678
+ {
679
+ label: a,
680
+ value: t[u],
681
+ onChange: (i) => l(u, i)
682
+ },
683
+ a
684
+ )) }),
685
+ e.default !== void 0 && /* @__PURE__ */ n(
686
+ K,
687
+ {
688
+ onClick: () => {
689
+ s(e.default), r(e.default);
690
+ }
691
+ }
692
+ )
693
+ ] });
694
+ }, xn = ({ field: e, initialValue: o, handleUpdateUniformField: r }) => {
695
+ const [t, s] = y(
696
+ o ?? e.default ?? [0, 0, 0, 0]
697
+ ), l = (a, u) => {
698
+ const i = [...t];
699
+ i[a] = u, s(i), r(i);
700
+ };
701
+ return /* @__PURE__ */ p("div", { className: "flex items-center gap-2 px-2", children: [
702
+ /* @__PURE__ */ n("div", { className: "flex flex-col gap-2", children: ["x", "y", "z", "w"].map((a, u) => /* @__PURE__ */ n(
703
+ H,
704
+ {
705
+ label: a,
706
+ value: t[u],
707
+ onChange: (i) => l(u, i)
708
+ },
709
+ a
710
+ )) }),
711
+ e.default !== void 0 && /* @__PURE__ */ n(
712
+ K,
713
+ {
714
+ onClick: () => {
715
+ s(e.default), r(e.default);
716
+ }
717
+ }
718
+ )
719
+ ] });
720
+ }, bn = ({ handleUpdateUniformField: e }) => {
721
+ const [o, r] = y(!1), [t, s] = y(0), l = R(0), a = R(0), u = R(0), i = R(e);
722
+ i.current = e, D(() => {
723
+ if (!o) return;
724
+ a.current = Date.now();
725
+ const c = () => {
726
+ const f = l.current + (Date.now() - a.current) / 1e3;
727
+ s(f), i.current(f), u.current = requestAnimationFrame(c);
728
+ };
729
+ return u.current = requestAnimationFrame(c), () => {
730
+ cancelAnimationFrame(u.current), l.current += (Date.now() - a.current) / 1e3;
731
+ };
732
+ }, [o]);
733
+ const m = () => r((c) => !c), h = () => {
734
+ r(!1), l.current = 0, s(0), i.current(0);
735
+ };
736
+ return /* @__PURE__ */ p("div", { className: "flex items-center ", children: [
737
+ /* @__PURE__ */ n(
738
+ "button",
739
+ {
740
+ onClick: m,
741
+ className: "text-xs font-mono text-neutral-500 bg-neutral-100 hover:bg-neutral-200 rounded-sm w-6 h-6 flex items-center justify-center select-none",
742
+ title: o ? "Pause" : "Play",
743
+ children: o ? "⏸" : "▶"
744
+ }
745
+ ),
746
+ /* @__PURE__ */ p("span", { className: "font-mono text-xs text-neutral-500 px-2 w-16 text-right tabular-nums", children: [
747
+ t.toFixed(2),
748
+ "s"
749
+ ] }),
750
+ /* @__PURE__ */ n(K, { onClick: h })
751
+ ] });
752
+ }, _n = ({ handleUpdateUniformField: e }) => {
753
+ const { mousePosition: o } = ie(oe), [r, t] = y([0, 0]), s = R(e);
754
+ return s.current = e, D(() => {
755
+ let l;
756
+ const a = () => {
757
+ const u = [
758
+ o.current[0],
759
+ o.current[1]
760
+ ];
761
+ t(u), s.current(u), l = requestAnimationFrame(a);
762
+ };
763
+ return l = requestAnimationFrame(a), () => cancelAnimationFrame(l);
764
+ }, []), /* @__PURE__ */ n("div", { className: "flex items-center ", children: /* @__PURE__ */ n("div", { className: "flex gap-2 flex-col", children: ["x", "y"].map((l, a) => /* @__PURE__ */ p("div", { className: "flex items-center w-20 relative", children: [
765
+ /* @__PURE__ */ n("span", { className: "absolute left-1 z-10 bg-neutral-200 h-4 w-4 grid place-items-center pointer-events-none rounded-sm", children: /* @__PURE__ */ n("p", { className: "text-[11px] font-mono w-3 text-neutral-500 leading-0 -translate-y-0.5 translate-x-0.5", children: l }) }),
766
+ /* @__PURE__ */ n("span", { className: "text-xs font-mono text-neutral-500 pl-5 pointer-events-none bg-neutral-100 rounded-sm w-full h-6 flex items-center justify-end px-1 tabular-nums", children: r[a].toFixed(3) })
767
+ ] }, l)) }) });
768
+ }, yn = ({ initialValue: e, handleUpdateUniformField: o }) => {
769
+ const [r, t] = y(!1), s = e?.src instanceof HTMLVideoElement ? e.src : null, l = typeof e?.src == "string" ? e.src : s?.src ?? null, a = s !== null, [u, i] = y(l), [m, h] = y(a), [c, f] = y(
770
+ l ? l.split("/").pop() ?? null : null
771
+ ), [b, C] = y(() => s && s.readyState >= 1 ? [s.videoWidth, s.videoHeight] : null);
772
+ D(() => {
773
+ if (b === null) {
774
+ if (s) {
775
+ const v = () => C([s.videoWidth, s.videoHeight]);
776
+ s.readyState >= 1 ? v() : s.addEventListener("loadedmetadata", v, { once: !0 });
777
+ } else if (l && !a) {
778
+ const v = new Image();
779
+ v.onload = () => C([v.naturalWidth, v.naturalHeight]), v.src = l;
780
+ }
781
+ }
782
+ }, []);
783
+ const N = R(null), F = (v) => {
784
+ if (!v) return;
785
+ const E = URL.createObjectURL(v), U = v.type.startsWith("video/");
786
+ if (i(E), h(U), f(v.name), C(null), U) {
787
+ const S = document.createElement("video");
788
+ S.autoplay = !0, S.muted = !0, S.loop = !0, S.playsInline = !0, S.onloadedmetadata = () => C([S.videoWidth, S.videoHeight]), S.src = E, S.play(), o({ type: "texture", src: S });
789
+ } else {
790
+ const S = new Image();
791
+ S.onload = () => C([S.naturalWidth, S.naturalHeight]), S.src = E, o({ type: "texture", src: E });
792
+ }
793
+ };
794
+ return D(() => {
795
+ if (!r) return;
796
+ const v = (E) => {
797
+ if (E.clipboardData) {
798
+ for (const U of E.clipboardData.items)
799
+ if (U.type.startsWith("image/") || U.type.startsWith("video/")) {
800
+ F(U.getAsFile());
801
+ break;
802
+ }
803
+ }
804
+ };
805
+ return window.addEventListener("paste", v), () => window.removeEventListener("paste", v);
806
+ }, [r]), /* @__PURE__ */ n("div", { className: "flex items-center ", children: /* @__PURE__ */ p("div", { className: "flex flex-col items-start gap-2", children: [
807
+ /* @__PURE__ */ n(
808
+ "div",
809
+ {
810
+ tabIndex: 0,
811
+ onFocus: () => t(!0),
812
+ onBlur: () => t(!1),
813
+ className: `w-32 h-32 rounded overflow-hidden flex flex-col items-center justify-center cursor-pointer select-none transition border-4 text-neutral-500 text-xs font-mono p-2 ${r ? "bg-neutral-50 border-neutral-300" : "bg-neutral-100 border-neutral-50"}`,
814
+ children: u ? m ? /* @__PURE__ */ n(
815
+ "video",
816
+ {
817
+ src: u,
818
+ className: "w-full h-full object-contain",
819
+ autoPlay: !0,
820
+ muted: !0,
821
+ loop: !0,
822
+ playsInline: !0
823
+ }
824
+ ) : /* @__PURE__ */ n("img", { src: u, className: "w-full h-full object-contain" }) : r ? "cmd+V" : /* @__PURE__ */ p(le, { children: [
825
+ /* @__PURE__ */ n("p", { children: "Paste" }),
826
+ /* @__PURE__ */ n("p", { children: "Here" })
827
+ ] })
828
+ }
829
+ ),
830
+ /* @__PURE__ */ p("div", { className: "flex flex-col items-start gap-0.5", children: [
831
+ /* @__PURE__ */ n(
832
+ "button",
833
+ {
834
+ className: "button-base",
835
+ onClick: () => N.current?.click(),
836
+ children: u ? "Replace" : "Upload"
837
+ }
838
+ ),
839
+ c && /* @__PURE__ */ n(
840
+ "span",
841
+ {
842
+ className: "text-[10px] text-neutral-400 font-mono truncate max-w-32",
843
+ title: c,
844
+ children: c
845
+ }
846
+ ),
847
+ b && /* @__PURE__ */ p("span", { className: "text-[10px] text-neutral-400 font-mono", children: [
848
+ b[0],
849
+ "×",
850
+ b[1]
851
+ ] })
852
+ ] }),
853
+ /* @__PURE__ */ n(
854
+ "input",
855
+ {
856
+ ref: N,
857
+ type: "file",
858
+ accept: "image/*,video/*",
859
+ className: "hidden",
860
+ onChange: (v) => F(v.target.files?.[0] ?? null)
861
+ }
862
+ )
863
+ ] }) });
864
+ }, wn = [
865
+ { position: 0, color: "#000000" },
866
+ { position: 1, color: "#ffffff" }
867
+ ], Cn = ({ width: e, height: o, handleUpdateUniformField: r }) => {
868
+ const t = R(r);
869
+ return t.current = r, D(() => {
870
+ t.current([e, o]);
871
+ }, [e, o]), /* @__PURE__ */ n("div", { className: "flex items-center ", children: /* @__PURE__ */ n("div", { className: "flex gap-2 flex-col", children: ["w", "h"].map((s, l) => /* @__PURE__ */ p("div", { className: "flex items-center w-20 relative", children: [
872
+ /* @__PURE__ */ n("span", { className: "absolute left-1 z-10 bg-neutral-200 h-4 w-4 grid place-items-center pointer-events-none rounded-sm", children: /* @__PURE__ */ n("p", { className: "text-[11px] font-mono w-3 text-neutral-500 leading-0 -translate-y-0.5 translate-x-0.5", children: s }) }),
873
+ /* @__PURE__ */ n("span", { className: "text-xs font-mono text-neutral-500 pl-5 pointer-events-none bg-neutral-100 rounded-sm w-full h-6 flex items-center justify-end px-1 tabular-nums", children: l === 0 ? e : o })
874
+ ] }, s)) }) });
875
+ }, Nn = ({ initialValue: e, handleUpdateUniformField: o }) => {
876
+ const [r, t] = y(
877
+ e?.stops ?? wn
878
+ ), s = R(null), l = R(null);
879
+ D(() => {
880
+ const c = s.current;
881
+ if (!c) return;
882
+ const f = c.getContext("2d");
883
+ if (f) {
884
+ for (let b = 0; b < c.width; b++)
885
+ f.fillStyle = ke(r, b / (c.width - 1)), f.fillRect(b, 0, 1, c.height);
886
+ o({ type: "gradient", stops: r });
887
+ }
888
+ }, [r]);
889
+ const a = (c) => (f) => {
890
+ f.preventDefault();
891
+ const b = l.current;
892
+ if (!b) return;
893
+ const C = (F) => {
894
+ const v = b.getBoundingClientRect(), U = Math.max(0, Math.min(F.clientX - v.left, v.width)) / v.width;
895
+ t(
896
+ (S) => S.map((g, k) => k === c ? { ...g, position: U } : g)
897
+ );
898
+ }, N = () => {
899
+ window.removeEventListener("mousemove", C), window.removeEventListener("mouseup", N);
900
+ };
901
+ window.addEventListener("mousemove", C), window.addEventListener("mouseup", N);
902
+ }, u = () => t((c) => [...c, { position: 1, color: "#ffffff" }]), i = (c) => {
903
+ r.length <= 1 || t((f) => f.filter((b, C) => C !== c));
904
+ }, m = (c, f) => t(
905
+ (b) => b.map((C, N) => N === c ? { ...C, position: f } : C)
906
+ ), h = (c, f) => t((b) => b.map((C, N) => N === c ? { ...C, color: f } : C));
907
+ return /* @__PURE__ */ p("div", { className: "flex flex-col gap-3 p-2", children: [
908
+ /* @__PURE__ */ p("div", { ref: l, className: "relative w-32 h-4 nodrag nopan", children: [
909
+ /* @__PURE__ */ n(
910
+ "canvas",
911
+ {
912
+ ref: s,
913
+ width: 128,
914
+ height: 16,
915
+ className: "w-32 h-4 rounded-sm border-2 border-neutral-200"
916
+ }
917
+ ),
918
+ r.map((c, f) => /* @__PURE__ */ n(
919
+ "button",
920
+ {
921
+ "aria-label": `gradient stop ${f}`,
922
+ className: "absolute w-4 h-4 -translate-x-1/2 -bottom-2 rounded-sm border-2 border-neutral-200 cursor-ew-resize",
923
+ style: {
924
+ left: `${c.position * 100}%`,
925
+ backgroundColor: c.color
926
+ },
927
+ onMouseDown: a(f)
928
+ },
929
+ f
930
+ ))
931
+ ] }),
932
+ /* @__PURE__ */ p("div", { className: "flex items-center justify-between w-32", children: [
933
+ /* @__PURE__ */ n("span", { className: "font-mono text-[10px] text-neutral-500", children: "STOPS" }),
934
+ /* @__PURE__ */ n(
935
+ "button",
936
+ {
937
+ onClick: u,
938
+ className: "font-mono text-[10px] text-neutral-500 hover:text-neutral-800 leading-none",
939
+ children: "ADD +"
940
+ }
941
+ )
942
+ ] }),
943
+ /* @__PURE__ */ n("div", { className: "flex flex-col gap-1.5", children: r.map((c, f) => /* @__PURE__ */ p("div", { className: "flex items-center gap-2", children: [
944
+ /* @__PURE__ */ n(
945
+ H,
946
+ {
947
+ value: c.position,
948
+ min: 0,
949
+ max: 1,
950
+ step: 0.01,
951
+ onChange: (b) => m(f, b)
952
+ }
953
+ ),
954
+ /* @__PURE__ */ n(
955
+ ve,
956
+ {
957
+ color: c.color,
958
+ onChange: (b) => h(f, b)
959
+ }
960
+ ),
961
+ r.length > 1 && /* @__PURE__ */ n(
962
+ "button",
963
+ {
964
+ onClick: () => i(f),
965
+ className: "text-xs text-neutral-400 hover:text-neutral-700 leading-none px-1",
966
+ "aria-label": `remove stop ${f}`,
967
+ children: "×"
968
+ }
969
+ )
970
+ ] }, f)) })
971
+ ] });
972
+ }, En = (e, o) => {
973
+ const r = {};
974
+ for (const t of e)
975
+ switch (t.type) {
976
+ case "float":
977
+ r[t.name] = t.default ?? 0;
978
+ break;
979
+ case "vec2":
980
+ r[t.name] = t.default ?? [0, 0];
981
+ break;
982
+ case "vec3":
983
+ r[t.name] = t.default ?? [0, 0, 0];
984
+ break;
985
+ case "vec4":
986
+ r[t.name] = t.default ?? [0, 0, 0, 0];
987
+ break;
988
+ }
989
+ if (o)
990
+ for (const t of e)
991
+ t.name in o && (r[t.name] = o[t.name]);
992
+ return r;
993
+ };
994
+ function Sn(e) {
995
+ switch (e.type) {
996
+ case "float":
997
+ return e.special === "time" ? "float time" : "float";
998
+ case "vec2":
999
+ return e.special === "mouse" ? "vec2 mouse" : e.special === "resolution" ? "vec2 resolution" : "vec2";
1000
+ case "vec3":
1001
+ return e.color ? "vec3 color" : "vec3";
1002
+ case "vec4":
1003
+ return e.color ? "vec4 color" : "vec4";
1004
+ case "sampler2D":
1005
+ return e.source === "gradient" ? "sampler2D gradient" : "sampler2D texture";
1006
+ }
1007
+ }
1008
+ const Ae = ({
1009
+ shader: e,
1010
+ initialUniforms: o,
1011
+ handleUpdateUniform: r
1012
+ }) => {
1013
+ const t = Q(() => ae(e), [e.source]), s = Q(
1014
+ () => En(t, o),
1015
+ [t]
1016
+ ), l = R(s);
1017
+ return D(() => {
1018
+ l.current = { ...s }, r(l.current);
1019
+ }, [s]), t.length === 0 ? /* @__PURE__ */ p("p", { className: "px-2 py-3 font-mono text-xs", children: [
1020
+ "No uniforms found.",
1021
+ " ",
1022
+ /* @__PURE__ */ p("span", { children: [
1023
+ "Add ",
1024
+ /* @__PURE__ */ n("code", { className: "", children: "// [min, max, default]" }),
1025
+ " comments to float uniforms."
1026
+ ] })
1027
+ ] }) : /* @__PURE__ */ n("div", { className: "rounded flex flex-col gap-1", children: t.map((a) => {
1028
+ const u = `${a.name}-${a.type}`, i = (c) => {
1029
+ l.current[a.name] = c, r(l.current);
1030
+ }, m = (c) => {
1031
+ c === null ? delete l.current[a.name] : l.current[a.name] = c, r(l.current);
1032
+ };
1033
+ let h = null;
1034
+ switch (a.type) {
1035
+ case "float":
1036
+ h = a.special === "time" ? /* @__PURE__ */ n(
1037
+ bn,
1038
+ {
1039
+ field: a,
1040
+ handleUpdateUniformField: i
1041
+ }
1042
+ ) : /* @__PURE__ */ n(
1043
+ mn,
1044
+ {
1045
+ field: a,
1046
+ initialValue: s[a.name],
1047
+ handleUpdateUniformField: i
1048
+ }
1049
+ );
1050
+ break;
1051
+ case "vec2":
1052
+ h = a.special === "mouse" ? /* @__PURE__ */ n(
1053
+ _n,
1054
+ {
1055
+ field: a,
1056
+ handleUpdateUniformField: i
1057
+ }
1058
+ ) : a.special === "resolution" ? /* @__PURE__ */ n(
1059
+ Cn,
1060
+ {
1061
+ field: a,
1062
+ width: e.resolution.width,
1063
+ height: e.resolution.height,
1064
+ handleUpdateUniformField: i
1065
+ }
1066
+ ) : /* @__PURE__ */ n(
1067
+ pn,
1068
+ {
1069
+ field: a,
1070
+ initialValue: s[a.name],
1071
+ handleUpdateUniformField: i
1072
+ }
1073
+ );
1074
+ break;
1075
+ case "vec3":
1076
+ h = a.color ? /* @__PURE__ */ n(
1077
+ hn,
1078
+ {
1079
+ field: a,
1080
+ initialValue: s[a.name],
1081
+ handleUpdateUniformField: i
1082
+ }
1083
+ ) : /* @__PURE__ */ n(
1084
+ gn,
1085
+ {
1086
+ field: a,
1087
+ initialValue: s[a.name],
1088
+ handleUpdateUniformField: i
1089
+ }
1090
+ );
1091
+ break;
1092
+ case "vec4":
1093
+ h = a.color ? /* @__PURE__ */ n(
1094
+ vn,
1095
+ {
1096
+ field: a,
1097
+ initialValue: s[a.name],
1098
+ handleUpdateUniformField: i
1099
+ }
1100
+ ) : /* @__PURE__ */ n(
1101
+ xn,
1102
+ {
1103
+ field: a,
1104
+ initialValue: s[a.name],
1105
+ handleUpdateUniformField: i
1106
+ }
1107
+ );
1108
+ break;
1109
+ case "sampler2D":
1110
+ a.source === "texture" ? h = /* @__PURE__ */ n(
1111
+ yn,
1112
+ {
1113
+ field: a,
1114
+ initialValue: s[a.name],
1115
+ handleUpdateUniformField: m
1116
+ }
1117
+ ) : a.source === "gradient" && (h = /* @__PURE__ */ n(
1118
+ Nn,
1119
+ {
1120
+ field: a,
1121
+ initialValue: s[a.name],
1122
+ handleUpdateUniformField: i
1123
+ }
1124
+ ));
1125
+ break;
1126
+ }
1127
+ return h === null ? null : /* @__PURE__ */ p("div", { className: "flex items-center gap-4 rounded-sm mb-1", children: [
1128
+ /* @__PURE__ */ n(fn, { name: a.name, type: Sn(a) }),
1129
+ /* @__PURE__ */ n("div", { className: "bg-neutral-100 p-1 rounded-md", children: h })
1130
+ ] }, u);
1131
+ }) });
1132
+ }, ce = ({
1133
+ children: e,
1134
+ open: o,
1135
+ className: r,
1136
+ handleOpenChange: t
1137
+ }) => {
1138
+ const s = R(null), [l, a] = y(o);
1139
+ return D(() => {
1140
+ a(!!o);
1141
+ }, [o]), D(() => {
1142
+ s.current !== null && (l ? s.current.showModal() : s.current.close()), t(l);
1143
+ }, [l]), /* @__PURE__ */ n(
1144
+ "dialog",
1145
+ {
1146
+ ref: s,
1147
+ className: `top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 w-3xl h-5/6 border border-neutral-300 rounded-lg starting:opacity-0 opacity-100 transition-all transition-discrete ${l ? "visible" : "hidden"} ${r} nopan nodrag nowheel`,
1148
+ children: e
1149
+ }
1150
+ );
1151
+ }, Ne = "pnpm i @sequenza/lib", Te = ({
1152
+ uniforms: e,
1153
+ patch: o,
1154
+ open: r,
1155
+ onOpenChange: t
1156
+ }) => {
1157
+ const s = dn(e, o), [l, a] = y("idle"), [u, i] = y("idle");
1158
+ return /* @__PURE__ */ p(
1159
+ ce,
1160
+ {
1161
+ open: r,
1162
+ handleOpenChange: t,
1163
+ className: "flex flex-col gap-4 p-6 overflow-y-auto",
1164
+ children: [
1165
+ /* @__PURE__ */ p("div", { className: "flex items-center justify-between", children: [
1166
+ /* @__PURE__ */ n("h2", { className: "text-sm font-medium text-neutral-800", children: "Integrate shader" }),
1167
+ /* @__PURE__ */ n("button", { className: "button-base", onClick: () => t(!1), children: "Close" })
1168
+ ] }),
1169
+ /* @__PURE__ */ p("div", { className: "flex flex-col gap-1", children: [
1170
+ /* @__PURE__ */ n("p", { className: "text-xs text-neutral-500", children: "Install" }),
1171
+ /* @__PURE__ */ p("div", { className: "flex items-center gap-2 bg-neutral-50 rounded py-4 px-4", children: [
1172
+ /* @__PURE__ */ n("code", { className: "text-xs text-neutral-700 w-full select-all", children: Ne }),
1173
+ /* @__PURE__ */ n("button", { className: "button-base", onClick: () => {
1174
+ navigator.clipboard.writeText(Ne), a("done"), setTimeout(() => a("idle"), 1800);
1175
+ }, children: l === "done" ? "Copied!" : "Copy" })
1176
+ ] })
1177
+ ] }),
1178
+ /* @__PURE__ */ p("div", { className: "flex flex-col gap-1 flex-1 min-h-0", children: [
1179
+ /* @__PURE__ */ n("p", { className: "text-xs text-neutral-500", children: "Component" }),
1180
+ /* @__PURE__ */ p("div", { className: "relative flex-1 min-h-0 bg-neutral-50 rounded", children: [
1181
+ /* @__PURE__ */ n(
1182
+ "button",
1183
+ {
1184
+ className: "absolute top-4 right-4 button-base",
1185
+ onClick: () => {
1186
+ navigator.clipboard.writeText(s), i("done"), setTimeout(() => i("idle"), 1800);
1187
+ },
1188
+ children: u === "done" ? "Copied!" : "Copy"
1189
+ }
1190
+ ),
1191
+ /* @__PURE__ */ n(
1192
+ "textarea",
1193
+ {
1194
+ readOnly: !0,
1195
+ value: s,
1196
+ className: "w-full h-full resize-none bg-transparent text-xs text-neutral-700 font-mono p-4 pr-12 outline-none"
1197
+ }
1198
+ )
1199
+ ] })
1200
+ ] })
1201
+ ]
1202
+ }
1203
+ );
1204
+ }, kn = ({
1205
+ open: e,
1206
+ onOpenChange: o,
1207
+ shader: r,
1208
+ patch: t,
1209
+ uniforms: s,
1210
+ nodeId: l,
1211
+ handleUpdateUniforms: a,
1212
+ handleUpdateNode: u
1213
+ }) => {
1214
+ const i = R(null), m = R(null), [h, c] = y(!1), [f, b] = y(null), C = (g, k) => {
1215
+ const B = g.split(/\n(?=\d+: )/), _ = {};
1216
+ for (const j of B) {
1217
+ const X = j.match(/^(\d+): ([\s\S]*)/);
1218
+ X && (_[parseInt(X[1], 10)] = X[2].trimEnd());
1219
+ }
1220
+ const P = Math.max(1, k - 3), Z = k + 3, G = [];
1221
+ for (let j = P; j <= Z; j++)
1222
+ _[j] !== void 0 && G.push(`${j}: ${_[j]}`);
1223
+ return G.join(`
1224
+ `);
1225
+ }, [N, F] = y({ w: 1, h: 1 }), { width: v, height: E } = r.resolution;
1226
+ D(() => {
1227
+ const g = m.current;
1228
+ if (!g) return;
1229
+ const k = new ResizeObserver(([B]) => {
1230
+ const { width: _, height: P } = B.contentRect;
1231
+ F({ w: _, h: P });
1232
+ });
1233
+ return k.observe(g), () => k.disconnect();
1234
+ }, []);
1235
+ const U = () => {
1236
+ i.current?.toBlob((g) => {
1237
+ g && navigator.clipboard.write([new ClipboardItem({ "image/png": g })]);
1238
+ });
1239
+ }, S = () => {
1240
+ const g = i.current?.toDataURL("image/png");
1241
+ if (!g) return;
1242
+ const k = document.createElement("a");
1243
+ k.href = g, k.download = `${r.name}.png`, k.click();
1244
+ };
1245
+ return /* @__PURE__ */ p(
1246
+ ce,
1247
+ {
1248
+ open: e,
1249
+ handleOpenChange: o,
1250
+ className: "flex flex-col w-full h-full",
1251
+ children: [
1252
+ /* @__PURE__ */ p("div", { className: "flex items-center justify-between px-6 py-4 shrink-0", children: [
1253
+ /* @__PURE__ */ n("h2", { className: "text-sm font-medium text-neutral-800", children: r.name }),
1254
+ /* @__PURE__ */ n("button", { className: "button-base", onClick: () => o(!1), children: "Close" })
1255
+ ] }),
1256
+ /* @__PURE__ */ p("div", { className: "flex gap-16 px-6 pb-6 flex-1 min-h-0 items-center", children: [
1257
+ /* @__PURE__ */ n("div", { className: "flex flex-col gap-8", children: /* @__PURE__ */ n("div", { className: "flex flex-col gap-2", children: /* @__PURE__ */ n(
1258
+ Ae,
1259
+ {
1260
+ shader: r,
1261
+ initialUniforms: s.current[r.id],
1262
+ handleUpdateUniform: (g) => a(r.id, g)
1263
+ }
1264
+ ) }) }),
1265
+ /* @__PURE__ */ p("div", { className: "h-full w-full flex flex-col gap-4 ", children: [
1266
+ /* @__PURE__ */ n(
1267
+ "div",
1268
+ {
1269
+ ref: m,
1270
+ className: "flex bg-neutral-50 rounded w-4/5 items-center justify-center h-full",
1271
+ children: /* @__PURE__ */ n(
1272
+ Re,
1273
+ {
1274
+ ref: i,
1275
+ animate: !0,
1276
+ width: v,
1277
+ height: E,
1278
+ patch: t,
1279
+ uniforms: s,
1280
+ className: v / E > N.w / N.h ? "w-full" : "h-full",
1281
+ onError: (g) => b(g)
1282
+ }
1283
+ )
1284
+ }
1285
+ ),
1286
+ /* @__PURE__ */ p("div", { className: "flex flex-col gap-2 ", children: [
1287
+ /* @__PURE__ */ p("div", { className: "flex gap-1 bg-neutral-100 p-1 rounded-md w-min", children: [
1288
+ /* @__PURE__ */ n(
1289
+ H,
1290
+ {
1291
+ label: "w",
1292
+ value: v,
1293
+ min: 1,
1294
+ step: 1,
1295
+ onChange: (g) => u(l, (k) => ({
1296
+ ...k,
1297
+ shader: { ...k.shader, resolution: { width: g, height: E } }
1298
+ }))
1299
+ }
1300
+ ),
1301
+ /* @__PURE__ */ n(
1302
+ H,
1303
+ {
1304
+ label: "h",
1305
+ value: E,
1306
+ min: 1,
1307
+ step: 1,
1308
+ onChange: (g) => u(l, (k) => ({
1309
+ ...k,
1310
+ shader: { ...k.shader, resolution: { width: v, height: g } }
1311
+ }))
1312
+ }
1313
+ )
1314
+ ] }),
1315
+ /* @__PURE__ */ p("div", { className: "flex gap-1 h-min w-min", children: [
1316
+ /* @__PURE__ */ n(
1317
+ "button",
1318
+ {
1319
+ className: "button-base",
1320
+ onClick: () => c(!0),
1321
+ children: "Export"
1322
+ }
1323
+ ),
1324
+ /* @__PURE__ */ n(
1325
+ Te,
1326
+ {
1327
+ uniforms: s.current,
1328
+ patch: t,
1329
+ open: h,
1330
+ onOpenChange: c
1331
+ }
1332
+ ),
1333
+ /* @__PURE__ */ n("button", { className: "button-base", onClick: U, children: "Copy" }),
1334
+ /* @__PURE__ */ n("button", { className: "button-base", onClick: S, children: "Save" })
1335
+ ] })
1336
+ ] })
1337
+ ] })
1338
+ ] }),
1339
+ f && /* @__PURE__ */ p("div", { className: "flex flex-col gap-2 mx-6 mb-6 p-2 bg-white border-2 border-red-100 rounded-md", children: [
1340
+ /* @__PURE__ */ n("p", { className: "text-white w-min text-nowrap bg-red-700 px-2 py-1 rounded text-xs", children: f.shaderName }),
1341
+ /* @__PURE__ */ n("pre", { className: "text-xs text-red-600 font-mono whitespace-pre-wrap break-all", children: C(f.message, f.line) }),
1342
+ /* @__PURE__ */ n(
1343
+ "button",
1344
+ {
1345
+ className: "self-start text-xs px-2 py-1 rounded border border-red-200 bg-white text-red-600 hover:bg-red-50 cursor-pointer",
1346
+ onClick: () => navigator.clipboard.writeText(f.message),
1347
+ children: "Copy error"
1348
+ }
1349
+ )
1350
+ ] })
1351
+ ]
1352
+ }
1353
+ );
1354
+ }, Rn = ({ data: e, selected: o, id: r }) => {
1355
+ const {
1356
+ patches: t,
1357
+ uniforms: s,
1358
+ handleUpdateUniforms: l,
1359
+ handleUpdateNode: a,
1360
+ showStats: u,
1361
+ setOpenExportNodeId: i,
1362
+ openPreviewNodeId: m,
1363
+ setOpenPreviewNodeId: h
1364
+ } = ie(oe);
1365
+ if (!t || t[e.shader.id] === void 0) return null;
1366
+ const { width: c, height: f } = e.shader.resolution, [b, C] = y(null), N = R(null), [F, v] = y("idle"), [E, U] = y("idle"), S = () => {
1367
+ N.current?.toBlob((_) => {
1368
+ _ && navigator.clipboard.write([new ClipboardItem({ "image/png": _ })]);
1369
+ }), v("done"), setTimeout(() => v("idle"), 1800);
1370
+ }, g = () => {
1371
+ const _ = N.current?.toDataURL("image/png");
1372
+ if (!_) return;
1373
+ const P = document.createElement("a");
1374
+ P.href = _, P.download = `${e.shader.name}.png`, P.click();
1375
+ }, k = Q(() => ae(e.shader).filter((_) => _.type === "sampler2D" && _.source === "input").map((_) => _.name), [e.shader]), B = (_, P) => {
1376
+ const Z = _.split(/\n(?=\d+: )/), G = {};
1377
+ for (const q of Z) {
1378
+ const ne = q.match(/^(\d+): ([\s\S]*)/);
1379
+ ne && (G[parseInt(ne[1], 10)] = ne[2].trimEnd());
1380
+ }
1381
+ const j = Math.max(1, P - 3), X = P + 3, ee = [];
1382
+ for (let q = j; q <= X; q++)
1383
+ G[q] !== void 0 && ee.push(`${q}: ${G[q]}`);
1384
+ return ee.join(`
1385
+ `);
1386
+ };
1387
+ return /* @__PURE__ */ p(
1388
+ "div",
1389
+ {
1390
+ className: `
1391
+ flex flex-col gap-4 bg-white rounded-lg p-6 relative transition-[outline] outline-neutral-200 duration-75
1392
+ ${o ? "outline-4" : "outline-0"}
1393
+ `,
1394
+ children: [
1395
+ /* @__PURE__ */ n("p", { className: "text-sm w-min py-1 px-2 bg-neutral-100 rounded-lg text-neutral-500 text-nowrap", children: e.shader.name }),
1396
+ u && /* @__PURE__ */ p(le, { children: [
1397
+ /* @__PURE__ */ p("p", { className: "text-xs text-neutral-500 absolute -top-6", children: [
1398
+ "ID: ",
1399
+ e.shader.id
1400
+ ] }),
1401
+ /* @__PURE__ */ n("p", { className: "text-xs text-neutral-500 absolute -top-10", children: e.shader.name })
1402
+ ] }),
1403
+ k.map((_) => /* @__PURE__ */ n(
1404
+ Ce,
1405
+ {
1406
+ id: _,
1407
+ type: "target",
1408
+ position: se.Top
1409
+ },
1410
+ _
1411
+ )),
1412
+ /* @__PURE__ */ p("div", { className: "flex gap-8", children: [
1413
+ /* @__PURE__ */ n("div", { className: "flex flex-col gap-2", children: /* @__PURE__ */ n(
1414
+ Ae,
1415
+ {
1416
+ shader: e.shader,
1417
+ initialUniforms: s.current[e.shader.id],
1418
+ handleUpdateUniform: (_) => {
1419
+ l(e.shader.id, _);
1420
+ }
1421
+ }
1422
+ ) }),
1423
+ /* @__PURE__ */ p("div", { className: "flex flex-col justify-center items-start gap-4 ", children: [
1424
+ /* @__PURE__ */ p("div", { className: "flex flex-col gap-2", children: [
1425
+ /* @__PURE__ */ p("div", { className: "relative max-w-96 group", children: [
1426
+ /* @__PURE__ */ p("div", { className: "flex absolute top-2 right-2 gap-2", children: [
1427
+ /* @__PURE__ */ n(
1428
+ "button",
1429
+ {
1430
+ className: "button-base group-hover:opacity-100 opacity-0",
1431
+ onClick: () => h(r),
1432
+ children: "Expand"
1433
+ }
1434
+ ),
1435
+ /* @__PURE__ */ n(
1436
+ kn,
1437
+ {
1438
+ open: m === r,
1439
+ onOpenChange: (_) => {
1440
+ h(_ ? r : null);
1441
+ },
1442
+ shader: e.shader,
1443
+ patch: t[e.shader.id],
1444
+ uniforms: s,
1445
+ nodeId: r,
1446
+ handleUpdateUniforms: l,
1447
+ handleUpdateNode: a
1448
+ }
1449
+ ),
1450
+ /* @__PURE__ */ n(
1451
+ "button",
1452
+ {
1453
+ className: `button-base ${e.paused ? "opacity-100" : "group-hover:opacity-100 opacity-0"}`,
1454
+ onClick: () => {
1455
+ a(r, (_) => ({ ..._, paused: !_.paused }));
1456
+ },
1457
+ children: e.paused ? "Resume" : "Pause"
1458
+ }
1459
+ )
1460
+ ] }),
1461
+ /* @__PURE__ */ n(
1462
+ Re,
1463
+ {
1464
+ ref: N,
1465
+ animate: !e.paused,
1466
+ width: c,
1467
+ height: f,
1468
+ patch: t[e.shader.id],
1469
+ uniforms: s,
1470
+ className: "w-full h-auto",
1471
+ style: { maxWidth: `${c / f * 24}rem` },
1472
+ onError: (_) => {
1473
+ C(_);
1474
+ }
1475
+ }
1476
+ )
1477
+ ] }),
1478
+ /* @__PURE__ */ p("div", { className: "flex gap-1 bg-neutral-100 rounded-md p-1 w-min", children: [
1479
+ /* @__PURE__ */ n(
1480
+ H,
1481
+ {
1482
+ label: "w",
1483
+ value: c,
1484
+ min: 1,
1485
+ step: 1,
1486
+ onChange: (_) => a(r, (P) => ({
1487
+ ...P,
1488
+ shader: { ...P.shader, resolution: { width: _, height: f } }
1489
+ }))
1490
+ }
1491
+ ),
1492
+ /* @__PURE__ */ n(
1493
+ H,
1494
+ {
1495
+ label: "h",
1496
+ value: f,
1497
+ min: 1,
1498
+ step: 1,
1499
+ onChange: (_) => a(r, (P) => ({
1500
+ ...P,
1501
+ shader: { ...P.shader, resolution: { width: c, height: _ } }
1502
+ }))
1503
+ }
1504
+ )
1505
+ ] })
1506
+ ] }),
1507
+ /* @__PURE__ */ p("div", { className: "flex gap-1", children: [
1508
+ /* @__PURE__ */ n(
1509
+ "button",
1510
+ {
1511
+ className: "button-base",
1512
+ onClick: () => i(r),
1513
+ children: "Export"
1514
+ }
1515
+ ),
1516
+ /* @__PURE__ */ n("button", { className: "button-base", onClick: S, children: F === "done" ? "Copied!" : "Copy" }),
1517
+ /* @__PURE__ */ n("button", { className: "button-base", onClick: g, children: "Save" })
1518
+ ] })
1519
+ ] })
1520
+ ] }),
1521
+ b && /* @__PURE__ */ p("div", { className: "flex flex-col gap-2 p-2 bg-white border-2 border-red-100 rounded-md relative", children: [
1522
+ /* @__PURE__ */ n("p", { className: "text-white w-min text-nowrap bg-red-700 px-2 py-1 rounded text-xs", children: b.shaderName }),
1523
+ /* @__PURE__ */ n("pre", { className: "text-xs text-red-600 font-mono whitespace-pre-wrap break-all", children: B(b.message, b.line) }),
1524
+ /* @__PURE__ */ n(
1525
+ "button",
1526
+ {
1527
+ className: "self-start text-xs px-2 py-1 rounded border border-red-200 bg-white text-red-600 hover:bg-red-50 cursor-pointer",
1528
+ onClick: () => {
1529
+ navigator.clipboard.writeText(b.message), U("done"), setTimeout(() => U("idle"), 1800);
1530
+ },
1531
+ children: E === "done" ? "Copied!" : "Copy error"
1532
+ }
1533
+ )
1534
+ ] }),
1535
+ /* @__PURE__ */ n(Ce, { id: "out", type: "source", position: se.Bottom })
1536
+ ]
1537
+ }
1538
+ );
1539
+ };
1540
+ function Un({
1541
+ sourceX: e,
1542
+ sourceY: o,
1543
+ targetX: r,
1544
+ targetY: t,
1545
+ sourcePosition: s,
1546
+ targetPosition: l,
1547
+ style: a = {},
1548
+ markerEnd: u,
1549
+ id: i
1550
+ }) {
1551
+ const [m, h, c] = Ee({
1552
+ sourceX: e,
1553
+ sourceY: o,
1554
+ sourcePosition: s,
1555
+ targetX: r,
1556
+ targetY: t,
1557
+ targetPosition: l
1558
+ }), { shaders: f, handleInsertShader: b } = ie(oe), [C, N] = y(!1), F = () => {
1559
+ console.log("d"), N(!0);
1560
+ };
1561
+ return /* @__PURE__ */ p(le, { children: [
1562
+ /* @__PURE__ */ n(Ye, { path: m, markerEnd: u, style: a }),
1563
+ /* @__PURE__ */ n(Ke, { children: /* @__PURE__ */ p(
1564
+ "div",
1565
+ {
1566
+ className: "absolute -translate-1/2 origin-center pointer-events-auto",
1567
+ style: {
1568
+ transform: `translate(${h}px,${c}px)`
1569
+ },
1570
+ children: [
1571
+ /* @__PURE__ */ n(
1572
+ "button",
1573
+ {
1574
+ className: "w-6 h-6 bg-neutral-200 rounded-full active:bg-neutral-200 z-10 flex items-center justify-center",
1575
+ onClick: () => F(),
1576
+ children: "+"
1577
+ }
1578
+ ),
1579
+ /* @__PURE__ */ n(
1580
+ ce,
1581
+ {
1582
+ open: C,
1583
+ handleOpenChange: (v) => {
1584
+ N(v);
1585
+ },
1586
+ children: /* @__PURE__ */ p("div", { className: "w-full h-full flex flex-col p-4", children: [
1587
+ /* @__PURE__ */ p("div", { className: "w-full flex justify-between", children: [
1588
+ /* @__PURE__ */ n("p", { children: "Add a Shader" }),
1589
+ /* @__PURE__ */ n(
1590
+ "button",
1591
+ {
1592
+ className: "button-base",
1593
+ onClick: () => {
1594
+ N(!1);
1595
+ },
1596
+ children: "Close"
1597
+ }
1598
+ )
1599
+ ] }),
1600
+ /* @__PURE__ */ n("div", { className: "w-full flex flex-col", children: f.map((v) => /* @__PURE__ */ n(
1601
+ "button",
1602
+ {
1603
+ className: "text-xs flex justify-start p-1 rounded-sm hover:bg-neutral-100 cursor-pointer text-neutral-500",
1604
+ onClick: () => {
1605
+ b(v, i);
1606
+ },
1607
+ children: v.id
1608
+ },
1609
+ v.id
1610
+ )) })
1611
+ ] })
1612
+ }
1613
+ )
1614
+ ]
1615
+ }
1616
+ ) })
1617
+ ] });
1618
+ }
1619
+ function In({
1620
+ fromX: e,
1621
+ fromY: o,
1622
+ toX: r,
1623
+ toY: t,
1624
+ fromPosition: s,
1625
+ toPosition: l,
1626
+ toHandle: a
1627
+ }) {
1628
+ const [u] = Ee({
1629
+ sourceX: e,
1630
+ sourceY: o,
1631
+ sourcePosition: s,
1632
+ targetX: r,
1633
+ targetY: t,
1634
+ targetPosition: l
1635
+ }), i = a ? "connect" : "new", m = t - 26, h = 6, c = 16, f = i.length * 6 + h * 2;
1636
+ return /* @__PURE__ */ p("g", { children: [
1637
+ /* @__PURE__ */ n("path", { fill: "none", stroke: "#b1b1b7", strokeWidth: 1.5, d: u }),
1638
+ /* @__PURE__ */ n(
1639
+ "rect",
1640
+ {
1641
+ x: r - f / 2,
1642
+ y: m - c / 2,
1643
+ width: f,
1644
+ height: c,
1645
+ rx: 4,
1646
+ fill: a ? "#404040" : "#e5e5e5",
1647
+ style: { pointerEvents: "none" }
1648
+ }
1649
+ ),
1650
+ /* @__PURE__ */ n(
1651
+ "text",
1652
+ {
1653
+ x: r,
1654
+ y: m,
1655
+ textAnchor: "middle",
1656
+ dominantBaseline: "central",
1657
+ fontSize: 10,
1658
+ fontFamily: "monospace",
1659
+ fill: a ? "#ffffff" : "#525252",
1660
+ style: { userSelect: "none", pointerEvents: "none" },
1661
+ children: i
1662
+ }
1663
+ ),
1664
+ /* @__PURE__ */ n("foreignObject", { x: r - 8, y: t - 8, width: 16, height: 16, style: { overflow: "visible" }, children: /* @__PURE__ */ n("div", { className: "w-4 h-4 rounded-full bg-neutral-400" }) })
1665
+ ] });
1666
+ }
1667
+ function he(e, o, r) {
1668
+ const t = new Map(e.map((l) => [l.id, l])), s = [r];
1669
+ for (; s.length > 0; ) {
1670
+ const l = s.shift(), a = t.get(l);
1671
+ if (!a || a.type !== "shader") continue;
1672
+ const u = a, { width: i, height: m } = u.data.shader.resolution, h = Se(
1673
+ a,
1674
+ [...t.values()],
1675
+ o
1676
+ );
1677
+ for (const c of h) {
1678
+ const f = {
1679
+ ...c,
1680
+ data: {
1681
+ ...c.data,
1682
+ shader: {
1683
+ ...c.data.shader,
1684
+ resolution: { width: i, height: m }
1685
+ }
1686
+ }
1687
+ };
1688
+ t.set(c.id, f), s.push(c.id);
1689
+ }
1690
+ }
1691
+ return [...t.values()];
1692
+ }
1693
+ const An = ({
1694
+ shaders: e,
1695
+ initialState: o,
1696
+ handleSave: r,
1697
+ className: t,
1698
+ initialShowStats: s,
1699
+ initialShaderPanelOpen: l,
1700
+ initialOpenPreviewNodeId: a,
1701
+ onEditorStateChange: u,
1702
+ onOpenPreviewNodeIdChange: i
1703
+ }) => {
1704
+ const [m, h] = y(o?.edges ?? []), [c, f] = y(() => {
1705
+ const d = o?.nodes ?? [], x = o?.edges ?? [], w = new Set(x.map((A) => A.target)), M = d.filter((A) => !w.has(A.id)).map((A) => A.id);
1706
+ let I = d;
1707
+ for (const A of M)
1708
+ I = he(I, x, A);
1709
+ return I;
1710
+ }), b = W(
1711
+ (d) => f((x) => Qe(d, x)),
1712
+ [f]
1713
+ ), C = W(
1714
+ (d) => h((x) => Ze(d, x)),
1715
+ [h]
1716
+ ), N = W(
1717
+ (d) => {
1718
+ const x = /* @__PURE__ */ new Set(), w = (M) => x.has(M) ? !1 : M === d.source ? !0 : (x.add(M), Se({ id: M }, c, m).some(
1719
+ (I) => w(I.id)
1720
+ ));
1721
+ return !w(d.target);
1722
+ },
1723
+ [c, m]
1724
+ ), F = W(
1725
+ (d) => {
1726
+ const x = _e({ ...d, type: "insert" }, m), w = he(
1727
+ c,
1728
+ x,
1729
+ d.source
1730
+ );
1731
+ h(x), f(w);
1732
+ },
1733
+ [m, c]
1734
+ ), { screenToFlowPosition: v } = en(), [E, U] = y(null), S = W(
1735
+ (d, x) => {
1736
+ if (!x.isValid && x.fromNode) {
1737
+ const { clientX: w, clientY: M } = "changedTouches" in d ? d.changedTouches[0] : d;
1738
+ U({
1739
+ position: v({
1740
+ x: w,
1741
+ y: M
1742
+ }),
1743
+ sourceId: x.fromNode.id
1744
+ });
1745
+ }
1746
+ },
1747
+ [v]
1748
+ ), g = R(
1749
+ o?.uniforms ?? {}
1750
+ );
1751
+ D(() => {
1752
+ o?.uniforms && (g.current = o.uniforms);
1753
+ }, [o]);
1754
+ const [k, B] = y(null);
1755
+ D(() => {
1756
+ const d = (x) => {
1757
+ (x.metaKey || x.ctrlKey) && x.key === "s" && (x.preventDefault(), r({ nodes: c, edges: m, uniforms: g.current }), B(/* @__PURE__ */ new Date()));
1758
+ };
1759
+ return window.addEventListener("keydown", d), () => window.removeEventListener("keydown", d);
1760
+ }, [c, m]);
1761
+ const _ = (d) => {
1762
+ const x = `${Math.random() * 1e5}`, w = { ...d, id: x };
1763
+ return {
1764
+ id: x,
1765
+ position: { x: 0, y: 0 },
1766
+ data: {
1767
+ shader: w,
1768
+ uniforms: g,
1769
+ paused: !1
1770
+ },
1771
+ type: "shader"
1772
+ };
1773
+ }, P = (d) => {
1774
+ f((x) => [...x, _(d)]);
1775
+ }, Z = (d, x) => {
1776
+ const w = m.find(($) => $.id === x);
1777
+ if (!w) return;
1778
+ const M = w.source, I = w.target, A = c.find(($) => $.id === M), V = c.find(($) => $.id === I), L = w.targetHandle;
1779
+ if (A && V && L) {
1780
+ const $ = _(d), Le = ae($.data.shader);
1781
+ let ue;
1782
+ for (const Y of Le)
1783
+ if (Y.type === "sampler2D" && Y.source === "input") {
1784
+ ue = Y.name;
1785
+ break;
1786
+ }
1787
+ if (ue === void 0) return;
1788
+ const [Hn, je, qe] = on({
1789
+ sourceX: A.position.x,
1790
+ sourceY: A.position.y,
1791
+ sourcePosition: se.Bottom,
1792
+ targetX: V.position.x,
1793
+ targetY: V.position.y,
1794
+ targetPosition: se.Top
1795
+ });
1796
+ $.position.x = je, $.position.y = qe, f((Y) => [...Y, $]), h((Y) => {
1797
+ const de = Y.filter(
1798
+ (Be) => Be.id !== x
1799
+ ), Ve = {
1800
+ id: "" + Math.random() * 1e4,
1801
+ source: A.id,
1802
+ target: $.id,
1803
+ targetHandle: ue,
1804
+ type: "insert"
1805
+ }, He = {
1806
+ id: "" + Math.random() * 1e4,
1807
+ source: $.id,
1808
+ target: V.id,
1809
+ targetHandle: L,
1810
+ type: "insert"
1811
+ };
1812
+ return de.push(Ve), de.push(He), de;
1813
+ });
1814
+ }
1815
+ }, [G, j] = Q(() => {
1816
+ const d = {};
1817
+ for (const w of c)
1818
+ d[w.id] = [];
1819
+ for (const w of m)
1820
+ d[w.target].push({
1821
+ from: w.source,
1822
+ to: w.target,
1823
+ input: w.targetHandle ?? ""
1824
+ });
1825
+ return [JSON.stringify(d), d];
1826
+ }, [m, c]), [X, ee] = Q(() => {
1827
+ const d = {};
1828
+ for (const x of c)
1829
+ if (x.type === "shader") {
1830
+ const w = x;
1831
+ d[w.id] = w.data.shader;
1832
+ }
1833
+ return [JSON.stringify(d), d];
1834
+ }, [c]), q = Q(() => {
1835
+ const d = {};
1836
+ for (const [x, w] of Object.entries(ee)) {
1837
+ d[x] = { shaders: [w], connections: [] };
1838
+ const M = [x];
1839
+ for (; M.length !== 0; ) {
1840
+ const I = M.shift();
1841
+ for (const A of j[I]) {
1842
+ const V = A.from;
1843
+ M.push(V);
1844
+ const L = ee[V];
1845
+ d[x].shaders.push(L), d[x].connections.push(A);
1846
+ }
1847
+ }
1848
+ }
1849
+ return d;
1850
+ }, [X, G]), ne = W(
1851
+ (d, x) => {
1852
+ g.current[d] = x;
1853
+ },
1854
+ []
1855
+ ), Fe = W(
1856
+ (d, x) => {
1857
+ f((w) => {
1858
+ const M = w.map((I) => {
1859
+ if (I.id === d && I.type === "shader") {
1860
+ const A = I;
1861
+ return { ...A, data: x(A.data) };
1862
+ }
1863
+ return I;
1864
+ });
1865
+ return he(M, m, d);
1866
+ });
1867
+ },
1868
+ [m]
1869
+ ), ge = R(0), xe = R([0, 0]);
1870
+ D(() => {
1871
+ const d = setInterval(() => {
1872
+ ge.current = Date.now();
1873
+ }, 10), x = (w) => {
1874
+ xe.current = [
1875
+ Math.min(1, w.clientX / window.innerWidth),
1876
+ Math.min(w.clientY / innerHeight, 1)
1877
+ ];
1878
+ };
1879
+ return window.addEventListener("mousemove", x), () => {
1880
+ clearInterval(d), window.removeEventListener("mousemove", x);
1881
+ };
1882
+ }, []);
1883
+ const Pe = (d, x, w) => {
1884
+ if (c.find((I) => I.id === x)) {
1885
+ const I = _(d);
1886
+ I.position = w;
1887
+ const A = ae(I.data.shader);
1888
+ let V;
1889
+ for (const L of A)
1890
+ if (L.type === "sampler2D" && L.source === "input") {
1891
+ V = L.name;
1892
+ break;
1893
+ }
1894
+ if (f((L) => [...L, I]), V !== void 0) {
1895
+ const L = {
1896
+ id: "" + Math.random(),
1897
+ source: x,
1898
+ target: I.id,
1899
+ targetHandle: V,
1900
+ type: "insert"
1901
+ };
1902
+ h(($) => _e(L, $));
1903
+ }
1904
+ }
1905
+ }, [J, Me] = y(s ?? !1), [te, De] = y(
1906
+ l ?? !0
1907
+ ), [re, be] = y(null), [$e, ze] = y(a ?? null), Oe = (d) => {
1908
+ ze(d), i?.(d);
1909
+ };
1910
+ return D(() => {
1911
+ u?.({ showStats: J, shaderPanelOpen: te });
1912
+ }, [J, te]), /* @__PURE__ */ p("div", { className: `w-full h-full ${t}`, children: [
1913
+ /* @__PURE__ */ n(
1914
+ oe.Provider,
1915
+ {
1916
+ value: {
1917
+ currentTime: ge,
1918
+ mousePosition: xe,
1919
+ shaders: e,
1920
+ patches: q,
1921
+ showStats: J,
1922
+ openExportNodeId: re,
1923
+ setOpenExportNodeId: be,
1924
+ openPreviewNodeId: $e,
1925
+ setOpenPreviewNodeId: Oe,
1926
+ uniforms: g,
1927
+ handleUpdateUniforms: ne,
1928
+ handleUpdateNode: Fe,
1929
+ handleInsertShader: Z
1930
+ },
1931
+ children: /* @__PURE__ */ p(
1932
+ nn,
1933
+ {
1934
+ panOnScroll: !0,
1935
+ proOptions: { hideAttribution: !0 },
1936
+ nodes: c,
1937
+ nodeTypes: { shader: Rn },
1938
+ edges: m,
1939
+ edgeTypes: { insert: Un },
1940
+ onNodesChange: b,
1941
+ onEdgesChange: C,
1942
+ onConnect: F,
1943
+ onConnectEnd: S,
1944
+ connectionLineComponent: In,
1945
+ isValidConnection: N,
1946
+ style: {
1947
+ background: "#F9F9F9"
1948
+ },
1949
+ fitView: !0,
1950
+ children: [
1951
+ /* @__PURE__ */ n(
1952
+ tn,
1953
+ {
1954
+ style: {
1955
+ "--xy-controls-button-background-color-default": "transparent",
1956
+ "--xy-controls-box-shadow-default": "none"
1957
+ }
1958
+ }
1959
+ ),
1960
+ /* @__PURE__ */ p(fe, { position: "top-left", className: "flex flex-col gap-4", children: [
1961
+ /* @__PURE__ */ n(
1962
+ "button",
1963
+ {
1964
+ className: "button-base",
1965
+ onClick: () => Me(!J),
1966
+ children: J ? "Hide Stats" : "Show Stats"
1967
+ }
1968
+ ),
1969
+ J && /* @__PURE__ */ p(le, { children: [
1970
+ /* @__PURE__ */ n("div", { className: "flex flex-col gap-2", children: c.map((d) => /* @__PURE__ */ n("p", { className: "text-xs text-neutral-400", children: d.id }, d.id)) }),
1971
+ /* @__PURE__ */ n("div", { className: "flex flex-col gap-2", children: m.map((d) => /* @__PURE__ */ p("p", { className: "text-xs text-neutral-400", children: [
1972
+ d.source,
1973
+ " ",
1974
+ ">",
1975
+ " ",
1976
+ d.target,
1977
+ " ",
1978
+ d.targetHandle
1979
+ ] }, d.id)) })
1980
+ ] })
1981
+ ] }),
1982
+ e.length > 0 && /* @__PURE__ */ n(fe, { position: "bottom-right", children: /* @__PURE__ */ p("div", { className: "w-56 flex flex-col rounded-sm bg-white overflow-hidden", children: [
1983
+ /* @__PURE__ */ p("div", { className: "flex items-center justify-between px-3 py-2", children: [
1984
+ /* @__PURE__ */ n("p", { className: "text-sm", children: "Add Shader" }),
1985
+ /* @__PURE__ */ n(
1986
+ "button",
1987
+ {
1988
+ className: "button-base",
1989
+ onClick: () => De(!te),
1990
+ children: te ? "Hide" : "Show"
1991
+ }
1992
+ )
1993
+ ] }),
1994
+ te && /* @__PURE__ */ n("div", { className: "flex flex-col gap-1 px-2 pb-2", children: e.sort((d, x) => d.name.localeCompare(x.name)).map((d) => /* @__PURE__ */ n(
1995
+ "button",
1996
+ {
1997
+ className: "text-xs flex justify-start p-1 rounded-sm hover:bg-neutral-100 cursor-pointer text-neutral-500",
1998
+ onClick: () => P(d),
1999
+ children: d.id
2000
+ },
2001
+ d.id
2002
+ )) })
2003
+ ] }) }),
2004
+ k && /* @__PURE__ */ n(fe, { position: "bottom-center", children: /* @__PURE__ */ p("p", { className: "text-xs text-neutral-400", children: [
2005
+ "Last saved at ",
2006
+ k.toLocaleTimeString()
2007
+ ] }) })
2008
+ ]
2009
+ }
2010
+ )
2011
+ }
2012
+ ),
2013
+ re !== null && q[re] && /* @__PURE__ */ n(
2014
+ Te,
2015
+ {
2016
+ uniforms: g.current,
2017
+ patch: q[re],
2018
+ open: !0,
2019
+ onOpenChange: (d) => {
2020
+ d || be(null);
2021
+ }
2022
+ }
2023
+ ),
2024
+ /* @__PURE__ */ n(
2025
+ ce,
2026
+ {
2027
+ open: E !== null,
2028
+ handleOpenChange: (d) => {
2029
+ d === !1 && U(null);
2030
+ },
2031
+ children: /* @__PURE__ */ p("div", { className: "w-full h-full flex flex-col p-4", children: [
2032
+ /* @__PURE__ */ p("div", { className: "w-full flex justify-between", children: [
2033
+ /* @__PURE__ */ n("p", { children: "Add a Shader" }),
2034
+ /* @__PURE__ */ n(
2035
+ "button",
2036
+ {
2037
+ className: "button-base",
2038
+ onClick: () => {
2039
+ U(null);
2040
+ },
2041
+ children: "Close"
2042
+ }
2043
+ )
2044
+ ] }),
2045
+ /* @__PURE__ */ n("div", { className: "w-full flex flex-col", children: e.map((d) => /* @__PURE__ */ n(
2046
+ "button",
2047
+ {
2048
+ className: "text-xs flex justify-start p-1 rounded-sm hover:bg-neutral-100 cursor-pointer text-neutral-500",
2049
+ onClick: () => {
2050
+ E && Pe(
2051
+ d,
2052
+ E.sourceId,
2053
+ E.position
2054
+ ), U(null);
2055
+ },
2056
+ children: d.id
2057
+ },
2058
+ d.id
2059
+ )) })
2060
+ ] })
2061
+ }
2062
+ )
2063
+ ] });
2064
+ }, Xn = (e) => /* @__PURE__ */ n(Je, { children: /* @__PURE__ */ n(An, { ...e }) });
2065
+ function Yn(e, o) {
2066
+ const r = { current: o }, t = e.shaders.map((l, a) => ({
2067
+ id: l.id,
2068
+ type: "shader",
2069
+ position: { x: 0, y: -a * 500 },
2070
+ data: {
2071
+ shader: l,
2072
+ uniforms: r,
2073
+ paused: !1
2074
+ }
2075
+ })), s = e.connections.map((l, a) => ({
2076
+ id: `edge-${a}`,
2077
+ source: l.from,
2078
+ target: l.to,
2079
+ targetHandle: l.input,
2080
+ type: "insert"
2081
+ }));
2082
+ return console.log("build", { nodes: t, edges: s, uniforms: o }), { nodes: t, edges: s, uniforms: o };
2083
+ }
2084
+ const Tn = `#version 300 es
2085
+ precision mediump float;
2086
+
2087
+ uniform sampler2D u_texture; // input
2088
+ uniform vec3 u_sourceColor; // color
2089
+ uniform vec4 u_targetColor; // color [0, 0, 0, 0]
2090
+ uniform float u_threshold; // [0, 1, 0.1]
2091
+
2092
+ in vec2 vUv;
2093
+ out vec4 fragColor;
2094
+
2095
+ void main() {
2096
+ vec4 texColor = texture(u_texture, vUv);
2097
+
2098
+ float colorDiff = distance(texColor.rgb, u_sourceColor) / 2.0;
2099
+
2100
+ if (colorDiff < u_threshold) {
2101
+ fragColor = u_targetColor;
2102
+ } else {
2103
+ fragColor = texColor;
2104
+ }
2105
+ }
2106
+ `, Fn = `#version 300 es
2107
+
2108
+ precision highp float;
2109
+
2110
+
2111
+ uniform float u_time; // time
2112
+ uniform vec2 u_resolution; // resolution
2113
+ uniform vec3 u_notes;
2114
+ uniform vec2 u_mouse; //mouse
2115
+
2116
+ uniform float u_flower_count; // [1, 10, 5]
2117
+ uniform float u_flower_rotation; // [-6, 10, 5]
2118
+
2119
+ uniform float u_ring_radius; // [-1, 10, 2]
2120
+ uniform float u_rotation_offset; // [1, 10, 5]
2121
+ uniform float u_mouse_rotation; // [0, 2, 0.1]
2122
+ uniform float u_mouse_scale_factor; // [0, 1, 0.1]
2123
+ uniform vec3 u_origin; // [0, 0.5, -20]
2124
+
2125
+ in vec2 vUv;
2126
+ out vec4 fragColor;
2127
+
2128
+ float sdSphere(vec3 p, float r)
2129
+ {
2130
+ return length(p) - r;
2131
+ }
2132
+
2133
+ float sdCappedCylinder(vec3 p, float h, float r)
2134
+ {
2135
+ vec2 d = abs(vec2(length(p.xz), p.y)) - vec2(r, h);
2136
+ return min(max(d.x,d.y),0.0) + length(max(d,0.0));
2137
+ }
2138
+
2139
+ float sdCappedCone( vec3 p, float h, float r1, float r2 )
2140
+ {
2141
+ vec2 q = vec2( length(p.xz), p.y );
2142
+ vec2 k1 = vec2(r2,h);
2143
+ vec2 k2 = vec2(r2-r1,2.0*h);
2144
+ vec2 ca = vec2(q.x-min(q.x,(q.y<0.0)?r1:r2), abs(q.y)-h);
2145
+ vec2 cb = q - k1 + k2*clamp( dot(k1-q,k2)/dot(k2, k2), 0.0, 1.0 );
2146
+ float s = (cb.x<0.0 && ca.y<0.0) ? -1.0 : 1.0;
2147
+ return s*sqrt( min(dot(ca, ca),dot(cb, cb)) );
2148
+ }
2149
+
2150
+ float sdEllipsoid(vec3 p, vec3 r)
2151
+ {
2152
+ return (length(p/r) - 1.0) * min(min(r.x,r.y),r.z);
2153
+ }
2154
+
2155
+ float smin(float a, float b, float k)
2156
+ {
2157
+ if (k <= 0.00001) return min(a, b);
2158
+ float h = clamp(0.5 + 0.5*(b-a)/k, 0.0, 1.0);
2159
+ return mix(b, a, h) - k*h*(1.0-h);
2160
+ }
2161
+
2162
+
2163
+ float gain( float x, float k )
2164
+ {
2165
+ float a = 0.5*pow(2.0*((x<0.5)?x:1.0-x), k);
2166
+ return (x<0.5)?a:1.0-a;
2167
+ }
2168
+
2169
+ vec3 rotateAroundAxis(vec3 v, vec3 axis, float angle) {
2170
+ axis = normalize(axis);
2171
+ float s = sin(angle);
2172
+ float c = cos(angle);
2173
+ float oc = 1.0 - c;
2174
+
2175
+ return v * c +
2176
+ cross(axis, v) * s +
2177
+ axis * dot(axis, v) * oc;
2178
+ }
2179
+
2180
+ float petals(vec3 p)
2181
+ {
2182
+ float petals = 1000.0;
2183
+ const int PETAL_COUNT = 6;
2184
+ for(int i = 0; i < PETAL_COUNT; i++)
2185
+ {
2186
+ float angle = float(i) / float(PETAL_COUNT) * 6.28318;
2187
+ vec3 rp = p;
2188
+
2189
+ float c = cos(angle);
2190
+ float s = sin(angle);
2191
+ rp.xz = mat2(c, -s, s, c) * rp.xz;
2192
+
2193
+ float dist_from_center = length(rp.xz) * 7.0;
2194
+
2195
+ // adds dip near stem
2196
+ rp.y -= 2.0 / pow(1.3 - (1.0-u_mouse.y * u_mouse_scale_factor) / 10.0, dist_from_center + abs(rp.x) * 5.0);
2197
+
2198
+ // adds tilt between leaves
2199
+ rp.y += smoothstep(-0.9, 0.9, rp.x / 4.0) + 1.0;
2200
+
2201
+ // pushes petal tip out
2202
+ rp.z += 1.0/(abs(rp.x) + 1.5) + 0.5 + (1.0-u_mouse.y * u_mouse_scale_factor) / 2.0;
2203
+
2204
+ float petal = sdEllipsoid(rp, vec3(0.1 + (1.0-u_mouse.y * u_mouse_scale_factor) / 10.0, 0.02, 0.2 + (1.0-u_mouse.y * u_mouse_scale_factor) / 10.0));
2205
+ petals = smin(petals, petal, 0.1);
2206
+ }
2207
+ return petals;
2208
+ }
2209
+
2210
+ float trumpet(vec3 p)
2211
+ {
2212
+ float dist_from_center = length(p.xz);
2213
+ vec3 p_base = p;
2214
+ p_base.y +=1.0;
2215
+ float trumpetbase = sdCappedCone(p_base, 0.6 + (1.0-u_mouse.y * u_mouse_scale_factor), 0.3, 0.1);
2216
+
2217
+ vec3 p_flare = p;
2218
+ p_flare.y -= 1.0 / (dist_from_center + 0.4) - 3.2 - (1.0-u_mouse.y * u_mouse_scale_factor);
2219
+
2220
+ float r = length(p_flare.xz);
2221
+ float angle = atan(p_flare.z, p_flare.x);
2222
+
2223
+
2224
+ float hyper = 1.0 / (r + 10.0);
2225
+
2226
+
2227
+ p_flare.y += hyper * sin(angle * (angle - 1.6) * 2.0);
2228
+
2229
+
2230
+ float flare = sdEllipsoid(p_flare, vec3(0.09 + (1.0-u_mouse.y * u_mouse_scale_factor) / 20.0, 0.01, 0.09 + (1.0-u_mouse.y * u_mouse_scale_factor) / 20.0));
2231
+ float trumpet = smin(trumpetbase, flare, 0.6 + (1.0-u_mouse.y * u_mouse_scale_factor) / 2.0);
2232
+
2233
+ return trumpet;
2234
+ }
2235
+
2236
+ float leaves(vec3 p) {
2237
+ float leaves = 1000.0;
2238
+ const int LEAF_COUNT = 5;
2239
+ for(int i = 0; i < LEAF_COUNT; i++)
2240
+ {
2241
+ float angle = float(i) / float(LEAF_COUNT) * 6.28318;
2242
+ vec3 rp = p;
2243
+
2244
+ float c = cos(angle);
2245
+ float s = sin(angle);
2246
+ rp.xz = mat2(c, -s, s, c) * rp.xz;
2247
+
2248
+ float dist_from_center = length(rp.xz);
2249
+
2250
+ rp.y += smoothstep(0.0,4.0, dist_from_center) * 20.0 - 15.0;
2251
+ rp.z += angle / 4.0;
2252
+
2253
+ float leaf = sdEllipsoid(rp, vec3(0.5, 2.0, 0.5 + (1.0-u_mouse.y * u_mouse_scale_factor) / 2.0));
2254
+ leaves = smin(leaves, leaf, (1.0-u_mouse.y * u_mouse_scale_factor));
2255
+ }
2256
+ return leaves;
2257
+ }
2258
+
2259
+ float single_flower(vec3 p)
2260
+ {
2261
+ float scaledTime = u_time / 2.0;
2262
+
2263
+ float bendStart = 7.0;
2264
+ float bendEnd = 0.0;
2265
+
2266
+ float h = clamp((p.y - bendStart) / (bendEnd - bendStart), 0.0, 1.0);
2267
+
2268
+ h = h * h;
2269
+
2270
+ float maxBend = sin(u_time / 2.0) / 10.0 + 0.6 - (gain(u_notes.x - u_notes.z / 2.0, 2.0)-0.5) / 5.0;
2271
+
2272
+ float bendAngle = h * maxBend;
2273
+
2274
+ //p = rotateAroundAxis(p, vec3(1.0, 0.0, 0.0), 0.2);
2275
+ p = rotateAroundAxis(p, vec3(0.0, 1.0, 0.0), u_flower_rotation);
2276
+
2277
+ p = rotateAroundAxis(p, vec3(1.0, 0.0, 0.0), -bendAngle);
2278
+
2279
+ //p.xz += vec2(sin(p.y * 0.2+ scaledTime), cos(p.y * 0.20 + scaledTime)) * smoothstep(-1.0, 0.0, p.y) / 2.0;
2280
+
2281
+ vec3 stemP = p;
2282
+ stemP.y -= 6.0;
2283
+ float stem = sdCappedCylinder(stemP, 7.0, 0.01);
2284
+
2285
+ float flower = smin(smin(petals(p), trumpet(p), 0.0), leaves(p), 0.0);
2286
+
2287
+ float scene = smin(flower, stem, 1.0);
2288
+
2289
+ return scene;
2290
+ }
2291
+
2292
+ float sceneSDF(vec3 p)
2293
+ {
2294
+ float radius = u_ring_radius + (1.0-u_mouse.y * u_mouse_scale_factor) * 3.0;
2295
+
2296
+ p = rotateAroundAxis(p, vec3(1.0, 0.0, 0.0), -0.5);
2297
+ float angle = atan(p.z, p.x) +.4 + (sin(u_time / 4.0) ) / 10.0 - (gain(u_mouse.x, 1.2) - 0.5) * u_mouse_rotation + u_rotation_offset;
2298
+ float r = length(p.xz);
2299
+
2300
+ float sectorAngle = 6.28318 / u_flower_count;
2301
+
2302
+ float id = floor((angle + 3.14159) / sectorAngle);
2303
+
2304
+ float centerAngle = id * sectorAngle + sectorAngle * 0.5 - 3.14159;
2305
+
2306
+ float localAngle = angle - centerAngle;
2307
+
2308
+ vec3 localP;
2309
+
2310
+ localP.x = r * cos(localAngle) - radius;
2311
+ localP.z = r * sin(localAngle);
2312
+ localP.y = p.y;
2313
+
2314
+ float variation = sin(id * 12.37);
2315
+
2316
+ localP = rotateAroundAxis(localP, vec3(0.0,1.0,0.0), centerAngle);
2317
+
2318
+ localP.y += sin(id * 5.17) * 0.35;
2319
+
2320
+ return single_flower(localP);
2321
+ }
2322
+
2323
+
2324
+
2325
+ void main()
2326
+ {
2327
+ vec2 uv = vec2(vUv.x * 2.0 - 1.0, (1.0 -vUv.y) * 2.0 - 1.0);
2328
+ float aspect = u_resolution.x / u_resolution.y;
2329
+ vec2 resolution = vec2(uv.x * aspect, uv.y) * 0.5;
2330
+
2331
+ vec3 ray_origin = vec3(0, (1.0-u_mouse.y * u_mouse_scale_factor) * 1.0, (1.0-u_mouse.y * u_mouse_scale_factor) * 7.0) + u_origin;
2332
+ vec3 ray_direction = normalize(vec3(resolution, 1.0));
2333
+
2334
+ float MAX_DIST = 20.0 + 10.0 * (1.0-u_mouse.y * u_mouse_scale_factor);
2335
+ const int MAX_STEPS = 100;
2336
+ float dist_traveled = 0.0;
2337
+ int steps = 0;
2338
+ int intersected = 0;
2339
+ float min_dist = 100.0;
2340
+
2341
+ for(int i = 0; i < MAX_STEPS; i++)
2342
+ {
2343
+ vec3 current_pos = ray_origin + ray_direction * dist_traveled;
2344
+
2345
+ float distance = sceneSDF(current_pos);
2346
+
2347
+ min_dist = min(distance, min_dist);
2348
+
2349
+ if(distance < 0.1)
2350
+ {
2351
+ intersected = 1;
2352
+ break;
2353
+ }
2354
+
2355
+ if(dist_traveled > MAX_DIST)
2356
+ break;
2357
+
2358
+ dist_traveled += distance * 0.5;
2359
+ steps += 1;
2360
+ }
2361
+
2362
+ fragColor = vec4(
2363
+ mix(
2364
+ vec3(
2365
+ //0.0,
2366
+ //pow(max(0.0,1.0 - float(min_dist)), 2.0 * u_notes.x + 1.0),
2367
+ pow(max(0.0,1.0 - float(min_dist)), 0.5 * u_notes.x + 1.0) * 1.2
2368
+ //pow(1.0 - float(steps) / float(MAX_STEPS), 2.0),
2369
+ //1.0
2370
+ ),
2371
+ vec3(
2372
+ pow(max(0.0,1.0 - dist_traveled / MAX_DIST), 1.0)
2373
+ //pow(1.0 - float(steps) / float(MAX_STEPS), 2.0)
2374
+ //1.0
2375
+ ),
2376
+ pow(min(1.0,(1.0 - u_notes.x - u_notes.z + u_notes.y) + 0.4), 2.0)
2377
+ //float(intersected)
2378
+ ),
2379
+ 1.0
2380
+ );
2381
+ }`, Pn = `#version 300 es
2382
+ precision mediump float;
2383
+
2384
+ uniform sampler2D u_texture; // input
2385
+ uniform float u_resolution; // [1, 100, 20]
2386
+ uniform float u_numColors; // [2, 16, 2]
2387
+
2388
+ in vec2 vUv;
2389
+ out vec4 fragColor;
2390
+
2391
+ int bayer(int x, int y) {
2392
+ int bayer64[64] = int[64](
2393
+ 0, 32, 8, 40, 2, 34, 10, 42,
2394
+ 48, 16, 56, 24, 50, 18, 58, 26,
2395
+ 12, 44, 4, 36, 14, 46, 6, 38,
2396
+ 60, 28, 52, 20, 62, 30, 54, 22,
2397
+ 3, 35, 11, 43, 1, 33, 9, 41,
2398
+ 51, 19, 59, 27, 49, 17, 57, 25,
2399
+ 15, 47, 7, 39, 13, 45, 5, 37,
2400
+ 63, 31, 55, 23, 61, 29, 53, 21
2401
+ );
2402
+ return bayer64[(y % 8) * 8 + (x % 8)];
2403
+ }
2404
+
2405
+ void main() {
2406
+ vec2 cell = floor(vUv * u_resolution);
2407
+ vec2 cellUv = cell / u_resolution;
2408
+
2409
+ vec4 color = texture(u_texture, cellUv);
2410
+
2411
+ float threshold = (float(bayer(int(cell.x), int(cell.y))) + 0.5) / 64.0 - 0.5;
2412
+
2413
+ float n = max(2.0, u_numColors);
2414
+ float step = 1.0 / (n - 1.0);
2415
+ vec3 dithered = clamp(round((color.rgb + threshold * step) / step) * step, 0.0, 1.0);
2416
+
2417
+ fragColor = vec4(dithered, color.a);
2418
+ }
2419
+ `, Mn = `#version 300 es
2420
+ precision mediump float;
2421
+
2422
+ uniform sampler2D u_texture; // input
2423
+ uniform float u_frequency; // [1, 100, 20]
2424
+ uniform float u_radius; // [0, 1, 0.5]
2425
+ uniform float u_rotation; // [0, 6.28, 0]
2426
+ uniform float u_constantSize; // [0, 1, 0]
2427
+ uniform vec4 u_background; // color [1, 1, 1, 1]
2428
+
2429
+ in vec2 vUv;
2430
+ out vec4 fragColor;
2431
+
2432
+ vec2 rot(vec2 v, float a) {
2433
+ float c = cos(a), s = sin(a);
2434
+ return mat2(c, -s, s, c) * v;
2435
+ }
2436
+
2437
+ void main() {
2438
+ // rotate UV space around center
2439
+ vec2 rotUv = rot(vUv - 0.5, u_rotation) + 0.5;
2440
+
2441
+ // find nearest grid cell center in rotated space
2442
+ vec2 cellUv = rotUv * u_frequency;
2443
+ vec2 cellId = round(cellUv);
2444
+
2445
+ // unrotate cell center to sample from original texture
2446
+ vec2 sampleUv = rot(cellId / u_frequency - 0.5, -u_rotation) + 0.5;
2447
+ vec4 cellColor = texture(u_texture, clamp(sampleUv, 0.0, 1.0));
2448
+
2449
+ // luminance drives dot radius unless constant size is toggled
2450
+ float lum = dot(cellColor.rgb, vec3(0.299, 0.587, 0.114));
2451
+ float dotRadius = u_radius * mix(lum, 1.0, step(0.5, u_constantSize));
2452
+
2453
+ // distance from current pixel to nearest cell center (in cell-space units)
2454
+ float dist = length(cellUv - cellId) / u_frequency * u_frequency;
2455
+
2456
+ fragColor = dist < dotRadius ? cellColor : u_background;
2457
+ }
2458
+ `, Dn = `#version 300 es
2459
+ precision highp float;
2460
+
2461
+ in vec2 vUv;
2462
+ out vec4 fragColor;
2463
+
2464
+ uniform vec2 u_resolution; // [100, 100]
2465
+ uniform float u_time; // time
2466
+ uniform float u_mod_size; // [0, 2, 1]
2467
+ uniform float u_tile_factor; // [1, 100, 10]
2468
+ uniform vec2 u_translation; // [0,0]
2469
+
2470
+ float modSigned(float x, float y) {
2471
+ return x - y * sign(x) * floor(abs(x/y));
2472
+ }
2473
+
2474
+ void main() {
2475
+ // Map UV coordinates to RGB
2476
+ float aspect = u_resolution.x / u_resolution.y;
2477
+ vec2 uv = vec2(
2478
+ (vUv.x + sin((u_translation.x +vUv.x) * 10.0) * sin(vUv.y + u_translation.y + u_time / 100.0) * .01 ) * aspect,
2479
+ vUv.y + sin((u_translation.y+vUv.y) * 7.0) * 0.05 * sin(vUv.x + u_translation.x + u_time / 100.)) * u_tile_factor + u_translation;
2480
+
2481
+ vec2 localUv = vec2(
2482
+ mod(uv.x, u_mod_size),
2483
+ mod(uv.y,u_mod_size)
2484
+ );
2485
+
2486
+ float dist = length(
2487
+ localUv - (u_mod_size / 2.0)
2488
+ );
2489
+
2490
+
2491
+ fragColor = mix(
2492
+ vec4(1.0 - localUv.x, localUv.y,1., 1.0),
2493
+ vec4(vec3(1.0), 1.0),
2494
+ smoothstep(0.6, 0.5, dist)
2495
+ );
2496
+ }`, $n = `#version 300 es
2497
+ precision mediump float;
2498
+
2499
+ uniform sampler2D u_texture;
2500
+ uniform float u_size; // [1, 100, 5]
2501
+ uniform vec2 u_resolution; // resolution
2502
+
2503
+ in vec2 vUv;
2504
+ out vec4 fragColor;
2505
+
2506
+ const float PI = 3.1415926535897932384626433832795;
2507
+
2508
+ // Gaussian function
2509
+ float gaussian(float x, float sigma) {
2510
+ return exp(-(x * x) / (2.0 * sigma * sigma)) / (sqrt(2.0 * PI) * sigma);
2511
+ }
2512
+
2513
+ void main() {
2514
+ vec2 texelSize = 1.0 / u_resolution;
2515
+ float sigma = u_size / 3.0; // Standard deviation based on size
2516
+
2517
+ vec4 result = vec4(0.0);
2518
+ float totalWeight = 0.0;
2519
+
2520
+ int kernelRadius = int(ceil(u_size));
2521
+
2522
+ // Two-pass separable Gaussian blur (horizontal + vertical in one pass for simplicity)
2523
+ // For better performance, this should be split into two passes, but for this implementation
2524
+ // we'll do a 2D kernel
2525
+ for (int x = -25; x <= 25; x++) {
2526
+ if (abs(float(x)) > float(kernelRadius)) continue;
2527
+
2528
+ for (int y = -25; y <= 25; y++) {
2529
+ if (abs(float(y)) > float(kernelRadius)) continue;
2530
+
2531
+ vec2 offset = vec2(float(x), float(y)) * texelSize;
2532
+ vec2 sampleCoord = vUv + offset;
2533
+
2534
+ // Clamp to edges
2535
+ sampleCoord = clamp(sampleCoord, vec2(0.0), vec2(1.0));
2536
+
2537
+ float distance = length(vec2(float(x), float(y)));
2538
+ float weight = gaussian(distance, sigma);
2539
+
2540
+ result += texture(u_texture, sampleCoord) * weight;
2541
+ totalWeight += weight;
2542
+ }
2543
+ }
2544
+
2545
+ fragColor = result / totalWeight;
2546
+ }
2547
+ `, zn = `#version 300 es
2548
+ precision mediump float;
2549
+
2550
+ uniform sampler2D u_texture;
2551
+ uniform sampler2D u_gradientTexture; // gradient
2552
+ in vec2 vUv;
2553
+ out vec4 fragColor;
2554
+
2555
+ void main() {
2556
+ vec4 color = texture(u_texture, vUv);
2557
+
2558
+ float brightness = dot(color.rgb, vec3(0.299, 0.587, 0.114));
2559
+
2560
+ vec4 gradientColor = texture(u_gradientTexture, vec2(brightness, 0.5));
2561
+
2562
+ fragColor = vec4(gradientColor.rgb, 1.0);
2563
+ }
2564
+ `, On = `#version 300 es
2565
+ precision mediump float;
2566
+
2567
+ uniform sampler2D u_texture; // input
2568
+ uniform vec3 u_hslAdjust; // H (degrees), S (0-1), L (0-1) — [0, 0, 0]
2569
+
2570
+ in vec2 vUv;
2571
+ out vec4 fragColor;
2572
+
2573
+ vec3 rgb2hsl(vec3 color) {
2574
+ float maxC = max(max(color.r, color.g), color.b);
2575
+ float minC = min(min(color.r, color.g), color.b);
2576
+ float delta = maxC - minC;
2577
+
2578
+ float h = 0.0;
2579
+ float s = 0.0;
2580
+ float l = (maxC + minC) / 2.0;
2581
+
2582
+ if (delta != 0.0) {
2583
+ s = l > 0.5 ? delta / (2.0 - maxC - minC) : delta / (maxC + minC);
2584
+
2585
+ if (color.r == maxC) {
2586
+ h = (color.g - color.b) / delta + (color.g < color.b ? 6.0 : 0.0);
2587
+ } else if (color.g == maxC) {
2588
+ h = (color.b - color.r) / delta + 2.0;
2589
+ } else {
2590
+ h = (color.r - color.g) / delta + 4.0;
2591
+ }
2592
+ h /= 6.0;
2593
+ }
2594
+
2595
+ return vec3(h, s, l);
2596
+ }
2597
+
2598
+ float hue2rgb(float p, float q, float t) {
2599
+ if (t < 0.0) t += 1.0;
2600
+ if (t > 1.0) t -= 1.0;
2601
+ if (t < 1.0/6.0) return p + (q - p) * 6.0 * t;
2602
+ if (t < 1.0/2.0) return q;
2603
+ if (t < 2.0/3.0) return p + (q - p) * (2.0/3.0 - t) * 6.0;
2604
+ return p;
2605
+ }
2606
+
2607
+ vec3 hsl2rgb(vec3 hsl) {
2608
+ float h = hsl.x;
2609
+ float s = hsl.y;
2610
+ float l = hsl.z;
2611
+
2612
+ if (s == 0.0) {
2613
+ return vec3(l);
2614
+ }
2615
+
2616
+ float q = l < 0.5 ? l * (1.0 + s) : l + s - l * s;
2617
+ float p = 2.0 * l - q;
2618
+ return vec3(
2619
+ hue2rgb(p, q, h + 1.0/3.0),
2620
+ hue2rgb(p, q, h),
2621
+ hue2rgb(p, q, h - 1.0/3.0)
2622
+ );
2623
+ }
2624
+
2625
+ void main() {
2626
+ vec4 color = texture(u_texture, vUv);
2627
+
2628
+ vec3 hsl = rgb2hsl(color.rgb);
2629
+
2630
+ hsl.x = mod(hsl.x + u_hslAdjust.x / 360.0, 1.0);
2631
+ hsl.y = clamp(hsl.y + u_hslAdjust.y, 0.0, 1.0);
2632
+ hsl.z = clamp(hsl.z + u_hslAdjust.z, 0.0, 1.0);
2633
+
2634
+ fragColor = vec4(hsl2rgb(hsl), color.a);
2635
+ }
2636
+ `, Ln = `#version 300 es
2637
+ precision highp float;
2638
+
2639
+ in vec2 vUv;
2640
+ out vec4 fragColor;
2641
+
2642
+ uniform sampler2D u_image_source; // texture
2643
+
2644
+ void main() {
2645
+ fragColor = texture(u_image_source, vec2(vUv.x, 1.0-vUv.y));
2646
+ }`, jn = `#version 300 es
2647
+ precision mediump float;
2648
+
2649
+ uniform sampler2D u_texture;
2650
+ uniform float u_size; // [1, 100, 5]
2651
+ uniform vec2 u_resolution; // resolution
2652
+
2653
+ in vec2 vUv;
2654
+ out vec4 fragColor;
2655
+
2656
+ void main() {
2657
+ vec2 texelSize = 1.0 / u_resolution;
2658
+
2659
+ vec4 result = vec4(0.0);
2660
+ int kernelRadius = int(ceil(u_size));
2661
+ int sampleCount = 0;
2662
+
2663
+ // Box blur - simple average of all pixels in the kernel
2664
+ for (int x = -25; x <= 25; x++) {
2665
+ if (abs(float(x)) > float(kernelRadius)) continue;
2666
+
2667
+ for (int y = -25; y <= 25; y++) {
2668
+ if (abs(float(y)) > float(kernelRadius)) continue;
2669
+
2670
+ vec2 offset = vec2(float(x), float(y)) * texelSize;
2671
+ vec2 sampleCoord = vUv + offset;
2672
+
2673
+ // Clamp to edges
2674
+ sampleCoord = clamp(sampleCoord, vec2(0.0), vec2(1.0));
2675
+
2676
+ result += texture(u_texture, sampleCoord);
2677
+ sampleCount++;
2678
+ }
2679
+ }
2680
+
2681
+ fragColor = result / float(sampleCount);
2682
+ }
2683
+ `, qn = `#version 300 es
2684
+ precision highp float;
2685
+
2686
+ uniform float u_time; // time
2687
+ uniform vec2 u_resolution; // resolution
2688
+ uniform vec2 u_mouse;
2689
+ uniform float u_amplitude;
2690
+
2691
+ uniform float u_rotation; // [0, 6.28, 0]
2692
+ uniform float u_density; // [10, 200, 30]
2693
+ uniform float u_threshold;
2694
+ uniform vec4 u_line_color; // color [0,0,0,0]
2695
+
2696
+ uniform sampler2D u_input_tex;
2697
+ uniform float u_mode; // [0, 1, 1]
2698
+
2699
+
2700
+ in vec2 vUv;
2701
+ out vec4 fragColor;
2702
+
2703
+ const float PI = 3.1415926535897932384626433832795;
2704
+
2705
+ /*
2706
+ angle is in radians
2707
+ */
2708
+ vec2 rotate(vec2 uv, float angle) {
2709
+ float c = cos(angle);
2710
+ float s = sin(angle);
2711
+ return mat2(c, -s, s, c) * uv;
2712
+ }
2713
+
2714
+ vec2 invRotate(vec2 uv, float angle) {
2715
+ float c = cos(angle);
2716
+ float s = sin(angle);
2717
+ return mat2(c, s, -s, c) * uv;
2718
+ }
2719
+
2720
+ vec2 rotateCenter(vec2 uv, float angle) {
2721
+ return rotate(uv - vec2(.5), u_rotation) + vec2(.5);
2722
+ }
2723
+
2724
+ void main() {
2725
+ vec2 uv = vec2(vUv.x, vUv.y);
2726
+ vec2 uvInRotatedSpace = invRotate(uv, u_rotation);
2727
+ vec2 targetPixInRot = vec2(floor(uvInRotatedSpace.x * u_density + 0.5)/u_density, uvInRotatedSpace.y);
2728
+ vec2 targetPixInRot2 = vec2(floor((uvInRotatedSpace.x) * u_density + 0.5)/u_density, uvInRotatedSpace.y + sin(u_mouse) / 20.0);
2729
+
2730
+ float distanceFromTargetInRot = smoothstep(0.0, 1.0, abs(targetPixInRot.x - uvInRotatedSpace.x) * 1.2) * 15.0 / (1.0 + u_amplitude * 5.0);
2731
+ float maxDist = 1.0 / u_density;
2732
+
2733
+ vec2 targetInCart = invRotate(targetPixInRot, -u_rotation);
2734
+ vec2 targetInCart2 = invRotate(targetPixInRot2, -u_rotation);
2735
+ vec4 targetColor = (texture(u_input_tex, targetInCart) + texture(u_input_tex, targetInCart2)) * 0.5;
2736
+
2737
+ float targetLum = pow(dot(targetColor.rgb, vec3(0.299, 0.587, 0.114)), 2.0);
2738
+
2739
+ // 1.0 is solid; should be shaded. 0.0 should be white space
2740
+ float solidMask = clamp(targetLum, 0.0, 1.0) < distanceFromTargetInRot * u_density ? 1.0 : 0.0;
2741
+
2742
+
2743
+ if (u_mode > 0.5) {
2744
+ if (solidMask < 0.5) {
2745
+ fragColor = vec4(vec3(u_line_color), 1.0);
2746
+ } else {
2747
+ fragColor = vec4(1.0);
2748
+ }
2749
+ } else {
2750
+ if (solidMask > 0.5) {
2751
+ fragColor = vec4(vec3(u_line_color), 1.0);
2752
+ } else {
2753
+ fragColor = vec4(1.0);
2754
+ }
2755
+ }
2756
+
2757
+ }`, Vn = `#version 300 es
2758
+ precision mediump float;
2759
+
2760
+ uniform sampler2D u_texture; // input
2761
+ uniform vec3 u_rgbAdjust; // RGB offset in [−255, 255] — [0, 0, 0]
2762
+
2763
+ in vec2 vUv;
2764
+ out vec4 fragColor;
2765
+
2766
+ void main() {
2767
+ vec4 color = texture(u_texture, vUv);
2768
+ vec3 adjusted = clamp(color.rgb + u_rgbAdjust / 255.0, 0.0, 1.0);
2769
+ fragColor = vec4(adjusted, color.a);
2770
+ }
2771
+ `, Kn = {
2772
+ "chromakey.frag": Tn,
2773
+ "dither_bayer.frag": Pn,
2774
+ "dots.frag": Mn,
2775
+ "daffodil.frag": Fn,
2776
+ "diamonds.frag": Dn,
2777
+ "gaussian.frag": $n,
2778
+ "gradientmap.frag": zn,
2779
+ "hsl.frag": On,
2780
+ "imageViewer.frag": Ln,
2781
+ "linear.frag": jn,
2782
+ "lines.frag": qn,
2783
+ "rgb.frag": Vn
2784
+ };
2785
+ export {
2786
+ Ce as CustomHandle,
2787
+ ce as Dialog,
2788
+ Xn as Editor,
2789
+ oe as EditorContext,
2790
+ Te as ExportDialog,
2791
+ cn as Renderer,
2792
+ Re as RendererComponent,
2793
+ H as Scrubber,
2794
+ Rn as ShaderNode,
2795
+ Ae as UniformForm,
2796
+ Yn as buildEditorState,
2797
+ dn as exportSequenzaPatch,
2798
+ ae as extractFields,
2799
+ Kn as staticShaders
2800
+ };