@tsparticles/plugin-absorbers 4.0.0-alpha.3 → 4.0.0-alpha.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (64) hide show
  1. package/215.min.js +2 -0
  2. package/215.min.js.LICENSE.txt +1 -0
  3. package/384.min.js +2 -0
  4. package/384.min.js.LICENSE.txt +1 -0
  5. package/688.min.js +2 -0
  6. package/688.min.js.LICENSE.txt +1 -0
  7. package/903.min.js +2 -0
  8. package/903.min.js.LICENSE.txt +1 -0
  9. package/980.min.js +2 -0
  10. package/980.min.js.LICENSE.txt +1 -0
  11. package/browser/AbsorberInstance.js +6 -24
  12. package/browser/AbsorbersInstancesManager.js +47 -0
  13. package/browser/AbsorbersInteractor.js +90 -0
  14. package/browser/AbsorbersPlugin.js +6 -16
  15. package/browser/AbsorbersPluginInstance.js +40 -0
  16. package/browser/index.js +10 -6
  17. package/cjs/AbsorberInstance.js +6 -24
  18. package/cjs/AbsorbersInstancesManager.js +47 -0
  19. package/cjs/AbsorbersInteractor.js +90 -0
  20. package/cjs/AbsorbersPlugin.js +6 -16
  21. package/cjs/AbsorbersPluginInstance.js +40 -0
  22. package/cjs/index.js +10 -6
  23. package/dist_browser_AbsorberInstance_js.js +60 -0
  24. package/dist_browser_AbsorbersInstancesManager_js.js +30 -0
  25. package/dist_browser_AbsorbersInteractor_js.js +60 -0
  26. package/dist_browser_AbsorbersPluginInstance_js.js +30 -0
  27. package/dist_browser_AbsorbersPlugin_js.js +2 -22
  28. package/esm/AbsorberInstance.js +6 -24
  29. package/esm/AbsorbersInstancesManager.js +47 -0
  30. package/esm/AbsorbersInteractor.js +90 -0
  31. package/esm/AbsorbersPlugin.js +6 -16
  32. package/esm/AbsorbersPluginInstance.js +40 -0
  33. package/esm/index.js +10 -6
  34. package/package.json +3 -2
  35. package/report.html +1 -1
  36. package/tsparticles.plugin.absorbers.js +48 -30
  37. package/tsparticles.plugin.absorbers.min.js +1 -1
  38. package/tsparticles.plugin.absorbers.min.js.LICENSE.txt +1 -1
  39. package/types/AbsorberContainer.d.ts +5 -4
  40. package/types/AbsorberInstance.d.ts +5 -5
  41. package/types/AbsorbersInstancesManager.d.ts +14 -0
  42. package/types/AbsorbersInteractor.d.ts +18 -0
  43. package/types/AbsorbersPlugin.d.ts +6 -6
  44. package/types/AbsorbersPluginInstance.d.ts +13 -0
  45. package/types/index.d.ts +1 -2
  46. package/types/types.d.ts +12 -9
  47. package/umd/AbsorberInstance.js +5 -23
  48. package/umd/AbsorbersInstancesManager.js +95 -0
  49. package/umd/AbsorbersInteractor.js +104 -0
  50. package/umd/AbsorbersPlugin.js +40 -16
  51. package/umd/AbsorbersPluginInstance.js +54 -0
  52. package/umd/index.js +11 -10
  53. package/47.min.js +0 -2
  54. package/47.min.js.LICENSE.txt +0 -1
  55. package/browser/Absorbers.js +0 -70
  56. package/browser/Enums/AbsorberClickMode.js +0 -4
  57. package/cjs/Absorbers.js +0 -70
  58. package/cjs/Enums/AbsorberClickMode.js +0 -4
  59. package/esm/Absorbers.js +0 -70
  60. package/esm/Enums/AbsorberClickMode.js +0 -4
  61. package/types/Absorbers.d.ts +0 -21
  62. package/types/Enums/AbsorberClickMode.d.ts +0 -3
  63. package/umd/Absorbers.js +0 -84
  64. package/umd/Enums/AbsorberClickMode.js +0 -17
@@ -0,0 +1,60 @@
1
+ /*!
2
+ * Author : Matteo Bruni
3
+ * MIT license: https://opensource.org/licenses/MIT
4
+ * Demo / Generator : https://particles.js.org/
5
+ * GitHub : https://www.github.com/matteobruni/tsparticles
6
+ * How to use? : Check the GitHub README
7
+ * v4.0.0-alpha.5
8
+ */
9
+ "use strict";
10
+ /*
11
+ * ATTENTION: The "eval" devtool has been used (maybe by default in mode: "development").
12
+ * This devtool is neither made for production nor for readable output files.
13
+ * It uses "eval()" calls to create a separate source file in the browser devtools.
14
+ * If you are trying to read the output file, select a different devtool (https://webpack.js.org/configuration/devtool/)
15
+ * or disable the default devtool with "devtool: false".
16
+ * If you are looking for production-ready output files, see mode: "production" (https://webpack.js.org/configuration/mode/).
17
+ */
18
+ (this["webpackChunk_tsparticles_plugin_absorbers"] = this["webpackChunk_tsparticles_plugin_absorbers"] || []).push([["dist_browser_AbsorberInstance_js"],{
19
+
20
+ /***/ "./dist/browser/AbsorberInstance.js"
21
+ /*!******************************************!*\
22
+ !*** ./dist/browser/AbsorberInstance.js ***!
23
+ \******************************************/
24
+ (__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) {
25
+
26
+ eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ AbsorberInstance: () => (/* binding */ AbsorberInstance)\n/* harmony export */ });\n/* harmony import */ var _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @tsparticles/engine */ \"@tsparticles/engine\");\n/* harmony import */ var _Options_Classes_Absorber_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./Options/Classes/Absorber.js */ \"./dist/browser/Options/Classes/Absorber.js\");\n\n\nconst squareExp = 2,\n absorbFactor = 0.033,\n minOrbitLength = 0,\n minRadius = 0,\n minMass = 0,\n minAngle = 0,\n maxAngle = _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.doublePI,\n minVelocity = 0;\nclass AbsorberInstance {\n constructor(engine, container, options, position) {\n this._calcPosition = () => {\n const exactPosition = (0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.calcPositionOrRandomFromSizeRanged)({\n size: this._container.canvas.size,\n position: this.options.position\n });\n return _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.Vector.create(exactPosition.x, exactPosition.y);\n };\n this._updateParticlePosition = (particle, v) => {\n if (particle.destroyed) {\n return;\n }\n const container = this._container,\n canvasSize = container.canvas.size;\n if (particle.needsNewPosition) {\n const newPosition = (0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.calcPositionOrRandomFromSize)({\n size: canvasSize\n });\n particle.position.setTo(newPosition);\n particle.velocity.setTo(particle.initialVelocity);\n particle.absorberOrbit = undefined;\n particle.needsNewPosition = false;\n }\n if (this.options.orbits) {\n if (particle.absorberOrbit === undefined) {\n particle.absorberOrbit = _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.Vector.origin;\n particle.absorberOrbit.length = (0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.getDistance)(particle.getPosition(), this.position);\n particle.absorberOrbit.angle = (0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.getRandom)() * maxAngle;\n }\n if (particle.absorberOrbit.length <= this.size && !this.options.destroy) {\n const minSize = Math.min(canvasSize.width, canvasSize.height),\n offset = 1,\n randomOffset = 0.1,\n randomFactor = 0.2;\n particle.absorberOrbit.length = minSize * (offset + ((0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.getRandom)() * randomFactor - randomOffset));\n }\n particle.absorberOrbitDirection ??= particle.velocity.x >= minVelocity ? _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.RotateDirection.clockwise : _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.RotateDirection.counterClockwise;\n const orbitRadius = particle.absorberOrbit.length,\n orbitAngle = particle.absorberOrbit.angle,\n orbitDirection = particle.absorberOrbitDirection;\n particle.velocity.setTo(_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.Vector.origin);\n const updateFunc = {\n x: orbitDirection === _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.RotateDirection.clockwise ? Math.cos : Math.sin,\n y: orbitDirection === _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.RotateDirection.clockwise ? Math.sin : Math.cos\n };\n particle.position.x = this.position.x + orbitRadius * updateFunc.x(orbitAngle);\n particle.position.y = this.position.y + orbitRadius * updateFunc.y(orbitAngle);\n particle.absorberOrbit.length -= v.length;\n particle.absorberOrbit.angle += (particle.retina.moveSpeed ?? minVelocity) * container.retina.pixelRatio / _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.percentDenominator * container.retina.reduceFactor;\n } else {\n const addV = _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.Vector.origin;\n addV.length = v.length;\n addV.angle = v.angle;\n particle.velocity.addTo(addV);\n }\n };\n this._container = container;\n this._engine = engine;\n this.initialPosition = position ? _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.Vector.create(position.x, position.y) : undefined;\n if (options instanceof _Options_Classes_Absorber_js__WEBPACK_IMPORTED_MODULE_1__.Absorber) {\n this.options = options;\n } else {\n this.options = new _Options_Classes_Absorber_js__WEBPACK_IMPORTED_MODULE_1__.Absorber();\n this.options.load(options);\n }\n this.name = this.options.name;\n this.opacity = this.options.opacity;\n this.size = (0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.getRangeValue)(this.options.size.value) * container.retina.pixelRatio;\n this.mass = this.size * this.options.size.density * container.retina.reduceFactor;\n const limit = this.options.size.limit;\n this.limit = {\n radius: limit.radius * container.retina.pixelRatio * container.retina.reduceFactor,\n mass: limit.mass\n };\n this.color = (0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.rangeColorToRgb)(this._engine, this.options.color) ?? {\n b: 0,\n g: 0,\n r: 0\n };\n this.position = this.initialPosition?.copy() ?? this._calcPosition();\n }\n attract(particle, delta) {\n const container = this._container,\n options = this.options,\n pos = particle.getPosition(),\n {\n dx,\n dy,\n distance\n } = (0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.getDistances)(this.position, pos),\n v = _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.Vector.create(dx, dy);\n v.length = this.mass / Math.pow(distance, squareExp) * container.retina.reduceFactor;\n if (distance < this.size + particle.getRadius()) {\n const sizeFactor = particle.getRadius() * absorbFactor * container.retina.pixelRatio * delta.factor;\n if (this.size > particle.getRadius() && distance < this.size - particle.getRadius() || particle.absorberOrbit !== undefined && particle.absorberOrbit.length < minOrbitLength) {\n if (options.destroy) {\n particle.destroy();\n } else {\n particle.needsNewPosition = true;\n this._updateParticlePosition(particle, v);\n }\n } else {\n if (options.destroy) {\n particle.size.value -= sizeFactor;\n }\n this._updateParticlePosition(particle, v);\n }\n if (this.limit.radius <= minRadius || this.size < this.limit.radius) {\n this.size += sizeFactor;\n }\n if (this.limit.mass <= minMass || this.mass < this.limit.mass) {\n this.mass += sizeFactor * this.options.size.density * container.retina.reduceFactor;\n }\n } else {\n this._updateParticlePosition(particle, v);\n }\n }\n draw(context) {\n context.translate(this.position.x, this.position.y);\n context.beginPath();\n context.arc(_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.originPoint.x, _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.originPoint.y, this.size, minAngle, maxAngle, false);\n context.closePath();\n context.fillStyle = (0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.getStyleFromRgb)(this.color, this._container.hdr, this.opacity);\n context.fill();\n }\n resize() {\n const initialPosition = this.initialPosition;\n this.position = initialPosition && (0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.isPointInside)(initialPosition, this._container.canvas.size, _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.Vector.origin) ? initialPosition : this._calcPosition();\n }\n}\n\n//# sourceURL=webpack://@tsparticles/plugin-absorbers/./dist/browser/AbsorberInstance.js?\n}");
27
+
28
+ /***/ },
29
+
30
+ /***/ "./dist/browser/Options/Classes/Absorber.js"
31
+ /*!**************************************************!*\
32
+ !*** ./dist/browser/Options/Classes/Absorber.js ***!
33
+ \**************************************************/
34
+ (__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) {
35
+
36
+ eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ Absorber: () => (/* binding */ Absorber)\n/* harmony export */ });\n/* harmony import */ var _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @tsparticles/engine */ \"@tsparticles/engine\");\n/* harmony import */ var _AbsorberSize_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./AbsorberSize.js */ \"./dist/browser/Options/Classes/AbsorberSize.js\");\n\n\nclass Absorber {\n constructor() {\n this.color = new _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.OptionsColor();\n this.color.value = \"#000000\";\n this.draggable = false;\n this.opacity = 1;\n this.destroy = true;\n this.orbits = false;\n this.size = new _AbsorberSize_js__WEBPACK_IMPORTED_MODULE_1__.AbsorberSize();\n }\n load(data) {\n if ((0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.isNull)(data)) {\n return;\n }\n if (data.color !== undefined) {\n this.color = _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.OptionsColor.create(this.color, data.color);\n }\n if (data.draggable !== undefined) {\n this.draggable = data.draggable;\n }\n this.name = data.name;\n if (data.opacity !== undefined) {\n this.opacity = data.opacity;\n }\n if (data.position !== undefined) {\n this.position = {};\n if (data.position.x !== undefined) {\n this.position.x = (0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.setRangeValue)(data.position.x);\n }\n if (data.position.y !== undefined) {\n this.position.y = (0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.setRangeValue)(data.position.y);\n }\n }\n if (data.size !== undefined) {\n this.size.load(data.size);\n }\n if (data.destroy !== undefined) {\n this.destroy = data.destroy;\n }\n if (data.orbits !== undefined) {\n this.orbits = data.orbits;\n }\n }\n}\n\n//# sourceURL=webpack://@tsparticles/plugin-absorbers/./dist/browser/Options/Classes/Absorber.js?\n}");
37
+
38
+ /***/ },
39
+
40
+ /***/ "./dist/browser/Options/Classes/AbsorberSize.js"
41
+ /*!******************************************************!*\
42
+ !*** ./dist/browser/Options/Classes/AbsorberSize.js ***!
43
+ \******************************************************/
44
+ (__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) {
45
+
46
+ eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ AbsorberSize: () => (/* binding */ AbsorberSize)\n/* harmony export */ });\n/* harmony import */ var _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @tsparticles/engine */ \"@tsparticles/engine\");\n/* harmony import */ var _AbsorberSizeLimit_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./AbsorberSizeLimit.js */ \"./dist/browser/Options/Classes/AbsorberSizeLimit.js\");\n\n\nclass AbsorberSize extends _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.ValueWithRandom {\n constructor() {\n super();\n this.density = 5;\n this.value = 50;\n this.limit = new _AbsorberSizeLimit_js__WEBPACK_IMPORTED_MODULE_1__.AbsorberSizeLimit();\n }\n load(data) {\n if ((0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.isNull)(data)) {\n return;\n }\n super.load(data);\n if (data.density !== undefined) {\n this.density = data.density;\n }\n if ((0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.isNumber)(data.limit)) {\n this.limit.radius = data.limit;\n } else {\n this.limit.load(data.limit);\n }\n }\n}\n\n//# sourceURL=webpack://@tsparticles/plugin-absorbers/./dist/browser/Options/Classes/AbsorberSize.js?\n}");
47
+
48
+ /***/ },
49
+
50
+ /***/ "./dist/browser/Options/Classes/AbsorberSizeLimit.js"
51
+ /*!***********************************************************!*\
52
+ !*** ./dist/browser/Options/Classes/AbsorberSizeLimit.js ***!
53
+ \***********************************************************/
54
+ (__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) {
55
+
56
+ eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ AbsorberSizeLimit: () => (/* binding */ AbsorberSizeLimit)\n/* harmony export */ });\n/* harmony import */ var _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @tsparticles/engine */ \"@tsparticles/engine\");\n\nclass AbsorberSizeLimit {\n constructor() {\n this.radius = 0;\n this.mass = 0;\n }\n load(data) {\n if ((0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.isNull)(data)) {\n return;\n }\n if (data.mass !== undefined) {\n this.mass = data.mass;\n }\n if (data.radius !== undefined) {\n this.radius = data.radius;\n }\n }\n}\n\n//# sourceURL=webpack://@tsparticles/plugin-absorbers/./dist/browser/Options/Classes/AbsorberSizeLimit.js?\n}");
57
+
58
+ /***/ }
59
+
60
+ }]);
@@ -0,0 +1,30 @@
1
+ /*!
2
+ * Author : Matteo Bruni
3
+ * MIT license: https://opensource.org/licenses/MIT
4
+ * Demo / Generator : https://particles.js.org/
5
+ * GitHub : https://www.github.com/matteobruni/tsparticles
6
+ * How to use? : Check the GitHub README
7
+ * v4.0.0-alpha.5
8
+ */
9
+ "use strict";
10
+ /*
11
+ * ATTENTION: The "eval" devtool has been used (maybe by default in mode: "development").
12
+ * This devtool is neither made for production nor for readable output files.
13
+ * It uses "eval()" calls to create a separate source file in the browser devtools.
14
+ * If you are trying to read the output file, select a different devtool (https://webpack.js.org/configuration/devtool/)
15
+ * or disable the default devtool with "devtool: false".
16
+ * If you are looking for production-ready output files, see mode: "production" (https://webpack.js.org/configuration/mode/).
17
+ */
18
+ (this["webpackChunk_tsparticles_plugin_absorbers"] = this["webpackChunk_tsparticles_plugin_absorbers"] || []).push([["dist_browser_AbsorbersInstancesManager_js"],{
19
+
20
+ /***/ "./dist/browser/AbsorbersInstancesManager.js"
21
+ /*!***************************************************!*\
22
+ !*** ./dist/browser/AbsorbersInstancesManager.js ***!
23
+ \***************************************************/
24
+ (__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) {
25
+
26
+ eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ AbsorbersInstancesManager: () => (/* binding */ AbsorbersInstancesManager)\n/* harmony export */ });\n/* harmony import */ var _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @tsparticles/engine */ \"@tsparticles/engine\");\n\nconst defaultIndex = 0;\nclass AbsorbersInstancesManager {\n constructor(engine) {\n this._containerArrays = new Map();\n this._engine = engine;\n }\n async addAbsorber(container, options, position) {\n const {\n AbsorberInstance\n } = await __webpack_require__.e(/*! import() */ \"dist_browser_AbsorberInstance_js\").then(__webpack_require__.bind(__webpack_require__, /*! ./AbsorberInstance.js */ \"./dist/browser/AbsorberInstance.js\")),\n absorber = new AbsorberInstance(this._engine, container, options, position),\n array = this.getArray(container);\n array.push(absorber);\n return absorber;\n }\n clear(container) {\n this.initContainer(container);\n this._containerArrays.set(container, []);\n }\n getArray(container) {\n this.initContainer(container);\n let array = this._containerArrays.get(container);\n if (!array) {\n array = [];\n this._containerArrays.set(container, array);\n }\n return array;\n }\n initContainer(container) {\n if (this._containerArrays.has(container)) {\n return;\n }\n this._containerArrays.set(container, []);\n container.getAbsorber ??= idxOrName => {\n const array = this.getArray(container);\n return idxOrName === undefined || (0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.isNumber)(idxOrName) ? array[idxOrName ?? defaultIndex] : array.find(t => t.name === idxOrName);\n };\n container.addAbsorber ??= (options, position) => {\n return this.addAbsorber(container, options, position);\n };\n }\n removeAbsorber(container, absorber) {\n const index = this.getArray(container).indexOf(absorber),\n deleteCount = 1;\n if (index >= defaultIndex) {\n this.getArray(container).splice(index, deleteCount);\n }\n }\n}\n\n//# sourceURL=webpack://@tsparticles/plugin-absorbers/./dist/browser/AbsorbersInstancesManager.js?\n}");
27
+
28
+ /***/ }
29
+
30
+ }]);
@@ -0,0 +1,60 @@
1
+ /*!
2
+ * Author : Matteo Bruni
3
+ * MIT license: https://opensource.org/licenses/MIT
4
+ * Demo / Generator : https://particles.js.org/
5
+ * GitHub : https://www.github.com/matteobruni/tsparticles
6
+ * How to use? : Check the GitHub README
7
+ * v4.0.0-alpha.5
8
+ */
9
+ "use strict";
10
+ /*
11
+ * ATTENTION: The "eval" devtool has been used (maybe by default in mode: "development").
12
+ * This devtool is neither made for production nor for readable output files.
13
+ * It uses "eval()" calls to create a separate source file in the browser devtools.
14
+ * If you are trying to read the output file, select a different devtool (https://webpack.js.org/configuration/devtool/)
15
+ * or disable the default devtool with "devtool: false".
16
+ * If you are looking for production-ready output files, see mode: "production" (https://webpack.js.org/configuration/mode/).
17
+ */
18
+ (this["webpackChunk_tsparticles_plugin_absorbers"] = this["webpackChunk_tsparticles_plugin_absorbers"] || []).push([["dist_browser_AbsorbersInteractor_js"],{
19
+
20
+ /***/ "./dist/browser/AbsorbersInteractor.js"
21
+ /*!*********************************************!*\
22
+ !*** ./dist/browser/AbsorbersInteractor.js ***!
23
+ \*********************************************/
24
+ (__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) {
25
+
26
+ eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ AbsorbersInteractor: () => (/* binding */ AbsorbersInteractor)\n/* harmony export */ });\n/* harmony import */ var _tsparticles_plugin_interactivity__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @tsparticles/plugin-interactivity */ \"@tsparticles/plugin-interactivity\");\n/* harmony import */ var _tsparticles_engine__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @tsparticles/engine */ \"@tsparticles/engine\");\n/* harmony import */ var _Options_Classes_Absorber_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./Options/Classes/Absorber.js */ \"./dist/browser/Options/Classes/Absorber.js\");\n\n\n\nconst absorbersMode = \"absorbers\";\nclass AbsorbersInteractor extends _tsparticles_plugin_interactivity__WEBPACK_IMPORTED_MODULE_0__.ExternalInteractorBase {\n constructor(container, instancesManager) {\n super(container);\n this.dragging = false;\n this._instancesManager = instancesManager;\n this._instancesManager.initContainer(container);\n this.handleClickMode = (mode, interactivityData) => {\n const container = this.container,\n options = container.actualOptions,\n absorbers = options.interactivity.modes.absorbers;\n if (!absorbers || mode !== absorbersMode) {\n return;\n }\n const {\n clickPosition\n } = interactivityData.mouse;\n if (clickPosition) {\n const existingAbsorber = instancesManager.getArray(this.container).some(t => (0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_1__.getDistance)(t.position, clickPosition) < t.size);\n if (existingAbsorber) {\n return;\n }\n }\n const absorbersModeOptions = (0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_1__.itemFromArray)(absorbers) ?? new _Options_Classes_Absorber_js__WEBPACK_IMPORTED_MODULE_2__.Absorber();\n void this._instancesManager.addAbsorber(container, absorbersModeOptions, clickPosition);\n };\n }\n clear() {}\n init() {}\n interact(interactivityData, delta) {\n for (const particle of this.container.particles.filter(p => this.isEnabled(interactivityData, p))) {\n for (const absorber of this._instancesManager.getArray(this.container)) {\n if (absorber.options.draggable) {\n const mouse = interactivityData.mouse;\n if (mouse.clicking && mouse.downPosition) {\n const mouseDist = (0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_1__.getDistance)(absorber.position, mouse.downPosition);\n if (mouseDist <= absorber.size) {\n this.dragging = true;\n this.draggingAbsorber = absorber;\n }\n } else {\n this.dragging = false;\n this.draggingAbsorber = undefined;\n }\n if (this.dragging && this.draggingAbsorber == absorber && mouse.position) {\n absorber.position.x = mouse.position.x;\n absorber.position.y = mouse.position.y;\n }\n }\n absorber.attract(particle, delta);\n if (particle.destroyed) {\n break;\n }\n }\n }\n }\n isEnabled(interactivityData, particle) {\n const container = this.container,\n options = container.actualOptions,\n mouse = interactivityData.mouse,\n events = (particle?.interactivity ?? options.interactivity).events;\n if (!mouse.clickPosition || !events.onClick.enable) {\n return false;\n }\n return (0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_1__.isInArray)(absorbersMode, events.onClick.mode);\n }\n loadModeOptions(options, ...sources) {\n options.absorbers ??= [];\n for (const source of sources) {\n if (!source) {\n continue;\n }\n if ((0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_1__.isArray)(source.absorbers)) {\n for (const absorber of source.absorbers) {\n const tmp = new _Options_Classes_Absorber_js__WEBPACK_IMPORTED_MODULE_2__.Absorber();\n tmp.load(absorber);\n options.absorbers.push(tmp);\n }\n } else {\n const tmp = new _Options_Classes_Absorber_js__WEBPACK_IMPORTED_MODULE_2__.Absorber();\n tmp.load(source.absorbers);\n options.absorbers.push(tmp);\n }\n }\n }\n reset() {}\n}\n\n//# sourceURL=webpack://@tsparticles/plugin-absorbers/./dist/browser/AbsorbersInteractor.js?\n}");
27
+
28
+ /***/ },
29
+
30
+ /***/ "./dist/browser/Options/Classes/Absorber.js"
31
+ /*!**************************************************!*\
32
+ !*** ./dist/browser/Options/Classes/Absorber.js ***!
33
+ \**************************************************/
34
+ (__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) {
35
+
36
+ eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ Absorber: () => (/* binding */ Absorber)\n/* harmony export */ });\n/* harmony import */ var _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @tsparticles/engine */ \"@tsparticles/engine\");\n/* harmony import */ var _AbsorberSize_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./AbsorberSize.js */ \"./dist/browser/Options/Classes/AbsorberSize.js\");\n\n\nclass Absorber {\n constructor() {\n this.color = new _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.OptionsColor();\n this.color.value = \"#000000\";\n this.draggable = false;\n this.opacity = 1;\n this.destroy = true;\n this.orbits = false;\n this.size = new _AbsorberSize_js__WEBPACK_IMPORTED_MODULE_1__.AbsorberSize();\n }\n load(data) {\n if ((0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.isNull)(data)) {\n return;\n }\n if (data.color !== undefined) {\n this.color = _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.OptionsColor.create(this.color, data.color);\n }\n if (data.draggable !== undefined) {\n this.draggable = data.draggable;\n }\n this.name = data.name;\n if (data.opacity !== undefined) {\n this.opacity = data.opacity;\n }\n if (data.position !== undefined) {\n this.position = {};\n if (data.position.x !== undefined) {\n this.position.x = (0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.setRangeValue)(data.position.x);\n }\n if (data.position.y !== undefined) {\n this.position.y = (0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.setRangeValue)(data.position.y);\n }\n }\n if (data.size !== undefined) {\n this.size.load(data.size);\n }\n if (data.destroy !== undefined) {\n this.destroy = data.destroy;\n }\n if (data.orbits !== undefined) {\n this.orbits = data.orbits;\n }\n }\n}\n\n//# sourceURL=webpack://@tsparticles/plugin-absorbers/./dist/browser/Options/Classes/Absorber.js?\n}");
37
+
38
+ /***/ },
39
+
40
+ /***/ "./dist/browser/Options/Classes/AbsorberSize.js"
41
+ /*!******************************************************!*\
42
+ !*** ./dist/browser/Options/Classes/AbsorberSize.js ***!
43
+ \******************************************************/
44
+ (__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) {
45
+
46
+ eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ AbsorberSize: () => (/* binding */ AbsorberSize)\n/* harmony export */ });\n/* harmony import */ var _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @tsparticles/engine */ \"@tsparticles/engine\");\n/* harmony import */ var _AbsorberSizeLimit_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./AbsorberSizeLimit.js */ \"./dist/browser/Options/Classes/AbsorberSizeLimit.js\");\n\n\nclass AbsorberSize extends _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.ValueWithRandom {\n constructor() {\n super();\n this.density = 5;\n this.value = 50;\n this.limit = new _AbsorberSizeLimit_js__WEBPACK_IMPORTED_MODULE_1__.AbsorberSizeLimit();\n }\n load(data) {\n if ((0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.isNull)(data)) {\n return;\n }\n super.load(data);\n if (data.density !== undefined) {\n this.density = data.density;\n }\n if ((0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.isNumber)(data.limit)) {\n this.limit.radius = data.limit;\n } else {\n this.limit.load(data.limit);\n }\n }\n}\n\n//# sourceURL=webpack://@tsparticles/plugin-absorbers/./dist/browser/Options/Classes/AbsorberSize.js?\n}");
47
+
48
+ /***/ },
49
+
50
+ /***/ "./dist/browser/Options/Classes/AbsorberSizeLimit.js"
51
+ /*!***********************************************************!*\
52
+ !*** ./dist/browser/Options/Classes/AbsorberSizeLimit.js ***!
53
+ \***********************************************************/
54
+ (__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) {
55
+
56
+ eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ AbsorberSizeLimit: () => (/* binding */ AbsorberSizeLimit)\n/* harmony export */ });\n/* harmony import */ var _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @tsparticles/engine */ \"@tsparticles/engine\");\n\nclass AbsorberSizeLimit {\n constructor() {\n this.radius = 0;\n this.mass = 0;\n }\n load(data) {\n if ((0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.isNull)(data)) {\n return;\n }\n if (data.mass !== undefined) {\n this.mass = data.mass;\n }\n if (data.radius !== undefined) {\n this.radius = data.radius;\n }\n }\n}\n\n//# sourceURL=webpack://@tsparticles/plugin-absorbers/./dist/browser/Options/Classes/AbsorberSizeLimit.js?\n}");
57
+
58
+ /***/ }
59
+
60
+ }]);
@@ -0,0 +1,30 @@
1
+ /*!
2
+ * Author : Matteo Bruni
3
+ * MIT license: https://opensource.org/licenses/MIT
4
+ * Demo / Generator : https://particles.js.org/
5
+ * GitHub : https://www.github.com/matteobruni/tsparticles
6
+ * How to use? : Check the GitHub README
7
+ * v4.0.0-alpha.5
8
+ */
9
+ "use strict";
10
+ /*
11
+ * ATTENTION: The "eval" devtool has been used (maybe by default in mode: "development").
12
+ * This devtool is neither made for production nor for readable output files.
13
+ * It uses "eval()" calls to create a separate source file in the browser devtools.
14
+ * If you are trying to read the output file, select a different devtool (https://webpack.js.org/configuration/devtool/)
15
+ * or disable the default devtool with "devtool: false".
16
+ * If you are looking for production-ready output files, see mode: "production" (https://webpack.js.org/configuration/mode/).
17
+ */
18
+ (this["webpackChunk_tsparticles_plugin_absorbers"] = this["webpackChunk_tsparticles_plugin_absorbers"] || []).push([["dist_browser_AbsorbersPluginInstance_js"],{
19
+
20
+ /***/ "./dist/browser/AbsorbersPluginInstance.js"
21
+ /*!*************************************************!*\
22
+ !*** ./dist/browser/AbsorbersPluginInstance.js ***!
23
+ \*************************************************/
24
+ (__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) {
25
+
26
+ eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ AbsorbersPluginInstance: () => (/* binding */ AbsorbersPluginInstance)\n/* harmony export */ });\n/* harmony import */ var _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @tsparticles/engine */ \"@tsparticles/engine\");\n\nclass AbsorbersPluginInstance {\n constructor(container, instancesManager) {\n this._container = container;\n this._instancesManager = instancesManager;\n this._instancesManager.initContainer(container);\n }\n draw(context) {\n for (const absorber of this._instancesManager.getArray(this._container)) {\n absorber.draw(context);\n }\n }\n async init() {\n const absorbers = this._container.actualOptions.absorbers,\n promises = (0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.executeOnSingleOrMultiple)(absorbers, async absorber => {\n await this._instancesManager.addAbsorber(this._container, absorber);\n });\n if ((0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.isArray)(promises)) {\n await Promise.all(promises);\n } else {\n await promises;\n }\n }\n particleUpdate(particle, delta) {\n for (const absorber of this._instancesManager.getArray(this._container)) {\n absorber.attract(particle, delta);\n if (particle.destroyed) {\n break;\n }\n }\n }\n resize() {\n for (const absorber of this._instancesManager.getArray(this._container)) {\n absorber.resize();\n }\n }\n stop() {\n this._instancesManager.clear(this._container);\n }\n}\n\n//# sourceURL=webpack://@tsparticles/plugin-absorbers/./dist/browser/AbsorbersPluginInstance.js?\n}");
27
+
28
+ /***/ }
29
+
30
+ }]);
@@ -4,7 +4,7 @@
4
4
  * Demo / Generator : https://particles.js.org/
5
5
  * GitHub : https://www.github.com/matteobruni/tsparticles
6
6
  * How to use? : Check the GitHub README
7
- * v4.0.0-alpha.3
7
+ * v4.0.0-alpha.5
8
8
  */
9
9
  "use strict";
10
10
  /*
@@ -17,33 +17,13 @@
17
17
  */
18
18
  (this["webpackChunk_tsparticles_plugin_absorbers"] = this["webpackChunk_tsparticles_plugin_absorbers"] || []).push([["dist_browser_AbsorbersPlugin_js"],{
19
19
 
20
- /***/ "./dist/browser/AbsorberInstance.js"
21
- /*!******************************************!*\
22
- !*** ./dist/browser/AbsorberInstance.js ***!
23
- \******************************************/
24
- (__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) {
25
-
26
- eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ AbsorberInstance: () => (/* binding */ AbsorberInstance)\n/* harmony export */ });\n/* harmony import */ var _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @tsparticles/engine */ \"@tsparticles/engine\");\n/* harmony import */ var _Options_Classes_Absorber_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./Options/Classes/Absorber.js */ \"./dist/browser/Options/Classes/Absorber.js\");\n\n\nconst squareExp = 2,\n absorbFactor = 0.033,\n minOrbitLength = 0,\n minRadius = 0,\n minMass = 0,\n minAngle = 0,\n double = 2,\n maxAngle = Math.PI * double,\n minVelocity = 0;\nclass AbsorberInstance {\n constructor(container, engine, options, position) {\n this._calcPosition = () => {\n const exactPosition = (0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.calcPositionOrRandomFromSizeRanged)({\n size: this._container.canvas.size,\n position: this.options.position\n });\n return _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.Vector.create(exactPosition.x, exactPosition.y);\n };\n this._updateParticlePosition = (particle, v) => {\n if (particle.destroyed) {\n return;\n }\n const container = this._container,\n canvasSize = container.canvas.size;\n if (particle.needsNewPosition) {\n const newPosition = (0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.calcPositionOrRandomFromSize)({\n size: canvasSize\n });\n particle.position.setTo(newPosition);\n particle.velocity.setTo(particle.initialVelocity);\n particle.absorberOrbit = undefined;\n particle.needsNewPosition = false;\n }\n if (this.options.orbits) {\n if (particle.absorberOrbit === undefined) {\n particle.absorberOrbit = _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.Vector.origin;\n particle.absorberOrbit.length = (0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.getDistance)(particle.getPosition(), this.position);\n particle.absorberOrbit.angle = (0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.getRandom)() * maxAngle;\n }\n if (particle.absorberOrbit.length <= this.size && !this.options.destroy) {\n const minSize = Math.min(canvasSize.width, canvasSize.height),\n offset = 1,\n randomOffset = 0.1,\n randomFactor = 0.2;\n particle.absorberOrbit.length = minSize * (offset + ((0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.getRandom)() * randomFactor - randomOffset));\n }\n particle.absorberOrbitDirection ??= particle.velocity.x >= minVelocity ? _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.RotateDirection.clockwise : _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.RotateDirection.counterClockwise;\n const orbitRadius = particle.absorberOrbit.length,\n orbitAngle = particle.absorberOrbit.angle,\n orbitDirection = particle.absorberOrbitDirection;\n particle.velocity.setTo(_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.Vector.origin);\n const updateFunc = {\n x: orbitDirection === _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.RotateDirection.clockwise ? Math.cos : Math.sin,\n y: orbitDirection === _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.RotateDirection.clockwise ? Math.sin : Math.cos\n };\n particle.position.x = this.position.x + orbitRadius * updateFunc.x(orbitAngle);\n particle.position.y = this.position.y + orbitRadius * updateFunc.y(orbitAngle);\n particle.absorberOrbit.length -= v.length;\n particle.absorberOrbit.angle += (particle.retina.moveSpeed ?? minVelocity) * container.retina.pixelRatio / _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.percentDenominator * container.retina.reduceFactor;\n } else {\n const addV = _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.Vector.origin;\n addV.length = v.length;\n addV.angle = v.angle;\n particle.velocity.addTo(addV);\n }\n };\n this._container = container;\n this._engine = engine;\n this.initialPosition = position ? _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.Vector.create(position.x, position.y) : undefined;\n if (options instanceof _Options_Classes_Absorber_js__WEBPACK_IMPORTED_MODULE_1__.Absorber) {\n this.options = options;\n } else {\n this.options = new _Options_Classes_Absorber_js__WEBPACK_IMPORTED_MODULE_1__.Absorber();\n this.options.load(options);\n }\n this.dragging = false;\n this.name = this.options.name;\n this.opacity = this.options.opacity;\n this.size = (0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.getRangeValue)(this.options.size.value) * container.retina.pixelRatio;\n this.mass = this.size * this.options.size.density * container.retina.reduceFactor;\n const limit = this.options.size.limit;\n this.limit = {\n radius: limit.radius * container.retina.pixelRatio * container.retina.reduceFactor,\n mass: limit.mass\n };\n this.color = (0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.rangeColorToRgb)(this._engine, this.options.color) ?? {\n b: 0,\n g: 0,\n r: 0\n };\n this.position = this.initialPosition?.copy() ?? this._calcPosition();\n }\n attract(particle) {\n const container = this._container,\n options = this.options;\n if (options.draggable) {\n const mouse = container.interactivity.mouse;\n if (mouse.clicking && mouse.downPosition) {\n const mouseDist = (0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.getDistance)(this.position, mouse.downPosition);\n if (mouseDist <= this.size) {\n this.dragging = true;\n }\n } else {\n this.dragging = false;\n }\n if (this.dragging && mouse.position) {\n this.position.x = mouse.position.x;\n this.position.y = mouse.position.y;\n }\n }\n const pos = particle.getPosition(),\n {\n dx,\n dy,\n distance\n } = (0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.getDistances)(this.position, pos),\n v = _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.Vector.create(dx, dy);\n v.length = this.mass / Math.pow(distance, squareExp) * container.retina.reduceFactor;\n if (distance < this.size + particle.getRadius()) {\n const sizeFactor = particle.getRadius() * absorbFactor * container.retina.pixelRatio;\n if (this.size > particle.getRadius() && distance < this.size - particle.getRadius() || particle.absorberOrbit !== undefined && particle.absorberOrbit.length < minOrbitLength) {\n if (options.destroy) {\n particle.destroy();\n } else {\n particle.needsNewPosition = true;\n this._updateParticlePosition(particle, v);\n }\n } else {\n if (options.destroy) {\n particle.size.value -= sizeFactor;\n }\n this._updateParticlePosition(particle, v);\n }\n if (this.limit.radius <= minRadius || this.size < this.limit.radius) {\n this.size += sizeFactor;\n }\n if (this.limit.mass <= minMass || this.mass < this.limit.mass) {\n this.mass += sizeFactor * this.options.size.density * container.retina.reduceFactor;\n }\n } else {\n this._updateParticlePosition(particle, v);\n }\n }\n draw(context) {\n context.translate(this.position.x, this.position.y);\n context.beginPath();\n context.arc(_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.originPoint.x, _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.originPoint.y, this.size, minAngle, maxAngle, false);\n context.closePath();\n context.fillStyle = (0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.getStyleFromRgb)(this.color, this._container.hdr, this.opacity);\n context.fill();\n }\n resize() {\n const initialPosition = this.initialPosition;\n this.position = initialPosition && (0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.isPointInside)(initialPosition, this._container.canvas.size, _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.Vector.origin) ? initialPosition : this._calcPosition();\n }\n}\n\n//# sourceURL=webpack://@tsparticles/plugin-absorbers/./dist/browser/AbsorberInstance.js?\n}");
27
-
28
- /***/ },
29
-
30
- /***/ "./dist/browser/Absorbers.js"
31
- /*!***********************************!*\
32
- !*** ./dist/browser/Absorbers.js ***!
33
- \***********************************/
34
- (__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) {
35
-
36
- eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ Absorbers: () => (/* binding */ Absorbers)\n/* harmony export */ });\n/* harmony import */ var _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @tsparticles/engine */ \"@tsparticles/engine\");\n/* harmony import */ var _Options_Classes_Absorber_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./Options/Classes/Absorber.js */ \"./dist/browser/Options/Classes/Absorber.js\");\n/* harmony import */ var _Enums_AbsorberClickMode_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./Enums/AbsorberClickMode.js */ \"./dist/browser/Enums/AbsorberClickMode.js\");\n/* harmony import */ var _AbsorberInstance_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./AbsorberInstance.js */ \"./dist/browser/AbsorberInstance.js\");\n\n\n\n\nconst defaultIndex = 0;\nclass Absorbers {\n constructor(container, engine) {\n this._container = container;\n this._engine = engine;\n this.array = [];\n this.absorbers = [];\n this.interactivityAbsorbers = [];\n container.getAbsorber = idxOrName => idxOrName === undefined || (0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.isNumber)(idxOrName) ? this.array[idxOrName ?? defaultIndex] : this.array.find(t => t.name === idxOrName);\n container.addAbsorber = async (options, position) => this.addAbsorber(options, position);\n }\n async addAbsorber(options, position) {\n const absorber = new _AbsorberInstance_js__WEBPACK_IMPORTED_MODULE_3__.AbsorberInstance(this._container, this._engine, options, position);\n this.array.push(absorber);\n return Promise.resolve(absorber);\n }\n draw(context) {\n for (const absorber of this.array) {\n absorber.draw(context);\n }\n }\n handleClickMode(mode) {\n const modeAbsorbers = this.interactivityAbsorbers;\n if (mode === _Enums_AbsorberClickMode_js__WEBPACK_IMPORTED_MODULE_2__.AbsorberClickMode.absorber) {\n const absorbersModeOptions = (0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.itemFromSingleOrMultiple)(modeAbsorbers) ?? new _Options_Classes_Absorber_js__WEBPACK_IMPORTED_MODULE_1__.Absorber(),\n aPosition = this._container.interactivity.mouse.clickPosition;\n void this.addAbsorber(absorbersModeOptions, aPosition);\n }\n }\n async init() {\n this.absorbers = this._container.actualOptions.absorbers;\n this.interactivityAbsorbers = this._container.actualOptions.interactivity.modes.absorbers;\n const promises = (0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.executeOnSingleOrMultiple)(this.absorbers, async absorber => {\n await this.addAbsorber(absorber);\n });\n if (promises instanceof Array) {\n await Promise.all(promises);\n } else {\n await promises;\n }\n }\n particleUpdate(particle) {\n for (const absorber of this.array) {\n absorber.attract(particle);\n if (particle.destroyed) {\n break;\n }\n }\n }\n removeAbsorber(absorber) {\n const index = this.array.indexOf(absorber),\n deleteCount = 1;\n if (index >= defaultIndex) {\n this.array.splice(index, deleteCount);\n }\n }\n resize() {\n for (const absorber of this.array) {\n absorber.resize();\n }\n }\n stop() {\n this.array = [];\n }\n}\n\n//# sourceURL=webpack://@tsparticles/plugin-absorbers/./dist/browser/Absorbers.js?\n}");
37
-
38
- /***/ },
39
-
40
20
  /***/ "./dist/browser/AbsorbersPlugin.js"
41
21
  /*!*****************************************!*\
42
22
  !*** ./dist/browser/AbsorbersPlugin.js ***!
43
23
  \*****************************************/
44
24
  (__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) {
45
25
 
46
- eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ AbsorbersPlugin: () => (/* binding */ AbsorbersPlugin)\n/* harmony export */ });\n/* harmony import */ var _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @tsparticles/engine */ \"@tsparticles/engine\");\n/* harmony import */ var _Options_Classes_Absorber_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./Options/Classes/Absorber.js */ \"./dist/browser/Options/Classes/Absorber.js\");\n/* harmony import */ var _Enums_AbsorberClickMode_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./Enums/AbsorberClickMode.js */ \"./dist/browser/Enums/AbsorberClickMode.js\");\n/* harmony import */ var _Absorbers_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./Absorbers.js */ \"./dist/browser/Absorbers.js\");\n\n\n\n\nclass AbsorbersPlugin {\n constructor(engine) {\n this.id = \"absorbers\";\n this._engine = engine;\n }\n async getPlugin(container) {\n return Promise.resolve(new _Absorbers_js__WEBPACK_IMPORTED_MODULE_3__.Absorbers(container, this._engine));\n }\n loadOptions(options, source) {\n if (!this.needsPlugin(options) && !this.needsPlugin(source)) {\n return;\n }\n if (source?.absorbers) {\n options.absorbers = (0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.executeOnSingleOrMultiple)(source.absorbers, absorber => {\n const tmp = new _Options_Classes_Absorber_js__WEBPACK_IMPORTED_MODULE_1__.Absorber();\n tmp.load(absorber);\n return tmp;\n });\n }\n options.interactivity.modes.absorbers = (0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.executeOnSingleOrMultiple)(source?.interactivity?.modes?.absorbers, absorber => {\n const tmp = new _Options_Classes_Absorber_js__WEBPACK_IMPORTED_MODULE_1__.Absorber();\n tmp.load(absorber);\n return tmp;\n });\n }\n needsPlugin(options) {\n if (!options) {\n return false;\n }\n const absorbers = options.absorbers;\n if ((0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.isArray)(absorbers)) {\n return !!absorbers.length;\n } else if (absorbers) {\n return true;\n } else if (options.interactivity?.events?.onClick?.mode && (0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.isInArray)(_Enums_AbsorberClickMode_js__WEBPACK_IMPORTED_MODULE_2__.AbsorberClickMode.absorber, options.interactivity.events.onClick.mode)) {\n return true;\n }\n return false;\n }\n}\n\n//# sourceURL=webpack://@tsparticles/plugin-absorbers/./dist/browser/AbsorbersPlugin.js?\n}");
26
+ eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ AbsorbersPlugin: () => (/* binding */ AbsorbersPlugin)\n/* harmony export */ });\n/* harmony import */ var _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @tsparticles/engine */ \"@tsparticles/engine\");\n/* harmony import */ var _Options_Classes_Absorber_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./Options/Classes/Absorber.js */ \"./dist/browser/Options/Classes/Absorber.js\");\n\n\nclass AbsorbersPlugin {\n constructor(instancesManager) {\n this.id = \"absorbers\";\n this._instancesManager = instancesManager;\n }\n async getPlugin(container) {\n const {\n AbsorbersPluginInstance\n } = await __webpack_require__.e(/*! import() */ \"dist_browser_AbsorbersPluginInstance_js\").then(__webpack_require__.bind(__webpack_require__, /*! ./AbsorbersPluginInstance.js */ \"./dist/browser/AbsorbersPluginInstance.js\"));\n return new AbsorbersPluginInstance(container, this._instancesManager);\n }\n loadOptions(_container, options, source) {\n if (!this.needsPlugin(options) && !this.needsPlugin(source)) {\n return;\n }\n if (source?.absorbers) {\n options.absorbers = (0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.executeOnSingleOrMultiple)(source.absorbers, absorber => {\n const tmp = new _Options_Classes_Absorber_js__WEBPACK_IMPORTED_MODULE_1__.Absorber();\n tmp.load(absorber);\n return tmp;\n });\n }\n }\n needsPlugin(options) {\n if (!options) {\n return false;\n }\n const absorbers = options.absorbers;\n if ((0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.isArray)(absorbers)) {\n return !!absorbers.length;\n } else if (absorbers) {\n return true;\n }\n return false;\n }\n}\n\n//# sourceURL=webpack://@tsparticles/plugin-absorbers/./dist/browser/AbsorbersPlugin.js?\n}");
47
27
 
48
28
  /***/ },
49
29
 
@@ -1,8 +1,8 @@
1
- import { RotateDirection, Vector, calcPositionOrRandomFromSize, calcPositionOrRandomFromSizeRanged, getDistance, getDistances, getRandom, getRangeValue, getStyleFromRgb, isPointInside, originPoint, percentDenominator, rangeColorToRgb, } from "@tsparticles/engine";
1
+ import { RotateDirection, Vector, calcPositionOrRandomFromSize, calcPositionOrRandomFromSizeRanged, doublePI, getDistance, getDistances, getRandom, getRangeValue, getStyleFromRgb, isPointInside, originPoint, percentDenominator, rangeColorToRgb, } from "@tsparticles/engine";
2
2
  import { Absorber } from "./Options/Classes/Absorber.js";
3
- const squareExp = 2, absorbFactor = 0.033, minOrbitLength = 0, minRadius = 0, minMass = 0, minAngle = 0, double = 2, maxAngle = Math.PI * double, minVelocity = 0;
3
+ const squareExp = 2, absorbFactor = 0.033, minOrbitLength = 0, minRadius = 0, minMass = 0, minAngle = 0, maxAngle = doublePI, minVelocity = 0;
4
4
  export class AbsorberInstance {
5
- constructor(container, engine, options, position) {
5
+ constructor(engine, container, options, position) {
6
6
  this._calcPosition = () => {
7
7
  const exactPosition = calcPositionOrRandomFromSizeRanged({
8
8
  size: this._container.canvas.size,
@@ -64,7 +64,6 @@ export class AbsorberInstance {
64
64
  this.options = new Absorber();
65
65
  this.options.load(options);
66
66
  }
67
- this.dragging = false;
68
67
  this.name = this.options.name;
69
68
  this.opacity = this.options.opacity;
70
69
  this.size = getRangeValue(this.options.size.value) * container.retina.pixelRatio;
@@ -81,28 +80,11 @@ export class AbsorberInstance {
81
80
  };
82
81
  this.position = this.initialPosition?.copy() ?? this._calcPosition();
83
82
  }
84
- attract(particle) {
85
- const container = this._container, options = this.options;
86
- if (options.draggable) {
87
- const mouse = container.interactivity.mouse;
88
- if (mouse.clicking && mouse.downPosition) {
89
- const mouseDist = getDistance(this.position, mouse.downPosition);
90
- if (mouseDist <= this.size) {
91
- this.dragging = true;
92
- }
93
- }
94
- else {
95
- this.dragging = false;
96
- }
97
- if (this.dragging && mouse.position) {
98
- this.position.x = mouse.position.x;
99
- this.position.y = mouse.position.y;
100
- }
101
- }
102
- const pos = particle.getPosition(), { dx, dy, distance } = getDistances(this.position, pos), v = Vector.create(dx, dy);
83
+ attract(particle, delta) {
84
+ const container = this._container, options = this.options, pos = particle.getPosition(), { dx, dy, distance } = getDistances(this.position, pos), v = Vector.create(dx, dy);
103
85
  v.length = (this.mass / Math.pow(distance, squareExp)) * container.retina.reduceFactor;
104
86
  if (distance < this.size + particle.getRadius()) {
105
- const sizeFactor = particle.getRadius() * absorbFactor * container.retina.pixelRatio;
87
+ const sizeFactor = particle.getRadius() * absorbFactor * container.retina.pixelRatio * delta.factor;
106
88
  if ((this.size > particle.getRadius() && distance < this.size - particle.getRadius()) ||
107
89
  (particle.absorberOrbit !== undefined && particle.absorberOrbit.length < minOrbitLength)) {
108
90
  if (options.destroy) {
@@ -0,0 +1,47 @@
1
+ import { isNumber } from "@tsparticles/engine";
2
+ const defaultIndex = 0;
3
+ export class AbsorbersInstancesManager {
4
+ constructor(engine) {
5
+ this._containerArrays = new Map();
6
+ this._engine = engine;
7
+ }
8
+ async addAbsorber(container, options, position) {
9
+ const { AbsorberInstance } = await import("./AbsorberInstance.js"), absorber = new AbsorberInstance(this._engine, container, options, position), array = this.getArray(container);
10
+ array.push(absorber);
11
+ return absorber;
12
+ }
13
+ clear(container) {
14
+ this.initContainer(container);
15
+ this._containerArrays.set(container, []);
16
+ }
17
+ getArray(container) {
18
+ this.initContainer(container);
19
+ let array = this._containerArrays.get(container);
20
+ if (!array) {
21
+ array = [];
22
+ this._containerArrays.set(container, array);
23
+ }
24
+ return array;
25
+ }
26
+ initContainer(container) {
27
+ if (this._containerArrays.has(container)) {
28
+ return;
29
+ }
30
+ this._containerArrays.set(container, []);
31
+ container.getAbsorber ??= (idxOrName) => {
32
+ const array = this.getArray(container);
33
+ return idxOrName === undefined || isNumber(idxOrName)
34
+ ? array[idxOrName ?? defaultIndex]
35
+ : array.find(t => t.name === idxOrName);
36
+ };
37
+ container.addAbsorber ??= (options, position) => {
38
+ return this.addAbsorber(container, options, position);
39
+ };
40
+ }
41
+ removeAbsorber(container, absorber) {
42
+ const index = this.getArray(container).indexOf(absorber), deleteCount = 1;
43
+ if (index >= defaultIndex) {
44
+ this.getArray(container).splice(index, deleteCount);
45
+ }
46
+ }
47
+ }
@@ -0,0 +1,90 @@
1
+ import { ExternalInteractorBase, } from "@tsparticles/plugin-interactivity";
2
+ import { getDistance, isArray, isInArray, itemFromArray, } from "@tsparticles/engine";
3
+ import { Absorber } from "./Options/Classes/Absorber.js";
4
+ const absorbersMode = "absorbers";
5
+ export class AbsorbersInteractor extends ExternalInteractorBase {
6
+ constructor(container, instancesManager) {
7
+ super(container);
8
+ this.dragging = false;
9
+ this._instancesManager = instancesManager;
10
+ this._instancesManager.initContainer(container);
11
+ this.handleClickMode = (mode, interactivityData) => {
12
+ const container = this.container, options = container.actualOptions, absorbers = options.interactivity.modes.absorbers;
13
+ if (!absorbers || mode !== absorbersMode) {
14
+ return;
15
+ }
16
+ const { clickPosition } = interactivityData.mouse;
17
+ if (clickPosition) {
18
+ const existingAbsorber = instancesManager
19
+ .getArray(this.container)
20
+ .some(t => getDistance(t.position, clickPosition) < t.size);
21
+ if (existingAbsorber) {
22
+ return;
23
+ }
24
+ }
25
+ const absorbersModeOptions = itemFromArray(absorbers) ?? new Absorber();
26
+ void this._instancesManager.addAbsorber(container, absorbersModeOptions, clickPosition);
27
+ };
28
+ }
29
+ clear() {
30
+ }
31
+ init() {
32
+ }
33
+ interact(interactivityData, delta) {
34
+ for (const particle of this.container.particles.filter(p => this.isEnabled(interactivityData, p))) {
35
+ for (const absorber of this._instancesManager.getArray(this.container)) {
36
+ if (absorber.options.draggable) {
37
+ const mouse = interactivityData.mouse;
38
+ if (mouse.clicking && mouse.downPosition) {
39
+ const mouseDist = getDistance(absorber.position, mouse.downPosition);
40
+ if (mouseDist <= absorber.size) {
41
+ this.dragging = true;
42
+ this.draggingAbsorber = absorber;
43
+ }
44
+ }
45
+ else {
46
+ this.dragging = false;
47
+ this.draggingAbsorber = undefined;
48
+ }
49
+ if (this.dragging && this.draggingAbsorber == absorber && mouse.position) {
50
+ absorber.position.x = mouse.position.x;
51
+ absorber.position.y = mouse.position.y;
52
+ }
53
+ }
54
+ absorber.attract(particle, delta);
55
+ if (particle.destroyed) {
56
+ break;
57
+ }
58
+ }
59
+ }
60
+ }
61
+ isEnabled(interactivityData, particle) {
62
+ const container = this.container, options = container.actualOptions, mouse = interactivityData.mouse, events = (particle?.interactivity ?? options.interactivity).events;
63
+ if (!mouse.clickPosition || !events.onClick.enable) {
64
+ return false;
65
+ }
66
+ return isInArray(absorbersMode, events.onClick.mode);
67
+ }
68
+ loadModeOptions(options, ...sources) {
69
+ options.absorbers ??= [];
70
+ for (const source of sources) {
71
+ if (!source) {
72
+ continue;
73
+ }
74
+ if (isArray(source.absorbers)) {
75
+ for (const absorber of source.absorbers) {
76
+ const tmp = new Absorber();
77
+ tmp.load(absorber);
78
+ options.absorbers.push(tmp);
79
+ }
80
+ }
81
+ else {
82
+ const tmp = new Absorber();
83
+ tmp.load(source.absorbers);
84
+ options.absorbers.push(tmp);
85
+ }
86
+ }
87
+ }
88
+ reset() {
89
+ }
90
+ }
@@ -1,16 +1,15 @@
1
- import { executeOnSingleOrMultiple, isArray, isInArray, } from "@tsparticles/engine";
1
+ import { executeOnSingleOrMultiple, isArray, } from "@tsparticles/engine";
2
2
  import { Absorber } from "./Options/Classes/Absorber.js";
3
- import { AbsorberClickMode } from "./Enums/AbsorberClickMode.js";
4
- import { Absorbers } from "./Absorbers.js";
5
3
  export class AbsorbersPlugin {
6
- constructor(engine) {
4
+ constructor(instancesManager) {
7
5
  this.id = "absorbers";
8
- this._engine = engine;
6
+ this._instancesManager = instancesManager;
9
7
  }
10
8
  async getPlugin(container) {
11
- return Promise.resolve(new Absorbers(container, this._engine));
9
+ const { AbsorbersPluginInstance } = await import("./AbsorbersPluginInstance.js");
10
+ return new AbsorbersPluginInstance(container, this._instancesManager);
12
11
  }
13
- loadOptions(options, source) {
12
+ loadOptions(_container, options, source) {
14
13
  if (!this.needsPlugin(options) && !this.needsPlugin(source)) {
15
14
  return;
16
15
  }
@@ -21,11 +20,6 @@ export class AbsorbersPlugin {
21
20
  return tmp;
22
21
  });
23
22
  }
24
- options.interactivity.modes.absorbers = executeOnSingleOrMultiple(source?.interactivity?.modes?.absorbers, absorber => {
25
- const tmp = new Absorber();
26
- tmp.load(absorber);
27
- return tmp;
28
- });
29
23
  }
30
24
  needsPlugin(options) {
31
25
  if (!options) {
@@ -38,10 +32,6 @@ export class AbsorbersPlugin {
38
32
  else if (absorbers) {
39
33
  return true;
40
34
  }
41
- else if (options.interactivity?.events?.onClick?.mode &&
42
- isInArray(AbsorberClickMode.absorber, options.interactivity.events.onClick.mode)) {
43
- return true;
44
- }
45
35
  return false;
46
36
  }
47
37
  }
@@ -0,0 +1,40 @@
1
+ import { executeOnSingleOrMultiple, isArray, } from "@tsparticles/engine";
2
+ export class AbsorbersPluginInstance {
3
+ constructor(container, instancesManager) {
4
+ this._container = container;
5
+ this._instancesManager = instancesManager;
6
+ this._instancesManager.initContainer(container);
7
+ }
8
+ draw(context) {
9
+ for (const absorber of this._instancesManager.getArray(this._container)) {
10
+ absorber.draw(context);
11
+ }
12
+ }
13
+ async init() {
14
+ const absorbers = this._container.actualOptions.absorbers, promises = executeOnSingleOrMultiple(absorbers, async (absorber) => {
15
+ await this._instancesManager.addAbsorber(this._container, absorber);
16
+ });
17
+ if (isArray(promises)) {
18
+ await Promise.all(promises);
19
+ }
20
+ else {
21
+ await promises;
22
+ }
23
+ }
24
+ particleUpdate(particle, delta) {
25
+ for (const absorber of this._instancesManager.getArray(this._container)) {
26
+ absorber.attract(particle, delta);
27
+ if (particle.destroyed) {
28
+ break;
29
+ }
30
+ }
31
+ }
32
+ resize() {
33
+ for (const absorber of this._instancesManager.getArray(this._container)) {
34
+ absorber.resize();
35
+ }
36
+ }
37
+ stop() {
38
+ this._instancesManager.clear(this._container);
39
+ }
40
+ }
package/esm/index.js CHANGED
@@ -1,8 +1,12 @@
1
- export function loadAbsorbersPlugin(engine) {
2
- engine.checkVersion("4.0.0-alpha.3");
3
- engine.register(async (e) => {
4
- const { AbsorbersPlugin } = await import("./AbsorbersPlugin.js");
5
- e.addPlugin(new AbsorbersPlugin(e));
1
+ export async function loadAbsorbersPlugin(engine) {
2
+ engine.checkVersion("4.0.0-alpha.5");
3
+ await engine.register(async (e) => {
4
+ const { loadInteractivityPlugin } = await import("@tsparticles/plugin-interactivity"), { AbsorbersInstancesManager } = await import("./AbsorbersInstancesManager.js"), { AbsorbersPlugin } = await import("./AbsorbersPlugin.js"), instancesManager = new AbsorbersInstancesManager(e);
5
+ await loadInteractivityPlugin(e);
6
+ e.addPlugin(new AbsorbersPlugin(instancesManager));
7
+ e.addInteractor?.("externalAbsorbers", async (container) => {
8
+ const { AbsorbersInteractor } = await import("./AbsorbersInteractor.js");
9
+ return new AbsorbersInteractor(container, instancesManager);
10
+ });
6
11
  });
7
12
  }
8
- export * from "./Enums/AbsorberClickMode.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tsparticles/plugin-absorbers",
3
- "version": "4.0.0-alpha.3",
3
+ "version": "4.0.0-alpha.5",
4
4
  "description": "tsParticles absorbers plugin",
5
5
  "homepage": "https://particles.js.org",
6
6
  "repository": {
@@ -86,7 +86,8 @@
86
86
  "./package.json": "./package.json"
87
87
  },
88
88
  "dependencies": {
89
- "@tsparticles/engine": "4.0.0-alpha.3"
89
+ "@tsparticles/engine": "4.0.0-alpha.5",
90
+ "@tsparticles/plugin-interactivity": "4.0.0-alpha.5"
90
91
  },
91
92
  "publishConfig": {
92
93
  "access": "public"