dsh-skill-browser 1.7.4 → 1.8.1
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/README.md +3 -0
- package/lib/client.js +2025 -1651
- package/package.json +58 -53
package/lib/client.js
CHANGED
|
@@ -1,1651 +1,2025 @@
|
|
|
1
|
-
window.__ModuleLoader__.load({
|
|
2
|
-
id: "dsh-skill-browser",
|
|
3
|
-
factory: function (require) {
|
|
4
|
-
var module = { exports: {} };
|
|
5
|
-
var exports = module.exports;
|
|
6
|
-
|
|
7
|
-
//
|
|
8
|
-
//
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
//
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
//
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
var
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
//
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
var
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
var
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
'
|
|
500
|
-
'
|
|
501
|
-
'
|
|
502
|
-
'
|
|
503
|
-
'#
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
'
|
|
508
|
-
'
|
|
509
|
-
'
|
|
510
|
-
'
|
|
511
|
-
'
|
|
512
|
-
|
|
513
|
-
'
|
|
514
|
-
'
|
|
515
|
-
'
|
|
516
|
-
'
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
'
|
|
520
|
-
'background
|
|
521
|
-
'
|
|
522
|
-
'
|
|
523
|
-
'
|
|
524
|
-
'
|
|
525
|
-
'
|
|
526
|
-
'
|
|
527
|
-
'
|
|
528
|
-
'
|
|
529
|
-
'
|
|
530
|
-
'
|
|
531
|
-
'
|
|
532
|
-
'
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
panel.
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
}
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
//
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
if (
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
if (
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
var
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
if (S.
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
}
|
|
933
|
-
|
|
934
|
-
}
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
if (
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
var
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
if (
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
//
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
return;
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
"
|
|
1188
|
-
|
|
1189
|
-
"
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
var
|
|
1211
|
-
var
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
'<
|
|
1218
|
-
'<
|
|
1219
|
-
'<
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
var
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
var
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
}
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
var
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
if (
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
|
|
1387
|
-
|
|
1388
|
-
|
|
1389
|
-
|
|
1390
|
-
|
|
1391
|
-
|
|
1392
|
-
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
}
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
|
-
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
if (!
|
|
1450
|
-
var
|
|
1451
|
-
if (
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
|
|
1460
|
-
|
|
1461
|
-
|
|
1462
|
-
}
|
|
1463
|
-
|
|
1464
|
-
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
|
|
1484
|
-
function
|
|
1485
|
-
var
|
|
1486
|
-
if (!
|
|
1487
|
-
|
|
1488
|
-
|
|
1489
|
-
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
|
|
1493
|
-
|
|
1494
|
-
|
|
1495
|
-
|
|
1496
|
-
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
} catch (e) {}
|
|
1513
|
-
|
|
1514
|
-
|
|
1515
|
-
if (
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
|
|
1519
|
-
|
|
1520
|
-
|
|
1521
|
-
|
|
1522
|
-
|
|
1523
|
-
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
|
|
1527
|
-
|
|
1528
|
-
|
|
1529
|
-
|
|
1530
|
-
|
|
1531
|
-
|
|
1532
|
-
|
|
1533
|
-
|
|
1534
|
-
|
|
1535
|
-
|
|
1536
|
-
|
|
1537
|
-
|
|
1538
|
-
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
|
|
1543
|
-
|
|
1544
|
-
|
|
1545
|
-
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
|
|
1552
|
-
|
|
1553
|
-
|
|
1554
|
-
|
|
1555
|
-
|
|
1556
|
-
|
|
1557
|
-
|
|
1558
|
-
|
|
1559
|
-
|
|
1560
|
-
|
|
1561
|
-
|
|
1562
|
-
|
|
1563
|
-
|
|
1564
|
-
|
|
1565
|
-
|
|
1566
|
-
|
|
1567
|
-
|
|
1568
|
-
|
|
1569
|
-
|
|
1570
|
-
|
|
1571
|
-
|
|
1572
|
-
|
|
1573
|
-
|
|
1574
|
-
|
|
1575
|
-
|
|
1576
|
-
|
|
1577
|
-
|
|
1578
|
-
|
|
1579
|
-
|
|
1580
|
-
|
|
1581
|
-
|
|
1582
|
-
|
|
1583
|
-
|
|
1584
|
-
|
|
1585
|
-
|
|
1586
|
-
|
|
1587
|
-
|
|
1588
|
-
|
|
1589
|
-
|
|
1590
|
-
|
|
1591
|
-
|
|
1592
|
-
|
|
1593
|
-
|
|
1594
|
-
|
|
1595
|
-
|
|
1596
|
-
|
|
1597
|
-
|
|
1598
|
-
|
|
1599
|
-
|
|
1600
|
-
|
|
1601
|
-
|
|
1602
|
-
|
|
1603
|
-
|
|
1604
|
-
|
|
1605
|
-
|
|
1606
|
-
|
|
1607
|
-
|
|
1608
|
-
|
|
1609
|
-
|
|
1610
|
-
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
|
|
1614
|
-
|
|
1615
|
-
|
|
1616
|
-
|
|
1617
|
-
|
|
1618
|
-
|
|
1619
|
-
|
|
1620
|
-
|
|
1621
|
-
|
|
1622
|
-
|
|
1623
|
-
|
|
1624
|
-
|
|
1625
|
-
|
|
1626
|
-
|
|
1627
|
-
|
|
1628
|
-
|
|
1629
|
-
|
|
1630
|
-
|
|
1631
|
-
|
|
1632
|
-
|
|
1633
|
-
if (
|
|
1634
|
-
|
|
1635
|
-
|
|
1636
|
-
|
|
1637
|
-
|
|
1638
|
-
|
|
1639
|
-
|
|
1640
|
-
|
|
1641
|
-
|
|
1642
|
-
|
|
1643
|
-
|
|
1644
|
-
|
|
1645
|
-
|
|
1646
|
-
|
|
1647
|
-
|
|
1648
|
-
|
|
1649
|
-
|
|
1650
|
-
|
|
1651
|
-
|
|
1
|
+
window.__ModuleLoader__.load({
|
|
2
|
+
id: "dsh-skill-browser",
|
|
3
|
+
factory: function (require) {
|
|
4
|
+
var module = { exports: {} };
|
|
5
|
+
var exports = module.exports;
|
|
6
|
+
// skin-catalog.js — shared 128-skin catalog for dsh-todo-float-ball /
|
|
7
|
+
// dsh-skill-browser / dsh-font-enhancer. Generated by make_skin_catalog.py.
|
|
8
|
+
// Proposal numbering matches the approved design sheets (01-128).
|
|
9
|
+
(function () {
|
|
10
|
+
if (window.__DSH_BALL_SKINS) return;
|
|
11
|
+
function hs(h,s,l,a){return a==null?("hsl("+h+","+s+"%,"+l+"%)"):("hsla("+h+","+s+"%,"+l+"%,"+a+")");}
|
|
12
|
+
var FORMULA = {
|
|
13
|
+
deep:[["朱砂","VERMILION",4],["酡颜","FLUSHED",13],["琥珀","AMBER",32],["缃色","PALE GOLD",44],["藤黄","GAMBOGE",52],["松花","PINE POLLEN",62],["葱倩","SCALLION",78],["艾绿","MUGWORT",96],["嫩柳","WILLOW",112],["竹青","BAMBOO",126],["石绿","MINERAL GREEN",138],["翡翠","JADEITE",152],["天水碧","SKY WATER",164],["铜绿","VERDIGRIS",172],["松石","TURQUOISE",180],["孔雀","PEACOCK",188],["晴山","CLEAR HILL",194],["天青","AZURE",200],["湖水","LAKE BLUE",207],["霁蓝","AFTER RAIN",214],["群青","ULTRAMARINE",221],["靛蓝","INDIGO",229],["绀青","NAVY",236],["藏蓝","TIBETAN",243],["窃蓝","FLEDGLING BLUE",250],["青莲","LOTUS VIOLET",258],["紫藤","WISTERIA",265],["紫棠","VIOLET WOOD",272],["雪青","SNOW LILAC",283],["丁香","LILAC",290],["堇色","VIOLET",297],["藕荷","LOTUS PINK",305],["烟霞","MISTY GLOW",315],["十样锦","BROCADE",326],["海棠","BEGONIA",334],["银红","SILVER RED",341],["桃夭","PEACH BLOSSOM",349],["绛纱","CRIMSON GAUZE",356]],
|
|
14
|
+
muted:[["栗","CHESTNUT",16],["驼","CAMEL",26],["灰陶","POTTERY",34],["枯茶","DRIED TEA",42],["秋香","AUTUMN",58],["苔径","MOSS PATH",88],["豆绿","BEAN GREEN",98],["青梅","GREEN PLUM",116],["苍山","PALE MOUNTAIN",150],["青矾","VITRIOL",194],["沧浪","PALE WAVE",205],["雾蓝","FOG BLUE",212],["青灰","BLUISH GRAY",224],["黛蓝","HAZY BLUE",232],["黛灰","INK GRAY",252],["紫灰","VIOLET GRAY",276],["烟紫","SMOKY VIOLET",288],["藕灰","LOTUS GRAY",308],["绛紫","CRIMSON PLUM",326],["檀","SANDLEWOOD",359]],
|
|
15
|
+
soft:[["曙光","FIRST LIGHT",8],["橄榄","OLIVE",66],["松间","PINEWOOD",140],["青栀","GARDENIA",168],["湖烟","LAKE MIST",190],["碧涛","BLUE WAVE",202],["竹月","BAMBOO MOON",216],["星蓝","STAR BLUE",226],["青冥","AZURE DEPTH",244],["紫冥","DUSK VIOLET",262],["夜堇","NIGHT VIOLET",284],["芋紫","TARO",300],["霞粉","GLOW PINK",338],["树莓","RASPBERRY",344],["樱贝","CHERRY SHELL",352]],
|
|
16
|
+
neutral:[["银鼠","SILVER RAT",205],["玄青","INK CYAN",160],["玄墨","JET BLACK",275],["乌羽","RAVEN",8],["烟灰","SMOKE",32],["灰鹄","SWAN",140],["玄天","DARK SKY",222],["黛烟","INK SMOKE",288],["铁灰","IRON",210],["磨石","WHETSTONE",95]],
|
|
17
|
+
light:[["月白","MOON WHITE",210],["卵白","EGG WHITE",88],["牙色","IVORY",46],["茶白","TEA WHITE",28],["米浆","RICE MILK",52],["亚麻","LINEN",32],["藕丝","LOTUS THREAD",330],["绫粉","SILK PINK",350],["青白","PALE CELADON",160],["天际","SKYLINE",205],["紫丁","PALE LILAC",285],["雾粉","MIST PINK",345],["薄荷","MINT",150],["绢黄","PALE SILK",48],["灰绿","SAGE",110],["雪浪","SNOW WAVE",195],["燕羽","SWALLOW",225]],
|
|
18
|
+
};
|
|
19
|
+
function varsFor(kind,hh){
|
|
20
|
+
var v={};
|
|
21
|
+
if(kind==="deep"){v={bgA:hs(hh,42,17),bgB:hs(hh,48,7),edge:hs(hh,60,85,".2"),spec:"rgba(255,255,255,.16)",stI:hs(hh,14,54),stP:hs(hh,40,62),stA:hs(hh,88,68),stD:hs(hh,50,42),lbc:hs(hh,35,94),trk:hs(hh,50,80,".13"),pbgA:hs(hh,24,12),pbgB:hs(hh,28,7),pbd:hs(hh,45,80,".14"),ptx:hs(hh,28,92),itm:hs(hh,16,66),itD:hs(hh,18,52),cctx:hs(hh,16,66),chipBg:hs(hh,30,60,".07"),hintC:hs(hh,12,45),hair1:hs(hh,88,68),hair2:hs(hh,50,42)};}
|
|
22
|
+
else if(kind==="muted"){v={bgA:hs(hh,19,15),bgB:hs(hh,20,6),edge:hs(hh,30,78,".17"),spec:"rgba(255,255,255,.1)",stI:hs(hh,10,50),stP:hs(hh,22,56),stA:hs(hh,42,62),stD:hs(hh,28,40),lbc:hs(hh,18,90),trk:hs(hh,30,75,".12"),pbgA:hs(hh,14,11),pbgB:hs(hh,16,6),pbd:hs(hh,25,75,".12"),ptx:hs(hh,14,88),itm:hs(hh,10,62),itD:hs(hh,12,48),cctx:hs(hh,10,62),chipBg:hs(hh,18,55,".06"),hintC:hs(hh,8,42),hair1:hs(hh,42,62),hair2:hs(hh,28,40)};}
|
|
23
|
+
else if(kind==="soft"){v={bgA:hs(hh,28,21),bgB:hs(hh,30,10),edge:hs(hh,45,85,".22"),spec:"rgba(255,255,255,.2)",stI:hs(hh,16,58),stP:hs(hh,36,66),stA:hs(hh,80,70),stD:hs(hh,44,46),lbc:hs(hh,30,95),trk:hs(hh,45,85,".14"),pbgA:hs(hh,20,15),pbgB:hs(hh,24,9),pbd:hs(hh,40,85,".15"),ptx:hs(hh,24,93),itm:hs(hh,14,70),itD:hs(hh,16,56),cctx:hs(hh,14,70),chipBg:hs(hh,26,65,".08"),hintC:hs(hh,10,50),hair1:hs(hh,80,70),hair2:hs(hh,44,46)};}
|
|
24
|
+
else if(kind==="neutral"){v={bgA:hs(hh,7,18),bgB:hs(hh,8,7),edge:"rgba(255,255,255,.14)",spec:"rgba(255,255,255,.12)",stI:hs(hh,10,52),stP:hs(hh,28,60),stA:hs(hh,62,64),stD:hs(hh,38,42),lbc:hs(hh,10,93),trk:hs(hh,20,80,".12"),pbgA:hs(hh,6,12),pbgB:hs(hh,7,7),pbd:"rgba(255,255,255,.09)",ptx:hs(hh,8,90),itm:hs(hh,8,64),itD:hs(hh,10,50),cctx:hs(hh,8,64),chipBg:"rgba(255,255,255,.05)",hintC:hs(hh,6,42),hair1:hs(hh,62,64),hair2:hs(hh,38,42)};}
|
|
25
|
+
else{v={bgA:hs(hh,36,96),bgB:hs(hh,26,84),edge:hs(hh,30,22,".26"),spec:"rgba(255,255,255,.85)",hi:"rgba(255,255,255,.7)",stI:hs(hh,10,60),stP:hs(hh,26,44),stA:hs(hh,40,30),stD:hs(hh,28,40),lbc:hs(hh,25,20),trk:hs(hh,25,20,".14"),pbgA:hs(hh,45,97),pbgB:hs(hh,32,90),pbd:hs(hh,30,25,".15"),ptx:hs(hh,25,20),itm:hs(hh,12,40),itD:hs(hh,14,52),cctx:hs(hh,12,42),chipBg:hs(hh,25,25,".06"),hintC:hs(hh,10,55),hair1:hs(hh,40,30),hair2:hs(hh,28,40)};}
|
|
26
|
+
return v;
|
|
27
|
+
}
|
|
28
|
+
var EX={};
|
|
29
|
+
var EX_ORDER=[];
|
|
30
|
+
EX["01"]={no:"01",name:"曜石极光",en:"OBSIDIAN AURORA",group:"招牌特效",anim:"flashy",vars:{bgA:"#273049",bgB:"#090c15",edge:"rgba(255,255,255,.16)",spec:"rgba(255,255,255,.16)",hi:"rgba(255,255,255,.12)",lbc:"#f2f7ff",trk:"rgba(255,255,255,.1)",stI:"#8fa0b8",stP:"#6fb6ff",stA:"#ffb454",stD:"#34e39a",pbgA:"#171c2b",pbgB:"#0c0f18",pbd:"rgba(255,255,255,.09)",ptx:"#dfe7f3",itm:"#b6c6dd",itD:"#7d9c8d",cctx:"#b6c6dd",chipBg:"rgba(255,255,255,.06)",hintC:"#5f6b80",hair1:"#34e39a",hair2:"#7c6bff"},rim:"%RIM%{position:absolute;inset:-3px;border-radius:inherit;pointer-events:none;background:conic-gradient(from 0deg,transparent 0 68%,var(--stA) 86%,#fff 93%,transparent 100%);-webkit-mask:radial-gradient(farthest-side,transparent calc(100% - 3px),#000 calc(100% - 2px));mask:radial-gradient(farthest-side,transparent calc(100% - 3px),#000 calc(100% - 2px));filter:drop-shadow(0 0 6px var(--stA));opacity:.95;animation:dshSkinSpin 2.6s linear infinite}",band:"%BAND%{position:absolute;inset:0;border-radius:inherit;pointer-events:none;background:radial-gradient(circle at 50% 122%,var(--st) 0%,transparent 54%);opacity:.13}"};
|
|
31
|
+
EX_ORDER.push("01");
|
|
32
|
+
EX["02"]={no:"02",name:"赛博机能",en:"CYBER CIRCUIT",group:"招牌特效",anim:"flashy",vars:{bgA:"#0d1b2e",bgB:"#04080f",edge:"rgba(0,229,255,.4)",spec:"rgba(255,255,255,.16)",hi:"rgba(255,255,255,.12)",lbc:"#c9e7f5",trk:"rgba(255,255,255,.1)",stI:"#4f7b95",stP:"#00e5ff",stA:"#ff2d95",stD:"#00ff9d",pbgA:"#0a1622",pbgB:"#050b12",pbd:"rgba(0,229,255,.24)",ptx:"#c9e7f5",itm:"#9fc3d8",itD:"#5f9a85",cctx:"#9fc3d8",chipBg:"rgba(0,229,255,.06)",hintC:"#4f7b95",hair1:"#00e5ff",hair2:"#ff2d95"},rim:"%RIM%{position:absolute;inset:-2px;border-radius:inherit;pointer-events:none;border:1px dashed var(--stP);animation:dshSkinSpin 6s linear infinite}",band:"%BAND%{position:absolute;inset:0;border-radius:inherit;pointer-events:none;background:repeating-linear-gradient(0deg,rgba(0,229,255,.07) 0 1px,transparent 1px 3px)}"};
|
|
33
|
+
EX_ORDER.push("02");
|
|
34
|
+
EX["03"]={no:"03",name:"等离子核心",en:"PLASMA CORE",group:"招牌特效",anim:"flashy",vars:{bgA:"#2a1210",bgB:"#0d0403",edge:"rgba(255,140,60,.4)",spec:"rgba(255,255,255,.16)",hi:"rgba(255,255,255,.12)",lbc:"#f5e3d5",trk:"rgba(255,255,255,.1)",stI:"#8a5a4a",stP:"#ffa23d",stA:"#ff5c2b",stD:"#ffd23d",pbgA:"#1c0e0a",pbgB:"#0c0504",pbd:"rgba(255,140,60,.22)",ptx:"#f5e3d5",itm:"#c8a795",itD:"#96826e",cctx:"#c8a795",chipBg:"rgba(255,140,60,.07)",hintC:"#8a5a4a",hair1:"#ff9a3d",hair2:"#ff3d81"},rim:"%RIM%{position:absolute;inset:-1px;border-radius:inherit;pointer-events:none;background:conic-gradient(from 40deg,rgba(255,154,61,0),#ff9a3d,#ff3d81,#3d9aff,rgba(61,154,255,0) 82%);-webkit-mask:radial-gradient(farthest-side,transparent calc(100% - 3px),#000 calc(100% - 1px));mask:radial-gradient(farthest-side,transparent calc(100% - 3px),#000 calc(100% - 1px));filter:blur(2.5px);animation:dshSkinSpin 3s linear infinite}"};
|
|
35
|
+
EX_ORDER.push("03");
|
|
36
|
+
EX["04"]={no:"04",name:"全息幻彩",en:"HOLOGRAPHIC",group:"招牌特效",anim:"flashy",vars:{bgA:"#b8a6f5",bgB:"#6ec6ee",edge:"rgba(255,255,255,.65)",spec:"rgba(255,255,255,.5)",hi:"rgba(255,255,255,.6)",lbc:"#241d4f",trk:"rgba(36,29,79,.2)",stI:"#7c86a8",stP:"#6a5df0",stA:"#e0559f",stD:"#0fae84",pbgA:"#f2f0ff",pbgB:"#e2e8ff",pbd:"rgba(106,93,240,.28)",ptx:"#2a2547",itm:"#4a5470",itD:"#57806c",cctx:"#4a5470",chipBg:"rgba(106,93,240,.08)",hintC:"#7a7fa0",hair1:"#e0559f",hair2:"#6a5df0"},rim:"%RIM%{position:absolute;inset:-3px;border-radius:inherit;pointer-events:none;background:conic-gradient(from 0deg,#ff9ad5,#ffd1a1,#a1ffd1,#9ad5ff,#b89aff,#ff9ad5);-webkit-mask:radial-gradient(farthest-side,transparent calc(100% - 2px),#000 calc(100% - 1px));mask:radial-gradient(farthest-side,transparent calc(100% - 2px),#000 calc(100% - 1px));filter:blur(3px);opacity:.8;animation:dshSkinSpin 9s linear infinite}",band:"%BAND%{position:absolute;inset:3px 4px 55% 4px;border-radius:inherit;pointer-events:none;background:linear-gradient(rgba(255,255,255,.7),rgba(255,255,255,.05));filter:blur(.5px)}"};
|
|
37
|
+
EX_ORDER.push("04");
|
|
38
|
+
EX["05"]={no:"05",name:"量子矩阵",en:"QUANTUM MATRIX",group:"招牌特效",anim:"flashy",vars:{bgA:"#0c1f12",bgB:"#020804",edge:"rgba(0,255,136,.4)",spec:"rgba(255,255,255,.16)",hi:"rgba(255,255,255,.12)",lbc:"#c9f5d9",trk:"rgba(255,255,255,.1)",stI:"#4f8a63",stP:"#27e584",stA:"#a3ff12",stD:"#00ff9d",pbgA:"#05130a",pbgB:"#020a05",pbd:"rgba(0,255,136,.25)",ptx:"#c9f5d9",itm:"#8fc7a5",itD:"#5f9a78",cctx:"#8fc7a5",chipBg:"rgba(0,255,136,.06)",hintC:"#4f8a63",hair1:"#27e584",hair2:"#a3ff12"},rim:"%RIM%{position:absolute;inset:-2px;border-radius:inherit;pointer-events:none;border:1px dashed rgba(0,255,136,.5);animation:dshSkinSpinR 5s linear infinite}",band:"%BAND%{position:absolute;inset:4px;border-radius:inherit;pointer-events:none;background-image:radial-gradient(rgba(0,255,136,.55) 1px,transparent 1.4px);background-size:7px 7px;-webkit-mask:radial-gradient(circle,#000 0 62%,transparent 74%);mask:radial-gradient(circle,#000 0 62%,transparent 74%);opacity:.5}"};
|
|
39
|
+
EX_ORDER.push("05");
|
|
40
|
+
EX["06"]={no:"06",name:"星环",en:"STAR HALO",group:"招牌特效",anim:"flashy",vars:{bgA:"#131a33",bgB:"#05070f",edge:"rgba(186,160,255,.35)",spec:"rgba(255,255,255,.16)",hi:"rgba(255,255,255,.12)",lbc:"#e2dcff",trk:"rgba(255,255,255,.1)",stI:"#7d86a8",stP:"#8f9fff",stA:"#ffc46e",stD:"#b28bff",pbgA:"#101527",pbgB:"#070a14",pbd:"rgba(150,130,255,.22)",ptx:"#e2dcff",itm:"#a99cd0",itD:"#8678b0",cctx:"#a99cd0",chipBg:"rgba(150,130,255,.07)",hintC:"#7d86a8",hair1:"#8f9fff",hair2:"#b28bff"},rim:"%RIM%{position:absolute;inset:-7px -15px;border-radius:50%;pointer-events:none;border:1.5px solid rgba(186,160,255,.65);transform:rotate(-16deg) scaleY(.42);box-shadow:0 0 10px rgba(150,120,255,.45),inset 0 0 6px rgba(150,120,255,.3)}",band:"%BAND%{position:absolute;inset:0;border-radius:inherit;pointer-events:none;background-image:radial-gradient(rgba(255,255,255,.8) 1px,transparent 1.3px),radial-gradient(rgba(186,160,255,.7) .8px,transparent 1.1px);background-size:21px 19px,13px 17px;background-position:4px 6px,9px 12px;opacity:.5;-webkit-mask:radial-gradient(circle,#000 0 55%,transparent 72%);mask:radial-gradient(circle,#000 0 55%,transparent 72%)}"};
|
|
41
|
+
EX_ORDER.push("06");
|
|
42
|
+
EX["07"]={no:"07",name:"熔岩核心",en:"MAGMA CORE",group:"招牌特效",anim:"flashy",vars:{bgA:"#1d0f0a",bgB:"#0a0403",edge:"rgba(255,110,40,.4)",spec:"rgba(255,255,255,.16)",hi:"rgba(255,255,255,.12)",lbc:"#f5ded0",trk:"rgba(255,255,255,.1)",stI:"#7d5648",stP:"#ff8a3d",stA:"#ff4d1f",stD:"#ffbe3d",pbgA:"#170d09",pbgB:"#0b0504",pbd:"rgba(255,110,40,.22)",ptx:"#f5ded0",itm:"#c8a48e",itD:"#96826e",cctx:"#c8a48e",chipBg:"rgba(255,110,40,.07)",hintC:"#7d5648",hair1:"#ff6b2b",hair2:"#ffbe3d"},band:"%BAND%{position:absolute;inset:2px;border-radius:inherit;pointer-events:none;background:repeating-conic-gradient(from 12deg,transparent 0 26deg,rgba(255,110,40,.6) 26deg 29deg);-webkit-mask:radial-gradient(circle,transparent 0 46%,#000 60% 78%,transparent 88%);mask:radial-gradient(circle,transparent 0 46%,#000 60% 78%,transparent 88%);opacity:.75}"};
|
|
43
|
+
EX_ORDER.push("07");
|
|
44
|
+
EX["08"]={no:"08",name:"极地冰川",en:"GLACIER",group:"招牌特效",anim:"flashy",vars:{bgA:"#dff0fa",bgB:"#9fc8e8",edge:"rgba(255,255,255,.78)",spec:"rgba(255,255,255,.75)",hi:"rgba(255,255,255,.7)",lbc:"#123247",trk:"rgba(20,60,90,.18)",stI:"#6f8ba5",stP:"#2f9dd8",stA:"#f06a5d",stD:"#0fa878",pbgA:"#eef7fd",pbgB:"#d8ecf8",pbd:"rgba(60,120,170,.3)",ptx:"#14344a",itm:"#3f5f7a",itD:"#4a7a63",cctx:"#3f5f7a",chipBg:"rgba(30,80,120,.07)",hintC:"#5b7d96",hair1:"#2f9dd8",hair2:"#0fa878"},band:"%BAND%{position:absolute;inset:2px;border-radius:inherit;pointer-events:none;background-image:radial-gradient(rgba(255,255,255,.95) 1px,transparent 1.5px);background-size:15px 13px;background-position:3px 4px;opacity:.8;-webkit-mask:radial-gradient(circle,#000 0 58%,transparent 75%);mask:radial-gradient(circle,#000 0 58%,transparent 75%)}"};
|
|
45
|
+
EX_ORDER.push("08");
|
|
46
|
+
EX["09"]={no:"09",name:"霓虹脉搏",en:"NEON PULSE",group:"招牌特效",anim:"flashy",vars:{bgA:"#10101f",bgB:"#05050c",edge:"rgba(255,45,149,.5)",spec:"rgba(255,255,255,.16)",hi:"rgba(255,255,255,.12)",lbc:"#f0d9ec",trk:"rgba(255,255,255,.1)",stI:"#5a5a7d",stP:"#00c8ff",stA:"#ff2d95",stD:"#00ff9d",pbgA:"#0d0d1a",pbgB:"#060609",pbd:"rgba(255,45,149,.3)",ptx:"#f0d9ec",itm:"#b893c9",itD:"#7d9c8d",cctx:"#b893c9",chipBg:"rgba(255,45,149,.07)",hintC:"#8b8bb0",hair1:"#ff2d95",hair2:"#00c8ff"},rim:"%RIM%{position:absolute;inset:-7px;border-radius:inherit;pointer-events:none;border:1px solid rgba(0,200,255,.3)}",extra:"%B%{box-shadow:inset 0 1px 0 rgba(255,255,255,.14),0 5px 14px rgba(0,0,0,.5),0 0 12px var(--st),0 0 0 1px var(--st) inset!important}"};
|
|
47
|
+
EX_ORDER.push("09");
|
|
48
|
+
EX["10"]={no:"10",name:"机械核心",en:"MECH CORE",group:"招牌特效",anim:"flashy",vars:{bgA:"#262b33",bgB:"#0e1116",edge:"rgba(255,176,32,.45)",spec:"rgba(255,255,255,.16)",hi:"rgba(255,255,255,.12)",lbc:"#dde3ec",trk:"rgba(255,255,255,.1)",stI:"#6f7a88",stP:"#58a6ff",stA:"#ffb020",stD:"#3fd68a",pbgA:"#171b22",pbgB:"#0c0f14",pbd:"rgba(255,176,32,.22)",ptx:"#dde3ec",itm:"#9aa5b3",itD:"#7d9c8d",cctx:"#9aa5b3",chipBg:"rgba(255,176,32,.06)",hintC:"#6f7a88",hair1:"#ffb020",hair2:"#58a6ff"},rim:"%RIM%{position:absolute;inset:-4px;border-radius:inherit;pointer-events:none;background:repeating-conic-gradient(from 0deg,rgba(255,176,32,.55) 0 7deg,transparent 7deg 24deg);-webkit-mask:radial-gradient(farthest-side,transparent calc(100% - 3.5px),#000 calc(100% - 2px));mask:radial-gradient(farthest-side,transparent calc(100% - 3.5px),#000 calc(100% - 2px));animation:dshSkinSpinR 11s linear infinite}",band:"%BAND%{position:absolute;inset:-1px;border-radius:inherit;pointer-events:none;background:radial-gradient(circle at 50% 4%,rgba(255,255,255,.7) 1.2px,transparent 1.8px),radial-gradient(circle at 50% 96%,rgba(255,255,255,.7) 1.2px,transparent 1.8px),radial-gradient(circle at 4% 50%,rgba(255,255,255,.7) 1.2px,transparent 1.8px),radial-gradient(circle at 96% 50%,rgba(255,255,255,.7) 1.2px,transparent 1.8px);opacity:.6}"};
|
|
49
|
+
EX_ORDER.push("10");
|
|
50
|
+
EX["11"]={no:"11",name:"暗物质",en:"DARK MATTER",group:"招牌特效",anim:"flashy",vars:{bgA:"#100a1f",bgB:"#030109",edge:"rgba(160,110,255,.4)",spec:"rgba(255,255,255,.16)",hi:"rgba(255,255,255,.12)",lbc:"#e4d9ff",trk:"rgba(255,255,255,.1)",stI:"#5f5480",stP:"#9d6bff",stA:"#d05cff",stD:"#7af0ff",pbgA:"#120c20",pbgB:"#070310",pbd:"rgba(160,110,255,.25)",ptx:"#e4d9ff",itm:"#a99cc9",itD:"#7d9c8d",cctx:"#a99cc9",chipBg:"rgba(160,110,255,.07)",hintC:"#9082b3",hair1:"#d05cff",hair2:"#7af0ff"},rim:"%RIM%{position:absolute;inset:-2px;border-radius:inherit;pointer-events:none;background:conic-gradient(from 90deg,transparent 0 30%,rgba(208,92,255,.9) 52%,rgba(122,240,255,.7) 68%,transparent 88%);-webkit-mask:radial-gradient(farthest-side,transparent calc(100% - 4px),#000 calc(100% - 1px));mask:radial-gradient(farthest-side,transparent calc(100% - 4px),#000 calc(100% - 1px));filter:blur(1.5px);animation:dshSkinSpin 2.2s linear infinite}",band:"%BAND%{position:absolute;inset:9px;border-radius:inherit;pointer-events:none;background:radial-gradient(circle,#000 0 55%,rgba(122,240,255,.25) 78%,transparent)}"};
|
|
51
|
+
EX_ORDER.push("11");
|
|
52
|
+
EX["12"]={no:"12",name:"粒子星云",en:"PARTICLE NEBULA",group:"招牌特效",anim:"flashy",vars:{bgA:"#1b1440",bgB:"#070516",edge:"rgba(200,140,255,.35)",spec:"rgba(255,255,255,.16)",hi:"rgba(255,255,255,.12)",lbc:"#e8def5",trk:"rgba(255,255,255,.1)",stI:"#7d72a8",stP:"#7fb0ff",stA:"#ff8ad0",stD:"#8affd0",pbgA:"#150f30",pbgB:"#090617",pbd:"rgba(170,130,255,.22)",ptx:"#e8def5",itm:"#b0a3cc",itD:"#7d9c8d",cctx:"#b0a3cc",chipBg:"rgba(170,130,255,.07)",hintC:"#7d72a8",hair1:"#ff8ad0",hair2:"#7fb0ff"},band:"%BAND%{position:absolute;inset:0;border-radius:inherit;pointer-events:none;background-image:radial-gradient(rgba(255,138,208,.9) 1.1px,transparent 1.6px),radial-gradient(rgba(127,176,255,.85) .9px,transparent 1.4px),radial-gradient(rgba(255,255,255,.9) .8px,transparent 1.2px);background-size:19px 17px,14px 21px,23px 13px;background-position:5px 7px,11px 14px,2px 16px;opacity:.75;-webkit-mask:radial-gradient(circle,#000 0 56%,transparent 74%);mask:radial-gradient(circle,#000 0 56%,transparent 74%)}"};
|
|
53
|
+
EX_ORDER.push("12");
|
|
54
|
+
EX["13"]={no:"13",name:"流体渐变",en:"FLUID GRADIENT",group:"招牌特效",anim:"flashy",vars:{bgA:"#7c5cf0",bgB:"#2a1a5e",edge:"rgba(255,255,255,.32)",spec:"rgba(255,255,255,.4)",hi:"rgba(255,255,255,.12)",lbc:"#f2edff",trk:"rgba(255,255,255,.1)",stI:"#8f86b8",stP:"#4dd8ff",stA:"#ff7ab0",stD:"#4dffc0",pbgA:"#151033",pbgB:"#0a0720",pbd:"rgba(180,150,255,.25)",ptx:"#ece4ff",itm:"#b3a6d9",itD:"#7d9c8d",cctx:"#b3a6d9",chipBg:"rgba(180,150,255,.08)",hintC:"#8f86b8",hair1:"#4dd8ff",hair2:"#ff7ab0"},band:"%BAND%{position:absolute;inset:0;border-radius:inherit;pointer-events:none;background:radial-gradient(circle at 28% 68%,rgba(255,122,176,.55),transparent 55%),radial-gradient(circle at 74% 26%,rgba(77,216,255,.5),transparent 52%)}"};
|
|
55
|
+
EX_ORDER.push("13");
|
|
56
|
+
EX["14"]={no:"14",name:"黄金时代",en:"GOLDEN AGE",group:"招牌特效",anim:"flashy",vars:{bgA:"#241d0d",bgB:"#0c0904",edge:"rgba(255,215,0,.45)",spec:"rgba(255,255,255,.16)",hi:"rgba(255,255,255,.12)",lbc:"#ffefc4",trk:"rgba(255,255,255,.1)",stI:"#8a7a4f",stP:"#e6c34d",stA:"#ffb020",stD:"#58d68d",pbgA:"#16120a",pbgB:"#0a0805",pbd:"rgba(255,215,0,.28)",ptx:"#f2e6c8",itm:"#c2b48c",itD:"#7d9c8d",cctx:"#c2b48c",chipBg:"rgba(255,215,0,.06)",hintC:"#8a7a4f",hair1:"#ffd700",hair2:"#e6c34d"},band:"%BAND%{position:absolute;inset:0;border-radius:inherit;pointer-events:none;background:linear-gradient(115deg,transparent 30%,rgba(255,236,170,.75) 47%,rgba(255,255,255,.9) 50%,rgba(255,236,170,.75) 53%,transparent 70%);background-size:260% 100%;background-position:118% 0;-webkit-mask:radial-gradient(circle,#000 0 62%,transparent 78%);mask:radial-gradient(circle,#000 0 62%,transparent 78%)}"};
|
|
57
|
+
EX_ORDER.push("14");
|
|
58
|
+
EX["15"]={no:"15",name:"蒸汽波",en:"VAPORWAVE",group:"招牌特效",anim:"flashy",vars:{bgA:"#2b1140",bgB:"#0d0518",edge:"rgba(255,94,200,.5)",spec:"rgba(255,255,255,.16)",hi:"rgba(255,255,255,.12)",lbc:"#f5dcf0",trk:"rgba(255,255,255,.1)",stI:"#7d5a95",stP:"#22d3ee",stA:"#ff5ec8",stD:"#3dffc8",pbgA:"#170b26",pbgB:"#0b0513",pbd:"rgba(255,94,200,.3)",ptx:"#f5dcf0",itm:"#c39cc9",itD:"#7d9c8d",cctx:"#c39cc9",chipBg:"rgba(255,94,200,.07)",hintC:"#7d5a95",hair1:"#ff5ec8",hair2:"#22d3ee"},band:"%BAND%{position:absolute;inset:2px 3px 52% 3px;border-radius:inherit;pointer-events:none;background:linear-gradient(rgba(255,150,220,.4),rgba(120,240,255,.08));filter:blur(.5px)}",extra:"%B%{box-shadow:inset 0 1px 0 rgba(255,255,255,.14),0 5px 14px rgba(0,0,0,.5),-4px -4px 16px rgba(255,94,200,.45),4px 4px 16px rgba(34,211,238,.45)!important}"};
|
|
59
|
+
EX_ORDER.push("15");
|
|
60
|
+
EX["16"]={no:"16",name:"战术HUD",en:"TACTICAL HUD",group:"招牌特效",anim:"flashy",vars:{bgA:"#0f1a12",bgB:"#050b07",edge:"rgba(74,222,128,.45)",spec:"rgba(255,255,255,.16)",hi:"rgba(255,255,255,.12)",lbc:"#d2f5dc",trk:"rgba(255,255,255,.1)",stI:"#5a7d66",stP:"#4ade80",stA:"#a3e635",stD:"#34e39a",pbgA:"#0c1710",pbgB:"#060d08",pbd:"rgba(74,222,128,.28)",ptx:"#d2f5dc",itm:"#8fb89c",itD:"#5f9a78",cctx:"#8fb89c",chipBg:"rgba(74,222,128,.06)",hintC:"#5a7d66",hair1:"#4ade80",hair2:"#a3e635"},rim:"%RIM%{position:absolute;inset:-5px;border-radius:inherit;pointer-events:none;background:repeating-conic-gradient(from 0deg,rgba(74,222,128,.5) 0 2deg,transparent 2deg 15deg);-webkit-mask:radial-gradient(farthest-side,transparent calc(100% - 2.5px),#000 calc(100% - 1px));mask:radial-gradient(farthest-side,transparent calc(100% - 2.5px),#000 calc(100% - 1px));animation:dshSkinSpin 14s linear infinite}",band:"%BAND%{position:absolute;inset:7px;border-radius:inherit;pointer-events:none;background:linear-gradient(rgba(74,222,128,.55),rgba(74,222,128,.55)) 50% 0/1px 7px no-repeat,linear-gradient(rgba(74,222,128,.55),rgba(74,222,128,.55)) 50% 100%/1px 7px no-repeat,linear-gradient(rgba(74,222,128,.55),rgba(74,222,128,.55)) 0 50%/7px 1px no-repeat,linear-gradient(rgba(74,222,128,.55),rgba(74,222,128,.55)) 100% 50%/7px 1px no-repeat;opacity:.7}"};
|
|
61
|
+
EX_ORDER.push("16");
|
|
62
|
+
EX["17"]={no:"17",name:"方块像素",en:"PIXEL QUEST",group:"招牌特效",anim:"flashy",vars:{bgA:"#3b4268",bgB:"#24283d",edge:"#0f1120",spec:"rgba(255,255,255,.22)",hi:"rgba(255,255,255,.1)",lbc:"#dfe4ff",trk:"rgba(16,18,31,.8)",stI:"#8a90b8",stP:"#41a6f6",stA:"#ffcd75",stD:"#38b764",pbgA:"#2a2f4a",pbgB:"#1a1d33",pbd:"rgba(15,17,32,.9)",ptx:"#dfe4ff",itm:"#9aa3cc",itD:"#7d9c8d",cctx:"#9aa3cc",chipBg:"rgba(255,255,255,.06)",hintC:"#9aa3c2",hair1:"#ffcd75",hair2:"#41a6f6"},extra:"%B%{border-radius:10px!important;box-shadow:inset 0 0 0 1px rgba(255,255,255,.1),5px 5px 0 rgba(0,0,0,.55),0 0 0 1px var(--edge)!important;font-family:Consolas,monospace!important}"};
|
|
63
|
+
EX_ORDER.push("17");
|
|
64
|
+
EX["18"]={no:"18",name:"磁悬浮轨道",en:"MAGLEV ORBIT",group:"招牌特效",anim:"flashy",vars:{bgA:"#141a24",bgB:"#070a10",edge:"rgba(90,209,230,.4)",spec:"rgba(255,255,255,.16)",hi:"rgba(255,255,255,.12)",lbc:"#d8ecf2",trk:"rgba(255,255,255,.1)",stI:"#5f7a88",stP:"#5ad1e6",stA:"#ffb454",stD:"#34e39a",pbgA:"#121822",pbgB:"#080c12",pbd:"rgba(90,209,230,.25)",ptx:"#d8ecf2",itm:"#96b5c2",itD:"#7d9c8d",cctx:"#96b5c2",chipBg:"rgba(90,209,230,.06)",hintC:"#5f7a88",hair1:"#5ad1e6",hair2:"#34e39a"},rim:"%RIM%{position:absolute;inset:-7px -15px;border-radius:50%;pointer-events:none;border:1.3px solid rgba(90,209,230,.7);transform:rotateX(66deg) rotate(-18deg);box-shadow:0 0 9px rgba(90,209,230,.4)}",band:"%BAND%{position:absolute;inset:-7px -15px;border-radius:50%;pointer-events:none;border:1.3px solid rgba(52,227,154,.55);transform:rotateX(66deg) rotate(52deg);box-shadow:0 0 9px rgba(52,227,154,.35)}"};
|
|
65
|
+
EX_ORDER.push("18");
|
|
66
|
+
EX["19"]={no:"19",name:"太阳风暴",en:"SOLAR FLARE",group:"招牌特效",anim:"flashy",vars:{bgA:"#2a1a08",bgB:"#0f0803",edge:"rgba(255,220,120,.5)",spec:"rgba(255,255,255,.16)",hi:"rgba(255,255,255,.12)",lbc:"#f8ecd2",trk:"rgba(255,255,255,.1)",stI:"#9a835a",stP:"#ffd23d",stA:"#ff9a1f",stD:"#ffe98a",pbgA:"#1c1206",pbgB:"#0d0803",pbd:"rgba(255,210,110,.28)",ptx:"#f8ecd2",itm:"#c9b491",itD:"#9a8a68",cctx:"#c9b491",chipBg:"rgba(255,210,110,.07)",hintC:"#9a835a",hair1:"#ffd23d",hair2:"#ff9a1f"},rim:"%RIM%{position:absolute;inset:-8px;border-radius:inherit;pointer-events:none;background:repeating-conic-gradient(from 0deg,rgba(255,220,120,.4) 0 4deg,transparent 4deg 16deg);-webkit-mask:radial-gradient(farthest-side,transparent calc(100% - 7px),#000 calc(100% - 3px),#000 calc(100% - 1px),transparent 100%);mask:radial-gradient(farthest-side,transparent calc(100% - 7px),#000 calc(100% - 3px),#000 calc(100% - 1px),transparent 100%);filter:blur(.6px);animation:dshSkinSpin 16s linear infinite}",band:"%BAND%{position:absolute;inset:0;border-radius:inherit;pointer-events:none;background:radial-gradient(circle at 50% 62%,rgba(255,240,180,.5) 0%,transparent 52%)}"};
|
|
67
|
+
EX_ORDER.push("19");
|
|
68
|
+
EX["20"]={no:"20",name:"深海荧光",en:"ABYSS BIOLUM",group:"招牌特效",anim:"flashy",vars:{bgA:"#06222a",bgB:"#02090c",edge:"rgba(45,212,191,.4)",spec:"rgba(255,255,255,.16)",hi:"rgba(255,255,255,.12)",lbc:"#d2f2ee",trk:"rgba(255,255,255,.1)",stI:"#4f7d7a",stP:"#2dd4bf",stA:"#b26bff",stD:"#5dffb0",pbgA:"#062026",pbgB:"#030c10",pbd:"rgba(45,212,191,.25)",ptx:"#d2f2ee",itm:"#8fc0ba",itD:"#5f9a85",cctx:"#8fc0ba",chipBg:"rgba(45,212,191,.06)",hintC:"#4f7d7a",hair1:"#2dd4bf",hair2:"#5dffb0"},band:"%BAND%{position:absolute;inset:0;border-radius:inherit;pointer-events:none;background-image:radial-gradient(rgba(93,255,214,.95) 1.2px,transparent 1.7px),radial-gradient(rgba(178,107,255,.85) 1px,transparent 1.5px),radial-gradient(rgba(93,220,255,.8) .9px,transparent 1.4px);background-size:17px 19px,13px 15px,21px 12px;background-position:4px 8px,10px 3px,15px 14px;opacity:.8;-webkit-mask:radial-gradient(circle,#000 0 54%,transparent 74%);mask:radial-gradient(circle,#000 0 54%,transparent 74%)}"};
|
|
69
|
+
EX_ORDER.push("20");
|
|
70
|
+
EX["21"]={no:"21",name:"墨玉",en:"INK JADE",group:"克制精选",anim:"calm",vars:{bgA:"#22302e",bgB:"#0b1211",edge:"rgba(190,225,215,.2)",spec:"rgba(255,255,255,.16)",hi:"rgba(255,255,255,.12)",lbc:"#dcf2ec",trk:"rgba(190,225,215,.14)",stI:"#5f7a74",stP:"#79a49a",stA:"#4fe0c0",stD:"#2a9d84",pbgA:"#141f1d",pbgB:"#0a100f",pbd:"rgba(190,225,215,.14)",ptx:"#d9ece7",itm:"#9db3ad",itD:"#6f938a",cctx:"#9db3ad",chipBg:"rgba(190,225,215,.07)",hintC:"#5f7a74",hair1:"#4fe0c0",hair2:"#2a9d84"},band:"%BAND%{position:absolute;inset:0;border-radius:inherit;pointer-events:none;background:radial-gradient(circle at 50% 122%,var(--st) 0%,transparent 54%);opacity:.13}"};
|
|
71
|
+
EX_ORDER.push("21");
|
|
72
|
+
EX["22"]={no:"22",name:"石墨极简",en:"GRAPHITE MONO",group:"克制精选",anim:"calm",vars:{bgA:"#262b33",bgB:"#101319",edge:"rgba(255,255,255,.14)",spec:"rgba(255,255,255,.16)",hi:"rgba(255,255,255,.12)",lbc:"#eef1f6",trk:"rgba(255,255,255,.1)",stI:"#6b7480",stP:"#9aa2ad",stA:"#e8edf2",stD:"#ffffff",pbgA:"#181c23",pbgB:"#0d1015",pbd:"rgba(255,255,255,.09)",ptx:"#e2e7ee",itm:"#9aa4b0",itD:"#7d8792",cctx:"#9aa4b0",chipBg:"rgba(255,255,255,.05)",hintC:"#67707f",hair1:"#e8edf2",hair2:"#6b7480"},band:"%BAND%{position:absolute;inset:0;border-radius:inherit;pointer-events:none;background:radial-gradient(circle at 50% 122%,var(--st) 0%,transparent 54%);opacity:.13}"};
|
|
73
|
+
EX_ORDER.push("22");
|
|
74
|
+
EX["23"]={no:"23",name:"暮蓝",en:"DUSK BLUE",group:"克制精选",anim:"calm",vars:{bgA:"#1e2836",bgB:"#0b0f18",edge:"rgba(170,195,230,.2)",spec:"rgba(255,255,255,.16)",hi:"rgba(255,255,255,.12)",lbc:"#dce6f4",trk:"rgba(170,195,230,.13)",stI:"#5d6b80",stP:"#8299b8",stA:"#9fc6f2",stD:"#5f86be",pbgA:"#141b26",pbgB:"#0a0e16",pbd:"rgba(170,195,230,.13)",ptx:"#d8e2f0",itm:"#9cafcc",itD:"#7288a6",cctx:"#9cafcc",chipBg:"rgba(170,195,230,.06)",hintC:"#5d6b80",hair1:"#9fc6f2",hair2:"#5f86be"},band:"%BAND%{position:absolute;inset:0;border-radius:inherit;pointer-events:none;background:radial-gradient(circle at 50% 122%,var(--st) 0%,transparent 54%);opacity:.13}"};
|
|
75
|
+
EX_ORDER.push("23");
|
|
76
|
+
EX["24"]={no:"24",name:"可可",en:"COCOA",group:"克制精选",anim:"calm",vars:{bgA:"#2b2019",bgB:"#120c08",edge:"rgba(224,190,150,.2)",spec:"rgba(255,255,255,.16)",hi:"rgba(255,255,255,.12)",lbc:"#f2e6d8",trk:"rgba(224,190,150,.13)",stI:"#7d6a5c",stP:"#ab8d70",stA:"#e0aa6e",stD:"#a87848",pbgA:"#1c1410",pbgB:"#0f0a07",pbd:"rgba(224,190,150,.13)",ptx:"#efe2d2",itm:"#bda892",itD:"#96826e",cctx:"#bda892",chipBg:"rgba(224,190,150,.06)",hintC:"#7d6a5c",hair1:"#e0aa6e",hair2:"#a87848"},band:"%BAND%{position:absolute;inset:0;border-radius:inherit;pointer-events:none;background:radial-gradient(circle at 50% 122%,var(--st) 0%,transparent 54%);opacity:.13}"};
|
|
77
|
+
EX_ORDER.push("24");
|
|
78
|
+
EX["25"]={no:"25",name:"雾灰哑光",en:"MATTE MIST",group:"克制精选",anim:"calm",vars:{bgA:"#2a2f36",bgB:"#161a20",edge:"rgba(200,210,222,.18)",spec:"rgba(255,255,255,.07)",hi:"rgba(255,255,255,.06)",lbc:"#e5eaf0",trk:"rgba(200,210,222,.12)",stI:"#67707c",stP:"#8b98a8",stA:"#bcc8d6",stD:"#8b9db2",pbgA:"#181c22",pbgB:"#0e1116",pbd:"rgba(200,210,222,.12)",ptx:"#dfe4ea",itm:"#9aa5b1",itD:"#7c8894",cctx:"#9aa5b1",chipBg:"rgba(200,210,222,.06)",hintC:"#67707c",hair1:"#bcc8d6",hair2:"#67707c"},band:"%BAND%{position:absolute;inset:0;border-radius:inherit;pointer-events:none;background:radial-gradient(circle at 50% 122%,var(--st) 0%,transparent 54%);opacity:.09}"};
|
|
79
|
+
EX_ORDER.push("25");
|
|
80
|
+
EX["26"]={no:"26",name:"苔原",en:"MOSS TUNDRA",group:"克制精选",anim:"calm",vars:{bgA:"#1c2a20",bgB:"#0a120c",edge:"rgba(180,215,185,.2)",spec:"rgba(255,255,255,.16)",hi:"rgba(255,255,255,.12)",lbc:"#ddeddd",trk:"rgba(180,215,185,.13)",stI:"#5d7a64",stP:"#86ad8c",stA:"#a4dca0",stD:"#4f9d68",pbgA:"#131f16",pbgB:"#0a110c",pbd:"rgba(180,215,185,.13)",ptx:"#dae9da",itm:"#9db8a0",itD:"#75967c",cctx:"#9db8a0",chipBg:"rgba(180,215,185,.06)",hintC:"#5d7a64",hair1:"#a4dca0",hair2:"#4f9d68"},band:"%BAND%{position:absolute;inset:0;border-radius:inherit;pointer-events:none;background:radial-gradient(circle at 50% 122%,var(--st) 0%,transparent 54%);opacity:.13}"};
|
|
81
|
+
EX_ORDER.push("26");
|
|
82
|
+
EX["27"]={no:"27",name:"烟紫",en:"DUSTY PLUM",group:"克制精选",anim:"calm",vars:{bgA:"#26202b",bgB:"#100b14",edge:"rgba(210,190,230,.2)",spec:"rgba(255,255,255,.16)",hi:"rgba(255,255,255,.12)",lbc:"#ebe2f4",trk:"rgba(210,190,230,.13)",stI:"#776b82",stP:"#9d8bb0",stA:"#c9aee6",stD:"#8a6cae",pbgA:"#171221",pbgB:"#0c0812",pbd:"rgba(210,190,230,.13)",ptx:"#e6ddf0",itm:"#a99bb8",itD:"#877799",cctx:"#a99bb8",chipBg:"rgba(210,190,230,.06)",hintC:"#776b82",hair1:"#c9aee6",hair2:"#8a6cae"},band:"%BAND%{position:absolute;inset:0;border-radius:inherit;pointer-events:none;background:radial-gradient(circle at 50% 122%,var(--st) 0%,transparent 54%);opacity:.13}"};
|
|
83
|
+
EX_ORDER.push("27");
|
|
84
|
+
EX["28"]={no:"28",name:"月白纸墨",en:"PAPER & INK",group:"克制精选",anim:"calm",vars:{bgA:"#f7f5ef",bgB:"#dcd8cd",edge:"rgba(60,55,45,.28)",spec:"rgba(255,255,255,.85)",hi:"rgba(255,255,255,.7)",lbc:"#2c2a24",trk:"rgba(60,55,45,.14)",stI:"#a09c92",stP:"#6e6a60",stA:"#33302a",stD:"#55524a",pbgA:"#faf9f5",pbgB:"#edeae1",pbd:"rgba(60,55,45,.16)",ptx:"#33302a",itm:"#6e6a60",itD:"#8b877d",cctx:"#6e6a60",chipBg:"rgba(60,55,45,.05)",hintC:"#8b877d",hair1:"#33302a",hair2:"#a09c92"},band:"%BAND%{position:absolute;inset:0;border-radius:inherit;pointer-events:none;background:radial-gradient(circle at 50% 122%,var(--st) 0%,transparent 54%);opacity:.13}"};
|
|
85
|
+
EX_ORDER.push("28");
|
|
86
|
+
var KIND_LABEL={deep:"浓郁深底",muted:"尘埃灰调",soft:"柔光深底",neutral:"中性点缀",light:"浅色纸面"};
|
|
87
|
+
var TINT="%BAND%{position:absolute;inset:0;border-radius:inherit;pointer-events:none;background:radial-gradient(circle at 50% 122%,var(--st) 0%,transparent 54%);opacity:.13}";
|
|
88
|
+
var ALL=[],BY_ID={};
|
|
89
|
+
(function build(){
|
|
90
|
+
EX_ORDER.forEach(function(id){var s=EX[id];s.id=id;s.kind="special";ALL.push(s);BY_ID[id]=s;});
|
|
91
|
+
var order=["deep","muted","soft","neutral","light"],no=28;
|
|
92
|
+
order.forEach(function(kind){
|
|
93
|
+
FORMULA[kind].forEach(function(row){
|
|
94
|
+
no++;var id=(no<100?"0":"")+String(no);
|
|
95
|
+
var s={id:id,no:id,name:row[0],en:row[1],kind:kind,group:KIND_LABEL[kind],anim:"calm",vars:varsFor(kind,row[2])};
|
|
96
|
+
if(!s.band)s.band=TINT;
|
|
97
|
+
ALL.push(s);BY_ID[id]=s;
|
|
98
|
+
});
|
|
99
|
+
});
|
|
100
|
+
})();
|
|
101
|
+
var KEY="dsh-ball-skin",DEFAULT_ID="01";
|
|
102
|
+
function getId(){try{var v=localStorage.getItem(KEY);if(v&&BY_ID[v])return v;}catch(e){}return DEFAULT_ID;}
|
|
103
|
+
function setSkin(id){
|
|
104
|
+
if(!BY_ID[id])return false;
|
|
105
|
+
try{localStorage.setItem(KEY,id);}catch(e){}
|
|
106
|
+
var hooks=window.__dshBallSkinHooks||[];
|
|
107
|
+
for(var i=0;i<hooks.length;i++){try{hooks[i](id,BY_ID[id]);}catch(e){}}
|
|
108
|
+
try{window.dispatchEvent(new CustomEvent("dsh-ball-skin-change",{detail:{id:id}}));}catch(e){}
|
|
109
|
+
return true;
|
|
110
|
+
}
|
|
111
|
+
function varsCss(sel,id){var s=BY_ID[id]||BY_ID[DEFAULT_ID];var out=sel+"{";
|
|
112
|
+
for(var k in s.vars){out+="--"+k+":"+s.vars[k]+";";}
|
|
113
|
+
return out+"}";}
|
|
114
|
+
function varsAll(sel){return varsCss(sel,getId());}
|
|
115
|
+
function fx(id,sel){var s=BY_ID[id]||BY_ID[DEFAULT_ID];var out=[];
|
|
116
|
+
if(s.rim)out.push(s.rim.split("%RIM%").join(sel.RIM));
|
|
117
|
+
if(s.band)out.push(s.band.split("%BAND%").join(sel.BAND));
|
|
118
|
+
if(s.extra)out.push(s.extra.split("%B%").join(sel.B));
|
|
119
|
+
return out.join("\n");}
|
|
120
|
+
function groups(){var g=[],seen={};ALL.forEach(function(s){if(!seen[s.group]){seen[s.group]=true;g.push(s.group);}});return g;}
|
|
121
|
+
window.__DSH_BALL_SKINS={ALL:ALL,BY_ID:BY_ID,getId:getId,setSkin:setSkin,varsCss:varsCss,varsAll:varsAll,fx:fx,groups:groups,KIND_LABEL:KIND_LABEL,KEY:KEY,DEFAULT_ID:DEFAULT_ID};
|
|
122
|
+
})();
|
|
123
|
+
|
|
124
|
+
// v1.5.5(2026-09-06):版本号对齐修复——host 端 index.js 的 VERSION
|
|
125
|
+
// 常量此前停在 1.5.1 未随 package.json 同步,现统一为 1.5.5。
|
|
126
|
+
// v1.7.0(2026-09-11):三功能升级——
|
|
127
|
+
// ① 技能卡片显示 SKILL.md 最新修改时间(yyyy-MM-dd HH:mm);
|
|
128
|
+
// ② 排序切换:按名称(默认)↔ 按修改时间降序(总清单与每个分类内);
|
|
129
|
+
// ③ 技能启用/停用:单技能开关 + 分类级全启用/全停用,走宿主
|
|
130
|
+
// POST /toggle 与 /toggle-batch(frontmatter disable-model-invocation
|
|
131
|
+
// 行级改写,SKILL.md 先自动备份),停用卡片灰显 + 徽章。
|
|
132
|
+
// v1.7.1(2026-09-11):操作反馈 UI 升级(用户实测反馈:开关无视觉状态、
|
|
133
|
+
// 操作无反馈,误点"全停用"80 个技能事后才发现)——
|
|
134
|
+
// ① 单技能开关换成滑动开关(胶囊轨道 34×18,开启=滑块右移+绿色#27ae60,
|
|
135
|
+
// 停用=滑块左移+灰色#555,transition .2s;状态按 skill.disabled 渲染,
|
|
136
|
+
// 点击乐观更新,API 失败回滚);
|
|
137
|
+
// ② 面板内右上角 toast 轻提示(2 秒自动消失,成功绿/失败红):单开关
|
|
138
|
+
// "已停用/已启用 <技能名>"、批量"已停用/启用 N 项"、部分失败
|
|
139
|
+
// "成功 X 项,失败 Y 项";批量进行中按钮显示"处理中…"防重入;
|
|
140
|
+
// ③ 排序升级四态循环:名称↑ → 名称↓ → 时间↓(最新在前)→ 时间↑(最旧在前),
|
|
141
|
+
// 单按钮显示当前态(SORT_ORDER 为唯一权威,legacy name/mtime 自动迁移)。
|
|
142
|
+
// v1.7.2(2026-09-11):三级滑块开关体系(样式统一胶囊滑块,聚合态半开样式)——
|
|
143
|
+
// ① 全局总开关(排序按钮旁,标签"全部技能"):状态=全部技能聚合
|
|
144
|
+
// (全启用→右绿 / 全停用→左灰 / 混合→居中半开 .dsb-sw-half + title"部分停用");
|
|
145
|
+
// 点击弹面板内确认菜单(非 window.confirm):"全部启用 (N 项)" /
|
|
146
|
+
// "全部停用 (N 项)" + 取消,停用项带醒目危险提示;确认后
|
|
147
|
+
// POST /toggle-batch body={dirs:[全量目录]}(不走 category,最稳)。
|
|
148
|
+
// ② 分类级滑块(替换 v1.7.0 排序栏内"全启用/全停用"两个按钮):小一号
|
|
149
|
+
// 胶囊滑块 + 小字"停用 x/y",聚合逻辑同全局;确认后
|
|
150
|
+
// POST /toggle-batch body={category:"<cat-id>"}。
|
|
151
|
+
// ③ 联动:任一层 toggle 成功后重算全局滑块 + 分类滑块 + 卡片
|
|
152
|
+
// (卡片走 patchCardsDisabled 局部更新类名/徽章,不整列表 innerHTML
|
|
153
|
+
// 重建,避免闪烁);聚合态唯一数据源 = S.data.skills 的 disabled 字段。
|
|
154
|
+
|
|
155
|
+
var S = {
|
|
156
|
+
mounted: false,
|
|
157
|
+
open: false,
|
|
158
|
+
panelBuilt: false,
|
|
159
|
+
view: "skills", // "skills" | "ledger"
|
|
160
|
+
data: null,
|
|
161
|
+
ledger: null,
|
|
162
|
+
ledgerDetail: null,
|
|
163
|
+
loading: false,
|
|
164
|
+
error: "",
|
|
165
|
+
cat: "all",
|
|
166
|
+
sub: "",
|
|
167
|
+
q: "",
|
|
168
|
+
detail: null,
|
|
169
|
+
sortMode: "name-asc", // v1.7.1 四态:"name-asc" | "name-desc" | "mtime-desc" | "mtime-asc"
|
|
170
|
+
toggling: false, // v1.7.0: toggle 请求进行中(防重复点击)
|
|
171
|
+
toastTimer: null, // v1.7.1: toast 自动消失定时器句柄
|
|
172
|
+
batchMenuScope: null // v1.7.2: 批量确认菜单当前作用域("global" 或分类 id)
|
|
173
|
+
};
|
|
174
|
+
|
|
175
|
+
// v1.7.1 排序四态循环的唯一权威定义(点击按钮沿数组循环)。
|
|
176
|
+
// asc=升序(旧/前→新/后,字符串 localeCompare、时间小→大),
|
|
177
|
+
// desc=降序(新在前/名称 Z→A)。
|
|
178
|
+
var SORT_ORDER = ["name-asc", "name-desc", "mtime-desc", "mtime-asc"];
|
|
179
|
+
function nextSortMode(m) {
|
|
180
|
+
var i = SORT_ORDER.indexOf(m);
|
|
181
|
+
if (i < 0) i = 0;
|
|
182
|
+
return SORT_ORDER[(i + 1) % SORT_ORDER.length];
|
|
183
|
+
}
|
|
184
|
+
// v1.7.0 老会话只存过 "name"/"mtime" 两态,读到旧值自动迁移到等价新态
|
|
185
|
+
function normalizeSortMode(m) {
|
|
186
|
+
if (m === "name") return "name-asc";
|
|
187
|
+
if (m === "mtime") return "mtime-desc";
|
|
188
|
+
return (SORT_ORDER.indexOf(m) >= 0) ? m : "name-asc";
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
// v1.7.1 文案兜底:优先用宿主 /skills 下发的 ui 常量(lib/zh.js UI_TEXT),
|
|
192
|
+
// 老宿主无该字段时用这里的同文兜底。
|
|
193
|
+
var UI_FALLBACK = {
|
|
194
|
+
sortByName: "按名称",
|
|
195
|
+
sortByMtime: "按修改时间",
|
|
196
|
+
sortToggleTitle: "切换排序方式(名称 ↔ 修改时间降序)",
|
|
197
|
+
mtimeLabel: "修改于",
|
|
198
|
+
disabledBadge: "已停用",
|
|
199
|
+
cardDisabledTitle: "已停用(模型技能目录中已摘除)· 点击卡片查看全文",
|
|
200
|
+
toggleEnableTip: "启用后技能恢复进模型技能目录",
|
|
201
|
+
toggleDisableTip: "停用后技能从模型技能目录摘除(SKILL.md 会先自动备份)",
|
|
202
|
+
batchEnable: "全启用",
|
|
203
|
+
batchDisable: "全停用",
|
|
204
|
+
batchBtnTitle: "对该分类下全部技能执行启用/停用",
|
|
205
|
+
batchConfirmDisable: "确定停用该分类下全部技能?(每个 SKILL.md 都会先自动备份,可再次全启用恢复)",
|
|
206
|
+
batchConfirmEnable: "确定启用该分类下全部技能?",
|
|
207
|
+
toggling: "执行中…",
|
|
208
|
+
toggleFailPrefix: "失败",
|
|
209
|
+
toggleDoneSuffix: "完成",
|
|
210
|
+
toggleEnable: "启用",
|
|
211
|
+
toggleDisable: "停用",
|
|
212
|
+
disabledCountSuffix: "项已停用",
|
|
213
|
+
// ── v1.7.1 新增:排序四态 / 滑动开关 / toast ──
|
|
214
|
+
sortNameAsc: "名称↑",
|
|
215
|
+
sortNameDesc: "名称↓",
|
|
216
|
+
sortMtimeDesc: "时间↓",
|
|
217
|
+
sortMtimeAsc: "时间↑",
|
|
218
|
+
sortCycleTitle: "排序(点击循环):名称↑ → 名称↓ → 时间↓(最新在前)→ 时间↑(最旧在前)",
|
|
219
|
+
switchOnText: "开",
|
|
220
|
+
switchOffText: "关",
|
|
221
|
+
toastDisabled: "已停用 {name}",
|
|
222
|
+
toastEnabled: "已启用 {name}",
|
|
223
|
+
toastBatchDisabled: "已停用 {n} 项",
|
|
224
|
+
toastBatchEnabled: "已启用 {n} 项",
|
|
225
|
+
toastBatchPartial: "成功 {x} 项,失败 {y} 项",
|
|
226
|
+
toastToggleFail: "操作失败:{err}",
|
|
227
|
+
processingText: "处理中…",
|
|
228
|
+
// ── v1.7.2 新增:三级滑块开关(全局总开关 / 分类聚合滑块 / 确认菜单)──
|
|
229
|
+
aggAllLabel: "全部技能",
|
|
230
|
+
aggMixedTitle: "部分停用(已停用 {x}/{y})· 点击选择批量启停",
|
|
231
|
+
aggAllOnTitle: "全部启用 · 点击选择批量启停",
|
|
232
|
+
aggAllOffTitle: "全部停用 · 点击选择批量启停",
|
|
233
|
+
aggEnableN: "全部启用 ({n} 项)",
|
|
234
|
+
aggDisableN: "全部停用 ({n} 项)",
|
|
235
|
+
aggDangerText: "将停用全部 {n} 项技能,新会话将不可用这些技能",
|
|
236
|
+
aggMenuTitleGlobal: "全局批量启停 — 作用于技能库全部技能",
|
|
237
|
+
aggMenuTitleCat: "分类批量启停 — 仅作用于当前分类",
|
|
238
|
+
aggMenuStat: "{scope} · 共 {n} 项 · 已停用 {x} 项",
|
|
239
|
+
aggCatStat: "停用 {x}/{y}",
|
|
240
|
+
aggCancelText: "取消"
|
|
241
|
+
};
|
|
242
|
+
function T(key) {
|
|
243
|
+
var ui = (S.data && S.data.ui) || null;
|
|
244
|
+
return (ui && typeof ui[key] === "string" && ui[key]) || UI_FALLBACK[key] || key;
|
|
245
|
+
}
|
|
246
|
+
// v1.7.1 简易占位替换(字符串模板 {name}/{n}/{x}/{y}/{err}),纯 JS 实现
|
|
247
|
+
function TF(key, vars) {
|
|
248
|
+
var t = T(key) || "";
|
|
249
|
+
vars = vars || {};
|
|
250
|
+
for (var k in vars) {
|
|
251
|
+
if (Object.prototype.hasOwnProperty.call(vars, k)) {
|
|
252
|
+
t = String(t).split("{" + k + "}").join(String(vars[k]));
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
return t;
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
var BALL_ID = "dsh-skill-browser-ball";
|
|
259
|
+
var PANEL_ID = "dsh-skill-browser-panel";
|
|
260
|
+
var GHOST_KEY = "dsh-skill-browser-ghost";
|
|
261
|
+
var BALL_POS_KEY = "dsh-skill-browser-ball-pos";
|
|
262
|
+
var BALL_VIS_KEY = "dsh-skill-browser-ball-visible";
|
|
263
|
+
var FONT_BALL_VIS_KEY = "dsh-font-ball-visible";
|
|
264
|
+
var TODO_BALL_VIS_KEY = "dsh-tfb-ball-visible";
|
|
265
|
+
|
|
266
|
+
// ---- helpers ----
|
|
267
|
+
function esc(s) {
|
|
268
|
+
return String(s == null ? "" : s)
|
|
269
|
+
.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """);
|
|
270
|
+
}
|
|
271
|
+
function $(id) { return document.getElementById(id); }
|
|
272
|
+
function apiBase() { return "/dsh-skill-browser"; }
|
|
273
|
+
function mountEl() { return document.documentElement || document.body; }
|
|
274
|
+
|
|
275
|
+
function catMeta(id) {
|
|
276
|
+
if (!S.data) return null;
|
|
277
|
+
var cs = S.data.categories || [];
|
|
278
|
+
for (var i = 0; i < cs.length; i++) if (cs[i].id === id) return cs[i];
|
|
279
|
+
return null;
|
|
280
|
+
}
|
|
281
|
+
function catLabel(id) {
|
|
282
|
+
if (id === "all") return "全部";
|
|
283
|
+
var m = catMeta(id);
|
|
284
|
+
return m ? (m.icon + " " + m.label) : id;
|
|
285
|
+
}
|
|
286
|
+
function subLabel(catId, subId) {
|
|
287
|
+
var m = catMeta(catId);
|
|
288
|
+
if (!m || !m.subs) return "";
|
|
289
|
+
for (var i = 0; i < m.subs.length; i++) if (m.subs[i].id === subId) return m.subs[i].label;
|
|
290
|
+
return subId;
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
function filtered() {
|
|
294
|
+
if (!S.data) return [];
|
|
295
|
+
var q = S.q.trim().toLowerCase();
|
|
296
|
+
var out = [];
|
|
297
|
+
var sk = S.data.skills || [];
|
|
298
|
+
for (var i = 0; i < sk.length; i++) {
|
|
299
|
+
var s = sk[i];
|
|
300
|
+
if (S.cat !== "all" && s.cat !== S.cat) continue;
|
|
301
|
+
if (S.sub && s.sub !== S.sub) continue;
|
|
302
|
+
if (q) {
|
|
303
|
+
var hay = (s.dir + " " + s.name + " " + (s.zh || "") + " " + (s.desc || "")).toLowerCase();
|
|
304
|
+
if (hay.indexOf(q) < 0) continue;
|
|
305
|
+
}
|
|
306
|
+
out.push(s);
|
|
307
|
+
}
|
|
308
|
+
return out;
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
function readStore(key, def) {
|
|
312
|
+
try { var v = localStorage.getItem(key); return v == null ? def : v === "1"; } catch (e) { return def; }
|
|
313
|
+
}
|
|
314
|
+
function writeStore(key, val) {
|
|
315
|
+
try { localStorage.setItem(key, val ? "1" : "0"); } catch (e) {}
|
|
316
|
+
}
|
|
317
|
+
function isGhost() {
|
|
318
|
+
try { return localStorage.getItem(GHOST_KEY) === "1"; } catch (e) { return false; }
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
// ---- data ----
|
|
322
|
+
function load(refresh) {
|
|
323
|
+
S.loading = true; S.error = ""; paint();
|
|
324
|
+
fetch(apiBase() + "/skills" + (refresh ? "?refresh=1" : ""))
|
|
325
|
+
.then(function (r) { return r.json(); })
|
|
326
|
+
.then(function (d) {
|
|
327
|
+
if (!d || !d.ok) throw new Error((d && d.error) || "bad response");
|
|
328
|
+
S.data = d;
|
|
329
|
+
closeBatchMenu(); // v1.7.2: 数据重扫后确认菜单里的 N 已过期,直接关闭
|
|
330
|
+
if (S.cat !== "all" && !catMeta(S.cat)) { S.cat = "all"; S.sub = ""; }
|
|
331
|
+
S.loading = false; paint();
|
|
332
|
+
})
|
|
333
|
+
.catch(function (e) {
|
|
334
|
+
S.loading = false;
|
|
335
|
+
S.error = "加载失败:" + (e && e.message ? e.message : e);
|
|
336
|
+
paint();
|
|
337
|
+
});
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
function loadLedger() {
|
|
341
|
+
if (S.ledger) return;
|
|
342
|
+
S.loading = true; S.error = ""; paint();
|
|
343
|
+
fetch(apiBase() + "/ledger")
|
|
344
|
+
.then(function (r) { return r.json(); })
|
|
345
|
+
.then(function (d) {
|
|
346
|
+
if (!d || !d.ok) throw new Error((d && d.error) || "bad response");
|
|
347
|
+
S.ledger = d;
|
|
348
|
+
S.loading = false; paint();
|
|
349
|
+
})
|
|
350
|
+
.catch(function (e) {
|
|
351
|
+
S.loading = false;
|
|
352
|
+
S.error = "台账加载失败:" + (e && e.message ? e.message : e);
|
|
353
|
+
paint();
|
|
354
|
+
});
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
function loadLedgerRefresh() {
|
|
358
|
+
S.ledger = null;
|
|
359
|
+
loadLedger();
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
// ---- 运行时配置(技能库位置 / 自动台账开关)----
|
|
363
|
+
// 目录选择:POST /pick-dir,由宿主端 spawn powershell -STA 弹 Windows
|
|
364
|
+
// FolderBrowserDialog(系统原生对话框)。不依赖 Electron renderer 的
|
|
365
|
+
// File API:Electron 32+ 已移除 File.path,webUtils 又依赖 preload 暴露,
|
|
366
|
+
// webkitdirectory 方案实测拿不到可靠真实路径(两次尝试均失败)。
|
|
367
|
+
function browseForDirectory() {
|
|
368
|
+
var st = $("dsb-set-status");
|
|
369
|
+
if (st) st.textContent = "正在打开系统目录选择框…(请在弹出的窗口中选择;若被遮挡请看任务栏)";
|
|
370
|
+
fetch(apiBase() + "/pick-dir", { method: "POST" })
|
|
371
|
+
.then(function (r) { return r.json(); })
|
|
372
|
+
.then(function (d) {
|
|
373
|
+
if (d && d.ok && d.path) {
|
|
374
|
+
var inp = $("dsb-set-root");
|
|
375
|
+
if (inp) inp.value = d.path;
|
|
376
|
+
saveConfig({ skillsDir: d.path }); // 选完即保存
|
|
377
|
+
} else if (d && d.ok) {
|
|
378
|
+
if (st) st.textContent = "已取消选择;可手动在输入框粘贴绝对路径后点「保存」";
|
|
379
|
+
} else {
|
|
380
|
+
if (st) st.textContent = "选择失败:" + ((d && d.error) || "未知错误") + ";可手动在输入框粘贴绝对路径";
|
|
381
|
+
}
|
|
382
|
+
})
|
|
383
|
+
.catch(function (e) {
|
|
384
|
+
if (st) st.textContent = "选择失败:" + (e && e.message ? e.message : e) + ";可手动在输入框粘贴绝对路径";
|
|
385
|
+
});
|
|
386
|
+
}
|
|
387
|
+
function loadConfig(cb) {
|
|
388
|
+
fetch(apiBase() + "/config")
|
|
389
|
+
.then(function (r) { return r.json(); })
|
|
390
|
+
.then(function (d) { if (d && d.ok && cb) cb(d); })
|
|
391
|
+
.catch(function () {});
|
|
392
|
+
}
|
|
393
|
+
function saveConfig(patch) {
|
|
394
|
+
var el = $("dsb-set-status");
|
|
395
|
+
fetch(apiBase() + "/config", {
|
|
396
|
+
method: "POST",
|
|
397
|
+
headers: { "content-type": "application/json" },
|
|
398
|
+
body: JSON.stringify(patch || {})
|
|
399
|
+
})
|
|
400
|
+
.then(function (r) { return r.json().catch(function () { throw new Error("HTTP " + r.status); }); })
|
|
401
|
+
.then(function (d) {
|
|
402
|
+
if (d && d.ok) {
|
|
403
|
+
S.data = null; S.ledger = null; // 根路径可能变了,强制重扫
|
|
404
|
+
if (S.open) { load(true); if (S.view === "ledger") loadLedgerRefresh(); }
|
|
405
|
+
paintConfigStatus(d);
|
|
406
|
+
} else {
|
|
407
|
+
if (el) el.textContent = "保存失败:" + ((d && d.error) || "未知错误") + "(宿主版本可能过旧,需重启 DSH)";
|
|
408
|
+
}
|
|
409
|
+
})
|
|
410
|
+
.catch(function (e) {
|
|
411
|
+
if (el) el.textContent = "保存失败:" + (e && e.message ? e.message : e) + "(宿主版本可能过旧,需重启 DSH)";
|
|
412
|
+
});
|
|
413
|
+
}
|
|
414
|
+
function paintConfigStatus(cfg) {
|
|
415
|
+
var el = $("dsb-set-status"), inp = $("dsb-set-root"), lcb = $("dsb-set-ledger");
|
|
416
|
+
if (!el) return;
|
|
417
|
+
var srcMap = { "settings-override": "设置页指定", "env": "环境变量", "config": "插件配置", "auto-detect": "自动识别", "none": "未找到" };
|
|
418
|
+
el.textContent = "当前技能库:" + (cfg.root || "未找到") + "(" + (srcMap[cfg.source] || cfg.source) + ")· 台账:" +
|
|
419
|
+
(cfg.ledgerExists ? "已存在" : (cfg.ledgerPath ? "将自动创建" : "—"));
|
|
420
|
+
if (inp && document.activeElement !== inp) inp.value = (cfg.runtime && cfg.runtime.skillsDir) || "";
|
|
421
|
+
if (lcb) lcb.checked = cfg.ledgerEnabled !== false;
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
function openDetail(dir) {
|
|
425
|
+
var box = $("dsb-detail-body"); if (box) box.textContent = "加载中…";
|
|
426
|
+
S.detail = { dir: dir, content: "" };
|
|
427
|
+
paint();
|
|
428
|
+
fetch(apiBase() + "/skill?dir=" + encodeURIComponent(dir))
|
|
429
|
+
.then(function (r) { return r.json(); })
|
|
430
|
+
.then(function (d) {
|
|
431
|
+
if (!S.detail || S.detail.dir !== dir) return;
|
|
432
|
+
S.detail.content = (d && d.ok) ? d.content : ("读取失败:" + ((d && d.error) || ""));
|
|
433
|
+
var box2 = $("dsb-detail-body");
|
|
434
|
+
if (box2) box2.textContent = S.detail.content;
|
|
435
|
+
})
|
|
436
|
+
.catch(function (e) {
|
|
437
|
+
var box3 = $("dsb-detail-body");
|
|
438
|
+
if (box3) box3.textContent = "读取失败:" + (e && e.message ? e.message : e);
|
|
439
|
+
});
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
function openLedgerDetail(skill) {
|
|
443
|
+
var box = $("dsb-detail-body"); if (box) box.textContent = "加载中…";
|
|
444
|
+
S.ledgerDetail = { skill: skill, detail: "" };
|
|
445
|
+
paint();
|
|
446
|
+
fetch(apiBase() + "/ledger-detail?skill=" + encodeURIComponent(skill))
|
|
447
|
+
.then(function (r) { return r.json(); })
|
|
448
|
+
.then(function (d) {
|
|
449
|
+
if (!S.ledgerDetail || S.ledgerDetail.skill !== skill) return;
|
|
450
|
+
var parts = [];
|
|
451
|
+
if (d && d.ok) {
|
|
452
|
+
if (d.detail) parts.push("【人工台账失败明细】\n" + d.detail);
|
|
453
|
+
if (d.autoEntries && d.autoEntries.length) {
|
|
454
|
+
var lines = ["【自动登记记录】共 " + d.autoEntries.length + " 条(最新在前)"];
|
|
455
|
+
var list = d.autoEntries.slice().reverse();
|
|
456
|
+
for (var i = 0; i < list.length; i++) {
|
|
457
|
+
var x = list[i];
|
|
458
|
+
lines.push("- " + String(x.ts || "").replace("T", " ").slice(0, 19) + " " + (x.ok ? "✅ 生效" : "❌ 未生效") + "(" + (x.kind || "auto") + ")" + (x.note || x.error ? " — " + (x.note || x.error) : ""));
|
|
459
|
+
}
|
|
460
|
+
parts.push(lines.join("\n"));
|
|
461
|
+
}
|
|
462
|
+
if (!parts.length) parts.push("(无失败明细记录)");
|
|
463
|
+
} else {
|
|
464
|
+
parts.push("读取失败:" + ((d && d.error) || ""));
|
|
465
|
+
}
|
|
466
|
+
S.ledgerDetail.detail = parts.join("\n\n");
|
|
467
|
+
var box2 = $("dsb-detail-body");
|
|
468
|
+
if (box2) box2.textContent = S.ledgerDetail.detail;
|
|
469
|
+
})
|
|
470
|
+
.catch(function (e) {
|
|
471
|
+
var box3 = $("dsb-detail-body");
|
|
472
|
+
if (box3) box3.textContent = "读取失败:" + (e && e.message ? e.message : e);
|
|
473
|
+
});
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
// ---- 字体插件球:纯 CSS 永久统一样式与显隐 ----
|
|
477
|
+
// 不再轮询检查:用全局 CSS 规则 + body 属性驱动,font-enhancer 重建按钮
|
|
478
|
+
// 多少次样式都自动生效(CSS 幂等)。不动 font-enhancer 一行代码。
|
|
479
|
+
function applyFontBallVisibility() {
|
|
480
|
+
// 属性设在 html 上(CSS 规则驱动)
|
|
481
|
+
var el = document.documentElement || document.body;
|
|
482
|
+
el.setAttribute("data-dsb-font-hidden", readStore(FONT_BALL_VIS_KEY, true) ? "0" : "1");
|
|
483
|
+
// 内联样式兜底(font-enhancer 的 display:block !important 若因时机问题未覆盖)
|
|
484
|
+
var t = document.getElementById("dsh-fe-toggle");
|
|
485
|
+
if (t) t.style.setProperty("display", readStore(FONT_BALL_VIS_KEY, true) ? "" : "none", "important");
|
|
486
|
+
// Todo 悬浮球(dsh-todo-float-ball)显隐:同字体球模式——共享其
|
|
487
|
+
// localStorage 键(dsh-tfb-ball-visible),属性+内联双兜底,
|
|
488
|
+
// 不动 todo 插件一行代码(CSS 幂等,重建后仍生效)。
|
|
489
|
+
var tfb = document.getElementById("dsh-tfb-root");
|
|
490
|
+
if (tfb) tfb.style.setProperty("display", readStore(TODO_BALL_VIS_KEY, true) ? "" : "none", "important");
|
|
491
|
+
}
|
|
492
|
+
function applyBallVisibility() {
|
|
493
|
+
var el = document.documentElement || document.body;
|
|
494
|
+
el.setAttribute("data-dsb-ball-hidden", readStore(BALL_VIS_KEY, true) ? "0" : "1");
|
|
495
|
+
}
|
|
496
|
+
|
|
497
|
+
// ---- panel ----
|
|
498
|
+
var PANEL_CSS =
|
|
499
|
+
'#dsh-skill-browser-panel{position:fixed;left:50%;top:50%;transform:translate(-50%,-50%);' +
|
|
500
|
+
'width:min(940px,94vw);height:min(660px,88vh);display:flex;flex-direction:column;' +
|
|
501
|
+
'background:rgba(24,26,34,.97);color:#e8eaf2;border:1px solid rgba(255,255,255,.1);border-radius:14px;' +
|
|
502
|
+
'box-shadow:0 12px 48px rgba(0,0,0,.5);z-index:2147481100;overflow:hidden;font-family:inherit}' +
|
|
503
|
+
'#dsb-built{display:flex;flex-direction:column;min-height:0;flex:1}' +
|
|
504
|
+
'.dsb-head{display:flex;align-items:center;justify-content:space-between;padding:12px 16px 6px}' +
|
|
505
|
+
'.dsb-title{font-size:16px;font-weight:600}' +
|
|
506
|
+
'.dsb-headbtns{display:flex;gap:6px}' +
|
|
507
|
+
'.dsb-btn{background:rgba(255,255,255,.08);color:#dfe3ee;border:1px solid rgba(255,255,255,.12);border-radius:8px;' +
|
|
508
|
+
'padding:4px 10px;font-size:12px;cursor:pointer}' +
|
|
509
|
+
'.dsb-btn:hover{background:rgba(255,255,255,.16)}' +
|
|
510
|
+
'.dsb-subtitle{padding:0 16px 6px;font-size:11px;color:#9aa1b5;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}' +
|
|
511
|
+
'.dsb-settings{display:none;padding:6px 16px;gap:6px;flex-direction:column;background:rgba(255,255,255,.04);border-bottom:1px solid rgba(255,255,255,.06);margin-bottom:4px}' +
|
|
512
|
+
'.dsb-set-row{display:flex;align-items:center;gap:8px;font-size:12.5px;cursor:pointer;padding:2px 0}' +
|
|
513
|
+
'.dsb-set-row input{accent-color:#5b6cff}' +
|
|
514
|
+
'.dsb-set-hint{font-size:11px;color:#9aa1b5}' +
|
|
515
|
+
'.dsb-set-rec{display:flex;align-items:center;justify-content:space-between;gap:8px;font-size:12.5px;padding:3px 0}' +
|
|
516
|
+
'.dsb-set-rec a{text-decoration:none;font-size:12px;background:rgba(255,255,255,.06);border:1px solid rgba(255,255,255,.12);border-radius:6px;padding:2px 8px;color:#ffd27a;cursor:pointer;white-space:nowrap}' +
|
|
517
|
+
'.dsb-set-rec a:hover{background:rgba(255,210,122,.15);border-color:rgba(255,210,122,.4)}' +
|
|
518
|
+
// v1.7.4 设置面板金边推广卡(广告卡自技能清单迁入):稍窄适配面板宽度
|
|
519
|
+
'.dsb-set-promo{border:1px solid rgba(255,210,122,.35);border-radius:8px;padding:6px 10px;margin-top:6px;background:rgba(255,210,122,.05);cursor:pointer;transition:background .15s}' +
|
|
520
|
+
'.dsb-set-promo:hover{background:rgba(255,210,122,.12)}' +
|
|
521
|
+
'.dsb-set-promo .p-name{font-size:12.5px;font-weight:600;color:#ffd27a}' +
|
|
522
|
+
'.dsb-set-promo .p-desc{font-size:11.5px;color:#c6cbdb;line-height:1.5;margin-top:2px;white-space:normal}' +
|
|
523
|
+
'.dsb-set-promo .p-tag{font-size:10.5px;color:#9aa1b5;margin-top:2px}' +
|
|
524
|
+
'.dsb-q{margin:4px 16px 8px;padding:7px 12px;border-radius:9px;border:1px solid rgba(255,255,255,.14);' +
|
|
525
|
+
'background:rgba(255,255,255,.06);color:#eef;font-size:13px;outline:none}' +
|
|
526
|
+
'.dsb-q:focus{border-color:#5b8cff}' +
|
|
527
|
+
'.dsb-chips{display:flex;flex-wrap:wrap;gap:6px;padding:0 16px 6px}' +
|
|
528
|
+
'.dsb-chip,.dsb-schip{background:rgba(255,255,255,.06);border:1px solid rgba(255,255,255,.1);color:#cdd3e3;' +
|
|
529
|
+
'border-radius:999px;padding:3px 10px;font-size:12px;cursor:pointer;white-space:nowrap}' +
|
|
530
|
+
'.dsb-chip:hover,.dsb-schip:hover{background:rgba(255,255,255,.14)}' +
|
|
531
|
+
'.dsb-chip-on{background:linear-gradient(135deg,#5b6cff,#2fa8ff);color:#fff;border-color:transparent}' +
|
|
532
|
+
'.dsb-n{opacity:.75;font-size:11px;margin-left:2px}' +
|
|
533
|
+
'.dsb-subs{display:none;flex-wrap:wrap;gap:6px;padding:0 16px 6px;border-top:1px dashed rgba(255,255,255,.08);padding-top:8px;margin:0 0 2px}' +
|
|
534
|
+
'.dsb-cards{flex:1;min-height:0;overflow-y:auto;display:grid;grid-template-columns:repeat(auto-fill,minmax(280px,1fr));' +
|
|
535
|
+
'gap:8px;padding:6px 16px 14px;align-content:start}' +
|
|
536
|
+
'.dsb-card{background:rgba(255,255,255,.05);border:1px solid rgba(255,255,255,.08);border-radius:10px;' +
|
|
537
|
+
'padding:10px 12px;cursor:pointer;transition:background .12s}' +
|
|
538
|
+
'.dsb-card:hover{background:rgba(120,140,255,.14);border-color:rgba(120,140,255,.4)}' +
|
|
539
|
+
'.dsb-card-name{font-family:ui-monospace,Consolas,monospace;font-size:12px;color:#8fc7ff;word-break:break-all}' +
|
|
540
|
+
'.dsb-card-zh{font-size:12.5px;color:#dfe3ee;margin-top:5px;line-height:1.5;' +
|
|
541
|
+
'display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}' +
|
|
542
|
+
'.dsb-card-tag{font-size:10.5px;color:#8b93a8;margin-top:6px}' +
|
|
543
|
+
'.dsb-empty{grid-column:1/-1;text-align:center;color:#9aa1b5;padding:40px 0;font-size:13px;line-height:1.7}' +
|
|
544
|
+
'.dsb-detail{position:absolute;inset:0;background:rgba(24,26,34,.99);flex-direction:column;z-index:2}' +
|
|
545
|
+
'.dsb-detail-body{flex:1;min-height:0;overflow:auto;margin:0;padding:6px 16px 16px;' +
|
|
546
|
+
'font-family:ui-monospace,Consolas,monospace;font-size:12px;line-height:1.65;color:#cfd6e8;white-space:pre-wrap;word-break:break-word}' +
|
|
547
|
+
'.dsb-tabs{display:flex;gap:4px;margin:0 8px}' +
|
|
548
|
+
'.dsb-tab{background:rgba(255,255,255,.06);border:1px solid rgba(255,255,255,.1);color:#cdd3e3;' +
|
|
549
|
+
'border-radius:8px;padding:4px 12px;font-size:12px;cursor:pointer}' +
|
|
550
|
+
'.dsb-tab:hover{background:rgba(255,255,255,.14)}' +
|
|
551
|
+
'.dsb-tab-on{background:linear-gradient(135deg,#5b6cff,#2fa8ff);color:#fff;border-color:transparent}' +
|
|
552
|
+
'.dsb-ledger{flex:1;min-height:0;display:flex;flex-direction:column;padding:0 16px 14px}' +
|
|
553
|
+
'.dsb-ledger-sum{display:flex;gap:10px;padding:4px 0 10px}' +
|
|
554
|
+
'.dsb-lsum-card{flex:1;background:rgba(255,255,255,.05);border:1px solid rgba(255,255,255,.09);border-radius:10px;' +
|
|
555
|
+
'padding:10px;text-align:center}' +
|
|
556
|
+
'.dsb-lsum-card b{display:block;font-size:22px;color:#8fc7ff}' +
|
|
557
|
+
'.dsb-lsum-card span{font-size:11px;color:#9aa1b5}' +
|
|
558
|
+
'.dsb-lsum-fail b{color:#ff9d9d}' +
|
|
559
|
+
'.dsb-ledger-table{flex:1;min-height:0;overflow-y:auto}' +
|
|
560
|
+
'.dsb-ltable{display:flex;flex-direction:column;gap:4px}' +
|
|
561
|
+
'.dsb-lrow{display:grid;grid-template-columns:34px 1fr 44px 44px 92px 1.2fr;gap:6px;align-items:center;' +
|
|
562
|
+
'background:rgba(255,255,255,.04);border:1px solid rgba(255,255,255,.07);border-radius:8px;padding:7px 10px;' +
|
|
563
|
+
'font-size:12px;cursor:pointer;transition:background .12s}' +
|
|
564
|
+
'.dsb-lrow:hover{background:rgba(120,140,255,.14)}' +
|
|
565
|
+
'.dsb-lhead{background:transparent;border-color:transparent;cursor:default;font-size:11px;color:#8b93a8}' +
|
|
566
|
+
'.dsb-lc-skill{font-family:ui-monospace,Consolas,monospace;color:#8fc7ff;word-break:break-all}' +
|
|
567
|
+
'.dsb-lc-fail{color:#ff9d9d;font-weight:700;text-align:center}' +
|
|
568
|
+
'.dsb-lc-rate{text-align:center}' +
|
|
569
|
+
'.dsb-lv-high{color:#ff7d7d;font-weight:700}' +
|
|
570
|
+
'.dsb-lv-mid{color:#ffb35c;font-weight:700}' +
|
|
571
|
+
'.dsb-lv-low{color:#ffd27a}' +
|
|
572
|
+
'.dsb-lst-done{color:#6fd48a}' +
|
|
573
|
+
'.dsb-lst-warn{color:#ffb35c}' +
|
|
574
|
+
'.dsb-lst-ok{color:#9aa1b5}' +
|
|
575
|
+
/* ── v1.7.0:排序切换 / 批量启停 / 单技能开关 / 停用视觉 ── */
|
|
576
|
+
'.dsb-sortbar{display:flex;align-items:center;gap:8px;padding:0 16px 6px}' +
|
|
577
|
+
'.dsb-sortbtn{background:rgba(255,255,255,.06);border:1px solid rgba(255,255,255,.12);color:#cdd3e3;' +
|
|
578
|
+
'border-radius:999px;padding:3px 12px;font-size:12px;cursor:pointer;white-space:nowrap}' +
|
|
579
|
+
'.dsb-sortbtn:hover{background:rgba(255,255,255,.14)}' +
|
|
580
|
+
'.dsb-sortbtn-on{background:linear-gradient(135deg,#5b6cff,#2fa8ff);color:#fff;border-color:transparent}' +
|
|
581
|
+
'.dsb-batchbtn{background:rgba(255,255,255,.06);border:1px solid rgba(255,255,255,.12);color:#cdd3e3;' +
|
|
582
|
+
'border-radius:6px;padding:2px 8px;font-size:11px;cursor:pointer;white-space:nowrap;margin-left:6px}' +
|
|
583
|
+
'.dsb-batchbtn:hover{background:rgba(255,255,255,.14)}' +
|
|
584
|
+
'.dsb-batchbtn-warn{color:#ffb3b3;border-color:rgba(255,120,120,.35)}' +
|
|
585
|
+
'.dsb-batchbtn-warn:hover{background:rgba(255,120,120,.15)}' +
|
|
586
|
+
'.dsb-batchbtn[disabled],.dsb-tgl[disabled]{opacity:.5;cursor:default}' +
|
|
587
|
+
'.dsb-batch-status{font-size:11px;color:#9aa1b5}' +
|
|
588
|
+
'.dsb-batch-fail{color:#ff9d9d}' +
|
|
589
|
+
'.dsb-card-off{opacity:.45;filter:grayscale(.7)}' +
|
|
590
|
+
'.dsb-card-off:hover{background:rgba(255,255,255,.05);border-color:rgba(255,255,255,.08)}' +
|
|
591
|
+
'.dsb-badge-off{display:inline-block;font-size:10px;color:#ffd27a;background:rgba(255,210,122,.12);' +
|
|
592
|
+
'border:1px solid rgba(255,210,122,.35);border-radius:6px;padding:0 6px;margin-left:6px;vertical-align:1px}' +
|
|
593
|
+
'.dsb-card-mtime{font-size:10.5px;color:#8b93a8;margin-top:3px}' +
|
|
594
|
+
'.dsb-tgl{background:rgba(255,255,255,.06);border:1px solid rgba(255,255,255,.12);color:#cdd3e3;' +
|
|
595
|
+
'border-radius:6px;padding:2px 8px;font-size:11px;cursor:pointer;white-space:nowrap}' +
|
|
596
|
+
'.dsb-tgl:hover{background:rgba(255,255,255,.16)}' +
|
|
597
|
+
'.dsb-tgl-on{color:#9fe0b5;border-color:rgba(120,220,150,.35)}' +
|
|
598
|
+
/* ── v1.7.1:滑动开关(胶囊轨道 34×18 + 圆形滑块,乐观更新)──
|
|
599
|
+
结构:<label class="dsb-switch" data-tgl=dir data-to=0|1>
|
|
600
|
+
<span class="dsb-sw-track"><span class="dsb-sw-thumb"></span></span>
|
|
601
|
+
<span class="dsb-sw-label">开/关</span></label>
|
|
602
|
+
开启态:.dsb-sw-on 轨道绿 #27ae60、滑块右移;停用态:轨道灰 #555、滑块左移。 */
|
|
603
|
+
'#dsh-skill-browser-panel .dsb-switch{display:inline-flex;align-items:center;gap:7px;cursor:pointer;user-select:none}' +
|
|
604
|
+
'#dsh-skill-browser-panel .dsb-switch[disabled]{opacity:.5;cursor:default}' +
|
|
605
|
+
'#dsh-skill-browser-panel .dsb-sw-track{position:relative;display:inline-block;width:34px;height:18px;' +
|
|
606
|
+
'border-radius:999px;background:#555;transition:background .2s;flex:none}' +
|
|
607
|
+
'#dsh-skill-browser-panel .dsb-sw-thumb{position:absolute;top:2px;left:2px;width:14px;height:14px;' +
|
|
608
|
+
'border-radius:50%;background:#fff;box-shadow:0 1px 3px rgba(0,0,0,.4);transition:left .2s}' +
|
|
609
|
+
'#dsh-skill-browser-panel .dsb-switch.dsb-sw-on .dsb-sw-track{background:#27ae60}' +
|
|
610
|
+
'#dsh-skill-browser-panel .dsb-switch.dsb-sw-on .dsb-sw-thumb{left:18px}' +
|
|
611
|
+
'#dsh-skill-browser-panel .dsb-sw-label{font-size:11px;color:#9aa1b5;white-space:nowrap}' +
|
|
612
|
+
'#dsh-skill-browser-panel .dsb-switch.dsb-sw-on .dsb-sw-label{color:#9fe0b5}' +
|
|
613
|
+
/* ── v1.7.1:面板内右上角 toast 轻提示(2s 自动消失,成功绿/失败红)── */
|
|
614
|
+
'#dsh-skill-browser-panel .dsb-toast{position:absolute;top:54px;right:16px;z-index:50;max-width:60%;' +
|
|
615
|
+
'padding:8px 14px;border-radius:9px;font-size:12.5px;line-height:1.5;white-space:nowrap;overflow:hidden;' +
|
|
616
|
+
'text-overflow:ellipsis;box-shadow:0 6px 22px rgba(0,0,0,.45);opacity:0;transform:translateY(-6px);' +
|
|
617
|
+
'transition:opacity .2s,transform .2s;pointer-events:none}' +
|
|
618
|
+
'#dsh-skill-browser-panel .dsb-toast.dsb-toast-show{opacity:1;transform:translateY(0)}' +
|
|
619
|
+
'#dsh-skill-browser-panel .dsb-toast-ok{background:rgba(39,174,96,.95);color:#fff;border:1px solid rgba(255,255,255,.25)}' +
|
|
620
|
+
'#dsh-skill-browser-panel .dsb-toast-err{background:rgba(192,57,43,.95);color:#fff;border:1px solid rgba(255,255,255,.25)}' +
|
|
621
|
+
/* ── v1.7.2:三级滑块开关(聚合态半开 / 小号分类滑块 / 面板内确认菜单)──
|
|
622
|
+
半开态 .dsb-sw-half:轨道左半灰右半绿 + 滑块居中,标签暖黄;
|
|
623
|
+
全启用=右绿(复用 .dsb-sw-on),全停用=左灰(无附加类)。 */
|
|
624
|
+
'#dsh-skill-browser-panel .dsb-sw-half .dsb-sw-track{background:linear-gradient(90deg,#555 0%,#555 50%,#27ae60 50%,#27ae60 100%)}' +
|
|
625
|
+
'#dsh-skill-browser-panel .dsb-sw-half .dsb-sw-thumb{left:10px}' +
|
|
626
|
+
'#dsh-skill-browser-panel .dsb-sw-half .dsb-sw-label{color:#ffd27a}' +
|
|
627
|
+
'#dsh-skill-browser-panel .dsb-switch.dsb-sw-agg[aria-disabled]{opacity:.5;cursor:default}' +
|
|
628
|
+
'#dsh-skill-browser-panel .dsb-sw-sep{width:1px;height:16px;background:rgba(255,255,255,.14);margin:0 2px;flex:none}' +
|
|
629
|
+
/* 分类级小一号胶囊滑块(轨道 26×14,滑块 10px) */
|
|
630
|
+
'#dsh-skill-browser-panel .dsb-sw-sm .dsb-sw-track{width:26px;height:14px}' +
|
|
631
|
+
'#dsh-skill-browser-panel .dsb-sw-sm .dsb-sw-thumb{width:10px;height:10px;top:2px;left:2px}' +
|
|
632
|
+
'#dsh-skill-browser-panel .dsb-switch.dsb-sw-sm.dsb-sw-on .dsb-sw-thumb{left:14px}' +
|
|
633
|
+
'#dsh-skill-browser-panel .dsb-switch.dsb-sw-sm.dsb-sw-half .dsb-sw-thumb{left:8px}' +
|
|
634
|
+
/* 面板内批量确认菜单(透明遮罩点击关闭 + 菜单浮层,非 window.confirm) */
|
|
635
|
+
'#dsh-skill-browser-panel .dsb-bmenu-mask{position:absolute;inset:0;z-index:58;background:transparent}' +
|
|
636
|
+
'#dsh-skill-browser-panel .dsb-bmenu{position:absolute;z-index:59;min-width:230px;max-width:78%;' +
|
|
637
|
+
'background:#232633;border:1px solid rgba(255,255,255,.16);border-radius:10px;padding:6px;' +
|
|
638
|
+
'box-shadow:0 10px 32px rgba(0,0,0,.55);display:none;flex-direction:column;gap:4px}' +
|
|
639
|
+
'#dsh-skill-browser-panel .dsb-bmenu-title{font-size:11px;color:#9aa1b5;padding:2px 6px 4px;line-height:1.5}' +
|
|
640
|
+
'#dsh-skill-browser-panel .dsb-bmenu-item{display:flex;flex-direction:column;align-items:flex-start;gap:2px;' +
|
|
641
|
+
'background:rgba(255,255,255,.06);border:1px solid rgba(255,255,255,.12);color:#dfe3ee;border-radius:8px;' +
|
|
642
|
+
'padding:6px 10px;font-size:12.5px;cursor:pointer;text-align:left;width:100%}' +
|
|
643
|
+
'#dsh-skill-browser-panel .dsb-bmenu-item:hover{background:rgba(120,140,255,.18)}' +
|
|
644
|
+
'#dsh-skill-browser-panel .dsb-bmenu-sub{font-size:10.5px;color:#9aa1b5;font-weight:400;line-height:1.5;white-space:normal}' +
|
|
645
|
+
'#dsh-skill-browser-panel .dsb-bmenu-danger{color:#ffb3b3;border-color:rgba(255,120,120,.4)}' +
|
|
646
|
+
'#dsh-skill-browser-panel .dsb-bmenu-danger:hover{background:rgba(255,120,120,.16)}' +
|
|
647
|
+
'#dsh-skill-browser-panel .dsb-bmenu-danger .dsb-bmenu-sub{color:#ff9d9d}' +
|
|
648
|
+
'#dsh-skill-browser-panel .dsb-bmenu-cancel{background:transparent;border:none;color:#9aa1b5;font-size:12px;cursor:pointer;padding:4px 6px;text-align:center}' +
|
|
649
|
+
'#dsh-skill-browser-panel .dsb-bmenu-cancel:hover{color:#dfe3ee}';
|
|
650
|
+
|
|
651
|
+
function buildPanel() {
|
|
652
|
+
if (S.panelBuilt) return;
|
|
653
|
+
var style = document.createElement("style");
|
|
654
|
+
style.id = "dsb-panel-style";
|
|
655
|
+
style.textContent = PANEL_CSS;
|
|
656
|
+
document.head.appendChild(style);
|
|
657
|
+
try { applySkinNow(); } catch (eSkin) {} // keep skin overrides after PANEL_CSS
|
|
658
|
+
|
|
659
|
+
var panel = document.createElement("div");
|
|
660
|
+
panel.id = PANEL_ID;
|
|
661
|
+
panel.innerHTML =
|
|
662
|
+
'<div class="dsb-head">' +
|
|
663
|
+
'<div class="dsb-title">🧩 技能浏览器</div>' +
|
|
664
|
+
'<div class="dsb-tabs">' +
|
|
665
|
+
'<button id="dsb-tab-skills" class="dsb-tab" data-view="skills">技能浏览</button>' +
|
|
666
|
+
'<button id="dsb-tab-ledger" class="dsb-tab" data-view="ledger">📋 失效台账</button>' +
|
|
667
|
+
'</div>' +
|
|
668
|
+
'<div class="dsb-headbtns">' +
|
|
669
|
+
'<button id="dsb-skin-btn" class="dsb-btn" title="切换皮肤(三球同步 · 128款)">🎨</button>' +
|
|
670
|
+
'<button id="dsb-setting" class="dsb-btn" title="开关设置">⚙</button>' +
|
|
671
|
+
'<button id="dsb-refresh" class="dsb-btn" title="重新扫描技能目录">↻ 刷新</button>' +
|
|
672
|
+
'<button id="dsb-close" class="dsb-btn" title="关闭">×</button>' +
|
|
673
|
+
'</div>' +
|
|
674
|
+
'</div>' +
|
|
675
|
+
'<div id="dsb-skin" class="dsb-skinmenu"></div>' +
|
|
676
|
+
'<div id="dsb-subtitle" class="dsb-subtitle"></div>' +
|
|
677
|
+
'<div id="dsb-settings" class="dsb-settings" style="display:none">' +
|
|
678
|
+
'<label class="dsb-set-row"><input type="checkbox" id="dsb-set-ball" /> 技能浏览器悬浮球(🧩)</label>' +
|
|
679
|
+
'<label class="dsb-set-row"><input type="checkbox" id="dsb-set-font" /> 字体插件悬浮球(🔤)</label>' +
|
|
680
|
+
'<div class="dsb-set-row" style="flex-wrap:wrap">' +
|
|
681
|
+
'<span style="min-width:70px">技能库位置</span>' +
|
|
682
|
+
'<input id="dsb-set-root" type="text" placeholder="留空=自动识别(~/.dsh/skills 等)" style="flex:1;min-width:220px;background:rgba(255,255,255,.07);border:1px solid rgba(255,255,255,.14);border-radius:6px;color:#eef;font-size:12px;padding:4px 8px;outline:none" />' +
|
|
683
|
+
'<button id="dsb-set-root-browse" class="dsb-btn" title="打开系统文件夹选择框">📁 选择</button>' +
|
|
684
|
+
'<button id="dsb-set-root-save" class="dsb-btn">保存</button>' +
|
|
685
|
+
'</div>' +
|
|
686
|
+
'<div class="dsb-set-row" style="flex-wrap:wrap">' +
|
|
687
|
+
'<span style="min-width:70px">悬浮球皮肤</span>' +
|
|
688
|
+
'<select id="dsb-set-skin" style="flex:1;min-width:220px;background:rgba(0,0,0,.35);border:1px solid rgba(255,255,255,.14);border-radius:6px;color:inherit;font-size:12px;padding:4px 6px;outline:none"></select>' +
|
|
689
|
+
'<span class="dsb-set-hint">三球同步 · 128 款</span>' +
|
|
690
|
+
'</div>' +
|
|
691
|
+
'<label class="dsb-set-row"><input type="checkbox" id="dsb-set-ledger" /> 失效台账自动登记(记录每次技能工具调用结果)</label>' +
|
|
692
|
+
'<span id="dsb-set-status" class="dsb-set-hint">当前技能库:识别中…</span>' +
|
|
693
|
+
'<span class="dsb-set-hint">💡 悬浮球显隐也可在 <b>DSH 设置页 → 「悬浮球导航」分区</b> 中控制;悬浮球可拖动;清单面板始终居中</span>' +
|
|
694
|
+
// ── v1.7.4 广告区(用户指定落位:设置面板 hint 之后)──
|
|
695
|
+
// hint 文案与原"💡悬浮球显隐设置"说明卡内容重复,二选一保留 hint。
|
|
696
|
+
// 3 张金边推广卡(.dsb-set-promo,rgba(255,210,122,.35)),前两张
|
|
697
|
+
// data-ext-url 点击直达 GitHub(委托见 buildPanel dsb-settings 绑定)。
|
|
698
|
+
// 不带 data-dir/data-tgl:不参与排序/计数/开关逻辑。
|
|
699
|
+
'<div class="dsb-set-promo" data-ext-url="https://github.com/loyalchiiina/dsh-chat-image-lightbox" title="点击打开 GitHub 仓库">' +
|
|
700
|
+
'<div class="p-name">🖼️ 推荐 · 照片显示器</div>' +
|
|
701
|
+
'<div class="p-desc">聊天图片灯箱:多图自动网格、全屏放大、高清下载——本插件悬浮球导航的好搭档</div>' +
|
|
702
|
+
'<div class="p-tag">dsh-chat-image-lightbox · 点击访问 ⭐ Star</div>' +
|
|
703
|
+
'</div>' +
|
|
704
|
+
'<div class="dsb-set-promo" data-ext-url="https://github.com/loyalchiiina/dsh-font-enhancer" title="点击打开 GitHub 仓库">' +
|
|
705
|
+
'<div class="p-name">🔤 推荐 · 字体插件</div>' +
|
|
706
|
+
'<div class="p-desc">界面分区自定义字体/颜色/字号,自带字体球与一键装字体——和技能球并排两个悬浮球</div>' +
|
|
707
|
+
'<div class="p-tag">dsh-font-enhancer · 点击访问 ⭐ Star</div>' +
|
|
708
|
+
'</div>' +
|
|
709
|
+
'<div class="dsb-set-promo" data-ext-url="https://github.com/loyalchiiina/dsh-todo-float-ball" title="点击打开 GitHub 仓库">' +
|
|
710
|
+
'<div class="p-name">📋 推荐 · Todo 悬浮球</div>' +
|
|
711
|
+
'<div class="p-desc">任务进度悬浮球:AI 的任务清单常驻屏幕,实时显示进行中步骤——多步长任务不错过进度(v0.9.0 已上 npm)</div>' +
|
|
712
|
+
'<div class="p-tag">dsh-todo-float-ball · 点击访问 ⭐ Star</div>' +
|
|
713
|
+
'</div>' +
|
|
714
|
+
'</div>' +
|
|
715
|
+
'<input id="dsb-q" class="dsb-q" type="text" placeholder="🔍 搜索技能名 / 中文简介 / 描述…" />' +
|
|
716
|
+
'<div id="dsb-sortbar" class="dsb-sortbar" style="display:none"></div>' +
|
|
717
|
+
'<div id="dsb-chips" class="dsb-chips"></div>' +
|
|
718
|
+
'<div id="dsb-subs" class="dsb-subs"></div>' +
|
|
719
|
+
'<div id="dsb-cards" class="dsb-cards"></div>' +
|
|
720
|
+
'<div id="dsb-ledger" class="dsb-ledger" style="display:none">' +
|
|
721
|
+
'<div id="dsb-ledger-sum" class="dsb-ledger-sum"></div>' +
|
|
722
|
+
'<div id="dsb-ledger-table" class="dsb-ledger-table"></div>' +
|
|
723
|
+
'</div>' +
|
|
724
|
+
'<div id="dsb-detail" class="dsb-detail" style="display:none">' +
|
|
725
|
+
'<div class="dsb-head">' +
|
|
726
|
+
'<div id="dsb-detail-title" class="dsb-title" style="font-size:14px"></div>' +
|
|
727
|
+
'<div class="dsb-headbtns">' +
|
|
728
|
+
'<button id="dsb-copy" class="dsb-btn" title="复制全文">复制</button>' +
|
|
729
|
+
'<button id="dsb-back" class="dsb-btn">← 返回</button>' +
|
|
730
|
+
'</div>' +
|
|
731
|
+
'</div>' +
|
|
732
|
+
'<pre id="dsb-detail-body" class="dsb-detail-body"></pre>' +
|
|
733
|
+
'</div>';
|
|
734
|
+
mountEl().appendChild(panel);
|
|
735
|
+
|
|
736
|
+
// v1.7.1 toast 轻提示容器:绝对定位在面板右上角(CSS .dsb-toast),初始隐藏
|
|
737
|
+
var toastHost = document.createElement("div");
|
|
738
|
+
toastHost.id = "dsb-toast";
|
|
739
|
+
toastHost.className = "dsb-toast";
|
|
740
|
+
panel.appendChild(toastHost);
|
|
741
|
+
|
|
742
|
+
// v1.7.2 三级滑块的批量确认菜单(面板内浮层,替代 window.confirm):
|
|
743
|
+
// 透明遮罩(点击任意处关闭)+ 菜单浮层(锚定在所点滑块下方,越界自动翻上来)
|
|
744
|
+
var bmenuMask = document.createElement("div");
|
|
745
|
+
bmenuMask.id = "dsb-bmenu-mask";
|
|
746
|
+
bmenuMask.className = "dsb-bmenu-mask";
|
|
747
|
+
bmenuMask.style.display = "none";
|
|
748
|
+
panel.appendChild(bmenuMask);
|
|
749
|
+
var bmenu = document.createElement("div");
|
|
750
|
+
bmenu.id = "dsb-bmenu";
|
|
751
|
+
bmenu.className = "dsb-bmenu";
|
|
752
|
+
bmenu.style.display = "none";
|
|
753
|
+
panel.appendChild(bmenu);
|
|
754
|
+
bmenu.addEventListener("click", function (ev) {
|
|
755
|
+
var it = ev.target.closest("[data-bmenu-act]");
|
|
756
|
+
if (!it) return;
|
|
757
|
+
var act = it.getAttribute("data-bmenu-act");
|
|
758
|
+
var scope = S.batchMenuScope;
|
|
759
|
+
closeBatchMenu();
|
|
760
|
+
if (!scope || act === "cancel") return;
|
|
761
|
+
if (act === "enable") batchToggle(scope, false);
|
|
762
|
+
else if (act === "disable") batchToggle(scope, true);
|
|
763
|
+
});
|
|
764
|
+
bmenuMask.addEventListener("click", function () { closeBatchMenu(); });
|
|
765
|
+
|
|
766
|
+
$("dsb-close").addEventListener("click", function () { closePanel(); });
|
|
767
|
+
$("dsb-refresh").addEventListener("click", function () { if (S.view === "ledger") loadLedgerRefresh(); else load(true); });
|
|
768
|
+
$("dsb-setting").addEventListener("click", function () {
|
|
769
|
+
var box = $("dsb-settings");
|
|
770
|
+
if (!box) return;
|
|
771
|
+
var show = box.style.display !== "block";
|
|
772
|
+
box.style.display = show ? "block" : "none";
|
|
773
|
+
if (show) { syncSettingsUI(); loadConfig(paintConfigStatus); }
|
|
774
|
+
});
|
|
775
|
+
var ballCb = $("dsb-set-ball"), fontCb = $("dsb-set-font");
|
|
776
|
+
if (ballCb) ballCb.addEventListener("change", function () {
|
|
777
|
+
writeStore(BALL_VIS_KEY, ballCb.checked);
|
|
778
|
+
applyBallVisibility();
|
|
779
|
+
if (!ballCb.checked && S.open) closePanel();
|
|
780
|
+
});
|
|
781
|
+
if (fontCb) fontCb.addEventListener("change", function () {
|
|
782
|
+
writeStore(FONT_BALL_VIS_KEY, fontCb.checked);
|
|
783
|
+
applyFontBallVisibility();
|
|
784
|
+
});
|
|
785
|
+
var ledgerCb = $("dsb-set-ledger");
|
|
786
|
+
if (ledgerCb) ledgerCb.addEventListener("change", function () {
|
|
787
|
+
saveConfig({ ledgerEnabled: ledgerCb.checked });
|
|
788
|
+
});
|
|
789
|
+
var rootSave = $("dsb-set-root-save");
|
|
790
|
+
if (rootSave) rootSave.addEventListener("click", function () {
|
|
791
|
+
var inp = $("dsb-set-root");
|
|
792
|
+
if (inp) saveConfig({ skillsDir: inp.value });
|
|
793
|
+
});
|
|
794
|
+
var rootBrowse = $("dsb-set-root-browse");
|
|
795
|
+
if (rootBrowse) rootBrowse.addEventListener("click", function () { browseForDirectory(); });
|
|
796
|
+
$("dsb-q").addEventListener("input", function () { S.q = this.value; S.sub = ""; paintChips(); paintSubs(); paintCards(); });
|
|
797
|
+
$("dsb-back").addEventListener("click", function () { S.detail = null; S.ledgerDetail = null; paint(); });
|
|
798
|
+
$("dsb-tab-skills").addEventListener("click", function () { S.view = "skills"; S.detail = null; S.ledgerDetail = null; paint(); });
|
|
799
|
+
$("dsb-tab-ledger").addEventListener("click", function () { S.view = "ledger"; S.detail = null; if (!S.ledger) loadLedger(); else paint(); });
|
|
800
|
+
$("dsb-ledger-table").addEventListener("click", function (ev) {
|
|
801
|
+
var el = ev.target.closest("[data-lskill]");
|
|
802
|
+
if (!el) return;
|
|
803
|
+
openLedgerDetail(el.getAttribute("data-lskill"));
|
|
804
|
+
});
|
|
805
|
+
$("dsb-chips").addEventListener("click", function (ev) {
|
|
806
|
+
var el = ev.target.closest("[data-cat]");
|
|
807
|
+
if (!el) return;
|
|
808
|
+
S.cat = el.getAttribute("data-cat");
|
|
809
|
+
S.sub = "";
|
|
810
|
+
paintChips(); paintSubs(); paintCards(); paintSortbar();
|
|
811
|
+
});
|
|
812
|
+
$("dsb-subs").addEventListener("click", function (ev) {
|
|
813
|
+
var el = ev.target.closest("[data-sub]");
|
|
814
|
+
if (!el) return;
|
|
815
|
+
S.sub = el.getAttribute("data-sub");
|
|
816
|
+
paintSubs(); paintCards();
|
|
817
|
+
});
|
|
818
|
+
// v1.7.0 排序切换 + v1.7.1 四态循环 + 分类级批量启停(事件委托到排序栏容器)
|
|
819
|
+
$("dsb-sortbar").addEventListener("click", function (ev) {
|
|
820
|
+
var sb = ev.target.closest("[data-sort]");
|
|
821
|
+
if (sb) {
|
|
822
|
+
// v1.7.1 四态循环:点击沿 SORT_ORDER 前进一步(名称↑→名称↓→时间↓→时间↑)
|
|
823
|
+
S.sortMode = nextSortMode(sb.getAttribute("data-sort") || S.sortMode);
|
|
824
|
+
paintSortbar(); paintCards();
|
|
825
|
+
return;
|
|
826
|
+
}
|
|
827
|
+
// v1.7.2 聚合滑块(全局 data-bagg="global" / 分类 data-bagg="<cat-id>"):
|
|
828
|
+
// 点击弹出面板内确认菜单(openBatchMenu),不再走 window.confirm
|
|
829
|
+
var agg = ev.target.closest("[data-bagg]");
|
|
830
|
+
if (agg) {
|
|
831
|
+
openBatchMenu(agg, agg.getAttribute("data-bagg") || "global");
|
|
832
|
+
return;
|
|
833
|
+
}
|
|
834
|
+
});
|
|
835
|
+
// v1.7.4 设置面板推广卡(data-ext-url)点击直达 GitHub:
|
|
836
|
+
// 广告卡迁入 #dsb-settings 后,原 #dsb-cards 委托覆盖不到,此处补一条同款委托。
|
|
837
|
+
$("dsb-settings").addEventListener("click", function (ev) {
|
|
838
|
+
var ext = ev.target.closest("[data-ext-url]");
|
|
839
|
+
if (ext) {
|
|
840
|
+
try { window.open(ext.getAttribute("data-ext-url"), "_blank", "noopener"); } catch (e2) {}
|
|
841
|
+
}
|
|
842
|
+
});
|
|
843
|
+
$("dsb-cards").addEventListener("click", function (ev) {
|
|
844
|
+
var ext = ev.target.closest("[data-ext-url]");
|
|
845
|
+
if (ext) {
|
|
846
|
+
try { window.open(ext.getAttribute("data-ext-url"), "_blank", "noopener"); } catch (e2) {}
|
|
847
|
+
return;
|
|
848
|
+
}
|
|
849
|
+
// v1.7.0 单技能启用/停用开关:点开关不打开详情(closest 先命中 tgl 按钮)
|
|
850
|
+
var tgl = ev.target.closest("[data-tgl]");
|
|
851
|
+
if (tgl) {
|
|
852
|
+
if (S.toggling) return;
|
|
853
|
+
var d1 = tgl.getAttribute("data-tgl");
|
|
854
|
+
var toDisabled = tgl.getAttribute("data-to") === "1";
|
|
855
|
+
toggleSkill(d1, toDisabled);
|
|
856
|
+
return;
|
|
857
|
+
}
|
|
858
|
+
var el = ev.target.closest("[data-dir]");
|
|
859
|
+
if (!el) return;
|
|
860
|
+
openDetail(el.getAttribute("data-dir"));
|
|
861
|
+
});
|
|
862
|
+
|
|
863
|
+
S.panelBuilt = true;
|
|
864
|
+
}
|
|
865
|
+
|
|
866
|
+
function closePanel() {
|
|
867
|
+
S.open = false;
|
|
868
|
+
S.detail = null;
|
|
869
|
+
S.batchMenuScope = null; // v1.7.2: 面板随 DOM 一起销毁,同步清确认菜单状态
|
|
870
|
+
var p = $(PANEL_ID);
|
|
871
|
+
if (p && p.parentNode) p.parentNode.removeChild(p);
|
|
872
|
+
var st = $("dsb-panel-style");
|
|
873
|
+
if (st && st.parentNode) st.parentNode.removeChild(st);
|
|
874
|
+
S.panelBuilt = false;
|
|
875
|
+
}
|
|
876
|
+
|
|
877
|
+
function openPanel() {
|
|
878
|
+
buildPanel();
|
|
879
|
+
S.open = true;
|
|
880
|
+
paint();
|
|
881
|
+
if (!S.data && !S.loading) load(false);
|
|
882
|
+
}
|
|
883
|
+
|
|
884
|
+
function paint() {
|
|
885
|
+
var panel = $(PANEL_ID);
|
|
886
|
+
if (!panel || !S.panelBuilt) return;
|
|
887
|
+
panel.style.display = S.open ? "flex" : "none";
|
|
888
|
+
if (!S.open) return;
|
|
889
|
+
var isLedger = S.view === "ledger";
|
|
890
|
+
var q = $("dsb-q"), chips = $("dsb-chips"), subs = $("dsb-subs"), cards = $("dsb-cards"), lg = $("dsb-ledger"), sortbar = $("dsb-sortbar");
|
|
891
|
+
if (q) q.style.display = isLedger ? "none" : "";
|
|
892
|
+
if (chips) chips.style.display = isLedger ? "none" : "";
|
|
893
|
+
if (subs) subs.style.display = isLedger ? "none" : "";
|
|
894
|
+
if (cards) cards.style.display = isLedger ? "none" : "";
|
|
895
|
+
if (sortbar) sortbar.style.display = isLedger ? "none" : "";
|
|
896
|
+
if (lg) lg.style.display = isLedger ? "block" : "none";
|
|
897
|
+
var t1 = $("dsb-tab-skills"), t2 = $("dsb-tab-ledger");
|
|
898
|
+
if (t1) t1.classList.toggle("dsb-tab-on", !isLedger);
|
|
899
|
+
if (t2) t2.classList.toggle("dsb-tab-on", isLedger);
|
|
900
|
+
paintHeader();
|
|
901
|
+
if (isLedger) paintLedger();
|
|
902
|
+
else { paintSortbar(); paintChips(); paintSubs(); paintCards(); }
|
|
903
|
+
paintDetail();
|
|
904
|
+
}
|
|
905
|
+
|
|
906
|
+
function paintHeader() {
|
|
907
|
+
var sub = $("dsb-subtitle");
|
|
908
|
+
if (!sub) return;
|
|
909
|
+
if (S.loading && !S.data) { sub.textContent = "扫描技能目录中…"; return; }
|
|
910
|
+
if (S.error) { sub.innerHTML = '<span style="color:#ff8f8f">' + esc(S.error) + '</span>'; return; }
|
|
911
|
+
if (!S.data) return;
|
|
912
|
+
var offCount = 0;
|
|
913
|
+
var sk = S.data.skills || [];
|
|
914
|
+
for (var i = 0; i < sk.length; i++) { if (sk[i].disabled) offCount++; }
|
|
915
|
+
sub.textContent = "共 " + S.data.total + " 个技能" +
|
|
916
|
+
(offCount ? "(" + offCount + " 已停用)" : "") +
|
|
917
|
+
" · " + (S.data.root || "?") +
|
|
918
|
+
" · 生成于 " + String(S.data.generatedAt || "").replace("T", " ").slice(0, 16);
|
|
919
|
+
}
|
|
920
|
+
|
|
921
|
+
function paintChips() {
|
|
922
|
+
var box = $("dsb-chips"); if (!box) return;
|
|
923
|
+
if (!S.data) { box.innerHTML = ""; return; }
|
|
924
|
+
var cs = S.data.categories || [];
|
|
925
|
+
var counts = {};
|
|
926
|
+
var sk = S.data.skills || [];
|
|
927
|
+
for (var i = 0; i < sk.length; i++) counts[sk[i].cat] = (counts[sk[i].cat] || 0) + 1;
|
|
928
|
+
var html = chip("all", "🧩 全部", S.data.total, S.cat === "all");
|
|
929
|
+
for (var j = 0; j < cs.length; j++) {
|
|
930
|
+
var c = cs[j];
|
|
931
|
+
html += chip(c.id, (c.icon || "") + " " + esc(c.label), counts[c.id] || 0, S.cat === c.id);
|
|
932
|
+
}
|
|
933
|
+
box.innerHTML = html;
|
|
934
|
+
}
|
|
935
|
+
function chip(id, label, count, active) {
|
|
936
|
+
return '<button class="dsb-chip' + (active ? " dsb-chip-on" : "") + '" data-cat="' + esc(id) + '">' +
|
|
937
|
+
esc(label) + ' <span class="dsb-n">' + count + "</span></button>";
|
|
938
|
+
}
|
|
939
|
+
|
|
940
|
+
function paintSubs() {
|
|
941
|
+
var box = $("dsb-subs"); if (!box) return;
|
|
942
|
+
var m = catMeta(S.cat);
|
|
943
|
+
if (!m || !m.subs || !m.subs.length || S.cat === "all") { box.innerHTML = ""; box.style.display = "none"; return; }
|
|
944
|
+
box.style.display = "flex";
|
|
945
|
+
var counts = {};
|
|
946
|
+
var sk = S.data.skills || [];
|
|
947
|
+
var q = S.q.trim().toLowerCase();
|
|
948
|
+
for (var i = 0; i < sk.length; i++) {
|
|
949
|
+
var s = sk[i];
|
|
950
|
+
if (s.cat !== S.cat) continue;
|
|
951
|
+
if (q && (s.dir + " " + s.name + " " + (s.zh || "") + " " + (s.desc || "")).toLowerCase().indexOf(q) < 0) continue;
|
|
952
|
+
counts[s.sub || "_"] = (counts[s.sub || "_"] || 0) + 1;
|
|
953
|
+
}
|
|
954
|
+
var total = 0, k;
|
|
955
|
+
for (k in counts) total += counts[k];
|
|
956
|
+
var html = '<button class="dsb-schip' + (S.sub === "" ? " dsb-chip-on" : "") + '" data-sub="">全部 ' + total + "</button>";
|
|
957
|
+
for (var j = 0; j < m.subs.length; j++) {
|
|
958
|
+
var sb = m.subs[j];
|
|
959
|
+
var n = counts[sb.id] || 0;
|
|
960
|
+
if (!n) continue;
|
|
961
|
+
html += '<button class="dsb-schip' + (S.sub === sb.id ? " dsb-chip-on" : "") + '" data-sub="' + esc(sb.id) + '">' +
|
|
962
|
+
esc(sb.label) + " " + n + "</button>";
|
|
963
|
+
}
|
|
964
|
+
box.innerHTML = html;
|
|
965
|
+
}
|
|
966
|
+
|
|
967
|
+
// ── v1.7.2 三级滑块:聚合态计算与渲染 ──
|
|
968
|
+
// aggCount:统计(可选按分类过滤)技能总数与已停用数——唯一数据源是
|
|
969
|
+
// S.data.skills 的 disabled 字段(内存数据,不额外请求)。
|
|
970
|
+
function aggCount(list, catFilter) {
|
|
971
|
+
var total = 0, off = 0;
|
|
972
|
+
for (var i = 0; i < list.length; i++) {
|
|
973
|
+
if (catFilter && list[i].cat !== catFilter) continue;
|
|
974
|
+
total++;
|
|
975
|
+
if (list[i].disabled) off++;
|
|
976
|
+
}
|
|
977
|
+
return { total: total, off: off };
|
|
978
|
+
}
|
|
979
|
+
// aggState:"on"=全部启用(右绿)| "off"=全部停用(左灰)| "half"=混合(居中半开)
|
|
980
|
+
function aggState(a) {
|
|
981
|
+
if (!a.total) return "off";
|
|
982
|
+
if (!a.off) return "on";
|
|
983
|
+
if (a.off >= a.total) return "off";
|
|
984
|
+
return "half";
|
|
985
|
+
}
|
|
986
|
+
// aggSwitchHtml:胶囊滑块 HTML(样式复用 .dsb-switch;state=on 加 dsb-sw-on、
|
|
987
|
+
// half 加 dsb-sw-half;label 可空——分类滑块不带文字标签,旁边小字显示 停用 x/y)
|
|
988
|
+
function aggSwitchHtml(state, attrs, title, label, small) {
|
|
989
|
+
var cls = "dsb-switch dsb-sw-agg" + (small ? " dsb-sw-sm" : "") +
|
|
990
|
+
(state === "on" ? " dsb-sw-on" : "") + (state === "half" ? " dsb-sw-half" : "");
|
|
991
|
+
return '<label class="' + cls + '" ' + attrs + ' title="' + esc(title || "") + '"' +
|
|
992
|
+
(S.toggling ? ' aria-disabled="true"' : "") + ">" +
|
|
993
|
+
'<span class="dsb-sw-track"><span class="dsb-sw-thumb"></span></span>' +
|
|
994
|
+
(label ? '<span class="dsb-sw-label">' + esc(label) + "</span>" : "") +
|
|
995
|
+
"</label>";
|
|
996
|
+
}
|
|
997
|
+
// ── v1.7.0 排序栏 + v1.7.1 四态循环按钮 + v1.7.2 三级滑块聚合开关 ──
|
|
998
|
+
// 排序单按钮显示当前排序态(点击循环);排序按钮右侧=全局总开关("全部技能");
|
|
999
|
+
// 选中具体分类时再追加分类级小滑块 + 小字"停用 x/y"。
|
|
1000
|
+
function sortLabel(m) {
|
|
1001
|
+
if (m === "name-asc") return T("sortNameAsc");
|
|
1002
|
+
if (m === "name-desc") return T("sortNameDesc");
|
|
1003
|
+
if (m === "mtime-asc") return T("sortMtimeAsc");
|
|
1004
|
+
if (m === "mtime-desc") return T("sortMtimeDesc");
|
|
1005
|
+
return T("sortNameAsc");
|
|
1006
|
+
}
|
|
1007
|
+
function paintSortbar() {
|
|
1008
|
+
var box = $("dsb-sortbar"); if (!box) return;
|
|
1009
|
+
var m = normalizeSortMode(S.sortMode);
|
|
1010
|
+
S.sortMode = m;
|
|
1011
|
+
var btns =
|
|
1012
|
+
'<button class="dsb-sortbtn dsb-sortbtn-on" data-sort="' + m + '" title="' + esc(T("sortCycleTitle")) + '">' +
|
|
1013
|
+
esc(sortLabel(m)) + '</button>';
|
|
1014
|
+
// v1.7.2 全局总开关(最重要):标签"全部技能",状态=所有技能聚合
|
|
1015
|
+
// (全启用→右绿 / 全停用→左灰 / 混合→居中半开+title"部分停用");
|
|
1016
|
+
// 点击任意态弹面板内确认菜单 openBatchMenu
|
|
1017
|
+
var sk = (S.data && S.data.skills) || [];
|
|
1018
|
+
var ga = aggCount(sk, null);
|
|
1019
|
+
var gs = aggState(ga);
|
|
1020
|
+
var gTitle = gs === "half" ? TF("aggMixedTitle", { x: ga.off, y: ga.total })
|
|
1021
|
+
: (gs === "on" ? T("aggAllOnTitle") : T("aggAllOffTitle"));
|
|
1022
|
+
var html = btns + aggSwitchHtml(gs, 'data-bagg="global"', gTitle, T("aggAllLabel"), false);
|
|
1023
|
+
// v1.7.2 分类级滑块:替换 v1.7.0 的"全启用/全停用"两个按钮——小一号胶囊
|
|
1024
|
+
// 滑块 + 旁边小字"停用 x/y"(该分类已停用数/总数),聚合逻辑同全局
|
|
1025
|
+
if (S.cat !== "all") {
|
|
1026
|
+
var ca = aggCount(sk, S.cat);
|
|
1027
|
+
var cs = aggState(ca);
|
|
1028
|
+
var cTitle = catLabel(S.cat) + " · " + (cs === "half" ? TF("aggMixedTitle", { x: ca.off, y: ca.total })
|
|
1029
|
+
: (cs === "on" ? T("aggAllOnTitle") : T("aggAllOffTitle")));
|
|
1030
|
+
html += '<span class="dsb-sw-sep"></span>' +
|
|
1031
|
+
aggSwitchHtml(cs, 'data-bagg="' + esc(S.cat) + '"', cTitle, "", true) +
|
|
1032
|
+
'<span class="dsb-batch-status">' + esc(TF("aggCatStat", { x: ca.off, y: ca.total })) + '</span>';
|
|
1033
|
+
}
|
|
1034
|
+
// v1.7.1 保留:批量进行中显示"处理中…"(滑块同时 aria-disabled 防重入)
|
|
1035
|
+
if (S.toggling) html += '<span class="dsb-batch-status">' + esc(T("processingText")) + '</span>';
|
|
1036
|
+
box.innerHTML = html;
|
|
1037
|
+
}
|
|
1038
|
+
|
|
1039
|
+
// v1.7.1:统一排序(总清单与分类内共用),四态口径——
|
|
1040
|
+
// name-asc:名称升序(A→Z,localeCompare);name-desc:名称降序(Z→A)
|
|
1041
|
+
// mtime-desc:修改时间新→旧(最新在前);mtime-asc:旧→新(最旧在前)
|
|
1042
|
+
// 同名/同时间的次序键用 dir 兜底,保证排序稳定可复现
|
|
1043
|
+
function sortList(list) {
|
|
1044
|
+
var m = normalizeSortMode(S.sortMode);
|
|
1045
|
+
var out = list.slice();
|
|
1046
|
+
if (m === "name-desc" || m === "name-asc") {
|
|
1047
|
+
out.sort(function (a, b) {
|
|
1048
|
+
var c = String(a.dir || "").localeCompare(String(b.dir || ""));
|
|
1049
|
+
return m === "name-asc" ? c : -c;
|
|
1050
|
+
});
|
|
1051
|
+
} else {
|
|
1052
|
+
out.sort(function (a, b) {
|
|
1053
|
+
var d = (Number(b.mtime) || 0) - (Number(a.mtime) || 0);
|
|
1054
|
+
if (!d) d = String(a.dir || "").localeCompare(String(b.dir || ""));
|
|
1055
|
+
return m === "mtime-desc" ? d : -d;
|
|
1056
|
+
});
|
|
1057
|
+
}
|
|
1058
|
+
return out;
|
|
1059
|
+
}
|
|
1060
|
+
|
|
1061
|
+
// v1.7.0:毫秒时间戳 → yyyy-MM-dd HH:mm(本地时区;非法/0 返回空)
|
|
1062
|
+
function fmtTime(ms) {
|
|
1063
|
+
var n = Number(ms);
|
|
1064
|
+
if (!isFinite(n) || n <= 0) return "";
|
|
1065
|
+
var d = new Date(n);
|
|
1066
|
+
if (isNaN(d.getTime())) return "";
|
|
1067
|
+
function p2(x) { return (x < 10 ? "0" : "") + x; }
|
|
1068
|
+
return d.getFullYear() + "-" + p2(d.getMonth() + 1) + "-" + p2(d.getDate()) + " " + p2(d.getHours()) + ":" + p2(d.getMinutes());
|
|
1069
|
+
}
|
|
1070
|
+
|
|
1071
|
+
// v1.7.1:面板内 toast 轻提示(右上角浮层,2 秒自动消失)。
|
|
1072
|
+
// kind="ok" 绿 / "err" 红;新提示覆盖旧提示并重置 2 秒计时;
|
|
1073
|
+
// 面板未构建/已关闭时元素不存在,静默跳过。
|
|
1074
|
+
function showToast(kind, text) {
|
|
1075
|
+
var el = $("dsb-toast");
|
|
1076
|
+
if (!el) return;
|
|
1077
|
+
el.className = "dsb-toast " + (kind === "err" ? "dsb-toast-err" : "dsb-toast-ok");
|
|
1078
|
+
el.textContent = text;
|
|
1079
|
+
el.classList.add("dsb-toast-show");
|
|
1080
|
+
if (S.toastTimer) { try { clearTimeout(S.toastTimer); } catch (e0) {} S.toastTimer = null; }
|
|
1081
|
+
S.toastTimer = setTimeout(function () {
|
|
1082
|
+
el.classList.remove("dsb-toast-show");
|
|
1083
|
+
S.toastTimer = null;
|
|
1084
|
+
}, 2000);
|
|
1085
|
+
}
|
|
1086
|
+
|
|
1087
|
+
// v1.7.1:单技能启用/停用(乐观更新)→ 点击瞬间先翻转滑块/灰显/徽章,
|
|
1088
|
+
// 再 POST /toggle;API 返回失败则回滚到请求前状态 + 红 toast。
|
|
1089
|
+
// 解决用户实测"点停用看不到任何变化"的问题:点击即有视觉反馈。
|
|
1090
|
+
function toggleSkill(dir, disable) {
|
|
1091
|
+
if (S.toggling) return;
|
|
1092
|
+
S.toggling = true;
|
|
1093
|
+
var sk = (S.data && S.data.skills) || [];
|
|
1094
|
+
var prev = null;
|
|
1095
|
+
for (var i = 0; i < sk.length; i++) {
|
|
1096
|
+
if (sk[i].dir === dir) { prev = !!sk[i].disabled; sk[i].disabled = !!disable; break; }
|
|
1097
|
+
}
|
|
1098
|
+
paintSortbar(); paintCards(); // 乐观重绘:滑块位置/颜色、卡片灰显、徽章立即变化
|
|
1099
|
+
fetch(apiBase() + "/toggle", {
|
|
1100
|
+
method: "POST",
|
|
1101
|
+
headers: { "content-type": "application/json" },
|
|
1102
|
+
body: JSON.stringify({ dir: dir, disable: disable })
|
|
1103
|
+
})
|
|
1104
|
+
.then(function (r) { return r.json().catch(function () { throw new Error("HTTP " + r.status); }); })
|
|
1105
|
+
.then(function (d) {
|
|
1106
|
+
S.toggling = false;
|
|
1107
|
+
if (d && d.ok) {
|
|
1108
|
+
ctxLogger("toggle " + dir + " -> " + (disable ? "disabled" : "enabled") + (d.backup ? " (backup ok)" : ""));
|
|
1109
|
+
showToast("ok", disable ? TF("toastDisabled", { name: dir }) : TF("toastEnabled", { name: dir }));
|
|
1110
|
+
} else {
|
|
1111
|
+
rollbackToggle(dir, prev, (d && d.error) || "unknown");
|
|
1112
|
+
}
|
|
1113
|
+
paintSortbar(); paintCards(); paintHeader(); // v1.7.2: paintHeader 同步副标题"已停用"计数
|
|
1114
|
+
})
|
|
1115
|
+
.catch(function (e) {
|
|
1116
|
+
S.toggling = false;
|
|
1117
|
+
rollbackToggle(dir, prev, (e && e.message ? e.message : e));
|
|
1118
|
+
paintSortbar(); paintCards(); paintHeader();
|
|
1119
|
+
});
|
|
1120
|
+
}
|
|
1121
|
+
// v1.7.1:toggle 失败回滚到请求前状态 + 红 toast(prevState 为请求前的 disabled 值)
|
|
1122
|
+
function rollbackToggle(dir, prevState, err) {
|
|
1123
|
+
var sk2 = (S.data && S.data.skills) || [];
|
|
1124
|
+
for (var i = 0; i < sk2.length; i++) {
|
|
1125
|
+
if (sk2[i].dir === dir) {
|
|
1126
|
+
if (prevState != null) sk2[i].disabled = prevState;
|
|
1127
|
+
break;
|
|
1128
|
+
}
|
|
1129
|
+
}
|
|
1130
|
+
showToast("err", TF("toastToggleFail", { err: err }));
|
|
1131
|
+
try { console.warn("[dsh-skill-browser] toggle " + dir + " failed: " + err); } catch (e) {}
|
|
1132
|
+
}
|
|
1133
|
+
|
|
1134
|
+
// v1.7.0:分类级全启用/全停用 → POST /toggle-batch
|
|
1135
|
+
// v1.7.1:进行中显示"处理中…"(防重入);完成后 toast 汇报"已停用/已启用 N 项"
|
|
1136
|
+
// (N=成功数),部分失败改报"成功 X 项,失败 Y 项"。
|
|
1137
|
+
// v1.7.2:升级为三级滑块统一批量执行入口 batchToggle(scope, disable)——
|
|
1138
|
+
// scope="global" → body={dirs:[全量技能目录]}(不用 category,直接传全量最稳);
|
|
1139
|
+
// scope=<cat-id> → body={category:"<cat-id>"};
|
|
1140
|
+
// 确认交互已上移到面板内确认菜单(openBatchMenu,替代 window.confirm),
|
|
1141
|
+
// 本函数只负责执行与三层联动刷新:①按 results 回写内存 disabled 字段;
|
|
1142
|
+
// ②patchCardsDisabled 局部刷新受影响卡片(不整列 innerHTML 重建,防闪烁);
|
|
1143
|
+
// ③paintSortbar 重算全局+分类聚合滑块与"停用 x/y"小字;④paintHeader 刷副标题。
|
|
1144
|
+
function batchToggle(scope, disable) {
|
|
1145
|
+
if (S.toggling) return;
|
|
1146
|
+
var isGlobal = scope === "global";
|
|
1147
|
+
var sk = (S.data && S.data.skills) || [];
|
|
1148
|
+
var dirs = [];
|
|
1149
|
+
for (var i = 0; i < sk.length; i++) {
|
|
1150
|
+
if (isGlobal || sk[i].cat === scope) dirs.push(sk[i].dir);
|
|
1151
|
+
}
|
|
1152
|
+
if (!dirs.length) return;
|
|
1153
|
+
S.toggling = true;
|
|
1154
|
+
paintSortbar(); // 聚合滑块进入"处理中…"半透明态(aria-disabled 防重入)
|
|
1155
|
+
var body = isGlobal ? { dirs: dirs, disable: disable } : { category: scope, disable: disable };
|
|
1156
|
+
fetch(apiBase() + "/toggle-batch", {
|
|
1157
|
+
method: "POST",
|
|
1158
|
+
headers: { "content-type": "application/json" },
|
|
1159
|
+
body: JSON.stringify(body)
|
|
1160
|
+
})
|
|
1161
|
+
.then(function (r) { return r.json().catch(function () { throw new Error("HTTP " + r.status); }); })
|
|
1162
|
+
.then(function (d) {
|
|
1163
|
+
S.toggling = false;
|
|
1164
|
+
if (d && d.ok) {
|
|
1165
|
+
var byDir = {};
|
|
1166
|
+
var changed = {};
|
|
1167
|
+
var res = d.results || [];
|
|
1168
|
+
for (var i2 = 0; i2 < res.length; i2++) {
|
|
1169
|
+
byDir[res[i2].dir] = res[i2];
|
|
1170
|
+
if (res[i2].ok) changed[res[i2].dir] = !!disable;
|
|
1171
|
+
}
|
|
1172
|
+
for (var j = 0; j < sk.length; j++) {
|
|
1173
|
+
var r2 = byDir[sk[j].dir];
|
|
1174
|
+
if (r2 && r2.ok) sk[j].disabled = !!disable;
|
|
1175
|
+
}
|
|
1176
|
+
patchCardsDisabled(changed); // ③卡片局部更新
|
|
1177
|
+
paintHeader(); // ④副标题"已停用"计数
|
|
1178
|
+
var okN = d.okCount || 0, fails = d.failCount || 0;
|
|
1179
|
+
if (fails) {
|
|
1180
|
+
showToast(fails >= okN ? "err" : "ok", TF("toastBatchPartial", { x: okN, y: fails }));
|
|
1181
|
+
} else {
|
|
1182
|
+
showToast("ok", TF(disable ? "toastBatchDisabled" : "toastBatchEnabled", { n: okN }));
|
|
1183
|
+
}
|
|
1184
|
+
ctxLogger("batch " + (isGlobal ? "global" : scope) + ": ok=" + okN + " fail=" + fails);
|
|
1185
|
+
} else {
|
|
1186
|
+
showToast("err", TF("toastToggleFail", { err: (d && d.error) || "unknown" }));
|
|
1187
|
+
try { console.warn("[dsh-skill-browser] batch failed: " + ((d && d.error) || "unknown")); } catch (e) {}
|
|
1188
|
+
}
|
|
1189
|
+
paintSortbar(); // ①②聚合滑块 + "停用 x/y" 小字重算刷新
|
|
1190
|
+
})
|
|
1191
|
+
.catch(function (e) {
|
|
1192
|
+
S.toggling = false;
|
|
1193
|
+
showToast("err", TF("toastToggleFail", { err: (e && e.message ? e.message : e) }));
|
|
1194
|
+
paintSortbar();
|
|
1195
|
+
try { console.warn("[dsh-skill-browser] batch error: " + (e && e.message ? e.message : e)); } catch (e2) {}
|
|
1196
|
+
});
|
|
1197
|
+
}
|
|
1198
|
+
|
|
1199
|
+
// v1.7.2:打开批量确认菜单(面板内浮层,锚定在所点聚合滑块下方,越界上翻)。
|
|
1200
|
+
// scope:"global" 或分类 id;N=当前作用域内技能总数;
|
|
1201
|
+
// 全局停用选项带醒目危险提示"将停用全部 N 项技能,新会话将不可用这些技能"。
|
|
1202
|
+
function openBatchMenu(anchor, scope) {
|
|
1203
|
+
if (S.toggling) return;
|
|
1204
|
+
var menu = $("dsb-bmenu"), mask = $("dsb-bmenu-mask"), panel = $(PANEL_ID);
|
|
1205
|
+
if (!menu || !mask || !panel || !anchor) return;
|
|
1206
|
+
var isGlobal = scope === "global";
|
|
1207
|
+
var a = aggCount((S.data && S.data.skills) || [], isGlobal ? null : scope);
|
|
1208
|
+
var n = a.total;
|
|
1209
|
+
var scopeName = isGlobal ? T("aggAllLabel") : catLabel(scope);
|
|
1210
|
+
var enSub = isGlobal ? "" : T("batchConfirmEnable");
|
|
1211
|
+
var disSub = isGlobal ? TF("aggDangerText", { n: n }) : T("batchConfirmDisable");
|
|
1212
|
+
menu.innerHTML =
|
|
1213
|
+
'<div class="dsb-bmenu-title">' + esc(isGlobal ? T("aggMenuTitleGlobal") : T("aggMenuTitleCat")) + '<br/>' +
|
|
1214
|
+
esc(TF("aggMenuStat", { scope: scopeName, n: n, x: a.off })) + '</div>' +
|
|
1215
|
+
'<button class="dsb-bmenu-item" data-bmenu-act="enable"><span>' + esc(TF("aggEnableN", { n: n })) + '</span>' +
|
|
1216
|
+
(enSub ? '<span class="dsb-bmenu-sub">' + esc(enSub) + '</span>' : "") + '</button>' +
|
|
1217
|
+
'<button class="dsb-bmenu-item dsb-bmenu-danger" data-bmenu-act="disable"><span>' + esc(TF("aggDisableN", { n: n })) + '</span>' +
|
|
1218
|
+
'<span class="dsb-bmenu-sub">⚠ ' + esc(disSub) + '</span></button>' +
|
|
1219
|
+
'<button class="dsb-bmenu-cancel" data-bmenu-act="cancel">' + esc(T("aggCancelText")) + '</button>';
|
|
1220
|
+
mask.style.display = "block";
|
|
1221
|
+
menu.style.display = "flex";
|
|
1222
|
+
S.batchMenuScope = scope;
|
|
1223
|
+
// 锚定:滑块下方 6px;右缘/下缘越界时向左/向上收进面板
|
|
1224
|
+
var ar = anchor.getBoundingClientRect();
|
|
1225
|
+
var pr = panel.getBoundingClientRect();
|
|
1226
|
+
var left = ar.left - pr.left;
|
|
1227
|
+
var top = ar.bottom - pr.top + 6;
|
|
1228
|
+
var mw = menu.offsetWidth, mh = menu.offsetHeight;
|
|
1229
|
+
var pw = panel.clientWidth, ph = panel.clientHeight;
|
|
1230
|
+
if (left + mw > pw - 8) left = Math.max(8, pw - mw - 8);
|
|
1231
|
+
if (top + mh > ph - 8) top = Math.max(8, ar.top - pr.top - mh - 6);
|
|
1232
|
+
menu.style.left = left + "px";
|
|
1233
|
+
menu.style.top = top + "px";
|
|
1234
|
+
}
|
|
1235
|
+
function closeBatchMenu() {
|
|
1236
|
+
S.batchMenuScope = null;
|
|
1237
|
+
var menu = $("dsb-bmenu"), mask = $("dsb-bmenu-mask");
|
|
1238
|
+
if (menu) menu.style.display = "none";
|
|
1239
|
+
if (mask) mask.style.display = "none";
|
|
1240
|
+
}
|
|
1241
|
+
|
|
1242
|
+
// v1.7.2:批量启停成功后的卡片局部更新——只改受影响卡片的类名/开关/徽章/
|
|
1243
|
+
// title,不重建 #dsb-cards 的 innerHTML(避免全列表闪烁)。DOM 里找不到的
|
|
1244
|
+
// 目录(被搜索/分类过滤掉的卡片)直接跳过,下次全量 paintCards 自然对齐。
|
|
1245
|
+
function patchCardsDisabled(map) {
|
|
1246
|
+
var box = $("dsb-cards"); if (!box) return;
|
|
1247
|
+
var cards = box.querySelectorAll('.dsb-card[data-dir]');
|
|
1248
|
+
for (var i = 0; i < cards.length; i++) {
|
|
1249
|
+
var card = cards[i];
|
|
1250
|
+
var dir = card.getAttribute("data-dir");
|
|
1251
|
+
if (!Object.prototype.hasOwnProperty.call(map, dir)) continue;
|
|
1252
|
+
var off = !!map[dir];
|
|
1253
|
+
card.classList.toggle("dsb-card-off", off);
|
|
1254
|
+
card.title = off ? T("cardDisabledTitle") : "点击查看 SKILL.md 全文";
|
|
1255
|
+
var sw = card.querySelector(".dsb-switch");
|
|
1256
|
+
if (sw) {
|
|
1257
|
+
sw.classList.toggle("dsb-sw-on", !off);
|
|
1258
|
+
sw.setAttribute("data-to", off ? "0" : "1");
|
|
1259
|
+
sw.title = off ? T("toggleEnableTip") : T("toggleDisableTip");
|
|
1260
|
+
var lbl = sw.querySelector(".dsb-sw-label");
|
|
1261
|
+
if (lbl) lbl.textContent = off ? T("switchOffText") : T("switchOnText");
|
|
1262
|
+
}
|
|
1263
|
+
var nameEl = card.querySelector(".dsb-card-name");
|
|
1264
|
+
if (nameEl) {
|
|
1265
|
+
var badge = nameEl.querySelector(".dsb-badge-off");
|
|
1266
|
+
if (off && !badge) {
|
|
1267
|
+
var b = document.createElement("span");
|
|
1268
|
+
b.className = "dsb-badge-off";
|
|
1269
|
+
b.textContent = T("disabledBadge");
|
|
1270
|
+
nameEl.appendChild(b);
|
|
1271
|
+
} else if (!off && badge && badge.parentNode) {
|
|
1272
|
+
badge.parentNode.removeChild(badge);
|
|
1273
|
+
}
|
|
1274
|
+
}
|
|
1275
|
+
}
|
|
1276
|
+
}
|
|
1277
|
+
function ctxLogger(msg) {
|
|
1278
|
+
try { console.log("[dsh-skill-browser] " + msg); } catch (e) {}
|
|
1279
|
+
}
|
|
1280
|
+
function paintCards() {
|
|
1281
|
+
var box = $("dsb-cards"); if (!box) return;
|
|
1282
|
+
if (S.error && !S.data) {
|
|
1283
|
+
box.innerHTML = '<div class="dsb-empty">' + esc(S.error) + '<br/><br/><button class="dsb-btn" id="dsb-retry">重试</button></div>';
|
|
1284
|
+
var r = $("dsb-retry");
|
|
1285
|
+
if (r) r.addEventListener("click", function () { load(true); });
|
|
1286
|
+
return;
|
|
1287
|
+
}
|
|
1288
|
+
if (!S.data) { box.innerHTML = '<div class="dsb-empty">加载中…</div>'; return; }
|
|
1289
|
+
var list = filtered();
|
|
1290
|
+
// v1.7.1 四态排序:名称↑(默认)/名称↓/时间↓(最新在前)/时间↑(最旧在前)
|
|
1291
|
+
list = sortList(list);
|
|
1292
|
+
if (!list.length) { box.innerHTML = '<div class="dsb-empty">没有匹配的技能</div>'; return; }
|
|
1293
|
+
var html = "";
|
|
1294
|
+
for (var i = 0; i < list.length; i++) {
|
|
1295
|
+
var s = list[i];
|
|
1296
|
+
var tag = s.sub ? esc(subLabel(s.cat, s.sub)) : esc(catLabel(s.cat));
|
|
1297
|
+
var brief = s.zh || (s.desc ? String(s.desc).slice(0, 90) + (s.desc.length > 90 ? "…" : "") : "(无描述)");
|
|
1298
|
+
var off = !!s.disabled;
|
|
1299
|
+
var mt = fmtTime(s.mtime);
|
|
1300
|
+
// v1.7.1 滑动开关:.dsb-sw-on=开启(绿轨+滑块右),无=停用(灰轨+滑块左)。
|
|
1301
|
+
// 状态唯一来源是 s.disabled;title 提示点击后的动作方向(off→点击启用)。
|
|
1302
|
+
html += '<div class="dsb-card' + (off ? " dsb-card-off" : "") + '" data-dir="' + esc(s.dir) + '" title="' + esc(off ? T("cardDisabledTitle") : "点击查看 SKILL.md 全文") + '">' +
|
|
1303
|
+
'<div class="dsb-card-name">' + esc(s.dir) + (off ? '<span class="dsb-badge-off">' + esc(T("disabledBadge")) + '</span>' : "") + "</div>" +
|
|
1304
|
+
'<div class="dsb-card-zh">' + esc(brief) + "</div>" +
|
|
1305
|
+
'<div class="dsb-card-tag">' + tag + "</div>" +
|
|
1306
|
+
(mt ? '<div class="dsb-card-mtime">' + esc(T("mtimeLabel")) + " " + esc(mt) + "</div>" : "") +
|
|
1307
|
+
'<div style="margin-top:6px">' +
|
|
1308
|
+
'<label class="dsb-switch' + (off ? "" : " dsb-sw-on") + '" data-tgl="' + esc(s.dir) + '" data-to="' + (off ? "0" : "1") +
|
|
1309
|
+
'" title="' + esc(off ? T("toggleEnableTip") : T("toggleDisableTip")) + '"' + (S.toggling ? ' aria-disabled="true"' : "") + '>' +
|
|
1310
|
+
'<span class="dsb-sw-track"><span class="dsb-sw-thumb"></span></span>' +
|
|
1311
|
+
'<span class="dsb-sw-label">' + esc(off ? T("switchOffText") : T("switchOnText")) + "</span>" +
|
|
1312
|
+
"</label>" +
|
|
1313
|
+
"</div>" +
|
|
1314
|
+
"</div>";
|
|
1315
|
+
}
|
|
1316
|
+
// ── v1.7.3/v1.7.4 用户指令:广告卡从技能清单彻底移除 ──
|
|
1317
|
+
// 技能列表/分类末尾恢复为纯技能卡列表(原 v1.7.2 追加在列表尾部的
|
|
1318
|
+
// 3 张推荐卡——🖼️照片显示器/🔤字体插件/💡悬浮球说明——已整体迁往
|
|
1319
|
+
// 设置面板 #dsb-settings 广告区,见 buildPanel 内注释)。
|
|
1320
|
+
box.innerHTML = html;
|
|
1321
|
+
}
|
|
1322
|
+
|
|
1323
|
+
function ledgerLevel(fails) {
|
|
1324
|
+
if (fails >= 4) return { cls: "dsb-lv-high", label: "高" };
|
|
1325
|
+
if (fails >= 2) return { cls: "dsb-lv-mid", label: "中" };
|
|
1326
|
+
return { cls: "dsb-lv-low", label: "低" };
|
|
1327
|
+
}
|
|
1328
|
+
|
|
1329
|
+
function paintLedger() {
|
|
1330
|
+
var sum = $("dsb-ledger-sum"), tbl = $("dsb-ledger-table");
|
|
1331
|
+
if (!sum || !tbl) return;
|
|
1332
|
+
if (S.loading && !S.ledger) { sum.innerHTML = '<div class="dsb-empty">台账加载中…</div>'; tbl.innerHTML = ""; return; }
|
|
1333
|
+
if (S.error && !S.ledger) { sum.innerHTML = '<div class="dsb-empty">' + esc(S.error) + '</div>'; tbl.innerHTML = ""; return; }
|
|
1334
|
+
if (!S.ledger) return;
|
|
1335
|
+
var l = S.ledger;
|
|
1336
|
+
var totalSkills = (S.data && S.data.total) || 0;
|
|
1337
|
+
var autoRecent = l.autoRecent || [];
|
|
1338
|
+
var autoFails = autoRecent.filter(function (x) { return !x.ok; }).length;
|
|
1339
|
+
var autoTotal = l.autoTotal || 0;
|
|
1340
|
+
var autoFailTotal = l.autoFailTotal || 0;
|
|
1341
|
+
sum.innerHTML =
|
|
1342
|
+
'<div class="dsb-lsum-card"><b>' + totalSkills + '</b><span>技能总数</span></div>' +
|
|
1343
|
+
'<div class="dsb-lsum-card dsb-lsum-fail"><b>' + l.totalFailSkills + '</b><span>人工·失败技能</span></div>' +
|
|
1344
|
+
'<div class="dsb-lsum-card dsb-lsum-fail"><b>' + l.totalFails + '</b><span>人工·累计失败</span></div>' +
|
|
1345
|
+
'<div class="dsb-lsum-card"><b>' + autoTotal + '</b><span>自动·调用总数</span></div>' +
|
|
1346
|
+
(autoFailTotal ? '<div class="dsb-lsum-card dsb-lsum-fail"><b>' + autoFailTotal + '</b><span>自动·失败</span></div>' : '');
|
|
1347
|
+
var rows = (l.entries || []).filter(function (e) { return e.fails > 0; });
|
|
1348
|
+
var html = '<div style="display:flex;align-items:center;gap:8px;font-size:12px;font-weight:600;margin:2px 0 6px">' +
|
|
1349
|
+
'<span>👤 人工台账</span>' +
|
|
1350
|
+
'<span style="font-weight:400;font-size:11px;color:#9aa1b5">技能生效-失效台账.md 统计表(人工维护 + 历史登记)</span>' +
|
|
1351
|
+
'</div>' +
|
|
1352
|
+
'<div class="dsb-ltable">' +
|
|
1353
|
+
'<div class="dsb-lrow dsb-lhead"><span class="dsb-lc-rank">#</span><span class="dsb-lc-skill">技能名</span><span class="dsb-lc-fail">失败</span><span class="dsb-lc-rate">等级</span><span class="dsb-lc-date">最近失败</span><span class="dsb-lc-status">强化状态</span></div>';
|
|
1354
|
+
if (!rows.length) {
|
|
1355
|
+
html += '<div class="dsb-lrow"><span class="dsb-lc-skill" style="opacity:.7;line-height:1.8">暂无人工登记。<br/>💡 技能触发失败时,在对话里说「<b>触发失败,登记</b>」或「<b>登记失败:技能名 原因</b>」,AI 会自动写入台账;<br/>插件也会自动记录每次技能调用(见下方 🤖 自动登记)。</span></div>';
|
|
1356
|
+
}
|
|
1357
|
+
for (var i = 0; i < rows.length; i++) {
|
|
1358
|
+
var e = rows[i];
|
|
1359
|
+
var lv = ledgerLevel(e.fails);
|
|
1360
|
+
var status = e.status || "";
|
|
1361
|
+
var statusCls = /待强化|⚠/.test(status) ? "dsb-lst-warn" : /已强化/.test(status) ? "dsb-lst-done" : "dsb-lst-ok";
|
|
1362
|
+
html += '<div class="dsb-lrow" data-lskill="' + esc(e.skill) + '" title="点击查看失败明细">' +
|
|
1363
|
+
'<span class="dsb-lc-rank">' + esc(e.rank || "—") + '</span>' +
|
|
1364
|
+
'<span class="dsb-lc-skill">' + esc(e.skill) + '</span>' +
|
|
1365
|
+
'<span class="dsb-lc-fail">' + e.fails + '</span>' +
|
|
1366
|
+
'<span class="dsb-lc-rate"><span class="' + lv.cls + '">' + lv.label + '</span></span>' +
|
|
1367
|
+
'<span class="dsb-lc-date">' + esc(e.lastDate || "—") + '</span>' +
|
|
1368
|
+
'<span class="dsb-lc-status ' + statusCls + '">' + esc(status) + '</span>' +
|
|
1369
|
+
'</div>';
|
|
1370
|
+
}
|
|
1371
|
+
html += '</div>';
|
|
1372
|
+
// 自动登记流水(与人工台账分开的独立区块,最新在上)
|
|
1373
|
+
var auto = l.autoRecent || [];
|
|
1374
|
+
html += '<div style="display:flex;align-items:center;gap:8px;font-size:12px;font-weight:600;margin:14px 0 6px;padding-top:10px;border-top:1px solid rgba(255,255,255,.08)">' +
|
|
1375
|
+
'<span>🤖 自动登记</span>' +
|
|
1376
|
+
'<span style="font-weight:400;font-size:11px;color:#9aa1b5">dsh-skill-browser 插件监听 skill 工具调用结果自动记录 · 近 ' + auto.length + ' 条,最新在前</span>' +
|
|
1377
|
+
'</div>';
|
|
1378
|
+
if (!auto.length) {
|
|
1379
|
+
html += '<div class="dsb-empty" style="padding:14px 0">暂无自动记录 — 插件会记录每次技能工具调用结果(成功✅ / 失败❌)</div>';
|
|
1380
|
+
} else {
|
|
1381
|
+
html += '<div class="dsb-ltable">';
|
|
1382
|
+
for (var a = 0; a < auto.length; a++) {
|
|
1383
|
+
var x = auto[a];
|
|
1384
|
+
var mark = x.ok ? "✅" : "❌";
|
|
1385
|
+
var cls = x.ok ? "dsb-lst-done" : "dsb-lst-warn";
|
|
1386
|
+
var note = x.note || x.error || "";
|
|
1387
|
+
html += '<div class="dsb-lrow" style="font-size:11.5px' + (x.ok ? ';opacity:.62' : '') + '"' + (x.ok ? '' : ' data-lskill="' + esc(x.skill) + '" title="点击查看失败详情"') + '>' +
|
|
1388
|
+
'<span class="dsb-lc-date" style="width:110px;flex:none">' + esc(String(x.ts || "").replace("T", " ").slice(5, 16)) + '</span>' +
|
|
1389
|
+
'<span class="' + cls + '" style="width:22px;flex:none;text-align:center">' + mark + '</span>' +
|
|
1390
|
+
'<span class="dsb-lc-skill" style="flex:1">' + esc(x.skill) + '</span>' +
|
|
1391
|
+
'<span style="width:64px;flex:none;color:#8b93a8;font-size:10.5px">' + esc(x.kind === "manual-report" ? "人工上报" : "工具结果") + '</span>' +
|
|
1392
|
+
'<span style="flex:2;color:#9aa1b5;overflow:hidden;text-overflow:ellipsis;white-space:nowrap">' + esc(x.kind || "") + (note ? " — " + esc(note.slice(0, 80)) : "") + '</span>' +
|
|
1393
|
+
'</div>';
|
|
1394
|
+
}
|
|
1395
|
+
html += '</div>';
|
|
1396
|
+
}
|
|
1397
|
+
tbl.innerHTML = html;
|
|
1398
|
+
}
|
|
1399
|
+
|
|
1400
|
+
function paintDetail() {
|
|
1401
|
+
var d = $("dsb-detail"); if (!d) return;
|
|
1402
|
+
var isLedgerDetail = S.view === "ledger" && S.ledgerDetail;
|
|
1403
|
+
if (S.detail || isLedgerDetail) {
|
|
1404
|
+
d.style.display = "flex";
|
|
1405
|
+
var t = $("dsb-detail-title");
|
|
1406
|
+
if (t) {
|
|
1407
|
+
if (isLedgerDetail) t.textContent = "📋 " + S.ledgerDetail.skill + " — 失败明细";
|
|
1408
|
+
else t.textContent = "📄 " + S.detail.dir + " / SKILL.md";
|
|
1409
|
+
}
|
|
1410
|
+
var b = $("dsb-detail-body");
|
|
1411
|
+
if (b && !b.textContent) b.textContent = "加载中…";
|
|
1412
|
+
} else {
|
|
1413
|
+
d.style.display = "none";
|
|
1414
|
+
}
|
|
1415
|
+
}
|
|
1416
|
+
|
|
1417
|
+
function syncSettingsUI() {
|
|
1418
|
+
var ballCb = $("dsb-set-ball"), fontCb = $("dsb-set-font");
|
|
1419
|
+
if (ballCb) ballCb.checked = readStore(BALL_VIS_KEY, true);
|
|
1420
|
+
if (fontCb) fontCb.checked = readStore(FONT_BALL_VIS_KEY, true);
|
|
1421
|
+
try { fillSkinSelect($("dsb-set-skin")); } catch (eSkin) {}
|
|
1422
|
+
}
|
|
1423
|
+
|
|
1424
|
+
// ---- 球体样式 + 字体球统一样式 + 显隐规则(纯 CSS,永久生效)----
|
|
1425
|
+
var CSS = [
|
|
1426
|
+
/* 技能球 */
|
|
1427
|
+
'#' + BALL_ID + '{position:fixed;right:74px;bottom:18px;width:46px;height:46px;border-radius:50%;background:radial-gradient(circle at 50% 60%, rgba(255,255,255,.98) 0%, rgba(214,232,247,.9) 9%, rgba(111,158,232,.7) 18%, rgba(165,46,255,.5) 32%, rgba(206,44,203,.35) 46%, rgba(10,14,30,.9) 66%, rgba(4,6,14,.99) 100%);box-shadow:0 0 22px rgba(111,158,232,.45),0 0 4px rgba(206,44,203,.3),0 4px 18px rgba(0,0,0,.55),inset 0 1px 3px rgba(255,255,255,.4),inset 0 -8px 16px rgba(206,44,203,.14),inset 0 0 14px rgba(80,120,255,.2);color:#ffffff;font-size:15px;font-weight:800;display:flex;align-items:center;justify-content:center;text-shadow:0 0 4px rgba(255,255,255,.95),0 0 10px rgba(160,200,255,.9),0 0 20px rgba(120,90,255,.7),0 2px 4px rgba(10,20,60,.8);filter:drop-shadow(0 0 6px rgba(180,210,255,.8));animation:dsbGlow 2.4s ease-in-out infinite;cursor:grab;z-index:2147481000;user-select:none;touch-action:none;animation:orbBreathe 3.2s ease-in-out infinite;}',
|
|
1428
|
+
'#' + BALL_ID + ':hover{transform:scale(1.08)}',
|
|
1429
|
+
'#' + BALL_ID + '::before{content:"";position:absolute;inset:1px;border-radius:50%;z-index:1;background:radial-gradient(ellipse 85% 26% at 50% 60%, rgba(255,255,255,1) 0%, rgba(235,245,255,.85) 18%, rgba(160,200,255,.5) 38%, rgba(190,120,255,.35) 55%, transparent 75%),radial-gradient(ellipse 70% 18% at 45% 42%, rgba(111,158,232,.55) 0%, transparent 70%),radial-gradient(ellipse 70% 18% at 55% 74%, rgba(206,44,203,.4) 0%, transparent 70%);filter:blur(1px);animation:bandFlow 4.5s ease-in-out infinite;}',
|
|
1430
|
+
'#' + BALL_ID + '::after{content:"";position:absolute;inset:-1px;border-radius:50%;z-index:1;background:conic-gradient(from 200deg, rgba(255,255,255,.55), rgba(140,180,255,.35), rgba(206,44,203,.4), rgba(255,255,255,.15), rgba(111,158,232,.4), rgba(255,255,255,.55));-webkit-mask:radial-gradient(circle, transparent 63%, #000 66%, #000 72%, transparent 76%);mask:radial-gradient(circle, transparent 63%, #000 66%, #000 72%, transparent 76%);animation:rimSpin 7s linear infinite;filter:blur(.5px);}',
|
|
1431
|
+
'@keyframes bandFlow{0%,100%{transform:translateY(-3px) scaleY(.94);opacity:.8}50%{transform:translateY(3px) scaleY(1.12);opacity:1}}',
|
|
1432
|
+
'@keyframes rimSpin{0%{transform:rotate(0deg)}100%{transform:rotate(360deg)}}',
|
|
1433
|
+
'@keyframes orbBreathe{0%,100%{transform:scale(.96);filter:brightness(.92)}50%{transform:scale(1.05);filter:brightness(1.12)}}',
|
|
1434
|
+
'@keyframes dsbGlow{0%,100%{text-shadow:0 0 4px rgba(255,255,255,.95),0 0 10px rgba(160,200,255,.9),0 0 20px rgba(120,90,255,.7)}50%{text-shadow:0 0 6px rgba(255,255,255,1),0 0 16px rgba(190,220,255,1),0 0 32px rgba(140,110,255,.9)}}',
|
|
1435
|
+
'#' + BALL_ID + ':hover{transform:scale(1.08)}',
|
|
1436
|
+
'#' + BALL_ID + ' .dsb-orb-fallback{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;font-size:17px;color:#9aa1b5;z-index:1}',
|
|
1437
|
+
'#' + BALL_ID + ':hover{transform:scale(1.08)}',
|
|
1438
|
+
'#' + BALL_ID + '.dsb-ghost{width:12px!important;height:12px!important;font-size:0!important;right:10px!important;bottom:10px!important;opacity:.3}',
|
|
1439
|
+
'#' + BALL_ID + '.dsb-ghost:hover{opacity:.8}',
|
|
1440
|
+
/* 字体球视觉:v1.5.9 起 font-enhancer 自带暖色极光玻璃样式,本插件不再代管其外观(避免覆盖);显隐控制见下方 data-dsb-font-hidden 规则 */
|
|
1441
|
+
/* 显隐开关:取消勾选=彻底隐藏球(display:none),勾选=显示原版 46px 大球 */
|
|
1442
|
+
'[data-dsb-ball-hidden="1"] #' + BALL_ID + '{display:none!important}',
|
|
1443
|
+
'[data-dsb-font-hidden="1"] #dsh-fe-toggle{display:none!important}'
|
|
1444
|
+
].join('\n');
|
|
1445
|
+
|
|
1446
|
+
function restoreBallPos(ball) {
|
|
1447
|
+
try {
|
|
1448
|
+
var raw = localStorage.getItem(BALL_POS_KEY);
|
|
1449
|
+
if (!raw) return;
|
|
1450
|
+
var p = JSON.parse(raw);
|
|
1451
|
+
if (typeof p.left === "number" && typeof p.top === "number") {
|
|
1452
|
+
ball.style.left = p.left + "px";
|
|
1453
|
+
ball.style.top = p.top + "px";
|
|
1454
|
+
ball.style.right = "auto";
|
|
1455
|
+
ball.style.bottom = "auto";
|
|
1456
|
+
}
|
|
1457
|
+
} catch (e) {}
|
|
1458
|
+
}
|
|
1459
|
+
function saveBallPos(ball) {
|
|
1460
|
+
try {
|
|
1461
|
+
localStorage.setItem(BALL_POS_KEY, JSON.stringify({ left: ball.offsetLeft, top: ball.offsetTop }));
|
|
1462
|
+
} catch (e) {}
|
|
1463
|
+
}
|
|
1464
|
+
|
|
1465
|
+
// v1.5.6 字体插件安装探测:dsh-fe-toggle 元素存在 = font-enhancer client 已运行。
|
|
1466
|
+
// 元素存在不依赖球显隐(隐藏是 CSS display,DOM 仍在);卸载/禁用后元素消失。
|
|
1467
|
+
function isFontEnhancerInstalled() {
|
|
1468
|
+
try { return !!document.getElementById("dsh-fe-toggle"); } catch (e) { return false; }
|
|
1469
|
+
}
|
|
1470
|
+
// Todo 球安装探测(兼容):dsh-todo-float-ball 未装时隐藏其开关,避免无效控件
|
|
1471
|
+
function isTodoBallInstalled() {
|
|
1472
|
+
try { return !!document.getElementById("dsh-tfb-root"); } catch (e) { return false; }
|
|
1473
|
+
}
|
|
1474
|
+
|
|
1475
|
+
// v1.5.3 一键恢复默认位置:清位置记忆与收起/隐藏状态,球立即回右下角默认位。
|
|
1476
|
+
// 供 DSH 设置页「悬浮球导航」分区按钮调用(球可能被拖出屏幕外卡住,无法点回)。
|
|
1477
|
+
// v1.5.7 推荐位安装徽标:探测三个插件的 client 运行状态,注入「已安装/未安装」徽标。
|
|
1478
|
+
function recBadgeInstalled(id) {
|
|
1479
|
+
if (id === "font") return !!document.getElementById("dsh-fe-toggle");
|
|
1480
|
+
if (id === "todoball") return isTodoBallInstalled();
|
|
1481
|
+
if (id === "skillbrowser") return !!document.getElementById(BALL_ID);
|
|
1482
|
+
return false; // lightbox 用异步 fetch 判定,不走这里
|
|
1483
|
+
}
|
|
1484
|
+
function markRecBadge(recId, installed) {
|
|
1485
|
+
var row = document.querySelector('[data-rec-id="' + recId + '"]');
|
|
1486
|
+
if (!row || row.querySelector(".fe-rec-badge")) return;
|
|
1487
|
+
var badge = document.createElement("span");
|
|
1488
|
+
badge.className = "fe-rec-badge";
|
|
1489
|
+
badge.textContent = installed ? "已安装" : "未安装";
|
|
1490
|
+
badge.style.cssText = "flex-shrink:0;margin-left:8px;font-size:11px;padding:2px 8px;border-radius:6px;" +
|
|
1491
|
+
(installed ? "background:rgba(120,220,150,.15);border:1px solid rgba(120,220,150,.4);color:#9fe0b5"
|
|
1492
|
+
: "background:rgba(255,120,120,.15);border:1px solid rgba(255,120,120,.35);color:#ffb3b3") +
|
|
1493
|
+
";white-space:nowrap";
|
|
1494
|
+
var star = row.querySelector("a");
|
|
1495
|
+
if (star) row.insertBefore(badge, star); else row.appendChild(badge);
|
|
1496
|
+
}
|
|
1497
|
+
function applyRecBadges() {
|
|
1498
|
+
["font", "skillbrowser", "lightbox"].forEach(function (id) {
|
|
1499
|
+
if (id === "lightbox") {
|
|
1500
|
+
try {
|
|
1501
|
+
fetch("/api/image-gallery/list").then(function (r) {
|
|
1502
|
+
markRecBadge("lightbox", r.ok);
|
|
1503
|
+
}).catch(function () { markRecBadge("lightbox", false); });
|
|
1504
|
+
} catch (e) { markRecBadge("lightbox", false); }
|
|
1505
|
+
} else {
|
|
1506
|
+
markRecBadge(id, recBadgeInstalled(id));
|
|
1507
|
+
}
|
|
1508
|
+
});
|
|
1509
|
+
}
|
|
1510
|
+
function resetBallToDefault() {
|
|
1511
|
+
try { localStorage.removeItem(BALL_POS_KEY); } catch (e) {}
|
|
1512
|
+
try { writeStore(BALL_VIS_KEY, true); } catch (e) {}
|
|
1513
|
+
try { writeStore(GHOST_KEY, false); } catch (e) {}
|
|
1514
|
+
var b = $(BALL_ID);
|
|
1515
|
+
if (b) {
|
|
1516
|
+
b.style.left = ""; b.style.top = "";
|
|
1517
|
+
b.style.right = "74px"; b.style.bottom = "18px";
|
|
1518
|
+
b.classList.remove("dsb-ghost");
|
|
1519
|
+
}
|
|
1520
|
+
try { applyBallVisibility(); } catch (e) {}
|
|
1521
|
+
// v1.5.6 双球联动(仅字体插件已安装时挂载):🎯 复位时顺带把字体球归位
|
|
1522
|
+
// (右下角 right:18px bottom:18px)。跨插件组合:只清位置记忆 + DOM 归位。
|
|
1523
|
+
if (isFontEnhancerInstalled()) try {
|
|
1524
|
+
var FE_POS_KEY = "dsh-font-enhancer";
|
|
1525
|
+
var raw = localStorage.getItem(FE_POS_KEY);
|
|
1526
|
+
if (raw) {
|
|
1527
|
+
var data = JSON.parse(raw);
|
|
1528
|
+
data.bx = null; data.by = null;
|
|
1529
|
+
localStorage.setItem(FE_POS_KEY, JSON.stringify(data));
|
|
1530
|
+
}
|
|
1531
|
+
} catch (e) {}
|
|
1532
|
+
try {
|
|
1533
|
+
var feBall = document.getElementById("dsh-fe-toggle");
|
|
1534
|
+
if (feBall) {
|
|
1535
|
+
feBall.style.left = "auto"; feBall.style.top = "auto";
|
|
1536
|
+
feBall.style.right = "18px"; feBall.style.bottom = "18px";
|
|
1537
|
+
}
|
|
1538
|
+
} catch (e) {}
|
|
1539
|
+
// v0.7.2 三球联动:🎯 复位时顺带把 Todo 球归位(右下角 right:18px bottom:18px)。
|
|
1540
|
+
// 同字体球模式:只清位置记忆 + DOM 归位,不动 todo 插件内部实现。
|
|
1541
|
+
try { localStorage.removeItem("dsh-todo-float-ball-pos"); } catch (e) {}
|
|
1542
|
+
try {
|
|
1543
|
+
var tfbHost = document.getElementById("dsh-tfb-root");
|
|
1544
|
+
var tfb = tfbHost && tfbHost.shadowRoot ? tfbHost.shadowRoot.querySelector(".tfb-ball") : null;
|
|
1545
|
+
if (tfb) {
|
|
1546
|
+
tfb.style.left = "auto"; tfb.style.top = "auto";
|
|
1547
|
+
tfb.style.right = "18px"; tfb.style.bottom = "18px";
|
|
1548
|
+
}
|
|
1549
|
+
} catch (e) {}
|
|
1550
|
+
try { console.log("[dsh-skill-browser] reset: skill ball + font ball + todo ball -> default positions (paired bottom-right)"); } catch (e) {}
|
|
1551
|
+
}
|
|
1552
|
+
|
|
1553
|
+
function buildBall() {
|
|
1554
|
+
if ($(BALL_ID)) return;
|
|
1555
|
+
var style = document.createElement("style");
|
|
1556
|
+
style.id = "dsb-ball-style";
|
|
1557
|
+
style.textContent = CSS;
|
|
1558
|
+
document.head.appendChild(style);
|
|
1559
|
+
|
|
1560
|
+
var ball = document.createElement("div");
|
|
1561
|
+
ball.id = BALL_ID;
|
|
1562
|
+
ball.title = "技能插件(点击开关面板,可拖动,Alt+点击 收起成小圆点)";
|
|
1563
|
+
ball.textContent = "技";
|
|
1564
|
+
|
|
1565
|
+
var drag = { active: false, moved: false, sx: 0, sy: 0, ox: 0, oy: 0 };
|
|
1566
|
+
ball.addEventListener("pointerdown", function (e) {
|
|
1567
|
+
drag.active = true; drag.moved = false;
|
|
1568
|
+
drag.sx = e.clientX; drag.sy = e.clientY;
|
|
1569
|
+
var r = ball.getBoundingClientRect();
|
|
1570
|
+
drag.ox = r.left; drag.oy = r.top;
|
|
1571
|
+
ball.style.transition = "none";
|
|
1572
|
+
try { ball.setPointerCapture(e.pointerId); } catch (e2) {}
|
|
1573
|
+
});
|
|
1574
|
+
ball.addEventListener("pointermove", function (e) {
|
|
1575
|
+
if (!drag.active) return;
|
|
1576
|
+
var dx = e.clientX - drag.sx, dy = e.clientY - drag.sy;
|
|
1577
|
+
if (Math.abs(dx) > 3 || Math.abs(dy) > 3) drag.moved = true;
|
|
1578
|
+
ball.style.left = (drag.ox + dx) + "px";
|
|
1579
|
+
ball.style.top = (drag.oy + dy) + "px";
|
|
1580
|
+
ball.style.right = "auto";
|
|
1581
|
+
ball.style.bottom = "auto";
|
|
1582
|
+
});
|
|
1583
|
+
function endDrag() {
|
|
1584
|
+
if (!drag.active) return;
|
|
1585
|
+
drag.active = false;
|
|
1586
|
+
ball.style.transition = "";
|
|
1587
|
+
if (drag.moved) saveBallPos(ball);
|
|
1588
|
+
}
|
|
1589
|
+
ball.addEventListener("pointerup", endDrag);
|
|
1590
|
+
ball.addEventListener("pointercancel", endDrag);
|
|
1591
|
+
|
|
1592
|
+
ball.addEventListener("click", function (ev) {
|
|
1593
|
+
if (drag.moved) { drag.moved = false; return; }
|
|
1594
|
+
if (ev.altKey) {
|
|
1595
|
+
var ghost = !isGhost();
|
|
1596
|
+
writeStore(GHOST_KEY, ghost);
|
|
1597
|
+
if (ghost) closePanel();
|
|
1598
|
+
paintGhost();
|
|
1599
|
+
return;
|
|
1600
|
+
}
|
|
1601
|
+
if (S.open) closePanel();
|
|
1602
|
+
else openPanel();
|
|
1603
|
+
});
|
|
1604
|
+
mountEl().appendChild(ball);
|
|
1605
|
+
restoreBallPos(ball);
|
|
1606
|
+
paintGhost();
|
|
1607
|
+
applyBallVisibility();
|
|
1608
|
+
}
|
|
1609
|
+
|
|
1610
|
+
function paintGhost() {
|
|
1611
|
+
var b = $(BALL_ID);
|
|
1612
|
+
if (!b) return;
|
|
1613
|
+
if (isGhost()) b.classList.add("dsb-ghost");
|
|
1614
|
+
else b.classList.remove("dsb-ghost");
|
|
1615
|
+
}
|
|
1616
|
+
|
|
1617
|
+
// ---- unified ball skin system (shared 128 skins, three-ball sync) ----
|
|
1618
|
+
var SKIN = window.__DSH_BALL_SKINS || null;
|
|
1619
|
+
var SKIN_STYLE_ID = "dsb-skin-style";
|
|
1620
|
+
function skinBallCss() {
|
|
1621
|
+
if (!SKIN) return "";
|
|
1622
|
+
var id = SKIN.getId();
|
|
1623
|
+
var s = SKIN.BY_ID[id];
|
|
1624
|
+
if (!s) return "";
|
|
1625
|
+
var B = "#dsh-skill-browser-ball", BAND = B + "::before", RIM = B + "::after";
|
|
1626
|
+
var css = SKIN.varsCss(B, id);
|
|
1627
|
+
css += "\n" + B + "{border-radius:50%!important;background:radial-gradient(circle at 32% 24%,var(--spec,rgba(255,255,255,.16)) 0%,rgba(255,255,255,.03) 28%,rgba(255,255,255,0) 46%),linear-gradient(158deg,var(--bgA,#262b33),var(--bgB,#101319))!important;border:1px solid var(--edge,rgba(255,255,255,.14))!important;box-shadow:inset 0 1px 0 var(--hi,rgba(255,255,255,.12)),0 5px 14px rgba(0,0,0,.42)!important;color:var(--lbc,#eef1f6)!important;text-shadow:0 0 6px var(--stA,transparent)!important;filter:none!important}";
|
|
1628
|
+
if (s.anim === "flashy") css += "\n" + B + "{animation:orbBreathe 3.2s ease-in-out infinite!important}";
|
|
1629
|
+
css += "\n" + BAND + "{content:\"\";position:absolute;inset:0;border-radius:inherit;z-index:1;background:radial-gradient(circle at 50% 122%,var(--stA,#888) 0%,transparent 54%);opacity:.13;filter:none;animation:none}";
|
|
1630
|
+
css += "\n" + RIM + "{content:none}";
|
|
1631
|
+
css += "\n@keyframes dshSkinSpin{0%{transform:rotate(0)}100%{transform:rotate(360deg)}}\n@keyframes dshSkinSpinR{0%{transform:rotate(0)}100%{transform:rotate(-360deg)}}";
|
|
1632
|
+
css += "\n" + SKIN.fx(id, { B: B, BAND: BAND, RIM: RIM });
|
|
1633
|
+
if (s.rim) css += "\n" + RIM + "{content:\"\"}";
|
|
1634
|
+
return css;
|
|
1635
|
+
}
|
|
1636
|
+
function skinPanelCss() {
|
|
1637
|
+
if (!SKIN) return "";
|
|
1638
|
+
var P = "#dsh-skill-browser-panel";
|
|
1639
|
+
var id = SKIN.getId();
|
|
1640
|
+
var css = SKIN.varsCss(P, id);
|
|
1641
|
+
css += "\n" + P + "{background:linear-gradient(180deg,var(--pbgA,rgba(24,26,34,.97)),var(--pbgB,rgba(13,15,21,.98)))!important;color:var(--ptx,#e8eaf2)!important;border:1px solid var(--pbd,rgba(255,255,255,.1))!important}";
|
|
1642
|
+
css += "\n" + P + " .dsb-btn{background:var(--chipBg,rgba(255,255,255,.08))!important;color:var(--ptx,#dfe3ee)!important;border:1px solid var(--pbd,rgba(255,255,255,.12))!important}";
|
|
1643
|
+
css += "\n" + P + " .dsb-subtitle{color:var(--itm,#9aa1b5)!important}";
|
|
1644
|
+
css += "\n" + P + " .dsb-q{background:var(--chipBg,rgba(255,255,255,.06))!important;border:1px solid var(--pbd,rgba(255,255,255,.14))!important;color:var(--ptx,#eef)!important}";
|
|
1645
|
+
css += "\n" + P + " .dsb-q:focus{border-color:var(--stA,#5b8cff)!important}";
|
|
1646
|
+
css += "\n" + P + " .dsb-chip{background:var(--chipBg,rgba(255,255,255,.06))!important;border:1px solid var(--pbd,rgba(255,255,255,.1))!important;color:var(--ptx,#cdd3e3)!important}";
|
|
1647
|
+
css += "\n" + P + " .dsb-schip{background:var(--chipBg,rgba(255,255,255,.06))!important;border:1px solid var(--pbd,rgba(255,255,255,.1))!important;color:var(--ptx,#cdd3e3)!important}";
|
|
1648
|
+
css += "\n" + P + " .dsb-chip-on{background:linear-gradient(135deg,var(--stA,#5b6cff),var(--stD,#2fa8ff))!important;color:#fff!important;border-color:transparent!important}";
|
|
1649
|
+
css += "\n" + P + " .dsb-tab-on{background:linear-gradient(135deg,var(--stA,#5b6cff),var(--stD,#2fa8ff))!important;color:#fff!important;border-color:transparent!important}";
|
|
1650
|
+
css += "\n" + P + " .dsb-sortbtn-on{background:linear-gradient(135deg,var(--stA,#5b6cff),var(--stD,#2fa8ff))!important;color:#fff!important;border-color:transparent!important}";
|
|
1651
|
+
css += "\n" + P + " .dsb-card{background:var(--chipBg,rgba(255,255,255,.05))!important;border:1px solid var(--pbd,rgba(255,255,255,.08))!important}";
|
|
1652
|
+
css += "\n" + P + " .dsb-card-name{color:var(--stA,#8fc7ff)!important}";
|
|
1653
|
+
css += "\n" + P + " .dsb-lc-skill{color:var(--stA,#8fc7ff)!important}";
|
|
1654
|
+
css += "\n" + P + " .dsb-card-zh{color:var(--ptx,#dfe3ee)!important}";
|
|
1655
|
+
css += "\n" + P + " .dsb-card-tag{color:var(--hintC,#8b93a8)!important}";
|
|
1656
|
+
css += "\n" + P + " .dsb-card-mtime{color:var(--hintC,#8b93a8)!important}";
|
|
1657
|
+
css += "\n" + P + " .dsb-lsum-card span{color:var(--hintC,#8b93a8)!important}";
|
|
1658
|
+
css += "\n" + P + " .dsb-lhead{color:var(--hintC,#8b93a8)!important}";
|
|
1659
|
+
css += "\n" + P + " .dsb-batch-status{color:var(--hintC,#8b93a8)!important}";
|
|
1660
|
+
css += "\n" + P + " .dsb-lsum-card b{color:var(--stA,#8fc7ff)!important}";
|
|
1661
|
+
css += "\n" + P + " .dsb-lsum-card{background:var(--chipBg,rgba(255,255,255,.05))!important;border:1px solid var(--pbd,rgba(255,255,255,.09))!important}";
|
|
1662
|
+
css += "\n" + P + " .dsb-lrow{background:var(--chipBg,rgba(255,255,255,.05))!important;border:1px solid var(--pbd,rgba(255,255,255,.09))!important}";
|
|
1663
|
+
css += "\n" + P + " .dsb-detail{background:linear-gradient(180deg,var(--pbgA,rgba(24,26,34,.99)),var(--pbgB,rgba(13,15,21,.99)))!important}";
|
|
1664
|
+
css += "\n" + P + " .dsb-set-row input{accent-color:var(--stA,#5b6cff)}";
|
|
1665
|
+
css += "\n" + P + " .dsb-switch.dsb-sw-on .dsb-sw-track{background:var(--stD,#27ae60)!important}";
|
|
1666
|
+
css += "\n" + P + " .dsb-sw-half .dsb-sw-track{background:linear-gradient(90deg,#555 0%,#555 50%,var(--stD,#27ae60) 50%,var(--stD,#27ae60) 100%)!important}";
|
|
1667
|
+
css += "\n" + P + " select{background:rgba(0,0,0,.35)!important;border:1px solid var(--pbd,rgba(255,255,255,.14))!important;color:var(--ptx,#eef)!important}";
|
|
1668
|
+
css += "\n" + P + " input[type=text]{background:var(--chipBg,rgba(255,255,255,.07))!important;border:1px solid var(--pbd,rgba(255,255,255,.14))!important;color:var(--ptx,#eef)!important}";
|
|
1669
|
+
// ---- unified typography (three-ball spec) ----
|
|
1670
|
+
css += "\n" + P + "{font-family:'Segoe UI','Microsoft YaHei','PingFang SC',system-ui,sans-serif!important;line-height:1.55!important;font-variant-numeric:tabular-nums}".replace("'Segoe UI','Microsoft YaHei','PingFang SC',system-ui,sans-serif", "'Segoe UI','Microsoft YaHei','PingFang SC',system-ui,sans-serif");
|
|
1671
|
+
css += "\n" + P + " .dsb-title{font-size:15px!important;font-family:'Segoe UI','Microsoft YaHei','PingFang SC',system-ui,sans-serif!important}".replace("'Segoe UI','Microsoft YaHei','PingFang SC',system-ui,sans-serif", "'Segoe UI','Microsoft YaHei','PingFang SC',system-ui,sans-serif");
|
|
1672
|
+
css += "\n" + P + " .dsb-subtitle{font-size:11.5px!important}";
|
|
1673
|
+
css += "\n" + P + ".dsb-set-hint{font-size:10.5px!important}";
|
|
1674
|
+
css += "\n" + P + ".dsb-batch-status{font-size:10.5px!important}";
|
|
1675
|
+
css += "\n" + P + ".dsb-card-tag{font-size:10.5px!important}";
|
|
1676
|
+
css += "\n" + P + ".dsb-card-mtime{font-size:10.5px!important}";
|
|
1677
|
+
css += "\n" + P + ".dsb-lsum-card span{font-size:10.5px!important}";
|
|
1678
|
+
css += "\n" + P + ".dsb-lhead{font-size:10.5px!important}";
|
|
1679
|
+
// ---- uncovered classes: make every remaining .dsb-* follow the skin vars ----
|
|
1680
|
+
// 修复:详情正文/tab/排序按钮/开关/空态/提示/批量菜单在浅色主题(04/08/28)下不可读。
|
|
1681
|
+
css += "\n" + P + " .dsb-detail-body{color:var(--ptx,#cfd6e8)!important;background:transparent!important}";
|
|
1682
|
+
css += "\n" + P + " .dsb-tab{background:var(--chipBg,rgba(255,255,255,.06))!important;border:1px solid var(--pbd,rgba(255,255,255,.1))!important;color:var(--itm,#cdd3e3)!important}";
|
|
1683
|
+
css += "\n" + P + " .dsb-tab:hover{background:var(--pbgB,rgba(255,255,255,.14))!important;color:var(--ptx,#e6e6e6)!important}";
|
|
1684
|
+
css += "\n" + P + " .dsb-sortbtn{background:var(--chipBg,rgba(255,255,255,.06))!important;border:1px solid var(--pbd,rgba(255,255,255,.12))!important;color:var(--itm,#cdd3e3)!important}";
|
|
1685
|
+
css += "\n" + P + " .dsb-sortbtn:hover{background:var(--pbgB,rgba(255,255,255,.14))!important;color:var(--ptx,#e6e6e6)!important}";
|
|
1686
|
+
css += "\n" + P + " .dsb-tgl{background:var(--chipBg,rgba(255,255,255,.06))!important;border:1px solid var(--pbd,rgba(255,255,255,.12))!important;color:var(--itm,#cdd3e3)!important}";
|
|
1687
|
+
css += "\n" + P + " .dsb-tgl:hover{background:var(--pbgB,rgba(255,255,255,.16))!important;color:var(--ptx,#e6e6e6)!important}";
|
|
1688
|
+
css += "\n" + P + " .dsb-tgl-on{color:var(--itD,#9fe0b5)!important;border-color:var(--itD,#9fe0b5)!important}";
|
|
1689
|
+
css += "\n" + P + " .dsb-batchbtn{background:var(--chipBg,rgba(255,255,255,.06))!important;border:1px solid var(--pbd,rgba(255,255,255,.12))!important;color:var(--itm,#cdd3e3)!important}";
|
|
1690
|
+
css += "\n" + P + " .dsb-batchbtn:hover{background:var(--pbgB,rgba(255,255,255,.14))!important;color:var(--ptx,#e6e6e6)!important}";
|
|
1691
|
+
css += "\n" + P + " .dsb-empty{color:var(--hintC,#9aa1b5)!important}";
|
|
1692
|
+
css += "\n" + P + " .dsb-set-hint{color:var(--hintC,#9aa1b5)!important}";
|
|
1693
|
+
css += "\n" + P + " .dsb-sw-label{color:var(--hintC,#9aa1b5)!important}";
|
|
1694
|
+
css += "\n" + P + " .dsb-switch.dsb-sw-on .dsb-sw-label{color:var(--itD,#9fe0b5)!important}";
|
|
1695
|
+
css += "\n" + P + " .dsb-sw-thumb{background:var(--ptx,#fff)!important;box-shadow:0 1px 3px rgba(0,0,0,.35)!important}";
|
|
1696
|
+
css += "\n" + P + " .dsb-sw-sep{background:var(--pbd,rgba(255,255,255,.14))!important}";
|
|
1697
|
+
css += "\n" + P + " .dsb-head .dsb-title{color:var(--ptx,#e8eaf2)!important}";
|
|
1698
|
+
css += "\n" + P + " .dsb-card-off{opacity:.5!important}";
|
|
1699
|
+
css += "\n" + P + " .dsb-badge-off{color:var(--stA,#ffd27a)!important;background:var(--chipBg,rgba(255,210,122,.12))!important;border:1px solid var(--pbd,rgba(255,210,122,.35))!important}";
|
|
1700
|
+
css += "\n" + P + " .dsb-bmenu{background:linear-gradient(180deg,var(--pbgA,#232633),var(--pbgB,#1b1d22))!important;border:1px solid var(--pbd,rgba(255,255,255,.16))!important;box-shadow:0 10px 32px rgba(0,0,0,.35)!important}";
|
|
1701
|
+
css += "\n" + P + " .dsb-bmenu-title{color:var(--hintC,#9aa1b5)!important}";
|
|
1702
|
+
css += "\n" + P + " .dsb-bmenu-sub{color:var(--hintC,#9aa1b5)!important}";
|
|
1703
|
+
css += "\n" + P + " .dsb-bmenu-item{background:var(--chipBg,rgba(255,255,255,.06))!important;border:1px solid var(--pbd,rgba(255,255,255,.12))!important;color:var(--ptx,#dfe3ee)!important}";
|
|
1704
|
+
css += "\n" + P + " .dsb-bmenu-item:hover{background:var(--pbgB,rgba(120,140,255,.18))!important;border-color:var(--stA,#5b8cff)!important}";
|
|
1705
|
+
css += "\n" + P + " .dsb-bmenu-cancel{color:var(--hintC,#9aa1b5)!important}";
|
|
1706
|
+
css += "\n" + P + " .dsb-bmenu-cancel:hover{color:var(--ptx,#dfe3ee)!important}";
|
|
1707
|
+
css += "\n" + P + " .dsb-toast{box-shadow:0 6px 22px var(--pbd,rgba(0,0,0,.45))!important}";
|
|
1708
|
+
return css;
|
|
1709
|
+
}
|
|
1710
|
+
// 原版皮肤(仅本球):flag 置位时清空皮肤覆盖样式,技能球回到原始星云紫。
|
|
1711
|
+
var SKIN_CLASSIC_KEY = "dsh-ball-skin-classic-skill";
|
|
1712
|
+
function isSkinClassic() { try { return localStorage.getItem(SKIN_CLASSIC_KEY) === "1"; } catch (e) { return false; } }
|
|
1713
|
+
function setSkinClassic(on) {
|
|
1714
|
+
try { if (on) localStorage.setItem(SKIN_CLASSIC_KEY, "1"); else localStorage.removeItem(SKIN_CLASSIC_KEY); } catch (e) {}
|
|
1715
|
+
applySkinNow();
|
|
1716
|
+
}
|
|
1717
|
+
function applySkinNow() {
|
|
1718
|
+
if (!SKIN) return;
|
|
1719
|
+
var el = document.getElementById(SKIN_STYLE_ID);
|
|
1720
|
+
if (!el) { el = document.createElement("style"); el.id = SKIN_STYLE_ID; }
|
|
1721
|
+
el.textContent = isSkinClassic() ? "" : skinBallCss() + "\n" + skinPanelCss();
|
|
1722
|
+
document.head.appendChild(el); // (re)append last so overrides win the cascade
|
|
1723
|
+
ensureSkinMenuCss();
|
|
1724
|
+
refreshSkinMenu();
|
|
1725
|
+
fillSkinSelect(document.getElementById("dsb-set-skin"));
|
|
1726
|
+
fillSkinSelect(document.getElementById("dsh-set-skin-global"));
|
|
1727
|
+
}
|
|
1728
|
+
function skinOptionsHtml() {
|
|
1729
|
+
if (!SKIN) return "";
|
|
1730
|
+
var html = "", groups = SKIN.groups();
|
|
1731
|
+
for (var g = 0; g < groups.length; g++) {
|
|
1732
|
+
html += '<optgroup label="' + groups[g] + '">';
|
|
1733
|
+
for (var i = 0; i < SKIN.ALL.length; i++) {
|
|
1734
|
+
var s = SKIN.ALL[i];
|
|
1735
|
+
if (s.group !== groups[g]) continue;
|
|
1736
|
+
html += '<option value="' + s.id + '">方案' + s.no + ' · ' + s.name + '</option>';
|
|
1737
|
+
}
|
|
1738
|
+
html += "</optgroup>";
|
|
1739
|
+
}
|
|
1740
|
+
return html;
|
|
1741
|
+
}
|
|
1742
|
+
function fillSkinSelect(sel) {
|
|
1743
|
+
if (!sel || !SKIN) return;
|
|
1744
|
+
if (!sel.options.length) {
|
|
1745
|
+
sel.innerHTML = '<option value="classic">原版 · 星云紫(仅本球)</option>' + skinOptionsHtml();
|
|
1746
|
+
}
|
|
1747
|
+
sel.value = isSkinClassic() ? "classic" : SKIN.getId();
|
|
1748
|
+
}
|
|
1749
|
+
// ---- todo-style grouped skin menu (panel 🎨) ----
|
|
1750
|
+
var SKINMENU_STYLE_ID = "dsb-skinmenu-style";
|
|
1751
|
+
var SKINMENU_MARGIN = "0 16px 10px";
|
|
1752
|
+
function skinMenuHtml() {
|
|
1753
|
+
if (!SKIN) return "";
|
|
1754
|
+
function dot(s) {
|
|
1755
|
+
var a = (s.vars && s.vars.stA) || "#888", b = (s.vars && s.vars.bgB) || "#222";
|
|
1756
|
+
return '<span class="dot" style="background:linear-gradient(135deg,' + a + ',' + b + ')"></span>';
|
|
1757
|
+
}
|
|
1758
|
+
var html = '<div class="cap">原版</div>';
|
|
1759
|
+
html += '<div class="row' + (isSkinClassic() ? " cur" : "") + '" data-skin-classic="1">' +
|
|
1760
|
+
'<span class="chk">' + (isSkinClassic() ? "✓" : "") + '</span>' +
|
|
1761
|
+
'<span class="dot" style="background:linear-gradient(135deg,#a5b8fc,#3c1e8f)"></span>' +
|
|
1762
|
+
"<span>原版 · 星云紫(仅本球)</span></div>";
|
|
1763
|
+
var groups = SKIN.groups();
|
|
1764
|
+
for (var g = 0; g < groups.length; g++) {
|
|
1765
|
+
html += '<div class="cap">' + groups[g] + "</div>";
|
|
1766
|
+
for (var i = 0; i < SKIN.ALL.length; i++) {
|
|
1767
|
+
var s = SKIN.ALL[i];
|
|
1768
|
+
if (s.group !== groups[g]) continue;
|
|
1769
|
+
var cur = !isSkinClassic() && s.id === SKIN.getId();
|
|
1770
|
+
html += '<div class="row' + (cur ? " cur" : "") + '" data-skin-id="' + s.id + '" title="' + s.en + ' (方案 ' + s.no + ')">' +
|
|
1771
|
+
'<span class="chk">' + (cur ? "✓" : "") + "</span>" + dot(s) +
|
|
1772
|
+
"<span>" + s.no + " · " + s.name + "</span></div>";
|
|
1773
|
+
}
|
|
1774
|
+
}
|
|
1775
|
+
return html;
|
|
1776
|
+
}
|
|
1777
|
+
function skinMenuEl() { return document.getElementById("dsb-skin"); }
|
|
1778
|
+
function refreshSkinMenu() {
|
|
1779
|
+
var m = skinMenuEl();
|
|
1780
|
+
if (m && m.classList.contains("open")) m.innerHTML = skinMenuHtml();
|
|
1781
|
+
}
|
|
1782
|
+
function toggleSkinMenu() {
|
|
1783
|
+
var m = skinMenuEl();
|
|
1784
|
+
if (!m) return;
|
|
1785
|
+
if (m.classList.contains("open")) { m.classList.remove("open"); m.innerHTML = ""; }
|
|
1786
|
+
else { m.innerHTML = skinMenuHtml(); m.classList.add("open"); }
|
|
1787
|
+
}
|
|
1788
|
+
function ensureSkinMenuCss() {
|
|
1789
|
+
var el = document.getElementById(SKINMENU_STYLE_ID);
|
|
1790
|
+
if (!el) {
|
|
1791
|
+
el = document.createElement("style");
|
|
1792
|
+
el.id = SKINMENU_STYLE_ID;
|
|
1793
|
+
el.textContent = SKINMENU_CSS;
|
|
1794
|
+
document.head.appendChild(el);
|
|
1795
|
+
}
|
|
1796
|
+
}
|
|
1797
|
+
// delegated: 🎨 button + menu rows (capture phase, immune to panel rebuilds)
|
|
1798
|
+
document.addEventListener("click", function (ev) {
|
|
1799
|
+
var t = ev.target;
|
|
1800
|
+
if (!t || !t.closest) return;
|
|
1801
|
+
if (t.closest("#dsb-skin-btn")) { ev.preventDefault(); toggleSkinMenu(); return; }
|
|
1802
|
+
var row = t.closest("#dsb-skin .row");
|
|
1803
|
+
if (!row) return;
|
|
1804
|
+
ev.stopPropagation();
|
|
1805
|
+
if (row.getAttribute("data-skin-classic")) { setSkinClassic(true); return; }
|
|
1806
|
+
var id = row.getAttribute("data-skin-id");
|
|
1807
|
+
if (id) { setSkinClassic(false); SKIN.setSkin(id); }
|
|
1808
|
+
}, true);
|
|
1809
|
+
var SKINMENU_CSS = ".dsb-skinmenu,.fe-skinmenu{display:none;max-height:46vh;overflow-y:auto;border:1px solid rgba(255,255,255,.12);border-radius:12px;background:rgba(10,13,20,.98);padding:6px;z-index:5;box-shadow:0 14px 40px rgba(0,0,0,.5)}\n.dsb-skinmenu.open,.fe-skinmenu.open{display:block}\n.dsb-skinmenu .cap,.fe-skinmenu .cap{font-size:10.5px;font-weight:700;color:#8b93a8;padding:6px 8px 2px;letter-spacing:1px}\n.dsb-skinmenu .row,.fe-skinmenu .row{display:flex;align-items:center;gap:8px;padding:5px 8px;border-radius:8px;cursor:pointer;font-size:12px;color:#dfe4ec;font-family:'Segoe UI','Microsoft YaHei','PingFang SC',system-ui,sans-serif}\n.dsb-skinmenu .row:hover,.fe-skinmenu .row:hover{background:rgba(255,255,255,.08)}\n.dsb-skinmenu .row.cur,.fe-skinmenu .row.cur{color:var(--stA,#ffd27a);font-weight:600}\n.dsb-skinmenu .dot,.fe-skinmenu .dot{width:10px;height:10px;border-radius:50%;flex-shrink:0;border:1px solid rgba(255,255,255,.2)}\n.dsb-skinmenu .chk,.fe-skinmenu .chk{width:14px;text-align:center;flex-shrink:0}";
|
|
1810
|
+
function ensureSkinMenuMargin() { var m = skinMenuEl(); if (m) m.style.margin = SKINMENU_MARGIN; }
|
|
1811
|
+
|
|
1812
|
+
if (SKIN) {
|
|
1813
|
+
try {
|
|
1814
|
+
window.__dshBallSkinHooks = window.__dshBallSkinHooks || [];
|
|
1815
|
+
if (window.__dshBallSkinHooks.indexOf(applySkinNow) < 0) window.__dshBallSkinHooks.push(applySkinNow);
|
|
1816
|
+
} catch (e) {}
|
|
1817
|
+
try { window.addEventListener("dsh-ball-skin-change", function () { applySkinNow(); }); } catch (e) {}
|
|
1818
|
+
try { window.addEventListener("storage", function (ev) { if (ev && ev.key === SKIN.KEY) applySkinNow(); }); } catch (e) {}
|
|
1819
|
+
// delegated change handling for every skin <select> (panel + DSH settings)
|
|
1820
|
+
document.addEventListener("change", function (ev) {
|
|
1821
|
+
var t = ev.target;
|
|
1822
|
+
if (!t || !t.id) return;
|
|
1823
|
+
if (t.id === "dsb-set-skin") {
|
|
1824
|
+
if (t.value === "classic") { setSkinClassic(true); return; }
|
|
1825
|
+
setSkinClassic(false);
|
|
1826
|
+
SKIN.setSkin(t.value);
|
|
1827
|
+
return;
|
|
1828
|
+
}
|
|
1829
|
+
if (t.id === "dsh-set-skin-global") {
|
|
1830
|
+
// 全局三球统一换肤:清掉本球与字体球的「原版」标记
|
|
1831
|
+
try { localStorage.removeItem(SKIN_CLASSIC_KEY); } catch (e) {}
|
|
1832
|
+
try { localStorage.removeItem("dsh-ball-skin-classic-font"); } catch (e) {}
|
|
1833
|
+
SKIN.setSkin(t.value);
|
|
1834
|
+
}
|
|
1835
|
+
// dsh-fe-skin-sel 由字体插件自己的监听处理(含其原版标记)
|
|
1836
|
+
}, true);
|
|
1837
|
+
}
|
|
1838
|
+
// ---- DSH 设置界面:settings.section 区块(纯函数组件)----
|
|
1839
|
+
// DIAG 版:组件被调用时上报 React 状态到宿主 /diag,用于定位内容为空原因。
|
|
1840
|
+
function diagReport(info) {
|
|
1841
|
+
try {
|
|
1842
|
+
fetch(apiBase() + "/diag", {
|
|
1843
|
+
method: "POST",
|
|
1844
|
+
headers: { "content-type": "application/json" },
|
|
1845
|
+
body: JSON.stringify(info)
|
|
1846
|
+
}).catch(function () {});
|
|
1847
|
+
} catch (e) {}
|
|
1848
|
+
}
|
|
1849
|
+
|
|
1850
|
+
function SettingsSection(props) {
|
|
1851
|
+
// 组件渲染即上报:React 可用性 + props 键
|
|
1852
|
+
try {
|
|
1853
|
+
diagReport({
|
|
1854
|
+
view: "settings-section-render",
|
|
1855
|
+
reactType: typeof React,
|
|
1856
|
+
reactKeys: React ? Object.keys(React).slice(0, 12) : [],
|
|
1857
|
+
propsKeys: props ? Object.keys(props) : []
|
|
1858
|
+
});
|
|
1859
|
+
} catch (e) {}
|
|
1860
|
+
|
|
1861
|
+
// 若 React 不可用则返回 null(内容空,但至少诊断日志能告诉我们原因)
|
|
1862
|
+
if (!React) return null;
|
|
1863
|
+
|
|
1864
|
+
var rows = [];
|
|
1865
|
+
// 未安装的球:开关仍显示但置灰+标注,保证"单独装任何一个,分区界面一致"(生态规格)
|
|
1866
|
+
function mkToggle(id, label, onChange, installed) {
|
|
1867
|
+
var on = installed !== false;
|
|
1868
|
+
return React.createElement("label", { key: id, style: { display: "flex", alignItems: "center", gap: "8px", fontSize: "13px", cursor: on ? "pointer" : "not-allowed", opacity: on ? 1 : .5 } },
|
|
1869
|
+
React.createElement("input", { type: "checkbox", id: id, disabled: !on, onChange: onChange }),
|
|
1870
|
+
React.createElement("span", null, label + (on ? "" : "(未安装)")));
|
|
1871
|
+
}
|
|
1872
|
+
rows.push(React.createElement("div", { key: "head", style: { fontWeight: "600", marginBottom: "4px" } }, "悬浮球导航"));
|
|
1873
|
+
rows.push(mkToggle("dsb-set-ball", "技能浏览器悬浮球(🧩)", function (e) {
|
|
1874
|
+
writeStore(BALL_VIS_KEY, e.target.checked);
|
|
1875
|
+
applyBallVisibility();
|
|
1876
|
+
if (!e.target.checked && S.open) closePanel();
|
|
1877
|
+
}, true));
|
|
1878
|
+
rows.push(mkToggle("dsb-set-font", "字体插件悬浮球(🔤)", function (e) {
|
|
1879
|
+
writeStore(FONT_BALL_VIS_KEY, e.target.checked);
|
|
1880
|
+
applyFontBallVisibility();
|
|
1881
|
+
}, isFontEnhancerInstalled()));
|
|
1882
|
+
rows.push(mkToggle("dsb-set-todo", "Todo 悬浮球(📋)", function (e) {
|
|
1883
|
+
writeStore(TODO_BALL_VIS_KEY, e.target.checked);
|
|
1884
|
+
if (typeof applyTodoBallVisibility === "function") applyTodoBallVisibility();
|
|
1885
|
+
var el = document.getElementById("dsh-tfb-root");
|
|
1886
|
+
if (el) el.style.setProperty("display", e.target.checked ? "" : "none", "important");
|
|
1887
|
+
}, isTodoBallInstalled()));
|
|
1888
|
+
// 悬浮球皮肤(三球同步):<select> 原生控件,不依赖 React hooks
|
|
1889
|
+
(function () {
|
|
1890
|
+
var SKG = window.__DSH_BALL_SKINS || null;
|
|
1891
|
+
if (!SKG || !React) return;
|
|
1892
|
+
var optgroups = [];
|
|
1893
|
+
var groups = SKG.groups();
|
|
1894
|
+
for (var g = 0; g < groups.length; g++) {
|
|
1895
|
+
var opts = [];
|
|
1896
|
+
for (var i = 0; i < SKG.ALL.length; i++) {
|
|
1897
|
+
var sp = SKG.ALL[i];
|
|
1898
|
+
if (sp.group !== groups[g]) continue;
|
|
1899
|
+
opts.push(React.createElement("option", { key: sp.id, value: sp.id }, "方案" + sp.no + " · " + sp.name));
|
|
1900
|
+
}
|
|
1901
|
+
optgroups.push(React.createElement("optgroup", { key: groups[g], label: groups[g] }, opts));
|
|
1902
|
+
}
|
|
1903
|
+
rows.push(React.createElement("div", { key: "skin-row", style: { display: "flex", alignItems: "center", gap: "8px", fontSize: "13px" } },
|
|
1904
|
+
React.createElement("span", null, "悬浮球皮肤"),
|
|
1905
|
+
React.createElement("select", {
|
|
1906
|
+
id: "dsh-set-skin-global",
|
|
1907
|
+
defaultValue: SKG.getId(),
|
|
1908
|
+
onChange: function (e) { SKG.setSkin(e.target.value); },
|
|
1909
|
+
style: { flex: "1", minWidth: "200px", background: "rgba(0,0,0,.35)", border: "1px solid rgba(255,255,255,.14)", borderRadius: "6px", color: "inherit", fontSize: "12px", padding: "4px 6px", outline: "none" }
|
|
1910
|
+
}, optgroups),
|
|
1911
|
+
React.createElement("span", { style: { fontSize: "12px", color: "#8b93a8" } }, "三球同步 · 128 款")
|
|
1912
|
+
));
|
|
1913
|
+
})();
|
|
1914
|
+
rows.push(React.createElement("div", { key: "hint", style: { fontSize: "12px", color: "#8b93a8" } },
|
|
1915
|
+
"悬浮球可拖动;清单面板始终居中;本分区就在 DSH 设置中,随时可改悬浮球显隐"));
|
|
1916
|
+
// ── 安装与更新须知(v1.5.7:24h 供应链政策 + 推荐清单说明)──
|
|
1917
|
+
rows.push(React.createElement("div", { key: "notice-block", style: { marginTop: "12px", padding: "10px 12px", background: "rgba(255,255,255,.03)", border: "1px solid rgba(255,255,255,.06)", borderRadius: "10px", fontSize: "12px", color: "#9aa1b5", lineHeight: "1.7" } },
|
|
1918
|
+
React.createElement("div", { style: { fontWeight: "600", color: "#cfd4dc", marginBottom: "4px" } }, "📌 安装与更新须知"),
|
|
1919
|
+
React.createElement("div", null, "1. 本分区由「技能浏览器」提供;技能球 / 字体球 / Todo 球三个悬浮球的显隐都在这里控制(新装默认全部显示)。"),
|
|
1920
|
+
React.createElement("div", null, "2. 推荐插件列表实时显示「已安装 / 未安装」状态:绿色「已安装」= 可直接使用;红色「未安装」= 点击 ⭐ Star 前往仓库,或到插件市场搜索安装。"),
|
|
1921
|
+
React.createElement("div", { style: { color: "#e0b0b0" } }, "3. 【重要】安装或更新插件时,若报错含 minimumReleaseAge 或 ERR_PNPM_MINIMUM_RELEASE_AGE_VIOLATION:这不是插件坏了,是 DSH 对刚发布 npm 包的 24 小时安全观察期(防止刚发布的投毒包)。"),
|
|
1922
|
+
React.createElement("div", { style: { color: "#e0b0b0" } }, "4. 遇到 24h 报错的处理:等一天再安装/更新即可自动通过,插件本体没有任何问题。插件作者连发多版时窗口期会顺延一天。"),
|
|
1923
|
+
React.createElement("div", null, "5. 悬浮球可拖动换位置;拖到屏幕外找不到时,点 🎯 按钮所有悬浮球一起回到右下角。三球已统一 128 款皮肤:在 DSH 设置页本分区的「悬浮球皮肤」下拉切换(三球同步),或在各球面板里切。")
|
|
1924
|
+
));
|
|
1925
|
+
// ── 一键恢复默认位置(v1.5.3 用户要求):悬浮球被拖出屏幕外卡住时,
|
|
1926
|
+
// 点此按钮立即回到默认右下角 (right:26px bottom:118px) 46px 常规大小,
|
|
1927
|
+
// 并顺带恢复显示、解除收起小圆点状态。无需重启。──
|
|
1928
|
+
rows.push(React.createElement("button", { key: "reset-pos",
|
|
1929
|
+
onClick: function () { try { resetBallToDefault(); } catch (e) {} },
|
|
1930
|
+
style: { alignSelf: "flex-start", fontSize: "13px", cursor: "pointer",
|
|
1931
|
+
background: "rgba(255,210,122,.12)", border: "1px solid rgba(255,210,122,.35)",
|
|
1932
|
+
borderRadius: "6px", padding: "6px 12px", color: "#ffd27a" }
|
|
1933
|
+
}, "🎯 所有悬浮球回到右下角"));
|
|
1934
|
+
// ── 推荐插件(v1.5.7 统一三条清单:字体/技能/照片,探测式安装徽标)──
|
|
1935
|
+
rows.push(React.createElement("div", { key: "rec-head", style: { fontWeight: "600", marginTop: "12px", marginBottom: "4px", borderTop: "1px solid rgba(255,255,255,.08)", paddingTop: "10px" } }, "推荐插件"));
|
|
1936
|
+
function recRow(key, recId, icon, text, repo) {
|
|
1937
|
+
return React.createElement("div", { key: key, "data-rec-id": recId, style: { display: "flex", alignItems: "center", justifyContent: "space-between", fontSize: "13px", padding: "3px 0" } },
|
|
1938
|
+
React.createElement("span", null, icon + " " + text),
|
|
1939
|
+
React.createElement("a", { href: "https://github.com/" + repo, target: "_blank", rel: "noopener", style: { textDecoration: "none", fontSize: "12px", background: "rgba(255,255,255,.06)", border: "1px solid rgba(255,255,255,.12)", borderRadius: "6px", padding: "2px 8px", color: "#ffd27a", cursor: "pointer", whiteSpace: "nowrap" } }, "⭐ Star"));
|
|
1940
|
+
}
|
|
1941
|
+
// ── 推荐插件(v1.5.7 统一清单:字体/技能/照片/Todo,探测式安装徽标)──
|
|
1942
|
+
// Todo 悬浮球皮肤切换(三皮肤):事件委托到本分区容器——React 合成
|
|
1943
|
+
// 事件与 ref 均不可靠(slot 重渲染会重建 DOM),委托到容器上永不失效。
|
|
1944
|
+
// 点击写 localStorage + 直调 todo 插件的 __dshtfbApplyTheme 钩子。
|
|
1945
|
+
rows.push(recRow("rec-font", "font", "🔤", "字体插件 — 区域自定义字体/颜色/字号", "loyalchiiina/dsh-font-enhancer"));
|
|
1946
|
+
rows.push(recRow("rec-skillbrowser", "skillbrowser", "🧩", "技能浏览器 — 悬浮球面板浏览共享技能库 + 失效台账", "loyalchiiina/dsh-skill-browser"));
|
|
1947
|
+
rows.push(recRow("rec-lightbox", "lightbox", "🖼️", "照片显示器 — 聊天图片灯箱(放大/下载/浏览)", "loyalchiiina/dsh-chat-image-lightbox"));
|
|
1948
|
+
rows.push(recRow("rec-todoball", "todoball", "📋", "Todo 悬浮球 — todo_write 进度常驻监控 + 多会话固定 + 三皮肤(面板内 🎨 切换)", "loyalchiiina/dsh-todo-float-ball"));return React.createElement("div", { "data-dsb-slot": "1", style: { display: "flex", flexDirection: "column", gap: "8px", padding: "8px 0" } }, rows);
|
|
1949
|
+
}
|
|
1950
|
+
|
|
1951
|
+
function registerSettings(ctx) {
|
|
1952
|
+
if (!ctx || !ctx.slots || !React) return false;
|
|
1953
|
+
// 直接调用(官方 dsh-im/archive-manager 均如此,不用 ctx.effect 包裹)
|
|
1954
|
+
try {
|
|
1955
|
+
ctx.slots.inject("settings.section", function () {
|
|
1956
|
+
return ctx.slots.register({
|
|
1957
|
+
name: "settings.section",
|
|
1958
|
+
id: "dsh-skill-browser",
|
|
1959
|
+
order: 22,
|
|
1960
|
+
label: function () { return "悬浮球导航"; },
|
|
1961
|
+
inject: function () { return {}; }
|
|
1962
|
+
}, SettingsSection);
|
|
1963
|
+
});
|
|
1964
|
+
return true;
|
|
1965
|
+
} catch (e) {
|
|
1966
|
+
try { console.warn("[dsh-skill-browser] settings registration failed", e); } catch (e2) {}
|
|
1967
|
+
return false;
|
|
1968
|
+
}
|
|
1969
|
+
}
|
|
1970
|
+
|
|
1971
|
+
// React for the settings.section slot (dsh-im 同款,__ModuleLoader__ 提供 react)
|
|
1972
|
+
var React = null;
|
|
1973
|
+
try {
|
|
1974
|
+
var _react = require("react");
|
|
1975
|
+
React = (_react && _react.default) || _react;
|
|
1976
|
+
} catch (e) { React = null; }
|
|
1977
|
+
// 兜底:若 require 拿不到,从全局 window 上找(部分环境挂 window.React)
|
|
1978
|
+
if (!React) { try { React = window.React || null; } catch (e) {} }
|
|
1979
|
+
|
|
1980
|
+
// ---- 旧状态迁移:v1.2.x 之前用户测试勾选可能在 localStorage 留下
|
|
1981
|
+
// "隐藏球"标记,导致球不显示且无法通过界面恢复。升级时强制重置一次。----
|
|
1982
|
+
function migrateOldState() {
|
|
1983
|
+
try {
|
|
1984
|
+
var ver = localStorage.getItem("dsh-skill-browser-cfg-ver");
|
|
1985
|
+
if (ver !== "4") {
|
|
1986
|
+
localStorage.setItem(BALL_VIS_KEY, "1"); // 球恢复显示
|
|
1987
|
+
localStorage.setItem(FONT_BALL_VIS_KEY, "1"); // 字体球恢复显示
|
|
1988
|
+
localStorage.removeItem(GHOST_KEY);
|
|
1989
|
+
// v3 复位(2026-09-05 用户要求"恢复原状"):同时清除拖拽位置记忆与
|
|
1990
|
+
// 收起小圆点状态,让悬浮球回到默认右下角 (right:26px bottom:118px) 常规大小。
|
|
1991
|
+
localStorage.removeItem(BALL_POS_KEY);
|
|
1992
|
+
localStorage.setItem("dsh-skill-browser-cfg-ver", "4");
|
|
1993
|
+
}
|
|
1994
|
+
} catch (e) {}
|
|
1995
|
+
}
|
|
1996
|
+
|
|
1997
|
+
// inject 必须导出为纯数组(同 archive-manager/dsh-im:cordis loader 读取
|
|
1998
|
+
// exports.inject 判定向 client ctx 注入哪些服务;函数形式曾被验证不生效)。
|
|
1999
|
+
// 目录选择走原生 <input type="file" webkitdirectory>,无需 remote seam。
|
|
2000
|
+
exports.inject = ["slots", "locale"];
|
|
2001
|
+
exports.apply = function (ctx) {
|
|
2002
|
+
// 设置分区每次 apply 都重新注册(DSH 热重载会释放 effect 导致分区消失,
|
|
2003
|
+
// 不设 mounted 守卫;重复注册由 slots 系统去重/替换)
|
|
2004
|
+
try { migrateOldState(); } catch (e) {}
|
|
2005
|
+
try { registerSettings(ctx); } catch (e) {}
|
|
2006
|
+
if (S.mounted) return;
|
|
2007
|
+
S.mounted = true;
|
|
2008
|
+
try { buildBall(); } catch (e) {
|
|
2009
|
+
try { console.warn("[dsh-skill-browser] mount failed", e); } catch (e2) {}
|
|
2010
|
+
return;
|
|
2011
|
+
}
|
|
2012
|
+
try { applySkinNow(); } catch (eSkin) {} // skin overrides after base ball CSS
|
|
2013
|
+
try {
|
|
2014
|
+
// 纯 CSS 显隐(html 属性驱动),无需轮询
|
|
2015
|
+
applyFontBallVisibility();
|
|
2016
|
+
applyBallVisibility();
|
|
2017
|
+
} catch (e) {}
|
|
2018
|
+
try { console.log("[dsh-skill-browser] client mounted (v1.7.2: 3-level aggregate switches + batch confirm menu)"); } catch (e3) {}
|
|
2019
|
+
setTimeout(applyRecBadges, 1200);
|
|
2020
|
+
setInterval(applyRecBadges, 5000);
|
|
2021
|
+
};
|
|
2022
|
+
|
|
2023
|
+
return module.exports;
|
|
2024
|
+
}
|
|
2025
|
+
});
|