From 6520435afabb3bb4cf703b96b415fbc1ec5c291a Mon Sep 17 00:00:00 2001 From: Ben Burlingham Date: Sat, 11 Nov 2017 17:14:04 -0800 Subject: [PATCH] Minor cleanups. --- js/arc.js | 3 ++- js/bundle.js | 6 +++--- js/index.js | 9 +-------- js/particle.js | 5 +++-- 4 files changed, 9 insertions(+), 14 deletions(-) diff --git a/js/arc.js b/js/arc.js index efd6f7a..746f64e 100644 --- a/js/arc.js +++ b/js/arc.js @@ -161,7 +161,8 @@ const Arc = { }, evade: function(arc) { - arc = Arc.changeRadius(arc, 15); + // Randomness here mitigates sticking in corners and between walls. + arc = Arc.changeRadius(arc, Random.num(15, 30)); arc.length = 0.3; return arc; diff --git a/js/bundle.js b/js/bundle.js index 27302f1..2cee5f1 100644 --- a/js/bundle.js +++ b/js/bundle.js @@ -1066,7 +1066,7 @@ eval("// removed by extract-text-webpack-plugin//# sourceMappingURL=data:applica /***/ (function(module, exports, __webpack_require__) { "use strict"; -eval("\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nvar _enums = __webpack_require__(/*! ./enums */ 22);\n\nvar _random = __webpack_require__(/*! ./random */ 33);\n\nvar _random2 = _interopRequireDefault(_random);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\n// \"How much of movement is in the correct direction\"\nvar rigidity = 0.9;\n// \"How close to the leader is enough\"\nvar sensitivity = 30;\n\nvar Arc = {\n create: function create(bounds) {\n var arc = {\n centerX: _random2.default.num(0, bounds.width),\n centerY: _random2.default.num(0, bounds.height),\n clockwise: _random2.default.bool(),\n endX: 0,\n endY: 0,\n length: _random2.default.num(_enums.RAD.t90, _enums.RAD.t360),\n prevEndX: 0,\n prevEndY: 0,\n radius: _random2.default.num(100, 200),\n speed: 0,\n theta: _random2.default.num(_enums.RAD.t90, _enums.RAD.t360)\n };\n\n arc.cosTheta = Math.cos(arc.theta);\n arc.sinTheta = Math.sin(arc.theta);\n\n arc.endX = arc.centerX + arc.radius * arc.cosTheta;\n arc.endY = arc.centerY - arc.radius * arc.sinTheta;\n\n arc = Arc.overflow(arc, bounds);\n\n return arc;\n },\n\n step: function step(arc, bounds) {\n // Ensure constant velocity and theta between 0 and 2π.\n var delta = arc.speed / arc.radius;\n arc.length -= delta;\n\n arc.theta += arc.clockwise ? -delta : +delta;\n arc.theta = arc.theta > 0 ? arc.theta % _enums.RAD.t360 : _enums.RAD.t360 + arc.theta;\n\n arc.cosTheta = Math.cos(arc.theta);\n arc.sinTheta = Math.sin(arc.theta);\n\n arc.prevEndX = arc.endX;\n arc.prevEndY = arc.endY;\n\n arc.endX = arc.centerX + arc.radius * arc.cosTheta;\n arc.endY = arc.centerY - arc.radius * arc.sinTheta;\n\n arc = Arc.overflow(arc, bounds);\n\n return arc;\n },\n\n randomize: function randomize(arc) {\n arc.length = _random2.default.num(_enums.RAD.t90, _enums.RAD.t360);\n\n arc = Arc.changeRadius(arc, _random2.default.num(100, 200));\n\n if (_random2.default.bool(0.8)) {\n arc = Arc.reverse(arc);\n }\n\n return arc;\n },\n\n overflow: function overflow(arc, bounds) {\n if (arc.endX < 0) {\n arc.endX += bounds.width;\n arc.centerX += bounds.width;\n } else if (arc.endX > bounds.width) {\n arc.endX -= bounds.width;\n arc.centerX -= bounds.width;\n }\n\n if (arc.endY < 0) {\n arc.endY += bounds.height;\n arc.centerY += bounds.height;\n } else if (arc.endY > bounds.height) {\n arc.endY -= bounds.height;\n arc.centerY -= bounds.height;\n }\n\n return arc;\n },\n\n changeRadius: function changeRadius(arc, newRadius) {\n var r0 = arc.radius;\n var r1 = newRadius;\n\n // Moves arc center to new radius while keeping theta constant.\n arc.centerX -= (r1 - r0) * arc.cosTheta;\n arc.centerY += (r1 - r0) * arc.sinTheta;\n arc.radius = r1;\n\n return arc;\n },\n\n changeSpeed: function changeSpeed(arc, newSpeed) {\n arc.speed = newSpeed * 1;\n return arc;\n },\n\n reverse: function reverse(arc) {\n arc.clockwise = !arc.clockwise;\n\n arc.theta = (arc.theta + _enums.RAD.t180) % _enums.RAD.t360;\n\n arc.cosTheta = Math.cos(arc.theta);\n arc.sinTheta = Math.sin(arc.theta);\n\n arc.centerX -= 2 * arc.radius * arc.cosTheta;\n arc.centerY += 2 * arc.radius * arc.sinTheta;\n\n return arc;\n },\n\n follow: function follow(arc, arcToFollow) {\n var prevD = Math.pow(Math.pow(arcToFollow.endX - arc.prevEndX, 2) + Math.pow(arcToFollow.endY - arc.prevEndY, 2), 0.5);\n\n var currD = Math.pow(Math.pow(arcToFollow.endX - arc.endX, 2) + Math.pow(arcToFollow.endY - arc.endY, 2), 0.5);\n\n var rigidityCoeff = (prevD - currD) / arc.speed;\n\n if (currD < sensitivity) {\n arc = arc.clockwise !== arcToFollow.clockwise ? Arc.reverse(arc) : arc;\n arc = Arc.changeRadius(arc, arcToFollow.radius);\n\n if (arc.speed > arcToFollow.speed) {\n arc = Arc.changeSpeed(arc, arc.speed - 1);\n }\n\n if (arc.speed < arcToFollow.speed) {\n arc = Arc.changeSpeed(arc, arc.speed + 1);\n }\n } else if (rigidityCoeff < rigidity) {\n arc = Arc.changeRadius(arc, 20);\n\n if (arc.speed > arcToFollow.speed) {\n arc = Arc.changeSpeed(arc, arc.speed - 1);\n }\n } else {\n arc = Arc.changeRadius(arc, 4000);\n\n if (arc.speed < arcToFollow.speed + 2) {\n arc = Arc.changeSpeed(arc, arc.speed + 1);\n }\n }\n\n return arc;\n },\n\n evade: function evade(arc) {\n arc = Arc.changeRadius(arc, 15);\n arc.length = 0.3;\n\n return arc;\n }\n};\n\nexports.default = Arc;//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiODMuanMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vanMvYXJjLmpzPzliNWYiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgRU5USVRJRVMsIFJBRCB9IGZyb20gJy4vZW51bXMnO1xuaW1wb3J0IFJhbmRvbSBmcm9tICcuL3JhbmRvbSc7XG5cbi8vIFwiSG93IG11Y2ggb2YgbW92ZW1lbnQgaXMgaW4gdGhlIGNvcnJlY3QgZGlyZWN0aW9uXCJcbmNvbnN0IHJpZ2lkaXR5ID0gMC45O1xuLy8gXCJIb3cgY2xvc2UgdG8gdGhlIGxlYWRlciBpcyBlbm91Z2hcIlxuY29uc3Qgc2Vuc2l0aXZpdHkgPSAzMDtcblxuY29uc3QgQXJjID0ge1xuICAgIGNyZWF0ZTogZnVuY3Rpb24oYm91bmRzKSB7XG4gICAgICAgIGxldCBhcmMgPSB7XG4gICAgICAgICAgICBjZW50ZXJYOiBSYW5kb20ubnVtKDAsIGJvdW5kcy53aWR0aCksXG4gICAgICAgICAgICBjZW50ZXJZOiBSYW5kb20ubnVtKDAsIGJvdW5kcy5oZWlnaHQpLFxuICAgICAgICAgICAgY2xvY2t3aXNlOiBSYW5kb20uYm9vbCgpLFxuICAgICAgICAgICAgZW5kWDogMCxcbiAgICAgICAgICAgIGVuZFk6IDAsXG4gICAgICAgICAgICBsZW5ndGg6IFJhbmRvbS5udW0oUkFELnQ5MCwgUkFELnQzNjApLFxuICAgICAgICAgICAgcHJldkVuZFg6IDAsXG4gICAgICAgICAgICBwcmV2RW5kWTogMCxcbiAgICAgICAgICAgIHJhZGl1czogUmFuZG9tLm51bSgxMDAsIDIwMCksXG4gICAgICAgICAgICBzcGVlZDogMCxcbiAgICAgICAgICAgIHRoZXRhOiBSYW5kb20ubnVtKFJBRC50OTAsIFJBRC50MzYwKVxuICAgICAgICB9O1xuXG4gICAgICAgIGFyYy5jb3NUaGV0YSA9IE1hdGguY29zKGFyYy50aGV0YSk7XG4gICAgICAgIGFyYy5zaW5UaGV0YSA9IE1hdGguc2luKGFyYy50aGV0YSk7XG5cbiAgICAgICAgYXJjLmVuZFggPSBhcmMuY2VudGVyWCArIGFyYy5yYWRpdXMgKiBhcmMuY29zVGhldGE7XG4gICAgICAgIGFyYy5lbmRZID0gYXJjLmNlbnRlclkgLSBhcmMucmFkaXVzICogYXJjLnNpblRoZXRhO1xuXG4gICAgICAgIGFyYyA9IEFyYy5vdmVyZmxvdyhhcmMsIGJvdW5kcyk7XG5cbiAgICAgICAgcmV0dXJuIGFyYztcbiAgICB9LFxuXG4gICAgc3RlcDogZnVuY3Rpb24oYXJjLCBib3VuZHMpIHtcbiAgICAgICAgLy8gRW5zdXJlIGNvbnN0YW50IHZlbG9jaXR5IGFuZCB0aGV0YSBiZXR3ZWVuIDAgYW5kIDLPgC5cbiAgICAgICAgY29uc3QgZGVsdGEgPSBhcmMuc3BlZWQgLyBhcmMucmFkaXVzO1xuICAgICAgICBhcmMubGVuZ3RoIC09IGRlbHRhO1xuXG4gICAgICAgIGFyYy50aGV0YSArPSAoYXJjLmNsb2Nrd2lzZSA/IC1kZWx0YSA6ICtkZWx0YSk7XG4gICAgICAgIGFyYy50aGV0YSA9IChhcmMudGhldGEgPiAwID8gYXJjLnRoZXRhICUgUkFELnQzNjAgOiBSQUQudDM2MCArIGFyYy50aGV0YSk7XG5cbiAgICAgICAgYXJjLmNvc1RoZXRhID0gTWF0aC5jb3MoYXJjLnRoZXRhKTtcbiAgICAgICAgYXJjLnNpblRoZXRhID0gTWF0aC5zaW4oYXJjLnRoZXRhKTtcblxuICAgICAgICBhcmMucHJldkVuZFggPSBhcmMuZW5kWDtcbiAgICAgICAgYXJjLnByZXZFbmRZID0gYXJjLmVuZFk7XG5cbiAgICAgICAgYXJjLmVuZFggPSBhcmMuY2VudGVyWCArIGFyYy5yYWRpdXMgKiBhcmMuY29zVGhldGE7XG4gICAgICAgIGFyYy5lbmRZID0gYXJjLmNlbnRlclkgLSBhcmMucmFkaXVzICogYXJjLnNpblRoZXRhO1xuXG4gICAgICAgIGFyYyA9IEFyYy5vdmVyZmxvdyhhcmMsIGJvdW5kcyk7XG5cbiAgICAgICAgcmV0dXJuIGFyYztcbiAgICB9LFxuXG4gICAgcmFuZG9taXplOiBmdW5jdGlvbihhcmMpIHtcbiAgICAgICAgYXJjLmxlbmd0aCA9IFJhbmRvbS5udW0oUkFELnQ5MCwgUkFELnQzNjApO1xuXG4gICAgICAgIGFyYyA9IEFyYy5jaGFuZ2VSYWRpdXMoYXJjLCBSYW5kb20ubnVtKDEwMCwgMjAwKSk7XG5cbiAgICAgICAgaWYgKFJhbmRvbS5ib29sKDAuOCkpIHtcbiAgICAgICAgICAgIGFyYyA9IEFyYy5yZXZlcnNlKGFyYyk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gYXJjO1xuICAgIH0sXG5cbiAgICBvdmVyZmxvdzogZnVuY3Rpb24oYXJjLCBib3VuZHMpIHtcbiAgICAgICAgaWYgKGFyYy5lbmRYIDwgMCkge1xuICAgICAgICAgICAgYXJjLmVuZFggKz0gYm91bmRzLndpZHRoO1xuICAgICAgICAgICAgYXJjLmNlbnRlclggKz0gYm91bmRzLndpZHRoXG4gICAgICAgIH0gZWxzZSBpZiAoYXJjLmVuZFggPiBib3VuZHMud2lkdGgpIHtcbiAgICAgICAgICAgIGFyYy5lbmRYIC09IGJvdW5kcy53aWR0aDtcbiAgICAgICAgICAgIGFyYy5jZW50ZXJYIC09IGJvdW5kcy53aWR0aFxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGFyYy5lbmRZIDwgMCkge1xuICAgICAgICAgICAgYXJjLmVuZFkgKz0gYm91bmRzLmhlaWdodDtcbiAgICAgICAgICAgIGFyYy5jZW50ZXJZICs9IGJvdW5kcy5oZWlnaHRcbiAgICAgICAgfSBlbHNlIGlmIChhcmMuZW5kWSA+IGJvdW5kcy5oZWlnaHQpIHtcbiAgICAgICAgICAgIGFyYy5lbmRZIC09IGJvdW5kcy5oZWlnaHQ7XG4gICAgICAgICAgICBhcmMuY2VudGVyWSAtPSBib3VuZHMuaGVpZ2h0XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gYXJjO1xuICAgIH0sXG5cbiAgICBjaGFuZ2VSYWRpdXM6IGZ1bmN0aW9uKGFyYywgbmV3UmFkaXVzKSB7XG4gICAgICAgIGNvbnN0IHIwID0gYXJjLnJhZGl1cztcbiAgICAgICAgY29uc3QgcjEgPSBuZXdSYWRpdXM7XG5cbiAgICAgICAgLy8gTW92ZXMgYXJjIGNlbnRlciB0byBuZXcgcmFkaXVzIHdoaWxlIGtlZXBpbmcgdGhldGEgY29uc3RhbnQuXG4gICAgICAgIGFyYy5jZW50ZXJYIC09IChyMSAtIHIwKSAqIGFyYy5jb3NUaGV0YTtcbiAgICAgICAgYXJjLmNlbnRlclkgKz0gKHIxIC0gcjApICogYXJjLnNpblRoZXRhO1xuICAgICAgICBhcmMucmFkaXVzID0gcjE7XG5cbiAgICAgICAgcmV0dXJuIGFyYztcbiAgICB9LFxuXG4gICAgY2hhbmdlU3BlZWQ6IGZ1bmN0aW9uKGFyYywgbmV3U3BlZWQpIHtcbiAgICAgICAgYXJjLnNwZWVkID0gbmV3U3BlZWQgKiAxO1xuICAgICAgICByZXR1cm4gYXJjO1xuICAgIH0sXG5cbiAgICByZXZlcnNlOiBmdW5jdGlvbihhcmMpIHtcbiAgICAgICAgYXJjLmNsb2Nrd2lzZSA9ICFhcmMuY2xvY2t3aXNlO1xuXG4gICAgICAgIGFyYy50aGV0YSA9IChhcmMudGhldGEgKyBSQUQudDE4MCkgJSBSQUQudDM2MDtcblxuICAgICAgICBhcmMuY29zVGhldGEgPSBNYXRoLmNvcyhhcmMudGhldGEpO1xuICAgICAgICBhcmMuc2luVGhldGEgPSBNYXRoLnNpbihhcmMudGhldGEpO1xuXG4gICAgICAgIGFyYy5jZW50ZXJYIC09ICgyICogYXJjLnJhZGl1cykgKiBhcmMuY29zVGhldGE7XG4gICAgICAgIGFyYy5jZW50ZXJZICs9ICgyICogYXJjLnJhZGl1cykgKiBhcmMuc2luVGhldGE7XG5cbiAgICAgICAgcmV0dXJuIGFyYztcbiAgICB9LFxuXG4gICAgZm9sbG93OiBmdW5jdGlvbihhcmMsIGFyY1RvRm9sbG93KSB7XG4gICAgICAgIGNvbnN0IHByZXZEID0gTWF0aC5wb3coXG4gICAgICAgICAgICBNYXRoLnBvdyhhcmNUb0ZvbGxvdy5lbmRYIC0gYXJjLnByZXZFbmRYLCAyKSArXG4gICAgICAgICAgICBNYXRoLnBvdyhhcmNUb0ZvbGxvdy5lbmRZIC0gYXJjLnByZXZFbmRZLCAyKVxuICAgICAgICAsIDAuNSk7XG5cbiAgICAgICAgY29uc3QgY3VyckQgPSBNYXRoLnBvdyhcbiAgICAgICAgICAgIE1hdGgucG93KGFyY1RvRm9sbG93LmVuZFggLSBhcmMuZW5kWCwgMikgK1xuICAgICAgICAgICAgIE1hdGgucG93KGFyY1RvRm9sbG93LmVuZFkgLSBhcmMuZW5kWSwgMilcbiAgICAgICAgLCAwLjUpO1xuXG4gICAgICAgIGNvbnN0IHJpZ2lkaXR5Q29lZmYgPSAocHJldkQgLSBjdXJyRCkgLyBhcmMuc3BlZWQ7XG5cbiAgICAgICAgaWYgKGN1cnJEIDwgc2Vuc2l0aXZpdHkpIHtcbiAgICAgICAgICAgIGFyYyA9IChhcmMuY2xvY2t3aXNlICE9PSBhcmNUb0ZvbGxvdy5jbG9ja3dpc2UgPyBBcmMucmV2ZXJzZShhcmMpIDogYXJjKTtcbiAgICAgICAgICAgIGFyYyA9IEFyYy5jaGFuZ2VSYWRpdXMoYXJjLCBhcmNUb0ZvbGxvdy5yYWRpdXMpO1xuXG4gICAgICAgICAgICBpZiAoYXJjLnNwZWVkID4gYXJjVG9Gb2xsb3cuc3BlZWQpIHtcbiAgICAgICAgICAgICAgICBhcmMgPSBBcmMuY2hhbmdlU3BlZWQoYXJjLCBhcmMuc3BlZWQgLSAxKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKGFyYy5zcGVlZCA8IGFyY1RvRm9sbG93LnNwZWVkKSB7XG4gICAgICAgICAgICAgICAgYXJjID0gQXJjLmNoYW5nZVNwZWVkKGFyYywgYXJjLnNwZWVkICsgMSk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgfSBlbHNlIGlmIChyaWdpZGl0eUNvZWZmIDwgcmlnaWRpdHkpIHtcbiAgICAgICAgICAgIGFyYyA9IEFyYy5jaGFuZ2VSYWRpdXMoYXJjLCAyMCk7XG5cbiAgICAgICAgICAgIGlmIChhcmMuc3BlZWQgPiBhcmNUb0ZvbGxvdy5zcGVlZCkge1xuICAgICAgICAgICAgICAgIGFyYyA9IEFyYy5jaGFuZ2VTcGVlZChhcmMsIGFyYy5zcGVlZCAtIDEpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgYXJjID0gQXJjLmNoYW5nZVJhZGl1cyhhcmMsIDQwMDApO1xuXG4gICAgICAgICAgICBpZiAoYXJjLnNwZWVkIDwgYXJjVG9Gb2xsb3cuc3BlZWQgKyAyKSB7XG4gICAgICAgICAgICAgICAgYXJjID0gQXJjLmNoYW5nZVNwZWVkKGFyYywgYXJjLnNwZWVkICsgMSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gYXJjO1xuICAgIH0sXG5cbiAgICBldmFkZTogZnVuY3Rpb24oYXJjKSB7XG4gICAgICAgIGFyYyA9IEFyYy5jaGFuZ2VSYWRpdXMoYXJjLCAxNSk7XG4gICAgICAgIGFyYy5sZW5ndGggPSAwLjM7XG5cbiAgICAgICAgcmV0dXJuIGFyYztcbiAgICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IEFyYztcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyBqcy9hcmMuanMiXSwibWFwcGluZ3MiOiI7Ozs7OztBQUFBO0FBQ0E7QUFBQTtBQUNBOzs7OztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBWEE7QUFDQTtBQWFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUlBO0FBQ0E7QUFJQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUEvSkE7QUFDQTtBQWlLQSIsInNvdXJjZVJvb3QiOiIifQ=="); +eval("\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nvar _enums = __webpack_require__(/*! ./enums */ 22);\n\nvar _random = __webpack_require__(/*! ./random */ 33);\n\nvar _random2 = _interopRequireDefault(_random);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\n// \"How much of movement is in the correct direction\"\nvar rigidity = 0.9;\n// \"How close to the leader is enough\"\nvar sensitivity = 30;\n\nvar Arc = {\n create: function create(bounds) {\n var arc = {\n centerX: _random2.default.num(0, bounds.width),\n centerY: _random2.default.num(0, bounds.height),\n clockwise: _random2.default.bool(),\n endX: 0,\n endY: 0,\n length: _random2.default.num(_enums.RAD.t90, _enums.RAD.t360),\n prevEndX: 0,\n prevEndY: 0,\n radius: _random2.default.num(100, 200),\n speed: 0,\n theta: _random2.default.num(_enums.RAD.t90, _enums.RAD.t360)\n };\n\n arc.cosTheta = Math.cos(arc.theta);\n arc.sinTheta = Math.sin(arc.theta);\n\n arc.endX = arc.centerX + arc.radius * arc.cosTheta;\n arc.endY = arc.centerY - arc.radius * arc.sinTheta;\n\n arc = Arc.overflow(arc, bounds);\n\n return arc;\n },\n\n step: function step(arc, bounds) {\n // Ensure constant velocity and theta between 0 and 2π.\n var delta = arc.speed / arc.radius;\n arc.length -= delta;\n\n arc.theta += arc.clockwise ? -delta : +delta;\n arc.theta = arc.theta > 0 ? arc.theta % _enums.RAD.t360 : _enums.RAD.t360 + arc.theta;\n\n arc.cosTheta = Math.cos(arc.theta);\n arc.sinTheta = Math.sin(arc.theta);\n\n arc.prevEndX = arc.endX;\n arc.prevEndY = arc.endY;\n\n arc.endX = arc.centerX + arc.radius * arc.cosTheta;\n arc.endY = arc.centerY - arc.radius * arc.sinTheta;\n\n arc = Arc.overflow(arc, bounds);\n\n return arc;\n },\n\n randomize: function randomize(arc) {\n arc.length = _random2.default.num(_enums.RAD.t90, _enums.RAD.t360);\n\n arc = Arc.changeRadius(arc, _random2.default.num(100, 200));\n\n if (_random2.default.bool(0.8)) {\n arc = Arc.reverse(arc);\n }\n\n return arc;\n },\n\n overflow: function overflow(arc, bounds) {\n if (arc.endX < 0) {\n arc.endX += bounds.width;\n arc.centerX += bounds.width;\n } else if (arc.endX > bounds.width) {\n arc.endX -= bounds.width;\n arc.centerX -= bounds.width;\n }\n\n if (arc.endY < 0) {\n arc.endY += bounds.height;\n arc.centerY += bounds.height;\n } else if (arc.endY > bounds.height) {\n arc.endY -= bounds.height;\n arc.centerY -= bounds.height;\n }\n\n return arc;\n },\n\n changeRadius: function changeRadius(arc, newRadius) {\n var r0 = arc.radius;\n var r1 = newRadius;\n\n // Moves arc center to new radius while keeping theta constant.\n arc.centerX -= (r1 - r0) * arc.cosTheta;\n arc.centerY += (r1 - r0) * arc.sinTheta;\n arc.radius = r1;\n\n return arc;\n },\n\n changeSpeed: function changeSpeed(arc, newSpeed) {\n arc.speed = newSpeed * 1;\n return arc;\n },\n\n reverse: function reverse(arc) {\n arc.clockwise = !arc.clockwise;\n\n arc.theta = (arc.theta + _enums.RAD.t180) % _enums.RAD.t360;\n\n arc.cosTheta = Math.cos(arc.theta);\n arc.sinTheta = Math.sin(arc.theta);\n\n arc.centerX -= 2 * arc.radius * arc.cosTheta;\n arc.centerY += 2 * arc.radius * arc.sinTheta;\n\n return arc;\n },\n\n follow: function follow(arc, arcToFollow) {\n var prevD = Math.pow(Math.pow(arcToFollow.endX - arc.prevEndX, 2) + Math.pow(arcToFollow.endY - arc.prevEndY, 2), 0.5);\n\n var currD = Math.pow(Math.pow(arcToFollow.endX - arc.endX, 2) + Math.pow(arcToFollow.endY - arc.endY, 2), 0.5);\n\n var rigidityCoeff = (prevD - currD) / arc.speed;\n\n if (currD < sensitivity) {\n arc = arc.clockwise !== arcToFollow.clockwise ? Arc.reverse(arc) : arc;\n arc = Arc.changeRadius(arc, arcToFollow.radius);\n\n if (arc.speed > arcToFollow.speed) {\n arc = Arc.changeSpeed(arc, arc.speed - 1);\n }\n\n if (arc.speed < arcToFollow.speed) {\n arc = Arc.changeSpeed(arc, arc.speed + 1);\n }\n } else if (rigidityCoeff < rigidity) {\n arc = Arc.changeRadius(arc, 20);\n\n if (arc.speed > arcToFollow.speed) {\n arc = Arc.changeSpeed(arc, arc.speed - 1);\n }\n } else {\n arc = Arc.changeRadius(arc, 4000);\n\n if (arc.speed < arcToFollow.speed + 2) {\n arc = Arc.changeSpeed(arc, arc.speed + 1);\n }\n }\n\n return arc;\n },\n\n evade: function evade(arc) {\n // Randomness here mitigates sticking in corners and between walls.\n arc = Arc.changeRadius(arc, _random2.default.num(15, 30));\n arc.length = 0.3;\n\n return arc;\n }\n};\n\nexports.default = Arc;//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiODMuanMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vanMvYXJjLmpzPzliNWYiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgRU5USVRJRVMsIFJBRCB9IGZyb20gJy4vZW51bXMnO1xuaW1wb3J0IFJhbmRvbSBmcm9tICcuL3JhbmRvbSc7XG5cbi8vIFwiSG93IG11Y2ggb2YgbW92ZW1lbnQgaXMgaW4gdGhlIGNvcnJlY3QgZGlyZWN0aW9uXCJcbmNvbnN0IHJpZ2lkaXR5ID0gMC45O1xuLy8gXCJIb3cgY2xvc2UgdG8gdGhlIGxlYWRlciBpcyBlbm91Z2hcIlxuY29uc3Qgc2Vuc2l0aXZpdHkgPSAzMDtcblxuY29uc3QgQXJjID0ge1xuICAgIGNyZWF0ZTogZnVuY3Rpb24oYm91bmRzKSB7XG4gICAgICAgIGxldCBhcmMgPSB7XG4gICAgICAgICAgICBjZW50ZXJYOiBSYW5kb20ubnVtKDAsIGJvdW5kcy53aWR0aCksXG4gICAgICAgICAgICBjZW50ZXJZOiBSYW5kb20ubnVtKDAsIGJvdW5kcy5oZWlnaHQpLFxuICAgICAgICAgICAgY2xvY2t3aXNlOiBSYW5kb20uYm9vbCgpLFxuICAgICAgICAgICAgZW5kWDogMCxcbiAgICAgICAgICAgIGVuZFk6IDAsXG4gICAgICAgICAgICBsZW5ndGg6IFJhbmRvbS5udW0oUkFELnQ5MCwgUkFELnQzNjApLFxuICAgICAgICAgICAgcHJldkVuZFg6IDAsXG4gICAgICAgICAgICBwcmV2RW5kWTogMCxcbiAgICAgICAgICAgIHJhZGl1czogUmFuZG9tLm51bSgxMDAsIDIwMCksXG4gICAgICAgICAgICBzcGVlZDogMCxcbiAgICAgICAgICAgIHRoZXRhOiBSYW5kb20ubnVtKFJBRC50OTAsIFJBRC50MzYwKVxuICAgICAgICB9O1xuXG4gICAgICAgIGFyYy5jb3NUaGV0YSA9IE1hdGguY29zKGFyYy50aGV0YSk7XG4gICAgICAgIGFyYy5zaW5UaGV0YSA9IE1hdGguc2luKGFyYy50aGV0YSk7XG5cbiAgICAgICAgYXJjLmVuZFggPSBhcmMuY2VudGVyWCArIGFyYy5yYWRpdXMgKiBhcmMuY29zVGhldGE7XG4gICAgICAgIGFyYy5lbmRZID0gYXJjLmNlbnRlclkgLSBhcmMucmFkaXVzICogYXJjLnNpblRoZXRhO1xuXG4gICAgICAgIGFyYyA9IEFyYy5vdmVyZmxvdyhhcmMsIGJvdW5kcyk7XG5cbiAgICAgICAgcmV0dXJuIGFyYztcbiAgICB9LFxuXG4gICAgc3RlcDogZnVuY3Rpb24oYXJjLCBib3VuZHMpIHtcbiAgICAgICAgLy8gRW5zdXJlIGNvbnN0YW50IHZlbG9jaXR5IGFuZCB0aGV0YSBiZXR3ZWVuIDAgYW5kIDLPgC5cbiAgICAgICAgY29uc3QgZGVsdGEgPSBhcmMuc3BlZWQgLyBhcmMucmFkaXVzO1xuICAgICAgICBhcmMubGVuZ3RoIC09IGRlbHRhO1xuXG4gICAgICAgIGFyYy50aGV0YSArPSAoYXJjLmNsb2Nrd2lzZSA/IC1kZWx0YSA6ICtkZWx0YSk7XG4gICAgICAgIGFyYy50aGV0YSA9IChhcmMudGhldGEgPiAwID8gYXJjLnRoZXRhICUgUkFELnQzNjAgOiBSQUQudDM2MCArIGFyYy50aGV0YSk7XG5cbiAgICAgICAgYXJjLmNvc1RoZXRhID0gTWF0aC5jb3MoYXJjLnRoZXRhKTtcbiAgICAgICAgYXJjLnNpblRoZXRhID0gTWF0aC5zaW4oYXJjLnRoZXRhKTtcblxuICAgICAgICBhcmMucHJldkVuZFggPSBhcmMuZW5kWDtcbiAgICAgICAgYXJjLnByZXZFbmRZID0gYXJjLmVuZFk7XG5cbiAgICAgICAgYXJjLmVuZFggPSBhcmMuY2VudGVyWCArIGFyYy5yYWRpdXMgKiBhcmMuY29zVGhldGE7XG4gICAgICAgIGFyYy5lbmRZID0gYXJjLmNlbnRlclkgLSBhcmMucmFkaXVzICogYXJjLnNpblRoZXRhO1xuXG4gICAgICAgIGFyYyA9IEFyYy5vdmVyZmxvdyhhcmMsIGJvdW5kcyk7XG5cbiAgICAgICAgcmV0dXJuIGFyYztcbiAgICB9LFxuXG4gICAgcmFuZG9taXplOiBmdW5jdGlvbihhcmMpIHtcbiAgICAgICAgYXJjLmxlbmd0aCA9IFJhbmRvbS5udW0oUkFELnQ5MCwgUkFELnQzNjApO1xuXG4gICAgICAgIGFyYyA9IEFyYy5jaGFuZ2VSYWRpdXMoYXJjLCBSYW5kb20ubnVtKDEwMCwgMjAwKSk7XG5cbiAgICAgICAgaWYgKFJhbmRvbS5ib29sKDAuOCkpIHtcbiAgICAgICAgICAgIGFyYyA9IEFyYy5yZXZlcnNlKGFyYyk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gYXJjO1xuICAgIH0sXG5cbiAgICBvdmVyZmxvdzogZnVuY3Rpb24oYXJjLCBib3VuZHMpIHtcbiAgICAgICAgaWYgKGFyYy5lbmRYIDwgMCkge1xuICAgICAgICAgICAgYXJjLmVuZFggKz0gYm91bmRzLndpZHRoO1xuICAgICAgICAgICAgYXJjLmNlbnRlclggKz0gYm91bmRzLndpZHRoXG4gICAgICAgIH0gZWxzZSBpZiAoYXJjLmVuZFggPiBib3VuZHMud2lkdGgpIHtcbiAgICAgICAgICAgIGFyYy5lbmRYIC09IGJvdW5kcy53aWR0aDtcbiAgICAgICAgICAgIGFyYy5jZW50ZXJYIC09IGJvdW5kcy53aWR0aFxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGFyYy5lbmRZIDwgMCkge1xuICAgICAgICAgICAgYXJjLmVuZFkgKz0gYm91bmRzLmhlaWdodDtcbiAgICAgICAgICAgIGFyYy5jZW50ZXJZICs9IGJvdW5kcy5oZWlnaHRcbiAgICAgICAgfSBlbHNlIGlmIChhcmMuZW5kWSA+IGJvdW5kcy5oZWlnaHQpIHtcbiAgICAgICAgICAgIGFyYy5lbmRZIC09IGJvdW5kcy5oZWlnaHQ7XG4gICAgICAgICAgICBhcmMuY2VudGVyWSAtPSBib3VuZHMuaGVpZ2h0XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gYXJjO1xuICAgIH0sXG5cbiAgICBjaGFuZ2VSYWRpdXM6IGZ1bmN0aW9uKGFyYywgbmV3UmFkaXVzKSB7XG4gICAgICAgIGNvbnN0IHIwID0gYXJjLnJhZGl1cztcbiAgICAgICAgY29uc3QgcjEgPSBuZXdSYWRpdXM7XG5cbiAgICAgICAgLy8gTW92ZXMgYXJjIGNlbnRlciB0byBuZXcgcmFkaXVzIHdoaWxlIGtlZXBpbmcgdGhldGEgY29uc3RhbnQuXG4gICAgICAgIGFyYy5jZW50ZXJYIC09IChyMSAtIHIwKSAqIGFyYy5jb3NUaGV0YTtcbiAgICAgICAgYXJjLmNlbnRlclkgKz0gKHIxIC0gcjApICogYXJjLnNpblRoZXRhO1xuICAgICAgICBhcmMucmFkaXVzID0gcjE7XG5cbiAgICAgICAgcmV0dXJuIGFyYztcbiAgICB9LFxuXG4gICAgY2hhbmdlU3BlZWQ6IGZ1bmN0aW9uKGFyYywgbmV3U3BlZWQpIHtcbiAgICAgICAgYXJjLnNwZWVkID0gbmV3U3BlZWQgKiAxO1xuICAgICAgICByZXR1cm4gYXJjO1xuICAgIH0sXG5cbiAgICByZXZlcnNlOiBmdW5jdGlvbihhcmMpIHtcbiAgICAgICAgYXJjLmNsb2Nrd2lzZSA9ICFhcmMuY2xvY2t3aXNlO1xuXG4gICAgICAgIGFyYy50aGV0YSA9IChhcmMudGhldGEgKyBSQUQudDE4MCkgJSBSQUQudDM2MDtcblxuICAgICAgICBhcmMuY29zVGhldGEgPSBNYXRoLmNvcyhhcmMudGhldGEpO1xuICAgICAgICBhcmMuc2luVGhldGEgPSBNYXRoLnNpbihhcmMudGhldGEpO1xuXG4gICAgICAgIGFyYy5jZW50ZXJYIC09ICgyICogYXJjLnJhZGl1cykgKiBhcmMuY29zVGhldGE7XG4gICAgICAgIGFyYy5jZW50ZXJZICs9ICgyICogYXJjLnJhZGl1cykgKiBhcmMuc2luVGhldGE7XG5cbiAgICAgICAgcmV0dXJuIGFyYztcbiAgICB9LFxuXG4gICAgZm9sbG93OiBmdW5jdGlvbihhcmMsIGFyY1RvRm9sbG93KSB7XG4gICAgICAgIGNvbnN0IHByZXZEID0gTWF0aC5wb3coXG4gICAgICAgICAgICBNYXRoLnBvdyhhcmNUb0ZvbGxvdy5lbmRYIC0gYXJjLnByZXZFbmRYLCAyKSArXG4gICAgICAgICAgICBNYXRoLnBvdyhhcmNUb0ZvbGxvdy5lbmRZIC0gYXJjLnByZXZFbmRZLCAyKVxuICAgICAgICAsIDAuNSk7XG5cbiAgICAgICAgY29uc3QgY3VyckQgPSBNYXRoLnBvdyhcbiAgICAgICAgICAgIE1hdGgucG93KGFyY1RvRm9sbG93LmVuZFggLSBhcmMuZW5kWCwgMikgK1xuICAgICAgICAgICAgIE1hdGgucG93KGFyY1RvRm9sbG93LmVuZFkgLSBhcmMuZW5kWSwgMilcbiAgICAgICAgLCAwLjUpO1xuXG4gICAgICAgIGNvbnN0IHJpZ2lkaXR5Q29lZmYgPSAocHJldkQgLSBjdXJyRCkgLyBhcmMuc3BlZWQ7XG5cbiAgICAgICAgaWYgKGN1cnJEIDwgc2Vuc2l0aXZpdHkpIHtcbiAgICAgICAgICAgIGFyYyA9IChhcmMuY2xvY2t3aXNlICE9PSBhcmNUb0ZvbGxvdy5jbG9ja3dpc2UgPyBBcmMucmV2ZXJzZShhcmMpIDogYXJjKTtcbiAgICAgICAgICAgIGFyYyA9IEFyYy5jaGFuZ2VSYWRpdXMoYXJjLCBhcmNUb0ZvbGxvdy5yYWRpdXMpO1xuXG4gICAgICAgICAgICBpZiAoYXJjLnNwZWVkID4gYXJjVG9Gb2xsb3cuc3BlZWQpIHtcbiAgICAgICAgICAgICAgICBhcmMgPSBBcmMuY2hhbmdlU3BlZWQoYXJjLCBhcmMuc3BlZWQgLSAxKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKGFyYy5zcGVlZCA8IGFyY1RvRm9sbG93LnNwZWVkKSB7XG4gICAgICAgICAgICAgICAgYXJjID0gQXJjLmNoYW5nZVNwZWVkKGFyYywgYXJjLnNwZWVkICsgMSk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgfSBlbHNlIGlmIChyaWdpZGl0eUNvZWZmIDwgcmlnaWRpdHkpIHtcbiAgICAgICAgICAgIGFyYyA9IEFyYy5jaGFuZ2VSYWRpdXMoYXJjLCAyMCk7XG5cbiAgICAgICAgICAgIGlmIChhcmMuc3BlZWQgPiBhcmNUb0ZvbGxvdy5zcGVlZCkge1xuICAgICAgICAgICAgICAgIGFyYyA9IEFyYy5jaGFuZ2VTcGVlZChhcmMsIGFyYy5zcGVlZCAtIDEpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgYXJjID0gQXJjLmNoYW5nZVJhZGl1cyhhcmMsIDQwMDApO1xuXG4gICAgICAgICAgICBpZiAoYXJjLnNwZWVkIDwgYXJjVG9Gb2xsb3cuc3BlZWQgKyAyKSB7XG4gICAgICAgICAgICAgICAgYXJjID0gQXJjLmNoYW5nZVNwZWVkKGFyYywgYXJjLnNwZWVkICsgMSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gYXJjO1xuICAgIH0sXG5cbiAgICBldmFkZTogZnVuY3Rpb24oYXJjKSB7XG4gICAgICAgIC8vIFJhbmRvbW5lc3MgaGVyZSBtaXRpZ2F0ZXMgc3RpY2tpbmcgaW4gY29ybmVycyBhbmQgYmV0d2VlbiB3YWxscy5cbiAgICAgICAgYXJjID0gQXJjLmNoYW5nZVJhZGl1cyhhcmMsIFJhbmRvbS5udW0oMTUsIDMwKSk7XG4gICAgICAgIGFyYy5sZW5ndGggPSAwLjM7XG5cbiAgICAgICAgcmV0dXJuIGFyYztcbiAgICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IEFyYztcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyBqcy9hcmMuanMiXSwibWFwcGluZ3MiOiI7Ozs7OztBQUFBO0FBQ0E7QUFBQTtBQUNBOzs7OztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBWEE7QUFDQTtBQWFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUlBO0FBQ0E7QUFJQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQWhLQTtBQUNBO0FBa0tBIiwic291cmNlUm9vdCI6IiJ9"); /***/ }), /* 84 */ @@ -1090,7 +1090,7 @@ eval("\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n}); /***/ (function(module, exports, __webpack_require__) { "use strict"; -eval("\n\nvar _rxjs = __webpack_require__(/*! rxjs */ 21);\n\nvar _rxjs2 = _interopRequireDefault(_rxjs);\n\nvar _animation1a = __webpack_require__(/*! ./animation1a */ 73);\n\nvar _animation1a2 = _interopRequireDefault(_animation1a);\n\nvar _animation1b = __webpack_require__(/*! ./animation1b */ 74);\n\nvar _animation1b2 = _interopRequireDefault(_animation1b);\n\nvar _animation2a = __webpack_require__(/*! ./animation2a */ 75);\n\nvar _animation2a2 = _interopRequireDefault(_animation2a);\n\nvar _animation2b = __webpack_require__(/*! ./animation2b */ 76);\n\nvar _animation2b2 = _interopRequireDefault(_animation2b);\n\nvar _animation3a = __webpack_require__(/*! ./animation3a */ 77);\n\nvar _animation3a2 = _interopRequireDefault(_animation3a);\n\nvar _animation3b = __webpack_require__(/*! ./animation3b */ 78);\n\nvar _animation3b2 = _interopRequireDefault(_animation3b);\n\nvar _animation3c = __webpack_require__(/*! ./animation3c */ 363);\n\nvar _animation3c2 = _interopRequireDefault(_animation3c);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\n__webpack_require__(/*! ../css/reset.scss */ 82);\n__webpack_require__(/*! ../css/index.scss */ 80);\n__webpack_require__(/*! ../css/particle.scss */ 81);\n__webpack_require__(/*! ../css/controls.scss */ 79);\n\nwindow.addEventListener('load', function () {\n var destroy$ = new _rxjs2.default.BehaviorSubject(null);\n\n // window.addEventListener('blur', () => {\n // destroy$.next('all');\n // });\n\n (0, _animation1a2.default)(destroy$);\n (0, _animation1b2.default)(destroy$);\n (0, _animation2a2.default)(destroy$);\n (0, _animation2b2.default)(destroy$);\n (0, _animation3a2.default)(destroy$);\n (0, _animation3b2.default)(destroy$);\n (0, _animation3c2.default)(destroy$);\n});\n\n// TODO remove bottom padding from Disqus\n// TODO sort out particle nextframe\n\n// INTERESTING CONTROLS:\n// sensitivity\n// rigidity\n// show leaders\n\n// TURN THE CORRECT DIRECTION - HUGE EFFICIENCY INCREASE//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiODUuanMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vanMvaW5kZXguanM/NDJmNiJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgUngsIHsgT2JzZXJ2YWJsZSB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IEFuaW1hdGlvbjFhIGZyb20gJy4vYW5pbWF0aW9uMWEnO1xuaW1wb3J0IEFuaW1hdGlvbjFiIGZyb20gJy4vYW5pbWF0aW9uMWInO1xuaW1wb3J0IEFuaW1hdGlvbjJhIGZyb20gJy4vYW5pbWF0aW9uMmEnO1xuaW1wb3J0IEFuaW1hdGlvbjJiIGZyb20gJy4vYW5pbWF0aW9uMmInO1xuaW1wb3J0IEFuaW1hdGlvbjNhIGZyb20gJy4vYW5pbWF0aW9uM2EnO1xuaW1wb3J0IEFuaW1hdGlvbjNiIGZyb20gJy4vYW5pbWF0aW9uM2InO1xuaW1wb3J0IEFuaW1hdGlvbjNjIGZyb20gJy4vYW5pbWF0aW9uM2MnO1xuXG5yZXF1aXJlKCcuLi9jc3MvcmVzZXQuc2NzcycpO1xucmVxdWlyZSgnLi4vY3NzL2luZGV4LnNjc3MnKTtcbnJlcXVpcmUoJy4uL2Nzcy9wYXJ0aWNsZS5zY3NzJyk7XG5yZXF1aXJlKCcuLi9jc3MvY29udHJvbHMuc2NzcycpO1xuXG53aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcignbG9hZCcsICgpID0+IHtcbiAgICBjb25zdCBkZXN0cm95JCA9IG5ldyBSeC5CZWhhdmlvclN1YmplY3QobnVsbCk7XG5cbiAgICAvLyB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcignYmx1cicsICgpID0+IHtcbiAgICAvLyAgICAgZGVzdHJveSQubmV4dCgnYWxsJyk7XG4gICAgLy8gfSk7XG5cbiAgICBBbmltYXRpb24xYShkZXN0cm95JCk7XG4gICAgQW5pbWF0aW9uMWIoZGVzdHJveSQpO1xuICAgIEFuaW1hdGlvbjJhKGRlc3Ryb3kkKTtcbiAgICBBbmltYXRpb24yYihkZXN0cm95JCk7XG4gICAgQW5pbWF0aW9uM2EoZGVzdHJveSQpO1xuICAgIEFuaW1hdGlvbjNiKGRlc3Ryb3kkKTtcbiAgICBBbmltYXRpb24zYyhkZXN0cm95JCk7XG59KTtcblxuLy8gVE9ETyByZW1vdmUgYm90dG9tIHBhZGRpbmcgZnJvbSBEaXNxdXNcbi8vIFRPRE8gc29ydCBvdXQgcGFydGljbGUgbmV4dGZyYW1lXG5cbi8vIElOVEVSRVNUSU5HIENPTlRST0xTOlxuLy8gc2Vuc2l0aXZpdHlcbi8vIHJpZ2lkaXR5XG4vLyBzaG93IGxlYWRlcnNcblxuLy8gVFVSTiBUSEUgQ09SUkVDVCBESVJFQ1RJT04gLSBIVUdFIEVGRklDSUVOQ1kgSU5DUkVBU0VcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyBqcy9pbmRleC5qcyJdLCJtYXBwaW5ncyI6Ijs7QUFBQTtBQUNBOzs7QUFBQTtBQUNBOzs7QUFBQTtBQUNBOzs7QUFBQTtBQUNBOzs7QUFBQTtBQUNBOzs7QUFBQTtBQUNBOzs7QUFBQTtBQUNBOzs7QUFBQTtBQUNBOzs7OztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZVJvb3QiOiIifQ=="); +eval("\n\nvar _rxjs = __webpack_require__(/*! rxjs */ 21);\n\nvar _rxjs2 = _interopRequireDefault(_rxjs);\n\nvar _animation1a = __webpack_require__(/*! ./animation1a */ 73);\n\nvar _animation1a2 = _interopRequireDefault(_animation1a);\n\nvar _animation1b = __webpack_require__(/*! ./animation1b */ 74);\n\nvar _animation1b2 = _interopRequireDefault(_animation1b);\n\nvar _animation2a = __webpack_require__(/*! ./animation2a */ 75);\n\nvar _animation2a2 = _interopRequireDefault(_animation2a);\n\nvar _animation2b = __webpack_require__(/*! ./animation2b */ 76);\n\nvar _animation2b2 = _interopRequireDefault(_animation2b);\n\nvar _animation3a = __webpack_require__(/*! ./animation3a */ 77);\n\nvar _animation3a2 = _interopRequireDefault(_animation3a);\n\nvar _animation3b = __webpack_require__(/*! ./animation3b */ 78);\n\nvar _animation3b2 = _interopRequireDefault(_animation3b);\n\nvar _animation3c = __webpack_require__(/*! ./animation3c */ 363);\n\nvar _animation3c2 = _interopRequireDefault(_animation3c);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\n__webpack_require__(/*! ../css/reset.scss */ 82);\n__webpack_require__(/*! ../css/index.scss */ 80);\n__webpack_require__(/*! ../css/particle.scss */ 81);\n__webpack_require__(/*! ../css/controls.scss */ 79);\n\nwindow.addEventListener('load', function () {\n var destroy$ = new _rxjs2.default.BehaviorSubject(null);\n\n // window.addEventListener('blur', () => {\n // destroy$.next('all');\n // });\n\n (0, _animation1a2.default)(destroy$);\n (0, _animation1b2.default)(destroy$);\n (0, _animation2a2.default)(destroy$);\n (0, _animation2b2.default)(destroy$);\n (0, _animation3a2.default)(destroy$);\n (0, _animation3b2.default)(destroy$);\n (0, _animation3c2.default)(destroy$);\n});\n\n// TODO remove bottom padding from Disqus\n// TODO TURN THE CORRECT DIRECTION - HUGE EFFICIENCY INCREASE//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiODUuanMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vanMvaW5kZXguanM/NDJmNiJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgUngsIHsgT2JzZXJ2YWJsZSB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IEFuaW1hdGlvbjFhIGZyb20gJy4vYW5pbWF0aW9uMWEnO1xuaW1wb3J0IEFuaW1hdGlvbjFiIGZyb20gJy4vYW5pbWF0aW9uMWInO1xuaW1wb3J0IEFuaW1hdGlvbjJhIGZyb20gJy4vYW5pbWF0aW9uMmEnO1xuaW1wb3J0IEFuaW1hdGlvbjJiIGZyb20gJy4vYW5pbWF0aW9uMmInO1xuaW1wb3J0IEFuaW1hdGlvbjNhIGZyb20gJy4vYW5pbWF0aW9uM2EnO1xuaW1wb3J0IEFuaW1hdGlvbjNiIGZyb20gJy4vYW5pbWF0aW9uM2InO1xuaW1wb3J0IEFuaW1hdGlvbjNjIGZyb20gJy4vYW5pbWF0aW9uM2MnO1xuXG5yZXF1aXJlKCcuLi9jc3MvcmVzZXQuc2NzcycpO1xucmVxdWlyZSgnLi4vY3NzL2luZGV4LnNjc3MnKTtcbnJlcXVpcmUoJy4uL2Nzcy9wYXJ0aWNsZS5zY3NzJyk7XG5yZXF1aXJlKCcuLi9jc3MvY29udHJvbHMuc2NzcycpO1xuXG53aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcignbG9hZCcsICgpID0+IHtcbiAgICBjb25zdCBkZXN0cm95JCA9IG5ldyBSeC5CZWhhdmlvclN1YmplY3QobnVsbCk7XG5cbiAgICAvLyB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcignYmx1cicsICgpID0+IHtcbiAgICAvLyAgICAgZGVzdHJveSQubmV4dCgnYWxsJyk7XG4gICAgLy8gfSk7XG5cbiAgICBBbmltYXRpb24xYShkZXN0cm95JCk7XG4gICAgQW5pbWF0aW9uMWIoZGVzdHJveSQpO1xuICAgIEFuaW1hdGlvbjJhKGRlc3Ryb3kkKTtcbiAgICBBbmltYXRpb24yYihkZXN0cm95JCk7XG4gICAgQW5pbWF0aW9uM2EoZGVzdHJveSQpO1xuICAgIEFuaW1hdGlvbjNiKGRlc3Ryb3kkKTtcbiAgICBBbmltYXRpb24zYyhkZXN0cm95JCk7XG59KTtcblxuLy8gVE9ETyByZW1vdmUgYm90dG9tIHBhZGRpbmcgZnJvbSBEaXNxdXNcbi8vIFRPRE8gVFVSTiBUSEUgQ09SUkVDVCBESVJFQ1RJT04gLSBIVUdFIEVGRklDSUVOQ1kgSU5DUkVBU0VcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyBqcy9pbmRleC5qcyJdLCJtYXBwaW5ncyI6Ijs7QUFBQTtBQUNBOzs7QUFBQTtBQUNBOzs7QUFBQTtBQUNBOzs7QUFBQTtBQUNBOzs7QUFBQTtBQUNBOzs7QUFBQTtBQUNBOzs7QUFBQTtBQUNBOzs7QUFBQTtBQUNBOzs7OztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJzb3VyY2VSb290IjoiIn0="); /***/ }), /* 86 */ @@ -1102,7 +1102,7 @@ eval("\n\nvar _rxjs = __webpack_require__(/*! rxjs */ 21);\n\nvar _rxjs2 = _inte /***/ (function(module, exports, __webpack_require__) { "use strict"; -eval("\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nvar _rxjs = __webpack_require__(/*! rxjs */ 21);\n\nvar _rxjs2 = _interopRequireDefault(_rxjs);\n\nvar _enums = __webpack_require__(/*! ./enums */ 22);\n\nvar _arc = __webpack_require__(/*! ./arc */ 83);\n\nvar _arc2 = _interopRequireDefault(_arc);\n\nvar _random = __webpack_require__(/*! ./random */ 33);\n\nvar _random2 = _interopRequireDefault(_random);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\n// ===== Constructor =====\n\nfunction Particle(parent, bounds, globalGrid, observables, behavior) {\n this.config = {\n behavior: behavior || _enums.BEHAVIOR.FREE,\n bounds: bounds,\n color: _random2.default.color(),\n gridSize: 5,\n randomize: true,\n showArc: false,\n showVision: false,\n visionRadius: 50\n };\n\n this.grids = {\n global: globalGrid || {},\n vision: createVisionGrid(this.config)\n };\n\n this.id = _random2.default.id(12);\n\n this.nodes = {\n body: createBodyNode(this.config),\n circle: undefined,\n container: createContainerNode(this.config, this.id),\n visionGrid: undefined\n };\n\n this.nodes.container.appendChild(this.nodes.body);\n parent.appendChild(this.nodes.container);\n\n this.leader = null;\n this.leaderTime = 0;\n\n this.arc = _arc2.default.create(bounds, this.grids.global);\n this.arc.length = 3;\n\n // If starting in a hazard, recurse.\n while (this.grids.global.getPoint({ x: this.arc.endX, y: this.arc.endY, type: _enums.ENTITIES.HAZARD }) !== undefined) {\n this.arc = _arc2.default.create(bounds, this.grids.global);\n }\n\n this.grids.global.setPoint({\n x: this.arc.endX,\n y: this.arc.endY,\n type: _enums.ENTITIES.PARTICLE\n }, this);\n\n this.remove$ = new _rxjs2.default.Subject();\n\n var frames = observables.fps$.takeUntil(this.remove$);\n frames.subscribe(this.subscribeFrameMove.bind(this));\n frames.subscribe(this.subscribeFrameRepaint.bind(this));\n\n observables.speed$.takeUntil(this.remove$).subscribe(this.subscribeSpeed.bind(this));\n\n observables.randomize$ && observables.randomize$.takeUntil(this.remove$).subscribe(this.subscribeRandomize.bind(this));\n\n observables.circle$ && observables.circle$.takeUntil(this.remove$).subscribe(this.subscribeCircle.bind(this));\n\n observables.vision$ && observables.vision$.takeUntil(this.remove$).subscribe(this.subscribeVision.bind(this));\n};\n\n// ===== PROTOTYPE =====\n\nParticle.prototype.remove = function () {\n this.grids.global.deletePoint({\n x: this.arc.endX,\n y: this.arc.endY,\n type: _enums.ENTITIES.PARTICLE\n });\n\n var parent = this.nodes.container.parentNode;\n parent.removeChild(this.nodes.container);\n this.remove$.next();\n delete this.nodes;\n};\n\nParticle.prototype.subscribeFrameMove = function (n) {\n this.grids.global.deletePoint({\n x: this.arc.endX,\n y: this.arc.endY,\n type: _enums.ENTITIES.PARTICLE\n });\n\n if (this.leader !== null) {\n this.arc = _arc2.default.follow(this.arc, this.leader.arc);\n } else if (this.arc.length <= 0 && this.config.randomize) {\n this.arc = _arc2.default.randomize(this.arc);\n }\n\n this.grids.vision = updateVisionGrid(this.arc, this.config, this.grids);\n\n var _look = look(this.arc, this.grids),\n hazards = _look.hazards,\n particles = _look.particles;\n\n this.updateLeader(particles);\n\n if (hazards.length > 0) {\n this.arc = _arc2.default.evade(this.arc);\n }\n\n this.arc = _arc2.default.step(this.arc, this.config.bounds);\n\n this.grids.global.setPoint({\n x: this.arc.endX,\n y: this.arc.endY,\n type: _enums.ENTITIES.PARTICLE\n }, this);\n};\n\nParticle.prototype.subscribeFrameRepaint = function (n) {\n repaintContainer(this.nodes.container, this.arc, this.leaderTime);\n repaintBody(this.nodes.body, this.arc, this.leaderTime);\n repaintCircle(this.nodes.circle, this.arc);\n repaintVisionGrid(this.nodes.visionGrid, this.arc, this.grids);\n};\n\nParticle.prototype.subscribeSpeed = function (value) {\n _arc2.default.changeSpeed(this.arc, value);\n};\n\nParticle.prototype.subscribeCircle = function (show) {\n if (show === false) {\n this.nodes.container.removeChild(this.nodes.circle);\n delete this.nodes.circle;\n } else {\n this.nodes.circle = createCircleNode(this.config);\n this.nodes.container.appendChild(this.nodes.circle);\n }\n};\n\nParticle.prototype.subscribeRandomize = function (value) {\n this.config.randomize = value;\n};\n\nParticle.prototype.subscribeVision = function (show) {\n if (show === false) {\n this.nodes.visionGrid.forEach(function (n) {\n return n.parentNode.removeChild(n);\n });\n delete this.nodes.visionGrid;\n } else {\n this.nodes.visionGrid = createVisionGridNodes(this.config, this.grids, this.nodes);\n }\n};\n\nParticle.prototype.updateLeader = function (particles) {\n var _this = this;\n\n if (this.config.behavior !== _enums.BEHAVIOR.COHESION) {\n return;\n }\n\n // Head-to-head: particles see eachother but shouldn't both lead.\n if (this.leader === null && particles.length > 0) {\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.leaderTime > 0;\n }) || candidates[0];\n\n if (leader !== undefined) {\n leader.leaderTime = 1;\n this.leaderTime = 0;\n this.leader = leader;\n }\n }\n\n if (this.leader === null) {\n if (this.leaderTime > 0) {\n this.leaderTime++;\n }\n\n // Reset leader after a bit. (320 frames is 10 seconds)\n if (this.leaderTime > 3000) {\n this.leaderTime = 0;\n }\n\n // This particle may now be leading - break execution.\n return;\n }\n\n // if (this.leader.nodes === undefined) {\n if (this.leader.leaderTime === 0 && this.leader.leader === null) {\n this.leader = null;\n return;\n }\n\n this.leaderTime = 0;\n\n // Visit next node to keep chains of leaders short.\n if (this.leader.leader !== null) {\n this.leader = this.leader.leader;\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 point.touch = true;\n } else {\n point.touch = false;\n }\n\n return acc;\n }, { hazards: [], particles: [] });\n}\n\n// ===== DOM CREATION =====\n\nfunction createBodyNode(config) {\n var node = document.createElement('div');\n node.className = 'particle-body';\n node.style.backgroundColor = config.color;\n return node;\n}\n\nfunction createCircleNode(config) {\n var node = document.createElement('div');\n node.className = 'particle-movement-circle';\n node.style.borderColor = config.color;\n return node;\n}\n\nfunction createContainerNode(config, id) {\n var node = document.createElement('div');\n node.className = 'particle-container';\n node.id = id;\n return node;\n}\n\nfunction createVisionGrid(config) {\n var side = config.gridSize,\n radius = config.visionRadius;\n\n var r0 = radius;\n var r1 = 45;\n\n var points = [];\n\n for (var x = -radius; x <= radius; x += side) {\n for (var y = -radius; y <= radius; y += side) {\n // Omit large slices of unused circle\n if (x > y || x < -y) {\n continue;\n }\n\n // Include vision band\n var r = Math.pow(Math.pow(x, 2) + Math.pow(y, 2), 0.5);\n if (r > r0 || r < r1) {\n continue;\n }\n\n var alpha = Math.atan(y / x);\n if (x < 0) {\n alpha += _enums.RAD.t180;\n }\n\n points.push({ x: x, y: y, r: r, alpha: alpha, touch: false });\n }\n }\n\n return points;\n}\n\nfunction createVisionGridNodes(config, grids, nodes) {\n return grids.vision.reduce(function (acc, _ref) {\n var x = _ref.x,\n y = _ref.y;\n\n var div = document.createElement('div');\n div.className = 'particle-vision-dot';\n div.style.backgroundColor = config.color;\n nodes.container.appendChild(div);\n\n acc.push(div);\n\n return acc;\n }, []);\n}\n\nfunction updateVisionGrid(arc, config, grids) {\n var global = grids.global,\n vision = grids.vision;\n\n\n return vision.reduce(function (acc, point) {\n var rad = arc.clockwise ? point.alpha - arc.theta : point.alpha - arc.theta + _enums.RAD.t180;\n\n point.x = point.r * Math.cos(rad);\n point.y = point.r * Math.sin(rad);\n\n return acc.concat(point);\n }, []);\n}\n\n// ===== DOM RENDERING =====\nfunction repaintContainer(node, arc, leaderTime) {\n node.style.left = arc.endX + 'px';\n node.style.top = arc.endY + 'px';\n\n // node.style.zIndex = (leaderTime > 0 ? 2000 : 2);\n}\n\nfunction repaintBody(node, arc, leaderTime) {\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 // node.style.border = (leaderTime > 0 ? '3px dotted #fff' : '');\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 ? '1px solid red' : '0';\n });\n}\n\nexports.default = Particle;//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiODYuanMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vanMvcGFydGljbGUuanM/M2JkZSJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgUngsIHsgT2JzZXJ2YWJsZSB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgQkVIQVZJT1IsIEVOVElUSUVTLCBSQUQgfSBmcm9tICcuL2VudW1zJztcbmltcG9ydCBBcmMgZnJvbSAnLi9hcmMnO1xuaW1wb3J0IFJhbmRvbSBmcm9tICcuL3JhbmRvbSc7XG5cbi8vID09PT09IENvbnN0cnVjdG9yID09PT09XG5cbmZ1bmN0aW9uIFBhcnRpY2xlKHBhcmVudCwgYm91bmRzLCBnbG9iYWxHcmlkLCBvYnNlcnZhYmxlcywgYmVoYXZpb3IpIHtcbiAgICB0aGlzLmNvbmZpZyA9IHtcbiAgICAgICAgYmVoYXZpb3I6IGJlaGF2aW9yIHx8IEJFSEFWSU9SLkZSRUUsXG4gICAgICAgIGJvdW5kcyxcbiAgICAgICAgY29sb3I6IFJhbmRvbS5jb2xvcigpLFxuICAgICAgICBncmlkU2l6ZTogNSxcbiAgICAgICAgcmFuZG9taXplOiB0cnVlLFxuICAgICAgICBzaG93QXJjOiBmYWxzZSxcbiAgICAgICAgc2hvd1Zpc2lvbjogZmFsc2UsXG4gICAgICAgIHZpc2lvblJhZGl1czogNTBcbiAgICB9O1xuXG4gICAgdGhpcy5ncmlkcyA9IHtcbiAgICAgICAgZ2xvYmFsOiBnbG9iYWxHcmlkIHx8IHt9LFxuICAgICAgICB2aXNpb246IGNyZWF0ZVZpc2lvbkdyaWQodGhpcy5jb25maWcpXG4gICAgfTtcblxuICAgIHRoaXMuaWQgPSBSYW5kb20uaWQoMTIpO1xuXG4gICAgdGhpcy5ub2RlcyA9IHtcbiAgICAgICAgYm9keTogY3JlYXRlQm9keU5vZGUodGhpcy5jb25maWcpLFxuICAgICAgICBjaXJjbGU6IHVuZGVmaW5lZCxcbiAgICAgICAgY29udGFpbmVyOiBjcmVhdGVDb250YWluZXJOb2RlKHRoaXMuY29uZmlnLCB0aGlzLmlkKSxcbiAgICAgICAgdmlzaW9uR3JpZDogdW5kZWZpbmVkLFxuICAgIH07XG5cbiAgICB0aGlzLm5vZGVzLmNvbnRhaW5lci5hcHBlbmRDaGlsZCh0aGlzLm5vZGVzLmJvZHkpO1xuICAgIHBhcmVudC5hcHBlbmRDaGlsZCh0aGlzLm5vZGVzLmNvbnRhaW5lcik7XG5cbiAgICB0aGlzLmxlYWRlciA9IG51bGw7XG4gICAgdGhpcy5sZWFkZXJUaW1lID0gMDtcblxuICAgIHRoaXMuYXJjID0gQXJjLmNyZWF0ZShib3VuZHMsIHRoaXMuZ3JpZHMuZ2xvYmFsKTtcbiAgICB0aGlzLmFyYy5sZW5ndGggPSAzO1xuXG4gICAgLy8gSWYgc3RhcnRpbmcgaW4gYSBoYXphcmQsIHJlY3Vyc2UuXG4gICAgd2hpbGUgKHRoaXMuZ3JpZHMuZ2xvYmFsLmdldFBvaW50KHsgeDogdGhpcy5hcmMuZW5kWCwgeTogdGhpcy5hcmMuZW5kWSwgdHlwZTogRU5USVRJRVMuSEFaQVJEfSkgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICB0aGlzLmFyYyA9IEFyYy5jcmVhdGUoYm91bmRzLCB0aGlzLmdyaWRzLmdsb2JhbCk7XG4gICAgfVxuXG4gICAgdGhpcy5ncmlkcy5nbG9iYWwuc2V0UG9pbnQoe1xuICAgICAgICB4OiB0aGlzLmFyYy5lbmRYLFxuICAgICAgICB5OiB0aGlzLmFyYy5lbmRZLFxuICAgICAgICB0eXBlOiBFTlRJVElFUy5QQVJUSUNMRVxuICAgIH0sIHRoaXMpO1xuXG4gICAgdGhpcy5yZW1vdmUkID0gbmV3IFJ4LlN1YmplY3QoKTtcblxuICAgIGNvbnN0IGZyYW1lcyA9IG9ic2VydmFibGVzLmZwcyQudGFrZVVudGlsKHRoaXMucmVtb3ZlJCk7XG4gICAgZnJhbWVzLnN1YnNjcmliZSh0aGlzLnN1YnNjcmliZUZyYW1lTW92ZS5iaW5kKHRoaXMpKTtcbiAgICBmcmFtZXMuc3Vic2NyaWJlKHRoaXMuc3Vic2NyaWJlRnJhbWVSZXBhaW50LmJpbmQodGhpcykpO1xuXG4gICAgb2JzZXJ2YWJsZXMuc3BlZWQkXG4gICAgICAgIC50YWtlVW50aWwodGhpcy5yZW1vdmUkKVxuICAgICAgICAuc3Vic2NyaWJlKHRoaXMuc3Vic2NyaWJlU3BlZWQuYmluZCh0aGlzKSk7XG5cbiAgICBvYnNlcnZhYmxlcy5yYW5kb21pemUkICYmIG9ic2VydmFibGVzLnJhbmRvbWl6ZSRcbiAgICAgICAgLnRha2VVbnRpbCh0aGlzLnJlbW92ZSQpXG4gICAgICAgIC5zdWJzY3JpYmUodGhpcy5zdWJzY3JpYmVSYW5kb21pemUuYmluZCh0aGlzKSk7XG5cbiAgICBvYnNlcnZhYmxlcy5jaXJjbGUkICYmIG9ic2VydmFibGVzLmNpcmNsZSRcbiAgICAgICAgLnRha2VVbnRpbCh0aGlzLnJlbW92ZSQpXG4gICAgICAgIC5zdWJzY3JpYmUodGhpcy5zdWJzY3JpYmVDaXJjbGUuYmluZCh0aGlzKSk7XG5cbiAgICBvYnNlcnZhYmxlcy52aXNpb24kICYmIG9ic2VydmFibGVzLnZpc2lvbiRcbiAgICAgICAgLnRha2VVbnRpbCh0aGlzLnJlbW92ZSQpXG4gICAgICAgIC5zdWJzY3JpYmUodGhpcy5zdWJzY3JpYmVWaXNpb24uYmluZCh0aGlzKSk7XG59O1xuXG4vLyA9PT09PSBQUk9UT1RZUEUgPT09PT1cblxuUGFydGljbGUucHJvdG90eXBlLnJlbW92ZSA9IGZ1bmN0aW9uKCkge1xuICAgIHRoaXMuZ3JpZHMuZ2xvYmFsLmRlbGV0ZVBvaW50KHtcbiAgICAgICAgeDogdGhpcy5hcmMuZW5kWCxcbiAgICAgICAgeTogdGhpcy5hcmMuZW5kWSxcbiAgICAgICAgdHlwZTogRU5USVRJRVMuUEFSVElDTEVcbiAgICB9KTtcblxuICAgIGNvbnN0IHBhcmVudCA9IHRoaXMubm9kZXMuY29udGFpbmVyLnBhcmVudE5vZGU7XG4gICAgcGFyZW50LnJlbW92ZUNoaWxkKHRoaXMubm9kZXMuY29udGFpbmVyKTtcbiAgICB0aGlzLnJlbW92ZSQubmV4dCgpO1xuICAgIGRlbGV0ZSB0aGlzLm5vZGVzO1xufVxuXG5QYXJ0aWNsZS5wcm90b3R5cGUuc3Vic2NyaWJlRnJhbWVNb3ZlID0gZnVuY3Rpb24obikge1xuICAgIHRoaXMuZ3JpZHMuZ2xvYmFsLmRlbGV0ZVBvaW50KHtcbiAgICAgICAgeDogdGhpcy5hcmMuZW5kWCxcbiAgICAgICAgeTogdGhpcy5hcmMuZW5kWSxcbiAgICAgICAgdHlwZTogRU5USVRJRVMuUEFSVElDTEVcbiAgICB9KTtcblxuICAgIGlmICh0aGlzLmxlYWRlciAhPT0gbnVsbCkge1xuICAgICAgICB0aGlzLmFyYyA9IEFyYy5mb2xsb3codGhpcy5hcmMsIHRoaXMubGVhZGVyLmFyYyk7XG4gICAgfSBlbHNlIGlmICh0aGlzLmFyYy5sZW5ndGggPD0gMCAmJiB0aGlzLmNvbmZpZy5yYW5kb21pemUpIHtcbiAgICAgICAgdGhpcy5hcmMgPSBBcmMucmFuZG9taXplKHRoaXMuYXJjKTtcbiAgICB9XG5cbiAgICB0aGlzLmdyaWRzLnZpc2lvbiA9IHVwZGF0ZVZpc2lvbkdyaWQodGhpcy5hcmMsIHRoaXMuY29uZmlnLCB0aGlzLmdyaWRzKTtcbiAgICBjb25zdCB7IGhhemFyZHMsIHBhcnRpY2xlcyB9ID0gbG9vayh0aGlzLmFyYywgdGhpcy5ncmlkcyk7XG5cbiAgICB0aGlzLnVwZGF0ZUxlYWRlcihwYXJ0aWNsZXMpO1xuXG4gICAgaWYgKGhhemFyZHMubGVuZ3RoID4gMCkge1xuICAgICAgICB0aGlzLmFyYyA9IEFyYy5ldmFkZSh0aGlzLmFyYyk7XG4gICAgfVxuXG4gICAgdGhpcy5hcmMgPSBBcmMuc3RlcCh0aGlzLmFyYywgdGhpcy5jb25maWcuYm91bmRzKTtcblxuICAgIHRoaXMuZ3JpZHMuZ2xvYmFsLnNldFBvaW50KHtcbiAgICAgICAgeDogdGhpcy5hcmMuZW5kWCxcbiAgICAgICAgeTogdGhpcy5hcmMuZW5kWSxcbiAgICAgICAgdHlwZTogRU5USVRJRVMuUEFSVElDTEVcbiAgICB9LCB0aGlzKTtcbn1cblxuUGFydGljbGUucHJvdG90eXBlLnN1YnNjcmliZUZyYW1lUmVwYWludCA9IGZ1bmN0aW9uKG4pIHtcbiAgICByZXBhaW50Q29udGFpbmVyKHRoaXMubm9kZXMuY29udGFpbmVyLCB0aGlzLmFyYywgdGhpcy5sZWFkZXJUaW1lKTtcbiAgICByZXBhaW50Qm9keSh0aGlzLm5vZGVzLmJvZHksIHRoaXMuYXJjLCB0aGlzLmxlYWRlclRpbWUpO1xuICAgIHJlcGFpbnRDaXJjbGUodGhpcy5ub2Rlcy5jaXJjbGUsIHRoaXMuYXJjKTtcbiAgICByZXBhaW50VmlzaW9uR3JpZCh0aGlzLm5vZGVzLnZpc2lvbkdyaWQsIHRoaXMuYXJjLCB0aGlzLmdyaWRzKTtcbn1cblxuUGFydGljbGUucHJvdG90eXBlLnN1YnNjcmliZVNwZWVkID0gZnVuY3Rpb24odmFsdWUpIHtcbiAgICBBcmMuY2hhbmdlU3BlZWQodGhpcy5hcmMsIHZhbHVlKTtcbn1cblxuUGFydGljbGUucHJvdG90eXBlLnN1YnNjcmliZUNpcmNsZSA9IGZ1bmN0aW9uKHNob3cpIHtcbiAgICBpZiAoc2hvdyA9PT0gZmFsc2UpIHtcbiAgICAgICAgdGhpcy5ub2Rlcy5jb250YWluZXIucmVtb3ZlQ2hpbGQodGhpcy5ub2Rlcy5jaXJjbGUpO1xuICAgICAgICBkZWxldGUgdGhpcy5ub2Rlcy5jaXJjbGU7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5ub2Rlcy5jaXJjbGUgPSBjcmVhdGVDaXJjbGVOb2RlKHRoaXMuY29uZmlnKTtcbiAgICAgICAgdGhpcy5ub2Rlcy5jb250YWluZXIuYXBwZW5kQ2hpbGQodGhpcy5ub2Rlcy5jaXJjbGUpO1xuICAgIH1cbn1cblxuUGFydGljbGUucHJvdG90eXBlLnN1YnNjcmliZVJhbmRvbWl6ZSA9IGZ1bmN0aW9uKHZhbHVlKSB7XG4gICAgdGhpcy5jb25maWcucmFuZG9taXplID0gdmFsdWU7XG59XG5cblBhcnRpY2xlLnByb3RvdHlwZS5zdWJzY3JpYmVWaXNpb24gPSBmdW5jdGlvbihzaG93KSB7XG4gICAgaWYgKHNob3cgPT09IGZhbHNlKSB7XG4gICAgICAgIHRoaXMubm9kZXMudmlzaW9uR3JpZC5mb3JFYWNoKG4gPT4gbi5wYXJlbnROb2RlLnJlbW92ZUNoaWxkKG4pKTtcbiAgICAgICAgZGVsZXRlIHRoaXMubm9kZXMudmlzaW9uR3JpZDtcbiAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLm5vZGVzLnZpc2lvbkdyaWQgPSBjcmVhdGVWaXNpb25HcmlkTm9kZXModGhpcy5jb25maWcsIHRoaXMuZ3JpZHMsIHRoaXMubm9kZXMpO1xuICAgIH1cbn1cblxuUGFydGljbGUucHJvdG90eXBlLnVwZGF0ZUxlYWRlciA9IGZ1bmN0aW9uKHBhcnRpY2xlcykge1xuICAgIGlmICh0aGlzLmNvbmZpZy5iZWhhdmlvciAhPT0gQkVIQVZJT1IuQ09IRVNJT04pIHtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIEhlYWQtdG8taGVhZDogcGFydGljbGVzIHNlZSBlYWNob3RoZXIgYnV0IHNob3VsZG4ndCBib3RoIGxlYWQuXG4gICAgaWYgKHRoaXMubGVhZGVyID09PSBudWxsICYmIHBhcnRpY2xlcy5sZW5ndGggPiAwKSB7XG4gICAgICAgIGNvbnN0IGNhbmRpZGF0ZXMgPSBwYXJ0aWNsZXNcbiAgICAgICAgICAgIC5maWx0ZXIodiA9PiB2LmxlYWRlciA/ICh2LmxlYWRlci5pZCAhPT0gdGhpcy5pZCkgOiB0cnVlKTtcblxuICAgICAgICBjb25zdCBsZWFkZXIgPSBjYW5kaWRhdGVzLmZpbmQodiA9PiAodi5sZWFkZXJUaW1lID4gMCkpIHx8IGNhbmRpZGF0ZXNbMF07XG5cbiAgICAgICAgaWYgKGxlYWRlciAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICBsZWFkZXIubGVhZGVyVGltZSA9IDE7XG4gICAgICAgICAgICB0aGlzLmxlYWRlclRpbWUgPSAwO1xuICAgICAgICAgICAgdGhpcy5sZWFkZXIgPSBsZWFkZXI7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAodGhpcy5sZWFkZXIgPT09IG51bGwpIHtcbiAgICAgICAgaWYgKHRoaXMubGVhZGVyVGltZSA+IDApIHtcbiAgICAgICAgICAgIHRoaXMubGVhZGVyVGltZSsrO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gUmVzZXQgbGVhZGVyIGFmdGVyIGEgYml0LiAoMzIwIGZyYW1lcyBpcyAxMCBzZWNvbmRzKVxuICAgICAgICBpZiAodGhpcy5sZWFkZXJUaW1lID4gMzAwMCkge1xuICAgICAgICAgICAgdGhpcy5sZWFkZXJUaW1lID0gMDtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFRoaXMgcGFydGljbGUgbWF5IG5vdyBiZSBsZWFkaW5nIC0gYnJlYWsgZXhlY3V0aW9uLlxuICAgICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgLy8gaWYgKHRoaXMubGVhZGVyLm5vZGVzID09PSB1bmRlZmluZWQpIHtcbiAgICBpZiAodGhpcy5sZWFkZXIubGVhZGVyVGltZSA9PT0gMCAmJiB0aGlzLmxlYWRlci5sZWFkZXIgPT09IG51bGwpIHtcbiAgICAgICAgdGhpcy5sZWFkZXIgPSBudWxsO1xuICAgICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdGhpcy5sZWFkZXJUaW1lID0gMDtcblxuICAgIC8vIFZpc2l0IG5leHQgbm9kZSB0byBrZWVwIGNoYWlucyBvZiBsZWFkZXJzIHNob3J0LlxuICAgIGlmICh0aGlzLmxlYWRlci5sZWFkZXIgIT09IG51bGwpIHtcbiAgICAgICAgdGhpcy5sZWFkZXIgPSB0aGlzLmxlYWRlci5sZWFkZXI7XG4gICAgfVxuXG4gICAgLy8gQmV3YXJlIG9mIGNpcmN1bGFyIGxlYWRlcnNoaXAsIHdoZXJlIGEgbGVhZGVyIHNlZXMgaXRzIHRhaWwuXG4gICAgaWYgKHRoaXMubGVhZGVyLmlkID09PSB0aGlzLmlkKSB7XG4gICAgICAgIHRoaXMubGVhZGVyID0gbnVsbDtcbiAgICB9XG59XG5cbmZ1bmN0aW9uIGxvb2soYXJjLCBncmlkcykge1xuICAgIGNvbnN0IHsgZ2xvYmFsLCB2aXNpb24gfSA9IGdyaWRzO1xuXG4gICAgcmV0dXJuIHZpc2lvbi5yZWR1Y2UoKGFjYywgcG9pbnQpID0+IHtcbiAgICAgICAgY29uc3QgeCA9IGFyYy5lbmRYICsgcG9pbnQueDtcbiAgICAgICAgY29uc3QgeSA9IGFyYy5lbmRZICsgcG9pbnQueTtcbiAgICAgICAgY29uc3QgcCA9IGdsb2JhbC5nZXRQb2ludCh7IHgsIHksIHR5cGU6IEVOVElUSUVTLlBBUlRJQ0xFIH0pO1xuXG4gICAgICAgIGlmIChwKSB7XG4gICAgICAgICAgICBhY2MucGFydGljbGVzLnB1c2gocCk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoZ2xvYmFsLmdldFBvaW50KHsgeCwgeSwgdHlwZTogRU5USVRJRVMuSEFaQVJEIH0pKSB7XG4gICAgICAgICAgICBhY2MuaGF6YXJkcy5wdXNoKHsgeCwgeSB9KTtcbiAgICAgICAgICAgIHBvaW50LnRvdWNoID0gdHJ1ZTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHBvaW50LnRvdWNoID0gZmFsc2U7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gYWNjO1xuICAgIH0sIHsgaGF6YXJkczogW10sIHBhcnRpY2xlczogW10gfSk7XG59XG5cbi8vID09PT09IERPTSBDUkVBVElPTiA9PT09PVxuXG5mdW5jdGlvbiBjcmVhdGVCb2R5Tm9kZShjb25maWcpIHtcbiAgICBjb25zdCBub2RlID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgbm9kZS5jbGFzc05hbWUgPSAncGFydGljbGUtYm9keSc7XG4gICAgbm9kZS5zdHlsZS5iYWNrZ3JvdW5kQ29sb3IgPSBjb25maWcuY29sb3I7XG4gICAgcmV0dXJuIG5vZGU7XG59XG5cbmZ1bmN0aW9uIGNyZWF0ZUNpcmNsZU5vZGUoY29uZmlnKSB7XG4gICAgY29uc3Qgbm9kZSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgIG5vZGUuY2xhc3NOYW1lID0gJ3BhcnRpY2xlLW1vdmVtZW50LWNpcmNsZSc7XG4gICAgbm9kZS5zdHlsZS5ib3JkZXJDb2xvciA9IGNvbmZpZy5jb2xvcjtcbiAgICByZXR1cm4gbm9kZTtcbn1cblxuZnVuY3Rpb24gY3JlYXRlQ29udGFpbmVyTm9kZShjb25maWcsIGlkKSB7XG4gICAgY29uc3Qgbm9kZSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgIG5vZGUuY2xhc3NOYW1lID0gJ3BhcnRpY2xlLWNvbnRhaW5lcic7XG4gICAgbm9kZS5pZCA9IGlkO1xuICAgIHJldHVybiBub2RlO1xufVxuXG5mdW5jdGlvbiBjcmVhdGVWaXNpb25HcmlkKGNvbmZpZykge1xuICAgIGNvbnN0IHsgZ3JpZFNpemU6IHNpZGUsIHZpc2lvblJhZGl1czogcmFkaXVzIH0gPSBjb25maWc7XG4gICAgY29uc3QgcjAgPSByYWRpdXM7XG4gICAgY29uc3QgcjEgPSA0NTtcblxuICAgIGNvbnN0IHBvaW50cyA9IFtdO1xuXG4gICAgZm9yIChsZXQgeCA9IC1yYWRpdXM7IHggPD0gcmFkaXVzOyB4ICs9IHNpZGUpIHtcbiAgICAgICAgZm9yIChsZXQgeSA9IC1yYWRpdXM7IHkgPD0gcmFkaXVzOyB5ICs9IHNpZGUpIHtcbiAgICAgICAgICAgIC8vIE9taXQgbGFyZ2Ugc2xpY2VzIG9mIHVudXNlZCBjaXJjbGVcbiAgICAgICAgICAgIGlmICh4ID4geSB8fCB4IDwgLXkpIHtcbiAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gSW5jbHVkZSB2aXNpb24gYmFuZFxuICAgICAgICAgICAgY29uc3QgciA9IE1hdGgucG93KE1hdGgucG93KHgsIDIpICsgTWF0aC5wb3coeSwgMiksIDAuNSk7XG4gICAgICAgICAgICBpZiAociA+IHIwIHx8IHIgPCByMSkge1xuICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBsZXQgYWxwaGEgPSBNYXRoLmF0YW4oeSAvIHgpO1xuICAgICAgICAgICAgaWYgKHggPCAwKSB7XG4gICAgICAgICAgICAgICAgYWxwaGEgKz0gUkFELnQxODA7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHBvaW50cy5wdXNoKHsgeCwgeSwgciwgYWxwaGEsIHRvdWNoOiBmYWxzZSB9KTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBwb2ludHM7XG59XG5cbmZ1bmN0aW9uIGNyZWF0ZVZpc2lvbkdyaWROb2Rlcyhjb25maWcsIGdyaWRzLCBub2Rlcykge1xuICAgIHJldHVybiBncmlkcy52aXNpb24ucmVkdWNlKChhY2MsIHsgeCwgeSB9KSA9PiB7XG4gICAgICAgIGNvbnN0IGRpdiA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgICAgICBkaXYuY2xhc3NOYW1lID0gJ3BhcnRpY2xlLXZpc2lvbi1kb3QnO1xuICAgICAgICBkaXYuc3R5bGUuYmFja2dyb3VuZENvbG9yID0gY29uZmlnLmNvbG9yO1xuICAgICAgICBub2Rlcy5jb250YWluZXIuYXBwZW5kQ2hpbGQoZGl2KTtcblxuICAgICAgICBhY2MucHVzaChkaXYpO1xuXG4gICAgICAgIHJldHVybiBhY2M7XG4gICAgfSwgW10pO1xufVxuXG5cbmZ1bmN0aW9uIHVwZGF0ZVZpc2lvbkdyaWQoYXJjLCBjb25maWcsIGdyaWRzKSB7XG4gICAgY29uc3QgeyBnbG9iYWwsIHZpc2lvbiB9ID0gZ3JpZHM7XG5cbiAgICByZXR1cm4gdmlzaW9uLnJlZHVjZSgoYWNjLCBwb2ludCkgPT4ge1xuICAgICAgICBjb25zdCByYWQgPSBhcmMuY2xvY2t3aXNlXG4gICAgICAgICAgICA/IHBvaW50LmFscGhhIC0gYXJjLnRoZXRhXG4gICAgICAgICAgICA6IHBvaW50LmFscGhhIC0gYXJjLnRoZXRhICsgUkFELnQxODA7XG5cbiAgICAgICAgcG9pbnQueCA9IHBvaW50LnIgKiBNYXRoLmNvcyhyYWQpO1xuICAgICAgICBwb2ludC55ID0gcG9pbnQuciAqIE1hdGguc2luKHJhZCk7XG5cbiAgICAgICAgcmV0dXJuIGFjYy5jb25jYXQocG9pbnQpO1xuICAgIH0sIFtdKTtcbn1cblxuLy8gPT09PT0gRE9NIFJFTkRFUklORyA9PT09PVxuZnVuY3Rpb24gcmVwYWludENvbnRhaW5lcihub2RlLCBhcmMsIGxlYWRlclRpbWUpIHtcbiAgICBub2RlLnN0eWxlLmxlZnQgPSBgJHthcmMuZW5kWH1weGA7XG4gICAgbm9kZS5zdHlsZS50b3AgPSBgJHthcmMuZW5kWX1weGA7XG5cbiAgICAvLyBub2RlLnN0eWxlLnpJbmRleCA9IChsZWFkZXJUaW1lID4gMCA/IDIwMDAgOiAyKTtcbn1cblxuZnVuY3Rpb24gcmVwYWludEJvZHkobm9kZSwgYXJjLCBsZWFkZXJUaW1lKSB7XG4gICAgY29uc3QgcmFkID0gYXJjLmNsb2Nrd2lzZVxuICAgICAgICA/IFJBRC50MTgwIC0gYXJjLnRoZXRhXG4gICAgICAgIDogUkFELnQzNjAgLSBhcmMudGhldGE7XG5cbiAgICBub2RlLnN0eWxlLnRyYW5zZm9ybSA9IGByb3RhdGUoJHtyYWQgKyBSQUQudDQ1fXJhZClgO1xuXG4gICAgLy8gbm9kZS5zdHlsZS5ib3JkZXIgPSAobGVhZGVyVGltZSA+IDAgPyAnM3B4IGRvdHRlZCAjZmZmJyA6ICcnKTtcbn1cblxuZnVuY3Rpb24gcmVwYWludENpcmNsZShub2RlLCBhcmMpIHtcbiAgICBpZiAobm9kZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBub2RlLnN0eWxlLndpZHRoID0gYCR7MiAqIGFyYy5yYWRpdXN9cHhgO1xuICAgIG5vZGUuc3R5bGUuaGVpZ2h0ID0gYCR7MiAqIGFyYy5yYWRpdXN9cHhgO1xuXG4gICAgbm9kZS5zdHlsZS5sZWZ0ID0gYC0ke2FyYy5yYWRpdXMgKyBhcmMucmFkaXVzICogYXJjLmNvc1RoZXRhfXB4YDtcbiAgICBub2RlLnN0eWxlLnRvcCA9IGAtJHthcmMucmFkaXVzIC0gYXJjLnJhZGl1cyAqIGFyYy5zaW5UaGV0YX1weGA7XG5cbiAgICBub2RlLnN0eWxlLmJvcmRlclJhZGl1cyA9IGAke2FyYy5yYWRpdXN9cHhgO1xufVxuXG5mdW5jdGlvbiByZXBhaW50VmlzaW9uR3JpZChub2RlcywgYXJjLCBncmlkcykge1xuICAgIGlmIChub2RlcyA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBncmlkcy52aXNpb24uZm9yRWFjaCgoeyB4LCB5LCB0b3VjaCB9LCBpKSA9PiB7XG4gICAgICAgIG5vZGVzW2ldLnN0eWxlLmxlZnQgPSBgJHt4fXB4YDtcbiAgICAgICAgbm9kZXNbaV0uc3R5bGUudG9wID0gYCR7eX1weGA7XG5cbiAgICAgICAgbm9kZXNbaV0uc3R5bGUuYm9yZGVyID0gKHRvdWNoID8gJzFweCBzb2xpZCByZWQnIDogJzAnKTtcbiAgICB9KTtcbn1cblxuZXhwb3J0IGRlZmF1bHQgUGFydGljbGU7XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8ganMvcGFydGljbGUuanMiXSwibWFwcGluZ3MiOiI7Ozs7OztBQUFBO0FBQ0E7OztBQUFBO0FBQ0E7QUFBQTtBQUNBOzs7QUFBQTtBQUNBOzs7OztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQVJBO0FBQ0E7QUFVQTtBQUNBO0FBQ0E7QUFGQTtBQUNBO0FBSUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFKQTtBQUNBO0FBTUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBSEE7QUFDQTtBQUtBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFHQTtBQUNBO0FBR0E7QUFDQTtBQUdBO0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBSEE7QUFDQTtBQUtBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFIQTtBQUNBO0FBS0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQWRBO0FBQUE7QUFBQTtBQUNBO0FBZUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBSEE7QUFLQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZVJvb3QiOiIifQ=="); +eval("\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nvar _rxjs = __webpack_require__(/*! rxjs */ 21);\n\nvar _rxjs2 = _interopRequireDefault(_rxjs);\n\nvar _enums = __webpack_require__(/*! ./enums */ 22);\n\nvar _arc = __webpack_require__(/*! ./arc */ 83);\n\nvar _arc2 = _interopRequireDefault(_arc);\n\nvar _random = __webpack_require__(/*! ./random */ 33);\n\nvar _random2 = _interopRequireDefault(_random);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\n// ===== Constructor =====\n\nfunction Particle(parent, bounds, globalGrid, observables, behavior) {\n this.config = {\n behavior: behavior || _enums.BEHAVIOR.FREE,\n bounds: bounds,\n color: _random2.default.color(),\n gridSize: 5,\n randomize: true,\n showArc: false,\n showVision: false,\n visionRadius: 50\n };\n\n this.grids = {\n global: globalGrid || {},\n vision: createVisionGrid(this.config)\n };\n\n this.id = _random2.default.id(12);\n\n this.nodes = {\n body: createBodyNode(this.config),\n circle: undefined,\n container: createContainerNode(this.config, this.id),\n visionGrid: undefined\n };\n\n this.nodes.container.appendChild(this.nodes.body);\n parent.appendChild(this.nodes.container);\n\n this.leader = null;\n this.leaderTime = 0;\n\n this.arc = _arc2.default.create(bounds, this.grids.global);\n this.arc.length = 3;\n\n // If starting in a hazard, recurse.\n while (this.grids.global.getPoint({ x: this.arc.endX, y: this.arc.endY, type: _enums.ENTITIES.HAZARD }) !== undefined) {\n this.arc = _arc2.default.create(bounds, this.grids.global);\n }\n\n this.grids.global.setPoint({\n x: this.arc.endX,\n y: this.arc.endY,\n type: _enums.ENTITIES.PARTICLE\n }, this);\n\n this.remove$ = new _rxjs2.default.Subject();\n\n var frames = observables.fps$.takeUntil(this.remove$);\n frames.subscribe(this.subscribeFrameMove.bind(this));\n frames.subscribe(this.subscribeFrameRepaint.bind(this));\n\n observables.speed$.takeUntil(this.remove$).subscribe(this.subscribeSpeed.bind(this));\n\n observables.randomize$ && observables.randomize$.takeUntil(this.remove$).subscribe(this.subscribeRandomize.bind(this));\n\n observables.circle$ && observables.circle$.takeUntil(this.remove$).subscribe(this.subscribeCircle.bind(this));\n\n observables.vision$ && observables.vision$.takeUntil(this.remove$).subscribe(this.subscribeVision.bind(this));\n};\n\n// ===== PROTOTYPE =====\n\nParticle.prototype.remove = function () {\n this.grids.global.deletePoint({\n x: this.arc.endX,\n y: this.arc.endY,\n type: _enums.ENTITIES.PARTICLE\n });\n\n var parent = this.nodes.container.parentNode;\n parent.removeChild(this.nodes.container);\n this.remove$.next();\n delete this.nodes;\n};\n\nParticle.prototype.subscribeFrameMove = function (n) {\n this.grids.global.deletePoint({\n x: this.arc.endX,\n y: this.arc.endY,\n type: _enums.ENTITIES.PARTICLE\n });\n\n if (this.leader !== null) {\n this.arc = _arc2.default.follow(this.arc, this.leader.arc);\n } else if (this.arc.length <= 0 && this.config.randomize) {\n this.arc = _arc2.default.randomize(this.arc);\n }\n\n this.grids.vision = updateVisionGrid(this.arc, this.config, this.grids);\n\n var _look = look(this.arc, this.grids),\n hazards = _look.hazards,\n particles = _look.particles;\n\n this.updateLeader(particles);\n\n if (hazards.length > 0) {\n this.arc = _arc2.default.evade(this.arc);\n }\n\n this.arc = _arc2.default.step(this.arc, this.config.bounds);\n\n this.grids.global.setPoint({\n x: this.arc.endX,\n y: this.arc.endY,\n type: _enums.ENTITIES.PARTICLE\n }, this);\n};\n\nParticle.prototype.subscribeFrameRepaint = function (n) {\n repaintContainer(this.nodes.container, this.arc, this.leaderTime);\n repaintBody(this.nodes.body, this.arc, this.leaderTime);\n repaintCircle(this.nodes.circle, this.arc);\n repaintVisionGrid(this.nodes.visionGrid, this.arc, this.grids);\n};\n\nParticle.prototype.subscribeSpeed = function (value) {\n _arc2.default.changeSpeed(this.arc, value);\n};\n\nParticle.prototype.subscribeCircle = function (show) {\n if (show === false) {\n this.nodes.container.removeChild(this.nodes.circle);\n delete this.nodes.circle;\n } else {\n this.nodes.circle = createCircleNode(this.config);\n this.nodes.container.appendChild(this.nodes.circle);\n }\n};\n\nParticle.prototype.subscribeRandomize = function (value) {\n this.config.randomize = value;\n};\n\nParticle.prototype.subscribeVision = function (show) {\n if (show === false) {\n this.nodes.visionGrid.forEach(function (n) {\n return n.parentNode.removeChild(n);\n });\n delete this.nodes.visionGrid;\n } else {\n this.nodes.visionGrid = createVisionGridNodes(this.config, this.grids, this.nodes);\n }\n};\n\nParticle.prototype.updateLeader = function (particles) {\n var _this = this;\n\n if (this.config.behavior !== _enums.BEHAVIOR.COHESION) {\n return;\n }\n\n // Head-to-head: particles see eachother but shouldn't both lead.\n if (this.leader === null && particles.length > 0) {\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.leaderTime > 0;\n }) || candidates[0];\n\n if (leader !== undefined) {\n leader.leaderTime = 1;\n this.leaderTime = 0;\n this.leader = leader;\n }\n }\n\n if (this.leader === null) {\n if (this.leaderTime > 0) {\n this.leaderTime++;\n }\n\n // Reset leader after a bit. (320 frames is 10 seconds)\n if (this.leaderTime > 3000) {\n this.leaderTime = 0;\n }\n\n // This particle may now be leading - break execution.\n return;\n }\n\n // if (this.leader.nodes === undefined) {\n if (this.leader.leaderTime === 0 && this.leader.leader === null) {\n this.leader = null;\n return;\n }\n\n this.leaderTime = 0;\n\n // Visit next node to keep chains of leaders short.\n if (this.leader.leader !== null) {\n this.leader = this.leader.leader;\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 point.touch = false;\n\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 point.touch = true;\n }\n\n if (global.getPoint({ x: x, y: y, type: _enums.ENTITIES.HAZARD })) {\n acc.hazards.push({ x: x, y: y });\n point.touch = true;\n }\n\n return acc;\n }, { hazards: [], particles: [] });\n}\n\n// ===== DOM CREATION =====\n\nfunction createBodyNode(config) {\n var node = document.createElement('div');\n node.className = 'particle-body';\n node.style.backgroundColor = config.color;\n return node;\n}\n\nfunction createCircleNode(config) {\n var node = document.createElement('div');\n node.className = 'particle-movement-circle';\n node.style.borderColor = config.color;\n return node;\n}\n\nfunction createContainerNode(config, id) {\n var node = document.createElement('div');\n node.className = 'particle-container';\n node.id = id;\n return node;\n}\n\nfunction createVisionGrid(config) {\n var side = config.gridSize,\n radius = config.visionRadius;\n\n var r0 = radius;\n var r1 = 45;\n\n var points = [];\n\n for (var x = -radius; x <= radius; x += side) {\n for (var y = -radius; y <= radius; y += side) {\n // Omit large slices of unused circle\n if (x > y || x < -y) {\n continue;\n }\n\n // Include vision band\n var r = Math.pow(Math.pow(x, 2) + Math.pow(y, 2), 0.5);\n if (r > r0 || r < r1) {\n continue;\n }\n\n var alpha = Math.atan(y / x);\n if (x < 0) {\n alpha += _enums.RAD.t180;\n }\n\n points.push({ x: x, y: y, r: r, alpha: alpha, touch: false });\n }\n }\n\n return points;\n}\n\nfunction createVisionGridNodes(config, grids, nodes) {\n return grids.vision.reduce(function (acc, _ref) {\n var x = _ref.x,\n y = _ref.y;\n\n var div = document.createElement('div');\n div.className = 'particle-vision-dot';\n div.style.backgroundColor = config.color;\n nodes.container.appendChild(div);\n\n acc.push(div);\n\n return acc;\n }, []);\n}\n\nfunction updateVisionGrid(arc, config, grids) {\n var global = grids.global,\n vision = grids.vision;\n\n\n return vision.reduce(function (acc, point) {\n var rad = arc.clockwise ? point.alpha - arc.theta : point.alpha - arc.theta + _enums.RAD.t180;\n\n point.x = point.r * Math.cos(rad);\n point.y = point.r * Math.sin(rad);\n\n return acc.concat(point);\n }, []);\n}\n\n// ===== DOM RENDERING =====\nfunction repaintContainer(node, arc, leaderTime) {\n node.style.left = arc.endX + 'px';\n node.style.top = arc.endY + 'px';\n\n // node.style.zIndex = (leaderTime > 0 ? 2000 : 2);\n}\n\nfunction repaintBody(node, arc, leaderTime) {\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 // node.style.border = (leaderTime > 0 ? '3px dotted #fff' : '');\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 ? '1px solid red' : '0';\n });\n}\n\nexports.default = Particle;//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiODYuanMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vanMvcGFydGljbGUuanM/M2JkZSJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgUngsIHsgT2JzZXJ2YWJsZSB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgQkVIQVZJT1IsIEVOVElUSUVTLCBSQUQgfSBmcm9tICcuL2VudW1zJztcbmltcG9ydCBBcmMgZnJvbSAnLi9hcmMnO1xuaW1wb3J0IFJhbmRvbSBmcm9tICcuL3JhbmRvbSc7XG5cbi8vID09PT09IENvbnN0cnVjdG9yID09PT09XG5cbmZ1bmN0aW9uIFBhcnRpY2xlKHBhcmVudCwgYm91bmRzLCBnbG9iYWxHcmlkLCBvYnNlcnZhYmxlcywgYmVoYXZpb3IpIHtcbiAgICB0aGlzLmNvbmZpZyA9IHtcbiAgICAgICAgYmVoYXZpb3I6IGJlaGF2aW9yIHx8IEJFSEFWSU9SLkZSRUUsXG4gICAgICAgIGJvdW5kcyxcbiAgICAgICAgY29sb3I6IFJhbmRvbS5jb2xvcigpLFxuICAgICAgICBncmlkU2l6ZTogNSxcbiAgICAgICAgcmFuZG9taXplOiB0cnVlLFxuICAgICAgICBzaG93QXJjOiBmYWxzZSxcbiAgICAgICAgc2hvd1Zpc2lvbjogZmFsc2UsXG4gICAgICAgIHZpc2lvblJhZGl1czogNTBcbiAgICB9O1xuXG4gICAgdGhpcy5ncmlkcyA9IHtcbiAgICAgICAgZ2xvYmFsOiBnbG9iYWxHcmlkIHx8IHt9LFxuICAgICAgICB2aXNpb246IGNyZWF0ZVZpc2lvbkdyaWQodGhpcy5jb25maWcpXG4gICAgfTtcblxuICAgIHRoaXMuaWQgPSBSYW5kb20uaWQoMTIpO1xuXG4gICAgdGhpcy5ub2RlcyA9IHtcbiAgICAgICAgYm9keTogY3JlYXRlQm9keU5vZGUodGhpcy5jb25maWcpLFxuICAgICAgICBjaXJjbGU6IHVuZGVmaW5lZCxcbiAgICAgICAgY29udGFpbmVyOiBjcmVhdGVDb250YWluZXJOb2RlKHRoaXMuY29uZmlnLCB0aGlzLmlkKSxcbiAgICAgICAgdmlzaW9uR3JpZDogdW5kZWZpbmVkLFxuICAgIH07XG5cbiAgICB0aGlzLm5vZGVzLmNvbnRhaW5lci5hcHBlbmRDaGlsZCh0aGlzLm5vZGVzLmJvZHkpO1xuICAgIHBhcmVudC5hcHBlbmRDaGlsZCh0aGlzLm5vZGVzLmNvbnRhaW5lcik7XG5cbiAgICB0aGlzLmxlYWRlciA9IG51bGw7XG4gICAgdGhpcy5sZWFkZXJUaW1lID0gMDtcblxuICAgIHRoaXMuYXJjID0gQXJjLmNyZWF0ZShib3VuZHMsIHRoaXMuZ3JpZHMuZ2xvYmFsKTtcbiAgICB0aGlzLmFyYy5sZW5ndGggPSAzO1xuXG4gICAgLy8gSWYgc3RhcnRpbmcgaW4gYSBoYXphcmQsIHJlY3Vyc2UuXG4gICAgd2hpbGUgKHRoaXMuZ3JpZHMuZ2xvYmFsLmdldFBvaW50KHsgeDogdGhpcy5hcmMuZW5kWCwgeTogdGhpcy5hcmMuZW5kWSwgdHlwZTogRU5USVRJRVMuSEFaQVJEfSkgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICB0aGlzLmFyYyA9IEFyYy5jcmVhdGUoYm91bmRzLCB0aGlzLmdyaWRzLmdsb2JhbCk7XG4gICAgfVxuXG4gICAgdGhpcy5ncmlkcy5nbG9iYWwuc2V0UG9pbnQoe1xuICAgICAgICB4OiB0aGlzLmFyYy5lbmRYLFxuICAgICAgICB5OiB0aGlzLmFyYy5lbmRZLFxuICAgICAgICB0eXBlOiBFTlRJVElFUy5QQVJUSUNMRVxuICAgIH0sIHRoaXMpO1xuXG4gICAgdGhpcy5yZW1vdmUkID0gbmV3IFJ4LlN1YmplY3QoKTtcblxuICAgIGNvbnN0IGZyYW1lcyA9IG9ic2VydmFibGVzLmZwcyQudGFrZVVudGlsKHRoaXMucmVtb3ZlJCk7XG4gICAgZnJhbWVzLnN1YnNjcmliZSh0aGlzLnN1YnNjcmliZUZyYW1lTW92ZS5iaW5kKHRoaXMpKTtcbiAgICBmcmFtZXMuc3Vic2NyaWJlKHRoaXMuc3Vic2NyaWJlRnJhbWVSZXBhaW50LmJpbmQodGhpcykpO1xuXG4gICAgb2JzZXJ2YWJsZXMuc3BlZWQkXG4gICAgICAgIC50YWtlVW50aWwodGhpcy5yZW1vdmUkKVxuICAgICAgICAuc3Vic2NyaWJlKHRoaXMuc3Vic2NyaWJlU3BlZWQuYmluZCh0aGlzKSk7XG5cbiAgICBvYnNlcnZhYmxlcy5yYW5kb21pemUkICYmIG9ic2VydmFibGVzLnJhbmRvbWl6ZSRcbiAgICAgICAgLnRha2VVbnRpbCh0aGlzLnJlbW92ZSQpXG4gICAgICAgIC5zdWJzY3JpYmUodGhpcy5zdWJzY3JpYmVSYW5kb21pemUuYmluZCh0aGlzKSk7XG5cbiAgICBvYnNlcnZhYmxlcy5jaXJjbGUkICYmIG9ic2VydmFibGVzLmNpcmNsZSRcbiAgICAgICAgLnRha2VVbnRpbCh0aGlzLnJlbW92ZSQpXG4gICAgICAgIC5zdWJzY3JpYmUodGhpcy5zdWJzY3JpYmVDaXJjbGUuYmluZCh0aGlzKSk7XG5cbiAgICBvYnNlcnZhYmxlcy52aXNpb24kICYmIG9ic2VydmFibGVzLnZpc2lvbiRcbiAgICAgICAgLnRha2VVbnRpbCh0aGlzLnJlbW92ZSQpXG4gICAgICAgIC5zdWJzY3JpYmUodGhpcy5zdWJzY3JpYmVWaXNpb24uYmluZCh0aGlzKSk7XG59O1xuXG4vLyA9PT09PSBQUk9UT1RZUEUgPT09PT1cblxuUGFydGljbGUucHJvdG90eXBlLnJlbW92ZSA9IGZ1bmN0aW9uKCkge1xuICAgIHRoaXMuZ3JpZHMuZ2xvYmFsLmRlbGV0ZVBvaW50KHtcbiAgICAgICAgeDogdGhpcy5hcmMuZW5kWCxcbiAgICAgICAgeTogdGhpcy5hcmMuZW5kWSxcbiAgICAgICAgdHlwZTogRU5USVRJRVMuUEFSVElDTEVcbiAgICB9KTtcblxuICAgIGNvbnN0IHBhcmVudCA9IHRoaXMubm9kZXMuY29udGFpbmVyLnBhcmVudE5vZGU7XG4gICAgcGFyZW50LnJlbW92ZUNoaWxkKHRoaXMubm9kZXMuY29udGFpbmVyKTtcbiAgICB0aGlzLnJlbW92ZSQubmV4dCgpO1xuICAgIGRlbGV0ZSB0aGlzLm5vZGVzO1xufVxuXG5QYXJ0aWNsZS5wcm90b3R5cGUuc3Vic2NyaWJlRnJhbWVNb3ZlID0gZnVuY3Rpb24obikge1xuICAgIHRoaXMuZ3JpZHMuZ2xvYmFsLmRlbGV0ZVBvaW50KHtcbiAgICAgICAgeDogdGhpcy5hcmMuZW5kWCxcbiAgICAgICAgeTogdGhpcy5hcmMuZW5kWSxcbiAgICAgICAgdHlwZTogRU5USVRJRVMuUEFSVElDTEVcbiAgICB9KTtcblxuICAgIGlmICh0aGlzLmxlYWRlciAhPT0gbnVsbCkge1xuICAgICAgICB0aGlzLmFyYyA9IEFyYy5mb2xsb3codGhpcy5hcmMsIHRoaXMubGVhZGVyLmFyYyk7XG4gICAgfSBlbHNlIGlmICh0aGlzLmFyYy5sZW5ndGggPD0gMCAmJiB0aGlzLmNvbmZpZy5yYW5kb21pemUpIHtcbiAgICAgICAgdGhpcy5hcmMgPSBBcmMucmFuZG9taXplKHRoaXMuYXJjKTtcbiAgICB9XG5cbiAgICB0aGlzLmdyaWRzLnZpc2lvbiA9IHVwZGF0ZVZpc2lvbkdyaWQodGhpcy5hcmMsIHRoaXMuY29uZmlnLCB0aGlzLmdyaWRzKTtcbiAgICBjb25zdCB7IGhhemFyZHMsIHBhcnRpY2xlcyB9ID0gbG9vayh0aGlzLmFyYywgdGhpcy5ncmlkcyk7XG5cbiAgICB0aGlzLnVwZGF0ZUxlYWRlcihwYXJ0aWNsZXMpO1xuXG4gICAgaWYgKGhhemFyZHMubGVuZ3RoID4gMCkge1xuICAgICAgICB0aGlzLmFyYyA9IEFyYy5ldmFkZSh0aGlzLmFyYyk7XG4gICAgfVxuXG4gICAgdGhpcy5hcmMgPSBBcmMuc3RlcCh0aGlzLmFyYywgdGhpcy5jb25maWcuYm91bmRzKTtcblxuICAgIHRoaXMuZ3JpZHMuZ2xvYmFsLnNldFBvaW50KHtcbiAgICAgICAgeDogdGhpcy5hcmMuZW5kWCxcbiAgICAgICAgeTogdGhpcy5hcmMuZW5kWSxcbiAgICAgICAgdHlwZTogRU5USVRJRVMuUEFSVElDTEVcbiAgICB9LCB0aGlzKTtcbn1cblxuUGFydGljbGUucHJvdG90eXBlLnN1YnNjcmliZUZyYW1lUmVwYWludCA9IGZ1bmN0aW9uKG4pIHtcbiAgICByZXBhaW50Q29udGFpbmVyKHRoaXMubm9kZXMuY29udGFpbmVyLCB0aGlzLmFyYywgdGhpcy5sZWFkZXJUaW1lKTtcbiAgICByZXBhaW50Qm9keSh0aGlzLm5vZGVzLmJvZHksIHRoaXMuYXJjLCB0aGlzLmxlYWRlclRpbWUpO1xuICAgIHJlcGFpbnRDaXJjbGUodGhpcy5ub2Rlcy5jaXJjbGUsIHRoaXMuYXJjKTtcbiAgICByZXBhaW50VmlzaW9uR3JpZCh0aGlzLm5vZGVzLnZpc2lvbkdyaWQsIHRoaXMuYXJjLCB0aGlzLmdyaWRzKTtcbn1cblxuUGFydGljbGUucHJvdG90eXBlLnN1YnNjcmliZVNwZWVkID0gZnVuY3Rpb24odmFsdWUpIHtcbiAgICBBcmMuY2hhbmdlU3BlZWQodGhpcy5hcmMsIHZhbHVlKTtcbn1cblxuUGFydGljbGUucHJvdG90eXBlLnN1YnNjcmliZUNpcmNsZSA9IGZ1bmN0aW9uKHNob3cpIHtcbiAgICBpZiAoc2hvdyA9PT0gZmFsc2UpIHtcbiAgICAgICAgdGhpcy5ub2Rlcy5jb250YWluZXIucmVtb3ZlQ2hpbGQodGhpcy5ub2Rlcy5jaXJjbGUpO1xuICAgICAgICBkZWxldGUgdGhpcy5ub2Rlcy5jaXJjbGU7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5ub2Rlcy5jaXJjbGUgPSBjcmVhdGVDaXJjbGVOb2RlKHRoaXMuY29uZmlnKTtcbiAgICAgICAgdGhpcy5ub2Rlcy5jb250YWluZXIuYXBwZW5kQ2hpbGQodGhpcy5ub2Rlcy5jaXJjbGUpO1xuICAgIH1cbn1cblxuUGFydGljbGUucHJvdG90eXBlLnN1YnNjcmliZVJhbmRvbWl6ZSA9IGZ1bmN0aW9uKHZhbHVlKSB7XG4gICAgdGhpcy5jb25maWcucmFuZG9taXplID0gdmFsdWU7XG59XG5cblBhcnRpY2xlLnByb3RvdHlwZS5zdWJzY3JpYmVWaXNpb24gPSBmdW5jdGlvbihzaG93KSB7XG4gICAgaWYgKHNob3cgPT09IGZhbHNlKSB7XG4gICAgICAgIHRoaXMubm9kZXMudmlzaW9uR3JpZC5mb3JFYWNoKG4gPT4gbi5wYXJlbnROb2RlLnJlbW92ZUNoaWxkKG4pKTtcbiAgICAgICAgZGVsZXRlIHRoaXMubm9kZXMudmlzaW9uR3JpZDtcbiAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLm5vZGVzLnZpc2lvbkdyaWQgPSBjcmVhdGVWaXNpb25HcmlkTm9kZXModGhpcy5jb25maWcsIHRoaXMuZ3JpZHMsIHRoaXMubm9kZXMpO1xuICAgIH1cbn1cblxuUGFydGljbGUucHJvdG90eXBlLnVwZGF0ZUxlYWRlciA9IGZ1bmN0aW9uKHBhcnRpY2xlcykge1xuICAgIGlmICh0aGlzLmNvbmZpZy5iZWhhdmlvciAhPT0gQkVIQVZJT1IuQ09IRVNJT04pIHtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIEhlYWQtdG8taGVhZDogcGFydGljbGVzIHNlZSBlYWNob3RoZXIgYnV0IHNob3VsZG4ndCBib3RoIGxlYWQuXG4gICAgaWYgKHRoaXMubGVhZGVyID09PSBudWxsICYmIHBhcnRpY2xlcy5sZW5ndGggPiAwKSB7XG4gICAgICAgIGNvbnN0IGNhbmRpZGF0ZXMgPSBwYXJ0aWNsZXNcbiAgICAgICAgICAgIC5maWx0ZXIodiA9PiB2LmxlYWRlciA/ICh2LmxlYWRlci5pZCAhPT0gdGhpcy5pZCkgOiB0cnVlKTtcblxuICAgICAgICBjb25zdCBsZWFkZXIgPSBjYW5kaWRhdGVzLmZpbmQodiA9PiAodi5sZWFkZXJUaW1lID4gMCkpIHx8IGNhbmRpZGF0ZXNbMF07XG5cbiAgICAgICAgaWYgKGxlYWRlciAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICBsZWFkZXIubGVhZGVyVGltZSA9IDE7XG4gICAgICAgICAgICB0aGlzLmxlYWRlclRpbWUgPSAwO1xuICAgICAgICAgICAgdGhpcy5sZWFkZXIgPSBsZWFkZXI7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAodGhpcy5sZWFkZXIgPT09IG51bGwpIHtcbiAgICAgICAgaWYgKHRoaXMubGVhZGVyVGltZSA+IDApIHtcbiAgICAgICAgICAgIHRoaXMubGVhZGVyVGltZSsrO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gUmVzZXQgbGVhZGVyIGFmdGVyIGEgYml0LiAoMzIwIGZyYW1lcyBpcyAxMCBzZWNvbmRzKVxuICAgICAgICBpZiAodGhpcy5sZWFkZXJUaW1lID4gMzAwMCkge1xuICAgICAgICAgICAgdGhpcy5sZWFkZXJUaW1lID0gMDtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFRoaXMgcGFydGljbGUgbWF5IG5vdyBiZSBsZWFkaW5nIC0gYnJlYWsgZXhlY3V0aW9uLlxuICAgICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgLy8gaWYgKHRoaXMubGVhZGVyLm5vZGVzID09PSB1bmRlZmluZWQpIHtcbiAgICBpZiAodGhpcy5sZWFkZXIubGVhZGVyVGltZSA9PT0gMCAmJiB0aGlzLmxlYWRlci5sZWFkZXIgPT09IG51bGwpIHtcbiAgICAgICAgdGhpcy5sZWFkZXIgPSBudWxsO1xuICAgICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdGhpcy5sZWFkZXJUaW1lID0gMDtcblxuICAgIC8vIFZpc2l0IG5leHQgbm9kZSB0byBrZWVwIGNoYWlucyBvZiBsZWFkZXJzIHNob3J0LlxuICAgIGlmICh0aGlzLmxlYWRlci5sZWFkZXIgIT09IG51bGwpIHtcbiAgICAgICAgdGhpcy5sZWFkZXIgPSB0aGlzLmxlYWRlci5sZWFkZXI7XG4gICAgfVxuXG4gICAgLy8gQmV3YXJlIG9mIGNpcmN1bGFyIGxlYWRlcnNoaXAsIHdoZXJlIGEgbGVhZGVyIHNlZXMgaXRzIHRhaWwuXG4gICAgaWYgKHRoaXMubGVhZGVyLmlkID09PSB0aGlzLmlkKSB7XG4gICAgICAgIHRoaXMubGVhZGVyID0gbnVsbDtcbiAgICB9XG59XG5cbmZ1bmN0aW9uIGxvb2soYXJjLCBncmlkcykge1xuICAgIGNvbnN0IHsgZ2xvYmFsLCB2aXNpb24gfSA9IGdyaWRzO1xuXG4gICAgcmV0dXJuIHZpc2lvbi5yZWR1Y2UoKGFjYywgcG9pbnQpID0+IHtcbiAgICAgICAgcG9pbnQudG91Y2ggPSBmYWxzZTtcblxuICAgICAgICBjb25zdCB4ID0gYXJjLmVuZFggKyBwb2ludC54O1xuICAgICAgICBjb25zdCB5ID0gYXJjLmVuZFkgKyBwb2ludC55O1xuICAgICAgICBjb25zdCBwID0gZ2xvYmFsLmdldFBvaW50KHsgeCwgeSwgdHlwZTogRU5USVRJRVMuUEFSVElDTEUgfSk7XG5cbiAgICAgICAgaWYgKHApIHtcbiAgICAgICAgICAgIGFjYy5wYXJ0aWNsZXMucHVzaChwKTtcbiAgICAgICAgICAgIHBvaW50LnRvdWNoID0gdHJ1ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChnbG9iYWwuZ2V0UG9pbnQoeyB4LCB5LCB0eXBlOiBFTlRJVElFUy5IQVpBUkQgfSkpIHtcbiAgICAgICAgICAgIGFjYy5oYXphcmRzLnB1c2goeyB4LCB5IH0pO1xuICAgICAgICAgICAgcG9pbnQudG91Y2ggPSB0cnVlO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGFjYztcbiAgICB9LCB7IGhhemFyZHM6IFtdLCBwYXJ0aWNsZXM6IFtdIH0pO1xufVxuXG4vLyA9PT09PSBET00gQ1JFQVRJT04gPT09PT1cblxuZnVuY3Rpb24gY3JlYXRlQm9keU5vZGUoY29uZmlnKSB7XG4gICAgY29uc3Qgbm9kZSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgIG5vZGUuY2xhc3NOYW1lID0gJ3BhcnRpY2xlLWJvZHknO1xuICAgIG5vZGUuc3R5bGUuYmFja2dyb3VuZENvbG9yID0gY29uZmlnLmNvbG9yO1xuICAgIHJldHVybiBub2RlO1xufVxuXG5mdW5jdGlvbiBjcmVhdGVDaXJjbGVOb2RlKGNvbmZpZykge1xuICAgIGNvbnN0IG5vZGUgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICBub2RlLmNsYXNzTmFtZSA9ICdwYXJ0aWNsZS1tb3ZlbWVudC1jaXJjbGUnO1xuICAgIG5vZGUuc3R5bGUuYm9yZGVyQ29sb3IgPSBjb25maWcuY29sb3I7XG4gICAgcmV0dXJuIG5vZGU7XG59XG5cbmZ1bmN0aW9uIGNyZWF0ZUNvbnRhaW5lck5vZGUoY29uZmlnLCBpZCkge1xuICAgIGNvbnN0IG5vZGUgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICBub2RlLmNsYXNzTmFtZSA9ICdwYXJ0aWNsZS1jb250YWluZXInO1xuICAgIG5vZGUuaWQgPSBpZDtcbiAgICByZXR1cm4gbm9kZTtcbn1cblxuZnVuY3Rpb24gY3JlYXRlVmlzaW9uR3JpZChjb25maWcpIHtcbiAgICBjb25zdCB7IGdyaWRTaXplOiBzaWRlLCB2aXNpb25SYWRpdXM6IHJhZGl1cyB9ID0gY29uZmlnO1xuICAgIGNvbnN0IHIwID0gcmFkaXVzO1xuICAgIGNvbnN0IHIxID0gNDU7XG5cbiAgICBjb25zdCBwb2ludHMgPSBbXTtcblxuICAgIGZvciAobGV0IHggPSAtcmFkaXVzOyB4IDw9IHJhZGl1czsgeCArPSBzaWRlKSB7XG4gICAgICAgIGZvciAobGV0IHkgPSAtcmFkaXVzOyB5IDw9IHJhZGl1czsgeSArPSBzaWRlKSB7XG4gICAgICAgICAgICAvLyBPbWl0IGxhcmdlIHNsaWNlcyBvZiB1bnVzZWQgY2lyY2xlXG4gICAgICAgICAgICBpZiAoeCA+IHkgfHwgeCA8IC15KSB7XG4gICAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIEluY2x1ZGUgdmlzaW9uIGJhbmRcbiAgICAgICAgICAgIGNvbnN0IHIgPSBNYXRoLnBvdyhNYXRoLnBvdyh4LCAyKSArIE1hdGgucG93KHksIDIpLCAwLjUpO1xuICAgICAgICAgICAgaWYgKHIgPiByMCB8fCByIDwgcjEpIHtcbiAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgbGV0IGFscGhhID0gTWF0aC5hdGFuKHkgLyB4KTtcbiAgICAgICAgICAgIGlmICh4IDwgMCkge1xuICAgICAgICAgICAgICAgIGFscGhhICs9IFJBRC50MTgwO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBwb2ludHMucHVzaCh7IHgsIHksIHIsIGFscGhhLCB0b3VjaDogZmFsc2UgfSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gcG9pbnRzO1xufVxuXG5mdW5jdGlvbiBjcmVhdGVWaXNpb25HcmlkTm9kZXMoY29uZmlnLCBncmlkcywgbm9kZXMpIHtcbiAgICByZXR1cm4gZ3JpZHMudmlzaW9uLnJlZHVjZSgoYWNjLCB7IHgsIHkgfSkgPT4ge1xuICAgICAgICBjb25zdCBkaXYgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICAgICAgZGl2LmNsYXNzTmFtZSA9ICdwYXJ0aWNsZS12aXNpb24tZG90JztcbiAgICAgICAgZGl2LnN0eWxlLmJhY2tncm91bmRDb2xvciA9IGNvbmZpZy5jb2xvcjtcbiAgICAgICAgbm9kZXMuY29udGFpbmVyLmFwcGVuZENoaWxkKGRpdik7XG5cbiAgICAgICAgYWNjLnB1c2goZGl2KTtcblxuICAgICAgICByZXR1cm4gYWNjO1xuICAgIH0sIFtdKTtcbn1cblxuXG5mdW5jdGlvbiB1cGRhdGVWaXNpb25HcmlkKGFyYywgY29uZmlnLCBncmlkcykge1xuICAgIGNvbnN0IHsgZ2xvYmFsLCB2aXNpb24gfSA9IGdyaWRzO1xuXG4gICAgcmV0dXJuIHZpc2lvbi5yZWR1Y2UoKGFjYywgcG9pbnQpID0+IHtcbiAgICAgICAgY29uc3QgcmFkID0gYXJjLmNsb2Nrd2lzZVxuICAgICAgICAgICAgPyBwb2ludC5hbHBoYSAtIGFyYy50aGV0YVxuICAgICAgICAgICAgOiBwb2ludC5hbHBoYSAtIGFyYy50aGV0YSArIFJBRC50MTgwO1xuXG4gICAgICAgIHBvaW50LnggPSBwb2ludC5yICogTWF0aC5jb3MocmFkKTtcbiAgICAgICAgcG9pbnQueSA9IHBvaW50LnIgKiBNYXRoLnNpbihyYWQpO1xuXG4gICAgICAgIHJldHVybiBhY2MuY29uY2F0KHBvaW50KTtcbiAgICB9LCBbXSk7XG59XG5cbi8vID09PT09IERPTSBSRU5ERVJJTkcgPT09PT1cbmZ1bmN0aW9uIHJlcGFpbnRDb250YWluZXIobm9kZSwgYXJjLCBsZWFkZXJUaW1lKSB7XG4gICAgbm9kZS5zdHlsZS5sZWZ0ID0gYCR7YXJjLmVuZFh9cHhgO1xuICAgIG5vZGUuc3R5bGUudG9wID0gYCR7YXJjLmVuZFl9cHhgO1xuXG4gICAgLy8gbm9kZS5zdHlsZS56SW5kZXggPSAobGVhZGVyVGltZSA+IDAgPyAyMDAwIDogMik7XG59XG5cbmZ1bmN0aW9uIHJlcGFpbnRCb2R5KG5vZGUsIGFyYywgbGVhZGVyVGltZSkge1xuICAgIGNvbnN0IHJhZCA9IGFyYy5jbG9ja3dpc2VcbiAgICAgICAgPyBSQUQudDE4MCAtIGFyYy50aGV0YVxuICAgICAgICA6IFJBRC50MzYwIC0gYXJjLnRoZXRhO1xuXG4gICAgbm9kZS5zdHlsZS50cmFuc2Zvcm0gPSBgcm90YXRlKCR7cmFkICsgUkFELnQ0NX1yYWQpYDtcblxuICAgIC8vIG5vZGUuc3R5bGUuYm9yZGVyID0gKGxlYWRlclRpbWUgPiAwID8gJzNweCBkb3R0ZWQgI2ZmZicgOiAnJyk7XG59XG5cbmZ1bmN0aW9uIHJlcGFpbnRDaXJjbGUobm9kZSwgYXJjKSB7XG4gICAgaWYgKG5vZGUgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgbm9kZS5zdHlsZS53aWR0aCA9IGAkezIgKiBhcmMucmFkaXVzfXB4YDtcbiAgICBub2RlLnN0eWxlLmhlaWdodCA9IGAkezIgKiBhcmMucmFkaXVzfXB4YDtcblxuICAgIG5vZGUuc3R5bGUubGVmdCA9IGAtJHthcmMucmFkaXVzICsgYXJjLnJhZGl1cyAqIGFyYy5jb3NUaGV0YX1weGA7XG4gICAgbm9kZS5zdHlsZS50b3AgPSBgLSR7YXJjLnJhZGl1cyAtIGFyYy5yYWRpdXMgKiBhcmMuc2luVGhldGF9cHhgO1xuXG4gICAgbm9kZS5zdHlsZS5ib3JkZXJSYWRpdXMgPSBgJHthcmMucmFkaXVzfXB4YDtcbn1cblxuZnVuY3Rpb24gcmVwYWludFZpc2lvbkdyaWQobm9kZXMsIGFyYywgZ3JpZHMpIHtcbiAgICBpZiAobm9kZXMgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgZ3JpZHMudmlzaW9uLmZvckVhY2goKHsgeCwgeSwgdG91Y2ggfSwgaSkgPT4ge1xuICAgICAgICBub2Rlc1tpXS5zdHlsZS5sZWZ0ID0gYCR7eH1weGA7XG4gICAgICAgIG5vZGVzW2ldLnN0eWxlLnRvcCA9IGAke3l9cHhgO1xuXG4gICAgICAgIG5vZGVzW2ldLnN0eWxlLmJvcmRlciA9ICh0b3VjaCA/ICcxcHggc29saWQgcmVkJyA6ICcwJyk7XG4gICAgfSk7XG59XG5cbmV4cG9ydCBkZWZhdWx0IFBhcnRpY2xlO1xuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIGpzL3BhcnRpY2xlLmpzIl0sIm1hcHBpbmdzIjoiOzs7Ozs7QUFBQTtBQUNBOzs7QUFBQTtBQUNBO0FBQUE7QUFDQTs7O0FBQUE7QUFDQTs7Ozs7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFSQTtBQUNBO0FBVUE7QUFDQTtBQUNBO0FBRkE7QUFDQTtBQUlBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBSkE7QUFDQTtBQU1BO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUhBO0FBQ0E7QUFLQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBR0E7QUFDQTtBQUdBO0FBQ0E7QUFHQTtBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUhBO0FBQ0E7QUFLQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBSEE7QUFDQTtBQUtBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFkQTtBQUFBO0FBQUE7QUFDQTtBQWVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUhBO0FBS0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZVJvb3QiOiIifQ=="); /***/ }), /* 87 */ diff --git a/js/index.js b/js/index.js index e8867c8..7c5d142 100644 --- a/js/index.js +++ b/js/index.js @@ -29,11 +29,4 @@ window.addEventListener('load', () => { }); // TODO remove bottom padding from Disqus -// TODO sort out particle nextframe - -// INTERESTING CONTROLS: -// sensitivity -// rigidity -// show leaders - -// TURN THE CORRECT DIRECTION - HUGE EFFICIENCY INCREASE +// TODO TURN THE CORRECT DIRECTION - HUGE EFFICIENCY INCREASE diff --git a/js/particle.js b/js/particle.js index e0f9747..1ae034b 100644 --- a/js/particle.js +++ b/js/particle.js @@ -210,19 +210,20 @@ function look(arc, grids) { const { global, vision } = grids; return vision.reduce((acc, point) => { + point.touch = false; + const x = arc.endX + point.x; const y = arc.endY + point.y; const p = global.getPoint({ x, y, type: ENTITIES.PARTICLE }); if (p) { acc.particles.push(p); + point.touch = true; } if (global.getPoint({ x, y, type: ENTITIES.HAZARD })) { acc.hazards.push({ x, y }); point.touch = true; - } else { - point.touch = false; } return acc;