@tsparticles/plugin-sounds 3.0.2 → 3.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. package/browser/Options/Classes/Sounds.js +4 -0
  2. package/browser/Options/Classes/SoundsEvent.js +4 -3
  3. package/browser/Options/Classes/SoundsIcon.js +1 -0
  4. package/browser/Options/Classes/SoundsIcons.js +4 -0
  5. package/browser/SoundsInstance.js +130 -69
  6. package/browser/index.js +13 -0
  7. package/browser/utils.js +11 -4
  8. package/cjs/Options/Classes/Sounds.js +4 -0
  9. package/cjs/Options/Classes/SoundsEvent.js +4 -3
  10. package/cjs/Options/Classes/SoundsIcon.js +1 -0
  11. package/cjs/Options/Classes/SoundsIcons.js +4 -0
  12. package/cjs/SoundsInstance.js +128 -67
  13. package/cjs/index.js +13 -0
  14. package/cjs/utils.js +14 -5
  15. package/esm/Options/Classes/Sounds.js +4 -0
  16. package/esm/Options/Classes/SoundsEvent.js +4 -3
  17. package/esm/Options/Classes/SoundsIcon.js +1 -0
  18. package/esm/Options/Classes/SoundsIcons.js +4 -0
  19. package/esm/SoundsInstance.js +130 -69
  20. package/esm/index.js +13 -0
  21. package/esm/utils.js +11 -4
  22. package/package.json +2 -2
  23. package/report.html +2 -2
  24. package/tsparticles.plugin.sounds.js +180 -77
  25. package/tsparticles.plugin.sounds.min.js +1 -1
  26. package/tsparticles.plugin.sounds.min.js.LICENSE.txt +1 -1
  27. package/types/Options/Classes/Sounds.d.ts +1 -0
  28. package/types/Options/Classes/SoundsEvent.d.ts +0 -5
  29. package/types/Options/Classes/SoundsIcon.d.ts +1 -0
  30. package/types/Options/Classes/SoundsIcons.d.ts +1 -0
  31. package/types/Options/Interfaces/ISounds.d.ts +1 -0
  32. package/types/Options/Interfaces/ISoundsIcon.d.ts +1 -0
  33. package/types/Options/Interfaces/ISoundsIcons.d.ts +1 -0
  34. package/types/SoundsInstance.d.ts +6 -0
  35. package/types/index.d.ts +1 -1
  36. package/types/types.d.ts +5 -5
  37. package/types/utils.d.ts +2 -0
  38. package/umd/Options/Classes/Sounds.js +4 -0
  39. package/umd/Options/Classes/SoundsEvent.js +4 -3
  40. package/umd/Options/Classes/SoundsIcon.js +1 -0
  41. package/umd/Options/Classes/SoundsIcons.js +4 -0
  42. package/umd/SoundsInstance.js +128 -67
  43. package/umd/index.js +14 -1
  44. package/umd/utils.js +14 -5
@@ -4,7 +4,7 @@
4
4
  * Demo / Generator : https://particles.js.org/
5
5
  * GitHub : https://www.github.com/matteobruni/tsparticles
6
6
  * How to use? : Check the GitHub README
7
- * v3.0.2
7
+ * v3.1.0
8
8
  */
9
9
  (function webpackUniversalModuleDefinition(root, factory) {
10
10
  if(typeof exports === 'object' && typeof module === 'object')
@@ -211,10 +211,11 @@ class SoundsEvent {
211
211
  return tmp;
212
212
  });
213
213
  }
214
- if (data.filter !== undefined) {
214
+ if (data.filter) {
215
215
  if ((0,engine_root_window_.isString)(data.filter)) {
216
- if ((0,engine_root_window_.isFunction)(window[data.filter])) {
217
- this.filter = window[data.filter];
216
+ const filterFunc = window[data.filter];
217
+ if ((0,engine_root_window_.isFunction)(filterFunc)) {
218
+ this.filter = filterFunc;
218
219
  }
219
220
  } else {
220
221
  this.filter = data.filter;
@@ -227,6 +228,7 @@ class SoundsIcon {
227
228
  constructor() {
228
229
  this.width = 24;
229
230
  this.height = 24;
231
+ this.style = "";
230
232
  }
231
233
  load(data) {
232
234
  if (!data) {
@@ -254,6 +256,7 @@ class SoundsIcons {
254
256
  this.unmute = new SoundsIcon();
255
257
  this.volumeDown = new SoundsIcon();
256
258
  this.volumeUp = new SoundsIcon();
259
+ this.enable = false;
257
260
  this.mute.svg = `<?xml version="1.0"?>
258
261
  <svg baseProfile="tiny" height="24px" version="1.2" viewBox="0 0 24 24" width="24px"
259
262
  xml:space="preserve" xmlns="http://www.w3.org/2000/svg"
@@ -295,6 +298,9 @@ class SoundsIcons {
295
298
  if (!data) {
296
299
  return;
297
300
  }
301
+ if (data.enable !== undefined) {
302
+ this.enable = data.enable;
303
+ }
298
304
  this.mute.load(data.mute);
299
305
  this.unmute.load(data.unmute);
300
306
  this.volumeDown.load(data.volumeDown);
@@ -338,6 +344,7 @@ class SoundsVolume {
338
344
 
339
345
  class Sounds {
340
346
  constructor() {
347
+ this.autoPlay = true;
341
348
  this.enable = false;
342
349
  this.events = [];
343
350
  this.icons = new SoundsIcons();
@@ -347,6 +354,9 @@ class Sounds {
347
354
  if (!data) {
348
355
  return;
349
356
  }
357
+ if (data.autoPlay !== undefined) {
358
+ this.autoPlay = data.autoPlay;
359
+ }
350
360
  if (data.enable !== undefined) {
351
361
  this.enable = data.enable;
352
362
  }
@@ -380,20 +390,33 @@ notes.set("B", [30.87, 61.74, 123.47, 246.94, 493.88, 987.77, 1975.53, 3951.07,
380
390
  notes.set("pause", [0]);
381
391
  function getNoteFrequency(note) {
382
392
  const regex = /(([A-G]b?)(\d))|pause/i,
383
- result = regex.exec(note);
384
- if (!result || !result.length) {
393
+ result = regex.exec(note),
394
+ groupKey = 2,
395
+ defaultMatchKey = 0,
396
+ innerGroupKey = 3;
397
+ if (!result?.length) {
385
398
  return;
386
399
  }
387
- const noteKey = result[2] || result[0],
400
+ const noteKey = result[groupKey] || result[defaultMatchKey],
388
401
  noteItem = notes.get(noteKey);
389
402
  if (!noteItem) {
390
403
  return;
391
404
  }
392
- return noteItem[parseInt(result[3] || "0")];
405
+ return noteItem[parseInt(result[innerGroupKey] || "0")];
393
406
  }
407
+ let muted = true;
408
+ const isWindowMuted = () => {
409
+ return muted;
410
+ };
411
+ const unmuteWindow = () => {
412
+ muted = false;
413
+ };
394
414
  ;// CONCATENATED MODULE: ./dist/browser/SoundsInstance.js
395
415
 
396
416
 
417
+ const zIndexOffset = 1,
418
+ rightOffset = 1,
419
+ minVolume = 0;
397
420
  function initImage(data) {
398
421
  const img = document.createElement("img"),
399
422
  {
@@ -409,13 +432,17 @@ function initImage(data) {
409
432
  {
410
433
  width,
411
434
  path,
435
+ style,
412
436
  svg
413
- } = iconOptions;
414
- setIconStyle(img, pos.top + margin, pos.right - (margin * (rightOffsets.length + 1) + width + rightOffsets.reduce((a, b) => a + b, 0)), display, options.fullScreen.zIndex + 1, width, margin);
437
+ } = iconOptions,
438
+ defaultAccumulator = 0;
439
+ setIconStyle(img, pos.top + margin, pos.right - (margin * (rightOffsets.length + rightOffset) + width + rightOffsets.reduce((a, b) => a + b, defaultAccumulator)), display, options.fullScreen.zIndex + zIndexOffset, width, margin, style);
415
440
  img.src = path ?? (svg ? `data:image/svg+xml;base64,${btoa(svg)}` : "");
416
- const parent = container.canvas.element?.parentNode || document.body;
441
+ const parent = container.canvas.element?.parentNode ?? document.body;
417
442
  parent.append(img);
418
- img.addEventListener("click", clickCb);
443
+ img.addEventListener("click", () => {
444
+ void clickCb();
445
+ });
419
446
  return img;
420
447
  }
421
448
  function removeImage(image) {
@@ -424,14 +451,15 @@ function removeImage(image) {
424
451
  }
425
452
  image.remove();
426
453
  }
427
- function setIconStyle(icon, top, left, display, zIndex, width, margin) {
454
+ function setIconStyle(icon, top, left, display, zIndex, width, margin, style) {
428
455
  icon.style.userSelect = "none";
429
456
  icon.style.webkitUserSelect = "none";
430
457
  icon.style.position = "absolute";
431
458
  icon.style.top = `${top + margin}px`;
432
459
  icon.style.left = `${left - margin - width}px`;
433
460
  icon.style.display = display;
434
- icon.style.zIndex = `${zIndex + 1}`;
461
+ icon.style.zIndex = `${zIndex + zIndexOffset}`;
462
+ icon.style.cssText += style;
435
463
  }
436
464
  class SoundsInstance {
437
465
  constructor(container, engine) {
@@ -453,12 +481,12 @@ class SoundsInstance {
453
481
  }
454
482
  for (const event of soundsOptions.events) {
455
483
  const cb = args => {
456
- (async () => {
484
+ void (async () => {
457
485
  const filterNotValid = event.filter && !event.filter(args);
458
486
  if (this._container !== args.container) {
459
487
  return;
460
488
  }
461
- if (!this._container || this._container.muted || this._container.destroyed) {
489
+ if (!this._container || !!this._container.muted || this._container.destroyed) {
462
490
  (0,engine_root_window_.executeOnSingleOrMultiple)(event.event, item => {
463
491
  this._engine.removeEventListener(item, cb);
464
492
  });
@@ -467,18 +495,19 @@ class SoundsInstance {
467
495
  if (filterNotValid) {
468
496
  return;
469
497
  }
498
+ const defaultNoteIndex = 0;
470
499
  if (event.audio) {
471
500
  this._playBuffer((0,engine_root_window_.itemFromSingleOrMultiple)(event.audio));
472
501
  } else if (event.melodies) {
473
502
  const melody = (0,engine_root_window_.itemFromArray)(event.melodies);
474
503
  if (melody.melodies.length) {
475
- await Promise.allSettled(melody.melodies.map(m => this._playNote(m.notes, 0, melody.loop)));
504
+ await Promise.allSettled(melody.melodies.map(m => this._playNote(m.notes, defaultNoteIndex, melody.loop)));
476
505
  } else {
477
- await this._playNote(melody.notes, 0, melody.loop);
506
+ await this._playNote(melody.notes, defaultNoteIndex, melody.loop);
478
507
  }
479
508
  } else if (event.notes) {
480
509
  const note = (0,engine_root_window_.itemFromArray)(event.notes);
481
- await this._playNote([note], 0, false);
510
+ await this._playNote([note], defaultNoteIndex, false);
482
511
  }
483
512
  })();
484
513
  };
@@ -487,18 +516,16 @@ class SoundsInstance {
487
516
  });
488
517
  }
489
518
  };
490
- this._mute = () => {
491
- const container = this._container;
492
- if (!container.audioContext) {
493
- return;
494
- }
519
+ this._mute = async () => {
520
+ const container = this._container,
521
+ audioContext = this._getAudioContext();
495
522
  for (const source of this._audioSources) {
496
523
  this._removeAudioSource(source);
497
524
  }
498
525
  if (this._gain) {
499
526
  this._gain.disconnect();
500
527
  }
501
- container.audioContext.close();
528
+ await audioContext.close();
502
529
  container.audioContext = undefined;
503
530
  this._engine.dispatchEvent("soundsMuted", {
504
531
  container: this._container
@@ -520,10 +547,11 @@ class SoundsInstance {
520
547
  source.start();
521
548
  };
522
549
  this._playFrequency = async (frequency, duration) => {
523
- if (!this._container.audioContext || !this._gain) {
550
+ if (!this._gain || this._container.muted) {
524
551
  return;
525
552
  }
526
- const oscillator = this._addOscillator(this._container.audioContext);
553
+ const audioContext = this._getAudioContext(),
554
+ oscillator = this._addOscillator(audioContext);
527
555
  oscillator.connect(this._gain);
528
556
  oscillator.type = "sine";
529
557
  oscillator.frequency.value = frequency;
@@ -536,14 +564,14 @@ class SoundsInstance {
536
564
  });
537
565
  };
538
566
  this._playMuteSound = () => {
539
- const container = this._container;
540
- if (!container.audioContext) {
567
+ if (this._container.muted) {
541
568
  return;
542
569
  }
543
- const gain = container.audioContext.createGain();
544
- gain.connect(container.audioContext.destination);
570
+ const audioContext = this._getAudioContext(),
571
+ gain = audioContext.createGain();
572
+ gain.connect(audioContext.destination);
545
573
  gain.gain.value = 0;
546
- const oscillator = container.audioContext.createOscillator();
574
+ const oscillator = audioContext.createOscillator();
547
575
  oscillator.connect(gain);
548
576
  oscillator.type = "sine";
549
577
  oscillator.frequency.value = 1;
@@ -567,7 +595,8 @@ class SoundsInstance {
567
595
  return this._playNoteValue(notes, noteIdx, idx);
568
596
  });
569
597
  await ((0,engine_root_window_.isArray)(promises) ? Promise.allSettled(promises) : promises);
570
- let nextNoteIdx = noteIdx + 1;
598
+ const indexOffset = 1;
599
+ let nextNoteIdx = noteIdx + indexOffset;
571
600
  if (loop && nextNoteIdx >= notes.length) {
572
601
  nextNoteIdx = nextNoteIdx % notes.length;
573
602
  }
@@ -595,7 +624,8 @@ class SoundsInstance {
595
624
  this._removeAudioSource = source => {
596
625
  source.stop();
597
626
  source.disconnect();
598
- this._audioSources.splice(this._audioSources.indexOf(source), 1);
627
+ const deleteCount = 1;
628
+ this._audioSources.splice(this._audioSources.indexOf(source), deleteCount);
599
629
  };
600
630
  this._unmute = () => {
601
631
  const container = this._container,
@@ -604,18 +634,13 @@ class SoundsInstance {
604
634
  if (!soundsOptions) {
605
635
  return;
606
636
  }
607
- if (!container.audioContext) {
608
- container.audioContext = new AudioContext();
609
- }
610
- const {
611
- audioContext
612
- } = container;
637
+ const audioContext = this._getAudioContext();
613
638
  if (!this._audioSources) {
614
639
  this._audioSources = [];
615
640
  }
616
641
  const gain = audioContext.createGain();
617
642
  gain.connect(audioContext.destination);
618
- gain.gain.value = soundsOptions.volume.value / 100;
643
+ gain.gain.value = soundsOptions.volume.value / engine_root_window_.percentDenominator;
619
644
  this._gain = gain;
620
645
  this._initEvents();
621
646
  this._engine.dispatchEvent("soundsUnmuted", {
@@ -624,7 +649,11 @@ class SoundsInstance {
624
649
  };
625
650
  this._updateMuteIcons = () => {
626
651
  const container = this._container,
627
- muteImg = this._muteImg,
652
+ soundsOptions = container.actualOptions.sounds;
653
+ if (!soundsOptions?.enable || !soundsOptions.icons.enable) {
654
+ return;
655
+ }
656
+ const muteImg = this._muteImg,
628
657
  unmuteImg = this._unmuteImg;
629
658
  if (muteImg) {
630
659
  muteImg.style.display = container.muted ? "block" : "none";
@@ -634,12 +663,13 @@ class SoundsInstance {
634
663
  }
635
664
  };
636
665
  this._updateMuteStatus = async () => {
637
- const container = this._container;
666
+ const container = this._container,
667
+ audioContext = this._getAudioContext();
638
668
  if (container.muted) {
639
- await container.audioContext?.suspend();
640
- this._mute();
669
+ await audioContext?.suspend();
670
+ await this._mute();
641
671
  } else {
642
- await container.audioContext?.resume();
672
+ await audioContext?.resume();
643
673
  this._unmute();
644
674
  this._playMuteSound();
645
675
  }
@@ -652,11 +682,11 @@ class SoundsInstance {
652
682
  }
653
683
  (0,engine_root_window_.clamp)(this._volume, soundsOptions.volume.min, soundsOptions.volume.max);
654
684
  let stateChanged = false;
655
- if (this._volume <= 0 && !container.muted) {
685
+ if (this._volume <= minVolume && !container.muted) {
656
686
  this._volume = 0;
657
687
  container.muted = true;
658
688
  stateChanged = true;
659
- } else if (this._volume > 0 && container.muted) {
689
+ } else if (this._volume > minVolume && container.muted) {
660
690
  container.muted = false;
661
691
  stateChanged = true;
662
692
  }
@@ -665,7 +695,7 @@ class SoundsInstance {
665
695
  await this._updateMuteStatus();
666
696
  }
667
697
  if (this._gain?.gain) {
668
- this._gain.gain.value = this._volume / 100;
698
+ this._gain.gain.value = this._volume / engine_root_window_.percentDenominator;
669
699
  }
670
700
  };
671
701
  this._container = container;
@@ -681,6 +711,20 @@ class SoundsInstance {
681
711
  if (!soundsOptions?.enable) {
682
712
  return;
683
713
  }
714
+ if (soundsOptions.autoPlay && isWindowMuted()) {
715
+ const firstClickHandler = () => {
716
+ removeEventListener(engine_root_window_.mouseDownEvent, firstClickHandler);
717
+ removeEventListener(engine_root_window_.touchStartEvent, firstClickHandler);
718
+ unmuteWindow();
719
+ void this.unmute();
720
+ };
721
+ const listenerOptions = {
722
+ capture: true,
723
+ once: true
724
+ };
725
+ addEventListener(engine_root_window_.mouseDownEvent, firstClickHandler, listenerOptions);
726
+ addEventListener(engine_root_window_.touchStartEvent, firstClickHandler, listenerOptions);
727
+ }
684
728
  this._volume = soundsOptions.volume.value;
685
729
  const events = soundsOptions.events;
686
730
  this._audioMap = new Map();
@@ -688,16 +732,26 @@ class SoundsInstance {
688
732
  if (!event.audio) {
689
733
  continue;
690
734
  }
691
- (0,engine_root_window_.executeOnSingleOrMultiple)(event.audio, async audio => {
735
+ const promises = (0,engine_root_window_.executeOnSingleOrMultiple)(event.audio, async audio => {
692
736
  const response = await fetch(audio.source);
693
737
  if (!response.ok) {
694
738
  return;
695
739
  }
696
- const arrayBuffer = await response.arrayBuffer();
697
- container.audioContext = new AudioContext();
698
- const audioBuffer = await container.audioContext.decodeAudioData(arrayBuffer);
740
+ const arrayBuffer = await response.arrayBuffer(),
741
+ audioContext = this._getAudioContext(),
742
+ audioBuffer = await audioContext.decodeAudioData(arrayBuffer);
699
743
  this._audioMap.set(audio.source, audioBuffer);
700
744
  });
745
+ if (promises instanceof Promise) {
746
+ await promises;
747
+ } else {
748
+ await Promise.allSettled(promises);
749
+ }
750
+ }
751
+ }
752
+ async mute() {
753
+ if (!this._container.muted) {
754
+ await this.toggleMute();
701
755
  }
702
756
  }
703
757
  async start() {
@@ -719,17 +773,17 @@ class SoundsInstance {
719
773
  volumeDown,
720
774
  volumeUp
721
775
  } = soundsOptions.icons,
722
- margin = 10;
723
- const toggleMute = async () => {
724
- container.muted = !container.muted;
725
- this._updateMuteIcons();
726
- await this._updateMuteStatus();
727
- };
776
+ margin = 10,
777
+ toggleMute = async () => {
778
+ await this.toggleMute();
779
+ },
780
+ enableIcons = soundsOptions.icons.enable,
781
+ display = enableIcons ? "block" : "none";
728
782
  this._muteImg = initImage({
729
783
  container,
730
784
  options,
731
785
  pos,
732
- display: "block",
786
+ display,
733
787
  iconOptions: mute,
734
788
  margin,
735
789
  rightOffsets: [volumeDown.width, volumeUp.width],
@@ -749,51 +803,100 @@ class SoundsInstance {
749
803
  container,
750
804
  options,
751
805
  pos,
752
- display: "block",
806
+ display,
753
807
  iconOptions: volumeDown,
754
808
  margin,
755
809
  rightOffsets: [volumeUp.width],
756
810
  clickCb: async () => {
757
- if (container.muted) {
758
- this._volume = 0;
759
- }
760
- this._volume -= soundsOptions.volume.step;
761
- await this._updateVolume();
811
+ await this.volumeDown();
762
812
  }
763
813
  });
764
814
  this._volumeUpImg = initImage({
765
815
  container,
766
816
  options,
767
817
  pos,
768
- display: "block",
818
+ display,
769
819
  iconOptions: volumeUp,
770
820
  margin,
771
821
  rightOffsets: [],
772
822
  clickCb: async () => {
773
- if (container.muted) {
774
- this._volume = 0;
775
- }
776
- this._volume += soundsOptions.volume.step;
777
- await this._updateVolume();
823
+ await this.volumeUp();
778
824
  }
779
825
  });
826
+ if (!isWindowMuted() && soundsOptions.autoPlay) {
827
+ await this.unmute();
828
+ }
780
829
  }
781
830
  stop() {
782
831
  this._container.muted = true;
783
- this._mute();
784
- removeImage(this._muteImg);
785
- removeImage(this._unmuteImg);
786
- removeImage(this._volumeDownImg);
787
- removeImage(this._volumeUpImg);
832
+ void (async () => {
833
+ await this._mute();
834
+ removeImage(this._muteImg);
835
+ removeImage(this._unmuteImg);
836
+ removeImage(this._volumeDownImg);
837
+ removeImage(this._volumeUpImg);
838
+ })();
839
+ }
840
+ async toggleMute() {
841
+ const container = this._container;
842
+ container.muted = !container.muted;
843
+ this._updateMuteIcons();
844
+ await this._updateMuteStatus();
845
+ }
846
+ async unmute() {
847
+ if (this._container.muted) {
848
+ await this.toggleMute();
849
+ }
850
+ }
851
+ async volumeDown() {
852
+ const container = this._container,
853
+ soundsOptions = container.actualOptions.sounds;
854
+ if (!soundsOptions?.enable) {
855
+ return;
856
+ }
857
+ if (container.muted) {
858
+ this._volume = 0;
859
+ }
860
+ this._volume -= soundsOptions.volume.step;
861
+ await this._updateVolume();
862
+ }
863
+ async volumeUp() {
864
+ const container = this._container,
865
+ soundsOptions = container.actualOptions.sounds;
866
+ if (!soundsOptions?.enable) {
867
+ return;
868
+ }
869
+ this._volume += soundsOptions.volume.step;
870
+ await this._updateVolume();
871
+ }
872
+ _getAudioContext() {
873
+ const container = this._container;
874
+ if (!container.audioContext) {
875
+ container.audioContext = new AudioContext();
876
+ }
877
+ return container.audioContext;
788
878
  }
789
879
  }
790
880
  ;// CONCATENATED MODULE: ./dist/browser/index.js
791
881
 
792
882
 
883
+
884
+
885
+ const generalFirstClickHandler = () => {
886
+ removeEventListener(engine_root_window_.mouseDownEvent, generalFirstClickHandler);
887
+ removeEventListener(engine_root_window_.touchStartEvent, generalFirstClickHandler);
888
+ unmuteWindow();
889
+ };
793
890
  class SoundsPlugin {
794
891
  constructor(engine) {
795
892
  this.id = "sounds";
796
893
  this._engine = engine;
894
+ const listenerOptions = {
895
+ capture: true,
896
+ once: true
897
+ };
898
+ addEventListener(engine_root_window_.mouseDownEvent, generalFirstClickHandler, listenerOptions);
899
+ addEventListener(engine_root_window_.touchStartEvent, generalFirstClickHandler, listenerOptions);
797
900
  }
798
901
  getPlugin(container) {
799
902
  return new SoundsInstance(container, this._engine);
@@ -1,2 +1,2 @@
1
1
  /*! For license information please see tsparticles.plugin.sounds.min.js.LICENSE.txt */
2
- !function(t,e){if("object"==typeof exports&&"object"==typeof module)module.exports=e(require("@tsparticles/engine"));else if("function"==typeof define&&define.amd)define(["@tsparticles/engine"],e);else{var i="object"==typeof exports?e(require("@tsparticles/engine")):e(t.window);for(var s in i)("object"==typeof exports?exports:t)[s]=i[s]}}(this,(t=>(()=>{"use strict";var e={533:e=>{e.exports=t}},i={};function s(t){var o=i[t];if(void 0!==o)return o.exports;var n=i[t]={exports:{}};return e[t](n,n.exports,s),n.exports}s.d=(t,e)=>{for(var i in e)s.o(e,i)&&!s.o(t,i)&&Object.defineProperty(t,i,{enumerable:!0,get:e[i]})},s.o=(t,e)=>Object.prototype.hasOwnProperty.call(t,e),s.r=t=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})};var o={};return(()=>{s.r(o),s.d(o,{loadSoundsPlugin:()=>g});var t=s(533);class e{constructor(){this.loop=!1,this.source=""}load(e){void 0!==e&&((0,t.isObject)(e)?(void 0!==e.loop&&(this.loop=e.loop),void 0!==e.source&&(this.source=e.source)):this.source=e)}}class i{constructor(){this.duration=500,this.value=[]}load(t){t&&(void 0!==t.duration&&(this.duration=t.duration),void 0!==t.value&&(this.value=t.value))}}class n{constructor(){this.loop=!1,this.melodies=[],this.notes=[]}load(t){void 0!==t&&(void 0!==t.loop&&(this.loop=t.loop),void 0!==t.melodies&&(this.melodies=t.melodies.map((t=>{const e=new n;return e.load(t),e}))),void 0!==t.notes&&(this.notes=t.notes.map((t=>{const e=new i;return e.load(t),e}))))}}class a{constructor(){this.event=[],this.notes=[]}load(s){s&&(void 0!==s.event&&(this.event=s.event),void 0!==s.audio&&((0,t.isArray)(s.audio)?this.audio=s.audio.map((t=>{const i=new e;return i.load(t),i})):(this.audio=new e,this.audio.load(s.audio))),void 0!==s.notes&&(this.notes=s.notes.map((t=>{const e=new i;return e.load(t),e}))),void 0!==s.melodies&&(this.melodies=s.melodies.map((t=>{const e=new n;return e.load(t),e}))),void 0!==s.filter&&((0,t.isString)(s.filter)?(0,t.isFunction)(window[s.filter])&&(this.filter=window[s.filter]):this.filter=s.filter))}}class c{constructor(){this.width=24,this.height=24}load(t){t&&(void 0!==t.path&&(this.path=t.path),void 0!==t.svg&&(this.svg=t.svg),void 0!==t.width&&(this.width=t.width),void 0!==t.height&&(this.height=t.height))}}class l{constructor(){this.mute=new c,this.unmute=new c,this.volumeDown=new c,this.volumeUp=new c,this.mute.svg='<?xml version="1.0"?>\n<svg baseProfile="tiny" height="24px" version="1.2" viewBox="0 0 24 24" width="24px"\n xml:space="preserve" xmlns="http://www.w3.org/2000/svg"\n xmlns:xlink="http://www.w3.org/1999/xlink">\n <g id="Layer_1">\n <path fill="#fff" d="M19.707,5.293c-0.391-0.391-1.023-0.391-1.414,0l-1.551,1.551c-0.345-0.688-0.987-1.02-1.604-1.02c-0.449,0-0.905,0.152-1.356,0.453l-2.672,1.781C10.357,8.561,8.904,9,8,9c-1.654,0-3,1.346-3,3v2c0,1.237,0.754,2.302,1.826,2.76l-1.533,1.533c-0.391,0.391-0.391,1.023,0,1.414C5.488,19.902,5.744,20,6,20s0.512-0.098,0.707-0.293l2.527-2.527c0.697,0.174,1.416,0.455,1.875,0.762l2.672,1.781c0.451,0.301,0.907,0.453,1.356,0.453C16.035,20.176,17,19.495,17,18V9.414l2.707-2.707C20.098,6.316,20.098,5.684,19.707,5.293z M14.891,7.941c0.038-0.025,0.073-0.046,0.104-0.062C14.998,7.914,15,7.954,15,8v1.293l-2,2V9.202L14.891,7.941z M7,12c0-0.552,0.448-1,1-1c1.211,0,2.907-0.495,4-1.146v2.439l-2.83,2.83C8.757,15.046,8.356,15,8,15c-0.552,0-1-0.448-1-1V12z M10.301,15.406L12,13.707v2.439C11.519,15.859,10.925,15.604,10.301,15.406z M14.994,18.12c-0.03-0.016-0.065-0.036-0.104-0.062L13,16.798v-4.091l2-2V18C15,18.046,14.998,18.086,14.994,18.12z"/>\n </g>\n</svg>',this.unmute.svg='<?xml version="1.0"?>\n<svg baseProfile="tiny" height="24px" version="1.2" viewBox="0 0 24 24" width="24px"\n xml:space="preserve" xmlns="http://www.w3.org/2000/svg"\n xmlns:xlink="http://www.w3.org/1999/xlink">\n <g id="Layer_1">\n <path fill="#fff" d="M17.138,5.824c-0.449,0-0.905,0.152-1.356,0.453l-2.672,1.781C12.357,8.561,10.904,9,10,9c-1.654,0-3,1.346-3,3v2c0,1.654,1.346,3,3,3c0.904,0,2.357,0.439,3.109,0.941l2.672,1.781c0.451,0.301,0.907,0.453,1.356,0.453C18.035,20.176,19,19.495,19,18V8C19,6.505,18.035,5.824,17.138,5.824z M14,16.146C12.907,15.495,11.211,15,10,15c-0.552,0-1-0.448-1-1v-2c0-0.552,0.448-1,1-1c1.211,0,2.907-0.495,4-1.146V16.146z M17,18c0,0.046-0.002,0.086-0.006,0.12c-0.03-0.016-0.065-0.036-0.104-0.062L15,16.798V9.202l1.891-1.261c0.038-0.025,0.073-0.046,0.104-0.062C16.998,7.914,17,7.954,17,8V18z"/>\n </g>\n</svg>',this.volumeDown.svg='<?xml version="1.0"?>\n<svg baseProfile="tiny" height="24px" version="1.2" viewBox="0 0 24 24" width="24px"\n xml:space="preserve" xmlns="http://www.w3.org/2000/svg"\n xmlns:xlink="http://www.w3.org/1999/xlink">\n <g id="Layer_1">\n <path fill="#fff" d="M15.138,5.824c-0.449,0-0.905,0.152-1.356,0.453l-2.672,1.781C10.357,8.561,8.904,9,8,9c-1.654,0-3,1.346-3,3v2c0,1.654,1.346,3,3,3c0.904,0,2.357,0.439,3.109,0.941l2.672,1.781c0.451,0.301,0.907,0.453,1.356,0.453C16.035,20.176,17,19.495,17,18V8C17,6.505,16.035,5.824,15.138,5.824z M8,15c-0.552,0-1-0.448-1-1v-2c0-0.552,0.448-1,1-1c1.211,0,2.907-0.495,4-1.146v6.293C10.907,15.495,9.211,15,8,15z M15,18c0,0.046-0.002,0.086-0.006,0.12c-0.03-0.016-0.065-0.036-0.104-0.062L13,16.798V9.202l1.891-1.261c0.038-0.025,0.073-0.046,0.104-0.062C14.998,7.914,15,7.954,15,8V18z"/>\n <path fill="#fff" d="M18.292,10.294c-0.39,0.391-0.39,1.023,0.002,1.414c0.345,0.345,0.535,0.803,0.535,1.291c0,0.489-0.19,0.948-0.536,1.294c-0.391,0.39-0.391,1.023,0,1.414C18.488,15.902,18.744,16,19,16s0.512-0.098,0.707-0.293c0.724-0.723,1.122-1.685,1.122-2.708s-0.398-1.984-1.123-2.707C19.317,9.903,18.683,9.901,18.292,10.294z"/>\n </g>\n</svg>',this.volumeUp.svg='<?xml version="1.0"?>\n<svg baseProfile="tiny" height="24px" version="1.2" viewBox="0 0 24 24" width="24px"\n xml:space="preserve" xmlns="http://www.w3.org/2000/svg"\n xmlns:xlink="http://www.w3.org/1999/xlink">\n <g id="Layer_1">\n <path fill="#fff" d="M16.706,10.292c-0.389-0.389-1.023-0.391-1.414,0.002c-0.39,0.391-0.39,1.023,0.002,1.414c0.345,0.345,0.535,0.803,0.535,1.291c0,0.489-0.19,0.948-0.536,1.294c-0.391,0.39-0.391,1.023,0,1.414C15.488,15.902,15.744,16,16,16s0.512-0.098,0.707-0.293c0.724-0.723,1.122-1.685,1.122-2.708S17.431,11.015,16.706,10.292z"/>\n <path fill="#fff" d="M18.706,8.292c-0.391-0.389-1.023-0.39-1.414,0.002c-0.39,0.391-0.39,1.024,0.002,1.414c0.879,0.877,1.363,2.044,1.364,3.287c0.001,1.246-0.484,2.417-1.365,3.298c-0.391,0.391-0.391,1.023,0,1.414C17.488,17.902,17.744,18,18,18s0.512-0.098,0.707-0.293c1.259-1.259,1.952-2.933,1.951-4.713C20.657,11.217,19.964,9.547,18.706,8.292z"/>\n <path fill="#fff" d="M20.706,6.292c-0.391-0.389-1.023-0.39-1.414,0.002c-0.39,0.391-0.39,1.024,0.002,1.414c1.412,1.409,2.191,3.285,2.192,5.284c0.002,2.002-0.777,3.885-2.193,5.301c-0.391,0.391-0.391,1.023,0,1.414C19.488,19.902,19.744,20,20,20s0.512-0.098,0.707-0.293c1.794-1.794,2.781-4.18,2.779-6.717C23.485,10.457,22.497,8.078,20.706,6.292z"/>\n <path fill="#fff" d="M12.138,5.824c-0.449,0-0.905,0.152-1.356,0.453L8.109,8.059C7.357,8.561,5.904,9,5,9c-1.654,0-3,1.346-3,3v2c0,1.654,1.346,3,3,3c0.904,0,2.357,0.439,3.109,0.941l2.672,1.781c0.451,0.301,0.907,0.453,1.356,0.453C13.035,20.176,14,19.495,14,18V8C14,6.505,13.035,5.824,12.138,5.824z M5,15c-0.552,0-1-0.448-1-1v-2c0-0.552,0.448-1,1-1c1.211,0,2.907-0.495,4-1.146v6.293C7.907,15.495,6.211,15,5,15z M12,18c0,0.046-0.002,0.086-0.006,0.12c-0.03-0.016-0.065-0.036-0.104-0.062L10,16.798V9.202l1.891-1.261c0.038-0.025,0.073-0.046,0.104-0.062C11.998,7.914,12,7.954,12,8V18z"/>\n </g>\n</svg>'}load(t){t&&(this.mute.load(t.mute),this.unmute.load(t.unmute),this.volumeDown.load(t.volumeDown),this.volumeUp.load(t.volumeUp))}}class u{constructor(){this.value=100,this.max=100,this.min=0,this.step=10}load(e){void 0!==e&&((0,t.isObject)(e)?(void 0!==e.max&&(this.max=e.max),void 0!==e.min&&(this.min=e.min),void 0!==e.step&&(this.step=e.step),void 0!==e.value&&(this.value=e.value)):this.value=e)}}class r{constructor(){this.enable=!1,this.events=[],this.icons=new l,this.volume=new u}load(t){t&&(void 0!==t.enable&&(this.enable=t.enable),void 0!==t.events&&(this.events=t.events.map((t=>{const e=new a;return e.load(t),e}))),this.icons.load(t.icons),void 0!==t.volume&&this.volume.load(t.volume))}}const d=new Map;function h(t){const e=/(([A-G]b?)(\d))|pause/i.exec(t);if(!e||!e.length)return;const i=e[2]||e[0],s=d.get(i);return s?s[parseInt(e[3]||"0")]:void 0}function p(t){const e=document.createElement("img"),{clickCb:i,container:s,display:o,iconOptions:n,margin:a,options:c,pos:l,rightOffsets:u}=t,{width:r,path:d,svg:h}=n;!function(t,e,i,s,o,n,a){t.style.userSelect="none",t.style.webkitUserSelect="none",t.style.position="absolute",t.style.top=`${e+a}px`,t.style.left=i-a-n+"px",t.style.display=s,t.style.zIndex=`${o+1}`}(e,l.top+a,l.right-(a*(u.length+1)+r+u.reduce(((t,e)=>t+e),0)),o,c.fullScreen.zIndex+1,r,a),e.src=d??(h?`data:image/svg+xml;base64,${btoa(h)}`:"");return(s.canvas.element?.parentNode||document.body).append(e),e.addEventListener("click",i),e}function m(t){t&&t.remove()}d.set("C",[16.35,32.7,65.41,130.81,261.63,523.25,1046.5,2093,4186.01]),d.set("Db",[17.32,34.65,69.3,138.59,277.18,554.37,1108.73,2217.46,4434.92]),d.set("D",[18.35,36.71,73.42,146.83,293.66,587.33,1174.66,2349.32,4698.63]),d.set("Eb",[19.45,38.89,77.78,155.56,311.13,622.25,1244.51,2489.02,4978.03]),d.set("E",[20.6,41.2,82.41,164.81,329.63,659.25,1318.51,2637.02,5274.04]),d.set("F",[21.83,43.65,87.31,174.61,349.23,698.46,1396.91,2793.83,5587.65]),d.set("Gb",[23.12,46.25,92.5,185,369.99,739.99,1479.98,2959.96,5919.91]),d.set("G",[24.5,49,98,196,392,783.99,1567.98,3135.96,6271.93]),d.set("Ab",[25.96,51.91,103.83,207.65,415.3,830.61,1661.22,3322.44,6644.88]),d.set("A",[27.5,55,110,220,440,880,1760,3520,7040]),d.set("Bb",[29.14,58.27,116.54,233.08,466.16,932.33,1864.66,3729.31,7458.62]),d.set("B",[30.87,61.74,123.47,246.94,493.88,987.77,1975.53,3951.07,7902.13]),d.set("pause",[0]);class v{constructor(e,i){this._addBuffer=t=>{const e=t.createBufferSource();return this._audioSources.push(e),e},this._addOscillator=t=>{const e=t.createOscillator();return this._audioSources.push(e),e},this._initEvents=()=>{const e=this._container,i=e.actualOptions.sounds;if(i?.enable&&e.canvas.element)for(const e of i.events){const i=s=>{(async()=>{const o=e.filter&&!e.filter(s);if(this._container===s.container)if(!this._container||this._container.muted||this._container.destroyed)(0,t.executeOnSingleOrMultiple)(e.event,(t=>{this._engine.removeEventListener(t,i)}));else if(!o)if(e.audio)this._playBuffer((0,t.itemFromSingleOrMultiple)(e.audio));else if(e.melodies){const i=(0,t.itemFromArray)(e.melodies);i.melodies.length?await Promise.allSettled(i.melodies.map((t=>this._playNote(t.notes,0,i.loop)))):await this._playNote(i.notes,0,i.loop)}else if(e.notes){const i=(0,t.itemFromArray)(e.notes);await this._playNote([i],0,!1)}})()};(0,t.executeOnSingleOrMultiple)(e.event,(t=>{this._engine.addEventListener(t,i)}))}},this._mute=()=>{const t=this._container;if(t.audioContext){for(const t of this._audioSources)this._removeAudioSource(t);this._gain&&this._gain.disconnect(),t.audioContext.close(),t.audioContext=void 0,this._engine.dispatchEvent("soundsMuted",{container:this._container})}},this._playBuffer=t=>{const e=this._audioMap.get(t.source);if(!e)return;const i=this._container.audioContext;if(!i)return;const s=this._addBuffer(i);s.loop=t.loop,s.buffer=e,s.connect(this._gain??i.destination),s.start()},this._playFrequency=async(t,e)=>{if(!this._container.audioContext||!this._gain)return;const i=this._addOscillator(this._container.audioContext);return i.connect(this._gain),i.type="sine",i.frequency.value=t,i.start(),new Promise((t=>{setTimeout((()=>{this._removeAudioSource(i),t()}),e)}))},this._playMuteSound=()=>{const t=this._container;if(!t.audioContext)return;const e=t.audioContext.createGain();e.connect(t.audioContext.destination),e.gain.value=0;const i=t.audioContext.createOscillator();i.connect(e),i.type="sine",i.frequency.value=1,i.start(),setTimeout((()=>{i.stop(),i.disconnect(),e.disconnect()}))},this._playNote=async(e,i,s)=>{if(this._container.muted)return;const o=e[i];if(!o)return;const n=o.value,a=(0,t.executeOnSingleOrMultiple)(n,(async(t,s)=>this._playNoteValue(e,i,s)));await((0,t.isArray)(a)?Promise.allSettled(a):a);let c=i+1;s&&c>=e.length&&(c%=e.length),this._container.muted||await this._playNote(e,c,s)},this._playNoteValue=async(e,i,s)=>{const o=e[i];if(!o)return;const n=(0,t.itemFromSingleOrMultiple)(o.value,s,!0);try{const e=h(n);if(!(0,t.isNumber)(e))return;await this._playFrequency(e,o.duration)}catch(e){(0,t.getLogger)().error(e)}},this._removeAudioSource=t=>{t.stop(),t.disconnect(),this._audioSources.splice(this._audioSources.indexOf(t),1)},this._unmute=()=>{const t=this._container,e=t.actualOptions.sounds;if(!e)return;t.audioContext||(t.audioContext=new AudioContext);const{audioContext:i}=t;this._audioSources||(this._audioSources=[]);const s=i.createGain();s.connect(i.destination),s.gain.value=e.volume.value/100,this._gain=s,this._initEvents(),this._engine.dispatchEvent("soundsUnmuted",{container:this._container})},this._updateMuteIcons=()=>{const t=this._container,e=this._muteImg,i=this._unmuteImg;e&&(e.style.display=t.muted?"block":"none"),i&&(i.style.display=t.muted?"none":"block")},this._updateMuteStatus=async()=>{const t=this._container;t.muted?(await(t.audioContext?.suspend()),this._mute()):(await(t.audioContext?.resume()),this._unmute(),this._playMuteSound())},this._updateVolume=async()=>{const e=this._container,i=e.actualOptions.sounds;if(!i?.enable)return;(0,t.clamp)(this._volume,i.volume.min,i.volume.max);let s=!1;this._volume<=0&&!e.muted?(this._volume=0,e.muted=!0,s=!0):this._volume>0&&e.muted&&(e.muted=!1,s=!0),s&&(this._updateMuteIcons(),await this._updateMuteStatus()),this._gain?.gain&&(this._gain.gain.value=this._volume/100)},this._container=e,this._engine=i,this._volume=0,this._audioSources=[],this._audioMap=new Map}async init(){const e=this._container,i=e.actualOptions.sounds;if(!i?.enable)return;this._volume=i.volume.value;const s=i.events;this._audioMap=new Map;for(const i of s)i.audio&&(0,t.executeOnSingleOrMultiple)(i.audio,(async t=>{const i=await fetch(t.source);if(!i.ok)return;const s=await i.arrayBuffer();e.audioContext=new AudioContext;const o=await e.audioContext.decodeAudioData(s);this._audioMap.set(t.source,o)}))}async start(){const t=this._container,e=t.actualOptions,i=e.sounds;if(!i?.enable||!t.canvas.element)return;t.muted=!0;const s=t.canvas.element,o={top:s.offsetTop,right:s.offsetLeft+s.offsetWidth},{mute:n,unmute:a,volumeDown:c,volumeUp:l}=i.icons,u=async()=>{t.muted=!t.muted,this._updateMuteIcons(),await this._updateMuteStatus()};this._muteImg=p({container:t,options:e,pos:o,display:"block",iconOptions:n,margin:10,rightOffsets:[c.width,l.width],clickCb:u}),this._unmuteImg=p({container:t,options:e,pos:o,display:"none",iconOptions:a,margin:10,rightOffsets:[c.width,l.width],clickCb:u}),this._volumeDownImg=p({container:t,options:e,pos:o,display:"block",iconOptions:c,margin:10,rightOffsets:[l.width],clickCb:async()=>{t.muted&&(this._volume=0),this._volume-=i.volume.step,await this._updateVolume()}}),this._volumeUpImg=p({container:t,options:e,pos:o,display:"block",iconOptions:l,margin:10,rightOffsets:[],clickCb:async()=>{t.muted&&(this._volume=0),this._volume+=i.volume.step,await this._updateVolume()}})}stop(){this._container.muted=!0,this._mute(),m(this._muteImg),m(this._unmuteImg),m(this._volumeDownImg),m(this._volumeUpImg)}}class f{constructor(t){this.id="sounds",this._engine=t}getPlugin(t){return new v(t,this._engine)}loadOptions(t,e){if(!this.needsPlugin(t)&&!this.needsPlugin(e))return;let i=t.sounds;void 0===i?.load&&(t.sounds=i=new r),i.load(e?.sounds)}needsPlugin(t){return t?.sounds?.enable??!1}}async function g(t,e=!0){await t.addPlugin(new f(t),e)}})(),o})()));
2
+ !function(t,e){if("object"==typeof exports&&"object"==typeof module)module.exports=e(require("@tsparticles/engine"));else if("function"==typeof define&&define.amd)define(["@tsparticles/engine"],e);else{var i="object"==typeof exports?e(require("@tsparticles/engine")):e(t.window);for(var n in i)("object"==typeof exports?exports:t)[n]=i[n]}}(this,(t=>(()=>{"use strict";var e={533:e=>{e.exports=t}},i={};function n(t){var s=i[t];if(void 0!==s)return s.exports;var o=i[t]={exports:{}};return e[t](o,o.exports,n),o.exports}n.d=(t,e)=>{for(var i in e)n.o(e,i)&&!n.o(t,i)&&Object.defineProperty(t,i,{enumerable:!0,get:e[i]})},n.o=(t,e)=>Object.prototype.hasOwnProperty.call(t,e),n.r=t=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})};var s={};return(()=>{n.r(s),n.d(s,{loadSoundsPlugin:()=>b});var t=n(533);class e{constructor(){this.loop=!1,this.source=""}load(e){void 0!==e&&((0,t.isObject)(e)?(void 0!==e.loop&&(this.loop=e.loop),void 0!==e.source&&(this.source=e.source)):this.source=e)}}class i{constructor(){this.duration=500,this.value=[]}load(t){t&&(void 0!==t.duration&&(this.duration=t.duration),void 0!==t.value&&(this.value=t.value))}}class o{constructor(){this.loop=!1,this.melodies=[],this.notes=[]}load(t){void 0!==t&&(void 0!==t.loop&&(this.loop=t.loop),void 0!==t.melodies&&(this.melodies=t.melodies.map((t=>{const e=new o;return e.load(t),e}))),void 0!==t.notes&&(this.notes=t.notes.map((t=>{const e=new i;return e.load(t),e}))))}}class a{constructor(){this.event=[],this.notes=[]}load(n){if(n&&(void 0!==n.event&&(this.event=n.event),void 0!==n.audio&&((0,t.isArray)(n.audio)?this.audio=n.audio.map((t=>{const i=new e;return i.load(t),i})):(this.audio=new e,this.audio.load(n.audio))),void 0!==n.notes&&(this.notes=n.notes.map((t=>{const e=new i;return e.load(t),e}))),void 0!==n.melodies&&(this.melodies=n.melodies.map((t=>{const e=new o;return e.load(t),e}))),n.filter))if((0,t.isString)(n.filter)){const e=window[n.filter];(0,t.isFunction)(e)&&(this.filter=e)}else this.filter=n.filter}}class c{constructor(){this.width=24,this.height=24,this.style=""}load(t){t&&(void 0!==t.path&&(this.path=t.path),void 0!==t.svg&&(this.svg=t.svg),void 0!==t.width&&(this.width=t.width),void 0!==t.height&&(this.height=t.height))}}class u{constructor(){this.mute=new c,this.unmute=new c,this.volumeDown=new c,this.volumeUp=new c,this.enable=!1,this.mute.svg='<?xml version="1.0"?>\n<svg baseProfile="tiny" height="24px" version="1.2" viewBox="0 0 24 24" width="24px"\n xml:space="preserve" xmlns="http://www.w3.org/2000/svg"\n xmlns:xlink="http://www.w3.org/1999/xlink">\n <g id="Layer_1">\n <path fill="#fff" d="M19.707,5.293c-0.391-0.391-1.023-0.391-1.414,0l-1.551,1.551c-0.345-0.688-0.987-1.02-1.604-1.02c-0.449,0-0.905,0.152-1.356,0.453l-2.672,1.781C10.357,8.561,8.904,9,8,9c-1.654,0-3,1.346-3,3v2c0,1.237,0.754,2.302,1.826,2.76l-1.533,1.533c-0.391,0.391-0.391,1.023,0,1.414C5.488,19.902,5.744,20,6,20s0.512-0.098,0.707-0.293l2.527-2.527c0.697,0.174,1.416,0.455,1.875,0.762l2.672,1.781c0.451,0.301,0.907,0.453,1.356,0.453C16.035,20.176,17,19.495,17,18V9.414l2.707-2.707C20.098,6.316,20.098,5.684,19.707,5.293z M14.891,7.941c0.038-0.025,0.073-0.046,0.104-0.062C14.998,7.914,15,7.954,15,8v1.293l-2,2V9.202L14.891,7.941z M7,12c0-0.552,0.448-1,1-1c1.211,0,2.907-0.495,4-1.146v2.439l-2.83,2.83C8.757,15.046,8.356,15,8,15c-0.552,0-1-0.448-1-1V12z M10.301,15.406L12,13.707v2.439C11.519,15.859,10.925,15.604,10.301,15.406z M14.994,18.12c-0.03-0.016-0.065-0.036-0.104-0.062L13,16.798v-4.091l2-2V18C15,18.046,14.998,18.086,14.994,18.12z"/>\n </g>\n</svg>',this.unmute.svg='<?xml version="1.0"?>\n<svg baseProfile="tiny" height="24px" version="1.2" viewBox="0 0 24 24" width="24px"\n xml:space="preserve" xmlns="http://www.w3.org/2000/svg"\n xmlns:xlink="http://www.w3.org/1999/xlink">\n <g id="Layer_1">\n <path fill="#fff" d="M17.138,5.824c-0.449,0-0.905,0.152-1.356,0.453l-2.672,1.781C12.357,8.561,10.904,9,10,9c-1.654,0-3,1.346-3,3v2c0,1.654,1.346,3,3,3c0.904,0,2.357,0.439,3.109,0.941l2.672,1.781c0.451,0.301,0.907,0.453,1.356,0.453C18.035,20.176,19,19.495,19,18V8C19,6.505,18.035,5.824,17.138,5.824z M14,16.146C12.907,15.495,11.211,15,10,15c-0.552,0-1-0.448-1-1v-2c0-0.552,0.448-1,1-1c1.211,0,2.907-0.495,4-1.146V16.146z M17,18c0,0.046-0.002,0.086-0.006,0.12c-0.03-0.016-0.065-0.036-0.104-0.062L15,16.798V9.202l1.891-1.261c0.038-0.025,0.073-0.046,0.104-0.062C16.998,7.914,17,7.954,17,8V18z"/>\n </g>\n</svg>',this.volumeDown.svg='<?xml version="1.0"?>\n<svg baseProfile="tiny" height="24px" version="1.2" viewBox="0 0 24 24" width="24px"\n xml:space="preserve" xmlns="http://www.w3.org/2000/svg"\n xmlns:xlink="http://www.w3.org/1999/xlink">\n <g id="Layer_1">\n <path fill="#fff" d="M15.138,5.824c-0.449,0-0.905,0.152-1.356,0.453l-2.672,1.781C10.357,8.561,8.904,9,8,9c-1.654,0-3,1.346-3,3v2c0,1.654,1.346,3,3,3c0.904,0,2.357,0.439,3.109,0.941l2.672,1.781c0.451,0.301,0.907,0.453,1.356,0.453C16.035,20.176,17,19.495,17,18V8C17,6.505,16.035,5.824,15.138,5.824z M8,15c-0.552,0-1-0.448-1-1v-2c0-0.552,0.448-1,1-1c1.211,0,2.907-0.495,4-1.146v6.293C10.907,15.495,9.211,15,8,15z M15,18c0,0.046-0.002,0.086-0.006,0.12c-0.03-0.016-0.065-0.036-0.104-0.062L13,16.798V9.202l1.891-1.261c0.038-0.025,0.073-0.046,0.104-0.062C14.998,7.914,15,7.954,15,8V18z"/>\n <path fill="#fff" d="M18.292,10.294c-0.39,0.391-0.39,1.023,0.002,1.414c0.345,0.345,0.535,0.803,0.535,1.291c0,0.489-0.19,0.948-0.536,1.294c-0.391,0.39-0.391,1.023,0,1.414C18.488,15.902,18.744,16,19,16s0.512-0.098,0.707-0.293c0.724-0.723,1.122-1.685,1.122-2.708s-0.398-1.984-1.123-2.707C19.317,9.903,18.683,9.901,18.292,10.294z"/>\n </g>\n</svg>',this.volumeUp.svg='<?xml version="1.0"?>\n<svg baseProfile="tiny" height="24px" version="1.2" viewBox="0 0 24 24" width="24px"\n xml:space="preserve" xmlns="http://www.w3.org/2000/svg"\n xmlns:xlink="http://www.w3.org/1999/xlink">\n <g id="Layer_1">\n <path fill="#fff" d="M16.706,10.292c-0.389-0.389-1.023-0.391-1.414,0.002c-0.39,0.391-0.39,1.023,0.002,1.414c0.345,0.345,0.535,0.803,0.535,1.291c0,0.489-0.19,0.948-0.536,1.294c-0.391,0.39-0.391,1.023,0,1.414C15.488,15.902,15.744,16,16,16s0.512-0.098,0.707-0.293c0.724-0.723,1.122-1.685,1.122-2.708S17.431,11.015,16.706,10.292z"/>\n <path fill="#fff" d="M18.706,8.292c-0.391-0.389-1.023-0.39-1.414,0.002c-0.39,0.391-0.39,1.024,0.002,1.414c0.879,0.877,1.363,2.044,1.364,3.287c0.001,1.246-0.484,2.417-1.365,3.298c-0.391,0.391-0.391,1.023,0,1.414C17.488,17.902,17.744,18,18,18s0.512-0.098,0.707-0.293c1.259-1.259,1.952-2.933,1.951-4.713C20.657,11.217,19.964,9.547,18.706,8.292z"/>\n <path fill="#fff" d="M20.706,6.292c-0.391-0.389-1.023-0.39-1.414,0.002c-0.39,0.391-0.39,1.024,0.002,1.414c1.412,1.409,2.191,3.285,2.192,5.284c0.002,2.002-0.777,3.885-2.193,5.301c-0.391,0.391-0.391,1.023,0,1.414C19.488,19.902,19.744,20,20,20s0.512-0.098,0.707-0.293c1.794-1.794,2.781-4.18,2.779-6.717C23.485,10.457,22.497,8.078,20.706,6.292z"/>\n <path fill="#fff" d="M12.138,5.824c-0.449,0-0.905,0.152-1.356,0.453L8.109,8.059C7.357,8.561,5.904,9,5,9c-1.654,0-3,1.346-3,3v2c0,1.654,1.346,3,3,3c0.904,0,2.357,0.439,3.109,0.941l2.672,1.781c0.451,0.301,0.907,0.453,1.356,0.453C13.035,20.176,14,19.495,14,18V8C14,6.505,13.035,5.824,12.138,5.824z M5,15c-0.552,0-1-0.448-1-1v-2c0-0.552,0.448-1,1-1c1.211,0,2.907-0.495,4-1.146v6.293C7.907,15.495,6.211,15,5,15z M12,18c0,0.046-0.002,0.086-0.006,0.12c-0.03-0.016-0.065-0.036-0.104-0.062L10,16.798V9.202l1.891-1.261c0.038-0.025,0.073-0.046,0.104-0.062C11.998,7.914,12,7.954,12,8V18z"/>\n </g>\n</svg>'}load(t){t&&(void 0!==t.enable&&(this.enable=t.enable),this.mute.load(t.mute),this.unmute.load(t.unmute),this.volumeDown.load(t.volumeDown),this.volumeUp.load(t.volumeUp))}}class l{constructor(){this.value=100,this.max=100,this.min=0,this.step=10}load(e){void 0!==e&&((0,t.isObject)(e)?(void 0!==e.max&&(this.max=e.max),void 0!==e.min&&(this.min=e.min),void 0!==e.step&&(this.step=e.step),void 0!==e.value&&(this.value=e.value)):this.value=e)}}class r{constructor(){this.autoPlay=!0,this.enable=!1,this.events=[],this.icons=new u,this.volume=new l}load(t){t&&(void 0!==t.autoPlay&&(this.autoPlay=t.autoPlay),void 0!==t.enable&&(this.enable=t.enable),void 0!==t.events&&(this.events=t.events.map((t=>{const e=new a;return e.load(t),e}))),this.icons.load(t.icons),void 0!==t.volume&&this.volume.load(t.volume))}}const d=new Map;function h(t){const e=/(([A-G]b?)(\d))|pause/i.exec(t);if(!e?.length)return;const i=e[2]||e[0],n=d.get(i);return n?n[parseInt(e[3]||"0")]:void 0}d.set("C",[16.35,32.7,65.41,130.81,261.63,523.25,1046.5,2093,4186.01]),d.set("Db",[17.32,34.65,69.3,138.59,277.18,554.37,1108.73,2217.46,4434.92]),d.set("D",[18.35,36.71,73.42,146.83,293.66,587.33,1174.66,2349.32,4698.63]),d.set("Eb",[19.45,38.89,77.78,155.56,311.13,622.25,1244.51,2489.02,4978.03]),d.set("E",[20.6,41.2,82.41,164.81,329.63,659.25,1318.51,2637.02,5274.04]),d.set("F",[21.83,43.65,87.31,174.61,349.23,698.46,1396.91,2793.83,5587.65]),d.set("Gb",[23.12,46.25,92.5,185,369.99,739.99,1479.98,2959.96,5919.91]),d.set("G",[24.5,49,98,196,392,783.99,1567.98,3135.96,6271.93]),d.set("Ab",[25.96,51.91,103.83,207.65,415.3,830.61,1661.22,3322.44,6644.88]),d.set("A",[27.5,55,110,220,440,880,1760,3520,7040]),d.set("Bb",[29.14,58.27,116.54,233.08,466.16,932.33,1864.66,3729.31,7458.62]),d.set("B",[30.87,61.74,123.47,246.94,493.88,987.77,1975.53,3951.07,7902.13]),d.set("pause",[0]);let v=!0;const m=()=>v,p=()=>{v=!1},f=1;function g(t){const e=document.createElement("img"),{clickCb:i,container:n,display:s,iconOptions:o,margin:a,options:c,pos:u,rightOffsets:l}=t,{width:r,path:d,style:h,svg:v}=o;!function(t,e,i,n,s,o,a,c){t.style.userSelect="none",t.style.webkitUserSelect="none",t.style.position="absolute",t.style.top=`${e+a}px`,t.style.left=i-a-o+"px",t.style.display=n,t.style.zIndex=`${s+f}`,t.style.cssText+=c}(e,u.top+a,u.right-(a*(l.length+1)+r+l.reduce(((t,e)=>t+e),0)),s,c.fullScreen.zIndex+f,r,a,h),e.src=d??(v?`data:image/svg+xml;base64,${btoa(v)}`:"");return(n.canvas.element?.parentNode??document.body).append(e),e.addEventListener("click",(()=>{i()})),e}function _(t){t&&t.remove()}class w{constructor(e,i){this._addBuffer=t=>{const e=t.createBufferSource();return this._audioSources.push(e),e},this._addOscillator=t=>{const e=t.createOscillator();return this._audioSources.push(e),e},this._initEvents=()=>{const e=this._container,i=e.actualOptions.sounds;if(i?.enable&&e.canvas.element)for(const e of i.events){const i=n=>{(async()=>{const s=e.filter&&!e.filter(n);if(this._container!==n.container)return;if(!this._container||this._container.muted||this._container.destroyed)return void(0,t.executeOnSingleOrMultiple)(e.event,(t=>{this._engine.removeEventListener(t,i)}));if(s)return;if(e.audio)this._playBuffer((0,t.itemFromSingleOrMultiple)(e.audio));else if(e.melodies){const i=(0,t.itemFromArray)(e.melodies);i.melodies.length?await Promise.allSettled(i.melodies.map((t=>this._playNote(t.notes,0,i.loop)))):await this._playNote(i.notes,0,i.loop)}else if(e.notes){const i=(0,t.itemFromArray)(e.notes);await this._playNote([i],0,!1)}})()};(0,t.executeOnSingleOrMultiple)(e.event,(t=>{this._engine.addEventListener(t,i)}))}},this._mute=async()=>{const t=this._container,e=this._getAudioContext();for(const t of this._audioSources)this._removeAudioSource(t);this._gain&&this._gain.disconnect(),await e.close(),t.audioContext=void 0,this._engine.dispatchEvent("soundsMuted",{container:this._container})},this._playBuffer=t=>{const e=this._audioMap.get(t.source);if(!e)return;const i=this._container.audioContext;if(!i)return;const n=this._addBuffer(i);n.loop=t.loop,n.buffer=e,n.connect(this._gain??i.destination),n.start()},this._playFrequency=async(t,e)=>{if(!this._gain||this._container.muted)return;const i=this._getAudioContext(),n=this._addOscillator(i);return n.connect(this._gain),n.type="sine",n.frequency.value=t,n.start(),new Promise((t=>{setTimeout((()=>{this._removeAudioSource(n),t()}),e)}))},this._playMuteSound=()=>{if(this._container.muted)return;const t=this._getAudioContext(),e=t.createGain();e.connect(t.destination),e.gain.value=0;const i=t.createOscillator();i.connect(e),i.type="sine",i.frequency.value=1,i.start(),setTimeout((()=>{i.stop(),i.disconnect(),e.disconnect()}))},this._playNote=async(e,i,n)=>{if(this._container.muted)return;const s=e[i];if(!s)return;const o=s.value,a=(0,t.executeOnSingleOrMultiple)(o,(async(t,n)=>this._playNoteValue(e,i,n)));await((0,t.isArray)(a)?Promise.allSettled(a):a);let c=i+1;n&&c>=e.length&&(c%=e.length),this._container.muted||await this._playNote(e,c,n)},this._playNoteValue=async(e,i,n)=>{const s=e[i];if(!s)return;const o=(0,t.itemFromSingleOrMultiple)(s.value,n,!0);try{const e=h(o);if(!(0,t.isNumber)(e))return;await this._playFrequency(e,s.duration)}catch(e){(0,t.getLogger)().error(e)}},this._removeAudioSource=t=>{t.stop(),t.disconnect();this._audioSources.splice(this._audioSources.indexOf(t),1)},this._unmute=()=>{const e=this._container.actualOptions.sounds;if(!e)return;const i=this._getAudioContext();this._audioSources||(this._audioSources=[]);const n=i.createGain();n.connect(i.destination),n.gain.value=e.volume.value/t.percentDenominator,this._gain=n,this._initEvents(),this._engine.dispatchEvent("soundsUnmuted",{container:this._container})},this._updateMuteIcons=()=>{const t=this._container,e=t.actualOptions.sounds;if(!e?.enable||!e.icons.enable)return;const i=this._muteImg,n=this._unmuteImg;i&&(i.style.display=t.muted?"block":"none"),n&&(n.style.display=t.muted?"none":"block")},this._updateMuteStatus=async()=>{const t=this._container,e=this._getAudioContext();t.muted?(await(e?.suspend()),await this._mute()):(await(e?.resume()),this._unmute(),this._playMuteSound())},this._updateVolume=async()=>{const e=this._container,i=e.actualOptions.sounds;if(!i?.enable)return;(0,t.clamp)(this._volume,i.volume.min,i.volume.max);let n=!1;this._volume<=0&&!e.muted?(this._volume=0,e.muted=!0,n=!0):this._volume>0&&e.muted&&(e.muted=!1,n=!0),n&&(this._updateMuteIcons(),await this._updateMuteStatus()),this._gain?.gain&&(this._gain.gain.value=this._volume/t.percentDenominator)},this._container=e,this._engine=i,this._volume=0,this._audioSources=[],this._audioMap=new Map}async init(){const e=this._container.actualOptions.sounds;if(!e?.enable)return;if(e.autoPlay&&m()){const e=()=>{removeEventListener(t.mouseDownEvent,e),removeEventListener(t.touchStartEvent,e),p(),this.unmute()},i={capture:!0,once:!0};addEventListener(t.mouseDownEvent,e,i),addEventListener(t.touchStartEvent,e,i)}this._volume=e.volume.value;const i=e.events;this._audioMap=new Map;for(const e of i){if(!e.audio)continue;const i=(0,t.executeOnSingleOrMultiple)(e.audio,(async t=>{const e=await fetch(t.source);if(!e.ok)return;const i=await e.arrayBuffer(),n=this._getAudioContext(),s=await n.decodeAudioData(i);this._audioMap.set(t.source,s)}));i instanceof Promise?await i:await Promise.allSettled(i)}}async mute(){this._container.muted||await this.toggleMute()}async start(){const t=this._container,e=t.actualOptions,i=e.sounds;if(!i?.enable||!t.canvas.element)return;t.muted=!0;const n=t.canvas.element,s={top:n.offsetTop,right:n.offsetLeft+n.offsetWidth},{mute:o,unmute:a,volumeDown:c,volumeUp:u}=i.icons,l=async()=>{await this.toggleMute()},r=i.icons.enable?"block":"none";this._muteImg=g({container:t,options:e,pos:s,display:r,iconOptions:o,margin:10,rightOffsets:[c.width,u.width],clickCb:l}),this._unmuteImg=g({container:t,options:e,pos:s,display:"none",iconOptions:a,margin:10,rightOffsets:[c.width,u.width],clickCb:l}),this._volumeDownImg=g({container:t,options:e,pos:s,display:r,iconOptions:c,margin:10,rightOffsets:[u.width],clickCb:async()=>{await this.volumeDown()}}),this._volumeUpImg=g({container:t,options:e,pos:s,display:r,iconOptions:u,margin:10,rightOffsets:[],clickCb:async()=>{await this.volumeUp()}}),!m()&&i.autoPlay&&await this.unmute()}stop(){this._container.muted=!0,(async()=>{await this._mute(),_(this._muteImg),_(this._unmuteImg),_(this._volumeDownImg),_(this._volumeUpImg)})()}async toggleMute(){const t=this._container;t.muted=!t.muted,this._updateMuteIcons(),await this._updateMuteStatus()}async unmute(){this._container.muted&&await this.toggleMute()}async volumeDown(){const t=this._container,e=t.actualOptions.sounds;e?.enable&&(t.muted&&(this._volume=0),this._volume-=e.volume.step,await this._updateVolume())}async volumeUp(){const t=this._container.actualOptions.sounds;t?.enable&&(this._volume+=t.volume.step,await this._updateVolume())}_getAudioContext(){const t=this._container;return t.audioContext||(t.audioContext=new AudioContext),t.audioContext}}const y=()=>{removeEventListener(t.mouseDownEvent,y),removeEventListener(t.touchStartEvent,y),p()};class x{constructor(e){this.id="sounds",this._engine=e;const i={capture:!0,once:!0};addEventListener(t.mouseDownEvent,y,i),addEventListener(t.touchStartEvent,y,i)}getPlugin(t){return new w(t,this._engine)}loadOptions(t,e){if(!this.needsPlugin(t)&&!this.needsPlugin(e))return;let i=t.sounds;void 0===i?.load&&(t.sounds=i=new r),i.load(e?.sounds)}needsPlugin(t){return t?.sounds?.enable??!1}}async function b(t,e=!0){await t.addPlugin(new x(t),e)}})(),s})()));
@@ -1 +1 @@
1
- /*! tsParticles Sounds Plugin v3.0.2 by Matteo Bruni */
1
+ /*! tsParticles Sounds Plugin v3.1.0 by Matteo Bruni */
@@ -4,6 +4,7 @@ import { SoundsEvent } from "./SoundsEvent.js";
4
4
  import { SoundsIcons } from "./SoundsIcons.js";
5
5
  import { SoundsVolume } from "./SoundsVolume.js";
6
6
  export declare class Sounds implements ISounds, IOptionLoader<ISounds> {
7
+ autoPlay: boolean;
7
8
  enable: boolean;
8
9
  events: SoundsEvent[];
9
10
  icons: SoundsIcons;
@@ -4,11 +4,6 @@ import type { ISoundsEvent } from "../Interfaces/ISoundsEvent.js";
4
4
  import { SoundsAudio } from "./SoundsAudio.js";
5
5
  import { SoundsMelody } from "./SoundsMelody.js";
6
6
  import { SoundsNote } from "./SoundsNote.js";
7
- declare global {
8
- interface Window {
9
- [key: string]: unknown;
10
- }
11
- }
12
7
  export declare class SoundsEvent implements ISoundsEvent, IOptionLoader<ISoundsEvent> {
13
8
  audio?: SingleOrMultiple<SoundsAudio>;
14
9
  event: SingleOrMultiple<string>;
@@ -3,6 +3,7 @@ import type { ISoundsIcon } from "../Interfaces/ISoundsIcon.js";
3
3
  export declare class SoundsIcon implements ISoundsIcon, IOptionLoader<ISoundsIcon> {
4
4
  height: number;
5
5
  path?: string;
6
+ style: string;
6
7
  svg?: string;
7
8
  width: number;
8
9
  constructor();
@@ -2,6 +2,7 @@ import type { IOptionLoader, RecursivePartial } from "@tsparticles/engine";
2
2
  import type { ISoundsIcons } from "../Interfaces/ISoundsIcons.js";
3
3
  import { SoundsIcon } from "./SoundsIcon.js";
4
4
  export declare class SoundsIcons implements ISoundsIcons, IOptionLoader<ISoundsIcons> {
5
+ enable: boolean;
5
6
  mute: SoundsIcon;
6
7
  unmute: SoundsIcon;
7
8
  volumeDown: SoundsIcon;
@@ -2,6 +2,7 @@ import type { ISoundsEvent } from "./ISoundsEvent.js";
2
2
  import type { ISoundsIcons } from "./ISoundsIcons.js";
3
3
  import type { ISoundsVolume } from "./ISoundsVolume.js";
4
4
  export interface ISounds {
5
+ autoPlay: boolean;
5
6
  enable: boolean;
6
7
  events: ISoundsEvent[];
7
8
  icons: ISoundsIcons;
@@ -1,6 +1,7 @@
1
1
  export interface ISoundsIcon {
2
2
  height: number;
3
3
  path?: string;
4
+ style: string;
4
5
  svg?: string;
5
6
  width: number;
6
7
  }