@tsparticles/engine 3.4.0 → 3.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/browser/Core/Container.js +3 -3
- package/browser/Core/Engine.js +1 -1
- package/browser/Utils/NumberUtils.js +17 -4
- package/cjs/Core/Container.js +3 -3
- package/cjs/Core/Engine.js +1 -1
- package/cjs/Utils/CanvasUtils.js +11 -12
- package/cjs/Utils/ColorUtils.js +20 -21
- package/cjs/Utils/NumberUtils.js +43 -28
- package/cjs/Utils/OptionsUtils.js +2 -3
- package/cjs/Utils/TypeUtils.js +6 -7
- package/cjs/Utils/Utils.js +29 -30
- package/cjs/init.js +1 -2
- package/esm/Core/Container.js +3 -3
- package/esm/Core/Engine.js +1 -1
- package/esm/Utils/NumberUtils.js +17 -4
- package/package.json +1 -1
- package/report.html +1 -1
- package/tsparticles.engine.js +6 -6
- package/tsparticles.engine.min.js +1 -1
- package/tsparticles.engine.min.js.LICENSE.txt +1 -1
- package/types/Utils/NumberUtils.d.ts +3 -0
- package/umd/Core/Container.js +4 -4
- package/umd/Core/Engine.js +1 -1
- package/umd/Utils/CanvasUtils.js +11 -12
- package/umd/Utils/ColorUtils.js +20 -21
- package/umd/Utils/NumberUtils.js +43 -28
- package/umd/Utils/OptionsUtils.js +2 -3
- package/umd/Utils/TypeUtils.js +6 -7
- package/umd/Utils/Utils.js +29 -30
- package/umd/init.js +1 -2
package/cjs/Utils/Utils.js
CHANGED
|
@@ -1,6 +1,34 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.setLogger = setLogger;
|
|
4
|
+
exports.getLogger = getLogger;
|
|
5
|
+
exports.isSsr = isSsr;
|
|
6
|
+
exports.hasMatchMedia = hasMatchMedia;
|
|
7
|
+
exports.safeMatchMedia = safeMatchMedia;
|
|
8
|
+
exports.safeIntersectionObserver = safeIntersectionObserver;
|
|
9
|
+
exports.safeMutationObserver = safeMutationObserver;
|
|
10
|
+
exports.isInArray = isInArray;
|
|
11
|
+
exports.loadFont = loadFont;
|
|
12
|
+
exports.arrayRandomIndex = arrayRandomIndex;
|
|
13
|
+
exports.itemFromArray = itemFromArray;
|
|
14
|
+
exports.isPointInside = isPointInside;
|
|
15
|
+
exports.areBoundsInside = areBoundsInside;
|
|
16
|
+
exports.calculateBounds = calculateBounds;
|
|
17
|
+
exports.deepExtend = deepExtend;
|
|
18
|
+
exports.isDivModeEnabled = isDivModeEnabled;
|
|
19
|
+
exports.divModeExecute = divModeExecute;
|
|
20
|
+
exports.singleDivModeExecute = singleDivModeExecute;
|
|
21
|
+
exports.divMode = divMode;
|
|
22
|
+
exports.circleBounceDataFromParticle = circleBounceDataFromParticle;
|
|
23
|
+
exports.circleBounce = circleBounce;
|
|
24
|
+
exports.rectBounce = rectBounce;
|
|
25
|
+
exports.executeOnSingleOrMultiple = executeOnSingleOrMultiple;
|
|
26
|
+
exports.itemFromSingleOrMultiple = itemFromSingleOrMultiple;
|
|
27
|
+
exports.findItemFromSingleOrMultiple = findItemFromSingleOrMultiple;
|
|
28
|
+
exports.initParticleNumericAnimationValue = initParticleNumericAnimationValue;
|
|
29
|
+
exports.getPosition = getPosition;
|
|
30
|
+
exports.getSize = getSize;
|
|
31
|
+
exports.updateAnimation = updateAnimation;
|
|
4
32
|
const NumberUtils_js_1 = require("./NumberUtils.js");
|
|
5
33
|
const Constants_js_1 = require("../Core/Utils/Constants.js");
|
|
6
34
|
const TypeUtils_js_1 = require("./TypeUtils.js");
|
|
@@ -27,11 +55,9 @@ function setLogger(logger) {
|
|
|
27
55
|
_logger.verbose = logger.verbose || _logger.verbose;
|
|
28
56
|
_logger.warning = logger.warning || _logger.warning;
|
|
29
57
|
}
|
|
30
|
-
exports.setLogger = setLogger;
|
|
31
58
|
function getLogger() {
|
|
32
59
|
return _logger;
|
|
33
60
|
}
|
|
34
|
-
exports.getLogger = getLogger;
|
|
35
61
|
function rectSideBounce(data) {
|
|
36
62
|
const res = { bounced: false }, { pSide, pOtherSide, rectSide, rectOtherSide, velocity, factor } = data, half = 0.5, minVelocity = 0;
|
|
37
63
|
if (pOtherSide.min < rectOtherSide.min ||
|
|
@@ -56,37 +82,31 @@ function checkSelector(element, selectors) {
|
|
|
56
82
|
function isSsr() {
|
|
57
83
|
return typeof window === "undefined" || !window || typeof window.document === "undefined" || !window.document;
|
|
58
84
|
}
|
|
59
|
-
exports.isSsr = isSsr;
|
|
60
85
|
function hasMatchMedia() {
|
|
61
86
|
return !isSsr() && typeof matchMedia !== "undefined";
|
|
62
87
|
}
|
|
63
|
-
exports.hasMatchMedia = hasMatchMedia;
|
|
64
88
|
function safeMatchMedia(query) {
|
|
65
89
|
if (!hasMatchMedia()) {
|
|
66
90
|
return;
|
|
67
91
|
}
|
|
68
92
|
return matchMedia(query);
|
|
69
93
|
}
|
|
70
|
-
exports.safeMatchMedia = safeMatchMedia;
|
|
71
94
|
function safeIntersectionObserver(callback) {
|
|
72
95
|
if (isSsr() || typeof IntersectionObserver === "undefined") {
|
|
73
96
|
return;
|
|
74
97
|
}
|
|
75
98
|
return new IntersectionObserver(callback);
|
|
76
99
|
}
|
|
77
|
-
exports.safeIntersectionObserver = safeIntersectionObserver;
|
|
78
100
|
function safeMutationObserver(callback) {
|
|
79
101
|
if (isSsr() || typeof MutationObserver === "undefined") {
|
|
80
102
|
return;
|
|
81
103
|
}
|
|
82
104
|
return new MutationObserver(callback);
|
|
83
105
|
}
|
|
84
|
-
exports.safeMutationObserver = safeMutationObserver;
|
|
85
106
|
function isInArray(value, array) {
|
|
86
107
|
const invalidIndex = -1;
|
|
87
108
|
return value === array || ((0, TypeUtils_js_1.isArray)(array) && array.indexOf(value) > invalidIndex);
|
|
88
109
|
}
|
|
89
|
-
exports.isInArray = isInArray;
|
|
90
110
|
async function loadFont(font, weight) {
|
|
91
111
|
try {
|
|
92
112
|
await document.fonts.load(`${weight ?? "400"} 36px '${font ?? "Verdana"}'`);
|
|
@@ -94,20 +114,16 @@ async function loadFont(font, weight) {
|
|
|
94
114
|
catch {
|
|
95
115
|
}
|
|
96
116
|
}
|
|
97
|
-
exports.loadFont = loadFont;
|
|
98
117
|
function arrayRandomIndex(array) {
|
|
99
118
|
return Math.floor((0, NumberUtils_js_1.getRandom)() * array.length);
|
|
100
119
|
}
|
|
101
|
-
exports.arrayRandomIndex = arrayRandomIndex;
|
|
102
120
|
function itemFromArray(array, index, useIndex = true) {
|
|
103
121
|
return array[index !== undefined && useIndex ? index % array.length : arrayRandomIndex(array)];
|
|
104
122
|
}
|
|
105
|
-
exports.itemFromArray = itemFromArray;
|
|
106
123
|
function isPointInside(point, size, offset, radius, direction) {
|
|
107
124
|
const minRadius = 0;
|
|
108
125
|
return areBoundsInside(calculateBounds(point, radius ?? minRadius), size, offset, direction);
|
|
109
126
|
}
|
|
110
|
-
exports.isPointInside = isPointInside;
|
|
111
127
|
function areBoundsInside(bounds, size, offset, direction) {
|
|
112
128
|
let inside = true;
|
|
113
129
|
if (!direction || direction === OutModeDirection_js_1.OutModeDirection.bottom) {
|
|
@@ -124,7 +140,6 @@ function areBoundsInside(bounds, size, offset, direction) {
|
|
|
124
140
|
}
|
|
125
141
|
return inside;
|
|
126
142
|
}
|
|
127
|
-
exports.areBoundsInside = areBoundsInside;
|
|
128
143
|
function calculateBounds(point, radius) {
|
|
129
144
|
return {
|
|
130
145
|
bottom: point.y + radius,
|
|
@@ -133,7 +148,6 @@ function calculateBounds(point, radius) {
|
|
|
133
148
|
top: point.y - radius,
|
|
134
149
|
};
|
|
135
150
|
}
|
|
136
|
-
exports.calculateBounds = calculateBounds;
|
|
137
151
|
function deepExtend(destination, ...sources) {
|
|
138
152
|
for (const source of sources) {
|
|
139
153
|
if (source === undefined || source === null) {
|
|
@@ -163,11 +177,9 @@ function deepExtend(destination, ...sources) {
|
|
|
163
177
|
}
|
|
164
178
|
return destination;
|
|
165
179
|
}
|
|
166
|
-
exports.deepExtend = deepExtend;
|
|
167
180
|
function isDivModeEnabled(mode, divs) {
|
|
168
181
|
return !!findItemFromSingleOrMultiple(divs, t => t.enable && isInArray(mode, t.mode));
|
|
169
182
|
}
|
|
170
|
-
exports.isDivModeEnabled = isDivModeEnabled;
|
|
171
183
|
function divModeExecute(mode, divs, callback) {
|
|
172
184
|
executeOnSingleOrMultiple(divs, div => {
|
|
173
185
|
const divMode = div.mode, divEnabled = div.enable;
|
|
@@ -176,14 +188,12 @@ function divModeExecute(mode, divs, callback) {
|
|
|
176
188
|
}
|
|
177
189
|
});
|
|
178
190
|
}
|
|
179
|
-
exports.divModeExecute = divModeExecute;
|
|
180
191
|
function singleDivModeExecute(div, callback) {
|
|
181
192
|
const selectors = div.selectors;
|
|
182
193
|
executeOnSingleOrMultiple(selectors, selector => {
|
|
183
194
|
callback(selector, div);
|
|
184
195
|
});
|
|
185
196
|
}
|
|
186
|
-
exports.singleDivModeExecute = singleDivModeExecute;
|
|
187
197
|
function divMode(divs, element) {
|
|
188
198
|
if (!element || !divs) {
|
|
189
199
|
return;
|
|
@@ -192,7 +202,6 @@ function divMode(divs, element) {
|
|
|
192
202
|
return checkSelector(element, div.selectors);
|
|
193
203
|
});
|
|
194
204
|
}
|
|
195
|
-
exports.divMode = divMode;
|
|
196
205
|
function circleBounceDataFromParticle(p) {
|
|
197
206
|
return {
|
|
198
207
|
position: p.getPosition(),
|
|
@@ -202,7 +211,6 @@ function circleBounceDataFromParticle(p) {
|
|
|
202
211
|
factor: Vectors_js_1.Vector.create((0, NumberUtils_js_1.getRangeValue)(p.options.bounce.horizontal.value), (0, NumberUtils_js_1.getRangeValue)(p.options.bounce.vertical.value)),
|
|
203
212
|
};
|
|
204
213
|
}
|
|
205
|
-
exports.circleBounceDataFromParticle = circleBounceDataFromParticle;
|
|
206
214
|
function circleBounce(p1, p2) {
|
|
207
215
|
const { x: xVelocityDiff, y: yVelocityDiff } = p1.velocity.sub(p2.velocity), [pos1, pos2] = [p1.position, p2.position], { dx: xDist, dy: yDist } = (0, NumberUtils_js_1.getDistances)(pos2, pos1), minimumDistance = 0;
|
|
208
216
|
if (xVelocityDiff * xDist + yVelocityDiff * yDist < minimumDistance) {
|
|
@@ -214,7 +222,6 @@ function circleBounce(p1, p2) {
|
|
|
214
222
|
p2.velocity.x = vFinal2.x * p2.factor.x;
|
|
215
223
|
p2.velocity.y = vFinal2.y * p2.factor.y;
|
|
216
224
|
}
|
|
217
|
-
exports.circleBounce = circleBounce;
|
|
218
225
|
function rectBounce(particle, divBounds) {
|
|
219
226
|
const pPos = particle.getPosition(), size = particle.getRadius(), bounds = calculateBounds(pPos, size), bounceOptions = particle.options.bounce, resH = rectSideBounce({
|
|
220
227
|
pSide: {
|
|
@@ -273,16 +280,13 @@ function rectBounce(particle, divBounds) {
|
|
|
273
280
|
}
|
|
274
281
|
}
|
|
275
282
|
}
|
|
276
|
-
exports.rectBounce = rectBounce;
|
|
277
283
|
function executeOnSingleOrMultiple(obj, callback) {
|
|
278
284
|
const defaultIndex = 0;
|
|
279
285
|
return (0, TypeUtils_js_1.isArray)(obj) ? obj.map((item, index) => callback(item, index)) : callback(obj, defaultIndex);
|
|
280
286
|
}
|
|
281
|
-
exports.executeOnSingleOrMultiple = executeOnSingleOrMultiple;
|
|
282
287
|
function itemFromSingleOrMultiple(obj, index, useIndex) {
|
|
283
288
|
return (0, TypeUtils_js_1.isArray)(obj) ? itemFromArray(obj, index, useIndex) : obj;
|
|
284
289
|
}
|
|
285
|
-
exports.itemFromSingleOrMultiple = itemFromSingleOrMultiple;
|
|
286
290
|
function findItemFromSingleOrMultiple(obj, callback) {
|
|
287
291
|
if ((0, TypeUtils_js_1.isArray)(obj)) {
|
|
288
292
|
return obj.find((t, index) => callback(t, index));
|
|
@@ -290,7 +294,6 @@ function findItemFromSingleOrMultiple(obj, callback) {
|
|
|
290
294
|
const defaultIndex = 0;
|
|
291
295
|
return callback(obj, defaultIndex) ? obj : undefined;
|
|
292
296
|
}
|
|
293
|
-
exports.findItemFromSingleOrMultiple = findItemFromSingleOrMultiple;
|
|
294
297
|
function initParticleNumericAnimationValue(options, pxRatio) {
|
|
295
298
|
const valueRange = options.value, animationOptions = options.animation, res = {
|
|
296
299
|
delayTime: (0, NumberUtils_js_1.getRangeValue)(animationOptions.delay) * Constants_js_1.millisecondsToSeconds,
|
|
@@ -341,7 +344,6 @@ function initParticleNumericAnimationValue(options, pxRatio) {
|
|
|
341
344
|
res.initialValue = res.value;
|
|
342
345
|
return res;
|
|
343
346
|
}
|
|
344
|
-
exports.initParticleNumericAnimationValue = initParticleNumericAnimationValue;
|
|
345
347
|
function getPositionOrSize(positionOrSize, canvasSize) {
|
|
346
348
|
const isPercent = positionOrSize.mode === PixelMode_js_1.PixelMode.percent;
|
|
347
349
|
if (!isPercent) {
|
|
@@ -365,11 +367,9 @@ function getPositionOrSize(positionOrSize, canvasSize) {
|
|
|
365
367
|
function getPosition(position, canvasSize) {
|
|
366
368
|
return getPositionOrSize(position, canvasSize);
|
|
367
369
|
}
|
|
368
|
-
exports.getPosition = getPosition;
|
|
369
370
|
function getSize(size, canvasSize) {
|
|
370
371
|
return getPositionOrSize(size, canvasSize);
|
|
371
372
|
}
|
|
372
|
-
exports.getSize = getSize;
|
|
373
373
|
function checkDestroy(particle, destroyType, value, minValue, maxValue) {
|
|
374
374
|
switch (destroyType) {
|
|
375
375
|
case DestroyType_js_1.DestroyType.max:
|
|
@@ -445,4 +445,3 @@ function updateAnimation(particle, data, changeDirection, destroyType, delta) {
|
|
|
445
445
|
data.value = (0, NumberUtils_js_1.clamp)(data.value, minValue, maxValue);
|
|
446
446
|
}
|
|
447
447
|
}
|
|
448
|
-
exports.updateAnimation = updateAnimation;
|
package/cjs/init.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.init =
|
|
3
|
+
exports.init = init;
|
|
4
4
|
const Engine_js_1 = require("./Core/Engine.js");
|
|
5
5
|
const HslColorManager_js_1 = require("./Utils/HslColorManager.js");
|
|
6
6
|
const RgbColorManager_js_1 = require("./Utils/RgbColorManager.js");
|
|
@@ -13,4 +13,3 @@ function init() {
|
|
|
13
13
|
engine.init();
|
|
14
14
|
return engine;
|
|
15
15
|
}
|
|
16
|
-
exports.init = init;
|
package/esm/Core/Container.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { animate, cancelAnimation, getRangeValue } from "../Utils/NumberUtils.js";
|
|
1
2
|
import { errorPrefix, millisecondsToSeconds } from "./Utils/Constants.js";
|
|
2
3
|
import { getLogger, safeIntersectionObserver } from "../Utils/Utils.js";
|
|
3
4
|
import { Canvas } from "./Canvas.js";
|
|
@@ -6,7 +7,6 @@ import { EventType } from "../Enums/Types/EventType.js";
|
|
|
6
7
|
import { Options } from "../Options/Classes/Options.js";
|
|
7
8
|
import { Particles } from "./Particles.js";
|
|
8
9
|
import { Retina } from "./Retina.js";
|
|
9
|
-
import { getRangeValue } from "../Utils/NumberUtils.js";
|
|
10
10
|
import { loadOptions } from "../Utils/OptionsUtils.js";
|
|
11
11
|
function guardCheck(container) {
|
|
12
12
|
return container && !container.destroyed;
|
|
@@ -255,7 +255,7 @@ export class Container {
|
|
|
255
255
|
}
|
|
256
256
|
this._nextFrame(timestamp);
|
|
257
257
|
};
|
|
258
|
-
this._drawAnimationFrame =
|
|
258
|
+
this._drawAnimationFrame = animate(timestamp => frame(timestamp));
|
|
259
259
|
}
|
|
260
260
|
async export(type, options = {}) {
|
|
261
261
|
for (const [, plugin] of this.plugins) {
|
|
@@ -346,7 +346,7 @@ export class Container {
|
|
|
346
346
|
return;
|
|
347
347
|
}
|
|
348
348
|
if (this._drawAnimationFrame !== undefined) {
|
|
349
|
-
|
|
349
|
+
cancelAnimation(this._drawAnimationFrame);
|
|
350
350
|
delete this._drawAnimationFrame;
|
|
351
351
|
}
|
|
352
352
|
if (this._paused) {
|
package/esm/Core/Engine.js
CHANGED
package/esm/Utils/NumberUtils.js
CHANGED
|
@@ -3,15 +3,18 @@ import { Vector } from "../Core/Utils/Vectors.js";
|
|
|
3
3
|
import { isNumber } from "./TypeUtils.js";
|
|
4
4
|
import { percentDenominator } from "../Core/Utils/Constants.js";
|
|
5
5
|
let _random = Math.random;
|
|
6
|
-
const
|
|
6
|
+
const _animationLoop = {
|
|
7
|
+
nextFrame: (cb) => requestAnimationFrame(cb),
|
|
8
|
+
cancel: (idx) => cancelAnimationFrame(idx),
|
|
9
|
+
}, easingFunctions = new Map(), double = 2, doublePI = Math.PI * double;
|
|
7
10
|
export function addEasing(name, easing) {
|
|
8
|
-
if (
|
|
11
|
+
if (easingFunctions.get(name)) {
|
|
9
12
|
return;
|
|
10
13
|
}
|
|
11
|
-
|
|
14
|
+
easingFunctions.set(name, easing);
|
|
12
15
|
}
|
|
13
16
|
export function getEasing(name) {
|
|
14
|
-
return
|
|
17
|
+
return easingFunctions.get(name) ?? ((value) => value);
|
|
15
18
|
}
|
|
16
19
|
export function setRandom(rnd = Math.random) {
|
|
17
20
|
_random = rnd;
|
|
@@ -20,6 +23,16 @@ export function getRandom() {
|
|
|
20
23
|
const min = 0, max = 1;
|
|
21
24
|
return clamp(_random(), min, max - Number.EPSILON);
|
|
22
25
|
}
|
|
26
|
+
export function setAnimationFunctions(nextFrame, cancel) {
|
|
27
|
+
_animationLoop.nextFrame = (callback) => nextFrame(callback);
|
|
28
|
+
_animationLoop.cancel = (handle) => cancel(handle);
|
|
29
|
+
}
|
|
30
|
+
export function animate(fn) {
|
|
31
|
+
return _animationLoop.nextFrame(fn);
|
|
32
|
+
}
|
|
33
|
+
export function cancelAnimation(handle) {
|
|
34
|
+
_animationLoop.cancel(handle);
|
|
35
|
+
}
|
|
23
36
|
export function clamp(num, min, max) {
|
|
24
37
|
return Math.min(Math.max(num, min), max);
|
|
25
38
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tsparticles/engine",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.5.0",
|
|
4
4
|
"description": "Easily create highly customizable particle, confetti and fireworks animations and use them as animated backgrounds for your website. Ready to use components available also for React, Vue.js (2.x and 3.x), Angular, Svelte, jQuery, Preact, Riot.js, Inferno.",
|
|
5
5
|
"homepage": "https://particles.js.org",
|
|
6
6
|
"scripts": {
|
package/report.html
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
<head>
|
|
4
4
|
<meta charset="UTF-8"/>
|
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1"/>
|
|
6
|
-
<title>@tsparticles/engine [
|
|
6
|
+
<title>@tsparticles/engine [1 Jul 2024 at 09:14]</title>
|
|
7
7
|
<link rel="shortcut icon" href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAMAAACdt4HsAAABrVBMVEUAAAD///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////+O1foceMD///+J0/qK1Pr7/v8Xdr/9///W8P4UdL7L7P0Scr2r4Pyj3vwad8D5/f/2/f+55f3E6f34+/2H0/ojfMKpzOd0rNgQcb3F3O/j9f7c8v6g3Pz0/P/w+v/q+P7n9v6T1/uQ1vuE0vqLut/y+v+Z2fvt+f+15Pzv9fuc2/vR7v2V2Pvd6/bg9P7I6/285/2y4/yp3/zp8vk8i8kqgMT7/P31+fyv4vxGkcz6/P6/6P3j7vfS5PNnpNUxhcbO7f7F6v3O4vHK3/DA2u631Ouy0eqXweKJud5wqthfoNMMbLvY8f73+v2dxeR8sNtTmdDx9/zX6PSjyeaCtd1YnNGX2PuQveCGt95Nls42h8dLlM3F4vBtAAAAM3RSTlMAAyOx0/sKBvik8opWGBMOAe3l1snDm2E9LSb06eHcu5JpHbarfHZCN9CBb08zzkdNS0kYaptYAAAFV0lEQVRYw92X51/aYBDHHS2O2qqttVbrqNq9m+TJIAYIShBkWwqIiCgoWvfeq7Z2/s29hyQNyUcR7LveGwVyXy6XH8/9rqxglLfUPLxVduUor3h0rfp2TYvpivk37929TkG037hffoX0+peVtZQc1589rigVUdXS/ABSAyEmGIO/1XfvldSK8vs3OqB6u3m0nxmIrvgB0dj7rr7Y9IbuF68hnfFaiHA/sxqm0wciIG43P60qKv9WXWc1RXGh/mFESFABTSBi0sNAKzqet17eCtOb3kZIDwxEEU0oAIJGYxNBDhBND29e0rtXXbcpuPmED9IhEAAQ/AXEaF8EPmnrrKsv0LvWR3fg5sWDNAFZOgAgaKvZDogHNU9MFwnnYROkc56RD5CjAbQX9Ow4g7upCsvYu55aSI/Nj0H1akgKQEUM94dwK65hYRmFU9MIcH/fqJYOZYcnuJSU/waKDgTOEVaVKhwrTRP5XzgSpAITYzom7UvkhFX5VutmxeNnWDjjswTKTyfgluNDGbUpWissXhF3s7mlSml+czWkg3D0l1nNjGNjz3myOQOa1KM/jOS6ebdbAVTCi4gljHSFrviza7tOgRWcS0MOUX9zdNgag5w7rRqA44Lzw0hr1WqES36dFliSJFlh2rXIae3FFcDDgKdxrUIDePr8jGcSClV1u7A9xeN0ModY/pHMxmR1EzRh8TJiwqsHmKW0l4FCEZI+jHio+JdPPE9qwQtTRxku2D8sIeRL2LnxWSllANCQGOIiqVHAz2ye2JR0DcH+HoxDkaADLjgxjKQ+AwCX/g0+DNgdG0ukYCONAe+dbc2IAc6fwt1ARoDSezNHxV2Cmzwv3O6lDMV55edBGwGK9n1+x2F8EDfAGCxug8MhpsMEcTEAWf3rx2vZhe/LAmtIn/6apE6PN0ULKgywD9mmdxbmFl3OvD5AS5fW5zLbv/YHmcsBTjf/afDz3MaZTVCfAP9z6/Bw6ycv8EUBWJIn9zYcoAWWlW9+OzO3vkTy8H+RANLmdrpOuYWdZYEXpo+TlCJrW5EARb7fF+bWdqf3hhyZI1nWJQHgznErZhbjoEsWqi8dQNoE294aldzFurwSABL2XXMf9+H1VQGke9exw5P/AnA5Pv5ngMul7LOvO922iwACu8WkCwLCafvM4CeWPxfA8lNHcWZSoi8EwMAIciKX2Z4SWCMAa3snCZ/G4EA8D6CMLNFsGQhkkz/gQNEBbPCbWsxGUpYVu3z8IyNAknwJkfPMEhLyrdi5RTyUVACkw4GSFRNWJNEW+fgPGwHD8/JxnRuLabN4CGNRkAE23na2+VmEAUmrYymSGjMAYqH84YUIyzgzs3XC7gNgH36Vcc4zKY9o9fgPBXUAiHHwVboBHGLiX6Zcjp1f2wu4tvzZKo0ecPnDtQYDQvJXaBeNzce45Fp28ZQLrEZVuFqgBwOalArKXnW1UzlnSusQKJqKYNuz4tOnI6sZG4zanpemv+7ySU2jbA9h6uhcgpfy6G2PahirDZ6zvq6zDduMVFTKvzw8wgyEdelwY9in3XkEPs3osJuwRQ4qTkfzifndg9Gfc4pdsu82+tTnHZTBa2EAMrqr2t43pguc8tNm7JQVQ2S0ukj2d22dhXYP0/veWtwKrCkNoNimAN5+Xr/oLrxswKbVJjteWrX7eR63o4j9q0GxnaBdWgGA5VStpanIjQmEhV0/nVt5VOFUvix6awJhPcAaTEShgrG+iGyvb5a0Ndb1YGHFPEwoqAinoaykaID1o1pdPNu7XsnCKQ3R+hwWIIhGvORcJUBYXe3Xa3vq/mF/N9V13ugufMkfXn+KHsRD0B8AAAAASUVORK5CYII=" type="image/x-icon" />
|
|
8
8
|
|
|
9
9
|
<script>
|