From e7c3fcd190658c552485e2bee55ede30980a7b1a Mon Sep 17 00:00:00 2001 From: Yeonjeong Choi Date: Tue, 28 Feb 2023 23:16:19 +0900 Subject: [PATCH] =?UTF-8?q?feat:=20=ED=95=99=EC=8A=B5=EC=9D=84=20=EC=9C=84?= =?UTF-8?q?=ED=95=B4=20=EC=B9=B4=EB=93=9C=20=EB=AD=89=EC=B9=98=EC=9D=98=20?= =?UTF-8?q?=EC=B9=B4=EB=93=9C=EB=93=A4=EC=9D=84=20=EC=A1=B0=ED=9A=8C?= =?UTF-8?q?=ED=95=A0=20=EC=88=98=20=EC=9E=88=EB=8B=A4.=20(#12)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * ๐Ÿงช getters test ์ถ”๊ฐ€ - id๋กœ ํ•„ํ„ฐ๋ง * โœจ Vuex getters ์ถ”๊ฐ€ - id์— ํ•ด๋‹น๋˜๋Š” Learnset ๋ฐ˜ํ™˜ * โœ… Vuex getter ์ˆ˜์ • ๋ฐ ์ถ”๊ฐ€ - ๊ธฐ์ค€๋‚ ์งœ ์ด์ „์— ํ•™์Šตํ•ด์•ผ ํ•˜๋Š” ๋ฐ์ดํ„ฐ ์กฐํšŒ * โœจ /learn route ์ถ”๊ฐ€ - ํ•™์Šต ์นด๋“œ ๋ฐ์ดํ„ฐ๋ฅผ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒฝ๋กœ * ๐Ÿงช LearnsetCard Component test ์ถ”๊ฐ€ * ๐Ÿ› ์ค‘๊ฐ„ ์งˆ๋ฌธ์— ์‘๋‹ต์ด ์—†๋Š” ๊ฒฝ์šฐ ์ฒ˜๋ฆฌ ์ถ”๊ฐ€ - ํ…Œ์ŠคํŠธ ์ˆ˜์ • - ๊ธฐ์กด ์ฝ”๋“œ๋Š” ๋งˆ์ง€๋ง‰ ํ•ญ๋ชฉ์„ ์ฒ˜๋ฆฌํ•˜์ง€ ์•Š์•˜์Œ * โ™ป๏ธ vuex getters ์ˆ˜์ • - id ํŒŒ๋ผ๋ฏธํ„ฐ์ „๋‹ฌ * โœจ /learnset route์—์„œ /learn ๋กœ ์ด๋™ํ•˜๋Š” ๋ฒ„ํŠผ์ถ”๊ฐ€ * ๐Ÿงช LearnsetCard test ์ˆ˜์ • - showBack, submitted data ์ „๋‹ฌ * โœจ Vuex getters ์ถ”๊ฐ€ * ๐Ÿ“ฆ highlight.js, swiper ์„ค์น˜ * ๐Ÿ’„ highlight, swiper ๊ด€๋ จ style ์ถ”๊ฐ€ * โœจ LearnsetCard ๋ Œ๋”๋ง * ๐Ÿ’„ markdown rendering css ์ถ”๊ฐ€ * โ™ป๏ธ markdown-it plugin ์ƒ์„ฑ ๋ฐ ์ ์šฉ - provide, inject๋กœ ๋ถˆ๋Ÿฌ์™€์„œ ์‚ฌ์šฉํ•˜๊ธฐ - ํ…Œ์ŠคํŠธ ์ฝ”๋“œ์—๋„ plugin ์ ์šฉ * โ™ป๏ธ BaseButton Component๋ฅผ ๊ณตํ†ต์œผ๋กœ ์‚ฌ์šฉํ•˜๋„๋ก ์ˆ˜์ • * โ™ป๏ธ ์ ์ˆ˜ ๋ฐ์ดํ„ฐ ์ƒ์ˆ˜๋กœ ๋ถ„๋ฆฌ * โœจ Vuex getters ์ˆ˜์ • - ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ id, baseDate ์ „๋‹ฌ * ๐Ÿงช LearnsetCard Component router ์„ค์ • * ๐Ÿ“ฆ supermemo ์„ค์น˜ * โœจ Card ์ ์ˆ˜ ๋งค๊ธฐ๊ธฐ ์ถ”๊ฐ€ - supermemo๋กœ dueDate ์—…๋ฐ์ดํŠธ - dueDate๊ฐ€ ์˜ค๋Š˜ ์ด์ „์ธ ํ•ญ๋ชฉ๋งŒ ํ™œ์„ฑํ™”ํ•˜๋Š” switch ์ถ”๊ฐ€ * ๐Ÿ”ฅ ํ•„์š”์—†๋Š” ์ฝ”๋“œ ์‚ญ์ œ * โœ… ๋กœ์ง ๋ณ€๊ฒฝ์œผ๋กœ ์ธํ•œ ํ…Œ์ŠคํŠธ ์ˆ˜์ • --- package-lock.json | 981 +++++++++++++----- package.json | 5 + src/assets/style.scss | 13 + src/components/AddLearnsetModal.vue | 47 +- src/components/BaseButton.vue | 3 +- src/components/LearnsetCard.vue | 130 +++ src/components/__tests__/LearnsetCard.spec.ts | 136 +++ src/constants/index.ts | 12 + src/main.ts | 4 + src/plugins/markdownit.ts | 71 ++ src/router/__tests__/router.spec.ts | 6 + src/router/index.ts | 6 + src/store/__tests__/getters.spec.ts | 78 ++ src/store/getters.ts | 36 + src/store/index.ts | 2 + src/store/types.ts | 11 +- src/utils/learnset.ts | 11 +- src/utils/supermemo.ts | 27 + src/views/DashboardView.vue | 6 +- src/views/LearnView.vue | 104 ++ src/views/LearnsetView.vue | 9 +- tests/unit/learnset.spec.ts | 2 +- 22 files changed, 1422 insertions(+), 278 deletions(-) create mode 100644 src/assets/style.scss create mode 100644 src/components/LearnsetCard.vue create mode 100644 src/components/__tests__/LearnsetCard.spec.ts create mode 100644 src/constants/index.ts create mode 100644 src/plugins/markdownit.ts create mode 100644 src/store/__tests__/getters.spec.ts create mode 100644 src/store/getters.ts create mode 100644 src/utils/supermemo.ts create mode 100644 src/views/LearnView.vue diff --git a/package-lock.json b/package-lock.json index 1b723bd..37862f0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,7 +10,11 @@ "dependencies": { "@vueuse/core": "^9.13.0", "file-dialog": "^0.0.8", + "github-markdown-css": "^5.2.0", + "highlight.js": "^11.7.0", "markdown-it": "^13.0.1", + "supermemo": "^2.0.17", + "swiper": "^9.0.5", "uuidv4": "^6.2.13", "vue": "^3.2.45", "vue-router": "^4.1.6", @@ -35,6 +39,7 @@ "jsdom": "^20.0.3", "npm-run-all": "^4.1.5", "prettier": "^2.7.1", + "sass": "^1.58.3", "typescript": "~4.7.4", "vite": "^4.0.0", "vitest": "^0.25.6", @@ -154,9 +159,9 @@ } }, "node_modules/@babel/parser": { - "version": "7.21.1", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.21.1.tgz", - "integrity": "sha512-JzhBFpkuhBNYUY7qs+wTzNmyCWUHEaAFpQQD2YfU1rPL38/L43Wvid0fFkiOCnHvsGncRZgEPyGnltABLcVDTg==", + "version": "7.21.2", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.21.2.tgz", + "integrity": "sha512-URpaIJQwEkEC2T9Kn+Ai6Xe/02iNaVCuT/PtoRz3GPVJVDpPd7mLo+VddTbhCRU9TXqW5mSrQfXZyi8kDKOVpQ==", "bin": { "parser": "bin/babel-parser.js" }, @@ -529,9 +534,9 @@ } }, "node_modules/@eslint/eslintrc": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.4.1.tgz", - "integrity": "sha512-XXrH9Uarn0stsyldqDYq8r++mROmWRI1xKMXa640Bb//SY1+ECYX6VzT6Lcx5frD0V30XieqJ0oX9I2Xj5aoMA==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.0.0.tgz", + "integrity": "sha512-fluIaaV+GyV24CCu/ggiHdV+j4RNh85yQnAYS/G2mZODZgGmmlrgCydjUcV3YvxCm9x8nMAfThsqTni4KiXT4A==", "dev": true, "dependencies": { "ajv": "^6.12.4", @@ -551,6 +556,15 @@ "url": "https://opencollective.com/eslint" } }, + "node_modules/@eslint/js": { + "version": "8.35.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.35.0.tgz", + "integrity": "sha512-JXdzbRiWclLVoD8sNUjR443VVlYqiYmDVT6rGUEIEHU5YJW0gaVZwV2xgM7D4arkvASqD0IlLUVjHiFuxaftRw==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, "node_modules/@humanwhocodes/config-array": { "version": "0.11.8", "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.8.tgz", @@ -625,6 +639,22 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, + "node_modules/@jest/types/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/@mdi/font": { "version": "7.1.96", "resolved": "https://registry.npmjs.org/@mdi/font/-/font-7.1.96.tgz", @@ -697,6 +727,22 @@ "node": ">=12" } }, + "node_modules/@testing-library/dom/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/@testing-library/jest-dom": { "version": "5.16.5", "resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-5.16.5.tgz", @@ -719,19 +765,6 @@ "yarn": ">=1" } }, - "node_modules/@testing-library/jest-dom/node_modules/chalk": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", - "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/@testing-library/vue": { "version": "6.6.1", "resolved": "https://registry.npmjs.org/@testing-library/vue/-/vue-6.6.1.tgz", @@ -886,9 +919,9 @@ "dev": true }, "node_modules/@types/node": { - "version": "18.14.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.14.0.tgz", - "integrity": "sha512-5EWrvLmglK+imbCJY0+INViFWUHg1AHel1sq4ZVSfdcNqGy9Edv3UB9IIzzg+xPaUcAgZYcfVs2fBcwDeZzU0A==", + "version": "18.14.2", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.14.2.tgz", + "integrity": "sha512-1uEQxww3DaghA0RxqHx0O0ppVlo43pJhepY51OxuQIKHpjbnYLA7vcdwioNPzIqmC2u3I/dmylcqjlh0e7AyUA==", "dev": true }, "node_modules/@types/semver": { @@ -944,14 +977,14 @@ "dev": true }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "5.53.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.53.0.tgz", - "integrity": "sha512-alFpFWNucPLdUOySmXCJpzr6HKC3bu7XooShWM+3w/EL6J2HIoB2PFxpLnq4JauWVk6DiVeNKzQlFEaE+X9sGw==", + "version": "5.54.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.54.0.tgz", + "integrity": "sha512-+hSN9BdSr629RF02d7mMtXhAJvDTyCbprNYJKrXETlul/Aml6YZwd90XioVbjejQeHbb3R8Dg0CkRgoJDxo8aw==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "5.53.0", - "@typescript-eslint/type-utils": "5.53.0", - "@typescript-eslint/utils": "5.53.0", + "@typescript-eslint/scope-manager": "5.54.0", + "@typescript-eslint/type-utils": "5.54.0", + "@typescript-eslint/utils": "5.54.0", "debug": "^4.3.4", "grapheme-splitter": "^1.0.4", "ignore": "^5.2.0", @@ -978,14 +1011,14 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "5.53.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.53.0.tgz", - "integrity": "sha512-MKBw9i0DLYlmdOb3Oq/526+al20AJZpANdT6Ct9ffxcV8nKCHz63t/S0IhlTFNsBIHJv+GY5SFJ0XfqVeydQrQ==", + "version": "5.54.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.54.0.tgz", + "integrity": "sha512-aAVL3Mu2qTi+h/r04WI/5PfNWvO6pdhpeMRWk9R7rEV4mwJNzoWf5CCU5vDKBsPIFQFjEq1xg7XBI2rjiMXQbQ==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "5.53.0", - "@typescript-eslint/types": "5.53.0", - "@typescript-eslint/typescript-estree": "5.53.0", + "@typescript-eslint/scope-manager": "5.54.0", + "@typescript-eslint/types": "5.54.0", + "@typescript-eslint/typescript-estree": "5.54.0", "debug": "^4.3.4" }, "engines": { @@ -1005,13 +1038,13 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "5.53.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.53.0.tgz", - "integrity": "sha512-Opy3dqNsp/9kBBeCPhkCNR7fmdSQqA+47r21hr9a14Bx0xnkElEQmhoHga+VoaoQ6uDHjDKmQPIYcUcKJifS7w==", + "version": "5.54.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.54.0.tgz", + "integrity": "sha512-VTPYNZ7vaWtYna9M4oD42zENOBrb+ZYyCNdFs949GcN8Miwn37b8b7eMj+EZaq7VK9fx0Jd+JhmkhjFhvnovhg==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.53.0", - "@typescript-eslint/visitor-keys": "5.53.0" + "@typescript-eslint/types": "5.54.0", + "@typescript-eslint/visitor-keys": "5.54.0" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -1022,13 +1055,13 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "5.53.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.53.0.tgz", - "integrity": "sha512-HO2hh0fmtqNLzTAme/KnND5uFNwbsdYhCZghK2SoxGp3Ifn2emv+hi0PBUjzzSh0dstUIFqOj3bp0AwQlK4OWw==", + "version": "5.54.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.54.0.tgz", + "integrity": "sha512-WI+WMJ8+oS+LyflqsD4nlXMsVdzTMYTxl16myXPaCXnSgc7LWwMsjxQFZCK/rVmTZ3FN71Ct78ehO9bRC7erYQ==", "dev": true, "dependencies": { - "@typescript-eslint/typescript-estree": "5.53.0", - "@typescript-eslint/utils": "5.53.0", + "@typescript-eslint/typescript-estree": "5.54.0", + "@typescript-eslint/utils": "5.54.0", "debug": "^4.3.4", "tsutils": "^3.21.0" }, @@ -1049,9 +1082,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "5.53.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.53.0.tgz", - "integrity": "sha512-5kcDL9ZUIP756K6+QOAfPkigJmCPHcLN7Zjdz76lQWWDdzfOhZDTj1irs6gPBKiXx5/6O3L0+AvupAut3z7D2A==", + "version": "5.54.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.54.0.tgz", + "integrity": "sha512-nExy+fDCBEgqblasfeE3aQ3NuafBUxZxgxXcYfzYRZFHdVvk5q60KhCSkG0noHgHRo/xQ/BOzURLZAafFpTkmQ==", "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -1062,13 +1095,13 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "5.53.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.53.0.tgz", - "integrity": "sha512-eKmipH7QyScpHSkhbptBBYh9v8FxtngLquq292YTEQ1pxVs39yFBlLC1xeIZcPPz1RWGqb7YgERJRGkjw8ZV7w==", + "version": "5.54.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.54.0.tgz", + "integrity": "sha512-X2rJG97Wj/VRo5YxJ8Qx26Zqf0RRKsVHd4sav8NElhbZzhpBI8jU54i6hfo9eheumj4oO4dcRN1B/zIVEqR/MQ==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.53.0", - "@typescript-eslint/visitor-keys": "5.53.0", + "@typescript-eslint/types": "5.54.0", + "@typescript-eslint/visitor-keys": "5.54.0", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -1089,16 +1122,16 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "5.53.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.53.0.tgz", - "integrity": "sha512-VUOOtPv27UNWLxFwQK/8+7kvxVC+hPHNsJjzlJyotlaHjLSIgOCKj9I0DBUjwOOA64qjBwx5afAPjksqOxMO0g==", + "version": "5.54.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.54.0.tgz", + "integrity": "sha512-cuwm8D/Z/7AuyAeJ+T0r4WZmlnlxQ8wt7C7fLpFlKMR+dY6QO79Cq1WpJhvZbMA4ZeZGHiRWnht7ZJ8qkdAunw==", "dev": true, "dependencies": { "@types/json-schema": "^7.0.9", "@types/semver": "^7.3.12", - "@typescript-eslint/scope-manager": "5.53.0", - "@typescript-eslint/types": "5.53.0", - "@typescript-eslint/typescript-estree": "5.53.0", + "@typescript-eslint/scope-manager": "5.54.0", + "@typescript-eslint/types": "5.54.0", + "@typescript-eslint/typescript-estree": "5.54.0", "eslint-scope": "^5.1.1", "eslint-utils": "^3.0.0", "semver": "^7.3.7" @@ -1115,12 +1148,12 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "5.53.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.53.0.tgz", - "integrity": "sha512-JqNLnX3leaHFZEN0gCh81sIvgrp/2GOACZNgO4+Tkf64u51kTpAyWFOY8XHx8XuXr3N2C9zgPPHtcpMg6z1g0w==", + "version": "5.54.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.54.0.tgz", + "integrity": "sha512-xu4wT7aRCakGINTLGeyGqDn+78BwFlggwBjnHa1ar/KaGagnmwLYmlrXIrgAaQ3AE1Vd6nLfKASm7LrFHNbKGA==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.53.0", + "@typescript-eslint/types": "5.54.0", "eslint-visitor-keys": "^3.3.0" }, "engines": { @@ -1145,40 +1178,40 @@ } }, "node_modules/@volar/language-core": { - "version": "1.2.0-alpha.19", - "resolved": "https://registry.npmjs.org/@volar/language-core/-/language-core-1.2.0-alpha.19.tgz", - "integrity": "sha512-l/QsncqY3aV4CwJtw3r88tmUGO9yoTwcTXqKUfMwU2RC7X97xe6yAaB2medK7T+Azx6Xpv2yh9g5V0immyMWcA==", + "version": "1.3.0-alpha.0", + "resolved": "https://registry.npmjs.org/@volar/language-core/-/language-core-1.3.0-alpha.0.tgz", + "integrity": "sha512-W3uMzecHPcbwddPu4SJpUcPakRBK/y/BP+U0U6NiPpUX1tONLC4yCawt+QBJqtgJ+sfD6ztf5PyvPL3hQRqfOA==", "dev": true, "dependencies": { - "@volar/source-map": "1.2.0-alpha.19" + "@volar/source-map": "1.3.0-alpha.0" } }, "node_modules/@volar/source-map": { - "version": "1.2.0-alpha.19", - "resolved": "https://registry.npmjs.org/@volar/source-map/-/source-map-1.2.0-alpha.19.tgz", - "integrity": "sha512-pkMPiP28r3zHvyoSh29q4/MY2T+UGtsEN5ASu6N0/JEI0Wl4KKk0+nKP2Fge1JtIx9ZLjpGQxPr1eHBFvHxLAg==", + "version": "1.3.0-alpha.0", + "resolved": "https://registry.npmjs.org/@volar/source-map/-/source-map-1.3.0-alpha.0.tgz", + "integrity": "sha512-jSdizxWFvDTvkPYZnO6ew3sBZUnS0abKCbuopkc0JrIlFbznWC/fPH3iPFIMS8/IIkRxq1Jh9VVG60SmtsdaMQ==", "dev": true, "dependencies": { "muggle-string": "^0.2.2" } }, "node_modules/@volar/typescript": { - "version": "1.2.0-alpha.19", - "resolved": "https://registry.npmjs.org/@volar/typescript/-/typescript-1.2.0-alpha.19.tgz", - "integrity": "sha512-KRObKfbQ5930m1nIWBsV3I8uJAaJpqkM76ArsG3cOURuJ1dQSkFm3820Ge/9Ps8Wgf/NDpLPiy21CWDXP1KjnA==", + "version": "1.3.0-alpha.0", + "resolved": "https://registry.npmjs.org/@volar/typescript/-/typescript-1.3.0-alpha.0.tgz", + "integrity": "sha512-5UItyW2cdH2mBLu4RrECRNJRgtvvzKrSCn2y3v/D61QwIDkGx4aeil6x8RFuUL5TFtV6QvVHXnsOHxNgd+sCow==", "dev": true, "dependencies": { - "@volar/language-core": "1.2.0-alpha.19" + "@volar/language-core": "1.3.0-alpha.0" } }, "node_modules/@volar/vue-language-core": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/@volar/vue-language-core/-/vue-language-core-1.1.7.tgz", - "integrity": "sha512-oEgMfbbU5kk6X+xs0U37KGdvHwq5xgQL7IhXLb0RUQVagVVnAzlkZs9m+Fv+XOioGwH75MeH2NQzk4+KVSCuEQ==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@volar/vue-language-core/-/vue-language-core-1.2.0.tgz", + "integrity": "sha512-w7yEiaITh2WzKe6u8ZdeLKCUz43wdmY/OqAmsB/PGDvvhTcVhCJ6f0W/RprZL1IhqH8wALoWiwEh/Wer7ZviMQ==", "dev": true, "dependencies": { - "@volar/language-core": "1.2.0-alpha.19", - "@volar/source-map": "1.2.0-alpha.19", + "@volar/language-core": "1.3.0-alpha.0", + "@volar/source-map": "1.3.0-alpha.0", "@vue/compiler-dom": "^3.2.47", "@vue/compiler-sfc": "^3.2.47", "@vue/reactivity": "^3.2.47", @@ -1213,13 +1246,13 @@ } }, "node_modules/@volar/vue-typescript": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/@volar/vue-typescript/-/vue-typescript-1.1.7.tgz", - "integrity": "sha512-JGHz+XUUS1MAgnBaDFsk2dBmMumMDYXJ40nH4EFzXUHyKOsinmuFsHaQJScZDOoM0NPeWK9jWaNOEozjygXXeQ==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@volar/vue-typescript/-/vue-typescript-1.2.0.tgz", + "integrity": "sha512-zjmRi9y3J1EkG+pfuHp8IbHmibihrKK485cfzsHjiuvJMGrpkWvlO5WVEk8oslMxxeGC5XwBFE9AOlvh378EPA==", "dev": true, "dependencies": { - "@volar/typescript": "1.2.0-alpha.19", - "@volar/vue-language-core": "1.1.7" + "@volar/typescript": "1.3.0-alpha.0", + "@volar/vue-language-core": "1.2.0" } }, "node_modules/@vue/compiler-core": { @@ -1586,6 +1619,19 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dev": true, + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, "node_modules/argparse": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", @@ -1642,6 +1688,15 @@ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "dev": true }, + "node_modules/binary-extensions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/boolbase": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", @@ -1711,19 +1766,16 @@ } }, "node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", "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": ">=8" } }, "node_modules/check-error": { @@ -1735,6 +1787,45 @@ "node": "*" } }, + "node_modules/chokidar": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", + "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/chokidar/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/ci-info": { "version": "3.8.0", "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.8.0.tgz", @@ -2053,10 +2144,9 @@ } }, "node_modules/entities": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-4.4.0.tgz", - "integrity": "sha512-oYp7156SP8LkeGD0GF85ad1X9Ai79WtRsZ2gxJqtBuzH+98YUV6jkHEKlZkMbcrjJjIVJNIDP/3WL9wQkoPbWA==", - "dev": true, + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-3.0.1.tgz", + "integrity": "sha512-WiyBqoomrwMdFG1e0kqvASYfnlb0lp8M5o5Fw2OFq1hNZxxcNk8Ik0Xm7LxzBhuidnZB/UtBqVCgUz3kBOP51Q==", "engines": { "node": ">=0.12" }, @@ -2303,12 +2393,13 @@ } }, "node_modules/eslint": { - "version": "8.34.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.34.0.tgz", - "integrity": "sha512-1Z8iFsucw+7kSqXNZVslXS8Ioa4u2KM7GPwuKtkTFAqZ/cHMcEaR+1+Br0wLlot49cNxIiZk5wp8EAbPcYZxTg==", + "version": "8.35.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.35.0.tgz", + "integrity": "sha512-BxAf1fVL7w+JLRQhWl2pzGeSiGqbWumV4WNvc9Rhp6tiCtm4oHnyPBSEtMGZwrQgudFQ+otqzWoPB7x+hxoWsw==", "dev": true, "dependencies": { - "@eslint/eslintrc": "^1.4.1", + "@eslint/eslintrc": "^2.0.0", + "@eslint/js": "8.35.0", "@humanwhocodes/config-array": "^0.11.8", "@humanwhocodes/module-importer": "^1.0.1", "@nodelib/fs.walk": "^1.2.8", @@ -2322,7 +2413,7 @@ "eslint-utils": "^3.0.0", "eslint-visitor-keys": "^3.3.0", "espree": "^9.4.0", - "esquery": "^1.4.0", + "esquery": "^1.4.2", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", "file-entry-cache": "^6.0.1", @@ -2461,6 +2552,22 @@ "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, + "node_modules/eslint/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/eslint/node_modules/eslint-scope": { "version": "7.1.1", "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.1.tgz", @@ -2834,6 +2941,14 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/github-markdown-css": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/github-markdown-css/-/github-markdown-css-5.2.0.tgz", + "integrity": "sha512-hq5RaCInSUZ48bImOZpkppW2/MT44StRgsbsZ8YA4vJFwLKB/Vo3k7R2t+pUGqO+ThG0QDMi96TewV/B3vyItg==", + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/glob": { "version": "8.1.0", "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", @@ -3050,6 +3165,14 @@ "he": "bin/he" } }, + "node_modules/highlight.js": { + "version": "11.7.0", + "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-11.7.0.tgz", + "integrity": "sha512-1rRqesRFhMO/PRF+G86evnyJkCgaZFOI+Z6kdj15TA18funfoqJXvgPCLSf0SWq3SRfg1j3HlDs8o4s3EGq1oQ==", + "engines": { + "node": ">=12.0.0" + } + }, "node_modules/hosted-git-info": { "version": "2.8.9", "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", @@ -3116,6 +3239,12 @@ "node": ">= 4" } }, + "node_modules/immutable": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.2.4.tgz", + "integrity": "sha512-WDxL3Hheb1JkRN3sQkyujNlL/xRjAo3rJtaU5xeufUauG66JdMr32bLj4gF+vWl84DIA3Zxw7tiAjneYzRRw+w==", + "dev": true + }, "node_modules/import-fresh": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", @@ -3234,6 +3363,18 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/is-boolean-object": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", @@ -3517,16 +3658,20 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/jest-diff/node_modules/ansi-styles": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "node_modules/jest-diff/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/ansi-styles?sponsor=1" + "url": "https://github.com/chalk/chalk?sponsor=1" } }, "node_modules/jest-diff/node_modules/pretty-format": { @@ -3543,6 +3688,18 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, + "node_modules/jest-diff/node_modules/pretty-format/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, "node_modules/jest-diff/node_modules/react-is": { "version": "18.2.0", "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", @@ -3573,16 +3730,20 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/jest-matcher-utils/node_modules/ansi-styles": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "node_modules/jest-matcher-utils/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/ansi-styles?sponsor=1" + "url": "https://github.com/chalk/chalk?sponsor=1" } }, "node_modules/jest-matcher-utils/node_modules/pretty-format": { @@ -3599,6 +3760,18 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, + "node_modules/jest-matcher-utils/node_modules/pretty-format/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, "node_modules/jest-matcher-utils/node_modules/react-is": { "version": "18.2.0", "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", @@ -3625,16 +3798,20 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/jest-message-util/node_modules/ansi-styles": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "node_modules/jest-message-util/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/ansi-styles?sponsor=1" + "url": "https://github.com/chalk/chalk?sponsor=1" } }, "node_modules/jest-message-util/node_modules/pretty-format": { @@ -3651,6 +3828,18 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, + "node_modules/jest-message-util/node_modules/pretty-format/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, "node_modules/jest-message-util/node_modules/react-is": { "version": "18.2.0", "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", @@ -3674,6 +3863,22 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, + "node_modules/jest-util/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/js-beautify": { "version": "1.14.6", "resolved": "https://registry.npmjs.org/js-beautify/-/js-beautify-1.14.6.tgz", @@ -3911,17 +4116,6 @@ "markdown-it": "bin/markdown-it.js" } }, - "node_modules/markdown-it/node_modules/entities": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/entities/-/entities-3.0.1.tgz", - "integrity": "sha512-WiyBqoomrwMdFG1e0kqvASYfnlb0lp8M5o5Fw2OFq1hNZxxcNk8Ik0Xm7LxzBhuidnZB/UtBqVCgUz3kBOP51Q==", - "engines": { - "node": ">=0.12" - }, - "funding": { - "url": "https://github.com/fb55/entities?sponsor=1" - } - }, "node_modules/mdurl": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz", @@ -4077,6 +4271,15 @@ "semver": "bin/semver" } }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/npm-run-all": { "version": "4.1.5", "resolved": "https://registry.npmjs.org/npm-run-all/-/npm-run-all-4.1.5.tgz", @@ -4403,6 +4606,18 @@ "url": "https://github.com/inikulin/parse5?sponsor=1" } }, + "node_modules/parse5/node_modules/entities": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.4.0.tgz", + "integrity": "sha512-oYp7156SP8LkeGD0GF85ad1X9Ai79WtRsZ2gxJqtBuzH+98YUV6jkHEKlZkMbcrjJjIVJNIDP/3WL9wQkoPbWA==", + "dev": true, + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, "node_modules/path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", @@ -4675,6 +4890,18 @@ "node": ">=4" } }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, "node_modules/redent": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz", @@ -4801,9 +5028,9 @@ } }, "node_modules/rollup": { - "version": "3.17.2", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.17.2.tgz", - "integrity": "sha512-qMNZdlQPCkWodrAZ3qnJtvCAl4vpQ8q77uEujVCCbC/6CLB7Lcmvjq7HyiOSnf4fxTT9XgsE36oLHJBH49xjqA==", + "version": "3.17.3", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.17.3.tgz", + "integrity": "sha512-p5LaCXiiOL/wrOkj8djsIDFmyU9ysUxcyW+EKRLHb6TKldJzXpImjcRSR+vgo09DBdofGcOoLOsRyxxG2n5/qQ==", "dev": true, "bin": { "rollup": "dist/bin/rollup" @@ -4859,6 +5086,23 @@ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", "dev": true }, + "node_modules/sass": { + "version": "1.58.3", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.58.3.tgz", + "integrity": "sha512-Q7RaEtYf6BflYrQ+buPudKR26/lH+10EmO9bBqbmPh/KeLqv8bjpTNqxe71ocONqXq+jYiCbpPUmQMS+JJPk4A==", + "dev": true, + "dependencies": { + "chokidar": ">=3.0.0 <4.0.0", + "immutable": "^4.0.0", + "source-map-js": ">=0.6.2 <2.0.0" + }, + "bin": { + "sass": "sass.js" + }, + "engines": { + "node": ">=12.0.0" + } + }, "node_modules/saxes": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/saxes/-/saxes-6.0.0.tgz", @@ -5017,6 +5261,11 @@ "integrity": "sha512-rr+VVSXtRhO4OHbXUiAF7xW3Bo9DuuF6C5jH+q/x15j2jniycgKbxU09Hr0WqlSLUs4i4ltHGXqTe7VHclYWyA==", "dev": true }, + "node_modules/ssr-window": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/ssr-window/-/ssr-window-4.0.2.tgz", + "integrity": "sha512-ISv/Ch+ig7SOtw7G2+qkwfVASzazUnvlDTwypdLoPoySv+6MqlOV10VwPSE6EWkGjhW50lUmghPmpYZXMu/+AQ==" + }, "node_modules/stack-utils": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz", @@ -5152,6 +5401,14 @@ "url": "https://github.com/sponsors/antfu" } }, + "node_modules/supermemo": { + "version": "2.0.17", + "resolved": "https://registry.npmjs.org/supermemo/-/supermemo-2.0.17.tgz", + "integrity": "sha512-c/BMAkG+IDYtAP1AR97DVU4x4gs8vfvLA4ejND7lHKdzjaAWwxixtcZjnQNfcyAKfZn2ovIYKJAGpTG45dr8ug==", + "engines": { + "node": ">=10" + } + }, "node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -5176,6 +5433,27 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/swiper": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/swiper/-/swiper-9.0.5.tgz", + "integrity": "sha512-UiLQ5fvn8L3ZZpaPa+9oiwKwhVGQt5TVc0UuXxFKHyTQe8g2E3vbPMiMfIGb6NhNGj5ntsSDyyNgg4qVmWlJkQ==", + "funding": [ + { + "type": "patreon", + "url": "https://www.patreon.com/swiperjs" + }, + { + "type": "open_collective", + "url": "http://opencollective.com/swiper" + } + ], + "dependencies": { + "ssr-window": "^4.0.2" + }, + "engines": { + "node": ">= 4.7.0" + } + }, "node_modules/symbol-tree": { "version": "3.2.4", "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", @@ -5600,13 +5878,13 @@ } }, "node_modules/vue-tsc": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/vue-tsc/-/vue-tsc-1.1.7.tgz", - "integrity": "sha512-TYuWJMQmwaV9kC1oWvw6fSHlymJpsD1ad4GaYqvUloph7E2QiVEXZyZe+lf0pHHayyltZp0Z+ZqcLuXoru8lzA==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/vue-tsc/-/vue-tsc-1.2.0.tgz", + "integrity": "sha512-rIlzqdrhyPYyLG9zxsVRa+JEseeS9s8F2BbVVVWRRsTZvJO2BbhLEb2HW3MY+DFma0378tnIqs+vfTzbcQtRFw==", "dev": true, "dependencies": { - "@volar/vue-language-core": "1.1.7", - "@volar/vue-typescript": "1.1.7" + "@volar/vue-language-core": "1.2.0", + "@volar/vue-typescript": "1.2.0" }, "bin": { "vue-tsc": "bin/vue-tsc.js" @@ -5938,9 +6216,9 @@ } }, "@babel/parser": { - "version": "7.21.1", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.21.1.tgz", - "integrity": "sha512-JzhBFpkuhBNYUY7qs+wTzNmyCWUHEaAFpQQD2YfU1rPL38/L43Wvid0fFkiOCnHvsGncRZgEPyGnltABLcVDTg==" + "version": "7.21.2", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.21.2.tgz", + "integrity": "sha512-URpaIJQwEkEC2T9Kn+Ai6Xe/02iNaVCuT/PtoRz3GPVJVDpPd7mLo+VddTbhCRU9TXqW5mSrQfXZyi8kDKOVpQ==" }, "@babel/runtime": { "version": "7.21.0", @@ -6106,9 +6384,9 @@ "optional": true }, "@eslint/eslintrc": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.4.1.tgz", - "integrity": "sha512-XXrH9Uarn0stsyldqDYq8r++mROmWRI1xKMXa640Bb//SY1+ECYX6VzT6Lcx5frD0V30XieqJ0oX9I2Xj5aoMA==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.0.0.tgz", + "integrity": "sha512-fluIaaV+GyV24CCu/ggiHdV+j4RNh85yQnAYS/G2mZODZgGmmlrgCydjUcV3YvxCm9x8nMAfThsqTni4KiXT4A==", "dev": true, "requires": { "ajv": "^6.12.4", @@ -6122,6 +6400,12 @@ "strip-json-comments": "^3.1.1" } }, + "@eslint/js": { + "version": "8.35.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.35.0.tgz", + "integrity": "sha512-JXdzbRiWclLVoD8sNUjR443VVlYqiYmDVT6rGUEIEHU5YJW0gaVZwV2xgM7D4arkvASqD0IlLUVjHiFuxaftRw==", + "dev": true + }, "@humanwhocodes/config-array": { "version": "0.11.8", "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.8.tgz", @@ -6175,6 +6459,18 @@ "@types/node": "*", "@types/yargs": "^17.0.8", "chalk": "^4.0.0" + }, + "dependencies": { + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + } } }, "@mdi/font": { @@ -6235,6 +6531,18 @@ "dom-accessibility-api": "^0.5.9", "lz-string": "^1.4.4", "pretty-format": "^27.0.2" + }, + "dependencies": { + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + } } }, "@testing-library/jest-dom": { @@ -6252,18 +6560,6 @@ "dom-accessibility-api": "^0.5.6", "lodash": "^4.17.15", "redent": "^3.0.0" - }, - "dependencies": { - "chalk": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", - "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - } } }, "@testing-library/vue": { @@ -6403,9 +6699,9 @@ "dev": true }, "@types/node": { - "version": "18.14.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.14.0.tgz", - "integrity": "sha512-5EWrvLmglK+imbCJY0+INViFWUHg1AHel1sq4ZVSfdcNqGy9Edv3UB9IIzzg+xPaUcAgZYcfVs2fBcwDeZzU0A==", + "version": "18.14.2", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.14.2.tgz", + "integrity": "sha512-1uEQxww3DaghA0RxqHx0O0ppVlo43pJhepY51OxuQIKHpjbnYLA7vcdwioNPzIqmC2u3I/dmylcqjlh0e7AyUA==", "dev": true }, "@types/semver": { @@ -6461,14 +6757,14 @@ "dev": true }, "@typescript-eslint/eslint-plugin": { - "version": "5.53.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.53.0.tgz", - "integrity": "sha512-alFpFWNucPLdUOySmXCJpzr6HKC3bu7XooShWM+3w/EL6J2HIoB2PFxpLnq4JauWVk6DiVeNKzQlFEaE+X9sGw==", + "version": "5.54.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.54.0.tgz", + "integrity": "sha512-+hSN9BdSr629RF02d7mMtXhAJvDTyCbprNYJKrXETlul/Aml6YZwd90XioVbjejQeHbb3R8Dg0CkRgoJDxo8aw==", "dev": true, "requires": { - "@typescript-eslint/scope-manager": "5.53.0", - "@typescript-eslint/type-utils": "5.53.0", - "@typescript-eslint/utils": "5.53.0", + "@typescript-eslint/scope-manager": "5.54.0", + "@typescript-eslint/type-utils": "5.54.0", + "@typescript-eslint/utils": "5.54.0", "debug": "^4.3.4", "grapheme-splitter": "^1.0.4", "ignore": "^5.2.0", @@ -6479,53 +6775,53 @@ } }, "@typescript-eslint/parser": { - "version": "5.53.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.53.0.tgz", - "integrity": "sha512-MKBw9i0DLYlmdOb3Oq/526+al20AJZpANdT6Ct9ffxcV8nKCHz63t/S0IhlTFNsBIHJv+GY5SFJ0XfqVeydQrQ==", + "version": "5.54.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.54.0.tgz", + "integrity": "sha512-aAVL3Mu2qTi+h/r04WI/5PfNWvO6pdhpeMRWk9R7rEV4mwJNzoWf5CCU5vDKBsPIFQFjEq1xg7XBI2rjiMXQbQ==", "dev": true, "requires": { - "@typescript-eslint/scope-manager": "5.53.0", - "@typescript-eslint/types": "5.53.0", - "@typescript-eslint/typescript-estree": "5.53.0", + "@typescript-eslint/scope-manager": "5.54.0", + "@typescript-eslint/types": "5.54.0", + "@typescript-eslint/typescript-estree": "5.54.0", "debug": "^4.3.4" } }, "@typescript-eslint/scope-manager": { - "version": "5.53.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.53.0.tgz", - "integrity": "sha512-Opy3dqNsp/9kBBeCPhkCNR7fmdSQqA+47r21hr9a14Bx0xnkElEQmhoHga+VoaoQ6uDHjDKmQPIYcUcKJifS7w==", + "version": "5.54.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.54.0.tgz", + "integrity": "sha512-VTPYNZ7vaWtYna9M4oD42zENOBrb+ZYyCNdFs949GcN8Miwn37b8b7eMj+EZaq7VK9fx0Jd+JhmkhjFhvnovhg==", "dev": true, "requires": { - "@typescript-eslint/types": "5.53.0", - "@typescript-eslint/visitor-keys": "5.53.0" + "@typescript-eslint/types": "5.54.0", + "@typescript-eslint/visitor-keys": "5.54.0" } }, "@typescript-eslint/type-utils": { - "version": "5.53.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.53.0.tgz", - "integrity": "sha512-HO2hh0fmtqNLzTAme/KnND5uFNwbsdYhCZghK2SoxGp3Ifn2emv+hi0PBUjzzSh0dstUIFqOj3bp0AwQlK4OWw==", + "version": "5.54.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.54.0.tgz", + "integrity": "sha512-WI+WMJ8+oS+LyflqsD4nlXMsVdzTMYTxl16myXPaCXnSgc7LWwMsjxQFZCK/rVmTZ3FN71Ct78ehO9bRC7erYQ==", "dev": true, "requires": { - "@typescript-eslint/typescript-estree": "5.53.0", - "@typescript-eslint/utils": "5.53.0", + "@typescript-eslint/typescript-estree": "5.54.0", + "@typescript-eslint/utils": "5.54.0", "debug": "^4.3.4", "tsutils": "^3.21.0" } }, "@typescript-eslint/types": { - "version": "5.53.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.53.0.tgz", - "integrity": "sha512-5kcDL9ZUIP756K6+QOAfPkigJmCPHcLN7Zjdz76lQWWDdzfOhZDTj1irs6gPBKiXx5/6O3L0+AvupAut3z7D2A==", + "version": "5.54.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.54.0.tgz", + "integrity": "sha512-nExy+fDCBEgqblasfeE3aQ3NuafBUxZxgxXcYfzYRZFHdVvk5q60KhCSkG0noHgHRo/xQ/BOzURLZAafFpTkmQ==", "dev": true }, "@typescript-eslint/typescript-estree": { - "version": "5.53.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.53.0.tgz", - "integrity": "sha512-eKmipH7QyScpHSkhbptBBYh9v8FxtngLquq292YTEQ1pxVs39yFBlLC1xeIZcPPz1RWGqb7YgERJRGkjw8ZV7w==", + "version": "5.54.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.54.0.tgz", + "integrity": "sha512-X2rJG97Wj/VRo5YxJ8Qx26Zqf0RRKsVHd4sav8NElhbZzhpBI8jU54i6hfo9eheumj4oO4dcRN1B/zIVEqR/MQ==", "dev": true, "requires": { - "@typescript-eslint/types": "5.53.0", - "@typescript-eslint/visitor-keys": "5.53.0", + "@typescript-eslint/types": "5.54.0", + "@typescript-eslint/visitor-keys": "5.54.0", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -6534,28 +6830,28 @@ } }, "@typescript-eslint/utils": { - "version": "5.53.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.53.0.tgz", - "integrity": "sha512-VUOOtPv27UNWLxFwQK/8+7kvxVC+hPHNsJjzlJyotlaHjLSIgOCKj9I0DBUjwOOA64qjBwx5afAPjksqOxMO0g==", + "version": "5.54.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.54.0.tgz", + "integrity": "sha512-cuwm8D/Z/7AuyAeJ+T0r4WZmlnlxQ8wt7C7fLpFlKMR+dY6QO79Cq1WpJhvZbMA4ZeZGHiRWnht7ZJ8qkdAunw==", "dev": true, "requires": { "@types/json-schema": "^7.0.9", "@types/semver": "^7.3.12", - "@typescript-eslint/scope-manager": "5.53.0", - "@typescript-eslint/types": "5.53.0", - "@typescript-eslint/typescript-estree": "5.53.0", + "@typescript-eslint/scope-manager": "5.54.0", + "@typescript-eslint/types": "5.54.0", + "@typescript-eslint/typescript-estree": "5.54.0", "eslint-scope": "^5.1.1", "eslint-utils": "^3.0.0", "semver": "^7.3.7" } }, "@typescript-eslint/visitor-keys": { - "version": "5.53.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.53.0.tgz", - "integrity": "sha512-JqNLnX3leaHFZEN0gCh81sIvgrp/2GOACZNgO4+Tkf64u51kTpAyWFOY8XHx8XuXr3N2C9zgPPHtcpMg6z1g0w==", + "version": "5.54.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.54.0.tgz", + "integrity": "sha512-xu4wT7aRCakGINTLGeyGqDn+78BwFlggwBjnHa1ar/KaGagnmwLYmlrXIrgAaQ3AE1Vd6nLfKASm7LrFHNbKGA==", "dev": true, "requires": { - "@typescript-eslint/types": "5.53.0", + "@typescript-eslint/types": "5.54.0", "eslint-visitor-keys": "^3.3.0" } }, @@ -6567,40 +6863,40 @@ "requires": {} }, "@volar/language-core": { - "version": "1.2.0-alpha.19", - "resolved": "https://registry.npmjs.org/@volar/language-core/-/language-core-1.2.0-alpha.19.tgz", - "integrity": "sha512-l/QsncqY3aV4CwJtw3r88tmUGO9yoTwcTXqKUfMwU2RC7X97xe6yAaB2medK7T+Azx6Xpv2yh9g5V0immyMWcA==", + "version": "1.3.0-alpha.0", + "resolved": "https://registry.npmjs.org/@volar/language-core/-/language-core-1.3.0-alpha.0.tgz", + "integrity": "sha512-W3uMzecHPcbwddPu4SJpUcPakRBK/y/BP+U0U6NiPpUX1tONLC4yCawt+QBJqtgJ+sfD6ztf5PyvPL3hQRqfOA==", "dev": true, "requires": { - "@volar/source-map": "1.2.0-alpha.19" + "@volar/source-map": "1.3.0-alpha.0" } }, "@volar/source-map": { - "version": "1.2.0-alpha.19", - "resolved": "https://registry.npmjs.org/@volar/source-map/-/source-map-1.2.0-alpha.19.tgz", - "integrity": "sha512-pkMPiP28r3zHvyoSh29q4/MY2T+UGtsEN5ASu6N0/JEI0Wl4KKk0+nKP2Fge1JtIx9ZLjpGQxPr1eHBFvHxLAg==", + "version": "1.3.0-alpha.0", + "resolved": "https://registry.npmjs.org/@volar/source-map/-/source-map-1.3.0-alpha.0.tgz", + "integrity": "sha512-jSdizxWFvDTvkPYZnO6ew3sBZUnS0abKCbuopkc0JrIlFbznWC/fPH3iPFIMS8/IIkRxq1Jh9VVG60SmtsdaMQ==", "dev": true, "requires": { "muggle-string": "^0.2.2" } }, "@volar/typescript": { - "version": "1.2.0-alpha.19", - "resolved": "https://registry.npmjs.org/@volar/typescript/-/typescript-1.2.0-alpha.19.tgz", - "integrity": "sha512-KRObKfbQ5930m1nIWBsV3I8uJAaJpqkM76ArsG3cOURuJ1dQSkFm3820Ge/9Ps8Wgf/NDpLPiy21CWDXP1KjnA==", + "version": "1.3.0-alpha.0", + "resolved": "https://registry.npmjs.org/@volar/typescript/-/typescript-1.3.0-alpha.0.tgz", + "integrity": "sha512-5UItyW2cdH2mBLu4RrECRNJRgtvvzKrSCn2y3v/D61QwIDkGx4aeil6x8RFuUL5TFtV6QvVHXnsOHxNgd+sCow==", "dev": true, "requires": { - "@volar/language-core": "1.2.0-alpha.19" + "@volar/language-core": "1.3.0-alpha.0" } }, "@volar/vue-language-core": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/@volar/vue-language-core/-/vue-language-core-1.1.7.tgz", - "integrity": "sha512-oEgMfbbU5kk6X+xs0U37KGdvHwq5xgQL7IhXLb0RUQVagVVnAzlkZs9m+Fv+XOioGwH75MeH2NQzk4+KVSCuEQ==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@volar/vue-language-core/-/vue-language-core-1.2.0.tgz", + "integrity": "sha512-w7yEiaITh2WzKe6u8ZdeLKCUz43wdmY/OqAmsB/PGDvvhTcVhCJ6f0W/RprZL1IhqH8wALoWiwEh/Wer7ZviMQ==", "dev": true, "requires": { - "@volar/language-core": "1.2.0-alpha.19", - "@volar/source-map": "1.2.0-alpha.19", + "@volar/language-core": "1.3.0-alpha.0", + "@volar/source-map": "1.3.0-alpha.0", "@vue/compiler-dom": "^3.2.47", "@vue/compiler-sfc": "^3.2.47", "@vue/reactivity": "^3.2.47", @@ -6631,13 +6927,13 @@ } }, "@volar/vue-typescript": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/@volar/vue-typescript/-/vue-typescript-1.1.7.tgz", - "integrity": "sha512-JGHz+XUUS1MAgnBaDFsk2dBmMumMDYXJ40nH4EFzXUHyKOsinmuFsHaQJScZDOoM0NPeWK9jWaNOEozjygXXeQ==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@volar/vue-typescript/-/vue-typescript-1.2.0.tgz", + "integrity": "sha512-zjmRi9y3J1EkG+pfuHp8IbHmibihrKK485cfzsHjiuvJMGrpkWvlO5WVEk8oslMxxeGC5XwBFE9AOlvh378EPA==", "dev": true, "requires": { - "@volar/typescript": "1.2.0-alpha.19", - "@volar/vue-language-core": "1.1.7" + "@volar/typescript": "1.3.0-alpha.0", + "@volar/vue-language-core": "1.2.0" } }, "@vue/compiler-core": { @@ -6900,6 +7196,16 @@ "color-convert": "^2.0.1" } }, + "anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dev": true, + "requires": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + } + }, "argparse": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", @@ -6944,6 +7250,12 @@ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "dev": true }, + "binary-extensions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "dev": true + }, "boolbase": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", @@ -7001,9 +7313,9 @@ } }, "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", "dev": true, "requires": { "ansi-styles": "^4.1.0", @@ -7016,6 +7328,33 @@ "integrity": "sha512-BrgHpW9NURQgzoNyjfq0Wu6VFO6D7IZEmJNdtgNqpzGG8RuNFHt2jQxWlAs4HMe119chBnv+34syEZtc6IhLtA==", "dev": true }, + "chokidar": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", + "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", + "dev": true, + "requires": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "fsevents": "~2.3.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "dependencies": { + "glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "requires": { + "is-glob": "^4.0.1" + } + } + } + }, "ci-info": { "version": "3.8.0", "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.8.0.tgz", @@ -7267,10 +7606,9 @@ } }, "entities": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-4.4.0.tgz", - "integrity": "sha512-oYp7156SP8LkeGD0GF85ad1X9Ai79WtRsZ2gxJqtBuzH+98YUV6jkHEKlZkMbcrjJjIVJNIDP/3WL9wQkoPbWA==", - "dev": true + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-3.0.1.tgz", + "integrity": "sha512-WiyBqoomrwMdFG1e0kqvASYfnlb0lp8M5o5Fw2OFq1hNZxxcNk8Ik0Xm7LxzBhuidnZB/UtBqVCgUz3kBOP51Q==" }, "error-ex": { "version": "1.3.2", @@ -7458,12 +7796,13 @@ } }, "eslint": { - "version": "8.34.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.34.0.tgz", - "integrity": "sha512-1Z8iFsucw+7kSqXNZVslXS8Ioa4u2KM7GPwuKtkTFAqZ/cHMcEaR+1+Br0wLlot49cNxIiZk5wp8EAbPcYZxTg==", + "version": "8.35.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.35.0.tgz", + "integrity": "sha512-BxAf1fVL7w+JLRQhWl2pzGeSiGqbWumV4WNvc9Rhp6tiCtm4oHnyPBSEtMGZwrQgudFQ+otqzWoPB7x+hxoWsw==", "dev": true, "requires": { - "@eslint/eslintrc": "^1.4.1", + "@eslint/eslintrc": "^2.0.0", + "@eslint/js": "8.35.0", "@humanwhocodes/config-array": "^0.11.8", "@humanwhocodes/module-importer": "^1.0.1", "@nodelib/fs.walk": "^1.2.8", @@ -7477,7 +7816,7 @@ "eslint-utils": "^3.0.0", "eslint-visitor-keys": "^3.3.0", "espree": "^9.4.0", - "esquery": "^1.4.0", + "esquery": "^1.4.2", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", "file-entry-cache": "^6.0.1", @@ -7504,6 +7843,16 @@ "text-table": "^0.2.0" }, "dependencies": { + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, "eslint-scope": { "version": "7.1.1", "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.1.tgz", @@ -7857,6 +8206,11 @@ "get-intrinsic": "^1.1.1" } }, + "github-markdown-css": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/github-markdown-css/-/github-markdown-css-5.2.0.tgz", + "integrity": "sha512-hq5RaCInSUZ48bImOZpkppW2/MT44StRgsbsZ8YA4vJFwLKB/Vo3k7R2t+pUGqO+ThG0QDMi96TewV/B3vyItg==" + }, "glob": { "version": "8.1.0", "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", @@ -8009,6 +8363,11 @@ "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", "dev": true }, + "highlight.js": { + "version": "11.7.0", + "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-11.7.0.tgz", + "integrity": "sha512-1rRqesRFhMO/PRF+G86evnyJkCgaZFOI+Z6kdj15TA18funfoqJXvgPCLSf0SWq3SRfg1j3HlDs8o4s3EGq1oQ==" + }, "hosted-git-info": { "version": "2.8.9", "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", @@ -8060,6 +8419,12 @@ "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==", "dev": true }, + "immutable": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.2.4.tgz", + "integrity": "sha512-WDxL3Hheb1JkRN3sQkyujNlL/xRjAo3rJtaU5xeufUauG66JdMr32bLj4gF+vWl84DIA3Zxw7tiAjneYzRRw+w==", + "dev": true + }, "import-fresh": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", @@ -8151,6 +8516,15 @@ "has-bigints": "^1.0.1" } }, + "is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "requires": { + "binary-extensions": "^2.0.0" + } + }, "is-boolean-object": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", @@ -8344,11 +8718,15 @@ "pretty-format": "^29.4.3" }, "dependencies": { - "ansi-styles": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "dev": true + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } }, "pretty-format": { "version": "29.4.3", @@ -8359,6 +8737,14 @@ "@jest/schemas": "^29.4.3", "ansi-styles": "^5.0.0", "react-is": "^18.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true + } } }, "react-is": { @@ -8387,11 +8773,15 @@ "pretty-format": "^29.4.3" }, "dependencies": { - "ansi-styles": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "dev": true + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } }, "pretty-format": { "version": "29.4.3", @@ -8402,6 +8792,14 @@ "@jest/schemas": "^29.4.3", "ansi-styles": "^5.0.0", "react-is": "^18.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true + } } }, "react-is": { @@ -8429,11 +8827,15 @@ "stack-utils": "^2.0.3" }, "dependencies": { - "ansi-styles": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "dev": true + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } }, "pretty-format": { "version": "29.4.3", @@ -8444,6 +8846,14 @@ "@jest/schemas": "^29.4.3", "ansi-styles": "^5.0.0", "react-is": "^18.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true + } } }, "react-is": { @@ -8466,6 +8876,18 @@ "ci-info": "^3.2.0", "graceful-fs": "^4.2.9", "picomatch": "^2.2.3" + }, + "dependencies": { + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + } } }, "js-beautify": { @@ -8653,13 +9075,6 @@ "linkify-it": "^4.0.1", "mdurl": "^1.0.1", "uc.micro": "^1.0.5" - }, - "dependencies": { - "entities": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/entities/-/entities-3.0.1.tgz", - "integrity": "sha512-WiyBqoomrwMdFG1e0kqvASYfnlb0lp8M5o5Fw2OFq1hNZxxcNk8Ik0Xm7LxzBhuidnZB/UtBqVCgUz3kBOP51Q==" - } } }, "mdurl": { @@ -8783,6 +9198,12 @@ } } }, + "normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true + }, "npm-run-all": { "version": "4.1.5", "resolved": "https://registry.npmjs.org/npm-run-all/-/npm-run-all-4.1.5.tgz", @@ -9023,6 +9444,14 @@ "dev": true, "requires": { "entities": "^4.4.0" + }, + "dependencies": { + "entities": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.4.0.tgz", + "integrity": "sha512-oYp7156SP8LkeGD0GF85ad1X9Ai79WtRsZ2gxJqtBuzH+98YUV6jkHEKlZkMbcrjJjIVJNIDP/3WL9wQkoPbWA==", + "dev": true + } } }, "path-exists": { @@ -9208,6 +9637,15 @@ } } }, + "readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "requires": { + "picomatch": "^2.2.1" + } + }, "redent": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz", @@ -9296,9 +9734,9 @@ } }, "rollup": { - "version": "3.17.2", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.17.2.tgz", - "integrity": "sha512-qMNZdlQPCkWodrAZ3qnJtvCAl4vpQ8q77uEujVCCbC/6CLB7Lcmvjq7HyiOSnf4fxTT9XgsE36oLHJBH49xjqA==", + "version": "3.17.3", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.17.3.tgz", + "integrity": "sha512-p5LaCXiiOL/wrOkj8djsIDFmyU9ysUxcyW+EKRLHb6TKldJzXpImjcRSR+vgo09DBdofGcOoLOsRyxxG2n5/qQ==", "dev": true, "requires": { "fsevents": "~2.3.2" @@ -9330,6 +9768,17 @@ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", "dev": true }, + "sass": { + "version": "1.58.3", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.58.3.tgz", + "integrity": "sha512-Q7RaEtYf6BflYrQ+buPudKR26/lH+10EmO9bBqbmPh/KeLqv8bjpTNqxe71ocONqXq+jYiCbpPUmQMS+JJPk4A==", + "dev": true, + "requires": { + "chokidar": ">=3.0.0 <4.0.0", + "immutable": "^4.0.0", + "source-map-js": ">=0.6.2 <2.0.0" + } + }, "saxes": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/saxes/-/saxes-6.0.0.tgz", @@ -9456,6 +9905,11 @@ "integrity": "sha512-rr+VVSXtRhO4OHbXUiAF7xW3Bo9DuuF6C5jH+q/x15j2jniycgKbxU09Hr0WqlSLUs4i4ltHGXqTe7VHclYWyA==", "dev": true }, + "ssr-window": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/ssr-window/-/ssr-window-4.0.2.tgz", + "integrity": "sha512-ISv/Ch+ig7SOtw7G2+qkwfVASzazUnvlDTwypdLoPoySv+6MqlOV10VwPSE6EWkGjhW50lUmghPmpYZXMu/+AQ==" + }, "stack-utils": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz", @@ -9554,6 +10008,11 @@ "acorn": "^8.8.2" } }, + "supermemo": { + "version": "2.0.17", + "resolved": "https://registry.npmjs.org/supermemo/-/supermemo-2.0.17.tgz", + "integrity": "sha512-c/BMAkG+IDYtAP1AR97DVU4x4gs8vfvLA4ejND7lHKdzjaAWwxixtcZjnQNfcyAKfZn2ovIYKJAGpTG45dr8ug==" + }, "supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -9569,6 +10028,14 @@ "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", "dev": true }, + "swiper": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/swiper/-/swiper-9.0.5.tgz", + "integrity": "sha512-UiLQ5fvn8L3ZZpaPa+9oiwKwhVGQt5TVc0UuXxFKHyTQe8g2E3vbPMiMfIGb6NhNGj5ntsSDyyNgg4qVmWlJkQ==", + "requires": { + "ssr-window": "^4.0.2" + } + }, "symbol-tree": { "version": "3.2.4", "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", @@ -9853,13 +10320,13 @@ } }, "vue-tsc": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/vue-tsc/-/vue-tsc-1.1.7.tgz", - "integrity": "sha512-TYuWJMQmwaV9kC1oWvw6fSHlymJpsD1ad4GaYqvUloph7E2QiVEXZyZe+lf0pHHayyltZp0Z+ZqcLuXoru8lzA==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/vue-tsc/-/vue-tsc-1.2.0.tgz", + "integrity": "sha512-rIlzqdrhyPYyLG9zxsVRa+JEseeS9s8F2BbVVVWRRsTZvJO2BbhLEb2HW3MY+DFma0378tnIqs+vfTzbcQtRFw==", "dev": true, "requires": { - "@volar/vue-language-core": "1.1.7", - "@volar/vue-typescript": "1.1.7" + "@volar/vue-language-core": "1.2.0", + "@volar/vue-typescript": "1.2.0" } }, "vuetify": { diff --git a/package.json b/package.json index 77beb82..6d4cf21 100644 --- a/package.json +++ b/package.json @@ -14,7 +14,11 @@ "dependencies": { "@vueuse/core": "^9.13.0", "file-dialog": "^0.0.8", + "github-markdown-css": "^5.2.0", + "highlight.js": "^11.7.0", "markdown-it": "^13.0.1", + "supermemo": "^2.0.17", + "swiper": "^9.0.5", "uuidv4": "^6.2.13", "vue": "^3.2.45", "vue-router": "^4.1.6", @@ -39,6 +43,7 @@ "jsdom": "^20.0.3", "npm-run-all": "^4.1.5", "prettier": "^2.7.1", + "sass": "^1.58.3", "typescript": "~4.7.4", "vite": "^4.0.0", "vitest": "^0.25.6", diff --git a/src/assets/style.scss b/src/assets/style.scss new file mode 100644 index 0000000..47c1229 --- /dev/null +++ b/src/assets/style.scss @@ -0,0 +1,13 @@ +@import 'highlight.js/scss/base16/atelier-sulphurpool-light.scss'; +@import 'github-markdown-css/github-markdown.css'; + +:root { + --swiper-navigation-sides-offset: -60px; + --swiper-navigation-size: 32px; /* To edit the size of the arrows */ + --swiper-navigation-color: #4527a0; /* To edit the color of the arrows */ +} + +.markdown-body { + padding: 10px; + background-color: rgba(0, 0, 0, 0); +} diff --git a/src/components/AddLearnsetModal.vue b/src/components/AddLearnsetModal.vue index 18f5304..3d848f2 100644 --- a/src/components/AddLearnsetModal.vue +++ b/src/components/AddLearnsetModal.vue @@ -1,6 +1,11 @@ + + diff --git a/src/components/__tests__/LearnsetCard.spec.ts b/src/components/__tests__/LearnsetCard.spec.ts new file mode 100644 index 0000000..0993229 --- /dev/null +++ b/src/components/__tests__/LearnsetCard.spec.ts @@ -0,0 +1,136 @@ +import LearnsetCard from '@/components/LearnsetCard.vue'; +import type { Card } from '@/types/interfaces'; +import { + findAllByTestId, + fireEvent, + render, + waitFor, +} from '@testing-library/vue'; +import vuetify from '@/utils/setupVuetify'; +import markdownit from 'markdown-it'; +import { markdownItPlugin } from '@/plugins/markdownit'; +import { createRouter, createWebHistory } from 'vue-router'; + +const router = createRouter({ + history: createWebHistory(), + routes: [], +}); + +describe('LearnsetCard Component', () => { + const md = markdownit({}); + const FRONT_TOKEN = md.parse(`## ์•ˆ๋…•ํ•˜์„ธ์š”\n\n`, {}); + const BACK_TOKEN = md.parse(`- ๋ฐ˜๊ฐ‘์Šต๋‹ˆ๋‹ค\n- ํ•˜ํ•˜ํ•˜ํ•˜\n\n\n`, {}); + + const CARD_DATA: Card = { + id: '1', + front: FRONT_TOKEN, + back: BACK_TOKEN, + title: '์•ˆ๋…•ํ•˜์„ธ์š”', + efactor: 2.5, + dueDate: '', + repetition: 0, + interval: 0, + reviewDate: '', + }; + + it('์นด๋“œ์˜ ์งˆ๋ฌธ์ด ๋ Œ๋”๋ง ๋œ๋‹ค.', () => { + const { getByText } = render(LearnsetCard, { + global: { + plugins: [router, vuetify, markdownItPlugin], + }, + props: { + card: CARD_DATA, + }, + }); + + expect(getByText('์•ˆ๋…•ํ•˜์„ธ์š”')).toBeInTheDocument(); + }); + + it('์ •๋‹ต ํ™•์ธ ๋ฒ„ํŠผ์„ ํด๋ฆญํ•˜๋ฉด ์นด๋“œ์˜ ์ •๋‹ต๊ณผ ์ ์ˆ˜๋ฅผ ๋งค๊ธธ ์ˆ˜ ์žˆ๋Š” ๋ฒ„ํŠผ์ด ๋ Œ๋”๋ง ๋œ๋‹ค.', async () => { + const { getByText, getAllByRole, getByRole, getByTestId } = render( + LearnsetCard, + { + global: { + plugins: [router, vuetify, markdownItPlugin], + }, + props: { + card: CARD_DATA, + review: true, + }, + data() { + return { + showBack: false, + submitted: false, + }; + }, + } + ); + await fireEvent.click(getByTestId('show-answer-btn')); + + expect(getByText('๋ฐ˜๊ฐ‘์Šต๋‹ˆ๋‹ค')).toBeInTheDocument(); + expect(getByText('ํ•˜ํ•˜ํ•˜ํ•˜')).toBeInTheDocument(); + + const scores = Array.from({ length: 6 }, (v, i) => i); + const scoreButtons: HTMLButtonElement[] = getAllByRole('button', { + name: /^[0-9]$/, + }); + scoreButtons.forEach(({ name }) => { + expect(scores.includes(Number(name))).toBeTruthy(); + }); + }); + + it('์ ์ˆ˜๋ฅผ ๋งค๊ธธ ์ˆ˜ ์žˆ๋Š” ๋ฒ„ํŠผ์„ ํด๋ฆญํ•˜๋ฉด ๋” ์ด์ƒ ๋ฒ„ํŠผ์„ ํด๋ฆญํ•  ์ˆ˜ ์—†๋‹ค.', async () => { + const { queryByRole, getAllByRole, getByRole, getByTestId } = render( + LearnsetCard, + { + global: { + plugins: [router, vuetify, markdownItPlugin], + }, + props: { + card: CARD_DATA, + review: true, + }, + data() { + return { + showBack: false, + submitted: false, + }; + }, + } + ); + + await fireEvent.click(getByTestId('show-answer-btn')); + + await fireEvent.click(getByRole('button', { name: '5' })); + + waitFor(() => { + const scoreButtons: HTMLButtonElement[] = getAllByRole('button', { + name: /^[0-9]$/, + }); + + scoreButtons.forEach((button) => { + expect(button).toBeDisabled(); + }); + }); + }); + + it('๋ฆฌ๋ทฐ๊ฐ€ ํ•„์š”ํ•˜์ง€ ์•Š๋Š” ํ•ญ๋ชฉ์€ ์ ์ˆ˜๋ฅผ ๋งค๊ธธ ์ˆ˜ ์—†๋‹ค.', () => { + const { queryByRole } = render(LearnsetCard, { + global: { + plugins: [router, vuetify, markdownItPlugin], + }, + props: { + card: CARD_DATA, + review: false, + }, + data() { + return { + showBack: false, + submitted: false, + }; + }, + }); + + expect(queryByRole('button', { name: '5' })).not.toBeInTheDocument(); + }); +}); diff --git a/src/constants/index.ts b/src/constants/index.ts new file mode 100644 index 0000000..fbd3569 --- /dev/null +++ b/src/constants/index.ts @@ -0,0 +1,12 @@ +const SCORES = [ + { score: '5', tooltip: '์™„๋ฒฝํ•œ ์‘๋‹ต' }, + { score: '4', tooltip: '๋ง์„ค์ž„ ๋์— ์˜ฌ๋ฐ”๋ฅธ ์‘๋‹ต' }, + { score: '3', tooltip: '์˜ฌ๋ฐ”๋ฅธ ์‘๋‹ต์ด์ง€๋งŒ ๊ธฐ์–ตํ•ด ๋‚ด๊ธฐ ์–ด๋ ค์›€' }, + { score: '2', tooltip: '์ž˜๋ชป๋œ ์‘๋‹ต, ์ •๋‹ต์„ ์‰ฝ๊ฒŒ ๊ธฐ์–ตํ•  ์ˆ˜๋Š” ์žˆ์Œ' }, + { score: '1', tooltip: '์ž˜๋ชป๋œ ์‘๋‹ต, ์˜ฌ๋ฐ”๋ฅธ ์‘๋‹ต์„ ๊ธฐ์–ตํ•จ' }, + { score: '0', tooltip: '์ „ํ˜€ ๊ธฐ์–ต์ด ์•ˆ๋‚จ' }, +]; + +const TIME_ZONE = 9 * 60 * 60 * 1000; + +export { SCORES, TIME_ZONE }; diff --git a/src/main.ts b/src/main.ts index d6c7e7f..28c4096 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,9 +1,12 @@ import { createApp } from 'vue'; import App from './App.vue'; import router from './router'; +import '@/assets/style.scss'; import 'vuetify/styles'; import '@mdi/font/css/materialdesignicons.css'; import vuetify from '@/utils/setupVuetify'; +import { markdownItPlugin } from '@/plugins/markdownit'; + import { createStore } from 'vuex'; import { store } from '@/store'; @@ -13,5 +16,6 @@ const app = createApp(App); app.use(vuexStore); app.use(router); app.use(vuetify); +app.use(markdownItPlugin); app.mount('#app'); diff --git a/src/plugins/markdownit.ts b/src/plugins/markdownit.ts new file mode 100644 index 0000000..62e961a --- /dev/null +++ b/src/plugins/markdownit.ts @@ -0,0 +1,71 @@ +import { inject } from 'vue'; +import type { InjectionKey, Plugin, App } from 'vue'; +import MarkdownIt, { type Options } from 'markdown-it'; +import hljs from 'highlight.js'; +import type Token from 'markdown-it/lib/token'; + +const markdownItKey: InjectionKey = Symbol('_markdownIt_'); + +export const useMarkdownIt = (): MarkdownIt => { + return inject(markdownItKey) as MarkdownIt; +}; + +export const markdownItPlugin: Plugin = { + install(app: App) { + const md: MarkdownIt = new MarkdownIt({ + html: true, + linkify: true, + highlight(code, lang) { + if (lang && hljs.getLanguage(lang)) { + try { + return `
${
+              hljs.highlight(code, { language: lang, ignoreIllegals: true })
+                .value
+            }
`; + } catch (__) { + console.log('markdownit error'); + } + } + + return ( + '
' +
+          md.utils.escapeHtml(code) +
+          '
' + ); + }, + }); + + const defaultRender = + md.renderer.rules.link_open || + function ( + tokens: Token[], + idx: number, + options: Options, + _: any, + self: any + ) { + return self.renderToken(tokens, idx, options); + }; + md.renderer.rules.link_open = function ( + tokens: Token[], + idx: number, + options: Options, + env: any, + self: any + ) { + const aIdx = tokens[idx].attrIndex('target'); + + if (aIdx < 0) { + tokens[idx].attrPush(['target', '_blank']); + } else { + const attrs = tokens[idx].attrs; + if (attrs) attrs[aIdx][1] = '_blank'; + tokens[idx].attrs = attrs; + } + + return defaultRender(tokens, idx, options, env, self); + }; + + app.provide(markdownItKey, md); + }, +}; diff --git a/src/router/__tests__/router.spec.ts b/src/router/__tests__/router.spec.ts index 5a04eca..5c51420 100644 --- a/src/router/__tests__/router.spec.ts +++ b/src/router/__tests__/router.spec.ts @@ -8,12 +8,18 @@ import { createStore, type StoreOptions } from 'vuex'; import { store } from '@/store'; import type { Learnset } from '@/types/interfaces'; import LearnsetView from '@/views/LearnsetView.vue'; +import LearnView from '@/views/LearnView.vue'; const router = createRouter({ history: createWebHistory(), routes: [ { path: '/', component: DashboardView, name: 'Dashboard' }, { path: '/learnset/:id', component: LearnsetView, name: 'LearnsetView' }, + { + path: '/learn/:id', + component: LearnView, + name: 'Learn', + }, ], }); diff --git a/src/router/index.ts b/src/router/index.ts index 1026495..b15aed4 100644 --- a/src/router/index.ts +++ b/src/router/index.ts @@ -1,5 +1,6 @@ import DashboardView from '@/views/DashboardView.vue'; import LearnsetView from '@/views/LearnsetView.vue'; +import LearnView from '@/views/LearnView.vue'; import { createRouter, createWebHistory } from 'vue-router'; @@ -8,6 +9,11 @@ const router = createRouter({ routes: [ { path: '/', component: DashboardView, name: 'Dashboard' }, { path: '/learnset/:id', component: LearnsetView, name: 'LearnsetView' }, + { + path: '/learn/:id', + component: LearnView, + name: 'Learn', + }, ], }); diff --git a/src/store/__tests__/getters.spec.ts b/src/store/__tests__/getters.spec.ts new file mode 100644 index 0000000..57c3f74 --- /dev/null +++ b/src/store/__tests__/getters.spec.ts @@ -0,0 +1,78 @@ +import type { Learnset } from '@/types/interfaces'; +import Token from 'markdown-it/lib/token'; +import { getters } from '../getters'; + +describe('getters', () => { + it('get learnset by id', () => { + const learnsets = [ + { + cards: [], + created: 0, + id: '1', + name: 'learnset 1', + }, + { + cards: [], + created: 0, + id: '2', + name: 'learnset 2', + }, + ]; + + const state = { learnsets }; + + const actual = getters.learnset(state)('1'); + + expect(actual).toEqual([learnsets[0]]); + }); + + it('get learnset by date', () => { + const TEMP_TOKEN = new Token('', '', 0); + const CARD1 = { + id: '1', + front: [TEMP_TOKEN], + back: [TEMP_TOKEN], + title: '์•ˆ๋…•ํ•˜์„ธ์š”', + efactor: 2.5, + dueDate: new Date('2023-02-25').toISOString(), + repetition: 0, + interval: 0, + reviewDate: '', + }; + + const CARD2 = { + id: '1', + front: [TEMP_TOKEN], + back: [TEMP_TOKEN], + title: '์•ˆ๋…•ํ•˜์„ธ์š”', + efactor: 2.5, + dueDate: new Date('2023-02-27').toISOString(), + repetition: 0, + interval: 0, + reviewDate: '', + }; + + const learnsets: Learnset[] = [ + { + cards: [CARD1, CARD2], + created: 0, + id: '1', + name: 'learnset 1', + }, + { + cards: [], + created: 0, + id: '2', + name: 'learnset 2', + }, + ]; + + const state = { learnsets }; + + const baseDate = new Date('2023-02-27').getTime(); + const actual = getters.reviewCards(state)({ id: '1', baseDate }); + const reviewCards = learnsets[0]; + reviewCards.cards = [CARD1]; + expect(actual).toEqual([reviewCards]); + }); +}); diff --git a/src/store/getters.ts b/src/store/getters.ts new file mode 100644 index 0000000..d8a4088 --- /dev/null +++ b/src/store/getters.ts @@ -0,0 +1,36 @@ +import type { Card, Learnset } from '@/types/interfaces'; +import type { RootState } from './state'; + +export const getters = { + learnset: + (state: RootState) => + (id: string): Learnset[] => { + const items = state.learnsets.filter((learnset) => learnset.id === id); + return items; + }, + reviewCards: + (state: RootState) => + ({ + id, + baseDate = new Date().getTime(), + }: { + id: string; + baseDate?: number; + }) => { + const filteredLearnset = state.learnsets.find( + (learnset) => learnset.id === id + ) as Learnset; + + const learnset = Object.assign({}, filteredLearnset); + const cards: Card[] = learnset?.cards.filter( + (card: Card) => + card.dueDate === '' || new Date(card.dueDate).getTime() < baseDate + ); + + learnset.cards = cards; + + return [learnset]; + }, +}; + +export type Getters = typeof getters; diff --git a/src/store/index.ts b/src/store/index.ts index 08bf378..4ee0141 100644 --- a/src/store/index.ts +++ b/src/store/index.ts @@ -1,9 +1,11 @@ import { state } from './state'; import { mutations } from './mutations'; +import { getters } from './getters'; export const store = { state() { return state; }, + getters, mutations, }; diff --git a/src/store/types.ts b/src/store/types.ts index b6c6645..d7327db 100644 --- a/src/store/types.ts +++ b/src/store/types.ts @@ -1,5 +1,6 @@ import type { CommitOptions, Store } from 'vuex'; import type { Mutations } from './mutations'; +import type { Getters } from './getters'; import type { RootState } from './state'; type MyMutations = { @@ -10,4 +11,12 @@ type MyMutations = { ): ReturnType; }; -export type MyStore = Omit, 'commit'> & MyMutations; +type MyGetters = { + getters: { + [K in keyof Getters]: ReturnType; + }; +}; + +export type MyStore = Omit, 'getters' | 'commit'> & + MyMutations & + MyGetters; diff --git a/src/utils/learnset.ts b/src/utils/learnset.ts index d5b5dca..feb35df 100644 --- a/src/utils/learnset.ts +++ b/src/utils/learnset.ts @@ -25,7 +25,11 @@ const getLearnsetFromTokens = (tokens: Token[]) => { if (type === 'heading_open' && tag === 'h2' && !front) { card.title = card.front[1].content; - cards.push({ ...card, id: uuid() }); + + if (card.back.length) { + cards.push({ ...card, id: uuid() }); + } + front = true; card['front'] = []; @@ -39,6 +43,11 @@ const getLearnsetFromTokens = (tokens: Token[]) => { } } + if (card.back.length > 0) { + card.title = card.front[1].content; + cards.push({ ...card, id: uuid() }); + } + const id = uuid(); const created = Date.now(); diff --git a/src/utils/supermemo.ts b/src/utils/supermemo.ts new file mode 100644 index 0000000..b96246a --- /dev/null +++ b/src/utils/supermemo.ts @@ -0,0 +1,27 @@ +import { supermemo, type SuperMemoGrade } from 'supermemo'; +import { TIME_ZONE } from '@/constants'; +import type { Card } from '@/types/interfaces'; + +const practice = (flashcard: Card, grade: SuperMemoGrade): Card => { + const { interval, repetition, efactor } = supermemo(flashcard, grade); + + const now = new Date(Date.now() + TIME_ZONE); + const dueDate = new Date( + now.getFullYear(), + now.getMonth(), + now.getDate() + interval, + now.getHours(), + now.getMinutes() + ).toISOString(); + + return { + ...flashcard, + reviewDate: now.toISOString(), + interval, + repetition, + efactor, + dueDate, + }; +}; + +export { practice }; diff --git a/src/views/DashboardView.vue b/src/views/DashboardView.vue index 301a6bc..d828b35 100644 --- a/src/views/DashboardView.vue +++ b/src/views/DashboardView.vue @@ -13,7 +13,6 @@ + + diff --git a/src/views/LearnsetView.vue b/src/views/LearnsetView.vue index f8662c3..47be7d7 100644 --- a/src/views/LearnsetView.vue +++ b/src/views/LearnsetView.vue @@ -1,7 +1,12 @@ - + diff --git a/tests/unit/learnset.spec.ts b/tests/unit/learnset.spec.ts index 0ac57e8..e3f3068 100644 --- a/tests/unit/learnset.spec.ts +++ b/tests/unit/learnset.spec.ts @@ -17,7 +17,7 @@ describe('learnset: getLearnsetFromTokens', () => { const { questions, responses } = FILE_DATA; const md = markdownit({}); const tokens = md.parse( - `${questions[0]}${responses[0]}${questions[1]}${responses[1]}${questions[2]}`, + `${questions[0]}${responses[0]}${questions[2]}${questions[1]}${responses[1]}`, {} );