@tsparticles/slim 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.
@@ -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')
@@ -139,6 +139,7 @@ __webpack_require__.d(__webpack_exports__, {
139
139
  colorToHsl: () => (/* reexport */ colorToHsl),
140
140
  colorToRgb: () => (/* reexport */ colorToRgb),
141
141
  deepExtend: () => (/* reexport */ deepExtend),
142
+ degToRad: () => (/* reexport */ degToRad),
142
143
  divMode: () => (/* reexport */ divMode),
143
144
  divModeExecute: () => (/* reexport */ divModeExecute),
144
145
  drawEffect: () => (/* reexport */ drawEffect),
@@ -171,6 +172,7 @@ __webpack_require__.d(__webpack_exports__, {
171
172
  getSize: () => (/* reexport */ getSize),
172
173
  getStyleFromHsl: () => (/* reexport */ getStyleFromHsl),
173
174
  getStyleFromRgb: () => (/* reexport */ getStyleFromRgb),
175
+ halfRandom: () => (/* reexport */ halfRandom),
174
176
  hasMatchMedia: () => (/* reexport */ hasMatchMedia),
175
177
  hslToRgb: () => (/* reexport */ hslToRgb),
176
178
  hslaToRgba: () => (/* reexport */ hslaToRgba),
@@ -191,6 +193,7 @@ __webpack_require__.d(__webpack_exports__, {
191
193
  loadOptions: () => (/* reexport */ loadOptions),
192
194
  loadParticlesOptions: () => (/* reexport */ loadParticlesOptions),
193
195
  loadSlim: () => (/* reexport */ loadSlim),
196
+ millisecondsToSeconds: () => (/* reexport */ millisecondsToSeconds),
194
197
  mix: () => (/* reexport */ mix),
195
198
  mouseDownEvent: () => (/* reexport */ mouseDownEvent),
196
199
  mouseLeaveEvent: () => (/* reexport */ mouseLeaveEvent),
@@ -200,6 +203,7 @@ __webpack_require__.d(__webpack_exports__, {
200
203
  paintBase: () => (/* reexport */ paintBase),
201
204
  paintImage: () => (/* reexport */ paintImage),
202
205
  parseAlpha: () => (/* reexport */ parseAlpha),
206
+ percentDenominator: () => (/* reexport */ percentDenominator),
203
207
  randomInRange: () => (/* reexport */ randomInRange),
204
208
  rangeColorToHsl: () => (/* reexport */ rangeColorToHsl),
205
209
  rangeColorToRgb: () => (/* reexport */ rangeColorToRgb),
@@ -220,6 +224,9 @@ __webpack_require__.d(__webpack_exports__, {
220
224
  touchMoveEvent: () => (/* reexport */ touchMoveEvent),
221
225
  touchStartEvent: () => (/* reexport */ touchStartEvent),
222
226
  tsParticles: () => (/* reexport */ tsParticles),
227
+ updateAnimation: () => (/* reexport */ updateAnimation),
228
+ updateColor: () => (/* reexport */ updateColor),
229
+ updateColorValue: () => (/* reexport */ updateColorValue),
223
230
  visibilityChangeEvent: () => (/* reexport */ visibilityChangeEvent)
224
231
  });
225
232
 
@@ -237,9 +244,19 @@ const touchCancelEvent = "touchcancel";
237
244
  const resizeEvent = "resize";
238
245
  const visibilityChangeEvent = "visibilitychange";
239
246
  const errorPrefix = "tsParticles - Error";
247
+ const percentDenominator = 100;
248
+ const halfRandom = 0.5;
249
+ const millisecondsToSeconds = 1000;
240
250
  ;// CONCATENATED MODULE: ../../engine/dist/browser/Core/Utils/Vector3d.js
241
251
 
242
252
 
253
+ const origin = {
254
+ x: 0,
255
+ y: 0,
256
+ z: 0
257
+ },
258
+ squareExp = 2,
259
+ inverseFactorNumerator = 1.0;
243
260
  class Vector3d {
244
261
  constructor(xOrCoords, y, z) {
245
262
  this._updateFromAngle = (angle, length) => {
@@ -250,17 +267,17 @@ class Vector3d {
250
267
  this.x = xOrCoords.x;
251
268
  this.y = xOrCoords.y;
252
269
  const coords3d = xOrCoords;
253
- this.z = coords3d.z ? coords3d.z : 0;
270
+ this.z = coords3d.z ? coords3d.z : origin.z;
254
271
  } else if (xOrCoords !== undefined && y !== undefined) {
255
272
  this.x = xOrCoords;
256
273
  this.y = y;
257
- this.z = z ?? 0;
274
+ this.z = z ?? origin.z;
258
275
  } else {
259
276
  throw new Error(`${errorPrefix} Vector3d not initialized correctly`);
260
277
  }
261
278
  }
262
279
  static get origin() {
263
- return Vector3d.create(0, 0, 0);
280
+ return Vector3d.create(origin.x, origin.y, origin.z);
264
281
  }
265
282
  get angle() {
266
283
  return Math.atan2(this.y, this.x);
@@ -306,7 +323,7 @@ class Vector3d {
306
323
  this.z /= n;
307
324
  }
308
325
  getLengthSq() {
309
- return this.x ** 2 + this.y ** 2;
326
+ return this.x ** squareExp + this.y ** squareExp;
310
327
  }
311
328
  mult(n) {
312
329
  return Vector3d.create(this.x * n, this.y * n, this.z * n);
@@ -317,19 +334,20 @@ class Vector3d {
317
334
  this.z *= n;
318
335
  }
319
336
  normalize() {
320
- const length = this.length;
321
- if (length != 0) {
322
- this.multTo(1.0 / length);
337
+ const length = this.length,
338
+ noLength = 0;
339
+ if (length != noLength) {
340
+ this.multTo(inverseFactorNumerator / length);
323
341
  }
324
342
  }
325
343
  rotate(angle) {
326
- return Vector3d.create(this.x * Math.cos(angle) - this.y * Math.sin(angle), this.x * Math.sin(angle) + this.y * Math.cos(angle), 0);
344
+ return Vector3d.create(this.x * Math.cos(angle) - this.y * Math.sin(angle), this.x * Math.sin(angle) + this.y * Math.cos(angle), origin.z);
327
345
  }
328
346
  setTo(c) {
329
347
  this.x = c.x;
330
348
  this.y = c.y;
331
349
  const v3d = c;
332
- this.z = v3d.z ? v3d.z : 0;
350
+ this.z = v3d.z ? v3d.z : origin.z;
333
351
  }
334
352
  sub(v) {
335
353
  return Vector3d.create(this.x - v.x, this.y - v.y, this.z - v.z);
@@ -342,12 +360,17 @@ class Vector3d {
342
360
  }
343
361
  ;// CONCATENATED MODULE: ../../engine/dist/browser/Core/Utils/Vector.js
344
362
 
363
+ const Vector_origin = {
364
+ x: 0,
365
+ y: 0,
366
+ z: 0
367
+ };
345
368
  class Vector extends Vector3d {
346
369
  constructor(xOrCoords, y) {
347
- super(xOrCoords, y, 0);
370
+ super(xOrCoords, y, Vector_origin.z);
348
371
  }
349
372
  static get origin() {
350
- return Vector.create(0, 0);
373
+ return Vector.create(Vector_origin.x, Vector_origin.y);
351
374
  }
352
375
  static clone(source) {
353
376
  return Vector.create(source.x, source.y);
@@ -359,8 +382,11 @@ class Vector extends Vector3d {
359
382
  ;// CONCATENATED MODULE: ../../engine/dist/browser/Utils/NumberUtils.js
360
383
 
361
384
 
385
+
362
386
  let _random = Math.random;
363
- const easings = new Map();
387
+ const easings = new Map(),
388
+ NumberUtils_double = 2,
389
+ doublePI = Math.PI * NumberUtils_double;
364
390
  function addEasing(name, easing) {
365
391
  if (easings.get(name)) {
366
392
  return;
@@ -368,13 +394,15 @@ function addEasing(name, easing) {
368
394
  easings.set(name, easing);
369
395
  }
370
396
  function getEasing(name) {
371
- return easings.get(name) || (value => value);
397
+ return easings.get(name) ?? (value => value);
372
398
  }
373
399
  function setRandom(rnd = Math.random) {
374
400
  _random = rnd;
375
401
  }
376
402
  function getRandom() {
377
- return clamp(_random(), 0, 1 - 1e-16);
403
+ const min = 0,
404
+ max = 1;
405
+ return clamp(_random(), min, max - Number.EPSILON);
378
406
  }
379
407
  function clamp(num, min, max) {
380
408
  return Math.min(Math.max(num, min), max);
@@ -383,10 +411,11 @@ function mix(comp1, comp2, weight1, weight2) {
383
411
  return Math.floor((comp1 * weight1 + comp2 * weight2) / (weight1 + weight2));
384
412
  }
385
413
  function randomInRange(r) {
386
- const max = getRangeMax(r);
414
+ const max = getRangeMax(r),
415
+ minOffset = 0;
387
416
  let min = getRangeMin(r);
388
417
  if (max === min) {
389
- min = 0;
418
+ min = minOffset;
390
419
  }
391
420
  return getRandom() * (max - min) + min;
392
421
  }
@@ -412,43 +441,52 @@ function setRangeValue(source, value) {
412
441
  }
413
442
  function getDistances(pointA, pointB) {
414
443
  const dx = pointA.x - pointB.x,
415
- dy = pointA.y - pointB.y;
444
+ dy = pointA.y - pointB.y,
445
+ squareExp = 2;
416
446
  return {
417
447
  dx: dx,
418
448
  dy: dy,
419
- distance: Math.sqrt(dx ** 2 + dy ** 2)
449
+ distance: Math.sqrt(dx ** squareExp + dy ** squareExp)
420
450
  };
421
451
  }
422
452
  function getDistance(pointA, pointB) {
423
453
  return getDistances(pointA, pointB).distance;
424
454
  }
455
+ function degToRad(degrees) {
456
+ const PIDeg = 180;
457
+ return degrees * Math.PI / PIDeg;
458
+ }
425
459
  function getParticleDirectionAngle(direction, position, center) {
426
460
  if (isNumber(direction)) {
427
- return direction * Math.PI / 180;
461
+ return degToRad(direction);
428
462
  }
463
+ const empty = 0,
464
+ half = 0.5,
465
+ quarter = 0.25,
466
+ threeQuarter = half + quarter;
429
467
  switch (direction) {
430
468
  case "top":
431
- return -Math.PI * 0.5;
469
+ return -Math.PI * half;
432
470
  case "top-right":
433
- return -Math.PI * 0.25;
471
+ return -Math.PI * quarter;
434
472
  case "right":
435
- return 0;
473
+ return empty;
436
474
  case "bottom-right":
437
- return Math.PI * 0.25;
475
+ return Math.PI * quarter;
438
476
  case "bottom":
439
- return Math.PI * 0.5;
477
+ return Math.PI * half;
440
478
  case "bottom-left":
441
- return Math.PI * 0.75;
479
+ return Math.PI * threeQuarter;
442
480
  case "left":
443
481
  return Math.PI;
444
482
  case "top-left":
445
- return -Math.PI * 0.75;
483
+ return -Math.PI * threeQuarter;
446
484
  case "inside":
447
485
  return Math.atan2(center.y - position.y, center.x - position.x);
448
486
  case "outside":
449
487
  return Math.atan2(position.y - center.y, position.x - center.x);
450
488
  default:
451
- return getRandom() * Math.PI * 2;
489
+ return getRandom() * doublePI;
452
490
  }
453
491
  }
454
492
  function getParticleBaseVelocity(direction) {
@@ -458,18 +496,19 @@ function getParticleBaseVelocity(direction) {
458
496
  return baseVelocity;
459
497
  }
460
498
  function collisionVelocity(v1, v2, m1, m2) {
461
- return Vector.create(v1.x * (m1 - m2) / (m1 + m2) + v2.x * 2 * m2 / (m1 + m2), v1.y);
499
+ const double = 2;
500
+ return Vector.create(v1.x * (m1 - m2) / (m1 + m2) + v2.x * double * m2 / (m1 + m2), v1.y);
462
501
  }
463
502
  function calcPositionFromSize(data) {
464
- return data.position && data.position.x !== undefined && data.position.y !== undefined ? {
465
- x: data.position.x * data.size.width / 100,
466
- y: data.position.y * data.size.height / 100
503
+ return data.position?.x !== undefined && data.position.y !== undefined ? {
504
+ x: data.position.x * data.size.width / percentDenominator,
505
+ y: data.position.y * data.size.height / percentDenominator
467
506
  } : undefined;
468
507
  }
469
508
  function calcPositionOrRandomFromSize(data) {
470
509
  return {
471
- x: (data.position?.x ?? getRandom() * 100) * data.size.width / 100,
472
- y: (data.position?.y ?? getRandom() * 100) * data.size.height / 100
510
+ x: (data.position?.x ?? getRandom() * percentDenominator) * data.size.width / percentDenominator,
511
+ y: (data.position?.y ?? getRandom() * percentDenominator) * data.size.height / percentDenominator
473
512
  };
474
513
  }
475
514
  function calcPositionOrRandomFromSizeRanged(data) {
@@ -499,11 +538,16 @@ function calcExactPositionOrRandomFromSizeRanged(data) {
499
538
  });
500
539
  }
501
540
  function parseAlpha(input) {
502
- return input ? input.endsWith("%") ? parseFloat(input) / 100 : parseFloat(input) : 1;
541
+ const defaultAlpha = 1;
542
+ if (!input) {
543
+ return defaultAlpha;
544
+ }
545
+ return input.endsWith("%") ? parseFloat(input) / percentDenominator : parseFloat(input);
503
546
  }
504
547
  ;// CONCATENATED MODULE: ../../engine/dist/browser/Utils/Utils.js
505
548
 
506
549
 
550
+
507
551
  const _logger = {
508
552
  debug: console.debug,
509
553
  error: console.error,
@@ -534,11 +578,13 @@ function rectSideBounce(data) {
534
578
  rectOtherSide,
535
579
  velocity,
536
580
  factor
537
- } = data;
581
+ } = data,
582
+ half = 0.5,
583
+ minVelocity = 0;
538
584
  if (pOtherSide.min < rectOtherSide.min || pOtherSide.min > rectOtherSide.max || pOtherSide.max < rectOtherSide.min || pOtherSide.max > rectOtherSide.max) {
539
585
  return res;
540
586
  }
541
- if (pSide.max >= rectSide.min && pSide.max <= (rectSide.max + rectSide.min) * 0.5 && velocity > 0 || pSide.min <= rectSide.max && pSide.min > (rectSide.max + rectSide.min) * 0.5 && velocity < 0) {
587
+ if (pSide.max >= rectSide.min && pSide.max <= (rectSide.max + rectSide.min) * half && velocity > minVelocity || pSide.min <= rectSide.max && pSide.min > (rectSide.max + rectSide.min) * half && velocity < minVelocity) {
542
588
  res.velocity = velocity * -factor;
543
589
  res.bounced = true;
544
590
  }
@@ -575,7 +621,8 @@ function safeMutationObserver(callback) {
575
621
  return new MutationObserver(callback);
576
622
  }
577
623
  function isInArray(value, array) {
578
- return value === array || isArray(array) && array.indexOf(value) > -1;
624
+ const invalidIndex = -1;
625
+ return value === array || isArray(array) && array.indexOf(value) > invalidIndex;
579
626
  }
580
627
  async function loadFont(font, weight) {
581
628
  try {
@@ -589,7 +636,8 @@ function itemFromArray(array, index, useIndex = true) {
589
636
  return array[index !== undefined && useIndex ? index % array.length : arrayRandomIndex(array)];
590
637
  }
591
638
  function isPointInside(point, size, offset, radius, direction) {
592
- return areBoundsInside(calculateBounds(point, radius ?? 0), size, offset, direction);
639
+ const minRadius = 0;
640
+ return areBoundsInside(calculateBounds(point, radius ?? minRadius), size, offset, direction);
593
641
  }
594
642
  function areBoundsInside(bounds, size, offset, direction) {
595
643
  let inside = true;
@@ -686,8 +734,9 @@ function circleBounce(p1, p2) {
686
734
  {
687
735
  dx: xDist,
688
736
  dy: yDist
689
- } = getDistances(pos2, pos1);
690
- if (xVelocityDiff * xDist + yVelocityDiff * yDist < 0) {
737
+ } = getDistances(pos2, pos1),
738
+ minimumDistance = 0;
739
+ if (xVelocityDiff * xDist + yVelocityDiff * yDist < minimumDistance) {
691
740
  return;
692
741
  }
693
742
  const angle = -Math.atan2(yDist, xDist),
@@ -767,19 +816,24 @@ function rectBounce(particle, divBounds) {
767
816
  }
768
817
  }
769
818
  function executeOnSingleOrMultiple(obj, callback) {
770
- return isArray(obj) ? obj.map((item, index) => callback(item, index)) : callback(obj, 0);
819
+ const defaultIndex = 0;
820
+ return isArray(obj) ? obj.map((item, index) => callback(item, index)) : callback(obj, defaultIndex);
771
821
  }
772
822
  function itemFromSingleOrMultiple(obj, index, useIndex) {
773
823
  return isArray(obj) ? itemFromArray(obj, index, useIndex) : obj;
774
824
  }
775
825
  function findItemFromSingleOrMultiple(obj, callback) {
776
- return isArray(obj) ? obj.find((t, index) => callback(t, index)) : callback(obj, 0) ? obj : undefined;
826
+ if (isArray(obj)) {
827
+ return obj.find((t, index) => callback(t, index));
828
+ }
829
+ const defaultIndex = 0;
830
+ return callback(obj, defaultIndex) ? obj : undefined;
777
831
  }
778
832
  function initParticleNumericAnimationValue(options, pxRatio) {
779
833
  const valueRange = options.value,
780
834
  animationOptions = options.animation,
781
835
  res = {
782
- delayTime: getRangeValue(animationOptions.delay) * 1000,
836
+ delayTime: getRangeValue(animationOptions.delay) * millisecondsToSeconds,
783
837
  enable: animationOptions.enable,
784
838
  value: getRangeValue(options.value) * pxRatio,
785
839
  max: getRangeMax(valueRange) * pxRatio,
@@ -787,9 +841,10 @@ function initParticleNumericAnimationValue(options, pxRatio) {
787
841
  loops: 0,
788
842
  maxLoops: getRangeValue(animationOptions.count),
789
843
  time: 0
790
- };
844
+ },
845
+ decayOffset = 1;
791
846
  if (animationOptions.enable) {
792
- res.decay = 1 - getRangeValue(animationOptions.decay);
847
+ res.decay = decayOffset - getRangeValue(animationOptions.decay);
793
848
  switch (animationOptions.mode) {
794
849
  case "increase":
795
850
  res.status = "increasing";
@@ -798,7 +853,7 @@ function initParticleNumericAnimationValue(options, pxRatio) {
798
853
  res.status = "decreasing";
799
854
  break;
800
855
  case "random":
801
- res.status = getRandom() >= 0.5 ? "increasing" : "decreasing";
856
+ res.status = getRandom() >= halfRandom ? "increasing" : "decreasing";
802
857
  break;
803
858
  }
804
859
  const autoStatus = animationOptions.mode === "auto";
@@ -819,7 +874,7 @@ function initParticleNumericAnimationValue(options, pxRatio) {
819
874
  default:
820
875
  res.value = randomInRange(res);
821
876
  if (autoStatus) {
822
- res.status = getRandom() >= 0.5 ? "increasing" : "decreasing";
877
+ res.status = getRandom() >= halfRandom ? "increasing" : "decreasing";
823
878
  }
824
879
  break;
825
880
  }
@@ -839,13 +894,13 @@ function getPositionOrSize(positionOrSize, canvasSize) {
839
894
  const isPosition = ("x" in positionOrSize);
840
895
  if (isPosition) {
841
896
  return {
842
- x: positionOrSize.x / 100 * canvasSize.width,
843
- y: positionOrSize.y / 100 * canvasSize.height
897
+ x: positionOrSize.x / percentDenominator * canvasSize.width,
898
+ y: positionOrSize.y / percentDenominator * canvasSize.height
844
899
  };
845
900
  } else {
846
901
  return {
847
- width: positionOrSize.width / 100 * canvasSize.width,
848
- height: positionOrSize.height / 100 * canvasSize.height
902
+ width: positionOrSize.width / percentDenominator * canvasSize.width,
903
+ height: positionOrSize.height / percentDenominator * canvasSize.height
849
904
  };
850
905
  }
851
906
  }
@@ -873,9 +928,85 @@ function isObject(arg) {
873
928
  function isArray(arg) {
874
929
  return Array.isArray(arg);
875
930
  }
931
+ function checkDestroy(particle, destroyType, value, minValue, maxValue) {
932
+ switch (destroyType) {
933
+ case "max":
934
+ if (value >= maxValue) {
935
+ particle.destroy();
936
+ }
937
+ break;
938
+ case "min":
939
+ if (value <= minValue) {
940
+ particle.destroy();
941
+ }
942
+ break;
943
+ }
944
+ }
945
+ function updateAnimation(particle, data, changeDirection, destroyType, delta) {
946
+ const minLoops = 0,
947
+ minDelay = 0,
948
+ identity = 1,
949
+ minVelocity = 0,
950
+ minDecay = 1;
951
+ if (particle.destroyed || !data || !data.enable || (data.maxLoops ?? minLoops) > minLoops && (data.loops ?? minLoops) > (data.maxLoops ?? minLoops)) {
952
+ return;
953
+ }
954
+ const velocity = (data.velocity ?? minVelocity) * delta.factor,
955
+ minValue = data.min,
956
+ maxValue = data.max,
957
+ decay = data.decay ?? minDecay;
958
+ if (!data.time) {
959
+ data.time = 0;
960
+ }
961
+ if ((data.delayTime ?? minDelay) > minDelay && data.time < (data.delayTime ?? minDelay)) {
962
+ data.time += delta.value;
963
+ }
964
+ if ((data.delayTime ?? minDelay) > minDelay && data.time < (data.delayTime ?? minDelay)) {
965
+ return;
966
+ }
967
+ switch (data.status) {
968
+ case "increasing":
969
+ if (data.value >= maxValue) {
970
+ if (changeDirection) {
971
+ data.status = "decreasing";
972
+ } else {
973
+ data.value -= maxValue;
974
+ }
975
+ if (!data.loops) {
976
+ data.loops = minLoops;
977
+ }
978
+ data.loops++;
979
+ } else {
980
+ data.value += velocity;
981
+ }
982
+ break;
983
+ case "decreasing":
984
+ if (data.value <= minValue) {
985
+ if (changeDirection) {
986
+ data.status = "increasing";
987
+ } else {
988
+ data.value += maxValue;
989
+ }
990
+ if (!data.loops) {
991
+ data.loops = minLoops;
992
+ }
993
+ data.loops++;
994
+ } else {
995
+ data.value -= velocity;
996
+ }
997
+ }
998
+ if (data.velocity && decay !== identity) {
999
+ data.velocity *= decay;
1000
+ }
1001
+ checkDestroy(particle, destroyType, data.value, minValue, maxValue);
1002
+ if (!particle.destroyed) {
1003
+ data.value = clamp(data.value, minValue, maxValue);
1004
+ }
1005
+ }
876
1006
  ;// CONCATENATED MODULE: ../../engine/dist/browser/Utils/ColorUtils.js
877
1007
 
878
1008
 
1009
+
879
1010
  const randomColorValue = "random",
880
1011
  midColorValue = "mid",
881
1012
  colorManagers = new Map();
@@ -893,12 +1024,15 @@ function stringToRgba(input) {
893
1024
  return r + r + g + g + b + b + (a !== undefined ? a + a : "");
894
1025
  }),
895
1026
  regex = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})?$/i,
896
- result = regex.exec(hexFixed);
1027
+ result = regex.exec(hexFixed),
1028
+ radix = 16,
1029
+ defaultAlpha = 1,
1030
+ alphaFactor = 0xff;
897
1031
  return result ? {
898
- a: result[4] !== undefined ? parseInt(result[4], 16) / 0xff : 1,
899
- b: parseInt(result[3], 16),
900
- g: parseInt(result[2], 16),
901
- r: parseInt(result[1], 16)
1032
+ a: result[4] !== undefined ? parseInt(result[4], radix) / alphaFactor : defaultAlpha,
1033
+ b: parseInt(result[3], radix),
1034
+ g: parseInt(result[2], radix),
1035
+ r: parseInt(result[1], radix)
902
1036
  } : undefined;
903
1037
  }
904
1038
  function rangeColorToRgb(input, index, useIndex = true) {
@@ -954,28 +1088,37 @@ function rangeColorToHsl(color, index, useIndex = true) {
954
1088
  return rgb ? rgbToHsl(rgb) : undefined;
955
1089
  }
956
1090
  function rgbToHsl(color) {
957
- const r1 = color.r / 255,
958
- g1 = color.g / 255,
959
- b1 = color.b / 255,
1091
+ const rgbMax = 255,
1092
+ hMax = 360,
1093
+ sMax = 100,
1094
+ lMax = 100,
1095
+ hMin = 0,
1096
+ sMin = 0,
1097
+ hPhase = 60,
1098
+ half = 0.5,
1099
+ double = 2,
1100
+ r1 = color.r / rgbMax,
1101
+ g1 = color.g / rgbMax,
1102
+ b1 = color.b / rgbMax,
960
1103
  max = Math.max(r1, g1, b1),
961
1104
  min = Math.min(r1, g1, b1),
962
1105
  res = {
963
- h: 0,
964
- l: (max + min) * 0.5,
965
- s: 0
1106
+ h: hMin,
1107
+ l: (max + min) * half,
1108
+ s: sMin
966
1109
  };
967
1110
  if (max !== min) {
968
- res.s = res.l < 0.5 ? (max - min) / (max + min) : (max - min) / (2.0 - max - min);
969
- res.h = r1 === max ? (g1 - b1) / (max - min) : res.h = g1 === max ? 2.0 + (b1 - r1) / (max - min) : 4.0 + (r1 - g1) / (max - min);
1111
+ res.s = res.l < half ? (max - min) / (max + min) : (max - min) / (double - max - min);
1112
+ res.h = r1 === max ? (g1 - b1) / (max - min) : res.h = g1 === max ? double + (b1 - r1) / (max - min) : double * double + (r1 - g1) / (max - min);
970
1113
  }
971
- res.l *= 100;
972
- res.s *= 100;
973
- res.h *= 60;
974
- if (res.h < 0) {
975
- res.h += 360;
1114
+ res.l *= lMax;
1115
+ res.s *= sMax;
1116
+ res.h *= hPhase;
1117
+ if (res.h < hMin) {
1118
+ res.h += hMax;
976
1119
  }
977
- if (res.h >= 360) {
978
- res.h -= 360;
1120
+ if (res.h >= hMax) {
1121
+ res.h -= hMax;
979
1122
  }
980
1123
  return res;
981
1124
  }
@@ -986,43 +1129,59 @@ function stringToRgb(input) {
986
1129
  return stringToRgba(input);
987
1130
  }
988
1131
  function hslToRgb(hsl) {
989
- const h = (hsl.h % 360 + 360) % 360,
990
- s = Math.max(0, Math.min(100, hsl.s)),
991
- l = Math.max(0, Math.min(100, hsl.l)),
992
- hNormalized = h / 360,
993
- sNormalized = s / 100,
994
- lNormalized = l / 100;
995
- if (s === 0) {
996
- const grayscaleValue = Math.round(lNormalized * 255);
1132
+ const hMax = 360,
1133
+ sMax = 100,
1134
+ lMax = 100,
1135
+ sMin = 0,
1136
+ lMin = 0,
1137
+ h = (hsl.h % hMax + hMax) % hMax,
1138
+ s = Math.max(sMin, Math.min(sMax, hsl.s)),
1139
+ l = Math.max(lMin, Math.min(lMax, hsl.l)),
1140
+ hNormalized = h / hMax,
1141
+ sNormalized = s / sMax,
1142
+ lNormalized = l / lMax,
1143
+ rgbFactor = 255,
1144
+ triple = 3;
1145
+ if (s === sMin) {
1146
+ const grayscaleValue = Math.round(lNormalized * rgbFactor);
997
1147
  return {
998
1148
  r: grayscaleValue,
999
1149
  g: grayscaleValue,
1000
1150
  b: grayscaleValue
1001
1151
  };
1002
1152
  }
1003
- const channel = (temp1, temp2, temp3) => {
1004
- if (temp3 < 0) {
1005
- temp3 += 1;
1153
+ const half = 0.5,
1154
+ double = 2,
1155
+ channel = (temp1, temp2, temp3) => {
1156
+ const temp3Min = 0,
1157
+ temp3Max = 1,
1158
+ sextuple = 6;
1159
+ if (temp3 < temp3Min) {
1160
+ temp3++;
1006
1161
  }
1007
- if (temp3 > 1) {
1008
- temp3 -= 1;
1162
+ if (temp3 > temp3Max) {
1163
+ temp3--;
1009
1164
  }
1010
- if (temp3 * 6 < 1) {
1011
- return temp1 + (temp2 - temp1) * 6 * temp3;
1165
+ if (temp3 * sextuple < temp3Max) {
1166
+ return temp1 + (temp2 - temp1) * sextuple * temp3;
1012
1167
  }
1013
- if (temp3 * 2 < 1) {
1168
+ if (temp3 * double < temp3Max) {
1014
1169
  return temp2;
1015
1170
  }
1016
- if (temp3 * 3 < 2) {
1017
- return temp1 + (temp2 - temp1) * (2 / 3 - temp3) * 6;
1171
+ if (temp3 * triple < temp3Max * double) {
1172
+ const temp3Offset = double / triple;
1173
+ return temp1 + (temp2 - temp1) * (temp3Offset - temp3) * sextuple;
1018
1174
  }
1019
1175
  return temp1;
1020
1176
  },
1021
- temp1 = lNormalized < 0.5 ? lNormalized * (1 + sNormalized) : lNormalized + sNormalized - lNormalized * sNormalized,
1022
- temp2 = 2 * lNormalized - temp1,
1023
- red = Math.min(255, 255 * channel(temp2, temp1, hNormalized + 1 / 3)),
1024
- green = Math.min(255, 255 * channel(temp2, temp1, hNormalized)),
1025
- blue = Math.min(255, 255 * channel(temp2, temp1, hNormalized - 1 / 3));
1177
+ sNormalizedOffset = 1,
1178
+ temp1 = lNormalized < half ? lNormalized * (sNormalizedOffset + sNormalized) : lNormalized + sNormalized - lNormalized * sNormalized,
1179
+ temp2 = double * lNormalized - temp1,
1180
+ phaseNumerator = 1,
1181
+ phaseThird = phaseNumerator / triple,
1182
+ red = Math.min(rgbFactor, rgbFactor * channel(temp2, temp1, hNormalized + phaseThird)),
1183
+ green = Math.min(rgbFactor, rgbFactor * channel(temp2, temp1, hNormalized)),
1184
+ blue = Math.min(rgbFactor, rgbFactor * channel(temp2, temp1, hNormalized - phaseThird));
1026
1185
  return {
1027
1186
  r: Math.round(red),
1028
1187
  g: Math.round(green),
@@ -1039,18 +1198,22 @@ function hslaToRgba(hsla) {
1039
1198
  };
1040
1199
  }
1041
1200
  function getRandomRgbColor(min) {
1042
- const fixedMin = min ?? 0;
1201
+ const defaultMin = 0,
1202
+ fixedMin = min ?? defaultMin,
1203
+ rgbMax = 256;
1043
1204
  return {
1044
- b: Math.floor(randomInRange(setRangeValue(fixedMin, 256))),
1045
- g: Math.floor(randomInRange(setRangeValue(fixedMin, 256))),
1046
- r: Math.floor(randomInRange(setRangeValue(fixedMin, 256)))
1205
+ b: Math.floor(randomInRange(setRangeValue(fixedMin, rgbMax))),
1206
+ g: Math.floor(randomInRange(setRangeValue(fixedMin, rgbMax))),
1207
+ r: Math.floor(randomInRange(setRangeValue(fixedMin, rgbMax)))
1047
1208
  };
1048
1209
  }
1049
1210
  function getStyleFromRgb(color, opacity) {
1050
- return `rgba(${color.r}, ${color.g}, ${color.b}, ${opacity ?? 1})`;
1211
+ const defaultOpacity = 1;
1212
+ return `rgba(${color.r}, ${color.g}, ${color.b}, ${opacity ?? defaultOpacity})`;
1051
1213
  }
1052
1214
  function getStyleFromHsl(color, opacity) {
1053
- return `hsla(${color.h}, ${color.s}%, ${color.l}%, ${opacity ?? 1})`;
1215
+ const defaultOpacity = 1;
1216
+ return `hsla(${color.h}, ${color.s}%, ${color.l}%, ${opacity ?? defaultOpacity})`;
1054
1217
  }
1055
1218
  function colorMix(color1, color2, size1, size2) {
1056
1219
  let rgb1 = color1,
@@ -1136,25 +1299,120 @@ function getHslAnimationFromHsl(hsl, animationOptions, reduceFactor) {
1136
1299
  }
1137
1300
  function setColorAnimation(colorValue, colorAnimation, reduceFactor) {
1138
1301
  colorValue.enable = colorAnimation.enable;
1302
+ const defaultVelocity = 0,
1303
+ decayOffset = 1,
1304
+ defaultLoops = 0,
1305
+ defaultTime = 0;
1139
1306
  if (colorValue.enable) {
1140
- colorValue.velocity = getRangeValue(colorAnimation.speed) / 100 * reduceFactor;
1141
- colorValue.decay = 1 - getRangeValue(colorAnimation.decay);
1307
+ colorValue.velocity = getRangeValue(colorAnimation.speed) / percentDenominator * reduceFactor;
1308
+ colorValue.decay = decayOffset - getRangeValue(colorAnimation.decay);
1142
1309
  colorValue.status = "increasing";
1143
- colorValue.loops = 0;
1310
+ colorValue.loops = defaultLoops;
1144
1311
  colorValue.maxLoops = getRangeValue(colorAnimation.count);
1145
- colorValue.time = 0;
1146
- colorValue.delayTime = getRangeValue(colorAnimation.delay) * 1000;
1312
+ colorValue.time = defaultTime;
1313
+ colorValue.delayTime = getRangeValue(colorAnimation.delay) * millisecondsToSeconds;
1147
1314
  if (!colorAnimation.sync) {
1148
1315
  colorValue.velocity *= getRandom();
1149
1316
  colorValue.value *= getRandom();
1150
1317
  }
1151
1318
  colorValue.initialValue = colorValue.value;
1319
+ colorValue.offset = setRangeValue(colorAnimation.offset);
1152
1320
  } else {
1153
- colorValue.velocity = 0;
1321
+ colorValue.velocity = defaultVelocity;
1322
+ }
1323
+ }
1324
+ function updateColorValue(data, range, decrease, delta) {
1325
+ const minLoops = 0,
1326
+ minDelay = 0,
1327
+ identity = 1,
1328
+ minVelocity = 0,
1329
+ minOffset = 0,
1330
+ velocityFactor = 3.6;
1331
+ if (!data || !data.enable || (data.maxLoops ?? minLoops) > minLoops && (data.loops ?? minLoops) > (data.maxLoops ?? minLoops)) {
1332
+ return;
1333
+ }
1334
+ if (!data.time) {
1335
+ data.time = 0;
1336
+ }
1337
+ if ((data.delayTime ?? minDelay) > minDelay && data.time < (data.delayTime ?? minDelay)) {
1338
+ data.time += delta.value;
1339
+ }
1340
+ if ((data.delayTime ?? minDelay) > minDelay && data.time < (data.delayTime ?? minDelay)) {
1341
+ return;
1342
+ }
1343
+ const offset = data.offset ? randomInRange(data.offset) : minOffset,
1344
+ velocity = (data.velocity ?? minVelocity) * delta.factor + offset * velocityFactor,
1345
+ decay = data.decay ?? identity,
1346
+ max = getRangeMax(range),
1347
+ min = getRangeMin(range);
1348
+ if (!decrease || data.status === "increasing") {
1349
+ data.value += velocity;
1350
+ if (data.value > max) {
1351
+ if (!data.loops) {
1352
+ data.loops = 0;
1353
+ }
1354
+ data.loops++;
1355
+ if (decrease) {
1356
+ data.status = "decreasing";
1357
+ } else {
1358
+ data.value -= max;
1359
+ }
1360
+ }
1361
+ } else {
1362
+ data.value -= velocity;
1363
+ const minValue = 0;
1364
+ if (data.value < minValue) {
1365
+ if (!data.loops) {
1366
+ data.loops = 0;
1367
+ }
1368
+ data.loops++;
1369
+ data.status = "increasing";
1370
+ }
1371
+ }
1372
+ if (data.velocity && decay !== identity) {
1373
+ data.velocity *= decay;
1374
+ }
1375
+ data.value = clamp(data.value, min, max);
1376
+ }
1377
+ function updateColor(color, delta) {
1378
+ if (!color) {
1379
+ return;
1380
+ }
1381
+ const {
1382
+ h,
1383
+ s,
1384
+ l
1385
+ } = color;
1386
+ const ranges = {
1387
+ h: {
1388
+ min: 0,
1389
+ max: 360
1390
+ },
1391
+ s: {
1392
+ min: 0,
1393
+ max: 100
1394
+ },
1395
+ l: {
1396
+ min: 0,
1397
+ max: 100
1398
+ }
1399
+ };
1400
+ if (h) {
1401
+ updateColorValue(h, ranges.h, false, delta);
1402
+ }
1403
+ if (s) {
1404
+ updateColorValue(s, ranges.s, true, delta);
1405
+ }
1406
+ if (l) {
1407
+ updateColorValue(l, ranges.l, true, delta);
1154
1408
  }
1155
1409
  }
1156
1410
  ;// CONCATENATED MODULE: ../../engine/dist/browser/Utils/CanvasUtils.js
1157
1411
 
1412
+ const CanvasUtils_origin = {
1413
+ x: 0,
1414
+ y: 0
1415
+ };
1158
1416
  function drawLine(context, begin, end) {
1159
1417
  context.beginPath();
1160
1418
  context.moveTo(begin.x, begin.y);
@@ -1163,44 +1421,46 @@ function drawLine(context, begin, end) {
1163
1421
  }
1164
1422
  function paintBase(context, dimension, baseColor) {
1165
1423
  context.fillStyle = baseColor ?? "rgba(0,0,0,0)";
1166
- context.fillRect(0, 0, dimension.width, dimension.height);
1424
+ context.fillRect(CanvasUtils_origin.x, CanvasUtils_origin.y, dimension.width, dimension.height);
1167
1425
  }
1168
1426
  function paintImage(context, dimension, image, opacity) {
1169
1427
  if (!image) {
1170
1428
  return;
1171
1429
  }
1172
1430
  context.globalAlpha = opacity;
1173
- context.drawImage(image, 0, 0, dimension.width, dimension.height);
1431
+ context.drawImage(image, CanvasUtils_origin.x, CanvasUtils_origin.y, dimension.width, dimension.height);
1174
1432
  context.globalAlpha = 1;
1175
1433
  }
1176
1434
  function clear(context, dimension) {
1177
- context.clearRect(0, 0, dimension.width, dimension.height);
1435
+ context.clearRect(CanvasUtils_origin.x, CanvasUtils_origin.y, dimension.width, dimension.height);
1178
1436
  }
1179
1437
  function drawParticle(data) {
1180
1438
  const {
1181
- container,
1182
- context,
1183
- particle,
1184
- delta,
1185
- colorStyles,
1186
- backgroundMask,
1187
- composite,
1188
- radius,
1189
- opacity,
1190
- shadow,
1191
- transform
1192
- } = data;
1193
- const pos = particle.getPosition(),
1194
- angle = particle.rotation + (particle.pathRotation ? particle.velocity.angle : 0),
1439
+ container,
1440
+ context,
1441
+ particle,
1442
+ delta,
1443
+ colorStyles,
1444
+ backgroundMask,
1445
+ composite,
1446
+ radius,
1447
+ opacity,
1448
+ shadow,
1449
+ transform
1450
+ } = data,
1451
+ pos = particle.getPosition(),
1452
+ defaultAngle = 0,
1453
+ angle = particle.rotation + (particle.pathRotation ? particle.velocity.angle : defaultAngle),
1195
1454
  rotateData = {
1196
1455
  sin: Math.sin(angle),
1197
1456
  cos: Math.cos(angle)
1198
1457
  },
1458
+ defaultTransformFactor = 1,
1199
1459
  transformData = {
1200
- a: rotateData.cos * (transform.a ?? 1),
1201
- b: rotateData.sin * (transform.b ?? 1),
1202
- c: -rotateData.sin * (transform.c ?? 1),
1203
- d: rotateData.cos * (transform.d ?? 1)
1460
+ a: rotateData.cos * (transform.a ?? defaultTransformFactor),
1461
+ b: rotateData.sin * (transform.b ?? defaultTransformFactor),
1462
+ c: -rotateData.sin * (transform.c ?? defaultTransformFactor),
1463
+ d: rotateData.cos * (transform.d ?? defaultTransformFactor)
1204
1464
  };
1205
1465
  context.setTransform(transformData.a, transformData.b, transformData.c, transformData.d, pos.x, pos.y);
1206
1466
  if (backgroundMask) {
@@ -1216,7 +1476,8 @@ function drawParticle(data) {
1216
1476
  if (colorStyles.fill) {
1217
1477
  context.fillStyle = colorStyles.fill;
1218
1478
  }
1219
- const strokeWidth = particle.strokeWidth ?? 0;
1479
+ const minStrokeWidth = 0,
1480
+ strokeWidth = particle.strokeWidth ?? minStrokeWidth;
1220
1481
  context.lineWidth = strokeWidth;
1221
1482
  if (colorStyles.stroke) {
1222
1483
  context.strokeStyle = colorStyles.stroke;
@@ -1228,23 +1489,14 @@ function drawParticle(data) {
1228
1489
  radius,
1229
1490
  opacity,
1230
1491
  delta,
1231
- transformData
1492
+ transformData,
1493
+ strokeWidth
1232
1494
  };
1233
- context.beginPath();
1234
1495
  drawShape(drawData);
1235
- if (particle.shapeClose) {
1236
- context.closePath();
1237
- }
1238
- if (strokeWidth > 0) {
1239
- context.stroke();
1240
- }
1241
- if (particle.shapeFill) {
1242
- context.fill();
1243
- }
1244
1496
  drawShapeAfterDraw(drawData);
1245
1497
  drawEffect(drawData);
1246
1498
  context.globalCompositeOperation = "source-over";
1247
- context.setTransform(1, 0, 0, 1, 0, 0);
1499
+ context.resetTransform();
1248
1500
  }
1249
1501
  function drawEffect(data) {
1250
1502
  const {
@@ -1277,14 +1529,16 @@ function drawEffect(data) {
1277
1529
  }
1278
1530
  function drawShape(data) {
1279
1531
  const {
1280
- container,
1281
- context,
1282
- particle,
1283
- radius,
1284
- opacity,
1285
- delta,
1286
- transformData
1287
- } = data;
1532
+ container,
1533
+ context,
1534
+ particle,
1535
+ radius,
1536
+ opacity,
1537
+ delta,
1538
+ strokeWidth,
1539
+ transformData
1540
+ } = data,
1541
+ minStrokeWidth = 0;
1288
1542
  if (!particle.shape) {
1289
1543
  return;
1290
1544
  }
@@ -1292,6 +1546,7 @@ function drawShape(data) {
1292
1546
  if (!drawer) {
1293
1547
  return;
1294
1548
  }
1549
+ context.beginPath();
1295
1550
  drawer.draw({
1296
1551
  context,
1297
1552
  particle,
@@ -1303,6 +1558,15 @@ function drawShape(data) {
1303
1558
  ...transformData
1304
1559
  }
1305
1560
  });
1561
+ if (particle.shapeClose) {
1562
+ context.closePath();
1563
+ }
1564
+ if (strokeWidth > minStrokeWidth) {
1565
+ context.stroke();
1566
+ }
1567
+ if (particle.shapeFill) {
1568
+ context.fill();
1569
+ }
1306
1570
  }
1307
1571
  function drawShapeAfterDraw(data) {
1308
1572
  const {
@@ -1318,7 +1582,7 @@ function drawShapeAfterDraw(data) {
1318
1582
  return;
1319
1583
  }
1320
1584
  const drawer = container.shapeDrawers.get(particle.shape);
1321
- if (!drawer || !drawer.afterDraw) {
1585
+ if (!drawer?.afterDraw) {
1322
1586
  return;
1323
1587
  }
1324
1588
  drawer.afterDraw({
@@ -1346,10 +1610,11 @@ function drawParticlePlugin(context, plugin, particle, delta) {
1346
1610
  plugin.drawParticle(context, particle, delta);
1347
1611
  }
1348
1612
  function alterHsl(color, type, value) {
1613
+ const lFactor = 1;
1349
1614
  return {
1350
1615
  h: color.h,
1351
1616
  s: color.s,
1352
- l: color.l + (type === "darken" ? -1 : 1) * value
1617
+ l: color.l + (type === "darken" ? -lFactor : lFactor) * value
1353
1618
  };
1354
1619
  }
1355
1620
  ;// CONCATENATED MODULE: ../../engine/dist/browser/Core/Canvas.js
@@ -1358,9 +1623,10 @@ function alterHsl(color, type, value) {
1358
1623
 
1359
1624
 
1360
1625
  function setTransformValue(factor, newFactor, key) {
1361
- const newValue = newFactor[key];
1626
+ const newValue = newFactor[key],
1627
+ defaultValue = 1;
1362
1628
  if (newValue !== undefined) {
1363
- factor[key] = (factor[key] ?? 1) * newValue;
1629
+ factor[key] = (factor[key] ?? defaultValue) * newValue;
1364
1630
  }
1365
1631
  }
1366
1632
  class Canvas {
@@ -1368,7 +1634,7 @@ class Canvas {
1368
1634
  this.container = container;
1369
1635
  this._applyPostDrawUpdaters = particle => {
1370
1636
  for (const updater of this._postDrawUpdaters) {
1371
- updater.afterDraw && updater.afterDraw(particle);
1637
+ updater.afterDraw?.(particle);
1372
1638
  }
1373
1639
  };
1374
1640
  this._applyPreDrawUpdaters = (ctx, particle, radius, zOpacity, colorStyles, transform) => {
@@ -1391,12 +1657,12 @@ class Canvas {
1391
1657
  setTransformValue(transform, updaterTransform, key);
1392
1658
  }
1393
1659
  }
1394
- updater.beforeDraw && updater.beforeDraw(particle);
1660
+ updater.beforeDraw?.(particle);
1395
1661
  }
1396
1662
  };
1397
1663
  this._applyResizePlugins = () => {
1398
1664
  for (const plugin of this._resizePlugins) {
1399
- plugin.resize && plugin.resize();
1665
+ plugin.resize?.();
1400
1666
  }
1401
1667
  };
1402
1668
  this._getPluginParticleColors = particle => {
@@ -1457,17 +1723,18 @@ class Canvas {
1457
1723
  if (!trail.enable) {
1458
1724
  return;
1459
1725
  }
1726
+ const factorNumerator = 1,
1727
+ opacity = factorNumerator / trail.length;
1460
1728
  if (trailFill.color) {
1461
1729
  const fillColor = rangeColorToRgb(trailFill.color);
1462
1730
  if (!fillColor) {
1463
1731
  return;
1464
1732
  }
1465
- const trail = options.particles.move.trail;
1466
1733
  this._trailFill = {
1467
1734
  color: {
1468
1735
  ...fillColor
1469
1736
  },
1470
- opacity: 1 / trail.length
1737
+ opacity
1471
1738
  };
1472
1739
  } else {
1473
1740
  await new Promise((resolve, reject) => {
@@ -1478,7 +1745,7 @@ class Canvas {
1478
1745
  img.addEventListener("load", () => {
1479
1746
  this._trailFill = {
1480
1747
  image: img,
1481
- opacity: 1 / trail.length
1748
+ opacity
1482
1749
  };
1483
1750
  resolve();
1484
1751
  });
@@ -1533,9 +1800,10 @@ class Canvas {
1533
1800
  return;
1534
1801
  }
1535
1802
  const priority = "important",
1536
- style = element.style;
1803
+ style = element.style,
1804
+ radix = 10;
1537
1805
  style.setProperty("position", "fixed", priority);
1538
- style.setProperty("z-index", this.container.actualOptions.fullScreen.zIndex.toString(10), priority);
1806
+ style.setProperty("z-index", this.container.actualOptions.fullScreen.zIndex.toString(radix), priority);
1539
1807
  style.setProperty("top", "0", priority);
1540
1808
  style.setProperty("left", "0", priority);
1541
1809
  style.setProperty("width", "100%", priority);
@@ -1558,10 +1826,11 @@ class Canvas {
1558
1826
  clear() {
1559
1827
  const options = this.container.actualOptions,
1560
1828
  trail = options.particles.move.trail,
1561
- trailFill = this._trailFill;
1829
+ trailFill = this._trailFill,
1830
+ minimumLength = 0;
1562
1831
  if (options.backgroundMask.enable) {
1563
1832
  this.paint();
1564
- } else if (trail.enable && trail.length > 0 && trailFill) {
1833
+ } else if (trail.enable && trail.length > minimumLength && trailFill) {
1565
1834
  if (trailFill.color) {
1566
1835
  this._paintBase(getStyleFromRgb(trailFill.color, trailFill.opacity));
1567
1836
  } else if (trailFill.image) {
@@ -1577,7 +1846,7 @@ class Canvas {
1577
1846
  this.stop();
1578
1847
  if (this._generated) {
1579
1848
  const element = this.element;
1580
- element && element.remove();
1849
+ element?.remove();
1581
1850
  } else {
1582
1851
  this._resetOriginalStyle();
1583
1852
  }
@@ -1597,8 +1866,9 @@ class Canvas {
1597
1866
  if (particle.spawning || particle.destroyed) {
1598
1867
  return;
1599
1868
  }
1600
- const radius = particle.getRadius();
1601
- if (radius <= 0) {
1869
+ const radius = particle.getRadius(),
1870
+ minimumSize = 0;
1871
+ if (radius <= minimumSize) {
1602
1872
  return;
1603
1873
  }
1604
1874
  const pfColor = particle.getFillColor(),
@@ -1617,8 +1887,11 @@ class Canvas {
1617
1887
  const container = this.container,
1618
1888
  options = container.actualOptions,
1619
1889
  zIndexOptions = particle.options.zIndex,
1620
- zOpacityFactor = (1 - particle.zIndexFactor) ** zIndexOptions.opacityRate,
1621
- opacity = particle.bubble.opacity ?? particle.opacity?.value ?? 1,
1890
+ zIndexFactorOffset = 1,
1891
+ zIndexFactor = zIndexFactorOffset - particle.zIndexFactor,
1892
+ zOpacityFactor = zIndexFactor ** zIndexOptions.opacityRate,
1893
+ defaultOpacity = 1,
1894
+ opacity = particle.bubble.opacity ?? particle.opacity?.value ?? defaultOpacity,
1622
1895
  strokeOpacity = particle.strokeOpacity ?? opacity,
1623
1896
  zOpacity = opacity * zOpacityFactor,
1624
1897
  zStrokeOpacity = strokeOpacity * zOpacityFactor,
@@ -1636,7 +1909,7 @@ class Canvas {
1636
1909
  colorStyles,
1637
1910
  backgroundMask: options.backgroundMask.enable,
1638
1911
  composite: options.backgroundMask.composite,
1639
- radius: radius * (1 - particle.zIndexFactor) ** zIndexOptions.sizeRate,
1912
+ radius: radius * zIndexFactor ** zIndexOptions.sizeRate,
1640
1913
  opacity: zOpacity,
1641
1914
  shadow: particle.options.shadow,
1642
1915
  transform
@@ -1708,7 +1981,7 @@ class Canvas {
1708
1981
  if (plugin.resize) {
1709
1982
  this._resizePlugins.push(plugin);
1710
1983
  }
1711
- if (plugin.particleFillColor || plugin.particleStrokeColor) {
1984
+ if (plugin.particleFillColor ?? plugin.particleStrokeColor) {
1712
1985
  this._colorPlugins.push(plugin);
1713
1986
  }
1714
1987
  }
@@ -1720,7 +1993,7 @@ class Canvas {
1720
1993
  if (updater.afterDraw) {
1721
1994
  this._postDrawUpdaters.push(updater);
1722
1995
  }
1723
- if (updater.getColorStyles || updater.getTransformValues || updater.beforeDraw) {
1996
+ if (updater.getColorStyles ?? updater.getTransformValues ?? updater.beforeDraw) {
1724
1997
  this._preDrawUpdaters.push(updater);
1725
1998
  }
1726
1999
  }
@@ -1806,6 +2079,7 @@ class Canvas {
1806
2079
  ;// CONCATENATED MODULE: ../../engine/dist/browser/Core/Utils/EventListeners.js
1807
2080
 
1808
2081
 
2082
+ const EventListeners_double = 2;
1809
2083
  function manageListener(element, event, handler, add, options) {
1810
2084
  if (add) {
1811
2085
  let addOptions = {
@@ -1842,7 +2116,8 @@ class EventListeners {
1842
2116
  executeOnSingleOrMultiple(onClick.mode, mode => this.container.handleClickMode(mode));
1843
2117
  }
1844
2118
  if (e.type === "touchend") {
1845
- setTimeout(() => this._mouseTouchFinish(), 500);
2119
+ const touchDelay = 500;
2120
+ setTimeout(() => this._mouseTouchFinish(), touchDelay);
1846
2121
  }
1847
2122
  };
1848
2123
  this._handleThemeChange = e => {
@@ -1853,7 +2128,7 @@ class EventListeners {
1853
2128
  themeName = mediaEvent.matches ? defaultThemes.dark : defaultThemes.light,
1854
2129
  theme = options.themes.find(theme => theme.name === themeName);
1855
2130
  if (theme && theme.default.auto) {
1856
- container.loadTheme(themeName);
2131
+ void container.loadTheme(themeName);
1857
2132
  }
1858
2133
  };
1859
2134
  this._handleVisibilityChange = () => {
@@ -1875,15 +2150,16 @@ class EventListeners {
1875
2150
  }
1876
2151
  }
1877
2152
  };
1878
- this._handleWindowResize = async () => {
2153
+ this._handleWindowResize = () => {
1879
2154
  if (this._resizeTimeout) {
1880
2155
  clearTimeout(this._resizeTimeout);
1881
2156
  delete this._resizeTimeout;
1882
2157
  }
1883
- this._resizeTimeout = setTimeout(async () => {
2158
+ const handleResize = async () => {
1884
2159
  const canvas = this.container.canvas;
1885
- canvas && (await canvas.windowResize());
1886
- }, this.container.actualOptions.interactivity.events.resize.delay * 1000);
2160
+ await canvas?.windowResize();
2161
+ };
2162
+ this._resizeTimeout = setTimeout(() => void handleResize(), this.container.actualOptions.interactivity.events.resize.delay * millisecondsToSeconds);
1887
2163
  };
1888
2164
  this._manageInteractivityListeners = (mouseLeaveTmpEvent, add) => {
1889
2165
  const handlers = this._handlers,
@@ -1974,12 +2250,12 @@ class EventListeners {
1974
2250
  this._resizeObserver.disconnect();
1975
2251
  delete this._resizeObserver;
1976
2252
  } else if (!this._resizeObserver && add && canvasEl) {
1977
- this._resizeObserver = new ResizeObserver(async entries => {
2253
+ this._resizeObserver = new ResizeObserver(entries => {
1978
2254
  const entry = entries.find(e => e.target === canvasEl);
1979
2255
  if (!entry) {
1980
2256
  return;
1981
2257
  }
1982
- await this._handleWindowResize();
2258
+ this._handleWindowResize();
1983
2259
  });
1984
2260
  this._resizeObserver.observe(canvasEl);
1985
2261
  }
@@ -2041,7 +2317,7 @@ class EventListeners {
2041
2317
  options = container.actualOptions,
2042
2318
  interactivity = container.interactivity,
2043
2319
  canvasEl = container.canvas.element;
2044
- if (!interactivity || !interactivity.element) {
2320
+ if (!interactivity?.element) {
2045
2321
  return;
2046
2322
  }
2047
2323
  interactivity.mouse.inside = true;
@@ -2065,8 +2341,8 @@ class EventListeners {
2065
2341
  targetRect = target.getBoundingClientRect(),
2066
2342
  canvasRect = canvasEl.getBoundingClientRect();
2067
2343
  pos = {
2068
- x: mouseEvent.offsetX + 2 * sourceRect.left - (targetRect.left + canvasRect.left),
2069
- y: mouseEvent.offsetY + 2 * sourceRect.top - (targetRect.top + canvasRect.top)
2344
+ x: mouseEvent.offsetX + EventListeners_double * sourceRect.left - (targetRect.left + canvasRect.left),
2345
+ y: mouseEvent.offsetY + EventListeners_double * sourceRect.top - (targetRect.top + canvasRect.top)
2070
2346
  };
2071
2347
  } else {
2072
2348
  pos = {
@@ -2084,11 +2360,13 @@ class EventListeners {
2084
2360
  this._canPush = e.type !== "touchmove";
2085
2361
  if (canvasEl) {
2086
2362
  const touchEvent = e,
2087
- lastTouch = touchEvent.touches[touchEvent.touches.length - 1],
2088
- canvasRect = canvasEl.getBoundingClientRect();
2363
+ lengthOffset = 1,
2364
+ lastTouch = touchEvent.touches[touchEvent.touches.length - lengthOffset],
2365
+ canvasRect = canvasEl.getBoundingClientRect(),
2366
+ defaultCoordinate = 0;
2089
2367
  pos = {
2090
- x: lastTouch.clientX - (canvasRect.left ?? 0),
2091
- y: lastTouch.clientY - (canvasRect.top ?? 0)
2368
+ x: lastTouch.clientX - (canvasRect.left ?? defaultCoordinate),
2369
+ y: lastTouch.clientY - (canvasRect.top ?? defaultCoordinate)
2092
2370
  };
2093
2371
  }
2094
2372
  }
@@ -2465,6 +2743,7 @@ class Interactivity {
2465
2743
  }
2466
2744
  ;// CONCATENATED MODULE: ../../engine/dist/browser/Options/Classes/ManualParticle.js
2467
2745
 
2746
+ const defaultPosition = 50;
2468
2747
  class ManualParticle {
2469
2748
  load(data) {
2470
2749
  if (!data) {
@@ -2472,8 +2751,8 @@ class ManualParticle {
2472
2751
  }
2473
2752
  if (data.position) {
2474
2753
  this.position = {
2475
- x: data.position.x ?? 50,
2476
- y: data.position.y ?? 50,
2754
+ x: data.position.x ?? defaultPosition,
2755
+ y: data.position.y ?? defaultPosition,
2477
2756
  mode: data.position.mode ?? "percent"
2478
2757
  };
2479
2758
  }
@@ -3562,6 +3841,9 @@ class Options {
3562
3841
  if (data.clear !== undefined) {
3563
3842
  this.clear = data.clear;
3564
3843
  }
3844
+ if (data.key !== undefined) {
3845
+ this.key = data.key;
3846
+ }
3565
3847
  if (data.name !== undefined) {
3566
3848
  this.name = data.name;
3567
3849
  }
@@ -3674,12 +3956,14 @@ class InteractionManager {
3674
3956
  }
3675
3957
  async externalInteract(delta) {
3676
3958
  for (const interactor of this._externalInteractors) {
3677
- interactor.isEnabled() && (await interactor.interact(delta));
3959
+ if (interactor.isEnabled()) {
3960
+ await interactor.interact(delta);
3961
+ }
3678
3962
  }
3679
3963
  }
3680
3964
  handleClickMode(mode) {
3681
3965
  for (const interactor of this._externalInteractors) {
3682
- interactor.handleClickMode && interactor.handleClickMode(mode);
3966
+ interactor.handleClickMode?.(mode);
3683
3967
  }
3684
3968
  }
3685
3969
  init() {
@@ -3702,15 +3986,21 @@ class InteractionManager {
3702
3986
  interactor.clear(particle, delta);
3703
3987
  }
3704
3988
  for (const interactor of this._particleInteractors) {
3705
- interactor.isEnabled(particle) && (await interactor.interact(particle, delta));
3989
+ if (interactor.isEnabled(particle)) {
3990
+ await interactor.interact(particle, delta);
3991
+ }
3706
3992
  }
3707
3993
  }
3708
- async reset(particle) {
3994
+ reset(particle) {
3709
3995
  for (const interactor of this._externalInteractors) {
3710
- interactor.isEnabled() && interactor.reset(particle);
3996
+ if (interactor.isEnabled()) {
3997
+ interactor.reset(particle);
3998
+ }
3711
3999
  }
3712
4000
  for (const interactor of this._particleInteractors) {
3713
- interactor.isEnabled(particle) && interactor.reset(particle);
4001
+ if (interactor.isEnabled(particle)) {
4002
+ interactor.reset(particle);
4003
+ }
3714
4004
  }
3715
4005
  }
3716
4006
  }
@@ -3724,6 +4014,10 @@ class InteractionManager {
3724
4014
 
3725
4015
 
3726
4016
 
4017
+ const defaultRetryCount = 0,
4018
+ Particle_double = 2,
4019
+ half = 0.5,
4020
+ Particle_squareExp = 2;
3727
4021
  function loadEffectData(effect, effectOptions, id, reduceDuplicates) {
3728
4022
  const effectData = effectOptions.options[effect];
3729
4023
  if (!effectData) {
@@ -3748,7 +4042,7 @@ function fixOutMode(data) {
3748
4042
  if (!isInArray(data.outMode, data.checkModes)) {
3749
4043
  return;
3750
4044
  }
3751
- const diameter = data.radius * 2;
4045
+ const diameter = data.radius * Particle_double;
3752
4046
  if (data.coord > data.maxCoord - diameter) {
3753
4047
  data.setCb(-data.radius);
3754
4048
  } else if (data.coord < diameter) {
@@ -3758,7 +4052,7 @@ function fixOutMode(data) {
3758
4052
  class Particle {
3759
4053
  constructor(engine, id, container, position, overrideOptions, group) {
3760
4054
  this.container = container;
3761
- this._calcPosition = (container, position, zIndex, tryCount = 0) => {
4055
+ this._calcPosition = (container, position, zIndex, tryCount = defaultRetryCount) => {
3762
4056
  for (const [, plugin] of container.plugins) {
3763
4057
  const pluginPos = plugin.particlePosition !== undefined ? plugin.particlePosition(position, this) : undefined;
3764
4058
  if (pluginPos) {
@@ -3798,7 +4092,8 @@ class Particle {
3798
4092
  fixVertical(outModes.top ?? outModes.default);
3799
4093
  fixVertical(outModes.bottom ?? outModes.default);
3800
4094
  if (this._checkOverlap(pos, tryCount)) {
3801
- return this._calcPosition(container, undefined, zIndex, tryCount + 1);
4095
+ const increment = 1;
4096
+ return this._calcPosition(container, undefined, zIndex, tryCount + increment);
3802
4097
  }
3803
4098
  return pos;
3804
4099
  };
@@ -3809,11 +4104,11 @@ class Particle {
3809
4104
  if (moveOptions.direction === "inside" || moveOptions.direction === "outside") {
3810
4105
  return res;
3811
4106
  }
3812
- const rad = Math.PI / 180 * getRangeValue(moveOptions.angle.value),
3813
- radOffset = Math.PI / 180 * getRangeValue(moveOptions.angle.offset),
4107
+ const rad = degToRad(getRangeValue(moveOptions.angle.value)),
4108
+ radOffset = degToRad(getRangeValue(moveOptions.angle.offset)),
3814
4109
  range = {
3815
- left: radOffset - rad * 0.5,
3816
- right: radOffset + rad * 0.5
4110
+ left: radOffset - rad * half,
4111
+ right: radOffset + rad * half
3817
4112
  };
3818
4113
  if (!moveOptions.straight) {
3819
4114
  res.angle += randomInRange(setRangeValue(range.left, range.right));
@@ -3823,7 +4118,7 @@ class Particle {
3823
4118
  }
3824
4119
  return res;
3825
4120
  };
3826
- this._checkOverlap = (pos, tryCount = 0) => {
4121
+ this._checkOverlap = (pos, tryCount = defaultRetryCount) => {
3827
4122
  const collisionsOptions = this.options.collisions,
3828
4123
  radius = this.getRadius();
3829
4124
  if (!collisionsOptions.enable) {
@@ -3833,8 +4128,9 @@ class Particle {
3833
4128
  if (overlapOptions.enable) {
3834
4129
  return false;
3835
4130
  }
3836
- const retries = overlapOptions.retries;
3837
- if (retries >= 0 && tryCount > retries) {
4131
+ const retries = overlapOptions.retries,
4132
+ minRetries = 0;
4133
+ if (retries >= minRetries && tryCount > retries) {
3838
4134
  throw new Error(`${errorPrefix} particle is overlapping and can't be placed`);
3839
4135
  }
3840
4136
  return !!this.container.particles.find(particle => getDistance(pos, particle.position) < radius + particle.getRadius());
@@ -3843,9 +4139,11 @@ class Particle {
3843
4139
  if (!color || !this.roll || !this.backColor && !this.roll.alter) {
3844
4140
  return color;
3845
4141
  }
3846
- const backFactor = this.roll.horizontal && this.roll.vertical ? 2 : 1,
3847
- backSum = this.roll.horizontal ? Math.PI * 0.5 : 0,
3848
- rolled = Math.floor(((this.roll.angle ?? 0) + backSum) / (Math.PI / backFactor)) % 2;
4142
+ const rollFactor = 1,
4143
+ none = 0,
4144
+ backFactor = this.roll.horizontal && this.roll.vertical ? Particle_double * rollFactor : rollFactor,
4145
+ backSum = this.roll.horizontal ? Math.PI * half : none,
4146
+ rolled = Math.floor(((this.roll.angle ?? none) + backSum) / (Math.PI / backFactor)) % Particle_double;
3849
4147
  if (!rolled) {
3850
4148
  return color;
3851
4149
  }
@@ -3859,13 +4157,15 @@ class Particle {
3859
4157
  };
3860
4158
  this._initPosition = position => {
3861
4159
  const container = this.container,
3862
- zIndexValue = getRangeValue(this.options.zIndex.value);
3863
- this.position = this._calcPosition(container, position, clamp(zIndexValue, 0, container.zLayers));
4160
+ zIndexValue = getRangeValue(this.options.zIndex.value),
4161
+ minZ = 0;
4162
+ this.position = this._calcPosition(container, position, clamp(zIndexValue, minZ, container.zLayers));
3864
4163
  this.initialPosition = this.position.copy();
3865
- const canvasSize = container.canvas.size;
4164
+ const canvasSize = container.canvas.size,
4165
+ defaultRadius = 0;
3866
4166
  this.moveCenter = {
3867
4167
  ...getPosition(this.options.move.center, canvasSize),
3868
- radius: this.options.move.center.radius ?? 0,
4168
+ radius: this.options.move.center.radius ?? defaultRadius,
3869
4169
  mode: this.options.move.center.mode ?? "percent"
3870
4170
  };
3871
4171
  this.direction = getParticleDirectionAngle(this.options.move.direction, this.position, this.moveCenter);
@@ -3892,14 +4192,14 @@ class Particle {
3892
4192
  const container = this.container,
3893
4193
  pathGenerator = this.pathGenerator,
3894
4194
  shapeDrawer = container.shapeDrawers.get(this.shape);
3895
- shapeDrawer && shapeDrawer.particleDestroy && shapeDrawer.particleDestroy(this);
4195
+ shapeDrawer?.particleDestroy?.(this);
3896
4196
  for (const [, plugin] of container.plugins) {
3897
- plugin.particleDestroyed && plugin.particleDestroyed(this, override);
4197
+ plugin.particleDestroyed?.(this, override);
3898
4198
  }
3899
4199
  for (const updater of container.particles.updaters) {
3900
- updater.particleDestroyed && updater.particleDestroyed(this, override);
4200
+ updater.particleDestroyed?.(this, override);
3901
4201
  }
3902
- pathGenerator && pathGenerator.reset(this);
4202
+ pathGenerator?.reset(this);
3903
4203
  this._engine.dispatchEvent("particleDestroyed", {
3904
4204
  container: this.container,
3905
4205
  data: {
@@ -3919,7 +4219,7 @@ class Particle {
3919
4219
  return this._getRollColor(this.bubble.color ?? getHslFromAnimation(this.color));
3920
4220
  }
3921
4221
  getMass() {
3922
- return this.getRadius() ** 2 * Math.PI * 0.5;
4222
+ return this.getRadius() ** Particle_squareExp * Math.PI * half;
3923
4223
  }
3924
4224
  getPosition() {
3925
4225
  return {
@@ -3967,7 +4267,7 @@ class Particle {
3967
4267
  const effectOptions = particlesOptions.effect,
3968
4268
  shapeOptions = particlesOptions.shape;
3969
4269
  if (overrideOptions) {
3970
- if (overrideOptions.effect && overrideOptions.effect.type) {
4270
+ if (overrideOptions.effect?.type) {
3971
4271
  const overrideEffectType = overrideOptions.effect.type,
3972
4272
  effect = itemFromSingleOrMultiple(overrideEffectType, this.id, reduceDuplicates);
3973
4273
  if (effect) {
@@ -3975,7 +4275,7 @@ class Particle {
3975
4275
  effectOptions.load(overrideOptions.effect);
3976
4276
  }
3977
4277
  }
3978
- if (overrideOptions.shape && overrideOptions.shape.type) {
4278
+ if (overrideOptions.shape?.type) {
3979
4279
  const overrideShapeType = overrideOptions.shape.type,
3980
4280
  shape = itemFromSingleOrMultiple(overrideShapeType, this.id, reduceDuplicates);
3981
4281
  if (shape) {
@@ -4005,7 +4305,7 @@ class Particle {
4005
4305
  this.shapeClose = shapeData?.close ?? particlesOptions.shape.close;
4006
4306
  this.options = particlesOptions;
4007
4307
  const pathOptions = this.options.move.path;
4008
- this.pathDelay = getRangeValue(pathOptions.delay.value) * 1000;
4308
+ this.pathDelay = getRangeValue(pathOptions.delay.value) * millisecondsToSeconds;
4009
4309
  if (pathOptions.generator) {
4010
4310
  this.pathGenerator = this._engine.getPathGenerator(pathOptions.generator);
4011
4311
  if (this.pathGenerator && container.addPath(pathOptions.generator, this.pathGenerator)) {
@@ -4024,7 +4324,8 @@ class Particle {
4024
4324
  this._initPosition(position);
4025
4325
  this.initialVelocity = this._calculateVelocity();
4026
4326
  this.velocity = this.initialVelocity.copy();
4027
- this.moveDecay = 1 - getRangeValue(this.options.move.decay);
4327
+ const decayOffset = 1;
4328
+ this.moveDecay = decayOffset - getRangeValue(this.options.move.decay);
4028
4329
  const particles = container.particles;
4029
4330
  particles.setLastZIndex(this.position.z);
4030
4331
  this.zIndexFactor = this.position.z / container.zLayers;
@@ -4036,7 +4337,7 @@ class Particle {
4036
4337
  container.effectDrawers.set(this.effect, effectDrawer);
4037
4338
  }
4038
4339
  }
4039
- if (effectDrawer && effectDrawer.loadEffect) {
4340
+ if (effectDrawer?.loadEffect) {
4040
4341
  effectDrawer.loadEffect(this);
4041
4342
  }
4042
4343
  let shapeDrawer = container.shapeDrawers.get(this.shape);
@@ -4046,7 +4347,7 @@ class Particle {
4046
4347
  container.shapeDrawers.set(this.shape, shapeDrawer);
4047
4348
  }
4048
4349
  }
4049
- if (shapeDrawer && shapeDrawer.loadShape) {
4350
+ if (shapeDrawer?.loadShape) {
4050
4351
  shapeDrawer.loadShape(this);
4051
4352
  }
4052
4353
  const sideCountFunc = shapeDrawer?.getSidesCount;
@@ -4059,16 +4360,12 @@ class Particle {
4059
4360
  updater.init(this);
4060
4361
  }
4061
4362
  for (const mover of particles.movers) {
4062
- mover.init && mover.init(this);
4063
- }
4064
- if (effectDrawer && effectDrawer.particleInit) {
4065
- effectDrawer.particleInit(container, this);
4066
- }
4067
- if (shapeDrawer && shapeDrawer.particleInit) {
4068
- shapeDrawer.particleInit(container, this);
4363
+ mover.init?.(this);
4069
4364
  }
4365
+ effectDrawer?.particleInit?.(container, this);
4366
+ shapeDrawer?.particleInit?.(container, this);
4070
4367
  for (const [, plugin] of container.plugins) {
4071
- plugin.particleCreated && plugin.particleCreated(this);
4368
+ plugin.particleCreated?.(this);
4072
4369
  }
4073
4370
  }
4074
4371
  isInsideCanvas() {
@@ -4082,7 +4379,7 @@ class Particle {
4082
4379
  }
4083
4380
  reset() {
4084
4381
  for (const updater of this.container.particles.updaters) {
4085
- updater.reset && updater.reset(this);
4382
+ updater.reset?.(this);
4086
4383
  }
4087
4384
  }
4088
4385
  }
@@ -4140,6 +4437,7 @@ class Rectangle extends Range {
4140
4437
 
4141
4438
 
4142
4439
 
4440
+ const Circle_squareExp = 2;
4143
4441
  class Circle extends Range {
4144
4442
  constructor(x, y, radius) {
4145
4443
  super(x, y);
@@ -4158,15 +4456,15 @@ class Circle extends Range {
4158
4456
  r = this.radius;
4159
4457
  if (range instanceof Circle) {
4160
4458
  const rSum = r + range.radius,
4161
- dist = Math.sqrt(distPos.x ** 2 + distPos.y ** 2);
4459
+ dist = Math.sqrt(distPos.x ** Circle_squareExp + distPos.y ** Circle_squareExp);
4162
4460
  return rSum > dist;
4163
4461
  } else if (range instanceof Rectangle) {
4164
4462
  const {
4165
4463
  width,
4166
4464
  height
4167
4465
  } = range.size,
4168
- edges = Math.pow(distPos.x - width, 2) + Math.pow(distPos.y - height, 2);
4169
- return edges <= r ** 2 || distPos.x <= r + width && distPos.y <= r + height || distPos.x <= width || distPos.y <= height;
4466
+ edges = Math.pow(distPos.x - width, Circle_squareExp) + Math.pow(distPos.y - height, Circle_squareExp);
4467
+ return edges <= r ** Circle_squareExp || distPos.x <= r + width && distPos.y <= r + height || distPos.x <= width || distPos.y <= height;
4170
4468
  }
4171
4469
  return false;
4172
4470
  }
@@ -4175,6 +4473,9 @@ class Circle extends Range {
4175
4473
 
4176
4474
 
4177
4475
 
4476
+ const QuadTree_half = 0.5,
4477
+ QuadTree_double = 2,
4478
+ subdivideCount = 4;
4178
4479
  class QuadTree {
4179
4480
  constructor(rectangle, capacity) {
4180
4481
  this.rectangle = rectangle;
@@ -4191,8 +4492,9 @@ class QuadTree {
4191
4492
  {
4192
4493
  capacity
4193
4494
  } = this;
4194
- for (let i = 0; i < 4; i++) {
4195
- this._subs.push(new QuadTree(new Rectangle(x + width * 0.5 * (i % 2), y + height * 0.5 * (Math.round(i * 0.5) - i % 2), width * 0.5, height * 0.5), capacity));
4495
+ for (let i = 0; i < subdivideCount; i++) {
4496
+ const fixedIndex = i % QuadTree_double;
4497
+ this._subs.push(new QuadTree(new Rectangle(x + width * QuadTree_half * fixedIndex, y + height * QuadTree_half * (Math.round(i * QuadTree_half) - fixedIndex), width * QuadTree_half, height * QuadTree_half), capacity));
4196
4498
  }
4197
4499
  this._divided = true;
4198
4500
  };
@@ -4214,7 +4516,7 @@ class QuadTree {
4214
4516
  return this._subs.some(sub => sub.insert(point));
4215
4517
  }
4216
4518
  query(range, check, found) {
4217
- const res = found || [];
4519
+ const res = found ?? [];
4218
4520
  if (!range.intersects(this.rectangle)) {
4219
4521
  return [];
4220
4522
  }
@@ -4246,7 +4548,9 @@ class QuadTree {
4246
4548
 
4247
4549
 
4248
4550
 
4249
- const qTreeCapacity = 4;
4551
+ const qTreeCapacity = 4,
4552
+ Particles_squareExp = 2,
4553
+ defaultRemoveQuantity = 1;
4250
4554
  const qTreeRectangle = canvasSize => {
4251
4555
  const {
4252
4556
  height,
@@ -4275,7 +4579,8 @@ class Particles {
4275
4579
  }
4276
4580
  const densityFactor = this._initDensityFactor(numberOptions.density),
4277
4581
  optParticlesNumber = numberOptions.value,
4278
- optParticlesLimit = numberOptions.limit.value > 0 ? numberOptions.limit.value : optParticlesNumber,
4582
+ minLimit = 0,
4583
+ optParticlesLimit = numberOptions.limit.value > minLimit ? numberOptions.limit.value : optParticlesNumber,
4279
4584
  particlesNumber = Math.min(optParticlesNumber, optParticlesLimit) * densityFactor + manualCount,
4280
4585
  particlesCount = Math.min(this.count, this.filter(t => t.group === group).length);
4281
4586
  if (group === undefined) {
@@ -4290,13 +4595,14 @@ class Particles {
4290
4595
  }
4291
4596
  };
4292
4597
  this._initDensityFactor = densityOptions => {
4293
- const container = this._container;
4598
+ const container = this._container,
4599
+ defaultFactor = 1;
4294
4600
  if (!container.canvas.element || !densityOptions.enable) {
4295
- return 1;
4601
+ return defaultFactor;
4296
4602
  }
4297
4603
  const canvas = container.canvas.element,
4298
4604
  pxRatio = container.retina.pixelRatio;
4299
- return canvas.width * canvas.height / (densityOptions.height * densityOptions.width * pxRatio ** 2);
4605
+ return canvas.width * canvas.height / (densityOptions.height * densityOptions.width * pxRatio ** Particles_squareExp);
4300
4606
  };
4301
4607
  this._pushParticle = (position, overrideOptions, group, initializer) => {
4302
4608
  try {
@@ -4325,7 +4631,6 @@ class Particles {
4325
4631
  return particle;
4326
4632
  } catch (e) {
4327
4633
  getLogger().warning(`${errorPrefix} adding particle: ${e}`);
4328
- return;
4329
4634
  }
4330
4635
  };
4331
4636
  this._removeParticle = (index, group, override) => {
@@ -4333,9 +4638,10 @@ class Particles {
4333
4638
  if (!particle || particle.group !== group) {
4334
4639
  return false;
4335
4640
  }
4336
- const zIdx = this._zArray.indexOf(particle);
4337
- this._array.splice(index, 1);
4338
- this._zArray.splice(zIdx, 1);
4641
+ const zIdx = this._zArray.indexOf(particle),
4642
+ deleteCount = 1;
4643
+ this._array.splice(index, deleteCount);
4644
+ this._zArray.splice(zIdx, deleteCount);
4339
4645
  particle.destroy(override);
4340
4646
  this._engine.dispatchEvent("particleRemoved", {
4341
4647
  container: this._container,
@@ -4375,11 +4681,14 @@ class Particles {
4375
4681
  addParticle(position, overrideOptions, group, initializer) {
4376
4682
  const limitOptions = this._container.actualOptions.particles.number.limit,
4377
4683
  limit = group === undefined ? this._limit : this._groupLimits.get(group) ?? this._limit,
4378
- currentCount = this.count;
4379
- if (limit > 0) {
4684
+ currentCount = this.count,
4685
+ minLimit = 0;
4686
+ if (limit > minLimit) {
4380
4687
  if (limitOptions.mode === "delete") {
4381
- const countToRemove = currentCount + 1 - limit;
4382
- if (countToRemove > 0) {
4688
+ const countOffset = 1,
4689
+ minCount = 0,
4690
+ countToRemove = currentCount + countOffset - limit;
4691
+ if (countToRemove > minCount) {
4383
4692
  this.removeQuantity(countToRemove);
4384
4693
  }
4385
4694
  } else if (limitOptions.mode === "wait") {
@@ -4475,23 +4784,28 @@ class Particles {
4475
4784
  remove(particle, group, override) {
4476
4785
  this.removeAt(this._array.indexOf(particle), undefined, group, override);
4477
4786
  }
4478
- removeAt(index, quantity = 1, group, override) {
4479
- if (index < 0 || index > this.count) {
4787
+ removeAt(index, quantity = defaultRemoveQuantity, group, override) {
4788
+ const minIndex = 0;
4789
+ if (index < minIndex || index > this.count) {
4480
4790
  return;
4481
4791
  }
4482
4792
  let deleted = 0;
4483
4793
  for (let i = index; deleted < quantity && i < this.count; i++) {
4484
- this._removeParticle(i--, group, override) && deleted++;
4794
+ if (this._removeParticle(i--, group, override)) {
4795
+ deleted++;
4796
+ }
4485
4797
  }
4486
4798
  }
4487
4799
  removeQuantity(quantity, group) {
4488
- this.removeAt(0, quantity, group);
4800
+ const defaultIndex = 0;
4801
+ this.removeAt(defaultIndex, quantity, group);
4489
4802
  }
4490
4803
  setDensity() {
4491
4804
  const options = this._container.actualOptions,
4492
- groups = options.particles.groups;
4805
+ groups = options.particles.groups,
4806
+ manualCount = 0;
4493
4807
  for (const group in groups) {
4494
- this._applyDensity(groups[group], 0, group);
4808
+ this._applyDensity(groups[group], manualCount, group);
4495
4809
  }
4496
4810
  this._applyDensity(options.particles, options.manualParticles.length);
4497
4811
  }
@@ -4510,7 +4824,7 @@ class Particles {
4510
4824
  pathGenerator.update();
4511
4825
  }
4512
4826
  for (const [, plugin] of container.plugins) {
4513
- plugin.update && (await plugin.update(delta));
4827
+ await plugin.update?.(delta);
4514
4828
  }
4515
4829
  const resizeFactor = this._resizeFactor;
4516
4830
  for (const particle of this._array) {
@@ -4521,15 +4835,17 @@ class Particles {
4521
4835
  particle.initialPosition.y *= resizeFactor.height;
4522
4836
  }
4523
4837
  particle.ignoresResizeRatio = false;
4524
- await this._interactionManager.reset(particle);
4838
+ this._interactionManager.reset(particle);
4525
4839
  for (const [, plugin] of this._container.plugins) {
4526
4840
  if (particle.destroyed) {
4527
4841
  break;
4528
4842
  }
4529
- plugin.particleUpdate && plugin.particleUpdate(particle, delta);
4843
+ plugin.particleUpdate?.(particle, delta);
4530
4844
  }
4531
4845
  for (const mover of this.movers) {
4532
- mover.isEnabled(particle) && mover.move(particle, delta);
4846
+ if (mover.isEnabled(particle)) {
4847
+ mover.move(particle, delta);
4848
+ }
4533
4849
  }
4534
4850
  if (particle.destroyed) {
4535
4851
  particlesToDelete.add(particle);
@@ -4564,7 +4880,8 @@ class Particles {
4564
4880
  if (this._needsSort) {
4565
4881
  const zArray = this._zArray;
4566
4882
  zArray.sort((a, b) => b.position.z - a.position.z || a.id - b.id);
4567
- this._lastZIndex = zArray[zArray.length - 1].position.z;
4883
+ const lengthOffset = 1;
4884
+ this._lastZIndex = zArray[zArray.length - lengthOffset].position.z;
4568
4885
  this._needsSort = false;
4569
4886
  }
4570
4887
  }
@@ -4572,17 +4889,19 @@ class Particles {
4572
4889
  ;// CONCATENATED MODULE: ../../engine/dist/browser/Core/Retina.js
4573
4890
 
4574
4891
 
4892
+ const defaultRatio = 1,
4893
+ defaultReduceFactor = 1;
4575
4894
  class Retina {
4576
4895
  constructor(container) {
4577
4896
  this.container = container;
4578
- this.pixelRatio = 1;
4579
- this.reduceFactor = 1;
4897
+ this.pixelRatio = defaultRatio;
4898
+ this.reduceFactor = defaultReduceFactor;
4580
4899
  }
4581
4900
  init() {
4582
4901
  const container = this.container,
4583
4902
  options = container.actualOptions;
4584
- this.pixelRatio = !options.detectRetina || isSsr() ? 1 : window.devicePixelRatio;
4585
- this.reduceFactor = 1;
4903
+ this.pixelRatio = !options.detectRetina || isSsr() ? defaultRatio : window.devicePixelRatio;
4904
+ this.reduceFactor = defaultReduceFactor;
4586
4905
  const ratio = this.pixelRatio,
4587
4906
  canvas = container.canvas;
4588
4907
  if (canvas.element) {
@@ -4623,10 +4942,11 @@ class Retina {
4623
4942
  function guardCheck(container) {
4624
4943
  return container && !container.destroyed;
4625
4944
  }
4626
- function initDelta(value, fpsLimit = 60, smooth = false) {
4945
+ const defaultFps = 60;
4946
+ function initDelta(value, fpsLimit = defaultFps, smooth = false) {
4627
4947
  return {
4628
4948
  value,
4629
- factor: smooth ? 60 / fpsLimit : 60 * value / 1000
4949
+ factor: smooth ? defaultFps / fpsLimit : defaultFps * value / millisecondsToSeconds
4630
4950
  };
4631
4951
  }
4632
4952
  function loadContainerOptions(engine, container, ...sourceOptionsArr) {
@@ -4644,12 +4964,16 @@ class Container {
4644
4964
  if (entry.target !== this.interactivity.element) {
4645
4965
  continue;
4646
4966
  }
4647
- (entry.isIntersecting ? this.play : this.pause)();
4967
+ if (entry.isIntersecting) {
4968
+ this.play();
4969
+ } else {
4970
+ this.pause();
4971
+ }
4648
4972
  }
4649
4973
  };
4650
4974
  this._nextFrame = async timestamp => {
4651
4975
  try {
4652
- if (!this._smooth && this._lastFrameTime !== undefined && timestamp < this._lastFrameTime + 1000 / this.fpsLimit) {
4976
+ if (!this._smooth && this._lastFrameTime !== undefined && timestamp < this._lastFrameTime + millisecondsToSeconds / this.fpsLimit) {
4653
4977
  this.draw(false);
4654
4978
  return;
4655
4979
  }
@@ -4657,7 +4981,7 @@ class Container {
4657
4981
  const delta = initDelta(timestamp - this._lastFrameTime, this.fpsLimit, this._smooth);
4658
4982
  this.addLifeTime(delta.value);
4659
4983
  this._lastFrameTime = timestamp;
4660
- if (delta.value > 1000) {
4984
+ if (delta.value > millisecondsToSeconds) {
4661
4985
  this.draw(false);
4662
4986
  return;
4663
4987
  }
@@ -4744,8 +5068,9 @@ class Container {
4744
5068
  pos = {
4745
5069
  x: mouseEvent.offsetX || mouseEvent.clientX,
4746
5070
  y: mouseEvent.offsetY || mouseEvent.clientY
4747
- };
4748
- clickOrTouchHandler(e, pos, 1);
5071
+ },
5072
+ radius = 1;
5073
+ clickOrTouchHandler(e, pos, radius);
4749
5074
  };
4750
5075
  const touchStartHandler = () => {
4751
5076
  if (!guardCheck(this)) {
@@ -4766,18 +5091,20 @@ class Container {
4766
5091
  }
4767
5092
  if (touched && !touchMoved) {
4768
5093
  const touchEvent = e;
4769
- let lastTouch = touchEvent.touches[touchEvent.touches.length - 1];
5094
+ const lengthOffset = 1;
5095
+ let lastTouch = touchEvent.touches[touchEvent.touches.length - lengthOffset];
4770
5096
  if (!lastTouch) {
4771
- lastTouch = touchEvent.changedTouches[touchEvent.changedTouches.length - 1];
5097
+ lastTouch = touchEvent.changedTouches[touchEvent.changedTouches.length - lengthOffset];
4772
5098
  if (!lastTouch) {
4773
5099
  return;
4774
5100
  }
4775
5101
  }
4776
5102
  const element = this.canvas.element,
4777
5103
  canvasRect = element ? element.getBoundingClientRect() : undefined,
5104
+ minCoordinate = 0,
4778
5105
  pos = {
4779
- x: lastTouch.clientX - (canvasRect ? canvasRect.left : 0),
4780
- y: lastTouch.clientY - (canvasRect ? canvasRect.top : 0)
5106
+ x: lastTouch.clientX - (canvasRect ? canvasRect.left : minCoordinate),
5107
+ y: lastTouch.clientY - (canvasRect ? canvasRect.top : minCoordinate)
4781
5108
  };
4782
5109
  clickOrTouchHandler(e, pos, Math.max(lastTouch.radiusX, lastTouch.radiusY));
4783
5110
  }
@@ -4820,10 +5147,10 @@ class Container {
4820
5147
  this.particles.destroy();
4821
5148
  this.canvas.destroy();
4822
5149
  for (const [, effectDrawer] of this.effectDrawers) {
4823
- effectDrawer.destroy && effectDrawer.destroy(this);
5150
+ effectDrawer.destroy?.(this);
4824
5151
  }
4825
5152
  for (const [, shapeDrawer] of this.shapeDrawers) {
4826
- shapeDrawer.destroy && shapeDrawer.destroy(this);
5153
+ shapeDrawer.destroy?.(this);
4827
5154
  }
4828
5155
  for (const key of this.effectDrawers.keys()) {
4829
5156
  this.effectDrawers.delete(key);
@@ -4834,9 +5161,11 @@ class Container {
4834
5161
  this._engine.clearPlugins(this);
4835
5162
  this.destroyed = true;
4836
5163
  const mainArr = this._engine.dom(),
4837
- idx = mainArr.findIndex(t => t === this);
4838
- if (idx >= 0) {
4839
- mainArr.splice(idx, 1);
5164
+ idx = mainArr.findIndex(t => t === this),
5165
+ minIndex = 0;
5166
+ if (idx >= minIndex) {
5167
+ const deleteCount = 1;
5168
+ mainArr.splice(idx, deleteCount);
4840
5169
  }
4841
5170
  this._engine.dispatchEvent("containerDestroyed", {
4842
5171
  container: this
@@ -4847,13 +5176,14 @@ class Container {
4847
5176
  return;
4848
5177
  }
4849
5178
  let refreshTime = force;
4850
- this._drawAnimationFrame = requestAnimationFrame(async timestamp => {
5179
+ const frame = async timestamp => {
4851
5180
  if (refreshTime) {
4852
5181
  this._lastFrameTime = undefined;
4853
5182
  refreshTime = false;
4854
5183
  }
4855
5184
  await this._nextFrame(timestamp);
4856
- });
5185
+ };
5186
+ this._drawAnimationFrame = requestAnimationFrame(timestamp => void frame(timestamp));
4857
5187
  }
4858
5188
  async export(type, options = {}) {
4859
5189
  for (const [, plugin] of this.plugins) {
@@ -4877,7 +5207,7 @@ class Container {
4877
5207
  }
4878
5208
  this.particles.handleClickMode(mode);
4879
5209
  for (const [, plugin] of this.plugins) {
4880
- plugin.handleClickMode && plugin.handleClickMode(mode);
5210
+ plugin.handleClickMode?.(mode);
4881
5211
  }
4882
5212
  }
4883
5213
  async init() {
@@ -4910,19 +5240,21 @@ class Container {
4910
5240
  this.canvas.initBackground();
4911
5241
  this.canvas.resize();
4912
5242
  this.zLayers = this.actualOptions.zLayers;
4913
- this._duration = getRangeValue(this.actualOptions.duration) * 1000;
4914
- this._delay = getRangeValue(this.actualOptions.delay) * 1000;
5243
+ this._duration = getRangeValue(this.actualOptions.duration) * millisecondsToSeconds;
5244
+ this._delay = getRangeValue(this.actualOptions.delay) * millisecondsToSeconds;
4915
5245
  this._lifeTime = 0;
4916
- this.fpsLimit = this.actualOptions.fpsLimit > 0 ? this.actualOptions.fpsLimit : 120;
5246
+ const defaultFpsLimit = 120,
5247
+ minFpsLimit = 0;
5248
+ this.fpsLimit = this.actualOptions.fpsLimit > minFpsLimit ? this.actualOptions.fpsLimit : defaultFpsLimit;
4917
5249
  this._smooth = this.actualOptions.smooth;
4918
5250
  for (const [, drawer] of this.effectDrawers) {
4919
- drawer.init && (await drawer.init(this));
5251
+ await drawer.init?.(this);
4920
5252
  }
4921
5253
  for (const [, drawer] of this.shapeDrawers) {
4922
- drawer.init && (await drawer.init(this));
5254
+ await drawer.init?.(this);
4923
5255
  }
4924
5256
  for (const [, plugin] of this.plugins) {
4925
- plugin.init && (await plugin.init());
5257
+ await plugin.init?.();
4926
5258
  }
4927
5259
  this._engine.dispatchEvent("containerInit", {
4928
5260
  container: this
@@ -4930,7 +5262,7 @@ class Container {
4930
5262
  this.particles.init();
4931
5263
  this.particles.setDensity();
4932
5264
  for (const [, plugin] of this.plugins) {
4933
- plugin.particlesSetup && plugin.particlesSetup();
5265
+ plugin.particlesSetup?.();
4934
5266
  }
4935
5267
  this._engine.dispatchEvent("particlesSetup", {
4936
5268
  container: this
@@ -4955,7 +5287,7 @@ class Container {
4955
5287
  return;
4956
5288
  }
4957
5289
  for (const [, plugin] of this.plugins) {
4958
- plugin.pause && plugin.pause();
5290
+ plugin.pause?.();
4959
5291
  }
4960
5292
  if (!this.pageHidden) {
4961
5293
  this._paused = true;
@@ -4986,7 +5318,7 @@ class Container {
4986
5318
  this._engine.dispatchEvent("containerPlay", {
4987
5319
  container: this
4988
5320
  });
4989
- this.draw(needsUpdate || false);
5321
+ this.draw(needsUpdate ?? false);
4990
5322
  }
4991
5323
  async refresh() {
4992
5324
  if (!guardCheck(this)) {
@@ -5011,20 +5343,21 @@ class Container {
5011
5343
  await this.init();
5012
5344
  this.started = true;
5013
5345
  await new Promise(resolve => {
5014
- this._delayTimeout = setTimeout(async () => {
5346
+ const start = async () => {
5015
5347
  this._eventListeners.addListeners();
5016
5348
  if (this.interactivity.element instanceof HTMLElement && this._intersectionObserver) {
5017
5349
  this._intersectionObserver.observe(this.interactivity.element);
5018
5350
  }
5019
5351
  for (const [, plugin] of this.plugins) {
5020
- plugin.start && (await plugin.start());
5352
+ await plugin.start?.();
5021
5353
  }
5022
5354
  this._engine.dispatchEvent("containerStarted", {
5023
5355
  container: this
5024
5356
  });
5025
5357
  this.play();
5026
5358
  resolve();
5027
- }, this._delay);
5359
+ };
5360
+ this._delayTimeout = setTimeout(() => void start(), this._delay);
5028
5361
  });
5029
5362
  }
5030
5363
  stop() {
@@ -5045,7 +5378,7 @@ class Container {
5045
5378
  this._intersectionObserver.unobserve(this.interactivity.element);
5046
5379
  }
5047
5380
  for (const [, plugin] of this.plugins) {
5048
- plugin.stop && plugin.stop();
5381
+ plugin.stop?.();
5049
5382
  }
5050
5383
  for (const key of this.plugins.keys()) {
5051
5384
  this.plugins.delete(key);
@@ -5082,7 +5415,7 @@ class EventDispatcher {
5082
5415
  }
5083
5416
  dispatchEvent(type, args) {
5084
5417
  const listeners = this._listeners.get(type);
5085
- listeners && listeners.forEach(handler => handler(args));
5418
+ listeners?.forEach(handler => handler(args));
5086
5419
  }
5087
5420
  hasEventListener(type) {
5088
5421
  return !!this._listeners.get(type);
@@ -5100,14 +5433,16 @@ class EventDispatcher {
5100
5433
  return;
5101
5434
  }
5102
5435
  const length = arr.length,
5103
- idx = arr.indexOf(listener);
5104
- if (idx < 0) {
5436
+ idx = arr.indexOf(listener),
5437
+ minIndex = 0;
5438
+ if (idx < minIndex) {
5105
5439
  return;
5106
5440
  }
5107
- if (length === 1) {
5441
+ const deleteCount = 1;
5442
+ if (length === deleteCount) {
5108
5443
  this._listeners.delete(type);
5109
5444
  } else {
5110
- arr.splice(idx, 1);
5445
+ arr.splice(idx, deleteCount);
5111
5446
  }
5112
5447
  }
5113
5448
  }
@@ -5165,21 +5500,23 @@ class Engine {
5165
5500
  return res;
5166
5501
  }
5167
5502
  get version() {
5168
- return "3.0.2";
5503
+ return "3.1.0";
5169
5504
  }
5170
5505
  addConfig(config) {
5171
- const name = config.name ?? "default";
5172
- this._configs.set(name, config);
5506
+ const key = config.key ?? config.name ?? "default";
5507
+ this._configs.set(key, config);
5173
5508
  this._eventDispatcher.dispatchEvent("configAdded", {
5174
5509
  data: {
5175
- name,
5510
+ name: key,
5176
5511
  config
5177
5512
  }
5178
5513
  });
5179
5514
  }
5180
5515
  async addEffect(effect, drawer, refresh = true) {
5181
5516
  executeOnSingleOrMultiple(effect, type => {
5182
- !this.getEffectDrawer(type) && this.effectDrawers.set(type, drawer);
5517
+ if (!this.getEffectDrawer(type)) {
5518
+ this.effectDrawers.set(type, drawer);
5519
+ }
5183
5520
  });
5184
5521
  await this.refresh(refresh);
5185
5522
  }
@@ -5199,20 +5536,28 @@ class Engine {
5199
5536
  await this.refresh(refresh);
5200
5537
  }
5201
5538
  async addPathGenerator(name, generator, refresh = true) {
5202
- !this.getPathGenerator(name) && this.pathGenerators.set(name, generator);
5539
+ if (!this.getPathGenerator(name)) {
5540
+ this.pathGenerators.set(name, generator);
5541
+ }
5203
5542
  await this.refresh(refresh);
5204
5543
  }
5205
5544
  async addPlugin(plugin, refresh = true) {
5206
- !this.getPlugin(plugin.id) && this.plugins.push(plugin);
5545
+ if (!this.getPlugin(plugin.id)) {
5546
+ this.plugins.push(plugin);
5547
+ }
5207
5548
  await this.refresh(refresh);
5208
5549
  }
5209
5550
  async addPreset(preset, options, override = false, refresh = true) {
5210
- (override || !this.getPreset(preset)) && this.presets.set(preset, options);
5551
+ if (override || !this.getPreset(preset)) {
5552
+ this.presets.set(preset, options);
5553
+ }
5211
5554
  await this.refresh(refresh);
5212
5555
  }
5213
5556
  async addShape(shape, drawer, refresh = true) {
5214
5557
  executeOnSingleOrMultiple(shape, type => {
5215
- !this.getShapeDrawer(type) && this.shapeDrawers.set(type, drawer);
5558
+ if (!this.getShapeDrawer(type)) {
5559
+ this.shapeDrawers.set(type, drawer);
5560
+ }
5216
5561
  });
5217
5562
  await this.refresh(refresh);
5218
5563
  }
@@ -5231,7 +5576,8 @@ class Engine {
5231
5576
  const dom = this.dom(),
5232
5577
  item = dom[index];
5233
5578
  if (!item || item.destroyed) {
5234
- dom.splice(index, 1);
5579
+ const deleteCount = 1;
5580
+ dom.splice(index, deleteCount);
5235
5581
  return;
5236
5582
  }
5237
5583
  return item;
@@ -5239,7 +5585,9 @@ class Engine {
5239
5585
  getAvailablePlugins(container) {
5240
5586
  const res = new Map();
5241
5587
  for (const plugin of this.plugins) {
5242
- plugin.needsPlugin(container.actualOptions) && res.set(plugin.id, plugin.getPlugin(container));
5588
+ if (plugin.needsPlugin(container.actualOptions)) {
5589
+ res.set(plugin.id, plugin.getPlugin(container));
5590
+ }
5243
5591
  }
5244
5592
  return res;
5245
5593
  }
@@ -5280,7 +5628,8 @@ class Engine {
5280
5628
  this._initialized = true;
5281
5629
  }
5282
5630
  async load(params) {
5283
- const id = params.id ?? `tsparticles${Math.floor(getRandom() * 10000)}`,
5631
+ const randomFactor = 10000,
5632
+ id = params.id ?? params.element?.id ?? `tsparticles${Math.floor(getRandom() * randomFactor)}`,
5284
5633
  {
5285
5634
  index,
5286
5635
  url
@@ -5298,12 +5647,14 @@ class Engine {
5298
5647
  }
5299
5648
  const currentOptions = itemFromSingleOrMultiple(options, index),
5300
5649
  dom = this.dom(),
5301
- oldIndex = dom.findIndex(v => v.id.description === id);
5302
- if (oldIndex >= 0) {
5650
+ oldIndex = dom.findIndex(v => v.id.description === id),
5651
+ minIndex = 0;
5652
+ if (oldIndex >= minIndex) {
5303
5653
  const old = this.domItem(oldIndex);
5304
5654
  if (old && !old.destroyed) {
5305
5655
  old.destroy();
5306
- dom.splice(oldIndex, 1);
5656
+ const deleteCount = 1;
5657
+ dom.splice(oldIndex, deleteCount);
5307
5658
  }
5308
5659
  }
5309
5660
  let canvasEl;
@@ -5313,7 +5664,8 @@ class Engine {
5313
5664
  } else {
5314
5665
  const existingCanvases = domContainer.getElementsByTagName("canvas");
5315
5666
  if (existingCanvases.length) {
5316
- canvasEl = existingCanvases[0];
5667
+ const firstIndex = 0;
5668
+ canvasEl = existingCanvases[firstIndex];
5317
5669
  canvasEl.dataset[generatedAttribute] = "false";
5318
5670
  } else {
5319
5671
  canvasEl = document.createElement("canvas");
@@ -5328,8 +5680,9 @@ class Engine {
5328
5680
  canvasEl.style.height = "100%";
5329
5681
  }
5330
5682
  const newItem = new Container(this, id, currentOptions);
5331
- if (oldIndex >= 0) {
5332
- dom.splice(oldIndex, 0, newItem);
5683
+ if (oldIndex >= minIndex) {
5684
+ const deleteCount = 0;
5685
+ dom.splice(oldIndex, deleteCount, newItem);
5333
5686
  } else {
5334
5687
  dom.push(newItem);
5335
5688
  }
@@ -5348,14 +5701,14 @@ class Engine {
5348
5701
  return;
5349
5702
  }
5350
5703
  for (const updater of updaters) {
5351
- updater.loadOptions && updater.loadOptions(options, ...sourceOptions);
5704
+ updater.loadOptions?.(options, ...sourceOptions);
5352
5705
  }
5353
5706
  }
5354
5707
  async refresh(refresh = true) {
5355
5708
  if (!refresh) {
5356
5709
  return;
5357
5710
  }
5358
- this.dom().forEach(t => t.refresh());
5711
+ await Promise.allSettled(this.dom().map(t => t.refresh()));
5359
5712
  }
5360
5713
  removeEventListener(type, listener) {
5361
5714
  this._eventDispatcher.removeEventListener(type, listener);
@@ -5401,12 +5754,15 @@ class HslColorManager {
5401
5754
  return;
5402
5755
  }
5403
5756
  const regex = /hsla?\(\s*(\d+)\s*,\s*(\d+)%\s*,\s*(\d+)%\s*(,\s*([\d.%]+)\s*)?\)/i,
5404
- result = regex.exec(input);
5757
+ result = regex.exec(input),
5758
+ minLength = 4,
5759
+ defaultAlpha = 1,
5760
+ radix = 10;
5405
5761
  return result ? hslaToRgba({
5406
- a: result.length > 4 ? parseAlpha(result[5]) : 1,
5407
- h: parseInt(result[1], 10),
5408
- l: parseInt(result[3], 10),
5409
- s: parseInt(result[2], 10)
5762
+ a: result.length > minLength ? parseAlpha(result[5]) : defaultAlpha,
5763
+ h: parseInt(result[1], radix),
5764
+ l: parseInt(result[3], radix),
5765
+ s: parseInt(result[2], radix)
5410
5766
  }) : undefined;
5411
5767
  }
5412
5768
  }
@@ -5440,12 +5796,15 @@ class RgbColorManager {
5440
5796
  return;
5441
5797
  }
5442
5798
  const regex = /rgba?\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*(,\s*([\d.%]+)\s*)?\)/i,
5443
- result = regex.exec(input);
5799
+ result = regex.exec(input),
5800
+ radix = 10,
5801
+ minLength = 4,
5802
+ defaultAlpha = 1;
5444
5803
  return result ? {
5445
- a: result.length > 4 ? parseAlpha(result[5]) : 1,
5446
- b: parseInt(result[3], 10),
5447
- g: parseInt(result[2], 10),
5448
- r: parseInt(result[1], 10)
5804
+ a: result.length > minLength ? parseAlpha(result[5]) : defaultAlpha,
5805
+ b: parseInt(result[3], radix),
5806
+ g: parseInt(result[2], radix),
5807
+ r: parseInt(result[1], radix)
5449
5808
  } : undefined;
5450
5809
  }
5451
5810
  }
@@ -5466,15 +5825,15 @@ function init() {
5466
5825
  ;// CONCATENATED MODULE: ../../engine/dist/browser/Core/Utils/ExternalInteractorBase.js
5467
5826
  class ExternalInteractorBase {
5468
5827
  constructor(container) {
5469
- this.container = container;
5470
5828
  this.type = "external";
5829
+ this.container = container;
5471
5830
  }
5472
5831
  }
5473
5832
  ;// CONCATENATED MODULE: ../../engine/dist/browser/Core/Utils/ParticlesInteractorBase.js
5474
5833
  class ParticlesInteractorBase {
5475
5834
  constructor(container) {
5476
- this.container = container;
5477
5835
  this.type = "particles";
5836
+ this.container = container;
5478
5837
  }
5479
5838
  }
5480
5839
  ;// CONCATENATED MODULE: ../../engine/dist/browser/exports.js
@@ -5578,6 +5937,12 @@ if (!isSsr()) {
5578
5937
 
5579
5938
  ;// CONCATENATED MODULE: ../../move/base/dist/browser/Utils.js
5580
5939
 
5940
+ const Utils_half = 0.5,
5941
+ minVelocity = 0,
5942
+ identity = 1,
5943
+ moveSpeedFactor = 60,
5944
+ minSpinRadius = 0,
5945
+ spinFactor = 0.01;
5581
5946
  function applyDistance(particle) {
5582
5947
  const initialPosition = particle.initialPosition,
5583
5948
  {
@@ -5594,23 +5959,25 @@ function applyDistance(particle) {
5594
5959
  if (!hDistance && !vDistance) {
5595
5960
  return;
5596
5961
  }
5597
- if ((hDistance && dxFixed >= hDistance || vDistance && dyFixed >= vDistance) && !particle.misplaced) {
5962
+ const hasHDistance = (hDistance && dxFixed >= hDistance) ?? false,
5963
+ hasVDistance = (vDistance && dyFixed >= vDistance) ?? false;
5964
+ if ((hasHDistance || hasVDistance) && !particle.misplaced) {
5598
5965
  particle.misplaced = !!hDistance && dxFixed > hDistance || !!vDistance && dyFixed > vDistance;
5599
5966
  if (hDistance) {
5600
- particle.velocity.x = particle.velocity.y * 0.5 - particle.velocity.x;
5967
+ particle.velocity.x = particle.velocity.y * Utils_half - particle.velocity.x;
5601
5968
  }
5602
5969
  if (vDistance) {
5603
- particle.velocity.y = particle.velocity.x * 0.5 - particle.velocity.y;
5970
+ particle.velocity.y = particle.velocity.x * Utils_half - particle.velocity.y;
5604
5971
  }
5605
5972
  } else if ((!hDistance || dxFixed < hDistance) && (!vDistance || dyFixed < vDistance) && particle.misplaced) {
5606
5973
  particle.misplaced = false;
5607
5974
  } else if (particle.misplaced) {
5608
5975
  const pos = particle.position,
5609
5976
  vel = particle.velocity;
5610
- if (hDistance && (pos.x < initialPosition.x && vel.x < 0 || pos.x > initialPosition.x && vel.x > 0)) {
5977
+ if (hDistance && (pos.x < initialPosition.x && vel.x < minVelocity || pos.x > initialPosition.x && vel.x > minVelocity)) {
5611
5978
  vel.x *= -getRandom();
5612
5979
  }
5613
- if (vDistance && (pos.y < initialPosition.y && vel.y < 0 || pos.y > initialPosition.y && vel.y > 0)) {
5980
+ if (vDistance && (pos.y < initialPosition.y && vel.y < minVelocity || pos.y > initialPosition.y && vel.y > minVelocity)) {
5614
5981
  vel.y *= -getRandom();
5615
5982
  }
5616
5983
  }
@@ -5618,24 +5985,24 @@ function applyDistance(particle) {
5618
5985
  function move(particle, moveOptions, moveSpeed, maxSpeed, moveDrift, delta) {
5619
5986
  applyPath(particle, delta);
5620
5987
  const gravityOptions = particle.gravity,
5621
- gravityFactor = gravityOptions?.enable && gravityOptions.inverse ? -1 : 1;
5988
+ gravityFactor = gravityOptions?.enable && gravityOptions.inverse ? -identity : identity;
5622
5989
  if (moveDrift && moveSpeed) {
5623
- particle.velocity.x += moveDrift * delta.factor / (60 * moveSpeed);
5990
+ particle.velocity.x += moveDrift * delta.factor / (moveSpeedFactor * moveSpeed);
5624
5991
  }
5625
5992
  if (gravityOptions?.enable && moveSpeed) {
5626
- particle.velocity.y += gravityFactor * (gravityOptions.acceleration * delta.factor) / (60 * moveSpeed);
5993
+ particle.velocity.y += gravityFactor * (gravityOptions.acceleration * delta.factor) / (moveSpeedFactor * moveSpeed);
5627
5994
  }
5628
5995
  const decay = particle.moveDecay;
5629
5996
  particle.velocity.multTo(decay);
5630
5997
  const velocity = particle.velocity.mult(moveSpeed);
5631
- if (gravityOptions?.enable && maxSpeed > 0 && (!gravityOptions.inverse && velocity.y >= 0 && velocity.y >= maxSpeed || gravityOptions.inverse && velocity.y <= 0 && velocity.y <= -maxSpeed)) {
5998
+ if (gravityOptions?.enable && maxSpeed > minVelocity && (!gravityOptions.inverse && velocity.y >= minVelocity && velocity.y >= maxSpeed || gravityOptions.inverse && velocity.y <= minVelocity && velocity.y <= -maxSpeed)) {
5632
5999
  velocity.y = gravityFactor * maxSpeed;
5633
6000
  if (moveSpeed) {
5634
6001
  particle.velocity.y = velocity.y / moveSpeed;
5635
6002
  }
5636
6003
  }
5637
6004
  const zIndexOptions = particle.options.zIndex,
5638
- zVelocityFactor = (1 - particle.zIndexFactor) ** zIndexOptions.velocityRate;
6005
+ zVelocityFactor = (identity - particle.zIndexFactor) ** zIndexOptions.velocityRate;
5639
6006
  velocity.multTo(zVelocityFactor);
5640
6007
  const {
5641
6008
  position
@@ -5659,15 +6026,15 @@ function spin(particle, moveSpeed) {
5659
6026
  particle.position.y = particle.spin.center.y + particle.spin.radius * updateFunc.y(particle.spin.angle);
5660
6027
  particle.spin.radius += particle.spin.acceleration;
5661
6028
  const maxCanvasSize = Math.max(container.canvas.size.width, container.canvas.size.height),
5662
- halfMaxSize = maxCanvasSize * 0.5;
6029
+ halfMaxSize = maxCanvasSize * Utils_half;
5663
6030
  if (particle.spin.radius > halfMaxSize) {
5664
6031
  particle.spin.radius = halfMaxSize;
5665
- particle.spin.acceleration *= -1;
5666
- } else if (particle.spin.radius < 0) {
5667
- particle.spin.radius = 0;
5668
- particle.spin.acceleration *= -1;
6032
+ particle.spin.acceleration *= -identity;
6033
+ } else if (particle.spin.radius < minSpinRadius) {
6034
+ particle.spin.radius = minSpinRadius;
6035
+ particle.spin.acceleration *= -identity;
5669
6036
  }
5670
- particle.spin.angle += moveSpeed * 0.01 * (1 - particle.spin.radius / maxCanvasSize);
6037
+ particle.spin.angle += moveSpeed * spinFactor * (identity - particle.spin.radius / maxCanvasSize);
5671
6038
  }
5672
6039
  function applyPath(particle, delta) {
5673
6040
  const particlesOptions = particle.options,
@@ -5685,18 +6052,20 @@ function applyPath(particle, delta) {
5685
6052
  particle.velocity.addTo(path);
5686
6053
  }
5687
6054
  if (pathOptions.clamp) {
5688
- particle.velocity.x = clamp(particle.velocity.x, -1, 1);
5689
- particle.velocity.y = clamp(particle.velocity.y, -1, 1);
6055
+ particle.velocity.x = clamp(particle.velocity.x, -identity, identity);
6056
+ particle.velocity.y = clamp(particle.velocity.y, -identity, identity);
5690
6057
  }
5691
6058
  particle.lastPathTime -= particle.pathDelay;
5692
6059
  }
5693
6060
  function getProximitySpeedFactor(particle) {
5694
- return particle.slow.inRange ? particle.slow.factor : 1;
6061
+ return particle.slow.inRange ? particle.slow.factor : identity;
5695
6062
  }
5696
6063
  ;// CONCATENATED MODULE: ../../move/base/dist/browser/BaseMover.js
5697
6064
 
5698
6065
 
5699
- const diffFactor = 2;
6066
+ const diffFactor = 2,
6067
+ defaultSizeFactor = 1,
6068
+ defaultDeltaFactor = 1;
5700
6069
  class BaseMover {
5701
6070
  constructor() {
5702
6071
  this._initSpin = particle => {
@@ -5710,17 +6079,19 @@ class BaseMover {
5710
6079
  x: 50,
5711
6080
  y: 50
5712
6081
  },
6082
+ spinFactor = 0.01,
5713
6083
  spinCenter = {
5714
- x: spinPos.x * 0.01 * container.canvas.size.width,
5715
- y: spinPos.y * 0.01 * container.canvas.size.height
6084
+ x: spinPos.x * spinFactor * container.canvas.size.width,
6085
+ y: spinPos.y * spinFactor * container.canvas.size.height
5716
6086
  },
5717
6087
  pos = particle.getPosition(),
5718
6088
  distance = getDistance(pos, spinCenter),
5719
6089
  spinAcceleration = getRangeValue(spinOptions.acceleration);
5720
6090
  particle.retina.spinAcceleration = spinAcceleration * container.retina.pixelRatio;
6091
+ const minVelocity = 0;
5721
6092
  particle.spin = {
5722
6093
  center: spinCenter,
5723
- direction: particle.velocity.x >= 0 ? "clockwise" : "counter-clockwise",
6094
+ direction: particle.velocity.x >= minVelocity ? "clockwise" : "counter-clockwise",
5724
6095
  angle: particle.velocity.angle,
5725
6096
  radius: distance,
5726
6097
  acceleration: particle.retina.spinAcceleration
@@ -5747,13 +6118,16 @@ class BaseMover {
5747
6118
  return;
5748
6119
  }
5749
6120
  const container = particle.container,
5750
- pxRatio = container.retina.pixelRatio,
5751
- slowFactor = getProximitySpeedFactor(particle),
5752
- baseSpeed = (particle.retina.moveSpeed ??= getRangeValue(moveOptions.speed) * pxRatio) * container.retina.reduceFactor,
5753
- moveDrift = particle.retina.moveDrift ??= getRangeValue(particle.options.move.drift) * pxRatio,
6121
+ pxRatio = container.retina.pixelRatio;
6122
+ particle.retina.moveSpeed ??= getRangeValue(moveOptions.speed) * pxRatio;
6123
+ particle.retina.moveDrift ??= getRangeValue(particle.options.move.drift) * pxRatio;
6124
+ const slowFactor = getProximitySpeedFactor(particle),
6125
+ baseSpeed = particle.retina.moveSpeed * container.retina.reduceFactor,
6126
+ moveDrift = particle.retina.moveDrift,
5754
6127
  maxSize = getRangeMax(particleOptions.size.value) * pxRatio,
5755
- sizeFactor = moveOptions.size ? particle.getRadius() / maxSize : 1,
5756
- moveSpeed = baseSpeed * sizeFactor * slowFactor * (delta.factor || 1) / diffFactor,
6128
+ sizeFactor = moveOptions.size ? particle.getRadius() / maxSize : defaultSizeFactor,
6129
+ deltaFactor = delta.factor || defaultDeltaFactor,
6130
+ moveSpeed = baseSpeed * sizeFactor * slowFactor * deltaFactor / diffFactor,
5757
6131
  maxSpeed = particle.retina.maxSpeed ?? container.retina.maxSpeed;
5758
6132
  if (moveOptions.spin.enable) {
5759
6133
  spin(particle, moveSpeed);
@@ -5770,6 +6144,15 @@ async function loadBaseMover(engine, refresh = true) {
5770
6144
  }
5771
6145
  ;// CONCATENATED MODULE: ../../shapes/circle/dist/browser/CircleDrawer.js
5772
6146
 
6147
+ const CircleDrawer_double = 2,
6148
+ CircleDrawer_doublePI = Math.PI * CircleDrawer_double,
6149
+ sides = 12,
6150
+ maxAngle = 360,
6151
+ minAngle = 0,
6152
+ CircleDrawer_origin = {
6153
+ x: 0,
6154
+ y: 0
6155
+ };
5773
6156
  class CircleDrawer {
5774
6157
  draw(data) {
5775
6158
  const {
@@ -5779,28 +6162,28 @@ class CircleDrawer {
5779
6162
  } = data;
5780
6163
  if (!particle.circleRange) {
5781
6164
  particle.circleRange = {
5782
- min: 0,
5783
- max: Math.PI * 2
6165
+ min: minAngle,
6166
+ max: CircleDrawer_doublePI
5784
6167
  };
5785
6168
  }
5786
6169
  const circleRange = particle.circleRange;
5787
- context.arc(0, 0, radius, circleRange.min, circleRange.max, false);
6170
+ context.arc(CircleDrawer_origin.x, CircleDrawer_origin.y, radius, circleRange.min, circleRange.max, false);
5788
6171
  }
5789
6172
  getSidesCount() {
5790
- return 12;
6173
+ return sides;
5791
6174
  }
5792
6175
  particleInit(container, particle) {
5793
6176
  const shapeData = particle.shapeData,
5794
6177
  angle = shapeData?.angle ?? {
5795
- max: 360,
5796
- min: 0
6178
+ max: maxAngle,
6179
+ min: minAngle
5797
6180
  };
5798
6181
  particle.circleRange = !isObject(angle) ? {
5799
- min: 0,
5800
- max: angle * Math.PI / 180
6182
+ min: minAngle,
6183
+ max: degToRad(angle)
5801
6184
  } : {
5802
- min: angle.min * Math.PI / 180,
5803
- max: angle.max * Math.PI / 180
6185
+ min: degToRad(angle.min),
6186
+ max: degToRad(angle.max)
5804
6187
  };
5805
6188
  }
5806
6189
  }
@@ -5809,84 +6192,8 @@ class CircleDrawer {
5809
6192
  async function loadCircleShape(engine, refresh = true) {
5810
6193
  await engine.addShape("circle", new CircleDrawer(), refresh);
5811
6194
  }
5812
- ;// CONCATENATED MODULE: ../../updaters/color/dist/browser/Utils.js
5813
-
5814
- function updateColorValue(delta, colorValue, valueAnimation, max, decrease) {
5815
- if (!colorValue || !valueAnimation.enable || (colorValue.maxLoops ?? 0) > 0 && (colorValue.loops ?? 0) > (colorValue.maxLoops ?? 0)) {
5816
- return;
5817
- }
5818
- if (!colorValue.time) {
5819
- colorValue.time = 0;
5820
- }
5821
- if ((colorValue.delayTime ?? 0) > 0 && colorValue.time < (colorValue.delayTime ?? 0)) {
5822
- colorValue.time += delta.value;
5823
- }
5824
- if ((colorValue.delayTime ?? 0) > 0 && colorValue.time < (colorValue.delayTime ?? 0)) {
5825
- return;
5826
- }
5827
- const offset = randomInRange(valueAnimation.offset),
5828
- velocity = (colorValue.velocity ?? 0) * delta.factor + offset * 3.6,
5829
- decay = colorValue.decay ?? 1;
5830
- if (!decrease || colorValue.status === "increasing") {
5831
- colorValue.value += velocity;
5832
- if (colorValue.value > max) {
5833
- if (!colorValue.loops) {
5834
- colorValue.loops = 0;
5835
- }
5836
- colorValue.loops++;
5837
- if (decrease) {
5838
- colorValue.status = "decreasing";
5839
- colorValue.value -= colorValue.value % max;
5840
- }
5841
- }
5842
- } else {
5843
- colorValue.value -= velocity;
5844
- if (colorValue.value < 0) {
5845
- if (!colorValue.loops) {
5846
- colorValue.loops = 0;
5847
- }
5848
- colorValue.loops++;
5849
- colorValue.status = "increasing";
5850
- colorValue.value += colorValue.value;
5851
- }
5852
- }
5853
- if (colorValue.velocity && decay !== 1) {
5854
- colorValue.velocity *= decay;
5855
- }
5856
- if (colorValue.value > max) {
5857
- colorValue.value %= max;
5858
- }
5859
- }
5860
- function updateColor(particle, delta) {
5861
- const {
5862
- h: hAnimation,
5863
- s: sAnimation,
5864
- l: lAnimation
5865
- } = particle.options.color.animation,
5866
- {
5867
- color
5868
- } = particle;
5869
- if (!color) {
5870
- return;
5871
- }
5872
- const {
5873
- h,
5874
- s,
5875
- l
5876
- } = color;
5877
- if (h) {
5878
- updateColorValue(delta, h, hAnimation, 360, false);
5879
- }
5880
- if (s) {
5881
- updateColorValue(delta, s, sAnimation, 100, true);
5882
- }
5883
- if (l) {
5884
- updateColorValue(delta, l, lAnimation, 100, true);
5885
- }
5886
- }
5887
6195
  ;// CONCATENATED MODULE: ../../updaters/color/dist/browser/ColorUpdater.js
5888
6196
 
5889
-
5890
6197
  class ColorUpdater {
5891
6198
  constructor(container) {
5892
6199
  this.container = container;
@@ -5909,7 +6216,7 @@ class ColorUpdater {
5909
6216
  return !particle.destroyed && !particle.spawning && (color?.h.value !== undefined && hAnimation.enable || color?.s.value !== undefined && sAnimation.enable || color?.l.value !== undefined && lAnimation.enable);
5910
6217
  }
5911
6218
  update(particle, delta) {
5912
- updateColor(particle, delta);
6219
+ updateColor(particle.color, delta);
5913
6220
  }
5914
6221
  }
5915
6222
  ;// CONCATENATED MODULE: ../../updaters/color/dist/browser/index.js
@@ -5917,91 +6224,27 @@ class ColorUpdater {
5917
6224
  async function loadColorUpdater(engine, refresh = true) {
5918
6225
  await engine.addParticleUpdater("color", container => new ColorUpdater(container), refresh);
5919
6226
  }
5920
- ;// CONCATENATED MODULE: ../../updaters/opacity/dist/browser/Utils.js
5921
-
5922
- function checkDestroy(particle, value, minValue, maxValue) {
5923
- switch (particle.options.opacity.animation.destroy) {
5924
- case "max":
5925
- if (value >= maxValue) {
5926
- particle.destroy();
5927
- }
5928
- break;
5929
- case "min":
5930
- if (value <= minValue) {
5931
- particle.destroy();
5932
- }
5933
- break;
5934
- }
5935
- }
5936
- function updateOpacity(particle, delta) {
5937
- const data = particle.opacity;
5938
- if (particle.destroyed || !data?.enable || (data.maxLoops ?? 0) > 0 && (data.loops ?? 0) > (data.maxLoops ?? 0)) {
5939
- return;
5940
- }
5941
- const minValue = data.min,
5942
- maxValue = data.max,
5943
- decay = data.decay ?? 1;
5944
- if (!data.time) {
5945
- data.time = 0;
5946
- }
5947
- if ((data.delayTime ?? 0) > 0 && data.time < (data.delayTime ?? 0)) {
5948
- data.time += delta.value;
5949
- }
5950
- if ((data.delayTime ?? 0) > 0 && data.time < (data.delayTime ?? 0)) {
5951
- return;
5952
- }
5953
- switch (data.status) {
5954
- case "increasing":
5955
- if (data.value >= maxValue) {
5956
- data.status = "decreasing";
5957
- if (!data.loops) {
5958
- data.loops = 0;
5959
- }
5960
- data.loops++;
5961
- } else {
5962
- data.value += (data.velocity ?? 0) * delta.factor;
5963
- }
5964
- break;
5965
- case "decreasing":
5966
- if (data.value <= minValue) {
5967
- data.status = "increasing";
5968
- if (!data.loops) {
5969
- data.loops = 0;
5970
- }
5971
- data.loops++;
5972
- } else {
5973
- data.value -= (data.velocity ?? 0) * delta.factor;
5974
- }
5975
- break;
5976
- }
5977
- if (data.velocity && data.decay !== 1) {
5978
- data.velocity *= decay;
5979
- }
5980
- checkDestroy(particle, data.value, minValue, maxValue);
5981
- if (!particle.destroyed) {
5982
- data.value = clamp(data.value, minValue, maxValue);
5983
- }
5984
- }
5985
6227
  ;// CONCATENATED MODULE: ../../updaters/opacity/dist/browser/OpacityUpdater.js
5986
6228
 
5987
-
5988
6229
  class OpacityUpdater {
5989
6230
  constructor(container) {
5990
6231
  this.container = container;
5991
6232
  }
5992
6233
  init(particle) {
5993
- const opacityOptions = particle.options.opacity;
5994
- particle.opacity = initParticleNumericAnimationValue(opacityOptions, 1);
6234
+ const opacityOptions = particle.options.opacity,
6235
+ pxRatio = 1;
6236
+ particle.opacity = initParticleNumericAnimationValue(opacityOptions, pxRatio);
5995
6237
  const opacityAnimation = opacityOptions.animation;
5996
6238
  if (opacityAnimation.enable) {
5997
- particle.opacity.velocity = getRangeValue(opacityAnimation.speed) / 100 * this.container.retina.reduceFactor;
6239
+ particle.opacity.velocity = getRangeValue(opacityAnimation.speed) / percentDenominator * this.container.retina.reduceFactor;
5998
6240
  if (!opacityAnimation.sync) {
5999
6241
  particle.opacity.velocity *= getRandom();
6000
6242
  }
6001
6243
  }
6002
6244
  }
6003
6245
  isEnabled(particle) {
6004
- return !particle.destroyed && !particle.spawning && !!particle.opacity && particle.opacity.enable && ((particle.opacity.maxLoops ?? 0) <= 0 || (particle.opacity.maxLoops ?? 0) > 0 && (particle.opacity.loops ?? 0) < (particle.opacity.maxLoops ?? 0));
6246
+ const none = 0;
6247
+ return !particle.destroyed && !particle.spawning && !!particle.opacity && particle.opacity.enable && ((particle.opacity.maxLoops ?? none) <= none || (particle.opacity.maxLoops ?? none) > none && (particle.opacity.loops ?? none) < (particle.opacity.maxLoops ?? none));
6005
6248
  }
6006
6249
  reset(particle) {
6007
6250
  if (particle.opacity) {
@@ -6010,10 +6253,10 @@ class OpacityUpdater {
6010
6253
  }
6011
6254
  }
6012
6255
  update(particle, delta) {
6013
- if (!this.isEnabled(particle)) {
6256
+ if (!this.isEnabled(particle) || !particle.opacity) {
6014
6257
  return;
6015
6258
  }
6016
- updateOpacity(particle, delta);
6259
+ updateAnimation(particle, particle.opacity, true, particle.options.opacity.animation.destroy, delta);
6017
6260
  }
6018
6261
  }
6019
6262
  ;// CONCATENATED MODULE: ../../updaters/opacity/dist/browser/index.js
@@ -6023,18 +6266,20 @@ async function loadOpacityUpdater(engine, refresh = true) {
6023
6266
  }
6024
6267
  ;// CONCATENATED MODULE: ../../updaters/outModes/dist/browser/Utils.js
6025
6268
 
6269
+ const Utils_minVelocity = 0,
6270
+ boundsMin = 0;
6026
6271
  function bounceHorizontal(data) {
6027
6272
  if (data.outMode !== "bounce" && data.outMode !== "bounce-horizontal" && data.outMode !== "bounceHorizontal" && data.outMode !== "split" || data.direction !== "left" && data.direction !== "right") {
6028
6273
  return;
6029
6274
  }
6030
- if (data.bounds.right < 0 && data.direction === "left") {
6275
+ if (data.bounds.right < boundsMin && data.direction === "left") {
6031
6276
  data.particle.position.x = data.size + data.offset.x;
6032
6277
  } else if (data.bounds.left > data.canvasSize.width && data.direction === "right") {
6033
6278
  data.particle.position.x = data.canvasSize.width - data.size - data.offset.x;
6034
6279
  }
6035
6280
  const velocity = data.particle.velocity.x;
6036
6281
  let bounced = false;
6037
- if (data.direction === "right" && data.bounds.right >= data.canvasSize.width && velocity > 0 || data.direction === "left" && data.bounds.left <= 0 && velocity < 0) {
6282
+ if (data.direction === "right" && data.bounds.right >= data.canvasSize.width && velocity > Utils_minVelocity || data.direction === "left" && data.bounds.left <= boundsMin && velocity < Utils_minVelocity) {
6038
6283
  const newVelocity = getRangeValue(data.particle.options.bounce.horizontal.value);
6039
6284
  data.particle.velocity.x *= -newVelocity;
6040
6285
  bounced = true;
@@ -6045,7 +6290,7 @@ function bounceHorizontal(data) {
6045
6290
  const minPos = data.offset.x + data.size;
6046
6291
  if (data.bounds.right >= data.canvasSize.width && data.direction === "right") {
6047
6292
  data.particle.position.x = data.canvasSize.width - minPos;
6048
- } else if (data.bounds.left <= 0 && data.direction === "left") {
6293
+ } else if (data.bounds.left <= boundsMin && data.direction === "left") {
6049
6294
  data.particle.position.x = minPos;
6050
6295
  }
6051
6296
  if (data.outMode === "split") {
@@ -6056,14 +6301,14 @@ function bounceVertical(data) {
6056
6301
  if (data.outMode !== "bounce" && data.outMode !== "bounce-vertical" && data.outMode !== "bounceVertical" && data.outMode !== "split" || data.direction !== "bottom" && data.direction !== "top") {
6057
6302
  return;
6058
6303
  }
6059
- if (data.bounds.bottom < 0 && data.direction === "top") {
6304
+ if (data.bounds.bottom < boundsMin && data.direction === "top") {
6060
6305
  data.particle.position.y = data.size + data.offset.y;
6061
6306
  } else if (data.bounds.top > data.canvasSize.height && data.direction === "bottom") {
6062
6307
  data.particle.position.y = data.canvasSize.height - data.size - data.offset.y;
6063
6308
  }
6064
6309
  const velocity = data.particle.velocity.y;
6065
6310
  let bounced = false;
6066
- if (data.direction === "bottom" && data.bounds.bottom >= data.canvasSize.height && velocity > 0 || data.direction === "top" && data.bounds.top <= 0 && velocity < 0) {
6311
+ if (data.direction === "bottom" && data.bounds.bottom >= data.canvasSize.height && velocity > Utils_minVelocity || data.direction === "top" && data.bounds.top <= boundsMin && velocity < Utils_minVelocity) {
6067
6312
  const newVelocity = getRangeValue(data.particle.options.bounce.vertical.value);
6068
6313
  data.particle.velocity.y *= -newVelocity;
6069
6314
  bounced = true;
@@ -6074,7 +6319,7 @@ function bounceVertical(data) {
6074
6319
  const minPos = data.offset.y + data.size;
6075
6320
  if (data.bounds.bottom >= data.canvasSize.height && data.direction === "bottom") {
6076
6321
  data.particle.position.y = data.canvasSize.height - minPos;
6077
- } else if (data.bounds.top <= 0 && data.direction === "top") {
6322
+ } else if (data.bounds.top <= boundsMin && data.direction === "top") {
6078
6323
  data.particle.position.y = minPos;
6079
6324
  }
6080
6325
  if (data.outMode === "split") {
@@ -6133,6 +6378,7 @@ class BounceOutMode {
6133
6378
  }
6134
6379
  ;// CONCATENATED MODULE: ../../updaters/outModes/dist/browser/DestroyOutMode.js
6135
6380
 
6381
+ const DestroyOutMode_minVelocity = 0;
6136
6382
  class DestroyOutMode {
6137
6383
  constructor(container) {
6138
6384
  this.container = container;
@@ -6160,7 +6406,7 @@ class DestroyOutMode {
6160
6406
  x: vx,
6161
6407
  y: vy
6162
6408
  } = particle.velocity;
6163
- if (vx < 0 && dx > particle.moveCenter.radius || vy < 0 && dy > particle.moveCenter.radius || vx >= 0 && dx < -particle.moveCenter.radius || vy >= 0 && dy < -particle.moveCenter.radius) {
6409
+ if (vx < DestroyOutMode_minVelocity && dx > particle.moveCenter.radius || vy < DestroyOutMode_minVelocity && dy > particle.moveCenter.radius || vx >= DestroyOutMode_minVelocity && dx < -particle.moveCenter.radius || vy >= DestroyOutMode_minVelocity && dy < -particle.moveCenter.radius) {
6164
6410
  return;
6165
6411
  }
6166
6412
  break;
@@ -6171,6 +6417,7 @@ class DestroyOutMode {
6171
6417
  }
6172
6418
  ;// CONCATENATED MODULE: ../../updaters/outModes/dist/browser/NoneOutMode.js
6173
6419
 
6420
+ const NoneOutMode_minVelocity = 0;
6174
6421
  class NoneOutMode {
6175
6422
  constructor(container) {
6176
6423
  this.container = container;
@@ -6180,7 +6427,7 @@ class NoneOutMode {
6180
6427
  if (!this.modes.includes(outMode)) {
6181
6428
  return;
6182
6429
  }
6183
- if (particle.options.move.distance.horizontal && (direction === "left" || direction === "right") || particle.options.move.distance.vertical && (direction === "top" || direction === "bottom")) {
6430
+ if ((particle.options.move.distance.horizontal && (direction === "left" || direction === "right")) ?? (particle.options.move.distance.vertical && (direction === "top" || direction === "bottom"))) {
6184
6431
  return;
6185
6432
  }
6186
6433
  const gravityOptions = particle.options.move.gravity,
@@ -6188,7 +6435,7 @@ class NoneOutMode {
6188
6435
  const canvasSize = container.canvas.size;
6189
6436
  const pRadius = particle.getRadius();
6190
6437
  if (!gravityOptions.enable) {
6191
- if (particle.velocity.y > 0 && particle.position.y <= canvasSize.height + pRadius || particle.velocity.y < 0 && particle.position.y >= -pRadius || particle.velocity.x > 0 && particle.position.x <= canvasSize.width + pRadius || particle.velocity.x < 0 && particle.position.x >= -pRadius) {
6438
+ if (particle.velocity.y > NoneOutMode_minVelocity && particle.position.y <= canvasSize.height + pRadius || particle.velocity.y < NoneOutMode_minVelocity && particle.position.y >= -pRadius || particle.velocity.x > NoneOutMode_minVelocity && particle.position.x <= canvasSize.width + pRadius || particle.velocity.x < NoneOutMode_minVelocity && particle.position.x >= -pRadius) {
6192
6439
  return;
6193
6440
  }
6194
6441
  if (!isPointInside(particle.position, container.canvas.size, Vector.origin, pRadius, direction)) {
@@ -6204,6 +6451,8 @@ class NoneOutMode {
6204
6451
  }
6205
6452
  ;// CONCATENATED MODULE: ../../updaters/outModes/dist/browser/OutOutMode.js
6206
6453
 
6454
+ const OutOutMode_minVelocity = 0,
6455
+ minDistance = 0;
6207
6456
  class OutOutMode {
6208
6457
  constructor(container) {
6209
6458
  this.container = container;
@@ -6229,7 +6478,7 @@ class OutOutMode {
6229
6478
  dx,
6230
6479
  dy
6231
6480
  } = getDistances(particle.position, circVec);
6232
- if (vx <= 0 && dx >= 0 || vy <= 0 && dy >= 0 || vx >= 0 && dx <= 0 || vy >= 0 && dy <= 0) {
6481
+ if (vx <= OutOutMode_minVelocity && dx >= minDistance || vy <= OutOutMode_minVelocity && dy >= minDistance || vx >= OutOutMode_minVelocity && dx <= minDistance || vy >= OutOutMode_minVelocity && dy <= minDistance) {
6233
6482
  return;
6234
6483
  }
6235
6484
  particle.position.x = Math.floor(randomInRange({
@@ -6331,12 +6580,12 @@ class OutOutMode {
6331
6580
 
6332
6581
  class OutOfCanvasUpdater {
6333
6582
  constructor(container) {
6334
- this.container = container;
6335
6583
  this._updateOutMode = (particle, delta, outMode, direction) => {
6336
6584
  for (const updater of this.updaters) {
6337
6585
  updater.update(particle, direction, delta, outMode);
6338
6586
  }
6339
6587
  };
6588
+ this.container = container;
6340
6589
  this.updaters = [new BounceOutMode(container), new DestroyOutMode(container), new OutOutMode(container), new NoneOutMode(container)];
6341
6590
  }
6342
6591
  init() {}
@@ -6356,97 +6605,32 @@ class OutOfCanvasUpdater {
6356
6605
  async function loadOutModesUpdater(engine, refresh = true) {
6357
6606
  await engine.addParticleUpdater("outModes", container => new OutOfCanvasUpdater(container), refresh);
6358
6607
  }
6359
- ;// CONCATENATED MODULE: ../../updaters/size/dist/browser/Utils.js
6360
-
6361
- function Utils_checkDestroy(particle, value, minValue, maxValue) {
6362
- switch (particle.options.size.animation.destroy) {
6363
- case "max":
6364
- if (value >= maxValue) {
6365
- particle.destroy();
6366
- }
6367
- break;
6368
- case "min":
6369
- if (value <= minValue) {
6370
- particle.destroy();
6371
- }
6372
- break;
6373
- }
6374
- }
6375
- function updateSize(particle, delta) {
6376
- const data = particle.size;
6377
- if (particle.destroyed || !data || !data.enable || (data.maxLoops ?? 0) > 0 && (data.loops ?? 0) > (data.maxLoops ?? 0)) {
6378
- return;
6379
- }
6380
- const sizeVelocity = (data.velocity ?? 0) * delta.factor,
6381
- minValue = data.min,
6382
- maxValue = data.max,
6383
- decay = data.decay ?? 1;
6384
- if (!data.time) {
6385
- data.time = 0;
6386
- }
6387
- if ((data.delayTime ?? 0) > 0 && data.time < (data.delayTime ?? 0)) {
6388
- data.time += delta.value;
6389
- }
6390
- if ((data.delayTime ?? 0) > 0 && data.time < (data.delayTime ?? 0)) {
6391
- return;
6392
- }
6393
- switch (data.status) {
6394
- case "increasing":
6395
- if (data.value >= maxValue) {
6396
- data.status = "decreasing";
6397
- if (!data.loops) {
6398
- data.loops = 0;
6399
- }
6400
- data.loops++;
6401
- } else {
6402
- data.value += sizeVelocity;
6403
- }
6404
- break;
6405
- case "decreasing":
6406
- if (data.value <= minValue) {
6407
- data.status = "increasing";
6408
- if (!data.loops) {
6409
- data.loops = 0;
6410
- }
6411
- data.loops++;
6412
- } else {
6413
- data.value -= sizeVelocity;
6414
- }
6415
- }
6416
- if (data.velocity && decay !== 1) {
6417
- data.velocity *= decay;
6418
- }
6419
- Utils_checkDestroy(particle, data.value, minValue, maxValue);
6420
- if (!particle.destroyed) {
6421
- data.value = clamp(data.value, minValue, maxValue);
6422
- }
6423
- }
6424
6608
  ;// CONCATENATED MODULE: ../../updaters/size/dist/browser/SizeUpdater.js
6425
6609
 
6426
-
6610
+ const minLoops = 0;
6427
6611
  class SizeUpdater {
6428
6612
  init(particle) {
6429
6613
  const container = particle.container,
6430
6614
  sizeOptions = particle.options.size,
6431
6615
  sizeAnimation = sizeOptions.animation;
6432
6616
  if (sizeAnimation.enable) {
6433
- particle.size.velocity = (particle.retina.sizeAnimationSpeed ?? container.retina.sizeAnimationSpeed) / 100 * container.retina.reduceFactor;
6617
+ particle.size.velocity = (particle.retina.sizeAnimationSpeed ?? container.retina.sizeAnimationSpeed) / percentDenominator * container.retina.reduceFactor;
6434
6618
  if (!sizeAnimation.sync) {
6435
6619
  particle.size.velocity *= getRandom();
6436
6620
  }
6437
6621
  }
6438
6622
  }
6439
6623
  isEnabled(particle) {
6440
- return !particle.destroyed && !particle.spawning && particle.size.enable && ((particle.size.maxLoops ?? 0) <= 0 || (particle.size.maxLoops ?? 0) > 0 && (particle.size.loops ?? 0) < (particle.size.maxLoops ?? 0));
6624
+ return !particle.destroyed && !particle.spawning && particle.size.enable && ((particle.size.maxLoops ?? minLoops) <= minLoops || (particle.size.maxLoops ?? minLoops) > minLoops && (particle.size.loops ?? minLoops) < (particle.size.maxLoops ?? minLoops));
6441
6625
  }
6442
6626
  reset(particle) {
6443
- particle.size.loops = 0;
6627
+ particle.size.loops = minLoops;
6444
6628
  }
6445
6629
  update(particle, delta) {
6446
6630
  if (!this.isEnabled(particle)) {
6447
6631
  return;
6448
6632
  }
6449
- updateSize(particle, delta);
6633
+ updateAnimation(particle, particle.size, true, particle.options.size.animation.destroy, delta);
6450
6634
  }
6451
6635
  }
6452
6636
  ;// CONCATENATED MODULE: ../../updaters/size/dist/browser/index.js
@@ -6476,6 +6660,7 @@ async function loadEasingQuadPlugin() {
6476
6660
  addEasing("ease-in-quad", value => value ** 2);
6477
6661
  addEasing("ease-out-quad", value => 1 - (1 - value) ** 2);
6478
6662
  addEasing("ease-in-out-quad", value => value < 0.5 ? 2 * value ** 2 : 1 - (-2 * value + 2) ** 2 / 2);
6663
+ await Promise.resolve();
6479
6664
  }
6480
6665
  ;// CONCATENATED MODULE: ../../shapes/emoji/dist/browser/EmojiDrawer.js
6481
6666
 
@@ -6486,8 +6671,11 @@ class EmojiDrawer {
6486
6671
  this._emojiShapeDict = new Map();
6487
6672
  }
6488
6673
  destroy() {
6489
- for (const [, emojiData] of this._emojiShapeDict) {
6490
- emojiData instanceof ImageBitmap && emojiData?.close();
6674
+ for (const [key, emojiData] of this._emojiShapeDict) {
6675
+ if (emojiData instanceof ImageBitmap) {
6676
+ emojiData?.close();
6677
+ this._emojiShapeDict.delete(key);
6678
+ }
6491
6679
  }
6492
6680
  }
6493
6681
  draw(data) {
@@ -6497,13 +6685,16 @@ class EmojiDrawer {
6497
6685
  radius,
6498
6686
  opacity
6499
6687
  } = data,
6500
- emojiData = particle.emojiData;
6688
+ emojiData = particle.emojiData,
6689
+ double = 2,
6690
+ diameter = radius * double,
6691
+ previousAlpha = context.globalAlpha;
6501
6692
  if (!emojiData) {
6502
6693
  return;
6503
6694
  }
6504
6695
  context.globalAlpha = opacity;
6505
- context.drawImage(emojiData, -radius, -radius, radius * 2, radius * 2);
6506
- context.globalAlpha = 1;
6696
+ context.drawImage(emojiData, -radius, -radius, diameter, diameter);
6697
+ context.globalAlpha = previousAlpha;
6507
6698
  }
6508
6699
  async init(container) {
6509
6700
  const options = container.actualOptions;
@@ -6512,7 +6703,9 @@ class EmojiDrawer {
6512
6703
  shapeOptions = validTypes.map(t => options.particles.shape.options[t]).find(t => !!t);
6513
6704
  if (shapeOptions) {
6514
6705
  executeOnSingleOrMultiple(shapeOptions, shape => {
6515
- shape.font && promises.push(loadFont(shape.font));
6706
+ if (shape.font) {
6707
+ promises.push(loadFont(shape.font));
6708
+ }
6516
6709
  });
6517
6710
  }
6518
6711
  await Promise.all(promises);
@@ -6522,52 +6715,52 @@ class EmojiDrawer {
6522
6715
  delete particle.emojiData;
6523
6716
  }
6524
6717
  particleInit(container, particle) {
6525
- if (!particle.emojiData) {
6526
- const shapeData = particle.shapeData;
6527
- if (!shapeData?.value) {
6528
- return;
6529
- }
6530
- const emoji = itemFromSingleOrMultiple(shapeData.value, particle.randomIndexData),
6531
- font = shapeData.font ?? defaultFont;
6532
- if (!emoji) {
6718
+ const double = 2,
6719
+ shapeData = particle.shapeData;
6720
+ if (!shapeData?.value) {
6721
+ return;
6722
+ }
6723
+ const emoji = itemFromSingleOrMultiple(shapeData.value, particle.randomIndexData),
6724
+ font = shapeData.font ?? defaultFont;
6725
+ if (!emoji) {
6726
+ return;
6727
+ }
6728
+ const key = `${emoji}_${font}`,
6729
+ existingData = this._emojiShapeDict.get(key);
6730
+ if (existingData) {
6731
+ particle.emojiData = existingData;
6732
+ return;
6733
+ }
6734
+ const canvasSize = getRangeMax(particle.size.value) * double;
6735
+ let emojiData;
6736
+ const maxSize = getRangeMax(particle.size.value);
6737
+ if (typeof OffscreenCanvas !== "undefined") {
6738
+ const canvas = new OffscreenCanvas(canvasSize, canvasSize),
6739
+ context = canvas.getContext("2d");
6740
+ if (!context) {
6533
6741
  return;
6534
6742
  }
6535
- const key = `${emoji}_${font}`,
6536
- existingData = this._emojiShapeDict.get(key);
6537
- if (existingData) {
6538
- particle.emojiData = existingData;
6743
+ context.font = `400 ${maxSize * double}px ${font}`;
6744
+ context.textBaseline = "middle";
6745
+ context.textAlign = "center";
6746
+ context.fillText(emoji, maxSize, maxSize);
6747
+ emojiData = canvas.transferToImageBitmap();
6748
+ } else {
6749
+ const canvas = document.createElement("canvas");
6750
+ canvas.width = canvasSize;
6751
+ canvas.height = canvasSize;
6752
+ const context = canvas.getContext("2d");
6753
+ if (!context) {
6539
6754
  return;
6540
6755
  }
6541
- const canvasSize = getRangeMax(particle.size.value) * 2;
6542
- let emojiData;
6543
- if (typeof OffscreenCanvas !== "undefined") {
6544
- const canvas = new OffscreenCanvas(canvasSize, canvasSize),
6545
- context = canvas.getContext("2d");
6546
- if (!context) {
6547
- return;
6548
- }
6549
- context.font = `400 ${getRangeMax(particle.size.value) * 2}px ${font}`;
6550
- context.textBaseline = "middle";
6551
- context.textAlign = "center";
6552
- context.fillText(emoji, getRangeMax(particle.size.value), getRangeMax(particle.size.value));
6553
- emojiData = canvas.transferToImageBitmap();
6554
- } else {
6555
- const canvas = document.createElement("canvas");
6556
- canvas.width = canvasSize;
6557
- canvas.height = canvasSize;
6558
- const context = canvas.getContext("2d");
6559
- if (!context) {
6560
- return;
6561
- }
6562
- context.font = `400 ${getRangeMax(particle.size.value) * 2}px ${font}`;
6563
- context.textBaseline = "middle";
6564
- context.textAlign = "center";
6565
- context.fillText(emoji, getRangeMax(particle.size.value), getRangeMax(particle.size.value));
6566
- emojiData = canvas;
6567
- }
6568
- this._emojiShapeDict.set(key, emojiData);
6569
- particle.emojiData = emojiData;
6756
+ context.font = `400 ${maxSize * double}px ${font}`;
6757
+ context.textBaseline = "middle";
6758
+ context.textAlign = "center";
6759
+ context.fillText(emoji, maxSize, maxSize);
6760
+ emojiData = canvas;
6570
6761
  }
6762
+ this._emojiShapeDict.set(key, emojiData);
6763
+ particle.emojiData = emojiData;
6571
6764
  }
6572
6765
  }
6573
6766
  ;// CONCATENATED MODULE: ../../shapes/emoji/dist/browser/index.js
@@ -6612,7 +6805,10 @@ class Attract {
6612
6805
  ;// CONCATENATED MODULE: ../../interactions/external/attract/dist/browser/Attractor.js
6613
6806
 
6614
6807
 
6615
- const attractMode = "attract";
6808
+ const attractMode = "attract",
6809
+ minRadius = 0,
6810
+ minFactor = 1,
6811
+ Attractor_identity = 1;
6616
6812
  class Attractor extends ExternalInteractorBase {
6617
6813
  constructor(engine, container) {
6618
6814
  super(container);
@@ -6638,20 +6834,19 @@ class Attractor extends ExternalInteractorBase {
6638
6834
  if (attract.clicking) {
6639
6835
  const mousePos = container.interactivity.mouse.clickPosition,
6640
6836
  attractRadius = container.retina.attractModeDistance;
6641
- if (!attractRadius || attractRadius < 0 || !mousePos) {
6837
+ if (!attractRadius || attractRadius < minRadius || !mousePos) {
6642
6838
  return;
6643
6839
  }
6644
6840
  this._processAttract(mousePos, attractRadius, new Circle(mousePos.x, mousePos.y, attractRadius));
6645
6841
  } else if (attract.clicking === false) {
6646
6842
  attract.particles = [];
6647
6843
  }
6648
- return;
6649
6844
  };
6650
6845
  this._hoverAttract = () => {
6651
6846
  const container = this.container,
6652
6847
  mousePos = container.interactivity.mouse.position,
6653
6848
  attractRadius = container.retina.attractModeDistance;
6654
- if (!attractRadius || attractRadius < 0 || !mousePos) {
6849
+ if (!attractRadius || attractRadius < minRadius || !mousePos) {
6655
6850
  return;
6656
6851
  }
6657
6852
  this._processAttract(mousePos, attractRadius, new Circle(mousePos.x, mousePos.y, attractRadius));
@@ -6665,13 +6860,13 @@ class Attractor extends ExternalInteractorBase {
6665
6860
  const query = container.particles.quadTree.query(area, p => this.isEnabled(p));
6666
6861
  for (const particle of query) {
6667
6862
  const {
6668
- dx,
6669
- dy,
6670
- distance
6671
- } = getDistances(particle.position, position);
6672
- const velocity = attractOptions.speed * attractOptions.factor;
6673
- const attractFactor = clamp(getEasing(attractOptions.easing)(1 - distance / attractRadius) * velocity, 0, attractOptions.maxSpeed);
6674
- const normVec = Vector.create(distance === 0 ? velocity : dx / distance * attractFactor, distance === 0 ? velocity : dy / distance * attractFactor);
6863
+ dx,
6864
+ dy,
6865
+ distance
6866
+ } = getDistances(particle.position, position),
6867
+ velocity = attractOptions.speed * attractOptions.factor,
6868
+ attractFactor = clamp(getEasing(attractOptions.easing)(Attractor_identity - distance / attractRadius) * velocity, minFactor, attractOptions.maxSpeed),
6869
+ normVec = Vector.create(!distance ? velocity : dx / distance * attractFactor, !distance ? velocity : dy / distance * attractFactor);
6675
6870
  particle.position.subFrom(normVec);
6676
6871
  }
6677
6872
  };
@@ -6712,7 +6907,7 @@ class Attractor extends ExternalInteractorBase {
6712
6907
  };
6713
6908
  }
6714
6909
  container.attract.clicking = false;
6715
- }, attract.duration * 1000);
6910
+ }, attract.duration * millisecondsToSeconds);
6716
6911
  };
6717
6912
  }
6718
6913
  clear() {}
@@ -6738,6 +6933,7 @@ class Attractor extends ExternalInteractorBase {
6738
6933
  } else if (clickEnabled && isInArray(attractMode, clickMode)) {
6739
6934
  this._clickAttract();
6740
6935
  }
6936
+ await Promise.resolve();
6741
6937
  }
6742
6938
  isEnabled(particle) {
6743
6939
  const container = this.container,
@@ -6785,7 +6981,13 @@ class Bounce {
6785
6981
  ;// CONCATENATED MODULE: ../../interactions/external/bounce/dist/browser/Bouncer.js
6786
6982
 
6787
6983
 
6788
- const bounceMode = "bounce";
6984
+ const bounceMode = "bounce",
6985
+ Bouncer_squareExp = 2,
6986
+ Bouncer_double = 2,
6987
+ Bouncer_half = 0.5,
6988
+ halfPI = Math.PI * Bouncer_half,
6989
+ toleranceFactor = 10,
6990
+ Bouncer_minRadius = 0;
6789
6991
  class Bouncer extends ExternalInteractorBase {
6790
6992
  constructor(container) {
6791
6993
  super(container);
@@ -6796,7 +6998,7 @@ class Bouncer extends ExternalInteractorBase {
6796
6998
  circleBounce(circleBounceDataFromParticle(particle), {
6797
6999
  position,
6798
7000
  radius,
6799
- mass: radius ** 2 * Math.PI / 2,
7001
+ mass: radius ** Bouncer_squareExp * halfPI,
6800
7002
  velocity: Vector.origin,
6801
7003
  factor: Vector.origin
6802
7004
  });
@@ -6808,10 +7010,10 @@ class Bouncer extends ExternalInteractorBase {
6808
7010
  this._processMouseBounce = () => {
6809
7011
  const container = this.container,
6810
7012
  pxRatio = container.retina.pixelRatio,
6811
- tolerance = 10 * pxRatio,
7013
+ tolerance = toleranceFactor * pxRatio,
6812
7014
  mousePos = container.interactivity.mouse.position,
6813
7015
  radius = container.retina.bounceModeDistance;
6814
- if (!radius || radius < 0 || !mousePos) {
7016
+ if (!radius || radius < Bouncer_minRadius || !mousePos) {
6815
7017
  return;
6816
7018
  }
6817
7019
  this._processBounce(mousePos, radius, new Circle(mousePos.x, mousePos.y, radius + tolerance));
@@ -6826,12 +7028,12 @@ class Bouncer extends ExternalInteractorBase {
6826
7028
  const elem = item,
6827
7029
  pxRatio = container.retina.pixelRatio,
6828
7030
  pos = {
6829
- x: (elem.offsetLeft + elem.offsetWidth / 2) * pxRatio,
6830
- y: (elem.offsetTop + elem.offsetHeight / 2) * pxRatio
7031
+ x: (elem.offsetLeft + elem.offsetWidth * Bouncer_half) * pxRatio,
7032
+ y: (elem.offsetTop + elem.offsetHeight * Bouncer_half) * pxRatio
6831
7033
  },
6832
- radius = elem.offsetWidth / 2 * pxRatio,
6833
- tolerance = 10 * pxRatio,
6834
- area = div.type === "circle" ? new Circle(pos.x, pos.y, radius + tolerance) : new Rectangle(elem.offsetLeft * pxRatio - tolerance, elem.offsetTop * pxRatio - tolerance, elem.offsetWidth * pxRatio + tolerance * 2, elem.offsetHeight * pxRatio + tolerance * 2);
7034
+ radius = elem.offsetWidth * Bouncer_half * pxRatio,
7035
+ tolerance = toleranceFactor * pxRatio,
7036
+ area = div.type === "circle" ? new Circle(pos.x, pos.y, radius + tolerance) : new Rectangle(elem.offsetLeft * pxRatio - tolerance, elem.offsetTop * pxRatio - tolerance, elem.offsetWidth * pxRatio + tolerance * Bouncer_double, elem.offsetHeight * pxRatio + tolerance * Bouncer_double);
6835
7037
  this._processBounce(pos, radius, area);
6836
7038
  });
6837
7039
  };
@@ -6858,6 +7060,7 @@ class Bouncer extends ExternalInteractorBase {
6858
7060
  } else {
6859
7061
  divModeExecute(bounceMode, divs, (selector, div) => this._singleSelectorBounce(selector, div));
6860
7062
  }
7063
+ await Promise.resolve();
6861
7064
  }
6862
7065
  isEnabled(particle) {
6863
7066
  const container = this.container,
@@ -6865,7 +7068,7 @@ class Bouncer extends ExternalInteractorBase {
6865
7068
  mouse = container.interactivity.mouse,
6866
7069
  events = (particle?.interactivity ?? options.interactivity).events,
6867
7070
  divs = events.onDiv;
6868
- return mouse.position && events.onHover.enable && isInArray(bounceMode, events.onHover.mode) || isDivModeEnabled(bounceMode, divs);
7071
+ return !!mouse.position && events.onHover.enable && isInArray(bounceMode, events.onHover.mode) || isDivModeEnabled(bounceMode, divs);
6869
7072
  }
6870
7073
  loadModeOptions(options, ...sources) {
6871
7074
  if (!options.bounce) {
@@ -6968,7 +7171,16 @@ function calculateBubbleValue(particleValue, modeValue, optionsValue, ratio) {
6968
7171
 
6969
7172
 
6970
7173
 
6971
- const bubbleMode = "bubble";
7174
+ const bubbleMode = "bubble",
7175
+ Bubbler_minDistance = 0,
7176
+ defaultClickTime = 0,
7177
+ Bubbler_double = 2,
7178
+ defaultOpacity = 1,
7179
+ ratioOffset = 1,
7180
+ defaultBubbleValue = 0,
7181
+ minRatio = 0,
7182
+ Bubbler_half = 0.5,
7183
+ Bubbler_defaultRatio = 1;
6972
7184
  class Bubbler extends ExternalInteractorBase {
6973
7185
  constructor(container) {
6974
7186
  super(container);
@@ -6984,7 +7196,7 @@ class Bubbler extends ExternalInteractorBase {
6984
7196
  container.bubble = {};
6985
7197
  }
6986
7198
  const distance = container.retina.bubbleModeDistance;
6987
- if (!distance || distance < 0) {
7199
+ if (!distance || distance < Bubbler_minDistance) {
6988
7200
  return;
6989
7201
  }
6990
7202
  const query = container.particles.quadTree.queryCircle(mouseClickPos, distance, p => this.isEnabled(p)),
@@ -6998,11 +7210,11 @@ class Bubbler extends ExternalInteractorBase {
6998
7210
  particle.bubble.inRange = !bubble.durationEnd;
6999
7211
  const pos = particle.getPosition(),
7000
7212
  distMouse = getDistance(pos, mouseClickPos),
7001
- timeSpent = (new Date().getTime() - (container.interactivity.mouse.clickTime || 0)) / 1000;
7213
+ timeSpent = (new Date().getTime() - (container.interactivity.mouse.clickTime ?? defaultClickTime)) / millisecondsToSeconds;
7002
7214
  if (timeSpent > bubbleOptions.duration) {
7003
7215
  bubble.durationEnd = true;
7004
7216
  }
7005
- if (timeSpent > bubbleOptions.duration * 2) {
7217
+ if (timeSpent > bubbleOptions.duration * Bubbler_double) {
7006
7218
  bubble.clicking = false;
7007
7219
  bubble.durationEnd = false;
7008
7220
  }
@@ -7025,7 +7237,7 @@ class Bubbler extends ExternalInteractorBase {
7025
7237
  },
7026
7238
  particlesObj: {
7027
7239
  optValue: getRangeMax(particle.options.opacity.value),
7028
- value: particle.opacity?.value ?? 1
7240
+ value: particle.opacity?.value ?? defaultOpacity
7029
7241
  },
7030
7242
  type: "opacity"
7031
7243
  };
@@ -7041,7 +7253,7 @@ class Bubbler extends ExternalInteractorBase {
7041
7253
  const container = this.container,
7042
7254
  mousePos = container.interactivity.mouse.position,
7043
7255
  distance = container.retina.bubbleModeDistance;
7044
- if (!distance || distance < 0 || mousePos === undefined) {
7256
+ if (!distance || distance < Bubbler_minDistance || !mousePos) {
7045
7257
  return;
7046
7258
  }
7047
7259
  const query = container.particles.quadTree.queryCircle(mousePos, distance, p => this.isEnabled(p));
@@ -7049,9 +7261,9 @@ class Bubbler extends ExternalInteractorBase {
7049
7261
  particle.bubble.inRange = true;
7050
7262
  const pos = particle.getPosition(),
7051
7263
  pointDistance = getDistance(pos, mousePos),
7052
- ratio = 1 - pointDistance / distance;
7264
+ ratio = ratioOffset - pointDistance / distance;
7053
7265
  if (pointDistance <= distance) {
7054
- if (ratio >= 0 && container.interactivity.status === mouseMoveEvent) {
7266
+ if (ratio >= minRatio && container.interactivity.status === mouseMoveEvent) {
7055
7267
  this._hoverBubbleSize(particle, ratio);
7056
7268
  this._hoverBubbleOpacity(particle, ratio);
7057
7269
  this._hoverBubbleColor(particle, ratio);
@@ -7084,7 +7296,7 @@ class Bubbler extends ExternalInteractorBase {
7084
7296
  if (bubbleOptions.mix) {
7085
7297
  particle.bubble.color = undefined;
7086
7298
  const pColor = particle.getFillColor();
7087
- particle.bubble.color = pColor ? rgbToHsl(colorMix(pColor, particle.bubble.finalColor, 1 - ratio, ratio)) : particle.bubble.finalColor;
7299
+ particle.bubble.color = pColor ? rgbToHsl(colorMix(pColor, particle.bubble.finalColor, ratioOffset - ratio, ratio)) : particle.bubble.finalColor;
7088
7300
  } else {
7089
7301
  particle.bubble.color = particle.bubble.finalColor;
7090
7302
  }
@@ -7097,7 +7309,7 @@ class Bubbler extends ExternalInteractorBase {
7097
7309
  return;
7098
7310
  }
7099
7311
  const optOpacity = particle.options.opacity.value,
7100
- pOpacity = particle.opacity?.value ?? 1,
7312
+ pOpacity = particle.opacity?.value ?? defaultOpacity,
7101
7313
  opacity = calculateBubbleValue(pOpacity, modeOpacity, getRangeMax(optOpacity), ratio);
7102
7314
  if (opacity !== undefined) {
7103
7315
  particle.bubble.opacity = opacity;
@@ -7128,9 +7340,9 @@ class Bubbler extends ExternalInteractorBase {
7128
7340
  bubbleDistance = container.retina.bubbleModeDistance,
7129
7341
  particlesParam = data.particlesObj.optValue,
7130
7342
  pObjBubble = data.bubbleObj.value,
7131
- pObj = data.particlesObj.value || 0,
7343
+ pObj = data.particlesObj.value ?? defaultBubbleValue,
7132
7344
  type = data.type;
7133
- if (!bubbleDistance || bubbleDistance < 0 || bubbleParam === particlesParam) {
7345
+ if (!bubbleDistance || bubbleDistance < Bubbler_minDistance || bubbleParam === particlesParam) {
7134
7346
  return;
7135
7347
  }
7136
7348
  if (!container.bubble) {
@@ -7178,10 +7390,10 @@ class Bubbler extends ExternalInteractorBase {
7178
7390
  const elem = item,
7179
7391
  pxRatio = container.retina.pixelRatio,
7180
7392
  pos = {
7181
- x: (elem.offsetLeft + elem.offsetWidth / 2) * pxRatio,
7182
- y: (elem.offsetTop + elem.offsetHeight / 2) * pxRatio
7393
+ x: (elem.offsetLeft + elem.offsetWidth * Bubbler_half) * pxRatio,
7394
+ y: (elem.offsetTop + elem.offsetHeight * Bubbler_half) * pxRatio
7183
7395
  },
7184
- repulseRadius = elem.offsetWidth / 2 * pxRatio,
7396
+ repulseRadius = elem.offsetWidth * Bubbler_half * pxRatio,
7185
7397
  area = div.type === "circle" ? new Circle(pos.x, pos.y, repulseRadius) : new Rectangle(elem.offsetLeft * pxRatio, elem.offsetTop * pxRatio, elem.offsetWidth * pxRatio, elem.offsetHeight * pxRatio),
7186
7398
  query = container.particles.quadTree.query(area, p => this.isEnabled(p));
7187
7399
  for (const particle of query) {
@@ -7195,9 +7407,9 @@ class Bubbler extends ExternalInteractorBase {
7195
7407
  this.clear(particle, delta, true);
7196
7408
  particle.bubble.div = elem;
7197
7409
  }
7198
- this._hoverBubbleSize(particle, 1, divBubble);
7199
- this._hoverBubbleOpacity(particle, 1, divBubble);
7200
- this._hoverBubbleColor(particle, 1, divBubble);
7410
+ this._hoverBubbleSize(particle, Bubbler_defaultRatio, divBubble);
7411
+ this._hoverBubbleOpacity(particle, Bubbler_defaultRatio, divBubble);
7412
+ this._hoverBubbleColor(particle, Bubbler_defaultRatio, divBubble);
7201
7413
  }
7202
7414
  });
7203
7415
  };
@@ -7251,6 +7463,7 @@ class Bubbler extends ExternalInteractorBase {
7251
7463
  } else {
7252
7464
  divModeExecute(bubbleMode, divs, (selector, div) => this._singleSelectorHover(delta, selector, div));
7253
7465
  }
7466
+ await Promise.resolve();
7254
7467
  }
7255
7468
  isEnabled(particle) {
7256
7469
  const container = this.container,
@@ -7263,7 +7476,7 @@ class Bubbler extends ExternalInteractorBase {
7263
7476
  onHover
7264
7477
  } = events,
7265
7478
  divBubble = isDivModeEnabled(bubbleMode, onDiv);
7266
- if (!(divBubble || onHover.enable && mouse.position || onClick.enable && mouse.clickPosition)) {
7479
+ if (!(divBubble || onHover.enable && !!mouse.position || onClick.enable && mouse.clickPosition)) {
7267
7480
  return false;
7268
7481
  }
7269
7482
  return isInArray(bubbleMode, onHover.mode) || isInArray(bubbleMode, onClick.mode) || divBubble;
@@ -7328,6 +7541,9 @@ class Connect {
7328
7541
  }
7329
7542
  ;// CONCATENATED MODULE: ../../interactions/external/connect/dist/browser/Utils.js
7330
7543
 
7544
+ const gradientMin = 0,
7545
+ gradientMax = 1,
7546
+ defaultLinksWidth = 0;
7331
7547
  function gradient(context, p1, p2, opacity) {
7332
7548
  const gradStop = Math.floor(p2.getRadius() / p1.getRadius()),
7333
7549
  color1 = p1.getFillColor(),
@@ -7339,9 +7555,9 @@ function gradient(context, p1, p2, opacity) {
7339
7555
  destPos = p2.getPosition(),
7340
7556
  midRgb = colorMix(color1, color2, p1.getRadius(), p2.getRadius()),
7341
7557
  grad = context.createLinearGradient(sourcePos.x, sourcePos.y, destPos.x, destPos.y);
7342
- grad.addColorStop(0, getStyleFromHsl(color1, opacity));
7343
- grad.addColorStop(gradStop > 1 ? 1 : gradStop, getStyleFromRgb(midRgb, opacity));
7344
- grad.addColorStop(1, getStyleFromHsl(color2, opacity));
7558
+ grad.addColorStop(gradientMin, getStyleFromHsl(color1, opacity));
7559
+ grad.addColorStop(clamp(gradStop, gradientMin, gradientMax), getStyleFromRgb(midRgb, opacity));
7560
+ grad.addColorStop(gradientMax, getStyleFromHsl(color2, opacity));
7345
7561
  return grad;
7346
7562
  }
7347
7563
  function drawConnectLine(context, width, lineStyle, begin, end) {
@@ -7366,14 +7582,15 @@ function drawConnection(container, p1, p2) {
7366
7582
  }
7367
7583
  const pos1 = p1.getPosition(),
7368
7584
  pos2 = p2.getPosition();
7369
- drawConnectLine(ctx, p1.retina.linksWidth ?? 0, ls, pos1, pos2);
7585
+ drawConnectLine(ctx, p1.retina.linksWidth ?? defaultLinksWidth, ls, pos1, pos2);
7370
7586
  });
7371
7587
  }
7372
7588
  ;// CONCATENATED MODULE: ../../interactions/external/connect/dist/browser/Connector.js
7373
7589
 
7374
7590
 
7375
7591
 
7376
- const connectMode = "connect";
7592
+ const connectMode = "connect",
7593
+ Connector_minDistance = 0;
7377
7594
  class Connector extends ExternalInteractorBase {
7378
7595
  constructor(container) {
7379
7596
  super(container);
@@ -7392,27 +7609,31 @@ class Connector extends ExternalInteractorBase {
7392
7609
  const container = this.container,
7393
7610
  options = container.actualOptions;
7394
7611
  if (options.interactivity.events.onHover.enable && container.interactivity.status === "pointermove") {
7395
- const mousePos = container.interactivity.mouse.position;
7396
- if (!container.retina.connectModeDistance || container.retina.connectModeDistance < 0 || !container.retina.connectModeRadius || container.retina.connectModeRadius < 0 || !mousePos) {
7612
+ const mousePos = container.interactivity.mouse.position,
7613
+ {
7614
+ connectModeDistance,
7615
+ connectModeRadius
7616
+ } = container.retina;
7617
+ if (!connectModeDistance || connectModeDistance < Connector_minDistance || !connectModeRadius || connectModeRadius < Connector_minDistance || !mousePos) {
7397
7618
  return;
7398
7619
  }
7399
- const distance = Math.abs(container.retina.connectModeRadius),
7620
+ const distance = Math.abs(connectModeRadius),
7400
7621
  query = container.particles.quadTree.queryCircle(mousePos, distance, p => this.isEnabled(p));
7401
- let i = 0;
7402
- for (const p1 of query) {
7403
- const pos1 = p1.getPosition();
7404
- for (const p2 of query.slice(i + 1)) {
7622
+ query.forEach((p1, i) => {
7623
+ const pos1 = p1.getPosition(),
7624
+ indexOffset = 1;
7625
+ for (const p2 of query.slice(i + indexOffset)) {
7405
7626
  const pos2 = p2.getPosition(),
7406
- distMax = Math.abs(container.retina.connectModeDistance),
7627
+ distMax = Math.abs(connectModeDistance),
7407
7628
  xDiff = Math.abs(pos1.x - pos2.x),
7408
7629
  yDiff = Math.abs(pos1.y - pos2.y);
7409
7630
  if (xDiff < distMax && yDiff < distMax) {
7410
7631
  drawConnection(container, p1, p2);
7411
7632
  }
7412
7633
  }
7413
- ++i;
7414
- }
7634
+ });
7415
7635
  }
7636
+ await Promise.resolve();
7416
7637
  }
7417
7638
  isEnabled(particle) {
7418
7639
  const container = this.container,
@@ -7487,6 +7708,7 @@ class Grab {
7487
7708
  }
7488
7709
  ;// CONCATENATED MODULE: ../../interactions/external/grab/dist/browser/Utils.js
7489
7710
 
7711
+ const defaultWidth = 0;
7490
7712
  function drawGrabLine(context, width, begin, end, colorLine, opacity) {
7491
7713
  drawLine(context, begin, end);
7492
7714
  context.strokeStyle = getStyleFromRgb(colorLine, opacity);
@@ -7496,14 +7718,16 @@ function drawGrabLine(context, width, begin, end, colorLine, opacity) {
7496
7718
  function drawGrab(container, particle, lineColor, opacity, mousePos) {
7497
7719
  container.canvas.draw(ctx => {
7498
7720
  const beginPos = particle.getPosition();
7499
- drawGrabLine(ctx, particle.retina.linksWidth ?? 0, beginPos, mousePos, lineColor, opacity);
7721
+ drawGrabLine(ctx, particle.retina.linksWidth ?? defaultWidth, beginPos, mousePos, lineColor, opacity);
7500
7722
  });
7501
7723
  }
7502
7724
  ;// CONCATENATED MODULE: ../../interactions/external/grab/dist/browser/Grabber.js
7503
7725
 
7504
7726
 
7505
7727
 
7506
- const grabMode = "grab";
7728
+ const grabMode = "grab",
7729
+ Grabber_minDistance = 0,
7730
+ minOpacity = 0;
7507
7731
  class Grabber extends ExternalInteractorBase {
7508
7732
  constructor(container) {
7509
7733
  super(container);
@@ -7529,7 +7753,7 @@ class Grabber extends ExternalInteractorBase {
7529
7753
  return;
7530
7754
  }
7531
7755
  const distance = container.retina.grabModeDistance;
7532
- if (!distance || distance < 0) {
7756
+ if (!distance || distance < Grabber_minDistance) {
7533
7757
  return;
7534
7758
  }
7535
7759
  const query = container.particles.quadTree.queryCircle(mousePos, distance, p => this.isEnabled(p));
@@ -7542,7 +7766,7 @@ class Grabber extends ExternalInteractorBase {
7542
7766
  const grabLineOptions = interactivity.modes.grab.links,
7543
7767
  lineOpacity = grabLineOptions.opacity,
7544
7768
  opacityLine = lineOpacity - pointDistance * lineOpacity / distance;
7545
- if (opacityLine <= 0) {
7769
+ if (opacityLine <= minOpacity) {
7546
7770
  continue;
7547
7771
  }
7548
7772
  const optColor = grabLineOptions.color ?? particle.options.links?.color;
@@ -7556,6 +7780,7 @@ class Grabber extends ExternalInteractorBase {
7556
7780
  }
7557
7781
  drawGrab(container, particle, colorLine, opacityLine, mousePos);
7558
7782
  }
7783
+ await Promise.resolve();
7559
7784
  }
7560
7785
  isEnabled(particle) {
7561
7786
  const container = this.container,
@@ -7643,7 +7868,8 @@ class Push {
7643
7868
  ;// CONCATENATED MODULE: ../../interactions/external/push/dist/browser/Pusher.js
7644
7869
 
7645
7870
 
7646
- const pushMode = "push";
7871
+ const pushMode = "push",
7872
+ minQuantity = 0;
7647
7873
  class Pusher extends ExternalInteractorBase {
7648
7874
  constructor(container) {
7649
7875
  super(container);
@@ -7658,7 +7884,7 @@ class Pusher extends ExternalInteractorBase {
7658
7884
  return;
7659
7885
  }
7660
7886
  const quantity = getRangeValue(pushOptions.quantity);
7661
- if (quantity <= 0) {
7887
+ if (quantity <= minQuantity) {
7662
7888
  return;
7663
7889
  }
7664
7890
  const group = itemFromArray([undefined, ...pushOptions.groups]),
@@ -7816,7 +8042,15 @@ class Repulse extends RepulseBase {
7816
8042
  ;// CONCATENATED MODULE: ../../interactions/external/repulse/dist/browser/Repulser.js
7817
8043
 
7818
8044
 
7819
- const repulseMode = "repulse";
8045
+ const repulseMode = "repulse",
8046
+ Repulser_minDistance = 0,
8047
+ repulseRadiusFactor = 6,
8048
+ repulseRadiusPower = 3,
8049
+ squarePower = 2,
8050
+ Repulser_minRadius = 0,
8051
+ minSpeed = 0,
8052
+ easingOffset = 1,
8053
+ Repulser_half = 0.5;
7820
8054
  class Repulser extends ExternalInteractorBase {
7821
8055
  constructor(engine, container) {
7822
8056
  super(container);
@@ -7826,7 +8060,7 @@ class Repulser extends ExternalInteractorBase {
7826
8060
  if (!repulseOptions) {
7827
8061
  return;
7828
8062
  }
7829
- const repulse = container.repulse || {
8063
+ const repulse = container.repulse ?? {
7830
8064
  particles: []
7831
8065
  };
7832
8066
  if (!repulse.finish) {
@@ -7840,10 +8074,10 @@ class Repulser extends ExternalInteractorBase {
7840
8074
  }
7841
8075
  if (repulse.clicking) {
7842
8076
  const repulseDistance = container.retina.repulseModeDistance;
7843
- if (!repulseDistance || repulseDistance < 0) {
8077
+ if (!repulseDistance || repulseDistance < Repulser_minDistance) {
7844
8078
  return;
7845
8079
  }
7846
- const repulseRadius = Math.pow(repulseDistance / 6, 3),
8080
+ const repulseRadius = Math.pow(repulseDistance / repulseRadiusFactor, repulseRadiusPower),
7847
8081
  mouseClickPos = container.interactivity.mouse.clickPosition;
7848
8082
  if (mouseClickPos === undefined) {
7849
8083
  return;
@@ -7856,7 +8090,7 @@ class Repulser extends ExternalInteractorBase {
7856
8090
  dy,
7857
8091
  distance
7858
8092
  } = getDistances(mouseClickPos, particle.position),
7859
- d = distance ** 2,
8093
+ d = distance ** squarePower,
7860
8094
  velocity = repulseOptions.speed,
7861
8095
  force = -repulseRadius * velocity / d;
7862
8096
  if (d <= repulseRadius) {
@@ -7877,7 +8111,7 @@ class Repulser extends ExternalInteractorBase {
7877
8111
  const container = this.container,
7878
8112
  mousePos = container.interactivity.mouse.position,
7879
8113
  repulseRadius = container.retina.repulseModeDistance;
7880
- if (!repulseRadius || repulseRadius < 0 || !mousePos) {
8114
+ if (!repulseRadius || repulseRadius < Repulser_minRadius || !mousePos) {
7881
8115
  return;
7882
8116
  }
7883
8117
  this._processRepulse(mousePos, repulseRadius, new Circle(mousePos.x, mousePos.y, repulseRadius));
@@ -7903,8 +8137,8 @@ class Repulser extends ExternalInteractorBase {
7903
8137
  dy,
7904
8138
  distance
7905
8139
  } = getDistances(particle.position, position),
7906
- repulseFactor = clamp(easingFunc(1 - distance / repulseRadius) * velocity, 0, maxSpeed),
7907
- normVec = Vector.create(distance === 0 ? velocity : dx / distance * repulseFactor, distance === 0 ? velocity : dy / distance * repulseFactor);
8140
+ repulseFactor = clamp(easingFunc(easingOffset - distance / repulseRadius) * velocity, minSpeed, maxSpeed),
8141
+ normVec = Vector.create(!distance ? velocity : dx / distance * repulseFactor, !distance ? velocity : dy / distance * repulseFactor);
7908
8142
  particle.position.addTo(normVec);
7909
8143
  }
7910
8144
  };
@@ -7922,10 +8156,10 @@ class Repulser extends ExternalInteractorBase {
7922
8156
  const elem = item,
7923
8157
  pxRatio = container.retina.pixelRatio,
7924
8158
  pos = {
7925
- x: (elem.offsetLeft + elem.offsetWidth / 2) * pxRatio,
7926
- y: (elem.offsetTop + elem.offsetHeight / 2) * pxRatio
8159
+ x: (elem.offsetLeft + elem.offsetWidth * Repulser_half) * pxRatio,
8160
+ y: (elem.offsetTop + elem.offsetHeight * Repulser_half) * pxRatio
7927
8161
  },
7928
- repulseRadius = elem.offsetWidth / 2 * pxRatio,
8162
+ repulseRadius = elem.offsetWidth * Repulser_half * pxRatio,
7929
8163
  area = div.type === "circle" ? new Circle(pos.x, pos.y, repulseRadius) : new Rectangle(elem.offsetLeft * pxRatio, elem.offsetTop * pxRatio, elem.offsetWidth * pxRatio, elem.offsetHeight * pxRatio),
7930
8164
  divs = repulse.divs,
7931
8165
  divRepulse = divMode(divs, elem);
@@ -7965,7 +8199,7 @@ class Repulser extends ExternalInteractorBase {
7965
8199
  return;
7966
8200
  }
7967
8201
  repulse.clicking = false;
7968
- }, repulseOpts.duration * 1000);
8202
+ }, repulseOpts.duration * millisecondsToSeconds);
7969
8203
  };
7970
8204
  }
7971
8205
  clear() {}
@@ -7996,6 +8230,7 @@ class Repulser extends ExternalInteractorBase {
7996
8230
  } else {
7997
8231
  divModeExecute(repulseMode, divs, (selector, div) => this._singleSelectorRepulse(selector, div));
7998
8232
  }
8233
+ await Promise.resolve();
7999
8234
  }
8000
8235
  isEnabled(particle) {
8001
8236
  const container = this.container,
@@ -8006,7 +8241,7 @@ class Repulser extends ExternalInteractorBase {
8006
8241
  hover = events.onHover,
8007
8242
  click = events.onClick,
8008
8243
  divRepulse = isDivModeEnabled(repulseMode, divs);
8009
- if (!(divRepulse || hover.enable && mouse.position || click.enable && mouse.clickPosition)) {
8244
+ if (!(divRepulse || hover.enable && !!mouse.position || click.enable && mouse.clickPosition)) {
8010
8245
  return false;
8011
8246
  }
8012
8247
  const hoverMode = hover.mode,
@@ -8055,7 +8290,8 @@ class Slow {
8055
8290
  ;// CONCATENATED MODULE: ../../interactions/external/slow/dist/browser/Slower.js
8056
8291
 
8057
8292
 
8058
- const slowMode = "slow";
8293
+ const slowMode = "slow",
8294
+ Slower_minRadius = 0;
8059
8295
  class Slower extends ExternalInteractorBase {
8060
8296
  constructor(container) {
8061
8297
  super(container);
@@ -8096,7 +8332,7 @@ class Slower extends ExternalInteractorBase {
8096
8332
  mousePos = container.interactivity.mouse.position,
8097
8333
  radius = container.retina.slowModeRadius,
8098
8334
  slowOptions = options.interactivity.modes.slow;
8099
- if (!slowOptions || !radius || radius < 0 || !mousePos) {
8335
+ if (!slowOptions || !radius || radius < Slower_minRadius || !mousePos) {
8100
8336
  return;
8101
8337
  }
8102
8338
  const particlePos = particle.getPosition(),
@@ -8138,32 +8374,39 @@ class ByteStream {
8138
8374
  return this.data[this.pos++];
8139
8375
  }
8140
8376
  nextTwoBytes() {
8141
- this.pos += 2;
8142
- return this.data[this.pos - 2] + (this.data[this.pos - 1] << 8);
8377
+ const increment = 2,
8378
+ previous = 1,
8379
+ shift = 8;
8380
+ this.pos += increment;
8381
+ return this.data[this.pos - increment] + (this.data[this.pos - previous] << shift);
8143
8382
  }
8144
8383
  readSubBlocks() {
8145
8384
  let blockString = "",
8146
8385
  size = 0;
8386
+ const minCount = 0,
8387
+ emptySize = 0;
8147
8388
  do {
8148
8389
  size = this.data[this.pos++];
8149
- for (let count = size; --count >= 0; blockString += String.fromCharCode(this.data[this.pos++])) {}
8150
- } while (size !== 0);
8390
+ for (let count = size; --count >= minCount; blockString += String.fromCharCode(this.data[this.pos++])) {}
8391
+ } while (size !== emptySize);
8151
8392
  return blockString;
8152
8393
  }
8153
8394
  readSubBlocksBin() {
8154
8395
  let size = 0,
8155
8396
  len = 0;
8156
- for (let offset = 0; (size = this.data[this.pos + offset]) !== 0; offset += size + 1) {
8397
+ const emptySize = 0,
8398
+ increment = 1;
8399
+ for (let offset = 0; size !== emptySize; offset += size + increment, size = this.data[this.pos + offset]) {
8157
8400
  len += size;
8158
8401
  }
8159
8402
  const blockData = new Uint8Array(len);
8160
- for (let i = 0; (size = this.data[this.pos++]) !== 0;) {
8161
- for (let count = size; --count >= 0; blockData[i++] = this.data[this.pos++]) {}
8403
+ for (let i = 0; size !== emptySize; size = this.data[this.pos++]) {
8404
+ for (let count = size; --count >= emptySize; blockData[i++] = this.data[this.pos++]) {}
8162
8405
  }
8163
8406
  return blockData;
8164
8407
  }
8165
8408
  skipSubBlocks() {
8166
- for (; this.data[this.pos] !== 0; this.pos += this.data[this.pos] + 1) {}
8409
+ for (const increment = 1, noData = 0; this.data[this.pos] !== noData; this.pos += this.data[this.pos] + increment) {}
8167
8410
  this.pos++;
8168
8411
  }
8169
8412
  }
@@ -8182,7 +8425,7 @@ function parseColorTable(byteStream, count) {
8182
8425
  }
8183
8426
  return colors;
8184
8427
  }
8185
- async function parseExtensionBlock(byteStream, gif, getFrameIndex, getTransparencyIndex) {
8428
+ function parseExtensionBlock(byteStream, gif, getFrameIndex, getTransparencyIndex) {
8186
8429
  switch (byteStream.nextByte()) {
8187
8430
  case 249:
8188
8431
  {
@@ -8264,11 +8507,19 @@ async function parseImageBlock(byteStream, gif, avgAlpha, getFrameIndex, getTran
8264
8507
  g,
8265
8508
  b
8266
8509
  } = (localColorTableFlag ? frame.localColorTable : gif.globalColorTable)[index];
8510
+ if (index !== getTransparencyIndex(null)) {
8511
+ return {
8512
+ r,
8513
+ g,
8514
+ b,
8515
+ a: 255
8516
+ };
8517
+ }
8267
8518
  return {
8268
8519
  r,
8269
8520
  g,
8270
8521
  b,
8271
- a: index === getTransparencyIndex(null) ? avgAlpha ? ~~((r + g + b) / 3) : 0 : 255
8522
+ a: avgAlpha ? ~~((r + g + b) / 3) : 0
8272
8523
  };
8273
8524
  };
8274
8525
  const image = (() => {
@@ -8297,7 +8548,10 @@ async function parseImageBlock(byteStream, gif, avgAlpha, getFrameIndex, getTran
8297
8548
  if (interlacedFlag) {
8298
8549
  for (let code = 0, size = minCodeSize + 1, pos = 0, dic = [[0]], pass = 0; pass < 4; pass++) {
8299
8550
  if (InterlaceOffsets[pass] < frame.height) {
8300
- for (let pixelPos = 0, lineIndex = 0;;) {
8551
+ let pixelPos = 0,
8552
+ lineIndex = 0,
8553
+ exit = false;
8554
+ while (!exit) {
8301
8555
  const last = code;
8302
8556
  code = readBits(pos, size);
8303
8557
  pos += size + 1;
@@ -8313,13 +8567,13 @@ async function parseImageBlock(byteStream, gif, avgAlpha, getFrameIndex, getTran
8313
8567
  } else if (last !== clearCode) {
8314
8568
  dic.push(dic[last].concat(dic[code][0]));
8315
8569
  }
8316
- for (let i = 0; i < dic[code].length; i++) {
8570
+ for (const item of dic[code]) {
8317
8571
  const {
8318
8572
  r,
8319
8573
  g,
8320
8574
  b,
8321
8575
  a
8322
- } = getColor(dic[code][i]);
8576
+ } = getColor(item);
8323
8577
  image.data.set([r, g, b, a], InterlaceOffsets[pass] * frame.width + InterlaceSteps[pass] * lineIndex + pixelPos % (frame.width * 4));
8324
8578
  pixelPos += 4;
8325
8579
  }
@@ -8330,7 +8584,7 @@ async function parseImageBlock(byteStream, gif, avgAlpha, getFrameIndex, getTran
8330
8584
  if (pixelPos === frame.width * 4 * (lineIndex + 1)) {
8331
8585
  lineIndex++;
8332
8586
  if (InterlaceOffsets[pass] + InterlaceSteps[pass] * lineIndex >= frame.height) {
8333
- break;
8587
+ exit = true;
8334
8588
  }
8335
8589
  }
8336
8590
  }
@@ -8346,7 +8600,13 @@ async function parseImageBlock(byteStream, gif, avgAlpha, getFrameIndex, getTran
8346
8600
  frame.image = image;
8347
8601
  frame.bitmap = await createImageBitmap(image);
8348
8602
  } else {
8349
- for (let code = 0, size = minCodeSize + 1, pos = 0, dic = [[0]], pixelPos = -4;;) {
8603
+ let code = 0,
8604
+ size = minCodeSize + 1,
8605
+ pos = 0,
8606
+ pixelPos = -4,
8607
+ exit = false;
8608
+ const dic = [[0]];
8609
+ while (!exit) {
8350
8610
  const last = code;
8351
8611
  code = readBits(pos, size);
8352
8612
  pos += size;
@@ -8358,6 +8618,7 @@ async function parseImageBlock(byteStream, gif, avgAlpha, getFrameIndex, getTran
8358
8618
  }
8359
8619
  } else {
8360
8620
  if (code === clearCode + 1) {
8621
+ exit = true;
8361
8622
  break;
8362
8623
  }
8363
8624
  if (code >= dic.length) {
@@ -8365,13 +8626,13 @@ async function parseImageBlock(byteStream, gif, avgAlpha, getFrameIndex, getTran
8365
8626
  } else if (last !== clearCode) {
8366
8627
  dic.push(dic[last].concat(dic[code][0]));
8367
8628
  }
8368
- for (let i = 0; i < dic[code].length; i++) {
8629
+ for (const item of dic[code]) {
8369
8630
  const {
8370
8631
  r,
8371
8632
  g,
8372
8633
  b,
8373
8634
  a
8374
- } = getColor(dic[code][i]);
8635
+ } = getColor(item);
8375
8636
  image.data.set([r, g, b, a], pixelPos += 4);
8376
8637
  }
8377
8638
  if (dic.length >= 1 << size && size < 0xc) {
@@ -8398,7 +8659,7 @@ async function parseBlock(byteStream, gif, avgAlpha, getFrameIndex, getTranspare
8398
8659
  await parseImageBlock(byteStream, gif, avgAlpha, getFrameIndex, getTransparencyIndex, progressCallback);
8399
8660
  break;
8400
8661
  case 33:
8401
- await parseExtensionBlock(byteStream, gif, getFrameIndex, getTransparencyIndex);
8662
+ parseExtensionBlock(byteStream, gif, getFrameIndex, getTransparencyIndex);
8402
8663
  break;
8403
8664
  default:
8404
8665
  throw new EvalError("undefined block found");
@@ -8539,6 +8800,9 @@ async function decodeGIF(gifURL, progressCallback, avgAlpha) {
8539
8800
  ;// CONCATENATED MODULE: ../../shapes/image/dist/browser/Utils.js
8540
8801
 
8541
8802
 
8803
+ const stringStart = 0,
8804
+ defaultLoopCount = 0,
8805
+ Utils_defaultOpacity = 1;
8542
8806
  const currentColorRegex = /(#(?:[0-9a-f]{2}){2,4}|(#[0-9a-f]{3})|(rgb|hsl)a?\((-?\d+%?[,\s]+){2,3}\s*[\d.]+%?\))|currentcolor/gi;
8543
8807
  function replaceColorSvg(imageShape, color, opacity) {
8544
8808
  const {
@@ -8552,7 +8816,7 @@ function replaceColorSvg(imageShape, color, opacity) {
8552
8816
  return svgData.replace(currentColorRegex, () => colorStyle);
8553
8817
  }
8554
8818
  const preFillIndex = svgData.indexOf(">");
8555
- return `${svgData.substring(0, preFillIndex)} fill="${colorStyle}"${svgData.substring(preFillIndex)}`;
8819
+ return `${svgData.substring(stringStart, preFillIndex)} fill="${colorStyle}"${svgData.substring(preFillIndex)}`;
8556
8820
  }
8557
8821
  async function loadImage(image) {
8558
8822
  return new Promise(resolve => {
@@ -8581,8 +8845,8 @@ async function loadGifImage(image) {
8581
8845
  image.loading = true;
8582
8846
  try {
8583
8847
  image.gifData = await decodeGIF(image.source);
8584
- image.gifLoopCount = getGIFLoopAmount(image.gifData) ?? 0;
8585
- if (image.gifLoopCount === 0) {
8848
+ image.gifLoopCount = getGIFLoopAmount(image.gifData) ?? defaultLoopCount;
8849
+ if (!image.gifLoopCount) {
8586
8850
  image.gifLoopCount = Infinity;
8587
8851
  }
8588
8852
  } catch {
@@ -8606,7 +8870,7 @@ async function downloadSvgImage(image) {
8606
8870
  image.loading = false;
8607
8871
  }
8608
8872
  function replaceImageColor(image, imageData, color, particle) {
8609
- const svgColoredData = replaceColorSvg(image, color, particle.opacity?.value ?? 1),
8873
+ const svgColoredData = replaceColorSvg(image, color, particle.opacity?.value ?? Utils_defaultOpacity),
8610
8874
  imageRes = {
8611
8875
  color,
8612
8876
  gif: imageData.gif,
@@ -8632,7 +8896,7 @@ function replaceImageColor(image, imageData, color, particle) {
8632
8896
  resolve(imageRes);
8633
8897
  domUrl.revokeObjectURL(url);
8634
8898
  });
8635
- img.addEventListener("error", async () => {
8899
+ const errorHandler = async () => {
8636
8900
  domUrl.revokeObjectURL(url);
8637
8901
  const img2 = {
8638
8902
  ...image,
@@ -8643,13 +8907,27 @@ function replaceImageColor(image, imageData, color, particle) {
8643
8907
  imageRes.loaded = true;
8644
8908
  imageRes.element = img2.element;
8645
8909
  resolve(imageRes);
8646
- });
8910
+ };
8911
+ img.addEventListener("error", () => void errorHandler());
8647
8912
  img.src = url;
8648
8913
  });
8649
8914
  }
8650
8915
  ;// CONCATENATED MODULE: ../../shapes/image/dist/browser/ImageDrawer.js
8651
8916
 
8652
8917
 
8918
+ const ImageDrawer_origin = {
8919
+ x: 0,
8920
+ y: 0
8921
+ },
8922
+ ImageDrawer_defaultLoopCount = 0,
8923
+ defaultFrame = 0,
8924
+ ImageDrawer_half = 0.5,
8925
+ initialTime = 0,
8926
+ firstIndex = 0,
8927
+ ImageDrawer_double = 2,
8928
+ defaultAlpha = 1,
8929
+ ImageDrawer_sides = 12,
8930
+ ImageDrawer_defaultRatio = 1;
8653
8931
  class ImageDrawer {
8654
8932
  constructor(engine) {
8655
8933
  this.loadImageShape = async imageShape => {
@@ -8693,18 +8971,18 @@ class ImageDrawer {
8693
8971
  }
8694
8972
  offscreenContext.imageSmoothingQuality = "low";
8695
8973
  offscreenContext.imageSmoothingEnabled = false;
8696
- offscreenContext.clearRect(0, 0, offscreenCanvas.width, offscreenCanvas.height);
8974
+ offscreenContext.clearRect(ImageDrawer_origin.x, ImageDrawer_origin.y, offscreenCanvas.width, offscreenCanvas.height);
8697
8975
  if (particle.gifLoopCount === undefined) {
8698
- particle.gifLoopCount = image.gifLoopCount ?? 0;
8976
+ particle.gifLoopCount = image.gifLoopCount ?? ImageDrawer_defaultLoopCount;
8699
8977
  }
8700
- let frameIndex = particle.gifFrame ?? 0;
8978
+ let frameIndex = particle.gifFrame ?? defaultFrame;
8701
8979
  const pos = {
8702
- x: -image.gifData.width * 0.5,
8703
- y: -image.gifData.height * 0.5
8980
+ x: -image.gifData.width * ImageDrawer_half,
8981
+ y: -image.gifData.height * ImageDrawer_half
8704
8982
  },
8705
8983
  frame = image.gifData.frames[frameIndex];
8706
8984
  if (particle.gifTime === undefined) {
8707
- particle.gifTime = 0;
8985
+ particle.gifTime = initialTime;
8708
8986
  }
8709
8987
  if (!frame.bitmap) {
8710
8988
  return;
@@ -8718,7 +8996,7 @@ class ImageDrawer {
8718
8996
  case 0:
8719
8997
  offscreenContext.drawImage(frame.bitmap, frame.left, frame.top);
8720
8998
  context.drawImage(offscreenCanvas, pos.x, pos.y);
8721
- offscreenContext.clearRect(0, 0, offscreenCanvas.width, offscreenCanvas.height);
8999
+ offscreenContext.clearRect(ImageDrawer_origin.x, ImageDrawer_origin.y, offscreenCanvas.width, offscreenCanvas.height);
8722
9000
  break;
8723
9001
  case 1:
8724
9002
  offscreenContext.drawImage(frame.bitmap, frame.left, frame.top);
@@ -8727,20 +9005,20 @@ class ImageDrawer {
8727
9005
  case 2:
8728
9006
  offscreenContext.drawImage(frame.bitmap, frame.left, frame.top);
8729
9007
  context.drawImage(offscreenCanvas, pos.x, pos.y);
8730
- offscreenContext.clearRect(0, 0, offscreenCanvas.width, offscreenCanvas.height);
8731
- if (image.gifData.globalColorTable.length === 0) {
8732
- offscreenContext.putImageData(image.gifData.frames[0].image, pos.x + frame.left, pos.y + frame.top);
9008
+ offscreenContext.clearRect(ImageDrawer_origin.x, ImageDrawer_origin.y, offscreenCanvas.width, offscreenCanvas.height);
9009
+ if (!image.gifData.globalColorTable.length) {
9010
+ offscreenContext.putImageData(image.gifData.frames[firstIndex].image, pos.x + frame.left, pos.y + frame.top);
8733
9011
  } else {
8734
9012
  offscreenContext.putImageData(image.gifData.backgroundImage, pos.x, pos.y);
8735
9013
  }
8736
9014
  break;
8737
9015
  case 3:
8738
9016
  {
8739
- const previousImageData = offscreenContext.getImageData(0, 0, offscreenCanvas.width, offscreenCanvas.height);
9017
+ const previousImageData = offscreenContext.getImageData(ImageDrawer_origin.x, ImageDrawer_origin.y, offscreenCanvas.width, offscreenCanvas.height);
8740
9018
  offscreenContext.drawImage(frame.bitmap, frame.left, frame.top);
8741
9019
  context.drawImage(offscreenCanvas, pos.x, pos.y);
8742
- offscreenContext.clearRect(0, 0, offscreenCanvas.width, offscreenCanvas.height);
8743
- offscreenContext.putImageData(previousImageData, 0, 0);
9020
+ offscreenContext.clearRect(ImageDrawer_origin.x, ImageDrawer_origin.y, offscreenCanvas.width, offscreenCanvas.height);
9021
+ offscreenContext.putImageData(previousImageData, ImageDrawer_origin.x, ImageDrawer_origin.y);
8744
9022
  }
8745
9023
  break;
8746
9024
  }
@@ -8748,11 +9026,11 @@ class ImageDrawer {
8748
9026
  if (particle.gifTime > frame.delayTime) {
8749
9027
  particle.gifTime -= frame.delayTime;
8750
9028
  if (++frameIndex >= image.gifData.frames.length) {
8751
- if (--particle.gifLoopCount <= 0) {
9029
+ if (--particle.gifLoopCount <= ImageDrawer_defaultLoopCount) {
8752
9030
  return;
8753
9031
  }
8754
- frameIndex = 0;
8755
- offscreenContext.clearRect(0, 0, offscreenCanvas.width, offscreenCanvas.height);
9032
+ frameIndex = firstIndex;
9033
+ offscreenContext.clearRect(ImageDrawer_origin.x, ImageDrawer_origin.y, offscreenCanvas.width, offscreenCanvas.height);
8756
9034
  }
8757
9035
  particle.gifFrame = frameIndex;
8758
9036
  }
@@ -8763,13 +9041,13 @@ class ImageDrawer {
8763
9041
  x: -radius,
8764
9042
  y: -radius
8765
9043
  },
8766
- diameter = radius * 2;
9044
+ diameter = radius * ImageDrawer_double;
8767
9045
  context.drawImage(element, pos.x, pos.y, diameter, diameter / ratio);
8768
9046
  }
8769
- context.globalAlpha = 1;
9047
+ context.globalAlpha = defaultAlpha;
8770
9048
  }
8771
9049
  getSidesCount() {
8772
- return 12;
9050
+ return ImageDrawer_sides;
8773
9051
  }
8774
9052
  async init(container) {
8775
9053
  const options = container.actualOptions;
@@ -8793,7 +9071,7 @@ class ImageDrawer {
8793
9071
  }
8794
9072
  const image = this._engine.images.find(t => t.name === imageData.name || t.source === imageData.src);
8795
9073
  if (!image) {
8796
- this.loadImageShape(imageData).then(() => {
9074
+ void this.loadImageShape(imageData).then(() => {
8797
9075
  this.loadShape(particle);
8798
9076
  });
8799
9077
  }
@@ -8822,7 +9100,7 @@ class ImageDrawer {
8822
9100
  });
8823
9101
  return;
8824
9102
  }
8825
- (async () => {
9103
+ void (async () => {
8826
9104
  let imageRes;
8827
9105
  if (image.svgData && color) {
8828
9106
  imageRes = await replaceImageColor(image, imageData, color, particle);
@@ -8835,7 +9113,7 @@ class ImageDrawer {
8835
9113
  gifData: image.gifData,
8836
9114
  gifLoopCount: image.gifLoopCount,
8837
9115
  loaded: true,
8838
- ratio: imageData.width && imageData.height ? imageData.width / imageData.height : image.ratio ?? 1,
9116
+ ratio: imageData.width && imageData.height ? imageData.width / imageData.height : image.ratio ?? ImageDrawer_defaultRatio,
8839
9117
  replaceColor: replaceColor,
8840
9118
  source: imageData.src
8841
9119
  };
@@ -8897,7 +9175,7 @@ class ImagePreloaderPlugin {
8897
9175
  return {};
8898
9176
  }
8899
9177
  loadOptions(options, source) {
8900
- if (!source || !source.preload) {
9178
+ if (!source?.preload) {
8901
9179
  return;
8902
9180
  }
8903
9181
  if (!options.preload) {
@@ -8924,6 +9202,7 @@ class ImagePreloaderPlugin {
8924
9202
 
8925
9203
 
8926
9204
 
9205
+ const extLength = 3;
8927
9206
  function addLoadImageToEngine(engine) {
8928
9207
  if (engine.loadImage) {
8929
9208
  return;
@@ -8943,14 +9222,19 @@ function addLoadImageToEngine(engine) {
8943
9222
  gif: data.gif ?? false,
8944
9223
  name: data.name ?? data.src,
8945
9224
  source: data.src,
8946
- type: data.src.substring(data.src.length - 3),
9225
+ type: data.src.substring(data.src.length - extLength),
8947
9226
  error: false,
8948
9227
  loading: true,
8949
9228
  replaceColor: data.replaceColor,
8950
9229
  ratio: data.width && data.height ? data.width / data.height : undefined
8951
9230
  };
8952
9231
  engine.images.push(image);
8953
- const imageFunc = data.gif ? loadGifImage : data.replaceColor ? downloadSvgImage : loadImage;
9232
+ let imageFunc;
9233
+ if (data.gif) {
9234
+ imageFunc = loadGifImage;
9235
+ } else {
9236
+ imageFunc = data.replaceColor ? downloadSvgImage : loadImage;
9237
+ }
8954
9238
  await imageFunc(image);
8955
9239
  } catch {
8956
9240
  throw new Error(`${errorPrefix} ${data.name ?? data.src} not found`);
@@ -9020,6 +9304,11 @@ class Life {
9020
9304
  ;// CONCATENATED MODULE: ../../updaters/life/dist/browser/LifeUpdater.js
9021
9305
 
9022
9306
 
9307
+ const noTime = 0,
9308
+ LifeUpdater_identity = 1,
9309
+ infiniteValue = -1,
9310
+ noLife = 0,
9311
+ minCanvasSize = 0;
9023
9312
  class LifeUpdater {
9024
9313
  constructor(container) {
9025
9314
  this.container = container;
@@ -9032,20 +9321,20 @@ class LifeUpdater {
9032
9321
  return;
9033
9322
  }
9034
9323
  particle.life = {
9035
- delay: container.retina.reduceFactor ? getRangeValue(lifeOptions.delay.value) * (lifeOptions.delay.sync ? 1 : getRandom()) / container.retina.reduceFactor * 1000 : 0,
9036
- delayTime: 0,
9037
- duration: container.retina.reduceFactor ? getRangeValue(lifeOptions.duration.value) * (lifeOptions.duration.sync ? 1 : getRandom()) / container.retina.reduceFactor * 1000 : 0,
9038
- time: 0,
9324
+ delay: container.retina.reduceFactor ? getRangeValue(lifeOptions.delay.value) * (lifeOptions.delay.sync ? LifeUpdater_identity : getRandom()) / container.retina.reduceFactor * millisecondsToSeconds : noTime,
9325
+ delayTime: noTime,
9326
+ duration: container.retina.reduceFactor ? getRangeValue(lifeOptions.duration.value) * (lifeOptions.duration.sync ? LifeUpdater_identity : getRandom()) / container.retina.reduceFactor * millisecondsToSeconds : noTime,
9327
+ time: noTime,
9039
9328
  count: lifeOptions.count
9040
9329
  };
9041
- if (particle.life.duration <= 0) {
9042
- particle.life.duration = -1;
9330
+ if (particle.life.duration <= noTime) {
9331
+ particle.life.duration = infiniteValue;
9043
9332
  }
9044
- if (particle.life.count <= 0) {
9045
- particle.life.count = -1;
9333
+ if (particle.life.count <= noTime) {
9334
+ particle.life.count = infiniteValue;
9046
9335
  }
9047
9336
  if (particle.life) {
9048
- particle.spawning = particle.life.delay > 0;
9337
+ particle.spawning = particle.life.delay > noTime;
9049
9338
  }
9050
9339
  }
9051
9340
  isEnabled(particle) {
@@ -9070,47 +9359,47 @@ class LifeUpdater {
9070
9359
  if (life.delayTime >= particle.life.delay) {
9071
9360
  justSpawned = true;
9072
9361
  particle.spawning = false;
9073
- life.delayTime = 0;
9074
- life.time = 0;
9362
+ life.delayTime = noTime;
9363
+ life.time = noTime;
9075
9364
  } else {
9076
9365
  return;
9077
9366
  }
9078
9367
  }
9079
- if (life.duration === -1) {
9368
+ if (life.duration === infiniteValue) {
9080
9369
  return;
9081
9370
  }
9082
9371
  if (particle.spawning) {
9083
9372
  return;
9084
9373
  }
9085
9374
  if (justSpawned) {
9086
- life.time = 0;
9375
+ life.time = noTime;
9087
9376
  } else {
9088
9377
  life.time += delta.value;
9089
9378
  }
9090
9379
  if (life.time < life.duration) {
9091
9380
  return;
9092
9381
  }
9093
- life.time = 0;
9094
- if (particle.life.count > 0) {
9382
+ life.time = noTime;
9383
+ if (particle.life.count > noLife) {
9095
9384
  particle.life.count--;
9096
9385
  }
9097
- if (particle.life.count === 0) {
9386
+ if (particle.life.count === noLife) {
9098
9387
  particle.destroy();
9099
9388
  return;
9100
9389
  }
9101
9390
  const canvasSize = this.container.canvas.size,
9102
- widthRange = setRangeValue(0, canvasSize.width),
9103
- heightRange = setRangeValue(0, canvasSize.width);
9391
+ widthRange = setRangeValue(minCanvasSize, canvasSize.width),
9392
+ heightRange = setRangeValue(minCanvasSize, canvasSize.width);
9104
9393
  particle.position.x = randomInRange(widthRange);
9105
9394
  particle.position.y = randomInRange(heightRange);
9106
9395
  particle.spawning = true;
9107
- life.delayTime = 0;
9108
- life.time = 0;
9396
+ life.delayTime = noTime;
9397
+ life.time = noTime;
9109
9398
  particle.reset();
9110
9399
  const lifeOptions = particle.options.life;
9111
9400
  if (lifeOptions) {
9112
- life.delay = getRangeValue(lifeOptions.delay.value) * 1000;
9113
- life.duration = getRangeValue(lifeOptions.duration.value) * 1000;
9401
+ life.delay = getRangeValue(lifeOptions.delay.value) * millisecondsToSeconds;
9402
+ life.duration = getRangeValue(lifeOptions.duration.value) * millisecondsToSeconds;
9114
9403
  }
9115
9404
  }
9116
9405
  }
@@ -9120,6 +9409,7 @@ async function loadLifeUpdater(engine, refresh = true) {
9120
9409
  await engine.addParticleUpdater("life", container => new LifeUpdater(container), refresh);
9121
9410
  }
9122
9411
  ;// CONCATENATED MODULE: ../../shapes/line/dist/browser/LineDrawer.js
9412
+ const LineDrawer_sides = 1;
9123
9413
  class LineDrawer {
9124
9414
  draw(data) {
9125
9415
  const {
@@ -9127,13 +9417,14 @@ class LineDrawer {
9127
9417
  particle,
9128
9418
  radius
9129
9419
  } = data,
9130
- shapeData = particle.shapeData;
9131
- context.moveTo(-radius / 2, 0);
9132
- context.lineTo(radius / 2, 0);
9420
+ shapeData = particle.shapeData,
9421
+ centerY = 0;
9422
+ context.moveTo(-radius, centerY);
9423
+ context.lineTo(radius, centerY);
9133
9424
  context.lineCap = shapeData?.cap ?? "butt";
9134
9425
  }
9135
9426
  getSidesCount() {
9136
- return 1;
9427
+ return LineDrawer_sides;
9137
9428
  }
9138
9429
  }
9139
9430
  ;// CONCATENATED MODULE: ../../shapes/line/dist/browser/index.js
@@ -9143,6 +9434,7 @@ async function loadLineShape(engine, refresh = true) {
9143
9434
  }
9144
9435
  ;// CONCATENATED MODULE: ../../move/parallax/dist/browser/ParallaxMover.js
9145
9436
 
9437
+ const ParallaxMover_half = 0.5;
9146
9438
  class ParallaxMover {
9147
9439
  init() {}
9148
9440
  isEnabled(particle) {
@@ -9162,8 +9454,8 @@ class ParallaxMover {
9162
9454
  }
9163
9455
  const canvasSize = container.canvas.size,
9164
9456
  canvasCenter = {
9165
- x: canvasSize.width * 0.5,
9166
- y: canvasSize.height * 0.5
9457
+ x: canvasSize.width * ParallaxMover_half,
9458
+ y: canvasSize.height * ParallaxMover_half
9167
9459
  },
9168
9460
  parallaxSmooth = parallaxOptions.smooth,
9169
9461
  factor = particle.getRadius() / parallaxForce,
@@ -9185,6 +9477,8 @@ async function loadParallaxMover(engine, refresh = true) {
9185
9477
  }
9186
9478
  ;// CONCATENATED MODULE: ../../interactions/particles/attract/dist/browser/Attractor.js
9187
9479
 
9480
+ const attractFactor = 1000,
9481
+ browser_Attractor_identity = 1;
9188
9482
  class Attractor_Attractor extends ParticlesInteractorBase {
9189
9483
  constructor(container) {
9190
9484
  super(container);
@@ -9209,15 +9503,16 @@ class Attractor_Attractor extends ParticlesInteractorBase {
9209
9503
  dy
9210
9504
  } = getDistances(pos1, pos2),
9211
9505
  rotate = p1.options.move.attract.rotate,
9212
- ax = dx / (rotate.x * 1000),
9213
- ay = dy / (rotate.y * 1000),
9506
+ ax = dx / (rotate.x * attractFactor),
9507
+ ay = dy / (rotate.y * attractFactor),
9214
9508
  p1Factor = p2.size.value / p1.size.value,
9215
- p2Factor = 1 / p1Factor;
9509
+ p2Factor = browser_Attractor_identity / p1Factor;
9216
9510
  p1.velocity.x -= ax * p1Factor;
9217
9511
  p1.velocity.y -= ay * p1Factor;
9218
9512
  p2.velocity.x += ax * p2Factor;
9219
9513
  p2.velocity.y += ay * p2Factor;
9220
9514
  }
9515
+ await Promise.resolve();
9221
9516
  }
9222
9517
  isEnabled(particle) {
9223
9518
  return particle.options.move.attract.enable;
@@ -9231,9 +9526,12 @@ async function loadParticlesAttractInteraction(engine, refresh = true) {
9231
9526
  }
9232
9527
  ;// CONCATENATED MODULE: ../../interactions/particles/collisions/dist/browser/Absorb.js
9233
9528
 
9529
+ const Absorb_half = 0.5,
9530
+ absorbFactor = 10,
9531
+ minAbsorbFactor = 0;
9234
9532
  function updateAbsorb(p1, r1, p2, r2, delta, pixelRatio) {
9235
- const factor = clamp(p1.options.collisions.absorb.speed * delta.factor / 10, 0, r2);
9236
- p1.size.value += factor / 2;
9533
+ const factor = clamp(p1.options.collisions.absorb.speed * delta.factor / absorbFactor, minAbsorbFactor, r2);
9534
+ p1.size.value += factor * Absorb_half;
9237
9535
  p2.size.value -= factor;
9238
9536
  if (r2 <= pixelRatio) {
9239
9537
  p2.size.value = 0;
@@ -9311,6 +9609,7 @@ function resolveCollision(p1, p2, delta, pixelRatio) {
9311
9609
  ;// CONCATENATED MODULE: ../../interactions/particles/collisions/dist/browser/Collider.js
9312
9610
 
9313
9611
 
9612
+ const Collider_double = 2;
9314
9613
  class Collider extends ParticlesInteractorBase {
9315
9614
  constructor(container) {
9316
9615
  super(container);
@@ -9324,7 +9623,7 @@ class Collider extends ParticlesInteractorBase {
9324
9623
  const container = this.container,
9325
9624
  pos1 = p1.getPosition(),
9326
9625
  radius1 = p1.getRadius(),
9327
- query = container.particles.quadTree.queryCircle(pos1, radius1 * 2);
9626
+ query = container.particles.quadTree.queryCircle(pos1, radius1 * Collider_double);
9328
9627
  for (const p2 of query) {
9329
9628
  if (p1 === p2 || !p2.options.collisions.enable || p1.options.collisions.mode !== p2.options.collisions.mode || p2.destroyed || p2.spawning) {
9330
9629
  continue;
@@ -9341,6 +9640,7 @@ class Collider extends ParticlesInteractorBase {
9341
9640
  }
9342
9641
  resolveCollision(p1, p2, delta, container.retina.pixelRatio);
9343
9642
  }
9643
+ await Promise.resolve();
9344
9644
  }
9345
9645
  isEnabled(particle) {
9346
9646
  return particle.options.collisions.enable;
@@ -9354,6 +9654,7 @@ async function loadParticlesCollisionsInteraction(engine, refresh = true) {
9354
9654
  }
9355
9655
  ;// CONCATENATED MODULE: ../../interactions/particles/links/dist/browser/CircleWarp.js
9356
9656
 
9657
+ const CircleWarp_double = 2;
9357
9658
  class CircleWarp extends Circle {
9358
9659
  constructor(x, y, radius, canvasSize) {
9359
9660
  super(x, y, radius);
@@ -9393,10 +9694,10 @@ class CircleWarp extends Circle {
9393
9694
  y: range.position.y - this.canvasSize.height
9394
9695
  };
9395
9696
  if (circle.radius !== undefined) {
9396
- const biggerCircle = new Circle(newPos.x, newPos.y, circle.radius * 2);
9697
+ const biggerCircle = new Circle(newPos.x, newPos.y, circle.radius * CircleWarp_double);
9397
9698
  return super.intersects(biggerCircle);
9398
9699
  } else if (rect.size !== undefined) {
9399
- const rectSW = new Rectangle(newPos.x, newPos.y, rect.size.width * 2, rect.size.height * 2);
9700
+ const rectSW = new Rectangle(newPos.x, newPos.y, rect.size.width * CircleWarp_double, rect.size.height * CircleWarp_double);
9400
9701
  return super.intersects(rectSW);
9401
9702
  }
9402
9703
  return false;
@@ -9508,6 +9809,13 @@ class Links {
9508
9809
 
9509
9810
 
9510
9811
 
9812
+ const Linker_squarePower = 2,
9813
+ opacityOffset = 1,
9814
+ Linker_origin = {
9815
+ x: 0,
9816
+ y: 0
9817
+ },
9818
+ Linker_minDistance = 0;
9511
9819
  function getLinkDistance(pos1, pos2, optDistance, canvasSize, warp) {
9512
9820
  const {
9513
9821
  dx,
@@ -9525,7 +9833,7 @@ function getLinkDistance(pos1, pos2, optDistance, canvasSize, warp) {
9525
9833
  x: Math.min(absDiffs.x, canvasSize.width - absDiffs.x),
9526
9834
  y: Math.min(absDiffs.y, canvasSize.height - absDiffs.y)
9527
9835
  };
9528
- return Math.sqrt(warpDistances.x ** 2 + warpDistances.y ** 2);
9836
+ return Math.sqrt(warpDistances.x ** Linker_squarePower + warpDistances.y ** Linker_squarePower);
9529
9837
  }
9530
9838
  class Linker extends ParticlesInteractorBase {
9531
9839
  constructor(container) {
@@ -9563,12 +9871,12 @@ class Linker extends ParticlesInteractorBase {
9563
9871
  const pos1 = p1.getPosition(),
9564
9872
  container = this.container,
9565
9873
  canvasSize = container.canvas.size;
9566
- if (pos1.x < 0 || pos1.y < 0 || pos1.x > canvasSize.width || pos1.y > canvasSize.height) {
9874
+ if (pos1.x < Linker_origin.x || pos1.y < Linker_origin.y || pos1.x > canvasSize.width || pos1.y > canvasSize.height) {
9567
9875
  return;
9568
9876
  }
9569
9877
  const linkOpt1 = p1.options.links,
9570
9878
  optOpacity = linkOpt1.opacity,
9571
- optDistance = p1.retina.linksDistance ?? 0,
9879
+ optDistance = p1.retina.linksDistance ?? Linker_minDistance,
9572
9880
  warp = linkOpt1.warp,
9573
9881
  range = warp ? new CircleWarp(pos1.x, pos1.y, optDistance, canvasSize) : new Circle(pos1.x, pos1.y, optDistance),
9574
9882
  query = container.particles.quadTree.query(range);
@@ -9578,20 +9886,21 @@ class Linker extends ParticlesInteractorBase {
9578
9886
  continue;
9579
9887
  }
9580
9888
  const pos2 = p2.getPosition();
9581
- if (pos2.x < 0 || pos2.y < 0 || pos2.x > canvasSize.width || pos2.y > canvasSize.height) {
9889
+ if (pos2.x < Linker_origin.x || pos2.y < Linker_origin.y || pos2.x > canvasSize.width || pos2.y > canvasSize.height) {
9582
9890
  continue;
9583
9891
  }
9584
9892
  const distance = getLinkDistance(pos1, pos2, optDistance, canvasSize, warp && linkOpt2.warp);
9585
9893
  if (distance > optDistance) {
9586
9894
  continue;
9587
9895
  }
9588
- const opacityLine = (1 - distance / optDistance) * optOpacity;
9896
+ const opacityLine = (opacityOffset - distance / optDistance) * optOpacity;
9589
9897
  this._setColor(p1);
9590
9898
  p1.links.push({
9591
9899
  destination: p2,
9592
9900
  opacity: opacityLine
9593
9901
  });
9594
9902
  }
9903
+ await Promise.resolve();
9595
9904
  }
9596
9905
  isEnabled(particle) {
9597
9906
  return !!particle.options.links?.enable;
@@ -9751,6 +10060,10 @@ function setLinkFrequency(particles, dictionary) {
9751
10060
  ;// CONCATENATED MODULE: ../../interactions/particles/links/dist/browser/LinkInstance.js
9752
10061
 
9753
10062
 
10063
+ const LinkInstance_minOpacity = 0,
10064
+ minWidth = 0,
10065
+ LinkInstance_minDistance = 0,
10066
+ LinkInstance_half = 0.5;
9754
10067
  class LinkInstance {
9755
10068
  constructor(container) {
9756
10069
  this.container = container;
@@ -9784,8 +10097,8 @@ class LinkInstance {
9784
10097
  if (!colorLine) {
9785
10098
  return;
9786
10099
  }
9787
- const width = p1.retina.linksWidth ?? 0,
9788
- maxDistance = p1.retina.linksDistance ?? 0,
10100
+ const width = p1.retina.linksWidth ?? minWidth,
10101
+ maxDistance = p1.retina.linksDistance ?? LinkInstance_minDistance,
9789
10102
  {
9790
10103
  backgroundMask
9791
10104
  } = options;
@@ -9816,15 +10129,15 @@ class LinkInstance {
9816
10129
  options = container.actualOptions,
9817
10130
  p2 = link1.destination,
9818
10131
  p3 = link2.destination,
9819
- opacityTriangle = triangleOptions.opacity ?? (link1.opacity + link2.opacity) / 2;
9820
- if (opacityTriangle <= 0) {
10132
+ opacityTriangle = triangleOptions.opacity ?? (link1.opacity + link2.opacity) * LinkInstance_half;
10133
+ if (opacityTriangle <= LinkInstance_minOpacity) {
9821
10134
  return;
9822
10135
  }
9823
10136
  container.canvas.draw(ctx => {
9824
10137
  const pos1 = p1.getPosition(),
9825
10138
  pos2 = p2.getPosition(),
9826
10139
  pos3 = p3.getPosition(),
9827
- linksDistance = p1.retina.linksDistance ?? 0;
10140
+ linksDistance = p1.retina.linksDistance ?? LinkInstance_minDistance;
9828
10141
  if (getDistance(pos1, pos2) > linksDistance || getDistance(pos3, pos2) > linksDistance || getDistance(pos3, pos1) > linksDistance) {
9829
10142
  return;
9830
10143
  }
@@ -9853,8 +10166,9 @@ class LinkInstance {
9853
10166
  return;
9854
10167
  }
9855
10168
  const vertices = p2.links?.filter(t => {
9856
- const linkFreq = this._getLinkFrequency(p2, t.destination);
9857
- return p2.options.links && linkFreq <= p2.options.links.frequency && p1Links.findIndex(l => l.destination === t.destination) >= 0;
10169
+ const linkFreq = this._getLinkFrequency(p2, t.destination),
10170
+ minCount = 0;
10171
+ return p2.options.links && linkFreq <= p2.options.links.frequency && p1Links.findIndex(l => l.destination === t.destination) >= minCount;
9858
10172
  });
9859
10173
  if (!vertices?.length) {
9860
10174
  return;
@@ -9884,13 +10198,13 @@ class LinkInstance {
9884
10198
  links,
9885
10199
  options
9886
10200
  } = particle;
9887
- if (!links || links.length <= 0) {
10201
+ if (!links?.length) {
9888
10202
  return;
9889
10203
  }
9890
10204
  const p1Links = links.filter(l => options.links && this._getLinkFrequency(particle, l.destination) <= options.links.frequency);
9891
10205
  for (const link of p1Links) {
9892
10206
  this._drawTriangles(options, particle, link, p1Links);
9893
- if (link.opacity > 0 && (particle.retina.linksWidth ?? 0) > 0) {
10207
+ if (link.opacity > LinkInstance_minOpacity && (particle.retina.linksWidth ?? minWidth) > minWidth) {
9894
10208
  this._drawLinkLine(particle, link);
9895
10209
  }
9896
10210
  }
@@ -9898,6 +10212,7 @@ class LinkInstance {
9898
10212
  async init() {
9899
10213
  this._freqs.links = new Map();
9900
10214
  this._freqs.triangles = new Map();
10215
+ await Promise.resolve();
9901
10216
  }
9902
10217
  particleCreated(particle) {
9903
10218
  particle.links = [];
@@ -9952,6 +10267,13 @@ async function loadParticlesLinksInteraction(engine, refresh = true) {
9952
10267
 
9953
10268
  ;// CONCATENATED MODULE: ../../shapes/polygon/dist/browser/PolygonDrawerBase.js
9954
10269
 
10270
+ const piDeg = 180,
10271
+ PolygonDrawerBase_origin = {
10272
+ x: 0,
10273
+ y: 0
10274
+ },
10275
+ defaultSides = 5,
10276
+ sidesOffset = 2;
9955
10277
  class PolygonDrawerBase {
9956
10278
  draw(data) {
9957
10279
  const {
@@ -9963,32 +10285,35 @@ class PolygonDrawerBase {
9963
10285
  side = this.getSidesData(particle, radius),
9964
10286
  sideCount = side.count.numerator * side.count.denominator,
9965
10287
  decimalSides = side.count.numerator / side.count.denominator,
9966
- interiorAngleDegrees = 180 * (decimalSides - 2) / decimalSides,
9967
- interiorAngle = Math.PI - Math.PI * interiorAngleDegrees / 180;
10288
+ interiorAngleDegrees = piDeg * (decimalSides - sidesOffset) / decimalSides,
10289
+ interiorAngle = Math.PI - degToRad(interiorAngleDegrees);
9968
10290
  if (!context) {
9969
10291
  return;
9970
10292
  }
9971
10293
  context.beginPath();
9972
10294
  context.translate(start.x, start.y);
9973
- context.moveTo(0, 0);
10295
+ context.moveTo(PolygonDrawerBase_origin.x, PolygonDrawerBase_origin.y);
9974
10296
  for (let i = 0; i < sideCount; i++) {
9975
- context.lineTo(side.length, 0);
9976
- context.translate(side.length, 0);
10297
+ context.lineTo(side.length, PolygonDrawerBase_origin.y);
10298
+ context.translate(side.length, PolygonDrawerBase_origin.y);
9977
10299
  context.rotate(interiorAngle);
9978
10300
  }
9979
10301
  }
9980
10302
  getSidesCount(particle) {
9981
10303
  const polygon = particle.shapeData;
9982
- return Math.round(getRangeValue(polygon?.sides ?? 5));
10304
+ return Math.round(getRangeValue(polygon?.sides ?? defaultSides));
9983
10305
  }
9984
10306
  }
9985
10307
  ;// CONCATENATED MODULE: ../../shapes/polygon/dist/browser/PolygonDrawer.js
9986
10308
 
10309
+ const sidesCenterFactor = 3.5,
10310
+ yFactor = 2.66,
10311
+ sidesFactor = 3;
9987
10312
  class PolygonDrawer extends PolygonDrawerBase {
9988
10313
  getCenter(particle, radius) {
9989
10314
  return {
9990
- x: -radius / (particle.sides / 3.5),
9991
- y: -radius / (2.66 / 3.5)
10315
+ x: -radius / (particle.sides / sidesCenterFactor),
10316
+ y: -radius / (yFactor / sidesCenterFactor)
9992
10317
  };
9993
10318
  }
9994
10319
  getSidesData(particle, radius) {
@@ -9998,29 +10323,33 @@ class PolygonDrawer extends PolygonDrawerBase {
9998
10323
  denominator: 1,
9999
10324
  numerator: sides
10000
10325
  },
10001
- length: radius * 2.66 / (sides / 3)
10326
+ length: radius * yFactor / (sides / sidesFactor)
10002
10327
  };
10003
10328
  }
10004
10329
  }
10005
10330
  ;// CONCATENATED MODULE: ../../shapes/polygon/dist/browser/TriangleDrawer.js
10006
10331
 
10332
+ const TriangleDrawer_yFactor = 1.66,
10333
+ TriangleDrawer_sides = 3,
10334
+ TriangleDrawer_double = 2;
10007
10335
  class TriangleDrawer extends PolygonDrawerBase {
10008
10336
  getCenter(particle, radius) {
10009
10337
  return {
10010
10338
  x: -radius,
10011
- y: radius / 1.66
10339
+ y: radius / TriangleDrawer_yFactor
10012
10340
  };
10013
10341
  }
10014
10342
  getSidesCount() {
10015
- return 3;
10343
+ return TriangleDrawer_sides;
10016
10344
  }
10017
10345
  getSidesData(particle, radius) {
10346
+ const diameter = radius * TriangleDrawer_double;
10018
10347
  return {
10019
10348
  count: {
10020
10349
  denominator: 2,
10021
10350
  numerator: 3
10022
10351
  },
10023
- length: radius * 2
10352
+ length: diameter
10024
10353
  };
10025
10354
  }
10026
10355
  }
@@ -10092,38 +10421,10 @@ class Rotate extends ValueWithRandom {
10092
10421
  ;// CONCATENATED MODULE: ../../updaters/rotate/dist/browser/RotateUpdater.js
10093
10422
 
10094
10423
 
10095
- function updateRotate(particle, delta) {
10096
- const rotate = particle.rotate,
10097
- rotateOptions = particle.options.rotate;
10098
- if (!rotate || !rotateOptions) {
10099
- return;
10100
- }
10101
- const rotateAnimation = rotateOptions.animation,
10102
- speed = (rotate.velocity ?? 0) * delta.factor,
10103
- max = 2 * Math.PI,
10104
- decay = rotate.decay ?? 1;
10105
- if (!rotateAnimation.enable) {
10106
- return;
10107
- }
10108
- switch (rotate.status) {
10109
- case "increasing":
10110
- rotate.value += speed;
10111
- if (rotate.value > max) {
10112
- rotate.value -= max;
10113
- }
10114
- break;
10115
- case "decreasing":
10116
- default:
10117
- rotate.value -= speed;
10118
- if (rotate.value < 0) {
10119
- rotate.value += max;
10120
- }
10121
- break;
10122
- }
10123
- if (rotate.velocity && decay !== 1) {
10124
- rotate.velocity *= decay;
10125
- }
10126
- }
10424
+ const RotateUpdater_double = 2,
10425
+ RotateUpdater_doublePI = Math.PI * RotateUpdater_double,
10426
+ RotateUpdater_identity = 1,
10427
+ doublePIDeg = 360;
10127
10428
  class RotateUpdater {
10128
10429
  constructor(container) {
10129
10430
  this.container = container;
@@ -10135,13 +10436,16 @@ class RotateUpdater {
10135
10436
  }
10136
10437
  particle.rotate = {
10137
10438
  enable: rotateOptions.animation.enable,
10138
- value: getRangeValue(rotateOptions.value) * Math.PI / 180
10439
+ value: degToRad(getRangeValue(rotateOptions.value)),
10440
+ min: 0,
10441
+ max: RotateUpdater_doublePI
10139
10442
  };
10140
10443
  particle.pathRotation = rotateOptions.path;
10141
10444
  let rotateDirection = rotateOptions.direction;
10142
10445
  if (rotateDirection === "random") {
10143
- const index = Math.floor(getRandom() * 2);
10144
- rotateDirection = index > 0 ? "counter-clockwise" : "clockwise";
10446
+ const index = Math.floor(getRandom() * RotateUpdater_double),
10447
+ minIndex = 0;
10448
+ rotateDirection = index > minIndex ? "counter-clockwise" : "clockwise";
10145
10449
  }
10146
10450
  switch (rotateDirection) {
10147
10451
  case "counter-clockwise":
@@ -10154,8 +10458,8 @@ class RotateUpdater {
10154
10458
  }
10155
10459
  const rotateAnimation = rotateOptions.animation;
10156
10460
  if (rotateAnimation.enable) {
10157
- particle.rotate.decay = 1 - getRangeValue(rotateAnimation.decay);
10158
- particle.rotate.velocity = getRangeValue(rotateAnimation.speed) / 360 * this.container.retina.reduceFactor;
10461
+ particle.rotate.decay = RotateUpdater_identity - getRangeValue(rotateAnimation.decay);
10462
+ particle.rotate.velocity = getRangeValue(rotateAnimation.speed) / doublePIDeg * this.container.retina.reduceFactor;
10159
10463
  if (!rotateAnimation.sync) {
10160
10464
  particle.rotate.velocity *= getRandom();
10161
10465
  }
@@ -10181,8 +10485,11 @@ class RotateUpdater {
10181
10485
  if (!this.isEnabled(particle)) {
10182
10486
  return;
10183
10487
  }
10184
- updateRotate(particle, delta);
10185
- particle.rotation = particle.rotate?.value ?? 0;
10488
+ if (!particle.rotate) {
10489
+ return;
10490
+ }
10491
+ updateAnimation(particle, particle.rotate, false, "none", delta);
10492
+ particle.rotation = particle.rotate.value;
10186
10493
  }
10187
10494
  }
10188
10495
  ;// CONCATENATED MODULE: ../../updaters/rotate/dist/browser/index.js
@@ -10191,7 +10498,10 @@ async function loadRotateUpdater(engine, refresh = true) {
10191
10498
  await engine.addParticleUpdater("rotate", container => new RotateUpdater(container), refresh);
10192
10499
  }
10193
10500
  ;// CONCATENATED MODULE: ../../shapes/square/dist/browser/SquareDrawer.js
10194
- const fixFactor = Math.sqrt(2);
10501
+ const fixFactorSquared = 2,
10502
+ fixFactor = Math.sqrt(fixFactorSquared),
10503
+ SquareDrawer_sides = 4,
10504
+ SquareDrawer_double = 2;
10195
10505
  class SquareDrawer {
10196
10506
  draw(data) {
10197
10507
  const {
@@ -10199,11 +10509,11 @@ class SquareDrawer {
10199
10509
  radius
10200
10510
  } = data,
10201
10511
  fixedRadius = radius / fixFactor,
10202
- fixedDiameter = fixedRadius * 2;
10512
+ fixedDiameter = fixedRadius * SquareDrawer_double;
10203
10513
  context.rect(-fixedRadius, -fixedRadius, fixedDiameter, fixedDiameter);
10204
10514
  }
10205
10515
  getSidesCount() {
10206
- return 4;
10516
+ return SquareDrawer_sides;
10207
10517
  }
10208
10518
  }
10209
10519
  ;// CONCATENATED MODULE: ../../shapes/square/dist/browser/index.js
@@ -10213,6 +10523,12 @@ async function loadSquareShape(engine, refresh = true) {
10213
10523
  }
10214
10524
  ;// CONCATENATED MODULE: ../../shapes/star/dist/browser/StarDrawer.js
10215
10525
 
10526
+ const defaultInset = 2,
10527
+ StarDrawer_origin = {
10528
+ x: 0,
10529
+ y: 0
10530
+ },
10531
+ StarDrawer_defaultSides = 5;
10216
10532
  class StarDrawer {
10217
10533
  draw(data) {
10218
10534
  const {
@@ -10221,22 +10537,22 @@ class StarDrawer {
10221
10537
  radius
10222
10538
  } = data,
10223
10539
  sides = particle.sides,
10224
- inset = particle.starInset ?? 2;
10225
- context.moveTo(0, 0 - radius);
10540
+ inset = particle.starInset ?? defaultInset;
10541
+ context.moveTo(StarDrawer_origin.x, StarDrawer_origin.y - radius);
10226
10542
  for (let i = 0; i < sides; i++) {
10227
10543
  context.rotate(Math.PI / sides);
10228
- context.lineTo(0, 0 - radius * inset);
10544
+ context.lineTo(StarDrawer_origin.x, StarDrawer_origin.y - radius * inset);
10229
10545
  context.rotate(Math.PI / sides);
10230
- context.lineTo(0, 0 - radius);
10546
+ context.lineTo(StarDrawer_origin.x, StarDrawer_origin.y - radius);
10231
10547
  }
10232
10548
  }
10233
10549
  getSidesCount(particle) {
10234
10550
  const star = particle.shapeData;
10235
- return Math.round(getRangeValue(star?.sides ?? 5));
10551
+ return Math.round(getRangeValue(star?.sides ?? StarDrawer_defaultSides));
10236
10552
  }
10237
10553
  particleInit(container, particle) {
10238
10554
  const star = particle.shapeData;
10239
- particle.starInset = getRangeValue(star?.inset ?? 2);
10555
+ particle.starInset = getRangeValue(star?.inset ?? defaultInset);
10240
10556
  }
10241
10557
  }
10242
10558
  ;// CONCATENATED MODULE: ../../shapes/star/dist/browser/index.js
@@ -10244,81 +10560,9 @@ class StarDrawer {
10244
10560
  async function loadStarShape(engine, refresh = true) {
10245
10561
  await engine.addShape("star", new StarDrawer(), refresh);
10246
10562
  }
10247
- ;// CONCATENATED MODULE: ../../updaters/strokeColor/dist/browser/Utils.js
10248
-
10249
- function Utils_updateColorValue(delta, colorValue, valueAnimation, max, decrease) {
10250
- if (!colorValue || !valueAnimation.enable || (colorValue.maxLoops ?? 0) > 0 && (colorValue.loops ?? 0) > (colorValue.maxLoops ?? 0)) {
10251
- return;
10252
- }
10253
- if (!colorValue.time) {
10254
- colorValue.time = 0;
10255
- }
10256
- if ((colorValue.delayTime ?? 0) > 0 && colorValue.time < (colorValue.delayTime ?? 0)) {
10257
- colorValue.time += delta.value;
10258
- }
10259
- if ((colorValue.delayTime ?? 0) > 0 && colorValue.time < (colorValue.delayTime ?? 0)) {
10260
- return;
10261
- }
10262
- const offset = randomInRange(valueAnimation.offset),
10263
- velocity = (colorValue.velocity ?? 0) * delta.factor + offset * 3.6,
10264
- decay = colorValue.decay ?? 1;
10265
- if (!decrease || colorValue.status === "increasing") {
10266
- colorValue.value += velocity;
10267
- if (colorValue.value > max) {
10268
- if (!colorValue.loops) {
10269
- colorValue.loops = 0;
10270
- }
10271
- colorValue.loops++;
10272
- if (decrease) {
10273
- colorValue.status = "decreasing";
10274
- colorValue.value -= colorValue.value % max;
10275
- }
10276
- }
10277
- } else {
10278
- colorValue.value -= velocity;
10279
- if (colorValue.value < 0) {
10280
- if (!colorValue.loops) {
10281
- colorValue.loops = 0;
10282
- }
10283
- colorValue.loops++;
10284
- colorValue.status = "increasing";
10285
- colorValue.value += colorValue.value;
10286
- }
10287
- }
10288
- if (colorValue.velocity && decay !== 1) {
10289
- colorValue.velocity *= decay;
10290
- }
10291
- if (colorValue.value > max) {
10292
- colorValue.value %= max;
10293
- }
10294
- }
10295
- function updateStrokeColor(particle, delta) {
10296
- if (!particle.strokeColor || !particle.strokeAnimation) {
10297
- return;
10298
- }
10299
- const {
10300
- h,
10301
- s,
10302
- l
10303
- } = particle.strokeColor,
10304
- {
10305
- h: hAnimation,
10306
- s: sAnimation,
10307
- l: lAnimation
10308
- } = particle.strokeAnimation;
10309
- if (h) {
10310
- Utils_updateColorValue(delta, h, hAnimation, 360, false);
10311
- }
10312
- if (s) {
10313
- Utils_updateColorValue(delta, s, sAnimation, 100, true);
10314
- }
10315
- if (l) {
10316
- Utils_updateColorValue(delta, l, lAnimation, 100, true);
10317
- }
10318
- }
10319
10563
  ;// CONCATENATED MODULE: ../../updaters/strokeColor/dist/browser/StrokeColorUpdater.js
10320
10564
 
10321
-
10565
+ const StrokeColorUpdater_defaultOpacity = 1;
10322
10566
  class StrokeColorUpdater {
10323
10567
  constructor(container) {
10324
10568
  this.container = container;
@@ -10328,7 +10572,7 @@ class StrokeColorUpdater {
10328
10572
  options = particle.options;
10329
10573
  const stroke = itemFromSingleOrMultiple(options.stroke, particle.id, options.reduceDuplicates);
10330
10574
  particle.strokeWidth = getRangeValue(stroke.width) * container.retina.pixelRatio;
10331
- particle.strokeOpacity = getRangeValue(stroke.opacity ?? 1);
10575
+ particle.strokeOpacity = getRangeValue(stroke.opacity ?? StrokeColorUpdater_defaultOpacity);
10332
10576
  particle.strokeAnimation = stroke.color?.animation;
10333
10577
  const strokeHslColor = rangeColorToHsl(stroke.color) ?? particle.getFillColor();
10334
10578
  if (strokeHslColor) {
@@ -10346,7 +10590,7 @@ class StrokeColorUpdater {
10346
10590
  if (!this.isEnabled(particle)) {
10347
10591
  return;
10348
10592
  }
10349
- updateStrokeColor(particle, delta);
10593
+ updateColor(particle.strokeColor, delta);
10350
10594
  }
10351
10595
  }
10352
10596
  ;// CONCATENATED MODULE: ../../updaters/strokeColor/dist/browser/index.js
@@ -10410,7 +10654,7 @@ async function loadSlim(engine, refresh = true) {
10410
10654
  ;// CONCATENATED MODULE: ./dist/browser/bundle.js
10411
10655
 
10412
10656
 
10413
- loadSlim(tsParticles);
10657
+ void loadSlim(tsParticles);
10414
10658
 
10415
10659
 
10416
10660
  /******/ return __webpack_exports__;