From 44e8c7bdc1bb5318c2f1e4e81602fca92d26bf53 Mon Sep 17 00:00:00 2001 From: Caleb Date: Fri, 3 Nov 2023 16:05:56 +1000 Subject: [PATCH] Convert TS to JS. Added eslint config --- .eslintrc.json | 55 + .gitignore | 2 - .vscode/settings.json | 5 + build.sh | 2 +- index.js | 57 +- package-lock.json | 3640 ++++++++++++++++++++++++++--------------- package.json | 1 + src/api.js | 151 ++ src/cardhandler.js | 75 + src/cardlist.js | 16 + src/dragging.js | 60 + src/index.js | 24 + src/layout.js | 419 +++++ src/task.js | 155 ++ ts-src/api.ts | 131 -- ts-src/cardhandler.ts | 60 - ts-src/cardlist.ts | 17 - ts-src/dragging.ts | 48 - ts-src/index.ts | 22 - ts-src/layout.ts | 362 ---- ts-src/task.ts | 128 -- tsconfig.json | 109 -- webpack.config.js | 14 +- 23 files changed, 3317 insertions(+), 2236 deletions(-) create mode 100644 .eslintrc.json create mode 100644 .vscode/settings.json create mode 100644 src/api.js create mode 100644 src/cardhandler.js create mode 100644 src/cardlist.js create mode 100644 src/dragging.js create mode 100644 src/index.js create mode 100644 src/layout.js create mode 100644 src/task.js delete mode 100644 ts-src/api.ts delete mode 100644 ts-src/cardhandler.ts delete mode 100644 ts-src/cardlist.ts delete mode 100644 ts-src/dragging.ts delete mode 100644 ts-src/index.ts delete mode 100644 ts-src/layout.ts delete mode 100644 ts-src/task.ts delete mode 100644 tsconfig.json diff --git a/.eslintrc.json b/.eslintrc.json new file mode 100644 index 0000000..b114d66 --- /dev/null +++ b/.eslintrc.json @@ -0,0 +1,55 @@ +{ + "env": { + "browser": true, + "es2021": true + }, + "extends": "eslint:recommended", + "parserOptions": { + "ecmaVersion": "latest", + "sourceType": "module" + }, + "rules": { + "indent": [ + "error", + 2 + ], + "linebreak-style": [ + "error", + "unix" + ], + "quotes": [ + "error", + "double" + ], + "semi": [ + "warn", + "always" + ], + "space-before-blocks": [ + "error", + "always" + ], + "arrow-spacing": [ + "error", + { + "before": true, + "after": true + } + ], + "keyword-spacing": [ + "error", + { + "before": true, + "after": true + } + ], + "no-unused-vars": "warn", + "template-curly-spacing": "error", + "prefer-template": "error", + "no-var": "error", + "prefer-const": "warn", + "no-nested-ternary": "error", + "no-tabs": "error", + "no-const-assign": "error" + } +} \ No newline at end of file diff --git a/.gitignore b/.gitignore index 083e3c2..06d7fbe 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,4 @@ [Bb]uild -src - # Created by https://www.toptal.com/developers/gitignore/api/node # Edit at https://www.toptal.com/developers/gitignore?templates=node diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..0dd53ed --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,5 @@ +{ + "editor.defaultFormatter": "dbaeumer.vscode-eslint", + "editor.formatOnSave": false, + "files.eol": "\n" +} \ No newline at end of file diff --git a/build.sh b/build.sh index 3ea6783..98f87f3 100644 --- a/build.sh +++ b/build.sh @@ -1 +1 @@ -clear;tsc;npx webpack \ No newline at end of file +clear;npx webpack \ No newline at end of file diff --git a/index.js b/index.js index 39af72c..4376576 100644 --- a/index.js +++ b/index.js @@ -14,9 +14,9 @@ /*!********************!*\ !*** ./src/api.js ***! \********************/ -/***/ ((__unused_webpack_module, exports, __webpack_require__) => { +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { -eval("\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nexports.listNameToID = exports.API = void 0;\nconst cardhandler_1 = __webpack_require__(/*! ./cardhandler */ \"./src/cardhandler.js\");\nconst cardlist_1 = __webpack_require__(/*! ./cardlist */ \"./src/cardlist.js\");\nconst layout_1 = __webpack_require__(/*! ./layout */ \"./src/layout.js\");\nconst task_1 = __webpack_require__(/*! ./task */ \"./src/task.js\");\nclass API {\n get Tasks() {\n return this.tasks;\n }\n get TaskLists() {\n return Array.from(this.cardHandler.Lists.values());\n }\n get CurrentTaskIndex() {\n return this.currentTaskIndex;\n }\n constructor() {\n this.currentTaskIndex = 0;\n this.tasks = new Map();\n this.cardHandler = new cardhandler_1.CardHandler();\n }\n serializeToLocalStorage() {\n const kanbanStr = JSON.stringify({\n index: this.currentTaskIndex,\n tasks: Array.from(this.tasks.entries()),\n taskLists: Array.from(this.cardHandler.Lists.keys()),\n });\n localStorage.setItem('my-kanban-board', kanbanStr);\n }\n tryLoadFromLocalStorage() {\n const boardDataStr = localStorage.getItem('my-kanban-board');\n if (!boardDataStr) {\n return;\n }\n const boardData = JSON.parse(boardDataStr);\n this.currentTaskIndex = boardData.index;\n boardData.tasks.forEach((item) => this.tasks.set(item[0], task_1.TaskItem.fromLoadedData(item[1])));\n boardData.taskLists.forEach((list) => this.cardHandler.push(new cardlist_1.CardList(list, listNameToID(list))));\n this.cardHandler.setHasDefault();\n (0, layout_1.generateElementsFromLoadedData)(this);\n }\n removeTaskItem(item) {\n this.tasks.delete(item.ID);\n }\n tryAddNewList() {\n return this.cardHandler.tryAddNewList();\n }\n taskListContains(identifier) {\n return this.cardHandler.Lists.has(identifier);\n }\n renameTaskList(oldID, newID) {\n this.cardHandler.renameTaskList(oldID, newID);\n this.cardHandler.setHasDefault();\n }\n deleteTaskList(identifier) {\n this.cardHandler.removeWithID(identifier);\n }\n addNewTask(createdAt, listID, title, tag, dueDate, color, description) {\n this.tasks.set(this.currentTaskIndex, new task_1.TaskItem(this.currentTaskIndex, createdAt, listID, title, tag, dueDate, color, description));\n this.advanceTask();\n }\n getTaskFromID(identifier) {\n const indexStr = identifier.lastIndexOf('-') + 1;\n const taskIndex = +identifier.slice(indexStr);\n const task = this.tasks.get(taskIndex);\n if (!task) {\n console.log(identifier);\n throw new Error(`Fatal task fetch error. Tried to fetch item with index: ${taskIndex}`);\n }\n return task;\n }\n advanceTask() {\n this.currentTaskIndex += 1;\n }\n}\nexports.API = API;\nfunction listNameToID(value) {\n let newName = new String(value);\n newName = newName.replace(' ', '-').toLocaleLowerCase().concat('-list');\n return newName.toString();\n}\nexports.listNameToID = listNameToID;\n\n\n//# sourceURL=webpack://kanban-board/./src/api.js?"); +eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ API: () => (/* binding */ API),\n/* harmony export */ listNameToID: () => (/* binding */ listNameToID)\n/* harmony export */ });\n/* harmony import */ var _cardhandler__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./cardhandler */ \"./src/cardhandler.js\");\n/* harmony import */ var _cardlist__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./cardlist */ \"./src/cardlist.js\");\n/* harmony import */ var _layout__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./layout */ \"./src/layout.js\");\n/* harmony import */ var _task__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./task */ \"./src/task.js\");\n\n\n\n\n\n\n\n\nclass API {\n get Tasks() {\n return this.tasks;\n }\n\n get TaskLists() {\n return Array.from(this.cardHandler.Lists.values());\n }\n\n get CurrentTaskIndex() {\n return this.currentTaskIndex;\n }\n\n constructor() {\n this.currentTaskIndex = 0;\n this.tasks = new Map();\n this.cardHandler = new _cardhandler__WEBPACK_IMPORTED_MODULE_0__.CardHandler();\n }\n\n serializeToLocalStorage() {\n const kanbanStr = JSON.stringify({\n index: this.currentTaskIndex,\n tasks: Array.from(this.tasks.entries()),\n taskLists: Array.from(this.cardHandler.Lists.keys()),\n });\n localStorage.setItem(\"my-kanban-board\", kanbanStr);\n }\n\n tryLoadFromLocalStorage() {\n const boardDataStr = localStorage.getItem(\"my-kanban-board\");\n if (!boardDataStr) {\n return;\n }\n\n const boardData = JSON.parse(boardDataStr);\n this.currentTaskIndex = boardData.index;\n\n boardData.tasks.forEach((item) =>\n this.tasks.set(item[0], _task__WEBPACK_IMPORTED_MODULE_3__.TaskItem.fromLoadedData(item[1]))\n );\n boardData.taskLists.forEach((list) =>\n this.cardHandler.push(new _cardlist__WEBPACK_IMPORTED_MODULE_1__.CardList(list, listNameToID(list)))\n );\n\n this.cardHandler.setHasDefault();\n\n (0,_layout__WEBPACK_IMPORTED_MODULE_2__.generateElementsFromLoadedData)(this);\n }\n\n removeTaskItem(item) {\n this.tasks.delete(item.ID);\n }\n\n tryAddNewList() {\n return this.cardHandler.tryAddNewList();\n }\n\n /**\n * @param {string} identifier\n */\n taskListContains(identifier) {\n return this.cardHandler.Lists.has(identifier);\n }\n\n /**\n * @param {string} oldID\n * @param {string} newID\n */\n renameTaskList(oldID, newID) {\n this.cardHandler.renameTaskList(oldID, newID);\n this.cardHandler.setHasDefault();\n }\n\n /**\n * @param {string} identifier\n */\n deleteTaskList(identifier) {\n this.cardHandler.removeWithID(identifier);\n }\n\n /**\n * @param {Date} createdAt\n * @param {string} listID\n * @param {string} title\n * @param {string} tag\n * @param {Date} dueDate\n * @param {string} color\n * @param {string} description\n */\n addNewTask(\n createdAt,\n listID,\n title,\n tag,\n dueDate,\n color,\n description\n ) {\n this.tasks.set(\n this.currentTaskIndex,\n new _task__WEBPACK_IMPORTED_MODULE_3__.TaskItem(\n this.currentTaskIndex,\n createdAt,\n listID,\n title,\n tag,\n dueDate,\n color,\n description\n )\n );\n this.advanceTask();\n }\n\n /**\n * @param {string} identifier\n * @returns {TaskItem}\n */\n getTaskFromID(identifier) {\n const indexStr = identifier.lastIndexOf(\"-\") + 1;\n const taskIndex = +identifier.slice(indexStr);\n const task = this.tasks.get(taskIndex);\n if (!task) {\n console.log(identifier);\n throw new Error(`Fatal task fetch error. Tried to fetch item with index: ${taskIndex}`);\n }\n return task;\n }\n\n advanceTask() {\n this.currentTaskIndex += 1;\n }\n}\n\n/**\n * @param {string} value \n * @returns \n */\nfunction listNameToID(value) {\n let newName = new String(value);\n newName = newName.replace(\" \", \"-\").toLocaleLowerCase().concat(\"-list\");\n return newName.toString();\n}\n\n\n//# sourceURL=webpack://kanban-board/./src/api.js?"); /***/ }), @@ -24,9 +24,9 @@ eval("\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nexpo /*!****************************!*\ !*** ./src/cardhandler.js ***! \****************************/ -/***/ ((__unused_webpack_module, exports, __webpack_require__) => { +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { -eval("\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nexports.CardHandler = void 0;\nconst api_1 = __webpack_require__(/*! ./api */ \"./src/api.js\");\nconst cardlist_1 = __webpack_require__(/*! ./cardlist */ \"./src/cardlist.js\");\nclass CardHandler {\n get HasDefault() {\n return this.hasDefault;\n }\n get Lists() {\n return this.lists;\n }\n constructor() {\n this.hasDefault = false;\n this.lists = new Map();\n }\n setHasDefault() {\n this.hasDefault = this.lists.has('New List');\n }\n push(list) {\n this.lists.set(list.Identifier, list);\n }\n tryAddNewList() {\n if (this.hasDefault) {\n return false;\n }\n this.lists.set('New List', new cardlist_1.CardList('New List', 'new-list'));\n this.hasDefault = true;\n return true;\n }\n removeWithID(identifier) {\n for (let [id, list] of this.lists.entries()) {\n if (list.ElementID === identifier) {\n this.lists.delete(id);\n this.setHasDefault();\n return;\n }\n }\n }\n renameTaskList(oldID, newID) {\n const oldCard = this.lists.get(oldID);\n if (oldCard) {\n this.lists.delete(oldID);\n this.lists.set(newID, oldCard);\n return;\n }\n this.lists.set(newID, new cardlist_1.CardList(newID, (0, api_1.listNameToID)(newID)));\n }\n}\nexports.CardHandler = CardHandler;\n\n\n//# sourceURL=webpack://kanban-board/./src/cardhandler.js?"); +eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ CardHandler: () => (/* binding */ CardHandler)\n/* harmony export */ });\n/* harmony import */ var _api__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./api */ \"./src/api.js\");\n/* harmony import */ var _cardlist__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./cardlist */ \"./src/cardlist.js\");\n\n\n\n\n\nclass CardHandler {\n get HasDefault() {\n return this.hasDefault;\n }\n\n get Lists() {\n return this.lists;\n }\n\n constructor() {\n this.hasDefault = false;\n this.lists = new Map();\n }\n\n setHasDefault() {\n this.hasDefault = this.lists.has(\"New List\");\n }\n\n /**\n * \n * @param {CardList} list \n */\n push(list) {\n this.lists.set(list.Identifier, list);\n }\n\n /**\n * @returns {boolean}\n */\n tryAddNewList() {\n if (this.hasDefault) {\n return false;\n }\n\n this.lists.set(\"New List\", new _cardlist__WEBPACK_IMPORTED_MODULE_1__.CardList(\"New List\", \"new-list\"));\n this.hasDefault = true;\n\n return true;\n }\n\n /**\n * \n * @param {string} identifier \n * @returns \n */\n removeWithID(identifier) {\n for (const [id, list] of this.lists.entries()) {\n if (list.ElementID === identifier) {\n this.lists.delete(id);\n this.setHasDefault();\n return;\n }\n }\n }\n\n /**\n * @param {string} oldID \n * @param {string} newID\n */\n renameTaskList(oldID, newID) {\n const oldCard = this.lists.get(oldID);\n if (oldCard) {\n this.lists.delete(oldID);\n this.lists.set(newID, oldCard);\n return;\n }\n\n this.lists.set(newID, new _cardlist__WEBPACK_IMPORTED_MODULE_1__.CardList(newID, (0,_api__WEBPACK_IMPORTED_MODULE_0__.listNameToID)(newID)));\n }\n}\n\n\n//# sourceURL=webpack://kanban-board/./src/cardhandler.js?"); /***/ }), @@ -34,9 +34,9 @@ eval("\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nexpo /*!*************************!*\ !*** ./src/cardlist.js ***! \*************************/ -/***/ ((__unused_webpack_module, exports) => { +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { -eval("\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nexports.CardList = void 0;\nclass CardList {\n get Identifier() {\n return this.identifier;\n }\n get ElementID() {\n return this.elementID;\n }\n constructor(identifier, elementID) {\n this.identifier = identifier;\n this.elementID = elementID;\n }\n}\nexports.CardList = CardList;\n\n\n//# sourceURL=webpack://kanban-board/./src/cardlist.js?"); +eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ CardList: () => (/* binding */ CardList)\n/* harmony export */ });\n\n\nclass CardList {\n get Identifier() {\n return this.identifier;\n }\n\n get ElementID() {\n return this.elementID;\n }\n\n constructor(identifier, elementID) {\n this.identifier = identifier;\n this.elementID = elementID;\n }\n}\n\n\n//# sourceURL=webpack://kanban-board/./src/cardlist.js?"); /***/ }), @@ -44,9 +44,9 @@ eval("\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nexpo /*!*************************!*\ !*** ./src/dragging.js ***! \*************************/ -/***/ ((__unused_webpack_module, exports, __webpack_require__) => { +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { -eval("\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nexports.setupListDragZone = exports.setupDraggables = void 0;\nconst layout_1 = __webpack_require__(/*! ./layout */ \"./src/layout.js\");\nfunction setupDraggables(api) {\n const dragables = document.querySelectorAll('.task');\n const droppables = document.querySelectorAll('.list-content');\n dragables.forEach((task) => (0, layout_1.addDragListeners)(task));\n droppables.forEach((zone) => setupListDragZone(api, zone));\n}\nexports.setupDraggables = setupDraggables;\nfunction setupListDragZone(api, zone) {\n zone.addEventListener('dragover', (e) => {\n e.preventDefault();\n const bottomTask = insertAboveTask(zone, e.clientY);\n const currentTask = document.querySelector('.is-dragging');\n const taskItem = api.getTaskFromID(currentTask.id);\n taskItem.setListID(zone.getAttribute('value'));\n if (!bottomTask) {\n zone.appendChild(currentTask);\n }\n else {\n zone.insertBefore(currentTask, bottomTask);\n }\n });\n}\nexports.setupListDragZone = setupListDragZone;\nfunction insertAboveTask(zone, mouseY) {\n // Grab all tasks that aren't currently being dragged\n const els = zone.querySelectorAll('.task:not(.is-dragging)');\n let closestTask = null;\n let closestOffset = Number.NEGATIVE_INFINITY;\n els.forEach((task) => {\n const { top } = task.getBoundingClientRect();\n const offset = mouseY - top;\n if (offset < 0 && offset > closestOffset) {\n closestOffset = offset;\n closestTask = task;\n }\n });\n return closestTask;\n}\n\n\n//# sourceURL=webpack://kanban-board/./src/dragging.js?"); +eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ setupDraggables: () => (/* binding */ setupDraggables),\n/* harmony export */ setupListDragZone: () => (/* binding */ setupListDragZone)\n/* harmony export */ });\n/* harmony import */ var _api__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./api */ \"./src/api.js\");\n/* harmony import */ var _layout__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./layout */ \"./src/layout.js\");\n\n\n\n\n\n/**\n * @param {API} api\n */\nfunction setupDraggables(api) {\n const dragables = document.querySelectorAll(\".task\");\n const droppables = document.querySelectorAll(\".list-content\");\n\n dragables.forEach((task) => (0,_layout__WEBPACK_IMPORTED_MODULE_1__.addDragListeners)(task));\n droppables.forEach((zone) => setupListDragZone(api, zone));\n}\n\n/**\n * @param {API} api\n * @param {HTMLElement} zone\n */\nfunction setupListDragZone(api, zone) {\n zone.addEventListener(\"dragover\", (e) => {\n e.preventDefault();\n\n const bottomTask = insertAboveTask(zone, e.clientY);\n const currentTask = document.querySelector(\".is-dragging\");\n\n const taskItem = api.getTaskFromID(currentTask.id);\n taskItem.setListID(zone.getAttribute(\"value\"));\n\n if (!bottomTask) {\n zone.appendChild(currentTask);\n } else {\n zone.insertBefore(currentTask, bottomTask);\n }\n\n // Serialize to disk, after changes\n api.serializeToLocalStorage();\n });\n}\n\nfunction insertAboveTask(zone, mouseY) {\n // Grab all tasks that aren't currently being dragged\n const els = zone.querySelectorAll(\".task:not(.is-dragging)\");\n\n let closestTask = null;\n let closestOffset = Number.NEGATIVE_INFINITY;\n\n els.forEach((task) => {\n const { top } = task.getBoundingClientRect();\n const offset = mouseY - top;\n\n if (offset < 0 && offset > closestOffset) {\n closestOffset = offset;\n closestTask = task;\n }\n });\n\n return closestTask;\n}\n\n\n//# sourceURL=webpack://kanban-board/./src/dragging.js?"); /***/ }), @@ -54,9 +54,9 @@ eval("\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nexpo /*!**********************!*\ !*** ./src/index.js ***! \**********************/ -/***/ ((__unused_webpack_module, exports, __webpack_require__) => { +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { -eval("\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nconst api_1 = __webpack_require__(/*! ./api */ \"./src/api.js\");\nconst dragging_1 = __webpack_require__(/*! ./dragging */ \"./src/dragging.js\");\nconst layout_1 = __webpack_require__(/*! ./layout */ \"./src/layout.js\");\nfunction main() {\n const api = new api_1.API();\n api.tryLoadFromLocalStorage();\n (0, layout_1.setupAddTask)(api);\n (0, layout_1.setupListAddButton)(api);\n (0, dragging_1.setupDraggables)(api);\n (0, layout_1.setupErrorModalLayout)();\n (0, layout_1.setupModalLayout)();\n}\nwindow.addEventListener('load', main);\n\n\n//# sourceURL=webpack://kanban-board/./src/index.js?"); +eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _api__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./api */ \"./src/api.js\");\n/* harmony import */ var _dragging__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./dragging */ \"./src/dragging.js\");\n/* harmony import */ var _layout__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./layout */ \"./src/layout.js\");\n\n\n\n\n\n\nfunction main() {\n const api = new _api__WEBPACK_IMPORTED_MODULE_0__.API();\n api.tryLoadFromLocalStorage();\n\n (0,_layout__WEBPACK_IMPORTED_MODULE_2__.setupAddTask)(api);\n (0,_layout__WEBPACK_IMPORTED_MODULE_2__.setupListAddButton)(api);\n (0,_dragging__WEBPACK_IMPORTED_MODULE_1__.setupDraggables)(api);\n\n (0,_layout__WEBPACK_IMPORTED_MODULE_2__.setupErrorModalLayout)();\n (0,_layout__WEBPACK_IMPORTED_MODULE_2__.setupModalLayout)();\n}\n\nwindow.addEventListener(\"load\", main);\n\n\n//# sourceURL=webpack://kanban-board/./src/index.js?"); /***/ }), @@ -64,9 +64,9 @@ eval("\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\ncons /*!***********************!*\ !*** ./src/layout.js ***! \***********************/ -/***/ ((__unused_webpack_module, exports, __webpack_require__) => { +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { -eval("\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nexports.generateElementsFromLoadedData = exports.setupNewTaskModalFields = exports.setupAddTask = exports.showErrorModal = exports.addDragListeners = exports.setupModalLayout = exports.setupErrorModalLayout = exports.setupListAddButton = void 0;\nconst api_1 = __webpack_require__(/*! ./api */ \"./src/api.js\");\nconst dragging_1 = __webpack_require__(/*! ./dragging */ \"./src/dragging.js\");\nconst task_1 = __webpack_require__(/*! ./task */ \"./src/task.js\");\nfunction setupListAddButton(api) {\n const btn = document.querySelector('#list-add-btn');\n btn.onclick = () => {\n const listDiv = document.querySelector('#task-lists');\n const listEl = createDefaultList(api);\n if (!listEl) {\n showErrorModal('Cannot create default list, as one already exists.');\n return;\n }\n listDiv.insertBefore(listEl, listDiv.children[listDiv.children.length - 1]);\n // Save results to disk\n api.serializeToLocalStorage();\n };\n}\nexports.setupListAddButton = setupListAddButton;\nfunction setupErrorModalLayout() {\n const modal = document.querySelector('#error-modal');\n const close = document.querySelector('#error-modal-close');\n close.onclick = function (e) {\n e.preventDefault();\n modal.style.display = 'none';\n };\n}\nexports.setupErrorModalLayout = setupErrorModalLayout;\nfunction setupModalLayout() {\n // Get the modal\n const modal = document.querySelector('#modal');\n const modalHeader = document.querySelector('#modal-header');\n // Get the element that closes the modal\n const span = document.querySelector('#close');\n const colorSelected = document.querySelector('#color-selected');\n const firstStyle = colorSelected.options[0].style;\n colorSelected.value = firstStyle.backgroundColor;\n colorSelected.style.background = firstStyle.backgroundColor;\n span.onclick = function () {\n modal.style.display = 'none';\n };\n colorSelected.onchange = function () {\n let color = colorSelected.options[colorSelected.selectedIndex].style.backgroundColor;\n colorSelected.style.backgroundColor = color;\n modalHeader.style.backgroundColor = color;\n };\n}\nexports.setupModalLayout = setupModalLayout;\nfunction addDragListeners(el) {\n el.addEventListener('dragstart', () => {\n el.classList.add('is-dragging');\n });\n el.addEventListener('dragend', () => {\n el.classList.remove('is-dragging');\n });\n}\nexports.addDragListeners = addDragListeners;\nfunction showErrorModal(message) {\n const errorModal = document.querySelector('#error-modal');\n const modalText = document.querySelector('#error-modal-text');\n modalText.innerText = message;\n errorModal.style.display = 'block';\n}\nexports.showErrorModal = showErrorModal;\nfunction setupAddTask(api) {\n const form = document.querySelector('#add-task-btn');\n form.onclick = (e) => {\n e.preventDefault();\n const lists = document.querySelectorAll('.swim-list');\n if (lists.length === 0) {\n showErrorModal('No lists available to add a task.');\n return;\n }\n const modal = document.querySelector('#modal');\n modal.style.display = 'block';\n setupNewTaskModalFields(api);\n };\n}\nexports.setupAddTask = setupAddTask;\nfunction setupNewTaskModalFields(api) {\n const modal = document.querySelector('#modal');\n const modalHeader = document.querySelector('#modal-header');\n const createdOn = document.querySelector('#created-on');\n const taskTitle = document.querySelector('#task-title');\n const taskDesc = document.querySelector('#task-desc');\n const saveBtn = document.querySelector('#modal-save-btn');\n const deleteBtn = document.querySelector('#modal-delete-btn');\n const tagKind = document.querySelector('#kind-option');\n tagKind.value = 'prg';\n const dueDate = document.querySelector('#due-date');\n dueDate.valueAsDate = null;\n const colorSelected = document.querySelector('#color-selected');\n const firstStyle = colorSelected.options[0].style;\n colorSelected.value = firstStyle.backgroundColor;\n colorSelected.style.background = firstStyle.backgroundColor;\n modalHeader.style.backgroundColor = colorSelected.value;\n const taskTitleText = `Task Title #${api.CurrentTaskIndex + 1}`;\n taskTitle.value = taskTitleText;\n taskDesc.value = '';\n const date = new Date();\n modal.style.display = 'block';\n createdOn.innerText = `Created on ${date.toDateString()}`;\n saveBtn.onclick = () => {\n if (taskTitle.value === taskTitleText) {\n showErrorModal('Invalid title name.');\n return;\n }\n // Add to todo list\n const firstList = document.querySelectorAll('.swim-list')[0];\n const listContent = firstList.querySelector('.list-content');\n const taskEl = createTaskItemElement(api, taskTitle.value, api.CurrentTaskIndex);\n listContent.appendChild(taskEl);\n const tagKind = document.querySelector('#kind-option');\n const dueDate = document.querySelector('#due-date');\n const colorSelected = document.querySelector('#color-selected');\n api.addNewTask(date, firstList.id, taskTitle.value, (0, task_1.tagStrToKind)(tagKind.value), dueDate.valueAsDate, colorSelected.style.background, taskDesc.value);\n // Save results to disk\n api.serializeToLocalStorage();\n // Hide modal\n modal.style.display = 'none';\n };\n // Hide delete button when creating new task\n deleteBtn.style.display = 'none';\n}\nexports.setupNewTaskModalFields = setupNewTaskModalFields;\nfunction generateElementsFromLoadedData(api) {\n const listDiv = document.querySelector('#task-lists');\n // Generate all list elements\n api.TaskLists.forEach((list) => {\n const listEl = createListWithName(api, list.Identifier);\n listDiv.insertBefore(listEl, listDiv.children[listDiv.children.length - 1]);\n });\n // Generate all task elements\n api.Tasks.forEach((task) => {\n const list = document.querySelector(`#${task.ListID}`);\n const content = list.querySelector('.list-content');\n content.appendChild(createTaskItemElement(api, task.Title, task.ID));\n });\n}\nexports.generateElementsFromLoadedData = generateElementsFromLoadedData;\nfunction populateTaskModalFields(api, taskID) {\n const task = api.getTaskFromID(taskID);\n const modal = document.querySelector('#modal');\n const modalHeader = document.querySelector('#modal-header');\n const createdOn = document.querySelector('#created-on');\n const taskTitle = document.querySelector('#task-title');\n const saveBtn = document.querySelector('#modal-save-btn');\n const deleteBtn = document.querySelector('#modal-delete-btn');\n const taskDesc = document.querySelector('#task-desc');\n const tagKind = document.querySelector('#kind-option');\n const dueDate = document.querySelector('#due-date-option');\n const colorSelected = document.querySelector('#color-selected');\n const taskTitleText = task.Title;\n taskTitle.value = taskTitleText;\n taskDesc.value = task.Description;\n createdOn.innerText = `Created on ${task.CreatedAt.toDateString()}`;\n tagKind.value = (0, task_1.tagKindToStr)(task.Tag);\n dueDate.valueAsDate = task.DueDate;\n modalHeader.style.background = task.Color;\n colorSelected.value = task.Color;\n colorSelected.style.background = task.Color;\n saveBtn.onclick = () => {\n task.applyFields(taskTitle.value, (0, task_1.tagStrToKind)(tagKind.value), dueDate.valueAsDate, colorSelected.style.background, taskDesc.value);\n // Save results to disk\n api.serializeToLocalStorage();\n // Hide modal\n modal.style.display = 'none';\n };\n deleteBtn.style.display = 'inline';\n deleteBtn.onclick = () => {\n // TODO: Add confirmation modal\n api.removeTaskItem(task);\n const listEl = document.querySelector(`#${task.ListID}`);\n const content = listEl.querySelector('.list-content');\n content.removeChild(document.querySelector(`#task-id-${task.ID}`));\n // Save results to disk\n api.serializeToLocalStorage();\n // Hide modal\n modal.style.display = 'none';\n };\n // Show modal\n modal.style.display = 'block';\n}\nfunction createTaskItemElement(api, taskTitle, index) {\n /**\n *
\n

Get Groceries

\n \n
\n */\n const taskID = `task-id-${index}`;\n const newTask = document.createElement('div');\n newTask.className = 'task';\n newTask.id = taskID;\n newTask.setAttribute('draggable', 'true');\n const taskTitleEl = document.createElement('p');\n newTask.appendChild(taskTitleEl);\n taskTitleEl.className = 'task-title';\n taskTitleEl.innerText = taskTitle;\n const innerBtn = document.createElement('button');\n newTask.appendChild(innerBtn);\n innerBtn.className = 'task-edit';\n innerBtn.innerText = '...';\n innerBtn.onclick = () => populateTaskModalFields(api, taskID);\n addDragListeners(newTask);\n return newTask;\n}\nfunction createDefaultList(api) {\n if (!api.tryAddNewList()) {\n return null;\n }\n return createListWithName(api, 'New List');\n}\nfunction createListWithName(api, title) {\n /**\n *
\n TODO\n
\n */\n const listID = (0, api_1.listNameToID)(title);\n const el = document.createElement('div');\n el.className = 'swim-list';\n el.id = listID;\n const header = document.createElement('div');\n el.appendChild(header);\n header.className = 'list-heading-inner-text';\n const headerTitle = document.createElement('input');\n header.appendChild(headerTitle);\n headerTitle.className = 'list-heading-input';\n headerTitle.type = 'text';\n headerTitle.value = title;\n headerTitle.defaultValue = title;\n headerTitle.onchange = (e) => listHeaderChange(el, headerTitle, e, api);\n const listContentZone = document.createElement('div');\n el.appendChild(listContentZone);\n listContentZone.setAttribute('value', listID);\n listContentZone.className = 'list-content';\n (0, dragging_1.setupListDragZone)(api, listContentZone);\n const deleteSpan = document.createElement('span');\n header.appendChild(deleteSpan);\n deleteSpan.className = 'list-delete-span';\n deleteSpan.innerText = '\\u{00D7}';\n deleteSpan.onclick = (e) => {\n e.preventDefault();\n if (listContentZone.children.length > 0) {\n showErrorModal('Cannot delete list that contains tasks.');\n return;\n }\n const listDiv = document.querySelector('#task-lists');\n listDiv.removeChild(el);\n api.deleteTaskList(listID);\n // Save results to disk\n api.serializeToLocalStorage();\n };\n return el;\n}\nfunction listHeaderChange(el, self, e, api) {\n e.preventDefault();\n const newID = (0, api_1.listNameToID)(self.value);\n if (el.id === newID) {\n return;\n }\n if (api.taskListContains(self.value)) {\n showErrorModal(`Task list with name '${self.value}' already exists.`);\n self.value = self.defaultValue;\n return;\n }\n const content = el.querySelector('.list-content');\n content.setAttribute('value', newID);\n api.renameTaskList(self.defaultValue, self.value);\n self.defaultValue = self.value;\n el.id = newID;\n // Save results to disk\n api.serializeToLocalStorage();\n}\n\n\n//# sourceURL=webpack://kanban-board/./src/layout.js?"); +eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ addDragListeners: () => (/* binding */ addDragListeners),\n/* harmony export */ generateElementsFromLoadedData: () => (/* binding */ generateElementsFromLoadedData),\n/* harmony export */ setupAddTask: () => (/* binding */ setupAddTask),\n/* harmony export */ setupErrorModalLayout: () => (/* binding */ setupErrorModalLayout),\n/* harmony export */ setupListAddButton: () => (/* binding */ setupListAddButton),\n/* harmony export */ setupModalLayout: () => (/* binding */ setupModalLayout),\n/* harmony export */ setupNewTaskModalFields: () => (/* binding */ setupNewTaskModalFields),\n/* harmony export */ showErrorModal: () => (/* binding */ showErrorModal)\n/* harmony export */ });\n/* harmony import */ var _api__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./api */ \"./src/api.js\");\n/* harmony import */ var _dragging__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./dragging */ \"./src/dragging.js\");\n/* harmony import */ var _task__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./task */ \"./src/task.js\");\n\n\n\n\n\n\n/**\n * \n * @param {API} api \n */\nfunction setupListAddButton(api) {\n const btn = document.querySelector(\"#list-add-btn\");\n btn.onclick = () => {\n const listDiv = document.querySelector(\"#task-lists\");\n const listEl = createDefaultList(api);\n if (!listEl) {\n showErrorModal(\"Cannot create default list, as one already exists.\");\n return;\n }\n\n listDiv.insertBefore(listEl, listDiv.children[listDiv.children.length - 1]);\n\n // Save results to disk\n api.serializeToLocalStorage();\n };\n}\n\nfunction setupErrorModalLayout() {\n const modal = document.querySelector(\"#error-modal\");\n const close = document.querySelector(\"#error-modal-close\");\n\n close.onclick = function (e) {\n e.preventDefault();\n modal.style.display = \"none\";\n };\n}\n\nfunction setupModalLayout() {\n // Get the modal\n const modal = document.querySelector(\"#modal\");\n const modalHeader = document.querySelector(\"#modal-header\");\n\n // Get the element that closes the modal\n const span = document.querySelector(\"#close\");\n const colorSelected = document.querySelector(\"#color-selected\");\n const firstStyle = colorSelected.options[0].style;\n colorSelected.value = firstStyle.backgroundColor;\n colorSelected.style.background = firstStyle.backgroundColor;\n\n span.onclick = function () {\n modal.style.display = \"none\";\n };\n\n colorSelected.onchange = function () {\n const color = colorSelected.options[colorSelected.selectedIndex].style.backgroundColor;\n\n colorSelected.style.backgroundColor = color;\n modalHeader.style.backgroundColor = color;\n };\n}\n\n/**\n * \n * @param {HTMLElement} el \n */\nfunction addDragListeners(el) {\n el.addEventListener(\"dragstart\", () => {\n el.classList.add(\"is-dragging\");\n });\n el.addEventListener(\"dragend\", () => {\n el.classList.remove(\"is-dragging\");\n });\n}\n\n/**\n * \n * @param {string} message \n */\nfunction showErrorModal(message) {\n const errorModal = document.querySelector(\"#error-modal\");\n const modalText = document.querySelector(\"#error-modal-text\") ;\n\n modalText.innerText = message;\n errorModal.style.display = \"block\";\n}\n\n/**\n * \n * @param {API} api \n */\nfunction setupAddTask(api) {\n const form = document.querySelector(\"#add-task-btn\");\n\n form.onclick = (e) => {\n e.preventDefault();\n\n const lists = document.querySelectorAll(\".swim-list\");\n if (lists.length === 0) {\n showErrorModal(\"No lists available to add a task.\");\n return;\n }\n\n const modal = document.querySelector(\"#modal\");\n modal.style.display = \"block\";\n setupNewTaskModalFields(api);\n };\n}\n\n/**\n * \n * @param {API} api \n */\nfunction setupNewTaskModalFields(api) {\n const modal = document.querySelector(\"#modal\");\n const modalHeader = document.querySelector(\"#modal-header\");\n const createdOn = document.querySelector(\"#created-on\");\n const taskTitle = document.querySelector(\"#task-title\");\n const taskDesc = document.querySelector(\"#task-desc\");\n const saveBtn = document.querySelector(\"#modal-save-btn\");\n const deleteBtn = document.querySelector(\"#modal-delete-btn\");\n\n const tagKind = document.querySelector(\"#kind-option\");\n tagKind.value = \"prg\";\n\n const dueDate = document.querySelector(\"#due-date\");\n dueDate.valueAsDate = null;\n\n const colorSelected = document.querySelector(\"#color-selected\");\n const firstStyle = colorSelected.options[0].style;\n colorSelected.value = firstStyle.backgroundColor;\n colorSelected.style.background = firstStyle.backgroundColor;\n\n modalHeader.style.backgroundColor = colorSelected.value;\n\n const taskTitleText = `Task Title #${api.CurrentTaskIndex + 1}`;\n taskTitle.value = taskTitleText;\n taskDesc.value = \"\";\n\n const date = new Date();\n modal.style.display = \"block\";\n createdOn.innerText = `Created on ${date.toDateString()}`;\n\n saveBtn.onclick = () => {\n if (taskTitle.value === taskTitleText) {\n showErrorModal(\"Invalid title name.\");\n return;\n }\n\n // Add to todo list\n const firstList = document.querySelectorAll(\".swim-list\")[0];\n const listContent = firstList.querySelector(\".list-content\");\n\n const taskEl = createTaskItemElement(api, taskTitle.value, api.CurrentTaskIndex);\n listContent.appendChild(taskEl);\n\n const tagKind = document.querySelector(\"#kind-option\");\n const dueDate = document.querySelector(\"#due-date\");\n const colorSelected = document.querySelector(\"#color-selected\");\n\n api.addNewTask(\n date,\n firstList.id,\n taskTitle.value,\n (0,_task__WEBPACK_IMPORTED_MODULE_2__.tagStrToKind)(tagKind.value),\n dueDate.valueAsDate,\n colorSelected.style.background,\n taskDesc.value\n );\n\n // Save results to disk\n api.serializeToLocalStorage();\n\n // Hide modal\n modal.style.display = \"none\";\n };\n\n // Hide delete button when creating new task\n deleteBtn.style.display = \"none\";\n}\n\n/**\n * \n * @param {API} api \n */\nfunction generateElementsFromLoadedData(api) {\n const listDiv = document.querySelector(\"#task-lists\");\n\n // Generate all list elements\n api.TaskLists.forEach((list) => {\n const listEl = createListWithName(api, list.Identifier);\n listDiv.insertBefore(listEl, listDiv.children[listDiv.children.length - 1]);\n });\n\n // Generate all task elements\n api.Tasks.forEach((task) => {\n const list = document.querySelector(`#${task.ListID}`);\n const content = list.querySelector(\".list-content\");\n content.appendChild(createTaskItemElement(api, task.Title, task.ID));\n });\n}\n\n/**\n * \n * @param {API} api \n * @param {string} taskID \n */\nfunction populateTaskModalFields(api, taskID) {\n const task = api.getTaskFromID(taskID);\n\n const modal = document.querySelector(\"#modal\");\n const modalHeader = document.querySelector(\"#modal-header\");\n const createdOn = document.querySelector(\"#created-on\");\n const taskTitle = document.querySelector(\"#task-title\");\n const saveBtn = document.querySelector(\"#modal-save-btn\");\n const deleteBtn = document.querySelector(\"#modal-delete-btn\");\n const taskDesc = document.querySelector(\"#task-desc\");\n\n const tagKind = document.querySelector(\"#kind-option\");\n const dueDate = document.querySelector(\"#due-date-option\");\n const colorSelected = document.querySelector(\"#color-selected\");\n\n const taskTitleText = task.Title;\n taskTitle.value = taskTitleText;\n taskDesc.value = task.Description;\n createdOn.innerText = `Created on ${task.CreatedAt.toDateString()}`;\n\n tagKind.value = (0,_task__WEBPACK_IMPORTED_MODULE_2__.tagKindToStr)(task.Tag);\n dueDate.valueAsDate = task.DueDate;\n\n modalHeader.style.background = task.Color;\n colorSelected.value = task.Color;\n colorSelected.style.background = task.Color;\n\n saveBtn.onclick = () => {\n task.applyFields(\n taskTitle.value,\n (0,_task__WEBPACK_IMPORTED_MODULE_2__.tagStrToKind)(tagKind.value),\n dueDate.valueAsDate,\n colorSelected.style.background,\n taskDesc.value\n );\n\n // Save results to disk\n api.serializeToLocalStorage();\n\n // Hide modal\n modal.style.display = \"none\";\n };\n\n deleteBtn.style.display = \"inline\";\n deleteBtn.onclick = () => {\n // TODO: Add confirmation modal\n\n api.removeTaskItem(task);\n\n const listEl = document.querySelector(`#${task.ListID}`);\n const content = listEl.querySelector(\".list-content\");\n content.removeChild(document.querySelector(`#task-id-${task.ID}`));\n\n // Save results to disk\n api.serializeToLocalStorage();\n\n // Hide modal\n modal.style.display = \"none\";\n };\n\n // Show modal\n modal.style.display = \"block\";\n}\n\n/**\n * \n * @param {API} api \n * @param {string} taskTitle \n * @param {number} index \n * @returns \n */\nfunction createTaskItemElement(api, taskTitle, index) {\n /**\n *
\n

Get Groceries

\n \n
\n */\n const taskID = `task-id-${index}`;\n const newTask = document.createElement(\"div\");\n newTask.className = \"task\";\n newTask.id = taskID;\n newTask.setAttribute(\"draggable\", \"true\");\n\n const taskTitleEl = document.createElement(\"p\");\n newTask.appendChild(taskTitleEl);\n\n taskTitleEl.className = \"task-title\";\n taskTitleEl.innerText = taskTitle;\n\n const innerBtn = document.createElement(\"button\");\n newTask.appendChild(innerBtn);\n\n innerBtn.className = \"task-edit\";\n innerBtn.innerText = \"...\";\n innerBtn.onclick = () => populateTaskModalFields(api, taskID);\n\n addDragListeners(newTask);\n\n return newTask;\n}\n\n/**\n * \n * @param {API} api \n * @returns \n */\nfunction createDefaultList(api) {\n if (!api.tryAddNewList()) {\n return null;\n }\n\n return createListWithName(api, \"New List\");\n}\n\n/**\n * \n * @param {API} api \n * @param {string} title \n * @returns \n */\nfunction createListWithName(api, title) {\n /**\n *
\n TODO\n
\n */\n const listID = (0,_api__WEBPACK_IMPORTED_MODULE_0__.listNameToID)(title);\n\n const el = document.createElement(\"div\");\n el.className = \"swim-list\";\n el.id = listID;\n\n const header = document.createElement(\"div\");\n el.appendChild(header);\n header.className = \"list-heading-inner-text\";\n\n const headerTitle = document.createElement(\"input\");\n header.appendChild(headerTitle);\n\n headerTitle.className = \"list-heading-input\";\n headerTitle.type = \"text\";\n headerTitle.value = title;\n headerTitle.defaultValue = title;\n\n headerTitle.onchange = (e) => listHeaderChange(el, headerTitle, e, api);\n\n const listContentZone = document.createElement(\"div\");\n el.appendChild(listContentZone);\n\n listContentZone.setAttribute(\"value\", listID);\n listContentZone.className = \"list-content\";\n\n (0,_dragging__WEBPACK_IMPORTED_MODULE_1__.setupListDragZone)(api, listContentZone);\n\n const deleteSpan = document.createElement(\"span\");\n header.appendChild(deleteSpan);\n\n deleteSpan.className = \"list-delete-span\";\n deleteSpan.innerText = \"\\u{00D7}\";\n deleteSpan.onclick = (e) => {\n e.preventDefault();\n\n if (listContentZone.children.length > 0) {\n showErrorModal(\"Cannot delete list that contains tasks.\");\n return;\n }\n\n const listDiv = document.querySelector(\"#task-lists\");\n listDiv.removeChild(el);\n\n api.deleteTaskList(listID);\n\n // Save results to disk\n api.serializeToLocalStorage();\n };\n\n return el;\n}\n\n/**\n * \n * @param {HTMLElement} el \n * @param {HTMLInputElement} self \n * @param {Event} e \n * @param {API} api \n * @returns \n */\nfunction listHeaderChange(el, self, e, api) {\n e.preventDefault();\n\n const newID = (0,_api__WEBPACK_IMPORTED_MODULE_0__.listNameToID)(self.value);\n if (el.id === newID) {\n return;\n }\n\n if (api.taskListContains(self.value)) {\n showErrorModal(`Task list with name '${self.value}' already exists.`);\n self.value = self.defaultValue;\n return;\n }\n\n const content = el.querySelector(\".list-content\");\n content.setAttribute(\"value\", newID);\n\n api.renameTaskList(self.defaultValue, self.value);\n\n self.defaultValue = self.value;\n el.id = newID;\n\n // Save results to disk\n api.serializeToLocalStorage();\n}\n\n\n//# sourceURL=webpack://kanban-board/./src/layout.js?"); /***/ }), @@ -74,9 +74,9 @@ eval("\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nexpo /*!*********************!*\ !*** ./src/task.js ***! \*********************/ -/***/ ((__unused_webpack_module, exports) => { +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { -eval("\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nexports.tagKindToStr = exports.tagStrToKind = exports.TaskItem = exports.TagKind = void 0;\nvar TagKind;\n(function (TagKind) {\n TagKind[TagKind[\"Programming\"] = 0] = \"Programming\";\n TagKind[TagKind[\"Graphics\"] = 1] = \"Graphics\";\n TagKind[TagKind[\"Documentation\"] = 2] = \"Documentation\";\n})(TagKind || (exports.TagKind = TagKind = {}));\nclass TaskItem {\n // Properties\n get ID() {\n return this.id;\n }\n get CreatedAt() {\n return this.createdAt;\n }\n get ListID() {\n return this.listID;\n }\n get Title() {\n return this.title;\n }\n get Tag() {\n return this.tag;\n }\n get DueDate() {\n return this.dueDate;\n }\n get Color() {\n return this.color;\n }\n get Description() {\n return this.description;\n }\n constructor(id, createdAt, listID, title, tag, dueDate, color, description) {\n this.id = id;\n this.createdAt = createdAt;\n this.listID = listID;\n this.title = title;\n this.tag = tag;\n this.dueDate = dueDate;\n this.color = color;\n this.description = description;\n }\n static fromLoadedData(item) {\n return new TaskItem(item.id, new Date(item.createdAt), item.listID, item.title, item.tag, !item.dueDate ? null : new Date(item.dueDate), item.color, item.description);\n }\n setListID(listID) {\n this.listID = listID;\n }\n applyFields(title, tag, dueDate, color, description) {\n this.title = title;\n this.tag = tag;\n this.dueDate = dueDate;\n this.color = color;\n this.description = description;\n }\n}\nexports.TaskItem = TaskItem;\nfunction tagStrToKind(tagStr) {\n switch (tagStr) {\n case 'prg':\n return TagKind.Programming;\n case 'gfx':\n return TagKind.Graphics;\n case 'doc':\n return TagKind.Documentation;\n default:\n throw new Error(`Undefined tag kind '${tagStr}'`);\n }\n}\nexports.tagStrToKind = tagStrToKind;\nfunction tagKindToStr(tag) {\n switch (tag) {\n case TagKind.Programming:\n return 'prg';\n case TagKind.Graphics:\n return 'gfx';\n case TagKind.Documentation:\n return 'doc';\n }\n}\nexports.tagKindToStr = tagKindToStr;\n\n\n//# sourceURL=webpack://kanban-board/./src/task.js?"); +eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ TagKind: () => (/* binding */ TagKind),\n/* harmony export */ TaskItem: () => (/* binding */ TaskItem),\n/* harmony export */ tagKindToStr: () => (/* binding */ tagKindToStr),\n/* harmony export */ tagStrToKind: () => (/* binding */ tagStrToKind)\n/* harmony export */ });\n\n\nconst TagKind = {\n Programming: 0,\n Graphics: 1,\n Documentation: 2,\n};\n\nclass TaskItem {\n // Properties\n get ID() {\n return this.id;\n }\n\n get CreatedAt() {\n return this.createdAt;\n }\n\n get ListID() {\n return this.listID;\n }\n\n get Title() {\n return this.title;\n }\n\n get Tag() {\n return this.tag;\n }\n\n get DueDate() {\n return this.dueDate;\n }\n\n get Color() {\n return this.color;\n }\n\n get Description() {\n return this.description;\n }\n\n /**\n * \n * @param {string} id \n * @param {Date} createdAt \n * @param {string} listID \n * @param {string} title \n * @param {TagKind} tag \n * @param {Date | null} dueDate \n * @param {string} color \n * @param {string} description \n */\n constructor(\n id,\n createdAt,\n listID,\n title,\n tag,\n dueDate,\n color,\n description\n ) {\n this.id = id;\n this.createdAt = createdAt;\n this.listID = listID;\n this.title = title;\n this.tag = tag;\n this.dueDate = dueDate;\n this.color = color;\n this.description = description;\n }\n\n /**\n * \n * @param {TaskItem} item \n * @returns \n */\n static fromLoadedData(item) {\n return new TaskItem(\n item.id,\n new Date(item.createdAt),\n item.listID,\n item.title,\n item.tag,\n !item.dueDate ? null : new Date(item.dueDate),\n item.color,\n item.description\n );\n }\n\n /**\n * \n * @param {string} listID \n */\n setListID(listID) {\n this.listID = listID;\n }\n\n /**\n * \n * @param {string} title \n * @param {TagKind} tag \n * @param {Date | null} dueDate \n * @param {string} color \n * @param {string} description \n */\n applyFields(\n title,\n tag,\n dueDate,\n color,\n description\n ) {\n this.title = title;\n this.tag = tag;\n this.dueDate = dueDate;\n this.color = color;\n this.description = description;\n }\n}\n\n/**\n * \n * @param {string} tagStr \n * @returns \n */\nfunction tagStrToKind(tagStr) {\n switch (tagStr) {\n case \"prg\":\n return TagKind.Programming;\n case \"gfx\":\n return TagKind.Graphics;\n case \"doc\":\n return TagKind.Documentation;\n default:\n throw new Error(`Undefined tag kind '${tagStr}'`);\n }\n}\n\n/**\n * \n * @param {TagKind} tag \n * @returns \n */\nfunction tagKindToStr(tag) {\n switch (tag) {\n case TagKind.Programming:\n return \"prg\";\n case TagKind.Graphics:\n return \"gfx\";\n case TagKind.Documentation:\n return \"doc\";\n }\n}\n\n\n//# sourceURL=webpack://kanban-board/./src/task.js?"); /***/ }) @@ -107,6 +107,35 @@ eval("\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nexpo /******/ } /******/ /************************************************************************/ +/******/ /* webpack/runtime/define property getters */ +/******/ (() => { +/******/ // define getter functions for harmony exports +/******/ __webpack_require__.d = (exports, definition) => { +/******/ for(var key in definition) { +/******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) { +/******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] }); +/******/ } +/******/ } +/******/ }; +/******/ })(); +/******/ +/******/ /* webpack/runtime/hasOwnProperty shorthand */ +/******/ (() => { +/******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop)) +/******/ })(); +/******/ +/******/ /* webpack/runtime/make namespace object */ +/******/ (() => { +/******/ // define __esModule on exports +/******/ __webpack_require__.r = (exports) => { +/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { +/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); +/******/ } +/******/ Object.defineProperty(exports, '__esModule', { value: true }); +/******/ }; +/******/ })(); +/******/ +/************************************************************************/ /******/ /******/ // startup /******/ // Load entry module and return exports diff --git a/package-lock.json b/package-lock.json index 4497820..0070473 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,1339 +1,2309 @@ { - "name": "kanban-board", - "version": "1.0.0", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "name": "kanban-board", - "version": "1.0.0", - "license": "ISC", - "devDependencies": { - "webpack": "^5.88.2", - "webpack-cli": "^5.1.4" - } - }, - "node_modules/@discoveryjs/json-ext": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz", - "integrity": "sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==", - "dev": true, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/@jridgewell/gen-mapping": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", - "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==", - "dev": true, - "dependencies": { - "@jridgewell/set-array": "^1.0.1", - "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.9" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/resolve-uri": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz", - "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==", - "dev": true, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/set-array": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", - "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", - "dev": true, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/source-map": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.5.tgz", - "integrity": "sha512-UTYAUj/wviwdsMfzoSJspJxbkH5o1snzwX0//0ENX1u/55kkZZkcTZP6u9bwKGkv+dkk9at4m1Cpt0uY80kcpQ==", - "dev": true, - "dependencies": { - "@jridgewell/gen-mapping": "^0.3.0", - "@jridgewell/trace-mapping": "^0.3.9" - } - }, - "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.4.15", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", - "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", - "dev": true - }, - "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.19", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.19.tgz", - "integrity": "sha512-kf37QtfW+Hwx/buWGMPcR60iF9ziHa6r/CZJIHbmcm4+0qrXiVdxegAH0F6yddEVQ7zdkjcGCgCzUu+BcbhQxw==", - "dev": true, - "dependencies": { - "@jridgewell/resolve-uri": "^3.1.0", - "@jridgewell/sourcemap-codec": "^1.4.14" - } - }, - "node_modules/@types/eslint": { - "version": "8.44.4", - "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.44.4.tgz", - "integrity": "sha512-lOzjyfY/D9QR4hY9oblZ76B90MYTB3RrQ4z2vBIJKj9ROCRqdkYl2gSUx1x1a4IWPjKJZLL4Aw1Zfay7eMnmnA==", - "dev": true, - "dependencies": { - "@types/estree": "*", - "@types/json-schema": "*" - } - }, - "node_modules/@types/eslint-scope": { - "version": "3.7.5", - "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.5.tgz", - "integrity": "sha512-JNvhIEyxVW6EoMIFIvj93ZOywYFatlpu9deeH6eSx6PE3WHYvHaQtmHmQeNw7aA81bYGBPPQqdtBm6b1SsQMmA==", - "dev": true, - "dependencies": { - "@types/eslint": "*", - "@types/estree": "*" - } - }, - "node_modules/@types/estree": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.2.tgz", - "integrity": "sha512-VeiPZ9MMwXjO32/Xu7+OwflfmeoRwkE/qzndw42gGtgJwZopBnzy2gD//NN1+go1mADzkDcqf/KnFRSjTJ8xJA==", - "dev": true - }, - "node_modules/@types/json-schema": { - "version": "7.0.13", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.13.tgz", - "integrity": "sha512-RbSSoHliUbnXj3ny0CNFOoxrIDV6SUGyStHsvDqosw6CkdPV8TtWGlfecuK4ToyMEAql6pzNxgCFKanovUzlgQ==", - "dev": true - }, - "node_modules/@types/node": { - "version": "20.8.4", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.8.4.tgz", - "integrity": "sha512-ZVPnqU58giiCjSxjVUESDtdPk4QR5WQhhINbc9UBrKLU68MX5BF6kbQzTrkwbolyr0X8ChBpXfavr5mZFKZQ5A==", - "dev": true, - "dependencies": { - "undici-types": "~5.25.1" - } - }, - "node_modules/@webassemblyjs/ast": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.6.tgz", - "integrity": "sha512-IN1xI7PwOvLPgjcf180gC1bqn3q/QaOCwYUahIOhbYUu8KA/3tw2RT/T0Gidi1l7Hhj5D/INhJxiICObqpMu4Q==", - "dev": true, - "dependencies": { - "@webassemblyjs/helper-numbers": "1.11.6", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6" - } - }, - "node_modules/@webassemblyjs/floating-point-hex-parser": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.6.tgz", - "integrity": "sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw==", - "dev": true - }, - "node_modules/@webassemblyjs/helper-api-error": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.6.tgz", - "integrity": "sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q==", - "dev": true - }, - "node_modules/@webassemblyjs/helper-buffer": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.6.tgz", - "integrity": "sha512-z3nFzdcp1mb8nEOFFk8DrYLpHvhKC3grJD2ardfKOzmbmJvEf/tPIqCY+sNcwZIY8ZD7IkB2l7/pqhUhqm7hLA==", - "dev": true - }, - "node_modules/@webassemblyjs/helper-numbers": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.6.tgz", - "integrity": "sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g==", - "dev": true, - "dependencies": { - "@webassemblyjs/floating-point-hex-parser": "1.11.6", - "@webassemblyjs/helper-api-error": "1.11.6", - "@xtuc/long": "4.2.2" - } - }, - "node_modules/@webassemblyjs/helper-wasm-bytecode": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.6.tgz", - "integrity": "sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA==", - "dev": true - }, - "node_modules/@webassemblyjs/helper-wasm-section": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.6.tgz", - "integrity": "sha512-LPpZbSOwTpEC2cgn4hTydySy1Ke+XEu+ETXuoyvuyezHO3Kjdu90KK95Sh9xTbmjrCsUwvWwCOQQNta37VrS9g==", - "dev": true, - "dependencies": { - "@webassemblyjs/ast": "1.11.6", - "@webassemblyjs/helper-buffer": "1.11.6", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6", - "@webassemblyjs/wasm-gen": "1.11.6" - } - }, - "node_modules/@webassemblyjs/ieee754": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.6.tgz", - "integrity": "sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg==", - "dev": true, - "dependencies": { - "@xtuc/ieee754": "^1.2.0" - } - }, - "node_modules/@webassemblyjs/leb128": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.6.tgz", - "integrity": "sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ==", - "dev": true, - "dependencies": { - "@xtuc/long": "4.2.2" - } - }, - "node_modules/@webassemblyjs/utf8": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.6.tgz", - "integrity": "sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA==", - "dev": true - }, - "node_modules/@webassemblyjs/wasm-edit": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.6.tgz", - "integrity": "sha512-Ybn2I6fnfIGuCR+Faaz7YcvtBKxvoLV3Lebn1tM4o/IAJzmi9AWYIPWpyBfU8cC+JxAO57bk4+zdsTjJR+VTOw==", - "dev": true, - "dependencies": { - "@webassemblyjs/ast": "1.11.6", - "@webassemblyjs/helper-buffer": "1.11.6", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6", - "@webassemblyjs/helper-wasm-section": "1.11.6", - "@webassemblyjs/wasm-gen": "1.11.6", - "@webassemblyjs/wasm-opt": "1.11.6", - "@webassemblyjs/wasm-parser": "1.11.6", - "@webassemblyjs/wast-printer": "1.11.6" - } - }, - "node_modules/@webassemblyjs/wasm-gen": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.6.tgz", - "integrity": "sha512-3XOqkZP/y6B4F0PBAXvI1/bky7GryoogUtfwExeP/v7Nzwo1QLcq5oQmpKlftZLbT+ERUOAZVQjuNVak6UXjPA==", - "dev": true, - "dependencies": { - "@webassemblyjs/ast": "1.11.6", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6", - "@webassemblyjs/ieee754": "1.11.6", - "@webassemblyjs/leb128": "1.11.6", - "@webassemblyjs/utf8": "1.11.6" - } - }, - "node_modules/@webassemblyjs/wasm-opt": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.6.tgz", - "integrity": "sha512-cOrKuLRE7PCe6AsOVl7WasYf3wbSo4CeOk6PkrjS7g57MFfVUF9u6ysQBBODX0LdgSvQqRiGz3CXvIDKcPNy4g==", - "dev": true, - "dependencies": { - "@webassemblyjs/ast": "1.11.6", - "@webassemblyjs/helper-buffer": "1.11.6", - "@webassemblyjs/wasm-gen": "1.11.6", - "@webassemblyjs/wasm-parser": "1.11.6" - } - }, - "node_modules/@webassemblyjs/wasm-parser": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.6.tgz", - "integrity": "sha512-6ZwPeGzMJM3Dqp3hCsLgESxBGtT/OeCvCZ4TA1JUPYgmhAx38tTPR9JaKy0S5H3evQpO/h2uWs2j6Yc/fjkpTQ==", - "dev": true, - "dependencies": { - "@webassemblyjs/ast": "1.11.6", - "@webassemblyjs/helper-api-error": "1.11.6", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6", - "@webassemblyjs/ieee754": "1.11.6", - "@webassemblyjs/leb128": "1.11.6", - "@webassemblyjs/utf8": "1.11.6" - } - }, - "node_modules/@webassemblyjs/wast-printer": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.11.6.tgz", - "integrity": "sha512-JM7AhRcE+yW2GWYaKeHL5vt4xqee5N2WcezptmgyhNS+ScggqcT1OtXykhAb13Sn5Yas0j2uv9tHgrjwvzAP4A==", - "dev": true, - "dependencies": { - "@webassemblyjs/ast": "1.11.6", - "@xtuc/long": "4.2.2" - } - }, - "node_modules/@webpack-cli/configtest": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-2.1.1.tgz", - "integrity": "sha512-wy0mglZpDSiSS0XHrVR+BAdId2+yxPSoJW8fsna3ZpYSlufjvxnP4YbKTCBZnNIcGN4r6ZPXV55X4mYExOfLmw==", - "dev": true, - "engines": { - "node": ">=14.15.0" - }, - "peerDependencies": { - "webpack": "5.x.x", - "webpack-cli": "5.x.x" - } - }, - "node_modules/@webpack-cli/info": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@webpack-cli/info/-/info-2.0.2.tgz", - "integrity": "sha512-zLHQdI/Qs1UyT5UBdWNqsARasIA+AaF8t+4u2aS2nEpBQh2mWIVb8qAklq0eUENnC5mOItrIB4LiS9xMtph18A==", - "dev": true, - "engines": { - "node": ">=14.15.0" - }, - "peerDependencies": { - "webpack": "5.x.x", - "webpack-cli": "5.x.x" - } - }, - "node_modules/@webpack-cli/serve": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-2.0.5.tgz", - "integrity": "sha512-lqaoKnRYBdo1UgDX8uF24AfGMifWK19TxPmM5FHc2vAGxrJ/qtyUyFBWoY1tISZdelsQ5fBcOusifo5o5wSJxQ==", - "dev": true, - "engines": { - "node": ">=14.15.0" - }, - "peerDependencies": { - "webpack": "5.x.x", - "webpack-cli": "5.x.x" - }, - "peerDependenciesMeta": { - "webpack-dev-server": { - "optional": true - } - } - }, - "node_modules/@xtuc/ieee754": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", - "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", - "dev": true - }, - "node_modules/@xtuc/long": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", - "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", - "dev": true - }, - "node_modules/acorn": { - "version": "8.10.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.10.0.tgz", - "integrity": "sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==", - "dev": true, - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/acorn-import-assertions": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.9.0.tgz", - "integrity": "sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA==", - "dev": true, - "peerDependencies": { - "acorn": "^8" - } - }, - "node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, - "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/ajv-keywords": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", - "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", - "dev": true, - "peerDependencies": { - "ajv": "^6.9.1" - } - }, - "node_modules/browserslist": { - "version": "4.22.1", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.22.1.tgz", - "integrity": "sha512-FEVc202+2iuClEhZhrWy6ZiAcRLvNMyYcxZ8raemul1DYVOVdFsbqckWLdsixQZCpJlwe77Z3UTalE7jsjnKfQ==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "dependencies": { - "caniuse-lite": "^1.0.30001541", - "electron-to-chromium": "^1.4.535", - "node-releases": "^2.0.13", - "update-browserslist-db": "^1.0.13" - }, - "bin": { - "browserslist": "cli.js" - }, - "engines": { - "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" - } - }, - "node_modules/buffer-from": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", - "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", - "dev": true - }, - "node_modules/caniuse-lite": { - "version": "1.0.30001547", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001547.tgz", - "integrity": "sha512-W7CrtIModMAxobGhz8iXmDfuJiiKg1WADMO/9x7/CLNin5cpSbuBjooyoIUVB5eyCc36QuTVlkVa1iB2S5+/eA==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/caniuse-lite" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ] - }, - "node_modules/chrome-trace-event": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz", - "integrity": "sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==", - "dev": true, - "engines": { - "node": ">=6.0" - } - }, - "node_modules/clone-deep": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", - "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==", - "dev": true, - "dependencies": { - "is-plain-object": "^2.0.4", - "kind-of": "^6.0.2", - "shallow-clone": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/colorette": { - "version": "2.0.20", - "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", - "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==", - "dev": true - }, - "node_modules/commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", - "dev": true - }, - "node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dev": true, - "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/electron-to-chromium": { - "version": "1.4.549", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.549.tgz", - "integrity": "sha512-gpXfJslSi4hYDkA0mTLEpYKRv9siAgSUgZ+UWyk+J5Cttpd1ThCVwdclzIwQSclz3hYn049+M2fgrP1WpvF8xg==", - "dev": true - }, - "node_modules/enhanced-resolve": { - "version": "5.15.0", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.15.0.tgz", - "integrity": "sha512-LXYT42KJ7lpIKECr2mAXIaMldcNCh/7E0KBKOu4KSfkHmP+mZmSs+8V5gBAqisWBy0OO4W5Oyys0GO1Y8KtdKg==", - "dev": true, - "dependencies": { - "graceful-fs": "^4.2.4", - "tapable": "^2.2.0" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/envinfo": { - "version": "7.10.0", - "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.10.0.tgz", - "integrity": "sha512-ZtUjZO6l5mwTHvc1L9+1q5p/R3wTopcfqMW8r5t8SJSKqeVI/LtajORwRFEKpEFuekjD0VBjwu1HMxL4UalIRw==", - "dev": true, - "bin": { - "envinfo": "dist/cli.js" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/es-module-lexer": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.3.1.tgz", - "integrity": "sha512-JUFAyicQV9mXc3YRxPnDlrfBKpqt6hUYzz9/boprUJHs4e4KVr3XwOF70doO6gwXUor6EWZJAyWAfKki84t20Q==", - "dev": true - }, - "node_modules/escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/eslint-scope": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", - "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", - "dev": true, - "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^4.1.1" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/esrecurse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", - "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", - "dev": true, - "dependencies": { - "estraverse": "^5.2.0" - }, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/esrecurse/node_modules/estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "dev": true, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/events": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", - "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", - "dev": true, - "engines": { - "node": ">=0.8.x" - } - }, - "node_modules/fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true - }, - "node_modules/fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "dev": true - }, - "node_modules/fastest-levenshtein": { - "version": "1.0.16", - "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz", - "integrity": "sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==", - "dev": true, - "engines": { - "node": ">= 4.9.1" - } - }, - "node_modules/find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, - "dependencies": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/glob-to-regexp": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", - "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", - "dev": true - }, - "node_modules/graceful-fs": { - "version": "4.2.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", - "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", - "dev": true - }, - "node_modules/has": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.4.tgz", - "integrity": "sha512-qdSAmqLF6209RFj4VVItywPMbm3vWylknmB3nvNiUIs72xAimcM8nVYxYr7ncvZq5qzk9MKIZR8ijqD/1QuYjQ==", - "dev": true, - "engines": { - "node": ">= 0.4.0" - } - }, - "node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/import-local": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz", - "integrity": "sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==", - "dev": true, - "dependencies": { - "pkg-dir": "^4.2.0", - "resolve-cwd": "^3.0.0" - }, - "bin": { - "import-local-fixture": "fixtures/cli.js" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/interpret": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/interpret/-/interpret-3.1.1.tgz", - "integrity": "sha512-6xwYfHbajpoF0xLW+iwLkhwgvLoZDfjYfoFNu8ftMoXINzwuymNLd9u/KmwtdT2GbR+/Cz66otEGEVVUHX9QLQ==", - "dev": true, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/is-core-module": { - "version": "2.13.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.0.tgz", - "integrity": "sha512-Z7dk6Qo8pOCp3l4tsX2C5ZVas4V+UxwQodwZhLopL91TX8UyyHEXafPcyoeeWuLrwzHcr3igO78wNLwHJHsMCQ==", - "dev": true, - "dependencies": { - "has": "^1.0.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dev": true, - "dependencies": { - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true - }, - "node_modules/isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/jest-worker": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", - "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==", - "dev": true, - "dependencies": { - "@types/node": "*", - "merge-stream": "^2.0.0", - "supports-color": "^8.0.0" - }, - "engines": { - "node": ">= 10.13.0" - } - }, - "node_modules/json-parse-even-better-errors": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", - "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", - "dev": true - }, - "node_modules/json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true - }, - "node_modules/kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/loader-runner": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz", - "integrity": "sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==", - "dev": true, - "engines": { - "node": ">=6.11.5" - } - }, - "node_modules/locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, - "dependencies": { - "p-locate": "^4.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/merge-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", - "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", - "dev": true - }, - "node_modules/mime-db": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", - "dev": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mime-types": { - "version": "2.1.35", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "dev": true, - "dependencies": { - "mime-db": "1.52.0" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/neo-async": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", - "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", - "dev": true - }, - "node_modules/node-releases": { - "version": "2.0.13", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.13.tgz", - "integrity": "sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ==", - "dev": true - }, - "node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "dependencies": { - "p-try": "^2.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dev": true, - "dependencies": { - "p-limit": "^2.2.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/path-parse": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", - "dev": true - }, - "node_modules/picocolors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", - "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", - "dev": true - }, - "node_modules/pkg-dir": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", - "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", - "dev": true, - "dependencies": { - "find-up": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/punycode": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz", - "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/randombytes": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", - "dev": true, - "dependencies": { - "safe-buffer": "^5.1.0" - } - }, - "node_modules/rechoir": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.8.0.tgz", - "integrity": "sha512-/vxpCXddiX8NGfGO/mTafwjq4aFa/71pvamip0++IQk3zG8cbCj0fifNPrjjF1XMXUne91jL9OoxmdykoEtifQ==", - "dev": true, - "dependencies": { - "resolve": "^1.20.0" - }, - "engines": { - "node": ">= 10.13.0" - } - }, - "node_modules/resolve": { - "version": "1.22.8", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", - "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", - "dev": true, - "dependencies": { - "is-core-module": "^2.13.0", - "path-parse": "^1.0.7", - "supports-preserve-symlinks-flag": "^1.0.0" - }, - "bin": { - "resolve": "bin/resolve" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/resolve-cwd": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", - "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", - "dev": true, - "dependencies": { - "resolve-from": "^5.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/schema-utils": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", - "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", - "dev": true, - "dependencies": { - "@types/json-schema": "^7.0.8", - "ajv": "^6.12.5", - "ajv-keywords": "^3.5.2" - }, - "engines": { - "node": ">= 10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - } - }, - "node_modules/serialize-javascript": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.1.tgz", - "integrity": "sha512-owoXEFjWRllis8/M1Q+Cw5k8ZH40e3zhp/ovX+Xr/vi1qj6QesbyXXViFbpNvWvPNAD62SutwEXavefrLJWj7w==", - "dev": true, - "dependencies": { - "randombytes": "^2.1.0" - } - }, - "node_modules/shallow-clone": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", - "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==", - "dev": true, - "dependencies": { - "kind-of": "^6.0.2" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, - "dependencies": { - "shebang-regex": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/source-map-support": { - "version": "0.5.21", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", - "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", - "dev": true, - "dependencies": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, - "node_modules/supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/supports-color?sponsor=1" - } - }, - "node_modules/supports-preserve-symlinks-flag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", - "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", - "dev": true, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/tapable": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", - "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/terser": { - "version": "5.21.0", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.21.0.tgz", - "integrity": "sha512-WtnFKrxu9kaoXuiZFSGrcAvvBqAdmKx0SFNmVNYdJamMu9yyN3I/QF0FbH4QcqJQ+y1CJnzxGIKH0cSj+FGYRw==", - "dev": true, - "dependencies": { - "@jridgewell/source-map": "^0.3.3", - "acorn": "^8.8.2", - "commander": "^2.20.0", - "source-map-support": "~0.5.20" - }, - "bin": { - "terser": "bin/terser" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/terser-webpack-plugin": { - "version": "5.3.9", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.9.tgz", - "integrity": "sha512-ZuXsqE07EcggTWQjXUj+Aot/OMcD0bMKGgF63f7UxYcu5/AJF53aIpK1YoP5xR9l6s/Hy2b+t1AM0bLNPRuhwA==", - "dev": true, - "dependencies": { - "@jridgewell/trace-mapping": "^0.3.17", - "jest-worker": "^27.4.5", - "schema-utils": "^3.1.1", - "serialize-javascript": "^6.0.1", - "terser": "^5.16.8" - }, - "engines": { - "node": ">= 10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^5.1.0" - }, - "peerDependenciesMeta": { - "@swc/core": { - "optional": true - }, - "esbuild": { - "optional": true - }, - "uglify-js": { - "optional": true - } - } - }, - "node_modules/undici-types": { - "version": "5.25.3", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.25.3.tgz", - "integrity": "sha512-Ga1jfYwRn7+cP9v8auvEXN1rX3sWqlayd4HP7OKk4mZWylEmu3KzXDUGrQUN6Ol7qo1gPvB2e5gX6udnyEPgdA==", - "dev": true - }, - "node_modules/update-browserslist-db": { - "version": "1.0.13", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz", - "integrity": "sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "dependencies": { - "escalade": "^3.1.1", - "picocolors": "^1.0.0" - }, - "bin": { - "update-browserslist-db": "cli.js" - }, - "peerDependencies": { - "browserslist": ">= 4.21.0" - } - }, - "node_modules/uri-js": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "dev": true, - "dependencies": { - "punycode": "^2.1.0" - } - }, - "node_modules/watchpack": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.0.tgz", - "integrity": "sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg==", - "dev": true, - "dependencies": { - "glob-to-regexp": "^0.4.1", - "graceful-fs": "^4.1.2" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/webpack": { - "version": "5.88.2", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.88.2.tgz", - "integrity": "sha512-JmcgNZ1iKj+aiR0OvTYtWQqJwq37Pf683dY9bVORwVbUrDhLhdn/PlO2sHsFHPkj7sHNQF3JwaAkp49V+Sq1tQ==", - "dev": true, - "dependencies": { - "@types/eslint-scope": "^3.7.3", - "@types/estree": "^1.0.0", - "@webassemblyjs/ast": "^1.11.5", - "@webassemblyjs/wasm-edit": "^1.11.5", - "@webassemblyjs/wasm-parser": "^1.11.5", - "acorn": "^8.7.1", - "acorn-import-assertions": "^1.9.0", - "browserslist": "^4.14.5", - "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^5.15.0", - "es-module-lexer": "^1.2.1", - "eslint-scope": "5.1.1", - "events": "^3.2.0", - "glob-to-regexp": "^0.4.1", - "graceful-fs": "^4.2.9", - "json-parse-even-better-errors": "^2.3.1", - "loader-runner": "^4.2.0", - "mime-types": "^2.1.27", - "neo-async": "^2.6.2", - "schema-utils": "^3.2.0", - "tapable": "^2.1.1", - "terser-webpack-plugin": "^5.3.7", - "watchpack": "^2.4.0", - "webpack-sources": "^3.2.3" - }, - "bin": { - "webpack": "bin/webpack.js" - }, - "engines": { - "node": ">=10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependenciesMeta": { - "webpack-cli": { - "optional": true - } - } - }, - "node_modules/webpack-cli": { - "version": "5.1.4", - "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-5.1.4.tgz", - "integrity": "sha512-pIDJHIEI9LR0yxHXQ+Qh95k2EvXpWzZ5l+d+jIo+RdSm9MiHfzazIxwwni/p7+x4eJZuvG1AJwgC4TNQ7NRgsg==", - "dev": true, - "dependencies": { - "@discoveryjs/json-ext": "^0.5.0", - "@webpack-cli/configtest": "^2.1.1", - "@webpack-cli/info": "^2.0.2", - "@webpack-cli/serve": "^2.0.5", - "colorette": "^2.0.14", - "commander": "^10.0.1", - "cross-spawn": "^7.0.3", - "envinfo": "^7.7.3", - "fastest-levenshtein": "^1.0.12", - "import-local": "^3.0.2", - "interpret": "^3.1.1", - "rechoir": "^0.8.0", - "webpack-merge": "^5.7.3" - }, - "bin": { - "webpack-cli": "bin/cli.js" - }, - "engines": { - "node": ">=14.15.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "5.x.x" - }, - "peerDependenciesMeta": { - "@webpack-cli/generators": { - "optional": true - }, - "webpack-bundle-analyzer": { - "optional": true - }, - "webpack-dev-server": { - "optional": true + "name": "kanban-board", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "kanban-board", + "version": "1.0.0", + "license": "ISC", + "devDependencies": { + "eslint": "^8.52.0", + "webpack": "^5.88.2", + "webpack-cli": "^5.1.4" + } + }, + "node_modules/@aashutoshrathi/word-wrap": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz", + "integrity": "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@discoveryjs/json-ext": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz", + "integrity": "sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==", + "dev": true, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", + "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", + "dev": true, + "dependencies": { + "eslint-visitor-keys": "^3.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@eslint-community/regexpp": { + "version": "4.10.0", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.10.0.tgz", + "integrity": "sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA==", + "dev": true, + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.2.tgz", + "integrity": "sha512-+wvgpDsrB1YqAMdEUCcnTlpfVBH7Vqn6A/NT3D8WVXFIaKMlErPIZT3oCIAVCOtarRpMtelZLqJeU3t7WY6X6g==", + "dev": true, + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^9.6.0", + "globals": "^13.19.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint/js": { + "version": "8.52.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.52.0.tgz", + "integrity": "sha512-mjZVbpaeMZludF2fsWLD0Z9gCref1Tk4i9+wddjRvpUNqqcndPkBD09N/Mapey0b3jaXbLm2kICwFv2E64QinA==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/@humanwhocodes/config-array": { + "version": "0.11.13", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.13.tgz", + "integrity": "sha512-JSBDMiDKSzQVngfRjOdFXgFfklaXI4K9nLF49Auh21lmBWRLIK3+xTErTWD4KU54pb6coM6ESE7Awz/FNU3zgQ==", + "dev": true, + "dependencies": { + "@humanwhocodes/object-schema": "^2.0.1", + "debug": "^4.1.1", + "minimatch": "^3.0.5" + }, + "engines": { + "node": ">=10.10.0" + } + }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true, + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/object-schema": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.1.tgz", + "integrity": "sha512-dvuCeX5fC9dXgJn9t+X5atfmgQAzUOWqS1254Gh0m6i8wKd10ebXkfNKiRK+1GWi/yTvvLDHpoxLr0xxxeslWw==", + "dev": true + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", + "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==", + "dev": true, + "dependencies": { + "@jridgewell/set-array": "^1.0.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.9" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz", + "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==", + "dev": true, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/set-array": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", + "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", + "dev": true, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/source-map": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.5.tgz", + "integrity": "sha512-UTYAUj/wviwdsMfzoSJspJxbkH5o1snzwX0//0ENX1u/55kkZZkcTZP6u9bwKGkv+dkk9at4m1Cpt0uY80kcpQ==", + "dev": true, + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.0", + "@jridgewell/trace-mapping": "^0.3.9" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.4.15", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", + "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", + "dev": true + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.19", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.19.tgz", + "integrity": "sha512-kf37QtfW+Hwx/buWGMPcR60iF9ziHa6r/CZJIHbmcm4+0qrXiVdxegAH0F6yddEVQ7zdkjcGCgCzUu+BcbhQxw==", + "dev": true, + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@types/eslint": { + "version": "8.44.4", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.44.4.tgz", + "integrity": "sha512-lOzjyfY/D9QR4hY9oblZ76B90MYTB3RrQ4z2vBIJKj9ROCRqdkYl2gSUx1x1a4IWPjKJZLL4Aw1Zfay7eMnmnA==", + "dev": true, + "dependencies": { + "@types/estree": "*", + "@types/json-schema": "*" + } + }, + "node_modules/@types/eslint-scope": { + "version": "3.7.5", + "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.5.tgz", + "integrity": "sha512-JNvhIEyxVW6EoMIFIvj93ZOywYFatlpu9deeH6eSx6PE3WHYvHaQtmHmQeNw7aA81bYGBPPQqdtBm6b1SsQMmA==", + "dev": true, + "dependencies": { + "@types/eslint": "*", + "@types/estree": "*" + } + }, + "node_modules/@types/estree": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.2.tgz", + "integrity": "sha512-VeiPZ9MMwXjO32/Xu7+OwflfmeoRwkE/qzndw42gGtgJwZopBnzy2gD//NN1+go1mADzkDcqf/KnFRSjTJ8xJA==", + "dev": true + }, + "node_modules/@types/json-schema": { + "version": "7.0.13", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.13.tgz", + "integrity": "sha512-RbSSoHliUbnXj3ny0CNFOoxrIDV6SUGyStHsvDqosw6CkdPV8TtWGlfecuK4ToyMEAql6pzNxgCFKanovUzlgQ==", + "dev": true + }, + "node_modules/@types/node": { + "version": "20.8.4", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.8.4.tgz", + "integrity": "sha512-ZVPnqU58giiCjSxjVUESDtdPk4QR5WQhhINbc9UBrKLU68MX5BF6kbQzTrkwbolyr0X8ChBpXfavr5mZFKZQ5A==", + "dev": true, + "dependencies": { + "undici-types": "~5.25.1" + } + }, + "node_modules/@ungap/structured-clone": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", + "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", + "dev": true + }, + "node_modules/@webassemblyjs/ast": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.6.tgz", + "integrity": "sha512-IN1xI7PwOvLPgjcf180gC1bqn3q/QaOCwYUahIOhbYUu8KA/3tw2RT/T0Gidi1l7Hhj5D/INhJxiICObqpMu4Q==", + "dev": true, + "dependencies": { + "@webassemblyjs/helper-numbers": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6" + } + }, + "node_modules/@webassemblyjs/floating-point-hex-parser": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.6.tgz", + "integrity": "sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw==", + "dev": true + }, + "node_modules/@webassemblyjs/helper-api-error": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.6.tgz", + "integrity": "sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q==", + "dev": true + }, + "node_modules/@webassemblyjs/helper-buffer": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.6.tgz", + "integrity": "sha512-z3nFzdcp1mb8nEOFFk8DrYLpHvhKC3grJD2ardfKOzmbmJvEf/tPIqCY+sNcwZIY8ZD7IkB2l7/pqhUhqm7hLA==", + "dev": true + }, + "node_modules/@webassemblyjs/helper-numbers": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.6.tgz", + "integrity": "sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g==", + "dev": true, + "dependencies": { + "@webassemblyjs/floating-point-hex-parser": "1.11.6", + "@webassemblyjs/helper-api-error": "1.11.6", + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webassemblyjs/helper-wasm-bytecode": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.6.tgz", + "integrity": "sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA==", + "dev": true + }, + "node_modules/@webassemblyjs/helper-wasm-section": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.6.tgz", + "integrity": "sha512-LPpZbSOwTpEC2cgn4hTydySy1Ke+XEu+ETXuoyvuyezHO3Kjdu90KK95Sh9xTbmjrCsUwvWwCOQQNta37VrS9g==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.11.6", + "@webassemblyjs/helper-buffer": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/wasm-gen": "1.11.6" + } + }, + "node_modules/@webassemblyjs/ieee754": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.6.tgz", + "integrity": "sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg==", + "dev": true, + "dependencies": { + "@xtuc/ieee754": "^1.2.0" + } + }, + "node_modules/@webassemblyjs/leb128": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.6.tgz", + "integrity": "sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ==", + "dev": true, + "dependencies": { + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webassemblyjs/utf8": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.6.tgz", + "integrity": "sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA==", + "dev": true + }, + "node_modules/@webassemblyjs/wasm-edit": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.6.tgz", + "integrity": "sha512-Ybn2I6fnfIGuCR+Faaz7YcvtBKxvoLV3Lebn1tM4o/IAJzmi9AWYIPWpyBfU8cC+JxAO57bk4+zdsTjJR+VTOw==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.11.6", + "@webassemblyjs/helper-buffer": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/helper-wasm-section": "1.11.6", + "@webassemblyjs/wasm-gen": "1.11.6", + "@webassemblyjs/wasm-opt": "1.11.6", + "@webassemblyjs/wasm-parser": "1.11.6", + "@webassemblyjs/wast-printer": "1.11.6" + } + }, + "node_modules/@webassemblyjs/wasm-gen": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.6.tgz", + "integrity": "sha512-3XOqkZP/y6B4F0PBAXvI1/bky7GryoogUtfwExeP/v7Nzwo1QLcq5oQmpKlftZLbT+ERUOAZVQjuNVak6UXjPA==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/ieee754": "1.11.6", + "@webassemblyjs/leb128": "1.11.6", + "@webassemblyjs/utf8": "1.11.6" + } + }, + "node_modules/@webassemblyjs/wasm-opt": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.6.tgz", + "integrity": "sha512-cOrKuLRE7PCe6AsOVl7WasYf3wbSo4CeOk6PkrjS7g57MFfVUF9u6ysQBBODX0LdgSvQqRiGz3CXvIDKcPNy4g==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.11.6", + "@webassemblyjs/helper-buffer": "1.11.6", + "@webassemblyjs/wasm-gen": "1.11.6", + "@webassemblyjs/wasm-parser": "1.11.6" + } + }, + "node_modules/@webassemblyjs/wasm-parser": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.6.tgz", + "integrity": "sha512-6ZwPeGzMJM3Dqp3hCsLgESxBGtT/OeCvCZ4TA1JUPYgmhAx38tTPR9JaKy0S5H3evQpO/h2uWs2j6Yc/fjkpTQ==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.11.6", + "@webassemblyjs/helper-api-error": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/ieee754": "1.11.6", + "@webassemblyjs/leb128": "1.11.6", + "@webassemblyjs/utf8": "1.11.6" + } + }, + "node_modules/@webassemblyjs/wast-printer": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.11.6.tgz", + "integrity": "sha512-JM7AhRcE+yW2GWYaKeHL5vt4xqee5N2WcezptmgyhNS+ScggqcT1OtXykhAb13Sn5Yas0j2uv9tHgrjwvzAP4A==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.11.6", + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webpack-cli/configtest": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-2.1.1.tgz", + "integrity": "sha512-wy0mglZpDSiSS0XHrVR+BAdId2+yxPSoJW8fsna3ZpYSlufjvxnP4YbKTCBZnNIcGN4r6ZPXV55X4mYExOfLmw==", + "dev": true, + "engines": { + "node": ">=14.15.0" + }, + "peerDependencies": { + "webpack": "5.x.x", + "webpack-cli": "5.x.x" + } + }, + "node_modules/@webpack-cli/info": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@webpack-cli/info/-/info-2.0.2.tgz", + "integrity": "sha512-zLHQdI/Qs1UyT5UBdWNqsARasIA+AaF8t+4u2aS2nEpBQh2mWIVb8qAklq0eUENnC5mOItrIB4LiS9xMtph18A==", + "dev": true, + "engines": { + "node": ">=14.15.0" + }, + "peerDependencies": { + "webpack": "5.x.x", + "webpack-cli": "5.x.x" + } + }, + "node_modules/@webpack-cli/serve": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-2.0.5.tgz", + "integrity": "sha512-lqaoKnRYBdo1UgDX8uF24AfGMifWK19TxPmM5FHc2vAGxrJ/qtyUyFBWoY1tISZdelsQ5fBcOusifo5o5wSJxQ==", + "dev": true, + "engines": { + "node": ">=14.15.0" + }, + "peerDependencies": { + "webpack": "5.x.x", + "webpack-cli": "5.x.x" + }, + "peerDependenciesMeta": { + "webpack-dev-server": { + "optional": true + } + } + }, + "node_modules/@xtuc/ieee754": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", + "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", + "dev": true + }, + "node_modules/@xtuc/long": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", + "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", + "dev": true + }, + "node_modules/acorn": { + "version": "8.10.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.10.0.tgz", + "integrity": "sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-import-assertions": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.9.0.tgz", + "integrity": "sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA==", + "dev": true, + "peerDependencies": { + "acorn": "^8" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ajv-keywords": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", + "dev": true, + "peerDependencies": { + "ajv": "^6.9.1" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/browserslist": { + "version": "4.22.1", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.22.1.tgz", + "integrity": "sha512-FEVc202+2iuClEhZhrWy6ZiAcRLvNMyYcxZ8raemul1DYVOVdFsbqckWLdsixQZCpJlwe77Z3UTalE7jsjnKfQ==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "caniuse-lite": "^1.0.30001541", + "electron-to-chromium": "^1.4.535", + "node-releases": "^2.0.13", + "update-browserslist-db": "^1.0.13" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "dev": true + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001547", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001547.tgz", + "integrity": "sha512-W7CrtIModMAxobGhz8iXmDfuJiiKg1WADMO/9x7/CLNin5cpSbuBjooyoIUVB5eyCc36QuTVlkVa1iB2S5+/eA==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ] + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/chalk/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/chrome-trace-event": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz", + "integrity": "sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==", + "dev": true, + "engines": { + "node": ">=6.0" + } + }, + "node_modules/clone-deep": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", + "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==", + "dev": true, + "dependencies": { + "is-plain-object": "^2.0.4", + "kind-of": "^6.0.2", + "shallow-clone": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/colorette": { + "version": "2.0.20", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", + "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==", + "dev": true + }, + "node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true + }, + "node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true + }, + "node_modules/doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/electron-to-chromium": { + "version": "1.4.549", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.549.tgz", + "integrity": "sha512-gpXfJslSi4hYDkA0mTLEpYKRv9siAgSUgZ+UWyk+J5Cttpd1ThCVwdclzIwQSclz3hYn049+M2fgrP1WpvF8xg==", + "dev": true + }, + "node_modules/enhanced-resolve": { + "version": "5.15.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.15.0.tgz", + "integrity": "sha512-LXYT42KJ7lpIKECr2mAXIaMldcNCh/7E0KBKOu4KSfkHmP+mZmSs+8V5gBAqisWBy0OO4W5Oyys0GO1Y8KtdKg==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.2.4", + "tapable": "^2.2.0" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/envinfo": { + "version": "7.10.0", + "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.10.0.tgz", + "integrity": "sha512-ZtUjZO6l5mwTHvc1L9+1q5p/R3wTopcfqMW8r5t8SJSKqeVI/LtajORwRFEKpEFuekjD0VBjwu1HMxL4UalIRw==", + "dev": true, + "bin": { + "envinfo": "dist/cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/es-module-lexer": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.3.1.tgz", + "integrity": "sha512-JUFAyicQV9mXc3YRxPnDlrfBKpqt6hUYzz9/boprUJHs4e4KVr3XwOF70doO6gwXUor6EWZJAyWAfKki84t20Q==", + "dev": true + }, + "node_modules/escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint": { + "version": "8.52.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.52.0.tgz", + "integrity": "sha512-zh/JHnaixqHZsolRB/w9/02akBk9EPrOs9JwcTP2ek7yL5bVvXuRariiaAjjoJ5DvuwQ1WAE/HsMz+w17YgBCg==", + "dev": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.6.1", + "@eslint/eslintrc": "^2.1.2", + "@eslint/js": "8.52.0", + "@humanwhocodes/config-array": "^0.11.13", + "@humanwhocodes/module-importer": "^1.0.1", + "@nodelib/fs.walk": "^1.2.8", + "@ungap/structured-clone": "^1.2.0", + "ajv": "^6.12.4", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.3.2", + "doctrine": "^3.0.0", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^7.2.2", + "eslint-visitor-keys": "^3.4.3", + "espree": "^9.6.1", + "esquery": "^1.4.2", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "globals": "^13.19.0", + "graphemer": "^1.4.0", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "is-path-inside": "^3.0.3", + "js-yaml": "^4.1.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3", + "strip-ansi": "^6.0.1", + "text-table": "^0.2.0" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "dev": true, + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint/node_modules/eslint-scope": { + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", + "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", + "dev": true, + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint/node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/eslint/node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/espree": { + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", + "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", + "dev": true, + "dependencies": { + "acorn": "^8.9.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^3.4.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/esquery": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", + "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", + "dev": true, + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esquery/node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esrecurse/node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/events": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", + "dev": true, + "engines": { + "node": ">=0.8.x" + } + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true + }, + "node_modules/fastest-levenshtein": { + "version": "1.0.16", + "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz", + "integrity": "sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==", + "dev": true, + "engines": { + "node": ">= 4.9.1" + } + }, + "node_modules/fastq": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz", + "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==", + "dev": true, + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/file-entry-cache": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "dev": true, + "dependencies": { + "flat-cache": "^3.0.4" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/flat-cache": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.1.1.tgz", + "integrity": "sha512-/qM2b3LUIaIgviBQovTLvijfyOQXPtSRnRK26ksj2J7rzPIecePUIpJsZ4T02Qg+xiAEKIs5K8dsHEd+VaKa/Q==", + "dev": true, + "dependencies": { + "flatted": "^3.2.9", + "keyv": "^4.5.3", + "rimraf": "^3.0.2" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/flatted": { + "version": "3.2.9", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.9.tgz", + "integrity": "sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ==", + "dev": true + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true + }, + "node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/glob-to-regexp": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", + "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", + "dev": true + }, + "node_modules/globals": { + "version": "13.23.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.23.0.tgz", + "integrity": "sha512-XAmF0RjlrjY23MA51q3HltdlGxUpXPvg0GioKiD9X6HD28iMjo2dKC8Vqwm7lne4GNr78+RHTfliktR6ZH09wA==", + "dev": true, + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true + }, + "node_modules/graphemer": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", + "dev": true + }, + "node_modules/has": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.4.tgz", + "integrity": "sha512-qdSAmqLF6209RFj4VVItywPMbm3vWylknmB3nvNiUIs72xAimcM8nVYxYr7ncvZq5qzk9MKIZR8ijqD/1QuYjQ==", + "dev": true, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/ignore": { + "version": "5.2.4", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", + "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dev": true, + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/import-fresh/node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/import-local": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz", + "integrity": "sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==", + "dev": true, + "dependencies": { + "pkg-dir": "^4.2.0", + "resolve-cwd": "^3.0.0" + }, + "bin": { + "import-local-fixture": "fixtures/cli.js" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "dev": true, + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "node_modules/interpret": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-3.1.1.tgz", + "integrity": "sha512-6xwYfHbajpoF0xLW+iwLkhwgvLoZDfjYfoFNu8ftMoXINzwuymNLd9u/KmwtdT2GbR+/Cz66otEGEVVUHX9QLQ==", + "dev": true, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/is-core-module": { + "version": "2.13.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.0.tgz", + "integrity": "sha512-Z7dk6Qo8pOCp3l4tsX2C5ZVas4V+UxwQodwZhLopL91TX8UyyHEXafPcyoeeWuLrwzHcr3igO78wNLwHJHsMCQ==", + "dev": true, + "dependencies": { + "has": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "dev": true, + "dependencies": { + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true + }, + "node_modules/isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/jest-worker": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", + "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==", + "dev": true, + "dependencies": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true + }, + "node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "dev": true + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "dev": true + }, + "node_modules/keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "dev": true, + "dependencies": { + "json-buffer": "3.0.1" + } + }, + "node_modules/kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/loader-runner": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz", + "integrity": "sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==", + "dev": true, + "engines": { + "node": ">=6.11.5" + } + }, + "node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true + }, + "node_modules/merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dev": true, + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true + }, + "node_modules/neo-async": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", + "dev": true + }, + "node_modules/node-releases": { + "version": "2.0.13", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.13.tgz", + "integrity": "sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ==", + "dev": true + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/optionator": { + "version": "0.9.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", + "integrity": "sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==", + "dev": true, + "dependencies": { + "@aashutoshrathi/word-wrap": "^1.2.3", + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true + }, + "node_modules/picocolors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", + "dev": true + }, + "node_modules/pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "dev": true, + "dependencies": { + "find-up": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/punycode": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz", + "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dev": true, + "dependencies": { + "safe-buffer": "^5.1.0" + } + }, + "node_modules/rechoir": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.8.0.tgz", + "integrity": "sha512-/vxpCXddiX8NGfGO/mTafwjq4aFa/71pvamip0++IQk3zG8cbCj0fifNPrjjF1XMXUne91jL9OoxmdykoEtifQ==", + "dev": true, + "dependencies": { + "resolve": "^1.20.0" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/resolve": { + "version": "1.22.8", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", + "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", + "dev": true, + "dependencies": { + "is-core-module": "^2.13.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-cwd": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", + "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", + "dev": true, + "dependencies": { + "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true, + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/schema-utils": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", + "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", + "dev": true, + "dependencies": { + "@types/json-schema": "^7.0.8", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/serialize-javascript": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.1.tgz", + "integrity": "sha512-owoXEFjWRllis8/M1Q+Cw5k8ZH40e3zhp/ovX+Xr/vi1qj6QesbyXXViFbpNvWvPNAD62SutwEXavefrLJWj7w==", + "dev": true, + "dependencies": { + "randombytes": "^2.1.0" + } + }, + "node_modules/shallow-clone": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", + "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==", + "dev": true, + "dependencies": { + "kind-of": "^6.0.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-support": { + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "dev": true, + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/tapable": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", + "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/terser": { + "version": "5.21.0", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.21.0.tgz", + "integrity": "sha512-WtnFKrxu9kaoXuiZFSGrcAvvBqAdmKx0SFNmVNYdJamMu9yyN3I/QF0FbH4QcqJQ+y1CJnzxGIKH0cSj+FGYRw==", + "dev": true, + "dependencies": { + "@jridgewell/source-map": "^0.3.3", + "acorn": "^8.8.2", + "commander": "^2.20.0", + "source-map-support": "~0.5.20" + }, + "bin": { + "terser": "bin/terser" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/terser-webpack-plugin": { + "version": "5.3.9", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.9.tgz", + "integrity": "sha512-ZuXsqE07EcggTWQjXUj+Aot/OMcD0bMKGgF63f7UxYcu5/AJF53aIpK1YoP5xR9l6s/Hy2b+t1AM0bLNPRuhwA==", + "dev": true, + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.17", + "jest-worker": "^27.4.5", + "schema-utils": "^3.1.1", + "serialize-javascript": "^6.0.1", + "terser": "^5.16.8" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.1.0" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "esbuild": { + "optional": true + }, + "uglify-js": { + "optional": true + } + } + }, + "node_modules/text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", + "dev": true + }, + "node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/undici-types": { + "version": "5.25.3", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.25.3.tgz", + "integrity": "sha512-Ga1jfYwRn7+cP9v8auvEXN1rX3sWqlayd4HP7OKk4mZWylEmu3KzXDUGrQUN6Ol7qo1gPvB2e5gX6udnyEPgdA==", + "dev": true + }, + "node_modules/update-browserslist-db": { + "version": "1.0.13", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz", + "integrity": "sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "escalade": "^3.1.1", + "picocolors": "^1.0.0" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/watchpack": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.0.tgz", + "integrity": "sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg==", + "dev": true, + "dependencies": { + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.1.2" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/webpack": { + "version": "5.88.2", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.88.2.tgz", + "integrity": "sha512-JmcgNZ1iKj+aiR0OvTYtWQqJwq37Pf683dY9bVORwVbUrDhLhdn/PlO2sHsFHPkj7sHNQF3JwaAkp49V+Sq1tQ==", + "dev": true, + "dependencies": { + "@types/eslint-scope": "^3.7.3", + "@types/estree": "^1.0.0", + "@webassemblyjs/ast": "^1.11.5", + "@webassemblyjs/wasm-edit": "^1.11.5", + "@webassemblyjs/wasm-parser": "^1.11.5", + "acorn": "^8.7.1", + "acorn-import-assertions": "^1.9.0", + "browserslist": "^4.14.5", + "chrome-trace-event": "^1.0.2", + "enhanced-resolve": "^5.15.0", + "es-module-lexer": "^1.2.1", + "eslint-scope": "5.1.1", + "events": "^3.2.0", + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.2.9", + "json-parse-even-better-errors": "^2.3.1", + "loader-runner": "^4.2.0", + "mime-types": "^2.1.27", + "neo-async": "^2.6.2", + "schema-utils": "^3.2.0", + "tapable": "^2.1.1", + "terser-webpack-plugin": "^5.3.7", + "watchpack": "^2.4.0", + "webpack-sources": "^3.2.3" + }, + "bin": { + "webpack": "bin/webpack.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependenciesMeta": { + "webpack-cli": { + "optional": true + } + } + }, + "node_modules/webpack-cli": { + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-5.1.4.tgz", + "integrity": "sha512-pIDJHIEI9LR0yxHXQ+Qh95k2EvXpWzZ5l+d+jIo+RdSm9MiHfzazIxwwni/p7+x4eJZuvG1AJwgC4TNQ7NRgsg==", + "dev": true, + "dependencies": { + "@discoveryjs/json-ext": "^0.5.0", + "@webpack-cli/configtest": "^2.1.1", + "@webpack-cli/info": "^2.0.2", + "@webpack-cli/serve": "^2.0.5", + "colorette": "^2.0.14", + "commander": "^10.0.1", + "cross-spawn": "^7.0.3", + "envinfo": "^7.7.3", + "fastest-levenshtein": "^1.0.12", + "import-local": "^3.0.2", + "interpret": "^3.1.1", + "rechoir": "^0.8.0", + "webpack-merge": "^5.7.3" + }, + "bin": { + "webpack-cli": "bin/cli.js" + }, + "engines": { + "node": ">=14.15.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "5.x.x" + }, + "peerDependenciesMeta": { + "@webpack-cli/generators": { + "optional": true + }, + "webpack-bundle-analyzer": { + "optional": true + }, + "webpack-dev-server": { + "optional": true + } + } + }, + "node_modules/webpack-cli/node_modules/commander": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz", + "integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==", + "dev": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/webpack-merge": { + "version": "5.9.0", + "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.9.0.tgz", + "integrity": "sha512-6NbRQw4+Sy50vYNTw7EyOn41OZItPiXB8GNv3INSoe3PSFaHJEz3SHTrYVaRm2LilNGnFUzh0FAwqPEmU/CwDg==", + "dev": true, + "dependencies": { + "clone-deep": "^4.0.1", + "wildcard": "^2.0.0" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/webpack-sources": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.3.tgz", + "integrity": "sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==", + "dev": true, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/wildcard": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.1.tgz", + "integrity": "sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ==", + "dev": true + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } } - } - }, - "node_modules/webpack-cli/node_modules/commander": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz", - "integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==", - "dev": true, - "engines": { - "node": ">=14" - } - }, - "node_modules/webpack-merge": { - "version": "5.9.0", - "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.9.0.tgz", - "integrity": "sha512-6NbRQw4+Sy50vYNTw7EyOn41OZItPiXB8GNv3INSoe3PSFaHJEz3SHTrYVaRm2LilNGnFUzh0FAwqPEmU/CwDg==", - "dev": true, - "dependencies": { - "clone-deep": "^4.0.1", - "wildcard": "^2.0.0" - }, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/webpack-sources": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.3.tgz", - "integrity": "sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==", - "dev": true, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/wildcard": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.1.tgz", - "integrity": "sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ==", - "dev": true } - } } diff --git a/package.json b/package.json index 2bbdf0b..cc044e3 100644 --- a/package.json +++ b/package.json @@ -10,6 +10,7 @@ "author": "", "license": "ISC", "devDependencies": { + "eslint": "^8.52.0", "webpack": "^5.88.2", "webpack-cli": "^5.1.4" } diff --git a/src/api.js b/src/api.js new file mode 100644 index 0000000..e73c24e --- /dev/null +++ b/src/api.js @@ -0,0 +1,151 @@ +"use strict"; + +import { CardHandler } from "./cardhandler"; +import { CardList } from "./cardlist"; +import { generateElementsFromLoadedData } from "./layout"; +import { TaskItem } from "./task"; + + +export class API { + get Tasks() { + return this.tasks; + } + + get TaskLists() { + return Array.from(this.cardHandler.Lists.values()); + } + + get CurrentTaskIndex() { + return this.currentTaskIndex; + } + + constructor() { + this.currentTaskIndex = 0; + this.tasks = new Map(); + this.cardHandler = new CardHandler(); + } + + serializeToLocalStorage() { + const kanbanStr = JSON.stringify({ + index: this.currentTaskIndex, + tasks: Array.from(this.tasks.entries()), + taskLists: Array.from(this.cardHandler.Lists.keys()), + }); + localStorage.setItem("my-kanban-board", kanbanStr); + } + + tryLoadFromLocalStorage() { + const boardDataStr = localStorage.getItem("my-kanban-board"); + if (!boardDataStr) { + return; + } + + const boardData = JSON.parse(boardDataStr); + this.currentTaskIndex = boardData.index; + + boardData.tasks.forEach((item) => + this.tasks.set(item[0], TaskItem.fromLoadedData(item[1])) + ); + boardData.taskLists.forEach((list) => + this.cardHandler.push(new CardList(list, listNameToID(list))) + ); + + this.cardHandler.setHasDefault(); + + generateElementsFromLoadedData(this); + } + + removeTaskItem(item) { + this.tasks.delete(item.ID); + } + + tryAddNewList() { + return this.cardHandler.tryAddNewList(); + } + + /** + * @param {string} identifier + */ + taskListContains(identifier) { + return this.cardHandler.Lists.has(identifier); + } + + /** + * @param {string} oldID + * @param {string} newID + */ + renameTaskList(oldID, newID) { + this.cardHandler.renameTaskList(oldID, newID); + this.cardHandler.setHasDefault(); + } + + /** + * @param {string} identifier + */ + deleteTaskList(identifier) { + this.cardHandler.removeWithID(identifier); + } + + /** + * @param {Date} createdAt + * @param {string} listID + * @param {string} title + * @param {string} tag + * @param {Date} dueDate + * @param {string} color + * @param {string} description + */ + addNewTask( + createdAt, + listID, + title, + tag, + dueDate, + color, + description + ) { + this.tasks.set( + this.currentTaskIndex, + new TaskItem( + this.currentTaskIndex, + createdAt, + listID, + title, + tag, + dueDate, + color, + description + ) + ); + this.advanceTask(); + } + + /** + * @param {string} identifier + * @returns {TaskItem} + */ + getTaskFromID(identifier) { + const indexStr = identifier.lastIndexOf("-") + 1; + const taskIndex = +identifier.slice(indexStr); + const task = this.tasks.get(taskIndex); + if (!task) { + console.log(identifier); + throw new Error(`Fatal task fetch error. Tried to fetch item with index: ${taskIndex}`); + } + return task; + } + + advanceTask() { + this.currentTaskIndex += 1; + } +} + +/** + * @param {string} value + * @returns + */ +export function listNameToID(value) { + let newName = new String(value); + newName = newName.replace(" ", "-").toLocaleLowerCase().concat("-list"); + return newName.toString(); +} diff --git a/src/cardhandler.js b/src/cardhandler.js new file mode 100644 index 0000000..1b0d3fb --- /dev/null +++ b/src/cardhandler.js @@ -0,0 +1,75 @@ +"use strict"; + +import { listNameToID } from "./api"; +import { CardList } from "./cardlist"; + +export class CardHandler { + get HasDefault() { + return this.hasDefault; + } + + get Lists() { + return this.lists; + } + + constructor() { + this.hasDefault = false; + this.lists = new Map(); + } + + setHasDefault() { + this.hasDefault = this.lists.has("New List"); + } + + /** + * + * @param {CardList} list + */ + push(list) { + this.lists.set(list.Identifier, list); + } + + /** + * @returns {boolean} + */ + tryAddNewList() { + if (this.hasDefault) { + return false; + } + + this.lists.set("New List", new CardList("New List", "new-list")); + this.hasDefault = true; + + return true; + } + + /** + * + * @param {string} identifier + * @returns + */ + removeWithID(identifier) { + for (const [id, list] of this.lists.entries()) { + if (list.ElementID === identifier) { + this.lists.delete(id); + this.setHasDefault(); + return; + } + } + } + + /** + * @param {string} oldID + * @param {string} newID + */ + renameTaskList(oldID, newID) { + const oldCard = this.lists.get(oldID); + if (oldCard) { + this.lists.delete(oldID); + this.lists.set(newID, oldCard); + return; + } + + this.lists.set(newID, new CardList(newID, listNameToID(newID))); + } +} diff --git a/src/cardlist.js b/src/cardlist.js new file mode 100644 index 0000000..15b588c --- /dev/null +++ b/src/cardlist.js @@ -0,0 +1,16 @@ +"use strict"; + +export class CardList { + get Identifier() { + return this.identifier; + } + + get ElementID() { + return this.elementID; + } + + constructor(identifier, elementID) { + this.identifier = identifier; + this.elementID = elementID; + } +} diff --git a/src/dragging.js b/src/dragging.js new file mode 100644 index 0000000..3611d62 --- /dev/null +++ b/src/dragging.js @@ -0,0 +1,60 @@ +"use strict"; + +import { API } from "./api"; +import { addDragListeners } from "./layout"; + +/** + * @param {API} api + */ +export function setupDraggables(api) { + const dragables = document.querySelectorAll(".task"); + const droppables = document.querySelectorAll(".list-content"); + + dragables.forEach((task) => addDragListeners(task)); + droppables.forEach((zone) => setupListDragZone(api, zone)); +} + +/** + * @param {API} api + * @param {HTMLElement} zone + */ +export function setupListDragZone(api, zone) { + zone.addEventListener("dragover", (e) => { + e.preventDefault(); + + const bottomTask = insertAboveTask(zone, e.clientY); + const currentTask = document.querySelector(".is-dragging"); + + const taskItem = api.getTaskFromID(currentTask.id); + taskItem.setListID(zone.getAttribute("value")); + + if (!bottomTask) { + zone.appendChild(currentTask); + } else { + zone.insertBefore(currentTask, bottomTask); + } + + // Serialize to disk, after changes + api.serializeToLocalStorage(); + }); +} + +function insertAboveTask(zone, mouseY) { + // Grab all tasks that aren't currently being dragged + const els = zone.querySelectorAll(".task:not(.is-dragging)"); + + let closestTask = null; + let closestOffset = Number.NEGATIVE_INFINITY; + + els.forEach((task) => { + const { top } = task.getBoundingClientRect(); + const offset = mouseY - top; + + if (offset < 0 && offset > closestOffset) { + closestOffset = offset; + closestTask = task; + } + }); + + return closestTask; +} diff --git a/src/index.js b/src/index.js new file mode 100644 index 0000000..2b9809c --- /dev/null +++ b/src/index.js @@ -0,0 +1,24 @@ +"use strict"; + +import { API } from "./api"; +import { setupDraggables } from "./dragging"; +import { + setupModalLayout, + setupAddTask, + setupListAddButton, + setupErrorModalLayout, +} from "./layout"; + +function main() { + const api = new API(); + api.tryLoadFromLocalStorage(); + + setupAddTask(api); + setupListAddButton(api); + setupDraggables(api); + + setupErrorModalLayout(); + setupModalLayout(); +} + +window.addEventListener("load", main); diff --git a/src/layout.js b/src/layout.js new file mode 100644 index 0000000..b88b492 --- /dev/null +++ b/src/layout.js @@ -0,0 +1,419 @@ +"use strict"; + +import { API, listNameToID } from "./api"; +import { setupListDragZone } from "./dragging"; +import { tagKindToStr, tagStrToKind } from "./task"; + +/** + * + * @param {API} api + */ +export function setupListAddButton(api) { + const btn = document.querySelector("#list-add-btn"); + btn.onclick = () => { + const listDiv = document.querySelector("#task-lists"); + const listEl = createDefaultList(api); + if (!listEl) { + showErrorModal("Cannot create default list, as one already exists."); + return; + } + + listDiv.insertBefore(listEl, listDiv.children[listDiv.children.length - 1]); + + // Save results to disk + api.serializeToLocalStorage(); + }; +} + +export function setupErrorModalLayout() { + const modal = document.querySelector("#error-modal"); + const close = document.querySelector("#error-modal-close"); + + close.onclick = function (e) { + e.preventDefault(); + modal.style.display = "none"; + }; +} + +export function setupModalLayout() { + // Get the modal + const modal = document.querySelector("#modal"); + const modalHeader = document.querySelector("#modal-header"); + + // Get the element that closes the modal + const span = document.querySelector("#close"); + const colorSelected = document.querySelector("#color-selected"); + const firstStyle = colorSelected.options[0].style; + colorSelected.value = firstStyle.backgroundColor; + colorSelected.style.background = firstStyle.backgroundColor; + + span.onclick = function () { + modal.style.display = "none"; + }; + + colorSelected.onchange = function () { + const color = colorSelected.options[colorSelected.selectedIndex].style.backgroundColor; + + colorSelected.style.backgroundColor = color; + modalHeader.style.backgroundColor = color; + }; +} + +/** + * + * @param {HTMLElement} el + */ +export function addDragListeners(el) { + el.addEventListener("dragstart", () => { + el.classList.add("is-dragging"); + }); + el.addEventListener("dragend", () => { + el.classList.remove("is-dragging"); + }); +} + +/** + * + * @param {string} message + */ +export function showErrorModal(message) { + const errorModal = document.querySelector("#error-modal"); + const modalText = document.querySelector("#error-modal-text") ; + + modalText.innerText = message; + errorModal.style.display = "block"; +} + +/** + * + * @param {API} api + */ +export function setupAddTask(api) { + const form = document.querySelector("#add-task-btn"); + + form.onclick = (e) => { + e.preventDefault(); + + const lists = document.querySelectorAll(".swim-list"); + if (lists.length === 0) { + showErrorModal("No lists available to add a task."); + return; + } + + const modal = document.querySelector("#modal"); + modal.style.display = "block"; + setupNewTaskModalFields(api); + }; +} + +/** + * + * @param {API} api + */ +export function setupNewTaskModalFields(api) { + const modal = document.querySelector("#modal"); + const modalHeader = document.querySelector("#modal-header"); + const createdOn = document.querySelector("#created-on"); + const taskTitle = document.querySelector("#task-title"); + const taskDesc = document.querySelector("#task-desc"); + const saveBtn = document.querySelector("#modal-save-btn"); + const deleteBtn = document.querySelector("#modal-delete-btn"); + + const tagKind = document.querySelector("#kind-option"); + tagKind.value = "prg"; + + const dueDate = document.querySelector("#due-date"); + dueDate.valueAsDate = null; + + const colorSelected = document.querySelector("#color-selected"); + const firstStyle = colorSelected.options[0].style; + colorSelected.value = firstStyle.backgroundColor; + colorSelected.style.background = firstStyle.backgroundColor; + + modalHeader.style.backgroundColor = colorSelected.value; + + const taskTitleText = `Task Title #${api.CurrentTaskIndex + 1}`; + taskTitle.value = taskTitleText; + taskDesc.value = ""; + + const date = new Date(); + modal.style.display = "block"; + createdOn.innerText = `Created on ${date.toDateString()}`; + + saveBtn.onclick = () => { + if (taskTitle.value === taskTitleText) { + showErrorModal("Invalid title name."); + return; + } + + // Add to todo list + const firstList = document.querySelectorAll(".swim-list")[0]; + const listContent = firstList.querySelector(".list-content"); + + const taskEl = createTaskItemElement(api, taskTitle.value, api.CurrentTaskIndex); + listContent.appendChild(taskEl); + + const tagKind = document.querySelector("#kind-option"); + const dueDate = document.querySelector("#due-date"); + const colorSelected = document.querySelector("#color-selected"); + + api.addNewTask( + date, + firstList.id, + taskTitle.value, + tagStrToKind(tagKind.value), + dueDate.valueAsDate, + colorSelected.style.background, + taskDesc.value + ); + + // Save results to disk + api.serializeToLocalStorage(); + + // Hide modal + modal.style.display = "none"; + }; + + // Hide delete button when creating new task + deleteBtn.style.display = "none"; +} + +/** + * + * @param {API} api + */ +export function generateElementsFromLoadedData(api) { + const listDiv = document.querySelector("#task-lists"); + + // Generate all list elements + api.TaskLists.forEach((list) => { + const listEl = createListWithName(api, list.Identifier); + listDiv.insertBefore(listEl, listDiv.children[listDiv.children.length - 1]); + }); + + // Generate all task elements + api.Tasks.forEach((task) => { + const list = document.querySelector(`#${task.ListID}`); + const content = list.querySelector(".list-content"); + content.appendChild(createTaskItemElement(api, task.Title, task.ID)); + }); +} + +/** + * + * @param {API} api + * @param {string} taskID + */ +function populateTaskModalFields(api, taskID) { + const task = api.getTaskFromID(taskID); + + const modal = document.querySelector("#modal"); + const modalHeader = document.querySelector("#modal-header"); + const createdOn = document.querySelector("#created-on"); + const taskTitle = document.querySelector("#task-title"); + const saveBtn = document.querySelector("#modal-save-btn"); + const deleteBtn = document.querySelector("#modal-delete-btn"); + const taskDesc = document.querySelector("#task-desc"); + + const tagKind = document.querySelector("#kind-option"); + const dueDate = document.querySelector("#due-date-option"); + const colorSelected = document.querySelector("#color-selected"); + + const taskTitleText = task.Title; + taskTitle.value = taskTitleText; + taskDesc.value = task.Description; + createdOn.innerText = `Created on ${task.CreatedAt.toDateString()}`; + + tagKind.value = tagKindToStr(task.Tag); + dueDate.valueAsDate = task.DueDate; + + modalHeader.style.background = task.Color; + colorSelected.value = task.Color; + colorSelected.style.background = task.Color; + + saveBtn.onclick = () => { + task.applyFields( + taskTitle.value, + tagStrToKind(tagKind.value), + dueDate.valueAsDate, + colorSelected.style.background, + taskDesc.value + ); + + // Save results to disk + api.serializeToLocalStorage(); + + // Hide modal + modal.style.display = "none"; + }; + + deleteBtn.style.display = "inline"; + deleteBtn.onclick = () => { + // TODO: Add confirmation modal + + api.removeTaskItem(task); + + const listEl = document.querySelector(`#${task.ListID}`); + const content = listEl.querySelector(".list-content"); + content.removeChild(document.querySelector(`#task-id-${task.ID}`)); + + // Save results to disk + api.serializeToLocalStorage(); + + // Hide modal + modal.style.display = "none"; + }; + + // Show modal + modal.style.display = "block"; +} + +/** + * + * @param {API} api + * @param {string} taskTitle + * @param {number} index + * @returns + */ +function createTaskItemElement(api, taskTitle, index) { + /** + *
+

Get Groceries

+ +
+ */ + const taskID = `task-id-${index}`; + const newTask = document.createElement("div"); + newTask.className = "task"; + newTask.id = taskID; + newTask.setAttribute("draggable", "true"); + + const taskTitleEl = document.createElement("p"); + newTask.appendChild(taskTitleEl); + + taskTitleEl.className = "task-title"; + taskTitleEl.innerText = taskTitle; + + const innerBtn = document.createElement("button"); + newTask.appendChild(innerBtn); + + innerBtn.className = "task-edit"; + innerBtn.innerText = "..."; + innerBtn.onclick = () => populateTaskModalFields(api, taskID); + + addDragListeners(newTask); + + return newTask; +} + +/** + * + * @param {API} api + * @returns + */ +function createDefaultList(api) { + if (!api.tryAddNewList()) { + return null; + } + + return createListWithName(api, "New List"); +} + +/** + * + * @param {API} api + * @param {string} title + * @returns + */ +function createListWithName(api, title) { + /** + *
+ TODO +
+ */ + const listID = listNameToID(title); + + const el = document.createElement("div"); + el.className = "swim-list"; + el.id = listID; + + const header = document.createElement("div"); + el.appendChild(header); + header.className = "list-heading-inner-text"; + + const headerTitle = document.createElement("input"); + header.appendChild(headerTitle); + + headerTitle.className = "list-heading-input"; + headerTitle.type = "text"; + headerTitle.value = title; + headerTitle.defaultValue = title; + + headerTitle.onchange = (e) => listHeaderChange(el, headerTitle, e, api); + + const listContentZone = document.createElement("div"); + el.appendChild(listContentZone); + + listContentZone.setAttribute("value", listID); + listContentZone.className = "list-content"; + + setupListDragZone(api, listContentZone); + + const deleteSpan = document.createElement("span"); + header.appendChild(deleteSpan); + + deleteSpan.className = "list-delete-span"; + deleteSpan.innerText = "\u{00D7}"; + deleteSpan.onclick = (e) => { + e.preventDefault(); + + if (listContentZone.children.length > 0) { + showErrorModal("Cannot delete list that contains tasks."); + return; + } + + const listDiv = document.querySelector("#task-lists"); + listDiv.removeChild(el); + + api.deleteTaskList(listID); + + // Save results to disk + api.serializeToLocalStorage(); + }; + + return el; +} + +/** + * + * @param {HTMLElement} el + * @param {HTMLInputElement} self + * @param {Event} e + * @param {API} api + * @returns + */ +function listHeaderChange(el, self, e, api) { + e.preventDefault(); + + const newID = listNameToID(self.value); + if (el.id === newID) { + return; + } + + if (api.taskListContains(self.value)) { + showErrorModal(`Task list with name '${self.value}' already exists.`); + self.value = self.defaultValue; + return; + } + + const content = el.querySelector(".list-content"); + content.setAttribute("value", newID); + + api.renameTaskList(self.defaultValue, self.value); + + self.defaultValue = self.value; + el.id = newID; + + // Save results to disk + api.serializeToLocalStorage(); +} diff --git a/src/task.js b/src/task.js new file mode 100644 index 0000000..92fee70 --- /dev/null +++ b/src/task.js @@ -0,0 +1,155 @@ +"use strict"; + +export const TagKind = { + Programming: 0, + Graphics: 1, + Documentation: 2, +}; + +export class TaskItem { + // Properties + get ID() { + return this.id; + } + + get CreatedAt() { + return this.createdAt; + } + + get ListID() { + return this.listID; + } + + get Title() { + return this.title; + } + + get Tag() { + return this.tag; + } + + get DueDate() { + return this.dueDate; + } + + get Color() { + return this.color; + } + + get Description() { + return this.description; + } + + /** + * + * @param {string} id + * @param {Date} createdAt + * @param {string} listID + * @param {string} title + * @param {TagKind} tag + * @param {Date | null} dueDate + * @param {string} color + * @param {string} description + */ + constructor( + id, + createdAt, + listID, + title, + tag, + dueDate, + color, + description + ) { + this.id = id; + this.createdAt = createdAt; + this.listID = listID; + this.title = title; + this.tag = tag; + this.dueDate = dueDate; + this.color = color; + this.description = description; + } + + /** + * + * @param {TaskItem} item + * @returns + */ + static fromLoadedData(item) { + return new TaskItem( + item.id, + new Date(item.createdAt), + item.listID, + item.title, + item.tag, + !item.dueDate ? null : new Date(item.dueDate), + item.color, + item.description + ); + } + + /** + * + * @param {string} listID + */ + setListID(listID) { + this.listID = listID; + } + + /** + * + * @param {string} title + * @param {TagKind} tag + * @param {Date | null} dueDate + * @param {string} color + * @param {string} description + */ + applyFields( + title, + tag, + dueDate, + color, + description + ) { + this.title = title; + this.tag = tag; + this.dueDate = dueDate; + this.color = color; + this.description = description; + } +} + +/** + * + * @param {string} tagStr + * @returns + */ +export function tagStrToKind(tagStr) { + switch (tagStr) { + case "prg": + return TagKind.Programming; + case "gfx": + return TagKind.Graphics; + case "doc": + return TagKind.Documentation; + default: + throw new Error(`Undefined tag kind '${tagStr}'`); + } +} + +/** + * + * @param {TagKind} tag + * @returns + */ +export function tagKindToStr(tag) { + switch (tag) { + case TagKind.Programming: + return "prg"; + case TagKind.Graphics: + return "gfx"; + case TagKind.Documentation: + return "doc"; + } +} diff --git a/ts-src/api.ts b/ts-src/api.ts deleted file mode 100644 index 2dcfa8d..0000000 --- a/ts-src/api.ts +++ /dev/null @@ -1,131 +0,0 @@ -import { CardHandler } from './cardhandler'; -import { CardList } from './cardlist'; -import { generateElementsFromLoadedData } from './layout'; -import { Color, DueDate, TagKind, TaskItem } from './task'; - -interface KanbanBoardData { - index: number; - tasks: [number, TaskItem][]; - taskLists: string[]; -} - -export class API { - private currentTaskIndex: number; - private tasks: Map; - private cardHandler: CardHandler; - - get Tasks(): Map { - return this.tasks; - } - - get TaskLists(): Array { - return Array.from(this.cardHandler.Lists.values()); - } - - get CurrentTaskIndex(): number { - return this.currentTaskIndex; - } - - constructor() { - this.currentTaskIndex = 0; - this.tasks = new Map(); - this.cardHandler = new CardHandler(); - } - - public serializeToLocalStorage() { - const kanbanStr = JSON.stringify({ - index: this.currentTaskIndex, - tasks: Array.from(this.tasks.entries()), - taskLists: Array.from(this.cardHandler.Lists.keys()), - }); - localStorage.setItem('my-kanban-board', kanbanStr); - } - - public tryLoadFromLocalStorage() { - const boardDataStr = localStorage.getItem('my-kanban-board'); - if (!boardDataStr) { - return; - } - - const boardData: KanbanBoardData = JSON.parse(boardDataStr); - this.currentTaskIndex = boardData.index; - - boardData.tasks.forEach((item) => - this.tasks.set(item[0], TaskItem.fromLoadedData(item[1])) - ); - boardData.taskLists.forEach((list) => - this.cardHandler.push(new CardList(list, listNameToID(list))) - ); - - this.cardHandler.setHasDefault(); - - generateElementsFromLoadedData(this); - } - - public removeTaskItem(item: TaskItem) { - this.tasks.delete(item.ID); - } - - public tryAddNewList(): boolean { - return this.cardHandler.tryAddNewList(); - } - - public taskListContains(identifier: string): boolean { - return this.cardHandler.Lists.has(identifier); - } - - public renameTaskList(oldID: string, newID: string) { - this.cardHandler.renameTaskList(oldID, newID); - this.cardHandler.setHasDefault(); - } - - public deleteTaskList(identifier: string) { - this.cardHandler.removeWithID(identifier); - } - - public addNewTask( - createdAt: Date, - listID: string, - title: string, - tag: TagKind, - dueDate: DueDate, - color: Color, - description: string - ) { - this.tasks.set( - this.currentTaskIndex, - new TaskItem( - this.currentTaskIndex, - createdAt, - listID, - title, - tag, - dueDate, - color, - description - ) - ); - this.advanceTask(); - } - - public getTaskFromID(identifier: string): TaskItem { - const indexStr = identifier.lastIndexOf('-') + 1; - const taskIndex = +identifier.slice(indexStr); - const task = this.tasks.get(taskIndex); - if (!task) { - console.log(identifier); - throw new Error(`Fatal task fetch error. Tried to fetch item with index: ${taskIndex}`); - } - return task; - } - - private advanceTask() { - this.currentTaskIndex += 1; - } -} - -export function listNameToID(value: string): string { - let newName = new String(value); - newName = newName.replace(' ', '-').toLocaleLowerCase().concat('-list'); - return newName.toString(); -} diff --git a/ts-src/cardhandler.ts b/ts-src/cardhandler.ts deleted file mode 100644 index 17ff8eb..0000000 --- a/ts-src/cardhandler.ts +++ /dev/null @@ -1,60 +0,0 @@ -import { listNameToID } from './api'; -import { CardList } from './cardlist'; - -export class CardHandler { - private hasDefault: boolean; - private lists: Map; - - get HasDefault(): boolean { - return this.hasDefault; - } - - get Lists(): Map { - return this.lists; - } - - constructor() { - this.hasDefault = false; - this.lists = new Map(); - } - - public setHasDefault() { - this.hasDefault = this.lists.has('New List'); - } - - public push(list: CardList) { - this.lists.set(list.Identifier, list); - } - - public tryAddNewList(): boolean { - if (this.hasDefault) { - return false; - } - - this.lists.set('New List', new CardList('New List', 'new-list')); - this.hasDefault = true; - - return true; - } - - public removeWithID(identifier: string) { - for (let [id, list] of this.lists.entries()) { - if (list.ElementID === identifier) { - this.lists.delete(id); - this.setHasDefault(); - return; - } - } - } - - public renameTaskList(oldID: string, newID: string) { - const oldCard = this.lists.get(oldID); - if (oldCard) { - this.lists.delete(oldID); - this.lists.set(newID, oldCard); - return; - } - - this.lists.set(newID, new CardList(newID, listNameToID(newID))); - } -} diff --git a/ts-src/cardlist.ts b/ts-src/cardlist.ts deleted file mode 100644 index 3c3136c..0000000 --- a/ts-src/cardlist.ts +++ /dev/null @@ -1,17 +0,0 @@ -export class CardList { - private identifier: string; - private elementID: string; - - get Identifier(): string { - return this.identifier; - } - - get ElementID(): string { - return this.elementID; - } - - constructor(identifier: string, elementID: string) { - this.identifier = identifier; - this.elementID = elementID; - } -} diff --git a/ts-src/dragging.ts b/ts-src/dragging.ts deleted file mode 100644 index cfb09c8..0000000 --- a/ts-src/dragging.ts +++ /dev/null @@ -1,48 +0,0 @@ -import { API } from './api'; -import { addDragListeners } from './layout'; - -export function setupDraggables(api: API) { - const dragables = document.querySelectorAll('.task') as NodeListOf; - const droppables = document.querySelectorAll('.list-content') as NodeListOf; - - dragables.forEach((task) => addDragListeners(task)); - droppables.forEach((zone) => setupListDragZone(api, zone)); -} - -export function setupListDragZone(api: API, zone: HTMLElement) { - zone.addEventListener('dragover', (e) => { - e.preventDefault(); - - const bottomTask = insertAboveTask(zone, e.clientY); - const currentTask = document.querySelector('.is-dragging') as HTMLElement; - - const taskItem = api.getTaskFromID(currentTask.id); - taskItem.setListID(zone.getAttribute('value')!); - - if (!bottomTask) { - zone.appendChild(currentTask); - } else { - zone.insertBefore(currentTask, bottomTask); - } - }); -} - -function insertAboveTask(zone: HTMLElement, mouseY: number): HTMLElement | null { - // Grab all tasks that aren't currently being dragged - const els = zone.querySelectorAll('.task:not(.is-dragging)') as NodeListOf; - - let closestTask: HTMLElement | null = null; - let closestOffset = Number.NEGATIVE_INFINITY; - - els.forEach((task) => { - const { top } = task.getBoundingClientRect(); - const offset = mouseY - top; - - if (offset < 0 && offset > closestOffset) { - closestOffset = offset; - closestTask = task; - } - }); - - return closestTask; -} diff --git a/ts-src/index.ts b/ts-src/index.ts deleted file mode 100644 index 247e0ef..0000000 --- a/ts-src/index.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { API } from './api'; -import { setupDraggables } from './dragging'; -import { - setupModalLayout, - setupAddTask, - setupListAddButton, - setupErrorModalLayout, -} from './layout'; - -function main() { - const api = new API(); - api.tryLoadFromLocalStorage(); - - setupAddTask(api); - setupListAddButton(api); - setupDraggables(api); - - setupErrorModalLayout(); - setupModalLayout(); -} - -window.addEventListener('load', main); diff --git a/ts-src/layout.ts b/ts-src/layout.ts deleted file mode 100644 index 7385405..0000000 --- a/ts-src/layout.ts +++ /dev/null @@ -1,362 +0,0 @@ -import { API, listNameToID } from './api'; -import { setupListDragZone } from './dragging'; -import { tagKindToStr, tagStrToKind } from './task'; - -export function setupListAddButton(api: API) { - const btn = document.querySelector('#list-add-btn') as HTMLButtonElement; - btn.onclick = () => { - const listDiv = document.querySelector('#task-lists') as HTMLDivElement; - const listEl = createDefaultList(api); - if (!listEl) { - showErrorModal('Cannot create default list, as one already exists.'); - return; - } - - listDiv.insertBefore(listEl, listDiv.children[listDiv.children.length - 1]); - - // Save results to disk - api.serializeToLocalStorage(); - }; -} - -export function setupErrorModalLayout() { - const modal = document.querySelector('#error-modal') as HTMLDivElement; - const close = document.querySelector('#error-modal-close') as HTMLButtonElement; - - close.onclick = function (e) { - e.preventDefault(); - modal.style.display = 'none'; - }; -} - -export function setupModalLayout() { - // Get the modal - const modal = document.querySelector('#modal') as HTMLElement; - const modalHeader = document.querySelector('#modal-header') as HTMLElement; - - // Get the element that closes the modal - const span = document.querySelector('#close') as HTMLSpanElement; - const colorSelected = document.querySelector('#color-selected') as HTMLSelectElement; - const firstStyle = colorSelected.options[0].style; - colorSelected.value = firstStyle.backgroundColor; - colorSelected.style.background = firstStyle.backgroundColor; - - span.onclick = function () { - modal.style.display = 'none'; - }; - - colorSelected.onchange = function () { - let color = colorSelected.options[colorSelected.selectedIndex].style.backgroundColor; - - colorSelected.style.backgroundColor = color; - modalHeader.style.backgroundColor = color; - }; -} - -export function addDragListeners(el: HTMLElement) { - el.addEventListener('dragstart', () => { - el.classList.add('is-dragging'); - }); - el.addEventListener('dragend', () => { - el.classList.remove('is-dragging'); - }); -} - -export function showErrorModal(message: string) { - const errorModal = document.querySelector('#error-modal') as HTMLElement; - const modalText = document.querySelector('#error-modal-text') as HTMLHeadingElement; - - modalText.innerText = message; - errorModal.style.display = 'block'; -} - -export function setupAddTask(api: API) { - const form = document.querySelector('#add-task-btn') as HTMLButtonElement; - - form.onclick = (e) => { - e.preventDefault(); - - const lists = document.querySelectorAll('.swim-list') as NodeListOf; - if (lists.length === 0) { - showErrorModal('No lists available to add a task.'); - return; - } - - const modal = document.querySelector('#modal') as HTMLElement; - modal.style.display = 'block'; - setupNewTaskModalFields(api); - }; -} - -export function setupNewTaskModalFields(api: API) { - const modal = document.querySelector('#modal') as HTMLElement; - const modalHeader = document.querySelector('#modal-header') as HTMLElement; - const createdOn = document.querySelector('#created-on') as HTMLInputElement; - const taskTitle = document.querySelector('#task-title') as HTMLInputElement; - const taskDesc = document.querySelector('#task-desc') as HTMLTextAreaElement; - const saveBtn = document.querySelector('#modal-save-btn') as HTMLButtonElement; - const deleteBtn = document.querySelector('#modal-delete-btn') as HTMLButtonElement; - - const tagKind = document.querySelector('#kind-option') as HTMLSelectElement; - tagKind.value = 'prg'; - - const dueDate = document.querySelector('#due-date') as HTMLInputElement; - dueDate.valueAsDate = null; - - const colorSelected = document.querySelector('#color-selected') as HTMLSelectElement; - const firstStyle = colorSelected.options[0].style; - colorSelected.value = firstStyle.backgroundColor; - colorSelected.style.background = firstStyle.backgroundColor; - - modalHeader.style.backgroundColor = colorSelected.value; - - const taskTitleText = `Task Title #${api.CurrentTaskIndex + 1}`; - taskTitle.value = taskTitleText; - taskDesc.value = ''; - - const date = new Date(); - modal.style.display = 'block'; - createdOn.innerText = `Created on ${date.toDateString()}`; - - saveBtn.onclick = () => { - if (taskTitle.value === taskTitleText) { - showErrorModal('Invalid title name.'); - return; - } - - // Add to todo list - const firstList = (document.querySelectorAll('.swim-list') as NodeListOf)[0]; - const listContent = firstList.querySelector('.list-content') as HTMLDivElement; - - const taskEl = createTaskItemElement(api, taskTitle.value, api.CurrentTaskIndex); - listContent.appendChild(taskEl); - - const tagKind = document.querySelector('#kind-option') as HTMLSelectElement; - const dueDate = document.querySelector('#due-date') as HTMLInputElement; - const colorSelected = document.querySelector('#color-selected') as HTMLSelectElement; - - api.addNewTask( - date, - firstList.id, - taskTitle.value, - tagStrToKind(tagKind.value), - dueDate.valueAsDate, - colorSelected.style.background, - taskDesc.value - ); - - // Save results to disk - api.serializeToLocalStorage(); - - // Hide modal - modal.style.display = 'none'; - }; - - // Hide delete button when creating new task - deleteBtn.style.display = 'none'; -} - -export function generateElementsFromLoadedData(api: API) { - const listDiv = document.querySelector('#task-lists') as HTMLDivElement; - - // Generate all list elements - api.TaskLists.forEach((list) => { - const listEl = createListWithName(api, list.Identifier); - listDiv.insertBefore(listEl, listDiv.children[listDiv.children.length - 1]); - }); - - // Generate all task elements - api.Tasks.forEach((task) => { - const list = document.querySelector(`#${task.ListID}`) as HTMLDivElement; - const content = list.querySelector('.list-content') as HTMLDivElement; - content.appendChild(createTaskItemElement(api, task.Title, task.ID)); - }); -} - -function populateTaskModalFields(api: API, taskID: string) { - const task = api.getTaskFromID(taskID); - - const modal = document.querySelector('#modal') as HTMLElement; - const modalHeader = document.querySelector('#modal-header') as HTMLElement; - const createdOn = document.querySelector('#created-on') as HTMLElement; - const taskTitle = document.querySelector('#task-title') as HTMLInputElement; - const saveBtn = document.querySelector('#modal-save-btn') as HTMLButtonElement; - const deleteBtn = document.querySelector('#modal-delete-btn') as HTMLButtonElement; - const taskDesc = document.querySelector('#task-desc') as HTMLTextAreaElement; - - const tagKind = document.querySelector('#kind-option') as HTMLSelectElement; - const dueDate = document.querySelector('#due-date-option') as HTMLInputElement; - const colorSelected = document.querySelector('#color-selected') as HTMLSelectElement; - - const taskTitleText = task.Title; - taskTitle.value = taskTitleText; - taskDesc.value = task.Description; - createdOn.innerText = `Created on ${task.CreatedAt.toDateString()}`; - - tagKind.value = tagKindToStr(task.Tag); - dueDate.valueAsDate = task.DueDate; - - modalHeader.style.background = task.Color; - colorSelected.value = task.Color; - colorSelected.style.background = task.Color; - - saveBtn.onclick = () => { - task.applyFields( - taskTitle.value, - tagStrToKind(tagKind.value), - dueDate.valueAsDate, - colorSelected.style.background, - taskDesc.value - ); - - // Save results to disk - api.serializeToLocalStorage(); - - // Hide modal - modal.style.display = 'none'; - }; - - deleteBtn.style.display = 'inline'; - deleteBtn.onclick = () => { - // TODO: Add confirmation modal - - api.removeTaskItem(task); - - const listEl = document.querySelector(`#${task.ListID}`) as HTMLElement; - const content = listEl.querySelector('.list-content') as HTMLElement; - content.removeChild(document.querySelector(`#task-id-${task.ID}`)!); - - // Save results to disk - api.serializeToLocalStorage(); - - // Hide modal - modal.style.display = 'none'; - }; - - // Show modal - modal.style.display = 'block'; -} - -function createTaskItemElement(api: API, taskTitle: string, index: number): HTMLElement { - /** - *
-

Get Groceries

- -
- */ - const taskID = `task-id-${index}`; - const newTask = document.createElement('div') as HTMLDivElement; - newTask.className = 'task'; - newTask.id = taskID; - newTask.setAttribute('draggable', 'true'); - - const taskTitleEl = document.createElement('p') as HTMLParagraphElement; - newTask.appendChild(taskTitleEl); - - taskTitleEl.className = 'task-title'; - taskTitleEl.innerText = taskTitle; - - const innerBtn = document.createElement('button'); - newTask.appendChild(innerBtn); - - innerBtn.className = 'task-edit'; - innerBtn.innerText = '...'; - innerBtn.onclick = () => populateTaskModalFields(api, taskID); - - addDragListeners(newTask); - - return newTask; -} - -function createDefaultList(api: API): HTMLElement | null { - if (!api.tryAddNewList()) { - return null; - } - - return createListWithName(api, 'New List'); -} - -function createListWithName(api: API, title: string): HTMLElement { - /** - *
- TODO -
- */ - const listID = listNameToID(title); - - const el = document.createElement('div') as HTMLDivElement; - el.className = 'swim-list'; - el.id = listID; - - const header = document.createElement('div') as HTMLDivElement; - el.appendChild(header); - header.className = 'list-heading-inner-text'; - - const headerTitle = document.createElement('input') as HTMLInputElement; - header.appendChild(headerTitle); - - headerTitle.className = 'list-heading-input'; - headerTitle.type = 'text'; - headerTitle.value = title; - headerTitle.defaultValue = title; - - headerTitle.onchange = (e) => listHeaderChange(el, headerTitle, e, api); - - const listContentZone = document.createElement('div') as HTMLDivElement; - el.appendChild(listContentZone); - - listContentZone.setAttribute('value', listID); - listContentZone.className = 'list-content'; - - setupListDragZone(api, listContentZone); - - const deleteSpan = document.createElement('span') as HTMLSpanElement; - header.appendChild(deleteSpan); - - deleteSpan.className = 'list-delete-span'; - deleteSpan.innerText = '\u{00D7}'; - deleteSpan.onclick = (e) => { - e.preventDefault(); - - if (listContentZone.children.length > 0) { - showErrorModal('Cannot delete list that contains tasks.'); - return; - } - - const listDiv = document.querySelector('#task-lists') as HTMLDivElement; - listDiv.removeChild(el); - - api.deleteTaskList(listID); - - // Save results to disk - api.serializeToLocalStorage(); - }; - - return el; -} - -function listHeaderChange(el: HTMLElement, self: HTMLInputElement, e: Event, api: API) { - e.preventDefault(); - - const newID = listNameToID(self.value); - if (el.id === newID) { - return; - } - - if (api.taskListContains(self.value)) { - showErrorModal(`Task list with name '${self.value}' already exists.`); - self.value = self.defaultValue; - return; - } - - const content = el.querySelector('.list-content') as HTMLElement; - content.setAttribute('value', newID); - - api.renameTaskList(self.defaultValue, self.value); - - self.defaultValue = self.value; - el.id = newID; - - // Save results to disk - api.serializeToLocalStorage(); -} diff --git a/ts-src/task.ts b/ts-src/task.ts deleted file mode 100644 index 0c050aa..0000000 --- a/ts-src/task.ts +++ /dev/null @@ -1,128 +0,0 @@ -export enum TagKind { - Programming, - Graphics, - Documentation, -} - -export type DueDate = Date | null; -export type Color = string; - -export class TaskItem { - private readonly id: number; - private readonly createdAt: Date; - - private listID: string; - private title: string; - private tag: TagKind; - private dueDate: DueDate; - private color: Color; - private description: string; - - // Properties - get ID(): number { - return this.id; - } - - get CreatedAt(): Date { - return this.createdAt; - } - - get ListID(): string { - return this.listID; - } - - get Title(): string { - return this.title; - } - - get Tag(): TagKind { - return this.tag; - } - - get DueDate(): DueDate { - return this.dueDate; - } - - get Color(): Color { - return this.color; - } - - get Description(): string { - return this.description; - } - - constructor( - id: number, - createdAt: Date, - listID: string, - title: string, - tag: TagKind, - dueDate: DueDate, - color: Color, - description: string - ) { - this.id = id; - this.createdAt = createdAt; - this.listID = listID; - this.title = title; - this.tag = tag; - this.dueDate = dueDate; - this.color = color; - this.description = description; - } - - public static fromLoadedData(item: TaskItem): TaskItem { - return new TaskItem( - item.id, - new Date(item.createdAt), - item.listID, - item.title, - item.tag, - !item.dueDate ? null : new Date(item.dueDate), - item.color, - item.description - ); - } - - public setListID(listID: string) { - this.listID = listID; - } - - public applyFields( - title: string, - tag: TagKind, - dueDate: DueDate, - color: Color, - description: string - ) { - this.title = title; - this.tag = tag; - this.dueDate = dueDate; - this.color = color; - this.description = description; - } -} - -export function tagStrToKind(tagStr: string): TagKind { - switch (tagStr) { - case 'prg': - return TagKind.Programming; - case 'gfx': - return TagKind.Graphics; - case 'doc': - return TagKind.Documentation; - default: - throw new Error(`Undefined tag kind '${tagStr}'`); - } -} - -export function tagKindToStr(tag: TagKind): string { - switch (tag) { - case TagKind.Programming: - return 'prg'; - case TagKind.Graphics: - return 'gfx'; - case TagKind.Documentation: - return 'doc'; - } -} diff --git a/tsconfig.json b/tsconfig.json deleted file mode 100644 index 4f83fe5..0000000 --- a/tsconfig.json +++ /dev/null @@ -1,109 +0,0 @@ -{ - "compilerOptions": { - /* Visit https://aka.ms/tsconfig to read more about this file */ - - /* Projects */ - // "incremental": true, /* Save .tsbuildinfo files to allow for incremental compilation of projects. */ - // "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */ - // "tsBuildInfoFile": "./.tsbuildinfo", /* Specify the path to .tsbuildinfo incremental compilation file. */ - // "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects. */ - // "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */ - // "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */ - - /* Language and Environment */ - "target": "es2016", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */ - // "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */ - // "jsx": "preserve", /* Specify what JSX code is generated. */ - // "experimentalDecorators": true, /* Enable experimental support for legacy experimental decorators. */ - // "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */ - // "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h'. */ - // "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */ - // "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using 'jsx: react-jsx*'. */ - // "reactNamespace": "", /* Specify the object invoked for 'createElement'. This only applies when targeting 'react' JSX emit. */ - // "noLib": true, /* Disable including any library files, including the default lib.d.ts. */ - // "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */ - // "moduleDetection": "auto", /* Control what method is used to detect module-format JS files. */ - - /* Modules */ - "module": "commonjs", /* Specify what module code is generated. */ - "rootDir": "./ts-src", /* Specify the root folder within your source files. */ - // "moduleResolution": "node10", /* Specify how TypeScript looks up a file from a given module specifier. */ - // "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */ - // "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */ - // "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */ - // "typeRoots": [], /* Specify multiple folders that act like './node_modules/@types'. */ - // "types": [], /* Specify type package names to be included without being referenced in a source file. */ - // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ - // "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */ - // "allowImportingTsExtensions": true, /* Allow imports to include TypeScript file extensions. Requires '--moduleResolution bundler' and either '--noEmit' or '--emitDeclarationOnly' to be set. */ - // "resolvePackageJsonExports": true, /* Use the package.json 'exports' field when resolving package imports. */ - // "resolvePackageJsonImports": true, /* Use the package.json 'imports' field when resolving imports. */ - // "customConditions": [], /* Conditions to set in addition to the resolver-specific defaults when resolving imports. */ - // "resolveJsonModule": true, /* Enable importing .json files. */ - // "allowArbitraryExtensions": true, /* Enable importing files with any extension, provided a declaration file is present. */ - // "noResolve": true, /* Disallow 'import's, 'require's or ''s from expanding the number of files TypeScript should add to a project. */ - - /* JavaScript Support */ - // "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */ - // "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */ - // "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'. */ - - /* Emit */ - // "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */ - // "declarationMap": true, /* Create sourcemaps for d.ts files. */ - // "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */ - // "sourceMap": true, /* Create source map files for emitted JavaScript files. */ - // "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */ - // "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output. */ - "outDir": "./src", /* Specify an output folder for all emitted files. */ - // "removeComments": true, /* Disable emitting comments. */ - // "noEmit": true, /* Disable emitting files from a compilation. */ - // "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */ - // "importsNotUsedAsValues": "remove", /* Specify emit/checking behavior for imports that are only used for types. */ - // "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */ - // "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */ - // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ - // "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */ - // "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */ - // "newLine": "crlf", /* Set the newline character for emitting files. */ - // "stripInternal": true, /* Disable emitting declarations that have '@internal' in their JSDoc comments. */ - // "noEmitHelpers": true, /* Disable generating custom helper functions like '__extends' in compiled output. */ - // "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */ - // "preserveConstEnums": true, /* Disable erasing 'const enum' declarations in generated code. */ - // "declarationDir": "./", /* Specify the output directory for generated declaration files. */ - // "preserveValueImports": true, /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */ - - /* Interop Constraints */ - // "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */ - // "verbatimModuleSyntax": true, /* Do not transform or elide any imports or exports not marked as type-only, ensuring they are written in the output file's format based on the 'module' setting. */ - // "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */ - // "esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */ - // "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */ - "forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */ - - /* Type Checking */ - "strict": true, /* Enable all strict type-checking options. */ - "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied 'any' type. */ - "strictNullChecks": true, /* When type checking, take into account 'null' and 'undefined'. */ - "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */ - // "strictBindCallApply": true, /* Check that the arguments for 'bind', 'call', and 'apply' methods match the original function. */ - // "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */ - "noImplicitThis": true, /* Enable error reporting when 'this' is given the type 'any'. */ - // "useUnknownInCatchVariables": true, /* Default catch clause variables as 'unknown' instead of 'any'. */ - "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */ - "noUnusedLocals": true, /* Enable error reporting when local variables aren't read. */ - "noUnusedParameters": true, /* Raise an error when a function parameter isn't read. */ - // "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */ - // "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */ - "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */ - // "noUncheckedIndexedAccess": true, /* Add 'undefined' to a type when accessed using an index. */ - "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */ - // "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type. */ - // "allowUnusedLabels": true, /* Disable error reporting for unused labels. */ - // "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */ - - /* Completeness */ - // "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */ - "skipLibCheck": true /* Skip type checking all .d.ts files. */ - } -} diff --git a/webpack.config.js b/webpack.config.js index a623455..e797079 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -1,10 +1,10 @@ -const path = require('path'); +/* eslint-disable */ module.exports = { - entry: './src/index.js', - mode: 'development', - output: { - filename: 'index.js', - path: __dirname, - }, + entry: "./src/index.js", + mode: "development", + output: { + filename: "index.js", + path: __dirname, + }, };