UNPKG

391 kBJavaScriptView Raw
1(function webpackUniversalModuleDefinition(root, factory) {
2 if (typeof exports === "object" && typeof module === "object") module.exports = factory(); else if (typeof define === "function" && define.amd) define([], factory); else {
3 var a = factory();
4 for (var i in a) (typeof exports === "object" ? exports : root)[i] = a[i];
5 }
6})(this, (function() {
7 return (() => {
8 "use strict";
9 var __webpack_modules__ = {};
10 var __webpack_module_cache__ = {};
11 function __webpack_require__(moduleId) {
12 var cachedModule = __webpack_module_cache__[moduleId];
13 if (cachedModule !== undefined) {
14 return cachedModule.exports;
15 }
16 var module = __webpack_module_cache__[moduleId] = {
17 exports: {}
18 };
19 __webpack_modules__[moduleId](module, module.exports, __webpack_require__);
20 return module.exports;
21 }
22 __webpack_require__.m = __webpack_modules__;
23 (() => {
24 var getProto = Object.getPrototypeOf ? obj => Object.getPrototypeOf(obj) : obj => obj.__proto__;
25 var leafPrototypes;
26 __webpack_require__.t = function(value, mode) {
27 if (mode & 1) value = this(value);
28 if (mode & 8) return value;
29 if (typeof value === "object" && value) {
30 if (mode & 4 && value.__esModule) return value;
31 if (mode & 16 && typeof value.then === "function") return value;
32 }
33 var ns = Object.create(null);
34 __webpack_require__.r(ns);
35 var def = {};
36 leafPrototypes = leafPrototypes || [ null, getProto({}), getProto([]), getProto(getProto) ];
37 for (var current = mode & 2 && value; typeof current == "object" && !~leafPrototypes.indexOf(current); current = getProto(current)) {
38 Object.getOwnPropertyNames(current).forEach((key => def[key] = () => value[key]));
39 }
40 def["default"] = () => value;
41 __webpack_require__.d(ns, def);
42 return ns;
43 };
44 })();
45 (() => {
46 __webpack_require__.d = (exports, definition) => {
47 for (var key in definition) {
48 if (__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {
49 Object.defineProperty(exports, key, {
50 enumerable: true,
51 get: definition[key]
52 });
53 }
54 }
55 };
56 })();
57 (() => {
58 __webpack_require__.f = {};
59 __webpack_require__.e = chunkId => Promise.all(Object.keys(__webpack_require__.f).reduce(((promises, key) => {
60 __webpack_require__.f[key](chunkId, promises);
61 return promises;
62 }), []));
63 })();
64 (() => {
65 __webpack_require__.u = chunkId => "" + "tsparticles.pathseg" + ".js";
66 })();
67 (() => {
68 __webpack_require__.g = function() {
69 if (typeof globalThis === "object") return globalThis;
70 try {
71 return this || new Function("return this")();
72 } catch (e) {
73 if (typeof window === "object") return window;
74 }
75 }();
76 })();
77 (() => {
78 __webpack_require__.o = (obj, prop) => Object.prototype.hasOwnProperty.call(obj, prop);
79 })();
80 (() => {
81 var inProgress = {};
82 var dataWebpackPrefix = "tsparticles:";
83 __webpack_require__.l = (url, done, key, chunkId) => {
84 if (inProgress[url]) {
85 inProgress[url].push(done);
86 return;
87 }
88 var script, needAttach;
89 if (key !== undefined) {
90 var scripts = document.getElementsByTagName("script");
91 for (var i = 0; i < scripts.length; i++) {
92 var s = scripts[i];
93 if (s.getAttribute("src") == url || s.getAttribute("data-webpack") == dataWebpackPrefix + key) {
94 script = s;
95 break;
96 }
97 }
98 }
99 if (!script) {
100 needAttach = true;
101 script = document.createElement("script");
102 script.charset = "utf-8";
103 script.timeout = 120;
104 if (__webpack_require__.nc) {
105 script.setAttribute("nonce", __webpack_require__.nc);
106 }
107 script.setAttribute("data-webpack", dataWebpackPrefix + key);
108 script.src = url;
109 }
110 inProgress[url] = [ done ];
111 var onScriptComplete = (prev, event) => {
112 script.onerror = script.onload = null;
113 clearTimeout(timeout);
114 var doneFns = inProgress[url];
115 delete inProgress[url];
116 script.parentNode && script.parentNode.removeChild(script);
117 doneFns && doneFns.forEach((fn => fn(event)));
118 if (prev) return prev(event);
119 };
120 var timeout = setTimeout(onScriptComplete.bind(null, undefined, {
121 type: "timeout",
122 target: script
123 }), 12e4);
124 script.onerror = onScriptComplete.bind(null, script.onerror);
125 script.onload = onScriptComplete.bind(null, script.onload);
126 needAttach && document.head.appendChild(script);
127 };
128 })();
129 (() => {
130 __webpack_require__.r = exports => {
131 if (typeof Symbol !== "undefined" && Symbol.toStringTag) {
132 Object.defineProperty(exports, Symbol.toStringTag, {
133 value: "Module"
134 });
135 }
136 Object.defineProperty(exports, "__esModule", {
137 value: true
138 });
139 };
140 })();
141 (() => {
142 var scriptUrl;
143 if (__webpack_require__.g.importScripts) scriptUrl = __webpack_require__.g.location + "";
144 var document = __webpack_require__.g.document;
145 if (!scriptUrl && document) {
146 if (document.currentScript) scriptUrl = document.currentScript.src;
147 if (!scriptUrl) {
148 var scripts = document.getElementsByTagName("script");
149 if (scripts.length) scriptUrl = scripts[scripts.length - 1].src;
150 }
151 }
152 if (!scriptUrl) throw new Error("Automatic publicPath is not supported in this browser");
153 scriptUrl = scriptUrl.replace(/#.*$/, "").replace(/\?.*$/, "").replace(/\/[^\/]+$/, "/");
154 __webpack_require__.p = scriptUrl;
155 })();
156 (() => {
157 var installedChunks = {
158 649: 0,
159 155: 0
160 };
161 __webpack_require__.f.j = (chunkId, promises) => {
162 var installedChunkData = __webpack_require__.o(installedChunks, chunkId) ? installedChunks[chunkId] : undefined;
163 if (installedChunkData !== 0) {
164 if (installedChunkData) {
165 promises.push(installedChunkData[2]);
166 } else {
167 if (true) {
168 var promise = new Promise(((resolve, reject) => installedChunkData = installedChunks[chunkId] = [ resolve, reject ]));
169 promises.push(installedChunkData[2] = promise);
170 var url = __webpack_require__.p + __webpack_require__.u(chunkId);
171 var error = new Error;
172 var loadingEnded = event => {
173 if (__webpack_require__.o(installedChunks, chunkId)) {
174 installedChunkData = installedChunks[chunkId];
175 if (installedChunkData !== 0) installedChunks[chunkId] = undefined;
176 if (installedChunkData) {
177 var errorType = event && (event.type === "load" ? "missing" : event.type);
178 var realSrc = event && event.target && event.target.src;
179 error.message = "Loading chunk " + chunkId + " failed.\n(" + errorType + ": " + realSrc + ")";
180 error.name = "ChunkLoadError";
181 error.type = errorType;
182 error.request = realSrc;
183 installedChunkData[1](error);
184 }
185 }
186 };
187 __webpack_require__.l(url, loadingEnded, "chunk-" + chunkId, chunkId);
188 } else installedChunks[chunkId] = 0;
189 }
190 }
191 };
192 var webpackJsonpCallback = (parentChunkLoadingFunction, data) => {
193 var [chunkIds, moreModules, runtime] = data;
194 var moduleId, chunkId, i = 0;
195 if (chunkIds.some((id => installedChunks[id] !== 0))) {
196 for (moduleId in moreModules) {
197 if (__webpack_require__.o(moreModules, moduleId)) {
198 __webpack_require__.m[moduleId] = moreModules[moduleId];
199 }
200 }
201 if (runtime) var result = runtime(__webpack_require__);
202 }
203 if (parentChunkLoadingFunction) parentChunkLoadingFunction(data);
204 for (;i < chunkIds.length; i++) {
205 chunkId = chunkIds[i];
206 if (__webpack_require__.o(installedChunks, chunkId) && installedChunks[chunkId]) {
207 installedChunks[chunkId][0]();
208 }
209 installedChunks[chunkIds[i]] = 0;
210 }
211 };
212 var chunkLoadingGlobal = this["webpackChunktsparticles"] = this["webpackChunktsparticles"] || [];
213 chunkLoadingGlobal.forEach(webpackJsonpCallback.bind(null, 0));
214 chunkLoadingGlobal.push = webpackJsonpCallback.bind(null, chunkLoadingGlobal.push.bind(chunkLoadingGlobal));
215 })();
216 var __webpack_exports__ = {};
217 __webpack_require__.r(__webpack_exports__);
218 __webpack_require__.d(__webpack_exports__, {
219 AbsorberClickMode: () => AbsorberClickMode,
220 AlterType: () => AlterType,
221 AnimationStatus: () => AnimationStatus,
222 Circle: () => Circle,
223 CircleWarp: () => CircleWarp,
224 ClickMode: () => ClickMode,
225 CollisionMode: () => CollisionMode,
226 Constants: () => Constants,
227 Container: () => Container,
228 DestroyMode: () => DestroyMode,
229 DestroyType: () => DestroyType,
230 DivMode: () => DivMode,
231 DivType: () => DivType,
232 EasingType: () => EasingType,
233 EmitterClickMode: () => EmitterClickMode,
234 EmitterShapeType: () => EmitterShapeType,
235 ExternalInteractorBase: () => ExternalInteractorBase,
236 GradientType: () => GradientType,
237 HoverMode: () => HoverMode,
238 InlineArrangement: () => InlineArrangement,
239 InteractivityDetect: () => InteractivityDetect,
240 InteractorType: () => InteractorType,
241 Main: () => Main,
242 MoveDirection: () => MoveDirection,
243 MoveType: () => MoveType,
244 OrbitType: () => OrbitType,
245 OutMode: () => OutMode,
246 OutModeDirection: () => OutModeDirection,
247 Particle: () => Particle,
248 ParticlesInteractorBase: () => ParticlesInteractorBase,
249 Point: () => Point,
250 Rectangle: () => Rectangle,
251 RollMode: () => RollMode,
252 RotateDirection: () => RotateDirection,
253 ShapeType: () => ShapeType,
254 SizeMode: () => SizeMode,
255 StartValueType: () => StartValueType,
256 ThemeMode: () => ThemeMode,
257 TiltDirection: () => TiltDirection,
258 Type: () => Type,
259 Vector: () => Vector,
260 alterHsl: () => alterHsl,
261 animate: () => animate,
262 areBoundsInside: () => areBoundsInside,
263 arrayRandomIndex: () => arrayRandomIndex,
264 calcEasing: () => calcEasing,
265 calculateBounds: () => calculateBounds,
266 cancelAnimation: () => cancelAnimation,
267 circleBounce: () => circleBounce,
268 circleBounceDataFromParticle: () => circleBounceDataFromParticle,
269 clamp: () => clamp,
270 clear: () => clear,
271 collisionVelocity: () => collisionVelocity,
272 colorMix: () => colorMix,
273 colorToHsl: () => colorToHsl,
274 colorToRgb: () => colorToRgb,
275 deepExtend: () => deepExtend,
276 divMode: () => divMode,
277 divModeExecute: () => divModeExecute,
278 drawConnectLine: () => drawConnectLine,
279 drawEllipse: () => drawEllipse,
280 drawGrabLine: () => drawGrabLine,
281 drawLinkLine: () => drawLinkLine,
282 drawLinkTriangle: () => drawLinkTriangle,
283 drawParticle: () => drawParticle,
284 drawParticlePlugin: () => drawParticlePlugin,
285 drawPlugin: () => drawPlugin,
286 drawShape: () => drawShape,
287 drawShapeAfterEffect: () => drawShapeAfterEffect,
288 getDistance: () => getDistance,
289 getDistances: () => getDistances,
290 getHslAnimationFromHsl: () => getHslAnimationFromHsl,
291 getHslFromAnimation: () => getHslFromAnimation,
292 getLinkColor: () => getLinkColor,
293 getLinkRandomColor: () => getLinkRandomColor,
294 getParticleBaseVelocity: () => getParticleBaseVelocity,
295 getParticleDirectionAngle: () => getParticleDirectionAngle,
296 getRandomRgbColor: () => getRandomRgbColor,
297 getRangeMax: () => getRangeMax,
298 getRangeMin: () => getRangeMin,
299 getRangeValue: () => getRangeValue,
300 getStyleFromHsl: () => getStyleFromHsl,
301 getStyleFromHsv: () => getStyleFromHsv,
302 getStyleFromRgb: () => getStyleFromRgb,
303 getValue: () => getValue,
304 gradient: () => gradient,
305 hslToHsv: () => hslToHsv,
306 hslToRgb: () => hslToRgb,
307 hslaToHsva: () => hslaToHsva,
308 hslaToRgba: () => hslaToRgba,
309 hsvToHsl: () => hsvToHsl,
310 hsvToRgb: () => hsvToRgb,
311 hsvaToHsla: () => hsvaToHsla,
312 hsvaToRgba: () => hsvaToRgba,
313 isDivModeEnabled: () => isDivModeEnabled,
314 isInArray: () => isInArray,
315 isPointInside: () => isPointInside,
316 isSsr: () => isSsr,
317 itemFromArray: () => itemFromArray,
318 loadFont: () => loadFont,
319 mix: () => mix,
320 pJSDom: () => pJSDom,
321 paintBase: () => paintBase,
322 particlesJS: () => particlesJS,
323 randomInRange: () => randomInRange,
324 rectBounce: () => rectBounce,
325 rgbToHsl: () => rgbToHsl,
326 rgbToHsv: () => rgbToHsv,
327 rgbaToHsva: () => rgbaToHsva,
328 setRangeValue: () => setRangeValue,
329 singleDivModeExecute: () => singleDivModeExecute,
330 stringToAlpha: () => stringToAlpha,
331 stringToRgb: () => stringToRgb,
332 tsParticles: () => tsParticles
333 });
334 const initPjs = main => {
335 const particlesJS = (tagId, options) => main.load(tagId, options);
336 particlesJS.load = (tagId, pathConfigJson, callback) => {
337 main.loadJSON(tagId, pathConfigJson).then((container => {
338 if (container) {
339 callback(container);
340 }
341 })).catch((() => {
342 callback(undefined);
343 }));
344 };
345 particlesJS.setOnClickHandler = callback => {
346 main.setOnClickHandler(callback);
347 };
348 const pJSDom = main.dom();
349 return {
350 particlesJS,
351 pJSDom
352 };
353 };
354 var MoveDirection;
355 (function(MoveDirection) {
356 MoveDirection["bottom"] = "bottom";
357 MoveDirection["bottomLeft"] = "bottom-left";
358 MoveDirection["bottomRight"] = "bottom-right";
359 MoveDirection["left"] = "left";
360 MoveDirection["none"] = "none";
361 MoveDirection["right"] = "right";
362 MoveDirection["top"] = "top";
363 MoveDirection["topLeft"] = "top-left";
364 MoveDirection["topRight"] = "top-right";
365 })(MoveDirection || (MoveDirection = {}));
366 var RotateDirection;
367 (function(RotateDirection) {
368 RotateDirection["clockwise"] = "clockwise";
369 RotateDirection["counterClockwise"] = "counter-clockwise";
370 RotateDirection["random"] = "random";
371 })(RotateDirection || (RotateDirection = {}));
372 var OutModeDirection;
373 (function(OutModeDirection) {
374 OutModeDirection["bottom"] = "bottom";
375 OutModeDirection["left"] = "left";
376 OutModeDirection["right"] = "right";
377 OutModeDirection["top"] = "top";
378 })(OutModeDirection || (OutModeDirection = {}));
379 var TiltDirection;
380 (function(TiltDirection) {
381 TiltDirection["clockwise"] = "clockwise";
382 TiltDirection["counterClockwise"] = "counter-clockwise";
383 TiltDirection["random"] = "random";
384 })(TiltDirection || (TiltDirection = {}));
385 var ClickMode;
386 (function(ClickMode) {
387 ClickMode["attract"] = "attract";
388 ClickMode["bubble"] = "bubble";
389 ClickMode["push"] = "push";
390 ClickMode["remove"] = "remove";
391 ClickMode["repulse"] = "repulse";
392 ClickMode["pause"] = "pause";
393 ClickMode["trail"] = "trail";
394 })(ClickMode || (ClickMode = {}));
395 var DestroyMode;
396 (function(DestroyMode) {
397 DestroyMode["none"] = "none";
398 DestroyMode["split"] = "split";
399 })(DestroyMode || (DestroyMode = {}));
400 var DivMode;
401 (function(DivMode) {
402 DivMode["bounce"] = "bounce";
403 DivMode["bubble"] = "bubble";
404 DivMode["repulse"] = "repulse";
405 })(DivMode || (DivMode = {}));
406 var HoverMode;
407 (function(HoverMode) {
408 HoverMode["attract"] = "attract";
409 HoverMode["bounce"] = "bounce";
410 HoverMode["bubble"] = "bubble";
411 HoverMode["connect"] = "connect";
412 HoverMode["grab"] = "grab";
413 HoverMode["light"] = "light";
414 HoverMode["repulse"] = "repulse";
415 HoverMode["slow"] = "slow";
416 HoverMode["trail"] = "trail";
417 })(HoverMode || (HoverMode = {}));
418 var CollisionMode;
419 (function(CollisionMode) {
420 CollisionMode["absorb"] = "absorb";
421 CollisionMode["bounce"] = "bounce";
422 CollisionMode["destroy"] = "destroy";
423 })(CollisionMode || (CollisionMode = {}));
424 var OutMode;
425 (function(OutMode) {
426 OutMode["bounce"] = "bounce";
427 OutMode["bounceHorizontal"] = "bounce-horizontal";
428 OutMode["bounceVertical"] = "bounce-vertical";
429 OutMode["none"] = "none";
430 OutMode["out"] = "out";
431 OutMode["destroy"] = "destroy";
432 OutMode["split"] = "split";
433 })(OutMode || (OutMode = {}));
434 var RollMode;
435 (function(RollMode) {
436 RollMode["both"] = "both";
437 RollMode["horizontal"] = "horizontal";
438 RollMode["vertical"] = "vertical";
439 })(RollMode || (RollMode = {}));
440 var SizeMode;
441 (function(SizeMode) {
442 SizeMode["precise"] = "precise";
443 SizeMode["percent"] = "percent";
444 })(SizeMode || (SizeMode = {}));
445 var ThemeMode;
446 (function(ThemeMode) {
447 ThemeMode["any"] = "any";
448 ThemeMode["dark"] = "dark";
449 ThemeMode["light"] = "light";
450 })(ThemeMode || (ThemeMode = {}));
451 var AnimationStatus;
452 (function(AnimationStatus) {
453 AnimationStatus[AnimationStatus["increasing"] = 0] = "increasing";
454 AnimationStatus[AnimationStatus["decreasing"] = 1] = "decreasing";
455 })(AnimationStatus || (AnimationStatus = {}));
456 var AlterType;
457 (function(AlterType) {
458 AlterType["darken"] = "darken";
459 AlterType["enlighten"] = "enlighten";
460 })(AlterType || (AlterType = {}));
461 var DestroyType;
462 (function(DestroyType) {
463 DestroyType["none"] = "none";
464 DestroyType["max"] = "max";
465 DestroyType["min"] = "min";
466 })(DestroyType || (DestroyType = {}));
467 var GradientType;
468 (function(GradientType) {
469 GradientType["linear"] = "linear";
470 GradientType["radial"] = "radial";
471 GradientType["random"] = "random";
472 })(GradientType || (GradientType = {}));
473 var InteractorType;
474 (function(InteractorType) {
475 InteractorType[InteractorType["External"] = 0] = "External";
476 InteractorType[InteractorType["Particles"] = 1] = "Particles";
477 })(InteractorType || (InteractorType = {}));
478 var ShapeType;
479 (function(ShapeType) {
480 ShapeType["char"] = "char";
481 ShapeType["character"] = "character";
482 ShapeType["circle"] = "circle";
483 ShapeType["edge"] = "edge";
484 ShapeType["image"] = "image";
485 ShapeType["images"] = "images";
486 ShapeType["line"] = "line";
487 ShapeType["polygon"] = "polygon";
488 ShapeType["square"] = "square";
489 ShapeType["star"] = "star";
490 ShapeType["triangle"] = "triangle";
491 })(ShapeType || (ShapeType = {}));
492 var StartValueType;
493 (function(StartValueType) {
494 StartValueType["max"] = "max";
495 StartValueType["min"] = "min";
496 StartValueType["random"] = "random";
497 })(StartValueType || (StartValueType = {}));
498 var DivType;
499 (function(DivType) {
500 DivType["circle"] = "circle";
501 DivType["rectangle"] = "rectangle";
502 })(DivType || (DivType = {}));
503 var EasingType;
504 (function(EasingType) {
505 EasingType["easeOutBack"] = "ease-out-back";
506 EasingType["easeOutCirc"] = "ease-out-circ";
507 EasingType["easeOutCubic"] = "ease-out-cubic";
508 EasingType["easeOutQuad"] = "ease-out-quad";
509 EasingType["easeOutQuart"] = "ease-out-quart";
510 EasingType["easeOutQuint"] = "ease-out-quint";
511 EasingType["easeOutExpo"] = "ease-out-expo";
512 EasingType["easeOutSine"] = "ease-out-sine";
513 })(EasingType || (EasingType = {}));
514 var OrbitType;
515 (function(OrbitType) {
516 OrbitType["front"] = "front";
517 OrbitType["back"] = "back";
518 })(OrbitType || (OrbitType = {}));
519 var InteractivityDetect;
520 (function(InteractivityDetect) {
521 InteractivityDetect["canvas"] = "canvas";
522 InteractivityDetect["parent"] = "parent";
523 InteractivityDetect["window"] = "window";
524 })(InteractivityDetect || (InteractivityDetect = {}));
525 class Vector {
526 constructor(x, y) {
527 let defX, defY;
528 if (y === undefined) {
529 if (typeof x === "number") {
530 throw new Error("tsParticles - Vector not initialized correctly");
531 }
532 const coords = x;
533 [defX, defY] = [ coords.x, coords.y ];
534 } else {
535 [defX, defY] = [ x, y ];
536 }
537 this.x = defX;
538 this.y = defY;
539 }
540 static clone(source) {
541 return Vector.create(source.x, source.y);
542 }
543 static create(x, y) {
544 return new Vector(x, y);
545 }
546 static get origin() {
547 return Vector.create(0, 0);
548 }
549 get angle() {
550 return Math.atan2(this.y, this.x);
551 }
552 set angle(angle) {
553 this.updateFromAngle(angle, this.length);
554 }
555 get length() {
556 return Math.sqrt(this.x ** 2 + this.y ** 2);
557 }
558 set length(length) {
559 this.updateFromAngle(this.angle, length);
560 }
561 add(v) {
562 return Vector.create(this.x + v.x, this.y + v.y);
563 }
564 addTo(v) {
565 this.x += v.x;
566 this.y += v.y;
567 }
568 sub(v) {
569 return Vector.create(this.x - v.x, this.y - v.y);
570 }
571 subFrom(v) {
572 this.x -= v.x;
573 this.y -= v.y;
574 }
575 mult(n) {
576 return Vector.create(this.x * n, this.y * n);
577 }
578 multTo(n) {
579 this.x *= n;
580 this.y *= n;
581 }
582 div(n) {
583 return Vector.create(this.x / n, this.y / n);
584 }
585 divTo(n) {
586 this.x /= n;
587 this.y /= n;
588 }
589 distanceTo(v) {
590 return this.sub(v).length;
591 }
592 getLengthSq() {
593 return this.x ** 2 + this.y ** 2;
594 }
595 distanceToSq(v) {
596 return this.sub(v).getLengthSq();
597 }
598 manhattanDistanceTo(v) {
599 return Math.abs(v.x - this.x) + Math.abs(v.y - this.y);
600 }
601 copy() {
602 return Vector.clone(this);
603 }
604 setTo(velocity) {
605 this.x = velocity.x;
606 this.y = velocity.y;
607 }
608 rotate(angle) {
609 return Vector.create(this.x * Math.cos(angle) - this.y * Math.sin(angle), this.x * Math.sin(angle) + this.y * Math.cos(angle));
610 }
611 updateFromAngle(angle, length) {
612 this.x = Math.cos(angle) * length;
613 this.y = Math.sin(angle) * length;
614 }
615 }
616 function clamp(num, min, max) {
617 return Math.min(Math.max(num, min), max);
618 }
619 function mix(comp1, comp2, weight1, weight2) {
620 return Math.floor((comp1 * weight1 + comp2 * weight2) / (weight1 + weight2));
621 }
622 function randomInRange(r) {
623 const max = getRangeMax(r);
624 let min = getRangeMin(r);
625 if (max === min) {
626 min = 0;
627 }
628 return Math.random() * (max - min) + min;
629 }
630 function getRangeValue(value) {
631 return typeof value === "number" ? value : randomInRange(value);
632 }
633 function getRangeMin(value) {
634 return typeof value === "number" ? value : value.min;
635 }
636 function getRangeMax(value) {
637 return typeof value === "number" ? value : value.max;
638 }
639 function setRangeValue(source, value) {
640 if (source === value || value === undefined && typeof source === "number") {
641 return source;
642 }
643 const min = getRangeMin(source), max = getRangeMax(source);
644 return value !== undefined ? {
645 min: Math.min(min, value),
646 max: Math.max(max, value)
647 } : setRangeValue(min, max);
648 }
649 function getValue(options) {
650 const random = options.random;
651 const {enable, minimumValue} = typeof random === "boolean" ? {
652 enable: random,
653 minimumValue: 0
654 } : random;
655 return enable ? getRangeValue(setRangeValue(options.value, minimumValue)) : getRangeValue(options.value);
656 }
657 function getDistances(pointA, pointB) {
658 const dx = pointA.x - pointB.x;
659 const dy = pointA.y - pointB.y;
660 return {
661 dx,
662 dy,
663 distance: Math.sqrt(dx * dx + dy * dy)
664 };
665 }
666 function getDistance(pointA, pointB) {
667 return getDistances(pointA, pointB).distance;
668 }
669 function getParticleDirectionAngle(direction) {
670 if (typeof direction === "number") {
671 return direction * Math.PI / 180;
672 } else {
673 switch (direction) {
674 case MoveDirection.top:
675 return -Math.PI / 2;
676
677 case MoveDirection.topRight:
678 return -Math.PI / 4;
679
680 case MoveDirection.right:
681 return 0;
682
683 case MoveDirection.bottomRight:
684 return Math.PI / 4;
685
686 case MoveDirection.bottom:
687 return Math.PI / 2;
688
689 case MoveDirection.bottomLeft:
690 return 3 * Math.PI / 4;
691
692 case MoveDirection.left:
693 return Math.PI;
694
695 case MoveDirection.topLeft:
696 return -3 * Math.PI / 4;
697
698 case MoveDirection.none:
699 default:
700 return Math.random() * Math.PI * 2;
701 }
702 }
703 }
704 function getParticleBaseVelocity(direction) {
705 const baseVelocity = Vector.origin;
706 baseVelocity.length = 1;
707 baseVelocity.angle = direction;
708 return baseVelocity;
709 }
710 function collisionVelocity(v1, v2, m1, m2) {
711 return Vector.create(v1.x * (m1 - m2) / (m1 + m2) + v2.x * 2 * m2 / (m1 + m2), v1.y);
712 }
713 function calcEasing(value, type) {
714 switch (type) {
715 case EasingType.easeOutQuad:
716 return 1 - (1 - value) ** 2;
717
718 case EasingType.easeOutCubic:
719 return 1 - (1 - value) ** 3;
720
721 case EasingType.easeOutQuart:
722 return 1 - (1 - value) ** 4;
723
724 case EasingType.easeOutQuint:
725 return 1 - (1 - value) ** 5;
726
727 case EasingType.easeOutExpo:
728 return value === 1 ? 1 : 1 - Math.pow(2, -10 * value);
729
730 case EasingType.easeOutSine:
731 return Math.sin(value * Math.PI / 2);
732
733 case EasingType.easeOutBack:
734 {
735 const c1 = 1.70158;
736 const c3 = c1 + 1;
737 return 1 + c3 * Math.pow(value - 1, 3) + c1 * Math.pow(value - 1, 2);
738 }
739
740 case EasingType.easeOutCirc:
741 return Math.sqrt(1 - Math.pow(value - 1, 2));
742
743 default:
744 return value;
745 }
746 }
747 function rectSideBounce(pSide, pOtherSide, rectSide, rectOtherSide, velocity, factor) {
748 const res = {
749 bounced: false
750 };
751 if (pOtherSide.min >= rectOtherSide.min && pOtherSide.min <= rectOtherSide.max && pOtherSide.max >= rectOtherSide.min && pOtherSide.max <= rectOtherSide.max) {
752 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) {
753 res.velocity = velocity * -factor;
754 res.bounced = true;
755 }
756 }
757 return res;
758 }
759 function checkSelector(element, selectors) {
760 if (selectors instanceof Array) {
761 for (const selector of selectors) {
762 if (element.matches(selector)) {
763 return true;
764 }
765 }
766 return false;
767 } else {
768 return element.matches(selectors);
769 }
770 }
771 function isSsr() {
772 return typeof window === "undefined" || !window || typeof window.document === "undefined" || !window.document;
773 }
774 function animate() {
775 return isSsr() ? callback => setTimeout(callback) : callback => (window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame || window.setTimeout)(callback);
776 }
777 function cancelAnimation() {
778 return isSsr() ? handle => clearTimeout(handle) : handle => (window.cancelAnimationFrame || window.webkitCancelRequestAnimationFrame || window.mozCancelRequestAnimationFrame || window.oCancelRequestAnimationFrame || window.msCancelRequestAnimationFrame || window.clearTimeout)(handle);
779 }
780 function isInArray(value, array) {
781 return value === array || array instanceof Array && array.indexOf(value) > -1;
782 }
783 async function loadFont(character) {
784 var _a, _b;
785 try {
786 await document.fonts.load(`${(_a = character.weight) !== null && _a !== void 0 ? _a : "400"} 36px '${(_b = character.font) !== null && _b !== void 0 ? _b : "Verdana"}'`);
787 } catch (_c) {}
788 }
789 function arrayRandomIndex(array) {
790 return Math.floor(Math.random() * array.length);
791 }
792 function itemFromArray(array, index, useIndex = true) {
793 const fixedIndex = index !== undefined && useIndex ? index % array.length : arrayRandomIndex(array);
794 return array[fixedIndex];
795 }
796 function isPointInside(point, size, radius, direction) {
797 return areBoundsInside(calculateBounds(point, radius !== null && radius !== void 0 ? radius : 0), size, direction);
798 }
799 function areBoundsInside(bounds, size, direction) {
800 let inside = true;
801 if (!direction || direction === OutModeDirection.bottom) {
802 inside = bounds.top < size.height;
803 }
804 if (inside && (!direction || direction === OutModeDirection.left)) {
805 inside = bounds.right > 0;
806 }
807 if (inside && (!direction || direction === OutModeDirection.right)) {
808 inside = bounds.left < size.width;
809 }
810 if (inside && (!direction || direction === OutModeDirection.top)) {
811 inside = bounds.bottom > 0;
812 }
813 return inside;
814 }
815 function calculateBounds(point, radius) {
816 return {
817 bottom: point.y + radius,
818 left: point.x - radius,
819 right: point.x + radius,
820 top: point.y - radius
821 };
822 }
823 function deepExtend(destination, ...sources) {
824 for (const source of sources) {
825 if (source === undefined || source === null) {
826 continue;
827 }
828 if (typeof source !== "object") {
829 destination = source;
830 continue;
831 }
832 const sourceIsArray = Array.isArray(source);
833 if (sourceIsArray && (typeof destination !== "object" || !destination || !Array.isArray(destination))) {
834 destination = [];
835 } else if (!sourceIsArray && (typeof destination !== "object" || !destination || Array.isArray(destination))) {
836 destination = {};
837 }
838 for (const key in source) {
839 if (key === "__proto__") {
840 continue;
841 }
842 const sourceDict = source;
843 const value = sourceDict[key];
844 const isObject = typeof value === "object";
845 const destDict = destination;
846 destDict[key] = isObject && Array.isArray(value) ? value.map((v => deepExtend(destDict[key], v))) : deepExtend(destDict[key], value);
847 }
848 }
849 return destination;
850 }
851 function isDivModeEnabled(mode, divs) {
852 return divs instanceof Array ? !!divs.find((t => t.enable && isInArray(mode, t.mode))) : isInArray(mode, divs.mode);
853 }
854 function divModeExecute(mode, divs, callback) {
855 if (divs instanceof Array) {
856 for (const div of divs) {
857 const divMode = div.mode;
858 const divEnabled = div.enable;
859 if (divEnabled && isInArray(mode, divMode)) {
860 singleDivModeExecute(div, callback);
861 }
862 }
863 } else {
864 const divMode = divs.mode;
865 const divEnabled = divs.enable;
866 if (divEnabled && isInArray(mode, divMode)) {
867 singleDivModeExecute(divs, callback);
868 }
869 }
870 }
871 function singleDivModeExecute(div, callback) {
872 const selectors = div.selectors;
873 if (selectors instanceof Array) {
874 for (const selector of selectors) {
875 callback(selector, div);
876 }
877 } else {
878 callback(selectors, div);
879 }
880 }
881 function divMode(divs, element) {
882 if (!element || !divs) {
883 return;
884 }
885 if (divs instanceof Array) {
886 return divs.find((d => checkSelector(element, d.selectors)));
887 } else if (checkSelector(element, divs.selectors)) {
888 return divs;
889 }
890 }
891 function circleBounceDataFromParticle(p) {
892 return {
893 position: p.getPosition(),
894 radius: p.getRadius(),
895 mass: p.getMass(),
896 velocity: p.velocity,
897 factor: Vector.create(getValue(p.options.bounce.horizontal), getValue(p.options.bounce.vertical))
898 };
899 }
900 function circleBounce(p1, p2) {
901 const xVelocityDiff = p1.velocity.x;
902 const yVelocityDiff = p1.velocity.y;
903 const pos1 = p1.position;
904 const pos2 = p2.position;
905 const xDist = pos2.x - pos1.x;
906 const yDist = pos2.y - pos1.y;
907 if (xVelocityDiff * xDist + yVelocityDiff * yDist >= 0) {
908 const angle = -Math.atan2(pos2.y - pos1.y, pos2.x - pos1.x);
909 const m1 = p1.mass;
910 const m2 = p2.mass;
911 const u1 = p1.velocity.rotate(angle);
912 const u2 = p2.velocity.rotate(angle);
913 const v1 = collisionVelocity(u1, u2, m1, m2);
914 const v2 = collisionVelocity(u2, u1, m1, m2);
915 const vFinal1 = v1.rotate(-angle);
916 const vFinal2 = v2.rotate(-angle);
917 p1.velocity.x = vFinal1.x * p1.factor.x;
918 p1.velocity.y = vFinal1.y * p1.factor.y;
919 p2.velocity.x = vFinal2.x * p2.factor.x;
920 p2.velocity.y = vFinal2.y * p2.factor.y;
921 }
922 }
923 function rectBounce(particle, divBounds) {
924 const pPos = particle.getPosition();
925 const size = particle.getRadius();
926 const bounds = calculateBounds(pPos, size);
927 const resH = rectSideBounce({
928 min: bounds.left,
929 max: bounds.right
930 }, {
931 min: bounds.top,
932 max: bounds.bottom
933 }, {
934 min: divBounds.left,
935 max: divBounds.right
936 }, {
937 min: divBounds.top,
938 max: divBounds.bottom
939 }, particle.velocity.x, getValue(particle.options.bounce.horizontal));
940 if (resH.bounced) {
941 if (resH.velocity !== undefined) {
942 particle.velocity.x = resH.velocity;
943 }
944 if (resH.position !== undefined) {
945 particle.position.x = resH.position;
946 }
947 }
948 const resV = rectSideBounce({
949 min: bounds.top,
950 max: bounds.bottom
951 }, {
952 min: bounds.left,
953 max: bounds.right
954 }, {
955 min: divBounds.top,
956 max: divBounds.bottom
957 }, {
958 min: divBounds.left,
959 max: divBounds.right
960 }, particle.velocity.y, getValue(particle.options.bounce.vertical));
961 if (resV.bounced) {
962 if (resV.velocity !== undefined) {
963 particle.velocity.y = resV.velocity;
964 }
965 if (resV.position !== undefined) {
966 particle.position.y = resV.position;
967 }
968 }
969 }
970 class Constants {}
971 Constants.canvasClass = "tsparticles-canvas-el";
972 Constants.randomColorValue = "random";
973 Constants.midColorValue = "mid";
974 Constants.touchEndEvent = "touchend";
975 Constants.mouseDownEvent = "mousedown";
976 Constants.mouseUpEvent = "mouseup";
977 Constants.mouseMoveEvent = "mousemove";
978 Constants.touchStartEvent = "touchstart";
979 Constants.touchMoveEvent = "touchmove";
980 Constants.mouseLeaveEvent = "mouseleave";
981 Constants.mouseOutEvent = "mouseout";
982 Constants.touchCancelEvent = "touchcancel";
983 Constants.resizeEvent = "resize";
984 Constants.visibilityChangeEvent = "visibilitychange";
985 Constants.noPolygonDataLoaded = "No polygon data loaded.";
986 Constants.noPolygonFound = "No polygon found, you need to specify SVG url in config.";
987 function hue2rgb(p, q, t) {
988 let tCalc = t;
989 if (tCalc < 0) {
990 tCalc += 1;
991 }
992 if (tCalc > 1) {
993 tCalc -= 1;
994 }
995 if (tCalc < 1 / 6) {
996 return p + (q - p) * 6 * tCalc;
997 }
998 if (tCalc < 1 / 2) {
999 return q;
1000 }
1001 if (tCalc < 2 / 3) {
1002 return p + (q - p) * (2 / 3 - tCalc) * 6;
1003 }
1004 return p;
1005 }
1006 function stringToRgba(input) {
1007 if (input.startsWith("rgb")) {
1008 const regex = /rgba?\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*(,\s*([\d.]+)\s*)?\)/i;
1009 const result = regex.exec(input);
1010 return result ? {
1011 a: result.length > 4 ? parseFloat(result[5]) : 1,
1012 b: parseInt(result[3], 10),
1013 g: parseInt(result[2], 10),
1014 r: parseInt(result[1], 10)
1015 } : undefined;
1016 } else if (input.startsWith("hsl")) {
1017 const regex = /hsla?\(\s*(\d+)\s*,\s*(\d+)%\s*,\s*(\d+)%\s*(,\s*([\d.]+)\s*)?\)/i;
1018 const result = regex.exec(input);
1019 return result ? hslaToRgba({
1020 a: result.length > 4 ? parseFloat(result[5]) : 1,
1021 h: parseInt(result[1], 10),
1022 l: parseInt(result[3], 10),
1023 s: parseInt(result[2], 10)
1024 }) : undefined;
1025 } else if (input.startsWith("hsv")) {
1026 const regex = /hsva?\(\s*(\d+)°\s*,\s*(\d+)%\s*,\s*(\d+)%\s*(,\s*([\d.]+)\s*)?\)/i;
1027 const result = regex.exec(input);
1028 return result ? hsvaToRgba({
1029 a: result.length > 4 ? parseFloat(result[5]) : 1,
1030 h: parseInt(result[1], 10),
1031 s: parseInt(result[2], 10),
1032 v: parseInt(result[3], 10)
1033 }) : undefined;
1034 } else {
1035 const shorthandRegex = /^#?([a-f\d])([a-f\d])([a-f\d])([a-f\d])?$/i;
1036 const hexFixed = input.replace(shorthandRegex, ((_m, r, g, b, a) => r + r + g + g + b + b + (a !== undefined ? a + a : "")));
1037 const regex = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})?$/i;
1038 const result = regex.exec(hexFixed);
1039 return result ? {
1040 a: result[4] !== undefined ? parseInt(result[4], 16) / 255 : 1,
1041 b: parseInt(result[3], 16),
1042 g: parseInt(result[2], 16),
1043 r: parseInt(result[1], 16)
1044 } : undefined;
1045 }
1046 }
1047 function colorToRgb(input, index, useIndex = true) {
1048 var _a, _b, _c;
1049 if (input === undefined) {
1050 return;
1051 }
1052 const color = typeof input === "string" ? {
1053 value: input
1054 } : input;
1055 let res;
1056 if (typeof color.value === "string") {
1057 if (color.value === Constants.randomColorValue) {
1058 res = getRandomRgbColor();
1059 } else {
1060 res = stringToRgb(color.value);
1061 }
1062 } else {
1063 if (color.value instanceof Array) {
1064 const colorSelected = itemFromArray(color.value, index, useIndex);
1065 res = colorToRgb({
1066 value: colorSelected
1067 });
1068 } else {
1069 const colorValue = color.value;
1070 const rgbColor = (_a = colorValue.rgb) !== null && _a !== void 0 ? _a : color.value;
1071 if (rgbColor.r !== undefined) {
1072 res = rgbColor;
1073 } else {
1074 const hslColor = (_b = colorValue.hsl) !== null && _b !== void 0 ? _b : color.value;
1075 if (hslColor.h !== undefined && hslColor.l !== undefined) {
1076 res = hslToRgb(hslColor);
1077 } else {
1078 const hsvColor = (_c = colorValue.hsv) !== null && _c !== void 0 ? _c : color.value;
1079 if (hsvColor.h !== undefined && hsvColor.v !== undefined) {
1080 res = hsvToRgb(hsvColor);
1081 }
1082 }
1083 }
1084 }
1085 }
1086 return res;
1087 }
1088 function colorToHsl(color, index, useIndex = true) {
1089 const rgb = colorToRgb(color, index, useIndex);
1090 return rgb !== undefined ? rgbToHsl(rgb) : undefined;
1091 }
1092 function rgbToHsl(color) {
1093 const r1 = color.r / 255;
1094 const g1 = color.g / 255;
1095 const b1 = color.b / 255;
1096 const max = Math.max(r1, g1, b1);
1097 const min = Math.min(r1, g1, b1);
1098 const res = {
1099 h: 0,
1100 l: (max + min) / 2,
1101 s: 0
1102 };
1103 if (max != min) {
1104 res.s = res.l < .5 ? (max - min) / (max + min) : (max - min) / (2 - max - min);
1105 res.h = r1 === max ? (g1 - b1) / (max - min) : res.h = g1 === max ? 2 + (b1 - r1) / (max - min) : 4 + (r1 - g1) / (max - min);
1106 }
1107 res.l *= 100;
1108 res.s *= 100;
1109 res.h *= 60;
1110 if (res.h < 0) {
1111 res.h += 360;
1112 }
1113 return res;
1114 }
1115 function stringToAlpha(input) {
1116 var _a;
1117 return (_a = stringToRgba(input)) === null || _a === void 0 ? void 0 : _a.a;
1118 }
1119 function stringToRgb(input) {
1120 return stringToRgba(input);
1121 }
1122 function hslToRgb(hsl) {
1123 const result = {
1124 b: 0,
1125 g: 0,
1126 r: 0
1127 };
1128 const hslPercent = {
1129 h: hsl.h / 360,
1130 l: hsl.l / 100,
1131 s: hsl.s / 100
1132 };
1133 if (hslPercent.s === 0) {
1134 result.b = hslPercent.l;
1135 result.g = hslPercent.l;
1136 result.r = hslPercent.l;
1137 } else {
1138 const q = hslPercent.l < .5 ? hslPercent.l * (1 + hslPercent.s) : hslPercent.l + hslPercent.s - hslPercent.l * hslPercent.s;
1139 const p = 2 * hslPercent.l - q;
1140 result.r = hue2rgb(p, q, hslPercent.h + 1 / 3);
1141 result.g = hue2rgb(p, q, hslPercent.h);
1142 result.b = hue2rgb(p, q, hslPercent.h - 1 / 3);
1143 }
1144 result.r = Math.floor(result.r * 255);
1145 result.g = Math.floor(result.g * 255);
1146 result.b = Math.floor(result.b * 255);
1147 return result;
1148 }
1149 function hslaToRgba(hsla) {
1150 const rgbResult = hslToRgb(hsla);
1151 return {
1152 a: hsla.a,
1153 b: rgbResult.b,
1154 g: rgbResult.g,
1155 r: rgbResult.r
1156 };
1157 }
1158 function hslToHsv(hsl) {
1159 const l = hsl.l / 100, sl = hsl.s / 100;
1160 const v = l + sl * Math.min(l, 1 - l), sv = !v ? 0 : 2 * (1 - l / v);
1161 return {
1162 h: hsl.h,
1163 s: sv * 100,
1164 v: v * 100
1165 };
1166 }
1167 function hslaToHsva(hsla) {
1168 const hsvResult = hslToHsv(hsla);
1169 return {
1170 a: hsla.a,
1171 h: hsvResult.h,
1172 s: hsvResult.s,
1173 v: hsvResult.v
1174 };
1175 }
1176 function hsvToHsl(hsv) {
1177 const v = hsv.v / 100, sv = hsv.s / 100;
1178 const l = v * (1 - sv / 2), sl = l === 0 || l === 1 ? 0 : (v - l) / Math.min(l, 1 - l);
1179 return {
1180 h: hsv.h,
1181 l: l * 100,
1182 s: sl * 100
1183 };
1184 }
1185 function hsvaToHsla(hsva) {
1186 const hslResult = hsvToHsl(hsva);
1187 return {
1188 a: hsva.a,
1189 h: hslResult.h,
1190 l: hslResult.l,
1191 s: hslResult.s
1192 };
1193 }
1194 function hsvToRgb(hsv) {
1195 const result = {
1196 b: 0,
1197 g: 0,
1198 r: 0
1199 };
1200 const hsvPercent = {
1201 h: hsv.h / 60,
1202 s: hsv.s / 100,
1203 v: hsv.v / 100
1204 };
1205 const c = hsvPercent.v * hsvPercent.s, x = c * (1 - Math.abs(hsvPercent.h % 2 - 1));
1206 let tempRgb;
1207 if (hsvPercent.h >= 0 && hsvPercent.h <= 1) {
1208 tempRgb = {
1209 r: c,
1210 g: x,
1211 b: 0
1212 };
1213 } else if (hsvPercent.h > 1 && hsvPercent.h <= 2) {
1214 tempRgb = {
1215 r: x,
1216 g: c,
1217 b: 0
1218 };
1219 } else if (hsvPercent.h > 2 && hsvPercent.h <= 3) {
1220 tempRgb = {
1221 r: 0,
1222 g: c,
1223 b: x
1224 };
1225 } else if (hsvPercent.h > 3 && hsvPercent.h <= 4) {
1226 tempRgb = {
1227 r: 0,
1228 g: x,
1229 b: c
1230 };
1231 } else if (hsvPercent.h > 4 && hsvPercent.h <= 5) {
1232 tempRgb = {
1233 r: x,
1234 g: 0,
1235 b: c
1236 };
1237 } else if (hsvPercent.h > 5 && hsvPercent.h <= 6) {
1238 tempRgb = {
1239 r: c,
1240 g: 0,
1241 b: x
1242 };
1243 }
1244 if (tempRgb) {
1245 const m = hsvPercent.v - c;
1246 result.r = Math.floor((tempRgb.r + m) * 255);
1247 result.g = Math.floor((tempRgb.g + m) * 255);
1248 result.b = Math.floor((tempRgb.b + m) * 255);
1249 }
1250 return result;
1251 }
1252 function hsvaToRgba(hsva) {
1253 const rgbResult = hsvToRgb(hsva);
1254 return {
1255 a: hsva.a,
1256 b: rgbResult.b,
1257 g: rgbResult.g,
1258 r: rgbResult.r
1259 };
1260 }
1261 function rgbToHsv(rgb) {
1262 const rgbPercent = {
1263 r: rgb.r / 255,
1264 g: rgb.g / 255,
1265 b: rgb.b / 255
1266 }, xMax = Math.max(rgbPercent.r, rgbPercent.g, rgbPercent.b), xMin = Math.min(rgbPercent.r, rgbPercent.g, rgbPercent.b), v = xMax, c = xMax - xMin;
1267 let h = 0;
1268 if (v === rgbPercent.r) {
1269 h = 60 * ((rgbPercent.g - rgbPercent.b) / c);
1270 } else if (v === rgbPercent.g) {
1271 h = 60 * (2 + (rgbPercent.b - rgbPercent.r) / c);
1272 } else if (v === rgbPercent.b) {
1273 h = 60 * (4 + (rgbPercent.r - rgbPercent.g) / c);
1274 }
1275 const s = !v ? 0 : c / v;
1276 return {
1277 h,
1278 s: s * 100,
1279 v: v * 100
1280 };
1281 }
1282 function rgbaToHsva(rgba) {
1283 const hsvResult = rgbToHsv(rgba);
1284 return {
1285 a: rgba.a,
1286 h: hsvResult.h,
1287 s: hsvResult.s,
1288 v: hsvResult.v
1289 };
1290 }
1291 function getRandomRgbColor(min) {
1292 const fixedMin = min !== null && min !== void 0 ? min : 0;
1293 return {
1294 b: Math.floor(randomInRange(setRangeValue(fixedMin, 256))),
1295 g: Math.floor(randomInRange(setRangeValue(fixedMin, 256))),
1296 r: Math.floor(randomInRange(setRangeValue(fixedMin, 256)))
1297 };
1298 }
1299 function getStyleFromRgb(color, opacity) {
1300 return `rgba(${color.r}, ${color.g}, ${color.b}, ${opacity !== null && opacity !== void 0 ? opacity : 1})`;
1301 }
1302 function getStyleFromHsl(color, opacity) {
1303 return `hsla(${color.h}, ${color.s}%, ${color.l}%, ${opacity !== null && opacity !== void 0 ? opacity : 1})`;
1304 }
1305 function getStyleFromHsv(color, opacity) {
1306 return getStyleFromHsl(hsvToHsl(color), opacity);
1307 }
1308 function colorMix(color1, color2, size1, size2) {
1309 let rgb1 = color1;
1310 let rgb2 = color2;
1311 if (rgb1.r === undefined) {
1312 rgb1 = hslToRgb(color1);
1313 }
1314 if (rgb2.r === undefined) {
1315 rgb2 = hslToRgb(color2);
1316 }
1317 return {
1318 b: mix(rgb1.b, rgb2.b, size1, size2),
1319 g: mix(rgb1.g, rgb2.g, size1, size2),
1320 r: mix(rgb1.r, rgb2.r, size1, size2)
1321 };
1322 }
1323 function getLinkColor(p1, p2, linkColor) {
1324 var _a, _b;
1325 if (linkColor === Constants.randomColorValue) {
1326 return getRandomRgbColor();
1327 } else if (linkColor === "mid") {
1328 const sourceColor = (_a = p1.getFillColor()) !== null && _a !== void 0 ? _a : p1.getStrokeColor();
1329 const destColor = (_b = p2 === null || p2 === void 0 ? void 0 : p2.getFillColor()) !== null && _b !== void 0 ? _b : p2 === null || p2 === void 0 ? void 0 : p2.getStrokeColor();
1330 if (sourceColor && destColor && p2) {
1331 return colorMix(sourceColor, destColor, p1.getRadius(), p2.getRadius());
1332 } else {
1333 const hslColor = sourceColor !== null && sourceColor !== void 0 ? sourceColor : destColor;
1334 if (hslColor) {
1335 return hslToRgb(hslColor);
1336 }
1337 }
1338 } else {
1339 return linkColor;
1340 }
1341 }
1342 function getLinkRandomColor(optColor, blink, consent) {
1343 const color = typeof optColor === "string" ? optColor : optColor.value;
1344 if (color === Constants.randomColorValue) {
1345 if (consent) {
1346 return colorToRgb({
1347 value: color
1348 });
1349 } else if (blink) {
1350 return Constants.randomColorValue;
1351 } else {
1352 return Constants.midColorValue;
1353 }
1354 } else {
1355 return colorToRgb({
1356 value: color
1357 });
1358 }
1359 }
1360 function getHslFromAnimation(animation) {
1361 return animation !== undefined ? {
1362 h: animation.h.value,
1363 s: animation.s.value,
1364 l: animation.l.value
1365 } : undefined;
1366 }
1367 function getHslAnimationFromHsl(hsl, animationOptions, reduceFactor) {
1368 const resColor = {
1369 h: {
1370 enable: false,
1371 value: hsl.h
1372 },
1373 s: {
1374 enable: false,
1375 value: hsl.s
1376 },
1377 l: {
1378 enable: false,
1379 value: hsl.l
1380 }
1381 };
1382 if (animationOptions) {
1383 setColorAnimation(resColor.h, animationOptions.h, reduceFactor);
1384 setColorAnimation(resColor.s, animationOptions.s, reduceFactor);
1385 setColorAnimation(resColor.l, animationOptions.l, reduceFactor);
1386 }
1387 return resColor;
1388 }
1389 function setColorAnimation(colorValue, colorAnimation, reduceFactor) {
1390 colorValue.enable = colorAnimation.enable;
1391 if (colorValue.enable) {
1392 colorValue.velocity = colorAnimation.speed / 100 * reduceFactor;
1393 if (colorAnimation.sync) {
1394 return;
1395 }
1396 colorValue.status = AnimationStatus.increasing;
1397 colorValue.velocity *= Math.random();
1398 if (colorValue.value) {
1399 colorValue.value *= Math.random();
1400 }
1401 } else {
1402 colorValue.velocity = 0;
1403 }
1404 }
1405 function drawLine(context, begin, end) {
1406 context.beginPath();
1407 context.moveTo(begin.x, begin.y);
1408 context.lineTo(end.x, end.y);
1409 context.closePath();
1410 }
1411 function drawTriangle(context, p1, p2, p3) {
1412 context.beginPath();
1413 context.moveTo(p1.x, p1.y);
1414 context.lineTo(p2.x, p2.y);
1415 context.lineTo(p3.x, p3.y);
1416 context.closePath();
1417 }
1418 function paintBase(context, dimension, baseColor) {
1419 context.save();
1420 context.fillStyle = baseColor !== null && baseColor !== void 0 ? baseColor : "rgba(0,0,0,0)";
1421 context.fillRect(0, 0, dimension.width, dimension.height);
1422 context.restore();
1423 }
1424 function clear(context, dimension) {
1425 context.clearRect(0, 0, dimension.width, dimension.height);
1426 }
1427 function drawLinkLine(context, width, begin, end, maxDistance, canvasSize, warp, backgroundMask, composite, colorLine, opacity, shadow) {
1428 let drawn = false;
1429 if (getDistance(begin, end) <= maxDistance) {
1430 drawLine(context, begin, end);
1431 drawn = true;
1432 } else if (warp) {
1433 let pi1;
1434 let pi2;
1435 const endNE = {
1436 x: end.x - canvasSize.width,
1437 y: end.y
1438 };
1439 const d1 = getDistances(begin, endNE);
1440 if (d1.distance <= maxDistance) {
1441 const yi = begin.y - d1.dy / d1.dx * begin.x;
1442 pi1 = {
1443 x: 0,
1444 y: yi
1445 };
1446 pi2 = {
1447 x: canvasSize.width,
1448 y: yi
1449 };
1450 } else {
1451 const endSW = {
1452 x: end.x,
1453 y: end.y - canvasSize.height
1454 };
1455 const d2 = getDistances(begin, endSW);
1456 if (d2.distance <= maxDistance) {
1457 const yi = begin.y - d2.dy / d2.dx * begin.x;
1458 const xi = -yi / (d2.dy / d2.dx);
1459 pi1 = {
1460 x: xi,
1461 y: 0
1462 };
1463 pi2 = {
1464 x: xi,
1465 y: canvasSize.height
1466 };
1467 } else {
1468 const endSE = {
1469 x: end.x - canvasSize.width,
1470 y: end.y - canvasSize.height
1471 };
1472 const d3 = getDistances(begin, endSE);
1473 if (d3.distance <= maxDistance) {
1474 const yi = begin.y - d3.dy / d3.dx * begin.x;
1475 const xi = -yi / (d3.dy / d3.dx);
1476 pi1 = {
1477 x: xi,
1478 y: yi
1479 };
1480 pi2 = {
1481 x: pi1.x + canvasSize.width,
1482 y: pi1.y + canvasSize.height
1483 };
1484 }
1485 }
1486 }
1487 if (pi1 && pi2) {
1488 drawLine(context, begin, pi1);
1489 drawLine(context, end, pi2);
1490 drawn = true;
1491 }
1492 }
1493 if (!drawn) {
1494 return;
1495 }
1496 context.lineWidth = width;
1497 if (backgroundMask) {
1498 context.globalCompositeOperation = composite;
1499 }
1500 context.strokeStyle = getStyleFromRgb(colorLine, opacity);
1501 if (shadow.enable) {
1502 const shadowColor = colorToRgb(shadow.color);
1503 if (shadowColor) {
1504 context.shadowBlur = shadow.blur;
1505 context.shadowColor = getStyleFromRgb(shadowColor);
1506 }
1507 }
1508 context.stroke();
1509 }
1510 function drawLinkTriangle(context, pos1, pos2, pos3, backgroundMask, composite, colorTriangle, opacityTriangle) {
1511 drawTriangle(context, pos1, pos2, pos3);
1512 if (backgroundMask) {
1513 context.globalCompositeOperation = composite;
1514 }
1515 context.fillStyle = getStyleFromRgb(colorTriangle, opacityTriangle);
1516 context.fill();
1517 }
1518 function drawConnectLine(context, width, lineStyle, begin, end) {
1519 context.save();
1520 drawLine(context, begin, end);
1521 context.lineWidth = width;
1522 context.strokeStyle = lineStyle;
1523 context.stroke();
1524 context.restore();
1525 }
1526 function gradient(context, p1, p2, opacity) {
1527 const gradStop = Math.floor(p2.getRadius() / p1.getRadius());
1528 const color1 = p1.getFillColor();
1529 const color2 = p2.getFillColor();
1530 if (!color1 || !color2) {
1531 return;
1532 }
1533 const sourcePos = p1.getPosition();
1534 const destPos = p2.getPosition();
1535 const midRgb = colorMix(color1, color2, p1.getRadius(), p2.getRadius());
1536 const grad = context.createLinearGradient(sourcePos.x, sourcePos.y, destPos.x, destPos.y);
1537 grad.addColorStop(0, getStyleFromHsl(color1, opacity));
1538 grad.addColorStop(gradStop > 1 ? 1 : gradStop, getStyleFromRgb(midRgb, opacity));
1539 grad.addColorStop(1, getStyleFromHsl(color2, opacity));
1540 return grad;
1541 }
1542 function drawGrabLine(context, width, begin, end, colorLine, opacity) {
1543 context.save();
1544 drawLine(context, begin, end);
1545 context.strokeStyle = getStyleFromRgb(colorLine, opacity);
1546 context.lineWidth = width;
1547 context.stroke();
1548 context.restore();
1549 }
1550 function drawParticle(container, context, particle, delta, fillColorValue, strokeColorValue, backgroundMask, composite, radius, opacity, shadow, gradient) {
1551 var _a, _b, _c, _d, _e, _f;
1552 const pos = particle.getPosition();
1553 const tiltOptions = particle.options.tilt;
1554 const rollOptions = particle.options.roll;
1555 context.save();
1556 if (tiltOptions.enable || rollOptions.enable) {
1557 const roll = rollOptions.enable && particle.roll;
1558 const tilt = tiltOptions.enable && particle.tilt;
1559 const rollHorizontal = roll && (rollOptions.mode === RollMode.horizontal || rollOptions.mode === RollMode.both);
1560 const rollVertical = roll && (rollOptions.mode === RollMode.vertical || rollOptions.mode === RollMode.both);
1561 context.setTransform(rollHorizontal ? Math.cos(particle.roll.angle) : 1, tilt ? Math.cos(particle.tilt.value) * particle.tilt.cosDirection : 0, tilt ? Math.sin(particle.tilt.value) * particle.tilt.sinDirection : 0, rollVertical ? Math.sin(particle.roll.angle) : 1, pos.x, pos.y);
1562 } else {
1563 context.translate(pos.x, pos.y);
1564 }
1565 context.beginPath();
1566 const angle = ((_b = (_a = particle.rotate) === null || _a === void 0 ? void 0 : _a.value) !== null && _b !== void 0 ? _b : 0) + (particle.options.rotate.path ? particle.velocity.angle : 0);
1567 if (angle !== 0) {
1568 context.rotate(angle);
1569 }
1570 if (backgroundMask) {
1571 context.globalCompositeOperation = composite;
1572 }
1573 const shadowColor = particle.shadowColor;
1574 if (shadow.enable && shadowColor) {
1575 context.shadowBlur = shadow.blur;
1576 context.shadowColor = getStyleFromRgb(shadowColor);
1577 context.shadowOffsetX = shadow.offset.x;
1578 context.shadowOffsetY = shadow.offset.y;
1579 }
1580 if (gradient) {
1581 const gradientAngle = gradient.angle.value;
1582 const fillGradient = gradient.type === GradientType.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);
1583 for (const color of gradient.colors) {
1584 fillGradient.addColorStop(color.stop, getStyleFromHsl({
1585 h: color.value.h.value,
1586 s: color.value.s.value,
1587 l: color.value.l.value
1588 }, (_d = (_c = color.opacity) === null || _c === void 0 ? void 0 : _c.value) !== null && _d !== void 0 ? _d : opacity));
1589 }
1590 context.fillStyle = fillGradient;
1591 } else {
1592 if (fillColorValue) {
1593 context.fillStyle = fillColorValue;
1594 }
1595 }
1596 const stroke = particle.stroke;
1597 context.lineWidth = (_e = particle.strokeWidth) !== null && _e !== void 0 ? _e : 0;
1598 if (strokeColorValue) {
1599 context.strokeStyle = strokeColorValue;
1600 }
1601 drawShape(container, context, particle, radius, opacity, delta);
1602 if (((_f = stroke === null || stroke === void 0 ? void 0 : stroke.width) !== null && _f !== void 0 ? _f : 0) > 0) {
1603 context.stroke();
1604 }
1605 if (particle.close) {
1606 context.closePath();
1607 }
1608 if (particle.fill) {
1609 context.fill();
1610 }
1611 context.restore();
1612 context.save();
1613 if (tiltOptions.enable && particle.tilt) {
1614 context.setTransform(1, Math.cos(particle.tilt.value) * particle.tilt.cosDirection, Math.sin(particle.tilt.value) * particle.tilt.sinDirection, 1, pos.x, pos.y);
1615 } else {
1616 context.translate(pos.x, pos.y);
1617 }
1618 if (angle !== 0) {
1619 context.rotate(angle);
1620 }
1621 if (backgroundMask) {
1622 context.globalCompositeOperation = composite;
1623 }
1624 drawShapeAfterEffect(container, context, particle, radius, opacity, delta);
1625 context.restore();
1626 }
1627 function drawShape(container, context, particle, radius, opacity, delta) {
1628 if (!particle.shape) {
1629 return;
1630 }
1631 const drawer = container.drawers.get(particle.shape);
1632 if (!drawer) {
1633 return;
1634 }
1635 drawer.draw(context, particle, radius, opacity, delta, container.retina.pixelRatio);
1636 }
1637 function drawShapeAfterEffect(container, context, particle, radius, opacity, delta) {
1638 if (!particle.shape) {
1639 return;
1640 }
1641 const drawer = container.drawers.get(particle.shape);
1642 if (!(drawer === null || drawer === void 0 ? void 0 : drawer.afterEffect)) {
1643 return;
1644 }
1645 drawer.afterEffect(context, particle, radius, opacity, delta, container.retina.pixelRatio);
1646 }
1647 function drawPlugin(context, plugin, delta) {
1648 if (!plugin.draw) {
1649 return;
1650 }
1651 context.save();
1652 plugin.draw(context, delta);
1653 context.restore();
1654 }
1655 function drawParticlePlugin(context, plugin, particle, delta) {
1656 if (plugin.drawParticle !== undefined) {
1657 context.save();
1658 plugin.drawParticle(context, particle, delta);
1659 context.restore();
1660 }
1661 }
1662 function drawEllipse(context, particle, fillColorValue, radius, opacity, width, rotation, start, end) {
1663 const pos = particle.getPosition();
1664 if (fillColorValue) {
1665 context.strokeStyle = getStyleFromHsl(fillColorValue, opacity);
1666 }
1667 if (width === 0) {
1668 return;
1669 }
1670 context.lineWidth = width;
1671 const rotationRadian = rotation * Math.PI / 180;
1672 context.beginPath();
1673 context.ellipse(pos.x, pos.y, radius / 2, radius * 2, rotationRadian, start, end);
1674 context.stroke();
1675 }
1676 function alterHsl(color, type, value) {
1677 return {
1678 h: color.h,
1679 s: color.s,
1680 l: color.l + (type === AlterType.darken ? -1 : 1) * value
1681 };
1682 }
1683 class Range {
1684 constructor(x, y) {
1685 this.position = {
1686 x,
1687 y
1688 };
1689 }
1690 }
1691 class Circle extends Range {
1692 constructor(x, y, radius) {
1693 super(x, y);
1694 this.radius = radius;
1695 }
1696 contains(point) {
1697 return getDistance(point, this.position) <= this.radius;
1698 }
1699 intersects(range) {
1700 const rect = range;
1701 const circle = range;
1702 const pos1 = this.position;
1703 const pos2 = range.position;
1704 const xDist = Math.abs(pos2.x - pos1.x);
1705 const yDist = Math.abs(pos2.y - pos1.y);
1706 const r = this.radius;
1707 if (circle.radius !== undefined) {
1708 const rSum = r + circle.radius;
1709 const dist = Math.sqrt(xDist * xDist + yDist + yDist);
1710 return rSum > dist;
1711 } else if (rect.size !== undefined) {
1712 const w = rect.size.width;
1713 const h = rect.size.height;
1714 const edges = Math.pow(xDist - w, 2) + Math.pow(yDist - h, 2);
1715 if (xDist > r + w || yDist > r + h) {
1716 return false;
1717 }
1718 if (xDist <= w || yDist <= h) {
1719 return true;
1720 }
1721 return edges <= r * r;
1722 }
1723 return false;
1724 }
1725 }
1726 class Rectangle extends Range {
1727 constructor(x, y, width, height) {
1728 super(x, y);
1729 this.size = {
1730 height,
1731 width
1732 };
1733 }
1734 contains(point) {
1735 const w = this.size.width;
1736 const h = this.size.height;
1737 const pos = this.position;
1738 return point.x >= pos.x && point.x <= pos.x + w && point.y >= pos.y && point.y <= pos.y + h;
1739 }
1740 intersects(range) {
1741 const rect = range;
1742 const circle = range;
1743 const w = this.size.width;
1744 const h = this.size.height;
1745 const pos1 = this.position;
1746 const pos2 = range.position;
1747 if (circle.radius !== undefined) {
1748 return circle.intersects(this);
1749 } else if (rect.size !== undefined) {
1750 const size2 = rect.size;
1751 const w2 = size2.width;
1752 const h2 = size2.height;
1753 return pos2.x < pos1.x + w && pos2.x + w2 > pos1.x && pos2.y < pos1.y + h && pos2.y + h2 > pos1.y;
1754 }
1755 return false;
1756 }
1757 }
1758 class CircleWarp extends Circle {
1759 constructor(x, y, radius, canvasSize) {
1760 super(x, y, radius);
1761 this.canvasSize = canvasSize;
1762 this.canvasSize = {
1763 height: canvasSize.height,
1764 width: canvasSize.width
1765 };
1766 }
1767 contains(point) {
1768 if (super.contains(point)) {
1769 return true;
1770 }
1771 const posNE = {
1772 x: point.x - this.canvasSize.width,
1773 y: point.y
1774 };
1775 if (super.contains(posNE)) {
1776 return true;
1777 }
1778 const posSE = {
1779 x: point.x - this.canvasSize.width,
1780 y: point.y - this.canvasSize.height
1781 };
1782 if (super.contains(posSE)) {
1783 return true;
1784 }
1785 const posSW = {
1786 x: point.x,
1787 y: point.y - this.canvasSize.height
1788 };
1789 return super.contains(posSW);
1790 }
1791 intersects(range) {
1792 if (super.intersects(range)) {
1793 return true;
1794 }
1795 const rect = range;
1796 const circle = range;
1797 const newPos = {
1798 x: range.position.x - this.canvasSize.width,
1799 y: range.position.y - this.canvasSize.height
1800 };
1801 if (circle.radius !== undefined) {
1802 const biggerCircle = new Circle(newPos.x, newPos.y, circle.radius * 2);
1803 return super.intersects(biggerCircle);
1804 } else if (rect.size !== undefined) {
1805 const rectSW = new Rectangle(newPos.x, newPos.y, rect.size.width * 2, rect.size.height * 2);
1806 return super.intersects(rectSW);
1807 }
1808 return false;
1809 }
1810 }
1811 function manageListener(element, event, handler, add, options) {
1812 if (add) {
1813 let addOptions = {
1814 passive: true
1815 };
1816 if (typeof options === "boolean") {
1817 addOptions.capture = options;
1818 } else if (options !== undefined) {
1819 addOptions = options;
1820 }
1821 element.addEventListener(event, handler, addOptions);
1822 } else {
1823 const removeOptions = options;
1824 element.removeEventListener(event, handler, removeOptions);
1825 }
1826 }
1827 class EventListeners {
1828 constructor(container) {
1829 this.container = container;
1830 this.canPush = true;
1831 this.mouseMoveHandler = e => this.mouseTouchMove(e);
1832 this.touchStartHandler = e => this.mouseTouchMove(e);
1833 this.touchMoveHandler = e => this.mouseTouchMove(e);
1834 this.touchEndHandler = () => this.mouseTouchFinish();
1835 this.mouseLeaveHandler = () => this.mouseTouchFinish();
1836 this.touchCancelHandler = () => this.mouseTouchFinish();
1837 this.touchEndClickHandler = e => this.mouseTouchClick(e);
1838 this.mouseUpHandler = e => this.mouseTouchClick(e);
1839 this.mouseDownHandler = () => this.mouseDown();
1840 this.visibilityChangeHandler = () => this.handleVisibilityChange();
1841 this.themeChangeHandler = e => this.handleThemeChange(e);
1842 this.resizeHandler = () => this.handleWindowResize();
1843 }
1844 addListeners() {
1845 this.manageListeners(true);
1846 }
1847 removeListeners() {
1848 this.manageListeners(false);
1849 }
1850 manageListeners(add) {
1851 var _a;
1852 const container = this.container;
1853 const options = container.actualOptions;
1854 const detectType = options.interactivity.detectsOn;
1855 let mouseLeaveEvent = Constants.mouseLeaveEvent;
1856 if (detectType === InteractivityDetect.window) {
1857 container.interactivity.element = window;
1858 mouseLeaveEvent = Constants.mouseOutEvent;
1859 } else if (detectType === InteractivityDetect.parent && container.canvas.element) {
1860 const canvasEl = container.canvas.element;
1861 container.interactivity.element = (_a = canvasEl.parentElement) !== null && _a !== void 0 ? _a : canvasEl.parentNode;
1862 } else {
1863 container.interactivity.element = container.canvas.element;
1864 }
1865 const mediaMatch = typeof matchMedia !== "undefined" && matchMedia("(prefers-color-scheme: dark)");
1866 if (mediaMatch) {
1867 manageListener(mediaMatch, "change", this.themeChangeHandler, add);
1868 }
1869 const interactivityEl = container.interactivity.element;
1870 if (!interactivityEl) {
1871 return;
1872 }
1873 const html = interactivityEl;
1874 if (options.interactivity.events.onHover.enable || options.interactivity.events.onClick.enable) {
1875 manageListener(interactivityEl, Constants.mouseMoveEvent, this.mouseMoveHandler, add);
1876 manageListener(interactivityEl, Constants.touchStartEvent, this.touchStartHandler, add);
1877 manageListener(interactivityEl, Constants.touchMoveEvent, this.touchMoveHandler, add);
1878 if (!options.interactivity.events.onClick.enable) {
1879 manageListener(interactivityEl, Constants.touchEndEvent, this.touchEndHandler, add);
1880 } else {
1881 manageListener(interactivityEl, Constants.touchEndEvent, this.touchEndClickHandler, add);
1882 manageListener(interactivityEl, Constants.mouseUpEvent, this.mouseUpHandler, add);
1883 manageListener(interactivityEl, Constants.mouseDownEvent, this.mouseDownHandler, add);
1884 }
1885 manageListener(interactivityEl, mouseLeaveEvent, this.mouseLeaveHandler, add);
1886 manageListener(interactivityEl, Constants.touchCancelEvent, this.touchCancelHandler, add);
1887 }
1888 if (container.canvas.element) {
1889 container.canvas.element.style.pointerEvents = html === container.canvas.element ? "initial" : "none";
1890 }
1891 if (options.interactivity.events.resize) {
1892 if (typeof ResizeObserver !== "undefined") {
1893 if (this.resizeObserver && !add) {
1894 if (container.canvas.element) {
1895 this.resizeObserver.unobserve(container.canvas.element);
1896 }
1897 this.resizeObserver.disconnect();
1898 delete this.resizeObserver;
1899 } else if (!this.resizeObserver && add && container.canvas.element) {
1900 this.resizeObserver = new ResizeObserver((entries => {
1901 const entry = entries.find((e => e.target === container.canvas.element));
1902 if (!entry) {
1903 return;
1904 }
1905 this.handleWindowResize();
1906 }));
1907 this.resizeObserver.observe(container.canvas.element);
1908 }
1909 } else {
1910 manageListener(window, Constants.resizeEvent, this.resizeHandler, add);
1911 }
1912 }
1913 if (document) {
1914 manageListener(document, Constants.visibilityChangeEvent, this.visibilityChangeHandler, add, false);
1915 }
1916 }
1917 handleWindowResize() {
1918 if (this.resizeTimeout) {
1919 clearTimeout(this.resizeTimeout);
1920 delete this.resizeTimeout;
1921 }
1922 this.resizeTimeout = setTimeout((() => {
1923 var _a;
1924 return (_a = this.container.canvas) === null || _a === void 0 ? void 0 : _a.windowResize();
1925 }), 500);
1926 }
1927 handleVisibilityChange() {
1928 const container = this.container;
1929 const options = container.actualOptions;
1930 this.mouseTouchFinish();
1931 if (!options.pauseOnBlur) {
1932 return;
1933 }
1934 if (document === null || document === void 0 ? void 0 : document.hidden) {
1935 container.pageHidden = true;
1936 container.pause();
1937 } else {
1938 container.pageHidden = false;
1939 if (container.getAnimationStatus()) {
1940 container.play(true);
1941 } else {
1942 container.draw(true);
1943 }
1944 }
1945 }
1946 mouseDown() {
1947 const interactivity = this.container.interactivity;
1948 if (interactivity) {
1949 const mouse = interactivity.mouse;
1950 mouse.clicking = true;
1951 mouse.downPosition = mouse.position;
1952 }
1953 }
1954 mouseTouchMove(e) {
1955 var _a, _b, _c, _d, _e, _f, _g;
1956 const container = this.container;
1957 const options = container.actualOptions;
1958 if (((_a = container.interactivity) === null || _a === void 0 ? void 0 : _a.element) === undefined) {
1959 return;
1960 }
1961 container.interactivity.mouse.inside = true;
1962 let pos;
1963 const canvas = container.canvas.element;
1964 if (e.type.startsWith("mouse")) {
1965 this.canPush = true;
1966 const mouseEvent = e;
1967 if (container.interactivity.element === window) {
1968 if (canvas) {
1969 const clientRect = canvas.getBoundingClientRect();
1970 pos = {
1971 x: mouseEvent.clientX - clientRect.left,
1972 y: mouseEvent.clientY - clientRect.top
1973 };
1974 }
1975 } else if (options.interactivity.detectsOn === InteractivityDetect.parent) {
1976 const source = mouseEvent.target;
1977 const target = mouseEvent.currentTarget;
1978 const canvasEl = container.canvas.element;
1979 if (source && target && canvasEl) {
1980 const sourceRect = source.getBoundingClientRect();
1981 const targetRect = target.getBoundingClientRect();
1982 const canvasRect = canvasEl.getBoundingClientRect();
1983 pos = {
1984 x: mouseEvent.offsetX + 2 * sourceRect.left - (targetRect.left + canvasRect.left),
1985 y: mouseEvent.offsetY + 2 * sourceRect.top - (targetRect.top + canvasRect.top)
1986 };
1987 } else {
1988 pos = {
1989 x: (_b = mouseEvent.offsetX) !== null && _b !== void 0 ? _b : mouseEvent.clientX,
1990 y: (_c = mouseEvent.offsetY) !== null && _c !== void 0 ? _c : mouseEvent.clientY
1991 };
1992 }
1993 } else {
1994 if (mouseEvent.target === container.canvas.element) {
1995 pos = {
1996 x: (_d = mouseEvent.offsetX) !== null && _d !== void 0 ? _d : mouseEvent.clientX,
1997 y: (_e = mouseEvent.offsetY) !== null && _e !== void 0 ? _e : mouseEvent.clientY
1998 };
1999 }
2000 }
2001 } else {
2002 this.canPush = e.type !== "touchmove";
2003 const touchEvent = e;
2004 const lastTouch = touchEvent.touches[touchEvent.touches.length - 1];
2005 const canvasRect = canvas === null || canvas === void 0 ? void 0 : canvas.getBoundingClientRect();
2006 pos = {
2007 x: lastTouch.clientX - ((_f = canvasRect === null || canvasRect === void 0 ? void 0 : canvasRect.left) !== null && _f !== void 0 ? _f : 0),
2008 y: lastTouch.clientY - ((_g = canvasRect === null || canvasRect === void 0 ? void 0 : canvasRect.top) !== null && _g !== void 0 ? _g : 0)
2009 };
2010 }
2011 const pxRatio = container.retina.pixelRatio;
2012 if (pos) {
2013 pos.x *= pxRatio;
2014 pos.y *= pxRatio;
2015 }
2016 container.interactivity.mouse.position = pos;
2017 container.interactivity.status = Constants.mouseMoveEvent;
2018 }
2019 mouseTouchFinish() {
2020 const interactivity = this.container.interactivity;
2021 if (interactivity === undefined) {
2022 return;
2023 }
2024 const mouse = interactivity.mouse;
2025 delete mouse.position;
2026 delete mouse.clickPosition;
2027 delete mouse.downPosition;
2028 interactivity.status = Constants.mouseLeaveEvent;
2029 mouse.inside = false;
2030 mouse.clicking = false;
2031 }
2032 mouseTouchClick(e) {
2033 const container = this.container;
2034 const options = container.actualOptions;
2035 const mouse = container.interactivity.mouse;
2036 mouse.inside = true;
2037 let handled = false;
2038 const mousePosition = mouse.position;
2039 if (mousePosition === undefined || !options.interactivity.events.onClick.enable) {
2040 return;
2041 }
2042 for (const [, plugin] of container.plugins) {
2043 if (plugin.clickPositionValid !== undefined) {
2044 handled = plugin.clickPositionValid(mousePosition);
2045 if (handled) {
2046 break;
2047 }
2048 }
2049 }
2050 if (!handled) {
2051 this.doMouseTouchClick(e);
2052 }
2053 mouse.clicking = false;
2054 }
2055 doMouseTouchClick(e) {
2056 const container = this.container;
2057 const options = container.actualOptions;
2058 if (this.canPush) {
2059 const mousePos = container.interactivity.mouse.position;
2060 if (mousePos) {
2061 container.interactivity.mouse.clickPosition = {
2062 x: mousePos.x,
2063 y: mousePos.y
2064 };
2065 } else {
2066 return;
2067 }
2068 container.interactivity.mouse.clickTime = (new Date).getTime();
2069 const onClick = options.interactivity.events.onClick;
2070 if (onClick.mode instanceof Array) {
2071 for (const mode of onClick.mode) {
2072 this.handleClickMode(mode);
2073 }
2074 } else {
2075 this.handleClickMode(onClick.mode);
2076 }
2077 }
2078 if (e.type === "touchend") {
2079 setTimeout((() => this.mouseTouchFinish()), 500);
2080 }
2081 }
2082 handleThemeChange(e) {
2083 const mediaEvent = e;
2084 const themeName = mediaEvent.matches ? this.container.options.defaultDarkTheme : this.container.options.defaultLightTheme;
2085 const theme = this.container.options.themes.find((theme => theme.name === themeName));
2086 if (theme && theme.default.auto) {
2087 this.container.loadTheme(themeName);
2088 }
2089 }
2090 handleClickMode(mode) {
2091 const container = this.container;
2092 const options = container.actualOptions;
2093 const pushNb = options.interactivity.modes.push.quantity;
2094 const removeNb = options.interactivity.modes.remove.quantity;
2095 switch (mode) {
2096 case ClickMode.push:
2097 {
2098 if (pushNb > 0) {
2099 const pushOptions = options.interactivity.modes.push;
2100 const group = itemFromArray([ undefined, ...pushOptions.groups ]);
2101 const groupOptions = group !== undefined ? container.actualOptions.particles.groups[group] : undefined;
2102 container.particles.push(pushNb, container.interactivity.mouse, groupOptions, group);
2103 }
2104 break;
2105 }
2106
2107 case ClickMode.remove:
2108 container.particles.removeQuantity(removeNb);
2109 break;
2110
2111 case ClickMode.bubble:
2112 container.bubble.clicking = true;
2113 break;
2114
2115 case ClickMode.repulse:
2116 container.repulse.clicking = true;
2117 container.repulse.count = 0;
2118 for (const particle of container.repulse.particles) {
2119 particle.velocity.setTo(particle.initialVelocity);
2120 }
2121 container.repulse.particles = [];
2122 container.repulse.finish = false;
2123 setTimeout((() => {
2124 if (!container.destroyed) {
2125 container.repulse.clicking = false;
2126 }
2127 }), options.interactivity.modes.repulse.duration * 1e3);
2128 break;
2129
2130 case ClickMode.attract:
2131 container.attract.clicking = true;
2132 container.attract.count = 0;
2133 for (const particle of container.attract.particles) {
2134 particle.velocity.setTo(particle.initialVelocity);
2135 }
2136 container.attract.particles = [];
2137 container.attract.finish = false;
2138 setTimeout((() => {
2139 if (!container.destroyed) {
2140 container.attract.clicking = false;
2141 }
2142 }), options.interactivity.modes.attract.duration * 1e3);
2143 break;
2144
2145 case ClickMode.pause:
2146 if (container.getAnimationStatus()) {
2147 container.pause();
2148 } else {
2149 container.play();
2150 }
2151 break;
2152 }
2153 for (const [, plugin] of container.plugins) {
2154 if (plugin.handleClickMode) {
2155 plugin.handleClickMode(mode);
2156 }
2157 }
2158 }
2159 }
2160 const plugins = [];
2161 const interactorsInitializers = new Map;
2162 const updatersInitializers = new Map;
2163 const interactors = new Map;
2164 const updaters = new Map;
2165 const presets = new Map;
2166 const drawers = new Map;
2167 const pathGenerators = new Map;
2168 class Plugins {
2169 static getPlugin(plugin) {
2170 return plugins.find((t => t.id === plugin));
2171 }
2172 static addPlugin(plugin) {
2173 if (!Plugins.getPlugin(plugin.id)) {
2174 plugins.push(plugin);
2175 }
2176 }
2177 static getAvailablePlugins(container) {
2178 const res = new Map;
2179 for (const plugin of plugins) {
2180 if (!plugin.needsPlugin(container.actualOptions)) {
2181 continue;
2182 }
2183 res.set(plugin.id, plugin.getPlugin(container));
2184 }
2185 return res;
2186 }
2187 static loadOptions(options, sourceOptions) {
2188 for (const plugin of plugins) {
2189 plugin.loadOptions(options, sourceOptions);
2190 }
2191 }
2192 static getPreset(preset) {
2193 return presets.get(preset);
2194 }
2195 static addPreset(presetKey, options, override = false) {
2196 if (override || !Plugins.getPreset(presetKey)) {
2197 presets.set(presetKey, options);
2198 }
2199 }
2200 static addShapeDrawer(type, drawer) {
2201 if (!Plugins.getShapeDrawer(type)) {
2202 drawers.set(type, drawer);
2203 }
2204 }
2205 static getShapeDrawer(type) {
2206 return drawers.get(type);
2207 }
2208 static getSupportedShapes() {
2209 return drawers.keys();
2210 }
2211 static getPathGenerator(type) {
2212 return pathGenerators.get(type);
2213 }
2214 static addPathGenerator(type, pathGenerator) {
2215 if (!Plugins.getPathGenerator(type)) {
2216 pathGenerators.set(type, pathGenerator);
2217 }
2218 }
2219 static getInteractors(container) {
2220 let res = interactors.get(container);
2221 if (!res) {
2222 res = [ ...interactorsInitializers.values() ].map((t => t(container)));
2223 interactors.set(container, res);
2224 }
2225 return res;
2226 }
2227 static addInteractor(name, initInteractor) {
2228 interactorsInitializers.set(name, initInteractor);
2229 }
2230 static getUpdaters(container) {
2231 let res = updaters.get(container);
2232 if (!res) {
2233 res = [ ...updatersInitializers.values() ].map((t => t(container)));
2234 updaters.set(container, res);
2235 }
2236 return res;
2237 }
2238 static addParticleUpdater(name, initUpdater) {
2239 updatersInitializers.set(name, initUpdater);
2240 }
2241 }
2242 class Point {
2243 constructor(position, particle) {
2244 this.position = position;
2245 this.particle = particle;
2246 }
2247 }
2248 class QuadTree {
2249 constructor(rectangle, capacity) {
2250 this.rectangle = rectangle;
2251 this.capacity = capacity;
2252 this.points = [];
2253 this.divided = false;
2254 }
2255 subdivide() {
2256 const x = this.rectangle.position.x;
2257 const y = this.rectangle.position.y;
2258 const w = this.rectangle.size.width;
2259 const h = this.rectangle.size.height;
2260 const capacity = this.capacity;
2261 this.northEast = new QuadTree(new Rectangle(x, y, w / 2, h / 2), capacity);
2262 this.northWest = new QuadTree(new Rectangle(x + w / 2, y, w / 2, h / 2), capacity);
2263 this.southEast = new QuadTree(new Rectangle(x, y + h / 2, w / 2, h / 2), capacity);
2264 this.southWest = new QuadTree(new Rectangle(x + w / 2, y + h / 2, w / 2, h / 2), capacity);
2265 this.divided = true;
2266 }
2267 insert(point) {
2268 var _a, _b, _c, _d, _e;
2269 if (!this.rectangle.contains(point.position)) {
2270 return false;
2271 }
2272 if (this.points.length < this.capacity) {
2273 this.points.push(point);
2274 return true;
2275 }
2276 if (!this.divided) {
2277 this.subdivide();
2278 }
2279 return (_e = ((_a = this.northEast) === null || _a === void 0 ? void 0 : _a.insert(point)) || ((_b = this.northWest) === null || _b === void 0 ? void 0 : _b.insert(point)) || ((_c = this.southEast) === null || _c === void 0 ? void 0 : _c.insert(point)) || ((_d = this.southWest) === null || _d === void 0 ? void 0 : _d.insert(point))) !== null && _e !== void 0 ? _e : false;
2280 }
2281 queryCircle(position, radius) {
2282 return this.query(new Circle(position.x, position.y, radius));
2283 }
2284 queryCircleWarp(position, radius, containerOrSize) {
2285 const container = containerOrSize;
2286 const size = containerOrSize;
2287 return this.query(new CircleWarp(position.x, position.y, radius, container.canvas !== undefined ? container.canvas.size : size));
2288 }
2289 queryRectangle(position, size) {
2290 return this.query(new Rectangle(position.x, position.y, size.width, size.height));
2291 }
2292 query(range, found) {
2293 var _a, _b, _c, _d;
2294 const res = found !== null && found !== void 0 ? found : [];
2295 if (!range.intersects(this.rectangle)) {
2296 return [];
2297 } else {
2298 for (const p of this.points) {
2299 if (!range.contains(p.position) && getDistance(range.position, p.position) > p.particle.getRadius()) {
2300 continue;
2301 }
2302 res.push(p.particle);
2303 }
2304 if (this.divided) {
2305 (_a = this.northEast) === null || _a === void 0 ? void 0 : _a.query(range, res);
2306 (_b = this.northWest) === null || _b === void 0 ? void 0 : _b.query(range, res);
2307 (_c = this.southEast) === null || _c === void 0 ? void 0 : _c.query(range, res);
2308 (_d = this.southWest) === null || _d === void 0 ? void 0 : _d.query(range, res);
2309 }
2310 }
2311 return res;
2312 }
2313 }
2314 class Canvas {
2315 constructor(container) {
2316 this.container = container;
2317 this.size = {
2318 height: 0,
2319 width: 0
2320 };
2321 this.context = null;
2322 this.generatedCanvas = false;
2323 }
2324 init() {
2325 this.resize();
2326 this.initStyle();
2327 this.initCover();
2328 this.initTrail();
2329 this.initBackground();
2330 this.paint();
2331 }
2332 loadCanvas(canvas, generatedCanvas) {
2333 var _a;
2334 if (!canvas.className) {
2335 canvas.className = Constants.canvasClass;
2336 }
2337 if (this.generatedCanvas) {
2338 (_a = this.element) === null || _a === void 0 ? void 0 : _a.remove();
2339 }
2340 this.generatedCanvas = generatedCanvas !== null && generatedCanvas !== void 0 ? generatedCanvas : this.generatedCanvas;
2341 this.element = canvas;
2342 this.originalStyle = deepExtend({}, this.element.style);
2343 this.size.height = canvas.offsetHeight;
2344 this.size.width = canvas.offsetWidth;
2345 this.context = this.element.getContext("2d");
2346 this.container.retina.init();
2347 this.initBackground();
2348 }
2349 destroy() {
2350 var _a;
2351 if (this.generatedCanvas) {
2352 (_a = this.element) === null || _a === void 0 ? void 0 : _a.remove();
2353 }
2354 this.draw((ctx => {
2355 clear(ctx, this.size);
2356 }));
2357 }
2358 paint() {
2359 const options = this.container.actualOptions;
2360 this.draw((ctx => {
2361 if (options.backgroundMask.enable && options.backgroundMask.cover && this.coverColor) {
2362 clear(ctx, this.size);
2363 this.paintBase(getStyleFromRgb(this.coverColor, this.coverColor.a));
2364 } else {
2365 this.paintBase();
2366 }
2367 }));
2368 }
2369 clear() {
2370 const options = this.container.actualOptions;
2371 const trail = options.particles.move.trail;
2372 if (options.backgroundMask.enable) {
2373 this.paint();
2374 } else if (trail.enable && trail.length > 0 && this.trailFillColor) {
2375 this.paintBase(getStyleFromRgb(this.trailFillColor, 1 / trail.length));
2376 } else {
2377 this.draw((ctx => {
2378 clear(ctx, this.size);
2379 }));
2380 }
2381 }
2382 windowResize() {
2383 if (!this.element) {
2384 return;
2385 }
2386 const container = this.container;
2387 this.resize();
2388 const needsRefresh = container.updateActualOptions();
2389 container.particles.setDensity();
2390 for (const [, plugin] of container.plugins) {
2391 if (plugin.resize !== undefined) {
2392 plugin.resize();
2393 }
2394 }
2395 if (needsRefresh) {
2396 container.refresh();
2397 }
2398 }
2399 resize() {
2400 if (!this.element) {
2401 return;
2402 }
2403 const container = this.container;
2404 const pxRatio = container.retina.pixelRatio;
2405 const size = container.canvas.size;
2406 const oldSize = {
2407 width: size.width,
2408 height: size.height
2409 };
2410 size.width = this.element.offsetWidth * pxRatio;
2411 size.height = this.element.offsetHeight * pxRatio;
2412 this.element.width = size.width;
2413 this.element.height = size.height;
2414 if (this.container.started) {
2415 this.resizeFactor = {
2416 width: size.width / oldSize.width,
2417 height: size.height / oldSize.height
2418 };
2419 }
2420 }
2421 drawConnectLine(p1, p2) {
2422 this.draw((ctx => {
2423 var _a;
2424 const lineStyle = this.lineStyle(p1, p2);
2425 if (!lineStyle) {
2426 return;
2427 }
2428 const pos1 = p1.getPosition();
2429 const pos2 = p2.getPosition();
2430 drawConnectLine(ctx, (_a = p1.retina.linksWidth) !== null && _a !== void 0 ? _a : this.container.retina.linksWidth, lineStyle, pos1, pos2);
2431 }));
2432 }
2433 drawGrabLine(particle, lineColor, opacity, mousePos) {
2434 const container = this.container;
2435 this.draw((ctx => {
2436 var _a;
2437 const beginPos = particle.getPosition();
2438 drawGrabLine(ctx, (_a = particle.retina.linksWidth) !== null && _a !== void 0 ? _a : container.retina.linksWidth, beginPos, mousePos, lineColor, opacity);
2439 }));
2440 }
2441 drawParticle(particle, delta) {
2442 var _a, _b, _c, _d, _e, _f;
2443 if (particle.spawning || particle.destroyed) {
2444 return;
2445 }
2446 const pfColor = particle.getFillColor();
2447 const psColor = (_a = particle.getStrokeColor()) !== null && _a !== void 0 ? _a : pfColor;
2448 if (!pfColor && !psColor) {
2449 return;
2450 }
2451 let [fColor, sColor] = this.getPluginParticleColors(particle);
2452 const pOptions = particle.options;
2453 const twinkle = pOptions.twinkle.particles;
2454 const twinkling = twinkle.enable && Math.random() < twinkle.frequency;
2455 if (!fColor || !sColor) {
2456 const twinkleRgb = colorToHsl(twinkle.color);
2457 if (!fColor) {
2458 fColor = twinkling && twinkleRgb !== undefined ? twinkleRgb : pfColor ? pfColor : undefined;
2459 }
2460 if (!sColor) {
2461 sColor = twinkling && twinkleRgb !== undefined ? twinkleRgb : psColor ? psColor : undefined;
2462 }
2463 }
2464 const options = this.container.actualOptions;
2465 const zIndexOptions = particle.options.zIndex;
2466 const zOpacityFactor = (1 - particle.zIndexFactor) ** zIndexOptions.opacityRate;
2467 const radius = particle.getRadius();
2468 const opacity = twinkling ? twinkle.opacity : (_d = (_b = particle.bubble.opacity) !== null && _b !== void 0 ? _b : (_c = particle.opacity) === null || _c === void 0 ? void 0 : _c.value) !== null && _d !== void 0 ? _d : 1;
2469 const strokeOpacity = (_f = (_e = particle.stroke) === null || _e === void 0 ? void 0 : _e.opacity) !== null && _f !== void 0 ? _f : opacity;
2470 const zOpacity = opacity * zOpacityFactor;
2471 const fillColorValue = fColor ? getStyleFromHsl(fColor, zOpacity) : undefined;
2472 if (!fillColorValue && !sColor) {
2473 return;
2474 }
2475 this.draw((ctx => {
2476 const zSizeFactor = (1 - particle.zIndexFactor) ** zIndexOptions.sizeRate;
2477 const zStrokeOpacity = strokeOpacity * zOpacityFactor;
2478 const strokeColorValue = sColor ? getStyleFromHsl(sColor, zStrokeOpacity) : fillColorValue;
2479 if (radius <= 0) {
2480 return;
2481 }
2482 const container = this.container;
2483 for (const updater of container.particles.updaters) {
2484 if (updater.beforeDraw) {
2485 updater.beforeDraw(particle);
2486 }
2487 }
2488 drawParticle(this.container, ctx, particle, delta, fillColorValue, strokeColorValue, options.backgroundMask.enable, options.backgroundMask.composite, radius * zSizeFactor, zOpacity, particle.options.shadow, particle.gradient);
2489 for (const updater of container.particles.updaters) {
2490 if (updater.afterDraw) {
2491 updater.afterDraw(particle);
2492 }
2493 }
2494 }));
2495 }
2496 drawPlugin(plugin, delta) {
2497 this.draw((ctx => {
2498 drawPlugin(ctx, plugin, delta);
2499 }));
2500 }
2501 drawParticlePlugin(plugin, particle, delta) {
2502 this.draw((ctx => {
2503 drawParticlePlugin(ctx, plugin, particle, delta);
2504 }));
2505 }
2506 initBackground() {
2507 const options = this.container.actualOptions;
2508 const background = options.background;
2509 const element = this.element;
2510 const elementStyle = element === null || element === void 0 ? void 0 : element.style;
2511 if (!elementStyle) {
2512 return;
2513 }
2514 if (background.color) {
2515 const color = colorToRgb(background.color);
2516 elementStyle.backgroundColor = color ? getStyleFromRgb(color, background.opacity) : "";
2517 } else {
2518 elementStyle.backgroundColor = "";
2519 }
2520 elementStyle.backgroundImage = background.image || "";
2521 elementStyle.backgroundPosition = background.position || "";
2522 elementStyle.backgroundRepeat = background.repeat || "";
2523 elementStyle.backgroundSize = background.size || "";
2524 }
2525 draw(cb) {
2526 if (!this.context) {
2527 return;
2528 }
2529 return cb(this.context);
2530 }
2531 initCover() {
2532 const options = this.container.actualOptions;
2533 const cover = options.backgroundMask.cover;
2534 const color = cover.color;
2535 const coverRgb = colorToRgb(color);
2536 if (coverRgb) {
2537 this.coverColor = {
2538 r: coverRgb.r,
2539 g: coverRgb.g,
2540 b: coverRgb.b,
2541 a: cover.opacity
2542 };
2543 }
2544 }
2545 initTrail() {
2546 const options = this.container.actualOptions;
2547 const trail = options.particles.move.trail;
2548 const fillColor = colorToRgb(trail.fillColor);
2549 if (fillColor) {
2550 const trail = options.particles.move.trail;
2551 this.trailFillColor = {
2552 r: fillColor.r,
2553 g: fillColor.g,
2554 b: fillColor.b,
2555 a: 1 / trail.length
2556 };
2557 }
2558 }
2559 getPluginParticleColors(particle) {
2560 let fColor;
2561 let sColor;
2562 for (const [, plugin] of this.container.plugins) {
2563 if (!fColor && plugin.particleFillColor) {
2564 fColor = colorToHsl(plugin.particleFillColor(particle));
2565 }
2566 if (!sColor && plugin.particleStrokeColor) {
2567 sColor = colorToHsl(plugin.particleStrokeColor(particle));
2568 }
2569 if (fColor && sColor) {
2570 break;
2571 }
2572 }
2573 return [ fColor, sColor ];
2574 }
2575 initStyle() {
2576 const element = this.element, options = this.container.actualOptions;
2577 if (!element) {
2578 return;
2579 }
2580 const originalStyle = this.originalStyle;
2581 if (options.fullScreen.enable) {
2582 this.originalStyle = deepExtend({}, element.style);
2583 element.style.position = "fixed";
2584 element.style.zIndex = options.fullScreen.zIndex.toString(10);
2585 element.style.top = "0";
2586 element.style.left = "0";
2587 element.style.width = "100%";
2588 element.style.height = "100%";
2589 } else if (originalStyle) {
2590 element.style.position = originalStyle.position;
2591 element.style.zIndex = originalStyle.zIndex;
2592 element.style.top = originalStyle.top;
2593 element.style.left = originalStyle.left;
2594 element.style.width = originalStyle.width;
2595 element.style.height = originalStyle.height;
2596 }
2597 }
2598 paintBase(baseColor) {
2599 this.draw((ctx => {
2600 paintBase(ctx, this.size, baseColor);
2601 }));
2602 }
2603 lineStyle(p1, p2) {
2604 return this.draw((ctx => {
2605 const options = this.container.actualOptions;
2606 const connectOptions = options.interactivity.modes.connect;
2607 return gradient(ctx, p1, p2, connectOptions.links.opacity);
2608 }));
2609 }
2610 }
2611 class OptionsColor {
2612 constructor() {
2613 this.value = "#fff";
2614 }
2615 static create(source, data) {
2616 const color = new OptionsColor;
2617 color.load(source);
2618 if (data !== undefined) {
2619 if (typeof data === "string" || data instanceof Array) {
2620 color.load({
2621 value: data
2622 });
2623 } else {
2624 color.load(data);
2625 }
2626 }
2627 return color;
2628 }
2629 load(data) {
2630 if ((data === null || data === void 0 ? void 0 : data.value) === undefined) {
2631 return;
2632 }
2633 this.value = data.value;
2634 }
2635 }
2636 class LinksShadow {
2637 constructor() {
2638 this.blur = 5;
2639 this.color = new OptionsColor;
2640 this.enable = false;
2641 this.color.value = "#00ff00";
2642 }
2643 load(data) {
2644 if (data === undefined) {
2645 return;
2646 }
2647 if (data.blur !== undefined) {
2648 this.blur = data.blur;
2649 }
2650 this.color = OptionsColor.create(this.color, data.color);
2651 if (data.enable !== undefined) {
2652 this.enable = data.enable;
2653 }
2654 }
2655 }
2656 class LinksTriangle {
2657 constructor() {
2658 this.enable = false;
2659 this.frequency = 1;
2660 }
2661 load(data) {
2662 if (data === undefined) {
2663 return;
2664 }
2665 if (data.color !== undefined) {
2666 this.color = OptionsColor.create(this.color, data.color);
2667 }
2668 if (data.enable !== undefined) {
2669 this.enable = data.enable;
2670 }
2671 if (data.frequency !== undefined) {
2672 this.frequency = data.frequency;
2673 }
2674 if (data.opacity !== undefined) {
2675 this.opacity = data.opacity;
2676 }
2677 }
2678 }
2679 class Links {
2680 constructor() {
2681 this.blink = false;
2682 this.color = new OptionsColor;
2683 this.consent = false;
2684 this.distance = 100;
2685 this.enable = false;
2686 this.frequency = 1;
2687 this.opacity = 1;
2688 this.shadow = new LinksShadow;
2689 this.triangles = new LinksTriangle;
2690 this.width = 1;
2691 this.warp = false;
2692 }
2693 load(data) {
2694 if (data === undefined) {
2695 return;
2696 }
2697 if (data.id !== undefined) {
2698 this.id = data.id;
2699 }
2700 if (data.blink !== undefined) {
2701 this.blink = data.blink;
2702 }
2703 this.color = OptionsColor.create(this.color, data.color);
2704 if (data.consent !== undefined) {
2705 this.consent = data.consent;
2706 }
2707 if (data.distance !== undefined) {
2708 this.distance = data.distance;
2709 }
2710 if (data.enable !== undefined) {
2711 this.enable = data.enable;
2712 }
2713 if (data.frequency !== undefined) {
2714 this.frequency = data.frequency;
2715 }
2716 if (data.opacity !== undefined) {
2717 this.opacity = data.opacity;
2718 }
2719 this.shadow.load(data.shadow);
2720 this.triangles.load(data.triangles);
2721 if (data.width !== undefined) {
2722 this.width = data.width;
2723 }
2724 if (data.warp !== undefined) {
2725 this.warp = data.warp;
2726 }
2727 }
2728 }
2729 class Attract {
2730 constructor() {
2731 this.distance = 200;
2732 this.enable = false;
2733 this.rotate = {
2734 x: 3e3,
2735 y: 3e3
2736 };
2737 }
2738 get rotateX() {
2739 return this.rotate.x;
2740 }
2741 set rotateX(value) {
2742 this.rotate.x = value;
2743 }
2744 get rotateY() {
2745 return this.rotate.y;
2746 }
2747 set rotateY(value) {
2748 this.rotate.y = value;
2749 }
2750 load(data) {
2751 var _a, _b, _c, _d;
2752 if (!data) {
2753 return;
2754 }
2755 if (data.distance !== undefined) {
2756 this.distance = data.distance;
2757 }
2758 if (data.enable !== undefined) {
2759 this.enable = data.enable;
2760 }
2761 const rotateX = (_b = (_a = data.rotate) === null || _a === void 0 ? void 0 : _a.x) !== null && _b !== void 0 ? _b : data.rotateX;
2762 if (rotateX !== undefined) {
2763 this.rotate.x = rotateX;
2764 }
2765 const rotateY = (_d = (_c = data.rotate) === null || _c === void 0 ? void 0 : _c.y) !== null && _d !== void 0 ? _d : data.rotateY;
2766 if (rotateY !== undefined) {
2767 this.rotate.y = rotateY;
2768 }
2769 }
2770 }
2771 class Trail {
2772 constructor() {
2773 this.enable = false;
2774 this.length = 10;
2775 this.fillColor = new OptionsColor;
2776 this.fillColor.value = "#000000";
2777 }
2778 load(data) {
2779 if (data === undefined) {
2780 return;
2781 }
2782 if (data.enable !== undefined) {
2783 this.enable = data.enable;
2784 }
2785 this.fillColor = OptionsColor.create(this.fillColor, data.fillColor);
2786 if (data.length !== undefined) {
2787 this.length = data.length;
2788 }
2789 }
2790 }
2791 class Random {
2792 constructor() {
2793 this.enable = false;
2794 this.minimumValue = 0;
2795 }
2796 load(data) {
2797 if (!data) {
2798 return;
2799 }
2800 if (data.enable !== undefined) {
2801 this.enable = data.enable;
2802 }
2803 if (data.minimumValue !== undefined) {
2804 this.minimumValue = data.minimumValue;
2805 }
2806 }
2807 }
2808 class ValueWithRandom {
2809 constructor() {
2810 this.random = new Random;
2811 this.value = 0;
2812 }
2813 load(data) {
2814 if (!data) {
2815 return;
2816 }
2817 if (typeof data.random === "boolean") {
2818 this.random.enable = data.random;
2819 } else {
2820 this.random.load(data.random);
2821 }
2822 if (data.value !== undefined) {
2823 this.value = setRangeValue(data.value, this.random.enable ? this.random.minimumValue : undefined);
2824 }
2825 }
2826 }
2827 class PathDelay extends ValueWithRandom {
2828 constructor() {
2829 super();
2830 }
2831 }
2832 class Path {
2833 constructor() {
2834 this.clamp = true;
2835 this.delay = new PathDelay;
2836 this.enable = false;
2837 this.options = {};
2838 }
2839 load(data) {
2840 if (data === undefined) {
2841 return;
2842 }
2843 if (data.clamp !== undefined) {
2844 this.clamp = data.clamp;
2845 }
2846 this.delay.load(data.delay);
2847 if (data.enable !== undefined) {
2848 this.enable = data.enable;
2849 }
2850 this.generator = data.generator;
2851 if (data.options) {
2852 this.options = deepExtend(this.options, data.options);
2853 }
2854 }
2855 }
2856 class MoveAngle {
2857 constructor() {
2858 this.offset = 0;
2859 this.value = 90;
2860 }
2861 load(data) {
2862 if (data === undefined) {
2863 return;
2864 }
2865 if (data.offset !== undefined) {
2866 this.offset = data.offset;
2867 }
2868 if (data.value !== undefined) {
2869 this.value = data.value;
2870 }
2871 }
2872 }
2873 class MoveGravity {
2874 constructor() {
2875 this.acceleration = 9.81;
2876 this.enable = false;
2877 this.inverse = false;
2878 this.maxSpeed = 50;
2879 }
2880 load(data) {
2881 if (!data) {
2882 return;
2883 }
2884 if (data.acceleration !== undefined) {
2885 this.acceleration = data.acceleration;
2886 }
2887 if (data.enable !== undefined) {
2888 this.enable = data.enable;
2889 }
2890 if (data.inverse !== undefined) {
2891 this.inverse = data.inverse;
2892 }
2893 if (data.maxSpeed !== undefined) {
2894 this.maxSpeed = data.maxSpeed;
2895 }
2896 }
2897 }
2898 class OutModes {
2899 constructor() {
2900 this.default = OutMode.out;
2901 }
2902 load(data) {
2903 var _a, _b, _c, _d;
2904 if (!data) {
2905 return;
2906 }
2907 if (data.default !== undefined) {
2908 this.default = data.default;
2909 }
2910 this.bottom = (_a = data.bottom) !== null && _a !== void 0 ? _a : data.default;
2911 this.left = (_b = data.left) !== null && _b !== void 0 ? _b : data.default;
2912 this.right = (_c = data.right) !== null && _c !== void 0 ? _c : data.default;
2913 this.top = (_d = data.top) !== null && _d !== void 0 ? _d : data.default;
2914 }
2915 }
2916 class Spin {
2917 constructor() {
2918 this.acceleration = 0;
2919 this.enable = false;
2920 }
2921 load(data) {
2922 if (!data) {
2923 return;
2924 }
2925 if (data.acceleration !== undefined) {
2926 this.acceleration = setRangeValue(data.acceleration);
2927 }
2928 if (data.enable !== undefined) {
2929 this.enable = data.enable;
2930 }
2931 this.position = data.position ? deepExtend({}, data.position) : undefined;
2932 }
2933 }
2934 class Move {
2935 constructor() {
2936 this.angle = new MoveAngle;
2937 this.attract = new Attract;
2938 this.decay = 0;
2939 this.distance = {};
2940 this.direction = MoveDirection.none;
2941 this.drift = 0;
2942 this.enable = false;
2943 this.gravity = new MoveGravity;
2944 this.path = new Path;
2945 this.outModes = new OutModes;
2946 this.random = false;
2947 this.size = false;
2948 this.speed = 2;
2949 this.spin = new Spin;
2950 this.straight = false;
2951 this.trail = new Trail;
2952 this.vibrate = false;
2953 this.warp = false;
2954 }
2955 get collisions() {
2956 return false;
2957 }
2958 set collisions(value) {}
2959 get bounce() {
2960 return this.collisions;
2961 }
2962 set bounce(value) {
2963 this.collisions = value;
2964 }
2965 get out_mode() {
2966 return this.outMode;
2967 }
2968 set out_mode(value) {
2969 this.outMode = value;
2970 }
2971 get outMode() {
2972 return this.outModes.default;
2973 }
2974 set outMode(value) {
2975 this.outModes.default = value;
2976 }
2977 get noise() {
2978 return this.path;
2979 }
2980 set noise(value) {
2981 this.path = value;
2982 }
2983 load(data) {
2984 var _a, _b, _c;
2985 if (data === undefined) {
2986 return;
2987 }
2988 if (data.angle !== undefined) {
2989 if (typeof data.angle === "number") {
2990 this.angle.value = data.angle;
2991 } else {
2992 this.angle.load(data.angle);
2993 }
2994 }
2995 this.attract.load(data.attract);
2996 if (data.decay !== undefined) {
2997 this.decay = data.decay;
2998 }
2999 if (data.direction !== undefined) {
3000 this.direction = data.direction;
3001 }
3002 if (data.distance !== undefined) {
3003 this.distance = typeof data.distance === "number" ? {
3004 horizontal: data.distance,
3005 vertical: data.distance
3006 } : deepExtend({}, data.distance);
3007 }
3008 if (data.drift !== undefined) {
3009 this.drift = setRangeValue(data.drift);
3010 }
3011 if (data.enable !== undefined) {
3012 this.enable = data.enable;
3013 }
3014 this.gravity.load(data.gravity);
3015 const outMode = (_a = data.outMode) !== null && _a !== void 0 ? _a : data.out_mode;
3016 if (data.outModes !== undefined || outMode !== undefined) {
3017 if (typeof data.outModes === "string" || data.outModes === undefined && outMode !== undefined) {
3018 this.outModes.load({
3019 default: (_b = data.outModes) !== null && _b !== void 0 ? _b : outMode
3020 });
3021 } else {
3022 this.outModes.load(data.outModes);
3023 }
3024 }
3025 this.path.load((_c = data.path) !== null && _c !== void 0 ? _c : data.noise);
3026 if (data.random !== undefined) {
3027 this.random = data.random;
3028 }
3029 if (data.size !== undefined) {
3030 this.size = data.size;
3031 }
3032 if (data.speed !== undefined) {
3033 this.speed = setRangeValue(data.speed);
3034 }
3035 this.spin.load(data.spin);
3036 if (data.straight !== undefined) {
3037 this.straight = data.straight;
3038 }
3039 this.trail.load(data.trail);
3040 if (data.vibrate !== undefined) {
3041 this.vibrate = data.vibrate;
3042 }
3043 if (data.warp !== undefined) {
3044 this.warp = data.warp;
3045 }
3046 }
3047 }
3048 class Density {
3049 constructor() {
3050 this.enable = false;
3051 this.area = 800;
3052 this.factor = 1e3;
3053 }
3054 get value_area() {
3055 return this.area;
3056 }
3057 set value_area(value) {
3058 this.area = value;
3059 }
3060 load(data) {
3061 var _a;
3062 if (data === undefined) {
3063 return;
3064 }
3065 if (data.enable !== undefined) {
3066 this.enable = data.enable;
3067 }
3068 const area = (_a = data.area) !== null && _a !== void 0 ? _a : data.value_area;
3069 if (area !== undefined) {
3070 this.area = area;
3071 }
3072 if (data.factor !== undefined) {
3073 this.factor = data.factor;
3074 }
3075 }
3076 }
3077 class ParticlesNumber {
3078 constructor() {
3079 this.density = new Density;
3080 this.limit = 0;
3081 this.value = 100;
3082 }
3083 get max() {
3084 return this.limit;
3085 }
3086 set max(value) {
3087 this.limit = value;
3088 }
3089 load(data) {
3090 var _a;
3091 if (data === undefined) {
3092 return;
3093 }
3094 this.density.load(data.density);
3095 const limit = (_a = data.limit) !== null && _a !== void 0 ? _a : data.max;
3096 if (limit !== undefined) {
3097 this.limit = limit;
3098 }
3099 if (data.value !== undefined) {
3100 this.value = data.value;
3101 }
3102 }
3103 }
3104 class AnimationOptions {
3105 constructor() {
3106 this.count = 0;
3107 this.enable = false;
3108 this.speed = 1;
3109 this.sync = false;
3110 }
3111 load(data) {
3112 if (!data) {
3113 return;
3114 }
3115 if (data.count !== undefined) {
3116 this.count = data.count;
3117 }
3118 if (data.enable !== undefined) {
3119 this.enable = data.enable;
3120 }
3121 if (data.speed !== undefined) {
3122 this.speed = data.speed;
3123 }
3124 if (data.sync !== undefined) {
3125 this.sync = data.sync;
3126 }
3127 }
3128 }
3129 class OpacityAnimation extends AnimationOptions {
3130 constructor() {
3131 super();
3132 this.destroy = DestroyType.none;
3133 this.enable = false;
3134 this.speed = 2;
3135 this.startValue = StartValueType.random;
3136 this.sync = false;
3137 }
3138 get opacity_min() {
3139 return this.minimumValue;
3140 }
3141 set opacity_min(value) {
3142 this.minimumValue = value;
3143 }
3144 load(data) {
3145 var _a;
3146 if (data === undefined) {
3147 return;
3148 }
3149 super.load(data);
3150 if (data.destroy !== undefined) {
3151 this.destroy = data.destroy;
3152 }
3153 if (data.enable !== undefined) {
3154 this.enable = data.enable;
3155 }
3156 this.minimumValue = (_a = data.minimumValue) !== null && _a !== void 0 ? _a : data.opacity_min;
3157 if (data.speed !== undefined) {
3158 this.speed = data.speed;
3159 }
3160 if (data.startValue !== undefined) {
3161 this.startValue = data.startValue;
3162 }
3163 if (data.sync !== undefined) {
3164 this.sync = data.sync;
3165 }
3166 }
3167 }
3168 class Opacity extends ValueWithRandom {
3169 constructor() {
3170 super();
3171 this.animation = new OpacityAnimation;
3172 this.random.minimumValue = .1;
3173 this.value = 1;
3174 }
3175 get anim() {
3176 return this.animation;
3177 }
3178 set anim(value) {
3179 this.animation = value;
3180 }
3181 load(data) {
3182 var _a;
3183 if (!data) {
3184 return;
3185 }
3186 super.load(data);
3187 const animation = (_a = data.animation) !== null && _a !== void 0 ? _a : data.anim;
3188 if (animation !== undefined) {
3189 this.animation.load(animation);
3190 this.value = setRangeValue(this.value, this.animation.enable ? this.animation.minimumValue : undefined);
3191 }
3192 }
3193 }
3194 class Shape {
3195 constructor() {
3196 this.options = {};
3197 this.type = ShapeType.circle;
3198 }
3199 get image() {
3200 var _a;
3201 return (_a = this.options[ShapeType.image]) !== null && _a !== void 0 ? _a : this.options[ShapeType.images];
3202 }
3203 set image(value) {
3204 this.options[ShapeType.image] = value;
3205 this.options[ShapeType.images] = value;
3206 }
3207 get custom() {
3208 return this.options;
3209 }
3210 set custom(value) {
3211 this.options = value;
3212 }
3213 get images() {
3214 return this.image;
3215 }
3216 set images(value) {
3217 this.image = value;
3218 }
3219 get stroke() {
3220 return [];
3221 }
3222 set stroke(_value) {}
3223 get character() {
3224 var _a;
3225 return (_a = this.options[ShapeType.character]) !== null && _a !== void 0 ? _a : this.options[ShapeType.char];
3226 }
3227 set character(value) {
3228 this.options[ShapeType.character] = value;
3229 this.options[ShapeType.char] = value;
3230 }
3231 get polygon() {
3232 var _a;
3233 return (_a = this.options[ShapeType.polygon]) !== null && _a !== void 0 ? _a : this.options[ShapeType.star];
3234 }
3235 set polygon(value) {
3236 this.options[ShapeType.polygon] = value;
3237 this.options[ShapeType.star] = value;
3238 }
3239 load(data) {
3240 var _a, _b, _c;
3241 if (data === undefined) {
3242 return;
3243 }
3244 const options = (_a = data.options) !== null && _a !== void 0 ? _a : data.custom;
3245 if (options !== undefined) {
3246 for (const shape in options) {
3247 const item = options[shape];
3248 if (item !== undefined) {
3249 this.options[shape] = deepExtend((_b = this.options[shape]) !== null && _b !== void 0 ? _b : {}, item);
3250 }
3251 }
3252 }
3253 this.loadShape(data.character, ShapeType.character, ShapeType.char, true);
3254 this.loadShape(data.polygon, ShapeType.polygon, ShapeType.star, false);
3255 this.loadShape((_c = data.image) !== null && _c !== void 0 ? _c : data.images, ShapeType.image, ShapeType.images, true);
3256 if (data.type !== undefined) {
3257 this.type = data.type;
3258 }
3259 }
3260 loadShape(item, mainKey, altKey, altOverride) {
3261 var _a, _b, _c, _d;
3262 if (item === undefined) {
3263 return;
3264 }
3265 if (item instanceof Array) {
3266 if (!(this.options[mainKey] instanceof Array)) {
3267 this.options[mainKey] = [];
3268 if (!this.options[altKey] || altOverride) {
3269 this.options[altKey] = [];
3270 }
3271 }
3272 this.options[mainKey] = deepExtend((_a = this.options[mainKey]) !== null && _a !== void 0 ? _a : [], item);
3273 if (!this.options[altKey] || altOverride) {
3274 this.options[altKey] = deepExtend((_b = this.options[altKey]) !== null && _b !== void 0 ? _b : [], item);
3275 }
3276 } else {
3277 if (this.options[mainKey] instanceof Array) {
3278 this.options[mainKey] = {};
3279 if (!this.options[altKey] || altOverride) {
3280 this.options[altKey] = {};
3281 }
3282 }
3283 this.options[mainKey] = deepExtend((_c = this.options[mainKey]) !== null && _c !== void 0 ? _c : {}, item);
3284 if (!this.options[altKey] || altOverride) {
3285 this.options[altKey] = deepExtend((_d = this.options[altKey]) !== null && _d !== void 0 ? _d : {}, item);
3286 }
3287 }
3288 }
3289 }
3290 class SizeAnimation extends AnimationOptions {
3291 constructor() {
3292 super();
3293 this.destroy = DestroyType.none;
3294 this.enable = false;
3295 this.speed = 5;
3296 this.startValue = StartValueType.random;
3297 this.sync = false;
3298 }
3299 get size_min() {
3300 return this.minimumValue;
3301 }
3302 set size_min(value) {
3303 this.minimumValue = value;
3304 }
3305 load(data) {
3306 var _a;
3307 if (data === undefined) {
3308 return;
3309 }
3310 super.load(data);
3311 if (data.destroy !== undefined) {
3312 this.destroy = data.destroy;
3313 }
3314 if (data.enable !== undefined) {
3315 this.enable = data.enable;
3316 }
3317 this.minimumValue = (_a = data.minimumValue) !== null && _a !== void 0 ? _a : data.size_min;
3318 if (data.speed !== undefined) {
3319 this.speed = data.speed;
3320 }
3321 if (data.startValue !== undefined) {
3322 this.startValue = data.startValue;
3323 }
3324 if (data.sync !== undefined) {
3325 this.sync = data.sync;
3326 }
3327 }
3328 }
3329 class Size extends ValueWithRandom {
3330 constructor() {
3331 super();
3332 this.animation = new SizeAnimation;
3333 this.random.minimumValue = 1;
3334 this.value = 3;
3335 }
3336 get anim() {
3337 return this.animation;
3338 }
3339 set anim(value) {
3340 this.animation = value;
3341 }
3342 load(data) {
3343 var _a;
3344 if (!data) {
3345 return;
3346 }
3347 super.load(data);
3348 const animation = (_a = data.animation) !== null && _a !== void 0 ? _a : data.anim;
3349 if (animation !== undefined) {
3350 this.animation.load(animation);
3351 this.value = setRangeValue(this.value, this.animation.enable ? this.animation.minimumValue : undefined);
3352 }
3353 }
3354 }
3355 class RotateAnimation {
3356 constructor() {
3357 this.enable = false;
3358 this.speed = 0;
3359 this.sync = false;
3360 }
3361 load(data) {
3362 if (data === undefined) {
3363 return;
3364 }
3365 if (data.enable !== undefined) {
3366 this.enable = data.enable;
3367 }
3368 if (data.speed !== undefined) {
3369 this.speed = data.speed;
3370 }
3371 if (data.sync !== undefined) {
3372 this.sync = data.sync;
3373 }
3374 }
3375 }
3376 class Rotate extends ValueWithRandom {
3377 constructor() {
3378 super();
3379 this.animation = new RotateAnimation;
3380 this.direction = RotateDirection.clockwise;
3381 this.path = false;
3382 this.value = 0;
3383 }
3384 load(data) {
3385 if (!data) {
3386 return;
3387 }
3388 super.load(data);
3389 if (data.direction !== undefined) {
3390 this.direction = data.direction;
3391 }
3392 this.animation.load(data.animation);
3393 if (data.path !== undefined) {
3394 this.path = data.path;
3395 }
3396 }
3397 }
3398 class Shadow {
3399 constructor() {
3400 this.blur = 0;
3401 this.color = new OptionsColor;
3402 this.enable = false;
3403 this.offset = {
3404 x: 0,
3405 y: 0
3406 };
3407 this.color.value = "#000000";
3408 }
3409 load(data) {
3410 if (data === undefined) {
3411 return;
3412 }
3413 if (data.blur !== undefined) {
3414 this.blur = data.blur;
3415 }
3416 this.color = OptionsColor.create(this.color, data.color);
3417 if (data.enable !== undefined) {
3418 this.enable = data.enable;
3419 }
3420 if (data.offset === undefined) {
3421 return;
3422 }
3423 if (data.offset.x !== undefined) {
3424 this.offset.x = data.offset.x;
3425 }
3426 if (data.offset.y !== undefined) {
3427 this.offset.y = data.offset.y;
3428 }
3429 }
3430 }
3431 class ColorAnimation {
3432 constructor() {
3433 this.count = 0;
3434 this.enable = false;
3435 this.offset = 0;
3436 this.speed = 1;
3437 this.sync = true;
3438 }
3439 load(data) {
3440 if (data === undefined) {
3441 return;
3442 }
3443 if (data.count !== undefined) {
3444 this.count = data.count;
3445 }
3446 if (data.enable !== undefined) {
3447 this.enable = data.enable;
3448 }
3449 if (data.offset !== undefined) {
3450 this.offset = setRangeValue(data.offset);
3451 }
3452 if (data.speed !== undefined) {
3453 this.speed = data.speed;
3454 }
3455 if (data.sync !== undefined) {
3456 this.sync = data.sync;
3457 }
3458 }
3459 }
3460 class HslAnimation {
3461 constructor() {
3462 this.h = new ColorAnimation;
3463 this.s = new ColorAnimation;
3464 this.l = new ColorAnimation;
3465 }
3466 load(data) {
3467 if (!data) {
3468 return;
3469 }
3470 this.h.load(data.h);
3471 this.s.load(data.s);
3472 this.l.load(data.l);
3473 }
3474 }
3475 class AnimatableColor extends OptionsColor {
3476 constructor() {
3477 super();
3478 this.animation = new HslAnimation;
3479 }
3480 static create(source, data) {
3481 const color = new AnimatableColor;
3482 color.load(source);
3483 if (data !== undefined) {
3484 if (typeof data === "string" || data instanceof Array) {
3485 color.load({
3486 value: data
3487 });
3488 } else {
3489 color.load(data);
3490 }
3491 }
3492 return color;
3493 }
3494 load(data) {
3495 super.load(data);
3496 if (!data) {
3497 return;
3498 }
3499 const colorAnimation = data.animation;
3500 if (colorAnimation !== undefined) {
3501 if (colorAnimation.enable !== undefined) {
3502 this.animation.h.load(colorAnimation);
3503 } else {
3504 this.animation.load(data.animation);
3505 }
3506 }
3507 }
3508 }
3509 class Stroke {
3510 constructor() {
3511 this.width = 0;
3512 }
3513 load(data) {
3514 if (data === undefined) {
3515 return;
3516 }
3517 if (data.color !== undefined) {
3518 this.color = AnimatableColor.create(this.color, data.color);
3519 }
3520 if (data.width !== undefined) {
3521 this.width = data.width;
3522 }
3523 if (data.opacity !== undefined) {
3524 this.opacity = data.opacity;
3525 }
3526 }
3527 }
3528 class BounceFactor extends ValueWithRandom {
3529 constructor() {
3530 super();
3531 this.random.minimumValue = .1;
3532 this.value = 1;
3533 }
3534 }
3535 class Bounce {
3536 constructor() {
3537 this.horizontal = new BounceFactor;
3538 this.vertical = new BounceFactor;
3539 }
3540 load(data) {
3541 if (!data) {
3542 return;
3543 }
3544 this.horizontal.load(data.horizontal);
3545 this.vertical.load(data.vertical);
3546 }
3547 }
3548 class CollisionsOverlap {
3549 constructor() {
3550 this.enable = true;
3551 this.retries = 0;
3552 }
3553 load(data) {
3554 if (!data) {
3555 return;
3556 }
3557 if (data.enable !== undefined) {
3558 this.enable = data.enable;
3559 }
3560 if (data.retries !== undefined) {
3561 this.retries = data.retries;
3562 }
3563 }
3564 }
3565 class Collisions {
3566 constructor() {
3567 this.bounce = new Bounce;
3568 this.enable = false;
3569 this.mode = CollisionMode.bounce;
3570 this.overlap = new CollisionsOverlap;
3571 }
3572 load(data) {
3573 if (data === undefined) {
3574 return;
3575 }
3576 this.bounce.load(data.bounce);
3577 if (data.enable !== undefined) {
3578 this.enable = data.enable;
3579 }
3580 if (data.mode !== undefined) {
3581 this.mode = data.mode;
3582 }
3583 this.overlap.load(data.overlap);
3584 }
3585 }
3586 class TwinkleValues {
3587 constructor() {
3588 this.enable = false;
3589 this.frequency = .05;
3590 this.opacity = 1;
3591 }
3592 load(data) {
3593 if (data === undefined) {
3594 return;
3595 }
3596 if (data.color !== undefined) {
3597 this.color = OptionsColor.create(this.color, data.color);
3598 }
3599 if (data.enable !== undefined) {
3600 this.enable = data.enable;
3601 }
3602 if (data.frequency !== undefined) {
3603 this.frequency = data.frequency;
3604 }
3605 if (data.opacity !== undefined) {
3606 this.opacity = data.opacity;
3607 }
3608 }
3609 }
3610 class Twinkle {
3611 constructor() {
3612 this.lines = new TwinkleValues;
3613 this.particles = new TwinkleValues;
3614 }
3615 load(data) {
3616 if (data === undefined) {
3617 return;
3618 }
3619 this.lines.load(data.lines);
3620 this.particles.load(data.particles);
3621 }
3622 }
3623 class LifeDelay extends ValueWithRandom {
3624 constructor() {
3625 super();
3626 this.sync = false;
3627 }
3628 load(data) {
3629 if (!data) {
3630 return;
3631 }
3632 super.load(data);
3633 if (data.sync !== undefined) {
3634 this.sync = data.sync;
3635 }
3636 }
3637 }
3638 class LifeDuration extends ValueWithRandom {
3639 constructor() {
3640 super();
3641 this.random.minimumValue = 1e-4;
3642 this.sync = false;
3643 }
3644 load(data) {
3645 if (data === undefined) {
3646 return;
3647 }
3648 super.load(data);
3649 if (data.sync !== undefined) {
3650 this.sync = data.sync;
3651 }
3652 }
3653 }
3654 class Life {
3655 constructor() {
3656 this.count = 0;
3657 this.delay = new LifeDelay;
3658 this.duration = new LifeDuration;
3659 }
3660 load(data) {
3661 if (data === undefined) {
3662 return;
3663 }
3664 if (data.count !== undefined) {
3665 this.count = data.count;
3666 }
3667 this.delay.load(data.delay);
3668 this.duration.load(data.duration);
3669 }
3670 }
3671 class SplitFactor extends ValueWithRandom {
3672 constructor() {
3673 super();
3674 this.value = 3;
3675 }
3676 }
3677 class SplitRate extends ValueWithRandom {
3678 constructor() {
3679 super();
3680 this.value = {
3681 min: 4,
3682 max: 9
3683 };
3684 }
3685 }
3686 class Split {
3687 constructor() {
3688 this.count = 1;
3689 this.factor = new SplitFactor;
3690 this.rate = new SplitRate;
3691 this.sizeOffset = true;
3692 }
3693 load(data) {
3694 if (!data) {
3695 return;
3696 }
3697 if (data.count !== undefined) {
3698 this.count = data.count;
3699 }
3700 this.factor.load(data.factor);
3701 this.rate.load(data.rate);
3702 if (data.particles !== undefined) {
3703 this.particles = deepExtend({}, data.particles);
3704 }
3705 if (data.sizeOffset !== undefined) {
3706 this.sizeOffset = data.sizeOffset;
3707 }
3708 }
3709 }
3710 class Destroy {
3711 constructor() {
3712 this.mode = DestroyMode.none;
3713 this.split = new Split;
3714 }
3715 load(data) {
3716 if (!data) {
3717 return;
3718 }
3719 if (data.mode !== undefined) {
3720 this.mode = data.mode;
3721 }
3722 this.split.load(data.split);
3723 }
3724 }
3725 class Wobble {
3726 constructor() {
3727 this.distance = 5;
3728 this.enable = false;
3729 this.speed = 50;
3730 }
3731 load(data) {
3732 if (!data) {
3733 return;
3734 }
3735 if (data.distance !== undefined) {
3736 this.distance = setRangeValue(data.distance);
3737 }
3738 if (data.enable !== undefined) {
3739 this.enable = data.enable;
3740 }
3741 if (data.speed !== undefined) {
3742 this.speed = setRangeValue(data.speed);
3743 }
3744 }
3745 }
3746 class TiltAnimation {
3747 constructor() {
3748 this.enable = false;
3749 this.speed = 0;
3750 this.sync = false;
3751 }
3752 load(data) {
3753 if (data === undefined) {
3754 return;
3755 }
3756 if (data.enable !== undefined) {
3757 this.enable = data.enable;
3758 }
3759 if (data.speed !== undefined) {
3760 this.speed = data.speed;
3761 }
3762 if (data.sync !== undefined) {
3763 this.sync = data.sync;
3764 }
3765 }
3766 }
3767 class Tilt extends ValueWithRandom {
3768 constructor() {
3769 super();
3770 this.animation = new TiltAnimation;
3771 this.direction = TiltDirection.clockwise;
3772 this.enable = false;
3773 this.value = 0;
3774 }
3775 load(data) {
3776 if (!data) {
3777 return;
3778 }
3779 super.load(data);
3780 this.animation.load(data.animation);
3781 if (data.direction !== undefined) {
3782 this.direction = data.direction;
3783 }
3784 if (data.enable !== undefined) {
3785 this.enable = data.enable;
3786 }
3787 }
3788 }
3789 class RollLight {
3790 constructor() {
3791 this.enable = false;
3792 this.value = 0;
3793 }
3794 load(data) {
3795 if (!data) {
3796 return;
3797 }
3798 if (data.enable !== undefined) {
3799 this.enable = data.enable;
3800 }
3801 if (data.value !== undefined) {
3802 this.value = data.value;
3803 }
3804 }
3805 }
3806 class Roll {
3807 constructor() {
3808 this.darken = new RollLight;
3809 this.enable = false;
3810 this.enlighten = new RollLight;
3811 this.mode = RollMode.vertical;
3812 this.speed = 25;
3813 }
3814 load(data) {
3815 if (!data) {
3816 return;
3817 }
3818 if (data.backColor !== undefined) {
3819 this.backColor = OptionsColor.create(this.backColor, data.backColor);
3820 }
3821 this.darken.load(data.darken);
3822 if (data.enable !== undefined) {
3823 this.enable = data.enable;
3824 }
3825 this.enlighten.load(data.enlighten);
3826 if (data.mode !== undefined) {
3827 this.mode = data.mode;
3828 }
3829 if (data.speed !== undefined) {
3830 this.speed = setRangeValue(data.speed);
3831 }
3832 }
3833 }
3834 class ZIndex extends ValueWithRandom {
3835 constructor() {
3836 super();
3837 this.opacityRate = 1;
3838 this.sizeRate = 1;
3839 this.velocityRate = 1;
3840 }
3841 load(data) {
3842 super.load(data);
3843 if (!data) {
3844 return;
3845 }
3846 if (data.opacityRate !== undefined) {
3847 this.opacityRate = data.opacityRate;
3848 }
3849 if (data.sizeRate !== undefined) {
3850 this.sizeRate = data.sizeRate;
3851 }
3852 if (data.velocityRate !== undefined) {
3853 this.velocityRate = data.velocityRate;
3854 }
3855 }
3856 }
3857 class OrbitRotation extends ValueWithRandom {
3858 constructor() {
3859 super();
3860 this.value = 45;
3861 this.random.enable = false;
3862 this.random.minimumValue = 0;
3863 }
3864 load(data) {
3865 if (data === undefined) {
3866 return;
3867 }
3868 super.load(data);
3869 }
3870 }
3871 class Orbit {
3872 constructor() {
3873 this.animation = new AnimationOptions;
3874 this.enable = false;
3875 this.opacity = 1;
3876 this.rotation = new OrbitRotation;
3877 this.width = 1;
3878 }
3879 load(data) {
3880 if (data === undefined) {
3881 return;
3882 }
3883 this.animation.load(data.animation);
3884 this.rotation.load(data.rotation);
3885 if (data.enable !== undefined) {
3886 this.enable = data.enable;
3887 }
3888 if (data.opacity !== undefined) {
3889 this.opacity = data.opacity;
3890 }
3891 if (data.width !== undefined) {
3892 this.width = data.width;
3893 }
3894 if (data.radius !== undefined) {
3895 this.radius = data.radius;
3896 }
3897 if (data.color !== undefined) {
3898 this.color = OptionsColor.create(this.color, data.color);
3899 }
3900 }
3901 }
3902 class Repulse extends ValueWithRandom {
3903 constructor() {
3904 super();
3905 this.enabled = false;
3906 this.distance = 1;
3907 this.duration = 1;
3908 this.factor = 1;
3909 this.speed = 1;
3910 }
3911 load(data) {
3912 super.load(data);
3913 if (!data) {
3914 return;
3915 }
3916 if (data.enabled !== undefined) {
3917 this.enabled = data.enabled;
3918 }
3919 if (data.distance !== undefined) {
3920 this.distance = data.distance;
3921 }
3922 if (data.duration !== undefined) {
3923 this.duration = data.duration;
3924 }
3925 if (data.factor !== undefined) {
3926 this.factor = data.factor;
3927 }
3928 if (data.speed !== undefined) {
3929 this.speed = data.speed;
3930 }
3931 }
3932 }
3933 class AnimatableGradient {
3934 constructor() {
3935 this.angle = new GradientAngle;
3936 this.colors = [];
3937 this.type = GradientType.random;
3938 }
3939 load(data) {
3940 if (!data) {
3941 return;
3942 }
3943 this.angle.load(data.angle);
3944 if (data.colors !== undefined) {
3945 this.colors = data.colors.map((s => {
3946 const tmp = new AnimatableGradientColor;
3947 tmp.load(s);
3948 return tmp;
3949 }));
3950 }
3951 if (data.type !== undefined) {
3952 this.type = data.type;
3953 }
3954 }
3955 }
3956 class GradientAngle {
3957 constructor() {
3958 this.value = 0;
3959 this.animation = new GradientAngleAnimation;
3960 this.direction = RotateDirection.clockwise;
3961 }
3962 load(data) {
3963 if (!data) {
3964 return;
3965 }
3966 this.animation.load(data.animation);
3967 if (data.value !== undefined) {
3968 this.value = data.value;
3969 }
3970 if (data.direction !== undefined) {
3971 this.direction = data.direction;
3972 }
3973 }
3974 }
3975 class GradientColorOpacity {
3976 constructor() {
3977 this.value = 0;
3978 this.animation = new GradientColorOpacityAnimation;
3979 }
3980 load(data) {
3981 if (!data) {
3982 return;
3983 }
3984 this.animation.load(data.animation);
3985 if (data.value !== undefined) {
3986 this.value = setRangeValue(data.value);
3987 }
3988 }
3989 }
3990 class AnimatableGradientColor {
3991 constructor() {
3992 this.stop = 0;
3993 this.value = new AnimatableColor;
3994 }
3995 load(data) {
3996 if (!data) {
3997 return;
3998 }
3999 if (data.stop !== undefined) {
4000 this.stop = data.stop;
4001 }
4002 this.value = AnimatableColor.create(this.value, data.value);
4003 if (data.opacity !== undefined) {
4004 this.opacity = new GradientColorOpacity;
4005 if (typeof data.opacity === "number") {
4006 this.opacity.value = data.opacity;
4007 } else {
4008 this.opacity.load(data.opacity);
4009 }
4010 }
4011 }
4012 }
4013 class GradientAngleAnimation {
4014 constructor() {
4015 this.count = 0;
4016 this.enable = false;
4017 this.speed = 0;
4018 this.sync = false;
4019 }
4020 load(data) {
4021 if (!data) {
4022 return;
4023 }
4024 if (data.count !== undefined) {
4025 this.count = data.count;
4026 }
4027 if (data.enable !== undefined) {
4028 this.enable = data.enable;
4029 }
4030 if (data.speed !== undefined) {
4031 this.speed = data.speed;
4032 }
4033 if (data.sync !== undefined) {
4034 this.sync = data.sync;
4035 }
4036 }
4037 }
4038 class GradientColorOpacityAnimation {
4039 constructor() {
4040 this.count = 0;
4041 this.enable = false;
4042 this.speed = 0;
4043 this.sync = false;
4044 this.startValue = StartValueType.random;
4045 }
4046 load(data) {
4047 if (!data) {
4048 return;
4049 }
4050 if (data.count !== undefined) {
4051 this.count = data.count;
4052 }
4053 if (data.enable !== undefined) {
4054 this.enable = data.enable;
4055 }
4056 if (data.speed !== undefined) {
4057 this.speed = data.speed;
4058 }
4059 if (data.sync !== undefined) {
4060 this.sync = data.sync;
4061 }
4062 if (data.startValue !== undefined) {
4063 this.startValue = data.startValue;
4064 }
4065 }
4066 }
4067 class ParticlesOptions {
4068 constructor() {
4069 this.bounce = new Bounce;
4070 this.collisions = new Collisions;
4071 this.color = new AnimatableColor;
4072 this.destroy = new Destroy;
4073 this.gradient = [];
4074 this.groups = {};
4075 this.life = new Life;
4076 this.links = new Links;
4077 this.move = new Move;
4078 this.number = new ParticlesNumber;
4079 this.opacity = new Opacity;
4080 this.orbit = new Orbit;
4081 this.reduceDuplicates = false;
4082 this.repulse = new Repulse;
4083 this.roll = new Roll;
4084 this.rotate = new Rotate;
4085 this.shadow = new Shadow;
4086 this.shape = new Shape;
4087 this.size = new Size;
4088 this.stroke = new Stroke;
4089 this.tilt = new Tilt;
4090 this.twinkle = new Twinkle;
4091 this.wobble = new Wobble;
4092 this.zIndex = new ZIndex;
4093 }
4094 get line_linked() {
4095 return this.links;
4096 }
4097 set line_linked(value) {
4098 this.links = value;
4099 }
4100 get lineLinked() {
4101 return this.links;
4102 }
4103 set lineLinked(value) {
4104 this.links = value;
4105 }
4106 load(data) {
4107 var _a, _b, _c, _d, _e, _f, _g, _h;
4108 if (data === undefined) {
4109 return;
4110 }
4111 this.bounce.load(data.bounce);
4112 this.color.load(AnimatableColor.create(this.color, data.color));
4113 this.destroy.load(data.destroy);
4114 this.life.load(data.life);
4115 const links = (_b = (_a = data.links) !== null && _a !== void 0 ? _a : data.lineLinked) !== null && _b !== void 0 ? _b : data.line_linked;
4116 if (links !== undefined) {
4117 this.links.load(links);
4118 }
4119 if (data.groups !== undefined) {
4120 for (const group in data.groups) {
4121 const item = data.groups[group];
4122 if (item !== undefined) {
4123 this.groups[group] = deepExtend((_c = this.groups[group]) !== null && _c !== void 0 ? _c : {}, item);
4124 }
4125 }
4126 }
4127 this.move.load(data.move);
4128 this.number.load(data.number);
4129 this.opacity.load(data.opacity);
4130 this.orbit.load(data.orbit);
4131 if (data.reduceDuplicates !== undefined) {
4132 this.reduceDuplicates = data.reduceDuplicates;
4133 }
4134 this.repulse.load(data.repulse);
4135 this.roll.load(data.roll);
4136 this.rotate.load(data.rotate);
4137 this.shape.load(data.shape);
4138 this.size.load(data.size);
4139 this.shadow.load(data.shadow);
4140 this.tilt.load(data.tilt);
4141 this.twinkle.load(data.twinkle);
4142 this.wobble.load(data.wobble);
4143 this.zIndex.load(data.zIndex);
4144 const collisions = (_e = (_d = data.move) === null || _d === void 0 ? void 0 : _d.collisions) !== null && _e !== void 0 ? _e : (_f = data.move) === null || _f === void 0 ? void 0 : _f.bounce;
4145 if (collisions !== undefined) {
4146 this.collisions.enable = collisions;
4147 }
4148 this.collisions.load(data.collisions);
4149 const strokeToLoad = (_g = data.stroke) !== null && _g !== void 0 ? _g : (_h = data.shape) === null || _h === void 0 ? void 0 : _h.stroke;
4150 if (strokeToLoad) {
4151 if (strokeToLoad instanceof Array) {
4152 this.stroke = strokeToLoad.map((s => {
4153 const tmp = new Stroke;
4154 tmp.load(s);
4155 return tmp;
4156 }));
4157 } else {
4158 if (this.stroke instanceof Array) {
4159 this.stroke = new Stroke;
4160 }
4161 this.stroke.load(strokeToLoad);
4162 }
4163 }
4164 const gradientToLoad = data.gradient;
4165 if (gradientToLoad) {
4166 if (gradientToLoad instanceof Array) {
4167 this.gradient = gradientToLoad.map((s => {
4168 const tmp = new AnimatableGradient;
4169 tmp.load(s);
4170 return tmp;
4171 }));
4172 } else {
4173 if (this.gradient instanceof Array) {
4174 this.gradient = new AnimatableGradient;
4175 }
4176 this.gradient.load(gradientToLoad);
4177 }
4178 }
4179 }
4180 }
4181 class Vector3d extends Vector {
4182 constructor(x, y, z) {
4183 super(x, y);
4184 this.z = z === undefined ? x.z : z;
4185 }
4186 static clone(source) {
4187 return Vector3d.create(source.x, source.y, source.z);
4188 }
4189 static create(x, y, z) {
4190 return new Vector3d(x, y, z);
4191 }
4192 add(v) {
4193 return v instanceof Vector3d ? Vector3d.create(this.x + v.x, this.y + v.y, this.z + v.z) : super.add(v);
4194 }
4195 addTo(v) {
4196 super.addTo(v);
4197 if (v instanceof Vector3d) {
4198 this.z += v.z;
4199 }
4200 }
4201 sub(v) {
4202 return v instanceof Vector3d ? Vector3d.create(this.x - v.x, this.y - v.y, this.z - v.z) : super.sub(v);
4203 }
4204 subFrom(v) {
4205 super.subFrom(v);
4206 if (v instanceof Vector3d) {
4207 this.z -= v.z;
4208 }
4209 }
4210 mult(n) {
4211 return Vector3d.create(this.x * n, this.y * n, this.z * n);
4212 }
4213 multTo(n) {
4214 super.multTo(n);
4215 this.z *= n;
4216 }
4217 div(n) {
4218 return Vector3d.create(this.x / n, this.y / n, this.z / n);
4219 }
4220 divTo(n) {
4221 super.divTo(n);
4222 this.z /= n;
4223 }
4224 copy() {
4225 return Vector3d.clone(this);
4226 }
4227 setTo(v) {
4228 super.setTo(v);
4229 if (v instanceof Vector3d) {
4230 this.z = v.z;
4231 }
4232 }
4233 }
4234 const fixOutMode = data => {
4235 if (isInArray(data.outMode, data.checkModes) || isInArray(data.outMode, data.checkModes)) {
4236 if (data.coord > data.maxCoord - data.radius * 2) {
4237 data.setCb(-data.radius);
4238 } else if (data.coord < data.radius * 2) {
4239 data.setCb(data.radius);
4240 }
4241 }
4242 };
4243 class Particle {
4244 constructor(id, container, position, overrideOptions, group) {
4245 var _a, _b, _c, _d, _e, _f, _g, _h, _j;
4246 this.id = id;
4247 this.container = container;
4248 this.group = group;
4249 this.fill = true;
4250 this.close = true;
4251 this.lastPathTime = 0;
4252 this.destroyed = false;
4253 this.unbreakable = false;
4254 this.splitCount = 0;
4255 this.misplaced = false;
4256 this.retina = {
4257 maxDistance: {}
4258 };
4259 const pxRatio = container.retina.pixelRatio;
4260 const mainOptions = container.actualOptions;
4261 const particlesOptions = new ParticlesOptions;
4262 particlesOptions.load(mainOptions.particles);
4263 const shapeType = particlesOptions.shape.type;
4264 const reduceDuplicates = particlesOptions.reduceDuplicates;
4265 this.shape = shapeType instanceof Array ? itemFromArray(shapeType, this.id, reduceDuplicates) : shapeType;
4266 if (overrideOptions === null || overrideOptions === void 0 ? void 0 : overrideOptions.shape) {
4267 if (overrideOptions.shape.type) {
4268 const overrideShapeType = overrideOptions.shape.type;
4269 this.shape = overrideShapeType instanceof Array ? itemFromArray(overrideShapeType, this.id, reduceDuplicates) : overrideShapeType;
4270 }
4271 const shapeOptions = new Shape;
4272 shapeOptions.load(overrideOptions.shape);
4273 if (this.shape) {
4274 this.shapeData = this.loadShapeData(shapeOptions, reduceDuplicates);
4275 }
4276 } else {
4277 this.shapeData = this.loadShapeData(particlesOptions.shape, reduceDuplicates);
4278 }
4279 if (overrideOptions !== undefined) {
4280 particlesOptions.load(overrideOptions);
4281 }
4282 if (((_a = this.shapeData) === null || _a === void 0 ? void 0 : _a.particles) !== undefined) {
4283 particlesOptions.load((_b = this.shapeData) === null || _b === void 0 ? void 0 : _b.particles);
4284 }
4285 this.fill = (_d = (_c = this.shapeData) === null || _c === void 0 ? void 0 : _c.fill) !== null && _d !== void 0 ? _d : this.fill;
4286 this.close = (_f = (_e = this.shapeData) === null || _e === void 0 ? void 0 : _e.close) !== null && _f !== void 0 ? _f : this.close;
4287 this.options = particlesOptions;
4288 this.pathDelay = getValue(this.options.move.path.delay) * 1e3;
4289 const zIndexValue = getRangeValue(this.options.zIndex.value);
4290 container.retina.initParticle(this);
4291 const sizeOptions = this.options.size, sizeRange = sizeOptions.value;
4292 this.size = {
4293 enable: sizeOptions.animation.enable,
4294 value: getValue(sizeOptions) * container.retina.pixelRatio,
4295 max: getRangeMax(sizeRange) * pxRatio,
4296 min: getRangeMin(sizeRange) * pxRatio,
4297 loops: 0,
4298 maxLoops: sizeOptions.animation.count
4299 };
4300 const sizeAnimation = sizeOptions.animation;
4301 if (sizeAnimation.enable) {
4302 this.size.status = AnimationStatus.increasing;
4303 switch (sizeAnimation.startValue) {
4304 case StartValueType.min:
4305 this.size.value = this.size.min;
4306 this.size.status = AnimationStatus.increasing;
4307 break;
4308
4309 case StartValueType.random:
4310 this.size.value = randomInRange(this.size) * pxRatio;
4311 this.size.status = Math.random() >= .5 ? AnimationStatus.increasing : AnimationStatus.decreasing;
4312 break;
4313
4314 case StartValueType.max:
4315 default:
4316 this.size.value = this.size.max;
4317 this.size.status = AnimationStatus.decreasing;
4318 break;
4319 }
4320 this.size.velocity = ((_g = this.retina.sizeAnimationSpeed) !== null && _g !== void 0 ? _g : container.retina.sizeAnimationSpeed) / 100 * container.retina.reduceFactor;
4321 if (!sizeAnimation.sync) {
4322 this.size.velocity *= Math.random();
4323 }
4324 }
4325 this.direction = getParticleDirectionAngle(this.options.move.direction);
4326 this.bubble = {
4327 inRange: false
4328 };
4329 this.initialVelocity = this.calculateVelocity();
4330 this.velocity = this.initialVelocity.copy();
4331 this.moveDecay = 1 - getRangeValue(this.options.move.decay);
4332 this.position = this.calcPosition(container, position, clamp(zIndexValue, 0, container.zLayers));
4333 this.initialPosition = this.position.copy();
4334 this.offset = Vector.origin;
4335 const particles = container.particles;
4336 particles.needsSort = particles.needsSort || particles.lastZIndex < this.position.z;
4337 particles.lastZIndex = this.position.z;
4338 this.zIndexFactor = this.position.z / container.zLayers;
4339 this.sides = 24;
4340 let drawer = container.drawers.get(this.shape);
4341 if (!drawer) {
4342 drawer = Plugins.getShapeDrawer(this.shape);
4343 if (drawer) {
4344 container.drawers.set(this.shape, drawer);
4345 }
4346 }
4347 if (drawer === null || drawer === void 0 ? void 0 : drawer.loadShape) {
4348 drawer === null || drawer === void 0 ? void 0 : drawer.loadShape(this);
4349 }
4350 const sideCountFunc = drawer === null || drawer === void 0 ? void 0 : drawer.getSidesCount;
4351 if (sideCountFunc) {
4352 this.sides = sideCountFunc(this);
4353 }
4354 this.life = this.loadLife();
4355 this.spawning = this.life.delay > 0;
4356 if (this.options.move.spin.enable) {
4357 const spinPos = (_h = this.options.move.spin.position) !== null && _h !== void 0 ? _h : {
4358 x: 50,
4359 y: 50
4360 };
4361 const spinCenter = {
4362 x: spinPos.x / 100 * container.canvas.size.width,
4363 y: spinPos.y / 100 * container.canvas.size.height
4364 };
4365 const pos = this.getPosition();
4366 const distance = getDistance(pos, spinCenter);
4367 this.spin = {
4368 center: spinCenter,
4369 direction: this.velocity.x >= 0 ? RotateDirection.clockwise : RotateDirection.counterClockwise,
4370 angle: this.velocity.angle,
4371 radius: distance,
4372 acceleration: (_j = this.retina.spinAcceleration) !== null && _j !== void 0 ? _j : getRangeValue(this.options.move.spin.acceleration)
4373 };
4374 }
4375 this.shadowColor = colorToRgb(this.options.shadow.color);
4376 for (const updater of container.particles.updaters) {
4377 if (updater.init) {
4378 updater.init(this);
4379 }
4380 }
4381 if (drawer && drawer.particleInit) {
4382 drawer.particleInit(container, this);
4383 }
4384 for (const [, plugin] of container.plugins) {
4385 if (plugin.particleCreated) {
4386 plugin.particleCreated(this);
4387 }
4388 }
4389 }
4390 isVisible() {
4391 return !this.destroyed && !this.spawning && this.isInsideCanvas();
4392 }
4393 isInsideCanvas() {
4394 const radius = this.getRadius();
4395 const canvasSize = this.container.canvas.size;
4396 return this.position.x >= -radius && this.position.y >= -radius && this.position.y <= canvasSize.height + radius && this.position.x <= canvasSize.width + radius;
4397 }
4398 draw(delta) {
4399 const container = this.container;
4400 for (const [, plugin] of container.plugins) {
4401 container.canvas.drawParticlePlugin(plugin, this, delta);
4402 }
4403 container.canvas.drawParticle(this, delta);
4404 }
4405 getPosition() {
4406 return {
4407 x: this.position.x + this.offset.x,
4408 y: this.position.y + this.offset.y,
4409 z: this.position.z
4410 };
4411 }
4412 getRadius() {
4413 var _a;
4414 return (_a = this.bubble.radius) !== null && _a !== void 0 ? _a : this.size.value;
4415 }
4416 getMass() {
4417 return this.getRadius() ** 2 * Math.PI / 2;
4418 }
4419 getFillColor() {
4420 var _a, _b, _c;
4421 const color = (_a = this.bubble.color) !== null && _a !== void 0 ? _a : getHslFromAnimation(this.color);
4422 if (color && this.roll && (this.backColor || this.roll.alter)) {
4423 const rolled = Math.floor(((_c = (_b = this.roll) === null || _b === void 0 ? void 0 : _b.angle) !== null && _c !== void 0 ? _c : 0) / (Math.PI / 2)) % 2;
4424 if (rolled) {
4425 if (this.backColor) {
4426 return this.backColor;
4427 }
4428 if (this.roll.alter) {
4429 return alterHsl(color, this.roll.alter.type, this.roll.alter.value);
4430 }
4431 }
4432 }
4433 return color;
4434 }
4435 getStrokeColor() {
4436 var _a, _b;
4437 return (_b = (_a = this.bubble.color) !== null && _a !== void 0 ? _a : getHslFromAnimation(this.strokeColor)) !== null && _b !== void 0 ? _b : this.getFillColor();
4438 }
4439 destroy(override) {
4440 this.destroyed = true;
4441 this.bubble.inRange = false;
4442 if (this.unbreakable) {
4443 return;
4444 }
4445 this.destroyed = true;
4446 this.bubble.inRange = false;
4447 for (const [, plugin] of this.container.plugins) {
4448 if (plugin.particleDestroyed) {
4449 plugin.particleDestroyed(this, override);
4450 }
4451 }
4452 if (override) {
4453 return;
4454 }
4455 const destroyOptions = this.options.destroy;
4456 if (destroyOptions.mode === DestroyMode.split) {
4457 this.split();
4458 }
4459 }
4460 reset() {
4461 if (this.opacity) {
4462 this.opacity.loops = 0;
4463 }
4464 this.size.loops = 0;
4465 }
4466 split() {
4467 const splitOptions = this.options.destroy.split;
4468 if (splitOptions.count >= 0 && this.splitCount++ > splitOptions.count) {
4469 return;
4470 }
4471 const rate = getRangeValue(splitOptions.rate.value);
4472 for (let i = 0; i < rate; i++) {
4473 this.container.particles.addSplitParticle(this);
4474 }
4475 }
4476 calcPosition(container, position, zIndex, tryCount = 0) {
4477 var _a, _b, _c, _d, _e, _f;
4478 for (const [, plugin] of container.plugins) {
4479 const pluginPos = plugin.particlePosition !== undefined ? plugin.particlePosition(position, this) : undefined;
4480 if (pluginPos !== undefined) {
4481 return Vector3d.create(pluginPos.x, pluginPos.y, zIndex);
4482 }
4483 }
4484 const canvasSize = container.canvas.size;
4485 const pos = Vector3d.create((_a = position === null || position === void 0 ? void 0 : position.x) !== null && _a !== void 0 ? _a : Math.random() * canvasSize.width, (_b = position === null || position === void 0 ? void 0 : position.y) !== null && _b !== void 0 ? _b : Math.random() * canvasSize.height, zIndex);
4486 const radius = this.getRadius();
4487 const outModes = this.options.move.outModes, fixHorizontal = outMode => {
4488 fixOutMode({
4489 outMode,
4490 checkModes: [ OutMode.bounce, OutMode.bounceHorizontal ],
4491 coord: pos.x,
4492 maxCoord: container.canvas.size.width,
4493 setCb: value => pos.x += value,
4494 radius
4495 });
4496 }, fixVertical = outMode => {
4497 fixOutMode({
4498 outMode,
4499 checkModes: [ OutMode.bounce, OutMode.bounceVertical ],
4500 coord: pos.y,
4501 maxCoord: container.canvas.size.height,
4502 setCb: value => pos.y += value,
4503 radius
4504 });
4505 };
4506 fixHorizontal((_c = outModes.left) !== null && _c !== void 0 ? _c : outModes.default);
4507 fixHorizontal((_d = outModes.right) !== null && _d !== void 0 ? _d : outModes.default);
4508 fixVertical((_e = outModes.top) !== null && _e !== void 0 ? _e : outModes.default);
4509 fixVertical((_f = outModes.bottom) !== null && _f !== void 0 ? _f : outModes.default);
4510 if (this.checkOverlap(pos, tryCount)) {
4511 return this.calcPosition(container, undefined, zIndex, tryCount + 1);
4512 }
4513 return pos;
4514 }
4515 checkOverlap(pos, tryCount = 0) {
4516 const collisionsOptions = this.options.collisions;
4517 const radius = this.getRadius();
4518 if (!collisionsOptions.enable) {
4519 return false;
4520 }
4521 const overlapOptions = collisionsOptions.overlap;
4522 if (overlapOptions.enable) {
4523 return false;
4524 }
4525 const retries = overlapOptions.retries;
4526 if (retries >= 0 && tryCount > retries) {
4527 throw new Error("Particle is overlapping and can't be placed");
4528 }
4529 let overlaps = false;
4530 for (const particle of this.container.particles.array) {
4531 if (getDistance(pos, particle.position) < radius + particle.getRadius()) {
4532 overlaps = true;
4533 break;
4534 }
4535 }
4536 return overlaps;
4537 }
4538 calculateVelocity() {
4539 const baseVelocity = getParticleBaseVelocity(this.direction);
4540 const res = baseVelocity.copy();
4541 const moveOptions = this.options.move;
4542 const rad = Math.PI / 180 * moveOptions.angle.value;
4543 const radOffset = Math.PI / 180 * moveOptions.angle.offset;
4544 const range = {
4545 left: radOffset - rad / 2,
4546 right: radOffset + rad / 2
4547 };
4548 if (!moveOptions.straight) {
4549 res.angle += randomInRange(setRangeValue(range.left, range.right));
4550 }
4551 if (moveOptions.random && typeof moveOptions.speed === "number") {
4552 res.length *= Math.random();
4553 }
4554 return res;
4555 }
4556 loadShapeData(shapeOptions, reduceDuplicates) {
4557 const shapeData = shapeOptions.options[this.shape];
4558 if (shapeData) {
4559 return deepExtend({}, shapeData instanceof Array ? itemFromArray(shapeData, this.id, reduceDuplicates) : shapeData);
4560 }
4561 }
4562 loadLife() {
4563 const container = this.container;
4564 const particlesOptions = this.options;
4565 const lifeOptions = particlesOptions.life;
4566 const life = {
4567 delay: container.retina.reduceFactor ? getRangeValue(lifeOptions.delay.value) * (lifeOptions.delay.sync ? 1 : Math.random()) / container.retina.reduceFactor * 1e3 : 0,
4568 delayTime: 0,
4569 duration: container.retina.reduceFactor ? getRangeValue(lifeOptions.duration.value) * (lifeOptions.duration.sync ? 1 : Math.random()) / container.retina.reduceFactor * 1e3 : 0,
4570 time: 0,
4571 count: particlesOptions.life.count
4572 };
4573 if (life.duration <= 0) {
4574 life.duration = -1;
4575 }
4576 if (life.count <= 0) {
4577 life.count = -1;
4578 }
4579 return life;
4580 }
4581 }
4582 class InteractionManager {
4583 constructor(container) {
4584 this.container = container;
4585 const interactors = Plugins.getInteractors(container);
4586 this.externalInteractors = [];
4587 this.particleInteractors = [];
4588 for (const interactor of interactors) {
4589 switch (interactor.type) {
4590 case InteractorType.External:
4591 this.externalInteractors.push(interactor);
4592 break;
4593
4594 case InteractorType.Particles:
4595 this.particleInteractors.push(interactor);
4596 break;
4597 }
4598 }
4599 }
4600 externalInteract(delta) {
4601 for (const interactor of this.externalInteractors) {
4602 if (interactor.isEnabled()) {
4603 interactor.interact(delta);
4604 }
4605 }
4606 }
4607 particlesInteract(particle, delta) {
4608 for (const interactor of this.externalInteractors) {
4609 interactor.reset(particle);
4610 }
4611 for (const interactor of this.particleInteractors) {
4612 if (interactor.isEnabled(particle)) {
4613 interactor.interact(particle, delta);
4614 }
4615 }
4616 }
4617 }
4618 function applyDistance(particle) {
4619 const initialPosition = particle.initialPosition;
4620 const {dx, dy} = getDistances(initialPosition, particle.position);
4621 const dxFixed = Math.abs(dx), dyFixed = Math.abs(dy);
4622 const hDistance = particle.retina.maxDistance.horizontal;
4623 const vDistance = particle.retina.maxDistance.vertical;
4624 if (!hDistance && !vDistance) {
4625 return;
4626 }
4627 if ((hDistance && dxFixed >= hDistance || vDistance && dyFixed >= vDistance) && !particle.misplaced) {
4628 particle.misplaced = !!hDistance && dxFixed > hDistance || !!vDistance && dyFixed > vDistance;
4629 if (hDistance) {
4630 particle.velocity.x = particle.velocity.y / 2 - particle.velocity.x;
4631 }
4632 if (vDistance) {
4633 particle.velocity.y = particle.velocity.x / 2 - particle.velocity.y;
4634 }
4635 } else if ((!hDistance || dxFixed < hDistance) && (!vDistance || dyFixed < vDistance) && particle.misplaced) {
4636 particle.misplaced = false;
4637 } else if (particle.misplaced) {
4638 const pos = particle.position, vel = particle.velocity;
4639 if (hDistance && (pos.x < initialPosition.x && vel.x < 0 || pos.x > initialPosition.x && vel.x > 0)) {
4640 vel.x *= -Math.random();
4641 }
4642 if (vDistance && (pos.y < initialPosition.y && vel.y < 0 || pos.y > initialPosition.y && vel.y > 0)) {
4643 vel.y *= -Math.random();
4644 }
4645 }
4646 }
4647 class Mover {
4648 constructor(container) {
4649 this.container = container;
4650 }
4651 move(particle, delta) {
4652 if (particle.destroyed) {
4653 return;
4654 }
4655 this.moveParticle(particle, delta);
4656 this.moveParallax(particle);
4657 }
4658 moveParticle(particle, delta) {
4659 var _a, _b, _c;
4660 var _d, _e;
4661 const particleOptions = particle.options;
4662 const moveOptions = particleOptions.move;
4663 if (!moveOptions.enable) {
4664 return;
4665 }
4666 const container = this.container, slowFactor = this.getProximitySpeedFactor(particle), baseSpeed = ((_a = (_d = particle.retina).moveSpeed) !== null && _a !== void 0 ? _a : _d.moveSpeed = getRangeValue(moveOptions.speed) * container.retina.pixelRatio) * container.retina.reduceFactor, moveDrift = (_b = (_e = particle.retina).moveDrift) !== null && _b !== void 0 ? _b : _e.moveDrift = getRangeValue(particle.options.move.drift) * container.retina.pixelRatio, maxSize = getRangeMax(particleOptions.size.value) * container.retina.pixelRatio, sizeFactor = moveOptions.size ? particle.getRadius() / maxSize : 1, diffFactor = 2, speedFactor = sizeFactor * slowFactor * (delta.factor || 1) / diffFactor, moveSpeed = baseSpeed * speedFactor;
4667 this.applyPath(particle, delta);
4668 const gravityOptions = moveOptions.gravity;
4669 const gravityFactor = gravityOptions.enable && gravityOptions.inverse ? -1 : 1;
4670 if (gravityOptions.enable && moveSpeed) {
4671 particle.velocity.y += gravityFactor * (gravityOptions.acceleration * delta.factor) / (60 * moveSpeed);
4672 }
4673 if (moveDrift && moveSpeed) {
4674 particle.velocity.x += moveDrift * delta.factor / (60 * moveSpeed);
4675 }
4676 const decay = particle.moveDecay;
4677 if (decay != 1) {
4678 particle.velocity.multTo(decay);
4679 }
4680 const velocity = particle.velocity.mult(moveSpeed);
4681 const maxSpeed = (_c = particle.retina.maxSpeed) !== null && _c !== void 0 ? _c : container.retina.maxSpeed;
4682 if (gravityOptions.enable && gravityOptions.maxSpeed > 0 && (!gravityOptions.inverse && velocity.y >= 0 && velocity.y >= maxSpeed || gravityOptions.inverse && velocity.y <= 0 && velocity.y <= -maxSpeed)) {
4683 velocity.y = gravityFactor * maxSpeed;
4684 if (moveSpeed) {
4685 particle.velocity.y = velocity.y / moveSpeed;
4686 }
4687 }
4688 const zIndexOptions = particle.options.zIndex, zVelocityFactor = (1 - particle.zIndexFactor) ** zIndexOptions.velocityRate;
4689 if (moveOptions.spin.enable) {
4690 this.spin(particle, moveSpeed);
4691 } else {
4692 if (zVelocityFactor != 1) {
4693 velocity.multTo(zVelocityFactor);
4694 }
4695 particle.position.addTo(velocity);
4696 if (moveOptions.vibrate) {
4697 particle.position.x += Math.sin(particle.position.x * Math.cos(particle.position.y));
4698 particle.position.y += Math.cos(particle.position.y * Math.sin(particle.position.x));
4699 }
4700 }
4701 applyDistance(particle);
4702 }
4703 spin(particle, moveSpeed) {
4704 const container = this.container;
4705 if (!particle.spin) {
4706 return;
4707 }
4708 const updateFunc = {
4709 x: particle.spin.direction === RotateDirection.clockwise ? Math.cos : Math.sin,
4710 y: particle.spin.direction === RotateDirection.clockwise ? Math.sin : Math.cos
4711 };
4712 particle.position.x = particle.spin.center.x + particle.spin.radius * updateFunc.x(particle.spin.angle);
4713 particle.position.y = particle.spin.center.y + particle.spin.radius * updateFunc.y(particle.spin.angle);
4714 particle.spin.radius += particle.spin.acceleration;
4715 const maxCanvasSize = Math.max(container.canvas.size.width, container.canvas.size.height);
4716 if (particle.spin.radius > maxCanvasSize / 2) {
4717 particle.spin.radius = maxCanvasSize / 2;
4718 particle.spin.acceleration *= -1;
4719 } else if (particle.spin.radius < 0) {
4720 particle.spin.radius = 0;
4721 particle.spin.acceleration *= -1;
4722 }
4723 particle.spin.angle += moveSpeed / 100 * (1 - particle.spin.radius / maxCanvasSize);
4724 }
4725 applyPath(particle, delta) {
4726 const particlesOptions = particle.options;
4727 const pathOptions = particlesOptions.move.path;
4728 const pathEnabled = pathOptions.enable;
4729 if (!pathEnabled) {
4730 return;
4731 }
4732 const container = this.container;
4733 if (particle.lastPathTime <= particle.pathDelay) {
4734 particle.lastPathTime += delta.value;
4735 return;
4736 }
4737 const path = container.pathGenerator.generate(particle);
4738 particle.velocity.addTo(path);
4739 if (pathOptions.clamp) {
4740 particle.velocity.x = clamp(particle.velocity.x, -1, 1);
4741 particle.velocity.y = clamp(particle.velocity.y, -1, 1);
4742 }
4743 particle.lastPathTime -= particle.pathDelay;
4744 }
4745 moveParallax(particle) {
4746 const container = this.container;
4747 const options = container.actualOptions;
4748 if (isSsr() || !options.interactivity.events.onHover.parallax.enable) {
4749 return;
4750 }
4751 const parallaxForce = options.interactivity.events.onHover.parallax.force;
4752 const mousePos = container.interactivity.mouse.position;
4753 if (!mousePos) {
4754 return;
4755 }
4756 const canvasCenter = {
4757 x: container.canvas.size.width / 2,
4758 y: container.canvas.size.height / 2
4759 };
4760 const parallaxSmooth = options.interactivity.events.onHover.parallax.smooth;
4761 const factor = particle.getRadius() / parallaxForce;
4762 const tmp = {
4763 x: (mousePos.x - canvasCenter.x) * factor,
4764 y: (mousePos.y - canvasCenter.y) * factor
4765 };
4766 particle.offset.x += (tmp.x - particle.offset.x) / parallaxSmooth;
4767 particle.offset.y += (tmp.y - particle.offset.y) / parallaxSmooth;
4768 }
4769 getProximitySpeedFactor(particle) {
4770 const container = this.container;
4771 const options = container.actualOptions;
4772 const active = isInArray(HoverMode.slow, options.interactivity.events.onHover.mode);
4773 if (!active) {
4774 return 1;
4775 }
4776 const mousePos = this.container.interactivity.mouse.position;
4777 if (!mousePos) {
4778 return 1;
4779 }
4780 const particlePos = particle.getPosition();
4781 const dist = getDistance(mousePos, particlePos);
4782 const radius = container.retina.slowModeRadius;
4783 if (dist > radius) {
4784 return 1;
4785 }
4786 const proximityFactor = dist / radius || 0;
4787 const slowFactor = options.interactivity.modes.slow.factor;
4788 return proximityFactor / slowFactor;
4789 }
4790 }
4791 class Particles {
4792 constructor(container) {
4793 this.container = container;
4794 this.nextId = 0;
4795 this.array = [];
4796 this.zArray = [];
4797 this.mover = new Mover(container);
4798 this.limit = 0;
4799 this.needsSort = false;
4800 this.lastZIndex = 0;
4801 this.freqs = {
4802 links: new Map,
4803 triangles: new Map
4804 };
4805 this.interactionManager = new InteractionManager(container);
4806 const canvasSize = this.container.canvas.size;
4807 this.linksColors = new Map;
4808 this.quadTree = new QuadTree(new Rectangle(-canvasSize.width / 4, -canvasSize.height / 4, canvasSize.width * 3 / 2, canvasSize.height * 3 / 2), 4);
4809 this.updaters = Plugins.getUpdaters(container);
4810 }
4811 get count() {
4812 return this.array.length;
4813 }
4814 init() {
4815 var _a;
4816 const container = this.container;
4817 const options = container.actualOptions;
4818 this.lastZIndex = 0;
4819 this.needsSort = false;
4820 this.freqs.links = new Map;
4821 this.freqs.triangles = new Map;
4822 let handled = false;
4823 for (const [, plugin] of container.plugins) {
4824 if (plugin.particlesInitialization !== undefined) {
4825 handled = plugin.particlesInitialization();
4826 }
4827 if (handled) {
4828 break;
4829 }
4830 }
4831 this.addManualParticles();
4832 if (!handled) {
4833 for (const group in options.particles.groups) {
4834 const groupOptions = options.particles.groups[group];
4835 for (let i = this.count, j = 0; j < ((_a = groupOptions.number) === null || _a === void 0 ? void 0 : _a.value) && i < options.particles.number.value; i++,
4836 j++) {
4837 this.addParticle(undefined, groupOptions, group);
4838 }
4839 }
4840 for (let i = this.count; i < options.particles.number.value; i++) {
4841 this.addParticle();
4842 }
4843 }
4844 container.pathGenerator.init(container);
4845 }
4846 redraw() {
4847 this.clear();
4848 this.init();
4849 this.draw({
4850 value: 0,
4851 factor: 0
4852 });
4853 }
4854 removeAt(index, quantity = 1, group, override) {
4855 if (!(index >= 0 && index <= this.count)) {
4856 return;
4857 }
4858 let deleted = 0;
4859 for (let i = index; deleted < quantity && i < this.count; i++) {
4860 const particle = this.array[i];
4861 if (!particle || particle.group !== group) {
4862 continue;
4863 }
4864 particle.destroy(override);
4865 this.array.splice(i--, 1);
4866 const zIdx = this.zArray.indexOf(particle);
4867 this.zArray.splice(zIdx, 1);
4868 deleted++;
4869 }
4870 }
4871 remove(particle, group, override) {
4872 this.removeAt(this.array.indexOf(particle), undefined, group, override);
4873 }
4874 update(delta) {
4875 const container = this.container;
4876 const particlesToDelete = [];
4877 container.pathGenerator.update();
4878 for (const [, plugin] of container.plugins) {
4879 if (plugin.update !== undefined) {
4880 plugin.update(delta);
4881 }
4882 }
4883 for (const particle of this.array) {
4884 const resizeFactor = container.canvas.resizeFactor;
4885 if (resizeFactor) {
4886 particle.position.x *= resizeFactor.width;
4887 particle.position.y *= resizeFactor.height;
4888 }
4889 particle.bubble.inRange = false;
4890 for (const [, plugin] of this.container.plugins) {
4891 if (particle.destroyed) {
4892 break;
4893 }
4894 if (plugin.particleUpdate) {
4895 plugin.particleUpdate(particle, delta);
4896 }
4897 }
4898 this.mover.move(particle, delta);
4899 if (particle.destroyed) {
4900 particlesToDelete.push(particle);
4901 continue;
4902 }
4903 this.quadTree.insert(new Point(particle.getPosition(), particle));
4904 }
4905 for (const particle of particlesToDelete) {
4906 this.remove(particle);
4907 }
4908 this.interactionManager.externalInteract(delta);
4909 for (const particle of container.particles.array) {
4910 for (const updater of this.updaters) {
4911 updater.update(particle, delta);
4912 }
4913 if (!particle.destroyed && !particle.spawning) {
4914 this.interactionManager.particlesInteract(particle, delta);
4915 }
4916 }
4917 delete container.canvas.resizeFactor;
4918 }
4919 draw(delta) {
4920 const container = this.container;
4921 container.canvas.clear();
4922 const canvasSize = this.container.canvas.size;
4923 this.quadTree = new QuadTree(new Rectangle(-canvasSize.width / 4, -canvasSize.height / 4, canvasSize.width * 3 / 2, canvasSize.height * 3 / 2), 4);
4924 this.update(delta);
4925 if (this.needsSort) {
4926 this.zArray.sort(((a, b) => b.position.z - a.position.z || a.id - b.id));
4927 this.lastZIndex = this.zArray[this.zArray.length - 1].position.z;
4928 this.needsSort = false;
4929 }
4930 for (const [, plugin] of container.plugins) {
4931 container.canvas.drawPlugin(plugin, delta);
4932 }
4933 for (const p of this.zArray) {
4934 p.draw(delta);
4935 }
4936 }
4937 clear() {
4938 this.array = [];
4939 this.zArray = [];
4940 }
4941 push(nb, mouse, overrideOptions, group) {
4942 this.pushing = true;
4943 for (let i = 0; i < nb; i++) {
4944 this.addParticle(mouse === null || mouse === void 0 ? void 0 : mouse.position, overrideOptions, group);
4945 }
4946 this.pushing = false;
4947 }
4948 addParticle(position, overrideOptions, group) {
4949 const container = this.container;
4950 const options = container.actualOptions;
4951 const limit = options.particles.number.limit * container.density;
4952 if (limit > 0) {
4953 const countToRemove = this.count + 1 - limit;
4954 if (countToRemove > 0) {
4955 this.removeQuantity(countToRemove);
4956 }
4957 }
4958 return this.pushParticle(position, overrideOptions, group);
4959 }
4960 addSplitParticle(parent) {
4961 const splitOptions = parent.options.destroy.split;
4962 const options = new ParticlesOptions;
4963 options.load(parent.options);
4964 const factor = getRangeValue(splitOptions.factor.value);
4965 options.color.load({
4966 value: {
4967 hsl: parent.getFillColor()
4968 }
4969 });
4970 if (typeof options.size.value === "number") {
4971 options.size.value /= factor;
4972 } else {
4973 options.size.value.min /= factor;
4974 options.size.value.max /= factor;
4975 }
4976 options.load(splitOptions.particles);
4977 const offset = splitOptions.sizeOffset ? setRangeValue(-parent.size.value, parent.size.value) : 0;
4978 const position = {
4979 x: parent.position.x + randomInRange(offset),
4980 y: parent.position.y + randomInRange(offset)
4981 };
4982 return this.pushParticle(position, options, parent.group, (particle => {
4983 if (particle.size.value < .5) {
4984 return false;
4985 }
4986 particle.velocity.length = randomInRange(setRangeValue(parent.velocity.length, particle.velocity.length));
4987 particle.splitCount = parent.splitCount + 1;
4988 particle.unbreakable = true;
4989 setTimeout((() => {
4990 particle.unbreakable = false;
4991 }), 500);
4992 return true;
4993 }));
4994 }
4995 removeQuantity(quantity, group) {
4996 this.removeAt(0, quantity, group);
4997 }
4998 getLinkFrequency(p1, p2) {
4999 const key = `${Math.min(p1.id, p2.id)}_${Math.max(p1.id, p2.id)}`;
5000 let res = this.freqs.links.get(key);
5001 if (res === undefined) {
5002 res = Math.random();
5003 this.freqs.links.set(key, res);
5004 }
5005 return res;
5006 }
5007 getTriangleFrequency(p1, p2, p3) {
5008 let [id1, id2, id3] = [ p1.id, p2.id, p3.id ];
5009 if (id1 > id2) {
5010 [id2, id1] = [ id1, id2 ];
5011 }
5012 if (id2 > id3) {
5013 [id3, id2] = [ id2, id3 ];
5014 }
5015 if (id1 > id3) {
5016 [id3, id1] = [ id1, id3 ];
5017 }
5018 const key = `${id1}_${id2}_${id3}`;
5019 let res = this.freqs.triangles.get(key);
5020 if (res === undefined) {
5021 res = Math.random();
5022 this.freqs.triangles.set(key, res);
5023 }
5024 return res;
5025 }
5026 addManualParticles() {
5027 const container = this.container;
5028 const options = container.actualOptions;
5029 for (const particle of options.manualParticles) {
5030 const pos = particle.position ? {
5031 x: particle.position.x * container.canvas.size.width / 100,
5032 y: particle.position.y * container.canvas.size.height / 100
5033 } : undefined;
5034 this.addParticle(pos, particle.options);
5035 }
5036 }
5037 setDensity() {
5038 const options = this.container.actualOptions;
5039 for (const group in options.particles.groups) {
5040 this.applyDensity(options.particles.groups[group], 0, group);
5041 }
5042 this.applyDensity(options.particles, options.manualParticles.length);
5043 }
5044 applyDensity(options, manualCount, group) {
5045 var _a;
5046 if (!((_a = options.number.density) === null || _a === void 0 ? void 0 : _a.enable)) {
5047 return;
5048 }
5049 const numberOptions = options.number;
5050 const densityFactor = this.initDensityFactor(numberOptions.density);
5051 const optParticlesNumber = numberOptions.value;
5052 const optParticlesLimit = numberOptions.limit > 0 ? numberOptions.limit : optParticlesNumber;
5053 const particlesNumber = Math.min(optParticlesNumber, optParticlesLimit) * densityFactor + manualCount;
5054 const particlesCount = Math.min(this.count, this.array.filter((t => t.group === group)).length);
5055 this.limit = numberOptions.limit * densityFactor;
5056 if (particlesCount < particlesNumber) {
5057 this.push(Math.abs(particlesNumber - particlesCount), undefined, options, group);
5058 } else if (particlesCount > particlesNumber) {
5059 this.removeQuantity(particlesCount - particlesNumber, group);
5060 }
5061 }
5062 initDensityFactor(densityOptions) {
5063 const container = this.container;
5064 if (!container.canvas.element || !densityOptions.enable) {
5065 return 1;
5066 }
5067 const canvas = container.canvas.element;
5068 const pxRatio = container.retina.pixelRatio;
5069 return canvas.width * canvas.height / (densityOptions.factor * pxRatio ** 2 * densityOptions.area);
5070 }
5071 pushParticle(position, overrideOptions, group, initializer) {
5072 try {
5073 const particle = new Particle(this.nextId, this.container, position, overrideOptions, group);
5074 let canAdd = true;
5075 if (initializer) {
5076 canAdd = initializer(particle);
5077 }
5078 if (!canAdd) {
5079 return;
5080 }
5081 this.array.push(particle);
5082 this.zArray.push(particle);
5083 this.nextId++;
5084 return particle;
5085 } catch (e) {
5086 console.warn(`error adding particle: ${e}`);
5087 return;
5088 }
5089 }
5090 }
5091 class Retina {
5092 constructor(container) {
5093 this.container = container;
5094 }
5095 init() {
5096 const container = this.container;
5097 const options = container.actualOptions;
5098 this.pixelRatio = !options.detectRetina || isSsr() ? 1 : window.devicePixelRatio;
5099 const motionOptions = this.container.actualOptions.motion;
5100 if (motionOptions && (motionOptions.disable || motionOptions.reduce.value)) {
5101 if (isSsr() || typeof matchMedia === "undefined" || !matchMedia) {
5102 this.reduceFactor = 1;
5103 } else {
5104 const mediaQuery = matchMedia("(prefers-reduced-motion: reduce)");
5105 if (mediaQuery) {
5106 this.handleMotionChange(mediaQuery);
5107 const handleChange = () => {
5108 this.handleMotionChange(mediaQuery);
5109 container.refresh().catch((() => {}));
5110 };
5111 if (mediaQuery.addEventListener !== undefined) {
5112 mediaQuery.addEventListener("change", handleChange);
5113 } else if (mediaQuery.addListener !== undefined) {
5114 mediaQuery.addListener(handleChange);
5115 }
5116 }
5117 }
5118 } else {
5119 this.reduceFactor = 1;
5120 }
5121 const ratio = this.pixelRatio;
5122 if (container.canvas.element) {
5123 const element = container.canvas.element;
5124 container.canvas.size.width = element.offsetWidth * ratio;
5125 container.canvas.size.height = element.offsetHeight * ratio;
5126 }
5127 const particles = options.particles;
5128 this.attractDistance = particles.move.attract.distance * ratio;
5129 this.linksDistance = particles.links.distance * ratio;
5130 this.linksWidth = particles.links.width * ratio;
5131 this.sizeAnimationSpeed = particles.size.animation.speed * ratio;
5132 this.maxSpeed = particles.move.gravity.maxSpeed * ratio;
5133 if (particles.orbit.radius !== undefined) {
5134 this.orbitRadius = particles.orbit.radius * this.container.retina.pixelRatio;
5135 }
5136 const modes = options.interactivity.modes;
5137 this.connectModeDistance = modes.connect.distance * ratio;
5138 this.connectModeRadius = modes.connect.radius * ratio;
5139 this.grabModeDistance = modes.grab.distance * ratio;
5140 this.repulseModeDistance = modes.repulse.distance * ratio;
5141 this.bounceModeDistance = modes.bounce.distance * ratio;
5142 this.attractModeDistance = modes.attract.distance * ratio;
5143 this.slowModeRadius = modes.slow.radius * ratio;
5144 this.bubbleModeDistance = modes.bubble.distance * ratio;
5145 if (modes.bubble.size) {
5146 this.bubbleModeSize = modes.bubble.size * ratio;
5147 }
5148 }
5149 initParticle(particle) {
5150 const options = particle.options;
5151 const ratio = this.pixelRatio;
5152 const moveDistance = options.move.distance;
5153 const props = particle.retina;
5154 props.attractDistance = options.move.attract.distance * ratio;
5155 props.linksDistance = options.links.distance * ratio;
5156 props.linksWidth = options.links.width * ratio;
5157 props.moveDrift = getRangeValue(options.move.drift) * ratio;
5158 props.moveSpeed = getRangeValue(options.move.speed) * ratio;
5159 props.sizeAnimationSpeed = options.size.animation.speed * ratio;
5160 if (particle.spin) {
5161 props.spinAcceleration = getRangeValue(options.move.spin.acceleration) * ratio;
5162 }
5163 const maxDistance = props.maxDistance;
5164 maxDistance.horizontal = moveDistance.horizontal !== undefined ? moveDistance.horizontal * ratio : undefined;
5165 maxDistance.vertical = moveDistance.vertical !== undefined ? moveDistance.vertical * ratio : undefined;
5166 props.maxSpeed = options.move.gravity.maxSpeed * ratio;
5167 }
5168 handleMotionChange(mediaQuery) {
5169 const options = this.container.actualOptions;
5170 if (mediaQuery.matches) {
5171 const motion = options.motion;
5172 this.reduceFactor = motion.disable ? 0 : motion.reduce.value ? 1 / motion.reduce.factor : 1;
5173 } else {
5174 this.reduceFactor = 1;
5175 }
5176 }
5177 }
5178 class FrameManager {
5179 constructor(container) {
5180 this.container = container;
5181 }
5182 nextFrame(timestamp) {
5183 var _a;
5184 try {
5185 const container = this.container;
5186 if (container.lastFrameTime !== undefined && timestamp < container.lastFrameTime + 1e3 / container.fpsLimit) {
5187 container.draw(false);
5188 return;
5189 }
5190 (_a = container.lastFrameTime) !== null && _a !== void 0 ? _a : container.lastFrameTime = timestamp;
5191 const deltaValue = timestamp - container.lastFrameTime;
5192 const delta = {
5193 value: deltaValue,
5194 factor: 60 * deltaValue / 1e3
5195 };
5196 container.lifeTime += delta.value;
5197 container.lastFrameTime = timestamp;
5198 if (deltaValue > 1e3) {
5199 container.draw(false);
5200 return;
5201 }
5202 container.particles.draw(delta);
5203 if (container.duration > 0 && container.lifeTime > container.duration) {
5204 container.destroy();
5205 return;
5206 }
5207 if (container.getAnimationStatus()) {
5208 container.draw(false);
5209 }
5210 } catch (e) {
5211 console.error("tsParticles error in animation loop", e);
5212 }
5213 }
5214 }
5215 class ClickEvent {
5216 constructor() {
5217 this.enable = false;
5218 this.mode = [];
5219 }
5220 load(data) {
5221 if (data === undefined) {
5222 return;
5223 }
5224 if (data.enable !== undefined) {
5225 this.enable = data.enable;
5226 }
5227 if (data.mode !== undefined) {
5228 this.mode = data.mode;
5229 }
5230 }
5231 }
5232 class DivEvent {
5233 constructor() {
5234 this.selectors = [];
5235 this.enable = false;
5236 this.mode = [];
5237 this.type = DivType.circle;
5238 }
5239 get elementId() {
5240 return this.ids;
5241 }
5242 set elementId(value) {
5243 this.ids = value;
5244 }
5245 get el() {
5246 return this.elementId;
5247 }
5248 set el(value) {
5249 this.elementId = value;
5250 }
5251 get ids() {
5252 return this.selectors instanceof Array ? this.selectors.map((t => t.replace("#", ""))) : this.selectors.replace("#", "");
5253 }
5254 set ids(value) {
5255 this.selectors = value instanceof Array ? value.map((t => `#${t}`)) : `#${value}`;
5256 }
5257 load(data) {
5258 var _a, _b;
5259 if (data === undefined) {
5260 return;
5261 }
5262 const ids = (_b = (_a = data.ids) !== null && _a !== void 0 ? _a : data.elementId) !== null && _b !== void 0 ? _b : data.el;
5263 if (ids !== undefined) {
5264 this.ids = ids;
5265 }
5266 if (data.selectors !== undefined) {
5267 this.selectors = data.selectors;
5268 }
5269 if (data.enable !== undefined) {
5270 this.enable = data.enable;
5271 }
5272 if (data.mode !== undefined) {
5273 this.mode = data.mode;
5274 }
5275 if (data.type !== undefined) {
5276 this.type = data.type;
5277 }
5278 }
5279 }
5280 class Parallax {
5281 constructor() {
5282 this.enable = false;
5283 this.force = 2;
5284 this.smooth = 10;
5285 }
5286 load(data) {
5287 if (data === undefined) {
5288 return;
5289 }
5290 if (data.enable !== undefined) {
5291 this.enable = data.enable;
5292 }
5293 if (data.force !== undefined) {
5294 this.force = data.force;
5295 }
5296 if (data.smooth !== undefined) {
5297 this.smooth = data.smooth;
5298 }
5299 }
5300 }
5301 class HoverEvent {
5302 constructor() {
5303 this.enable = false;
5304 this.mode = [];
5305 this.parallax = new Parallax;
5306 }
5307 load(data) {
5308 if (data === undefined) {
5309 return;
5310 }
5311 if (data.enable !== undefined) {
5312 this.enable = data.enable;
5313 }
5314 if (data.mode !== undefined) {
5315 this.mode = data.mode;
5316 }
5317 this.parallax.load(data.parallax);
5318 }
5319 }
5320 class Events {
5321 constructor() {
5322 this.onClick = new ClickEvent;
5323 this.onDiv = new DivEvent;
5324 this.onHover = new HoverEvent;
5325 this.resize = true;
5326 }
5327 get onclick() {
5328 return this.onClick;
5329 }
5330 set onclick(value) {
5331 this.onClick = value;
5332 }
5333 get ondiv() {
5334 return this.onDiv;
5335 }
5336 set ondiv(value) {
5337 this.onDiv = value;
5338 }
5339 get onhover() {
5340 return this.onHover;
5341 }
5342 set onhover(value) {
5343 this.onHover = value;
5344 }
5345 load(data) {
5346 var _a, _b, _c;
5347 if (data === undefined) {
5348 return;
5349 }
5350 this.onClick.load((_a = data.onClick) !== null && _a !== void 0 ? _a : data.onclick);
5351 const onDiv = (_b = data.onDiv) !== null && _b !== void 0 ? _b : data.ondiv;
5352 if (onDiv !== undefined) {
5353 if (onDiv instanceof Array) {
5354 this.onDiv = onDiv.map((div => {
5355 const tmp = new DivEvent;
5356 tmp.load(div);
5357 return tmp;
5358 }));
5359 } else {
5360 this.onDiv = new DivEvent;
5361 this.onDiv.load(onDiv);
5362 }
5363 }
5364 this.onHover.load((_c = data.onHover) !== null && _c !== void 0 ? _c : data.onhover);
5365 if (data.resize !== undefined) {
5366 this.resize = data.resize;
5367 }
5368 }
5369 }
5370 class BubbleBase {
5371 constructor() {
5372 this.distance = 200;
5373 this.duration = .4;
5374 this.mix = false;
5375 }
5376 load(data) {
5377 if (data === undefined) {
5378 return;
5379 }
5380 if (data.distance !== undefined) {
5381 this.distance = data.distance;
5382 }
5383 if (data.duration !== undefined) {
5384 this.duration = data.duration;
5385 }
5386 if (data.mix !== undefined) {
5387 this.mix = data.mix;
5388 }
5389 if (data.opacity !== undefined) {
5390 this.opacity = data.opacity;
5391 }
5392 if (data.color !== undefined) {
5393 if (data.color instanceof Array) {
5394 this.color = data.color.map((s => OptionsColor.create(undefined, s)));
5395 } else {
5396 if (this.color instanceof Array) {
5397 this.color = new OptionsColor;
5398 }
5399 this.color = OptionsColor.create(this.color, data.color);
5400 }
5401 }
5402 if (data.size !== undefined) {
5403 this.size = data.size;
5404 }
5405 }
5406 }
5407 class BubbleDiv extends BubbleBase {
5408 constructor() {
5409 super();
5410 this.selectors = [];
5411 }
5412 get ids() {
5413 return this.selectors instanceof Array ? this.selectors.map((t => t.replace("#", ""))) : this.selectors.replace("#", "");
5414 }
5415 set ids(value) {
5416 this.selectors = value instanceof Array ? value.map((t => `#${t}`)) : `#${value}`;
5417 }
5418 load(data) {
5419 super.load(data);
5420 if (data === undefined) {
5421 return;
5422 }
5423 if (data.ids !== undefined) {
5424 this.ids = data.ids;
5425 }
5426 if (data.selectors !== undefined) {
5427 this.selectors = data.selectors;
5428 }
5429 }
5430 }
5431 class Bubble extends BubbleBase {
5432 load(data) {
5433 super.load(data);
5434 if (!(data !== undefined && data.divs !== undefined)) {
5435 return;
5436 }
5437 if (data.divs instanceof Array) {
5438 this.divs = data.divs.map((s => {
5439 const tmp = new BubbleDiv;
5440 tmp.load(s);
5441 return tmp;
5442 }));
5443 } else {
5444 if (this.divs instanceof Array || !this.divs) {
5445 this.divs = new BubbleDiv;
5446 }
5447 this.divs.load(data.divs);
5448 }
5449 }
5450 }
5451 class ConnectLinks {
5452 constructor() {
5453 this.opacity = .5;
5454 }
5455 load(data) {
5456 if (!(data !== undefined && data.opacity !== undefined)) {
5457 return;
5458 }
5459 this.opacity = data.opacity;
5460 }
5461 }
5462 class Connect {
5463 constructor() {
5464 this.distance = 80;
5465 this.links = new ConnectLinks;
5466 this.radius = 60;
5467 }
5468 get line_linked() {
5469 return this.links;
5470 }
5471 set line_linked(value) {
5472 this.links = value;
5473 }
5474 get lineLinked() {
5475 return this.links;
5476 }
5477 set lineLinked(value) {
5478 this.links = value;
5479 }
5480 load(data) {
5481 var _a, _b;
5482 if (data === undefined) {
5483 return;
5484 }
5485 if (data.distance !== undefined) {
5486 this.distance = data.distance;
5487 }
5488 this.links.load((_b = (_a = data.links) !== null && _a !== void 0 ? _a : data.lineLinked) !== null && _b !== void 0 ? _b : data.line_linked);
5489 if (data.radius !== undefined) {
5490 this.radius = data.radius;
5491 }
5492 }
5493 }
5494 class GrabLinks {
5495 constructor() {
5496 this.blink = false;
5497 this.consent = false;
5498 this.opacity = 1;
5499 }
5500 load(data) {
5501 if (data === undefined) {
5502 return;
5503 }
5504 if (data.blink !== undefined) {
5505 this.blink = data.blink;
5506 }
5507 if (data.color !== undefined) {
5508 this.color = OptionsColor.create(this.color, data.color);
5509 }
5510 if (data.consent !== undefined) {
5511 this.consent = data.consent;
5512 }
5513 if (data.opacity !== undefined) {
5514 this.opacity = data.opacity;
5515 }
5516 }
5517 }
5518 class Grab {
5519 constructor() {
5520 this.distance = 100;
5521 this.links = new GrabLinks;
5522 }
5523 get line_linked() {
5524 return this.links;
5525 }
5526 set line_linked(value) {
5527 this.links = value;
5528 }
5529 get lineLinked() {
5530 return this.links;
5531 }
5532 set lineLinked(value) {
5533 this.links = value;
5534 }
5535 load(data) {
5536 var _a, _b;
5537 if (data === undefined) {
5538 return;
5539 }
5540 if (data.distance !== undefined) {
5541 this.distance = data.distance;
5542 }
5543 this.links.load((_b = (_a = data.links) !== null && _a !== void 0 ? _a : data.lineLinked) !== null && _b !== void 0 ? _b : data.line_linked);
5544 }
5545 }
5546 class Remove {
5547 constructor() {
5548 this.quantity = 2;
5549 }
5550 get particles_nb() {
5551 return this.quantity;
5552 }
5553 set particles_nb(value) {
5554 this.quantity = value;
5555 }
5556 load(data) {
5557 var _a;
5558 if (data === undefined) {
5559 return;
5560 }
5561 const quantity = (_a = data.quantity) !== null && _a !== void 0 ? _a : data.particles_nb;
5562 if (quantity !== undefined) {
5563 this.quantity = quantity;
5564 }
5565 }
5566 }
5567 class Push {
5568 constructor() {
5569 this.default = true;
5570 this.groups = [];
5571 this.quantity = 4;
5572 }
5573 get particles_nb() {
5574 return this.quantity;
5575 }
5576 set particles_nb(value) {
5577 this.quantity = value;
5578 }
5579 load(data) {
5580 var _a;
5581 if (data === undefined) {
5582 return;
5583 }
5584 if (data.default !== undefined) {
5585 this.default = data.default;
5586 }
5587 if (data.groups !== undefined) {
5588 this.groups = data.groups.map((t => t));
5589 }
5590 if (!this.groups.length) {
5591 this.default = true;
5592 }
5593 const quantity = (_a = data.quantity) !== null && _a !== void 0 ? _a : data.particles_nb;
5594 if (quantity !== undefined) {
5595 this.quantity = quantity;
5596 }
5597 }
5598 }
5599 class RepulseBase {
5600 constructor() {
5601 this.distance = 200;
5602 this.duration = .4;
5603 this.factor = 100;
5604 this.speed = 1;
5605 this.maxSpeed = 50;
5606 this.easing = EasingType.easeOutQuad;
5607 }
5608 load(data) {
5609 if (!data) {
5610 return;
5611 }
5612 if (data.distance !== undefined) {
5613 this.distance = data.distance;
5614 }
5615 if (data.duration !== undefined) {
5616 this.duration = data.duration;
5617 }
5618 if (data.easing !== undefined) {
5619 this.easing = data.easing;
5620 }
5621 if (data.factor !== undefined) {
5622 this.factor = data.factor;
5623 }
5624 if (data.speed !== undefined) {
5625 this.speed = data.speed;
5626 }
5627 if (data.maxSpeed !== undefined) {
5628 this.maxSpeed = data.maxSpeed;
5629 }
5630 }
5631 }
5632 class RepulseDiv extends RepulseBase {
5633 constructor() {
5634 super();
5635 this.selectors = [];
5636 }
5637 get ids() {
5638 if (this.selectors instanceof Array) {
5639 return this.selectors.map((t => t.replace("#", "")));
5640 } else {
5641 return this.selectors.replace("#", "");
5642 }
5643 }
5644 set ids(value) {
5645 if (value instanceof Array) {
5646 this.selectors = value.map((() => `#${value}`));
5647 } else {
5648 this.selectors = `#${value}`;
5649 }
5650 }
5651 load(data) {
5652 super.load(data);
5653 if (data === undefined) {
5654 return;
5655 }
5656 if (data.ids !== undefined) {
5657 this.ids = data.ids;
5658 }
5659 if (data.selectors !== undefined) {
5660 this.selectors = data.selectors;
5661 }
5662 }
5663 }
5664 class Repulse_Repulse extends RepulseBase {
5665 load(data) {
5666 super.load(data);
5667 if ((data === null || data === void 0 ? void 0 : data.divs) === undefined) {
5668 return;
5669 }
5670 if (data.divs instanceof Array) {
5671 this.divs = data.divs.map((s => {
5672 const tmp = new RepulseDiv;
5673 tmp.load(s);
5674 return tmp;
5675 }));
5676 } else {
5677 if (this.divs instanceof Array || !this.divs) {
5678 this.divs = new RepulseDiv;
5679 }
5680 this.divs.load(data.divs);
5681 }
5682 }
5683 }
5684 class Slow {
5685 constructor() {
5686 this.factor = 3;
5687 this.radius = 200;
5688 }
5689 get active() {
5690 return false;
5691 }
5692 set active(_value) {}
5693 load(data) {
5694 if (data === undefined) {
5695 return;
5696 }
5697 if (data.factor !== undefined) {
5698 this.factor = data.factor;
5699 }
5700 if (data.radius !== undefined) {
5701 this.radius = data.radius;
5702 }
5703 }
5704 }
5705 class Trail_Trail {
5706 constructor() {
5707 this.delay = 1;
5708 this.pauseOnStop = false;
5709 this.quantity = 1;
5710 }
5711 load(data) {
5712 if (data === undefined) {
5713 return;
5714 }
5715 if (data.delay !== undefined) {
5716 this.delay = data.delay;
5717 }
5718 if (data.quantity !== undefined) {
5719 this.quantity = data.quantity;
5720 }
5721 if (data.particles !== undefined) {
5722 this.particles = deepExtend({}, data.particles);
5723 }
5724 if (data.pauseOnStop !== undefined) {
5725 this.pauseOnStop = data.pauseOnStop;
5726 }
5727 }
5728 }
5729 class Attract_Attract {
5730 constructor() {
5731 this.distance = 200;
5732 this.duration = .4;
5733 this.easing = EasingType.easeOutQuad;
5734 this.factor = 1;
5735 this.maxSpeed = 50;
5736 this.speed = 1;
5737 }
5738 load(data) {
5739 if (!data) {
5740 return;
5741 }
5742 if (data.distance !== undefined) {
5743 this.distance = data.distance;
5744 }
5745 if (data.duration !== undefined) {
5746 this.duration = data.duration;
5747 }
5748 if (data.easing !== undefined) {
5749 this.easing = data.easing;
5750 }
5751 if (data.factor !== undefined) {
5752 this.factor = data.factor;
5753 }
5754 if (data.maxSpeed !== undefined) {
5755 this.maxSpeed = data.maxSpeed;
5756 }
5757 if (data.speed !== undefined) {
5758 this.speed = data.speed;
5759 }
5760 }
5761 }
5762 class LightGradient {
5763 constructor() {
5764 this.start = new OptionsColor;
5765 this.stop = new OptionsColor;
5766 this.start.value = "#ffffff";
5767 this.stop.value = "#000000";
5768 }
5769 load(data) {
5770 if (data === undefined) {
5771 return;
5772 }
5773 this.start = OptionsColor.create(this.start, data.start);
5774 this.stop = OptionsColor.create(this.stop, data.stop);
5775 }
5776 }
5777 class LightArea {
5778 constructor() {
5779 this.gradient = new LightGradient;
5780 this.radius = 1e3;
5781 }
5782 load(data) {
5783 if (data === undefined) {
5784 return;
5785 }
5786 this.gradient.load(data.gradient);
5787 if (data.radius !== undefined) {
5788 this.radius = data.radius;
5789 }
5790 }
5791 }
5792 class LightShadow {
5793 constructor() {
5794 this.color = new OptionsColor;
5795 this.color.value = "#000000";
5796 this.length = 2e3;
5797 }
5798 load(data) {
5799 if (data === undefined) {
5800 return;
5801 }
5802 this.color = OptionsColor.create(this.color, data.color);
5803 if (data.length !== undefined) {
5804 this.length = data.length;
5805 }
5806 }
5807 }
5808 class Light {
5809 constructor() {
5810 this.area = new LightArea;
5811 this.shadow = new LightShadow;
5812 }
5813 load(data) {
5814 if (data === undefined) {
5815 return;
5816 }
5817 this.area.load(data.area);
5818 this.shadow.load(data.shadow);
5819 }
5820 }
5821 class Bounce_Bounce {
5822 constructor() {
5823 this.distance = 200;
5824 }
5825 load(data) {
5826 if (!data) {
5827 return;
5828 }
5829 if (data.distance !== undefined) {
5830 this.distance = data.distance;
5831 }
5832 }
5833 }
5834 class Modes {
5835 constructor() {
5836 this.attract = new Attract_Attract;
5837 this.bounce = new Bounce_Bounce;
5838 this.bubble = new Bubble;
5839 this.connect = new Connect;
5840 this.grab = new Grab;
5841 this.light = new Light;
5842 this.push = new Push;
5843 this.remove = new Remove;
5844 this.repulse = new Repulse_Repulse;
5845 this.slow = new Slow;
5846 this.trail = new Trail_Trail;
5847 }
5848 load(data) {
5849 if (data === undefined) {
5850 return;
5851 }
5852 this.attract.load(data.attract);
5853 this.bubble.load(data.bubble);
5854 this.connect.load(data.connect);
5855 this.grab.load(data.grab);
5856 this.light.load(data.light);
5857 this.push.load(data.push);
5858 this.remove.load(data.remove);
5859 this.repulse.load(data.repulse);
5860 this.slow.load(data.slow);
5861 this.trail.load(data.trail);
5862 }
5863 }
5864 class Interactivity {
5865 constructor() {
5866 this.detectsOn = InteractivityDetect.canvas;
5867 this.events = new Events;
5868 this.modes = new Modes;
5869 }
5870 get detect_on() {
5871 return this.detectsOn;
5872 }
5873 set detect_on(value) {
5874 this.detectsOn = value;
5875 }
5876 load(data) {
5877 var _a, _b, _c;
5878 if (data === undefined) {
5879 return;
5880 }
5881 const detectsOn = (_a = data.detectsOn) !== null && _a !== void 0 ? _a : data.detect_on;
5882 if (detectsOn !== undefined) {
5883 this.detectsOn = detectsOn;
5884 }
5885 this.events.load(data.events);
5886 this.modes.load(data.modes);
5887 if (((_c = (_b = data.modes) === null || _b === void 0 ? void 0 : _b.slow) === null || _c === void 0 ? void 0 : _c.active) === true) {
5888 if (this.events.onHover.mode instanceof Array) {
5889 if (this.events.onHover.mode.indexOf(HoverMode.slow) < 0) {
5890 this.events.onHover.mode.push(HoverMode.slow);
5891 }
5892 } else if (this.events.onHover.mode !== HoverMode.slow) {
5893 this.events.onHover.mode = [ this.events.onHover.mode, HoverMode.slow ];
5894 }
5895 }
5896 }
5897 }
5898 class BackgroundMaskCover {
5899 constructor() {
5900 this.color = new OptionsColor;
5901 this.opacity = 1;
5902 }
5903 load(data) {
5904 if (data === undefined) {
5905 return;
5906 }
5907 if (data.color !== undefined) {
5908 this.color = OptionsColor.create(this.color, data.color);
5909 }
5910 if (data.opacity !== undefined) {
5911 this.opacity = data.opacity;
5912 }
5913 }
5914 }
5915 class BackgroundMask {
5916 constructor() {
5917 this.composite = "destination-out";
5918 this.cover = new BackgroundMaskCover;
5919 this.enable = false;
5920 }
5921 load(data) {
5922 if (data === undefined) {
5923 return;
5924 }
5925 if (data.composite !== undefined) {
5926 this.composite = data.composite;
5927 }
5928 if (data.cover !== undefined) {
5929 const cover = data.cover;
5930 const color = typeof data.cover === "string" ? {
5931 color: data.cover
5932 } : data.cover;
5933 this.cover.load(cover.color !== undefined ? cover : {
5934 color
5935 });
5936 }
5937 if (data.enable !== undefined) {
5938 this.enable = data.enable;
5939 }
5940 }
5941 }
5942 class Background {
5943 constructor() {
5944 this.color = new OptionsColor;
5945 this.color.value = "";
5946 this.image = "";
5947 this.position = "";
5948 this.repeat = "";
5949 this.size = "";
5950 this.opacity = 1;
5951 }
5952 load(data) {
5953 if (data === undefined) {
5954 return;
5955 }
5956 if (data.color !== undefined) {
5957 this.color = OptionsColor.create(this.color, data.color);
5958 }
5959 if (data.image !== undefined) {
5960 this.image = data.image;
5961 }
5962 if (data.position !== undefined) {
5963 this.position = data.position;
5964 }
5965 if (data.repeat !== undefined) {
5966 this.repeat = data.repeat;
5967 }
5968 if (data.size !== undefined) {
5969 this.size = data.size;
5970 }
5971 if (data.opacity !== undefined) {
5972 this.opacity = data.opacity;
5973 }
5974 }
5975 }
5976 class ThemeDefault {
5977 constructor() {
5978 this.auto = false;
5979 this.mode = ThemeMode.any;
5980 this.value = false;
5981 }
5982 load(data) {
5983 if (!data) {
5984 return;
5985 }
5986 if (data.auto !== undefined) {
5987 this.auto = data.auto;
5988 }
5989 if (data.mode !== undefined) {
5990 this.mode = data.mode;
5991 }
5992 if (data.value !== undefined) {
5993 this.value = data.value;
5994 }
5995 }
5996 }
5997 class Theme {
5998 constructor() {
5999 this.name = "";
6000 this.default = new ThemeDefault;
6001 }
6002 load(data) {
6003 if (data === undefined) {
6004 return;
6005 }
6006 if (data.name !== undefined) {
6007 this.name = data.name;
6008 }
6009 this.default.load(data.default);
6010 if (data.options !== undefined) {
6011 this.options = deepExtend({}, data.options);
6012 }
6013 }
6014 }
6015 class FullScreen {
6016 constructor() {
6017 this.enable = false;
6018 this.zIndex = -1;
6019 }
6020 load(data) {
6021 if (!data) {
6022 return;
6023 }
6024 if (data.enable !== undefined) {
6025 this.enable = data.enable;
6026 }
6027 if (data.zIndex !== undefined) {
6028 this.zIndex = data.zIndex;
6029 }
6030 }
6031 }
6032 class MotionReduce {
6033 constructor() {
6034 this.factor = 4;
6035 this.value = true;
6036 }
6037 load(data) {
6038 if (!data) {
6039 return;
6040 }
6041 if (data.factor !== undefined) {
6042 this.factor = data.factor;
6043 }
6044 if (data.value !== undefined) {
6045 this.value = data.value;
6046 }
6047 }
6048 }
6049 class Motion {
6050 constructor() {
6051 this.disable = false;
6052 this.reduce = new MotionReduce;
6053 }
6054 load(data) {
6055 if (!data) {
6056 return;
6057 }
6058 if (data.disable !== undefined) {
6059 this.disable = data.disable;
6060 }
6061 this.reduce.load(data.reduce);
6062 }
6063 }
6064 class ManualParticle {
6065 load(data) {
6066 var _a, _b;
6067 if (!data) {
6068 return;
6069 }
6070 if (data.position !== undefined) {
6071 this.position = {
6072 x: (_a = data.position.x) !== null && _a !== void 0 ? _a : 50,
6073 y: (_b = data.position.y) !== null && _b !== void 0 ? _b : 50
6074 };
6075 }
6076 if (data.options !== undefined) {
6077 this.options = deepExtend({}, data.options);
6078 }
6079 }
6080 }
6081 class Responsive {
6082 constructor() {
6083 this.maxWidth = Infinity;
6084 this.options = {};
6085 }
6086 load(data) {
6087 if (!data) {
6088 return;
6089 }
6090 if (data.maxWidth !== undefined) {
6091 this.maxWidth = data.maxWidth;
6092 }
6093 if (data.options !== undefined) {
6094 this.options = deepExtend({}, data.options);
6095 }
6096 }
6097 }
6098 var __classPrivateFieldGet = undefined && undefined.__classPrivateFieldGet || function(receiver, state, kind, f) {
6099 if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
6100 if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
6101 return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
6102 };
6103 var _Options_instances, _Options_findDefaultTheme;
6104 class Options {
6105 constructor() {
6106 _Options_instances.add(this);
6107 this.autoPlay = true;
6108 this.background = new Background;
6109 this.backgroundMask = new BackgroundMask;
6110 this.fullScreen = new FullScreen;
6111 this.detectRetina = true;
6112 this.duration = 0;
6113 this.fpsLimit = 60;
6114 this.interactivity = new Interactivity;
6115 this.manualParticles = [];
6116 this.motion = new Motion;
6117 this.particles = new ParticlesOptions;
6118 this.pauseOnBlur = true;
6119 this.pauseOnOutsideViewport = true;
6120 this.responsive = [];
6121 this.themes = [];
6122 this.zLayers = 100;
6123 }
6124 get fps_limit() {
6125 return this.fpsLimit;
6126 }
6127 set fps_limit(value) {
6128 this.fpsLimit = value;
6129 }
6130 get retina_detect() {
6131 return this.detectRetina;
6132 }
6133 set retina_detect(value) {
6134 this.detectRetina = value;
6135 }
6136 get backgroundMode() {
6137 return this.fullScreen;
6138 }
6139 set backgroundMode(value) {
6140 this.fullScreen.load(value);
6141 }
6142 load(data) {
6143 var _a, _b, _c, _d, _e;
6144 if (data === undefined) {
6145 return;
6146 }
6147 if (data.preset !== undefined) {
6148 if (data.preset instanceof Array) {
6149 for (const preset of data.preset) {
6150 this.importPreset(preset);
6151 }
6152 } else {
6153 this.importPreset(data.preset);
6154 }
6155 }
6156 if (data.autoPlay !== undefined) {
6157 this.autoPlay = data.autoPlay;
6158 }
6159 const detectRetina = (_a = data.detectRetina) !== null && _a !== void 0 ? _a : data.retina_detect;
6160 if (detectRetina !== undefined) {
6161 this.detectRetina = detectRetina;
6162 }
6163 if (data.duration !== undefined) {
6164 this.duration = data.duration;
6165 }
6166 const fpsLimit = (_b = data.fpsLimit) !== null && _b !== void 0 ? _b : data.fps_limit;
6167 if (fpsLimit !== undefined) {
6168 this.fpsLimit = fpsLimit;
6169 }
6170 if (data.pauseOnBlur !== undefined) {
6171 this.pauseOnBlur = data.pauseOnBlur;
6172 }
6173 if (data.pauseOnOutsideViewport !== undefined) {
6174 this.pauseOnOutsideViewport = data.pauseOnOutsideViewport;
6175 }
6176 if (data.zLayers !== undefined) {
6177 this.zLayers = data.zLayers;
6178 }
6179 this.background.load(data.background);
6180 const fullScreen = (_c = data.fullScreen) !== null && _c !== void 0 ? _c : data.backgroundMode;
6181 if (typeof fullScreen === "boolean") {
6182 this.fullScreen.enable = fullScreen;
6183 } else {
6184 this.fullScreen.load(fullScreen);
6185 }
6186 this.backgroundMask.load(data.backgroundMask);
6187 this.interactivity.load(data.interactivity);
6188 if (data.manualParticles !== undefined) {
6189 this.manualParticles = data.manualParticles.map((t => {
6190 const tmp = new ManualParticle;
6191 tmp.load(t);
6192 return tmp;
6193 }));
6194 }
6195 this.motion.load(data.motion);
6196 this.particles.load(data.particles);
6197 Plugins.loadOptions(this, data);
6198 if (data.responsive !== undefined) {
6199 for (const responsive of data.responsive) {
6200 const optResponsive = new Responsive;
6201 optResponsive.load(responsive);
6202 this.responsive.push(optResponsive);
6203 }
6204 }
6205 this.responsive.sort(((a, b) => a.maxWidth - b.maxWidth));
6206 if (data.themes !== undefined) {
6207 for (const theme of data.themes) {
6208 const optTheme = new Theme;
6209 optTheme.load(theme);
6210 this.themes.push(optTheme);
6211 }
6212 }
6213 this.defaultDarkTheme = (_d = __classPrivateFieldGet(this, _Options_instances, "m", _Options_findDefaultTheme).call(this, ThemeMode.dark)) === null || _d === void 0 ? void 0 : _d.name;
6214 this.defaultLightTheme = (_e = __classPrivateFieldGet(this, _Options_instances, "m", _Options_findDefaultTheme).call(this, ThemeMode.light)) === null || _e === void 0 ? void 0 : _e.name;
6215 }
6216 setTheme(name) {
6217 if (name) {
6218 const chosenTheme = this.themes.find((theme => theme.name === name));
6219 if (chosenTheme) {
6220 this.load(chosenTheme.options);
6221 }
6222 } else {
6223 const mediaMatch = typeof matchMedia !== "undefined" && matchMedia("(prefers-color-scheme: dark)"), clientDarkMode = mediaMatch && mediaMatch.matches, defaultTheme = __classPrivateFieldGet(this, _Options_instances, "m", _Options_findDefaultTheme).call(this, clientDarkMode ? ThemeMode.dark : ThemeMode.light);
6224 if (defaultTheme) {
6225 this.load(defaultTheme.options);
6226 }
6227 }
6228 }
6229 setResponsive(width, pxRatio, defaultOptions) {
6230 this.load(defaultOptions);
6231 const responsiveOptions = this.responsive.find((t => t.maxWidth * pxRatio > width));
6232 this.load(responsiveOptions === null || responsiveOptions === void 0 ? void 0 : responsiveOptions.options);
6233 return responsiveOptions === null || responsiveOptions === void 0 ? void 0 : responsiveOptions.maxWidth;
6234 }
6235 importPreset(preset) {
6236 this.load(Plugins.getPreset(preset));
6237 }
6238 }
6239 _Options_instances = new WeakSet, _Options_findDefaultTheme = function _Options_findDefaultTheme(mode) {
6240 var _a;
6241 return (_a = this.themes.find((theme => theme.default.value && theme.default.mode === mode))) !== null && _a !== void 0 ? _a : this.themes.find((theme => theme.default.value && theme.default.mode === ThemeMode.any));
6242 };
6243 class Container {
6244 constructor(id, sourceOptions, ...presets) {
6245 this.id = id;
6246 this.fpsLimit = 60;
6247 this.duration = 0;
6248 this.lifeTime = 0;
6249 this.firstStart = true;
6250 this.started = false;
6251 this.destroyed = false;
6252 this.paused = true;
6253 this.lastFrameTime = 0;
6254 this.zLayers = 100;
6255 this.pageHidden = false;
6256 this._sourceOptions = sourceOptions;
6257 this.retina = new Retina(this);
6258 this.canvas = new Canvas(this);
6259 this.particles = new Particles(this);
6260 this.drawer = new FrameManager(this);
6261 this.pathGenerator = {
6262 generate: () => {
6263 const v = Vector.create(0, 0);
6264 v.length = Math.random();
6265 v.angle = Math.random() * Math.PI * 2;
6266 return v;
6267 },
6268 init: () => {},
6269 update: () => {}
6270 };
6271 this.interactivity = {
6272 mouse: {
6273 clicking: false,
6274 inside: false
6275 }
6276 };
6277 this.bubble = {};
6278 this.repulse = {
6279 particles: []
6280 };
6281 this.attract = {
6282 particles: []
6283 };
6284 this.plugins = new Map;
6285 this.drawers = new Map;
6286 this.density = 1;
6287 this._options = new Options;
6288 this.actualOptions = new Options;
6289 for (const preset of presets) {
6290 this._options.load(Plugins.getPreset(preset));
6291 }
6292 const shapes = Plugins.getSupportedShapes();
6293 for (const type of shapes) {
6294 const drawer = Plugins.getShapeDrawer(type);
6295 if (drawer) {
6296 this.drawers.set(type, drawer);
6297 }
6298 }
6299 this._options.load(this._sourceOptions);
6300 this.eventListeners = new EventListeners(this);
6301 if (typeof IntersectionObserver !== "undefined" && IntersectionObserver) {
6302 this.intersectionObserver = new IntersectionObserver((entries => this.intersectionManager(entries)));
6303 }
6304 }
6305 get options() {
6306 return this._options;
6307 }
6308 get sourceOptions() {
6309 return this._sourceOptions;
6310 }
6311 play(force) {
6312 const needsUpdate = this.paused || force;
6313 if (this.firstStart && !this.actualOptions.autoPlay) {
6314 this.firstStart = false;
6315 return;
6316 }
6317 if (this.paused) {
6318 this.paused = false;
6319 }
6320 if (needsUpdate) {
6321 for (const [, plugin] of this.plugins) {
6322 if (plugin.play) {
6323 plugin.play();
6324 }
6325 }
6326 }
6327 this.draw(needsUpdate || false);
6328 }
6329 pause() {
6330 if (this.drawAnimationFrame !== undefined) {
6331 cancelAnimation()(this.drawAnimationFrame);
6332 delete this.drawAnimationFrame;
6333 }
6334 if (this.paused) {
6335 return;
6336 }
6337 for (const [, plugin] of this.plugins) {
6338 if (plugin.pause) {
6339 plugin.pause();
6340 }
6341 }
6342 if (!this.pageHidden) {
6343 this.paused = true;
6344 }
6345 }
6346 draw(force) {
6347 let refreshTime = force;
6348 this.drawAnimationFrame = animate()((timestamp => {
6349 if (refreshTime) {
6350 this.lastFrameTime = undefined;
6351 refreshTime = false;
6352 }
6353 this.drawer.nextFrame(timestamp);
6354 }));
6355 }
6356 getAnimationStatus() {
6357 return !this.paused && !this.pageHidden;
6358 }
6359 setNoise(noiseOrGenerator, init, update) {
6360 this.setPath(noiseOrGenerator, init, update);
6361 }
6362 setPath(pathOrGenerator, init, update) {
6363 if (!pathOrGenerator) {
6364 return;
6365 }
6366 if (typeof pathOrGenerator === "function") {
6367 this.pathGenerator.generate = pathOrGenerator;
6368 if (init) {
6369 this.pathGenerator.init = init;
6370 }
6371 if (update) {
6372 this.pathGenerator.update = update;
6373 }
6374 } else {
6375 if (pathOrGenerator.generate) {
6376 this.pathGenerator.generate = pathOrGenerator.generate;
6377 }
6378 if (pathOrGenerator.init) {
6379 this.pathGenerator.init = pathOrGenerator.init;
6380 }
6381 if (pathOrGenerator.update) {
6382 this.pathGenerator.update = pathOrGenerator.update;
6383 }
6384 }
6385 }
6386 destroy() {
6387 this.stop();
6388 this.canvas.destroy();
6389 for (const [, drawer] of this.drawers) {
6390 if (drawer.destroy) {
6391 drawer.destroy(this);
6392 }
6393 }
6394 for (const key of this.drawers.keys()) {
6395 this.drawers.delete(key);
6396 }
6397 this.destroyed = true;
6398 }
6399 exportImg(callback) {
6400 this.exportImage(callback);
6401 }
6402 exportImage(callback, type, quality) {
6403 var _a;
6404 return (_a = this.canvas.element) === null || _a === void 0 ? void 0 : _a.toBlob(callback, type !== null && type !== void 0 ? type : "image/png", quality);
6405 }
6406 exportConfiguration() {
6407 return JSON.stringify(this.actualOptions, undefined, 2);
6408 }
6409 refresh() {
6410 this.stop();
6411 return this.start();
6412 }
6413 reset() {
6414 this._options = new Options;
6415 return this.refresh();
6416 }
6417 stop() {
6418 if (!this.started) {
6419 return;
6420 }
6421 this.firstStart = true;
6422 this.started = false;
6423 this.eventListeners.removeListeners();
6424 this.pause();
6425 this.particles.clear();
6426 this.canvas.clear();
6427 if (this.interactivity.element instanceof HTMLElement && this.intersectionObserver) {
6428 this.intersectionObserver.observe(this.interactivity.element);
6429 }
6430 for (const [, plugin] of this.plugins) {
6431 if (plugin.stop) {
6432 plugin.stop();
6433 }
6434 }
6435 for (const key of this.plugins.keys()) {
6436 this.plugins.delete(key);
6437 }
6438 this.particles.linksColors = new Map;
6439 delete this.particles.grabLineColor;
6440 delete this.particles.linksColor;
6441 }
6442 async loadTheme(name) {
6443 this.currentTheme = name;
6444 await this.refresh();
6445 }
6446 async start() {
6447 if (this.started) {
6448 return;
6449 }
6450 await this.init();
6451 this.started = true;
6452 this.eventListeners.addListeners();
6453 if (this.interactivity.element instanceof HTMLElement && this.intersectionObserver) {
6454 this.intersectionObserver.observe(this.interactivity.element);
6455 }
6456 for (const [, plugin] of this.plugins) {
6457 if (plugin.startAsync !== undefined) {
6458 await plugin.startAsync();
6459 } else if (plugin.start !== undefined) {
6460 plugin.start();
6461 }
6462 }
6463 this.play();
6464 }
6465 addClickHandler(callback) {
6466 const el = this.interactivity.element;
6467 if (!el) {
6468 return;
6469 }
6470 const clickOrTouchHandler = (e, pos, radius) => {
6471 if (this.destroyed) {
6472 return;
6473 }
6474 const pxRatio = this.retina.pixelRatio, posRetina = {
6475 x: pos.x * pxRatio,
6476 y: pos.y * pxRatio
6477 }, particles = this.particles.quadTree.queryCircle(posRetina, radius * pxRatio);
6478 callback(e, particles);
6479 };
6480 const clickHandler = e => {
6481 if (this.destroyed) {
6482 return;
6483 }
6484 const mouseEvent = e;
6485 const pos = {
6486 x: mouseEvent.offsetX || mouseEvent.clientX,
6487 y: mouseEvent.offsetY || mouseEvent.clientY
6488 };
6489 clickOrTouchHandler(e, pos, 1);
6490 };
6491 const touchStartHandler = () => {
6492 if (this.destroyed) {
6493 return;
6494 }
6495 touched = true;
6496 touchMoved = false;
6497 };
6498 const touchMoveHandler = () => {
6499 if (this.destroyed) {
6500 return;
6501 }
6502 touchMoved = true;
6503 };
6504 const touchEndHandler = e => {
6505 var _a, _b, _c;
6506 if (this.destroyed) {
6507 return;
6508 }
6509 if (touched && !touchMoved) {
6510 const touchEvent = e;
6511 let lastTouch = touchEvent.touches[touchEvent.touches.length - 1];
6512 if (!lastTouch) {
6513 lastTouch = touchEvent.changedTouches[touchEvent.changedTouches.length - 1];
6514 if (!lastTouch) {
6515 return;
6516 }
6517 }
6518 const canvasRect = (_a = this.canvas.element) === null || _a === void 0 ? void 0 : _a.getBoundingClientRect();
6519 const pos = {
6520 x: lastTouch.clientX - ((_b = canvasRect === null || canvasRect === void 0 ? void 0 : canvasRect.left) !== null && _b !== void 0 ? _b : 0),
6521 y: lastTouch.clientY - ((_c = canvasRect === null || canvasRect === void 0 ? void 0 : canvasRect.top) !== null && _c !== void 0 ? _c : 0)
6522 };
6523 clickOrTouchHandler(e, pos, Math.max(lastTouch.radiusX, lastTouch.radiusY));
6524 }
6525 touched = false;
6526 touchMoved = false;
6527 };
6528 const touchCancelHandler = () => {
6529 if (this.destroyed) {
6530 return;
6531 }
6532 touched = false;
6533 touchMoved = false;
6534 };
6535 let touched = false;
6536 let touchMoved = false;
6537 el.addEventListener("click", clickHandler);
6538 el.addEventListener("touchstart", touchStartHandler);
6539 el.addEventListener("touchmove", touchMoveHandler);
6540 el.addEventListener("touchend", touchEndHandler);
6541 el.addEventListener("touchcancel", touchCancelHandler);
6542 }
6543 updateActualOptions() {
6544 this.actualOptions.responsive = [];
6545 const newMaxWidth = this.actualOptions.setResponsive(this.canvas.size.width, this.retina.pixelRatio, this._options);
6546 this.actualOptions.setTheme(this.currentTheme);
6547 if (this.responsiveMaxWidth != newMaxWidth) {
6548 this.responsiveMaxWidth = newMaxWidth;
6549 return true;
6550 }
6551 return false;
6552 }
6553 async init() {
6554 this.actualOptions = new Options;
6555 this.actualOptions.load(this._options);
6556 this.retina.init();
6557 this.canvas.init();
6558 this.updateActualOptions();
6559 this.canvas.initBackground();
6560 this.canvas.resize();
6561 this.zLayers = this.actualOptions.zLayers;
6562 this.duration = getRangeValue(this.actualOptions.duration);
6563 this.lifeTime = 0;
6564 this.fpsLimit = this.actualOptions.fpsLimit > 0 ? this.actualOptions.fpsLimit : 60;
6565 const availablePlugins = Plugins.getAvailablePlugins(this);
6566 for (const [id, plugin] of availablePlugins) {
6567 this.plugins.set(id, plugin);
6568 }
6569 for (const [, drawer] of this.drawers) {
6570 if (drawer.init) {
6571 await drawer.init(this);
6572 }
6573 }
6574 for (const [, plugin] of this.plugins) {
6575 if (plugin.init) {
6576 plugin.init(this.actualOptions);
6577 } else if (plugin.initAsync !== undefined) {
6578 await plugin.initAsync(this.actualOptions);
6579 }
6580 }
6581 const pathOptions = this.actualOptions.particles.move.path;
6582 if (pathOptions.generator) {
6583 const customGenerator = Plugins.getPathGenerator(pathOptions.generator);
6584 if (customGenerator) {
6585 if (customGenerator.init) {
6586 this.pathGenerator.init = customGenerator.init;
6587 }
6588 if (customGenerator.generate) {
6589 this.pathGenerator.generate = customGenerator.generate;
6590 }
6591 if (customGenerator.update) {
6592 this.pathGenerator.update = customGenerator.update;
6593 }
6594 }
6595 }
6596 this.particles.init();
6597 this.particles.setDensity();
6598 for (const [, plugin] of this.plugins) {
6599 if (plugin.particlesSetup !== undefined) {
6600 plugin.particlesSetup();
6601 }
6602 }
6603 }
6604 intersectionManager(entries) {
6605 if (!this.actualOptions.pauseOnOutsideViewport) {
6606 return;
6607 }
6608 for (const entry of entries) {
6609 if (entry.target !== this.interactivity.element) {
6610 continue;
6611 }
6612 if (entry.isIntersecting) {
6613 this.play();
6614 } else {
6615 this.pause();
6616 }
6617 }
6618 }
6619 }
6620 const tsParticlesDom = [];
6621 function fetchError(statusCode) {
6622 console.error(`Error tsParticles - fetch status: ${statusCode}`);
6623 console.error("Error tsParticles - File config not found");
6624 }
6625 class Loader {
6626 static dom() {
6627 return tsParticlesDom;
6628 }
6629 static domItem(index) {
6630 const dom = Loader.dom();
6631 const item = dom[index];
6632 if (item && !item.destroyed) {
6633 return item;
6634 }
6635 dom.splice(index, 1);
6636 }
6637 static async loadOptions(params) {
6638 var _a, _b, _c;
6639 const tagId = (_a = params.tagId) !== null && _a !== void 0 ? _a : `tsparticles${Math.floor(Math.random() * 1e4)}`;
6640 const {options, index} = params;
6641 let domContainer = (_b = params.element) !== null && _b !== void 0 ? _b : document.getElementById(tagId);
6642 if (!domContainer) {
6643 domContainer = document.createElement("div");
6644 domContainer.id = tagId;
6645 (_c = document.querySelector("body")) === null || _c === void 0 ? void 0 : _c.append(domContainer);
6646 }
6647 const currentOptions = options instanceof Array ? itemFromArray(options, index) : options;
6648 const dom = Loader.dom();
6649 const oldIndex = dom.findIndex((v => v.id === tagId));
6650 if (oldIndex >= 0) {
6651 const old = Loader.domItem(oldIndex);
6652 if (old && !old.destroyed) {
6653 old.destroy();
6654 dom.splice(oldIndex, 1);
6655 }
6656 }
6657 let canvasEl;
6658 let generatedCanvas;
6659 if (domContainer.tagName.toLowerCase() === "canvas") {
6660 canvasEl = domContainer;
6661 generatedCanvas = false;
6662 } else {
6663 const existingCanvases = domContainer.getElementsByTagName("canvas");
6664 if (existingCanvases.length) {
6665 canvasEl = existingCanvases[0];
6666 if (!canvasEl.className) {
6667 canvasEl.className = Constants.canvasClass;
6668 }
6669 generatedCanvas = false;
6670 } else {
6671 generatedCanvas = true;
6672 canvasEl = document.createElement("canvas");
6673 canvasEl.className = Constants.canvasClass;
6674 canvasEl.style.width = "100%";
6675 canvasEl.style.height = "100%";
6676 domContainer.appendChild(canvasEl);
6677 }
6678 }
6679 const newItem = new Container(tagId, currentOptions);
6680 if (oldIndex >= 0) {
6681 dom.splice(oldIndex, 0, newItem);
6682 } else {
6683 dom.push(newItem);
6684 }
6685 newItem.canvas.loadCanvas(canvasEl, generatedCanvas);
6686 await newItem.start();
6687 return newItem;
6688 }
6689 static async loadRemoteOptions(params) {
6690 const {url: jsonUrl, index} = params;
6691 const url = jsonUrl instanceof Array ? itemFromArray(jsonUrl, index) : jsonUrl;
6692 if (!url) {
6693 return;
6694 }
6695 const response = await fetch(url);
6696 if (!response.ok) {
6697 fetchError(response.status);
6698 return;
6699 }
6700 const data = await response.json();
6701 return await Loader.loadOptions({
6702 tagId: params.tagId,
6703 element: params.element,
6704 index,
6705 options: data
6706 });
6707 }
6708 static load(tagId, options, index) {
6709 const params = {
6710 index
6711 };
6712 if (typeof tagId === "string") {
6713 params.tagId = tagId;
6714 } else {
6715 params.options = tagId;
6716 }
6717 if (typeof options === "number") {
6718 params.index = options !== null && options !== void 0 ? options : params.index;
6719 } else {
6720 params.options = options !== null && options !== void 0 ? options : params.options;
6721 }
6722 return this.loadOptions(params);
6723 }
6724 static async set(id, domContainer, options, index) {
6725 const params = {
6726 index
6727 };
6728 if (typeof id === "string") {
6729 params.tagId = id;
6730 } else {
6731 params.element = id;
6732 }
6733 if (domContainer instanceof HTMLElement) {
6734 params.element = domContainer;
6735 } else {
6736 params.options = domContainer;
6737 }
6738 if (typeof options === "number") {
6739 params.index = options;
6740 } else {
6741 params.options = options !== null && options !== void 0 ? options : params.options;
6742 }
6743 return this.loadOptions(params);
6744 }
6745 static async loadJSON(tagId, jsonUrl, index) {
6746 let url, id;
6747 if (typeof jsonUrl === "number" || jsonUrl === undefined) {
6748 url = tagId;
6749 } else {
6750 id = tagId;
6751 url = jsonUrl;
6752 }
6753 return await Loader.loadRemoteOptions({
6754 tagId: id,
6755 url,
6756 index
6757 });
6758 }
6759 static async setJSON(id, domContainer, jsonUrl, index) {
6760 let url, newId, newIndex, element;
6761 if (id instanceof HTMLElement) {
6762 element = id;
6763 url = domContainer;
6764 newIndex = jsonUrl;
6765 } else {
6766 newId = id;
6767 element = domContainer;
6768 url = jsonUrl;
6769 newIndex = index;
6770 }
6771 return await Loader.loadRemoteOptions({
6772 tagId: newId,
6773 url,
6774 index: newIndex,
6775 element
6776 });
6777 }
6778 static setOnClickHandler(callback) {
6779 const dom = Loader.dom();
6780 if (dom.length === 0) {
6781 throw new Error("Can only set click handlers after calling tsParticles.load() or tsParticles.loadJSON()");
6782 }
6783 for (const domItem of dom) {
6784 domItem.addClickHandler(callback);
6785 }
6786 }
6787 }
6788 var __classPrivateFieldSet = undefined && undefined.__classPrivateFieldSet || function(receiver, state, value, kind, f) {
6789 if (kind === "m") throw new TypeError("Private method is not writable");
6790 if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
6791 if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
6792 return kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value),
6793 value;
6794 };
6795 var main_classPrivateFieldGet = undefined && undefined.__classPrivateFieldGet || function(receiver, state, kind, f) {
6796 if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
6797 if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
6798 return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
6799 };
6800 var _Main_initialized;
6801 class Main {
6802 constructor() {
6803 _Main_initialized.set(this, void 0);
6804 __classPrivateFieldSet(this, _Main_initialized, false, "f");
6805 }
6806 init() {
6807 if (!main_classPrivateFieldGet(this, _Main_initialized, "f")) {
6808 __classPrivateFieldSet(this, _Main_initialized, true, "f");
6809 }
6810 }
6811 async loadFromArray(tagId, options, index) {
6812 return Loader.load(tagId, options, index);
6813 }
6814 async load(tagId, options) {
6815 return Loader.load(tagId, options);
6816 }
6817 async set(id, element, options) {
6818 return Loader.set(id, element, options);
6819 }
6820 async loadJSON(tagId, pathConfigJson, index) {
6821 return Loader.loadJSON(tagId, pathConfigJson, index);
6822 }
6823 async setJSON(id, element, pathConfigJson, index) {
6824 return Loader.setJSON(id, element, pathConfigJson, index);
6825 }
6826 setOnClickHandler(callback) {
6827 Loader.setOnClickHandler(callback);
6828 }
6829 dom() {
6830 return Loader.dom();
6831 }
6832 domItem(index) {
6833 return Loader.domItem(index);
6834 }
6835 addShape(shape, drawer, init, afterEffect, destroy) {
6836 let customDrawer;
6837 if (typeof drawer === "function") {
6838 customDrawer = {
6839 afterEffect,
6840 destroy,
6841 draw: drawer,
6842 init
6843 };
6844 } else {
6845 customDrawer = drawer;
6846 }
6847 Plugins.addShapeDrawer(shape, customDrawer);
6848 }
6849 addPreset(preset, options, override = false) {
6850 Plugins.addPreset(preset, options, override);
6851 }
6852 addPlugin(plugin) {
6853 Plugins.addPlugin(plugin);
6854 }
6855 addPathGenerator(name, generator) {
6856 Plugins.addPathGenerator(name, generator);
6857 }
6858 addInteractor(name, interactorInitializer) {
6859 Plugins.addInteractor(name, interactorInitializer);
6860 }
6861 addParticleUpdater(name, updaterInitializer) {
6862 Plugins.addParticleUpdater(name, updaterInitializer);
6863 }
6864 }
6865 _Main_initialized = new WeakMap;
6866 class CircleDrawer {
6867 getSidesCount() {
6868 return 12;
6869 }
6870 draw(context, particle, radius) {
6871 context.arc(0, 0, radius, 0, Math.PI * 2, false);
6872 }
6873 }
6874 function loadCircleShape(tsParticles) {
6875 tsParticles.addShape("circle", new CircleDrawer);
6876 }
6877 class LifeUpdater {
6878 constructor(container) {
6879 this.container = container;
6880 }
6881 init() {}
6882 isEnabled(particle) {
6883 return !particle.destroyed;
6884 }
6885 update(particle, delta) {
6886 if (!this.isEnabled(particle)) {
6887 return;
6888 }
6889 const life = particle.life;
6890 let justSpawned = false;
6891 if (particle.spawning) {
6892 life.delayTime += delta.value;
6893 if (life.delayTime >= particle.life.delay) {
6894 justSpawned = true;
6895 particle.spawning = false;
6896 life.delayTime = 0;
6897 life.time = 0;
6898 } else {
6899 return;
6900 }
6901 }
6902 if (life.duration === -1) {
6903 return;
6904 }
6905 if (particle.spawning) {
6906 return;
6907 }
6908 if (justSpawned) {
6909 life.time = 0;
6910 } else {
6911 life.time += delta.value;
6912 }
6913 if (life.time < life.duration) {
6914 return;
6915 }
6916 life.time = 0;
6917 if (particle.life.count > 0) {
6918 particle.life.count--;
6919 }
6920 if (particle.life.count === 0) {
6921 particle.destroy();
6922 return;
6923 }
6924 const canvasSize = this.container.canvas.size, widthRange = setRangeValue(0, canvasSize.width), heightRange = setRangeValue(0, canvasSize.width);
6925 particle.position.x = randomInRange(widthRange);
6926 particle.position.y = randomInRange(heightRange);
6927 particle.spawning = true;
6928 life.delayTime = 0;
6929 life.time = 0;
6930 particle.reset();
6931 const lifeOptions = particle.options.life;
6932 life.delay = getRangeValue(lifeOptions.delay.value) * 1e3;
6933 life.duration = getRangeValue(lifeOptions.duration.value) * 1e3;
6934 }
6935 }
6936 function loadLifeUpdater(tsParticles) {
6937 tsParticles.addParticleUpdater("life", (container => new LifeUpdater(container)));
6938 }
6939 class ExternalInteractorBase {
6940 constructor(container) {
6941 this.container = container;
6942 this.type = InteractorType.External;
6943 }
6944 }
6945 class Connector extends ExternalInteractorBase {
6946 constructor(container) {
6947 super(container);
6948 }
6949 isEnabled() {
6950 const container = this.container, mouse = container.interactivity.mouse, events = container.actualOptions.interactivity.events;
6951 if (!(events.onHover.enable && mouse.position)) {
6952 return false;
6953 }
6954 return isInArray(HoverMode.connect, events.onHover.mode);
6955 }
6956 reset() {}
6957 interact() {
6958 const container = this.container, options = container.actualOptions;
6959 if (options.interactivity.events.onHover.enable && container.interactivity.status === "mousemove") {
6960 const mousePos = container.interactivity.mouse.position;
6961 if (!mousePos) {
6962 return;
6963 }
6964 const distance = Math.abs(container.retina.connectModeRadius), query = container.particles.quadTree.queryCircle(mousePos, distance);
6965 let i = 0;
6966 for (const p1 of query) {
6967 const pos1 = p1.getPosition();
6968 for (const p2 of query.slice(i + 1)) {
6969 const pos2 = p2.getPosition(), distMax = Math.abs(container.retina.connectModeDistance), xDiff = Math.abs(pos1.x - pos2.x), yDiff = Math.abs(pos1.y - pos2.y);
6970 if (xDiff < distMax && yDiff < distMax) {
6971 container.canvas.drawConnectLine(p1, p2);
6972 }
6973 }
6974 ++i;
6975 }
6976 }
6977 }
6978 }
6979 function loadExternalConnectInteraction(tsParticles) {
6980 tsParticles.addInteractor("externalConnect", (container => new Connector(container)));
6981 }
6982 function checkDestroy(particle, value, minValue, maxValue) {
6983 switch (particle.options.opacity.animation.destroy) {
6984 case DestroyType.max:
6985 if (value >= maxValue) {
6986 particle.destroy();
6987 }
6988 break;
6989
6990 case DestroyType.min:
6991 if (value <= minValue) {
6992 particle.destroy();
6993 }
6994 break;
6995 }
6996 }
6997 function updateOpacity(particle, delta) {
6998 var _a, _b, _c, _d, _e;
6999 if (!particle.opacity) {
7000 return;
7001 }
7002 const minValue = particle.opacity.min;
7003 const maxValue = particle.opacity.max;
7004 if (!(!particle.destroyed && particle.opacity.enable && (((_a = particle.opacity.maxLoops) !== null && _a !== void 0 ? _a : 0) <= 0 || ((_b = particle.opacity.loops) !== null && _b !== void 0 ? _b : 0) < ((_c = particle.opacity.maxLoops) !== null && _c !== void 0 ? _c : 0)))) {
7005 return;
7006 }
7007 switch (particle.opacity.status) {
7008 case AnimationStatus.increasing:
7009 if (particle.opacity.value >= maxValue) {
7010 particle.opacity.status = AnimationStatus.decreasing;
7011 if (!particle.opacity.loops) {
7012 particle.opacity.loops = 0;
7013 }
7014 particle.opacity.loops++;
7015 } else {
7016 particle.opacity.value += ((_d = particle.opacity.velocity) !== null && _d !== void 0 ? _d : 0) * delta.factor;
7017 }
7018 break;
7019
7020 case AnimationStatus.decreasing:
7021 if (particle.opacity.value <= minValue) {
7022 particle.opacity.status = AnimationStatus.increasing;
7023 if (!particle.opacity.loops) {
7024 particle.opacity.loops = 0;
7025 }
7026 particle.opacity.loops++;
7027 } else {
7028 particle.opacity.value -= ((_e = particle.opacity.velocity) !== null && _e !== void 0 ? _e : 0) * delta.factor;
7029 }
7030 break;
7031 }
7032 checkDestroy(particle, particle.opacity.value, minValue, maxValue);
7033 if (!particle.destroyed) {
7034 particle.opacity.value = clamp(particle.opacity.value, minValue, maxValue);
7035 }
7036 }
7037 class OpacityUpdater {
7038 constructor(container) {
7039 this.container = container;
7040 }
7041 init(particle) {
7042 const opacityOptions = particle.options.opacity;
7043 particle.opacity = {
7044 enable: opacityOptions.animation.enable,
7045 max: getRangeMax(opacityOptions.value),
7046 min: getRangeMin(opacityOptions.value),
7047 value: getRangeValue(opacityOptions.value),
7048 loops: 0,
7049 maxLoops: opacityOptions.animation.count
7050 };
7051 const opacityAnimation = opacityOptions.animation;
7052 if (opacityAnimation.enable) {
7053 particle.opacity.status = AnimationStatus.increasing;
7054 const opacityRange = opacityOptions.value;
7055 particle.opacity.min = getRangeMin(opacityRange);
7056 particle.opacity.max = getRangeMax(opacityRange);
7057 switch (opacityAnimation.startValue) {
7058 case StartValueType.min:
7059 particle.opacity.value = particle.opacity.min;
7060 particle.opacity.status = AnimationStatus.increasing;
7061 break;
7062
7063 case StartValueType.random:
7064 particle.opacity.value = randomInRange(particle.opacity);
7065 particle.opacity.status = Math.random() >= .5 ? AnimationStatus.increasing : AnimationStatus.decreasing;
7066 break;
7067
7068 case StartValueType.max:
7069 default:
7070 particle.opacity.value = particle.opacity.max;
7071 particle.opacity.status = AnimationStatus.decreasing;
7072 break;
7073 }
7074 particle.opacity.velocity = opacityAnimation.speed / 100 * this.container.retina.reduceFactor;
7075 if (!opacityAnimation.sync) {
7076 particle.opacity.velocity *= Math.random();
7077 }
7078 }
7079 }
7080 isEnabled(particle) {
7081 var _a, _b, _c;
7082 return !particle.destroyed && !particle.spawning && !!particle.opacity && particle.opacity.enable && (((_a = particle.opacity.maxLoops) !== null && _a !== void 0 ? _a : 0) <= 0 || ((_b = particle.opacity.loops) !== null && _b !== void 0 ? _b : 0) < ((_c = particle.opacity.maxLoops) !== null && _c !== void 0 ? _c : 0));
7083 }
7084 update(particle, delta) {
7085 if (!this.isEnabled(particle)) {
7086 return;
7087 }
7088 updateOpacity(particle, delta);
7089 }
7090 }
7091 function loadOpacityUpdater(tsParticles) {
7092 tsParticles.addParticleUpdater("opacity", (container => new OpacityUpdater(container)));
7093 }
7094 function loadImage(source) {
7095 return new Promise(((resolve, reject) => {
7096 if (!source) {
7097 reject("Error tsParticles - No image.src");
7098 return;
7099 }
7100 const image = {
7101 source,
7102 type: source.substr(source.length - 3)
7103 };
7104 const img = new Image;
7105 img.addEventListener("load", (() => {
7106 image.element = img;
7107 resolve(image);
7108 }));
7109 img.addEventListener("error", (() => {
7110 reject(`Error tsParticles - loading image: ${source}`);
7111 }));
7112 img.src = source;
7113 }));
7114 }
7115 async function downloadSvgImage(source) {
7116 if (!source) {
7117 throw new Error("Error tsParticles - No image.src");
7118 }
7119 const image = {
7120 source,
7121 type: source.substr(source.length - 3)
7122 };
7123 if (image.type !== "svg") {
7124 return loadImage(source);
7125 }
7126 const response = await fetch(image.source);
7127 if (!response.ok) {
7128 throw new Error("Error tsParticles - Image not found");
7129 }
7130 image.svgData = await response.text();
7131 return image;
7132 }
7133 function replaceColorSvg(imageShape, color, opacity) {
7134 const {svgData} = imageShape;
7135 if (!svgData) {
7136 return "";
7137 }
7138 if (svgData.includes("fill")) {
7139 const currentColor = /(#(?:[0-9a-f]{2}){2,4}|(#[0-9a-f]{3})|(rgb|hsl)a?\((-?\d+%?[,\s]+){2,3}\s*[\d.]+%?\))|currentcolor/gi;
7140 return svgData.replace(currentColor, (() => getStyleFromHsl(color, opacity)));
7141 }
7142 const preFillIndex = svgData.indexOf(">");
7143 return `${svgData.substring(0, preFillIndex)} fill="${getStyleFromHsl(color, opacity)}"${svgData.substring(preFillIndex)}`;
7144 }
7145 var ImageDrawer_classPrivateFieldSet = undefined && undefined.__classPrivateFieldSet || function(receiver, state, value, kind, f) {
7146 if (kind === "m") throw new TypeError("Private method is not writable");
7147 if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
7148 if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
7149 return kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value),
7150 value;
7151 };
7152 var ImageDrawer_classPrivateFieldGet = undefined && undefined.__classPrivateFieldGet || function(receiver, state, kind, f) {
7153 if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
7154 if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
7155 return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
7156 };
7157 var _ImageDrawer_images;
7158 class ImageDrawer {
7159 constructor() {
7160 _ImageDrawer_images.set(this, void 0);
7161 ImageDrawer_classPrivateFieldSet(this, _ImageDrawer_images, [], "f");
7162 }
7163 getSidesCount() {
7164 return 12;
7165 }
7166 getImages(container) {
7167 const containerImages = ImageDrawer_classPrivateFieldGet(this, _ImageDrawer_images, "f").find((t => t.id === container.id));
7168 if (!containerImages) {
7169 ImageDrawer_classPrivateFieldGet(this, _ImageDrawer_images, "f").push({
7170 id: container.id,
7171 images: []
7172 });
7173 return this.getImages(container);
7174 } else {
7175 return containerImages;
7176 }
7177 }
7178 addImage(container, image) {
7179 const containerImages = this.getImages(container);
7180 containerImages === null || containerImages === void 0 ? void 0 : containerImages.images.push(image);
7181 }
7182 async init(container) {
7183 await this.loadImagesFromParticlesOptions(container, container.actualOptions.particles);
7184 await this.loadImagesFromParticlesOptions(container, container.actualOptions.interactivity.modes.trail.particles);
7185 for (const manualParticle of container.actualOptions.manualParticles) {
7186 await this.loadImagesFromParticlesOptions(container, manualParticle.options);
7187 }
7188 const emitterOptions = container.actualOptions;
7189 if (emitterOptions.emitters) {
7190 if (emitterOptions.emitters instanceof Array) {
7191 for (const emitter of emitterOptions.emitters) {
7192 await this.loadImagesFromParticlesOptions(container, emitter.particles);
7193 }
7194 } else {
7195 await this.loadImagesFromParticlesOptions(container, emitterOptions.emitters.particles);
7196 }
7197 }
7198 const interactiveEmitters = emitterOptions.interactivity.modes.emitters;
7199 if (interactiveEmitters) {
7200 if (interactiveEmitters instanceof Array) {
7201 for (const emitter of interactiveEmitters) {
7202 await this.loadImagesFromParticlesOptions(container, emitter.particles);
7203 }
7204 } else {
7205 await this.loadImagesFromParticlesOptions(container, interactiveEmitters.particles);
7206 }
7207 }
7208 }
7209 destroy() {
7210 ImageDrawer_classPrivateFieldSet(this, _ImageDrawer_images, [], "f");
7211 }
7212 async loadImagesFromParticlesOptions(container, options) {
7213 var _a, _b, _c;
7214 const shapeOptions = options === null || options === void 0 ? void 0 : options.shape;
7215 if (!(shapeOptions === null || shapeOptions === void 0 ? void 0 : shapeOptions.type) || !shapeOptions.options || !isInArray(ShapeType.image, shapeOptions.type) && !isInArray(ShapeType.images, shapeOptions.type)) {
7216 return;
7217 }
7218 const idx = ImageDrawer_classPrivateFieldGet(this, _ImageDrawer_images, "f").findIndex((t => t.id === container.id));
7219 if (idx >= 0) {
7220 ImageDrawer_classPrivateFieldGet(this, _ImageDrawer_images, "f").splice(idx, 1);
7221 }
7222 const imageOptions = (_a = shapeOptions.options[ShapeType.images]) !== null && _a !== void 0 ? _a : shapeOptions.options[ShapeType.image];
7223 if (imageOptions instanceof Array) {
7224 for (const optionsImage of imageOptions) {
7225 await this.loadImageShape(container, optionsImage);
7226 }
7227 } else {
7228 await this.loadImageShape(container, imageOptions);
7229 }
7230 if (options === null || options === void 0 ? void 0 : options.groups) {
7231 for (const groupName in options.groups) {
7232 const group = options.groups[groupName];
7233 await this.loadImagesFromParticlesOptions(container, group);
7234 }
7235 }
7236 if ((_c = (_b = options === null || options === void 0 ? void 0 : options.destroy) === null || _b === void 0 ? void 0 : _b.split) === null || _c === void 0 ? void 0 : _c.particles) {
7237 await this.loadImagesFromParticlesOptions(container, options === null || options === void 0 ? void 0 : options.destroy.split.particles);
7238 }
7239 }
7240 async loadImageShape(container, imageShape) {
7241 try {
7242 const imageFunc = imageShape.replaceColor ? downloadSvgImage : loadImage;
7243 const image = await imageFunc(imageShape.src);
7244 if (image) {
7245 this.addImage(container, image);
7246 }
7247 } catch (_a) {
7248 console.warn(`tsParticles error - ${imageShape.src} not found`);
7249 }
7250 }
7251 draw(context, particle, radius, opacity) {
7252 var _a, _b;
7253 if (!context) {
7254 return;
7255 }
7256 const image = particle.image;
7257 const element = (_a = image === null || image === void 0 ? void 0 : image.data) === null || _a === void 0 ? void 0 : _a.element;
7258 if (!element) {
7259 return;
7260 }
7261 const ratio = (_b = image === null || image === void 0 ? void 0 : image.ratio) !== null && _b !== void 0 ? _b : 1;
7262 const pos = {
7263 x: -radius,
7264 y: -radius
7265 };
7266 if (!(image === null || image === void 0 ? void 0 : image.data.svgData) || !(image === null || image === void 0 ? void 0 : image.replaceColor)) {
7267 context.globalAlpha = opacity;
7268 }
7269 context.drawImage(element, pos.x, pos.y, radius * 2, radius * 2 / ratio);
7270 if (!(image === null || image === void 0 ? void 0 : image.data.svgData) || !(image === null || image === void 0 ? void 0 : image.replaceColor)) {
7271 context.globalAlpha = 1;
7272 }
7273 }
7274 loadShape(particle) {
7275 var _a, _b, _c, _d, _e, _f, _g;
7276 if (particle.shape !== "image" && particle.shape !== "images") {
7277 return;
7278 }
7279 const images = this.getImages(particle.container).images;
7280 const imageData = particle.shapeData;
7281 const image = (_a = images.find((t => t.source === imageData.src))) !== null && _a !== void 0 ? _a : images[0];
7282 const color = particle.getFillColor();
7283 let imageRes;
7284 if (!image) {
7285 return;
7286 }
7287 if (image.svgData !== undefined && imageData.replaceColor && color) {
7288 const svgColoredData = replaceColorSvg(image, color, (_c = (_b = particle.opacity) === null || _b === void 0 ? void 0 : _b.value) !== null && _c !== void 0 ? _c : 1);
7289 const svg = new Blob([ svgColoredData ], {
7290 type: "image/svg+xml"
7291 });
7292 const domUrl = URL || window.URL || window.webkitURL || window;
7293 const url = domUrl.createObjectURL(svg);
7294 const img = new Image;
7295 imageRes = {
7296 data: Object.assign(Object.assign({}, image), {
7297 svgData: svgColoredData
7298 }),
7299 ratio: imageData.width / imageData.height,
7300 replaceColor: (_d = imageData.replaceColor) !== null && _d !== void 0 ? _d : imageData.replace_color,
7301 source: imageData.src
7302 };
7303 img.addEventListener("load", (() => {
7304 const pImage = particle.image;
7305 if (pImage) {
7306 pImage.loaded = true;
7307 image.element = img;
7308 }
7309 domUrl.revokeObjectURL(url);
7310 }));
7311 img.addEventListener("error", (() => {
7312 domUrl.revokeObjectURL(url);
7313 loadImage(imageData.src).then((img2 => {
7314 const pImage = particle.image;
7315 if (pImage) {
7316 image.element = img2 === null || img2 === void 0 ? void 0 : img2.element;
7317 pImage.loaded = true;
7318 }
7319 }));
7320 }));
7321 img.src = url;
7322 } else {
7323 imageRes = {
7324 data: image,
7325 loaded: true,
7326 ratio: imageData.width / imageData.height,
7327 replaceColor: (_e = imageData.replaceColor) !== null && _e !== void 0 ? _e : imageData.replace_color,
7328 source: imageData.src
7329 };
7330 }
7331 if (!imageRes.ratio) {
7332 imageRes.ratio = 1;
7333 }
7334 const fill = (_f = imageData.fill) !== null && _f !== void 0 ? _f : particle.fill;
7335 const close = (_g = imageData.close) !== null && _g !== void 0 ? _g : particle.close;
7336 const imageShape = {
7337 image: imageRes,
7338 fill,
7339 close
7340 };
7341 particle.image = imageShape.image;
7342 particle.fill = imageShape.fill;
7343 particle.close = imageShape.close;
7344 }
7345 }
7346 _ImageDrawer_images = new WeakMap;
7347 function loadImageShape(tsParticles) {
7348 const imageDrawer = new ImageDrawer;
7349 tsParticles.addShape("image", imageDrawer);
7350 tsParticles.addShape("images", imageDrawer);
7351 }
7352 class PolygonDrawerBase {
7353 getSidesCount(particle) {
7354 var _a, _b;
7355 const polygon = particle.shapeData;
7356 return (_b = (_a = polygon === null || polygon === void 0 ? void 0 : polygon.sides) !== null && _a !== void 0 ? _a : polygon === null || polygon === void 0 ? void 0 : polygon.nb_sides) !== null && _b !== void 0 ? _b : 5;
7357 }
7358 draw(context, particle, radius) {
7359 const start = this.getCenter(particle, radius);
7360 const side = this.getSidesData(particle, radius);
7361 const sideCount = side.count.numerator * side.count.denominator;
7362 const decimalSides = side.count.numerator / side.count.denominator;
7363 const interiorAngleDegrees = 180 * (decimalSides - 2) / decimalSides;
7364 const interiorAngle = Math.PI - Math.PI * interiorAngleDegrees / 180;
7365 if (!context) {
7366 return;
7367 }
7368 context.beginPath();
7369 context.translate(start.x, start.y);
7370 context.moveTo(0, 0);
7371 for (let i = 0; i < sideCount; i++) {
7372 context.lineTo(side.length, 0);
7373 context.translate(side.length, 0);
7374 context.rotate(interiorAngle);
7375 }
7376 }
7377 }
7378 class PolygonDrawer extends PolygonDrawerBase {
7379 getSidesData(particle, radius) {
7380 var _a, _b;
7381 const polygon = particle.shapeData;
7382 const sides = (_b = (_a = polygon === null || polygon === void 0 ? void 0 : polygon.sides) !== null && _a !== void 0 ? _a : polygon === null || polygon === void 0 ? void 0 : polygon.nb_sides) !== null && _b !== void 0 ? _b : 5;
7383 return {
7384 count: {
7385 denominator: 1,
7386 numerator: sides
7387 },
7388 length: radius * 2.66 / (sides / 3)
7389 };
7390 }
7391 getCenter(particle, radius) {
7392 const sides = this.getSidesCount(particle);
7393 return {
7394 x: -radius / (sides / 3.5),
7395 y: -radius / (2.66 / 3.5)
7396 };
7397 }
7398 }
7399 class TriangleDrawer extends PolygonDrawerBase {
7400 getSidesCount() {
7401 return 3;
7402 }
7403 getSidesData(particle, radius) {
7404 return {
7405 count: {
7406 denominator: 2,
7407 numerator: 3
7408 },
7409 length: radius * 2
7410 };
7411 }
7412 getCenter(particle, radius) {
7413 return {
7414 x: -radius,
7415 y: radius / 1.66
7416 };
7417 }
7418 }
7419 function loadGenericPolygonShape(tsParticles) {
7420 tsParticles.addShape("polygon", new PolygonDrawer);
7421 }
7422 function loadTriangleShape(tsParticles) {
7423 tsParticles.addShape("triangle", new TriangleDrawer);
7424 }
7425 function loadPolygonShape(tsParticles) {
7426 loadGenericPolygonShape(tsParticles);
7427 loadTriangleShape(tsParticles);
7428 }
7429 var ProcessBubbleType;
7430 (function(ProcessBubbleType) {
7431 ProcessBubbleType["color"] = "color";
7432 ProcessBubbleType["opacity"] = "opacity";
7433 ProcessBubbleType["size"] = "size";
7434 })(ProcessBubbleType || (ProcessBubbleType = {}));
7435 function calculateBubbleValue(particleValue, modeValue, optionsValue, ratio) {
7436 if (modeValue >= optionsValue) {
7437 const value = particleValue + (modeValue - optionsValue) * ratio;
7438 return clamp(value, particleValue, modeValue);
7439 } else if (modeValue < optionsValue) {
7440 const value = particleValue - (optionsValue - modeValue) * ratio;
7441 return clamp(value, modeValue, particleValue);
7442 }
7443 }
7444 class Bubbler extends ExternalInteractorBase {
7445 constructor(container) {
7446 super(container);
7447 }
7448 isEnabled() {
7449 const container = this.container, options = container.actualOptions, mouse = container.interactivity.mouse, events = options.interactivity.events, divs = events.onDiv, divBubble = isDivModeEnabled(DivMode.bubble, divs);
7450 if (!(divBubble || events.onHover.enable && mouse.position || events.onClick.enable && mouse.clickPosition)) {
7451 return false;
7452 }
7453 const hoverMode = events.onHover.mode;
7454 const clickMode = events.onClick.mode;
7455 return isInArray(HoverMode.bubble, hoverMode) || isInArray(ClickMode.bubble, clickMode) || divBubble;
7456 }
7457 reset(particle, force) {
7458 if (!(!particle.bubble.inRange || force)) {
7459 return;
7460 }
7461 delete particle.bubble.div;
7462 delete particle.bubble.opacity;
7463 delete particle.bubble.radius;
7464 delete particle.bubble.color;
7465 }
7466 interact() {
7467 const options = this.container.actualOptions, events = options.interactivity.events, onHover = events.onHover, onClick = events.onClick, hoverEnabled = onHover.enable, hoverMode = onHover.mode, clickEnabled = onClick.enable, clickMode = onClick.mode, divs = events.onDiv;
7468 if (hoverEnabled && isInArray(HoverMode.bubble, hoverMode)) {
7469 this.hoverBubble();
7470 } else if (clickEnabled && isInArray(ClickMode.bubble, clickMode)) {
7471 this.clickBubble();
7472 } else {
7473 divModeExecute(DivMode.bubble, divs, ((selector, div) => this.singleSelectorHover(selector, div)));
7474 }
7475 }
7476 singleSelectorHover(selector, div) {
7477 const container = this.container, selectors = document.querySelectorAll(selector);
7478 if (!selectors.length) {
7479 return;
7480 }
7481 selectors.forEach((item => {
7482 const elem = item, pxRatio = container.retina.pixelRatio, pos = {
7483 x: (elem.offsetLeft + elem.offsetWidth / 2) * pxRatio,
7484 y: (elem.offsetTop + elem.offsetHeight / 2) * pxRatio
7485 }, repulseRadius = elem.offsetWidth / 2 * pxRatio, area = div.type === DivType.circle ? new Circle(pos.x, pos.y, repulseRadius) : new Rectangle(elem.offsetLeft * pxRatio, elem.offsetTop * pxRatio, elem.offsetWidth * pxRatio, elem.offsetHeight * pxRatio), query = container.particles.quadTree.query(area);
7486 for (const particle of query) {
7487 if (!area.contains(particle.getPosition())) {
7488 continue;
7489 }
7490 particle.bubble.inRange = true;
7491 const divs = container.actualOptions.interactivity.modes.bubble.divs;
7492 const divBubble = divMode(divs, elem);
7493 if (!particle.bubble.div || particle.bubble.div !== elem) {
7494 this.reset(particle, true);
7495 particle.bubble.div = elem;
7496 }
7497 this.hoverBubbleSize(particle, 1, divBubble);
7498 this.hoverBubbleOpacity(particle, 1, divBubble);
7499 this.hoverBubbleColor(particle, 1, divBubble);
7500 }
7501 }));
7502 }
7503 process(particle, distMouse, timeSpent, data) {
7504 const container = this.container, bubbleParam = data.bubbleObj.optValue;
7505 if (bubbleParam === undefined) {
7506 return;
7507 }
7508 const options = container.actualOptions, bubbleDuration = options.interactivity.modes.bubble.duration, bubbleDistance = container.retina.bubbleModeDistance, particlesParam = data.particlesObj.optValue, pObjBubble = data.bubbleObj.value, pObj = data.particlesObj.value || 0, type = data.type;
7509 if (bubbleParam === particlesParam) {
7510 return;
7511 }
7512 if (!container.bubble.durationEnd) {
7513 if (distMouse <= bubbleDistance) {
7514 const obj = pObjBubble !== null && pObjBubble !== void 0 ? pObjBubble : pObj;
7515 if (obj !== bubbleParam) {
7516 const value = pObj - timeSpent * (pObj - bubbleParam) / bubbleDuration;
7517 if (type === ProcessBubbleType.size) {
7518 particle.bubble.radius = value;
7519 }
7520 if (type === ProcessBubbleType.opacity) {
7521 particle.bubble.opacity = value;
7522 }
7523 }
7524 } else {
7525 if (type === ProcessBubbleType.size) {
7526 delete particle.bubble.radius;
7527 }
7528 if (type === ProcessBubbleType.opacity) {
7529 delete particle.bubble.opacity;
7530 }
7531 }
7532 } else if (pObjBubble) {
7533 if (type === ProcessBubbleType.size) {
7534 delete particle.bubble.radius;
7535 }
7536 if (type === ProcessBubbleType.opacity) {
7537 delete particle.bubble.opacity;
7538 }
7539 }
7540 }
7541 clickBubble() {
7542 var _a, _b;
7543 const container = this.container, options = container.actualOptions, mouseClickPos = container.interactivity.mouse.clickPosition;
7544 if (!mouseClickPos) {
7545 return;
7546 }
7547 const distance = container.retina.bubbleModeDistance, query = container.particles.quadTree.queryCircle(mouseClickPos, distance);
7548 for (const particle of query) {
7549 if (!container.bubble.clicking) {
7550 continue;
7551 }
7552 particle.bubble.inRange = !container.bubble.durationEnd;
7553 const pos = particle.getPosition(), distMouse = getDistance(pos, mouseClickPos), timeSpent = ((new Date).getTime() - (container.interactivity.mouse.clickTime || 0)) / 1e3;
7554 if (timeSpent > options.interactivity.modes.bubble.duration) {
7555 container.bubble.durationEnd = true;
7556 }
7557 if (timeSpent > options.interactivity.modes.bubble.duration * 2) {
7558 container.bubble.clicking = false;
7559 container.bubble.durationEnd = false;
7560 }
7561 const sizeData = {
7562 bubbleObj: {
7563 optValue: container.retina.bubbleModeSize,
7564 value: particle.bubble.radius
7565 },
7566 particlesObj: {
7567 optValue: getRangeMax(particle.options.size.value) * container.retina.pixelRatio,
7568 value: particle.size.value
7569 },
7570 type: ProcessBubbleType.size
7571 };
7572 this.process(particle, distMouse, timeSpent, sizeData);
7573 const opacityData = {
7574 bubbleObj: {
7575 optValue: options.interactivity.modes.bubble.opacity,
7576 value: particle.bubble.opacity
7577 },
7578 particlesObj: {
7579 optValue: getRangeMax(particle.options.opacity.value),
7580 value: (_b = (_a = particle.opacity) === null || _a === void 0 ? void 0 : _a.value) !== null && _b !== void 0 ? _b : 1
7581 },
7582 type: ProcessBubbleType.opacity
7583 };
7584 this.process(particle, distMouse, timeSpent, opacityData);
7585 if (!container.bubble.durationEnd) {
7586 if (distMouse <= container.retina.bubbleModeDistance) {
7587 this.hoverBubbleColor(particle, distMouse);
7588 } else {
7589 delete particle.bubble.color;
7590 }
7591 } else {
7592 delete particle.bubble.color;
7593 }
7594 }
7595 }
7596 hoverBubble() {
7597 const container = this.container, mousePos = container.interactivity.mouse.position;
7598 if (mousePos === undefined) {
7599 return;
7600 }
7601 const distance = container.retina.bubbleModeDistance, query = container.particles.quadTree.queryCircle(mousePos, distance);
7602 for (const particle of query) {
7603 particle.bubble.inRange = true;
7604 const pos = particle.getPosition(), pointDistance = getDistance(pos, mousePos), ratio = 1 - pointDistance / distance;
7605 if (pointDistance <= distance) {
7606 if (ratio >= 0 && container.interactivity.status === Constants.mouseMoveEvent) {
7607 this.hoverBubbleSize(particle, ratio);
7608 this.hoverBubbleOpacity(particle, ratio);
7609 this.hoverBubbleColor(particle, ratio);
7610 }
7611 } else {
7612 this.reset(particle);
7613 }
7614 if (container.interactivity.status === Constants.mouseLeaveEvent) {
7615 this.reset(particle);
7616 }
7617 }
7618 }
7619 hoverBubbleSize(particle, ratio, divBubble) {
7620 const container = this.container, modeSize = (divBubble === null || divBubble === void 0 ? void 0 : divBubble.size) ? divBubble.size * container.retina.pixelRatio : container.retina.bubbleModeSize;
7621 if (modeSize === undefined) {
7622 return;
7623 }
7624 const optSize = getRangeMax(particle.options.size.value) * container.retina.pixelRatio;
7625 const pSize = particle.size.value;
7626 const size = calculateBubbleValue(pSize, modeSize, optSize, ratio);
7627 if (size !== undefined) {
7628 particle.bubble.radius = size;
7629 }
7630 }
7631 hoverBubbleOpacity(particle, ratio, divBubble) {
7632 var _a, _b, _c;
7633 const container = this.container, options = container.actualOptions, modeOpacity = (_a = divBubble === null || divBubble === void 0 ? void 0 : divBubble.opacity) !== null && _a !== void 0 ? _a : options.interactivity.modes.bubble.opacity;
7634 if (!modeOpacity) {
7635 return;
7636 }
7637 const optOpacity = particle.options.opacity.value;
7638 const pOpacity = (_c = (_b = particle.opacity) === null || _b === void 0 ? void 0 : _b.value) !== null && _c !== void 0 ? _c : 1;
7639 const opacity = calculateBubbleValue(pOpacity, modeOpacity, getRangeMax(optOpacity), ratio);
7640 if (opacity !== undefined) {
7641 particle.bubble.opacity = opacity;
7642 }
7643 }
7644 hoverBubbleColor(particle, ratio, divBubble) {
7645 const options = this.container.actualOptions;
7646 const bubbleOptions = divBubble !== null && divBubble !== void 0 ? divBubble : options.interactivity.modes.bubble;
7647 if (!particle.bubble.finalColor) {
7648 const modeColor = bubbleOptions.color;
7649 if (!modeColor) {
7650 return;
7651 }
7652 const bubbleColor = modeColor instanceof Array ? itemFromArray(modeColor) : modeColor;
7653 particle.bubble.finalColor = colorToHsl(bubbleColor);
7654 }
7655 if (!particle.bubble.finalColor) {
7656 return;
7657 }
7658 if (bubbleOptions.mix) {
7659 particle.bubble.color = undefined;
7660 const pColor = particle.getFillColor();
7661 particle.bubble.color = pColor ? rgbToHsl(colorMix(pColor, particle.bubble.finalColor, 1 - ratio, ratio)) : particle.bubble.finalColor;
7662 } else {
7663 particle.bubble.color = particle.bubble.finalColor;
7664 }
7665 }
7666 }
7667 function loadExternalBubbleInteraction(tsParticles) {
7668 tsParticles.addInteractor("externalBubble", (container => new Bubbler(container)));
7669 }
7670 class Attractor extends ExternalInteractorBase {
7671 constructor(container) {
7672 super(container);
7673 }
7674 isEnabled() {
7675 const container = this.container, options = container.actualOptions, mouse = container.interactivity.mouse, events = options.interactivity.events;
7676 if ((!mouse.position || !events.onHover.enable) && (!mouse.clickPosition || !events.onClick.enable)) {
7677 return false;
7678 }
7679 const hoverMode = events.onHover.mode, clickMode = events.onClick.mode;
7680 return isInArray(HoverMode.attract, hoverMode) || isInArray(ClickMode.attract, clickMode);
7681 }
7682 reset() {}
7683 interact() {
7684 const container = this.container, options = container.actualOptions, mouseMoveStatus = container.interactivity.status === Constants.mouseMoveEvent, events = options.interactivity.events, hoverEnabled = events.onHover.enable, hoverMode = events.onHover.mode, clickEnabled = events.onClick.enable, clickMode = events.onClick.mode;
7685 if (mouseMoveStatus && hoverEnabled && isInArray(HoverMode.attract, hoverMode)) {
7686 this.hoverAttract();
7687 } else if (clickEnabled && isInArray(ClickMode.attract, clickMode)) {
7688 this.clickAttract();
7689 }
7690 }
7691 hoverAttract() {
7692 const container = this.container;
7693 const mousePos = container.interactivity.mouse.position;
7694 if (!mousePos) {
7695 return;
7696 }
7697 const attractRadius = container.retina.attractModeDistance;
7698 this.processAttract(mousePos, attractRadius, new Circle(mousePos.x, mousePos.y, attractRadius));
7699 }
7700 processAttract(position, attractRadius, area) {
7701 const container = this.container;
7702 const attractOptions = container.actualOptions.interactivity.modes.attract;
7703 const query = container.particles.quadTree.query(area);
7704 for (const particle of query) {
7705 const {dx, dy, distance} = getDistances(particle.position, position);
7706 const velocity = attractOptions.speed * attractOptions.factor;
7707 const attractFactor = clamp(calcEasing(1 - distance / attractRadius, attractOptions.easing) * velocity, 0, attractOptions.maxSpeed);
7708 const normVec = Vector.create(distance === 0 ? velocity : dx / distance * attractFactor, distance === 0 ? velocity : dy / distance * attractFactor);
7709 particle.position.subFrom(normVec);
7710 }
7711 }
7712 clickAttract() {
7713 const container = this.container;
7714 if (!container.attract.finish) {
7715 if (!container.attract.count) {
7716 container.attract.count = 0;
7717 }
7718 container.attract.count++;
7719 if (container.attract.count === container.particles.count) {
7720 container.attract.finish = true;
7721 }
7722 }
7723 if (container.attract.clicking) {
7724 const mousePos = container.interactivity.mouse.clickPosition;
7725 if (!mousePos) {
7726 return;
7727 }
7728 const attractRadius = container.retina.attractModeDistance;
7729 this.processAttract(mousePos, attractRadius, new Circle(mousePos.x, mousePos.y, attractRadius));
7730 } else if (container.attract.clicking === false) {
7731 container.attract.particles = [];
7732 }
7733 return;
7734 }
7735 }
7736 function loadExternalAttractInteraction(tsParticles) {
7737 tsParticles.addInteractor("externalAttract", (container => new Attractor(container)));
7738 }
7739 class Grabber extends ExternalInteractorBase {
7740 constructor(container) {
7741 super(container);
7742 }
7743 isEnabled() {
7744 const container = this.container, mouse = container.interactivity.mouse, events = container.actualOptions.interactivity.events;
7745 return events.onHover.enable && !!mouse.position && isInArray(HoverMode.grab, events.onHover.mode);
7746 }
7747 reset() {}
7748 interact() {
7749 var _a;
7750 const container = this.container, options = container.actualOptions, interactivity = options.interactivity;
7751 if (interactivity.events.onHover.enable && container.interactivity.status === Constants.mouseMoveEvent) {
7752 const mousePos = container.interactivity.mouse.position;
7753 if (!mousePos) {
7754 return;
7755 }
7756 const distance = container.retina.grabModeDistance, query = container.particles.quadTree.queryCircle(mousePos, distance);
7757 for (const particle of query) {
7758 const pos = particle.getPosition(), pointDistance = getDistance(pos, mousePos);
7759 if (pointDistance <= distance) {
7760 const grabLineOptions = interactivity.modes.grab.links, lineOpacity = grabLineOptions.opacity, opacityLine = lineOpacity - pointDistance * lineOpacity / distance;
7761 if (opacityLine <= 0) {
7762 continue;
7763 }
7764 const optColor = (_a = grabLineOptions.color) !== null && _a !== void 0 ? _a : particle.options.links.color;
7765 if (!container.particles.grabLineColor) {
7766 const linksOptions = options.interactivity.modes.grab.links;
7767 container.particles.grabLineColor = getLinkRandomColor(optColor, linksOptions.blink, linksOptions.consent);
7768 }
7769 const colorLine = getLinkColor(particle, undefined, container.particles.grabLineColor);
7770 if (!colorLine) {
7771 return;
7772 }
7773 container.canvas.drawGrabLine(particle, colorLine, opacityLine, mousePos);
7774 }
7775 }
7776 }
7777 }
7778 }
7779 function loadExternalGrabInteraction(tsParticles) {
7780 tsParticles.addInteractor("externalGrab", (container => new Grabber(container)));
7781 }
7782 class StarDrawer {
7783 getSidesCount(particle) {
7784 var _a, _b;
7785 const star = particle.shapeData;
7786 return (_b = (_a = star === null || star === void 0 ? void 0 : star.sides) !== null && _a !== void 0 ? _a : star === null || star === void 0 ? void 0 : star.nb_sides) !== null && _b !== void 0 ? _b : 5;
7787 }
7788 draw(context, particle, radius) {
7789 var _a;
7790 const star = particle.shapeData;
7791 const sides = this.getSidesCount(particle);
7792 const inset = (_a = star === null || star === void 0 ? void 0 : star.inset) !== null && _a !== void 0 ? _a : 2;
7793 context.moveTo(0, 0 - radius);
7794 for (let i = 0; i < sides; i++) {
7795 context.rotate(Math.PI / sides);
7796 context.lineTo(0, 0 - radius * inset);
7797 context.rotate(Math.PI / sides);
7798 context.lineTo(0, 0 - radius);
7799 }
7800 }
7801 }
7802 function loadStarShape(tsParticles) {
7803 tsParticles.addShape("star", new StarDrawer);
7804 }
7805 class ParticlesInteractorBase {
7806 constructor(container) {
7807 this.container = container;
7808 this.type = InteractorType.Particles;
7809 }
7810 }
7811 class Attractor_Attractor extends ParticlesInteractorBase {
7812 constructor(container) {
7813 super(container);
7814 }
7815 interact(p1) {
7816 var _a;
7817 const container = this.container, distance = (_a = p1.retina.attractDistance) !== null && _a !== void 0 ? _a : container.retina.attractDistance, pos1 = p1.getPosition(), query = container.particles.quadTree.queryCircle(pos1, distance);
7818 for (const p2 of query) {
7819 if (p1 === p2 || !p2.options.move.attract.enable || p2.destroyed || p2.spawning) {
7820 continue;
7821 }
7822 const pos2 = p2.getPosition(), {dx, dy} = getDistances(pos1, pos2), rotate = p1.options.move.attract.rotate, ax = dx / (rotate.x * 1e3), ay = dy / (rotate.y * 1e3), p1Factor = p2.size.value / p1.size.value, p2Factor = 1 / p1Factor;
7823 p1.velocity.x -= ax * p1Factor;
7824 p1.velocity.y -= ay * p1Factor;
7825 p2.velocity.x += ax * p2Factor;
7826 p2.velocity.y += ay * p2Factor;
7827 }
7828 }
7829 isEnabled(particle) {
7830 return particle.options.move.attract.enable;
7831 }
7832 reset() {}
7833 }
7834 function loadParticlesAttractInteraction(tsParticles) {
7835 tsParticles.addInteractor("particlesAttract", (container => new Attractor_Attractor(container)));
7836 }
7837 const fixFactor = Math.sqrt(2);
7838 class SquareDrawer {
7839 getSidesCount() {
7840 return 4;
7841 }
7842 draw(context, particle, radius) {
7843 context.rect(-radius / fixFactor, -radius / fixFactor, radius * 2 / fixFactor, radius * 2 / fixFactor);
7844 }
7845 }
7846 function loadSquareShape(tsParticles) {
7847 const drawer = new SquareDrawer;
7848 tsParticles.addShape("edge", drawer);
7849 tsParticles.addShape("square", drawer);
7850 }
7851 function updateColorValue(delta, value, valueAnimation, max, decrease) {
7852 var _a;
7853 const colorValue = value;
7854 if (!colorValue || !colorValue.enable) {
7855 return;
7856 }
7857 const offset = randomInRange(valueAnimation.offset);
7858 const velocity = ((_a = value.velocity) !== null && _a !== void 0 ? _a : 0) * delta.factor + offset * 3.6;
7859 if (!decrease || colorValue.status === AnimationStatus.increasing) {
7860 colorValue.value += velocity;
7861 if (decrease && colorValue.value > max) {
7862 colorValue.status = AnimationStatus.decreasing;
7863 colorValue.value -= colorValue.value % max;
7864 }
7865 } else {
7866 colorValue.value -= velocity;
7867 if (colorValue.value < 0) {
7868 colorValue.status = AnimationStatus.increasing;
7869 colorValue.value += colorValue.value;
7870 }
7871 }
7872 if (colorValue.value > max) {
7873 colorValue.value %= max;
7874 }
7875 }
7876 function updateStrokeColor(particle, delta) {
7877 var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
7878 if (!((_a = particle.stroke) === null || _a === void 0 ? void 0 : _a.color)) {
7879 return;
7880 }
7881 const animationOptions = particle.stroke.color.animation;
7882 const h = (_c = (_b = particle.strokeColor) === null || _b === void 0 ? void 0 : _b.h) !== null && _c !== void 0 ? _c : (_d = particle.color) === null || _d === void 0 ? void 0 : _d.h;
7883 if (h) {
7884 updateColorValue(delta, h, animationOptions.h, 360, false);
7885 }
7886 const s = (_f = (_e = particle.strokeColor) === null || _e === void 0 ? void 0 : _e.s) !== null && _f !== void 0 ? _f : (_g = particle.color) === null || _g === void 0 ? void 0 : _g.s;
7887 if (s) {
7888 updateColorValue(delta, s, animationOptions.s, 100, true);
7889 }
7890 const l = (_j = (_h = particle.strokeColor) === null || _h === void 0 ? void 0 : _h.l) !== null && _j !== void 0 ? _j : (_k = particle.color) === null || _k === void 0 ? void 0 : _k.l;
7891 if (l) {
7892 updateColorValue(delta, l, animationOptions.l, 100, true);
7893 }
7894 }
7895 class StrokeColorUpdater {
7896 constructor(container) {
7897 this.container = container;
7898 }
7899 init(particle) {
7900 var _a, _b;
7901 const container = this.container;
7902 particle.stroke = particle.options.stroke instanceof Array ? itemFromArray(particle.options.stroke, particle.id, particle.options.reduceDuplicates) : particle.options.stroke;
7903 particle.strokeWidth = particle.stroke.width * container.retina.pixelRatio;
7904 const strokeHslColor = (_a = colorToHsl(particle.stroke.color)) !== null && _a !== void 0 ? _a : particle.getFillColor();
7905 if (strokeHslColor) {
7906 particle.strokeColor = getHslAnimationFromHsl(strokeHslColor, (_b = particle.stroke.color) === null || _b === void 0 ? void 0 : _b.animation, container.retina.reduceFactor);
7907 }
7908 }
7909 isEnabled(particle) {
7910 var _a, _b, _c, _d;
7911 const color = (_a = particle.stroke) === null || _a === void 0 ? void 0 : _a.color;
7912 return !particle.destroyed && !particle.spawning && !!color && (((_b = particle.strokeColor) === null || _b === void 0 ? void 0 : _b.h.value) !== undefined && color.animation.h.enable || ((_c = particle.strokeColor) === null || _c === void 0 ? void 0 : _c.s.value) !== undefined && color.animation.s.enable || ((_d = particle.strokeColor) === null || _d === void 0 ? void 0 : _d.l.value) !== undefined && color.animation.l.enable);
7913 }
7914 update(particle, delta) {
7915 if (!this.isEnabled(particle)) {
7916 return;
7917 }
7918 updateStrokeColor(particle, delta);
7919 }
7920 }
7921 function loadStrokeColorUpdater(tsParticles) {
7922 tsParticles.addParticleUpdater("strokeColor", (container => new StrokeColorUpdater(container)));
7923 }
7924 function ColorUpdater_updateColorValue(delta, value, valueAnimation, max, decrease) {
7925 var _a;
7926 const colorValue = value;
7927 if (!colorValue || !valueAnimation.enable) {
7928 return;
7929 }
7930 const offset = randomInRange(valueAnimation.offset);
7931 const velocity = ((_a = value.velocity) !== null && _a !== void 0 ? _a : 0) * delta.factor + offset * 3.6;
7932 if (!decrease || colorValue.status === AnimationStatus.increasing) {
7933 colorValue.value += velocity;
7934 if (decrease && colorValue.value > max) {
7935 colorValue.status = AnimationStatus.decreasing;
7936 colorValue.value -= colorValue.value % max;
7937 }
7938 } else {
7939 colorValue.value -= velocity;
7940 if (colorValue.value < 0) {
7941 colorValue.status = AnimationStatus.increasing;
7942 colorValue.value += colorValue.value;
7943 }
7944 }
7945 if (colorValue.value > max) {
7946 colorValue.value %= max;
7947 }
7948 }
7949 function updateColor(particle, delta) {
7950 var _a, _b, _c;
7951 const animationOptions = particle.options.color.animation;
7952 if (((_a = particle.color) === null || _a === void 0 ? void 0 : _a.h) !== undefined) {
7953 ColorUpdater_updateColorValue(delta, particle.color.h, animationOptions.h, 360, false);
7954 }
7955 if (((_b = particle.color) === null || _b === void 0 ? void 0 : _b.s) !== undefined) {
7956 ColorUpdater_updateColorValue(delta, particle.color.s, animationOptions.s, 100, true);
7957 }
7958 if (((_c = particle.color) === null || _c === void 0 ? void 0 : _c.l) !== undefined) {
7959 ColorUpdater_updateColorValue(delta, particle.color.l, animationOptions.l, 100, true);
7960 }
7961 }
7962 class ColorUpdater {
7963 constructor(container) {
7964 this.container = container;
7965 }
7966 init(particle) {
7967 const hslColor = colorToHsl(particle.options.color, particle.id, particle.options.reduceDuplicates);
7968 if (hslColor) {
7969 particle.color = getHslAnimationFromHsl(hslColor, particle.options.color.animation, this.container.retina.reduceFactor);
7970 }
7971 }
7972 isEnabled(particle) {
7973 var _a, _b, _c;
7974 const animationOptions = particle.options.color.animation;
7975 return !particle.destroyed && !particle.spawning && (((_a = particle.color) === null || _a === void 0 ? void 0 : _a.h.value) !== undefined && animationOptions.h.enable || ((_b = particle.color) === null || _b === void 0 ? void 0 : _b.s.value) !== undefined && animationOptions.s.enable || ((_c = particle.color) === null || _c === void 0 ? void 0 : _c.l.value) !== undefined && animationOptions.l.enable);
7976 }
7977 update(particle, delta) {
7978 updateColor(particle, delta);
7979 }
7980 }
7981 function loadColorUpdater(tsParticles) {
7982 tsParticles.addParticleUpdater("color", (container => new ColorUpdater(container)));
7983 }
7984 function bounce(p1, p2) {
7985 circleBounce(circleBounceDataFromParticle(p1), circleBounceDataFromParticle(p2));
7986 }
7987 function destroy(p1, p2) {
7988 if (!p1.unbreakable && !p2.unbreakable) {
7989 bounce(p1, p2);
7990 }
7991 if (p1.getRadius() === undefined && p2.getRadius() !== undefined) {
7992 p1.destroy();
7993 } else if (p1.getRadius() !== undefined && p2.getRadius() === undefined) {
7994 p2.destroy();
7995 } else if (p1.getRadius() !== undefined && p2.getRadius() !== undefined) {
7996 if (p1.getRadius() >= p2.getRadius()) {
7997 p2.destroy();
7998 } else {
7999 p1.destroy();
8000 }
8001 }
8002 }
8003 class Collider extends ParticlesInteractorBase {
8004 constructor(container) {
8005 super(container);
8006 }
8007 isEnabled(particle) {
8008 return particle.options.collisions.enable;
8009 }
8010 reset() {}
8011 interact(p1) {
8012 const container = this.container;
8013 const pos1 = p1.getPosition();
8014 const radius1 = p1.getRadius();
8015 const query = container.particles.quadTree.queryCircle(pos1, radius1 * 2);
8016 for (const p2 of query) {
8017 if (p1 === p2 || !p2.options.collisions.enable || p1.options.collisions.mode !== p2.options.collisions.mode || p2.destroyed || p2.spawning) {
8018 continue;
8019 }
8020 const pos2 = p2.getPosition();
8021 if (Math.round(pos1.z) !== Math.round(pos2.z)) {
8022 continue;
8023 }
8024 const dist = getDistance(pos1, pos2);
8025 const radius2 = p2.getRadius();
8026 const distP = radius1 + radius2;
8027 if (dist <= distP) {
8028 this.resolveCollision(p1, p2);
8029 }
8030 }
8031 }
8032 resolveCollision(p1, p2) {
8033 switch (p1.options.collisions.mode) {
8034 case CollisionMode.absorb:
8035 {
8036 this.absorb(p1, p2);
8037 break;
8038 }
8039
8040 case CollisionMode.bounce:
8041 {
8042 bounce(p1, p2);
8043 break;
8044 }
8045
8046 case CollisionMode.destroy:
8047 {
8048 destroy(p1, p2);
8049 break;
8050 }
8051 }
8052 }
8053 absorb(p1, p2) {
8054 const container = this.container;
8055 const fps = container.fpsLimit / 1e3;
8056 if (p1.getRadius() === undefined && p2.getRadius() !== undefined) {
8057 p1.destroy();
8058 } else if (p1.getRadius() !== undefined && p2.getRadius() === undefined) {
8059 p2.destroy();
8060 } else if (p1.getRadius() !== undefined && p2.getRadius() !== undefined) {
8061 if (p1.getRadius() >= p2.getRadius()) {
8062 const factor = clamp(p1.getRadius() / p2.getRadius(), 0, p2.getRadius()) * fps;
8063 p1.size.value += factor;
8064 p2.size.value -= factor;
8065 if (p2.getRadius() <= container.retina.pixelRatio) {
8066 p2.size.value = 0;
8067 p2.destroy();
8068 }
8069 } else {
8070 const factor = clamp(p2.getRadius() / p1.getRadius(), 0, p1.getRadius()) * fps;
8071 p1.size.value -= factor;
8072 p2.size.value += factor;
8073 if (p1.getRadius() <= container.retina.pixelRatio) {
8074 p1.size.value = 0;
8075 p1.destroy();
8076 }
8077 }
8078 }
8079 }
8080 }
8081 function loadParticlesCollisionsInteraction(tsParticles) {
8082 tsParticles.addInteractor("particlesCollisions", (container => new Collider(container)));
8083 }
8084 function updateAngle(particle, delta) {
8085 var _a;
8086 const rotate = particle.rotate;
8087 if (!rotate) {
8088 return;
8089 }
8090 const rotateOptions = particle.options.rotate;
8091 const rotateAnimation = rotateOptions.animation;
8092 const speed = ((_a = rotate.velocity) !== null && _a !== void 0 ? _a : 0) * delta.factor;
8093 const max = 2 * Math.PI;
8094 if (!rotateAnimation.enable) {
8095 return;
8096 }
8097 switch (rotate.status) {
8098 case AnimationStatus.increasing:
8099 rotate.value += speed;
8100 if (rotate.value > max) {
8101 rotate.value -= max;
8102 }
8103 break;
8104
8105 case AnimationStatus.decreasing:
8106 default:
8107 rotate.value -= speed;
8108 if (rotate.value < 0) {
8109 rotate.value += max;
8110 }
8111 break;
8112 }
8113 }
8114 class AngleUpdater {
8115 constructor(container) {
8116 this.container = container;
8117 }
8118 init(particle) {
8119 const rotateOptions = particle.options.rotate;
8120 particle.rotate = {
8121 enable: rotateOptions.animation.enable,
8122 value: getRangeValue(rotateOptions.value) * Math.PI / 180
8123 };
8124 let rotateDirection = rotateOptions.direction;
8125 if (rotateDirection === RotateDirection.random) {
8126 const index = Math.floor(Math.random() * 2);
8127 rotateDirection = index > 0 ? RotateDirection.counterClockwise : RotateDirection.clockwise;
8128 }
8129 switch (rotateDirection) {
8130 case RotateDirection.counterClockwise:
8131 case "counterClockwise":
8132 particle.rotate.status = AnimationStatus.decreasing;
8133 break;
8134
8135 case RotateDirection.clockwise:
8136 particle.rotate.status = AnimationStatus.increasing;
8137 break;
8138 }
8139 const rotateAnimation = particle.options.rotate.animation;
8140 if (rotateAnimation.enable) {
8141 particle.rotate.velocity = rotateAnimation.speed / 360 * this.container.retina.reduceFactor;
8142 if (!rotateAnimation.sync) {
8143 particle.rotate.velocity *= Math.random();
8144 }
8145 }
8146 }
8147 isEnabled(particle) {
8148 const rotate = particle.options.rotate;
8149 const rotateAnimation = rotate.animation;
8150 return !particle.destroyed && !particle.spawning && !rotate.path && rotateAnimation.enable;
8151 }
8152 update(particle, delta) {
8153 if (!this.isEnabled(particle)) {
8154 return;
8155 }
8156 updateAngle(particle, delta);
8157 }
8158 }
8159 function loadAngleUpdater(tsParticles) {
8160 tsParticles.addParticleUpdater("angle", (container => new AngleUpdater(container)));
8161 }
8162 function bounceHorizontal(data) {
8163 if (!(data.outMode === OutMode.bounce || data.outMode === OutMode.bounceHorizontal || data.outMode === "bounceHorizontal" || data.outMode === OutMode.split)) {
8164 return;
8165 }
8166 const velocity = data.particle.velocity.x;
8167 let bounced = false;
8168 if (data.direction === OutModeDirection.right && data.bounds.right >= data.canvasSize.width && velocity > 0 || data.direction === OutModeDirection.left && data.bounds.left <= 0 && velocity < 0) {
8169 const newVelocity = getRangeValue(data.particle.options.bounce.horizontal.value);
8170 data.particle.velocity.x *= -newVelocity;
8171 bounced = true;
8172 }
8173 if (!bounced) {
8174 return;
8175 }
8176 const minPos = data.offset.x + data.size;
8177 if (data.bounds.right >= data.canvasSize.width) {
8178 data.particle.position.x = data.canvasSize.width - minPos;
8179 } else if (data.bounds.left <= 0) {
8180 data.particle.position.x = minPos;
8181 }
8182 if (data.outMode === OutMode.split) {
8183 data.particle.destroy();
8184 }
8185 }
8186 function bounceVertical(data) {
8187 if (data.outMode === OutMode.bounce || data.outMode === OutMode.bounceVertical || data.outMode === "bounceVertical" || data.outMode === OutMode.split) {
8188 const velocity = data.particle.velocity.y;
8189 let bounced = false;
8190 if (data.direction === OutModeDirection.bottom && data.bounds.bottom >= data.canvasSize.height && velocity > 0 || data.direction === OutModeDirection.top && data.bounds.top <= 0 && velocity < 0) {
8191 const newVelocity = getRangeValue(data.particle.options.bounce.vertical.value);
8192 data.particle.velocity.y *= -newVelocity;
8193 bounced = true;
8194 }
8195 if (!bounced) {
8196 return;
8197 }
8198 const minPos = data.offset.y + data.size;
8199 if (data.bounds.bottom >= data.canvasSize.height) {
8200 data.particle.position.y = data.canvasSize.height - minPos;
8201 } else if (data.bounds.top <= 0) {
8202 data.particle.position.y = minPos;
8203 }
8204 if (data.outMode === OutMode.split) {
8205 data.particle.destroy();
8206 }
8207 }
8208 }
8209 class OutOfCanvasUpdater {
8210 constructor(container) {
8211 this.container = container;
8212 }
8213 init() {}
8214 isEnabled(particle) {
8215 return !particle.destroyed && !particle.spawning;
8216 }
8217 update(particle, delta) {
8218 var _a, _b, _c, _d;
8219 const outModes = particle.options.move.outModes;
8220 this.updateOutMode(particle, delta, (_a = outModes.bottom) !== null && _a !== void 0 ? _a : outModes.default, OutModeDirection.bottom);
8221 this.updateOutMode(particle, delta, (_b = outModes.left) !== null && _b !== void 0 ? _b : outModes.default, OutModeDirection.left);
8222 this.updateOutMode(particle, delta, (_c = outModes.right) !== null && _c !== void 0 ? _c : outModes.default, OutModeDirection.right);
8223 this.updateOutMode(particle, delta, (_d = outModes.top) !== null && _d !== void 0 ? _d : outModes.default, OutModeDirection.top);
8224 }
8225 updateOutMode(particle, delta, outMode, direction) {
8226 switch (outMode) {
8227 case OutMode.bounce:
8228 case OutMode.bounceVertical:
8229 case OutMode.bounceHorizontal:
8230 case "bounceVertical":
8231 case "bounceHorizontal":
8232 case OutMode.split:
8233 this.bounce(particle, delta, direction, outMode);
8234 break;
8235
8236 case OutMode.destroy:
8237 this.destroy(particle, direction);
8238 break;
8239
8240 case OutMode.out:
8241 this.out(particle, direction);
8242 break;
8243
8244 case OutMode.none:
8245 default:
8246 this.none(particle, direction);
8247 break;
8248 }
8249 }
8250 destroy(particle, direction) {
8251 const container = this.container;
8252 if (isPointInside(particle.position, container.canvas.size, particle.getRadius(), direction)) {
8253 return;
8254 }
8255 container.particles.remove(particle, undefined, true);
8256 }
8257 out(particle, direction) {
8258 const container = this.container;
8259 if (isPointInside(particle.position, container.canvas.size, particle.getRadius(), direction)) {
8260 return;
8261 }
8262 const wrap = particle.options.move.warp, canvasSize = container.canvas.size, newPos = {
8263 bottom: canvasSize.height + particle.getRadius() + particle.offset.y,
8264 left: -particle.getRadius() - particle.offset.x,
8265 right: canvasSize.width + particle.getRadius() + particle.offset.x,
8266 top: -particle.getRadius() - particle.offset.y
8267 }, sizeValue = particle.getRadius(), nextBounds = calculateBounds(particle.position, sizeValue);
8268 if (direction === OutModeDirection.right && nextBounds.left > canvasSize.width + particle.offset.x) {
8269 particle.position.x = newPos.left;
8270 particle.initialPosition.x = particle.position.x;
8271 if (!wrap) {
8272 particle.position.y = Math.random() * canvasSize.height;
8273 particle.initialPosition.y = particle.position.y;
8274 }
8275 } else if (direction === OutModeDirection.left && nextBounds.right < -particle.offset.x) {
8276 particle.position.x = newPos.right;
8277 particle.initialPosition.x = particle.position.x;
8278 if (!wrap) {
8279 particle.position.y = Math.random() * canvasSize.height;
8280 particle.initialPosition.y = particle.position.y;
8281 }
8282 }
8283 if (direction === OutModeDirection.bottom && nextBounds.top > canvasSize.height + particle.offset.y) {
8284 if (!wrap) {
8285 particle.position.x = Math.random() * canvasSize.width;
8286 particle.initialPosition.x = particle.position.x;
8287 }
8288 particle.position.y = newPos.top;
8289 particle.initialPosition.y = particle.position.y;
8290 } else if (direction === OutModeDirection.top && nextBounds.bottom < -particle.offset.y) {
8291 if (!wrap) {
8292 particle.position.x = Math.random() * canvasSize.width;
8293 particle.initialPosition.x = particle.position.x;
8294 }
8295 particle.position.y = newPos.bottom;
8296 particle.initialPosition.y = particle.position.y;
8297 }
8298 }
8299 bounce(particle, delta, direction, outMode) {
8300 const container = this.container;
8301 let handled = false;
8302 for (const [, plugin] of container.plugins) {
8303 if (plugin.particleBounce !== undefined) {
8304 handled = plugin.particleBounce(particle, delta, direction);
8305 }
8306 if (handled) {
8307 break;
8308 }
8309 }
8310 if (handled) {
8311 return;
8312 }
8313 const pos = particle.getPosition(), offset = particle.offset, size = particle.getRadius(), bounds = calculateBounds(pos, size), canvasSize = container.canvas.size;
8314 bounceHorizontal({
8315 particle,
8316 outMode,
8317 direction,
8318 bounds,
8319 canvasSize,
8320 offset,
8321 size
8322 });
8323 bounceVertical({
8324 particle,
8325 outMode,
8326 direction,
8327 bounds,
8328 canvasSize,
8329 offset,
8330 size
8331 });
8332 }
8333 none(particle, direction) {
8334 if (particle.options.move.distance.horizontal && (direction === OutModeDirection.left || direction === OutModeDirection.right) || particle.options.move.distance.vertical && (direction === OutModeDirection.top || direction === OutModeDirection.bottom)) {
8335 return;
8336 }
8337 const gravityOptions = particle.options.move.gravity, container = this.container;
8338 const canvasSize = container.canvas.size;
8339 const pRadius = particle.getRadius();
8340 if (!gravityOptions.enable) {
8341 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) {
8342 return;
8343 }
8344 if (!isPointInside(particle.position, container.canvas.size, pRadius, direction)) {
8345 container.particles.remove(particle);
8346 }
8347 } else {
8348 const position = particle.position;
8349 if (!gravityOptions.inverse && position.y > canvasSize.height + pRadius && direction === OutModeDirection.bottom || gravityOptions.inverse && position.y < -pRadius && direction === OutModeDirection.top) {
8350 container.particles.remove(particle);
8351 }
8352 }
8353 }
8354 }
8355 function loadOutModesUpdater(tsParticles) {
8356 tsParticles.addParticleUpdater("outModes", (container => new OutOfCanvasUpdater(container)));
8357 }
8358 class Repulser extends ExternalInteractorBase {
8359 constructor(container) {
8360 super(container);
8361 }
8362 isEnabled() {
8363 const container = this.container, options = container.actualOptions, mouse = container.interactivity.mouse, events = options.interactivity.events, divs = events.onDiv, divRepulse = isDivModeEnabled(DivMode.repulse, divs);
8364 if (!(divRepulse || events.onHover.enable && mouse.position || events.onClick.enable && mouse.clickPosition)) {
8365 return false;
8366 }
8367 const hoverMode = events.onHover.mode, clickMode = events.onClick.mode;
8368 return isInArray(HoverMode.repulse, hoverMode) || isInArray(ClickMode.repulse, clickMode) || divRepulse;
8369 }
8370 reset() {}
8371 interact() {
8372 const container = this.container, options = container.actualOptions, mouseMoveStatus = container.interactivity.status === Constants.mouseMoveEvent, events = options.interactivity.events, hoverEnabled = events.onHover.enable, hoverMode = events.onHover.mode, clickEnabled = events.onClick.enable, clickMode = events.onClick.mode, divs = events.onDiv;
8373 if (mouseMoveStatus && hoverEnabled && isInArray(HoverMode.repulse, hoverMode)) {
8374 this.hoverRepulse();
8375 } else if (clickEnabled && isInArray(ClickMode.repulse, clickMode)) {
8376 this.clickRepulse();
8377 } else {
8378 divModeExecute(DivMode.repulse, divs, ((selector, div) => this.singleSelectorRepulse(selector, div)));
8379 }
8380 }
8381 singleSelectorRepulse(selector, div) {
8382 const container = this.container, query = document.querySelectorAll(selector);
8383 if (!query.length) {
8384 return;
8385 }
8386 query.forEach((item => {
8387 const elem = item, pxRatio = container.retina.pixelRatio, pos = {
8388 x: (elem.offsetLeft + elem.offsetWidth / 2) * pxRatio,
8389 y: (elem.offsetTop + elem.offsetHeight / 2) * pxRatio
8390 }, repulseRadius = elem.offsetWidth / 2 * pxRatio, area = div.type === DivType.circle ? new Circle(pos.x, pos.y, repulseRadius) : new Rectangle(elem.offsetLeft * pxRatio, elem.offsetTop * pxRatio, elem.offsetWidth * pxRatio, elem.offsetHeight * pxRatio), divs = container.actualOptions.interactivity.modes.repulse.divs, divRepulse = divMode(divs, elem);
8391 this.processRepulse(pos, repulseRadius, area, divRepulse);
8392 }));
8393 }
8394 hoverRepulse() {
8395 const container = this.container, mousePos = container.interactivity.mouse.position;
8396 if (!mousePos) {
8397 return;
8398 }
8399 const repulseRadius = container.retina.repulseModeDistance;
8400 this.processRepulse(mousePos, repulseRadius, new Circle(mousePos.x, mousePos.y, repulseRadius));
8401 }
8402 processRepulse(position, repulseRadius, area, divRepulse) {
8403 var _a;
8404 const container = this.container, query = container.particles.quadTree.query(area), repulseOptions = container.actualOptions.interactivity.modes.repulse;
8405 for (const particle of query) {
8406 const {dx, dy, distance} = getDistances(particle.position, position), velocity = ((_a = divRepulse === null || divRepulse === void 0 ? void 0 : divRepulse.speed) !== null && _a !== void 0 ? _a : repulseOptions.speed) * repulseOptions.factor, repulseFactor = clamp(calcEasing(1 - distance / repulseRadius, repulseOptions.easing) * velocity, 0, repulseOptions.maxSpeed), normVec = Vector.create(distance === 0 ? velocity : dx / distance * repulseFactor, distance === 0 ? velocity : dy / distance * repulseFactor);
8407 particle.position.addTo(normVec);
8408 }
8409 }
8410 clickRepulse() {
8411 const container = this.container;
8412 if (!container.repulse.finish) {
8413 if (!container.repulse.count) {
8414 container.repulse.count = 0;
8415 }
8416 container.repulse.count++;
8417 if (container.repulse.count === container.particles.count) {
8418 container.repulse.finish = true;
8419 }
8420 }
8421 if (container.repulse.clicking) {
8422 const repulseDistance = container.retina.repulseModeDistance, repulseRadius = Math.pow(repulseDistance / 6, 3), mouseClickPos = container.interactivity.mouse.clickPosition;
8423 if (mouseClickPos === undefined) {
8424 return;
8425 }
8426 const range = new Circle(mouseClickPos.x, mouseClickPos.y, repulseRadius), query = container.particles.quadTree.query(range);
8427 for (const particle of query) {
8428 const {dx, dy, distance} = getDistances(mouseClickPos, particle.position), d = distance ** 2, velocity = container.actualOptions.interactivity.modes.repulse.speed, force = -repulseRadius * velocity / d;
8429 if (d <= repulseRadius) {
8430 container.repulse.particles.push(particle);
8431 const vect = Vector.create(dx, dy);
8432 vect.length = force;
8433 particle.velocity.setTo(vect);
8434 }
8435 }
8436 } else if (container.repulse.clicking === false) {
8437 for (const particle of container.repulse.particles) {
8438 particle.velocity.setTo(particle.initialVelocity);
8439 }
8440 container.repulse.particles = [];
8441 }
8442 }
8443 }
8444 function loadExternalRepulseInteraction(tsParticles) {
8445 tsParticles.addInteractor("externalRepulse", (container => new Repulser(container)));
8446 }
8447 class LineDrawer {
8448 getSidesCount() {
8449 return 1;
8450 }
8451 draw(context, particle, radius) {
8452 context.moveTo(-radius / 2, 0);
8453 context.lineTo(radius / 2, 0);
8454 }
8455 }
8456 function loadLineShape(tsParticles) {
8457 tsParticles.addShape("line", new LineDrawer);
8458 }
8459 class Bouncer extends ExternalInteractorBase {
8460 constructor(container) {
8461 super(container);
8462 }
8463 isEnabled() {
8464 const container = this.container, options = container.actualOptions, mouse = container.interactivity.mouse, events = options.interactivity.events, divs = events.onDiv;
8465 return mouse.position && events.onHover.enable && isInArray(HoverMode.bounce, events.onHover.mode) || isDivModeEnabled(DivMode.bounce, divs);
8466 }
8467 interact() {
8468 const container = this.container, options = container.actualOptions, events = options.interactivity.events, mouseMoveStatus = container.interactivity.status === Constants.mouseMoveEvent, hoverEnabled = events.onHover.enable, hoverMode = events.onHover.mode, divs = events.onDiv;
8469 if (mouseMoveStatus && hoverEnabled && isInArray(HoverMode.bounce, hoverMode)) {
8470 this.processMouseBounce();
8471 } else {
8472 divModeExecute(DivMode.bounce, divs, ((selector, div) => this.singleSelectorBounce(selector, div)));
8473 }
8474 }
8475 reset() {}
8476 processMouseBounce() {
8477 const container = this.container, pxRatio = container.retina.pixelRatio, tolerance = 10 * pxRatio, mousePos = container.interactivity.mouse.position, radius = container.retina.bounceModeDistance;
8478 if (mousePos) {
8479 this.processBounce(mousePos, radius, new Circle(mousePos.x, mousePos.y, radius + tolerance));
8480 }
8481 }
8482 singleSelectorBounce(selector, div) {
8483 const container = this.container;
8484 const query = document.querySelectorAll(selector);
8485 if (!query.length) {
8486 return;
8487 }
8488 query.forEach((item => {
8489 const elem = item, pxRatio = container.retina.pixelRatio, pos = {
8490 x: (elem.offsetLeft + elem.offsetWidth / 2) * pxRatio,
8491 y: (elem.offsetTop + elem.offsetHeight / 2) * pxRatio
8492 }, radius = elem.offsetWidth / 2 * pxRatio, tolerance = 10 * pxRatio;
8493 const area = div.type === DivType.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);
8494 this.processBounce(pos, radius, area);
8495 }));
8496 }
8497 processBounce(position, radius, area) {
8498 const query = this.container.particles.quadTree.query(area);
8499 for (const particle of query) {
8500 if (area instanceof Circle) {
8501 circleBounce(circleBounceDataFromParticle(particle), {
8502 position,
8503 radius,
8504 mass: radius ** 2 * Math.PI / 2,
8505 velocity: Vector.origin,
8506 factor: Vector.origin
8507 });
8508 } else if (area instanceof Rectangle) {
8509 rectBounce(particle, calculateBounds(position, radius));
8510 }
8511 }
8512 }
8513 }
8514 function loadExternalBounceInteraction(tsParticles) {
8515 tsParticles.addInteractor("externalBounce", (container => new Bouncer(container)));
8516 }
8517 const validTypes = [ "text", "character", "char" ];
8518 class TextDrawer {
8519 getSidesCount() {
8520 return 12;
8521 }
8522 async init(container) {
8523 const options = container.actualOptions;
8524 if (validTypes.find((t => isInArray(t, options.particles.shape.type)))) {
8525 const shapeOptions = validTypes.map((t => options.particles.shape.options[t])).find((t => !!t));
8526 if (shapeOptions instanceof Array) {
8527 const promises = [];
8528 for (const character of shapeOptions) {
8529 promises.push(loadFont(character));
8530 }
8531 await Promise.allSettled(promises);
8532 } else {
8533 if (shapeOptions !== undefined) {
8534 await loadFont(shapeOptions);
8535 }
8536 }
8537 }
8538 }
8539 draw(context, particle, radius, opacity) {
8540 var _a, _b, _c;
8541 const character = particle.shapeData;
8542 if (character === undefined) {
8543 return;
8544 }
8545 const textData = character.value;
8546 if (textData === undefined) {
8547 return;
8548 }
8549 const textParticle = particle;
8550 if (textParticle.text === undefined) {
8551 textParticle.text = textData instanceof Array ? itemFromArray(textData, particle.randomIndexData) : textData;
8552 }
8553 const text = textParticle.text;
8554 const style = (_a = character.style) !== null && _a !== void 0 ? _a : "";
8555 const weight = (_b = character.weight) !== null && _b !== void 0 ? _b : "400";
8556 const size = Math.round(radius) * 2;
8557 const font = (_c = character.font) !== null && _c !== void 0 ? _c : "Verdana";
8558 const fill = particle.fill;
8559 const offsetX = text.length * radius / 2;
8560 context.font = `${style} ${weight} ${size}px "${font}"`;
8561 const pos = {
8562 x: -offsetX,
8563 y: radius / 2
8564 };
8565 context.globalAlpha = opacity;
8566 if (fill) {
8567 context.fillText(text, pos.x, pos.y);
8568 } else {
8569 context.strokeText(text, pos.x, pos.y);
8570 }
8571 context.globalAlpha = 1;
8572 }
8573 }
8574 function loadTextShape(tsParticles) {
8575 const drawer = new TextDrawer;
8576 for (const type of validTypes) {
8577 tsParticles.addShape(type, drawer);
8578 }
8579 }
8580 function getLinkDistance(pos1, pos2, optDistance, canvasSize, warp) {
8581 let distance = getDistance(pos1, pos2);
8582 if (!warp || distance <= optDistance) {
8583 return distance;
8584 }
8585 const pos2NE = {
8586 x: pos2.x - canvasSize.width,
8587 y: pos2.y
8588 };
8589 distance = getDistance(pos1, pos2NE);
8590 if (distance <= optDistance) {
8591 return distance;
8592 }
8593 const pos2SE = {
8594 x: pos2.x - canvasSize.width,
8595 y: pos2.y - canvasSize.height
8596 };
8597 distance = getDistance(pos1, pos2SE);
8598 if (distance <= optDistance) {
8599 return distance;
8600 }
8601 const pos2SW = {
8602 x: pos2.x,
8603 y: pos2.y - canvasSize.height
8604 };
8605 distance = getDistance(pos1, pos2SW);
8606 return distance;
8607 }
8608 class Linker extends ParticlesInteractorBase {
8609 constructor(container) {
8610 super(container);
8611 }
8612 isEnabled(particle) {
8613 return particle.options.links.enable;
8614 }
8615 reset() {}
8616 interact(p1) {
8617 var _a;
8618 p1.links = [];
8619 const pos1 = p1.getPosition();
8620 const container = this.container;
8621 const canvasSize = container.canvas.size;
8622 if (pos1.x < 0 || pos1.y < 0 || pos1.x > canvasSize.width || pos1.y > canvasSize.height) {
8623 return;
8624 }
8625 const linkOpt1 = p1.options.links;
8626 const optOpacity = linkOpt1.opacity;
8627 const optDistance = (_a = p1.retina.linksDistance) !== null && _a !== void 0 ? _a : container.retina.linksDistance;
8628 const warp = linkOpt1.warp;
8629 const range = warp ? new CircleWarp(pos1.x, pos1.y, optDistance, canvasSize) : new Circle(pos1.x, pos1.y, optDistance);
8630 const query = container.particles.quadTree.query(range);
8631 for (const p2 of query) {
8632 const linkOpt2 = p2.options.links;
8633 if (p1 === p2 || !linkOpt2.enable || linkOpt1.id !== linkOpt2.id || p2.spawning || p2.destroyed || p1.links.map((t => t.destination)).indexOf(p2) !== -1 || p2.links.map((t => t.destination)).indexOf(p1) !== -1) {
8634 continue;
8635 }
8636 const pos2 = p2.getPosition();
8637 if (pos2.x < 0 || pos2.y < 0 || pos2.x > canvasSize.width || pos2.y > canvasSize.height) {
8638 continue;
8639 }
8640 const distance = getLinkDistance(pos1, pos2, optDistance, canvasSize, warp && linkOpt2.warp);
8641 if (distance > optDistance) {
8642 return;
8643 }
8644 const opacityLine = (1 - distance / optDistance) * optOpacity;
8645 this.setColor(p1);
8646 p1.links.push({
8647 destination: p2,
8648 opacity: opacityLine
8649 });
8650 }
8651 }
8652 setColor(p1) {
8653 const container = this.container;
8654 const linksOptions = p1.options.links;
8655 let linkColor = linksOptions.id === undefined ? container.particles.linksColor : container.particles.linksColors.get(linksOptions.id);
8656 if (!linkColor) {
8657 const optColor = linksOptions.color;
8658 linkColor = getLinkRandomColor(optColor, linksOptions.blink, linksOptions.consent);
8659 if (linksOptions.id === undefined) {
8660 container.particles.linksColor = linkColor;
8661 } else {
8662 container.particles.linksColors.set(linksOptions.id, linkColor);
8663 }
8664 }
8665 }
8666 }
8667 class LinkInstance {
8668 constructor(container) {
8669 this.container = container;
8670 }
8671 particleCreated(particle) {
8672 const linkParticle = particle;
8673 linkParticle.links = [];
8674 }
8675 particleDestroyed(particle) {
8676 const linkParticle = particle;
8677 linkParticle.links = [];
8678 }
8679 drawParticle(context, particle) {
8680 const linkParticle = particle;
8681 const container = this.container;
8682 const particles = container.particles;
8683 const pOptions = particle.options;
8684 if (linkParticle.links.length > 0) {
8685 context.save();
8686 const p1Links = linkParticle.links.filter((l => {
8687 const linkFreq = container.particles.getLinkFrequency(linkParticle, l.destination);
8688 return linkFreq <= pOptions.links.frequency;
8689 }));
8690 for (const link of p1Links) {
8691 const p2 = link.destination;
8692 if (pOptions.links.triangles.enable) {
8693 const links = p1Links.map((l => l.destination));
8694 const vertices = p2.links.filter((t => {
8695 const linkFreq = container.particles.getLinkFrequency(p2, t.destination);
8696 return linkFreq <= p2.options.links.frequency && links.indexOf(t.destination) >= 0;
8697 }));
8698 if (vertices.length) {
8699 for (const vertex of vertices) {
8700 const p3 = vertex.destination;
8701 const triangleFreq = particles.getTriangleFrequency(linkParticle, p2, p3);
8702 if (triangleFreq > pOptions.links.triangles.frequency) {
8703 continue;
8704 }
8705 this.drawLinkTriangle(linkParticle, link, vertex);
8706 }
8707 }
8708 }
8709 if (link.opacity > 0 && container.retina.linksWidth > 0) {
8710 this.drawLinkLine(linkParticle, link);
8711 }
8712 }
8713 context.restore();
8714 }
8715 }
8716 drawLinkTriangle(p1, link1, link2) {
8717 var _a;
8718 const container = this.container;
8719 const options = container.actualOptions;
8720 const p2 = link1.destination;
8721 const p3 = link2.destination;
8722 const triangleOptions = p1.options.links.triangles;
8723 const opacityTriangle = (_a = triangleOptions.opacity) !== null && _a !== void 0 ? _a : (link1.opacity + link2.opacity) / 2;
8724 if (opacityTriangle <= 0) {
8725 return;
8726 }
8727 const pos1 = p1.getPosition();
8728 const pos2 = p2.getPosition();
8729 const pos3 = p3.getPosition();
8730 container.canvas.draw((ctx => {
8731 if (getDistance(pos1, pos2) > container.retina.linksDistance || getDistance(pos3, pos2) > container.retina.linksDistance || getDistance(pos3, pos1) > container.retina.linksDistance) {
8732 return;
8733 }
8734 let colorTriangle = colorToRgb(triangleOptions.color);
8735 if (!colorTriangle) {
8736 const linksOptions = p1.options.links;
8737 const linkColor = linksOptions.id !== undefined ? container.particles.linksColors.get(linksOptions.id) : container.particles.linksColor;
8738 colorTriangle = getLinkColor(p1, p2, linkColor);
8739 }
8740 if (!colorTriangle) {
8741 return;
8742 }
8743 drawLinkTriangle(ctx, pos1, pos2, pos3, options.backgroundMask.enable, options.backgroundMask.composite, colorTriangle, opacityTriangle);
8744 }));
8745 }
8746 drawLinkLine(p1, link) {
8747 const container = this.container;
8748 const options = container.actualOptions;
8749 const p2 = link.destination;
8750 let opacity = link.opacity;
8751 const pos1 = p1.getPosition();
8752 const pos2 = p2.getPosition();
8753 container.canvas.draw((ctx => {
8754 var _a, _b;
8755 let colorLine;
8756 const twinkle = p1.options.twinkle.lines;
8757 if (twinkle.enable) {
8758 const twinkleFreq = twinkle.frequency;
8759 const twinkleRgb = colorToRgb(twinkle.color);
8760 const twinkling = Math.random() < twinkleFreq;
8761 if (twinkling && twinkleRgb !== undefined) {
8762 colorLine = twinkleRgb;
8763 opacity = twinkle.opacity;
8764 }
8765 }
8766 if (!colorLine) {
8767 const linksOptions = p1.options.links;
8768 const linkColor = linksOptions.id !== undefined ? container.particles.linksColors.get(linksOptions.id) : container.particles.linksColor;
8769 colorLine = getLinkColor(p1, p2, linkColor);
8770 }
8771 if (!colorLine) {
8772 return;
8773 }
8774 const width = (_a = p1.retina.linksWidth) !== null && _a !== void 0 ? _a : container.retina.linksWidth;
8775 const maxDistance = (_b = p1.retina.linksDistance) !== null && _b !== void 0 ? _b : container.retina.linksDistance;
8776 drawLinkLine(ctx, width, pos1, pos2, maxDistance, container.canvas.size, p1.options.links.warp, options.backgroundMask.enable, options.backgroundMask.composite, colorLine, opacity, p1.options.links.shadow);
8777 }));
8778 }
8779 }
8780 class Plugin {
8781 constructor() {
8782 this.id = "links";
8783 }
8784 getPlugin(container) {
8785 return new LinkInstance(container);
8786 }
8787 needsPlugin() {
8788 return true;
8789 }
8790 loadOptions() {}
8791 }
8792 function loadPlugin(tsParticles) {
8793 const plugin = new Plugin;
8794 tsParticles.addPlugin(plugin);
8795 }
8796 function loadInteraction(tsParticles) {
8797 tsParticles.addInteractor("particlesLinks", (container => new Linker(container)));
8798 }
8799 function loadParticlesLinksInteraction(tsParticles) {
8800 loadInteraction(tsParticles);
8801 loadPlugin(tsParticles);
8802 }
8803 function SizeUpdater_checkDestroy(particle, value, minValue, maxValue) {
8804 switch (particle.options.size.animation.destroy) {
8805 case DestroyType.max:
8806 if (value >= maxValue) {
8807 particle.destroy();
8808 }
8809 break;
8810
8811 case DestroyType.min:
8812 if (value <= minValue) {
8813 particle.destroy();
8814 }
8815 break;
8816 }
8817 }
8818 function updateSize(particle, delta) {
8819 var _a, _b, _c, _d;
8820 const sizeVelocity = ((_a = particle.size.velocity) !== null && _a !== void 0 ? _a : 0) * delta.factor;
8821 const minValue = particle.size.min;
8822 const maxValue = particle.size.max;
8823 if (!(!particle.destroyed && particle.size.enable && (((_b = particle.size.loops) !== null && _b !== void 0 ? _b : 0) <= 0 || ((_c = particle.size.loops) !== null && _c !== void 0 ? _c : 0) < ((_d = particle.size.maxLoops) !== null && _d !== void 0 ? _d : 0)))) {
8824 return;
8825 }
8826 switch (particle.size.status) {
8827 case AnimationStatus.increasing:
8828 if (particle.size.value >= maxValue) {
8829 particle.size.status = AnimationStatus.decreasing;
8830 if (!particle.size.loops) {
8831 particle.size.loops = 0;
8832 }
8833 particle.size.loops++;
8834 } else {
8835 particle.size.value += sizeVelocity;
8836 }
8837 break;
8838
8839 case AnimationStatus.decreasing:
8840 if (particle.size.value <= minValue) {
8841 particle.size.status = AnimationStatus.increasing;
8842 if (!particle.size.loops) {
8843 particle.size.loops = 0;
8844 }
8845 particle.size.loops++;
8846 } else {
8847 particle.size.value -= sizeVelocity;
8848 }
8849 }
8850 SizeUpdater_checkDestroy(particle, particle.size.value, minValue, maxValue);
8851 if (!particle.destroyed) {
8852 particle.size.value = clamp(particle.size.value, minValue, maxValue);
8853 }
8854 }
8855 class SizeUpdater {
8856 init() {}
8857 isEnabled(particle) {
8858 var _a, _b, _c;
8859 return !particle.destroyed && !particle.spawning && particle.size.enable && (((_a = particle.size.loops) !== null && _a !== void 0 ? _a : 0) <= 0 || ((_b = particle.size.loops) !== null && _b !== void 0 ? _b : 0) < ((_c = particle.size.maxLoops) !== null && _c !== void 0 ? _c : 0));
8860 }
8861 update(particle, delta) {
8862 if (!this.isEnabled(particle)) {
8863 return;
8864 }
8865 updateSize(particle, delta);
8866 }
8867 }
8868 function loadSizeUpdater(tsParticles) {
8869 tsParticles.addParticleUpdater("size", (() => new SizeUpdater));
8870 }
8871 function loadSlim(tsParticles) {
8872 loadExternalAttractInteraction(tsParticles);
8873 loadExternalBounceInteraction(tsParticles);
8874 loadExternalBubbleInteraction(tsParticles);
8875 loadExternalConnectInteraction(tsParticles);
8876 loadExternalGrabInteraction(tsParticles);
8877 loadExternalRepulseInteraction(tsParticles);
8878 loadParticlesAttractInteraction(tsParticles);
8879 loadParticlesCollisionsInteraction(tsParticles);
8880 loadParticlesLinksInteraction(tsParticles);
8881 loadCircleShape(tsParticles);
8882 loadImageShape(tsParticles);
8883 loadLineShape(tsParticles);
8884 loadPolygonShape(tsParticles);
8885 loadSquareShape(tsParticles);
8886 loadStarShape(tsParticles);
8887 loadTextShape(tsParticles);
8888 loadLifeUpdater(tsParticles);
8889 loadOpacityUpdater(tsParticles);
8890 loadSizeUpdater(tsParticles);
8891 loadAngleUpdater(tsParticles);
8892 loadColorUpdater(tsParticles);
8893 loadStrokeColorUpdater(tsParticles);
8894 loadOutModesUpdater(tsParticles);
8895 }
8896 class TrailMaker extends ExternalInteractorBase {
8897 constructor(container) {
8898 super(container);
8899 this.delay = 0;
8900 }
8901 interact(delta) {
8902 var _a, _b, _c, _d;
8903 if (!this.container.retina.reduceFactor) {
8904 return;
8905 }
8906 const container = this.container, options = container.actualOptions, trailOptions = options.interactivity.modes.trail, optDelay = trailOptions.delay * 1e3 / this.container.retina.reduceFactor;
8907 if (this.delay < optDelay) {
8908 this.delay += delta.value;
8909 }
8910 if (this.delay < optDelay) {
8911 return;
8912 }
8913 let canEmit = true;
8914 if (trailOptions.pauseOnStop) {
8915 if (container.interactivity.mouse.position === this.lastPosition || ((_a = container.interactivity.mouse.position) === null || _a === void 0 ? void 0 : _a.x) === ((_b = this.lastPosition) === null || _b === void 0 ? void 0 : _b.x) && ((_c = container.interactivity.mouse.position) === null || _c === void 0 ? void 0 : _c.y) === ((_d = this.lastPosition) === null || _d === void 0 ? void 0 : _d.y)) {
8916 canEmit = false;
8917 }
8918 }
8919 if (container.interactivity.mouse.position) {
8920 this.lastPosition = {
8921 x: container.interactivity.mouse.position.x,
8922 y: container.interactivity.mouse.position.y
8923 };
8924 } else {
8925 delete this.lastPosition;
8926 }
8927 if (canEmit) {
8928 container.particles.push(trailOptions.quantity, container.interactivity.mouse, trailOptions.particles);
8929 }
8930 this.delay -= optDelay;
8931 }
8932 isEnabled() {
8933 const container = this.container, options = container.actualOptions, mouse = container.interactivity.mouse, events = options.interactivity.events;
8934 return mouse.clicking && mouse.inside && !!mouse.position && isInArray(ClickMode.trail, events.onClick.mode) || mouse.inside && !!mouse.position && isInArray(HoverMode.trail, events.onHover.mode);
8935 }
8936 reset() {}
8937 }
8938 function loadExternalTrailInteraction(tsParticles) {
8939 tsParticles.addInteractor("externalTrail", (container => new TrailMaker(container)));
8940 }
8941 function updateTilt(particle, delta) {
8942 var _a;
8943 if (!particle.tilt) {
8944 return;
8945 }
8946 const tilt = particle.options.tilt;
8947 const tiltAnimation = tilt.animation;
8948 const speed = ((_a = particle.tilt.velocity) !== null && _a !== void 0 ? _a : 0) * delta.factor;
8949 const max = 2 * Math.PI;
8950 if (!tiltAnimation.enable) {
8951 return;
8952 }
8953 switch (particle.tilt.status) {
8954 case AnimationStatus.increasing:
8955 particle.tilt.value += speed;
8956 if (particle.tilt.value > max) {
8957 particle.tilt.value -= max;
8958 }
8959 break;
8960
8961 case AnimationStatus.decreasing:
8962 default:
8963 particle.tilt.value -= speed;
8964 if (particle.tilt.value < 0) {
8965 particle.tilt.value += max;
8966 }
8967 break;
8968 }
8969 }
8970 class TiltUpdater {
8971 constructor(container) {
8972 this.container = container;
8973 }
8974 init(particle) {
8975 const tiltOptions = particle.options.tilt;
8976 particle.tilt = {
8977 enable: tiltOptions.enable,
8978 value: getRangeValue(tiltOptions.value) * Math.PI / 180,
8979 sinDirection: Math.random() >= .5 ? 1 : -1,
8980 cosDirection: Math.random() >= .5 ? 1 : -1
8981 };
8982 let tiltDirection = tiltOptions.direction;
8983 if (tiltDirection === TiltDirection.random) {
8984 const index = Math.floor(Math.random() * 2);
8985 tiltDirection = index > 0 ? TiltDirection.counterClockwise : TiltDirection.clockwise;
8986 }
8987 switch (tiltDirection) {
8988 case TiltDirection.counterClockwise:
8989 case "counterClockwise":
8990 particle.tilt.status = AnimationStatus.decreasing;
8991 break;
8992
8993 case TiltDirection.clockwise:
8994 particle.tilt.status = AnimationStatus.increasing;
8995 break;
8996 }
8997 const tiltAnimation = particle.options.tilt.animation;
8998 if (tiltAnimation.enable) {
8999 particle.tilt.velocity = tiltAnimation.speed / 360 * this.container.retina.reduceFactor;
9000 if (!tiltAnimation.sync) {
9001 particle.tilt.velocity *= Math.random();
9002 }
9003 }
9004 }
9005 isEnabled(particle) {
9006 const tilt = particle.options.tilt;
9007 const tiltAnimation = tilt.animation;
9008 return !particle.destroyed && !particle.spawning && tiltAnimation.enable;
9009 }
9010 update(particle, delta) {
9011 if (!this.isEnabled(particle)) {
9012 return;
9013 }
9014 updateTilt(particle, delta);
9015 }
9016 }
9017 function loadTiltUpdater(tsParticles) {
9018 tsParticles.addParticleUpdater("tilt", (container => new TiltUpdater(container)));
9019 }
9020 function updateWobble(particle, delta) {
9021 var _a;
9022 const wobble = particle.options.wobble;
9023 if (!wobble.enable || !particle.wobble) {
9024 return;
9025 }
9026 const speed = particle.wobble.speed * delta.factor;
9027 const distance = ((_a = particle.retina.wobbleDistance) !== null && _a !== void 0 ? _a : 0) * delta.factor / (1e3 / 60);
9028 const max = 2 * Math.PI;
9029 particle.wobble.angle += speed;
9030 if (particle.wobble.angle > max) {
9031 particle.wobble.angle -= max;
9032 }
9033 particle.position.x += distance * Math.cos(particle.wobble.angle);
9034 particle.position.y += distance * Math.abs(Math.sin(particle.wobble.angle));
9035 }
9036 class WobbleUpdater {
9037 constructor(container) {
9038 this.container = container;
9039 }
9040 init(particle) {
9041 const wobbleOpt = particle.options.wobble;
9042 if (wobbleOpt.enable) {
9043 particle.wobble = {
9044 angle: Math.random() * Math.PI * 2,
9045 speed: getRangeValue(wobbleOpt.speed) / 360
9046 };
9047 } else {
9048 particle.wobble = {
9049 angle: 0,
9050 speed: 0
9051 };
9052 }
9053 particle.retina.wobbleDistance = getRangeValue(wobbleOpt.distance) * this.container.retina.pixelRatio;
9054 }
9055 isEnabled(particle) {
9056 return !particle.destroyed && !particle.spawning && particle.options.wobble.enable;
9057 }
9058 update(particle, delta) {
9059 if (!this.isEnabled(particle)) {
9060 return;
9061 }
9062 updateWobble(particle, delta);
9063 }
9064 }
9065 function loadWobbleUpdater(tsParticles) {
9066 tsParticles.addParticleUpdater("wobble", (container => new WobbleUpdater(container)));
9067 }
9068 class AbsorberInstance {
9069 constructor(absorbers, container, options, position) {
9070 var _a, _b, _c;
9071 this.absorbers = absorbers;
9072 this.container = container;
9073 this.initialPosition = position ? Vector.create(position.x, position.y) : undefined;
9074 this.options = options;
9075 this.dragging = false;
9076 this.name = this.options.name;
9077 this.opacity = this.options.opacity;
9078 this.size = getRangeValue(options.size.value) * container.retina.pixelRatio;
9079 this.mass = this.size * options.size.density * container.retina.reduceFactor;
9080 const limit = options.size.limit;
9081 this.limit = limit !== undefined ? limit * container.retina.pixelRatio * container.retina.reduceFactor : limit;
9082 const color = typeof options.color === "string" ? {
9083 value: options.color
9084 } : options.color;
9085 this.color = (_a = colorToRgb(color)) !== null && _a !== void 0 ? _a : {
9086 b: 0,
9087 g: 0,
9088 r: 0
9089 };
9090 this.position = (_c = (_b = this.initialPosition) === null || _b === void 0 ? void 0 : _b.copy()) !== null && _c !== void 0 ? _c : this.calcPosition();
9091 }
9092 attract(particle) {
9093 const container = this.container;
9094 const options = this.options;
9095 if (options.draggable) {
9096 const mouse = container.interactivity.mouse;
9097 if (mouse.clicking && mouse.downPosition) {
9098 const mouseDist = getDistance(this.position, mouse.downPosition);
9099 if (mouseDist <= this.size) {
9100 this.dragging = true;
9101 }
9102 } else {
9103 this.dragging = false;
9104 }
9105 if (this.dragging && mouse.position) {
9106 this.position.x = mouse.position.x;
9107 this.position.y = mouse.position.y;
9108 }
9109 }
9110 const pos = particle.getPosition();
9111 const {dx, dy, distance} = getDistances(this.position, pos);
9112 const v = Vector.create(dx, dy);
9113 v.length = this.mass / Math.pow(distance, 2) * container.retina.reduceFactor;
9114 if (distance < this.size + particle.getRadius()) {
9115 const sizeFactor = particle.getRadius() * .033 * container.retina.pixelRatio;
9116 if (this.size > particle.getRadius() && distance < this.size - particle.getRadius() || particle.absorberOrbit !== undefined && particle.absorberOrbit.length < 0) {
9117 if (options.destroy) {
9118 particle.destroy();
9119 } else {
9120 particle.needsNewPosition = true;
9121 this.updateParticlePosition(particle, v);
9122 }
9123 } else {
9124 if (options.destroy) {
9125 particle.size.value -= sizeFactor;
9126 }
9127 this.updateParticlePosition(particle, v);
9128 }
9129 if (this.limit === undefined || this.size < this.limit) {
9130 this.size += sizeFactor;
9131 }
9132 this.mass += sizeFactor * this.options.size.density * container.retina.reduceFactor;
9133 } else {
9134 this.updateParticlePosition(particle, v);
9135 }
9136 }
9137 resize() {
9138 const initialPosition = this.initialPosition;
9139 this.position = initialPosition && isPointInside(initialPosition, this.container.canvas.size) ? initialPosition : this.calcPosition();
9140 }
9141 draw(context) {
9142 context.translate(this.position.x, this.position.y);
9143 context.beginPath();
9144 context.arc(0, 0, this.size, 0, Math.PI * 2, false);
9145 context.closePath();
9146 context.fillStyle = getStyleFromRgb(this.color, this.opacity);
9147 context.fill();
9148 }
9149 calcPosition() {
9150 var _a, _b;
9151 const container = this.container;
9152 const percentPosition = this.options.position;
9153 return Vector.create(((_a = percentPosition === null || percentPosition === void 0 ? void 0 : percentPosition.x) !== null && _a !== void 0 ? _a : Math.random() * 100) / 100 * container.canvas.size.width, ((_b = percentPosition === null || percentPosition === void 0 ? void 0 : percentPosition.y) !== null && _b !== void 0 ? _b : Math.random() * 100) / 100 * container.canvas.size.height);
9154 }
9155 updateParticlePosition(particle, v) {
9156 var _a;
9157 if (particle.destroyed) {
9158 return;
9159 }
9160 const container = this.container;
9161 const canvasSize = container.canvas.size;
9162 if (particle.needsNewPosition) {
9163 const pSize = particle.getRadius();
9164 particle.position.x = (canvasSize.width - pSize * 2) * (1 + (Math.random() * .2 - .1)) + pSize;
9165 particle.position.y = (canvasSize.height - pSize * 2) * (1 + (Math.random() * .2 - .1)) + pSize;
9166 particle.needsNewPosition = false;
9167 }
9168 if (this.options.orbits) {
9169 if (particle.absorberOrbit === undefined) {
9170 particle.absorberOrbit = Vector.create(0, 0);
9171 particle.absorberOrbit.length = getDistance(particle.getPosition(), this.position);
9172 particle.absorberOrbit.angle = Math.random() * Math.PI * 2;
9173 }
9174 if (particle.absorberOrbit.length <= this.size && !this.options.destroy) {
9175 const minSize = Math.min(canvasSize.width, canvasSize.height);
9176 particle.absorberOrbit.length = minSize * (1 + (Math.random() * .2 - .1));
9177 }
9178 if (particle.absorberOrbitDirection === undefined) {
9179 particle.absorberOrbitDirection = particle.velocity.x >= 0 ? RotateDirection.clockwise : RotateDirection.counterClockwise;
9180 }
9181 const orbitRadius = particle.absorberOrbit.length;
9182 const orbitAngle = particle.absorberOrbit.angle;
9183 const orbitDirection = particle.absorberOrbitDirection;
9184 particle.velocity.x = 0;
9185 particle.velocity.y = 0;
9186 const updateFunc = {
9187 x: orbitDirection === RotateDirection.clockwise ? Math.cos : Math.sin,
9188 y: orbitDirection === RotateDirection.clockwise ? Math.sin : Math.cos
9189 };
9190 particle.position.x = this.position.x + orbitRadius * updateFunc.x(orbitAngle);
9191 particle.position.y = this.position.y + orbitRadius * updateFunc.y(orbitAngle);
9192 particle.absorberOrbit.length -= v.length;
9193 particle.absorberOrbit.angle += ((_a = particle.retina.moveSpeed) !== null && _a !== void 0 ? _a : 0) * container.retina.pixelRatio / 100 * container.retina.reduceFactor;
9194 } else {
9195 const addV = Vector.origin;
9196 addV.length = v.length;
9197 addV.angle = v.angle;
9198 particle.velocity.addTo(addV);
9199 }
9200 }
9201 }
9202 class AbsorberSize extends ValueWithRandom {
9203 constructor() {
9204 super();
9205 this.density = 5;
9206 this.random.minimumValue = 1;
9207 this.value = 50;
9208 }
9209 load(data) {
9210 if (!data) {
9211 return;
9212 }
9213 super.load(data);
9214 if (data.density !== undefined) {
9215 this.density = data.density;
9216 }
9217 if (data.limit !== undefined) {
9218 this.limit = data.limit;
9219 }
9220 if (data.limit !== undefined) {
9221 this.limit = data.limit;
9222 }
9223 }
9224 }
9225 class Absorber {
9226 constructor() {
9227 this.color = new OptionsColor;
9228 this.color.value = "#000000";
9229 this.draggable = false;
9230 this.opacity = 1;
9231 this.destroy = true;
9232 this.orbits = false;
9233 this.size = new AbsorberSize;
9234 }
9235 load(data) {
9236 if (data === undefined) {
9237 return;
9238 }
9239 if (data.color !== undefined) {
9240 this.color = OptionsColor.create(this.color, data.color);
9241 }
9242 if (data.draggable !== undefined) {
9243 this.draggable = data.draggable;
9244 }
9245 this.name = data.name;
9246 if (data.opacity !== undefined) {
9247 this.opacity = data.opacity;
9248 }
9249 if (data.position !== undefined) {
9250 this.position = {
9251 x: data.position.x,
9252 y: data.position.y
9253 };
9254 }
9255 if (data.size !== undefined) {
9256 this.size.load(data.size);
9257 }
9258 if (data.destroy !== undefined) {
9259 this.destroy = data.destroy;
9260 }
9261 if (data.orbits !== undefined) {
9262 this.orbits = data.orbits;
9263 }
9264 }
9265 }
9266 var AbsorberClickMode;
9267 (function(AbsorberClickMode) {
9268 AbsorberClickMode["absorber"] = "absorber";
9269 })(AbsorberClickMode || (AbsorberClickMode = {}));
9270 class Absorbers {
9271 constructor(container) {
9272 this.container = container;
9273 this.array = [];
9274 this.absorbers = [];
9275 this.interactivityAbsorbers = [];
9276 const overridableContainer = container;
9277 overridableContainer.getAbsorber = idxOrName => idxOrName === undefined || typeof idxOrName === "number" ? this.array[idxOrName || 0] : this.array.find((t => t.name === idxOrName));
9278 overridableContainer.addAbsorber = (options, position) => this.addAbsorber(options, position);
9279 }
9280 init(options) {
9281 var _a, _b;
9282 if (!options) {
9283 return;
9284 }
9285 if (options.absorbers) {
9286 if (options.absorbers instanceof Array) {
9287 this.absorbers = options.absorbers.map((s => {
9288 const tmp = new Absorber;
9289 tmp.load(s);
9290 return tmp;
9291 }));
9292 } else {
9293 if (this.absorbers instanceof Array) {
9294 this.absorbers = new Absorber;
9295 }
9296 this.absorbers.load(options.absorbers);
9297 }
9298 }
9299 const interactivityAbsorbers = (_b = (_a = options.interactivity) === null || _a === void 0 ? void 0 : _a.modes) === null || _b === void 0 ? void 0 : _b.absorbers;
9300 if (interactivityAbsorbers) {
9301 if (interactivityAbsorbers instanceof Array) {
9302 this.interactivityAbsorbers = interactivityAbsorbers.map((s => {
9303 const tmp = new Absorber;
9304 tmp.load(s);
9305 return tmp;
9306 }));
9307 } else {
9308 if (this.interactivityAbsorbers instanceof Array) {
9309 this.interactivityAbsorbers = new Absorber;
9310 }
9311 this.interactivityAbsorbers.load(interactivityAbsorbers);
9312 }
9313 }
9314 if (this.absorbers instanceof Array) {
9315 for (const absorberOptions of this.absorbers) {
9316 this.addAbsorber(absorberOptions);
9317 }
9318 } else {
9319 this.addAbsorber(this.absorbers);
9320 }
9321 }
9322 particleUpdate(particle) {
9323 for (const absorber of this.array) {
9324 absorber.attract(particle);
9325 if (particle.destroyed) {
9326 break;
9327 }
9328 }
9329 }
9330 draw(context) {
9331 for (const absorber of this.array) {
9332 context.save();
9333 absorber.draw(context);
9334 context.restore();
9335 }
9336 }
9337 stop() {
9338 this.array = [];
9339 }
9340 resize() {
9341 for (const absorber of this.array) {
9342 absorber.resize();
9343 }
9344 }
9345 handleClickMode(mode) {
9346 const container = this.container;
9347 const absorberOptions = this.absorbers;
9348 const modeAbsorbers = this.interactivityAbsorbers;
9349 if (mode === AbsorberClickMode.absorber) {
9350 let absorbersModeOptions;
9351 if (modeAbsorbers instanceof Array) {
9352 if (modeAbsorbers.length > 0) {
9353 absorbersModeOptions = itemFromArray(modeAbsorbers);
9354 }
9355 } else {
9356 absorbersModeOptions = modeAbsorbers;
9357 }
9358 const absorbersOptions = absorbersModeOptions !== null && absorbersModeOptions !== void 0 ? absorbersModeOptions : absorberOptions instanceof Array ? itemFromArray(absorberOptions) : absorberOptions;
9359 const aPosition = container.interactivity.mouse.clickPosition;
9360 this.addAbsorber(absorbersOptions, aPosition);
9361 }
9362 }
9363 addAbsorber(options, position) {
9364 const absorber = new AbsorberInstance(this, this.container, options, position);
9365 this.array.push(absorber);
9366 return absorber;
9367 }
9368 removeAbsorber(absorber) {
9369 const index = this.array.indexOf(absorber);
9370 if (index >= 0) {
9371 this.array.splice(index, 1);
9372 }
9373 }
9374 }
9375 class plugin_Plugin {
9376 constructor() {
9377 this.id = "absorbers";
9378 }
9379 getPlugin(container) {
9380 return new Absorbers(container);
9381 }
9382 needsPlugin(options) {
9383 var _a, _b, _c;
9384 if (options === undefined) {
9385 return false;
9386 }
9387 const absorbers = options.absorbers;
9388 let loadAbsorbers = false;
9389 if (absorbers instanceof Array) {
9390 if (absorbers.length) {
9391 loadAbsorbers = true;
9392 }
9393 } else if (absorbers !== undefined) {
9394 loadAbsorbers = true;
9395 } else if (((_c = (_b = (_a = options.interactivity) === null || _a === void 0 ? void 0 : _a.events) === null || _b === void 0 ? void 0 : _b.onClick) === null || _c === void 0 ? void 0 : _c.mode) && isInArray(AbsorberClickMode.absorber, options.interactivity.events.onClick.mode)) {
9396 loadAbsorbers = true;
9397 }
9398 return loadAbsorbers;
9399 }
9400 loadOptions(options, source) {
9401 var _a, _b;
9402 if (!this.needsPlugin(options) && !this.needsPlugin(source)) {
9403 return;
9404 }
9405 const optionsCast = options;
9406 if (source === null || source === void 0 ? void 0 : source.absorbers) {
9407 if ((source === null || source === void 0 ? void 0 : source.absorbers) instanceof Array) {
9408 optionsCast.absorbers = source === null || source === void 0 ? void 0 : source.absorbers.map((s => {
9409 const tmp = new Absorber;
9410 tmp.load(s);
9411 return tmp;
9412 }));
9413 } else {
9414 let absorberOptions = optionsCast.absorbers;
9415 if ((absorberOptions === null || absorberOptions === void 0 ? void 0 : absorberOptions.load) === undefined) {
9416 optionsCast.absorbers = absorberOptions = new Absorber;
9417 }
9418 absorberOptions.load(source === null || source === void 0 ? void 0 : source.absorbers);
9419 }
9420 }
9421 const interactivityAbsorbers = (_b = (_a = source === null || source === void 0 ? void 0 : source.interactivity) === null || _a === void 0 ? void 0 : _a.modes) === null || _b === void 0 ? void 0 : _b.absorbers;
9422 if (interactivityAbsorbers) {
9423 if (interactivityAbsorbers instanceof Array) {
9424 optionsCast.interactivity.modes.absorbers = interactivityAbsorbers.map((s => {
9425 const tmp = new Absorber;
9426 tmp.load(s);
9427 return tmp;
9428 }));
9429 } else {
9430 let absorberOptions = optionsCast.interactivity.modes.absorbers;
9431 if ((absorberOptions === null || absorberOptions === void 0 ? void 0 : absorberOptions.load) === undefined) {
9432 optionsCast.interactivity.modes.absorbers = absorberOptions = new Absorber;
9433 }
9434 absorberOptions.load(interactivityAbsorbers);
9435 }
9436 }
9437 }
9438 }
9439 function loadAbsorbersPlugin(tsParticles) {
9440 const plugin = new plugin_Plugin;
9441 tsParticles.addPlugin(plugin);
9442 }
9443 class EmitterSize {
9444 constructor() {
9445 this.mode = SizeMode.percent;
9446 this.height = 0;
9447 this.width = 0;
9448 }
9449 load(data) {
9450 if (data === undefined) {
9451 return;
9452 }
9453 if (data.mode !== undefined) {
9454 this.mode = data.mode;
9455 }
9456 if (data.height !== undefined) {
9457 this.height = data.height;
9458 }
9459 if (data.width !== undefined) {
9460 this.width = data.width;
9461 }
9462 }
9463 }
9464 const shapes = new Map;
9465 class ShapeManager {
9466 static addShape(name, drawer) {
9467 if (!ShapeManager.getShape(name)) {
9468 shapes.set(name, drawer);
9469 }
9470 }
9471 static getShape(name) {
9472 return shapes.get(name);
9473 }
9474 static getSupportedShapes() {
9475 return shapes.keys();
9476 }
9477 }
9478 var EmitterInstance_classPrivateFieldSet = undefined && undefined.__classPrivateFieldSet || function(receiver, state, value, kind, f) {
9479 if (kind === "m") throw new TypeError("Private method is not writable");
9480 if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
9481 if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
9482 return kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value),
9483 value;
9484 };
9485 var EmitterInstance_classPrivateFieldGet = undefined && undefined.__classPrivateFieldGet || function(receiver, state, kind, f) {
9486 if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
9487 if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
9488 return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
9489 };
9490 var _EmitterInstance_firstSpawn, _EmitterInstance_startParticlesAdded;
9491 class EmitterInstance {
9492 constructor(emitters, container, emitterOptions, position) {
9493 var _a, _b, _c, _d, _e, _f;
9494 var _g;
9495 this.emitters = emitters;
9496 this.container = container;
9497 _EmitterInstance_firstSpawn.set(this, void 0);
9498 _EmitterInstance_startParticlesAdded.set(this, void 0);
9499 this.currentDuration = 0;
9500 this.currentEmitDelay = 0;
9501 this.currentSpawnDelay = 0;
9502 this.initialPosition = position;
9503 this.emitterOptions = deepExtend({}, emitterOptions);
9504 this.spawnDelay = ((_a = this.emitterOptions.life.delay) !== null && _a !== void 0 ? _a : 0) * 1e3 / this.container.retina.reduceFactor;
9505 this.position = (_b = this.initialPosition) !== null && _b !== void 0 ? _b : this.calcPosition();
9506 this.name = emitterOptions.name;
9507 this.shape = ShapeManager.getShape(emitterOptions.shape);
9508 this.fill = emitterOptions.fill;
9509 EmitterInstance_classPrivateFieldSet(this, _EmitterInstance_firstSpawn, !this.emitterOptions.life.wait, "f");
9510 EmitterInstance_classPrivateFieldSet(this, _EmitterInstance_startParticlesAdded, false, "f");
9511 let particlesOptions = deepExtend({}, this.emitterOptions.particles);
9512 particlesOptions !== null && particlesOptions !== void 0 ? particlesOptions : particlesOptions = {};
9513 (_c = particlesOptions.move) !== null && _c !== void 0 ? _c : particlesOptions.move = {};
9514 (_d = (_g = particlesOptions.move).direction) !== null && _d !== void 0 ? _d : _g.direction = this.emitterOptions.direction;
9515 if (this.emitterOptions.spawnColor !== undefined) {
9516 this.spawnColor = colorToHsl(this.emitterOptions.spawnColor);
9517 }
9518 this.paused = !this.emitterOptions.autoPlay;
9519 this.particlesOptions = particlesOptions;
9520 this.size = (_e = this.emitterOptions.size) !== null && _e !== void 0 ? _e : (() => {
9521 const size = new EmitterSize;
9522 size.load({
9523 height: 0,
9524 mode: SizeMode.percent,
9525 width: 0
9526 });
9527 return size;
9528 })();
9529 this.lifeCount = (_f = this.emitterOptions.life.count) !== null && _f !== void 0 ? _f : -1;
9530 this.immortal = this.lifeCount <= 0;
9531 this.play();
9532 }
9533 externalPlay() {
9534 this.paused = false;
9535 this.play();
9536 }
9537 externalPause() {
9538 this.paused = true;
9539 this.pause();
9540 }
9541 play() {
9542 var _a;
9543 if (this.paused) {
9544 return;
9545 }
9546 if (this.container.retina.reduceFactor && (this.lifeCount > 0 || this.immortal || !this.emitterOptions.life.count) && (EmitterInstance_classPrivateFieldGet(this, _EmitterInstance_firstSpawn, "f") || this.currentSpawnDelay >= ((_a = this.spawnDelay) !== null && _a !== void 0 ? _a : 0))) {
9547 if (this.emitDelay === undefined) {
9548 const delay = getRangeValue(this.emitterOptions.rate.delay);
9549 this.emitDelay = 1e3 * delay / this.container.retina.reduceFactor;
9550 }
9551 if (this.lifeCount > 0 || this.immortal) {
9552 this.prepareToDie();
9553 }
9554 }
9555 }
9556 pause() {
9557 if (this.paused) {
9558 return;
9559 }
9560 delete this.emitDelay;
9561 }
9562 resize() {
9563 const initialPosition = this.initialPosition;
9564 this.position = initialPosition && isPointInside(initialPosition, this.container.canvas.size) ? initialPosition : this.calcPosition();
9565 }
9566 update(delta) {
9567 var _a, _b, _c;
9568 if (this.paused) {
9569 return;
9570 }
9571 if (EmitterInstance_classPrivateFieldGet(this, _EmitterInstance_firstSpawn, "f")) {
9572 EmitterInstance_classPrivateFieldSet(this, _EmitterInstance_firstSpawn, false, "f");
9573 this.currentSpawnDelay = (_a = this.spawnDelay) !== null && _a !== void 0 ? _a : 0;
9574 this.currentEmitDelay = (_b = this.emitDelay) !== null && _b !== void 0 ? _b : 0;
9575 }
9576 if (!EmitterInstance_classPrivateFieldGet(this, _EmitterInstance_startParticlesAdded, "f")) {
9577 EmitterInstance_classPrivateFieldSet(this, _EmitterInstance_startParticlesAdded, true, "f");
9578 this.emitParticles(this.emitterOptions.startCount);
9579 }
9580 if (this.duration !== undefined) {
9581 this.currentDuration += delta.value;
9582 if (this.currentDuration >= this.duration) {
9583 this.pause();
9584 if (this.spawnDelay !== undefined) {
9585 delete this.spawnDelay;
9586 }
9587 if (!this.immortal) {
9588 this.lifeCount--;
9589 }
9590 if (this.lifeCount > 0 || this.immortal) {
9591 this.position = this.calcPosition();
9592 this.spawnDelay = ((_c = this.emitterOptions.life.delay) !== null && _c !== void 0 ? _c : 0) * 1e3 / this.container.retina.reduceFactor;
9593 } else {
9594 this.destroy();
9595 }
9596 this.currentDuration -= this.duration;
9597 delete this.duration;
9598 }
9599 }
9600 if (this.spawnDelay !== undefined) {
9601 this.currentSpawnDelay += delta.value;
9602 if (this.currentSpawnDelay >= this.spawnDelay) {
9603 this.play();
9604 this.currentSpawnDelay -= this.currentSpawnDelay;
9605 delete this.spawnDelay;
9606 }
9607 }
9608 if (this.emitDelay !== undefined) {
9609 this.currentEmitDelay += delta.value;
9610 if (this.currentEmitDelay >= this.emitDelay) {
9611 this.emit();
9612 this.currentEmitDelay -= this.emitDelay;
9613 }
9614 }
9615 }
9616 prepareToDie() {
9617 var _a;
9618 if (this.paused) {
9619 return;
9620 }
9621 const duration = (_a = this.emitterOptions.life) === null || _a === void 0 ? void 0 : _a.duration;
9622 if (this.container.retina.reduceFactor && (this.lifeCount > 0 || this.immortal) && duration !== undefined && duration > 0) {
9623 this.duration = duration * 1e3;
9624 }
9625 }
9626 destroy() {
9627 this.emitters.removeEmitter(this);
9628 }
9629 calcPosition() {
9630 var _a, _b;
9631 const container = this.container;
9632 const percentPosition = this.emitterOptions.position;
9633 return {
9634 x: ((_a = percentPosition === null || percentPosition === void 0 ? void 0 : percentPosition.x) !== null && _a !== void 0 ? _a : Math.random() * 100) / 100 * container.canvas.size.width,
9635 y: ((_b = percentPosition === null || percentPosition === void 0 ? void 0 : percentPosition.y) !== null && _b !== void 0 ? _b : Math.random() * 100) / 100 * container.canvas.size.height
9636 };
9637 }
9638 emit() {
9639 if (this.paused) {
9640 return;
9641 }
9642 const quantity = getRangeValue(this.emitterOptions.rate.quantity);
9643 this.emitParticles(quantity);
9644 }
9645 emitParticles(quantity) {
9646 var _a, _b, _c;
9647 const container = this.container;
9648 const position = this.position;
9649 const offset = {
9650 x: this.size.mode === SizeMode.percent ? container.canvas.size.width * this.size.width / 100 : this.size.width,
9651 y: this.size.mode === SizeMode.percent ? container.canvas.size.height * this.size.height / 100 : this.size.height
9652 };
9653 for (let i = 0; i < quantity; i++) {
9654 const particlesOptions = deepExtend({}, this.particlesOptions);
9655 if (this.spawnColor) {
9656 const colorAnimation = (_a = this.emitterOptions.spawnColor) === null || _a === void 0 ? void 0 : _a.animation;
9657 if (colorAnimation) {
9658 const hueAnimation = colorAnimation;
9659 if (hueAnimation.enable) {
9660 this.spawnColor.h = this.setColorAnimation(hueAnimation, this.spawnColor.h, 360);
9661 } else {
9662 const hslAnimation = colorAnimation;
9663 this.spawnColor.h = this.setColorAnimation(hslAnimation.h, this.spawnColor.h, 360);
9664 this.spawnColor.s = this.setColorAnimation(hslAnimation.s, this.spawnColor.s, 100);
9665 this.spawnColor.l = this.setColorAnimation(hslAnimation.l, this.spawnColor.l, 100);
9666 }
9667 }
9668 if (!particlesOptions.color) {
9669 particlesOptions.color = {
9670 value: this.spawnColor
9671 };
9672 } else {
9673 particlesOptions.color.value = this.spawnColor;
9674 }
9675 }
9676 const pPosition = (_c = (_b = this.shape) === null || _b === void 0 ? void 0 : _b.randomPosition(position, offset, this.fill)) !== null && _c !== void 0 ? _c : position;
9677 container.particles.addParticle(pPosition, particlesOptions);
9678 }
9679 }
9680 setColorAnimation(animation, initValue, maxValue) {
9681 var _a;
9682 const container = this.container;
9683 if (!animation.enable) {
9684 return initValue;
9685 }
9686 const colorOffset = randomInRange(animation.offset);
9687 const delay = getRangeValue(this.emitterOptions.rate.delay);
9688 const emitFactor = 1e3 * delay / container.retina.reduceFactor;
9689 const colorSpeed = (_a = animation.speed) !== null && _a !== void 0 ? _a : 0;
9690 return (initValue + colorSpeed * container.fpsLimit / emitFactor + colorOffset * 3.6) % maxValue;
9691 }
9692 }
9693 _EmitterInstance_firstSpawn = new WeakMap, _EmitterInstance_startParticlesAdded = new WeakMap;
9694 class EmitterRate {
9695 constructor() {
9696 this.quantity = 1;
9697 this.delay = .1;
9698 }
9699 load(data) {
9700 if (data === undefined) {
9701 return;
9702 }
9703 if (data.quantity !== undefined) {
9704 this.quantity = setRangeValue(data.quantity);
9705 }
9706 if (data.delay !== undefined) {
9707 this.delay = setRangeValue(data.delay);
9708 }
9709 }
9710 }
9711 class EmitterLife {
9712 constructor() {
9713 this.wait = false;
9714 }
9715 load(data) {
9716 if (data === undefined) {
9717 return;
9718 }
9719 if (data.count !== undefined) {
9720 this.count = data.count;
9721 }
9722 if (data.delay !== undefined) {
9723 this.delay = data.delay;
9724 }
9725 if (data.duration !== undefined) {
9726 this.duration = data.duration;
9727 }
9728 if (data.wait !== undefined) {
9729 this.wait = data.wait;
9730 }
9731 }
9732 }
9733 var EmitterClickMode;
9734 (function(EmitterClickMode) {
9735 EmitterClickMode["emitter"] = "emitter";
9736 })(EmitterClickMode || (EmitterClickMode = {}));
9737 var EmitterShapeType;
9738 (function(EmitterShapeType) {
9739 EmitterShapeType["circle"] = "circle";
9740 EmitterShapeType["square"] = "square";
9741 })(EmitterShapeType || (EmitterShapeType = {}));
9742 class Emitter {
9743 constructor() {
9744 this.autoPlay = true;
9745 this.fill = true;
9746 this.life = new EmitterLife;
9747 this.rate = new EmitterRate;
9748 this.shape = EmitterShapeType.square;
9749 this.startCount = 0;
9750 }
9751 load(data) {
9752 if (data === undefined) {
9753 return;
9754 }
9755 if (data.autoPlay !== undefined) {
9756 this.autoPlay = data.autoPlay;
9757 }
9758 if (data.size !== undefined) {
9759 if (this.size === undefined) {
9760 this.size = new EmitterSize;
9761 }
9762 this.size.load(data.size);
9763 }
9764 if (data.direction !== undefined) {
9765 this.direction = data.direction;
9766 }
9767 if (data.fill !== undefined) {
9768 this.fill = data.fill;
9769 }
9770 this.life.load(data.life);
9771 this.name = data.name;
9772 if (data.particles !== undefined) {
9773 this.particles = deepExtend({}, data.particles);
9774 }
9775 this.rate.load(data.rate);
9776 if (data.shape !== undefined) {
9777 this.shape = data.shape;
9778 }
9779 if (data.position !== undefined) {
9780 this.position = {
9781 x: data.position.x,
9782 y: data.position.y
9783 };
9784 }
9785 if (data.spawnColor !== undefined) {
9786 if (this.spawnColor === undefined) {
9787 this.spawnColor = new AnimatableColor;
9788 }
9789 this.spawnColor.load(data.spawnColor);
9790 }
9791 if (data.startCount !== undefined) {
9792 this.startCount = data.startCount;
9793 }
9794 }
9795 }
9796 class Emitters {
9797 constructor(container) {
9798 this.container = container;
9799 this.array = [];
9800 this.emitters = [];
9801 this.interactivityEmitters = [];
9802 const overridableContainer = container;
9803 overridableContainer.getEmitter = idxOrName => idxOrName === undefined || typeof idxOrName === "number" ? this.array[idxOrName || 0] : this.array.find((t => t.name === idxOrName));
9804 overridableContainer.addEmitter = (options, position) => this.addEmitter(options, position);
9805 overridableContainer.playEmitter = idxOrName => {
9806 const emitter = overridableContainer.getEmitter(idxOrName);
9807 if (emitter) {
9808 emitter.externalPlay();
9809 }
9810 };
9811 overridableContainer.pauseEmitter = idxOrName => {
9812 const emitter = overridableContainer.getEmitter(idxOrName);
9813 if (emitter) {
9814 emitter.externalPause();
9815 }
9816 };
9817 }
9818 init(options) {
9819 var _a, _b;
9820 if (!options) {
9821 return;
9822 }
9823 if (options.emitters) {
9824 if (options.emitters instanceof Array) {
9825 this.emitters = options.emitters.map((s => {
9826 const tmp = new Emitter;
9827 tmp.load(s);
9828 return tmp;
9829 }));
9830 } else {
9831 if (this.emitters instanceof Array) {
9832 this.emitters = new Emitter;
9833 }
9834 this.emitters.load(options.emitters);
9835 }
9836 }
9837 const interactivityEmitters = (_b = (_a = options.interactivity) === null || _a === void 0 ? void 0 : _a.modes) === null || _b === void 0 ? void 0 : _b.emitters;
9838 if (interactivityEmitters) {
9839 if (interactivityEmitters instanceof Array) {
9840 this.interactivityEmitters = interactivityEmitters.map((s => {
9841 const tmp = new Emitter;
9842 tmp.load(s);
9843 return tmp;
9844 }));
9845 } else {
9846 if (this.interactivityEmitters instanceof Array) {
9847 this.interactivityEmitters = new Emitter;
9848 }
9849 this.interactivityEmitters.load(interactivityEmitters);
9850 }
9851 }
9852 if (this.emitters instanceof Array) {
9853 for (const emitterOptions of this.emitters) {
9854 this.addEmitter(emitterOptions);
9855 }
9856 } else {
9857 this.addEmitter(this.emitters);
9858 }
9859 }
9860 play() {
9861 for (const emitter of this.array) {
9862 emitter.play();
9863 }
9864 }
9865 pause() {
9866 for (const emitter of this.array) {
9867 emitter.pause();
9868 }
9869 }
9870 stop() {
9871 this.array = [];
9872 }
9873 update(delta) {
9874 for (const emitter of this.array) {
9875 emitter.update(delta);
9876 }
9877 }
9878 handleClickMode(mode) {
9879 const container = this.container;
9880 const emitterOptions = this.emitters;
9881 const modeEmitters = this.interactivityEmitters;
9882 if (mode === EmitterClickMode.emitter) {
9883 let emitterModeOptions;
9884 if (modeEmitters instanceof Array) {
9885 if (modeEmitters.length > 0) {
9886 emitterModeOptions = itemFromArray(modeEmitters);
9887 }
9888 } else {
9889 emitterModeOptions = modeEmitters;
9890 }
9891 const emittersOptions = emitterModeOptions !== null && emitterModeOptions !== void 0 ? emitterModeOptions : emitterOptions instanceof Array ? itemFromArray(emitterOptions) : emitterOptions;
9892 const ePosition = container.interactivity.mouse.clickPosition;
9893 this.addEmitter(deepExtend({}, emittersOptions), ePosition);
9894 }
9895 }
9896 resize() {
9897 for (const emitter of this.array) {
9898 emitter.resize();
9899 }
9900 }
9901 addEmitter(options, position) {
9902 const emitter = new EmitterInstance(this, this.container, options, position);
9903 this.array.push(emitter);
9904 return emitter;
9905 }
9906 removeEmitter(emitter) {
9907 const index = this.array.indexOf(emitter);
9908 if (index >= 0) {
9909 this.array.splice(index, 1);
9910 }
9911 }
9912 }
9913 class CircleShape {
9914 randomPosition(position, offset, fill) {
9915 const generateTheta = (x, y) => {
9916 const u = Math.random() / 4;
9917 const theta = Math.atan(y / x * Math.tan(2 * Math.PI * u));
9918 const v = Math.random();
9919 if (v < .25) {
9920 return theta;
9921 } else if (v < .5) {
9922 return Math.PI - theta;
9923 } else if (v < .75) {
9924 return Math.PI + theta;
9925 } else {
9926 return -theta;
9927 }
9928 };
9929 const radius = (x, y, theta) => x * y / Math.sqrt((y * Math.cos(theta)) ** 2 + (x * Math.sin(theta)) ** 2);
9930 const [a, b] = [ offset.x / 2, offset.y / 2 ];
9931 const randomTheta = generateTheta(a, b), maxRadius = radius(a, b, randomTheta), randomRadius = fill ? maxRadius * Math.sqrt(Math.random()) : maxRadius;
9932 return {
9933 x: position.x + randomRadius * Math.cos(randomTheta),
9934 y: position.y + randomRadius * Math.sin(randomTheta)
9935 };
9936 }
9937 }
9938 function randomSquareCoordinate(position, offset) {
9939 return position + offset * (Math.random() - .5);
9940 }
9941 class SquareShape {
9942 randomPosition(position, offset, fill) {
9943 if (fill) {
9944 return {
9945 x: randomSquareCoordinate(position.x, offset.x),
9946 y: randomSquareCoordinate(position.y, offset.y)
9947 };
9948 } else {
9949 const halfW = offset.x / 2, halfH = offset.y / 2, side = Math.floor(Math.random() * 4), v = (Math.random() - .5) * 2;
9950 switch (side) {
9951 case 0:
9952 return {
9953 x: position.x + v * halfW,
9954 y: position.y - halfH
9955 };
9956
9957 case 1:
9958 return {
9959 x: position.x - halfW,
9960 y: position.y + v * halfH
9961 };
9962
9963 case 2:
9964 return {
9965 x: position.x + v * halfW,
9966 y: position.y + halfH
9967 };
9968
9969 case 3:
9970 default:
9971 return {
9972 x: position.x + halfW,
9973 y: position.y + v * halfH
9974 };
9975 }
9976 }
9977 }
9978 }
9979 class EmittersPlugin {
9980 constructor() {
9981 this.id = "emitters";
9982 }
9983 getPlugin(container) {
9984 return new Emitters(container);
9985 }
9986 needsPlugin(options) {
9987 var _a, _b, _c;
9988 if (options === undefined) {
9989 return false;
9990 }
9991 const emitters = options.emitters;
9992 return emitters instanceof Array && !!emitters.length || emitters !== undefined || !!((_c = (_b = (_a = options.interactivity) === null || _a === void 0 ? void 0 : _a.events) === null || _b === void 0 ? void 0 : _b.onClick) === null || _c === void 0 ? void 0 : _c.mode) && isInArray(EmitterClickMode.emitter, options.interactivity.events.onClick.mode);
9993 }
9994 loadOptions(options, source) {
9995 var _a, _b;
9996 if (!this.needsPlugin(options) && !this.needsPlugin(source)) {
9997 return;
9998 }
9999 const optionsCast = options;
10000 if (source === null || source === void 0 ? void 0 : source.emitters) {
10001 if ((source === null || source === void 0 ? void 0 : source.emitters) instanceof Array) {
10002 optionsCast.emitters = source === null || source === void 0 ? void 0 : source.emitters.map((s => {
10003 const tmp = new Emitter;
10004 tmp.load(s);
10005 return tmp;
10006 }));
10007 } else {
10008 let emitterOptions = optionsCast.emitters;
10009 if ((emitterOptions === null || emitterOptions === void 0 ? void 0 : emitterOptions.load) === undefined) {
10010 optionsCast.emitters = emitterOptions = new Emitter;
10011 }
10012 emitterOptions.load(source === null || source === void 0 ? void 0 : source.emitters);
10013 }
10014 }
10015 const interactivityEmitters = (_b = (_a = source === null || source === void 0 ? void 0 : source.interactivity) === null || _a === void 0 ? void 0 : _a.modes) === null || _b === void 0 ? void 0 : _b.emitters;
10016 if (interactivityEmitters) {
10017 if (interactivityEmitters instanceof Array) {
10018 optionsCast.interactivity.modes.emitters = interactivityEmitters.map((s => {
10019 const tmp = new Emitter;
10020 tmp.load(s);
10021 return tmp;
10022 }));
10023 } else {
10024 let emitterOptions = optionsCast.interactivity.modes.emitters;
10025 if ((emitterOptions === null || emitterOptions === void 0 ? void 0 : emitterOptions.load) === undefined) {
10026 optionsCast.interactivity.modes.emitters = emitterOptions = new Emitter;
10027 }
10028 emitterOptions.load(interactivityEmitters);
10029 }
10030 }
10031 }
10032 }
10033 function loadEmittersPlugin(tsParticles) {
10034 const plugin = new EmittersPlugin;
10035 tsParticles.addPlugin(plugin);
10036 if (!tsParticles.addEmitterShape) {
10037 tsParticles.addEmitterShape = (name, shape) => {
10038 ShapeManager.addShape(name, shape);
10039 };
10040 }
10041 tsParticles.addEmitterShape(EmitterShapeType.circle, new CircleShape);
10042 tsParticles.addEmitterShape(EmitterShapeType.square, new SquareShape);
10043 }
10044 var InlineArrangement;
10045 (function(InlineArrangement) {
10046 InlineArrangement["equidistant"] = "equidistant";
10047 InlineArrangement["onePerPoint"] = "one-per-point";
10048 InlineArrangement["perPoint"] = "per-point";
10049 InlineArrangement["randomLength"] = "random-length";
10050 InlineArrangement["randomPoint"] = "random-point";
10051 })(InlineArrangement || (InlineArrangement = {}));
10052 var MoveType;
10053 (function(MoveType) {
10054 MoveType["path"] = "path";
10055 MoveType["radius"] = "radius";
10056 })(MoveType || (MoveType = {}));
10057 var Type;
10058 (function(Type) {
10059 Type["inline"] = "inline";
10060 Type["inside"] = "inside";
10061 Type["outside"] = "outside";
10062 Type["none"] = "none";
10063 })(Type || (Type = {}));
10064 class DrawStroke {
10065 constructor() {
10066 this.color = new OptionsColor;
10067 this.width = .5;
10068 this.opacity = 1;
10069 }
10070 load(data) {
10071 var _a;
10072 if (data !== undefined) {
10073 this.color = OptionsColor.create(this.color, data.color);
10074 if (typeof this.color.value === "string") {
10075 this.opacity = (_a = stringToAlpha(this.color.value)) !== null && _a !== void 0 ? _a : this.opacity;
10076 }
10077 if (data.opacity !== undefined) {
10078 this.opacity = data.opacity;
10079 }
10080 if (data.width !== undefined) {
10081 this.width = data.width;
10082 }
10083 }
10084 }
10085 }
10086 class Draw {
10087 constructor() {
10088 this.enable = false;
10089 this.stroke = new DrawStroke;
10090 }
10091 get lineWidth() {
10092 return this.stroke.width;
10093 }
10094 set lineWidth(value) {
10095 this.stroke.width = value;
10096 }
10097 get lineColor() {
10098 return this.stroke.color;
10099 }
10100 set lineColor(value) {
10101 this.stroke.color = OptionsColor.create(this.stroke.color, value);
10102 }
10103 load(data) {
10104 var _a;
10105 if (data !== undefined) {
10106 if (data.enable !== undefined) {
10107 this.enable = data.enable;
10108 }
10109 const stroke = (_a = data.stroke) !== null && _a !== void 0 ? _a : {
10110 color: data.lineColor,
10111 width: data.lineWidth
10112 };
10113 this.stroke.load(stroke);
10114 }
10115 }
10116 }
10117 class Move_Move {
10118 constructor() {
10119 this.radius = 10;
10120 this.type = MoveType.path;
10121 }
10122 load(data) {
10123 if (data !== undefined) {
10124 if (data.radius !== undefined) {
10125 this.radius = data.radius;
10126 }
10127 if (data.type !== undefined) {
10128 this.type = data.type;
10129 }
10130 }
10131 }
10132 }
10133 class Inline {
10134 constructor() {
10135 this.arrangement = InlineArrangement.onePerPoint;
10136 }
10137 load(data) {
10138 if (data !== undefined) {
10139 if (data.arrangement !== undefined) {
10140 this.arrangement = data.arrangement;
10141 }
10142 }
10143 }
10144 }
10145 class LocalSvg {
10146 constructor() {
10147 this.path = [];
10148 this.size = {
10149 height: 0,
10150 width: 0
10151 };
10152 }
10153 load(data) {
10154 if (data !== undefined) {
10155 if (data.path !== undefined) {
10156 this.path = data.path;
10157 }
10158 if (data.size !== undefined) {
10159 if (data.size.width !== undefined) {
10160 this.size.width = data.size.width;
10161 }
10162 if (data.size.height !== undefined) {
10163 this.size.height = data.size.height;
10164 }
10165 }
10166 }
10167 }
10168 }
10169 class PolygonMask {
10170 constructor() {
10171 this.draw = new Draw;
10172 this.enable = false;
10173 this.inline = new Inline;
10174 this.move = new Move_Move;
10175 this.scale = 1;
10176 this.type = Type.none;
10177 }
10178 get inlineArrangement() {
10179 return this.inline.arrangement;
10180 }
10181 set inlineArrangement(value) {
10182 this.inline.arrangement = value;
10183 }
10184 load(data) {
10185 var _a;
10186 if (data !== undefined) {
10187 this.draw.load(data.draw);
10188 const inline = (_a = data.inline) !== null && _a !== void 0 ? _a : {
10189 arrangement: data.inlineArrangement
10190 };
10191 if (inline !== undefined) {
10192 this.inline.load(inline);
10193 }
10194 this.move.load(data.move);
10195 if (data.scale !== undefined) {
10196 this.scale = data.scale;
10197 }
10198 if (data.type !== undefined) {
10199 this.type = data.type;
10200 }
10201 if (data.enable !== undefined) {
10202 this.enable = data.enable;
10203 } else {
10204 this.enable = this.type !== Type.none;
10205 }
10206 if (data.url !== undefined) {
10207 this.url = data.url;
10208 }
10209 if (data.data !== undefined) {
10210 if (typeof data.data === "string") {
10211 this.data = data.data;
10212 } else {
10213 this.data = new LocalSvg;
10214 this.data.load(data.data);
10215 }
10216 }
10217 if (data.position !== undefined) {
10218 this.position = deepExtend({}, data.position);
10219 }
10220 }
10221 }
10222 }
10223 function drawPolygonMask(context, rawData, stroke) {
10224 const color = colorToRgb(stroke.color);
10225 if (!color) {
10226 return;
10227 }
10228 context.beginPath();
10229 context.moveTo(rawData[0].x, rawData[0].y);
10230 for (const item of rawData) {
10231 context.lineTo(item.x, item.y);
10232 }
10233 context.closePath();
10234 context.strokeStyle = getStyleFromRgb(color);
10235 context.lineWidth = stroke.width;
10236 context.stroke();
10237 }
10238 function drawPolygonMaskPath(context, path, stroke, position) {
10239 context.translate(position.x, position.y);
10240 const color = colorToRgb(stroke.color);
10241 if (!color) {
10242 return;
10243 }
10244 context.strokeStyle = getStyleFromRgb(color, stroke.opacity);
10245 context.lineWidth = stroke.width;
10246 context.stroke(path);
10247 }
10248 function parsePaths(paths, scale, offset) {
10249 var _a;
10250 const res = [];
10251 for (const path of paths) {
10252 const segments = path.element.pathSegList;
10253 const len = (_a = segments === null || segments === void 0 ? void 0 : segments.numberOfItems) !== null && _a !== void 0 ? _a : 0;
10254 const p = {
10255 x: 0,
10256 y: 0
10257 };
10258 for (let i = 0; i < len; i++) {
10259 const segment = segments === null || segments === void 0 ? void 0 : segments.getItem(i);
10260 const svgPathSeg = window.SVGPathSeg;
10261 switch (segment === null || segment === void 0 ? void 0 : segment.pathSegType) {
10262 case svgPathSeg.PATHSEG_MOVETO_ABS:
10263 case svgPathSeg.PATHSEG_LINETO_ABS:
10264 case svgPathSeg.PATHSEG_CURVETO_CUBIC_ABS:
10265 case svgPathSeg.PATHSEG_CURVETO_QUADRATIC_ABS:
10266 case svgPathSeg.PATHSEG_ARC_ABS:
10267 case svgPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_ABS:
10268 case svgPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_ABS:
10269 {
10270 const absSeg = segment;
10271 p.x = absSeg.x;
10272 p.y = absSeg.y;
10273 break;
10274 }
10275
10276 case svgPathSeg.PATHSEG_LINETO_HORIZONTAL_ABS:
10277 p.x = segment.x;
10278 break;
10279
10280 case svgPathSeg.PATHSEG_LINETO_VERTICAL_ABS:
10281 p.y = segment.y;
10282 break;
10283
10284 case svgPathSeg.PATHSEG_LINETO_REL:
10285 case svgPathSeg.PATHSEG_MOVETO_REL:
10286 case svgPathSeg.PATHSEG_CURVETO_CUBIC_REL:
10287 case svgPathSeg.PATHSEG_CURVETO_QUADRATIC_REL:
10288 case svgPathSeg.PATHSEG_ARC_REL:
10289 case svgPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_REL:
10290 case svgPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_REL:
10291 {
10292 const relSeg = segment;
10293 p.x += relSeg.x;
10294 p.y += relSeg.y;
10295 break;
10296 }
10297
10298 case svgPathSeg.PATHSEG_LINETO_HORIZONTAL_REL:
10299 p.x += segment.x;
10300 break;
10301
10302 case svgPathSeg.PATHSEG_LINETO_VERTICAL_REL:
10303 p.y += segment.y;
10304 break;
10305
10306 case svgPathSeg.PATHSEG_UNKNOWN:
10307 case svgPathSeg.PATHSEG_CLOSEPATH:
10308 continue;
10309 }
10310 res.push({
10311 x: p.x * scale + offset.x,
10312 y: p.y * scale + offset.y
10313 });
10314 }
10315 }
10316 return res;
10317 }
10318 function calcClosestPtOnSegment(s1, s2, pos) {
10319 const {dx, dy} = getDistances(pos, s1);
10320 const {dx: dxx, dy: dyy} = getDistances(s2, s1);
10321 const t = (dx * dxx + dy * dyy) / (dxx ** 2 + dyy ** 2);
10322 let x = s1.x + dxx * t;
10323 let y = s1.y + dyy * t;
10324 if (t < 0) {
10325 x = s1.x;
10326 y = s1.y;
10327 } else if (t > 1) {
10328 x = s2.x;
10329 y = s2.y;
10330 }
10331 return {
10332 x,
10333 y,
10334 isOnSegment: t >= 0 && t <= 1
10335 };
10336 }
10337 function segmentBounce(start, stop, velocity) {
10338 const {dx, dy} = getDistances(start, stop);
10339 const wallAngle = Math.atan2(dy, dx);
10340 const wallNormalX = Math.sin(wallAngle);
10341 const wallNormalY = -Math.cos(wallAngle);
10342 const d = 2 * (velocity.x * wallNormalX + velocity.y * wallNormalY);
10343 velocity.x -= d * wallNormalX;
10344 velocity.y -= d * wallNormalY;
10345 }
10346 class PolygonMaskInstance {
10347 constructor(container) {
10348 this.container = container;
10349 this.dimension = {
10350 height: 0,
10351 width: 0
10352 };
10353 this.path2DSupported = !!window.Path2D;
10354 this.options = new PolygonMask;
10355 this.polygonMaskMoveRadius = this.options.move.radius * container.retina.pixelRatio;
10356 }
10357 async initAsync(options) {
10358 this.options.load(options === null || options === void 0 ? void 0 : options.polygon);
10359 const polygonMaskOptions = this.options;
10360 this.polygonMaskMoveRadius = polygonMaskOptions.move.radius * this.container.retina.pixelRatio;
10361 if (polygonMaskOptions.enable) {
10362 await this.initRawData();
10363 }
10364 }
10365 resize() {
10366 const container = this.container;
10367 const options = this.options;
10368 if (!(options.enable && options.type !== Type.none)) {
10369 return;
10370 }
10371 if (this.redrawTimeout) {
10372 clearTimeout(this.redrawTimeout);
10373 }
10374 this.redrawTimeout = window.setTimeout((async () => {
10375 await this.initRawData(true);
10376 container.particles.redraw();
10377 }), 250);
10378 }
10379 stop() {
10380 delete this.raw;
10381 delete this.paths;
10382 }
10383 particlesInitialization() {
10384 const options = this.options;
10385 if (options.enable && options.type === Type.inline && (options.inline.arrangement === InlineArrangement.onePerPoint || options.inline.arrangement === InlineArrangement.perPoint)) {
10386 this.drawPoints();
10387 return true;
10388 }
10389 return false;
10390 }
10391 particlePosition(position) {
10392 var _a, _b;
10393 const options = this.options;
10394 if (!(options.enable && ((_b = (_a = this.raw) === null || _a === void 0 ? void 0 : _a.length) !== null && _b !== void 0 ? _b : 0) > 0)) {
10395 return;
10396 }
10397 return deepExtend({}, position ? position : this.randomPoint());
10398 }
10399 particleBounce(particle, delta, direction) {
10400 return this.polygonBounce(particle, delta, direction);
10401 }
10402 clickPositionValid(position) {
10403 const options = this.options;
10404 return options.enable && options.type !== Type.none && options.type !== Type.inline && this.checkInsidePolygon(position);
10405 }
10406 draw(context) {
10407 var _a;
10408 if (!((_a = this.paths) === null || _a === void 0 ? void 0 : _a.length)) {
10409 return;
10410 }
10411 const options = this.options;
10412 const polygonDraw = options.draw;
10413 if (!(options.enable && polygonDraw.enable)) {
10414 return;
10415 }
10416 const rawData = this.raw;
10417 for (const path of this.paths) {
10418 const path2d = path.path2d;
10419 const path2dSupported = this.path2DSupported;
10420 if (!context) {
10421 continue;
10422 }
10423 if (path2dSupported && path2d && this.offset) {
10424 drawPolygonMaskPath(context, path2d, polygonDraw.stroke, this.offset);
10425 } else if (rawData) {
10426 drawPolygonMask(context, rawData, polygonDraw.stroke);
10427 }
10428 }
10429 }
10430 polygonBounce(particle, _delta, direction) {
10431 const options = this.options;
10432 if (!this.raw || !options.enable || direction !== OutModeDirection.top) {
10433 return false;
10434 }
10435 if (options.type === Type.inside || options.type === Type.outside) {
10436 let closest, dx, dy;
10437 const pos = particle.getPosition(), radius = particle.getRadius();
10438 for (let i = 0, j = this.raw.length - 1; i < this.raw.length; j = i++) {
10439 const pi = this.raw[i], pj = this.raw[j];
10440 closest = calcClosestPtOnSegment(pi, pj, pos);
10441 const dist = getDistances(pos, closest);
10442 [dx, dy] = [ dist.dx, dist.dy ];
10443 if (dist.distance < radius) {
10444 segmentBounce(pi, pj, particle.velocity);
10445 return true;
10446 }
10447 }
10448 if (closest && dx !== undefined && dy !== undefined && !this.checkInsidePolygon(pos)) {
10449 const factor = {
10450 x: 1,
10451 y: 1
10452 };
10453 if (particle.position.x >= closest.x) {
10454 factor.x = -1;
10455 }
10456 if (particle.position.y >= closest.y) {
10457 factor.y = -1;
10458 }
10459 particle.position.x = closest.x + radius * 2 * factor.x;
10460 particle.position.y = closest.y + radius * 2 * factor.y;
10461 particle.velocity.mult(-1);
10462 return true;
10463 }
10464 } else if (options.type === Type.inline && particle.initialPosition) {
10465 const dist = getDistance(particle.initialPosition, particle.getPosition());
10466 if (dist > this.polygonMaskMoveRadius) {
10467 particle.velocity.x = particle.velocity.y / 2 - particle.velocity.x;
10468 particle.velocity.y = particle.velocity.x / 2 - particle.velocity.y;
10469 return true;
10470 }
10471 }
10472 return false;
10473 }
10474 checkInsidePolygon(position) {
10475 var _a, _b;
10476 const container = this.container;
10477 const options = this.options;
10478 if (!options.enable || options.type === Type.none || options.type === Type.inline) {
10479 return true;
10480 }
10481 if (!this.raw) {
10482 throw new Error(Constants.noPolygonFound);
10483 }
10484 const canvasSize = container.canvas.size;
10485 const x = (_a = position === null || position === void 0 ? void 0 : position.x) !== null && _a !== void 0 ? _a : Math.random() * canvasSize.width;
10486 const y = (_b = position === null || position === void 0 ? void 0 : position.y) !== null && _b !== void 0 ? _b : Math.random() * canvasSize.height;
10487 let inside = false;
10488 for (let i = 0, j = this.raw.length - 1; i < this.raw.length; j = i++) {
10489 const pi = this.raw[i];
10490 const pj = this.raw[j];
10491 const intersect = pi.y > y !== pj.y > y && x < (pj.x - pi.x) * (y - pi.y) / (pj.y - pi.y) + pi.x;
10492 if (intersect) {
10493 inside = !inside;
10494 }
10495 }
10496 return options.type === Type.inside ? inside : options.type === Type.outside ? !inside : false;
10497 }
10498 parseSvgPath(xml, force) {
10499 var _a, _b, _c;
10500 const forceDownload = force !== null && force !== void 0 ? force : false;
10501 if (this.paths !== undefined && !forceDownload) {
10502 return this.raw;
10503 }
10504 const container = this.container;
10505 const options = this.options;
10506 const parser = new DOMParser;
10507 const doc = parser.parseFromString(xml, "image/svg+xml");
10508 const svg = doc.getElementsByTagName("svg")[0];
10509 let svgPaths = svg.getElementsByTagName("path");
10510 if (!svgPaths.length) {
10511 svgPaths = doc.getElementsByTagName("path");
10512 }
10513 this.paths = [];
10514 for (let i = 0; i < svgPaths.length; i++) {
10515 const path = svgPaths.item(i);
10516 if (path) {
10517 this.paths.push({
10518 element: path,
10519 length: path.getTotalLength()
10520 });
10521 }
10522 }
10523 const pxRatio = container.retina.pixelRatio;
10524 const scale = options.scale / pxRatio;
10525 this.dimension.width = parseFloat((_a = svg.getAttribute("width")) !== null && _a !== void 0 ? _a : "0") * scale;
10526 this.dimension.height = parseFloat((_b = svg.getAttribute("height")) !== null && _b !== void 0 ? _b : "0") * scale;
10527 const position = (_c = options.position) !== null && _c !== void 0 ? _c : {
10528 x: 50,
10529 y: 50
10530 };
10531 this.offset = {
10532 x: container.canvas.size.width * position.x / (100 * pxRatio) - this.dimension.width / 2,
10533 y: container.canvas.size.height * position.y / (100 * pxRatio) - this.dimension.height / 2
10534 };
10535 return parsePaths(this.paths, scale, this.offset);
10536 }
10537 async downloadSvgPath(svgUrl, force) {
10538 const options = this.options;
10539 const url = svgUrl || options.url;
10540 const forceDownload = force !== null && force !== void 0 ? force : false;
10541 if (!url || this.paths !== undefined && !forceDownload) {
10542 return this.raw;
10543 }
10544 const req = await fetch(url);
10545 if (!req.ok) {
10546 throw new Error("tsParticles Error - Error occurred during polygon mask download");
10547 }
10548 return this.parseSvgPath(await req.text(), force);
10549 }
10550 drawPoints() {
10551 if (!this.raw) {
10552 return;
10553 }
10554 for (const item of this.raw) {
10555 this.container.particles.addParticle({
10556 x: item.x,
10557 y: item.y
10558 });
10559 }
10560 }
10561 randomPoint() {
10562 const container = this.container;
10563 const options = this.options;
10564 let position;
10565 if (options.type === Type.inline) {
10566 switch (options.inline.arrangement) {
10567 case InlineArrangement.randomPoint:
10568 position = this.getRandomPoint();
10569 break;
10570
10571 case InlineArrangement.randomLength:
10572 position = this.getRandomPointByLength();
10573 break;
10574
10575 case InlineArrangement.equidistant:
10576 position = this.getEquidistantPointByIndex(container.particles.count);
10577 break;
10578
10579 case InlineArrangement.onePerPoint:
10580 case InlineArrangement.perPoint:
10581 default:
10582 position = this.getPointByIndex(container.particles.count);
10583 }
10584 } else {
10585 position = {
10586 x: Math.random() * container.canvas.size.width,
10587 y: Math.random() * container.canvas.size.height
10588 };
10589 }
10590 if (this.checkInsidePolygon(position)) {
10591 return position;
10592 } else {
10593 return this.randomPoint();
10594 }
10595 }
10596 getRandomPoint() {
10597 if (!this.raw || !this.raw.length) {
10598 throw new Error(Constants.noPolygonDataLoaded);
10599 }
10600 const coords = itemFromArray(this.raw);
10601 return {
10602 x: coords.x,
10603 y: coords.y
10604 };
10605 }
10606 getRandomPointByLength() {
10607 var _a, _b, _c;
10608 const options = this.options;
10609 if (!this.raw || !this.raw.length || !((_a = this.paths) === null || _a === void 0 ? void 0 : _a.length)) {
10610 throw new Error(Constants.noPolygonDataLoaded);
10611 }
10612 const path = itemFromArray(this.paths);
10613 const distance = Math.floor(Math.random() * path.length) + 1;
10614 const point = path.element.getPointAtLength(distance);
10615 return {
10616 x: point.x * options.scale + (((_b = this.offset) === null || _b === void 0 ? void 0 : _b.x) || 0),
10617 y: point.y * options.scale + (((_c = this.offset) === null || _c === void 0 ? void 0 : _c.y) || 0)
10618 };
10619 }
10620 getEquidistantPointByIndex(index) {
10621 var _a, _b, _c, _d, _e, _f, _g;
10622 const options = this.container.actualOptions;
10623 const polygonMaskOptions = this.options;
10624 if (!this.raw || !this.raw.length || !((_a = this.paths) === null || _a === void 0 ? void 0 : _a.length)) throw new Error(Constants.noPolygonDataLoaded);
10625 let offset = 0;
10626 let point;
10627 const totalLength = this.paths.reduce(((tot, path) => tot + path.length), 0);
10628 const distance = totalLength / options.particles.number.value;
10629 for (const path of this.paths) {
10630 const pathDistance = distance * index - offset;
10631 if (pathDistance <= path.length) {
10632 point = path.element.getPointAtLength(pathDistance);
10633 break;
10634 } else {
10635 offset += path.length;
10636 }
10637 }
10638 return {
10639 x: ((_b = point === null || point === void 0 ? void 0 : point.x) !== null && _b !== void 0 ? _b : 0) * polygonMaskOptions.scale + ((_d = (_c = this.offset) === null || _c === void 0 ? void 0 : _c.x) !== null && _d !== void 0 ? _d : 0),
10640 y: ((_e = point === null || point === void 0 ? void 0 : point.y) !== null && _e !== void 0 ? _e : 0) * polygonMaskOptions.scale + ((_g = (_f = this.offset) === null || _f === void 0 ? void 0 : _f.y) !== null && _g !== void 0 ? _g : 0)
10641 };
10642 }
10643 getPointByIndex(index) {
10644 if (!this.raw || !this.raw.length) {
10645 throw new Error(Constants.noPolygonDataLoaded);
10646 }
10647 const coords = this.raw[index % this.raw.length];
10648 return {
10649 x: coords.x,
10650 y: coords.y
10651 };
10652 }
10653 createPath2D() {
10654 var _a, _b;
10655 const options = this.options;
10656 if (!this.path2DSupported || !((_a = this.paths) === null || _a === void 0 ? void 0 : _a.length)) {
10657 return;
10658 }
10659 for (const path of this.paths) {
10660 const pathData = (_b = path.element) === null || _b === void 0 ? void 0 : _b.getAttribute("d");
10661 if (pathData) {
10662 const path2d = new Path2D(pathData);
10663 const matrix = document.createElementNS("http://www.w3.org/2000/svg", "svg").createSVGMatrix();
10664 const finalPath = new Path2D;
10665 const transform = matrix.scale(options.scale);
10666 if (finalPath.addPath) {
10667 finalPath.addPath(path2d, transform);
10668 path.path2d = finalPath;
10669 } else {
10670 delete path.path2d;
10671 }
10672 } else {
10673 delete path.path2d;
10674 }
10675 if (path.path2d || !this.raw) {
10676 continue;
10677 }
10678 path.path2d = new Path2D;
10679 path.path2d.moveTo(this.raw[0].x, this.raw[0].y);
10680 this.raw.forEach(((pos, i) => {
10681 var _a;
10682 if (i > 0) {
10683 (_a = path.path2d) === null || _a === void 0 ? void 0 : _a.lineTo(pos.x, pos.y);
10684 }
10685 }));
10686 path.path2d.closePath();
10687 }
10688 }
10689 async initRawData(force) {
10690 const options = this.options;
10691 if (options.url) {
10692 this.raw = await this.downloadSvgPath(options.url, force);
10693 } else if (options.data) {
10694 const data = options.data;
10695 let svg;
10696 if (typeof data !== "string") {
10697 const path = data.path instanceof Array ? data.path.map((t => `<path d="${t}" />`)).join("") : `<path d="${data.path}" />`;
10698 const namespaces = 'xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"';
10699 svg = `<svg ${namespaces} width="${data.size.width}" height="${data.size.height}">${path}</svg>`;
10700 } else {
10701 svg = data;
10702 }
10703 this.raw = this.parseSvgPath(svg, force);
10704 }
10705 this.createPath2D();
10706 }
10707 }
10708 class PolygonMask_plugin_Plugin {
10709 constructor() {
10710 this.id = "polygonMask";
10711 }
10712 getPlugin(container) {
10713 return new PolygonMaskInstance(container);
10714 }
10715 needsPlugin(options) {
10716 var _a, _b, _c;
10717 return (_b = (_a = options === null || options === void 0 ? void 0 : options.polygon) === null || _a === void 0 ? void 0 : _a.enable) !== null && _b !== void 0 ? _b : ((_c = options === null || options === void 0 ? void 0 : options.polygon) === null || _c === void 0 ? void 0 : _c.type) !== undefined && options.polygon.type !== Type.none;
10718 }
10719 loadOptions(options, source) {
10720 if (!this.needsPlugin(source)) {
10721 return;
10722 }
10723 const optionsCast = options;
10724 let polygonOptions = optionsCast.polygon;
10725 if ((polygonOptions === null || polygonOptions === void 0 ? void 0 : polygonOptions.load) === undefined) {
10726 optionsCast.polygon = polygonOptions = new PolygonMask;
10727 }
10728 polygonOptions.load(source === null || source === void 0 ? void 0 : source.polygon);
10729 }
10730 }
10731 async function loadPolygonMaskPlugin(tsParticles) {
10732 if (!isSsr() && !window.SVGPathSeg) {
10733 await __webpack_require__.e(917).then(__webpack_require__.t.bind(__webpack_require__, 167, 23));
10734 }
10735 const plugin = new PolygonMask_plugin_Plugin;
10736 tsParticles.addPlugin(plugin);
10737 }
10738 function updateRoll(particle, delta) {
10739 const roll = particle.options.roll;
10740 if (!particle.roll || !roll.enable) {
10741 return;
10742 }
10743 const speed = particle.roll.speed * delta.factor;
10744 const max = 2 * Math.PI;
10745 particle.roll.angle += speed;
10746 if (particle.roll.angle > max) {
10747 particle.roll.angle -= max;
10748 }
10749 }
10750 class RollUpdater {
10751 init(particle) {
10752 const rollOpt = particle.options.roll;
10753 if (rollOpt.enable) {
10754 particle.roll = {
10755 angle: Math.random() * Math.PI * 2,
10756 speed: getRangeValue(rollOpt.speed) / 360
10757 };
10758 if (rollOpt.backColor) {
10759 particle.backColor = colorToHsl(rollOpt.backColor);
10760 } else if (rollOpt.darken.enable && rollOpt.enlighten.enable) {
10761 const alterType = Math.random() >= .5 ? AlterType.darken : AlterType.enlighten;
10762 particle.roll.alter = {
10763 type: alterType,
10764 value: alterType === AlterType.darken ? rollOpt.darken.value : rollOpt.enlighten.value
10765 };
10766 } else if (rollOpt.darken.enable) {
10767 particle.roll.alter = {
10768 type: AlterType.darken,
10769 value: rollOpt.darken.value
10770 };
10771 } else if (rollOpt.enlighten.enable) {
10772 particle.roll.alter = {
10773 type: AlterType.enlighten,
10774 value: rollOpt.enlighten.value
10775 };
10776 }
10777 } else {
10778 particle.roll = {
10779 angle: 0,
10780 speed: 0
10781 };
10782 }
10783 }
10784 isEnabled(particle) {
10785 const roll = particle.options.roll;
10786 return !particle.destroyed && !particle.spawning && roll.enable;
10787 }
10788 update(particle, delta) {
10789 if (!this.isEnabled(particle)) {
10790 return;
10791 }
10792 updateRoll(particle, delta);
10793 }
10794 }
10795 function loadRollUpdater(tsParticles) {
10796 tsParticles.addParticleUpdater("roll", (() => new RollUpdater));
10797 }
10798 function loadFull(tsParticles) {
10799 loadSlim(tsParticles);
10800 loadExternalTrailInteraction(tsParticles);
10801 loadRollUpdater(tsParticles);
10802 loadTiltUpdater(tsParticles);
10803 loadWobbleUpdater(tsParticles);
10804 loadAbsorbersPlugin(tsParticles);
10805 loadEmittersPlugin(tsParticles);
10806 loadPolygonMaskPlugin(tsParticles);
10807 }
10808 const tsParticles = new Main;
10809 tsParticles.init();
10810 loadFull(tsParticles);
10811 const {particlesJS, pJSDom} = initPjs(tsParticles);
10812 return __webpack_exports__;
10813 })();
10814}));
\No newline at end of file