├── .github └── workflows │ └── linters.yml ├── .gitignore ├── README.md ├── dist ├── index.html └── main.js ├── package-lock.json ├── package.json ├── src ├── images │ └── Screenshot1.png ├── index.html ├── index.js ├── style.css └── utils │ └── structure.js └── webpack.config.js /.github/workflows/linters.yml: -------------------------------------------------------------------------------- 1 | name: Linters 2 | 3 | on: pull_request 4 | 5 | env: 6 | FORCE_COLOR: 1 7 | 8 | jobs: 9 | lighthouse: 10 | name: Lighthouse 11 | runs-on: ubuntu-18.04 12 | steps: 13 | - uses: actions/checkout@v2 14 | - uses: actions/setup-node@v1 15 | with: 16 | node-version: "12.x" 17 | - name: Setup Lighthouse 18 | run: npm install -g @lhci/cli@0.7.x 19 | - name: Lighthouse Report 20 | run: lhci autorun --upload.target=temporary-public-storage --collect.staticDistDir=. 21 | webhint: 22 | name: Webhint 23 | runs-on: ubuntu-18.04 24 | steps: 25 | - uses: actions/checkout@v2 26 | - uses: actions/setup-node@v1 27 | with: 28 | node-version: "12.x" 29 | - name: Setup Webhint 30 | run: | 31 | npm install --save-dev hint@6.x 32 | [ -f .hintrc ] || wget https://raw.githubusercontent.com/microverseinc/linters-config/master/html-css-js/.hintrc 33 | - name: Webhint Report 34 | run: npx hint . 35 | stylelint: 36 | name: Stylelint 37 | runs-on: ubuntu-18.04 38 | steps: 39 | - uses: actions/checkout@v2 40 | - uses: actions/setup-node@v1 41 | with: 42 | node-version: "12.x" 43 | - name: Setup Stylelint 44 | run: | 45 | npm install --save-dev stylelint@13.x stylelint-scss@3.x stylelint-config-standard@21.x stylelint-csstree-validator@1.x 46 | [ -f .stylelintrc.json ] || wget https://raw.githubusercontent.com/microverseinc/linters-config/master/html-css-js/.stylelintrc.json 47 | - name: Stylelint Report 48 | run: npx stylelint "**/*.{css,scss}" 49 | eslint: 50 | name: ESLint 51 | runs-on: ubuntu-18.04 52 | steps: 53 | - uses: actions/checkout@v2 54 | - uses: actions/setup-node@v1 55 | with: 56 | node-version: "12.x" 57 | - name: Setup ESLint 58 | run: | 59 | npm install --save-dev eslint@7.x eslint-config-airbnb-base@14.x eslint-plugin-import@2.x babel-eslint@10.x 60 | [ -f .eslintrc.json ] || wget https://raw.githubusercontent.com/microverseinc/linters-config/master/html-css-js/.eslintrc.json 61 | - name: ESLint Report 62 | run: npx eslint . 63 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # .gitignore 2 | node_modules/ -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![](https://img.shields.io/badge/thecodechaser-blueviolet) 2 | 3 | # To Do List 4 | 5 | > To Do List project is list of todo items, users can add and remove item from todo list. 6 | 7 | ## Screenshots: 8 | 9 | ![screenshot](./src/images/Screenshot1.png) 10 | 11 | Porject's features are added into seperate branch to keep main branch safe. 12 | 13 | ## Built With 14 | 15 | - HTML 16 | - CSS 17 | - JavaScript 18 | - Webpack 19 | 20 | ## Online live link 21 | 22 | [Visit project online](https://thecodechaser.github.io/todo-list/dist/) 23 | 24 | ## Getting Started 25 | 26 | To get a local copy up and running follow these simple example steps. 27 | 28 | ### Using it Locally 29 | - Clone the project from GitHub [here](git@github.com:thecodechaser/todo-list.git) 30 | - Run the following commands as listed in your terminal: 31 | - `npm install` 32 | - `npm run build` 33 | - `npm start` 34 | 35 | ## Visit And Open Files 36 | 37 | [Visit Repo](https://github.com/thecodechaser/todo-list) 38 | 39 | ## Download Repo 40 | 41 | [Download Repo](https://github.com/thecodechaser/todo-list/archive/refs/heads/main.zip) 42 | 43 | ## Authors 44 | 45 | 👤 **Ranjeet Singh** 46 | 47 | - GitHub: [@githubhandle](https://github.com/thecodechaser) 48 | - Twitter: [@twitterhandle](https://twitter.com/thecodechaser) 49 | - LinkedIn: [LinkedIn](https://linkedin.com/in/thecodechaser) 50 | 51 | ## 🤝 Contributing 52 | 53 | Contributions, issues, and feature requests are welcome! 54 | 55 | Feel free to check the [issues page](https://github.com/thecodechaser/todo-list/issues). 56 | 57 | ## Show your support 58 | 59 | Give a ⭐️ if you like this project! 60 | 61 | ## Acknowledgments 62 | 63 | - Inspiration: Microverse 64 | 65 | ## 📝 License 66 | 67 | This project is [MIT](./MIT.md) licensed. 68 | -------------------------------------------------------------------------------- /dist/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 13 | To Do List 14 | 15 | 16 |
17 |
18 |

Today's To Do

19 | 20 |
21 |
22 |
23 | 24 | 25 |
26 |
27 |
28 |
29 |
30 | 31 | 32 | -------------------------------------------------------------------------------- /dist/main.js: -------------------------------------------------------------------------------- 1 | /******/ (() => { // webpackBootstrap 2 | /******/ "use strict"; 3 | /******/ var __webpack_modules__ = ({ 4 | 5 | /***/ "./node_modules/css-loader/dist/cjs.js!./src/style.css": 6 | /*!*************************************************************!*\ 7 | !*** ./node_modules/css-loader/dist/cjs.js!./src/style.css ***! 8 | \*************************************************************/ 9 | /***/ ((module, __webpack_exports__, __webpack_require__) => { 10 | 11 | __webpack_require__.r(__webpack_exports__); 12 | /* harmony export */ __webpack_require__.d(__webpack_exports__, { 13 | /* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__) 14 | /* harmony export */ }); 15 | /* harmony import */ var _node_modules_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../node_modules/css-loader/dist/runtime/sourceMaps.js */ "./node_modules/css-loader/dist/runtime/sourceMaps.js"); 16 | /* harmony import */ var _node_modules_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0__); 17 | /* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../node_modules/css-loader/dist/runtime/api.js */ "./node_modules/css-loader/dist/runtime/api.js"); 18 | /* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__); 19 | // Imports 20 | 21 | 22 | var ___CSS_LOADER_EXPORT___ = _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default()((_node_modules_css_loader_dist_runtime_sourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default())); 23 | ___CSS_LOADER_EXPORT___.push([module.id, "@import url(https://fonts.googleapis.com/css2?family=Poppins&display=swap);"]); 24 | // Module 25 | ___CSS_LOADER_EXPORT___.push([module.id, "/* stylesheet */\r\n\r\nbody {\r\n font-family: \"Poppins\", sans-serif;\r\n}\r\n\r\n.main-container {\r\n border: 3px solid #dfe1e6;\r\n margin: 30px 20px 0 20px;\r\n box-shadow: 5px 5px #dfe1e6;\r\n}\r\n\r\n.list-head {\r\n display: flex;\r\n justify-content: space-between;\r\n margin: 0 10px;\r\n}\r\n\r\nhr {\r\n height: 1px;\r\n background-color: #dfe1e6;\r\n border: none;\r\n margin: 0;\r\n}\r\n\r\nform {\r\n display: flex;\r\n}\r\n\r\n.fa-level-down-alt {\r\n font-size: 20px;\r\n color: rgba(5, 5, 5, 0.507);\r\n}\r\n\r\n.form-input {\r\n font-style: italic;\r\n padding: 10px;\r\n border: none;\r\n width: 90%;\r\n outline: none;\r\n}\r\n\r\n.main-heading {\r\n font-weight: 100;\r\n font-size: 18px;\r\n color: rgba(0, 0, 0, 0.877);\r\n}\r\n\r\n.fa-sync-alt {\r\n margin-top: 17px;\r\n margin-right: 10px;\r\n color: rgba(5, 5, 5, 0.507);\r\n}\r\n\r\nul {\r\n padding: 0;\r\n gap: 10px;\r\n display: flex;\r\n flex-direction: column;\r\n list-style-type: none;\r\n}\r\n\r\n.list-item {\r\n display: flex;\r\n gap: 10px;\r\n padding-left: 0;\r\n}\r\n\r\n.list-input {\r\n margin-top: 5px;\r\n transform: scale(1.3);\r\n}\r\n\r\n.item-details {\r\n margin-top: 0;\r\n width: 300px;\r\n border: none;\r\n resize: none;\r\n outline: none;\r\n}\r\n\r\n.fa-trash-alt {\r\n display: none;\r\n margin-left: 150px;\r\n color: rgba(73, 73, 73, 0.726);\r\n}\r\n\r\n.fa-square {\r\n font-size: 18px;\r\n margin-top: 18px;\r\n color: rgb(73, 73, 73);\r\n}\r\n\r\n.clear {\r\n text-align: center;\r\n font-size: 18px;\r\n color: rgb(87, 80, 80);\r\n background-color: #80808048;\r\n margin-bottom: 0;\r\n padding: 20px 0;\r\n}\r\n\r\n@media screen and (min-width: 772px) {\r\n .main-container {\r\n margin: 30px 30vw 0 30vw;\r\n }\r\n}\r\n", "",{"version":3,"sources":["webpack://./src/style.css"],"names":[],"mappings":"AAAA,eAAe;;AAGf;EACE,kCAAkC;AACpC;;AAEA;EACE,yBAAyB;EACzB,wBAAwB;EACxB,2BAA2B;AAC7B;;AAEA;EACE,aAAa;EACb,8BAA8B;EAC9B,cAAc;AAChB;;AAEA;EACE,WAAW;EACX,yBAAyB;EACzB,YAAY;EACZ,SAAS;AACX;;AAEA;EACE,aAAa;AACf;;AAEA;EACE,eAAe;EACf,2BAA2B;AAC7B;;AAEA;EACE,kBAAkB;EAClB,aAAa;EACb,YAAY;EACZ,UAAU;EACV,aAAa;AACf;;AAEA;EACE,gBAAgB;EAChB,eAAe;EACf,2BAA2B;AAC7B;;AAEA;EACE,gBAAgB;EAChB,kBAAkB;EAClB,2BAA2B;AAC7B;;AAEA;EACE,UAAU;EACV,SAAS;EACT,aAAa;EACb,sBAAsB;EACtB,qBAAqB;AACvB;;AAEA;EACE,aAAa;EACb,SAAS;EACT,eAAe;AACjB;;AAEA;EACE,eAAe;EACf,qBAAqB;AACvB;;AAEA;EACE,aAAa;EACb,YAAY;EACZ,YAAY;EACZ,YAAY;EACZ,aAAa;AACf;;AAEA;EACE,aAAa;EACb,kBAAkB;EAClB,8BAA8B;AAChC;;AAEA;EACE,eAAe;EACf,gBAAgB;EAChB,sBAAsB;AACxB;;AAEA;EACE,kBAAkB;EAClB,eAAe;EACf,sBAAsB;EACtB,2BAA2B;EAC3B,gBAAgB;EAChB,eAAe;AACjB;;AAEA;EACE;IACE,wBAAwB;EAC1B;AACF","sourcesContent":["/* stylesheet */\r\n@import url(\"https://fonts.googleapis.com/css2?family=Poppins&display=swap\");\r\n\r\nbody {\r\n font-family: \"Poppins\", sans-serif;\r\n}\r\n\r\n.main-container {\r\n border: 3px solid #dfe1e6;\r\n margin: 30px 20px 0 20px;\r\n box-shadow: 5px 5px #dfe1e6;\r\n}\r\n\r\n.list-head {\r\n display: flex;\r\n justify-content: space-between;\r\n margin: 0 10px;\r\n}\r\n\r\nhr {\r\n height: 1px;\r\n background-color: #dfe1e6;\r\n border: none;\r\n margin: 0;\r\n}\r\n\r\nform {\r\n display: flex;\r\n}\r\n\r\n.fa-level-down-alt {\r\n font-size: 20px;\r\n color: rgba(5, 5, 5, 0.507);\r\n}\r\n\r\n.form-input {\r\n font-style: italic;\r\n padding: 10px;\r\n border: none;\r\n width: 90%;\r\n outline: none;\r\n}\r\n\r\n.main-heading {\r\n font-weight: 100;\r\n font-size: 18px;\r\n color: rgba(0, 0, 0, 0.877);\r\n}\r\n\r\n.fa-sync-alt {\r\n margin-top: 17px;\r\n margin-right: 10px;\r\n color: rgba(5, 5, 5, 0.507);\r\n}\r\n\r\nul {\r\n padding: 0;\r\n gap: 10px;\r\n display: flex;\r\n flex-direction: column;\r\n list-style-type: none;\r\n}\r\n\r\n.list-item {\r\n display: flex;\r\n gap: 10px;\r\n padding-left: 0;\r\n}\r\n\r\n.list-input {\r\n margin-top: 5px;\r\n transform: scale(1.3);\r\n}\r\n\r\n.item-details {\r\n margin-top: 0;\r\n width: 300px;\r\n border: none;\r\n resize: none;\r\n outline: none;\r\n}\r\n\r\n.fa-trash-alt {\r\n display: none;\r\n margin-left: 150px;\r\n color: rgba(73, 73, 73, 0.726);\r\n}\r\n\r\n.fa-square {\r\n font-size: 18px;\r\n margin-top: 18px;\r\n color: rgb(73, 73, 73);\r\n}\r\n\r\n.clear {\r\n text-align: center;\r\n font-size: 18px;\r\n color: rgb(87, 80, 80);\r\n background-color: #80808048;\r\n margin-bottom: 0;\r\n padding: 20px 0;\r\n}\r\n\r\n@media screen and (min-width: 772px) {\r\n .main-container {\r\n margin: 30px 30vw 0 30vw;\r\n }\r\n}\r\n"],"sourceRoot":""}]); 26 | // Exports 27 | /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (___CSS_LOADER_EXPORT___); 28 | 29 | 30 | /***/ }), 31 | 32 | /***/ "./node_modules/css-loader/dist/runtime/api.js": 33 | /*!*****************************************************!*\ 34 | !*** ./node_modules/css-loader/dist/runtime/api.js ***! 35 | \*****************************************************/ 36 | /***/ ((module) => { 37 | 38 | 39 | 40 | /* 41 | MIT License http://www.opensource.org/licenses/mit-license.php 42 | Author Tobias Koppers @sokra 43 | */ 44 | module.exports = function (cssWithMappingToString) { 45 | var list = []; // return the list of modules as css string 46 | 47 | list.toString = function toString() { 48 | return this.map(function (item) { 49 | var content = ""; 50 | var needLayer = typeof item[5] !== "undefined"; 51 | 52 | if (item[4]) { 53 | content += "@supports (".concat(item[4], ") {"); 54 | } 55 | 56 | if (item[2]) { 57 | content += "@media ".concat(item[2], " {"); 58 | } 59 | 60 | if (needLayer) { 61 | content += "@layer".concat(item[5].length > 0 ? " ".concat(item[5]) : "", " {"); 62 | } 63 | 64 | content += cssWithMappingToString(item); 65 | 66 | if (needLayer) { 67 | content += "}"; 68 | } 69 | 70 | if (item[2]) { 71 | content += "}"; 72 | } 73 | 74 | if (item[4]) { 75 | content += "}"; 76 | } 77 | 78 | return content; 79 | }).join(""); 80 | }; // import a list of modules into the list 81 | 82 | 83 | list.i = function i(modules, media, dedupe, supports, layer) { 84 | if (typeof modules === "string") { 85 | modules = [[null, modules, undefined]]; 86 | } 87 | 88 | var alreadyImportedModules = {}; 89 | 90 | if (dedupe) { 91 | for (var k = 0; k < this.length; k++) { 92 | var id = this[k][0]; 93 | 94 | if (id != null) { 95 | alreadyImportedModules[id] = true; 96 | } 97 | } 98 | } 99 | 100 | for (var _k = 0; _k < modules.length; _k++) { 101 | var item = [].concat(modules[_k]); 102 | 103 | if (dedupe && alreadyImportedModules[item[0]]) { 104 | continue; 105 | } 106 | 107 | if (typeof layer !== "undefined") { 108 | if (typeof item[5] === "undefined") { 109 | item[5] = layer; 110 | } else { 111 | item[1] = "@layer".concat(item[5].length > 0 ? " ".concat(item[5]) : "", " {").concat(item[1], "}"); 112 | item[5] = layer; 113 | } 114 | } 115 | 116 | if (media) { 117 | if (!item[2]) { 118 | item[2] = media; 119 | } else { 120 | item[1] = "@media ".concat(item[2], " {").concat(item[1], "}"); 121 | item[2] = media; 122 | } 123 | } 124 | 125 | if (supports) { 126 | if (!item[4]) { 127 | item[4] = "".concat(supports); 128 | } else { 129 | item[1] = "@supports (".concat(item[4], ") {").concat(item[1], "}"); 130 | item[4] = supports; 131 | } 132 | } 133 | 134 | list.push(item); 135 | } 136 | }; 137 | 138 | return list; 139 | }; 140 | 141 | /***/ }), 142 | 143 | /***/ "./node_modules/css-loader/dist/runtime/sourceMaps.js": 144 | /*!************************************************************!*\ 145 | !*** ./node_modules/css-loader/dist/runtime/sourceMaps.js ***! 146 | \************************************************************/ 147 | /***/ ((module) => { 148 | 149 | 150 | 151 | module.exports = function (item) { 152 | var content = item[1]; 153 | var cssMapping = item[3]; 154 | 155 | if (!cssMapping) { 156 | return content; 157 | } 158 | 159 | if (typeof btoa === "function") { 160 | var base64 = btoa(unescape(encodeURIComponent(JSON.stringify(cssMapping)))); 161 | var data = "sourceMappingURL=data:application/json;charset=utf-8;base64,".concat(base64); 162 | var sourceMapping = "/*# ".concat(data, " */"); 163 | var sourceURLs = cssMapping.sources.map(function (source) { 164 | return "/*# sourceURL=".concat(cssMapping.sourceRoot || "").concat(source, " */"); 165 | }); 166 | return [content].concat(sourceURLs).concat([sourceMapping]).join("\n"); 167 | } 168 | 169 | return [content].join("\n"); 170 | }; 171 | 172 | /***/ }), 173 | 174 | /***/ "./src/style.css": 175 | /*!***********************!*\ 176 | !*** ./src/style.css ***! 177 | \***********************/ 178 | /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { 179 | 180 | __webpack_require__.r(__webpack_exports__); 181 | /* harmony export */ __webpack_require__.d(__webpack_exports__, { 182 | /* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__) 183 | /* harmony export */ }); 184 | /* harmony import */ var _node_modules_style_loader_dist_runtime_injectStylesIntoStyleTag_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! !../node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js */ "./node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js"); 185 | /* harmony import */ var _node_modules_style_loader_dist_runtime_injectStylesIntoStyleTag_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_node_modules_style_loader_dist_runtime_injectStylesIntoStyleTag_js__WEBPACK_IMPORTED_MODULE_0__); 186 | /* harmony import */ var _node_modules_style_loader_dist_runtime_styleDomAPI_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! !../node_modules/style-loader/dist/runtime/styleDomAPI.js */ "./node_modules/style-loader/dist/runtime/styleDomAPI.js"); 187 | /* harmony import */ var _node_modules_style_loader_dist_runtime_styleDomAPI_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_node_modules_style_loader_dist_runtime_styleDomAPI_js__WEBPACK_IMPORTED_MODULE_1__); 188 | /* harmony import */ var _node_modules_style_loader_dist_runtime_insertBySelector_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! !../node_modules/style-loader/dist/runtime/insertBySelector.js */ "./node_modules/style-loader/dist/runtime/insertBySelector.js"); 189 | /* harmony import */ var _node_modules_style_loader_dist_runtime_insertBySelector_js__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(_node_modules_style_loader_dist_runtime_insertBySelector_js__WEBPACK_IMPORTED_MODULE_2__); 190 | /* harmony import */ var _node_modules_style_loader_dist_runtime_setAttributesWithoutAttributes_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! !../node_modules/style-loader/dist/runtime/setAttributesWithoutAttributes.js */ "./node_modules/style-loader/dist/runtime/setAttributesWithoutAttributes.js"); 191 | /* harmony import */ var _node_modules_style_loader_dist_runtime_setAttributesWithoutAttributes_js__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(_node_modules_style_loader_dist_runtime_setAttributesWithoutAttributes_js__WEBPACK_IMPORTED_MODULE_3__); 192 | /* harmony import */ var _node_modules_style_loader_dist_runtime_insertStyleElement_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! !../node_modules/style-loader/dist/runtime/insertStyleElement.js */ "./node_modules/style-loader/dist/runtime/insertStyleElement.js"); 193 | /* harmony import */ var _node_modules_style_loader_dist_runtime_insertStyleElement_js__WEBPACK_IMPORTED_MODULE_4___default = /*#__PURE__*/__webpack_require__.n(_node_modules_style_loader_dist_runtime_insertStyleElement_js__WEBPACK_IMPORTED_MODULE_4__); 194 | /* harmony import */ var _node_modules_style_loader_dist_runtime_styleTagTransform_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! !../node_modules/style-loader/dist/runtime/styleTagTransform.js */ "./node_modules/style-loader/dist/runtime/styleTagTransform.js"); 195 | /* harmony import */ var _node_modules_style_loader_dist_runtime_styleTagTransform_js__WEBPACK_IMPORTED_MODULE_5___default = /*#__PURE__*/__webpack_require__.n(_node_modules_style_loader_dist_runtime_styleTagTransform_js__WEBPACK_IMPORTED_MODULE_5__); 196 | /* harmony import */ var _node_modules_css_loader_dist_cjs_js_style_css__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! !!../node_modules/css-loader/dist/cjs.js!./style.css */ "./node_modules/css-loader/dist/cjs.js!./src/style.css"); 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | var options = {}; 209 | 210 | options.styleTagTransform = (_node_modules_style_loader_dist_runtime_styleTagTransform_js__WEBPACK_IMPORTED_MODULE_5___default()); 211 | options.setAttributes = (_node_modules_style_loader_dist_runtime_setAttributesWithoutAttributes_js__WEBPACK_IMPORTED_MODULE_3___default()); 212 | 213 | options.insert = _node_modules_style_loader_dist_runtime_insertBySelector_js__WEBPACK_IMPORTED_MODULE_2___default().bind(null, "head"); 214 | 215 | options.domAPI = (_node_modules_style_loader_dist_runtime_styleDomAPI_js__WEBPACK_IMPORTED_MODULE_1___default()); 216 | options.insertStyleElement = (_node_modules_style_loader_dist_runtime_insertStyleElement_js__WEBPACK_IMPORTED_MODULE_4___default()); 217 | 218 | var update = _node_modules_style_loader_dist_runtime_injectStylesIntoStyleTag_js__WEBPACK_IMPORTED_MODULE_0___default()(_node_modules_css_loader_dist_cjs_js_style_css__WEBPACK_IMPORTED_MODULE_6__["default"], options); 219 | 220 | 221 | 222 | 223 | /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (_node_modules_css_loader_dist_cjs_js_style_css__WEBPACK_IMPORTED_MODULE_6__["default"] && _node_modules_css_loader_dist_cjs_js_style_css__WEBPACK_IMPORTED_MODULE_6__["default"].locals ? _node_modules_css_loader_dist_cjs_js_style_css__WEBPACK_IMPORTED_MODULE_6__["default"].locals : undefined); 224 | 225 | 226 | /***/ }), 227 | 228 | /***/ "./node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js": 229 | /*!****************************************************************************!*\ 230 | !*** ./node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js ***! 231 | \****************************************************************************/ 232 | /***/ ((module) => { 233 | 234 | 235 | 236 | var stylesInDOM = []; 237 | 238 | function getIndexByIdentifier(identifier) { 239 | var result = -1; 240 | 241 | for (var i = 0; i < stylesInDOM.length; i++) { 242 | if (stylesInDOM[i].identifier === identifier) { 243 | result = i; 244 | break; 245 | } 246 | } 247 | 248 | return result; 249 | } 250 | 251 | function modulesToDom(list, options) { 252 | var idCountMap = {}; 253 | var identifiers = []; 254 | 255 | for (var i = 0; i < list.length; i++) { 256 | var item = list[i]; 257 | var id = options.base ? item[0] + options.base : item[0]; 258 | var count = idCountMap[id] || 0; 259 | var identifier = "".concat(id, " ").concat(count); 260 | idCountMap[id] = count + 1; 261 | var indexByIdentifier = getIndexByIdentifier(identifier); 262 | var obj = { 263 | css: item[1], 264 | media: item[2], 265 | sourceMap: item[3], 266 | supports: item[4], 267 | layer: item[5] 268 | }; 269 | 270 | if (indexByIdentifier !== -1) { 271 | stylesInDOM[indexByIdentifier].references++; 272 | stylesInDOM[indexByIdentifier].updater(obj); 273 | } else { 274 | var updater = addElementStyle(obj, options); 275 | options.byIndex = i; 276 | stylesInDOM.splice(i, 0, { 277 | identifier: identifier, 278 | updater: updater, 279 | references: 1 280 | }); 281 | } 282 | 283 | identifiers.push(identifier); 284 | } 285 | 286 | return identifiers; 287 | } 288 | 289 | function addElementStyle(obj, options) { 290 | var api = options.domAPI(options); 291 | api.update(obj); 292 | 293 | var updater = function updater(newObj) { 294 | if (newObj) { 295 | if (newObj.css === obj.css && newObj.media === obj.media && newObj.sourceMap === obj.sourceMap && newObj.supports === obj.supports && newObj.layer === obj.layer) { 296 | return; 297 | } 298 | 299 | api.update(obj = newObj); 300 | } else { 301 | api.remove(); 302 | } 303 | }; 304 | 305 | return updater; 306 | } 307 | 308 | module.exports = function (list, options) { 309 | options = options || {}; 310 | list = list || []; 311 | var lastIdentifiers = modulesToDom(list, options); 312 | return function update(newList) { 313 | newList = newList || []; 314 | 315 | for (var i = 0; i < lastIdentifiers.length; i++) { 316 | var identifier = lastIdentifiers[i]; 317 | var index = getIndexByIdentifier(identifier); 318 | stylesInDOM[index].references--; 319 | } 320 | 321 | var newLastIdentifiers = modulesToDom(newList, options); 322 | 323 | for (var _i = 0; _i < lastIdentifiers.length; _i++) { 324 | var _identifier = lastIdentifiers[_i]; 325 | 326 | var _index = getIndexByIdentifier(_identifier); 327 | 328 | if (stylesInDOM[_index].references === 0) { 329 | stylesInDOM[_index].updater(); 330 | 331 | stylesInDOM.splice(_index, 1); 332 | } 333 | } 334 | 335 | lastIdentifiers = newLastIdentifiers; 336 | }; 337 | }; 338 | 339 | /***/ }), 340 | 341 | /***/ "./node_modules/style-loader/dist/runtime/insertBySelector.js": 342 | /*!********************************************************************!*\ 343 | !*** ./node_modules/style-loader/dist/runtime/insertBySelector.js ***! 344 | \********************************************************************/ 345 | /***/ ((module) => { 346 | 347 | 348 | 349 | var memo = {}; 350 | /* istanbul ignore next */ 351 | 352 | function getTarget(target) { 353 | if (typeof memo[target] === "undefined") { 354 | var styleTarget = document.querySelector(target); // Special case to return head of iframe instead of iframe itself 355 | 356 | if (window.HTMLIFrameElement && styleTarget instanceof window.HTMLIFrameElement) { 357 | try { 358 | // This will throw an exception if access to iframe is blocked 359 | // due to cross-origin restrictions 360 | styleTarget = styleTarget.contentDocument.head; 361 | } catch (e) { 362 | // istanbul ignore next 363 | styleTarget = null; 364 | } 365 | } 366 | 367 | memo[target] = styleTarget; 368 | } 369 | 370 | return memo[target]; 371 | } 372 | /* istanbul ignore next */ 373 | 374 | 375 | function insertBySelector(insert, style) { 376 | var target = getTarget(insert); 377 | 378 | if (!target) { 379 | throw new Error("Couldn't find a style target. This probably means that the value for the 'insert' parameter is invalid."); 380 | } 381 | 382 | target.appendChild(style); 383 | } 384 | 385 | module.exports = insertBySelector; 386 | 387 | /***/ }), 388 | 389 | /***/ "./node_modules/style-loader/dist/runtime/insertStyleElement.js": 390 | /*!**********************************************************************!*\ 391 | !*** ./node_modules/style-loader/dist/runtime/insertStyleElement.js ***! 392 | \**********************************************************************/ 393 | /***/ ((module) => { 394 | 395 | 396 | 397 | /* istanbul ignore next */ 398 | function insertStyleElement(options) { 399 | var element = document.createElement("style"); 400 | options.setAttributes(element, options.attributes); 401 | options.insert(element, options.options); 402 | return element; 403 | } 404 | 405 | module.exports = insertStyleElement; 406 | 407 | /***/ }), 408 | 409 | /***/ "./node_modules/style-loader/dist/runtime/setAttributesWithoutAttributes.js": 410 | /*!**********************************************************************************!*\ 411 | !*** ./node_modules/style-loader/dist/runtime/setAttributesWithoutAttributes.js ***! 412 | \**********************************************************************************/ 413 | /***/ ((module, __unused_webpack_exports, __webpack_require__) => { 414 | 415 | 416 | 417 | /* istanbul ignore next */ 418 | function setAttributesWithoutAttributes(styleElement) { 419 | var nonce = true ? __webpack_require__.nc : 0; 420 | 421 | if (nonce) { 422 | styleElement.setAttribute("nonce", nonce); 423 | } 424 | } 425 | 426 | module.exports = setAttributesWithoutAttributes; 427 | 428 | /***/ }), 429 | 430 | /***/ "./node_modules/style-loader/dist/runtime/styleDomAPI.js": 431 | /*!***************************************************************!*\ 432 | !*** ./node_modules/style-loader/dist/runtime/styleDomAPI.js ***! 433 | \***************************************************************/ 434 | /***/ ((module) => { 435 | 436 | 437 | 438 | /* istanbul ignore next */ 439 | function apply(styleElement, options, obj) { 440 | var css = ""; 441 | 442 | if (obj.supports) { 443 | css += "@supports (".concat(obj.supports, ") {"); 444 | } 445 | 446 | if (obj.media) { 447 | css += "@media ".concat(obj.media, " {"); 448 | } 449 | 450 | var needLayer = typeof obj.layer !== "undefined"; 451 | 452 | if (needLayer) { 453 | css += "@layer".concat(obj.layer.length > 0 ? " ".concat(obj.layer) : "", " {"); 454 | } 455 | 456 | css += obj.css; 457 | 458 | if (needLayer) { 459 | css += "}"; 460 | } 461 | 462 | if (obj.media) { 463 | css += "}"; 464 | } 465 | 466 | if (obj.supports) { 467 | css += "}"; 468 | } 469 | 470 | var sourceMap = obj.sourceMap; 471 | 472 | if (sourceMap && typeof btoa !== "undefined") { 473 | css += "\n/*# sourceMappingURL=data:application/json;base64,".concat(btoa(unescape(encodeURIComponent(JSON.stringify(sourceMap)))), " */"); 474 | } // For old IE 475 | 476 | /* istanbul ignore if */ 477 | 478 | 479 | options.styleTagTransform(css, styleElement, options.options); 480 | } 481 | 482 | function removeStyleElement(styleElement) { 483 | // istanbul ignore if 484 | if (styleElement.parentNode === null) { 485 | return false; 486 | } 487 | 488 | styleElement.parentNode.removeChild(styleElement); 489 | } 490 | /* istanbul ignore next */ 491 | 492 | 493 | function domAPI(options) { 494 | var styleElement = options.insertStyleElement(options); 495 | return { 496 | update: function update(obj) { 497 | apply(styleElement, options, obj); 498 | }, 499 | remove: function remove() { 500 | removeStyleElement(styleElement); 501 | } 502 | }; 503 | } 504 | 505 | module.exports = domAPI; 506 | 507 | /***/ }), 508 | 509 | /***/ "./node_modules/style-loader/dist/runtime/styleTagTransform.js": 510 | /*!*********************************************************************!*\ 511 | !*** ./node_modules/style-loader/dist/runtime/styleTagTransform.js ***! 512 | \*********************************************************************/ 513 | /***/ ((module) => { 514 | 515 | 516 | 517 | /* istanbul ignore next */ 518 | function styleTagTransform(css, styleElement) { 519 | if (styleElement.styleSheet) { 520 | styleElement.styleSheet.cssText = css; 521 | } else { 522 | while (styleElement.firstChild) { 523 | styleElement.removeChild(styleElement.firstChild); 524 | } 525 | 526 | styleElement.appendChild(document.createTextNode(css)); 527 | } 528 | } 529 | 530 | module.exports = styleTagTransform; 531 | 532 | /***/ }), 533 | 534 | /***/ "./src/utils/structure.js": 535 | /*!********************************!*\ 536 | !*** ./src/utils/structure.js ***! 537 | \********************************/ 538 | /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { 539 | 540 | __webpack_require__.r(__webpack_exports__); 541 | /* harmony export */ __webpack_require__.d(__webpack_exports__, { 542 | /* harmony export */ "default": () => (/* binding */ populateStorage) 543 | /* harmony export */ }); 544 | /* eslint-disable no-use-before-define */ 545 | const items = []; 546 | const form = document.querySelector('.form-element'); 547 | const displayTask = () => { 548 | const container = document.querySelector('.list-container'); 549 | form.addEventListener('submit', (event) => { 550 | event.preventDefault(); 551 | const data = form.elements[0].value; 552 | const object = { 553 | description: data, 554 | completed: false, 555 | index: items.length + 1, 556 | }; 557 | form.reset(); 558 | items.push(object); 559 | localStorage.setItem('itemsLocal', JSON.stringify(items)); 560 | render(); 561 | }); 562 | const clearElement = document.createElement('p'); 563 | clearElement.className = 'clear'; 564 | clearElement.innerText = 'Clear all completed'; 565 | container.appendChild(clearElement); 566 | const clear = document.querySelector('.clear'); 567 | const list = document.createElement('ul'); 568 | list.className = 'ul-list'; 569 | container.insertBefore(list, clear); 570 | }; 571 | 572 | const removeItem = () => { 573 | const button = document.querySelectorAll('.fa-trash-alt'); 574 | button.forEach((item) => { 575 | const parent = item.parentNode; 576 | const superParent = parent.parentNode; 577 | const index = Array.prototype.indexOf.call(superParent.children, parent); 578 | const listInput = parent.firstChild; 579 | item.addEventListener('click', () => { 580 | const itemsLocal = JSON.parse(localStorage.getItem('itemsLocal')); 581 | items.splice(0, items.length, ...itemsLocal); 582 | if (listInput.hasAttribute('checked')) { 583 | parent.remove(); 584 | items.splice(index, 1); 585 | } 586 | for (let i = 0; i < items.length; i += 1) { 587 | items[i].index = i + 1; 588 | } 589 | localStorage.setItem('itemsLocal', JSON.stringify(items)); 590 | render(); 591 | }); 592 | }); 593 | }; 594 | 595 | const clearList = () => { 596 | const getClearElement = document.querySelector('.clear'); 597 | getClearElement.addEventListener('click', () => { 598 | for (let i = 0; i < items.length; i += 1) { 599 | if (items[i].completed) { 600 | items.splice(i, 1); 601 | } 602 | } 603 | 604 | for (let i = 0; i < items.length; i += 1) { 605 | items[i].index = i + 1; 606 | } 607 | localStorage.setItem('itemsLocal', JSON.stringify(items)); 608 | render(); 609 | }); 610 | }; 611 | 612 | const updateValues = () => { 613 | const itemDetails = document.querySelectorAll('.item-details'); 614 | itemDetails.forEach((item) => { 615 | const parent = item.parentNode; 616 | const superParent = parent.parentNode; 617 | const index = Array.prototype.indexOf.call(superParent.children, parent); 618 | item.addEventListener('change', () => { 619 | items[index].description = item.value; 620 | localStorage.setItem('itemsLocal', JSON.stringify(items)); 621 | }); 622 | }); 623 | }; 624 | 625 | const textDecoration = (listInput) => { 626 | listInput.forEach((item) => { 627 | if (item.hasAttribute('checked')) { 628 | item.nextSibling.style.textDecoration = 'line-through'; 629 | } else { 630 | item.nextSibling.style.textDecoration = 'none'; 631 | } 632 | }); 633 | }; 634 | 635 | function populateStorage() { 636 | window.addEventListener('load', () => { 637 | render(); 638 | const listInput = document.querySelectorAll('.list-input'); 639 | const itemsLocal = JSON.parse(localStorage.getItem('itemsLocal')); 640 | listInput.forEach((item) => { 641 | const parent = item.parentNode; 642 | const superParent = parent.parentNode; 643 | const index = Array.prototype.indexOf.call(superParent.children, parent); 644 | const currentItem = itemsLocal[index].completed; 645 | if (currentItem) { 646 | item.setAttribute('checked', ''); 647 | parent.lastChild.style.display = 'block'; 648 | } 649 | }); 650 | textDecoration(listInput); 651 | }); 652 | } 653 | 654 | function userInteraction(listInput) { 655 | listInput.forEach((item) => { 656 | item.addEventListener('change', () => { 657 | const itemsLocal = JSON.parse(localStorage.getItem('itemsLocal')); 658 | const parent = item.parentNode; 659 | const superParent = parent.parentNode; 660 | const index = Array.prototype.indexOf.call(superParent.children, parent); 661 | const currentItem = itemsLocal[index].completed; 662 | if (currentItem) { 663 | item.removeAttribute('checked'); 664 | parent.lastChild.style.display = 'none'; 665 | itemsLocal[index].completed = false; 666 | } else { 667 | item.setAttribute('checked', ''); 668 | parent.lastChild.style.display = 'block'; 669 | itemsLocal[index].completed = true; 670 | } 671 | textDecoration(listInput); 672 | localStorage.setItem('itemsLocal', JSON.stringify(itemsLocal)); 673 | items.splice(0, items.length, ...itemsLocal); 674 | }); 675 | }); 676 | } 677 | 678 | const render = () => { 679 | const list = document.querySelector('.ul-list'); 680 | const itemsLocal = JSON.parse(localStorage.getItem('itemsLocal')); 681 | items.splice(0, items.length, ...itemsLocal); 682 | list.innerHTML = ''; 683 | for (let i = 0; i < itemsLocal.length; i += 1) { 684 | const { description } = itemsLocal[i]; 685 | const listItem = document.createElement('li'); 686 | listItem.className = 'list-item'; 687 | listItem.innerHTML = ``; 688 | list.appendChild(listItem); 689 | } 690 | const listInput = document.querySelectorAll('.list-input'); 691 | userInteraction(listInput); 692 | clearList(listInput); 693 | removeItem(); 694 | updateValues(); 695 | }; 696 | 697 | displayTask(); 698 | 699 | 700 | /***/ }) 701 | 702 | /******/ }); 703 | /************************************************************************/ 704 | /******/ // The module cache 705 | /******/ var __webpack_module_cache__ = {}; 706 | /******/ 707 | /******/ // The require function 708 | /******/ function __webpack_require__(moduleId) { 709 | /******/ // Check if module is in cache 710 | /******/ var cachedModule = __webpack_module_cache__[moduleId]; 711 | /******/ if (cachedModule !== undefined) { 712 | /******/ return cachedModule.exports; 713 | /******/ } 714 | /******/ // Create a new module (and put it into the cache) 715 | /******/ var module = __webpack_module_cache__[moduleId] = { 716 | /******/ id: moduleId, 717 | /******/ // no module.loaded needed 718 | /******/ exports: {} 719 | /******/ }; 720 | /******/ 721 | /******/ // Execute the module function 722 | /******/ __webpack_modules__[moduleId](module, module.exports, __webpack_require__); 723 | /******/ 724 | /******/ // Return the exports of the module 725 | /******/ return module.exports; 726 | /******/ } 727 | /******/ 728 | /************************************************************************/ 729 | /******/ /* webpack/runtime/compat get default export */ 730 | /******/ (() => { 731 | /******/ // getDefaultExport function for compatibility with non-harmony modules 732 | /******/ __webpack_require__.n = (module) => { 733 | /******/ var getter = module && module.__esModule ? 734 | /******/ () => (module['default']) : 735 | /******/ () => (module); 736 | /******/ __webpack_require__.d(getter, { a: getter }); 737 | /******/ return getter; 738 | /******/ }; 739 | /******/ })(); 740 | /******/ 741 | /******/ /* webpack/runtime/define property getters */ 742 | /******/ (() => { 743 | /******/ // define getter functions for harmony exports 744 | /******/ __webpack_require__.d = (exports, definition) => { 745 | /******/ for(var key in definition) { 746 | /******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) { 747 | /******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] }); 748 | /******/ } 749 | /******/ } 750 | /******/ }; 751 | /******/ })(); 752 | /******/ 753 | /******/ /* webpack/runtime/hasOwnProperty shorthand */ 754 | /******/ (() => { 755 | /******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop)) 756 | /******/ })(); 757 | /******/ 758 | /******/ /* webpack/runtime/make namespace object */ 759 | /******/ (() => { 760 | /******/ // define __esModule on exports 761 | /******/ __webpack_require__.r = (exports) => { 762 | /******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { 763 | /******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); 764 | /******/ } 765 | /******/ Object.defineProperty(exports, '__esModule', { value: true }); 766 | /******/ }; 767 | /******/ })(); 768 | /******/ 769 | /************************************************************************/ 770 | var __webpack_exports__ = {}; 771 | // This entry need to be wrapped in an IIFE because it need to be isolated against other modules in the chunk. 772 | (() => { 773 | /*!**********************!*\ 774 | !*** ./src/index.js ***! 775 | \**********************/ 776 | __webpack_require__.r(__webpack_exports__); 777 | /* harmony import */ var _style_css__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./style.css */ "./src/style.css"); 778 | /* harmony import */ var _utils_structure_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./utils/structure.js */ "./src/utils/structure.js"); 779 | 780 | 781 | 782 | (0,_utils_structure_js__WEBPACK_IMPORTED_MODULE_1__["default"])(); 783 | 784 | })(); 785 | 786 | /******/ })() 787 | ; 788 | //# sourceMappingURL=data:application/json;charset=utf-8;base64,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Y2stZGVtby8uL3NyYy9zdHlsZS5jc3MiLCJ3ZWJwYWNrOi8vd2VicGFjay1kZW1vLy4vbm9kZV9tb2R1bGVzL2Nzcy1sb2FkZXIvZGlzdC9ydW50aW1lL2FwaS5qcyIsIndlYnBhY2s6Ly93ZWJwYWNrLWRlbW8vLi9ub2RlX21vZHVsZXMvY3NzLWxvYWRlci9kaXN0L3J1bnRpbWUvc291cmNlTWFwcy5qcyIsIndlYnBhY2s6Ly93ZWJwYWNrLWRlbW8vLi9zcmMvc3R5bGUuY3NzPzcxNjMiLCJ3ZWJwYWNrOi8vd2VicGFjay1kZW1vLy4vbm9kZV9tb2R1bGVzL3N0eWxlLWxvYWRlci9kaXN0L3J1bnRpbWUvaW5qZWN0U3R5bGVzSW50b1N0eWxlVGFnLmpzIiwid2VicGFjazovL3dlYnBhY2stZGVtby8uL25vZGVfbW9kdWxlcy9zdHlsZS1sb2FkZXIvZGlzdC9ydW50aW1lL2luc2VydEJ5U2VsZWN0b3IuanMiLCJ3ZWJwYWNrOi8vd2VicGFjay1kZW1vLy4vbm9kZV9tb2R1bGVzL3N0eWxlLWxvYWRlci9kaXN0L3J1bnRpbWUvaW5zZXJ0U3R5bGVFbGVtZW50LmpzIiwid2VicGFjazovL3dlYnBhY2stZGVtby8uL25vZGVfbW9kdWxlcy9zdHlsZS1sb2FkZXIvZGlzdC9ydW50aW1lL3NldEF0dHJpYnV0ZXNXaXRob3V0QXR0cmlidXRlcy5qcyIsIndlYnBhY2s6Ly93ZWJwYWNrLWRlbW8vLi9ub2RlX21vZHVsZXMvc3R5bGUtbG9hZGVyL2Rpc3QvcnVudGltZS9zdHlsZURvbUFQSS5qcyIsIndlYnBhY2s6Ly93ZWJwYWNrLWRlbW8vLi9ub2RlX21vZHVsZXMvc3R5bGUtbG9hZGVyL2Rpc3QvcnVudGltZS9zdHlsZVRhZ1RyYW5zZm9ybS5qcyIsIndlYnBhY2s6Ly93ZWJwYWNrLWRlbW8vLi9zcmMvdXRpbHMvc3RydWN0dXJlLmpzIiwid2VicGFjazovL3dlYnBhY2stZGVtby93ZWJwYWNrL2Jvb3RzdHJhcCIsIndlYnBhY2s6Ly93ZWJwYWNrLWRlbW8vd2VicGFjay9ydW50aW1lL2NvbXBhdCBnZXQgZGVmYXVsdCBleHBvcnQiLCJ3ZWJwYWNrOi8vd2VicGFjay1kZW1vL3dlYnBhY2svcnVudGltZS9kZWZpbmUgcHJvcGVydHkgZ2V0dGVycyIsIndlYnBhY2s6Ly93ZWJwYWNrLWRlbW8vd2VicGFjay9ydW50aW1lL2hhc093blByb3BlcnR5IHNob3J0aGFuZCIsIndlYnBhY2s6Ly93ZWJwYWNrLWRlbW8vd2VicGFjay9ydW50aW1lL21ha2UgbmFtZXNwYWNlIG9iamVjdCIsIndlYnBhY2s6Ly93ZWJwYWNrLWRlbW8vLi9zcmMvaW5kZXguanMiXSwic291cmNlc0NvbnRlbnQiOlsiLy8gSW1wb3J0c1xuaW1wb3J0IF9fX0NTU19MT0FERVJfQVBJX1NPVVJDRU1BUF9JTVBPUlRfX18gZnJvbSBcIi4uL25vZGVfbW9kdWxlcy9jc3MtbG9hZGVyL2Rpc3QvcnVudGltZS9zb3VyY2VNYXBzLmpzXCI7XG5pbXBvcnQgX19fQ1NTX0xPQURFUl9BUElfSU1QT1JUX19fIGZyb20gXCIuLi9ub2RlX21vZHVsZXMvY3NzLWxvYWRlci9kaXN0L3J1bnRpbWUvYXBpLmpzXCI7XG52YXIgX19fQ1NTX0xPQURFUl9FWFBPUlRfX18gPSBfX19DU1NfTE9BREVSX0FQSV9JTVBPUlRfX18oX19fQ1NTX0xPQURFUl9BUElfU09VUkNFTUFQX0lNUE9SVF9fXyk7XG5fX19DU1NfTE9BREVSX0VYUE9SVF9fXy5wdXNoKFttb2R1bGUuaWQsIFwiQGltcG9ydCB1cmwoaHR0cHM6Ly9mb250cy5nb29nbGVhcGlzLmNvbS9jc3MyP2ZhbWlseT1Qb3BwaW5zJmRpc3BsYXk9c3dhcCk7XCJdKTtcbi8vIE1vZHVsZVxuX19fQ1NTX0xPQURFUl9FWFBPUlRfX18ucHVzaChbbW9kdWxlLmlkLCBcIi8qIHN0eWxlc2hlZXQgKi9cXHJcXG5cXHJcXG5ib2R5IHtcXHJcXG4gIGZvbnQtZmFtaWx5OiBcXFwiUG9wcGluc1xcXCIsIHNhbnMtc2VyaWY7XFxyXFxufVxcclxcblxcclxcbi5tYWluLWNvbnRhaW5lciB7XFxyXFxuICBib3JkZXI6IDNweCBzb2xpZCAjZGZlMWU2O1xcclxcbiAgbWFyZ2luOiAzMHB4IDIwcHggMCAyMHB4O1xcclxcbiAgYm94LXNoYWRvdzogNXB4IDVweCAjZGZlMWU2O1xcclxcbn1cXHJcXG5cXHJcXG4ubGlzdC1oZWFkIHtcXHJcXG4gIGRpc3BsYXk6IGZsZXg7XFxyXFxuICBqdXN0aWZ5LWNvbnRlbnQ6IHNwYWNlLWJldHdlZW47XFxyXFxuICBtYXJnaW46IDAgMTBweDtcXHJcXG59XFxyXFxuXFxyXFxuaHIge1xcclxcbiAgaGVpZ2h0OiAxcHg7XFxyXFxuICBiYWNrZ3JvdW5kLWNvbG9yOiAjZGZlMWU2O1xcclxcbiAgYm9yZGVyOiBub25lO1xcclxcbiAgbWFyZ2luOiAwO1xcclxcbn1cXHJcXG5cXHJcXG5mb3JtIHtcXHJcXG4gIGRpc3BsYXk6IGZsZXg7XFxyXFxufVxcclxcblxcclxcbi5mYS1sZXZlbC1kb3duLWFsdCB7XFxyXFxuICBmb250LXNpemU6IDIwcHg7XFxyXFxuICBjb2xvcjogcmdiYSg1LCA1LCA1LCAwLjUwNyk7XFxyXFxufVxcclxcblxcclxcbi5mb3JtLWlucHV0IHtcXHJcXG4gIGZvbnQtc3R5bGU6IGl0YWxpYztcXHJcXG4gIHBhZGRpbmc6IDEwcHg7XFxyXFxuICBib3JkZXI6IG5vbmU7XFxyXFxuICB3aWR0aDogOTAlO1xcclxcbiAgb3V0bGluZTogbm9uZTtcXHJcXG59XFxyXFxuXFxyXFxuLm1haW4taGVhZGluZyB7XFxyXFxuICBmb250LXdlaWdodDogMTAwO1xcclxcbiAgZm9udC1zaXplOiAxOHB4O1xcclxcbiAgY29sb3I6IHJnYmEoMCwgMCwgMCwgMC44NzcpO1xcclxcbn1cXHJcXG5cXHJcXG4uZmEtc3luYy1hbHQge1xcclxcbiAgbWFyZ2luLXRvcDogMTdweDtcXHJcXG4gIG1hcmdpbi1yaWdodDogMTBweDtcXHJcXG4gIGNvbG9yOiByZ2JhKDUsIDUsIDUsIDAuNTA3KTtcXHJcXG59XFxyXFxuXFxyXFxudWwge1xcclxcbiAgcGFkZGluZzogMDtcXHJcXG4gIGdhcDogMTBweDtcXHJcXG4gIGRpc3BsYXk6IGZsZXg7XFxyXFxuICBmbGV4LWRpcmVjdGlvbjogY29sdW1uO1xcclxcbiAgbGlzdC1zdHlsZS10eXBlOiBub25lO1xcclxcbn1cXHJcXG5cXHJcXG4ubGlzdC1pdGVtIHtcXHJcXG4gIGRpc3BsYXk6IGZsZXg7XFxyXFxuICBnYXA6IDEwcHg7XFxyXFxuICBwYWRkaW5nLWxlZnQ6IDA7XFxyXFxufVxcclxcblxcclxcbi5saXN0LWlucHV0IHtcXHJcXG4gIG1hcmdpbi10b3A6IDVweDtcXHJcXG4gIHRyYW5zZm9ybTogc2NhbGUoMS4zKTtcXHJcXG59XFxyXFxuXFxyXFxuLml0ZW0tZGV0YWlscyB7XFxyXFxuICBtYXJnaW4tdG9wOiAwO1xcclxcbiAgd2lkdGg6IDMwMHB4O1xcclxcbiAgYm9yZGVyOiBub25lO1xcclxcbiAgcmVzaXplOiBub25lO1xcclxcbiAgb3V0bGluZTogbm9uZTtcXHJcXG59XFxyXFxuXFxyXFxuLmZhLXRyYXNoLWFsdCB7XFxyXFxuICBkaXNwbGF5OiBub25lO1xcclxcbiAgbWFyZ2luLWxlZnQ6IDE1MHB4O1xcclxcbiAgY29sb3I6IHJnYmEoNzMsIDczLCA3MywgMC43MjYpO1xcclxcbn1cXHJcXG5cXHJcXG4uZmEtc3F1YXJlIHtcXHJcXG4gIGZvbnQtc2l6ZTogMThweDtcXHJcXG4gIG1hcmdpbi10b3A6IDE4cHg7XFxyXFxuICBjb2xvcjogcmdiKDczLCA3MywgNzMpO1xcclxcbn1cXHJcXG5cXHJcXG4uY2xlYXIge1xcclxcbiAgdGV4dC1hbGlnbjogY2VudGVyO1xcclxcbiAgZm9udC1zaXplOiAxOHB4O1xcclxcbiAgY29sb3I6IHJnYig4NywgODAsIDgwKTtcXHJcXG4gIGJhY2tncm91bmQtY29sb3I6ICM4MDgwODA0ODtcXHJcXG4gIG1hcmdpbi1ib3R0b206IDA7XFxyXFxuICBwYWRkaW5nOiAyMHB4IDA7XFxyXFxufVxcclxcblxcclxcbkBtZWRpYSBzY3JlZW4gYW5kIChtaW4td2lkdGg6IDc3MnB4KSB7XFxyXFxuICAubWFpbi1jb250YWluZXIge1xcclxcbiAgICBtYXJnaW46IDMwcHggMzB2dyAwIDMwdnc7XFxyXFxuICB9XFxyXFxufVxcclxcblwiLCBcIlwiLHtcInZlcnNpb25cIjozLFwic291cmNlc1wiOltcIndlYnBhY2s6Ly8uL3NyYy9zdHlsZS5jc3NcIl0sXCJuYW1lc1wiOltdLFwibWFwcGluZ3NcIjpcIkFBQUEsZUFBZTs7QUFHZjtFQUNFLGtDQUFrQztBQUNwQzs7QUFFQTtFQUNFLHlCQUF5QjtFQUN6Qix3QkFBd0I7RUFDeEIsMkJBQTJCO0FBQzdCOztBQUVBO0VBQ0UsYUFBYTtFQUNiLDhCQUE4QjtFQUM5QixjQUFjO0FBQ2hCOztBQUVBO0VBQ0UsV0FBVztFQUNYLHlCQUF5QjtFQUN6QixZQUFZO0VBQ1osU0FBUztBQUNYOztBQUVBO0VBQ0UsYUFBYTtBQUNmOztBQUVBO0VBQ0UsZUFBZTtFQUNmLDJCQUEyQjtBQUM3Qjs7QUFFQTtFQUNFLGtCQUFrQjtFQUNsQixhQUFhO0VBQ2IsWUFBWTtFQUNaLFVBQVU7RUFDVixhQUFhO0FBQ2Y7O0FBRUE7RUFDRSxnQkFBZ0I7RUFDaEIsZUFBZTtFQUNmLDJCQUEyQjtBQUM3Qjs7QUFFQTtFQUNFLGdCQUFnQjtFQUNoQixrQkFBa0I7RUFDbEIsMkJBQTJCO0FBQzdCOztBQUVBO0VBQ0UsVUFBVTtFQUNWLFNBQVM7RUFDVCxhQUFhO0VBQ2Isc0JBQXNCO0VBQ3RCLHFCQUFxQjtBQUN2Qjs7QUFFQTtFQUNFLGFBQWE7RUFDYixTQUFTO0VBQ1QsZUFBZTtBQUNqQjs7QUFFQTtFQUNFLGVBQWU7RUFDZixxQkFBcUI7QUFDdkI7O0FBRUE7RUFDRSxhQUFhO0VBQ2IsWUFBWTtFQUNaLFlBQVk7RUFDWixZQUFZO0VBQ1osYUFBYTtBQUNmOztBQUVBO0VBQ0UsYUFBYTtFQUNiLGtCQUFrQjtFQUNsQiw4QkFBOEI7QUFDaEM7O0FBRUE7RUFDRSxlQUFlO0VBQ2YsZ0JBQWdCO0VBQ2hCLHNCQUFzQjtBQUN4Qjs7QUFFQTtFQUNFLGtCQUFrQjtFQUNsQixlQUFlO0VBQ2Ysc0JBQXNCO0VBQ3RCLDJCQUEyQjtFQUMzQixnQkFBZ0I7RUFDaEIsZUFBZTtBQUNqQjs7QUFFQTtFQUNFO0lBQ0Usd0JBQXdCO0VBQzFCO0FBQ0ZcIixcInNvdXJjZXNDb250ZW50XCI6W1wiLyogc3R5bGVzaGVldCAqL1xcclxcbkBpbXBvcnQgdXJsKFxcXCJodHRwczovL2ZvbnRzLmdvb2dsZWFwaXMuY29tL2NzczI/ZmFtaWx5PVBvcHBpbnMmZGlzcGxheT1zd2FwXFxcIik7XFxyXFxuXFxyXFxuYm9keSB7XFxyXFxuICBmb250LWZhbWlseTogXFxcIlBvcHBpbnNcXFwiLCBzYW5zLXNlcmlmO1xcclxcbn1cXHJcXG5cXHJcXG4ubWFpbi1jb250YWluZXIge1xcclxcbiAgYm9yZGVyOiAzcHggc29saWQgI2RmZTFlNjtcXHJcXG4gIG1hcmdpbjogMzBweCAyMHB4IDAgMjBweDtcXHJcXG4gIGJveC1zaGFkb3c6IDVweCA1cHggI2RmZTFlNjtcXHJcXG59XFxyXFxuXFxyXFxuLmxpc3QtaGVhZCB7XFxyXFxuICBkaXNwbGF5OiBmbGV4O1xcclxcbiAganVzdGlmeS1jb250ZW50OiBzcGFjZS1iZXR3ZWVuO1xcclxcbiAgbWFyZ2luOiAwIDEwcHg7XFxyXFxufVxcclxcblxcclxcbmhyIHtcXHJcXG4gIGhlaWdodDogMXB4O1xcclxcbiAgYmFja2dyb3VuZC1jb2xvcjogI2RmZTFlNjtcXHJcXG4gIGJvcmRlcjogbm9uZTtcXHJcXG4gIG1hcmdpbjogMDtcXHJcXG59XFxyXFxuXFxyXFxuZm9ybSB7XFxyXFxuICBkaXNwbGF5OiBmbGV4O1xcclxcbn1cXHJcXG5cXHJcXG4uZmEtbGV2ZWwtZG93bi1hbHQge1xcclxcbiAgZm9udC1zaXplOiAyMHB4O1xcclxcbiAgY29sb3I6IHJnYmEoNSwgNSwgNSwgMC41MDcpO1xcclxcbn1cXHJcXG5cXHJcXG4uZm9ybS1pbnB1dCB7XFxyXFxuICBmb250LXN0eWxlOiBpdGFsaWM7XFxyXFxuICBwYWRkaW5nOiAxMHB4O1xcclxcbiAgYm9yZGVyOiBub25lO1xcclxcbiAgd2lkdGg6IDkwJTtcXHJcXG4gIG91dGxpbmU6IG5vbmU7XFxyXFxufVxcclxcblxcclxcbi5tYWluLWhlYWRpbmcge1xcclxcbiAgZm9udC13ZWlnaHQ6IDEwMDtcXHJcXG4gIGZvbnQtc2l6ZTogMThweDtcXHJcXG4gIGNvbG9yOiByZ2JhKDAsIDAsIDAsIDAuODc3KTtcXHJcXG59XFxyXFxuXFxyXFxuLmZhLXN5bmMtYWx0IHtcXHJcXG4gIG1hcmdpbi10b3A6IDE3cHg7XFxyXFxuICBtYXJnaW4tcmlnaHQ6IDEwcHg7XFxyXFxuICBjb2xvcjogcmdiYSg1LCA1LCA1LCAwLjUwNyk7XFxyXFxufVxcclxcblxcclxcbnVsIHtcXHJcXG4gIHBhZGRpbmc6IDA7XFxyXFxuICBnYXA6IDEwcHg7XFxyXFxuICBkaXNwbGF5OiBmbGV4O1xcclxcbiAgZmxleC1kaXJlY3Rpb246IGNvbHVtbjtcXHJcXG4gIGxpc3Qtc3R5bGUtdHlwZTogbm9uZTtcXHJcXG59XFxyXFxuXFxyXFxuLmxpc3QtaXRlbSB7XFxyXFxuICBkaXNwbGF5OiBmbGV4O1xcclxcbiAgZ2FwOiAxMHB4O1xcclxcbiAgcGFkZGluZy1sZWZ0OiAwO1xcclxcbn1cXHJcXG5cXHJcXG4ubGlzdC1pbnB1dCB7XFxyXFxuICBtYXJnaW4tdG9wOiA1cHg7XFxyXFxuICB0cmFuc2Zvcm06IHNjYWxlKDEuMyk7XFxyXFxufVxcclxcblxcclxcbi5pdGVtLWRldGFpbHMge1xcclxcbiAgbWFyZ2luLXRvcDogMDtcXHJcXG4gIHdpZHRoOiAzMDBweDtcXHJcXG4gIGJvcmRlcjogbm9uZTtcXHJcXG4gIHJlc2l6ZTogbm9uZTtcXHJcXG4gIG91dGxpbmU6IG5vbmU7XFxyXFxufVxcclxcblxcclxcbi5mYS10cmFzaC1hbHQge1xcclxcbiAgZGlzcGxheTogbm9uZTtcXHJcXG4gIG1hcmdpbi1sZWZ0OiAxNTBweDtcXHJcXG4gIGNvbG9yOiByZ2JhKDczLCA3MywgNzMsIDAuNzI2KTtcXHJcXG59XFxyXFxuXFxyXFxuLmZhLXNxdWFyZSB7XFxyXFxuICBmb250LXNpemU6IDE4cHg7XFxyXFxuICBtYXJnaW4tdG9wOiAxOHB4O1xcclxcbiAgY29sb3I6IHJnYig3MywgNzMsIDczKTtcXHJcXG59XFxyXFxuXFxyXFxuLmNsZWFyIHtcXHJcXG4gIHRleHQtYWxpZ246IGNlbnRlcjtcXHJcXG4gIGZvbnQtc2l6ZTogMThweDtcXHJcXG4gIGNvbG9yOiByZ2IoODcsIDgwLCA4MCk7XFxyXFxuICBiYWNrZ3JvdW5kLWNvbG9yOiAjODA4MDgwNDg7XFxyXFxuICBtYXJnaW4tYm90dG9tOiAwO1xcclxcbiAgcGFkZGluZzogMjBweCAwO1xcclxcbn1cXHJcXG5cXHJcXG5AbWVkaWEgc2NyZWVuIGFuZCAobWluLXdpZHRoOiA3NzJweCkge1xcclxcbiAgLm1haW4tY29udGFpbmVyIHtcXHJcXG4gICAgbWFyZ2luOiAzMHB4IDMwdncgMCAzMHZ3O1xcclxcbiAgfVxcclxcbn1cXHJcXG5cIl0sXCJzb3VyY2VSb290XCI6XCJcIn1dKTtcbi8vIEV4cG9ydHNcbmV4cG9ydCBkZWZhdWx0IF9fX0NTU19MT0FERVJfRVhQT1JUX19fO1xuIiwiXCJ1c2Ugc3RyaWN0XCI7XG5cbi8qXG4gIE1JVCBMaWNlbnNlIGh0dHA6Ly93d3cub3BlbnNvdXJjZS5vcmcvbGljZW5zZXMvbWl0LWxpY2Vuc2UucGhwXG4gIEF1dGhvciBUb2JpYXMgS29wcGVycyBAc29rcmFcbiovXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChjc3NXaXRoTWFwcGluZ1RvU3RyaW5nKSB7XG4gIHZhciBsaXN0ID0gW107IC8vIHJldHVybiB0aGUgbGlzdCBvZiBtb2R1bGVzIGFzIGNzcyBzdHJpbmdcblxuICBsaXN0LnRvU3RyaW5nID0gZnVuY3Rpb24gdG9TdHJpbmcoKSB7XG4gICAgcmV0dXJuIHRoaXMubWFwKGZ1bmN0aW9uIChpdGVtKSB7XG4gICAgICB2YXIgY29udGVudCA9IFwiXCI7XG4gICAgICB2YXIgbmVlZExheWVyID0gdHlwZW9mIGl0ZW1bNV0gIT09IFwidW5kZWZpbmVkXCI7XG5cbiAgICAgIGlmIChpdGVtWzRdKSB7XG4gICAgICAgIGNvbnRlbnQgKz0gXCJAc3VwcG9ydHMgKFwiLmNvbmNhdChpdGVtWzRdLCBcIikge1wiKTtcbiAgICAgIH1cblxuICAgICAgaWYgKGl0ZW1bMl0pIHtcbiAgICAgICAgY29udGVudCArPSBcIkBtZWRpYSBcIi5jb25jYXQoaXRlbVsyXSwgXCIge1wiKTtcbiAgICAgIH1cblxuICAgICAgaWYgKG5lZWRMYXllcikge1xuICAgICAgICBjb250ZW50ICs9IFwiQGxheWVyXCIuY29uY2F0KGl0ZW1bNV0ubGVuZ3RoID4gMCA/IFwiIFwiLmNvbmNhdChpdGVtWzVdKSA6IFwiXCIsIFwiIHtcIik7XG4gICAgICB9XG5cbiAgICAgIGNvbnRlbnQgKz0gY3NzV2l0aE1hcHBpbmdUb1N0cmluZyhpdGVtKTtcblxuICAgICAgaWYgKG5lZWRMYXllcikge1xuICAgICAgICBjb250ZW50ICs9IFwifVwiO1xuICAgICAgfVxuXG4gICAgICBpZiAoaXRlbVsyXSkge1xuICAgICAgICBjb250ZW50ICs9IFwifVwiO1xuICAgICAgfVxuXG4gICAgICBpZiAoaXRlbVs0XSkge1xuICAgICAgICBjb250ZW50ICs9IFwifVwiO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gY29udGVudDtcbiAgICB9KS5qb2luKFwiXCIpO1xuICB9OyAvLyBpbXBvcnQgYSBsaXN0IG9mIG1vZHVsZXMgaW50byB0aGUgbGlzdFxuXG5cbiAgbGlzdC5pID0gZnVuY3Rpb24gaShtb2R1bGVzLCBtZWRpYSwgZGVkdXBlLCBzdXBwb3J0cywgbGF5ZXIpIHtcbiAgICBpZiAodHlwZW9mIG1vZHVsZXMgPT09IFwic3RyaW5nXCIpIHtcbiAgICAgIG1vZHVsZXMgPSBbW251bGwsIG1vZHVsZXMsIHVuZGVmaW5lZF1dO1xuICAgIH1cblxuICAgIHZhciBhbHJlYWR5SW1wb3J0ZWRNb2R1bGVzID0ge307XG5cbiAgICBpZiAoZGVkdXBlKSB7XG4gICAgICBmb3IgKHZhciBrID0gMDsgayA8IHRoaXMubGVuZ3RoOyBrKyspIHtcbiAgICAgICAgdmFyIGlkID0gdGhpc1trXVswXTtcblxuICAgICAgICBpZiAoaWQgIT0gbnVsbCkge1xuICAgICAgICAgIGFscmVhZHlJbXBvcnRlZE1vZHVsZXNbaWRdID0gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIGZvciAodmFyIF9rID0gMDsgX2sgPCBtb2R1bGVzLmxlbmd0aDsgX2srKykge1xuICAgICAgdmFyIGl0ZW0gPSBbXS5jb25jYXQobW9kdWxlc1tfa10pO1xuXG4gICAgICBpZiAoZGVkdXBlICYmIGFscmVhZHlJbXBvcnRlZE1vZHVsZXNbaXRlbVswXV0pIHtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIGlmICh0eXBlb2YgbGF5ZXIgIT09IFwidW5kZWZpbmVkXCIpIHtcbiAgICAgICAgaWYgKHR5cGVvZiBpdGVtWzVdID09PSBcInVuZGVmaW5lZFwiKSB7XG4gICAgICAgICAgaXRlbVs1XSA9IGxheWVyO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGl0ZW1bMV0gPSBcIkBsYXllclwiLmNvbmNhdChpdGVtWzVdLmxlbmd0aCA+IDAgPyBcIiBcIi5jb25jYXQoaXRlbVs1XSkgOiBcIlwiLCBcIiB7XCIpLmNvbmNhdChpdGVtWzFdLCBcIn1cIik7XG4gICAgICAgICAgaXRlbVs1XSA9IGxheWVyO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGlmIChtZWRpYSkge1xuICAgICAgICBpZiAoIWl0ZW1bMl0pIHtcbiAgICAgICAgICBpdGVtWzJdID0gbWVkaWE7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgaXRlbVsxXSA9IFwiQG1lZGlhIFwiLmNvbmNhdChpdGVtWzJdLCBcIiB7XCIpLmNvbmNhdChpdGVtWzFdLCBcIn1cIik7XG4gICAgICAgICAgaXRlbVsyXSA9IG1lZGlhO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGlmIChzdXBwb3J0cykge1xuICAgICAgICBpZiAoIWl0ZW1bNF0pIHtcbiAgICAgICAgICBpdGVtWzRdID0gXCJcIi5jb25jYXQoc3VwcG9ydHMpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGl0ZW1bMV0gPSBcIkBzdXBwb3J0cyAoXCIuY29uY2F0KGl0ZW1bNF0sIFwiKSB7XCIpLmNvbmNhdChpdGVtWzFdLCBcIn1cIik7XG4gICAgICAgICAgaXRlbVs0XSA9IHN1cHBvcnRzO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGxpc3QucHVzaChpdGVtKTtcbiAgICB9XG4gIH07XG5cbiAgcmV0dXJuIGxpc3Q7XG59OyIsIlwidXNlIHN0cmljdFwiO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChpdGVtKSB7XG4gIHZhciBjb250ZW50ID0gaXRlbVsxXTtcbiAgdmFyIGNzc01hcHBpbmcgPSBpdGVtWzNdO1xuXG4gIGlmICghY3NzTWFwcGluZykge1xuICAgIHJldHVybiBjb250ZW50O1xuICB9XG5cbiAgaWYgKHR5cGVvZiBidG9hID09PSBcImZ1bmN0aW9uXCIpIHtcbiAgICB2YXIgYmFzZTY0ID0gYnRvYSh1bmVzY2FwZShlbmNvZGVVUklDb21wb25lbnQoSlNPTi5zdHJpbmdpZnkoY3NzTWFwcGluZykpKSk7XG4gICAgdmFyIGRhdGEgPSBcInNvdXJjZU1hcHBpbmdVUkw9ZGF0YTphcHBsaWNhdGlvbi9qc29uO2NoYXJzZXQ9dXRmLTg7YmFzZTY0LFwiLmNvbmNhdChiYXNlNjQpO1xuICAgIHZhciBzb3VyY2VNYXBwaW5nID0gXCIvKiMgXCIuY29uY2F0KGRhdGEsIFwiICovXCIpO1xuICAgIHZhciBzb3VyY2VVUkxzID0gY3NzTWFwcGluZy5zb3VyY2VzLm1hcChmdW5jdGlvbiAoc291cmNlKSB7XG4gICAgICByZXR1cm4gXCIvKiMgc291cmNlVVJMPVwiLmNvbmNhdChjc3NNYXBwaW5nLnNvdXJjZVJvb3QgfHwgXCJcIikuY29uY2F0KHNvdXJjZSwgXCIgKi9cIik7XG4gICAgfSk7XG4gICAgcmV0dXJuIFtjb250ZW50XS5jb25jYXQoc291cmNlVVJMcykuY29uY2F0KFtzb3VyY2VNYXBwaW5nXSkuam9pbihcIlxcblwiKTtcbiAgfVxuXG4gIHJldHVybiBbY29udGVudF0uam9pbihcIlxcblwiKTtcbn07IiwiXG4gICAgICBpbXBvcnQgQVBJIGZyb20gXCIhLi4vbm9kZV9tb2R1bGVzL3N0eWxlLWxvYWRlci9kaXN0L3J1bnRpbWUvaW5qZWN0U3R5bGVzSW50b1N0eWxlVGFnLmpzXCI7XG4gICAgICBpbXBvcnQgZG9tQVBJIGZyb20gXCIhLi4vbm9kZV9tb2R1bGVzL3N0eWxlLWxvYWRlci9kaXN0L3J1bnRpbWUvc3R5bGVEb21BUEkuanNcIjtcbiAgICAgIGltcG9ydCBpbnNlcnRGbiBmcm9tIFwiIS4uL25vZGVfbW9kdWxlcy9zdHlsZS1sb2FkZXIvZGlzdC9ydW50aW1lL2luc2VydEJ5U2VsZWN0b3IuanNcIjtcbiAgICAgIGltcG9ydCBzZXRBdHRyaWJ1dGVzIGZyb20gXCIhLi4vbm9kZV9tb2R1bGVzL3N0eWxlLWxvYWRlci9kaXN0L3J1bnRpbWUvc2V0QXR0cmlidXRlc1dpdGhvdXRBdHRyaWJ1dGVzLmpzXCI7XG4gICAgICBpbXBvcnQgaW5zZXJ0U3R5bGVFbGVtZW50IGZyb20gXCIhLi4vbm9kZV9tb2R1bGVzL3N0eWxlLWxvYWRlci9kaXN0L3J1bnRpbWUvaW5zZXJ0U3R5bGVFbGVtZW50LmpzXCI7XG4gICAgICBpbXBvcnQgc3R5bGVUYWdUcmFuc2Zvcm1GbiBmcm9tIFwiIS4uL25vZGVfbW9kdWxlcy9zdHlsZS1sb2FkZXIvZGlzdC9ydW50aW1lL3N0eWxlVGFnVHJhbnNmb3JtLmpzXCI7XG4gICAgICBpbXBvcnQgY29udGVudCwgKiBhcyBuYW1lZEV4cG9ydCBmcm9tIFwiISEuLi9ub2RlX21vZHVsZXMvY3NzLWxvYWRlci9kaXN0L2Nqcy5qcyEuL3N0eWxlLmNzc1wiO1xuICAgICAgXG4gICAgICBcblxudmFyIG9wdGlvbnMgPSB7fTtcblxub3B0aW9ucy5zdHlsZVRhZ1RyYW5zZm9ybSA9IHN0eWxlVGFnVHJhbnNmb3JtRm47XG5vcHRpb25zLnNldEF0dHJpYnV0ZXMgPSBzZXRBdHRyaWJ1dGVzO1xuXG4gICAgICBvcHRpb25zLmluc2VydCA9IGluc2VydEZuLmJpbmQobnVsbCwgXCJoZWFkXCIpO1xuICAgIFxub3B0aW9ucy5kb21BUEkgPSBkb21BUEk7XG5vcHRpb25zLmluc2VydFN0eWxlRWxlbWVudCA9IGluc2VydFN0eWxlRWxlbWVudDtcblxudmFyIHVwZGF0ZSA9IEFQSShjb250ZW50LCBvcHRpb25zKTtcblxuXG5cbmV4cG9ydCAqIGZyb20gXCIhIS4uL25vZGVfbW9kdWxlcy9jc3MtbG9hZGVyL2Rpc3QvY2pzLmpzIS4vc3R5bGUuY3NzXCI7XG4gICAgICAgZXhwb3J0IGRlZmF1bHQgY29udGVudCAmJiBjb250ZW50LmxvY2FscyA/IGNvbnRlbnQubG9jYWxzIDogdW5kZWZpbmVkO1xuIiwiXCJ1c2Ugc3RyaWN0XCI7XG5cbnZhciBzdHlsZXNJbkRPTSA9IFtdO1xuXG5mdW5jdGlvbiBnZXRJbmRleEJ5SWRlbnRpZmllcihpZGVudGlmaWVyKSB7XG4gIHZhciByZXN1bHQgPSAtMTtcblxuICBmb3IgKHZhciBpID0gMDsgaSA8IHN0eWxlc0luRE9NLmxlbmd0aDsgaSsrKSB7XG4gICAgaWYgKHN0eWxlc0luRE9NW2ldLmlkZW50aWZpZXIgPT09IGlkZW50aWZpZXIpIHtcbiAgICAgIHJlc3VsdCA9IGk7XG4gICAgICBicmVhaztcbiAgICB9XG4gIH1cblxuICByZXR1cm4gcmVzdWx0O1xufVxuXG5mdW5jdGlvbiBtb2R1bGVzVG9Eb20obGlzdCwgb3B0aW9ucykge1xuICB2YXIgaWRDb3VudE1hcCA9IHt9O1xuICB2YXIgaWRlbnRpZmllcnMgPSBbXTtcblxuICBmb3IgKHZhciBpID0gMDsgaSA8IGxpc3QubGVuZ3RoOyBpKyspIHtcbiAgICB2YXIgaXRlbSA9IGxpc3RbaV07XG4gICAgdmFyIGlkID0gb3B0aW9ucy5iYXNlID8gaXRlbVswXSArIG9wdGlvbnMuYmFzZSA6IGl0ZW1bMF07XG4gICAgdmFyIGNvdW50ID0gaWRDb3VudE1hcFtpZF0gfHwgMDtcbiAgICB2YXIgaWRlbnRpZmllciA9IFwiXCIuY29uY2F0KGlkLCBcIiBcIikuY29uY2F0KGNvdW50KTtcbiAgICBpZENvdW50TWFwW2lkXSA9IGNvdW50ICsgMTtcbiAgICB2YXIgaW5kZXhCeUlkZW50aWZpZXIgPSBnZXRJbmRleEJ5SWRlbnRpZmllcihpZGVudGlmaWVyKTtcbiAgICB2YXIgb2JqID0ge1xuICAgICAgY3NzOiBpdGVtWzFdLFxuICAgICAgbWVkaWE6IGl0ZW1bMl0sXG4gICAgICBzb3VyY2VNYXA6IGl0ZW1bM10sXG4gICAgICBzdXBwb3J0czogaXRlbVs0XSxcbiAgICAgIGxheWVyOiBpdGVtWzVdXG4gICAgfTtcblxuICAgIGlmIChpbmRleEJ5SWRlbnRpZmllciAhPT0gLTEpIHtcbiAgICAgIHN0eWxlc0luRE9NW2luZGV4QnlJZGVudGlmaWVyXS5yZWZlcmVuY2VzKys7XG4gICAgICBzdHlsZXNJbkRPTVtpbmRleEJ5SWRlbnRpZmllcl0udXBkYXRlcihvYmopO1xuICAgIH0gZWxzZSB7XG4gICAgICB2YXIgdXBkYXRlciA9IGFkZEVsZW1lbnRTdHlsZShvYmosIG9wdGlvbnMpO1xuICAgICAgb3B0aW9ucy5ieUluZGV4ID0gaTtcbiAgICAgIHN0eWxlc0luRE9NLnNwbGljZShpLCAwLCB7XG4gICAgICAgIGlkZW50aWZpZXI6IGlkZW50aWZpZXIsXG4gICAgICAgIHVwZGF0ZXI6IHVwZGF0ZXIsXG4gICAgICAgIHJlZmVyZW5jZXM6IDFcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIGlkZW50aWZpZXJzLnB1c2goaWRlbnRpZmllcik7XG4gIH1cblxuICByZXR1cm4gaWRlbnRpZmllcnM7XG59XG5cbmZ1bmN0aW9uIGFkZEVsZW1lbnRTdHlsZShvYmosIG9wdGlvbnMpIHtcbiAgdmFyIGFwaSA9IG9wdGlvbnMuZG9tQVBJKG9wdGlvbnMpO1xuICBhcGkudXBkYXRlKG9iaik7XG5cbiAgdmFyIHVwZGF0ZXIgPSBmdW5jdGlvbiB1cGRhdGVyKG5ld09iaikge1xuICAgIGlmIChuZXdPYmopIHtcbiAgICAgIGlmIChuZXdPYmouY3NzID09PSBvYmouY3NzICYmIG5ld09iai5tZWRpYSA9PT0gb2JqLm1lZGlhICYmIG5ld09iai5zb3VyY2VNYXAgPT09IG9iai5zb3VyY2VNYXAgJiYgbmV3T2JqLnN1cHBvcnRzID09PSBvYmouc3VwcG9ydHMgJiYgbmV3T2JqLmxheWVyID09PSBvYmoubGF5ZXIpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBhcGkudXBkYXRlKG9iaiA9IG5ld09iaik7XG4gICAgfSBlbHNlIHtcbiAgICAgIGFwaS5yZW1vdmUoKTtcbiAgICB9XG4gIH07XG5cbiAgcmV0dXJuIHVwZGF0ZXI7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKGxpc3QsIG9wdGlvbnMpIHtcbiAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge307XG4gIGxpc3QgPSBsaXN0IHx8IFtdO1xuICB2YXIgbGFzdElkZW50aWZpZXJzID0gbW9kdWxlc1RvRG9tKGxpc3QsIG9wdGlvbnMpO1xuICByZXR1cm4gZnVuY3Rpb24gdXBkYXRlKG5ld0xpc3QpIHtcbiAgICBuZXdMaXN0ID0gbmV3TGlzdCB8fCBbXTtcblxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbGFzdElkZW50aWZpZXJzLmxlbmd0aDsgaSsrKSB7XG4gICAgICB2YXIgaWRlbnRpZmllciA9IGxhc3RJZGVudGlmaWVyc1tpXTtcbiAgICAgIHZhciBpbmRleCA9IGdldEluZGV4QnlJZGVudGlmaWVyKGlkZW50aWZpZXIpO1xuICAgICAgc3R5bGVzSW5ET01baW5kZXhdLnJlZmVyZW5jZXMtLTtcbiAgICB9XG5cbiAgICB2YXIgbmV3TGFzdElkZW50aWZpZXJzID0gbW9kdWxlc1RvRG9tKG5ld0xpc3QsIG9wdGlvbnMpO1xuXG4gICAgZm9yICh2YXIgX2kgPSAwOyBfaSA8IGxhc3RJZGVudGlmaWVycy5sZW5ndGg7IF9pKyspIHtcbiAgICAgIHZhciBfaWRlbnRpZmllciA9IGxhc3RJZGVudGlmaWVyc1tfaV07XG5cbiAgICAgIHZhciBfaW5kZXggPSBnZXRJbmRleEJ5SWRlbnRpZmllcihfaWRlbnRpZmllcik7XG5cbiAgICAgIGlmIChzdHlsZXNJbkRPTVtfaW5kZXhdLnJlZmVyZW5jZXMgPT09IDApIHtcbiAgICAgICAgc3R5bGVzSW5ET01bX2luZGV4XS51cGRhdGVyKCk7XG5cbiAgICAgICAgc3R5bGVzSW5ET00uc3BsaWNlKF9pbmRleCwgMSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgbGFzdElkZW50aWZpZXJzID0gbmV3TGFzdElkZW50aWZpZXJzO1xuICB9O1xufTsiLCJcInVzZSBzdHJpY3RcIjtcblxudmFyIG1lbW8gPSB7fTtcbi8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICAqL1xuXG5mdW5jdGlvbiBnZXRUYXJnZXQodGFyZ2V0KSB7XG4gIGlmICh0eXBlb2YgbWVtb1t0YXJnZXRdID09PSBcInVuZGVmaW5lZFwiKSB7XG4gICAgdmFyIHN0eWxlVGFyZ2V0ID0gZG9jdW1lbnQucXVlcnlTZWxlY3Rvcih0YXJnZXQpOyAvLyBTcGVjaWFsIGNhc2UgdG8gcmV0dXJuIGhlYWQgb2YgaWZyYW1lIGluc3RlYWQgb2YgaWZyYW1lIGl0c2VsZlxuXG4gICAgaWYgKHdpbmRvdy5IVE1MSUZyYW1lRWxlbWVudCAmJiBzdHlsZVRhcmdldCBpbnN0YW5jZW9mIHdpbmRvdy5IVE1MSUZyYW1lRWxlbWVudCkge1xuICAgICAgdHJ5IHtcbiAgICAgICAgLy8gVGhpcyB3aWxsIHRocm93IGFuIGV4Y2VwdGlvbiBpZiBhY2Nlc3MgdG8gaWZyYW1lIGlzIGJsb2NrZWRcbiAgICAgICAgLy8gZHVlIHRvIGNyb3NzLW9yaWdpbiByZXN0cmljdGlvbnNcbiAgICAgICAgc3R5bGVUYXJnZXQgPSBzdHlsZVRhcmdldC5jb250ZW50RG9jdW1lbnQuaGVhZDtcbiAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgLy8gaXN0YW5idWwgaWdub3JlIG5leHRcbiAgICAgICAgc3R5bGVUYXJnZXQgPSBudWxsO1xuICAgICAgfVxuICAgIH1cblxuICAgIG1lbW9bdGFyZ2V0XSA9IHN0eWxlVGFyZ2V0O1xuICB9XG5cbiAgcmV0dXJuIG1lbW9bdGFyZ2V0XTtcbn1cbi8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICAqL1xuXG5cbmZ1bmN0aW9uIGluc2VydEJ5U2VsZWN0b3IoaW5zZXJ0LCBzdHlsZSkge1xuICB2YXIgdGFyZ2V0ID0gZ2V0VGFyZ2V0KGluc2VydCk7XG5cbiAgaWYgKCF0YXJnZXQpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXCJDb3VsZG4ndCBmaW5kIGEgc3R5bGUgdGFyZ2V0LiBUaGlzIHByb2JhYmx5IG1lYW5zIHRoYXQgdGhlIHZhbHVlIGZvciB0aGUgJ2luc2VydCcgcGFyYW1ldGVyIGlzIGludmFsaWQuXCIpO1xuICB9XG5cbiAgdGFyZ2V0LmFwcGVuZENoaWxkKHN0eWxlKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBpbnNlcnRCeVNlbGVjdG9yOyIsIlwidXNlIHN0cmljdFwiO1xuXG4vKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAgKi9cbmZ1bmN0aW9uIGluc2VydFN0eWxlRWxlbWVudChvcHRpb25zKSB7XG4gIHZhciBlbGVtZW50ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcInN0eWxlXCIpO1xuICBvcHRpb25zLnNldEF0dHJpYnV0ZXMoZWxlbWVudCwgb3B0aW9ucy5hdHRyaWJ1dGVzKTtcbiAgb3B0aW9ucy5pbnNlcnQoZWxlbWVudCwgb3B0aW9ucy5vcHRpb25zKTtcbiAgcmV0dXJuIGVsZW1lbnQ7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gaW5zZXJ0U3R5bGVFbGVtZW50OyIsIlwidXNlIHN0cmljdFwiO1xuXG4vKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAgKi9cbmZ1bmN0aW9uIHNldEF0dHJpYnV0ZXNXaXRob3V0QXR0cmlidXRlcyhzdHlsZUVsZW1lbnQpIHtcbiAgdmFyIG5vbmNlID0gdHlwZW9mIF9fd2VicGFja19ub25jZV9fICE9PSBcInVuZGVmaW5lZFwiID8gX193ZWJwYWNrX25vbmNlX18gOiBudWxsO1xuXG4gIGlmIChub25jZSkge1xuICAgIHN0eWxlRWxlbWVudC5zZXRBdHRyaWJ1dGUoXCJub25jZVwiLCBub25jZSk7XG4gIH1cbn1cblxubW9kdWxlLmV4cG9ydHMgPSBzZXRBdHRyaWJ1dGVzV2l0aG91dEF0dHJpYnV0ZXM7IiwiXCJ1c2Ugc3RyaWN0XCI7XG5cbi8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICAqL1xuZnVuY3Rpb24gYXBwbHkoc3R5bGVFbGVtZW50LCBvcHRpb25zLCBvYmopIHtcbiAgdmFyIGNzcyA9IFwiXCI7XG5cbiAgaWYgKG9iai5zdXBwb3J0cykge1xuICAgIGNzcyArPSBcIkBzdXBwb3J0cyAoXCIuY29uY2F0KG9iai5zdXBwb3J0cywgXCIpIHtcIik7XG4gIH1cblxuICBpZiAob2JqLm1lZGlhKSB7XG4gICAgY3NzICs9IFwiQG1lZGlhIFwiLmNvbmNhdChvYmoubWVkaWEsIFwiIHtcIik7XG4gIH1cblxuICB2YXIgbmVlZExheWVyID0gdHlwZW9mIG9iai5sYXllciAhPT0gXCJ1bmRlZmluZWRcIjtcblxuICBpZiAobmVlZExheWVyKSB7XG4gICAgY3NzICs9IFwiQGxheWVyXCIuY29uY2F0KG9iai5sYXllci5sZW5ndGggPiAwID8gXCIgXCIuY29uY2F0KG9iai5sYXllcikgOiBcIlwiLCBcIiB7XCIpO1xuICB9XG5cbiAgY3NzICs9IG9iai5jc3M7XG5cbiAgaWYgKG5lZWRMYXllcikge1xuICAgIGNzcyArPSBcIn1cIjtcbiAgfVxuXG4gIGlmIChvYmoubWVkaWEpIHtcbiAgICBjc3MgKz0gXCJ9XCI7XG4gIH1cblxuICBpZiAob2JqLnN1cHBvcnRzKSB7XG4gICAgY3NzICs9IFwifVwiO1xuICB9XG5cbiAgdmFyIHNvdXJjZU1hcCA9IG9iai5zb3VyY2VNYXA7XG5cbiAgaWYgKHNvdXJjZU1hcCAmJiB0eXBlb2YgYnRvYSAhPT0gXCJ1bmRlZmluZWRcIikge1xuICAgIGNzcyArPSBcIlxcbi8qIyBzb3VyY2VNYXBwaW5nVVJMPWRhdGE6YXBwbGljYXRpb24vanNvbjtiYXNlNjQsXCIuY29uY2F0KGJ0b2EodW5lc2NhcGUoZW5jb2RlVVJJQ29tcG9uZW50KEpTT04uc3RyaW5naWZ5KHNvdXJjZU1hcCkpKSksIFwiICovXCIpO1xuICB9IC8vIEZvciBvbGQgSUVcblxuICAvKiBpc3RhbmJ1bCBpZ25vcmUgaWYgICovXG5cblxuICBvcHRpb25zLnN0eWxlVGFnVHJhbnNmb3JtKGNzcywgc3R5bGVFbGVtZW50LCBvcHRpb25zLm9wdGlvbnMpO1xufVxuXG5mdW5jdGlvbiByZW1vdmVTdHlsZUVsZW1lbnQoc3R5bGVFbGVtZW50KSB7XG4gIC8vIGlzdGFuYnVsIGlnbm9yZSBpZlxuICBpZiAoc3R5bGVFbGVtZW50LnBhcmVudE5vZGUgPT09IG51bGwpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICBzdHlsZUVsZW1lbnQucGFyZW50Tm9kZS5yZW1vdmVDaGlsZChzdHlsZUVsZW1lbnQpO1xufVxuLyogaXN0YW5idWwgaWdub3JlIG5leHQgICovXG5cblxuZnVuY3Rpb24gZG9tQVBJKG9wdGlvbnMpIHtcbiAgdmFyIHN0eWxlRWxlbWVudCA9IG9wdGlvbnMuaW5zZXJ0U3R5bGVFbGVtZW50KG9wdGlvbnMpO1xuICByZXR1cm4ge1xuICAgIHVwZGF0ZTogZnVuY3Rpb24gdXBkYXRlKG9iaikge1xuICAgICAgYXBwbHkoc3R5bGVFbGVtZW50LCBvcHRpb25zLCBvYmopO1xuICAgIH0sXG4gICAgcmVtb3ZlOiBmdW5jdGlvbiByZW1vdmUoKSB7XG4gICAgICByZW1vdmVTdHlsZUVsZW1lbnQoc3R5bGVFbGVtZW50KTtcbiAgICB9XG4gIH07XG59XG5cbm1vZHVsZS5leHBvcnRzID0gZG9tQVBJOyIsIlwidXNlIHN0cmljdFwiO1xuXG4vKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAgKi9cbmZ1bmN0aW9uIHN0eWxlVGFnVHJhbnNmb3JtKGNzcywgc3R5bGVFbGVtZW50KSB7XG4gIGlmIChzdHlsZUVsZW1lbnQuc3R5bGVTaGVldCkge1xuICAgIHN0eWxlRWxlbWVudC5zdHlsZVNoZWV0LmNzc1RleHQgPSBjc3M7XG4gIH0gZWxzZSB7XG4gICAgd2hpbGUgKHN0eWxlRWxlbWVudC5maXJzdENoaWxkKSB7XG4gICAgICBzdHlsZUVsZW1lbnQucmVtb3ZlQ2hpbGQoc3R5bGVFbGVtZW50LmZpcnN0Q2hpbGQpO1xuICAgIH1cblxuICAgIHN0eWxlRWxlbWVudC5hcHBlbmRDaGlsZChkb2N1bWVudC5jcmVhdGVUZXh0Tm9kZShjc3MpKTtcbiAgfVxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHN0eWxlVGFnVHJhbnNmb3JtOyIsIi8qIGVzbGludC1kaXNhYmxlIG5vLXVzZS1iZWZvcmUtZGVmaW5lICovXHJcbmNvbnN0IGl0ZW1zID0gW107XHJcbmNvbnN0IGZvcm0gPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcuZm9ybS1lbGVtZW50Jyk7XHJcbmNvbnN0IGRpc3BsYXlUYXNrID0gKCkgPT4ge1xyXG4gIGNvbnN0IGNvbnRhaW5lciA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJy5saXN0LWNvbnRhaW5lcicpO1xyXG4gIGZvcm0uYWRkRXZlbnRMaXN0ZW5lcignc3VibWl0JywgKGV2ZW50KSA9PiB7XHJcbiAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xyXG4gICAgY29uc3QgZGF0YSA9IGZvcm0uZWxlbWVudHNbMF0udmFsdWU7XHJcbiAgICBjb25zdCBvYmplY3QgPSB7XHJcbiAgICAgIGRlc2NyaXB0aW9uOiBkYXRhLFxyXG4gICAgICBjb21wbGV0ZWQ6IGZhbHNlLFxyXG4gICAgICBpbmRleDogaXRlbXMubGVuZ3RoICsgMSxcclxuICAgIH07XHJcbiAgICBmb3JtLnJlc2V0KCk7XHJcbiAgICBpdGVtcy5wdXNoKG9iamVjdCk7XHJcbiAgICBsb2NhbFN0b3JhZ2Uuc2V0SXRlbSgnaXRlbXNMb2NhbCcsIEpTT04uc3RyaW5naWZ5KGl0ZW1zKSk7XHJcbiAgICByZW5kZXIoKTtcclxuICB9KTtcclxuICBjb25zdCBjbGVhckVsZW1lbnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdwJyk7XHJcbiAgY2xlYXJFbGVtZW50LmNsYXNzTmFtZSA9ICdjbGVhcic7XHJcbiAgY2xlYXJFbGVtZW50LmlubmVyVGV4dCA9ICdDbGVhciBhbGwgY29tcGxldGVkJztcclxuICBjb250YWluZXIuYXBwZW5kQ2hpbGQoY2xlYXJFbGVtZW50KTtcclxuICBjb25zdCBjbGVhciA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJy5jbGVhcicpO1xyXG4gIGNvbnN0IGxpc3QgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCd1bCcpO1xyXG4gIGxpc3QuY2xhc3NOYW1lID0gJ3VsLWxpc3QnO1xyXG4gIGNvbnRhaW5lci5pbnNlcnRCZWZvcmUobGlzdCwgY2xlYXIpO1xyXG59O1xyXG5cclxuY29uc3QgcmVtb3ZlSXRlbSA9ICgpID0+IHtcclxuICBjb25zdCBidXR0b24gPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKCcuZmEtdHJhc2gtYWx0Jyk7XHJcbiAgYnV0dG9uLmZvckVhY2goKGl0ZW0pID0+IHtcclxuICAgIGNvbnN0IHBhcmVudCA9IGl0ZW0ucGFyZW50Tm9kZTtcclxuICAgIGNvbnN0IHN1cGVyUGFyZW50ID0gcGFyZW50LnBhcmVudE5vZGU7XHJcbiAgICBjb25zdCBpbmRleCA9IEFycmF5LnByb3RvdHlwZS5pbmRleE9mLmNhbGwoc3VwZXJQYXJlbnQuY2hpbGRyZW4sIHBhcmVudCk7XHJcbiAgICBjb25zdCBsaXN0SW5wdXQgPSBwYXJlbnQuZmlyc3RDaGlsZDtcclxuICAgIGl0ZW0uYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCAoKSA9PiB7XHJcbiAgICAgIGNvbnN0IGl0ZW1zTG9jYWwgPSBKU09OLnBhcnNlKGxvY2FsU3RvcmFnZS5nZXRJdGVtKCdpdGVtc0xvY2FsJykpO1xyXG4gICAgICBpdGVtcy5zcGxpY2UoMCwgaXRlbXMubGVuZ3RoLCAuLi5pdGVtc0xvY2FsKTtcclxuICAgICAgaWYgKGxpc3RJbnB1dC5oYXNBdHRyaWJ1dGUoJ2NoZWNrZWQnKSkge1xyXG4gICAgICAgIHBhcmVudC5yZW1vdmUoKTtcclxuICAgICAgICBpdGVtcy5zcGxpY2UoaW5kZXgsIDEpO1xyXG4gICAgICB9XHJcbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgaXRlbXMubGVuZ3RoOyBpICs9IDEpIHtcclxuICAgICAgICBpdGVtc1tpXS5pbmRleCA9IGkgKyAxO1xyXG4gICAgICB9XHJcbiAgICAgIGxvY2FsU3RvcmFnZS5zZXRJdGVtKCdpdGVtc0xvY2FsJywgSlNPTi5zdHJpbmdpZnkoaXRlbXMpKTtcclxuICAgICAgcmVuZGVyKCk7XHJcbiAgICB9KTtcclxuICB9KTtcclxufTtcclxuXHJcbmNvbnN0IGNsZWFyTGlzdCA9ICgpID0+IHtcclxuICBjb25zdCBnZXRDbGVhckVsZW1lbnQgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcuY2xlYXInKTtcclxuICBnZXRDbGVhckVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCAoKSA9PiB7XHJcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGl0ZW1zLmxlbmd0aDsgaSArPSAxKSB7XHJcbiAgICAgIGlmIChpdGVtc1tpXS5jb21wbGV0ZWQpIHtcclxuICAgICAgICBpdGVtcy5zcGxpY2UoaSwgMSk7XHJcbiAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGl0ZW1zLmxlbmd0aDsgaSArPSAxKSB7XHJcbiAgICAgIGl0ZW1zW2ldLmluZGV4ID0gaSArIDE7XHJcbiAgICB9XHJcbiAgICBsb2NhbFN0b3JhZ2Uuc2V0SXRlbSgnaXRlbXNMb2NhbCcsIEpTT04uc3RyaW5naWZ5KGl0ZW1zKSk7XHJcbiAgICByZW5kZXIoKTtcclxuICB9KTtcclxufTtcclxuXHJcbmNvbnN0IHVwZGF0ZVZhbHVlcyA9ICgpID0+IHtcclxuICBjb25zdCBpdGVtRGV0YWlscyA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoJy5pdGVtLWRldGFpbHMnKTtcclxuICBpdGVtRGV0YWlscy5mb3JFYWNoKChpdGVtKSA9PiB7XHJcbiAgICBjb25zdCBwYXJlbnQgPSBpdGVtLnBhcmVudE5vZGU7XHJcbiAgICBjb25zdCBzdXBlclBhcmVudCA9IHBhcmVudC5wYXJlbnROb2RlO1xyXG4gICAgY29uc3QgaW5kZXggPSBBcnJheS5wcm90b3R5cGUuaW5kZXhPZi5jYWxsKHN1cGVyUGFyZW50LmNoaWxkcmVuLCBwYXJlbnQpO1xyXG4gICAgaXRlbS5hZGRFdmVudExpc3RlbmVyKCdjaGFuZ2UnLCAoKSA9PiB7XHJcbiAgICAgIGl0ZW1zW2luZGV4XS5kZXNjcmlwdGlvbiA9IGl0ZW0udmFsdWU7XHJcbiAgICAgIGxvY2FsU3RvcmFnZS5zZXRJdGVtKCdpdGVtc0xvY2FsJywgSlNPTi5zdHJpbmdpZnkoaXRlbXMpKTtcclxuICAgIH0pO1xyXG4gIH0pO1xyXG59O1xyXG5cclxuY29uc3QgdGV4dERlY29yYXRpb24gPSAobGlzdElucHV0KSA9PiB7XHJcbiAgbGlzdElucHV0LmZvckVhY2goKGl0ZW0pID0+IHtcclxuICAgIGlmIChpdGVtLmhhc0F0dHJpYnV0ZSgnY2hlY2tlZCcpKSB7XHJcbiAgICAgIGl0ZW0ubmV4dFNpYmxpbmcuc3R5bGUudGV4dERlY29yYXRpb24gPSAnbGluZS10aHJvdWdoJztcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIGl0ZW0ubmV4dFNpYmxpbmcuc3R5bGUudGV4dERlY29yYXRpb24gPSAnbm9uZSc7XHJcbiAgICB9XHJcbiAgfSk7XHJcbn07XHJcblxyXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBwb3B1bGF0ZVN0b3JhZ2UoKSB7XHJcbiAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ2xvYWQnLCAoKSA9PiB7XHJcbiAgICByZW5kZXIoKTtcclxuICAgIGNvbnN0IGxpc3RJbnB1dCA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoJy5saXN0LWlucHV0Jyk7XHJcbiAgICBjb25zdCBpdGVtc0xvY2FsID0gSlNPTi5wYXJzZShsb2NhbFN0b3JhZ2UuZ2V0SXRlbSgnaXRlbXNMb2NhbCcpKTtcclxuICAgIGxpc3RJbnB1dC5mb3JFYWNoKChpdGVtKSA9PiB7XHJcbiAgICAgIGNvbnN0IHBhcmVudCA9IGl0ZW0ucGFyZW50Tm9kZTtcclxuICAgICAgY29uc3Qgc3VwZXJQYXJlbnQgPSBwYXJlbnQucGFyZW50Tm9kZTtcclxuICAgICAgY29uc3QgaW5kZXggPSBBcnJheS5wcm90b3R5cGUuaW5kZXhPZi5jYWxsKHN1cGVyUGFyZW50LmNoaWxkcmVuLCBwYXJlbnQpO1xyXG4gICAgICBjb25zdCBjdXJyZW50SXRlbSA9IGl0ZW1zTG9jYWxbaW5kZXhdLmNvbXBsZXRlZDtcclxuICAgICAgaWYgKGN1cnJlbnRJdGVtKSB7XHJcbiAgICAgICAgaXRlbS5zZXRBdHRyaWJ1dGUoJ2NoZWNrZWQnLCAnJyk7XHJcbiAgICAgICAgcGFyZW50Lmxhc3RDaGlsZC5zdHlsZS5kaXNwbGF5ID0gJ2Jsb2NrJztcclxuICAgICAgfVxyXG4gICAgfSk7XHJcbiAgICB0ZXh0RGVjb3JhdGlvbihsaXN0SW5wdXQpO1xyXG4gIH0pO1xyXG59XHJcblxyXG5mdW5jdGlvbiB1c2VySW50ZXJhY3Rpb24obGlzdElucHV0KSB7XHJcbiAgbGlzdElucHV0LmZvckVhY2goKGl0ZW0pID0+IHtcclxuICAgIGl0ZW0uYWRkRXZlbnRMaXN0ZW5lcignY2hhbmdlJywgKCkgPT4ge1xyXG4gICAgICBjb25zdCBpdGVtc0xvY2FsID0gSlNPTi5wYXJzZShsb2NhbFN0b3JhZ2UuZ2V0SXRlbSgnaXRlbXNMb2NhbCcpKTtcclxuICAgICAgY29uc3QgcGFyZW50ID0gaXRlbS5wYXJlbnROb2RlO1xyXG4gICAgICBjb25zdCBzdXBlclBhcmVudCA9IHBhcmVudC5wYXJlbnROb2RlO1xyXG4gICAgICBjb25zdCBpbmRleCA9IEFycmF5LnByb3RvdHlwZS5pbmRleE9mLmNhbGwoc3VwZXJQYXJlbnQuY2hpbGRyZW4sIHBhcmVudCk7XHJcbiAgICAgIGNvbnN0IGN1cnJlbnRJdGVtID0gaXRlbXNMb2NhbFtpbmRleF0uY29tcGxldGVkO1xyXG4gICAgICBpZiAoY3VycmVudEl0ZW0pIHtcclxuICAgICAgICBpdGVtLnJlbW92ZUF0dHJpYnV0ZSgnY2hlY2tlZCcpO1xyXG4gICAgICAgIHBhcmVudC5sYXN0Q2hpbGQuc3R5bGUuZGlzcGxheSA9ICdub25lJztcclxuICAgICAgICBpdGVtc0xvY2FsW2luZGV4XS5jb21wbGV0ZWQgPSBmYWxzZTtcclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICBpdGVtLnNldEF0dHJpYnV0ZSgnY2hlY2tlZCcsICcnKTtcclxuICAgICAgICBwYXJlbnQubGFzdENoaWxkLnN0eWxlLmRpc3BsYXkgPSAnYmxvY2snO1xyXG4gICAgICAgIGl0ZW1zTG9jYWxbaW5kZXhdLmNvbXBsZXRlZCA9IHRydWU7XHJcbiAgICAgIH1cclxuICAgICAgdGV4dERlY29yYXRpb24obGlzdElucHV0KTtcclxuICAgICAgbG9jYWxTdG9yYWdlLnNldEl0ZW0oJ2l0ZW1zTG9jYWwnLCBKU09OLnN0cmluZ2lmeShpdGVtc0xvY2FsKSk7XHJcbiAgICAgIGl0ZW1zLnNwbGljZSgwLCBpdGVtcy5sZW5ndGgsIC4uLml0ZW1zTG9jYWwpO1xyXG4gICAgfSk7XHJcbiAgfSk7XHJcbn1cclxuXHJcbmNvbnN0IHJlbmRlciA9ICgpID0+IHtcclxuICBjb25zdCBsaXN0ID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignLnVsLWxpc3QnKTtcclxuICBjb25zdCBpdGVtc0xvY2FsID0gSlNPTi5wYXJzZShsb2NhbFN0b3JhZ2UuZ2V0SXRlbSgnaXRlbXNMb2NhbCcpKTtcclxuICBpdGVtcy5zcGxpY2UoMCwgaXRlbXMubGVuZ3RoLCAuLi5pdGVtc0xvY2FsKTtcclxuICBsaXN0LmlubmVySFRNTCA9ICcnO1xyXG4gIGZvciAobGV0IGkgPSAwOyBpIDwgaXRlbXNMb2NhbC5sZW5ndGg7IGkgKz0gMSkge1xyXG4gICAgY29uc3QgeyBkZXNjcmlwdGlvbiB9ID0gaXRlbXNMb2NhbFtpXTtcclxuICAgIGNvbnN0IGxpc3RJdGVtID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnbGknKTtcclxuICAgIGxpc3RJdGVtLmNsYXNzTmFtZSA9ICdsaXN0LWl0ZW0nO1xyXG4gICAgbGlzdEl0ZW0uaW5uZXJIVE1MID0gYDxpbnB1dCBjbGFzcz1cImxpc3QtaW5wdXRcIiB0eXBlPVwiY2hlY2tib3hcIj48dGV4dGFyZWEgbmFtZT1cInRleHRhcmVhIGNvbHM9XCIzMFwiIGNsYXNzPVwiaXRlbS1kZXRhaWxzXCI+JHtkZXNjcmlwdGlvbn08L3RleHRhcmVhPjxpIGNsYXNzPVwiZmFzIGZhLXRyYXNoLWFsdFwiPjwvaT5gO1xyXG4gICAgbGlzdC5hcHBlbmRDaGlsZChsaXN0SXRlbSk7XHJcbiAgfVxyXG4gIGNvbnN0IGxpc3RJbnB1dCA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoJy5saXN0LWlucHV0Jyk7XHJcbiAgdXNlckludGVyYWN0aW9uKGxpc3RJbnB1dCk7XHJcbiAgY2xlYXJMaXN0KGxpc3RJbnB1dCk7XHJcbiAgcmVtb3ZlSXRlbSgpO1xyXG4gIHVwZGF0ZVZhbHVlcygpO1xyXG59O1xyXG5cclxuZGlzcGxheVRhc2soKTtcclxuIiwiLy8gVGhlIG1vZHVsZSBjYWNoZVxudmFyIF9fd2VicGFja19tb2R1bGVfY2FjaGVfXyA9IHt9O1xuXG4vLyBUaGUgcmVxdWlyZSBmdW5jdGlvblxuZnVuY3Rpb24gX193ZWJwYWNrX3JlcXVpcmVfXyhtb2R1bGVJZCkge1xuXHQvLyBDaGVjayBpZiBtb2R1bGUgaXMgaW4gY2FjaGVcblx0dmFyIGNhY2hlZE1vZHVsZSA9IF9fd2VicGFja19tb2R1bGVfY2FjaGVfX1ttb2R1bGVJZF07XG5cdGlmIChjYWNoZWRNb2R1bGUgIT09IHVuZGVmaW5lZCkge1xuXHRcdHJldHVybiBjYWNoZWRNb2R1bGUuZXhwb3J0cztcblx0fVxuXHQvLyBDcmVhdGUgYSBuZXcgbW9kdWxlIChhbmQgcHV0IGl0IGludG8gdGhlIGNhY2hlKVxuXHR2YXIgbW9kdWxlID0gX193ZWJwYWNrX21vZHVsZV9jYWNoZV9fW21vZHVsZUlkXSA9IHtcblx0XHRpZDogbW9kdWxlSWQsXG5cdFx0Ly8gbm8gbW9kdWxlLmxvYWRlZCBuZWVkZWRcblx0XHRleHBvcnRzOiB7fVxuXHR9O1xuXG5cdC8vIEV4ZWN1dGUgdGhlIG1vZHVsZSBmdW5jdGlvblxuXHRfX3dlYnBhY2tfbW9kdWxlc19fW21vZHVsZUlkXShtb2R1bGUsIG1vZHVsZS5leHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKTtcblxuXHQvLyBSZXR1cm4gdGhlIGV4cG9ydHMgb2YgdGhlIG1vZHVsZVxuXHRyZXR1cm4gbW9kdWxlLmV4cG9ydHM7XG59XG5cbiIsIi8vIGdldERlZmF1bHRFeHBvcnQgZnVuY3Rpb24gZm9yIGNvbXBhdGliaWxpdHkgd2l0aCBub24taGFybW9ueSBtb2R1bGVzXG5fX3dlYnBhY2tfcmVxdWlyZV9fLm4gPSAobW9kdWxlKSA9PiB7XG5cdHZhciBnZXR0ZXIgPSBtb2R1bGUgJiYgbW9kdWxlLl9fZXNNb2R1bGUgP1xuXHRcdCgpID0+IChtb2R1bGVbJ2RlZmF1bHQnXSkgOlxuXHRcdCgpID0+IChtb2R1bGUpO1xuXHRfX3dlYnBhY2tfcmVxdWlyZV9fLmQoZ2V0dGVyLCB7IGE6IGdldHRlciB9KTtcblx0cmV0dXJuIGdldHRlcjtcbn07IiwiLy8gZGVmaW5lIGdldHRlciBmdW5jdGlvbnMgZm9yIGhhcm1vbnkgZXhwb3J0c1xuX193ZWJwYWNrX3JlcXVpcmVfXy5kID0gKGV4cG9ydHMsIGRlZmluaXRpb24pID0+IHtcblx0Zm9yKHZhciBrZXkgaW4gZGVmaW5pdGlvbikge1xuXHRcdGlmKF9fd2VicGFja19yZXF1aXJlX18ubyhkZWZpbml0aW9uLCBrZXkpICYmICFfX3dlYnBhY2tfcmVxdWlyZV9fLm8oZXhwb3J0cywga2V5KSkge1xuXHRcdFx0T2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIGtleSwgeyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGRlZmluaXRpb25ba2V5XSB9KTtcblx0XHR9XG5cdH1cbn07IiwiX193ZWJwYWNrX3JlcXVpcmVfXy5vID0gKG9iaiwgcHJvcCkgPT4gKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChvYmosIHByb3ApKSIsIi8vIGRlZmluZSBfX2VzTW9kdWxlIG9uIGV4cG9ydHNcbl9fd2VicGFja19yZXF1aXJlX18uciA9IChleHBvcnRzKSA9PiB7XG5cdGlmKHR5cGVvZiBTeW1ib2wgIT09ICd1bmRlZmluZWQnICYmIFN5bWJvbC50b1N0cmluZ1RhZykge1xuXHRcdE9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBTeW1ib2wudG9TdHJpbmdUYWcsIHsgdmFsdWU6ICdNb2R1bGUnIH0pO1xuXHR9XG5cdE9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCAnX19lc01vZHVsZScsIHsgdmFsdWU6IHRydWUgfSk7XG59OyIsImltcG9ydCAnLi9zdHlsZS5jc3MnO1xyXG5pbXBvcnQgcG9wdWxhdGVTdG9yYWdlIGZyb20gJy4vdXRpbHMvc3RydWN0dXJlLmpzJztcclxuXHJcbnBvcHVsYXRlU3RvcmFnZSgpO1xyXG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0= -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "webpack-demo", 3 | "version": "1.0.0", 4 | "description": "", 5 | "private": true, 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1", 8 | "watch": "webpack --watch", 9 | "start": "webpack serve --open", 10 | "build": "webpack" 11 | }, 12 | "keywords": [], 13 | "author": "", 14 | "license": "MIT", 15 | "devDependencies": { 16 | "babel-eslint": "^10.1.0", 17 | "css-loader": "^6.5.1", 18 | "eslint": "^7.32.0", 19 | "eslint-config-airbnb-base": "^14.2.1", 20 | "eslint-plugin-import": "^2.25.3", 21 | "html-webpack-plugin": "^5.5.0", 22 | "style-loader": "^3.3.1", 23 | "webpack": "^5.64.4", 24 | "webpack-cli": "^4.9.1", 25 | "webpack-dev-server": "^4.6.0" 26 | }, 27 | "dependencies": { 28 | "lodash": "^4.17.21" 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/images/Screenshot1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thecodechaser/todo-list-code-review/2bec7087a1d210edb7efab4c26a30fd910ba0821/src/images/Screenshot1.png -------------------------------------------------------------------------------- /src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 13 | To Do List 14 | 15 | 16 |
17 |
18 |

Today's To Do

19 | 20 |
21 |
22 |
23 | 24 | 25 |
26 |
27 |
28 |
29 |
30 | 31 | 32 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | import './style.css'; 2 | import populateStorage from './utils/structure.js'; 3 | 4 | populateStorage(); 5 | -------------------------------------------------------------------------------- /src/style.css: -------------------------------------------------------------------------------- 1 | /* stylesheet */ 2 | @import url("https://fonts.googleapis.com/css2?family=Poppins&display=swap"); 3 | 4 | body { 5 | font-family: "Poppins", sans-serif; 6 | } 7 | 8 | .main-container { 9 | border: 3px solid #dfe1e6; 10 | margin: 30px 20px 0 20px; 11 | box-shadow: 5px 5px #dfe1e6; 12 | } 13 | 14 | .list-head { 15 | display: flex; 16 | justify-content: space-between; 17 | margin: 0 10px; 18 | } 19 | 20 | hr { 21 | height: 1px; 22 | background-color: #dfe1e6; 23 | border: none; 24 | margin: 0; 25 | } 26 | 27 | form { 28 | display: flex; 29 | } 30 | 31 | .fa-level-down-alt { 32 | font-size: 20px; 33 | color: rgba(5, 5, 5, 0.507); 34 | } 35 | 36 | .form-input { 37 | font-style: italic; 38 | padding: 10px; 39 | border: none; 40 | width: 90%; 41 | outline: none; 42 | } 43 | 44 | .main-heading { 45 | font-weight: 100; 46 | font-size: 18px; 47 | color: rgba(0, 0, 0, 0.877); 48 | } 49 | 50 | .fa-sync-alt { 51 | margin-top: 17px; 52 | margin-right: 10px; 53 | color: rgba(5, 5, 5, 0.507); 54 | } 55 | 56 | ul { 57 | padding: 0; 58 | gap: 10px; 59 | display: flex; 60 | flex-direction: column; 61 | list-style-type: none; 62 | } 63 | 64 | .list-item { 65 | display: flex; 66 | gap: 10px; 67 | padding-left: 0; 68 | } 69 | 70 | .list-input { 71 | margin-top: 5px; 72 | transform: scale(1.3); 73 | } 74 | 75 | .item-details { 76 | margin-top: 0; 77 | width: 300px; 78 | border: none; 79 | resize: none; 80 | outline: none; 81 | } 82 | 83 | .fa-trash-alt { 84 | display: none; 85 | margin-left: 150px; 86 | color: rgba(73, 73, 73, 0.726); 87 | } 88 | 89 | .fa-square { 90 | font-size: 18px; 91 | margin-top: 18px; 92 | color: rgb(73, 73, 73); 93 | } 94 | 95 | .clear { 96 | font-size: 18px; 97 | border: none; 98 | color: rgb(87, 80, 80); 99 | background-color: #80808048; 100 | padding: 30px 0; 101 | width: 100%; 102 | cursor: pointer; 103 | } 104 | 105 | @media screen and (min-width: 772px) { 106 | .main-container { 107 | margin: 30px 30vw 0 30vw; 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /src/utils/structure.js: -------------------------------------------------------------------------------- 1 | const items = []; 2 | 3 | const textDecoration = (listInput) => { 4 | listInput.forEach((item) => { 5 | if (item.hasAttribute('checked')) { 6 | item.nextSibling.style.textDecoration = 'line-through'; 7 | } else { 8 | item.nextSibling.style.textDecoration = 'none'; 9 | } 10 | }); 11 | }; 12 | 13 | const userInteraction = (listInput) => { 14 | listInput.forEach((item) => { 15 | item.addEventListener('change', () => { 16 | const itemsLocal = JSON.parse(localStorage.getItem('itemsLocal')); 17 | const parent = item.parentNode; 18 | const superParent = parent.parentNode; 19 | const index = Array.prototype.indexOf.call(superParent.children, parent); 20 | const currentItem = itemsLocal[index].completed; 21 | if (currentItem) { 22 | item.removeAttribute('checked'); 23 | parent.lastChild.style.display = 'none'; 24 | itemsLocal[index].completed = false; 25 | } else { 26 | item.setAttribute('checked', ''); 27 | parent.lastChild.style.display = 'block'; 28 | itemsLocal[index].completed = true; 29 | } 30 | textDecoration(listInput); 31 | localStorage.setItem('itemsLocal', JSON.stringify(itemsLocal)); 32 | items.splice(0, items.length, ...itemsLocal); 33 | }); 34 | }); 35 | }; 36 | 37 | const removeItem = () => { 38 | const button = document.querySelectorAll('.fa-trash-alt'); 39 | button.forEach((item) => { 40 | const parent = item.parentNode; 41 | const superParent = parent.parentNode; 42 | const index = Array.prototype.indexOf.call(superParent.children, parent); 43 | const listInput = parent.firstChild; 44 | item.addEventListener('click', () => { 45 | const itemsLocal = JSON.parse(localStorage.getItem('itemsLocal')); 46 | items.splice(0, items.length, ...itemsLocal); 47 | if (listInput.hasAttribute('checked')) { 48 | parent.remove(); 49 | items.splice(index, 1); 50 | } 51 | for (let i = 0; i < items.length; i += 1) { 52 | items[i].index = i + 1; 53 | } 54 | localStorage.setItem('itemsLocal', JSON.stringify(items)); 55 | }); 56 | }); 57 | }; 58 | 59 | const clearList = () => { 60 | const itemsLocal = JSON.parse(localStorage.getItem('itemsLocal')); 61 | items.splice(0, items.length, ...itemsLocal); 62 | const list = document.querySelector('.ul-list'); 63 | const getClearElement = document.querySelector('.clear'); 64 | getClearElement.addEventListener('click', () => { 65 | for (let i = 0; i < items.length; i += 1) { 66 | if (items[i].completed) { 67 | items.splice(i, 1); 68 | list.childNodes[i].remove(); 69 | } 70 | } 71 | for (let i = 0; i < items.length; i += 1) { 72 | items[i].index = i + 1; 73 | } 74 | localStorage.setItem('itemsLocal', JSON.stringify(items)); 75 | }); 76 | }; 77 | 78 | const updateValues = () => { 79 | const itemDetails = document.querySelectorAll('.item-details'); 80 | itemDetails.forEach((item) => { 81 | const parent = item.parentNode; 82 | const superParent = parent.parentNode; 83 | const index = Array.prototype.indexOf.call(superParent.children, parent); 84 | item.addEventListener('change', () => { 85 | items[index].description = item.value; 86 | localStorage.setItem('itemsLocal', JSON.stringify(items)); 87 | }); 88 | }); 89 | }; 90 | 91 | const render = () => { 92 | const list = document.querySelector('.ul-list'); 93 | const itemsLocal = JSON.parse(localStorage.getItem('itemsLocal')); 94 | items.splice(0, items.length, ...itemsLocal); 95 | list.innerHTML = ''; 96 | for (let i = 0; i < itemsLocal.length; i += 1) { 97 | const { description } = itemsLocal[i]; 98 | const listItem = document.createElement('li'); 99 | listItem.className = 'list-item'; 100 | listItem.innerHTML = ``; 101 | list.appendChild(listItem); 102 | } 103 | const listInput = document.querySelectorAll('.list-input'); 104 | userInteraction(listInput); 105 | removeItem(); 106 | clearList(); 107 | updateValues(); 108 | }; 109 | 110 | const displayTask = () => { 111 | const form = document.querySelector('.form-element'); 112 | const container = document.querySelector('.list-container'); 113 | form.addEventListener('submit', (event) => { 114 | event.preventDefault(); 115 | const data = form.elements[0].value; 116 | const object = { 117 | description: data, 118 | completed: false, 119 | index: items.length + 1, 120 | }; 121 | form.reset(); 122 | items.push(object); 123 | localStorage.setItem('itemsLocal', JSON.stringify(items)); 124 | render(); 125 | }); 126 | const clearElement = document.createElement('button'); 127 | clearElement.className = 'clear'; 128 | clearElement.innerText = 'Clear all completed'; 129 | container.appendChild(clearElement); 130 | const clear = document.querySelector('.clear'); 131 | const list = document.createElement('ul'); 132 | list.className = 'ul-list'; 133 | container.insertBefore(list, clear); 134 | }; 135 | 136 | export default function populateStorage() { 137 | window.addEventListener('load', () => { 138 | render(); 139 | const listInput = document.querySelectorAll('.list-input'); 140 | const itemsLocal = JSON.parse(localStorage.getItem('itemsLocal')); 141 | listInput.forEach((item) => { 142 | const parent = item.parentNode; 143 | const superParent = parent.parentNode; 144 | const index = Array.prototype.indexOf.call(superParent.children, parent); 145 | const currentItem = itemsLocal[index].completed; 146 | if (currentItem) { 147 | item.setAttribute('checked', ''); 148 | parent.lastChild.style.display = 'block'; 149 | } 150 | }); 151 | textDecoration(listInput); 152 | }); 153 | } 154 | 155 | displayTask(); 156 | -------------------------------------------------------------------------------- /webpack.config.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | const HtmlWebpackPlugin = require('html-webpack-plugin'); 3 | 4 | module.exports = { 5 | mode: 'development', 6 | entry: { 7 | index: './src/index.js', 8 | }, 9 | devtool: 'inline-source-map', 10 | devServer: { 11 | static: './dist', 12 | }, 13 | plugins: [ 14 | new HtmlWebpackPlugin({ 15 | template: './src/index.html', 16 | }), 17 | ], 18 | output: { 19 | filename: 'main.js', 20 | path: path.resolve(__dirname, 'dist'), 21 | clean: true, 22 | }, 23 | module: { 24 | rules: [ 25 | { 26 | test: /\.css$/i, 27 | use: ['style-loader', 'css-loader'], 28 | }, 29 | ], 30 | }, 31 | }; 32 | --------------------------------------------------------------------------------