@digitalmeadow/control-panel 1.0.3 → 1.0.5

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,12 +1,297 @@
1
+ const z = `
2
+ .cp-root {
3
+ position: fixed;
4
+ top: 10px;
5
+ right: 10px;
6
+ width: 280px;
7
+ max-height: 90vh;
8
+ overflow: auto;
9
+ background: transparent;
10
+ color: #fff;
11
+ mix-blend-mode: exclusion;
12
+ font-family:
13
+ -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial,
14
+ sans-serif;
15
+ font-size: 10px;
16
+ line-height: 1.2;
17
+ padding: 8px;
18
+ z-index: 100;
19
+ }
20
+
21
+ .cp-root::-webkit-scrollbar {
22
+ width: 1px;
23
+ }
24
+ .cp-root::-webkit-scrollbar-track {
25
+ background: transparent;
26
+ }
27
+ .cp-root::-webkit-scrollbar-thumb {
28
+ background: rgba(255, 255, 255, 0.5);
29
+ }
30
+
31
+ .cp-summary {
32
+ cursor: pointer;
33
+ user-select: none;
34
+ font-weight: bold;
35
+ outline: none;
36
+ }
37
+
38
+ .cp-summary-root {
39
+ position: sticky;
40
+ top: 0;
41
+ }
42
+
43
+ .cp-stats {
44
+ float: right;
45
+ font-weight: normal;
46
+ opacity: 0.6;
47
+ font-size: 0.9em;
48
+ font-variant-numeric: tabular-nums;
49
+ }
50
+
51
+ .cp-content {
52
+ margin-top: 4px;
53
+ display: flex;
54
+ flex-direction: column;
55
+ gap: 6px;
56
+ }
57
+
58
+ .cp-folder {
59
+ width: 100%;
60
+ }
61
+
62
+ .cp-folder-content {
63
+ margin: 0 0 6px 0;
64
+ padding: 4px 0 0 9px;
65
+ }
66
+
67
+ .cp-controller {
68
+ display: flex;
69
+ }
70
+
71
+ .cp-label {
72
+ margin: auto 0;
73
+ width: 50%;
74
+ flex-shrink: 0;
75
+ overflow: hidden;
76
+ text-overflow: ellipsis;
77
+ white-space: nowrap;
78
+ user-select: none;
79
+ padding-right: 8px;
80
+ opacity: 0.8;
81
+ }
82
+
83
+ .cp-input-number {
84
+ width: 50%;
85
+ background: transparent;
86
+ border: 1px solid #fff;
87
+ color: inherit;
88
+ padding: 2px 4px;
89
+ border-radius: 2px;
90
+ font-family: inherit;
91
+ font-size: inherit;
92
+ }
93
+
94
+ .cp-input-number:focus {
95
+ outline: none;
96
+ border-color: #fff;
97
+ background: transparent;
98
+ }
99
+
100
+ .cp-select {
101
+ width: 50%;
102
+ background: rgba(255, 255, 255, 0.3);
103
+ border: none;
104
+ padding: 2px 4px;
105
+ border-radius: 2px;
106
+ font-family: inherit;
107
+ font-size: inherit;
108
+ }
109
+
110
+ .cp-checkbox {
111
+ margin: auto 0;
112
+ }
113
+
114
+ .cp-button {
115
+ width: 100%;
116
+ background: rgba(255, 255, 255, 0.3);
117
+ border: none;
118
+ padding: 4px 2px;
119
+ border-radius: 2px;
120
+ cursor: pointer;
121
+ text-align: center;
122
+ font-family: inherit;
123
+ font-size: inherit;
124
+ transition: background 0.1s;
125
+ }
126
+
127
+ .cp-button:hover {
128
+ background: rgba(255, 255, 255, 0.4);
129
+ }
130
+
131
+ .cp-button:active {
132
+ background: rgba(255, 255, 255, 0.2);
133
+ transform: translateY(1px);
134
+ }
135
+
136
+ .cp-controller[data-disabled="true"] {
137
+ opacity: 0.5;
138
+ pointer-events: none;
139
+ cursor: not-allowed;
140
+ }
141
+
142
+ .cp-controller-details {
143
+ width: 50%;
144
+ }
145
+
146
+ .cp-controller-summary {
147
+ cursor: pointer;
148
+ outline: none;
149
+ }
150
+
151
+ .cp-controller-summary-content {
152
+ display: inline-flex;
153
+ align-items: center;
154
+ gap: 6px;
155
+ width: calc(100% - 16px);
156
+ vertical-align: middle;
157
+ }
158
+
159
+ .cp-input-range {
160
+ -webkit-appearance: none;
161
+ flex: 1;
162
+ min-width: 0;
163
+ height: 2px;
164
+ background: rgba(255, 255, 255, 0.3);
165
+ margin: 0;
166
+ vertical-align: middle;
167
+ cursor: grab;
168
+ }
169
+ .cp-input-range::-webkit-slider-thumb {
170
+ -webkit-appearance: none;
171
+ width: 4px;
172
+ height: 8px;
173
+ border-radius: 1px;
174
+ background: #fff;
175
+ cursor: grab;
176
+ }
177
+ .cp-input-range::-moz-range-thumb {
178
+ width: 4px;
179
+ height: 16px;
180
+ background: #fff;
181
+ cursor: grab;
182
+ }
183
+
184
+ .cp-input-range:active {
185
+ cursor: grabbing;
186
+ }
187
+
188
+ .cp-value-display {
189
+ min-width: 24px;
190
+ text-align: right;
191
+ font-variant-numeric: tabular-nums;
192
+ font-size: 0.9em;
193
+ opacity: 0.8;
194
+ user-select: none;
195
+ }
196
+
197
+ .cp-number-settings {
198
+ margin-top: 4px;
199
+ background: transparent;
200
+ display: flex;
201
+ flex-direction: column;
202
+ gap: 4px;
203
+ }
204
+
205
+ .cp-separator {
206
+ border: none;
207
+ border-top: 1px solid rgba(255, 255, 255, 0.3);
208
+ margin: 4px 0;
209
+ width: 100%;
210
+ }
211
+
212
+ .cp-setting-row {
213
+ display: flex;
214
+ align-items: center;
215
+ gap: 4px;
216
+ }
217
+
218
+ .cp-setting-label {
219
+ width: 50%;
220
+ font-size: 0.9em;
221
+ opacity: 0.7;
222
+ }
223
+
224
+ .cp-input-small {
225
+ width: 50%;
226
+ }
227
+
228
+ .cp-radios {
229
+ width: 50%;
230
+ display: flex;
231
+ gap: 2px;
232
+ }
233
+
234
+ .cp-radio {
235
+ flex: 1;
236
+ font-size: 0.9em;
237
+ padding: 4px 2px;
238
+ height: 100%;
239
+ }
240
+
241
+ .cp-radio[data-active="true"] {
242
+ background: rgba(255, 255, 255, 0.2);
243
+ border-color: #fff;
244
+ font-weight: bold;
245
+ }
246
+
247
+ .cp-button-delete {
248
+ width: 24px;
249
+ padding: 0;
250
+ display: flex;
251
+ align-items: center;
252
+ justify-content: center;
253
+ line-height: 1;
254
+ }
255
+
256
+ .cp-input-color {
257
+ padding: 0;
258
+ margin: 0;
259
+ border: none;
260
+ background: none;
261
+ outline: none;
262
+
263
+ isolation: isolate;
264
+ mix-blend-mode: normal;
265
+ cursor: pointer;
266
+ }
267
+
268
+ .cp-color-swatch {
269
+ width: 10px;
270
+ height: 10px;
271
+ margin-right: 8px;
272
+ }
273
+
274
+ .cp-stops-container {
275
+ display: flex;
276
+ flex-direction: column;
277
+ gap: 4px;
278
+ }
279
+ `;
280
+ let V = !1;
281
+ function R() {
282
+ if (V) return;
283
+ const n = document.createElement("style");
284
+ n.id = "control-panel-styles", n.textContent = z, document.head.appendChild(n), V = !0;
285
+ }
1
286
  function r(n, t = {}, e = []) {
2
- const i = document.createElement(n);
3
- for (const [s, a] of Object.entries(t))
4
- s === "className" ? i.className = String(a) : s === "style" && typeof a == "object" ? Object.assign(i.style, a) : s === "open" && typeof a == "boolean" ? a ? i.setAttribute("open", "") : i.removeAttribute("open") : typeof a != "object" && i.setAttribute(s, String(a));
5
- for (const s of e)
6
- typeof s == "string" ? i.appendChild(document.createTextNode(s)) : i.appendChild(s);
7
- return i;
8
- }
9
- function B(n) {
287
+ const s = document.createElement(n);
288
+ for (const [i, a] of Object.entries(t))
289
+ i === "className" ? s.className = String(a) : i === "style" && typeof a == "object" ? Object.assign(s.style, a) : i === "open" && typeof a == "boolean" ? a ? s.setAttribute("open", "") : s.removeAttribute("open") : typeof a != "object" && s.setAttribute(i, String(a));
290
+ for (const i of e)
291
+ typeof i == "string" ? s.appendChild(document.createTextNode(i)) : s.appendChild(i);
292
+ return s;
293
+ }
294
+ function D(n) {
10
295
  const t = r(
11
296
  "button",
12
297
  {
@@ -16,39 +301,39 @@ function B(n) {
16
301
  );
17
302
  return t.addEventListener("click", n), t;
18
303
  }
19
- function R(n) {
304
+ function j(n) {
20
305
  return n.replace(/([A-Z])/g, " $1").replace(/^./, (t) => t.toUpperCase()).trim();
21
306
  }
22
- function D(n, t, e) {
307
+ function O(n, t, e) {
23
308
  return Math.min(Math.max(n, t), e);
24
309
  }
25
- function j(n, t, e) {
310
+ function $(n, t, e) {
26
311
  if (t.length !== e.length)
27
312
  throw new Error("Input and output ranges must have the same length");
28
313
  if (t.length < 2)
29
314
  throw new Error("Input and output ranges must have at least two values");
30
- let i = 0;
31
- for (; i < t.length - 1 && n > t[i + 1]; )
32
- i++;
33
- if (i === t.length - 1)
315
+ let s = 0;
316
+ for (; s < t.length - 1 && n > t[s + 1]; )
317
+ s++;
318
+ if (s === t.length - 1)
34
319
  return e[e.length - 1];
35
- if (i === 0 && n < t[0])
320
+ if (s === 0 && n < t[0])
36
321
  return e[0];
37
- const s = t[i], a = t[i + 1], o = e[i], h = e[i + 1];
38
- return (n - s) / (a - s) * (h - o) + o;
322
+ const i = t[s], a = t[s + 1], o = e[s], c = e[s + 1];
323
+ return (n - i) / (a - i) * (c - o) + o;
39
324
  }
40
- class z {
325
+ class U {
41
326
  constructor() {
42
- this.source = null, this.stream = null, this.fftSize = 2048, this.smoothingTimeConstant = 0.92, this.spectrumBoost = 2, this.levels = {
327
+ this.source = null, this.stream = null, this.fftSize = 2048, this.smoothingTimeConstant = 0.82, this.spectrumBoost = 3, this.levels = {
328
+ volume: 0,
43
329
  bass: 0,
44
330
  mids: 0,
45
- highs: 0,
46
- volume: 0
331
+ highs: 0
47
332
  }, this.peaks = {
333
+ volume: 0,
48
334
  bass: 0,
49
335
  mids: 0,
50
- highs: 0,
51
- volume: 0
336
+ highs: 0
52
337
  }, this._isAnalyzing = !1, this.loop = () => {
53
338
  this._isAnalyzing && (requestAnimationFrame(this.loop), this.update());
54
339
  };
@@ -67,8 +352,8 @@ class z {
67
352
  }) : e = navigator.mediaDevices.getUserMedia({
68
353
  audio: !0
69
354
  });
70
- const i = await e;
71
- this.ctx.state === "suspended" && this.ctx.resume(), this.source && this.source.disconnect(), this.stream && this.stream.getTracks().forEach((s) => s.stop()), this.stream = i, this.source = this.ctx.createMediaStreamSource(this.stream), this.source.connect(this.analyser), this._isAnalyzing = !0, this.loop();
355
+ const s = await e;
356
+ this.ctx.state === "suspended" && this.ctx.resume(), this.source && this.source.disconnect(), this.stream && this.stream.getTracks().forEach((i) => i.stop()), this.stream = s, this.source = this.ctx.createMediaStreamSource(this.stream), this.source.connect(this.analyser), this._isAnalyzing = !0, this.loop();
72
357
  } catch (e) {
73
358
  console.error("Error accessing audio input:", e), this._isAnalyzing = !1;
74
359
  }
@@ -76,35 +361,35 @@ class z {
76
361
  update() {
77
362
  if (this.analyser.getByteFrequencyData(this.dataArray), this.analyser.getByteTimeDomainData(this.waveformArray), this.spectrumBoost !== 1) {
78
363
  const p = this.dataArray.length;
79
- for (let c = 0; c < p; c++) {
80
- const u = 1 + c / p * (this.spectrumBoost - 1);
81
- this.dataArray[c] = Math.min(255, this.dataArray[c] * u);
364
+ for (let h = 0; h < p; h++) {
365
+ const m = 1 + h / p * (this.spectrumBoost - 1);
366
+ this.dataArray[h] = Math.min(255, this.dataArray[h] * m);
82
367
  }
83
368
  }
84
- const t = [2, 10], e = [10, 150], i = [150, 600], s = this.getAverage(t[0], t[1]), a = this.getAverage(e[0], e[1]), o = this.getAverage(i[0], i[1]), h = this.getAverage(0, i[1]);
85
- this.processLevel("bass", s), this.processLevel("mids", a), this.processLevel("highs", o), this.processLevel("volume", h);
369
+ const t = [2, 10], e = [10, 150], s = [150, 600], i = this.getAverage(t[0], t[1]), a = this.getAverage(e[0], e[1]), o = this.getAverage(s[0], s[1]), c = this.getAverage(0, s[1]);
370
+ this.processLevel("bass", i), this.processLevel("mids", a), this.processLevel("highs", o), this.processLevel("volume", c);
86
371
  }
87
372
  processLevel(t, e) {
88
- this.peaks[t] -= 5e-4, this.peaks[t] = D(this.peaks[t], 0.1, 1), e > this.peaks[t] && (this.peaks[t] = e), this.levels[t] = D(
89
- j(e, [0, this.peaks[t]], [0, 1]),
373
+ this.peaks[t] -= 5e-4, this.peaks[t] = O(this.peaks[t], 0.1, 1), e > this.peaks[t] && (this.peaks[t] = e), this.levels[t] = O(
374
+ $(e, [0, this.peaks[t]], [0, 1]),
90
375
  0,
91
376
  1
92
377
  );
93
378
  }
94
379
  getAverage(t, e) {
95
- let i = 0;
96
- const s = e - t;
97
- if (s <= 0) return 0;
380
+ let s = 0;
381
+ const i = e - t;
382
+ if (i <= 0) return 0;
98
383
  for (let a = t; a < e; a++)
99
- i += this.dataArray[a];
100
- return i / s / 255;
384
+ s += this.dataArray[a];
385
+ return s / i / 255;
101
386
  }
102
387
  getSignal(t) {
103
388
  return () => this.levels[t];
104
389
  }
105
390
  }
106
- const x = new z();
107
- class $ {
391
+ const C = new U();
392
+ class H {
108
393
  constructor() {
109
394
  this.midiAccess = null, this.values = /* @__PURE__ */ new Map(), this.isListening = !1, this.resolveListen = null, this.listeningCallback = null, this.init();
110
395
  }
@@ -125,18 +410,18 @@ class $ {
125
410
  e.onmidimessage = this.handleMessage.bind(this);
126
411
  }
127
412
  handleMessage(t) {
128
- const e = t.data, [i] = e;
129
- if ((i & 240) >= 240) return;
413
+ const e = t.data, [s] = e;
414
+ if ((s & 240) >= 240) return;
130
415
  const a = this.getIdFromMessage(t), o = this.normalizeValue(e);
131
416
  this.values.set(a, o), this.isListening && this.resolveListen && o > 0 && (this.resolveListen(a), this.isListening = !1, this.resolveListen = null, this.listeningCallback && this.listeningCallback());
132
417
  }
133
418
  getIdFromMessage(t) {
134
- const e = t.data, [i, s] = e, a = i & 240, o = t.currentTarget.name || "unknown", h = a === 144 || a === 128 ? "note" : "ctrl", p = o.replace(/[^a-zA-Z0-9]/g, "");
135
- return `${s}_${h}_${p}`;
419
+ const e = t.data, [s, i] = e, a = s & 240, o = t.currentTarget.name || "unknown", c = a === 144 || a === 128 ? "note" : "ctrl", p = o.replace(/[^a-zA-Z0-9]/g, "");
420
+ return `${i}_${c}_${p}`;
136
421
  }
137
422
  normalizeValue(t) {
138
- const [e, i, s] = t, a = e & 240;
139
- return a === 144 ? s > 0 ? 1 : 0 : a === 128 ? 0 : a === 176 ? s / 127 : 0;
423
+ const [e, s, i] = t, a = e & 240;
424
+ return a === 144 ? i > 0 ? 1 : 0 : a === 128 ? 0 : a === 176 ? i / 127 : 0;
140
425
  }
141
426
  listen() {
142
427
  return this.isListening = !0, new Promise((t) => {
@@ -150,13 +435,108 @@ class $ {
150
435
  return () => this.values.get(t) ?? 0;
151
436
  }
152
437
  }
153
- const q = new $(), M = class M {
154
- constructor(t, e, i = {}) {
155
- this.changeFns = /* @__PURE__ */ new Set(), this.object = t, this.property = e, this.key = i.id ?? e, this.initialValue = this.object[this.property], this.domElement = r("div", { className: "cp-controller" });
156
- const s = i.label ?? R(e), a = r("label", { className: "cp-label" }, [
157
- String(s)
438
+ const W = new H();
439
+ class _ {
440
+ constructor() {
441
+ this.configs = /* @__PURE__ */ new Map(), this.lastRandomUpdateTime = 0, this.currentRandomValue = 0, this.startTime = performance.now(), this.configs.set("constant", {
442
+ frequency: 0.1,
443
+ // Units per second
444
+ amplitude: 1,
445
+ offset: 0,
446
+ phase: 0
447
+ }), this.configs.set("sine", {
448
+ frequency: 0.1,
449
+ amplitude: 1,
450
+ offset: 0,
451
+ phase: 0
452
+ }), this.configs.set("sawtooth", {
453
+ frequency: 0.1,
454
+ amplitude: 1,
455
+ offset: 0,
456
+ phase: 0
457
+ }), this.configs.set("triangle", {
458
+ frequency: 0.1,
459
+ amplitude: 1,
460
+ offset: 0,
461
+ phase: 0
462
+ }), this.configs.set("square", {
463
+ frequency: 0.1,
464
+ amplitude: 1,
465
+ offset: 0,
466
+ phase: 0
467
+ }), this.configs.set("random", {
468
+ frequency: 10,
469
+ // Updates per second
470
+ amplitude: 1,
471
+ offset: 0,
472
+ phase: 0
473
+ });
474
+ }
475
+ setConfig(t, e) {
476
+ const s = this.configs.get(t);
477
+ this.configs.set(t, { ...s, ...e });
478
+ }
479
+ getConfig(t) {
480
+ return { ...this.configs.get(t) };
481
+ }
482
+ getTime() {
483
+ return (performance.now() - this.startTime) / 1e3;
484
+ }
485
+ normalizeOutput(t, e) {
486
+ const s = t * e.amplitude + e.offset;
487
+ return Math.max(0, Math.min(1, s));
488
+ }
489
+ constant(t) {
490
+ const e = t ? { ...this.configs.get("constant"), ...t } : this.configs.get("constant"), i = this.getTime() * e.frequency % 1;
491
+ return this.normalizeOutput(i, e);
492
+ }
493
+ sine(t) {
494
+ const e = t ? { ...this.configs.get("sine"), ...t } : this.configs.get("sine"), s = this.getTime(), i = e.phase * Math.PI * 2, o = (Math.sin(s * e.frequency * Math.PI * 2 + i) + 1) / 2;
495
+ return this.normalizeOutput(o, e);
496
+ }
497
+ sawtooth(t) {
498
+ const e = t ? { ...this.configs.get("sawtooth"), ...t } : this.configs.get("sawtooth"), s = this.getTime(), i = e.phase, a = (s * e.frequency + i) % 1 + i % 1;
499
+ return this.normalizeOutput(a % 1, e);
500
+ }
501
+ triangle(t) {
502
+ const e = t ? { ...this.configs.get("triangle"), ...t } : this.configs.get("triangle"), s = this.getTime(), i = e.phase, a = (s * e.frequency + i) % 1, o = a < 0.5 ? a * 2 : 2 - a * 2;
503
+ return this.normalizeOutput(o, e);
504
+ }
505
+ square(t) {
506
+ const e = t ? { ...this.configs.get("square"), ...t } : this.configs.get("square"), s = this.getTime(), i = e.phase, o = (s * e.frequency + i) % 1 < 0.5 ? 0 : 1;
507
+ return this.normalizeOutput(o, e);
508
+ }
509
+ random(t) {
510
+ const e = t ? { ...this.configs.get("random"), ...t } : this.configs.get("random"), s = performance.now(), i = 1e3 / e.frequency;
511
+ return s - this.lastRandomUpdateTime > i && (this.currentRandomValue = Math.random(), this.lastRandomUpdateTime = s), this.normalizeOutput(this.currentRandomValue, e);
512
+ }
513
+ getSignal(t) {
514
+ switch (t) {
515
+ case "constant":
516
+ return () => this.constant();
517
+ case "sine":
518
+ return () => this.sine();
519
+ case "sawtooth":
520
+ return () => this.sawtooth();
521
+ case "triangle":
522
+ return () => this.triangle();
523
+ case "square":
524
+ return () => this.square();
525
+ case "random":
526
+ return () => this.random();
527
+ }
528
+ }
529
+ reset() {
530
+ this.startTime = performance.now(), this.lastRandomUpdateTime = 0, this.currentRandomValue = 0;
531
+ }
532
+ }
533
+ const J = new _(), T = class T {
534
+ constructor(t, e, s = {}) {
535
+ this.changeFns = /* @__PURE__ */ new Set(), this.object = t, this.property = e, this.key = s.id ?? e, this.initialValue = this.object[this.property], this.domElement = r("div", { className: "cp-controller" });
536
+ const i = s.label ?? j(e), a = r("label", { className: "cp-label" }, [
537
+ String(i)
158
538
  ]);
159
- a.setAttribute("title", String(s)), this.domElement.appendChild(a), i.disabled && this.domElement.setAttribute("data-disabled", "true");
539
+ a.setAttribute("title", String(i)), this.domElement.appendChild(a), s.disabled && this.domElement.setAttribute("data-disabled", "true");
160
540
  }
161
541
  get value() {
162
542
  return this.object[this.property];
@@ -184,9 +564,9 @@ const q = new $(), M = class M {
184
564
  this.domElement.appendChild(t);
185
565
  }
186
566
  };
187
- M.audio = x, M.midi = q;
188
- let m = M;
189
- const O = {
567
+ T.audio = C, T.midi = W, T.math = J;
568
+ let d = T;
569
+ const P = {
190
570
  linear: (n) => n,
191
571
  quadIn: (n) => n * n,
192
572
  quadOut: (n) => n * (2 - n),
@@ -201,28 +581,52 @@ const O = {
201
581
  sineOut: (n) => Math.sin(n * Math.PI / 2),
202
582
  sineInOut: (n) => -(Math.cos(Math.PI * n) - 1) / 2
203
583
  };
204
- class P {
584
+ class B {
205
585
  constructor(t) {
206
586
  this.rafId = null, this.currentSignalType = null, this.currentMidiId = null, this.currentEase = "linear", this.currentBehaviour = "forward", this.loop = () => {
207
587
  if (this.currentSignalType) {
208
588
  let e = 0;
209
- this.currentSignalType === "midi" ? this.currentMidiId && (e = m.midi.getSignal(this.currentMidiId)()) : e = m.audio.getSignal(this.currentSignalType)();
210
- const i = O[this.currentEase](e);
211
- this.onChange(i, this.currentBehaviour), this.rafId = requestAnimationFrame(this.loop);
589
+ this.currentSignalType === "midi" ? this.currentMidiId && (e = d.midi.getSignal(this.currentMidiId)()) : [
590
+ "constant",
591
+ "sine",
592
+ "sawtooth",
593
+ "triangle",
594
+ "square",
595
+ "random"
596
+ ].includes(this.currentSignalType) ? e = d.math.getSignal(
597
+ this.currentSignalType
598
+ )() : ["volume", "bass", "mids", "highs"].includes(this.currentSignalType) && (e = d.audio.getSignal(
599
+ this.currentSignalType
600
+ )());
601
+ const s = P[this.currentEase](e);
602
+ this.onChange(s, this.currentBehaviour), this.rafId = requestAnimationFrame(this.loop);
212
603
  }
213
604
  }, this.onChange = t.onChange, this.setupControllers(t.container);
214
605
  }
215
606
  setupControllers(t) {
216
607
  const e = this.createSettingSelect(
217
608
  "signal",
218
- ["none", "bass", "mids", "highs", "volume", "midi"],
609
+ [
610
+ "none",
611
+ "volume",
612
+ "bass",
613
+ "mids",
614
+ "highs",
615
+ "constant",
616
+ "sine",
617
+ "sawtooth",
618
+ "triangle",
619
+ "square",
620
+ "random",
621
+ "midi"
622
+ ],
219
623
  (o) => this.setSignalType(o)
220
624
  );
221
625
  this.signalSelect = e.select, t.appendChild(e.row), this.midiRow = r("div", {
222
626
  className: "cp-setting-row",
223
627
  style: "display: none;"
224
628
  });
225
- const i = r(
629
+ const s = r(
226
630
  "label",
227
631
  { className: "cp-setting-label" },
228
632
  ["Midi"]
@@ -233,44 +637,112 @@ class P {
233
637
  ["Learn"]
234
638
  ), this.midiBtn.addEventListener("click", async () => {
235
639
  if (this.midiBtn.textContent === "Listening...") {
236
- m.midi.cancelListen(), this.setMidiId(null);
640
+ d.midi.cancelListen(), this.setMidiId(null);
237
641
  return;
238
642
  }
239
643
  this.midiBtn.textContent = "Listening...";
240
- const o = await m.midi.listen();
644
+ const o = await d.midi.listen();
241
645
  this.setMidiId(o);
242
- }), this.midiRow.appendChild(i), this.midiRow.appendChild(this.midiBtn), t.appendChild(this.midiRow);
243
- const s = this.createSettingSelect(
646
+ }), this.midiRow.appendChild(s), this.midiRow.appendChild(this.midiBtn), t.appendChild(this.midiRow), this.mathParamsContainer = r("div", {
647
+ style: "display: none; flex-direction: column; gap: 4px;"
648
+ }), t.appendChild(this.mathParamsContainer);
649
+ const i = this.createSettingSelect(
244
650
  "behaviour",
245
651
  ["forward", "backward", "loopForward", "loopBackward", "pingpong"],
246
652
  (o) => this.setBehaviour(o)
247
653
  );
248
- this.behaviourRow = s.row, this.behaviourSelect = s.select, this.behaviourRow.style.display = "none", this.behaviourSelect.value = this.currentBehaviour, t.appendChild(this.behaviourRow);
654
+ this.behaviourRow = i.row, this.behaviourSelect = i.select, this.behaviourRow.style.display = "none", this.behaviourSelect.value = this.currentBehaviour, t.appendChild(this.behaviourRow);
249
655
  const a = this.createSettingSelect(
250
656
  "ease",
251
- Object.keys(O),
657
+ Object.keys(P),
252
658
  (o) => this.setEase(o)
253
659
  );
254
660
  this.easeRow = a.row, this.easeSelect = a.select, this.easeRow.style.display = "none", this.easeSelect.value = this.currentEase, t.appendChild(this.easeRow);
255
661
  }
256
- createSettingSelect(t, e, i) {
257
- const s = r("div", { className: "cp-setting-row" }), a = r("label", { className: "cp-setting-label" }, [
662
+ createSettingSelect(t, e, s) {
663
+ const i = r("div", { className: "cp-setting-row" }), a = r("label", { className: "cp-setting-label" }, [
258
664
  t
259
665
  ]), o = r("select", {
260
666
  className: "cp-select cp-input-small"
261
667
  });
262
- return e.forEach((h) => {
263
- const p = r("option", { value: h }, [h]);
668
+ return e.forEach((c) => {
669
+ const p = r("option", { value: c }, [c]);
264
670
  o.appendChild(p);
265
- }), o.addEventListener("change", () => i(o.value)), s.appendChild(a), s.appendChild(o), { row: s, select: o };
671
+ }), o.addEventListener("change", () => s(o.value)), i.appendChild(a), i.appendChild(o), { row: i, select: o };
672
+ }
673
+ createNumberInput(t, e, s, i, a, o) {
674
+ const c = r("div", { className: "cp-setting-row" }), p = r("label", { className: "cp-setting-label" }, [
675
+ t
676
+ ]), h = r("input", {
677
+ className: "cp-input-number cp-input-small",
678
+ type: "number",
679
+ value: String(e),
680
+ min: String(s),
681
+ max: String(i),
682
+ step: String(a)
683
+ });
684
+ return h.addEventListener("input", () => {
685
+ const u = parseFloat(h.value);
686
+ isNaN(u) || o(u);
687
+ }), c.appendChild(p), c.appendChild(h), { row: c, input: h };
688
+ }
689
+ updateMathParams(t) {
690
+ this.mathParamsContainer.innerHTML = "";
691
+ const e = d.math.getConfig(t);
692
+ let s = "Frequency", i = 0.1, a = 10, o = 0.1;
693
+ t === "random" ? a = 30 : t === "constant" && (s = "Speed", i = 0.01, a = 2, o = 0.01);
694
+ const c = this.createNumberInput(
695
+ s,
696
+ e.frequency,
697
+ i,
698
+ a,
699
+ o,
700
+ (u) => d.math.setConfig(t, { frequency: u })
701
+ );
702
+ this.mathParamsContainer.appendChild(c.row);
703
+ const p = this.createNumberInput(
704
+ "Amplitude",
705
+ e.amplitude,
706
+ 0,
707
+ 2,
708
+ 0.1,
709
+ (u) => d.math.setConfig(t, { amplitude: u })
710
+ );
711
+ this.mathParamsContainer.appendChild(p.row);
712
+ const h = this.createNumberInput(
713
+ "Offset",
714
+ e.offset,
715
+ 0,
716
+ 1,
717
+ 0.1,
718
+ (u) => d.math.setConfig(t, { offset: u })
719
+ );
720
+ if (this.mathParamsContainer.appendChild(h.row), ["sine", "sawtooth", "triangle", "square"].includes(t)) {
721
+ const u = this.createNumberInput(
722
+ "Phase",
723
+ e.phase,
724
+ 0,
725
+ 1,
726
+ 0.01,
727
+ (m) => d.math.setConfig(t, { phase: m })
728
+ );
729
+ this.mathParamsContainer.appendChild(u.row);
730
+ }
266
731
  }
267
732
  setSignalType(t) {
268
733
  if (!t || t === "none")
269
- this.currentSignalType = null, this.currentMidiId = null, this.midiRow.style.display = "none", this.easeRow.style.display = "none", this.behaviourRow.style.display = "none", this.stop(), this.signalSelect.value !== "none" && (this.signalSelect.value = "none");
734
+ this.currentSignalType = null, this.currentMidiId = null, this.midiRow.style.display = "none", this.mathParamsContainer.style.display = "none", this.easeRow.style.display = "none", this.behaviourRow.style.display = "none", this.stop(), this.signalSelect.value !== "none" && (this.signalSelect.value = "none");
270
735
  else {
271
736
  this.currentSignalType = t;
272
- const e = t === "midi";
273
- this.midiRow.style.display = e ? "flex" : "none", this.easeRow.style.display = "flex", this.behaviourRow.style.display = "flex", e || (this.currentMidiId = null, m.audio.ctx.state === "suspended" && m.audio.setInput("microphone")), this.start(), this.signalSelect.value !== t && (this.signalSelect.value = t);
737
+ const e = t === "midi", s = [
738
+ "constant",
739
+ "sine",
740
+ "sawtooth",
741
+ "triangle",
742
+ "square",
743
+ "random"
744
+ ].includes(t), i = ["volume", "bass", "mids", "highs"].includes(t);
745
+ this.midiRow.style.display = e ? "flex" : "none", this.mathParamsContainer.style.display = s ? "flex" : "none", s && this.updateMathParams(t), this.easeRow.style.display = "flex", this.behaviourRow.style.display = "flex", i ? (this.currentMidiId = null, d.audio.ctx.state === "suspended" && d.audio.setInput("microphone")) : e || (this.currentMidiId = null), this.start(), this.signalSelect.value !== t && (this.signalSelect.value = t);
274
746
  }
275
747
  }
276
748
  setMidiId(t) {
@@ -303,10 +775,10 @@ class P {
303
775
  this.setSignalType("none"), this.setEase("linear"), this.setBehaviour("forward"), this.setMidiId(null);
304
776
  }
305
777
  }
306
- class H extends m {
307
- constructor(t, e, i = {}) {
308
- super(t, e, i), this.pingPongDirection = 1, this.min = 0, this.max = 100, this.initialOptions = i, this.min = i.min ?? 0, this.max = i.max ?? 100;
309
- const s = r("details", {
778
+ class G extends d {
779
+ constructor(t, e, s = {}) {
780
+ super(t, e, s), this.pingPongDirection = 1, this.min = 0, this.max = 100, this.initialOptions = s, this.min = s.min ?? 0, this.max = s.max ?? 100;
781
+ const i = r("details", {
310
782
  className: "cp-controller-details"
311
783
  }), a = r("summary", {
312
784
  className: "cp-controller-summary"
@@ -314,8 +786,8 @@ class H extends m {
314
786
  this.input = r("input", {
315
787
  type: "range",
316
788
  className: "cp-input-range",
317
- step: i.step ?? "any"
318
- }), i.min !== void 0 && (this.input.min = String(i.min)), i.max !== void 0 && (this.input.max = String(i.max)), this.input.value = String(this.value), this.display = r(
789
+ step: s.step ?? "any"
790
+ }), s.min !== void 0 && (this.input.min = String(s.min)), s.max !== void 0 && (this.input.max = String(s.max)), this.input.value = String(this.value), this.display = r(
319
791
  "span",
320
792
  {
321
793
  className: "cp-value-display"
@@ -330,30 +802,30 @@ class H extends m {
330
802
  const o = r("div", {
331
803
  className: "cp-controller-summary-content"
332
804
  });
333
- o.appendChild(this.input), o.appendChild(this.display), a.appendChild(o), s.appendChild(a);
334
- const h = r("div", { className: "cp-number-settings" }), p = this.createSetting(
805
+ o.appendChild(this.input), o.appendChild(this.display), a.appendChild(o), i.appendChild(a);
806
+ const c = r("div", { className: "cp-number-settings" }), p = this.createSetting(
335
807
  "min",
336
- i.min,
808
+ s.min,
337
809
  (l) => this.setMin(l)
338
810
  );
339
- this.minInput = p.input, h.appendChild(p.row);
340
- const c = this.createSetting(
811
+ this.minInput = p.input, c.appendChild(p.row);
812
+ const h = this.createSetting(
341
813
  "max",
342
- i.max,
814
+ s.max,
343
815
  (l) => this.setMax(l)
344
816
  );
345
- this.maxInput = c.input, h.appendChild(c.row);
346
- const y = this.createSetting(
817
+ this.maxInput = h.input, c.appendChild(h.row);
818
+ const u = this.createSetting(
347
819
  "step",
348
- i.step,
820
+ s.step,
349
821
  (l) => this.setStep(l)
350
822
  );
351
- this.stepInput = y.input, h.appendChild(y.row);
352
- const u = r("hr", { className: "cp-separator" });
353
- h.appendChild(u), this.signalHandler = new P({
354
- container: h,
355
- onChange: (l, d) => this.applySignal(l, d)
356
- }), s.appendChild(h), this.appendWidget(s);
823
+ this.stepInput = u.input, c.appendChild(u.row);
824
+ const m = r("hr", { className: "cp-separator" });
825
+ c.appendChild(m), this.signalHandler = new B({
826
+ container: c,
827
+ onChange: (l, f) => this.applySignal(l, f)
828
+ }), i.appendChild(c), this.appendWidget(i);
357
829
  }
358
830
  // Setters
359
831
  setMin(t) {
@@ -366,34 +838,34 @@ class H extends m {
366
838
  t === void 0 && (t = ""), typeof t == "number" && (t = String(t)), t === "" || t === "any" || isNaN(parseFloat(t)) ? this.input.step = "any" : this.input.step = t, this.stepInput && (t === "any" || t === "" ? this.stepInput.value = "" : this.stepInput.value !== t && (this.stepInput.value = t));
367
839
  }
368
840
  applySignal(t, e) {
369
- const i = this.max - this.min;
370
- let s;
841
+ const s = this.max - this.min;
842
+ let i;
371
843
  if (e === "forward")
372
- s = this.min + t * i;
844
+ i = this.min + t * s;
373
845
  else if (e === "backward")
374
- s = this.max - t * i;
846
+ i = this.max - t * s;
375
847
  else {
376
- const a = t * (i * 0.01);
377
- s = this.value, e === "loopForward" ? (s += a, s > this.max && (s = this.min + (s - this.min) % i)) : e === "loopBackward" ? (s -= a, s < this.min && (s = this.max - (this.max - s) % i)) : e === "pingpong" && (s += a * this.pingPongDirection, s >= this.max ? (s = this.max, this.pingPongDirection = -1) : s <= this.min && (s = this.min, this.pingPongDirection = 1));
848
+ const a = t * (s * 0.01);
849
+ i = this.value, e === "loopForward" ? (i += a, i > this.max && (i = this.min + (i - this.min) % s)) : e === "loopBackward" ? (i -= a, i < this.min && (i = this.max - (this.max - i) % s)) : e === "pingpong" && (i += a * this.pingPongDirection, i >= this.max ? (i = this.max, this.pingPongDirection = -1) : i <= this.min && (i = this.min, this.pingPongDirection = 1));
378
850
  }
379
- s = this.roundToStep(s), this.setValue(s), this.input.value = String(s), this.display.textContent = String(s.toFixed(1));
851
+ i = this.roundToStep(i), this.setValue(i), this.input.value = String(i), this.display.textContent = String(i.toFixed(1));
380
852
  }
381
853
  roundToStep(t) {
382
854
  const e = this.input.step;
383
855
  if (e === "any" || e === "" || isNaN(parseFloat(e)))
384
856
  return t;
385
- const i = parseFloat(e), s = this.min;
386
- return s + Math.round((t - s) / i) * i;
857
+ const s = parseFloat(e), i = this.min;
858
+ return i + Math.round((t - i) / s) * s;
387
859
  }
388
- createSetting(t, e, i) {
389
- const s = r("div", { className: "cp-setting-row" }), a = r("label", { className: "cp-setting-label" }, [
860
+ createSetting(t, e, s) {
861
+ const i = r("div", { className: "cp-setting-row" }), a = r("label", { className: "cp-setting-label" }, [
390
862
  t
391
863
  ]), o = r("input", {
392
864
  type: "number",
393
865
  className: "cp-input-number cp-input-small",
394
866
  step: "any"
395
867
  });
396
- return e !== void 0 && (o.value = String(e)), o.addEventListener("input", () => i(o.value)), s.appendChild(a), s.appendChild(o), { row: s, input: o };
868
+ return e !== void 0 && (o.value = String(e)), o.addEventListener("input", () => s(o.value)), i.appendChild(a), i.appendChild(o), { row: i, input: o };
397
869
  }
398
870
  updateDisplay() {
399
871
  this.input.value = String(this.value), this.display.textContent = String(this.value.toFixed(1));
@@ -419,8 +891,8 @@ class H extends m {
419
891
  ), e.max !== void 0 ? this.setMax(e.max) : this.setMax(
420
892
  this.initialOptions.max !== void 0 ? this.initialOptions.max : ""
421
893
  ), e.step !== void 0 ? this.setStep(e.step) : this.setStep(this.initialOptions.step);
422
- let i = t.value;
423
- !isNaN(this.min) && i < this.min && (i = this.min), !isNaN(this.max) && i > this.max && (i = this.max), this.setValue(i), this.signalHandler?.load(e.signal);
894
+ let s = t.value;
895
+ !isNaN(this.min) && s < this.min && (s = this.min), !isNaN(this.max) && s > this.max && (s = this.max), this.setValue(s), this.signalHandler?.load(e.signal);
424
896
  }
425
897
  }
426
898
  reset() {
@@ -434,24 +906,24 @@ class H extends m {
434
906
  ), this.setStep(this.initialOptions.step), this.signalHandler?.reset();
435
907
  }
436
908
  }
437
- class U extends m {
438
- constructor(t, e, i) {
439
- super(t, e, i), this.optionValues = [], this.select = r("select", { className: "cp-select" }), this.optionValues = i.options || [], this.optionValues.forEach((s, a) => {
909
+ class Z extends d {
910
+ constructor(t, e, s) {
911
+ super(t, e, s), this.optionValues = [], this.select = r("select", { className: "cp-select" }), this.optionValues = s.options || [], this.optionValues.forEach((i, a) => {
440
912
  const o = r("option", { value: String(a) }, [
441
- String(s)
913
+ String(i)
442
914
  ]);
443
915
  this.select.appendChild(o);
444
916
  }), this.updateDisplay(), this.select.addEventListener("change", () => {
445
- const s = parseInt(this.select.value), a = this.optionValues[s];
917
+ const i = parseInt(this.select.value), a = this.optionValues[i];
446
918
  this.setValue(a);
447
919
  }), this.appendWidget(this.select);
448
920
  }
449
921
  setOptions(t) {
450
- this.select.innerHTML = "", this.optionValues = t, this.optionValues.forEach((e, i) => {
451
- const s = r("option", { value: String(i) }, [
922
+ this.select.innerHTML = "", this.optionValues = t, this.optionValues.forEach((e, s) => {
923
+ const i = r("option", { value: String(s) }, [
452
924
  String(e)
453
925
  ]);
454
- this.select.appendChild(s);
926
+ this.select.appendChild(i);
455
927
  }), this.updateDisplay(), this.select.value === "" && this.optionValues.length > 0 && this.setValue(this.optionValues[0]);
456
928
  }
457
929
  updateDisplay() {
@@ -459,11 +931,11 @@ class U extends m {
459
931
  t !== -1 && (this.select.value = String(t));
460
932
  }
461
933
  }
462
- class _ extends m {
463
- constructor(t, e, i = {}) {
464
- const s = { action: e };
465
- super(s, "action", i);
466
- const a = i.label ?? t;
934
+ class K extends d {
935
+ constructor(t, e, s = {}) {
936
+ const i = { action: e };
937
+ super(i, "action", s);
938
+ const a = s.label ?? t;
467
939
  this.button = r("button", { className: "cp-button" }, [
468
940
  String(a)
469
941
  ]), this.button.addEventListener("click", () => {
@@ -474,9 +946,9 @@ class _ extends m {
474
946
  updateDisplay() {
475
947
  }
476
948
  }
477
- class W extends m {
478
- constructor(t, e, i = {}) {
479
- super(t, e, i), this.input = r("input", {
949
+ class Y extends d {
950
+ constructor(t, e, s = {}) {
951
+ super(t, e, s), this.input = r("input", {
480
952
  type: "checkbox",
481
953
  className: "cp-checkbox"
482
954
  }), this.input.checked = this.value, this.input.addEventListener("change", () => {
@@ -487,32 +959,32 @@ class W extends m {
487
959
  this.input.checked = this.value;
488
960
  }
489
961
  }
490
- class J extends m {
491
- constructor(t, e, i) {
492
- super(t, e, i), this.buttons = [], this.optionValues = [], this.container = r("div", { className: "cp-radios" }), this.optionValues = i.options || [], this.optionValues.forEach((s) => {
962
+ class Q extends d {
963
+ constructor(t, e, s) {
964
+ super(t, e, s), this.buttons = [], this.optionValues = [], this.container = r("div", { className: "cp-radios" }), this.optionValues = s.options || [], this.optionValues.forEach((i) => {
493
965
  const a = r("button", { className: "cp-button cp-radio" }, [
494
- String(s)
966
+ String(i)
495
967
  ]);
496
968
  a.addEventListener("click", () => {
497
- this.setValue(s);
969
+ this.setValue(i);
498
970
  }), this.container.appendChild(a), this.buttons.push(a);
499
971
  }), this.updateDisplay(), this.appendWidget(this.container);
500
972
  }
501
973
  updateDisplay() {
502
974
  const t = this.value;
503
- this.buttons.forEach((e, i) => {
504
- this.optionValues[i] === t ? e.setAttribute("data-active", "true") : e.removeAttribute("data-active");
975
+ this.buttons.forEach((e, s) => {
976
+ this.optionValues[s] === t ? e.setAttribute("data-active", "true") : e.removeAttribute("data-active");
505
977
  });
506
978
  }
507
979
  }
508
- class G extends m {
509
- constructor(t, e, i = {}) {
510
- super(t, e, i), this.input = r("input", {
980
+ class X extends d {
981
+ constructor(t, e, s = {}) {
982
+ super(t, e, s), this.input = r("input", {
511
983
  type: "color",
512
984
  className: "cp-input-color",
513
985
  value: this.value || "#000000"
514
- }), this.appendWidget(this.input), this.input.addEventListener("input", (s) => {
515
- const a = s.target;
986
+ }), this.appendWidget(this.input), this.input.addEventListener("input", (i) => {
987
+ const a = i.target;
516
988
  this.setValue(a.value);
517
989
  }), this.updateDisplay();
518
990
  }
@@ -522,7 +994,7 @@ class G extends m {
522
994
  }
523
995
  function F(n) {
524
996
  const t = /^#?([a-f\d])([a-f\d])([a-f\d])$/i;
525
- n = n.replace(t, (i, s, a, o) => s + s + a + a + o + o);
997
+ n = n.replace(t, (s, i, a, o) => i + i + a + a + o + o);
526
998
  const e = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(n);
527
999
  return e ? [
528
1000
  parseInt(e[1], 16),
@@ -530,27 +1002,27 @@ function F(n) {
530
1002
  parseInt(e[3], 16)
531
1003
  ] : [0, 0, 0];
532
1004
  }
533
- function Z(n, t, e) {
1005
+ function tt(n, t, e) {
534
1006
  return "#" + ((1 << 24) + (Math.round(n) << 16) + (Math.round(t) << 8) + Math.round(e)).toString(16).slice(1);
535
1007
  }
536
1008
  function w(n) {
537
1009
  const t = n / 255;
538
1010
  return t <= 0.04045 ? t / 12.92 : Math.pow((t + 0.055) / 1.055, 2.4);
539
1011
  }
540
- function A(n) {
1012
+ function L(n) {
541
1013
  return n <= 31308e-7 ? n * 12.92 * 255 : (1.055 * Math.pow(n, 1 / 2.4) - 0.055) * 255;
542
1014
  }
543
- function K(n, t, e) {
544
- const [i, s, a] = F(n), [o, h, p] = F(t), c = w(i), y = w(s), u = w(a), l = w(o), d = w(h), f = w(p), v = c + e * (l - c), I = y + e * (d - y), S = u + e * (f - u), C = A(v), g = A(I), b = A(S);
545
- return Z(C, g, b);
1015
+ function et(n, t, e) {
1016
+ const [s, i, a] = F(n), [o, c, p] = F(t), h = w(s), u = w(i), m = w(a), l = w(o), f = w(c), g = w(p), b = h + e * (l - h), I = u + e * (f - u), v = m + e * (g - m), S = L(b), y = L(I), x = L(v);
1017
+ return tt(S, y, x);
546
1018
  }
547
- class Q extends m {
548
- constructor(t, e, i = {}) {
549
- super(t, e, i), this.stops = [], this.pingPongDirection = 1, this.animationT = 0, this.manualPosition = 0, this.initialOptions = i, this.stops = i.stops || [
1019
+ class st extends d {
1020
+ constructor(t, e, s = {}) {
1021
+ super(t, e, s), this.stops = [], this.pingPongDirection = 1, this.animationT = 0, this.manualPosition = 0, this.initialOptions = s, this.stops = s.stops || [
550
1022
  { color: "#000000", position: 0 },
551
1023
  { color: "#ffffff", position: 1 }
552
1024
  ], this.sortStops();
553
- const s = r("details", {
1025
+ const i = r("details", {
554
1026
  className: "cp-controller-details"
555
1027
  }), a = r("summary", {
556
1028
  className: "cp-controller-summary"
@@ -564,11 +1036,11 @@ class Q extends m {
564
1036
  "span",
565
1037
  { className: "cp-value-display" },
566
1038
  [String(this.value)]
567
- ), o.appendChild(this.displayColor), o.appendChild(this.displayText), a.appendChild(o), s.appendChild(a);
568
- const h = r("div", { className: "cp-number-settings" });
1039
+ ), o.appendChild(this.displayColor), o.appendChild(this.displayText), a.appendChild(o), i.appendChild(a);
1040
+ const c = r("div", { className: "cp-number-settings" });
569
1041
  this.stopsContainer = r("div", {
570
1042
  className: "cp-stops-container"
571
- }), this.renderStops(), h.appendChild(this.stopsContainer);
1043
+ }), this.renderStops(), c.appendChild(this.stopsContainer);
572
1044
  const p = r(
573
1045
  "button",
574
1046
  {
@@ -578,25 +1050,25 @@ class Q extends m {
578
1050
  );
579
1051
  p.addEventListener("click", () => {
580
1052
  this.stops.push({ color: "#ffffff", position: 0.5 }), this.sortStops(), this.renderStops(), this.updateOutput();
581
- }), h.appendChild(p);
582
- const c = r("hr", { className: "cp-separator" });
583
- h.appendChild(c), this.signalHandler = new P({
584
- container: h,
585
- onChange: (y, u) => this.applySignal(y, u)
586
- }), s.appendChild(h), this.appendWidget(s), this.updateOutput(0);
1053
+ }), c.appendChild(p);
1054
+ const h = r("hr", { className: "cp-separator" });
1055
+ c.appendChild(h), this.signalHandler = new B({
1056
+ container: c,
1057
+ onChange: (u, m) => this.applySignal(u, m)
1058
+ }), i.appendChild(c), this.appendWidget(i), this.updateOutput(0);
587
1059
  }
588
1060
  sortStops() {
589
1061
  this.stops.sort((t, e) => t.position - e.position);
590
1062
  }
591
1063
  renderStops() {
592
1064
  this.stopsContainer.innerHTML = "", this.stops.forEach((t, e) => {
593
- const i = r("div", { className: "cp-setting-row" }), s = r("input", {
1065
+ const s = r("div", { className: "cp-setting-row" }), i = r("input", {
594
1066
  type: "color",
595
1067
  className: "cp-input-color",
596
1068
  value: t.color
597
1069
  });
598
- s.addEventListener("input", (h) => {
599
- t.color = h.target.value, this.updateOutput();
1070
+ i.addEventListener("input", (c) => {
1071
+ t.color = c.target.value, this.updateOutput();
600
1072
  });
601
1073
  const a = r("input", {
602
1074
  type: "number",
@@ -606,14 +1078,14 @@ class Q extends m {
606
1078
  step: "0.01",
607
1079
  value: String(t.position)
608
1080
  });
609
- a.addEventListener("change", (h) => {
610
- let p = parseFloat(h.target.value);
1081
+ a.addEventListener("change", (c) => {
1082
+ let p = parseFloat(c.target.value);
611
1083
  isNaN(p) && (p = 0), t.position = Math.max(0, Math.min(1, p)), this.sortStops(), this.renderStops(), this.updateOutput();
612
1084
  });
613
- const o = B(() => {
1085
+ const o = D(() => {
614
1086
  this.stops.splice(e, 1), this.renderStops(), this.updateOutput();
615
1087
  });
616
- i.appendChild(s), i.appendChild(a), i.appendChild(o), this.stopsContainer.appendChild(i);
1088
+ s.appendChild(i), s.appendChild(a), s.appendChild(o), this.stopsContainer.appendChild(s);
617
1089
  });
618
1090
  }
619
1091
  // Calculate color at t (0-1) and update value
@@ -629,11 +1101,11 @@ class Q extends m {
629
1101
  else if (t >= this.stops[this.stops.length - 1].position)
630
1102
  e = this.stops[this.stops.length - 1].color;
631
1103
  else
632
- for (let i = 0; i < this.stops.length - 1; i++) {
633
- const s = this.stops[i], a = this.stops[i + 1];
634
- if (t >= s.position && t <= a.position) {
635
- const o = a.position - s.position, h = o === 0 ? 0 : (t - s.position) / o;
636
- e = K(s.color, a.color, h);
1104
+ for (let s = 0; s < this.stops.length - 1; s++) {
1105
+ const i = this.stops[s], a = this.stops[s + 1];
1106
+ if (t >= i.position && t <= a.position) {
1107
+ const o = a.position - i.position, c = o === 0 ? 0 : (t - i.position) / o;
1108
+ e = et(i.color, a.color, c);
637
1109
  break;
638
1110
  }
639
1111
  }
@@ -643,16 +1115,16 @@ class Q extends m {
643
1115
  this.displayColor && (this.displayColor.style.backgroundColor = this.value), this.displayText && (this.displayText.textContent = this.value);
644
1116
  }
645
1117
  applySignal(t, e) {
646
- let i = t;
1118
+ let s = t;
647
1119
  if (e === "forward")
648
- i = t;
1120
+ s = t;
649
1121
  else if (e === "backward")
650
- i = 1 - t;
1122
+ s = 1 - t;
651
1123
  else {
652
- const s = t * 0.05;
653
- e === "loopForward" ? (this.animationT = (this.animationT + s) % 1, i = this.animationT) : e === "loopBackward" ? (this.animationT = (this.animationT - s + 1) % 1, i = this.animationT) : e === "pingpong" && (this.animationT += s * this.pingPongDirection, this.animationT >= 1 ? (this.animationT = 1, this.pingPongDirection = -1) : this.animationT <= 0 && (this.animationT = 0, this.pingPongDirection = 1), i = this.animationT);
1124
+ const i = t * 0.05;
1125
+ e === "loopForward" ? (this.animationT = (this.animationT + i) % 1, s = this.animationT) : e === "loopBackward" ? (this.animationT = (this.animationT - i + 1) % 1, s = this.animationT) : e === "pingpong" && (this.animationT += i * this.pingPongDirection, this.animationT >= 1 ? (this.animationT = 1, this.pingPongDirection = -1) : this.animationT <= 0 && (this.animationT = 0, this.pingPongDirection = 1), s = this.animationT);
654
1126
  }
655
- this.updateOutput(i), this.manualPosition = i;
1127
+ this.updateOutput(s), this.manualPosition = s;
656
1128
  }
657
1129
  save() {
658
1130
  return {
@@ -672,24 +1144,24 @@ class Q extends m {
672
1144
  ], this.sortStops(), this.renderStops(), this.signalHandler?.reset(), this.updateOutput(0);
673
1145
  }
674
1146
  }
675
- class X extends m {
676
- constructor(t, e, i = {}) {
677
- super(t, e, i), this.items = [], this.initialOptions = i, this.itemType = i.itemType || "string", this.items = this.parseValue(this.value);
678
- const s = r("details", {
1147
+ class it extends d {
1148
+ constructor(t, e, s = {}) {
1149
+ super(t, e, s), this.items = [], this.initialOptions = s, this.itemType = s.itemType || "string", this.items = this.parseValue(this.value);
1150
+ const i = r("details", {
679
1151
  className: "cp-controller-details"
680
1152
  }), a = r("summary", {
681
1153
  className: "cp-controller-summary"
682
1154
  }), o = r("div", {
683
1155
  className: "cp-controller-summary-content"
684
- }), h = r("span", { className: "cp-value-display" }, [
1156
+ }), c = r("span", { className: "cp-value-display" }, [
685
1157
  `${this.items.length} items`
686
1158
  ]);
687
- o.appendChild(h), a.appendChild(o), s.appendChild(a);
1159
+ o.appendChild(c), a.appendChild(o), i.appendChild(a);
688
1160
  const p = r("div", { className: "cp-number-settings" });
689
1161
  this.itemsContainer = r("div", {
690
1162
  className: "cp-stops-container"
691
1163
  }), this.renderItems(), p.appendChild(this.itemsContainer);
692
- const c = r(
1164
+ const h = r(
693
1165
  "button",
694
1166
  {
695
1167
  className: "cp-button cp-input-small",
@@ -697,9 +1169,9 @@ class X extends m {
697
1169
  },
698
1170
  ["+ Add Item"]
699
1171
  );
700
- c.addEventListener("click", () => {
1172
+ h.addEventListener("click", () => {
701
1173
  this.addItem();
702
- }), p.appendChild(c), s.appendChild(p), this.appendWidget(s);
1174
+ }), p.appendChild(h), i.appendChild(p), this.appendWidget(i);
703
1175
  }
704
1176
  parseValue(t) {
705
1177
  return !t || t.trim() === "" ? [] : t.split(",").map((e) => e.trim());
@@ -731,28 +1203,28 @@ class X extends m {
731
1203
  }
732
1204
  renderItems() {
733
1205
  this.itemsContainer.innerHTML = "", this.items.forEach((t, e) => {
734
- const i = r("div", { className: "cp-setting-row" });
735
- let s;
736
- this.itemType === "color" ? s = r("input", {
1206
+ const s = r("div", { className: "cp-setting-row" });
1207
+ let i;
1208
+ this.itemType === "color" ? i = r("input", {
737
1209
  type: "color",
738
1210
  className: "cp-input-color",
739
1211
  value: t
740
- }) : this.itemType === "number" ? s = r("input", {
1212
+ }) : this.itemType === "number" ? i = r("input", {
741
1213
  type: "number",
742
1214
  className: "cp-input-number cp-input-small",
743
1215
  step: "any",
744
1216
  value: t
745
- }) : s = r("input", {
1217
+ }) : i = r("input", {
746
1218
  type: "text",
747
1219
  className: "cp-input-number cp-input-small",
748
1220
  value: t
749
- }), s.addEventListener("input", (o) => {
1221
+ }), i.addEventListener("input", (o) => {
750
1222
  this.items[e] = o.target.value, this.updateValue();
751
1223
  });
752
- const a = B(() => {
1224
+ const a = D(() => {
753
1225
  this.items.splice(e, 1), this.renderItems(), this.updateValue();
754
1226
  });
755
- i.appendChild(s), i.appendChild(a), this.itemsContainer.appendChild(i);
1227
+ s.appendChild(i), s.appendChild(a), this.itemsContainer.appendChild(s);
756
1228
  });
757
1229
  }
758
1230
  updateDisplay() {
@@ -768,16 +1240,16 @@ class X extends m {
768
1240
  this.items = this.parseValue(t), this.renderItems(), this.updateValue();
769
1241
  }
770
1242
  }
771
- class Y {
1243
+ class nt {
772
1244
  constructor() {
773
1245
  this.frames = 0, this.pollingInterval = 1e3, this.prevTime = performance.now(), this.render = () => {
774
1246
  this.frames++;
775
1247
  const t = performance.now();
776
1248
  if (t >= this.prevTime + this.pollingInterval) {
777
1249
  const e = Math.round(this.frames * 1e3 / (t - this.prevTime));
778
- let i = "";
779
- const s = performance.memory;
780
- s && (i = ` / ${Math.round(s.usedJSHeapSize / 1048576)}MB`), this.domElement.textContent = `${e} FPS${i}`, this.prevTime = t, this.frames = 0;
1250
+ let s = "";
1251
+ const i = performance.memory;
1252
+ i && (s = ` / ${Math.round(i.usedJSHeapSize / 1048576)}MB`), this.domElement.textContent = `${e} FPS${s}`, this.prevTime = t, this.frames = 0;
781
1253
  }
782
1254
  this.rafId = requestAnimationFrame(this.render);
783
1255
  }, this.domElement = r("span", { className: "cp-stats" }), this.rafId = requestAnimationFrame(this.render);
@@ -786,44 +1258,44 @@ class Y {
786
1258
  cancelAnimationFrame(this.rafId);
787
1259
  }
788
1260
  }
789
- class k {
1261
+ class q {
790
1262
  constructor() {
791
1263
  this.controllers = [], this.folders = [];
792
1264
  }
793
- addNumber(t, e, i = {}) {
794
- const s = new H(t, e, i);
795
- return this.contentElement.appendChild(s.domElement), this.controllers.push(s), s;
1265
+ addNumber(t, e, s = {}) {
1266
+ const i = new G(t, e, s);
1267
+ return this.contentElement.appendChild(i.domElement), this.controllers.push(i), i;
796
1268
  }
797
- addSelect(t, e, i = {}) {
798
- const s = new U(t, e, i);
799
- return this.contentElement.appendChild(s.domElement), this.controllers.push(s), s;
1269
+ addSelect(t, e, s = {}) {
1270
+ const i = new Z(t, e, s);
1271
+ return this.contentElement.appendChild(i.domElement), this.controllers.push(i), i;
800
1272
  }
801
- addBoolean(t, e, i = {}) {
802
- const s = new W(t, e, i);
803
- return this.contentElement.appendChild(s.domElement), this.controllers.push(s), s;
1273
+ addBoolean(t, e, s = {}) {
1274
+ const i = new Y(t, e, s);
1275
+ return this.contentElement.appendChild(i.domElement), this.controllers.push(i), i;
804
1276
  }
805
- addButton(t, e, i = {}) {
806
- const s = new _(t, e, i);
807
- return this.contentElement.appendChild(s.domElement), this.controllers.push(s), s;
1277
+ addButton(t, e, s = {}) {
1278
+ const i = new K(t, e, s);
1279
+ return this.contentElement.appendChild(i.domElement), this.controllers.push(i), i;
808
1280
  }
809
- addRadio(t, e, i = {}) {
810
- const s = new J(t, e, i);
811
- return this.contentElement.appendChild(s.domElement), this.controllers.push(s), s;
1281
+ addRadio(t, e, s = {}) {
1282
+ const i = new Q(t, e, s);
1283
+ return this.contentElement.appendChild(i.domElement), this.controllers.push(i), i;
812
1284
  }
813
- addColor(t, e, i = {}) {
814
- const s = new G(t, e, i);
815
- return this.contentElement.appendChild(s.domElement), this.controllers.push(s), s;
1285
+ addColor(t, e, s = {}) {
1286
+ const i = new X(t, e, s);
1287
+ return this.contentElement.appendChild(i.domElement), this.controllers.push(i), i;
816
1288
  }
817
- addGradient(t, e, i = {}) {
818
- const s = new Q(t, e, i);
819
- return this.contentElement.appendChild(s.domElement), this.controllers.push(s), s;
1289
+ addGradient(t, e, s = {}) {
1290
+ const i = new st(t, e, s);
1291
+ return this.contentElement.appendChild(i.domElement), this.controllers.push(i), i;
820
1292
  }
821
- addArray(t, e, i = {}) {
822
- const s = new X(t, e, i);
823
- return this.contentElement.appendChild(s.domElement), this.controllers.push(s), s;
1293
+ addArray(t, e, s = {}) {
1294
+ const i = new it(t, e, s);
1295
+ return this.contentElement.appendChild(i.domElement), this.controllers.push(i), i;
824
1296
  }
825
1297
  addFolder(t) {
826
- const e = new tt(t);
1298
+ const e = new at(t);
827
1299
  return this.contentElement.appendChild(e.domElement), this.folders.push(e), e;
828
1300
  }
829
1301
  save() {
@@ -845,13 +1317,13 @@ class k {
845
1317
  for (const e of this.controllers)
846
1318
  if (typeof e.value != "function")
847
1319
  if (t.controllers && e.key in t.controllers) {
848
- const i = t.controllers[e.key];
849
- i !== void 0 && e.load(i);
1320
+ const s = t.controllers[e.key];
1321
+ s !== void 0 && e.load(s);
850
1322
  } else
851
1323
  e.reset();
852
1324
  for (const e of this.folders) {
853
- const i = t.folders ? t.folders[e.title] : void 0;
854
- e.load(i);
1325
+ const s = t.folders ? t.folders[e.title] : void 0;
1326
+ e.load(s);
855
1327
  }
856
1328
  }
857
1329
  reset() {
@@ -861,7 +1333,7 @@ class k {
861
1333
  t.reset();
862
1334
  }
863
1335
  }
864
- class tt extends k {
1336
+ class at extends q {
865
1337
  constructor(t) {
866
1338
  super(), this.title = t, this.domElement = r("details", {
867
1339
  className: "cp-folder",
@@ -879,40 +1351,40 @@ class tt extends k {
879
1351
  );
880
1352
  }
881
1353
  }
882
- class et extends k {
1354
+ class ot extends q {
883
1355
  constructor(t, e = {}) {
884
- super(), this.domElement = r("details", {
1356
+ super(), R(), this.domElement = r("details", {
885
1357
  className: "cp-root",
886
1358
  open: !0
887
1359
  }), this.summaryElement = r("summary", {
888
1360
  className: "cp-summary cp-summary-root"
889
1361
  }), this.domElement.appendChild(this.summaryElement);
890
- const i = r("span", {}, [
1362
+ const s = r("span", {}, [
891
1363
  e.title || "ControlPanel"
892
1364
  ]);
893
- this.summaryElement.appendChild(i), this.stats = new Y(), this.summaryElement.appendChild(this.stats.domElement), this.contentElement = r("div", { className: "cp-content" }), this.domElement.appendChild(this.contentElement);
894
- const s = this.addFolder("_Signals"), a = {
1365
+ this.summaryElement.appendChild(s), this.stats = new nt(), this.summaryElement.appendChild(this.stats.domElement), this.contentElement = r("div", { className: "cp-content" }), this.domElement.appendChild(this.contentElement);
1366
+ const i = this.addFolder("_Signals"), a = {
895
1367
  audioInput: null,
896
1368
  fftSize: 2048
897
1369
  };
898
- s.addRadio(a, "audioInput", {
1370
+ i.addRadio(a, "audioInput", {
899
1371
  label: "Audio Signal",
900
1372
  options: ["microphone", "browser"]
901
1373
  }).onChange((l) => {
902
- x.setInput(l);
903
- }), s.addSelect(a, "fftSize", {
1374
+ C.setInput(l);
1375
+ }), i.addSelect(a, "fftSize", {
904
1376
  label: "FFT Size",
905
1377
  options: [256, 512, 1024, 2048]
906
1378
  }).onChange((l) => {
907
- x.setFFTSize(l);
908
- }), s.addNumber(x, "smoothingTimeConstant", {
1379
+ C.setFFTSize(l);
1380
+ }), i.addNumber(C, "smoothingTimeConstant", {
909
1381
  min: 0,
910
1382
  max: 0.99,
911
1383
  step: 0.01,
912
1384
  label: "Smoothing"
913
1385
  }).onChange((l) => {
914
- x.analyser.smoothingTimeConstant = l;
915
- }), s.addNumber(x, "spectrumBoost", {
1386
+ C.analyser.smoothingTimeConstant = l;
1387
+ }), i.addNumber(C, "spectrumBoost", {
916
1388
  min: 1,
917
1389
  max: 5,
918
1390
  step: 0.1,
@@ -920,127 +1392,127 @@ class et extends k {
920
1392
  }), t ? t.appendChild(this.domElement) : document.body.appendChild(this.domElement);
921
1393
  const o = e.title || "ControlPanel";
922
1394
  this.presetStoragePrefix = `cp-presets-${o}-`;
923
- const h = this.addFolder("_User Presets"), p = () => {
1395
+ const c = this.addFolder("_User Presets"), p = () => {
924
1396
  const l = ["Default"];
925
1397
  if (typeof localStorage > "u") return l;
926
- for (let d = 0; d < localStorage.length; d++) {
927
- const f = localStorage.key(d);
928
- if (f && f.startsWith(this.presetStoragePrefix)) {
929
- const v = f.substring(this.presetStoragePrefix.length);
930
- v !== "Default" && !l.includes(v) && l.push(v);
1398
+ for (let f = 0; f < localStorage.length; f++) {
1399
+ const g = localStorage.key(f);
1400
+ if (g && g.startsWith(this.presetStoragePrefix)) {
1401
+ const b = g.substring(this.presetStoragePrefix.length);
1402
+ b !== "Default" && !l.includes(b) && l.push(b);
931
1403
  }
932
1404
  }
933
1405
  return l.sort();
934
- }, c = {
1406
+ }, h = {
935
1407
  selected: "Default",
936
1408
  save: () => {
937
- const l = prompt("Preset Name:", c.selected);
1409
+ const l = prompt("Preset Name:", h.selected);
938
1410
  if (l) {
939
1411
  if (l === "Default") {
940
1412
  alert("Cannot overwrite Default preset");
941
1413
  return;
942
1414
  }
943
- const d = this.presetStoragePrefix + l;
944
- this.saveToLocalStorage(d);
945
- const f = p();
946
- u.setOptions(f), c.selected = l, u.setValue(l);
1415
+ const f = this.presetStoragePrefix + l;
1416
+ this.saveToLocalStorage(f);
1417
+ const g = p();
1418
+ m.setOptions(g), h.selected = l, m.setValue(l);
947
1419
  }
948
1420
  },
949
1421
  load: () => {
950
- const l = c.selected, d = this.presetStoragePrefix + l;
951
- this.loadFromLocalStorage(d), c.selected = l, u.setValue(l);
1422
+ const l = h.selected, f = this.presetStoragePrefix + l;
1423
+ this.loadFromLocalStorage(f), h.selected = l, m.setValue(l);
952
1424
  },
953
1425
  delete: () => {
954
- if (c.selected === "Default") {
1426
+ if (h.selected === "Default") {
955
1427
  alert("Cannot delete Default preset");
956
1428
  return;
957
1429
  }
958
- if (confirm(`Delete preset "${c.selected}"?`)) {
959
- const l = this.presetStoragePrefix + c.selected;
1430
+ if (confirm(`Delete preset "${h.selected}"?`)) {
1431
+ const l = this.presetStoragePrefix + h.selected;
960
1432
  localStorage.removeItem(l);
961
- const d = p();
962
- u.setOptions(d), c.selected = "Default", u.setValue("Default"), this.reset();
1433
+ const f = p();
1434
+ m.setOptions(f), h.selected = "Default", m.setValue("Default"), this.reset();
963
1435
  }
964
1436
  },
965
1437
  export: () => {
966
- const l = this.save(), d = (T) => {
1438
+ const l = this.save(), f = (M) => {
967
1439
  const N = {
968
1440
  controllers: {},
969
1441
  folders: {}
970
1442
  };
971
- for (const [E, L] of Object.entries(T.controllers))
972
- E.startsWith("_") || (N.controllers[E] = L);
973
- for (const [E, L] of Object.entries(
974
- T.folders
1443
+ for (const [E, k] of Object.entries(M.controllers))
1444
+ E.startsWith("_") || (N.controllers[E] = k);
1445
+ for (const [E, k] of Object.entries(
1446
+ M.folders
975
1447
  ))
976
- E.startsWith("_") || (N.folders[E] = d(L));
1448
+ E.startsWith("_") || (N.folders[E] = f(k));
977
1449
  return N;
978
- }, f = d(l), v = {
979
- _presetName: c.selected || "CustomPreset",
1450
+ }, g = f(l), b = {
1451
+ _presetName: h.selected || "CustomPreset",
980
1452
  _exportDate: (/* @__PURE__ */ new Date()).toISOString(),
981
1453
  _instructions: "To add as factory preset: Copy 'controllers' and 'folders' fields into the presets.json file",
982
- ...f
983
- }, I = JSON.stringify(v, null, 2), S = new Blob([I], { type: "application/json" }), C = URL.createObjectURL(S), g = document.createElement("a");
984
- g.href = C;
985
- const b = (/* @__PURE__ */ new Date()).toISOString().split("T")[0], V = c.selected.replace(/[^a-z0-9]/gi, "-").toLowerCase();
986
- g.download = `${o.toLowerCase()}-preset-${V}-${b}.json`, document.body.appendChild(g), g.click(), document.body.removeChild(g), URL.revokeObjectURL(C);
1454
+ ...g
1455
+ }, I = JSON.stringify(b, null, 2), v = new Blob([I], { type: "application/json" }), S = URL.createObjectURL(v), y = document.createElement("a");
1456
+ y.href = S;
1457
+ const x = (/* @__PURE__ */ new Date()).toISOString().split("T")[0], A = h.selected.replace(/[^a-z0-9]/gi, "-").toLowerCase();
1458
+ y.download = `${o.toLowerCase()}-preset-${A}-${x}.json`, document.body.appendChild(y), y.click(), document.body.removeChild(y), URL.revokeObjectURL(S);
987
1459
  },
988
1460
  import: () => {
989
1461
  const l = document.createElement("input");
990
- l.type = "file", l.accept = ".json", l.onchange = (d) => {
991
- const f = d.target.files?.[0];
992
- if (!f) return;
993
- const v = new FileReader();
994
- v.onload = (I) => {
1462
+ l.type = "file", l.accept = ".json", l.onchange = (f) => {
1463
+ const g = f.target.files?.[0];
1464
+ if (!g) return;
1465
+ const b = new FileReader();
1466
+ b.onload = (I) => {
995
1467
  try {
996
- const S = I.target?.result, C = JSON.parse(S), g = {
997
- controllers: C.controllers || {},
998
- folders: C.folders || {}
1468
+ const v = I.target?.result, S = JSON.parse(v), y = {
1469
+ controllers: S.controllers || {},
1470
+ folders: S.folders || {}
999
1471
  };
1000
- if (!g.controllers || !g.folders) {
1472
+ if (!y.controllers || !y.folders) {
1001
1473
  alert(
1002
1474
  "Invalid preset file: missing 'controllers' or 'folders'"
1003
1475
  );
1004
1476
  return;
1005
1477
  }
1006
- this.load(g);
1007
- const b = C._presetName || "ImportedPreset";
1478
+ this.load(y);
1479
+ const x = S._presetName || "ImportedPreset";
1008
1480
  if (confirm(
1009
- `Preset loaded! Save as "${b}" to User Presets?`
1481
+ `Preset loaded! Save as "${x}" to User Presets?`
1010
1482
  )) {
1011
- const T = this.presetStoragePrefix + b;
1012
- this.saveToLocalStorage(T);
1483
+ const M = this.presetStoragePrefix + x;
1484
+ this.saveToLocalStorage(M);
1013
1485
  const N = p();
1014
- u.setOptions(N), c.selected = b, u.setValue(b);
1486
+ m.setOptions(N), h.selected = x, m.setValue(x);
1015
1487
  }
1016
- } catch (S) {
1488
+ } catch (v) {
1017
1489
  alert(
1018
- `Failed to import preset: ${S instanceof Error ? S.message : "Invalid JSON"}`
1019
- ), console.error("Import error:", S);
1490
+ `Failed to import preset: ${v instanceof Error ? v.message : "Invalid JSON"}`
1491
+ ), console.error("Import error:", v);
1020
1492
  }
1021
- }, v.readAsText(f);
1493
+ }, b.readAsText(g);
1022
1494
  }, l.click();
1023
1495
  }
1024
- }, y = p(), u = h.addSelect(c, "selected", {
1496
+ }, u = p(), m = c.addSelect(h, "selected", {
1025
1497
  label: "Preset",
1026
- options: y
1498
+ options: u
1027
1499
  });
1028
- h.addButton("Load", () => c.load()), h.addButton("Save / New", () => c.save()), h.addButton("Delete", () => c.delete()), h.addButton("Export JSON", () => c.export()), h.addButton("Import JSON", () => c.import());
1500
+ c.addButton("Load", () => h.load()), c.addButton("Save / New", () => h.save()), c.addButton("Delete", () => h.delete()), c.addButton("Export JSON", () => h.export()), c.addButton("Import JSON", () => h.import());
1029
1501
  }
1030
1502
  saveToLocalStorage(t) {
1031
1503
  const e = this.save();
1032
1504
  try {
1033
1505
  localStorage.setItem(t, JSON.stringify(e));
1034
- } catch (i) {
1035
- console.warn("ControlPanel: Failed to save to localStorage", i);
1506
+ } catch (s) {
1507
+ console.warn("ControlPanel: Failed to save to localStorage", s);
1036
1508
  }
1037
1509
  }
1038
1510
  loadFromLocalStorage(t) {
1039
1511
  try {
1040
1512
  const e = localStorage.getItem(t);
1041
1513
  if (e) {
1042
- const i = JSON.parse(e);
1043
- this.load(i);
1514
+ const s = JSON.parse(e);
1515
+ this.load(s);
1044
1516
  }
1045
1517
  } catch (e) {
1046
1518
  console.warn("ControlPanel: Failed to load from localStorage", e);
@@ -1055,20 +1527,22 @@ class et extends k {
1055
1527
  }
1056
1528
  }
1057
1529
  export {
1058
- X as ArrayController,
1059
- z as AudioSignals,
1060
- W as BooleanController,
1061
- _ as ButtonController,
1062
- G as ColorController,
1063
- et as ControlPanel,
1064
- k as ControlPanelContainer,
1065
- m as Controller,
1066
- tt as Folder,
1067
- Q as GradientController,
1068
- $ as MidiSignals,
1069
- H as NumberController,
1070
- J as RadioController,
1071
- U as SelectController,
1072
- x as audioSignals,
1073
- q as midiSignals
1530
+ it as ArrayController,
1531
+ U as AudioSignals,
1532
+ Y as BooleanController,
1533
+ K as ButtonController,
1534
+ X as ColorController,
1535
+ ot as ControlPanel,
1536
+ q as ControlPanelContainer,
1537
+ d as Controller,
1538
+ at as Folder,
1539
+ st as GradientController,
1540
+ _ as MathSignals,
1541
+ H as MidiSignals,
1542
+ G as NumberController,
1543
+ Q as RadioController,
1544
+ Z as SelectController,
1545
+ C as audioSignals,
1546
+ J as mathSignals,
1547
+ W as midiSignals
1074
1548
  };