From c5b2c33ed850b51e78129b87b5e799e8bfd935da Mon Sep 17 00:00:00 2001 From: Ben Burlingham Date: Sat, 11 Nov 2017 12:34:02 -0800 Subject: [PATCH] Cohesion coming together (heh). --- js/animation.js | 3 +-- js/animation3a.js | 5 +++-- js/arc.js | 54 +++++++++++++++++++++++++++++++---------------- js/bundle.js | 10 ++++----- js/index.js | 3 ++- js/particle.js | 16 ++++---------- 6 files changed, 51 insertions(+), 40 deletions(-) diff --git a/js/animation.js b/js/animation.js index 2c776fa..343acdf 100644 --- a/js/animation.js +++ b/js/animation.js @@ -46,8 +46,7 @@ Animation.prototype.subscribeCount = function(count) { Animation.prototype.addHazards = function() { const bounds = this.container.getBoundingClientRect(); - // const n = Random.num(1, 3); - const n = 3 + const n = Random.num(1, 3); for (let i = 0; i < n; i++) { const w = Random.num(50, 200); const h = Random.num(50, 200); diff --git a/js/animation3a.js b/js/animation3a.js index 0d522b1..f39f523 100644 --- a/js/animation3a.js +++ b/js/animation3a.js @@ -5,11 +5,12 @@ export default function(destroy$) { const id = '3a'; const config = { id, - maxCount: 10, + count: 5, + maxCount: 1000, showAlignmentControl: true, showCohesionControl: true, showSeparationControl: true, - showVisionGridControl: true + // showVisionGridControl: true }; const observables = Controls(destroy$, config); diff --git a/js/arc.js b/js/arc.js index a119b9e..4ff0313 100644 --- a/js/arc.js +++ b/js/arc.js @@ -13,6 +13,7 @@ const Arc = { prevEndX: 0, prevEndY: 0, radius: Random.num(100, 200), + speed: 0, theta: Random.num(RAD.t90, RAD.t360) }; @@ -32,9 +33,9 @@ const Arc = { return arc; }, - step: function(arc, bounds, speed) { + step: function(arc, bounds) { // Ensure constant velocity and theta between 0 and 2π. - const delta = speed / arc.radius; + const delta = arc.speed / arc.radius; arc.length -= delta; arc.theta += (arc.clockwise ? -delta : +delta); @@ -99,6 +100,11 @@ const Arc = { return arc; }, + changeSpeed: function(arc, newSpeed) { + arc.speed = newSpeed * 1; + return arc; + }, + reverse: function(arc) { arc.clockwise = !arc.clockwise; @@ -113,32 +119,44 @@ const Arc = { return arc; }, + match: function(arc, arcToMatch) { + + }, + follow: function(arc, arcToFollow) { - if (arc.clockwise !== arcToFollow.clockwise) { - arc = Arc.reverse(arc); - } + arc = (arc.clockwise !== arcToFollow.clockwise ? Arc.reverse(arc) : arc); - if (Math.abs(arc.theta - arcToFollow.theta) > 0.2) { - arc = Arc.changeRadius(arc, 50); - } else { - arc = Arc.changeRadius(arc, arcToFollow.radius); - } + const prevD = Math.pow( + Math.pow(arcToFollow.endX - arc.prevEndX, 2) + + Math.pow(arcToFollow.endY - arc.prevEndY, 2) + , 0.5); - return arc; - }, + const currD = Math.pow( + Math.pow(arcToFollow.endX - arc.endX, 2) + + Math.pow(arcToFollow.endY - arc.endY, 2) + , 0.5); + + // "How much of movement is in the correct direction" + const ratio = (prevD - currD) / arc.speed; - goto: function (arc, x, y, speed) { - const prevD = Math.pow(Math.pow(x - arc.prevEndX, 2) + Math.pow(y - arc.prevEndY, 2), 0.5); - const currD = Math.pow(Math.pow(x - arc.endX, 2) + Math.pow(y - arc.endY, 2), 0.5); - const ratio = (prevD - currD) / speed; + // TODO adjust speed + // TODO turn in the correct direction - if (currD < 10) { - throw new Error(`Arc end of (${arc.endX},${arc.endY}) is within 50px of (${x},${y})`); + if (currD < 20) { + // if (Math.abs(arc.centerX - arcToFollow.centerX) < 10 && Math.abs(arc.centerY - arcToFollow.centerX) < 10) { + arc = Arc.changeRadius(arc, arcToFollow.radius); + if (arc.speed > arcToFollow.speed) { + arc = Arc.changeSpeed(arc, arc.speed - 1); + } } else if (ratio < 0.8) { // arc = (ratio < 0 ? Arc.reverse(arc) : arc); arc = Arc.changeRadius(arc, 20); } else { arc = Arc.changeRadius(arc, 400); + + if (arc.speed < (arcToFollow.speed + 2)) { + arc = Arc.changeSpeed(arc, arc.speed + 1); + } } return arc; diff --git a/js/bundle.js b/js/bundle.js index 1805bd2..c5fd8d5 100644 --- a/js/bundle.js +++ b/js/bundle.js @@ -256,7 +256,7 @@ eval("\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n}); /***/ (function(module, exports, __webpack_require__) { "use strict"; -eval("\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nvar _rxjs = __webpack_require__(/*! rxjs */ 21);\n\nvar _rxjs2 = _interopRequireDefault(_rxjs);\n\nvar _grid = __webpack_require__(/*! ./grid */ 84);\n\nvar _grid2 = _interopRequireDefault(_grid);\n\nvar _particle = __webpack_require__(/*! ./particle */ 86);\n\nvar _particle2 = _interopRequireDefault(_particle);\n\nvar _controls = __webpack_require__(/*! ./controls */ 14);\n\nvar _controls2 = _interopRequireDefault(_controls);\n\nvar _random = __webpack_require__(/*! ./random */ 33);\n\nvar _random2 = _interopRequireDefault(_random);\n\nvar _enums = __webpack_require__(/*! ./enums */ 22);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nfunction Animation(observables, id, showHazards) {\n this.id = id;\n this.observables = observables;\n this.particles = [];\n this.grid = new _grid2.default();\n this.fpsInterval = null;\n\n this.container = document.createElement('div');\n this.container.className = 'animationContainer';\n document.getElementById(id).appendChild(this.container);\n\n this.observables.count$.skip(1).subscribe(this.subscribeCount.bind(this));\n this.observables.animating$.subscribe(this.subscribeAnimating.bind(this));\n}\n\nAnimation.prototype.subscribeAnimating = function (isAnimating) {\n if (isAnimating === false) {\n clearInterval(this.fpsInterval);\n } else {\n var fps$ = this.observables.fps$;\n\n this.fpsInterval = setInterval(fps$.next.bind(fps$), 1000 / 32);\n }\n};\n\nAnimation.prototype.subscribeCount = function (count) {\n var bounds = this.container.getBoundingClientRect();\n\n while (this.particles.length > count) {\n var p = this.particles.pop();\n p.remove();\n }\n\n while (this.particles.length < count) {\n var _p = new _particle2.default(this.container, bounds, this.grid, this.observables);\n this.particles.push(_p);\n }\n};\n\nAnimation.prototype.addHazards = function () {\n var bounds = this.container.getBoundingClientRect();\n\n // const n = Random.num(1, 3);\n var n = 3;\n for (var i = 0; i < n; i++) {\n var w = _random2.default.num(50, 200);\n var h = _random2.default.num(50, 200);\n\n this.grid.setArea({\n x: _random2.default.num(0, bounds.width - w),\n y: _random2.default.num(0, bounds.height - h),\n w: w,\n h: h,\n type: _enums.ENTITIES.HAZARD\n }, this.container);\n }\n};\n\nexports.default = Animation;//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMTUuanMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vanMvYW5pbWF0aW9uLmpzPzBiNTMiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IFJ4LCB7IE9ic2VydmFibGUgfSBmcm9tICdyeGpzJztcbmltcG9ydCBHcmlkIGZyb20gJy4vZ3JpZCc7XG5pbXBvcnQgUGFydGljbGUgZnJvbSAnLi9wYXJ0aWNsZSc7XG5pbXBvcnQgQ29udHJvbHMgZnJvbSAnLi9jb250cm9scyc7XG5pbXBvcnQgUmFuZG9tIGZyb20gJy4vcmFuZG9tJztcbmltcG9ydCB7IENPTlRST0xTLCBFTlRJVElFUyB9IGZyb20gJy4vZW51bXMnO1xuXG5mdW5jdGlvbiBBbmltYXRpb24ob2JzZXJ2YWJsZXMsIGlkLCBzaG93SGF6YXJkcykge1xuICAgIHRoaXMuaWQgPSBpZDtcbiAgICB0aGlzLm9ic2VydmFibGVzID0gb2JzZXJ2YWJsZXM7XG4gICAgdGhpcy5wYXJ0aWNsZXMgPSBbXTtcbiAgICB0aGlzLmdyaWQgPSBuZXcgR3JpZCgpO1xuICAgIHRoaXMuZnBzSW50ZXJ2YWwgPSBudWxsO1xuXG4gICAgdGhpcy5jb250YWluZXIgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICB0aGlzLmNvbnRhaW5lci5jbGFzc05hbWUgPSAnYW5pbWF0aW9uQ29udGFpbmVyJztcbiAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChpZCkuYXBwZW5kQ2hpbGQodGhpcy5jb250YWluZXIpO1xuXG4gICAgdGhpcy5vYnNlcnZhYmxlcy5jb3VudCQuc2tpcCgxKS5zdWJzY3JpYmUodGhpcy5zdWJzY3JpYmVDb3VudC5iaW5kKHRoaXMpKTtcbiAgICB0aGlzLm9ic2VydmFibGVzLmFuaW1hdGluZyQuc3Vic2NyaWJlKHRoaXMuc3Vic2NyaWJlQW5pbWF0aW5nLmJpbmQodGhpcykpO1xufVxuXG5BbmltYXRpb24ucHJvdG90eXBlLnN1YnNjcmliZUFuaW1hdGluZyA9IGZ1bmN0aW9uKGlzQW5pbWF0aW5nKSB7XG4gICAgaWYgKGlzQW5pbWF0aW5nID09PSBmYWxzZSkge1xuICAgICAgICBjbGVhckludGVydmFsKHRoaXMuZnBzSW50ZXJ2YWwpO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIGNvbnN0IHsgZnBzJCB9ID0gdGhpcy5vYnNlcnZhYmxlcztcbiAgICAgICAgdGhpcy5mcHNJbnRlcnZhbCA9IHNldEludGVydmFsKGZwcyQubmV4dC5iaW5kKGZwcyQpLCAxMDAwIC8gMzIpO1xuICAgIH1cbn1cblxuQW5pbWF0aW9uLnByb3RvdHlwZS5zdWJzY3JpYmVDb3VudCA9IGZ1bmN0aW9uKGNvdW50KSB7XG4gICAgY29uc3QgYm91bmRzID0gdGhpcy5jb250YWluZXIuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG5cbiAgICB3aGlsZSAodGhpcy5wYXJ0aWNsZXMubGVuZ3RoID4gY291bnQpIHtcbiAgICAgICAgY29uc3QgcCA9IHRoaXMucGFydGljbGVzLnBvcCgpO1xuICAgICAgICBwLnJlbW92ZSgpO1xuICAgIH1cblxuICAgIHdoaWxlICh0aGlzLnBhcnRpY2xlcy5sZW5ndGggPCBjb3VudCkge1xuICAgICAgICBjb25zdCBwID0gbmV3IFBhcnRpY2xlKHRoaXMuY29udGFpbmVyLCBib3VuZHMsIHRoaXMuZ3JpZCwgdGhpcy5vYnNlcnZhYmxlcyk7XG4gICAgICAgIHRoaXMucGFydGljbGVzLnB1c2gocCk7XG4gICAgfVxufVxuXG5BbmltYXRpb24ucHJvdG90eXBlLmFkZEhhemFyZHMgPSBmdW5jdGlvbigpIHtcbiAgICBjb25zdCBib3VuZHMgPSB0aGlzLmNvbnRhaW5lci5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcblxuICAgIC8vIGNvbnN0IG4gPSBSYW5kb20ubnVtKDEsIDMpO1xuICAgIGNvbnN0IG4gPSAzXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBuOyBpKyspIHtcbiAgICAgICAgY29uc3QgdyA9IFJhbmRvbS5udW0oNTAsIDIwMCk7XG4gICAgICAgIGNvbnN0IGggPSBSYW5kb20ubnVtKDUwLCAyMDApO1xuXG4gICAgICAgIHRoaXMuZ3JpZC5zZXRBcmVhKHtcbiAgICAgICAgICAgIHg6IFJhbmRvbS5udW0oMCwgYm91bmRzLndpZHRoIC0gdyksXG4gICAgICAgICAgICB5OiBSYW5kb20ubnVtKDAsIGJvdW5kcy5oZWlnaHQgLSBoKSxcbiAgICAgICAgICAgIHcsXG4gICAgICAgICAgICBoLFxuICAgICAgICAgICAgdHlwZTogRU5USVRJRVMuSEFaQVJEXG4gICAgICAgIH0sIHRoaXMuY29udGFpbmVyKTtcbiAgICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IEFuaW1hdGlvbjtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyBqcy9hbmltYXRpb24uanMiXSwibWFwcGluZ3MiOiI7Ozs7OztBQUFBO0FBQ0E7OztBQUFBO0FBQ0E7OztBQUFBO0FBQ0E7OztBQUFBO0FBQ0E7OztBQUFBO0FBQ0E7OztBQUFBO0FBQ0E7OztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUxBO0FBT0E7QUFDQTtBQUNBO0FBQ0EiLCJzb3VyY2VSb290IjoiIn0="); +eval("\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nvar _rxjs = __webpack_require__(/*! rxjs */ 21);\n\nvar _rxjs2 = _interopRequireDefault(_rxjs);\n\nvar _grid = __webpack_require__(/*! ./grid */ 84);\n\nvar _grid2 = _interopRequireDefault(_grid);\n\nvar _particle = __webpack_require__(/*! ./particle */ 86);\n\nvar _particle2 = _interopRequireDefault(_particle);\n\nvar _controls = __webpack_require__(/*! ./controls */ 14);\n\nvar _controls2 = _interopRequireDefault(_controls);\n\nvar _random = __webpack_require__(/*! ./random */ 33);\n\nvar _random2 = _interopRequireDefault(_random);\n\nvar _enums = __webpack_require__(/*! ./enums */ 22);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nfunction Animation(observables, id, showHazards) {\n this.id = id;\n this.observables = observables;\n this.particles = [];\n this.grid = new _grid2.default();\n this.fpsInterval = null;\n\n this.container = document.createElement('div');\n this.container.className = 'animationContainer';\n document.getElementById(id).appendChild(this.container);\n\n this.observables.count$.skip(1).subscribe(this.subscribeCount.bind(this));\n this.observables.animating$.subscribe(this.subscribeAnimating.bind(this));\n}\n\nAnimation.prototype.subscribeAnimating = function (isAnimating) {\n if (isAnimating === false) {\n clearInterval(this.fpsInterval);\n } else {\n var fps$ = this.observables.fps$;\n\n this.fpsInterval = setInterval(fps$.next.bind(fps$), 1000 / 32);\n }\n};\n\nAnimation.prototype.subscribeCount = function (count) {\n var bounds = this.container.getBoundingClientRect();\n\n while (this.particles.length > count) {\n var p = this.particles.pop();\n p.remove();\n }\n\n while (this.particles.length < count) {\n var _p = new _particle2.default(this.container, bounds, this.grid, this.observables);\n this.particles.push(_p);\n }\n};\n\nAnimation.prototype.addHazards = function () {\n var bounds = this.container.getBoundingClientRect();\n\n var n = _random2.default.num(1, 3);\n for (var i = 0; i < n; i++) {\n var w = _random2.default.num(50, 200);\n var h = _random2.default.num(50, 200);\n\n this.grid.setArea({\n x: _random2.default.num(0, bounds.width - w),\n y: _random2.default.num(0, bounds.height - h),\n w: w,\n h: h,\n type: _enums.ENTITIES.HAZARD\n }, this.container);\n }\n};\n\nexports.default = Animation;//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMTUuanMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vanMvYW5pbWF0aW9uLmpzPzBiNTMiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IFJ4LCB7IE9ic2VydmFibGUgfSBmcm9tICdyeGpzJztcbmltcG9ydCBHcmlkIGZyb20gJy4vZ3JpZCc7XG5pbXBvcnQgUGFydGljbGUgZnJvbSAnLi9wYXJ0aWNsZSc7XG5pbXBvcnQgQ29udHJvbHMgZnJvbSAnLi9jb250cm9scyc7XG5pbXBvcnQgUmFuZG9tIGZyb20gJy4vcmFuZG9tJztcbmltcG9ydCB7IENPTlRST0xTLCBFTlRJVElFUyB9IGZyb20gJy4vZW51bXMnO1xuXG5mdW5jdGlvbiBBbmltYXRpb24ob2JzZXJ2YWJsZXMsIGlkLCBzaG93SGF6YXJkcykge1xuICAgIHRoaXMuaWQgPSBpZDtcbiAgICB0aGlzLm9ic2VydmFibGVzID0gb2JzZXJ2YWJsZXM7XG4gICAgdGhpcy5wYXJ0aWNsZXMgPSBbXTtcbiAgICB0aGlzLmdyaWQgPSBuZXcgR3JpZCgpO1xuICAgIHRoaXMuZnBzSW50ZXJ2YWwgPSBudWxsO1xuXG4gICAgdGhpcy5jb250YWluZXIgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICB0aGlzLmNvbnRhaW5lci5jbGFzc05hbWUgPSAnYW5pbWF0aW9uQ29udGFpbmVyJztcbiAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChpZCkuYXBwZW5kQ2hpbGQodGhpcy5jb250YWluZXIpO1xuXG4gICAgdGhpcy5vYnNlcnZhYmxlcy5jb3VudCQuc2tpcCgxKS5zdWJzY3JpYmUodGhpcy5zdWJzY3JpYmVDb3VudC5iaW5kKHRoaXMpKTtcbiAgICB0aGlzLm9ic2VydmFibGVzLmFuaW1hdGluZyQuc3Vic2NyaWJlKHRoaXMuc3Vic2NyaWJlQW5pbWF0aW5nLmJpbmQodGhpcykpO1xufVxuXG5BbmltYXRpb24ucHJvdG90eXBlLnN1YnNjcmliZUFuaW1hdGluZyA9IGZ1bmN0aW9uKGlzQW5pbWF0aW5nKSB7XG4gICAgaWYgKGlzQW5pbWF0aW5nID09PSBmYWxzZSkge1xuICAgICAgICBjbGVhckludGVydmFsKHRoaXMuZnBzSW50ZXJ2YWwpO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIGNvbnN0IHsgZnBzJCB9ID0gdGhpcy5vYnNlcnZhYmxlcztcbiAgICAgICAgdGhpcy5mcHNJbnRlcnZhbCA9IHNldEludGVydmFsKGZwcyQubmV4dC5iaW5kKGZwcyQpLCAxMDAwIC8gMzIpO1xuICAgIH1cbn1cblxuQW5pbWF0aW9uLnByb3RvdHlwZS5zdWJzY3JpYmVDb3VudCA9IGZ1bmN0aW9uKGNvdW50KSB7XG4gICAgY29uc3QgYm91bmRzID0gdGhpcy5jb250YWluZXIuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG5cbiAgICB3aGlsZSAodGhpcy5wYXJ0aWNsZXMubGVuZ3RoID4gY291bnQpIHtcbiAgICAgICAgY29uc3QgcCA9IHRoaXMucGFydGljbGVzLnBvcCgpO1xuICAgICAgICBwLnJlbW92ZSgpO1xuICAgIH1cblxuICAgIHdoaWxlICh0aGlzLnBhcnRpY2xlcy5sZW5ndGggPCBjb3VudCkge1xuICAgICAgICBjb25zdCBwID0gbmV3IFBhcnRpY2xlKHRoaXMuY29udGFpbmVyLCBib3VuZHMsIHRoaXMuZ3JpZCwgdGhpcy5vYnNlcnZhYmxlcyk7XG4gICAgICAgIHRoaXMucGFydGljbGVzLnB1c2gocCk7XG4gICAgfVxufVxuXG5BbmltYXRpb24ucHJvdG90eXBlLmFkZEhhemFyZHMgPSBmdW5jdGlvbigpIHtcbiAgICBjb25zdCBib3VuZHMgPSB0aGlzLmNvbnRhaW5lci5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcblxuICAgIGNvbnN0IG4gPSBSYW5kb20ubnVtKDEsIDMpO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbjsgaSsrKSB7XG4gICAgICAgIGNvbnN0IHcgPSBSYW5kb20ubnVtKDUwLCAyMDApO1xuICAgICAgICBjb25zdCBoID0gUmFuZG9tLm51bSg1MCwgMjAwKTtcblxuICAgICAgICB0aGlzLmdyaWQuc2V0QXJlYSh7XG4gICAgICAgICAgICB4OiBSYW5kb20ubnVtKDAsIGJvdW5kcy53aWR0aCAtIHcpLFxuICAgICAgICAgICAgeTogUmFuZG9tLm51bSgwLCBib3VuZHMuaGVpZ2h0IC0gaCksXG4gICAgICAgICAgICB3LFxuICAgICAgICAgICAgaCxcbiAgICAgICAgICAgIHR5cGU6IEVOVElUSUVTLkhBWkFSRFxuICAgICAgICB9LCB0aGlzLmNvbnRhaW5lcik7XG4gICAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBBbmltYXRpb247XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8ganMvYW5pbWF0aW9uLmpzIl0sIm1hcHBpbmdzIjoiOzs7Ozs7QUFBQTtBQUNBOzs7QUFBQTtBQUNBOzs7QUFBQTtBQUNBOzs7QUFBQTtBQUNBOzs7QUFBQTtBQUNBOzs7QUFBQTtBQUNBOzs7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBTEE7QUFPQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZVJvb3QiOiIifQ=="); /***/ }), /* 16 */ @@ -998,7 +998,7 @@ eval("\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n}); /***/ (function(module, exports, __webpack_require__) { "use strict"; -eval("\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nexports.default = function (destroy$) {\n var id = '3a';\n var config = {\n id: id,\n maxCount: 10,\n showAlignmentControl: true,\n showCohesionControl: true,\n showSeparationControl: true,\n showVisionGridControl: true\n };\n\n var observables = (0, _controls2.default)(destroy$, config);\n new _animation2.default(observables, id);\n};\n\nvar _animation = __webpack_require__(/*! ./animation */ 15);\n\nvar _animation2 = _interopRequireDefault(_animation);\n\nvar _controls = __webpack_require__(/*! ./controls */ 14);\n\nvar _controls2 = _interopRequireDefault(_controls);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNzcuanMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vanMvYW5pbWF0aW9uM2EuanM/YzA5NyJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgQW5pbWF0aW9uIGZyb20gJy4vYW5pbWF0aW9uJztcbmltcG9ydCBDb250cm9scyBmcm9tICcuL2NvbnRyb2xzJztcblxuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24oZGVzdHJveSQpIHtcbiAgICBjb25zdCBpZCA9ICczYSc7XG4gICAgY29uc3QgY29uZmlnID0ge1xuICAgICAgICBpZCxcbiAgICAgICAgbWF4Q291bnQ6IDEwLFxuICAgICAgICBzaG93QWxpZ25tZW50Q29udHJvbDogdHJ1ZSxcbiAgICAgICAgc2hvd0NvaGVzaW9uQ29udHJvbDogdHJ1ZSxcbiAgICAgICAgc2hvd1NlcGFyYXRpb25Db250cm9sOiB0cnVlLFxuICAgICAgICBzaG93VmlzaW9uR3JpZENvbnRyb2w6IHRydWVcbiAgICB9O1xuXG4gICAgY29uc3Qgb2JzZXJ2YWJsZXMgPSBDb250cm9scyhkZXN0cm95JCwgY29uZmlnKTtcbiAgICBuZXcgQW5pbWF0aW9uKG9ic2VydmFibGVzLCBpZCk7XG59XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8ganMvYW5pbWF0aW9uM2EuanMiXSwibWFwcGluZ3MiOiI7Ozs7OztBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQU5BO0FBQ0E7QUFRQTtBQUNBO0FBQ0E7QUFDQTtBQWpCQTtBQUNBOzs7QUFBQTtBQUNBOzs7QSIsInNvdXJjZVJvb3QiOiIifQ=="); +eval("\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nexports.default = function (destroy$) {\n var id = '3a';\n var config = {\n id: id,\n count: 5,\n maxCount: 1000,\n showAlignmentControl: true,\n showCohesionControl: true,\n showSeparationControl: true\n };\n\n var observables = (0, _controls2.default)(destroy$, config);\n new _animation2.default(observables, id);\n};\n\nvar _animation = __webpack_require__(/*! ./animation */ 15);\n\nvar _animation2 = _interopRequireDefault(_animation);\n\nvar _controls = __webpack_require__(/*! ./controls */ 14);\n\nvar _controls2 = _interopRequireDefault(_controls);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNzcuanMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vanMvYW5pbWF0aW9uM2EuanM/YzA5NyJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgQW5pbWF0aW9uIGZyb20gJy4vYW5pbWF0aW9uJztcbmltcG9ydCBDb250cm9scyBmcm9tICcuL2NvbnRyb2xzJztcblxuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24oZGVzdHJveSQpIHtcbiAgICBjb25zdCBpZCA9ICczYSc7XG4gICAgY29uc3QgY29uZmlnID0ge1xuICAgICAgICBpZCxcbiAgICAgICAgY291bnQ6IDUsXG4gICAgICAgIG1heENvdW50OiAxMDAwLFxuICAgICAgICBzaG93QWxpZ25tZW50Q29udHJvbDogdHJ1ZSxcbiAgICAgICAgc2hvd0NvaGVzaW9uQ29udHJvbDogdHJ1ZSxcbiAgICAgICAgc2hvd1NlcGFyYXRpb25Db250cm9sOiB0cnVlLFxuICAgICAgICAvLyBzaG93VmlzaW9uR3JpZENvbnRyb2w6IHRydWVcbiAgICB9O1xuXG4gICAgY29uc3Qgb2JzZXJ2YWJsZXMgPSBDb250cm9scyhkZXN0cm95JCwgY29uZmlnKTtcbiAgICBuZXcgQW5pbWF0aW9uKG9ic2VydmFibGVzLCBpZCk7XG59XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8ganMvYW5pbWF0aW9uM2EuanMiXSwibWFwcGluZ3MiOiI7Ozs7OztBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQU5BO0FBQ0E7QUFTQTtBQUNBO0FBQ0E7QUFDQTtBQWxCQTtBQUNBOzs7QUFBQTtBQUNBOzs7QSIsInNvdXJjZVJvb3QiOiIifQ=="); /***/ }), /* 78 */ @@ -1066,7 +1066,7 @@ eval("// removed by extract-text-webpack-plugin//# sourceMappingURL=data:applica /***/ (function(module, exports, __webpack_require__) { "use strict"; -eval("\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nvar _enums = __webpack_require__(/*! ./enums */ 22);\n\nvar _random = __webpack_require__(/*! ./random */ 33);\n\nvar _random2 = _interopRequireDefault(_random);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nvar Arc = {\n create: function create(bounds, grid) {\n var arc = {\n centerX: _random2.default.num(0, bounds.width),\n centerY: _random2.default.num(0, bounds.height),\n clockwise: _random2.default.bool(),\n endX: 0,\n endY: 0,\n length: _random2.default.num(_enums.RAD.t90, _enums.RAD.t360),\n prevEndX: 0,\n prevEndY: 0,\n radius: _random2.default.num(100, 200),\n theta: _random2.default.num(_enums.RAD.t90, _enums.RAD.t360)\n };\n\n arc.cosTheta = Math.cos(arc.theta);\n arc.sinTheta = Math.sin(arc.theta);\n\n arc.endX = arc.centerX + arc.radius * arc.cosTheta;\n arc.endY = arc.centerY - arc.radius * arc.sinTheta;\n\n arc = Arc.overflow(arc, bounds);\n\n // If starting in a hazard, recurse.\n // if (grid.getPoint({ x: arc.endX, y: arc.endY, type: ENTITIES.HAZARD })) {\n // arc = Arc.create(bounds, grid);\n // }\n\n return arc;\n },\n\n step: function step(arc, bounds, speed) {\n // Ensure constant velocity and theta between 0 and 2π.\n var delta = speed / arc.radius;\n arc.length -= delta;\n\n arc.theta += arc.clockwise ? -delta : +delta;\n arc.theta = arc.theta > 0 ? arc.theta % _enums.RAD.t360 : _enums.RAD.t360 + arc.theta;\n\n arc.cosTheta = Math.cos(arc.theta);\n arc.sinTheta = Math.sin(arc.theta);\n\n arc.prevEndX = arc.endX;\n arc.prevEndY = arc.endY;\n\n arc.endX = arc.centerX + arc.radius * arc.cosTheta;\n arc.endY = arc.centerY - arc.radius * arc.sinTheta;\n\n // Overflow.\n arc = Arc.overflow(arc, bounds);\n\n return arc;\n },\n\n randomize: function randomize(arc) {\n arc.length = _random2.default.num(_enums.RAD.t90, _enums.RAD.t360);\n\n arc = Arc.changeRadius(arc, _random2.default.num(100, 200));\n\n if (_random2.default.bool(0.8)) {\n arc = Arc.reverse(arc);\n }\n\n return arc;\n },\n\n overflow: function overflow(arc, bounds) {\n if (arc.endX < 0) {\n arc.endX += bounds.width;\n arc.centerX += bounds.width;\n } else if (arc.endX > bounds.width) {\n arc.endX -= bounds.width;\n arc.centerX -= bounds.width;\n }\n\n if (arc.endY < 0) {\n arc.endY += bounds.height;\n arc.centerY += bounds.height;\n } else if (arc.endY > bounds.height) {\n arc.endY -= bounds.height;\n arc.centerY -= bounds.height;\n }\n\n return arc;\n },\n\n changeRadius: function changeRadius(arc, newRadius) {\n var r0 = arc.radius;\n var r1 = newRadius;\n\n // Moves arc center to new radius while keeping theta constant.\n arc.centerX -= (r1 - r0) * arc.cosTheta;\n arc.centerY += (r1 - r0) * arc.sinTheta;\n arc.radius = r1;\n\n return arc;\n },\n\n reverse: function reverse(arc) {\n arc.clockwise = !arc.clockwise;\n\n arc.theta = (arc.theta + _enums.RAD.t180) % _enums.RAD.t360;\n\n arc.cosTheta = Math.cos(arc.theta);\n arc.sinTheta = Math.sin(arc.theta);\n\n arc.centerX -= 2 * arc.radius * arc.cosTheta;\n arc.centerY += 2 * arc.radius * arc.sinTheta;\n\n return arc;\n },\n\n follow: function follow(arc, arcToFollow) {\n if (arc.clockwise !== arcToFollow.clockwise) {\n arc = Arc.reverse(arc);\n }\n\n if (Math.abs(arc.theta - arcToFollow.theta) > 0.2) {\n arc = Arc.changeRadius(arc, 50);\n } else {\n arc = Arc.changeRadius(arc, arcToFollow.radius);\n }\n\n return arc;\n },\n\n goto: function goto(arc, x, y, speed) {\n var prevD = Math.pow(Math.pow(x - arc.prevEndX, 2) + Math.pow(y - arc.prevEndY, 2), 0.5);\n var currD = Math.pow(Math.pow(x - arc.endX, 2) + Math.pow(y - arc.endY, 2), 0.5);\n var ratio = (prevD - currD) / speed;\n\n if (currD < 10) {\n throw new Error('Arc end of (' + arc.endX + ',' + arc.endY + ') is within 50px of (' + x + ',' + y + ')');\n } else if (ratio < 0.8) {\n // arc = (ratio < 0 ? Arc.reverse(arc) : arc);\n arc = Arc.changeRadius(arc, 20);\n } else {\n arc = Arc.changeRadius(arc, 400);\n }\n\n return arc;\n },\n\n evade: function evade(arc) {\n arc = Arc.changeRadius(arc, 20);\n arc.length = 1;\n\n return arc;\n }\n};\n\nexports.default = Arc;//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiODMuanMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vanMvYXJjLmpzPzliNWYiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgRU5USVRJRVMsIFJBRCB9IGZyb20gJy4vZW51bXMnO1xuaW1wb3J0IFJhbmRvbSBmcm9tICcuL3JhbmRvbSc7XG5cbmNvbnN0IEFyYyA9IHtcbiAgICBjcmVhdGU6IGZ1bmN0aW9uKGJvdW5kcywgZ3JpZCkge1xuICAgICAgICBsZXQgYXJjID0ge1xuICAgICAgICAgICAgY2VudGVyWDogUmFuZG9tLm51bSgwLCBib3VuZHMud2lkdGgpLFxuICAgICAgICAgICAgY2VudGVyWTogUmFuZG9tLm51bSgwLCBib3VuZHMuaGVpZ2h0KSxcbiAgICAgICAgICAgIGNsb2Nrd2lzZTogUmFuZG9tLmJvb2woKSxcbiAgICAgICAgICAgIGVuZFg6IDAsXG4gICAgICAgICAgICBlbmRZOiAwLFxuICAgICAgICAgICAgbGVuZ3RoOiBSYW5kb20ubnVtKFJBRC50OTAsIFJBRC50MzYwKSxcbiAgICAgICAgICAgIHByZXZFbmRYOiAwLFxuICAgICAgICAgICAgcHJldkVuZFk6IDAsXG4gICAgICAgICAgICByYWRpdXM6IFJhbmRvbS5udW0oMTAwLCAyMDApLFxuICAgICAgICAgICAgdGhldGE6IFJhbmRvbS5udW0oUkFELnQ5MCwgUkFELnQzNjApXG4gICAgICAgIH07XG5cbiAgICAgICAgYXJjLmNvc1RoZXRhID0gTWF0aC5jb3MoYXJjLnRoZXRhKTtcbiAgICAgICAgYXJjLnNpblRoZXRhID0gTWF0aC5zaW4oYXJjLnRoZXRhKTtcblxuICAgICAgICBhcmMuZW5kWCA9IGFyYy5jZW50ZXJYICsgYXJjLnJhZGl1cyAqIGFyYy5jb3NUaGV0YTtcbiAgICAgICAgYXJjLmVuZFkgPSBhcmMuY2VudGVyWSAtIGFyYy5yYWRpdXMgKiBhcmMuc2luVGhldGE7XG5cbiAgICAgICAgYXJjID0gQXJjLm92ZXJmbG93KGFyYywgYm91bmRzKTtcblxuICAgICAgICAvLyBJZiBzdGFydGluZyBpbiBhIGhhemFyZCwgcmVjdXJzZS5cbiAgICAgICAgLy8gaWYgKGdyaWQuZ2V0UG9pbnQoeyB4OiBhcmMuZW5kWCwgeTogYXJjLmVuZFksIHR5cGU6IEVOVElUSUVTLkhBWkFSRCB9KSkge1xuICAgICAgICAvLyAgICAgYXJjID0gQXJjLmNyZWF0ZShib3VuZHMsIGdyaWQpO1xuICAgICAgICAvLyB9XG5cbiAgICAgICAgcmV0dXJuIGFyYztcbiAgICB9LFxuXG4gICAgc3RlcDogZnVuY3Rpb24oYXJjLCBib3VuZHMsIHNwZWVkKSB7XG4gICAgICAgIC8vIEVuc3VyZSBjb25zdGFudCB2ZWxvY2l0eSBhbmQgdGhldGEgYmV0d2VlbiAwIGFuZCAyz4AuXG4gICAgICAgIGNvbnN0IGRlbHRhID0gc3BlZWQgLyBhcmMucmFkaXVzO1xuICAgICAgICBhcmMubGVuZ3RoIC09IGRlbHRhO1xuXG4gICAgICAgIGFyYy50aGV0YSArPSAoYXJjLmNsb2Nrd2lzZSA/IC1kZWx0YSA6ICtkZWx0YSk7XG4gICAgICAgIGFyYy50aGV0YSA9IChhcmMudGhldGEgPiAwID8gYXJjLnRoZXRhICUgUkFELnQzNjAgOiBSQUQudDM2MCArIGFyYy50aGV0YSk7XG5cbiAgICAgICAgYXJjLmNvc1RoZXRhID0gTWF0aC5jb3MoYXJjLnRoZXRhKTtcbiAgICAgICAgYXJjLnNpblRoZXRhID0gTWF0aC5zaW4oYXJjLnRoZXRhKTtcblxuICAgICAgICBhcmMucHJldkVuZFggPSBhcmMuZW5kWDtcbiAgICAgICAgYXJjLnByZXZFbmRZID0gYXJjLmVuZFk7XG5cbiAgICAgICAgYXJjLmVuZFggPSBhcmMuY2VudGVyWCArIGFyYy5yYWRpdXMgKiBhcmMuY29zVGhldGE7XG4gICAgICAgIGFyYy5lbmRZID0gYXJjLmNlbnRlclkgLSBhcmMucmFkaXVzICogYXJjLnNpblRoZXRhO1xuXG4gICAgICAgIC8vIE92ZXJmbG93LlxuICAgICAgICBhcmMgPSBBcmMub3ZlcmZsb3coYXJjLCBib3VuZHMpO1xuXG4gICAgICAgIHJldHVybiBhcmM7XG4gICAgfSxcblxuICAgIHJhbmRvbWl6ZTogZnVuY3Rpb24oYXJjKSB7XG4gICAgICAgIGFyYy5sZW5ndGggPSBSYW5kb20ubnVtKFJBRC50OTAsIFJBRC50MzYwKTtcblxuICAgICAgICBhcmMgPSBBcmMuY2hhbmdlUmFkaXVzKGFyYywgUmFuZG9tLm51bSgxMDAsIDIwMCkpO1xuXG4gICAgICAgIGlmIChSYW5kb20uYm9vbCgwLjgpKSB7XG4gICAgICAgICAgICBhcmMgPSBBcmMucmV2ZXJzZShhcmMpO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGFyYztcbiAgICB9LFxuXG4gICAgb3ZlcmZsb3c6IGZ1bmN0aW9uKGFyYywgYm91bmRzKSB7XG4gICAgICAgIGlmIChhcmMuZW5kWCA8IDApIHtcbiAgICAgICAgICAgIGFyYy5lbmRYICs9IGJvdW5kcy53aWR0aDtcbiAgICAgICAgICAgIGFyYy5jZW50ZXJYICs9IGJvdW5kcy53aWR0aFxuICAgICAgICB9IGVsc2UgaWYgKGFyYy5lbmRYID4gYm91bmRzLndpZHRoKSB7XG4gICAgICAgICAgICBhcmMuZW5kWCAtPSBib3VuZHMud2lkdGg7XG4gICAgICAgICAgICBhcmMuY2VudGVyWCAtPSBib3VuZHMud2lkdGhcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChhcmMuZW5kWSA8IDApIHtcbiAgICAgICAgICAgIGFyYy5lbmRZICs9IGJvdW5kcy5oZWlnaHQ7XG4gICAgICAgICAgICBhcmMuY2VudGVyWSArPSBib3VuZHMuaGVpZ2h0XG4gICAgICAgIH0gZWxzZSBpZiAoYXJjLmVuZFkgPiBib3VuZHMuaGVpZ2h0KSB7XG4gICAgICAgICAgICBhcmMuZW5kWSAtPSBib3VuZHMuaGVpZ2h0O1xuICAgICAgICAgICAgYXJjLmNlbnRlclkgLT0gYm91bmRzLmhlaWdodFxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGFyYztcbiAgICB9LFxuXG4gICAgY2hhbmdlUmFkaXVzOiBmdW5jdGlvbihhcmMsIG5ld1JhZGl1cykge1xuICAgICAgICBjb25zdCByMCA9IGFyYy5yYWRpdXM7XG4gICAgICAgIGNvbnN0IHIxID0gbmV3UmFkaXVzO1xuXG4gICAgICAgIC8vIE1vdmVzIGFyYyBjZW50ZXIgdG8gbmV3IHJhZGl1cyB3aGlsZSBrZWVwaW5nIHRoZXRhIGNvbnN0YW50LlxuICAgICAgICBhcmMuY2VudGVyWCAtPSAocjEgLSByMCkgKiBhcmMuY29zVGhldGE7XG4gICAgICAgIGFyYy5jZW50ZXJZICs9IChyMSAtIHIwKSAqIGFyYy5zaW5UaGV0YTtcbiAgICAgICAgYXJjLnJhZGl1cyA9IHIxO1xuXG4gICAgICAgIHJldHVybiBhcmM7XG4gICAgfSxcblxuICAgIHJldmVyc2U6IGZ1bmN0aW9uKGFyYykge1xuICAgICAgICBhcmMuY2xvY2t3aXNlID0gIWFyYy5jbG9ja3dpc2U7XG5cbiAgICAgICAgYXJjLnRoZXRhID0gKGFyYy50aGV0YSArIFJBRC50MTgwKSAlIFJBRC50MzYwO1xuXG4gICAgICAgIGFyYy5jb3NUaGV0YSA9IE1hdGguY29zKGFyYy50aGV0YSk7XG4gICAgICAgIGFyYy5zaW5UaGV0YSA9IE1hdGguc2luKGFyYy50aGV0YSk7XG5cbiAgICAgICAgYXJjLmNlbnRlclggLT0gKDIgKiBhcmMucmFkaXVzKSAqIGFyYy5jb3NUaGV0YTtcbiAgICAgICAgYXJjLmNlbnRlclkgKz0gKDIgKiBhcmMucmFkaXVzKSAqIGFyYy5zaW5UaGV0YTtcblxuICAgICAgICByZXR1cm4gYXJjO1xuICAgIH0sXG5cbiAgICBmb2xsb3c6IGZ1bmN0aW9uKGFyYywgYXJjVG9Gb2xsb3cpIHtcbiAgICAgICAgaWYgKGFyYy5jbG9ja3dpc2UgIT09IGFyY1RvRm9sbG93LmNsb2Nrd2lzZSkge1xuICAgICAgICAgICAgYXJjID0gQXJjLnJldmVyc2UoYXJjKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChNYXRoLmFicyhhcmMudGhldGEgLSBhcmNUb0ZvbGxvdy50aGV0YSkgPiAwLjIpIHtcbiAgICAgICAgICAgIGFyYyA9IEFyYy5jaGFuZ2VSYWRpdXMoYXJjLCA1MCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBhcmMgPSBBcmMuY2hhbmdlUmFkaXVzKGFyYywgYXJjVG9Gb2xsb3cucmFkaXVzKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBhcmM7XG4gICAgfSxcblxuICAgIGdvdG86IGZ1bmN0aW9uIChhcmMsIHgsIHksIHNwZWVkKSB7XG4gICAgICAgIGNvbnN0IHByZXZEID0gTWF0aC5wb3coTWF0aC5wb3coeCAtIGFyYy5wcmV2RW5kWCwgMikgKyBNYXRoLnBvdyh5IC0gYXJjLnByZXZFbmRZLCAyKSwgMC41KTtcbiAgICAgICAgY29uc3QgY3VyckQgPSBNYXRoLnBvdyhNYXRoLnBvdyh4IC0gYXJjLmVuZFgsIDIpICsgTWF0aC5wb3coeSAtIGFyYy5lbmRZLCAyKSwgMC41KTtcbiAgICAgICAgY29uc3QgcmF0aW8gPSAocHJldkQgLSBjdXJyRCkgLyBzcGVlZDtcblxuICAgICAgICBpZiAoY3VyckQgPCAxMCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBBcmMgZW5kIG9mICgke2FyYy5lbmRYfSwke2FyYy5lbmRZfSkgaXMgd2l0aGluIDUwcHggb2YgKCR7eH0sJHt5fSlgKTtcbiAgICAgICAgfSBlbHNlIGlmIChyYXRpbyA8IDAuOCkge1xuICAgICAgICAgICAgLy8gYXJjID0gKHJhdGlvIDwgMCA/IEFyYy5yZXZlcnNlKGFyYykgOiBhcmMpO1xuICAgICAgICAgICAgYXJjID0gQXJjLmNoYW5nZVJhZGl1cyhhcmMsIDIwKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGFyYyA9IEFyYy5jaGFuZ2VSYWRpdXMoYXJjLCA0MDApO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGFyYztcbiAgICB9LFxuXG4gICAgZXZhZGU6IGZ1bmN0aW9uKGFyYykge1xuICAgICAgICBhcmMgPSBBcmMuY2hhbmdlUmFkaXVzKGFyYywgMjApO1xuICAgICAgICBhcmMubGVuZ3RoID0gMTtcblxuICAgICAgICByZXR1cm4gYXJjO1xuICAgIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgQXJjO1xuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIGpzL2FyYy5qcyJdLCJtYXBwaW5ncyI6Ijs7Ozs7O0FBQUE7QUFDQTtBQUFBO0FBQ0E7Ozs7O0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFWQTtBQUNBO0FBWUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQXBKQTtBQUNBO0FBc0pBIiwic291cmNlUm9vdCI6IiJ9"); +eval("\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nvar _enums = __webpack_require__(/*! ./enums */ 22);\n\nvar _random = __webpack_require__(/*! ./random */ 33);\n\nvar _random2 = _interopRequireDefault(_random);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nvar Arc = {\n create: function create(bounds, grid) {\n var arc = {\n centerX: _random2.default.num(0, bounds.width),\n centerY: _random2.default.num(0, bounds.height),\n clockwise: _random2.default.bool(),\n endX: 0,\n endY: 0,\n length: _random2.default.num(_enums.RAD.t90, _enums.RAD.t360),\n prevEndX: 0,\n prevEndY: 0,\n radius: _random2.default.num(100, 200),\n speed: 0,\n theta: _random2.default.num(_enums.RAD.t90, _enums.RAD.t360)\n };\n\n arc.cosTheta = Math.cos(arc.theta);\n arc.sinTheta = Math.sin(arc.theta);\n\n arc.endX = arc.centerX + arc.radius * arc.cosTheta;\n arc.endY = arc.centerY - arc.radius * arc.sinTheta;\n\n arc = Arc.overflow(arc, bounds);\n\n // If starting in a hazard, recurse.\n // if (grid.getPoint({ x: arc.endX, y: arc.endY, type: ENTITIES.HAZARD })) {\n // arc = Arc.create(bounds, grid);\n // }\n\n return arc;\n },\n\n step: function step(arc, bounds) {\n // Ensure constant velocity and theta between 0 and 2π.\n var delta = arc.speed / arc.radius;\n arc.length -= delta;\n\n arc.theta += arc.clockwise ? -delta : +delta;\n arc.theta = arc.theta > 0 ? arc.theta % _enums.RAD.t360 : _enums.RAD.t360 + arc.theta;\n\n arc.cosTheta = Math.cos(arc.theta);\n arc.sinTheta = Math.sin(arc.theta);\n\n arc.prevEndX = arc.endX;\n arc.prevEndY = arc.endY;\n\n arc.endX = arc.centerX + arc.radius * arc.cosTheta;\n arc.endY = arc.centerY - arc.radius * arc.sinTheta;\n\n // Overflow.\n arc = Arc.overflow(arc, bounds);\n\n return arc;\n },\n\n randomize: function randomize(arc) {\n arc.length = _random2.default.num(_enums.RAD.t90, _enums.RAD.t360);\n\n arc = Arc.changeRadius(arc, _random2.default.num(100, 200));\n\n if (_random2.default.bool(0.8)) {\n arc = Arc.reverse(arc);\n }\n\n return arc;\n },\n\n overflow: function overflow(arc, bounds) {\n if (arc.endX < 0) {\n arc.endX += bounds.width;\n arc.centerX += bounds.width;\n } else if (arc.endX > bounds.width) {\n arc.endX -= bounds.width;\n arc.centerX -= bounds.width;\n }\n\n if (arc.endY < 0) {\n arc.endY += bounds.height;\n arc.centerY += bounds.height;\n } else if (arc.endY > bounds.height) {\n arc.endY -= bounds.height;\n arc.centerY -= bounds.height;\n }\n\n return arc;\n },\n\n changeRadius: function changeRadius(arc, newRadius) {\n var r0 = arc.radius;\n var r1 = newRadius;\n\n // Moves arc center to new radius while keeping theta constant.\n arc.centerX -= (r1 - r0) * arc.cosTheta;\n arc.centerY += (r1 - r0) * arc.sinTheta;\n arc.radius = r1;\n\n return arc;\n },\n\n changeSpeed: function changeSpeed(arc, newSpeed) {\n arc.speed = newSpeed * 1;\n return arc;\n },\n\n reverse: function reverse(arc) {\n arc.clockwise = !arc.clockwise;\n\n arc.theta = (arc.theta + _enums.RAD.t180) % _enums.RAD.t360;\n\n arc.cosTheta = Math.cos(arc.theta);\n arc.sinTheta = Math.sin(arc.theta);\n\n arc.centerX -= 2 * arc.radius * arc.cosTheta;\n arc.centerY += 2 * arc.radius * arc.sinTheta;\n\n return arc;\n },\n\n match: function match(arc, arcToMatch) {},\n\n follow: function follow(arc, arcToFollow) {\n arc = arc.clockwise !== arcToFollow.clockwise ? Arc.reverse(arc) : arc;\n\n var prevD = Math.pow(Math.pow(arcToFollow.endX - arc.prevEndX, 2) + Math.pow(arcToFollow.endY - arc.prevEndY, 2), 0.5);\n\n var currD = Math.pow(Math.pow(arcToFollow.endX - arc.endX, 2) + Math.pow(arcToFollow.endY - arc.endY, 2), 0.5);\n\n // \"How much of movement is in the correct direction\"\n var ratio = (prevD - currD) / arc.speed;\n\n // TODO adjust speed\n // TODO turn in the correct direction\n\n if (currD < 20) {\n // if (Math.abs(arc.centerX - arcToFollow.centerX) < 10 && Math.abs(arc.centerY - arcToFollow.centerX) < 10) {\n arc = Arc.changeRadius(arc, arcToFollow.radius);\n if (arc.speed > arcToFollow.speed) {\n arc = Arc.changeSpeed(arc, arc.speed - 1);\n }\n } else if (ratio < 0.8) {\n // arc = (ratio < 0 ? Arc.reverse(arc) : arc);\n arc = Arc.changeRadius(arc, 20);\n } else {\n arc = Arc.changeRadius(arc, 400);\n\n if (arc.speed < arcToFollow.speed + 2) {\n arc = Arc.changeSpeed(arc, arc.speed + 1);\n }\n }\n\n return arc;\n },\n\n evade: function evade(arc) {\n arc = Arc.changeRadius(arc, 20);\n arc.length = 1;\n\n return arc;\n }\n};\n\nexports.default = Arc;//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiODMuanMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vanMvYXJjLmpzPzliNWYiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgRU5USVRJRVMsIFJBRCB9IGZyb20gJy4vZW51bXMnO1xuaW1wb3J0IFJhbmRvbSBmcm9tICcuL3JhbmRvbSc7XG5cbmNvbnN0IEFyYyA9IHtcbiAgICBjcmVhdGU6IGZ1bmN0aW9uKGJvdW5kcywgZ3JpZCkge1xuICAgICAgICBsZXQgYXJjID0ge1xuICAgICAgICAgICAgY2VudGVyWDogUmFuZG9tLm51bSgwLCBib3VuZHMud2lkdGgpLFxuICAgICAgICAgICAgY2VudGVyWTogUmFuZG9tLm51bSgwLCBib3VuZHMuaGVpZ2h0KSxcbiAgICAgICAgICAgIGNsb2Nrd2lzZTogUmFuZG9tLmJvb2woKSxcbiAgICAgICAgICAgIGVuZFg6IDAsXG4gICAgICAgICAgICBlbmRZOiAwLFxuICAgICAgICAgICAgbGVuZ3RoOiBSYW5kb20ubnVtKFJBRC50OTAsIFJBRC50MzYwKSxcbiAgICAgICAgICAgIHByZXZFbmRYOiAwLFxuICAgICAgICAgICAgcHJldkVuZFk6IDAsXG4gICAgICAgICAgICByYWRpdXM6IFJhbmRvbS5udW0oMTAwLCAyMDApLFxuICAgICAgICAgICAgc3BlZWQ6IDAsXG4gICAgICAgICAgICB0aGV0YTogUmFuZG9tLm51bShSQUQudDkwLCBSQUQudDM2MClcbiAgICAgICAgfTtcblxuICAgICAgICBhcmMuY29zVGhldGEgPSBNYXRoLmNvcyhhcmMudGhldGEpO1xuICAgICAgICBhcmMuc2luVGhldGEgPSBNYXRoLnNpbihhcmMudGhldGEpO1xuXG4gICAgICAgIGFyYy5lbmRYID0gYXJjLmNlbnRlclggKyBhcmMucmFkaXVzICogYXJjLmNvc1RoZXRhO1xuICAgICAgICBhcmMuZW5kWSA9IGFyYy5jZW50ZXJZIC0gYXJjLnJhZGl1cyAqIGFyYy5zaW5UaGV0YTtcblxuICAgICAgICBhcmMgPSBBcmMub3ZlcmZsb3coYXJjLCBib3VuZHMpO1xuXG4gICAgICAgIC8vIElmIHN0YXJ0aW5nIGluIGEgaGF6YXJkLCByZWN1cnNlLlxuICAgICAgICAvLyBpZiAoZ3JpZC5nZXRQb2ludCh7IHg6IGFyYy5lbmRYLCB5OiBhcmMuZW5kWSwgdHlwZTogRU5USVRJRVMuSEFaQVJEIH0pKSB7XG4gICAgICAgIC8vICAgICBhcmMgPSBBcmMuY3JlYXRlKGJvdW5kcywgZ3JpZCk7XG4gICAgICAgIC8vIH1cblxuICAgICAgICByZXR1cm4gYXJjO1xuICAgIH0sXG5cbiAgICBzdGVwOiBmdW5jdGlvbihhcmMsIGJvdW5kcykge1xuICAgICAgICAvLyBFbnN1cmUgY29uc3RhbnQgdmVsb2NpdHkgYW5kIHRoZXRhIGJldHdlZW4gMCBhbmQgMs+ALlxuICAgICAgICBjb25zdCBkZWx0YSA9IGFyYy5zcGVlZCAvIGFyYy5yYWRpdXM7XG4gICAgICAgIGFyYy5sZW5ndGggLT0gZGVsdGE7XG5cbiAgICAgICAgYXJjLnRoZXRhICs9IChhcmMuY2xvY2t3aXNlID8gLWRlbHRhIDogK2RlbHRhKTtcbiAgICAgICAgYXJjLnRoZXRhID0gKGFyYy50aGV0YSA+IDAgPyBhcmMudGhldGEgJSBSQUQudDM2MCA6IFJBRC50MzYwICsgYXJjLnRoZXRhKTtcblxuICAgICAgICBhcmMuY29zVGhldGEgPSBNYXRoLmNvcyhhcmMudGhldGEpO1xuICAgICAgICBhcmMuc2luVGhldGEgPSBNYXRoLnNpbihhcmMudGhldGEpO1xuXG4gICAgICAgIGFyYy5wcmV2RW5kWCA9IGFyYy5lbmRYO1xuICAgICAgICBhcmMucHJldkVuZFkgPSBhcmMuZW5kWTtcblxuICAgICAgICBhcmMuZW5kWCA9IGFyYy5jZW50ZXJYICsgYXJjLnJhZGl1cyAqIGFyYy5jb3NUaGV0YTtcbiAgICAgICAgYXJjLmVuZFkgPSBhcmMuY2VudGVyWSAtIGFyYy5yYWRpdXMgKiBhcmMuc2luVGhldGE7XG5cbiAgICAgICAgLy8gT3ZlcmZsb3cuXG4gICAgICAgIGFyYyA9IEFyYy5vdmVyZmxvdyhhcmMsIGJvdW5kcyk7XG5cbiAgICAgICAgcmV0dXJuIGFyYztcbiAgICB9LFxuXG4gICAgcmFuZG9taXplOiBmdW5jdGlvbihhcmMpIHtcbiAgICAgICAgYXJjLmxlbmd0aCA9IFJhbmRvbS5udW0oUkFELnQ5MCwgUkFELnQzNjApO1xuXG4gICAgICAgIGFyYyA9IEFyYy5jaGFuZ2VSYWRpdXMoYXJjLCBSYW5kb20ubnVtKDEwMCwgMjAwKSk7XG5cbiAgICAgICAgaWYgKFJhbmRvbS5ib29sKDAuOCkpIHtcbiAgICAgICAgICAgIGFyYyA9IEFyYy5yZXZlcnNlKGFyYyk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gYXJjO1xuICAgIH0sXG5cbiAgICBvdmVyZmxvdzogZnVuY3Rpb24oYXJjLCBib3VuZHMpIHtcbiAgICAgICAgaWYgKGFyYy5lbmRYIDwgMCkge1xuICAgICAgICAgICAgYXJjLmVuZFggKz0gYm91bmRzLndpZHRoO1xuICAgICAgICAgICAgYXJjLmNlbnRlclggKz0gYm91bmRzLndpZHRoXG4gICAgICAgIH0gZWxzZSBpZiAoYXJjLmVuZFggPiBib3VuZHMud2lkdGgpIHtcbiAgICAgICAgICAgIGFyYy5lbmRYIC09IGJvdW5kcy53aWR0aDtcbiAgICAgICAgICAgIGFyYy5jZW50ZXJYIC09IGJvdW5kcy53aWR0aFxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGFyYy5lbmRZIDwgMCkge1xuICAgICAgICAgICAgYXJjLmVuZFkgKz0gYm91bmRzLmhlaWdodDtcbiAgICAgICAgICAgIGFyYy5jZW50ZXJZICs9IGJvdW5kcy5oZWlnaHRcbiAgICAgICAgfSBlbHNlIGlmIChhcmMuZW5kWSA+IGJvdW5kcy5oZWlnaHQpIHtcbiAgICAgICAgICAgIGFyYy5lbmRZIC09IGJvdW5kcy5oZWlnaHQ7XG4gICAgICAgICAgICBhcmMuY2VudGVyWSAtPSBib3VuZHMuaGVpZ2h0XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gYXJjO1xuICAgIH0sXG5cbiAgICBjaGFuZ2VSYWRpdXM6IGZ1bmN0aW9uKGFyYywgbmV3UmFkaXVzKSB7XG4gICAgICAgIGNvbnN0IHIwID0gYXJjLnJhZGl1cztcbiAgICAgICAgY29uc3QgcjEgPSBuZXdSYWRpdXM7XG5cbiAgICAgICAgLy8gTW92ZXMgYXJjIGNlbnRlciB0byBuZXcgcmFkaXVzIHdoaWxlIGtlZXBpbmcgdGhldGEgY29uc3RhbnQuXG4gICAgICAgIGFyYy5jZW50ZXJYIC09IChyMSAtIHIwKSAqIGFyYy5jb3NUaGV0YTtcbiAgICAgICAgYXJjLmNlbnRlclkgKz0gKHIxIC0gcjApICogYXJjLnNpblRoZXRhO1xuICAgICAgICBhcmMucmFkaXVzID0gcjE7XG5cbiAgICAgICAgcmV0dXJuIGFyYztcbiAgICB9LFxuXG4gICAgY2hhbmdlU3BlZWQ6IGZ1bmN0aW9uKGFyYywgbmV3U3BlZWQpIHtcbiAgICAgICAgYXJjLnNwZWVkID0gbmV3U3BlZWQgKiAxO1xuICAgICAgICByZXR1cm4gYXJjO1xuICAgIH0sXG5cbiAgICByZXZlcnNlOiBmdW5jdGlvbihhcmMpIHtcbiAgICAgICAgYXJjLmNsb2Nrd2lzZSA9ICFhcmMuY2xvY2t3aXNlO1xuXG4gICAgICAgIGFyYy50aGV0YSA9IChhcmMudGhldGEgKyBSQUQudDE4MCkgJSBSQUQudDM2MDtcblxuICAgICAgICBhcmMuY29zVGhldGEgPSBNYXRoLmNvcyhhcmMudGhldGEpO1xuICAgICAgICBhcmMuc2luVGhldGEgPSBNYXRoLnNpbihhcmMudGhldGEpO1xuXG4gICAgICAgIGFyYy5jZW50ZXJYIC09ICgyICogYXJjLnJhZGl1cykgKiBhcmMuY29zVGhldGE7XG4gICAgICAgIGFyYy5jZW50ZXJZICs9ICgyICogYXJjLnJhZGl1cykgKiBhcmMuc2luVGhldGE7XG5cbiAgICAgICAgcmV0dXJuIGFyYztcbiAgICB9LFxuXG4gICAgbWF0Y2g6IGZ1bmN0aW9uKGFyYywgYXJjVG9NYXRjaCkge1xuXG4gICAgfSxcblxuICAgIGZvbGxvdzogZnVuY3Rpb24oYXJjLCBhcmNUb0ZvbGxvdykge1xuICAgICAgICBhcmMgPSAoYXJjLmNsb2Nrd2lzZSAhPT0gYXJjVG9Gb2xsb3cuY2xvY2t3aXNlID8gQXJjLnJldmVyc2UoYXJjKSA6IGFyYyk7XG5cbiAgICAgICAgY29uc3QgcHJldkQgPSBNYXRoLnBvdyhcbiAgICAgICAgICAgIE1hdGgucG93KGFyY1RvRm9sbG93LmVuZFggLSBhcmMucHJldkVuZFgsIDIpICtcbiAgICAgICAgICAgIE1hdGgucG93KGFyY1RvRm9sbG93LmVuZFkgLSBhcmMucHJldkVuZFksIDIpXG4gICAgICAgICwgMC41KTtcblxuICAgICAgICBjb25zdCBjdXJyRCA9IE1hdGgucG93KFxuICAgICAgICAgICAgTWF0aC5wb3coYXJjVG9Gb2xsb3cuZW5kWCAtIGFyYy5lbmRYLCAyKSArXG4gICAgICAgICAgICAgTWF0aC5wb3coYXJjVG9Gb2xsb3cuZW5kWSAtIGFyYy5lbmRZLCAyKVxuICAgICAgICAsIDAuNSk7XG5cbiAgICAgICAgLy8gXCJIb3cgbXVjaCBvZiBtb3ZlbWVudCBpcyBpbiB0aGUgY29ycmVjdCBkaXJlY3Rpb25cIlxuICAgICAgICBjb25zdCByYXRpbyA9IChwcmV2RCAtIGN1cnJEKSAvIGFyYy5zcGVlZDtcblxuICAgICAgICAvLyBUT0RPIGFkanVzdCBzcGVlZFxuICAgICAgICAvLyBUT0RPIHR1cm4gaW4gdGhlIGNvcnJlY3QgZGlyZWN0aW9uXG5cbiAgICAgICAgaWYgKGN1cnJEIDwgMjApIHtcbiAgICAgICAgLy8gaWYgKE1hdGguYWJzKGFyYy5jZW50ZXJYIC0gYXJjVG9Gb2xsb3cuY2VudGVyWCkgPCAxMCAmJiBNYXRoLmFicyhhcmMuY2VudGVyWSAtIGFyY1RvRm9sbG93LmNlbnRlclgpIDwgMTApIHtcbiAgICAgICAgICAgIGFyYyA9IEFyYy5jaGFuZ2VSYWRpdXMoYXJjLCBhcmNUb0ZvbGxvdy5yYWRpdXMpO1xuICAgICAgICAgICAgaWYgKGFyYy5zcGVlZCA+IGFyY1RvRm9sbG93LnNwZWVkKSB7XG4gICAgICAgICAgICAgICAgYXJjID0gQXJjLmNoYW5nZVNwZWVkKGFyYywgYXJjLnNwZWVkIC0gMSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSBpZiAocmF0aW8gPCAwLjgpIHtcbiAgICAgICAgICAgIC8vIGFyYyA9IChyYXRpbyA8IDAgPyBBcmMucmV2ZXJzZShhcmMpIDogYXJjKTtcbiAgICAgICAgICAgIGFyYyA9IEFyYy5jaGFuZ2VSYWRpdXMoYXJjLCAyMCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBhcmMgPSBBcmMuY2hhbmdlUmFkaXVzKGFyYywgNDAwKTtcblxuICAgICAgICAgICAgaWYgKGFyYy5zcGVlZCA8IChhcmNUb0ZvbGxvdy5zcGVlZCArIDIpKSB7XG4gICAgICAgICAgICAgICAgYXJjID0gQXJjLmNoYW5nZVNwZWVkKGFyYywgYXJjLnNwZWVkICsgMSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gYXJjO1xuICAgIH0sXG5cbiAgICBldmFkZTogZnVuY3Rpb24oYXJjKSB7XG4gICAgICAgIGFyYyA9IEFyYy5jaGFuZ2VSYWRpdXMoYXJjLCAyMCk7XG4gICAgICAgIGFyYy5sZW5ndGggPSAxO1xuXG4gICAgICAgIHJldHVybiBhcmM7XG4gICAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBBcmM7XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8ganMvYXJjLmpzIl0sIm1hcHBpbmdzIjoiOzs7Ozs7QUFBQTtBQUNBO0FBQUE7QUFDQTs7Ozs7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBWEE7QUFDQTtBQWFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBSUE7QUFDQTtBQUlBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUF0S0E7QUFDQTtBQXdLQSIsInNvdXJjZVJvb3QiOiIifQ=="); /***/ }), /* 84 */ @@ -1090,7 +1090,7 @@ eval("\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n}); /***/ (function(module, exports, __webpack_require__) { "use strict"; -eval("\n\nvar _rxjs = __webpack_require__(/*! rxjs */ 21);\n\nvar _rxjs2 = _interopRequireDefault(_rxjs);\n\nvar _animation1a = __webpack_require__(/*! ./animation1a */ 73);\n\nvar _animation1a2 = _interopRequireDefault(_animation1a);\n\nvar _animation1b = __webpack_require__(/*! ./animation1b */ 74);\n\nvar _animation1b2 = _interopRequireDefault(_animation1b);\n\nvar _animation2a = __webpack_require__(/*! ./animation2a */ 75);\n\nvar _animation2a2 = _interopRequireDefault(_animation2a);\n\nvar _animation2b = __webpack_require__(/*! ./animation2b */ 76);\n\nvar _animation2b2 = _interopRequireDefault(_animation2b);\n\nvar _animation3a = __webpack_require__(/*! ./animation3a */ 77);\n\nvar _animation3a2 = _interopRequireDefault(_animation3a);\n\nvar _animation3b = __webpack_require__(/*! ./animation3b */ 78);\n\nvar _animation3b2 = _interopRequireDefault(_animation3b);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\n__webpack_require__(/*! ../css/reset.scss */ 82);\n__webpack_require__(/*! ../css/index.scss */ 80);\n__webpack_require__(/*! ../css/particle.scss */ 81);\n__webpack_require__(/*! ../css/controls.scss */ 79);\n\nwindow.addEventListener('load', function () {\n var destroy$ = new _rxjs2.default.BehaviorSubject(null);\n\n (0, _animation1a2.default)(destroy$);\n (0, _animation1b2.default)(destroy$);\n (0, _animation2a2.default)(destroy$);\n (0, _animation2b2.default)(destroy$);\n (0, _animation3a2.default)(destroy$);\n (0, _animation3b2.default)(destroy$);\n});\n\n// TODO remove bottom padding from Disqus\n// TODO fix \"hangup\" small radius evade bug\n// TODO sort out particle nextframe\n// TODO abs positioning on controls elements so order doesn't matter\n// TODO BehaviorSubject listener on bounds change\n// TODO are vision grid nodes removed properly\n// TODO overlapping grid points\n// TODO grid touches\n\n// TODO ANIM1ab free movement\n\n// TODO ANIM3a streamline updateLeader\n// TODO ANIM3b separation\n// TODO ANIM3c alignment//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiODUuanMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vanMvaW5kZXguanM/NDJmNiJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgUngsIHsgT2JzZXJ2YWJsZSB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IEFuaW1hdGlvbjFhIGZyb20gJy4vYW5pbWF0aW9uMWEnO1xuaW1wb3J0IEFuaW1hdGlvbjFiIGZyb20gJy4vYW5pbWF0aW9uMWInO1xuaW1wb3J0IEFuaW1hdGlvbjJhIGZyb20gJy4vYW5pbWF0aW9uMmEnO1xuaW1wb3J0IEFuaW1hdGlvbjJiIGZyb20gJy4vYW5pbWF0aW9uMmInO1xuaW1wb3J0IEFuaW1hdGlvbjNhIGZyb20gJy4vYW5pbWF0aW9uM2EnO1xuaW1wb3J0IEFuaW1hdGlvbjNiIGZyb20gJy4vYW5pbWF0aW9uM2InO1xuXG5yZXF1aXJlKCcuLi9jc3MvcmVzZXQuc2NzcycpO1xucmVxdWlyZSgnLi4vY3NzL2luZGV4LnNjc3MnKTtcbnJlcXVpcmUoJy4uL2Nzcy9wYXJ0aWNsZS5zY3NzJyk7XG5yZXF1aXJlKCcuLi9jc3MvY29udHJvbHMuc2NzcycpO1xuXG53aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcignbG9hZCcsICgpID0+IHtcbiAgICBjb25zdCBkZXN0cm95JCA9IG5ldyBSeC5CZWhhdmlvclN1YmplY3QobnVsbCk7XG5cbiAgICBBbmltYXRpb24xYShkZXN0cm95JCk7XG4gICAgQW5pbWF0aW9uMWIoZGVzdHJveSQpO1xuICAgIEFuaW1hdGlvbjJhKGRlc3Ryb3kkKTtcbiAgICBBbmltYXRpb24yYihkZXN0cm95JCk7XG4gICAgQW5pbWF0aW9uM2EoZGVzdHJveSQpO1xuICAgIEFuaW1hdGlvbjNiKGRlc3Ryb3kkKTtcbn0pO1xuXG4vLyBUT0RPIHJlbW92ZSBib3R0b20gcGFkZGluZyBmcm9tIERpc3F1c1xuLy8gVE9ETyBmaXggXCJoYW5ndXBcIiBzbWFsbCByYWRpdXMgZXZhZGUgYnVnXG4vLyBUT0RPIHNvcnQgb3V0IHBhcnRpY2xlIG5leHRmcmFtZVxuLy8gVE9ETyBhYnMgcG9zaXRpb25pbmcgb24gY29udHJvbHMgZWxlbWVudHMgc28gb3JkZXIgZG9lc24ndCBtYXR0ZXJcbi8vIFRPRE8gQmVoYXZpb3JTdWJqZWN0IGxpc3RlbmVyIG9uIGJvdW5kcyBjaGFuZ2Vcbi8vIFRPRE8gYXJlIHZpc2lvbiBncmlkIG5vZGVzIHJlbW92ZWQgcHJvcGVybHlcbi8vIFRPRE8gb3ZlcmxhcHBpbmcgZ3JpZCBwb2ludHNcbi8vIFRPRE8gZ3JpZCB0b3VjaGVzXG5cbi8vIFRPRE8gQU5JTTFhYiBmcmVlIG1vdmVtZW50XG5cbi8vIFRPRE8gQU5JTTNhIHN0cmVhbWxpbmUgdXBkYXRlTGVhZGVyXG4vLyBUT0RPIEFOSU0zYiBzZXBhcmF0aW9uXG4vLyBUT0RPIEFOSU0zYyBhbGlnbm1lbnRcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyBqcy9pbmRleC5qcyJdLCJtYXBwaW5ncyI6Ijs7QUFBQTtBQUNBOzs7QUFBQTtBQUNBOzs7QUFBQTtBQUNBOzs7QUFBQTtBQUNBOzs7QUFBQTtBQUNBOzs7QUFBQTtBQUNBOzs7QUFBQTtBQUNBOzs7OztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZVJvb3QiOiIifQ=="); +eval("\n\nvar _rxjs = __webpack_require__(/*! rxjs */ 21);\n\nvar _rxjs2 = _interopRequireDefault(_rxjs);\n\nvar _animation1a = __webpack_require__(/*! ./animation1a */ 73);\n\nvar _animation1a2 = _interopRequireDefault(_animation1a);\n\nvar _animation1b = __webpack_require__(/*! ./animation1b */ 74);\n\nvar _animation1b2 = _interopRequireDefault(_animation1b);\n\nvar _animation2a = __webpack_require__(/*! ./animation2a */ 75);\n\nvar _animation2a2 = _interopRequireDefault(_animation2a);\n\nvar _animation2b = __webpack_require__(/*! ./animation2b */ 76);\n\nvar _animation2b2 = _interopRequireDefault(_animation2b);\n\nvar _animation3a = __webpack_require__(/*! ./animation3a */ 77);\n\nvar _animation3a2 = _interopRequireDefault(_animation3a);\n\nvar _animation3b = __webpack_require__(/*! ./animation3b */ 78);\n\nvar _animation3b2 = _interopRequireDefault(_animation3b);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\n__webpack_require__(/*! ../css/reset.scss */ 82);\n__webpack_require__(/*! ../css/index.scss */ 80);\n__webpack_require__(/*! ../css/particle.scss */ 81);\n__webpack_require__(/*! ../css/controls.scss */ 79);\n\nwindow.addEventListener('load', function () {\n var destroy$ = new _rxjs2.default.BehaviorSubject(null);\n\n (0, _animation1a2.default)(destroy$);\n (0, _animation1b2.default)(destroy$);\n (0, _animation2a2.default)(destroy$);\n (0, _animation2b2.default)(destroy$);\n (0, _animation3a2.default)(destroy$);\n (0, _animation3b2.default)(destroy$);\n});\n\n// TODO remove bottom padding from Disqus\n// TODO fix \"hangup\" small radius evade bug\n// TODO sort out particle nextframe\n// TODO abs positioning on controls elements so order doesn't matter\n// TODO BehaviorSubject listener on bounds change\n// TODO are vision grid nodes removed properly\n// TODO grid touches\n// TODO start with n particles doesn't update slider\n// TODO leader not quite right, if 2 particles, sometimes ignored\n\n// TODO ANIM1ab free movement\n\n// TODO ANIM3a streamline updateLeader\n// TODO ANIM3b separation\n// TODO ANIM3c alignment//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiODUuanMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vanMvaW5kZXguanM/NDJmNiJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgUngsIHsgT2JzZXJ2YWJsZSB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IEFuaW1hdGlvbjFhIGZyb20gJy4vYW5pbWF0aW9uMWEnO1xuaW1wb3J0IEFuaW1hdGlvbjFiIGZyb20gJy4vYW5pbWF0aW9uMWInO1xuaW1wb3J0IEFuaW1hdGlvbjJhIGZyb20gJy4vYW5pbWF0aW9uMmEnO1xuaW1wb3J0IEFuaW1hdGlvbjJiIGZyb20gJy4vYW5pbWF0aW9uMmInO1xuaW1wb3J0IEFuaW1hdGlvbjNhIGZyb20gJy4vYW5pbWF0aW9uM2EnO1xuaW1wb3J0IEFuaW1hdGlvbjNiIGZyb20gJy4vYW5pbWF0aW9uM2InO1xuXG5yZXF1aXJlKCcuLi9jc3MvcmVzZXQuc2NzcycpO1xucmVxdWlyZSgnLi4vY3NzL2luZGV4LnNjc3MnKTtcbnJlcXVpcmUoJy4uL2Nzcy9wYXJ0aWNsZS5zY3NzJyk7XG5yZXF1aXJlKCcuLi9jc3MvY29udHJvbHMuc2NzcycpO1xuXG53aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcignbG9hZCcsICgpID0+IHtcbiAgICBjb25zdCBkZXN0cm95JCA9IG5ldyBSeC5CZWhhdmlvclN1YmplY3QobnVsbCk7XG5cbiAgICBBbmltYXRpb24xYShkZXN0cm95JCk7XG4gICAgQW5pbWF0aW9uMWIoZGVzdHJveSQpO1xuICAgIEFuaW1hdGlvbjJhKGRlc3Ryb3kkKTtcbiAgICBBbmltYXRpb24yYihkZXN0cm95JCk7XG4gICAgQW5pbWF0aW9uM2EoZGVzdHJveSQpO1xuICAgIEFuaW1hdGlvbjNiKGRlc3Ryb3kkKTtcbn0pO1xuXG4vLyBUT0RPIHJlbW92ZSBib3R0b20gcGFkZGluZyBmcm9tIERpc3F1c1xuLy8gVE9ETyBmaXggXCJoYW5ndXBcIiBzbWFsbCByYWRpdXMgZXZhZGUgYnVnXG4vLyBUT0RPIHNvcnQgb3V0IHBhcnRpY2xlIG5leHRmcmFtZVxuLy8gVE9ETyBhYnMgcG9zaXRpb25pbmcgb24gY29udHJvbHMgZWxlbWVudHMgc28gb3JkZXIgZG9lc24ndCBtYXR0ZXJcbi8vIFRPRE8gQmVoYXZpb3JTdWJqZWN0IGxpc3RlbmVyIG9uIGJvdW5kcyBjaGFuZ2Vcbi8vIFRPRE8gYXJlIHZpc2lvbiBncmlkIG5vZGVzIHJlbW92ZWQgcHJvcGVybHlcbi8vIFRPRE8gZ3JpZCB0b3VjaGVzXG4vLyBUT0RPIHN0YXJ0IHdpdGggbiBwYXJ0aWNsZXMgZG9lc24ndCB1cGRhdGUgc2xpZGVyXG4vLyBUT0RPIGxlYWRlciBub3QgcXVpdGUgcmlnaHQsIGlmIDIgcGFydGljbGVzLCBzb21ldGltZXMgaWdub3JlZFxuXG4vLyBUT0RPIEFOSU0xYWIgZnJlZSBtb3ZlbWVudFxuXG4vLyBUT0RPIEFOSU0zYSBzdHJlYW1saW5lIHVwZGF0ZUxlYWRlclxuLy8gVE9ETyBBTklNM2Igc2VwYXJhdGlvblxuLy8gVE9ETyBBTklNM2MgYWxpZ25tZW50XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8ganMvaW5kZXguanMiXSwibWFwcGluZ3MiOiI7O0FBQUE7QUFDQTs7O0FBQUE7QUFDQTs7O0FBQUE7QUFDQTs7O0FBQUE7QUFDQTs7O0FBQUE7QUFDQTs7O0FBQUE7QUFDQTs7O0FBQUE7QUFDQTs7Ozs7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZVJvb3QiOiIifQ=="); /***/ }), /* 86 */ @@ -1102,7 +1102,7 @@ eval("\n\nvar _rxjs = __webpack_require__(/*! rxjs */ 21);\n\nvar _rxjs2 = _inte /***/ (function(module, exports, __webpack_require__) { "use strict"; -eval("\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nvar _rxjs = __webpack_require__(/*! rxjs */ 21);\n\nvar _rxjs2 = _interopRequireDefault(_rxjs);\n\nvar _enums = __webpack_require__(/*! ./enums */ 22);\n\nvar _arc = __webpack_require__(/*! ./arc */ 83);\n\nvar _arc2 = _interopRequireDefault(_arc);\n\nvar _random = __webpack_require__(/*! ./random */ 33);\n\nvar _random2 = _interopRequireDefault(_random);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\n// ===== Constructor =====\n\nfunction Particle(parent, bounds, globalGrid, observables) {\n this.config = {\n behavior: _enums.BEHAVIOR.COHESION,\n bounds: bounds,\n color: _random2.default.color(),\n gridSize: 5,\n randomize: true,\n showArc: false,\n showVision: false,\n speed: 4,\n visionRadius: 50\n };\n\n this.grids = {\n global: globalGrid || {},\n vision: createVisionGrid(this.config)\n };\n\n this.id = _random2.default.id(12);\n\n this.nodes = {\n body: createBodyNode(this.config),\n circle: undefined,\n container: createContainerNode(this.config, this.id),\n visionGrid: undefined\n };\n\n this.nodes.container.appendChild(this.nodes.body);\n parent.appendChild(this.nodes.container);\n\n this.leader = null;\n this.isLeader = false;\n\n this.arc = _arc2.default.create(bounds, this.grids.global);\n\n // If starting in a hazard, recurse.\n while (this.grids.global.getPoint({ x: this.arc.endX, y: this.arc.endY, type: _enums.ENTITIES.HAZARD }) !== undefined) {\n this.arc = _arc2.default.create(bounds, this.grids.global);\n }\n\n this.grids.global.setPoint({\n x: this.arc.endX,\n y: this.arc.endY,\n type: _enums.ENTITIES.PARTICLE\n }, this);\n\n this.remove$ = new _rxjs2.default.Subject();\n\n observables.fps$.takeUntil(this.remove$).subscribe(this.subscribeNextFrame.bind(this));\n\n observables.speed$.takeUntil(this.remove$).subscribe(this.subscribeSpeed.bind(this));\n\n observables.randomize$ && observables.randomize$.takeUntil(this.remove$).subscribe(this.subscribeRandomize.bind(this));\n\n observables.circle$ && observables.circle$.takeUntil(this.remove$).subscribe(this.subscribeCircle.bind(this));\n\n observables.vision$ && observables.vision$.takeUntil(this.remove$).subscribe(this.subscribeVision.bind(this));\n};\n\n// ===== PROTOTYPE =====\n\nParticle.prototype.remove = function () {\n this.grids.global.deletePoint({\n x: this.arc.endX,\n y: this.arc.endY,\n type: _enums.ENTITIES.PARTICLE\n });\n\n var parent = this.nodes.container.parentNode;\n parent.removeChild(this.nodes.container);\n this.remove$.next();\n delete this.nodes;\n};\n\nParticle.prototype.subscribeNextFrame = function () {\n this.grids.global.deletePoint({\n x: this.arc.endX,\n y: this.arc.endY,\n type: _enums.ENTITIES.PARTICLE\n });\n\n if (this.nodes === undefined) {\n console.warn('no nodes in', this.id);\n return;\n }\n\n // this.arc = Arc.goto(this.arc, 200, 200, this.config.speed)\n\n this.arc = _arc2.default.step(this.arc, this.config.bounds, this.config.speed);\n\n if (this.leader !== null) {\n this.arc = _arc2.default.follow(this.arc, this.leader.arc);\n } else if (this.arc.length <= 0 && this.config.randomize) {\n this.arc = _arc2.default.randomize(this.arc);\n }\n\n this.grids.vision = updateVisionGrid(this.arc, this.config, this.grids);\n\n var _look = look(this.arc, this.grids),\n hazards = _look.hazards,\n particles = _look.particles;\n\n if (hazards.length > 0) {\n // this.arc = Arc.evade(this.arc);\n }\n\n this.updateLeader(particles);\n\n this.grids.global.setPoint({\n x: this.arc.endX,\n y: this.arc.endY,\n type: _enums.ENTITIES.PARTICLE\n }, this);\n\n repaintContainer(this.nodes.container, this.arc);\n repaintBody(this.nodes.body, this.arc, this.isLeader);\n repaintCircle(this.nodes.circle, this.arc);\n repaintVisionGrid(this.nodes.visionGrid, this.arc, this.grids);\n};\n\nParticle.prototype.subscribeSpeed = function (value) {\n this.config.speed = value;\n};\n\nParticle.prototype.subscribeCircle = function (show) {\n if (show === false) {\n this.nodes.container.removeChild(this.nodes.circle);\n delete this.nodes.circle;\n } else {\n this.nodes.circle = createCircleNode(this.config);\n this.nodes.container.appendChild(this.nodes.circle);\n }\n};\n\nParticle.prototype.subscribeRandomize = function (value) {\n this.config.randomize = value;\n};\n\nParticle.prototype.subscribeVision = function (show) {\n if (show === false) {\n this.nodes.visionGrid.forEach(function (n) {\n return n.parentNode.removeChild(n);\n });\n delete this.nodes.visionGrid;\n } else {\n this.nodes.visionGrid = createVisionGridNodes(this.config, this.grids, this.nodes);\n }\n};\n\nParticle.prototype.updateLeader = function (particles) {\n var _this = this;\n\n if (this.config.behavior !== _enums.BEHAVIOR.COHESION) {\n return;\n }\n\n if (this.leader === null && particles.length > 0) {\n // Head-to-head: particles see eachother but shouldn't both lead.\n var candidates = particles.filter(function (v) {\n return v.leader ? v.leader.id !== _this.id : true;\n });\n\n var leader = candidates.find(function (v) {\n return v.isLeader;\n }) || candidates[0];\n\n if (leader !== undefined) {\n leader.isLeader = true;\n this.leader = leader;\n }\n }\n\n if (this.leader === null) {\n return;\n }\n\n if (this.leader.nodes === undefined) {\n this.leader = null;\n return;\n }\n\n if (this.leader.leader !== null) {\n this.leader = this.leader.leader;\n }\n\n if (this.isLeader) {\n this.isLeader = false;\n }\n\n // Beware of circular leadership, where a leader sees its tail.\n if (this.leader.id === this.id) {\n this.leader = null;\n }\n};\n\nfunction look(arc, grids) {\n var global = grids.global,\n vision = grids.vision;\n\n\n return vision.reduce(function (acc, point) {\n var x = arc.endX + point.x;\n var y = arc.endY + point.y;\n var p = global.getPoint({ x: x, y: y, type: _enums.ENTITIES.PARTICLE });\n\n if (p) {\n acc.particles.push(p);\n }\n\n if (global.getPoint({ x: x, y: y, type: _enums.ENTITIES.HAZARD })) {\n acc.hazards.push({ x: x, y: y });\n }\n\n return acc;\n }, { hazards: [], particles: [] });\n}\n\n// ===== DOM CREATION =====\n\nfunction createBodyNode(config) {\n var node = document.createElement('div');\n node.className = 'particle-body';\n node.style.backgroundColor = config.color;\n return node;\n}\n\nfunction createCircleNode(config) {\n var node = document.createElement('div');\n node.className = 'particle-movement-circle';\n node.style.borderColor = config.color;\n return node;\n}\n\nfunction createContainerNode(config, id) {\n var node = document.createElement('div');\n node.className = 'particle-container';\n node.id = id;\n return node;\n}\n\nfunction createVisionGrid(config) {\n var side = config.gridSize,\n radius = config.visionRadius;\n\n var r0 = radius;\n var r1 = 45;\n\n var points = [];\n\n for (var x = -radius; x <= radius; x += side) {\n for (var y = -radius; y <= radius; y += side) {\n // Omit large slices of unused circle\n if (x > y || x < -y) {\n continue;\n }\n\n // Include vision band\n var r = Math.pow(Math.pow(x, 2) + Math.pow(y, 2), 0.5);\n if (r > r0 || r < r1) {\n continue;\n }\n\n var alpha = Math.atan(y / x);\n if (x < 0) {\n alpha += _enums.RAD.t180;\n }\n\n points.push({ x: x, y: y, r: r, alpha: alpha, touch: false });\n }\n }\n\n return points;\n}\n\nfunction createVisionGridNodes(config, grids, nodes) {\n return grids.vision.reduce(function (acc, _ref) {\n var x = _ref.x,\n y = _ref.y;\n\n var div = document.createElement('div');\n div.className = 'particle-vision-dot';\n div.style.backgroundColor = config.color;\n nodes.container.appendChild(div);\n\n acc.push(div);\n\n return acc;\n }, []);\n}\n\nfunction updateVisionGrid(arc, config, grids) {\n var global = grids.global,\n vision = grids.vision;\n\n\n return vision.reduce(function (acc, point) {\n var rad = arc.clockwise ? point.alpha - arc.theta : point.alpha - arc.theta + _enums.RAD.t180;\n\n point.x = point.r * Math.cos(rad);\n point.y = point.r * Math.sin(rad);\n\n return acc.concat(point);\n }, []);\n}\n\n// ===== DOM RENDERING =====\nfunction repaintContainer(node, arc) {\n node.style.left = arc.endX + 'px';\n node.style.top = arc.endY + 'px';\n}\n\nfunction repaintBody(node, arc, isLeader) {\n var rad = arc.clockwise ? _enums.RAD.t180 - arc.theta : _enums.RAD.t360 - arc.theta;\n\n node.style.transform = 'rotate(' + (rad + _enums.RAD.t45) + 'rad)';\n\n isLeader ? node.style.outline = '1px solid red' : node.style.outline = '';\n}\n\nfunction repaintCircle(node, arc) {\n if (node === undefined) {\n return;\n }\n\n node.style.width = 2 * arc.radius + 'px';\n node.style.height = 2 * arc.radius + 'px';\n\n node.style.left = '-' + (arc.radius + arc.radius * arc.cosTheta) + 'px';\n node.style.top = '-' + (arc.radius - arc.radius * arc.sinTheta) + 'px';\n\n node.style.borderRadius = arc.radius + 'px';\n}\n\nfunction repaintVisionGrid(nodes, arc, grids) {\n if (nodes === undefined) {\n return;\n }\n\n grids.vision.forEach(function (_ref2, i) {\n var x = _ref2.x,\n y = _ref2.y,\n touch = _ref2.touch;\n\n nodes[i].style.left = x + 'px';\n nodes[i].style.top = y + 'px';\n\n nodes[i].style.border = touch ? '2px solid red' : '0';\n });\n}\n\nexports.default = Particle;//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiODYuanMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vanMvcGFydGljbGUuanM/M2JkZSJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgUngsIHsgT2JzZXJ2YWJsZSB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgQkVIQVZJT1IsIEVOVElUSUVTLCBSQUQgfSBmcm9tICcuL2VudW1zJztcbmltcG9ydCBBcmMgZnJvbSAnLi9hcmMnO1xuaW1wb3J0IFJhbmRvbSBmcm9tICcuL3JhbmRvbSc7XG5cbi8vID09PT09IENvbnN0cnVjdG9yID09PT09XG5cbmZ1bmN0aW9uIFBhcnRpY2xlKHBhcmVudCwgYm91bmRzLCBnbG9iYWxHcmlkLCBvYnNlcnZhYmxlcykge1xuICAgIHRoaXMuY29uZmlnID0ge1xuICAgICAgICBiZWhhdmlvcjogQkVIQVZJT1IuQ09IRVNJT04sXG4gICAgICAgIGJvdW5kcyxcbiAgICAgICAgY29sb3I6IFJhbmRvbS5jb2xvcigpLFxuICAgICAgICBncmlkU2l6ZTogNSxcbiAgICAgICAgcmFuZG9taXplOiB0cnVlLFxuICAgICAgICBzaG93QXJjOiBmYWxzZSxcbiAgICAgICAgc2hvd1Zpc2lvbjogZmFsc2UsXG4gICAgICAgIHNwZWVkOiA0LFxuICAgICAgICB2aXNpb25SYWRpdXM6IDUwXG4gICAgfTtcblxuICAgIHRoaXMuZ3JpZHMgPSB7XG4gICAgICAgIGdsb2JhbDogZ2xvYmFsR3JpZCB8fCB7fSxcbiAgICAgICAgdmlzaW9uOiBjcmVhdGVWaXNpb25HcmlkKHRoaXMuY29uZmlnKVxuICAgIH07XG5cbiAgICB0aGlzLmlkID0gUmFuZG9tLmlkKDEyKTtcblxuICAgIHRoaXMubm9kZXMgPSB7XG4gICAgICAgIGJvZHk6IGNyZWF0ZUJvZHlOb2RlKHRoaXMuY29uZmlnKSxcbiAgICAgICAgY2lyY2xlOiB1bmRlZmluZWQsXG4gICAgICAgIGNvbnRhaW5lcjogY3JlYXRlQ29udGFpbmVyTm9kZSh0aGlzLmNvbmZpZywgdGhpcy5pZCksXG4gICAgICAgIHZpc2lvbkdyaWQ6IHVuZGVmaW5lZCxcbiAgICB9O1xuXG4gICAgdGhpcy5ub2Rlcy5jb250YWluZXIuYXBwZW5kQ2hpbGQodGhpcy5ub2Rlcy5ib2R5KTtcbiAgICBwYXJlbnQuYXBwZW5kQ2hpbGQodGhpcy5ub2Rlcy5jb250YWluZXIpO1xuXG4gICAgdGhpcy5sZWFkZXIgPSBudWxsO1xuICAgIHRoaXMuaXNMZWFkZXIgPSBmYWxzZTtcblxuICAgIHRoaXMuYXJjID0gQXJjLmNyZWF0ZShib3VuZHMsIHRoaXMuZ3JpZHMuZ2xvYmFsKTtcblxuICAgIC8vIElmIHN0YXJ0aW5nIGluIGEgaGF6YXJkLCByZWN1cnNlLlxuICAgIHdoaWxlICh0aGlzLmdyaWRzLmdsb2JhbC5nZXRQb2ludCh7IHg6IHRoaXMuYXJjLmVuZFgsIHk6IHRoaXMuYXJjLmVuZFksIHR5cGU6IEVOVElUSUVTLkhBWkFSRH0pICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgdGhpcy5hcmMgPSBBcmMuY3JlYXRlKGJvdW5kcywgdGhpcy5ncmlkcy5nbG9iYWwpO1xuICAgIH1cblxuICAgIHRoaXMuZ3JpZHMuZ2xvYmFsLnNldFBvaW50KHtcbiAgICAgICAgeDogdGhpcy5hcmMuZW5kWCxcbiAgICAgICAgeTogdGhpcy5hcmMuZW5kWSxcbiAgICAgICAgdHlwZTogRU5USVRJRVMuUEFSVElDTEVcbiAgICB9LCB0aGlzKTtcblxuICAgIHRoaXMucmVtb3ZlJCA9IG5ldyBSeC5TdWJqZWN0KCk7XG5cbiAgICBvYnNlcnZhYmxlcy5mcHMkXG4gICAgICAgIC50YWtlVW50aWwodGhpcy5yZW1vdmUkKVxuICAgICAgICAuc3Vic2NyaWJlKHRoaXMuc3Vic2NyaWJlTmV4dEZyYW1lLmJpbmQodGhpcykpO1xuXG4gICAgb2JzZXJ2YWJsZXMuc3BlZWQkXG4gICAgICAgIC50YWtlVW50aWwodGhpcy5yZW1vdmUkKVxuICAgICAgICAuc3Vic2NyaWJlKHRoaXMuc3Vic2NyaWJlU3BlZWQuYmluZCh0aGlzKSk7XG5cbiAgICBvYnNlcnZhYmxlcy5yYW5kb21pemUkICYmIG9ic2VydmFibGVzLnJhbmRvbWl6ZSRcbiAgICAgICAgLnRha2VVbnRpbCh0aGlzLnJlbW92ZSQpXG4gICAgICAgIC5zdWJzY3JpYmUodGhpcy5zdWJzY3JpYmVSYW5kb21pemUuYmluZCh0aGlzKSk7XG5cbiAgICBvYnNlcnZhYmxlcy5jaXJjbGUkICYmIG9ic2VydmFibGVzLmNpcmNsZSRcbiAgICAgICAgLnRha2VVbnRpbCh0aGlzLnJlbW92ZSQpXG4gICAgICAgIC5zdWJzY3JpYmUodGhpcy5zdWJzY3JpYmVDaXJjbGUuYmluZCh0aGlzKSk7XG5cbiAgICBvYnNlcnZhYmxlcy52aXNpb24kICYmIG9ic2VydmFibGVzLnZpc2lvbiRcbiAgICAgICAgLnRha2VVbnRpbCh0aGlzLnJlbW92ZSQpXG4gICAgICAgIC5zdWJzY3JpYmUodGhpcy5zdWJzY3JpYmVWaXNpb24uYmluZCh0aGlzKSk7XG59O1xuXG4vLyA9PT09PSBQUk9UT1RZUEUgPT09PT1cblxuUGFydGljbGUucHJvdG90eXBlLnJlbW92ZSA9IGZ1bmN0aW9uKCkge1xuICAgIHRoaXMuZ3JpZHMuZ2xvYmFsLmRlbGV0ZVBvaW50KHtcbiAgICAgICAgeDogdGhpcy5hcmMuZW5kWCxcbiAgICAgICAgeTogdGhpcy5hcmMuZW5kWSxcbiAgICAgICAgdHlwZTogRU5USVRJRVMuUEFSVElDTEVcbiAgICB9KTtcblxuICAgIGNvbnN0IHBhcmVudCA9IHRoaXMubm9kZXMuY29udGFpbmVyLnBhcmVudE5vZGU7XG4gICAgcGFyZW50LnJlbW92ZUNoaWxkKHRoaXMubm9kZXMuY29udGFpbmVyKTtcbiAgICB0aGlzLnJlbW92ZSQubmV4dCgpO1xuICAgIGRlbGV0ZSB0aGlzLm5vZGVzO1xufVxuXG5QYXJ0aWNsZS5wcm90b3R5cGUuc3Vic2NyaWJlTmV4dEZyYW1lID0gZnVuY3Rpb24oKSB7XG4gICAgdGhpcy5ncmlkcy5nbG9iYWwuZGVsZXRlUG9pbnQoe1xuICAgICAgICB4OiB0aGlzLmFyYy5lbmRYLFxuICAgICAgICB5OiB0aGlzLmFyYy5lbmRZLFxuICAgICAgICB0eXBlOiBFTlRJVElFUy5QQVJUSUNMRVxuICAgIH0pO1xuXG4gICAgaWYgKHRoaXMubm9kZXMgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICBjb25zb2xlLndhcm4oJ25vIG5vZGVzIGluJywgdGhpcy5pZCk7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyB0aGlzLmFyYyA9IEFyYy5nb3RvKHRoaXMuYXJjLCAyMDAsIDIwMCwgdGhpcy5jb25maWcuc3BlZWQpXG5cbiAgICB0aGlzLmFyYyA9IEFyYy5zdGVwKHRoaXMuYXJjLCB0aGlzLmNvbmZpZy5ib3VuZHMsIHRoaXMuY29uZmlnLnNwZWVkKTtcblxuICAgIGlmICh0aGlzLmxlYWRlciAhPT0gbnVsbCkge1xuICAgICAgICB0aGlzLmFyYyA9IEFyYy5mb2xsb3codGhpcy5hcmMsIHRoaXMubGVhZGVyLmFyYyk7XG4gICAgfSBlbHNlIGlmICh0aGlzLmFyYy5sZW5ndGggPD0gMCAmJiB0aGlzLmNvbmZpZy5yYW5kb21pemUpIHtcbiAgICAgICAgdGhpcy5hcmMgPSBBcmMucmFuZG9taXplKHRoaXMuYXJjKTtcbiAgICB9XG5cbiAgICB0aGlzLmdyaWRzLnZpc2lvbiA9IHVwZGF0ZVZpc2lvbkdyaWQodGhpcy5hcmMsIHRoaXMuY29uZmlnLCB0aGlzLmdyaWRzKTtcbiAgICBjb25zdCB7IGhhemFyZHMsIHBhcnRpY2xlcyB9ID0gbG9vayh0aGlzLmFyYywgdGhpcy5ncmlkcyk7XG5cbiAgICBpZiAoaGF6YXJkcy5sZW5ndGggPiAwKSB7XG4gICAgICAgIC8vIHRoaXMuYXJjID0gQXJjLmV2YWRlKHRoaXMuYXJjKTtcbiAgICB9XG5cbiAgICB0aGlzLnVwZGF0ZUxlYWRlcihwYXJ0aWNsZXMpO1xuXG4gICAgdGhpcy5ncmlkcy5nbG9iYWwuc2V0UG9pbnQoe1xuICAgICAgICB4OiB0aGlzLmFyYy5lbmRYLFxuICAgICAgICB5OiB0aGlzLmFyYy5lbmRZLFxuICAgICAgICB0eXBlOiBFTlRJVElFUy5QQVJUSUNMRVxuICAgIH0sIHRoaXMpO1xuXG4gICAgcmVwYWludENvbnRhaW5lcih0aGlzLm5vZGVzLmNvbnRhaW5lciwgdGhpcy5hcmMpO1xuICAgIHJlcGFpbnRCb2R5KHRoaXMubm9kZXMuYm9keSwgdGhpcy5hcmMsIHRoaXMuaXNMZWFkZXIpO1xuICAgIHJlcGFpbnRDaXJjbGUodGhpcy5ub2Rlcy5jaXJjbGUsIHRoaXMuYXJjKTtcbiAgICByZXBhaW50VmlzaW9uR3JpZCh0aGlzLm5vZGVzLnZpc2lvbkdyaWQsIHRoaXMuYXJjLCB0aGlzLmdyaWRzKTtcbn1cblxuUGFydGljbGUucHJvdG90eXBlLnN1YnNjcmliZVNwZWVkID0gZnVuY3Rpb24odmFsdWUpIHtcbiAgICB0aGlzLmNvbmZpZy5zcGVlZCA9IHZhbHVlO1xufVxuXG5cblBhcnRpY2xlLnByb3RvdHlwZS5zdWJzY3JpYmVDaXJjbGUgPSBmdW5jdGlvbihzaG93KSB7XG4gICAgaWYgKHNob3cgPT09IGZhbHNlKSB7XG4gICAgICAgIHRoaXMubm9kZXMuY29udGFpbmVyLnJlbW92ZUNoaWxkKHRoaXMubm9kZXMuY2lyY2xlKTtcbiAgICAgICAgZGVsZXRlIHRoaXMubm9kZXMuY2lyY2xlO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMubm9kZXMuY2lyY2xlID0gY3JlYXRlQ2lyY2xlTm9kZSh0aGlzLmNvbmZpZyk7XG4gICAgICAgIHRoaXMubm9kZXMuY29udGFpbmVyLmFwcGVuZENoaWxkKHRoaXMubm9kZXMuY2lyY2xlKTtcbiAgICB9XG59XG5cblBhcnRpY2xlLnByb3RvdHlwZS5zdWJzY3JpYmVSYW5kb21pemUgPSBmdW5jdGlvbih2YWx1ZSkge1xuICAgIHRoaXMuY29uZmlnLnJhbmRvbWl6ZSA9IHZhbHVlO1xufVxuXG5QYXJ0aWNsZS5wcm90b3R5cGUuc3Vic2NyaWJlVmlzaW9uID0gZnVuY3Rpb24oc2hvdykge1xuICAgIGlmIChzaG93ID09PSBmYWxzZSkge1xuICAgICAgICB0aGlzLm5vZGVzLnZpc2lvbkdyaWQuZm9yRWFjaChuID0+IG4ucGFyZW50Tm9kZS5yZW1vdmVDaGlsZChuKSk7XG4gICAgICAgIGRlbGV0ZSB0aGlzLm5vZGVzLnZpc2lvbkdyaWQ7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5ub2Rlcy52aXNpb25HcmlkID0gY3JlYXRlVmlzaW9uR3JpZE5vZGVzKHRoaXMuY29uZmlnLCB0aGlzLmdyaWRzLCB0aGlzLm5vZGVzKTtcbiAgICB9XG59XG5cblBhcnRpY2xlLnByb3RvdHlwZS51cGRhdGVMZWFkZXIgPSBmdW5jdGlvbihwYXJ0aWNsZXMpIHtcbiAgICBpZiAodGhpcy5jb25maWcuYmVoYXZpb3IgIT09IEJFSEFWSU9SLkNPSEVTSU9OKSB7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5sZWFkZXIgPT09IG51bGwgJiYgcGFydGljbGVzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgLy8gSGVhZC10by1oZWFkOiBwYXJ0aWNsZXMgc2VlIGVhY2hvdGhlciBidXQgc2hvdWxkbid0IGJvdGggbGVhZC5cbiAgICAgICAgY29uc3QgY2FuZGlkYXRlcyA9IHBhcnRpY2xlc1xuICAgICAgICAgICAgLmZpbHRlcih2ID0+IHYubGVhZGVyID8gKHYubGVhZGVyLmlkICE9PSB0aGlzLmlkKSA6IHRydWUpO1xuXG4gICAgICAgIGNvbnN0IGxlYWRlciA9IGNhbmRpZGF0ZXMuZmluZCh2ID0+IHYuaXNMZWFkZXIpIHx8IGNhbmRpZGF0ZXNbMF07XG5cbiAgICAgICAgaWYgKGxlYWRlciAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICBsZWFkZXIuaXNMZWFkZXIgPSB0cnVlO1xuICAgICAgICAgICAgdGhpcy5sZWFkZXIgPSBsZWFkZXI7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAodGhpcy5sZWFkZXIgPT09IG51bGwpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmICh0aGlzLmxlYWRlci5ub2RlcyA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHRoaXMubGVhZGVyID0gbnVsbDtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmICh0aGlzLmxlYWRlci5sZWFkZXIgIT09IG51bGwpIHtcbiAgICAgICAgdGhpcy5sZWFkZXIgPSB0aGlzLmxlYWRlci5sZWFkZXI7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuaXNMZWFkZXIpIHtcbiAgICAgICAgdGhpcy5pc0xlYWRlciA9IGZhbHNlO1xuICAgIH1cblxuICAgIC8vIEJld2FyZSBvZiBjaXJjdWxhciBsZWFkZXJzaGlwLCB3aGVyZSBhIGxlYWRlciBzZWVzIGl0cyB0YWlsLlxuICAgIGlmICh0aGlzLmxlYWRlci5pZCA9PT0gdGhpcy5pZCkge1xuICAgICAgICB0aGlzLmxlYWRlciA9IG51bGw7XG4gICAgfVxufVxuXG5mdW5jdGlvbiBsb29rKGFyYywgZ3JpZHMpIHtcbiAgICBjb25zdCB7IGdsb2JhbCwgdmlzaW9uIH0gPSBncmlkcztcblxuICAgIHJldHVybiB2aXNpb24ucmVkdWNlKChhY2MsIHBvaW50KSA9PiB7XG4gICAgICAgIGNvbnN0IHggPSBhcmMuZW5kWCArIHBvaW50Lng7XG4gICAgICAgIGNvbnN0IHkgPSBhcmMuZW5kWSArIHBvaW50Lnk7XG4gICAgICAgIGNvbnN0IHAgPSBnbG9iYWwuZ2V0UG9pbnQoeyB4LCB5LCB0eXBlOiBFTlRJVElFUy5QQVJUSUNMRSB9KTtcblxuICAgICAgICBpZiAocCkge1xuICAgICAgICAgICAgYWNjLnBhcnRpY2xlcy5wdXNoKHApO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGdsb2JhbC5nZXRQb2ludCh7IHgsIHksIHR5cGU6IEVOVElUSUVTLkhBWkFSRCB9KSkge1xuICAgICAgICAgICAgYWNjLmhhemFyZHMucHVzaCh7IHgsIHkgfSk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gYWNjO1xuICAgIH0sIHsgaGF6YXJkczogW10sIHBhcnRpY2xlczogW10gfSk7XG59XG5cbi8vID09PT09IERPTSBDUkVBVElPTiA9PT09PVxuXG5mdW5jdGlvbiBjcmVhdGVCb2R5Tm9kZShjb25maWcpIHtcbiAgICBjb25zdCBub2RlID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgbm9kZS5jbGFzc05hbWUgPSAncGFydGljbGUtYm9keSc7XG4gICAgbm9kZS5zdHlsZS5iYWNrZ3JvdW5kQ29sb3IgPSBjb25maWcuY29sb3I7XG4gICAgcmV0dXJuIG5vZGU7XG59XG5cbmZ1bmN0aW9uIGNyZWF0ZUNpcmNsZU5vZGUoY29uZmlnKSB7XG4gICAgY29uc3Qgbm9kZSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgIG5vZGUuY2xhc3NOYW1lID0gJ3BhcnRpY2xlLW1vdmVtZW50LWNpcmNsZSc7XG4gICAgbm9kZS5zdHlsZS5ib3JkZXJDb2xvciA9IGNvbmZpZy5jb2xvcjtcbiAgICByZXR1cm4gbm9kZTtcbn1cblxuZnVuY3Rpb24gY3JlYXRlQ29udGFpbmVyTm9kZShjb25maWcsIGlkKSB7XG4gICAgY29uc3Qgbm9kZSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgIG5vZGUuY2xhc3NOYW1lID0gJ3BhcnRpY2xlLWNvbnRhaW5lcic7XG4gICAgbm9kZS5pZCA9IGlkO1xuICAgIHJldHVybiBub2RlO1xufVxuXG5mdW5jdGlvbiBjcmVhdGVWaXNpb25HcmlkKGNvbmZpZykge1xuICAgIGNvbnN0IHsgZ3JpZFNpemU6IHNpZGUsIHZpc2lvblJhZGl1czogcmFkaXVzIH0gPSBjb25maWc7XG4gICAgY29uc3QgcjAgPSByYWRpdXM7XG4gICAgY29uc3QgcjEgPSA0NTtcblxuICAgIGNvbnN0IHBvaW50cyA9IFtdO1xuXG4gICAgZm9yIChsZXQgeCA9IC1yYWRpdXM7IHggPD0gcmFkaXVzOyB4ICs9IHNpZGUpIHtcbiAgICAgICAgZm9yIChsZXQgeSA9IC1yYWRpdXM7IHkgPD0gcmFkaXVzOyB5ICs9IHNpZGUpIHtcbiAgICAgICAgICAgIC8vIE9taXQgbGFyZ2Ugc2xpY2VzIG9mIHVudXNlZCBjaXJjbGVcbiAgICAgICAgICAgIGlmICh4ID4geSB8fCB4IDwgLXkpIHtcbiAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gSW5jbHVkZSB2aXNpb24gYmFuZFxuICAgICAgICAgICAgY29uc3QgciA9IE1hdGgucG93KE1hdGgucG93KHgsIDIpICsgTWF0aC5wb3coeSwgMiksIDAuNSk7XG4gICAgICAgICAgICBpZiAociA+IHIwIHx8IHIgPCByMSkge1xuICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBsZXQgYWxwaGEgPSBNYXRoLmF0YW4oeSAvIHgpO1xuICAgICAgICAgICAgaWYgKHggPCAwKSB7XG4gICAgICAgICAgICAgICAgYWxwaGEgKz0gUkFELnQxODA7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHBvaW50cy5wdXNoKHsgeCwgeSwgciwgYWxwaGEsIHRvdWNoOiBmYWxzZSB9KTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBwb2ludHM7XG59XG5cbmZ1bmN0aW9uIGNyZWF0ZVZpc2lvbkdyaWROb2Rlcyhjb25maWcsIGdyaWRzLCBub2Rlcykge1xuICAgIHJldHVybiBncmlkcy52aXNpb24ucmVkdWNlKChhY2MsIHsgeCwgeSB9KSA9PiB7XG4gICAgICAgIGNvbnN0IGRpdiA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgICAgICBkaXYuY2xhc3NOYW1lID0gJ3BhcnRpY2xlLXZpc2lvbi1kb3QnO1xuICAgICAgICBkaXYuc3R5bGUuYmFja2dyb3VuZENvbG9yID0gY29uZmlnLmNvbG9yO1xuICAgICAgICBub2Rlcy5jb250YWluZXIuYXBwZW5kQ2hpbGQoZGl2KTtcblxuICAgICAgICBhY2MucHVzaChkaXYpO1xuXG4gICAgICAgIHJldHVybiBhY2M7XG4gICAgfSwgW10pO1xufVxuXG5cbmZ1bmN0aW9uIHVwZGF0ZVZpc2lvbkdyaWQoYXJjLCBjb25maWcsIGdyaWRzKSB7XG4gICAgY29uc3QgeyBnbG9iYWwsIHZpc2lvbiB9ID0gZ3JpZHM7XG5cbiAgICByZXR1cm4gdmlzaW9uLnJlZHVjZSgoYWNjLCBwb2ludCkgPT4ge1xuICAgICAgICBjb25zdCByYWQgPSBhcmMuY2xvY2t3aXNlXG4gICAgICAgICAgICA/IHBvaW50LmFscGhhIC0gYXJjLnRoZXRhXG4gICAgICAgICAgICA6IHBvaW50LmFscGhhIC0gYXJjLnRoZXRhICsgUkFELnQxODA7XG5cbiAgICAgICAgcG9pbnQueCA9IHBvaW50LnIgKiBNYXRoLmNvcyhyYWQpO1xuICAgICAgICBwb2ludC55ID0gcG9pbnQuciAqIE1hdGguc2luKHJhZCk7XG5cbiAgICAgICAgcmV0dXJuIGFjYy5jb25jYXQocG9pbnQpO1xuICAgIH0sIFtdKTtcbn1cblxuLy8gPT09PT0gRE9NIFJFTkRFUklORyA9PT09PVxuZnVuY3Rpb24gcmVwYWludENvbnRhaW5lcihub2RlLCBhcmMpIHtcbiAgICBub2RlLnN0eWxlLmxlZnQgPSBgJHthcmMuZW5kWH1weGA7XG4gICAgbm9kZS5zdHlsZS50b3AgPSBgJHthcmMuZW5kWX1weGA7XG59XG5cbmZ1bmN0aW9uIHJlcGFpbnRCb2R5KG5vZGUsIGFyYywgaXNMZWFkZXIpIHtcbiAgICBjb25zdCByYWQgPSBhcmMuY2xvY2t3aXNlXG4gICAgICAgID8gUkFELnQxODAgLSBhcmMudGhldGFcbiAgICAgICAgOiBSQUQudDM2MCAtIGFyYy50aGV0YTtcblxuICAgIG5vZGUuc3R5bGUudHJhbnNmb3JtID0gYHJvdGF0ZSgke3JhZCArIFJBRC50NDV9cmFkKWA7XG5cbiAgICBpc0xlYWRlciA/IG5vZGUuc3R5bGUub3V0bGluZSA9ICcxcHggc29saWQgcmVkJyA6IG5vZGUuc3R5bGUub3V0bGluZSA9ICcnO1xufVxuXG5mdW5jdGlvbiByZXBhaW50Q2lyY2xlKG5vZGUsIGFyYykge1xuICAgIGlmIChub2RlID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIG5vZGUuc3R5bGUud2lkdGggPSBgJHsyICogYXJjLnJhZGl1c31weGA7XG4gICAgbm9kZS5zdHlsZS5oZWlnaHQgPSBgJHsyICogYXJjLnJhZGl1c31weGA7XG5cbiAgICBub2RlLnN0eWxlLmxlZnQgPSBgLSR7YXJjLnJhZGl1cyArIGFyYy5yYWRpdXMgKiBhcmMuY29zVGhldGF9cHhgO1xuICAgIG5vZGUuc3R5bGUudG9wID0gYC0ke2FyYy5yYWRpdXMgLSBhcmMucmFkaXVzICogYXJjLnNpblRoZXRhfXB4YDtcblxuICAgIG5vZGUuc3R5bGUuYm9yZGVyUmFkaXVzID0gYCR7YXJjLnJhZGl1c31weGA7XG59XG5cbmZ1bmN0aW9uIHJlcGFpbnRWaXNpb25HcmlkKG5vZGVzLCBhcmMsIGdyaWRzKSB7XG4gICAgaWYgKG5vZGVzID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGdyaWRzLnZpc2lvbi5mb3JFYWNoKCh7IHgsIHksIHRvdWNoIH0sIGkpID0+IHtcbiAgICAgICAgbm9kZXNbaV0uc3R5bGUubGVmdCA9IGAke3h9cHhgO1xuICAgICAgICBub2Rlc1tpXS5zdHlsZS50b3AgPSBgJHt5fXB4YDtcblxuICAgICAgICBub2Rlc1tpXS5zdHlsZS5ib3JkZXIgPSAodG91Y2ggPyAnMnB4IHNvbGlkIHJlZCcgOiAnMCcpO1xuICAgIH0pO1xufVxuXG5leHBvcnQgZGVmYXVsdCBQYXJ0aWNsZTtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyBqcy9wYXJ0aWNsZS5qcyJdLCJtYXBwaW5ncyI6Ijs7Ozs7O0FBQUE7QUFDQTs7O0FBQUE7QUFDQTtBQUFBO0FBQ0E7OztBQUFBO0FBQ0E7Ozs7O0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFUQTtBQUNBO0FBV0E7QUFDQTtBQUNBO0FBRkE7QUFDQTtBQUlBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBSkE7QUFDQTtBQU1BO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFIQTtBQUNBO0FBS0E7QUFDQTtBQUNBO0FBQ0E7QUFHQTtBQUNBO0FBR0E7QUFDQTtBQUdBO0FBQ0E7QUFHQTtBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUhBO0FBQ0E7QUFLQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBSEE7QUFDQTtBQUtBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUF2QkE7QUFBQTtBQUFBO0FBQ0E7QUF3QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFIQTtBQUNBO0FBS0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwic291cmNlUm9vdCI6IiJ9"); +eval("\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nvar _rxjs = __webpack_require__(/*! rxjs */ 21);\n\nvar _rxjs2 = _interopRequireDefault(_rxjs);\n\nvar _enums = __webpack_require__(/*! ./enums */ 22);\n\nvar _arc = __webpack_require__(/*! ./arc */ 83);\n\nvar _arc2 = _interopRequireDefault(_arc);\n\nvar _random = __webpack_require__(/*! ./random */ 33);\n\nvar _random2 = _interopRequireDefault(_random);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\n// ===== Constructor =====\n\nfunction Particle(parent, bounds, globalGrid, observables) {\n this.config = {\n behavior: _enums.BEHAVIOR.COHESION,\n bounds: bounds,\n color: _random2.default.color(),\n gridSize: 5,\n randomize: true,\n showArc: false,\n showVision: false,\n visionRadius: 50\n };\n\n this.grids = {\n global: globalGrid || {},\n vision: createVisionGrid(this.config)\n };\n\n this.id = _random2.default.id(12);\n\n this.nodes = {\n body: createBodyNode(this.config),\n circle: undefined,\n container: createContainerNode(this.config, this.id),\n visionGrid: undefined\n };\n\n this.nodes.container.appendChild(this.nodes.body);\n parent.appendChild(this.nodes.container);\n\n this.leader = null;\n this.isLeader = false;\n\n this.arc = _arc2.default.create(bounds, this.grids.global);\n this.arc.length = 3;\n\n // If starting in a hazard, recurse.\n while (this.grids.global.getPoint({ x: this.arc.endX, y: this.arc.endY, type: _enums.ENTITIES.HAZARD }) !== undefined) {\n this.arc = _arc2.default.create(bounds, this.grids.global);\n }\n\n this.grids.global.setPoint({\n x: this.arc.endX,\n y: this.arc.endY,\n type: _enums.ENTITIES.PARTICLE\n }, this);\n\n this.remove$ = new _rxjs2.default.Subject();\n\n observables.fps$.takeUntil(this.remove$).subscribe(this.subscribeNextFrame.bind(this));\n\n observables.speed$.takeUntil(this.remove$).subscribe(this.subscribeSpeed.bind(this));\n\n observables.randomize$ && observables.randomize$.takeUntil(this.remove$).subscribe(this.subscribeRandomize.bind(this));\n\n observables.circle$ && observables.circle$.takeUntil(this.remove$).subscribe(this.subscribeCircle.bind(this));\n\n observables.vision$ && observables.vision$.takeUntil(this.remove$).subscribe(this.subscribeVision.bind(this));\n};\n\n// ===== PROTOTYPE =====\n\nParticle.prototype.remove = function () {\n this.grids.global.deletePoint({\n x: this.arc.endX,\n y: this.arc.endY,\n type: _enums.ENTITIES.PARTICLE\n });\n\n var parent = this.nodes.container.parentNode;\n parent.removeChild(this.nodes.container);\n this.remove$.next();\n delete this.nodes;\n};\n\nParticle.prototype.subscribeNextFrame = function () {\n this.grids.global.deletePoint({\n x: this.arc.endX,\n y: this.arc.endY,\n type: _enums.ENTITIES.PARTICLE\n });\n\n if (this.leader !== null) {\n this.arc = _arc2.default.follow(this.arc, this.leader.arc);\n } else if (this.arc.length <= 0 && this.config.randomize) {\n this.arc = _arc2.default.randomize(this.arc);\n }\n\n this.arc = _arc2.default.step(this.arc, this.config.bounds);\n\n this.grids.vision = updateVisionGrid(this.arc, this.config, this.grids);\n\n var _look = look(this.arc, this.grids),\n hazards = _look.hazards,\n particles = _look.particles;\n\n if (hazards.length > 0) {\n // this.arc = Arc.evade(this.arc);\n }\n\n this.updateLeader(particles);\n\n this.grids.global.setPoint({\n x: this.arc.endX,\n y: this.arc.endY,\n type: _enums.ENTITIES.PARTICLE\n }, this);\n\n repaintContainer(this.nodes.container, this.arc);\n repaintBody(this.nodes.body, this.arc, this.isLeader);\n repaintCircle(this.nodes.circle, this.arc);\n repaintVisionGrid(this.nodes.visionGrid, this.arc, this.grids);\n};\n\nParticle.prototype.subscribeSpeed = function (value) {\n _arc2.default.changeSpeed(this.arc, value);\n};\n\nParticle.prototype.subscribeCircle = function (show) {\n if (show === false) {\n this.nodes.container.removeChild(this.nodes.circle);\n delete this.nodes.circle;\n } else {\n this.nodes.circle = createCircleNode(this.config);\n this.nodes.container.appendChild(this.nodes.circle);\n }\n};\n\nParticle.prototype.subscribeRandomize = function (value) {\n this.config.randomize = value;\n};\n\nParticle.prototype.subscribeVision = function (show) {\n if (show === false) {\n this.nodes.visionGrid.forEach(function (n) {\n return n.parentNode.removeChild(n);\n });\n delete this.nodes.visionGrid;\n } else {\n this.nodes.visionGrid = createVisionGridNodes(this.config, this.grids, this.nodes);\n }\n};\n\nParticle.prototype.updateLeader = function (particles) {\n var _this = this;\n\n if (this.config.behavior !== _enums.BEHAVIOR.COHESION) {\n return;\n }\n\n if (this.leader === null && particles.length > 0) {\n // Head-to-head: particles see eachother but shouldn't both lead.\n var candidates = particles.filter(function (v) {\n return v.leader ? v.leader.id !== _this.id : true;\n });\n\n var leader = candidates.find(function (v) {\n return v.isLeader;\n }) || candidates[0];\n\n if (leader !== undefined) {\n leader.isLeader = true;\n this.leader = leader;\n }\n }\n\n if (this.leader === null) {\n return;\n }\n\n if (this.leader.nodes === undefined) {\n this.leader = null;\n return;\n }\n\n if (this.leader.leader !== null) {\n this.leader = this.leader.leader;\n }\n\n if (this.isLeader) {\n this.isLeader = false;\n }\n\n // Beware of circular leadership, where a leader sees its tail.\n if (this.leader.id === this.id) {\n this.leader = null;\n }\n};\n\nfunction look(arc, grids) {\n var global = grids.global,\n vision = grids.vision;\n\n\n return vision.reduce(function (acc, point) {\n var x = arc.endX + point.x;\n var y = arc.endY + point.y;\n var p = global.getPoint({ x: x, y: y, type: _enums.ENTITIES.PARTICLE });\n\n if (p) {\n acc.particles.push(p);\n }\n\n if (global.getPoint({ x: x, y: y, type: _enums.ENTITIES.HAZARD })) {\n acc.hazards.push({ x: x, y: y });\n }\n\n return acc;\n }, { hazards: [], particles: [] });\n}\n\n// ===== DOM CREATION =====\n\nfunction createBodyNode(config) {\n var node = document.createElement('div');\n node.className = 'particle-body';\n node.style.backgroundColor = config.color;\n return node;\n}\n\nfunction createCircleNode(config) {\n var node = document.createElement('div');\n node.className = 'particle-movement-circle';\n node.style.borderColor = config.color;\n return node;\n}\n\nfunction createContainerNode(config, id) {\n var node = document.createElement('div');\n node.className = 'particle-container';\n node.id = id;\n return node;\n}\n\nfunction createVisionGrid(config) {\n var side = config.gridSize,\n radius = config.visionRadius;\n\n var r0 = radius;\n var r1 = 45;\n\n var points = [];\n\n for (var x = -radius; x <= radius; x += side) {\n for (var y = -radius; y <= radius; y += side) {\n // Omit large slices of unused circle\n if (x > y || x < -y) {\n continue;\n }\n\n // Include vision band\n var r = Math.pow(Math.pow(x, 2) + Math.pow(y, 2), 0.5);\n if (r > r0 || r < r1) {\n continue;\n }\n\n var alpha = Math.atan(y / x);\n if (x < 0) {\n alpha += _enums.RAD.t180;\n }\n\n points.push({ x: x, y: y, r: r, alpha: alpha, touch: false });\n }\n }\n\n return points;\n}\n\nfunction createVisionGridNodes(config, grids, nodes) {\n return grids.vision.reduce(function (acc, _ref) {\n var x = _ref.x,\n y = _ref.y;\n\n var div = document.createElement('div');\n div.className = 'particle-vision-dot';\n div.style.backgroundColor = config.color;\n nodes.container.appendChild(div);\n\n acc.push(div);\n\n return acc;\n }, []);\n}\n\nfunction updateVisionGrid(arc, config, grids) {\n var global = grids.global,\n vision = grids.vision;\n\n\n return vision.reduce(function (acc, point) {\n var rad = arc.clockwise ? point.alpha - arc.theta : point.alpha - arc.theta + _enums.RAD.t180;\n\n point.x = point.r * Math.cos(rad);\n point.y = point.r * Math.sin(rad);\n\n return acc.concat(point);\n }, []);\n}\n\n// ===== DOM RENDERING =====\nfunction repaintContainer(node, arc) {\n node.style.left = arc.endX + 'px';\n node.style.top = arc.endY + 'px';\n}\n\nfunction repaintBody(node, arc, isLeader) {\n var rad = arc.clockwise ? _enums.RAD.t180 - arc.theta : _enums.RAD.t360 - arc.theta;\n\n node.style.transform = 'rotate(' + (rad + _enums.RAD.t45) + 'rad)';\n\n isLeader ? node.style.outline = '1px solid red' : node.style.outline = '';\n}\n\nfunction repaintCircle(node, arc) {\n if (node === undefined) {\n return;\n }\n\n node.style.width = 2 * arc.radius + 'px';\n node.style.height = 2 * arc.radius + 'px';\n\n node.style.left = '-' + (arc.radius + arc.radius * arc.cosTheta) + 'px';\n node.style.top = '-' + (arc.radius - arc.radius * arc.sinTheta) + 'px';\n\n node.style.borderRadius = arc.radius + 'px';\n}\n\nfunction repaintVisionGrid(nodes, arc, grids) {\n if (nodes === undefined) {\n return;\n }\n\n grids.vision.forEach(function (_ref2, i) {\n var x = _ref2.x,\n y = _ref2.y,\n touch = _ref2.touch;\n\n nodes[i].style.left = x + 'px';\n nodes[i].style.top = y + 'px';\n\n nodes[i].style.border = touch ? '2px solid red' : '0';\n });\n}\n\nexports.default = Particle;//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiODYuanMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vanMvcGFydGljbGUuanM/M2JkZSJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgUngsIHsgT2JzZXJ2YWJsZSB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgQkVIQVZJT1IsIEVOVElUSUVTLCBSQUQgfSBmcm9tICcuL2VudW1zJztcbmltcG9ydCBBcmMgZnJvbSAnLi9hcmMnO1xuaW1wb3J0IFJhbmRvbSBmcm9tICcuL3JhbmRvbSc7XG5cbi8vID09PT09IENvbnN0cnVjdG9yID09PT09XG5cbmZ1bmN0aW9uIFBhcnRpY2xlKHBhcmVudCwgYm91bmRzLCBnbG9iYWxHcmlkLCBvYnNlcnZhYmxlcykge1xuICAgIHRoaXMuY29uZmlnID0ge1xuICAgICAgICBiZWhhdmlvcjogQkVIQVZJT1IuQ09IRVNJT04sXG4gICAgICAgIGJvdW5kcyxcbiAgICAgICAgY29sb3I6IFJhbmRvbS5jb2xvcigpLFxuICAgICAgICBncmlkU2l6ZTogNSxcbiAgICAgICAgcmFuZG9taXplOiB0cnVlLFxuICAgICAgICBzaG93QXJjOiBmYWxzZSxcbiAgICAgICAgc2hvd1Zpc2lvbjogZmFsc2UsXG4gICAgICAgIHZpc2lvblJhZGl1czogNTBcbiAgICB9O1xuXG4gICAgdGhpcy5ncmlkcyA9IHtcbiAgICAgICAgZ2xvYmFsOiBnbG9iYWxHcmlkIHx8IHt9LFxuICAgICAgICB2aXNpb246IGNyZWF0ZVZpc2lvbkdyaWQodGhpcy5jb25maWcpXG4gICAgfTtcblxuICAgIHRoaXMuaWQgPSBSYW5kb20uaWQoMTIpO1xuXG4gICAgdGhpcy5ub2RlcyA9IHtcbiAgICAgICAgYm9keTogY3JlYXRlQm9keU5vZGUodGhpcy5jb25maWcpLFxuICAgICAgICBjaXJjbGU6IHVuZGVmaW5lZCxcbiAgICAgICAgY29udGFpbmVyOiBjcmVhdGVDb250YWluZXJOb2RlKHRoaXMuY29uZmlnLCB0aGlzLmlkKSxcbiAgICAgICAgdmlzaW9uR3JpZDogdW5kZWZpbmVkLFxuICAgIH07XG5cbiAgICB0aGlzLm5vZGVzLmNvbnRhaW5lci5hcHBlbmRDaGlsZCh0aGlzLm5vZGVzLmJvZHkpO1xuICAgIHBhcmVudC5hcHBlbmRDaGlsZCh0aGlzLm5vZGVzLmNvbnRhaW5lcik7XG5cbiAgICB0aGlzLmxlYWRlciA9IG51bGw7XG4gICAgdGhpcy5pc0xlYWRlciA9IGZhbHNlO1xuXG4gICAgdGhpcy5hcmMgPSBBcmMuY3JlYXRlKGJvdW5kcywgdGhpcy5ncmlkcy5nbG9iYWwpO1xuICAgIHRoaXMuYXJjLmxlbmd0aCA9IDM7XG5cbiAgICAvLyBJZiBzdGFydGluZyBpbiBhIGhhemFyZCwgcmVjdXJzZS5cbiAgICB3aGlsZSAodGhpcy5ncmlkcy5nbG9iYWwuZ2V0UG9pbnQoeyB4OiB0aGlzLmFyYy5lbmRYLCB5OiB0aGlzLmFyYy5lbmRZLCB0eXBlOiBFTlRJVElFUy5IQVpBUkR9KSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHRoaXMuYXJjID0gQXJjLmNyZWF0ZShib3VuZHMsIHRoaXMuZ3JpZHMuZ2xvYmFsKTtcbiAgICB9XG5cbiAgICB0aGlzLmdyaWRzLmdsb2JhbC5zZXRQb2ludCh7XG4gICAgICAgIHg6IHRoaXMuYXJjLmVuZFgsXG4gICAgICAgIHk6IHRoaXMuYXJjLmVuZFksXG4gICAgICAgIHR5cGU6IEVOVElUSUVTLlBBUlRJQ0xFXG4gICAgfSwgdGhpcyk7XG5cbiAgICB0aGlzLnJlbW92ZSQgPSBuZXcgUnguU3ViamVjdCgpO1xuXG4gICAgb2JzZXJ2YWJsZXMuZnBzJFxuICAgICAgICAudGFrZVVudGlsKHRoaXMucmVtb3ZlJClcbiAgICAgICAgLnN1YnNjcmliZSh0aGlzLnN1YnNjcmliZU5leHRGcmFtZS5iaW5kKHRoaXMpKTtcblxuICAgIG9ic2VydmFibGVzLnNwZWVkJFxuICAgICAgICAudGFrZVVudGlsKHRoaXMucmVtb3ZlJClcbiAgICAgICAgLnN1YnNjcmliZSh0aGlzLnN1YnNjcmliZVNwZWVkLmJpbmQodGhpcykpO1xuXG4gICAgb2JzZXJ2YWJsZXMucmFuZG9taXplJCAmJiBvYnNlcnZhYmxlcy5yYW5kb21pemUkXG4gICAgICAgIC50YWtlVW50aWwodGhpcy5yZW1vdmUkKVxuICAgICAgICAuc3Vic2NyaWJlKHRoaXMuc3Vic2NyaWJlUmFuZG9taXplLmJpbmQodGhpcykpO1xuXG4gICAgb2JzZXJ2YWJsZXMuY2lyY2xlJCAmJiBvYnNlcnZhYmxlcy5jaXJjbGUkXG4gICAgICAgIC50YWtlVW50aWwodGhpcy5yZW1vdmUkKVxuICAgICAgICAuc3Vic2NyaWJlKHRoaXMuc3Vic2NyaWJlQ2lyY2xlLmJpbmQodGhpcykpO1xuXG4gICAgb2JzZXJ2YWJsZXMudmlzaW9uJCAmJiBvYnNlcnZhYmxlcy52aXNpb24kXG4gICAgICAgIC50YWtlVW50aWwodGhpcy5yZW1vdmUkKVxuICAgICAgICAuc3Vic2NyaWJlKHRoaXMuc3Vic2NyaWJlVmlzaW9uLmJpbmQodGhpcykpO1xufTtcblxuLy8gPT09PT0gUFJPVE9UWVBFID09PT09XG5cblBhcnRpY2xlLnByb3RvdHlwZS5yZW1vdmUgPSBmdW5jdGlvbigpIHtcbiAgICB0aGlzLmdyaWRzLmdsb2JhbC5kZWxldGVQb2ludCh7XG4gICAgICAgIHg6IHRoaXMuYXJjLmVuZFgsXG4gICAgICAgIHk6IHRoaXMuYXJjLmVuZFksXG4gICAgICAgIHR5cGU6IEVOVElUSUVTLlBBUlRJQ0xFXG4gICAgfSk7XG5cbiAgICBjb25zdCBwYXJlbnQgPSB0aGlzLm5vZGVzLmNvbnRhaW5lci5wYXJlbnROb2RlO1xuICAgIHBhcmVudC5yZW1vdmVDaGlsZCh0aGlzLm5vZGVzLmNvbnRhaW5lcik7XG4gICAgdGhpcy5yZW1vdmUkLm5leHQoKTtcbiAgICBkZWxldGUgdGhpcy5ub2Rlcztcbn1cblxuUGFydGljbGUucHJvdG90eXBlLnN1YnNjcmliZU5leHRGcmFtZSA9IGZ1bmN0aW9uKCkge1xuICAgIHRoaXMuZ3JpZHMuZ2xvYmFsLmRlbGV0ZVBvaW50KHtcbiAgICAgICAgeDogdGhpcy5hcmMuZW5kWCxcbiAgICAgICAgeTogdGhpcy5hcmMuZW5kWSxcbiAgICAgICAgdHlwZTogRU5USVRJRVMuUEFSVElDTEVcbiAgICB9KTtcblxuICAgIGlmICh0aGlzLmxlYWRlciAhPT0gbnVsbCkge1xuICAgICAgICB0aGlzLmFyYyA9IEFyYy5mb2xsb3codGhpcy5hcmMsIHRoaXMubGVhZGVyLmFyYyk7XG4gICAgfSBlbHNlIGlmICh0aGlzLmFyYy5sZW5ndGggPD0gMCAmJiB0aGlzLmNvbmZpZy5yYW5kb21pemUpIHtcbiAgICAgICAgdGhpcy5hcmMgPSBBcmMucmFuZG9taXplKHRoaXMuYXJjKTtcbiAgICB9XG5cbiAgICB0aGlzLmFyYyA9IEFyYy5zdGVwKHRoaXMuYXJjLCB0aGlzLmNvbmZpZy5ib3VuZHMpO1xuXG4gICAgdGhpcy5ncmlkcy52aXNpb24gPSB1cGRhdGVWaXNpb25HcmlkKHRoaXMuYXJjLCB0aGlzLmNvbmZpZywgdGhpcy5ncmlkcyk7XG4gICAgY29uc3QgeyBoYXphcmRzLCBwYXJ0aWNsZXMgfSA9IGxvb2sodGhpcy5hcmMsIHRoaXMuZ3JpZHMpO1xuXG4gICAgaWYgKGhhemFyZHMubGVuZ3RoID4gMCkge1xuICAgICAgICAvLyB0aGlzLmFyYyA9IEFyYy5ldmFkZSh0aGlzLmFyYyk7XG4gICAgfVxuXG4gICAgdGhpcy51cGRhdGVMZWFkZXIocGFydGljbGVzKTtcblxuICAgIHRoaXMuZ3JpZHMuZ2xvYmFsLnNldFBvaW50KHtcbiAgICAgICAgeDogdGhpcy5hcmMuZW5kWCxcbiAgICAgICAgeTogdGhpcy5hcmMuZW5kWSxcbiAgICAgICAgdHlwZTogRU5USVRJRVMuUEFSVElDTEVcbiAgICB9LCB0aGlzKTtcblxuICAgIHJlcGFpbnRDb250YWluZXIodGhpcy5ub2Rlcy5jb250YWluZXIsIHRoaXMuYXJjKTtcbiAgICByZXBhaW50Qm9keSh0aGlzLm5vZGVzLmJvZHksIHRoaXMuYXJjLCB0aGlzLmlzTGVhZGVyKTtcbiAgICByZXBhaW50Q2lyY2xlKHRoaXMubm9kZXMuY2lyY2xlLCB0aGlzLmFyYyk7XG4gICAgcmVwYWludFZpc2lvbkdyaWQodGhpcy5ub2Rlcy52aXNpb25HcmlkLCB0aGlzLmFyYywgdGhpcy5ncmlkcyk7XG59XG5cblBhcnRpY2xlLnByb3RvdHlwZS5zdWJzY3JpYmVTcGVlZCA9IGZ1bmN0aW9uKHZhbHVlKSB7XG4gICAgQXJjLmNoYW5nZVNwZWVkKHRoaXMuYXJjLCB2YWx1ZSk7XG59XG5cblBhcnRpY2xlLnByb3RvdHlwZS5zdWJzY3JpYmVDaXJjbGUgPSBmdW5jdGlvbihzaG93KSB7XG4gICAgaWYgKHNob3cgPT09IGZhbHNlKSB7XG4gICAgICAgIHRoaXMubm9kZXMuY29udGFpbmVyLnJlbW92ZUNoaWxkKHRoaXMubm9kZXMuY2lyY2xlKTtcbiAgICAgICAgZGVsZXRlIHRoaXMubm9kZXMuY2lyY2xlO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMubm9kZXMuY2lyY2xlID0gY3JlYXRlQ2lyY2xlTm9kZSh0aGlzLmNvbmZpZyk7XG4gICAgICAgIHRoaXMubm9kZXMuY29udGFpbmVyLmFwcGVuZENoaWxkKHRoaXMubm9kZXMuY2lyY2xlKTtcbiAgICB9XG59XG5cblBhcnRpY2xlLnByb3RvdHlwZS5zdWJzY3JpYmVSYW5kb21pemUgPSBmdW5jdGlvbih2YWx1ZSkge1xuICAgIHRoaXMuY29uZmlnLnJhbmRvbWl6ZSA9IHZhbHVlO1xufVxuXG5QYXJ0aWNsZS5wcm90b3R5cGUuc3Vic2NyaWJlVmlzaW9uID0gZnVuY3Rpb24oc2hvdykge1xuICAgIGlmIChzaG93ID09PSBmYWxzZSkge1xuICAgICAgICB0aGlzLm5vZGVzLnZpc2lvbkdyaWQuZm9yRWFjaChuID0+IG4ucGFyZW50Tm9kZS5yZW1vdmVDaGlsZChuKSk7XG4gICAgICAgIGRlbGV0ZSB0aGlzLm5vZGVzLnZpc2lvbkdyaWQ7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5ub2Rlcy52aXNpb25HcmlkID0gY3JlYXRlVmlzaW9uR3JpZE5vZGVzKHRoaXMuY29uZmlnLCB0aGlzLmdyaWRzLCB0aGlzLm5vZGVzKTtcbiAgICB9XG59XG5cblBhcnRpY2xlLnByb3RvdHlwZS51cGRhdGVMZWFkZXIgPSBmdW5jdGlvbihwYXJ0aWNsZXMpIHtcbiAgICBpZiAodGhpcy5jb25maWcuYmVoYXZpb3IgIT09IEJFSEFWSU9SLkNPSEVTSU9OKSB7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5sZWFkZXIgPT09IG51bGwgJiYgcGFydGljbGVzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgLy8gSGVhZC10by1oZWFkOiBwYXJ0aWNsZXMgc2VlIGVhY2hvdGhlciBidXQgc2hvdWxkbid0IGJvdGggbGVhZC5cbiAgICAgICAgY29uc3QgY2FuZGlkYXRlcyA9IHBhcnRpY2xlc1xuICAgICAgICAgICAgLmZpbHRlcih2ID0+IHYubGVhZGVyID8gKHYubGVhZGVyLmlkICE9PSB0aGlzLmlkKSA6IHRydWUpO1xuXG4gICAgICAgIGNvbnN0IGxlYWRlciA9IGNhbmRpZGF0ZXMuZmluZCh2ID0+IHYuaXNMZWFkZXIpIHx8IGNhbmRpZGF0ZXNbMF07XG5cbiAgICAgICAgaWYgKGxlYWRlciAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICBsZWFkZXIuaXNMZWFkZXIgPSB0cnVlO1xuICAgICAgICAgICAgdGhpcy5sZWFkZXIgPSBsZWFkZXI7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAodGhpcy5sZWFkZXIgPT09IG51bGwpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmICh0aGlzLmxlYWRlci5ub2RlcyA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHRoaXMubGVhZGVyID0gbnVsbDtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmICh0aGlzLmxlYWRlci5sZWFkZXIgIT09IG51bGwpIHtcbiAgICAgICAgdGhpcy5sZWFkZXIgPSB0aGlzLmxlYWRlci5sZWFkZXI7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuaXNMZWFkZXIpIHtcbiAgICAgICAgdGhpcy5pc0xlYWRlciA9IGZhbHNlO1xuICAgIH1cblxuICAgIC8vIEJld2FyZSBvZiBjaXJjdWxhciBsZWFkZXJzaGlwLCB3aGVyZSBhIGxlYWRlciBzZWVzIGl0cyB0YWlsLlxuICAgIGlmICh0aGlzLmxlYWRlci5pZCA9PT0gdGhpcy5pZCkge1xuICAgICAgICB0aGlzLmxlYWRlciA9IG51bGw7XG4gICAgfVxufVxuXG5mdW5jdGlvbiBsb29rKGFyYywgZ3JpZHMpIHtcbiAgICBjb25zdCB7IGdsb2JhbCwgdmlzaW9uIH0gPSBncmlkcztcblxuICAgIHJldHVybiB2aXNpb24ucmVkdWNlKChhY2MsIHBvaW50KSA9PiB7XG4gICAgICAgIGNvbnN0IHggPSBhcmMuZW5kWCArIHBvaW50Lng7XG4gICAgICAgIGNvbnN0IHkgPSBhcmMuZW5kWSArIHBvaW50Lnk7XG4gICAgICAgIGNvbnN0IHAgPSBnbG9iYWwuZ2V0UG9pbnQoeyB4LCB5LCB0eXBlOiBFTlRJVElFUy5QQVJUSUNMRSB9KTtcblxuICAgICAgICBpZiAocCkge1xuICAgICAgICAgICAgYWNjLnBhcnRpY2xlcy5wdXNoKHApO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGdsb2JhbC5nZXRQb2ludCh7IHgsIHksIHR5cGU6IEVOVElUSUVTLkhBWkFSRCB9KSkge1xuICAgICAgICAgICAgYWNjLmhhemFyZHMucHVzaCh7IHgsIHkgfSk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gYWNjO1xuICAgIH0sIHsgaGF6YXJkczogW10sIHBhcnRpY2xlczogW10gfSk7XG59XG5cbi8vID09PT09IERPTSBDUkVBVElPTiA9PT09PVxuXG5mdW5jdGlvbiBjcmVhdGVCb2R5Tm9kZShjb25maWcpIHtcbiAgICBjb25zdCBub2RlID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgbm9kZS5jbGFzc05hbWUgPSAncGFydGljbGUtYm9keSc7XG4gICAgbm9kZS5zdHlsZS5iYWNrZ3JvdW5kQ29sb3IgPSBjb25maWcuY29sb3I7XG4gICAgcmV0dXJuIG5vZGU7XG59XG5cbmZ1bmN0aW9uIGNyZWF0ZUNpcmNsZU5vZGUoY29uZmlnKSB7XG4gICAgY29uc3Qgbm9kZSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgIG5vZGUuY2xhc3NOYW1lID0gJ3BhcnRpY2xlLW1vdmVtZW50LWNpcmNsZSc7XG4gICAgbm9kZS5zdHlsZS5ib3JkZXJDb2xvciA9IGNvbmZpZy5jb2xvcjtcbiAgICByZXR1cm4gbm9kZTtcbn1cblxuZnVuY3Rpb24gY3JlYXRlQ29udGFpbmVyTm9kZShjb25maWcsIGlkKSB7XG4gICAgY29uc3Qgbm9kZSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgIG5vZGUuY2xhc3NOYW1lID0gJ3BhcnRpY2xlLWNvbnRhaW5lcic7XG4gICAgbm9kZS5pZCA9IGlkO1xuICAgIHJldHVybiBub2RlO1xufVxuXG5mdW5jdGlvbiBjcmVhdGVWaXNpb25HcmlkKGNvbmZpZykge1xuICAgIGNvbnN0IHsgZ3JpZFNpemU6IHNpZGUsIHZpc2lvblJhZGl1czogcmFkaXVzIH0gPSBjb25maWc7XG4gICAgY29uc3QgcjAgPSByYWRpdXM7XG4gICAgY29uc3QgcjEgPSA0NTtcblxuICAgIGNvbnN0IHBvaW50cyA9IFtdO1xuXG4gICAgZm9yIChsZXQgeCA9IC1yYWRpdXM7IHggPD0gcmFkaXVzOyB4ICs9IHNpZGUpIHtcbiAgICAgICAgZm9yIChsZXQgeSA9IC1yYWRpdXM7IHkgPD0gcmFkaXVzOyB5ICs9IHNpZGUpIHtcbiAgICAgICAgICAgIC8vIE9taXQgbGFyZ2Ugc2xpY2VzIG9mIHVudXNlZCBjaXJjbGVcbiAgICAgICAgICAgIGlmICh4ID4geSB8fCB4IDwgLXkpIHtcbiAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gSW5jbHVkZSB2aXNpb24gYmFuZFxuICAgICAgICAgICAgY29uc3QgciA9IE1hdGgucG93KE1hdGgucG93KHgsIDIpICsgTWF0aC5wb3coeSwgMiksIDAuNSk7XG4gICAgICAgICAgICBpZiAociA+IHIwIHx8IHIgPCByMSkge1xuICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBsZXQgYWxwaGEgPSBNYXRoLmF0YW4oeSAvIHgpO1xuICAgICAgICAgICAgaWYgKHggPCAwKSB7XG4gICAgICAgICAgICAgICAgYWxwaGEgKz0gUkFELnQxODA7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHBvaW50cy5wdXNoKHsgeCwgeSwgciwgYWxwaGEsIHRvdWNoOiBmYWxzZSB9KTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBwb2ludHM7XG59XG5cbmZ1bmN0aW9uIGNyZWF0ZVZpc2lvbkdyaWROb2Rlcyhjb25maWcsIGdyaWRzLCBub2Rlcykge1xuICAgIHJldHVybiBncmlkcy52aXNpb24ucmVkdWNlKChhY2MsIHsgeCwgeSB9KSA9PiB7XG4gICAgICAgIGNvbnN0IGRpdiA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgICAgICBkaXYuY2xhc3NOYW1lID0gJ3BhcnRpY2xlLXZpc2lvbi1kb3QnO1xuICAgICAgICBkaXYuc3R5bGUuYmFja2dyb3VuZENvbG9yID0gY29uZmlnLmNvbG9yO1xuICAgICAgICBub2Rlcy5jb250YWluZXIuYXBwZW5kQ2hpbGQoZGl2KTtcblxuICAgICAgICBhY2MucHVzaChkaXYpO1xuXG4gICAgICAgIHJldHVybiBhY2M7XG4gICAgfSwgW10pO1xufVxuXG5cbmZ1bmN0aW9uIHVwZGF0ZVZpc2lvbkdyaWQoYXJjLCBjb25maWcsIGdyaWRzKSB7XG4gICAgY29uc3QgeyBnbG9iYWwsIHZpc2lvbiB9ID0gZ3JpZHM7XG5cbiAgICByZXR1cm4gdmlzaW9uLnJlZHVjZSgoYWNjLCBwb2ludCkgPT4ge1xuICAgICAgICBjb25zdCByYWQgPSBhcmMuY2xvY2t3aXNlXG4gICAgICAgICAgICA/IHBvaW50LmFscGhhIC0gYXJjLnRoZXRhXG4gICAgICAgICAgICA6IHBvaW50LmFscGhhIC0gYXJjLnRoZXRhICsgUkFELnQxODA7XG5cbiAgICAgICAgcG9pbnQueCA9IHBvaW50LnIgKiBNYXRoLmNvcyhyYWQpO1xuICAgICAgICBwb2ludC55ID0gcG9pbnQuciAqIE1hdGguc2luKHJhZCk7XG5cbiAgICAgICAgcmV0dXJuIGFjYy5jb25jYXQocG9pbnQpO1xuICAgIH0sIFtdKTtcbn1cblxuLy8gPT09PT0gRE9NIFJFTkRFUklORyA9PT09PVxuZnVuY3Rpb24gcmVwYWludENvbnRhaW5lcihub2RlLCBhcmMpIHtcbiAgICBub2RlLnN0eWxlLmxlZnQgPSBgJHthcmMuZW5kWH1weGA7XG4gICAgbm9kZS5zdHlsZS50b3AgPSBgJHthcmMuZW5kWX1weGA7XG59XG5cbmZ1bmN0aW9uIHJlcGFpbnRCb2R5KG5vZGUsIGFyYywgaXNMZWFkZXIpIHtcbiAgICBjb25zdCByYWQgPSBhcmMuY2xvY2t3aXNlXG4gICAgICAgID8gUkFELnQxODAgLSBhcmMudGhldGFcbiAgICAgICAgOiBSQUQudDM2MCAtIGFyYy50aGV0YTtcblxuICAgIG5vZGUuc3R5bGUudHJhbnNmb3JtID0gYHJvdGF0ZSgke3JhZCArIFJBRC50NDV9cmFkKWA7XG5cbiAgICBpc0xlYWRlciA/IG5vZGUuc3R5bGUub3V0bGluZSA9ICcxcHggc29saWQgcmVkJyA6IG5vZGUuc3R5bGUub3V0bGluZSA9ICcnO1xufVxuXG5mdW5jdGlvbiByZXBhaW50Q2lyY2xlKG5vZGUsIGFyYykge1xuICAgIGlmIChub2RlID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIG5vZGUuc3R5bGUud2lkdGggPSBgJHsyICogYXJjLnJhZGl1c31weGA7XG4gICAgbm9kZS5zdHlsZS5oZWlnaHQgPSBgJHsyICogYXJjLnJhZGl1c31weGA7XG5cbiAgICBub2RlLnN0eWxlLmxlZnQgPSBgLSR7YXJjLnJhZGl1cyArIGFyYy5yYWRpdXMgKiBhcmMuY29zVGhldGF9cHhgO1xuICAgIG5vZGUuc3R5bGUudG9wID0gYC0ke2FyYy5yYWRpdXMgLSBhcmMucmFkaXVzICogYXJjLnNpblRoZXRhfXB4YDtcblxuICAgIG5vZGUuc3R5bGUuYm9yZGVyUmFkaXVzID0gYCR7YXJjLnJhZGl1c31weGA7XG59XG5cbmZ1bmN0aW9uIHJlcGFpbnRWaXNpb25HcmlkKG5vZGVzLCBhcmMsIGdyaWRzKSB7XG4gICAgaWYgKG5vZGVzID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGdyaWRzLnZpc2lvbi5mb3JFYWNoKCh7IHgsIHksIHRvdWNoIH0sIGkpID0+IHtcbiAgICAgICAgbm9kZXNbaV0uc3R5bGUubGVmdCA9IGAke3h9cHhgO1xuICAgICAgICBub2Rlc1tpXS5zdHlsZS50b3AgPSBgJHt5fXB4YDtcblxuICAgICAgICBub2Rlc1tpXS5zdHlsZS5ib3JkZXIgPSAodG91Y2ggPyAnMnB4IHNvbGlkIHJlZCcgOiAnMCcpO1xuICAgIH0pO1xufVxuXG5leHBvcnQgZGVmYXVsdCBQYXJ0aWNsZTtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyBqcy9wYXJ0aWNsZS5qcyJdLCJtYXBwaW5ncyI6Ijs7Ozs7O0FBQUE7QUFDQTs7O0FBQUE7QUFDQTtBQUFBO0FBQ0E7OztBQUFBO0FBQ0E7Ozs7O0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBUkE7QUFDQTtBQVVBO0FBQ0E7QUFDQTtBQUZBO0FBQ0E7QUFJQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUpBO0FBQ0E7QUFNQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFIQTtBQUNBO0FBS0E7QUFDQTtBQUNBO0FBQ0E7QUFHQTtBQUNBO0FBR0E7QUFDQTtBQUdBO0FBQ0E7QUFHQTtBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUhBO0FBQ0E7QUFLQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBSEE7QUFDQTtBQUtBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBaEJBO0FBQUE7QUFBQTtBQUNBO0FBaUJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBSEE7QUFDQTtBQUtBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZVJvb3QiOiIifQ=="); /***/ }), /* 87 */ diff --git a/js/index.js b/js/index.js index f691387..ecb5871 100644 --- a/js/index.js +++ b/js/index.js @@ -28,8 +28,9 @@ window.addEventListener('load', () => { // TODO abs positioning on controls elements so order doesn't matter // TODO BehaviorSubject listener on bounds change // TODO are vision grid nodes removed properly -// TODO overlapping grid points // TODO grid touches +// TODO start with n particles doesn't update slider +// TODO leader not quite right, if 2 particles, sometimes ignored // TODO ANIM1ab free movement diff --git a/js/particle.js b/js/particle.js index 8ee63f7..aa0763b 100644 --- a/js/particle.js +++ b/js/particle.js @@ -14,7 +14,6 @@ function Particle(parent, bounds, globalGrid, observables) { randomize: true, showArc: false, showVision: false, - speed: 4, visionRadius: 50 }; @@ -39,6 +38,7 @@ function Particle(parent, bounds, globalGrid, observables) { this.isLeader = false; this.arc = Arc.create(bounds, this.grids.global); + this.arc.length = 3; // If starting in a hazard, recurse. while (this.grids.global.getPoint({ x: this.arc.endX, y: this.arc.endY, type: ENTITIES.HAZARD}) !== undefined) { @@ -96,21 +96,14 @@ Particle.prototype.subscribeNextFrame = function() { type: ENTITIES.PARTICLE }); - if (this.nodes === undefined) { - console.warn('no nodes in', this.id); - return; - } - - // this.arc = Arc.goto(this.arc, 200, 200, this.config.speed) - - this.arc = Arc.step(this.arc, this.config.bounds, this.config.speed); - if (this.leader !== null) { this.arc = Arc.follow(this.arc, this.leader.arc); } else if (this.arc.length <= 0 && this.config.randomize) { this.arc = Arc.randomize(this.arc); } + this.arc = Arc.step(this.arc, this.config.bounds); + this.grids.vision = updateVisionGrid(this.arc, this.config, this.grids); const { hazards, particles } = look(this.arc, this.grids); @@ -133,10 +126,9 @@ Particle.prototype.subscribeNextFrame = function() { } Particle.prototype.subscribeSpeed = function(value) { - this.config.speed = value; + Arc.changeSpeed(this.arc, value); } - Particle.prototype.subscribeCircle = function(show) { if (show === false) { this.nodes.container.removeChild(this.nodes.circle);