diff --git a/client/dist/bundle.js b/client/dist/bundle.js index 3af789d..b6a6b68 100644 --- a/client/dist/bundle.js +++ b/client/dist/bundle.js @@ -94,7 +94,7 @@ /***/ (function(module, exports, __webpack_require__) { "use strict"; -eval("\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nvar _react = __webpack_require__(/*! react */ \"./node_modules/react/index.js\");\n\nvar _react2 = _interopRequireDefault(_react);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nvar Brick = function Brick(props) {\n return _react2.default.createElement(\n \"div\",\n { className: \"brick\" },\n _react2.default.createElement(\n \"p\",\n null,\n props.word\n )\n );\n};\n\nexports.default = Brick;//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9jbGllbnQvc3JjL2NvbXBvbmVudHMvQnJpY2suanN4LmpzIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vL2NsaWVudC9zcmMvY29tcG9uZW50cy9Ccmljay5qc3g/MDI3NyJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgUmVhY3QgZnJvbSAncmVhY3QnO1xuXG5jb25zdCBCcmljayA9IChwcm9wcykgPT4ge1xuICByZXR1cm4gKFxuICAgIDxkaXYgY2xhc3NOYW1lPVwiYnJpY2tcIj5cbiAgICAgIDxwPntwcm9wcy53b3JkfTwvcD5cbiAgICA8L2Rpdj5cbiAgKVxufVxuXG5leHBvcnQgZGVmYXVsdCBCcmljazsiXSwibWFwcGluZ3MiOiI7Ozs7OztBQUFBO0FBQ0E7Ozs7O0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBREE7QUFJQTtBQUNBO0FBQ0EiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///./client/src/components/Brick.jsx\n"); +eval("\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nvar _react = __webpack_require__(/*! react */ \"./node_modules/react/index.js\");\n\nvar _react2 = _interopRequireDefault(_react);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nvar Brick = function Brick(props) {\n return _react2.default.createElement(\n 'div',\n { className: 'brick ' + props.powerup },\n _react2.default.createElement(\n 'p',\n null,\n props.word\n )\n );\n};\n\nexports.default = Brick;//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9jbGllbnQvc3JjL2NvbXBvbmVudHMvQnJpY2suanN4LmpzIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vL2NsaWVudC9zcmMvY29tcG9uZW50cy9Ccmljay5qc3g/MDI3NyJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgUmVhY3QgZnJvbSAncmVhY3QnO1xuXG5jb25zdCBCcmljayA9IChwcm9wcykgPT4ge1xuICByZXR1cm4gKFxuICAgIDxkaXYgY2xhc3NOYW1lPXtgYnJpY2sgJHtwcm9wcy5wb3dlcnVwfWB9PlxuICAgICAgPHA+e3Byb3BzLndvcmR9PC9wPlxuICAgIDwvZGl2PlxuICApXG59XG5cbmV4cG9ydCBkZWZhdWx0IEJyaWNrOyJdLCJtYXBwaW5ncyI6Ijs7Ozs7O0FBQUE7QUFDQTs7Ozs7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFEQTtBQUlBO0FBQ0E7QUFDQSIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///./client/src/components/Brick.jsx\n"); /***/ }), @@ -106,7 +106,19 @@ eval("\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n /***/ (function(module, exports, __webpack_require__) { "use strict"; -eval("/* WEBPACK VAR INJECTION */(function(process) {\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();\n\nvar _react = __webpack_require__(/*! react */ \"./node_modules/react/index.js\");\n\nvar _react2 = _interopRequireDefault(_react);\n\nvar _Brick = __webpack_require__(/*! ./Brick.jsx */ \"./client/src/components/Brick.jsx\");\n\nvar _Brick2 = _interopRequireDefault(_Brick);\n\nvar _axios = __webpack_require__(/*! axios */ \"./node_modules/axios/index.js\");\n\nvar _axios2 = _interopRequireDefault(_axios);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nfunction _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\"); } return call && (typeof call === \"object\" || typeof call === \"function\") ? call : self; }\n\nfunction _inherits(subClass, superClass) { if (typeof superClass !== \"function\" && superClass !== null) { throw new TypeError(\"Super expression must either be null or a function, not \" + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }\n\nvar io = __webpack_require__(/*! socket.io-client */ \"./node_modules/socket.io-client/lib/index.js\");\nvar socket = io();\n\nvar Game = function (_React$Component) {\n _inherits(Game, _React$Component);\n\n function Game(props) {\n _classCallCheck(this, Game);\n\n var _this = _possibleConstructorReturn(this, (Game.__proto__ || Object.getPrototypeOf(Game)).call(this, props));\n\n _this.state = {\n userInput: '',\n dictionary: {},\n words: [],\n theirWords: [],\n time: 0,\n timeInterval: 1000,\n round: 'all',\n instructions: [\"Humpty Dumpty sat on a wall,\", \"Humpty Dumpty had a great fall.\", \"All the king's horses and all the king's men\", \"Couldn't put Humpty together again.\", \"HURRY - KEEP TYPING TO PREVENT HIS DEMISE!\"],\n prompt: 'START GAME',\n opponentTime: 0\n };\n\n _this.getReady = _this.getReady.bind(_this);\n _this.startGame = _this.startGame.bind(_this);\n _this.addWord = _this.addWord.bind(_this);\n _this.updateOpponentWordList = _this.updateOpponentWordList.bind(_this);\n _this.handleChange = _this.handleChange.bind(_this);\n _this.handleSubmit = _this.handleSubmit.bind(_this);\n _this.sendScore = _this.sendScore.bind(_this);\n _this.stopGame = _this.stopGame.bind(_this);\n\n var c = io.connect(process.env.PORT, { query: _this.state.time });\n console.log('c', c);\n\n socket.on('receive words from opponent', function (words) {\n _this.updateOpponentWordList(words);\n });\n socket.on('startGame', function () {\n _this.startGame();\n });\n socket.on('they lost', function (score) {\n // this is bad, eventually put a red x over their bricks or something\n _this.setState({\n opponentTime: score\n });\n document.getElementById('their-game').style.backgroundColor = \"red\";\n });\n return _this;\n }\n\n // get words from dictionary and join socket\n\n\n _createClass(Game, [{\n key: 'componentDidMount',\n value: function componentDidMount() {\n var _this2 = this;\n\n _axios2.default.get('/dictionary').then(function (results) {\n _this2.setState({\n dictionary: results.data\n });\n }).catch(function (err) {\n console.error(err);\n });\n socket.emit('entering room', {\n room: this.props.room,\n username: this.props.username\n });\n }\n\n // sends your words to opponent\n\n }, {\n key: 'componentDidUpdate',\n value: function componentDidUpdate(prevProps, prevState) {\n if (this.state.words.length !== prevState.words.length) {\n socket.emit('send words to opponent', {\n room: this.props.room,\n newWords: this.state.words\n });\n }\n }\n\n // leave socket\n\n }, {\n key: 'componentWillUnmount',\n value: function componentWillUnmount() {\n socket.emit('leaving room', {\n room: this.props.room,\n username: this.props.username\n });\n }\n\n // hides starter form and user input, waits for another player to start game\n\n }, {\n key: 'getReady',\n value: function getReady(e) {\n e.preventDefault();\n document.getElementById('starter-form').disabled = true;\n document.getElementById('user-input').disabled = true;\n this.setState({\n prompt: 'WAITING...'\n });\n socket.emit('ready', {\n room: this.props.room,\n username: this.props.username\n });\n }\n }, {\n key: 'startGame',\n value: function startGame() {\n var _this3 = this;\n\n document.getElementById('typing-input').disabled = false;\n document.getElementById('typing-input').focus();\n document.getElementById('overlay').style.display = \"none\";\n document.getElementById('their-game').style.backgroundColor = \"transparent\";\n document.getElementById('gudetama').style = {\n display: \"inline-block\",\n backgroundColor: \"none\"\n };\n document.getElementById('their-gudetama').style = {\n display: \"inline-block\",\n backgroundColor: \"none\"\n };\n\n // long function to define what happens at every interval\n var go = function go() {\n // creates a loop by calling itself:\n var step = setTimeout(function () {\n go();\n }, _this3.state.timeInterval);\n\n // adds a brick:\n _this3.addWord();\n\n // ends game or changes background color of gudetama based on length of \"words\" array\n // (as bricks build up, background turns a darker red to signify danger)\n if (_this3.state.words.length >= 20) {\n clearTimeout(step);\n //console.log('opponent time',this.state.time)\n socket.emit('i lost', {\n room: _this3.props.room,\n username: _this3.props.username,\n score: _this3.state.time\n });\n _this3.stopGame();\n } else if (_this3.state.words.length > 15) {\n document.getElementById('gudetama').style.backgroundColor = \"rgba(255, 0, 0, 1)\";\n } else if (_this3.state.words.length > 10) {\n document.getElementById('gudetama').style.backgroundColor = \"rgba(255, 0, 0, 0.5)\";\n }\n\n // updates the time and speeds up the game accordingly \n // (as timeInterval decreases, words appear at a faster rate)\n var newTime = _this3.state.time + 1;\n if (newTime > 20) {\n _this3.setState({\n time: newTime,\n timeInterval: 600\n //round: 'roundThree', // uncomment these to only serve short words at beginning, long words at end\n });\n } else if (newTime > 8) {\n _this3.setState({\n time: newTime,\n timeInterval: 800\n //round: 'roundTwo',\n });\n } else {\n _this3.setState({\n time: newTime\n //round: 'roundOne',\n });\n }\n };\n\n // blank slate, then start!\n this.setState({\n words: [],\n time: 0,\n timeInterval: 1000,\n userInput: ''\n }, function () {\n return go();\n });\n }\n\n // pulls random word from dictionary obj and adds it to words state\n\n }, {\n key: 'addWord',\n value: function addWord() {\n var availableWords = this.state.dictionary[this.state.round];\n var newWord = availableWords[Math.floor(Math.random() * availableWords.length)];\n this.setState({\n words: [].concat(_toConsumableArray(this.state.words), [newWord])\n });\n }\n\n // updates your view of opponent's words\n\n }, {\n key: 'updateOpponentWordList',\n value: function updateOpponentWordList(words) {\n this.setState({\n theirWords: words\n });\n }\n\n // updates userInput with what user is currently typing\n\n }, {\n key: 'handleChange',\n value: function handleChange(e) {\n this.setState({\n userInput: e.target.value\n });\n }\n\n // when the user hits \"enter\"\n\n }, {\n key: 'handleSubmit',\n value: function handleSubmit(e) {\n e.preventDefault();\n var submittedWord = this.state.userInput;\n var index = this.state.words.indexOf(submittedWord);\n\n // check if what they typed is in our \"words\" array\n // flash green for a correctly typed word and remove word from \"words\" array\n if (index !== -1) {\n document.getElementById('typing-input').style.backgroundColor = \"green\";\n var newWords = this.state.words.slice();\n newWords.splice(index, 1);\n playCorrect();\n this.setState({\n words: newWords\n });\n } else {\n // else flash red for a mistyped word\n playWrong();\n document.getElementById('typing-input').style.backgroundColor = \"red\";\n }\n\n setTimeout(function () {\n document.getElementById('typing-input').style.backgroundColor = \"white\";\n }, 100);\n\n this.setState({\n userInput: ''\n });\n }\n\n // upon game over, sends username and score to database to be added/updated\n\n }, {\n key: 'sendScore',\n value: function sendScore(username, score) {\n _axios2.default.post('/wordgame', {\n \"username\": username,\n \"high_score\": score\n }).then(function (result) {\n console.log(result);\n }).catch(function (err) {\n console.error(err);\n });\n }\n }, {\n key: 'stopGame',\n value: function stopGame() {\n document.getElementById('typing-input').disabled = true;\n document.getElementById('overlay').style.display = \"block\";\n document.getElementById('gudetama').style.display = \"none\";\n document.getElementById('their-gudetama').style.display = \"none\";\n document.getElementById('starter-form').disabled = false;\n document.getElementById('user-input').disabled = false;\n\n // enables user to hit \"enter\" after 2 seconds to restart game\n setTimeout(function () {\n if (document.getElementById('overlay').display !== \"none\") {\n document.getElementById('user-input').focus();\n }\n }, 2000);\n\n this.sendScore(this.props.username, this.state.time);\n\n // audio effect\n playGameOver();\n\n this.setState({\n // maybe find a way to compare your score vs opponent's score and show YOU WIN/YOU LOSE\n instructions: ['GAME OVER', 'YOU SCORED: ' + this.state.time, 'YOUR OPPONENT SCORED: ' + this.state.opponentTime],\n prompt: 'REPLAY'\n });\n }\n }, {\n key: 'render',\n value: function render() {\n return _react2.default.createElement(\n 'div',\n { className: 'game' },\n _react2.default.createElement(\n 'div',\n { id: 'overlay' },\n _react2.default.createElement(\n 'div',\n null,\n this.state.instructions.map(function (line, index) {\n // audio effect:\n playStart();\n return _react2.default.createElement(\n 'span',\n { key: index },\n line,\n _react2.default.createElement('br', null)\n );\n })\n ),\n _react2.default.createElement('div', { id: 'crackedegg' }),\n _react2.default.createElement(\n 'div',\n null,\n _react2.default.createElement(\n 'form',\n { id: 'starter-form', onSubmit: this.getReady, autoComplete: 'off' },\n _react2.default.createElement('input', { id: 'user-input', placeholder: 'Who are you?', value: this.props.username, onChange: this.props.handleUserNameChange, autoFocus: true })\n )\n ),\n _react2.default.createElement(\n 'div',\n { id: 'overlay-start', onClick: this.startGame, className: 'blinking' },\n this.state.prompt\n )\n ),\n _react2.default.createElement(\n 'div',\n { className: 'timer' },\n _react2.default.createElement(\n 'h1',\n null,\n this.state.time\n )\n ),\n _react2.default.createElement(\n 'div',\n { className: 'board' },\n _react2.default.createElement(\n 'div',\n { className: 'play' },\n this.state.words.map(function (word, index) {\n return _react2.default.createElement(_Brick2.default, { word: word, key: index });\n }),\n _react2.default.createElement('div', { id: 'gudetama' }),\n _react2.default.createElement(\n 'form',\n { onSubmit: this.handleSubmit, autoComplete: 'off' },\n _react2.default.createElement('input', { id: 'typing-input', value: this.state.userInput, onChange: this.handleChange })\n )\n ),\n _react2.default.createElement(\n 'div',\n { className: 'play', id: 'their-game' },\n this.state.theirWords.map(function (word, index) {\n return _react2.default.createElement(_Brick2.default, { word: word, key: index });\n }),\n _react2.default.createElement('div', { id: 'their-gudetama' }),\n _react2.default.createElement(\n 'form',\n { autoComplete: 'off' },\n _react2.default.createElement('input', { value: 'OPPONENT' })\n )\n )\n )\n );\n }\n }]);\n\n return Game;\n}(_react2.default.Component);\n\nexports.default = Game;\n/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../../../node_modules/process/browser.js */ \"./node_modules/process/browser.js\")))//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9jbGllbnQvc3JjL2NvbXBvbmVudHMvR2FtZS5qc3guanMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vY2xpZW50L3NyYy9jb21wb25lbnRzL0dhbWUuanN4PzE2ZWIiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IFJlYWN0IGZyb20gJ3JlYWN0JztcbmltcG9ydCBCcmljayBmcm9tICcuL0JyaWNrLmpzeCc7XG5pbXBvcnQgYXhpb3MgZnJvbSAnYXhpb3MnO1xuY29uc3QgaW8gPSByZXF1aXJlKCdzb2NrZXQuaW8tY2xpZW50Jyk7IFxuY29uc3Qgc29ja2V0ID0gaW8oKTtcblxuY2xhc3MgR2FtZSBleHRlbmRzIFJlYWN0LkNvbXBvbmVudCB7XG4gIGNvbnN0cnVjdG9yKHByb3BzKSB7XG4gICAgc3VwZXIocHJvcHMpO1xuICAgIHRoaXMuc3RhdGUgPSB7XG4gICAgICB1c2VySW5wdXQ6ICcnLFxuICAgICAgZGljdGlvbmFyeToge30sXG4gICAgICB3b3JkczogW10sXG4gICAgICB0aGVpcldvcmRzOiBbXSxcbiAgICAgIHRpbWU6IDAsXG4gICAgICB0aW1lSW50ZXJ2YWw6IDEwMDAsXG4gICAgICByb3VuZDogJ2FsbCcsXG4gICAgICBpbnN0cnVjdGlvbnM6IFtcIkh1bXB0eSBEdW1wdHkgc2F0IG9uIGEgd2FsbCxcIiwgXCJIdW1wdHkgRHVtcHR5IGhhZCBhIGdyZWF0IGZhbGwuXCIsIFwiQWxsIHRoZSBraW5nJ3MgaG9yc2VzIGFuZCBhbGwgdGhlIGtpbmcncyBtZW5cIiwgXCJDb3VsZG4ndCBwdXQgSHVtcHR5IHRvZ2V0aGVyIGFnYWluLlwiLCBcIkhVUlJZIC0gS0VFUCBUWVBJTkcgVE8gUFJFVkVOVCBISVMgREVNSVNFIVwiXSxcbiAgICAgIHByb21wdDogJ1NUQVJUIEdBTUUnLFxuICAgICAgb3Bwb25lbnRUaW1lOiAwXG4gICAgfVxuICAgIFxuICAgIHRoaXMuZ2V0UmVhZHkgPSB0aGlzLmdldFJlYWR5LmJpbmQodGhpcyk7XG4gICAgdGhpcy5zdGFydEdhbWUgPSB0aGlzLnN0YXJ0R2FtZS5iaW5kKHRoaXMpO1xuICAgIHRoaXMuYWRkV29yZCA9IHRoaXMuYWRkV29yZC5iaW5kKHRoaXMpO1xuICAgIHRoaXMudXBkYXRlT3Bwb25lbnRXb3JkTGlzdCA9IHRoaXMudXBkYXRlT3Bwb25lbnRXb3JkTGlzdC5iaW5kKHRoaXMpO1xuICAgIHRoaXMuaGFuZGxlQ2hhbmdlID0gdGhpcy5oYW5kbGVDaGFuZ2UuYmluZCh0aGlzKTtcbiAgICB0aGlzLmhhbmRsZVN1Ym1pdCA9IHRoaXMuaGFuZGxlU3VibWl0LmJpbmQodGhpcyk7XG4gICAgdGhpcy5zZW5kU2NvcmUgPSB0aGlzLnNlbmRTY29yZS5iaW5kKHRoaXMpO1xuICAgIHRoaXMuc3RvcEdhbWUgPSB0aGlzLnN0b3BHYW1lLmJpbmQodGhpcyk7XG5cbiAgICB2YXIgYyA9IGlvLmNvbm5lY3QocHJvY2Vzcy5lbnYuUE9SVCwge3F1ZXJ5OiB0aGlzLnN0YXRlLnRpbWV9KVxuICAgIGNvbnNvbGUubG9nKCdjJywgYylcblxuICAgIHNvY2tldC5vbigncmVjZWl2ZSB3b3JkcyBmcm9tIG9wcG9uZW50JywgKHdvcmRzKSA9PiB7XG4gICAgICB0aGlzLnVwZGF0ZU9wcG9uZW50V29yZExpc3Qod29yZHMpO1xuICAgIH0pO1xuICAgIHNvY2tldC5vbignc3RhcnRHYW1lJywgKCkgPT4ge1xuICAgICAgdGhpcy5zdGFydEdhbWUoKTtcbiAgICB9KTtcbiAgICBzb2NrZXQub24oJ3RoZXkgbG9zdCcsIChzY29yZSkgPT4ge1xuICAgICAgLy8gdGhpcyBpcyBiYWQsIGV2ZW50dWFsbHkgcHV0IGEgcmVkIHggb3ZlciB0aGVpciBicmlja3Mgb3Igc29tZXRoaW5nXG4gICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgb3Bwb25lbnRUaW1lOiBzY29yZSxcbiAgICAgIH0pXG4gICAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgndGhlaXItZ2FtZScpLnN0eWxlLmJhY2tncm91bmRDb2xvciA9IFwicmVkXCI7XG4gICAgfSk7XG4gIH1cblxuICAvLyBnZXQgd29yZHMgZnJvbSBkaWN0aW9uYXJ5IGFuZCBqb2luIHNvY2tldFxuICBjb21wb25lbnREaWRNb3VudCgpIHtcbiAgICBheGlvcy5nZXQoJy9kaWN0aW9uYXJ5JylcbiAgICAudGhlbihyZXN1bHRzID0+IHtcbiAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICBkaWN0aW9uYXJ5OiByZXN1bHRzLmRhdGEsXG4gICAgICB9KVxuICAgIH0pLmNhdGNoKGVyciA9PiB7XG4gICAgICBjb25zb2xlLmVycm9yKGVycik7XG4gICAgfSk7XG4gICAgc29ja2V0LmVtaXQoJ2VudGVyaW5nIHJvb20nLCB7XG4gICAgICByb29tOiB0aGlzLnByb3BzLnJvb20sIFxuICAgICAgdXNlcm5hbWU6IHRoaXMucHJvcHMudXNlcm5hbWVcbiAgICB9KTtcbiAgfVxuXG4gIC8vIHNlbmRzIHlvdXIgd29yZHMgdG8gb3Bwb25lbnRcbiAgY29tcG9uZW50RGlkVXBkYXRlKHByZXZQcm9wcywgcHJldlN0YXRlKSB7XG4gICAgaWYgKHRoaXMuc3RhdGUud29yZHMubGVuZ3RoICE9PSBwcmV2U3RhdGUud29yZHMubGVuZ3RoKSB7XG4gICAgICBzb2NrZXQuZW1pdCgnc2VuZCB3b3JkcyB0byBvcHBvbmVudCcsIHtcbiAgICAgICAgcm9vbTogdGhpcy5wcm9wcy5yb29tLFxuICAgICAgICBuZXdXb3JkczogdGhpcy5zdGF0ZS53b3JkcyxcbiAgICAgIH0pOyBcbiAgICB9XG4gIH1cblxuICAvLyBsZWF2ZSBzb2NrZXRcbiAgY29tcG9uZW50V2lsbFVubW91bnQoKSB7ICBcbiAgICBzb2NrZXQuZW1pdCgnbGVhdmluZyByb29tJywge1xuICAgICAgcm9vbTogdGhpcy5wcm9wcy5yb29tLFxuICAgICAgdXNlcm5hbWU6IHRoaXMucHJvcHMudXNlcm5hbWUsXG4gICAgfSk7XG4gIH1cblxuICAvLyBoaWRlcyBzdGFydGVyIGZvcm0gYW5kIHVzZXIgaW5wdXQsIHdhaXRzIGZvciBhbm90aGVyIHBsYXllciB0byBzdGFydCBnYW1lXG4gIGdldFJlYWR5KGUpIHtcbiAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3N0YXJ0ZXItZm9ybScpLmRpc2FibGVkID0gdHJ1ZTtcbiAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgndXNlci1pbnB1dCcpLmRpc2FibGVkID0gdHJ1ZTtcbiAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgIHByb21wdDogJ1dBSVRJTkcuLi4nLFxuICAgIH0pO1xuICAgIHNvY2tldC5lbWl0KCdyZWFkeScsIHtcbiAgICAgIHJvb206IHRoaXMucHJvcHMucm9vbSwgXG4gICAgICB1c2VybmFtZTogdGhpcy5wcm9wcy51c2VybmFtZVxuICAgIH0pO1xuICB9XG5cbiAgc3RhcnRHYW1lKCkge1xuICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCd0eXBpbmctaW5wdXQnKS5kaXNhYmxlZCA9IGZhbHNlO1xuICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCd0eXBpbmctaW5wdXQnKS5mb2N1cygpO1xuICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdvdmVybGF5Jykuc3R5bGUuZGlzcGxheSA9IFwibm9uZVwiO1xuICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCd0aGVpci1nYW1lJykuc3R5bGUuYmFja2dyb3VuZENvbG9yID0gXCJ0cmFuc3BhcmVudFwiO1xuICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdndWRldGFtYScpLnN0eWxlID0ge1xuICAgICAgZGlzcGxheTogXCJpbmxpbmUtYmxvY2tcIixcbiAgICAgIGJhY2tncm91bmRDb2xvcjogXCJub25lXCIsXG4gICAgfTtcbiAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgndGhlaXItZ3VkZXRhbWEnKS5zdHlsZSA9IHtcbiAgICAgIGRpc3BsYXk6IFwiaW5saW5lLWJsb2NrXCIsXG4gICAgICBiYWNrZ3JvdW5kQ29sb3I6IFwibm9uZVwiLFxuICAgIH07XG5cbiAgICAvLyBsb25nIGZ1bmN0aW9uIHRvIGRlZmluZSB3aGF0IGhhcHBlbnMgYXQgZXZlcnkgaW50ZXJ2YWxcbiAgICB2YXIgZ28gPSAoKSA9PiB7XG4gICAgICAvLyBjcmVhdGVzIGEgbG9vcCBieSBjYWxsaW5nIGl0c2VsZjpcbiAgICAgIHZhciBzdGVwID0gc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgIGdvKCk7XG4gICAgICB9LCB0aGlzLnN0YXRlLnRpbWVJbnRlcnZhbCk7XG5cbiAgICAgIC8vIGFkZHMgYSBicmljazpcbiAgICAgIHRoaXMuYWRkV29yZCgpO1xuXG4gICAgICAvLyBlbmRzIGdhbWUgb3IgY2hhbmdlcyBiYWNrZ3JvdW5kIGNvbG9yIG9mIGd1ZGV0YW1hIGJhc2VkIG9uIGxlbmd0aCBvZiBcIndvcmRzXCIgYXJyYXlcbiAgICAgIC8vIChhcyBicmlja3MgYnVpbGQgdXAsIGJhY2tncm91bmQgdHVybnMgYSBkYXJrZXIgcmVkIHRvIHNpZ25pZnkgZGFuZ2VyKVxuICAgICAgaWYgKHRoaXMuc3RhdGUud29yZHMubGVuZ3RoID49IDIwKSB7XG4gICAgICAgIGNsZWFyVGltZW91dChzdGVwKTtcbiAgICAgICAgLy9jb25zb2xlLmxvZygnb3Bwb25lbnQgdGltZScsdGhpcy5zdGF0ZS50aW1lKVxuICAgICAgICBzb2NrZXQuZW1pdCgnaSBsb3N0Jywge1xuICAgICAgICAgIHJvb206IHRoaXMucHJvcHMucm9vbSwgXG4gICAgICAgICAgdXNlcm5hbWU6IHRoaXMucHJvcHMudXNlcm5hbWUsIFxuICAgICAgICAgIHNjb3JlOiB0aGlzLnN0YXRlLnRpbWVcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuc3RvcEdhbWUoKTtcbiAgICAgIH0gZWxzZSBpZiAodGhpcy5zdGF0ZS53b3Jkcy5sZW5ndGggPiAxNSkge1xuICAgICAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnZ3VkZXRhbWEnKS5zdHlsZS5iYWNrZ3JvdW5kQ29sb3IgPSBcInJnYmEoMjU1LCAwLCAwLCAxKVwiO1xuICAgICAgfSBlbHNlIGlmICh0aGlzLnN0YXRlLndvcmRzLmxlbmd0aCA+IDEwKSB7XG4gICAgICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdndWRldGFtYScpLnN0eWxlLmJhY2tncm91bmRDb2xvciA9IFwicmdiYSgyNTUsIDAsIDAsIDAuNSlcIjtcbiAgICAgIH1cblxuICAgICAgLy8gdXBkYXRlcyB0aGUgdGltZSBhbmQgc3BlZWRzIHVwIHRoZSBnYW1lIGFjY29yZGluZ2x5IFxuICAgICAgLy8gKGFzIHRpbWVJbnRlcnZhbCBkZWNyZWFzZXMsIHdvcmRzIGFwcGVhciBhdCBhIGZhc3RlciByYXRlKVxuICAgICAgdmFyIG5ld1RpbWUgPSB0aGlzLnN0YXRlLnRpbWUgKyAxO1xuICAgICAgaWYgKG5ld1RpbWUgPiAyMCkge1xuICAgICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgICB0aW1lOiBuZXdUaW1lLFxuICAgICAgICAgIHRpbWVJbnRlcnZhbDogNjAwLFxuICAgICAgICAgIC8vcm91bmQ6ICdyb3VuZFRocmVlJywgLy8gdW5jb21tZW50IHRoZXNlIHRvIG9ubHkgc2VydmUgc2hvcnQgd29yZHMgYXQgYmVnaW5uaW5nLCBsb25nIHdvcmRzIGF0IGVuZFxuICAgICAgICB9KTtcbiAgICAgIH0gZWxzZSBpZiAobmV3VGltZSA+IDgpIHsgXG4gICAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICAgIHRpbWU6IG5ld1RpbWUsXG4gICAgICAgICAgdGltZUludGVydmFsOiA4MDAsXG4gICAgICAgICAgLy9yb3VuZDogJ3JvdW5kVHdvJyxcbiAgICAgICAgfSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgICB0aW1lOiBuZXdUaW1lLFxuICAgICAgICAgIC8vcm91bmQ6ICdyb3VuZE9uZScsXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIGJsYW5rIHNsYXRlLCB0aGVuIHN0YXJ0IVxuICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgd29yZHM6IFtdLFxuICAgICAgdGltZTogMCxcbiAgICAgIHRpbWVJbnRlcnZhbDogMTAwMCxcbiAgICAgIHVzZXJJbnB1dDogJycsXG4gICAgfSwgKCkgPT4gZ28oKSk7XG4gIFxuICB9XG5cbiAgLy8gcHVsbHMgcmFuZG9tIHdvcmQgZnJvbSBkaWN0aW9uYXJ5IG9iaiBhbmQgYWRkcyBpdCB0byB3b3JkcyBzdGF0ZVxuICBhZGRXb3JkKCkge1xuICAgIHZhciBhdmFpbGFibGVXb3JkcyA9IHRoaXMuc3RhdGUuZGljdGlvbmFyeVt0aGlzLnN0YXRlLnJvdW5kXTtcbiAgICB2YXIgbmV3V29yZCA9IGF2YWlsYWJsZVdvcmRzW01hdGguZmxvb3IoTWF0aC5yYW5kb20oKSAqIGF2YWlsYWJsZVdvcmRzLmxlbmd0aCldO1xuICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgd29yZHM6IFsuLi50aGlzLnN0YXRlLndvcmRzLCBuZXdXb3JkXVxuICAgIH0pO1xuICB9XG5cbiAgLy8gdXBkYXRlcyB5b3VyIHZpZXcgb2Ygb3Bwb25lbnQncyB3b3Jkc1xuICB1cGRhdGVPcHBvbmVudFdvcmRMaXN0KHdvcmRzKSB7XG4gICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICB0aGVpcldvcmRzOiB3b3Jkc1xuICAgIH0pXG4gIH1cblxuICAvLyB1cGRhdGVzIHVzZXJJbnB1dCB3aXRoIHdoYXQgdXNlciBpcyBjdXJyZW50bHkgdHlwaW5nXG4gIGhhbmRsZUNoYW5nZShlKSB7XG4gICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICB1c2VySW5wdXQ6IGUudGFyZ2V0LnZhbHVlLFxuICAgIH0pXG4gIH1cblxuICAvLyB3aGVuIHRoZSB1c2VyIGhpdHMgXCJlbnRlclwiXG4gIGhhbmRsZVN1Ym1pdChlKSB7XG4gICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuICAgIHZhciBzdWJtaXR0ZWRXb3JkID0gdGhpcy5zdGF0ZS51c2VySW5wdXQ7XG4gICAgdmFyIGluZGV4ID0gdGhpcy5zdGF0ZS53b3Jkcy5pbmRleE9mKHN1Ym1pdHRlZFdvcmQpO1xuICAgIFxuICAgIC8vIGNoZWNrIGlmIHdoYXQgdGhleSB0eXBlZCBpcyBpbiBvdXIgXCJ3b3Jkc1wiIGFycmF5XG4gICAgLy8gZmxhc2ggZ3JlZW4gZm9yIGEgY29ycmVjdGx5IHR5cGVkIHdvcmQgYW5kIHJlbW92ZSB3b3JkIGZyb20gXCJ3b3Jkc1wiIGFycmF5XG4gICAgaWYgKGluZGV4ICE9PSAtMSkge1xuICAgICAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3R5cGluZy1pbnB1dCcpLnN0eWxlLmJhY2tncm91bmRDb2xvciA9IFwiZ3JlZW5cIjtcbiAgICAgIHZhciBuZXdXb3JkcyA9IHRoaXMuc3RhdGUud29yZHMuc2xpY2UoKTtcbiAgICAgIG5ld1dvcmRzLnNwbGljZShpbmRleCwgMSk7XG4gICAgICBwbGF5Q29ycmVjdCgpOyBcbiAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICB3b3JkczogbmV3V29yZHMsXG4gICAgICB9KTtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gZWxzZSBmbGFzaCByZWQgZm9yIGEgbWlzdHlwZWQgd29yZFxuICAgICAgcGxheVdyb25nKCk7IFxuICAgICAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3R5cGluZy1pbnB1dCcpLnN0eWxlLmJhY2tncm91bmRDb2xvciA9IFwicmVkXCI7XG4gICAgfVxuXG4gICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgndHlwaW5nLWlucHV0Jykuc3R5bGUuYmFja2dyb3VuZENvbG9yID0gXCJ3aGl0ZVwiO1xuICAgIH0sIDEwMCk7XG5cbiAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgIHVzZXJJbnB1dDogJycsXG4gICAgfSk7XG4gIH1cblxuICAvLyB1cG9uIGdhbWUgb3Zlciwgc2VuZHMgdXNlcm5hbWUgYW5kIHNjb3JlIHRvIGRhdGFiYXNlIHRvIGJlIGFkZGVkL3VwZGF0ZWRcbiAgc2VuZFNjb3JlKHVzZXJuYW1lLCBzY29yZSkge1xuICAgIGF4aW9zLnBvc3QoJy93b3JkZ2FtZScsIHtcbiAgICAgIFwidXNlcm5hbWVcIjogdXNlcm5hbWUsXG4gICAgICBcImhpZ2hfc2NvcmVcIjogc2NvcmVcbiAgICB9KVxuICAgIC50aGVuKHJlc3VsdCA9PiB7XG4gICAgICBjb25zb2xlLmxvZyhyZXN1bHQpO1xuICAgIH0pLmNhdGNoKGVyciA9PiB7XG4gICAgICBjb25zb2xlLmVycm9yKGVycik7XG4gICAgfSlcbiAgfVxuXG4gIHN0b3BHYW1lKCkge1xuICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCd0eXBpbmctaW5wdXQnKS5kaXNhYmxlZCA9IHRydWU7XG4gICAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ292ZXJsYXknKS5zdHlsZS5kaXNwbGF5ID0gXCJibG9ja1wiO1xuICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdndWRldGFtYScpLnN0eWxlLmRpc3BsYXkgPSBcIm5vbmVcIjtcbiAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgndGhlaXItZ3VkZXRhbWEnKS5zdHlsZS5kaXNwbGF5ID0gXCJub25lXCI7XG4gICAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3N0YXJ0ZXItZm9ybScpLmRpc2FibGVkID0gZmFsc2U7XG4gICAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3VzZXItaW5wdXQnKS5kaXNhYmxlZCA9IGZhbHNlO1xuXG4gICAgLy8gZW5hYmxlcyB1c2VyIHRvIGhpdCBcImVudGVyXCIgYWZ0ZXIgMiBzZWNvbmRzIHRvIHJlc3RhcnQgZ2FtZVxuICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgaWYgKGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdvdmVybGF5JykuZGlzcGxheSAhPT0gXCJub25lXCIpIHtcbiAgICAgICAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3VzZXItaW5wdXQnKS5mb2N1cygpO1xuICAgICAgfVxuICAgIH0sIDIwMDApO1xuICAgIFxuICAgIHRoaXMuc2VuZFNjb3JlKHRoaXMucHJvcHMudXNlcm5hbWUsIHRoaXMuc3RhdGUudGltZSk7XG4gXG4gICAgLy8gYXVkaW8gZWZmZWN0XG4gICAgcGxheUdhbWVPdmVyKCk7XG4gICAgXG4gICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAvLyBtYXliZSBmaW5kIGEgd2F5IHRvIGNvbXBhcmUgeW91ciBzY29yZSB2cyBvcHBvbmVudCdzIHNjb3JlIGFuZCBzaG93IFlPVSBXSU4vWU9VIExPU0VcbiAgICAgIGluc3RydWN0aW9uczogWydHQU1FIE9WRVInLCBgWU9VIFNDT1JFRDogJHt0aGlzLnN0YXRlLnRpbWV9YCwgYFlPVVIgT1BQT05FTlQgU0NPUkVEOiAke3RoaXMuc3RhdGUub3Bwb25lbnRUaW1lfWBdLFxuICAgICAgcHJvbXB0OiAnUkVQTEFZJyxcbiAgICB9KTtcbiAgfVxuXG4gIHJlbmRlcigpIHtcbiAgICByZXR1cm4gKFxuICAgICAgPGRpdiBjbGFzc05hbWU9XCJnYW1lXCI+XG4gICAgICAgIDxkaXYgaWQ9XCJvdmVybGF5XCI+XG4gICAgICAgICAgPGRpdj57dGhpcy5zdGF0ZS5pbnN0cnVjdGlvbnMubWFwKChsaW5lLCBpbmRleCkgPT4ge1xuICAgICAgICAgICAgLy8gYXVkaW8gZWZmZWN0OlxuICAgICAgICAgICAgcGxheVN0YXJ0KCk7XG4gICAgICAgICAgICByZXR1cm4gKDxzcGFuIGtleT17aW5kZXh9PntsaW5lfTxicj48L2JyPjwvc3Bhbj4pXG4gICAgICAgICAgfSl9PC9kaXY+XG4gICAgICAgICAgPGRpdiBpZD1cImNyYWNrZWRlZ2dcIj48L2Rpdj5cbiAgICAgICAgICA8ZGl2PlxuICAgICAgICAgICAgey8qIFwiZ2V0UmVhZHlcIiB3YWl0cyBmb3IgMiBwbGF5ZXJzLCBcInN0YXJ0R2FtZVwiIChvbiBjbGljaykgaXMgMSBwbGF5ZXIgKi99XG4gICAgICAgICAgICA8Zm9ybSBpZD1cInN0YXJ0ZXItZm9ybVwiIG9uU3VibWl0PXt0aGlzLmdldFJlYWR5fSBhdXRvQ29tcGxldGU9XCJvZmZcIj5cbiAgICAgICAgICAgICAgPGlucHV0IGlkPVwidXNlci1pbnB1dFwiIHBsYWNlaG9sZGVyPVwiV2hvIGFyZSB5b3U/XCIgdmFsdWU9e3RoaXMucHJvcHMudXNlcm5hbWV9IG9uQ2hhbmdlPXt0aGlzLnByb3BzLmhhbmRsZVVzZXJOYW1lQ2hhbmdlfSBhdXRvRm9jdXMvPlxuICAgICAgICAgICAgPC9mb3JtPlxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIDxkaXYgaWQ9XCJvdmVybGF5LXN0YXJ0XCIgb25DbGljaz17dGhpcy5zdGFydEdhbWV9IGNsYXNzTmFtZT1cImJsaW5raW5nXCI+e3RoaXMuc3RhdGUucHJvbXB0fTwvZGl2PlxuICAgICAgICA8L2Rpdj5cbiAgICBcbiAgICAgICAgPGRpdiBjbGFzc05hbWU9XCJ0aW1lclwiPlxuICAgICAgICAgIDxoMT57dGhpcy5zdGF0ZS50aW1lfTwvaDE+XG4gICAgICAgIDwvZGl2PlxuXG4gICAgICAgIDxkaXYgY2xhc3NOYW1lPVwiYm9hcmRcIj5cbiAgICAgICAgICB7LyogeW91ciBnYW1lOiAqL31cbiAgICAgICAgICA8ZGl2IGNsYXNzTmFtZT1cInBsYXlcIj4gXG4gICAgICAgICAgICB7dGhpcy5zdGF0ZS53b3Jkcy5tYXAoKHdvcmQsIGluZGV4KSA9PiB7XG4gICAgICAgICAgICAgIHJldHVybiA8QnJpY2sgd29yZD17d29yZH0ga2V5PXtpbmRleH0gLz5cbiAgICAgICAgICAgIH0pfVxuICAgICAgICAgICAgPGRpdiBpZD1cImd1ZGV0YW1hXCI+PC9kaXY+XG4gICAgICAgICAgICA8Zm9ybSBvblN1Ym1pdD17dGhpcy5oYW5kbGVTdWJtaXR9IGF1dG9Db21wbGV0ZT1cIm9mZlwiPlxuICAgICAgICAgICAgICA8aW5wdXQgaWQ9XCJ0eXBpbmctaW5wdXRcIiB2YWx1ZT17dGhpcy5zdGF0ZS51c2VySW5wdXR9IG9uQ2hhbmdlPXt0aGlzLmhhbmRsZUNoYW5nZX0gLz5cbiAgICAgICAgICAgIDwvZm9ybT5cbiAgICAgICAgICA8L2Rpdj5cblxuICAgICAgICAgIHsvKiB0aGVpciBnYW1lOiAqL31cbiAgICAgICAgICA8ZGl2IGNsYXNzTmFtZT1cInBsYXlcIiBpZD1cInRoZWlyLWdhbWVcIj4gXG4gICAgICAgICAgICB7dGhpcy5zdGF0ZS50aGVpcldvcmRzLm1hcCgod29yZCwgaW5kZXgpID0+IHtcbiAgICAgICAgICAgICAgcmV0dXJuIDxCcmljayB3b3JkPXt3b3JkfSBrZXk9e2luZGV4fSAvPlxuICAgICAgICAgICAgfSl9XG4gICAgICAgICAgICA8ZGl2IGlkPVwidGhlaXItZ3VkZXRhbWFcIj48L2Rpdj5cbiAgICAgICAgICAgIDxmb3JtIGF1dG9Db21wbGV0ZT1cIm9mZlwiPlxuICAgICAgICAgICAgICA8aW5wdXQgdmFsdWU9XCJPUFBPTkVOVFwiIC8+XG4gICAgICAgICAgICA8L2Zvcm0+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvZGl2PlxuICAgICAgPC9kaXY+XG4gICAgKVxuICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IEdhbWU7Il0sIm1hcHBpbmdzIjoiOzs7Ozs7OztBQUFBO0FBQ0E7OztBQUFBO0FBQ0E7OztBQUFBO0FBQ0E7Ozs7Ozs7Ozs7Ozs7QUFBQTtBQUNBO0FBQ0E7QUFDQTs7O0FBQ0E7QUFBQTtBQUNBO0FBREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFWQTtBQUNBO0FBWUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFEQTtBQUdBO0FBQ0E7QUF2Q0E7QUF3Q0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBREE7QUFBQTtBQUNBO0FBQUE7QUFFQTtBQUNBO0FBREE7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFGQTtBQUlBO0FBQ0E7QUFDQTtBQUNBOzs7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRkE7QUFJQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUZBO0FBSUE7QUFDQTtBQUNBO0FBQ0E7OztBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQURBO0FBR0E7QUFDQTtBQUNBO0FBRkE7QUFJQTs7O0FBRUE7QUFBQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFGQTtBQUlBO0FBQ0E7QUFDQTtBQUZBO0FBQ0E7QUFJQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUhBO0FBS0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBSEE7QUFLQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBSEE7QUFLQTtBQUNBO0FBQ0E7QUFDQTtBQUZBO0FBSUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBSkE7QUFLQTtBQUFBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7OztBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFEQTtBQUdBO0FBQ0E7QUFDQTtBQUNBOzs7QUFBQTtBQUNBO0FBQ0E7QUFEQTtBQUdBO0FBQ0E7QUFDQTtBQUNBOzs7QUFBQTtBQUNBO0FBQ0E7QUFEQTtBQUdBO0FBQ0E7QUFDQTtBQUNBOzs7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBREE7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFEQTtBQUdBO0FBQ0E7QUFDQTtBQUNBOzs7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUZBO0FBS0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBSEE7QUFLQTs7O0FBRUE7QUFDQTtBQUNBO0FBQUE7QUFDQTtBQUFBO0FBQUE7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUpBO0FBS0E7QUFDQTtBQUFBO0FBQUE7QUFFQTtBQUFBO0FBQUE7QUFDQTtBQURBO0FBRkE7QUFNQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBYkE7QUFnQkE7QUFBQTtBQUFBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQURBO0FBSUE7QUFBQTtBQUFBO0FBRUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFDQTtBQURBO0FBTEE7QUFXQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUNBO0FBREE7QUFMQTtBQWJBO0FBckJBO0FBOENBOzs7O0FBblRBO0FBQ0E7QUFxVEE7QSIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///./client/src/components/Game.jsx\n"); +eval("/* WEBPACK VAR INJECTION */(function(process) {\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();\n\nvar _react = __webpack_require__(/*! react */ \"./node_modules/react/index.js\");\n\nvar _react2 = _interopRequireDefault(_react);\n\nvar _Brick = __webpack_require__(/*! ./Brick.jsx */ \"./client/src/components/Brick.jsx\");\n\nvar _Brick2 = _interopRequireDefault(_Brick);\n\nvar _axios = __webpack_require__(/*! axios */ \"./node_modules/axios/index.js\");\n\nvar _axios2 = _interopRequireDefault(_axios);\n\nvar _PowerBank = __webpack_require__(/*! ./PowerBank.jsx */ \"./client/src/components/PowerBank.jsx\");\n\nvar _PowerBank2 = _interopRequireDefault(_PowerBank);\n\nvar _constants = __webpack_require__(/*! constants */ \"./node_modules/constants-browserify/constants.json\");\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nfunction _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\"); } return call && (typeof call === \"object\" || typeof call === \"function\") ? call : self; }\n\nfunction _inherits(subClass, superClass) { if (typeof superClass !== \"function\" && superClass !== null) { throw new TypeError(\"Super expression must either be null or a function, not \" + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }\n\nvar io = __webpack_require__(/*! socket.io-client */ \"./node_modules/socket.io-client/lib/index.js\");\nvar socket = io();\n\nvar Game = function (_React$Component) {\n _inherits(Game, _React$Component);\n\n function Game(props) {\n _classCallCheck(this, Game);\n\n var _this = _possibleConstructorReturn(this, (Game.__proto__ || Object.getPrototypeOf(Game)).call(this, props));\n\n _this.state = {\n userInput: '',\n dictionary: {},\n words: [],\n theirWords: [],\n time: 0,\n timeInterval: 1000,\n round: 'all',\n instructions: [\"Humpty Dumpty sat on a wall,\", \"Humpty Dumpty had a great fall.\", \"All the king's horses and all the king's men\", \"Couldn't put Humpty together again.\", \"HURRY - KEEP TYPING TO PREVENT HIS DEMISE!\"],\n prompt: 'START GAME',\n opponentTime: 0,\n powerups: {},\n bankedPowers: []\n };\n\n _this.getReady = _this.getReady.bind(_this);\n _this.startGame = _this.startGame.bind(_this);\n _this.addWord = _this.addWord.bind(_this);\n _this.updateOpponentWordList = _this.updateOpponentWordList.bind(_this);\n _this.handleChange = _this.handleChange.bind(_this);\n _this.handleSubmit = _this.handleSubmit.bind(_this);\n _this.sendScore = _this.sendScore.bind(_this);\n _this.stopGame = _this.stopGame.bind(_this);\n\n _this.pauseGame = _this.pauseGame.bind(_this);\n _this.removeWords = _this.removeWords.bind(_this);\n _this.shuffleArray = _this.shuffleArray.bind(_this);\n _this.switchWords = _this.switchWords.bind(_this);\n\n _this.removeAllWords = _this.removeAllWords.bind(_this);\n _this.stopAll = _this.stopAll.bind(_this);\n _this.usePower = _this.usePower.bind(_this);\n _this.addPower = _this.addPower.bind(_this);\n var c = io.connect(process.env.PORT, { query: _this.state.time });\n console.log('c', c);\n\n socket.on('receive words from opponent', function (words) {\n _this.updateOpponentWordList(words);\n });\n socket.on('startGame', function () {\n _this.startGame();\n });\n socket.on('they lost', function (score) {\n // this is bad, eventually put a red x over their bricks or something\n _this.setState({\n opponentTime: score\n });\n document.getElementById('their-game').style.backgroundColor = \"red\";\n });\n return _this;\n }\n\n // get words from dictionary and join socket\n\n\n _createClass(Game, [{\n key: 'componentDidMount',\n value: function componentDidMount() {\n var _this2 = this;\n\n _axios2.default.get('/dictionary').then(function (results) {\n _this2.setState({\n dictionary: results.data\n });\n }).catch(function (err) {\n console.error(err);\n });\n socket.emit('entering room', {\n room: this.props.room,\n username: this.props.username\n });\n }\n\n // sends your words to opponent\n\n }, {\n key: 'componentDidUpdate',\n value: function componentDidUpdate(prevProps, prevState) {\n if (this.state.words.length !== prevState.words.length) {\n socket.emit('send words to opponent', {\n room: this.props.room,\n newWords: this.state.words\n });\n }\n }\n\n // leave socket\n\n }, {\n key: 'componentWillUnmount',\n value: function componentWillUnmount() {\n socket.emit('leaving room', {\n room: this.props.room,\n username: this.props.username\n });\n }\n\n // hides starter form and user input, waits for another player to start game\n\n }, {\n key: 'getReady',\n value: function getReady(e) {\n e.preventDefault();\n document.getElementById('starter-form').disabled = true;\n document.getElementById('user-input').disabled = true;\n this.setState({\n prompt: 'WAITING...'\n });\n socket.emit('ready', {\n room: this.props.room,\n username: this.props.username\n });\n }\n }, {\n key: 'startGame',\n value: function startGame() {\n var _this3 = this;\n\n document.getElementById('typing-input').disabled = false;\n document.getElementById('typing-input').focus();\n document.getElementById('overlay').style.display = \"none\";\n document.getElementById('their-game').style.backgroundColor = \"transparent\";\n document.getElementById('gudetama').style = {\n display: \"inline-block\",\n backgroundColor: \"none\"\n };\n document.getElementById('their-gudetama').style = {\n display: \"inline-block\",\n backgroundColor: \"none\"\n };\n\n // long function to define what happens at every interval\n var go = function go() {\n // creates a loop by calling itself:\n var step = setTimeout(function () {\n go();\n }, _this3.state.timeInterval);\n\n // adds a brick:\n _this3.addWord();\n\n // ends game or changes background color of gudetama based on length of \"words\" array\n // (as bricks build up, background turns a darker red to signify danger)\n if (_this3.state.words.length >= 20) {\n clearTimeout(step);\n //console.log('opponent time',this.state.time)\n socket.emit('i lost', {\n room: _this3.props.room,\n username: _this3.props.username,\n score: _this3.state.time\n });\n _this3.stopGame();\n } else if (_this3.state.words.length > 15) {\n document.getElementById('gudetama').style.backgroundColor = \"rgba(255, 0, 0, 1)\";\n } else if (_this3.state.words.length > 10) {\n document.getElementById('gudetama').style.backgroundColor = \"rgba(255, 0, 0, 0.5)\";\n }\n\n // updates the time and speeds up the game accordingly \n // (as timeInterval decreases, words appear at a faster rate)\n var newTime = _this3.state.time + 1;\n if (newTime > 20) {\n _this3.setState({\n time: newTime,\n timeInterval: 600\n //round: 'roundThree', // uncomment these to only serve short words at beginning, long words at end\n });\n } else if (newTime > 8) {\n _this3.setState({\n time: newTime,\n timeInterval: 800\n //round: 'roundTwo',\n });\n } else {\n _this3.setState({\n time: newTime\n //round: 'roundOne',\n });\n }\n };\n\n // blank slate, then start!\n this.setState({\n words: [],\n time: 0,\n timeInterval: 1000,\n userInput: ''\n }, function () {\n return go();\n });\n }\n\n // pulls random word from dictionary obj and adds it to words state\n\n }, {\n key: 'addWord',\n value: function addWord() {\n var availableWords = this.state.dictionary[this.state.round];\n var newWord = availableWords[Math.floor(Math.random() * availableWords.length)];\n this.addPower(newWord);\n this.setState({\n words: [].concat(_toConsumableArray(this.state.words), [newWord])\n });\n }\n\n // updates your view of opponent's words\n\n }, {\n key: 'updateOpponentWordList',\n value: function updateOpponentWordList(words) {\n this.setState({\n theirWords: words\n });\n }\n\n // updates userInput with what user is currently typing\n\n }, {\n key: 'handleChange',\n value: function handleChange(e) {\n this.setState({\n userInput: e.target.value\n });\n }\n\n // when the user hits \"enter\"\n\n }, {\n key: 'handleSubmit',\n value: function handleSubmit(e) {\n e.preventDefault();\n var submittedWord = this.state.userInput;\n var index = this.state.words.indexOf(submittedWord);\n var powerups;\n var deposit;\n // check if what they typed is in our \"words\" array\n // flash green for a correctly typed word and remove word from \"words\" array\n if (index !== -1) {\n\n document.getElementById('typing-input').style.backgroundColor = \"green\";\n var newWords = this.state.words.slice();\n newWords.splice(index, 1);\n playCorrect();\n\n if (this.state.powerups[submittedWord] != undefined) {\n powerups = Object.assign({}, this.state.powerups);\n deposit = powerups[submittedWord];\n delete powerups[submittedWord];\n\n if (this.state.bankedPowers.length != 0) {\n deposit = [].concat(_toConsumableArray(this.state.bankedPowers), [deposit]);\n } else {\n deposit = [deposit];\n }\n\n this.setState({\n words: newWords,\n bankedPowers: deposit,\n powerups: powerups\n });\n } else {\n this.setState({\n words: newWords\n });\n }\n } else {\n // else flash red for a mistyped word\n playWrong();\n document.getElementById('typing-input').style.backgroundColor = \"red\";\n }\n\n setTimeout(function () {\n document.getElementById('typing-input').style.backgroundColor = \"white\";\n }, 100);\n\n this.setState({\n userInput: ''\n });\n }\n\n // upon game over, sends username and score to database to be added/updated\n\n }, {\n key: 'sendScore',\n value: function sendScore(username, score) {\n _axios2.default.post('/wordgame', {\n \"username\": username,\n \"high_score\": score\n }).then(function (result) {\n console.log(result);\n }).catch(function (err) {\n console.error(err);\n });\n }\n }, {\n key: 'stopGame',\n value: function stopGame() {\n document.getElementById('typing-input').disabled = true;\n document.getElementById('overlay').style.display = \"block\";\n document.getElementById('gudetama').style.display = \"none\";\n document.getElementById('their-gudetama').style.display = \"none\";\n document.getElementById('starter-form').disabled = false;\n document.getElementById('user-input').disabled = false;\n\n // enables user to hit \"enter\" after 2 seconds to restart game\n setTimeout(function () {\n if (document.getElementById('overlay').display !== \"none\") {\n document.getElementById('user-input').focus();\n }\n }, 2000);\n\n this.sendScore(this.props.username, this.state.time);\n\n // audio effect\n playGameOver();\n\n this.setState({\n // maybe find a way to compare your score vs opponent's score and show YOU WIN/YOU LOSE\n instructions: ['GAME OVER', 'YOU SCORED: ' + this.state.time, 'YOUR OPPONENT SCORED: ' + this.state.opponentTime],\n prompt: 'REPLAY'\n });\n }\n\n //ADDED FOR POWERUPS\n\n }, {\n key: 'pauseGame',\n value: function pauseGame() {\n var _this4 = this;\n\n var previousInterval = this.state.timeInterval;\n setInterval(function () {\n _this4.setState({\n timeInterval: previousInterval\n });\n }, 5000);\n this.setState({\n timeInterval: 5000\n });\n }\n }, {\n key: 'shuffleArray',\n value: function shuffleArray(arr) {\n var current = arr.length;\n var temp;\n var rand;\n\n while (current !== 0) {\n rand = Math.floor(Math.random() * current);\n current--;\n temp = arr[current];\n arr[current] = arr[rand];\n arr[rand] = temp;\n }\n return arr;\n }\n }, {\n key: 'removeWords',\n value: function removeWords(num) {\n var removeWords = this.state.words.slice();\n var half = Math.floor(removeWords.length / 2);\n removeWords = this.shuffleArray(removeWords);\n removeWords = removeWords.slice(0, half);\n this.setState({\n words: removeWords\n });\n }\n }, {\n key: 'switchWords',\n value: function switchWords() {\n var list = this.state.words.slice();\n list.pop();\n list.push(\"aaa\");\n this.setState({\n words: list\n });\n }\n }, {\n key: 'removeAllWords',\n value: function removeAllWords(num) {\n this.setState({\n words: []\n });\n }\n }, {\n key: 'usePower',\n value: function usePower(e) {\n var temp;\n var banked;\n if (e.keyCode === 32) {\n temp = e.target.value;\n temp = temp.substring(0, temp.length - 1);\n\n if (this.state.bankedPowers[0] != undefined) {\n if (this.state.bankedPowers[0] === 'power0') {\n this.removeAllWords();\n } else if (this.state.bankedPowers[0] === 'power1') {\n this.pauseGame();\n } else if (this.state.bankedPowers[0] === 'power2') {\n this.removeWords();\n }\n banked = this.state.bankedPowers.slice();\n banked.shift();\n }\n this.setState({\n userInput: temp,\n bankedPowers: banked\n });\n }\n }\n }, {\n key: 'addPower',\n value: function addPower(word) {\n var chance = 4;\n var rand = Math.floor(Math.random() * chance) + 1;\n var current;\n if (rand === 1) {\n if (Object.keys(this.state.powerups).length === 0) {\n current = {};\n } else {\n current = this.state.powerups;\n }\n current[word] = \"power\" + Math.floor(Math.random() * 3);\n this.setState({\n powerups: current\n });\n }\n }\n }, {\n key: 'stopAll',\n value: function stopAll() {\n this.setState({\n timeInterval: 100000\n });\n }\n //END OF POWERUPS\n\n }, {\n key: 'render',\n value: function render() {\n var _this5 = this;\n\n return _react2.default.createElement(\n 'div',\n { className: 'game' },\n _react2.default.createElement(\n 'div',\n { id: 'overlay' },\n _react2.default.createElement(\n 'div',\n null,\n this.state.instructions.map(function (line, index) {\n // audio effect:\n playStart();\n return _react2.default.createElement(\n 'span',\n { key: index },\n line,\n _react2.default.createElement('br', null)\n );\n })\n ),\n _react2.default.createElement('div', { id: 'crackedegg' }),\n _react2.default.createElement(\n 'div',\n null,\n _react2.default.createElement(\n 'form',\n { id: 'starter-form', onSubmit: this.getReady, autoComplete: 'off' },\n _react2.default.createElement('input', { id: 'user-input', placeholder: 'Who are you?', value: this.props.username, onChange: this.props.handleUserNameChange, autoFocus: true })\n )\n ),\n _react2.default.createElement(\n 'div',\n { id: 'overlay-start', onClick: this.startGame, className: 'blinking' },\n this.state.prompt\n )\n ),\n _react2.default.createElement(\n 'div',\n { className: 'timer' },\n _react2.default.createElement(\n 'h1',\n null,\n this.state.time\n )\n ),\n _react2.default.createElement(\n 'div',\n { className: 'board' },\n _react2.default.createElement(\n 'div',\n { className: 'play' },\n this.state.words.map(function (word, index) {\n return _react2.default.createElement(_Brick2.default, { word: word, key: index, powerup: _this5.state.powerups[word] ? _this5.state.powerups[word] : \"\" });\n }),\n _react2.default.createElement('div', { id: 'gudetama' }),\n _react2.default.createElement(\n 'form',\n { onSubmit: this.handleSubmit, autoComplete: 'off' },\n _react2.default.createElement('input', { id: 'typing-input', type: 'text', value: this.state.userInput, onChange: this.handleChange, onKeyUp: this.usePower })\n )\n ),\n _react2.default.createElement(\n 'div',\n { id: 'power-bank' },\n _react2.default.createElement(\n 'h5',\n null,\n 'Powers:'\n ),\n this.state.bankedPowers.map(function (powerup, index) {\n return _react2.default.createElement(_PowerBank2.default, { key: index, powerup: powerup });\n }),\n _react2.default.createElement(\n 'div',\n { id: 'legend' },\n _react2.default.createElement(\n 'div',\n { className: 'power1' },\n 'Pause (5s)'\n ),\n _react2.default.createElement(\n 'div',\n { className: 'power2' },\n 'Remove 1/2'\n ),\n _react2.default.createElement(\n 'div',\n { className: 'power0' },\n 'Remove All'\n )\n )\n ),\n _react2.default.createElement(\n 'div',\n { className: 'play', id: 'their-game' },\n this.state.theirWords.map(function (word, index) {\n return _react2.default.createElement(_Brick2.default, { word: word, key: index });\n }),\n _react2.default.createElement('div', { id: 'their-gudetama' }),\n _react2.default.createElement(\n 'form',\n { autoComplete: 'off' },\n _react2.default.createElement('input', { value: 'OPPONENT' })\n )\n )\n )\n );\n }\n }]);\n\n return Game;\n}(_react2.default.Component);\n\nexports.default = Game;\n/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../../../node_modules/process/browser.js */ \"./node_modules/process/browser.js\")))//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9jbGllbnQvc3JjL2NvbXBvbmVudHMvR2FtZS5qc3guanMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vY2xpZW50L3NyYy9jb21wb25lbnRzL0dhbWUuanN4PzE2ZWIiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IFJlYWN0IGZyb20gJ3JlYWN0JztcbmltcG9ydCBCcmljayBmcm9tICcuL0JyaWNrLmpzeCc7XG5pbXBvcnQgYXhpb3MgZnJvbSAnYXhpb3MnO1xuaW1wb3J0IFBvd2VyQmFuayBmcm9tICcuL1Bvd2VyQmFuay5qc3gnO1xuXG5pbXBvcnQgeyBFRVhJU1QgfSBmcm9tICdjb25zdGFudHMnO1xuY29uc3QgaW8gPSByZXF1aXJlKCdzb2NrZXQuaW8tY2xpZW50Jyk7IFxuY29uc3Qgc29ja2V0ID0gaW8oKTtcblxuY2xhc3MgR2FtZSBleHRlbmRzIFJlYWN0LkNvbXBvbmVudCB7XG4gIGNvbnN0cnVjdG9yKHByb3BzKSB7XG4gICAgc3VwZXIocHJvcHMpO1xuICAgIHRoaXMuc3RhdGUgPSB7XG4gICAgICB1c2VySW5wdXQ6ICcnLFxuICAgICAgZGljdGlvbmFyeToge30sXG4gICAgICB3b3JkczogW10sXG4gICAgICB0aGVpcldvcmRzOiBbXSxcbiAgICAgIHRpbWU6IDAsXG4gICAgICB0aW1lSW50ZXJ2YWw6IDEwMDAsXG4gICAgICByb3VuZDogJ2FsbCcsXG4gICAgICBpbnN0cnVjdGlvbnM6IFtcIkh1bXB0eSBEdW1wdHkgc2F0IG9uIGEgd2FsbCxcIiwgXCJIdW1wdHkgRHVtcHR5IGhhZCBhIGdyZWF0IGZhbGwuXCIsIFwiQWxsIHRoZSBraW5nJ3MgaG9yc2VzIGFuZCBhbGwgdGhlIGtpbmcncyBtZW5cIiwgXCJDb3VsZG4ndCBwdXQgSHVtcHR5IHRvZ2V0aGVyIGFnYWluLlwiLCBcIkhVUlJZIC0gS0VFUCBUWVBJTkcgVE8gUFJFVkVOVCBISVMgREVNSVNFIVwiXSxcbiAgICAgIHByb21wdDogJ1NUQVJUIEdBTUUnLFxuICAgICAgb3Bwb25lbnRUaW1lOiAwLFxuICAgICAgcG93ZXJ1cHM6IHt9LFxuICAgICAgYmFua2VkUG93ZXJzOiBbXVxuICAgIH1cbiAgICBcbiAgICB0aGlzLmdldFJlYWR5ID0gdGhpcy5nZXRSZWFkeS5iaW5kKHRoaXMpO1xuICAgIHRoaXMuc3RhcnRHYW1lID0gdGhpcy5zdGFydEdhbWUuYmluZCh0aGlzKTtcbiAgICB0aGlzLmFkZFdvcmQgPSB0aGlzLmFkZFdvcmQuYmluZCh0aGlzKTtcbiAgICB0aGlzLnVwZGF0ZU9wcG9uZW50V29yZExpc3QgPSB0aGlzLnVwZGF0ZU9wcG9uZW50V29yZExpc3QuYmluZCh0aGlzKTtcbiAgICB0aGlzLmhhbmRsZUNoYW5nZSA9IHRoaXMuaGFuZGxlQ2hhbmdlLmJpbmQodGhpcyk7XG4gICAgdGhpcy5oYW5kbGVTdWJtaXQgPSB0aGlzLmhhbmRsZVN1Ym1pdC5iaW5kKHRoaXMpO1xuICAgIHRoaXMuc2VuZFNjb3JlID0gdGhpcy5zZW5kU2NvcmUuYmluZCh0aGlzKTtcbiAgICB0aGlzLnN0b3BHYW1lID0gdGhpcy5zdG9wR2FtZS5iaW5kKHRoaXMpO1xuXG4gICAgdGhpcy5wYXVzZUdhbWUgPSB0aGlzLnBhdXNlR2FtZS5iaW5kKHRoaXMpO1xuICAgIHRoaXMucmVtb3ZlV29yZHMgPSB0aGlzLnJlbW92ZVdvcmRzLmJpbmQodGhpcyk7XG4gICAgdGhpcy5zaHVmZmxlQXJyYXkgPSB0aGlzLnNodWZmbGVBcnJheS5iaW5kKHRoaXMpO1xuICAgIHRoaXMuc3dpdGNoV29yZHMgPSB0aGlzLnN3aXRjaFdvcmRzLmJpbmQodGhpcyk7XG5cbiAgICB0aGlzLnJlbW92ZUFsbFdvcmRzID0gdGhpcy5yZW1vdmVBbGxXb3Jkcy5iaW5kKHRoaXMpO1xuICAgIHRoaXMuc3RvcEFsbCA9IHRoaXMuc3RvcEFsbC5iaW5kKHRoaXMpO1xuICAgIHRoaXMudXNlUG93ZXIgPSB0aGlzLnVzZVBvd2VyLmJpbmQodGhpcyk7XG4gICAgdGhpcy5hZGRQb3dlciA9IHRoaXMuYWRkUG93ZXIuYmluZCh0aGlzKTtcbiAgICB2YXIgYyA9IGlvLmNvbm5lY3QocHJvY2Vzcy5lbnYuUE9SVCwge3F1ZXJ5OiB0aGlzLnN0YXRlLnRpbWV9KVxuICAgIGNvbnNvbGUubG9nKCdjJywgYylcblxuICAgIHNvY2tldC5vbigncmVjZWl2ZSB3b3JkcyBmcm9tIG9wcG9uZW50JywgKHdvcmRzKSA9PiB7XG4gICAgICB0aGlzLnVwZGF0ZU9wcG9uZW50V29yZExpc3Qod29yZHMpO1xuICAgIH0pO1xuICAgIHNvY2tldC5vbignc3RhcnRHYW1lJywgKCkgPT4ge1xuICAgICAgdGhpcy5zdGFydEdhbWUoKTtcbiAgICB9KTtcbiAgICBzb2NrZXQub24oJ3RoZXkgbG9zdCcsIChzY29yZSkgPT4ge1xuICAgICAgLy8gdGhpcyBpcyBiYWQsIGV2ZW50dWFsbHkgcHV0IGEgcmVkIHggb3ZlciB0aGVpciBicmlja3Mgb3Igc29tZXRoaW5nXG4gICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgb3Bwb25lbnRUaW1lOiBzY29yZSxcbiAgICAgIH0pXG4gICAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgndGhlaXItZ2FtZScpLnN0eWxlLmJhY2tncm91bmRDb2xvciA9IFwicmVkXCI7XG4gICAgfSk7XG4gIH1cblxuICAvLyBnZXQgd29yZHMgZnJvbSBkaWN0aW9uYXJ5IGFuZCBqb2luIHNvY2tldFxuICBjb21wb25lbnREaWRNb3VudCgpIHtcbiAgICBheGlvcy5nZXQoJy9kaWN0aW9uYXJ5JylcbiAgICAudGhlbihyZXN1bHRzID0+IHtcbiAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICBkaWN0aW9uYXJ5OiByZXN1bHRzLmRhdGEsXG4gICAgICB9KVxuICAgIH0pLmNhdGNoKGVyciA9PiB7XG4gICAgICBjb25zb2xlLmVycm9yKGVycik7XG4gICAgfSk7XG4gICAgc29ja2V0LmVtaXQoJ2VudGVyaW5nIHJvb20nLCB7XG4gICAgICByb29tOiB0aGlzLnByb3BzLnJvb20sIFxuICAgICAgdXNlcm5hbWU6IHRoaXMucHJvcHMudXNlcm5hbWVcbiAgICB9KTtcbiAgfVxuXG4gIC8vIHNlbmRzIHlvdXIgd29yZHMgdG8gb3Bwb25lbnRcbiAgY29tcG9uZW50RGlkVXBkYXRlKHByZXZQcm9wcywgcHJldlN0YXRlKSB7XG4gICAgaWYgKHRoaXMuc3RhdGUud29yZHMubGVuZ3RoICE9PSBwcmV2U3RhdGUud29yZHMubGVuZ3RoKSB7XG4gICAgICBzb2NrZXQuZW1pdCgnc2VuZCB3b3JkcyB0byBvcHBvbmVudCcsIHtcbiAgICAgICAgcm9vbTogdGhpcy5wcm9wcy5yb29tLFxuICAgICAgICBuZXdXb3JkczogdGhpcy5zdGF0ZS53b3JkcyxcbiAgICAgIH0pOyBcbiAgICB9XG4gIH1cblxuICAvLyBsZWF2ZSBzb2NrZXRcbiAgY29tcG9uZW50V2lsbFVubW91bnQoKSB7ICBcbiAgICBzb2NrZXQuZW1pdCgnbGVhdmluZyByb29tJywge1xuICAgICAgcm9vbTogdGhpcy5wcm9wcy5yb29tLFxuICAgICAgdXNlcm5hbWU6IHRoaXMucHJvcHMudXNlcm5hbWUsXG4gICAgfSk7XG4gIH1cblxuICAvLyBoaWRlcyBzdGFydGVyIGZvcm0gYW5kIHVzZXIgaW5wdXQsIHdhaXRzIGZvciBhbm90aGVyIHBsYXllciB0byBzdGFydCBnYW1lXG4gIGdldFJlYWR5KGUpIHtcbiAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3N0YXJ0ZXItZm9ybScpLmRpc2FibGVkID0gdHJ1ZTtcbiAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgndXNlci1pbnB1dCcpLmRpc2FibGVkID0gdHJ1ZTtcbiAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgIHByb21wdDogJ1dBSVRJTkcuLi4nLFxuICAgIH0pO1xuICAgIHNvY2tldC5lbWl0KCdyZWFkeScsIHtcbiAgICAgIHJvb206IHRoaXMucHJvcHMucm9vbSwgXG4gICAgICB1c2VybmFtZTogdGhpcy5wcm9wcy51c2VybmFtZVxuICAgIH0pO1xuICB9XG5cbiAgc3RhcnRHYW1lKCkge1xuICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCd0eXBpbmctaW5wdXQnKS5kaXNhYmxlZCA9IGZhbHNlO1xuICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCd0eXBpbmctaW5wdXQnKS5mb2N1cygpO1xuICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdvdmVybGF5Jykuc3R5bGUuZGlzcGxheSA9IFwibm9uZVwiO1xuICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCd0aGVpci1nYW1lJykuc3R5bGUuYmFja2dyb3VuZENvbG9yID0gXCJ0cmFuc3BhcmVudFwiO1xuICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdndWRldGFtYScpLnN0eWxlID0ge1xuICAgICAgZGlzcGxheTogXCJpbmxpbmUtYmxvY2tcIixcbiAgICAgIGJhY2tncm91bmRDb2xvcjogXCJub25lXCIsXG4gICAgfTtcbiAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgndGhlaXItZ3VkZXRhbWEnKS5zdHlsZSA9IHtcbiAgICAgIGRpc3BsYXk6IFwiaW5saW5lLWJsb2NrXCIsXG4gICAgICBiYWNrZ3JvdW5kQ29sb3I6IFwibm9uZVwiLFxuICAgIH07XG5cbiAgICAvLyBsb25nIGZ1bmN0aW9uIHRvIGRlZmluZSB3aGF0IGhhcHBlbnMgYXQgZXZlcnkgaW50ZXJ2YWxcbiAgICB2YXIgZ28gPSAoKSA9PiB7XG4gICAgICAvLyBjcmVhdGVzIGEgbG9vcCBieSBjYWxsaW5nIGl0c2VsZjpcbiAgICAgIHZhciBzdGVwID0gc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgIGdvKCk7XG4gICAgICB9LCB0aGlzLnN0YXRlLnRpbWVJbnRlcnZhbCk7XG5cbiAgICAgIC8vIGFkZHMgYSBicmljazpcbiAgICAgIHRoaXMuYWRkV29yZCgpO1xuXG4gICAgICAvLyBlbmRzIGdhbWUgb3IgY2hhbmdlcyBiYWNrZ3JvdW5kIGNvbG9yIG9mIGd1ZGV0YW1hIGJhc2VkIG9uIGxlbmd0aCBvZiBcIndvcmRzXCIgYXJyYXlcbiAgICAgIC8vIChhcyBicmlja3MgYnVpbGQgdXAsIGJhY2tncm91bmQgdHVybnMgYSBkYXJrZXIgcmVkIHRvIHNpZ25pZnkgZGFuZ2VyKVxuICAgICAgaWYgKHRoaXMuc3RhdGUud29yZHMubGVuZ3RoID49IDIwKSB7XG4gICAgICAgIGNsZWFyVGltZW91dChzdGVwKTtcbiAgICAgICAgLy9jb25zb2xlLmxvZygnb3Bwb25lbnQgdGltZScsdGhpcy5zdGF0ZS50aW1lKVxuICAgICAgICBzb2NrZXQuZW1pdCgnaSBsb3N0Jywge1xuICAgICAgICAgIHJvb206IHRoaXMucHJvcHMucm9vbSwgXG4gICAgICAgICAgdXNlcm5hbWU6IHRoaXMucHJvcHMudXNlcm5hbWUsIFxuICAgICAgICAgIHNjb3JlOiB0aGlzLnN0YXRlLnRpbWVcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuc3RvcEdhbWUoKTtcbiAgICAgIH0gZWxzZSBpZiAodGhpcy5zdGF0ZS53b3Jkcy5sZW5ndGggPiAxNSkge1xuICAgICAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnZ3VkZXRhbWEnKS5zdHlsZS5iYWNrZ3JvdW5kQ29sb3IgPSBcInJnYmEoMjU1LCAwLCAwLCAxKVwiO1xuICAgICAgfSBlbHNlIGlmICh0aGlzLnN0YXRlLndvcmRzLmxlbmd0aCA+IDEwKSB7XG4gICAgICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdndWRldGFtYScpLnN0eWxlLmJhY2tncm91bmRDb2xvciA9IFwicmdiYSgyNTUsIDAsIDAsIDAuNSlcIjtcbiAgICAgIH1cblxuICAgICAgLy8gdXBkYXRlcyB0aGUgdGltZSBhbmQgc3BlZWRzIHVwIHRoZSBnYW1lIGFjY29yZGluZ2x5IFxuICAgICAgLy8gKGFzIHRpbWVJbnRlcnZhbCBkZWNyZWFzZXMsIHdvcmRzIGFwcGVhciBhdCBhIGZhc3RlciByYXRlKVxuICAgICAgdmFyIG5ld1RpbWUgPSB0aGlzLnN0YXRlLnRpbWUgKyAxO1xuICAgICAgaWYgKG5ld1RpbWUgPiAyMCkge1xuICAgICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgICB0aW1lOiBuZXdUaW1lLFxuICAgICAgICAgIHRpbWVJbnRlcnZhbDogNjAwLFxuICAgICAgICAgIC8vcm91bmQ6ICdyb3VuZFRocmVlJywgLy8gdW5jb21tZW50IHRoZXNlIHRvIG9ubHkgc2VydmUgc2hvcnQgd29yZHMgYXQgYmVnaW5uaW5nLCBsb25nIHdvcmRzIGF0IGVuZFxuICAgICAgICB9KTtcbiAgICAgIH0gZWxzZSBpZiAobmV3VGltZSA+IDgpIHsgXG4gICAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICAgIHRpbWU6IG5ld1RpbWUsXG4gICAgICAgICAgdGltZUludGVydmFsOiA4MDAsXG4gICAgICAgICAgLy9yb3VuZDogJ3JvdW5kVHdvJyxcbiAgICAgICAgfSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgICB0aW1lOiBuZXdUaW1lLFxuICAgICAgICAgIC8vcm91bmQ6ICdyb3VuZE9uZScsXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIGJsYW5rIHNsYXRlLCB0aGVuIHN0YXJ0IVxuICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgd29yZHM6IFtdLFxuICAgICAgdGltZTogMCxcbiAgICAgIHRpbWVJbnRlcnZhbDogMTAwMCxcbiAgICAgIHVzZXJJbnB1dDogJycsXG4gICAgfSwgKCkgPT4gZ28oKSk7XG4gIFxuICB9XG5cbiAgLy8gcHVsbHMgcmFuZG9tIHdvcmQgZnJvbSBkaWN0aW9uYXJ5IG9iaiBhbmQgYWRkcyBpdCB0byB3b3JkcyBzdGF0ZVxuICBhZGRXb3JkKCkge1xuICAgIHZhciBhdmFpbGFibGVXb3JkcyA9IHRoaXMuc3RhdGUuZGljdGlvbmFyeVt0aGlzLnN0YXRlLnJvdW5kXTtcbiAgICB2YXIgbmV3V29yZCA9IGF2YWlsYWJsZVdvcmRzW01hdGguZmxvb3IoTWF0aC5yYW5kb20oKSAqIGF2YWlsYWJsZVdvcmRzLmxlbmd0aCldO1xuICAgIHRoaXMuYWRkUG93ZXIobmV3V29yZCk7XG4gICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICB3b3JkczogWy4uLnRoaXMuc3RhdGUud29yZHMsIG5ld1dvcmRdXG4gICAgfSk7XG4gIH1cblxuICAvLyB1cGRhdGVzIHlvdXIgdmlldyBvZiBvcHBvbmVudCdzIHdvcmRzXG4gIHVwZGF0ZU9wcG9uZW50V29yZExpc3Qod29yZHMpIHtcbiAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgIHRoZWlyV29yZHM6IHdvcmRzXG4gICAgfSlcbiAgfVxuXG4gIC8vIHVwZGF0ZXMgdXNlcklucHV0IHdpdGggd2hhdCB1c2VyIGlzIGN1cnJlbnRseSB0eXBpbmdcbiAgaGFuZGxlQ2hhbmdlKGUpIHtcbiAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgIHVzZXJJbnB1dDogZS50YXJnZXQudmFsdWUsXG4gICAgfSlcbiAgfVxuXG4gIC8vIHdoZW4gdGhlIHVzZXIgaGl0cyBcImVudGVyXCJcbiAgaGFuZGxlU3VibWl0KGUpIHtcbiAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgdmFyIHN1Ym1pdHRlZFdvcmQgPSB0aGlzLnN0YXRlLnVzZXJJbnB1dDtcbiAgICB2YXIgaW5kZXggPSB0aGlzLnN0YXRlLndvcmRzLmluZGV4T2Yoc3VibWl0dGVkV29yZCk7XG4gICAgdmFyIHBvd2VydXBzO1xuICAgIHZhciBkZXBvc2l0O1xuICAgIC8vIGNoZWNrIGlmIHdoYXQgdGhleSB0eXBlZCBpcyBpbiBvdXIgXCJ3b3Jkc1wiIGFycmF5XG4gICAgLy8gZmxhc2ggZ3JlZW4gZm9yIGEgY29ycmVjdGx5IHR5cGVkIHdvcmQgYW5kIHJlbW92ZSB3b3JkIGZyb20gXCJ3b3Jkc1wiIGFycmF5XG4gICAgaWYgKGluZGV4ICE9PSAtMSkge1xuICAgIFxuICAgICAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3R5cGluZy1pbnB1dCcpLnN0eWxlLmJhY2tncm91bmRDb2xvciA9IFwiZ3JlZW5cIjtcbiAgICAgIHZhciBuZXdXb3JkcyA9IHRoaXMuc3RhdGUud29yZHMuc2xpY2UoKTtcbiAgICAgIG5ld1dvcmRzLnNwbGljZShpbmRleCwgMSk7XG4gICAgICBwbGF5Q29ycmVjdCgpO1xuXG4gICAgICBpZih0aGlzLnN0YXRlLnBvd2VydXBzW3N1Ym1pdHRlZFdvcmRdICE9IHVuZGVmaW5lZCl7XG4gICAgICAgIHBvd2VydXBzID0gT2JqZWN0LmFzc2lnbih7fSwgdGhpcy5zdGF0ZS5wb3dlcnVwcyk7XG4gICAgICAgIGRlcG9zaXQgPSBwb3dlcnVwc1tzdWJtaXR0ZWRXb3JkXTtcbiAgICAgICAgZGVsZXRlIHBvd2VydXBzW3N1Ym1pdHRlZFdvcmRdO1xuICAgIFxuICAgICAgICBpZih0aGlzLnN0YXRlLmJhbmtlZFBvd2Vycy5sZW5ndGggIT0gMCl7XG4gICAgICAgICAgZGVwb3NpdCA9IFsuLi50aGlzLnN0YXRlLmJhbmtlZFBvd2VycywgZGVwb3NpdF1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBkZXBvc2l0ID0gW2RlcG9zaXRdO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgICAgd29yZHM6IG5ld1dvcmRzLFxuICAgICAgICAgIGJhbmtlZFBvd2VyczogZGVwb3NpdCxcbiAgICAgICAgICBwb3dlcnVwczogcG93ZXJ1cHNcbiAgICAgICAgfSk7XG5cbiAgICAgIH0gZWxzZSB7IFxuICAgICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgICB3b3JkczogbmV3V29yZHMsXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICAvLyBlbHNlIGZsYXNoIHJlZCBmb3IgYSBtaXN0eXBlZCB3b3JkXG4gICAgICBwbGF5V3JvbmcoKTsgXG4gICAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgndHlwaW5nLWlucHV0Jykuc3R5bGUuYmFja2dyb3VuZENvbG9yID0gXCJyZWRcIjtcbiAgICB9XG5cbiAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCd0eXBpbmctaW5wdXQnKS5zdHlsZS5iYWNrZ3JvdW5kQ29sb3IgPSBcIndoaXRlXCI7XG4gICAgfSwgMTAwKTtcblxuICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgdXNlcklucHV0OiAnJyxcbiAgICB9KTtcbiAgfVxuXG4gIC8vIHVwb24gZ2FtZSBvdmVyLCBzZW5kcyB1c2VybmFtZSBhbmQgc2NvcmUgdG8gZGF0YWJhc2UgdG8gYmUgYWRkZWQvdXBkYXRlZFxuICBzZW5kU2NvcmUodXNlcm5hbWUsIHNjb3JlKSB7XG4gICAgYXhpb3MucG9zdCgnL3dvcmRnYW1lJywge1xuICAgICAgXCJ1c2VybmFtZVwiOiB1c2VybmFtZSxcbiAgICAgIFwiaGlnaF9zY29yZVwiOiBzY29yZVxuICAgIH0pXG4gICAgLnRoZW4ocmVzdWx0ID0+IHtcbiAgICAgIGNvbnNvbGUubG9nKHJlc3VsdCk7XG4gICAgfSkuY2F0Y2goZXJyID0+IHtcbiAgICAgIGNvbnNvbGUuZXJyb3IoZXJyKTtcbiAgICB9KVxuICB9XG5cbiAgc3RvcEdhbWUoKSB7XG4gICAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3R5cGluZy1pbnB1dCcpLmRpc2FibGVkID0gdHJ1ZTtcbiAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnb3ZlcmxheScpLnN0eWxlLmRpc3BsYXkgPSBcImJsb2NrXCI7XG4gICAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2d1ZGV0YW1hJykuc3R5bGUuZGlzcGxheSA9IFwibm9uZVwiO1xuICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCd0aGVpci1ndWRldGFtYScpLnN0eWxlLmRpc3BsYXkgPSBcIm5vbmVcIjtcbiAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnc3RhcnRlci1mb3JtJykuZGlzYWJsZWQgPSBmYWxzZTtcbiAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgndXNlci1pbnB1dCcpLmRpc2FibGVkID0gZmFsc2U7XG5cbiAgICAvLyBlbmFibGVzIHVzZXIgdG8gaGl0IFwiZW50ZXJcIiBhZnRlciAyIHNlY29uZHMgdG8gcmVzdGFydCBnYW1lXG4gICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICBpZiAoZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ292ZXJsYXknKS5kaXNwbGF5ICE9PSBcIm5vbmVcIikge1xuICAgICAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgndXNlci1pbnB1dCcpLmZvY3VzKCk7XG4gICAgICB9XG4gICAgfSwgMjAwMCk7XG4gICAgXG4gICAgdGhpcy5zZW5kU2NvcmUodGhpcy5wcm9wcy51c2VybmFtZSwgdGhpcy5zdGF0ZS50aW1lKTtcbiBcbiAgICAvLyBhdWRpbyBlZmZlY3RcbiAgICBwbGF5R2FtZU92ZXIoKTtcbiAgICBcbiAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgIC8vIG1heWJlIGZpbmQgYSB3YXkgdG8gY29tcGFyZSB5b3VyIHNjb3JlIHZzIG9wcG9uZW50J3Mgc2NvcmUgYW5kIHNob3cgWU9VIFdJTi9ZT1UgTE9TRVxuICAgICAgaW5zdHJ1Y3Rpb25zOiBbJ0dBTUUgT1ZFUicsIGBZT1UgU0NPUkVEOiAke3RoaXMuc3RhdGUudGltZX1gLCBgWU9VUiBPUFBPTkVOVCBTQ09SRUQ6ICR7dGhpcy5zdGF0ZS5vcHBvbmVudFRpbWV9YF0sXG4gICAgICBwcm9tcHQ6ICdSRVBMQVknLFxuICAgIH0pO1xuICB9XG4gIFxuICAvL0FEREVEIEZPUiBQT1dFUlVQU1xuICBwYXVzZUdhbWUoKXtcbiAgICB2YXIgcHJldmlvdXNJbnRlcnZhbCA9IHRoaXMuc3RhdGUudGltZUludGVydmFsO1xuICAgIHNldEludGVydmFsKCgpPT57XG4gICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgdGltZUludGVydmFsOiBwcmV2aW91c0ludGVydmFsXG4gICAgICB9KTtcbiAgICB9LDUwMDApO1xuICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgdGltZUludGVydmFsOiA1MDAwXG4gICAgfSk7XG4gIH1cblxuICBzaHVmZmxlQXJyYXkoYXJyKXtcbiAgICB2YXIgY3VycmVudCA9IGFyci5sZW5ndGg7XG4gICAgdmFyIHRlbXA7XG4gICAgdmFyIHJhbmQ7XG5cbiAgICB3aGlsZShjdXJyZW50ICE9PSAwKXtcbiAgICAgIHJhbmQgPSBNYXRoLmZsb29yKE1hdGgucmFuZG9tKCkgKiBjdXJyZW50KTtcbiAgICAgIGN1cnJlbnQtLTtcbiAgICAgIHRlbXAgPSBhcnJbY3VycmVudF07XG4gICAgICBhcnJbY3VycmVudF0gPSBhcnJbcmFuZF07XG4gICAgICBhcnJbcmFuZF0gPSB0ZW1wO1xuICAgIH0gIFxuICAgIHJldHVybiBhcnI7XG4gIH1cblxuICByZW1vdmVXb3JkcyhudW0pe1xuICAgIHZhciByZW1vdmVXb3JkcyA9IHRoaXMuc3RhdGUud29yZHMuc2xpY2UoKTtcbiAgICB2YXIgaGFsZiA9IE1hdGguZmxvb3IocmVtb3ZlV29yZHMubGVuZ3RoLzIpO1xuICAgIHJlbW92ZVdvcmRzID0gdGhpcy5zaHVmZmxlQXJyYXkocmVtb3ZlV29yZHMpO1xuICAgIHJlbW92ZVdvcmRzID0gcmVtb3ZlV29yZHMuc2xpY2UoMCwgaGFsZik7XG4gICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICB3b3JkczogcmVtb3ZlV29yZHNcbiAgICB9KTtcbiAgfVxuXG4gIHN3aXRjaFdvcmRzKCl7XG4gICAgdmFyIGxpc3QgPSB0aGlzLnN0YXRlLndvcmRzLnNsaWNlKCk7XG4gICAgbGlzdC5wb3AoKTtcbiAgICBsaXN0LnB1c2goXCJhYWFcIik7XG4gICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICB3b3JkczogbGlzdFxuICAgIH0pO1xuICB9XG4gIHJlbW92ZUFsbFdvcmRzKG51bSl7XG4gICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICB3b3JkczogW11cbiAgICB9KTtcbiAgfVxuICB1c2VQb3dlcihlKXtcbiAgICB2YXIgdGVtcDtcbiAgICB2YXIgYmFua2VkO1xuICAgIGlmKGUua2V5Q29kZSA9PT0gMzIpe1xuICAgICAgdGVtcCA9IGUudGFyZ2V0LnZhbHVlO1xuICAgICAgdGVtcCA9IHRlbXAuc3Vic3RyaW5nKDAsIHRlbXAubGVuZ3RoLTEpO1xuICAgICBcbiAgICAgIGlmKHRoaXMuc3RhdGUuYmFua2VkUG93ZXJzWzBdICE9IHVuZGVmaW5lZCl7XG4gICAgICAgIGlmKHRoaXMuc3RhdGUuYmFua2VkUG93ZXJzWzBdID09PSAncG93ZXIwJyl7XG4gICAgICAgICAgdGhpcy5yZW1vdmVBbGxXb3JkcygpO1xuICAgICAgICB9IGVsc2UgaWYodGhpcy5zdGF0ZS5iYW5rZWRQb3dlcnNbMF0gPT09ICdwb3dlcjEnKXtcbiAgICAgICAgICB0aGlzLnBhdXNlR2FtZSgpO1xuICAgICAgICB9IGVsc2UgaWYodGhpcy5zdGF0ZS5iYW5rZWRQb3dlcnNbMF0gPT09ICdwb3dlcjInKXtcbiAgICAgICAgICB0aGlzLnJlbW92ZVdvcmRzKCk7XG4gICAgICAgIH1cbiAgICAgICAgYmFua2VkID0gdGhpcy5zdGF0ZS5iYW5rZWRQb3dlcnMuc2xpY2UoKTtcbiAgICAgICAgYmFua2VkLnNoaWZ0KCk7IFxuICAgICAgfVxuICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgIHVzZXJJbnB1dDogdGVtcCxcbiAgICAgICAgYmFua2VkUG93ZXJzOiBiYW5rZWRcbiAgICAgIH0pXG4gICAgfVxuICB9XG5cbiAgYWRkUG93ZXIod29yZCl7XG4gICAgdmFyIGNoYW5jZSA9IDQ7XG4gICAgdmFyIHJhbmQgPSBNYXRoLmZsb29yKE1hdGgucmFuZG9tKCkgKiBjaGFuY2UpICsgMTtcbiAgICB2YXIgY3VycmVudDtcbiAgICBpZihyYW5kID09PSAxKXtcbiAgICAgIGlmKE9iamVjdC5rZXlzKHRoaXMuc3RhdGUucG93ZXJ1cHMpLmxlbmd0aCA9PT0gMCl7XG4gICAgICAgIGN1cnJlbnQgPSB7fTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGN1cnJlbnQgPSB0aGlzLnN0YXRlLnBvd2VydXBzO1xuICAgICAgfVxuICAgICAgY3VycmVudFt3b3JkXSA9IFwicG93ZXJcIiArIE1hdGguZmxvb3IoTWF0aC5yYW5kb20oKSAqIDMpO1xuICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgIHBvd2VydXBzOiBjdXJyZW50XG4gICAgICB9KVxuICAgIH1cbiAgfVxuXG4gIHN0b3BBbGwoKXtcbiAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgIHRpbWVJbnRlcnZhbDogMTAwMDAwXG4gICAgfSk7XG4gIH1cbiAgLy9FTkQgT0YgUE9XRVJVUFNcblxuICByZW5kZXIoKSB7XG4gICAgcmV0dXJuIChcbiAgICAgIDxkaXYgY2xhc3NOYW1lPVwiZ2FtZVwiPlxuICAgICAgICA8ZGl2IGlkPVwib3ZlcmxheVwiPlxuICAgICAgICAgIDxkaXY+e3RoaXMuc3RhdGUuaW5zdHJ1Y3Rpb25zLm1hcCgobGluZSwgaW5kZXgpID0+IHtcbiAgICAgICAgICAgIC8vIGF1ZGlvIGVmZmVjdDpcbiAgICAgICAgICAgIHBsYXlTdGFydCgpO1xuICAgICAgICAgICAgcmV0dXJuICg8c3BhbiBrZXk9e2luZGV4fT57bGluZX08YnI+PC9icj48L3NwYW4+KVxuICAgICAgICAgIH0pfTwvZGl2PlxuICAgICAgICAgIDxkaXYgaWQ9XCJjcmFja2VkZWdnXCI+PC9kaXY+XG4gICAgICAgICAgPGRpdj5cbiAgICAgICAgICAgIHsvKiBcImdldFJlYWR5XCIgd2FpdHMgZm9yIDIgcGxheWVycywgXCJzdGFydEdhbWVcIiAob24gY2xpY2spIGlzIDEgcGxheWVyICovfVxuICAgICAgICAgICAgPGZvcm0gaWQ9XCJzdGFydGVyLWZvcm1cIiBvblN1Ym1pdD17dGhpcy5nZXRSZWFkeX0gYXV0b0NvbXBsZXRlPVwib2ZmXCI+XG4gICAgICAgICAgICAgIDxpbnB1dCBpZD1cInVzZXItaW5wdXRcIiBwbGFjZWhvbGRlcj1cIldobyBhcmUgeW91P1wiIHZhbHVlPXt0aGlzLnByb3BzLnVzZXJuYW1lfSBvbkNoYW5nZT17dGhpcy5wcm9wcy5oYW5kbGVVc2VyTmFtZUNoYW5nZX0gYXV0b0ZvY3VzLz5cbiAgICAgICAgICAgIDwvZm9ybT5cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8ZGl2IGlkPVwib3ZlcmxheS1zdGFydFwiIG9uQ2xpY2s9e3RoaXMuc3RhcnRHYW1lfSBjbGFzc05hbWU9XCJibGlua2luZ1wiPnt0aGlzLnN0YXRlLnByb21wdH08L2Rpdj5cbiAgICAgICAgPC9kaXY+XG4gICAgXG4gICAgICAgIDxkaXYgY2xhc3NOYW1lPVwidGltZXJcIj5cbiAgICAgICAgICA8aDE+e3RoaXMuc3RhdGUudGltZX08L2gxPlxuICAgICAgICAgIHsvKjxidXR0b24gaWQ9J2J1dHRvbi1zdG9wYWxsJyBvbkNsaWNrPXt0aGlzLnN0b3BBbGx9PlNUT1BBTEw8L2J1dHRvbj5cbiAgICAgICAgICA8YnV0dG9uIGlkPSdidXR0b24tcGF1c2UnIG9uQ2xpY2s9e3RoaXMucGF1c2VHYW1lfT5QQVVTRTwvYnV0dG9uPlxuICAgICAgICAgIDxidXR0b24gaWQ9J2J1dHRvbi1yZW1vdmVXb3Jkcycgb25DbGljaz17KCk9PnRoaXMucmVtb3ZlV29yZHMoMyl9PlJFTU9WRTwvYnV0dG9uPlxuICAgICAgICA8YnV0dG9uIGlkPSdidXR0b24tc3dpdGNoV29yZHMnIG9uQ2xpY2s9e3RoaXMuc3dpdGNoV29yZHN9PlNXSVRDSDwvYnV0dG9uPiovfVxuICAgICAgICA8L2Rpdj5cblxuICAgICAgICA8ZGl2IGNsYXNzTmFtZT1cImJvYXJkXCI+XG4gICAgICAgICAgey8qIHlvdXIgZ2FtZTogKi99XG4gICAgICAgICAgPGRpdiBjbGFzc05hbWU9XCJwbGF5XCI+IFxuICAgICAgICAgICAge3RoaXMuc3RhdGUud29yZHMubWFwKCh3b3JkLCBpbmRleCkgPT4ge1xuICAgICAgICAgICAgICByZXR1cm4gPEJyaWNrIHdvcmQ9e3dvcmR9IGtleT17aW5kZXh9IHBvd2VydXA9e3RoaXMuc3RhdGUucG93ZXJ1cHNbd29yZF0gPyB0aGlzLnN0YXRlLnBvd2VydXBzW3dvcmRdIDogXCJcIn0vPlxuICAgICAgICAgICAgfSl9XG4gICAgICAgICAgICA8ZGl2IGlkPVwiZ3VkZXRhbWFcIj48L2Rpdj5cbiAgICAgICAgICAgIDxmb3JtIG9uU3VibWl0PXt0aGlzLmhhbmRsZVN1Ym1pdH0gYXV0b0NvbXBsZXRlPVwib2ZmXCI+XG4gICAgICAgICAgICAgIDxpbnB1dCBpZD1cInR5cGluZy1pbnB1dFwiIHR5cGU9J3RleHQnIHZhbHVlPXt0aGlzLnN0YXRlLnVzZXJJbnB1dH0gb25DaGFuZ2U9e3RoaXMuaGFuZGxlQ2hhbmdlfSBvbktleVVwPXt0aGlzLnVzZVBvd2VyfS8+XG4gICAgICAgICAgICA8L2Zvcm0+XG4gICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICA8ZGl2IGlkPVwicG93ZXItYmFua1wiPlxuICAgICAgICAgICAgPGg1PlBvd2Vyczo8L2g1PlxuICAgICAgICAgICAge3RoaXMuc3RhdGUuYmFua2VkUG93ZXJzLm1hcCgocG93ZXJ1cCwgaW5kZXgpPT57XG4gICAgICAgICAgICAgIHJldHVybiA8UG93ZXJCYW5rIGtleT17aW5kZXh9IHBvd2VydXA9e3Bvd2VydXB9IC8+XG4gICAgICAgICAgICB9KX1cbiAgICAgICAgICAgIDxkaXYgaWQ9J2xlZ2VuZCc+XG4gICAgICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPSdwb3dlcjEnPlBhdXNlICg1cyk8L2Rpdj5cbiAgICAgICAgICAgICAgPGRpdiBjbGFzc05hbWU9J3Bvd2VyMic+UmVtb3ZlIDEvMjwvZGl2PlxuICAgICAgICAgICAgICA8ZGl2IGNsYXNzTmFtZT0ncG93ZXIwJz5SZW1vdmUgQWxsPC9kaXY+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgXG5cbiAgICAgICAgICB7LyogdGhlaXIgZ2FtZTogKi99XG4gICAgICAgICAgPGRpdiBjbGFzc05hbWU9XCJwbGF5XCIgaWQ9XCJ0aGVpci1nYW1lXCI+IFxuICAgICAgICAgICAge3RoaXMuc3RhdGUudGhlaXJXb3Jkcy5tYXAoKHdvcmQsIGluZGV4KSA9PiB7XG4gICAgICAgICAgICAgIHJldHVybiA8QnJpY2sgd29yZD17d29yZH0ga2V5PXtpbmRleH0gLz5cbiAgICAgICAgICAgIH0pfVxuICAgICAgICAgICAgPGRpdiBpZD1cInRoZWlyLWd1ZGV0YW1hXCI+PC9kaXY+XG4gICAgICAgICAgICA8Zm9ybSBhdXRvQ29tcGxldGU9XCJvZmZcIj5cbiAgICAgICAgICAgICAgPGlucHV0IHZhbHVlPVwiT1BQT05FTlRcIiAvPlxuICAgICAgICAgICAgPC9mb3JtPlxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L2Rpdj5cbiAgICAgIDwvZGl2PlxuICAgIClcbiAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBHYW1lOyJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7QUFBQTtBQUNBOzs7QUFBQTtBQUNBOzs7QUFBQTtBQUNBOzs7QUFBQTtBQUNBOzs7QUFDQTtBQUNBOzs7Ozs7Ozs7OztBQUFBO0FBQ0E7QUFDQTtBQUNBOzs7QUFDQTtBQUFBO0FBQ0E7QUFEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFaQTtBQUNBO0FBY0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFEQTtBQUdBO0FBQ0E7QUFsREE7QUFtREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBREE7QUFBQTtBQUNBO0FBQUE7QUFFQTtBQUNBO0FBREE7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFGQTtBQUlBO0FBQ0E7QUFDQTtBQUNBOzs7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRkE7QUFJQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUZBO0FBSUE7QUFDQTtBQUNBO0FBQ0E7OztBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQURBO0FBR0E7QUFDQTtBQUNBO0FBRkE7QUFJQTs7O0FBRUE7QUFBQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFGQTtBQUlBO0FBQ0E7QUFDQTtBQUZBO0FBQ0E7QUFJQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUhBO0FBS0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBSEE7QUFLQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBSEE7QUFLQTtBQUNBO0FBQ0E7QUFDQTtBQUZBO0FBSUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBSkE7QUFLQTtBQUFBO0FBRUE7QUFDQTtBQUNBO0FBQ0E7OztBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQURBO0FBR0E7QUFDQTtBQUNBO0FBQ0E7OztBQUFBO0FBQ0E7QUFDQTtBQURBO0FBR0E7QUFDQTtBQUNBO0FBQ0E7OztBQUFBO0FBQ0E7QUFDQTtBQURBO0FBR0E7QUFDQTtBQUNBO0FBQ0E7OztBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUhBO0FBTUE7QUFDQTtBQUNBO0FBREE7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQURBO0FBR0E7QUFDQTtBQUNBO0FBQ0E7OztBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBRkE7QUFLQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFIQTtBQUtBO0FBQ0E7QUFDQTtBQUNBOzs7QUFBQTtBQUFBO0FBQ0E7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQURBO0FBR0E7QUFDQTtBQUNBO0FBREE7QUFHQTs7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFEQTtBQUdBOzs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFEQTtBQUdBOzs7QUFDQTtBQUNBO0FBQ0E7QUFEQTtBQUdBOzs7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFGQTtBQUlBO0FBQ0E7OztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBREE7QUFHQTtBQUNBOzs7QUFFQTtBQUNBO0FBQ0E7QUFEQTtBQUdBO0FBQ0E7QUFDQTs7O0FBQ0E7QUFBQTtBQUNBO0FBQUE7QUFDQTtBQUFBO0FBQ0E7QUFBQTtBQUFBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFKQTtBQUtBO0FBQ0E7QUFBQTtBQUFBO0FBRUE7QUFBQTtBQUFBO0FBQ0E7QUFEQTtBQUZBO0FBTUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQWJBO0FBZ0JBO0FBQUE7QUFBQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFEQTtBQVFBO0FBQUE7QUFBQTtBQUVBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQ0E7QUFEQTtBQUxBO0FBVUE7QUFBQTtBQUFBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUhBO0FBTEE7QUFjQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUNBO0FBREE7QUFMQTtBQTFCQTtBQXpCQTtBQStEQTs7OztBQTFjQTtBQUNBO0FBNGNBO0EiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///./client/src/components/Game.jsx\n"); + +/***/ }), + +/***/ "./client/src/components/PowerBank.jsx": +/*!*********************************************!*\ + !*** ./client/src/components/PowerBank.jsx ***! + \*********************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; +eval("\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nvar _react = __webpack_require__(/*! react */ \"./node_modules/react/index.js\");\n\nvar _react2 = _interopRequireDefault(_react);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nvar PowerBank = function PowerBank(props) {\n return _react2.default.createElement('div', { className: 'powerup ' + props.powerup });\n};\n\nexports.default = PowerBank;//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9jbGllbnQvc3JjL2NvbXBvbmVudHMvUG93ZXJCYW5rLmpzeC5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy9jbGllbnQvc3JjL2NvbXBvbmVudHMvUG93ZXJCYW5rLmpzeD8yMDIwIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBSZWFjdCBmcm9tICdyZWFjdCc7XG5cbmNvbnN0IFBvd2VyQmFuayA9IChwcm9wcykgPT4ge1xuICAgIHJldHVybiAoXG4gICAgICAgIDxkaXYgY2xhc3NOYW1lPXtgcG93ZXJ1cCAke3Byb3BzLnBvd2VydXB9YH0+PC9kaXY+XG4gICAgKVxufVxuXG5leHBvcnQgZGVmYXVsdCBQb3dlckJhbms7XG4iXSwibWFwcGluZ3MiOiI7Ozs7OztBQUFBO0FBQ0E7Ozs7O0FBQ0E7QUFDQTtBQUdBO0FBQ0E7QUFDQSIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///./client/src/components/PowerBank.jsx\n"); /***/ }), @@ -545,6 +557,17 @@ eval("\nmodule.exports = function(a, b){\n var fn = function(){};\n fn.prototy /***/ }), +/***/ "./node_modules/constants-browserify/constants.json": +/*!**********************************************************!*\ + !*** ./node_modules/constants-browserify/constants.json ***! + \**********************************************************/ +/*! exports provided: O_RDONLY, O_WRONLY, O_RDWR, S_IFMT, S_IFREG, S_IFDIR, S_IFCHR, S_IFBLK, S_IFIFO, S_IFLNK, S_IFSOCK, O_CREAT, O_EXCL, O_NOCTTY, O_TRUNC, O_APPEND, O_DIRECTORY, O_NOFOLLOW, O_SYNC, O_SYMLINK, O_NONBLOCK, S_IRWXU, S_IRUSR, S_IWUSR, S_IXUSR, S_IRWXG, S_IRGRP, S_IWGRP, S_IXGRP, S_IRWXO, S_IROTH, S_IWOTH, S_IXOTH, E2BIG, EACCES, EADDRINUSE, EADDRNOTAVAIL, EAFNOSUPPORT, EAGAIN, EALREADY, EBADF, EBADMSG, EBUSY, ECANCELED, ECHILD, ECONNABORTED, ECONNREFUSED, ECONNRESET, EDEADLK, EDESTADDRREQ, EDOM, EDQUOT, EEXIST, EFAULT, EFBIG, EHOSTUNREACH, EIDRM, EILSEQ, EINPROGRESS, EINTR, EINVAL, EIO, EISCONN, EISDIR, ELOOP, EMFILE, EMLINK, EMSGSIZE, EMULTIHOP, ENAMETOOLONG, ENETDOWN, ENETRESET, ENETUNREACH, ENFILE, ENOBUFS, ENODATA, ENODEV, ENOENT, ENOEXEC, ENOLCK, ENOLINK, ENOMEM, ENOMSG, ENOPROTOOPT, ENOSPC, ENOSR, ENOSTR, ENOSYS, ENOTCONN, ENOTDIR, ENOTEMPTY, ENOTSOCK, ENOTSUP, ENOTTY, ENXIO, EOPNOTSUPP, EOVERFLOW, EPERM, EPIPE, EPROTO, EPROTONOSUPPORT, EPROTOTYPE, ERANGE, EROFS, ESPIPE, ESRCH, ESTALE, ETIME, ETIMEDOUT, ETXTBSY, EWOULDBLOCK, EXDEV, SIGHUP, SIGINT, SIGQUIT, SIGILL, SIGTRAP, SIGABRT, SIGIOT, SIGBUS, SIGFPE, SIGKILL, SIGUSR1, SIGSEGV, SIGUSR2, SIGPIPE, SIGALRM, SIGTERM, SIGCHLD, SIGCONT, SIGSTOP, SIGTSTP, SIGTTIN, SIGTTOU, SIGURG, SIGXCPU, SIGXFSZ, SIGVTALRM, SIGPROF, SIGWINCH, SIGIO, SIGSYS, SSL_OP_ALL, SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION, SSL_OP_CIPHER_SERVER_PREFERENCE, SSL_OP_CISCO_ANYCONNECT, SSL_OP_COOKIE_EXCHANGE, SSL_OP_CRYPTOPRO_TLSEXT_BUG, SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS, SSL_OP_EPHEMERAL_RSA, SSL_OP_LEGACY_SERVER_CONNECT, SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER, SSL_OP_MICROSOFT_SESS_ID_BUG, SSL_OP_MSIE_SSLV2_RSA_PADDING, SSL_OP_NETSCAPE_CA_DN_BUG, SSL_OP_NETSCAPE_CHALLENGE_BUG, SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG, SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG, SSL_OP_NO_COMPRESSION, SSL_OP_NO_QUERY_MTU, SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION, SSL_OP_NO_SSLv2, SSL_OP_NO_SSLv3, SSL_OP_NO_TICKET, SSL_OP_NO_TLSv1, SSL_OP_NO_TLSv1_1, SSL_OP_NO_TLSv1_2, SSL_OP_PKCS1_CHECK_1, SSL_OP_PKCS1_CHECK_2, SSL_OP_SINGLE_DH_USE, SSL_OP_SINGLE_ECDH_USE, SSL_OP_SSLEAY_080_CLIENT_DH_BUG, SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG, SSL_OP_TLS_BLOCK_PADDING_BUG, SSL_OP_TLS_D5_BUG, SSL_OP_TLS_ROLLBACK_BUG, ENGINE_METHOD_DSA, ENGINE_METHOD_DH, ENGINE_METHOD_RAND, ENGINE_METHOD_ECDH, ENGINE_METHOD_ECDSA, ENGINE_METHOD_CIPHERS, ENGINE_METHOD_DIGESTS, ENGINE_METHOD_STORE, ENGINE_METHOD_PKEY_METHS, ENGINE_METHOD_PKEY_ASN1_METHS, ENGINE_METHOD_ALL, ENGINE_METHOD_NONE, DH_CHECK_P_NOT_SAFE_PRIME, DH_CHECK_P_NOT_PRIME, DH_UNABLE_TO_CHECK_GENERATOR, DH_NOT_SUITABLE_GENERATOR, NPN_ENABLED, RSA_PKCS1_PADDING, RSA_SSLV23_PADDING, RSA_NO_PADDING, RSA_PKCS1_OAEP_PADDING, RSA_X931_PADDING, RSA_PKCS1_PSS_PADDING, POINT_CONVERSION_COMPRESSED, POINT_CONVERSION_UNCOMPRESSED, POINT_CONVERSION_HYBRID, F_OK, R_OK, W_OK, X_OK, UV_UDP_REUSEADDR, default */ +/***/ (function(module) { + +eval("module.exports = {\"O_RDONLY\":0,\"O_WRONLY\":1,\"O_RDWR\":2,\"S_IFMT\":61440,\"S_IFREG\":32768,\"S_IFDIR\":16384,\"S_IFCHR\":8192,\"S_IFBLK\":24576,\"S_IFIFO\":4096,\"S_IFLNK\":40960,\"S_IFSOCK\":49152,\"O_CREAT\":512,\"O_EXCL\":2048,\"O_NOCTTY\":131072,\"O_TRUNC\":1024,\"O_APPEND\":8,\"O_DIRECTORY\":1048576,\"O_NOFOLLOW\":256,\"O_SYNC\":128,\"O_SYMLINK\":2097152,\"O_NONBLOCK\":4,\"S_IRWXU\":448,\"S_IRUSR\":256,\"S_IWUSR\":128,\"S_IXUSR\":64,\"S_IRWXG\":56,\"S_IRGRP\":32,\"S_IWGRP\":16,\"S_IXGRP\":8,\"S_IRWXO\":7,\"S_IROTH\":4,\"S_IWOTH\":2,\"S_IXOTH\":1,\"E2BIG\":7,\"EACCES\":13,\"EADDRINUSE\":48,\"EADDRNOTAVAIL\":49,\"EAFNOSUPPORT\":47,\"EAGAIN\":35,\"EALREADY\":37,\"EBADF\":9,\"EBADMSG\":94,\"EBUSY\":16,\"ECANCELED\":89,\"ECHILD\":10,\"ECONNABORTED\":53,\"ECONNREFUSED\":61,\"ECONNRESET\":54,\"EDEADLK\":11,\"EDESTADDRREQ\":39,\"EDOM\":33,\"EDQUOT\":69,\"EEXIST\":17,\"EFAULT\":14,\"EFBIG\":27,\"EHOSTUNREACH\":65,\"EIDRM\":90,\"EILSEQ\":92,\"EINPROGRESS\":36,\"EINTR\":4,\"EINVAL\":22,\"EIO\":5,\"EISCONN\":56,\"EISDIR\":21,\"ELOOP\":62,\"EMFILE\":24,\"EMLINK\":31,\"EMSGSIZE\":40,\"EMULTIHOP\":95,\"ENAMETOOLONG\":63,\"ENETDOWN\":50,\"ENETRESET\":52,\"ENETUNREACH\":51,\"ENFILE\":23,\"ENOBUFS\":55,\"ENODATA\":96,\"ENODEV\":19,\"ENOENT\":2,\"ENOEXEC\":8,\"ENOLCK\":77,\"ENOLINK\":97,\"ENOMEM\":12,\"ENOMSG\":91,\"ENOPROTOOPT\":42,\"ENOSPC\":28,\"ENOSR\":98,\"ENOSTR\":99,\"ENOSYS\":78,\"ENOTCONN\":57,\"ENOTDIR\":20,\"ENOTEMPTY\":66,\"ENOTSOCK\":38,\"ENOTSUP\":45,\"ENOTTY\":25,\"ENXIO\":6,\"EOPNOTSUPP\":102,\"EOVERFLOW\":84,\"EPERM\":1,\"EPIPE\":32,\"EPROTO\":100,\"EPROTONOSUPPORT\":43,\"EPROTOTYPE\":41,\"ERANGE\":34,\"EROFS\":30,\"ESPIPE\":29,\"ESRCH\":3,\"ESTALE\":70,\"ETIME\":101,\"ETIMEDOUT\":60,\"ETXTBSY\":26,\"EWOULDBLOCK\":35,\"EXDEV\":18,\"SIGHUP\":1,\"SIGINT\":2,\"SIGQUIT\":3,\"SIGILL\":4,\"SIGTRAP\":5,\"SIGABRT\":6,\"SIGIOT\":6,\"SIGBUS\":10,\"SIGFPE\":8,\"SIGKILL\":9,\"SIGUSR1\":30,\"SIGSEGV\":11,\"SIGUSR2\":31,\"SIGPIPE\":13,\"SIGALRM\":14,\"SIGTERM\":15,\"SIGCHLD\":20,\"SIGCONT\":19,\"SIGSTOP\":17,\"SIGTSTP\":18,\"SIGTTIN\":21,\"SIGTTOU\":22,\"SIGURG\":16,\"SIGXCPU\":24,\"SIGXFSZ\":25,\"SIGVTALRM\":26,\"SIGPROF\":27,\"SIGWINCH\":28,\"SIGIO\":23,\"SIGSYS\":12,\"SSL_OP_ALL\":2147486719,\"SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION\":262144,\"SSL_OP_CIPHER_SERVER_PREFERENCE\":4194304,\"SSL_OP_CISCO_ANYCONNECT\":32768,\"SSL_OP_COOKIE_EXCHANGE\":8192,\"SSL_OP_CRYPTOPRO_TLSEXT_BUG\":2147483648,\"SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS\":2048,\"SSL_OP_EPHEMERAL_RSA\":0,\"SSL_OP_LEGACY_SERVER_CONNECT\":4,\"SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER\":32,\"SSL_OP_MICROSOFT_SESS_ID_BUG\":1,\"SSL_OP_MSIE_SSLV2_RSA_PADDING\":0,\"SSL_OP_NETSCAPE_CA_DN_BUG\":536870912,\"SSL_OP_NETSCAPE_CHALLENGE_BUG\":2,\"SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG\":1073741824,\"SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG\":8,\"SSL_OP_NO_COMPRESSION\":131072,\"SSL_OP_NO_QUERY_MTU\":4096,\"SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION\":65536,\"SSL_OP_NO_SSLv2\":16777216,\"SSL_OP_NO_SSLv3\":33554432,\"SSL_OP_NO_TICKET\":16384,\"SSL_OP_NO_TLSv1\":67108864,\"SSL_OP_NO_TLSv1_1\":268435456,\"SSL_OP_NO_TLSv1_2\":134217728,\"SSL_OP_PKCS1_CHECK_1\":0,\"SSL_OP_PKCS1_CHECK_2\":0,\"SSL_OP_SINGLE_DH_USE\":1048576,\"SSL_OP_SINGLE_ECDH_USE\":524288,\"SSL_OP_SSLEAY_080_CLIENT_DH_BUG\":128,\"SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG\":0,\"SSL_OP_TLS_BLOCK_PADDING_BUG\":512,\"SSL_OP_TLS_D5_BUG\":256,\"SSL_OP_TLS_ROLLBACK_BUG\":8388608,\"ENGINE_METHOD_DSA\":2,\"ENGINE_METHOD_DH\":4,\"ENGINE_METHOD_RAND\":8,\"ENGINE_METHOD_ECDH\":16,\"ENGINE_METHOD_ECDSA\":32,\"ENGINE_METHOD_CIPHERS\":64,\"ENGINE_METHOD_DIGESTS\":128,\"ENGINE_METHOD_STORE\":256,\"ENGINE_METHOD_PKEY_METHS\":512,\"ENGINE_METHOD_PKEY_ASN1_METHS\":1024,\"ENGINE_METHOD_ALL\":65535,\"ENGINE_METHOD_NONE\":0,\"DH_CHECK_P_NOT_SAFE_PRIME\":2,\"DH_CHECK_P_NOT_PRIME\":1,\"DH_UNABLE_TO_CHECK_GENERATOR\":4,\"DH_NOT_SUITABLE_GENERATOR\":8,\"NPN_ENABLED\":1,\"RSA_PKCS1_PADDING\":1,\"RSA_SSLV23_PADDING\":2,\"RSA_NO_PADDING\":3,\"RSA_PKCS1_OAEP_PADDING\":4,\"RSA_X931_PADDING\":5,\"RSA_PKCS1_PSS_PADDING\":6,\"POINT_CONVERSION_COMPRESSED\":2,\"POINT_CONVERSION_UNCOMPRESSED\":4,\"POINT_CONVERSION_HYBRID\":6,\"F_OK\":0,\"R_OK\":4,\"W_OK\":2,\"X_OK\":1,\"UV_UDP_REUSEADDR\":4};//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvY29uc3RhbnRzLWJyb3dzZXJpZnkvY29uc3RhbnRzLmpzb24uanMiLCJzb3VyY2VzIjpbXSwibWFwcGluZ3MiOiIiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///./node_modules/constants-browserify/constants.json\n"); + +/***/ }), + /***/ "./node_modules/debug/src/browser.js": /*!*******************************************!*\ !*** ./node_modules/debug/src/browser.js ***! @@ -1223,7 +1246,7 @@ eval("\n\nvar alphabet = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqr /*! no static exports found */ /***/ (function(module, exports) { -eval("/* (ignored) *///# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMC5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy93cyAoaWdub3JlZCk/NTMwNSJdLCJzb3VyY2VzQ29udGVudCI6WyIvKiAoaWdub3JlZCkgKi8iXSwibWFwcGluZ3MiOiJBQUFBIiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///0\n"); +eval("/* (ignored) *///# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMC5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy93cyAoaWdub3JlZCk/Y2JjOSJdLCJzb3VyY2VzQ29udGVudCI6WyIvKiAoaWdub3JlZCkgKi8iXSwibWFwcGluZ3MiOiJBQUFBIiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///0\n"); /***/ }) diff --git a/client/dist/style.css b/client/dist/style.css index f9f6a20..9dea6fa 100644 --- a/client/dist/style.css +++ b/client/dist/style.css @@ -180,3 +180,58 @@ input { .sbHeader{ margin-left: 70px } + +.power0 { + color: green; +} + +.power1 { + color: red; +} + +.power2 { + color: blue; +} + +.powerup { + display: inline-block; + width: 15px; + height: 15px; + border: 1px solid black; + margin: 2px; +} + +#power-bank { + width: 125px; +} +#power-bank .power0{ + background-color: green; +} + +#power-bank .power1 { + background-color: red; +} + +#power-bank .power2 { + background-color: blue; +} + +#power-bank #legend .power0{ + background-color: green; + +} +#power-bank #legend .power1 { + background-color: red; + +} +#power-bank #legend .power2 { + background-color: blue; + +} + +#power-bank #legend div{ + width: 120px; + padding: 1px; + color: white; + font-size: 9px; +} \ No newline at end of file diff --git a/client/src/components/Brick.jsx b/client/src/components/Brick.jsx index ed35854..6ca2404 100644 --- a/client/src/components/Brick.jsx +++ b/client/src/components/Brick.jsx @@ -2,7 +2,7 @@ import React from 'react'; const Brick = (props) => { return ( -
+

{props.word}

) diff --git a/client/src/components/Game.jsx b/client/src/components/Game.jsx index 2982790..c775887 100644 --- a/client/src/components/Game.jsx +++ b/client/src/components/Game.jsx @@ -1,6 +1,9 @@ import React from 'react'; import Brick from './Brick.jsx'; import axios from 'axios'; +import PowerBank from './PowerBank.jsx'; + +import { EEXIST } from 'constants'; const io = require('socket.io-client'); const socket = io(); @@ -17,7 +20,9 @@ class Game extends React.Component { round: 'all', instructions: ["Humpty Dumpty sat on a wall,", "Humpty Dumpty had a great fall.", "All the king's horses and all the king's men", "Couldn't put Humpty together again.", "HURRY - KEEP TYPING TO PREVENT HIS DEMISE!"], prompt: 'START GAME', - opponentTime: 0 + opponentTime: 0, + powerups: {}, + bankedPowers: [] } this.getReady = this.getReady.bind(this); @@ -29,6 +34,15 @@ class Game extends React.Component { this.sendScore = this.sendScore.bind(this); this.stopGame = this.stopGame.bind(this); + this.pauseGame = this.pauseGame.bind(this); + this.removeWords = this.removeWords.bind(this); + this.shuffleArray = this.shuffleArray.bind(this); + this.switchWords = this.switchWords.bind(this); + + this.removeAllWords = this.removeAllWords.bind(this); + this.stopAll = this.stopAll.bind(this); + this.usePower = this.usePower.bind(this); + this.addPower = this.addPower.bind(this); var c = io.connect(process.env.PORT, {query: this.state.time}) console.log('c', c) @@ -173,6 +187,7 @@ class Game extends React.Component { addWord() { var availableWords = this.state.dictionary[this.state.round]; var newWord = availableWords[Math.floor(Math.random() * availableWords.length)]; + this.addPower(newWord); this.setState({ words: [...this.state.words, newWord] }); @@ -197,17 +212,39 @@ class Game extends React.Component { e.preventDefault(); var submittedWord = this.state.userInput; var index = this.state.words.indexOf(submittedWord); - + var powerups; + var deposit; // check if what they typed is in our "words" array // flash green for a correctly typed word and remove word from "words" array if (index !== -1) { + document.getElementById('typing-input').style.backgroundColor = "green"; var newWords = this.state.words.slice(); newWords.splice(index, 1); - playCorrect(); - this.setState({ - words: newWords, - }); + playCorrect(); + + if(this.state.powerups[submittedWord] != undefined){ + powerups = Object.assign({}, this.state.powerups); + deposit = powerups[submittedWord]; + delete powerups[submittedWord]; + + if(this.state.bankedPowers.length != 0){ + deposit = [...this.state.bankedPowers, deposit] + } else { + deposit = [deposit]; + } + + this.setState({ + words: newWords, + bankedPowers: deposit, + powerups: powerups + }); + + } else { + this.setState({ + words: newWords, + }); + } } else { // else flash red for a mistyped word playWrong(); @@ -262,6 +299,106 @@ class Game extends React.Component { prompt: 'REPLAY', }); } + + //ADDED FOR POWERUPS + pauseGame(){ + var previousInterval = this.state.timeInterval; + setInterval(()=>{ + this.setState({ + timeInterval: previousInterval + }); + },5000); + this.setState({ + timeInterval: 5000 + }); + } + + shuffleArray(arr){ + var current = arr.length; + var temp; + var rand; + + while(current !== 0){ + rand = Math.floor(Math.random() * current); + current--; + temp = arr[current]; + arr[current] = arr[rand]; + arr[rand] = temp; + } + return arr; + } + + removeWords(num){ + var removeWords = this.state.words.slice(); + var half = Math.floor(removeWords.length/2); + removeWords = this.shuffleArray(removeWords); + removeWords = removeWords.slice(0, half); + this.setState({ + words: removeWords + }); + } + + switchWords(){ + var list = this.state.words.slice(); + list.pop(); + list.push("aaa"); + this.setState({ + words: list + }); + } + removeAllWords(num){ + this.setState({ + words: [] + }); + } + usePower(e){ + var temp; + var banked; + if(e.keyCode === 32){ + temp = e.target.value; + temp = temp.substring(0, temp.length-1); + + if(this.state.bankedPowers[0] != undefined){ + if(this.state.bankedPowers[0] === 'power0'){ + this.removeAllWords(); + } else if(this.state.bankedPowers[0] === 'power1'){ + this.pauseGame(); + } else if(this.state.bankedPowers[0] === 'power2'){ + this.removeWords(); + } + banked = this.state.bankedPowers.slice(); + banked.shift(); + } + this.setState({ + userInput: temp, + bankedPowers: banked + }) + } + } + + addPower(word){ + var chance = 4; + var rand = Math.floor(Math.random() * chance) + 1; + var current; + if(rand === 1){ + if(Object.keys(this.state.powerups).length === 0){ + current = {}; + } else { + current = this.state.powerups; + } + current[word] = "power" + Math.floor(Math.random() * 3); + this.setState({ + powerups: current + }) + } + } + + stopAll(){ + this.setState({ + timeInterval: 100000 + }); + } + //END OF POWERUPS render() { return ( @@ -284,20 +421,37 @@ class Game extends React.Component {

{this.state.time}

+ {/* + + + */}
{/* your game: */}
{this.state.words.map((word, index) => { - return + return })}
- +
+
+
Powers:
+ {this.state.bankedPowers.map((powerup, index)=>{ + return + })} +
+
Pause (5s)
+
Remove 1/2
+
Remove All
+
+
+ + {/* their game: */}
{this.state.theirWords.map((word, index) => { diff --git a/client/src/components/PowerBank.jsx b/client/src/components/PowerBank.jsx new file mode 100644 index 0000000..175472a --- /dev/null +++ b/client/src/components/PowerBank.jsx @@ -0,0 +1,9 @@ +import React from 'react'; + +const PowerBank = (props) => { + return ( +
+ ) +} + +export default PowerBank;