@hfd-sdk/keyboard-kit 1.0.0 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,1742 @@
1
+ var uo = Object.defineProperty;
2
+ var wo = (e, o, l) => o in e ? uo(e, o, { enumerable: !0, configurable: !0, writable: !0, value: l }) : e[o] = l;
3
+ var D = (e, o, l) => wo(e, typeof o != "symbol" ? o + "" : o, l);
4
+ import { s as mo, c as Mo, a as go, b as ao } from "../runtime-core.es.js";
5
+ import { c as bo, a as po, b as ko } from "../assert-hfd-device.js";
6
+ import { g as $o } from "../assert-hfd-device.js";
7
+ function P(e, o, l) {
8
+ const t = l * o, s = t * (1 - Math.abs(e / 60 % 2 - 1)), i = l - t;
9
+ let f, n, m;
10
+ return e >= 0 && e < 60 ? (f = t, n = s, m = 0) : e >= 60 && e < 120 ? (f = s, n = t, m = 0) : e >= 120 && e < 180 ? (f = 0, n = t, m = s) : e >= 180 && e < 240 ? (f = 0, n = s, m = t) : e >= 240 && e < 300 ? (f = s, n = 0, m = t) : (f = t, n = 0, m = s), {
11
+ r: Math.round((f + i) * 255),
12
+ g: Math.round((n + i) * 255),
13
+ b: Math.round((m + i) * 255)
14
+ };
15
+ }
16
+ function Co(e) {
17
+ if (e.length > 7 || e.length < 4)
18
+ return { r: 0, g: 0, b: 0 };
19
+ if (e.length === 4) {
20
+ const s = parseInt(e[1] + e[1], 16), i = parseInt(e[2] + e[2], 16), f = parseInt(e[3] + e[3], 16);
21
+ return { r: s, g: i, b: f };
22
+ }
23
+ const o = parseInt(e.slice(1, 3), 16), l = parseInt(e.slice(3, 5), 16), t = parseInt(e.slice(5, 7), 16);
24
+ return { r: o, g: l, b: t };
25
+ }
26
+ const vo = [
27
+ [{ row: 2, col: 6 }],
28
+ [
29
+ { row: 1, col: 6 },
30
+ { row: 1, col: 7 },
31
+ { row: 2, col: 5 },
32
+ { row: 2, col: 7 },
33
+ { row: 3, col: 6 },
34
+ { row: 3, col: 7 }
35
+ ],
36
+ [
37
+ { row: 0, col: 6 },
38
+ { row: 0, col: 7 },
39
+ { row: 0, col: 8 },
40
+ { row: 1, col: 5 },
41
+ { row: 1, col: 8 },
42
+ { row: 2, col: 4 },
43
+ { row: 2, col: 8 },
44
+ { row: 3, col: 5 },
45
+ { row: 3, col: 8 },
46
+ { row: 4, col: 4 },
47
+ { row: 4, col: 5 },
48
+ { row: 4, col: 6 },
49
+ { row: 4, col: 7 }
50
+ ],
51
+ [
52
+ { row: 0, col: 5 },
53
+ { row: 0, col: 9 },
54
+ { row: 1, col: 4 },
55
+ { row: 1, col: 9 },
56
+ { row: 2, col: 3 },
57
+ { row: 2, col: 9 },
58
+ { row: 3, col: 4 },
59
+ { row: 3, col: 9 },
60
+ { row: 4, col: 3 }
61
+ ],
62
+ [
63
+ { row: 0, col: 4 },
64
+ { row: 0, col: 10 },
65
+ { row: 1, col: 3 },
66
+ { row: 1, col: 10 },
67
+ { row: 2, col: 2 },
68
+ { row: 2, col: 10 },
69
+ { row: 3, col: 3 },
70
+ { row: 3, col: 10 }
71
+ ],
72
+ [
73
+ { row: 0, col: 3 },
74
+ { row: 0, col: 11 },
75
+ { row: 1, col: 2 },
76
+ { row: 1, col: 11 },
77
+ { row: 2, col: 1 },
78
+ { row: 2, col: 11 },
79
+ { row: 3, col: 2 },
80
+ { row: 3, col: 11 },
81
+ { row: 4, col: 2 },
82
+ { row: 4, col: 8 }
83
+ ],
84
+ [
85
+ { row: 0, col: 2 },
86
+ { row: 0, col: 12 },
87
+ { row: 1, col: 1 },
88
+ { row: 1, col: 12 },
89
+ { row: 2, col: 0 },
90
+ { row: 2, col: 12 },
91
+ { row: 3, col: 0 },
92
+ { row: 3, col: 1 },
93
+ { row: 3, col: 12 },
94
+ { row: 3, col: 13 },
95
+ { row: 4, col: 1 },
96
+ { row: 4, col: 9 },
97
+ { row: 4, col: 10 }
98
+ ],
99
+ [
100
+ { row: 0, col: 0 },
101
+ { row: 0, col: 1 },
102
+ { row: 0, col: 13 },
103
+ { row: 0, col: 14 },
104
+ { row: 1, col: 0 },
105
+ { row: 1, col: 13 },
106
+ { row: 1, col: 14 },
107
+ { row: 2, col: 13 },
108
+ { row: 2, col: 14 },
109
+ { row: 3, col: 14 },
110
+ { row: 4, col: 0 },
111
+ { row: 4, col: 11 },
112
+ { row: 4, col: 12 },
113
+ { row: 4, col: 13 },
114
+ { row: 4, col: 14 }
115
+ ]
116
+ ], Ro = [
117
+ [{ row: 2, col: 8 }],
118
+ [
119
+ { row: 1, col: 8 },
120
+ { row: 1, col: 9 },
121
+ { row: 2, col: 7 },
122
+ { row: 2, col: 9 },
123
+ { row: 3, col: 7 },
124
+ { row: 3, col: 8 }
125
+ ],
126
+ [
127
+ { row: 0, col: 7 },
128
+ { row: 0, col: 8 },
129
+ { row: 0, col: 9 },
130
+ { row: 1, col: 7 },
131
+ { row: 1, col: 10 },
132
+ { row: 2, col: 6 },
133
+ { row: 2, col: 10 },
134
+ { row: 3, col: 6 },
135
+ { row: 3, col: 9 },
136
+ { row: 4, col: 7 },
137
+ { row: 4, col: 8 },
138
+ { row: 4, col: 9 }
139
+ ],
140
+ [
141
+ { row: 0, col: 6 },
142
+ { row: 1, col: 6 },
143
+ { row: 1, col: 11 },
144
+ { row: 2, col: 5 },
145
+ { row: 2, col: 11 },
146
+ { row: 3, col: 5 },
147
+ { row: 3, col: 10 },
148
+ { row: 4, col: 10 },
149
+ { row: 4, col: 6 }
150
+ ],
151
+ [
152
+ { row: 1, col: 5 },
153
+ { row: 2, col: 4 },
154
+ { row: 3, col: 4 },
155
+ { row: 4, col: 5 },
156
+ { row: 5, col: 4 },
157
+ // 空格偏移空位
158
+ { row: 5, col: 5 },
159
+ // 空格偏移空位
160
+ { row: 5, col: 6 },
161
+ { row: 5, col: 7 },
162
+ // 空格偏移空位
163
+ { row: 5, col: 8 },
164
+ // 空格偏移空位
165
+ { row: 5, col: 9 },
166
+ // 空格偏移空位
167
+ { row: 0, col: 10 },
168
+ { row: 1, col: 12 },
169
+ { row: 2, col: 12 },
170
+ { row: 3, col: 11 },
171
+ { row: 4, col: 11 },
172
+ { row: 5, col: 10 }
173
+ ],
174
+ [
175
+ { row: 0, col: 5 },
176
+ { row: 1, col: 4 },
177
+ { row: 2, col: 3 },
178
+ { row: 3, col: 3 },
179
+ { row: 4, col: 4 },
180
+ { row: 0, col: 11 },
181
+ { row: 1, col: 13 },
182
+ { row: 2, col: 13 },
183
+ { row: 3, col: 12 },
184
+ { row: 5, col: 3 },
185
+ // 第六行第四个位置预留
186
+ { row: 5, col: 11 }
187
+ ],
188
+ [
189
+ { row: 0, col: 4 },
190
+ { row: 1, col: 3 },
191
+ { row: 2, col: 2 },
192
+ { row: 3, col: 2 },
193
+ { row: 3, col: 13 },
194
+ // 扩展第四行 +1 位置
195
+ { row: 4, col: 3 },
196
+ { row: 0, col: 12 },
197
+ { row: 0, col: 13 },
198
+ { row: 5, col: 12 },
199
+ { row: 5, col: 13 },
200
+ { row: 4, col: 12 },
201
+ { row: 4, col: 13 }
202
+ // 适配右 shift 偏移
203
+ ],
204
+ [
205
+ { row: 0, col: 3 },
206
+ { row: 1, col: 2 },
207
+ { row: 2, col: 1 },
208
+ { row: 3, col: 1 },
209
+ { row: 3, col: 14 },
210
+ // 扩展第四行 +2 位置
211
+ { row: 4, col: 2 },
212
+ { row: 4, col: 14 },
213
+ // 右 shift 和 ↑ 之间的空位
214
+ { row: 0, col: 14 },
215
+ { row: 1, col: 14 },
216
+ { row: 2, col: 14 },
217
+ { row: 5, col: 2 },
218
+ { row: 5, col: 14 }
219
+ ],
220
+ [
221
+ { row: 0, col: 2 },
222
+ { row: 1, col: 1 },
223
+ { row: 2, col: 0 },
224
+ { row: 3, col: 0 },
225
+ { row: 3, col: 15 },
226
+ // 扩展第四行 +3 位置
227
+ { row: 4, col: 0 },
228
+ { row: 4, col: 1 },
229
+ // 适配 Z 不偏移
230
+ { row: 5, col: 1 },
231
+ { row: 0, col: 15 },
232
+ { row: 1, col: 15 },
233
+ { row: 2, col: 15 },
234
+ { row: 4, col: 15 },
235
+ { row: 5, col: 15 }
236
+ ],
237
+ [
238
+ { row: 0, col: 0 },
239
+ { row: 1, col: 0 },
240
+ { row: 0, col: 1 },
241
+ // 适配 F1 不偏移
242
+ { row: 0, col: 16 },
243
+ { row: 1, col: 16 },
244
+ { row: 2, col: 16 },
245
+ { row: 3, col: 16 },
246
+ // 扩展第四行 +4 位置
247
+ { row: 4, col: 16 },
248
+ // 第五行最后一个位置预留
249
+ { row: 5, col: 0 },
250
+ { row: 5, col: 16 }
251
+ ]
252
+ ], Ao = [
253
+ [{ row: 2, col: 9 }],
254
+ [
255
+ { row: 1, col: 9 },
256
+ { row: 1, col: 10 },
257
+ { row: 2, col: 8 },
258
+ { row: 2, col: 10 },
259
+ { row: 3, col: 8 },
260
+ { row: 3, col: 9 }
261
+ ],
262
+ [
263
+ { row: 0, col: 8 },
264
+ { row: 0, col: 9 },
265
+ { row: 0, col: 10 },
266
+ { row: 1, col: 8 },
267
+ { row: 1, col: 11 },
268
+ { row: 2, col: 7 },
269
+ { row: 2, col: 11 },
270
+ { row: 3, col: 7 },
271
+ { row: 3, col: 10 },
272
+ { row: 4, col: 8 },
273
+ { row: 4, col: 9 },
274
+ { row: 4, col: 10 }
275
+ ],
276
+ [
277
+ { row: 0, col: 7 },
278
+ { row: 1, col: 7 },
279
+ { row: 1, col: 12 },
280
+ { row: 2, col: 6 },
281
+ { row: 2, col: 12 },
282
+ { row: 3, col: 6 },
283
+ { row: 3, col: 11 },
284
+ { row: 4, col: 11 },
285
+ { row: 4, col: 7 }
286
+ ],
287
+ [
288
+ { row: 0, col: 6 },
289
+ { row: 1, col: 6 },
290
+ { row: 2, col: 5 },
291
+ { row: 3, col: 5 },
292
+ { row: 4, col: 6 },
293
+ { row: 5, col: 5 },
294
+ { row: 5, col: 6 },
295
+ { row: 5, col: 7 },
296
+ { row: 5, col: 8 },
297
+ { row: 5, col: 9 },
298
+ { row: 5, col: 10 },
299
+ { row: 0, col: 11 },
300
+ { row: 1, col: 13 },
301
+ { row: 2, col: 13 },
302
+ { row: 3, col: 12 },
303
+ { row: 4, col: 12 },
304
+ { row: 5, col: 11 }
305
+ ],
306
+ [
307
+ { row: 1, col: 5 },
308
+ { row: 2, col: 4 },
309
+ { row: 3, col: 4 },
310
+ { row: 4, col: 5 },
311
+ { row: 0, col: 12 },
312
+ { row: 0, col: 13 },
313
+ { row: 4, col: 13 },
314
+ { row: 1, col: 14 },
315
+ { row: 2, col: 14 },
316
+ { row: 3, col: 13 },
317
+ { row: 5, col: 4 },
318
+ { row: 5, col: 12 },
319
+ { row: 5, col: 13 }
320
+ ],
321
+ [
322
+ { row: 0, col: 5 },
323
+ { row: 1, col: 4 },
324
+ { row: 2, col: 3 },
325
+ { row: 3, col: 3 },
326
+ { row: 3, col: 14 },
327
+ { row: 4, col: 4 },
328
+ { row: 0, col: 14 },
329
+ { row: 0, col: 15 },
330
+ { row: 1, col: 15 },
331
+ { row: 2, col: 15 },
332
+ { row: 5, col: 3 },
333
+ { row: 5, col: 14 },
334
+ { row: 4, col: 14 }
335
+ ],
336
+ [
337
+ { row: 0, col: 4 },
338
+ { row: 1, col: 3 },
339
+ { row: 2, col: 2 },
340
+ { row: 3, col: 2 },
341
+ { row: 3, col: 15 },
342
+ { row: 4, col: 3 },
343
+ { row: 4, col: 15 },
344
+ { row: 5, col: 15 },
345
+ { row: 0, col: 16 },
346
+ { row: 1, col: 16 },
347
+ { row: 2, col: 16 }
348
+ ],
349
+ [
350
+ { row: 0, col: 3 },
351
+ { row: 1, col: 2 },
352
+ { row: 2, col: 1 },
353
+ { row: 3, col: 1 },
354
+ { row: 3, col: 16 },
355
+ { row: 4, col: 2 },
356
+ { row: 5, col: 2 },
357
+ { row: 4, col: 16 },
358
+ { row: 5, col: 16 },
359
+ { row: 0, col: 17 },
360
+ { row: 1, col: 17 },
361
+ { row: 2, col: 17 }
362
+ ],
363
+ [
364
+ { row: 2, col: 0 },
365
+ { row: 3, col: 0 },
366
+ { row: 0, col: 1 },
367
+ { row: 1, col: 1 },
368
+ { row: 0, col: 2 },
369
+ { row: 3, col: 17 },
370
+ { row: 4, col: 17 },
371
+ { row: 5, col: 17 },
372
+ { row: 0, col: 18 },
373
+ { row: 1, col: 18 },
374
+ { row: 2, col: 18 },
375
+ { row: 5, col: 18 }
376
+ ],
377
+ [
378
+ { row: 1, col: 0 },
379
+ { row: 4, col: 0 },
380
+ { row: 4, col: 1 },
381
+ { row: 5, col: 1 },
382
+ { row: 3, col: 18 },
383
+ { row: 4, col: 18 },
384
+ { row: 0, col: 19 },
385
+ { row: 1, col: 19 },
386
+ { row: 2, col: 19 },
387
+ { row: 5, col: 19 }
388
+ ],
389
+ [
390
+ { row: 0, col: 0 },
391
+ { row: 3, col: 19 },
392
+ { row: 4, col: 19 },
393
+ { row: 5, col: 19 },
394
+ { row: 5, col: 0 },
395
+ { row: 0, col: 20 },
396
+ { row: 1, col: 20 },
397
+ { row: 2, col: 20 }
398
+ ]
399
+ ];
400
+ function Oo(e) {
401
+ if (e)
402
+ return e === "ring_68" ? vo : e === "ring_87" ? Ro : e === "ring_108" ? Ao : e;
403
+ }
404
+ function x(e, o, l) {
405
+ const t = [];
406
+ for (let s = o; s <= l; s++)
407
+ t.push({ row: e, col: s });
408
+ return t;
409
+ }
410
+ const Eo = {
411
+ left: [x(4, 0, 2), x(3, 0, 2), x(2, 0, 1), x(1, 0, 1), x(0, 0, 1)],
412
+ middle: [x(4, 3, 8), x(3, 4, 10), x(2, 4, 9), x(1, 6, 8), x(0, 7, 8)],
413
+ right: [x(4, 9, 14), x(3, 12, 14), x(2, 12, 14), x(1, 13, 14), x(0, 14, 14)]
414
+ }, So = {
415
+ left: [x(5, 0, 2), x(4, 0, 2), x(3, 0, 1), x(2, 0, 1), x(1, 0, 1), x(0, 0, 0)],
416
+ middle: [x(5, 3, 12), x(4, 4, 11), x(3, 4, 10), x(2, 5, 9), x(1, 6, 9), x(0, 6, 8)],
417
+ right: [x(5, 13, 16), x(4, 14, 16), x(3, 13, 16), x(2, 14, 16), x(1, 15, 16), x(0, 16, 16)]
418
+ }, Lo = {
419
+ left: [x(5, 0, 2), x(4, 0, 2), x(3, 0, 1), x(2, 0, 1), x(1, 0, 1), x(0, 0, 0)],
420
+ middle: [x(5, 3, 12), x(4, 4, 11), x(3, 4, 10), x(2, 5, 9), x(1, 6, 9), x(0, 6, 8)],
421
+ right: [x(5, 13, 16), x(4, 14, 16), x(3, 14, 16), x(2, 14, 16), x(1, 15, 16), x(0, 16, 16)]
422
+ }, Io = {
423
+ left: [x(5, 0, 2), x(4, 0, 2), x(3, 0, 1), x(2, 0, 1), x(1, 0, 1), x(0, 0, 0)],
424
+ middle: [x(5, 3, 14), x(4, 4, 13), x(3, 4, 12), x(2, 5, 12), x(1, 8, 11), x(0, 9, 9)],
425
+ right: [x(5, 15, 18), x(4, 15, 18), x(3, 15, 18), x(2, 17, 18), x(1, 18, 18), x(0, 18, 18)]
426
+ };
427
+ function _o(e) {
428
+ if (e)
429
+ return e === "volcano_64" ? Eo : e === "volcano_84_iso" ? So : e === "volcano_87" ? Lo : e === "volcano_98" ? Io : e;
430
+ }
431
+ class Po {
432
+ constructor(o) {
433
+ // 绘画状态(对应 web 端 composable 中的 ref)
434
+ D(this, "bgStep", 0);
435
+ // 背景步进值,用于色相偏移
436
+ D(this, "pulseOffset", 0);
437
+ // 脉冲偏移
438
+ D(this, "pulseSpeed", 5e-3);
439
+ // 脉冲速度
440
+ D(this, "colorCycleOffset", 0);
441
+ // 颜色循环偏移
442
+ D(this, "smoothedActiveRings", 0);
443
+ // 平滑活跃环数
444
+ D(this, "smoothedAmplitude", 0);
445
+ // 平滑振幅
446
+ D(this, "bgSpeed", 0);
447
+ // 背景速度
448
+ D(this, "lastMaxHeight", 0);
449
+ D(this, "diffHeight", 0);
450
+ D(this, "tidalOffset", 0);
451
+ D(this, "smoothingFactor", 0.2);
452
+ // 当前帧参数
453
+ D(this, "params", {
454
+ mode: 13,
455
+ amplitude: 50,
456
+ backMode: 0,
457
+ backBrightness: 100,
458
+ currentAmplitude: 0
459
+ });
460
+ this.keyboardConfig = o;
461
+ }
462
+ /** 键盘行数 */
463
+ get keyboardRows() {
464
+ return this.keyboardConfig.keyList.length;
465
+ }
466
+ /** 键盘最大列数值(含最大列偏移) */
467
+ get keyboardMaxCols() {
468
+ const { keyList: o, musicConfig: l } = this.keyboardConfig;
469
+ return o.reduce((s, i) => Math.max(s, i.length), 0) + ((l == null ? void 0 : l.maxColOffset) || 0);
470
+ }
471
+ /** 中心点 Y */
472
+ get centerY() {
473
+ const o = this.keyboardRows;
474
+ return o % 2 === 0 ? o / 2 - 1 : Math.floor(o / 2);
475
+ }
476
+ /** 中心点 X */
477
+ get centerX() {
478
+ var l;
479
+ const o = ((l = this.keyboardConfig.keyList[this.centerY]) == null ? void 0 : l.length) ?? 0;
480
+ return o % 2 === 0 ? o / 2 - 1 : Math.floor(o / 2);
481
+ }
482
+ /** 按键总数 */
483
+ get keyCount() {
484
+ return this.keyboardConfig.keyList.reduce((o, l) => o + l.length, 0);
485
+ }
486
+ /**
487
+ * 渲染一帧按键 RGB 网格
488
+ * @param params 当前帧参数
489
+ * @returns 按键 RGB 网格 [row][col]
490
+ */
491
+ render(o) {
492
+ this.params = o, this.bgStep >= 360 && (this.bgStep = 0), this.bgStep += 10;
493
+ const l = o.currentAmplitude > 0, t = bo(this.keyboardConfig);
494
+ if (o.backMode && this.fillModeColor(t, o.backMode), !l)
495
+ return t;
496
+ switch (o.mode) {
497
+ // 绿色/黄色/红色
498
+ case 1:
499
+ // 色谱
500
+ case 4:
501
+ this.visualizerBottomToTop(t, o.mode);
502
+ break;
503
+ // 随曲起舞
504
+ case 13:
505
+ this.visualizerDance(t);
506
+ break;
507
+ // 尘埃光漩(旋转线条)
508
+ case 14:
509
+ this.visualizerRotatingLines(t);
510
+ break;
511
+ // 蛰伏火山(山)
512
+ case 15:
513
+ this.visualizerMountains(t);
514
+ break;
515
+ // 光矢穿心(爱心)
516
+ case 16:
517
+ this.visualizerHeart(t);
518
+ break;
519
+ // 萤火轨迹(线性波动)
520
+ case 17:
521
+ this.visualizerLinearWave(t);
522
+ break;
523
+ // 光茧共振
524
+ case 18:
525
+ this.visualizerAfternoonSunlight(t);
526
+ break;
527
+ // 音叉振空(潮汐共振)
528
+ case 19:
529
+ this.visualizerTidalResonance(t);
530
+ break;
531
+ // 曲率遗轨(线性波动缩短)
532
+ case 20:
533
+ this.visualizerLinearWaveShortened(t);
534
+ break;
535
+ // 行波律动
536
+ case 21:
537
+ this.visualizerRowWaveRhythm(t);
538
+ break;
539
+ // 双心共舞
540
+ case 22:
541
+ this.visualizerDualCenterDance(t);
542
+ break;
543
+ }
544
+ return t;
545
+ }
546
+ /** 根据模式填充背景颜色 */
547
+ fillModeColor(o, l, t) {
548
+ switch (l) {
549
+ // 白色
550
+ case 6:
551
+ this.drawSolidColor(o, { r: 255, g: 255, b: 255 });
552
+ break;
553
+ // 红色
554
+ case 7:
555
+ this.drawSolidColor(o, { r: 255, g: 0, b: 0 });
556
+ break;
557
+ // 橙色
558
+ case 8:
559
+ this.drawSolidColor(o, { r: 255, g: 64, b: 0 });
560
+ break;
561
+ // 黄色
562
+ case 9:
563
+ this.drawSolidColor(o, { r: 255, g: 255, b: 0 });
564
+ break;
565
+ // 蓝色
566
+ case 10:
567
+ this.drawSolidColor(o, { r: 0, g: 0, b: 255 });
568
+ break;
569
+ // 绿色
570
+ case 11:
571
+ this.drawSolidColor(o, { r: 0, g: 255, b: 0 });
572
+ break;
573
+ // 绿色/黄色/红色
574
+ case 1:
575
+ this.drawMultiRowColors(o, [
576
+ { r: 0, g: 255, b: 0 },
577
+ { r: 255, g: 255, b: 0 },
578
+ { r: 255, g: 0, b: 0 }
579
+ ]);
580
+ break;
581
+ // 彩虹色
582
+ case 2:
583
+ this.drawMultiRowColors(o, [
584
+ { r: 255, g: 0, b: 255 },
585
+ { r: 0, g: 0, b: 255 },
586
+ { r: 0, g: 255, b: 255 },
587
+ { r: 0, g: 255, b: 0 },
588
+ { r: 255, g: 255, b: 0 },
589
+ { r: 255, g: 0, b: 0 }
590
+ ]);
591
+ break;
592
+ // 色谱
593
+ case 4:
594
+ this.drawColorWheel(o, t);
595
+ break;
596
+ // 频谱循环
597
+ case 5:
598
+ this.drawSpectrumCycle(o);
599
+ break;
600
+ }
601
+ }
602
+ /** 填充单色 */
603
+ drawSolidColor(o, l) {
604
+ const t = Math.round(this.params.backBrightness * 2.55);
605
+ o.forEach((s) => {
606
+ const i = Math.round(t * l.r / 256), f = Math.round(t * l.g / 256), n = Math.round(t * l.b / 256);
607
+ for (let m = 0; m < s.length; m++)
608
+ s[m] = { r: i, g: f, b: n };
609
+ });
610
+ }
611
+ /** 填充色谱 */
612
+ drawColorWheel(o, l) {
613
+ const t = Math.round(this.params.backBrightness * 2.55);
614
+ for (let s = 0; s < this.keyboardRows; s++)
615
+ for (let i = 0; i < this.keyboardMaxCols; i++)
616
+ if (o[s] && o[s][i] !== void 0) {
617
+ const f = Math.atan2(s - this.centerY, i - this.centerX);
618
+ let n = this.bgStep + (180 + f * (180 / Math.PI)) % 360;
619
+ n < 0 && (n += 360), n >= 360 && (n -= 360);
620
+ const m = P(n, 1, l || t / 255);
621
+ o[s][i] = { r: m.r, g: m.g, b: m.b };
622
+ }
623
+ }
624
+ /** 填充频谱循环 */
625
+ drawSpectrumCycle(o) {
626
+ const l = Math.round(this.params.backBrightness * 2.55), t = P(Math.round(this.bgStep) % 360, 1, l / 255);
627
+ for (let s = 0; s < this.keyboardRows; s++)
628
+ for (let i = 0; i < this.keyboardMaxCols; i++)
629
+ o[s] && o[s][i] !== void 0 && (o[s][i] = { r: t.r, g: t.g, b: t.b });
630
+ }
631
+ /** 填充多行颜色 */
632
+ drawMultiRowColors(o, l) {
633
+ if (!l || !Array.isArray(l) || l.length === 0) {
634
+ console.warn("颜色数组不能为空");
635
+ return;
636
+ }
637
+ const t = Math.round(this.params.backBrightness * (255 / 100)), s = l.length, i = Math.floor(this.keyboardRows / s), f = this.keyboardRows % s;
638
+ let n = 0;
639
+ for (let m = 0; m < s; m++) {
640
+ const u = l[m], w = i + (m < f ? 1 : 0), b = Math.round(t * u.r / 256), C = Math.round(t * u.g / 256), c = Math.round(t * u.b / 256);
641
+ for (let g = 0; g < w && n < this.keyboardRows; g++) {
642
+ for (let k = 0; k < this.keyboardMaxCols; k++)
643
+ o[n] && o[n][k] !== void 0 && (o[n][k] = { r: b, g: C, b: c });
644
+ n++;
645
+ }
646
+ }
647
+ }
648
+ /** 随曲起舞 */
649
+ visualizerDance(o) {
650
+ var g, k;
651
+ const l = Oo((g = this.keyboardConfig.musicConfig) == null ? void 0 : g.ringKeyPositions), t = [];
652
+ let s = null, i = 0;
653
+ if (l && l.length > 1)
654
+ s = l[0][0] ?? null, l.slice(1).forEach((y) => {
655
+ t.push(y.map((r) => ({ ...r })));
656
+ }), i = t.length;
657
+ else {
658
+ let y = 0;
659
+ for (let r = 0; r < this.keyboardRows; r++)
660
+ for (let a = 0; a < this.keyboardMaxCols; a++) {
661
+ const d = a - this.centerX, h = r - this.centerY, M = Math.sqrt(d * d + h * h);
662
+ M > y && (y = M);
663
+ }
664
+ i = Math.max(4, Math.ceil(y));
665
+ for (let r = 0; r < i; r++)
666
+ t[r] = [];
667
+ for (let r = 0; r < this.keyboardRows; r++) {
668
+ let a = 0;
669
+ for (let d = 0; d < this.keyboardMaxCols; d++) {
670
+ const h = d - this.centerX + a, M = r - this.centerY, v = Math.sqrt(h * h + M * M), R = Math.floor(v / y * (i - 0.01));
671
+ R === 0 && Math.abs(h) < 0.5 && Math.abs(M) < 0.5 || R >= 0 && R < i && t[R].push({ row: r, col: d + a });
672
+ }
673
+ }
674
+ if (t[1] && t[1].length > 2 && t[2]) {
675
+ const r = t[1].shift();
676
+ let a = null;
677
+ this.keyboardRows < 6 ? (a = t[1][4], t[1].splice(4, 1)) : a = t[1].pop(), r && t[2].push(r), a && t[2].push(a);
678
+ }
679
+ }
680
+ this.pulseOffset += this.pulseSpeed, this.pulseOffset >= 1 && (this.pulseOffset = 0);
681
+ const f = 5e-3;
682
+ this.colorCycleOffset += f, this.colorCycleOffset >= 1 && (this.colorCycleOffset = 0);
683
+ const n = [];
684
+ for (let y = 0; y < i; y++)
685
+ n[y] = (this.pulseOffset - y / i + 1) % 1;
686
+ const m = Math.min(this.params.currentAmplitude, 1), u = Math.max(0.01, 0.06 - m * 0.05);
687
+ let w;
688
+ m < u ? w = 0 : w = Math.max(
689
+ 1,
690
+ // 最少 1 个圆环
691
+ Math.min(i, Math.round(this.params.currentAmplitude * i))
692
+ );
693
+ const b = this.params.amplitude / 100;
694
+ this.smoothedActiveRings = this.smoothedActiveRings + (w - this.smoothedActiveRings) * b;
695
+ const C = Math.round(this.smoothedActiveRings), c = s ?? { row: this.centerY, col: this.centerX };
696
+ if (c.col >= 0 && c.col < this.keyboardMaxCols && c.row >= 0 && c.row < this.keyboardRows) {
697
+ const y = this.colorCycleOffset * 360 % 360, r = P(y, 1, 1);
698
+ o[c.row][c.col] = r;
699
+ }
700
+ for (let y = 0; y < C; y++) {
701
+ if (!((k = t[y]) != null && k.length)) continue;
702
+ const a = (n[y] + this.colorCycleOffset) * 360 % 360, h = P(a, 1, 1);
703
+ for (const M of t[y]) {
704
+ const { row: v, col: R } = M;
705
+ R >= 0 && R < this.keyboardMaxCols && v >= 0 && v < this.keyboardRows && (o[v][R] = h);
706
+ }
707
+ }
708
+ }
709
+ /** 双心共舞 */
710
+ visualizerDualCenterDance(o) {
711
+ const l = this.keyCount;
712
+ let t = [], s = [];
713
+ this.keyboardRows >= 7 ? (t = [
714
+ [{ x: 3, y: 3 }],
715
+ [{ x: 3, y: 2 }, { x: 4, y: 2 }, { x: 2, y: 3 }, { x: 4, y: 3 }, { x: 2, y: 4 }, { x: 3, y: 4 }],
716
+ [{ x: 2, y: 1 }, { x: 3, y: 1 }, { x: 4, y: 1 }, { x: 5, y: 1 }, { x: 1, y: 2 }, { x: 5, y: 2 }, { x: 1, y: 3 }, { x: 5, y: 3 }, { x: 1, y: 5 }, { x: 2, y: 5 }, { x: 3, y: 5 }, { x: 4, y: 5 }, { x: 5, y: 5 }, { x: 2, y: 2 }, { x: 4, y: 4 }],
717
+ [{ x: 0, y: 0 }, { x: 1, y: 0 }, { x: 2, y: 0 }, { x: 3, y: 0 }, { x: 4, y: 0 }, { x: 6, y: 1 }, { x: 0, y: 2 }, { x: 6, y: 2 }, { x: 0, y: 3 }, { x: 6, y: 3 }, { x: 0, y: 4 }, { x: 6, y: 4 }, { x: 0, y: 5 }, { x: 6, y: 5 }, { x: 1, y: 6 }, { x: 2, y: 6 }, { x: 3, y: 6 }, { x: 4, y: 6 }, { x: 5, y: 6 }, { x: 5, y: 4 }, { x: 1, y: 4 }, { x: 1, y: 1 }],
718
+ [{ x: 5, y: 0 }, { x: 7, y: 1 }, { x: 7, y: 2 }, { x: 7, y: 3 }, { x: 7, y: 4 }, { x: 7, y: 5 }, { x: 0, y: 6 }, { x: 6, y: 6 }],
719
+ [{ x: 6, y: 0 }, { x: 7, y: 6 }, { x: 0, y: 1 }]
720
+ ], s = [
721
+ [{ x: 11, y: 3 }],
722
+ [{ x: 11, y: 2 }, { x: 12, y: 2 }, { x: 10, y: 3 }, { x: 12, y: 3 }, { x: 10, y: 4 }, { x: 11, y: 4 }],
723
+ [{ x: 10, y: 1 }, { x: 11, y: 1 }, { x: 12, y: 1 }, { x: 13, y: 1 }, { x: 9, y: 2 }, { x: 13, y: 2 }, { x: 9, y: 3 }, { x: 13, y: 3 }, { x: 9, y: 5 }, { x: 10, y: 5 }, { x: 11, y: 5 }, { x: 12, y: 5 }, { x: 13, y: 5 }, { x: 10, y: 2 }, { x: 12, y: 4 }],
724
+ [{ x: 8, y: 0 }, { x: 9, y: 0 }, { x: 10, y: 0 }, { x: 11, y: 0 }, { x: 12, y: 0 }, { x: 14, y: 1 }, { x: 8, y: 2 }, { x: 14, y: 2 }, { x: 8, y: 3 }, { x: 14, y: 3 }, { x: 8, y: 4 }, { x: 14, y: 4 }, { x: 8, y: 5 }, { x: 14, y: 5 }, { x: 9, y: 6 }, { x: 10, y: 6 }, { x: 11, y: 6 }, { x: 12, y: 6 }, { x: 13, y: 6 }, { x: 13, y: 4 }, { x: 9, y: 4 }, { x: 9, y: 1 }],
725
+ [{ x: 7, y: 0 }, { x: 13, y: 0 }, { x: 15, y: 1 }, { x: 15, y: 2 }, { x: 15, y: 3 }, { x: 15, y: 4 }, { x: 15, y: 5 }, { x: 8, y: 6 }, { x: 14, y: 6 }],
726
+ [{ x: 14, y: 0 }, { x: 15, y: 0 }, { x: 16, y: 1 }, { x: 16, y: 2 }, { x: 16, y: 3 }, { x: 16, y: 4 }, { x: 16, y: 5 }, { x: 15, y: 6 }, { x: 16, y: 6 }, { x: 8, y: 1 }]
727
+ ]) : l > 102 ? (t = [
728
+ [{ x: 4, y: 2 }],
729
+ [{ x: 4, y: 1 }, { x: 5, y: 1 }, { x: 3, y: 2 }, { x: 5, y: 2 }, { x: 3, y: 3 }, { x: 4, y: 3 }],
730
+ [{ x: 4, y: 0 }, { x: 5, y: 0 }, { x: 3, y: 1 }, { x: 6, y: 1 }, { x: 2, y: 2 }, { x: 6, y: 2 }, { x: 2, y: 3 }, { x: 5, y: 3 }, { x: 3, y: 4 }, { x: 4, y: 4 }, { x: 5, y: 4 }],
731
+ [{ x: 3, y: 0 }, { x: 6, y: 0 }, { x: 2, y: 1 }, { x: 7, y: 1 }, { x: 1, y: 2 }, { x: 7, y: 2 }, { x: 1, y: 3 }, { x: 6, y: 3 }, { x: 2, y: 4 }, { x: 6, y: 4 }, { x: 3, y: 5 }, { x: 4, y: 5 }, { x: 5, y: 5 }, { x: 6, y: 5 }, { x: 7, y: 5 }, { x: 8, y: 5 }, { x: 9, y: 5 }],
732
+ [{ x: 2, y: 0 }, { x: 7, y: 0 }, { x: 1, y: 1 }, { x: 8, y: 1 }, { x: 0, y: 2 }, { x: 8, y: 2 }, { x: 0, y: 3 }, { x: 7, y: 3 }, { x: 0, y: 4 }, { x: 1, y: 4 }, { x: 7, y: 4 }, { x: 1, y: 5 }, { x: 2, y: 5 }],
733
+ [{ x: 0, y: 0 }, { x: 1, y: 0 }, { x: 8, y: 0 }, { x: 9, y: 0 }, { x: 0, y: 1 }, { x: 9, y: 1 }, { x: 9, y: 2 }, { x: 8, y: 3 }, { x: 8, y: 4 }, { x: 0, y: 5 }],
734
+ [{ x: 9, y: 0 }, { x: 9, y: 4 }]
735
+ ], s = [
736
+ [{ x: 15, y: 2 }],
737
+ [{ x: 15, y: 1 }, { x: 14, y: 2 }, { x: 16, y: 2 }, { x: 14, y: 3 }, { x: 15, y: 3 }],
738
+ [{ x: 15, y: 0 }, { x: 14, y: 1 }, { x: 16, y: 1 }, { x: 13, y: 2 }, { x: 17, y: 2 }, { x: 12, y: 3 }, { x: 13, y: 3 }, { x: 16, y: 3 }, { x: 14, y: 4 }, { x: 15, y: 4 }, { x: 16, y: 4 }],
739
+ [{ x: 14, y: 0 }, { x: 16, y: 0 }, { x: 13, y: 1 }, { x: 17, y: 1 }, { x: 12, y: 2 }, { x: 18, y: 2 }, { x: 11, y: 3 }, { x: 17, y: 3 }, { x: 12, y: 4 }, { x: 13, y: 4 }, { x: 17, y: 4 }, { x: 18, y: 4 }, { x: 13, y: 5 }, { x: 14, y: 5 }, { x: 15, y: 5 }, { x: 16, y: 5 }, { x: 17, y: 5 }, { x: 18, y: 5 }],
740
+ [{ x: 12, y: 0 }, { x: 13, y: 0 }, { x: 17, y: 0 }, { x: 12, y: 1 }, { x: 18, y: 1 }, { x: 11, y: 2 }, { x: 19, y: 2 }, { x: 10, y: 3 }, { x: 18, y: 3 }, { x: 11, y: 4 }, { x: 19, y: 4 }, { x: 11, y: 5 }, { x: 12, y: 5 }, { x: 19, y: 5 }],
741
+ [{ x: 11, y: 0 }, { x: 18, y: 0 }, { x: 11, y: 1 }, { x: 19, y: 1 }, { x: 10, y: 2 }, { x: 20, y: 2 }, { x: 9, y: 3 }, { x: 19, y: 3 }, { x: 10, y: 4 }, { x: 20, y: 4 }, { x: 10, y: 5 }, { x: 20, y: 5 }],
742
+ [{ x: 10, y: 0 }, { x: 19, y: 0 }, { x: 20, y: 0 }, { x: 10, y: 1 }, { x: 20, y: 1 }, { x: 21, y: 1 }]
743
+ ]) : l > 90 ? (t = [
744
+ [{ x: 4, y: 2 }],
745
+ [{ x: 4, y: 1 }, { x: 5, y: 1 }, { x: 3, y: 2 }, { x: 5, y: 2 }, { x: 3, y: 3 }, { x: 4, y: 3 }],
746
+ [{ x: 4, y: 0 }, { x: 6, y: 1 }, { x: 2, y: 2 }, { x: 6, y: 2 }, { x: 2, y: 3 }, { x: 6, y: 3 }, { x: 4, y: 4 }, { x: 3, y: 1 }, { x: 5, y: 3 }],
747
+ [{ x: 2, y: 0 }, { x: 6, y: 0 }, { x: 7, y: 1 }, { x: 1, y: 2 }, { x: 7, y: 2 }, { x: 1, y: 3 }, { x: 7, y: 3 }, { x: 2, y: 4 }, { x: 6, y: 4 }, { x: 3, y: 5 }, { x: 4, y: 5 }, { x: 5, y: 5 }, { x: 5, y: 0 }, { x: 3, y: 0 }, { x: 5, y: 4 }, { x: 3, y: 4 }, { x: 2, y: 1 }],
748
+ [{ x: 1, y: 0 }, { x: 7, y: 0 }, { x: 8, y: 1 }, { x: 0, y: 2 }, { x: 8, y: 2 }, { x: 0, y: 3 }, { x: 8, y: 3 }, { x: 1, y: 4 }, { x: 7, y: 4 }, { x: 2, y: 5 }, { x: 6, y: 5 }, { x: 1, y: 1 }],
749
+ [{ x: 0, y: 0 }, { x: 8, y: 0 }, { x: 9, y: 2 }, { x: 0, y: 4 }, { x: 8, y: 4 }, { x: 0, y: 5 }, { x: 1, y: 5 }, { x: 7, y: 5 }, { x: 8, y: 5 }],
750
+ [{ x: 9, y: 0 }, { x: 9, y: 1 }, { x: 9, y: 3 }, { x: 9, y: 4 }, { x: 9, y: 5 }, { x: 0, y: 1 }]
751
+ ], s = [
752
+ [{ x: 14, y: 2 }],
753
+ [{ x: 14, y: 1 }, { x: 15, y: 1 }, { x: 13, y: 2 }, { x: 15, y: 2 }, { x: 13, y: 3 }, { x: 14, y: 3 }],
754
+ [{ x: 14, y: 0 }, { x: 16, y: 1 }, { x: 12, y: 2 }, { x: 16, y: 2 }, { x: 12, y: 3 }, { x: 16, y: 3 }, { x: 14, y: 4 }, { x: 13, y: 1 }, { x: 15, y: 3 }],
755
+ [{ x: 12, y: 0 }, { x: 16, y: 0 }, { x: 17, y: 1 }, { x: 11, y: 2 }, { x: 17, y: 2 }, { x: 11, y: 3 }, { x: 17, y: 3 }, { x: 12, y: 4 }, { x: 16, y: 4 }, { x: 13, y: 5 }, { x: 14, y: 5 }, { x: 15, y: 5 }, { x: 15, y: 0 }, { x: 13, y: 0 }, { x: 15, y: 4 }, { x: 13, y: 4 }, { x: 12, y: 1 }],
756
+ [{ x: 11, y: 0 }, { x: 17, y: 0 }, { x: 18, y: 1 }, { x: 10, y: 2 }, { x: 18, y: 2 }, { x: 10, y: 3 }, { x: 18, y: 3 }, { x: 11, y: 4 }, { x: 17, y: 4 }, { x: 12, y: 5 }, { x: 16, y: 5 }, { x: 11, y: 1 }],
757
+ [{ x: 10, y: 0 }, { x: 18, y: 0 }, { x: 10, y: 4 }, { x: 18, y: 4 }, { x: 10, y: 5 }, { x: 11, y: 5 }, { x: 17, y: 5 }, { x: 18, y: 5 }],
758
+ [{ x: 19, y: 0 }, { x: 20, y: 0 }, { x: 10, y: 1 }, { x: 19, y: 4 }, { x: 19, y: 5 }]
759
+ ]) : l > 75 ? (t = [
760
+ [{ x: 4, y: 2 }],
761
+ [{ x: 4, y: 1 }, { x: 5, y: 1 }, { x: 3, y: 2 }, { x: 5, y: 2 }, { x: 3, y: 3 }, { x: 4, y: 3 }],
762
+ [{ x: 4, y: 0 }, { x: 5, y: 0 }, { x: 3, y: 1 }, { x: 6, y: 1 }, { x: 2, y: 2 }, { x: 6, y: 2 }, { x: 2, y: 3 }, { x: 5, y: 3 }, { x: 6, y: 3 }, { x: 3, y: 4 }, { x: 4, y: 4 }, { x: 5, y: 4 }, { x: 6, y: 4 }],
763
+ [{ x: 3, y: 0 }, { x: 6, y: 0 }, { x: 2, y: 1 }, { x: 7, y: 1 }, { x: 1, y: 2 }, { x: 7, y: 2 }, { x: 1, y: 3 }, { x: 7, y: 3 }, { x: 2, y: 4 }, { x: 7, y: 4 }, { x: 2, y: 5 }, { x: 3, y: 5 }, { x: 4, y: 5 }, { x: 5, y: 5 }, { x: 6, y: 5 }, { x: 7, y: 5 }],
764
+ [{ x: 0, y: 0 }, { x: 1, y: 0 }, { x: 2, y: 0 }, { x: 7, y: 0 }, { x: 8, y: 0 }, { x: 0, y: 1 }, { x: 1, y: 1 }, { x: 8, y: 1 }, { x: 0, y: 2 }, { x: 8, y: 2 }, { x: 8, y: 2 }, { x: 0, y: 3 }, { x: 8, y: 3 }, { x: 0, y: 4 }, { x: 1, y: 4 }, { x: 8, y: 4 }, { x: 0, y: 5 }, { x: 1, y: 5 }, { x: 8, y: 5 }]
765
+ ], s = [
766
+ [{ x: 12, y: 2 }],
767
+ [{ x: 12, y: 1 }, { x: 13, y: 1 }, { x: 11, y: 2 }, { x: 13, y: 2 }, { x: 11, y: 3 }, { x: 12, y: 3 }],
768
+ [{ x: 11, y: 0 }, { x: 12, y: 0 }, { x: 13, y: 0 }, { x: 11, y: 1 }, { x: 14, y: 1 }, { x: 10, y: 2 }, { x: 14, y: 2 }, { x: 10, y: 3 }, { x: 13, y: 3 }, { x: 14, y: 3 }, { x: 11, y: 4 }, { x: 12, y: 4 }, { x: 13, y: 4 }],
769
+ [{ x: 10, y: 0 }, { x: 14, y: 0 }, { x: 10, y: 1 }, { x: 15, y: 1 }, { x: 9, y: 2 }, { x: 15, y: 2 }, { x: 9, y: 3 }, { x: 15, y: 3 }, { x: 10, y: 4 }, { x: 14, y: 4 }, { x: 15, y: 4 }, { x: 11, y: 5 }, { x: 12, y: 5 }, { x: 13, y: 5 }, { x: 14, y: 5 }],
770
+ [{ x: 9, y: 0 }, { x: 15, y: 0 }, { x: 16, y: 0 }, { x: 9, y: 1 }, { x: 16, y: 1 }, { x: 16, y: 2 }, { x: 16, y: 3 }, { x: 9, y: 4 }, { x: 16, y: 4 }, { x: 9, y: 5 }, { x: 10, y: 5 }, { x: 15, y: 5 }, { x: 16, y: 5 }]
771
+ ]) : (t = [
772
+ [{ x: 3, y: 2 }],
773
+ [{ x: 3, y: 1 }, { x: 4, y: 1 }, { x: 2, y: 2 }, { x: 4, y: 2 }, { x: 3, y: 3 }, { x: 4, y: 3 }],
774
+ [{ x: 3, y: 0 }, { x: 4, y: 0 }, { x: 2, y: 1 }, { x: 5, y: 1 }, { x: 1, y: 2 }, { x: 5, y: 2 }, { x: 2, y: 3 }, { x: 5, y: 3 }, { x: 4, y: 4 }, { x: 5, y: 4 }, { x: 6, y: 4 }],
775
+ [{ x: 2, y: 0 }, { x: 5, y: 0 }, { x: 1, y: 1 }, { x: 6, y: 1 }, { x: 0, y: 2 }, { x: 6, y: 2 }, { x: 0, y: 3 }, { x: 1, y: 3 }, { x: 6, y: 3 }, { x: 2, y: 4 }],
776
+ [{ x: 0, y: 0 }, { x: 1, y: 0 }, { x: 6, y: 0 }, { x: 0, y: 1 }, { x: 0, y: 4 }, { x: 1, y: 4 }]
777
+ ], s = [
778
+ [{ x: 9, y: 2 }],
779
+ [{ x: 9, y: 1 }, { x: 10, y: 1 }, { x: 8, y: 2 }, { x: 10, y: 2 }, { x: 9, y: 3 }, { x: 10, y: 3 }],
780
+ [{ x: 9, y: 0 }, { x: 10, y: 0 }, { x: 8, y: 1 }, { x: 11, y: 1 }, { x: 7, y: 2 }, { x: 11, y: 2 }, { x: 8, y: 3 }, { x: 11, y: 3 }, { x: 7, y: 4 }, { x: 8, y: 4 }, { x: 9, y: 4 }],
781
+ [{ x: 8, y: 0 }, { x: 11, y: 0 }, { x: 12, y: 0 }, { x: 7, y: 1 }, { x: 12, y: 1 }, { x: 12, y: 2 }, { x: 7, y: 3 }, { x: 12, y: 3 }, { x: 13, y: 3 }, { x: 7, y: 4 }, { x: 10, y: 4 }, { x: 11, y: 4 }],
782
+ [{ x: 7, y: 0 }, { x: 13, y: 0 }, { x: 14, y: 0 }, { x: 13, y: 1 }, { x: 14, y: 1 }, { x: 13, y: 2 }, { x: 14, y: 2 }, { x: 14, y: 3 }, { x: 12, y: 4 }, { x: 13, y: 4 }, { x: 14, y: 4 }, { x: 15, y: 4 }, { x: 15, y: 0 }, { x: 15, y: 1 }]
783
+ ]);
784
+ const i = Math.ceil((t.length + s.length) / 2);
785
+ this.pulseOffset += this.pulseSpeed, this.pulseOffset >= 1 && (this.pulseOffset = 0);
786
+ const f = 5e-3;
787
+ this.colorCycleOffset += f, this.colorCycleOffset >= 1 && (this.colorCycleOffset = 0);
788
+ const n = [];
789
+ for (let c = 0; c < i; c++)
790
+ n[c] = (this.pulseOffset - c / i + 1) % 1;
791
+ const m = Math.min(this.params.currentAmplitude, 1), u = Math.max(0.01, 0.06 - m * 0.05);
792
+ let w;
793
+ m < u ? w = 0 : w = Math.max(1, Math.min(i, Math.round(this.params.currentAmplitude * i)));
794
+ const b = this.params.amplitude / 100;
795
+ this.smoothedActiveRings = this.smoothedActiveRings + (w - this.smoothedActiveRings) * b;
796
+ const C = Math.ceil(this.smoothedActiveRings);
797
+ for (let c = 0; c < C; c++) {
798
+ if (!t[c]) continue;
799
+ const k = (n[c] + this.colorCycleOffset) * 360 % 360, r = P(k, 1, 1);
800
+ for (const a of t[c]) {
801
+ const d = a.x, h = a.y;
802
+ d >= 0 && d < this.keyboardMaxCols && h >= 0 && h < this.keyboardRows && (o[h][d] = r);
803
+ }
804
+ }
805
+ for (let c = 0; c < C; c++) {
806
+ if (!t[c]) continue;
807
+ const k = (n[c] + this.colorCycleOffset) * 360 % 360, r = P(k, 1, 1);
808
+ for (const a of s[c]) {
809
+ const d = a.x, h = a.y;
810
+ d >= 0 && d < this.keyboardMaxCols && h >= 0 && h < this.keyboardRows && (o[h][d] = r);
811
+ }
812
+ }
813
+ }
814
+ /** 尘埃光漩(旋转线条) */
815
+ visualizerRotatingLines(o) {
816
+ const l = this.params.amplitude / 100;
817
+ this.smoothedAmplitude += (this.params.currentAmplitude - this.smoothedAmplitude) * l, this.bgSpeed += 4, this.bgSpeed >= 360 && (this.bgSpeed = 0);
818
+ let t = 0;
819
+ for (let u = 0; u < this.keyboardRows; u++)
820
+ for (let w = 0; w < this.keyboardMaxCols; w++) {
821
+ const b = w - this.centerX, C = u - this.centerY, c = Math.sqrt(b * b + C * C);
822
+ c > t && (t = c);
823
+ }
824
+ const s = Math.min(this.smoothedAmplitude, 1), i = Math.max(
825
+ 1,
826
+ t * s
827
+ // 根据振幅动态调整长度
828
+ ), f = s, n = [
829
+ { r: 0, g: 255, b: 0 },
830
+ // 绿色
831
+ { r: 0, g: 0, b: 255 },
832
+ // 蓝色
833
+ { r: 255, g: 255, b: 0 },
834
+ // 黄色
835
+ { r: 255, g: 0, b: 0 }
836
+ // 红色
837
+ ], m = [0, 45, 90, 135];
838
+ for (let u = 0; u < 4; u++) {
839
+ const w = n[u], c = (m[u] + this.bgSpeed) % 360 * Math.PI / -180, g = Math.cos(c) * f * 2, k = Math.sin(c) * f * 1;
840
+ for (let y = -i; y <= i; y += 0.5) {
841
+ const r = Math.round(this.centerX + g * y), a = Math.round(this.centerY + k * y);
842
+ r >= 0 && r < this.keyboardMaxCols && a >= 0 && a < this.keyboardRows && (o[a][r] = w);
843
+ }
844
+ }
845
+ }
846
+ /** 蛰伏火山(山) */
847
+ visualizerMountains(o) {
848
+ var y;
849
+ this.colorCycleOffset = (this.colorCycleOffset + 0.01) % 1;
850
+ const l = this.colorCycleOffset * 360 % 360, t = Math.floor(this.keyboardMaxCols * 0.2), s = 1 + this.params.currentAmplitude * 1.5, i = [3, 3, 2, 2, 2, 1];
851
+ let f = [4, 3, 3, 3, 2, 1];
852
+ const n = this.keyCount;
853
+ n < 75 ? f = [4, 3, 3, 2, 1, 1] : n > 100 ? f = [5, 4, 4, 2, 1, 1] : n > 90 && (f = [4, 4, 4, 2, 1, 1]);
854
+ const m = Math.min(
855
+ Math.floor(t * s * 2),
856
+ Math.floor(this.keyboardMaxCols * 0.4)
857
+ ), u = 0, w = Math.floor(this.keyboardMaxCols / 2), b = this.keyboardMaxCols - 1, C = Math.min(
858
+ this.keyboardRows,
859
+ Math.floor((this.params.currentAmplitude * 1 + this.params.amplitude / 100 * 0.5) * this.keyboardRows)
860
+ );
861
+ let c = this.lastMaxHeight;
862
+ this.diffHeight > 0 ? (this.diffHeight -= 1, c = Math.min(this.keyboardRows, this.lastMaxHeight + 1), this.lastMaxHeight = c) : this.diffHeight < 0 ? (this.diffHeight += 1, c = Math.max(0, this.lastMaxHeight - 1), this.lastMaxHeight = c) : this.diffHeight = C - this.lastMaxHeight;
863
+ const g = _o((y = this.keyboardConfig.musicConfig) == null ? void 0 : y.volcanoKeyPositions);
864
+ if (g) {
865
+ const r = Math.min(c, this.keyboardRows);
866
+ [
867
+ { layers: g.left, color: P((l + 0) % 360, 1, 1) },
868
+ { layers: g.middle, color: P((l + 120) % 360, 1, 1) },
869
+ { layers: g.right, color: P((l + 240) % 360, 1, 1) }
870
+ ].forEach(({ layers: d, color: h }) => {
871
+ var v;
872
+ const M = Math.min(r, d.length);
873
+ for (let R = 0; R < M; R++)
874
+ (v = d[R]) == null || v.forEach(({ row: E, col: A }) => {
875
+ E >= 0 && E < this.keyboardRows && A >= 0 && A < this.keyboardMaxCols && (o[E][A] = h);
876
+ });
877
+ });
878
+ return;
879
+ }
880
+ [
881
+ {
882
+ peakX: u,
883
+ widths: i,
884
+ width: 0,
885
+ color: P((l + 0) % 360, 1, 1)
886
+ },
887
+ // 左山(基础 hue)
888
+ {
889
+ peakX: w,
890
+ widths: void 0,
891
+ width: m,
892
+ color: P((l + 120) % 360, 1, 1)
893
+ },
894
+ // 中山(hue + 120 度)
895
+ {
896
+ peakX: b,
897
+ widths: f,
898
+ width: 0,
899
+ color: P((l + 240) % 360, 1, 1)
900
+ }
901
+ // 右山(hue + 240 度)
902
+ ].forEach((r, a) => {
903
+ const d = Math.min(c, this.keyboardRows);
904
+ if (!(d <= 0))
905
+ if (a === 0)
906
+ for (let h = 0; h < d; h++) {
907
+ const M = this.keyboardRows - 1 - h;
908
+ if (M < 0) break;
909
+ const v = r.widths && r.widths[h] || 1, R = r.peakX, E = Math.min(this.keyboardMaxCols - 1, r.peakX + v - 1);
910
+ for (let A = R; A <= E; A++)
911
+ A >= 0 && A < this.keyboardMaxCols && M >= 0 && M < this.keyboardRows && (o[M][A] = r.color);
912
+ }
913
+ else if (a === 2)
914
+ for (let h = 0; h < d; h++) {
915
+ const M = this.keyboardRows - 1 - h;
916
+ if (M < 0) break;
917
+ const v = r.widths && r.widths[h] || 1, R = r.peakX, E = Math.max(0, r.peakX - v + 1);
918
+ for (let A = E; A <= R; A++)
919
+ A >= 0 && A < this.keyboardMaxCols && M >= 0 && M < this.keyboardRows && (o[M][A] = r.color);
920
+ }
921
+ else
922
+ for (let h = 0; h < d; h++) {
923
+ const M = this.keyboardRows - 1 - h;
924
+ if (M < 0) break;
925
+ const v = i[h] ?? 1, R = f[h] ?? 1, E = u + v - 1, A = b - R + 1, L = E + 1, S = A - 1, T = Math.max(0, S - L + 1);
926
+ if (T <= 0) continue;
927
+ const N = (L + S) / 2, Q = d === 1 ? 0 : h / (d - 1), K = Math.max(1, Math.floor(T * (1 - Q))) / 2, $ = Math.max(L, Math.ceil(N - K)), J = Math.min(S, Math.floor(N + K));
928
+ for (let B = $; B <= J; B++)
929
+ B >= 0 && B < this.keyboardMaxCols && M >= 0 && M < this.keyboardRows && (o[M][B] = r.color);
930
+ }
931
+ });
932
+ }
933
+ /** 光矢穿心(爱心) */
934
+ visualizerHeart(o) {
935
+ const l = this.params.amplitude / 100;
936
+ this.smoothedAmplitude += (this.params.currentAmplitude - this.smoothedAmplitude) * l;
937
+ const t = Math.min(this.smoothedAmplitude, 1), s = 1 + t * 0.2;
938
+ this.colorCycleOffset = (this.colorCycleOffset + 5e-3) % 1;
939
+ const i = this.colorCycleOffset * 360 % 360, f = P(i, 1, 1), n = P((i + 180) % 360, 1, 1);
940
+ let m = [];
941
+ this.keyboardRows >= 7 ? m = [
942
+ [1, 4],
943
+ [1, 5],
944
+ [1, 8],
945
+ [1, 9],
946
+ [2, 3],
947
+ [2, 4],
948
+ [2, 5],
949
+ [2, 6],
950
+ [2, 7],
951
+ [2, 8],
952
+ [2, 9],
953
+ [2, 10],
954
+ [3, 4],
955
+ [3, 5],
956
+ [3, 6],
957
+ [3, 7],
958
+ [3, 8],
959
+ [4, 5],
960
+ [4, 6],
961
+ [4, 7],
962
+ [5, 6],
963
+ [5, 7]
964
+ ] : this.keyboardRows < 6 ? m = [
965
+ [0, 4],
966
+ [0, 5],
967
+ [0, 8],
968
+ [0, 9],
969
+ [1, 3],
970
+ [1, 4],
971
+ [1, 5],
972
+ [1, 6],
973
+ [1, 7],
974
+ [1, 8],
975
+ [1, 9],
976
+ [2, 4],
977
+ [2, 5],
978
+ [2, 6],
979
+ [2, 7],
980
+ [2, 8],
981
+ [3, 6],
982
+ [3, 7]
983
+ ] : m = [
984
+ [0, 4],
985
+ [0, 5],
986
+ [0, 8],
987
+ [0, 9],
988
+ [1, 3],
989
+ [1, 4],
990
+ [1, 5],
991
+ [1, 6],
992
+ [1, 7],
993
+ [1, 8],
994
+ [1, 9],
995
+ [1, 10],
996
+ [2, 4],
997
+ [2, 5],
998
+ [2, 6],
999
+ [2, 7],
1000
+ [2, 8],
1001
+ [3, 5],
1002
+ [3, 6],
1003
+ [3, 7],
1004
+ [4, 6],
1005
+ [4, 7]
1006
+ ];
1007
+ const u = this.keyboardRows % 2 === 0;
1008
+ let w = [];
1009
+ if (u) {
1010
+ const C = Math.floor(this.keyboardRows / 2) - 1, c = Math.floor(this.keyboardRows / 2);
1011
+ w = [C, c];
1012
+ } else
1013
+ w = [Math.floor(this.keyboardRows / 2)];
1014
+ const b = Math.min(1, t * 1 + this.params.amplitude / 100 * 0.1) * this.keyboardMaxCols;
1015
+ w.forEach((C) => {
1016
+ if (C >= 0 && C < this.keyboardRows)
1017
+ for (let c = 0; c < b; c++) {
1018
+ const g = this.keyboardMaxCols - 1 - c;
1019
+ g >= 0 && g < this.keyboardMaxCols && (o[C][g] = n);
1020
+ }
1021
+ }), m.forEach((C) => {
1022
+ const [c, g] = C;
1023
+ if (c < this.keyboardRows && g < this.keyboardMaxCols) {
1024
+ const k = f.r * s, y = f.g * s, r = f.b * s;
1025
+ o[c][g] = {
1026
+ r: Math.min(255, k),
1027
+ g: Math.min(255, y),
1028
+ b: Math.min(255, r)
1029
+ };
1030
+ }
1031
+ });
1032
+ }
1033
+ /** 光茧共振 */
1034
+ visualizerAfternoonSunlight(o) {
1035
+ const l = this.params.amplitude / 100;
1036
+ this.smoothedAmplitude += (this.params.currentAmplitude - this.smoothedAmplitude) * l;
1037
+ const t = this.smoothedAmplitude, s = Math.ceil(this.keyboardMaxCols * t);
1038
+ this.colorCycleOffset = (this.colorCycleOffset + 5e-3) % 1;
1039
+ const i = this.colorCycleOffset * 360, f = /* @__PURE__ */ new Map(), n = (u) => {
1040
+ const w = Math.round(u);
1041
+ return f.has(w) || f.set(w, P(w, 1, 1)), f.get(w);
1042
+ };
1043
+ if (s > 0) {
1044
+ const u = Math.max(0, this.keyboardMaxCols - s);
1045
+ for (let w = u; w < this.keyboardMaxCols; w++) {
1046
+ const b = (i + w / this.keyboardMaxCols * 120) % 360;
1047
+ o[0][w] = n(b);
1048
+ }
1049
+ }
1050
+ const m = this.keyboardMaxCols - 1;
1051
+ if (s > 0) {
1052
+ const u = Math.ceil(this.keyboardRows * t);
1053
+ for (let w = 0; w < u; w++) {
1054
+ const b = (i + 60 + w / this.keyboardRows * 120) % 360;
1055
+ o[w][m] = n(b);
1056
+ }
1057
+ }
1058
+ if (s > 0) {
1059
+ const u = Math.max(0, this.keyboardMaxCols - s), w = this.keyboardRows - 1, b = this.keyboardMaxCols - 1, C = 0, c = b - u, g = C - w, k = Math.max(Math.abs(c), Math.abs(g)), y = 2;
1060
+ if (k > 0) {
1061
+ const r = c / k, a = g / k, d = 180 / k;
1062
+ for (let h = 0; h <= k; h++) {
1063
+ const M = Math.round(u + h * r), v = Math.round(w + h * a), R = (i + h * d) % 360, E = n(R);
1064
+ for (let A = 0; A < y; A++) {
1065
+ const L = M + A - Math.floor(y / 2), S = v;
1066
+ if (L >= 0 && L < this.keyboardMaxCols && S >= 0 && S < this.keyboardRows && (o[S][L] = E), A < y - 1) {
1067
+ const T = v + A - Math.floor(y / 2);
1068
+ M >= 0 && M < this.keyboardMaxCols && T >= 0 && T < this.keyboardRows && T !== S && (o[T][M] = E);
1069
+ }
1070
+ }
1071
+ }
1072
+ }
1073
+ }
1074
+ }
1075
+ /** 音叉振空(潮汐共振) */
1076
+ visualizerTidalResonance(o) {
1077
+ const l = (this.params.currentAmplitude - this.smoothedAmplitude) * (this.params.amplitude / 100);
1078
+ this.smoothedAmplitude += l, this.smoothedAmplitude = Math.max(0, Math.min(this.smoothedAmplitude, 1));
1079
+ const t = this.smoothedAmplitude;
1080
+ this.tidalOffset += 0.1, this.tidalOffset >= Math.PI * 2 && (this.tidalOffset = 0);
1081
+ const s = 5e-3 + t * 0.01;
1082
+ this.colorCycleOffset = (this.colorCycleOffset + s) % 1;
1083
+ const i = this.colorCycleOffset * 360, f = /* @__PURE__ */ new Map(), n = (A) => {
1084
+ const L = Math.round(A);
1085
+ return f.has(L) || f.set(L, P(L, 1, 1)), f.get(L);
1086
+ }, m = 0, u = Math.floor(this.keyboardMaxCols / 2), w = t, b = (Math.random() - 0.5) * w * 0.1, C = u * 0.2, c = t * u * 0.6, g = b * u * 0.15, k = Math.floor(Math.max(2, C + c + g)), y = t * this.keyboardMaxCols * 0.15, r = w * this.keyboardMaxCols * 0.2, a = (Math.random() - 0.5) * w * this.keyboardMaxCols * 0.15, d = Math.floor(y + r + a), h = (A, L, S, T, N = !0) => {
1087
+ const Q = d > 2 ? 3 : 2, Z = Math.min(2, Math.floor(t * 2)), U = t * 0.8, $ = (Math.random() * 2 - 1) * U, J = L, B = 0.2 + t * 0.4 + Math.random() * U * 0.1, p = this.tidalOffset + (Math.random() - 0.5) * U;
1088
+ for (let O = 0; O < T; O++) {
1089
+ const W = A + O * J, H = m + O;
1090
+ let F = 0;
1091
+ if (t > 0.1) {
1092
+ const I = Math.sin(O * B + p), _ = (Math.random() - 0.5) * U * 0.5;
1093
+ F = Math.floor($ * (I + _));
1094
+ }
1095
+ const X = H + F;
1096
+ if (X >= 0 && X < this.keyboardRows)
1097
+ for (let I = 0; I < Q; I++) {
1098
+ const _ = N ? W + I : W + I + 1;
1099
+ _ >= 0 && _ < this.keyboardMaxCols && (o[X][_] = S);
1100
+ }
1101
+ if (Z > 0)
1102
+ for (let I = 1; I <= Z; I++) {
1103
+ const _ = W - J * I, oo = H - I;
1104
+ let V = 0;
1105
+ if (t > 0.1) {
1106
+ const j = Math.sin((O - I) * B + p), z = (Math.random() - 0.5) * U * 0.3;
1107
+ V = Math.floor($ * (j + z));
1108
+ }
1109
+ const G = oo + V;
1110
+ if (_ >= 0 && _ < this.keyboardMaxCols && G >= 0 && G < this.keyboardRows && o[G][_].r === 0) {
1111
+ const j = 0.5 - I * 0.2;
1112
+ o[G][_] = {
1113
+ r: Math.round(S.r * j),
1114
+ g: Math.round(S.g * j),
1115
+ b: Math.round(S.b * j)
1116
+ };
1117
+ }
1118
+ }
1119
+ }
1120
+ }, M = (i + t * 60) % 360, v = (i + 180 + t * 60) % 360, R = n(M), E = n(v);
1121
+ k > 0 && (h(u - 1 - d, -1, R, k, !0), h(u + 1 + d, -1, E, k, !1));
1122
+ }
1123
+ /** 萤火轨迹(线性波动) */
1124
+ visualizerLinearWave(o) {
1125
+ const l = Math.min(this.params.currentAmplitude, 1);
1126
+ this.pulseOffset += 0.5, this.pulseOffset >= Math.PI * 2 && (this.pulseOffset = 0), this.colorCycleOffset = (this.colorCycleOffset + 0.02) % 1;
1127
+ const t = this.keyboardRows % 2 === 0;
1128
+ let s = [];
1129
+ if (t) {
1130
+ const i = Math.floor(this.keyboardRows / 2) - 1, f = Math.floor(this.keyboardRows / 2);
1131
+ s = [i, f];
1132
+ } else
1133
+ s = [Math.floor(this.keyboardRows / 2)];
1134
+ for (let i = 0; i < this.keyboardMaxCols; i++) {
1135
+ const f = i / this.keyboardMaxCols * Math.PI * 2, n = Math.sin(this.pulseOffset + f), m = i / (this.keyboardMaxCols - 1), u = 1 - Math.pow(m, 0.8), w = 1 + l * 2, b = Math.max(0.3, this.params.amplitude / 50), C = w * b * u, c = Math.round(n * C), g = (i / this.keyboardMaxCols * 360 + this.colorCycleOffset * 360) % 360, k = P(g, 1, 1);
1136
+ s.forEach((y) => {
1137
+ const r = y + c;
1138
+ r >= 0 && r < this.keyboardRows && (o[r][i] = k);
1139
+ const a = Math.min(3, Math.abs(c));
1140
+ for (let d = 1; d <= a; d++) {
1141
+ const h = y + Math.sign(c) * d;
1142
+ if (h >= 0 && h < this.keyboardRows && h !== r) {
1143
+ const M = 1 - d / (a + 1), v = {
1144
+ r: Math.round(k.r * M * 0.6),
1145
+ g: Math.round(k.g * M * 0.6),
1146
+ b: Math.round(k.b * M * 0.6)
1147
+ };
1148
+ o[h][i] = v;
1149
+ }
1150
+ }
1151
+ });
1152
+ }
1153
+ }
1154
+ /** 曲率遗轨(线性波动缩短) */
1155
+ visualizerLinearWaveShortened(o) {
1156
+ this.smoothedAmplitude += (this.params.currentAmplitude - this.smoothedAmplitude) * this.smoothingFactor;
1157
+ const l = Math.min(this.smoothedAmplitude, 1);
1158
+ this.pulseOffset += 0.5, this.pulseOffset >= Math.PI * 2 && (this.pulseOffset = 0), this.colorCycleOffset = (this.colorCycleOffset + 0.02) % 1;
1159
+ const t = this.keyboardRows % 2 === 0;
1160
+ let s = [];
1161
+ if (t) {
1162
+ const b = Math.floor(this.keyboardRows / 2) - 1, C = Math.floor(this.keyboardRows / 2);
1163
+ s = [b, C];
1164
+ } else
1165
+ s = [Math.floor(this.keyboardRows / 2)];
1166
+ const i = Math.max(2, Math.floor(this.keyboardRows / 2.5)), f = Math.floor(this.keyboardMaxCols / 4), m = this.keyboardMaxCols - f, u = f + Math.floor(m * l), w = this.keyboardMaxCols - u;
1167
+ for (let b = w; b < this.keyboardMaxCols; b++) {
1168
+ const C = b / this.keyboardMaxCols * Math.PI * 2, c = Math.sin(this.pulseOffset + C), g = b / (this.keyboardMaxCols - 1), k = 1 - Math.pow(g, 1.2), y = Math.max(2, i * 0.6), r = 1 + l * 1, a = Math.max(0.3, this.params.amplitude / 50), d = y * r * a * k, h = Math.round(c * d), M = (b / this.keyboardMaxCols * 360 + this.colorCycleOffset * 360) % 360, v = P(M, 1, 1);
1169
+ s.forEach((R) => {
1170
+ const E = R + h;
1171
+ E >= 0 && E < this.keyboardRows && (o[E][b] = v);
1172
+ const A = Math.min(3, Math.abs(h));
1173
+ for (let L = 1; L <= A; L++) {
1174
+ const S = R + Math.sign(h) * L;
1175
+ if (S >= 0 && S < this.keyboardRows && S !== E) {
1176
+ const T = 1 - L / (A + 1), N = {
1177
+ r: Math.round(v.r * T * 0.6),
1178
+ g: Math.round(v.g * T * 0.6),
1179
+ b: Math.round(v.b * T * 0.6)
1180
+ };
1181
+ o[S][b] = N;
1182
+ }
1183
+ }
1184
+ });
1185
+ }
1186
+ }
1187
+ /** 行波律动 */
1188
+ visualizerRowWaveRhythm(o) {
1189
+ const l = this.params.amplitude / 100 * 0.8;
1190
+ this.smoothedAmplitude += (this.params.currentAmplitude - this.smoothedAmplitude) * l;
1191
+ const t = Math.min(this.smoothedAmplitude, 1);
1192
+ this.pulseOffset += 0.02, this.pulseOffset >= Math.PI * 2 && (this.pulseOffset = 0), this.colorCycleOffset = (this.colorCycleOffset + 0.01) % 1;
1193
+ for (let s = 0; s < this.keyboardRows; s++) {
1194
+ const i = s * 123.456 + this.pulseOffset * 10, f = Math.sin(i) * 0.5 + 0.5, n = Math.sin(i * 1.618) * 0.5 + 0.5, m = Math.sin(i * 2.718) * 0.5 + 0.5, u = t * this.keyboardMaxCols * 1.2, w = f * 0.3 + n * 0.6 + m * 0.1, b = Math.max(0, Math.floor(u * w)), C = (this.colorCycleOffset * 360 + s / this.keyboardRows * 180) % 360, c = P(C, 1, 1);
1195
+ for (let g = 0; g < Math.min(b, this.keyboardMaxCols); g++)
1196
+ o[s][g] = {
1197
+ r: c.r,
1198
+ g: c.g,
1199
+ b: c.b
1200
+ };
1201
+ }
1202
+ }
1203
+ /** 曲率频阶(底部到顶部) */
1204
+ visualizerBottomToTop(o, l) {
1205
+ const t = this.params.amplitude / 100;
1206
+ this.smoothedAmplitude += (this.params.currentAmplitude - this.smoothedAmplitude) * t;
1207
+ const s = Array.from(
1208
+ { length: this.keyboardRows },
1209
+ () => Array.from({ length: this.keyboardMaxCols }, () => ({ r: 0, g: 0, b: 0 }))
1210
+ );
1211
+ this.fillModeColor(s, l, 1), this.pulseOffset += this.params.amplitude / 1e3;
1212
+ const i = Math.min(this.smoothedAmplitude, 1), f = [];
1213
+ for (let n = 0; n < this.keyboardMaxCols; n++) {
1214
+ const m = n / this.keyboardMaxCols, u = 0.2 + 0.3 * Math.cos(m * Math.PI), w = Math.sin(this.pulseOffset * Math.PI * 1.8 + n * 0.7) * 0.2, b = Math.sin(this.pulseOffset * Math.PI * 0.9 + n * 1.3) * 0.15, C = Math.sin(this.pulseOffset * Math.PI * 2.3 + n * 0.4) * 0.1, c = Math.sin(n * 2.1 + this.pulseOffset * 3.2) * 0.3;
1215
+ let g = u + w + b + C + c;
1216
+ g < 0.1 ? g = 0 : g = Math.pow(g, 1.5), g = Math.max(0, Math.min(1.2, g));
1217
+ const y = i * (this.params.amplitude / 8) * g * this.keyboardRows;
1218
+ f[n] = Math.max(0, Math.floor(y));
1219
+ }
1220
+ for (let n = 0; n < this.keyboardRows; n++) {
1221
+ const m = this.keyboardRows - 1 - n;
1222
+ for (let u = 0; u < this.keyboardMaxCols; u++)
1223
+ m < f[u] && (o[n][u] = s[n][u]);
1224
+ }
1225
+ }
1226
+ }
1227
+ const To = 50, Wo = 5;
1228
+ function zo(e) {
1229
+ return typeof e.isActive == "function";
1230
+ }
1231
+ const Ho = (e) => {
1232
+ const o = new TextEncoder().encode(e);
1233
+ return btoa(String.fromCharCode.apply(null, Array.from(o)));
1234
+ };
1235
+ async function Vo(e) {
1236
+ const o = await po(e.device), l = new Po(e.keyboardConfig), t = e.intervalMs ?? To, s = e.silenceThreshold ?? Wo;
1237
+ let i = 0, f = !1, n = e.mode ?? 13, m = v(e.amplitude ?? 50, 1, 100), u = e.backMode ?? 0, w = v(e.backBrightness ?? 100, 10, 100), b = 0, C = 0, c = !1, g = !1, k = 1e3, y = null, r = e.amplitudeSource, a = !1, d = null, h = !1, M = "";
1238
+ function v(p, O, W) {
1239
+ return Math.min(W, Math.max(O, p));
1240
+ }
1241
+ function R() {
1242
+ var p;
1243
+ (p = e.onStateChange) == null || p.call(e, E());
1244
+ }
1245
+ function E() {
1246
+ return {
1247
+ running: !!i,
1248
+ mode: n,
1249
+ amplitude: m,
1250
+ backMode: u,
1251
+ backBrightness: w,
1252
+ currentAmplitude: b,
1253
+ sourceActive: c,
1254
+ testMode: g,
1255
+ currentKeysRgb: y
1256
+ };
1257
+ }
1258
+ function A(p) {
1259
+ p > 0 ? (C = 0, b = Math.min(1, p / 1e3)) : (C++, C >= s && (b = 0));
1260
+ }
1261
+ async function L() {
1262
+ if (!i || f) return;
1263
+ if (g) {
1264
+ C = 0, b = k / 1e3, S(!0);
1265
+ return;
1266
+ }
1267
+ const p = r;
1268
+ if (!p) {
1269
+ S(!1);
1270
+ return;
1271
+ }
1272
+ if (zo(p) && !p.isActive()) {
1273
+ S(!1);
1274
+ return;
1275
+ }
1276
+ try {
1277
+ const O = await p.getAmplitude();
1278
+ typeof O == "number" && A(O || 0), S(!0);
1279
+ } catch {
1280
+ K(), S(!1);
1281
+ }
1282
+ }
1283
+ function S(p) {
1284
+ c !== p && (c = p, R());
1285
+ }
1286
+ async function T(p) {
1287
+ var O, W;
1288
+ if (!f) {
1289
+ if ((O = e.onKeysRgbChange) == null || O.call(e, p), a) {
1290
+ d = p;
1291
+ return;
1292
+ }
1293
+ a = !0;
1294
+ try {
1295
+ const H = ko(p, e.keyboardConfig);
1296
+ let F = 0;
1297
+ if (e.ledConfig) {
1298
+ const X = Math.max(e.ledConfig.rows, e.ledConfig.cols);
1299
+ F = Math.ceil(b * 1e3 / (1e3 / X));
1300
+ }
1301
+ await o.setMusicData(H, F, e.isUSBDevice, e.lightingVersion);
1302
+ } catch (H) {
1303
+ (W = e.onError) == null || W.call(e, H);
1304
+ } finally {
1305
+ if (a = !1, d) {
1306
+ const H = d;
1307
+ d = null, T(H);
1308
+ }
1309
+ }
1310
+ }
1311
+ }
1312
+ async function N() {
1313
+ var O;
1314
+ const p = e.screenLightClient;
1315
+ if (p)
1316
+ try {
1317
+ const W = `${n}`;
1318
+ (!h || M !== W) && (h = !0, M = W, await Q(), await p.setMusicMode(`${n}&100&0&100&0`));
1319
+ const H = await p.getMusicStatus(), { keyList: F, musicConfig: X } = e.keyboardConfig, I = F.length, oo = F.reduce((z, q) => Math.max(z, q.length), 0) + ((X == null ? void 0 : X.maxColOffset) || 0), V = Array.from(
1320
+ { length: I },
1321
+ () => Array.from({ length: oo }, () => ({ r: 0, g: 0, b: 0 }))
1322
+ );
1323
+ ((H == null ? void 0 : H.keys) ?? []).filter((z) => z.keyCode !== 0 || z.keyCode === 0 && z.keyIndex !== 0).forEach((z) => {
1324
+ var q;
1325
+ ((q = V[z.row]) == null ? void 0 : q[z.col]) !== void 0 && (V[z.row][z.col] = Co(z.color));
1326
+ }), S(!0), y = V, await T(V);
1327
+ } catch (W) {
1328
+ (O = e.onError) == null || O.call(e, W);
1329
+ }
1330
+ }
1331
+ async function Q() {
1332
+ var O;
1333
+ const p = e.screenLightClient;
1334
+ if (p)
1335
+ try {
1336
+ const { name: W, vendorId: H, productId: F, connectType: X, keyList: I, musicConfig: _ } = e.keyboardConfig, oo = I.reduce((q, eo) => Math.max(q, eo.length), 0), V = (_ == null ? void 0 : _.maxColOffset) || 0, G = I.map((q, eo) => {
1337
+ let lo = 0;
1338
+ return q.map((to, xo) => {
1339
+ let no = xo + lo;
1340
+ if (_ != null && _.keyOffset) {
1341
+ const ro = _.keyOffset.find((fo) => fo.value === to.value);
1342
+ ro && (no += ro.offsetX, lo += ro.offsetX);
1343
+ }
1344
+ return {
1345
+ row: eo,
1346
+ col: no,
1347
+ code: to.keyCode,
1348
+ index: to.value,
1349
+ name: to.name
1350
+ };
1351
+ });
1352
+ }), j = {
1353
+ name: W,
1354
+ // 设备名称
1355
+ vendorId: H,
1356
+ // VID
1357
+ productId: F,
1358
+ // PID
1359
+ deviceMode: X === "USB" ? 0 : 1,
1360
+ // 0 是有线 1 是无线
1361
+ layouts: {
1362
+ rows: I.length,
1363
+ // 键盘的行数
1364
+ cols: oo + V,
1365
+ // 键盘最长的列数
1366
+ keys: G.flat()
1367
+ }
1368
+ }, z = encodeURIComponent(Ho(JSON.stringify(j)));
1369
+ await p.setKeyboardLayout(z);
1370
+ } catch (W) {
1371
+ (O = e.onError) == null || O.call(e, W);
1372
+ }
1373
+ }
1374
+ function Z() {
1375
+ var p;
1376
+ if (!f) {
1377
+ if (n === 100) {
1378
+ N();
1379
+ return;
1380
+ }
1381
+ h = !1, L();
1382
+ try {
1383
+ if (!c) return;
1384
+ const O = l.render({
1385
+ mode: n,
1386
+ amplitude: m,
1387
+ backMode: u,
1388
+ backBrightness: w,
1389
+ currentAmplitude: b
1390
+ });
1391
+ y = O, T(O);
1392
+ } catch (O) {
1393
+ (p = e.onError) == null || p.call(e, O);
1394
+ }
1395
+ }
1396
+ }
1397
+ function U() {
1398
+ i || (i = mo(Z, t), R());
1399
+ }
1400
+ function K() {
1401
+ i && (Mo(i), i = 0, R());
1402
+ }
1403
+ function $() {
1404
+ var p;
1405
+ f || (f = !0, K(), d = null, a = !1, (p = e.screenLightClient) == null || p.close());
1406
+ }
1407
+ function J() {
1408
+ f && (f = !1, U());
1409
+ }
1410
+ function B() {
1411
+ var p, O;
1412
+ K(), (p = r == null ? void 0 : r.stop) == null || p.call(r), (O = e.screenLightClient) == null || O.close();
1413
+ }
1414
+ return {
1415
+ start: U,
1416
+ stop: K,
1417
+ pause: $,
1418
+ resume: J,
1419
+ dispose: B,
1420
+ setMode(p) {
1421
+ n = p, R();
1422
+ },
1423
+ setAmplitude(p) {
1424
+ m = v(p, 1, 100), R();
1425
+ },
1426
+ setBackMode(p) {
1427
+ u = p, R();
1428
+ },
1429
+ setBackBrightness(p) {
1430
+ w = v(p, 10, 100), R();
1431
+ },
1432
+ setTestMode(p, O) {
1433
+ g = p, typeof O == "number" && (k = O), R();
1434
+ },
1435
+ setAmplitudeSource(p) {
1436
+ var O;
1437
+ r !== p && ((O = r == null ? void 0 : r.stop) == null || O.call(r), r = p, c = !1, R());
1438
+ },
1439
+ getState: E
1440
+ };
1441
+ }
1442
+ const co = 5, Y = 0.01, so = 0.3, io = 8e-3;
1443
+ function Ko() {
1444
+ let e = null, o = null, l = null, t = null, s = null, i = Y, f = {
1445
+ low: Y,
1446
+ mid: Y,
1447
+ high: Y
1448
+ }, n = !1;
1449
+ function m() {
1450
+ e = null, o = null, l = null, t = null, s = null, i = Y, f = {
1451
+ low: Y,
1452
+ mid: Y,
1453
+ high: Y
1454
+ }, n = !1;
1455
+ }
1456
+ function u(r) {
1457
+ r > i ? i = i * (1 - so) + r * so : i = i * (1 - io) + r * io, i = Math.max(i, Y);
1458
+ const a = r / i;
1459
+ return Math.min(1e3, Math.round(a * 1e3));
1460
+ }
1461
+ function w() {
1462
+ C();
1463
+ }
1464
+ async function b() {
1465
+ var r;
1466
+ if (!n) {
1467
+ if (!((r = navigator.mediaDevices) != null && r.getDisplayMedia))
1468
+ throw new Error("当前浏览器不支持 getDisplayMedia");
1469
+ try {
1470
+ const a = await navigator.mediaDevices.getDisplayMedia({
1471
+ video: {
1472
+ displaySurface: "monitor"
1473
+ },
1474
+ audio: {
1475
+ echoCancellation: !1,
1476
+ noiseSuppression: !1,
1477
+ autoGainControl: !1
1478
+ }
1479
+ }), d = a.getAudioTracks();
1480
+ if (d.length === 0)
1481
+ throw a.getTracks().forEach((M) => M.stop()), new Error("未获取到音频轨道,请勾选分享系统音频或标签页音频");
1482
+ a.getVideoTracks().forEach((M) => M.stop()), e = new AudioContext(), o = e.createAnalyser(), o.fftSize = 2048, o.smoothingTimeConstant = 0.75, e.createMediaStreamSource(a).connect(o), l = a, t = new Float32Array(o.fftSize), s = new Uint8Array(o.frequencyBinCount), i = Y, n = !0, d.forEach((M) => {
1483
+ M.addEventListener("ended", w);
1484
+ });
1485
+ } catch (a) {
1486
+ throw a instanceof Error && a.name === "NotAllowedError" ? new Error("取消了授权") : a;
1487
+ }
1488
+ }
1489
+ }
1490
+ function C() {
1491
+ !n && !l && !e || (l == null || l.getAudioTracks().forEach((r) => {
1492
+ r.removeEventListener("ended", w), r.stop();
1493
+ }), l == null || l.getVideoTracks().forEach((r) => r.stop()), l = null, (e == null ? void 0 : e.state) !== "closed" && (e == null || e.close()), m());
1494
+ }
1495
+ function c() {
1496
+ if (!n || !o || !t) return 0;
1497
+ o.getFloatTimeDomainData(t);
1498
+ let r = 0, a = 0;
1499
+ for (let v = 0; v < t.length; v++) {
1500
+ const R = Math.abs(t[v] ?? 0);
1501
+ r = Math.max(r, R), a += R * R;
1502
+ }
1503
+ const d = Math.sqrt(a / t.length), h = r * 0.6 + d * 0.4, M = u(h);
1504
+ return M <= co ? 0 : M;
1505
+ }
1506
+ function g(r, a, d) {
1507
+ if (!e || !o) return 0;
1508
+ const h = e.sampleRate / o.fftSize, M = Math.max(0, Math.floor(a / h)), v = Math.min(r.length - 1, Math.ceil(d / h));
1509
+ if (v < M) return 0;
1510
+ let R = 0;
1511
+ for (let E = M; E <= v; E++) {
1512
+ const A = (r[E] ?? 0) / 255;
1513
+ R += A * A;
1514
+ }
1515
+ return Math.sqrt(R / (v - M + 1));
1516
+ }
1517
+ function k(r, a) {
1518
+ const d = f[a], h = r > d ? so : io, M = Math.max(d * (1 - h) + r * h, Y);
1519
+ f[a] = M;
1520
+ const v = Math.min(1e3, Math.round(r / M * 1e3));
1521
+ return v <= co ? 0 : v;
1522
+ }
1523
+ function y() {
1524
+ return !n || !o || !s ? { low: 0, mid: 0, high: 0 } : (o.getByteFrequencyData(s), {
1525
+ low: k(g(s, 20, 250), "low"),
1526
+ mid: k(g(s, 250, 4e3), "mid"),
1527
+ high: k(g(s, 4e3, 2e4), "high")
1528
+ });
1529
+ }
1530
+ return {
1531
+ start: b,
1532
+ stop: C,
1533
+ getAmplitude: c,
1534
+ isActive: () => n,
1535
+ getFrequencyBands: y
1536
+ };
1537
+ }
1538
+ const ho = `const m = "/api/audio/amplitude";
1539
+ let u = "http://127.0.0.1:9191", f = 500, d = 50, a, n = !1;
1540
+ const r = /* @__PURE__ */ new Map();
1541
+ async function g(t) {
1542
+ const e = new AbortController(), s = setTimeout(() => e.abort(), f);
1543
+ try {
1544
+ const i = await fetch(\`\${u}\${t}\`, { signal: e.signal });
1545
+ if (!i.ok) throw new Error(\`插件请求失败: \${i.status}\`);
1546
+ const o = await i.json().catch(() => {
1547
+ });
1548
+ return (o == null ? void 0 : o.data) !== void 0 ? o.data : o;
1549
+ } finally {
1550
+ clearTimeout(s);
1551
+ }
1552
+ }
1553
+ function p(t) {
1554
+ const e = r.get(t);
1555
+ if (e) return e;
1556
+ const s = g(t).finally(() => r.delete(t));
1557
+ return r.set(t, s), s;
1558
+ }
1559
+ async function l() {
1560
+ if (!n) {
1561
+ n = !0;
1562
+ try {
1563
+ const t = await p(m);
1564
+ self.postMessage({
1565
+ type: "amplitude",
1566
+ value: typeof (t == null ? void 0 : t.amplitude) == "number" ? t.amplitude : 0
1567
+ });
1568
+ } catch (t) {
1569
+ self.postMessage({
1570
+ type: "amplitude-error",
1571
+ message: t instanceof Error ? t.message : String(t)
1572
+ });
1573
+ } finally {
1574
+ n = !1;
1575
+ }
1576
+ }
1577
+ }
1578
+ function c() {
1579
+ a === void 0 && (l(), a = setInterval(() => void l(), d));
1580
+ }
1581
+ function v() {
1582
+ a !== void 0 && (clearInterval(a), a = void 0);
1583
+ }
1584
+ self.addEventListener("message", (t) => {
1585
+ const e = t.data;
1586
+ if (!(!e || typeof e != "object"))
1587
+ switch (e.type) {
1588
+ case "init":
1589
+ u = e.baseUrl, f = e.timeoutMs, d = e.pollIntervalMs, a !== void 0 && (v(), c());
1590
+ break;
1591
+ case "start-poll":
1592
+ c();
1593
+ break;
1594
+ case "request":
1595
+ p(e.path).then((s) => {
1596
+ self.postMessage({ type: "response", id: e.id, ok: !0, data: s });
1597
+ }).catch((s) => {
1598
+ self.postMessage({
1599
+ type: "response",
1600
+ id: e.id,
1601
+ ok: !1,
1602
+ error: s instanceof Error ? s.message : String(s)
1603
+ });
1604
+ });
1605
+ break;
1606
+ }
1607
+ });
1608
+ `, yo = typeof self < "u" && self.Blob && new Blob(["URL.revokeObjectURL(import.meta.url);", ho], { type: "text/javascript;charset=utf-8" });
1609
+ function Do(e) {
1610
+ let o;
1611
+ try {
1612
+ if (o = yo && (self.URL || self.webkitURL).createObjectURL(yo), !o) throw "";
1613
+ const l = new Worker(o, {
1614
+ type: "module",
1615
+ name: e == null ? void 0 : e.name
1616
+ });
1617
+ return l.addEventListener("error", () => {
1618
+ (self.URL || self.webkitURL).revokeObjectURL(o);
1619
+ }), l;
1620
+ } catch {
1621
+ return new Worker(
1622
+ "data:text/javascript;charset=utf-8," + encodeURIComponent(ho),
1623
+ {
1624
+ type: "module",
1625
+ name: e == null ? void 0 : e.name
1626
+ }
1627
+ );
1628
+ }
1629
+ }
1630
+ const Xo = "http://127.0.0.1:9191", Yo = 500, Bo = 50;
1631
+ function jo(e = Xo, o = {}) {
1632
+ const l = o.timeoutMs ?? Yo, t = o.pollIntervalMs ?? Bo;
1633
+ let s, i = !1, f = 0, n, m;
1634
+ const u = /* @__PURE__ */ new Set(), w = /* @__PURE__ */ new Map();
1635
+ function b(y) {
1636
+ for (const r of u) r.reject(y);
1637
+ u.clear();
1638
+ for (const r of w.values()) r.reject(y);
1639
+ w.clear();
1640
+ }
1641
+ function C() {
1642
+ if (s) return s;
1643
+ const y = new Do({ name: "music-v2-plugin" });
1644
+ return y.postMessage({ type: "init", baseUrl: e, timeoutMs: l, pollIntervalMs: t }), y.addEventListener("message", (r) => {
1645
+ const a = r.data;
1646
+ if ((a == null ? void 0 : a.type) === "amplitude") {
1647
+ n = a.value, m = void 0;
1648
+ for (const d of u) d.resolve(a.value);
1649
+ u.clear();
1650
+ return;
1651
+ }
1652
+ if ((a == null ? void 0 : a.type) === "amplitude-error") {
1653
+ m = new Error(a.message), n = void 0;
1654
+ for (const d of u) d.reject(m);
1655
+ u.clear();
1656
+ return;
1657
+ }
1658
+ if ((a == null ? void 0 : a.type) === "response") {
1659
+ const d = w.get(a.id);
1660
+ if (!d) return;
1661
+ w.delete(a.id), a.ok ? d.resolve(a.data) : d.reject(new Error(a.error || "插件请求失败"));
1662
+ }
1663
+ }), y.addEventListener("error", () => {
1664
+ const r = new Error("插件 Worker 异常");
1665
+ m = r, n = void 0, i = !1, b(r), y.terminate(), s === y && (s = void 0);
1666
+ }), s = y, y;
1667
+ }
1668
+ function c() {
1669
+ s && (b(new Error("插件客户端已停止")), s.terminate(), s = void 0, i = !1, n = void 0, m = void 0);
1670
+ }
1671
+ function g() {
1672
+ return new Promise((y, r) => {
1673
+ const a = go(() => {
1674
+ u.delete(d), r(m ?? new Error("插件请求超时"));
1675
+ }, l + t), d = {
1676
+ resolve: (h) => {
1677
+ ao(a), y(h);
1678
+ },
1679
+ reject: (h) => {
1680
+ ao(a), r(h);
1681
+ }
1682
+ };
1683
+ u.add(d);
1684
+ });
1685
+ }
1686
+ async function k(y) {
1687
+ const r = C(), a = ++f;
1688
+ return new Promise((d, h) => {
1689
+ w.set(a, { resolve: d, reject: h }), r.postMessage({ type: "request", id: a, path: y });
1690
+ });
1691
+ }
1692
+ return {
1693
+ /** 获取振幅,返回 0-1000 */
1694
+ async getAmplitude() {
1695
+ const y = C();
1696
+ return i || (i = !0, y.postMessage({ type: "start-poll" })), typeof n == "number" && !m ? n : g();
1697
+ },
1698
+ /** 设置键盘布局(base64 编码后的布局 JSON) */
1699
+ setKeyboardLayout(y) {
1700
+ return k(`/api/keyboard/layout/base64?data=${y}`);
1701
+ },
1702
+ /** 设置音乐律动模式 */
1703
+ setMusicMode(y) {
1704
+ return k(`/api/keyboard/musiceffect?param=${y}`);
1705
+ },
1706
+ /** 获取音乐律动状态(屏光联动每键颜色) */
1707
+ getMusicStatus() {
1708
+ return k("/api/keyboard/musiceffect/");
1709
+ },
1710
+ /** 关闭音乐律动 */
1711
+ close() {
1712
+ return k("/api/keyboard/musiceffect/close/");
1713
+ },
1714
+ /** 获取硬件信息 */
1715
+ getHardwareInfo() {
1716
+ return k("/api/hardware/info");
1717
+ },
1718
+ stop() {
1719
+ c();
1720
+ }
1721
+ };
1722
+ }
1723
+ export {
1724
+ P as HSVtoRGB,
1725
+ Po as MusicV2Renderer,
1726
+ Ao as RING_108_KEY_POSITIONS,
1727
+ vo as RING_68_KEY_POSITIONS,
1728
+ Ro as RING_87_KEY_POSITIONS,
1729
+ Eo as VOLCANO_64_KEY_POSITIONS,
1730
+ So as VOLCANO_84_ISO_KEY_POSITIONS,
1731
+ Lo as VOLCANO_87_KEY_POSITIONS,
1732
+ Io as VOLCANO_98_KEY_POSITIONS,
1733
+ ko as buildMusicData,
1734
+ bo as createKeysRgbGrid,
1735
+ Vo as createMusicV2Engine,
1736
+ jo as createMusicV2PluginClient,
1737
+ Ko as createSystemAudioSource,
1738
+ $o as getMusicGridCol,
1739
+ Oo as getMusicRingKeyPositions,
1740
+ _o as getMusicVolcanoKeyPositions,
1741
+ Co as hexToRgb
1742
+ };