diff --git a/js/animation.js b/js/animation.js index b28256d..6980e88 100644 --- a/js/animation.js +++ b/js/animation.js @@ -8,72 +8,27 @@ function Animation(observables, id) { this.id = id; this.observables = observables; this.particles = []; + this.grid = new Grid(); + this.fpsInterval = null; this.container = document.createElement('div'); this.container.className = 'animationContainer'; document.getElementById(id).appendChild(this.container); - this.observables.animating$.subscribe(this.updateAnimating.bind(this)); - this.observables.count$.skip(1).subscribe(this.updateCount.bind(this)); - - // observables.circle$, PROBABLY WON'T NEED THESE, WILL BE In PARTICLE - // observables.randomize$, - // observables.speed$ - - // this.observables.count$.next(99); - - //
- - // console.warn("Mounting Animation", this.id); - - // console.warn('updateAnimating in Animation', isAnimating) - // this.isAnimating = isAnimating; - // if (isAnimating) { - // const fps$ = Rx.Observable.interval(1000 / 32) - // .takeWhile(_ => this.isAnimating); - // - // fps$.subscribe(this.nextFrame.bind(this)); - // } - - // this.container = container; - // this.particles = []; - // this.isAnimating = false; - // this.config = config; - // this.grid = new Grid(); - - // this.updateAnimating(false); - // this.updateCircle(config.circleControl); - // this.updateSpeed(config.speed); - // this.updateRandomize(this.config.randomizeControl); - - // Must be last, after configs all set up and container is fully rendered. - // this.updateCount(this.config.count); + this.observables.count$.skip(1).subscribe(this.subscribeCount.bind(this)); + this.observables.animating$.subscribe(this.subscribeAnimating.bind(this)); } -Animation.prototype.updateAnimating = function(isAnimating) { +Animation.prototype.subscribeAnimating = function(isAnimating) { if (isAnimating === false) { - return; + clearInterval(this.fpsInterval); + } else { + const { fps$ } = this.observables; + this.fpsInterval = setInterval(fps$.next.bind(fps$), 1000 / 32); } - - const fps$ = Rx.Observable.interval(1000 / 32) - .takeUntil(this.observables.animating$); - - fps$.subscribe(this.nextFrame.bind(this)); } -Animation.prototype.nextFrame = function() { - this.particles.forEach(p => { - const prevX = p.arc.endX; - const prevY = p.arc.endY; - - p.nextFrame(); - - // this.grid.deletePoint({ x: prevX, y: prevY, type: ENTITIES.PARTICLE }); - // this.grid.setPoint({ x: p.arc.endX, y: p.arc.endY, type: ENTITIES.PARTICLE }, p); - }); -} - -Animation.prototype.updateCount = function(count) { +Animation.prototype.subscribeCount = function(count) { const bounds = this.container.getBoundingClientRect(); while (this.particles.length > count) { @@ -82,25 +37,9 @@ Animation.prototype.updateCount = function(count) { } while (this.particles.length < count) { - const p = new Particle(this.container, bounds, this.config, this.grid); + const p = new Particle(this.container, bounds, this.grid, this.observables); this.particles.push(p); } } -Animation.prototype.updateSpeed = function(value) { - // Options must be stored; they are passed to new particles. - this.config.speed = value; - this.particles.forEach(p => p.updateConfig({ speed: value })); -} - -Animation.prototype.updateCircle = function(value) { - this.config.showMovementCircle = value; - this.particles.forEach(p => p.updateConfig({ showMovementCircle: value })); -} - -Animation.prototype.updateRandomize = function(value) { - this.config.randomize = value; - this.particles.forEach(p => p.updateConfig({ randomize: value })); -} - export default Animation; diff --git a/js/animation1b.js b/js/animation1b.js index 0f9e7c6..e2c638d 100644 --- a/js/animation1b.js +++ b/js/animation1b.js @@ -5,7 +5,7 @@ export default function(destroy$) { const id = '1b'; const config = { id, - max: 10 + maxCount: 1000 }; const observables = Controls(destroy$, config); diff --git a/js/bundle.js b/js/bundle.js index 90cfc25..0eb9e5d 100644 --- a/js/bundle.js +++ b/js/bundle.js @@ -448,7 +448,7 @@ eval("\nvar isArray_1 = __webpack_require__(/*! ../util/isArray */ 11);\nfunctio /***/ (function(module, exports, __webpack_require__) { "use strict"; -eval("\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nexports.default = function (destroy$, _ref) {\n var _ref$count = _ref.count,\n count = _ref$count === undefined ? 1 : _ref$count,\n id = _ref.id,\n _ref$maxCount = _ref.maxCount,\n maxCount = _ref$maxCount === undefined ? 10 : _ref$maxCount,\n _ref$showCircleContro = _ref.showCircleControl,\n showCircleControl = _ref$showCircleContro === undefined ? false : _ref$showCircleContro,\n _ref$showRandomizeCon = _ref.showRandomizeControl,\n showRandomizeControl = _ref$showRandomizeCon === undefined ? false : _ref$showRandomizeCon;\n\n var container = document.createElement('div');\n container.className = 'controlsContainer';\n container.id = 'controls' + id;\n document.getElementById(id).appendChild(container);\n\n var observables = {\n count$: createCountControl(container, 0, maxCount),\n speed$: createSpeedControl(container),\n circle$: showCircleControl ? createCircleControl(container) : undefined,\n randomize$: showRandomizeControl ? createRandomizeControl(container) : undefined,\n animating$: createAnimatingControl(container)\n };\n\n observables.animating$.subscribe(function (isAnimating) {\n if (isAnimating === true) {\n destroy$.next(id);\n\n if (observables.count$.getValue() === 0) {\n observables.count$.next(count);\n }\n }\n });\n\n destroy$.subscribe(function (sourceId) {\n if (id !== sourceId) {\n observables.animating$.next(false);\n observables.count$.next(0);\n }\n });\n\n return observables;\n};\n\nvar _rxjs = __webpack_require__(/*! rxjs */ 19);\n\nvar _rxjs2 = _interopRequireDefault(_rxjs);\n\nvar _enums = __webpack_require__(/*! ./enums */ 20);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nfunction createAnimatingControl(container) {\n var label = document.createElement('label');\n label.className = 'controls-label';\n label.className = 'controls-animating';\n\n var text = document.createElement('span');\n\n var checkbox = document.createElement('input');\n checkbox.type = 'checkbox';\n checkbox.checked = false;\n\n label.appendChild(checkbox);\n label.appendChild(text);\n\n container.appendChild(label);\n\n var animating$ = new _rxjs2.default.BehaviorSubject(false);\n\n label.addEventListener('change', function (evt) {\n animating$.next(evt.target.checked);\n });\n\n animating$.subscribe(function (isAnimating) {\n text.innerHTML = isAnimating ? '◼ Stop' : '▶ Start';\n checkbox.checked = isAnimating;\n });\n\n return animating$;\n}\n\nfunction createCountControl(container, initialValue, max) {\n var label = document.createElement('label');\n label.className = 'controls-range';\n\n var text = document.createElement('span');\n text.innerHTML = initialValue == 1 ? '1 particle' : initialValue + ' particles';\n text.className = 'controls-range-text';\n\n var slider = document.createElement('input');\n slider.type = 'range';\n slider.min = 1;\n slider.max = max;\n slider.value = initialValue;\n slider.className = 'controls-range-input';\n\n label.appendChild(text);\n label.appendChild(slider);\n\n container.appendChild(label);\n\n var count$ = new _rxjs2.default.BehaviorSubject(initialValue);\n\n label.addEventListener('input', function (evt) {\n count$.next(evt.target.value * 1);\n });\n\n count$.subscribe(function (value) {\n text.innerHTML = value == 1 ? '1 particle' : value + ' particles';\n });\n\n return count$;\n}\n\nfunction createSpeedControl(container) {\n var label = document.createElement('label');\n label.className = 'controls-range';\n\n var text = document.createElement('span');\n text.className = 'controls-range-text';\n text.innerHTML = 'Speed: 0';\n\n var slider = document.createElement('input');\n slider.type = 'range';\n slider.min = 1;\n slider.max = 15;\n slider.value = 4;\n slider.className = 'controls-range-input';\n\n label.appendChild(text);\n label.appendChild(slider);\n\n container.appendChild(label);\n\n var speed$ = new _rxjs2.default.BehaviorSubject(slider.value);\n\n label.addEventListener('input', function (evt) {\n speed$.next(evt.target.value * 1);\n });\n\n speed$.subscribe(function (value) {\n text.innerHTML = 'Speed: ' + value;\n });\n\n return speed$;\n}\n\nfunction createCircleControl(container) {\n var label = document.createElement('label');\n label.className = 'controls-checkbox';\n\n var text = document.createElement('span');\n text.innerHTML = 'Show movement circle';\n text.className = 'controls-checkbox-text';\n\n var checkbox = document.createElement('input');\n checkbox.type = 'checkbox';\n checkbox.className = 'controls-checkbox-input';\n checkbox.checked = true;\n\n label.appendChild(checkbox);\n label.appendChild(text);\n\n container.appendChild(label);\n\n var circle$ = _rxjs2.default.Observable.fromEvent(label, 'change').map(function (evt) {\n return evt.target.checked;\n });\n\n return circle$;\n}\n\nfunction createRandomizeControl(container) {\n var label = document.createElement('label');\n label.className = 'controls-checkbox';\n\n var text = document.createElement('span');\n text.innerHTML = 'Randomize movement';\n text.className = 'controls-checkbox-text';\n\n var checkbox = document.createElement('input');\n checkbox.type = 'checkbox';\n checkbox.className = 'controls-checkbox-input';\n checkbox.checked = true;\n\n label.appendChild(checkbox);\n label.appendChild(text);\n\n container.appendChild(label);\n\n var circle$ = _rxjs2.default.Observable.fromEvent(label, 'change').map(function (evt) {\n return evt.target.checked;\n });\n\n return randomize$;\n}//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMzEuanMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vanMvY29udHJvbHMuanM/ZTk5YiJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgUngsIHsgT2JzZXJ2YWJsZSB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgQ09OVFJPTFMgfSBmcm9tICcuL2VudW1zJztcblxuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24oZGVzdHJveSQsIHtcbiAgICBjb3VudCA9IDEsXG4gICAgaWQsXG4gICAgbWF4Q291bnQgPSAxMCxcbiAgICBzaG93Q2lyY2xlQ29udHJvbCA9IGZhbHNlLFxuICAgIHNob3dSYW5kb21pemVDb250cm9sID0gZmFsc2Vcbn0pIHtcbiAgICBjb25zdCBjb250YWluZXIgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICBjb250YWluZXIuY2xhc3NOYW1lID0gJ2NvbnRyb2xzQ29udGFpbmVyJztcbiAgICBjb250YWluZXIuaWQgPSBgY29udHJvbHMke2lkfWA7XG4gICAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoaWQpLmFwcGVuZENoaWxkKGNvbnRhaW5lcik7XG5cbiAgICBjb25zdCBvYnNlcnZhYmxlcyA9IHtcbiAgICAgICAgY291bnQkOiBjcmVhdGVDb3VudENvbnRyb2woY29udGFpbmVyLCAwLCBtYXhDb3VudCksXG4gICAgICAgIHNwZWVkJDogY3JlYXRlU3BlZWRDb250cm9sKGNvbnRhaW5lciksXG4gICAgICAgIGNpcmNsZSQ6IHNob3dDaXJjbGVDb250cm9sID8gY3JlYXRlQ2lyY2xlQ29udHJvbChjb250YWluZXIpIDogdW5kZWZpbmVkLFxuICAgICAgICByYW5kb21pemUkOiBzaG93UmFuZG9taXplQ29udHJvbCA/IGNyZWF0ZVJhbmRvbWl6ZUNvbnRyb2woY29udGFpbmVyKSA6IHVuZGVmaW5lZCxcbiAgICAgICAgYW5pbWF0aW5nJDogY3JlYXRlQW5pbWF0aW5nQ29udHJvbChjb250YWluZXIpLFxuICAgIH07XG5cbiAgICBvYnNlcnZhYmxlcy5hbmltYXRpbmckLnN1YnNjcmliZSgoaXNBbmltYXRpbmcpID0+IHtcbiAgICAgICAgaWYgKGlzQW5pbWF0aW5nID09PSB0cnVlKSB7XG4gICAgICAgICAgICBkZXN0cm95JC5uZXh0KGlkKTtcblxuICAgICAgICAgICAgaWYgKG9ic2VydmFibGVzLmNvdW50JC5nZXRWYWx1ZSgpID09PSAwKSB7XG4gICAgICAgICAgICAgICAgb2JzZXJ2YWJsZXMuY291bnQkLm5leHQoY291bnQpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfSk7XG5cbiAgICBkZXN0cm95JC5zdWJzY3JpYmUoKHNvdXJjZUlkKSA9PiB7XG4gICAgICAgIGlmIChpZCAhPT0gc291cmNlSWQpIHtcbiAgICAgICAgICAgIG9ic2VydmFibGVzLmFuaW1hdGluZyQubmV4dChmYWxzZSk7XG4gICAgICAgICAgICBvYnNlcnZhYmxlcy5jb3VudCQubmV4dCgwKTtcbiAgICAgICAgfVxuICAgIH0pO1xuXG4gICAgcmV0dXJuIG9ic2VydmFibGVzO1xufVxuXG5cbmZ1bmN0aW9uIGNyZWF0ZUFuaW1hdGluZ0NvbnRyb2woY29udGFpbmVyKSB7XG4gICAgY29uc3QgbGFiZWwgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdsYWJlbCcpO1xuICAgIGxhYmVsLmNsYXNzTmFtZSA9ICdjb250cm9scy1sYWJlbCc7XG4gICAgbGFiZWwuY2xhc3NOYW1lID0gJ2NvbnRyb2xzLWFuaW1hdGluZyc7XG5cbiAgICBjb25zdCB0ZXh0ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnc3BhbicpO1xuXG4gICAgY29uc3QgY2hlY2tib3ggPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdpbnB1dCcpO1xuICAgIGNoZWNrYm94LnR5cGUgPSAnY2hlY2tib3gnO1xuICAgIGNoZWNrYm94LmNoZWNrZWQgPSBmYWxzZTtcblxuICAgIGxhYmVsLmFwcGVuZENoaWxkKGNoZWNrYm94KTtcbiAgICBsYWJlbC5hcHBlbmRDaGlsZCh0ZXh0KTtcblxuICAgIGNvbnRhaW5lci5hcHBlbmRDaGlsZChsYWJlbCk7XG5cbiAgICBjb25zdCBhbmltYXRpbmckID0gbmV3IFJ4LkJlaGF2aW9yU3ViamVjdChmYWxzZSk7XG5cbiAgICBsYWJlbC5hZGRFdmVudExpc3RlbmVyKCdjaGFuZ2UnLCAoZXZ0KSA9PiB7XG4gICAgICAgIGFuaW1hdGluZyQubmV4dChldnQudGFyZ2V0LmNoZWNrZWQpO1xuICAgIH0pO1xuXG4gICAgYW5pbWF0aW5nJC5zdWJzY3JpYmUoKGlzQW5pbWF0aW5nKSA9PiB7XG4gICAgICAgIHRleHQuaW5uZXJIVE1MID0gKGlzQW5pbWF0aW5nID8gJyYjOTcyNDsgU3RvcCcgOiAnJiM5NjU0OyBTdGFydCcpO1xuICAgICAgICBjaGVja2JveC5jaGVja2VkID0gaXNBbmltYXRpbmc7XG4gICAgfSk7XG5cbiAgICByZXR1cm4gYW5pbWF0aW5nJDtcbn1cblxuZnVuY3Rpb24gY3JlYXRlQ291bnRDb250cm9sKGNvbnRhaW5lciwgaW5pdGlhbFZhbHVlLCBtYXgpIHtcbiAgICBjb25zdCBsYWJlbCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2xhYmVsJyk7XG4gICAgbGFiZWwuY2xhc3NOYW1lID0gJ2NvbnRyb2xzLXJhbmdlJztcblxuICAgIGNvbnN0IHRleHQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdzcGFuJyk7XG4gICAgdGV4dC5pbm5lckhUTUwgPSAoaW5pdGlhbFZhbHVlID09IDEpID8gJzEgcGFydGljbGUnIDogYCR7aW5pdGlhbFZhbHVlfSBwYXJ0aWNsZXNgO1xuICAgIHRleHQuY2xhc3NOYW1lID0gJ2NvbnRyb2xzLXJhbmdlLXRleHQnO1xuXG4gICAgY29uc3Qgc2xpZGVyID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnaW5wdXQnKTtcbiAgICBzbGlkZXIudHlwZSA9ICdyYW5nZSc7XG4gICAgc2xpZGVyLm1pbiA9IDE7XG4gICAgc2xpZGVyLm1heCA9IG1heDtcbiAgICBzbGlkZXIudmFsdWUgPSBpbml0aWFsVmFsdWU7XG4gICAgc2xpZGVyLmNsYXNzTmFtZSA9ICdjb250cm9scy1yYW5nZS1pbnB1dCc7XG5cbiAgICBsYWJlbC5hcHBlbmRDaGlsZCh0ZXh0KTtcbiAgICBsYWJlbC5hcHBlbmRDaGlsZChzbGlkZXIpO1xuXG4gICAgY29udGFpbmVyLmFwcGVuZENoaWxkKGxhYmVsKTtcblxuICAgIGNvbnN0IGNvdW50JCA9IG5ldyBSeC5CZWhhdmlvclN1YmplY3QoaW5pdGlhbFZhbHVlKTtcblxuICAgIGxhYmVsLmFkZEV2ZW50TGlzdGVuZXIoJ2lucHV0JywgKGV2dCkgPT4ge1xuICAgICAgICBjb3VudCQubmV4dChldnQudGFyZ2V0LnZhbHVlICogMSk7XG4gICAgfSk7XG5cbiAgICBjb3VudCQuc3Vic2NyaWJlKCh2YWx1ZSkgPT4ge1xuICAgICAgICB0ZXh0LmlubmVySFRNTCA9ICh2YWx1ZSA9PSAxKSA/ICcxIHBhcnRpY2xlJyA6IGAke3ZhbHVlfSBwYXJ0aWNsZXNgO1xuICAgIH0pO1xuXG4gICAgcmV0dXJuIGNvdW50JDtcbn1cblxuZnVuY3Rpb24gY3JlYXRlU3BlZWRDb250cm9sKGNvbnRhaW5lcikge1xuICAgIGNvbnN0IGxhYmVsID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnbGFiZWwnKTtcbiAgICBsYWJlbC5jbGFzc05hbWUgPSAnY29udHJvbHMtcmFuZ2UnO1xuXG4gICAgY29uc3QgdGV4dCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3NwYW4nKTtcbiAgICB0ZXh0LmNsYXNzTmFtZSA9ICdjb250cm9scy1yYW5nZS10ZXh0JztcbiAgICB0ZXh0LmlubmVySFRNTCA9ICdTcGVlZDogMCc7XG5cbiAgICBjb25zdCBzbGlkZXIgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdpbnB1dCcpO1xuICAgIHNsaWRlci50eXBlID0gJ3JhbmdlJztcbiAgICBzbGlkZXIubWluID0gMTtcbiAgICBzbGlkZXIubWF4ID0gMTU7XG4gICAgc2xpZGVyLnZhbHVlID0gNDtcbiAgICBzbGlkZXIuY2xhc3NOYW1lID0gJ2NvbnRyb2xzLXJhbmdlLWlucHV0JztcblxuICAgIGxhYmVsLmFwcGVuZENoaWxkKHRleHQpO1xuICAgIGxhYmVsLmFwcGVuZENoaWxkKHNsaWRlcik7XG5cbiAgICBjb250YWluZXIuYXBwZW5kQ2hpbGQobGFiZWwpO1xuXG4gICAgY29uc3Qgc3BlZWQkID0gbmV3IFJ4LkJlaGF2aW9yU3ViamVjdChzbGlkZXIudmFsdWUpO1xuXG4gICAgbGFiZWwuYWRkRXZlbnRMaXN0ZW5lcignaW5wdXQnLCAoZXZ0KSA9PiB7XG4gICAgICAgIHNwZWVkJC5uZXh0KGV2dC50YXJnZXQudmFsdWUgKiAxKTtcbiAgICB9KTtcblxuICAgIHNwZWVkJC5zdWJzY3JpYmUoKHZhbHVlKSA9PiB7XG4gICAgICAgIHRleHQuaW5uZXJIVE1MID0gYFNwZWVkOiAke3ZhbHVlfWA7XG4gICAgfSk7XG5cbiAgICByZXR1cm4gc3BlZWQkO1xufVxuXG5mdW5jdGlvbiBjcmVhdGVDaXJjbGVDb250cm9sKGNvbnRhaW5lcikge1xuICAgIGNvbnN0IGxhYmVsID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnbGFiZWwnKTtcbiAgICBsYWJlbC5jbGFzc05hbWUgPSAnY29udHJvbHMtY2hlY2tib3gnO1xuXG4gICAgY29uc3QgdGV4dCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3NwYW4nKTtcbiAgICB0ZXh0LmlubmVySFRNTCA9ICdTaG93IG1vdmVtZW50IGNpcmNsZSc7XG4gICAgdGV4dC5jbGFzc05hbWUgPSAnY29udHJvbHMtY2hlY2tib3gtdGV4dCc7XG5cbiAgICBjb25zdCBjaGVja2JveCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2lucHV0Jyk7XG4gICAgY2hlY2tib3gudHlwZSA9ICdjaGVja2JveCc7XG4gICAgY2hlY2tib3guY2xhc3NOYW1lID0gJ2NvbnRyb2xzLWNoZWNrYm94LWlucHV0JztcbiAgICBjaGVja2JveC5jaGVja2VkID0gdHJ1ZTtcblxuICAgIGxhYmVsLmFwcGVuZENoaWxkKGNoZWNrYm94KTtcbiAgICBsYWJlbC5hcHBlbmRDaGlsZCh0ZXh0KTtcblxuICAgIGNvbnRhaW5lci5hcHBlbmRDaGlsZChsYWJlbCk7XG5cbiAgICBjb25zdCBjaXJjbGUkID0gUnguT2JzZXJ2YWJsZS5mcm9tRXZlbnQobGFiZWwsICdjaGFuZ2UnKVxuICAgICAgICAubWFwKGV2dCA9PiBldnQudGFyZ2V0LmNoZWNrZWQpO1xuXG4gICAgcmV0dXJuIGNpcmNsZSQ7XG59XG5cbmZ1bmN0aW9uIGNyZWF0ZVJhbmRvbWl6ZUNvbnRyb2woY29udGFpbmVyKSB7XG4gICAgY29uc3QgbGFiZWwgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdsYWJlbCcpO1xuICAgIGxhYmVsLmNsYXNzTmFtZSA9ICdjb250cm9scy1jaGVja2JveCc7XG5cbiAgICBjb25zdCB0ZXh0ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnc3BhbicpO1xuICAgIHRleHQuaW5uZXJIVE1MID0gJ1JhbmRvbWl6ZSBtb3ZlbWVudCc7XG4gICAgdGV4dC5jbGFzc05hbWUgPSAnY29udHJvbHMtY2hlY2tib3gtdGV4dCc7XG5cbiAgICBjb25zdCBjaGVja2JveCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2lucHV0Jyk7XG4gICAgY2hlY2tib3gudHlwZSA9ICdjaGVja2JveCc7XG4gICAgY2hlY2tib3guY2xhc3NOYW1lID0gJ2NvbnRyb2xzLWNoZWNrYm94LWlucHV0JztcbiAgICBjaGVja2JveC5jaGVja2VkID0gdHJ1ZTtcblxuICAgIGxhYmVsLmFwcGVuZENoaWxkKGNoZWNrYm94KTtcbiAgICBsYWJlbC5hcHBlbmRDaGlsZCh0ZXh0KTtcblxuICAgIGNvbnRhaW5lci5hcHBlbmRDaGlsZChsYWJlbCk7XG5cbiAgICBjb25zdCBjaXJjbGUkID0gUnguT2JzZXJ2YWJsZS5mcm9tRXZlbnQobGFiZWwsICdjaGFuZ2UnKVxuICAgICAgICAubWFwKGV2dCA9PiBldnQudGFyZ2V0LmNoZWNrZWQpO1xuXG4gICAgcmV0dXJuIHJhbmRvbWl6ZSQ7XG59XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8ganMvY29udHJvbHMuanMiXSwibWFwcGluZ3MiOiI7Ozs7OztBQUdBO0FBTUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBTEE7QUFDQTtBQU9BO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUExQ0E7QUFDQTs7O0FBQUE7QUFDQTs7O0FBMENBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBIiwic291cmNlUm9vdCI6IiJ9"); +eval("\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nexports.default = function (destroy$, _ref) {\n var _ref$count = _ref.count,\n count = _ref$count === undefined ? 1 : _ref$count,\n id = _ref.id,\n _ref$maxCount = _ref.maxCount,\n maxCount = _ref$maxCount === undefined ? 10 : _ref$maxCount,\n _ref$showCircleContro = _ref.showCircleControl,\n showCircleControl = _ref$showCircleContro === undefined ? false : _ref$showCircleContro,\n _ref$showRandomizeCon = _ref.showRandomizeControl,\n showRandomizeControl = _ref$showRandomizeCon === undefined ? false : _ref$showRandomizeCon;\n\n var container = document.createElement('div');\n container.className = 'controlsContainer';\n container.id = 'controls' + id;\n document.getElementById(id).appendChild(container);\n\n var observables = {\n fps$: new _rxjs2.default.Subject(),\n count$: createCountControl(container, 0, maxCount),\n speed$: createSpeedControl(container),\n circle$: showCircleControl ? createCircleControl(container) : undefined,\n randomize$: showRandomizeControl ? createRandomizeControl(container) : undefined,\n animating$: createAnimatingControl(container)\n };\n\n observables.animating$.subscribe(function (isAnimating) {\n if (isAnimating === true) {\n destroy$.next(id);\n\n if (observables.count$.getValue() === 0) {\n observables.count$.next(count);\n }\n }\n });\n\n destroy$.subscribe(function (sourceId) {\n if (id !== sourceId) {\n observables.animating$.next(false);\n observables.count$.next(0);\n }\n });\n\n return observables;\n};\n\nvar _rxjs = __webpack_require__(/*! rxjs */ 19);\n\nvar _rxjs2 = _interopRequireDefault(_rxjs);\n\nvar _enums = __webpack_require__(/*! ./enums */ 20);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nfunction createAnimatingControl(container) {\n var label = document.createElement('label');\n label.className = 'controls-label';\n label.className = 'controls-animating';\n\n var text = document.createElement('span');\n\n var checkbox = document.createElement('input');\n checkbox.type = 'checkbox';\n checkbox.checked = false;\n\n label.appendChild(checkbox);\n label.appendChild(text);\n\n container.appendChild(label);\n\n var animating$ = new _rxjs2.default.BehaviorSubject(false);\n\n label.addEventListener('change', function (evt) {\n animating$.next(evt.target.checked);\n });\n\n animating$.subscribe(function (isAnimating) {\n text.innerHTML = isAnimating ? '◼ Stop' : '▶ Start';\n checkbox.checked = isAnimating;\n });\n\n return animating$;\n}\n\nfunction createCountControl(container, initialValue, max) {\n var label = document.createElement('label');\n label.className = 'controls-range';\n\n var text = document.createElement('span');\n text.innerHTML = initialValue == 1 ? '1 particle' : initialValue + ' particles';\n text.className = 'controls-range-text';\n\n var slider = document.createElement('input');\n slider.type = 'range';\n slider.min = 1;\n slider.max = max;\n slider.value = initialValue;\n slider.className = 'controls-range-input';\n\n label.appendChild(text);\n label.appendChild(slider);\n\n container.appendChild(label);\n\n var count$ = new _rxjs2.default.BehaviorSubject(initialValue);\n\n label.addEventListener('input', function (evt) {\n count$.next(evt.target.value * 1);\n });\n\n count$.subscribe(function (value) {\n text.innerHTML = value == 1 ? '1 particle' : value + ' particles';\n });\n\n return count$;\n}\n\nfunction createSpeedControl(container) {\n var label = document.createElement('label');\n label.className = 'controls-range';\n\n var text = document.createElement('span');\n text.className = 'controls-range-text';\n text.innerHTML = 'Speed: 0';\n\n var slider = document.createElement('input');\n slider.type = 'range';\n slider.min = 1;\n slider.max = 15;\n slider.value = 4;\n slider.className = 'controls-range-input';\n\n label.appendChild(text);\n label.appendChild(slider);\n\n container.appendChild(label);\n\n var speed$ = new _rxjs2.default.BehaviorSubject(slider.value);\n\n label.addEventListener('input', function (evt) {\n speed$.next(evt.target.value * 1);\n });\n\n speed$.subscribe(function (value) {\n text.innerHTML = 'Speed: ' + value;\n });\n\n return speed$;\n}\n\nfunction createCircleControl(container) {\n var label = document.createElement('label');\n label.className = 'controls-checkbox';\n\n var text = document.createElement('span');\n text.innerHTML = 'Show movement circle';\n text.className = 'controls-checkbox-text';\n\n var checkbox = document.createElement('input');\n checkbox.type = 'checkbox';\n checkbox.className = 'controls-checkbox-input';\n checkbox.checked = true;\n\n label.appendChild(checkbox);\n label.appendChild(text);\n\n container.appendChild(label);\n\n var circle$ = new _rxjs2.default.BehaviorSubject(true);\n\n label.addEventListener('change', function (evt) {\n circle$.next(evt.target.checked);\n });\n\n return circle$;\n}\n\nfunction createRandomizeControl(container) {\n var label = document.createElement('label');\n label.className = 'controls-checkbox';\n\n var text = document.createElement('span');\n text.innerHTML = 'Randomize movement';\n text.className = 'controls-checkbox-text';\n\n var checkbox = document.createElement('input');\n checkbox.type = 'checkbox';\n checkbox.className = 'controls-checkbox-input';\n checkbox.checked = true;\n\n label.appendChild(checkbox);\n label.appendChild(text);\n\n container.appendChild(label);\n\n var randomize$ = new _rxjs2.default.BehaviorSubject(true);\n\n label.addEventListener('change', function (evt) {\n randomize$.next(evt.target.checked);\n });\n\n return randomize$;\n}//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMzEuanMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vanMvY29udHJvbHMuanM/ZTk5YiJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgUngsIHsgT2JzZXJ2YWJsZSB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgQ09OVFJPTFMgfSBmcm9tICcuL2VudW1zJztcblxuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24oZGVzdHJveSQsIHtcbiAgICBjb3VudCA9IDEsXG4gICAgaWQsXG4gICAgbWF4Q291bnQgPSAxMCxcbiAgICBzaG93Q2lyY2xlQ29udHJvbCA9IGZhbHNlLFxuICAgIHNob3dSYW5kb21pemVDb250cm9sID0gZmFsc2Vcbn0pIHtcbiAgICBjb25zdCBjb250YWluZXIgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICBjb250YWluZXIuY2xhc3NOYW1lID0gJ2NvbnRyb2xzQ29udGFpbmVyJztcbiAgICBjb250YWluZXIuaWQgPSBgY29udHJvbHMke2lkfWA7XG4gICAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoaWQpLmFwcGVuZENoaWxkKGNvbnRhaW5lcik7XG5cbiAgICBjb25zdCBvYnNlcnZhYmxlcyA9IHtcbiAgICAgICAgZnBzJDogbmV3IFJ4LlN1YmplY3QoKSxcbiAgICAgICAgY291bnQkOiBjcmVhdGVDb3VudENvbnRyb2woY29udGFpbmVyLCAwLCBtYXhDb3VudCksXG4gICAgICAgIHNwZWVkJDogY3JlYXRlU3BlZWRDb250cm9sKGNvbnRhaW5lciksXG4gICAgICAgIGNpcmNsZSQ6IHNob3dDaXJjbGVDb250cm9sID8gY3JlYXRlQ2lyY2xlQ29udHJvbChjb250YWluZXIpIDogdW5kZWZpbmVkLFxuICAgICAgICByYW5kb21pemUkOiBzaG93UmFuZG9taXplQ29udHJvbCA/IGNyZWF0ZVJhbmRvbWl6ZUNvbnRyb2woY29udGFpbmVyKSA6IHVuZGVmaW5lZCxcbiAgICAgICAgYW5pbWF0aW5nJDogY3JlYXRlQW5pbWF0aW5nQ29udHJvbChjb250YWluZXIpLFxuICAgIH07XG5cbiAgICBvYnNlcnZhYmxlcy5hbmltYXRpbmckLnN1YnNjcmliZSgoaXNBbmltYXRpbmcpID0+IHtcbiAgICAgICAgaWYgKGlzQW5pbWF0aW5nID09PSB0cnVlKSB7XG4gICAgICAgICAgICBkZXN0cm95JC5uZXh0KGlkKTtcblxuICAgICAgICAgICAgaWYgKG9ic2VydmFibGVzLmNvdW50JC5nZXRWYWx1ZSgpID09PSAwKSB7XG4gICAgICAgICAgICAgICAgb2JzZXJ2YWJsZXMuY291bnQkLm5leHQoY291bnQpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfSk7XG5cbiAgICBkZXN0cm95JC5zdWJzY3JpYmUoKHNvdXJjZUlkKSA9PiB7XG4gICAgICAgIGlmIChpZCAhPT0gc291cmNlSWQpIHtcbiAgICAgICAgICAgIG9ic2VydmFibGVzLmFuaW1hdGluZyQubmV4dChmYWxzZSk7XG4gICAgICAgICAgICBvYnNlcnZhYmxlcy5jb3VudCQubmV4dCgwKTtcbiAgICAgICAgfVxuICAgIH0pO1xuXG4gICAgcmV0dXJuIG9ic2VydmFibGVzO1xufVxuXG5cbmZ1bmN0aW9uIGNyZWF0ZUFuaW1hdGluZ0NvbnRyb2woY29udGFpbmVyKSB7XG4gICAgY29uc3QgbGFiZWwgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdsYWJlbCcpO1xuICAgIGxhYmVsLmNsYXNzTmFtZSA9ICdjb250cm9scy1sYWJlbCc7XG4gICAgbGFiZWwuY2xhc3NOYW1lID0gJ2NvbnRyb2xzLWFuaW1hdGluZyc7XG5cbiAgICBjb25zdCB0ZXh0ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnc3BhbicpO1xuXG4gICAgY29uc3QgY2hlY2tib3ggPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdpbnB1dCcpO1xuICAgIGNoZWNrYm94LnR5cGUgPSAnY2hlY2tib3gnO1xuICAgIGNoZWNrYm94LmNoZWNrZWQgPSBmYWxzZTtcblxuICAgIGxhYmVsLmFwcGVuZENoaWxkKGNoZWNrYm94KTtcbiAgICBsYWJlbC5hcHBlbmRDaGlsZCh0ZXh0KTtcblxuICAgIGNvbnRhaW5lci5hcHBlbmRDaGlsZChsYWJlbCk7XG5cbiAgICBjb25zdCBhbmltYXRpbmckID0gbmV3IFJ4LkJlaGF2aW9yU3ViamVjdChmYWxzZSk7XG5cbiAgICBsYWJlbC5hZGRFdmVudExpc3RlbmVyKCdjaGFuZ2UnLCAoZXZ0KSA9PiB7XG4gICAgICAgIGFuaW1hdGluZyQubmV4dChldnQudGFyZ2V0LmNoZWNrZWQpO1xuICAgIH0pO1xuXG4gICAgYW5pbWF0aW5nJC5zdWJzY3JpYmUoKGlzQW5pbWF0aW5nKSA9PiB7XG4gICAgICAgIHRleHQuaW5uZXJIVE1MID0gKGlzQW5pbWF0aW5nID8gJyYjOTcyNDsgU3RvcCcgOiAnJiM5NjU0OyBTdGFydCcpO1xuICAgICAgICBjaGVja2JveC5jaGVja2VkID0gaXNBbmltYXRpbmc7XG4gICAgfSk7XG5cbiAgICByZXR1cm4gYW5pbWF0aW5nJDtcbn1cblxuZnVuY3Rpb24gY3JlYXRlQ291bnRDb250cm9sKGNvbnRhaW5lciwgaW5pdGlhbFZhbHVlLCBtYXgpIHtcbiAgICBjb25zdCBsYWJlbCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2xhYmVsJyk7XG4gICAgbGFiZWwuY2xhc3NOYW1lID0gJ2NvbnRyb2xzLXJhbmdlJztcblxuICAgIGNvbnN0IHRleHQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdzcGFuJyk7XG4gICAgdGV4dC5pbm5lckhUTUwgPSAoaW5pdGlhbFZhbHVlID09IDEpID8gJzEgcGFydGljbGUnIDogYCR7aW5pdGlhbFZhbHVlfSBwYXJ0aWNsZXNgO1xuICAgIHRleHQuY2xhc3NOYW1lID0gJ2NvbnRyb2xzLXJhbmdlLXRleHQnO1xuXG4gICAgY29uc3Qgc2xpZGVyID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnaW5wdXQnKTtcbiAgICBzbGlkZXIudHlwZSA9ICdyYW5nZSc7XG4gICAgc2xpZGVyLm1pbiA9IDE7XG4gICAgc2xpZGVyLm1heCA9IG1heDtcbiAgICBzbGlkZXIudmFsdWUgPSBpbml0aWFsVmFsdWU7XG4gICAgc2xpZGVyLmNsYXNzTmFtZSA9ICdjb250cm9scy1yYW5nZS1pbnB1dCc7XG5cbiAgICBsYWJlbC5hcHBlbmRDaGlsZCh0ZXh0KTtcbiAgICBsYWJlbC5hcHBlbmRDaGlsZChzbGlkZXIpO1xuXG4gICAgY29udGFpbmVyLmFwcGVuZENoaWxkKGxhYmVsKTtcblxuICAgIGNvbnN0IGNvdW50JCA9IG5ldyBSeC5CZWhhdmlvclN1YmplY3QoaW5pdGlhbFZhbHVlKTtcblxuICAgIGxhYmVsLmFkZEV2ZW50TGlzdGVuZXIoJ2lucHV0JywgKGV2dCkgPT4ge1xuICAgICAgICBjb3VudCQubmV4dChldnQudGFyZ2V0LnZhbHVlICogMSk7XG4gICAgfSk7XG5cbiAgICBjb3VudCQuc3Vic2NyaWJlKCh2YWx1ZSkgPT4ge1xuICAgICAgICB0ZXh0LmlubmVySFRNTCA9ICh2YWx1ZSA9PSAxKSA/ICcxIHBhcnRpY2xlJyA6IGAke3ZhbHVlfSBwYXJ0aWNsZXNgO1xuICAgIH0pO1xuXG4gICAgcmV0dXJuIGNvdW50JDtcbn1cblxuZnVuY3Rpb24gY3JlYXRlU3BlZWRDb250cm9sKGNvbnRhaW5lcikge1xuICAgIGNvbnN0IGxhYmVsID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnbGFiZWwnKTtcbiAgICBsYWJlbC5jbGFzc05hbWUgPSAnY29udHJvbHMtcmFuZ2UnO1xuXG4gICAgY29uc3QgdGV4dCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3NwYW4nKTtcbiAgICB0ZXh0LmNsYXNzTmFtZSA9ICdjb250cm9scy1yYW5nZS10ZXh0JztcbiAgICB0ZXh0LmlubmVySFRNTCA9ICdTcGVlZDogMCc7XG5cbiAgICBjb25zdCBzbGlkZXIgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdpbnB1dCcpO1xuICAgIHNsaWRlci50eXBlID0gJ3JhbmdlJztcbiAgICBzbGlkZXIubWluID0gMTtcbiAgICBzbGlkZXIubWF4ID0gMTU7XG4gICAgc2xpZGVyLnZhbHVlID0gNDtcbiAgICBzbGlkZXIuY2xhc3NOYW1lID0gJ2NvbnRyb2xzLXJhbmdlLWlucHV0JztcblxuICAgIGxhYmVsLmFwcGVuZENoaWxkKHRleHQpO1xuICAgIGxhYmVsLmFwcGVuZENoaWxkKHNsaWRlcik7XG5cbiAgICBjb250YWluZXIuYXBwZW5kQ2hpbGQobGFiZWwpO1xuXG4gICAgY29uc3Qgc3BlZWQkID0gbmV3IFJ4LkJlaGF2aW9yU3ViamVjdChzbGlkZXIudmFsdWUpO1xuXG4gICAgbGFiZWwuYWRkRXZlbnRMaXN0ZW5lcignaW5wdXQnLCAoZXZ0KSA9PiB7XG4gICAgICAgIHNwZWVkJC5uZXh0KGV2dC50YXJnZXQudmFsdWUgKiAxKTtcbiAgICB9KTtcblxuICAgIHNwZWVkJC5zdWJzY3JpYmUoKHZhbHVlKSA9PiB7XG4gICAgICAgIHRleHQuaW5uZXJIVE1MID0gYFNwZWVkOiAke3ZhbHVlfWA7XG4gICAgfSk7XG5cbiAgICByZXR1cm4gc3BlZWQkO1xufVxuXG5mdW5jdGlvbiBjcmVhdGVDaXJjbGVDb250cm9sKGNvbnRhaW5lcikge1xuICAgIGNvbnN0IGxhYmVsID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnbGFiZWwnKTtcbiAgICBsYWJlbC5jbGFzc05hbWUgPSAnY29udHJvbHMtY2hlY2tib3gnO1xuXG4gICAgY29uc3QgdGV4dCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3NwYW4nKTtcbiAgICB0ZXh0LmlubmVySFRNTCA9ICdTaG93IG1vdmVtZW50IGNpcmNsZSc7XG4gICAgdGV4dC5jbGFzc05hbWUgPSAnY29udHJvbHMtY2hlY2tib3gtdGV4dCc7XG5cbiAgICBjb25zdCBjaGVja2JveCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2lucHV0Jyk7XG4gICAgY2hlY2tib3gudHlwZSA9ICdjaGVja2JveCc7XG4gICAgY2hlY2tib3guY2xhc3NOYW1lID0gJ2NvbnRyb2xzLWNoZWNrYm94LWlucHV0JztcbiAgICBjaGVja2JveC5jaGVja2VkID0gdHJ1ZTtcblxuICAgIGxhYmVsLmFwcGVuZENoaWxkKGNoZWNrYm94KTtcbiAgICBsYWJlbC5hcHBlbmRDaGlsZCh0ZXh0KTtcblxuICAgIGNvbnRhaW5lci5hcHBlbmRDaGlsZChsYWJlbCk7XG5cbiAgICBjb25zdCBjaXJjbGUkID0gbmV3IFJ4LkJlaGF2aW9yU3ViamVjdCh0cnVlKTtcblxuICAgIGxhYmVsLmFkZEV2ZW50TGlzdGVuZXIoJ2NoYW5nZScsIChldnQpID0+IHtcbiAgICAgICAgY2lyY2xlJC5uZXh0KGV2dC50YXJnZXQuY2hlY2tlZCk7XG4gICAgfSk7XG5cbiAgICByZXR1cm4gY2lyY2xlJDtcbn1cblxuZnVuY3Rpb24gY3JlYXRlUmFuZG9taXplQ29udHJvbChjb250YWluZXIpIHtcbiAgICBjb25zdCBsYWJlbCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2xhYmVsJyk7XG4gICAgbGFiZWwuY2xhc3NOYW1lID0gJ2NvbnRyb2xzLWNoZWNrYm94JztcblxuICAgIGNvbnN0IHRleHQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdzcGFuJyk7XG4gICAgdGV4dC5pbm5lckhUTUwgPSAnUmFuZG9taXplIG1vdmVtZW50JztcbiAgICB0ZXh0LmNsYXNzTmFtZSA9ICdjb250cm9scy1jaGVja2JveC10ZXh0JztcblxuICAgIGNvbnN0IGNoZWNrYm94ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnaW5wdXQnKTtcbiAgICBjaGVja2JveC50eXBlID0gJ2NoZWNrYm94JztcbiAgICBjaGVja2JveC5jbGFzc05hbWUgPSAnY29udHJvbHMtY2hlY2tib3gtaW5wdXQnO1xuICAgIGNoZWNrYm94LmNoZWNrZWQgPSB0cnVlO1xuXG4gICAgbGFiZWwuYXBwZW5kQ2hpbGQoY2hlY2tib3gpO1xuICAgIGxhYmVsLmFwcGVuZENoaWxkKHRleHQpO1xuXG4gICAgY29udGFpbmVyLmFwcGVuZENoaWxkKGxhYmVsKTtcblxuICAgIGNvbnN0IHJhbmRvbWl6ZSQgPSBuZXcgUnguQmVoYXZpb3JTdWJqZWN0KHRydWUpO1xuXG4gICAgbGFiZWwuYWRkRXZlbnRMaXN0ZW5lcignY2hhbmdlJywgKGV2dCkgPT4ge1xuICAgICAgICByYW5kb21pemUkLm5leHQoZXZ0LnRhcmdldC5jaGVja2VkKTtcbiAgICB9KTtcblxuICAgIHJldHVybiByYW5kb21pemUkO1xufVxuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIGpzL2NvbnRyb2xzLmpzIl0sIm1hcHBpbmdzIjoiOzs7Ozs7QUFHQTtBQU1BO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBTkE7QUFDQTtBQVFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUEzQ0E7QUFDQTs7O0FBQUE7QUFDQTs7O0FBMkNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJzb3VyY2VSb290IjoiIn0="); /***/ }), /* 32 */ @@ -983,7 +983,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 _rxjs = __webpack_require__(/*! rxjs */ 19);\n\nvar _rxjs2 = _interopRequireDefault(_rxjs);\n\nvar _grid = __webpack_require__(/*! ./grid */ 79);\n\nvar _grid2 = _interopRequireDefault(_grid);\n\nvar _particle = __webpack_require__(/*! ./particle */ 81);\n\nvar _particle2 = _interopRequireDefault(_particle);\n\nvar _controls = __webpack_require__(/*! ./controls */ 31);\n\nvar _controls2 = _interopRequireDefault(_controls);\n\nvar _enums = __webpack_require__(/*! ./enums */ 20);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nfunction Animation(observables, id) {\n this.id = id;\n this.observables = observables;\n this.particles = [];\n\n this.container = document.createElement('div');\n this.container.className = 'animationContainer';\n document.getElementById(id).appendChild(this.container);\n\n this.observables.animating$.subscribe(this.updateAnimating.bind(this));\n this.observables.count$.skip(1).subscribe(this.updateCount.bind(this));\n\n // observables.circle$, PROBABLY WON'T NEED THESE, WILL BE In PARTICLE\n // observables.randomize$,\n // observables.speed$\n\n // this.observables.count$.next(99);\n\n //\n\n // console.warn(\"Mounting Animation\", this.id);\n\n // console.warn('updateAnimating in Animation', isAnimating)\n // this.isAnimating = isAnimating;\n // if (isAnimating) {\n // const fps$ = Rx.Observable.interval(1000 / 32)\n // .takeWhile(_ => this.isAnimating);\n //\n // fps$.subscribe(this.nextFrame.bind(this));\n // }\n\n // this.container = container;\n // this.particles = [];\n // this.isAnimating = false;\n // this.config = config;\n // this.grid = new Grid();\n\n // this.updateAnimating(false);\n // this.updateCircle(config.circleControl);\n // this.updateSpeed(config.speed);\n // this.updateRandomize(this.config.randomizeControl);\n\n // Must be last, after configs all set up and container is fully rendered.\n // this.updateCount(this.config.count);\n}\n\nAnimation.prototype.updateAnimating = function (isAnimating) {\n if (isAnimating === false) {\n return;\n }\n\n var fps$ = _rxjs2.default.Observable.interval(1000 / 32).takeUntil(this.observables.animating$);\n\n fps$.subscribe(this.nextFrame.bind(this));\n};\n\nAnimation.prototype.nextFrame = function () {\n this.particles.forEach(function (p) {\n var prevX = p.arc.endX;\n var prevY = p.arc.endY;\n\n p.nextFrame();\n\n // this.grid.deletePoint({ x: prevX, y: prevY, type: ENTITIES.PARTICLE });\n // this.grid.setPoint({ x: p.arc.endX, y: p.arc.endY, type: ENTITIES.PARTICLE }, p);\n });\n};\n\nAnimation.prototype.updateCount = 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.config, this.grid);\n this.particles.push(_p);\n }\n};\n\nAnimation.prototype.updateSpeed = function (value) {\n // Options must be stored; they are passed to new particles.\n this.config.speed = value;\n this.particles.forEach(function (p) {\n return p.updateConfig({ speed: value });\n });\n};\n\nAnimation.prototype.updateCircle = function (value) {\n this.config.showMovementCircle = value;\n this.particles.forEach(function (p) {\n return p.updateConfig({ showMovementCircle: value });\n });\n};\n\nAnimation.prototype.updateRandomize = function (value) {\n this.config.randomize = value;\n this.particles.forEach(function (p) {\n return p.updateConfig({ randomize: value });\n });\n};\n\nexports.default = Animation;//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNzcuanMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vanMvYW5pbWF0aW9uLmpzPzBiNTMiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IFJ4LCB7IE9ic2VydmFibGUgfSBmcm9tICdyeGpzJztcbmltcG9ydCBHcmlkIGZyb20gJy4vZ3JpZCc7XG5pbXBvcnQgUGFydGljbGUgZnJvbSAnLi9wYXJ0aWNsZSc7XG5pbXBvcnQgQ29udHJvbHMgZnJvbSAnLi9jb250cm9scyc7XG5pbXBvcnQgeyBDT05UUk9MUywgRU5USVRJRVMgfSBmcm9tICcuL2VudW1zJztcblxuZnVuY3Rpb24gQW5pbWF0aW9uKG9ic2VydmFibGVzLCBpZCkge1xuICAgIHRoaXMuaWQgPSBpZDtcbiAgICB0aGlzLm9ic2VydmFibGVzID0gb2JzZXJ2YWJsZXM7XG4gICAgdGhpcy5wYXJ0aWNsZXMgPSBbXTtcblxuICAgIHRoaXMuY29udGFpbmVyID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgdGhpcy5jb250YWluZXIuY2xhc3NOYW1lID0gJ2FuaW1hdGlvbkNvbnRhaW5lcic7XG4gICAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoaWQpLmFwcGVuZENoaWxkKHRoaXMuY29udGFpbmVyKTtcblxuICAgIHRoaXMub2JzZXJ2YWJsZXMuYW5pbWF0aW5nJC5zdWJzY3JpYmUodGhpcy51cGRhdGVBbmltYXRpbmcuYmluZCh0aGlzKSk7XG4gICAgdGhpcy5vYnNlcnZhYmxlcy5jb3VudCQuc2tpcCgxKS5zdWJzY3JpYmUodGhpcy51cGRhdGVDb3VudC5iaW5kKHRoaXMpKTtcblxuICAgIC8vIG9ic2VydmFibGVzLmNpcmNsZSQsICBQUk9CQUJMWSBXT04nVCBORUVEIFRIRVNFLCBXSUxMIEJFIEluIFBBUlRJQ0xFXG4gICAgLy8gb2JzZXJ2YWJsZXMucmFuZG9taXplJCxcbiAgICAvLyBvYnNlcnZhYmxlcy5zcGVlZCRcblxuICAgIC8vIHRoaXMub2JzZXJ2YWJsZXMuY291bnQkLm5leHQoOTkpO1xuXG4gICAgLy88ZGl2IGNsYXNzPSdhbmltYXRpb25Db250YWluZXInPjwvZGl2PlxuXG4gICAgLy8gY29uc29sZS53YXJuKFwiTW91bnRpbmcgQW5pbWF0aW9uXCIsIHRoaXMuaWQpO1xuXG4gICAgLy8gY29uc29sZS53YXJuKCd1cGRhdGVBbmltYXRpbmcgaW4gQW5pbWF0aW9uJywgaXNBbmltYXRpbmcpXG4gICAgLy8gdGhpcy5pc0FuaW1hdGluZyA9IGlzQW5pbWF0aW5nO1xuICAgIC8vIGlmIChpc0FuaW1hdGluZykge1xuICAgIC8vICAgICBjb25zdCBmcHMkID0gUnguT2JzZXJ2YWJsZS5pbnRlcnZhbCgxMDAwIC8gMzIpXG4gICAgLy8gICAgICAgICAudGFrZVdoaWxlKF8gPT4gdGhpcy5pc0FuaW1hdGluZyk7XG4gICAgLy9cbiAgICAvLyAgICAgZnBzJC5zdWJzY3JpYmUodGhpcy5uZXh0RnJhbWUuYmluZCh0aGlzKSk7XG4gICAgLy8gfVxuXG4gICAgLy8gdGhpcy5jb250YWluZXIgPSBjb250YWluZXI7XG4gICAgLy8gdGhpcy5wYXJ0aWNsZXMgPSBbXTtcbiAgICAvLyB0aGlzLmlzQW5pbWF0aW5nID0gZmFsc2U7XG4gICAgLy8gdGhpcy5jb25maWcgPSBjb25maWc7XG4gICAgLy8gdGhpcy5ncmlkID0gbmV3IEdyaWQoKTtcblxuICAgIC8vIHRoaXMudXBkYXRlQW5pbWF0aW5nKGZhbHNlKTtcbiAgICAvLyB0aGlzLnVwZGF0ZUNpcmNsZShjb25maWcuY2lyY2xlQ29udHJvbCk7XG4gICAgLy8gdGhpcy51cGRhdGVTcGVlZChjb25maWcuc3BlZWQpO1xuICAgIC8vIHRoaXMudXBkYXRlUmFuZG9taXplKHRoaXMuY29uZmlnLnJhbmRvbWl6ZUNvbnRyb2wpO1xuXG4gICAgLy8gTXVzdCBiZSBsYXN0LCBhZnRlciBjb25maWdzIGFsbCBzZXQgdXAgYW5kIGNvbnRhaW5lciBpcyBmdWxseSByZW5kZXJlZC5cbiAgICAvLyB0aGlzLnVwZGF0ZUNvdW50KHRoaXMuY29uZmlnLmNvdW50KTtcbn1cblxuQW5pbWF0aW9uLnByb3RvdHlwZS51cGRhdGVBbmltYXRpbmcgPSBmdW5jdGlvbihpc0FuaW1hdGluZykge1xuICAgIGlmIChpc0FuaW1hdGluZyA9PT0gZmFsc2UpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IGZwcyQgPSBSeC5PYnNlcnZhYmxlLmludGVydmFsKDEwMDAgLyAzMilcbiAgICAgICAgLnRha2VVbnRpbCh0aGlzLm9ic2VydmFibGVzLmFuaW1hdGluZyQpO1xuXG4gICAgZnBzJC5zdWJzY3JpYmUodGhpcy5uZXh0RnJhbWUuYmluZCh0aGlzKSk7XG59XG5cbkFuaW1hdGlvbi5wcm90b3R5cGUubmV4dEZyYW1lID0gZnVuY3Rpb24oKSB7XG4gICAgdGhpcy5wYXJ0aWNsZXMuZm9yRWFjaChwID0+IHtcbiAgICAgICAgY29uc3QgcHJldlggPSBwLmFyYy5lbmRYO1xuICAgICAgICBjb25zdCBwcmV2WSA9IHAuYXJjLmVuZFk7XG5cbiAgICAgICAgcC5uZXh0RnJhbWUoKTtcblxuICAgICAgICAvLyB0aGlzLmdyaWQuZGVsZXRlUG9pbnQoeyB4OiBwcmV2WCwgeTogcHJldlksIHR5cGU6IEVOVElUSUVTLlBBUlRJQ0xFIH0pO1xuICAgICAgICAvLyB0aGlzLmdyaWQuc2V0UG9pbnQoeyB4OiBwLmFyYy5lbmRYLCB5OiBwLmFyYy5lbmRZLCB0eXBlOiBFTlRJVElFUy5QQVJUSUNMRSB9LCBwKTtcbiAgICB9KTtcbn1cblxuQW5pbWF0aW9uLnByb3RvdHlwZS51cGRhdGVDb3VudCA9IGZ1bmN0aW9uKGNvdW50KSB7XG4gICAgY29uc3QgYm91bmRzID0gdGhpcy5jb250YWluZXIuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG5cbiAgICB3aGlsZSAodGhpcy5wYXJ0aWNsZXMubGVuZ3RoID4gY291bnQpIHtcbiAgICAgICAgY29uc3QgcCA9IHRoaXMucGFydGljbGVzLnBvcCgpO1xuICAgICAgICBwLnJlbW92ZSgpO1xuICAgIH1cblxuICAgIHdoaWxlICh0aGlzLnBhcnRpY2xlcy5sZW5ndGggPCBjb3VudCkge1xuICAgICAgICBjb25zdCBwID0gbmV3IFBhcnRpY2xlKHRoaXMuY29udGFpbmVyLCBib3VuZHMsIHRoaXMuY29uZmlnLCB0aGlzLmdyaWQpO1xuICAgICAgICB0aGlzLnBhcnRpY2xlcy5wdXNoKHApO1xuICAgIH1cbn1cblxuQW5pbWF0aW9uLnByb3RvdHlwZS51cGRhdGVTcGVlZCA9IGZ1bmN0aW9uKHZhbHVlKSB7XG4gICAgLy8gT3B0aW9ucyBtdXN0IGJlIHN0b3JlZDsgdGhleSBhcmUgcGFzc2VkIHRvIG5ldyBwYXJ0aWNsZXMuXG4gICAgdGhpcy5jb25maWcuc3BlZWQgPSB2YWx1ZTtcbiAgICB0aGlzLnBhcnRpY2xlcy5mb3JFYWNoKHAgPT4gcC51cGRhdGVDb25maWcoeyBzcGVlZDogdmFsdWUgfSkpO1xufVxuXG5BbmltYXRpb24ucHJvdG90eXBlLnVwZGF0ZUNpcmNsZSA9IGZ1bmN0aW9uKHZhbHVlKSB7XG4gICAgdGhpcy5jb25maWcuc2hvd01vdmVtZW50Q2lyY2xlID0gdmFsdWU7XG4gICAgdGhpcy5wYXJ0aWNsZXMuZm9yRWFjaChwID0+IHAudXBkYXRlQ29uZmlnKHsgc2hvd01vdmVtZW50Q2lyY2xlOiB2YWx1ZSB9KSk7XG59XG5cbkFuaW1hdGlvbi5wcm90b3R5cGUudXBkYXRlUmFuZG9taXplID0gZnVuY3Rpb24odmFsdWUpIHtcbiAgICB0aGlzLmNvbmZpZy5yYW5kb21pemUgPSB2YWx1ZTtcbiAgICB0aGlzLnBhcnRpY2xlcy5mb3JFYWNoKHAgPT4gcC51cGRhdGVDb25maWcoeyByYW5kb21pemU6IHZhbHVlIH0pKTtcbn1cblxuZXhwb3J0IGRlZmF1bHQgQW5pbWF0aW9uO1xuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIGpzL2FuaW1hdGlvbi5qcyJdLCJtYXBwaW5ncyI6Ijs7Ozs7O0FBQUE7QUFDQTs7O0FBQUE7QUFDQTs7O0FBQUE7QUFDQTs7O0FBQUE7QUFDQTs7O0FBQUE7QUFDQTs7O0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBIiwic291cmNlUm9vdCI6IiJ9"); +eval("\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nvar _rxjs = __webpack_require__(/*! rxjs */ 19);\n\nvar _rxjs2 = _interopRequireDefault(_rxjs);\n\nvar _grid = __webpack_require__(/*! ./grid */ 79);\n\nvar _grid2 = _interopRequireDefault(_grid);\n\nvar _particle = __webpack_require__(/*! ./particle */ 81);\n\nvar _particle2 = _interopRequireDefault(_particle);\n\nvar _controls = __webpack_require__(/*! ./controls */ 31);\n\nvar _controls2 = _interopRequireDefault(_controls);\n\nvar _enums = __webpack_require__(/*! ./enums */ 20);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nfunction Animation(observables, id) {\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\nexports.default = Animation;//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNzcuanMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vanMvYW5pbWF0aW9uLmpzPzBiNTMiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IFJ4LCB7IE9ic2VydmFibGUgfSBmcm9tICdyeGpzJztcbmltcG9ydCBHcmlkIGZyb20gJy4vZ3JpZCc7XG5pbXBvcnQgUGFydGljbGUgZnJvbSAnLi9wYXJ0aWNsZSc7XG5pbXBvcnQgQ29udHJvbHMgZnJvbSAnLi9jb250cm9scyc7XG5pbXBvcnQgeyBDT05UUk9MUywgRU5USVRJRVMgfSBmcm9tICcuL2VudW1zJztcblxuZnVuY3Rpb24gQW5pbWF0aW9uKG9ic2VydmFibGVzLCBpZCkge1xuICAgIHRoaXMuaWQgPSBpZDtcbiAgICB0aGlzLm9ic2VydmFibGVzID0gb2JzZXJ2YWJsZXM7XG4gICAgdGhpcy5wYXJ0aWNsZXMgPSBbXTtcbiAgICB0aGlzLmdyaWQgPSBuZXcgR3JpZCgpO1xuICAgIHRoaXMuZnBzSW50ZXJ2YWwgPSBudWxsO1xuXG4gICAgdGhpcy5jb250YWluZXIgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICB0aGlzLmNvbnRhaW5lci5jbGFzc05hbWUgPSAnYW5pbWF0aW9uQ29udGFpbmVyJztcbiAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChpZCkuYXBwZW5kQ2hpbGQodGhpcy5jb250YWluZXIpO1xuXG4gICAgdGhpcy5vYnNlcnZhYmxlcy5jb3VudCQuc2tpcCgxKS5zdWJzY3JpYmUodGhpcy5zdWJzY3JpYmVDb3VudC5iaW5kKHRoaXMpKTtcbiAgICB0aGlzLm9ic2VydmFibGVzLmFuaW1hdGluZyQuc3Vic2NyaWJlKHRoaXMuc3Vic2NyaWJlQW5pbWF0aW5nLmJpbmQodGhpcykpO1xufVxuXG5BbmltYXRpb24ucHJvdG90eXBlLnN1YnNjcmliZUFuaW1hdGluZyA9IGZ1bmN0aW9uKGlzQW5pbWF0aW5nKSB7XG4gICAgaWYgKGlzQW5pbWF0aW5nID09PSBmYWxzZSkge1xuICAgICAgICBjbGVhckludGVydmFsKHRoaXMuZnBzSW50ZXJ2YWwpO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIGNvbnN0IHsgZnBzJCB9ID0gdGhpcy5vYnNlcnZhYmxlcztcbiAgICAgICAgdGhpcy5mcHNJbnRlcnZhbCA9IHNldEludGVydmFsKGZwcyQubmV4dC5iaW5kKGZwcyQpLCAxMDAwIC8gMzIpO1xuICAgIH1cbn1cblxuQW5pbWF0aW9uLnByb3RvdHlwZS5zdWJzY3JpYmVDb3VudCA9IGZ1bmN0aW9uKGNvdW50KSB7XG4gICAgY29uc3QgYm91bmRzID0gdGhpcy5jb250YWluZXIuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG5cbiAgICB3aGlsZSAodGhpcy5wYXJ0aWNsZXMubGVuZ3RoID4gY291bnQpIHtcbiAgICAgICAgY29uc3QgcCA9IHRoaXMucGFydGljbGVzLnBvcCgpO1xuICAgICAgICBwLnJlbW92ZSgpO1xuICAgIH1cblxuICAgIHdoaWxlICh0aGlzLnBhcnRpY2xlcy5sZW5ndGggPCBjb3VudCkge1xuICAgICAgICBjb25zdCBwID0gbmV3IFBhcnRpY2xlKHRoaXMuY29udGFpbmVyLCBib3VuZHMsIHRoaXMuZ3JpZCwgdGhpcy5vYnNlcnZhYmxlcyk7XG4gICAgICAgIHRoaXMucGFydGljbGVzLnB1c2gocCk7XG4gICAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBBbmltYXRpb247XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8ganMvYW5pbWF0aW9uLmpzIl0sIm1hcHBpbmdzIjoiOzs7Ozs7QUFBQTtBQUNBOzs7QUFBQTtBQUNBOzs7QUFBQTtBQUNBOzs7QUFBQTtBQUNBOzs7QUFBQTtBQUNBOzs7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZVJvb3QiOiIifQ=="); /***/ }), /* 78 */ @@ -1019,7 +1019,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 */ 19);\n\nvar _rxjs2 = _interopRequireDefault(_rxjs);\n\nvar _animation1a = __webpack_require__(/*! ./animation1a */ 360);\n\nvar _animation1a2 = _interopRequireDefault(_animation1a);\n\nvar _animation1b = __webpack_require__(/*! ./animation1b */ 361);\n\nvar _animation1b2 = _interopRequireDefault(_animation1b);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\n// import Container1b from './container1b';\n// import Container2a from './container2a';\n// import Container2b from './container2b';\n// import Container3a from './container3a';\n\n__webpack_require__(/*! ../css/reset.scss */ 76);\n__webpack_require__(/*! ../css/index.scss */ 74);\n__webpack_require__(/*! ../css/particle.scss */ 75);\n__webpack_require__(/*! ../css/controls.scss */ 73);\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});\n\n// TODO remove bottom padding from Disqus\n// TODO fix \"hangup\" small radius evade bug\n// TODO don't load simulation until requested\n// TODO sort out particle nextframe\n// TODO subscriber on bounds change\n// TODO abs positioning on controls elements so order doesn't matter\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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiODAuanMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vanMvaW5kZXguanM/NDJmNiJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgUngsIHsgT2JzZXJ2YWJsZSB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IEFuaW1hdGlvbjFhIGZyb20gJy4vYW5pbWF0aW9uMWEnO1xuaW1wb3J0IEFuaW1hdGlvbjFiIGZyb20gJy4vYW5pbWF0aW9uMWInO1xuLy8gaW1wb3J0IENvbnRhaW5lcjFiIGZyb20gJy4vY29udGFpbmVyMWInO1xuLy8gaW1wb3J0IENvbnRhaW5lcjJhIGZyb20gJy4vY29udGFpbmVyMmEnO1xuLy8gaW1wb3J0IENvbnRhaW5lcjJiIGZyb20gJy4vY29udGFpbmVyMmInO1xuLy8gaW1wb3J0IENvbnRhaW5lcjNhIGZyb20gJy4vY29udGFpbmVyM2EnO1xuXG5yZXF1aXJlKCcuLi9jc3MvcmVzZXQuc2NzcycpO1xucmVxdWlyZSgnLi4vY3NzL2luZGV4LnNjc3MnKTtcbnJlcXVpcmUoJy4uL2Nzcy9wYXJ0aWNsZS5zY3NzJyk7XG5yZXF1aXJlKCcuLi9jc3MvY29udHJvbHMuc2NzcycpO1xuXG53aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcignbG9hZCcsICgpID0+IHtcbiAgICBjb25zdCBkZXN0cm95JCA9IG5ldyBSeC5CZWhhdmlvclN1YmplY3QobnVsbCk7XG5cbiAgICBBbmltYXRpb24xYShkZXN0cm95JCk7XG4gICAgQW5pbWF0aW9uMWIoZGVzdHJveSQpO1xufSk7XG5cbi8vIFRPRE8gcmVtb3ZlIGJvdHRvbSBwYWRkaW5nIGZyb20gRGlzcXVzXG4vLyBUT0RPIGZpeCBcImhhbmd1cFwiIHNtYWxsIHJhZGl1cyBldmFkZSBidWdcbi8vIFRPRE8gZG9uJ3QgbG9hZCBzaW11bGF0aW9uIHVudGlsIHJlcXVlc3RlZFxuLy8gVE9ETyBzb3J0IG91dCBwYXJ0aWNsZSBuZXh0ZnJhbWVcbi8vIFRPRE8gc3Vic2NyaWJlciBvbiBib3VuZHMgY2hhbmdlXG4vLyBUT0RPIGFicyBwb3NpdGlvbmluZyBvbiBjb250cm9scyBlbGVtZW50cyBzbyBvcmRlciBkb2Vzbid0IG1hdHRlclxuXG4vLyBUT0RPIEFOSU0xYWIgZnJlZSBtb3ZlbWVudFxuXG4vLyBUT0RPIEFOSU0zYSBzdHJlYW1saW5lIHVwZGF0ZUxlYWRlclxuLy8gVE9ETyBBTklNM2Igc2VwYXJhdGlvblxuLy8gVE9ETyBBTklNM2MgYWxpZ25tZW50XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8ganMvaW5kZXguanMiXSwibWFwcGluZ3MiOiI7O0FBQUE7QUFDQTs7O0FBQUE7QUFDQTs7O0FBQUE7QUFDQTs7Ozs7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwic291cmNlUm9vdCI6IiJ9"); +eval("\n\nvar _rxjs = __webpack_require__(/*! rxjs */ 19);\n\nvar _rxjs2 = _interopRequireDefault(_rxjs);\n\nvar _animation1a = __webpack_require__(/*! ./animation1a */ 360);\n\nvar _animation1a2 = _interopRequireDefault(_animation1a);\n\nvar _animation1b = __webpack_require__(/*! ./animation1b */ 361);\n\nvar _animation1b2 = _interopRequireDefault(_animation1b);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\n// import Container1b from './container1b';\n// import Container2a from './container2a';\n// import Container2b from './container2b';\n// import Container3a from './container3a';\n\n__webpack_require__(/*! ../css/reset.scss */ 76);\n__webpack_require__(/*! ../css/index.scss */ 74);\n__webpack_require__(/*! ../css/particle.scss */ 75);\n__webpack_require__(/*! ../css/controls.scss */ 73);\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});\n\n// TODO remove bottom padding from Disqus\n// TODO fix \"hangup\" small radius evade bug\n// TODO don't load simulation until requested\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\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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiODAuanMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vanMvaW5kZXguanM/NDJmNiJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgUngsIHsgT2JzZXJ2YWJsZSB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IEFuaW1hdGlvbjFhIGZyb20gJy4vYW5pbWF0aW9uMWEnO1xuaW1wb3J0IEFuaW1hdGlvbjFiIGZyb20gJy4vYW5pbWF0aW9uMWInO1xuLy8gaW1wb3J0IENvbnRhaW5lcjFiIGZyb20gJy4vY29udGFpbmVyMWInO1xuLy8gaW1wb3J0IENvbnRhaW5lcjJhIGZyb20gJy4vY29udGFpbmVyMmEnO1xuLy8gaW1wb3J0IENvbnRhaW5lcjJiIGZyb20gJy4vY29udGFpbmVyMmInO1xuLy8gaW1wb3J0IENvbnRhaW5lcjNhIGZyb20gJy4vY29udGFpbmVyM2EnO1xuXG5yZXF1aXJlKCcuLi9jc3MvcmVzZXQuc2NzcycpO1xucmVxdWlyZSgnLi4vY3NzL2luZGV4LnNjc3MnKTtcbnJlcXVpcmUoJy4uL2Nzcy9wYXJ0aWNsZS5zY3NzJyk7XG5yZXF1aXJlKCcuLi9jc3MvY29udHJvbHMuc2NzcycpO1xuXG53aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcignbG9hZCcsICgpID0+IHtcbiAgICBjb25zdCBkZXN0cm95JCA9IG5ldyBSeC5CZWhhdmlvclN1YmplY3QobnVsbCk7XG5cbiAgICBBbmltYXRpb24xYShkZXN0cm95JCk7XG4gICAgQW5pbWF0aW9uMWIoZGVzdHJveSQpO1xufSk7XG5cbi8vIFRPRE8gcmVtb3ZlIGJvdHRvbSBwYWRkaW5nIGZyb20gRGlzcXVzXG4vLyBUT0RPIGZpeCBcImhhbmd1cFwiIHNtYWxsIHJhZGl1cyBldmFkZSBidWdcbi8vIFRPRE8gZG9uJ3QgbG9hZCBzaW11bGF0aW9uIHVudGlsIHJlcXVlc3RlZFxuLy8gVE9ETyBzb3J0IG91dCBwYXJ0aWNsZSBuZXh0ZnJhbWVcbi8vIFRPRE8gYWJzIHBvc2l0aW9uaW5nIG9uIGNvbnRyb2xzIGVsZW1lbnRzIHNvIG9yZGVyIGRvZXNuJ3QgbWF0dGVyXG4vLyBUT0RPIEJlaGF2aW9yU3ViamVjdCBsaXN0ZW5lciBvbiBib3VuZHMgY2hhbmdlXG5cbi8vIFRPRE8gQU5JTTFhYiBmcmVlIG1vdmVtZW50XG5cbi8vIFRPRE8gQU5JTTNhIHN0cmVhbWxpbmUgdXBkYXRlTGVhZGVyXG4vLyBUT0RPIEFOSU0zYiBzZXBhcmF0aW9uXG4vLyBUT0RPIEFOSU0zYyBhbGlnbm1lbnRcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyBqcy9pbmRleC5qcyJdLCJtYXBwaW5ncyI6Ijs7QUFBQTtBQUNBOzs7QUFBQTtBQUNBOzs7QUFBQTtBQUNBOzs7OztBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJzb3VyY2VSb290IjoiIn0="); /***/ }), /* 81 */ @@ -1031,7 +1031,7 @@ eval("\n\nvar _rxjs = __webpack_require__(/*! rxjs */ 19);\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 */ 19);\n\nvar _rxjs2 = _interopRequireDefault(_rxjs);\n\nvar _enums = __webpack_require__(/*! ./enums */ 20);\n\nvar _arc = __webpack_require__(/*! ./arc */ 78);\n\nvar _arc2 = _interopRequireDefault(_arc);\n\nvar _random = __webpack_require__(/*! ./random */ 40);\n\nvar _random2 = _interopRequireDefault(_random);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nvar baseConfig = {\n behavior: _enums.BEHAVIOR.COHESION,\n bounds: {},\n color: 'red',\n gridSize: 5,\n randomize: true,\n showArc: false,\n showVision: false,\n speed: 4,\n visionRadius: 50\n};\n\n// ===== Constructor =====\n\nfunction Particle(parent, bounds, config, globalGrid) {\n this.config = Object.assign({}, baseConfig, config);\n this.config.color = _random2.default.color();\n // this.config.bounds = bounds;\n\n this.grids = {\n global: globalGrid || {},\n vision: createVisionGrid(this.config)\n };\n\n this.id = _random2.default.id(6);\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.updateConfig(this.config);\n // this.grids.global.setPoint({ x: p.arc.endX, y: p.arc.endY, type: ENTITIES.PARTICLE }, p);\n // this.nextFrame(globalGrid);\n};\n\n// ===== PROTOTYPE =====\n\nParticle.prototype.remove = function () {\n // this.grids.globals.deletePoint({ x: p.arc.endX, y: p.arc.endY, type: ENTITIES.PARTICLE });\n\n var parent = this.nodes.container.parentNode;\n parent.removeChild(this.nodes.container);\n\n delete this.nodes;\n return this;\n};\n\nParticle.prototype.nextFrame = function () {\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 // const { hazards, particles } = look(this.arc, this.grids);\n //\n // if (hazards.length > 0) {\n // this.arc = Arc.evade(this.arc);\n // }\n //\n // this.updateLeader(particles);\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.subscriber = function (_ref) {\n var key = _ref.key,\n value = _ref.value;\n};\n\nParticle.prototype.updateConfig = function (config) {\n // Object.assign(this.config, config);\n //\n // const { showArc, showVision } = this.config;\n //\n // if (showArc === true && this.nodes.circle === undefined) {\n // this.nodes.circle = createCircleNode(this.config);\n // this.nodes.container.appendChild(this.nodes.circle);\n // }\n //\n // if (showArc === false && this.nodes.circle !== undefined) {\n // this.nodes.container.removeChild(this.nodes.circle);\n // delete this.nodes.circle;\n // }\n //\n // if (showVision === true && this.nodes.visionGrid === undefined) {\n // this.nodes.visionGrid = createVisionGridNodes(this.config, this.grids, this.nodes);\n // }\n //\n // if (showVision === false && this.nodes.visionGrid !== undefined) {\n // delete this.nodex.visionGrid;\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 if (config.showArc === false) {\n return undefined;\n }\n\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 if (config.showVision === false) {\n return undefined;\n }\n\n return grids.vision.reduce(function (acc, _ref2) {\n var x = _ref2.x,\n y = _ref2.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 (_ref3, i) {\n var x = _ref3.x,\n y = _ref3.y,\n touch = _ref3.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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiODEuanMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vanMvcGFydGljbGUuanM/M2JkZSJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgUngsIHsgT2JzZXJ2YWJsZSB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgQkVIQVZJT1IsIEVOVElUSUVTLCBSQUQgfSBmcm9tICcuL2VudW1zJztcbmltcG9ydCBBcmMgZnJvbSAnLi9hcmMnO1xuaW1wb3J0IFJhbmRvbSBmcm9tICcuL3JhbmRvbSc7XG5cbmNvbnN0IGJhc2VDb25maWcgPSB7XG4gICAgYmVoYXZpb3I6IEJFSEFWSU9SLkNPSEVTSU9OLFxuICAgIGJvdW5kczoge30sXG4gICAgY29sb3I6ICdyZWQnLFxuICAgIGdyaWRTaXplOiA1LFxuICAgIHJhbmRvbWl6ZTogdHJ1ZSxcbiAgICBzaG93QXJjOiBmYWxzZSxcbiAgICBzaG93VmlzaW9uOiBmYWxzZSxcbiAgICBzcGVlZDogNCxcbiAgICB2aXNpb25SYWRpdXM6IDUwXG59O1xuXG4vLyA9PT09PSBDb25zdHJ1Y3RvciA9PT09PVxuXG5mdW5jdGlvbiBQYXJ0aWNsZShwYXJlbnQsIGJvdW5kcywgY29uZmlnLCBnbG9iYWxHcmlkKSB7XG4gICAgdGhpcy5jb25maWcgPSBPYmplY3QuYXNzaWduKHt9LCBiYXNlQ29uZmlnLCBjb25maWcpO1xuICAgIHRoaXMuY29uZmlnLmNvbG9yID0gUmFuZG9tLmNvbG9yKCk7XG4gICAgLy8gdGhpcy5jb25maWcuYm91bmRzID0gYm91bmRzO1xuXG4gICAgdGhpcy5ncmlkcyA9IHtcbiAgICAgICAgZ2xvYmFsOiBnbG9iYWxHcmlkIHx8IHt9LFxuICAgICAgICB2aXNpb246IGNyZWF0ZVZpc2lvbkdyaWQodGhpcy5jb25maWcpXG4gICAgfTtcblxuICAgIHRoaXMuaWQgPSBSYW5kb20uaWQoNik7XG5cbiAgICB0aGlzLm5vZGVzID0ge1xuICAgICAgICBib2R5OiBjcmVhdGVCb2R5Tm9kZSh0aGlzLmNvbmZpZyksXG4gICAgICAgIGNpcmNsZTogdW5kZWZpbmVkLFxuICAgICAgICBjb250YWluZXI6IGNyZWF0ZUNvbnRhaW5lck5vZGUodGhpcy5jb25maWcsIHRoaXMuaWQpLFxuICAgICAgICB2aXNpb25HcmlkOiB1bmRlZmluZWQsXG4gICAgfTtcblxuICAgIHRoaXMubm9kZXMuY29udGFpbmVyLmFwcGVuZENoaWxkKHRoaXMubm9kZXMuYm9keSk7XG4gICAgcGFyZW50LmFwcGVuZENoaWxkKHRoaXMubm9kZXMuY29udGFpbmVyKTtcblxuICAgIHRoaXMubGVhZGVyID0gbnVsbDtcbiAgICB0aGlzLmlzTGVhZGVyID0gZmFsc2U7XG5cbiAgICB0aGlzLmFyYyA9IEFyYy5jcmVhdGUoYm91bmRzLCB0aGlzLmdyaWRzLmdsb2JhbCk7XG4gICAgLy8gdGhpcy51cGRhdGVDb25maWcodGhpcy5jb25maWcpO1xuICAgIC8vIHRoaXMuZ3JpZHMuZ2xvYmFsLnNldFBvaW50KHsgeDogcC5hcmMuZW5kWCwgeTogcC5hcmMuZW5kWSwgdHlwZTogRU5USVRJRVMuUEFSVElDTEUgfSwgcCk7XG4gICAgLy8gdGhpcy5uZXh0RnJhbWUoZ2xvYmFsR3JpZCk7XG4gICAgXG59O1xuXG4vLyA9PT09PSBQUk9UT1RZUEUgPT09PT1cblxuUGFydGljbGUucHJvdG90eXBlLnJlbW92ZSA9IGZ1bmN0aW9uKCkge1xuICAgIC8vIHRoaXMuZ3JpZHMuZ2xvYmFscy5kZWxldGVQb2ludCh7IHg6IHAuYXJjLmVuZFgsIHk6IHAuYXJjLmVuZFksIHR5cGU6IEVOVElUSUVTLlBBUlRJQ0xFIH0pO1xuXG4gICAgY29uc3QgcGFyZW50ID0gdGhpcy5ub2Rlcy5jb250YWluZXIucGFyZW50Tm9kZTtcbiAgICBwYXJlbnQucmVtb3ZlQ2hpbGQodGhpcy5ub2Rlcy5jb250YWluZXIpO1xuXG4gICAgZGVsZXRlIHRoaXMubm9kZXM7XG4gICAgcmV0dXJuIHRoaXM7XG59XG5cblBhcnRpY2xlLnByb3RvdHlwZS5uZXh0RnJhbWUgPSBmdW5jdGlvbigpIHtcbiAgICAvLyB0aGlzLmFyYyA9IEFyYy5nb3RvKHRoaXMuYXJjLCAyMDAsIDIwMCwgdGhpcy5jb25maWcuc3BlZWQpXG5cbiAgICB0aGlzLmFyYyA9IEFyYy5zdGVwKHRoaXMuYXJjLCB0aGlzLmNvbmZpZy5ib3VuZHMsIHRoaXMuY29uZmlnLnNwZWVkKTtcblxuICAgIGlmICh0aGlzLmxlYWRlciAhPT0gbnVsbCkge1xuICAgICAgICB0aGlzLmFyYyA9IEFyYy5mb2xsb3codGhpcy5hcmMsIHRoaXMubGVhZGVyLmFyYyk7XG4gICAgfSBlbHNlIGlmICh0aGlzLmFyYy5sZW5ndGggPD0gMCAmJiB0aGlzLmNvbmZpZy5yYW5kb21pemUpIHtcbiAgICAgICAgdGhpcy5hcmMgPSBBcmMucmFuZG9taXplKHRoaXMuYXJjKTtcbiAgICB9XG5cbiAgICAvLyB0aGlzLmdyaWRzLnZpc2lvbiA9IHVwZGF0ZVZpc2lvbkdyaWQodGhpcy5hcmMsIHRoaXMuY29uZmlnLCB0aGlzLmdyaWRzKTtcbiAgICAvLyBjb25zdCB7IGhhemFyZHMsIHBhcnRpY2xlcyB9ID0gbG9vayh0aGlzLmFyYywgdGhpcy5ncmlkcyk7XG4gICAgLy9cbiAgICAvLyBpZiAoaGF6YXJkcy5sZW5ndGggPiAwKSB7XG4gICAgLy8gICAgIHRoaXMuYXJjID0gQXJjLmV2YWRlKHRoaXMuYXJjKTtcbiAgICAvLyB9XG4gICAgLy9cbiAgICAvLyB0aGlzLnVwZGF0ZUxlYWRlcihwYXJ0aWNsZXMpO1xuXG4gICAgcmVwYWludENvbnRhaW5lcih0aGlzLm5vZGVzLmNvbnRhaW5lciwgdGhpcy5hcmMpO1xuICAgIHJlcGFpbnRCb2R5KHRoaXMubm9kZXMuYm9keSwgdGhpcy5hcmMsIHRoaXMuaXNMZWFkZXIpO1xuICAgIHJlcGFpbnRDaXJjbGUodGhpcy5ub2Rlcy5jaXJjbGUsIHRoaXMuYXJjKTtcbiAgICByZXBhaW50VmlzaW9uR3JpZCh0aGlzLm5vZGVzLnZpc2lvbkdyaWQsIHRoaXMuYXJjLCB0aGlzLmdyaWRzKTtcbn1cblxuUGFydGljbGUucHJvdG90eXBlLnN1YnNjcmliZXIgPSBmdW5jdGlvbih7IGtleSwgdmFsdWUgfSkge1xuXG59XG5cblBhcnRpY2xlLnByb3RvdHlwZS51cGRhdGVDb25maWcgPSBmdW5jdGlvbihjb25maWcpIHtcbi8vICAgICBPYmplY3QuYXNzaWduKHRoaXMuY29uZmlnLCBjb25maWcpO1xuLy9cbi8vICAgICBjb25zdCB7IHNob3dBcmMsIHNob3dWaXNpb24gfSA9IHRoaXMuY29uZmlnO1xuLy9cbi8vICAgICBpZiAoc2hvd0FyYyA9PT0gdHJ1ZSAmJiB0aGlzLm5vZGVzLmNpcmNsZSA9PT0gdW5kZWZpbmVkKSB7XG4vLyAgICAgICAgIHRoaXMubm9kZXMuY2lyY2xlID0gY3JlYXRlQ2lyY2xlTm9kZSh0aGlzLmNvbmZpZyk7XG4vLyAgICAgICAgIHRoaXMubm9kZXMuY29udGFpbmVyLmFwcGVuZENoaWxkKHRoaXMubm9kZXMuY2lyY2xlKTtcbi8vICAgICB9XG4vL1xuLy8gICAgIGlmIChzaG93QXJjID09PSBmYWxzZSAmJiB0aGlzLm5vZGVzLmNpcmNsZSAhPT0gdW5kZWZpbmVkKSB7XG4vLyAgICAgICAgIHRoaXMubm9kZXMuY29udGFpbmVyLnJlbW92ZUNoaWxkKHRoaXMubm9kZXMuY2lyY2xlKTtcbi8vICAgICAgICAgZGVsZXRlIHRoaXMubm9kZXMuY2lyY2xlO1xuLy8gICAgIH1cbi8vXG4vLyAgICAgaWYgKHNob3dWaXNpb24gPT09IHRydWUgJiYgdGhpcy5ub2Rlcy52aXNpb25HcmlkID09PSB1bmRlZmluZWQpIHtcbi8vICAgICAgICAgdGhpcy5ub2Rlcy52aXNpb25HcmlkID0gY3JlYXRlVmlzaW9uR3JpZE5vZGVzKHRoaXMuY29uZmlnLCB0aGlzLmdyaWRzLCB0aGlzLm5vZGVzKTtcbi8vICAgICB9XG4vL1xuLy8gICAgIGlmIChzaG93VmlzaW9uID09PSBmYWxzZSAmJiB0aGlzLm5vZGVzLnZpc2lvbkdyaWQgIT09IHVuZGVmaW5lZCkge1xuLy8gICAgICAgICBkZWxldGUgdGhpcy5ub2RleC52aXNpb25HcmlkO1xuLy8gICAgIH1cbn1cblxuUGFydGljbGUucHJvdG90eXBlLnVwZGF0ZUxlYWRlciA9IGZ1bmN0aW9uKHBhcnRpY2xlcykge1xuICAgIGlmICh0aGlzLmNvbmZpZy5iZWhhdmlvciAhPT0gQkVIQVZJT1IuQ09IRVNJT04pIHtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmICh0aGlzLmxlYWRlciA9PT0gbnVsbCAmJiBwYXJ0aWNsZXMubGVuZ3RoID4gMCkge1xuICAgICAgICAvLyBIZWFkLXRvLWhlYWQ6IHBhcnRpY2xlcyBzZWUgZWFjaG90aGVyIGJ1dCBzaG91bGRuJ3QgYm90aCBsZWFkLlxuICAgICAgICBjb25zdCBjYW5kaWRhdGVzID0gcGFydGljbGVzXG4gICAgICAgICAgICAuZmlsdGVyKHYgPT4gdi5sZWFkZXIgPyAodi5sZWFkZXIuaWQgIT09IHRoaXMuaWQpIDogdHJ1ZSk7XG5cbiAgICAgICAgY29uc3QgbGVhZGVyID0gY2FuZGlkYXRlcy5maW5kKHYgPT4gdi5pc0xlYWRlcikgfHwgY2FuZGlkYXRlc1swXTtcblxuICAgICAgICBpZiAobGVhZGVyICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIGxlYWRlci5pc0xlYWRlciA9IHRydWU7XG4gICAgICAgICAgICB0aGlzLmxlYWRlciA9IGxlYWRlcjtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGlmICh0aGlzLmxlYWRlciA9PT0gbnVsbCkge1xuICAgICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKHRoaXMubGVhZGVyLm5vZGVzID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgdGhpcy5sZWFkZXIgPSBudWxsO1xuICAgICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKHRoaXMubGVhZGVyLmxlYWRlciAhPT0gbnVsbCkge1xuICAgICAgICB0aGlzLmxlYWRlciA9IHRoaXMubGVhZGVyLmxlYWRlcjtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5pc0xlYWRlcikge1xuICAgICAgICB0aGlzLmlzTGVhZGVyID0gZmFsc2U7XG4gICAgfVxuXG4gICAgLy8gQmV3YXJlIG9mIGNpcmN1bGFyIGxlYWRlcnNoaXAsIHdoZXJlIGEgbGVhZGVyIHNlZXMgaXRzIHRhaWwuXG4gICAgaWYgKHRoaXMubGVhZGVyLmlkID09PSB0aGlzLmlkKSB7XG4gICAgICAgIHRoaXMubGVhZGVyID0gbnVsbDtcbiAgICB9XG59XG5cbmZ1bmN0aW9uIGxvb2soYXJjLCBncmlkcykge1xuICAgIGNvbnN0IHsgZ2xvYmFsLCB2aXNpb24gfSA9IGdyaWRzO1xuXG4gICAgcmV0dXJuIHZpc2lvbi5yZWR1Y2UoKGFjYywgcG9pbnQpID0+IHtcbiAgICAgICAgY29uc3QgeCA9IGFyYy5lbmRYICsgcG9pbnQueDtcbiAgICAgICAgY29uc3QgeSA9IGFyYy5lbmRZICsgcG9pbnQueTtcbiAgICAgICAgY29uc3QgcCA9IGdsb2JhbC5nZXRQb2ludCh7IHgsIHksIHR5cGU6IEVOVElUSUVTLlBBUlRJQ0xFIH0pO1xuXG4gICAgICAgIGlmIChwKSB7XG4gICAgICAgICAgICBhY2MucGFydGljbGVzLnB1c2gocCk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoZ2xvYmFsLmdldFBvaW50KHsgeCwgeSwgdHlwZTogRU5USVRJRVMuSEFaQVJEIH0pKSB7XG4gICAgICAgICAgICBhY2MuaGF6YXJkcy5wdXNoKHsgeCwgeSB9KTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBhY2M7XG4gICAgfSwgeyBoYXphcmRzOiBbXSwgcGFydGljbGVzOiBbXSB9KTtcbn1cblxuLy8gPT09PT0gRE9NIENSRUFUSU9OID09PT09XG5cbmZ1bmN0aW9uIGNyZWF0ZUJvZHlOb2RlKGNvbmZpZykge1xuICAgIGNvbnN0IG5vZGUgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICBub2RlLmNsYXNzTmFtZSA9ICdwYXJ0aWNsZS1ib2R5JztcbiAgICBub2RlLnN0eWxlLmJhY2tncm91bmRDb2xvciA9IGNvbmZpZy5jb2xvcjtcbiAgICByZXR1cm4gbm9kZTtcbn1cblxuZnVuY3Rpb24gY3JlYXRlQ2lyY2xlTm9kZShjb25maWcpIHtcbiAgICBpZiAoY29uZmlnLnNob3dBcmMgPT09IGZhbHNlKSB7XG4gICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgfVxuXG4gICAgY29uc3Qgbm9kZSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgIG5vZGUuY2xhc3NOYW1lID0gJ3BhcnRpY2xlLW1vdmVtZW50LWNpcmNsZSc7XG4gICAgbm9kZS5zdHlsZS5ib3JkZXJDb2xvciA9IGNvbmZpZy5jb2xvcjtcbiAgICByZXR1cm4gbm9kZTtcbn1cblxuZnVuY3Rpb24gY3JlYXRlQ29udGFpbmVyTm9kZShjb25maWcsIGlkKSB7XG4gICAgY29uc3Qgbm9kZSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgIG5vZGUuY2xhc3NOYW1lID0gJ3BhcnRpY2xlLWNvbnRhaW5lcic7XG4gICAgbm9kZS5pZCA9IGlkO1xuICAgIHJldHVybiBub2RlO1xufVxuXG5mdW5jdGlvbiBjcmVhdGVWaXNpb25HcmlkKGNvbmZpZykge1xuICAgIGNvbnN0IHsgZ3JpZFNpemU6IHNpZGUsIHZpc2lvblJhZGl1czogcmFkaXVzIH0gPSBjb25maWc7XG4gICAgY29uc3QgcjAgPSByYWRpdXM7XG4gICAgY29uc3QgcjEgPSA0NTtcblxuICAgIGNvbnN0IHBvaW50cyA9IFtdO1xuXG4gICAgZm9yIChsZXQgeCA9IC1yYWRpdXM7IHggPD0gcmFkaXVzOyB4ICs9IHNpZGUpIHtcbiAgICAgICAgZm9yIChsZXQgeSA9IC1yYWRpdXM7IHkgPD0gcmFkaXVzOyB5ICs9IHNpZGUpIHtcbiAgICAgICAgICAgIC8vIE9taXQgbGFyZ2Ugc2xpY2VzIG9mIHVudXNlZCBjaXJjbGVcbiAgICAgICAgICAgIGlmICh4ID4geSB8fCB4IDwgLXkpIHtcbiAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gSW5jbHVkZSB2aXNpb24gYmFuZFxuICAgICAgICAgICAgY29uc3QgciA9IE1hdGgucG93KE1hdGgucG93KHgsIDIpICsgTWF0aC5wb3coeSwgMiksIDAuNSk7XG4gICAgICAgICAgICBpZiAociA+IHIwIHx8IHIgPCByMSkge1xuICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBsZXQgYWxwaGEgPSBNYXRoLmF0YW4oeSAvIHgpO1xuICAgICAgICAgICAgaWYgKHggPCAwKSB7XG4gICAgICAgICAgICAgICAgYWxwaGEgKz0gUkFELnQxODA7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHBvaW50cy5wdXNoKHsgeCwgeSwgciwgYWxwaGEsIHRvdWNoOiBmYWxzZSB9KTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBwb2ludHM7XG59XG5cbmZ1bmN0aW9uIGNyZWF0ZVZpc2lvbkdyaWROb2Rlcyhjb25maWcsIGdyaWRzLCBub2Rlcykge1xuICAgIGlmIChjb25maWcuc2hvd1Zpc2lvbiA9PT0gZmFsc2UpIHtcbiAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9XG5cbiAgICByZXR1cm4gZ3JpZHMudmlzaW9uLnJlZHVjZSgoYWNjLCB7IHgsIHkgfSkgPT4ge1xuICAgICAgICBjb25zdCBkaXYgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICAgICAgZGl2LmNsYXNzTmFtZSA9ICdwYXJ0aWNsZS12aXNpb24tZG90JztcbiAgICAgICAgZGl2LnN0eWxlLmJhY2tncm91bmRDb2xvciA9IGNvbmZpZy5jb2xvcjtcbiAgICAgICAgbm9kZXMuY29udGFpbmVyLmFwcGVuZENoaWxkKGRpdik7XG5cbiAgICAgICAgYWNjLnB1c2goZGl2KTtcblxuICAgICAgICByZXR1cm4gYWNjO1xuICAgIH0sIFtdKTtcbn1cblxuXG5mdW5jdGlvbiB1cGRhdGVWaXNpb25HcmlkKGFyYywgY29uZmlnLCBncmlkcykge1xuICAgIGNvbnN0IHsgZ2xvYmFsLCB2aXNpb24gfSA9IGdyaWRzO1xuXG4gICAgcmV0dXJuIHZpc2lvbi5yZWR1Y2UoKGFjYywgcG9pbnQpID0+IHtcbiAgICAgICAgY29uc3QgcmFkID0gYXJjLmNsb2Nrd2lzZVxuICAgICAgICAgICAgPyBwb2ludC5hbHBoYSAtIGFyYy50aGV0YVxuICAgICAgICAgICAgOiBwb2ludC5hbHBoYSAtIGFyYy50aGV0YSArIFJBRC50MTgwO1xuXG4gICAgICAgIHBvaW50LnggPSBwb2ludC5yICogTWF0aC5jb3MocmFkKTtcbiAgICAgICAgcG9pbnQueSA9IHBvaW50LnIgKiBNYXRoLnNpbihyYWQpO1xuXG4gICAgICAgIHJldHVybiBhY2MuY29uY2F0KHBvaW50KTtcbiAgICB9LCBbXSk7XG59XG5cbi8vID09PT09IERPTSBSRU5ERVJJTkcgPT09PT1cbmZ1bmN0aW9uIHJlcGFpbnRDb250YWluZXIobm9kZSwgYXJjKSB7XG4gICAgbm9kZS5zdHlsZS5sZWZ0ID0gYCR7YXJjLmVuZFh9cHhgO1xuICAgIG5vZGUuc3R5bGUudG9wID0gYCR7YXJjLmVuZFl9cHhgO1xufVxuXG5mdW5jdGlvbiByZXBhaW50Qm9keShub2RlLCBhcmMsIGlzTGVhZGVyKSB7XG4gICAgY29uc3QgcmFkID0gYXJjLmNsb2Nrd2lzZVxuICAgICAgICA/IFJBRC50MTgwIC0gYXJjLnRoZXRhXG4gICAgICAgIDogUkFELnQzNjAgLSBhcmMudGhldGE7XG5cbiAgICBub2RlLnN0eWxlLnRyYW5zZm9ybSA9IGByb3RhdGUoJHtyYWQgKyBSQUQudDQ1fXJhZClgO1xuXG4gICAgaXNMZWFkZXIgPyBub2RlLnN0eWxlLm91dGxpbmUgPSAnMXB4IHNvbGlkIHJlZCcgOiBub2RlLnN0eWxlLm91dGxpbmUgPSAnJztcbn1cblxuZnVuY3Rpb24gcmVwYWludENpcmNsZShub2RlLCBhcmMpIHtcbiAgICBpZiAobm9kZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBub2RlLnN0eWxlLndpZHRoID0gYCR7MiAqIGFyYy5yYWRpdXN9cHhgO1xuICAgIG5vZGUuc3R5bGUuaGVpZ2h0ID0gYCR7MiAqIGFyYy5yYWRpdXN9cHhgO1xuXG4gICAgbm9kZS5zdHlsZS5sZWZ0ID0gYC0ke2FyYy5yYWRpdXMgKyBhcmMucmFkaXVzICogYXJjLmNvc1RoZXRhfXB4YDtcbiAgICBub2RlLnN0eWxlLnRvcCA9IGAtJHthcmMucmFkaXVzIC0gYXJjLnJhZGl1cyAqIGFyYy5zaW5UaGV0YX1weGA7XG5cbiAgICBub2RlLnN0eWxlLmJvcmRlclJhZGl1cyA9IGAke2FyYy5yYWRpdXN9cHhgO1xufVxuXG5mdW5jdGlvbiByZXBhaW50VmlzaW9uR3JpZChub2RlcywgYXJjLCBncmlkcykge1xuICAgIGlmIChub2RlcyA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBncmlkcy52aXNpb24uZm9yRWFjaCgoeyB4LCB5LCB0b3VjaCB9LCBpKSA9PiB7XG4gICAgICAgIG5vZGVzW2ldLnN0eWxlLmxlZnQgPSBgJHt4fXB4YDtcbiAgICAgICAgbm9kZXNbaV0uc3R5bGUudG9wID0gYCR7eX1weGA7XG5cbiAgICAgICAgbm9kZXNbaV0uc3R5bGUuYm9yZGVyID0gKHRvdWNoID8gJzJweCBzb2xpZCByZWQnIDogJzAnKTtcbiAgICB9KTtcbn1cblxuZXhwb3J0IGRlZmF1bHQgUGFydGljbGU7XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8ganMvcGFydGljbGUuanMiXSwibWFwcGluZ3MiOiI7Ozs7OztBQUFBO0FBQ0E7OztBQUFBO0FBQ0E7QUFBQTtBQUNBOzs7QUFBQTtBQUNBOzs7OztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBVEE7QUFDQTtBQVdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRkE7QUFDQTtBQUlBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBSkE7QUFDQTtBQU1BO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwic291cmNlUm9vdCI6IiJ9"); +eval("\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nvar _rxjs = __webpack_require__(/*! rxjs */ 19);\n\nvar _rxjs2 = _interopRequireDefault(_rxjs);\n\nvar _enums = __webpack_require__(/*! ./enums */ 20);\n\nvar _arc = __webpack_require__(/*! ./arc */ 78);\n\nvar _arc2 = _interopRequireDefault(_arc);\n\nvar _random = __webpack_require__(/*! ./random */ 40);\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(6);\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.grids.global.setPoint({ x: p.arc.endX, y: p.arc.endY, type: ENTITIES.PARTICLE }, p); // USE ID?\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.circle$ && observables.circle$.takeUntil(this.remove$).subscribe(this.subscribeCircle.bind(this));\n\n // observables.randomize$.subscribe(this.subscribeRandomize.bind(this));\n};\n\n// ===== PROTOTYPE =====\n\nParticle.prototype.remove = function () {\n // this.grids.globals.deletePoint({ x: p.arc.endX, y: p.arc.endY, type: ENTITIES.PARTICLE });\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.arc = Arc.goto(this.arc, 200, 200, this.config.speed)\n if (this.nodes === undefined) {\n console.warn('no nodes in', this.id);\n return;\n }\n\n this.arc = _arc2.default.step(this.arc, this.config.bounds, this.config.speed);\n\n if (this.leader !== null) {\n // this.arc = Arc.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 // const { hazards, particles } = look(this.arc, this.grids);\n\n // if (hazards.length > 0) {\n // this.arc = Arc.evade(this.arc);\n // }\n\n // this.updateLeader(particles);\n\n // const prevX = p.arc.endX;\n // const prevY = p.arc.endY;\n\n // this.grid.deletePoint({ x: prevX, y: prevY, type: ENTITIES.PARTICLE });\n // this.grid.setPoint({ x: p.arc.endX, y: p.arc.endY, type: ENTITIES.PARTICLE }, p);\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\n// if (showVision === true && this.nodes.visionGrid === undefined) {\n// this.nodes.visionGrid = createVisionGridNodes(this.config, this.grids, this.nodes);\n// }\n//\n// if (showVision === false && this.nodes.visionGrid !== undefined) {\n// delete this.nodex.visionGrid;\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.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 if (config.showVision === false) {\n return undefined;\n }\n\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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiODEuanMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vanMvcGFydGljbGUuanM/M2JkZSJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgUngsIHsgT2JzZXJ2YWJsZSB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgQkVIQVZJT1IsIEVOVElUSUVTLCBSQUQgfSBmcm9tICcuL2VudW1zJztcbmltcG9ydCBBcmMgZnJvbSAnLi9hcmMnO1xuaW1wb3J0IFJhbmRvbSBmcm9tICcuL3JhbmRvbSc7XG5cbi8vID09PT09IENvbnN0cnVjdG9yID09PT09XG5cbmZ1bmN0aW9uIFBhcnRpY2xlKHBhcmVudCwgYm91bmRzLCBnbG9iYWxHcmlkLCBvYnNlcnZhYmxlcykge1xuICAgIHRoaXMuY29uZmlnID0ge1xuICAgICAgICBiZWhhdmlvcjogQkVIQVZJT1IuQ09IRVNJT04sXG4gICAgICAgIGJvdW5kcyxcbiAgICAgICAgY29sb3I6IFJhbmRvbS5jb2xvcigpLFxuICAgICAgICBncmlkU2l6ZTogNSxcbiAgICAgICAgcmFuZG9taXplOiB0cnVlLFxuICAgICAgICBzaG93QXJjOiBmYWxzZSxcbiAgICAgICAgc2hvd1Zpc2lvbjogZmFsc2UsXG4gICAgICAgIHNwZWVkOiA0LFxuICAgICAgICB2aXNpb25SYWRpdXM6IDUwXG4gICAgfTtcblxuICAgIHRoaXMuZ3JpZHMgPSB7XG4gICAgICAgIGdsb2JhbDogZ2xvYmFsR3JpZCB8fCB7fSxcbiAgICAgICAgdmlzaW9uOiBjcmVhdGVWaXNpb25HcmlkKHRoaXMuY29uZmlnKVxuICAgIH07XG5cbiAgICB0aGlzLmlkID0gUmFuZG9tLmlkKDYpO1xuXG4gICAgdGhpcy5ub2RlcyA9IHtcbiAgICAgICAgYm9keTogY3JlYXRlQm9keU5vZGUodGhpcy5jb25maWcpLFxuICAgICAgICBjaXJjbGU6IHVuZGVmaW5lZCxcbiAgICAgICAgY29udGFpbmVyOiBjcmVhdGVDb250YWluZXJOb2RlKHRoaXMuY29uZmlnLCB0aGlzLmlkKSxcbiAgICAgICAgdmlzaW9uR3JpZDogdW5kZWZpbmVkLFxuICAgIH07XG5cbiAgICB0aGlzLm5vZGVzLmNvbnRhaW5lci5hcHBlbmRDaGlsZCh0aGlzLm5vZGVzLmJvZHkpO1xuICAgIHBhcmVudC5hcHBlbmRDaGlsZCh0aGlzLm5vZGVzLmNvbnRhaW5lcik7XG5cbiAgICB0aGlzLmxlYWRlciA9IG51bGw7XG4gICAgdGhpcy5pc0xlYWRlciA9IGZhbHNlO1xuXG4gICAgdGhpcy5hcmMgPSBBcmMuY3JlYXRlKGJvdW5kcywgdGhpcy5ncmlkcy5nbG9iYWwpO1xuICAgIC8vIHRoaXMuZ3JpZHMuZ2xvYmFsLnNldFBvaW50KHsgeDogcC5hcmMuZW5kWCwgeTogcC5hcmMuZW5kWSwgdHlwZTogRU5USVRJRVMuUEFSVElDTEUgfSwgcCk7IC8vIFVTRSBJRD9cblxuICAgIHRoaXMucmVtb3ZlJCA9IG5ldyBSeC5TdWJqZWN0KCk7XG5cbiAgICBvYnNlcnZhYmxlcy5mcHMkXG4gICAgICAgIC50YWtlVW50aWwodGhpcy5yZW1vdmUkKVxuICAgICAgICAuc3Vic2NyaWJlKHRoaXMuc3Vic2NyaWJlTmV4dEZyYW1lLmJpbmQodGhpcykpO1xuXG4gICAgb2JzZXJ2YWJsZXMuc3BlZWQkXG4gICAgICAgIC50YWtlVW50aWwodGhpcy5yZW1vdmUkKVxuICAgICAgICAuc3Vic2NyaWJlKHRoaXMuc3Vic2NyaWJlU3BlZWQuYmluZCh0aGlzKSk7XG5cbiAgICBvYnNlcnZhYmxlcy5jaXJjbGUkICYmIG9ic2VydmFibGVzLmNpcmNsZSRcbiAgICAgICAgLnRha2VVbnRpbCh0aGlzLnJlbW92ZSQpXG4gICAgICAgIC5zdWJzY3JpYmUodGhpcy5zdWJzY3JpYmVDaXJjbGUuYmluZCh0aGlzKSk7XG5cblxuICAgIC8vIG9ic2VydmFibGVzLnJhbmRvbWl6ZSQuc3Vic2NyaWJlKHRoaXMuc3Vic2NyaWJlUmFuZG9taXplLmJpbmQodGhpcykpO1xufTtcblxuLy8gPT09PT0gUFJPVE9UWVBFID09PT09XG5cblBhcnRpY2xlLnByb3RvdHlwZS5yZW1vdmUgPSBmdW5jdGlvbigpIHtcbiAgICAvLyB0aGlzLmdyaWRzLmdsb2JhbHMuZGVsZXRlUG9pbnQoeyB4OiBwLmFyYy5lbmRYLCB5OiBwLmFyYy5lbmRZLCB0eXBlOiBFTlRJVElFUy5QQVJUSUNMRSB9KTtcblxuICAgIGNvbnN0IHBhcmVudCA9IHRoaXMubm9kZXMuY29udGFpbmVyLnBhcmVudE5vZGU7XG4gICAgcGFyZW50LnJlbW92ZUNoaWxkKHRoaXMubm9kZXMuY29udGFpbmVyKTtcbiAgICB0aGlzLnJlbW92ZSQubmV4dCgpO1xuICAgIGRlbGV0ZSB0aGlzLm5vZGVzO1xufVxuXG5QYXJ0aWNsZS5wcm90b3R5cGUuc3Vic2NyaWJlTmV4dEZyYW1lID0gZnVuY3Rpb24oKSB7XG4gICAgLy8gdGhpcy5hcmMgPSBBcmMuZ290byh0aGlzLmFyYywgMjAwLCAyMDAsIHRoaXMuY29uZmlnLnNwZWVkKVxuICAgIGlmICh0aGlzLm5vZGVzID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgY29uc29sZS53YXJuKCdubyBub2RlcyBpbicsIHRoaXMuaWQpO1xuICAgICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdGhpcy5hcmMgPSBBcmMuc3RlcCh0aGlzLmFyYywgdGhpcy5jb25maWcuYm91bmRzLCB0aGlzLmNvbmZpZy5zcGVlZCk7XG5cbiAgICBpZiAodGhpcy5sZWFkZXIgIT09IG51bGwpIHtcbiAgICAvLyAgICAgdGhpcy5hcmMgPSBBcmMuZm9sbG93KHRoaXMuYXJjLCB0aGlzLmxlYWRlci5hcmMpO1xuICAgIH0gZWxzZSBpZiAodGhpcy5hcmMubGVuZ3RoIDw9IDAgJiYgdGhpcy5jb25maWcucmFuZG9taXplKSB7XG4gICAgICAgIHRoaXMuYXJjID0gQXJjLnJhbmRvbWl6ZSh0aGlzLmFyYyk7XG4gICAgfVxuXG4gICAgLy8gdGhpcy5ncmlkcy52aXNpb24gPSB1cGRhdGVWaXNpb25HcmlkKHRoaXMuYXJjLCB0aGlzLmNvbmZpZywgdGhpcy5ncmlkcyk7XG4gICAgLy8gY29uc3QgeyBoYXphcmRzLCBwYXJ0aWNsZXMgfSA9IGxvb2sodGhpcy5hcmMsIHRoaXMuZ3JpZHMpO1xuXG4gICAgLy8gaWYgKGhhemFyZHMubGVuZ3RoID4gMCkge1xuICAgIC8vICAgICB0aGlzLmFyYyA9IEFyYy5ldmFkZSh0aGlzLmFyYyk7XG4gICAgLy8gfVxuXG4gICAgLy8gdGhpcy51cGRhdGVMZWFkZXIocGFydGljbGVzKTtcblxuICAgIC8vIGNvbnN0IHByZXZYID0gcC5hcmMuZW5kWDtcbiAgICAvLyBjb25zdCBwcmV2WSA9IHAuYXJjLmVuZFk7XG5cbiAgICAvLyB0aGlzLmdyaWQuZGVsZXRlUG9pbnQoeyB4OiBwcmV2WCwgeTogcHJldlksIHR5cGU6IEVOVElUSUVTLlBBUlRJQ0xFIH0pO1xuICAgIC8vIHRoaXMuZ3JpZC5zZXRQb2ludCh7IHg6IHAuYXJjLmVuZFgsIHk6IHAuYXJjLmVuZFksIHR5cGU6IEVOVElUSUVTLlBBUlRJQ0xFIH0sIHApO1xuXG4gICAgcmVwYWludENvbnRhaW5lcih0aGlzLm5vZGVzLmNvbnRhaW5lciwgdGhpcy5hcmMpO1xuICAgIHJlcGFpbnRCb2R5KHRoaXMubm9kZXMuYm9keSwgdGhpcy5hcmMsIHRoaXMuaXNMZWFkZXIpO1xuICAgIHJlcGFpbnRDaXJjbGUodGhpcy5ub2Rlcy5jaXJjbGUsIHRoaXMuYXJjKTtcbiAgICByZXBhaW50VmlzaW9uR3JpZCh0aGlzLm5vZGVzLnZpc2lvbkdyaWQsIHRoaXMuYXJjLCB0aGlzLmdyaWRzKTtcbn1cblxuUGFydGljbGUucHJvdG90eXBlLnN1YnNjcmliZVNwZWVkID0gZnVuY3Rpb24odmFsdWUpIHtcbiAgICB0aGlzLmNvbmZpZy5zcGVlZCA9IHZhbHVlO1xufVxuXG4vLyAgICAgaWYgKHNob3dWaXNpb24gPT09IHRydWUgJiYgdGhpcy5ub2Rlcy52aXNpb25HcmlkID09PSB1bmRlZmluZWQpIHtcbi8vICAgICAgICAgdGhpcy5ub2Rlcy52aXNpb25HcmlkID0gY3JlYXRlVmlzaW9uR3JpZE5vZGVzKHRoaXMuY29uZmlnLCB0aGlzLmdyaWRzLCB0aGlzLm5vZGVzKTtcbi8vICAgICB9XG4vL1xuLy8gICAgIGlmIChzaG93VmlzaW9uID09PSBmYWxzZSAmJiB0aGlzLm5vZGVzLnZpc2lvbkdyaWQgIT09IHVuZGVmaW5lZCkge1xuLy8gICAgICAgICBkZWxldGUgdGhpcy5ub2RleC52aXNpb25HcmlkO1xuLy8gICAgIH1cblxuUGFydGljbGUucHJvdG90eXBlLnN1YnNjcmliZUNpcmNsZSA9IGZ1bmN0aW9uKHNob3cpIHtcbiAgICBpZiAoc2hvdyA9PT0gZmFsc2UpIHtcbiAgICAgICAgdGhpcy5ub2Rlcy5jb250YWluZXIucmVtb3ZlQ2hpbGQodGhpcy5ub2Rlcy5jaXJjbGUpO1xuICAgICAgICBkZWxldGUgdGhpcy5ub2Rlcy5jaXJjbGU7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5ub2Rlcy5jaXJjbGUgPSBjcmVhdGVDaXJjbGVOb2RlKHRoaXMuY29uZmlnKTtcbiAgICAgICAgdGhpcy5ub2Rlcy5jb250YWluZXIuYXBwZW5kQ2hpbGQodGhpcy5ub2Rlcy5jaXJjbGUpO1xuICAgIH1cbn1cblxuUGFydGljbGUucHJvdG90eXBlLnN1YnNjcmliZVJhbmRvbWl6ZSA9IGZ1bmN0aW9uKHZhbHVlKSB7XG4gICAgdGhpcy5jb25maWcucmFuZG9taXplID0gdmFsdWU7XG59XG5cblBhcnRpY2xlLnByb3RvdHlwZS51cGRhdGVMZWFkZXIgPSBmdW5jdGlvbihwYXJ0aWNsZXMpIHtcbiAgICBpZiAodGhpcy5jb25maWcuYmVoYXZpb3IgIT09IEJFSEFWSU9SLkNPSEVTSU9OKSB7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5sZWFkZXIgPT09IG51bGwgJiYgcGFydGljbGVzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgLy8gSGVhZC10by1oZWFkOiBwYXJ0aWNsZXMgc2VlIGVhY2hvdGhlciBidXQgc2hvdWxkbid0IGJvdGggbGVhZC5cbiAgICAgICAgY29uc3QgY2FuZGlkYXRlcyA9IHBhcnRpY2xlc1xuICAgICAgICAgICAgLmZpbHRlcih2ID0+IHYubGVhZGVyID8gKHYubGVhZGVyLmlkICE9PSB0aGlzLmlkKSA6IHRydWUpO1xuXG4gICAgICAgIGNvbnN0IGxlYWRlciA9IGNhbmRpZGF0ZXMuZmluZCh2ID0+IHYuaXNMZWFkZXIpIHx8IGNhbmRpZGF0ZXNbMF07XG5cbiAgICAgICAgaWYgKGxlYWRlciAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICBsZWFkZXIuaXNMZWFkZXIgPSB0cnVlO1xuICAgICAgICAgICAgdGhpcy5sZWFkZXIgPSBsZWFkZXI7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAodGhpcy5sZWFkZXIgPT09IG51bGwpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmICh0aGlzLmxlYWRlci5ub2RlcyA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHRoaXMubGVhZGVyID0gbnVsbDtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmICh0aGlzLmxlYWRlci5sZWFkZXIgIT09IG51bGwpIHtcbiAgICAgICAgdGhpcy5sZWFkZXIgPSB0aGlzLmxlYWRlci5sZWFkZXI7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuaXNMZWFkZXIpIHtcbiAgICAgICAgdGhpcy5pc0xlYWRlciA9IGZhbHNlO1xuICAgIH1cblxuICAgIC8vIEJld2FyZSBvZiBjaXJjdWxhciBsZWFkZXJzaGlwLCB3aGVyZSBhIGxlYWRlciBzZWVzIGl0cyB0YWlsLlxuICAgIGlmICh0aGlzLmxlYWRlci5pZCA9PT0gdGhpcy5pZCkge1xuICAgICAgICB0aGlzLmxlYWRlciA9IG51bGw7XG4gICAgfVxufVxuXG5mdW5jdGlvbiBsb29rKGFyYywgZ3JpZHMpIHtcbiAgICBjb25zdCB7IGdsb2JhbCwgdmlzaW9uIH0gPSBncmlkcztcblxuICAgIHJldHVybiB2aXNpb24ucmVkdWNlKChhY2MsIHBvaW50KSA9PiB7XG4gICAgICAgIGNvbnN0IHggPSBhcmMuZW5kWCArIHBvaW50Lng7XG4gICAgICAgIGNvbnN0IHkgPSBhcmMuZW5kWSArIHBvaW50Lnk7XG4gICAgICAgIGNvbnN0IHAgPSBnbG9iYWwuZ2V0UG9pbnQoeyB4LCB5LCB0eXBlOiBFTlRJVElFUy5QQVJUSUNMRSB9KTtcblxuICAgICAgICBpZiAocCkge1xuICAgICAgICAgICAgYWNjLnBhcnRpY2xlcy5wdXNoKHApO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGdsb2JhbC5nZXRQb2ludCh7IHgsIHksIHR5cGU6IEVOVElUSUVTLkhBWkFSRCB9KSkge1xuICAgICAgICAgICAgYWNjLmhhemFyZHMucHVzaCh7IHgsIHkgfSk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gYWNjO1xuICAgIH0sIHsgaGF6YXJkczogW10sIHBhcnRpY2xlczogW10gfSk7XG59XG5cbi8vID09PT09IERPTSBDUkVBVElPTiA9PT09PVxuXG5mdW5jdGlvbiBjcmVhdGVCb2R5Tm9kZShjb25maWcpIHtcbiAgICBjb25zdCBub2RlID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgbm9kZS5jbGFzc05hbWUgPSAncGFydGljbGUtYm9keSc7XG4gICAgbm9kZS5zdHlsZS5iYWNrZ3JvdW5kQ29sb3IgPSBjb25maWcuY29sb3I7XG4gICAgcmV0dXJuIG5vZGU7XG59XG5cbmZ1bmN0aW9uIGNyZWF0ZUNpcmNsZU5vZGUoY29uZmlnKSB7XG4gICAgY29uc3Qgbm9kZSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgIG5vZGUuY2xhc3NOYW1lID0gJ3BhcnRpY2xlLW1vdmVtZW50LWNpcmNsZSc7XG4gICAgbm9kZS5zdHlsZS5ib3JkZXJDb2xvciA9IGNvbmZpZy5jb2xvcjtcbiAgICByZXR1cm4gbm9kZTtcbn1cblxuZnVuY3Rpb24gY3JlYXRlQ29udGFpbmVyTm9kZShjb25maWcsIGlkKSB7XG4gICAgY29uc3Qgbm9kZSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgIG5vZGUuY2xhc3NOYW1lID0gJ3BhcnRpY2xlLWNvbnRhaW5lcic7XG4gICAgbm9kZS5pZCA9IGlkO1xuICAgIHJldHVybiBub2RlO1xufVxuXG5mdW5jdGlvbiBjcmVhdGVWaXNpb25HcmlkKGNvbmZpZykge1xuICAgIGNvbnN0IHsgZ3JpZFNpemU6IHNpZGUsIHZpc2lvblJhZGl1czogcmFkaXVzIH0gPSBjb25maWc7XG4gICAgY29uc3QgcjAgPSByYWRpdXM7XG4gICAgY29uc3QgcjEgPSA0NTtcblxuICAgIGNvbnN0IHBvaW50cyA9IFtdO1xuXG4gICAgZm9yIChsZXQgeCA9IC1yYWRpdXM7IHggPD0gcmFkaXVzOyB4ICs9IHNpZGUpIHtcbiAgICAgICAgZm9yIChsZXQgeSA9IC1yYWRpdXM7IHkgPD0gcmFkaXVzOyB5ICs9IHNpZGUpIHtcbiAgICAgICAgICAgIC8vIE9taXQgbGFyZ2Ugc2xpY2VzIG9mIHVudXNlZCBjaXJjbGVcbiAgICAgICAgICAgIGlmICh4ID4geSB8fCB4IDwgLXkpIHtcbiAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gSW5jbHVkZSB2aXNpb24gYmFuZFxuICAgICAgICAgICAgY29uc3QgciA9IE1hdGgucG93KE1hdGgucG93KHgsIDIpICsgTWF0aC5wb3coeSwgMiksIDAuNSk7XG4gICAgICAgICAgICBpZiAociA+IHIwIHx8IHIgPCByMSkge1xuICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBsZXQgYWxwaGEgPSBNYXRoLmF0YW4oeSAvIHgpO1xuICAgICAgICAgICAgaWYgKHggPCAwKSB7XG4gICAgICAgICAgICAgICAgYWxwaGEgKz0gUkFELnQxODA7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHBvaW50cy5wdXNoKHsgeCwgeSwgciwgYWxwaGEsIHRvdWNoOiBmYWxzZSB9KTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBwb2ludHM7XG59XG5cbmZ1bmN0aW9uIGNyZWF0ZVZpc2lvbkdyaWROb2Rlcyhjb25maWcsIGdyaWRzLCBub2Rlcykge1xuICAgIGlmIChjb25maWcuc2hvd1Zpc2lvbiA9PT0gZmFsc2UpIHtcbiAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9XG5cbiAgICByZXR1cm4gZ3JpZHMudmlzaW9uLnJlZHVjZSgoYWNjLCB7IHgsIHkgfSkgPT4ge1xuICAgICAgICBjb25zdCBkaXYgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICAgICAgZGl2LmNsYXNzTmFtZSA9ICdwYXJ0aWNsZS12aXNpb24tZG90JztcbiAgICAgICAgZGl2LnN0eWxlLmJhY2tncm91bmRDb2xvciA9IGNvbmZpZy5jb2xvcjtcbiAgICAgICAgbm9kZXMuY29udGFpbmVyLmFwcGVuZENoaWxkKGRpdik7XG5cbiAgICAgICAgYWNjLnB1c2goZGl2KTtcblxuICAgICAgICByZXR1cm4gYWNjO1xuICAgIH0sIFtdKTtcbn1cblxuXG5mdW5jdGlvbiB1cGRhdGVWaXNpb25HcmlkKGFyYywgY29uZmlnLCBncmlkcykge1xuICAgIGNvbnN0IHsgZ2xvYmFsLCB2aXNpb24gfSA9IGdyaWRzO1xuXG4gICAgcmV0dXJuIHZpc2lvbi5yZWR1Y2UoKGFjYywgcG9pbnQpID0+IHtcbiAgICAgICAgY29uc3QgcmFkID0gYXJjLmNsb2Nrd2lzZVxuICAgICAgICAgICAgPyBwb2ludC5hbHBoYSAtIGFyYy50aGV0YVxuICAgICAgICAgICAgOiBwb2ludC5hbHBoYSAtIGFyYy50aGV0YSArIFJBRC50MTgwO1xuXG4gICAgICAgIHBvaW50LnggPSBwb2ludC5yICogTWF0aC5jb3MocmFkKTtcbiAgICAgICAgcG9pbnQueSA9IHBvaW50LnIgKiBNYXRoLnNpbihyYWQpO1xuXG4gICAgICAgIHJldHVybiBhY2MuY29uY2F0KHBvaW50KTtcbiAgICB9LCBbXSk7XG59XG5cbi8vID09PT09IERPTSBSRU5ERVJJTkcgPT09PT1cbmZ1bmN0aW9uIHJlcGFpbnRDb250YWluZXIobm9kZSwgYXJjKSB7XG4gICAgbm9kZS5zdHlsZS5sZWZ0ID0gYCR7YXJjLmVuZFh9cHhgO1xuICAgIG5vZGUuc3R5bGUudG9wID0gYCR7YXJjLmVuZFl9cHhgO1xufVxuXG5mdW5jdGlvbiByZXBhaW50Qm9keShub2RlLCBhcmMsIGlzTGVhZGVyKSB7XG4gICAgY29uc3QgcmFkID0gYXJjLmNsb2Nrd2lzZVxuICAgICAgICA/IFJBRC50MTgwIC0gYXJjLnRoZXRhXG4gICAgICAgIDogUkFELnQzNjAgLSBhcmMudGhldGE7XG5cbiAgICBub2RlLnN0eWxlLnRyYW5zZm9ybSA9IGByb3RhdGUoJHtyYWQgKyBSQUQudDQ1fXJhZClgO1xuXG4gICAgaXNMZWFkZXIgPyBub2RlLnN0eWxlLm91dGxpbmUgPSAnMXB4IHNvbGlkIHJlZCcgOiBub2RlLnN0eWxlLm91dGxpbmUgPSAnJztcbn1cblxuZnVuY3Rpb24gcmVwYWludENpcmNsZShub2RlLCBhcmMpIHtcbiAgICBpZiAobm9kZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBub2RlLnN0eWxlLndpZHRoID0gYCR7MiAqIGFyYy5yYWRpdXN9cHhgO1xuICAgIG5vZGUuc3R5bGUuaGVpZ2h0ID0gYCR7MiAqIGFyYy5yYWRpdXN9cHhgO1xuXG4gICAgbm9kZS5zdHlsZS5sZWZ0ID0gYC0ke2FyYy5yYWRpdXMgKyBhcmMucmFkaXVzICogYXJjLmNvc1RoZXRhfXB4YDtcbiAgICBub2RlLnN0eWxlLnRvcCA9IGAtJHthcmMucmFkaXVzIC0gYXJjLnJhZGl1cyAqIGFyYy5zaW5UaGV0YX1weGA7XG5cbiAgICBub2RlLnN0eWxlLmJvcmRlclJhZGl1cyA9IGAke2FyYy5yYWRpdXN9cHhgO1xufVxuXG5mdW5jdGlvbiByZXBhaW50VmlzaW9uR3JpZChub2RlcywgYXJjLCBncmlkcykge1xuICAgIGlmIChub2RlcyA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBncmlkcy52aXNpb24uZm9yRWFjaCgoeyB4LCB5LCB0b3VjaCB9LCBpKSA9PiB7XG4gICAgICAgIG5vZGVzW2ldLnN0eWxlLmxlZnQgPSBgJHt4fXB4YDtcbiAgICAgICAgbm9kZXNbaV0uc3R5bGUudG9wID0gYCR7eX1weGA7XG5cbiAgICAgICAgbm9kZXNbaV0uc3R5bGUuYm9yZGVyID0gKHRvdWNoID8gJzJweCBzb2xpZCByZWQnIDogJzAnKTtcbiAgICB9KTtcbn1cblxuZXhwb3J0IGRlZmF1bHQgUGFydGljbGU7XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8ganMvcGFydGljbGUuanMiXSwibWFwcGluZ3MiOiI7Ozs7OztBQUFBO0FBQ0E7OztBQUFBO0FBQ0E7QUFBQTtBQUNBOzs7QUFBQTtBQUNBOzs7OztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBVEE7QUFDQTtBQVdBO0FBQ0E7QUFDQTtBQUZBO0FBQ0E7QUFJQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUpBO0FBQ0E7QUFNQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUdBO0FBQ0E7QUFHQTtBQUNBO0FBSUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwic291cmNlUm9vdCI6IiJ9"); /***/ }), /* 82 */ @@ -4367,7 +4367,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 = '1b';\n var config = {\n id: id,\n max: 10\n };\n\n var observables = (0, _controls2.default)(destroy$, config);\n new _animation2.default(observables, id);\n};\n\nvar _animation = __webpack_require__(/*! ./animation */ 77);\n\nvar _animation2 = _interopRequireDefault(_animation);\n\nvar _controls = __webpack_require__(/*! ./controls */ 31);\n\nvar _controls2 = _interopRequireDefault(_controls);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMzYxLmpzIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vL2pzL2FuaW1hdGlvbjFiLmpzP2QyZDIiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IEFuaW1hdGlvbiBmcm9tICcuL2FuaW1hdGlvbic7XG5pbXBvcnQgQ29udHJvbHMgZnJvbSAnLi9jb250cm9scyc7XG5cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uKGRlc3Ryb3kkKSB7XG4gICAgY29uc3QgaWQgPSAnMWInO1xuICAgIGNvbnN0IGNvbmZpZyA9IHtcbiAgICAgICAgaWQsXG4gICAgICAgIG1heDogMTBcbiAgICB9O1xuXG4gICAgY29uc3Qgb2JzZXJ2YWJsZXMgPSBDb250cm9scyhkZXN0cm95JCwgY29uZmlnKTtcbiAgICBuZXcgQW5pbWF0aW9uKG9ic2VydmFibGVzLCBpZCk7XG59XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8ganMvYW5pbWF0aW9uMWIuanMiXSwibWFwcGluZ3MiOiI7Ozs7OztBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFGQTtBQUNBO0FBSUE7QUFDQTtBQUNBO0FBQ0E7QUFiQTtBQUNBOzs7QUFBQTtBQUNBOzs7QSIsInNvdXJjZVJvb3QiOiIifQ=="); +eval("\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nexports.default = function (destroy$) {\n var id = '1b';\n var config = {\n id: id,\n maxCount: 1000\n };\n\n var observables = (0, _controls2.default)(destroy$, config);\n new _animation2.default(observables, id);\n};\n\nvar _animation = __webpack_require__(/*! ./animation */ 77);\n\nvar _animation2 = _interopRequireDefault(_animation);\n\nvar _controls = __webpack_require__(/*! ./controls */ 31);\n\nvar _controls2 = _interopRequireDefault(_controls);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMzYxLmpzIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vL2pzL2FuaW1hdGlvbjFiLmpzP2QyZDIiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IEFuaW1hdGlvbiBmcm9tICcuL2FuaW1hdGlvbic7XG5pbXBvcnQgQ29udHJvbHMgZnJvbSAnLi9jb250cm9scyc7XG5cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uKGRlc3Ryb3kkKSB7XG4gICAgY29uc3QgaWQgPSAnMWInO1xuICAgIGNvbnN0IGNvbmZpZyA9IHtcbiAgICAgICAgaWQsXG4gICAgICAgIG1heENvdW50OiAxMDAwXG4gICAgfTtcblxuICAgIGNvbnN0IG9ic2VydmFibGVzID0gQ29udHJvbHMoZGVzdHJveSQsIGNvbmZpZyk7XG4gICAgbmV3IEFuaW1hdGlvbihvYnNlcnZhYmxlcywgaWQpO1xufVxuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIGpzL2FuaW1hdGlvbjFiLmpzIl0sIm1hcHBpbmdzIjoiOzs7Ozs7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRkE7QUFDQTtBQUlBO0FBQ0E7QUFDQTtBQUNBO0FBYkE7QUFDQTs7O0FBQUE7QUFDQTs7O0EiLCJzb3VyY2VSb290IjoiIn0="); /***/ }) /******/ ]); \ No newline at end of file diff --git a/js/controls.js b/js/controls.js index 3ae2757..c2b22fb 100644 --- a/js/controls.js +++ b/js/controls.js @@ -14,6 +14,7 @@ export default function(destroy$, { document.getElementById(id).appendChild(container); const observables = { + fps$: new Rx.Subject(), count$: createCountControl(container, 0, maxCount), speed$: createSpeedControl(container), circle$: showCircleControl ? createCircleControl(container) : undefined, @@ -156,8 +157,11 @@ function createCircleControl(container) { container.appendChild(label); - const circle$ = Rx.Observable.fromEvent(label, 'change') - .map(evt => evt.target.checked); + const circle$ = new Rx.BehaviorSubject(true); + + label.addEventListener('change', (evt) => { + circle$.next(evt.target.checked); + }); return circle$; } @@ -180,8 +184,11 @@ function createRandomizeControl(container) { container.appendChild(label); - const circle$ = Rx.Observable.fromEvent(label, 'change') - .map(evt => evt.target.checked); + const randomize$ = new Rx.BehaviorSubject(true); + + label.addEventListener('change', (evt) => { + randomize$.next(evt.target.checked); + }); return randomize$; } diff --git a/js/index.js b/js/index.js index 88e9bd9..2e404ce 100644 --- a/js/index.js +++ b/js/index.js @@ -22,8 +22,8 @@ window.addEventListener('load', () => { // TODO fix "hangup" small radius evade bug // TODO don't load simulation until requested // TODO sort out particle nextframe -// TODO subscriber on bounds change // TODO abs positioning on controls elements so order doesn't matter +// TODO BehaviorSubject listener on bounds change // TODO ANIM1ab free movement diff --git a/js/particle.js b/js/particle.js index 1ee3fcd..3286b4d 100644 --- a/js/particle.js +++ b/js/particle.js @@ -3,24 +3,20 @@ import { BEHAVIOR, ENTITIES, RAD } from './enums'; import Arc from './arc'; import Random from './random'; -const baseConfig = { - behavior: BEHAVIOR.COHESION, - bounds: {}, - color: 'red', - gridSize: 5, - randomize: true, - showArc: false, - showVision: false, - speed: 4, - visionRadius: 50 -}; - // ===== Constructor ===== -function Particle(parent, bounds, config, globalGrid) { - this.config = Object.assign({}, baseConfig, config); - this.config.color = Random.color(); - // this.config.bounds = bounds; +function Particle(parent, bounds, globalGrid, observables) { + this.config = { + behavior: BEHAVIOR.COHESION, + bounds, + color: Random.color(), + gridSize: 5, + randomize: true, + showArc: false, + showVision: false, + speed: 4, + visionRadius: 50 + }; this.grids = { global: globalGrid || {}, @@ -43,10 +39,24 @@ function Particle(parent, bounds, config, globalGrid) { this.isLeader = false; this.arc = Arc.create(bounds, this.grids.global); - // this.updateConfig(this.config); - // this.grids.global.setPoint({ x: p.arc.endX, y: p.arc.endY, type: ENTITIES.PARTICLE }, p); - // this.nextFrame(globalGrid); - + // this.grids.global.setPoint({ x: p.arc.endX, y: p.arc.endY, type: ENTITIES.PARTICLE }, p); // USE ID? + + this.remove$ = new Rx.Subject(); + + observables.fps$ + .takeUntil(this.remove$) + .subscribe(this.subscribeNextFrame.bind(this)); + + observables.speed$ + .takeUntil(this.remove$) + .subscribe(this.subscribeSpeed.bind(this)); + + observables.circle$ && observables.circle$ + .takeUntil(this.remove$) + .subscribe(this.subscribeCircle.bind(this)); + + + // observables.randomize$.subscribe(this.subscribeRandomize.bind(this)); }; // ===== PROTOTYPE ===== @@ -56,56 +66,50 @@ Particle.prototype.remove = function() { const parent = this.nodes.container.parentNode; parent.removeChild(this.nodes.container); - + this.remove$.next(); delete this.nodes; - return this; } -Particle.prototype.nextFrame = function() { +Particle.prototype.subscribeNextFrame = function() { // this.arc = Arc.goto(this.arc, 200, 200, this.config.speed) + if (this.nodes === undefined) { + console.warn('no nodes in', this.id); + return; + } 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); + // 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.grids.vision = updateVisionGrid(this.arc, this.config, this.grids); // const { hazards, particles } = look(this.arc, this.grids); - // + // if (hazards.length > 0) { // this.arc = Arc.evade(this.arc); // } - // + // this.updateLeader(particles); + // const prevX = p.arc.endX; + // const prevY = p.arc.endY; + + // this.grid.deletePoint({ x: prevX, y: prevY, type: ENTITIES.PARTICLE }); + // this.grid.setPoint({ x: p.arc.endX, y: p.arc.endY, type: ENTITIES.PARTICLE }, p); + repaintContainer(this.nodes.container, this.arc); repaintBody(this.nodes.body, this.arc, this.isLeader); repaintCircle(this.nodes.circle, this.arc); repaintVisionGrid(this.nodes.visionGrid, this.arc, this.grids); } -Particle.prototype.subscriber = function({ key, value }) { - +Particle.prototype.subscribeSpeed = function(value) { + this.config.speed = value; } -Particle.prototype.updateConfig = function(config) { -// Object.assign(this.config, config); -// -// const { showArc, showVision } = this.config; -// -// if (showArc === true && this.nodes.circle === undefined) { -// this.nodes.circle = createCircleNode(this.config); -// this.nodes.container.appendChild(this.nodes.circle); -// } -// -// if (showArc === false && this.nodes.circle !== undefined) { -// this.nodes.container.removeChild(this.nodes.circle); -// delete this.nodes.circle; -// } -// // if (showVision === true && this.nodes.visionGrid === undefined) { // this.nodes.visionGrid = createVisionGridNodes(this.config, this.grids, this.nodes); // } @@ -113,6 +117,19 @@ Particle.prototype.updateConfig = function(config) { // if (showVision === false && this.nodes.visionGrid !== undefined) { // delete this.nodex.visionGrid; // } + +Particle.prototype.subscribeCircle = function(show) { + if (show === false) { + this.nodes.container.removeChild(this.nodes.circle); + delete this.nodes.circle; + } else { + this.nodes.circle = createCircleNode(this.config); + this.nodes.container.appendChild(this.nodes.circle); + } +} + +Particle.prototype.subscribeRandomize = function(value) { + this.config.randomize = value; } Particle.prototype.updateLeader = function(particles) { @@ -186,10 +203,6 @@ function createBodyNode(config) { } function createCircleNode(config) { - if (config.showArc === false) { - return undefined; - } - const node = document.createElement('div'); node.className = 'particle-movement-circle'; node.style.borderColor = config.color;