UNPKG

599 kBJavaScriptView Raw
1/*!
2 * Author : Matteo Bruni
3 * MIT license: https://opensource.org/licenses/MIT
4 * Demo / Generator : https://particles.js.org/
5 * GitHub : https://www.github.com/matteobruni/tsparticles
6 * How to use? : Check the GitHub README
7 * v2.12.0
8 */
9(function webpackUniversalModuleDefinition(root, factory) {
10 if(typeof exports === 'object' && typeof module === 'object')
11 module.exports = factory();
12 else if(typeof define === 'function' && define.amd)
13 define([], factory);
14 else {
15 var a = factory();
16 for(var i in a) (typeof exports === 'object' ? exports : root)[i] = a[i];
17 }
18})(this, () => {
19return /******/ (() => { // webpackBootstrap
20/******/ "use strict";
21/******/ var __webpack_modules__ = ({
22
23/***/ 442:
24/***/ (() => {
25
26
27
28(function () {
29 "use strict";
30
31 try {
32 if (typeof window === "undefined") return;
33 if (!("SVGPathSeg" in window)) {
34 window.SVGPathSeg = function (type, typeAsLetter, owningPathSegList) {
35 this.pathSegType = type;
36 this.pathSegTypeAsLetter = typeAsLetter;
37 this._owningPathSegList = owningPathSegList;
38 };
39 window.SVGPathSeg.prototype.classname = "SVGPathSeg";
40 window.SVGPathSeg.PATHSEG_UNKNOWN = 0;
41 window.SVGPathSeg.PATHSEG_CLOSEPATH = 1;
42 window.SVGPathSeg.PATHSEG_MOVETO_ABS = 2;
43 window.SVGPathSeg.PATHSEG_MOVETO_REL = 3;
44 window.SVGPathSeg.PATHSEG_LINETO_ABS = 4;
45 window.SVGPathSeg.PATHSEG_LINETO_REL = 5;
46 window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_ABS = 6;
47 window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_REL = 7;
48 window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_ABS = 8;
49 window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_REL = 9;
50 window.SVGPathSeg.PATHSEG_ARC_ABS = 10;
51 window.SVGPathSeg.PATHSEG_ARC_REL = 11;
52 window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_ABS = 12;
53 window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_REL = 13;
54 window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_ABS = 14;
55 window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_REL = 15;
56 window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_ABS = 16;
57 window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_REL = 17;
58 window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_ABS = 18;
59 window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_REL = 19;
60 window.SVGPathSeg.prototype._segmentChanged = function () {
61 if (this._owningPathSegList) this._owningPathSegList.segmentChanged(this);
62 };
63 window.SVGPathSegClosePath = function (owningPathSegList) {
64 window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_CLOSEPATH, "z", owningPathSegList);
65 };
66 window.SVGPathSegClosePath.prototype = Object.create(window.SVGPathSeg.prototype);
67 window.SVGPathSegClosePath.prototype.toString = function () {
68 return "[object SVGPathSegClosePath]";
69 };
70 window.SVGPathSegClosePath.prototype._asPathString = function () {
71 return this.pathSegTypeAsLetter;
72 };
73 window.SVGPathSegClosePath.prototype.clone = function () {
74 return new window.SVGPathSegClosePath(undefined);
75 };
76 window.SVGPathSegMovetoAbs = function (owningPathSegList, x, y) {
77 window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_MOVETO_ABS, "M", owningPathSegList);
78 this._x = x;
79 this._y = y;
80 };
81 window.SVGPathSegMovetoAbs.prototype = Object.create(window.SVGPathSeg.prototype);
82 window.SVGPathSegMovetoAbs.prototype.toString = function () {
83 return "[object SVGPathSegMovetoAbs]";
84 };
85 window.SVGPathSegMovetoAbs.prototype._asPathString = function () {
86 return `${this.pathSegTypeAsLetter} ${this._x} ${this._y}`;
87 };
88 window.SVGPathSegMovetoAbs.prototype.clone = function () {
89 return new window.SVGPathSegMovetoAbs(undefined, this._x, this._y);
90 };
91 Object.defineProperty(window.SVGPathSegMovetoAbs.prototype, "x", {
92 get: function () {
93 return this._x;
94 },
95 set: function (x) {
96 this._x = x;
97 this._segmentChanged();
98 },
99 enumerable: true
100 });
101 Object.defineProperty(window.SVGPathSegMovetoAbs.prototype, "y", {
102 get: function () {
103 return this._y;
104 },
105 set: function (y) {
106 this._y = y;
107 this._segmentChanged();
108 },
109 enumerable: true
110 });
111 window.SVGPathSegMovetoRel = function (owningPathSegList, x, y) {
112 window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_MOVETO_REL, "m", owningPathSegList);
113 this._x = x;
114 this._y = y;
115 };
116 window.SVGPathSegMovetoRel.prototype = Object.create(window.SVGPathSeg.prototype);
117 window.SVGPathSegMovetoRel.prototype.toString = function () {
118 return "[object SVGPathSegMovetoRel]";
119 };
120 window.SVGPathSegMovetoRel.prototype._asPathString = function () {
121 return `${this.pathSegTypeAsLetter} ${this._x} ${this._y}`;
122 };
123 window.SVGPathSegMovetoRel.prototype.clone = function () {
124 return new window.SVGPathSegMovetoRel(undefined, this._x, this._y);
125 };
126 Object.defineProperty(window.SVGPathSegMovetoRel.prototype, "x", {
127 get: function () {
128 return this._x;
129 },
130 set: function (x) {
131 this._x = x;
132 this._segmentChanged();
133 },
134 enumerable: true
135 });
136 Object.defineProperty(window.SVGPathSegMovetoRel.prototype, "y", {
137 get: function () {
138 return this._y;
139 },
140 set: function (y) {
141 this._y = y;
142 this._segmentChanged();
143 },
144 enumerable: true
145 });
146 window.SVGPathSegLinetoAbs = function (owningPathSegList, x, y) {
147 window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_LINETO_ABS, "L", owningPathSegList);
148 this._x = x;
149 this._y = y;
150 };
151 window.SVGPathSegLinetoAbs.prototype = Object.create(window.SVGPathSeg.prototype);
152 window.SVGPathSegLinetoAbs.prototype.toString = function () {
153 return "[object SVGPathSegLinetoAbs]";
154 };
155 window.SVGPathSegLinetoAbs.prototype._asPathString = function () {
156 return `${this.pathSegTypeAsLetter} ${this._x} ${this._y}`;
157 };
158 window.SVGPathSegLinetoAbs.prototype.clone = function () {
159 return new window.SVGPathSegLinetoAbs(undefined, this._x, this._y);
160 };
161 Object.defineProperty(window.SVGPathSegLinetoAbs.prototype, "x", {
162 get: function () {
163 return this._x;
164 },
165 set: function (x) {
166 this._x = x;
167 this._segmentChanged();
168 },
169 enumerable: true
170 });
171 Object.defineProperty(window.SVGPathSegLinetoAbs.prototype, "y", {
172 get: function () {
173 return this._y;
174 },
175 set: function (y) {
176 this._y = y;
177 this._segmentChanged();
178 },
179 enumerable: true
180 });
181 window.SVGPathSegLinetoRel = function (owningPathSegList, x, y) {
182 window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_LINETO_REL, "l", owningPathSegList);
183 this._x = x;
184 this._y = y;
185 };
186 window.SVGPathSegLinetoRel.prototype = Object.create(window.SVGPathSeg.prototype);
187 window.SVGPathSegLinetoRel.prototype.toString = function () {
188 return "[object SVGPathSegLinetoRel]";
189 };
190 window.SVGPathSegLinetoRel.prototype._asPathString = function () {
191 return `${this.pathSegTypeAsLetter} ${this._x} ${this._y}`;
192 };
193 window.SVGPathSegLinetoRel.prototype.clone = function () {
194 return new window.SVGPathSegLinetoRel(undefined, this._x, this._y);
195 };
196 Object.defineProperty(window.SVGPathSegLinetoRel.prototype, "x", {
197 get: function () {
198 return this._x;
199 },
200 set: function (x) {
201 this._x = x;
202 this._segmentChanged();
203 },
204 enumerable: true
205 });
206 Object.defineProperty(window.SVGPathSegLinetoRel.prototype, "y", {
207 get: function () {
208 return this._y;
209 },
210 set: function (y) {
211 this._y = y;
212 this._segmentChanged();
213 },
214 enumerable: true
215 });
216 window.SVGPathSegCurvetoCubicAbs = function (owningPathSegList, x, y, x1, y1, x2, y2) {
217 window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_ABS, "C", owningPathSegList);
218 this._x = x;
219 this._y = y;
220 this._x1 = x1;
221 this._y1 = y1;
222 this._x2 = x2;
223 this._y2 = y2;
224 };
225 window.SVGPathSegCurvetoCubicAbs.prototype = Object.create(window.SVGPathSeg.prototype);
226 window.SVGPathSegCurvetoCubicAbs.prototype.toString = function () {
227 return "[object SVGPathSegCurvetoCubicAbs]";
228 };
229 window.SVGPathSegCurvetoCubicAbs.prototype._asPathString = function () {
230 return `${this.pathSegTypeAsLetter} ${this._x1} ${this._y1} ${this._x2} ${this._y2} ${this._x} ${this._y}`;
231 };
232 window.SVGPathSegCurvetoCubicAbs.prototype.clone = function () {
233 return new window.SVGPathSegCurvetoCubicAbs(undefined, this._x, this._y, this._x1, this._y1, this._x2, this._y2);
234 };
235 Object.defineProperty(window.SVGPathSegCurvetoCubicAbs.prototype, "x", {
236 get: function () {
237 return this._x;
238 },
239 set: function (x) {
240 this._x = x;
241 this._segmentChanged();
242 },
243 enumerable: true
244 });
245 Object.defineProperty(window.SVGPathSegCurvetoCubicAbs.prototype, "y", {
246 get: function () {
247 return this._y;
248 },
249 set: function (y) {
250 this._y = y;
251 this._segmentChanged();
252 },
253 enumerable: true
254 });
255 Object.defineProperty(window.SVGPathSegCurvetoCubicAbs.prototype, "x1", {
256 get: function () {
257 return this._x1;
258 },
259 set: function (x1) {
260 this._x1 = x1;
261 this._segmentChanged();
262 },
263 enumerable: true
264 });
265 Object.defineProperty(window.SVGPathSegCurvetoCubicAbs.prototype, "y1", {
266 get: function () {
267 return this._y1;
268 },
269 set: function (y1) {
270 this._y1 = y1;
271 this._segmentChanged();
272 },
273 enumerable: true
274 });
275 Object.defineProperty(window.SVGPathSegCurvetoCubicAbs.prototype, "x2", {
276 get: function () {
277 return this._x2;
278 },
279 set: function (x2) {
280 this._x2 = x2;
281 this._segmentChanged();
282 },
283 enumerable: true
284 });
285 Object.defineProperty(window.SVGPathSegCurvetoCubicAbs.prototype, "y2", {
286 get: function () {
287 return this._y2;
288 },
289 set: function (y2) {
290 this._y2 = y2;
291 this._segmentChanged();
292 },
293 enumerable: true
294 });
295 window.SVGPathSegCurvetoCubicRel = function (owningPathSegList, x, y, x1, y1, x2, y2) {
296 window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_REL, "c", owningPathSegList);
297 this._x = x;
298 this._y = y;
299 this._x1 = x1;
300 this._y1 = y1;
301 this._x2 = x2;
302 this._y2 = y2;
303 };
304 window.SVGPathSegCurvetoCubicRel.prototype = Object.create(window.SVGPathSeg.prototype);
305 window.SVGPathSegCurvetoCubicRel.prototype.toString = function () {
306 return "[object SVGPathSegCurvetoCubicRel]";
307 };
308 window.SVGPathSegCurvetoCubicRel.prototype._asPathString = function () {
309 return `${this.pathSegTypeAsLetter} ${this._x1} ${this._y1} ${this._x2} ${this._y2} ${this._x} ${this._y}`;
310 };
311 window.SVGPathSegCurvetoCubicRel.prototype.clone = function () {
312 return new window.SVGPathSegCurvetoCubicRel(undefined, this._x, this._y, this._x1, this._y1, this._x2, this._y2);
313 };
314 Object.defineProperty(window.SVGPathSegCurvetoCubicRel.prototype, "x", {
315 get: function () {
316 return this._x;
317 },
318 set: function (x) {
319 this._x = x;
320 this._segmentChanged();
321 },
322 enumerable: true
323 });
324 Object.defineProperty(window.SVGPathSegCurvetoCubicRel.prototype, "y", {
325 get: function () {
326 return this._y;
327 },
328 set: function (y) {
329 this._y = y;
330 this._segmentChanged();
331 },
332 enumerable: true
333 });
334 Object.defineProperty(window.SVGPathSegCurvetoCubicRel.prototype, "x1", {
335 get: function () {
336 return this._x1;
337 },
338 set: function (x1) {
339 this._x1 = x1;
340 this._segmentChanged();
341 },
342 enumerable: true
343 });
344 Object.defineProperty(window.SVGPathSegCurvetoCubicRel.prototype, "y1", {
345 get: function () {
346 return this._y1;
347 },
348 set: function (y1) {
349 this._y1 = y1;
350 this._segmentChanged();
351 },
352 enumerable: true
353 });
354 Object.defineProperty(window.SVGPathSegCurvetoCubicRel.prototype, "x2", {
355 get: function () {
356 return this._x2;
357 },
358 set: function (x2) {
359 this._x2 = x2;
360 this._segmentChanged();
361 },
362 enumerable: true
363 });
364 Object.defineProperty(window.SVGPathSegCurvetoCubicRel.prototype, "y2", {
365 get: function () {
366 return this._y2;
367 },
368 set: function (y2) {
369 this._y2 = y2;
370 this._segmentChanged();
371 },
372 enumerable: true
373 });
374 window.SVGPathSegCurvetoQuadraticAbs = function (owningPathSegList, x, y, x1, y1) {
375 window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_ABS, "Q", owningPathSegList);
376 this._x = x;
377 this._y = y;
378 this._x1 = x1;
379 this._y1 = y1;
380 };
381 window.SVGPathSegCurvetoQuadraticAbs.prototype = Object.create(window.SVGPathSeg.prototype);
382 window.SVGPathSegCurvetoQuadraticAbs.prototype.toString = function () {
383 return "[object SVGPathSegCurvetoQuadraticAbs]";
384 };
385 window.SVGPathSegCurvetoQuadraticAbs.prototype._asPathString = function () {
386 return `${this.pathSegTypeAsLetter} ${this._x1} ${this._y1} ${this._x} ${this._y}`;
387 };
388 window.SVGPathSegCurvetoQuadraticAbs.prototype.clone = function () {
389 return new window.SVGPathSegCurvetoQuadraticAbs(undefined, this._x, this._y, this._x1, this._y1);
390 };
391 Object.defineProperty(window.SVGPathSegCurvetoQuadraticAbs.prototype, "x", {
392 get: function () {
393 return this._x;
394 },
395 set: function (x) {
396 this._x = x;
397 this._segmentChanged();
398 },
399 enumerable: true
400 });
401 Object.defineProperty(window.SVGPathSegCurvetoQuadraticAbs.prototype, "y", {
402 get: function () {
403 return this._y;
404 },
405 set: function (y) {
406 this._y = y;
407 this._segmentChanged();
408 },
409 enumerable: true
410 });
411 Object.defineProperty(window.SVGPathSegCurvetoQuadraticAbs.prototype, "x1", {
412 get: function () {
413 return this._x1;
414 },
415 set: function (x1) {
416 this._x1 = x1;
417 this._segmentChanged();
418 },
419 enumerable: true
420 });
421 Object.defineProperty(window.SVGPathSegCurvetoQuadraticAbs.prototype, "y1", {
422 get: function () {
423 return this._y1;
424 },
425 set: function (y1) {
426 this._y1 = y1;
427 this._segmentChanged();
428 },
429 enumerable: true
430 });
431 window.SVGPathSegCurvetoQuadraticRel = function (owningPathSegList, x, y, x1, y1) {
432 window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_REL, "q", owningPathSegList);
433 this._x = x;
434 this._y = y;
435 this._x1 = x1;
436 this._y1 = y1;
437 };
438 window.SVGPathSegCurvetoQuadraticRel.prototype = Object.create(window.SVGPathSeg.prototype);
439 window.SVGPathSegCurvetoQuadraticRel.prototype.toString = function () {
440 return "[object SVGPathSegCurvetoQuadraticRel]";
441 };
442 window.SVGPathSegCurvetoQuadraticRel.prototype._asPathString = function () {
443 return `${this.pathSegTypeAsLetter} ${this._x1} ${this._y1} ${this._x} ${this._y}`;
444 };
445 window.SVGPathSegCurvetoQuadraticRel.prototype.clone = function () {
446 return new window.SVGPathSegCurvetoQuadraticRel(undefined, this._x, this._y, this._x1, this._y1);
447 };
448 Object.defineProperty(window.SVGPathSegCurvetoQuadraticRel.prototype, "x", {
449 get: function () {
450 return this._x;
451 },
452 set: function (x) {
453 this._x = x;
454 this._segmentChanged();
455 },
456 enumerable: true
457 });
458 Object.defineProperty(window.SVGPathSegCurvetoQuadraticRel.prototype, "y", {
459 get: function () {
460 return this._y;
461 },
462 set: function (y) {
463 this._y = y;
464 this._segmentChanged();
465 },
466 enumerable: true
467 });
468 Object.defineProperty(window.SVGPathSegCurvetoQuadraticRel.prototype, "x1", {
469 get: function () {
470 return this._x1;
471 },
472 set: function (x1) {
473 this._x1 = x1;
474 this._segmentChanged();
475 },
476 enumerable: true
477 });
478 Object.defineProperty(window.SVGPathSegCurvetoQuadraticRel.prototype, "y1", {
479 get: function () {
480 return this._y1;
481 },
482 set: function (y1) {
483 this._y1 = y1;
484 this._segmentChanged();
485 },
486 enumerable: true
487 });
488 window.SVGPathSegArcAbs = function (owningPathSegList, x, y, r1, r2, angle, largeArcFlag, sweepFlag) {
489 window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_ARC_ABS, "A", owningPathSegList);
490 this._x = x;
491 this._y = y;
492 this._r1 = r1;
493 this._r2 = r2;
494 this._angle = angle;
495 this._largeArcFlag = largeArcFlag;
496 this._sweepFlag = sweepFlag;
497 };
498 window.SVGPathSegArcAbs.prototype = Object.create(window.SVGPathSeg.prototype);
499 window.SVGPathSegArcAbs.prototype.toString = function () {
500 return "[object SVGPathSegArcAbs]";
501 };
502 window.SVGPathSegArcAbs.prototype._asPathString = function () {
503 return `${this.pathSegTypeAsLetter} ${this._r1} ${this._r2} ${this._angle} ${this._largeArcFlag ? "1" : "0"} ${this._sweepFlag ? "1" : "0"} ${this._x} ${this._y}`;
504 };
505 window.SVGPathSegArcAbs.prototype.clone = function () {
506 return new window.SVGPathSegArcAbs(undefined, this._x, this._y, this._r1, this._r2, this._angle, this._largeArcFlag, this._sweepFlag);
507 };
508 Object.defineProperty(window.SVGPathSegArcAbs.prototype, "x", {
509 get: function () {
510 return this._x;
511 },
512 set: function (x) {
513 this._x = x;
514 this._segmentChanged();
515 },
516 enumerable: true
517 });
518 Object.defineProperty(window.SVGPathSegArcAbs.prototype, "y", {
519 get: function () {
520 return this._y;
521 },
522 set: function (y) {
523 this._y = y;
524 this._segmentChanged();
525 },
526 enumerable: true
527 });
528 Object.defineProperty(window.SVGPathSegArcAbs.prototype, "r1", {
529 get: function () {
530 return this._r1;
531 },
532 set: function (r1) {
533 this._r1 = r1;
534 this._segmentChanged();
535 },
536 enumerable: true
537 });
538 Object.defineProperty(window.SVGPathSegArcAbs.prototype, "r2", {
539 get: function () {
540 return this._r2;
541 },
542 set: function (r2) {
543 this._r2 = r2;
544 this._segmentChanged();
545 },
546 enumerable: true
547 });
548 Object.defineProperty(window.SVGPathSegArcAbs.prototype, "angle", {
549 get: function () {
550 return this._angle;
551 },
552 set: function (angle) {
553 this._angle = angle;
554 this._segmentChanged();
555 },
556 enumerable: true
557 });
558 Object.defineProperty(window.SVGPathSegArcAbs.prototype, "largeArcFlag", {
559 get: function () {
560 return this._largeArcFlag;
561 },
562 set: function (largeArcFlag) {
563 this._largeArcFlag = largeArcFlag;
564 this._segmentChanged();
565 },
566 enumerable: true
567 });
568 Object.defineProperty(window.SVGPathSegArcAbs.prototype, "sweepFlag", {
569 get: function () {
570 return this._sweepFlag;
571 },
572 set: function (sweepFlag) {
573 this._sweepFlag = sweepFlag;
574 this._segmentChanged();
575 },
576 enumerable: true
577 });
578 window.SVGPathSegArcRel = function (owningPathSegList, x, y, r1, r2, angle, largeArcFlag, sweepFlag) {
579 window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_ARC_REL, "a", owningPathSegList);
580 this._x = x;
581 this._y = y;
582 this._r1 = r1;
583 this._r2 = r2;
584 this._angle = angle;
585 this._largeArcFlag = largeArcFlag;
586 this._sweepFlag = sweepFlag;
587 };
588 window.SVGPathSegArcRel.prototype = Object.create(window.SVGPathSeg.prototype);
589 window.SVGPathSegArcRel.prototype.toString = function () {
590 return "[object SVGPathSegArcRel]";
591 };
592 window.SVGPathSegArcRel.prototype._asPathString = function () {
593 return `${this.pathSegTypeAsLetter} ${this._r1} ${this._r2} ${this._angle} ${this._largeArcFlag ? "1" : "0"} ${this._sweepFlag ? "1" : "0"} ${this._x} ${this._y}`;
594 };
595 window.SVGPathSegArcRel.prototype.clone = function () {
596 return new window.SVGPathSegArcRel(undefined, this._x, this._y, this._r1, this._r2, this._angle, this._largeArcFlag, this._sweepFlag);
597 };
598 Object.defineProperty(window.SVGPathSegArcRel.prototype, "x", {
599 get: function () {
600 return this._x;
601 },
602 set: function (x) {
603 this._x = x;
604 this._segmentChanged();
605 },
606 enumerable: true
607 });
608 Object.defineProperty(window.SVGPathSegArcRel.prototype, "y", {
609 get: function () {
610 return this._y;
611 },
612 set: function (y) {
613 this._y = y;
614 this._segmentChanged();
615 },
616 enumerable: true
617 });
618 Object.defineProperty(window.SVGPathSegArcRel.prototype, "r1", {
619 get: function () {
620 return this._r1;
621 },
622 set: function (r1) {
623 this._r1 = r1;
624 this._segmentChanged();
625 },
626 enumerable: true
627 });
628 Object.defineProperty(window.SVGPathSegArcRel.prototype, "r2", {
629 get: function () {
630 return this._r2;
631 },
632 set: function (r2) {
633 this._r2 = r2;
634 this._segmentChanged();
635 },
636 enumerable: true
637 });
638 Object.defineProperty(window.SVGPathSegArcRel.prototype, "angle", {
639 get: function () {
640 return this._angle;
641 },
642 set: function (angle) {
643 this._angle = angle;
644 this._segmentChanged();
645 },
646 enumerable: true
647 });
648 Object.defineProperty(window.SVGPathSegArcRel.prototype, "largeArcFlag", {
649 get: function () {
650 return this._largeArcFlag;
651 },
652 set: function (largeArcFlag) {
653 this._largeArcFlag = largeArcFlag;
654 this._segmentChanged();
655 },
656 enumerable: true
657 });
658 Object.defineProperty(window.SVGPathSegArcRel.prototype, "sweepFlag", {
659 get: function () {
660 return this._sweepFlag;
661 },
662 set: function (sweepFlag) {
663 this._sweepFlag = sweepFlag;
664 this._segmentChanged();
665 },
666 enumerable: true
667 });
668 window.SVGPathSegLinetoHorizontalAbs = function (owningPathSegList, x) {
669 window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_ABS, "H", owningPathSegList);
670 this._x = x;
671 };
672 window.SVGPathSegLinetoHorizontalAbs.prototype = Object.create(window.SVGPathSeg.prototype);
673 window.SVGPathSegLinetoHorizontalAbs.prototype.toString = function () {
674 return "[object SVGPathSegLinetoHorizontalAbs]";
675 };
676 window.SVGPathSegLinetoHorizontalAbs.prototype._asPathString = function () {
677 return `${this.pathSegTypeAsLetter} ${this._x}`;
678 };
679 window.SVGPathSegLinetoHorizontalAbs.prototype.clone = function () {
680 return new window.SVGPathSegLinetoHorizontalAbs(undefined, this._x);
681 };
682 Object.defineProperty(window.SVGPathSegLinetoHorizontalAbs.prototype, "x", {
683 get: function () {
684 return this._x;
685 },
686 set: function (x) {
687 this._x = x;
688 this._segmentChanged();
689 },
690 enumerable: true
691 });
692 window.SVGPathSegLinetoHorizontalRel = function (owningPathSegList, x) {
693 window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_REL, "h", owningPathSegList);
694 this._x = x;
695 };
696 window.SVGPathSegLinetoHorizontalRel.prototype = Object.create(window.SVGPathSeg.prototype);
697 window.SVGPathSegLinetoHorizontalRel.prototype.toString = function () {
698 return "[object SVGPathSegLinetoHorizontalRel]";
699 };
700 window.SVGPathSegLinetoHorizontalRel.prototype._asPathString = function () {
701 return `${this.pathSegTypeAsLetter} ${this._x}`;
702 };
703 window.SVGPathSegLinetoHorizontalRel.prototype.clone = function () {
704 return new window.SVGPathSegLinetoHorizontalRel(undefined, this._x);
705 };
706 Object.defineProperty(window.SVGPathSegLinetoHorizontalRel.prototype, "x", {
707 get: function () {
708 return this._x;
709 },
710 set: function (x) {
711 this._x = x;
712 this._segmentChanged();
713 },
714 enumerable: true
715 });
716 window.SVGPathSegLinetoVerticalAbs = function (owningPathSegList, y) {
717 window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_ABS, "V", owningPathSegList);
718 this._y = y;
719 };
720 window.SVGPathSegLinetoVerticalAbs.prototype = Object.create(window.SVGPathSeg.prototype);
721 window.SVGPathSegLinetoVerticalAbs.prototype.toString = function () {
722 return "[object SVGPathSegLinetoVerticalAbs]";
723 };
724 window.SVGPathSegLinetoVerticalAbs.prototype._asPathString = function () {
725 return `${this.pathSegTypeAsLetter} ${this._y}`;
726 };
727 window.SVGPathSegLinetoVerticalAbs.prototype.clone = function () {
728 return new window.SVGPathSegLinetoVerticalAbs(undefined, this._y);
729 };
730 Object.defineProperty(window.SVGPathSegLinetoVerticalAbs.prototype, "y", {
731 get: function () {
732 return this._y;
733 },
734 set: function (y) {
735 this._y = y;
736 this._segmentChanged();
737 },
738 enumerable: true
739 });
740 window.SVGPathSegLinetoVerticalRel = function (owningPathSegList, y) {
741 window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_REL, "v", owningPathSegList);
742 this._y = y;
743 };
744 window.SVGPathSegLinetoVerticalRel.prototype = Object.create(window.SVGPathSeg.prototype);
745 window.SVGPathSegLinetoVerticalRel.prototype.toString = function () {
746 return "[object SVGPathSegLinetoVerticalRel]";
747 };
748 window.SVGPathSegLinetoVerticalRel.prototype._asPathString = function () {
749 return `${this.pathSegTypeAsLetter} ${this._y}`;
750 };
751 window.SVGPathSegLinetoVerticalRel.prototype.clone = function () {
752 return new window.SVGPathSegLinetoVerticalRel(undefined, this._y);
753 };
754 Object.defineProperty(window.SVGPathSegLinetoVerticalRel.prototype, "y", {
755 get: function () {
756 return this._y;
757 },
758 set: function (y) {
759 this._y = y;
760 this._segmentChanged();
761 },
762 enumerable: true
763 });
764 window.SVGPathSegCurvetoCubicSmoothAbs = function (owningPathSegList, x, y, x2, y2) {
765 window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_ABS, "S", owningPathSegList);
766 this._x = x;
767 this._y = y;
768 this._x2 = x2;
769 this._y2 = y2;
770 };
771 window.SVGPathSegCurvetoCubicSmoothAbs.prototype = Object.create(window.SVGPathSeg.prototype);
772 window.SVGPathSegCurvetoCubicSmoothAbs.prototype.toString = function () {
773 return "[object SVGPathSegCurvetoCubicSmoothAbs]";
774 };
775 window.SVGPathSegCurvetoCubicSmoothAbs.prototype._asPathString = function () {
776 return `${this.pathSegTypeAsLetter} ${this._x2} ${this._y2} ${this._x} ${this._y}`;
777 };
778 window.SVGPathSegCurvetoCubicSmoothAbs.prototype.clone = function () {
779 return new window.SVGPathSegCurvetoCubicSmoothAbs(undefined, this._x, this._y, this._x2, this._y2);
780 };
781 Object.defineProperty(window.SVGPathSegCurvetoCubicSmoothAbs.prototype, "x", {
782 get: function () {
783 return this._x;
784 },
785 set: function (x) {
786 this._x = x;
787 this._segmentChanged();
788 },
789 enumerable: true
790 });
791 Object.defineProperty(window.SVGPathSegCurvetoCubicSmoothAbs.prototype, "y", {
792 get: function () {
793 return this._y;
794 },
795 set: function (y) {
796 this._y = y;
797 this._segmentChanged();
798 },
799 enumerable: true
800 });
801 Object.defineProperty(window.SVGPathSegCurvetoCubicSmoothAbs.prototype, "x2", {
802 get: function () {
803 return this._x2;
804 },
805 set: function (x2) {
806 this._x2 = x2;
807 this._segmentChanged();
808 },
809 enumerable: true
810 });
811 Object.defineProperty(window.SVGPathSegCurvetoCubicSmoothAbs.prototype, "y2", {
812 get: function () {
813 return this._y2;
814 },
815 set: function (y2) {
816 this._y2 = y2;
817 this._segmentChanged();
818 },
819 enumerable: true
820 });
821 window.SVGPathSegCurvetoCubicSmoothRel = function (owningPathSegList, x, y, x2, y2) {
822 window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_REL, "s", owningPathSegList);
823 this._x = x;
824 this._y = y;
825 this._x2 = x2;
826 this._y2 = y2;
827 };
828 window.SVGPathSegCurvetoCubicSmoothRel.prototype = Object.create(window.SVGPathSeg.prototype);
829 window.SVGPathSegCurvetoCubicSmoothRel.prototype.toString = function () {
830 return "[object SVGPathSegCurvetoCubicSmoothRel]";
831 };
832 window.SVGPathSegCurvetoCubicSmoothRel.prototype._asPathString = function () {
833 return `${this.pathSegTypeAsLetter} ${this._x2} ${this._y2} ${this._x} ${this._y}`;
834 };
835 window.SVGPathSegCurvetoCubicSmoothRel.prototype.clone = function () {
836 return new window.SVGPathSegCurvetoCubicSmoothRel(undefined, this._x, this._y, this._x2, this._y2);
837 };
838 Object.defineProperty(window.SVGPathSegCurvetoCubicSmoothRel.prototype, "x", {
839 get: function () {
840 return this._x;
841 },
842 set: function (x) {
843 this._x = x;
844 this._segmentChanged();
845 },
846 enumerable: true
847 });
848 Object.defineProperty(window.SVGPathSegCurvetoCubicSmoothRel.prototype, "y", {
849 get: function () {
850 return this._y;
851 },
852 set: function (y) {
853 this._y = y;
854 this._segmentChanged();
855 },
856 enumerable: true
857 });
858 Object.defineProperty(window.SVGPathSegCurvetoCubicSmoothRel.prototype, "x2", {
859 get: function () {
860 return this._x2;
861 },
862 set: function (x2) {
863 this._x2 = x2;
864 this._segmentChanged();
865 },
866 enumerable: true
867 });
868 Object.defineProperty(window.SVGPathSegCurvetoCubicSmoothRel.prototype, "y2", {
869 get: function () {
870 return this._y2;
871 },
872 set: function (y2) {
873 this._y2 = y2;
874 this._segmentChanged();
875 },
876 enumerable: true
877 });
878 window.SVGPathSegCurvetoQuadraticSmoothAbs = function (owningPathSegList, x, y) {
879 window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_ABS, "T", owningPathSegList);
880 this._x = x;
881 this._y = y;
882 };
883 window.SVGPathSegCurvetoQuadraticSmoothAbs.prototype = Object.create(window.SVGPathSeg.prototype);
884 window.SVGPathSegCurvetoQuadraticSmoothAbs.prototype.toString = function () {
885 return "[object SVGPathSegCurvetoQuadraticSmoothAbs]";
886 };
887 window.SVGPathSegCurvetoQuadraticSmoothAbs.prototype._asPathString = function () {
888 return `${this.pathSegTypeAsLetter} ${this._x} ${this._y}`;
889 };
890 window.SVGPathSegCurvetoQuadraticSmoothAbs.prototype.clone = function () {
891 return new window.SVGPathSegCurvetoQuadraticSmoothAbs(undefined, this._x, this._y);
892 };
893 Object.defineProperty(window.SVGPathSegCurvetoQuadraticSmoothAbs.prototype, "x", {
894 get: function () {
895 return this._x;
896 },
897 set: function (x) {
898 this._x = x;
899 this._segmentChanged();
900 },
901 enumerable: true
902 });
903 Object.defineProperty(window.SVGPathSegCurvetoQuadraticSmoothAbs.prototype, "y", {
904 get: function () {
905 return this._y;
906 },
907 set: function (y) {
908 this._y = y;
909 this._segmentChanged();
910 },
911 enumerable: true
912 });
913 window.SVGPathSegCurvetoQuadraticSmoothRel = function (owningPathSegList, x, y) {
914 window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_REL, "t", owningPathSegList);
915 this._x = x;
916 this._y = y;
917 };
918 window.SVGPathSegCurvetoQuadraticSmoothRel.prototype = Object.create(window.SVGPathSeg.prototype);
919 window.SVGPathSegCurvetoQuadraticSmoothRel.prototype.toString = function () {
920 return "[object SVGPathSegCurvetoQuadraticSmoothRel]";
921 };
922 window.SVGPathSegCurvetoQuadraticSmoothRel.prototype._asPathString = function () {
923 return `${this.pathSegTypeAsLetter} ${this._x} ${this._y}`;
924 };
925 window.SVGPathSegCurvetoQuadraticSmoothRel.prototype.clone = function () {
926 return new window.SVGPathSegCurvetoQuadraticSmoothRel(undefined, this._x, this._y);
927 };
928 Object.defineProperty(window.SVGPathSegCurvetoQuadraticSmoothRel.prototype, "x", {
929 get: function () {
930 return this._x;
931 },
932 set: function (x) {
933 this._x = x;
934 this._segmentChanged();
935 },
936 enumerable: true
937 });
938 Object.defineProperty(window.SVGPathSegCurvetoQuadraticSmoothRel.prototype, "y", {
939 get: function () {
940 return this._y;
941 },
942 set: function (y) {
943 this._y = y;
944 this._segmentChanged();
945 },
946 enumerable: true
947 });
948 window.SVGPathElement.prototype.createSVGPathSegClosePath = function () {
949 return new window.SVGPathSegClosePath(undefined);
950 };
951 window.SVGPathElement.prototype.createSVGPathSegMovetoAbs = function (x, y) {
952 return new window.SVGPathSegMovetoAbs(undefined, x, y);
953 };
954 window.SVGPathElement.prototype.createSVGPathSegMovetoRel = function (x, y) {
955 return new window.SVGPathSegMovetoRel(undefined, x, y);
956 };
957 window.SVGPathElement.prototype.createSVGPathSegLinetoAbs = function (x, y) {
958 return new window.SVGPathSegLinetoAbs(undefined, x, y);
959 };
960 window.SVGPathElement.prototype.createSVGPathSegLinetoRel = function (x, y) {
961 return new window.SVGPathSegLinetoRel(undefined, x, y);
962 };
963 window.SVGPathElement.prototype.createSVGPathSegCurvetoCubicAbs = function (x, y, x1, y1, x2, y2) {
964 return new window.SVGPathSegCurvetoCubicAbs(undefined, x, y, x1, y1, x2, y2);
965 };
966 window.SVGPathElement.prototype.createSVGPathSegCurvetoCubicRel = function (x, y, x1, y1, x2, y2) {
967 return new window.SVGPathSegCurvetoCubicRel(undefined, x, y, x1, y1, x2, y2);
968 };
969 window.SVGPathElement.prototype.createSVGPathSegCurvetoQuadraticAbs = function (x, y, x1, y1) {
970 return new window.SVGPathSegCurvetoQuadraticAbs(undefined, x, y, x1, y1);
971 };
972 window.SVGPathElement.prototype.createSVGPathSegCurvetoQuadraticRel = function (x, y, x1, y1) {
973 return new window.SVGPathSegCurvetoQuadraticRel(undefined, x, y, x1, y1);
974 };
975 window.SVGPathElement.prototype.createSVGPathSegArcAbs = function (x, y, r1, r2, angle, largeArcFlag, sweepFlag) {
976 return new window.SVGPathSegArcAbs(undefined, x, y, r1, r2, angle, largeArcFlag, sweepFlag);
977 };
978 window.SVGPathElement.prototype.createSVGPathSegArcRel = function (x, y, r1, r2, angle, largeArcFlag, sweepFlag) {
979 return new window.SVGPathSegArcRel(undefined, x, y, r1, r2, angle, largeArcFlag, sweepFlag);
980 };
981 window.SVGPathElement.prototype.createSVGPathSegLinetoHorizontalAbs = function (x) {
982 return new window.SVGPathSegLinetoHorizontalAbs(undefined, x);
983 };
984 window.SVGPathElement.prototype.createSVGPathSegLinetoHorizontalRel = function (x) {
985 return new window.SVGPathSegLinetoHorizontalRel(undefined, x);
986 };
987 window.SVGPathElement.prototype.createSVGPathSegLinetoVerticalAbs = function (y) {
988 return new window.SVGPathSegLinetoVerticalAbs(undefined, y);
989 };
990 window.SVGPathElement.prototype.createSVGPathSegLinetoVerticalRel = function (y) {
991 return new window.SVGPathSegLinetoVerticalRel(undefined, y);
992 };
993 window.SVGPathElement.prototype.createSVGPathSegCurvetoCubicSmoothAbs = function (x, y, x2, y2) {
994 return new window.SVGPathSegCurvetoCubicSmoothAbs(undefined, x, y, x2, y2);
995 };
996 window.SVGPathElement.prototype.createSVGPathSegCurvetoCubicSmoothRel = function (x, y, x2, y2) {
997 return new window.SVGPathSegCurvetoCubicSmoothRel(undefined, x, y, x2, y2);
998 };
999 window.SVGPathElement.prototype.createSVGPathSegCurvetoQuadraticSmoothAbs = function (x, y) {
1000 return new window.SVGPathSegCurvetoQuadraticSmoothAbs(undefined, x, y);
1001 };
1002 window.SVGPathElement.prototype.createSVGPathSegCurvetoQuadraticSmoothRel = function (x, y) {
1003 return new window.SVGPathSegCurvetoQuadraticSmoothRel(undefined, x, y);
1004 };
1005 if (!("getPathSegAtLength" in window.SVGPathElement.prototype)) {
1006 window.SVGPathElement.prototype.getPathSegAtLength = function (distance) {
1007 if (distance === undefined || !isFinite(distance)) throw "Invalid arguments.";
1008 const measurementElement = document.createElementNS("http://www.w3.org/2000/svg", "path");
1009 measurementElement.setAttribute("d", this.getAttribute("d"));
1010 let lastPathSegment = measurementElement.pathSegList.numberOfItems - 1;
1011 if (lastPathSegment <= 0) return 0;
1012 do {
1013 measurementElement.pathSegList.removeItem(lastPathSegment);
1014 if (distance > measurementElement.getTotalLength()) break;
1015 lastPathSegment--;
1016 } while (lastPathSegment > 0);
1017 return lastPathSegment;
1018 };
1019 }
1020 }
1021 if (!("SVGPathSegList" in window) || !("appendItem" in window.SVGPathSegList.prototype)) {
1022 window.SVGPathSegList = function (pathElement) {
1023 this._pathElement = pathElement;
1024 this._list = this._parsePath(this._pathElement.getAttribute("d"));
1025 this._mutationObserverConfig = {
1026 attributes: true,
1027 attributeFilter: ["d"]
1028 };
1029 this._pathElementMutationObserver = new MutationObserver(this._updateListFromPathMutations.bind(this));
1030 this._pathElementMutationObserver.observe(this._pathElement, this._mutationObserverConfig);
1031 };
1032 window.SVGPathSegList.prototype.classname = "SVGPathSegList";
1033 Object.defineProperty(window.SVGPathSegList.prototype, "numberOfItems", {
1034 get: function () {
1035 this._checkPathSynchronizedToList();
1036 return this._list.length;
1037 },
1038 enumerable: true
1039 });
1040 Object.defineProperty(window.SVGPathSegList.prototype, "length", {
1041 get: function () {
1042 this._checkPathSynchronizedToList();
1043 return this._list.length;
1044 },
1045 enumerable: true
1046 });
1047 Object.defineProperty(window.SVGPathElement.prototype, "pathSegList", {
1048 get: function () {
1049 if (!this._pathSegList) this._pathSegList = new window.SVGPathSegList(this);
1050 return this._pathSegList;
1051 },
1052 enumerable: true
1053 });
1054 Object.defineProperty(window.SVGPathElement.prototype, "normalizedPathSegList", {
1055 get: function () {
1056 return this.pathSegList;
1057 },
1058 enumerable: true
1059 });
1060 Object.defineProperty(window.SVGPathElement.prototype, "animatedPathSegList", {
1061 get: function () {
1062 return this.pathSegList;
1063 },
1064 enumerable: true
1065 });
1066 Object.defineProperty(window.SVGPathElement.prototype, "animatedNormalizedPathSegList", {
1067 get: function () {
1068 return this.pathSegList;
1069 },
1070 enumerable: true
1071 });
1072 window.SVGPathSegList.prototype._checkPathSynchronizedToList = function () {
1073 this._updateListFromPathMutations(this._pathElementMutationObserver.takeRecords());
1074 };
1075 window.SVGPathSegList.prototype._updateListFromPathMutations = function (mutationRecords) {
1076 if (!this._pathElement) return;
1077 let hasPathMutations = false;
1078 mutationRecords.forEach(function (record) {
1079 if (record.attributeName == "d") hasPathMutations = true;
1080 });
1081 if (hasPathMutations) this._list = this._parsePath(this._pathElement.getAttribute("d"));
1082 };
1083 window.SVGPathSegList.prototype._writeListToPath = function () {
1084 this._pathElementMutationObserver.disconnect();
1085 this._pathElement.setAttribute("d", window.SVGPathSegList._pathSegArrayAsString(this._list));
1086 this._pathElementMutationObserver.observe(this._pathElement, this._mutationObserverConfig);
1087 };
1088 window.SVGPathSegList.prototype.segmentChanged = function () {
1089 this._writeListToPath();
1090 };
1091 window.SVGPathSegList.prototype.clear = function () {
1092 this._checkPathSynchronizedToList();
1093 this._list.forEach(function (pathSeg) {
1094 pathSeg._owningPathSegList = null;
1095 });
1096 this._list = [];
1097 this._writeListToPath();
1098 };
1099 window.SVGPathSegList.prototype.initialize = function (newItem) {
1100 this._checkPathSynchronizedToList();
1101 this._list = [newItem];
1102 newItem._owningPathSegList = this;
1103 this._writeListToPath();
1104 return newItem;
1105 };
1106 window.SVGPathSegList.prototype._checkValidIndex = function (index) {
1107 if (isNaN(index) || index < 0 || index >= this.numberOfItems) throw "INDEX_SIZE_ERR";
1108 };
1109 window.SVGPathSegList.prototype.getItem = function (index) {
1110 this._checkPathSynchronizedToList();
1111 this._checkValidIndex(index);
1112 return this._list[index];
1113 };
1114 window.SVGPathSegList.prototype.insertItemBefore = function (newItem, index) {
1115 this._checkPathSynchronizedToList();
1116 if (index > this.numberOfItems) index = this.numberOfItems;
1117 if (newItem._owningPathSegList) {
1118 newItem = newItem.clone();
1119 }
1120 this._list.splice(index, 0, newItem);
1121 newItem._owningPathSegList = this;
1122 this._writeListToPath();
1123 return newItem;
1124 };
1125 window.SVGPathSegList.prototype.replaceItem = function (newItem, index) {
1126 this._checkPathSynchronizedToList();
1127 if (newItem._owningPathSegList) {
1128 newItem = newItem.clone();
1129 }
1130 this._checkValidIndex(index);
1131 this._list[index] = newItem;
1132 newItem._owningPathSegList = this;
1133 this._writeListToPath();
1134 return newItem;
1135 };
1136 window.SVGPathSegList.prototype.removeItem = function (index) {
1137 this._checkPathSynchronizedToList();
1138 this._checkValidIndex(index);
1139 const item = this._list[index];
1140 this._list.splice(index, 1);
1141 this._writeListToPath();
1142 return item;
1143 };
1144 window.SVGPathSegList.prototype.appendItem = function (newItem) {
1145 this._checkPathSynchronizedToList();
1146 if (newItem._owningPathSegList) {
1147 newItem = newItem.clone();
1148 }
1149 this._list.push(newItem);
1150 newItem._owningPathSegList = this;
1151 this._writeListToPath();
1152 return newItem;
1153 };
1154 window.SVGPathSegList._pathSegArrayAsString = function (pathSegArray) {
1155 let string = "";
1156 let first = true;
1157 pathSegArray.forEach(function (pathSeg) {
1158 if (first) {
1159 first = false;
1160 string += pathSeg._asPathString();
1161 } else {
1162 string += ` ${pathSeg._asPathString()}`;
1163 }
1164 });
1165 return string;
1166 };
1167 window.SVGPathSegList.prototype._parsePath = function (string) {
1168 if (!string || !string.length) return [];
1169 const owningPathSegList = this;
1170 const Builder = function () {
1171 this.pathSegList = [];
1172 };
1173 Builder.prototype.appendSegment = function (pathSeg) {
1174 this.pathSegList.push(pathSeg);
1175 };
1176 const Source = function (string) {
1177 this._string = string;
1178 this._currentIndex = 0;
1179 this._endIndex = this._string.length;
1180 this._previousCommand = window.SVGPathSeg.PATHSEG_UNKNOWN;
1181 this._skipOptionalSpaces();
1182 };
1183 Source.prototype._isCurrentSpace = function () {
1184 const character = this._string[this._currentIndex];
1185 return character <= " " && (character == " " || character == "\n" || character == "\t" || character == "\r" || character == "\f");
1186 };
1187 Source.prototype._skipOptionalSpaces = function () {
1188 while (this._currentIndex < this._endIndex && this._isCurrentSpace()) this._currentIndex++;
1189 return this._currentIndex < this._endIndex;
1190 };
1191 Source.prototype._skipOptionalSpacesOrDelimiter = function () {
1192 if (this._currentIndex < this._endIndex && !this._isCurrentSpace() && this._string.charAt(this._currentIndex) != ",") return false;
1193 if (this._skipOptionalSpaces()) {
1194 if (this._currentIndex < this._endIndex && this._string.charAt(this._currentIndex) == ",") {
1195 this._currentIndex++;
1196 this._skipOptionalSpaces();
1197 }
1198 }
1199 return this._currentIndex < this._endIndex;
1200 };
1201 Source.prototype.hasMoreData = function () {
1202 return this._currentIndex < this._endIndex;
1203 };
1204 Source.prototype.peekSegmentType = function () {
1205 const lookahead = this._string[this._currentIndex];
1206 return this._pathSegTypeFromChar(lookahead);
1207 };
1208 Source.prototype._pathSegTypeFromChar = function (lookahead) {
1209 switch (lookahead) {
1210 case "Z":
1211 case "z":
1212 return window.SVGPathSeg.PATHSEG_CLOSEPATH;
1213 case "M":
1214 return window.SVGPathSeg.PATHSEG_MOVETO_ABS;
1215 case "m":
1216 return window.SVGPathSeg.PATHSEG_MOVETO_REL;
1217 case "L":
1218 return window.SVGPathSeg.PATHSEG_LINETO_ABS;
1219 case "l":
1220 return window.SVGPathSeg.PATHSEG_LINETO_REL;
1221 case "C":
1222 return window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_ABS;
1223 case "c":
1224 return window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_REL;
1225 case "Q":
1226 return window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_ABS;
1227 case "q":
1228 return window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_REL;
1229 case "A":
1230 return window.SVGPathSeg.PATHSEG_ARC_ABS;
1231 case "a":
1232 return window.SVGPathSeg.PATHSEG_ARC_REL;
1233 case "H":
1234 return window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_ABS;
1235 case "h":
1236 return window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_REL;
1237 case "V":
1238 return window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_ABS;
1239 case "v":
1240 return window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_REL;
1241 case "S":
1242 return window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_ABS;
1243 case "s":
1244 return window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_REL;
1245 case "T":
1246 return window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_ABS;
1247 case "t":
1248 return window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_REL;
1249 default:
1250 return window.SVGPathSeg.PATHSEG_UNKNOWN;
1251 }
1252 };
1253 Source.prototype._nextCommandHelper = function (lookahead, previousCommand) {
1254 if ((lookahead == "+" || lookahead == "-" || lookahead == "." || lookahead >= "0" && lookahead <= "9") && previousCommand != window.SVGPathSeg.PATHSEG_CLOSEPATH) {
1255 if (previousCommand == window.SVGPathSeg.PATHSEG_MOVETO_ABS) return window.SVGPathSeg.PATHSEG_LINETO_ABS;
1256 if (previousCommand == window.SVGPathSeg.PATHSEG_MOVETO_REL) return window.SVGPathSeg.PATHSEG_LINETO_REL;
1257 return previousCommand;
1258 }
1259 return window.SVGPathSeg.PATHSEG_UNKNOWN;
1260 };
1261 Source.prototype.initialCommandIsMoveTo = function () {
1262 if (!this.hasMoreData()) return true;
1263 const command = this.peekSegmentType();
1264 return command == window.SVGPathSeg.PATHSEG_MOVETO_ABS || command == window.SVGPathSeg.PATHSEG_MOVETO_REL;
1265 };
1266 Source.prototype._parseNumber = function () {
1267 let exponent = 0;
1268 let integer = 0;
1269 let frac = 1;
1270 let decimal = 0;
1271 let sign = 1;
1272 let expsign = 1;
1273 const startIndex = this._currentIndex;
1274 this._skipOptionalSpaces();
1275 if (this._currentIndex < this._endIndex && this._string.charAt(this._currentIndex) == "+") this._currentIndex++;else if (this._currentIndex < this._endIndex && this._string.charAt(this._currentIndex) == "-") {
1276 this._currentIndex++;
1277 sign = -1;
1278 }
1279 if (this._currentIndex == this._endIndex || (this._string.charAt(this._currentIndex) < "0" || this._string.charAt(this._currentIndex) > "9") && this._string.charAt(this._currentIndex) != ".") return undefined;
1280 const startIntPartIndex = this._currentIndex;
1281 while (this._currentIndex < this._endIndex && this._string.charAt(this._currentIndex) >= "0" && this._string.charAt(this._currentIndex) <= "9") this._currentIndex++;
1282 if (this._currentIndex != startIntPartIndex) {
1283 let scanIntPartIndex = this._currentIndex - 1;
1284 let multiplier = 1;
1285 while (scanIntPartIndex >= startIntPartIndex) {
1286 integer += multiplier * (this._string.charAt(scanIntPartIndex--) - "0");
1287 multiplier *= 10;
1288 }
1289 }
1290 if (this._currentIndex < this._endIndex && this._string.charAt(this._currentIndex) == ".") {
1291 this._currentIndex++;
1292 if (this._currentIndex >= this._endIndex || this._string.charAt(this._currentIndex) < "0" || this._string.charAt(this._currentIndex) > "9") return undefined;
1293 while (this._currentIndex < this._endIndex && this._string.charAt(this._currentIndex) >= "0" && this._string.charAt(this._currentIndex) <= "9") {
1294 frac *= 10;
1295 decimal += (this._string.charAt(this._currentIndex) - "0") / frac;
1296 this._currentIndex += 1;
1297 }
1298 }
1299 if (this._currentIndex != startIndex && this._currentIndex + 1 < this._endIndex && (this._string.charAt(this._currentIndex) == "e" || this._string.charAt(this._currentIndex) == "E") && this._string.charAt(this._currentIndex + 1) != "x" && this._string.charAt(this._currentIndex + 1) != "m") {
1300 this._currentIndex++;
1301 if (this._string.charAt(this._currentIndex) == "+") {
1302 this._currentIndex++;
1303 } else if (this._string.charAt(this._currentIndex) == "-") {
1304 this._currentIndex++;
1305 expsign = -1;
1306 }
1307 if (this._currentIndex >= this._endIndex || this._string.charAt(this._currentIndex) < "0" || this._string.charAt(this._currentIndex) > "9") return undefined;
1308 while (this._currentIndex < this._endIndex && this._string.charAt(this._currentIndex) >= "0" && this._string.charAt(this._currentIndex) <= "9") {
1309 exponent *= 10;
1310 exponent += this._string.charAt(this._currentIndex) - "0";
1311 this._currentIndex++;
1312 }
1313 }
1314 let number = integer + decimal;
1315 number *= sign;
1316 if (exponent) number *= Math.pow(10, expsign * exponent);
1317 if (startIndex == this._currentIndex) return undefined;
1318 this._skipOptionalSpacesOrDelimiter();
1319 return number;
1320 };
1321 Source.prototype._parseArcFlag = function () {
1322 if (this._currentIndex >= this._endIndex) return undefined;
1323 let flag = false;
1324 const flagChar = this._string.charAt(this._currentIndex++);
1325 if (flagChar == "0") flag = false;else if (flagChar == "1") flag = true;else return undefined;
1326 this._skipOptionalSpacesOrDelimiter();
1327 return flag;
1328 };
1329 Source.prototype.parseSegment = function () {
1330 const lookahead = this._string[this._currentIndex];
1331 let command = this._pathSegTypeFromChar(lookahead);
1332 if (command == window.SVGPathSeg.PATHSEG_UNKNOWN) {
1333 if (this._previousCommand == window.SVGPathSeg.PATHSEG_UNKNOWN) return null;
1334 command = this._nextCommandHelper(lookahead, this._previousCommand);
1335 if (command == window.SVGPathSeg.PATHSEG_UNKNOWN) return null;
1336 } else {
1337 this._currentIndex++;
1338 }
1339 this._previousCommand = command;
1340 let points;
1341 switch (command) {
1342 case window.SVGPathSeg.PATHSEG_MOVETO_REL:
1343 return new window.SVGPathSegMovetoRel(owningPathSegList, this._parseNumber(), this._parseNumber());
1344 case window.SVGPathSeg.PATHSEG_MOVETO_ABS:
1345 return new window.SVGPathSegMovetoAbs(owningPathSegList, this._parseNumber(), this._parseNumber());
1346 case window.SVGPathSeg.PATHSEG_LINETO_REL:
1347 return new window.SVGPathSegLinetoRel(owningPathSegList, this._parseNumber(), this._parseNumber());
1348 case window.SVGPathSeg.PATHSEG_LINETO_ABS:
1349 return new window.SVGPathSegLinetoAbs(owningPathSegList, this._parseNumber(), this._parseNumber());
1350 case window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_REL:
1351 return new window.SVGPathSegLinetoHorizontalRel(owningPathSegList, this._parseNumber());
1352 case window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_ABS:
1353 return new window.SVGPathSegLinetoHorizontalAbs(owningPathSegList, this._parseNumber());
1354 case window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_REL:
1355 return new window.SVGPathSegLinetoVerticalRel(owningPathSegList, this._parseNumber());
1356 case window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_ABS:
1357 return new window.SVGPathSegLinetoVerticalAbs(owningPathSegList, this._parseNumber());
1358 case window.SVGPathSeg.PATHSEG_CLOSEPATH:
1359 this._skipOptionalSpaces();
1360 return new window.SVGPathSegClosePath(owningPathSegList);
1361 case window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_REL:
1362 points = {
1363 x1: this._parseNumber(),
1364 y1: this._parseNumber(),
1365 x2: this._parseNumber(),
1366 y2: this._parseNumber(),
1367 x: this._parseNumber(),
1368 y: this._parseNumber()
1369 };
1370 return new window.SVGPathSegCurvetoCubicRel(owningPathSegList, points.x, points.y, points.x1, points.y1, points.x2, points.y2);
1371 case window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_ABS:
1372 points = {
1373 x1: this._parseNumber(),
1374 y1: this._parseNumber(),
1375 x2: this._parseNumber(),
1376 y2: this._parseNumber(),
1377 x: this._parseNumber(),
1378 y: this._parseNumber()
1379 };
1380 return new window.SVGPathSegCurvetoCubicAbs(owningPathSegList, points.x, points.y, points.x1, points.y1, points.x2, points.y2);
1381 case window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_REL:
1382 points = {
1383 x2: this._parseNumber(),
1384 y2: this._parseNumber(),
1385 x: this._parseNumber(),
1386 y: this._parseNumber()
1387 };
1388 return new window.SVGPathSegCurvetoCubicSmoothRel(owningPathSegList, points.x, points.y, points.x2, points.y2);
1389 case window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_ABS:
1390 points = {
1391 x2: this._parseNumber(),
1392 y2: this._parseNumber(),
1393 x: this._parseNumber(),
1394 y: this._parseNumber()
1395 };
1396 return new window.SVGPathSegCurvetoCubicSmoothAbs(owningPathSegList, points.x, points.y, points.x2, points.y2);
1397 case window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_REL:
1398 points = {
1399 x1: this._parseNumber(),
1400 y1: this._parseNumber(),
1401 x: this._parseNumber(),
1402 y: this._parseNumber()
1403 };
1404 return new window.SVGPathSegCurvetoQuadraticRel(owningPathSegList, points.x, points.y, points.x1, points.y1);
1405 case window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_ABS:
1406 points = {
1407 x1: this._parseNumber(),
1408 y1: this._parseNumber(),
1409 x: this._parseNumber(),
1410 y: this._parseNumber()
1411 };
1412 return new window.SVGPathSegCurvetoQuadraticAbs(owningPathSegList, points.x, points.y, points.x1, points.y1);
1413 case window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_REL:
1414 return new window.SVGPathSegCurvetoQuadraticSmoothRel(owningPathSegList, this._parseNumber(), this._parseNumber());
1415 case window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_ABS:
1416 return new window.SVGPathSegCurvetoQuadraticSmoothAbs(owningPathSegList, this._parseNumber(), this._parseNumber());
1417 case window.SVGPathSeg.PATHSEG_ARC_REL:
1418 points = {
1419 x1: this._parseNumber(),
1420 y1: this._parseNumber(),
1421 arcAngle: this._parseNumber(),
1422 arcLarge: this._parseArcFlag(),
1423 arcSweep: this._parseArcFlag(),
1424 x: this._parseNumber(),
1425 y: this._parseNumber()
1426 };
1427 return new window.SVGPathSegArcRel(owningPathSegList, points.x, points.y, points.x1, points.y1, points.arcAngle, points.arcLarge, points.arcSweep);
1428 case window.SVGPathSeg.PATHSEG_ARC_ABS:
1429 points = {
1430 x1: this._parseNumber(),
1431 y1: this._parseNumber(),
1432 arcAngle: this._parseNumber(),
1433 arcLarge: this._parseArcFlag(),
1434 arcSweep: this._parseArcFlag(),
1435 x: this._parseNumber(),
1436 y: this._parseNumber()
1437 };
1438 return new window.SVGPathSegArcAbs(owningPathSegList, points.x, points.y, points.x1, points.y1, points.arcAngle, points.arcLarge, points.arcSweep);
1439 default:
1440 throw "Unknown path seg type.";
1441 }
1442 };
1443 const builder = new Builder();
1444 const source = new Source(string);
1445 if (!source.initialCommandIsMoveTo()) return [];
1446 while (source.hasMoreData()) {
1447 const pathSeg = source.parseSegment();
1448 if (!pathSeg) return [];
1449 builder.appendSegment(pathSeg);
1450 }
1451 return builder.pathSegList;
1452 };
1453 }
1454 } catch (e) {
1455 console.warn("An error occurred in tsParticles pathseg polyfill. If the Polygon Mask is not working, please open an issue here: https://github.com/matteobruni/tsparticles", e);
1456 }
1457})();
1458
1459/***/ })
1460
1461/******/ });
1462/************************************************************************/
1463/******/ // The module cache
1464/******/ var __webpack_module_cache__ = {};
1465/******/
1466/******/ // The require function
1467/******/ function __webpack_require__(moduleId) {
1468/******/ // Check if module is in cache
1469/******/ var cachedModule = __webpack_module_cache__[moduleId];
1470/******/ if (cachedModule !== undefined) {
1471/******/ return cachedModule.exports;
1472/******/ }
1473/******/ // Create a new module (and put it into the cache)
1474/******/ var module = __webpack_module_cache__[moduleId] = {
1475/******/ // no module.id needed
1476/******/ // no module.loaded needed
1477/******/ exports: {}
1478/******/ };
1479/******/
1480/******/ // Execute the module function
1481/******/ __webpack_modules__[moduleId](module, module.exports, __webpack_require__);
1482/******/
1483/******/ // Return the exports of the module
1484/******/ return module.exports;
1485/******/ }
1486/******/
1487/************************************************************************/
1488/******/ /* webpack/runtime/define property getters */
1489/******/ (() => {
1490/******/ // define getter functions for harmony exports
1491/******/ __webpack_require__.d = (exports, definition) => {
1492/******/ for(var key in definition) {
1493/******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {
1494/******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });
1495/******/ }
1496/******/ }
1497/******/ };
1498/******/ })();
1499/******/
1500/******/ /* webpack/runtime/hasOwnProperty shorthand */
1501/******/ (() => {
1502/******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))
1503/******/ })();
1504/******/
1505/******/ /* webpack/runtime/make namespace object */
1506/******/ (() => {
1507/******/ // define __esModule on exports
1508/******/ __webpack_require__.r = (exports) => {
1509/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
1510/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
1511/******/ }
1512/******/ Object.defineProperty(exports, '__esModule', { value: true });
1513/******/ };
1514/******/ })();
1515/******/
1516/************************************************************************/
1517var __webpack_exports__ = {};
1518// This entry need to be wrapped in an IIFE because it need to be isolated against other modules in the chunk.
1519(() => {
1520// ESM COMPAT FLAG
1521__webpack_require__.r(__webpack_exports__);
1522
1523// EXPORTS
1524__webpack_require__.d(__webpack_exports__, {
1525 AnimatableColor: () => (/* reexport */ AnimatableColor),
1526 AnimationOptions: () => (/* reexport */ AnimationOptions),
1527 AnimationValueWithRandom: () => (/* reexport */ AnimationValueWithRandom),
1528 Background: () => (/* reexport */ Background),
1529 BackgroundMask: () => (/* reexport */ BackgroundMask),
1530 BackgroundMaskCover: () => (/* reexport */ BackgroundMaskCover),
1531 Circle: () => (/* reexport */ Circle),
1532 ClickEvent: () => (/* reexport */ ClickEvent),
1533 Collisions: () => (/* reexport */ Collisions),
1534 CollisionsAbsorb: () => (/* reexport */ CollisionsAbsorb),
1535 CollisionsOverlap: () => (/* reexport */ CollisionsOverlap),
1536 ColorAnimation: () => (/* reexport */ ColorAnimation),
1537 DivEvent: () => (/* reexport */ DivEvent),
1538 Events: () => (/* reexport */ Events),
1539 ExternalInteractorBase: () => (/* reexport */ ExternalInteractorBase),
1540 FullScreen: () => (/* reexport */ FullScreen),
1541 HoverEvent: () => (/* reexport */ HoverEvent),
1542 HslAnimation: () => (/* reexport */ HslAnimation),
1543 HslColorManager: () => (/* reexport */ HslColorManager),
1544 Interactivity: () => (/* reexport */ Interactivity),
1545 ManualParticle: () => (/* reexport */ ManualParticle),
1546 Modes: () => (/* reexport */ Modes),
1547 Move: () => (/* reexport */ Move),
1548 MoveAngle: () => (/* reexport */ MoveAngle),
1549 MoveAttract: () => (/* reexport */ MoveAttract),
1550 MoveCenter: () => (/* reexport */ MoveCenter),
1551 MoveGravity: () => (/* reexport */ MoveGravity),
1552 MovePath: () => (/* reexport */ MovePath),
1553 MoveTrail: () => (/* reexport */ MoveTrail),
1554 Opacity: () => (/* reexport */ Opacity),
1555 OpacityAnimation: () => (/* reexport */ OpacityAnimation),
1556 Options: () => (/* reexport */ Options),
1557 OptionsColor: () => (/* reexport */ OptionsColor),
1558 OutModes: () => (/* reexport */ OutModes),
1559 Parallax: () => (/* reexport */ Parallax),
1560 ParticlesBounce: () => (/* reexport */ ParticlesBounce),
1561 ParticlesBounceFactor: () => (/* reexport */ ParticlesBounceFactor),
1562 ParticlesDensity: () => (/* reexport */ ParticlesDensity),
1563 ParticlesInteractorBase: () => (/* reexport */ ParticlesInteractorBase),
1564 ParticlesNumber: () => (/* reexport */ ParticlesNumber),
1565 ParticlesOptions: () => (/* reexport */ ParticlesOptions),
1566 Point: () => (/* reexport */ Point),
1567 Range: () => (/* reexport */ Range),
1568 RangedAnimationOptions: () => (/* reexport */ RangedAnimationOptions),
1569 RangedAnimationValueWithRandom: () => (/* reexport */ RangedAnimationValueWithRandom),
1570 Rectangle: () => (/* reexport */ Rectangle),
1571 ResizeEvent: () => (/* reexport */ ResizeEvent),
1572 Responsive: () => (/* reexport */ Responsive),
1573 RgbColorManager: () => (/* reexport */ RgbColorManager),
1574 Shadow: () => (/* reexport */ Shadow),
1575 Shape: () => (/* reexport */ Shape),
1576 Size: () => (/* reexport */ Size),
1577 SizeAnimation: () => (/* reexport */ SizeAnimation),
1578 Spin: () => (/* reexport */ Spin),
1579 Stroke: () => (/* reexport */ Stroke),
1580 Theme: () => (/* reexport */ Theme),
1581 ThemeDefault: () => (/* reexport */ ThemeDefault),
1582 ValueWithRandom: () => (/* reexport */ ValueWithRandom),
1583 Vector: () => (/* reexport */ Vector),
1584 Vector3d: () => (/* reexport */ Vector3d),
1585 ZIndex: () => (/* reexport */ ZIndex),
1586 addColorManager: () => (/* reexport */ addColorManager),
1587 addEasing: () => (/* reexport */ addEasing),
1588 alterHsl: () => (/* reexport */ alterHsl),
1589 areBoundsInside: () => (/* reexport */ areBoundsInside),
1590 arrayRandomIndex: () => (/* reexport */ arrayRandomIndex),
1591 calcExactPositionOrRandomFromSize: () => (/* reexport */ calcExactPositionOrRandomFromSize),
1592 calcExactPositionOrRandomFromSizeRanged: () => (/* reexport */ calcExactPositionOrRandomFromSizeRanged),
1593 calcPositionFromSize: () => (/* reexport */ calcPositionFromSize),
1594 calcPositionOrRandomFromSize: () => (/* reexport */ calcPositionOrRandomFromSize),
1595 calcPositionOrRandomFromSizeRanged: () => (/* reexport */ calcPositionOrRandomFromSizeRanged),
1596 calculateBounds: () => (/* reexport */ calculateBounds),
1597 circleBounce: () => (/* reexport */ circleBounce),
1598 circleBounceDataFromParticle: () => (/* reexport */ circleBounceDataFromParticle),
1599 clamp: () => (/* reexport */ clamp),
1600 clear: () => (/* reexport */ clear),
1601 collisionVelocity: () => (/* reexport */ collisionVelocity),
1602 colorMix: () => (/* reexport */ colorMix),
1603 colorToHsl: () => (/* reexport */ colorToHsl),
1604 colorToRgb: () => (/* reexport */ colorToRgb),
1605 deepExtend: () => (/* reexport */ deepExtend),
1606 divMode: () => (/* reexport */ divMode),
1607 divModeExecute: () => (/* reexport */ divModeExecute),
1608 drawLine: () => (/* reexport */ drawLine),
1609 drawParticle: () => (/* reexport */ drawParticle),
1610 drawParticlePlugin: () => (/* reexport */ drawParticlePlugin),
1611 drawPlugin: () => (/* reexport */ drawPlugin),
1612 drawShape: () => (/* reexport */ drawShape),
1613 drawShapeAfterEffect: () => (/* reexport */ drawShapeAfterEffect),
1614 drawTriangle: () => (/* reexport */ drawTriangle),
1615 errorPrefix: () => (/* reexport */ errorPrefix),
1616 executeOnSingleOrMultiple: () => (/* reexport */ executeOnSingleOrMultiple),
1617 findItemFromSingleOrMultiple: () => (/* reexport */ findItemFromSingleOrMultiple),
1618 generatedAttribute: () => (/* reexport */ generatedAttribute),
1619 getDistance: () => (/* reexport */ getDistance),
1620 getDistances: () => (/* reexport */ getDistances),
1621 getEasing: () => (/* reexport */ getEasing),
1622 getHslAnimationFromHsl: () => (/* reexport */ getHslAnimationFromHsl),
1623 getHslFromAnimation: () => (/* reexport */ getHslFromAnimation),
1624 getLinkColor: () => (/* reexport */ getLinkColor),
1625 getLinkRandomColor: () => (/* reexport */ getLinkRandomColor),
1626 getLogger: () => (/* reexport */ getLogger),
1627 getParticleBaseVelocity: () => (/* reexport */ getParticleBaseVelocity),
1628 getParticleDirectionAngle: () => (/* reexport */ getParticleDirectionAngle),
1629 getPosition: () => (/* reexport */ getPosition),
1630 getRandom: () => (/* reexport */ getRandom),
1631 getRandomRgbColor: () => (/* reexport */ getRandomRgbColor),
1632 getRangeMax: () => (/* reexport */ getRangeMax),
1633 getRangeMin: () => (/* reexport */ getRangeMin),
1634 getRangeValue: () => (/* reexport */ getRangeValue),
1635 getSize: () => (/* reexport */ getSize),
1636 getStyleFromHsl: () => (/* reexport */ ColorUtils_getStyleFromHsl),
1637 getStyleFromRgb: () => (/* reexport */ getStyleFromRgb),
1638 getValue: () => (/* reexport */ getValue),
1639 hasMatchMedia: () => (/* reexport */ hasMatchMedia),
1640 hslToRgb: () => (/* reexport */ hslToRgb),
1641 hslaToRgba: () => (/* reexport */ hslaToRgba),
1642 initParticleNumericAnimationValue: () => (/* reexport */ initParticleNumericAnimationValue),
1643 isArray: () => (/* reexport */ isArray),
1644 isBoolean: () => (/* reexport */ isBoolean),
1645 isDivModeEnabled: () => (/* reexport */ isDivModeEnabled),
1646 isFunction: () => (/* reexport */ isFunction),
1647 isInArray: () => (/* reexport */ isInArray),
1648 isNumber: () => (/* reexport */ isNumber),
1649 isObject: () => (/* reexport */ isObject),
1650 isPointInside: () => (/* reexport */ isPointInside),
1651 isSsr: () => (/* reexport */ isSsr),
1652 isString: () => (/* reexport */ isString),
1653 itemFromArray: () => (/* reexport */ itemFromArray),
1654 itemFromSingleOrMultiple: () => (/* reexport */ itemFromSingleOrMultiple),
1655 loadAll: () => (/* reexport */ loadAll),
1656 loadFont: () => (/* reexport */ loadFont),
1657 loadOptions: () => (/* reexport */ loadOptions),
1658 loadParticlesOptions: () => (/* reexport */ loadParticlesOptions),
1659 mix: () => (/* reexport */ mix),
1660 mouseDownEvent: () => (/* reexport */ mouseDownEvent),
1661 mouseLeaveEvent: () => (/* reexport */ mouseLeaveEvent),
1662 mouseMoveEvent: () => (/* reexport */ mouseMoveEvent),
1663 mouseOutEvent: () => (/* reexport */ mouseOutEvent),
1664 mouseUpEvent: () => (/* reexport */ mouseUpEvent),
1665 paintBase: () => (/* reexport */ paintBase),
1666 paintImage: () => (/* reexport */ paintImage),
1667 parseAlpha: () => (/* reexport */ parseAlpha),
1668 randomInRange: () => (/* reexport */ randomInRange),
1669 rangeColorToHsl: () => (/* reexport */ rangeColorToHsl),
1670 rangeColorToRgb: () => (/* reexport */ rangeColorToRgb),
1671 rectBounce: () => (/* reexport */ rectBounce),
1672 resizeEvent: () => (/* reexport */ resizeEvent),
1673 rgbToHsl: () => (/* reexport */ rgbToHsl),
1674 safeMatchMedia: () => (/* reexport */ safeMatchMedia),
1675 safeMutationObserver: () => (/* reexport */ safeMutationObserver),
1676 setLogger: () => (/* reexport */ setLogger),
1677 setRandom: () => (/* reexport */ setRandom),
1678 setRangeValue: () => (/* reexport */ setRangeValue),
1679 singleDivModeExecute: () => (/* reexport */ singleDivModeExecute),
1680 stringToAlpha: () => (/* reexport */ stringToAlpha),
1681 stringToRgb: () => (/* reexport */ stringToRgb),
1682 touchCancelEvent: () => (/* reexport */ touchCancelEvent),
1683 touchEndEvent: () => (/* reexport */ touchEndEvent),
1684 touchMoveEvent: () => (/* reexport */ touchMoveEvent),
1685 touchStartEvent: () => (/* reexport */ touchStartEvent),
1686 tsParticles: () => (/* reexport */ tsParticles),
1687 visibilityChangeEvent: () => (/* reexport */ visibilityChangeEvent)
1688});
1689
1690;// CONCATENATED MODULE: ../../engine/dist/esm/Core/Utils/Constants.js
1691const generatedAttribute = "generated";
1692const mouseDownEvent = "pointerdown";
1693const mouseUpEvent = "pointerup";
1694const mouseLeaveEvent = "pointerleave";
1695const mouseOutEvent = "pointerout";
1696const mouseMoveEvent = "pointermove";
1697const touchStartEvent = "touchstart";
1698const touchEndEvent = "touchend";
1699const touchMoveEvent = "touchmove";
1700const touchCancelEvent = "touchcancel";
1701const resizeEvent = "resize";
1702const visibilityChangeEvent = "visibilitychange";
1703const errorPrefix = "tsParticles - Error";
1704;// CONCATENATED MODULE: ../../engine/dist/esm/Core/Utils/Vector3d.js
1705
1706
1707class Vector3d {
1708 constructor(xOrCoords, y, z) {
1709 this._updateFromAngle = (angle, length) => {
1710 this.x = Math.cos(angle) * length;
1711 this.y = Math.sin(angle) * length;
1712 };
1713 if (!isNumber(xOrCoords) && xOrCoords) {
1714 this.x = xOrCoords.x;
1715 this.y = xOrCoords.y;
1716 const coords3d = xOrCoords;
1717 this.z = coords3d.z ? coords3d.z : 0;
1718 } else if (xOrCoords !== undefined && y !== undefined) {
1719 this.x = xOrCoords;
1720 this.y = y;
1721 this.z = z ?? 0;
1722 } else {
1723 throw new Error(`${errorPrefix} Vector3d not initialized correctly`);
1724 }
1725 }
1726 static get origin() {
1727 return Vector3d.create(0, 0, 0);
1728 }
1729 get angle() {
1730 return Math.atan2(this.y, this.x);
1731 }
1732 set angle(angle) {
1733 this._updateFromAngle(angle, this.length);
1734 }
1735 get length() {
1736 return Math.sqrt(this.getLengthSq());
1737 }
1738 set length(length) {
1739 this._updateFromAngle(this.angle, length);
1740 }
1741 static clone(source) {
1742 return Vector3d.create(source.x, source.y, source.z);
1743 }
1744 static create(x, y, z) {
1745 return new Vector3d(x, y, z);
1746 }
1747 add(v) {
1748 return Vector3d.create(this.x + v.x, this.y + v.y, this.z + v.z);
1749 }
1750 addTo(v) {
1751 this.x += v.x;
1752 this.y += v.y;
1753 this.z += v.z;
1754 }
1755 copy() {
1756 return Vector3d.clone(this);
1757 }
1758 distanceTo(v) {
1759 return this.sub(v).length;
1760 }
1761 distanceToSq(v) {
1762 return this.sub(v).getLengthSq();
1763 }
1764 div(n) {
1765 return Vector3d.create(this.x / n, this.y / n, this.z / n);
1766 }
1767 divTo(n) {
1768 this.x /= n;
1769 this.y /= n;
1770 this.z /= n;
1771 }
1772 getLengthSq() {
1773 return this.x ** 2 + this.y ** 2;
1774 }
1775 mult(n) {
1776 return Vector3d.create(this.x * n, this.y * n, this.z * n);
1777 }
1778 multTo(n) {
1779 this.x *= n;
1780 this.y *= n;
1781 this.z *= n;
1782 }
1783 normalize() {
1784 const length = this.length;
1785 if (length != 0) {
1786 this.multTo(1.0 / length);
1787 }
1788 }
1789 rotate(angle) {
1790 return Vector3d.create(this.x * Math.cos(angle) - this.y * Math.sin(angle), this.x * Math.sin(angle) + this.y * Math.cos(angle), 0);
1791 }
1792 setTo(c) {
1793 this.x = c.x;
1794 this.y = c.y;
1795 const v3d = c;
1796 this.z = v3d.z ? v3d.z : 0;
1797 }
1798 sub(v) {
1799 return Vector3d.create(this.x - v.x, this.y - v.y, this.z - v.z);
1800 }
1801 subFrom(v) {
1802 this.x -= v.x;
1803 this.y -= v.y;
1804 this.z -= v.z;
1805 }
1806}
1807;// CONCATENATED MODULE: ../../engine/dist/esm/Core/Utils/Vector.js
1808
1809class Vector extends Vector3d {
1810 constructor(xOrCoords, y) {
1811 super(xOrCoords, y, 0);
1812 }
1813 static get origin() {
1814 return Vector.create(0, 0);
1815 }
1816 static clone(source) {
1817 return Vector.create(source.x, source.y);
1818 }
1819 static create(x, y) {
1820 return new Vector(x, y);
1821 }
1822}
1823;// CONCATENATED MODULE: ../../engine/dist/esm/Utils/Utils.js
1824
1825
1826const _logger = {
1827 debug: console.debug,
1828 error: console.error,
1829 info: console.info,
1830 log: console.log,
1831 verbose: console.log,
1832 warning: console.warn
1833};
1834function setLogger(logger) {
1835 _logger.debug = logger.debug || _logger.debug;
1836 _logger.error = logger.error || _logger.error;
1837 _logger.info = logger.info || _logger.info;
1838 _logger.log = logger.log || _logger.log;
1839 _logger.verbose = logger.verbose || _logger.verbose;
1840 _logger.warning = logger.warning || _logger.warning;
1841}
1842function getLogger() {
1843 return _logger;
1844}
1845function rectSideBounce(data) {
1846 const res = {
1847 bounced: false
1848 },
1849 {
1850 pSide,
1851 pOtherSide,
1852 rectSide,
1853 rectOtherSide,
1854 velocity,
1855 factor
1856 } = data;
1857 if (pOtherSide.min < rectOtherSide.min || pOtherSide.min > rectOtherSide.max || pOtherSide.max < rectOtherSide.min || pOtherSide.max > rectOtherSide.max) {
1858 return res;
1859 }
1860 if (pSide.max >= rectSide.min && pSide.max <= (rectSide.max + rectSide.min) / 2 && velocity > 0 || pSide.min <= rectSide.max && pSide.min > (rectSide.max + rectSide.min) / 2 && velocity < 0) {
1861 res.velocity = velocity * -factor;
1862 res.bounced = true;
1863 }
1864 return res;
1865}
1866function checkSelector(element, selectors) {
1867 const res = executeOnSingleOrMultiple(selectors, selector => {
1868 return element.matches(selector);
1869 });
1870 return isArray(res) ? res.some(t => t) : res;
1871}
1872function isSsr() {
1873 return typeof window === "undefined" || !window || typeof window.document === "undefined" || !window.document;
1874}
1875function hasMatchMedia() {
1876 return !isSsr() && typeof matchMedia !== "undefined";
1877}
1878function safeMatchMedia(query) {
1879 if (!hasMatchMedia()) {
1880 return;
1881 }
1882 return matchMedia(query);
1883}
1884function safeMutationObserver(callback) {
1885 if (isSsr() || typeof MutationObserver === "undefined") {
1886 return;
1887 }
1888 return new MutationObserver(callback);
1889}
1890function isInArray(value, array) {
1891 return value === array || isArray(array) && array.indexOf(value) > -1;
1892}
1893async function loadFont(font, weight) {
1894 try {
1895 await document.fonts.load(`${weight ?? "400"} 36px '${font ?? "Verdana"}'`);
1896 } catch {}
1897}
1898function arrayRandomIndex(array) {
1899 return Math.floor(getRandom() * array.length);
1900}
1901function itemFromArray(array, index, useIndex = true) {
1902 return array[index !== undefined && useIndex ? index % array.length : arrayRandomIndex(array)];
1903}
1904function isPointInside(point, size, offset, radius, direction) {
1905 return areBoundsInside(calculateBounds(point, radius ?? 0), size, offset, direction);
1906}
1907function areBoundsInside(bounds, size, offset, direction) {
1908 let inside = true;
1909 if (!direction || direction === "bottom") {
1910 inside = bounds.top < size.height + offset.x;
1911 }
1912 if (inside && (!direction || direction === "left")) {
1913 inside = bounds.right > offset.x;
1914 }
1915 if (inside && (!direction || direction === "right")) {
1916 inside = bounds.left < size.width + offset.y;
1917 }
1918 if (inside && (!direction || direction === "top")) {
1919 inside = bounds.bottom > offset.y;
1920 }
1921 return inside;
1922}
1923function calculateBounds(point, radius) {
1924 return {
1925 bottom: point.y + radius,
1926 left: point.x - radius,
1927 right: point.x + radius,
1928 top: point.y - radius
1929 };
1930}
1931function deepExtend(destination, ...sources) {
1932 for (const source of sources) {
1933 if (source === undefined || source === null) {
1934 continue;
1935 }
1936 if (!isObject(source)) {
1937 destination = source;
1938 continue;
1939 }
1940 const sourceIsArray = Array.isArray(source);
1941 if (sourceIsArray && (isObject(destination) || !destination || !Array.isArray(destination))) {
1942 destination = [];
1943 } else if (!sourceIsArray && (isObject(destination) || !destination || Array.isArray(destination))) {
1944 destination = {};
1945 }
1946 for (const key in source) {
1947 if (key === "__proto__") {
1948 continue;
1949 }
1950 const sourceDict = source,
1951 value = sourceDict[key],
1952 destDict = destination;
1953 destDict[key] = isObject(value) && Array.isArray(value) ? value.map(v => deepExtend(destDict[key], v)) : deepExtend(destDict[key], value);
1954 }
1955 }
1956 return destination;
1957}
1958function isDivModeEnabled(mode, divs) {
1959 return !!findItemFromSingleOrMultiple(divs, t => t.enable && isInArray(mode, t.mode));
1960}
1961function divModeExecute(mode, divs, callback) {
1962 executeOnSingleOrMultiple(divs, div => {
1963 const divMode = div.mode,
1964 divEnabled = div.enable;
1965 if (divEnabled && isInArray(mode, divMode)) {
1966 singleDivModeExecute(div, callback);
1967 }
1968 });
1969}
1970function singleDivModeExecute(div, callback) {
1971 const selectors = div.selectors;
1972 executeOnSingleOrMultiple(selectors, selector => {
1973 callback(selector, div);
1974 });
1975}
1976function divMode(divs, element) {
1977 if (!element || !divs) {
1978 return;
1979 }
1980 return findItemFromSingleOrMultiple(divs, div => {
1981 return checkSelector(element, div.selectors);
1982 });
1983}
1984function circleBounceDataFromParticle(p) {
1985 return {
1986 position: p.getPosition(),
1987 radius: p.getRadius(),
1988 mass: p.getMass(),
1989 velocity: p.velocity,
1990 factor: Vector.create(getValue(p.options.bounce.horizontal), getValue(p.options.bounce.vertical))
1991 };
1992}
1993function circleBounce(p1, p2) {
1994 const {
1995 x: xVelocityDiff,
1996 y: yVelocityDiff
1997 } = p1.velocity.sub(p2.velocity),
1998 [pos1, pos2] = [p1.position, p2.position],
1999 {
2000 dx: xDist,
2001 dy: yDist
2002 } = getDistances(pos2, pos1);
2003 if (xVelocityDiff * xDist + yVelocityDiff * yDist < 0) {
2004 return;
2005 }
2006 const angle = -Math.atan2(yDist, xDist),
2007 m1 = p1.mass,
2008 m2 = p2.mass,
2009 u1 = p1.velocity.rotate(angle),
2010 u2 = p2.velocity.rotate(angle),
2011 v1 = collisionVelocity(u1, u2, m1, m2),
2012 v2 = collisionVelocity(u2, u1, m1, m2),
2013 vFinal1 = v1.rotate(-angle),
2014 vFinal2 = v2.rotate(-angle);
2015 p1.velocity.x = vFinal1.x * p1.factor.x;
2016 p1.velocity.y = vFinal1.y * p1.factor.y;
2017 p2.velocity.x = vFinal2.x * p2.factor.x;
2018 p2.velocity.y = vFinal2.y * p2.factor.y;
2019}
2020function rectBounce(particle, divBounds) {
2021 const pPos = particle.getPosition(),
2022 size = particle.getRadius(),
2023 bounds = calculateBounds(pPos, size),
2024 resH = rectSideBounce({
2025 pSide: {
2026 min: bounds.left,
2027 max: bounds.right
2028 },
2029 pOtherSide: {
2030 min: bounds.top,
2031 max: bounds.bottom
2032 },
2033 rectSide: {
2034 min: divBounds.left,
2035 max: divBounds.right
2036 },
2037 rectOtherSide: {
2038 min: divBounds.top,
2039 max: divBounds.bottom
2040 },
2041 velocity: particle.velocity.x,
2042 factor: getValue(particle.options.bounce.horizontal)
2043 });
2044 if (resH.bounced) {
2045 if (resH.velocity !== undefined) {
2046 particle.velocity.x = resH.velocity;
2047 }
2048 if (resH.position !== undefined) {
2049 particle.position.x = resH.position;
2050 }
2051 }
2052 const resV = rectSideBounce({
2053 pSide: {
2054 min: bounds.top,
2055 max: bounds.bottom
2056 },
2057 pOtherSide: {
2058 min: bounds.left,
2059 max: bounds.right
2060 },
2061 rectSide: {
2062 min: divBounds.top,
2063 max: divBounds.bottom
2064 },
2065 rectOtherSide: {
2066 min: divBounds.left,
2067 max: divBounds.right
2068 },
2069 velocity: particle.velocity.y,
2070 factor: getValue(particle.options.bounce.vertical)
2071 });
2072 if (resV.bounced) {
2073 if (resV.velocity !== undefined) {
2074 particle.velocity.y = resV.velocity;
2075 }
2076 if (resV.position !== undefined) {
2077 particle.position.y = resV.position;
2078 }
2079 }
2080}
2081function executeOnSingleOrMultiple(obj, callback) {
2082 return isArray(obj) ? obj.map((item, index) => callback(item, index)) : callback(obj, 0);
2083}
2084function itemFromSingleOrMultiple(obj, index, useIndex) {
2085 return isArray(obj) ? itemFromArray(obj, index, useIndex) : obj;
2086}
2087function findItemFromSingleOrMultiple(obj, callback) {
2088 return isArray(obj) ? obj.find((t, index) => callback(t, index)) : callback(obj, 0) ? obj : undefined;
2089}
2090function initParticleNumericAnimationValue(options, pxRatio) {
2091 const valueRange = options.value,
2092 animationOptions = options.animation,
2093 res = {
2094 delayTime: getRangeValue(animationOptions.delay) * 1000,
2095 enable: animationOptions.enable,
2096 value: getRangeValue(options.value) * pxRatio,
2097 max: getRangeMax(valueRange) * pxRatio,
2098 min: getRangeMin(valueRange) * pxRatio,
2099 loops: 0,
2100 maxLoops: getRangeValue(animationOptions.count),
2101 time: 0
2102 };
2103 if (animationOptions.enable) {
2104 res.decay = 1 - getRangeValue(animationOptions.decay);
2105 switch (animationOptions.mode) {
2106 case "increase":
2107 res.status = "increasing";
2108 break;
2109 case "decrease":
2110 res.status = "decreasing";
2111 break;
2112 case "random":
2113 res.status = getRandom() >= 0.5 ? "increasing" : "decreasing";
2114 break;
2115 }
2116 const autoStatus = animationOptions.mode === "auto";
2117 switch (animationOptions.startValue) {
2118 case "min":
2119 res.value = res.min;
2120 if (autoStatus) {
2121 res.status = "increasing";
2122 }
2123 break;
2124 case "max":
2125 res.value = res.max;
2126 if (autoStatus) {
2127 res.status = "decreasing";
2128 }
2129 break;
2130 case "random":
2131 default:
2132 res.value = randomInRange(res);
2133 if (autoStatus) {
2134 res.status = getRandom() >= 0.5 ? "increasing" : "decreasing";
2135 }
2136 break;
2137 }
2138 }
2139 res.initialValue = res.value;
2140 return res;
2141}
2142function getPositionOrSize(positionOrSize, canvasSize) {
2143 const isPercent = positionOrSize.mode === "percent";
2144 if (!isPercent) {
2145 const {
2146 mode: _,
2147 ...rest
2148 } = positionOrSize;
2149 return rest;
2150 }
2151 const isPosition = ("x" in positionOrSize);
2152 if (isPosition) {
2153 return {
2154 x: positionOrSize.x / 100 * canvasSize.width,
2155 y: positionOrSize.y / 100 * canvasSize.height
2156 };
2157 } else {
2158 return {
2159 width: positionOrSize.width / 100 * canvasSize.width,
2160 height: positionOrSize.height / 100 * canvasSize.height
2161 };
2162 }
2163}
2164function getPosition(position, canvasSize) {
2165 return getPositionOrSize(position, canvasSize);
2166}
2167function getSize(size, canvasSize) {
2168 return getPositionOrSize(size, canvasSize);
2169}
2170function isBoolean(arg) {
2171 return typeof arg === "boolean";
2172}
2173function isString(arg) {
2174 return typeof arg === "string";
2175}
2176function isNumber(arg) {
2177 return typeof arg === "number";
2178}
2179function isFunction(arg) {
2180 return typeof arg === "function";
2181}
2182function isObject(arg) {
2183 return typeof arg === "object" && arg !== null;
2184}
2185function isArray(arg) {
2186 return Array.isArray(arg);
2187}
2188;// CONCATENATED MODULE: ../../engine/dist/esm/Utils/NumberUtils.js
2189
2190
2191let _random = Math.random;
2192const easings = new Map();
2193function addEasing(name, easing) {
2194 if (easings.get(name)) {
2195 return;
2196 }
2197 easings.set(name, easing);
2198}
2199function getEasing(name) {
2200 return easings.get(name) || (value => value);
2201}
2202function setRandom(rnd = Math.random) {
2203 _random = rnd;
2204}
2205function getRandom() {
2206 return clamp(_random(), 0, 1 - 1e-16);
2207}
2208function clamp(num, min, max) {
2209 return Math.min(Math.max(num, min), max);
2210}
2211function mix(comp1, comp2, weight1, weight2) {
2212 return Math.floor((comp1 * weight1 + comp2 * weight2) / (weight1 + weight2));
2213}
2214function randomInRange(r) {
2215 const max = getRangeMax(r);
2216 let min = getRangeMin(r);
2217 if (max === min) {
2218 min = 0;
2219 }
2220 return getRandom() * (max - min) + min;
2221}
2222function getRangeValue(value) {
2223 return isNumber(value) ? value : randomInRange(value);
2224}
2225function getRangeMin(value) {
2226 return isNumber(value) ? value : value.min;
2227}
2228function getRangeMax(value) {
2229 return isNumber(value) ? value : value.max;
2230}
2231function setRangeValue(source, value) {
2232 if (source === value || value === undefined && isNumber(source)) {
2233 return source;
2234 }
2235 const min = getRangeMin(source),
2236 max = getRangeMax(source);
2237 return value !== undefined ? {
2238 min: Math.min(min, value),
2239 max: Math.max(max, value)
2240 } : setRangeValue(min, max);
2241}
2242function getValue(options) {
2243 const random = options.random,
2244 {
2245 enable,
2246 minimumValue
2247 } = isBoolean(random) ? {
2248 enable: random,
2249 minimumValue: 0
2250 } : random;
2251 return enable ? getRangeValue(setRangeValue(options.value, minimumValue)) : getRangeValue(options.value);
2252}
2253function getDistances(pointA, pointB) {
2254 const dx = pointA.x - pointB.x,
2255 dy = pointA.y - pointB.y;
2256 return {
2257 dx: dx,
2258 dy: dy,
2259 distance: Math.sqrt(dx ** 2 + dy ** 2)
2260 };
2261}
2262function getDistance(pointA, pointB) {
2263 return getDistances(pointA, pointB).distance;
2264}
2265function getParticleDirectionAngle(direction, position, center) {
2266 if (isNumber(direction)) {
2267 return direction * Math.PI / 180;
2268 }
2269 switch (direction) {
2270 case "top":
2271 return -Math.PI / 2;
2272 case "top-right":
2273 return -Math.PI / 4;
2274 case "right":
2275 return 0;
2276 case "bottom-right":
2277 return Math.PI / 4;
2278 case "bottom":
2279 return Math.PI / 2;
2280 case "bottom-left":
2281 return 3 * Math.PI / 4;
2282 case "left":
2283 return Math.PI;
2284 case "top-left":
2285 return -3 * Math.PI / 4;
2286 case "inside":
2287 return Math.atan2(center.y - position.y, center.x - position.x);
2288 case "outside":
2289 return Math.atan2(position.y - center.y, position.x - center.x);
2290 default:
2291 return getRandom() * Math.PI * 2;
2292 }
2293}
2294function getParticleBaseVelocity(direction) {
2295 const baseVelocity = Vector.origin;
2296 baseVelocity.length = 1;
2297 baseVelocity.angle = direction;
2298 return baseVelocity;
2299}
2300function collisionVelocity(v1, v2, m1, m2) {
2301 return Vector.create(v1.x * (m1 - m2) / (m1 + m2) + v2.x * 2 * m2 / (m1 + m2), v1.y);
2302}
2303function calcPositionFromSize(data) {
2304 return data.position && data.position.x !== undefined && data.position.y !== undefined ? {
2305 x: data.position.x * data.size.width / 100,
2306 y: data.position.y * data.size.height / 100
2307 } : undefined;
2308}
2309function calcPositionOrRandomFromSize(data) {
2310 return {
2311 x: (data.position?.x ?? getRandom() * 100) * data.size.width / 100,
2312 y: (data.position?.y ?? getRandom() * 100) * data.size.height / 100
2313 };
2314}
2315function calcPositionOrRandomFromSizeRanged(data) {
2316 const position = {
2317 x: data.position?.x !== undefined ? getRangeValue(data.position.x) : undefined,
2318 y: data.position?.y !== undefined ? getRangeValue(data.position.y) : undefined
2319 };
2320 return calcPositionOrRandomFromSize({
2321 size: data.size,
2322 position
2323 });
2324}
2325function calcExactPositionOrRandomFromSize(data) {
2326 return {
2327 x: data.position?.x ?? getRandom() * data.size.width,
2328 y: data.position?.y ?? getRandom() * data.size.height
2329 };
2330}
2331function calcExactPositionOrRandomFromSizeRanged(data) {
2332 const position = {
2333 x: data.position?.x !== undefined ? getRangeValue(data.position.x) : undefined,
2334 y: data.position?.y !== undefined ? getRangeValue(data.position.y) : undefined
2335 };
2336 return calcExactPositionOrRandomFromSize({
2337 size: data.size,
2338 position
2339 });
2340}
2341function parseAlpha(input) {
2342 return input ? input.endsWith("%") ? parseFloat(input) / 100 : parseFloat(input) : 1;
2343}
2344;// CONCATENATED MODULE: ../../shapes/arrow/dist/esm/ArrowDrawer.js
2345
2346class ArrowDrawer {
2347 draw(context, particle, radius) {
2348 const width = radius * 2,
2349 heightFactor = particle.heightFactor ?? 0.5,
2350 headWidthFactor = particle.headWidthFactor ?? 0.2,
2351 bodyHeightFactor = particle.bodyHeightFactor ?? 0.5,
2352 height = width * heightFactor,
2353 headWidth = width * headWidthFactor,
2354 bodyHeight = height * bodyHeightFactor;
2355 context.moveTo(-width / 2, 0);
2356 context.lineTo(-width / 2, -bodyHeight / 2);
2357 context.lineTo(width / 2 - headWidth, -bodyHeight / 2);
2358 context.lineTo(width / 2 - headWidth, -height / 2);
2359 context.lineTo(width / 2 + headWidth, 0);
2360 context.lineTo(width / 2 - headWidth, height / 2);
2361 context.lineTo(width / 2 - headWidth, bodyHeight / 2);
2362 context.lineTo(-width / 2, bodyHeight / 2);
2363 context.lineTo(-width / 2, 0);
2364 }
2365 particleInit(container, particle) {
2366 const shapeData = particle.shapeData;
2367 particle.heightFactor = getRangeValue(shapeData?.heightFactor ?? 0.5);
2368 particle.headWidthFactor = getRangeValue(shapeData?.headWidthFactor ?? 0.2);
2369 particle.bodyHeightFactor = getRangeValue(shapeData?.bodyHeightFactor ?? 0.5);
2370 }
2371}
2372;// CONCATENATED MODULE: ../../shapes/arrow/dist/esm/index.js
2373
2374async function loadArrowShape(engine, refresh = true) {
2375 await engine.addShape("arrow", new ArrowDrawer(), refresh);
2376}
2377;// CONCATENATED MODULE: ../../shapes/bubble/dist/esm/BubbleDrawer.js
2378class BubbleDrawer {
2379 afterEffect(context, particle, radius) {
2380 context.beginPath();
2381 context.arc(radius / 3, -radius / 3, radius / 3, 0, Math.PI * 2, false);
2382 context.closePath();
2383 context.fillStyle = "#fff9";
2384 context.fill();
2385 }
2386 draw(context, particle, radius) {
2387 context.arc(0, 0, radius, 0, Math.PI * 2, false);
2388 }
2389}
2390;// CONCATENATED MODULE: ../../shapes/bubble/dist/esm/index.js
2391
2392async function loadBubbleShape(engine, refresh = true) {
2393 await engine.addShape("bubble", new BubbleDrawer(), refresh);
2394}
2395;// CONCATENATED MODULE: ../../plugins/canvasMask/dist/esm/Options/Classes/CanvasMaskOverride.js
2396class CanvasMaskOverride {
2397 constructor() {
2398 this.color = true;
2399 this.opacity = false;
2400 }
2401 load(data) {
2402 if (!data) {
2403 return;
2404 }
2405 if (data.color !== undefined) {
2406 this.color = data.color;
2407 }
2408 if (data.opacity !== undefined) {
2409 this.opacity = data.opacity;
2410 }
2411 }
2412}
2413;// CONCATENATED MODULE: ../../plugins/canvasMask/dist/esm/Options/Classes/CanvasMaskPixels.js
2414
2415class CanvasMaskPixels {
2416 constructor() {
2417 this.filter = pixel => pixel.a > 0;
2418 this.offset = 4;
2419 }
2420 load(data) {
2421 if (!data) {
2422 return;
2423 }
2424 if (data.filter !== undefined) {
2425 if (isString(data.filter)) {
2426 if (Object.hasOwn(window, data.filter)) {
2427 const filter = window[data.filter];
2428 if (isFunction(filter)) {
2429 this.filter = filter;
2430 }
2431 }
2432 } else {
2433 this.filter = data.filter;
2434 }
2435 }
2436 if (data.offset !== undefined) {
2437 this.offset = data.offset;
2438 }
2439 }
2440}
2441;// CONCATENATED MODULE: ../../plugins/canvasMask/dist/esm/Options/Classes/ImageMask.js
2442class ImageMask {
2443 constructor() {
2444 this.src = "";
2445 }
2446 load(data) {
2447 if (!data) {
2448 return;
2449 }
2450 if (data.src !== undefined) {
2451 this.src = data.src;
2452 }
2453 }
2454}
2455;// CONCATENATED MODULE: ../../plugins/canvasMask/dist/esm/Options/Classes/FontTextMask.js
2456class FontTextMask {
2457 constructor() {
2458 this.family = "sans-serif";
2459 this.size = 100;
2460 }
2461 load(data) {
2462 if (!data) {
2463 return;
2464 }
2465 if (data.family !== undefined) {
2466 this.family = data.family;
2467 }
2468 if (data.size !== undefined) {
2469 this.size = data.size;
2470 }
2471 if (data.style !== undefined) {
2472 this.style = data.style;
2473 }
2474 if (data.variant !== undefined) {
2475 this.variant = data.variant;
2476 }
2477 if (data.weight !== undefined) {
2478 this.weight = data.weight;
2479 }
2480 }
2481}
2482;// CONCATENATED MODULE: ../../plugins/canvasMask/dist/esm/Options/Classes/TextMaskLine.js
2483class TextMaskLine {
2484 constructor() {
2485 this.separator = "\n";
2486 this.spacing = 10;
2487 }
2488 load(data) {
2489 if (!data) {
2490 return;
2491 }
2492 if (data.separator !== undefined) {
2493 this.separator = data.separator;
2494 }
2495 if (data.spacing !== undefined) {
2496 this.spacing = data.spacing;
2497 }
2498 }
2499}
2500;// CONCATENATED MODULE: ../../plugins/canvasMask/dist/esm/Options/Classes/TextMask.js
2501
2502
2503class TextMask {
2504 constructor() {
2505 this.color = "#000000";
2506 this.font = new FontTextMask();
2507 this.lines = new TextMaskLine();
2508 this.text = "";
2509 }
2510 load(data) {
2511 if (!data) {
2512 return;
2513 }
2514 if (data.color !== undefined) {
2515 this.color = data.color;
2516 }
2517 this.font.load(data.font);
2518 this.lines.load(data.lines);
2519 if (data.text !== undefined) {
2520 this.text = data.text;
2521 }
2522 }
2523}
2524;// CONCATENATED MODULE: ../../plugins/canvasMask/dist/esm/Options/Classes/CanvasMask.js
2525
2526
2527
2528
2529class CanvasMask {
2530 constructor() {
2531 this.enable = false;
2532 this.override = new CanvasMaskOverride();
2533 this.pixels = new CanvasMaskPixels();
2534 this.position = {
2535 x: 50,
2536 y: 50
2537 };
2538 this.scale = 1;
2539 }
2540 load(data) {
2541 if (!data) {
2542 return;
2543 }
2544 if (data.element !== undefined && data.element instanceof HTMLCanvasElement) {
2545 this.element = data.element;
2546 }
2547 if (data.enable !== undefined) {
2548 this.enable = data.enable;
2549 }
2550 if (data.image) {
2551 if (!this.image) {
2552 this.image = new ImageMask();
2553 }
2554 this.image.load(data.image);
2555 }
2556 this.pixels.load(data.pixels);
2557 if (data.position) {
2558 this.position = {
2559 x: data.position.x ?? this.position.x,
2560 y: data.position.y ?? this.position.y
2561 };
2562 }
2563 this.override.load(data.override);
2564 if (data.scale !== undefined) {
2565 this.scale = data.scale;
2566 }
2567 if (data.selector !== undefined) {
2568 this.selector = data.selector;
2569 }
2570 if (data.text) {
2571 if (!this.text) {
2572 this.text = new TextMask();
2573 }
2574 this.text.load(data.text);
2575 }
2576 }
2577}
2578;// CONCATENATED MODULE: ../../plugins/canvasMask/dist/esm/utils.js
2579
2580function shuffle(array) {
2581 for (let currentIndex = array.length - 1; currentIndex >= 0; currentIndex--) {
2582 const randomIndex = Math.floor(getRandom() * currentIndex);
2583 [array[currentIndex], array[randomIndex]] = [array[randomIndex], array[currentIndex]];
2584 }
2585 return array;
2586}
2587function addParticlesFromCanvasPixels(container, data, position, scale, override, filter) {
2588 const {
2589 height,
2590 width
2591 } = data,
2592 numPixels = height * width,
2593 indexArray = shuffle(range(numPixels)),
2594 maxParticles = Math.min(numPixels, container.actualOptions.particles.number.value),
2595 canvasSize = container.canvas.size;
2596 let selectedPixels = 0;
2597 const positionOffset = {
2598 x: canvasSize.width * position.x / 100 - width * scale / 2,
2599 y: canvasSize.height * position.y / 100 - height * scale / 2
2600 };
2601 while (selectedPixels < maxParticles && indexArray.length) {
2602 const nextIndex = indexArray.pop() || 0,
2603 pixelPos = {
2604 x: nextIndex % width,
2605 y: Math.floor(nextIndex / width)
2606 },
2607 pixel = data.pixels[pixelPos.y][pixelPos.x],
2608 shouldCreateParticle = filter(pixel);
2609 if (shouldCreateParticle) {
2610 const pos = {
2611 x: pixelPos.x * scale + positionOffset.x,
2612 y: pixelPos.y * scale + positionOffset.y
2613 };
2614 const pOptions = {};
2615 if (override.color) {
2616 pOptions.color = {
2617 value: pixel
2618 };
2619 }
2620 if (override.opacity) {
2621 pOptions.opacity = {
2622 value: pixel.a
2623 };
2624 }
2625 container.particles.addParticle(pos, pOptions);
2626 selectedPixels++;
2627 }
2628 }
2629}
2630function getCanvasImageData(ctx, size, offset, clear = true) {
2631 const imageData = ctx.getImageData(0, 0, size.width, size.height).data;
2632 if (clear) {
2633 ctx.clearRect(0, 0, size.width, size.height);
2634 }
2635 const pixels = [];
2636 for (let i = 0; i < imageData.length; i += offset) {
2637 const idx = i / offset,
2638 pos = {
2639 x: idx % size.width,
2640 y: Math.floor(idx / size.width)
2641 };
2642 if (!pixels[pos.y]) {
2643 pixels[pos.y] = [];
2644 }
2645 pixels[pos.y][pos.x] = {
2646 r: imageData[i],
2647 g: imageData[i + 1],
2648 b: imageData[i + 2],
2649 a: imageData[i + 3] / 255
2650 };
2651 }
2652 return {
2653 pixels,
2654 width: Math.min(...pixels.map(row => row.length)),
2655 height: pixels.length
2656 };
2657}
2658function getImageData(src, offset) {
2659 const image = new Image();
2660 image.crossOrigin = "Anonymous";
2661 const p = new Promise((resolve, reject) => {
2662 image.onerror = reject;
2663 image.onload = () => {
2664 const canvas = document.createElement("canvas");
2665 canvas.width = image.width;
2666 canvas.height = image.height;
2667 const context = canvas.getContext("2d");
2668 if (!context) {
2669 return reject(new Error(`${errorPrefix} Could not get canvas context`));
2670 }
2671 context.drawImage(image, 0, 0, image.width, image.height, 0, 0, canvas.width, canvas.height);
2672 resolve(getCanvasImageData(context, canvas, offset));
2673 };
2674 });
2675 image.src = src;
2676 return p;
2677}
2678function getTextData(textOptions, offset) {
2679 const canvas = document.createElement("canvas"),
2680 context = canvas.getContext("2d"),
2681 {
2682 font,
2683 text,
2684 lines: linesOptions,
2685 color
2686 } = textOptions;
2687 if (!text || !context) {
2688 return;
2689 }
2690 const lines = text.split(linesOptions.separator),
2691 fontSize = isNumber(font.size) ? `${font.size}px` : font.size,
2692 linesData = [];
2693 let maxWidth = 0,
2694 totalHeight = 0;
2695 for (const line of lines) {
2696 context.font = `${font.style || ""} ${font.variant || ""} ${font.weight || ""} ${fontSize} ${font.family}`;
2697 const measure = context.measureText(line),
2698 lineData = {
2699 measure,
2700 text: line,
2701 height: measure.actualBoundingBoxAscent + measure.actualBoundingBoxDescent,
2702 width: measure.width
2703 };
2704 maxWidth = Math.max(maxWidth || 0, lineData.width);
2705 totalHeight += lineData.height + linesOptions.spacing;
2706 linesData.push(lineData);
2707 }
2708 canvas.width = maxWidth;
2709 canvas.height = totalHeight;
2710 let currentHeight = 0;
2711 for (const line of linesData) {
2712 context.font = `${font.style || ""} ${font.variant || ""} ${font.weight || ""} ${fontSize} ${font.family}`;
2713 context.fillStyle = color;
2714 context.fillText(line.text, 0, currentHeight + line.measure.actualBoundingBoxAscent);
2715 currentHeight += line.height + linesOptions.spacing;
2716 }
2717 return getCanvasImageData(context, canvas, offset);
2718}
2719const range = n => [...Array(n).keys()];
2720;// CONCATENATED MODULE: ../../plugins/canvasMask/dist/esm/CanvasMaskInstance.js
2721
2722class CanvasMaskInstance {
2723 constructor(container, engine) {
2724 this._container = container;
2725 this._engine = engine;
2726 }
2727 async init() {
2728 const container = this._container,
2729 options = container.actualOptions.canvasMask;
2730 if (!options?.enable) {
2731 return;
2732 }
2733 let pixelData = {
2734 pixels: [],
2735 height: 0,
2736 width: 0
2737 };
2738 const offset = options.pixels.offset;
2739 if (options.image) {
2740 const url = options.image.src;
2741 if (!url) {
2742 return;
2743 }
2744 pixelData = await getImageData(url, offset);
2745 } else if (options.text) {
2746 const textOptions = options.text;
2747 const data = getTextData(textOptions, offset);
2748 if (!data) {
2749 return;
2750 }
2751 pixelData = data;
2752 } else if (options.element || options.selector) {
2753 const canvas = options.element || options.selector && document.querySelector(options.selector);
2754 if (!canvas) {
2755 return;
2756 }
2757 const context = canvas.getContext("2d");
2758 if (!context) {
2759 return;
2760 }
2761 pixelData = getCanvasImageData(context, canvas, offset);
2762 }
2763 addParticlesFromCanvasPixels(container, pixelData, options.position, options.scale, options.override, options.pixels.filter);
2764 }
2765}
2766;// CONCATENATED MODULE: ../../plugins/canvasMask/dist/esm/index.js
2767
2768
2769class CanvasMaskPlugin {
2770 constructor(engine) {
2771 this.id = "canvasMask";
2772 this._engine = engine;
2773 }
2774 getPlugin(container) {
2775 return new CanvasMaskInstance(container, this._engine);
2776 }
2777 loadOptions(options, source) {
2778 if (!this.needsPlugin(options) && !this.needsPlugin(source)) {
2779 return;
2780 }
2781 let canvasMaskOptions = options.canvasMask;
2782 if (canvasMaskOptions?.load === undefined) {
2783 options.canvasMask = canvasMaskOptions = new CanvasMask();
2784 }
2785 canvasMaskOptions.load(source?.canvasMask);
2786 }
2787 needsPlugin(options) {
2788 return options?.canvasMask?.enable ?? false;
2789 }
2790}
2791async function loadCanvasMaskPlugin(engine, refresh = true) {
2792 await engine.addPlugin(new CanvasMaskPlugin(engine), refresh);
2793}
2794;// CONCATENATED MODULE: ../../shapes/cards/dist/esm/Utils.js
2795function drawPath(ctx, radius, path) {
2796 if (!path.segments.length || !path.segments[0].values.length) {
2797 return;
2798 }
2799 ctx.moveTo(path.segments[0].values[0].x * radius, path.segments[0].values[0].y * radius);
2800 for (let i = 0; i < path.segments.length; i++) {
2801 const segment = path.segments[i];
2802 ctx.bezierCurveTo(segment.values[1].x * radius, segment.values[1].y * radius, segment.values[2].x * radius, segment.values[2].y * radius, segment.values[3].x * radius, segment.values[3].y * radius);
2803 }
2804 for (let i = path.segments.length - 1; i >= 0; i--) {
2805 const segment = path.segments[i];
2806 ctx.bezierCurveTo(-segment.values[2].x * radius, segment.values[2].y * radius, -segment.values[1].x * radius, segment.values[1].y * radius, -segment.values[0].x * radius, segment.values[0].y * radius);
2807 }
2808}
2809const n = 1.0 / 2;
2810const paths = {
2811 heart: {
2812 segments: [{
2813 values: [{
2814 x: 0,
2815 y: n
2816 }, {
2817 x: 0,
2818 y: n
2819 }, {
2820 x: n,
2821 y: 0
2822 }, {
2823 x: n,
2824 y: -n / 2
2825 }]
2826 }, {
2827 values: [{
2828 x: n,
2829 y: -n / 2
2830 }, {
2831 x: n,
2832 y: -n / 2
2833 }, {
2834 x: n,
2835 y: -n
2836 }, {
2837 x: n / 2,
2838 y: -n
2839 }]
2840 }, {
2841 values: [{
2842 x: n / 2,
2843 y: -n
2844 }, {
2845 x: n / 2,
2846 y: -n
2847 }, {
2848 x: 0,
2849 y: -n
2850 }, {
2851 x: 0,
2852 y: -n / 2
2853 }]
2854 }]
2855 },
2856 diamond: {
2857 segments: [{
2858 values: [{
2859 x: 0,
2860 y: n
2861 }, {
2862 x: 0,
2863 y: n
2864 }, {
2865 x: 3 * n / 4,
2866 y: 0
2867 }, {
2868 x: 3 * n / 4,
2869 y: 0
2870 }]
2871 }, {
2872 values: [{
2873 x: 3 * n / 4,
2874 y: 0
2875 }, {
2876 x: 3 * n / 4,
2877 y: 0
2878 }, {
2879 x: 0,
2880 y: -n
2881 }, {
2882 x: 0,
2883 y: -n
2884 }]
2885 }]
2886 },
2887 club: {
2888 segments: [{
2889 values: [{
2890 x: 0,
2891 y: -n
2892 }, {
2893 x: 0,
2894 y: -n
2895 }, {
2896 x: n / 2,
2897 y: -n
2898 }, {
2899 x: n / 2,
2900 y: -n / 2
2901 }]
2902 }, {
2903 values: [{
2904 x: n / 2,
2905 y: -n / 2
2906 }, {
2907 x: n / 2,
2908 y: -n / 2
2909 }, {
2910 x: n,
2911 y: -n / 2
2912 }, {
2913 x: n,
2914 y: 0
2915 }]
2916 }, {
2917 values: [{
2918 x: n,
2919 y: 0
2920 }, {
2921 x: n,
2922 y: 0
2923 }, {
2924 x: n,
2925 y: n / 2
2926 }, {
2927 x: n / 2,
2928 y: n / 2
2929 }]
2930 }, {
2931 values: [{
2932 x: n / 2,
2933 y: n / 2
2934 }, {
2935 x: n / 2,
2936 y: n / 2
2937 }, {
2938 x: n / 8,
2939 y: n / 2
2940 }, {
2941 x: n / 8,
2942 y: n / 8
2943 }]
2944 }, {
2945 values: [{
2946 x: n / 8,
2947 y: n / 8
2948 }, {
2949 x: n / 8,
2950 y: n / 2
2951 }, {
2952 x: n / 2,
2953 y: n
2954 }, {
2955 x: n / 2,
2956 y: n
2957 }]
2958 }, {
2959 values: [{
2960 x: n / 2,
2961 y: n
2962 }, {
2963 x: n / 2,
2964 y: n
2965 }, {
2966 x: 0,
2967 y: n
2968 }, {
2969 x: 0,
2970 y: n
2971 }]
2972 }]
2973 },
2974 spade: {
2975 segments: [{
2976 values: [{
2977 x: 0,
2978 y: -n
2979 }, {
2980 x: 0,
2981 y: -n
2982 }, {
2983 x: n,
2984 y: -n / 2
2985 }, {
2986 x: n,
2987 y: 0
2988 }]
2989 }, {
2990 values: [{
2991 x: n,
2992 y: 0
2993 }, {
2994 x: n,
2995 y: 0
2996 }, {
2997 x: n,
2998 y: n / 2
2999 }, {
3000 x: n / 2,
3001 y: n / 2
3002 }]
3003 }, {
3004 values: [{
3005 x: n / 2,
3006 y: n / 2
3007 }, {
3008 x: n / 2,
3009 y: n / 2
3010 }, {
3011 x: n / 8,
3012 y: n / 2
3013 }, {
3014 x: n / 8,
3015 y: n / 8
3016 }]
3017 }, {
3018 values: [{
3019 x: n / 8,
3020 y: n / 8
3021 }, {
3022 x: n / 8,
3023 y: n / 2
3024 }, {
3025 x: n / 2,
3026 y: n
3027 }, {
3028 x: n / 2,
3029 y: n
3030 }]
3031 }, {
3032 values: [{
3033 x: n / 2,
3034 y: n
3035 }, {
3036 x: n / 2,
3037 y: n
3038 }, {
3039 x: 0,
3040 y: n
3041 }, {
3042 x: 0,
3043 y: n
3044 }]
3045 }]
3046 }
3047};
3048;// CONCATENATED MODULE: ../../shapes/cards/dist/esm/CardsSuitsDrawers.js
3049
3050class SpadeDrawer {
3051 draw(context, _particle, radius) {
3052 drawPath(context, radius, paths.spade);
3053 }
3054}
3055class HeartDrawer {
3056 draw(context, _particle, radius) {
3057 drawPath(context, radius, paths.heart);
3058 }
3059}
3060class DiamondDrawer {
3061 draw(context, _particle, radius) {
3062 drawPath(context, radius, paths.diamond);
3063 }
3064}
3065class ClubDrawer {
3066 draw(context, _particle, radius) {
3067 drawPath(context, radius, paths.club);
3068 }
3069}
3070;// CONCATENATED MODULE: ../../shapes/cards/dist/esm/index.js
3071
3072async function loadCardsShape(engine, refresh = true) {
3073 await engine.addShape(["spade", "spades"], new SpadeDrawer(), refresh);
3074 await engine.addShape(["heart", "hearts"], new HeartDrawer(), refresh);
3075 await engine.addShape(["diamond", "diamonds"], new DiamondDrawer(), refresh);
3076 await engine.addShape(["club", "clubs"], new ClubDrawer(), refresh);
3077}
3078;// CONCATENATED MODULE: ../../shapes/cog/dist/esm/CogDrawer.js
3079
3080class CogDrawer {
3081 afterEffect(ctx, particle, radius) {
3082 if (particle.cogHoleRadius === undefined || particle.cogInnerRadius === undefined || particle.cogInnerTaper === undefined || particle.cogNotches === undefined || particle.cogOuterTaper === undefined) {
3083 return;
3084 }
3085 const pi2 = 2 * Math.PI,
3086 holeRadius = radius * particle.cogHoleRadius / 100;
3087 ctx.globalCompositeOperation = "destination-out";
3088 ctx.beginPath();
3089 ctx.moveTo(holeRadius, 0);
3090 ctx.arc(0, 0, holeRadius, 0, pi2);
3091 ctx.closePath();
3092 ctx.fill();
3093 ctx.globalCompositeOperation = "source-over";
3094 }
3095 draw(ctx, particle, radius) {
3096 if (particle.cogHoleRadius === undefined || particle.cogInnerRadius === undefined || particle.cogInnerTaper === undefined || particle.cogNotches === undefined || particle.cogOuterTaper === undefined) {
3097 return;
3098 }
3099 const pi2 = 2 * Math.PI,
3100 angle = pi2 / (particle.cogNotches * 2),
3101 taperAI = angle * particle.cogInnerTaper * 0.005,
3102 taperAO = angle * particle.cogOuterTaper * 0.005,
3103 innerRadius = radius * particle.cogInnerRadius / 100;
3104 let a = angle,
3105 toggle = false;
3106 ctx.moveTo(radius * Math.cos(taperAO), radius * Math.sin(taperAO));
3107 for (; a <= pi2; a += angle) {
3108 if (toggle) {
3109 ctx.lineTo(innerRadius * Math.cos(a - taperAI), innerRadius * Math.sin(a - taperAI));
3110 ctx.lineTo(radius * Math.cos(a + taperAO), radius * Math.sin(a + taperAO));
3111 } else {
3112 ctx.lineTo(radius * Math.cos(a - taperAO), radius * Math.sin(a - taperAO));
3113 ctx.lineTo(innerRadius * Math.cos(a + taperAI), innerRadius * Math.sin(a + taperAI));
3114 }
3115 toggle = !toggle;
3116 }
3117 }
3118 particleInit(container, particle) {
3119 const shapeData = particle.shapeData;
3120 particle.cogHoleRadius = getRangeValue(shapeData?.holeRadius ?? 44);
3121 particle.cogInnerRadius = getRangeValue(shapeData?.innerRadius ?? 72);
3122 particle.cogInnerTaper = getRangeValue(shapeData?.innerTaper ?? 35);
3123 particle.cogNotches = getRangeValue(shapeData?.notches ?? 7);
3124 particle.cogOuterTaper = getRangeValue(shapeData?.outerTaper ?? 50);
3125 }
3126}
3127;// CONCATENATED MODULE: ../../shapes/cog/dist/esm/index.js
3128
3129async function loadCogShape(engine, refresh = true) {
3130 await engine.addShape("cog", new CogDrawer(), refresh);
3131}
3132;// CONCATENATED MODULE: ../../paths/curves/dist/esm/Curves.js
3133
3134function CurvesPathGen(rndFunc, period, nbHarmonics, attenHarmonics, lowValue = 0, highValue = 1) {
3135 const arP0 = [],
3136 arP1 = [],
3137 amplitudes = [],
3138 increments = [],
3139 phases = [],
3140 randomFunc = rndFunc ?? getRandom;
3141 let globAmplitude = 0;
3142 if (nbHarmonics < 1) nbHarmonics = 1;
3143 for (let kh = 1; kh <= nbHarmonics; ++kh) {
3144 arP0[kh] = randomFunc();
3145 arP1[kh] = randomFunc();
3146 amplitudes[kh] = kh === 1 ? 1 : amplitudes[kh - 1] * attenHarmonics;
3147 globAmplitude += amplitudes[kh];
3148 increments[kh] = kh / period;
3149 phases[kh] = randomFunc();
3150 }
3151 amplitudes.forEach((value, kh) => amplitudes[kh] = value / globAmplitude * (highValue - lowValue));
3152 return () => {
3153 let pf,
3154 pfl,
3155 signal = 0;
3156 for (let kh = nbHarmonics; kh >= 1; --kh) {
3157 pf = phases[kh] += increments[kh];
3158 if (phases[kh] >= 1) {
3159 pf = phases[kh] -= 1;
3160 arP0[kh] = arP1[kh];
3161 arP1[kh] = randomFunc();
3162 }
3163 pfl = pf ** 2 * (3 - 2 * pf);
3164 signal += (arP0[kh] * (1 - pfl) + arP1[kh] * pfl) * amplitudes[kh];
3165 }
3166 return signal + lowValue;
3167 };
3168}
3169;// CONCATENATED MODULE: ../../paths/curves/dist/esm/CurvesPathGenerator.js
3170
3171
3172class CurvesPathGenerator {
3173 constructor() {
3174 this.options = {
3175 rndFunc: null,
3176 period: 100,
3177 nbHarmonics: 2,
3178 attenHarmonics: 0.8,
3179 lowValue: -0.03,
3180 highValue: 0.03
3181 };
3182 }
3183 generate(p) {
3184 if (!p.pathGen) {
3185 const options = this.options;
3186 p.pathGen = CurvesPathGen(options.rndFunc, options.period, options.nbHarmonics, options.attenHarmonics, options.lowValue, options.highValue);
3187 }
3188 if (!p.curveVelocity) {
3189 p.curveVelocity = Vector.origin;
3190 p.curveVelocity.length = getRandom() * 0.6 + 0.8;
3191 p.curveVelocity.angle = getRandom() * Math.PI * 2;
3192 } else {
3193 p.curveVelocity.length += 0.01;
3194 p.curveVelocity.angle = (p.curveVelocity.angle + p.pathGen()) % (Math.PI * 2);
3195 }
3196 p.velocity.x = 0;
3197 p.velocity.y = 0;
3198 return p.curveVelocity;
3199 }
3200 init(container) {
3201 const sourceOptions = container.actualOptions.particles.move.path.options,
3202 {
3203 options
3204 } = this;
3205 if (isFunction(sourceOptions.rndFunc)) {
3206 options.rndFunc = sourceOptions.rndFunc;
3207 } else if (isString(sourceOptions.rndFunc)) {
3208 options.rndFunc = window[sourceOptions.rndFunc] || this.options.rndFunc;
3209 }
3210 options.period = sourceOptions.period ?? options.period;
3211 options.nbHarmonics = sourceOptions.nbHarmonics ?? options.nbHarmonics;
3212 options.attenHarmonics = sourceOptions.attenHarmonics ?? options.attenHarmonics;
3213 options.lowValue = sourceOptions.lowValue ?? options.lowValue;
3214 options.highValue = sourceOptions.highValue ?? options.highValue;
3215 }
3216 reset(particle) {
3217 delete particle.pathGen;
3218 delete particle.curveVelocity;
3219 }
3220 update() {}
3221}
3222;// CONCATENATED MODULE: ../../paths/curves/dist/esm/index.js
3223
3224const curvesPathName = "curvesPathGenerator";
3225async function loadCurvesPath(engine, refresh = true) {
3226 await engine.addPathGenerator(curvesPathName, new CurvesPathGenerator(), refresh);
3227}
3228;// CONCATENATED MODULE: ../../plugins/easings/back/dist/esm/index.js
3229
3230async function loadEasingBackPlugin() {
3231 addEasing("ease-in-back", value => {
3232 const c1 = 1.70158,
3233 c3 = c1 + 1;
3234 return c3 * value ** 3 - c1 * value ** 2;
3235 });
3236 addEasing("ease-out-back", value => {
3237 const c1 = 1.70158,
3238 c3 = c1 + 1;
3239 return 1 + c3 * Math.pow(value - 1, 3) + c1 * Math.pow(value - 1, 2);
3240 });
3241 addEasing("ease-in-out-back", value => {
3242 const c1 = 1.70158,
3243 c2 = c1 * 1.525;
3244 return value < 0.5 ? (2 * value) ** 2 * ((c2 + 1) * 2 * value - c2) / 2 : ((2 * value - 2) ** 2 * ((c2 + 1) * (value * 2 - 2) + c2) + 2) / 2;
3245 });
3246}
3247;// CONCATENATED MODULE: ../../plugins/easings/circ/dist/esm/index.js
3248
3249async function loadEasingCircPlugin() {
3250 addEasing("ease-in-circ", value => 1 - Math.sqrt(1 - value ** 2));
3251 addEasing("ease-out-circ", value => Math.sqrt(1 - (value - 1) ** 2));
3252 addEasing("ease-in-out-circ", value => value < 0.5 ? (1 - Math.sqrt(1 - (2 * value) ** 2)) / 2 : (Math.sqrt(1 - (-2 * value + 2) ** 2) + 1) / 2);
3253}
3254;// CONCATENATED MODULE: ../../plugins/easings/cubic/dist/esm/index.js
3255
3256async function loadEasingCubicPlugin() {
3257 addEasing("ease-in-cubic", value => value ** 3);
3258 addEasing("ease-out-cubic", value => 1 - (1 - value) ** 3);
3259 addEasing("ease-in-out-cubic", value => value < 0.5 ? 4 * value ** 3 : 1 - (-2 * value + 2) ** 3 / 2);
3260}
3261;// CONCATENATED MODULE: ../../plugins/easings/expo/dist/esm/index.js
3262
3263async function loadEasingExpoPlugin() {
3264 addEasing("ease-in-expo", value => !value ? 0 : 2 ** (10 * value - 10));
3265 addEasing("ease-out-expo", value => value === 1 ? 1 : 1 - Math.pow(2, -10 * value));
3266 addEasing("ease-in-out-expo", value => !value ? 0 : value === 1 ? 1 : value < 0.5 ? 2 ** (20 * value - 10) / 2 : (2 - 2 ** (-20 * value + 10)) / 2);
3267}
3268;// CONCATENATED MODULE: ../../plugins/easings/quart/dist/esm/index.js
3269
3270async function loadEasingQuartPlugin() {
3271 addEasing("ease-in-quart", value => value ** 4);
3272 addEasing("ease-out-quart", value => 1 - (1 - value) ** 4);
3273 addEasing("ease-in-out-quart", value => value < 0.5 ? 8 * value ** 4 : 1 - (-2 * value + 2) ** 4 / 2);
3274}
3275;// CONCATENATED MODULE: ../../plugins/easings/quint/dist/esm/index.js
3276
3277async function loadEasingQuintPlugin() {
3278 addEasing("ease-in-quint", value => value ** 5);
3279 addEasing("ease-out-quint", value => 1 - (1 - value) ** 5);
3280 addEasing("ease-in-out-quint", value => value < 0.5 ? 16 * value ** 5 : 1 - (-2 * value + 2) ** 5 / 2);
3281}
3282;// CONCATENATED MODULE: ../../plugins/easings/sine/dist/esm/index.js
3283
3284async function loadEasingSinePlugin() {
3285 addEasing("ease-in-sine", value => 1 - Math.cos(value * Math.PI / 2));
3286 addEasing("ease-out-sine", value => Math.sin(value * Math.PI / 2));
3287 addEasing("ease-in-out-sine", value => -(Math.cos(Math.PI * value) - 1) / 2);
3288}
3289;// CONCATENATED MODULE: ../../plugins/exports/image/dist/esm/ExportImageInstance.js
3290class ExportImageInstance {
3291 constructor(container, engine) {
3292 this._exportImage = async data => {
3293 const element = this._container.canvas.element;
3294 if (!element) {
3295 return;
3296 }
3297 return new Promise(resolve => {
3298 element.toBlob(blob => {
3299 if (!blob) {
3300 resolve(undefined);
3301 return;
3302 }
3303 resolve(blob);
3304 }, data.type ?? "image/png", data.quality);
3305 });
3306 };
3307 this._container = container;
3308 this._engine = engine;
3309 }
3310 async export(type, data) {
3311 const res = {
3312 supported: false
3313 };
3314 switch (type) {
3315 case "image":
3316 res.supported = true;
3317 res.blob = await this._exportImage(data);
3318 break;
3319 }
3320 return res;
3321 }
3322}
3323;// CONCATENATED MODULE: ../../plugins/exports/image/dist/esm/index.js
3324
3325class ExportImagePlugin {
3326 constructor(engine) {
3327 this.id = "export-image";
3328 this._engine = engine;
3329 }
3330 getPlugin(container) {
3331 return new ExportImageInstance(container, this._engine);
3332 }
3333 loadOptions() {}
3334 needsPlugin() {
3335 return true;
3336 }
3337}
3338async function loadExportImagePlugin(engine, refresh = true) {
3339 await engine.addPlugin(new ExportImagePlugin(engine), refresh);
3340}
3341;// CONCATENATED MODULE: ../../plugins/exports/json/dist/esm/ExportJSONInstance.js
3342class ExportJSONInstance {
3343 constructor(container, engine) {
3344 this._exportJSON = async () => {
3345 const json = JSON.stringify(this._container.actualOptions, (key, value) => {
3346 if (key.startsWith("_")) {
3347 return;
3348 }
3349 return value;
3350 }, 2);
3351 return new Blob([json], {
3352 type: "application/json"
3353 });
3354 };
3355 this._container = container;
3356 this._engine = engine;
3357 }
3358 async export(type) {
3359 const res = {
3360 supported: false
3361 };
3362 switch (type) {
3363 case "json":
3364 res.supported = true;
3365 res.blob = await this._exportJSON();
3366 break;
3367 }
3368 return res;
3369 }
3370}
3371;// CONCATENATED MODULE: ../../plugins/exports/json/dist/esm/index.js
3372
3373class ExportJSONPlugin {
3374 constructor(engine) {
3375 this.id = "export-json";
3376 this._engine = engine;
3377 }
3378 getPlugin(container) {
3379 return new ExportJSONInstance(container, this._engine);
3380 }
3381 loadOptions() {}
3382 needsPlugin() {
3383 return true;
3384 }
3385}
3386async function loadExportJSONPlugin(engine, refresh = true) {
3387 await engine.addPlugin(new ExportJSONPlugin(engine), refresh);
3388}
3389;// CONCATENATED MODULE: ../../plugins/exports/video/dist/esm/ExportVideoInstance.js
3390const videoTypes = ["webm", "ogg", "mp4", "x-matroska"],
3391 codecs = ["vp9", "vp9.0", "vp8", "vp8.0", "avc1", "av1", "h265", "h.265", "h264", "h.264", "opus", "pcm", "aac", "mpeg", "mp4a"];
3392function getVideoSupportedMimeTypes() {
3393 const isSupported = MediaRecorder.isTypeSupported,
3394 supported = [];
3395 videoTypes.forEach(type => {
3396 const mimeType = `video/${type}`;
3397 codecs.forEach(codec => [`${mimeType};codecs=${codec}`, `${mimeType};codecs=${codec.toUpperCase()}`].forEach(variation => {
3398 if (isSupported(variation)) {
3399 supported.push(variation);
3400 }
3401 }));
3402 if (isSupported(mimeType)) {
3403 supported.push(mimeType);
3404 }
3405 });
3406 return supported;
3407}
3408class ExportVideoInstance {
3409 constructor(container, engine) {
3410 this._supportedTypes = [];
3411 this._exportVideo = async data => {
3412 const element = this._container.canvas.element;
3413 if (!element) {
3414 return;
3415 }
3416 return new Promise(resolve => {
3417 const stream = element.captureStream(data.fps ?? this._container.actualOptions.fpsLimit),
3418 mimeType = data.mimeType ?? this._supportedTypes[0],
3419 recorder = new MediaRecorder(stream, {
3420 mimeType
3421 }),
3422 chunks = [];
3423 recorder.addEventListener("dataavailable", event => {
3424 chunks.push(event.data);
3425 });
3426 recorder.addEventListener("stop", () => {
3427 resolve(new Blob(chunks, {
3428 type: mimeType
3429 }));
3430 });
3431 recorder.start();
3432 setTimeout(() => {
3433 recorder.stop();
3434 }, data.duration ?? 5000);
3435 });
3436 };
3437 this._container = container;
3438 this._engine = engine;
3439 this._supportedTypes = getVideoSupportedMimeTypes();
3440 }
3441 async export(type, data) {
3442 const res = {
3443 supported: false
3444 };
3445 switch (type) {
3446 case "video":
3447 res.supported = true;
3448 res.blob = await this._exportVideo(data);
3449 break;
3450 }
3451 return res;
3452 }
3453}
3454;// CONCATENATED MODULE: ../../plugins/exports/video/dist/esm/index.js
3455
3456class ExportVideoPlugin {
3457 constructor(engine) {
3458 this.id = "export-video";
3459 this._engine = engine;
3460 }
3461 getPlugin(container) {
3462 return new ExportVideoInstance(container, this._engine);
3463 }
3464 loadOptions() {}
3465 needsPlugin() {
3466 return true;
3467 }
3468}
3469async function loadExportVideoPlugin(engine, refresh = true) {
3470 await engine.addPlugin(new ExportVideoPlugin(engine), refresh);
3471}
3472;// CONCATENATED MODULE: ../../engine/dist/esm/Options/Classes/OptionsColor.js
3473
3474class OptionsColor {
3475 constructor() {
3476 this.value = "";
3477 }
3478 static create(source, data) {
3479 const color = new OptionsColor();
3480 color.load(source);
3481 if (data !== undefined) {
3482 if (isString(data) || isArray(data)) {
3483 color.load({
3484 value: data
3485 });
3486 } else {
3487 color.load(data);
3488 }
3489 }
3490 return color;
3491 }
3492 load(data) {
3493 if (data?.value === undefined) {
3494 return;
3495 }
3496 this.value = data.value;
3497 }
3498}
3499;// CONCATENATED MODULE: ../../engine/dist/esm/Options/Classes/AnimationOptions.js
3500
3501class AnimationOptions {
3502 constructor() {
3503 this.count = 0;
3504 this.enable = false;
3505 this.speed = 1;
3506 this.decay = 0;
3507 this.delay = 0;
3508 this.sync = false;
3509 }
3510 load(data) {
3511 if (!data) {
3512 return;
3513 }
3514 if (data.count !== undefined) {
3515 this.count = setRangeValue(data.count);
3516 }
3517 if (data.enable !== undefined) {
3518 this.enable = data.enable;
3519 }
3520 if (data.speed !== undefined) {
3521 this.speed = setRangeValue(data.speed);
3522 }
3523 if (data.decay !== undefined) {
3524 this.decay = setRangeValue(data.decay);
3525 }
3526 if (data.delay !== undefined) {
3527 this.delay = setRangeValue(data.delay);
3528 }
3529 if (data.sync !== undefined) {
3530 this.sync = data.sync;
3531 }
3532 }
3533}
3534class RangedAnimationOptions extends AnimationOptions {
3535 constructor() {
3536 super();
3537 this.mode = "auto";
3538 this.startValue = "random";
3539 }
3540 load(data) {
3541 super.load(data);
3542 if (!data) {
3543 return;
3544 }
3545 if (data.minimumValue !== undefined) {
3546 this.minimumValue = data.minimumValue;
3547 }
3548 if (data.mode !== undefined) {
3549 this.mode = data.mode;
3550 }
3551 if (data.startValue !== undefined) {
3552 this.startValue = data.startValue;
3553 }
3554 }
3555}
3556;// CONCATENATED MODULE: ../../engine/dist/esm/Options/Classes/Random.js
3557class Random {
3558 constructor() {
3559 this.enable = false;
3560 this.minimumValue = 0;
3561 }
3562 load(data) {
3563 if (!data) {
3564 return;
3565 }
3566 if (data.enable !== undefined) {
3567 this.enable = data.enable;
3568 }
3569 if (data.minimumValue !== undefined) {
3570 this.minimumValue = data.minimumValue;
3571 }
3572 }
3573}
3574;// CONCATENATED MODULE: ../../engine/dist/esm/Options/Classes/ValueWithRandom.js
3575
3576
3577
3578
3579class ValueWithRandom {
3580 constructor() {
3581 this.random = new Random();
3582 this.value = 0;
3583 }
3584 load(data) {
3585 if (!data) {
3586 return;
3587 }
3588 if (isBoolean(data.random)) {
3589 this.random.enable = data.random;
3590 } else {
3591 this.random.load(data.random);
3592 }
3593 if (data.value !== undefined) {
3594 this.value = setRangeValue(data.value, this.random.enable ? this.random.minimumValue : undefined);
3595 }
3596 }
3597}
3598class AnimationValueWithRandom extends ValueWithRandom {
3599 constructor() {
3600 super();
3601 this.animation = new AnimationOptions();
3602 }
3603 get anim() {
3604 return this.animation;
3605 }
3606 set anim(value) {
3607 this.animation = value;
3608 }
3609 load(data) {
3610 super.load(data);
3611 if (!data) {
3612 return;
3613 }
3614 const animation = data.animation ?? data.anim;
3615 if (animation !== undefined) {
3616 this.animation.load(animation);
3617 }
3618 }
3619}
3620class RangedAnimationValueWithRandom extends AnimationValueWithRandom {
3621 constructor() {
3622 super();
3623 this.animation = new RangedAnimationOptions();
3624 }
3625 load(data) {
3626 super.load(data);
3627 if (!data) {
3628 return;
3629 }
3630 const animation = data.animation ?? data.anim;
3631 if (animation !== undefined) {
3632 this.value = setRangeValue(this.value, this.animation.enable ? this.animation.minimumValue : undefined);
3633 }
3634 }
3635}
3636;// CONCATENATED MODULE: ../../plugins/absorbers/dist/esm/Options/Classes/AbsorberSizeLimit.js
3637class AbsorberSizeLimit {
3638 constructor() {
3639 this.radius = 0;
3640 this.mass = 0;
3641 }
3642 load(data) {
3643 if (!data) {
3644 return;
3645 }
3646 if (data.mass !== undefined) {
3647 this.mass = data.mass;
3648 }
3649 if (data.radius !== undefined) {
3650 this.radius = data.radius;
3651 }
3652 }
3653}
3654;// CONCATENATED MODULE: ../../plugins/absorbers/dist/esm/Options/Classes/AbsorberSize.js
3655
3656
3657class AbsorberSize extends ValueWithRandom {
3658 constructor() {
3659 super();
3660 this.density = 5;
3661 this.value = 50;
3662 this.limit = new AbsorberSizeLimit();
3663 }
3664 load(data) {
3665 if (!data) {
3666 return;
3667 }
3668 super.load(data);
3669 if (data.density !== undefined) {
3670 this.density = data.density;
3671 }
3672 if (isNumber(data.limit)) {
3673 this.limit.radius = data.limit;
3674 } else {
3675 this.limit.load(data.limit);
3676 }
3677 }
3678}
3679;// CONCATENATED MODULE: ../../plugins/absorbers/dist/esm/Options/Classes/Absorber.js
3680
3681
3682class Absorber {
3683 constructor() {
3684 this.color = new OptionsColor();
3685 this.color.value = "#000000";
3686 this.draggable = false;
3687 this.opacity = 1;
3688 this.destroy = true;
3689 this.orbits = false;
3690 this.size = new AbsorberSize();
3691 }
3692 load(data) {
3693 if (data === undefined) {
3694 return;
3695 }
3696 if (data.color !== undefined) {
3697 this.color = OptionsColor.create(this.color, data.color);
3698 }
3699 if (data.draggable !== undefined) {
3700 this.draggable = data.draggable;
3701 }
3702 this.name = data.name;
3703 if (data.opacity !== undefined) {
3704 this.opacity = data.opacity;
3705 }
3706 if (data.position !== undefined) {
3707 this.position = {};
3708 if (data.position.x !== undefined) {
3709 this.position.x = setRangeValue(data.position.x);
3710 }
3711 if (data.position.y !== undefined) {
3712 this.position.y = setRangeValue(data.position.y);
3713 }
3714 }
3715 if (data.size !== undefined) {
3716 this.size.load(data.size);
3717 }
3718 if (data.destroy !== undefined) {
3719 this.destroy = data.destroy;
3720 }
3721 if (data.orbits !== undefined) {
3722 this.orbits = data.orbits;
3723 }
3724 }
3725}
3726;// CONCATENATED MODULE: ../../engine/dist/esm/Utils/ColorUtils.js
3727
3728
3729const randomColorValue = "random",
3730 midColorValue = "mid",
3731 colorManagers = new Map();
3732function addColorManager(manager) {
3733 colorManagers.set(manager.key, manager);
3734}
3735function hue2rgb(p, q, t) {
3736 if (t < 0) {
3737 t += 1;
3738 }
3739 if (t > 1) {
3740 t -= 1;
3741 }
3742 if (t < 1 / 6) {
3743 return p + (q - p) * 6 * t;
3744 }
3745 if (t < 1 / 2) {
3746 return q;
3747 }
3748 if (t < 2 / 3) {
3749 return p + (q - p) * (2 / 3 - t) * 6;
3750 }
3751 return p;
3752}
3753function stringToRgba(input) {
3754 for (const [, manager] of colorManagers) {
3755 if (input.startsWith(manager.stringPrefix)) {
3756 return manager.parseString(input);
3757 }
3758 }
3759 const shorthandRegex = /^#?([a-f\d])([a-f\d])([a-f\d])([a-f\d])?$/i,
3760 hexFixed = input.replace(shorthandRegex, (_, r, g, b, a) => {
3761 return r + r + g + g + b + b + (a !== undefined ? a + a : "");
3762 }),
3763 regex = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})?$/i,
3764 result = regex.exec(hexFixed);
3765 return result ? {
3766 a: result[4] !== undefined ? parseInt(result[4], 16) / 0xff : 1,
3767 b: parseInt(result[3], 16),
3768 g: parseInt(result[2], 16),
3769 r: parseInt(result[1], 16)
3770 } : undefined;
3771}
3772function rangeColorToRgb(input, index, useIndex = true) {
3773 if (!input) {
3774 return;
3775 }
3776 const color = isString(input) ? {
3777 value: input
3778 } : input;
3779 if (isString(color.value)) {
3780 return colorToRgb(color.value, index, useIndex);
3781 }
3782 if (isArray(color.value)) {
3783 return rangeColorToRgb({
3784 value: itemFromArray(color.value, index, useIndex)
3785 });
3786 }
3787 for (const [, manager] of colorManagers) {
3788 const res = manager.handleRangeColor(color);
3789 if (res) {
3790 return res;
3791 }
3792 }
3793}
3794function colorToRgb(input, index, useIndex = true) {
3795 if (!input) {
3796 return;
3797 }
3798 const color = isString(input) ? {
3799 value: input
3800 } : input;
3801 if (isString(color.value)) {
3802 return color.value === randomColorValue ? getRandomRgbColor() : stringToRgb(color.value);
3803 }
3804 if (isArray(color.value)) {
3805 return colorToRgb({
3806 value: itemFromArray(color.value, index, useIndex)
3807 });
3808 }
3809 for (const [, manager] of colorManagers) {
3810 const res = manager.handleColor(color);
3811 if (res) {
3812 return res;
3813 }
3814 }
3815}
3816function colorToHsl(color, index, useIndex = true) {
3817 const rgb = colorToRgb(color, index, useIndex);
3818 return rgb ? rgbToHsl(rgb) : undefined;
3819}
3820function rangeColorToHsl(color, index, useIndex = true) {
3821 const rgb = rangeColorToRgb(color, index, useIndex);
3822 return rgb ? rgbToHsl(rgb) : undefined;
3823}
3824function rgbToHsl(color) {
3825 const r1 = color.r / 255,
3826 g1 = color.g / 255,
3827 b1 = color.b / 255,
3828 max = Math.max(r1, g1, b1),
3829 min = Math.min(r1, g1, b1),
3830 res = {
3831 h: 0,
3832 l: (max + min) / 2,
3833 s: 0
3834 };
3835 if (max !== min) {
3836 res.s = res.l < 0.5 ? (max - min) / (max + min) : (max - min) / (2.0 - max - min);
3837 res.h = r1 === max ? (g1 - b1) / (max - min) : res.h = g1 === max ? 2.0 + (b1 - r1) / (max - min) : 4.0 + (r1 - g1) / (max - min);
3838 }
3839 res.l *= 100;
3840 res.s *= 100;
3841 res.h *= 60;
3842 if (res.h < 0) {
3843 res.h += 360;
3844 }
3845 if (res.h >= 360) {
3846 res.h -= 360;
3847 }
3848 return res;
3849}
3850function stringToAlpha(input) {
3851 return stringToRgba(input)?.a;
3852}
3853function stringToRgb(input) {
3854 return stringToRgba(input);
3855}
3856function hslToRgb(hsl) {
3857 const result = {
3858 b: 0,
3859 g: 0,
3860 r: 0
3861 },
3862 hslPercent = {
3863 h: hsl.h / 360,
3864 l: hsl.l / 100,
3865 s: hsl.s / 100
3866 };
3867 if (!hslPercent.s) {
3868 result.r = result.g = result.b = hslPercent.l;
3869 } else {
3870 const q = hslPercent.l < 0.5 ? hslPercent.l * (1 + hslPercent.s) : hslPercent.l + hslPercent.s - hslPercent.l * hslPercent.s,
3871 p = 2 * hslPercent.l - q;
3872 result.r = hue2rgb(p, q, hslPercent.h + 1 / 3);
3873 result.g = hue2rgb(p, q, hslPercent.h);
3874 result.b = hue2rgb(p, q, hslPercent.h - 1 / 3);
3875 }
3876 result.r = Math.floor(result.r * 255);
3877 result.g = Math.floor(result.g * 255);
3878 result.b = Math.floor(result.b * 255);
3879 return result;
3880}
3881function hslaToRgba(hsla) {
3882 const rgbResult = hslToRgb(hsla);
3883 return {
3884 a: hsla.a,
3885 b: rgbResult.b,
3886 g: rgbResult.g,
3887 r: rgbResult.r
3888 };
3889}
3890function getRandomRgbColor(min) {
3891 const fixedMin = min ?? 0;
3892 return {
3893 b: Math.floor(randomInRange(setRangeValue(fixedMin, 256))),
3894 g: Math.floor(randomInRange(setRangeValue(fixedMin, 256))),
3895 r: Math.floor(randomInRange(setRangeValue(fixedMin, 256)))
3896 };
3897}
3898function getStyleFromRgb(color, opacity) {
3899 return `rgba(${color.r}, ${color.g}, ${color.b}, ${opacity ?? 1})`;
3900}
3901function ColorUtils_getStyleFromHsl(color, opacity) {
3902 return `hsla(${color.h}, ${color.s}%, ${color.l}%, ${opacity ?? 1})`;
3903}
3904function colorMix(color1, color2, size1, size2) {
3905 let rgb1 = color1,
3906 rgb2 = color2;
3907 if (rgb1.r === undefined) {
3908 rgb1 = hslToRgb(color1);
3909 }
3910 if (rgb2.r === undefined) {
3911 rgb2 = hslToRgb(color2);
3912 }
3913 return {
3914 b: mix(rgb1.b, rgb2.b, size1, size2),
3915 g: mix(rgb1.g, rgb2.g, size1, size2),
3916 r: mix(rgb1.r, rgb2.r, size1, size2)
3917 };
3918}
3919function getLinkColor(p1, p2, linkColor) {
3920 if (linkColor === randomColorValue) {
3921 return getRandomRgbColor();
3922 } else if (linkColor === midColorValue) {
3923 const sourceColor = p1.getFillColor() ?? p1.getStrokeColor(),
3924 destColor = p2?.getFillColor() ?? p2?.getStrokeColor();
3925 if (sourceColor && destColor && p2) {
3926 return colorMix(sourceColor, destColor, p1.getRadius(), p2.getRadius());
3927 } else {
3928 const hslColor = sourceColor ?? destColor;
3929 if (hslColor) {
3930 return hslToRgb(hslColor);
3931 }
3932 }
3933 } else {
3934 return linkColor;
3935 }
3936}
3937function getLinkRandomColor(optColor, blink, consent) {
3938 const color = isString(optColor) ? optColor : optColor.value;
3939 if (color === randomColorValue) {
3940 if (consent) {
3941 return rangeColorToRgb({
3942 value: color
3943 });
3944 }
3945 if (blink) {
3946 return randomColorValue;
3947 }
3948 return midColorValue;
3949 } else if (color === midColorValue) {
3950 return midColorValue;
3951 } else {
3952 return rangeColorToRgb({
3953 value: color
3954 });
3955 }
3956}
3957function getHslFromAnimation(animation) {
3958 return animation !== undefined ? {
3959 h: animation.h.value,
3960 s: animation.s.value,
3961 l: animation.l.value
3962 } : undefined;
3963}
3964function getHslAnimationFromHsl(hsl, animationOptions, reduceFactor) {
3965 const resColor = {
3966 h: {
3967 enable: false,
3968 value: hsl.h
3969 },
3970 s: {
3971 enable: false,
3972 value: hsl.s
3973 },
3974 l: {
3975 enable: false,
3976 value: hsl.l
3977 }
3978 };
3979 if (animationOptions) {
3980 setColorAnimation(resColor.h, animationOptions.h, reduceFactor);
3981 setColorAnimation(resColor.s, animationOptions.s, reduceFactor);
3982 setColorAnimation(resColor.l, animationOptions.l, reduceFactor);
3983 }
3984 return resColor;
3985}
3986function setColorAnimation(colorValue, colorAnimation, reduceFactor) {
3987 colorValue.enable = colorAnimation.enable;
3988 if (colorValue.enable) {
3989 colorValue.velocity = getRangeValue(colorAnimation.speed) / 100 * reduceFactor;
3990 colorValue.decay = 1 - getRangeValue(colorAnimation.decay);
3991 colorValue.status = "increasing";
3992 colorValue.loops = 0;
3993 colorValue.maxLoops = getRangeValue(colorAnimation.count);
3994 colorValue.time = 0;
3995 colorValue.delayTime = getRangeValue(colorAnimation.delay) * 1000;
3996 if (!colorAnimation.sync) {
3997 colorValue.velocity *= getRandom();
3998 colorValue.value *= getRandom();
3999 }
4000 colorValue.initialValue = colorValue.value;
4001 } else {
4002 colorValue.velocity = 0;
4003 }
4004}
4005;// CONCATENATED MODULE: ../../plugins/absorbers/dist/esm/AbsorberInstance.js
4006
4007
4008class AbsorberInstance {
4009 constructor(absorbers, container, options, position) {
4010 this.absorbers = absorbers;
4011 this.container = container;
4012 this._calcPosition = () => {
4013 const exactPosition = calcPositionOrRandomFromSizeRanged({
4014 size: this.container.canvas.size,
4015 position: this.options.position
4016 });
4017 return Vector.create(exactPosition.x, exactPosition.y);
4018 };
4019 this._updateParticlePosition = (particle, v) => {
4020 if (particle.destroyed) {
4021 return;
4022 }
4023 const container = this.container,
4024 canvasSize = container.canvas.size;
4025 if (particle.needsNewPosition) {
4026 const newPosition = calcPositionOrRandomFromSize({
4027 size: canvasSize
4028 });
4029 particle.position.setTo(newPosition);
4030 particle.velocity.setTo(particle.initialVelocity);
4031 particle.absorberOrbit = undefined;
4032 particle.needsNewPosition = false;
4033 }
4034 if (this.options.orbits) {
4035 if (particle.absorberOrbit === undefined) {
4036 particle.absorberOrbit = Vector.create(0, 0);
4037 particle.absorberOrbit.length = getDistance(particle.getPosition(), this.position);
4038 particle.absorberOrbit.angle = getRandom() * Math.PI * 2;
4039 }
4040 if (particle.absorberOrbit.length <= this.size && !this.options.destroy) {
4041 const minSize = Math.min(canvasSize.width, canvasSize.height);
4042 particle.absorberOrbit.length = minSize * (1 + (getRandom() * 0.2 - 0.1));
4043 }
4044 if (particle.absorberOrbitDirection === undefined) {
4045 particle.absorberOrbitDirection = particle.velocity.x >= 0 ? "clockwise" : "counter-clockwise";
4046 }
4047 const orbitRadius = particle.absorberOrbit.length,
4048 orbitAngle = particle.absorberOrbit.angle,
4049 orbitDirection = particle.absorberOrbitDirection;
4050 particle.velocity.setTo(Vector.origin);
4051 const updateFunc = {
4052 x: orbitDirection === "clockwise" ? Math.cos : Math.sin,
4053 y: orbitDirection === "clockwise" ? Math.sin : Math.cos
4054 };
4055 particle.position.x = this.position.x + orbitRadius * updateFunc.x(orbitAngle);
4056 particle.position.y = this.position.y + orbitRadius * updateFunc.y(orbitAngle);
4057 particle.absorberOrbit.length -= v.length;
4058 particle.absorberOrbit.angle += (particle.retina.moveSpeed ?? 0) * container.retina.pixelRatio / 100 * container.retina.reduceFactor;
4059 } else {
4060 const addV = Vector.origin;
4061 addV.length = v.length;
4062 addV.angle = v.angle;
4063 particle.velocity.addTo(addV);
4064 }
4065 };
4066 this.initialPosition = position ? Vector.create(position.x, position.y) : undefined;
4067 if (options instanceof Absorber) {
4068 this.options = options;
4069 } else {
4070 this.options = new Absorber();
4071 this.options.load(options);
4072 }
4073 this.dragging = false;
4074 this.name = this.options.name;
4075 this.opacity = this.options.opacity;
4076 this.size = getRangeValue(this.options.size.value) * container.retina.pixelRatio;
4077 this.mass = this.size * this.options.size.density * container.retina.reduceFactor;
4078 const limit = this.options.size.limit;
4079 this.limit = {
4080 radius: limit.radius * container.retina.pixelRatio * container.retina.reduceFactor,
4081 mass: limit.mass
4082 };
4083 this.color = rangeColorToRgb(this.options.color) ?? {
4084 b: 0,
4085 g: 0,
4086 r: 0
4087 };
4088 this.position = this.initialPosition?.copy() ?? this._calcPosition();
4089 }
4090 attract(particle) {
4091 const container = this.container,
4092 options = this.options;
4093 if (options.draggable) {
4094 const mouse = container.interactivity.mouse;
4095 if (mouse.clicking && mouse.downPosition) {
4096 const mouseDist = getDistance(this.position, mouse.downPosition);
4097 if (mouseDist <= this.size) {
4098 this.dragging = true;
4099 }
4100 } else {
4101 this.dragging = false;
4102 }
4103 if (this.dragging && mouse.position) {
4104 this.position.x = mouse.position.x;
4105 this.position.y = mouse.position.y;
4106 }
4107 }
4108 const pos = particle.getPosition(),
4109 {
4110 dx,
4111 dy,
4112 distance
4113 } = getDistances(this.position, pos),
4114 v = Vector.create(dx, dy);
4115 v.length = this.mass / Math.pow(distance, 2) * container.retina.reduceFactor;
4116 if (distance < this.size + particle.getRadius()) {
4117 const sizeFactor = particle.getRadius() * 0.033 * container.retina.pixelRatio;
4118 if (this.size > particle.getRadius() && distance < this.size - particle.getRadius() || particle.absorberOrbit !== undefined && particle.absorberOrbit.length < 0) {
4119 if (options.destroy) {
4120 particle.destroy();
4121 } else {
4122 particle.needsNewPosition = true;
4123 this._updateParticlePosition(particle, v);
4124 }
4125 } else {
4126 if (options.destroy) {
4127 particle.size.value -= sizeFactor;
4128 }
4129 this._updateParticlePosition(particle, v);
4130 }
4131 if (this.limit.radius <= 0 || this.size < this.limit.radius) {
4132 this.size += sizeFactor;
4133 }
4134 if (this.limit.mass <= 0 || this.mass < this.limit.mass) {
4135 this.mass += sizeFactor * this.options.size.density * container.retina.reduceFactor;
4136 }
4137 } else {
4138 this._updateParticlePosition(particle, v);
4139 }
4140 }
4141 draw(context) {
4142 context.translate(this.position.x, this.position.y);
4143 context.beginPath();
4144 context.arc(0, 0, this.size, 0, Math.PI * 2, false);
4145 context.closePath();
4146 context.fillStyle = getStyleFromRgb(this.color, this.opacity);
4147 context.fill();
4148 }
4149 resize() {
4150 const initialPosition = this.initialPosition;
4151 this.position = initialPosition && isPointInside(initialPosition, this.container.canvas.size, Vector.origin) ? initialPosition : this._calcPosition();
4152 }
4153}
4154;// CONCATENATED MODULE: ../../plugins/absorbers/dist/esm/Absorbers.js
4155
4156
4157class Absorbers {
4158 constructor(container) {
4159 this.container = container;
4160 this.array = [];
4161 this.absorbers = [];
4162 this.interactivityAbsorbers = [];
4163 container.getAbsorber = idxOrName => idxOrName === undefined || isNumber(idxOrName) ? this.array[idxOrName || 0] : this.array.find(t => t.name === idxOrName);
4164 container.addAbsorber = (options, position) => this.addAbsorber(options, position);
4165 }
4166 addAbsorber(options, position) {
4167 const absorber = new AbsorberInstance(this, this.container, options, position);
4168 this.array.push(absorber);
4169 return absorber;
4170 }
4171 draw(context) {
4172 for (const absorber of this.array) {
4173 absorber.draw(context);
4174 }
4175 }
4176 handleClickMode(mode) {
4177 const absorberOptions = this.absorbers,
4178 modeAbsorbers = this.interactivityAbsorbers;
4179 if (mode === "absorber") {
4180 const absorbersModeOptions = itemFromSingleOrMultiple(modeAbsorbers),
4181 absorbersOptions = absorbersModeOptions ?? itemFromSingleOrMultiple(absorberOptions),
4182 aPosition = this.container.interactivity.mouse.clickPosition;
4183 this.addAbsorber(absorbersOptions, aPosition);
4184 }
4185 }
4186 async init() {
4187 this.absorbers = this.container.actualOptions.absorbers;
4188 this.interactivityAbsorbers = this.container.actualOptions.interactivity.modes.absorbers;
4189 executeOnSingleOrMultiple(this.absorbers, absorber => {
4190 this.addAbsorber(absorber);
4191 });
4192 }
4193 particleUpdate(particle) {
4194 for (const absorber of this.array) {
4195 absorber.attract(particle);
4196 if (particle.destroyed) {
4197 break;
4198 }
4199 }
4200 }
4201 removeAbsorber(absorber) {
4202 const index = this.array.indexOf(absorber);
4203 if (index >= 0) {
4204 this.array.splice(index, 1);
4205 }
4206 }
4207 resize() {
4208 for (const absorber of this.array) {
4209 absorber.resize();
4210 }
4211 }
4212 stop() {
4213 this.array = [];
4214 }
4215}
4216;// CONCATENATED MODULE: ../../plugins/absorbers/dist/esm/index.js
4217
4218
4219
4220class AbsorbersPlugin {
4221 constructor() {
4222 this.id = "absorbers";
4223 }
4224 getPlugin(container) {
4225 return new Absorbers(container);
4226 }
4227 loadOptions(options, source) {
4228 if (!this.needsPlugin(options) && !this.needsPlugin(source)) {
4229 return;
4230 }
4231 if (source?.absorbers) {
4232 options.absorbers = executeOnSingleOrMultiple(source.absorbers, absorber => {
4233 const tmp = new Absorber();
4234 tmp.load(absorber);
4235 return tmp;
4236 });
4237 }
4238 options.interactivity.modes.absorbers = executeOnSingleOrMultiple(source?.interactivity?.modes?.absorbers, absorber => {
4239 const tmp = new Absorber();
4240 tmp.load(absorber);
4241 return tmp;
4242 });
4243 }
4244 needsPlugin(options) {
4245 if (!options) {
4246 return false;
4247 }
4248 const absorbers = options.absorbers;
4249 if (isArray(absorbers)) {
4250 return !!absorbers.length;
4251 } else if (absorbers) {
4252 return true;
4253 } else if (options.interactivity?.events?.onClick?.mode && isInArray("absorber", options.interactivity.events.onClick.mode)) {
4254 return true;
4255 }
4256 return false;
4257 }
4258}
4259async function loadAbsorbersPlugin(engine, refresh = true) {
4260 await engine.addPlugin(new AbsorbersPlugin(), refresh);
4261}
4262
4263
4264;// CONCATENATED MODULE: ../../updaters/destroy/dist/esm/Options/Classes/DestroyBounds.js
4265
4266class DestroyBounds {
4267 load(data) {
4268 if (!data) {
4269 return;
4270 }
4271 if (data.bottom !== undefined) {
4272 this.bottom = setRangeValue(data.bottom);
4273 }
4274 if (data.left !== undefined) {
4275 this.left = setRangeValue(data.left);
4276 }
4277 if (data.right !== undefined) {
4278 this.right = setRangeValue(data.right);
4279 }
4280 if (data.top !== undefined) {
4281 this.top = setRangeValue(data.top);
4282 }
4283 }
4284}
4285;// CONCATENATED MODULE: ../../updaters/destroy/dist/esm/Options/Classes/SplitFactor.js
4286
4287class SplitFactor extends ValueWithRandom {
4288 constructor() {
4289 super();
4290 this.value = 3;
4291 }
4292}
4293;// CONCATENATED MODULE: ../../updaters/destroy/dist/esm/Options/Classes/SplitRate.js
4294
4295class SplitRate extends ValueWithRandom {
4296 constructor() {
4297 super();
4298 this.value = {
4299 min: 4,
4300 max: 9
4301 };
4302 }
4303}
4304;// CONCATENATED MODULE: ../../updaters/destroy/dist/esm/Options/Classes/Split.js
4305
4306
4307
4308class Split {
4309 constructor() {
4310 this.count = 1;
4311 this.factor = new SplitFactor();
4312 this.rate = new SplitRate();
4313 this.sizeOffset = true;
4314 }
4315 load(data) {
4316 if (!data) {
4317 return;
4318 }
4319 if (data.color !== undefined) {
4320 this.color = OptionsColor.create(this.color, data.color);
4321 }
4322 if (data.count !== undefined) {
4323 this.count = data.count;
4324 }
4325 this.factor.load(data.factor);
4326 this.rate.load(data.rate);
4327 this.particles = executeOnSingleOrMultiple(data.particles, particles => {
4328 return deepExtend({}, particles);
4329 });
4330 if (data.sizeOffset !== undefined) {
4331 this.sizeOffset = data.sizeOffset;
4332 }
4333 if (data.colorOffset) {
4334 this.colorOffset = this.colorOffset ?? {};
4335 if (data.colorOffset.h !== undefined) {
4336 this.colorOffset.h = data.colorOffset.h;
4337 }
4338 if (data.colorOffset.s !== undefined) {
4339 this.colorOffset.s = data.colorOffset.s;
4340 }
4341 if (data.colorOffset.l !== undefined) {
4342 this.colorOffset.l = data.colorOffset.l;
4343 }
4344 }
4345 }
4346}
4347;// CONCATENATED MODULE: ../../updaters/destroy/dist/esm/Options/Classes/Destroy.js
4348
4349
4350class Destroy {
4351 constructor() {
4352 this.bounds = new DestroyBounds();
4353 this.mode = "none";
4354 this.split = new Split();
4355 }
4356 load(data) {
4357 if (!data) {
4358 return;
4359 }
4360 if (data.mode) {
4361 this.mode = data.mode;
4362 }
4363 if (data.bounds) {
4364 this.bounds.load(data.bounds);
4365 }
4366 this.split.load(data.split);
4367 }
4368}
4369;// CONCATENATED MODULE: ../../engine/dist/esm/Options/Classes/ColorAnimation.js
4370
4371class ColorAnimation {
4372 constructor() {
4373 this.count = 0;
4374 this.enable = false;
4375 this.offset = 0;
4376 this.speed = 1;
4377 this.delay = 0;
4378 this.decay = 0;
4379 this.sync = true;
4380 }
4381 load(data) {
4382 if (!data) {
4383 return;
4384 }
4385 if (data.count !== undefined) {
4386 this.count = setRangeValue(data.count);
4387 }
4388 if (data.enable !== undefined) {
4389 this.enable = data.enable;
4390 }
4391 if (data.offset !== undefined) {
4392 this.offset = setRangeValue(data.offset);
4393 }
4394 if (data.speed !== undefined) {
4395 this.speed = setRangeValue(data.speed);
4396 }
4397 if (data.decay !== undefined) {
4398 this.decay = setRangeValue(data.decay);
4399 }
4400 if (data.delay !== undefined) {
4401 this.delay = setRangeValue(data.delay);
4402 }
4403 if (data.sync !== undefined) {
4404 this.sync = data.sync;
4405 }
4406 }
4407}
4408;// CONCATENATED MODULE: ../../engine/dist/esm/Options/Classes/HslAnimation.js
4409
4410class HslAnimation {
4411 constructor() {
4412 this.h = new ColorAnimation();
4413 this.s = new ColorAnimation();
4414 this.l = new ColorAnimation();
4415 }
4416 load(data) {
4417 if (!data) {
4418 return;
4419 }
4420 this.h.load(data.h);
4421 this.s.load(data.s);
4422 this.l.load(data.l);
4423 }
4424}
4425;// CONCATENATED MODULE: ../../engine/dist/esm/Options/Classes/AnimatableColor.js
4426
4427
4428
4429class AnimatableColor extends OptionsColor {
4430 constructor() {
4431 super();
4432 this.animation = new HslAnimation();
4433 }
4434 static create(source, data) {
4435 const color = new AnimatableColor();
4436 color.load(source);
4437 if (data !== undefined) {
4438 if (isString(data) || isArray(data)) {
4439 color.load({
4440 value: data
4441 });
4442 } else {
4443 color.load(data);
4444 }
4445 }
4446 return color;
4447 }
4448 load(data) {
4449 super.load(data);
4450 if (!data) {
4451 return;
4452 }
4453 const colorAnimation = data.animation;
4454 if (colorAnimation !== undefined) {
4455 if (colorAnimation.enable !== undefined) {
4456 this.animation.h.load(colorAnimation);
4457 } else {
4458 this.animation.load(data.animation);
4459 }
4460 }
4461 }
4462}
4463;// CONCATENATED MODULE: ../../engine/dist/esm/Options/Classes/Particles/Collisions/CollisionsAbsorb.js
4464class CollisionsAbsorb {
4465 constructor() {
4466 this.speed = 2;
4467 }
4468 load(data) {
4469 if (!data) {
4470 return;
4471 }
4472 if (data.speed !== undefined) {
4473 this.speed = data.speed;
4474 }
4475 }
4476}
4477;// CONCATENATED MODULE: ../../engine/dist/esm/Options/Classes/Particles/Collisions/CollisionsOverlap.js
4478class CollisionsOverlap {
4479 constructor() {
4480 this.enable = true;
4481 this.retries = 0;
4482 }
4483 load(data) {
4484 if (!data) {
4485 return;
4486 }
4487 if (data.enable !== undefined) {
4488 this.enable = data.enable;
4489 }
4490 if (data.retries !== undefined) {
4491 this.retries = data.retries;
4492 }
4493 }
4494}
4495;// CONCATENATED MODULE: ../../engine/dist/esm/Options/Classes/Particles/Bounce/ParticlesBounceFactor.js
4496
4497class ParticlesBounceFactor extends ValueWithRandom {
4498 constructor() {
4499 super();
4500 this.random.minimumValue = 0.1;
4501 this.value = 1;
4502 }
4503}
4504;// CONCATENATED MODULE: ../../engine/dist/esm/Options/Classes/Particles/Bounce/ParticlesBounce.js
4505
4506class ParticlesBounce {
4507 constructor() {
4508 this.horizontal = new ParticlesBounceFactor();
4509 this.vertical = new ParticlesBounceFactor();
4510 }
4511 load(data) {
4512 if (!data) {
4513 return;
4514 }
4515 this.horizontal.load(data.horizontal);
4516 this.vertical.load(data.vertical);
4517 }
4518}
4519;// CONCATENATED MODULE: ../../engine/dist/esm/Options/Classes/Particles/Collisions/Collisions.js
4520
4521
4522
4523
4524class Collisions {
4525 constructor() {
4526 this.absorb = new CollisionsAbsorb();
4527 this.bounce = new ParticlesBounce();
4528 this.enable = false;
4529 this.maxSpeed = 50;
4530 this.mode = "bounce";
4531 this.overlap = new CollisionsOverlap();
4532 }
4533 load(data) {
4534 if (!data) {
4535 return;
4536 }
4537 this.absorb.load(data.absorb);
4538 this.bounce.load(data.bounce);
4539 if (data.enable !== undefined) {
4540 this.enable = data.enable;
4541 }
4542 if (data.maxSpeed !== undefined) {
4543 this.maxSpeed = setRangeValue(data.maxSpeed);
4544 }
4545 if (data.mode !== undefined) {
4546 this.mode = data.mode;
4547 }
4548 this.overlap.load(data.overlap);
4549 }
4550}
4551;// CONCATENATED MODULE: ../../engine/dist/esm/Options/Classes/Particles/Move/MoveAngle.js
4552
4553class MoveAngle {
4554 constructor() {
4555 this.offset = 0;
4556 this.value = 90;
4557 }
4558 load(data) {
4559 if (!data) {
4560 return;
4561 }
4562 if (data.offset !== undefined) {
4563 this.offset = setRangeValue(data.offset);
4564 }
4565 if (data.value !== undefined) {
4566 this.value = setRangeValue(data.value);
4567 }
4568 }
4569}
4570;// CONCATENATED MODULE: ../../engine/dist/esm/Options/Classes/Particles/Move/MoveAttract.js
4571
4572class MoveAttract {
4573 constructor() {
4574 this.distance = 200;
4575 this.enable = false;
4576 this.rotate = {
4577 x: 3000,
4578 y: 3000
4579 };
4580 }
4581 get rotateX() {
4582 return this.rotate.x;
4583 }
4584 set rotateX(value) {
4585 this.rotate.x = value;
4586 }
4587 get rotateY() {
4588 return this.rotate.y;
4589 }
4590 set rotateY(value) {
4591 this.rotate.y = value;
4592 }
4593 load(data) {
4594 if (!data) {
4595 return;
4596 }
4597 if (data.distance !== undefined) {
4598 this.distance = setRangeValue(data.distance);
4599 }
4600 if (data.enable !== undefined) {
4601 this.enable = data.enable;
4602 }
4603 const rotateX = data.rotate?.x ?? data.rotateX;
4604 if (rotateX !== undefined) {
4605 this.rotate.x = rotateX;
4606 }
4607 const rotateY = data.rotate?.y ?? data.rotateY;
4608 if (rotateY !== undefined) {
4609 this.rotate.y = rotateY;
4610 }
4611 }
4612}
4613;// CONCATENATED MODULE: ../../engine/dist/esm/Options/Classes/Particles/Move/MoveCenter.js
4614class MoveCenter {
4615 constructor() {
4616 this.x = 50;
4617 this.y = 50;
4618 this.mode = "percent";
4619 this.radius = 0;
4620 }
4621 load(data) {
4622 if (!data) {
4623 return;
4624 }
4625 if (data.x !== undefined) {
4626 this.x = data.x;
4627 }
4628 if (data.y !== undefined) {
4629 this.y = data.y;
4630 }
4631 if (data.mode !== undefined) {
4632 this.mode = data.mode;
4633 }
4634 if (data.radius !== undefined) {
4635 this.radius = data.radius;
4636 }
4637 }
4638}
4639;// CONCATENATED MODULE: ../../engine/dist/esm/Options/Classes/Particles/Move/MoveGravity.js
4640
4641class MoveGravity {
4642 constructor() {
4643 this.acceleration = 9.81;
4644 this.enable = false;
4645 this.inverse = false;
4646 this.maxSpeed = 50;
4647 }
4648 load(data) {
4649 if (!data) {
4650 return;
4651 }
4652 if (data.acceleration !== undefined) {
4653 this.acceleration = setRangeValue(data.acceleration);
4654 }
4655 if (data.enable !== undefined) {
4656 this.enable = data.enable;
4657 }
4658 if (data.inverse !== undefined) {
4659 this.inverse = data.inverse;
4660 }
4661 if (data.maxSpeed !== undefined) {
4662 this.maxSpeed = setRangeValue(data.maxSpeed);
4663 }
4664 }
4665}
4666;// CONCATENATED MODULE: ../../engine/dist/esm/Options/Classes/Particles/Move/Path/MovePath.js
4667
4668
4669class MovePath {
4670 constructor() {
4671 this.clamp = true;
4672 this.delay = new ValueWithRandom();
4673 this.enable = false;
4674 this.options = {};
4675 }
4676 load(data) {
4677 if (!data) {
4678 return;
4679 }
4680 if (data.clamp !== undefined) {
4681 this.clamp = data.clamp;
4682 }
4683 this.delay.load(data.delay);
4684 if (data.enable !== undefined) {
4685 this.enable = data.enable;
4686 }
4687 this.generator = data.generator;
4688 if (data.options) {
4689 this.options = deepExtend(this.options, data.options);
4690 }
4691 }
4692}
4693;// CONCATENATED MODULE: ../../engine/dist/esm/Options/Classes/Particles/Move/MoveTrailFill.js
4694
4695class MoveTrailFill {
4696 load(data) {
4697 if (!data) {
4698 return;
4699 }
4700 if (data.color !== undefined) {
4701 this.color = OptionsColor.create(this.color, data.color);
4702 }
4703 if (data.image !== undefined) {
4704 this.image = data.image;
4705 }
4706 }
4707}
4708;// CONCATENATED MODULE: ../../engine/dist/esm/Options/Classes/Particles/Move/MoveTrail.js
4709
4710class MoveTrail {
4711 constructor() {
4712 this.enable = false;
4713 this.length = 10;
4714 this.fill = new MoveTrailFill();
4715 }
4716 get fillColor() {
4717 return this.fill.color;
4718 }
4719 set fillColor(value) {
4720 this.fill.load({
4721 color: value
4722 });
4723 }
4724 load(data) {
4725 if (!data) {
4726 return;
4727 }
4728 if (data.enable !== undefined) {
4729 this.enable = data.enable;
4730 }
4731 if (data.fill !== undefined || data.fillColor !== undefined) {
4732 this.fill.load(data.fill || {
4733 color: data.fillColor
4734 });
4735 }
4736 if (data.length !== undefined) {
4737 this.length = data.length;
4738 }
4739 }
4740}
4741;// CONCATENATED MODULE: ../../engine/dist/esm/Options/Classes/Particles/Move/OutModes.js
4742class OutModes {
4743 constructor() {
4744 this.default = "out";
4745 }
4746 load(data) {
4747 if (!data) {
4748 return;
4749 }
4750 if (data.default !== undefined) {
4751 this.default = data.default;
4752 }
4753 this.bottom = data.bottom ?? data.default;
4754 this.left = data.left ?? data.default;
4755 this.right = data.right ?? data.default;
4756 this.top = data.top ?? data.default;
4757 }
4758}
4759;// CONCATENATED MODULE: ../../engine/dist/esm/Options/Classes/Particles/Move/Spin.js
4760
4761
4762class Spin {
4763 constructor() {
4764 this.acceleration = 0;
4765 this.enable = false;
4766 }
4767 load(data) {
4768 if (!data) {
4769 return;
4770 }
4771 if (data.acceleration !== undefined) {
4772 this.acceleration = setRangeValue(data.acceleration);
4773 }
4774 if (data.enable !== undefined) {
4775 this.enable = data.enable;
4776 }
4777 if (data.position) {
4778 this.position = deepExtend({}, data.position);
4779 }
4780 }
4781}
4782;// CONCATENATED MODULE: ../../engine/dist/esm/Options/Classes/Particles/Move/Move.js
4783
4784
4785
4786
4787
4788
4789
4790
4791
4792
4793class Move {
4794 constructor() {
4795 this.angle = new MoveAngle();
4796 this.attract = new MoveAttract();
4797 this.center = new MoveCenter();
4798 this.decay = 0;
4799 this.distance = {};
4800 this.direction = "none";
4801 this.drift = 0;
4802 this.enable = false;
4803 this.gravity = new MoveGravity();
4804 this.path = new MovePath();
4805 this.outModes = new OutModes();
4806 this.random = false;
4807 this.size = false;
4808 this.speed = 2;
4809 this.spin = new Spin();
4810 this.straight = false;
4811 this.trail = new MoveTrail();
4812 this.vibrate = false;
4813 this.warp = false;
4814 }
4815 get bounce() {
4816 return this.collisions;
4817 }
4818 set bounce(value) {
4819 this.collisions = value;
4820 }
4821 get collisions() {
4822 return false;
4823 }
4824 set collisions(_) {}
4825 get noise() {
4826 return this.path;
4827 }
4828 set noise(value) {
4829 this.path = value;
4830 }
4831 get outMode() {
4832 return this.outModes.default;
4833 }
4834 set outMode(value) {
4835 this.outModes.default = value;
4836 }
4837 get out_mode() {
4838 return this.outMode;
4839 }
4840 set out_mode(value) {
4841 this.outMode = value;
4842 }
4843 load(data) {
4844 if (!data) {
4845 return;
4846 }
4847 this.angle.load(isNumber(data.angle) ? {
4848 value: data.angle
4849 } : data.angle);
4850 this.attract.load(data.attract);
4851 this.center.load(data.center);
4852 if (data.decay !== undefined) {
4853 this.decay = setRangeValue(data.decay);
4854 }
4855 if (data.direction !== undefined) {
4856 this.direction = data.direction;
4857 }
4858 if (data.distance !== undefined) {
4859 this.distance = isNumber(data.distance) ? {
4860 horizontal: data.distance,
4861 vertical: data.distance
4862 } : {
4863 ...data.distance
4864 };
4865 }
4866 if (data.drift !== undefined) {
4867 this.drift = setRangeValue(data.drift);
4868 }
4869 if (data.enable !== undefined) {
4870 this.enable = data.enable;
4871 }
4872 this.gravity.load(data.gravity);
4873 const outModes = data.outModes ?? data.outMode ?? data.out_mode;
4874 if (outModes !== undefined) {
4875 if (isObject(outModes)) {
4876 this.outModes.load(outModes);
4877 } else {
4878 this.outModes.load({
4879 default: outModes
4880 });
4881 }
4882 }
4883 this.path.load(data.path ?? data.noise);
4884 if (data.random !== undefined) {
4885 this.random = data.random;
4886 }
4887 if (data.size !== undefined) {
4888 this.size = data.size;
4889 }
4890 if (data.speed !== undefined) {
4891 this.speed = setRangeValue(data.speed);
4892 }
4893 this.spin.load(data.spin);
4894 if (data.straight !== undefined) {
4895 this.straight = data.straight;
4896 }
4897 this.trail.load(data.trail);
4898 if (data.vibrate !== undefined) {
4899 this.vibrate = data.vibrate;
4900 }
4901 if (data.warp !== undefined) {
4902 this.warp = data.warp;
4903 }
4904 }
4905}
4906;// CONCATENATED MODULE: ../../engine/dist/esm/Options/Classes/Particles/Opacity/OpacityAnimation.js
4907
4908class OpacityAnimation extends RangedAnimationOptions {
4909 constructor() {
4910 super();
4911 this.destroy = "none";
4912 this.speed = 2;
4913 }
4914 get opacity_min() {
4915 return this.minimumValue;
4916 }
4917 set opacity_min(value) {
4918 this.minimumValue = value;
4919 }
4920 load(data) {
4921 if (data?.opacity_min !== undefined && data.minimumValue === undefined) {
4922 data.minimumValue = data.opacity_min;
4923 }
4924 super.load(data);
4925 if (!data) {
4926 return;
4927 }
4928 if (data.destroy !== undefined) {
4929 this.destroy = data.destroy;
4930 }
4931 }
4932}
4933;// CONCATENATED MODULE: ../../engine/dist/esm/Options/Classes/Particles/Opacity/Opacity.js
4934
4935
4936
4937class Opacity extends ValueWithRandom {
4938 constructor() {
4939 super();
4940 this.animation = new OpacityAnimation();
4941 this.random.minimumValue = 0.1;
4942 this.value = 1;
4943 }
4944 get anim() {
4945 return this.animation;
4946 }
4947 set anim(value) {
4948 this.animation = value;
4949 }
4950 load(data) {
4951 if (!data) {
4952 return;
4953 }
4954 super.load(data);
4955 const animation = data.animation ?? data.anim;
4956 if (animation !== undefined) {
4957 this.animation.load(animation);
4958 this.value = setRangeValue(this.value, this.animation.enable ? this.animation.minimumValue : undefined);
4959 }
4960 }
4961}
4962;// CONCATENATED MODULE: ../../engine/dist/esm/Options/Classes/Particles/Number/ParticlesDensity.js
4963class ParticlesDensity {
4964 constructor() {
4965 this.enable = false;
4966 this.width = 1920;
4967 this.height = 1080;
4968 }
4969 get area() {
4970 return this.width;
4971 }
4972 set area(value) {
4973 this.width = value;
4974 }
4975 get factor() {
4976 return this.height;
4977 }
4978 set factor(value) {
4979 this.height = value;
4980 }
4981 get value_area() {
4982 return this.area;
4983 }
4984 set value_area(value) {
4985 this.area = value;
4986 }
4987 load(data) {
4988 if (!data) {
4989 return;
4990 }
4991 if (data.enable !== undefined) {
4992 this.enable = data.enable;
4993 }
4994 const width = data.width ?? data.area ?? data.value_area;
4995 if (width !== undefined) {
4996 this.width = width;
4997 }
4998 const height = data.height ?? data.factor;
4999 if (height !== undefined) {
5000 this.height = height;
5001 }
5002 }
5003}
5004;// CONCATENATED MODULE: ../../engine/dist/esm/Options/Classes/Particles/Number/ParticlesNumber.js
5005
5006class ParticlesNumber {
5007 constructor() {
5008 this.density = new ParticlesDensity();
5009 this.limit = 0;
5010 this.value = 0;
5011 }
5012 get max() {
5013 return this.limit;
5014 }
5015 set max(value) {
5016 this.limit = value;
5017 }
5018 load(data) {
5019 if (!data) {
5020 return;
5021 }
5022 this.density.load(data.density);
5023 const limit = data.limit ?? data.max;
5024 if (limit !== undefined) {
5025 this.limit = limit;
5026 }
5027 if (data.value !== undefined) {
5028 this.value = data.value;
5029 }
5030 }
5031}
5032;// CONCATENATED MODULE: ../../engine/dist/esm/Options/Classes/Particles/Shadow.js
5033
5034class Shadow {
5035 constructor() {
5036 this.blur = 0;
5037 this.color = new OptionsColor();
5038 this.enable = false;
5039 this.offset = {
5040 x: 0,
5041 y: 0
5042 };
5043 this.color.value = "#000";
5044 }
5045 load(data) {
5046 if (!data) {
5047 return;
5048 }
5049 if (data.blur !== undefined) {
5050 this.blur = data.blur;
5051 }
5052 this.color = OptionsColor.create(this.color, data.color);
5053 if (data.enable !== undefined) {
5054 this.enable = data.enable;
5055 }
5056 if (data.offset === undefined) {
5057 return;
5058 }
5059 if (data.offset.x !== undefined) {
5060 this.offset.x = data.offset.x;
5061 }
5062 if (data.offset.y !== undefined) {
5063 this.offset.y = data.offset.y;
5064 }
5065 }
5066}
5067;// CONCATENATED MODULE: ../../engine/dist/esm/Options/Classes/Particles/Shape/Shape.js
5068
5069const charKey = "character",
5070 charAltKey = "char",
5071 imageKey = "image",
5072 imageAltKey = "images",
5073 polygonKey = "polygon",
5074 polygonAltKey = "star";
5075class Shape {
5076 constructor() {
5077 this.loadShape = (item, mainKey, altKey, altOverride) => {
5078 if (!item) {
5079 return;
5080 }
5081 const itemIsArray = isArray(item),
5082 emptyValue = itemIsArray ? [] : {},
5083 mainDifferentValues = itemIsArray !== isArray(this.options[mainKey]),
5084 altDifferentValues = itemIsArray !== isArray(this.options[altKey]);
5085 if (mainDifferentValues) {
5086 this.options[mainKey] = emptyValue;
5087 }
5088 if (altDifferentValues && altOverride) {
5089 this.options[altKey] = emptyValue;
5090 }
5091 this.options[mainKey] = deepExtend(this.options[mainKey] ?? emptyValue, item);
5092 if (!this.options[altKey] || altOverride) {
5093 this.options[altKey] = deepExtend(this.options[altKey] ?? emptyValue, item);
5094 }
5095 };
5096 this.close = true;
5097 this.fill = true;
5098 this.options = {};
5099 this.type = "circle";
5100 }
5101 get character() {
5102 return this.options[charKey] ?? this.options[charAltKey];
5103 }
5104 set character(value) {
5105 this.options[charAltKey] = this.options[charKey] = value;
5106 }
5107 get custom() {
5108 return this.options;
5109 }
5110 set custom(value) {
5111 this.options = value;
5112 }
5113 get image() {
5114 return this.options[imageKey] ?? this.options[imageAltKey];
5115 }
5116 set image(value) {
5117 this.options[imageAltKey] = this.options[imageKey] = value;
5118 }
5119 get images() {
5120 return this.image;
5121 }
5122 set images(value) {
5123 this.image = value;
5124 }
5125 get polygon() {
5126 return this.options[polygonKey] ?? this.options[polygonAltKey];
5127 }
5128 set polygon(value) {
5129 this.options[polygonAltKey] = this.options[polygonKey] = value;
5130 }
5131 get stroke() {
5132 return [];
5133 }
5134 set stroke(_value) {}
5135 load(data) {
5136 if (!data) {
5137 return;
5138 }
5139 const options = data.options ?? data.custom;
5140 if (options !== undefined) {
5141 for (const shape in options) {
5142 const item = options[shape];
5143 if (item) {
5144 this.options[shape] = deepExtend(this.options[shape] ?? {}, item);
5145 }
5146 }
5147 }
5148 this.loadShape(data.character, charKey, charAltKey, true);
5149 this.loadShape(data.polygon, polygonKey, polygonAltKey, false);
5150 this.loadShape(data.image ?? data.images, imageKey, imageAltKey, true);
5151 if (data.close !== undefined) {
5152 this.close = data.close;
5153 }
5154 if (data.fill !== undefined) {
5155 this.fill = data.fill;
5156 }
5157 if (data.type !== undefined) {
5158 this.type = data.type;
5159 }
5160 }
5161}
5162;// CONCATENATED MODULE: ../../engine/dist/esm/Options/Classes/Particles/Size/SizeAnimation.js
5163
5164class SizeAnimation extends RangedAnimationOptions {
5165 constructor() {
5166 super();
5167 this.destroy = "none";
5168 this.speed = 5;
5169 }
5170 get size_min() {
5171 return this.minimumValue;
5172 }
5173 set size_min(value) {
5174 this.minimumValue = value;
5175 }
5176 load(data) {
5177 if (data?.size_min !== undefined && data.minimumValue === undefined) {
5178 data.minimumValue = data.size_min;
5179 }
5180 super.load(data);
5181 if (!data) {
5182 return;
5183 }
5184 if (data.destroy !== undefined) {
5185 this.destroy = data.destroy;
5186 }
5187 }
5188}
5189;// CONCATENATED MODULE: ../../engine/dist/esm/Options/Classes/Particles/Size/Size.js
5190
5191
5192
5193class Size extends ValueWithRandom {
5194 constructor() {
5195 super();
5196 this.animation = new SizeAnimation();
5197 this.random.minimumValue = 1;
5198 this.value = 3;
5199 }
5200 get anim() {
5201 return this.animation;
5202 }
5203 set anim(value) {
5204 this.animation = value;
5205 }
5206 load(data) {
5207 super.load(data);
5208 if (!data) {
5209 return;
5210 }
5211 const animation = data.animation ?? data.anim;
5212 if (animation !== undefined) {
5213 this.animation.load(animation);
5214 this.value = setRangeValue(this.value, this.animation.enable ? this.animation.minimumValue : undefined);
5215 }
5216 }
5217}
5218;// CONCATENATED MODULE: ../../engine/dist/esm/Options/Classes/Particles/Stroke.js
5219
5220
5221class Stroke {
5222 constructor() {
5223 this.width = 0;
5224 }
5225 load(data) {
5226 if (!data) {
5227 return;
5228 }
5229 if (data.color !== undefined) {
5230 this.color = AnimatableColor.create(this.color, data.color);
5231 }
5232 if (data.width !== undefined) {
5233 this.width = setRangeValue(data.width);
5234 }
5235 if (data.opacity !== undefined) {
5236 this.opacity = setRangeValue(data.opacity);
5237 }
5238 }
5239}
5240;// CONCATENATED MODULE: ../../engine/dist/esm/Options/Classes/Particles/ZIndex/ZIndex.js
5241
5242class ZIndex extends ValueWithRandom {
5243 constructor() {
5244 super();
5245 this.opacityRate = 1;
5246 this.sizeRate = 1;
5247 this.velocityRate = 1;
5248 }
5249 load(data) {
5250 super.load(data);
5251 if (!data) {
5252 return;
5253 }
5254 if (data.opacityRate !== undefined) {
5255 this.opacityRate = data.opacityRate;
5256 }
5257 if (data.sizeRate !== undefined) {
5258 this.sizeRate = data.sizeRate;
5259 }
5260 if (data.velocityRate !== undefined) {
5261 this.velocityRate = data.velocityRate;
5262 }
5263 }
5264}
5265;// CONCATENATED MODULE: ../../engine/dist/esm/Options/Classes/Particles/ParticlesOptions.js
5266
5267
5268
5269
5270
5271
5272
5273
5274
5275
5276
5277
5278class ParticlesOptions {
5279 constructor(engine, container) {
5280 this._engine = engine;
5281 this._container = container;
5282 this.bounce = new ParticlesBounce();
5283 this.collisions = new Collisions();
5284 this.color = new AnimatableColor();
5285 this.color.value = "#fff";
5286 this.groups = {};
5287 this.move = new Move();
5288 this.number = new ParticlesNumber();
5289 this.opacity = new Opacity();
5290 this.reduceDuplicates = false;
5291 this.shadow = new Shadow();
5292 this.shape = new Shape();
5293 this.size = new Size();
5294 this.stroke = new Stroke();
5295 this.zIndex = new ZIndex();
5296 }
5297 load(data) {
5298 if (!data) {
5299 return;
5300 }
5301 this.bounce.load(data.bounce);
5302 this.color.load(AnimatableColor.create(this.color, data.color));
5303 if (data.groups !== undefined) {
5304 for (const group in data.groups) {
5305 const item = data.groups[group];
5306 if (item !== undefined) {
5307 this.groups[group] = deepExtend(this.groups[group] ?? {}, item);
5308 }
5309 }
5310 }
5311 this.move.load(data.move);
5312 this.number.load(data.number);
5313 this.opacity.load(data.opacity);
5314 if (data.reduceDuplicates !== undefined) {
5315 this.reduceDuplicates = data.reduceDuplicates;
5316 }
5317 this.shape.load(data.shape);
5318 this.size.load(data.size);
5319 this.shadow.load(data.shadow);
5320 this.zIndex.load(data.zIndex);
5321 const collisions = data.move?.collisions ?? data.move?.bounce;
5322 if (collisions !== undefined) {
5323 this.collisions.enable = collisions;
5324 }
5325 this.collisions.load(data.collisions);
5326 if (data.interactivity !== undefined) {
5327 this.interactivity = deepExtend({}, data.interactivity);
5328 }
5329 const strokeToLoad = data.stroke ?? data.shape?.stroke;
5330 if (strokeToLoad) {
5331 this.stroke = executeOnSingleOrMultiple(strokeToLoad, t => {
5332 const tmp = new Stroke();
5333 tmp.load(t);
5334 return tmp;
5335 });
5336 }
5337 if (this._container) {
5338 const updaters = this._engine.plugins.updaters.get(this._container);
5339 if (updaters) {
5340 for (const updater of updaters) {
5341 if (updater.loadOptions) {
5342 updater.loadOptions(this, data);
5343 }
5344 }
5345 }
5346 const interactors = this._engine.plugins.interactors.get(this._container);
5347 if (interactors) {
5348 for (const interactor of interactors) {
5349 if (interactor.loadParticlesOptions) {
5350 interactor.loadParticlesOptions(this, data);
5351 }
5352 }
5353 }
5354 }
5355 }
5356}
5357;// CONCATENATED MODULE: ../../engine/dist/esm/Utils/OptionsUtils.js
5358
5359function loadOptions(options, ...sourceOptionsArr) {
5360 for (const sourceOptions of sourceOptionsArr) {
5361 options.load(sourceOptions);
5362 }
5363}
5364function loadParticlesOptions(engine, container, ...sourceOptionsArr) {
5365 const options = new ParticlesOptions(engine, container);
5366 loadOptions(options, ...sourceOptionsArr);
5367 return options;
5368}
5369;// CONCATENATED MODULE: ../../updaters/destroy/dist/esm/Utils.js
5370
5371function addSplitParticle(engine, container, parent, splitParticlesOptions) {
5372 const destroyOptions = parent.options.destroy;
5373 if (!destroyOptions) {
5374 return;
5375 }
5376 const splitOptions = destroyOptions.split,
5377 options = loadParticlesOptions(engine, container, parent.options),
5378 factor = getValue(splitOptions.factor),
5379 parentColor = parent.getFillColor();
5380 if (splitOptions.color) {
5381 options.color.load(splitOptions.color);
5382 } else if (splitOptions.colorOffset && parentColor) {
5383 options.color.load({
5384 value: {
5385 hsl: {
5386 h: parentColor.h + getRangeValue(splitOptions.colorOffset.h ?? 0),
5387 s: parentColor.s + getRangeValue(splitOptions.colorOffset.s ?? 0),
5388 l: parentColor.l + getRangeValue(splitOptions.colorOffset.l ?? 0)
5389 }
5390 }
5391 });
5392 } else {
5393 options.color.load({
5394 value: {
5395 hsl: parent.getFillColor()
5396 }
5397 });
5398 }
5399 options.move.load({
5400 center: {
5401 x: parent.position.x,
5402 y: parent.position.y,
5403 mode: "precise"
5404 }
5405 });
5406 if (isNumber(options.size.value)) {
5407 options.size.value /= factor;
5408 } else {
5409 options.size.value.min /= factor;
5410 options.size.value.max /= factor;
5411 }
5412 options.load(splitParticlesOptions);
5413 const offset = splitOptions.sizeOffset ? setRangeValue(-parent.size.value, parent.size.value) : 0,
5414 position = {
5415 x: parent.position.x + randomInRange(offset),
5416 y: parent.position.y + randomInRange(offset)
5417 };
5418 return container.particles.addParticle(position, options, parent.group, particle => {
5419 if (particle.size.value < 0.5) {
5420 return false;
5421 }
5422 particle.velocity.length = randomInRange(setRangeValue(parent.velocity.length, particle.velocity.length));
5423 particle.splitCount = (parent.splitCount ?? 0) + 1;
5424 particle.unbreakable = true;
5425 setTimeout(() => {
5426 particle.unbreakable = false;
5427 }, 500);
5428 return true;
5429 });
5430}
5431function split(engine, container, particle) {
5432 const destroyOptions = particle.options.destroy;
5433 if (!destroyOptions) {
5434 return;
5435 }
5436 const splitOptions = destroyOptions.split;
5437 if (splitOptions.count >= 0 && (particle.splitCount === undefined || particle.splitCount++ > splitOptions.count)) {
5438 return;
5439 }
5440 const rate = getValue(splitOptions.rate),
5441 particlesSplitOptions = itemFromSingleOrMultiple(splitOptions.particles);
5442 for (let i = 0; i < rate; i++) {
5443 addSplitParticle(engine, container, particle, particlesSplitOptions);
5444 }
5445}
5446;// CONCATENATED MODULE: ../../updaters/destroy/dist/esm/DestroyUpdater.js
5447
5448
5449
5450class DestroyUpdater {
5451 constructor(engine, container) {
5452 this.engine = engine;
5453 this.container = container;
5454 }
5455 init(particle) {
5456 const container = this.container,
5457 particlesOptions = particle.options,
5458 destroyOptions = particlesOptions.destroy;
5459 if (!destroyOptions) {
5460 return;
5461 }
5462 particle.splitCount = 0;
5463 const destroyBoundsOptions = destroyOptions.bounds;
5464 if (!particle.destroyBounds) {
5465 particle.destroyBounds = {};
5466 }
5467 const {
5468 bottom,
5469 left,
5470 right,
5471 top
5472 } = destroyBoundsOptions,
5473 {
5474 destroyBounds
5475 } = particle,
5476 canvasSize = container.canvas.size;
5477 if (bottom) {
5478 destroyBounds.bottom = getRangeValue(bottom) * canvasSize.height / 100;
5479 }
5480 if (left) {
5481 destroyBounds.left = getRangeValue(left) * canvasSize.width / 100;
5482 }
5483 if (right) {
5484 destroyBounds.right = getRangeValue(right) * canvasSize.width / 100;
5485 }
5486 if (top) {
5487 destroyBounds.top = getRangeValue(top) * canvasSize.height / 100;
5488 }
5489 }
5490 isEnabled(particle) {
5491 return !particle.destroyed;
5492 }
5493 loadOptions(options, ...sources) {
5494 if (!options.destroy) {
5495 options.destroy = new Destroy();
5496 }
5497 for (const source of sources) {
5498 options.destroy.load(source?.destroy);
5499 }
5500 }
5501 particleDestroyed(particle, override) {
5502 if (override) {
5503 return;
5504 }
5505 const destroyOptions = particle.options.destroy;
5506 if (destroyOptions && destroyOptions.mode === "split") {
5507 split(this.engine, this.container, particle);
5508 }
5509 }
5510 update(particle) {
5511 if (!this.isEnabled(particle)) {
5512 return;
5513 }
5514 const position = particle.getPosition(),
5515 bounds = particle.destroyBounds;
5516 if (!bounds) {
5517 return;
5518 }
5519 if (bounds.bottom !== undefined && position.y >= bounds.bottom || bounds.left !== undefined && position.x <= bounds.left || bounds.right !== undefined && position.x >= bounds.right || bounds.top !== undefined && position.y <= bounds.top) {
5520 particle.destroy();
5521 }
5522 }
5523}
5524;// CONCATENATED MODULE: ../../updaters/destroy/dist/esm/index.js
5525
5526async function loadDestroyUpdater(engine, refresh = true) {
5527 await engine.addParticleUpdater("destroy", container => new DestroyUpdater(engine, container), refresh);
5528}
5529;// CONCATENATED MODULE: ../../plugins/emitters/dist/esm/Shapes/Circle/CircleShape.js
5530
5531class CircleShape {
5532 randomPosition(position, size, fill) {
5533 const generateTheta = (x, y) => {
5534 const u = getRandom() / 4.0,
5535 theta = Math.atan(y / x * Math.tan(2 * Math.PI * u)),
5536 v = getRandom();
5537 if (v < 0.25) {
5538 return theta;
5539 } else if (v < 0.5) {
5540 return Math.PI - theta;
5541 } else if (v < 0.75) {
5542 return Math.PI + theta;
5543 } else {
5544 return -theta;
5545 }
5546 },
5547 radius = (x, y, theta) => x * y / Math.sqrt((y * Math.cos(theta)) ** 2 + (x * Math.sin(theta)) ** 2),
5548 [a, b] = [size.width / 2, size.height / 2],
5549 randomTheta = generateTheta(a, b),
5550 maxRadius = radius(a, b, randomTheta),
5551 randomRadius = fill ? maxRadius * Math.sqrt(getRandom()) : maxRadius;
5552 return {
5553 x: position.x + randomRadius * Math.cos(randomTheta),
5554 y: position.y + randomRadius * Math.sin(randomTheta)
5555 };
5556 }
5557}
5558;// CONCATENATED MODULE: ../../plugins/emitters/dist/esm/Options/Classes/EmitterLife.js
5559
5560class EmitterLife {
5561 constructor() {
5562 this.wait = false;
5563 }
5564 load(data) {
5565 if (!data) {
5566 return;
5567 }
5568 if (data.count !== undefined) {
5569 this.count = data.count;
5570 }
5571 if (data.delay !== undefined) {
5572 this.delay = setRangeValue(data.delay);
5573 }
5574 if (data.duration !== undefined) {
5575 this.duration = setRangeValue(data.duration);
5576 }
5577 if (data.wait !== undefined) {
5578 this.wait = data.wait;
5579 }
5580 }
5581}
5582;// CONCATENATED MODULE: ../../plugins/emitters/dist/esm/Options/Classes/EmitterRate.js
5583
5584class EmitterRate {
5585 constructor() {
5586 this.quantity = 1;
5587 this.delay = 0.1;
5588 }
5589 load(data) {
5590 if (data === undefined) {
5591 return;
5592 }
5593 if (data.quantity !== undefined) {
5594 this.quantity = setRangeValue(data.quantity);
5595 }
5596 if (data.delay !== undefined) {
5597 this.delay = setRangeValue(data.delay);
5598 }
5599 }
5600}
5601;// CONCATENATED MODULE: ../../plugins/emitters/dist/esm/Options/Classes/EmitterSize.js
5602class EmitterSize {
5603 constructor() {
5604 this.mode = "percent";
5605 this.height = 0;
5606 this.width = 0;
5607 }
5608 load(data) {
5609 if (data === undefined) {
5610 return;
5611 }
5612 if (data.mode !== undefined) {
5613 this.mode = data.mode;
5614 }
5615 if (data.height !== undefined) {
5616 this.height = data.height;
5617 }
5618 if (data.width !== undefined) {
5619 this.width = data.width;
5620 }
5621 }
5622}
5623;// CONCATENATED MODULE: ../../plugins/emitters/dist/esm/Options/Classes/Emitter.js
5624
5625
5626
5627
5628class Emitter {
5629 constructor() {
5630 this.autoPlay = true;
5631 this.fill = true;
5632 this.life = new EmitterLife();
5633 this.rate = new EmitterRate();
5634 this.shape = "square";
5635 this.startCount = 0;
5636 }
5637 load(data) {
5638 if (!data) {
5639 return;
5640 }
5641 if (data.autoPlay !== undefined) {
5642 this.autoPlay = data.autoPlay;
5643 }
5644 if (data.size !== undefined) {
5645 if (!this.size) {
5646 this.size = new EmitterSize();
5647 }
5648 this.size.load(data.size);
5649 }
5650 if (data.direction !== undefined) {
5651 this.direction = data.direction;
5652 }
5653 this.domId = data.domId;
5654 if (data.fill !== undefined) {
5655 this.fill = data.fill;
5656 }
5657 this.life.load(data.life);
5658 this.name = data.name;
5659 this.particles = executeOnSingleOrMultiple(data.particles, particles => {
5660 return deepExtend({}, particles);
5661 });
5662 this.rate.load(data.rate);
5663 if (data.shape !== undefined) {
5664 this.shape = data.shape;
5665 }
5666 if (data.position !== undefined) {
5667 this.position = {};
5668 if (data.position.x !== undefined) {
5669 this.position.x = setRangeValue(data.position.x);
5670 }
5671 if (data.position.y !== undefined) {
5672 this.position.y = setRangeValue(data.position.y);
5673 }
5674 }
5675 if (data.spawnColor !== undefined) {
5676 if (this.spawnColor === undefined) {
5677 this.spawnColor = new AnimatableColor();
5678 }
5679 this.spawnColor.load(data.spawnColor);
5680 }
5681 if (data.startCount !== undefined) {
5682 this.startCount = data.startCount;
5683 }
5684 }
5685}
5686;// CONCATENATED MODULE: ../../plugins/emitters/dist/esm/EmitterInstance.js
5687
5688
5689
5690class EmitterInstance {
5691 constructor(engine, emitters, container, options, position) {
5692 this.emitters = emitters;
5693 this.container = container;
5694 this._calcPosition = () => {
5695 return calcPositionOrRandomFromSizeRanged({
5696 size: this.container.canvas.size,
5697 position: this.options.position
5698 });
5699 };
5700 this._destroy = () => {
5701 this.emitters.removeEmitter(this);
5702 this._engine.dispatchEvent("emitterDestroyed", {
5703 container: this.container,
5704 data: {
5705 emitter: this
5706 }
5707 });
5708 };
5709 this._emit = () => {
5710 if (this._paused) {
5711 return;
5712 }
5713 const quantity = getRangeValue(this.options.rate.quantity);
5714 this._emitParticles(quantity);
5715 };
5716 this._emitParticles = quantity => {
5717 const position = this.getPosition(),
5718 size = this.getSize(),
5719 singleParticlesOptions = itemFromSingleOrMultiple(this._particlesOptions);
5720 for (let i = 0; i < quantity; i++) {
5721 const particlesOptions = deepExtend({}, singleParticlesOptions);
5722 if (this.spawnColor) {
5723 const hslAnimation = this.options.spawnColor?.animation;
5724 if (hslAnimation) {
5725 this.spawnColor.h = this._setColorAnimation(hslAnimation.h, this.spawnColor.h, 360);
5726 this.spawnColor.s = this._setColorAnimation(hslAnimation.s, this.spawnColor.s, 100);
5727 this.spawnColor.l = this._setColorAnimation(hslAnimation.l, this.spawnColor.l, 100);
5728 }
5729 if (!particlesOptions.color) {
5730 particlesOptions.color = {
5731 value: this.spawnColor
5732 };
5733 } else {
5734 particlesOptions.color.value = this.spawnColor;
5735 }
5736 }
5737 if (!position) {
5738 return;
5739 }
5740 const pPosition = this._shape?.randomPosition(position, size, this.fill) ?? position;
5741 this.container.particles.addParticle(pPosition, particlesOptions);
5742 }
5743 };
5744 this._prepareToDie = () => {
5745 if (this._paused) {
5746 return;
5747 }
5748 const duration = this.options.life?.duration !== undefined ? getRangeValue(this.options.life.duration) : undefined;
5749 if (this.container.retina.reduceFactor && (this._lifeCount > 0 || this._immortal) && duration !== undefined && duration > 0) {
5750 this._duration = duration * 1000;
5751 }
5752 };
5753 this._setColorAnimation = (animation, initValue, maxValue) => {
5754 const container = this.container;
5755 if (!animation.enable) {
5756 return initValue;
5757 }
5758 const colorOffset = randomInRange(animation.offset),
5759 delay = getRangeValue(this.options.rate.delay),
5760 emitFactor = 1000 * delay / container.retina.reduceFactor,
5761 colorSpeed = getRangeValue(animation.speed ?? 0);
5762 return (initValue + colorSpeed * container.fpsLimit / emitFactor + colorOffset * 3.6) % maxValue;
5763 };
5764 this._engine = engine;
5765 this._currentDuration = 0;
5766 this._currentEmitDelay = 0;
5767 this._currentSpawnDelay = 0;
5768 this._initialPosition = position;
5769 if (options instanceof Emitter) {
5770 this.options = options;
5771 } else {
5772 this.options = new Emitter();
5773 this.options.load(options);
5774 }
5775 this._spawnDelay = getRangeValue(this.options.life.delay ?? 0) * 1000 / this.container.retina.reduceFactor;
5776 this.position = this._initialPosition ?? this._calcPosition();
5777 this.name = this.options.name;
5778 this._shape = this._engine.emitterShapeManager?.getShape(this.options.shape);
5779 this.fill = this.options.fill;
5780 this._firstSpawn = !this.options.life.wait;
5781 this._startParticlesAdded = false;
5782 let particlesOptions = deepExtend({}, this.options.particles);
5783 particlesOptions ??= {};
5784 particlesOptions.move ??= {};
5785 particlesOptions.move.direction ??= this.options.direction;
5786 if (this.options.spawnColor) {
5787 this.spawnColor = rangeColorToHsl(this.options.spawnColor);
5788 }
5789 this._paused = !this.options.autoPlay;
5790 this._particlesOptions = particlesOptions;
5791 this.size = this.options.size ?? (() => {
5792 const size = new EmitterSize();
5793 size.load({
5794 height: 0,
5795 mode: "percent",
5796 width: 0
5797 });
5798 return size;
5799 })();
5800 this._lifeCount = this.options.life.count ?? -1;
5801 this._immortal = this._lifeCount <= 0;
5802 this._engine.dispatchEvent("emitterCreated", {
5803 container,
5804 data: {
5805 emitter: this
5806 }
5807 });
5808 this.play();
5809 }
5810 externalPause() {
5811 this._paused = true;
5812 this.pause();
5813 }
5814 externalPlay() {
5815 this._paused = false;
5816 this.play();
5817 }
5818 getPosition() {
5819 if (this.options.domId) {
5820 const container = this.container,
5821 element = document.getElementById(this.options.domId);
5822 if (element) {
5823 const elRect = element.getBoundingClientRect();
5824 return {
5825 x: (elRect.x + elRect.width / 2) * container.retina.pixelRatio,
5826 y: (elRect.y + elRect.height / 2) * container.retina.pixelRatio
5827 };
5828 }
5829 }
5830 return this.position;
5831 }
5832 getSize() {
5833 const container = this.container;
5834 if (this.options.domId) {
5835 const element = document.getElementById(this.options.domId);
5836 if (element) {
5837 const elRect = element.getBoundingClientRect();
5838 return {
5839 width: elRect.width * container.retina.pixelRatio,
5840 height: elRect.height * container.retina.pixelRatio
5841 };
5842 }
5843 }
5844 return getSize(this.size, container.canvas.size);
5845 }
5846 pause() {
5847 if (this._paused) {
5848 return;
5849 }
5850 delete this._emitDelay;
5851 }
5852 play() {
5853 if (this._paused) {
5854 return;
5855 }
5856 if (!(this.container.retina.reduceFactor && (this._lifeCount > 0 || this._immortal || !this.options.life.count) && (this._firstSpawn || this._currentSpawnDelay >= (this._spawnDelay ?? 0)))) {
5857 return;
5858 }
5859 if (this._emitDelay === undefined) {
5860 const delay = getRangeValue(this.options.rate.delay);
5861 this._emitDelay = 1000 * delay / this.container.retina.reduceFactor;
5862 }
5863 if (this._lifeCount > 0 || this._immortal) {
5864 this._prepareToDie();
5865 }
5866 }
5867 resize() {
5868 const initialPosition = this._initialPosition;
5869 this.position = initialPosition && isPointInside(initialPosition, this.container.canvas.size, Vector.origin) ? initialPosition : this._calcPosition();
5870 }
5871 update(delta) {
5872 if (this._paused) {
5873 return;
5874 }
5875 if (this._firstSpawn) {
5876 this._firstSpawn = false;
5877 this._currentSpawnDelay = this._spawnDelay ?? 0;
5878 this._currentEmitDelay = this._emitDelay ?? 0;
5879 }
5880 if (!this._startParticlesAdded) {
5881 this._startParticlesAdded = true;
5882 this._emitParticles(this.options.startCount);
5883 }
5884 if (this._duration !== undefined) {
5885 this._currentDuration += delta.value;
5886 if (this._currentDuration >= this._duration) {
5887 this.pause();
5888 if (this._spawnDelay !== undefined) {
5889 delete this._spawnDelay;
5890 }
5891 if (!this._immortal) {
5892 this._lifeCount--;
5893 }
5894 if (this._lifeCount > 0 || this._immortal) {
5895 this.position = this._calcPosition();
5896 this._spawnDelay = getRangeValue(this.options.life.delay ?? 0) * 1000 / this.container.retina.reduceFactor;
5897 } else {
5898 this._destroy();
5899 }
5900 this._currentDuration -= this._duration;
5901 delete this._duration;
5902 }
5903 }
5904 if (this._spawnDelay !== undefined) {
5905 this._currentSpawnDelay += delta.value;
5906 if (this._currentSpawnDelay >= this._spawnDelay) {
5907 this._engine.dispatchEvent("emitterPlay", {
5908 container: this.container
5909 });
5910 this.play();
5911 this._currentSpawnDelay -= this._currentSpawnDelay;
5912 delete this._spawnDelay;
5913 }
5914 }
5915 if (this._emitDelay !== undefined) {
5916 this._currentEmitDelay += delta.value;
5917 if (this._currentEmitDelay >= this._emitDelay) {
5918 this._emit();
5919 this._currentEmitDelay -= this._emitDelay;
5920 }
5921 }
5922 }
5923}
5924;// CONCATENATED MODULE: ../../plugins/emitters/dist/esm/Emitters.js
5925
5926
5927
5928class Emitters {
5929 constructor(engine, container) {
5930 this.container = container;
5931 this._engine = engine;
5932 this.array = [];
5933 this.emitters = [];
5934 this.interactivityEmitters = {
5935 random: {
5936 count: 1,
5937 enable: false
5938 },
5939 value: []
5940 };
5941 container.getEmitter = idxOrName => idxOrName === undefined || isNumber(idxOrName) ? this.array[idxOrName || 0] : this.array.find(t => t.name === idxOrName);
5942 container.addEmitter = (options, position) => this.addEmitter(options, position);
5943 container.removeEmitter = idxOrName => {
5944 const emitter = container.getEmitter(idxOrName);
5945 if (emitter) {
5946 this.removeEmitter(emitter);
5947 }
5948 };
5949 container.playEmitter = idxOrName => {
5950 const emitter = container.getEmitter(idxOrName);
5951 if (emitter) {
5952 emitter.externalPlay();
5953 }
5954 };
5955 container.pauseEmitter = idxOrName => {
5956 const emitter = container.getEmitter(idxOrName);
5957 if (emitter) {
5958 emitter.externalPause();
5959 }
5960 };
5961 }
5962 addEmitter(options, position) {
5963 const emitterOptions = new Emitter();
5964 emitterOptions.load(options);
5965 const emitter = new EmitterInstance(this._engine, this, this.container, emitterOptions, position);
5966 this.array.push(emitter);
5967 return emitter;
5968 }
5969 handleClickMode(mode) {
5970 const emitterOptions = this.emitters,
5971 modeEmitters = this.interactivityEmitters;
5972 if (mode !== "emitter") {
5973 return;
5974 }
5975 let emittersModeOptions;
5976 if (modeEmitters && isArray(modeEmitters.value)) {
5977 if (modeEmitters.value.length > 0 && modeEmitters.random.enable) {
5978 emittersModeOptions = [];
5979 const usedIndexes = [];
5980 for (let i = 0; i < modeEmitters.random.count; i++) {
5981 const idx = arrayRandomIndex(modeEmitters.value);
5982 if (usedIndexes.includes(idx) && usedIndexes.length < modeEmitters.value.length) {
5983 i--;
5984 continue;
5985 }
5986 usedIndexes.push(idx);
5987 emittersModeOptions.push(itemFromArray(modeEmitters.value, idx));
5988 }
5989 } else {
5990 emittersModeOptions = modeEmitters.value;
5991 }
5992 } else {
5993 emittersModeOptions = modeEmitters?.value;
5994 }
5995 const emittersOptions = emittersModeOptions ?? emitterOptions,
5996 ePosition = this.container.interactivity.mouse.clickPosition;
5997 executeOnSingleOrMultiple(emittersOptions, emitter => {
5998 this.addEmitter(emitter, ePosition);
5999 });
6000 }
6001 async init() {
6002 this.emitters = this.container.actualOptions.emitters;
6003 this.interactivityEmitters = this.container.actualOptions.interactivity.modes.emitters;
6004 if (!this.emitters) {
6005 return;
6006 }
6007 if (isArray(this.emitters)) {
6008 for (const emitterOptions of this.emitters) {
6009 this.addEmitter(emitterOptions);
6010 }
6011 } else {
6012 this.addEmitter(this.emitters);
6013 }
6014 }
6015 pause() {
6016 for (const emitter of this.array) {
6017 emitter.pause();
6018 }
6019 }
6020 play() {
6021 for (const emitter of this.array) {
6022 emitter.play();
6023 }
6024 }
6025 removeEmitter(emitter) {
6026 const index = this.array.indexOf(emitter);
6027 if (index >= 0) {
6028 this.array.splice(index, 1);
6029 }
6030 }
6031 resize() {
6032 for (const emitter of this.array) {
6033 emitter.resize();
6034 }
6035 }
6036 stop() {
6037 this.array = [];
6038 }
6039 update(delta) {
6040 for (const emitter of this.array) {
6041 emitter.update(delta);
6042 }
6043 }
6044}
6045;// CONCATENATED MODULE: ../../plugins/emitters/dist/esm/ShapeManager.js
6046const shapes = new Map();
6047class ShapeManager {
6048 constructor(engine) {
6049 this._engine = engine;
6050 }
6051 addShape(name, drawer) {
6052 if (!this.getShape(name)) {
6053 shapes.set(name, drawer);
6054 }
6055 }
6056 getShape(name) {
6057 return shapes.get(name);
6058 }
6059 getSupportedShapes() {
6060 return shapes.keys();
6061 }
6062}
6063;// CONCATENATED MODULE: ../../plugins/emitters/dist/esm/Shapes/Square/SquareShape.js
6064
6065function randomSquareCoordinate(position, offset) {
6066 return position + offset * (getRandom() - 0.5);
6067}
6068class SquareShape {
6069 randomPosition(position, size, fill) {
6070 if (fill) {
6071 return {
6072 x: randomSquareCoordinate(position.x, size.width),
6073 y: randomSquareCoordinate(position.y, size.height)
6074 };
6075 } else {
6076 const halfW = size.width / 2,
6077 halfH = size.height / 2,
6078 side = Math.floor(getRandom() * 4),
6079 v = (getRandom() - 0.5) * 2;
6080 switch (side) {
6081 case 0:
6082 return {
6083 x: position.x + v * halfW,
6084 y: position.y - halfH
6085 };
6086 case 1:
6087 return {
6088 x: position.x - halfW,
6089 y: position.y + v * halfH
6090 };
6091 case 2:
6092 return {
6093 x: position.x + v * halfW,
6094 y: position.y + halfH
6095 };
6096 case 3:
6097 default:
6098 return {
6099 x: position.x + halfW,
6100 y: position.y + v * halfH
6101 };
6102 }
6103 }
6104 }
6105}
6106;// CONCATENATED MODULE: ../../plugins/emitters/dist/esm/index.js
6107
6108
6109
6110
6111
6112
6113class EmittersPlugin {
6114 constructor(engine) {
6115 this._engine = engine;
6116 this.id = "emitters";
6117 }
6118 getPlugin(container) {
6119 return new Emitters(this._engine, container);
6120 }
6121 loadOptions(options, source) {
6122 if (!this.needsPlugin(options) && !this.needsPlugin(source)) {
6123 return;
6124 }
6125 if (source?.emitters) {
6126 options.emitters = executeOnSingleOrMultiple(source.emitters, emitter => {
6127 const tmp = new Emitter();
6128 tmp.load(emitter);
6129 return tmp;
6130 });
6131 }
6132 const interactivityEmitters = source?.interactivity?.modes?.emitters;
6133 if (interactivityEmitters) {
6134 if (isArray(interactivityEmitters)) {
6135 options.interactivity.modes.emitters = {
6136 random: {
6137 count: 1,
6138 enable: true
6139 },
6140 value: interactivityEmitters.map(s => {
6141 const tmp = new Emitter();
6142 tmp.load(s);
6143 return tmp;
6144 })
6145 };
6146 } else {
6147 const emitterMode = interactivityEmitters;
6148 if (emitterMode.value !== undefined) {
6149 if (isArray(emitterMode.value)) {
6150 options.interactivity.modes.emitters = {
6151 random: {
6152 count: emitterMode.random.count ?? 1,
6153 enable: emitterMode.random.enable ?? false
6154 },
6155 value: emitterMode.value.map(s => {
6156 const tmp = new Emitter();
6157 tmp.load(s);
6158 return tmp;
6159 })
6160 };
6161 } else {
6162 const tmp = new Emitter();
6163 tmp.load(emitterMode.value);
6164 options.interactivity.modes.emitters = {
6165 random: {
6166 count: emitterMode.random.count ?? 1,
6167 enable: emitterMode.random.enable ?? false
6168 },
6169 value: tmp
6170 };
6171 }
6172 } else {
6173 const emitterOptions = options.interactivity.modes.emitters = {
6174 random: {
6175 count: 1,
6176 enable: false
6177 },
6178 value: new Emitter()
6179 };
6180 emitterOptions.value.load(interactivityEmitters);
6181 }
6182 }
6183 }
6184 }
6185 needsPlugin(options) {
6186 if (!options) {
6187 return false;
6188 }
6189 const emitters = options.emitters;
6190 return isArray(emitters) && !!emitters.length || emitters !== undefined || !!options.interactivity?.events?.onClick?.mode && isInArray("emitter", options.interactivity.events.onClick.mode);
6191 }
6192}
6193async function loadEmittersPlugin(engine, refresh = true) {
6194 if (!engine.emitterShapeManager) {
6195 engine.emitterShapeManager = new ShapeManager(engine);
6196 }
6197 if (!engine.addEmitterShape) {
6198 engine.addEmitterShape = (name, shape) => {
6199 engine.emitterShapeManager?.addShape(name, shape);
6200 };
6201 }
6202 const plugin = new EmittersPlugin(engine);
6203 await engine.addPlugin(plugin, refresh);
6204 engine.addEmitterShape("circle", new CircleShape());
6205 engine.addEmitterShape("square", new SquareShape());
6206}
6207
6208
6209
6210
6211;// CONCATENATED MODULE: ../../engine/dist/esm/Core/Utils/ExternalInteractorBase.js
6212class ExternalInteractorBase {
6213 constructor(container) {
6214 this.container = container;
6215 this.type = "external";
6216 }
6217}
6218;// CONCATENATED MODULE: ../../interactions/external/trail/dist/esm/Options/Classes/Trail.js
6219
6220class Trail {
6221 constructor() {
6222 this.delay = 1;
6223 this.pauseOnStop = false;
6224 this.quantity = 1;
6225 }
6226 load(data) {
6227 if (!data) {
6228 return;
6229 }
6230 if (data.delay !== undefined) {
6231 this.delay = data.delay;
6232 }
6233 if (data.quantity !== undefined) {
6234 this.quantity = data.quantity;
6235 }
6236 if (data.particles !== undefined) {
6237 this.particles = deepExtend({}, data.particles);
6238 }
6239 if (data.pauseOnStop !== undefined) {
6240 this.pauseOnStop = data.pauseOnStop;
6241 }
6242 }
6243}
6244;// CONCATENATED MODULE: ../../interactions/external/trail/dist/esm/TrailMaker.js
6245
6246
6247class TrailMaker extends ExternalInteractorBase {
6248 constructor(container) {
6249 super(container);
6250 this._delay = 0;
6251 }
6252 clear() {}
6253 init() {}
6254 async interact(delta) {
6255 const container = this.container,
6256 {
6257 interactivity
6258 } = container;
6259 if (!container.retina.reduceFactor) {
6260 return;
6261 }
6262 const options = container.actualOptions,
6263 trailOptions = options.interactivity.modes.trail;
6264 if (!trailOptions) {
6265 return;
6266 }
6267 const optDelay = trailOptions.delay * 1000 / this.container.retina.reduceFactor;
6268 if (this._delay < optDelay) {
6269 this._delay += delta.value;
6270 }
6271 if (this._delay < optDelay) {
6272 return;
6273 }
6274 const canEmit = !(trailOptions.pauseOnStop && (interactivity.mouse.position === this._lastPosition || interactivity.mouse.position?.x === this._lastPosition?.x && interactivity.mouse.position?.y === this._lastPosition?.y));
6275 const mousePos = container.interactivity.mouse.position;
6276 if (mousePos) {
6277 this._lastPosition = {
6278 ...mousePos
6279 };
6280 } else {
6281 delete this._lastPosition;
6282 }
6283 if (canEmit) {
6284 container.particles.push(trailOptions.quantity, container.interactivity.mouse, trailOptions.particles);
6285 }
6286 this._delay -= optDelay;
6287 }
6288 isEnabled(particle) {
6289 const container = this.container,
6290 options = container.actualOptions,
6291 mouse = container.interactivity.mouse,
6292 events = (particle?.interactivity ?? options.interactivity).events;
6293 return mouse.clicking && mouse.inside && !!mouse.position && isInArray("trail", events.onClick.mode) || mouse.inside && !!mouse.position && isInArray("trail", events.onHover.mode);
6294 }
6295 loadModeOptions(options, ...sources) {
6296 if (!options.trail) {
6297 options.trail = new Trail();
6298 }
6299 for (const source of sources) {
6300 options.trail.load(source?.trail);
6301 }
6302 }
6303 reset() {}
6304}
6305;// CONCATENATED MODULE: ../../interactions/external/trail/dist/esm/index.js
6306
6307async function loadExternalTrailInteraction(engine, refresh = true) {
6308 await engine.addInteractor("externalTrail", container => new TrailMaker(container), refresh);
6309}
6310
6311
6312;// CONCATENATED MODULE: ../../updaters/roll/dist/esm/Utils.js
6313
6314function initParticle(particle) {
6315 const rollOpt = particle.options.roll;
6316 if (!rollOpt?.enable) {
6317 particle.roll = {
6318 enable: false,
6319 horizontal: false,
6320 vertical: false,
6321 angle: 0,
6322 speed: 0
6323 };
6324 return;
6325 }
6326 particle.roll = {
6327 enable: rollOpt.enable,
6328 horizontal: rollOpt.mode === "horizontal" || rollOpt.mode === "both",
6329 vertical: rollOpt.mode === "vertical" || rollOpt.mode === "both",
6330 angle: getRandom() * Math.PI * 2,
6331 speed: getRangeValue(rollOpt.speed) / 360
6332 };
6333 if (rollOpt.backColor) {
6334 particle.backColor = rangeColorToHsl(rollOpt.backColor);
6335 } else if (rollOpt.darken.enable && rollOpt.enlighten.enable) {
6336 const alterType = getRandom() >= 0.5 ? "darken" : "enlighten";
6337 particle.roll.alter = {
6338 type: alterType,
6339 value: getRangeValue(alterType === "darken" ? rollOpt.darken.value : rollOpt.enlighten.value)
6340 };
6341 } else if (rollOpt.darken.enable) {
6342 particle.roll.alter = {
6343 type: "darken",
6344 value: getRangeValue(rollOpt.darken.value)
6345 };
6346 } else if (rollOpt.enlighten.enable) {
6347 particle.roll.alter = {
6348 type: "enlighten",
6349 value: getRangeValue(rollOpt.enlighten.value)
6350 };
6351 }
6352}
6353function updateRoll(particle, delta) {
6354 const roll = particle.options.roll,
6355 data = particle.roll;
6356 if (!data || !roll?.enable) {
6357 return;
6358 }
6359 const speed = data.speed * delta.factor,
6360 max = 2 * Math.PI;
6361 data.angle += speed;
6362 if (data.angle > max) {
6363 data.angle -= max;
6364 }
6365}
6366;// CONCATENATED MODULE: ../../updaters/roll/dist/esm/Options/Classes/RollLight.js
6367
6368class RollLight {
6369 constructor() {
6370 this.enable = false;
6371 this.value = 0;
6372 }
6373 load(data) {
6374 if (!data) {
6375 return;
6376 }
6377 if (data.enable !== undefined) {
6378 this.enable = data.enable;
6379 }
6380 if (data.value !== undefined) {
6381 this.value = setRangeValue(data.value);
6382 }
6383 }
6384}
6385;// CONCATENATED MODULE: ../../updaters/roll/dist/esm/Options/Classes/Roll.js
6386
6387
6388class Roll {
6389 constructor() {
6390 this.darken = new RollLight();
6391 this.enable = false;
6392 this.enlighten = new RollLight();
6393 this.mode = "vertical";
6394 this.speed = 25;
6395 }
6396 load(data) {
6397 if (!data) {
6398 return;
6399 }
6400 if (data.backColor !== undefined) {
6401 this.backColor = OptionsColor.create(this.backColor, data.backColor);
6402 }
6403 this.darken.load(data.darken);
6404 if (data.enable !== undefined) {
6405 this.enable = data.enable;
6406 }
6407 this.enlighten.load(data.enlighten);
6408 if (data.mode !== undefined) {
6409 this.mode = data.mode;
6410 }
6411 if (data.speed !== undefined) {
6412 this.speed = setRangeValue(data.speed);
6413 }
6414 }
6415}
6416;// CONCATENATED MODULE: ../../updaters/roll/dist/esm/RollUpdater.js
6417
6418
6419class RollUpdater {
6420 getTransformValues(particle) {
6421 const roll = particle.roll?.enable && particle.roll,
6422 rollHorizontal = roll && roll.horizontal,
6423 rollVertical = roll && roll.vertical;
6424 return {
6425 a: rollHorizontal ? Math.cos(roll.angle) : undefined,
6426 d: rollVertical ? Math.sin(roll.angle) : undefined
6427 };
6428 }
6429 init(particle) {
6430 initParticle(particle);
6431 }
6432 isEnabled(particle) {
6433 const roll = particle.options.roll;
6434 return !particle.destroyed && !particle.spawning && !!roll?.enable;
6435 }
6436 loadOptions(options, ...sources) {
6437 if (!options.roll) {
6438 options.roll = new Roll();
6439 }
6440 for (const source of sources) {
6441 options.roll.load(source?.roll);
6442 }
6443 }
6444 update(particle, delta) {
6445 if (!this.isEnabled(particle)) {
6446 return;
6447 }
6448 updateRoll(particle, delta);
6449 }
6450}
6451;// CONCATENATED MODULE: ../../updaters/roll/dist/esm/index.js
6452
6453async function loadRollUpdater(engine, refresh = true) {
6454 await engine.addParticleUpdater("roll", () => new RollUpdater(), refresh);
6455}
6456;// CONCATENATED MODULE: ../../engine/dist/esm/Utils/CanvasUtils.js
6457
6458function drawLine(context, begin, end) {
6459 context.beginPath();
6460 context.moveTo(begin.x, begin.y);
6461 context.lineTo(end.x, end.y);
6462 context.closePath();
6463}
6464function drawTriangle(context, p1, p2, p3) {
6465 context.beginPath();
6466 context.moveTo(p1.x, p1.y);
6467 context.lineTo(p2.x, p2.y);
6468 context.lineTo(p3.x, p3.y);
6469 context.closePath();
6470}
6471function paintBase(context, dimension, baseColor) {
6472 context.fillStyle = baseColor ?? "rgba(0,0,0,0)";
6473 context.fillRect(0, 0, dimension.width, dimension.height);
6474}
6475function paintImage(context, dimension, image, opacity) {
6476 if (!image) {
6477 return;
6478 }
6479 context.globalAlpha = opacity;
6480 context.drawImage(image, 0, 0, dimension.width, dimension.height);
6481 context.globalAlpha = 1;
6482}
6483function clear(context, dimension) {
6484 context.clearRect(0, 0, dimension.width, dimension.height);
6485}
6486function drawParticle(data) {
6487 const {
6488 container,
6489 context,
6490 particle,
6491 delta,
6492 colorStyles,
6493 backgroundMask,
6494 composite,
6495 radius,
6496 opacity,
6497 shadow,
6498 transform
6499 } = data;
6500 const pos = particle.getPosition(),
6501 angle = particle.rotation + (particle.pathRotation ? particle.velocity.angle : 0),
6502 rotateData = {
6503 sin: Math.sin(angle),
6504 cos: Math.cos(angle)
6505 },
6506 transformData = {
6507 a: rotateData.cos * (transform.a ?? 1),
6508 b: rotateData.sin * (transform.b ?? 1),
6509 c: -rotateData.sin * (transform.c ?? 1),
6510 d: rotateData.cos * (transform.d ?? 1)
6511 };
6512 context.setTransform(transformData.a, transformData.b, transformData.c, transformData.d, pos.x, pos.y);
6513 context.beginPath();
6514 if (backgroundMask) {
6515 context.globalCompositeOperation = composite;
6516 }
6517 const shadowColor = particle.shadowColor;
6518 if (shadow.enable && shadowColor) {
6519 context.shadowBlur = shadow.blur;
6520 context.shadowColor = getStyleFromRgb(shadowColor);
6521 context.shadowOffsetX = shadow.offset.x;
6522 context.shadowOffsetY = shadow.offset.y;
6523 }
6524 if (colorStyles.fill) {
6525 context.fillStyle = colorStyles.fill;
6526 }
6527 const strokeWidth = particle.strokeWidth ?? 0;
6528 context.lineWidth = strokeWidth;
6529 if (colorStyles.stroke) {
6530 context.strokeStyle = colorStyles.stroke;
6531 }
6532 drawShape(container, context, particle, radius, opacity, delta);
6533 if (strokeWidth > 0) {
6534 context.stroke();
6535 }
6536 if (particle.close) {
6537 context.closePath();
6538 }
6539 if (particle.fill) {
6540 context.fill();
6541 }
6542 drawShapeAfterEffect(container, context, particle, radius, opacity, delta);
6543 context.globalCompositeOperation = "source-over";
6544 context.setTransform(1, 0, 0, 1, 0, 0);
6545}
6546function drawShape(container, context, particle, radius, opacity, delta) {
6547 if (!particle.shape) {
6548 return;
6549 }
6550 const drawer = container.drawers.get(particle.shape);
6551 if (!drawer) {
6552 return;
6553 }
6554 drawer.draw(context, particle, radius, opacity, delta, container.retina.pixelRatio);
6555}
6556function drawShapeAfterEffect(container, context, particle, radius, opacity, delta) {
6557 if (!particle.shape) {
6558 return;
6559 }
6560 const drawer = container.drawers.get(particle.shape);
6561 if (!drawer || !drawer.afterEffect) {
6562 return;
6563 }
6564 drawer.afterEffect(context, particle, radius, opacity, delta, container.retina.pixelRatio);
6565}
6566function drawPlugin(context, plugin, delta) {
6567 if (!plugin.draw) {
6568 return;
6569 }
6570 plugin.draw(context, delta);
6571}
6572function drawParticlePlugin(context, plugin, particle, delta) {
6573 if (!plugin.drawParticle) {
6574 return;
6575 }
6576 plugin.drawParticle(context, particle, delta);
6577}
6578function alterHsl(color, type, value) {
6579 return {
6580 h: color.h,
6581 s: color.s,
6582 l: color.l + (type === "darken" ? -1 : 1) * value
6583 };
6584}
6585;// CONCATENATED MODULE: ../../engine/dist/esm/Core/Canvas.js
6586
6587
6588
6589
6590function setTransformValue(factor, newFactor, key) {
6591 const newValue = newFactor[key];
6592 if (newValue !== undefined) {
6593 factor[key] = (factor[key] ?? 1) * newValue;
6594 }
6595}
6596class Canvas {
6597 constructor(container) {
6598 this.container = container;
6599 this._applyPostDrawUpdaters = particle => {
6600 for (const updater of this._postDrawUpdaters) {
6601 updater.afterDraw && updater.afterDraw(particle);
6602 }
6603 };
6604 this._applyPreDrawUpdaters = (ctx, particle, radius, zOpacity, colorStyles, transform) => {
6605 for (const updater of this._preDrawUpdaters) {
6606 if (updater.getColorStyles) {
6607 const {
6608 fill,
6609 stroke
6610 } = updater.getColorStyles(particle, ctx, radius, zOpacity);
6611 if (fill) {
6612 colorStyles.fill = fill;
6613 }
6614 if (stroke) {
6615 colorStyles.stroke = stroke;
6616 }
6617 }
6618 if (updater.getTransformValues) {
6619 const updaterTransform = updater.getTransformValues(particle);
6620 for (const key in updaterTransform) {
6621 setTransformValue(transform, updaterTransform, key);
6622 }
6623 }
6624 updater.beforeDraw && updater.beforeDraw(particle);
6625 }
6626 };
6627 this._applyResizePlugins = () => {
6628 for (const plugin of this._resizePlugins) {
6629 plugin.resize && plugin.resize();
6630 }
6631 };
6632 this._getPluginParticleColors = particle => {
6633 let fColor, sColor;
6634 for (const plugin of this._colorPlugins) {
6635 if (!fColor && plugin.particleFillColor) {
6636 fColor = rangeColorToHsl(plugin.particleFillColor(particle));
6637 }
6638 if (!sColor && plugin.particleStrokeColor) {
6639 sColor = rangeColorToHsl(plugin.particleStrokeColor(particle));
6640 }
6641 if (fColor && sColor) {
6642 break;
6643 }
6644 }
6645 return [fColor, sColor];
6646 };
6647 this._initCover = () => {
6648 const options = this.container.actualOptions,
6649 cover = options.backgroundMask.cover,
6650 color = cover.color,
6651 coverRgb = rangeColorToRgb(color);
6652 if (coverRgb) {
6653 const coverColor = {
6654 ...coverRgb,
6655 a: cover.opacity
6656 };
6657 this._coverColorStyle = getStyleFromRgb(coverColor, coverColor.a);
6658 }
6659 };
6660 this._initStyle = () => {
6661 const element = this.element,
6662 options = this.container.actualOptions;
6663 if (!element) {
6664 return;
6665 }
6666 if (this._fullScreen) {
6667 this._originalStyle = deepExtend({}, element.style);
6668 this._setFullScreenStyle();
6669 } else {
6670 this._resetOriginalStyle();
6671 }
6672 for (const key in options.style) {
6673 if (!key || !options.style) {
6674 continue;
6675 }
6676 const value = options.style[key];
6677 if (!value) {
6678 continue;
6679 }
6680 element.style.setProperty(key, value, "important");
6681 }
6682 };
6683 this._initTrail = async () => {
6684 const options = this.container.actualOptions,
6685 trail = options.particles.move.trail,
6686 trailFill = trail.fill;
6687 if (!trail.enable) {
6688 return;
6689 }
6690 if (trailFill.color) {
6691 const fillColor = rangeColorToRgb(trailFill.color);
6692 if (!fillColor) {
6693 return;
6694 }
6695 const trail = options.particles.move.trail;
6696 this._trailFill = {
6697 color: {
6698 ...fillColor
6699 },
6700 opacity: 1 / trail.length
6701 };
6702 } else {
6703 await new Promise((resolve, reject) => {
6704 if (!trailFill.image) {
6705 return;
6706 }
6707 const img = document.createElement("img");
6708 img.addEventListener("load", () => {
6709 this._trailFill = {
6710 image: img,
6711 opacity: 1 / trail.length
6712 };
6713 resolve();
6714 });
6715 img.addEventListener("error", evt => {
6716 reject(evt.error);
6717 });
6718 img.src = trailFill.image;
6719 });
6720 }
6721 };
6722 this._paintBase = baseColor => {
6723 this.draw(ctx => paintBase(ctx, this.size, baseColor));
6724 };
6725 this._paintImage = (image, opacity) => {
6726 this.draw(ctx => paintImage(ctx, this.size, image, opacity));
6727 };
6728 this._repairStyle = () => {
6729 const element = this.element;
6730 if (!element) {
6731 return;
6732 }
6733 this._safeMutationObserver(observer => observer.disconnect());
6734 this._initStyle();
6735 this.initBackground();
6736 this._safeMutationObserver(observer => observer.observe(element, {
6737 attributes: true
6738 }));
6739 };
6740 this._resetOriginalStyle = () => {
6741 const element = this.element,
6742 originalStyle = this._originalStyle;
6743 if (!(element && originalStyle)) {
6744 return;
6745 }
6746 const style = element.style;
6747 style.position = originalStyle.position;
6748 style.zIndex = originalStyle.zIndex;
6749 style.top = originalStyle.top;
6750 style.left = originalStyle.left;
6751 style.width = originalStyle.width;
6752 style.height = originalStyle.height;
6753 };
6754 this._safeMutationObserver = callback => {
6755 if (!this._mutationObserver) {
6756 return;
6757 }
6758 callback(this._mutationObserver);
6759 };
6760 this._setFullScreenStyle = () => {
6761 const element = this.element;
6762 if (!element) {
6763 return;
6764 }
6765 const priority = "important",
6766 style = element.style;
6767 style.setProperty("position", "fixed", priority);
6768 style.setProperty("z-index", this.container.actualOptions.fullScreen.zIndex.toString(10), priority);
6769 style.setProperty("top", "0", priority);
6770 style.setProperty("left", "0", priority);
6771 style.setProperty("width", "100%", priority);
6772 style.setProperty("height", "100%", priority);
6773 };
6774 this.size = {
6775 height: 0,
6776 width: 0
6777 };
6778 this._context = null;
6779 this._generated = false;
6780 this._preDrawUpdaters = [];
6781 this._postDrawUpdaters = [];
6782 this._resizePlugins = [];
6783 this._colorPlugins = [];
6784 }
6785 get _fullScreen() {
6786 return this.container.actualOptions.fullScreen.enable;
6787 }
6788 clear() {
6789 const options = this.container.actualOptions,
6790 trail = options.particles.move.trail,
6791 trailFill = this._trailFill;
6792 if (options.backgroundMask.enable) {
6793 this.paint();
6794 } else if (trail.enable && trail.length > 0 && trailFill) {
6795 if (trailFill.color) {
6796 this._paintBase(getStyleFromRgb(trailFill.color, trailFill.opacity));
6797 } else if (trailFill.image) {
6798 this._paintImage(trailFill.image, trailFill.opacity);
6799 }
6800 } else {
6801 this.draw(ctx => {
6802 clear(ctx, this.size);
6803 });
6804 }
6805 }
6806 destroy() {
6807 this.stop();
6808 if (this._generated) {
6809 const element = this.element;
6810 element && element.remove();
6811 } else {
6812 this._resetOriginalStyle();
6813 }
6814 this._preDrawUpdaters = [];
6815 this._postDrawUpdaters = [];
6816 this._resizePlugins = [];
6817 this._colorPlugins = [];
6818 }
6819 draw(cb) {
6820 const ctx = this._context;
6821 if (!ctx) {
6822 return;
6823 }
6824 return cb(ctx);
6825 }
6826 drawParticle(particle, delta) {
6827 if (particle.spawning || particle.destroyed) {
6828 return;
6829 }
6830 const radius = particle.getRadius();
6831 if (radius <= 0) {
6832 return;
6833 }
6834 const pfColor = particle.getFillColor(),
6835 psColor = particle.getStrokeColor() ?? pfColor;
6836 let [fColor, sColor] = this._getPluginParticleColors(particle);
6837 if (!fColor) {
6838 fColor = pfColor;
6839 }
6840 if (!sColor) {
6841 sColor = psColor;
6842 }
6843 if (!fColor && !sColor) {
6844 return;
6845 }
6846 this.draw(ctx => {
6847 const container = this.container,
6848 options = container.actualOptions,
6849 zIndexOptions = particle.options.zIndex,
6850 zOpacityFactor = (1 - particle.zIndexFactor) ** zIndexOptions.opacityRate,
6851 opacity = particle.bubble.opacity ?? particle.opacity?.value ?? 1,
6852 strokeOpacity = particle.strokeOpacity ?? opacity,
6853 zOpacity = opacity * zOpacityFactor,
6854 zStrokeOpacity = strokeOpacity * zOpacityFactor,
6855 transform = {},
6856 colorStyles = {
6857 fill: fColor ? ColorUtils_getStyleFromHsl(fColor, zOpacity) : undefined
6858 };
6859 colorStyles.stroke = sColor ? ColorUtils_getStyleFromHsl(sColor, zStrokeOpacity) : colorStyles.fill;
6860 this._applyPreDrawUpdaters(ctx, particle, radius, zOpacity, colorStyles, transform);
6861 drawParticle({
6862 container,
6863 context: ctx,
6864 particle,
6865 delta,
6866 colorStyles,
6867 backgroundMask: options.backgroundMask.enable,
6868 composite: options.backgroundMask.composite,
6869 radius: radius * (1 - particle.zIndexFactor) ** zIndexOptions.sizeRate,
6870 opacity: zOpacity,
6871 shadow: particle.options.shadow,
6872 transform
6873 });
6874 this._applyPostDrawUpdaters(particle);
6875 });
6876 }
6877 drawParticlePlugin(plugin, particle, delta) {
6878 this.draw(ctx => drawParticlePlugin(ctx, plugin, particle, delta));
6879 }
6880 drawPlugin(plugin, delta) {
6881 this.draw(ctx => drawPlugin(ctx, plugin, delta));
6882 }
6883 async init() {
6884 this._safeMutationObserver(obs => obs.disconnect());
6885 this._mutationObserver = safeMutationObserver(records => {
6886 for (const record of records) {
6887 if (record.type === "attributes" && record.attributeName === "style") {
6888 this._repairStyle();
6889 }
6890 }
6891 });
6892 this.resize();
6893 this._initStyle();
6894 this._initCover();
6895 try {
6896 await this._initTrail();
6897 } catch (e) {
6898 getLogger().error(e);
6899 }
6900 this.initBackground();
6901 this._safeMutationObserver(obs => {
6902 if (!this.element) {
6903 return;
6904 }
6905 obs.observe(this.element, {
6906 attributes: true
6907 });
6908 });
6909 this.initUpdaters();
6910 this.initPlugins();
6911 this.paint();
6912 }
6913 initBackground() {
6914 const options = this.container.actualOptions,
6915 background = options.background,
6916 element = this.element;
6917 if (!element) {
6918 return;
6919 }
6920 const elementStyle = element.style;
6921 if (!elementStyle) {
6922 return;
6923 }
6924 if (background.color) {
6925 const color = rangeColorToRgb(background.color);
6926 elementStyle.backgroundColor = color ? getStyleFromRgb(color, background.opacity) : "";
6927 } else {
6928 elementStyle.backgroundColor = "";
6929 }
6930 elementStyle.backgroundImage = background.image || "";
6931 elementStyle.backgroundPosition = background.position || "";
6932 elementStyle.backgroundRepeat = background.repeat || "";
6933 elementStyle.backgroundSize = background.size || "";
6934 }
6935 initPlugins() {
6936 this._resizePlugins = [];
6937 for (const [, plugin] of this.container.plugins) {
6938 if (plugin.resize) {
6939 this._resizePlugins.push(plugin);
6940 }
6941 if (plugin.particleFillColor || plugin.particleStrokeColor) {
6942 this._colorPlugins.push(plugin);
6943 }
6944 }
6945 }
6946 initUpdaters() {
6947 this._preDrawUpdaters = [];
6948 this._postDrawUpdaters = [];
6949 for (const updater of this.container.particles.updaters) {
6950 if (updater.afterDraw) {
6951 this._postDrawUpdaters.push(updater);
6952 }
6953 if (updater.getColorStyles || updater.getTransformValues || updater.beforeDraw) {
6954 this._preDrawUpdaters.push(updater);
6955 }
6956 }
6957 }
6958 loadCanvas(canvas) {
6959 if (this._generated && this.element) {
6960 this.element.remove();
6961 }
6962 this._generated = canvas.dataset && generatedAttribute in canvas.dataset ? canvas.dataset[generatedAttribute] === "true" : this._generated;
6963 this.element = canvas;
6964 this.element.ariaHidden = "true";
6965 this._originalStyle = deepExtend({}, this.element.style);
6966 this.size.height = canvas.offsetHeight;
6967 this.size.width = canvas.offsetWidth;
6968 this._context = this.element.getContext("2d");
6969 this._safeMutationObserver(obs => {
6970 if (!this.element) {
6971 return;
6972 }
6973 obs.observe(this.element, {
6974 attributes: true
6975 });
6976 });
6977 this.container.retina.init();
6978 this.initBackground();
6979 }
6980 paint() {
6981 const options = this.container.actualOptions;
6982 this.draw(ctx => {
6983 if (options.backgroundMask.enable && options.backgroundMask.cover) {
6984 clear(ctx, this.size);
6985 this._paintBase(this._coverColorStyle);
6986 } else {
6987 this._paintBase();
6988 }
6989 });
6990 }
6991 resize() {
6992 if (!this.element) {
6993 return false;
6994 }
6995 const container = this.container,
6996 pxRatio = container.retina.pixelRatio,
6997 size = container.canvas.size,
6998 newSize = {
6999 width: this.element.offsetWidth * pxRatio,
7000 height: this.element.offsetHeight * pxRatio
7001 };
7002 if (newSize.height === size.height && newSize.width === size.width && newSize.height === this.element.height && newSize.width === this.element.width) {
7003 return false;
7004 }
7005 const oldSize = {
7006 ...size
7007 };
7008 this.element.width = size.width = this.element.offsetWidth * pxRatio;
7009 this.element.height = size.height = this.element.offsetHeight * pxRatio;
7010 if (this.container.started) {
7011 this.resizeFactor = {
7012 width: size.width / oldSize.width,
7013 height: size.height / oldSize.height
7014 };
7015 }
7016 return true;
7017 }
7018 stop() {
7019 this._safeMutationObserver(obs => obs.disconnect());
7020 this._mutationObserver = undefined;
7021 this.draw(ctx => clear(ctx, this.size));
7022 }
7023 async windowResize() {
7024 if (!this.element || !this.resize()) {
7025 return;
7026 }
7027 const container = this.container,
7028 needsRefresh = container.updateActualOptions();
7029 container.particles.setDensity();
7030 this._applyResizePlugins();
7031 if (needsRefresh) {
7032 await container.refresh();
7033 }
7034 }
7035}
7036;// CONCATENATED MODULE: ../../engine/dist/esm/Core/Utils/EventListeners.js
7037
7038
7039function manageListener(element, event, handler, add, options) {
7040 if (add) {
7041 let addOptions = {
7042 passive: true
7043 };
7044 if (isBoolean(options)) {
7045 addOptions.capture = options;
7046 } else if (options !== undefined) {
7047 addOptions = options;
7048 }
7049 element.addEventListener(event, handler, addOptions);
7050 } else {
7051 const removeOptions = options;
7052 element.removeEventListener(event, handler, removeOptions);
7053 }
7054}
7055class EventListeners {
7056 constructor(container) {
7057 this.container = container;
7058 this._doMouseTouchClick = e => {
7059 const container = this.container,
7060 options = container.actualOptions;
7061 if (this._canPush) {
7062 const mouseInteractivity = container.interactivity.mouse,
7063 mousePos = mouseInteractivity.position;
7064 if (!mousePos) {
7065 return;
7066 }
7067 mouseInteractivity.clickPosition = {
7068 ...mousePos
7069 };
7070 mouseInteractivity.clickTime = new Date().getTime();
7071 const onClick = options.interactivity.events.onClick;
7072 executeOnSingleOrMultiple(onClick.mode, mode => this.container.handleClickMode(mode));
7073 }
7074 if (e.type === "touchend") {
7075 setTimeout(() => this._mouseTouchFinish(), 500);
7076 }
7077 };
7078 this._handleThemeChange = e => {
7079 const mediaEvent = e,
7080 container = this.container,
7081 options = container.options,
7082 defaultThemes = options.defaultThemes,
7083 themeName = mediaEvent.matches ? defaultThemes.dark : defaultThemes.light,
7084 theme = options.themes.find(theme => theme.name === themeName);
7085 if (theme && theme.default.auto) {
7086 container.loadTheme(themeName);
7087 }
7088 };
7089 this._handleVisibilityChange = () => {
7090 const container = this.container,
7091 options = container.actualOptions;
7092 this._mouseTouchFinish();
7093 if (!options.pauseOnBlur) {
7094 return;
7095 }
7096 if (document && document.hidden) {
7097 container.pageHidden = true;
7098 container.pause();
7099 } else {
7100 container.pageHidden = false;
7101 if (container.getAnimationStatus()) {
7102 container.play(true);
7103 } else {
7104 container.draw(true);
7105 }
7106 }
7107 };
7108 this._handleWindowResize = async () => {
7109 if (this._resizeTimeout) {
7110 clearTimeout(this._resizeTimeout);
7111 delete this._resizeTimeout;
7112 }
7113 this._resizeTimeout = setTimeout(async () => {
7114 const canvas = this.container.canvas;
7115 canvas && (await canvas.windowResize());
7116 }, this.container.actualOptions.interactivity.events.resize.delay * 1000);
7117 };
7118 this._manageInteractivityListeners = (mouseLeaveTmpEvent, add) => {
7119 const handlers = this._handlers,
7120 container = this.container,
7121 options = container.actualOptions;
7122 const interactivityEl = container.interactivity.element;
7123 if (!interactivityEl) {
7124 return;
7125 }
7126 const html = interactivityEl,
7127 canvasEl = container.canvas.element;
7128 if (canvasEl) {
7129 canvasEl.style.pointerEvents = html === canvasEl ? "initial" : "none";
7130 }
7131 if (!(options.interactivity.events.onHover.enable || options.interactivity.events.onClick.enable)) {
7132 return;
7133 }
7134 manageListener(interactivityEl, mouseMoveEvent, handlers.mouseMove, add);
7135 manageListener(interactivityEl, touchStartEvent, handlers.touchStart, add);
7136 manageListener(interactivityEl, touchMoveEvent, handlers.touchMove, add);
7137 if (!options.interactivity.events.onClick.enable) {
7138 manageListener(interactivityEl, touchEndEvent, handlers.touchEnd, add);
7139 } else {
7140 manageListener(interactivityEl, touchEndEvent, handlers.touchEndClick, add);
7141 manageListener(interactivityEl, mouseUpEvent, handlers.mouseUp, add);
7142 manageListener(interactivityEl, mouseDownEvent, handlers.mouseDown, add);
7143 }
7144 manageListener(interactivityEl, mouseLeaveTmpEvent, handlers.mouseLeave, add);
7145 manageListener(interactivityEl, touchCancelEvent, handlers.touchCancel, add);
7146 };
7147 this._manageListeners = add => {
7148 const handlers = this._handlers,
7149 container = this.container,
7150 options = container.actualOptions,
7151 detectType = options.interactivity.detectsOn,
7152 canvasEl = container.canvas.element;
7153 let mouseLeaveTmpEvent = mouseLeaveEvent;
7154 if (detectType === "window") {
7155 container.interactivity.element = window;
7156 mouseLeaveTmpEvent = mouseOutEvent;
7157 } else if (detectType === "parent" && canvasEl) {
7158 container.interactivity.element = canvasEl.parentElement ?? canvasEl.parentNode;
7159 } else {
7160 container.interactivity.element = canvasEl;
7161 }
7162 this._manageMediaMatch(add);
7163 this._manageResize(add);
7164 this._manageInteractivityListeners(mouseLeaveTmpEvent, add);
7165 if (document) {
7166 manageListener(document, visibilityChangeEvent, handlers.visibilityChange, add, false);
7167 }
7168 };
7169 this._manageMediaMatch = add => {
7170 const handlers = this._handlers,
7171 mediaMatch = safeMatchMedia("(prefers-color-scheme: dark)");
7172 if (!mediaMatch) {
7173 return;
7174 }
7175 if (mediaMatch.addEventListener !== undefined) {
7176 manageListener(mediaMatch, "change", handlers.themeChange, add);
7177 return;
7178 }
7179 if (mediaMatch.addListener === undefined) {
7180 return;
7181 }
7182 if (add) {
7183 mediaMatch.addListener(handlers.oldThemeChange);
7184 } else {
7185 mediaMatch.removeListener(handlers.oldThemeChange);
7186 }
7187 };
7188 this._manageResize = add => {
7189 const handlers = this._handlers,
7190 container = this.container,
7191 options = container.actualOptions;
7192 if (!options.interactivity.events.resize) {
7193 return;
7194 }
7195 if (typeof ResizeObserver === "undefined") {
7196 manageListener(window, resizeEvent, handlers.resize, add);
7197 return;
7198 }
7199 const canvasEl = container.canvas.element;
7200 if (this._resizeObserver && !add) {
7201 if (canvasEl) {
7202 this._resizeObserver.unobserve(canvasEl);
7203 }
7204 this._resizeObserver.disconnect();
7205 delete this._resizeObserver;
7206 } else if (!this._resizeObserver && add && canvasEl) {
7207 this._resizeObserver = new ResizeObserver(async entries => {
7208 const entry = entries.find(e => e.target === canvasEl);
7209 if (!entry) {
7210 return;
7211 }
7212 await this._handleWindowResize();
7213 });
7214 this._resizeObserver.observe(canvasEl);
7215 }
7216 };
7217 this._mouseDown = () => {
7218 const {
7219 interactivity
7220 } = this.container;
7221 if (!interactivity) {
7222 return;
7223 }
7224 const {
7225 mouse
7226 } = interactivity;
7227 mouse.clicking = true;
7228 mouse.downPosition = mouse.position;
7229 };
7230 this._mouseTouchClick = e => {
7231 const container = this.container,
7232 options = container.actualOptions,
7233 {
7234 mouse
7235 } = container.interactivity;
7236 mouse.inside = true;
7237 let handled = false;
7238 const mousePosition = mouse.position;
7239 if (!mousePosition || !options.interactivity.events.onClick.enable) {
7240 return;
7241 }
7242 for (const [, plugin] of container.plugins) {
7243 if (!plugin.clickPositionValid) {
7244 continue;
7245 }
7246 handled = plugin.clickPositionValid(mousePosition);
7247 if (handled) {
7248 break;
7249 }
7250 }
7251 if (!handled) {
7252 this._doMouseTouchClick(e);
7253 }
7254 mouse.clicking = false;
7255 };
7256 this._mouseTouchFinish = () => {
7257 const interactivity = this.container.interactivity;
7258 if (!interactivity) {
7259 return;
7260 }
7261 const mouse = interactivity.mouse;
7262 delete mouse.position;
7263 delete mouse.clickPosition;
7264 delete mouse.downPosition;
7265 interactivity.status = mouseLeaveEvent;
7266 mouse.inside = false;
7267 mouse.clicking = false;
7268 };
7269 this._mouseTouchMove = e => {
7270 const container = this.container,
7271 options = container.actualOptions,
7272 interactivity = container.interactivity,
7273 canvasEl = container.canvas.element;
7274 if (!interactivity || !interactivity.element) {
7275 return;
7276 }
7277 interactivity.mouse.inside = true;
7278 let pos;
7279 if (e.type.startsWith("pointer")) {
7280 this._canPush = true;
7281 const mouseEvent = e;
7282 if (interactivity.element === window) {
7283 if (canvasEl) {
7284 const clientRect = canvasEl.getBoundingClientRect();
7285 pos = {
7286 x: mouseEvent.clientX - clientRect.left,
7287 y: mouseEvent.clientY - clientRect.top
7288 };
7289 }
7290 } else if (options.interactivity.detectsOn === "parent") {
7291 const source = mouseEvent.target,
7292 target = mouseEvent.currentTarget;
7293 if (source && target && canvasEl) {
7294 const sourceRect = source.getBoundingClientRect(),
7295 targetRect = target.getBoundingClientRect(),
7296 canvasRect = canvasEl.getBoundingClientRect();
7297 pos = {
7298 x: mouseEvent.offsetX + 2 * sourceRect.left - (targetRect.left + canvasRect.left),
7299 y: mouseEvent.offsetY + 2 * sourceRect.top - (targetRect.top + canvasRect.top)
7300 };
7301 } else {
7302 pos = {
7303 x: mouseEvent.offsetX ?? mouseEvent.clientX,
7304 y: mouseEvent.offsetY ?? mouseEvent.clientY
7305 };
7306 }
7307 } else if (mouseEvent.target === canvasEl) {
7308 pos = {
7309 x: mouseEvent.offsetX ?? mouseEvent.clientX,
7310 y: mouseEvent.offsetY ?? mouseEvent.clientY
7311 };
7312 }
7313 } else {
7314 this._canPush = e.type !== "touchmove";
7315 if (canvasEl) {
7316 const touchEvent = e,
7317 lastTouch = touchEvent.touches[touchEvent.touches.length - 1],
7318 canvasRect = canvasEl.getBoundingClientRect();
7319 pos = {
7320 x: lastTouch.clientX - (canvasRect.left ?? 0),
7321 y: lastTouch.clientY - (canvasRect.top ?? 0)
7322 };
7323 }
7324 }
7325 const pxRatio = container.retina.pixelRatio;
7326 if (pos) {
7327 pos.x *= pxRatio;
7328 pos.y *= pxRatio;
7329 }
7330 interactivity.mouse.position = pos;
7331 interactivity.status = mouseMoveEvent;
7332 };
7333 this._touchEnd = e => {
7334 const evt = e,
7335 touches = Array.from(evt.changedTouches);
7336 for (const touch of touches) {
7337 this._touches.delete(touch.identifier);
7338 }
7339 this._mouseTouchFinish();
7340 };
7341 this._touchEndClick = e => {
7342 const evt = e,
7343 touches = Array.from(evt.changedTouches);
7344 for (const touch of touches) {
7345 this._touches.delete(touch.identifier);
7346 }
7347 this._mouseTouchClick(e);
7348 };
7349 this._touchStart = e => {
7350 const evt = e,
7351 touches = Array.from(evt.changedTouches);
7352 for (const touch of touches) {
7353 this._touches.set(touch.identifier, performance.now());
7354 }
7355 this._mouseTouchMove(e);
7356 };
7357 this._canPush = true;
7358 this._touches = new Map();
7359 this._handlers = {
7360 mouseDown: () => this._mouseDown(),
7361 mouseLeave: () => this._mouseTouchFinish(),
7362 mouseMove: e => this._mouseTouchMove(e),
7363 mouseUp: e => this._mouseTouchClick(e),
7364 touchStart: e => this._touchStart(e),
7365 touchMove: e => this._mouseTouchMove(e),
7366 touchEnd: e => this._touchEnd(e),
7367 touchCancel: e => this._touchEnd(e),
7368 touchEndClick: e => this._touchEndClick(e),
7369 visibilityChange: () => this._handleVisibilityChange(),
7370 themeChange: e => this._handleThemeChange(e),
7371 oldThemeChange: e => this._handleThemeChange(e),
7372 resize: () => {
7373 this._handleWindowResize();
7374 }
7375 };
7376 }
7377 addListeners() {
7378 this._manageListeners(true);
7379 }
7380 removeListeners() {
7381 this._manageListeners(false);
7382 }
7383}
7384;// CONCATENATED MODULE: ../../engine/dist/esm/Options/Classes/Background/Background.js
7385
7386class Background {
7387 constructor() {
7388 this.color = new OptionsColor();
7389 this.color.value = "";
7390 this.image = "";
7391 this.position = "";
7392 this.repeat = "";
7393 this.size = "";
7394 this.opacity = 1;
7395 }
7396 load(data) {
7397 if (!data) {
7398 return;
7399 }
7400 if (data.color !== undefined) {
7401 this.color = OptionsColor.create(this.color, data.color);
7402 }
7403 if (data.image !== undefined) {
7404 this.image = data.image;
7405 }
7406 if (data.position !== undefined) {
7407 this.position = data.position;
7408 }
7409 if (data.repeat !== undefined) {
7410 this.repeat = data.repeat;
7411 }
7412 if (data.size !== undefined) {
7413 this.size = data.size;
7414 }
7415 if (data.opacity !== undefined) {
7416 this.opacity = data.opacity;
7417 }
7418 }
7419}
7420;// CONCATENATED MODULE: ../../engine/dist/esm/Options/Classes/BackgroundMask/BackgroundMaskCover.js
7421
7422class BackgroundMaskCover {
7423 constructor() {
7424 this.color = new OptionsColor();
7425 this.color.value = "#fff";
7426 this.opacity = 1;
7427 }
7428 load(data) {
7429 if (!data) {
7430 return;
7431 }
7432 if (data.color !== undefined) {
7433 this.color = OptionsColor.create(this.color, data.color);
7434 }
7435 if (data.opacity !== undefined) {
7436 this.opacity = data.opacity;
7437 }
7438 }
7439}
7440;// CONCATENATED MODULE: ../../engine/dist/esm/Options/Classes/BackgroundMask/BackgroundMask.js
7441
7442
7443class BackgroundMask {
7444 constructor() {
7445 this.composite = "destination-out";
7446 this.cover = new BackgroundMaskCover();
7447 this.enable = false;
7448 }
7449 load(data) {
7450 if (!data) {
7451 return;
7452 }
7453 if (data.composite !== undefined) {
7454 this.composite = data.composite;
7455 }
7456 if (data.cover !== undefined) {
7457 const cover = data.cover;
7458 const color = isString(data.cover) ? {
7459 color: data.cover
7460 } : data.cover;
7461 this.cover.load(cover.color !== undefined ? cover : {
7462 color: color
7463 });
7464 }
7465 if (data.enable !== undefined) {
7466 this.enable = data.enable;
7467 }
7468 }
7469}
7470;// CONCATENATED MODULE: ../../engine/dist/esm/Options/Classes/FullScreen/FullScreen.js
7471class FullScreen {
7472 constructor() {
7473 this.enable = true;
7474 this.zIndex = 0;
7475 }
7476 load(data) {
7477 if (!data) {
7478 return;
7479 }
7480 if (data.enable !== undefined) {
7481 this.enable = data.enable;
7482 }
7483 if (data.zIndex !== undefined) {
7484 this.zIndex = data.zIndex;
7485 }
7486 }
7487}
7488;// CONCATENATED MODULE: ../../engine/dist/esm/Options/Classes/Interactivity/Events/ClickEvent.js
7489class ClickEvent {
7490 constructor() {
7491 this.enable = false;
7492 this.mode = [];
7493 }
7494 load(data) {
7495 if (!data) {
7496 return;
7497 }
7498 if (data.enable !== undefined) {
7499 this.enable = data.enable;
7500 }
7501 if (data.mode !== undefined) {
7502 this.mode = data.mode;
7503 }
7504 }
7505}
7506;// CONCATENATED MODULE: ../../engine/dist/esm/Options/Classes/Interactivity/Events/DivEvent.js
7507
7508class DivEvent {
7509 constructor() {
7510 this.selectors = [];
7511 this.enable = false;
7512 this.mode = [];
7513 this.type = "circle";
7514 }
7515 get el() {
7516 return this.elementId;
7517 }
7518 set el(value) {
7519 this.elementId = value;
7520 }
7521 get elementId() {
7522 return this.ids;
7523 }
7524 set elementId(value) {
7525 this.ids = value;
7526 }
7527 get ids() {
7528 return executeOnSingleOrMultiple(this.selectors, t => t.replace("#", ""));
7529 }
7530 set ids(value) {
7531 this.selectors = executeOnSingleOrMultiple(value, t => `#${t}`);
7532 }
7533 load(data) {
7534 if (!data) {
7535 return;
7536 }
7537 const ids = data.ids ?? data.elementId ?? data.el;
7538 if (ids !== undefined) {
7539 this.ids = ids;
7540 }
7541 if (data.selectors !== undefined) {
7542 this.selectors = data.selectors;
7543 }
7544 if (data.enable !== undefined) {
7545 this.enable = data.enable;
7546 }
7547 if (data.mode !== undefined) {
7548 this.mode = data.mode;
7549 }
7550 if (data.type !== undefined) {
7551 this.type = data.type;
7552 }
7553 }
7554}
7555;// CONCATENATED MODULE: ../../engine/dist/esm/Options/Classes/Interactivity/Events/Parallax.js
7556class Parallax {
7557 constructor() {
7558 this.enable = false;
7559 this.force = 2;
7560 this.smooth = 10;
7561 }
7562 load(data) {
7563 if (!data) {
7564 return;
7565 }
7566 if (data.enable !== undefined) {
7567 this.enable = data.enable;
7568 }
7569 if (data.force !== undefined) {
7570 this.force = data.force;
7571 }
7572 if (data.smooth !== undefined) {
7573 this.smooth = data.smooth;
7574 }
7575 }
7576}
7577;// CONCATENATED MODULE: ../../engine/dist/esm/Options/Classes/Interactivity/Events/HoverEvent.js
7578
7579class HoverEvent {
7580 constructor() {
7581 this.enable = false;
7582 this.mode = [];
7583 this.parallax = new Parallax();
7584 }
7585 load(data) {
7586 if (!data) {
7587 return;
7588 }
7589 if (data.enable !== undefined) {
7590 this.enable = data.enable;
7591 }
7592 if (data.mode !== undefined) {
7593 this.mode = data.mode;
7594 }
7595 this.parallax.load(data.parallax);
7596 }
7597}
7598;// CONCATENATED MODULE: ../../engine/dist/esm/Options/Classes/Interactivity/Events/ResizeEvent.js
7599class ResizeEvent {
7600 constructor() {
7601 this.delay = 0.5;
7602 this.enable = true;
7603 }
7604 load(data) {
7605 if (data === undefined) {
7606 return;
7607 }
7608 if (data.delay !== undefined) {
7609 this.delay = data.delay;
7610 }
7611 if (data.enable !== undefined) {
7612 this.enable = data.enable;
7613 }
7614 }
7615}
7616;// CONCATENATED MODULE: ../../engine/dist/esm/Options/Classes/Interactivity/Events/Events.js
7617
7618
7619
7620
7621
7622class Events {
7623 constructor() {
7624 this.onClick = new ClickEvent();
7625 this.onDiv = new DivEvent();
7626 this.onHover = new HoverEvent();
7627 this.resize = new ResizeEvent();
7628 }
7629 get onclick() {
7630 return this.onClick;
7631 }
7632 set onclick(value) {
7633 this.onClick = value;
7634 }
7635 get ondiv() {
7636 return this.onDiv;
7637 }
7638 set ondiv(value) {
7639 this.onDiv = value;
7640 }
7641 get onhover() {
7642 return this.onHover;
7643 }
7644 set onhover(value) {
7645 this.onHover = value;
7646 }
7647 load(data) {
7648 if (!data) {
7649 return;
7650 }
7651 this.onClick.load(data.onClick ?? data.onclick);
7652 const onDiv = data.onDiv ?? data.ondiv;
7653 if (onDiv !== undefined) {
7654 this.onDiv = executeOnSingleOrMultiple(onDiv, t => {
7655 const tmp = new DivEvent();
7656 tmp.load(t);
7657 return tmp;
7658 });
7659 }
7660 this.onHover.load(data.onHover ?? data.onhover);
7661 if (isBoolean(data.resize)) {
7662 this.resize.enable = data.resize;
7663 } else {
7664 this.resize.load(data.resize);
7665 }
7666 }
7667}
7668;// CONCATENATED MODULE: ../../engine/dist/esm/Options/Classes/Interactivity/Modes/Modes.js
7669class Modes {
7670 constructor(engine, container) {
7671 this._engine = engine;
7672 this._container = container;
7673 }
7674 load(data) {
7675 if (!data) {
7676 return;
7677 }
7678 if (!this._container) {
7679 return;
7680 }
7681 const interactors = this._engine.plugins.interactors.get(this._container);
7682 if (!interactors) {
7683 return;
7684 }
7685 for (const interactor of interactors) {
7686 if (!interactor.loadModeOptions) {
7687 continue;
7688 }
7689 interactor.loadModeOptions(this, data);
7690 }
7691 }
7692}
7693;// CONCATENATED MODULE: ../../engine/dist/esm/Options/Classes/Interactivity/Interactivity.js
7694
7695
7696class Interactivity {
7697 constructor(engine, container) {
7698 this.detectsOn = "window";
7699 this.events = new Events();
7700 this.modes = new Modes(engine, container);
7701 }
7702 get detect_on() {
7703 return this.detectsOn;
7704 }
7705 set detect_on(value) {
7706 this.detectsOn = value;
7707 }
7708 load(data) {
7709 if (!data) {
7710 return;
7711 }
7712 const detectsOn = data.detectsOn ?? data.detect_on;
7713 if (detectsOn !== undefined) {
7714 this.detectsOn = detectsOn;
7715 }
7716 this.events.load(data.events);
7717 this.modes.load(data.modes);
7718 }
7719}
7720;// CONCATENATED MODULE: ../../engine/dist/esm/Options/Classes/ManualParticle.js
7721
7722class ManualParticle {
7723 load(data) {
7724 if (!data) {
7725 return;
7726 }
7727 if (data.position) {
7728 this.position = {
7729 x: data.position.x ?? 50,
7730 y: data.position.y ?? 50,
7731 mode: data.position.mode ?? "percent"
7732 };
7733 }
7734 if (data.options) {
7735 this.options = deepExtend({}, data.options);
7736 }
7737 }
7738}
7739;// CONCATENATED MODULE: ../../engine/dist/esm/Options/Classes/Responsive.js
7740
7741class Responsive {
7742 constructor() {
7743 this.maxWidth = Infinity;
7744 this.options = {};
7745 this.mode = "canvas";
7746 }
7747 load(data) {
7748 if (!data) {
7749 return;
7750 }
7751 if (data.maxWidth !== undefined) {
7752 this.maxWidth = data.maxWidth;
7753 }
7754 if (data.mode !== undefined) {
7755 if (data.mode === "screen") {
7756 this.mode = "screen";
7757 } else {
7758 this.mode = "canvas";
7759 }
7760 }
7761 if (data.options !== undefined) {
7762 this.options = deepExtend({}, data.options);
7763 }
7764 }
7765}
7766;// CONCATENATED MODULE: ../../engine/dist/esm/Options/Classes/Theme/ThemeDefault.js
7767class ThemeDefault {
7768 constructor() {
7769 this.auto = false;
7770 this.mode = "any";
7771 this.value = false;
7772 }
7773 load(data) {
7774 if (!data) {
7775 return;
7776 }
7777 if (data.auto !== undefined) {
7778 this.auto = data.auto;
7779 }
7780 if (data.mode !== undefined) {
7781 this.mode = data.mode;
7782 }
7783 if (data.value !== undefined) {
7784 this.value = data.value;
7785 }
7786 }
7787}
7788;// CONCATENATED MODULE: ../../engine/dist/esm/Options/Classes/Theme/Theme.js
7789
7790
7791class Theme {
7792 constructor() {
7793 this.name = "";
7794 this.default = new ThemeDefault();
7795 }
7796 load(data) {
7797 if (!data) {
7798 return;
7799 }
7800 if (data.name !== undefined) {
7801 this.name = data.name;
7802 }
7803 this.default.load(data.default);
7804 if (data.options !== undefined) {
7805 this.options = deepExtend({}, data.options);
7806 }
7807 }
7808}
7809;// CONCATENATED MODULE: ../../engine/dist/esm/Options/Classes/Options.js
7810
7811
7812
7813
7814
7815
7816
7817
7818
7819
7820class Options {
7821 constructor(engine, container) {
7822 this._findDefaultTheme = mode => {
7823 return this.themes.find(theme => theme.default.value && theme.default.mode === mode) ?? this.themes.find(theme => theme.default.value && theme.default.mode === "any");
7824 };
7825 this._importPreset = preset => {
7826 this.load(this._engine.plugins.getPreset(preset));
7827 };
7828 this._engine = engine;
7829 this._container = container;
7830 this.autoPlay = true;
7831 this.background = new Background();
7832 this.backgroundMask = new BackgroundMask();
7833 this.defaultThemes = {};
7834 this.delay = 0;
7835 this.fullScreen = new FullScreen();
7836 this.detectRetina = true;
7837 this.duration = 0;
7838 this.fpsLimit = 120;
7839 this.interactivity = new Interactivity(engine, container);
7840 this.manualParticles = [];
7841 this.particles = loadParticlesOptions(this._engine, this._container);
7842 this.pauseOnBlur = true;
7843 this.pauseOnOutsideViewport = true;
7844 this.responsive = [];
7845 this.smooth = false;
7846 this.style = {};
7847 this.themes = [];
7848 this.zLayers = 100;
7849 }
7850 get backgroundMode() {
7851 return this.fullScreen;
7852 }
7853 set backgroundMode(value) {
7854 this.fullScreen.load(value);
7855 }
7856 get fps_limit() {
7857 return this.fpsLimit;
7858 }
7859 set fps_limit(value) {
7860 this.fpsLimit = value;
7861 }
7862 get retina_detect() {
7863 return this.detectRetina;
7864 }
7865 set retina_detect(value) {
7866 this.detectRetina = value;
7867 }
7868 load(data) {
7869 if (!data) {
7870 return;
7871 }
7872 if (data.preset !== undefined) {
7873 executeOnSingleOrMultiple(data.preset, preset => this._importPreset(preset));
7874 }
7875 if (data.autoPlay !== undefined) {
7876 this.autoPlay = data.autoPlay;
7877 }
7878 if (data.delay !== undefined) {
7879 this.delay = setRangeValue(data.delay);
7880 }
7881 const detectRetina = data.detectRetina ?? data.retina_detect;
7882 if (detectRetina !== undefined) {
7883 this.detectRetina = detectRetina;
7884 }
7885 if (data.duration !== undefined) {
7886 this.duration = setRangeValue(data.duration);
7887 }
7888 const fpsLimit = data.fpsLimit ?? data.fps_limit;
7889 if (fpsLimit !== undefined) {
7890 this.fpsLimit = fpsLimit;
7891 }
7892 if (data.pauseOnBlur !== undefined) {
7893 this.pauseOnBlur = data.pauseOnBlur;
7894 }
7895 if (data.pauseOnOutsideViewport !== undefined) {
7896 this.pauseOnOutsideViewport = data.pauseOnOutsideViewport;
7897 }
7898 if (data.zLayers !== undefined) {
7899 this.zLayers = data.zLayers;
7900 }
7901 this.background.load(data.background);
7902 const fullScreen = data.fullScreen ?? data.backgroundMode;
7903 if (isBoolean(fullScreen)) {
7904 this.fullScreen.enable = fullScreen;
7905 } else {
7906 this.fullScreen.load(fullScreen);
7907 }
7908 this.backgroundMask.load(data.backgroundMask);
7909 this.interactivity.load(data.interactivity);
7910 if (data.manualParticles) {
7911 this.manualParticles = data.manualParticles.map(t => {
7912 const tmp = new ManualParticle();
7913 tmp.load(t);
7914 return tmp;
7915 });
7916 }
7917 this.particles.load(data.particles);
7918 this.style = deepExtend(this.style, data.style);
7919 this._engine.plugins.loadOptions(this, data);
7920 if (data.smooth !== undefined) {
7921 this.smooth = data.smooth;
7922 }
7923 const interactors = this._engine.plugins.interactors.get(this._container);
7924 if (interactors) {
7925 for (const interactor of interactors) {
7926 if (interactor.loadOptions) {
7927 interactor.loadOptions(this, data);
7928 }
7929 }
7930 }
7931 if (data.responsive !== undefined) {
7932 for (const responsive of data.responsive) {
7933 const optResponsive = new Responsive();
7934 optResponsive.load(responsive);
7935 this.responsive.push(optResponsive);
7936 }
7937 }
7938 this.responsive.sort((a, b) => a.maxWidth - b.maxWidth);
7939 if (data.themes !== undefined) {
7940 for (const theme of data.themes) {
7941 const existingTheme = this.themes.find(t => t.name === theme.name);
7942 if (!existingTheme) {
7943 const optTheme = new Theme();
7944 optTheme.load(theme);
7945 this.themes.push(optTheme);
7946 } else {
7947 existingTheme.load(theme);
7948 }
7949 }
7950 }
7951 this.defaultThemes.dark = this._findDefaultTheme("dark")?.name;
7952 this.defaultThemes.light = this._findDefaultTheme("light")?.name;
7953 }
7954 setResponsive(width, pxRatio, defaultOptions) {
7955 this.load(defaultOptions);
7956 const responsiveOptions = this.responsive.find(t => t.mode === "screen" && screen ? t.maxWidth > screen.availWidth : t.maxWidth * pxRatio > width);
7957 this.load(responsiveOptions?.options);
7958 return responsiveOptions?.maxWidth;
7959 }
7960 setTheme(name) {
7961 if (name) {
7962 const chosenTheme = this.themes.find(theme => theme.name === name);
7963 if (chosenTheme) {
7964 this.load(chosenTheme.options);
7965 }
7966 } else {
7967 const mediaMatch = safeMatchMedia("(prefers-color-scheme: dark)"),
7968 clientDarkMode = mediaMatch && mediaMatch.matches,
7969 defaultTheme = this._findDefaultTheme(clientDarkMode ? "dark" : "light");
7970 if (defaultTheme) {
7971 this.load(defaultTheme.options);
7972 }
7973 }
7974 }
7975}
7976;// CONCATENATED MODULE: ../../engine/dist/esm/Core/Utils/InteractionManager.js
7977class InteractionManager {
7978 constructor(engine, container) {
7979 this.container = container;
7980 this._engine = engine;
7981 this._interactors = engine.plugins.getInteractors(this.container, true);
7982 this._externalInteractors = [];
7983 this._particleInteractors = [];
7984 }
7985 async externalInteract(delta) {
7986 for (const interactor of this._externalInteractors) {
7987 interactor.isEnabled() && (await interactor.interact(delta));
7988 }
7989 }
7990 handleClickMode(mode) {
7991 for (const interactor of this._externalInteractors) {
7992 interactor.handleClickMode && interactor.handleClickMode(mode);
7993 }
7994 }
7995 init() {
7996 this._externalInteractors = [];
7997 this._particleInteractors = [];
7998 for (const interactor of this._interactors) {
7999 switch (interactor.type) {
8000 case "external":
8001 this._externalInteractors.push(interactor);
8002 break;
8003 case "particles":
8004 this._particleInteractors.push(interactor);
8005 break;
8006 }
8007 interactor.init();
8008 }
8009 }
8010 async particlesInteract(particle, delta) {
8011 for (const interactor of this._externalInteractors) {
8012 interactor.clear(particle, delta);
8013 }
8014 for (const interactor of this._particleInteractors) {
8015 interactor.isEnabled(particle) && (await interactor.interact(particle, delta));
8016 }
8017 }
8018 async reset(particle) {
8019 for (const interactor of this._externalInteractors) {
8020 interactor.isEnabled() && interactor.reset(particle);
8021 }
8022 for (const interactor of this._particleInteractors) {
8023 interactor.isEnabled(particle) && interactor.reset(particle);
8024 }
8025 }
8026}
8027;// CONCATENATED MODULE: ../../engine/dist/esm/Core/Particle.js
8028
8029
8030
8031
8032
8033
8034
8035
8036
8037const fixOutMode = data => {
8038 if (!isInArray(data.outMode, data.checkModes)) {
8039 return;
8040 }
8041 const diameter = data.radius * 2;
8042 if (data.coord > data.maxCoord - diameter) {
8043 data.setCb(-data.radius);
8044 } else if (data.coord < diameter) {
8045 data.setCb(data.radius);
8046 }
8047};
8048class Particle {
8049 constructor(engine, id, container, position, overrideOptions, group) {
8050 this.container = container;
8051 this._calcPosition = (container, position, zIndex, tryCount = 0) => {
8052 for (const [, plugin] of container.plugins) {
8053 const pluginPos = plugin.particlePosition !== undefined ? plugin.particlePosition(position, this) : undefined;
8054 if (pluginPos) {
8055 return Vector3d.create(pluginPos.x, pluginPos.y, zIndex);
8056 }
8057 }
8058 const canvasSize = container.canvas.size,
8059 exactPosition = calcExactPositionOrRandomFromSize({
8060 size: canvasSize,
8061 position: position
8062 }),
8063 pos = Vector3d.create(exactPosition.x, exactPosition.y, zIndex),
8064 radius = this.getRadius(),
8065 outModes = this.options.move.outModes,
8066 fixHorizontal = outMode => {
8067 fixOutMode({
8068 outMode,
8069 checkModes: ["bounce", "bounce-horizontal"],
8070 coord: pos.x,
8071 maxCoord: container.canvas.size.width,
8072 setCb: value => pos.x += value,
8073 radius
8074 });
8075 },
8076 fixVertical = outMode => {
8077 fixOutMode({
8078 outMode,
8079 checkModes: ["bounce", "bounce-vertical"],
8080 coord: pos.y,
8081 maxCoord: container.canvas.size.height,
8082 setCb: value => pos.y += value,
8083 radius
8084 });
8085 };
8086 fixHorizontal(outModes.left ?? outModes.default);
8087 fixHorizontal(outModes.right ?? outModes.default);
8088 fixVertical(outModes.top ?? outModes.default);
8089 fixVertical(outModes.bottom ?? outModes.default);
8090 if (this._checkOverlap(pos, tryCount)) {
8091 return this._calcPosition(container, undefined, zIndex, tryCount + 1);
8092 }
8093 return pos;
8094 };
8095 this._calculateVelocity = () => {
8096 const baseVelocity = getParticleBaseVelocity(this.direction),
8097 res = baseVelocity.copy(),
8098 moveOptions = this.options.move;
8099 if (moveOptions.direction === "inside" || moveOptions.direction === "outside") {
8100 return res;
8101 }
8102 const rad = Math.PI / 180 * getRangeValue(moveOptions.angle.value),
8103 radOffset = Math.PI / 180 * getRangeValue(moveOptions.angle.offset),
8104 range = {
8105 left: radOffset - rad / 2,
8106 right: radOffset + rad / 2
8107 };
8108 if (!moveOptions.straight) {
8109 res.angle += randomInRange(setRangeValue(range.left, range.right));
8110 }
8111 if (moveOptions.random && typeof moveOptions.speed === "number") {
8112 res.length *= getRandom();
8113 }
8114 return res;
8115 };
8116 this._checkOverlap = (pos, tryCount = 0) => {
8117 const collisionsOptions = this.options.collisions,
8118 radius = this.getRadius();
8119 if (!collisionsOptions.enable) {
8120 return false;
8121 }
8122 const overlapOptions = collisionsOptions.overlap;
8123 if (overlapOptions.enable) {
8124 return false;
8125 }
8126 const retries = overlapOptions.retries;
8127 if (retries >= 0 && tryCount > retries) {
8128 throw new Error(`${errorPrefix} particle is overlapping and can't be placed`);
8129 }
8130 return !!this.container.particles.find(particle => getDistance(pos, particle.position) < radius + particle.getRadius());
8131 };
8132 this._getRollColor = color => {
8133 if (!color || !this.roll || !this.backColor && !this.roll.alter) {
8134 return color;
8135 }
8136 const backFactor = this.roll.horizontal && this.roll.vertical ? 2 : 1,
8137 backSum = this.roll.horizontal ? Math.PI / 2 : 0,
8138 rolled = Math.floor(((this.roll.angle ?? 0) + backSum) / (Math.PI / backFactor)) % 2;
8139 if (!rolled) {
8140 return color;
8141 }
8142 if (this.backColor) {
8143 return this.backColor;
8144 }
8145 if (this.roll.alter) {
8146 return alterHsl(color, this.roll.alter.type, this.roll.alter.value);
8147 }
8148 return color;
8149 };
8150 this._initPosition = position => {
8151 const container = this.container,
8152 zIndexValue = getRangeValue(this.options.zIndex.value);
8153 this.position = this._calcPosition(container, position, clamp(zIndexValue, 0, container.zLayers));
8154 this.initialPosition = this.position.copy();
8155 const canvasSize = container.canvas.size;
8156 this.moveCenter = {
8157 ...getPosition(this.options.move.center, canvasSize),
8158 radius: this.options.move.center.radius ?? 0,
8159 mode: this.options.move.center.mode ?? "percent"
8160 };
8161 this.direction = getParticleDirectionAngle(this.options.move.direction, this.position, this.moveCenter);
8162 switch (this.options.move.direction) {
8163 case "inside":
8164 this.outType = "inside";
8165 break;
8166 case "outside":
8167 this.outType = "outside";
8168 break;
8169 }
8170 this.offset = Vector.origin;
8171 };
8172 this._loadShapeData = (shapeOptions, reduceDuplicates) => {
8173 const shapeData = shapeOptions.options[this.shape];
8174 if (!shapeData) {
8175 return;
8176 }
8177 return deepExtend({
8178 close: shapeOptions.close,
8179 fill: shapeOptions.fill
8180 }, itemFromSingleOrMultiple(shapeData, this.id, reduceDuplicates));
8181 };
8182 this._engine = engine;
8183 this.init(id, position, overrideOptions, group);
8184 }
8185 destroy(override) {
8186 if (this.unbreakable || this.destroyed) {
8187 return;
8188 }
8189 this.destroyed = true;
8190 this.bubble.inRange = false;
8191 this.slow.inRange = false;
8192 const container = this.container,
8193 pathGenerator = this.pathGenerator;
8194 for (const [, plugin] of container.plugins) {
8195 if (plugin.particleDestroyed) {
8196 plugin.particleDestroyed(this, override);
8197 }
8198 }
8199 for (const updater of container.particles.updaters) {
8200 if (updater.particleDestroyed) {
8201 updater.particleDestroyed(this, override);
8202 }
8203 }
8204 if (pathGenerator) {
8205 pathGenerator.reset(this);
8206 }
8207 }
8208 draw(delta) {
8209 const container = this.container;
8210 for (const [, plugin] of container.plugins) {
8211 container.canvas.drawParticlePlugin(plugin, this, delta);
8212 }
8213 container.canvas.drawParticle(this, delta);
8214 }
8215 getFillColor() {
8216 return this._getRollColor(this.bubble.color ?? getHslFromAnimation(this.color));
8217 }
8218 getMass() {
8219 return this.getRadius() ** 2 * Math.PI / 2;
8220 }
8221 getPosition() {
8222 return {
8223 x: this.position.x + this.offset.x,
8224 y: this.position.y + this.offset.y,
8225 z: this.position.z
8226 };
8227 }
8228 getRadius() {
8229 return this.bubble.radius ?? this.size.value;
8230 }
8231 getStrokeColor() {
8232 return this._getRollColor(this.bubble.color ?? getHslFromAnimation(this.strokeColor));
8233 }
8234 init(id, position, overrideOptions, group) {
8235 const container = this.container,
8236 engine = this._engine;
8237 this.id = id;
8238 this.group = group;
8239 this.fill = true;
8240 this.pathRotation = false;
8241 this.close = true;
8242 this.lastPathTime = 0;
8243 this.destroyed = false;
8244 this.unbreakable = false;
8245 this.rotation = 0;
8246 this.misplaced = false;
8247 this.retina = {
8248 maxDistance: {}
8249 };
8250 this.outType = "normal";
8251 this.ignoresResizeRatio = true;
8252 const pxRatio = container.retina.pixelRatio,
8253 mainOptions = container.actualOptions,
8254 particlesOptions = loadParticlesOptions(this._engine, container, mainOptions.particles),
8255 shapeType = particlesOptions.shape.type,
8256 {
8257 reduceDuplicates
8258 } = particlesOptions;
8259 this.shape = itemFromSingleOrMultiple(shapeType, this.id, reduceDuplicates);
8260 const shapeOptions = particlesOptions.shape;
8261 if (overrideOptions && overrideOptions.shape && overrideOptions.shape.type) {
8262 const overrideShapeType = overrideOptions.shape.type,
8263 shape = itemFromSingleOrMultiple(overrideShapeType, this.id, reduceDuplicates);
8264 if (shape) {
8265 this.shape = shape;
8266 shapeOptions.load(overrideOptions.shape);
8267 }
8268 }
8269 this.shapeData = this._loadShapeData(shapeOptions, reduceDuplicates);
8270 particlesOptions.load(overrideOptions);
8271 const shapeData = this.shapeData;
8272 if (shapeData) {
8273 particlesOptions.load(shapeData.particles);
8274 }
8275 const interactivity = new Interactivity(engine, container);
8276 interactivity.load(container.actualOptions.interactivity);
8277 interactivity.load(particlesOptions.interactivity);
8278 this.interactivity = interactivity;
8279 this.fill = shapeData?.fill ?? particlesOptions.shape.fill;
8280 this.close = shapeData?.close ?? particlesOptions.shape.close;
8281 this.options = particlesOptions;
8282 const pathOptions = this.options.move.path;
8283 this.pathDelay = getValue(pathOptions.delay) * 1000;
8284 if (pathOptions.generator) {
8285 this.pathGenerator = this._engine.plugins.getPathGenerator(pathOptions.generator);
8286 if (this.pathGenerator && container.addPath(pathOptions.generator, this.pathGenerator)) {
8287 this.pathGenerator.init(container);
8288 }
8289 }
8290 container.retina.initParticle(this);
8291 this.size = initParticleNumericAnimationValue(this.options.size, pxRatio);
8292 this.bubble = {
8293 inRange: false
8294 };
8295 this.slow = {
8296 inRange: false,
8297 factor: 1
8298 };
8299 this._initPosition(position);
8300 this.initialVelocity = this._calculateVelocity();
8301 this.velocity = this.initialVelocity.copy();
8302 this.moveDecay = 1 - getRangeValue(this.options.move.decay);
8303 const particles = container.particles;
8304 particles.needsSort = particles.needsSort || particles.lastZIndex < this.position.z;
8305 particles.lastZIndex = this.position.z;
8306 this.zIndexFactor = this.position.z / container.zLayers;
8307 this.sides = 24;
8308 let drawer = container.drawers.get(this.shape);
8309 if (!drawer) {
8310 drawer = this._engine.plugins.getShapeDrawer(this.shape);
8311 if (drawer) {
8312 container.drawers.set(this.shape, drawer);
8313 }
8314 }
8315 if (drawer && drawer.loadShape) {
8316 drawer.loadShape(this);
8317 }
8318 const sideCountFunc = drawer?.getSidesCount;
8319 if (sideCountFunc) {
8320 this.sides = sideCountFunc(this);
8321 }
8322 this.spawning = false;
8323 this.shadowColor = rangeColorToRgb(this.options.shadow.color);
8324 for (const updater of container.particles.updaters) {
8325 updater.init(this);
8326 }
8327 for (const mover of container.particles.movers) {
8328 mover.init && mover.init(this);
8329 }
8330 if (drawer && drawer.particleInit) {
8331 drawer.particleInit(container, this);
8332 }
8333 for (const [, plugin] of container.plugins) {
8334 plugin.particleCreated && plugin.particleCreated(this);
8335 }
8336 }
8337 isInsideCanvas() {
8338 const radius = this.getRadius(),
8339 canvasSize = this.container.canvas.size,
8340 position = this.position;
8341 return position.x >= -radius && position.y >= -radius && position.y <= canvasSize.height + radius && position.x <= canvasSize.width + radius;
8342 }
8343 isVisible() {
8344 return !this.destroyed && !this.spawning && this.isInsideCanvas();
8345 }
8346 reset() {
8347 for (const updater of this.container.particles.updaters) {
8348 updater.reset && updater.reset(this);
8349 }
8350 }
8351}
8352;// CONCATENATED MODULE: ../../engine/dist/esm/Core/Utils/Point.js
8353class Point {
8354 constructor(position, particle) {
8355 this.position = position;
8356 this.particle = particle;
8357 }
8358}
8359;// CONCATENATED MODULE: ../../engine/dist/esm/Core/Utils/Range.js
8360class Range {
8361 constructor(x, y) {
8362 this.position = {
8363 x: x,
8364 y: y
8365 };
8366 }
8367}
8368;// CONCATENATED MODULE: ../../engine/dist/esm/Core/Utils/Rectangle.js
8369
8370
8371class Rectangle extends Range {
8372 constructor(x, y, width, height) {
8373 super(x, y);
8374 this.size = {
8375 height: height,
8376 width: width
8377 };
8378 }
8379 contains(point) {
8380 const w = this.size.width,
8381 h = this.size.height,
8382 pos = this.position;
8383 return point.x >= pos.x && point.x <= pos.x + w && point.y >= pos.y && point.y <= pos.y + h;
8384 }
8385 intersects(range) {
8386 if (range instanceof Circle) {
8387 range.intersects(this);
8388 }
8389 const w = this.size.width,
8390 h = this.size.height,
8391 pos1 = this.position,
8392 pos2 = range.position,
8393 size2 = range instanceof Rectangle ? range.size : {
8394 width: 0,
8395 height: 0
8396 },
8397 w2 = size2.width,
8398 h2 = size2.height;
8399 return pos2.x < pos1.x + w && pos2.x + w2 > pos1.x && pos2.y < pos1.y + h && pos2.y + h2 > pos1.y;
8400 }
8401}
8402;// CONCATENATED MODULE: ../../engine/dist/esm/Core/Utils/Circle.js
8403
8404
8405
8406class Circle extends Range {
8407 constructor(x, y, radius) {
8408 super(x, y);
8409 this.radius = radius;
8410 }
8411 contains(point) {
8412 return getDistance(point, this.position) <= this.radius;
8413 }
8414 intersects(range) {
8415 const pos1 = this.position,
8416 pos2 = range.position,
8417 distPos = {
8418 x: Math.abs(pos2.x - pos1.x),
8419 y: Math.abs(pos2.y - pos1.y)
8420 },
8421 r = this.radius;
8422 if (range instanceof Circle) {
8423 const rSum = r + range.radius,
8424 dist = Math.sqrt(distPos.x ** 2 + distPos.y ** 2);
8425 return rSum > dist;
8426 } else if (range instanceof Rectangle) {
8427 const {
8428 width,
8429 height
8430 } = range.size,
8431 edges = Math.pow(distPos.x - width, 2) + Math.pow(distPos.y - height, 2);
8432 return edges <= r ** 2 || distPos.x <= r + width && distPos.y <= r + height || distPos.x <= width || distPos.y <= height;
8433 }
8434 return false;
8435 }
8436}
8437;// CONCATENATED MODULE: ../../engine/dist/esm/Core/Utils/QuadTree.js
8438
8439
8440
8441class QuadTree {
8442 constructor(rectangle, capacity) {
8443 this.rectangle = rectangle;
8444 this.capacity = capacity;
8445 this._subdivide = () => {
8446 const {
8447 x,
8448 y
8449 } = this.rectangle.position,
8450 {
8451 width,
8452 height
8453 } = this.rectangle.size,
8454 {
8455 capacity
8456 } = this;
8457 for (let i = 0; i < 4; i++) {
8458 this._subs.push(new QuadTree(new Rectangle(x + width / 2 * (i % 2), y + height / 2 * (Math.round(i / 2) - i % 2), width / 2, height / 2), capacity));
8459 }
8460 this._divided = true;
8461 };
8462 this._points = [];
8463 this._divided = false;
8464 this._subs = [];
8465 }
8466 insert(point) {
8467 if (!this.rectangle.contains(point.position)) {
8468 return false;
8469 }
8470 if (this._points.length < this.capacity) {
8471 this._points.push(point);
8472 return true;
8473 }
8474 if (!this._divided) {
8475 this._subdivide();
8476 }
8477 return this._subs.some(sub => sub.insert(point));
8478 }
8479 query(range, check, found) {
8480 const res = found || [];
8481 if (!range.intersects(this.rectangle)) {
8482 return [];
8483 }
8484 for (const p of this._points) {
8485 if (!range.contains(p.position) && getDistance(range.position, p.position) > p.particle.getRadius() && (!check || check(p.particle))) {
8486 continue;
8487 }
8488 res.push(p.particle);
8489 }
8490 if (this._divided) {
8491 for (const sub of this._subs) {
8492 sub.query(range, check, res);
8493 }
8494 }
8495 return res;
8496 }
8497 queryCircle(position, radius, check) {
8498 return this.query(new Circle(position.x, position.y, radius), check);
8499 }
8500 queryRectangle(position, size, check) {
8501 return this.query(new Rectangle(position.x, position.y, size.width, size.height), check);
8502 }
8503}
8504;// CONCATENATED MODULE: ../../engine/dist/esm/Core/Particles.js
8505
8506
8507
8508
8509
8510
8511
8512const qTreeCapacity = 4;
8513const qTreeRectangle = canvasSize => {
8514 return new Rectangle(-canvasSize.width / 4, -canvasSize.height / 4, canvasSize.width * 3 / 2, canvasSize.height * 3 / 2);
8515};
8516class Particles {
8517 constructor(engine, container) {
8518 this._applyDensity = (options, manualCount, group) => {
8519 if (!options.number.density?.enable) {
8520 return;
8521 }
8522 const numberOptions = options.number,
8523 densityFactor = this._initDensityFactor(numberOptions.density),
8524 optParticlesNumber = numberOptions.value,
8525 optParticlesLimit = numberOptions.limit > 0 ? numberOptions.limit : optParticlesNumber,
8526 particlesNumber = Math.min(optParticlesNumber, optParticlesLimit) * densityFactor + manualCount,
8527 particlesCount = Math.min(this.count, this.filter(t => t.group === group).length);
8528 this.limit = numberOptions.limit * densityFactor;
8529 if (particlesCount < particlesNumber) {
8530 this.push(Math.abs(particlesNumber - particlesCount), undefined, options, group);
8531 } else if (particlesCount > particlesNumber) {
8532 this.removeQuantity(particlesCount - particlesNumber, group);
8533 }
8534 };
8535 this._initDensityFactor = densityOptions => {
8536 const container = this._container;
8537 if (!container.canvas.element || !densityOptions.enable) {
8538 return 1;
8539 }
8540 const canvas = container.canvas.element,
8541 pxRatio = container.retina.pixelRatio;
8542 return canvas.width * canvas.height / (densityOptions.factor * pxRatio ** 2 * densityOptions.area);
8543 };
8544 this._pushParticle = (position, overrideOptions, group, initializer) => {
8545 try {
8546 let particle = this.pool.pop();
8547 if (particle) {
8548 particle.init(this._nextId, position, overrideOptions, group);
8549 } else {
8550 particle = new Particle(this._engine, this._nextId, this._container, position, overrideOptions, group);
8551 }
8552 let canAdd = true;
8553 if (initializer) {
8554 canAdd = initializer(particle);
8555 }
8556 if (!canAdd) {
8557 return;
8558 }
8559 this._array.push(particle);
8560 this._zArray.push(particle);
8561 this._nextId++;
8562 this._engine.dispatchEvent("particleAdded", {
8563 container: this._container,
8564 data: {
8565 particle
8566 }
8567 });
8568 return particle;
8569 } catch (e) {
8570 getLogger().warning(`${errorPrefix} adding particle: ${e}`);
8571 return;
8572 }
8573 };
8574 this._removeParticle = (index, group, override) => {
8575 const particle = this._array[index];
8576 if (!particle || particle.group !== group) {
8577 return false;
8578 }
8579 particle.destroy(override);
8580 const zIdx = this._zArray.indexOf(particle);
8581 this._array.splice(index, 1);
8582 this._zArray.splice(zIdx, 1);
8583 this.pool.push(particle);
8584 this._engine.dispatchEvent("particleRemoved", {
8585 container: this._container,
8586 data: {
8587 particle
8588 }
8589 });
8590 return true;
8591 };
8592 this._engine = engine;
8593 this._container = container;
8594 this._nextId = 0;
8595 this._array = [];
8596 this._zArray = [];
8597 this.pool = [];
8598 this.limit = 0;
8599 this.needsSort = false;
8600 this.lastZIndex = 0;
8601 this._interactionManager = new InteractionManager(engine, container);
8602 const canvasSize = container.canvas.size;
8603 this.quadTree = new QuadTree(qTreeRectangle(canvasSize), qTreeCapacity);
8604 this.movers = this._engine.plugins.getMovers(container, true);
8605 this.updaters = this._engine.plugins.getUpdaters(container, true);
8606 }
8607 get count() {
8608 return this._array.length;
8609 }
8610 addManualParticles() {
8611 const container = this._container,
8612 options = container.actualOptions;
8613 for (const particle of options.manualParticles) {
8614 this.addParticle(particle.position ? getPosition(particle.position, container.canvas.size) : undefined, particle.options);
8615 }
8616 }
8617 addParticle(position, overrideOptions, group, initializer) {
8618 const container = this._container,
8619 options = container.actualOptions,
8620 limit = options.particles.number.limit;
8621 if (limit > 0) {
8622 const countToRemove = this.count + 1 - limit;
8623 if (countToRemove > 0) {
8624 this.removeQuantity(countToRemove);
8625 }
8626 }
8627 return this._pushParticle(position, overrideOptions, group, initializer);
8628 }
8629 clear() {
8630 this._array = [];
8631 this._zArray = [];
8632 }
8633 destroy() {
8634 this._array = [];
8635 this._zArray = [];
8636 this.movers = [];
8637 this.updaters = [];
8638 }
8639 async draw(delta) {
8640 const container = this._container;
8641 container.canvas.clear();
8642 await this.update(delta);
8643 for (const [, plugin] of container.plugins) {
8644 container.canvas.drawPlugin(plugin, delta);
8645 }
8646 for (const p of this._zArray) {
8647 p.draw(delta);
8648 }
8649 }
8650 filter(condition) {
8651 return this._array.filter(condition);
8652 }
8653 find(condition) {
8654 return this._array.find(condition);
8655 }
8656 handleClickMode(mode) {
8657 this._interactionManager.handleClickMode(mode);
8658 }
8659 init() {
8660 const container = this._container,
8661 options = container.actualOptions;
8662 this.lastZIndex = 0;
8663 this.needsSort = false;
8664 let handled = false;
8665 this.updaters = this._engine.plugins.getUpdaters(container, true);
8666 this._interactionManager.init();
8667 for (const [, plugin] of container.plugins) {
8668 if (plugin.particlesInitialization !== undefined) {
8669 handled = plugin.particlesInitialization();
8670 }
8671 if (handled) {
8672 break;
8673 }
8674 }
8675 this._interactionManager.init();
8676 for (const [, pathGenerator] of container.pathGenerators) {
8677 pathGenerator.init(container);
8678 }
8679 this.addManualParticles();
8680 if (!handled) {
8681 for (const group in options.particles.groups) {
8682 const groupOptions = options.particles.groups[group];
8683 for (let i = this.count, j = 0; j < groupOptions.number?.value && i < options.particles.number.value; i++, j++) {
8684 this.addParticle(undefined, groupOptions, group);
8685 }
8686 }
8687 for (let i = this.count; i < options.particles.number.value; i++) {
8688 this.addParticle();
8689 }
8690 }
8691 }
8692 push(nb, mouse, overrideOptions, group) {
8693 this.pushing = true;
8694 for (let i = 0; i < nb; i++) {
8695 this.addParticle(mouse?.position, overrideOptions, group);
8696 }
8697 this.pushing = false;
8698 }
8699 async redraw() {
8700 this.clear();
8701 this.init();
8702 await this.draw({
8703 value: 0,
8704 factor: 0
8705 });
8706 }
8707 remove(particle, group, override) {
8708 this.removeAt(this._array.indexOf(particle), undefined, group, override);
8709 }
8710 removeAt(index, quantity = 1, group, override) {
8711 if (index < 0 || index > this.count) {
8712 return;
8713 }
8714 let deleted = 0;
8715 for (let i = index; deleted < quantity && i < this.count; i++) {
8716 this._removeParticle(i--, group, override) && deleted++;
8717 }
8718 }
8719 removeQuantity(quantity, group) {
8720 this.removeAt(0, quantity, group);
8721 }
8722 setDensity() {
8723 const options = this._container.actualOptions,
8724 groups = options.particles.groups;
8725 for (const group in groups) {
8726 this._applyDensity(groups[group], 0, group);
8727 }
8728 this._applyDensity(options.particles, options.manualParticles.length);
8729 }
8730 async update(delta) {
8731 const container = this._container,
8732 particlesToDelete = new Set();
8733 this.quadTree = new QuadTree(qTreeRectangle(container.canvas.size), qTreeCapacity);
8734 for (const [, pathGenerator] of container.pathGenerators) {
8735 pathGenerator.update();
8736 }
8737 for (const [, plugin] of container.plugins) {
8738 plugin.update && plugin.update(delta);
8739 }
8740 for (const particle of this._array) {
8741 const resizeFactor = container.canvas.resizeFactor;
8742 if (resizeFactor && !particle.ignoresResizeRatio) {
8743 particle.position.x *= resizeFactor.width;
8744 particle.position.y *= resizeFactor.height;
8745 particle.initialPosition.x *= resizeFactor.width;
8746 particle.initialPosition.y *= resizeFactor.height;
8747 }
8748 particle.ignoresResizeRatio = false;
8749 await this._interactionManager.reset(particle);
8750 for (const [, plugin] of this._container.plugins) {
8751 if (particle.destroyed) {
8752 break;
8753 }
8754 if (plugin.particleUpdate) {
8755 plugin.particleUpdate(particle, delta);
8756 }
8757 }
8758 for (const mover of this.movers) {
8759 mover.isEnabled(particle) && mover.move(particle, delta);
8760 }
8761 if (particle.destroyed) {
8762 particlesToDelete.add(particle);
8763 continue;
8764 }
8765 this.quadTree.insert(new Point(particle.getPosition(), particle));
8766 }
8767 if (particlesToDelete.size) {
8768 const checkDelete = p => !particlesToDelete.has(p);
8769 this._array = this.filter(checkDelete);
8770 this._zArray = this._zArray.filter(checkDelete);
8771 this.pool.push(...particlesToDelete);
8772 }
8773 await this._interactionManager.externalInteract(delta);
8774 for (const particle of this._array) {
8775 for (const updater of this.updaters) {
8776 updater.update(particle, delta);
8777 }
8778 if (!particle.destroyed && !particle.spawning) {
8779 await this._interactionManager.particlesInteract(particle, delta);
8780 }
8781 }
8782 delete container.canvas.resizeFactor;
8783 if (this.needsSort) {
8784 const zArray = this._zArray;
8785 zArray.sort((a, b) => b.position.z - a.position.z || a.id - b.id);
8786 this.lastZIndex = zArray[zArray.length - 1].position.z;
8787 this.needsSort = false;
8788 }
8789 }
8790}
8791;// CONCATENATED MODULE: ../../engine/dist/esm/Core/Retina.js
8792
8793
8794class Retina {
8795 constructor(container) {
8796 this.container = container;
8797 this.pixelRatio = 1;
8798 this.reduceFactor = 1;
8799 }
8800 init() {
8801 const container = this.container,
8802 options = container.actualOptions;
8803 this.pixelRatio = !options.detectRetina || isSsr() ? 1 : window.devicePixelRatio;
8804 this.reduceFactor = 1;
8805 const ratio = this.pixelRatio;
8806 if (container.canvas.element) {
8807 const element = container.canvas.element;
8808 container.canvas.size.width = element.offsetWidth * ratio;
8809 container.canvas.size.height = element.offsetHeight * ratio;
8810 }
8811 const particles = options.particles,
8812 moveOptions = particles.move;
8813 this.attractDistance = getRangeValue(moveOptions.attract.distance) * ratio;
8814 this.maxSpeed = getRangeValue(moveOptions.gravity.maxSpeed) * ratio;
8815 this.sizeAnimationSpeed = getRangeValue(particles.size.animation.speed) * ratio;
8816 }
8817 initParticle(particle) {
8818 const options = particle.options,
8819 ratio = this.pixelRatio,
8820 moveOptions = options.move,
8821 moveDistance = moveOptions.distance,
8822 props = particle.retina;
8823 props.attractDistance = getRangeValue(moveOptions.attract.distance) * ratio;
8824 props.moveDrift = getRangeValue(moveOptions.drift) * ratio;
8825 props.moveSpeed = getRangeValue(moveOptions.speed) * ratio;
8826 props.sizeAnimationSpeed = getRangeValue(options.size.animation.speed) * ratio;
8827 const maxDistance = props.maxDistance;
8828 maxDistance.horizontal = moveDistance.horizontal !== undefined ? moveDistance.horizontal * ratio : undefined;
8829 maxDistance.vertical = moveDistance.vertical !== undefined ? moveDistance.vertical * ratio : undefined;
8830 props.maxSpeed = getRangeValue(moveOptions.gravity.maxSpeed) * ratio;
8831 }
8832}
8833;// CONCATENATED MODULE: ../../engine/dist/esm/Core/Container.js
8834
8835
8836
8837
8838
8839
8840
8841
8842
8843function guardCheck(container) {
8844 return container && !container.destroyed;
8845}
8846function initDelta(value, fpsLimit = 60, smooth = false) {
8847 return {
8848 value,
8849 factor: smooth ? 60 / fpsLimit : 60 * value / 1000
8850 };
8851}
8852function loadContainerOptions(engine, container, ...sourceOptionsArr) {
8853 const options = new Options(engine, container);
8854 loadOptions(options, ...sourceOptionsArr);
8855 return options;
8856}
8857const defaultPathGeneratorKey = "default",
8858 defaultPathGenerator = {
8859 generate: p => p.velocity,
8860 init: () => {},
8861 update: () => {},
8862 reset: () => {}
8863 };
8864class Container {
8865 constructor(engine, id, sourceOptions) {
8866 this.id = id;
8867 this._intersectionManager = entries => {
8868 if (!guardCheck(this) || !this.actualOptions.pauseOnOutsideViewport) {
8869 return;
8870 }
8871 for (const entry of entries) {
8872 if (entry.target !== this.interactivity.element) {
8873 continue;
8874 }
8875 (entry.isIntersecting ? this.play : this.pause)();
8876 }
8877 };
8878 this._nextFrame = async timestamp => {
8879 try {
8880 if (!this.smooth && this.lastFrameTime !== undefined && timestamp < this.lastFrameTime + 1000 / this.fpsLimit) {
8881 this.draw(false);
8882 return;
8883 }
8884 this.lastFrameTime ??= timestamp;
8885 const delta = initDelta(timestamp - this.lastFrameTime, this.fpsLimit, this.smooth);
8886 this.addLifeTime(delta.value);
8887 this.lastFrameTime = timestamp;
8888 if (delta.value > 1000) {
8889 this.draw(false);
8890 return;
8891 }
8892 await this.particles.draw(delta);
8893 if (!this.alive()) {
8894 this.destroy();
8895 return;
8896 }
8897 if (this.getAnimationStatus()) {
8898 this.draw(false);
8899 }
8900 } catch (e) {
8901 getLogger().error(`${errorPrefix} in animation loop`, e);
8902 }
8903 };
8904 this._engine = engine;
8905 this.fpsLimit = 120;
8906 this.smooth = false;
8907 this._delay = 0;
8908 this._duration = 0;
8909 this._lifeTime = 0;
8910 this._firstStart = true;
8911 this.started = false;
8912 this.destroyed = false;
8913 this._paused = true;
8914 this.lastFrameTime = 0;
8915 this.zLayers = 100;
8916 this.pageHidden = false;
8917 this._sourceOptions = sourceOptions;
8918 this._initialSourceOptions = sourceOptions;
8919 this.retina = new Retina(this);
8920 this.canvas = new Canvas(this);
8921 this.particles = new Particles(this._engine, this);
8922 this.pathGenerators = new Map();
8923 this.interactivity = {
8924 mouse: {
8925 clicking: false,
8926 inside: false
8927 }
8928 };
8929 this.plugins = new Map();
8930 this.drawers = new Map();
8931 this._options = loadContainerOptions(this._engine, this);
8932 this.actualOptions = loadContainerOptions(this._engine, this);
8933 this._eventListeners = new EventListeners(this);
8934 if (typeof IntersectionObserver !== "undefined" && IntersectionObserver) {
8935 this._intersectionObserver = new IntersectionObserver(entries => this._intersectionManager(entries));
8936 }
8937 this._engine.dispatchEvent("containerBuilt", {
8938 container: this
8939 });
8940 }
8941 get options() {
8942 return this._options;
8943 }
8944 get sourceOptions() {
8945 return this._sourceOptions;
8946 }
8947 addClickHandler(callback) {
8948 if (!guardCheck(this)) {
8949 return;
8950 }
8951 const el = this.interactivity.element;
8952 if (!el) {
8953 return;
8954 }
8955 const clickOrTouchHandler = (e, pos, radius) => {
8956 if (!guardCheck(this)) {
8957 return;
8958 }
8959 const pxRatio = this.retina.pixelRatio,
8960 posRetina = {
8961 x: pos.x * pxRatio,
8962 y: pos.y * pxRatio
8963 },
8964 particles = this.particles.quadTree.queryCircle(posRetina, radius * pxRatio);
8965 callback(e, particles);
8966 };
8967 const clickHandler = e => {
8968 if (!guardCheck(this)) {
8969 return;
8970 }
8971 const mouseEvent = e,
8972 pos = {
8973 x: mouseEvent.offsetX || mouseEvent.clientX,
8974 y: mouseEvent.offsetY || mouseEvent.clientY
8975 };
8976 clickOrTouchHandler(e, pos, 1);
8977 };
8978 const touchStartHandler = () => {
8979 if (!guardCheck(this)) {
8980 return;
8981 }
8982 touched = true;
8983 touchMoved = false;
8984 };
8985 const touchMoveHandler = () => {
8986 if (!guardCheck(this)) {
8987 return;
8988 }
8989 touchMoved = true;
8990 };
8991 const touchEndHandler = e => {
8992 if (!guardCheck(this)) {
8993 return;
8994 }
8995 if (touched && !touchMoved) {
8996 const touchEvent = e;
8997 let lastTouch = touchEvent.touches[touchEvent.touches.length - 1];
8998 if (!lastTouch) {
8999 lastTouch = touchEvent.changedTouches[touchEvent.changedTouches.length - 1];
9000 if (!lastTouch) {
9001 return;
9002 }
9003 }
9004 const element = this.canvas.element,
9005 canvasRect = element ? element.getBoundingClientRect() : undefined,
9006 pos = {
9007 x: lastTouch.clientX - (canvasRect ? canvasRect.left : 0),
9008 y: lastTouch.clientY - (canvasRect ? canvasRect.top : 0)
9009 };
9010 clickOrTouchHandler(e, pos, Math.max(lastTouch.radiusX, lastTouch.radiusY));
9011 }
9012 touched = false;
9013 touchMoved = false;
9014 };
9015 const touchCancelHandler = () => {
9016 if (!guardCheck(this)) {
9017 return;
9018 }
9019 touched = false;
9020 touchMoved = false;
9021 };
9022 let touched = false,
9023 touchMoved = false;
9024 el.addEventListener("click", clickHandler);
9025 el.addEventListener("touchstart", touchStartHandler);
9026 el.addEventListener("touchmove", touchMoveHandler);
9027 el.addEventListener("touchend", touchEndHandler);
9028 el.addEventListener("touchcancel", touchCancelHandler);
9029 }
9030 addLifeTime(value) {
9031 this._lifeTime += value;
9032 }
9033 addPath(key, generator, override = false) {
9034 if (!guardCheck(this) || !override && this.pathGenerators.has(key)) {
9035 return false;
9036 }
9037 this.pathGenerators.set(key, generator ?? defaultPathGenerator);
9038 return true;
9039 }
9040 alive() {
9041 return !this._duration || this._lifeTime <= this._duration;
9042 }
9043 destroy() {
9044 if (!guardCheck(this)) {
9045 return;
9046 }
9047 this.stop();
9048 this.particles.destroy();
9049 this.canvas.destroy();
9050 for (const [, drawer] of this.drawers) {
9051 drawer.destroy && drawer.destroy(this);
9052 }
9053 for (const key of this.drawers.keys()) {
9054 this.drawers.delete(key);
9055 }
9056 this._engine.plugins.destroy(this);
9057 this.destroyed = true;
9058 const mainArr = this._engine.dom(),
9059 idx = mainArr.findIndex(t => t === this);
9060 if (idx >= 0) {
9061 mainArr.splice(idx, 1);
9062 }
9063 this._engine.dispatchEvent("containerDestroyed", {
9064 container: this
9065 });
9066 }
9067 draw(force) {
9068 if (!guardCheck(this)) {
9069 return;
9070 }
9071 let refreshTime = force;
9072 this._drawAnimationFrame = requestAnimationFrame(async timestamp => {
9073 if (refreshTime) {
9074 this.lastFrameTime = undefined;
9075 refreshTime = false;
9076 }
9077 await this._nextFrame(timestamp);
9078 });
9079 }
9080 async export(type, options = {}) {
9081 for (const [, plugin] of this.plugins) {
9082 if (!plugin.export) {
9083 continue;
9084 }
9085 const res = await plugin.export(type, options);
9086 if (!res.supported) {
9087 continue;
9088 }
9089 return res.blob;
9090 }
9091 getLogger().error(`${errorPrefix} - Export plugin with type ${type} not found`);
9092 }
9093 getAnimationStatus() {
9094 return !this._paused && !this.pageHidden && guardCheck(this);
9095 }
9096 handleClickMode(mode) {
9097 if (!guardCheck(this)) {
9098 return;
9099 }
9100 this.particles.handleClickMode(mode);
9101 for (const [, plugin] of this.plugins) {
9102 plugin.handleClickMode && plugin.handleClickMode(mode);
9103 }
9104 }
9105 async init() {
9106 if (!guardCheck(this)) {
9107 return;
9108 }
9109 const shapes = this._engine.plugins.getSupportedShapes();
9110 for (const type of shapes) {
9111 const drawer = this._engine.plugins.getShapeDrawer(type);
9112 if (drawer) {
9113 this.drawers.set(type, drawer);
9114 }
9115 }
9116 this._options = loadContainerOptions(this._engine, this, this._initialSourceOptions, this.sourceOptions);
9117 this.actualOptions = loadContainerOptions(this._engine, this, this._options);
9118 const availablePlugins = this._engine.plugins.getAvailablePlugins(this);
9119 for (const [id, plugin] of availablePlugins) {
9120 this.plugins.set(id, plugin);
9121 }
9122 this.retina.init();
9123 await this.canvas.init();
9124 this.updateActualOptions();
9125 this.canvas.initBackground();
9126 this.canvas.resize();
9127 this.zLayers = this.actualOptions.zLayers;
9128 this._duration = getRangeValue(this.actualOptions.duration) * 1000;
9129 this._delay = getRangeValue(this.actualOptions.delay) * 1000;
9130 this._lifeTime = 0;
9131 this.fpsLimit = this.actualOptions.fpsLimit > 0 ? this.actualOptions.fpsLimit : 120;
9132 this.smooth = this.actualOptions.smooth;
9133 for (const [, drawer] of this.drawers) {
9134 drawer.init && (await drawer.init(this));
9135 }
9136 for (const [, plugin] of this.plugins) {
9137 plugin.init && (await plugin.init());
9138 }
9139 this._engine.dispatchEvent("containerInit", {
9140 container: this
9141 });
9142 this.particles.init();
9143 this.particles.setDensity();
9144 for (const [, plugin] of this.plugins) {
9145 plugin.particlesSetup && plugin.particlesSetup();
9146 }
9147 this._engine.dispatchEvent("particlesSetup", {
9148 container: this
9149 });
9150 }
9151 async loadTheme(name) {
9152 if (!guardCheck(this)) {
9153 return;
9154 }
9155 this._currentTheme = name;
9156 await this.refresh();
9157 }
9158 pause() {
9159 if (!guardCheck(this)) {
9160 return;
9161 }
9162 if (this._drawAnimationFrame !== undefined) {
9163 cancelAnimationFrame(this._drawAnimationFrame);
9164 delete this._drawAnimationFrame;
9165 }
9166 if (this._paused) {
9167 return;
9168 }
9169 for (const [, plugin] of this.plugins) {
9170 plugin.pause && plugin.pause();
9171 }
9172 if (!this.pageHidden) {
9173 this._paused = true;
9174 }
9175 this._engine.dispatchEvent("containerPaused", {
9176 container: this
9177 });
9178 }
9179 play(force) {
9180 if (!guardCheck(this)) {
9181 return;
9182 }
9183 const needsUpdate = this._paused || force;
9184 if (this._firstStart && !this.actualOptions.autoPlay) {
9185 this._firstStart = false;
9186 return;
9187 }
9188 if (this._paused) {
9189 this._paused = false;
9190 }
9191 if (needsUpdate) {
9192 for (const [, plugin] of this.plugins) {
9193 if (plugin.play) {
9194 plugin.play();
9195 }
9196 }
9197 }
9198 this._engine.dispatchEvent("containerPlay", {
9199 container: this
9200 });
9201 this.draw(needsUpdate || false);
9202 }
9203 async refresh() {
9204 if (!guardCheck(this)) {
9205 return;
9206 }
9207 this.stop();
9208 return this.start();
9209 }
9210 async reset() {
9211 if (!guardCheck(this)) {
9212 return;
9213 }
9214 this._initialSourceOptions = undefined;
9215 this._options = loadContainerOptions(this._engine, this);
9216 this.actualOptions = loadContainerOptions(this._engine, this, this._options);
9217 return this.refresh();
9218 }
9219 setNoise(noiseOrGenerator, init, update) {
9220 if (!guardCheck(this)) {
9221 return;
9222 }
9223 this.setPath(noiseOrGenerator, init, update);
9224 }
9225 setPath(pathOrGenerator, init, update) {
9226 if (!pathOrGenerator || !guardCheck(this)) {
9227 return;
9228 }
9229 const pathGenerator = {
9230 ...defaultPathGenerator
9231 };
9232 if (isFunction(pathOrGenerator)) {
9233 pathGenerator.generate = pathOrGenerator;
9234 if (init) {
9235 pathGenerator.init = init;
9236 }
9237 if (update) {
9238 pathGenerator.update = update;
9239 }
9240 } else {
9241 const oldGenerator = pathGenerator;
9242 pathGenerator.generate = pathOrGenerator.generate || oldGenerator.generate;
9243 pathGenerator.init = pathOrGenerator.init || oldGenerator.init;
9244 pathGenerator.update = pathOrGenerator.update || oldGenerator.update;
9245 }
9246 this.addPath(defaultPathGeneratorKey, pathGenerator, true);
9247 }
9248 async start() {
9249 if (!guardCheck(this) || this.started) {
9250 return;
9251 }
9252 await this.init();
9253 this.started = true;
9254 await new Promise(resolve => {
9255 this._delayTimeout = setTimeout(async () => {
9256 this._eventListeners.addListeners();
9257 if (this.interactivity.element instanceof HTMLElement && this._intersectionObserver) {
9258 this._intersectionObserver.observe(this.interactivity.element);
9259 }
9260 for (const [, plugin] of this.plugins) {
9261 plugin.start && (await plugin.start());
9262 }
9263 this._engine.dispatchEvent("containerStarted", {
9264 container: this
9265 });
9266 this.play();
9267 resolve();
9268 }, this._delay);
9269 });
9270 }
9271 stop() {
9272 if (!guardCheck(this) || !this.started) {
9273 return;
9274 }
9275 if (this._delayTimeout) {
9276 clearTimeout(this._delayTimeout);
9277 delete this._delayTimeout;
9278 }
9279 this._firstStart = true;
9280 this.started = false;
9281 this._eventListeners.removeListeners();
9282 this.pause();
9283 this.particles.clear();
9284 this.canvas.stop();
9285 if (this.interactivity.element instanceof HTMLElement && this._intersectionObserver) {
9286 this._intersectionObserver.unobserve(this.interactivity.element);
9287 }
9288 for (const [, plugin] of this.plugins) {
9289 plugin.stop && plugin.stop();
9290 }
9291 for (const key of this.plugins.keys()) {
9292 this.plugins.delete(key);
9293 }
9294 this._sourceOptions = this._options;
9295 this._engine.dispatchEvent("containerStopped", {
9296 container: this
9297 });
9298 }
9299 updateActualOptions() {
9300 this.actualOptions.responsive = [];
9301 const newMaxWidth = this.actualOptions.setResponsive(this.canvas.size.width, this.retina.pixelRatio, this._options);
9302 this.actualOptions.setTheme(this._currentTheme);
9303 if (this.responsiveMaxWidth === newMaxWidth) {
9304 return false;
9305 }
9306 this.responsiveMaxWidth = newMaxWidth;
9307 return true;
9308 }
9309}
9310;// CONCATENATED MODULE: ../../engine/dist/esm/Utils/EventDispatcher.js
9311class EventDispatcher {
9312 constructor() {
9313 this._listeners = new Map();
9314 }
9315 addEventListener(type, listener) {
9316 this.removeEventListener(type, listener);
9317 let arr = this._listeners.get(type);
9318 if (!arr) {
9319 arr = [];
9320 this._listeners.set(type, arr);
9321 }
9322 arr.push(listener);
9323 }
9324 dispatchEvent(type, args) {
9325 const listeners = this._listeners.get(type);
9326 listeners && listeners.forEach(handler => handler(args));
9327 }
9328 hasEventListener(type) {
9329 return !!this._listeners.get(type);
9330 }
9331 removeAllEventListeners(type) {
9332 if (!type) {
9333 this._listeners = new Map();
9334 } else {
9335 this._listeners.delete(type);
9336 }
9337 }
9338 removeEventListener(type, listener) {
9339 const arr = this._listeners.get(type);
9340 if (!arr) {
9341 return;
9342 }
9343 const length = arr.length,
9344 idx = arr.indexOf(listener);
9345 if (idx < 0) {
9346 return;
9347 }
9348 if (length === 1) {
9349 this._listeners.delete(type);
9350 } else {
9351 arr.splice(idx, 1);
9352 }
9353 }
9354}
9355;// CONCATENATED MODULE: ../../engine/dist/esm/Core/Utils/Plugins.js
9356
9357function getItemsFromInitializer(container, map, initializers, force = false) {
9358 let res = map.get(container);
9359 if (!res || force) {
9360 res = [...initializers.values()].map(t => t(container));
9361 map.set(container, res);
9362 }
9363 return res;
9364}
9365class Plugins {
9366 constructor(engine) {
9367 this._engine = engine;
9368 this.plugins = [];
9369 this._initializers = {
9370 interactors: new Map(),
9371 movers: new Map(),
9372 updaters: new Map()
9373 };
9374 this.interactors = new Map();
9375 this.movers = new Map();
9376 this.updaters = new Map();
9377 this.presets = new Map();
9378 this.drawers = new Map();
9379 this.pathGenerators = new Map();
9380 }
9381 addInteractor(name, initInteractor) {
9382 this._initializers.interactors.set(name, initInteractor);
9383 }
9384 addParticleMover(name, initMover) {
9385 this._initializers.movers.set(name, initMover);
9386 }
9387 addParticleUpdater(name, initUpdater) {
9388 this._initializers.updaters.set(name, initUpdater);
9389 }
9390 addPathGenerator(type, pathGenerator) {
9391 !this.getPathGenerator(type) && this.pathGenerators.set(type, pathGenerator);
9392 }
9393 addPlugin(plugin) {
9394 !this.getPlugin(plugin.id) && this.plugins.push(plugin);
9395 }
9396 addPreset(presetKey, options, override = false) {
9397 (override || !this.getPreset(presetKey)) && this.presets.set(presetKey, options);
9398 }
9399 addShapeDrawer(types, drawer) {
9400 executeOnSingleOrMultiple(types, type => {
9401 !this.getShapeDrawer(type) && this.drawers.set(type, drawer);
9402 });
9403 }
9404 destroy(container) {
9405 this.updaters.delete(container);
9406 this.movers.delete(container);
9407 this.interactors.delete(container);
9408 }
9409 getAvailablePlugins(container) {
9410 const res = new Map();
9411 for (const plugin of this.plugins) {
9412 plugin.needsPlugin(container.actualOptions) && res.set(plugin.id, plugin.getPlugin(container));
9413 }
9414 return res;
9415 }
9416 getInteractors(container, force = false) {
9417 return getItemsFromInitializer(container, this.interactors, this._initializers.interactors, force);
9418 }
9419 getMovers(container, force = false) {
9420 return getItemsFromInitializer(container, this.movers, this._initializers.movers, force);
9421 }
9422 getPathGenerator(type) {
9423 return this.pathGenerators.get(type);
9424 }
9425 getPlugin(plugin) {
9426 return this.plugins.find(t => t.id === plugin);
9427 }
9428 getPreset(preset) {
9429 return this.presets.get(preset);
9430 }
9431 getShapeDrawer(type) {
9432 return this.drawers.get(type);
9433 }
9434 getSupportedShapes() {
9435 return this.drawers.keys();
9436 }
9437 getUpdaters(container, force = false) {
9438 return getItemsFromInitializer(container, this.updaters, this._initializers.updaters, force);
9439 }
9440 loadOptions(options, sourceOptions) {
9441 for (const plugin of this.plugins) {
9442 plugin.loadOptions(options, sourceOptions);
9443 }
9444 }
9445 loadParticlesOptions(container, options, ...sourceOptions) {
9446 const updaters = this.updaters.get(container);
9447 if (!updaters) {
9448 return;
9449 }
9450 for (const updater of updaters) {
9451 updater.loadOptions && updater.loadOptions(options, ...sourceOptions);
9452 }
9453 }
9454}
9455;// CONCATENATED MODULE: ../../engine/dist/esm/Core/Engine.js
9456
9457
9458
9459
9460
9461
9462async function getDataFromUrl(data) {
9463 const url = itemFromSingleOrMultiple(data.url, data.index);
9464 if (!url) {
9465 return data.fallback;
9466 }
9467 const response = await fetch(url);
9468 if (response.ok) {
9469 return response.json();
9470 }
9471 getLogger().error(`${errorPrefix} ${response.status} while retrieving config file`);
9472 return data.fallback;
9473}
9474function isParamsEmpty(params) {
9475 return !params.id && !params.element && !params.url && !params.options;
9476}
9477function isParams(obj) {
9478 return !isParamsEmpty(obj);
9479}
9480class Engine {
9481 constructor() {
9482 this._configs = new Map();
9483 this._domArray = [];
9484 this._eventDispatcher = new EventDispatcher();
9485 this._initialized = false;
9486 this.plugins = new Plugins(this);
9487 }
9488 get configs() {
9489 const res = {};
9490 for (const [name, config] of this._configs) {
9491 res[name] = config;
9492 }
9493 return res;
9494 }
9495 get version() {
9496 return "2.12.0";
9497 }
9498 addConfig(nameOrConfig, config) {
9499 if (isString(nameOrConfig)) {
9500 if (config) {
9501 config.name = nameOrConfig;
9502 this._configs.set(nameOrConfig, config);
9503 }
9504 } else {
9505 this._configs.set(nameOrConfig.name ?? "default", nameOrConfig);
9506 }
9507 }
9508 addEventListener(type, listener) {
9509 this._eventDispatcher.addEventListener(type, listener);
9510 }
9511 async addInteractor(name, interactorInitializer, refresh = true) {
9512 this.plugins.addInteractor(name, interactorInitializer);
9513 await this.refresh(refresh);
9514 }
9515 async addMover(name, moverInitializer, refresh = true) {
9516 this.plugins.addParticleMover(name, moverInitializer);
9517 await this.refresh(refresh);
9518 }
9519 async addParticleUpdater(name, updaterInitializer, refresh = true) {
9520 this.plugins.addParticleUpdater(name, updaterInitializer);
9521 await this.refresh(refresh);
9522 }
9523 async addPathGenerator(name, generator, refresh = true) {
9524 this.plugins.addPathGenerator(name, generator);
9525 await this.refresh(refresh);
9526 }
9527 async addPlugin(plugin, refresh = true) {
9528 this.plugins.addPlugin(plugin);
9529 await this.refresh(refresh);
9530 }
9531 async addPreset(preset, options, override = false, refresh = true) {
9532 this.plugins.addPreset(preset, options, override);
9533 await this.refresh(refresh);
9534 }
9535 async addShape(shape, drawer, initOrRefresh, afterEffectOrRefresh, destroyOrRefresh, refresh = true) {
9536 let customDrawer;
9537 let realRefresh = refresh,
9538 realInit,
9539 realAfterEffect,
9540 realDestroy;
9541 if (isBoolean(initOrRefresh)) {
9542 realRefresh = initOrRefresh;
9543 realInit = undefined;
9544 } else {
9545 realInit = initOrRefresh;
9546 }
9547 if (isBoolean(afterEffectOrRefresh)) {
9548 realRefresh = afterEffectOrRefresh;
9549 realAfterEffect = undefined;
9550 } else {
9551 realAfterEffect = afterEffectOrRefresh;
9552 }
9553 if (isBoolean(destroyOrRefresh)) {
9554 realRefresh = destroyOrRefresh;
9555 realDestroy = undefined;
9556 } else {
9557 realDestroy = destroyOrRefresh;
9558 }
9559 if (isFunction(drawer)) {
9560 customDrawer = {
9561 afterEffect: realAfterEffect,
9562 destroy: realDestroy,
9563 draw: drawer,
9564 init: realInit
9565 };
9566 } else {
9567 customDrawer = drawer;
9568 }
9569 this.plugins.addShapeDrawer(shape, customDrawer);
9570 await this.refresh(realRefresh);
9571 }
9572 dispatchEvent(type, args) {
9573 this._eventDispatcher.dispatchEvent(type, args);
9574 }
9575 dom() {
9576 return this._domArray;
9577 }
9578 domItem(index) {
9579 const dom = this.dom(),
9580 item = dom[index];
9581 if (!item || item.destroyed) {
9582 dom.splice(index, 1);
9583 return;
9584 }
9585 return item;
9586 }
9587 init() {
9588 if (this._initialized) {
9589 return;
9590 }
9591 this._initialized = true;
9592 }
9593 async load(tagIdOrOptionsOrParams, options) {
9594 return this.loadFromArray(tagIdOrOptionsOrParams, options);
9595 }
9596 async loadFromArray(tagIdOrOptionsOrParams, optionsOrIndex, index) {
9597 let params;
9598 if (!isParams(tagIdOrOptionsOrParams)) {
9599 params = {};
9600 if (isString(tagIdOrOptionsOrParams)) {
9601 params.id = tagIdOrOptionsOrParams;
9602 } else {
9603 params.options = tagIdOrOptionsOrParams;
9604 }
9605 if (isNumber(optionsOrIndex)) {
9606 params.index = optionsOrIndex;
9607 } else {
9608 params.options = optionsOrIndex ?? params.options;
9609 }
9610 params.index = index ?? params.index;
9611 } else {
9612 params = tagIdOrOptionsOrParams;
9613 }
9614 return this._loadParams(params);
9615 }
9616 async loadJSON(tagId, pathConfigJson, index) {
9617 let url, id;
9618 if (isNumber(pathConfigJson) || pathConfigJson === undefined) {
9619 url = tagId;
9620 } else {
9621 id = tagId;
9622 url = pathConfigJson;
9623 }
9624 return this._loadParams({
9625 id: id,
9626 url,
9627 index
9628 });
9629 }
9630 async refresh(refresh = true) {
9631 if (!refresh) {
9632 return;
9633 }
9634 this.dom().forEach(t => t.refresh());
9635 }
9636 removeEventListener(type, listener) {
9637 this._eventDispatcher.removeEventListener(type, listener);
9638 }
9639 async set(id, element, options, index) {
9640 const params = {
9641 index
9642 };
9643 if (isString(id)) {
9644 params.id = id;
9645 } else {
9646 params.element = id;
9647 }
9648 if (element instanceof HTMLElement) {
9649 params.element = element;
9650 } else {
9651 params.options = element;
9652 }
9653 if (isNumber(options)) {
9654 params.index = options;
9655 } else {
9656 params.options = options ?? params.options;
9657 }
9658 return this._loadParams(params);
9659 }
9660 async setJSON(id, element, pathConfigJson, index) {
9661 const params = {};
9662 if (id instanceof HTMLElement) {
9663 params.element = id;
9664 params.url = element;
9665 params.index = pathConfigJson;
9666 } else {
9667 params.id = id;
9668 params.element = element;
9669 params.url = pathConfigJson;
9670 params.index = index;
9671 }
9672 return this._loadParams(params);
9673 }
9674 setOnClickHandler(callback) {
9675 const dom = this.dom();
9676 if (!dom.length) {
9677 throw new Error(`${errorPrefix} can only set click handlers after calling tsParticles.load()`);
9678 }
9679 for (const domItem of dom) {
9680 domItem.addClickHandler(callback);
9681 }
9682 }
9683 async _loadParams(params) {
9684 const id = params.id ?? `tsparticles${Math.floor(getRandom() * 10000)}`,
9685 {
9686 index,
9687 url
9688 } = params,
9689 options = url ? await getDataFromUrl({
9690 fallback: params.options,
9691 url,
9692 index
9693 }) : params.options;
9694 let domContainer = params.element ?? document.getElementById(id);
9695 if (!domContainer) {
9696 domContainer = document.createElement("div");
9697 domContainer.id = id;
9698 document.body.append(domContainer);
9699 }
9700 const currentOptions = itemFromSingleOrMultiple(options, index),
9701 dom = this.dom(),
9702 oldIndex = dom.findIndex(v => v.id === id);
9703 if (oldIndex >= 0) {
9704 const old = this.domItem(oldIndex);
9705 if (old && !old.destroyed) {
9706 old.destroy();
9707 dom.splice(oldIndex, 1);
9708 }
9709 }
9710 let canvasEl;
9711 if (domContainer.tagName.toLowerCase() === "canvas") {
9712 canvasEl = domContainer;
9713 canvasEl.dataset[generatedAttribute] = "false";
9714 } else {
9715 const existingCanvases = domContainer.getElementsByTagName("canvas");
9716 if (existingCanvases.length) {
9717 canvasEl = existingCanvases[0];
9718 canvasEl.dataset[generatedAttribute] = "false";
9719 } else {
9720 canvasEl = document.createElement("canvas");
9721 canvasEl.dataset[generatedAttribute] = "true";
9722 domContainer.appendChild(canvasEl);
9723 }
9724 }
9725 if (!canvasEl.style.width) {
9726 canvasEl.style.width = "100%";
9727 }
9728 if (!canvasEl.style.height) {
9729 canvasEl.style.height = "100%";
9730 }
9731 const newItem = new Container(this, id, currentOptions);
9732 if (oldIndex >= 0) {
9733 dom.splice(oldIndex, 0, newItem);
9734 } else {
9735 dom.push(newItem);
9736 }
9737 newItem.canvas.loadCanvas(canvasEl);
9738 await newItem.start();
9739 return newItem;
9740 }
9741}
9742;// CONCATENATED MODULE: ../../engine/dist/esm/Utils/HslColorManager.js
9743
9744
9745class HslColorManager {
9746 constructor() {
9747 this.key = "hsl";
9748 this.stringPrefix = "hsl";
9749 }
9750 handleColor(color) {
9751 const colorValue = color.value,
9752 hslColor = colorValue.hsl ?? color.value;
9753 if (hslColor.h !== undefined && hslColor.s !== undefined && hslColor.l !== undefined) {
9754 return hslToRgb(hslColor);
9755 }
9756 }
9757 handleRangeColor(color) {
9758 const colorValue = color.value,
9759 hslColor = colorValue.hsl ?? color.value;
9760 if (hslColor.h !== undefined && hslColor.l !== undefined) {
9761 return hslToRgb({
9762 h: getRangeValue(hslColor.h),
9763 l: getRangeValue(hslColor.l),
9764 s: getRangeValue(hslColor.s)
9765 });
9766 }
9767 }
9768 parseString(input) {
9769 if (!input.startsWith("hsl")) {
9770 return;
9771 }
9772 const regex = /hsla?\(\s*(\d+)\s*,\s*(\d+)%\s*,\s*(\d+)%\s*(,\s*([\d.%]+)\s*)?\)/i,
9773 result = regex.exec(input);
9774 return result ? hslaToRgba({
9775 a: result.length > 4 ? parseAlpha(result[5]) : 1,
9776 h: parseInt(result[1], 10),
9777 l: parseInt(result[3], 10),
9778 s: parseInt(result[2], 10)
9779 }) : undefined;
9780 }
9781}
9782;// CONCATENATED MODULE: ../../engine/dist/esm/Utils/RgbColorManager.js
9783
9784class RgbColorManager {
9785 constructor() {
9786 this.key = "rgb";
9787 this.stringPrefix = "rgb";
9788 }
9789 handleColor(color) {
9790 const colorValue = color.value,
9791 rgbColor = colorValue.rgb ?? color.value;
9792 if (rgbColor.r !== undefined) {
9793 return rgbColor;
9794 }
9795 }
9796 handleRangeColor(color) {
9797 const colorValue = color.value,
9798 rgbColor = colorValue.rgb ?? color.value;
9799 if (rgbColor.r !== undefined) {
9800 return {
9801 r: getRangeValue(rgbColor.r),
9802 g: getRangeValue(rgbColor.g),
9803 b: getRangeValue(rgbColor.b)
9804 };
9805 }
9806 }
9807 parseString(input) {
9808 if (!input.startsWith(this.stringPrefix)) {
9809 return;
9810 }
9811 const regex = /rgba?\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*(,\s*([\d.%]+)\s*)?\)/i,
9812 result = regex.exec(input);
9813 return result ? {
9814 a: result.length > 4 ? parseAlpha(result[5]) : 1,
9815 b: parseInt(result[3], 10),
9816 g: parseInt(result[2], 10),
9817 r: parseInt(result[1], 10)
9818 } : undefined;
9819 }
9820}
9821;// CONCATENATED MODULE: ../../engine/dist/esm/init.js
9822
9823
9824
9825
9826function init() {
9827 const rgbColorManager = new RgbColorManager(),
9828 hslColorManager = new HslColorManager();
9829 addColorManager(rgbColorManager);
9830 addColorManager(hslColorManager);
9831 const engine = new Engine();
9832 engine.init();
9833 return engine;
9834}
9835;// CONCATENATED MODULE: ../../engine/dist/esm/Core/Utils/ParticlesInteractorBase.js
9836class ParticlesInteractorBase {
9837 constructor(container) {
9838 this.container = container;
9839 this.type = "particles";
9840 }
9841}
9842;// CONCATENATED MODULE: ../../engine/dist/esm/exports.js
9843
9844
9845
9846
9847
9848
9849
9850
9851
9852
9853
9854
9855
9856
9857
9858
9859
9860
9861
9862
9863
9864
9865
9866
9867
9868
9869
9870
9871
9872
9873
9874
9875
9876
9877
9878
9879
9880
9881
9882
9883
9884
9885
9886
9887
9888
9889
9890
9891
9892
9893
9894
9895
9896
9897
9898
9899
9900
9901
9902
9903
9904
9905
9906
9907
9908
9909
9910
9911
9912
9913
9914
9915
9916
9917
9918
9919
9920
9921
9922
9923
9924
9925
9926
9927
9928
9929
9930
9931
9932;// CONCATENATED MODULE: ../../engine/dist/esm/index.js
9933
9934
9935const tsParticles = init();
9936if (!isSsr()) {
9937 window.tsParticles = tsParticles;
9938}
9939
9940
9941
9942;// CONCATENATED MODULE: ../pjs/dist/esm/marcbruederlin/Particles.js
9943
9944class Particles_Particles {
9945 static init(options) {
9946 const particles = new Particles_Particles(),
9947 selector = options.selector;
9948 if (!selector) {
9949 throw new Error("No selector provided");
9950 }
9951 const el = document.querySelector(selector);
9952 if (!el) {
9953 throw new Error("No element found for selector");
9954 }
9955 tsParticles.set(selector.replace(".", "").replace("!", ""), el, {
9956 fullScreen: {
9957 enable: false
9958 },
9959 particles: {
9960 color: {
9961 value: options.color ?? "!000000"
9962 },
9963 links: {
9964 color: "random",
9965 distance: options.minDistance ?? 120,
9966 enable: options.connectParticles ?? false
9967 },
9968 move: {
9969 enable: true,
9970 speed: options.speed ?? 0.5
9971 },
9972 number: {
9973 value: options.maxParticles ?? 100
9974 },
9975 size: {
9976 value: {
9977 min: 1,
9978 max: options.sizeVariations ?? 3
9979 }
9980 }
9981 },
9982 responsive: options.responsive?.map(responsive => ({
9983 maxWidth: responsive.breakpoint,
9984 options: {
9985 particles: {
9986 color: {
9987 value: responsive.options?.color
9988 },
9989 links: {
9990 distance: responsive.options?.minDistance,
9991 enable: responsive.options?.connectParticles
9992 },
9993 number: {
9994 value: options.maxParticles
9995 },
9996 move: {
9997 enable: true,
9998 speed: responsive.options?.speed
9999 },
10000 size: {
10001 value: responsive.options?.sizeVariations
10002 }
10003 }
10004 }
10005 }))
10006 }).then(container => {
10007 particles._container = container;
10008 });
10009 return particles;
10010 }
10011 destroy() {
10012 const container = this._container;
10013 container && container.destroy();
10014 }
10015 pauseAnimation() {
10016 const container = this._container;
10017 container && container.pause();
10018 }
10019 resumeAnimation() {
10020 const container = this._container;
10021 container && container.play();
10022 }
10023}
10024;// CONCATENATED MODULE: ../pjs/dist/esm/VincentGarreau/particles.js
10025const initParticlesJS = engine => {
10026 const particlesJS = (tagId, options) => {
10027 return engine.load(tagId, options);
10028 };
10029 particlesJS.load = (tagId, pathConfigJson, callback) => {
10030 engine.loadJSON(tagId, pathConfigJson).then(container => {
10031 if (container) {
10032 callback(container);
10033 }
10034 }).catch(() => {
10035 callback(undefined);
10036 });
10037 };
10038 particlesJS.setOnClickHandler = callback => {
10039 engine.setOnClickHandler(callback);
10040 };
10041 const pJSDom = engine.dom();
10042 return {
10043 particlesJS,
10044 pJSDom
10045 };
10046};
10047
10048;// CONCATENATED MODULE: ../pjs/dist/esm/index.js
10049
10050
10051const initPjs = engine => {
10052 const {
10053 particlesJS,
10054 pJSDom
10055 } = initParticlesJS(engine);
10056 window.particlesJS = particlesJS;
10057 window.pJSDom = pJSDom;
10058 window.Particles = Particles_Particles;
10059 return {
10060 particlesJS,
10061 pJSDom,
10062 Particles: Particles_Particles
10063 };
10064};
10065
10066;// CONCATENATED MODULE: ../../move/base/dist/esm/Utils.js
10067
10068function applyDistance(particle) {
10069 const initialPosition = particle.initialPosition,
10070 {
10071 dx,
10072 dy
10073 } = getDistances(initialPosition, particle.position),
10074 dxFixed = Math.abs(dx),
10075 dyFixed = Math.abs(dy),
10076 {
10077 maxDistance
10078 } = particle.retina,
10079 hDistance = maxDistance.horizontal,
10080 vDistance = maxDistance.vertical;
10081 if (!hDistance && !vDistance) {
10082 return;
10083 }
10084 if ((hDistance && dxFixed >= hDistance || vDistance && dyFixed >= vDistance) && !particle.misplaced) {
10085 particle.misplaced = !!hDistance && dxFixed > hDistance || !!vDistance && dyFixed > vDistance;
10086 if (hDistance) {
10087 particle.velocity.x = particle.velocity.y / 2 - particle.velocity.x;
10088 }
10089 if (vDistance) {
10090 particle.velocity.y = particle.velocity.x / 2 - particle.velocity.y;
10091 }
10092 } else if ((!hDistance || dxFixed < hDistance) && (!vDistance || dyFixed < vDistance) && particle.misplaced) {
10093 particle.misplaced = false;
10094 } else if (particle.misplaced) {
10095 const pos = particle.position,
10096 vel = particle.velocity;
10097 if (hDistance && (pos.x < initialPosition.x && vel.x < 0 || pos.x > initialPosition.x && vel.x > 0)) {
10098 vel.x *= -getRandom();
10099 }
10100 if (vDistance && (pos.y < initialPosition.y && vel.y < 0 || pos.y > initialPosition.y && vel.y > 0)) {
10101 vel.y *= -getRandom();
10102 }
10103 }
10104}
10105function move(particle, moveOptions, moveSpeed, maxSpeed, moveDrift, delta) {
10106 applyPath(particle, delta);
10107 const gravityOptions = particle.gravity,
10108 gravityFactor = gravityOptions?.enable && gravityOptions.inverse ? -1 : 1;
10109 if (moveDrift && moveSpeed) {
10110 particle.velocity.x += moveDrift * delta.factor / (60 * moveSpeed);
10111 }
10112 if (gravityOptions?.enable && moveSpeed) {
10113 particle.velocity.y += gravityFactor * (gravityOptions.acceleration * delta.factor) / (60 * moveSpeed);
10114 }
10115 const decay = particle.moveDecay;
10116 particle.velocity.multTo(decay);
10117 const velocity = particle.velocity.mult(moveSpeed);
10118 if (gravityOptions?.enable && maxSpeed > 0 && (!gravityOptions.inverse && velocity.y >= 0 && velocity.y >= maxSpeed || gravityOptions.inverse && velocity.y <= 0 && velocity.y <= -maxSpeed)) {
10119 velocity.y = gravityFactor * maxSpeed;
10120 if (moveSpeed) {
10121 particle.velocity.y = velocity.y / moveSpeed;
10122 }
10123 }
10124 const zIndexOptions = particle.options.zIndex,
10125 zVelocityFactor = (1 - particle.zIndexFactor) ** zIndexOptions.velocityRate;
10126 velocity.multTo(zVelocityFactor);
10127 const {
10128 position
10129 } = particle;
10130 position.addTo(velocity);
10131 if (moveOptions.vibrate) {
10132 position.x += Math.sin(position.x * Math.cos(position.y));
10133 position.y += Math.cos(position.y * Math.sin(position.x));
10134 }
10135}
10136function spin(particle, moveSpeed) {
10137 const container = particle.container;
10138 if (!particle.spin) {
10139 return;
10140 }
10141 const updateFunc = {
10142 x: particle.spin.direction === "clockwise" ? Math.cos : Math.sin,
10143 y: particle.spin.direction === "clockwise" ? Math.sin : Math.cos
10144 };
10145 particle.position.x = particle.spin.center.x + particle.spin.radius * updateFunc.x(particle.spin.angle);
10146 particle.position.y = particle.spin.center.y + particle.spin.radius * updateFunc.y(particle.spin.angle);
10147 particle.spin.radius += particle.spin.acceleration;
10148 const maxCanvasSize = Math.max(container.canvas.size.width, container.canvas.size.height);
10149 if (particle.spin.radius > maxCanvasSize / 2) {
10150 particle.spin.radius = maxCanvasSize / 2;
10151 particle.spin.acceleration *= -1;
10152 } else if (particle.spin.radius < 0) {
10153 particle.spin.radius = 0;
10154 particle.spin.acceleration *= -1;
10155 }
10156 particle.spin.angle += moveSpeed / 100 * (1 - particle.spin.radius / maxCanvasSize);
10157}
10158function applyPath(particle, delta) {
10159 const particlesOptions = particle.options,
10160 pathOptions = particlesOptions.move.path,
10161 pathEnabled = pathOptions.enable;
10162 if (!pathEnabled) {
10163 return;
10164 }
10165 if (particle.lastPathTime <= particle.pathDelay) {
10166 particle.lastPathTime += delta.value;
10167 return;
10168 }
10169 const path = particle.pathGenerator?.generate(particle, delta);
10170 if (path) {
10171 particle.velocity.addTo(path);
10172 }
10173 if (pathOptions.clamp) {
10174 particle.velocity.x = clamp(particle.velocity.x, -1, 1);
10175 particle.velocity.y = clamp(particle.velocity.y, -1, 1);
10176 }
10177 particle.lastPathTime -= particle.pathDelay;
10178}
10179function getProximitySpeedFactor(particle) {
10180 return particle.slow.inRange ? particle.slow.factor : 1;
10181}
10182;// CONCATENATED MODULE: ../../move/base/dist/esm/BaseMover.js
10183
10184
10185const diffFactor = 2;
10186class BaseMover {
10187 constructor() {
10188 this._initSpin = particle => {
10189 const container = particle.container,
10190 options = particle.options,
10191 spinOptions = options.move.spin;
10192 if (!spinOptions.enable) {
10193 return;
10194 }
10195 const spinPos = spinOptions.position ?? {
10196 x: 50,
10197 y: 50
10198 },
10199 spinCenter = {
10200 x: spinPos.x / 100 * container.canvas.size.width,
10201 y: spinPos.y / 100 * container.canvas.size.height
10202 },
10203 pos = particle.getPosition(),
10204 distance = getDistance(pos, spinCenter),
10205 spinAcceleration = getRangeValue(spinOptions.acceleration);
10206 particle.retina.spinAcceleration = spinAcceleration * container.retina.pixelRatio;
10207 particle.spin = {
10208 center: spinCenter,
10209 direction: particle.velocity.x >= 0 ? "clockwise" : "counter-clockwise",
10210 angle: particle.velocity.angle,
10211 radius: distance,
10212 acceleration: particle.retina.spinAcceleration
10213 };
10214 };
10215 }
10216 init(particle) {
10217 const options = particle.options,
10218 gravityOptions = options.move.gravity;
10219 particle.gravity = {
10220 enable: gravityOptions.enable,
10221 acceleration: getRangeValue(gravityOptions.acceleration),
10222 inverse: gravityOptions.inverse
10223 };
10224 this._initSpin(particle);
10225 }
10226 isEnabled(particle) {
10227 return !particle.destroyed && particle.options.move.enable;
10228 }
10229 move(particle, delta) {
10230 const particleOptions = particle.options,
10231 moveOptions = particleOptions.move;
10232 if (!moveOptions.enable) {
10233 return;
10234 }
10235 const container = particle.container,
10236 pxRatio = container.retina.pixelRatio,
10237 slowFactor = getProximitySpeedFactor(particle),
10238 baseSpeed = (particle.retina.moveSpeed ??= getRangeValue(moveOptions.speed) * pxRatio) * container.retina.reduceFactor,
10239 moveDrift = particle.retina.moveDrift ??= getRangeValue(particle.options.move.drift) * pxRatio,
10240 maxSize = getRangeMax(particleOptions.size.value) * pxRatio,
10241 sizeFactor = moveOptions.size ? particle.getRadius() / maxSize : 1,
10242 moveSpeed = baseSpeed * sizeFactor * slowFactor * (delta.factor || 1) / diffFactor,
10243 maxSpeed = particle.retina.maxSpeed ?? container.retina.maxSpeed;
10244 if (moveOptions.spin.enable) {
10245 spin(particle, moveSpeed);
10246 } else {
10247 move(particle, moveOptions, moveSpeed, maxSpeed, moveDrift, delta);
10248 }
10249 applyDistance(particle);
10250 }
10251}
10252;// CONCATENATED MODULE: ../../move/base/dist/esm/index.js
10253
10254async function loadBaseMover(engine, refresh = true) {
10255 await engine.addMover("base", () => new BaseMover(), refresh);
10256}
10257;// CONCATENATED MODULE: ../../shapes/circle/dist/esm/CircleDrawer.js
10258
10259class CircleDrawer {
10260 draw(context, particle, radius) {
10261 if (!particle.circleRange) {
10262 particle.circleRange = {
10263 min: 0,
10264 max: Math.PI * 2
10265 };
10266 }
10267 const circleRange = particle.circleRange;
10268 context.arc(0, 0, radius, circleRange.min, circleRange.max, false);
10269 }
10270 getSidesCount() {
10271 return 12;
10272 }
10273 particleInit(container, particle) {
10274 const shapeData = particle.shapeData,
10275 angle = shapeData?.angle ?? {
10276 max: 360,
10277 min: 0
10278 };
10279 particle.circleRange = !isObject(angle) ? {
10280 min: 0,
10281 max: angle * Math.PI / 180
10282 } : {
10283 min: angle.min * Math.PI / 180,
10284 max: angle.max * Math.PI / 180
10285 };
10286 }
10287}
10288;// CONCATENATED MODULE: ../../shapes/circle/dist/esm/index.js
10289
10290async function loadCircleShape(engine, refresh = true) {
10291 await engine.addShape("circle", new CircleDrawer(), refresh);
10292}
10293;// CONCATENATED MODULE: ../../updaters/color/dist/esm/Utils.js
10294
10295function updateColorValue(delta, colorValue, valueAnimation, max, decrease) {
10296 if (!colorValue || !valueAnimation.enable || (colorValue.maxLoops ?? 0) > 0 && (colorValue.loops ?? 0) > (colorValue.maxLoops ?? 0)) {
10297 return;
10298 }
10299 if (!colorValue.time) {
10300 colorValue.time = 0;
10301 }
10302 if ((colorValue.delayTime ?? 0) > 0 && colorValue.time < (colorValue.delayTime ?? 0)) {
10303 colorValue.time += delta.value;
10304 }
10305 if ((colorValue.delayTime ?? 0) > 0 && colorValue.time < (colorValue.delayTime ?? 0)) {
10306 return;
10307 }
10308 const offset = randomInRange(valueAnimation.offset),
10309 velocity = (colorValue.velocity ?? 0) * delta.factor + offset * 3.6,
10310 decay = colorValue.decay ?? 1;
10311 if (!decrease || colorValue.status === "increasing") {
10312 colorValue.value += velocity;
10313 if (colorValue.value > max) {
10314 if (!colorValue.loops) {
10315 colorValue.loops = 0;
10316 }
10317 colorValue.loops++;
10318 if (decrease) {
10319 colorValue.status = "decreasing";
10320 colorValue.value -= colorValue.value % max;
10321 }
10322 }
10323 } else {
10324 colorValue.value -= velocity;
10325 if (colorValue.value < 0) {
10326 if (!colorValue.loops) {
10327 colorValue.loops = 0;
10328 }
10329 colorValue.loops++;
10330 colorValue.status = "increasing";
10331 colorValue.value += colorValue.value;
10332 }
10333 }
10334 if (colorValue.velocity && decay !== 1) {
10335 colorValue.velocity *= decay;
10336 }
10337 if (colorValue.value > max) {
10338 colorValue.value %= max;
10339 }
10340}
10341function updateColor(particle, delta) {
10342 const {
10343 h: hAnimation,
10344 s: sAnimation,
10345 l: lAnimation
10346 } = particle.options.color.animation,
10347 {
10348 color
10349 } = particle;
10350 if (!color) {
10351 return;
10352 }
10353 const {
10354 h,
10355 s,
10356 l
10357 } = color;
10358 if (h) {
10359 updateColorValue(delta, h, hAnimation, 360, false);
10360 }
10361 if (s) {
10362 updateColorValue(delta, s, sAnimation, 100, true);
10363 }
10364 if (l) {
10365 updateColorValue(delta, l, lAnimation, 100, true);
10366 }
10367}
10368;// CONCATENATED MODULE: ../../updaters/color/dist/esm/ColorUpdater.js
10369
10370
10371class ColorUpdater {
10372 constructor(container) {
10373 this.container = container;
10374 }
10375 init(particle) {
10376 const hslColor = rangeColorToHsl(particle.options.color, particle.id, particle.options.reduceDuplicates);
10377 if (hslColor) {
10378 particle.color = getHslAnimationFromHsl(hslColor, particle.options.color.animation, this.container.retina.reduceFactor);
10379 }
10380 }
10381 isEnabled(particle) {
10382 const {
10383 h: hAnimation,
10384 s: sAnimation,
10385 l: lAnimation
10386 } = particle.options.color.animation,
10387 {
10388 color
10389 } = particle;
10390 return !particle.destroyed && !particle.spawning && (color?.h.value !== undefined && hAnimation.enable || color?.s.value !== undefined && sAnimation.enable || color?.l.value !== undefined && lAnimation.enable);
10391 }
10392 update(particle, delta) {
10393 updateColor(particle, delta);
10394 }
10395}
10396;// CONCATENATED MODULE: ../../updaters/color/dist/esm/index.js
10397
10398async function loadColorUpdater(engine, refresh = true) {
10399 await engine.addParticleUpdater("color", container => new ColorUpdater(container), refresh);
10400}
10401;// CONCATENATED MODULE: ../../updaters/opacity/dist/esm/Utils.js
10402
10403function checkDestroy(particle, value, minValue, maxValue) {
10404 switch (particle.options.opacity.animation.destroy) {
10405 case "max":
10406 if (value >= maxValue) {
10407 particle.destroy();
10408 }
10409 break;
10410 case "min":
10411 if (value <= minValue) {
10412 particle.destroy();
10413 }
10414 break;
10415 }
10416}
10417function updateOpacity(particle, delta) {
10418 const data = particle.opacity;
10419 if (particle.destroyed || !data?.enable || (data.maxLoops ?? 0) > 0 && (data.loops ?? 0) > (data.maxLoops ?? 0)) {
10420 return;
10421 }
10422 const minValue = data.min,
10423 maxValue = data.max,
10424 decay = data.decay ?? 1;
10425 if (!data.time) {
10426 data.time = 0;
10427 }
10428 if ((data.delayTime ?? 0) > 0 && data.time < (data.delayTime ?? 0)) {
10429 data.time += delta.value;
10430 }
10431 if ((data.delayTime ?? 0) > 0 && data.time < (data.delayTime ?? 0)) {
10432 return;
10433 }
10434 switch (data.status) {
10435 case "increasing":
10436 if (data.value >= maxValue) {
10437 data.status = "decreasing";
10438 if (!data.loops) {
10439 data.loops = 0;
10440 }
10441 data.loops++;
10442 } else {
10443 data.value += (data.velocity ?? 0) * delta.factor;
10444 }
10445 break;
10446 case "decreasing":
10447 if (data.value <= minValue) {
10448 data.status = "increasing";
10449 if (!data.loops) {
10450 data.loops = 0;
10451 }
10452 data.loops++;
10453 } else {
10454 data.value -= (data.velocity ?? 0) * delta.factor;
10455 }
10456 break;
10457 }
10458 if (data.velocity && data.decay !== 1) {
10459 data.velocity *= decay;
10460 }
10461 checkDestroy(particle, data.value, minValue, maxValue);
10462 if (!particle.destroyed) {
10463 data.value = clamp(data.value, minValue, maxValue);
10464 }
10465}
10466;// CONCATENATED MODULE: ../../updaters/opacity/dist/esm/OpacityUpdater.js
10467
10468
10469class OpacityUpdater {
10470 constructor(container) {
10471 this.container = container;
10472 }
10473 init(particle) {
10474 const opacityOptions = particle.options.opacity;
10475 particle.opacity = initParticleNumericAnimationValue(opacityOptions, 1);
10476 const opacityAnimation = opacityOptions.animation;
10477 if (opacityAnimation.enable) {
10478 particle.opacity.velocity = getRangeValue(opacityAnimation.speed) / 100 * this.container.retina.reduceFactor;
10479 if (!opacityAnimation.sync) {
10480 particle.opacity.velocity *= getRandom();
10481 }
10482 }
10483 }
10484 isEnabled(particle) {
10485 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));
10486 }
10487 reset(particle) {
10488 if (particle.opacity) {
10489 particle.opacity.time = 0;
10490 particle.opacity.loops = 0;
10491 }
10492 }
10493 update(particle, delta) {
10494 if (!this.isEnabled(particle)) {
10495 return;
10496 }
10497 updateOpacity(particle, delta);
10498 }
10499}
10500;// CONCATENATED MODULE: ../../updaters/opacity/dist/esm/index.js
10501
10502async function loadOpacityUpdater(engine, refresh = true) {
10503 await engine.addParticleUpdater("opacity", container => new OpacityUpdater(container), refresh);
10504}
10505;// CONCATENATED MODULE: ../../updaters/outModes/dist/esm/Utils.js
10506
10507function bounceHorizontal(data) {
10508 if (data.outMode !== "bounce" && data.outMode !== "bounce-horizontal" && data.outMode !== "bounceHorizontal" && data.outMode !== "split" || data.direction !== "left" && data.direction !== "right") {
10509 return;
10510 }
10511 if (data.bounds.right < 0 && data.direction === "left") {
10512 data.particle.position.x = data.size + data.offset.x;
10513 } else if (data.bounds.left > data.canvasSize.width && data.direction === "right") {
10514 data.particle.position.x = data.canvasSize.width - data.size - data.offset.x;
10515 }
10516 const velocity = data.particle.velocity.x;
10517 let bounced = false;
10518 if (data.direction === "right" && data.bounds.right >= data.canvasSize.width && velocity > 0 || data.direction === "left" && data.bounds.left <= 0 && velocity < 0) {
10519 const newVelocity = getValue(data.particle.options.bounce.horizontal);
10520 data.particle.velocity.x *= -newVelocity;
10521 bounced = true;
10522 }
10523 if (!bounced) {
10524 return;
10525 }
10526 const minPos = data.offset.x + data.size;
10527 if (data.bounds.right >= data.canvasSize.width && data.direction === "right") {
10528 data.particle.position.x = data.canvasSize.width - minPos;
10529 } else if (data.bounds.left <= 0 && data.direction === "left") {
10530 data.particle.position.x = minPos;
10531 }
10532 if (data.outMode === "split") {
10533 data.particle.destroy();
10534 }
10535}
10536function bounceVertical(data) {
10537 if (data.outMode !== "bounce" && data.outMode !== "bounce-vertical" && data.outMode !== "bounceVertical" && data.outMode !== "split" || data.direction !== "bottom" && data.direction !== "top") {
10538 return;
10539 }
10540 if (data.bounds.bottom < 0 && data.direction === "top") {
10541 data.particle.position.y = data.size + data.offset.y;
10542 } else if (data.bounds.top > data.canvasSize.height && data.direction === "bottom") {
10543 data.particle.position.y = data.canvasSize.height - data.size - data.offset.y;
10544 }
10545 const velocity = data.particle.velocity.y;
10546 let bounced = false;
10547 if (data.direction === "bottom" && data.bounds.bottom >= data.canvasSize.height && velocity > 0 || data.direction === "top" && data.bounds.top <= 0 && velocity < 0) {
10548 const newVelocity = getValue(data.particle.options.bounce.vertical);
10549 data.particle.velocity.y *= -newVelocity;
10550 bounced = true;
10551 }
10552 if (!bounced) {
10553 return;
10554 }
10555 const minPos = data.offset.y + data.size;
10556 if (data.bounds.bottom >= data.canvasSize.height && data.direction === "bottom") {
10557 data.particle.position.y = data.canvasSize.height - minPos;
10558 } else if (data.bounds.top <= 0 && data.direction === "top") {
10559 data.particle.position.y = minPos;
10560 }
10561 if (data.outMode === "split") {
10562 data.particle.destroy();
10563 }
10564}
10565;// CONCATENATED MODULE: ../../updaters/outModes/dist/esm/BounceOutMode.js
10566
10567
10568class BounceOutMode {
10569 constructor(container) {
10570 this.container = container;
10571 this.modes = ["bounce", "bounce-vertical", "bounce-horizontal", "bounceVertical", "bounceHorizontal", "split"];
10572 }
10573 update(particle, direction, delta, outMode) {
10574 if (!this.modes.includes(outMode)) {
10575 return;
10576 }
10577 const container = this.container;
10578 let handled = false;
10579 for (const [, plugin] of container.plugins) {
10580 if (plugin.particleBounce !== undefined) {
10581 handled = plugin.particleBounce(particle, delta, direction);
10582 }
10583 if (handled) {
10584 break;
10585 }
10586 }
10587 if (handled) {
10588 return;
10589 }
10590 const pos = particle.getPosition(),
10591 offset = particle.offset,
10592 size = particle.getRadius(),
10593 bounds = calculateBounds(pos, size),
10594 canvasSize = container.canvas.size;
10595 bounceHorizontal({
10596 particle,
10597 outMode,
10598 direction,
10599 bounds,
10600 canvasSize,
10601 offset,
10602 size
10603 });
10604 bounceVertical({
10605 particle,
10606 outMode,
10607 direction,
10608 bounds,
10609 canvasSize,
10610 offset,
10611 size
10612 });
10613 }
10614}
10615;// CONCATENATED MODULE: ../../updaters/outModes/dist/esm/DestroyOutMode.js
10616
10617class DestroyOutMode {
10618 constructor(container) {
10619 this.container = container;
10620 this.modes = ["destroy"];
10621 }
10622 update(particle, direction, _delta, outMode) {
10623 if (!this.modes.includes(outMode)) {
10624 return;
10625 }
10626 const container = this.container;
10627 switch (particle.outType) {
10628 case "normal":
10629 case "outside":
10630 if (isPointInside(particle.position, container.canvas.size, Vector.origin, particle.getRadius(), direction)) {
10631 return;
10632 }
10633 break;
10634 case "inside":
10635 {
10636 const {
10637 dx,
10638 dy
10639 } = getDistances(particle.position, particle.moveCenter);
10640 const {
10641 x: vx,
10642 y: vy
10643 } = particle.velocity;
10644 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) {
10645 return;
10646 }
10647 break;
10648 }
10649 }
10650 container.particles.remove(particle, undefined, true);
10651 }
10652}
10653;// CONCATENATED MODULE: ../../updaters/outModes/dist/esm/NoneOutMode.js
10654
10655class NoneOutMode {
10656 constructor(container) {
10657 this.container = container;
10658 this.modes = ["none"];
10659 }
10660 update(particle, direction, delta, outMode) {
10661 if (!this.modes.includes(outMode)) {
10662 return;
10663 }
10664 if (particle.options.move.distance.horizontal && (direction === "left" || direction === "right") || particle.options.move.distance.vertical && (direction === "top" || direction === "bottom")) {
10665 return;
10666 }
10667 const gravityOptions = particle.options.move.gravity,
10668 container = this.container;
10669 const canvasSize = container.canvas.size;
10670 const pRadius = particle.getRadius();
10671 if (!gravityOptions.enable) {
10672 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) {
10673 return;
10674 }
10675 if (!isPointInside(particle.position, container.canvas.size, Vector.origin, pRadius, direction)) {
10676 container.particles.remove(particle);
10677 }
10678 } else {
10679 const position = particle.position;
10680 if (!gravityOptions.inverse && position.y > canvasSize.height + pRadius && direction === "bottom" || gravityOptions.inverse && position.y < -pRadius && direction === "top") {
10681 container.particles.remove(particle);
10682 }
10683 }
10684 }
10685}
10686;// CONCATENATED MODULE: ../../updaters/outModes/dist/esm/OutOutMode.js
10687
10688class OutOutMode {
10689 constructor(container) {
10690 this.container = container;
10691 this.modes = ["out"];
10692 }
10693 update(particle, direction, delta, outMode) {
10694 if (!this.modes.includes(outMode)) {
10695 return;
10696 }
10697 const container = this.container;
10698 switch (particle.outType) {
10699 case "inside":
10700 {
10701 const {
10702 x: vx,
10703 y: vy
10704 } = particle.velocity;
10705 const circVec = Vector.origin;
10706 circVec.length = particle.moveCenter.radius;
10707 circVec.angle = particle.velocity.angle + Math.PI;
10708 circVec.addTo(Vector.create(particle.moveCenter));
10709 const {
10710 dx,
10711 dy
10712 } = getDistances(particle.position, circVec);
10713 if (vx <= 0 && dx >= 0 || vy <= 0 && dy >= 0 || vx >= 0 && dx <= 0 || vy >= 0 && dy <= 0) {
10714 return;
10715 }
10716 particle.position.x = Math.floor(randomInRange({
10717 min: 0,
10718 max: container.canvas.size.width
10719 }));
10720 particle.position.y = Math.floor(randomInRange({
10721 min: 0,
10722 max: container.canvas.size.height
10723 }));
10724 const {
10725 dx: newDx,
10726 dy: newDy
10727 } = getDistances(particle.position, particle.moveCenter);
10728 particle.direction = Math.atan2(-newDy, -newDx);
10729 particle.velocity.angle = particle.direction;
10730 break;
10731 }
10732 default:
10733 {
10734 if (isPointInside(particle.position, container.canvas.size, Vector.origin, particle.getRadius(), direction)) {
10735 return;
10736 }
10737 switch (particle.outType) {
10738 case "outside":
10739 {
10740 particle.position.x = Math.floor(randomInRange({
10741 min: -particle.moveCenter.radius,
10742 max: particle.moveCenter.radius
10743 })) + particle.moveCenter.x;
10744 particle.position.y = Math.floor(randomInRange({
10745 min: -particle.moveCenter.radius,
10746 max: particle.moveCenter.radius
10747 })) + particle.moveCenter.y;
10748 const {
10749 dx,
10750 dy
10751 } = getDistances(particle.position, particle.moveCenter);
10752 if (particle.moveCenter.radius) {
10753 particle.direction = Math.atan2(dy, dx);
10754 particle.velocity.angle = particle.direction;
10755 }
10756 break;
10757 }
10758 case "normal":
10759 {
10760 const wrap = particle.options.move.warp,
10761 canvasSize = container.canvas.size,
10762 newPos = {
10763 bottom: canvasSize.height + particle.getRadius() + particle.offset.y,
10764 left: -particle.getRadius() - particle.offset.x,
10765 right: canvasSize.width + particle.getRadius() + particle.offset.x,
10766 top: -particle.getRadius() - particle.offset.y
10767 },
10768 sizeValue = particle.getRadius(),
10769 nextBounds = calculateBounds(particle.position, sizeValue);
10770 if (direction === "right" && nextBounds.left > canvasSize.width + particle.offset.x) {
10771 particle.position.x = newPos.left;
10772 particle.initialPosition.x = particle.position.x;
10773 if (!wrap) {
10774 particle.position.y = getRandom() * canvasSize.height;
10775 particle.initialPosition.y = particle.position.y;
10776 }
10777 } else if (direction === "left" && nextBounds.right < -particle.offset.x) {
10778 particle.position.x = newPos.right;
10779 particle.initialPosition.x = particle.position.x;
10780 if (!wrap) {
10781 particle.position.y = getRandom() * canvasSize.height;
10782 particle.initialPosition.y = particle.position.y;
10783 }
10784 }
10785 if (direction === "bottom" && nextBounds.top > canvasSize.height + particle.offset.y) {
10786 if (!wrap) {
10787 particle.position.x = getRandom() * canvasSize.width;
10788 particle.initialPosition.x = particle.position.x;
10789 }
10790 particle.position.y = newPos.top;
10791 particle.initialPosition.y = particle.position.y;
10792 } else if (direction === "top" && nextBounds.bottom < -particle.offset.y) {
10793 if (!wrap) {
10794 particle.position.x = getRandom() * canvasSize.width;
10795 particle.initialPosition.x = particle.position.x;
10796 }
10797 particle.position.y = newPos.bottom;
10798 particle.initialPosition.y = particle.position.y;
10799 }
10800 break;
10801 }
10802 }
10803 break;
10804 }
10805 }
10806 }
10807}
10808;// CONCATENATED MODULE: ../../updaters/outModes/dist/esm/OutOfCanvasUpdater.js
10809
10810
10811
10812
10813class OutOfCanvasUpdater {
10814 constructor(container) {
10815 this.container = container;
10816 this._updateOutMode = (particle, delta, outMode, direction) => {
10817 for (const updater of this.updaters) {
10818 updater.update(particle, direction, delta, outMode);
10819 }
10820 };
10821 this.updaters = [new BounceOutMode(container), new DestroyOutMode(container), new OutOutMode(container), new NoneOutMode(container)];
10822 }
10823 init() {}
10824 isEnabled(particle) {
10825 return !particle.destroyed && !particle.spawning;
10826 }
10827 update(particle, delta) {
10828 const outModes = particle.options.move.outModes;
10829 this._updateOutMode(particle, delta, outModes.bottom ?? outModes.default, "bottom");
10830 this._updateOutMode(particle, delta, outModes.left ?? outModes.default, "left");
10831 this._updateOutMode(particle, delta, outModes.right ?? outModes.default, "right");
10832 this._updateOutMode(particle, delta, outModes.top ?? outModes.default, "top");
10833 }
10834}
10835;// CONCATENATED MODULE: ../../updaters/outModes/dist/esm/index.js
10836
10837async function loadOutModesUpdater(engine, refresh = true) {
10838 await engine.addParticleUpdater("outModes", container => new OutOfCanvasUpdater(container), refresh);
10839}
10840;// CONCATENATED MODULE: ../../updaters/size/dist/esm/Utils.js
10841
10842function Utils_checkDestroy(particle, value, minValue, maxValue) {
10843 switch (particle.options.size.animation.destroy) {
10844 case "max":
10845 if (value >= maxValue) {
10846 particle.destroy();
10847 }
10848 break;
10849 case "min":
10850 if (value <= minValue) {
10851 particle.destroy();
10852 }
10853 break;
10854 }
10855}
10856function updateSize(particle, delta) {
10857 const data = particle.size;
10858 if (particle.destroyed || !data || !data.enable || (data.maxLoops ?? 0) > 0 && (data.loops ?? 0) > (data.maxLoops ?? 0)) {
10859 return;
10860 }
10861 const sizeVelocity = (data.velocity ?? 0) * delta.factor,
10862 minValue = data.min,
10863 maxValue = data.max,
10864 decay = data.decay ?? 1;
10865 if (!data.time) {
10866 data.time = 0;
10867 }
10868 if ((data.delayTime ?? 0) > 0 && data.time < (data.delayTime ?? 0)) {
10869 data.time += delta.value;
10870 }
10871 if ((data.delayTime ?? 0) > 0 && data.time < (data.delayTime ?? 0)) {
10872 return;
10873 }
10874 switch (data.status) {
10875 case "increasing":
10876 if (data.value >= maxValue) {
10877 data.status = "decreasing";
10878 if (!data.loops) {
10879 data.loops = 0;
10880 }
10881 data.loops++;
10882 } else {
10883 data.value += sizeVelocity;
10884 }
10885 break;
10886 case "decreasing":
10887 if (data.value <= minValue) {
10888 data.status = "increasing";
10889 if (!data.loops) {
10890 data.loops = 0;
10891 }
10892 data.loops++;
10893 } else {
10894 data.value -= sizeVelocity;
10895 }
10896 }
10897 if (data.velocity && decay !== 1) {
10898 data.velocity *= decay;
10899 }
10900 Utils_checkDestroy(particle, data.value, minValue, maxValue);
10901 if (!particle.destroyed) {
10902 data.value = clamp(data.value, minValue, maxValue);
10903 }
10904}
10905;// CONCATENATED MODULE: ../../updaters/size/dist/esm/SizeUpdater.js
10906
10907
10908class SizeUpdater {
10909 init(particle) {
10910 const container = particle.container,
10911 sizeOptions = particle.options.size,
10912 sizeAnimation = sizeOptions.animation;
10913 if (sizeAnimation.enable) {
10914 particle.size.velocity = (particle.retina.sizeAnimationSpeed ?? container.retina.sizeAnimationSpeed) / 100 * container.retina.reduceFactor;
10915 if (!sizeAnimation.sync) {
10916 particle.size.velocity *= getRandom();
10917 }
10918 }
10919 }
10920 isEnabled(particle) {
10921 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));
10922 }
10923 reset(particle) {
10924 particle.size.loops = 0;
10925 }
10926 update(particle, delta) {
10927 if (!this.isEnabled(particle)) {
10928 return;
10929 }
10930 updateSize(particle, delta);
10931 }
10932}
10933;// CONCATENATED MODULE: ../../updaters/size/dist/esm/index.js
10934
10935async function loadSizeUpdater(engine, refresh = true) {
10936 await engine.addParticleUpdater("size", () => new SizeUpdater(), refresh);
10937}
10938;// CONCATENATED MODULE: ../basic/dist/esm/index.js
10939
10940
10941
10942
10943
10944
10945async function loadBasic(engine, refresh = true) {
10946 await loadBaseMover(engine, false);
10947 await loadCircleShape(engine, false);
10948 await loadColorUpdater(engine, false);
10949 await loadOpacityUpdater(engine, false);
10950 await loadOutModesUpdater(engine, false);
10951 await loadSizeUpdater(engine, false);
10952 await engine.refresh(refresh);
10953}
10954;// CONCATENATED MODULE: ../../plugins/easings/quad/dist/esm/index.js
10955
10956async function loadEasingQuadPlugin() {
10957 addEasing("ease-in-quad", value => value ** 2);
10958 addEasing("ease-out-quad", value => 1 - (1 - value) ** 2);
10959 addEasing("ease-in-out-quad", value => value < 0.5 ? 2 * value ** 2 : 1 - (-2 * value + 2) ** 2 / 2);
10960}
10961;// CONCATENATED MODULE: ../../interactions/external/attract/dist/esm/Options/Classes/Attract.js
10962class Attract {
10963 constructor() {
10964 this.distance = 200;
10965 this.duration = 0.4;
10966 this.easing = "ease-out-quad";
10967 this.factor = 1;
10968 this.maxSpeed = 50;
10969 this.speed = 1;
10970 }
10971 load(data) {
10972 if (!data) {
10973 return;
10974 }
10975 if (data.distance !== undefined) {
10976 this.distance = data.distance;
10977 }
10978 if (data.duration !== undefined) {
10979 this.duration = data.duration;
10980 }
10981 if (data.easing !== undefined) {
10982 this.easing = data.easing;
10983 }
10984 if (data.factor !== undefined) {
10985 this.factor = data.factor;
10986 }
10987 if (data.maxSpeed !== undefined) {
10988 this.maxSpeed = data.maxSpeed;
10989 }
10990 if (data.speed !== undefined) {
10991 this.speed = data.speed;
10992 }
10993 }
10994}
10995;// CONCATENATED MODULE: ../../interactions/external/attract/dist/esm/Attractor.js
10996
10997
10998class Attractor extends ExternalInteractorBase {
10999 constructor(engine, container) {
11000 super(container);
11001 this._clickAttract = () => {
11002 const container = this.container;
11003 if (!container.attract) {
11004 container.attract = {
11005 particles: []
11006 };
11007 }
11008 const {
11009 attract
11010 } = container;
11011 if (!attract.finish) {
11012 if (!attract.count) {
11013 attract.count = 0;
11014 }
11015 attract.count++;
11016 if (attract.count === container.particles.count) {
11017 attract.finish = true;
11018 }
11019 }
11020 if (attract.clicking) {
11021 const mousePos = container.interactivity.mouse.clickPosition,
11022 attractRadius = container.retina.attractModeDistance;
11023 if (!attractRadius || attractRadius < 0 || !mousePos) {
11024 return;
11025 }
11026 this._processAttract(mousePos, attractRadius, new Circle(mousePos.x, mousePos.y, attractRadius));
11027 } else if (attract.clicking === false) {
11028 attract.particles = [];
11029 }
11030 return;
11031 };
11032 this._hoverAttract = () => {
11033 const container = this.container,
11034 mousePos = container.interactivity.mouse.position,
11035 attractRadius = container.retina.attractModeDistance;
11036 if (!attractRadius || attractRadius < 0 || !mousePos) {
11037 return;
11038 }
11039 this._processAttract(mousePos, attractRadius, new Circle(mousePos.x, mousePos.y, attractRadius));
11040 };
11041 this._processAttract = (position, attractRadius, area) => {
11042 const container = this.container,
11043 attractOptions = container.actualOptions.interactivity.modes.attract;
11044 if (!attractOptions) {
11045 return;
11046 }
11047 const query = container.particles.quadTree.query(area, p => this.isEnabled(p));
11048 for (const particle of query) {
11049 const {
11050 dx,
11051 dy,
11052 distance
11053 } = getDistances(particle.position, position);
11054 const velocity = attractOptions.speed * attractOptions.factor;
11055 const attractFactor = clamp(getEasing(attractOptions.easing)(1 - distance / attractRadius) * velocity, 0, attractOptions.maxSpeed);
11056 const normVec = Vector.create(distance === 0 ? velocity : dx / distance * attractFactor, distance === 0 ? velocity : dy / distance * attractFactor);
11057 particle.position.subFrom(normVec);
11058 }
11059 };
11060 this._engine = engine;
11061 if (!container.attract) {
11062 container.attract = {
11063 particles: []
11064 };
11065 }
11066 this.handleClickMode = mode => {
11067 const options = this.container.actualOptions,
11068 attract = options.interactivity.modes.attract;
11069 if (!attract || mode !== "attract") {
11070 return;
11071 }
11072 if (!container.attract) {
11073 container.attract = {
11074 particles: []
11075 };
11076 }
11077 container.attract.clicking = true;
11078 container.attract.count = 0;
11079 for (const particle of container.attract.particles) {
11080 if (!this.isEnabled(particle)) {
11081 continue;
11082 }
11083 particle.velocity.setTo(particle.initialVelocity);
11084 }
11085 container.attract.particles = [];
11086 container.attract.finish = false;
11087 setTimeout(() => {
11088 if (container.destroyed) {
11089 return;
11090 }
11091 if (!container.attract) {
11092 container.attract = {
11093 particles: []
11094 };
11095 }
11096 container.attract.clicking = false;
11097 }, attract.duration * 1000);
11098 };
11099 }
11100 clear() {}
11101 init() {
11102 const container = this.container,
11103 attract = container.actualOptions.interactivity.modes.attract;
11104 if (!attract) {
11105 return;
11106 }
11107 container.retina.attractModeDistance = attract.distance * container.retina.pixelRatio;
11108 }
11109 async interact() {
11110 const container = this.container,
11111 options = container.actualOptions,
11112 mouseMoveStatus = container.interactivity.status === mouseMoveEvent,
11113 events = options.interactivity.events,
11114 hoverEnabled = events.onHover.enable,
11115 hoverMode = events.onHover.mode,
11116 clickEnabled = events.onClick.enable,
11117 clickMode = events.onClick.mode;
11118 if (mouseMoveStatus && hoverEnabled && isInArray("attract", hoverMode)) {
11119 this._hoverAttract();
11120 } else if (clickEnabled && isInArray("attract", clickMode)) {
11121 this._clickAttract();
11122 }
11123 }
11124 isEnabled(particle) {
11125 const container = this.container,
11126 options = container.actualOptions,
11127 mouse = container.interactivity.mouse,
11128 events = (particle?.interactivity ?? options.interactivity).events;
11129 if ((!mouse.position || !events.onHover.enable) && (!mouse.clickPosition || !events.onClick.enable)) {
11130 return false;
11131 }
11132 const hoverMode = events.onHover.mode,
11133 clickMode = events.onClick.mode;
11134 return isInArray("attract", hoverMode) || isInArray("attract", clickMode);
11135 }
11136 loadModeOptions(options, ...sources) {
11137 if (!options.attract) {
11138 options.attract = new Attract();
11139 }
11140 for (const source of sources) {
11141 options.attract.load(source?.attract);
11142 }
11143 }
11144 reset() {}
11145}
11146;// CONCATENATED MODULE: ../../interactions/external/attract/dist/esm/index.js
11147
11148async function loadExternalAttractInteraction(engine, refresh = true) {
11149 await engine.addInteractor("externalAttract", container => new Attractor(engine, container), refresh);
11150}
11151
11152
11153;// CONCATENATED MODULE: ../../interactions/external/bounce/dist/esm/Options/Classes/Bounce.js
11154class Bounce {
11155 constructor() {
11156 this.distance = 200;
11157 }
11158 load(data) {
11159 if (!data) {
11160 return;
11161 }
11162 if (data.distance !== undefined) {
11163 this.distance = data.distance;
11164 }
11165 }
11166}
11167;// CONCATENATED MODULE: ../../interactions/external/bounce/dist/esm/Bouncer.js
11168
11169
11170class Bouncer extends ExternalInteractorBase {
11171 constructor(container) {
11172 super(container);
11173 this._processBounce = (position, radius, area) => {
11174 const query = this.container.particles.quadTree.query(area, p => this.isEnabled(p));
11175 for (const particle of query) {
11176 if (area instanceof Circle) {
11177 circleBounce(circleBounceDataFromParticle(particle), {
11178 position,
11179 radius,
11180 mass: radius ** 2 * Math.PI / 2,
11181 velocity: Vector.origin,
11182 factor: Vector.origin
11183 });
11184 } else if (area instanceof Rectangle) {
11185 rectBounce(particle, calculateBounds(position, radius));
11186 }
11187 }
11188 };
11189 this._processMouseBounce = () => {
11190 const container = this.container,
11191 pxRatio = container.retina.pixelRatio,
11192 tolerance = 10 * pxRatio,
11193 mousePos = container.interactivity.mouse.position,
11194 radius = container.retina.bounceModeDistance;
11195 if (!radius || radius < 0 || !mousePos) {
11196 return;
11197 }
11198 this._processBounce(mousePos, radius, new Circle(mousePos.x, mousePos.y, radius + tolerance));
11199 };
11200 this._singleSelectorBounce = (selector, div) => {
11201 const container = this.container,
11202 query = document.querySelectorAll(selector);
11203 if (!query.length) {
11204 return;
11205 }
11206 query.forEach(item => {
11207 const elem = item,
11208 pxRatio = container.retina.pixelRatio,
11209 pos = {
11210 x: (elem.offsetLeft + elem.offsetWidth / 2) * pxRatio,
11211 y: (elem.offsetTop + elem.offsetHeight / 2) * pxRatio
11212 },
11213 radius = elem.offsetWidth / 2 * pxRatio,
11214 tolerance = 10 * pxRatio,
11215 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);
11216 this._processBounce(pos, radius, area);
11217 });
11218 };
11219 }
11220 clear() {}
11221 init() {
11222 const container = this.container,
11223 bounce = container.actualOptions.interactivity.modes.bounce;
11224 if (!bounce) {
11225 return;
11226 }
11227 container.retina.bounceModeDistance = bounce.distance * container.retina.pixelRatio;
11228 }
11229 async interact() {
11230 const container = this.container,
11231 options = container.actualOptions,
11232 events = options.interactivity.events,
11233 mouseMoveStatus = container.interactivity.status === mouseMoveEvent,
11234 hoverEnabled = events.onHover.enable,
11235 hoverMode = events.onHover.mode,
11236 divs = events.onDiv;
11237 if (mouseMoveStatus && hoverEnabled && isInArray("bounce", hoverMode)) {
11238 this._processMouseBounce();
11239 } else {
11240 divModeExecute("bounce", divs, (selector, div) => this._singleSelectorBounce(selector, div));
11241 }
11242 }
11243 isEnabled(particle) {
11244 const container = this.container,
11245 options = container.actualOptions,
11246 mouse = container.interactivity.mouse,
11247 events = (particle?.interactivity ?? options.interactivity).events,
11248 divs = events.onDiv;
11249 return mouse.position && events.onHover.enable && isInArray("bounce", events.onHover.mode) || isDivModeEnabled("bounce", divs);
11250 }
11251 loadModeOptions(options, ...sources) {
11252 if (!options.bounce) {
11253 options.bounce = new Bounce();
11254 }
11255 for (const source of sources) {
11256 options.bounce.load(source?.bounce);
11257 }
11258 }
11259 reset() {}
11260}
11261;// CONCATENATED MODULE: ../../interactions/external/bounce/dist/esm/index.js
11262
11263async function loadExternalBounceInteraction(engine, refresh = true) {
11264 await engine.addInteractor("externalBounce", container => new Bouncer(container), refresh);
11265}
11266
11267
11268;// CONCATENATED MODULE: ../../interactions/external/bubble/dist/esm/Options/Classes/BubbleBase.js
11269
11270class BubbleBase {
11271 constructor() {
11272 this.distance = 200;
11273 this.duration = 0.4;
11274 this.mix = false;
11275 }
11276 load(data) {
11277 if (!data) {
11278 return;
11279 }
11280 if (data.distance !== undefined) {
11281 this.distance = data.distance;
11282 }
11283 if (data.duration !== undefined) {
11284 this.duration = data.duration;
11285 }
11286 if (data.mix !== undefined) {
11287 this.mix = data.mix;
11288 }
11289 if (data.opacity !== undefined) {
11290 this.opacity = data.opacity;
11291 }
11292 if (data.color !== undefined) {
11293 const sourceColor = isArray(this.color) ? undefined : this.color;
11294 this.color = executeOnSingleOrMultiple(data.color, color => {
11295 return OptionsColor.create(sourceColor, color);
11296 });
11297 }
11298 if (data.size !== undefined) {
11299 this.size = data.size;
11300 }
11301 }
11302}
11303;// CONCATENATED MODULE: ../../interactions/external/bubble/dist/esm/Options/Classes/BubbleDiv.js
11304
11305
11306class BubbleDiv extends BubbleBase {
11307 constructor() {
11308 super();
11309 this.selectors = [];
11310 }
11311 get ids() {
11312 return executeOnSingleOrMultiple(this.selectors, t => t.replace("#", ""));
11313 }
11314 set ids(value) {
11315 this.selectors = executeOnSingleOrMultiple(value, t => `#${t}`);
11316 }
11317 load(data) {
11318 super.load(data);
11319 if (!data) {
11320 return;
11321 }
11322 if (data.ids !== undefined) {
11323 this.ids = data.ids;
11324 }
11325 if (data.selectors !== undefined) {
11326 this.selectors = data.selectors;
11327 }
11328 }
11329}
11330;// CONCATENATED MODULE: ../../interactions/external/bubble/dist/esm/Options/Classes/Bubble.js
11331
11332
11333
11334class Bubble extends BubbleBase {
11335 load(data) {
11336 super.load(data);
11337 if (!data) {
11338 return;
11339 }
11340 this.divs = executeOnSingleOrMultiple(data.divs, div => {
11341 const tmp = new BubbleDiv();
11342 tmp.load(div);
11343 return tmp;
11344 });
11345 }
11346}
11347;// CONCATENATED MODULE: ../../interactions/external/bubble/dist/esm/Utils.js
11348
11349function calculateBubbleValue(particleValue, modeValue, optionsValue, ratio) {
11350 if (modeValue >= optionsValue) {
11351 const value = particleValue + (modeValue - optionsValue) * ratio;
11352 return clamp(value, particleValue, modeValue);
11353 } else if (modeValue < optionsValue) {
11354 const value = particleValue - (optionsValue - modeValue) * ratio;
11355 return clamp(value, modeValue, particleValue);
11356 }
11357}
11358;// CONCATENATED MODULE: ../../interactions/external/bubble/dist/esm/Bubbler.js
11359
11360
11361
11362class Bubbler extends ExternalInteractorBase {
11363 constructor(container) {
11364 super(container);
11365 this._clickBubble = () => {
11366 const container = this.container,
11367 options = container.actualOptions,
11368 mouseClickPos = container.interactivity.mouse.clickPosition,
11369 bubbleOptions = options.interactivity.modes.bubble;
11370 if (!bubbleOptions || !mouseClickPos) {
11371 return;
11372 }
11373 if (!container.bubble) {
11374 container.bubble = {};
11375 }
11376 const distance = container.retina.bubbleModeDistance;
11377 if (!distance || distance < 0) {
11378 return;
11379 }
11380 const query = container.particles.quadTree.queryCircle(mouseClickPos, distance, p => this.isEnabled(p)),
11381 {
11382 bubble
11383 } = container;
11384 for (const particle of query) {
11385 if (!bubble.clicking) {
11386 continue;
11387 }
11388 particle.bubble.inRange = !bubble.durationEnd;
11389 const pos = particle.getPosition(),
11390 distMouse = getDistance(pos, mouseClickPos),
11391 timeSpent = (new Date().getTime() - (container.interactivity.mouse.clickTime || 0)) / 1000;
11392 if (timeSpent > bubbleOptions.duration) {
11393 bubble.durationEnd = true;
11394 }
11395 if (timeSpent > bubbleOptions.duration * 2) {
11396 bubble.clicking = false;
11397 bubble.durationEnd = false;
11398 }
11399 const sizeData = {
11400 bubbleObj: {
11401 optValue: container.retina.bubbleModeSize,
11402 value: particle.bubble.radius
11403 },
11404 particlesObj: {
11405 optValue: getRangeMax(particle.options.size.value) * container.retina.pixelRatio,
11406 value: particle.size.value
11407 },
11408 type: "size"
11409 };
11410 this._process(particle, distMouse, timeSpent, sizeData);
11411 const opacityData = {
11412 bubbleObj: {
11413 optValue: bubbleOptions.opacity,
11414 value: particle.bubble.opacity
11415 },
11416 particlesObj: {
11417 optValue: getRangeMax(particle.options.opacity.value),
11418 value: particle.opacity?.value ?? 1
11419 },
11420 type: "opacity"
11421 };
11422 this._process(particle, distMouse, timeSpent, opacityData);
11423 if (!bubble.durationEnd && distMouse <= distance) {
11424 this._hoverBubbleColor(particle, distMouse);
11425 } else {
11426 delete particle.bubble.color;
11427 }
11428 }
11429 };
11430 this._hoverBubble = () => {
11431 const container = this.container,
11432 mousePos = container.interactivity.mouse.position,
11433 distance = container.retina.bubbleModeDistance;
11434 if (!distance || distance < 0 || mousePos === undefined) {
11435 return;
11436 }
11437 const query = container.particles.quadTree.queryCircle(mousePos, distance, p => this.isEnabled(p));
11438 for (const particle of query) {
11439 particle.bubble.inRange = true;
11440 const pos = particle.getPosition(),
11441 pointDistance = getDistance(pos, mousePos),
11442 ratio = 1 - pointDistance / distance;
11443 if (pointDistance <= distance) {
11444 if (ratio >= 0 && container.interactivity.status === mouseMoveEvent) {
11445 this._hoverBubbleSize(particle, ratio);
11446 this._hoverBubbleOpacity(particle, ratio);
11447 this._hoverBubbleColor(particle, ratio);
11448 }
11449 } else {
11450 this.reset(particle);
11451 }
11452 if (container.interactivity.status === mouseLeaveEvent) {
11453 this.reset(particle);
11454 }
11455 }
11456 };
11457 this._hoverBubbleColor = (particle, ratio, divBubble) => {
11458 const options = this.container.actualOptions,
11459 bubbleOptions = divBubble ?? options.interactivity.modes.bubble;
11460 if (!bubbleOptions) {
11461 return;
11462 }
11463 if (!particle.bubble.finalColor) {
11464 const modeColor = bubbleOptions.color;
11465 if (!modeColor) {
11466 return;
11467 }
11468 const bubbleColor = itemFromSingleOrMultiple(modeColor);
11469 particle.bubble.finalColor = rangeColorToHsl(bubbleColor);
11470 }
11471 if (!particle.bubble.finalColor) {
11472 return;
11473 }
11474 if (bubbleOptions.mix) {
11475 particle.bubble.color = undefined;
11476 const pColor = particle.getFillColor();
11477 particle.bubble.color = pColor ? rgbToHsl(colorMix(pColor, particle.bubble.finalColor, 1 - ratio, ratio)) : particle.bubble.finalColor;
11478 } else {
11479 particle.bubble.color = particle.bubble.finalColor;
11480 }
11481 };
11482 this._hoverBubbleOpacity = (particle, ratio, divBubble) => {
11483 const container = this.container,
11484 options = container.actualOptions,
11485 modeOpacity = divBubble?.opacity ?? options.interactivity.modes.bubble?.opacity;
11486 if (!modeOpacity) {
11487 return;
11488 }
11489 const optOpacity = particle.options.opacity.value,
11490 pOpacity = particle.opacity?.value ?? 1,
11491 opacity = calculateBubbleValue(pOpacity, modeOpacity, getRangeMax(optOpacity), ratio);
11492 if (opacity !== undefined) {
11493 particle.bubble.opacity = opacity;
11494 }
11495 };
11496 this._hoverBubbleSize = (particle, ratio, divBubble) => {
11497 const container = this.container,
11498 modeSize = divBubble?.size ? divBubble.size * container.retina.pixelRatio : container.retina.bubbleModeSize;
11499 if (modeSize === undefined) {
11500 return;
11501 }
11502 const optSize = getRangeMax(particle.options.size.value) * container.retina.pixelRatio,
11503 pSize = particle.size.value,
11504 size = calculateBubbleValue(pSize, modeSize, optSize, ratio);
11505 if (size !== undefined) {
11506 particle.bubble.radius = size;
11507 }
11508 };
11509 this._process = (particle, distMouse, timeSpent, data) => {
11510 const container = this.container,
11511 bubbleParam = data.bubbleObj.optValue,
11512 options = container.actualOptions,
11513 bubbleOptions = options.interactivity.modes.bubble;
11514 if (!bubbleOptions || bubbleParam === undefined) {
11515 return;
11516 }
11517 const bubbleDuration = bubbleOptions.duration,
11518 bubbleDistance = container.retina.bubbleModeDistance,
11519 particlesParam = data.particlesObj.optValue,
11520 pObjBubble = data.bubbleObj.value,
11521 pObj = data.particlesObj.value || 0,
11522 type = data.type;
11523 if (!bubbleDistance || bubbleDistance < 0 || bubbleParam === particlesParam) {
11524 return;
11525 }
11526 if (!container.bubble) {
11527 container.bubble = {};
11528 }
11529 if (container.bubble.durationEnd) {
11530 if (pObjBubble) {
11531 if (type === "size") {
11532 delete particle.bubble.radius;
11533 }
11534 if (type === "opacity") {
11535 delete particle.bubble.opacity;
11536 }
11537 }
11538 } else {
11539 if (distMouse <= bubbleDistance) {
11540 const obj = pObjBubble ?? pObj;
11541 if (obj !== bubbleParam) {
11542 const value = pObj - timeSpent * (pObj - bubbleParam) / bubbleDuration;
11543 if (type === "size") {
11544 particle.bubble.radius = value;
11545 }
11546 if (type === "opacity") {
11547 particle.bubble.opacity = value;
11548 }
11549 }
11550 } else {
11551 if (type === "size") {
11552 delete particle.bubble.radius;
11553 }
11554 if (type === "opacity") {
11555 delete particle.bubble.opacity;
11556 }
11557 }
11558 }
11559 };
11560 this._singleSelectorHover = (delta, selector, div) => {
11561 const container = this.container,
11562 selectors = document.querySelectorAll(selector),
11563 bubble = container.actualOptions.interactivity.modes.bubble;
11564 if (!bubble || !selectors.length) {
11565 return;
11566 }
11567 selectors.forEach(item => {
11568 const elem = item,
11569 pxRatio = container.retina.pixelRatio,
11570 pos = {
11571 x: (elem.offsetLeft + elem.offsetWidth / 2) * pxRatio,
11572 y: (elem.offsetTop + elem.offsetHeight / 2) * pxRatio
11573 },
11574 repulseRadius = elem.offsetWidth / 2 * pxRatio,
11575 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),
11576 query = container.particles.quadTree.query(area, p => this.isEnabled(p));
11577 for (const particle of query) {
11578 if (!area.contains(particle.getPosition())) {
11579 continue;
11580 }
11581 particle.bubble.inRange = true;
11582 const divs = bubble.divs,
11583 divBubble = divMode(divs, elem);
11584 if (!particle.bubble.div || particle.bubble.div !== elem) {
11585 this.clear(particle, delta, true);
11586 particle.bubble.div = elem;
11587 }
11588 this._hoverBubbleSize(particle, 1, divBubble);
11589 this._hoverBubbleOpacity(particle, 1, divBubble);
11590 this._hoverBubbleColor(particle, 1, divBubble);
11591 }
11592 });
11593 };
11594 if (!container.bubble) {
11595 container.bubble = {};
11596 }
11597 this.handleClickMode = mode => {
11598 if (mode !== "bubble") {
11599 return;
11600 }
11601 if (!container.bubble) {
11602 container.bubble = {};
11603 }
11604 container.bubble.clicking = true;
11605 };
11606 }
11607 clear(particle, delta, force) {
11608 if (particle.bubble.inRange && !force) {
11609 return;
11610 }
11611 delete particle.bubble.div;
11612 delete particle.bubble.opacity;
11613 delete particle.bubble.radius;
11614 delete particle.bubble.color;
11615 }
11616 init() {
11617 const container = this.container,
11618 bubble = container.actualOptions.interactivity.modes.bubble;
11619 if (!bubble) {
11620 return;
11621 }
11622 container.retina.bubbleModeDistance = bubble.distance * container.retina.pixelRatio;
11623 if (bubble.size !== undefined) {
11624 container.retina.bubbleModeSize = bubble.size * container.retina.pixelRatio;
11625 }
11626 }
11627 async interact(delta) {
11628 const options = this.container.actualOptions,
11629 events = options.interactivity.events,
11630 onHover = events.onHover,
11631 onClick = events.onClick,
11632 hoverEnabled = onHover.enable,
11633 hoverMode = onHover.mode,
11634 clickEnabled = onClick.enable,
11635 clickMode = onClick.mode,
11636 divs = events.onDiv;
11637 if (hoverEnabled && isInArray("bubble", hoverMode)) {
11638 this._hoverBubble();
11639 } else if (clickEnabled && isInArray("bubble", clickMode)) {
11640 this._clickBubble();
11641 } else {
11642 divModeExecute("bubble", divs, (selector, div) => this._singleSelectorHover(delta, selector, div));
11643 }
11644 }
11645 isEnabled(particle) {
11646 const container = this.container,
11647 options = container.actualOptions,
11648 mouse = container.interactivity.mouse,
11649 events = (particle?.interactivity ?? options.interactivity).events,
11650 {
11651 onClick,
11652 onDiv,
11653 onHover
11654 } = events,
11655 divBubble = isDivModeEnabled("bubble", onDiv);
11656 if (!(divBubble || onHover.enable && mouse.position || onClick.enable && mouse.clickPosition)) {
11657 return false;
11658 }
11659 return isInArray("bubble", onHover.mode) || isInArray("bubble", onClick.mode) || divBubble;
11660 }
11661 loadModeOptions(options, ...sources) {
11662 if (!options.bubble) {
11663 options.bubble = new Bubble();
11664 }
11665 for (const source of sources) {
11666 options.bubble.load(source?.bubble);
11667 }
11668 }
11669 reset(particle) {
11670 particle.bubble.inRange = false;
11671 }
11672}
11673;// CONCATENATED MODULE: ../../interactions/external/bubble/dist/esm/index.js
11674
11675async function loadExternalBubbleInteraction(engine, refresh = true) {
11676 await engine.addInteractor("externalBubble", container => new Bubbler(container), refresh);
11677}
11678
11679
11680
11681
11682
11683
11684;// CONCATENATED MODULE: ../../interactions/external/connect/dist/esm/Options/Classes/ConnectLinks.js
11685class ConnectLinks {
11686 constructor() {
11687 this.opacity = 0.5;
11688 }
11689 load(data) {
11690 if (!data) {
11691 return;
11692 }
11693 if (data.opacity !== undefined) {
11694 this.opacity = data.opacity;
11695 }
11696 }
11697}
11698;// CONCATENATED MODULE: ../../interactions/external/connect/dist/esm/Options/Classes/Connect.js
11699
11700class Connect {
11701 constructor() {
11702 this.distance = 80;
11703 this.links = new ConnectLinks();
11704 this.radius = 60;
11705 }
11706 get lineLinked() {
11707 return this.links;
11708 }
11709 set lineLinked(value) {
11710 this.links = value;
11711 }
11712 get line_linked() {
11713 return this.links;
11714 }
11715 set line_linked(value) {
11716 this.links = value;
11717 }
11718 load(data) {
11719 if (!data) {
11720 return;
11721 }
11722 if (data.distance !== undefined) {
11723 this.distance = data.distance;
11724 }
11725 this.links.load(data.links ?? data.lineLinked ?? data.line_linked);
11726 if (data.radius !== undefined) {
11727 this.radius = data.radius;
11728 }
11729 }
11730}
11731;// CONCATENATED MODULE: ../../interactions/external/connect/dist/esm/Utils.js
11732
11733function gradient(context, p1, p2, opacity) {
11734 const gradStop = Math.floor(p2.getRadius() / p1.getRadius()),
11735 color1 = p1.getFillColor(),
11736 color2 = p2.getFillColor();
11737 if (!color1 || !color2) {
11738 return;
11739 }
11740 const sourcePos = p1.getPosition(),
11741 destPos = p2.getPosition(),
11742 midRgb = colorMix(color1, color2, p1.getRadius(), p2.getRadius()),
11743 grad = context.createLinearGradient(sourcePos.x, sourcePos.y, destPos.x, destPos.y);
11744 grad.addColorStop(0, ColorUtils_getStyleFromHsl(color1, opacity));
11745 grad.addColorStop(gradStop > 1 ? 1 : gradStop, getStyleFromRgb(midRgb, opacity));
11746 grad.addColorStop(1, ColorUtils_getStyleFromHsl(color2, opacity));
11747 return grad;
11748}
11749function drawConnectLine(context, width, lineStyle, begin, end) {
11750 drawLine(context, begin, end);
11751 context.lineWidth = width;
11752 context.strokeStyle = lineStyle;
11753 context.stroke();
11754}
11755function lineStyle(container, ctx, p1, p2) {
11756 const options = container.actualOptions,
11757 connectOptions = options.interactivity.modes.connect;
11758 if (!connectOptions) {
11759 return;
11760 }
11761 return gradient(ctx, p1, p2, connectOptions.links.opacity);
11762}
11763function drawConnection(container, p1, p2) {
11764 container.canvas.draw(ctx => {
11765 const ls = lineStyle(container, ctx, p1, p2);
11766 if (!ls) {
11767 return;
11768 }
11769 const pos1 = p1.getPosition(),
11770 pos2 = p2.getPosition();
11771 drawConnectLine(ctx, p1.retina.linksWidth ?? 0, ls, pos1, pos2);
11772 });
11773}
11774;// CONCATENATED MODULE: ../../interactions/external/connect/dist/esm/Connector.js
11775
11776
11777
11778class Connector extends ExternalInteractorBase {
11779 constructor(container) {
11780 super(container);
11781 }
11782 clear() {}
11783 init() {
11784 const container = this.container,
11785 connect = container.actualOptions.interactivity.modes.connect;
11786 if (!connect) {
11787 return;
11788 }
11789 container.retina.connectModeDistance = connect.distance * container.retina.pixelRatio;
11790 container.retina.connectModeRadius = connect.radius * container.retina.pixelRatio;
11791 }
11792 async interact() {
11793 const container = this.container,
11794 options = container.actualOptions;
11795 if (options.interactivity.events.onHover.enable && container.interactivity.status === "pointermove") {
11796 const mousePos = container.interactivity.mouse.position;
11797 if (!container.retina.connectModeDistance || container.retina.connectModeDistance < 0 || !container.retina.connectModeRadius || container.retina.connectModeRadius < 0 || !mousePos) {
11798 return;
11799 }
11800 const distance = Math.abs(container.retina.connectModeRadius),
11801 query = container.particles.quadTree.queryCircle(mousePos, distance, p => this.isEnabled(p));
11802 let i = 0;
11803 for (const p1 of query) {
11804 const pos1 = p1.getPosition();
11805 for (const p2 of query.slice(i + 1)) {
11806 const pos2 = p2.getPosition(),
11807 distMax = Math.abs(container.retina.connectModeDistance),
11808 xDiff = Math.abs(pos1.x - pos2.x),
11809 yDiff = Math.abs(pos1.y - pos2.y);
11810 if (xDiff < distMax && yDiff < distMax) {
11811 drawConnection(container, p1, p2);
11812 }
11813 }
11814 ++i;
11815 }
11816 }
11817 }
11818 isEnabled(particle) {
11819 const container = this.container,
11820 mouse = container.interactivity.mouse,
11821 events = (particle?.interactivity ?? container.actualOptions.interactivity).events;
11822 if (!(events.onHover.enable && mouse.position)) {
11823 return false;
11824 }
11825 return isInArray("connect", events.onHover.mode);
11826 }
11827 loadModeOptions(options, ...sources) {
11828 if (!options.connect) {
11829 options.connect = new Connect();
11830 }
11831 for (const source of sources) {
11832 options.connect.load(source?.connect);
11833 }
11834 }
11835 reset() {}
11836}
11837;// CONCATENATED MODULE: ../../interactions/external/connect/dist/esm/index.js
11838
11839async function loadExternalConnectInteraction(engine, refresh = true) {
11840 await engine.addInteractor("externalConnect", container => new Connector(container), refresh);
11841}
11842
11843
11844
11845
11846;// CONCATENATED MODULE: ../../interactions/external/grab/dist/esm/Options/Classes/GrabLinks.js
11847
11848class GrabLinks {
11849 constructor() {
11850 this.blink = false;
11851 this.consent = false;
11852 this.opacity = 1;
11853 }
11854 load(data) {
11855 if (!data) {
11856 return;
11857 }
11858 if (data.blink !== undefined) {
11859 this.blink = data.blink;
11860 }
11861 if (data.color !== undefined) {
11862 this.color = OptionsColor.create(this.color, data.color);
11863 }
11864 if (data.consent !== undefined) {
11865 this.consent = data.consent;
11866 }
11867 if (data.opacity !== undefined) {
11868 this.opacity = data.opacity;
11869 }
11870 }
11871}
11872;// CONCATENATED MODULE: ../../interactions/external/grab/dist/esm/Options/Classes/Grab.js
11873
11874class Grab {
11875 constructor() {
11876 this.distance = 100;
11877 this.links = new GrabLinks();
11878 }
11879 get lineLinked() {
11880 return this.links;
11881 }
11882 set lineLinked(value) {
11883 this.links = value;
11884 }
11885 get line_linked() {
11886 return this.links;
11887 }
11888 set line_linked(value) {
11889 this.links = value;
11890 }
11891 load(data) {
11892 if (!data) {
11893 return;
11894 }
11895 if (data.distance !== undefined) {
11896 this.distance = data.distance;
11897 }
11898 this.links.load(data.links ?? data.lineLinked ?? data.line_linked);
11899 }
11900}
11901;// CONCATENATED MODULE: ../../interactions/external/grab/dist/esm/Utils.js
11902
11903function drawGrabLine(context, width, begin, end, colorLine, opacity) {
11904 drawLine(context, begin, end);
11905 context.strokeStyle = getStyleFromRgb(colorLine, opacity);
11906 context.lineWidth = width;
11907 context.stroke();
11908}
11909function drawGrab(container, particle, lineColor, opacity, mousePos) {
11910 container.canvas.draw(ctx => {
11911 const beginPos = particle.getPosition();
11912 drawGrabLine(ctx, particle.retina.linksWidth ?? 0, beginPos, mousePos, lineColor, opacity);
11913 });
11914}
11915;// CONCATENATED MODULE: ../../interactions/external/grab/dist/esm/Grabber.js
11916
11917
11918
11919class Grabber extends ExternalInteractorBase {
11920 constructor(container) {
11921 super(container);
11922 }
11923 clear() {}
11924 init() {
11925 const container = this.container,
11926 grab = container.actualOptions.interactivity.modes.grab;
11927 if (!grab) {
11928 return;
11929 }
11930 container.retina.grabModeDistance = grab.distance * container.retina.pixelRatio;
11931 }
11932 async interact() {
11933 const container = this.container,
11934 options = container.actualOptions,
11935 interactivity = options.interactivity;
11936 if (!interactivity.modes.grab || !interactivity.events.onHover.enable || container.interactivity.status !== mouseMoveEvent) {
11937 return;
11938 }
11939 const mousePos = container.interactivity.mouse.position;
11940 if (!mousePos) {
11941 return;
11942 }
11943 const distance = container.retina.grabModeDistance;
11944 if (!distance || distance < 0) {
11945 return;
11946 }
11947 const query = container.particles.quadTree.queryCircle(mousePos, distance, p => this.isEnabled(p));
11948 for (const particle of query) {
11949 const pos = particle.getPosition(),
11950 pointDistance = getDistance(pos, mousePos);
11951 if (pointDistance > distance) {
11952 continue;
11953 }
11954 const grabLineOptions = interactivity.modes.grab.links,
11955 lineOpacity = grabLineOptions.opacity,
11956 opacityLine = lineOpacity - pointDistance * lineOpacity / distance;
11957 if (opacityLine <= 0) {
11958 continue;
11959 }
11960 const optColor = grabLineOptions.color ?? particle.options.links?.color;
11961 if (!container.particles.grabLineColor && optColor) {
11962 const linksOptions = interactivity.modes.grab.links;
11963 container.particles.grabLineColor = getLinkRandomColor(optColor, linksOptions.blink, linksOptions.consent);
11964 }
11965 const colorLine = getLinkColor(particle, undefined, container.particles.grabLineColor);
11966 if (!colorLine) {
11967 continue;
11968 }
11969 drawGrab(container, particle, colorLine, opacityLine, mousePos);
11970 }
11971 }
11972 isEnabled(particle) {
11973 const container = this.container,
11974 mouse = container.interactivity.mouse,
11975 events = (particle?.interactivity ?? container.actualOptions.interactivity).events;
11976 return events.onHover.enable && !!mouse.position && isInArray("grab", events.onHover.mode);
11977 }
11978 loadModeOptions(options, ...sources) {
11979 if (!options.grab) {
11980 options.grab = new Grab();
11981 }
11982 for (const source of sources) {
11983 options.grab.load(source?.grab);
11984 }
11985 }
11986 reset() {}
11987}
11988;// CONCATENATED MODULE: ../../interactions/external/grab/dist/esm/index.js
11989
11990async function loadExternalGrabInteraction(engine, refresh = true) {
11991 await engine.addInteractor("externalGrab", container => new Grabber(container), refresh);
11992}
11993
11994
11995
11996
11997;// CONCATENATED MODULE: ../../interactions/external/pause/dist/esm/Pauser.js
11998
11999class Pauser extends ExternalInteractorBase {
12000 constructor(container) {
12001 super(container);
12002 this.handleClickMode = mode => {
12003 if (mode !== "pause") {
12004 return;
12005 }
12006 const container = this.container;
12007 if (container.getAnimationStatus()) {
12008 container.pause();
12009 } else {
12010 container.play();
12011 }
12012 };
12013 }
12014 clear() {}
12015 init() {}
12016 async interact() {}
12017 isEnabled() {
12018 return true;
12019 }
12020 reset() {}
12021}
12022;// CONCATENATED MODULE: ../../interactions/external/pause/dist/esm/index.js
12023
12024async function loadExternalPauseInteraction(engine, refresh = true) {
12025 await engine.addInteractor("externalPause", container => new Pauser(container), refresh);
12026}
12027;// CONCATENATED MODULE: ../../interactions/external/push/dist/esm/Options/Classes/Push.js
12028
12029class Push {
12030 constructor() {
12031 this.default = true;
12032 this.groups = [];
12033 this.quantity = 4;
12034 }
12035 get particles_nb() {
12036 return this.quantity;
12037 }
12038 set particles_nb(value) {
12039 this.quantity = setRangeValue(value);
12040 }
12041 load(data) {
12042 if (!data) {
12043 return;
12044 }
12045 if (data.default !== undefined) {
12046 this.default = data.default;
12047 }
12048 if (data.groups !== undefined) {
12049 this.groups = data.groups.map(t => t);
12050 }
12051 if (!this.groups.length) {
12052 this.default = true;
12053 }
12054 const quantity = data.quantity ?? data.particles_nb;
12055 if (quantity !== undefined) {
12056 this.quantity = setRangeValue(quantity);
12057 }
12058 }
12059}
12060;// CONCATENATED MODULE: ../../interactions/external/push/dist/esm/Pusher.js
12061
12062
12063class Pusher extends ExternalInteractorBase {
12064 constructor(container) {
12065 super(container);
12066 this.handleClickMode = mode => {
12067 if (mode !== "push") {
12068 return;
12069 }
12070 const container = this.container,
12071 options = container.actualOptions,
12072 pushOptions = options.interactivity.modes.push;
12073 if (!pushOptions) {
12074 return;
12075 }
12076 const quantity = getRangeValue(pushOptions.quantity);
12077 if (quantity <= 0) {
12078 return;
12079 }
12080 const group = itemFromArray([undefined, ...pushOptions.groups]),
12081 groupOptions = group !== undefined ? container.actualOptions.particles.groups[group] : undefined;
12082 container.particles.push(quantity, container.interactivity.mouse, groupOptions, group);
12083 };
12084 }
12085 clear() {}
12086 init() {}
12087 async interact() {}
12088 isEnabled() {
12089 return true;
12090 }
12091 loadModeOptions(options, ...sources) {
12092 if (!options.push) {
12093 options.push = new Push();
12094 }
12095 for (const source of sources) {
12096 options.push.load(source?.push);
12097 }
12098 }
12099 reset() {}
12100}
12101;// CONCATENATED MODULE: ../../interactions/external/push/dist/esm/index.js
12102
12103async function loadExternalPushInteraction(engine, refresh = true) {
12104 await engine.addInteractor("externalPush", container => new Pusher(container), refresh);
12105}
12106
12107
12108;// CONCATENATED MODULE: ../../interactions/external/remove/dist/esm/Options/Classes/Remove.js
12109
12110class Remove {
12111 constructor() {
12112 this.quantity = 2;
12113 }
12114 get particles_nb() {
12115 return this.quantity;
12116 }
12117 set particles_nb(value) {
12118 this.quantity = setRangeValue(value);
12119 }
12120 load(data) {
12121 if (!data) {
12122 return;
12123 }
12124 const quantity = data.quantity ?? data.particles_nb;
12125 if (quantity !== undefined) {
12126 this.quantity = setRangeValue(quantity);
12127 }
12128 }
12129}
12130;// CONCATENATED MODULE: ../../interactions/external/remove/dist/esm/Remover.js
12131
12132
12133class Remover extends ExternalInteractorBase {
12134 constructor(container) {
12135 super(container);
12136 this.handleClickMode = mode => {
12137 const container = this.container,
12138 options = container.actualOptions;
12139 if (!options.interactivity.modes.remove || mode !== "remove") {
12140 return;
12141 }
12142 const removeNb = getRangeValue(options.interactivity.modes.remove.quantity);
12143 container.particles.removeQuantity(removeNb);
12144 };
12145 }
12146 clear() {}
12147 init() {}
12148 async interact() {}
12149 isEnabled() {
12150 return true;
12151 }
12152 loadModeOptions(options, ...sources) {
12153 if (!options.remove) {
12154 options.remove = new Remove();
12155 }
12156 for (const source of sources) {
12157 options.remove.load(source?.remove);
12158 }
12159 }
12160 reset() {}
12161}
12162;// CONCATENATED MODULE: ../../interactions/external/remove/dist/esm/index.js
12163
12164async function loadExternalRemoveInteraction(engine, refresh = true) {
12165 await engine.addInteractor("externalRemove", container => new Remover(container), refresh);
12166}
12167
12168
12169;// CONCATENATED MODULE: ../../interactions/external/repulse/dist/esm/Options/Classes/RepulseBase.js
12170class RepulseBase {
12171 constructor() {
12172 this.distance = 200;
12173 this.duration = 0.4;
12174 this.factor = 100;
12175 this.speed = 1;
12176 this.maxSpeed = 50;
12177 this.easing = "ease-out-quad";
12178 }
12179 load(data) {
12180 if (!data) {
12181 return;
12182 }
12183 if (data.distance !== undefined) {
12184 this.distance = data.distance;
12185 }
12186 if (data.duration !== undefined) {
12187 this.duration = data.duration;
12188 }
12189 if (data.easing !== undefined) {
12190 this.easing = data.easing;
12191 }
12192 if (data.factor !== undefined) {
12193 this.factor = data.factor;
12194 }
12195 if (data.speed !== undefined) {
12196 this.speed = data.speed;
12197 }
12198 if (data.maxSpeed !== undefined) {
12199 this.maxSpeed = data.maxSpeed;
12200 }
12201 }
12202}
12203;// CONCATENATED MODULE: ../../interactions/external/repulse/dist/esm/Options/Classes/RepulseDiv.js
12204
12205
12206class RepulseDiv extends RepulseBase {
12207 constructor() {
12208 super();
12209 this.selectors = [];
12210 }
12211 get ids() {
12212 return executeOnSingleOrMultiple(this.selectors, t => t.replace("#", ""));
12213 }
12214 set ids(value) {
12215 this.selectors = executeOnSingleOrMultiple(value, t => `#${t}`);
12216 }
12217 load(data) {
12218 super.load(data);
12219 if (!data) {
12220 return;
12221 }
12222 if (data.ids !== undefined) {
12223 this.ids = data.ids;
12224 }
12225 if (data.selectors !== undefined) {
12226 this.selectors = data.selectors;
12227 }
12228 }
12229}
12230;// CONCATENATED MODULE: ../../interactions/external/repulse/dist/esm/Options/Classes/Repulse.js
12231
12232
12233
12234class Repulse extends RepulseBase {
12235 load(data) {
12236 super.load(data);
12237 if (!data) {
12238 return;
12239 }
12240 this.divs = executeOnSingleOrMultiple(data.divs, div => {
12241 const tmp = new RepulseDiv();
12242 tmp.load(div);
12243 return tmp;
12244 });
12245 }
12246}
12247;// CONCATENATED MODULE: ../../interactions/external/repulse/dist/esm/Repulser.js
12248
12249
12250class Repulser extends ExternalInteractorBase {
12251 constructor(engine, container) {
12252 super(container);
12253 this._clickRepulse = () => {
12254 const container = this.container,
12255 repulseOptions = container.actualOptions.interactivity.modes.repulse;
12256 if (!repulseOptions) {
12257 return;
12258 }
12259 const repulse = container.repulse || {
12260 particles: []
12261 };
12262 if (!repulse.finish) {
12263 if (!repulse.count) {
12264 repulse.count = 0;
12265 }
12266 repulse.count++;
12267 if (repulse.count === container.particles.count) {
12268 repulse.finish = true;
12269 }
12270 }
12271 if (repulse.clicking) {
12272 const repulseDistance = container.retina.repulseModeDistance;
12273 if (!repulseDistance || repulseDistance < 0) {
12274 return;
12275 }
12276 const repulseRadius = Math.pow(repulseDistance / 6, 3),
12277 mouseClickPos = container.interactivity.mouse.clickPosition;
12278 if (mouseClickPos === undefined) {
12279 return;
12280 }
12281 const range = new Circle(mouseClickPos.x, mouseClickPos.y, repulseRadius),
12282 query = container.particles.quadTree.query(range, p => this.isEnabled(p));
12283 for (const particle of query) {
12284 const {
12285 dx,
12286 dy,
12287 distance
12288 } = getDistances(mouseClickPos, particle.position),
12289 d = distance ** 2,
12290 velocity = repulseOptions.speed,
12291 force = -repulseRadius * velocity / d;
12292 if (d <= repulseRadius) {
12293 repulse.particles.push(particle);
12294 const vect = Vector.create(dx, dy);
12295 vect.length = force;
12296 particle.velocity.setTo(vect);
12297 }
12298 }
12299 } else if (repulse.clicking === false) {
12300 for (const particle of repulse.particles) {
12301 particle.velocity.setTo(particle.initialVelocity);
12302 }
12303 repulse.particles = [];
12304 }
12305 };
12306 this._hoverRepulse = () => {
12307 const container = this.container,
12308 mousePos = container.interactivity.mouse.position,
12309 repulseRadius = container.retina.repulseModeDistance;
12310 if (!repulseRadius || repulseRadius < 0 || !mousePos) {
12311 return;
12312 }
12313 this._processRepulse(mousePos, repulseRadius, new Circle(mousePos.x, mousePos.y, repulseRadius));
12314 };
12315 this._processRepulse = (position, repulseRadius, area, divRepulse) => {
12316 const container = this.container,
12317 query = container.particles.quadTree.query(area, p => this.isEnabled(p)),
12318 repulseOptions = container.actualOptions.interactivity.modes.repulse;
12319 if (!repulseOptions) {
12320 return;
12321 }
12322 for (const particle of query) {
12323 const {
12324 dx,
12325 dy,
12326 distance
12327 } = getDistances(particle.position, position),
12328 velocity = (divRepulse?.speed ?? repulseOptions.speed) * repulseOptions.factor,
12329 repulseFactor = clamp(getEasing(repulseOptions.easing)(1 - distance / repulseRadius) * velocity, 0, repulseOptions.maxSpeed),
12330 normVec = Vector.create(distance === 0 ? velocity : dx / distance * repulseFactor, distance === 0 ? velocity : dy / distance * repulseFactor);
12331 particle.position.addTo(normVec);
12332 }
12333 };
12334 this._singleSelectorRepulse = (selector, div) => {
12335 const container = this.container,
12336 repulse = container.actualOptions.interactivity.modes.repulse;
12337 if (!repulse) {
12338 return;
12339 }
12340 const query = document.querySelectorAll(selector);
12341 if (!query.length) {
12342 return;
12343 }
12344 query.forEach(item => {
12345 const elem = item,
12346 pxRatio = container.retina.pixelRatio,
12347 pos = {
12348 x: (elem.offsetLeft + elem.offsetWidth / 2) * pxRatio,
12349 y: (elem.offsetTop + elem.offsetHeight / 2) * pxRatio
12350 },
12351 repulseRadius = elem.offsetWidth / 2 * pxRatio,
12352 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),
12353 divs = repulse.divs,
12354 divRepulse = divMode(divs, elem);
12355 this._processRepulse(pos, repulseRadius, area, divRepulse);
12356 });
12357 };
12358 this._engine = engine;
12359 if (!container.repulse) {
12360 container.repulse = {
12361 particles: []
12362 };
12363 }
12364 this.handleClickMode = mode => {
12365 const options = this.container.actualOptions,
12366 repulseOpts = options.interactivity.modes.repulse;
12367 if (!repulseOpts || mode !== "repulse") {
12368 return;
12369 }
12370 if (!container.repulse) {
12371 container.repulse = {
12372 particles: []
12373 };
12374 }
12375 const repulse = container.repulse;
12376 repulse.clicking = true;
12377 repulse.count = 0;
12378 for (const particle of container.repulse.particles) {
12379 if (!this.isEnabled(particle)) {
12380 continue;
12381 }
12382 particle.velocity.setTo(particle.initialVelocity);
12383 }
12384 repulse.particles = [];
12385 repulse.finish = false;
12386 setTimeout(() => {
12387 if (container.destroyed) {
12388 return;
12389 }
12390 repulse.clicking = false;
12391 }, repulseOpts.duration * 1000);
12392 };
12393 }
12394 clear() {}
12395 init() {
12396 const container = this.container,
12397 repulse = container.actualOptions.interactivity.modes.repulse;
12398 if (!repulse) {
12399 return;
12400 }
12401 container.retina.repulseModeDistance = repulse.distance * container.retina.pixelRatio;
12402 }
12403 async interact() {
12404 const container = this.container,
12405 options = container.actualOptions,
12406 mouseMoveStatus = container.interactivity.status === mouseMoveEvent,
12407 events = options.interactivity.events,
12408 hover = events.onHover,
12409 hoverEnabled = hover.enable,
12410 hoverMode = hover.mode,
12411 click = events.onClick,
12412 clickEnabled = click.enable,
12413 clickMode = click.mode,
12414 divs = events.onDiv;
12415 if (mouseMoveStatus && hoverEnabled && isInArray("repulse", hoverMode)) {
12416 this._hoverRepulse();
12417 } else if (clickEnabled && isInArray("repulse", clickMode)) {
12418 this._clickRepulse();
12419 } else {
12420 divModeExecute("repulse", divs, (selector, div) => this._singleSelectorRepulse(selector, div));
12421 }
12422 }
12423 isEnabled(particle) {
12424 const container = this.container,
12425 options = container.actualOptions,
12426 mouse = container.interactivity.mouse,
12427 events = (particle?.interactivity ?? options.interactivity).events,
12428 divs = events.onDiv,
12429 hover = events.onHover,
12430 click = events.onClick,
12431 divRepulse = isDivModeEnabled("repulse", divs);
12432 if (!(divRepulse || hover.enable && mouse.position || click.enable && mouse.clickPosition)) {
12433 return false;
12434 }
12435 const hoverMode = hover.mode,
12436 clickMode = click.mode;
12437 return isInArray("repulse", hoverMode) || isInArray("repulse", clickMode) || divRepulse;
12438 }
12439 loadModeOptions(options, ...sources) {
12440 if (!options.repulse) {
12441 options.repulse = new Repulse();
12442 }
12443 for (const source of sources) {
12444 options.repulse.load(source?.repulse);
12445 }
12446 }
12447 reset() {}
12448}
12449;// CONCATENATED MODULE: ../../interactions/external/repulse/dist/esm/index.js
12450
12451async function loadExternalRepulseInteraction(engine, refresh = true) {
12452 await engine.addInteractor("externalRepulse", container => new Repulser(engine, container), refresh);
12453}
12454
12455
12456
12457
12458
12459
12460;// CONCATENATED MODULE: ../../interactions/external/slow/dist/esm/Options/Classes/Slow.js
12461class Slow {
12462 constructor() {
12463 this.factor = 3;
12464 this.radius = 200;
12465 }
12466 load(data) {
12467 if (!data) {
12468 return;
12469 }
12470 if (data.factor !== undefined) {
12471 this.factor = data.factor;
12472 }
12473 if (data.radius !== undefined) {
12474 this.radius = data.radius;
12475 }
12476 }
12477}
12478;// CONCATENATED MODULE: ../../interactions/external/slow/dist/esm/Slower.js
12479
12480
12481class Slower extends ExternalInteractorBase {
12482 constructor(container) {
12483 super(container);
12484 }
12485 clear(particle, delta, force) {
12486 if (particle.slow.inRange && !force) {
12487 return;
12488 }
12489 particle.slow.factor = 1;
12490 }
12491 init() {
12492 const container = this.container,
12493 slow = container.actualOptions.interactivity.modes.slow;
12494 if (!slow) {
12495 return;
12496 }
12497 container.retina.slowModeRadius = slow.radius * container.retina.pixelRatio;
12498 }
12499 async interact() {}
12500 isEnabled(particle) {
12501 const container = this.container,
12502 mouse = container.interactivity.mouse,
12503 events = (particle?.interactivity ?? container.actualOptions.interactivity).events;
12504 return events.onHover.enable && !!mouse.position && isInArray("slow", events.onHover.mode);
12505 }
12506 loadModeOptions(options, ...sources) {
12507 if (!options.slow) {
12508 options.slow = new Slow();
12509 }
12510 for (const source of sources) {
12511 options.slow.load(source?.slow);
12512 }
12513 }
12514 reset(particle) {
12515 particle.slow.inRange = false;
12516 const container = this.container,
12517 options = container.actualOptions,
12518 mousePos = container.interactivity.mouse.position,
12519 radius = container.retina.slowModeRadius,
12520 slowOptions = options.interactivity.modes.slow;
12521 if (!slowOptions || !radius || radius < 0 || !mousePos) {
12522 return;
12523 }
12524 const particlePos = particle.getPosition(),
12525 dist = getDistance(mousePos, particlePos),
12526 proximityFactor = dist / radius,
12527 slowFactor = slowOptions.factor,
12528 {
12529 slow
12530 } = particle;
12531 if (dist > radius) {
12532 return;
12533 }
12534 slow.inRange = true;
12535 slow.factor = proximityFactor / slowFactor;
12536 }
12537}
12538;// CONCATENATED MODULE: ../../interactions/external/slow/dist/esm/index.js
12539
12540async function loadExternalSlowInteraction(engine, refresh = true) {
12541 await engine.addInteractor("externalSlow", container => new Slower(container), refresh);
12542}
12543
12544
12545;// CONCATENATED MODULE: ../../shapes/image/dist/esm/GifUtils/Constants.js
12546const InterlaceOffsets = [0, 4, 2, 1];
12547const InterlaceSteps = [8, 8, 4, 2];
12548;// CONCATENATED MODULE: ../../shapes/image/dist/esm/GifUtils/ByteStream.js
12549class ByteStream {
12550 constructor(bytes) {
12551 this.pos = 0;
12552 this.data = new Uint8ClampedArray(bytes);
12553 }
12554 getString(count) {
12555 const slice = this.data.slice(this.pos, this.pos + count);
12556 this.pos += slice.length;
12557 return slice.reduce((acc, curr) => acc + String.fromCharCode(curr), "");
12558 }
12559 nextByte() {
12560 return this.data[this.pos++];
12561 }
12562 nextTwoBytes() {
12563 this.pos += 2;
12564 return this.data[this.pos - 2] + (this.data[this.pos - 1] << 8);
12565 }
12566 readSubBlocks() {
12567 let blockString = "",
12568 size = 0;
12569 do {
12570 size = this.data[this.pos++];
12571 for (let count = size; --count >= 0; blockString += String.fromCharCode(this.data[this.pos++])) {}
12572 } while (size !== 0);
12573 return blockString;
12574 }
12575 readSubBlocksBin() {
12576 let size = 0,
12577 len = 0;
12578 for (let offset = 0; (size = this.data[this.pos + offset]) !== 0; offset += size + 1) {
12579 len += size;
12580 }
12581 const blockData = new Uint8Array(len);
12582 for (let i = 0; (size = this.data[this.pos++]) !== 0;) {
12583 for (let count = size; --count >= 0; blockData[i++] = this.data[this.pos++]) {}
12584 }
12585 return blockData;
12586 }
12587 skipSubBlocks() {
12588 for (; this.data[this.pos] !== 0; this.pos += this.data[this.pos] + 1) {}
12589 this.pos++;
12590 }
12591}
12592;// CONCATENATED MODULE: ../../shapes/image/dist/esm/GifUtils/Utils.js
12593
12594
12595function parseColorTable(byteStream, count) {
12596 const colors = [];
12597 for (let i = 0; i < count; i++) {
12598 colors.push({
12599 r: byteStream.data[byteStream.pos],
12600 g: byteStream.data[byteStream.pos + 1],
12601 b: byteStream.data[byteStream.pos + 2]
12602 });
12603 byteStream.pos += 3;
12604 }
12605 return colors;
12606}
12607async function parseExtensionBlock(byteStream, gif, getFrameIndex, getTransparencyIndex) {
12608 switch (byteStream.nextByte()) {
12609 case 249:
12610 {
12611 const frame = gif.frames[getFrameIndex(false)];
12612 byteStream.pos++;
12613 const packedByte = byteStream.nextByte();
12614 frame.GCreserved = (packedByte & 0xe0) >>> 5;
12615 frame.disposalMethod = (packedByte & 0x1c) >>> 2;
12616 frame.userInputDelayFlag = (packedByte & 2) === 2;
12617 const transparencyFlag = (packedByte & 1) === 1;
12618 frame.delayTime = byteStream.nextTwoBytes() * 0xa;
12619 const transparencyIndex = byteStream.nextByte();
12620 if (transparencyFlag) {
12621 getTransparencyIndex(transparencyIndex);
12622 }
12623 byteStream.pos++;
12624 break;
12625 }
12626 case 255:
12627 {
12628 byteStream.pos++;
12629 const applicationExtension = {
12630 identifier: byteStream.getString(8),
12631 authenticationCode: byteStream.getString(3),
12632 data: byteStream.readSubBlocksBin()
12633 };
12634 gif.applicationExtensions.push(applicationExtension);
12635 break;
12636 }
12637 case 254:
12638 {
12639 gif.comments.push([getFrameIndex(false), byteStream.readSubBlocks()]);
12640 break;
12641 }
12642 case 1:
12643 {
12644 if (gif.globalColorTable.length === 0) {
12645 throw new EvalError("plain text extension without global color table");
12646 }
12647 byteStream.pos++;
12648 gif.frames[getFrameIndex(false)].plainTextData = {
12649 left: byteStream.nextTwoBytes(),
12650 top: byteStream.nextTwoBytes(),
12651 width: byteStream.nextTwoBytes(),
12652 height: byteStream.nextTwoBytes(),
12653 charSize: {
12654 width: byteStream.nextTwoBytes(),
12655 height: byteStream.nextTwoBytes()
12656 },
12657 foregroundColor: byteStream.nextByte(),
12658 backgroundColor: byteStream.nextByte(),
12659 text: byteStream.readSubBlocks()
12660 };
12661 break;
12662 }
12663 default:
12664 byteStream.skipSubBlocks();
12665 break;
12666 }
12667}
12668async function parseImageBlock(byteStream, gif, avgAlpha, getFrameIndex, getTransparencyIndex, progressCallback) {
12669 const frame = gif.frames[getFrameIndex(true)];
12670 frame.left = byteStream.nextTwoBytes();
12671 frame.top = byteStream.nextTwoBytes();
12672 frame.width = byteStream.nextTwoBytes();
12673 frame.height = byteStream.nextTwoBytes();
12674 const packedByte = byteStream.nextByte(),
12675 localColorTableFlag = (packedByte & 0x80) === 0x80,
12676 interlacedFlag = (packedByte & 0x40) === 0x40;
12677 frame.sortFlag = (packedByte & 0x20) === 0x20;
12678 frame.reserved = (packedByte & 0x18) >>> 3;
12679 const localColorCount = 1 << (packedByte & 7) + 1;
12680 if (localColorTableFlag) {
12681 frame.localColorTable = parseColorTable(byteStream, localColorCount);
12682 }
12683 const getColor = index => {
12684 const {
12685 r,
12686 g,
12687 b
12688 } = (localColorTableFlag ? frame.localColorTable : gif.globalColorTable)[index];
12689 return {
12690 r,
12691 g,
12692 b,
12693 a: index === getTransparencyIndex(null) ? avgAlpha ? ~~((r + g + b) / 3) : 0 : 255
12694 };
12695 };
12696 const image = (() => {
12697 try {
12698 return new ImageData(frame.width, frame.height, {
12699 colorSpace: "srgb"
12700 });
12701 } catch (error) {
12702 if (error instanceof DOMException && error.name === "IndexSizeError") {
12703 return null;
12704 }
12705 throw error;
12706 }
12707 })();
12708 if (image == null) {
12709 throw new EvalError("GIF frame size is to large");
12710 }
12711 const minCodeSize = byteStream.nextByte(),
12712 imageData = byteStream.readSubBlocksBin(),
12713 clearCode = 1 << minCodeSize;
12714 const readBits = (pos, len) => {
12715 const bytePos = pos >>> 3,
12716 bitPos = pos & 7;
12717 return (imageData[bytePos] + (imageData[bytePos + 1] << 8) + (imageData[bytePos + 2] << 16) & (1 << len) - 1 << bitPos) >>> bitPos;
12718 };
12719 if (interlacedFlag) {
12720 for (let code = 0, size = minCodeSize + 1, pos = 0, dic = [[0]], pass = 0; pass < 4; pass++) {
12721 if (InterlaceOffsets[pass] < frame.height) {
12722 for (let pixelPos = 0, lineIndex = 0;;) {
12723 const last = code;
12724 code = readBits(pos, size);
12725 pos += size + 1;
12726 if (code === clearCode) {
12727 size = minCodeSize + 1;
12728 dic.length = clearCode + 2;
12729 for (let i = 0; i < dic.length; i++) {
12730 dic[i] = i < clearCode ? [i] : [];
12731 }
12732 } else {
12733 if (code >= dic.length) {
12734 dic.push(dic[last].concat(dic[last][0]));
12735 } else if (last !== clearCode) {
12736 dic.push(dic[last].concat(dic[code][0]));
12737 }
12738 for (let i = 0; i < dic[code].length; i++) {
12739 const {
12740 r,
12741 g,
12742 b,
12743 a
12744 } = getColor(dic[code][i]);
12745 image.data.set([r, g, b, a], InterlaceOffsets[pass] * frame.width + InterlaceSteps[pass] * lineIndex + pixelPos % (frame.width * 4));
12746 pixelPos += 4;
12747 }
12748 if (dic.length === 1 << size && size < 0xc) {
12749 size++;
12750 }
12751 }
12752 if (pixelPos === frame.width * 4 * (lineIndex + 1)) {
12753 lineIndex++;
12754 if (InterlaceOffsets[pass] + InterlaceSteps[pass] * lineIndex >= frame.height) {
12755 break;
12756 }
12757 }
12758 }
12759 }
12760 progressCallback?.(byteStream.pos / (byteStream.data.length - 1), getFrameIndex(false) + 1, image, {
12761 x: frame.left,
12762 y: frame.top
12763 }, {
12764 width: gif.width,
12765 height: gif.height
12766 });
12767 }
12768 frame.image = image;
12769 frame.bitmap = await createImageBitmap(image);
12770 } else {
12771 for (let code = 0, size = minCodeSize + 1, pos = 0, dic = [[0]], pixelPos = -4;;) {
12772 const last = code;
12773 code = readBits(pos, size);
12774 pos += size;
12775 if (code === clearCode) {
12776 size = minCodeSize + 1;
12777 dic.length = clearCode + 2;
12778 for (let i = 0; i < dic.length; i++) {
12779 dic[i] = i < clearCode ? [i] : [];
12780 }
12781 } else {
12782 if (code === clearCode + 1) {
12783 break;
12784 }
12785 if (code >= dic.length) {
12786 dic.push(dic[last].concat(dic[last][0]));
12787 } else if (last !== clearCode) {
12788 dic.push(dic[last].concat(dic[code][0]));
12789 }
12790 for (let i = 0; i < dic[code].length; i++) {
12791 const {
12792 r,
12793 g,
12794 b,
12795 a
12796 } = getColor(dic[code][i]);
12797 image.data.set([r, g, b, a], pixelPos += 4);
12798 }
12799 if (dic.length >= 1 << size && size < 0xc) {
12800 size++;
12801 }
12802 }
12803 }
12804 frame.image = image;
12805 frame.bitmap = await createImageBitmap(image);
12806 progressCallback?.((byteStream.pos + 1) / byteStream.data.length, getFrameIndex(false) + 1, frame.image, {
12807 x: frame.left,
12808 y: frame.top
12809 }, {
12810 width: gif.width,
12811 height: gif.height
12812 });
12813 }
12814}
12815async function parseBlock(byteStream, gif, avgAlpha, getFrameIndex, getTransparencyIndex, progressCallback) {
12816 switch (byteStream.nextByte()) {
12817 case 59:
12818 return true;
12819 case 44:
12820 await parseImageBlock(byteStream, gif, avgAlpha, getFrameIndex, getTransparencyIndex, progressCallback);
12821 break;
12822 case 33:
12823 await parseExtensionBlock(byteStream, gif, getFrameIndex, getTransparencyIndex);
12824 break;
12825 default:
12826 throw new EvalError("undefined block found");
12827 }
12828 return false;
12829}
12830function getGIFLoopAmount(gif) {
12831 for (const extension of gif.applicationExtensions) {
12832 if (extension.identifier + extension.authenticationCode !== "NETSCAPE2.0") {
12833 continue;
12834 }
12835 return extension.data[1] + (extension.data[2] << 8);
12836 }
12837 return NaN;
12838}
12839async function decodeGIF(gifURL, progressCallback, avgAlpha) {
12840 if (!avgAlpha) avgAlpha = false;
12841 const res = await fetch(gifURL);
12842 if (!res.ok && res.status === 404) {
12843 throw new EvalError("file not found");
12844 }
12845 const buffer = await res.arrayBuffer();
12846 const gif = {
12847 width: 0,
12848 height: 0,
12849 totalTime: 0,
12850 colorRes: 0,
12851 pixelAspectRatio: 0,
12852 frames: [],
12853 sortFlag: false,
12854 globalColorTable: [],
12855 backgroundImage: new ImageData(1, 1, {
12856 colorSpace: "srgb"
12857 }),
12858 comments: [],
12859 applicationExtensions: []
12860 },
12861 byteStream = new ByteStream(new Uint8ClampedArray(buffer));
12862 if (byteStream.getString(6) !== "GIF89a") {
12863 throw new Error("not a supported GIF file");
12864 }
12865 gif.width = byteStream.nextTwoBytes();
12866 gif.height = byteStream.nextTwoBytes();
12867 const packedByte = byteStream.nextByte(),
12868 globalColorTableFlag = (packedByte & 0x80) === 0x80;
12869 gif.colorRes = (packedByte & 0x70) >>> 4;
12870 gif.sortFlag = (packedByte & 8) === 8;
12871 const globalColorCount = 1 << (packedByte & 7) + 1,
12872 backgroundColorIndex = byteStream.nextByte();
12873 gif.pixelAspectRatio = byteStream.nextByte();
12874 if (gif.pixelAspectRatio !== 0) {
12875 gif.pixelAspectRatio = (gif.pixelAspectRatio + 0xf) / 0x40;
12876 }
12877 if (globalColorTableFlag) {
12878 gif.globalColorTable = parseColorTable(byteStream, globalColorCount);
12879 }
12880 const backgroundImage = (() => {
12881 try {
12882 return new ImageData(gif.width, gif.height, {
12883 colorSpace: "srgb"
12884 });
12885 } catch (error) {
12886 if (error instanceof DOMException && error.name === "IndexSizeError") {
12887 return null;
12888 }
12889 throw error;
12890 }
12891 })();
12892 if (backgroundImage == null) {
12893 throw new Error("GIF frame size is to large");
12894 }
12895 const {
12896 r,
12897 g,
12898 b
12899 } = gif.globalColorTable[backgroundColorIndex];
12900 backgroundImage.data.set(globalColorTableFlag ? [r, g, b, 255] : [0, 0, 0, 0]);
12901 for (let i = 4; i < backgroundImage.data.length; i *= 2) {
12902 backgroundImage.data.copyWithin(i, 0, i);
12903 }
12904 gif.backgroundImage = backgroundImage;
12905 let frameIndex = -1,
12906 incrementFrameIndex = true,
12907 transparencyIndex = -1;
12908 const getframeIndex = increment => {
12909 if (increment) {
12910 incrementFrameIndex = true;
12911 }
12912 return frameIndex;
12913 };
12914 const getTransparencyIndex = newValue => {
12915 if (newValue != null) {
12916 transparencyIndex = newValue;
12917 }
12918 return transparencyIndex;
12919 };
12920 try {
12921 do {
12922 if (incrementFrameIndex) {
12923 gif.frames.push({
12924 left: 0,
12925 top: 0,
12926 width: 0,
12927 height: 0,
12928 disposalMethod: 0,
12929 image: new ImageData(1, 1, {
12930 colorSpace: "srgb"
12931 }),
12932 plainTextData: null,
12933 userInputDelayFlag: false,
12934 delayTime: 0,
12935 sortFlag: false,
12936 localColorTable: [],
12937 reserved: 0,
12938 GCreserved: 0
12939 });
12940 frameIndex++;
12941 transparencyIndex = -1;
12942 incrementFrameIndex = false;
12943 }
12944 } while (!(await parseBlock(byteStream, gif, avgAlpha, getframeIndex, getTransparencyIndex, progressCallback)));
12945 gif.frames.length--;
12946 for (const frame of gif.frames) {
12947 if (frame.userInputDelayFlag && frame.delayTime === 0) {
12948 gif.totalTime = Infinity;
12949 break;
12950 }
12951 gif.totalTime += frame.delayTime;
12952 }
12953 return gif;
12954 } catch (error) {
12955 if (error instanceof EvalError) {
12956 throw new Error(`error while parsing frame ${frameIndex} "${error.message}"`);
12957 }
12958 throw error;
12959 }
12960}
12961;// CONCATENATED MODULE: ../../shapes/image/dist/esm/Utils.js
12962
12963
12964const currentColorRegex = /(#(?:[0-9a-f]{2}){2,4}|(#[0-9a-f]{3})|(rgb|hsl)a?\((-?\d+%?[,\s]+){2,3}\s*[\d.]+%?\))|currentcolor/gi;
12965function replaceColorSvg(imageShape, color, opacity) {
12966 const {
12967 svgData
12968 } = imageShape;
12969 if (!svgData) {
12970 return "";
12971 }
12972 const colorStyle = ColorUtils_getStyleFromHsl(color, opacity);
12973 if (svgData.includes("fill")) {
12974 return svgData.replace(currentColorRegex, () => colorStyle);
12975 }
12976 const preFillIndex = svgData.indexOf(">");
12977 return `${svgData.substring(0, preFillIndex)} fill="${colorStyle}"${svgData.substring(preFillIndex)}`;
12978}
12979async function loadImage(image) {
12980 return new Promise(resolve => {
12981 image.loading = true;
12982 const img = new Image();
12983 image.element = img;
12984 img.addEventListener("load", () => {
12985 image.loading = false;
12986 resolve();
12987 });
12988 img.addEventListener("error", () => {
12989 image.element = undefined;
12990 image.error = true;
12991 image.loading = false;
12992 getLogger().error(`${errorPrefix} loading image: ${image.source}`);
12993 resolve();
12994 });
12995 img.src = image.source;
12996 });
12997}
12998async function loadGifImage(image) {
12999 if (image.type !== "gif") {
13000 await loadImage(image);
13001 return;
13002 }
13003 image.loading = true;
13004 try {
13005 image.gifData = await decodeGIF(image.source);
13006 image.gifLoopCount = getGIFLoopAmount(image.gifData) ?? 0;
13007 if (image.gifLoopCount === 0) {
13008 image.gifLoopCount = Infinity;
13009 }
13010 } catch {
13011 image.error = true;
13012 }
13013 image.loading = false;
13014}
13015async function downloadSvgImage(image) {
13016 if (image.type !== "svg") {
13017 await loadImage(image);
13018 return;
13019 }
13020 image.loading = true;
13021 const response = await fetch(image.source);
13022 if (!response.ok) {
13023 getLogger().error(`${errorPrefix} Image not found`);
13024 image.error = true;
13025 } else {
13026 image.svgData = await response.text();
13027 }
13028 image.loading = false;
13029}
13030function replaceImageColor(image, imageData, color, particle) {
13031 const svgColoredData = replaceColorSvg(image, color, particle.opacity?.value ?? 1),
13032 imageRes = {
13033 color,
13034 gif: imageData.gif,
13035 data: {
13036 ...image,
13037 svgData: svgColoredData
13038 },
13039 loaded: false,
13040 ratio: imageData.width / imageData.height,
13041 replaceColor: imageData.replaceColor ?? imageData.replace_color,
13042 source: imageData.src
13043 };
13044 return new Promise(resolve => {
13045 const svg = new Blob([svgColoredData], {
13046 type: "image/svg+xml"
13047 }),
13048 domUrl = URL || window.URL || window.webkitURL || window,
13049 url = domUrl.createObjectURL(svg),
13050 img = new Image();
13051 img.addEventListener("load", () => {
13052 imageRes.loaded = true;
13053 imageRes.element = img;
13054 resolve(imageRes);
13055 domUrl.revokeObjectURL(url);
13056 });
13057 img.addEventListener("error", async () => {
13058 domUrl.revokeObjectURL(url);
13059 const img2 = {
13060 ...image,
13061 error: false,
13062 loading: true
13063 };
13064 await loadImage(img2);
13065 imageRes.loaded = true;
13066 imageRes.element = img2.element;
13067 resolve(imageRes);
13068 });
13069 img.src = url;
13070 });
13071}
13072;// CONCATENATED MODULE: ../../shapes/image/dist/esm/ImageDrawer.js
13073
13074
13075class ImageDrawer {
13076 constructor(engine) {
13077 this.loadImageShape = async imageShape => {
13078 if (!this._engine.loadImage) {
13079 throw new Error(`${errorPrefix} image shape not initialized`);
13080 }
13081 await this._engine.loadImage({
13082 gif: imageShape.gif,
13083 name: imageShape.name,
13084 replaceColor: imageShape.replaceColor ?? imageShape.replace_color ?? false,
13085 src: imageShape.src
13086 });
13087 };
13088 this._engine = engine;
13089 }
13090 addImage(image) {
13091 if (!this._engine.images) {
13092 this._engine.images = [];
13093 }
13094 this._engine.images.push(image);
13095 }
13096 draw(context, particle, radius, opacity, delta) {
13097 const image = particle.image,
13098 element = image?.element;
13099 if (!image) {
13100 return;
13101 }
13102 context.globalAlpha = opacity;
13103 if (image.gif && image.gifData) {
13104 const offscreenCanvas = new OffscreenCanvas(image.gifData.width, image.gifData.height),
13105 offscreenContext = offscreenCanvas.getContext("2d");
13106 if (!offscreenContext) {
13107 throw new Error("could not create offscreen canvas context");
13108 }
13109 offscreenContext.imageSmoothingQuality = "low";
13110 offscreenContext.imageSmoothingEnabled = false;
13111 offscreenContext.clearRect(0, 0, offscreenCanvas.width, offscreenCanvas.height);
13112 if (particle.gifLoopCount === undefined) {
13113 particle.gifLoopCount = image.gifLoopCount ?? 0;
13114 }
13115 let frameIndex = particle.gifFrame ?? 0;
13116 const pos = {
13117 x: -image.gifData.width * 0.5,
13118 y: -image.gifData.height * 0.5
13119 },
13120 frame = image.gifData.frames[frameIndex];
13121 if (particle.gifTime === undefined) {
13122 particle.gifTime = 0;
13123 }
13124 if (!frame.bitmap) {
13125 return;
13126 }
13127 context.scale(radius / image.gifData.width, radius / image.gifData.height);
13128 switch (frame.disposalMethod) {
13129 case 4:
13130 case 5:
13131 case 6:
13132 case 7:
13133 case 0:
13134 offscreenContext.drawImage(frame.bitmap, frame.left, frame.top);
13135 context.drawImage(offscreenCanvas, pos.x, pos.y);
13136 offscreenContext.clearRect(0, 0, offscreenCanvas.width, offscreenCanvas.height);
13137 break;
13138 case 1:
13139 offscreenContext.drawImage(frame.bitmap, frame.left, frame.top);
13140 context.drawImage(offscreenCanvas, pos.x, pos.y);
13141 break;
13142 case 2:
13143 offscreenContext.drawImage(frame.bitmap, frame.left, frame.top);
13144 context.drawImage(offscreenCanvas, pos.x, pos.y);
13145 offscreenContext.clearRect(0, 0, offscreenCanvas.width, offscreenCanvas.height);
13146 if (image.gifData.globalColorTable.length === 0) {
13147 offscreenContext.putImageData(image.gifData.frames[0].image, pos.x + frame.left, pos.y + frame.top);
13148 } else {
13149 offscreenContext.putImageData(image.gifData.backgroundImage, pos.x, pos.y);
13150 }
13151 break;
13152 case 3:
13153 {
13154 const previousImageData = offscreenContext.getImageData(0, 0, offscreenCanvas.width, offscreenCanvas.height);
13155 offscreenContext.drawImage(frame.bitmap, frame.left, frame.top);
13156 context.drawImage(offscreenCanvas, pos.x, pos.y);
13157 offscreenContext.clearRect(0, 0, offscreenCanvas.width, offscreenCanvas.height);
13158 offscreenContext.putImageData(previousImageData, 0, 0);
13159 }
13160 break;
13161 }
13162 particle.gifTime += delta.value;
13163 if (particle.gifTime > frame.delayTime) {
13164 particle.gifTime -= frame.delayTime;
13165 if (++frameIndex >= image.gifData.frames.length) {
13166 if (--particle.gifLoopCount <= 0) {
13167 return;
13168 }
13169 frameIndex = 0;
13170 offscreenContext.clearRect(0, 0, offscreenCanvas.width, offscreenCanvas.height);
13171 }
13172 particle.gifFrame = frameIndex;
13173 }
13174 context.scale(image.gifData.width / radius, image.gifData.height / radius);
13175 } else if (element) {
13176 const ratio = image.ratio,
13177 pos = {
13178 x: -radius,
13179 y: -radius
13180 };
13181 context.drawImage(element, pos.x, pos.y, radius * 2, radius * 2 / ratio);
13182 }
13183 context.globalAlpha = 1;
13184 }
13185 getSidesCount() {
13186 return 12;
13187 }
13188 async init(container) {
13189 const options = container.actualOptions;
13190 if (!options.preload || !this._engine.loadImage) {
13191 return;
13192 }
13193 for (const imageData of options.preload) {
13194 await this._engine.loadImage(imageData);
13195 }
13196 }
13197 loadShape(particle) {
13198 if (particle.shape !== "image" && particle.shape !== "images") {
13199 return;
13200 }
13201 if (!this._engine.images) {
13202 this._engine.images = [];
13203 }
13204 const imageData = particle.shapeData,
13205 image = this._engine.images.find(t => t.name === imageData.name || t.source === imageData.src);
13206 if (!image) {
13207 this.loadImageShape(imageData).then(() => {
13208 this.loadShape(particle);
13209 });
13210 }
13211 }
13212 particleInit(container, particle) {
13213 if (particle.shape !== "image" && particle.shape !== "images") {
13214 return;
13215 }
13216 if (!this._engine.images) {
13217 this._engine.images = [];
13218 }
13219 const images = this._engine.images,
13220 imageData = particle.shapeData,
13221 color = particle.getFillColor(),
13222 image = images.find(t => t.name === imageData.name || t.source === imageData.src);
13223 if (!image) {
13224 return;
13225 }
13226 const replaceColor = imageData.replaceColor ?? imageData.replace_color ?? image.replaceColor;
13227 if (image.loading) {
13228 setTimeout(() => {
13229 this.particleInit(container, particle);
13230 });
13231 return;
13232 }
13233 (async () => {
13234 let imageRes;
13235 if (image.svgData && color) {
13236 imageRes = await replaceImageColor(image, imageData, color, particle);
13237 } else {
13238 imageRes = {
13239 color,
13240 data: image,
13241 element: image.element,
13242 gif: image.gif,
13243 gifData: image.gifData,
13244 gifLoopCount: image.gifLoopCount,
13245 loaded: true,
13246 ratio: imageData.width && imageData.height ? imageData.width / imageData.height : image.ratio ?? 1,
13247 replaceColor: replaceColor,
13248 source: imageData.src
13249 };
13250 }
13251 if (!imageRes.ratio) {
13252 imageRes.ratio = 1;
13253 }
13254 const fill = imageData.fill ?? particle.fill,
13255 close = imageData.close ?? particle.close,
13256 imageShape = {
13257 image: imageRes,
13258 fill,
13259 close
13260 };
13261 particle.image = imageShape.image;
13262 particle.fill = imageShape.fill;
13263 particle.close = imageShape.close;
13264 })();
13265 }
13266}
13267;// CONCATENATED MODULE: ../../shapes/image/dist/esm/Options/Classes/Preload.js
13268class Preload {
13269 constructor() {
13270 this.src = "";
13271 this.gif = false;
13272 }
13273 load(data) {
13274 if (!data) {
13275 return;
13276 }
13277 if (data.gif !== undefined) {
13278 this.gif = data.gif;
13279 }
13280 if (data.height !== undefined) {
13281 this.height = data.height;
13282 }
13283 if (data.name !== undefined) {
13284 this.name = data.name;
13285 }
13286 if (data.replaceColor !== undefined) {
13287 this.replaceColor = data.replaceColor;
13288 }
13289 if (data.src !== undefined) {
13290 this.src = data.src;
13291 }
13292 if (data.width !== undefined) {
13293 this.width = data.width;
13294 }
13295 }
13296}
13297;// CONCATENATED MODULE: ../../shapes/image/dist/esm/ImagePreloader.js
13298
13299class ImagePreloaderPlugin {
13300 constructor(engine) {
13301 this.id = "imagePreloader";
13302 this._engine = engine;
13303 }
13304 getPlugin() {
13305 return {};
13306 }
13307 loadOptions(options, source) {
13308 if (!source || !source.preload) {
13309 return;
13310 }
13311 if (!options.preload) {
13312 options.preload = [];
13313 }
13314 const preloadOptions = options.preload;
13315 for (const item of source.preload) {
13316 const existing = preloadOptions.find(t => t.name === item.name || t.src === item.src);
13317 if (existing) {
13318 existing.load(item);
13319 } else {
13320 const preload = new Preload();
13321 preload.load(item);
13322 preloadOptions.push(preload);
13323 }
13324 }
13325 }
13326 needsPlugin() {
13327 return true;
13328 }
13329}
13330;// CONCATENATED MODULE: ../../shapes/image/dist/esm/index.js
13331
13332
13333
13334
13335function addLoadImageToEngine(engine) {
13336 if (engine.loadImage) {
13337 return;
13338 }
13339 engine.loadImage = async data => {
13340 if (!data.name && !data.src) {
13341 throw new Error(`${errorPrefix} no image source provided`);
13342 }
13343 if (!engine.images) {
13344 engine.images = [];
13345 }
13346 if (engine.images.find(t => t.name === data.name || t.source === data.src)) {
13347 return;
13348 }
13349 try {
13350 const image = {
13351 gif: data.gif ?? false,
13352 name: data.name ?? data.src,
13353 source: data.src,
13354 type: data.src.substring(data.src.length - 3),
13355 error: false,
13356 loading: true,
13357 replaceColor: data.replaceColor,
13358 ratio: data.width && data.height ? data.width / data.height : undefined
13359 };
13360 engine.images.push(image);
13361 const imageFunc = data.gif ? loadGifImage : data.replaceColor ? downloadSvgImage : loadImage;
13362 await imageFunc(image);
13363 } catch {
13364 throw new Error(`${errorPrefix} ${data.name ?? data.src} not found`);
13365 }
13366 };
13367}
13368async function loadImageShape(engine, refresh = true) {
13369 addLoadImageToEngine(engine);
13370 const preloader = new ImagePreloaderPlugin(engine);
13371 await engine.addPlugin(preloader, refresh);
13372 await engine.addShape(["image", "images"], new ImageDrawer(engine), refresh);
13373}
13374;// CONCATENATED MODULE: ../../updaters/life/dist/esm/Options/Classes/LifeDelay.js
13375
13376class LifeDelay extends ValueWithRandom {
13377 constructor() {
13378 super();
13379 this.sync = false;
13380 }
13381 load(data) {
13382 if (!data) {
13383 return;
13384 }
13385 super.load(data);
13386 if (data.sync !== undefined) {
13387 this.sync = data.sync;
13388 }
13389 }
13390}
13391;// CONCATENATED MODULE: ../../updaters/life/dist/esm/Options/Classes/LifeDuration.js
13392
13393class LifeDuration extends ValueWithRandom {
13394 constructor() {
13395 super();
13396 this.random.minimumValue = 0.0001;
13397 this.sync = false;
13398 }
13399 load(data) {
13400 if (!data) {
13401 return;
13402 }
13403 super.load(data);
13404 if (data.sync !== undefined) {
13405 this.sync = data.sync;
13406 }
13407 }
13408}
13409;// CONCATENATED MODULE: ../../updaters/life/dist/esm/Options/Classes/Life.js
13410
13411
13412class Life {
13413 constructor() {
13414 this.count = 0;
13415 this.delay = new LifeDelay();
13416 this.duration = new LifeDuration();
13417 }
13418 load(data) {
13419 if (!data) {
13420 return;
13421 }
13422 if (data.count !== undefined) {
13423 this.count = data.count;
13424 }
13425 this.delay.load(data.delay);
13426 this.duration.load(data.duration);
13427 }
13428}
13429;// CONCATENATED MODULE: ../../updaters/life/dist/esm/LifeUpdater.js
13430
13431
13432class LifeUpdater {
13433 constructor(container) {
13434 this.container = container;
13435 }
13436 init(particle) {
13437 const container = this.container,
13438 particlesOptions = particle.options,
13439 lifeOptions = particlesOptions.life;
13440 if (!lifeOptions) {
13441 return;
13442 }
13443 particle.life = {
13444 delay: container.retina.reduceFactor ? getRangeValue(lifeOptions.delay.value) * (lifeOptions.delay.sync ? 1 : getRandom()) / container.retina.reduceFactor * 1000 : 0,
13445 delayTime: 0,
13446 duration: container.retina.reduceFactor ? getRangeValue(lifeOptions.duration.value) * (lifeOptions.duration.sync ? 1 : getRandom()) / container.retina.reduceFactor * 1000 : 0,
13447 time: 0,
13448 count: lifeOptions.count
13449 };
13450 if (particle.life.duration <= 0) {
13451 particle.life.duration = -1;
13452 }
13453 if (particle.life.count <= 0) {
13454 particle.life.count = -1;
13455 }
13456 if (particle.life) {
13457 particle.spawning = particle.life.delay > 0;
13458 }
13459 }
13460 isEnabled(particle) {
13461 return !particle.destroyed;
13462 }
13463 loadOptions(options, ...sources) {
13464 if (!options.life) {
13465 options.life = new Life();
13466 }
13467 for (const source of sources) {
13468 options.life.load(source?.life);
13469 }
13470 }
13471 update(particle, delta) {
13472 if (!this.isEnabled(particle) || !particle.life) {
13473 return;
13474 }
13475 const life = particle.life;
13476 let justSpawned = false;
13477 if (particle.spawning) {
13478 life.delayTime += delta.value;
13479 if (life.delayTime >= particle.life.delay) {
13480 justSpawned = true;
13481 particle.spawning = false;
13482 life.delayTime = 0;
13483 life.time = 0;
13484 } else {
13485 return;
13486 }
13487 }
13488 if (life.duration === -1) {
13489 return;
13490 }
13491 if (particle.spawning) {
13492 return;
13493 }
13494 if (justSpawned) {
13495 life.time = 0;
13496 } else {
13497 life.time += delta.value;
13498 }
13499 if (life.time < life.duration) {
13500 return;
13501 }
13502 life.time = 0;
13503 if (particle.life.count > 0) {
13504 particle.life.count--;
13505 }
13506 if (particle.life.count === 0) {
13507 particle.destroy();
13508 return;
13509 }
13510 const canvasSize = this.container.canvas.size,
13511 widthRange = setRangeValue(0, canvasSize.width),
13512 heightRange = setRangeValue(0, canvasSize.width);
13513 particle.position.x = randomInRange(widthRange);
13514 particle.position.y = randomInRange(heightRange);
13515 particle.spawning = true;
13516 life.delayTime = 0;
13517 life.time = 0;
13518 particle.reset();
13519 const lifeOptions = particle.options.life;
13520 if (lifeOptions) {
13521 life.delay = getRangeValue(lifeOptions.delay.value) * 1000;
13522 life.duration = getRangeValue(lifeOptions.duration.value) * 1000;
13523 }
13524 }
13525}
13526;// CONCATENATED MODULE: ../../updaters/life/dist/esm/index.js
13527
13528async function loadLifeUpdater(engine, refresh = true) {
13529 await engine.addParticleUpdater("life", container => new LifeUpdater(container), refresh);
13530}
13531;// CONCATENATED MODULE: ../../shapes/line/dist/esm/LineDrawer.js
13532class LineDrawer {
13533 draw(context, particle, radius) {
13534 const shapeData = particle.shapeData;
13535 context.moveTo(-radius / 2, 0);
13536 context.lineTo(radius / 2, 0);
13537 context.lineCap = shapeData?.cap ?? "butt";
13538 }
13539 getSidesCount() {
13540 return 1;
13541 }
13542}
13543;// CONCATENATED MODULE: ../../shapes/line/dist/esm/index.js
13544
13545async function loadLineShape(engine, refresh = true) {
13546 await engine.addShape("line", new LineDrawer(), refresh);
13547}
13548;// CONCATENATED MODULE: ../../move/parallax/dist/esm/ParallaxMover.js
13549
13550class ParallaxMover {
13551 init() {}
13552 isEnabled(particle) {
13553 return !isSsr() && !particle.destroyed && particle.container.actualOptions.interactivity.events.onHover.parallax.enable;
13554 }
13555 move(particle) {
13556 const container = particle.container,
13557 options = container.actualOptions,
13558 parallaxOptions = options.interactivity.events.onHover.parallax;
13559 if (isSsr() || !parallaxOptions.enable) {
13560 return;
13561 }
13562 const parallaxForce = parallaxOptions.force,
13563 mousePos = container.interactivity.mouse.position;
13564 if (!mousePos) {
13565 return;
13566 }
13567 const canvasSize = container.canvas.size,
13568 canvasCenter = {
13569 x: canvasSize.width / 2,
13570 y: canvasSize.height / 2
13571 },
13572 parallaxSmooth = parallaxOptions.smooth,
13573 factor = particle.getRadius() / parallaxForce,
13574 centerDistance = {
13575 x: (mousePos.x - canvasCenter.x) * factor,
13576 y: (mousePos.y - canvasCenter.y) * factor
13577 },
13578 {
13579 offset
13580 } = particle;
13581 offset.x += (centerDistance.x - offset.x) / parallaxSmooth;
13582 offset.y += (centerDistance.y - offset.y) / parallaxSmooth;
13583 }
13584}
13585;// CONCATENATED MODULE: ../../move/parallax/dist/esm/index.js
13586
13587async function loadParallaxMover(engine, refresh = true) {
13588 await engine.addMover("parallax", () => new ParallaxMover(), refresh);
13589}
13590;// CONCATENATED MODULE: ../../interactions/particles/attract/dist/esm/Attractor.js
13591
13592class Attractor_Attractor extends ParticlesInteractorBase {
13593 constructor(container) {
13594 super(container);
13595 }
13596 clear() {}
13597 init() {}
13598 async interact(p1) {
13599 const container = this.container,
13600 distance = p1.retina.attractDistance ?? container.retina.attractDistance,
13601 pos1 = p1.getPosition(),
13602 query = container.particles.quadTree.queryCircle(pos1, distance);
13603 for (const p2 of query) {
13604 if (p1 === p2 || !p2.options.move.attract.enable || p2.destroyed || p2.spawning) {
13605 continue;
13606 }
13607 const pos2 = p2.getPosition(),
13608 {
13609 dx,
13610 dy
13611 } = getDistances(pos1, pos2),
13612 rotate = p1.options.move.attract.rotate,
13613 ax = dx / (rotate.x * 1000),
13614 ay = dy / (rotate.y * 1000),
13615 p1Factor = p2.size.value / p1.size.value,
13616 p2Factor = 1 / p1Factor;
13617 p1.velocity.x -= ax * p1Factor;
13618 p1.velocity.y -= ay * p1Factor;
13619 p2.velocity.x += ax * p2Factor;
13620 p2.velocity.y += ay * p2Factor;
13621 }
13622 }
13623 isEnabled(particle) {
13624 return particle.options.move.attract.enable;
13625 }
13626 reset() {}
13627}
13628;// CONCATENATED MODULE: ../../interactions/particles/attract/dist/esm/index.js
13629
13630async function loadParticlesAttractInteraction(engine, refresh = true) {
13631 await engine.addInteractor("particlesAttract", container => new Attractor_Attractor(container), refresh);
13632}
13633;// CONCATENATED MODULE: ../../interactions/particles/collisions/dist/esm/Absorb.js
13634
13635function updateAbsorb(p1, r1, p2, r2, delta, pixelRatio) {
13636 const factor = clamp(p1.options.collisions.absorb.speed * delta.factor / 10, 0, r2);
13637 p1.size.value += factor / 2;
13638 p2.size.value -= factor;
13639 if (r2 <= pixelRatio) {
13640 p2.size.value = 0;
13641 p2.destroy();
13642 }
13643}
13644function absorb(p1, p2, delta, pixelRatio) {
13645 const r1 = p1.getRadius(),
13646 r2 = p2.getRadius();
13647 if (r1 === undefined && r2 !== undefined) {
13648 p1.destroy();
13649 } else if (r1 !== undefined && r2 === undefined) {
13650 p2.destroy();
13651 } else if (r1 !== undefined && r2 !== undefined) {
13652 if (r1 >= r2) {
13653 updateAbsorb(p1, r1, p2, r2, delta, pixelRatio);
13654 } else {
13655 updateAbsorb(p2, r2, p1, r1, delta, pixelRatio);
13656 }
13657 }
13658}
13659;// CONCATENATED MODULE: ../../interactions/particles/collisions/dist/esm/Bounce.js
13660
13661const fixBounceSpeed = p => {
13662 if (p.collisionMaxSpeed === undefined) {
13663 p.collisionMaxSpeed = getRangeValue(p.options.collisions.maxSpeed);
13664 }
13665 if (p.velocity.length > p.collisionMaxSpeed) {
13666 p.velocity.length = p.collisionMaxSpeed;
13667 }
13668};
13669function bounce(p1, p2) {
13670 circleBounce(circleBounceDataFromParticle(p1), circleBounceDataFromParticle(p2));
13671 fixBounceSpeed(p1);
13672 fixBounceSpeed(p2);
13673}
13674;// CONCATENATED MODULE: ../../interactions/particles/collisions/dist/esm/Destroy.js
13675
13676function destroy(p1, p2) {
13677 if (!p1.unbreakable && !p2.unbreakable) {
13678 bounce(p1, p2);
13679 }
13680 if (p1.getRadius() === undefined && p2.getRadius() !== undefined) {
13681 p1.destroy();
13682 } else if (p1.getRadius() !== undefined && p2.getRadius() === undefined) {
13683 p2.destroy();
13684 } else if (p1.getRadius() !== undefined && p2.getRadius() !== undefined) {
13685 const deleteP = p1.getRadius() >= p2.getRadius() ? p2 : p1;
13686 deleteP.destroy();
13687 }
13688}
13689;// CONCATENATED MODULE: ../../interactions/particles/collisions/dist/esm/ResolveCollision.js
13690
13691
13692
13693function resolveCollision(p1, p2, delta, pixelRatio) {
13694 switch (p1.options.collisions.mode) {
13695 case "absorb":
13696 {
13697 absorb(p1, p2, delta, pixelRatio);
13698 break;
13699 }
13700 case "bounce":
13701 {
13702 bounce(p1, p2);
13703 break;
13704 }
13705 case "destroy":
13706 {
13707 destroy(p1, p2);
13708 break;
13709 }
13710 }
13711}
13712;// CONCATENATED MODULE: ../../interactions/particles/collisions/dist/esm/Collider.js
13713
13714
13715class Collider extends ParticlesInteractorBase {
13716 constructor(container) {
13717 super(container);
13718 }
13719 clear() {}
13720 init() {}
13721 async interact(p1, delta) {
13722 if (p1.destroyed || p1.spawning) {
13723 return;
13724 }
13725 const container = this.container,
13726 pos1 = p1.getPosition(),
13727 radius1 = p1.getRadius(),
13728 query = container.particles.quadTree.queryCircle(pos1, radius1 * 2);
13729 for (const p2 of query) {
13730 if (p1 === p2 || !p2.options.collisions.enable || p1.options.collisions.mode !== p2.options.collisions.mode || p2.destroyed || p2.spawning) {
13731 continue;
13732 }
13733 const pos2 = p2.getPosition(),
13734 radius2 = p2.getRadius();
13735 if (Math.abs(Math.round(pos1.z) - Math.round(pos2.z)) > radius1 + radius2) {
13736 continue;
13737 }
13738 const dist = getDistance(pos1, pos2),
13739 distP = radius1 + radius2;
13740 if (dist > distP) {
13741 continue;
13742 }
13743 resolveCollision(p1, p2, delta, container.retina.pixelRatio);
13744 }
13745 }
13746 isEnabled(particle) {
13747 return particle.options.collisions.enable;
13748 }
13749 reset() {}
13750}
13751;// CONCATENATED MODULE: ../../interactions/particles/collisions/dist/esm/index.js
13752
13753async function loadParticlesCollisionsInteraction(engine, refresh = true) {
13754 await engine.addInteractor("particlesCollisions", container => new Collider(container), refresh);
13755}
13756;// CONCATENATED MODULE: ../../interactions/particles/links/dist/esm/CircleWarp.js
13757
13758class CircleWarp extends Circle {
13759 constructor(x, y, radius, canvasSize) {
13760 super(x, y, radius);
13761 this.canvasSize = canvasSize;
13762 this.canvasSize = {
13763 ...canvasSize
13764 };
13765 }
13766 contains(point) {
13767 const {
13768 width,
13769 height
13770 } = this.canvasSize;
13771 const {
13772 x,
13773 y
13774 } = point;
13775 return super.contains(point) || super.contains({
13776 x: x - width,
13777 y
13778 }) || super.contains({
13779 x: x - width,
13780 y: y - height
13781 }) || super.contains({
13782 x,
13783 y: y - height
13784 });
13785 }
13786 intersects(range) {
13787 if (super.intersects(range)) {
13788 return true;
13789 }
13790 const rect = range,
13791 circle = range,
13792 newPos = {
13793 x: range.position.x - this.canvasSize.width,
13794 y: range.position.y - this.canvasSize.height
13795 };
13796 if (circle.radius !== undefined) {
13797 const biggerCircle = new Circle(newPos.x, newPos.y, circle.radius * 2);
13798 return super.intersects(biggerCircle);
13799 } else if (rect.size !== undefined) {
13800 const rectSW = new Rectangle(newPos.x, newPos.y, rect.size.width * 2, rect.size.height * 2);
13801 return super.intersects(rectSW);
13802 }
13803 return false;
13804 }
13805}
13806;// CONCATENATED MODULE: ../../interactions/particles/links/dist/esm/Options/Classes/LinksShadow.js
13807
13808class LinksShadow {
13809 constructor() {
13810 this.blur = 5;
13811 this.color = new OptionsColor();
13812 this.color.value = "#000";
13813 this.enable = false;
13814 }
13815 load(data) {
13816 if (!data) {
13817 return;
13818 }
13819 if (data.blur !== undefined) {
13820 this.blur = data.blur;
13821 }
13822 this.color = OptionsColor.create(this.color, data.color);
13823 if (data.enable !== undefined) {
13824 this.enable = data.enable;
13825 }
13826 }
13827}
13828;// CONCATENATED MODULE: ../../interactions/particles/links/dist/esm/Options/Classes/LinksTriangle.js
13829
13830class LinksTriangle {
13831 constructor() {
13832 this.enable = false;
13833 this.frequency = 1;
13834 }
13835 load(data) {
13836 if (!data) {
13837 return;
13838 }
13839 if (data.color !== undefined) {
13840 this.color = OptionsColor.create(this.color, data.color);
13841 }
13842 if (data.enable !== undefined) {
13843 this.enable = data.enable;
13844 }
13845 if (data.frequency !== undefined) {
13846 this.frequency = data.frequency;
13847 }
13848 if (data.opacity !== undefined) {
13849 this.opacity = data.opacity;
13850 }
13851 }
13852}
13853;// CONCATENATED MODULE: ../../interactions/particles/links/dist/esm/Options/Classes/Links.js
13854
13855
13856
13857class Links {
13858 constructor() {
13859 this.blink = false;
13860 this.color = new OptionsColor();
13861 this.color.value = "#fff";
13862 this.consent = false;
13863 this.distance = 100;
13864 this.enable = false;
13865 this.frequency = 1;
13866 this.opacity = 1;
13867 this.shadow = new LinksShadow();
13868 this.triangles = new LinksTriangle();
13869 this.width = 1;
13870 this.warp = false;
13871 }
13872 load(data) {
13873 if (!data) {
13874 return;
13875 }
13876 if (data.id !== undefined) {
13877 this.id = data.id;
13878 }
13879 if (data.blink !== undefined) {
13880 this.blink = data.blink;
13881 }
13882 this.color = OptionsColor.create(this.color, data.color);
13883 if (data.consent !== undefined) {
13884 this.consent = data.consent;
13885 }
13886 if (data.distance !== undefined) {
13887 this.distance = data.distance;
13888 }
13889 if (data.enable !== undefined) {
13890 this.enable = data.enable;
13891 }
13892 if (data.frequency !== undefined) {
13893 this.frequency = data.frequency;
13894 }
13895 if (data.opacity !== undefined) {
13896 this.opacity = data.opacity;
13897 }
13898 this.shadow.load(data.shadow);
13899 this.triangles.load(data.triangles);
13900 if (data.width !== undefined) {
13901 this.width = data.width;
13902 }
13903 if (data.warp !== undefined) {
13904 this.warp = data.warp;
13905 }
13906 }
13907}
13908;// CONCATENATED MODULE: ../../interactions/particles/links/dist/esm/Linker.js
13909
13910
13911
13912function getLinkDistance(pos1, pos2, optDistance, canvasSize, warp) {
13913 const {
13914 dx,
13915 dy,
13916 distance
13917 } = getDistances(pos1, pos2);
13918 if (!warp || distance <= optDistance) {
13919 return distance;
13920 }
13921 const absDiffs = {
13922 x: Math.abs(dx),
13923 y: Math.abs(dy)
13924 },
13925 warpDistances = {
13926 x: Math.min(absDiffs.x, canvasSize.width - absDiffs.x),
13927 y: Math.min(absDiffs.y, canvasSize.height - absDiffs.y)
13928 };
13929 return Math.sqrt(warpDistances.x ** 2 + warpDistances.y ** 2);
13930}
13931class Linker extends ParticlesInteractorBase {
13932 constructor(container) {
13933 super(container);
13934 this._setColor = p1 => {
13935 if (!p1.options.links) {
13936 return;
13937 }
13938 const container = this.linkContainer,
13939 linksOptions = p1.options.links;
13940 let linkColor = linksOptions.id === undefined ? container.particles.linksColor : container.particles.linksColors.get(linksOptions.id);
13941 if (linkColor) {
13942 return;
13943 }
13944 const optColor = linksOptions.color;
13945 linkColor = getLinkRandomColor(optColor, linksOptions.blink, linksOptions.consent);
13946 if (linksOptions.id === undefined) {
13947 container.particles.linksColor = linkColor;
13948 } else {
13949 container.particles.linksColors.set(linksOptions.id, linkColor);
13950 }
13951 };
13952 this.linkContainer = container;
13953 }
13954 clear() {}
13955 init() {
13956 this.linkContainer.particles.linksColor = undefined;
13957 this.linkContainer.particles.linksColors = new Map();
13958 }
13959 async interact(p1) {
13960 if (!p1.options.links) {
13961 return;
13962 }
13963 p1.links = [];
13964 const pos1 = p1.getPosition(),
13965 container = this.container,
13966 canvasSize = container.canvas.size;
13967 if (pos1.x < 0 || pos1.y < 0 || pos1.x > canvasSize.width || pos1.y > canvasSize.height) {
13968 return;
13969 }
13970 const linkOpt1 = p1.options.links,
13971 optOpacity = linkOpt1.opacity,
13972 optDistance = p1.retina.linksDistance ?? 0,
13973 warp = linkOpt1.warp,
13974 range = warp ? new CircleWarp(pos1.x, pos1.y, optDistance, canvasSize) : new Circle(pos1.x, pos1.y, optDistance),
13975 query = container.particles.quadTree.query(range);
13976 for (const p2 of query) {
13977 const linkOpt2 = p2.options.links;
13978 if (p1 === p2 || !linkOpt2?.enable || linkOpt1.id !== linkOpt2.id || p2.spawning || p2.destroyed || !p2.links || p1.links.some(t => t.destination === p2) || p2.links.some(t => t.destination === p1)) {
13979 continue;
13980 }
13981 const pos2 = p2.getPosition();
13982 if (pos2.x < 0 || pos2.y < 0 || pos2.x > canvasSize.width || pos2.y > canvasSize.height) {
13983 continue;
13984 }
13985 const distance = getLinkDistance(pos1, pos2, optDistance, canvasSize, warp && linkOpt2.warp);
13986 if (distance > optDistance) {
13987 continue;
13988 }
13989 const opacityLine = (1 - distance / optDistance) * optOpacity;
13990 this._setColor(p1);
13991 p1.links.push({
13992 destination: p2,
13993 opacity: opacityLine
13994 });
13995 }
13996 }
13997 isEnabled(particle) {
13998 return !!particle.options.links?.enable;
13999 }
14000 loadParticlesOptions(options, ...sources) {
14001 if (!options.links) {
14002 options.links = new Links();
14003 }
14004 for (const source of sources) {
14005 options.links.load(source?.links ?? source?.lineLinked ?? source?.line_linked);
14006 }
14007 }
14008 reset() {}
14009}
14010;// CONCATENATED MODULE: ../../interactions/particles/links/dist/esm/interaction.js
14011
14012async function loadLinksInteraction(engine, refresh = true) {
14013 await engine.addInteractor("particlesLinks", container => new Linker(container), refresh);
14014}
14015;// CONCATENATED MODULE: ../../interactions/particles/links/dist/esm/Utils.js
14016
14017function drawLinkLine(params) {
14018 let drawn = false;
14019 const {
14020 begin,
14021 end,
14022 maxDistance,
14023 context,
14024 canvasSize,
14025 width,
14026 backgroundMask,
14027 colorLine,
14028 opacity,
14029 links
14030 } = params;
14031 if (getDistance(begin, end) <= maxDistance) {
14032 drawLine(context, begin, end);
14033 drawn = true;
14034 } else if (links.warp) {
14035 let pi1;
14036 let pi2;
14037 const endNE = {
14038 x: end.x - canvasSize.width,
14039 y: end.y
14040 };
14041 const d1 = getDistances(begin, endNE);
14042 if (d1.distance <= maxDistance) {
14043 const yi = begin.y - d1.dy / d1.dx * begin.x;
14044 pi1 = {
14045 x: 0,
14046 y: yi
14047 };
14048 pi2 = {
14049 x: canvasSize.width,
14050 y: yi
14051 };
14052 } else {
14053 const endSW = {
14054 x: end.x,
14055 y: end.y - canvasSize.height
14056 };
14057 const d2 = getDistances(begin, endSW);
14058 if (d2.distance <= maxDistance) {
14059 const yi = begin.y - d2.dy / d2.dx * begin.x;
14060 const xi = -yi / (d2.dy / d2.dx);
14061 pi1 = {
14062 x: xi,
14063 y: 0
14064 };
14065 pi2 = {
14066 x: xi,
14067 y: canvasSize.height
14068 };
14069 } else {
14070 const endSE = {
14071 x: end.x - canvasSize.width,
14072 y: end.y - canvasSize.height
14073 };
14074 const d3 = getDistances(begin, endSE);
14075 if (d3.distance <= maxDistance) {
14076 const yi = begin.y - d3.dy / d3.dx * begin.x;
14077 const xi = -yi / (d3.dy / d3.dx);
14078 pi1 = {
14079 x: xi,
14080 y: yi
14081 };
14082 pi2 = {
14083 x: pi1.x + canvasSize.width,
14084 y: pi1.y + canvasSize.height
14085 };
14086 }
14087 }
14088 }
14089 if (pi1 && pi2) {
14090 drawLine(context, begin, pi1);
14091 drawLine(context, end, pi2);
14092 drawn = true;
14093 }
14094 }
14095 if (!drawn) {
14096 return;
14097 }
14098 context.lineWidth = width;
14099 if (backgroundMask.enable) {
14100 context.globalCompositeOperation = backgroundMask.composite;
14101 }
14102 context.strokeStyle = getStyleFromRgb(colorLine, opacity);
14103 const {
14104 shadow
14105 } = links;
14106 if (shadow.enable) {
14107 const shadowColor = rangeColorToRgb(shadow.color);
14108 if (shadowColor) {
14109 context.shadowBlur = shadow.blur;
14110 context.shadowColor = getStyleFromRgb(shadowColor);
14111 }
14112 }
14113 context.stroke();
14114}
14115function drawLinkTriangle(params) {
14116 const {
14117 context,
14118 pos1,
14119 pos2,
14120 pos3,
14121 backgroundMask,
14122 colorTriangle,
14123 opacityTriangle
14124 } = params;
14125 drawTriangle(context, pos1, pos2, pos3);
14126 if (backgroundMask.enable) {
14127 context.globalCompositeOperation = backgroundMask.composite;
14128 }
14129 context.fillStyle = getStyleFromRgb(colorTriangle, opacityTriangle);
14130 context.fill();
14131}
14132function getLinkKey(ids) {
14133 ids.sort((a, b) => a - b);
14134 return ids.join("_");
14135}
14136function setLinkFrequency(particles, dictionary) {
14137 const key = getLinkKey(particles.map(t => t.id));
14138 let res = dictionary.get(key);
14139 if (res === undefined) {
14140 res = getRandom();
14141 dictionary.set(key, res);
14142 }
14143 return res;
14144}
14145;// CONCATENATED MODULE: ../../interactions/particles/links/dist/esm/LinkInstance.js
14146
14147
14148class LinkInstance {
14149 constructor(container) {
14150 this.container = container;
14151 this._drawLinkLine = (p1, link) => {
14152 const p1LinksOptions = p1.options.links;
14153 if (!p1LinksOptions?.enable) {
14154 return;
14155 }
14156 const container = this.container,
14157 options = container.actualOptions,
14158 p2 = link.destination,
14159 pos1 = p1.getPosition(),
14160 pos2 = p2.getPosition();
14161 let opacity = link.opacity;
14162 container.canvas.draw(ctx => {
14163 let colorLine;
14164 const twinkle = p1.options.twinkle?.lines;
14165 if (twinkle?.enable) {
14166 const twinkleFreq = twinkle.frequency,
14167 twinkleRgb = rangeColorToRgb(twinkle.color),
14168 twinkling = getRandom() < twinkleFreq;
14169 if (twinkling && twinkleRgb) {
14170 colorLine = twinkleRgb;
14171 opacity = getRangeValue(twinkle.opacity);
14172 }
14173 }
14174 if (!colorLine) {
14175 const linkColor = p1LinksOptions.id !== undefined ? container.particles.linksColors.get(p1LinksOptions.id) : container.particles.linksColor;
14176 colorLine = getLinkColor(p1, p2, linkColor);
14177 }
14178 if (!colorLine) {
14179 return;
14180 }
14181 const width = p1.retina.linksWidth ?? 0,
14182 maxDistance = p1.retina.linksDistance ?? 0,
14183 {
14184 backgroundMask
14185 } = options;
14186 drawLinkLine({
14187 context: ctx,
14188 width,
14189 begin: pos1,
14190 end: pos2,
14191 maxDistance,
14192 canvasSize: container.canvas.size,
14193 links: p1LinksOptions,
14194 backgroundMask: backgroundMask,
14195 colorLine,
14196 opacity
14197 });
14198 });
14199 };
14200 this._drawLinkTriangle = (p1, link1, link2) => {
14201 const linksOptions = p1.options.links;
14202 if (!linksOptions?.enable) {
14203 return;
14204 }
14205 const triangleOptions = linksOptions.triangles;
14206 if (!triangleOptions.enable) {
14207 return;
14208 }
14209 const container = this.container,
14210 options = container.actualOptions,
14211 p2 = link1.destination,
14212 p3 = link2.destination,
14213 opacityTriangle = triangleOptions.opacity ?? (link1.opacity + link2.opacity) / 2;
14214 if (opacityTriangle <= 0) {
14215 return;
14216 }
14217 container.canvas.draw(ctx => {
14218 const pos1 = p1.getPosition(),
14219 pos2 = p2.getPosition(),
14220 pos3 = p3.getPosition(),
14221 linksDistance = p1.retina.linksDistance ?? 0;
14222 if (getDistance(pos1, pos2) > linksDistance || getDistance(pos3, pos2) > linksDistance || getDistance(pos3, pos1) > linksDistance) {
14223 return;
14224 }
14225 let colorTriangle = rangeColorToRgb(triangleOptions.color);
14226 if (!colorTriangle) {
14227 const linkColor = linksOptions.id !== undefined ? container.particles.linksColors.get(linksOptions.id) : container.particles.linksColor;
14228 colorTriangle = getLinkColor(p1, p2, linkColor);
14229 }
14230 if (!colorTriangle) {
14231 return;
14232 }
14233 drawLinkTriangle({
14234 context: ctx,
14235 pos1,
14236 pos2,
14237 pos3,
14238 backgroundMask: options.backgroundMask,
14239 colorTriangle,
14240 opacityTriangle
14241 });
14242 });
14243 };
14244 this._drawTriangles = (options, p1, link, p1Links) => {
14245 const p2 = link.destination;
14246 if (!(options.links?.triangles.enable && p2.options.links?.triangles.enable)) {
14247 return;
14248 }
14249 const vertices = p2.links?.filter(t => {
14250 const linkFreq = this._getLinkFrequency(p2, t.destination);
14251 return p2.options.links && linkFreq <= p2.options.links.frequency && p1Links.findIndex(l => l.destination === t.destination) >= 0;
14252 });
14253 if (!vertices?.length) {
14254 return;
14255 }
14256 for (const vertex of vertices) {
14257 const p3 = vertex.destination,
14258 triangleFreq = this._getTriangleFrequency(p1, p2, p3);
14259 if (triangleFreq > options.links.triangles.frequency) {
14260 continue;
14261 }
14262 this._drawLinkTriangle(p1, link, vertex);
14263 }
14264 };
14265 this._getLinkFrequency = (p1, p2) => {
14266 return setLinkFrequency([p1, p2], this._freqs.links);
14267 };
14268 this._getTriangleFrequency = (p1, p2, p3) => {
14269 return setLinkFrequency([p1, p2, p3], this._freqs.triangles);
14270 };
14271 this._freqs = {
14272 links: new Map(),
14273 triangles: new Map()
14274 };
14275 }
14276 drawParticle(context, particle) {
14277 const {
14278 links,
14279 options
14280 } = particle;
14281 if (!links || links.length <= 0) {
14282 return;
14283 }
14284 const p1Links = links.filter(l => options.links && this._getLinkFrequency(particle, l.destination) <= options.links.frequency);
14285 for (const link of p1Links) {
14286 this._drawTriangles(options, particle, link, p1Links);
14287 if (link.opacity > 0 && (particle.retina.linksWidth ?? 0) > 0) {
14288 this._drawLinkLine(particle, link);
14289 }
14290 }
14291 }
14292 async init() {
14293 this._freqs.links = new Map();
14294 this._freqs.triangles = new Map();
14295 }
14296 particleCreated(particle) {
14297 particle.links = [];
14298 if (!particle.options.links) {
14299 return;
14300 }
14301 const ratio = this.container.retina.pixelRatio,
14302 {
14303 retina
14304 } = particle,
14305 {
14306 distance,
14307 width
14308 } = particle.options.links;
14309 retina.linksDistance = distance * ratio;
14310 retina.linksWidth = width * ratio;
14311 }
14312 particleDestroyed(particle) {
14313 particle.links = [];
14314 }
14315}
14316;// CONCATENATED MODULE: ../../interactions/particles/links/dist/esm/plugin.js
14317
14318class LinksPlugin {
14319 constructor() {
14320 this.id = "links";
14321 }
14322 getPlugin(container) {
14323 return new LinkInstance(container);
14324 }
14325 loadOptions() {}
14326 needsPlugin() {
14327 return true;
14328 }
14329}
14330async function loadLinksPlugin(engine, refresh = true) {
14331 const plugin = new LinksPlugin();
14332 await engine.addPlugin(plugin, refresh);
14333}
14334;// CONCATENATED MODULE: ../../interactions/particles/links/dist/esm/index.js
14335
14336
14337async function loadParticlesLinksInteraction(engine, refresh = true) {
14338 await loadLinksInteraction(engine, refresh);
14339 await loadLinksPlugin(engine, refresh);
14340}
14341
14342
14343
14344
14345
14346
14347;// CONCATENATED MODULE: ../../shapes/polygon/dist/esm/PolygonDrawerBase.js
14348
14349class PolygonDrawerBase {
14350 draw(context, particle, radius) {
14351 const start = this.getCenter(particle, radius),
14352 side = this.getSidesData(particle, radius),
14353 sideCount = side.count.numerator * side.count.denominator,
14354 decimalSides = side.count.numerator / side.count.denominator,
14355 interiorAngleDegrees = 180 * (decimalSides - 2) / decimalSides,
14356 interiorAngle = Math.PI - Math.PI * interiorAngleDegrees / 180;
14357 if (!context) {
14358 return;
14359 }
14360 context.beginPath();
14361 context.translate(start.x, start.y);
14362 context.moveTo(0, 0);
14363 for (let i = 0; i < sideCount; i++) {
14364 context.lineTo(side.length, 0);
14365 context.translate(side.length, 0);
14366 context.rotate(interiorAngle);
14367 }
14368 }
14369 getSidesCount(particle) {
14370 const polygon = particle.shapeData;
14371 return Math.round(getRangeValue(polygon?.sides ?? polygon?.nb_sides ?? 5));
14372 }
14373}
14374;// CONCATENATED MODULE: ../../shapes/polygon/dist/esm/PolygonDrawer.js
14375
14376class PolygonDrawer extends PolygonDrawerBase {
14377 getCenter(particle, radius) {
14378 return {
14379 x: -radius / (particle.sides / 3.5),
14380 y: -radius / (2.66 / 3.5)
14381 };
14382 }
14383 getSidesData(particle, radius) {
14384 const sides = particle.sides;
14385 return {
14386 count: {
14387 denominator: 1,
14388 numerator: sides
14389 },
14390 length: radius * 2.66 / (sides / 3)
14391 };
14392 }
14393}
14394;// CONCATENATED MODULE: ../../shapes/polygon/dist/esm/TriangleDrawer.js
14395
14396class TriangleDrawer extends PolygonDrawerBase {
14397 getCenter(particle, radius) {
14398 return {
14399 x: -radius,
14400 y: radius / 1.66
14401 };
14402 }
14403 getSidesCount() {
14404 return 3;
14405 }
14406 getSidesData(particle, radius) {
14407 return {
14408 count: {
14409 denominator: 2,
14410 numerator: 3
14411 },
14412 length: radius * 2
14413 };
14414 }
14415}
14416;// CONCATENATED MODULE: ../../shapes/polygon/dist/esm/index.js
14417
14418
14419async function loadGenericPolygonShape(engine, refresh = true) {
14420 await engine.addShape("polygon", new PolygonDrawer(), refresh);
14421}
14422async function loadTriangleShape(engine, refresh = true) {
14423 await engine.addShape("triangle", new TriangleDrawer(), refresh);
14424}
14425async function loadPolygonShape(engine, refresh = true) {
14426 await loadGenericPolygonShape(engine, refresh);
14427 await loadTriangleShape(engine, refresh);
14428}
14429;// CONCATENATED MODULE: ../../updaters/rotate/dist/esm/Options/Classes/RotateAnimation.js
14430
14431class RotateAnimation {
14432 constructor() {
14433 this.enable = false;
14434 this.speed = 0;
14435 this.decay = 0;
14436 this.sync = false;
14437 }
14438 load(data) {
14439 if (!data) {
14440 return;
14441 }
14442 if (data.enable !== undefined) {
14443 this.enable = data.enable;
14444 }
14445 if (data.speed !== undefined) {
14446 this.speed = setRangeValue(data.speed);
14447 }
14448 if (data.decay !== undefined) {
14449 this.decay = setRangeValue(data.decay);
14450 }
14451 if (data.sync !== undefined) {
14452 this.sync = data.sync;
14453 }
14454 }
14455}
14456;// CONCATENATED MODULE: ../../updaters/rotate/dist/esm/Options/Classes/Rotate.js
14457
14458
14459class Rotate extends ValueWithRandom {
14460 constructor() {
14461 super();
14462 this.animation = new RotateAnimation();
14463 this.direction = "clockwise";
14464 this.path = false;
14465 this.value = 0;
14466 }
14467 load(data) {
14468 if (!data) {
14469 return;
14470 }
14471 super.load(data);
14472 if (data.direction !== undefined) {
14473 this.direction = data.direction;
14474 }
14475 this.animation.load(data.animation);
14476 if (data.path !== undefined) {
14477 this.path = data.path;
14478 }
14479 }
14480}
14481;// CONCATENATED MODULE: ../../updaters/rotate/dist/esm/RotateUpdater.js
14482
14483
14484function updateRotate(particle, delta) {
14485 const rotate = particle.rotate,
14486 rotateOptions = particle.options.rotate;
14487 if (!rotate || !rotateOptions) {
14488 return;
14489 }
14490 const rotateAnimation = rotateOptions.animation,
14491 speed = (rotate.velocity ?? 0) * delta.factor,
14492 max = 2 * Math.PI,
14493 decay = rotate.decay ?? 1;
14494 if (!rotateAnimation.enable) {
14495 return;
14496 }
14497 switch (rotate.status) {
14498 case "increasing":
14499 rotate.value += speed;
14500 if (rotate.value > max) {
14501 rotate.value -= max;
14502 }
14503 break;
14504 case "decreasing":
14505 default:
14506 rotate.value -= speed;
14507 if (rotate.value < 0) {
14508 rotate.value += max;
14509 }
14510 break;
14511 }
14512 if (rotate.velocity && decay !== 1) {
14513 rotate.velocity *= decay;
14514 }
14515}
14516class RotateUpdater {
14517 constructor(container) {
14518 this.container = container;
14519 }
14520 init(particle) {
14521 const rotateOptions = particle.options.rotate;
14522 if (!rotateOptions) {
14523 return;
14524 }
14525 particle.rotate = {
14526 enable: rotateOptions.animation.enable,
14527 value: getRangeValue(rotateOptions.value) * Math.PI / 180
14528 };
14529 particle.pathRotation = rotateOptions.path;
14530 let rotateDirection = rotateOptions.direction;
14531 if (rotateDirection === "random") {
14532 const index = Math.floor(getRandom() * 2);
14533 rotateDirection = index > 0 ? "counter-clockwise" : "clockwise";
14534 }
14535 switch (rotateDirection) {
14536 case "counter-clockwise":
14537 case "counterClockwise":
14538 particle.rotate.status = "decreasing";
14539 break;
14540 case "clockwise":
14541 particle.rotate.status = "increasing";
14542 break;
14543 }
14544 const rotateAnimation = rotateOptions.animation;
14545 if (rotateAnimation.enable) {
14546 particle.rotate.decay = 1 - getRangeValue(rotateAnimation.decay);
14547 particle.rotate.velocity = getRangeValue(rotateAnimation.speed) / 360 * this.container.retina.reduceFactor;
14548 if (!rotateAnimation.sync) {
14549 particle.rotate.velocity *= getRandom();
14550 }
14551 }
14552 particle.rotation = particle.rotate.value;
14553 }
14554 isEnabled(particle) {
14555 const rotate = particle.options.rotate;
14556 if (!rotate) {
14557 return false;
14558 }
14559 return !particle.destroyed && !particle.spawning && rotate.animation.enable && !rotate.path;
14560 }
14561 loadOptions(options, ...sources) {
14562 if (!options.rotate) {
14563 options.rotate = new Rotate();
14564 }
14565 for (const source of sources) {
14566 options.rotate.load(source?.rotate);
14567 }
14568 }
14569 update(particle, delta) {
14570 if (!this.isEnabled(particle)) {
14571 return;
14572 }
14573 updateRotate(particle, delta);
14574 particle.rotation = particle.rotate?.value ?? 0;
14575 }
14576}
14577;// CONCATENATED MODULE: ../../updaters/rotate/dist/esm/index.js
14578
14579async function loadRotateUpdater(engine, refresh = true) {
14580 await engine.addParticleUpdater("rotate", container => new RotateUpdater(container), refresh);
14581}
14582;// CONCATENATED MODULE: ../../shapes/square/dist/esm/SquareDrawer.js
14583const fixFactor = Math.sqrt(2);
14584class SquareDrawer {
14585 draw(context, particle, radius) {
14586 const fixedRadius = radius / fixFactor,
14587 fixedDiameter = fixedRadius * 2;
14588 context.rect(-fixedRadius, -fixedRadius, fixedDiameter, fixedDiameter);
14589 }
14590 getSidesCount() {
14591 return 4;
14592 }
14593}
14594;// CONCATENATED MODULE: ../../shapes/square/dist/esm/index.js
14595
14596async function loadSquareShape(engine, refresh = true) {
14597 await engine.addShape(["edge", "square"], new SquareDrawer(), refresh);
14598}
14599;// CONCATENATED MODULE: ../../shapes/star/dist/esm/StarDrawer.js
14600
14601class StarDrawer {
14602 draw(context, particle, radius) {
14603 const sides = particle.sides,
14604 inset = particle.starInset ?? 2;
14605 context.moveTo(0, 0 - radius);
14606 for (let i = 0; i < sides; i++) {
14607 context.rotate(Math.PI / sides);
14608 context.lineTo(0, 0 - radius * inset);
14609 context.rotate(Math.PI / sides);
14610 context.lineTo(0, 0 - radius);
14611 }
14612 }
14613 getSidesCount(particle) {
14614 const star = particle.shapeData;
14615 return Math.round(getRangeValue(star?.sides ?? star?.nb_sides ?? 5));
14616 }
14617 particleInit(container, particle) {
14618 const star = particle.shapeData,
14619 inset = getRangeValue(star?.inset ?? 2);
14620 particle.starInset = inset;
14621 }
14622}
14623;// CONCATENATED MODULE: ../../shapes/star/dist/esm/index.js
14624
14625async function loadStarShape(engine, refresh = true) {
14626 await engine.addShape("star", new StarDrawer(), refresh);
14627}
14628;// CONCATENATED MODULE: ../../updaters/strokeColor/dist/esm/Utils.js
14629
14630function Utils_updateColorValue(delta, colorValue, valueAnimation, max, decrease) {
14631 if (!colorValue || !valueAnimation.enable || (colorValue.maxLoops ?? 0) > 0 && (colorValue.loops ?? 0) > (colorValue.maxLoops ?? 0)) {
14632 return;
14633 }
14634 if (!colorValue.time) {
14635 colorValue.time = 0;
14636 }
14637 if ((colorValue.delayTime ?? 0) > 0 && colorValue.time < (colorValue.delayTime ?? 0)) {
14638 colorValue.time += delta.value;
14639 }
14640 if ((colorValue.delayTime ?? 0) > 0 && colorValue.time < (colorValue.delayTime ?? 0)) {
14641 return;
14642 }
14643 const offset = randomInRange(valueAnimation.offset),
14644 velocity = (colorValue.velocity ?? 0) * delta.factor + offset * 3.6,
14645 decay = colorValue.decay ?? 1;
14646 if (!decrease || colorValue.status === "increasing") {
14647 colorValue.value += velocity;
14648 if (colorValue.value > max) {
14649 if (!colorValue.loops) {
14650 colorValue.loops = 0;
14651 }
14652 colorValue.loops++;
14653 if (decrease) {
14654 colorValue.status = "decreasing";
14655 colorValue.value -= colorValue.value % max;
14656 }
14657 }
14658 } else {
14659 colorValue.value -= velocity;
14660 if (colorValue.value < 0) {
14661 if (!colorValue.loops) {
14662 colorValue.loops = 0;
14663 }
14664 colorValue.loops++;
14665 colorValue.status = "increasing";
14666 colorValue.value += colorValue.value;
14667 }
14668 }
14669 if (colorValue.velocity && decay !== 1) {
14670 colorValue.velocity *= decay;
14671 }
14672 if (colorValue.value > max) {
14673 colorValue.value %= max;
14674 }
14675}
14676function updateStrokeColor(particle, delta) {
14677 if (!particle.strokeColor || !particle.strokeAnimation) {
14678 return;
14679 }
14680 const {
14681 h,
14682 s,
14683 l
14684 } = particle.strokeColor,
14685 {
14686 h: hAnimation,
14687 s: sAnimation,
14688 l: lAnimation
14689 } = particle.strokeAnimation;
14690 if (h) {
14691 Utils_updateColorValue(delta, h, hAnimation, 360, false);
14692 }
14693 if (s) {
14694 Utils_updateColorValue(delta, s, sAnimation, 100, true);
14695 }
14696 if (l) {
14697 Utils_updateColorValue(delta, l, lAnimation, 100, true);
14698 }
14699}
14700;// CONCATENATED MODULE: ../../updaters/strokeColor/dist/esm/StrokeColorUpdater.js
14701
14702
14703class StrokeColorUpdater {
14704 constructor(container) {
14705 this.container = container;
14706 }
14707 init(particle) {
14708 const container = this.container,
14709 options = particle.options;
14710 const stroke = itemFromSingleOrMultiple(options.stroke, particle.id, options.reduceDuplicates);
14711 particle.strokeWidth = getRangeValue(stroke.width) * container.retina.pixelRatio;
14712 particle.strokeOpacity = getRangeValue(stroke.opacity ?? 1);
14713 particle.strokeAnimation = stroke.color?.animation;
14714 const strokeHslColor = rangeColorToHsl(stroke.color) ?? particle.getFillColor();
14715 if (strokeHslColor) {
14716 particle.strokeColor = getHslAnimationFromHsl(strokeHslColor, particle.strokeAnimation, container.retina.reduceFactor);
14717 }
14718 }
14719 isEnabled(particle) {
14720 const color = particle.strokeAnimation,
14721 {
14722 strokeColor
14723 } = particle;
14724 return !particle.destroyed && !particle.spawning && !!color && (strokeColor?.h.value !== undefined && strokeColor.h.enable || strokeColor?.s.value !== undefined && strokeColor.s.enable || strokeColor?.l.value !== undefined && strokeColor.l.enable);
14725 }
14726 update(particle, delta) {
14727 if (!this.isEnabled(particle)) {
14728 return;
14729 }
14730 updateStrokeColor(particle, delta);
14731 }
14732}
14733;// CONCATENATED MODULE: ../../updaters/strokeColor/dist/esm/index.js
14734
14735async function loadStrokeColorUpdater(engine, refresh = true) {
14736 await engine.addParticleUpdater("strokeColor", container => new StrokeColorUpdater(container), refresh);
14737}
14738;// CONCATENATED MODULE: ../../shapes/text/dist/esm/TextDrawer.js
14739
14740const validTypes = ["text", "character", "char"];
14741class TextDrawer {
14742 draw(context, particle, radius, opacity) {
14743 const character = particle.shapeData;
14744 if (character === undefined) {
14745 return;
14746 }
14747 const textData = character.value;
14748 if (textData === undefined) {
14749 return;
14750 }
14751 if (particle.text === undefined) {
14752 particle.text = itemFromSingleOrMultiple(textData, particle.randomIndexData);
14753 }
14754 const text = particle.text,
14755 style = character.style ?? "",
14756 weight = character.weight ?? "400",
14757 size = Math.round(radius) * 2,
14758 font = character.font ?? "Verdana",
14759 fill = particle.fill,
14760 offsetX = text.length * radius / 2;
14761 context.font = `${style} ${weight} ${size}px "${font}"`;
14762 const pos = {
14763 x: -offsetX,
14764 y: radius / 2
14765 };
14766 context.globalAlpha = opacity;
14767 if (fill) {
14768 context.fillText(text, pos.x, pos.y);
14769 } else {
14770 context.strokeText(text, pos.x, pos.y);
14771 }
14772 context.globalAlpha = 1;
14773 }
14774 getSidesCount() {
14775 return 12;
14776 }
14777 async init(container) {
14778 const options = container.actualOptions;
14779 if (validTypes.find(t => isInArray(t, options.particles.shape.type))) {
14780 const shapeOptions = validTypes.map(t => options.particles.shape.options[t]).find(t => !!t),
14781 promises = [];
14782 executeOnSingleOrMultiple(shapeOptions, shape => {
14783 promises.push(loadFont(shape.font, shape.weight));
14784 });
14785 await Promise.all(promises);
14786 }
14787 }
14788 particleInit(container, particle) {
14789 if (!particle.shape || !validTypes.includes(particle.shape)) {
14790 return;
14791 }
14792 const character = particle.shapeData;
14793 if (character === undefined) {
14794 return;
14795 }
14796 const textData = character.value;
14797 if (textData === undefined) {
14798 return;
14799 }
14800 particle.text = itemFromSingleOrMultiple(textData, particle.randomIndexData);
14801 }
14802}
14803;// CONCATENATED MODULE: ../../shapes/text/dist/esm/index.js
14804
14805async function loadTextShape(engine, refresh = true) {
14806 await engine.addShape(validTypes, new TextDrawer(), refresh);
14807}
14808;// CONCATENATED MODULE: ../slim/dist/esm/index.js
14809
14810
14811
14812
14813
14814
14815
14816
14817
14818
14819
14820
14821
14822
14823
14824
14825
14826
14827
14828
14829
14830
14831
14832
14833
14834
14835async function loadSlim(engine, refresh = true) {
14836 initPjs(engine);
14837 await loadParallaxMover(engine, false);
14838 await loadExternalAttractInteraction(engine, false);
14839 await loadExternalBounceInteraction(engine, false);
14840 await loadExternalBubbleInteraction(engine, false);
14841 await loadExternalConnectInteraction(engine, false);
14842 await loadExternalGrabInteraction(engine, false);
14843 await loadExternalPauseInteraction(engine, false);
14844 await loadExternalPushInteraction(engine, false);
14845 await loadExternalRemoveInteraction(engine, false);
14846 await loadExternalRepulseInteraction(engine, false);
14847 await loadExternalSlowInteraction(engine, false);
14848 await loadParticlesAttractInteraction(engine, false);
14849 await loadParticlesCollisionsInteraction(engine, false);
14850 await loadParticlesLinksInteraction(engine, false);
14851 await loadEasingQuadPlugin();
14852 await loadImageShape(engine, false);
14853 await loadLineShape(engine, false);
14854 await loadPolygonShape(engine, false);
14855 await loadSquareShape(engine, false);
14856 await loadStarShape(engine, false);
14857 await loadTextShape(engine, false);
14858 await loadLifeUpdater(engine, false);
14859 await loadRotateUpdater(engine, false);
14860 await loadStrokeColorUpdater(engine, false);
14861 await loadBasic(engine, refresh);
14862}
14863;// CONCATENATED MODULE: ../../updaters/tilt/dist/esm/Options/Classes/TiltAnimation.js
14864
14865class TiltAnimation {
14866 constructor() {
14867 this.enable = false;
14868 this.speed = 0;
14869 this.decay = 0;
14870 this.sync = false;
14871 }
14872 load(data) {
14873 if (!data) {
14874 return;
14875 }
14876 if (data.enable !== undefined) {
14877 this.enable = data.enable;
14878 }
14879 if (data.speed !== undefined) {
14880 this.speed = setRangeValue(data.speed);
14881 }
14882 if (data.decay !== undefined) {
14883 this.decay = setRangeValue(data.decay);
14884 }
14885 if (data.sync !== undefined) {
14886 this.sync = data.sync;
14887 }
14888 }
14889}
14890;// CONCATENATED MODULE: ../../updaters/tilt/dist/esm/Options/Classes/Tilt.js
14891
14892
14893class Tilt extends ValueWithRandom {
14894 constructor() {
14895 super();
14896 this.animation = new TiltAnimation();
14897 this.direction = "clockwise";
14898 this.enable = false;
14899 this.value = 0;
14900 }
14901 load(data) {
14902 super.load(data);
14903 if (!data) {
14904 return;
14905 }
14906 this.animation.load(data.animation);
14907 if (data.direction !== undefined) {
14908 this.direction = data.direction;
14909 }
14910 if (data.enable !== undefined) {
14911 this.enable = data.enable;
14912 }
14913 }
14914}
14915;// CONCATENATED MODULE: ../../updaters/tilt/dist/esm/Utils.js
14916function updateTilt(particle, delta) {
14917 if (!particle.tilt || !particle.options.tilt) {
14918 return;
14919 }
14920 const tilt = particle.options.tilt,
14921 tiltAnimation = tilt.animation,
14922 speed = (particle.tilt.velocity ?? 0) * delta.factor,
14923 max = 2 * Math.PI,
14924 decay = particle.tilt.decay ?? 1;
14925 if (!tiltAnimation.enable) {
14926 return;
14927 }
14928 switch (particle.tilt.status) {
14929 case "increasing":
14930 particle.tilt.value += speed;
14931 if (particle.tilt.value > max) {
14932 particle.tilt.value -= max;
14933 }
14934 break;
14935 case "decreasing":
14936 default:
14937 particle.tilt.value -= speed;
14938 if (particle.tilt.value < 0) {
14939 particle.tilt.value += max;
14940 }
14941 break;
14942 }
14943 if (particle.tilt.velocity && decay !== 1) {
14944 particle.tilt.velocity *= decay;
14945 }
14946}
14947;// CONCATENATED MODULE: ../../updaters/tilt/dist/esm/TiltUpdater.js
14948
14949
14950
14951class TiltUpdater {
14952 constructor(container) {
14953 this.container = container;
14954 }
14955 getTransformValues(particle) {
14956 const tilt = particle.tilt?.enable && particle.tilt;
14957 return {
14958 b: tilt ? Math.cos(tilt.value) * tilt.cosDirection : undefined,
14959 c: tilt ? Math.sin(tilt.value) * tilt.sinDirection : undefined
14960 };
14961 }
14962 init(particle) {
14963 const tiltOptions = particle.options.tilt;
14964 if (!tiltOptions) {
14965 return;
14966 }
14967 particle.tilt = {
14968 enable: tiltOptions.enable,
14969 value: getRangeValue(tiltOptions.value) * Math.PI / 180,
14970 sinDirection: getRandom() >= 0.5 ? 1 : -1,
14971 cosDirection: getRandom() >= 0.5 ? 1 : -1
14972 };
14973 let tiltDirection = tiltOptions.direction;
14974 if (tiltDirection === "random") {
14975 const index = Math.floor(getRandom() * 2);
14976 tiltDirection = index > 0 ? "counter-clockwise" : "clockwise";
14977 }
14978 switch (tiltDirection) {
14979 case "counter-clockwise":
14980 case "counterClockwise":
14981 particle.tilt.status = "decreasing";
14982 break;
14983 case "clockwise":
14984 particle.tilt.status = "increasing";
14985 break;
14986 }
14987 const tiltAnimation = particle.options.tilt?.animation;
14988 if (tiltAnimation?.enable) {
14989 particle.tilt.decay = 1 - getRangeValue(tiltAnimation.decay);
14990 particle.tilt.velocity = getRangeValue(tiltAnimation.speed) / 360 * this.container.retina.reduceFactor;
14991 if (!tiltAnimation.sync) {
14992 particle.tilt.velocity *= getRandom();
14993 }
14994 }
14995 }
14996 isEnabled(particle) {
14997 const tiltAnimation = particle.options.tilt?.animation;
14998 return !particle.destroyed && !particle.spawning && !!tiltAnimation?.enable;
14999 }
15000 loadOptions(options, ...sources) {
15001 if (!options.tilt) {
15002 options.tilt = new Tilt();
15003 }
15004 for (const source of sources) {
15005 options.tilt.load(source?.tilt);
15006 }
15007 }
15008 update(particle, delta) {
15009 if (!this.isEnabled(particle)) {
15010 return;
15011 }
15012 updateTilt(particle, delta);
15013 }
15014}
15015;// CONCATENATED MODULE: ../../updaters/tilt/dist/esm/index.js
15016
15017async function loadTiltUpdater(engine, refresh = true) {
15018 await engine.addParticleUpdater("tilt", container => new TiltUpdater(container), refresh);
15019}
15020;// CONCATENATED MODULE: ../../updaters/twinkle/dist/esm/Options/Classes/TwinkleValues.js
15021
15022class TwinkleValues {
15023 constructor() {
15024 this.enable = false;
15025 this.frequency = 0.05;
15026 this.opacity = 1;
15027 }
15028 load(data) {
15029 if (!data) {
15030 return;
15031 }
15032 if (data.color !== undefined) {
15033 this.color = OptionsColor.create(this.color, data.color);
15034 }
15035 if (data.enable !== undefined) {
15036 this.enable = data.enable;
15037 }
15038 if (data.frequency !== undefined) {
15039 this.frequency = data.frequency;
15040 }
15041 if (data.opacity !== undefined) {
15042 this.opacity = setRangeValue(data.opacity);
15043 }
15044 }
15045}
15046;// CONCATENATED MODULE: ../../updaters/twinkle/dist/esm/Options/Classes/Twinkle.js
15047
15048class Twinkle {
15049 constructor() {
15050 this.lines = new TwinkleValues();
15051 this.particles = new TwinkleValues();
15052 }
15053 load(data) {
15054 if (!data) {
15055 return;
15056 }
15057 this.lines.load(data.lines);
15058 this.particles.load(data.particles);
15059 }
15060}
15061;// CONCATENATED MODULE: ../../updaters/twinkle/dist/esm/TwinkleUpdater.js
15062
15063
15064class TwinkleUpdater {
15065 getColorStyles(particle, context, radius, opacity) {
15066 const pOptions = particle.options,
15067 twinkleOptions = pOptions.twinkle;
15068 if (!twinkleOptions) {
15069 return {};
15070 }
15071 const twinkle = twinkleOptions.particles,
15072 twinkling = twinkle.enable && getRandom() < twinkle.frequency,
15073 zIndexOptions = particle.options.zIndex,
15074 zOpacityFactor = (1 - particle.zIndexFactor) ** zIndexOptions.opacityRate,
15075 twinklingOpacity = twinkling ? getRangeValue(twinkle.opacity) * zOpacityFactor : opacity,
15076 twinkleRgb = rangeColorToHsl(twinkle.color),
15077 twinkleStyle = twinkleRgb ? ColorUtils_getStyleFromHsl(twinkleRgb, twinklingOpacity) : undefined,
15078 res = {},
15079 needsTwinkle = twinkling && twinkleStyle;
15080 res.fill = needsTwinkle ? twinkleStyle : undefined;
15081 res.stroke = needsTwinkle ? twinkleStyle : undefined;
15082 return res;
15083 }
15084 init() {}
15085 isEnabled(particle) {
15086 const pOptions = particle.options,
15087 twinkleOptions = pOptions.twinkle;
15088 if (!twinkleOptions) {
15089 return false;
15090 }
15091 return twinkleOptions.particles.enable;
15092 }
15093 loadOptions(options, ...sources) {
15094 if (!options.twinkle) {
15095 options.twinkle = new Twinkle();
15096 }
15097 for (const source of sources) {
15098 options.twinkle.load(source?.twinkle);
15099 }
15100 }
15101 update() {}
15102}
15103;// CONCATENATED MODULE: ../../updaters/twinkle/dist/esm/index.js
15104
15105async function loadTwinkleUpdater(engine, refresh = true) {
15106 await engine.addParticleUpdater("twinkle", () => new TwinkleUpdater(), refresh);
15107}
15108;// CONCATENATED MODULE: ../../updaters/wobble/dist/esm/Options/Classes/WobbleSpeed.js
15109
15110class WobbleSpeed {
15111 constructor() {
15112 this.angle = 50;
15113 this.move = 10;
15114 }
15115 load(data) {
15116 if (!data) {
15117 return;
15118 }
15119 if (data.angle !== undefined) {
15120 this.angle = setRangeValue(data.angle);
15121 }
15122 if (data.move !== undefined) {
15123 this.move = setRangeValue(data.move);
15124 }
15125 }
15126}
15127;// CONCATENATED MODULE: ../../updaters/wobble/dist/esm/Options/Classes/Wobble.js
15128
15129
15130class Wobble {
15131 constructor() {
15132 this.distance = 5;
15133 this.enable = false;
15134 this.speed = new WobbleSpeed();
15135 }
15136 load(data) {
15137 if (!data) {
15138 return;
15139 }
15140 if (data.distance !== undefined) {
15141 this.distance = setRangeValue(data.distance);
15142 }
15143 if (data.enable !== undefined) {
15144 this.enable = data.enable;
15145 }
15146 if (data.speed !== undefined) {
15147 if (isNumber(data.speed)) {
15148 this.speed.load({
15149 angle: data.speed
15150 });
15151 } else {
15152 const rangeSpeed = data.speed;
15153 if (rangeSpeed.min !== undefined) {
15154 this.speed.load({
15155 angle: rangeSpeed
15156 });
15157 } else {
15158 this.speed.load(data.speed);
15159 }
15160 }
15161 }
15162 }
15163}
15164;// CONCATENATED MODULE: ../../updaters/wobble/dist/esm/Utils.js
15165function updateWobble(particle, delta) {
15166 const {
15167 wobble: wobbleOptions
15168 } = particle.options,
15169 {
15170 wobble
15171 } = particle;
15172 if (!wobbleOptions?.enable || !wobble) {
15173 return;
15174 }
15175 const angleSpeed = wobble.angleSpeed * delta.factor,
15176 moveSpeed = wobble.moveSpeed * delta.factor,
15177 distance = moveSpeed * ((particle.retina.wobbleDistance ?? 0) * delta.factor) / (1000 / 60),
15178 max = 2 * Math.PI,
15179 {
15180 position
15181 } = particle;
15182 wobble.angle += angleSpeed;
15183 if (wobble.angle > max) {
15184 wobble.angle -= max;
15185 }
15186 position.x += distance * Math.cos(wobble.angle);
15187 position.y += distance * Math.abs(Math.sin(wobble.angle));
15188}
15189;// CONCATENATED MODULE: ../../updaters/wobble/dist/esm/WobbleUpdater.js
15190
15191
15192
15193class WobbleUpdater {
15194 constructor(container) {
15195 this.container = container;
15196 }
15197 init(particle) {
15198 const wobbleOpt = particle.options.wobble;
15199 if (wobbleOpt?.enable) {
15200 particle.wobble = {
15201 angle: getRandom() * Math.PI * 2,
15202 angleSpeed: getRangeValue(wobbleOpt.speed.angle) / 360,
15203 moveSpeed: getRangeValue(wobbleOpt.speed.move) / 10
15204 };
15205 } else {
15206 particle.wobble = {
15207 angle: 0,
15208 angleSpeed: 0,
15209 moveSpeed: 0
15210 };
15211 }
15212 particle.retina.wobbleDistance = getRangeValue(wobbleOpt?.distance ?? 0) * this.container.retina.pixelRatio;
15213 }
15214 isEnabled(particle) {
15215 return !particle.destroyed && !particle.spawning && !!particle.options.wobble?.enable;
15216 }
15217 loadOptions(options, ...sources) {
15218 if (!options.wobble) {
15219 options.wobble = new Wobble();
15220 }
15221 for (const source of sources) {
15222 options.wobble.load(source?.wobble);
15223 }
15224 }
15225 update(particle, delta) {
15226 if (!this.isEnabled(particle)) {
15227 return;
15228 }
15229 updateWobble(particle, delta);
15230 }
15231}
15232;// CONCATENATED MODULE: ../../updaters/wobble/dist/esm/index.js
15233
15234async function loadWobbleUpdater(engine, refresh = true) {
15235 await engine.addParticleUpdater("wobble", container => new WobbleUpdater(container), refresh);
15236}
15237;// CONCATENATED MODULE: ../full/dist/esm/index.js
15238
15239
15240
15241
15242
15243
15244
15245
15246
15247async function loadFull(engine, refresh = true) {
15248 await loadDestroyUpdater(engine, false);
15249 await loadRollUpdater(engine, false);
15250 await loadTiltUpdater(engine, false);
15251 await loadTwinkleUpdater(engine, false);
15252 await loadWobbleUpdater(engine, false);
15253 await loadExternalTrailInteraction(engine, false);
15254 await loadAbsorbersPlugin(engine, false);
15255 await loadEmittersPlugin(engine, false);
15256 await loadSlim(engine, refresh);
15257}
15258;// CONCATENATED MODULE: ../../updaters/gradient/dist/esm/Options/Classes/GradientColorOpacityAnimation.js
15259
15260class GradientColorOpacityAnimation {
15261 constructor() {
15262 this.count = 0;
15263 this.enable = false;
15264 this.speed = 0;
15265 this.decay = 0;
15266 this.delay = 0;
15267 this.sync = false;
15268 this.startValue = "random";
15269 }
15270 load(data) {
15271 if (!data) {
15272 return;
15273 }
15274 if (data.count !== undefined) {
15275 this.count = setRangeValue(data.count);
15276 }
15277 if (data.enable !== undefined) {
15278 this.enable = data.enable;
15279 }
15280 if (data.speed !== undefined) {
15281 this.speed = setRangeValue(data.speed);
15282 }
15283 if (data.sync !== undefined) {
15284 this.sync = data.sync;
15285 }
15286 if (data.startValue !== undefined) {
15287 this.startValue = data.startValue;
15288 }
15289 if (data.decay !== undefined) {
15290 this.decay = setRangeValue(data.decay);
15291 }
15292 if (data.delay !== undefined) {
15293 this.delay = setRangeValue(data.delay);
15294 }
15295 }
15296}
15297;// CONCATENATED MODULE: ../../updaters/gradient/dist/esm/Options/Classes/GradientColorOpacity.js
15298
15299
15300class GradientColorOpacity {
15301 constructor() {
15302 this.value = 0;
15303 this.animation = new GradientColorOpacityAnimation();
15304 }
15305 load(data) {
15306 if (!data) {
15307 return;
15308 }
15309 this.animation.load(data.animation);
15310 if (data.value !== undefined) {
15311 this.value = setRangeValue(data.value);
15312 }
15313 }
15314}
15315;// CONCATENATED MODULE: ../../updaters/gradient/dist/esm/Options/Classes/AnimatableGradientColor.js
15316
15317
15318class AnimatableGradientColor {
15319 constructor() {
15320 this.stop = 0;
15321 this.value = new AnimatableColor();
15322 }
15323 load(data) {
15324 if (!data) {
15325 return;
15326 }
15327 if (data.stop !== undefined) {
15328 this.stop = data.stop;
15329 }
15330 this.value = AnimatableColor.create(this.value, data.value);
15331 if (data.opacity !== undefined) {
15332 this.opacity = new GradientColorOpacity();
15333 if (isNumber(data.opacity)) {
15334 this.opacity.value = data.opacity;
15335 } else {
15336 this.opacity.load(data.opacity);
15337 }
15338 }
15339 }
15340}
15341;// CONCATENATED MODULE: ../../updaters/gradient/dist/esm/Options/Classes/GradientAngleAnimation.js
15342
15343class GradientAngleAnimation {
15344 constructor() {
15345 this.count = 0;
15346 this.enable = false;
15347 this.speed = 0;
15348 this.decay = 0;
15349 this.delay = 0;
15350 this.sync = false;
15351 }
15352 load(data) {
15353 if (!data) {
15354 return;
15355 }
15356 if (data.count !== undefined) {
15357 this.count = setRangeValue(data.count);
15358 }
15359 if (data.enable !== undefined) {
15360 this.enable = data.enable;
15361 }
15362 if (data.speed !== undefined) {
15363 this.speed = setRangeValue(data.speed);
15364 }
15365 if (data.decay !== undefined) {
15366 this.decay = setRangeValue(data.decay);
15367 }
15368 if (data.delay !== undefined) {
15369 this.delay = setRangeValue(data.delay);
15370 }
15371 if (data.sync !== undefined) {
15372 this.sync = data.sync;
15373 }
15374 }
15375}
15376;// CONCATENATED MODULE: ../../updaters/gradient/dist/esm/Options/Classes/GradientAngle.js
15377
15378
15379class GradientAngle {
15380 constructor() {
15381 this.value = 0;
15382 this.animation = new GradientAngleAnimation();
15383 this.direction = "clockwise";
15384 }
15385 load(data) {
15386 if (!data) {
15387 return;
15388 }
15389 this.animation.load(data.animation);
15390 if (data.value !== undefined) {
15391 this.value = setRangeValue(data.value);
15392 }
15393 if (data.direction !== undefined) {
15394 this.direction = data.direction;
15395 }
15396 }
15397}
15398;// CONCATENATED MODULE: ../../updaters/gradient/dist/esm/Options/Classes/AnimatableGradient.js
15399
15400
15401class AnimatableGradient {
15402 constructor() {
15403 this.angle = new GradientAngle();
15404 this.colors = [];
15405 this.type = "random";
15406 }
15407 load(data) {
15408 if (!data) {
15409 return;
15410 }
15411 this.angle.load(data.angle);
15412 if (data.colors !== undefined) {
15413 this.colors = data.colors.map(s => {
15414 const tmp = new AnimatableGradientColor();
15415 tmp.load(s);
15416 return tmp;
15417 });
15418 }
15419 if (data.type !== undefined) {
15420 this.type = data.type;
15421 }
15422 }
15423}
15424;// CONCATENATED MODULE: ../../updaters/gradient/dist/esm/Utils.js
15425function updateColorOpacity(delta, value) {
15426 if (!value.enable) {
15427 return;
15428 }
15429 const decay = value.decay ?? 1;
15430 switch (value.status) {
15431 case "increasing":
15432 if (value.value >= value.max) {
15433 value.status = "decreasing";
15434 } else {
15435 value.value += (value.velocity ?? 0) * delta.factor;
15436 }
15437 break;
15438 case "decreasing":
15439 if (value.value <= value.min) {
15440 value.status = "increasing";
15441 } else {
15442 value.value -= (value.velocity ?? 0) * delta.factor;
15443 }
15444 break;
15445 }
15446 if (value.velocity && decay !== 1) {
15447 value.velocity *= decay;
15448 }
15449}
15450function esm_Utils_updateColorValue(delta, colorValue, max, decrease) {
15451 if (!colorValue || !colorValue.enable) {
15452 return;
15453 }
15454 if (!colorValue.time) {
15455 colorValue.time = 0;
15456 }
15457 if ((colorValue.delayTime ?? 0) > 0 && colorValue.time < (colorValue.delayTime ?? 0)) {
15458 colorValue.time += delta.value;
15459 }
15460 if ((colorValue.delayTime ?? 0) > 0 && colorValue.time < (colorValue.delayTime ?? 0)) {
15461 return;
15462 }
15463 const velocity = (colorValue.velocity ?? 0) * delta.factor,
15464 decay = colorValue.decay ?? 1;
15465 if (!decrease || colorValue.status === "increasing") {
15466 colorValue.value += velocity;
15467 if (decrease && colorValue.value > max) {
15468 colorValue.status = "decreasing";
15469 colorValue.value -= colorValue.value % max;
15470 }
15471 } else {
15472 colorValue.value -= velocity;
15473 if (colorValue.value < 0) {
15474 colorValue.status = "increasing";
15475 colorValue.value += colorValue.value;
15476 }
15477 }
15478 if (colorValue.value > max) {
15479 colorValue.value %= max;
15480 }
15481 if (colorValue.velocity && decay !== 1) {
15482 colorValue.velocity *= decay;
15483 }
15484}
15485function updateAngle(delta, angle) {
15486 const speed = (angle.velocity ?? 0) * delta.factor,
15487 max = 2 * Math.PI,
15488 decay = angle.decay ?? 1;
15489 if (!angle.enable) {
15490 return;
15491 }
15492 switch (angle.status) {
15493 case "increasing":
15494 angle.value += speed;
15495 if (angle.value > max) {
15496 angle.value -= max;
15497 }
15498 break;
15499 case "decreasing":
15500 default:
15501 angle.value -= speed;
15502 if (angle.value < 0) {
15503 angle.value += max;
15504 }
15505 break;
15506 }
15507 if (angle.velocity && decay !== 1) {
15508 angle.velocity *= decay;
15509 }
15510}
15511function updateGradient(particle, delta) {
15512 const {
15513 gradient
15514 } = particle;
15515 if (!gradient) {
15516 return;
15517 }
15518 updateAngle(delta, gradient.angle);
15519 for (const color of gradient.colors) {
15520 if (particle.color?.h !== undefined) {
15521 esm_Utils_updateColorValue(delta, color.value.h, 360, false);
15522 }
15523 if (particle.color?.s !== undefined) {
15524 esm_Utils_updateColorValue(delta, color.value.s, 100, true);
15525 }
15526 if (particle.color?.l !== undefined) {
15527 esm_Utils_updateColorValue(delta, color.value.l, 100, true);
15528 }
15529 if (color.opacity) {
15530 updateColorOpacity(delta, color.opacity);
15531 }
15532 }
15533}
15534;// CONCATENATED MODULE: ../../updaters/gradient/dist/esm/GradientUpdater.js
15535
15536
15537
15538class GradientUpdater {
15539 getColorStyles(particle, context, radius, opacity) {
15540 const gradient = particle.gradient;
15541 if (!gradient) {
15542 return {};
15543 }
15544 const gradientAngle = gradient.angle.value,
15545 fillGradient = gradient.type === "radial" ? context.createRadialGradient(0, 0, 0, 0, 0, radius) : context.createLinearGradient(Math.cos(gradientAngle) * -radius, Math.sin(gradientAngle) * -radius, Math.cos(gradientAngle) * radius, Math.sin(gradientAngle) * radius);
15546 for (const {
15547 stop,
15548 value,
15549 opacity: cOpacity
15550 } of gradient.colors) {
15551 fillGradient.addColorStop(stop, ColorUtils_getStyleFromHsl({
15552 h: value.h.value,
15553 s: value.s.value,
15554 l: value.l.value
15555 }, cOpacity?.value ?? opacity));
15556 }
15557 return {
15558 fill: fillGradient
15559 };
15560 }
15561 init(particle) {
15562 const gradient = itemFromSingleOrMultiple(particle.options.gradient);
15563 if (!gradient) {
15564 return;
15565 }
15566 const {
15567 angle
15568 } = gradient;
15569 particle.gradient = {
15570 angle: {
15571 value: getRangeValue(angle.value),
15572 enable: angle.animation.enable,
15573 velocity: getRangeValue(angle.animation.speed) / 360 * particle.container.retina.reduceFactor,
15574 decay: 1 - getRangeValue(angle.animation.decay),
15575 delayTime: getRangeValue(angle.animation.delay) * 1000,
15576 time: 0
15577 },
15578 type: gradient.type,
15579 colors: []
15580 };
15581 let rotateDirection = gradient.angle.direction;
15582 if (rotateDirection === "random") {
15583 rotateDirection = getRandom() > 0.5 ? "counter-clockwise" : "clockwise";
15584 }
15585 switch (rotateDirection) {
15586 case "counter-clockwise":
15587 case "counterClockwise":
15588 particle.gradient.angle.status = "decreasing";
15589 break;
15590 case "clockwise":
15591 particle.gradient.angle.status = "increasing";
15592 break;
15593 }
15594 const reduceDuplicates = particle.options.reduceDuplicates;
15595 for (const grColor of gradient.colors) {
15596 const grHslColor = rangeColorToHsl(grColor.value, particle.id, reduceDuplicates);
15597 if (!grHslColor) {
15598 continue;
15599 }
15600 const grHslAnimation = getHslAnimationFromHsl(grHslColor, grColor.value.animation, particle.container.retina.reduceFactor),
15601 addColor = {
15602 stop: grColor.stop,
15603 value: grHslAnimation,
15604 opacity: grColor.opacity ? {
15605 enable: grColor.opacity.animation.enable,
15606 max: getRangeMax(grColor.opacity.value),
15607 min: getRangeMin(grColor.opacity.value),
15608 status: "increasing",
15609 value: getRangeValue(grColor.opacity.value),
15610 velocity: getRangeValue(grColor.opacity.animation.speed) / 100 * particle.container.retina.reduceFactor,
15611 decay: 1 - getRangeValue(grColor.opacity.animation.decay),
15612 delayTime: getRangeValue(grColor.opacity.animation.delay) * 1000,
15613 time: 0
15614 } : undefined
15615 };
15616 const {
15617 opacity: addOpacity
15618 } = addColor;
15619 if (grColor.opacity && addOpacity) {
15620 const opacityRange = grColor.opacity.value;
15621 addOpacity.min = getRangeMin(opacityRange);
15622 addOpacity.max = getRangeMax(opacityRange);
15623 const opacityAnimation = grColor.opacity.animation;
15624 switch (opacityAnimation.startValue) {
15625 case "min":
15626 addOpacity.value = addOpacity.min;
15627 addOpacity.status = "increasing";
15628 break;
15629 case "max":
15630 addOpacity.value = addOpacity.max;
15631 addOpacity.status = "decreasing";
15632 break;
15633 case "random":
15634 default:
15635 addOpacity.value = randomInRange(addOpacity);
15636 addOpacity.status = getRandom() >= 0.5 ? "increasing" : "decreasing";
15637 break;
15638 }
15639 }
15640 particle.gradient.colors.push(addColor);
15641 }
15642 }
15643 isEnabled(particle) {
15644 return !particle.destroyed && !particle.spawning && (particle.gradient?.angle.enable || (particle.gradient?.colors.some(c => c.value.h.enable || c.value.s.enable || c.value.l.enable) ?? false));
15645 }
15646 loadOptions(options, ...sources) {
15647 for (const source of sources) {
15648 if (!source?.gradient) {
15649 continue;
15650 }
15651 const gradientToLoad = source.gradient;
15652 if (!gradientToLoad) {
15653 continue;
15654 }
15655 options.gradient = executeOnSingleOrMultiple(gradientToLoad, gradient => {
15656 const tmp = new AnimatableGradient();
15657 tmp.load(gradient);
15658 return tmp;
15659 });
15660 }
15661 }
15662 update(particle, delta) {
15663 updateGradient(particle, delta);
15664 }
15665}
15666;// CONCATENATED MODULE: ../../updaters/gradient/dist/esm/index.js
15667
15668async function loadGradientUpdater(engine, refresh = true) {
15669 await engine.addParticleUpdater("gradient", () => new GradientUpdater(), refresh);
15670}
15671;// CONCATENATED MODULE: ../../shapes/heart/dist/esm/HeartDrawer.js
15672class HeartDrawer_HeartDrawer {
15673 draw(context, _particle, radius) {
15674 const x = -radius,
15675 y = -radius;
15676 context.moveTo(x, y + radius / 2);
15677 context.quadraticCurveTo(x, y, x + radius / 2, y);
15678 context.quadraticCurveTo(x + radius, y, x + radius, y + radius / 2);
15679 context.quadraticCurveTo(x + radius, y, x + radius * 3 / 2, y);
15680 context.quadraticCurveTo(x + radius * 2, y, x + radius * 2, y + radius / 2);
15681 context.quadraticCurveTo(x + radius * 2, y + radius, x + radius * 3 / 2, y + radius * 3 / 2);
15682 context.lineTo(x + radius, y + radius * 2);
15683 context.lineTo(x + radius / 2, y + radius * 3 / 2);
15684 context.quadraticCurveTo(x, y + radius, x, y + radius / 2);
15685 }
15686}
15687;// CONCATENATED MODULE: ../../shapes/heart/dist/esm/index.js
15688
15689async function loadHeartShape(engine, refresh = true) {
15690 await engine.addShape("heart", new HeartDrawer_HeartDrawer(), refresh);
15691}
15692;// CONCATENATED MODULE: ../../plugins/hsvColor/dist/esm/HsvColorManager.js
15693
15694function rgbToHsv(rgb) {
15695 const rgbPercent = {
15696 r: rgb.r / 255,
15697 g: rgb.g / 255,
15698 b: rgb.b / 255
15699 },
15700 xMax = Math.max(rgbPercent.r, rgbPercent.g, rgbPercent.b),
15701 xMin = Math.min(rgbPercent.r, rgbPercent.g, rgbPercent.b),
15702 v = xMax,
15703 c = xMax - xMin;
15704 let h = 0;
15705 if (v === rgbPercent.r) {
15706 h = 60 * ((rgbPercent.g - rgbPercent.b) / c);
15707 } else if (v === rgbPercent.g) {
15708 h = 60 * (2 + (rgbPercent.b - rgbPercent.r) / c);
15709 } else if (v === rgbPercent.b) {
15710 h = 60 * (4 + (rgbPercent.r - rgbPercent.g) / c);
15711 }
15712 const s = !v ? 0 : c / v;
15713 return {
15714 h,
15715 s: s * 100,
15716 v: v * 100
15717 };
15718}
15719function rgbaToHsva(rgba) {
15720 return {
15721 a: rgba.a,
15722 ...rgbToHsv(rgba)
15723 };
15724}
15725function getStyleFromHsv(color, opacity) {
15726 return getStyleFromHsl(hsvToHsl(color), opacity);
15727}
15728function hslToHsv(hsl) {
15729 const l = hsl.l / 100,
15730 sl = hsl.s / 100,
15731 v = l + sl * Math.min(l, 1 - l),
15732 sv = !v ? 0 : 2 * (1 - l / v);
15733 return {
15734 h: hsl.h,
15735 s: sv * 100,
15736 v: v * 100
15737 };
15738}
15739function hslaToHsva(hsla) {
15740 return {
15741 a: hsla.a,
15742 ...hslToHsv(hsla)
15743 };
15744}
15745function hsvToHsl(hsv) {
15746 const v = hsv.v / 100,
15747 sv = hsv.s / 100,
15748 l = v * (1 - sv / 2),
15749 sl = l === 0 || l === 1 ? 0 : (v - l) / Math.min(l, 1 - l);
15750 return {
15751 h: hsv.h,
15752 l: l * 100,
15753 s: sl * 100
15754 };
15755}
15756function hsvaToHsla(hsva) {
15757 return {
15758 a: hsva.a,
15759 ...hsvToHsl(hsva)
15760 };
15761}
15762function hsvToRgb(hsv) {
15763 const result = {
15764 b: 0,
15765 g: 0,
15766 r: 0
15767 },
15768 hsvPercent = {
15769 h: hsv.h / 60,
15770 s: hsv.s / 100,
15771 v: hsv.v / 100
15772 },
15773 c = hsvPercent.v * hsvPercent.s,
15774 x = c * (1 - Math.abs(hsvPercent.h % 2 - 1));
15775 let tempRgb;
15776 if (hsvPercent.h >= 0 && hsvPercent.h <= 1) {
15777 tempRgb = {
15778 r: c,
15779 g: x,
15780 b: 0
15781 };
15782 } else if (hsvPercent.h > 1 && hsvPercent.h <= 2) {
15783 tempRgb = {
15784 r: x,
15785 g: c,
15786 b: 0
15787 };
15788 } else if (hsvPercent.h > 2 && hsvPercent.h <= 3) {
15789 tempRgb = {
15790 r: 0,
15791 g: c,
15792 b: x
15793 };
15794 } else if (hsvPercent.h > 3 && hsvPercent.h <= 4) {
15795 tempRgb = {
15796 r: 0,
15797 g: x,
15798 b: c
15799 };
15800 } else if (hsvPercent.h > 4 && hsvPercent.h <= 5) {
15801 tempRgb = {
15802 r: x,
15803 g: 0,
15804 b: c
15805 };
15806 } else if (hsvPercent.h > 5 && hsvPercent.h <= 6) {
15807 tempRgb = {
15808 r: c,
15809 g: 0,
15810 b: x
15811 };
15812 }
15813 if (tempRgb) {
15814 const m = hsvPercent.v - c;
15815 result.r = Math.floor((tempRgb.r + m) * 255);
15816 result.g = Math.floor((tempRgb.g + m) * 255);
15817 result.b = Math.floor((tempRgb.b + m) * 255);
15818 }
15819 return result;
15820}
15821function hsvaToRgba(hsva) {
15822 return {
15823 a: hsva.a,
15824 ...hsvToRgb(hsva)
15825 };
15826}
15827class HsvColorManager {
15828 constructor() {
15829 this.key = "hsv";
15830 this.stringPrefix = "hsv";
15831 }
15832 handleColor(color) {
15833 const colorValue = color.value,
15834 hsvColor = colorValue.hsv ?? color.value;
15835 if (hsvColor.h !== undefined && hsvColor.v !== undefined) {
15836 return hsvToRgb(hsvColor);
15837 }
15838 }
15839 handleRangeColor(color) {
15840 const colorValue = color.value,
15841 hsvColor = colorValue.hsv ?? color.value;
15842 if (hsvColor.h !== undefined && hsvColor.v !== undefined) {
15843 return hsvToRgb({
15844 h: getRangeValue(hsvColor.h),
15845 s: getRangeValue(hsvColor.s),
15846 v: getRangeValue(hsvColor.v)
15847 });
15848 }
15849 }
15850 parseString(input) {
15851 if (!input.startsWith("hsv")) {
15852 return;
15853 }
15854 const regex = /hsva?\(\s*(\d+)°\s*,\s*(\d+)%\s*,\s*(\d+)%\s*(,\s*([\d.%]+)\s*)?\)/i,
15855 result = regex.exec(input);
15856 return result ? hsvaToRgba({
15857 a: result.length > 4 ? parseAlpha(result[5]) : 1,
15858 h: parseInt(result[1], 10),
15859 s: parseInt(result[2], 10),
15860 v: parseInt(result[3], 10)
15861 }) : undefined;
15862 }
15863}
15864;// CONCATENATED MODULE: ../../plugins/hsvColor/dist/esm/index.js
15865
15866
15867async function loadHsvColorPlugin() {
15868 addColorManager(new HsvColorManager());
15869}
15870;// CONCATENATED MODULE: ../../plugins/infection/dist/esm/Options/Classes/InfectionStage.js
15871
15872class InfectionStage {
15873 constructor() {
15874 this.color = new OptionsColor();
15875 this.color.value = "#ff0000";
15876 this.radius = 0;
15877 this.rate = 1;
15878 }
15879 load(data) {
15880 if (data === undefined) {
15881 return;
15882 }
15883 if (data.color !== undefined) {
15884 this.color = OptionsColor.create(this.color, data.color);
15885 }
15886 this.duration = data.duration;
15887 this.infectedStage = data.infectedStage;
15888 if (data.radius !== undefined) {
15889 this.radius = data.radius;
15890 }
15891 if (data.rate !== undefined) {
15892 this.rate = data.rate;
15893 }
15894 }
15895}
15896;// CONCATENATED MODULE: ../../plugins/infection/dist/esm/Options/Classes/Infection.js
15897
15898class Infection {
15899 constructor() {
15900 this.cure = false;
15901 this.delay = 0;
15902 this.enable = false;
15903 this.infections = 0;
15904 this.stages = [];
15905 }
15906 load(data) {
15907 if (data === undefined) {
15908 return;
15909 }
15910 if (data.cure !== undefined) {
15911 this.cure = data.cure;
15912 }
15913 if (data.delay !== undefined) {
15914 this.delay = data.delay;
15915 }
15916 if (data.enable !== undefined) {
15917 this.enable = data.enable;
15918 }
15919 if (data.infections !== undefined) {
15920 this.infections = data.infections;
15921 }
15922 if (data.stages === undefined) {
15923 return;
15924 }
15925 this.stages = data.stages.map(t => {
15926 const s = new InfectionStage();
15927 s.load(t);
15928 return s;
15929 });
15930 }
15931}
15932;// CONCATENATED MODULE: ../../plugins/infection/dist/esm/Infecter.js
15933class Infecter {
15934 constructor(container) {
15935 this._nextInfectionStage = particle => {
15936 const infectionOptions = this._container.actualOptions.infection,
15937 {
15938 infection
15939 } = particle;
15940 if (!infectionOptions || !infection) {
15941 return;
15942 }
15943 const stagesCount = infectionOptions.stages.length;
15944 if (stagesCount <= 0 || infection.stage === undefined) {
15945 return;
15946 }
15947 infection.time = 0;
15948 if (stagesCount <= ++infection.stage) {
15949 if (infectionOptions.cure) {
15950 delete infection.stage;
15951 delete infection.time;
15952 return;
15953 } else {
15954 infection.stage = 0;
15955 infection.time = 0;
15956 }
15957 }
15958 };
15959 this._container = container;
15960 }
15961 startInfection(particle, stage) {
15962 const infectionOptions = this._container.actualOptions.infection,
15963 {
15964 infection
15965 } = particle;
15966 if (!infectionOptions || !infection) {
15967 return;
15968 }
15969 const stages = infectionOptions.stages,
15970 stagesCount = stages.length;
15971 if (stage > stagesCount || stage < 0) {
15972 return;
15973 }
15974 infection.delay = 0;
15975 infection.delayStage = stage;
15976 }
15977 updateInfection(particle, delta) {
15978 const infectionOptions = this._container.actualOptions.infection,
15979 {
15980 infection
15981 } = particle;
15982 if (!infectionOptions || !infection) {
15983 return;
15984 }
15985 const stages = infectionOptions.stages,
15986 stagesCount = stages.length;
15987 if (infection.delay !== undefined && infection.delayStage !== undefined) {
15988 const stage = infection.delayStage;
15989 if (stage > stagesCount || stage < 0) {
15990 return;
15991 }
15992 if (infection.delay >= infectionOptions.delay * 1000) {
15993 infection.stage = stage;
15994 infection.time = 0;
15995 delete infection.delay;
15996 delete infection.delayStage;
15997 } else {
15998 infection.delay += delta;
15999 }
16000 } else {
16001 delete infection.delay;
16002 delete infection.delayStage;
16003 }
16004 if (infection.stage !== undefined && infection.time !== undefined) {
16005 const infectionStage = stages[infection.stage];
16006 if (infectionStage.duration !== undefined && infectionStage.duration >= 0) {
16007 if (infection.time > infectionStage.duration * 1000) {
16008 this._nextInfectionStage(particle);
16009 } else {
16010 infection.time += delta;
16011 }
16012 } else {
16013 infection.time += delta;
16014 }
16015 } else {
16016 delete infection.stage;
16017 delete infection.time;
16018 }
16019 }
16020 updateInfectionStage(particle, stage) {
16021 const options = this._container.actualOptions,
16022 {
16023 infection
16024 } = particle;
16025 if (!options.infection || !infection) {
16026 return;
16027 }
16028 const stagesCount = options.infection.stages.length;
16029 if (stage > stagesCount || stage < 0 || infection.stage !== undefined && infection.stage > stage) {
16030 return;
16031 }
16032 infection.stage = stage;
16033 infection.time = 0;
16034 }
16035}
16036;// CONCATENATED MODULE: ../../plugins/infection/dist/esm/InfectionInstance.js
16037
16038
16039class InfectionInstance {
16040 constructor(container) {
16041 this._container = container;
16042 this._container.infecter = new Infecter(this._container);
16043 }
16044 particleFillColor(particle) {
16045 const options = this._container.actualOptions;
16046 if (!particle.infection || !options.infection) {
16047 return;
16048 }
16049 const infectionStage = particle.infection.stage,
16050 infection = options.infection,
16051 infectionStages = infection.stages;
16052 return infectionStage !== undefined ? infectionStages[infectionStage].color : undefined;
16053 }
16054 particleStrokeColor(particle) {
16055 return this.particleFillColor(particle);
16056 }
16057 particlesSetup() {
16058 const options = this._container.actualOptions;
16059 if (!options.infection) {
16060 return;
16061 }
16062 for (let i = 0; i < options.infection.infections; i++) {
16063 const notInfected = this._container.particles.filter(p => {
16064 const infP = p;
16065 if (!infP.infection) {
16066 infP.infection = {};
16067 }
16068 return infP.infection.stage === undefined;
16069 });
16070 const infected = itemFromArray(notInfected);
16071 this._container.infecter?.startInfection(infected, 0);
16072 }
16073 }
16074}
16075;// CONCATENATED MODULE: ../../plugins/infection/dist/esm/ParticlesInfecter.js
16076
16077class ParticlesInfecter extends ParticlesInteractorBase {
16078 constructor(container) {
16079 super(container);
16080 }
16081 clear() {}
16082 init() {}
16083 async interact(p1, delta) {
16084 const infecter = this.container.infecter;
16085 if (!infecter) {
16086 return;
16087 }
16088 infecter.updateInfection(p1, delta.value);
16089 if (p1.infection?.stage === undefined) {
16090 return;
16091 }
16092 const container = this.container,
16093 options = container.actualOptions,
16094 infectionOptions = options.infection;
16095 if (!infectionOptions?.enable || infectionOptions.stages.length < 1) {
16096 return;
16097 }
16098 const infectionStage1 = infectionOptions.stages[p1.infection.stage],
16099 pxRatio = container.retina.pixelRatio,
16100 radius = p1.getRadius() * 2 + infectionStage1.radius * pxRatio,
16101 pos = p1.getPosition(),
16102 infectedStage1 = infectionStage1.infectedStage ?? p1.infection.stage,
16103 query = container.particles.quadTree.queryCircle(pos, radius),
16104 infections = infectionStage1.rate,
16105 neighbors = query.length;
16106 for (const p2 of query) {
16107 const infP2 = p2;
16108 if (infP2 === p1 || infP2.destroyed || infP2.spawning || !(infP2.infection?.stage === undefined || infP2.infection.stage !== p1.infection.stage) || getRandom() >= infections / neighbors) {
16109 continue;
16110 }
16111 if (infP2.infection?.stage === undefined) {
16112 infecter.startInfection(infP2, infectedStage1);
16113 } else if (infP2.infection.stage < p1.infection.stage) {
16114 infecter.updateInfectionStage(infP2, infectedStage1);
16115 } else if (infP2.infection.stage > p1.infection.stage) {
16116 const infectionStage2 = infectionOptions.stages[infP2.infection.stage];
16117 const infectedStage2 = infectionStage2?.infectedStage ?? infP2.infection.stage;
16118 infecter.updateInfectionStage(p1, infectedStage2);
16119 }
16120 }
16121 }
16122 isEnabled() {
16123 return this.container.actualOptions?.infection?.enable ?? false;
16124 }
16125 reset() {}
16126}
16127;// CONCATENATED MODULE: ../../plugins/infection/dist/esm/index.js
16128
16129
16130
16131class InfectionPlugin {
16132 constructor() {
16133 this.id = "infection";
16134 }
16135 getPlugin(container) {
16136 return new InfectionInstance(container);
16137 }
16138 loadOptions(options, source) {
16139 if (!this.needsPlugin(options) && !this.needsPlugin(source)) {
16140 return;
16141 }
16142 let infectionOptions = options.infection;
16143 if (infectionOptions?.load === undefined) {
16144 options.infection = infectionOptions = new Infection();
16145 }
16146 infectionOptions.load(source?.infection);
16147 }
16148 needsPlugin(options) {
16149 return options?.infection?.enable ?? false;
16150 }
16151}
16152async function loadInfectionPlugin(engine, refresh = true) {
16153 const plugin = new InfectionPlugin();
16154 await engine.addPlugin(plugin, refresh);
16155 await engine.addInteractor("particlesInfection", container => new ParticlesInfecter(container), refresh);
16156}
16157
16158
16159;// CONCATENATED MODULE: ../../interactions/light/dist/esm/Options/Classes/LightGradient.js
16160
16161class LightGradient {
16162 constructor() {
16163 this.start = new OptionsColor();
16164 this.stop = new OptionsColor();
16165 this.start.value = "#ffffff";
16166 this.stop.value = "#000000";
16167 }
16168 load(data) {
16169 if (!data) {
16170 return;
16171 }
16172 this.start = OptionsColor.create(this.start, data.start);
16173 this.stop = OptionsColor.create(this.stop, data.stop);
16174 }
16175}
16176;// CONCATENATED MODULE: ../../interactions/light/dist/esm/Options/Classes/LightArea.js
16177
16178class LightArea {
16179 constructor() {
16180 this.gradient = new LightGradient();
16181 this.radius = 1000;
16182 }
16183 load(data) {
16184 if (!data) {
16185 return;
16186 }
16187 this.gradient.load(data.gradient);
16188 if (data.radius !== undefined) {
16189 this.radius = data.radius;
16190 }
16191 }
16192}
16193;// CONCATENATED MODULE: ../../interactions/light/dist/esm/Options/Classes/LightShadow.js
16194
16195class LightShadow {
16196 constructor() {
16197 this.color = new OptionsColor();
16198 this.color.value = "#000000";
16199 this.length = 2000;
16200 }
16201 load(data) {
16202 if (!data) {
16203 return;
16204 }
16205 this.color = OptionsColor.create(this.color, data.color);
16206 if (data.length !== undefined) {
16207 this.length = data.length;
16208 }
16209 }
16210}
16211;// CONCATENATED MODULE: ../../interactions/light/dist/esm/Options/Classes/Light.js
16212
16213
16214class Light {
16215 constructor() {
16216 this.area = new LightArea();
16217 this.shadow = new LightShadow();
16218 }
16219 load(data) {
16220 if (!data) {
16221 return;
16222 }
16223 this.area.load(data.area);
16224 this.shadow.load(data.shadow);
16225 }
16226}
16227;// CONCATENATED MODULE: ../../interactions/light/dist/esm/Utils.js
16228
16229function drawLight(container, context, mousePos) {
16230 const lightOptions = container.actualOptions.interactivity.modes.light?.area;
16231 if (!lightOptions) {
16232 return;
16233 }
16234 context.beginPath();
16235 context.arc(mousePos.x, mousePos.y, lightOptions.radius, 0, 2 * Math.PI);
16236 const gradientAmbientLight = context.createRadialGradient(mousePos.x, mousePos.y, 0, mousePos.x, mousePos.y, lightOptions.radius);
16237 const gradientRgb = container.canvas.mouseLight;
16238 if (!gradientRgb || !gradientRgb.start || !gradientRgb.stop) {
16239 return;
16240 }
16241 gradientAmbientLight.addColorStop(0, getStyleFromRgb(gradientRgb.start));
16242 gradientAmbientLight.addColorStop(1, getStyleFromRgb(gradientRgb.stop));
16243 context.fillStyle = gradientAmbientLight;
16244 context.fill();
16245}
16246function drawParticleShadow(container, context, particle, mousePos) {
16247 const pos = particle.getPosition(),
16248 shadowOptions = container.actualOptions.interactivity.modes.light?.shadow;
16249 if (!shadowOptions) {
16250 return;
16251 }
16252 const shadowRgb = particle.lightShadow;
16253 if (!shadowRgb) {
16254 return;
16255 }
16256 const radius = particle.getRadius(),
16257 sides = particle.sides,
16258 full = Math.PI * 2 / sides,
16259 angle = -particle.rotation + Math.PI / 4,
16260 factor = 1,
16261 dots = [];
16262 for (let i = 0; i < sides; i++) {
16263 dots.push({
16264 x: pos.x + radius * Math.sin(angle + full * i) * factor,
16265 y: pos.y + radius * Math.cos(angle + full * i) * factor
16266 });
16267 }
16268 const points = [],
16269 shadowLength = shadowOptions.length;
16270 for (const dot of dots) {
16271 const dotAngle = Math.atan2(mousePos.y - dot.y, mousePos.x - dot.x),
16272 end = {
16273 x: dot.x + shadowLength * Math.sin(-dotAngle - Math.PI / 2),
16274 y: dot.y + shadowLength * Math.cos(-dotAngle - Math.PI / 2)
16275 };
16276 points.push({
16277 end: end,
16278 start: dot
16279 });
16280 }
16281 const shadowColor = getStyleFromRgb(shadowRgb),
16282 last = points.length - 1;
16283 for (let i = last, n = 0; i >= 0; n = i--) {
16284 context.beginPath();
16285 context.moveTo(points[i].start.x, points[i].start.y);
16286 context.lineTo(points[n].start.x, points[n].start.y);
16287 context.lineTo(points[n].end.x, points[n].end.y);
16288 context.lineTo(points[i].end.x, points[i].end.y);
16289 context.fillStyle = shadowColor;
16290 context.fill();
16291 }
16292}
16293;// CONCATENATED MODULE: ../../interactions/light/dist/esm/ExternalLighter.js
16294
16295
16296
16297class ExternalLighter extends ExternalInteractorBase {
16298 constructor(container) {
16299 super(container);
16300 }
16301 clear() {}
16302 init() {}
16303 async interact() {
16304 const container = this.container,
16305 options = container.actualOptions,
16306 interactivity = container.interactivity;
16307 if (!options.interactivity.events.onHover.enable || interactivity.status !== "pointermove") {
16308 return;
16309 }
16310 const mousePos = interactivity.mouse.position;
16311 if (!mousePos) {
16312 return;
16313 }
16314 container.canvas.draw(ctx => {
16315 drawLight(container, ctx, mousePos);
16316 });
16317 }
16318 isEnabled(particle) {
16319 const container = this.container,
16320 mouse = container.interactivity.mouse,
16321 interactivity = particle?.interactivity ?? container.actualOptions.interactivity,
16322 events = interactivity.events;
16323 if (!(events.onHover.enable && mouse.position)) {
16324 return false;
16325 }
16326 const res = isInArray("light", events.onHover.mode);
16327 if (res && interactivity.modes.light) {
16328 const lightGradient = interactivity.modes.light.area.gradient;
16329 container.canvas.mouseLight = {
16330 start: rangeColorToRgb(lightGradient.start),
16331 stop: rangeColorToRgb(lightGradient.stop)
16332 };
16333 }
16334 return res;
16335 }
16336 loadModeOptions(options, ...sources) {
16337 if (!options.light) {
16338 options.light = new Light();
16339 }
16340 for (const source of sources) {
16341 options.light.load(source?.light);
16342 }
16343 }
16344 reset() {}
16345}
16346;// CONCATENATED MODULE: ../../interactions/light/dist/esm/ParticlesLighter.js
16347
16348
16349class ParticlesLighter extends ParticlesInteractorBase {
16350 constructor(container) {
16351 super(container);
16352 }
16353 clear() {}
16354 init() {}
16355 async interact(particle) {
16356 const container = this.container,
16357 options = container.actualOptions,
16358 interactivity = container.interactivity;
16359 if (!options.interactivity.events.onHover.enable || interactivity.status !== "pointermove") {
16360 return;
16361 }
16362 const mousePos = interactivity.mouse.position;
16363 if (!mousePos) {
16364 return;
16365 }
16366 container.canvas.draw(ctx => {
16367 drawParticleShadow(container, ctx, particle, mousePos);
16368 });
16369 }
16370 isEnabled(particle) {
16371 const container = this.container,
16372 interactivity = particle.interactivity ?? container.actualOptions.interactivity,
16373 mouse = container.interactivity.mouse,
16374 events = interactivity.events;
16375 if (!(events.onHover.enable && mouse.position)) {
16376 return false;
16377 }
16378 const res = isInArray("light", events.onHover.mode);
16379 if (res && interactivity.modes.light) {
16380 const shadowOptions = interactivity.modes.light.shadow;
16381 particle.lightShadow = rangeColorToRgb(shadowOptions.color);
16382 }
16383 return res;
16384 }
16385 reset() {}
16386}
16387;// CONCATENATED MODULE: ../../interactions/light/dist/esm/index.js
16388
16389
16390async function loadLightInteraction(engine, refresh = true) {
16391 await engine.addInteractor("externalLight", container => new ExternalLighter(container), refresh);
16392 await engine.addInteractor("particlesLight", container => new ParticlesLighter(container), refresh);
16393}
16394
16395
16396
16397
16398
16399
16400
16401
16402;// CONCATENATED MODULE: ../../plugins/motion/dist/esm/Options/Classes/MotionReduce.js
16403class MotionReduce {
16404 constructor() {
16405 this.factor = 4;
16406 this.value = true;
16407 }
16408 load(data) {
16409 if (!data) {
16410 return;
16411 }
16412 if (data.factor !== undefined) {
16413 this.factor = data.factor;
16414 }
16415 if (data.value !== undefined) {
16416 this.value = data.value;
16417 }
16418 }
16419}
16420;// CONCATENATED MODULE: ../../plugins/motion/dist/esm/Options/Classes/Motion.js
16421
16422class Motion {
16423 constructor() {
16424 this.disable = false;
16425 this.reduce = new MotionReduce();
16426 }
16427 load(data) {
16428 if (!data) {
16429 return;
16430 }
16431 if (data.disable !== undefined) {
16432 this.disable = data.disable;
16433 }
16434 this.reduce.load(data.reduce);
16435 }
16436}
16437;// CONCATENATED MODULE: ../../plugins/motion/dist/esm/MotionInstance.js
16438
16439class MotionInstance {
16440 constructor(container, engine) {
16441 this._handleMotionChange = mediaQuery => {
16442 const container = this._container,
16443 motion = container.actualOptions.motion;
16444 if (!motion) {
16445 return;
16446 }
16447 container.retina.reduceFactor = mediaQuery.matches ? motion.disable ? 0 : motion.reduce.value ? 1 / motion.reduce.factor : 1 : 1;
16448 };
16449 this._container = container;
16450 this._engine = engine;
16451 }
16452 async init() {
16453 const container = this._container,
16454 options = container.actualOptions.motion;
16455 if (!(options && (options.disable || options.reduce.value))) {
16456 container.retina.reduceFactor = 1;
16457 return;
16458 }
16459 const mediaQuery = safeMatchMedia("(prefers-reduced-motion: reduce)");
16460 if (!mediaQuery) {
16461 container.retina.reduceFactor = 1;
16462 return;
16463 }
16464 this._handleMotionChange(mediaQuery);
16465 const handleChange = async () => {
16466 this._handleMotionChange(mediaQuery);
16467 try {
16468 await container.refresh();
16469 } catch {}
16470 };
16471 if (mediaQuery.addEventListener !== undefined) {
16472 mediaQuery.addEventListener("change", handleChange);
16473 } else if (mediaQuery.addListener !== undefined) {
16474 mediaQuery.addListener(handleChange);
16475 }
16476 }
16477}
16478;// CONCATENATED MODULE: ../../plugins/motion/dist/esm/index.js
16479
16480
16481class MotionPlugin {
16482 constructor(engine) {
16483 this.id = "motion";
16484 this._engine = engine;
16485 }
16486 getPlugin(container) {
16487 return new MotionInstance(container, this._engine);
16488 }
16489 loadOptions(options, source) {
16490 if (!this.needsPlugin()) {
16491 return;
16492 }
16493 let motionOptions = options.motion;
16494 if (!motionOptions?.load) {
16495 options.motion = motionOptions = new Motion();
16496 }
16497 motionOptions.load(source?.motion);
16498 }
16499 needsPlugin() {
16500 return true;
16501 }
16502}
16503async function loadMotionPlugin(engine, refresh = true) {
16504 await engine.addPlugin(new MotionPlugin(engine), refresh);
16505}
16506;// CONCATENATED MODULE: ../../shapes/multiline-text/dist/esm/MultilineTextDrawer.js
16507
16508class MultilineTextDrawer {
16509 constructor() {
16510 this._drawLine = (context, line, radius, opacity, index, fill) => {
16511 const offsetX = line.length * radius / 2,
16512 pos = {
16513 x: -offsetX,
16514 y: radius / 2
16515 };
16516 if (fill) {
16517 context.fillText(line, pos.x, pos.y + radius * 2 * index);
16518 } else {
16519 context.strokeText(line, pos.x, pos.y + radius * 2 * index);
16520 }
16521 };
16522 }
16523 draw(context, particle, radius, opacity) {
16524 const character = particle.shapeData;
16525 if (character === undefined) {
16526 return;
16527 }
16528 const textData = character.value;
16529 if (textData === undefined) {
16530 return;
16531 }
16532 if (particle.text === undefined) {
16533 particle.text = itemFromSingleOrMultiple(textData, particle.randomIndexData);
16534 }
16535 const text = particle.text,
16536 style = character.style ?? "",
16537 weight = character.weight ?? "400",
16538 size = Math.round(radius) * 2,
16539 font = character.font ?? "Verdana",
16540 fill = particle.fill;
16541 context.font = `${style} ${weight} ${size}px "${font}"`;
16542 const lines = text?.split("\n");
16543 if (!lines) {
16544 return;
16545 }
16546 context.globalAlpha = opacity;
16547 for (let i = 0; i < lines.length; i++) {
16548 this._drawLine(context, lines[i], radius, opacity, i, fill);
16549 }
16550 context.globalAlpha = 1;
16551 }
16552 async init(container) {
16553 const options = container.options,
16554 shapeType = "multiline-text";
16555 if (isInArray(shapeType, options.particles.shape.type)) {
16556 const shapeOptions = options.particles.shape.options[shapeType],
16557 promises = [];
16558 executeOnSingleOrMultiple(shapeOptions, shape => {
16559 promises.push(loadFont(shape.font, shape.weight));
16560 });
16561 await Promise.all(promises);
16562 }
16563 }
16564 particleInit(container, particle) {
16565 if (particle.shape !== "multiline-text") {
16566 return;
16567 }
16568 const character = particle.shapeData;
16569 if (character === undefined) {
16570 return;
16571 }
16572 const textData = character.value;
16573 if (textData === undefined) {
16574 return;
16575 }
16576 particle.text = itemFromSingleOrMultiple(textData, particle.randomIndexData);
16577 }
16578}
16579;// CONCATENATED MODULE: ../../shapes/multiline-text/dist/esm/index.js
16580
16581async function loadMultilineTextShape(engine, refresh = true) {
16582 await engine.addShape("multiline-text", new MultilineTextDrawer(), refresh);
16583}
16584;// CONCATENATED MODULE: ../../updaters/orbit/dist/esm/Options/Classes/OrbitRotation.js
16585
16586class OrbitRotation extends ValueWithRandom {
16587 constructor() {
16588 super();
16589 this.value = 45;
16590 this.random.enable = false;
16591 this.random.minimumValue = 0;
16592 }
16593 load(data) {
16594 if (data === undefined) {
16595 return;
16596 }
16597 super.load(data);
16598 }
16599}
16600;// CONCATENATED MODULE: ../../updaters/orbit/dist/esm/Options/Classes/Orbit.js
16601
16602
16603class Orbit {
16604 constructor() {
16605 this.animation = new AnimationOptions();
16606 this.enable = false;
16607 this.opacity = 1;
16608 this.rotation = new OrbitRotation();
16609 this.width = 1;
16610 }
16611 load(data) {
16612 if (!data) {
16613 return;
16614 }
16615 this.animation.load(data.animation);
16616 this.rotation.load(data.rotation);
16617 if (data.enable !== undefined) {
16618 this.enable = data.enable;
16619 }
16620 if (data.opacity !== undefined) {
16621 this.opacity = setRangeValue(data.opacity);
16622 }
16623 if (data.width !== undefined) {
16624 this.width = setRangeValue(data.width);
16625 }
16626 if (data.radius !== undefined) {
16627 this.radius = setRangeValue(data.radius);
16628 }
16629 if (data.color !== undefined) {
16630 this.color = OptionsColor.create(this.color, data.color);
16631 }
16632 }
16633}
16634;// CONCATENATED MODULE: ../../updaters/orbit/dist/esm/Utils.js
16635
16636function drawEllipse(context, particle, fillColorValue, radius, opacity, width, rotation, start, end) {
16637 if (width <= 0) {
16638 return;
16639 }
16640 const pos = particle.getPosition();
16641 if (fillColorValue) {
16642 context.strokeStyle = ColorUtils_getStyleFromHsl(fillColorValue, opacity);
16643 }
16644 context.lineWidth = width;
16645 const rotationRadian = rotation * Math.PI / 180;
16646 context.beginPath();
16647 context.ellipse(pos.x, pos.y, radius / 2, radius * 2, rotationRadian, start, end);
16648 context.stroke();
16649}
16650;// CONCATENATED MODULE: ../../updaters/orbit/dist/esm/OrbitUpdater.js
16651
16652
16653
16654class OrbitUpdater {
16655 constructor(container) {
16656 this.container = container;
16657 }
16658 afterDraw(particle) {
16659 const orbitOptions = particle.options.orbit;
16660 if (orbitOptions?.enable) {
16661 this.drawOrbit(particle, "front");
16662 }
16663 }
16664 beforeDraw(particle) {
16665 const orbitOptions = particle.options.orbit;
16666 if (orbitOptions?.enable) {
16667 this.drawOrbit(particle, "back");
16668 }
16669 }
16670 drawOrbit(particle, type) {
16671 const container = this.container;
16672 let start, end;
16673 switch (type) {
16674 case "back":
16675 start = Math.PI / 2;
16676 end = Math.PI * 3 / 2;
16677 break;
16678 case "front":
16679 start = Math.PI * 3 / 2;
16680 end = Math.PI / 2;
16681 break;
16682 default:
16683 start = 0;
16684 end = 2 * Math.PI;
16685 }
16686 container.canvas.draw(ctx => {
16687 drawEllipse(ctx, particle, particle.orbitColor ?? particle.getFillColor(), particle.retina.orbitRadius ?? container.retina.orbitRadius ?? particle.getRadius(), particle.orbitOpacity ?? 1, particle.orbitWidth ?? 1, (particle.orbitRotation ?? 0) * container.retina.pixelRatio, start, end);
16688 });
16689 }
16690 init(particle) {
16691 const container = this.container,
16692 particlesOptions = particle.options,
16693 orbitOptions = particlesOptions.orbit;
16694 if (!orbitOptions?.enable) {
16695 return;
16696 }
16697 particle.orbitRotation = getRangeValue(orbitOptions.rotation.value);
16698 particle.orbitColor = rangeColorToHsl(orbitOptions.color);
16699 particle.retina.orbitRadius = orbitOptions.radius !== undefined ? getRangeValue(orbitOptions.radius) * container.retina.pixelRatio : undefined;
16700 container.retina.orbitRadius = particle.retina.orbitRadius;
16701 particle.orbitAnimationSpeed = orbitOptions.animation.enable ? getRangeValue(orbitOptions.animation.speed) : 0;
16702 particle.orbitWidth = getRangeValue(orbitOptions.width);
16703 particle.orbitOpacity = getRangeValue(orbitOptions.opacity);
16704 }
16705 isEnabled(particle) {
16706 const orbitAnimations = particle.options.orbit?.animation;
16707 return !particle.destroyed && !particle.spawning && !!orbitAnimations?.enable;
16708 }
16709 loadOptions(options, ...sources) {
16710 if (!options.orbit) {
16711 options.orbit = new Orbit();
16712 }
16713 for (const source of sources) {
16714 options.orbit.load(source?.orbit);
16715 }
16716 }
16717 update(particle, delta) {
16718 if (!this.isEnabled(particle)) {
16719 return;
16720 }
16721 if (particle.orbitRotation === undefined) {
16722 particle.orbitRotation = 0;
16723 }
16724 particle.orbitRotation += (particle.orbitAnimationSpeed ?? 0 / (Math.PI * 2)) * delta.factor;
16725 }
16726}
16727;// CONCATENATED MODULE: ../../updaters/orbit/dist/esm/index.js
16728
16729async function loadOrbitUpdater(engine, refresh = true) {
16730 await engine.addParticleUpdater("orbit", container => new OrbitUpdater(container), refresh);
16731}
16732;// CONCATENATED MODULE: ../../interactions/particles/repulse/dist/esm/Options/Classes/ParticlesRepulse.js
16733
16734class ParticlesRepulse extends ValueWithRandom {
16735 constructor() {
16736 super();
16737 this.enabled = false;
16738 this.distance = 1;
16739 this.duration = 1;
16740 this.factor = 1;
16741 this.speed = 1;
16742 }
16743 load(data) {
16744 super.load(data);
16745 if (!data) {
16746 return;
16747 }
16748 if (data.enabled !== undefined) {
16749 this.enabled = data.enabled;
16750 }
16751 if (data.distance !== undefined) {
16752 this.distance = setRangeValue(data.distance);
16753 }
16754 if (data.duration !== undefined) {
16755 this.duration = setRangeValue(data.duration);
16756 }
16757 if (data.factor !== undefined) {
16758 this.factor = setRangeValue(data.factor);
16759 }
16760 if (data.speed !== undefined) {
16761 this.speed = setRangeValue(data.speed);
16762 }
16763 }
16764}
16765;// CONCATENATED MODULE: ../../interactions/particles/repulse/dist/esm/Repulser.js
16766
16767
16768class Repulser_Repulser extends ParticlesInteractorBase {
16769 constructor(container) {
16770 super(container);
16771 }
16772 clear() {}
16773 init() {}
16774 async interact(p1) {
16775 const container = this.container;
16776 if (!p1.repulse) {
16777 const repulseOpt1 = p1.options.repulse;
16778 if (!repulseOpt1) {
16779 return;
16780 }
16781 p1.repulse = {
16782 distance: getRangeValue(repulseOpt1.distance) * container.retina.pixelRatio,
16783 speed: getRangeValue(repulseOpt1.speed),
16784 factor: getRangeValue(repulseOpt1.factor)
16785 };
16786 }
16787 const pos1 = p1.getPosition(),
16788 query = container.particles.quadTree.queryCircle(pos1, p1.repulse.distance);
16789 for (const p2 of query) {
16790 if (p1 === p2 || p2.destroyed) {
16791 continue;
16792 }
16793 const pos2 = p2.getPosition();
16794 const {
16795 dx,
16796 dy,
16797 distance
16798 } = getDistances(pos2, pos1);
16799 const velocity = p1.repulse.speed * p1.repulse.factor;
16800 if (distance > 0) {
16801 const repulseFactor = clamp((1 - Math.pow(distance / p1.repulse.distance, 2)) * velocity, 0, velocity);
16802 const normVec = Vector.create(dx / distance * repulseFactor, dy / distance * repulseFactor);
16803 p2.position.addTo(normVec);
16804 } else {
16805 const velocityVec = Vector.create(velocity, velocity);
16806 p2.position.addTo(velocityVec);
16807 }
16808 }
16809 }
16810 isEnabled(particle) {
16811 return particle.options.repulse?.enabled ?? false;
16812 }
16813 loadParticlesOptions(options, ...sources) {
16814 if (!options.repulse) {
16815 options.repulse = new ParticlesRepulse();
16816 }
16817 for (const source of sources) {
16818 options.repulse.load(source?.repulse);
16819 }
16820 }
16821 reset() {}
16822}
16823;// CONCATENATED MODULE: ../../interactions/particles/repulse/dist/esm/index.js
16824
16825async function loadParticlesRepulseInteraction(engine, refresh = true) {
16826 await engine.addInteractor("particlesRepulse", container => new Repulser_Repulser(container), refresh);
16827}
16828;// CONCATENATED MODULE: ../../shapes/path/dist/esm/Utils.js
16829function Utils_drawPath(ctx, radius, path) {
16830 ctx.moveTo(path.segments[0].values[0].x * radius, path.segments[0].values[0].y * radius);
16831 for (let i = 0; i < path.segments.length; i++) {
16832 const segment = path.segments[i];
16833 switch (segment.type) {
16834 case "line":
16835 ctx.lineTo(segment.values[0].x * radius, segment.values[0].y * radius);
16836 break;
16837 case "bezier":
16838 ctx.bezierCurveTo(segment.values[1].x * radius, segment.values[1].y * radius, segment.values[2].x * radius, segment.values[2].y * radius, segment.values[3].x * radius, segment.values[3].y * radius);
16839 break;
16840 case "quadratic":
16841 ctx.quadraticCurveTo(segment.values[1].x * radius, segment.values[1].y * radius, segment.values[2].x * radius, segment.values[2].y * radius);
16842 break;
16843 case "arc":
16844 ctx.arc(segment.values[0].x * radius, segment.values[0].y * radius, segment.values[1].x * radius, segment.values[2].x, segment.values[2].y);
16845 break;
16846 case "ellipse":
16847 ctx.ellipse(segment.values[0].x * radius, segment.values[0].y * radius, segment.values[1].x * radius, segment.values[1].y * radius, segment.values[2].x, segment.values[3].x, segment.values[3].y);
16848 }
16849 }
16850 if (!path.half) {
16851 return;
16852 }
16853 for (let i = path.segments.length - 1; i >= 0; i--) {
16854 const segment = path.segments[i];
16855 switch (segment.type) {
16856 case "line":
16857 ctx.lineTo(segment.values[0].x * -radius, segment.values[0].y * radius);
16858 break;
16859 case "bezier":
16860 ctx.bezierCurveTo(-segment.values[2].x * radius, segment.values[2].y * radius, -segment.values[1].x * radius, segment.values[1].y * radius, -segment.values[0].x * radius, segment.values[0].y * radius);
16861 break;
16862 case "quadratic":
16863 ctx.quadraticCurveTo(-segment.values[1].x * radius, segment.values[1].y * radius, -segment.values[2].x * radius, segment.values[2].y * radius);
16864 break;
16865 }
16866 }
16867}
16868;// CONCATENATED MODULE: ../../shapes/path/dist/esm/PathDrawer.js
16869
16870
16871class PathDrawer {
16872 draw(context, particle, radius) {
16873 if (!particle.pathData) {
16874 return;
16875 }
16876 Utils_drawPath(context, radius, particle.pathData);
16877 }
16878 particleInit(container, particle) {
16879 const shape = particle.shapeData;
16880 if (!shape) {
16881 return;
16882 }
16883 particle.pathData = deepExtend({}, shape);
16884 }
16885}
16886;// CONCATENATED MODULE: ../../shapes/path/dist/esm/index.js
16887
16888async function loadPathShape(engine, refresh = true) {
16889 await engine.addShape("path", new PathDrawer(), refresh);
16890}
16891;// CONCATENATED MODULE: ../../paths/perlinNoise/dist/esm/Grad.js
16892class Grad {
16893 constructor(x, y, z) {
16894 this.x = x;
16895 this.y = y;
16896 this.z = z;
16897 }
16898 dot2(x, y) {
16899 return this.x * x + this.y * y;
16900 }
16901 dot3(x, y, z) {
16902 return this.dot2(x, y) + this.z * z;
16903 }
16904}
16905;// CONCATENATED MODULE: ../../paths/perlinNoise/dist/esm/PerlinNoise.js
16906
16907const grad3 = [new Grad(1, 1, 0), new Grad(-1, 1, 0), new Grad(1, -1, 0), new Grad(-1, -1, 0), new Grad(1, 0, 1), new Grad(-1, 0, 1), new Grad(1, 0, -1), new Grad(-1, 0, -1), new Grad(0, 1, 1), new Grad(0, -1, 1), new Grad(0, 1, -1), new Grad(0, -1, -1)];
16908const p = [151, 160, 137, 91, 90, 15, 131, 13, 201, 95, 96, 53, 194, 233, 7, 225, 140, 36, 103, 30, 69, 142, 8, 99, 37, 240, 21, 10, 23, 190, 6, 148, 247, 120, 234, 75, 0, 26, 197, 62, 94, 252, 219, 203, 117, 35, 11, 32, 57, 177, 33, 88, 237, 149, 56, 87, 174, 20, 125, 136, 171, 168, 68, 175, 74, 165, 71, 134, 139, 48, 27, 166, 77, 146, 158, 231, 83, 111, 229, 122, 60, 211, 133, 230, 220, 105, 92, 41, 55, 46, 245, 40, 244, 102, 143, 54, 65, 25, 63, 161, 1, 216, 80, 73, 209, 76, 132, 187, 208, 89, 18, 169, 200, 196, 135, 130, 116, 188, 159, 86, 164, 100, 109, 198, 173, 186, 3, 64, 52, 217, 226, 250, 124, 123, 5, 202, 38, 147, 118, 126, 255, 82, 85, 212, 207, 206, 59, 227, 47, 16, 58, 17, 182, 189, 28, 42, 223, 183, 170, 213, 119, 248, 152, 2, 44, 154, 163, 70, 221, 153, 101, 155, 167, 43, 172, 9, 129, 22, 39, 253, 19, 98, 108, 110, 79, 113, 224, 232, 178, 185, 112, 104, 218, 246, 97, 228, 251, 34, 242, 193, 238, 210, 144, 12, 191, 179, 162, 241, 81, 51, 145, 235, 249, 14, 239, 107, 49, 192, 214, 31, 181, 199, 106, 157, 184, 84, 204, 176, 115, 121, 50, 45, 127, 4, 150, 254, 138, 236, 205, 93, 222, 114, 67, 29, 24, 72, 243, 141, 128, 195, 78, 66, 215, 61, 156, 180];
16909const perm = new Array(512);
16910const gradP = new Array(512);
16911function fade(t) {
16912 return t * t * t * (t * (t * 6 - 15) + 10);
16913}
16914function lerp(a, b, t) {
16915 return (1 - t) * a + t * b;
16916}
16917class PerlinNoise {
16918 noise(x, y, z) {
16919 let X = Math.floor(x),
16920 Y = Math.floor(y),
16921 Z = Math.floor(z);
16922 x = x - X;
16923 y = y - Y;
16924 z = z - Z;
16925 X = X & 255;
16926 Y = Y & 255;
16927 Z = Z & 255;
16928 const n000 = gradP[X + perm[Y + perm[Z]]].dot3(x, y, z),
16929 n001 = gradP[X + perm[Y + perm[Z + 1]]].dot3(x, y, z - 1),
16930 n010 = gradP[X + perm[Y + 1 + perm[Z]]].dot3(x, y - 1, z),
16931 n011 = gradP[X + perm[Y + 1 + perm[Z + 1]]].dot3(x, y - 1, z - 1),
16932 n100 = gradP[X + 1 + perm[Y + perm[Z]]].dot3(x - 1, y, z),
16933 n101 = gradP[X + 1 + perm[Y + perm[Z + 1]]].dot3(x - 1, y, z - 1),
16934 n110 = gradP[X + 1 + perm[Y + 1 + perm[Z]]].dot3(x - 1, y - 1, z),
16935 n111 = gradP[X + 1 + perm[Y + 1 + perm[Z + 1]]].dot3(x - 1, y - 1, z - 1),
16936 u = fade(x),
16937 v = fade(y),
16938 w = fade(z);
16939 return lerp(lerp(lerp(n000, n100, u), lerp(n001, n101, u), w), lerp(lerp(n010, n110, u), lerp(n011, n111, u), w), v);
16940 }
16941 seed(inputSeed) {
16942 let seed = inputSeed;
16943 if (seed > 0 && seed < 1) {
16944 seed *= 65536;
16945 }
16946 seed = Math.floor(seed);
16947 if (seed < 256) {
16948 seed |= seed << 8;
16949 }
16950 for (let i = 0; i < 256; i++) {
16951 const v = i & 1 ? p[i] ^ seed & 255 : p[i] ^ seed >> 8 & 255;
16952 perm[i] = perm[i + 256] = v;
16953 gradP[i] = gradP[i + 256] = grad3[v % 12];
16954 }
16955 }
16956}
16957;// CONCATENATED MODULE: ../../paths/perlinNoise/dist/esm/PerlinNoiseGenerator.js
16958
16959
16960class PerlinNoiseGenerator {
16961 constructor() {
16962 this._calculateField = () => {
16963 const {
16964 field,
16965 noiseGen,
16966 options
16967 } = this;
16968 for (let x = 0; x < options.columns; x++) {
16969 const column = field[x];
16970 for (let y = 0; y < options.rows; y++) {
16971 const cell = column[y];
16972 cell.length = noiseGen.noise(x / 100 + 40000, y / 100 + 40000, this.noiseZ);
16973 cell.angle = noiseGen.noise(x / 50, y / 50, this.noiseZ) * Math.PI * 2;
16974 }
16975 }
16976 };
16977 this._drawField = ctx => {
16978 const {
16979 field,
16980 options
16981 } = this;
16982 for (let x = 0; x < options.columns; x++) {
16983 const column = field[x];
16984 for (let y = 0; y < options.rows; y++) {
16985 const cell = column[y],
16986 {
16987 angle,
16988 length
16989 } = cell;
16990 ctx.setTransform(1, 0, 0, 1, x * this.options.size, y * this.options.size);
16991 ctx.rotate(angle);
16992 ctx.strokeStyle = "white";
16993 ctx.beginPath();
16994 ctx.moveTo(0, 0);
16995 ctx.lineTo(0, this.options.size * length);
16996 ctx.stroke();
16997 ctx.setTransform(1, 0, 0, 1, 0, 0);
16998 }
16999 }
17000 };
17001 this._initField = () => {
17002 const {
17003 columns,
17004 rows
17005 } = this.options;
17006 this.field = new Array(columns);
17007 for (let x = 0; x < columns; x++) {
17008 this.field[x] = new Array(rows);
17009 for (let y = 0; y < rows; y++) {
17010 this.field[x][y] = Vector.origin;
17011 }
17012 }
17013 };
17014 this._resetField = container => {
17015 const sourceOptions = container.actualOptions.particles.move.path.options,
17016 {
17017 options
17018 } = this;
17019 options.size = sourceOptions.size > 0 ? sourceOptions.size : 20;
17020 options.increment = sourceOptions.increment > 0 ? sourceOptions.increment : 0.004;
17021 options.draw = !!sourceOptions.draw;
17022 options.width = container.canvas.size.width;
17023 options.height = container.canvas.size.height;
17024 this.noiseGen.seed(sourceOptions.seed ?? getRandom());
17025 options.columns = Math.floor(this.options.width / this.options.size) + 1;
17026 options.rows = Math.floor(this.options.height / this.options.size) + 1;
17027 this._initField();
17028 };
17029 this._setup = container => {
17030 this.noiseZ = 0;
17031 this._resetField(container);
17032 window.addEventListener("resize", () => this._resetField(container));
17033 };
17034 this.noiseGen = new PerlinNoise();
17035 this.field = [];
17036 this.noiseZ = 0;
17037 this.options = {
17038 draw: false,
17039 size: 20,
17040 increment: 0.004,
17041 columns: 0,
17042 rows: 0,
17043 width: 0,
17044 height: 0
17045 };
17046 }
17047 generate(particle) {
17048 const pos = particle.getPosition(),
17049 {
17050 size
17051 } = this.options,
17052 point = {
17053 x: Math.max(Math.floor(pos.x / size), 0),
17054 y: Math.max(Math.floor(pos.y / size), 0)
17055 },
17056 {
17057 field
17058 } = this;
17059 return !field || !field[point.x] || !field[point.x][point.y] ? Vector.origin : field[point.x][point.y].copy();
17060 }
17061 init(container) {
17062 this.container = container;
17063 this._setup(container);
17064 }
17065 reset() {}
17066 update() {
17067 if (!this.container) {
17068 return;
17069 }
17070 this._calculateField();
17071 this.noiseZ += this.options.increment;
17072 if (this.options.draw) {
17073 this.container.canvas.draw(ctx => this._drawField(ctx));
17074 }
17075 }
17076}
17077;// CONCATENATED MODULE: ../../paths/perlinNoise/dist/esm/index.js
17078
17079const perlinNoisePathName = "perlinNoise";
17080async function loadPerlinNoisePath(engine, refresh = true) {
17081 await engine.addPathGenerator(perlinNoisePathName, new PerlinNoiseGenerator(), refresh);
17082}
17083// EXTERNAL MODULE: ../../plugins/polygonMask/dist/esm/pathseg.js
17084var pathseg = __webpack_require__(442);
17085;// CONCATENATED MODULE: ../../plugins/polygonMask/dist/esm/Options/Classes/PolygonMaskDrawStroke.js
17086
17087class PolygonMaskDrawStroke {
17088 constructor() {
17089 this.color = new OptionsColor();
17090 this.width = 0.5;
17091 this.opacity = 1;
17092 }
17093 load(data) {
17094 if (!data) {
17095 return;
17096 }
17097 this.color = OptionsColor.create(this.color, data.color);
17098 if (isString(this.color.value)) {
17099 this.opacity = stringToAlpha(this.color.value) ?? this.opacity;
17100 }
17101 if (data.opacity !== undefined) {
17102 this.opacity = data.opacity;
17103 }
17104 if (data.width !== undefined) {
17105 this.width = data.width;
17106 }
17107 }
17108}
17109;// CONCATENATED MODULE: ../../plugins/polygonMask/dist/esm/Options/Classes/PolygonMaskDraw.js
17110
17111
17112class PolygonMaskDraw {
17113 constructor() {
17114 this.enable = false;
17115 this.stroke = new PolygonMaskDrawStroke();
17116 }
17117 get lineColor() {
17118 return this.stroke.color;
17119 }
17120 set lineColor(value) {
17121 this.stroke.color = OptionsColor.create(this.stroke.color, value);
17122 }
17123 get lineWidth() {
17124 return this.stroke.width;
17125 }
17126 set lineWidth(value) {
17127 this.stroke.width = value;
17128 }
17129 load(data) {
17130 if (!data) {
17131 return;
17132 }
17133 if (data.enable !== undefined) {
17134 this.enable = data.enable;
17135 }
17136 const stroke = data.stroke ?? {
17137 color: data.lineColor,
17138 width: data.lineWidth
17139 };
17140 this.stroke.load(stroke);
17141 }
17142}
17143;// CONCATENATED MODULE: ../../plugins/polygonMask/dist/esm/Options/Classes/PolygonMaskInline.js
17144class PolygonMaskInline {
17145 constructor() {
17146 this.arrangement = "one-per-point";
17147 }
17148 load(data) {
17149 if (!data) {
17150 return;
17151 }
17152 if (data.arrangement !== undefined) {
17153 this.arrangement = data.arrangement;
17154 }
17155 }
17156}
17157;// CONCATENATED MODULE: ../../plugins/polygonMask/dist/esm/Options/Classes/PolygonMaskLocalSvg.js
17158class PolygonMaskLocalSvg {
17159 constructor() {
17160 this.path = [];
17161 this.size = {
17162 height: 0,
17163 width: 0
17164 };
17165 }
17166 load(data) {
17167 if (!data) {
17168 return;
17169 }
17170 if (data.path !== undefined) {
17171 this.path = data.path;
17172 }
17173 if (data.size !== undefined) {
17174 if (data.size.width !== undefined) {
17175 this.size.width = data.size.width;
17176 }
17177 if (data.size.height !== undefined) {
17178 this.size.height = data.size.height;
17179 }
17180 }
17181 }
17182}
17183;// CONCATENATED MODULE: ../../plugins/polygonMask/dist/esm/Options/Classes/PolygonMaskMove.js
17184class PolygonMaskMove {
17185 constructor() {
17186 this.radius = 10;
17187 this.type = "path";
17188 }
17189 load(data) {
17190 if (!data) {
17191 return;
17192 }
17193 if (data.radius !== undefined) {
17194 this.radius = data.radius;
17195 }
17196 if (data.type !== undefined) {
17197 this.type = data.type;
17198 }
17199 }
17200}
17201;// CONCATENATED MODULE: ../../plugins/polygonMask/dist/esm/Options/Classes/PolygonMask.js
17202
17203
17204
17205
17206
17207class PolygonMask {
17208 constructor() {
17209 this.draw = new PolygonMaskDraw();
17210 this.enable = false;
17211 this.inline = new PolygonMaskInline();
17212 this.move = new PolygonMaskMove();
17213 this.scale = 1;
17214 this.type = "none";
17215 }
17216 get inlineArrangement() {
17217 return this.inline.arrangement;
17218 }
17219 set inlineArrangement(value) {
17220 this.inline.arrangement = value;
17221 }
17222 load(data) {
17223 if (!data) {
17224 return;
17225 }
17226 this.draw.load(data.draw);
17227 this.inline.load(data.inline);
17228 this.move.load(data.move);
17229 if (data.scale !== undefined) {
17230 this.scale = data.scale;
17231 }
17232 if (data.type !== undefined) {
17233 this.type = data.type;
17234 }
17235 if (data.enable !== undefined) {
17236 this.enable = data.enable;
17237 } else {
17238 this.enable = this.type !== "none";
17239 }
17240 if (data.url !== undefined) {
17241 this.url = data.url;
17242 }
17243 if (data.data !== undefined) {
17244 if (isString(data.data)) {
17245 this.data = data.data;
17246 } else {
17247 this.data = new PolygonMaskLocalSvg();
17248 this.data.load(data.data);
17249 }
17250 }
17251 if (data.position !== undefined) {
17252 this.position = deepExtend({}, data.position);
17253 }
17254 }
17255}
17256;// CONCATENATED MODULE: ../../plugins/polygonMask/dist/esm/utils.js
17257
17258function drawPolygonMask(context, rawData, stroke) {
17259 const color = rangeColorToRgb(stroke.color);
17260 if (!color) {
17261 return;
17262 }
17263 context.beginPath();
17264 context.moveTo(rawData[0].x, rawData[0].y);
17265 for (const item of rawData) {
17266 context.lineTo(item.x, item.y);
17267 }
17268 context.closePath();
17269 context.strokeStyle = getStyleFromRgb(color);
17270 context.lineWidth = stroke.width;
17271 context.stroke();
17272}
17273function drawPolygonMaskPath(context, path, stroke, position) {
17274 context.setTransform(1, 0, 0, 1, position.x, position.y);
17275 const color = rangeColorToRgb(stroke.color);
17276 if (!color) {
17277 return;
17278 }
17279 context.strokeStyle = getStyleFromRgb(color, stroke.opacity);
17280 context.lineWidth = stroke.width;
17281 context.stroke(path);
17282 context.setTransform(1, 0, 0, 1, 0, 0);
17283}
17284function parsePaths(paths, scale, offset) {
17285 const res = [];
17286 for (const path of paths) {
17287 const segments = path.element.pathSegList,
17288 len = segments?.numberOfItems ?? 0,
17289 p = {
17290 x: 0,
17291 y: 0
17292 };
17293 for (let i = 0; i < len; i++) {
17294 const segment = segments?.getItem(i),
17295 svgPathSeg = window.SVGPathSeg;
17296 switch (segment?.pathSegType) {
17297 case svgPathSeg.PATHSEG_MOVETO_ABS:
17298 case svgPathSeg.PATHSEG_LINETO_ABS:
17299 case svgPathSeg.PATHSEG_CURVETO_CUBIC_ABS:
17300 case svgPathSeg.PATHSEG_CURVETO_QUADRATIC_ABS:
17301 case svgPathSeg.PATHSEG_ARC_ABS:
17302 case svgPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_ABS:
17303 case svgPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_ABS:
17304 {
17305 const absSeg = segment;
17306 p.x = absSeg.x;
17307 p.y = absSeg.y;
17308 break;
17309 }
17310 case svgPathSeg.PATHSEG_LINETO_HORIZONTAL_ABS:
17311 p.x = segment.x;
17312 break;
17313 case svgPathSeg.PATHSEG_LINETO_VERTICAL_ABS:
17314 p.y = segment.y;
17315 break;
17316 case svgPathSeg.PATHSEG_LINETO_REL:
17317 case svgPathSeg.PATHSEG_MOVETO_REL:
17318 case svgPathSeg.PATHSEG_CURVETO_CUBIC_REL:
17319 case svgPathSeg.PATHSEG_CURVETO_QUADRATIC_REL:
17320 case svgPathSeg.PATHSEG_ARC_REL:
17321 case svgPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_REL:
17322 case svgPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_REL:
17323 {
17324 const relSeg = segment;
17325 p.x += relSeg.x;
17326 p.y += relSeg.y;
17327 break;
17328 }
17329 case svgPathSeg.PATHSEG_LINETO_HORIZONTAL_REL:
17330 p.x += segment.x;
17331 break;
17332 case svgPathSeg.PATHSEG_LINETO_VERTICAL_REL:
17333 p.y += segment.y;
17334 break;
17335 case svgPathSeg.PATHSEG_UNKNOWN:
17336 case svgPathSeg.PATHSEG_CLOSEPATH:
17337 continue;
17338 }
17339 res.push({
17340 x: p.x * scale + offset.x,
17341 y: p.y * scale + offset.y
17342 });
17343 }
17344 }
17345 return res;
17346}
17347function calcClosestPtOnSegment(s1, s2, pos) {
17348 const {
17349 dx: dx1,
17350 dy: dy1
17351 } = getDistances(pos, s1),
17352 {
17353 dx: dx2,
17354 dy: dy2
17355 } = getDistances(s2, s1),
17356 t = (dx1 * dx2 + dy1 * dy2) / (dx2 ** 2 + dy2 ** 2),
17357 res = {
17358 x: s1.x + dx2 * t,
17359 y: s1.y + dy2 * t,
17360 isOnSegment: t >= 0 && t <= 1
17361 };
17362 if (t < 0) {
17363 res.x = s1.x;
17364 res.y = s1.y;
17365 } else if (t > 1) {
17366 res.x = s2.x;
17367 res.y = s2.y;
17368 }
17369 return res;
17370}
17371function segmentBounce(start, stop, velocity) {
17372 const {
17373 dx,
17374 dy
17375 } = getDistances(start, stop),
17376 wallAngle = Math.atan2(dy, dx),
17377 wallNormal = Vector.create(Math.sin(wallAngle), -Math.cos(wallAngle)),
17378 d = 2 * (velocity.x * wallNormal.x + velocity.y * wallNormal.y);
17379 wallNormal.multTo(d);
17380 velocity.subFrom(wallNormal);
17381}
17382;// CONCATENATED MODULE: ../../plugins/polygonMask/dist/esm/PolygonMaskInstance.js
17383
17384
17385const noPolygonDataLoaded = `${errorPrefix} No polygon data loaded.`,
17386 noPolygonFound = `${errorPrefix} No polygon found, you need to specify SVG url in config.`;
17387class PolygonMaskInstance {
17388 constructor(container, engine) {
17389 this._checkInsidePolygon = position => {
17390 const container = this._container,
17391 options = container.actualOptions.polygon;
17392 if (!options?.enable || options.type === "none" || options.type === "inline") {
17393 return true;
17394 }
17395 if (!this.raw) {
17396 throw new Error(noPolygonFound);
17397 }
17398 const canvasSize = container.canvas.size,
17399 x = position?.x ?? getRandom() * canvasSize.width,
17400 y = position?.y ?? getRandom() * canvasSize.height;
17401 let inside = false;
17402 for (let i = 0, j = this.raw.length - 1; i < this.raw.length; j = i++) {
17403 const pi = this.raw[i],
17404 pj = this.raw[j],
17405 intersect = pi.y > y !== pj.y > y && x < (pj.x - pi.x) * (y - pi.y) / (pj.y - pi.y) + pi.x;
17406 if (intersect) {
17407 inside = !inside;
17408 }
17409 }
17410 return options.type === "inside" ? inside : options.type === "outside" ? !inside : false;
17411 };
17412 this._createPath2D = () => {
17413 const container = this._container,
17414 options = container.actualOptions.polygon;
17415 if (!options || !this.paths?.length) {
17416 return;
17417 }
17418 for (const path of this.paths) {
17419 const pathData = path.element?.getAttribute("d");
17420 if (pathData) {
17421 const path2d = new Path2D(pathData),
17422 matrix = document.createElementNS("http://www.w3.org/2000/svg", "svg").createSVGMatrix(),
17423 finalPath = new Path2D(),
17424 transform = matrix.scale(this._scale);
17425 if (finalPath.addPath) {
17426 finalPath.addPath(path2d, transform);
17427 path.path2d = finalPath;
17428 } else {
17429 delete path.path2d;
17430 }
17431 } else {
17432 delete path.path2d;
17433 }
17434 if (path.path2d || !this.raw) {
17435 continue;
17436 }
17437 path.path2d = new Path2D();
17438 path.path2d.moveTo(this.raw[0].x, this.raw[0].y);
17439 this.raw.forEach((pos, i) => {
17440 if (i > 0) {
17441 path.path2d?.lineTo(pos.x, pos.y);
17442 }
17443 });
17444 path.path2d.closePath();
17445 }
17446 };
17447 this._downloadSvgPath = async (svgUrl, force) => {
17448 const options = this._container.actualOptions.polygon;
17449 if (!options) {
17450 return;
17451 }
17452 const url = svgUrl || options.url,
17453 forceDownload = force ?? false;
17454 if (!url || this.paths !== undefined && !forceDownload) {
17455 return this.raw;
17456 }
17457 const req = await fetch(url);
17458 if (!req.ok) {
17459 throw new Error(`${errorPrefix} occurred during polygon mask download`);
17460 }
17461 return this._parseSvgPath(await req.text(), force);
17462 };
17463 this._drawPoints = () => {
17464 if (!this.raw) {
17465 return;
17466 }
17467 for (const item of this.raw) {
17468 this._container.particles.addParticle({
17469 x: item.x,
17470 y: item.y
17471 });
17472 }
17473 };
17474 this._getEquidistantPointByIndex = index => {
17475 const container = this._container,
17476 options = container.actualOptions,
17477 polygonMaskOptions = options.polygon;
17478 if (!polygonMaskOptions) {
17479 return;
17480 }
17481 if (!this.raw || !this.raw.length || !this.paths?.length) {
17482 throw new Error(noPolygonDataLoaded);
17483 }
17484 let offset = 0,
17485 point;
17486 const totalLength = this.paths.reduce((tot, path) => tot + path.length, 0),
17487 distance = totalLength / options.particles.number.value;
17488 for (const path of this.paths) {
17489 const pathDistance = distance * index - offset;
17490 if (pathDistance <= path.length) {
17491 point = path.element.getPointAtLength(pathDistance);
17492 break;
17493 } else {
17494 offset += path.length;
17495 }
17496 }
17497 const scale = this._scale;
17498 return {
17499 x: (point?.x ?? 0) * scale + (this.offset?.x ?? 0),
17500 y: (point?.y ?? 0) * scale + (this.offset?.y ?? 0)
17501 };
17502 };
17503 this._getPointByIndex = index => {
17504 if (!this.raw || !this.raw.length) {
17505 throw new Error(noPolygonDataLoaded);
17506 }
17507 const coords = this.raw[index % this.raw.length];
17508 return {
17509 x: coords.x,
17510 y: coords.y
17511 };
17512 };
17513 this._getRandomPoint = () => {
17514 if (!this.raw || !this.raw.length) {
17515 throw new Error(noPolygonDataLoaded);
17516 }
17517 const coords = itemFromArray(this.raw);
17518 return {
17519 x: coords.x,
17520 y: coords.y
17521 };
17522 };
17523 this._getRandomPointByLength = () => {
17524 const container = this._container,
17525 options = container.actualOptions.polygon;
17526 if (!options) {
17527 return;
17528 }
17529 if (!this.raw || !this.raw.length || !this.paths?.length) {
17530 throw new Error(noPolygonDataLoaded);
17531 }
17532 const path = itemFromArray(this.paths),
17533 distance = Math.floor(getRandom() * path.length) + 1,
17534 point = path.element.getPointAtLength(distance),
17535 scale = this._scale;
17536 return {
17537 x: point.x * scale + (this.offset?.x || 0),
17538 y: point.y * scale + (this.offset?.y || 0)
17539 };
17540 };
17541 this._initRawData = async force => {
17542 const options = this._container.actualOptions.polygon;
17543 if (!options) {
17544 return;
17545 }
17546 if (options.url) {
17547 this.raw = await this._downloadSvgPath(options.url, force);
17548 } else if (options.data) {
17549 const data = options.data;
17550 let svg;
17551 if (isString(data)) {
17552 svg = data;
17553 } else {
17554 const getPath = p => `<path d="${p}" />`,
17555 path = isArray(data.path) ? data.path.map(getPath).join("") : getPath(data.path);
17556 const namespaces = 'xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"';
17557 svg = `<svg ${namespaces} width="${data.size.width}" height="${data.size.height}">${path}</svg>`;
17558 }
17559 this.raw = this._parseSvgPath(svg, force);
17560 }
17561 this._createPath2D();
17562 this._engine.dispatchEvent("polygonMaskLoaded", {
17563 container: this._container
17564 });
17565 };
17566 this._parseSvgPath = (xml, force) => {
17567 const forceDownload = force ?? false;
17568 if (this.paths !== undefined && !forceDownload) {
17569 return this.raw;
17570 }
17571 const container = this._container,
17572 options = container.actualOptions.polygon;
17573 if (!options) {
17574 return;
17575 }
17576 const parser = new DOMParser(),
17577 doc = parser.parseFromString(xml, "image/svg+xml"),
17578 svg = doc.getElementsByTagName("svg")[0];
17579 let svgPaths = svg.getElementsByTagName("path");
17580 if (!svgPaths.length) {
17581 svgPaths = doc.getElementsByTagName("path");
17582 }
17583 this.paths = [];
17584 for (let i = 0; i < svgPaths.length; i++) {
17585 const path = svgPaths.item(i);
17586 if (path) {
17587 this.paths.push({
17588 element: path,
17589 length: path.getTotalLength()
17590 });
17591 }
17592 }
17593 const scale = this._scale;
17594 this.dimension.width = parseFloat(svg.getAttribute("width") ?? "0") * scale;
17595 this.dimension.height = parseFloat(svg.getAttribute("height") ?? "0") * scale;
17596 const position = options.position ?? {
17597 x: 50,
17598 y: 50
17599 },
17600 canvasSize = container.canvas.size;
17601 this.offset = {
17602 x: canvasSize.width * position.x / 100 - this.dimension.width / 2,
17603 y: canvasSize.height * position.y / 100 - this.dimension.height / 2
17604 };
17605 return parsePaths(this.paths, scale, this.offset);
17606 };
17607 this._polygonBounce = (particle, _delta, direction) => {
17608 const options = this._container.actualOptions.polygon;
17609 if (!this.raw || !options?.enable || direction !== "top") {
17610 return false;
17611 }
17612 if (options.type === "inside" || options.type === "outside") {
17613 let closest, dx, dy;
17614 const pos = particle.getPosition(),
17615 radius = particle.getRadius();
17616 for (let i = 0, j = this.raw.length - 1; i < this.raw.length; j = i++) {
17617 const pi = this.raw[i],
17618 pj = this.raw[j];
17619 closest = calcClosestPtOnSegment(pi, pj, pos);
17620 const dist = getDistances(pos, closest);
17621 [dx, dy] = [dist.dx, dist.dy];
17622 if (dist.distance < radius) {
17623 segmentBounce(pi, pj, particle.velocity);
17624 return true;
17625 }
17626 }
17627 if (closest && dx !== undefined && dy !== undefined && !this._checkInsidePolygon(pos)) {
17628 const factor = {
17629 x: 1,
17630 y: 1
17631 },
17632 diameter = radius * 2;
17633 if (pos.x >= closest.x) {
17634 factor.x = -1;
17635 }
17636 if (pos.y >= closest.y) {
17637 factor.y = -1;
17638 }
17639 particle.position.x = closest.x + diameter * factor.x;
17640 particle.position.y = closest.y + diameter * factor.y;
17641 particle.velocity.mult(-1);
17642 return true;
17643 }
17644 } else if (options.type === "inline" && particle.initialPosition) {
17645 const dist = getDistance(particle.initialPosition, particle.getPosition()),
17646 {
17647 velocity
17648 } = particle;
17649 if (dist > this._moveRadius) {
17650 velocity.x = velocity.y / 2 - velocity.x;
17651 velocity.y = velocity.x / 2 - velocity.y;
17652 return true;
17653 }
17654 }
17655 return false;
17656 };
17657 this._randomPoint = () => {
17658 const container = this._container,
17659 options = container.actualOptions.polygon;
17660 if (!options) {
17661 return;
17662 }
17663 let position;
17664 if (options.type === "inline") {
17665 switch (options.inline.arrangement) {
17666 case "random-point":
17667 position = this._getRandomPoint();
17668 break;
17669 case "random-length":
17670 position = this._getRandomPointByLength();
17671 break;
17672 case "equidistant":
17673 position = this._getEquidistantPointByIndex(container.particles.count);
17674 break;
17675 case "one-per-point":
17676 case "per-point":
17677 default:
17678 position = this._getPointByIndex(container.particles.count);
17679 }
17680 } else {
17681 const canvasSize = container.canvas.size;
17682 position = {
17683 x: getRandom() * canvasSize.width,
17684 y: getRandom() * canvasSize.height
17685 };
17686 }
17687 if (this._checkInsidePolygon(position)) {
17688 return position;
17689 } else {
17690 return this._randomPoint();
17691 }
17692 };
17693 this._container = container;
17694 this._engine = engine;
17695 this.dimension = {
17696 height: 0,
17697 width: 0
17698 };
17699 this._moveRadius = 0;
17700 this._scale = 1;
17701 }
17702 clickPositionValid(position) {
17703 const options = this._container.actualOptions.polygon;
17704 return !!options?.enable && options.type !== "none" && options.type !== "inline" && this._checkInsidePolygon(position);
17705 }
17706 draw(context) {
17707 if (!this.paths?.length) {
17708 return;
17709 }
17710 const options = this._container.actualOptions.polygon;
17711 if (!options?.enable) {
17712 return;
17713 }
17714 const polygonDraw = options.draw;
17715 if (!polygonDraw.enable) {
17716 return;
17717 }
17718 const rawData = this.raw;
17719 for (const path of this.paths) {
17720 const path2d = path.path2d;
17721 if (!context) {
17722 continue;
17723 }
17724 if (path2d && this.offset) {
17725 drawPolygonMaskPath(context, path2d, polygonDraw.stroke, this.offset);
17726 } else if (rawData) {
17727 drawPolygonMask(context, rawData, polygonDraw.stroke);
17728 }
17729 }
17730 }
17731 async init() {
17732 const container = this._container,
17733 polygonMaskOptions = container.actualOptions.polygon,
17734 pxRatio = container.retina.pixelRatio;
17735 if (!polygonMaskOptions) {
17736 return;
17737 }
17738 this._moveRadius = polygonMaskOptions.move.radius * pxRatio;
17739 this._scale = polygonMaskOptions.scale * pxRatio;
17740 if (polygonMaskOptions.enable) {
17741 await this._initRawData();
17742 }
17743 }
17744 particleBounce(particle, delta, direction) {
17745 return this._polygonBounce(particle, delta, direction);
17746 }
17747 particlePosition(position) {
17748 const options = this._container.actualOptions.polygon;
17749 if (!(options?.enable && (this.raw?.length ?? 0) > 0)) {
17750 return;
17751 }
17752 return deepExtend({}, position ? position : this._randomPoint());
17753 }
17754 particlesInitialization() {
17755 const options = this._container.actualOptions.polygon;
17756 if (options?.enable && options.type === "inline" && (options.inline.arrangement === "one-per-point" || options.inline.arrangement === "per-point")) {
17757 this._drawPoints();
17758 return true;
17759 }
17760 return false;
17761 }
17762 resize() {
17763 const container = this._container,
17764 options = container.actualOptions.polygon;
17765 if (!(options?.enable && options.type !== "none")) {
17766 return;
17767 }
17768 if (this.redrawTimeout) {
17769 clearTimeout(this.redrawTimeout);
17770 }
17771 this.redrawTimeout = window.setTimeout(async () => {
17772 await this._initRawData(true);
17773 await container.particles.redraw();
17774 }, 250);
17775 }
17776 stop() {
17777 delete this.raw;
17778 delete this.paths;
17779 }
17780}
17781;// CONCATENATED MODULE: ../../plugins/polygonMask/dist/esm/index.js
17782
17783
17784
17785class PolygonMaskPlugin {
17786 constructor(engine) {
17787 this.id = "polygonMask";
17788 this._engine = engine;
17789 }
17790 getPlugin(container) {
17791 return new PolygonMaskInstance(container, this._engine);
17792 }
17793 loadOptions(options, source) {
17794 if (!this.needsPlugin(options) && !this.needsPlugin(source)) {
17795 return;
17796 }
17797 let polygonOptions = options.polygon;
17798 if (polygonOptions?.load === undefined) {
17799 options.polygon = polygonOptions = new PolygonMask();
17800 }
17801 polygonOptions.load(source?.polygon);
17802 }
17803 needsPlugin(options) {
17804 return options?.polygon?.enable ?? (options?.polygon?.type !== undefined && options.polygon.type !== "none");
17805 }
17806}
17807async function loadPolygonMaskPlugin(engine, refresh = true) {
17808 await engine.addPlugin(new PolygonMaskPlugin(engine), refresh);
17809}
17810
17811
17812
17813;// CONCATENATED MODULE: ../../paths/polygon/dist/esm/PolygonPathGenerator.js
17814
17815class PolygonPathGenerator {
17816 constructor() {
17817 this._createDirs = () => {
17818 this.dirsList = [];
17819 for (let i = 0; i < 360; i += 360 / this.options.sides) {
17820 const angle = this.options.angle + i;
17821 this.dirsList.push(Vector.create(Math.cos(angle * Math.PI / 180), Math.sin(angle * Math.PI / 180)));
17822 }
17823 };
17824 this.dirsList = [];
17825 this.options = {
17826 sides: 6,
17827 turnSteps: 20,
17828 angle: 30
17829 };
17830 }
17831 generate(p) {
17832 const {
17833 sides
17834 } = this.options;
17835 if (p.hexStep === undefined) {
17836 p.hexStep = 0;
17837 }
17838 if (p.hexDirection === undefined) {
17839 p.hexDirection = sides === 6 ? (getRandom() * 3 | 0) * 2 : getRandom() * sides | 0;
17840 }
17841 if (p.hexSpeed === undefined) {
17842 p.hexSpeed = p.velocity.length;
17843 }
17844 if (p.hexStep % this.options.turnSteps === 0) {
17845 p.hexDirection = getRandom() > 0.5 ? (p.hexDirection + 1) % sides : (p.hexDirection + sides - 1) % sides;
17846 }
17847 p.velocity.x = 0;
17848 p.velocity.y = 0;
17849 p.hexStep++;
17850 const direction = this.dirsList[p.hexDirection];
17851 return Vector.create(direction.x * p.hexSpeed, direction.y * p.hexSpeed);
17852 }
17853 init(container) {
17854 const options = container.actualOptions.particles.move.path.options;
17855 this.options.sides = options.sides > 0 ? options.sides : 6;
17856 this.options.angle = options.angle ?? 30;
17857 this.options.turnSteps = options.turnSteps >= 0 ? options.turnSteps : 20;
17858 this._createDirs();
17859 }
17860 reset(particle) {
17861 delete particle.hexStep;
17862 delete particle.hexDirection;
17863 delete particle.hexSpeed;
17864 }
17865 update() {}
17866}
17867;// CONCATENATED MODULE: ../../paths/polygon/dist/esm/index.js
17868
17869const polygonPathName = "polygonPathGenerator";
17870async function loadPolygonPath(engine, refresh = true) {
17871 await engine.addPathGenerator(polygonPathName, new PolygonPathGenerator(), refresh);
17872}
17873;// CONCATENATED MODULE: ../../shapes/rounded-polygon/dist/esm/RoundedPolygonDrawer.js
17874
17875function polygon(sides, radius, rot = 0) {
17876 const step = Math.PI * 2 / sides,
17877 path = [];
17878 for (let i = 0; i < sides; i++) {
17879 path.push({
17880 x: Math.cos(i * step + rot) * radius,
17881 y: Math.sin(i * step + rot) * radius
17882 });
17883 }
17884 return path;
17885}
17886function roundedPath(context, path, radius) {
17887 let p1 = path[0],
17888 p2 = path[1];
17889 const len = path.length;
17890 context.moveTo((p1.x + p2.x) / 2, (p1.y + p2.y) / 2);
17891 for (let i = 1; i <= len; i++) {
17892 p1 = p2;
17893 p2 = path[(i + 1) % len];
17894 context.arcTo(p1.x, p1.y, (p1.x + p2.x) / 2, (p1.y + p2.y) / 2, radius);
17895 }
17896}
17897class RoundedPolygonDrawer {
17898 draw(context, particle, radius) {
17899 roundedPath(context, polygon(particle.sides, radius), particle.borderRadius ?? 5);
17900 }
17901 getSidesCount(particle) {
17902 const roundedPolygon = particle.shapeData;
17903 return Math.round(getRangeValue(roundedPolygon?.sides ?? 5));
17904 }
17905 particleInit(container, particle) {
17906 const shapeData = particle.shapeData;
17907 particle.borderRadius = Math.round(getRangeValue(shapeData?.radius ?? 5)) * container.retina.pixelRatio;
17908 }
17909}
17910;// CONCATENATED MODULE: ../../shapes/rounded-polygon/dist/esm/index.js
17911
17912async function loadRoundedPolygonShape(engine, refresh = true) {
17913 await engine.addShape("rounded-polygon", new RoundedPolygonDrawer(), refresh);
17914}
17915;// CONCATENATED MODULE: ../../shapes/rounded-rect/dist/esm/RoundedRectDrawer.js
17916
17917const RoundedRectDrawer_fixFactor = Math.sqrt(2),
17918 drawRoundedRect = (ctx, info, radius = {
17919 topRight: 4,
17920 bottomRight: 4,
17921 bottomLeft: 4,
17922 topLeft: 4
17923 }) => {
17924 const {
17925 x,
17926 y,
17927 width,
17928 height
17929 } = info,
17930 r = x + width,
17931 b = y + height;
17932 ctx.moveTo(x + radius.topLeft, y);
17933 ctx.lineTo(r - radius.topRight, y);
17934 ctx.quadraticCurveTo(r, y, r, y + radius.topRight);
17935 ctx.lineTo(r, y + height - radius.bottomRight);
17936 ctx.quadraticCurveTo(r, b, r - radius.bottomRight, b);
17937 ctx.lineTo(x + radius.bottomLeft, b);
17938 ctx.quadraticCurveTo(x, b, x, b - radius.bottomLeft);
17939 ctx.lineTo(x, y + radius.topLeft);
17940 ctx.quadraticCurveTo(x, y, x + radius.topLeft, y);
17941 };
17942class RoundedRectDrawer {
17943 draw(context, particle, radius) {
17944 const fixedRadius = radius / RoundedRectDrawer_fixFactor,
17945 fixedDiameter = fixedRadius * 2,
17946 borderRadius = particle.borderRadius ?? 5;
17947 if ("roundRect" in context) {
17948 context.roundRect(-fixedRadius, -fixedRadius, fixedDiameter, fixedDiameter, borderRadius);
17949 } else {
17950 drawRoundedRect(context, {
17951 x: -fixedRadius,
17952 y: -fixedRadius,
17953 height: fixedDiameter,
17954 width: fixedDiameter
17955 }, {
17956 topLeft: borderRadius,
17957 topRight: borderRadius,
17958 bottomLeft: borderRadius,
17959 bottomRight: borderRadius
17960 });
17961 }
17962 }
17963 particleInit(container, particle) {
17964 const shapeData = particle.shapeData;
17965 particle.borderRadius = getRangeValue(shapeData?.radius ?? 5) * container.retina.pixelRatio;
17966 }
17967}
17968;// CONCATENATED MODULE: ../../shapes/rounded-rect/dist/esm/index.js
17969
17970async function loadRoundedRectShape(engine, refresh = true) {
17971 await engine.addShape("rounded-rect", new RoundedRectDrawer(), refresh);
17972}
17973;// CONCATENATED MODULE: ../../paths/svg/dist/esm/SVGPathGenerator.js
17974
17975class SVGPathGenerator {
17976 constructor() {
17977 this._paths = [];
17978 this._reverse = false;
17979 this._size = {
17980 width: 0,
17981 height: 0
17982 };
17983 this._scale = 1;
17984 this._offset = {
17985 x: 0,
17986 y: 0,
17987 mode: "percent"
17988 };
17989 this._width = 0;
17990 }
17991 generate(particle, delta) {
17992 const container = particle.container,
17993 pxRatio = container.retina.pixelRatio;
17994 if (particle.svgDirection === undefined) {
17995 particle.svgDirection = getRandom() > 0.5 ? 0 : 1;
17996 }
17997 if (particle.svgPathIndex === undefined) {
17998 particle.svgPathIndex = Math.floor(Math.random() * this._paths.length);
17999 }
18000 if (particle.svgSpeed === undefined) {
18001 particle.svgSpeed = particle.velocity.mult((particle.retina.moveSpeed ?? 1) / 2).length;
18002 }
18003 if (particle.svgStep === undefined) {
18004 particle.svgStep = randomInRange({
18005 min: 0,
18006 max: this._paths[particle.svgPathIndex].length
18007 }) * pxRatio;
18008 }
18009 if (particle.svgOffset === undefined) {
18010 particle.svgOffset = {
18011 width: randomInRange({
18012 min: -this._width / 2,
18013 max: this._width / 2
18014 }) * pxRatio,
18015 height: randomInRange({
18016 min: -this._width / 2,
18017 max: this._width / 2
18018 }) * pxRatio
18019 };
18020 }
18021 if (particle.svgInitialPosition === undefined) {
18022 particle.svgInitialPosition = {
18023 ...particle.position
18024 };
18025 }
18026 particle.velocity.x = 0;
18027 particle.velocity.y = 0;
18028 if (particle.svgDirection === 0) {
18029 particle.svgStep += particle.svgSpeed * delta.factor;
18030 } else {
18031 particle.svgStep -= particle.svgSpeed * delta.factor;
18032 }
18033 let path = this._paths[particle.svgPathIndex];
18034 if (path) {
18035 const pathLength = path.length;
18036 if (particle.svgStep >= pathLength) {
18037 particle.svgPathIndex = particle.svgPathIndex + 1;
18038 if (particle.svgPathIndex >= this._paths.length) {
18039 if (this._reverse) {
18040 particle.svgPathIndex = this._paths.length - 1;
18041 particle.svgDirection = 1;
18042 } else {
18043 particle.svgPathIndex = 0;
18044 particle.svgStep = 0;
18045 }
18046 }
18047 } else if (particle.svgStep <= 0) {
18048 particle.svgPathIndex = particle.svgPathIndex - 1;
18049 if (particle.svgPathIndex < 0) {
18050 if (this._reverse) {
18051 particle.svgPathIndex = 0;
18052 particle.svgDirection = 0;
18053 } else {
18054 particle.svgPathIndex = this._paths.length - 1;
18055 path = this._paths[particle.svgPathIndex];
18056 particle.svgStep = path.length;
18057 }
18058 }
18059 }
18060 path = this._paths[particle.svgPathIndex];
18061 }
18062 if (path) {
18063 const pathElement = path.element,
18064 pos = pathElement.getPointAtLength(particle.svgStep),
18065 canvasSize = particle.container.canvas.size,
18066 offset = getPosition(this._offset, canvasSize),
18067 scale = this._scale * pxRatio;
18068 particle.position.x = (pos.x - this._size.width / 2) * scale + particle.svgInitialPosition.x + offset.x + particle.svgOffset.width;
18069 particle.position.y = (pos.y - this._size.height / 2) * scale + particle.svgInitialPosition.y + offset.y + particle.svgOffset.height;
18070 }
18071 return Vector.origin;
18072 }
18073 init(container) {
18074 const options = container.actualOptions.particles.move.path.options,
18075 position = options.position ?? this._offset;
18076 this._reverse = options.reverse ?? this._reverse;
18077 this._scale = options.scale ?? 1;
18078 this._offset.x = position.x;
18079 this._offset.y = position.y;
18080 this._offset.mode = position.mode;
18081 this._width = options.width ?? 0;
18082 if (options.url && !options.path) {
18083 const url = options.url;
18084 (async () => {
18085 const response = await fetch(url),
18086 data = await response.text();
18087 const parser = new DOMParser(),
18088 doc = parser.parseFromString(data, "image/svg+xml"),
18089 svg = doc.getElementsByTagName("svg")[0];
18090 let svgPaths = svg.getElementsByTagName("path");
18091 if (!svgPaths.length) {
18092 svgPaths = doc.getElementsByTagName("path");
18093 }
18094 this._paths = [];
18095 for (let i = 0; i < svgPaths.length; i++) {
18096 const path = svgPaths.item(i);
18097 if (path) {
18098 this._paths.push({
18099 element: path,
18100 length: path.getTotalLength()
18101 });
18102 }
18103 }
18104 this._size.height = parseFloat(svg.getAttribute("height") ?? "0");
18105 this._size.width = parseFloat(svg.getAttribute("width") ?? "0");
18106 })();
18107 } else if (options.path) {
18108 const path = options.path;
18109 this._paths = [];
18110 for (const item of path.data) {
18111 const element = document.createElementNS("http://www.w3.org/2000/svg", "path");
18112 element.setAttribute("d", item);
18113 this._paths.push({
18114 element,
18115 length: element.getTotalLength()
18116 });
18117 }
18118 this._size.height = path.size.height;
18119 this._size.width = path.size.width;
18120 }
18121 }
18122 reset() {}
18123 update() {}
18124}
18125;// CONCATENATED MODULE: ../../paths/svg/dist/esm/index.js
18126
18127const svgPathName = "svgPathGenerator";
18128async function loadSVGPath(engine, refresh = true) {
18129 await engine.addPathGenerator(svgPathName, new SVGPathGenerator(), refresh);
18130}
18131;// CONCATENATED MODULE: ../../paths/simplexNoise/dist/esm/simplex.js
18132function shuffleSeed(seed) {
18133 const newSeed = new Uint32Array(1);
18134 newSeed[0] = seed[0] * 1664525 + 1013904223;
18135 return newSeed;
18136}
18137const NORM_4D = 1.0 / 30.0;
18138const SQUISH_4D = (Math.sqrt(4 + 1) - 1) / 4;
18139const STRETCH_4D = (1 / Math.sqrt(4 + 1) - 1) / 4;
18140function contribution4D(multiplier, xsb, ysb, zsb, wsb) {
18141 return {
18142 dx: -xsb - multiplier * SQUISH_4D,
18143 dy: -ysb - multiplier * SQUISH_4D,
18144 dz: -zsb - multiplier * SQUISH_4D,
18145 dw: -wsb - multiplier * SQUISH_4D,
18146 xsb,
18147 ysb,
18148 zsb,
18149 wsb
18150 };
18151}
18152function makeNoise4D(clientSeed) {
18153 const contributions = [];
18154 for (let i = 0; i < p4D.length; i += 16) {
18155 const baseSet = base4D[p4D[i]];
18156 let previous = null,
18157 current = null;
18158 for (let k = 0; k < baseSet.length; k += 5) {
18159 current = contribution4D(baseSet[k], baseSet[k + 1], baseSet[k + 2], baseSet[k + 3], baseSet[k + 4]);
18160 if (previous === null) {
18161 contributions[i / 16] = current;
18162 } else {
18163 previous.next = current;
18164 }
18165 previous = current;
18166 }
18167 if (current) {
18168 current.next = contribution4D(p4D[i + 1], p4D[i + 2], p4D[i + 3], p4D[i + 4], p4D[i + 5]);
18169 current.next.next = contribution4D(p4D[i + 6], p4D[i + 7], p4D[i + 8], p4D[i + 9], p4D[i + 10]);
18170 current.next.next.next = contribution4D(p4D[i + 11], p4D[i + 12], p4D[i + 13], p4D[i + 14], p4D[i + 15]);
18171 }
18172 }
18173 const lookup = [];
18174 for (let i = 0; i < lookupPairs4D.length; i += 2) {
18175 lookup[lookupPairs4D[i]] = contributions[lookupPairs4D[i + 1]];
18176 }
18177 const perm = new Uint8Array(256),
18178 perm4D = new Uint8Array(256),
18179 source = new Uint8Array(256);
18180 for (let i = 0; i < 256; i++) {
18181 source[i] = i;
18182 }
18183 let seed = new Uint32Array(1);
18184 seed[0] = clientSeed;
18185 seed = shuffleSeed(shuffleSeed(shuffleSeed(seed)));
18186 for (let i = 255; i >= 0; i--) {
18187 seed = shuffleSeed(seed);
18188 const r = new Uint32Array(1);
18189 r[0] = (seed[0] + 31) % (i + 1);
18190 if (r[0] < 0) {
18191 r[0] += i + 1;
18192 }
18193 perm[i] = source[r[0]];
18194 perm4D[i] = perm[i] & 0xfc;
18195 source[r[0]] = source[i];
18196 }
18197 return (x, y, z, w) => {
18198 const stretchOffset = (x + y + z + w) * STRETCH_4D,
18199 xs = x + stretchOffset,
18200 ys = y + stretchOffset,
18201 zs = z + stretchOffset,
18202 ws = w + stretchOffset,
18203 xsb = Math.floor(xs),
18204 ysb = Math.floor(ys),
18205 zsb = Math.floor(zs),
18206 wsb = Math.floor(ws),
18207 squishOffset = (xsb + ysb + zsb + wsb) * SQUISH_4D,
18208 dx0 = x - (xsb + squishOffset),
18209 dy0 = y - (ysb + squishOffset),
18210 dz0 = z - (zsb + squishOffset),
18211 dw0 = w - (wsb + squishOffset),
18212 xins = xs - xsb,
18213 yins = ys - ysb,
18214 zins = zs - zsb,
18215 wins = ws - wsb,
18216 inSum = xins + yins + zins + wins,
18217 hash = zins - wins + 1 | yins - zins + 1 << 1 | yins - wins + 1 << 2 | xins - yins + 1 << 3 | xins - zins + 1 << 4 | xins - wins + 1 << 5 | inSum << 6 | inSum + wins << 8 | inSum + zins << 11 | inSum + yins << 14 | inSum + xins << 17;
18218 let value = 0;
18219 for (let c = lookup[hash]; c !== undefined; c = c.next) {
18220 const dx = dx0 + c.dx,
18221 dy = dy0 + c.dy,
18222 dz = dz0 + c.dz,
18223 dw = dw0 + c.dw,
18224 attn = 2 - dx * dx - dy * dy - dz * dz - dw * dw;
18225 if (attn > 0) {
18226 const px = xsb + c.xsb,
18227 py = ysb + c.ysb,
18228 pz = zsb + c.zsb,
18229 pw = wsb + c.wsb,
18230 indexPartA = perm[px & 0xff],
18231 indexPartB = perm[indexPartA + py & 0xff],
18232 indexPartC = perm[indexPartB + pz & 0xff],
18233 index = perm4D[indexPartC + pw & 0xff],
18234 valuePart = gradients4D[index] * dx + gradients4D[index + 1] * dy + gradients4D[index + 2] * dz + gradients4D[index + 3] * dw;
18235 value += attn * attn * attn * attn * valuePart;
18236 }
18237 }
18238 return value * NORM_4D;
18239 };
18240}
18241const base4D = [[0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 1], [3, 1, 1, 1, 0, 3, 1, 1, 0, 1, 3, 1, 0, 1, 1, 3, 0, 1, 1, 1, 4, 1, 1, 1, 1], [1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 1, 2, 1, 1, 0, 0, 2, 1, 0, 1, 0, 2, 1, 0, 0, 1, 2, 0, 1, 1, 0, 2, 0, 1, 0, 1, 2, 0, 0, 1, 1], [3, 1, 1, 1, 0, 3, 1, 1, 0, 1, 3, 1, 0, 1, 1, 3, 0, 1, 1, 1, 2, 1, 1, 0, 0, 2, 1, 0, 1, 0, 2, 1, 0, 0, 1, 2, 0, 1, 1, 0, 2, 0, 1, 0, 1, 2, 0, 0, 1, 1]],
18242 gradients4D = [3, 1, 1, 1, 1, 3, 1, 1, 1, 1, 3, 1, 1, 1, 1, 3, -3, 1, 1, 1, -1, 3, 1, 1, -1, 1, 3, 1, -1, 1, 1, 3, 3, -1, 1, 1, 1, -3, 1, 1, 1, -1, 3, 1, 1, -1, 1, 3, -3, -1, 1, 1, -1, -3, 1, 1, -1, -1, 3, 1, -1, -1, 1, 3, 3, 1, -1, 1, 1, 3, -1, 1, 1, 1, -3, 1, 1, 1, -1, 3, -3, 1, -1, 1, -1, 3, -1, 1, -1, 1, -3, 1, -1, 1, -1, 3, 3, -1, -1, 1, 1, -3, -1, 1, 1, -1, -3, 1, 1, -1, -1, 3, -3, -1, -1, 1, -1, -3, -1, 1, -1, -1, -3, 1, -1, -1, -1, 3, 3, 1, 1, -1, 1, 3, 1, -1, 1, 1, 3, -1, 1, 1, 1, -3, -3, 1, 1, -1, -1, 3, 1, -1, -1, 1, 3, -1, -1, 1, 1, -3, 3, -1, 1, -1, 1, -3, 1, -1, 1, -1, 3, -1, 1, -1, 1, -3, -3, -1, 1, -1, -1, -3, 1, -1, -1, -1, 3, -1, -1, -1, 1, -3, 3, 1, -1, -1, 1, 3, -1, -1, 1, 1, -3, -1, 1, 1, -1, -3, -3, 1, -1, -1, -1, 3, -1, -1, -1, 1, -3, -1, -1, 1, -1, -3, 3, -1, -1, -1, 1, -3, -1, -1, 1, -1, -3, -1, 1, -1, -1, -3, -3, -1, -1, -1, -1, -3, -1, -1, -1, -1, -3, -1, -1, -1, -1, -3],
18243 lookupPairs4D = [0, 3, 1, 2, 2, 3, 5, 2, 6, 1, 7, 1, 8, 3, 9, 2, 10, 3, 13, 2, 16, 3, 18, 3, 22, 1, 23, 1, 24, 3, 26, 3, 33, 2, 37, 2, 38, 1, 39, 1, 41, 2, 45, 2, 54, 1, 55, 1, 56, 0, 57, 0, 58, 0, 59, 0, 60, 0, 61, 0, 62, 0, 63, 0, 256, 3, 258, 3, 264, 3, 266, 3, 272, 3, 274, 3, 280, 3, 282, 3, 2049, 2, 2053, 2, 2057, 2, 2061, 2, 2081, 2, 2085, 2, 2089, 2, 2093, 2, 2304, 9, 2305, 9, 2312, 9, 2313, 9, 16390, 1, 16391, 1, 16406, 1, 16407, 1, 16422, 1, 16423, 1, 16438, 1, 16439, 1, 16642, 8, 16646, 8, 16658, 8, 16662, 8, 18437, 6, 18439, 6, 18469, 6, 18471, 6, 18688, 9, 18689, 9, 18690, 8, 18693, 6, 18694, 8, 18695, 6, 18696, 9, 18697, 9, 18706, 8, 18710, 8, 18725, 6, 18727, 6, 131128, 0, 131129, 0, 131130, 0, 131131, 0, 131132, 0, 131133, 0, 131134, 0, 131135, 0, 131352, 7, 131354, 7, 131384, 7, 131386, 7, 133161, 5, 133165, 5, 133177, 5, 133181, 5, 133376, 9, 133377, 9, 133384, 9, 133385, 9, 133400, 7, 133402, 7, 133417, 5, 133421, 5, 133432, 7, 133433, 5, 133434, 7, 133437, 5, 147510, 4, 147511, 4, 147518, 4, 147519, 4, 147714, 8, 147718, 8, 147730, 8, 147734, 8, 147736, 7, 147738, 7, 147766, 4, 147767, 4, 147768, 7, 147770, 7, 147774, 4, 147775, 4, 149509, 6, 149511, 6, 149541, 6, 149543, 6, 149545, 5, 149549, 5, 149558, 4, 149559, 4, 149561, 5, 149565, 5, 149566, 4, 149567, 4, 149760, 9, 149761, 9, 149762, 8, 149765, 6, 149766, 8, 149767, 6, 149768, 9, 149769, 9, 149778, 8, 149782, 8, 149784, 7, 149786, 7, 149797, 6, 149799, 6, 149801, 5, 149805, 5, 149814, 4, 149815, 4, 149816, 7, 149817, 5, 149818, 7, 149821, 5, 149822, 4, 149823, 4, 149824, 37, 149825, 37, 149826, 36, 149829, 34, 149830, 36, 149831, 34, 149832, 37, 149833, 37, 149842, 36, 149846, 36, 149848, 35, 149850, 35, 149861, 34, 149863, 34, 149865, 33, 149869, 33, 149878, 32, 149879, 32, 149880, 35, 149881, 33, 149882, 35, 149885, 33, 149886, 32, 149887, 32, 150080, 49, 150082, 48, 150088, 49, 150098, 48, 150104, 47, 150106, 47, 151873, 46, 151877, 45, 151881, 46, 151909, 45, 151913, 44, 151917, 44, 152128, 49, 152129, 46, 152136, 49, 152137, 46, 166214, 43, 166215, 42, 166230, 43, 166247, 42, 166262, 41, 166263, 41, 166466, 48, 166470, 43, 166482, 48, 166486, 43, 168261, 45, 168263, 42, 168293, 45, 168295, 42, 168512, 31, 168513, 28, 168514, 31, 168517, 28, 168518, 25, 168519, 25, 280952, 40, 280953, 39, 280954, 40, 280957, 39, 280958, 38, 280959, 38, 281176, 47, 281178, 47, 281208, 40, 281210, 40, 282985, 44, 282989, 44, 283001, 39, 283005, 39, 283208, 30, 283209, 27, 283224, 30, 283241, 27, 283256, 22, 283257, 22, 297334, 41, 297335, 41, 297342, 38, 297343, 38, 297554, 29, 297558, 24, 297562, 29, 297590, 24, 297594, 21, 297598, 21, 299365, 26, 299367, 23, 299373, 26, 299383, 23, 299389, 20, 299391, 20, 299584, 31, 299585, 28, 299586, 31, 299589, 28, 299590, 25, 299591, 25, 299592, 30, 299593, 27, 299602, 29, 299606, 24, 299608, 30, 299610, 29, 299621, 26, 299623, 23, 299625, 27, 299629, 26, 299638, 24, 299639, 23, 299640, 22, 299641, 22, 299642, 21, 299645, 20, 299646, 21, 299647, 20, 299648, 61, 299649, 60, 299650, 61, 299653, 60, 299654, 59, 299655, 59, 299656, 58, 299657, 57, 299666, 55, 299670, 54, 299672, 58, 299674, 55, 299685, 52, 299687, 51, 299689, 57, 299693, 52, 299702, 54, 299703, 51, 299704, 56, 299705, 56, 299706, 53, 299709, 50, 299710, 53, 299711, 50, 299904, 61, 299906, 61, 299912, 58, 299922, 55, 299928, 58, 299930, 55, 301697, 60, 301701, 60, 301705, 57, 301733, 52, 301737, 57, 301741, 52, 301952, 79, 301953, 79, 301960, 76, 301961, 76, 316038, 59, 316039, 59, 316054, 54, 316071, 51, 316086, 54, 316087, 51, 316290, 78, 316294, 78, 316306, 73, 316310, 73, 318085, 77, 318087, 77, 318117, 70, 318119, 70, 318336, 79, 318337, 79, 318338, 78, 318341, 77, 318342, 78, 318343, 77, 430776, 56, 430777, 56, 430778, 53, 430781, 50, 430782, 53, 430783, 50, 431000, 75, 431002, 72, 431032, 75, 431034, 72, 432809, 74, 432813, 69, 432825, 74, 432829, 69, 433032, 76, 433033, 76, 433048, 75, 433065, 74, 433080, 75, 433081, 74, 447158, 71, 447159, 68, 447166, 71, 447167, 68, 447378, 73, 447382, 73, 447386, 72, 447414, 71, 447418, 72, 447422, 71, 449189, 70, 449191, 70, 449197, 69, 449207, 68, 449213, 69, 449215, 68, 449408, 67, 449409, 67, 449410, 66, 449413, 64, 449414, 66, 449415, 64, 449416, 67, 449417, 67, 449426, 66, 449430, 66, 449432, 65, 449434, 65, 449445, 64, 449447, 64, 449449, 63, 449453, 63, 449462, 62, 449463, 62, 449464, 65, 449465, 63, 449466, 65, 449469, 63, 449470, 62, 449471, 62, 449472, 19, 449473, 19, 449474, 18, 449477, 16, 449478, 18, 449479, 16, 449480, 19, 449481, 19, 449490, 18, 449494, 18, 449496, 17, 449498, 17, 449509, 16, 449511, 16, 449513, 15, 449517, 15, 449526, 14, 449527, 14, 449528, 17, 449529, 15, 449530, 17, 449533, 15, 449534, 14, 449535, 14, 449728, 19, 449729, 19, 449730, 18, 449734, 18, 449736, 19, 449737, 19, 449746, 18, 449750, 18, 449752, 17, 449754, 17, 449784, 17, 449786, 17, 451520, 19, 451521, 19, 451525, 16, 451527, 16, 451528, 19, 451529, 19, 451557, 16, 451559, 16, 451561, 15, 451565, 15, 451577, 15, 451581, 15, 451776, 19, 451777, 19, 451784, 19, 451785, 19, 465858, 18, 465861, 16, 465862, 18, 465863, 16, 465874, 18, 465878, 18, 465893, 16, 465895, 16, 465910, 14, 465911, 14, 465918, 14, 465919, 14, 466114, 18, 466118, 18, 466130, 18, 466134, 18, 467909, 16, 467911, 16, 467941, 16, 467943, 16, 468160, 13, 468161, 13, 468162, 13, 468163, 13, 468164, 13, 468165, 13, 468166, 13, 468167, 13, 580568, 17, 580570, 17, 580585, 15, 580589, 15, 580598, 14, 580599, 14, 580600, 17, 580601, 15, 580602, 17, 580605, 15, 580606, 14, 580607, 14, 580824, 17, 580826, 17, 580856, 17, 580858, 17, 582633, 15, 582637, 15, 582649, 15, 582653, 15, 582856, 12, 582857, 12, 582872, 12, 582873, 12, 582888, 12, 582889, 12, 582904, 12, 582905, 12, 596982, 14, 596983, 14, 596990, 14, 596991, 14, 597202, 11, 597206, 11, 597210, 11, 597214, 11, 597234, 11, 597238, 11, 597242, 11, 597246, 11, 599013, 10, 599015, 10, 599021, 10, 599023, 10, 599029, 10, 599031, 10, 599037, 10, 599039, 10, 599232, 13, 599233, 13, 599234, 13, 599235, 13, 599236, 13, 599237, 13, 599238, 13, 599239, 13, 599240, 12, 599241, 12, 599250, 11, 599254, 11, 599256, 12, 599257, 12, 599258, 11, 599262, 11, 599269, 10, 599271, 10, 599272, 12, 599273, 12, 599277, 10, 599279, 10, 599282, 11, 599285, 10, 599286, 11, 599287, 10, 599288, 12, 599289, 12, 599290, 11, 599293, 10, 599294, 11, 599295, 10],
18244 p4D = [0, 0, 1, -1, 0, 0, 0, 1, 0, -1, 0, 0, 1, 0, 0, -1, 0, 0, -1, 1, 0, 0, 0, 0, 1, -1, 0, 0, 0, 1, 0, -1, 0, 0, -1, 0, 1, 0, 0, 0, -1, 1, 0, 0, 0, 0, 1, -1, 0, 0, -1, 0, 0, 1, 0, 0, -1, 0, 1, 0, 0, 0, -1, 1, 0, 2, 1, 1, 0, 0, 1, 1, 1, -1, 0, 1, 1, 1, 0, -1, 0, 2, 1, 0, 1, 0, 1, 1, -1, 1, 0, 1, 1, 0, 1, -1, 0, 2, 0, 1, 1, 0, 1, -1, 1, 1, 0, 1, 0, 1, 1, -1, 0, 2, 1, 0, 0, 1, 1, 1, -1, 0, 1, 1, 1, 0, -1, 1, 0, 2, 0, 1, 0, 1, 1, -1, 1, 0, 1, 1, 0, 1, -1, 1, 0, 2, 0, 0, 1, 1, 1, -1, 0, 1, 1, 1, 0, -1, 1, 1, 1, 4, 2, 1, 1, 0, 4, 1, 2, 1, 0, 4, 1, 1, 2, 0, 1, 4, 2, 1, 0, 1, 4, 1, 2, 0, 1, 4, 1, 1, 0, 2, 1, 4, 2, 0, 1, 1, 4, 1, 0, 2, 1, 4, 1, 0, 1, 2, 1, 4, 0, 2, 1, 1, 4, 0, 1, 2, 1, 4, 0, 1, 1, 2, 1, 2, 1, 1, 0, 0, 3, 2, 1, 0, 0, 3, 1, 2, 0, 0, 1, 2, 1, 0, 1, 0, 3, 2, 0, 1, 0, 3, 1, 0, 2, 0, 1, 2, 0, 1, 1, 0, 3, 0, 2, 1, 0, 3, 0, 1, 2, 0, 1, 2, 1, 0, 0, 1, 3, 2, 0, 0, 1, 3, 1, 0, 0, 2, 1, 2, 0, 1, 0, 1, 3, 0, 2, 0, 1, 3, 0, 1, 0, 2, 1, 2, 0, 0, 1, 1, 3, 0, 0, 2, 1, 3, 0, 0, 1, 2, 2, 3, 1, 1, 1, 0, 2, 1, 1, 1, -1, 2, 2, 0, 0, 0, 2, 3, 1, 1, 0, 1, 2, 1, 1, -1, 1, 2, 2, 0, 0, 0, 2, 3, 1, 0, 1, 1, 2, 1, -1, 1, 1, 2, 2, 0, 0, 0, 2, 3, 1, 1, 1, 0, 2, 1, 1, 1, -1, 2, 0, 2, 0, 0, 2, 3, 1, 1, 0, 1, 2, 1, 1, -1, 1, 2, 0, 2, 0, 0, 2, 3, 0, 1, 1, 1, 2, -1, 1, 1, 1, 2, 0, 2, 0, 0, 2, 3, 1, 1, 1, 0, 2, 1, 1, 1, -1, 2, 0, 0, 2, 0, 2, 3, 1, 0, 1, 1, 2, 1, -1, 1, 1, 2, 0, 0, 2, 0, 2, 3, 0, 1, 1, 1, 2, -1, 1, 1, 1, 2, 0, 0, 2, 0, 2, 3, 1, 1, 0, 1, 2, 1, 1, -1, 1, 2, 0, 0, 0, 2, 2, 3, 1, 0, 1, 1, 2, 1, -1, 1, 1, 2, 0, 0, 0, 2, 2, 3, 0, 1, 1, 1, 2, -1, 1, 1, 1, 2, 0, 0, 0, 2, 2, 1, 1, 1, -1, 0, 1, 1, 1, 0, -1, 0, 0, 0, 0, 0, 2, 1, 1, -1, 1, 0, 1, 1, 0, 1, -1, 0, 0, 0, 0, 0, 2, 1, -1, 1, 1, 0, 1, 0, 1, 1, -1, 0, 0, 0, 0, 0, 2, 1, 1, -1, 0, 1, 1, 1, 0, -1, 1, 0, 0, 0, 0, 0, 2, 1, -1, 1, 0, 1, 1, 0, 1, -1, 1, 0, 0, 0, 0, 0, 2, 1, -1, 0, 1, 1, 1, 0, -1, 1, 1, 0, 0, 0, 0, 0, 2, 1, 1, 1, -1, 0, 1, 1, 1, 0, -1, 2, 2, 0, 0, 0, 2, 1, 1, -1, 1, 0, 1, 1, 0, 1, -1, 2, 2, 0, 0, 0, 2, 1, 1, -1, 0, 1, 1, 1, 0, -1, 1, 2, 2, 0, 0, 0, 2, 1, 1, 1, -1, 0, 1, 1, 1, 0, -1, 2, 0, 2, 0, 0, 2, 1, -1, 1, 1, 0, 1, 0, 1, 1, -1, 2, 0, 2, 0, 0, 2, 1, -1, 1, 0, 1, 1, 0, 1, -1, 1, 2, 0, 2, 0, 0, 2, 1, 1, -1, 1, 0, 1, 1, 0, 1, -1, 2, 0, 0, 2, 0, 2, 1, -1, 1, 1, 0, 1, 0, 1, 1, -1, 2, 0, 0, 2, 0, 2, 1, -1, 0, 1, 1, 1, 0, -1, 1, 1, 2, 0, 0, 2, 0, 2, 1, 1, -1, 0, 1, 1, 1, 0, -1, 1, 2, 0, 0, 0, 2, 2, 1, -1, 1, 0, 1, 1, 0, 1, -1, 1, 2, 0, 0, 0, 2, 2, 1, -1, 0, 1, 1, 1, 0, -1, 1, 1, 2, 0, 0, 0, 2, 3, 1, 1, 0, 0, 0, 2, 2, 0, 0, 0, 2, 1, 1, 1, -1, 3, 1, 0, 1, 0, 0, 2, 0, 2, 0, 0, 2, 1, 1, 1, -1, 3, 1, 0, 0, 1, 0, 2, 0, 0, 2, 0, 2, 1, 1, 1, -1, 3, 1, 1, 0, 0, 0, 2, 2, 0, 0, 0, 2, 1, 1, -1, 1, 3, 1, 0, 1, 0, 0, 2, 0, 2, 0, 0, 2, 1, 1, -1, 1, 3, 1, 0, 0, 0, 1, 2, 0, 0, 0, 2, 2, 1, 1, -1, 1, 3, 1, 1, 0, 0, 0, 2, 2, 0, 0, 0, 2, 1, -1, 1, 1, 3, 1, 0, 0, 1, 0, 2, 0, 0, 2, 0, 2, 1, -1, 1, 1, 3, 1, 0, 0, 0, 1, 2, 0, 0, 0, 2, 2, 1, -1, 1, 1, 3, 1, 0, 1, 0, 0, 2, 0, 2, 0, 0, 2, -1, 1, 1, 1, 3, 1, 0, 0, 1, 0, 2, 0, 0, 2, 0, 2, -1, 1, 1, 1, 3, 1, 0, 0, 0, 1, 2, 0, 0, 0, 2, 2, -1, 1, 1, 1, 3, 3, 2, 1, 0, 0, 3, 1, 2, 0, 0, 4, 1, 1, 1, 1, 3, 3, 2, 0, 1, 0, 3, 1, 0, 2, 0, 4, 1, 1, 1, 1, 3, 3, 0, 2, 1, 0, 3, 0, 1, 2, 0, 4, 1, 1, 1, 1, 3, 3, 2, 0, 0, 1, 3, 1, 0, 0, 2, 4, 1, 1, 1, 1, 3, 3, 0, 2, 0, 1, 3, 0, 1, 0, 2, 4, 1, 1, 1, 1, 3, 3, 0, 0, 2, 1, 3, 0, 0, 1, 2, 4, 1, 1, 1, 1, 3, 3, 2, 1, 0, 0, 3, 1, 2, 0, 0, 2, 1, 1, 1, -1, 3, 3, 2, 0, 1, 0, 3, 1, 0, 2, 0, 2, 1, 1, 1, -1, 3, 3, 0, 2, 1, 0, 3, 0, 1, 2, 0, 2, 1, 1, 1, -1, 3, 3, 2, 1, 0, 0, 3, 1, 2, 0, 0, 2, 1, 1, -1, 1, 3, 3, 2, 0, 0, 1, 3, 1, 0, 0, 2, 2, 1, 1, -1, 1, 3, 3, 0, 2, 0, 1, 3, 0, 1, 0, 2, 2, 1, 1, -1, 1, 3, 3, 2, 0, 1, 0, 3, 1, 0, 2, 0, 2, 1, -1, 1, 1, 3, 3, 2, 0, 0, 1, 3, 1, 0, 0, 2, 2, 1, -1, 1, 1, 3, 3, 0, 0, 2, 1, 3, 0, 0, 1, 2, 2, 1, -1, 1, 1, 3, 3, 0, 2, 1, 0, 3, 0, 1, 2, 0, 2, -1, 1, 1, 1, 3, 3, 0, 2, 0, 1, 3, 0, 1, 0, 2, 2, -1, 1, 1, 1, 3, 3, 0, 0, 2, 1, 3, 0, 0, 1, 2, 2, -1, 1, 1, 1];
18245;// CONCATENATED MODULE: ../../paths/simplexNoise/dist/esm/SimplexNoiseGenerator.js
18246
18247
18248class SimplexNoiseGenerator {
18249 constructor() {
18250 this._calculateField = () => {
18251 for (let x = 0; x < this.options.columns; x++) {
18252 for (let y = 0; y < this.options.rows; y++) {
18253 for (let z = 0; z < this.options.layers; z++) {
18254 this.field[x][y][z][0] = this.noiseFunc(x / 50, y / 50, z / 50, this.noiseW) * Math.PI * 2;
18255 this.field[x][y][z][1] = this.noiseFunc(x / 100 + 40000, y / 100 + 40000, z / 100 + 40000, this.noiseW);
18256 }
18257 }
18258 }
18259 };
18260 this._initField = () => {
18261 this.field = new Array(this.options.columns);
18262 for (let x = 0; x < this.options.columns; x++) {
18263 this.field[x] = new Array(this.options.rows);
18264 for (let y = 0; y < this.options.rows; y++) {
18265 this.field[x][y] = new Array(this.options.layers);
18266 for (let z = 0; z < this.options.layers; z++) {
18267 this.field[x][y][z] = [0, 0];
18268 }
18269 }
18270 }
18271 };
18272 this._resetField = container => {
18273 const sourceOptions = container.actualOptions.particles.move.path.options;
18274 this.options.size = sourceOptions.size > 0 ? sourceOptions.size : 20;
18275 this.options.increment = sourceOptions.increment > 0 ? sourceOptions.increment : 0.004;
18276 this.options.width = container.canvas.size.width;
18277 this.options.height = container.canvas.size.height;
18278 this.noiseFunc = makeNoise4D(sourceOptions.seed ?? getRandom());
18279 this.options.columns = Math.floor(this.options.width / this.options.size) + 1;
18280 this.options.rows = Math.floor(this.options.height / this.options.size) + 1;
18281 this.options.layers = Math.floor(container.zLayers / this.options.size) + 1;
18282 this._initField();
18283 };
18284 this._setup = container => {
18285 this.noiseW = 0;
18286 this._resetField(container);
18287 addEventListener("resize", () => this._resetField(container));
18288 };
18289 this.field = [];
18290 this.noiseFunc = makeNoise4D(getRandom());
18291 this.noiseW = 0;
18292 this.options = {
18293 size: 20,
18294 increment: 0.004,
18295 columns: 0,
18296 rows: 0,
18297 layers: 0,
18298 width: 0,
18299 height: 0
18300 };
18301 }
18302 generate(particle) {
18303 const pos = particle.getPosition(),
18304 point = {
18305 x: Math.max(Math.floor(pos.x / this.options.size), 0),
18306 y: Math.max(Math.floor(pos.y / this.options.size), 0),
18307 z: Math.max(Math.floor(pos.z / this.options.size), 0)
18308 },
18309 v = Vector.origin;
18310 if (!this.field || !this.field[point.x] || !this.field[point.x][point.y] || !this.field[point.x][point.y][point.z]) {
18311 return v;
18312 }
18313 v.length = this.field[point.x][point.y][point.z][1];
18314 v.angle = this.field[point.x][point.y][point.z][0];
18315 return v;
18316 }
18317 init(container) {
18318 this.container = container;
18319 this._setup(this.container);
18320 }
18321 reset() {}
18322 update() {
18323 if (!this.container) {
18324 return;
18325 }
18326 this._calculateField();
18327 this.noiseW += this.options.increment;
18328 }
18329}
18330;// CONCATENATED MODULE: ../../paths/simplexNoise/dist/esm/index.js
18331
18332const simplexNoisePathName = "simplexNoise";
18333async function loadSimplexNoisePath(engine, refresh = true) {
18334 await engine.addPathGenerator(simplexNoisePathName, new SimplexNoiseGenerator(), refresh);
18335}
18336;// CONCATENATED MODULE: ../../plugins/sounds/dist/esm/Options/Classes/SoundsAudio.js
18337
18338class SoundsAudio {
18339 constructor() {
18340 this.loop = false;
18341 this.source = "";
18342 }
18343 load(data) {
18344 if (data === undefined) {
18345 return;
18346 }
18347 if (isObject(data)) {
18348 if (data.loop !== undefined) {
18349 this.loop = data.loop;
18350 }
18351 if (data.source !== undefined) {
18352 this.source = data.source;
18353 }
18354 } else {
18355 this.source = data;
18356 }
18357 }
18358}
18359;// CONCATENATED MODULE: ../../plugins/sounds/dist/esm/Options/Classes/SoundsNote.js
18360class SoundsNote {
18361 constructor() {
18362 this.duration = 500;
18363 this.value = [];
18364 }
18365 load(data) {
18366 if (!data) {
18367 return;
18368 }
18369 if (data.duration !== undefined) {
18370 this.duration = data.duration;
18371 }
18372 if (data.value !== undefined) {
18373 this.value = data.value;
18374 }
18375 }
18376}
18377;// CONCATENATED MODULE: ../../plugins/sounds/dist/esm/Options/Classes/SoundsMelody.js
18378
18379class SoundsMelody {
18380 constructor() {
18381 this.loop = false;
18382 this.melodies = [];
18383 this.notes = [];
18384 }
18385 load(data) {
18386 if (data === undefined) {
18387 return;
18388 }
18389 if (data.loop !== undefined) {
18390 this.loop = data.loop;
18391 }
18392 if (data.melodies !== undefined) {
18393 this.melodies = data.melodies.map(s => {
18394 const tmp = new SoundsMelody();
18395 tmp.load(s);
18396 return tmp;
18397 });
18398 }
18399 if (data.notes !== undefined) {
18400 this.notes = data.notes.map(s => {
18401 const tmp = new SoundsNote();
18402 tmp.load(s);
18403 return tmp;
18404 });
18405 }
18406 }
18407}
18408;// CONCATENATED MODULE: ../../plugins/sounds/dist/esm/Options/Classes/SoundsEvent.js
18409
18410
18411
18412
18413class SoundsEvent {
18414 constructor() {
18415 this.event = [];
18416 this.notes = [];
18417 }
18418 load(data) {
18419 if (!data) {
18420 return;
18421 }
18422 if (data.event !== undefined) {
18423 this.event = data.event;
18424 }
18425 if (data.audio !== undefined) {
18426 if (isArray(data.audio)) {
18427 this.audio = data.audio.map(s => {
18428 const tmp = new SoundsAudio();
18429 tmp.load(s);
18430 return tmp;
18431 });
18432 } else {
18433 this.audio = new SoundsAudio();
18434 this.audio.load(data.audio);
18435 }
18436 }
18437 if (data.notes !== undefined) {
18438 this.notes = data.notes.map(t => {
18439 const tmp = new SoundsNote();
18440 tmp.load(t);
18441 return tmp;
18442 });
18443 }
18444 if (data.melodies !== undefined) {
18445 this.melodies = data.melodies.map(t => {
18446 const tmp = new SoundsMelody();
18447 tmp.load(t);
18448 return tmp;
18449 });
18450 }
18451 if (data.filter !== undefined) {
18452 if (isString(data.filter)) {
18453 if (isFunction(window[data.filter])) {
18454 this.filter = window[data.filter];
18455 }
18456 } else {
18457 this.filter = data.filter;
18458 }
18459 }
18460 }
18461}
18462;// CONCATENATED MODULE: ../../plugins/sounds/dist/esm/Options/Classes/SoundsIcon.js
18463class SoundsIcon {
18464 constructor() {
18465 this.width = 24;
18466 this.height = 24;
18467 }
18468 load(data) {
18469 if (!data) {
18470 return;
18471 }
18472 if (data.path !== undefined) {
18473 this.path = data.path;
18474 }
18475 if (data.svg !== undefined) {
18476 this.svg = data.svg;
18477 }
18478 if (data.width !== undefined) {
18479 this.width = data.width;
18480 }
18481 if (data.height !== undefined) {
18482 this.height = data.height;
18483 }
18484 }
18485}
18486;// CONCATENATED MODULE: ../../plugins/sounds/dist/esm/Options/Classes/SoundsIcons.js
18487
18488class SoundsIcons {
18489 constructor() {
18490 this.mute = new SoundsIcon();
18491 this.unmute = new SoundsIcon();
18492 this.volumeDown = new SoundsIcon();
18493 this.volumeUp = new SoundsIcon();
18494 this.mute.svg = `<?xml version="1.0"?>
18495<svg baseProfile="tiny" height="24px" version="1.2" viewBox="0 0 24 24" width="24px"
18496 xml:space="preserve" xmlns="http://www.w3.org/2000/svg"
18497 xmlns:xlink="http://www.w3.org/1999/xlink">
18498 <g id="Layer_1">
18499 <path fill="#fff" d="M19.707,5.293c-0.391-0.391-1.023-0.391-1.414,0l-1.551,1.551c-0.345-0.688-0.987-1.02-1.604-1.02c-0.449,0-0.905,0.152-1.356,0.453l-2.672,1.781C10.357,8.561,8.904,9,8,9c-1.654,0-3,1.346-3,3v2c0,1.237,0.754,2.302,1.826,2.76l-1.533,1.533c-0.391,0.391-0.391,1.023,0,1.414C5.488,19.902,5.744,20,6,20s0.512-0.098,0.707-0.293l2.527-2.527c0.697,0.174,1.416,0.455,1.875,0.762l2.672,1.781c0.451,0.301,0.907,0.453,1.356,0.453C16.035,20.176,17,19.495,17,18V9.414l2.707-2.707C20.098,6.316,20.098,5.684,19.707,5.293z M14.891,7.941c0.038-0.025,0.073-0.046,0.104-0.062C14.998,7.914,15,7.954,15,8v1.293l-2,2V9.202L14.891,7.941z M7,12c0-0.552,0.448-1,1-1c1.211,0,2.907-0.495,4-1.146v2.439l-2.83,2.83C8.757,15.046,8.356,15,8,15c-0.552,0-1-0.448-1-1V12z M10.301,15.406L12,13.707v2.439C11.519,15.859,10.925,15.604,10.301,15.406z M14.994,18.12c-0.03-0.016-0.065-0.036-0.104-0.062L13,16.798v-4.091l2-2V18C15,18.046,14.998,18.086,14.994,18.12z"/>
18500 </g>
18501</svg>`;
18502 this.unmute.svg = `<?xml version="1.0"?>
18503<svg baseProfile="tiny" height="24px" version="1.2" viewBox="0 0 24 24" width="24px"
18504 xml:space="preserve" xmlns="http://www.w3.org/2000/svg"
18505 xmlns:xlink="http://www.w3.org/1999/xlink">
18506 <g id="Layer_1">
18507 <path fill="#fff" d="M17.138,5.824c-0.449,0-0.905,0.152-1.356,0.453l-2.672,1.781C12.357,8.561,10.904,9,10,9c-1.654,0-3,1.346-3,3v2c0,1.654,1.346,3,3,3c0.904,0,2.357,0.439,3.109,0.941l2.672,1.781c0.451,0.301,0.907,0.453,1.356,0.453C18.035,20.176,19,19.495,19,18V8C19,6.505,18.035,5.824,17.138,5.824z M14,16.146C12.907,15.495,11.211,15,10,15c-0.552,0-1-0.448-1-1v-2c0-0.552,0.448-1,1-1c1.211,0,2.907-0.495,4-1.146V16.146z M17,18c0,0.046-0.002,0.086-0.006,0.12c-0.03-0.016-0.065-0.036-0.104-0.062L15,16.798V9.202l1.891-1.261c0.038-0.025,0.073-0.046,0.104-0.062C16.998,7.914,17,7.954,17,8V18z"/>
18508 </g>
18509</svg>`;
18510 this.volumeDown.svg = `<?xml version="1.0"?>
18511<svg baseProfile="tiny" height="24px" version="1.2" viewBox="0 0 24 24" width="24px"
18512 xml:space="preserve" xmlns="http://www.w3.org/2000/svg"
18513 xmlns:xlink="http://www.w3.org/1999/xlink">
18514 <g id="Layer_1">
18515 <path fill="#fff" d="M15.138,5.824c-0.449,0-0.905,0.152-1.356,0.453l-2.672,1.781C10.357,8.561,8.904,9,8,9c-1.654,0-3,1.346-3,3v2c0,1.654,1.346,3,3,3c0.904,0,2.357,0.439,3.109,0.941l2.672,1.781c0.451,0.301,0.907,0.453,1.356,0.453C16.035,20.176,17,19.495,17,18V8C17,6.505,16.035,5.824,15.138,5.824z M8,15c-0.552,0-1-0.448-1-1v-2c0-0.552,0.448-1,1-1c1.211,0,2.907-0.495,4-1.146v6.293C10.907,15.495,9.211,15,8,15z M15,18c0,0.046-0.002,0.086-0.006,0.12c-0.03-0.016-0.065-0.036-0.104-0.062L13,16.798V9.202l1.891-1.261c0.038-0.025,0.073-0.046,0.104-0.062C14.998,7.914,15,7.954,15,8V18z"/>
18516 <path fill="#fff" d="M18.292,10.294c-0.39,0.391-0.39,1.023,0.002,1.414c0.345,0.345,0.535,0.803,0.535,1.291c0,0.489-0.19,0.948-0.536,1.294c-0.391,0.39-0.391,1.023,0,1.414C18.488,15.902,18.744,16,19,16s0.512-0.098,0.707-0.293c0.724-0.723,1.122-1.685,1.122-2.708s-0.398-1.984-1.123-2.707C19.317,9.903,18.683,9.901,18.292,10.294z"/>
18517 </g>
18518</svg>`;
18519 this.volumeUp.svg = `<?xml version="1.0"?>
18520<svg baseProfile="tiny" height="24px" version="1.2" viewBox="0 0 24 24" width="24px"
18521 xml:space="preserve" xmlns="http://www.w3.org/2000/svg"
18522 xmlns:xlink="http://www.w3.org/1999/xlink">
18523 <g id="Layer_1">
18524 <path fill="#fff" d="M16.706,10.292c-0.389-0.389-1.023-0.391-1.414,0.002c-0.39,0.391-0.39,1.023,0.002,1.414c0.345,0.345,0.535,0.803,0.535,1.291c0,0.489-0.19,0.948-0.536,1.294c-0.391,0.39-0.391,1.023,0,1.414C15.488,15.902,15.744,16,16,16s0.512-0.098,0.707-0.293c0.724-0.723,1.122-1.685,1.122-2.708S17.431,11.015,16.706,10.292z"/>
18525 <path fill="#fff" d="M18.706,8.292c-0.391-0.389-1.023-0.39-1.414,0.002c-0.39,0.391-0.39,1.024,0.002,1.414c0.879,0.877,1.363,2.044,1.364,3.287c0.001,1.246-0.484,2.417-1.365,3.298c-0.391,0.391-0.391,1.023,0,1.414C17.488,17.902,17.744,18,18,18s0.512-0.098,0.707-0.293c1.259-1.259,1.952-2.933,1.951-4.713C20.657,11.217,19.964,9.547,18.706,8.292z"/>
18526 <path fill="#fff" d="M20.706,6.292c-0.391-0.389-1.023-0.39-1.414,0.002c-0.39,0.391-0.39,1.024,0.002,1.414c1.412,1.409,2.191,3.285,2.192,5.284c0.002,2.002-0.777,3.885-2.193,5.301c-0.391,0.391-0.391,1.023,0,1.414C19.488,19.902,19.744,20,20,20s0.512-0.098,0.707-0.293c1.794-1.794,2.781-4.18,2.779-6.717C23.485,10.457,22.497,8.078,20.706,6.292z"/>
18527 <path fill="#fff" d="M12.138,5.824c-0.449,0-0.905,0.152-1.356,0.453L8.109,8.059C7.357,8.561,5.904,9,5,9c-1.654,0-3,1.346-3,3v2c0,1.654,1.346,3,3,3c0.904,0,2.357,0.439,3.109,0.941l2.672,1.781c0.451,0.301,0.907,0.453,1.356,0.453C13.035,20.176,14,19.495,14,18V8C14,6.505,13.035,5.824,12.138,5.824z M5,15c-0.552,0-1-0.448-1-1v-2c0-0.552,0.448-1,1-1c1.211,0,2.907-0.495,4-1.146v6.293C7.907,15.495,6.211,15,5,15z M12,18c0,0.046-0.002,0.086-0.006,0.12c-0.03-0.016-0.065-0.036-0.104-0.062L10,16.798V9.202l1.891-1.261c0.038-0.025,0.073-0.046,0.104-0.062C11.998,7.914,12,7.954,12,8V18z"/>
18528 </g>
18529</svg>`;
18530 }
18531 load(data) {
18532 if (!data) {
18533 return;
18534 }
18535 this.mute.load(data.mute);
18536 this.unmute.load(data.unmute);
18537 this.volumeDown.load(data.volumeDown);
18538 this.volumeUp.load(data.volumeUp);
18539 }
18540}
18541;// CONCATENATED MODULE: ../../plugins/sounds/dist/esm/Options/Classes/SoundsVolume.js
18542
18543class SoundsVolume {
18544 constructor() {
18545 this.value = 100;
18546 this.max = 100;
18547 this.min = 0;
18548 this.step = 10;
18549 }
18550 load(data) {
18551 if (data === undefined) {
18552 return;
18553 }
18554 if (isObject(data)) {
18555 if (data.max !== undefined) {
18556 this.max = data.max;
18557 }
18558 if (data.min !== undefined) {
18559 this.min = data.min;
18560 }
18561 if (data.step !== undefined) {
18562 this.step = data.step;
18563 }
18564 if (data.value !== undefined) {
18565 this.value = data.value;
18566 }
18567 } else {
18568 this.value = data;
18569 }
18570 }
18571}
18572;// CONCATENATED MODULE: ../../plugins/sounds/dist/esm/Options/Classes/Sounds.js
18573
18574
18575
18576class Sounds {
18577 constructor() {
18578 this.enable = false;
18579 this.events = [];
18580 this.icons = new SoundsIcons();
18581 this.volume = new SoundsVolume();
18582 }
18583 load(data) {
18584 if (!data) {
18585 return;
18586 }
18587 if (data.enable !== undefined) {
18588 this.enable = data.enable;
18589 }
18590 if (data.events !== undefined) {
18591 this.events = data.events.map(t => {
18592 const event = new SoundsEvent();
18593 event.load(t);
18594 return event;
18595 });
18596 }
18597 this.icons.load(data.icons);
18598 if (data.volume !== undefined) {
18599 this.volume.load(data.volume);
18600 }
18601 }
18602}
18603;// CONCATENATED MODULE: ../../plugins/sounds/dist/esm/utils.js
18604const notes = new Map();
18605notes.set("C", [16.35, 32.7, 65.41, 130.81, 261.63, 523.25, 1046.5, 2093.0, 4186.01]);
18606notes.set("Db", [17.32, 34.65, 69.3, 138.59, 277.18, 554.37, 1108.73, 2217.46, 4434.92]);
18607notes.set("D", [18.35, 36.71, 73.42, 146.83, 293.66, 587.33, 1174.66, 2349.32, 4698.63]);
18608notes.set("Eb", [19.45, 38.89, 77.78, 155.56, 311.13, 622.25, 1244.51, 2489.02, 4978.03]);
18609notes.set("E", [20.6, 41.2, 82.41, 164.81, 329.63, 659.25, 1318.51, 2637.02, 5274.04]);
18610notes.set("F", [21.83, 43.65, 87.31, 174.61, 349.23, 698.46, 1396.91, 2793.83, 5587.65]);
18611notes.set("Gb", [23.12, 46.25, 92.5, 185.0, 369.99, 739.99, 1479.98, 2959.96, 5919.91]);
18612notes.set("G", [24.5, 49.0, 98.0, 196.0, 392.0, 783.99, 1567.98, 3135.96, 6271.93]);
18613notes.set("Ab", [25.96, 51.91, 103.83, 207.65, 415.3, 830.61, 1661.22, 3322.44, 6644.88]);
18614notes.set("A", [27.5, 55.0, 110.0, 220.0, 440.0, 880.0, 1760.0, 3520.0, 7040.0]);
18615notes.set("Bb", [29.14, 58.27, 116.54, 233.08, 466.16, 932.33, 1864.66, 3729.31, 7458.62]);
18616notes.set("B", [30.87, 61.74, 123.47, 246.94, 493.88, 987.77, 1975.53, 3951.07, 7902.13]);
18617notes.set("pause", [0]);
18618function getNoteFrequency(note) {
18619 const regex = /(([A-G]b?)(\d))|pause/i,
18620 result = regex.exec(note);
18621 if (!result || !result.length) {
18622 return;
18623 }
18624 const noteKey = result[2] || result[0],
18625 noteItem = notes.get(noteKey);
18626 if (!noteItem) {
18627 return;
18628 }
18629 return noteItem[parseInt(result[3] || "0")];
18630}
18631;// CONCATENATED MODULE: ../../plugins/sounds/dist/esm/SoundsInstance.js
18632
18633
18634function initImage(data) {
18635 const img = document.createElement("img"),
18636 {
18637 clickCb,
18638 container,
18639 display,
18640 iconOptions,
18641 margin,
18642 options,
18643 pos,
18644 rightOffsets
18645 } = data,
18646 {
18647 width,
18648 path,
18649 svg
18650 } = iconOptions;
18651 setIconStyle(img, pos.top + margin, pos.right - (margin * (rightOffsets.length + 1) + width + rightOffsets.reduce((a, b) => a + b, 0)), display, options.fullScreen.zIndex + 1, width, margin);
18652 img.src = path ?? (svg ? `data:image/svg+xml;base64,${btoa(svg)}` : "");
18653 const parent = container.canvas.element?.parentNode || document.body;
18654 parent.append(img);
18655 img.addEventListener("click", clickCb);
18656 return img;
18657}
18658function removeImage(image) {
18659 if (!image) {
18660 return;
18661 }
18662 image.remove();
18663}
18664function setIconStyle(icon, top, left, display, zIndex, width, margin) {
18665 icon.style.userSelect = "none";
18666 icon.style.webkitUserSelect = "none";
18667 icon.style.position = "absolute";
18668 icon.style.top = `${top + margin}px`;
18669 icon.style.left = `${left - margin - width}px`;
18670 icon.style.display = display;
18671 icon.style.zIndex = `${zIndex + 1}`;
18672}
18673class SoundsInstance {
18674 constructor(container, engine) {
18675 this._addBuffer = audioCtx => {
18676 const buffer = audioCtx.createBufferSource();
18677 this._audioSources.push(buffer);
18678 return buffer;
18679 };
18680 this._addOscillator = audioCtx => {
18681 const oscillator = audioCtx.createOscillator();
18682 this._audioSources.push(oscillator);
18683 return oscillator;
18684 };
18685 this._initEvents = () => {
18686 const container = this._container,
18687 soundsOptions = container.actualOptions.sounds;
18688 if (!soundsOptions?.enable || !container.canvas.element) {
18689 return;
18690 }
18691 for (const event of soundsOptions.events) {
18692 const cb = async args => {
18693 if (this._container !== args.container) {
18694 return;
18695 }
18696 if (!this._container || this._container.muted || this._container.destroyed) {
18697 executeOnSingleOrMultiple(event.event, item => {
18698 this._engine.removeEventListener(item, cb);
18699 });
18700 return;
18701 }
18702 if (event.filter && !event.filter(args)) {
18703 return;
18704 }
18705 if (event.audio) {
18706 this._playBuffer(itemFromSingleOrMultiple(event.audio));
18707 } else if (event.melodies) {
18708 const melody = itemFromArray(event.melodies);
18709 if (melody.melodies.length) {
18710 await Promise.allSettled(melody.melodies.map(m => this._playNote(m.notes, 0, melody.loop)));
18711 } else {
18712 await this._playNote(melody.notes, 0, melody.loop);
18713 }
18714 } else if (event.notes) {
18715 const note = itemFromArray(event.notes);
18716 await this._playNote([note], 0, false);
18717 }
18718 };
18719 executeOnSingleOrMultiple(event.event, item => {
18720 this._engine.addEventListener(item, cb);
18721 });
18722 }
18723 };
18724 this._mute = () => {
18725 const container = this._container;
18726 if (!container.audioContext) {
18727 return;
18728 }
18729 for (const source of this._audioSources) {
18730 this._removeAudioSource(source);
18731 }
18732 if (this._gain) {
18733 this._gain.disconnect();
18734 }
18735 container.audioContext.close();
18736 container.audioContext = undefined;
18737 this._engine.dispatchEvent("soundsMuted", {
18738 container: this._container
18739 });
18740 };
18741 this._playBuffer = audio => {
18742 const audioBuffer = this._audioMap.get(audio.source);
18743 if (!audioBuffer) {
18744 return;
18745 }
18746 const audioCtx = this._container.audioContext;
18747 if (!audioCtx) {
18748 return;
18749 }
18750 const source = this._addBuffer(audioCtx);
18751 source.loop = audio.loop;
18752 source.buffer = audioBuffer;
18753 source.connect(this._gain ?? audioCtx.destination);
18754 source.start();
18755 };
18756 this._playFrequency = async (frequency, duration) => {
18757 if (!this._container.audioContext || !this._gain) {
18758 return;
18759 }
18760 const oscillator = this._addOscillator(this._container.audioContext);
18761 oscillator.connect(this._gain);
18762 oscillator.type = "sine";
18763 oscillator.frequency.value = frequency;
18764 oscillator.start();
18765 return new Promise(resolve => {
18766 setTimeout(() => {
18767 this._removeAudioSource(oscillator);
18768 resolve();
18769 }, duration);
18770 });
18771 };
18772 this._playMuteSound = () => {
18773 const container = this._container;
18774 if (!container.audioContext) {
18775 return;
18776 }
18777 const gain = container.audioContext.createGain();
18778 gain.connect(container.audioContext.destination);
18779 gain.gain.value = 0;
18780 const oscillator = container.audioContext.createOscillator();
18781 oscillator.connect(gain);
18782 oscillator.type = "sine";
18783 oscillator.frequency.value = 1;
18784 oscillator.start();
18785 setTimeout(() => {
18786 oscillator.stop();
18787 oscillator.disconnect();
18788 gain.disconnect();
18789 });
18790 };
18791 this._playNote = async (notes, noteIdx, loop) => {
18792 if (this._container.muted) {
18793 return;
18794 }
18795 const note = notes[noteIdx];
18796 if (!note) {
18797 return;
18798 }
18799 const value = note.value;
18800 const promises = executeOnSingleOrMultiple(value, async (_, idx) => {
18801 return this._playNoteValue(notes, noteIdx, idx);
18802 });
18803 await (isArray(promises) ? Promise.allSettled(promises) : promises);
18804 let nextNoteIdx = noteIdx + 1;
18805 if (loop && nextNoteIdx >= notes.length) {
18806 nextNoteIdx = nextNoteIdx % notes.length;
18807 }
18808 if (this._container.muted) {
18809 return;
18810 }
18811 await this._playNote(notes, nextNoteIdx, loop);
18812 };
18813 this._playNoteValue = async (notes, noteIdx, valueIdx) => {
18814 const note = notes[noteIdx];
18815 if (!note) {
18816 return;
18817 }
18818 const value = itemFromSingleOrMultiple(note.value, valueIdx, true);
18819 try {
18820 const freq = getNoteFrequency(value);
18821 if (!isNumber(freq)) {
18822 return;
18823 }
18824 await this._playFrequency(freq, note.duration);
18825 } catch (e) {
18826 getLogger().error(e);
18827 }
18828 };
18829 this._removeAudioSource = source => {
18830 source.stop();
18831 source.disconnect();
18832 this._audioSources.splice(this._audioSources.indexOf(source), 1);
18833 };
18834 this._unmute = () => {
18835 const container = this._container,
18836 options = container.actualOptions,
18837 soundsOptions = options.sounds;
18838 if (!soundsOptions) {
18839 return;
18840 }
18841 if (!container.audioContext) {
18842 container.audioContext = new AudioContext();
18843 }
18844 const {
18845 audioContext
18846 } = container;
18847 if (!this._audioSources) {
18848 this._audioSources = [];
18849 }
18850 const gain = audioContext.createGain();
18851 gain.connect(audioContext.destination);
18852 gain.gain.value = soundsOptions.volume.value / 100;
18853 this._gain = gain;
18854 this._initEvents();
18855 this._engine.dispatchEvent("soundsUnmuted", {
18856 container: this._container
18857 });
18858 };
18859 this._updateMuteIcons = () => {
18860 const container = this._container,
18861 muteImg = this._muteImg,
18862 unmuteImg = this._unmuteImg;
18863 if (muteImg) {
18864 muteImg.style.display = container.muted ? "block" : "none";
18865 }
18866 if (unmuteImg) {
18867 unmuteImg.style.display = container.muted ? "none" : "block";
18868 }
18869 };
18870 this._updateMuteStatus = () => {
18871 const container = this._container;
18872 if (container.muted) {
18873 this._mute();
18874 } else {
18875 this._unmute();
18876 this._playMuteSound();
18877 }
18878 };
18879 this._updateVolume = () => {
18880 const container = this._container,
18881 soundsOptions = container.actualOptions.sounds;
18882 if (!soundsOptions?.enable) {
18883 return;
18884 }
18885 clamp(this._volume, soundsOptions.volume.min, soundsOptions.volume.max);
18886 let stateChanged = false;
18887 if (this._volume <= 0 && !container.muted) {
18888 this._volume = 0;
18889 container.muted = true;
18890 stateChanged = true;
18891 } else if (this._volume > 0 && container.muted) {
18892 container.muted = false;
18893 stateChanged = true;
18894 }
18895 if (stateChanged) {
18896 this._updateMuteIcons();
18897 this._updateMuteStatus();
18898 }
18899 if (this._gain?.gain) {
18900 this._gain.gain.value = this._volume / 100;
18901 }
18902 };
18903 this._container = container;
18904 this._engine = engine;
18905 this._volume = 0;
18906 this._audioSources = [];
18907 this._audioMap = new Map();
18908 }
18909 async init() {
18910 const container = this._container,
18911 options = container.actualOptions,
18912 soundsOptions = options.sounds;
18913 if (!soundsOptions?.enable) {
18914 return;
18915 }
18916 this._volume = soundsOptions.volume.value;
18917 const events = soundsOptions.events;
18918 this._audioMap = new Map();
18919 for (const event of events) {
18920 if (!event.audio) {
18921 continue;
18922 }
18923 executeOnSingleOrMultiple(event.audio, async audio => {
18924 const response = await fetch(audio.source);
18925 if (!response.ok) {
18926 return;
18927 }
18928 const arrayBuffer = await response.arrayBuffer();
18929 container.audioContext = new AudioContext();
18930 const audioBuffer = await container.audioContext.decodeAudioData(arrayBuffer);
18931 this._audioMap.set(audio.source, audioBuffer);
18932 });
18933 }
18934 }
18935 async start() {
18936 const container = this._container,
18937 options = container.actualOptions,
18938 soundsOptions = options.sounds;
18939 if (!soundsOptions?.enable || !container.canvas.element) {
18940 return;
18941 }
18942 container.muted = true;
18943 const canvas = container.canvas.element,
18944 pos = {
18945 top: canvas.offsetTop,
18946 right: canvas.offsetLeft + canvas.offsetWidth
18947 },
18948 {
18949 mute,
18950 unmute,
18951 volumeDown,
18952 volumeUp
18953 } = soundsOptions.icons,
18954 margin = 10;
18955 const toggleMute = () => {
18956 container.muted = !container.muted;
18957 this._updateMuteIcons();
18958 this._updateMuteStatus();
18959 };
18960 this._muteImg = initImage({
18961 container,
18962 options,
18963 pos,
18964 display: "block",
18965 iconOptions: mute,
18966 margin,
18967 rightOffsets: [volumeDown.width, volumeUp.width],
18968 clickCb: toggleMute
18969 });
18970 this._unmuteImg = initImage({
18971 container,
18972 options,
18973 pos,
18974 display: "none",
18975 iconOptions: unmute,
18976 margin,
18977 rightOffsets: [volumeDown.width, volumeUp.width],
18978 clickCb: toggleMute
18979 });
18980 this._volumeDownImg = initImage({
18981 container,
18982 options,
18983 pos,
18984 display: "block",
18985 iconOptions: volumeDown,
18986 margin,
18987 rightOffsets: [volumeUp.width],
18988 clickCb: () => {
18989 if (container.muted) {
18990 this._volume = 0;
18991 }
18992 this._volume -= soundsOptions.volume.step;
18993 this._updateVolume();
18994 }
18995 });
18996 this._volumeUpImg = initImage({
18997 container,
18998 options,
18999 pos,
19000 display: "block",
19001 iconOptions: volumeUp,
19002 margin,
19003 rightOffsets: [],
19004 clickCb: () => {
19005 if (container.muted) {
19006 this._volume = 0;
19007 }
19008 this._volume += soundsOptions.volume.step;
19009 this._updateVolume();
19010 }
19011 });
19012 }
19013 stop() {
19014 this._container.muted = true;
19015 this._mute();
19016 removeImage(this._muteImg);
19017 removeImage(this._unmuteImg);
19018 removeImage(this._volumeDownImg);
19019 removeImage(this._volumeUpImg);
19020 }
19021}
19022;// CONCATENATED MODULE: ../../plugins/sounds/dist/esm/index.js
19023
19024
19025class SoundsPlugin {
19026 constructor(engine) {
19027 this.id = "sounds";
19028 this._engine = engine;
19029 }
19030 getPlugin(container) {
19031 return new SoundsInstance(container, this._engine);
19032 }
19033 loadOptions(options, source) {
19034 if (!this.needsPlugin(options) && !this.needsPlugin(source)) {
19035 return;
19036 }
19037 let soundsOptions = options.sounds;
19038 if (soundsOptions?.load === undefined) {
19039 options.sounds = soundsOptions = new Sounds();
19040 }
19041 soundsOptions.load(source?.sounds);
19042 }
19043 needsPlugin(options) {
19044 return options?.sounds?.enable ?? false;
19045 }
19046}
19047async function loadSoundsPlugin(engine, refresh = true) {
19048 await engine.addPlugin(new SoundsPlugin(engine), refresh);
19049}
19050;// CONCATENATED MODULE: ../../shapes/spiral/dist/esm/SpiralDrawer.js
19051
19052class SpiralDrawer {
19053 draw(context, particle, radius) {
19054 if (particle.spiralInnerRadius === undefined || particle.spiralLineSpacing === undefined || particle.spiralWidthFactor === undefined) {
19055 return;
19056 }
19057 const realWidth = (radius - particle.spiralInnerRadius) / particle.spiralLineSpacing,
19058 widthFactor = 10;
19059 for (let i = 0; i < realWidth * widthFactor; i++) {
19060 const angle = i / widthFactor,
19061 factor = particle.spiralInnerRadius + particle.spiralLineSpacing * angle,
19062 pos = {
19063 x: factor * Math.cos(angle),
19064 y: factor * Math.sin(angle)
19065 };
19066 context.lineTo(pos.x, pos.y);
19067 }
19068 }
19069 particleInit(container, particle) {
19070 const pixelRatio = container.retina.pixelRatio,
19071 shapeData = particle.shapeData;
19072 particle.spiralInnerRadius = getRangeValue(shapeData.innerRadius ?? 1) * pixelRatio;
19073 particle.spiralLineSpacing = getRangeValue(shapeData.lineSpacing ?? 1) * pixelRatio;
19074 particle.spiralWidthFactor = getRangeValue(shapeData.widthFactor ?? 10);
19075 }
19076}
19077;// CONCATENATED MODULE: ../../shapes/spiral/dist/esm/index.js
19078
19079async function loadSpiralShape(engine, refresh = true) {
19080 await engine.addShape("spiral", new SpiralDrawer(), refresh);
19081}
19082;// CONCATENATED MODULE: ./dist/browser/index.js
19083
19084
19085
19086
19087
19088
19089
19090
19091
19092
19093
19094
19095
19096
19097
19098
19099
19100
19101
19102
19103
19104
19105
19106
19107
19108
19109
19110
19111
19112
19113
19114
19115
19116
19117
19118
19119async function loadAll(engine, refresh = true) {
19120 await loadFull(engine, false);
19121 await loadHsvColorPlugin();
19122 await loadEasingBackPlugin();
19123 await loadEasingCircPlugin();
19124 await loadEasingCubicPlugin();
19125 await loadEasingExpoPlugin();
19126 await loadEasingQuartPlugin();
19127 await loadEasingQuintPlugin();
19128 await loadEasingSinePlugin();
19129 await loadHsvColorPlugin();
19130 await loadCanvasMaskPlugin(engine, false);
19131 await loadInfectionPlugin(engine, false);
19132 await loadMotionPlugin(engine, false);
19133 await loadPolygonMaskPlugin(engine, false);
19134 await loadSoundsPlugin(engine, false);
19135 await loadExportImagePlugin(engine, false);
19136 await loadExportJSONPlugin(engine, false);
19137 await loadExportVideoPlugin(engine, false);
19138 await loadLightInteraction(engine, false);
19139 await loadParticlesRepulseInteraction(engine, false);
19140 await loadGradientUpdater(engine, false);
19141 await loadOrbitUpdater(engine, false);
19142 await loadCurvesPath(engine, false);
19143 await loadPerlinNoisePath(engine, false);
19144 await loadPolygonPath(engine, false);
19145 await loadSVGPath(engine, false);
19146 await loadSimplexNoisePath(engine, false);
19147 await loadArrowShape(engine, false);
19148 await loadBubbleShape(engine, false);
19149 await loadCardsShape(engine, false);
19150 await loadCogShape(engine, false);
19151 await loadHeartShape(engine, false);
19152 await loadMultilineTextShape(engine, false);
19153 await loadPathShape(engine, false);
19154 await loadRoundedPolygonShape(engine, false);
19155 await loadRoundedRectShape(engine, false);
19156 await loadSpiralShape(engine, false);
19157 await engine.refresh(refresh);
19158}
19159;// CONCATENATED MODULE: ./dist/browser/bundle.js
19160
19161
19162loadAll(tsParticles);
19163
19164
19165})();
19166
19167/******/ return __webpack_exports__;
19168/******/ })()
19169;
19170});
\No newline at end of file