diff --git a/.husky/pre-commit b/.husky/pre-commit deleted file mode 100755 index 36af2198..00000000 --- a/.husky/pre-commit +++ /dev/null @@ -1,4 +0,0 @@ -#!/bin/sh -. "$(dirname "$0")/_/husky.sh" - -npx lint-staged diff --git a/.knip.json b/.knip.json deleted file mode 100644 index 4438d7fa..00000000 --- a/.knip.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "ignoreDependencies": ["ts-node"] -} diff --git a/.lintstagedrc.json b/.lintstagedrc.json deleted file mode 100644 index f020ceed..00000000 --- a/.lintstagedrc.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "*.{js,jsx,ts,tsx}": "eslint", - "*.{js,json,jsx,scss,ts,tsx}": "prettier --write", - "*.md": "markdownlint" -} diff --git a/.markdownlint.json b/.markdownlint.json deleted file mode 100644 index 250854ca..00000000 --- a/.markdownlint.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "blanks-around-lists": false, - "emphasis-style": { "style": "underscore" }, - "line-length": { "headings": false, "tables": false }, - "no-duplicate-heading": { "siblings_only": true }, - "no-emphasis-as-header": false, - "ol-prefix": { "style": "one" }, - "strong-style": { "style": "asterisk" } -} diff --git a/.prettierrc.json b/.prettierrc.json deleted file mode 100644 index b967d7b0..00000000 --- a/.prettierrc.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "importOrder": [ - "", - "", - "", - "^@/", - "^[.]" - ], - "plugins": ["@ianvs/prettier-plugin-sort-imports"], - "singleQuote": true -} diff --git a/.yarnrc b/.yarnrc deleted file mode 100644 index fdd705c6..00000000 --- a/.yarnrc +++ /dev/null @@ -1 +0,0 @@ -save-prefix "" diff --git a/eslint.config.mjs b/eslint.config.mjs index f77c1ada..3eb0b51a 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -27,6 +27,7 @@ export default [ { argsIgnorePattern: '^_', ignoreRestSiblings: true }, ], 'import/consistent-type-specifier-style': ['error', 'prefer-inline'], + 'no-console': ['error', { allow: ['error', 'warn'] }], }, }, ].map((it) => ({ diff --git a/knip.config.js b/knip.config.js new file mode 100644 index 00000000..30c8ec9f --- /dev/null +++ b/knip.config.js @@ -0,0 +1,4 @@ +module.exports = { + ignore: ['markdownlint.config.js'], + ignoreDependencies: ['ts-node'], +}; diff --git a/markdown/articles/2020/01/01/echoes-of-the-past.md b/markdown/articles/2020/01/01/echoes-of-the-past.md index 860f38e8..4fec15ba 100644 --- a/markdown/articles/2020/01/01/echoes-of-the-past.md +++ b/markdown/articles/2020/01/01/echoes-of-the-past.md @@ -130,7 +130,9 @@ be more aggressive with your cantrips. ## Matchups and sideboarding based on broad category -### Fair Blue Decks (Slghtly Favorable, how much depends a lot on the specfic opponent) +### Fair Blue Decks + +_Slightly favorable, how much depends a lot on the specfic opponent._ It may seem suprising on the surface, but this deck is fine against blue decks. Refilling a blue mage's hand or going all in on Doomsday may not seem like good @@ -156,7 +158,9 @@ number of goblins against slower control. Even if they don't win outright they can get your opponent low and force them to spend resources dealing with the horde while you build back up for another go. -### Permanent Based Hate Decks including Burn (Slightly Unfavorable, except DnT which is even or slightly favorable) +### Permanent Based Hate Decks including Burn + +_Slightly unfavorable, except Taxes which is even or slightly favorable._ Generally in these matchups you win by giving your opponent as few turns as possible. You have wishable cards to deal with a permanent or 2, but it can be @@ -171,7 +175,9 @@ and bring in your bounce spells or anything like Abrade or Abrupt Decay that you may have. These matchups tend to be straightforward. Watchout for things that affect your manabase, and try your best to create an opening. -### Combo Mirrors and Pseudo-Mirrors (Slightly Favorable, faster = less favorable) +### Combo Mirrors and Pseudo-Mirrors + +_Slightly favorable, faster: less favorable._ This list is fast enough to have a shot against just about any other combo deck, has strong game against discard with Veil of Summer and Echoes, and packs enough diff --git a/markdown/chapters/appendices/faq.md b/markdown/chapters/appendices/faq.md index 49a9d715..18df0c48 100644 --- a/markdown/chapters/appendices/faq.md +++ b/markdown/chapters/appendices/faq.md @@ -3,6 +3,8 @@ banner: Information Booth | UNF | 218d title: Frequently Asked Questions --- + + ## Table of Contents ## Preamble diff --git a/markdownlint.config.js b/markdownlint.config.js new file mode 100644 index 00000000..efab4424 --- /dev/null +++ b/markdownlint.config.js @@ -0,0 +1,6 @@ +module.exports = { + default: true, + 'line-length': { tables: false }, + 'no-duplicate-heading': { siblings_only: true }, + 'ol-prefix': { style: 'one' }, +}; diff --git a/package.json b/package.json index 19e89029..b8d92919 100644 --- a/package.json +++ b/package.json @@ -19,8 +19,7 @@ "lint:format:wiki": "prettier --check --log-level warn markdown/", "lint:prune": "knip --exclude enumMembers", "lint:typings": "tsc", - "lint:wiki": "markdownlint markdown/", - "prepare": "husky install", + "lint:wiki": "markdownlint --config markdownlint.config.js markdown/", "scryfall": "node ./scryfall/server.js", "start": "next start", "test": "jest", @@ -34,7 +33,7 @@ "@korumite/kiwi": "2.9.1", "@mdi/js": "7.4.47", "@mdi/react": "1.6.1", - "@mui/material": "5.15.17", + "@mui/material": "5.15.18", "@mui/system": "5.15.15", "@mui/utils": "5.15.14", "@vercel/analytics": "1.2.2", @@ -56,7 +55,7 @@ "remark-parse": "11.0.0", "remark-stringify": "11.0.0", "remark-toc": "9.0.0", - "simple-icons": "11.14.0", + "simple-icons": "11.15.0", "unified": "11.0.4", "unist-util-remove": "4.0.0", "unist-util-select": "5.1.0", @@ -64,7 +63,7 @@ "vfile-matter": "5.0.0" }, "devDependencies": { - "@eslint/js": "9.2.0", + "@eslint/js": "9.3.0", "@ianvs/prettier-plugin-sort-imports": "4.2.1", "@testing-library/jest-dom": "6.4.5", "@testing-library/react": "15.0.7", @@ -76,13 +75,11 @@ "@types/react-syntax-highlighter": "15.5.13", "@types/unist": "3.0.2", "concurrently": "8.2.2", - "eslint": "9.2.0", + "eslint": "9.3.0", "eslint-plugin-import": "2.29.1", - "husky": "9.0.11", "jest": "29.7.0", "jest-environment-jsdom": "29.7.0", "knip": "5.16.0", - "lint-staged": "15.2.2", "markdownlint-cli": "0.40.0", "mdast-util-directive": "3.0.0", "prettier": "3.2.5", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index d51732c2..889f925f 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -27,8 +27,8 @@ importers: specifier: 1.6.1 version: 1.6.1 '@mui/material': - specifier: 5.15.17 - version: 5.15.17(@emotion/react@11.11.4(@types/react@18.3.2)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.2)(react@18.3.1))(@types/react@18.3.2)(react@18.3.1))(@types/react@18.3.2)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + specifier: 5.15.18 + version: 5.15.18(@emotion/react@11.11.4(@types/react@18.3.2)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.2)(react@18.3.1))(@types/react@18.3.2)(react@18.3.1))(@types/react@18.3.2)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@mui/system': specifier: 5.15.15 version: 5.15.15(@emotion/react@11.11.4(@types/react@18.3.2)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.2)(react@18.3.1))(@types/react@18.3.2)(react@18.3.1))(@types/react@18.3.2)(react@18.3.1) @@ -52,7 +52,7 @@ importers: version: 14.2.3(@babel/core@7.24.5)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) plaiceholder: specifier: 3.0.0 - version: 3.0.0(sharp@0.33.3) + version: 3.0.0(sharp@0.33.4) react: specifier: 18.3.1 version: 18.3.1 @@ -93,8 +93,8 @@ importers: specifier: 9.0.0 version: 9.0.0 simple-icons: - specifier: 11.14.0 - version: 11.14.0 + specifier: 11.15.0 + version: 11.15.0 unified: specifier: 11.0.4 version: 11.0.4 @@ -112,8 +112,8 @@ importers: version: 5.0.0 devDependencies: '@eslint/js': - specifier: 9.2.0 - version: 9.2.0 + specifier: 9.3.0 + version: 9.3.0 '@ianvs/prettier-plugin-sort-imports': specifier: 4.2.1 version: 4.2.1(prettier@3.2.5) @@ -148,14 +148,11 @@ importers: specifier: 8.2.2 version: 8.2.2 eslint: - specifier: 9.2.0 - version: 9.2.0 + specifier: 9.3.0 + version: 9.3.0 eslint-plugin-import: specifier: 2.29.1 - version: 2.29.1(@typescript-eslint/parser@7.9.0(eslint@9.2.0)(typescript@5.4.5))(eslint@9.2.0) - husky: - specifier: 9.0.11 - version: 9.0.11 + version: 2.29.1(@typescript-eslint/parser@7.9.0(eslint@9.3.0)(typescript@5.4.5))(eslint@9.3.0) jest: specifier: 29.7.0 version: 29.7.0(@types/node@20.12.12)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@types/node@20.12.12)(typescript@5.4.5)) @@ -165,9 +162,6 @@ importers: knip: specifier: 5.16.0 version: 5.16.0(@types/node@20.12.12)(typescript@5.4.5) - lint-staged: - specifier: 15.2.2 - version: 15.2.2 markdownlint-cli: specifier: 0.40.0 version: 0.40.0 @@ -185,7 +179,7 @@ importers: version: 5.4.5 typescript-eslint: specifier: 7.9.0 - version: 7.9.0(eslint@9.2.0)(typescript@5.4.5) + version: 7.9.0(eslint@9.3.0)(typescript@5.4.5) packages: @@ -442,12 +436,12 @@ packages: resolution: {integrity: sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA==} engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} - '@eslint/eslintrc@3.0.2': - resolution: {integrity: sha512-wV19ZEGEMAC1eHgrS7UQPqsdEiCIbTKTasEfcXAigzoXICcqZSjBZEHlZwNVvKg6UBCjSlos84XiLqsRJnIcIg==} + '@eslint/eslintrc@3.1.0': + resolution: {integrity: sha512-4Bfj15dVJdoy3RfZmmo86RK1Fwzn6SstsvK9JS+BaVKqC6QQQQyXekNaC+g+LKNgkQ+2VhGAzm6hO40AhMR3zQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@eslint/js@9.2.0': - resolution: {integrity: sha512-ESiIudvhoYni+MdsI8oD7skpprZ89qKocwRM2KEvhhBJ9nl5MRh7BXU5GTod7Mdygq+AUl+QzId6iWJKR/wABA==} + '@eslint/js@9.3.0': + resolution: {integrity: sha512-niBqk8iwv96+yuTwjM6bWg8ovzAPF9qkICsGtcoa5/dmqcEMfdwNAX7+/OHcJHc7wj7XqPxH98oAHytFYlw6Sw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@floating-ui/core@1.6.2': @@ -479,8 +473,8 @@ packages: '@humanwhocodes/object-schema@2.0.3': resolution: {integrity: sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==} - '@humanwhocodes/retry@0.2.4': - resolution: {integrity: sha512-Ttl/jHpxfS3st5sxwICYfk4pOH0WrLI1SpW283GgQL7sCWU7EHIOhX4b4fkIxr3tkfzwg8+FNojtzsIEE7Ecgg==} + '@humanwhocodes/retry@0.3.0': + resolution: {integrity: sha512-d2CGZR2o7fS6sWB7DG/3a95bGKQyHMACZ5aW8qGkkqQpUoZV6C0X7Pc7l4ZNMZkfNBf4VWNe9E1jRsf0G146Ew==} engines: {node: '>=18.18'} '@ianvs/prettier-plugin-sort-imports@4.2.1': @@ -492,14 +486,14 @@ packages: '@vue/compiler-sfc': optional: true - '@img/sharp-darwin-arm64@0.33.3': - resolution: {integrity: sha512-FaNiGX1MrOuJ3hxuNzWgsT/mg5OHG/Izh59WW2mk1UwYHUwtfbhk5QNKYZgxf0pLOhx9ctGiGa2OykD71vOnSw==} + '@img/sharp-darwin-arm64@0.33.4': + resolution: {integrity: sha512-p0suNqXufJs9t3RqLBO6vvrgr5OhgbWp76s5gTRvdmxmuv9E1rcaqGUsl3l4mKVmXPkTkTErXediAui4x+8PSA==} engines: {glibc: '>=2.26', node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'} cpu: [arm64] os: [darwin] - '@img/sharp-darwin-x64@0.33.3': - resolution: {integrity: sha512-2QeSl7QDK9ru//YBT4sQkoq7L0EAJZA3rtV+v9p8xTKl4U1bUqTIaCnoC7Ctx2kCjQgwFXDasOtPTCT8eCTXvw==} + '@img/sharp-darwin-x64@0.33.4': + resolution: {integrity: sha512-0l7yRObwtTi82Z6ebVI2PnHT8EB2NxBgpK2MiKJZJ7cz32R4lxd001ecMhzzsZig3Yv9oclvqqdV93jo9hy+Dw==} engines: {glibc: '>=2.26', node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'} cpu: [x64] os: [darwin] @@ -552,55 +546,55 @@ packages: cpu: [x64] os: [linux] - '@img/sharp-linux-arm64@0.33.3': - resolution: {integrity: sha512-Zf+sF1jHZJKA6Gor9hoYG2ljr4wo9cY4twaxgFDvlG0Xz9V7sinsPp8pFd1XtlhTzYo0IhDbl3rK7P6MzHpnYA==} + '@img/sharp-linux-arm64@0.33.4': + resolution: {integrity: sha512-2800clwVg1ZQtxwSoTlHvtm9ObgAax7V6MTAB/hDT945Tfyy3hVkmiHpeLPCKYqYR1Gcmv1uDZ3a4OFwkdBL7Q==} engines: {glibc: '>=2.26', node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'} cpu: [arm64] os: [linux] - '@img/sharp-linux-arm@0.33.3': - resolution: {integrity: sha512-Q7Ee3fFSC9P7vUSqVEF0zccJsZ8GiiCJYGWDdhEjdlOeS9/jdkyJ6sUSPj+bL8VuOYFSbofrW0t/86ceVhx32w==} + '@img/sharp-linux-arm@0.33.4': + resolution: {integrity: sha512-RUgBD1c0+gCYZGCCe6mMdTiOFS0Zc/XrN0fYd6hISIKcDUbAW5NtSQW9g/powkrXYm6Vzwd6y+fqmExDuCdHNQ==} engines: {glibc: '>=2.28', node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'} cpu: [arm] os: [linux] - '@img/sharp-linux-s390x@0.33.3': - resolution: {integrity: sha512-vFk441DKRFepjhTEH20oBlFrHcLjPfI8B0pMIxGm3+yilKyYeHEVvrZhYFdqIseSclIqbQ3SnZMwEMWonY5XFA==} - engines: {glibc: '>=2.28', node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'} + '@img/sharp-linux-s390x@0.33.4': + resolution: {integrity: sha512-h3RAL3siQoyzSoH36tUeS0PDmb5wINKGYzcLB5C6DIiAn2F3udeFAum+gj8IbA/82+8RGCTn7XW8WTFnqag4tQ==} + engines: {glibc: '>=2.31', node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'} cpu: [s390x] os: [linux] - '@img/sharp-linux-x64@0.33.3': - resolution: {integrity: sha512-Q4I++herIJxJi+qmbySd072oDPRkCg/SClLEIDh5IL9h1zjhqjv82H0Seupd+q2m0yOfD+/fJnjSoDFtKiHu2g==} + '@img/sharp-linux-x64@0.33.4': + resolution: {integrity: sha512-GoR++s0XW9DGVi8SUGQ/U4AeIzLdNjHka6jidVwapQ/JebGVQIpi52OdyxCNVRE++n1FCLzjDovJNozif7w/Aw==} engines: {glibc: '>=2.26', node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'} cpu: [x64] os: [linux] - '@img/sharp-linuxmusl-arm64@0.33.3': - resolution: {integrity: sha512-qnDccehRDXadhM9PM5hLvcPRYqyFCBN31kq+ErBSZtZlsAc1U4Z85xf/RXv1qolkdu+ibw64fUDaRdktxTNP9A==} + '@img/sharp-linuxmusl-arm64@0.33.4': + resolution: {integrity: sha512-nhr1yC3BlVrKDTl6cO12gTpXMl4ITBUZieehFvMntlCXFzH2bvKG76tBL2Y/OqhupZt81pR7R+Q5YhJxW0rGgQ==} engines: {musl: '>=1.2.2', node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'} cpu: [arm64] os: [linux] - '@img/sharp-linuxmusl-x64@0.33.3': - resolution: {integrity: sha512-Jhchim8kHWIU/GZ+9poHMWRcefeaxFIs9EBqf9KtcC14Ojk6qua7ghKiPs0sbeLbLj/2IGBtDcxHyjCdYWkk2w==} + '@img/sharp-linuxmusl-x64@0.33.4': + resolution: {integrity: sha512-uCPTku0zwqDmZEOi4ILyGdmW76tH7dm8kKlOIV1XC5cLyJ71ENAAqarOHQh0RLfpIpbV5KOpXzdU6XkJtS0daw==} engines: {musl: '>=1.2.2', node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'} cpu: [x64] os: [linux] - '@img/sharp-wasm32@0.33.3': - resolution: {integrity: sha512-68zivsdJ0koE96stdUfM+gmyaK/NcoSZK5dV5CAjES0FUXS9lchYt8LAB5rTbM7nlWtxaU/2GON0HVN6/ZYJAQ==} + '@img/sharp-wasm32@0.33.4': + resolution: {integrity: sha512-Bmmauh4sXUsUqkleQahpdNXKvo+wa1V9KhT2pDA4VJGKwnKMJXiSTGphn0gnJrlooda0QxCtXc6RX1XAU6hMnQ==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'} cpu: [wasm32] - '@img/sharp-win32-ia32@0.33.3': - resolution: {integrity: sha512-CyimAduT2whQD8ER4Ux7exKrtfoaUiVr7HG0zZvO0XTFn2idUWljjxv58GxNTkFb8/J9Ub9AqITGkJD6ZginxQ==} + '@img/sharp-win32-ia32@0.33.4': + resolution: {integrity: sha512-99SJ91XzUhYHbx7uhK3+9Lf7+LjwMGQZMDlO/E/YVJ7Nc3lyDFZPGhjwiYdctoH2BOzW9+TnfqcaMKt0jHLdqw==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'} cpu: [ia32] os: [win32] - '@img/sharp-win32-x64@0.33.3': - resolution: {integrity: sha512-viT4fUIDKnli3IfOephGnolMzhz5VaTvDRkYqtZxOMIoMQ4MrAziO7pT1nVnOt2FAm7qW5aa+CCc13aEY6Le0g==} + '@img/sharp-win32-x64@0.33.4': + resolution: {integrity: sha512-3QLocdTRVIrFNye5YocZl+KKpYKP+fksi1QhmOArgx7GyhIbQp/WrJRu176jm8IxromS7RIkzMiMINVdBtC8Aw==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'} cpu: [x64] os: [win32] @@ -724,11 +718,11 @@ packages: '@types/react': optional: true - '@mui/core-downloads-tracker@5.15.17': - resolution: {integrity: sha512-DVAejDQkjNnIac7MfP8sLzuo7fyrBPxNdXe+6bYqOqg1z2OPTlfFAejSNzWe7UenRMuFu9/AyFXj/X2vN2w6dA==} + '@mui/core-downloads-tracker@5.15.18': + resolution: {integrity: sha512-/9pVk+Al8qxAjwFUADv4BRZgMpZM4m5E+2Q/20qhVPuIJWqKp4Ie4tGExac6zu93rgPTYVQGgu+1vjiT0E+cEw==} - '@mui/material@5.15.17': - resolution: {integrity: sha512-ru/MLvTkCh0AZXmqwIpqGTOoVBS/sX48zArXq/DvktxXZx4fskiRA2PEc7Rk5ZlFiZhKh4moL4an+l8zZwq49Q==} + '@mui/material@5.15.18': + resolution: {integrity: sha512-n+/dsiqux74fFfcRUJjok+ieNQ7+BEk6/OwX9cLcLvriZrZb+/7Y8+Fd2HlUUbn5N0CDurgAHm0VH1DqyJ9HAw==} engines: {node: '>=12.0.0'} peerDependencies: '@emotion/react': ^11.5.0 @@ -1171,10 +1165,6 @@ packages: resolution: {integrity: sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==} engines: {node: '>=8'} - ansi-escapes@6.2.1: - resolution: {integrity: sha512-4nJ3yixlEthEJ9Rk4vPcdBRkZvQZlYyu8j4/Mqz5sgIkddmEnH2Yj2ZrnP9S3tQOvSNRUIgVNF/1yPpRAGNRig==} - engines: {node: '>=14.16'} - ansi-regex@5.0.1: resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} engines: {node: '>=8'} @@ -1343,8 +1333,8 @@ packages: resolution: {integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==} engines: {node: '>=10'} - caniuse-lite@1.0.30001618: - resolution: {integrity: sha512-p407+D1tIkDvsEAPS22lJxLQQaG8OTBEqo0KhzfABGk0TU4juBNDSfH0hyAp/HRyx+M8L17z/ltyhxh27FTfQg==} + caniuse-lite@1.0.30001620: + resolution: {integrity: sha512-WJvYsOjd1/BYUY6SNGUosK9DUidBPDTnOARHp3fSmFO1ekdxaY6nKRttEVrfMmYi80ctS0kz1wiWmm14fVc3ew==} ccount@2.0.1: resolution: {integrity: sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==} @@ -1361,10 +1351,6 @@ packages: resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} engines: {node: '>=10'} - chalk@5.3.0: - resolution: {integrity: sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==} - engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} - char-regex@1.0.2: resolution: {integrity: sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==} engines: {node: '>=10'} @@ -1401,14 +1387,6 @@ packages: resolution: {integrity: sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==} engines: {node: '>=6'} - cli-cursor@4.0.0: - resolution: {integrity: sha512-VGtlMu3x/4DOtIUwEkRezxUZ2lBacNJCHash0N0WeZDBS+7Ux1dm3XWAgWYxLJFMMdOeXMHXorshEFhbMSGelg==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - - cli-truncate@4.0.0: - resolution: {integrity: sha512-nPdaFdQ0h/GEigbPClz11D0v/ZJEwxmeVZGeMo3Z5StPtUTkA9o1lD6QwoirYiSDzbcwn2XcjwmCp68W1IS4TA==} - engines: {node: '>=18'} - client-only@0.0.1: resolution: {integrity: sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==} @@ -1451,9 +1429,6 @@ packages: resolution: {integrity: sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==} engines: {node: '>=12.5.0'} - colorette@2.0.20: - resolution: {integrity: sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==} - combined-stream@1.0.8: resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} engines: {node: '>= 0.8'} @@ -1464,10 +1439,6 @@ packages: comma-separated-tokens@2.0.3: resolution: {integrity: sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==} - commander@11.1.0: - resolution: {integrity: sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==} - engines: {node: '>=16'} - commander@12.0.0: resolution: {integrity: sha512-MwVNWlYjDTtOjX5PiD7o5pK0UrFU/OYgcJfjjK4RaHZETNtjJqrZa9Y9ds88+A+f+d5lv+561eZ+yCKoS3gbAA==} engines: {node: '>=18'} @@ -1659,16 +1630,13 @@ packages: easy-table@1.2.0: resolution: {integrity: sha512-OFzVOv03YpvtcWGe5AayU5G2hgybsg3iqA6drU8UaoZyB9jLGMTrz9+asnLp/E+6qPh88yEI1gvyZFZ41dmgww==} - electron-to-chromium@1.4.771: - resolution: {integrity: sha512-b/CmBh1c5SXZy5oFu4a0o+2TdM0AYStiwoQebEoImGAINstCsS/s/MOvPKMoxu1nA2BJtEOJI1nC/VoVRzdXWA==} + electron-to-chromium@1.4.774: + resolution: {integrity: sha512-132O1XCd7zcTkzS3FgkAzKmnBuNJjK8WjcTtNuoylj7MYbqw5eXehjQ5OK91g0zm7OTKIPeaAG4CPoRfD9M1Mg==} emittery@0.13.1: resolution: {integrity: sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==} engines: {node: '>=12'} - emoji-regex@10.3.0: - resolution: {integrity: sha512-QpLs9D9v9kArv4lfDEgg1X/gN5XLnf/A6l9cs8SPZLRZR3ZkY9+kwIQTxm+fsSej5UMYGE8fdoaZVIBlqG0XTw==} - emoji-regex@8.0.0: resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} @@ -1780,8 +1748,8 @@ packages: resolution: {integrity: sha512-OtIRv/2GyiF6o/d8K7MYKKbXrOUBIK6SfkIRM4Z0dY3w+LiQ0vy3F57m0Z71bjbyeiWFiHJ8brqnmE6H6/jEuw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - eslint@9.2.0: - resolution: {integrity: sha512-0n/I88vZpCOzO+PQpt0lbsqmn9AsnsJAQseIqhZFI8ibQT0U1AkEKRxA3EVMos0BoHSXDQvCXY25TUjB5tr8Og==} + eslint@9.3.0: + resolution: {integrity: sha512-5Iv4CsZW030lpUqHBapdPo3MJetAPtejVW8B84GIcIIv8+ohFaddXsrn1Gn8uD9ijDb+kcYKFUVmC8qG8B2ORQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} hasBin: true @@ -1813,17 +1781,10 @@ packages: resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} engines: {node: '>=0.10.0'} - eventemitter3@5.0.1: - resolution: {integrity: sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==} - execa@5.1.1: resolution: {integrity: sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==} engines: {node: '>=10'} - execa@8.0.1: - resolution: {integrity: sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==} - engines: {node: '>=16.17'} - exit@0.1.2: resolution: {integrity: sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==} engines: {node: '>= 0.8.0'} @@ -1938,10 +1899,6 @@ packages: resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} engines: {node: 6.* || 8.* || >= 10.*} - get-east-asian-width@1.2.0: - resolution: {integrity: sha512-2nk+7SIVb14QrgXFHcm84tD4bKQz0RxPuMT8Ag5KPOq7J5fEmAg0UbXdTOSHqNuHSU28k55qnceesxXRZGzKWA==} - engines: {node: '>=18'} - get-intrinsic@1.2.4: resolution: {integrity: sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==} engines: {node: '>= 0.4'} @@ -1958,10 +1915,6 @@ packages: resolution: {integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==} engines: {node: '>=10'} - get-stream@8.0.1: - resolution: {integrity: sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==} - engines: {node: '>=16'} - get-symbol-description@1.0.2: resolution: {integrity: sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg==} engines: {node: '>= 0.4'} @@ -2093,15 +2046,6 @@ packages: resolution: {integrity: sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==} engines: {node: '>=10.17.0'} - human-signals@5.0.0: - resolution: {integrity: sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==} - engines: {node: '>=16.17.0'} - - husky@9.0.11: - resolution: {integrity: sha512-AB6lFlbwwyIqMdHYhwPe+kjOC3Oc5P3nThEoW/AaO2BX3vJDjWPFxYLxokUZOo6RNX20He3AaT8sESs9NJcmEw==} - engines: {node: '>=18'} - hasBin: true - iconv-lite@0.6.3: resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==} engines: {node: '>=0.10.0'} @@ -2209,14 +2153,6 @@ packages: resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} engines: {node: '>=8'} - is-fullwidth-code-point@4.0.0: - resolution: {integrity: sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ==} - engines: {node: '>=12'} - - is-fullwidth-code-point@5.0.0: - resolution: {integrity: sha512-OVa3u9kkBbw7b8Xw5F9P+D/T9X+Z4+JruYVNapTjPYZYUznQ5YfWeFkOj606XYYW8yugTfC8Pj0hYqvi4ryAhA==} - engines: {node: '>=18'} - is-generator-fn@2.1.0: resolution: {integrity: sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==} engines: {node: '>=6'} @@ -2274,10 +2210,6 @@ packages: resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==} engines: {node: '>=8'} - is-stream@3.0.0: - resolution: {integrity: sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - is-string@1.0.7: resolution: {integrity: sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==} engines: {node: '>= 0.4'} @@ -2553,25 +2485,12 @@ packages: resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} engines: {node: '>= 0.8.0'} - lilconfig@3.0.0: - resolution: {integrity: sha512-K2U4W2Ff5ibV7j7ydLr+zLAkIg5JJ4lPn1Ltsdt+Tz/IjQ8buJ55pZAxoP34lqIiwtF9iAvtLv3JGv7CAyAg+g==} - engines: {node: '>=14'} - lines-and-columns@1.2.4: resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} linkify-it@5.0.0: resolution: {integrity: sha512-5aHCbzQRADcdP+ATqnDuhhJ/MRIqDkZX5pyjFHRRysS8vZ5AbqGEoFIb6pYHPZ+L/OC2Lc+xT8uHVVR5CAK/wQ==} - lint-staged@15.2.2: - resolution: {integrity: sha512-TiTt93OPh1OZOsb5B7k96A/ATl2AjIZo+vnzFZ6oHK5FuTk63ByDtxGQpHm+kFETjEWqgkF95M8FRXKR/LEBcw==} - engines: {node: '>=18.12.0'} - hasBin: true - - listr2@8.0.1: - resolution: {integrity: sha512-ovJXBXkKGfq+CwmKTjluEqFi3p4h8xvkxGQQAQan22YCgef4KZ1mKGjzfGh6PL6AW5Csw0QiQPNuQyH+6Xk3hA==} - engines: {node: '>=18.0.0'} - locate-path@5.0.0: resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==} engines: {node: '>=8'} @@ -2589,10 +2508,6 @@ packages: lodash@4.17.21: resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} - log-update@6.0.0: - resolution: {integrity: sha512-niTvB4gqvtof056rRIrTZvjNYE4rCUzO6X/X+kYjd7WFxXeJ0NwEFnRxX6ehkvv3jTwrXnNdtAak5XYZuIyPFw==} - engines: {node: '>=18'} - longest-streak@3.1.0: resolution: {integrity: sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==} @@ -2824,10 +2739,6 @@ packages: resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==} engines: {node: '>=6'} - mimic-fn@4.0.0: - resolution: {integrity: sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==} - engines: {node: '>=12'} - min-indent@1.0.1: resolution: {integrity: sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==} engines: {node: '>=4'} @@ -2892,10 +2803,6 @@ packages: resolution: {integrity: sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==} engines: {node: '>=8'} - npm-run-path@5.3.0: - resolution: {integrity: sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - nth-check@2.1.1: resolution: {integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==} @@ -2943,10 +2850,6 @@ packages: resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==} engines: {node: '>=6'} - onetime@6.0.0: - resolution: {integrity: sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==} - engines: {node: '>=12'} - optionator@0.9.4: resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==} engines: {node: '>= 0.8.0'} @@ -3008,10 +2911,6 @@ packages: resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} engines: {node: '>=8'} - path-key@4.0.0: - resolution: {integrity: sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==} - engines: {node: '>=12'} - path-parse@1.0.7: resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} @@ -3037,11 +2936,6 @@ packages: resolution: {integrity: sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==} engines: {node: '>=12'} - pidtree@0.6.0: - resolution: {integrity: sha512-eG2dWTVw5bzqGRztnHExczNxt5VGsE6OwTeCG3fdUf9KBsZzO3R5OIIIzWR+iZA0NtZ+RDVdaoE2dK1cn6jH4g==} - engines: {node: '>=0.10'} - hasBin: true - pirates@4.0.6: resolution: {integrity: sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==} engines: {node: '>= 6'} @@ -3240,10 +3134,6 @@ packages: resolution: {integrity: sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==} hasBin: true - restore-cursor@4.0.0: - resolution: {integrity: sha512-I9fPXU9geO9bHOt9pHHOhOkYerIMsmVaWB0rA2AI9ERh/+x/i7MV5HKBNrg+ljO5eoPVgCcnFuRjJ9uH6I/3eg==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - reusify@1.0.4: resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==} engines: {iojs: '>=1.0.0', node: '>=0.10.0'} @@ -3251,9 +3141,6 @@ packages: reverse-arguments@1.0.0: resolution: {integrity: sha512-/x8uIPdTafBqakK0TmPNJzgkLP+3H+yxpUJhCQHsLBg1rYEVNR2D8BRYNWQhVBjyOd7oo1dZRVzIkwMY2oqfYQ==} - rfdc@1.3.1: - resolution: {integrity: sha512-r5a3l5HzYlIC68TpmYKlxWjmOP6wiPJ1vWv2HeLhNsRZMrCkxeqxiHlQ21oXmQ4F3SiryXBHhAD7JZqvOJjFmg==} - run-con@1.3.2: resolution: {integrity: sha512-CcfE+mYiTcKEzg0IqS08+efdnH0oJ3zV0wSUFBNrMHMuxCtXvBCLzCJHatwuXDcu/RlhjTziTo/a1ruQik6/Yg==} hasBin: true @@ -3306,8 +3193,8 @@ packages: resolution: {integrity: sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==} engines: {node: '>= 0.4'} - sharp@0.33.3: - resolution: {integrity: sha512-vHUeXJU1UvlO/BNwTpT0x/r53WkLUVxrmb5JTgW92fdFCFk0ispLMAeu/jPO2vjkXM1fYUi3K7/qcLF47pwM1A==} + sharp@0.33.4: + resolution: {integrity: sha512-7i/dt5kGl7qR4gwPRD2biwD2/SvBn3O04J77XKFgL2OnZtQw+AG9wnuS/csmu80nPRHLYE9E41fyEiG8nhH6/Q==} engines: {libvips: '>=8.15.2', node: ^18.17.0 || ^20.3.0 || >=21.0.0} shebang-command@2.0.0: @@ -3335,8 +3222,8 @@ packages: resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} engines: {node: '>=14'} - simple-icons@11.14.0: - resolution: {integrity: sha512-KJ2R28d6tV+uu3GbRQTHizCGyjkI0QPhooYUcv4GjiE4XG0wSlqCFN/pUQK6gno46F0Fk2cyG5otFAK8EMaiYw==} + simple-icons@11.15.0: + resolution: {integrity: sha512-uDAdtIGc56YJiGpdzImENY4E+5qtHEorW11KoXiwDj4u4YSY74G+q/a9idlY8iEqrjghHGkZ/ras0jRT7JpDTQ==} engines: {node: '>=0.12.18'} simple-swizzle@0.2.2: @@ -3349,14 +3236,6 @@ packages: resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} engines: {node: '>=8'} - slice-ansi@5.0.0: - resolution: {integrity: sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ==} - engines: {node: '>=12'} - - slice-ansi@7.1.0: - resolution: {integrity: sha512-bSiSngZ/jWeX93BqeIAbImyTbEihizcwNjFoRUIY/T1wWQsfsm2Vw1agPKylXvQTU7iASGdHhyqRlqQzfz+Htg==} - engines: {node: '>=18'} - smol-toml@1.1.4: resolution: {integrity: sha512-Y0OT8HezWsTNeEOSVxDnKOW/AyNXHQ4BwJNbAXlLTF5wWsBvrcHhIkE5Rf8kQMLmgf7nDX3PVOlgC6/Aiggu3Q==} engines: {node: '>= 18', pnpm: '>= 8'} @@ -3396,10 +3275,6 @@ packages: resolution: {integrity: sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==} engines: {node: '>=10.0.0'} - string-argv@0.3.2: - resolution: {integrity: sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==} - engines: {node: '>=0.6.19'} - string-length@4.0.2: resolution: {integrity: sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==} engines: {node: '>=10'} @@ -3412,10 +3287,6 @@ packages: resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==} engines: {node: '>=12'} - string-width@7.1.0: - resolution: {integrity: sha512-SEIJCWiX7Kg4c129n48aDRwLbFb2LJmXXFrWBG4NGaRtMQ3myKPKbwrD1BKqQn74oCoNMBVrfDEr5M9YxCsrkw==} - engines: {node: '>=18'} - string.fromcodepoint@0.2.1: resolution: {integrity: sha512-n69H31OnxSGSZyZbgBlvYIXlrMhJQ0dQAX1js1QDhpaUH6zmU3QYlj07bCwCNlPOu3oRXIubGPl2gDGnHsiCqg==} @@ -3457,10 +3328,6 @@ packages: resolution: {integrity: sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==} engines: {node: '>=6'} - strip-final-newline@3.0.0: - resolution: {integrity: sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==} - engines: {node: '>=12'} - strip-indent@3.0.0: resolution: {integrity: sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==} engines: {node: '>=8'} @@ -3755,10 +3622,6 @@ packages: resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==} engines: {node: '>=12'} - wrap-ansi@9.0.0: - resolution: {integrity: sha512-G8ura3S+3Z2G+mkgNRq8dqaFZAuxfsxpBB8OCTGRTCtp+l/v9nbFNmCUP1BZMts3G1142MsZfn6eeUKrr4PD1Q==} - engines: {node: '>=18'} - wrappy@1.0.2: resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} @@ -3800,10 +3663,6 @@ packages: resolution: {integrity: sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==} engines: {node: '>= 6'} - yaml@2.3.4: - resolution: {integrity: sha512-8aAvwVUSHpfEqTQ4w/KMlf3HcRdt50E5ODIQJBw1fQ5RL34xabzxtUlzTXVqc4rkZsPbvrXKWnABCD7kWSmocA==} - engines: {node: '>= 14'} - yaml@2.4.2: resolution: {integrity: sha512-B3VqDZ+JAg1nZpaEmWtTXUlBneoGx6CPM9b0TENK6aoSu5t73dItudwdgmi6tHlIZZId4dZ9skcAQ2UbcyAeVA==} engines: {node: '>= 14'} @@ -4158,14 +4017,14 @@ snapshots: to-pascal-case: 1.0.0 unescape-js: 1.1.4 - '@eslint-community/eslint-utils@4.4.0(eslint@9.2.0)': + '@eslint-community/eslint-utils@4.4.0(eslint@9.3.0)': dependencies: - eslint: 9.2.0 + eslint: 9.3.0 eslint-visitor-keys: 3.4.3 '@eslint-community/regexpp@4.10.0': {} - '@eslint/eslintrc@3.0.2': + '@eslint/eslintrc@3.1.0': dependencies: ajv: 6.12.6 debug: 4.3.4 @@ -4179,7 +4038,7 @@ snapshots: transitivePeerDependencies: - supports-color - '@eslint/js@9.2.0': {} + '@eslint/js@9.3.0': {} '@floating-ui/core@1.6.2': dependencies: @@ -4212,7 +4071,7 @@ snapshots: '@humanwhocodes/object-schema@2.0.3': {} - '@humanwhocodes/retry@0.2.4': {} + '@humanwhocodes/retry@0.3.0': {} '@ianvs/prettier-plugin-sort-imports@4.2.1(prettier@3.2.5)': dependencies: @@ -4226,12 +4085,12 @@ snapshots: transitivePeerDependencies: - supports-color - '@img/sharp-darwin-arm64@0.33.3': + '@img/sharp-darwin-arm64@0.33.4': optionalDependencies: '@img/sharp-libvips-darwin-arm64': 1.0.2 optional: true - '@img/sharp-darwin-x64@0.33.3': + '@img/sharp-darwin-x64@0.33.4': optionalDependencies: '@img/sharp-libvips-darwin-x64': 1.0.2 optional: true @@ -4260,45 +4119,45 @@ snapshots: '@img/sharp-libvips-linuxmusl-x64@1.0.2': optional: true - '@img/sharp-linux-arm64@0.33.3': + '@img/sharp-linux-arm64@0.33.4': optionalDependencies: '@img/sharp-libvips-linux-arm64': 1.0.2 optional: true - '@img/sharp-linux-arm@0.33.3': + '@img/sharp-linux-arm@0.33.4': optionalDependencies: '@img/sharp-libvips-linux-arm': 1.0.2 optional: true - '@img/sharp-linux-s390x@0.33.3': + '@img/sharp-linux-s390x@0.33.4': optionalDependencies: '@img/sharp-libvips-linux-s390x': 1.0.2 optional: true - '@img/sharp-linux-x64@0.33.3': + '@img/sharp-linux-x64@0.33.4': optionalDependencies: '@img/sharp-libvips-linux-x64': 1.0.2 optional: true - '@img/sharp-linuxmusl-arm64@0.33.3': + '@img/sharp-linuxmusl-arm64@0.33.4': optionalDependencies: '@img/sharp-libvips-linuxmusl-arm64': 1.0.2 optional: true - '@img/sharp-linuxmusl-x64@0.33.3': + '@img/sharp-linuxmusl-x64@0.33.4': optionalDependencies: '@img/sharp-libvips-linuxmusl-x64': 1.0.2 optional: true - '@img/sharp-wasm32@0.33.3': + '@img/sharp-wasm32@0.33.4': dependencies: '@emnapi/runtime': 1.1.1 optional: true - '@img/sharp-win32-ia32@0.33.3': + '@img/sharp-win32-ia32@0.33.4': optional: true - '@img/sharp-win32-x64@0.33.3': + '@img/sharp-win32-x64@0.33.4': optional: true '@isaacs/cliui@8.0.2': @@ -4534,13 +4393,13 @@ snapshots: optionalDependencies: '@types/react': 18.3.2 - '@mui/core-downloads-tracker@5.15.17': {} + '@mui/core-downloads-tracker@5.15.18': {} - '@mui/material@5.15.17(@emotion/react@11.11.4(@types/react@18.3.2)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.2)(react@18.3.1))(@types/react@18.3.2)(react@18.3.1))(@types/react@18.3.2)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@mui/material@5.15.18(@emotion/react@11.11.4(@types/react@18.3.2)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.2)(react@18.3.1))(@types/react@18.3.2)(react@18.3.1))(@types/react@18.3.2)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@babel/runtime': 7.24.5 '@mui/base': 5.0.0-beta.40(@types/react@18.3.2)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@mui/core-downloads-tracker': 5.15.17 + '@mui/core-downloads-tracker': 5.15.18 '@mui/system': 5.15.15(@emotion/react@11.11.4(@types/react@18.3.2)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.2)(react@18.3.1))(@types/react@18.3.2)(react@18.3.1))(@types/react@18.3.2)(react@18.3.1) '@mui/types': 7.2.14(@types/react@18.3.2) '@mui/utils': 5.15.14(@types/react@18.3.2)(react@18.3.1) @@ -4853,15 +4712,15 @@ snapshots: dependencies: '@types/yargs-parser': 21.0.3 - '@typescript-eslint/eslint-plugin@7.9.0(@typescript-eslint/parser@7.9.0(eslint@9.2.0)(typescript@5.4.5))(eslint@9.2.0)(typescript@5.4.5)': + '@typescript-eslint/eslint-plugin@7.9.0(@typescript-eslint/parser@7.9.0(eslint@9.3.0)(typescript@5.4.5))(eslint@9.3.0)(typescript@5.4.5)': dependencies: '@eslint-community/regexpp': 4.10.0 - '@typescript-eslint/parser': 7.9.0(eslint@9.2.0)(typescript@5.4.5) + '@typescript-eslint/parser': 7.9.0(eslint@9.3.0)(typescript@5.4.5) '@typescript-eslint/scope-manager': 7.9.0 - '@typescript-eslint/type-utils': 7.9.0(eslint@9.2.0)(typescript@5.4.5) - '@typescript-eslint/utils': 7.9.0(eslint@9.2.0)(typescript@5.4.5) + '@typescript-eslint/type-utils': 7.9.0(eslint@9.3.0)(typescript@5.4.5) + '@typescript-eslint/utils': 7.9.0(eslint@9.3.0)(typescript@5.4.5) '@typescript-eslint/visitor-keys': 7.9.0 - eslint: 9.2.0 + eslint: 9.3.0 graphemer: 1.4.0 ignore: 5.3.1 natural-compare: 1.4.0 @@ -4871,14 +4730,14 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/parser@7.9.0(eslint@9.2.0)(typescript@5.4.5)': + '@typescript-eslint/parser@7.9.0(eslint@9.3.0)(typescript@5.4.5)': dependencies: '@typescript-eslint/scope-manager': 7.9.0 '@typescript-eslint/types': 7.9.0 '@typescript-eslint/typescript-estree': 7.9.0(typescript@5.4.5) '@typescript-eslint/visitor-keys': 7.9.0 debug: 4.3.4 - eslint: 9.2.0 + eslint: 9.3.0 optionalDependencies: typescript: 5.4.5 transitivePeerDependencies: @@ -4889,12 +4748,12 @@ snapshots: '@typescript-eslint/types': 7.9.0 '@typescript-eslint/visitor-keys': 7.9.0 - '@typescript-eslint/type-utils@7.9.0(eslint@9.2.0)(typescript@5.4.5)': + '@typescript-eslint/type-utils@7.9.0(eslint@9.3.0)(typescript@5.4.5)': dependencies: '@typescript-eslint/typescript-estree': 7.9.0(typescript@5.4.5) - '@typescript-eslint/utils': 7.9.0(eslint@9.2.0)(typescript@5.4.5) + '@typescript-eslint/utils': 7.9.0(eslint@9.3.0)(typescript@5.4.5) debug: 4.3.4 - eslint: 9.2.0 + eslint: 9.3.0 ts-api-utils: 1.3.0(typescript@5.4.5) optionalDependencies: typescript: 5.4.5 @@ -4918,13 +4777,13 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/utils@7.9.0(eslint@9.2.0)(typescript@5.4.5)': + '@typescript-eslint/utils@7.9.0(eslint@9.3.0)(typescript@5.4.5)': dependencies: - '@eslint-community/eslint-utils': 4.4.0(eslint@9.2.0) + '@eslint-community/eslint-utils': 4.4.0(eslint@9.3.0) '@typescript-eslint/scope-manager': 7.9.0 '@typescript-eslint/types': 7.9.0 '@typescript-eslint/typescript-estree': 7.9.0(typescript@5.4.5) - eslint: 9.2.0 + eslint: 9.3.0 transitivePeerDependencies: - supports-color - typescript @@ -4980,8 +4839,6 @@ snapshots: dependencies: type-fest: 0.21.3 - ansi-escapes@6.2.1: {} - ansi-regex@5.0.1: {} ansi-regex@6.0.1: {} @@ -5160,8 +5017,8 @@ snapshots: browserslist@4.23.0: dependencies: - caniuse-lite: 1.0.30001618 - electron-to-chromium: 1.4.771 + caniuse-lite: 1.0.30001620 + electron-to-chromium: 1.4.774 node-releases: 2.0.14 update-browserslist-db: 1.0.16(browserslist@4.23.0) @@ -5189,7 +5046,7 @@ snapshots: camelcase@6.3.0: {} - caniuse-lite@1.0.30001618: {} + caniuse-lite@1.0.30001620: {} ccount@2.0.1: {} @@ -5209,8 +5066,6 @@ snapshots: ansi-styles: 4.3.0 supports-color: 7.2.0 - chalk@5.3.0: {} - char-regex@1.0.2: {} character-entities-html4@2.1.0: {} @@ -5233,15 +5088,6 @@ snapshots: clean-stack@2.2.0: {} - cli-cursor@4.0.0: - dependencies: - restore-cursor: 4.0.0 - - cli-truncate@4.0.0: - dependencies: - slice-ansi: 5.0.0 - string-width: 7.1.0 - client-only@0.0.1: {} cliui@8.0.1: @@ -5281,8 +5127,6 @@ snapshots: color-convert: 2.0.1 color-string: 1.9.1 - colorette@2.0.20: {} - combined-stream@1.0.8: dependencies: delayed-stream: 1.0.0 @@ -5291,8 +5135,6 @@ snapshots: comma-separated-tokens@2.0.3: {} - commander@11.1.0: {} - commander@12.0.0: {} commander@4.1.1: {} @@ -5480,12 +5322,10 @@ snapshots: optionalDependencies: wcwidth: 1.0.1 - electron-to-chromium@1.4.771: {} + electron-to-chromium@1.4.774: {} emittery@0.13.1: {} - emoji-regex@10.3.0: {} - emoji-regex@8.0.0: {} emoji-regex@9.2.2: {} @@ -5597,17 +5437,17 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-module-utils@2.8.1(@typescript-eslint/parser@7.9.0(eslint@9.2.0)(typescript@5.4.5))(eslint-import-resolver-node@0.3.9)(eslint@9.2.0): + eslint-module-utils@2.8.1(@typescript-eslint/parser@7.9.0(eslint@9.3.0)(typescript@5.4.5))(eslint-import-resolver-node@0.3.9)(eslint@9.3.0): dependencies: debug: 3.2.7 optionalDependencies: - '@typescript-eslint/parser': 7.9.0(eslint@9.2.0)(typescript@5.4.5) - eslint: 9.2.0 + '@typescript-eslint/parser': 7.9.0(eslint@9.3.0)(typescript@5.4.5) + eslint: 9.3.0 eslint-import-resolver-node: 0.3.9 transitivePeerDependencies: - supports-color - eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.9.0(eslint@9.2.0)(typescript@5.4.5))(eslint@9.2.0): + eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.9.0(eslint@9.3.0)(typescript@5.4.5))(eslint@9.3.0): dependencies: array-includes: 3.1.8 array.prototype.findlastindex: 1.2.5 @@ -5615,9 +5455,9 @@ snapshots: array.prototype.flatmap: 1.3.2 debug: 3.2.7 doctrine: 2.1.0 - eslint: 9.2.0 + eslint: 9.3.0 eslint-import-resolver-node: 0.3.9 - eslint-module-utils: 2.8.1(@typescript-eslint/parser@7.9.0(eslint@9.2.0)(typescript@5.4.5))(eslint-import-resolver-node@0.3.9)(eslint@9.2.0) + eslint-module-utils: 2.8.1(@typescript-eslint/parser@7.9.0(eslint@9.3.0)(typescript@5.4.5))(eslint-import-resolver-node@0.3.9)(eslint@9.3.0) hasown: 2.0.2 is-core-module: 2.13.1 is-glob: 4.0.3 @@ -5628,7 +5468,7 @@ snapshots: semver: 6.3.1 tsconfig-paths: 3.15.0 optionalDependencies: - '@typescript-eslint/parser': 7.9.0(eslint@9.2.0)(typescript@5.4.5) + '@typescript-eslint/parser': 7.9.0(eslint@9.3.0)(typescript@5.4.5) transitivePeerDependencies: - eslint-import-resolver-typescript - eslint-import-resolver-webpack @@ -5643,15 +5483,15 @@ snapshots: eslint-visitor-keys@4.0.0: {} - eslint@9.2.0: + eslint@9.3.0: dependencies: - '@eslint-community/eslint-utils': 4.4.0(eslint@9.2.0) + '@eslint-community/eslint-utils': 4.4.0(eslint@9.3.0) '@eslint-community/regexpp': 4.10.0 - '@eslint/eslintrc': 3.0.2 - '@eslint/js': 9.2.0 + '@eslint/eslintrc': 3.1.0 + '@eslint/js': 9.3.0 '@humanwhocodes/config-array': 0.13.0 '@humanwhocodes/module-importer': 1.0.1 - '@humanwhocodes/retry': 0.2.4 + '@humanwhocodes/retry': 0.3.0 '@nodelib/fs.walk': 1.2.8 ajv: 6.12.6 chalk: 4.1.2 @@ -5704,8 +5544,6 @@ snapshots: esutils@2.0.3: {} - eventemitter3@5.0.1: {} - execa@5.1.1: dependencies: cross-spawn: 7.0.3 @@ -5718,18 +5556,6 @@ snapshots: signal-exit: 3.0.7 strip-final-newline: 2.0.0 - execa@8.0.1: - dependencies: - cross-spawn: 7.0.3 - get-stream: 8.0.1 - human-signals: 5.0.0 - is-stream: 3.0.0 - merge-stream: 2.0.0 - npm-run-path: 5.3.0 - onetime: 6.0.0 - signal-exit: 4.1.0 - strip-final-newline: 3.0.0 - exit@0.1.2: {} expect@29.7.0: @@ -5844,8 +5670,6 @@ snapshots: get-caller-file@2.0.5: {} - get-east-asian-width@1.2.0: {} - get-intrinsic@1.2.4: dependencies: es-errors: 1.3.0 @@ -5860,8 +5684,6 @@ snapshots: get-stream@6.0.1: {} - get-stream@8.0.1: {} - get-symbol-description@1.0.2: dependencies: call-bind: 1.0.7 @@ -6025,10 +5847,6 @@ snapshots: human-signals@2.1.0: {} - human-signals@5.0.0: {} - - husky@9.0.11: {} - iconv-lite@0.6.3: dependencies: safer-buffer: 2.1.2 @@ -6124,12 +5942,6 @@ snapshots: is-fullwidth-code-point@3.0.0: {} - is-fullwidth-code-point@4.0.0: {} - - is-fullwidth-code-point@5.0.0: - dependencies: - get-east-asian-width: 1.2.0 - is-generator-fn@2.1.0: {} is-glob@4.0.3: @@ -6169,8 +5981,6 @@ snapshots: is-stream@2.0.1: {} - is-stream@3.0.0: {} - is-string@1.0.7: dependencies: has-tostringtag: 1.0.2 @@ -6668,38 +6478,12 @@ snapshots: prelude-ls: 1.2.1 type-check: 0.4.0 - lilconfig@3.0.0: {} - lines-and-columns@1.2.4: {} linkify-it@5.0.0: dependencies: uc.micro: 2.1.0 - lint-staged@15.2.2: - dependencies: - chalk: 5.3.0 - commander: 11.1.0 - debug: 4.3.4 - execa: 8.0.1 - lilconfig: 3.0.0 - listr2: 8.0.1 - micromatch: 4.0.5 - pidtree: 0.6.0 - string-argv: 0.3.2 - yaml: 2.3.4 - transitivePeerDependencies: - - supports-color - - listr2@8.0.1: - dependencies: - cli-truncate: 4.0.0 - colorette: 2.0.20 - eventemitter3: 5.0.1 - log-update: 6.0.0 - rfdc: 1.3.1 - wrap-ansi: 9.0.0 - locate-path@5.0.0: dependencies: p-locate: 4.1.0 @@ -6714,14 +6498,6 @@ snapshots: lodash@4.17.21: {} - log-update@6.0.0: - dependencies: - ansi-escapes: 6.2.1 - cli-cursor: 4.0.0 - slice-ansi: 7.1.0 - strip-ansi: 7.1.0 - wrap-ansi: 9.0.0 - longest-streak@3.1.0: {} loose-envify@1.4.0: @@ -7205,8 +6981,6 @@ snapshots: mimic-fn@2.1.0: {} - mimic-fn@4.0.0: {} - min-indent@1.0.1: {} minimatch@3.1.2: @@ -7234,7 +7008,7 @@ snapshots: '@next/env': 14.2.3 '@swc/helpers': 0.5.5 busboy: 1.6.0 - caniuse-lite: 1.0.30001618 + caniuse-lite: 1.0.30001620 graceful-fs: 4.2.11 postcss: 8.4.31 react: 18.3.1 @@ -7264,10 +7038,6 @@ snapshots: dependencies: path-key: 3.1.1 - npm-run-path@5.3.0: - dependencies: - path-key: 4.0.0 - nth-check@2.1.1: dependencies: boolbase: 1.0.0 @@ -7318,10 +7088,6 @@ snapshots: dependencies: mimic-fn: 2.1.0 - onetime@6.0.0: - dependencies: - mimic-fn: 4.0.0 - optionator@0.9.4: dependencies: deep-is: 0.1.4 @@ -7396,8 +7162,6 @@ snapshots: path-key@3.1.1: {} - path-key@4.0.0: {} - path-parse@1.0.7: {} path-scurry@1.11.1: @@ -7415,17 +7179,15 @@ snapshots: picomatch@4.0.2: {} - pidtree@0.6.0: {} - pirates@4.0.6: {} pkg-dir@4.2.0: dependencies: find-up: 4.1.0 - plaiceholder@3.0.0(sharp@0.33.3): + plaiceholder@3.0.0(sharp@0.33.4): dependencies: - sharp: 0.33.3 + sharp: 0.33.4 possible-typed-array-names@1.0.0: {} @@ -7661,17 +7423,10 @@ snapshots: path-parse: 1.0.7 supports-preserve-symlinks-flag: 1.0.0 - restore-cursor@4.0.0: - dependencies: - onetime: 5.1.2 - signal-exit: 3.0.7 - reusify@1.0.4: {} reverse-arguments@1.0.0: {} - rfdc@1.3.1: {} - run-con@1.3.2: dependencies: deep-extend: 0.6.0 @@ -7737,14 +7492,14 @@ snapshots: functions-have-names: 1.2.3 has-property-descriptors: 1.0.2 - sharp@0.33.3: + sharp@0.33.4: dependencies: color: 4.2.3 detect-libc: 2.0.3 semver: 7.6.2 optionalDependencies: - '@img/sharp-darwin-arm64': 0.33.3 - '@img/sharp-darwin-x64': 0.33.3 + '@img/sharp-darwin-arm64': 0.33.4 + '@img/sharp-darwin-x64': 0.33.4 '@img/sharp-libvips-darwin-arm64': 1.0.2 '@img/sharp-libvips-darwin-x64': 1.0.2 '@img/sharp-libvips-linux-arm': 1.0.2 @@ -7753,15 +7508,15 @@ snapshots: '@img/sharp-libvips-linux-x64': 1.0.2 '@img/sharp-libvips-linuxmusl-arm64': 1.0.2 '@img/sharp-libvips-linuxmusl-x64': 1.0.2 - '@img/sharp-linux-arm': 0.33.3 - '@img/sharp-linux-arm64': 0.33.3 - '@img/sharp-linux-s390x': 0.33.3 - '@img/sharp-linux-x64': 0.33.3 - '@img/sharp-linuxmusl-arm64': 0.33.3 - '@img/sharp-linuxmusl-x64': 0.33.3 - '@img/sharp-wasm32': 0.33.3 - '@img/sharp-win32-ia32': 0.33.3 - '@img/sharp-win32-x64': 0.33.3 + '@img/sharp-linux-arm': 0.33.4 + '@img/sharp-linux-arm64': 0.33.4 + '@img/sharp-linux-s390x': 0.33.4 + '@img/sharp-linux-x64': 0.33.4 + '@img/sharp-linuxmusl-arm64': 0.33.4 + '@img/sharp-linuxmusl-x64': 0.33.4 + '@img/sharp-wasm32': 0.33.4 + '@img/sharp-win32-ia32': 0.33.4 + '@img/sharp-win32-x64': 0.33.4 shebang-command@2.0.0: dependencies: @@ -7784,7 +7539,7 @@ snapshots: signal-exit@4.1.0: {} - simple-icons@11.14.0: {} + simple-icons@11.15.0: {} simple-swizzle@0.2.2: dependencies: @@ -7794,16 +7549,6 @@ snapshots: slash@3.0.0: {} - slice-ansi@5.0.0: - dependencies: - ansi-styles: 6.2.1 - is-fullwidth-code-point: 4.0.0 - - slice-ansi@7.1.0: - dependencies: - ansi-styles: 6.2.1 - is-fullwidth-code-point: 5.0.0 - smol-toml@1.1.4: {} source-map-js@1.2.0: {} @@ -7831,8 +7576,6 @@ snapshots: streamsearch@1.1.0: {} - string-argv@0.3.2: {} - string-length@4.0.2: dependencies: char-regex: 1.0.2 @@ -7850,12 +7593,6 @@ snapshots: emoji-regex: 9.2.2 strip-ansi: 7.1.0 - string-width@7.1.0: - dependencies: - emoji-regex: 10.3.0 - get-east-asian-width: 1.2.0 - strip-ansi: 7.1.0 - string.fromcodepoint@0.2.1: {} string.prototype.trim@1.2.9: @@ -7898,8 +7635,6 @@ snapshots: strip-final-newline@2.0.0: {} - strip-final-newline@3.0.0: {} - strip-indent@3.0.0: dependencies: min-indent: 1.0.1 @@ -8056,12 +7791,12 @@ snapshots: is-typed-array: 1.1.13 possible-typed-array-names: 1.0.0 - typescript-eslint@7.9.0(eslint@9.2.0)(typescript@5.4.5): + typescript-eslint@7.9.0(eslint@9.3.0)(typescript@5.4.5): dependencies: - '@typescript-eslint/eslint-plugin': 7.9.0(@typescript-eslint/parser@7.9.0(eslint@9.2.0)(typescript@5.4.5))(eslint@9.2.0)(typescript@5.4.5) - '@typescript-eslint/parser': 7.9.0(eslint@9.2.0)(typescript@5.4.5) - '@typescript-eslint/utils': 7.9.0(eslint@9.2.0)(typescript@5.4.5) - eslint: 9.2.0 + '@typescript-eslint/eslint-plugin': 7.9.0(@typescript-eslint/parser@7.9.0(eslint@9.3.0)(typescript@5.4.5))(eslint@9.3.0)(typescript@5.4.5) + '@typescript-eslint/parser': 7.9.0(eslint@9.3.0)(typescript@5.4.5) + '@typescript-eslint/utils': 7.9.0(eslint@9.3.0)(typescript@5.4.5) + eslint: 9.3.0 optionalDependencies: typescript: 5.4.5 transitivePeerDependencies: @@ -8239,12 +7974,6 @@ snapshots: string-width: 5.1.2 strip-ansi: 7.1.0 - wrap-ansi@9.0.0: - dependencies: - ansi-styles: 6.2.1 - string-width: 7.1.0 - strip-ansi: 7.1.0 - wrappy@1.0.2: {} write-file-atomic@4.0.2: @@ -8266,8 +7995,6 @@ snapshots: yaml@1.10.2: {} - yaml@2.3.4: {} - yaml@2.4.2: {} yargs-parser@21.1.1: {} diff --git a/prettier.config.js b/prettier.config.js new file mode 100644 index 00000000..936c7d8d --- /dev/null +++ b/prettier.config.js @@ -0,0 +1,11 @@ +module.exports = { + importOrder: [ + '', + '', + '', + '^@/', + '^[.]', + ], + plugins: ['@ianvs/prettier-plugin-sort-imports'], + singleQuote: true, +}; diff --git a/src/components/Markdown/Markdown.tsx b/src/components/Markdown/Markdown.tsx index ad829229..b600cbd9 100644 --- a/src/components/Markdown/Markdown.tsx +++ b/src/components/Markdown/Markdown.tsx @@ -30,7 +30,6 @@ import { Youtube, } from '@/components/Markdown/renderers'; import { SpoilsCalculator } from '@/components/SpoilsCalculator/SpoilsCalculator'; -import { type Decklists } from '@/tools/decklists/types'; import { type Article, type Chapter, @@ -77,7 +76,6 @@ const COMPONENTS_EXTRA = { } as const; type Props = { - decklists: Decklists; markdown: Article | Chapter | Partial; /** Whether the component should scroll to the current anchor. */ withScroll?: boolean; @@ -85,7 +83,6 @@ type Props = { }; export const Markdown: FunctionComponent = ({ - decklists, markdown, withScroll = true, withWrapper = true, @@ -100,7 +97,7 @@ export const Markdown: FunctionComponent = ({ // NOTE Our own remarkers remarkBase, remarkCard, - [remarkDecklist, { decklists }], + [remarkDecklist, { decklists: markdown.decklists }], [remarkRow, { scries: markdown.scries }], ], } as const satisfies Record; diff --git a/src/components/Markdown/renderers/Decklist.tsx b/src/components/Markdown/renderers/Decklist.tsx index d264112d..368fefc5 100644 --- a/src/components/Markdown/renderers/Decklist.tsx +++ b/src/components/Markdown/renderers/Decklist.tsx @@ -25,7 +25,7 @@ export const Decklist: FunctionComponent = ({ decklist, node }) => { mainCount={decklist.mainCount} side={decklist.side[0] || []} sideCount={decklist.sideCount} - title={decklist.title || decklist.titleAsFile} + title={decklist.title || decklist.titleFromPath} /> ); }; diff --git a/src/pages/404.tsx b/src/pages/404.tsx index 94f9a810..49b6dc46 100644 --- a/src/pages/404.tsx +++ b/src/pages/404.tsx @@ -9,7 +9,7 @@ type Props = { menu: MenuEntry[]; }; -const NotFoundPage: NextPage = ({ menu }) => ( +const Page: NextPage = ({ menu }) => ( 404 @@ -23,4 +23,4 @@ export const getStaticProps: GetStaticProps = () => ({ }, }); -export default NotFoundPage; +export default Page; diff --git a/src/pages/[category]/[chapter].tsx b/src/pages/[category]/[chapter].tsx index 5f70d5c9..b2ad2a19 100644 --- a/src/pages/[category]/[chapter].tsx +++ b/src/pages/[category]/[chapter].tsx @@ -10,8 +10,6 @@ import { import { Banner } from '@/components/Banner/Banner'; import { Layout } from '@/components/Layout/Layout'; import { Markdown } from '@/components/Markdown/Markdown'; -import { getDecklists } from '@/tools/decklists/getDecklists'; -import { type Decklists } from '@/tools/decklists/types'; import { getChapterCards } from '@/tools/markdown/getChapterCards'; import { getChapter } from '@/tools/markdown/getMarkdown'; import { getMenu } from '@/tools/markdown/getMenu'; @@ -23,16 +21,15 @@ import { type Props = { chapter: Chapter; - decklists: Decklists; menu: MenuEntry[]; }; -const ChapterPage: NextPage = ({ chapter, decklists, menu }) => ( +const Page: NextPage = ({ chapter, menu }) => ( - + @@ -59,10 +56,9 @@ export const getStaticProps: GetStaticProps = async ({ return { props: { chapter: await getChapter(category, chapter), - decklists: getDecklists(), menu: getMenu(), }, }; }; -export default ChapterPage; +export default Page; diff --git a/src/pages/articles.tsx b/src/pages/articles.tsx index d2c79314..81a39c95 100644 --- a/src/pages/articles.tsx +++ b/src/pages/articles.tsx @@ -19,7 +19,7 @@ type Props = { menu: MenuEntry[]; }; -const ArticlesPage: NextPage = ({ articles, menu }) => ( +const Page: NextPage = ({ articles, menu }) => ( @@ -49,4 +49,4 @@ export const getStaticProps: GetStaticProps = async () => ({ }, }); -export default ArticlesPage; +export default Page; diff --git a/src/pages/articles/[year]/[month]/[day]/[article].tsx b/src/pages/articles/[year]/[month]/[day]/[article].tsx index 8cec7a25..3742370a 100644 --- a/src/pages/articles/[year]/[month]/[day]/[article].tsx +++ b/src/pages/articles/[year]/[month]/[day]/[article].tsx @@ -10,10 +10,8 @@ import { import { Banner } from '@/components/Banner/Banner'; import { Layout } from '@/components/Layout/Layout'; import { Markdown } from '@/components/Markdown/Markdown'; -import { getDecklists } from '@/tools/decklists/getDecklists'; -import { type Decklists } from '@/tools/decklists/types'; import { getArticleCards } from '@/tools/markdown/getArticleCards'; -import { getArticle, getPartial } from '@/tools/markdown/getMarkdown'; +import { getArticle, getMarkdown } from '@/tools/markdown/getMarkdown'; import { getMenu } from '@/tools/markdown/getMenu'; import { type Article, @@ -24,12 +22,11 @@ import { type Props = { article: Article; - decklists: Decklists; footer: Partial; menu: MenuEntry[]; }; -const ArticlePage: NextPage = ({ article, decklists, footer, menu }) => ( +const Page: NextPage = ({ article, footer, menu }) => ( = ({ article, decklists, footer, menu }) => ( title={article.matter.title} /> - + - + @@ -74,11 +71,10 @@ export const getStaticProps: GetStaticProps = async ({ return { props: { article: await getArticle(year, month, day, article), - decklists: getDecklists(), - footer: await getPartial('article-footer'), + footer: await getMarkdown('partials', 'article-footer.md'), menu: getMenu(), }, }; }; -export default ArticlePage; +export default Page; diff --git a/src/pages/index.tsx b/src/pages/index.tsx index ad84fab4..f7295d7b 100644 --- a/src/pages/index.tsx +++ b/src/pages/index.tsx @@ -5,10 +5,8 @@ import { useEffect, useRef, useState } from 'react'; import { ArticleCard } from '@/components/ArticleCard/ArticleCard'; import { Layout } from '@/components/Layout/Layout'; import { Markdown } from '@/components/Markdown/Markdown'; -import { getDecklists } from '@/tools/decklists/getDecklists'; -import { type Decklists } from '@/tools/decklists/types'; import { getArticleCards } from '@/tools/markdown/getArticleCards'; -import { getPartial } from '@/tools/markdown/getMarkdown'; +import { getMarkdown } from '@/tools/markdown/getMarkdown'; import { getMenu } from '@/tools/markdown/getMenu'; import { type ArticleCard as ArticleCardModel, @@ -20,12 +18,11 @@ const ARTICLES_INITIAL_SIZE = 5; type Props = { articles: ArticleCardModel[]; - decklists: Decklists; menu: MenuEntry[]; welcome: Partial; }; -const HomePage: NextPage = ({ articles, decklists, menu, welcome }) => { +const Page: NextPage = ({ articles, menu, welcome }) => { const articlesRoot = useRef(null); const [size, setSize] = useState(ARTICLES_INITIAL_SIZE); @@ -45,11 +42,11 @@ const HomePage: NextPage = ({ articles, decklists, menu, welcome }) => { return ( - - + + - + @@ -84,10 +81,9 @@ const HomePage: NextPage = ({ articles, decklists, menu, welcome }) => { export const getStaticProps: GetStaticProps = async () => ({ props: { articles: await getArticleCards(), - decklists: getDecklists(), menu: getMenu(), - welcome: await getPartial('welcome'), + welcome: await getMarkdown('partials', 'welcome.md'), }, }); -export default HomePage; +export default Page; diff --git a/src/pages/license.tsx b/src/pages/license.tsx index 0c1c375c..2a204986 100644 --- a/src/pages/license.tsx +++ b/src/pages/license.tsx @@ -3,26 +3,23 @@ import { type GetStaticProps, type NextPage } from 'next'; import { Layout } from '@/components/Layout/Layout'; import { Markdown } from '@/components/Markdown/Markdown'; -import { getDecklists } from '@/tools/decklists/getDecklists'; -import { type Decklists } from '@/tools/decklists/types'; -import { getPartial } from '@/tools/markdown/getMarkdown'; +import { getMarkdown } from '@/tools/markdown/getMarkdown'; import { getMenu } from '@/tools/markdown/getMenu'; import { type MenuEntry, type Partial } from '@/tools/markdown/types'; type Props = { - decklists: Decklists; license: Partial; menu: MenuEntry[]; }; -const LicensePage: NextPage = ({ decklists, license, menu }) => ( +const Page: NextPage = ({ license, menu }) => ( License - + @@ -30,10 +27,9 @@ const LicensePage: NextPage = ({ decklists, license, menu }) => ( export const getStaticProps: GetStaticProps = async () => ({ props: { - decklists: getDecklists(), - license: await getPartial('license'), + license: await getMarkdown('partials', 'license.md'), menu: getMenu(), }, }); -export default LicensePage; +export default Page; diff --git a/src/pages/sandbox/index.tsx b/src/pages/sandbox/index.tsx index 557ba97a..fa7cd93c 100644 --- a/src/pages/sandbox/index.tsx +++ b/src/pages/sandbox/index.tsx @@ -25,7 +25,7 @@ type Props = { menu: MenuEntry[]; }; -const SandboxPage: NextPage = ({ menu }) => { +const Page: NextPage = ({ menu }) => { const [input, setInput] = useState(DEFAULT_INPUT); const [output, setOutput] = useState<{ id: number; text: string }[]>([]); @@ -126,4 +126,4 @@ export const getStaticProps: GetStaticProps = async () => ({ }, }); -export default SandboxPage; +export default Page; diff --git a/src/pages/sandbox/markdown.tsx b/src/pages/sandbox/markdown.tsx index 2c8cda05..ddfef803 100644 --- a/src/pages/sandbox/markdown.tsx +++ b/src/pages/sandbox/markdown.tsx @@ -3,23 +3,20 @@ import { type GetStaticProps, type NextPage } from 'next'; import { Layout } from '@/components/Layout/Layout'; import { Markdown } from '@/components/Markdown/Markdown'; -import { getDecklists } from '@/tools/decklists/getDecklists'; -import { type Decklists } from '@/tools/decklists/types'; -import { getPartial } from '@/tools/markdown/getMarkdown'; +import { getMarkdown } from '@/tools/markdown/getMarkdown'; import { getMenu } from '@/tools/markdown/getMenu'; import { type MenuEntry, type Partial } from '@/tools/markdown/types'; type Props = { - decklists: Decklists; markdown: Partial; menu: MenuEntry[]; }; -const Page: NextPage = ({ decklists, markdown, menu }) => ( +const Page: NextPage = ({ markdown, menu }) => ( - + @@ -27,8 +24,7 @@ const Page: NextPage = ({ decklists, markdown, menu }) => ( export const getStaticProps: GetStaticProps = async () => ({ props: { - decklists: getDecklists(), - markdown: await getPartial('sandbox'), + markdown: await getMarkdown('partials', 'sandbox.md'), menu: getMenu(), }, }); diff --git a/src/tools/decklists/constants.ts b/src/tools/decklists/constants.ts index 070f2c16..c44fd767 100644 --- a/src/tools/decklists/constants.ts +++ b/src/tools/decklists/constants.ts @@ -1,11 +1,3 @@ -import { join } from 'node:path'; - -/** File extension to consider for decklist files. */ -export const DECKLISTS_EXTENSION = '.txt'; - -/** Base URL for decklists. */ -export const BASE_DECKLISTS_URL = join(process.cwd(), 'decklists'); - /** Collection of regular expression used to parse a decklist file. */ export const DECK_RE = { card: /(\d+) +(.+)\b */, diff --git a/src/tools/decklists/getDecklist.ts b/src/tools/decklists/getDecklist.ts new file mode 100644 index 00000000..3621ce7b --- /dev/null +++ b/src/tools/decklists/getDecklist.ts @@ -0,0 +1,18 @@ +import { readFileSync } from 'node:fs'; +import { join } from 'node:path'; + +import { parse } from '@/tools/decklists/parse'; +import { type Decklist, type DecklistExtra } from '@/tools/decklists/types'; +import { formatDate } from '@/tools/io/formatDate'; + +/** Base file URL for decklists. */ +const BASE_URL = join(process.cwd(), 'decklists'); + +/** Read decklist file found at the path crumbs. */ +export const getDecklist = (...crumbs: string[]): Decklist & DecklistExtra => { + const path = join(BASE_URL, ...crumbs) + '.txt'; + const decklist = parse(readFileSync(path, 'utf8')); + const [title, ...dateCrumbs] = crumbs.reverse(); + const date: null | string = formatDate(...dateCrumbs.reverse()); + return { ...decklist, date, titleFromPath: title as string }; +}; diff --git a/src/tools/decklists/getDecklists.ts b/src/tools/decklists/getDecklists.ts deleted file mode 100644 index a502b6ac..00000000 --- a/src/tools/decklists/getDecklists.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { readFileSync } from 'node:fs'; -import { join } from 'node:path'; -import { walk } from '@korumite/kiwi/server'; - -import { - BASE_DECKLISTS_URL, - DECKLISTS_EXTENSION, -} from '@/tools/decklists/constants'; -import { parse } from '@/tools/decklists/parse'; -import { type Decklists } from '@/tools/decklists/types'; -import { formatDate } from '@/tools/io/formatDate'; - -/** Read file system and return all decklists. */ -export const getDecklists = (): Decklists => { - const extension = DECKLISTS_EXTENSION; - const files = walk(BASE_DECKLISTS_URL, { extension }); - const decklists = files.reduce((accumulator, crumbs) => { - const slug = join(...crumbs); - const path = join(BASE_DECKLISTS_URL, slug) + extension; - const decklist = parse(readFileSync(path, 'utf8')); - const [title, ...dateCrumbs] = crumbs.reverse(); - const date: null | string = formatDate(...dateCrumbs.reverse()); - const titleAsFile = title as string; - return { ...accumulator, [slug]: { ...decklist, date, titleAsFile } }; - }, {}); - return decklists; -}; diff --git a/src/tools/decklists/types.ts b/src/tools/decklists/types.ts index aa8bdbdd..f31a3e47 100644 --- a/src/tools/decklists/types.ts +++ b/src/tools/decklists/types.ts @@ -12,7 +12,7 @@ export type Decklist = { export type DecklistExtra = { date: null | string; - titleAsFile: string; + titleFromPath: string; }; export type Decklists = Record; diff --git a/src/tools/markdown/constants/Files.ts b/src/tools/markdown/constants/Files.ts index 871ae484..351297e2 100644 --- a/src/tools/markdown/constants/Files.ts +++ b/src/tools/markdown/constants/Files.ts @@ -3,15 +3,13 @@ import { join } from 'node:path'; /** File extension to consider for Markdown content. */ export const MARKDOWN_EXTENSION = '.md'; -/** Base URL for Markdown content. */ -const BASE_MARKDOWN_URL = join(process.cwd(), 'markdown'); +/** Base file URL for Markdown content. */ +export const BASE_URL = join(process.cwd(), 'markdown'); -/** Base URLs for Markdown content. */ +/** Base file URLs for Markdown content categories. */ export const BASE_URLS = { /** Base URL for articles. */ - ARTICLE: join(BASE_MARKDOWN_URL, 'articles'), + ARTICLES: join(BASE_URL, 'articles'), /** Base URL for chapters. */ - CHAPTER: join(BASE_MARKDOWN_URL, 'chapters'), - /** Base URL for partials. */ - PARTIAL: join(BASE_MARKDOWN_URL, 'partials'), + CHAPTERS: join(BASE_URL, 'chapters'), } as const; diff --git a/src/tools/markdown/getArticleCards.ts b/src/tools/markdown/getArticleCards.ts index 131b7c0b..cd292be3 100644 --- a/src/tools/markdown/getArticleCards.ts +++ b/src/tools/markdown/getArticleCards.ts @@ -22,7 +22,7 @@ type ArticleCardPending = Omit & /** Read file system and return a list of all articles. */ export const getArticleCards = async (): Promise => { const extension = MARKDOWN_EXTENSION; - const files = walk(BASE_URLS.ARTICLE, { extension }); + const files = walk(BASE_URLS.ARTICLES, { extension }); /** Warmup array for banner promises. */ const banners: Promise[] = []; // NOTE Reduce rightwards to sort descending @@ -33,7 +33,7 @@ export const getArticleCards = async (): Promise => { const path = join(...crumbs) + extension; let matter: ArticleMatter; try { - matter = readArticleMatter(read(BASE_URLS.ARTICLE, path).matter); + matter = readArticleMatter(read(BASE_URLS.ARTICLES, path).matter); } catch (error) { const message = error instanceof Error ? error.message : `${error}`; throw new Error(`${message} in "${path}"`); diff --git a/src/tools/markdown/getChapterCards.ts b/src/tools/markdown/getChapterCards.ts index c5e30831..0e1eca48 100644 --- a/src/tools/markdown/getChapterCards.ts +++ b/src/tools/markdown/getChapterCards.ts @@ -12,7 +12,7 @@ import { assertCategory, assertDepth } from '@/tools/markdown/utilities'; /** Read file system and return a list of all chapters. */ export const getChapterCards = (): ChapterCard[] => { const extension = MARKDOWN_EXTENSION; - const files = walk(BASE_URLS.CHAPTER, { extension }); + const files = walk(BASE_URLS.CHAPTERS, { extension }); const cards = files.reduce((accumulator, crumbs) => { assertDepth(crumbs, 2); const [category, slug] = crumbs; @@ -20,7 +20,7 @@ export const getChapterCards = (): ChapterCard[] => { const path = join(...crumbs) + extension; let matter: ChapterMatter; try { - matter = readChapterMatter(read(BASE_URLS.CHAPTER, path).matter); + matter = readChapterMatter(read(BASE_URLS.CHAPTERS, path).matter); } catch (error) { const message = error instanceof Error ? error.message : `${error}`; throw new Error(`${message} in "${path}"`); diff --git a/src/tools/markdown/getMarkdown.ts b/src/tools/markdown/getMarkdown.ts index 8e4826f0..60bb4f26 100644 --- a/src/tools/markdown/getMarkdown.ts +++ b/src/tools/markdown/getMarkdown.ts @@ -1,13 +1,13 @@ import { readFileSync } from 'node:fs'; import { join } from 'node:path'; -import readingTime from 'reading-time'; import remarkDirective from 'remark-directive'; import remarkFrontmatter from 'remark-frontmatter'; import remarkParse from 'remark-parse'; import remarkStringify from 'remark-stringify'; import { unified } from 'unified'; -import { BASE_URLS } from '@/tools/markdown/constants/Files'; +import { type Decklists } from '@/tools/decklists/types'; +import { BASE_URL } from '@/tools/markdown/constants/Files'; import { getBanner } from '@/tools/markdown/getBanner'; import { readArticleMatter, @@ -18,25 +18,37 @@ import { type Chapter, type Partial, } from '@/tools/markdown/types'; +import { remarkDecklists } from '@/tools/remark/remarkDecklists.server'; +import { remarkMatter } from '@/tools/remark/remarkFrontmatter.server'; import { remarkMana } from '@/tools/remark/remarkMana.server'; +import { remarkMinutes } from '@/tools/remark/remarkMinutes.server'; import { remarkScries } from '@/tools/remark/remarkScries.server'; import { type Scries } from '@/tools/scryfall/types'; -import { remarkMatter } from '../remark/remarkFrontmatter.server'; -const getMarkdown = async (path: string): Promise => { - const buffer = readFileSync(path + '.md'); +/** + * Read the Markdown content found at the provided path crumbs. + * This does not handle the file extension and it has to be provided in the last + * crumb. The path is relative to the root of the project. + */ +export const getMarkdown = async (...crumbs: string[]): Promise => { + const path = join(...crumbs); + const buffer = readFileSync(join(BASE_URL, path)); try { const { data, value } = await unified() + .use(remarkDecklists) .use(remarkDirective) .use(remarkFrontmatter) .use(remarkMana) .use(remarkMatter) + .use(remarkMinutes) .use(remarkParse) .use(remarkScries) .use(remarkStringify) .process(buffer); return { + decklists: data.decklists as Decklists, matter: data.matter as Record, + minutes: data.minutes as number, scries: data.scries as Scries, text: String(value), }; @@ -50,13 +62,12 @@ const getMarkdown = async (path: string): Promise => { export const getArticle = async ( ...crumbs: [year: string, month: string, day: string, article: string] ): Promise
=> { - const path = join(BASE_URLS.ARTICLE, ...crumbs); + const path = join('articles', ...crumbs) + '.md'; const markdown = await getMarkdown(path); try { const matter = readArticleMatter(markdown.matter); const banner = await getBanner(matter.banner); - const minutes = readingTime(markdown.text).minutes; - return { ...markdown, banner, matter, minutes }; + return { ...markdown, banner, matter }; } catch (error) { const message = error instanceof Error ? error.message : `${error}`; throw new Error(`${message} in "${path}"`); @@ -67,7 +78,7 @@ export const getArticle = async ( export const getChapter = async ( ...crumbs: [category: string, chapter: string] ): Promise => { - const path = join(BASE_URLS.CHAPTER, ...crumbs); + const path = join('chapters', ...crumbs) + '.md'; const markdown = await getMarkdown(path); try { const matter = readChapterMatter(markdown.matter); @@ -78,7 +89,3 @@ export const getChapter = async ( throw new Error(`${message} in "${path}"`); } }; - -/** Convenience helper to read a partial. See `getMarkdown`. */ -export const getPartial = (path: string): Promise => - getMarkdown(join(BASE_URLS.PARTIAL, path)); diff --git a/src/tools/markdown/types.ts b/src/tools/markdown/types.ts index cb2e5a36..79d23953 100644 --- a/src/tools/markdown/types.ts +++ b/src/tools/markdown/types.ts @@ -1,3 +1,4 @@ +import { type Decklists } from '@/tools/decklists/types'; import { type Category } from '@/tools/markdown/constants/Category'; import { type Kind } from '@/tools/markdown/constants/Kind'; import { type Tag } from '@/tools/markdown/constants/Tag'; @@ -33,7 +34,9 @@ export type ChapterCard = Card & { // Documents /////////////////////////////////////////////////////////////////// export type Partial = { + decklists: Decklists; matter: Record; + minutes: number; scries: Scries; text: string; }; @@ -41,7 +44,6 @@ export type Partial = { export type Article = Omit & { banner: Banner; matter: ArticleMatter; - minutes: number; }; export type Chapter = Omit & { diff --git a/src/tools/remark/remarkBase.client.ts b/src/tools/remark/remarkBase.client.ts index 7daac1d8..1895e434 100644 --- a/src/tools/remark/remarkBase.client.ts +++ b/src/tools/remark/remarkBase.client.ts @@ -1,14 +1,13 @@ import { hastify } from '@korumite/kiwi/client'; import { type Directives } from 'mdast-util-directive'; -import { type Node } from 'unist'; -import { visit, type Test } from 'unist-util-visit'; +import { visit } from 'unist-util-visit'; import { type Remarker } from '@/tools/remark/typings'; /** Preliminary visit to mark directives by name for future remarkers. */ export const remarkBase: Remarker = () => (tree) => { const tests = ['containerDirective', 'leafDirective', 'textDirective']; - visit(tree, tests, (node) => { + visit(tree, tests, (node) => { const directive = node as Directives; hastify(directive, directive.attributes || {}); }); diff --git a/src/tools/remark/remarkCard.client.ts b/src/tools/remark/remarkCard.client.ts index 394a8dae..173188d3 100644 --- a/src/tools/remark/remarkCard.client.ts +++ b/src/tools/remark/remarkCard.client.ts @@ -1,9 +1,8 @@ import { hastify } from '@korumite/kiwi/client'; import { type Text } from 'mdast'; import { type TextDirective } from 'mdast-util-directive'; -import { type Node } from 'unist'; import { select } from 'unist-util-select'; -import { visit, type Test } from 'unist-util-visit'; +import { visit } from 'unist-util-visit'; import { getCard } from '@/tools/game/getCard'; import { type Remarker } from '@/tools/remark/typings'; @@ -11,7 +10,7 @@ import { type Remarker } from '@/tools/remark/typings'; /** Augment card directives with the real cards names. */ export const remarkCard: Remarker = () => (tree) => { const tests = [{ name: 'card', type: 'textDirective' }]; - visit(tree, tests, (node) => { + visit(tree, tests, (node) => { const directive = node as TextDirective; const text = select('text', directive) as Text | undefined; if (text) { diff --git a/src/tools/remark/remarkDecklist.client.ts b/src/tools/remark/remarkDecklist.client.ts index 5fb2d30c..43f0367a 100644 --- a/src/tools/remark/remarkDecklist.client.ts +++ b/src/tools/remark/remarkDecklist.client.ts @@ -1,7 +1,6 @@ import { hastify } from '@korumite/kiwi/client'; import { type LeafDirective } from 'mdast-util-directive'; -import { type Node } from 'unist'; -import { visit, type Test } from 'unist-util-visit'; +import { visit } from 'unist-util-visit'; import { type Decklists } from '@/tools/decklists/types'; import { type Remarker } from '@/tools/remark/typings'; @@ -11,7 +10,7 @@ export const remarkDecklist: Remarker<[{ decklists: Decklists }]> = ({ decklists }) => (tree) => { const tests = [{ name: 'decklist', type: 'leafDirective' }]; - visit(tree, tests, (node) => { + visit(tree, tests, (node) => { const directive = node as LeafDirective; const path = directive.attributes?.path; if (path) { diff --git a/src/tools/remark/remarkDecklists.server.ts b/src/tools/remark/remarkDecklists.server.ts new file mode 100644 index 00000000..c986861c --- /dev/null +++ b/src/tools/remark/remarkDecklists.server.ts @@ -0,0 +1,21 @@ +import { type LeafDirective } from 'mdast-util-directive'; +import { type Plugin } from 'unified'; +import { visit } from 'unist-util-visit'; + +import { getDecklist } from '@/tools/decklists/getDecklist'; +import { type Decklists } from '@/tools/decklists/types'; + +/** Augment the tree with decklists found. */ +export const remarkDecklists: Plugin = () => async (tree, file) => { + const tests = [{ name: 'decklist', type: 'leafDirective' }]; + const decklists: Decklists = {}; + visit(tree, tests, (node) => { + const directive = node as LeafDirective; + const path = directive.attributes?.path; + if (typeof path !== 'string') { + throw new Error(`Invalid path for decklist "${path}"`); + } + decklists[path] = getDecklist(...path.split('/')); + }); + Object.assign(file.data, { decklists }); +}; diff --git a/src/tools/remark/remarkMana.server.ts b/src/tools/remark/remarkMana.server.ts index fb46b98f..1dacef3f 100644 --- a/src/tools/remark/remarkMana.server.ts +++ b/src/tools/remark/remarkMana.server.ts @@ -5,7 +5,7 @@ import { type Plugin } from 'unified'; import { MANA_RE } from '@/tools/mana/constants'; -export const remarkMana: Plugin = () => async (tree) => { +export const remarkMana: Plugin = () => async (tree) => findAndReplace(tree as Nodes, [ MANA_RE, (_match, value) => @@ -16,4 +16,3 @@ export const remarkMana: Plugin = () => async (tree) => { type: 'textDirective', }) satisfies TextDirective, ]); -}; diff --git a/src/tools/remark/remarkMinutes.server.ts b/src/tools/remark/remarkMinutes.server.ts new file mode 100644 index 00000000..9f0a28dd --- /dev/null +++ b/src/tools/remark/remarkMinutes.server.ts @@ -0,0 +1,13 @@ +import readingTime from 'reading-time'; +import { type Plugin } from 'unified'; +import { type Literal } from 'unist'; +import { visit } from 'unist-util-visit'; + +export const remarkMinutes: Plugin = () => async (tree, file) => { + let text = ''; + visit(tree, 'text', (node) => { + text += (node as Literal).value; + }); + const { minutes } = readingTime(text); + Object.assign(file.data, { minutes }); +}; diff --git a/src/tools/remark/remarkRow.client.ts b/src/tools/remark/remarkRow.client.ts index def71b27..432f045f 100644 --- a/src/tools/remark/remarkRow.client.ts +++ b/src/tools/remark/remarkRow.client.ts @@ -1,9 +1,8 @@ import { hastify } from '@korumite/kiwi/client'; import { type Text } from 'mdast'; import { type ContainerDirective } from 'mdast-util-directive'; -import { type Node } from 'unist'; import { select } from 'unist-util-select'; -import { visit, type Test } from 'unist-util-visit'; +import { visit } from 'unist-util-visit'; import { type Remarker } from '@/tools/remark/typings'; import { type Scries } from '@/tools/scryfall/types'; @@ -13,7 +12,7 @@ export const remarkRow: Remarker<[{ scries: Scries }]> = ({ scries }) => (tree) => { const tests = [{ name: 'row', type: 'containerDirective' }]; - visit(tree, tests, (node) => { + visit(tree, tests, (node) => { const directive = node as ContainerDirective; const text = select('text', directive) as Text | undefined; if (text) { diff --git a/src/tools/remark/remarkScries.server.ts b/src/tools/remark/remarkScries.server.ts index ab9a9900..476002e3 100644 --- a/src/tools/remark/remarkScries.server.ts +++ b/src/tools/remark/remarkScries.server.ts @@ -1,9 +1,8 @@ import { type Text } from 'mdast'; import { type ContainerDirective } from 'mdast-util-directive'; import { type Plugin } from 'unified'; -import { type Node } from 'unist'; import { select } from 'unist-util-select'; -import { visit, type Test } from 'unist-util-visit'; +import { visit } from 'unist-util-visit'; import { readFaces } from '@/tools/scryfall/read'; import { scry } from '@/tools/scryfall/scry'; @@ -17,7 +16,7 @@ export const remarkScries: Plugin = () => async (tree, file) => { const promises: Promise[] = []; const scries: Scries = {}; const tests = [{ name: 'row', type: 'containerDirective' }]; - visit(tree, tests, (node) => { + visit(tree, tests, (node) => { const directive = node as ContainerDirective; const text = select('text', directive) as Text | undefined; if (!text) {