diff --git a/.editorconfig b/.editorconfig index bcb7b46..d47cf54 100644 --- a/.editorconfig +++ b/.editorconfig @@ -19,6 +19,9 @@ indent_style = tab indent_size = 4 indent_style = tab +[*.neon] +indent_style = tab + [*.xml] indent_style = tab diff --git a/.eslintignore b/.eslintignore deleted file mode 100644 index e25a32a..0000000 --- a/.eslintignore +++ /dev/null @@ -1,6 +0,0 @@ -.git/ -*.min.js -node_modules/ -symbolic/ -tmp/ -vendor/ diff --git a/.eslintrc.json b/.eslintrc.json deleted file mode 100644 index 449161c..0000000 --- a/.eslintrc.json +++ /dev/null @@ -1,29 +0,0 @@ -{ - "env": { - "browser": true - }, - "extends": [ - "eslint:recommended", - "standard" - ], - "rules": { - "camelcase": "off", - "comma-dangle": ["warn", { - "arrays": "always-multiline", - "objects": "always-multiline" - }], - "eqeqeq": "off", - "indent": ["warn", "tab", { "SwitchCase": 1 }], - "linebreak-style": ["error", "unix"], - "max-len": ["warn", 165], - "no-tabs": "off", - "semi": ["warn", "always"], - "space-before-function-paren": ["warn", { - "anonymous": "always", - "named": "never", - "asyncArrow": "always" - }], - "yoda": "off" - }, - "root": true -} diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..79603e5 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,25 @@ +# https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates + +version: 2 +updates: + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "monthly" + - package-ecosystem: "npm" + directory: "/" + schedule: + interval: "monthly" + groups: + eslint: + patterns: + - "*eslint*" + - "globals" + - "neostandard" + stylelint: + patterns: + - "*stylelint*" + - package-ecosystem: "composer" + directory: "/" + schedule: + interval: "monthly" diff --git a/.github/workflows/generate.yml b/.github/workflows/generate.yml index 3f70d3e..ef34e30 100644 --- a/.github/workflows/generate.yml +++ b/.github/workflows/generate.yml @@ -27,7 +27,7 @@ jobs: id: diff run: | DIFF=$(git diff --numstat -- $FILE | wc -l) - echo "::set-output name=DIFF::$DIFF" + echo "DIFF=$DIFF" >> $GITHUB_OUTPUT - name: Commit changes run: | diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index cfc5717..22c87a3 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -10,7 +10,7 @@ jobs: tests: # https://github.com/actions/virtual-environments - runs-on: ubuntu-22.04 + runs-on: ubuntu-24.04 defaults: run: working-directory: ./Extensions @@ -31,7 +31,7 @@ jobs: - name: Use Composer cache id: composer-cache - uses: actions/cache@v3 + uses: actions/cache@v4 with: path: Extensions/vendor key: ${{ runner.os }}-php-${{ hashFiles('**/composer.lock') }} @@ -54,18 +54,15 @@ jobs: - name: PHPStan run: composer run-script phpstan - - name: PHPStan Next Level - run: composer run-script phpstan-next - # NPM tests - name: Uses Node.js - uses: actions/setup-node@v3 + uses: actions/setup-node@v4 with: # https://nodejs.org/en/about/releases/ - node-version: '18' + node-version: '22' cache: 'npm' - cache-dependency-path: 'Extensions/composer.lock' + cache-dependency-path: 'Extensions/package-lock.json' - run: npm ci @@ -85,7 +82,7 @@ jobs: - name: Use shell cache id: shell-cache - uses: actions/cache@v3 + uses: actions/cache@v4 with: path: Extensions/bin key: ${{ runner.os }}-typos@v1.16.21 diff --git a/.gitignore b/.gitignore index ba24d9d..239c9a7 100644 --- a/.gitignore +++ b/.gitignore @@ -2,5 +2,6 @@ bin/ node_modules/ symbolic/ +third-party/ tmp/ vendor/ diff --git a/.jshintignore b/.jshintignore index 81fdc48..686db07 100644 --- a/.jshintignore +++ b/.jshintignore @@ -1,5 +1,6 @@ .git/ node_modules/ symbolic/ +third-party/ tmp/ vendor/ diff --git a/.markdownlint.json b/.markdownlint.json index c6961a7..0596513 100644 --- a/.markdownlint.json +++ b/.markdownlint.json @@ -6,11 +6,12 @@ "line-length": false, "no-hard-tabs": false, "no-inline-html": { - "allowed_elements": ["br", "kbd"] + "allowed_elements": ["br", "img", "kbd"] }, "no-multiple-blanks": { "maximum": 2 }, + "no-trailing-spaces": true, "ul-indent": false, "ul-style": { "style": "consistent" diff --git a/.markdownlintignore b/.markdownlintignore index 81fdc48..686db07 100644 --- a/.markdownlintignore +++ b/.markdownlintignore @@ -1,5 +1,6 @@ .git/ node_modules/ symbolic/ +third-party/ tmp/ vendor/ diff --git a/.stylelintignore b/.stylelintignore index 81fdc48..686db07 100644 --- a/.stylelintignore +++ b/.stylelintignore @@ -1,5 +1,6 @@ .git/ node_modules/ symbolic/ +third-party/ tmp/ vendor/ diff --git a/.stylelintrc.json b/.stylelintrc.json index 05d07ca..7005633 100644 --- a/.stylelintrc.json +++ b/.stylelintrc.json @@ -3,7 +3,7 @@ "plugins": [ "stylelint-order", "stylelint-scss", - "stylelint-stylistic" + "@stylistic/stylelint-plugin" ], "rules": { "at-rule-empty-line-before": [ @@ -11,27 +11,27 @@ "ignoreAtRules": [ "after-comment", "else" ] } ], - "stylistic/at-rule-name-space-after": [ + "@stylistic/at-rule-name-space-after": [ "always", { "ignoreAtRules": [ "after-comment" ] } ], - "stylistic/block-closing-brace-newline-after": [ + "@stylistic/block-closing-brace-newline-after": [ "always", { "ignoreAtRules": [ "if", "else" ] } ], - "stylistic/block-closing-brace-newline-before": "always-multi-line", - "stylistic/block-opening-brace-newline-after": "always-multi-line", - "stylistic/block-opening-brace-space-before": "always", - "stylistic/color-hex-case": "lower", + "@stylistic/block-closing-brace-newline-before": "always-multi-line", + "@stylistic/block-opening-brace-newline-after": "always-multi-line", + "@stylistic/block-opening-brace-space-before": "always", + "@stylistic/color-hex-case": "lower", "color-hex-length": "short", "color-no-invalid-hex": true, - "stylistic/declaration-colon-space-after": "always", - "stylistic/declaration-colon-space-before": "never", - "stylistic/indentation": "tab", + "@stylistic/declaration-colon-space-after": "always", + "@stylistic/declaration-colon-space-before": "never", + "@stylistic/indentation": "tab", "no-descending-specificity": null, - "stylistic/no-eol-whitespace": true, + "@stylistic/no-eol-whitespace": true, "property-no-vendor-prefix": true, "rule-empty-line-before": [ "always", { diff --git a/.typos.toml b/.typos.toml index 452d6a9..5a2e687 100644 --- a/.typos.toml +++ b/.typos.toml @@ -17,6 +17,7 @@ extend-exclude = [ "bin/", "node_modules/", "symbolic/", + "third-party/", "tmp/", "vendor/", "xExtension-ReadingTime/README.md" diff --git a/README.md b/README.md index 19c93fa..cf1ad87 100644 --- a/README.md +++ b/README.md @@ -6,15 +6,28 @@ To install an extension, download [the extension archive](https://github.com/Fre Then, upload the specific extension(s) you want on your server. Extensions must be in the `./extensions` directory of your FreshRSS installation. +## Commands for developers + +```sh +# Test this repository and its extensions +make test-all + +# Test compatibility between `../FreshRSS/` core and all known extensions from `./repositories.json` +./generate.php +composer run-script phpstan-third-party +``` + +## Core extensions + +*Custom CSS* and *Custom JS* are now a part of [core extensions shipped with FreshRSS](https://github.com/FreshRSS/FreshRSS/tree/edge/lib/core-extensions). + ## Third-party extensions There are some FreshRSS extensions out there, developed by community members: ### By [@kevinpapst](https://github.com/kevinpapst), [Web](https://www.kevinpapst.de/) -* [Dilbert](https://github.com/kevinpapst/freshrss-dilbert): Display your daily Dilbert comic in FreshRSS directly -* [Teem](https://github.com/kevinpapst/freshrss-teem): Display videos from the skydiving website jointheteem.com inline - +* [Youtube](xExtension-YouTube) shows YouTube videos inline in the feed ### By [@oYoX](https://github.com/oyox), [Web](https://oyox.de/) @@ -36,9 +49,9 @@ There are some FreshRSS extensions out there, developed by community members: * [Reddit Image](https://github.com/aledeg/FreshRSS-extensions/tree/master/xExtension-RedditImage): Replace link to Reddit topic with resource link -### By [@Lapineige](https://github.com/lapineige) +### By [@Lapineige](https://github.com/lapineige), [@hkcomori](https://github.com/hkcomori) -* [Reading Time](https://framagit.org/Lapineige/FreshRSS_Extension-ReadingTime): Add a reading time estimation next to each article. +* [Reading Time](https://github.com/FreshRSS/Extensions/tree/master/xExtension-ReadingTime): Add a reading time estimation next to each article. ### By [@Korbak](https://github.com/Korbak) @@ -47,9 +60,13 @@ There are some FreshRSS extensions out there, developed by community members: ### By [@CN-Tools](https://github.com/cn-tools) -* [YouTube Channel 2 RSSFeed](https://github.com/cn-tools/cntools_FreshRssExtensions/tree/master/xExtension-YouTubeChannel2RssFeed): You can add a YouTube Channel URL and will get it as RSSFeed -* [Feed Title Builder](https://github.com/cn-tools/cntools_FreshRssExtensions/tree/master/xExtension-FeedTitleBuilder): Build your own feed title based on url, the original feed title and the date the feed was added +* [Black List](https://github.com/cn-tools/cntools_FreshRssExtensions/tree/master/xExtension-BlackList): Blacklist to block feeds for users * [Copy 2 Clipboard](https://github.com/cn-tools/cntools_FreshRssExtensions/tree/master/xExtension-Copy2Clipboard): Add a button in the navigation bar to copy the destination links of all visible entries into clipboard +* [Feed Title Builder](https://github.com/cn-tools/cntools_FreshRssExtensions/tree/master/xExtension-FeedTitleBuilder): Build your own feed title based on url, the original feed title and the date the feed was added +* [FilterTitle](https://github.com/cn-tools/cntools_FreshRssExtensions/tree/master/xExtension-FilterTitle): Filter out feed entries by keywords parsed by the feed entry title +* [RemoveEmojis](https://github.com/cn-tools/cntools_FreshRssExtensions/tree/master/xExtension-RemoveEmojis): Remove emojis in the title of newly added feed entries +* [SendToMyJD2](https://github.com/cn-tools/cntools_FreshRssExtensions/tree/master/xExtension-SendToMyJD2): Send links to a jDownloader2 instance with the myJDownloader2 API +* [YouTube Channel 2 RSSFeed](https://github.com/cn-tools/cntools_FreshRssExtensions/tree/master/xExtension-YouTubeChannel2RssFeed): You can add a YouTube Channel URL and will get it as RSSFeed. Additional you can detect YouTube shorts. ### By [@DevonHess](https://github.com/DevonHess) @@ -71,6 +88,15 @@ There are some FreshRSS extensions out there, developed by community members: * [Pocket Button](https://github.com/christian-putzke/freshrss-pocket-button): Add articles to Pocket with one simple button click or a keyboard shortcut. +### By [@huffstler](https://github.com/huffstler) + +* [Star To Pocket](https://github.com/huffstler/xExtension-StarToPocket): Like the extension above, but sends articles to Pocket when they are starred. Also works with FreshRSS client applications! + +### By [@Joedmin](https://github.com/Joedmin/) + +* [Readeck Button](https://github.com/Joedmin/xExtension-readeck-button): Add articles to a selected Readeck instance with one simple button click or a keyboard shortcut. +* [Wallabag Button](https://github.com/Joedmin/xExtension-wallabag-button): Add articles to a selected Wallabag instance with one simple button click or a keyboard shortcut. + ### By [@printfuck](https://github.com/printfuck/) * [Readable](https://github.com/printfuck/xExtension-Readable): Fetch article content for selected feeds with [Readability](https://github.com/mozilla/readability) or [Mercury](https://github.com/postlight/mercury-parser) @@ -119,3 +145,27 @@ There are some FreshRSS extensions out there, developed by community members: ### By [@jacob2826](https://github.com/jacob2826) * [TranslateTitlesCN](https://github.com/jacob2826/FreshRSS-TranslateTitlesCN): Translate article titles of the specified feed into Chinese, using [DeepLX](https://github.com/OwO-Network/DeepLX) or Google Translate. + +### By [@kalvn](https://github.com/kalvn) + +* [Mark Previous as Read](https://github.com/kalvn/freshrss-mark-previous-as-read): Adds a button in the footer of each entry. Clicking this button will mark all previous entries belonging to the current feed, as read. + +### By [@lukasMega](https://github.com/lukasMega) + +* [Word Highlighter](https://github.com/lukasMega/Extensions-FreshRSS-): Gives you ability to highlight user-defined words (using [mark.js](https://github.com/julkue/mark.js)) + +### By [@LiangWei88](https://github.com/LiangWei88) + +* [ArticleSummary](https://github.com/LiangWei88/xExtension-ArticleSummary): A powerful article summarization plugin for FreshRSS that allows users to generate summaries using a language model API conforming to the OpenAI API specification. + +### By [@Niehztog](https://github.com/Niehztog) + +* [Article Full Text](https://github.com/Niehztog/freshrss-af-readability): Fetches full article contents and adds them to feed items by using [Fivefilters Readability.php library](https://github.com/fivefilters/readability.php) (no docker containers required). + +### By [@tryallthethings](https://github.com/tryallthethings) + +* [FreshVibes](https://github.com/tryallthethings/freshvibes): A fully customizable iGoogle / Netvibes-like dashboard view + +### By [@pe1uca](https://github.com/pe1uca) + +* [Rate limiter](https://github.com/pe1uca/xExtension-RateLimiter/): Prevents FreshRSS from making too many requests to the same site in a defined amount of time. diff --git a/composer.json b/composer.json index 9122289..daa8bee 100644 --- a/composer.json +++ b/composer.json @@ -17,7 +17,7 @@ "WebSub" ], "require": { - "php": ">=7.4", + "php": ">=8.1", "ext-ctype": "*", "ext-curl": "*", "ext-dom": "*", @@ -45,27 +45,26 @@ "ext-pdo_pgsql": "*" }, "require-dev": { - "php": ">=8.0", + "php": ">=8.1", "ext-phar": "*", "ext-tokenizer": "*", "ext-xmlwriter": "*", - "phpstan/phpstan": "^1.10", - "phpstan/phpstan-strict-rules": "^1.5", - "squizlabs/php_codesniffer": "^3.7" + "phpstan/phpstan": "^2", + "phpstan/phpstan-strict-rules": "^2", + "squizlabs/php_codesniffer": "^3" }, "scripts": { "php-lint": "find . -type d -name 'vendor' -prune -o -name '*.php' -print0 | xargs -0 -n1 -P4 php -l 1>/dev/null", "phtml-lint": "find . -type d -name 'vendor' -prune -o -name '*.phtml' -print0 | xargs -0 -n1 -P4 php -l 1>/dev/null", "phpcs": "phpcs . -s", "phpcbf": "phpcbf . -p -s", - "phpstan": "phpstan analyse --memory-limit 512M .", - "phpstan-next": "phpstan analyse --level 9 --memory-limit 512M $(find . -type d -name 'vendor' -prune -o -name '*.php' -o -name '*.phtml' | grep -Fxvf ./tests/phpstan-next.txt | sort | paste -s -)", + "phpstan": "phpstan analyse .", + "phpstan-third-party": "phpstan analyse -c phpstan-third-party.neon .", "test": [ "@php-lint", "@phtml-lint", "@phpcs", - "@phpstan", - "@phpstan-next" + "@phpstan" ], "fix": [ "@phpcbf" diff --git a/composer.lock b/composer.lock index 269ce71..1693453 100644 --- a/composer.lock +++ b/composer.lock @@ -4,25 +4,25 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "2c89b2e0c08f09d94faa394270fc16a9", + "content-hash": "02054632764558c26a4fbecc0e408c09", "packages": [], "packages-dev": [ { "name": "phpstan/phpstan", - "version": "1.10.44", + "version": "2.1.17", "source": { "type": "git", "url": "https://github.com/phpstan/phpstan.git", - "reference": "bf84367c53a23f759513985c54ffe0d0c249825b" + "reference": "89b5ef665716fa2a52ecd2633f21007a6a349053" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan/zipball/bf84367c53a23f759513985c54ffe0d0c249825b", - "reference": "bf84367c53a23f759513985c54ffe0d0c249825b", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/89b5ef665716fa2a52ecd2633f21007a6a349053", + "reference": "89b5ef665716fa2a52ecd2633f21007a6a349053", "shasum": "" }, "require": { - "php": "^7.2|^8.0" + "php": "^7.4|^8.0" }, "conflict": { "phpstan/phpstan-shim": "*" @@ -61,38 +61,33 @@ { "url": "https://github.com/phpstan", "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/phpstan/phpstan", - "type": "tidelift" } ], - "time": "2023-11-21T16:30:46+00:00" + "time": "2025-05-21T20:55:28+00:00" }, { "name": "phpstan/phpstan-strict-rules", - "version": "1.5.2", + "version": "2.0.4", "source": { "type": "git", "url": "https://github.com/phpstan/phpstan-strict-rules.git", - "reference": "7a50e9662ee9f3942e4aaaf3d603653f60282542" + "reference": "3e139cbe67fafa3588e1dbe27ca50f31fdb6236a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan-strict-rules/zipball/7a50e9662ee9f3942e4aaaf3d603653f60282542", - "reference": "7a50e9662ee9f3942e4aaaf3d603653f60282542", + "url": "https://api.github.com/repos/phpstan/phpstan-strict-rules/zipball/3e139cbe67fafa3588e1dbe27ca50f31fdb6236a", + "reference": "3e139cbe67fafa3588e1dbe27ca50f31fdb6236a", "shasum": "" }, "require": { - "php": "^7.2 || ^8.0", - "phpstan/phpstan": "^1.10.34" + "php": "^7.4 || ^8.0", + "phpstan/phpstan": "^2.0.4" }, "require-dev": { - "nikic/php-parser": "^4.13.0", "php-parallel-lint/php-parallel-lint": "^1.2", - "phpstan/phpstan-deprecation-rules": "^1.1", - "phpstan/phpstan-phpunit": "^1.0", - "phpunit/phpunit": "^9.5" + "phpstan/phpstan-deprecation-rules": "^2.0", + "phpstan/phpstan-phpunit": "^2.0", + "phpunit/phpunit": "^9.6" }, "type": "phpstan-extension", "extra": { @@ -114,22 +109,22 @@ "description": "Extra strict and opinionated rules for PHPStan", "support": { "issues": "https://github.com/phpstan/phpstan-strict-rules/issues", - "source": "https://github.com/phpstan/phpstan-strict-rules/tree/1.5.2" + "source": "https://github.com/phpstan/phpstan-strict-rules/tree/2.0.4" }, - "time": "2023-10-30T14:35:06+00:00" + "time": "2025-03-18T11:42:40+00:00" }, { "name": "squizlabs/php_codesniffer", - "version": "3.7.2", + "version": "3.13.2", "source": { "type": "git", - "url": "https://github.com/squizlabs/PHP_CodeSniffer.git", - "reference": "ed8e00df0a83aa96acf703f8c2979ff33341f879" + "url": "https://github.com/PHPCSStandards/PHP_CodeSniffer.git", + "reference": "5b5e3821314f947dd040c70f7992a64eac89025c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/ed8e00df0a83aa96acf703f8c2979ff33341f879", - "reference": "ed8e00df0a83aa96acf703f8c2979ff33341f879", + "url": "https://api.github.com/repos/PHPCSStandards/PHP_CodeSniffer/zipball/5b5e3821314f947dd040c70f7992a64eac89025c", + "reference": "5b5e3821314f947dd040c70f7992a64eac89025c", "shasum": "" }, "require": { @@ -139,11 +134,11 @@ "php": ">=5.4.0" }, "require-dev": { - "phpunit/phpunit": "^4.0 || ^5.0 || ^6.0 || ^7.0" + "phpunit/phpunit": "^4.0 || ^5.0 || ^6.0 || ^7.0 || ^8.0 || ^9.3.4" }, "bin": [ - "bin/phpcs", - "bin/phpcbf" + "bin/phpcbf", + "bin/phpcs" ], "type": "library", "extra": { @@ -158,22 +153,49 @@ "authors": [ { "name": "Greg Sherwood", - "role": "lead" + "role": "Former lead" + }, + { + "name": "Juliette Reinders Folmer", + "role": "Current lead" + }, + { + "name": "Contributors", + "homepage": "https://github.com/PHPCSStandards/PHP_CodeSniffer/graphs/contributors" } ], "description": "PHP_CodeSniffer tokenizes PHP, JavaScript and CSS files and detects violations of a defined set of coding standards.", - "homepage": "https://github.com/squizlabs/PHP_CodeSniffer", + "homepage": "https://github.com/PHPCSStandards/PHP_CodeSniffer", "keywords": [ "phpcs", "standards", "static analysis" ], "support": { - "issues": "https://github.com/squizlabs/PHP_CodeSniffer/issues", - "source": "https://github.com/squizlabs/PHP_CodeSniffer", - "wiki": "https://github.com/squizlabs/PHP_CodeSniffer/wiki" + "issues": "https://github.com/PHPCSStandards/PHP_CodeSniffer/issues", + "security": "https://github.com/PHPCSStandards/PHP_CodeSniffer/security/policy", + "source": "https://github.com/PHPCSStandards/PHP_CodeSniffer", + "wiki": "https://github.com/PHPCSStandards/PHP_CodeSniffer/wiki" }, - "time": "2023-02-22T23:07:41+00:00" + "funding": [ + { + "url": "https://github.com/PHPCSStandards", + "type": "github" + }, + { + "url": "https://github.com/jrfnl", + "type": "github" + }, + { + "url": "https://opencollective.com/php_codesniffer", + "type": "open_collective" + }, + { + "url": "https://thanks.dev/u/gh/phpcsstandards", + "type": "thanks_dev" + } + ], + "time": "2025-06-17T22:17:01+00:00" } ], "aliases": [], @@ -182,7 +204,7 @@ "prefer-stable": false, "prefer-lowest": false, "platform": { - "php": ">=7.4", + "php": ">=8.1", "ext-ctype": "*", "ext-curl": "*", "ext-dom": "*", @@ -205,10 +227,10 @@ "ext-zlib": "*" }, "platform-dev": { - "php": ">=8.0", + "php": ">=8.1", "ext-phar": "*", "ext-tokenizer": "*", "ext-xmlwriter": "*" }, - "plugin-api-version": "2.6.0" + "plugin-api-version": "2.3.0" } diff --git a/eslint.config.js b/eslint.config.js new file mode 100644 index 0000000..c65f752 --- /dev/null +++ b/eslint.config.js @@ -0,0 +1,55 @@ +import globals from "globals"; +import js from "@eslint/js"; +import neostandard, { resolveIgnoresFromGitignore } from 'neostandard'; +import stylistic from '@stylistic/eslint-plugin'; + +export default [ + { + files: ["**/*.js"], + languageOptions: { + globals: { + ...globals.browser, + }, + sourceType: "script", + }, + }, + { + ignores: [ + ...resolveIgnoresFromGitignore(), + "**/*.min.js", + "extensions/", + "p/scripts/vendor/", + ], + }, + js.configs.recommended, + // stylistic.configs['recommended-flat'], + ...neostandard(), + { + plugins: { + "@stylistic": stylistic, + }, + rules: { + "camelcase": "off", + "eqeqeq": "off", + "no-empty": ["error", { "allowEmptyCatch": true }], + "no-unused-vars": ["error", { + "args": "none", + "caughtErrors": "none", + }], + "object-shorthand": "off", + "yoda": "off", + "@stylistic/indent": ["warn", "tab", { "SwitchCase": 1 }], + "@stylistic/linebreak-style": ["error", "unix"], + "@stylistic/max-len": ["warn", 165], + "@stylistic/no-tabs": "off", + "@stylistic/quotes": ["off", "single", { "avoidEscape": true }], + "@stylistic/quote-props": ["warn", "consistent"], + "@stylistic/semi": ["warn", "always"], + "@stylistic/space-before-function-paren": ["warn", { + "anonymous": "always", + "asyncArrow": "always", + "named": "never", + }], + }, + }, +]; diff --git a/extensions.json b/extensions.json index dcf3d9a..4e1922a 100644 --- a/extensions.json +++ b/extensions.json @@ -1,22 +1,44 @@ { "version": 0.1, "extensions": [ + { + "name": "Af_Readability", + "author": "niehztog", + "description": "Try to inline article content using Readability", + "version": "0.1", + "entrypoint": "Af_Readability", + "type": "user", + "url": "https://github.com/Niehztog/freshrss-af-readability", + "method": "git", + "directory": "." + }, { "name": "Always togglable menu", "author": "nicofrand", "description": "This makes the icon to toggle the menu always shown, even on larger screens.", - "version": 1.2, + "version": "1.2", "entrypoint": "TogglableMenu", "type": "user", "url": "https://framagit.org/nicofrand/xextension-togglablemenu", "method": "git", "directory": "." }, + { + "name": "ArticleSummary", + "author": "Liang", + "description": "A powerful article summarization plugin for FreshRSS that allows users to generate summaries using a language model API conforming to the OpenAI API specification.", + "version": "0.1.2", + "entrypoint": "ArticleSummary", + "type": "user", + "url": "https://github.com/LiangWei88/xExtension-ArticleSummary", + "method": "git", + "directory": "." + }, { "name": "Auto Refresh", "author": "Essa AlAwadi", "description": "Automatically refreshes the RSS feed when there is no activity", - "version": 1.3, + "version": "1.3", "entrypoint": "AutoRefresh", "type": "user", "url": "https://github.com/Eisa01/FreshRSS---Auto-Refresh-Extension", @@ -27,7 +49,7 @@ "name": "AutoTTL", "author": "Magnus Kokk", "description": "A FreshRSS extension for automatic feed refresh TTL based on the average frequency of entries.", - "version": "0.4.1", + "version": "0.5.8", "entrypoint": "AutoTTL", "type": "user", "url": "https://github.com/mgnsk/FreshRSS-AutoTTL", @@ -38,7 +60,7 @@ "name": "Black List", "author": "CNTools | Clemens Neubauer", "description": "Blacklist to block feeds for users", - "version": "0.1-alpha", + "version": "0.0.1", "entrypoint": "BlackList", "type": "system", "url": "https://github.com/cn-tools/cntools_FreshRssExtensions", @@ -49,7 +71,7 @@ "name": "Clickable Links", "author": "Kapdap", "description": "Replaces non-clickable plain text URLs found in articles with clickable HTML links.", - "version": 1.01, + "version": "1.01", "entrypoint": "ClickableLink", "type": "user", "url": "https://github.com/kapdap/freshrss-extensions", @@ -60,7 +82,7 @@ "name": "Colorful List", "author": "Claud Xiao", "description": "Colorful Entry Title based on RSS source", - "version": 0.3, + "version": "0.3.2", "entrypoint": "ColorfulList", "type": "user", "url": "https://github.com/FreshRSS/Extensions", @@ -71,7 +93,7 @@ "name": "Comics in feed", "author": "José Moreira", "description": "Embed the images from comics feeds directly.", - "version": "1.1.0", + "version": "1.5.1", "entrypoint": "ComicsInFeed", "type": "system", "url": "https://github.com/giventofly/freshrss-comicsinfeed", @@ -82,35 +104,13 @@ "name": "Copy2Clipboard", "author": "CNTools | Clemens Neubauer", "description": "Copy the destination links of all visible entries into clipboard", - "version": 0.4, + "version": "0.4", "entrypoint": "Copy2Clipboard", "type": "user", "url": "https://github.com/cn-tools/cntools_FreshRssExtensions", "method": "git", "directory": "xExtension-Copy2Clipboard" }, - { - "name": "Custom CSS", - "author": "Marien Fressinaud", - "description": "Give possibility to overwrite the CSS with a user-specific rules.", - "version": "0.4", - "entrypoint": "CustomCSS", - "type": "user", - "url": "https://github.com/FreshRSS/Extensions", - "method": "git", - "directory": "xExtension-CustomCSS" - }, - { - "name": "Custom JS", - "author": "Frans de Jonge", - "description": "Apply custom JS.", - "version": "0.4", - "entrypoint": "CustomJS", - "type": "user", - "url": "https://github.com/FreshRSS/Extensions", - "method": "git", - "directory": "xExtension-CustomJS" - }, { "name": "Date Format", "author": "Alexis Degrugillier", @@ -122,17 +122,6 @@ "method": "git", "directory": "." }, - { - "name": "Dilberts Daily Comic", - "author": "Kevin Papst", - "description": "Embed the images from Dilberts daily feed inside article content.", - "version": "0.3.1", - "entrypoint": "Dilbert", - "type": "system", - "url": "https://github.com/kevinpapst/freshrss-dilbert", - "method": "git", - "directory": "xExtension-Dilbert" - }, { "name": "Feed Priority Shortcut", "author": "Aidi Stan", @@ -148,29 +137,51 @@ "name": "FeedTitleBuilder", "author": "CNTools | Clemens Neubauer", "description": "Build your own feed title based on url, the original feed title and the date the feed was added", - "version": 0.2, + "version": "0.2", "entrypoint": "FeedTitleBuilder", "type": "user", "url": "https://github.com/cn-tools/cntools_FreshRssExtensions", "method": "git", "directory": "xExtension-FeedTitleBuilder" }, + { + "name": "FilterTitle", + "author": "CNTools | Clemens Neubauer", + "description": "Filter feed entries by filter keywords in title", + "version": "0.1.0", + "entrypoint": "FilterTitle", + "type": "system", + "url": "https://github.com/cn-tools/cntools_FreshRssExtensions", + "method": "git", + "directory": "xExtension-FilterTitle" + }, { "name": "Fixed Nav Menu", "author": "Marco Heizmann", "description": "Sets the position of the navigation menu to fixed when scrolling down.", - "version": 0.1, + "version": "0.1", "entrypoint": "FixedNavMenu", "type": "user", "url": "https://github.com/oyox/FreshRSS-extensions", "method": "git", "directory": "xExtension-FixedNavMenu" }, + { + "name": "Fresh Vibes View", + "author": "Try all the things", + "description": "Provides a Netvibes-like dashboard view with draggable feed containers.", + "version": "1.8.6", + "entrypoint": "FreshVibesView", + "type": "user", + "url": "https://github.com/tryallthethings/freshvibes", + "method": "git", + "directory": "." + }, { "name": "FreshRss FlareSolverr", "author": "James Ravenscroft", "description": "Use a Flaresolverr instance to bypass cloudflare security checks", - "version": 0.1, + "version": "0.3", "entrypoint": "FlareSolverr", "type": "system", "url": "https://github.com/ravenscroftj/freshrss-flaresolverr-extension", @@ -181,7 +192,7 @@ "name": "GReader Redate", "author": "Julien Avérous", "description": "Use published date instead of fetching date.", - "version": 1.3, + "version": "1.3", "entrypoint": "GReaderRedate", "type": "user", "url": "https://github.com/javerous/freshrss-greader-redate", @@ -192,7 +203,7 @@ "name": "Image Cache", "author": "Victrid", "description": "Cache feed images on your own facility or Cloudflare cache.", - "version": 0.3, + "version": "0.4.1", "entrypoint": "ImageCache", "type": "user", "url": "https://github.com/Victrid/freshrss-image-cache-plugin", @@ -203,7 +214,7 @@ "name": "Image Proxy", "author": "Frans de Jonge", "description": "No insecure content warnings or disappearing images.", - "version": "0.6", + "version": "1.0", "entrypoint": "ImageProxy", "type": "user", "url": "https://github.com/FreshRSS/Extensions", @@ -214,18 +225,29 @@ "name": "Invidious Video Feed", "author": "Korbak (forked from Kevin Papst)", "description": "Embed YouTube feeds inside article content, but with Invidious.", - "version": 1.1, + "version": "1.1", "entrypoint": "Invidious", "type": "system", "url": "https://github.com/Korbak/freshrss-invidious", "method": "git", "directory": "xExtension-Invidious" }, + { + "name": "Invidious Video Feed", + "author": "Paul Tunbridge (forked from Korbak and Kevin Papst)", + "description": "Embed YouTube feeds inside article content, but with Invidious.", + "version": "1.1", + "entrypoint": "Invidious", + "type": "user", + "url": "https://github.com/tunbridgep/freshrss-invidious", + "method": "git", + "directory": "xExtension-Invidious" + }, { "name": "Kagi Summarizer", "author": "Rudis Muiznieks", "description": "Add buttons to summarize articles with the Kagi Universal Summarizer.", - "version": 0.2, + "version": "0.4", "entrypoint": "KagiSummarizer", "type": "user", "url": "https://code.sitosis.com/rudism/freshrss-kagi-summarizer", @@ -236,7 +258,7 @@ "name": "Keep Folder State", "author": "Marco Heizmann", "description": "Stores the state of the folders locally and expand them automatically if necessary.", - "version": 0.1, + "version": "0.1", "entrypoint": "KeepFolderState", "type": "user", "url": "https://github.com/oyox/FreshRSS-extensions", @@ -247,18 +269,29 @@ "name": "LaTeX support", "author": "Alexis Degrugillier", "description": "Add support for LaTeX notation rendering", - "version": "0.1.4", + "version": "0.1.5", "entrypoint": "LatexSupport", "type": "user", "url": "https://github.com/aledeg/xExtension-LatexSupport", "method": "git", "directory": "." }, + { + "name": "Mark Previous as Read", + "author": "kalvn", + "description": "This extension adds a button in the footer of each entry. Clicking this button will mark all previous entries as read.", + "version": "1.1.1", + "entrypoint": "MarkPreviousAsRead", + "type": "user", + "url": "https://github.com/kalvn/freshrss-mark-previous-as-read", + "method": "git", + "directory": "xExtension-MarkPreviousAsRead" + }, { "name": "Mobile Scroll Menu", "author": "Marco Heizmann", "description": "Automatically hides the header menu on mobile phones, when scrolling down and shows it when scrolling up.", - "version": 0.2, + "version": "0.2", "entrypoint": "MobileScrollMenu", "type": "user", "url": "https://github.com/oyox/FreshRSS-extensions", @@ -268,8 +301,8 @@ { "name": "News Assistant", "author": "Mervyn Zhan", - "description": "Use the api of `OpenAI` to summary the news.", - "version": 0.1, + "description": "Using the ai api of `OpenAI`, `Anthropic`, `Groq` by [Portkey-AI/gateway](https://github.com/Portkey-AI/gateway/) to summary the news.", + "version": "0.12.0", "entrypoint": "NewsAssistant", "type": "system", "url": "https://github.com/reply2future/xExtension-NewsAssistant", @@ -280,7 +313,7 @@ "name": "Pocket Button", "author": "Christian Putzke", "description": "Add articles to Pocket with one simple button click or a keyboard shortcut.", - "version": 0.4, + "version": "0.6", "entrypoint": "PocketButton", "type": "user", "url": "https://github.com/christian-putzke/freshrss-pocket-button", @@ -291,7 +324,7 @@ "name": "Quick Collapse", "author": "romibi and Marien Fressinaud", "description": "Quickly change from folded to unfolded articles", - "version": "0.2", + "version": "1.0.2", "entrypoint": "QuickCollapse", "type": "user", "url": "https://github.com/FreshRSS/Extensions", @@ -302,18 +335,29 @@ "name": "RSS-Bridge", "author": "Devon Hess", "description": "Run URLs through RSS-Bridge detection.", - "version": 1.1, + "version": "1.1", "entrypoint": "RssBridge", "type": "system", "url": "https://github.com/DevonHess/FreshRSS-Extensions", "method": "git", "directory": "xExtension-RssBridge" }, + { + "name": "RateLimitFeeds", + "author": "pe1uca", + "description": "Rate limit feed updates per site.", + "version": "3.2.0", + "entrypoint": "RateLimiter", + "type": "system", + "url": "https://github.com/pe1uca/xExtension-RateLimiter", + "method": "git", + "directory": "." + }, { "name": "Readable", "author": "printfuck", "description": "Fetch article content for selected feeds with readability or mercury", - "version": "0.2", + "version": "0.4", "entrypoint": "Readable", "type": "user", "url": "https://github.com/printfuck/xExtension-Readable", @@ -321,21 +365,21 @@ "directory": "." }, { - "name": "Reading Time", - "author": "Lapineige", - "description": "Add a reading time estimation next to each article title", - "version": 1.5, - "entrypoint": "ReadingTime", + "name": "Readeck Button", + "author": "Joedmin", + "description": "Add articles to Readeck with one simple button click or a keyboard shortcut.", + "version": "0.11", + "entrypoint": "ReadeckButton", "type": "user", - "url": "https://framagit.org/Lapineige/FreshRSS_Extension-ReadingTime/", + "url": "https://github.com/Joedmin/xExtension-readeck-button", "method": "git", "directory": "." }, { "name": "ReadingTime", - "author": "Lapineige", + "author": "Lapineige, hkcomori", "description": "Add a reading time estimation next to each article", - "version": "1.5", + "version": "1.6.1", "entrypoint": "ReadingTime", "type": "user", "url": "https://github.com/FreshRSS/Extensions", @@ -353,11 +397,33 @@ "method": "git", "directory": "." }, + { + "name": "Remove emojis", + "author": "CNTools | Clemens Neubauer", + "description": "remove emojis in the title of newly added feed entries", + "version": "0.1-dev", + "entrypoint": "RemoveEmojis", + "type": "user", + "url": "https://github.com/cn-tools/cntools_FreshRssExtensions", + "method": "git", + "directory": "xExtension-RemoveEmojis" + }, + { + "name": "SendToMyJD2", + "author": "CNTools | Clemens Neubauer", + "description": "Send links to a jDownloader2 instance with the myJDownloader2 API", + "version": "0.0.1-alpha", + "entrypoint": "SendToMyJD2", + "type": "user", + "url": "https://github.com/cn-tools/cntools_FreshRssExtensions", + "method": "git", + "directory": "xExtension-SendToMyJD2" + }, { "name": "Share By Email", "author": "Marien Fressinaud", "description": "Improve the sharing by email system.", - "version": "0.2.1", + "version": "0.3.3", "entrypoint": "ShareByEmail", "type": "user", "url": "https://github.com/FreshRSS/Extensions", @@ -366,9 +432,9 @@ }, { "name": "ShowFeedID", - "author": "math-GH", - "description": "Show the feed ID", - "version": "0.2", + "author": "math-GH, Inverle", + "description": "Show the ID of feed and category", + "version": "0.4.2", "entrypoint": "ShowFeedID", "type": "user", "url": "https://github.com/FreshRSS/Extensions", @@ -379,35 +445,35 @@ "name": "Smart Mobile Menu", "author": "Marco Heizmann", "description": "Minimizes the required button space and groups buttons.", - "version": 0.1, + "version": "0.1", "entrypoint": "SmartMobileMenu", "type": "user", "url": "https://github.com/oyox/FreshRSS-extensions", "method": "git", "directory": "xExtension-SmartMobileMenu" }, + { + "name": "StarToPocket", + "author": "Pat Hough", + "description": "An extension that sends an article to Pocket when you Star (Favorite) it.", + "version": "1", + "entrypoint": "StarToPocket", + "type": "user", + "url": "https://github.com/huffstler/xExtension-StarToPocket", + "method": "git", + "directory": "." + }, { "name": "Sticky Feeds", "author": "Marien Fressinaud", "description": "Set the feed aside in the main stream following the window scroll.", - "version": "0.2", + "version": "0.2.2", "entrypoint": "StickyFeeds", "type": "user", "url": "https://github.com/FreshRSS/Extensions", "method": "git", "directory": "xExtension-StickyFeeds" }, - { - "name": "Teem Video Feed", - "author": "Kevin Papst", - "description": "Embed video from JOINTHETEEM inside article content.", - "version": 0.1, - "entrypoint": "Teem", - "type": "system", - "url": "https://github.com/kevinpapst/freshrss-teem", - "method": "git", - "directory": "xExtension-Teem" - }, { "name": "Theme Mode Synchronizer", "author": "Aidi Stan", @@ -423,29 +489,18 @@ "name": "ThreePanesView", "author": "nicofrand", "description": "Adds a third vertical pane along the articles list, to display the articles content.", - "version": 1.14, + "version": "1.15", "entrypoint": "ThreePanesView", "type": "user", "url": "https://framagit.org/nicofrand/xextension-threepanesview", "method": "git", "directory": "." }, - { - "name": "TinyTinyRSS API", - "author": "Marien Fressinaud", - "description": "Provides an API compliant with TinyTinyRSS applications.", - "version": "0.1", - "entrypoint": "TTRSS_API", - "type": "system", - "url": "https://github.com/FreshRSS/Extensions", - "method": "git", - "directory": "xExtension-TTRSS_API" - }, { "name": "Title-Wrap", "author": "₣rans de Jonge, Joris Kinable", "description": "Applies a line-wrap to long article titles, as opposed to truncating the title when it overflows its display area.", - "version": "0.2", + "version": "0.3.1", "entrypoint": "TitleWrap", "type": "user", "url": "https://github.com/FreshRSS/Extensions", @@ -456,7 +511,7 @@ "name": "Touch Control", "author": "Marco Heizmann", "description": "Add touch gestures to FreshRSS.", - "version": 0.2, + "version": "0.2", "entrypoint": "TouchControl", "type": "user", "url": "https://github.com/oyox/FreshRSS-extensions", @@ -465,8 +520,8 @@ }, { "name": "TranslateTitlesCN", - "version": "0.2", - "description": "Translate article titles of the specified feed into Chinese, using DeepLX or Google Translate.", + "version": "0.3.1", + "description": "Translate article titles of the specified feed into Chinese.", "author": "jacob2826", "website": "https://github.com/jacob2826/FreshRSS-TranslateTitlesCN", "entrypoint": "TranslateTitles", @@ -479,13 +534,24 @@ "name": "TwitchChannel2RssFeed", "author": "Babico", "description": "Transfer Twitch Channel URL into RSS Feed URL.", - "version": 0.2, + "version": "0.2", "entrypoint": "TwitchChannel2RssFeed", "type": "user", "url": "https://github.com/babico/xExtension-TwitchChannel2RssFeed", "method": "git", "directory": "." }, + { + "name": "Wallabag Button", + "author": "Joedmin", + "description": "Add articles to Wallabag with one simple button click or a keyboard shortcut.", + "version": "0.5", + "entrypoint": "WallabagButton", + "type": "user", + "url": "https://github.com/Joedmin/xExtension-wallabag-button", + "method": "git", + "directory": "." + }, { "name": "White List", "author": "Alexis Degrugillier", @@ -498,21 +564,32 @@ "directory": "." }, { - "name": "YouTube/PeerTube Video Feed", + "name": "Word highlighter", + "author": "Lukas Melega", + "description": "Highlight specific words", + "version": "0.0.3", + "entrypoint": "WordHighlighter", + "type": "user", + "url": "https://github.com/FreshRSS/Extensions", + "method": "git", + "directory": "xExtension-WordHighlighter" + }, + { + "name": "YouTube Video Feed", "author": "Kevin Papst", - "description": "Embed YouTube/PeerTube feeds inside article content.", - "version": 0.1, + "description": "Embed YouTube feeds inside article content.", + "version": "0.13", "entrypoint": "YouTube", "type": "user", - "url": "https://github.com/kevinpapst/freshrss-youtube", + "url": "https://github.com/FreshRSS/Extensions", "method": "git", "directory": "xExtension-YouTube" }, { "name": "YouTubeChannel2RssFeed", "author": "CNTools | Clemens Neubauer", - "description": "Transfer YouTube Channel URL into RSS Feed URL.", - "version": 0.5, + "description": "Transfer YouTube URL into RSS Feed URL.", + "version": "0.6.1", "entrypoint": "YouTubeChannel2RssFeed", "type": "user", "url": "https://github.com/cn-tools/cntools_FreshRssExtensions", diff --git a/generate.php b/generate.php index 45819a3..5447066 100755 --- a/generate.php +++ b/generate.php @@ -6,11 +6,12 @@ // ------------------- // const VERSION = 0.1; const TYPE_GIT = 'git'; -$tempFolder = './tmp'; +$tempFolder = './third-party/'; $extensions = []; $gitRepositories = []; if (file_exists($tempFolder)) { + // TODO: Improve by keeping git copy if possible (e.g. fetch + reset) exec("rm -rf -- {$tempFolder}"); } @@ -28,7 +29,7 @@ try { } foreach ($repositories as $repository) { - if (null === $url = ($repository['url'] ?? null)) { + if (!is_array($repository) || !is_string($url = ($repository['url'] ?? null))) { continue; } if (TYPE_GIT === ($repository['type'] ?? null)) { @@ -53,6 +54,7 @@ foreach ($gitRepositories as $key => $gitRepository) { } $directory = basename(dirname($metadataFile)); $metadata['url'] = $gitRepository; + $metadata['version'] = is_scalar($metadata['version'] ?? null) ? strval($metadata['version']) : ''; $metadata['method'] = TYPE_GIT; $metadata['directory'] = ($directory === sha1($gitRepository)) ? '.' : $directory; $extensions[] = $metadata; diff --git a/package-lock.json b/package-lock.json index 38d0060..45772b3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -7,134 +7,54 @@ "name": "freshrss-extensions", "license": "see each extension", "devDependencies": { - "eslint": "^8.51.0", - "eslint-config-standard": "^17.1.0", - "eslint-plugin-import": "^2.28.1", - "eslint-plugin-n": "^16.0.1", - "eslint-plugin-promise": "^6.1.1", - "markdownlint-cli": "^0.37.0", - "rtlcss": "^4.1.1", - "sass": "^1.69.0", - "stylelint": "^15.10.3", - "stylelint-config-recommended-scss": "^13.1.0", - "stylelint-order": "^6.0.3", - "stylelint-stylistic": "^0.4.3" + "@eslint/js": "^9.8.0", + "@stylistic/stylelint-plugin": "^3.1.3", + "eslint": "^9.30.1", + "globals": "^16.3.0", + "markdownlint-cli": "^0.45.0", + "neostandard": "^0.12.1", + "rtlcss": "^4.3.0", + "sass": "^1.89.2", + "stylelint": "^16.21.0", + "stylelint-config-recommended-scss": "^15.0.1", + "stylelint-order": "^7.0.0" }, "engines": { - "node": ">=12" - } - }, - "node_modules/@aashutoshrathi/word-wrap": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz", - "integrity": "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==", - "dev": true, - "engines": { - "node": ">=0.10.0" + "node": ">=18" } }, "node_modules/@babel/code-frame": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.23.4.tgz", - "integrity": "sha512-r1IONyb6Ia+jYR2vvIDhdWdlTGhqbBoFqLTQidzZ4kepUFH15ejXvFHxCVbtl7BOXIudsIubf4E81xeA3h3IXA==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.7.tgz", + "integrity": "sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA==", "dev": true, "dependencies": { - "@babel/highlight": "^7.23.4", - "chalk": "^2.4.2" + "@babel/highlight": "^7.24.7", + "picocolors": "^1.0.0" }, "engines": { "node": ">=6.9.0" } }, - "node_modules/@babel/code-frame/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/code-frame/node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/code-frame/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/@babel/code-frame/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true - }, - "node_modules/@babel/code-frame/node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/@babel/code-frame/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/code-frame/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.22.20", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", - "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz", + "integrity": "sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==", "dev": true, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/highlight": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.23.4.tgz", - "integrity": "sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.7.tgz", + "integrity": "sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==", "dev": true, "dependencies": { - "@babel/helper-validator-identifier": "^7.22.20", + "@babel/helper-validator-identifier": "^7.24.7", "chalk": "^2.4.2", - "js-tokens": "^4.0.0" + "js-tokens": "^4.0.0", + "picocolors": "^1.0.0" }, "engines": { "node": ">=6.9.0" @@ -212,9 +132,9 @@ } }, "node_modules/@csstools/css-parser-algorithms": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/@csstools/css-parser-algorithms/-/css-parser-algorithms-2.3.2.tgz", - "integrity": "sha512-sLYGdAdEY2x7TSw9FtmdaTrh2wFtRJO5VMbBrA8tEqEod7GEggFmxTSK9XqExib3yMuYNcvcTdCZIP6ukdjAIA==", + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@csstools/css-parser-algorithms/-/css-parser-algorithms-3.0.5.tgz", + "integrity": "sha512-DaDeUkXZKjdGhgYaHNJTV9pV7Y9B3b644jCLs9Upc3VeNGg6LWARAT6O+Q+/COo+2gg/bM5rhpMAtf70WqfBdQ==", "dev": true, "funding": [ { @@ -227,16 +147,16 @@ } ], "engines": { - "node": "^14 || ^16 || >=18" + "node": ">=18" }, "peerDependencies": { - "@csstools/css-tokenizer": "^2.2.1" + "@csstools/css-tokenizer": "^3.0.4" } }, "node_modules/@csstools/css-tokenizer": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/@csstools/css-tokenizer/-/css-tokenizer-2.2.1.tgz", - "integrity": "sha512-Zmsf2f/CaEPWEVgw29odOj+WEVoiJy9s9NOv5GgNY9mZ1CZ7394By6wONrONrTsnNDv6F9hR02nvFihrGVGHBg==", + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@csstools/css-tokenizer/-/css-tokenizer-3.0.4.tgz", + "integrity": "sha512-Vd/9EVDiu6PPJt9yAh6roZP6El1xHrdvIVGjyBsHR0RYwNHgL7FJPyIIW4fANJNG6FtyZfvlRPpFI4ZM/lubvw==", "dev": true, "funding": [ { @@ -249,13 +169,13 @@ } ], "engines": { - "node": "^14 || ^16 || >=18" + "node": ">=18" } }, "node_modules/@csstools/media-query-list-parser": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@csstools/media-query-list-parser/-/media-query-list-parser-2.1.5.tgz", - "integrity": "sha512-IxVBdYzR8pYe89JiyXQuYk4aVVoCPhMJkz6ElRwlVysjwURTsTk/bmY/z4FfeRE+CRBMlykPwXEVUg8lThv7AQ==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@csstools/media-query-list-parser/-/media-query-list-parser-3.0.1.tgz", + "integrity": "sha512-HNo8gGD02kHmcbX6PvCoUuOQvn4szyB9ca63vZHKX5A81QytgDG4oxG4IaEfHTlEZSZ6MjPEMWIVU+zF2PZcgw==", "dev": true, "funding": [ { @@ -268,75 +188,46 @@ } ], "engines": { - "node": "^14 || ^16 || >=18" + "node": ">=18" }, "peerDependencies": { - "@csstools/css-parser-algorithms": "^2.3.2", - "@csstools/css-tokenizer": "^2.2.1" + "@csstools/css-parser-algorithms": "^3.0.1", + "@csstools/css-tokenizer": "^3.0.1" } }, - "node_modules/@csstools/selector-specificity": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@csstools/selector-specificity/-/selector-specificity-3.0.0.tgz", - "integrity": "sha512-hBI9tfBtuPIi885ZsZ32IMEU/5nlZH/KOVYJCOh7gyMxaVLGmLedYqFN6Ui1LXkI8JlC8IsuC0rF0btcRZKd5g==", + "node_modules/@dual-bundle/import-meta-resolve": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@dual-bundle/import-meta-resolve/-/import-meta-resolve-4.1.0.tgz", + "integrity": "sha512-+nxncfwHM5SgAtrVzgpzJOI1ol0PkumhVo469KCf9lUi21IGcY90G98VuHm9VRrUypmAzawAHO9bs6hqeADaVg==", "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "engines": { - "node": "^14 || ^16 || >=18" - }, - "peerDependencies": { - "postcss-selector-parser": "^6.0.13" + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" } }, "node_modules/@eslint-community/eslint-utils": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", - "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.1.tgz", + "integrity": "sha512-s3O3waFUrMV8P/XaF/+ZTp1X9XBZW1a4B97ZnjQF2KYWaFD2A8KyFBsrsfSjEmjn3RGWAIuvlneuZm3CUK3jbA==", "dev": true, "dependencies": { - "eslint-visitor-keys": "^3.3.0" + "eslint-visitor-keys": "^3.4.3" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, + "funding": { + "url": "https://opencollective.com/eslint" + }, "peerDependencies": { "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" } }, - "node_modules/@eslint-community/regexpp": { - "version": "4.10.0", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.10.0.tgz", - "integrity": "sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA==", + "node_modules/@eslint-community/eslint-utils/node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", "dev": true, - "engines": { - "node": "^12.0.0 || ^14.0.0 || >=16.0.0" - } - }, - "node_modules/@eslint/eslintrc": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.3.tgz", - "integrity": "sha512-yZzuIG+jnVu6hNSzFEN07e8BxF3uAzYtQb6uDkaYZLo6oYZDCq454c5kB8zxnzfCYyP4MIuyBn10L0DqwujTmA==", - "dev": true, - "dependencies": { - "ajv": "^6.12.4", - "debug": "^4.3.2", - "espree": "^9.6.0", - "globals": "^13.19.0", - "ignore": "^5.2.0", - "import-fresh": "^3.2.1", - "js-yaml": "^4.1.0", - "minimatch": "^3.1.2", - "strip-json-comments": "^3.1.1" - }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, @@ -344,27 +235,166 @@ "url": "https://opencollective.com/eslint" } }, - "node_modules/@eslint/js": { - "version": "8.54.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.54.0.tgz", - "integrity": "sha512-ut5V+D+fOoWPgGGNj83GGjnntO39xDy6DWxO0wb7Jp3DcMX0TfIqdzHF85VTQkerdyGmuuMD9AKAo5KiNlf/AQ==", + "node_modules/@eslint-community/regexpp": { + "version": "4.12.1", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.1.tgz", + "integrity": "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==", "dev": true, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" } }, - "node_modules/@humanwhocodes/config-array": { - "version": "0.11.13", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.13.tgz", - "integrity": "sha512-JSBDMiDKSzQVngfRjOdFXgFfklaXI4K9nLF49Auh21lmBWRLIK3+xTErTWD4KU54pb6coM6ESE7Awz/FNU3zgQ==", + "node_modules/@eslint/config-array": { + "version": "0.21.0", + "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.21.0.tgz", + "integrity": "sha512-ENIdc4iLu0d93HeYirvKmrzshzofPw6VkZRKQGe9Nv46ZnWUzcF1xV01dcvEg/1wXUR61OmmlSfyeyO7EvjLxQ==", "dev": true, "dependencies": { - "@humanwhocodes/object-schema": "^2.0.1", - "debug": "^4.1.1", - "minimatch": "^3.0.5" + "@eslint/object-schema": "^2.1.6", + "debug": "^4.3.1", + "minimatch": "^3.1.2" }, "engines": { - "node": ">=10.10.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/config-helpers": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.3.0.tgz", + "integrity": "sha512-ViuymvFmcJi04qdZeDc2whTHryouGcDlaxPqarTD0ZE10ISpxGUVZGZDx4w01upyIynL3iu6IXH2bS1NhclQMw==", + "dev": true, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/core": { + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.14.0.tgz", + "integrity": "sha512-qIbV0/JZr7iSDjqAc60IqbLdsj9GDt16xQtWD+B78d/HAlvysGdZZ6rpJHGAc2T0FQx1X6thsSPdnoiGKdNtdg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@types/json-schema": "^7.0.15" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.1.tgz", + "integrity": "sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^10.0.1", + "globals": "^14.0.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint/eslintrc/node_modules/globals": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", + "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@eslint/js": { + "version": "9.30.1", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.30.1.tgz", + "integrity": "sha512-zXhuECFlyep42KZUhWjfvsmXGX39W8K8LFb8AWXM9gSV9dQB+MrJGLKvW6Zw0Ggnbpw0VHTtrhFXYe3Gym18jg==", + "dev": true, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://eslint.org/donate" + } + }, + "node_modules/@eslint/object-schema": { + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.6.tgz", + "integrity": "sha512-RBMg5FRL0I0gs51M/guSAj5/e14VQ4tpZnQNWwuDT66P14I43ItmPfIZRhO9fUVIPOAQXU47atlywZ/czoqFPA==", + "dev": true, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/plugin-kit": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.3.1.tgz", + "integrity": "sha512-0J+zgWxHN+xXONWIyPWKFMgVuJoZuGiIFu8yxk7RJjxkzpGmyja5wRFqZIVtjDVOQpV+Rw0iOAjYPE2eQyjr0w==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/core": "^0.14.0", + "levn": "^0.4.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@humanfs/core": { + "version": "0.19.1", + "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz", + "integrity": "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==", + "dev": true, + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanfs/node": { + "version": "0.16.6", + "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.6.tgz", + "integrity": "sha512-YuI2ZHQL78Q5HbhDiBA1X4LmYdXCKCMQIfw0pw7piHJwyREFebJUvrQN4cMssyES6x+vfUbx1CIpaQUKYdQZOw==", + "dev": true, + "dependencies": { + "@humanfs/core": "^0.19.1", + "@humanwhocodes/retry": "^0.3.0" + }, + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanfs/node/node_modules/@humanwhocodes/retry": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.3.1.tgz", + "integrity": "sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==", + "dev": true, + "engines": { + "node": ">=18.18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/gitignore-to-minimatch": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@humanwhocodes/gitignore-to-minimatch/-/gitignore-to-minimatch-1.0.2.tgz", + "integrity": "sha512-rSqmMJDdLFUsyxR6FMtD00nfQKKLFb1kv+qBbOVKqErvloEIJLo5bDTJTQNTYgeyp78JsA7u/NPi5jT1GR/MuA==", + "dev": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" } }, "node_modules/@humanwhocodes/module-importer": { @@ -380,17 +410,26 @@ "url": "https://github.com/sponsors/nzakas" } }, - "node_modules/@humanwhocodes/object-schema": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.1.tgz", - "integrity": "sha512-dvuCeX5fC9dXgJn9t+X5atfmgQAzUOWqS1254Gh0m6i8wKd10ebXkfNKiRK+1GWi/yTvvLDHpoxLr0xxxeslWw==", - "dev": true + "node_modules/@humanwhocodes/retry": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.2.tgz", + "integrity": "sha512-xeO57FpIu4p1Ri3Jq/EXq4ClRm86dVF2z/+kvFnyqVYRavTZmaFaUBbWCOuuTh0o/g7DSsk6kc2vrS4Vl5oPOQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } }, "node_modules/@isaacs/cliui": { "version": "8.0.2", "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", "dev": true, + "license": "ISC", "dependencies": { "string-width": "^5.1.2", "string-width-cjs": "npm:string-width@^4.2.0", @@ -404,10 +443,11 @@ } }, "node_modules/@isaacs/cliui/node_modules/ansi-regex": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", - "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", + "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", "dev": true, + "license": "MIT", "engines": { "node": ">=12" }, @@ -420,6 +460,7 @@ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", "dev": true, + "license": "MIT", "dependencies": { "ansi-regex": "^6.0.1" }, @@ -430,6 +471,15 @@ "url": "https://github.com/chalk/strip-ansi?sponsor=1" } }, + "node_modules/@keyv/serialize": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@keyv/serialize/-/serialize-1.0.3.tgz", + "integrity": "sha512-qnEovoOp5Np2JDGonIDL6Ayihw0RhnRh6vxPuHo4RDn1UOzwEo4AeIfpL6UGIrsceWrCMiVPgwRjbHu4vYFc3g==", + "dev": true, + "dependencies": { + "buffer": "^6.0.3" + } + }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -465,44 +515,602 @@ "node": ">= 8" } }, - "node_modules/@pkgjs/parseargs": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", - "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "node_modules/@nolyfill/is-core-module": { + "version": "1.0.39", + "resolved": "https://registry.npmjs.org/@nolyfill/is-core-module/-/is-core-module-1.0.39.tgz", + "integrity": "sha512-nn5ozdjYQpUCZlWGuxcJY/KpxkWQs4DcbMCmKojjyrYDEAGy4Ce19NN4v5MduafTwJlbKc99UA8YhSVqq9yPZA==", "dev": true, - "optional": true, "engines": { - "node": ">=14" + "node": ">=12.4.0" } }, - "node_modules/@types/json5": { - "version": "0.0.29", - "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", - "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", + "node_modules/@parcel/watcher": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher/-/watcher-2.5.0.tgz", + "integrity": "sha512-i0GV1yJnm2n3Yq1qw6QrUrd/LI9bE8WEBOTtOkpCXHHdyN3TAGgqAK/DAT05z4fq2x04cARXt2pDmjWjL92iTQ==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "dependencies": { + "detect-libc": "^1.0.3", + "is-glob": "^4.0.3", + "micromatch": "^4.0.5", + "node-addon-api": "^7.0.0" + }, + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + }, + "optionalDependencies": { + "@parcel/watcher-android-arm64": "2.5.0", + "@parcel/watcher-darwin-arm64": "2.5.0", + "@parcel/watcher-darwin-x64": "2.5.0", + "@parcel/watcher-freebsd-x64": "2.5.0", + "@parcel/watcher-linux-arm-glibc": "2.5.0", + "@parcel/watcher-linux-arm-musl": "2.5.0", + "@parcel/watcher-linux-arm64-glibc": "2.5.0", + "@parcel/watcher-linux-arm64-musl": "2.5.0", + "@parcel/watcher-linux-x64-glibc": "2.5.0", + "@parcel/watcher-linux-x64-musl": "2.5.0", + "@parcel/watcher-win32-arm64": "2.5.0", + "@parcel/watcher-win32-ia32": "2.5.0", + "@parcel/watcher-win32-x64": "2.5.0" + } + }, + "node_modules/@parcel/watcher-android-arm64": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher-android-arm64/-/watcher-android-arm64-2.5.0.tgz", + "integrity": "sha512-qlX4eS28bUcQCdribHkg/herLe+0A9RyYC+mm2PXpncit8z5b3nSqGVzMNR3CmtAOgRutiZ02eIJJgP/b1iEFQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-darwin-arm64": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-arm64/-/watcher-darwin-arm64-2.5.0.tgz", + "integrity": "sha512-hyZ3TANnzGfLpRA2s/4U1kbw2ZI4qGxaRJbBH2DCSREFfubMswheh8TeiC1sGZ3z2jUf3s37P0BBlrD3sjVTUw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-darwin-x64": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-x64/-/watcher-darwin-x64-2.5.0.tgz", + "integrity": "sha512-9rhlwd78saKf18fT869/poydQK8YqlU26TMiNg7AIu7eBp9adqbJZqmdFOsbZ5cnLp5XvRo9wcFmNHgHdWaGYA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-freebsd-x64": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher-freebsd-x64/-/watcher-freebsd-x64-2.5.0.tgz", + "integrity": "sha512-syvfhZzyM8kErg3VF0xpV8dixJ+RzbUaaGaeb7uDuz0D3FK97/mZ5AJQ3XNnDsXX7KkFNtyQyFrXZzQIcN49Tw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-arm-glibc": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-glibc/-/watcher-linux-arm-glibc-2.5.0.tgz", + "integrity": "sha512-0VQY1K35DQET3dVYWpOaPFecqOT9dbuCfzjxoQyif1Wc574t3kOSkKevULddcR9znz1TcklCE7Ht6NIxjvTqLA==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-arm-musl": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-musl/-/watcher-linux-arm-musl-2.5.0.tgz", + "integrity": "sha512-6uHywSIzz8+vi2lAzFeltnYbdHsDm3iIB57d4g5oaB9vKwjb6N6dRIgZMujw4nm5r6v9/BQH0noq6DzHrqr2pA==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-arm64-glibc": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-glibc/-/watcher-linux-arm64-glibc-2.5.0.tgz", + "integrity": "sha512-BfNjXwZKxBy4WibDb/LDCriWSKLz+jJRL3cM/DllnHH5QUyoiUNEp3GmL80ZqxeumoADfCCP19+qiYiC8gUBjA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-arm64-musl": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-musl/-/watcher-linux-arm64-musl-2.5.0.tgz", + "integrity": "sha512-S1qARKOphxfiBEkwLUbHjCY9BWPdWnW9j7f7Hb2jPplu8UZ3nes7zpPOW9bkLbHRvWM0WDTsjdOTUgW0xLBN1Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-x64-glibc": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-glibc/-/watcher-linux-x64-glibc-2.5.0.tgz", + "integrity": "sha512-d9AOkusyXARkFD66S6zlGXyzx5RvY+chTP9Jp0ypSTC9d4lzyRs9ovGf/80VCxjKddcUvnsGwCHWuF2EoPgWjw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-x64-musl": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-musl/-/watcher-linux-x64-musl-2.5.0.tgz", + "integrity": "sha512-iqOC+GoTDoFyk/VYSFHwjHhYrk8bljW6zOhPuhi5t9ulqiYq1togGJB5e3PwYVFFfeVgc6pbz3JdQyDoBszVaA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-win32-arm64": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-arm64/-/watcher-win32-arm64-2.5.0.tgz", + "integrity": "sha512-twtft1d+JRNkM5YbmexfcH/N4znDtjgysFaV9zvZmmJezQsKpkfLYJ+JFV3uygugK6AtIM2oADPkB2AdhBrNig==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-win32-ia32": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-ia32/-/watcher-win32-ia32-2.5.0.tgz", + "integrity": "sha512-+rgpsNRKwo8A53elqbbHXdOMtY/tAtTzManTWShB5Kk54N8Q9mzNWV7tV+IbGueCbcj826MfWGU3mprWtuf1TA==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-win32-x64": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-x64/-/watcher-win32-x64-2.5.0.tgz", + "integrity": "sha512-lPrxve92zEHdgeff3aiu4gDOIt4u7sJYha6wbdEZDCDUhtjTsOMiaJzG5lMY4GkWH8p0fMmO2Ppq5G5XXG+DQw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@stylistic/eslint-plugin": { + "version": "2.11.0", + "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin/-/eslint-plugin-2.11.0.tgz", + "integrity": "sha512-PNRHbydNG5EH8NK4c+izdJlxajIR6GxcUhzsYNRsn6Myep4dsZt0qFCz3rCPnkvgO5FYibDcMqgNHUT+zvjYZw==", + "dev": true, + "dependencies": { + "@typescript-eslint/utils": "^8.13.0", + "eslint-visitor-keys": "^4.2.0", + "espree": "^10.3.0", + "estraverse": "^5.3.0", + "picomatch": "^4.0.2" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "peerDependencies": { + "eslint": ">=8.40.0" + } + }, + "node_modules/@stylistic/stylelint-plugin": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/@stylistic/stylelint-plugin/-/stylelint-plugin-3.1.3.tgz", + "integrity": "sha512-85fsmzgsIVmyG3/GFrjuYj6Cz8rAM7IZiPiXCMiSMfoDOC1lOrzrXPDk24WqviAghnPqGpx8b0caK2PuewWGFg==", + "dev": true, + "dependencies": { + "@csstools/css-parser-algorithms": "^3.0.1", + "@csstools/css-tokenizer": "^3.0.1", + "@csstools/media-query-list-parser": "^3.0.1", + "is-plain-object": "^5.0.0", + "postcss": "^8.4.41", + "postcss-selector-parser": "^6.1.2", + "postcss-value-parser": "^4.2.0", + "style-search": "^0.1.0" + }, + "engines": { + "node": "^18.12 || >=20.9" + }, + "peerDependencies": { + "stylelint": "^16.8.0" + } + }, + "node_modules/@types/debug": { + "version": "4.1.12", + "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.12.tgz", + "integrity": "sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/ms": "*" + } + }, + "node_modules/@types/doctrine": { + "version": "0.0.9", + "resolved": "https://registry.npmjs.org/@types/doctrine/-/doctrine-0.0.9.tgz", + "integrity": "sha512-eOIHzCUSH7SMfonMG1LsC2f8vxBFtho6NGBznK41R84YzPuvSBzrhEps33IsQiOW9+VL6NQ9DbjQJznk/S4uRA==", "dev": true }, - "node_modules/@types/minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-hov8bUuiLiyFPGyFPE1lwWhmzYbirOXQNNo40+y3zow8aFVTeyn3VWL0VFFfdNddA8S4Vf0Tc062rzyNr7Paag==", + "node_modules/@types/estree": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz", + "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==", "dev": true }, - "node_modules/@types/normalize-package-data": { - "version": "2.4.4", - "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.4.tgz", - "integrity": "sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==", - "dev": true + "node_modules/@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "dev": true, + "license": "MIT" }, - "node_modules/@ungap/structured-clone": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", - "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", - "dev": true + "node_modules/@types/katex": { + "version": "0.16.7", + "resolved": "https://registry.npmjs.org/@types/katex/-/katex-0.16.7.tgz", + "integrity": "sha512-HMwFiRujE5PjrgwHQ25+bsLJgowjGjm5Z8FVSf0N6PwgJrwxH0QxzHYDcKsTfV3wva0vzrpqMTJS2jXPr5BMEQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/ms": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@types/ms/-/ms-2.1.0.tgz", + "integrity": "sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/unist": { + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.11.tgz", + "integrity": "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "8.20.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.20.0.tgz", + "integrity": "sha512-naduuphVw5StFfqp4Gq4WhIBE2gN1GEmMUExpJYknZJdRnc+2gDzB8Z3+5+/Kv33hPQRDGzQO/0opHE72lZZ6A==", + "dev": true, + "dependencies": { + "@eslint-community/regexpp": "^4.10.0", + "@typescript-eslint/scope-manager": "8.20.0", + "@typescript-eslint/type-utils": "8.20.0", + "@typescript-eslint/utils": "8.20.0", + "@typescript-eslint/visitor-keys": "8.20.0", + "graphemer": "^1.4.0", + "ignore": "^5.3.1", + "natural-compare": "^1.4.0", + "ts-api-utils": "^2.0.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^8.0.0 || ^8.0.0-alpha.0", + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <5.8.0" + } + }, + "node_modules/@typescript-eslint/parser": { + "version": "8.20.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.20.0.tgz", + "integrity": "sha512-gKXG7A5HMyjDIedBi6bUrDcun8GIjnI8qOwVLiY3rx6T/sHP/19XLJOnIq/FgQvWLHja5JN/LSE7eklNBr612g==", + "dev": true, + "dependencies": { + "@typescript-eslint/scope-manager": "8.20.0", + "@typescript-eslint/types": "8.20.0", + "@typescript-eslint/typescript-estree": "8.20.0", + "@typescript-eslint/visitor-keys": "8.20.0", + "debug": "^4.3.4" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <5.8.0" + } + }, + "node_modules/@typescript-eslint/scope-manager": { + "version": "8.20.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.20.0.tgz", + "integrity": "sha512-J7+VkpeGzhOt3FeG1+SzhiMj9NzGD/M6KoGn9f4dbz3YzK9hvbhVTmLj/HiTp9DazIzJ8B4XcM80LrR9Dm1rJw==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "8.20.0", + "@typescript-eslint/visitor-keys": "8.20.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/type-utils": { + "version": "8.20.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.20.0.tgz", + "integrity": "sha512-bPC+j71GGvA7rVNAHAtOjbVXbLN5PkwqMvy1cwGeaxUoRQXVuKCebRoLzm+IPW/NtFFpstn1ummSIasD5t60GA==", + "dev": true, + "dependencies": { + "@typescript-eslint/typescript-estree": "8.20.0", + "@typescript-eslint/utils": "8.20.0", + "debug": "^4.3.4", + "ts-api-utils": "^2.0.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <5.8.0" + } + }, + "node_modules/@typescript-eslint/types": { + "version": "8.20.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.20.0.tgz", + "integrity": "sha512-cqaMiY72CkP+2xZRrFt3ExRBu0WmVitN/rYPZErA80mHjHx/Svgp8yfbzkJmDoQ/whcytOPO9/IZXnOc+wigRA==", + "dev": true, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/typescript-estree": { + "version": "8.20.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.20.0.tgz", + "integrity": "sha512-Y7ncuy78bJqHI35NwzWol8E0X7XkRVS4K4P4TCyzWkOJih5NDvtoRDW4Ba9YJJoB2igm9yXDdYI/+fkiiAxPzA==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "8.20.0", + "@typescript-eslint/visitor-keys": "8.20.0", + "debug": "^4.3.4", + "fast-glob": "^3.3.2", + "is-glob": "^4.0.3", + "minimatch": "^9.0.4", + "semver": "^7.6.0", + "ts-api-utils": "^2.0.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <5.8.0" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@typescript-eslint/utils": { + "version": "8.20.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.20.0.tgz", + "integrity": "sha512-dq70RUw6UK9ei7vxc4KQtBRk7qkHZv447OUZ6RPQMQl71I3NZxQJX/f32Smr+iqWrB02pHKn2yAdHBb0KNrRMA==", + "dev": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.4.0", + "@typescript-eslint/scope-manager": "8.20.0", + "@typescript-eslint/types": "8.20.0", + "@typescript-eslint/typescript-estree": "8.20.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <5.8.0" + } + }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "8.20.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.20.0.tgz", + "integrity": "sha512-v/BpkeeYAsPkKCkR8BDwcno0llhzWVqPOamQrAEMdpZav2Y9OVjd9dwJyBLJWwf335B5DmlifECIkZRJCaGaHA==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "8.20.0", + "eslint-visitor-keys": "^4.2.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } }, "node_modules/acorn": { - "version": "8.11.2", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.2.tgz", - "integrity": "sha512-nc0Axzp/0FILLEVsm4fNwLCwMttvhEI263QtVPQcbpfZZ3ts0hLsZGOpE6czNlid7CJ9MlyH8reXkpsf3YUY4w==", + "version": "8.15.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", + "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", "dev": true, "bin": { "acorn": "bin/acorn" @@ -525,6 +1133,7 @@ "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "dev": true, + "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -560,19 +1169,6 @@ "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", @@ -580,28 +1176,32 @@ "dev": true }, "node_modules/array-buffer-byte-length": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.0.tgz", - "integrity": "sha512-LPuwb2P+NrQw3XhxGc36+XSvuBPopovXYTR9Ew++Du9Yb/bx5AzBfrIsBoj0EZUifjQU+sHL21sseZ3jerWO/A==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.2.tgz", + "integrity": "sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw==", "dev": true, "dependencies": { - "call-bind": "^1.0.2", - "is-array-buffer": "^3.0.1" + "call-bound": "^1.0.3", + "is-array-buffer": "^3.0.5" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/array-includes": { - "version": "3.1.7", - "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.7.tgz", - "integrity": "sha512-dlcsNBIiWhPkHdOEEKnehA+RNUWDc4UqFtnIXU4uuYDPtA4LDkr7qip2p0VvFAEXNDr0yWZ9PJyIRiGjRLQzwQ==", + "version": "3.1.8", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.8.tgz", + "integrity": "sha512-itaWrbYbqpGXkGhZPGUulwnhVf5Hpy1xiCFsGqyIGglbBxmG5vSjxQen3/WGOjPpNEv1RtBLKxbmVXm8HpJStQ==", "dev": true, "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "get-intrinsic": "^1.2.1", + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.4", "is-string": "^1.0.7" }, "engines": { @@ -620,17 +1220,18 @@ "node": ">=8" } }, - "node_modules/array.prototype.findlastindex": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.3.tgz", - "integrity": "sha512-LzLoiOMAxvy+Gd3BAq3B7VeIgPdo+Q8hthvKtXybMvRV0jrXfJM/t8mw7nNlpEcVlVUnCnM2KSX4XU5HmpodOA==", + "node_modules/array.prototype.findlast": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/array.prototype.findlast/-/array.prototype.findlast-1.2.5.tgz", + "integrity": "sha512-CVvd6FHg1Z3POpBLxO6E6zr+rSKEQ9L6rZHAaY7lLfhKsWYUBBOuMs0e9o24oopj6H+geRCX0YJ+TJLBK2eHyQ==", "dev": true, "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "es-shim-unscopables": "^1.0.0", - "get-intrinsic": "^1.2.1" + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "es-shim-unscopables": "^1.0.2" }, "engines": { "node": ">= 0.4" @@ -640,15 +1241,15 @@ } }, "node_modules/array.prototype.flat": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.2.tgz", - "integrity": "sha512-djYB+Zx2vLewY8RWlNCUdHjDXs2XOgm602S9E7P/UpHgfeHL00cRiIF+IN/G/aUJ7kGPb6yO/ErDI5V2s8iycA==", + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.3.tgz", + "integrity": "sha512-rwG/ja1neyLqCuGZ5YYrznA62D4mZXg0i1cIskIUKSiqF3Cje9/wXAls9B9s1Wa2fomMsIv8czB8jZcPmxCXFg==", "dev": true, "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "es-shim-unscopables": "^1.0.0" + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-shim-unscopables": "^1.0.2" }, "engines": { "node": ">= 0.4" @@ -658,15 +1259,15 @@ } }, "node_modules/array.prototype.flatmap": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.2.tgz", - "integrity": "sha512-Ewyx0c9PmpcsByhSW4r+9zDU7sGjFc86qf/kKtuSCRdhfbk0SNLLkaT5qvcHnRGgc5NP/ly/y+qkXkqONX54CQ==", + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.3.tgz", + "integrity": "sha512-Y7Wt51eKJSyi80hFrJCePGGNo5ktJCslFuboqJsbf57CCPcm5zztluPlc4/aD8sWsKvlwatezpV4U1efk8kpjg==", "dev": true, "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "es-shim-unscopables": "^1.0.0" + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-shim-unscopables": "^1.0.2" }, "engines": { "node": ">= 0.4" @@ -675,19 +1276,35 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/array.prototype.tosorted": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/array.prototype.tosorted/-/array.prototype.tosorted-1.1.4.tgz", + "integrity": "sha512-p6Fx8B7b7ZhL/gmUsAy0D15WhvDccw3mnGNbZpi3pmeJdxtWsj2jEaI4Y6oo3XiHfzuSgPwKc04MYt6KgvC/wA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.3", + "es-errors": "^1.3.0", + "es-shim-unscopables": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/arraybuffer.prototype.slice": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.2.tgz", - "integrity": "sha512-yMBKppFur/fbHu9/6USUe03bZ4knMYiwFBcyiaXB8Go0qNehwX6inYPzK9U0NeQvGxKthcmHcaR8P5MStSRBAw==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.4.tgz", + "integrity": "sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ==", "dev": true, "dependencies": { - "array-buffer-byte-length": "^1.0.0", - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "get-intrinsic": "^1.2.1", - "is-array-buffer": "^3.0.2", - "is-shared-array-buffer": "^1.0.2" + "array-buffer-byte-length": "^1.0.1", + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "is-array-buffer": "^3.0.4" }, "engines": { "node": ">= 0.4" @@ -696,15 +1313,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/arrify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", - "integrity": "sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/astral-regex": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", @@ -715,10 +1323,13 @@ } }, "node_modules/available-typed-arrays": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz", - "integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", + "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", "dev": true, + "dependencies": { + "possible-typed-array-names": "^1.0.0" + }, "engines": { "node": ">= 0.4" }, @@ -732,14 +1343,25 @@ "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==", + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", "dev": true, - "engines": { - "node": ">=8" - } + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] }, "node_modules/brace-expansion": { "version": "1.1.11", @@ -752,74 +1374,102 @@ } }, "node_modules/braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", "dev": true, "dependencies": { - "fill-range": "^7.0.1" + "fill-range": "^7.1.1" }, "engines": { "node": ">=8" } }, - "node_modules/builtin-modules": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.3.0.tgz", - "integrity": "sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==", + "node_modules/buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", "dev": true, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" } }, - "node_modules/builtins": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/builtins/-/builtins-5.0.1.tgz", - "integrity": "sha512-qwVpFEHNfhYJIzNRBvd2C1kyo6jz3ZSMPyyuR47OPdiKWlbYnZNyDWuyR175qDnAJLiCo5fBBqPb3RiXgWlkOQ==", + "node_modules/cacheable": { + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/cacheable/-/cacheable-1.10.1.tgz", + "integrity": "sha512-Fa2BZY0CS9F0PFc/6aVA6tgpOdw+hmv9dkZOlHXII5v5Hw+meJBIWDcPrG9q/dXxGcNbym5t77fzmawrBQfTmQ==", "dev": true, "dependencies": { - "semver": "^7.0.0" + "hookified": "^1.10.0", + "keyv": "^5.3.4" } }, - "node_modules/builtins/node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "node_modules/cacheable/node_modules/keyv": { + "version": "5.3.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-5.3.4.tgz", + "integrity": "sha512-ypEvQvInNpUe+u+w8BIcPkQvEqXquyyibWE/1NB5T2BTzIpS5cGEV1LZskDzPSTvNAaT4+5FutvzlvnkxOSKlw==", "dev": true, "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/builtins/node_modules/semver": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", - "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" + "@keyv/serialize": "^1.0.3" } }, "node_modules/call-bind": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.5.tgz", - "integrity": "sha512-C3nQxfFZxFRVoJoGKKI8y3MOEo129NQ+FgQ08iye+Mk4zNZZGdjfs06bVTr+DBSlA66Q2VEcMki/cUCP4SercQ==", + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz", + "integrity": "sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==", "dev": true, "dependencies": { - "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.1", - "set-function-length": "^1.1.1" + "call-bind-apply-helpers": "^1.0.0", + "es-define-property": "^1.0.0", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.1.tgz", + "integrity": "sha512-BhYE+WDaywFg2TBWYNXAE+8B1ATnThNBqXHP5nQu0jWJdVvY2hvkpyB3qOmtmDePiS5/BDQ8wASEWGMWRG148g==", + "dev": true, + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/call-bound": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.3.tgz", + "integrity": "sha512-YTd+6wGlNlPxSuri7Y6X8tY2dmm12UMH66RpKMhiX6rsk5wXXnYgbUcOt8kiS31/AjfoTOvCsE+w8nZQLQnzHA==", + "dev": true, + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "get-intrinsic": "^1.2.6" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -834,48 +1484,6 @@ "node": ">=6" } }, - "node_modules/camelcase": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", - "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/camelcase-keys": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-7.0.2.tgz", - "integrity": "sha512-Rjs1H+A9R+Ig+4E/9oyB66UC5Mj9Xq3N//vcLf2WzgdTi/3gUu3Z9KoqmlrEG4VuuLK8wJHofxzdQXz/knhiYg==", - "dev": true, - "dependencies": { - "camelcase": "^6.3.0", - "map-obj": "^4.1.0", - "quick-lru": "^5.1.1", - "type-fest": "^1.2.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/camelcase-keys/node_modules/type-fest": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-1.4.0.tgz", - "integrity": "sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", @@ -892,43 +1500,52 @@ "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/chokidar": { - "version": "3.5.3", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", - "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", + "node_modules/character-entities": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-2.0.2.tgz", + "integrity": "sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==", "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" + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" } }, - "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==", + "node_modules/character-entities-legacy": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-3.0.0.tgz", + "integrity": "sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/character-reference-invalid": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-2.0.1.tgz", + "integrity": "sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw==", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/chokidar": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", + "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", "dev": true, "dependencies": { - "is-glob": "^4.0.1" + "readdirp": "^4.0.1" }, "engines": { - "node": ">= 6" + "node": ">= 14.16.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" } }, "node_modules/color-convert": { @@ -956,12 +1573,13 @@ "dev": true }, "node_modules/commander": { - "version": "11.0.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-11.0.0.tgz", - "integrity": "sha512-9HMlXtt/BNoYr8ooyjjNRdIilOTkVJXB+GhxMTtOKwk0R4j4lS4NpjuqmRxroBfnfTSHQIHQB7wryHhXarNjmQ==", + "version": "13.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-13.1.0.tgz", + "integrity": "sha512-/rFeCpNJQbhSZjGVwO9RFV3xPqbnERS8MmIQzCtD/zl6gpJuV/bMLuN92oG3F7d8oDEHHRrujSXNUr8fpjntKw==", "dev": true, + "license": "MIT", "engines": { - "node": ">=16" + "node": ">=18" } }, "node_modules/concat-map": { @@ -971,15 +1589,15 @@ "dev": true }, "node_modules/cosmiconfig": { - "version": "8.3.6", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.3.6.tgz", - "integrity": "sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA==", + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-9.0.0.tgz", + "integrity": "sha512-itvL5h8RETACmOTFc4UfIyB2RfEHi71Ax6E/PivVxq9NseKbOWpeyHEOIbmAw1rs8Ak0VursQNww7lf7YtUwzg==", "dev": true, "dependencies": { + "env-paths": "^2.2.1", "import-fresh": "^3.3.0", "js-yaml": "^4.1.0", - "parse-json": "^5.2.0", - "path-type": "^4.0.0" + "parse-json": "^5.2.0" }, "engines": { "node": ">=14" @@ -997,9 +1615,9 @@ } }, "node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", "dev": true, "dependencies": { "path-key": "^3.1.0", @@ -1011,21 +1629,21 @@ } }, "node_modules/css-functions-list": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/css-functions-list/-/css-functions-list-3.2.1.tgz", - "integrity": "sha512-Nj5YcaGgBtuUmn1D7oHqPW0c9iui7xsTsj5lIX8ZgevdfhmjFfKB3r8moHJtNJnctnYXJyYX5I1pp90HM4TPgQ==", + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/css-functions-list/-/css-functions-list-3.2.3.tgz", + "integrity": "sha512-IQOkD3hbR5KrN93MtcYuad6YPuTSUhntLHDuLEbFWE+ff2/XSZNdZG+LcbbIW5AXKg/WFIfYItIzVoHngHXZzA==", "dev": true, "engines": { "node": ">=12 || >=16" } }, "node_modules/css-tree": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.3.1.tgz", - "integrity": "sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-3.1.0.tgz", + "integrity": "sha512-0eW44TGN5SQXU1mWSkKwFstI/22X2bG1nYzZTYMAWjylYURhse752YgbE4Cx46AC+bAvI+/dYTPRk1LqSUnu6w==", "dev": true, "dependencies": { - "mdn-data": "2.0.30", + "mdn-data": "2.12.2", "source-map-js": "^1.0.1" }, "engines": { @@ -1044,13 +1662,65 @@ "node": ">=4" } }, - "node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "node_modules/data-view-buffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.2.tgz", + "integrity": "sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ==", "dev": true, "dependencies": { - "ms": "2.1.2" + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/data-view-byte-length": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.2.tgz", + "integrity": "sha512-tuhGbE6CfTM9+5ANGf+oQb72Ky/0+s3xKUpHvShfiz2RxMFgFPjsXuRLBVMtvMs15awe45SRb83D6wH4ew6wlQ==", + "dev": true, + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/inspect-js" + } + }, + "node_modules/data-view-byte-offset": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.1.tgz", + "integrity": "sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ==", + "dev": true, + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/debug": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz", + "integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" }, "engines": { "node": ">=6.0" @@ -1061,50 +1731,18 @@ } } }, - "node_modules/decamelize": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-5.0.1.tgz", - "integrity": "sha512-VfxadyCECXgQlkoEAjeghAr5gY3Hf+IKjKb+X8tGVDtveCjN+USwprd2q3QXBR9T1+x2DG0XZF5/w+7HAtSaXA==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/decamelize-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/decamelize-keys/-/decamelize-keys-1.1.1.tgz", - "integrity": "sha512-WiPxgEirIV0/eIOMcnFBA3/IJZAZqKnwAwWyvvdi4lsr1WCN22nhdf/3db3DoZcUjTV2SqfzIwNyp6y2xs3nmg==", + "node_modules/decode-named-character-reference": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/decode-named-character-reference/-/decode-named-character-reference-1.1.0.tgz", + "integrity": "sha512-Wy+JTSbFThEOXQIR2L6mxJvEs+veIzpmqD7ynWxMXGpnk3smkHQOp6forLdHsKpAMW9iJpaBBIxz285t1n1C3w==", "dev": true, + "license": "MIT", "dependencies": { - "decamelize": "^1.1.0", - "map-obj": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" + "character-entities": "^2.0.0" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/decamelize-keys/node_modules/decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/decamelize-keys/node_modules/map-obj": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", - "integrity": "sha512-7N/q3lyZ+LVCp7PzuxrJr4KMbBE2hW7BT7YNia330OFxIf4d3r5zVpicP2650l7CPN6RM9zOJRl3NGpqSiw3Eg==", - "dev": true, - "engines": { - "node": ">=0.10.0" + "type": "github", + "url": "https://github.com/sponsors/wooorm" } }, "node_modules/deep-extend": { @@ -1123,17 +1761,20 @@ "dev": true }, "node_modules/define-data-property": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.1.tgz", - "integrity": "sha512-E7uGkTzkk1d0ByLeSc6ZsFS79Axg+m1P/VsgYsxHgiuc3tFSj+MjMIwe90FC4lOAZzNBdY7kkO2P2wKdsQ1vgQ==", + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", "dev": true, "dependencies": { - "get-intrinsic": "^1.2.1", - "gopd": "^1.0.1", - "has-property-descriptors": "^1.0.0" + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" }, "engines": { "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, "node_modules/define-properties": { @@ -1153,6 +1794,43 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/dequal": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", + "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/detect-libc": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", + "integrity": "sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==", + "dev": true, + "optional": true, + "bin": { + "detect-libc": "bin/detect-libc.js" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/devlop": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/devlop/-/devlop-1.1.0.tgz", + "integrity": "sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==", + "dev": true, + "license": "MIT", + "dependencies": { + "dequal": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/dir-glob": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", @@ -1177,23 +1855,53 @@ "node": ">=6.0.0" } }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "dev": true, + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/eastasianwidth": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/emoji-regex": { "version": "9.2.2", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", - "dev": true + "dev": true, + "license": "MIT" + }, + "node_modules/enhanced-resolve": { + "version": "5.18.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.0.tgz", + "integrity": "sha512-0/r0MySGYG8YqlayBZ6MuCfECmHFdJ5qyPh8s8wa5Hnm6SaFLSK1VYCbj+NKp090Nm1caZhD+QTnmxO7esYGyQ==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.2.4", + "tapable": "^2.2.0" + }, + "engines": { + "node": ">=10.13.0" + } }, "node_modules/entities": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/entities/-/entities-3.0.1.tgz", - "integrity": "sha512-WiyBqoomrwMdFG1e0kqvASYfnlb0lp8M5o5Fw2OFq1hNZxxcNk8Ik0Xm7LxzBhuidnZB/UtBqVCgUz3kBOP51Q==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", "dev": true, + "license": "BSD-2-Clause", "engines": { "node": ">=0.12" }, @@ -1201,6 +1909,15 @@ "url": "https://github.com/fb55/entities?sponsor=1" } }, + "node_modules/env-paths": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", + "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", + "dev": true, + "engines": { + "node": ">=6" + } + }, "node_modules/error-ex": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", @@ -1211,50 +1928,62 @@ } }, "node_modules/es-abstract": { - "version": "1.22.3", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.22.3.tgz", - "integrity": "sha512-eiiY8HQeYfYH2Con2berK+To6GrK2RxbPawDkGq4UiCQQfZHb6wX9qQqkbpPqaxQFcl8d9QzZqo0tGE0VcrdwA==", + "version": "1.23.9", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.9.tgz", + "integrity": "sha512-py07lI0wjxAC/DcfK1S6G7iANonniZwTISvdPzk9hzeH0IZIshbuuFxLIU96OyF89Yb9hiqWn8M/bY83KY5vzA==", "dev": true, "dependencies": { - "array-buffer-byte-length": "^1.0.0", - "arraybuffer.prototype.slice": "^1.0.2", - "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.5", - "es-set-tostringtag": "^2.0.1", - "es-to-primitive": "^1.2.1", - "function.prototype.name": "^1.1.6", - "get-intrinsic": "^1.2.2", - "get-symbol-description": "^1.0.0", - "globalthis": "^1.0.3", - "gopd": "^1.0.1", - "has-property-descriptors": "^1.0.0", - "has-proto": "^1.0.1", - "has-symbols": "^1.0.3", - "hasown": "^2.0.0", - "internal-slot": "^1.0.5", - "is-array-buffer": "^3.0.2", + "array-buffer-byte-length": "^1.0.2", + "arraybuffer.prototype.slice": "^1.0.4", + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "data-view-buffer": "^1.0.2", + "data-view-byte-length": "^1.0.2", + "data-view-byte-offset": "^1.0.1", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "es-set-tostringtag": "^2.1.0", + "es-to-primitive": "^1.3.0", + "function.prototype.name": "^1.1.8", + "get-intrinsic": "^1.2.7", + "get-proto": "^1.0.0", + "get-symbol-description": "^1.1.0", + "globalthis": "^1.0.4", + "gopd": "^1.2.0", + "has-property-descriptors": "^1.0.2", + "has-proto": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "internal-slot": "^1.1.0", + "is-array-buffer": "^3.0.5", "is-callable": "^1.2.7", - "is-negative-zero": "^2.0.2", - "is-regex": "^1.1.4", - "is-shared-array-buffer": "^1.0.2", - "is-string": "^1.0.7", - "is-typed-array": "^1.1.12", - "is-weakref": "^1.0.2", - "object-inspect": "^1.13.1", + "is-data-view": "^1.0.2", + "is-regex": "^1.2.1", + "is-shared-array-buffer": "^1.0.4", + "is-string": "^1.1.1", + "is-typed-array": "^1.1.15", + "is-weakref": "^1.1.0", + "math-intrinsics": "^1.1.0", + "object-inspect": "^1.13.3", "object-keys": "^1.1.1", - "object.assign": "^4.1.4", - "regexp.prototype.flags": "^1.5.1", - "safe-array-concat": "^1.0.1", - "safe-regex-test": "^1.0.0", - "string.prototype.trim": "^1.2.8", - "string.prototype.trimend": "^1.0.7", - "string.prototype.trimstart": "^1.0.7", - "typed-array-buffer": "^1.0.0", - "typed-array-byte-length": "^1.0.0", - "typed-array-byte-offset": "^1.0.0", - "typed-array-length": "^1.0.4", - "unbox-primitive": "^1.0.2", - "which-typed-array": "^1.1.13" + "object.assign": "^4.1.7", + "own-keys": "^1.0.1", + "regexp.prototype.flags": "^1.5.3", + "safe-array-concat": "^1.1.3", + "safe-push-apply": "^1.0.0", + "safe-regex-test": "^1.1.0", + "set-proto": "^1.0.0", + "string.prototype.trim": "^1.2.10", + "string.prototype.trimend": "^1.0.9", + "string.prototype.trimstart": "^1.0.8", + "typed-array-buffer": "^1.0.3", + "typed-array-byte-length": "^1.0.3", + "typed-array-byte-offset": "^1.0.4", + "typed-array-length": "^1.0.7", + "unbox-primitive": "^1.1.0", + "which-typed-array": "^1.1.18" }, "engines": { "node": ">= 0.4" @@ -1263,15 +1992,73 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/es-set-tostringtag": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.2.tgz", - "integrity": "sha512-BuDyupZt65P9D2D2vA/zqcI3G5xRsklm5N3xCwuiy+/vKy8i0ifdsQP1sLgO4tZDSCaQUSnmC48khknGMV3D2Q==", + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-iterator-helpers": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.2.1.tgz", + "integrity": "sha512-uDn+FE1yrDzyC0pCo961B2IHbdM8y/ACZsKD4dG6WqrjV53BADjwa7D+1aom2rsNVfLyDgU/eigvlJGJ08OQ4w==", "dev": true, "dependencies": { - "get-intrinsic": "^1.2.2", - "has-tostringtag": "^1.0.0", - "hasown": "^2.0.0" + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.6", + "es-errors": "^1.3.0", + "es-set-tostringtag": "^2.0.3", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.6", + "globalthis": "^1.0.4", + "gopd": "^1.2.0", + "has-property-descriptors": "^1.0.2", + "has-proto": "^1.2.0", + "has-symbols": "^1.1.0", + "internal-slot": "^1.1.0", + "iterator.prototype": "^1.1.4", + "safe-array-concat": "^1.1.3" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-object-atoms": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "dev": true, + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-set-tostringtag": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", + "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", + "dev": true, + "dependencies": { + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" }, "engines": { "node": ">= 0.4" @@ -1287,14 +2074,14 @@ } }, "node_modules/es-to-primitive": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", - "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.3.0.tgz", + "integrity": "sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==", "dev": true, "dependencies": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" + "is-callable": "^1.2.7", + "is-date-object": "^1.0.5", + "is-symbol": "^1.0.4" }, "engines": { "node": ">= 0.4" @@ -1304,9 +2091,9 @@ } }, "node_modules/escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz", + "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==", "dev": true, "engines": { "node": ">=6" @@ -1325,65 +2112,73 @@ } }, "node_modules/eslint": { - "version": "8.54.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.54.0.tgz", - "integrity": "sha512-NY0DfAkM8BIZDVl6PgSa1ttZbx3xHgJzSNJKYcQglem6CppHyMhRIQkBVSSMaSRnLhig3jsDbEzOjwCVt4AmmA==", + "version": "9.30.1", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.30.1.tgz", + "integrity": "sha512-zmxXPNMOXmwm9E0yQLi5uqXHs7uq2UIiqEKo3Gq+3fwo1XrJ+hijAZImyF7hclW3E6oHz43Yk3RP8at6OTKflQ==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", - "@eslint-community/regexpp": "^4.6.1", - "@eslint/eslintrc": "^2.1.3", - "@eslint/js": "8.54.0", - "@humanwhocodes/config-array": "^0.11.13", + "@eslint-community/regexpp": "^4.12.1", + "@eslint/config-array": "^0.21.0", + "@eslint/config-helpers": "^0.3.0", + "@eslint/core": "^0.14.0", + "@eslint/eslintrc": "^3.3.1", + "@eslint/js": "9.30.1", + "@eslint/plugin-kit": "^0.3.1", + "@humanfs/node": "^0.16.6", "@humanwhocodes/module-importer": "^1.0.1", - "@nodelib/fs.walk": "^1.2.8", - "@ungap/structured-clone": "^1.2.0", + "@humanwhocodes/retry": "^0.4.2", + "@types/estree": "^1.0.6", + "@types/json-schema": "^7.0.15", "ajv": "^6.12.4", "chalk": "^4.0.0", - "cross-spawn": "^7.0.2", + "cross-spawn": "^7.0.6", "debug": "^4.3.2", - "doctrine": "^3.0.0", "escape-string-regexp": "^4.0.0", - "eslint-scope": "^7.2.2", - "eslint-visitor-keys": "^3.4.3", - "espree": "^9.6.1", - "esquery": "^1.4.2", + "eslint-scope": "^8.4.0", + "eslint-visitor-keys": "^4.2.1", + "espree": "^10.4.0", + "esquery": "^1.5.0", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^6.0.1", + "file-entry-cache": "^8.0.0", "find-up": "^5.0.0", "glob-parent": "^6.0.2", - "globals": "^13.19.0", - "graphemer": "^1.4.0", "ignore": "^5.2.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", - "is-path-inside": "^3.0.3", - "js-yaml": "^4.1.0", "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.4.1", "lodash.merge": "^4.6.2", "minimatch": "^3.1.2", "natural-compare": "^1.4.0", - "optionator": "^0.9.3", - "strip-ansi": "^6.0.1", - "text-table": "^0.2.0" + "optionator": "^0.9.3" }, "bin": { "eslint": "bin/eslint.js" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { - "url": "https://opencollective.com/eslint" + "url": "https://eslint.org/donate" + }, + "peerDependencies": { + "jiti": "*" + }, + "peerDependenciesMeta": { + "jiti": { + "optional": true + } } }, "node_modules/eslint-compat-utils": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/eslint-compat-utils/-/eslint-compat-utils-0.1.2.tgz", - "integrity": "sha512-Jia4JDldWnFNIru1Ehx1H5s9/yxiRHY/TimCuUc0jNexew3cF1gI6CYZil1ociakfWO3rRqFjl1mskBblB3RYg==", + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/eslint-compat-utils/-/eslint-compat-utils-0.5.1.tgz", + "integrity": "sha512-3z3vFexKIEnjHE3zCMRo6fn/e44U7T1khUjg+Hp0ZQMCigh28rALD0nPFBcGZuiLC5rLZa2ubQHDRln09JfU2Q==", "dev": true, + "dependencies": { + "semver": "^7.5.4" + }, "engines": { "node": ">=12" }, @@ -1391,35 +2186,6 @@ "eslint": ">=6.0.0" } }, - "node_modules/eslint-config-standard": { - "version": "17.1.0", - "resolved": "https://registry.npmjs.org/eslint-config-standard/-/eslint-config-standard-17.1.0.tgz", - "integrity": "sha512-IwHwmaBNtDK4zDHQukFDW5u/aTb8+meQWZvNFWkiGmbWjD6bqyuSSBxxXKkCftCUzc1zwCH2m/baCNDLGmuO5Q==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "engines": { - "node": ">=12.0.0" - }, - "peerDependencies": { - "eslint": "^8.0.1", - "eslint-plugin-import": "^2.25.2", - "eslint-plugin-n": "^15.0.0 || ^16.0.0 ", - "eslint-plugin-promise": "^6.0.0" - } - }, "node_modules/eslint-import-resolver-node": { "version": "0.3.9", "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz", @@ -1440,93 +2206,226 @@ "ms": "^2.1.1" } }, - "node_modules/eslint-module-utils": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.8.0.tgz", - "integrity": "sha512-aWajIYfsqCKRDgUfjEXNN/JlrzauMuSEy5sbd7WXbtW3EH6A6MpwEh42c7qD+MqQo9QMJ6fWLAeIJynx0g6OAw==", + "node_modules/eslint-import-resolver-typescript": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-typescript/-/eslint-import-resolver-typescript-3.7.0.tgz", + "integrity": "sha512-Vrwyi8HHxY97K5ebydMtffsWAn1SCR9eol49eCd5fJS4O1WV7PaAjbcjmbfJJSMz/t4Mal212Uz/fQZrOB8mow==", "dev": true, "dependencies": { - "debug": "^3.2.7" - }, - "engines": { - "node": ">=4" - }, - "peerDependenciesMeta": { - "eslint": { - "optional": true - } - } - }, - "node_modules/eslint-module-utils/node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "dependencies": { - "ms": "^2.1.1" - } - }, - "node_modules/eslint-plugin-es-x": { - "version": "7.4.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-es-x/-/eslint-plugin-es-x-7.4.0.tgz", - "integrity": "sha512-WJa3RhYzBtl8I37ebY9p76s61UhZyi4KaFOnX2A5r32RPazkXj5yoT6PGnD02dhwzEUj0KwsUdqfKDd/OuvGsw==", - "dev": true, - "dependencies": { - "@eslint-community/eslint-utils": "^4.1.2", - "@eslint-community/regexpp": "^4.6.0", - "eslint-compat-utils": "^0.1.2" + "@nolyfill/is-core-module": "1.0.39", + "debug": "^4.3.7", + "enhanced-resolve": "^5.15.0", + "fast-glob": "^3.3.2", + "get-tsconfig": "^4.7.5", + "is-bun-module": "^1.0.2", + "is-glob": "^4.0.3", + "stable-hash": "^0.0.4" }, "engines": { "node": "^14.18.0 || >=16.0.0" }, "funding": { - "url": "https://github.com/sponsors/ota-meshi" + "url": "https://opencollective.com/unts/projects/eslint-import-resolver-ts" + }, + "peerDependencies": { + "eslint": "*", + "eslint-plugin-import": "*", + "eslint-plugin-import-x": "*" + }, + "peerDependenciesMeta": { + "eslint-plugin-import": { + "optional": true + }, + "eslint-plugin-import-x": { + "optional": true + } + } + }, + "node_modules/eslint-plugin-es-x": { + "version": "7.8.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-es-x/-/eslint-plugin-es-x-7.8.0.tgz", + "integrity": "sha512-7Ds8+wAAoV3T+LAKeu39Y5BzXCrGKrcISfgKEqTS4BDN8SFEDQd0S43jiQ8vIa3wUKD07qitZdfzlenSi8/0qQ==", + "dev": true, + "funding": [ + "https://github.com/sponsors/ota-meshi", + "https://opencollective.com/eslint" + ], + "dependencies": { + "@eslint-community/eslint-utils": "^4.1.2", + "@eslint-community/regexpp": "^4.11.0", + "eslint-compat-utils": "^0.5.1" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" }, "peerDependencies": { "eslint": ">=8" } }, - "node_modules/eslint-plugin-import": { - "version": "2.29.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.29.0.tgz", - "integrity": "sha512-QPOO5NO6Odv5lpoTkddtutccQjysJuFxoPS7fAHO+9m9udNHvTCPSAMW9zGAYj8lAIdr40I8yPCdUYrncXtrwg==", + "node_modules/eslint-plugin-import-x": { + "version": "4.6.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-import-x/-/eslint-plugin-import-x-4.6.1.tgz", + "integrity": "sha512-wluSUifMIb7UfwWXqx7Yx0lE/SGCcGXECLx/9bCmbY2nneLwvAZ4vkd1IXDjPKFvdcdUgr1BaRnaRpx3k2+Pfw==", "dev": true, "dependencies": { - "array-includes": "^3.1.7", - "array.prototype.findlastindex": "^1.2.3", - "array.prototype.flat": "^1.3.2", - "array.prototype.flatmap": "^1.3.2", - "debug": "^3.2.7", - "doctrine": "^2.1.0", + "@types/doctrine": "^0.0.9", + "@typescript-eslint/scope-manager": "^8.1.0", + "@typescript-eslint/utils": "^8.1.0", + "debug": "^4.3.4", + "doctrine": "^3.0.0", + "enhanced-resolve": "^5.17.1", "eslint-import-resolver-node": "^0.3.9", - "eslint-module-utils": "^2.8.0", - "hasown": "^2.0.0", - "is-core-module": "^2.13.1", + "get-tsconfig": "^4.7.3", "is-glob": "^4.0.3", + "minimatch": "^9.0.3", + "semver": "^7.6.3", + "stable-hash": "^0.0.4", + "tslib": "^2.6.3" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0" + } + }, + "node_modules/eslint-plugin-import-x/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/eslint-plugin-import-x/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/eslint-plugin-n": { + "version": "17.15.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-n/-/eslint-plugin-n-17.15.1.tgz", + "integrity": "sha512-KFw7x02hZZkBdbZEFQduRGH4VkIH4MW97ClsbAM4Y4E6KguBJWGfWG1P4HEIpZk2bkoWf0bojpnjNAhYQP8beA==", + "dev": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.4.1", + "enhanced-resolve": "^5.17.1", + "eslint-plugin-es-x": "^7.8.0", + "get-tsconfig": "^4.8.1", + "globals": "^15.11.0", + "ignore": "^5.3.2", + "minimatch": "^9.0.5", + "semver": "^7.6.3" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + }, + "peerDependencies": { + "eslint": ">=8.23.0" + } + }, + "node_modules/eslint-plugin-n/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/eslint-plugin-n/node_modules/globals": { + "version": "15.15.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-15.15.0.tgz", + "integrity": "sha512-7ACyT3wmyp3I61S4fG682L0VA2RGD9otkqGJIwNUMF1SWUombIIk+af1unuDYgMm082aHYwD+mzJvv9Iu8dsgg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint-plugin-n/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/eslint-plugin-promise": { + "version": "7.2.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-7.2.1.tgz", + "integrity": "sha512-SWKjd+EuvWkYaS+uN2csvj0KoP43YTu7+phKQ5v+xw6+A0gutVX2yqCeCkC3uLCJFiPfR2dD8Es5L7yUsmvEaA==", + "dev": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.4.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + }, + "peerDependencies": { + "eslint": "^7.0.0 || ^8.0.0 || ^9.0.0" + } + }, + "node_modules/eslint-plugin-react": { + "version": "7.37.4", + "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.37.4.tgz", + "integrity": "sha512-BGP0jRmfYyvOyvMoRX/uoUeW+GqNj9y16bPQzqAHf3AYII/tDs+jMN0dBVkl88/OZwNGwrVFxE7riHsXVfy/LQ==", + "dev": true, + "dependencies": { + "array-includes": "^3.1.8", + "array.prototype.findlast": "^1.2.5", + "array.prototype.flatmap": "^1.3.3", + "array.prototype.tosorted": "^1.1.4", + "doctrine": "^2.1.0", + "es-iterator-helpers": "^1.2.1", + "estraverse": "^5.3.0", + "hasown": "^2.0.2", + "jsx-ast-utils": "^2.4.1 || ^3.0.0", "minimatch": "^3.1.2", - "object.fromentries": "^2.0.7", - "object.groupby": "^1.0.1", - "object.values": "^1.1.7", + "object.entries": "^1.1.8", + "object.fromentries": "^2.0.8", + "object.values": "^1.2.1", + "prop-types": "^15.8.1", + "resolve": "^2.0.0-next.5", "semver": "^6.3.1", - "tsconfig-paths": "^3.14.2" + "string.prototype.matchall": "^4.0.12", + "string.prototype.repeat": "^1.0.0" }, "engines": { "node": ">=4" }, "peerDependencies": { - "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8" + "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9.7" } }, - "node_modules/eslint-plugin-import/node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "dependencies": { - "ms": "^2.1.1" - } - }, - "node_modules/eslint-plugin-import/node_modules/doctrine": { + "node_modules/eslint-plugin-react/node_modules/doctrine": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", @@ -1538,121 +2437,81 @@ "node": ">=0.10.0" } }, - "node_modules/eslint-plugin-n": { - "version": "16.3.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-n/-/eslint-plugin-n-16.3.1.tgz", - "integrity": "sha512-w46eDIkxQ2FaTHcey7G40eD+FhTXOdKudDXPUO2n9WNcslze/i/HT2qJ3GXjHngYSGDISIgPNhwGtgoix4zeOw==", + "node_modules/eslint-plugin-react/node_modules/resolve": { + "version": "2.0.0-next.5", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.5.tgz", + "integrity": "sha512-U7WjGVG9sH8tvjW5SmGbQuui75FiyjAX72HX15DwBBwF9dNiQZRQAg9nnPhYy+TUnE0+VcrttuvNI8oSxZcocA==", "dev": true, "dependencies": { - "@eslint-community/eslint-utils": "^4.4.0", - "builtins": "^5.0.1", - "eslint-plugin-es-x": "^7.1.0", - "get-tsconfig": "^4.7.0", - "ignore": "^5.2.4", - "is-builtin-module": "^3.2.1", - "is-core-module": "^2.12.1", - "minimatch": "^3.1.2", - "resolve": "^1.22.2", - "semver": "^7.5.3" - }, - "engines": { - "node": ">=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/mysticatea" - }, - "peerDependencies": { - "eslint": ">=7.0.0" - } - }, - "node_modules/eslint-plugin-n/node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/eslint-plugin-n/node_modules/semver": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", - "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" + "is-core-module": "^2.13.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" }, "bin": { - "semver": "bin/semver.js" + "resolve": "bin/resolve" }, - "engines": { - "node": ">=10" + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/eslint-plugin-promise": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-6.1.1.tgz", - "integrity": "sha512-tjqWDwVZQo7UIPMeDReOpUgHCmCiH+ePnVT+5zVapL0uuHnegBUs2smM13CzOs2Xb5+MHMRFTs9v24yjba4Oig==", + "node_modules/eslint-plugin-react/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "peerDependencies": { - "eslint": "^7.0.0 || ^8.0.0" + "bin": { + "semver": "bin/semver.js" } }, "node_modules/eslint-scope": { - "version": "7.2.2", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", - "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", + "version": "8.4.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.4.0.tgz", + "integrity": "sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==", "dev": true, "dependencies": { "esrecurse": "^4.3.0", "estraverse": "^5.2.0" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "url": "https://opencollective.com/eslint" } }, "node_modules/eslint-visitor-keys": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", - "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz", + "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==", "dev": true, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "url": "https://opencollective.com/eslint" } }, "node_modules/espree": { - "version": "9.6.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", - "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-10.4.0.tgz", + "integrity": "sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==", "dev": true, "dependencies": { - "acorn": "^8.9.0", + "acorn": "^8.15.0", "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^3.4.1" + "eslint-visitor-keys": "^4.2.1" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "url": "https://opencollective.com/eslint" } }, "node_modules/esquery": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", - "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", + "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", "dev": true, "dependencies": { "estraverse": "^5.1.0" @@ -1698,16 +2557,16 @@ "dev": true }, "node_modules/fast-glob": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", - "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", + "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", "dev": true, "dependencies": { "@nodelib/fs.stat": "^2.0.2", "@nodelib/fs.walk": "^1.2.3", "glob-parent": "^5.1.2", "merge2": "^1.3.0", - "micromatch": "^4.0.4" + "micromatch": "^4.0.8" }, "engines": { "node": ">=8.6.0" @@ -1729,7 +2588,8 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/fast-levenshtein": { "version": "2.0.6", @@ -1737,6 +2597,22 @@ "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", "dev": true }, + "node_modules/fast-uri": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.5.tgz", + "integrity": "sha512-5JnBCWpFlMo0a3ciDy/JckMzzv1U9coZrIhedq+HXxxUfDTAiS0LA8OKVao4G9BxmCVck/jtA5r3KAtRWEyD8Q==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ] + }, "node_modules/fastest-levenshtein": { "version": "1.0.16", "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz", @@ -1747,30 +2623,30 @@ } }, "node_modules/fastq": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz", - "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==", + "version": "1.17.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", + "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", "dev": true, "dependencies": { "reusify": "^1.0.4" } }, "node_modules/file-entry-cache": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", - "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", + "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", "dev": true, "dependencies": { - "flat-cache": "^3.0.4" + "flat-cache": "^4.0.0" }, "engines": { - "node": "^10.12.0 || >=12.0.0" + "node": ">=16.0.0" } }, "node_modules/fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", "dev": true, "dependencies": { "to-regex-range": "^5.0.1" @@ -1796,24 +2672,24 @@ } }, "node_modules/flat-cache": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", - "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", + "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", "dev": true, "dependencies": { "flatted": "^3.2.9", - "keyv": "^4.5.3", - "rimraf": "^3.0.2" + "keyv": "^4.5.4" }, "engines": { - "node": "^10.12.0 || >=12.0.0" + "node": ">=16" } }, "node_modules/flatted": { - "version": "3.2.9", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.9.tgz", - "integrity": "sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ==", - "dev": true + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.3.tgz", + "integrity": "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==", + "dev": true, + "license": "ISC" }, "node_modules/for-each": { "version": "0.3.3", @@ -1825,12 +2701,13 @@ } }, "node_modules/foreground-child": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.1.1.tgz", - "integrity": "sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==", + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz", + "integrity": "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==", "dev": true, + "license": "ISC", "dependencies": { - "cross-spawn": "^7.0.0", + "cross-spawn": "^7.0.6", "signal-exit": "^4.0.1" }, "engines": { @@ -1840,26 +2717,6 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", - "dev": true - }, - "node_modules/fsevents": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", - "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", - "dev": true, - "hasInstallScript": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, "node_modules/function-bind": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", @@ -1870,15 +2727,17 @@ } }, "node_modules/function.prototype.name": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.6.tgz", - "integrity": "sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==", + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.8.tgz", + "integrity": "sha512-e5iwyodOHhbMr/yNrc7fDYG4qlbIvI5gajyzPnb5TCwyhjApznQh1BMFou9b30SevY43gCJKXycoCBjMbsuW0Q==", "dev": true, "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "functions-have-names": "^1.2.3" + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "functions-have-names": "^1.2.3", + "hasown": "^2.0.2", + "is-callable": "^1.2.7" }, "engines": { "node": ">= 0.4" @@ -1897,40 +2756,51 @@ } }, "node_modules/get-intrinsic": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.2.tgz", - "integrity": "sha512-0gSo4ml/0j98Y3lngkFEot/zhiCeWsbYIlZ+uZOVgzLyLaUw7wxUL+nCTP0XJvJg1AXulJRI3UJi8GsbDuxdGA==", + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.7.tgz", + "integrity": "sha512-VW6Pxhsrk0KAOqs3WEd0klDiF/+V7gQOpAvY1jVU/LHmaD/kQO4523aiJuikX/QAKYiW6x8Jh+RJej1almdtCA==", "dev": true, "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", "function-bind": "^1.1.2", - "has-proto": "^1.0.1", - "has-symbols": "^1.0.3", - "hasown": "^2.0.0" + "get-proto": "^1.0.0", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/get-stdin": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-9.0.0.tgz", - "integrity": "sha512-dVKBjfWisLAicarI2Sf+JuBE/DghV4UzNAVe9yhEJuzeREd3JhOTE9cUaJTeSa77fsbQUK3pcOpJfM59+VKZaA==", + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", "dev": true, - "engines": { - "node": ">=12" + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "engines": { + "node": ">= 0.4" } }, "node_modules/get-symbol-description": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz", - "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.1.0.tgz", + "integrity": "sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==", "dev": true, "dependencies": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.1.1" + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6" }, "engines": { "node": ">= 0.4" @@ -1940,9 +2810,9 @@ } }, "node_modules/get-tsconfig": { - "version": "4.7.2", - "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.7.2.tgz", - "integrity": "sha512-wuMsz4leaj5hbGgg4IvDU0bqJagpftG5l5cXIAvo8uZrqn0NJqwtfupTN00VnkQJPcIRrxYrm1Ue24btpCha2A==", + "version": "4.8.1", + "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.8.1.tgz", + "integrity": "sha512-k9PN+cFBmaLWtVz29SkUoqU5O0slLuHJXt/2P+tMVFT+phsSGXGkp9t3rQIqdz0e+06EHNGs3oM6ZX1s2zHxRg==", "dev": true, "dependencies": { "resolve-pkg-maps": "^1.0.0" @@ -1952,22 +2822,24 @@ } }, "node_modules/glob": { - "version": "10.3.10", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.10.tgz", - "integrity": "sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g==", + "version": "11.0.2", + "resolved": "https://registry.npmjs.org/glob/-/glob-11.0.2.tgz", + "integrity": "sha512-YT7U7Vye+t5fZ/QMkBFrTJ7ZQxInIUjwyAjVj84CYXqgBdv30MFUPGnBR6sQaVq6Is15wYJUsnzTuWaGRBhBAQ==", "dev": true, + "license": "ISC", "dependencies": { "foreground-child": "^3.1.0", - "jackspeak": "^2.3.5", - "minimatch": "^9.0.1", - "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0", - "path-scurry": "^1.10.1" + "jackspeak": "^4.0.1", + "minimatch": "^10.0.0", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^2.0.0" }, "bin": { "glob": "dist/esm/bin.mjs" }, "engines": { - "node": ">=16 || 14 >=14.17" + "node": "20 || >=22" }, "funding": { "url": "https://github.com/sponsors/isaacs" @@ -1990,20 +2862,22 @@ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", "dev": true, + "license": "MIT", "dependencies": { "balanced-match": "^1.0.0" } }, "node_modules/glob/node_modules/minimatch": { - "version": "9.0.3", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", - "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.0.1.tgz", + "integrity": "sha512-ethXTt3SGGR+95gudmqJ1eNhRO7eGEGIgYA9vnPatK4/etz2MEVDno5GMCibdMTuBMyElzIlgxMna3K94XDIDQ==", "dev": true, + "license": "ISC", "dependencies": { "brace-expansion": "^2.0.1" }, "engines": { - "node": ">=16 || 14 >=14.17" + "node": "20 || >=22" }, "funding": { "url": "https://github.com/sponsors/isaacs" @@ -2054,27 +2928,25 @@ } }, "node_modules/globals": { - "version": "13.23.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.23.0.tgz", - "integrity": "sha512-XAmF0RjlrjY23MA51q3HltdlGxUpXPvg0GioKiD9X6HD28iMjo2dKC8Vqwm7lne4GNr78+RHTfliktR6ZH09wA==", + "version": "16.3.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-16.3.0.tgz", + "integrity": "sha512-bqWEnJ1Nt3neqx2q5SFfGS8r/ahumIakg3HcwtNlrVlwXIeNumWn/c7Pn/wKzGhf6SaW6H6uWXLqC30STCMchQ==", "dev": true, - "dependencies": { - "type-fest": "^0.20.2" - }, "engines": { - "node": ">=8" + "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/globalthis": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.3.tgz", - "integrity": "sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz", + "integrity": "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==", "dev": true, "dependencies": { - "define-properties": "^1.1.3" + "define-properties": "^1.2.1", + "gopd": "^1.0.1" }, "engines": { "node": ">= 0.4" @@ -2110,37 +2982,37 @@ "dev": true }, "node_modules/gopd": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", - "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", "dev": true, - "dependencies": { - "get-intrinsic": "^1.1.3" + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true + }, "node_modules/graphemer": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", "dev": true }, - "node_modules/hard-rejection": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/hard-rejection/-/hard-rejection-2.1.0.tgz", - "integrity": "sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA==", + "node_modules/has-bigints": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.1.0.tgz", + "integrity": "sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg==", "dev": true, "engines": { - "node": ">=6" - } - }, - "node_modules/has-bigints": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", - "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==", - "dev": true, + "node": ">= 0.4" + }, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -2155,22 +3027,25 @@ } }, "node_modules/has-property-descriptors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.1.tgz", - "integrity": "sha512-VsX8eaIewvas0xnvinAe9bw4WfIeODpGYikiWYLH+dma0Jw6KHYqWiWfhQlgOVK8D6PvjubK5Uc4P0iIhIcNVg==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", "dev": true, "dependencies": { - "get-intrinsic": "^1.2.2" + "es-define-property": "^1.0.0" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/has-proto": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz", - "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.2.0.tgz", + "integrity": "sha512-KIL7eQPfHQRC8+XluaIw7BHUwwqL19bQn4hzNgdr+1wXoU0KKj6rufu47lhY7KbJR2C6T6+PfyN0Ea7wkSS+qQ==", "dev": true, + "dependencies": { + "dunder-proto": "^1.0.0" + }, "engines": { "node": ">= 0.4" }, @@ -2179,9 +3054,9 @@ } }, "node_modules/has-symbols": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", - "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", "dev": true, "engines": { "node": ">= 0.4" @@ -2191,12 +3066,12 @@ } }, "node_modules/has-tostringtag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", - "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", "dev": true, "dependencies": { - "has-symbols": "^1.0.2" + "has-symbols": "^1.0.3" }, "engines": { "node": ">= 0.4" @@ -2206,9 +3081,9 @@ } }, "node_modules/hasown": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.0.tgz", - "integrity": "sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", "dev": true, "dependencies": { "function-bind": "^1.1.2" @@ -2217,29 +3092,11 @@ "node": ">= 0.4" } }, - "node_modules/hosted-git-info": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.1.0.tgz", - "integrity": "sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==", - "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/hosted-git-info/node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } + "node_modules/hookified": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/hookified/-/hookified-1.10.0.tgz", + "integrity": "sha512-dJw0492Iddsj56U1JsSTm9E/0B/29a1AuoSLRAte8vQg/kaTGF3IgjEWT8c8yG4cC10+HisE1x5QAwR0Xwc+DA==", + "dev": true }, "node_modules/html-tags": { "version": "3.3.1", @@ -2253,19 +3110,39 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, "node_modules/ignore": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.0.tgz", - "integrity": "sha512-g7dmpshy+gD7mh88OC9NwSGTKoc3kyLAZQRU1mt53Aw/vnvfXnbC+F/7F7QoYVKbV+KNvJx8wArewKy1vXMtlg==", + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", "dev": true, "engines": { "node": ">= 4" } }, "node_modules/immutable": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.4.tgz", - "integrity": "sha512-fsXeu4J4i6WNWSikpI88v/PcVflZz+6kMhUfIwc5SY+poQRPnaf5V7qds6SUyUN3cVxEzuCab7QIoLOQ+DQ1wA==", + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/immutable/-/immutable-5.0.3.tgz", + "integrity": "sha512-P8IdPQHq3lA1xVeBRi5VPqUm5HDgKnx0Ru51wZz5mjxHr5n3RWhjIpOFU7ybkUxfB+5IToy+OLaHYDBIWsv+uw==", "dev": true }, "node_modules/import-fresh": { @@ -2284,15 +3161,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/import-lazy": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-4.0.0.tgz", - "integrity": "sha512-rKtvo6a868b5Hu3heneU+L4yEQ4jYKLtjpnPeUdK7h0yzXGmyBTypknlkCvHFBqfX9YlorEiMM6Dnq/5atfHkw==", - "dev": true, - "engines": { - "node": ">=8" - } - }, "node_modules/imurmurhash": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", @@ -2302,66 +3170,67 @@ "node": ">=0.8.19" } }, - "node_modules/indent-string": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-5.0.0.tgz", - "integrity": "sha512-m6FAo/spmsW2Ab2fU35JTYwtOKa2yAwXSwgjSv1TJzh4Mh7mC3lzAOVLBprb72XsTrgkEIsl7YrFNAiDiRhIGg==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", - "dev": true, - "dependencies": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true - }, "node_modules/ini": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ini/-/ini-4.1.1.tgz", - "integrity": "sha512-QQnnxNyfvmHFIsj7gkPcYymR8Jdw/o7mp5ZFihxn6h8Ci6fh3Dx4E1gPjpQEpIuPo9XVNY/ZUwh4BPMjGyL01g==", + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/ini/-/ini-4.1.3.tgz", + "integrity": "sha512-X7rqawQBvfdjS10YU1y1YVreA3SsLrW9dX2CewP2EbBJM4ypVNLDkO5y04gejPwKIY9lR+7r9gn3rFPt/kmWFg==", "dev": true, "engines": { "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, "node_modules/internal-slot": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.6.tgz", - "integrity": "sha512-Xj6dv+PsbtwyPpEflsejS+oIZxmMlV44zAhG479uYu89MsjcYOhCFnNyKrkJrihbsiasQyY0afoCl/9BLR65bg==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.1.0.tgz", + "integrity": "sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==", "dev": true, "dependencies": { - "get-intrinsic": "^1.2.2", - "hasown": "^2.0.0", - "side-channel": "^1.0.4" + "es-errors": "^1.3.0", + "hasown": "^2.0.2", + "side-channel": "^1.1.0" }, "engines": { "node": ">= 0.4" } }, + "node_modules/is-alphabetical": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-2.0.1.tgz", + "integrity": "sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ==", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-alphanumerical": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-2.0.1.tgz", + "integrity": "sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-alphabetical": "^2.0.0", + "is-decimal": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/is-array-buffer": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.2.tgz", - "integrity": "sha512-y+FyyR/w8vfIRq4eQcM1EYgSTnmHXPqaF+IgzgraytCFq5Xh8lllDVmAZolPJiZttZLeFSINPYMaEJ7/vWUa1w==", + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.5.tgz", + "integrity": "sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==", "dev": true, "dependencies": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.2.0", - "is-typed-array": "^1.1.10" + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "get-intrinsic": "^1.2.6" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -2373,38 +3242,16 @@ "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", "dev": true }, - "node_modules/is-bigint": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", - "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", - "dev": true, - "dependencies": { - "has-bigints": "^1.0.1" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-binary-path": { + "node_modules/is-async-function": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "resolved": "https://registry.npmjs.org/is-async-function/-/is-async-function-2.1.0.tgz", + "integrity": "sha512-GExz9MtyhlZyXYLxzlJRj5WUCE661zhDa1Yna52CN57AJsymh+DvXXjyveSioqSRdxvUrdKdvqB1b5cVKsNpWQ==", "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", - "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" + "call-bound": "^1.0.3", + "get-proto": "^1.0.1", + "has-tostringtag": "^1.0.2", + "safe-regex-test": "^1.1.0" }, "engines": { "node": ">= 0.4" @@ -2413,19 +3260,44 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-builtin-module": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-3.2.1.tgz", - "integrity": "sha512-BSLE3HnV2syZ0FK0iMA/yUGplUeMmNz4AW5fnTunbCIqZi4vG3WjJT9FHMy5D69xmAYBHXQhJdALdpwVxV501A==", + "node_modules/is-bigint": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.1.0.tgz", + "integrity": "sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ==", "dev": true, "dependencies": { - "builtin-modules": "^3.3.0" + "has-bigints": "^1.0.2" }, "engines": { - "node": ">=6" + "node": ">= 0.4" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-boolean-object": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.2.1.tgz", + "integrity": "sha512-l9qO6eFlUETHtuihLcYOaLKByJ1f+N4kthcU9YjHy3N+B3hWv0y/2Nd0mu/7lTFnRQHTrSdXF50HQ3bl5fEnng==", + "dev": true, + "dependencies": { + "call-bound": "^1.0.2", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-bun-module": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/is-bun-module/-/is-bun-module-1.3.0.tgz", + "integrity": "sha512-DgXeu5UWI0IsMQundYb5UAOzm6G2eVnarJ0byP6Tm55iZNKceD59LNPA2L4VvsScTtHcw0yEkVwSf7PC+QoLSA==", + "dev": true, + "dependencies": { + "semver": "^7.6.3" } }, "node_modules/is-callable": { @@ -2441,24 +3313,12 @@ } }, "node_modules/is-core-module": { - "version": "2.13.1", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz", - "integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==", + "version": "2.16.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz", + "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==", "dev": true, "dependencies": { - "hasown": "^2.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-date-object": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", - "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", - "dev": true, - "dependencies": { - "has-tostringtag": "^1.0.0" + "hasown": "^2.0.2" }, "engines": { "node": ">= 0.4" @@ -2467,6 +3327,50 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-data-view": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.2.tgz", + "integrity": "sha512-RKtWF8pGmS87i2D6gqQu/l7EYRlVdfzemCJN/P3UOs//x1QE7mfhvzHIApBTRf7axvT6DMGwSwBXYCT0nfB9xw==", + "dev": true, + "dependencies": { + "call-bound": "^1.0.2", + "get-intrinsic": "^1.2.6", + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-date-object": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.1.0.tgz", + "integrity": "sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==", + "dev": true, + "dependencies": { + "call-bound": "^1.0.2", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-decimal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-2.0.1.tgz", + "integrity": "sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A==", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", @@ -2476,6 +3380,21 @@ "node": ">=0.10.0" } }, + "node_modules/is-finalizationregistry": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-finalizationregistry/-/is-finalizationregistry-1.1.1.tgz", + "integrity": "sha512-1pC6N8qWJbWoPtEjgcL2xyhQOP491EQjeUo3qTKcmV8YSDDJrOepfG8pcC7h/QgnQHYSv0mJ3Z/ZWxmatVrysg==", + "dev": true, + "dependencies": { + "call-bound": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-fullwidth-code-point": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", @@ -2485,6 +3404,24 @@ "node": ">=8" } }, + "node_modules/is-generator-function": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.1.0.tgz", + "integrity": "sha512-nPUB5km40q9e8UfN/Zc24eLlzdSf9OfKByBw9CIdw4H1giPMeA0OIJvbchsCu4npfI2QcMVBsGEBHKZ7wLTWmQ==", + "dev": true, + "dependencies": { + "call-bound": "^1.0.3", + "get-proto": "^1.0.0", + "has-tostringtag": "^1.0.2", + "safe-regex-test": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-glob": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", @@ -2497,10 +3434,21 @@ "node": ">=0.10.0" } }, - "node_modules/is-negative-zero": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz", - "integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==", + "node_modules/is-hexadecimal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-2.0.1.tgz", + "integrity": "sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg==", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-map": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.3.tgz", + "integrity": "sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==", "dev": true, "engines": { "node": ">= 0.4" @@ -2519,12 +3467,13 @@ } }, "node_modules/is-number-object": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", - "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.1.1.tgz", + "integrity": "sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw==", "dev": true, "dependencies": { - "has-tostringtag": "^1.0.0" + "call-bound": "^1.0.3", + "has-tostringtag": "^1.0.2" }, "engines": { "node": ">= 0.4" @@ -2533,24 +3482,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-path-inside": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", - "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-plain-obj": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", - "integrity": "sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/is-plain-object": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", @@ -2561,13 +3492,15 @@ } }, "node_modules/is-regex": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", - "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.2.1.tgz", + "integrity": "sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==", "dev": true, "dependencies": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" + "call-bound": "^1.0.2", + "gopd": "^1.2.0", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" }, "engines": { "node": ">= 0.4" @@ -2576,25 +3509,41 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-set": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.3.tgz", + "integrity": "sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-shared-array-buffer": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz", - "integrity": "sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.4.tgz", + "integrity": "sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A==", "dev": true, "dependencies": { - "call-bind": "^1.0.2" + "call-bound": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/is-string": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", - "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.1.1.tgz", + "integrity": "sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA==", "dev": true, "dependencies": { - "has-tostringtag": "^1.0.0" + "call-bound": "^1.0.3", + "has-tostringtag": "^1.0.2" }, "engines": { "node": ">= 0.4" @@ -2604,12 +3553,14 @@ } }, "node_modules/is-symbol": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", - "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.1.1.tgz", + "integrity": "sha512-9gGx6GTtCQM73BgmHQXfDmLtfjjTUDSyoxTCbp5WtoixAhfgsDirWIcVQ/IHpvI5Vgd5i/J5F7B9cN/WlVbC/w==", "dev": true, "dependencies": { - "has-symbols": "^1.0.2" + "call-bound": "^1.0.2", + "has-symbols": "^1.1.0", + "safe-regex-test": "^1.1.0" }, "engines": { "node": ">= 0.4" @@ -2619,12 +3570,12 @@ } }, "node_modules/is-typed-array": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.12.tgz", - "integrity": "sha512-Z14TF2JNG8Lss5/HMqt0//T9JeHXttXy5pH/DBU4vi98ozO2btxzq9MwYDZYnKwU8nRsz/+GVFVRDq3DkVuSPg==", + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.15.tgz", + "integrity": "sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==", "dev": true, "dependencies": { - "which-typed-array": "^1.1.11" + "which-typed-array": "^1.1.16" }, "engines": { "node": ">= 0.4" @@ -2633,13 +3584,44 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-weakmap": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.2.tgz", + "integrity": "sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-weakref": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", - "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.1.0.tgz", + "integrity": "sha512-SXM8Nwyys6nT5WP6pltOwKytLV7FqQ4UiibxVmW+EIosHcmCqkkjViTb5SNssDlkCiEYRP1/pdWUKVvZBmsR2Q==", "dev": true, "dependencies": { - "call-bind": "^1.0.2" + "call-bound": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakset": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.4.tgz", + "integrity": "sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ==", + "dev": true, + "dependencies": { + "call-bound": "^1.0.3", + "get-intrinsic": "^1.2.6" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -2657,22 +3639,37 @@ "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", "dev": true }, - "node_modules/jackspeak": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-2.3.6.tgz", - "integrity": "sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ==", + "node_modules/iterator.prototype": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/iterator.prototype/-/iterator.prototype-1.1.5.tgz", + "integrity": "sha512-H0dkQoCa3b2VEeKQBOxFph+JAbcrQdE7KC0UkqwpLmv2EC4P41QXP+rqo9wYodACiG5/WM5s9oDApTU8utwj9g==", "dev": true, + "dependencies": { + "define-data-property": "^1.1.4", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.6", + "get-proto": "^1.0.0", + "has-symbols": "^1.1.0", + "set-function-name": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/jackspeak": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-4.1.1.tgz", + "integrity": "sha512-zptv57P3GpL+O0I7VdMJNBZCu+BPHVQUk55Ft8/QCJjTVxrnJHuVuX/0Bl2A6/+2oyR/ZMEuFKwmzqqZ/U5nPQ==", + "dev": true, + "license": "BlueOak-1.0.0", "dependencies": { "@isaacs/cliui": "^8.0.2" }, "engines": { - "node": ">=14" + "node": "20 || >=22" }, "funding": { "url": "https://github.com/sponsors/isaacs" - }, - "optionalDependencies": { - "@pkgjs/parseargs": "^0.11.0" } }, "node_modules/js-tokens": { @@ -2709,7 +3706,8 @@ "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/json-stable-stringify-without-jsonify": { "version": "1.0.1", @@ -2717,23 +3715,62 @@ "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", "dev": true }, - "node_modules/json5": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", - "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", + "node_modules/jsonc-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.3.1.tgz", + "integrity": "sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ==", + "dev": true + }, + "node_modules/jsonpointer": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-5.0.1.tgz", + "integrity": "sha512-p/nXbhSEcu3pZRdkW1OfJhpsVtW1gd4Wa1fnQc9YLiTfAjn0312eMKimbdIQzuZl9aa9xUGaRlP9T/CJE/ditQ==", "dev": true, - "dependencies": { - "minimist": "^1.2.0" - }, - "bin": { - "json5": "lib/cli.js" + "engines": { + "node": ">=0.10.0" } }, - "node_modules/jsonc-parser": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.2.0.tgz", - "integrity": "sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==", - "dev": true + "node_modules/jsx-ast-utils": { + "version": "3.3.5", + "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.5.tgz", + "integrity": "sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ==", + "dev": true, + "dependencies": { + "array-includes": "^3.1.6", + "array.prototype.flat": "^1.3.1", + "object.assign": "^4.1.4", + "object.values": "^1.1.6" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/katex": { + "version": "0.16.22", + "resolved": "https://registry.npmjs.org/katex/-/katex-0.16.22.tgz", + "integrity": "sha512-XCHRdUw4lf3SKBaJe4EvgqIuWwkPSo9XoeO8GjQW94Bp7TWv9hNhzZjZ+OH9yf1UmLygb7DIT5GSFQiyt16zYg==", + "dev": true, + "funding": [ + "https://opencollective.com/katex", + "https://github.com/sponsors/katex" + ], + "license": "MIT", + "dependencies": { + "commander": "^8.3.0" + }, + "bin": { + "katex": "cli.js" + } + }, + "node_modules/katex/node_modules/commander": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz", + "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 12" + } }, "node_modules/keyv": { "version": "4.5.4", @@ -2754,10 +3791,11 @@ } }, "node_modules/known-css-properties": { - "version": "0.29.0", - "resolved": "https://registry.npmjs.org/known-css-properties/-/known-css-properties-0.29.0.tgz", - "integrity": "sha512-Ne7wqW7/9Cz54PDt4I3tcV+hAyat8ypyOGzYRJQfdxnnjeWsTxt1cy8pjvvKeI5kfXuyvULyeeAvwvvtAX3ayQ==", - "dev": true + "version": "0.36.0", + "resolved": "https://registry.npmjs.org/known-css-properties/-/known-css-properties-0.36.0.tgz", + "integrity": "sha512-A+9jP+IUmuQsNdsLdcg6Yt7voiMF/D4K83ew0OpJtpu+l34ef7LaohWV0Rc6KNvzw6ZDizkqfyB5JznZnzuKQA==", + "dev": true, + "license": "MIT" }, "node_modules/levn": { "version": "0.4.1", @@ -2779,12 +3817,13 @@ "dev": true }, "node_modules/linkify-it": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-4.0.1.tgz", - "integrity": "sha512-C7bfi1UZmoj8+PQx22XyeXCuBlokoyWQL5pWSP+EI6nzRylyThouddufc2c1NDIcP9k5agmN9fLpA7VNJfIiqw==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-5.0.0.tgz", + "integrity": "sha512-5aHCbzQRADcdP+ATqnDuhhJ/MRIqDkZX5pyjFHRRysS8vZ5AbqGEoFIb6pYHPZ+L/OC2Lc+xT8uHVVR5CAK/wQ==", "dev": true, + "license": "MIT", "dependencies": { - "uc.micro": "^1.0.1" + "uc.micro": "^2.0.0" } }, "node_modules/locate-path": { @@ -2814,77 +3853,93 @@ "integrity": "sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw==", "dev": true }, - "node_modules/lru-cache": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.1.0.tgz", - "integrity": "sha512-/1clY/ui8CzjKFyjdvwPWJUYKiFVXG2I2cY0ssG7h4+hwk+XOIX7ZSG9Q7TW8TW3Kp3BUSqgFWBLgL4PJ+Blag==", + "node_modules/loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", "dev": true, - "engines": { - "node": "14 || >=16.14" + "dependencies": { + "js-tokens": "^3.0.0 || ^4.0.0" + }, + "bin": { + "loose-envify": "cli.js" } }, - "node_modules/map-obj": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-4.3.0.tgz", - "integrity": "sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ==", + "node_modules/lru-cache": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.1.0.tgz", + "integrity": "sha512-QIXZUBJUx+2zHUdQujWejBkcD9+cs94tLn0+YL8UrCh+D5sCXZ4c7LaEH48pNwRY3MLDgqUFyhlCyjJPf1WP0A==", "dev": true, + "license": "ISC", "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": "20 || >=22" } }, "node_modules/markdown-it": { - "version": "13.0.1", - "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-13.0.1.tgz", - "integrity": "sha512-lTlxriVoy2criHP0JKRhO2VDG9c2ypWCsT237eDiLqi09rmbKoUetyGHq2uOIRoRS//kfoJckS0eUzzkDR+k2Q==", + "version": "14.1.0", + "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-14.1.0.tgz", + "integrity": "sha512-a54IwgWPaeBCAAsv13YgmALOF1elABB08FxO9i+r4VFk5Vl4pKokRPeX8u5TCgSsPi6ec1otfLjdOpVcgbpshg==", "dev": true, + "license": "MIT", "dependencies": { "argparse": "^2.0.1", - "entities": "~3.0.1", - "linkify-it": "^4.0.1", - "mdurl": "^1.0.1", - "uc.micro": "^1.0.5" + "entities": "^4.4.0", + "linkify-it": "^5.0.0", + "mdurl": "^2.0.0", + "punycode.js": "^2.3.1", + "uc.micro": "^2.1.0" }, "bin": { - "markdown-it": "bin/markdown-it.js" + "markdown-it": "bin/markdown-it.mjs" } }, "node_modules/markdownlint": { - "version": "0.31.1", - "resolved": "https://registry.npmjs.org/markdownlint/-/markdownlint-0.31.1.tgz", - "integrity": "sha512-CKMR2hgcIBrYlIUccDCOvi966PZ0kJExDrUi1R+oF9PvqQmCrTqjOsgIvf2403OmJ+CWomuzDoylr6KbuMyvHA==", + "version": "0.38.0", + "resolved": "https://registry.npmjs.org/markdownlint/-/markdownlint-0.38.0.tgz", + "integrity": "sha512-xaSxkaU7wY/0852zGApM8LdlIfGCW8ETZ0Rr62IQtAnUMlMuifsg09vWJcNYeL4f0anvr8Vo4ZQar8jGpV0btQ==", "dev": true, + "license": "MIT", "dependencies": { - "markdown-it": "13.0.1", - "markdownlint-micromark": "0.1.7" + "micromark": "4.0.2", + "micromark-core-commonmark": "2.0.3", + "micromark-extension-directive": "4.0.0", + "micromark-extension-gfm-autolink-literal": "2.1.0", + "micromark-extension-gfm-footnote": "2.1.0", + "micromark-extension-gfm-table": "2.1.1", + "micromark-extension-math": "3.1.0", + "micromark-util-types": "2.0.2" }, "engines": { - "node": ">=16" + "node": ">=20" + }, + "funding": { + "url": "https://github.com/sponsors/DavidAnson" } }, "node_modules/markdownlint-cli": { - "version": "0.37.0", - "resolved": "https://registry.npmjs.org/markdownlint-cli/-/markdownlint-cli-0.37.0.tgz", - "integrity": "sha512-hNKAc0bWBBuVhJbSWbUhRzavstiB4o1jh3JeSpwC4/dt6eJ54lRfYHRxVdzVp4qGWBKbeE6Pg490PFEfrKjqSg==", + "version": "0.45.0", + "resolved": "https://registry.npmjs.org/markdownlint-cli/-/markdownlint-cli-0.45.0.tgz", + "integrity": "sha512-GiWr7GfJLVfcopL3t3pLumXCYs8sgWppjIA1F/Cc3zIMgD3tmkpyZ1xkm1Tej8mw53B93JsDjgA3KOftuYcfOw==", "dev": true, + "license": "MIT", "dependencies": { - "commander": "~11.0.0", - "get-stdin": "~9.0.0", - "glob": "~10.3.4", - "ignore": "~5.2.4", - "js-yaml": "^4.1.0", - "jsonc-parser": "~3.2.0", - "markdownlint": "~0.31.1", - "minimatch": "~9.0.3", - "run-con": "~1.3.2" + "commander": "~13.1.0", + "glob": "~11.0.2", + "ignore": "~7.0.4", + "js-yaml": "~4.1.0", + "jsonc-parser": "~3.3.1", + "jsonpointer": "~5.0.1", + "markdown-it": "~14.1.0", + "markdownlint": "~0.38.0", + "minimatch": "~10.0.1", + "run-con": "~1.3.2", + "smol-toml": "~1.3.4" }, "bin": { "markdownlint": "markdownlint.js" }, "engines": { - "node": ">=16" + "node": ">=20" } }, "node_modules/markdownlint-cli/node_modules/brace-expansion": { @@ -2892,41 +3947,44 @@ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", "dev": true, + "license": "MIT", "dependencies": { "balanced-match": "^1.0.0" } }, "node_modules/markdownlint-cli/node_modules/ignore": { - "version": "5.2.4", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", - "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==", + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.5.tgz", + "integrity": "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==", "dev": true, + "license": "MIT", "engines": { "node": ">= 4" } }, "node_modules/markdownlint-cli/node_modules/minimatch": { - "version": "9.0.3", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", - "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.0.1.tgz", + "integrity": "sha512-ethXTt3SGGR+95gudmqJ1eNhRO7eGEGIgYA9vnPatK4/etz2MEVDno5GMCibdMTuBMyElzIlgxMna3K94XDIDQ==", "dev": true, + "license": "ISC", "dependencies": { "brace-expansion": "^2.0.1" }, "engines": { - "node": ">=16 || 14 >=14.17" + "node": "20 || >=22" }, "funding": { "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/markdownlint-micromark": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/markdownlint-micromark/-/markdownlint-micromark-0.1.7.tgz", - "integrity": "sha512-BbRPTC72fl5vlSKv37v/xIENSRDYL/7X/XoFzZ740FGEbs9vZerLrIkFRY0rv7slQKxDczToYuMmqQFN61fi4Q==", + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", "dev": true, "engines": { - "node": ">=16" + "node": ">= 0.4" } }, "node_modules/mathml-tag-names": { @@ -2940,50 +3998,25 @@ } }, "node_modules/mdn-data": { - "version": "2.0.30", - "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.30.tgz", - "integrity": "sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==", + "version": "2.12.2", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.12.2.tgz", + "integrity": "sha512-IEn+pegP1aManZuckezWCO+XZQDplx1366JoVhTpMpBB1sPey/SbveZQUosKiKiGYjg1wH4pMlNgXbCiYgihQA==", "dev": true }, "node_modules/mdurl": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz", - "integrity": "sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g==", - "dev": true + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-2.0.0.tgz", + "integrity": "sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==", + "dev": true, + "license": "MIT" }, "node_modules/meow": { - "version": "10.1.5", - "resolved": "https://registry.npmjs.org/meow/-/meow-10.1.5.tgz", - "integrity": "sha512-/d+PQ4GKmGvM9Bee/DPa8z3mXs/pkvJE2KEThngVNOqtmljC6K7NMPxtc2JeZYTmpWb9k/TmxjeL18ez3h7vCw==", - "dev": true, - "dependencies": { - "@types/minimist": "^1.2.2", - "camelcase-keys": "^7.0.0", - "decamelize": "^5.0.0", - "decamelize-keys": "^1.1.0", - "hard-rejection": "^2.1.0", - "minimist-options": "4.1.0", - "normalize-package-data": "^3.0.2", - "read-pkg-up": "^8.0.0", - "redent": "^4.0.0", - "trim-newlines": "^4.0.2", - "type-fest": "^1.2.2", - "yargs-parser": "^20.2.9" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/meow/node_modules/type-fest": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-1.4.0.tgz", - "integrity": "sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA==", + "version": "13.2.0", + "resolved": "https://registry.npmjs.org/meow/-/meow-13.2.0.tgz", + "integrity": "sha512-pxQJQzB6djGPXh08dacEloMFopsOqGVRKFPYvPOt9XDZ1HasbgDZA74CJGreSU4G3Ak7EFJGoiH2auq+yXISgA==", "dev": true, "engines": { - "node": ">=10" + "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -2998,26 +4031,565 @@ "node": ">= 8" } }, + "node_modules/micromark": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/micromark/-/micromark-4.0.2.tgz", + "integrity": "sha512-zpe98Q6kvavpCr1NPVSCMebCKfD7CA2NqZ+rykeNhONIJBpc1tFKt9hucLGwha3jNTNI8lHpctWJWoimVF4PfA==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "@types/debug": "^4.0.0", + "debug": "^4.0.0", + "decode-named-character-reference": "^1.0.0", + "devlop": "^1.0.0", + "micromark-core-commonmark": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-combine-extensions": "^2.0.0", + "micromark-util-decode-numeric-character-reference": "^2.0.0", + "micromark-util-encode": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-resolve-all": "^2.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "micromark-util-subtokenize": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-core-commonmark": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/micromark-core-commonmark/-/micromark-core-commonmark-2.0.3.tgz", + "integrity": "sha512-RDBrHEMSxVFLg6xvnXmb1Ayr2WzLAWjeSATAoxwKYJV94TeNavgoIdA0a9ytzDSVzBy2YKFK+emCPOEibLeCrg==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "decode-named-character-reference": "^1.0.0", + "devlop": "^1.0.0", + "micromark-factory-destination": "^2.0.0", + "micromark-factory-label": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-factory-title": "^2.0.0", + "micromark-factory-whitespace": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-classify-character": "^2.0.0", + "micromark-util-html-tag-name": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-resolve-all": "^2.0.0", + "micromark-util-subtokenize": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-directive": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-directive/-/micromark-extension-directive-4.0.0.tgz", + "integrity": "sha512-/C2nqVmXXmiseSSuCdItCMho7ybwwop6RrrRPk0KbOHW21JKoCldC+8rFOaundDoRBUWBnJJcxeA/Kvi34WQXg==", + "dev": true, + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-factory-whitespace": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0", + "parse-entities": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-autolink-literal": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-autolink-literal/-/micromark-extension-gfm-autolink-literal-2.1.0.tgz", + "integrity": "sha512-oOg7knzhicgQ3t4QCjCWgTmfNhvQbDDnJeVu9v81r7NltNCVmhPy1fJRX27pISafdjL+SVc4d3l48Gb6pbRypw==", + "dev": true, + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-footnote": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-footnote/-/micromark-extension-gfm-footnote-2.1.0.tgz", + "integrity": "sha512-/yPhxI1ntnDNsiHtzLKYnE3vf9JZ6cAisqVDauhp4CEHxlb4uoOTxOCJ+9s51bIB8U1N1FJ1RXOKTIlD5B/gqw==", + "dev": true, + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-core-commonmark": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-table": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-table/-/micromark-extension-gfm-table-2.1.1.tgz", + "integrity": "sha512-t2OU/dXXioARrC6yWfJ4hqB7rct14e8f7m0cbI5hUmDyyIlwv5vEtooptH8INkbLzOatzKuVbQmAYcbWoyz6Dg==", + "dev": true, + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-math": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/micromark-extension-math/-/micromark-extension-math-3.1.0.tgz", + "integrity": "sha512-lvEqd+fHjATVs+2v/8kg9i5Q0AP2k85H0WUOwpIVvUML8BapsMvh1XAogmQjOCsLpoKRCVQqEkQBB3NhVBcsOg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/katex": "^0.16.0", + "devlop": "^1.0.0", + "katex": "^0.16.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-factory-destination": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-destination/-/micromark-factory-destination-2.0.1.tgz", + "integrity": "sha512-Xe6rDdJlkmbFRExpTOmRj9N3MaWmbAgdpSrBQvCFqhezUn4AHqJHbaEnfbVYYiexVSs//tqOdY/DxhjdCiJnIA==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-label": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-label/-/micromark-factory-label-2.0.1.tgz", + "integrity": "sha512-VFMekyQExqIW7xIChcXn4ok29YE3rnuyveW3wZQWWqF4Nv9Wk5rgJ99KzPvHjkmPXF93FXIbBp6YdW3t71/7Vg==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-space": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.1.tgz", + "integrity": "sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-title": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-title/-/micromark-factory-title-2.0.1.tgz", + "integrity": "sha512-5bZ+3CjhAd9eChYTHsjy6TGxpOFSKgKKJPJxr293jTbfry2KDoWkhBb6TcPVB4NmzaPhMs1Frm9AZH7OD4Cjzw==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-whitespace": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-whitespace/-/micromark-factory-whitespace-2.0.1.tgz", + "integrity": "sha512-Ob0nuZ3PKt/n0hORHyvoD9uZhr+Za8sFoP+OnMcnWK5lngSzALgQYKMr9RJVOWLqQYuyn6ulqGWSXdwf6F80lQ==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-character": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz", + "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-chunked": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-chunked/-/micromark-util-chunked-2.0.1.tgz", + "integrity": "sha512-QUNFEOPELfmvv+4xiNg2sRYeS/P84pTW0TCgP5zc9FpXetHY0ab7SxKyAQCNCc1eK0459uoLI1y5oO5Vc1dbhA==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-classify-character": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-classify-character/-/micromark-util-classify-character-2.0.1.tgz", + "integrity": "sha512-K0kHzM6afW/MbeWYWLjoHQv1sgg2Q9EccHEDzSkxiP/EaagNzCm7T/WMKZ3rjMbvIpvBiZgwR3dKMygtA4mG1Q==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-combine-extensions": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-combine-extensions/-/micromark-util-combine-extensions-2.0.1.tgz", + "integrity": "sha512-OnAnH8Ujmy59JcyZw8JSbK9cGpdVY44NKgSM7E9Eh7DiLS2E9RNQf0dONaGDzEG9yjEl5hcqeIsj4hfRkLH/Bg==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-chunked": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-decode-numeric-character-reference": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-2.0.2.tgz", + "integrity": "sha512-ccUbYk6CwVdkmCQMyr64dXz42EfHGkPQlBj5p7YVGzq8I7CtjXZJrubAYezf7Rp+bjPseiROqe7G6foFd+lEuw==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-encode": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-2.0.1.tgz", + "integrity": "sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-util-html-tag-name": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-html-tag-name/-/micromark-util-html-tag-name-2.0.1.tgz", + "integrity": "sha512-2cNEiYDhCWKI+Gs9T0Tiysk136SnR13hhO8yW6BGNyhOC4qYFnwF1nKfD3HFAIXA5c45RrIG1ub11GiXeYd1xA==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-util-normalize-identifier": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-2.0.1.tgz", + "integrity": "sha512-sxPqmo70LyARJs0w2UclACPUUEqltCkJ6PhKdMIDuJ3gSf/Q+/GIe3WKl0Ijb/GyH9lOpUkRAO2wp0GVkLvS9Q==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-resolve-all": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-resolve-all/-/micromark-util-resolve-all-2.0.1.tgz", + "integrity": "sha512-VdQyxFWFT2/FGJgwQnJYbe1jjQoNTS4RjglmSjTUlpUMa95Htx9NHeYW4rGDJzbjvCsl9eLjMQwGeElsqmzcHg==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-sanitize-uri": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-2.0.1.tgz", + "integrity": "sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-encode": "^2.0.0", + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-subtokenize": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-subtokenize/-/micromark-util-subtokenize-2.1.0.tgz", + "integrity": "sha512-XQLu552iSctvnEcgXw6+Sx75GflAPNED1qx7eBJ+wydBb2KCbRZe+NwvIEEMM83uml1+2WSXpBAcp9IUCgCYWA==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-symbol": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", + "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-util-types": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-2.0.2.tgz", + "integrity": "sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, "node_modules/micromatch": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", - "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", "dev": true, "dependencies": { - "braces": "^3.0.2", + "braces": "^3.0.3", "picomatch": "^2.3.1" }, "engines": { "node": ">=8.6" } }, - "node_modules/min-indent": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", - "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==", + "node_modules/micromatch/node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", "dev": true, "engines": { - "node": ">=4" + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" } }, "node_modules/minimatch": { @@ -3041,39 +4613,26 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/minimist-options": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/minimist-options/-/minimist-options-4.1.0.tgz", - "integrity": "sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A==", - "dev": true, - "dependencies": { - "arrify": "^1.0.1", - "is-plain-obj": "^1.1.0", - "kind-of": "^6.0.3" - }, - "engines": { - "node": ">= 6" - } - }, "node_modules/minipass": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.4.tgz", - "integrity": "sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==", + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", "dev": true, + "license": "ISC", "engines": { "node": ">=16 || 14 >=14.17" } }, "node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", "dev": true }, "node_modules/nanoid": { - "version": "3.3.7", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", - "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", + "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", "dev": true, "funding": [ { @@ -3094,48 +4653,55 @@ "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", "dev": true }, - "node_modules/normalize-package-data": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-3.0.3.tgz", - "integrity": "sha512-p2W1sgqij3zMMyRC067Dg16bfzVH+w7hyegmpIvZ4JNjqtGOVAIvLmjBx3yP7YTe9vKJgkoNOPjwQGogDoMXFA==", + "node_modules/neostandard": { + "version": "0.12.1", + "resolved": "https://registry.npmjs.org/neostandard/-/neostandard-0.12.1.tgz", + "integrity": "sha512-As/LDK+xx591BLb1rPRaPs+JfXFgyNx5BoBui1KBeF/J4s0mW8+NBohrYnMfgm1w1t7E/Y/tU34MjMiP6lns6A==", "dev": true, + "license": "MIT", "dependencies": { - "hosted-git-info": "^4.0.1", - "is-core-module": "^2.5.0", - "semver": "^7.3.4", - "validate-npm-package-license": "^3.0.1" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/normalize-package-data/node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/normalize-package-data/node_modules/semver": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", - "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" + "@humanwhocodes/gitignore-to-minimatch": "^1.0.2", + "@stylistic/eslint-plugin": "2.11.0", + "eslint-import-resolver-typescript": "^3.7.0", + "eslint-plugin-import-x": "^4.5.0", + "eslint-plugin-n": "^17.14.0", + "eslint-plugin-promise": "^7.2.1", + "eslint-plugin-react": "^7.37.2", + "find-up": "^5.0.0", + "globals": "^15.13.0", + "peowly": "^1.3.2", + "typescript-eslint": "^8.17.0" }, "bin": { - "semver": "bin/semver.js" + "neostandard": "cli.mjs" }, "engines": { - "node": ">=10" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "peerDependencies": { + "eslint": "^9.0.0" } }, + "node_modules/neostandard/node_modules/globals": { + "version": "15.15.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-15.15.0.tgz", + "integrity": "sha512-7ACyT3wmyp3I61S4fG682L0VA2RGD9otkqGJIwNUMF1SWUombIIk+af1unuDYgMm082aHYwD+mzJvv9Iu8dsgg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/node-addon-api": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-7.1.1.tgz", + "integrity": "sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==", + "dev": true, + "optional": true + }, "node_modules/normalize-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", @@ -3145,11 +4711,23 @@ "node": ">=0.10.0" } }, - "node_modules/object-inspect": { - "version": "1.13.1", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", - "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==", + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-inspect": { + "version": "1.13.3", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.3.tgz", + "integrity": "sha512-kDCGIbxkDSXE3euJZZXzc6to7fCrKHNI/hSRQnRuQ+BWjFNzZwiFF8fj/6o2t2G9/jTj8PSIYTfCLelLZEeRpA==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -3164,14 +4742,16 @@ } }, "node_modules/object.assign": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.4.tgz", - "integrity": "sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==", + "version": "4.1.7", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.7.tgz", + "integrity": "sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==", "dev": true, "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "has-symbols": "^1.0.3", + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0", + "has-symbols": "^1.1.0", "object-keys": "^1.1.1" }, "engines": { @@ -3181,15 +4761,30 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/object.fromentries": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.7.tgz", - "integrity": "sha512-UPbPHML6sL8PI/mOqPwsH4G6iyXcCGzLin8KvEPenOZN5lpCNBZZQ+V62vdjB1mQHrmqGQt5/OJzemUA+KJmEA==", + "node_modules/object.entries": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.8.tgz", + "integrity": "sha512-cmopxi8VwRIAw/fkijJohSfpef5PdN0pMQJN6VC/ZKvn0LIknWD8KtgY6KlQdEc4tIjcQ3HxSMmnvtzIscdaYQ==", "dev": true, "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1" + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.fromentries": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.8.tgz", + "integrity": "sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-object-atoms": "^1.0.0" }, "engines": { "node": ">= 0.4" @@ -3198,27 +4793,16 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/object.groupby": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/object.groupby/-/object.groupby-1.0.1.tgz", - "integrity": "sha512-HqaQtqLnp/8Bn4GL16cj+CUYbnpe1bh0TtEaWvybszDG4tgxCJuRpV8VGuvNaI1fAnI4lUJzDG55MXcOH4JZcQ==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "get-intrinsic": "^1.2.1" - } - }, "node_modules/object.values": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.7.tgz", - "integrity": "sha512-aU6xnDFYT3x17e/f0IiiwlGPTy2jzMySGfUB4fq6z7CV8l85CWHDk5ErhyhpfDHhrOMwGFhSQkhMGHaIotA6Ng==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.2.1.tgz", + "integrity": "sha512-gXah6aZrcUxjWg2zR2MwouP2eHlCBzdV4pygudehaKXSGW4v2AsRQUK+lwwXhii6KFZcunEnmSUoYp5CXibxtA==", "dev": true, "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1" + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" }, "engines": { "node": ">= 0.4" @@ -3227,32 +4811,40 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "dev": true, - "dependencies": { - "wrappy": "1" - } - }, "node_modules/optionator": { - "version": "0.9.3", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", - "integrity": "sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==", + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", + "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", "dev": true, "dependencies": { - "@aashutoshrathi/word-wrap": "^1.2.3", "deep-is": "^0.1.3", "fast-levenshtein": "^2.0.6", "levn": "^0.4.1", "prelude-ls": "^1.2.1", - "type-check": "^0.4.0" + "type-check": "^0.4.0", + "word-wrap": "^1.2.5" }, "engines": { "node": ">= 0.8.0" } }, + "node_modules/own-keys": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/own-keys/-/own-keys-1.0.1.tgz", + "integrity": "sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.2.6", + "object-keys": "^1.1.1", + "safe-push-apply": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/p-limit": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", @@ -3283,6 +4875,13 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/package-json-from-dist": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", + "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", + "dev": true, + "license": "BlueOak-1.0.0" + }, "node_modules/parent-module": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", @@ -3295,6 +4894,26 @@ "node": ">=6" } }, + "node_modules/parse-entities": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-4.0.2.tgz", + "integrity": "sha512-GG2AQYWoLgL877gQIKeRPGO1xF9+eG1ujIb5soS5gPvLQ1y2o8FL90w2QWNdf9I361Mpp7726c+lj3U0qK1uGw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/unist": "^2.0.0", + "character-entities-legacy": "^3.0.0", + "character-reference-invalid": "^2.0.0", + "decode-named-character-reference": "^1.0.0", + "is-alphanumerical": "^2.0.0", + "is-decimal": "^2.0.0", + "is-hexadecimal": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/parse-json": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", @@ -3322,15 +4941,6 @@ "node": ">=8" } }, - "node_modules/path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/path-key": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", @@ -3347,16 +4957,17 @@ "dev": true }, "node_modules/path-scurry": { - "version": "1.10.1", - "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.10.1.tgz", - "integrity": "sha512-MkhCqzzBEpPvxxQ71Md0b1Kk51W01lrYvlMzSUaIzNsODdd7mqhiimSZlr+VegAz5Z6Vzt9Xg2ttE//XBhH3EQ==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.0.tgz", + "integrity": "sha512-ypGJsmGtdXUOeM5u93TyeIEfEhM6s+ljAhrk5vAvSx8uyY/02OvrZnA0YNGUrPXfpJMgI1ODd3nwz8Npx4O4cg==", "dev": true, + "license": "BlueOak-1.0.0", "dependencies": { - "lru-cache": "^9.1.1 || ^10.0.0", - "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + "lru-cache": "^11.0.0", + "minipass": "^7.1.2" }, "engines": { - "node": ">=16 || 14 >=14.17" + "node": "20 || >=22" }, "funding": { "url": "https://github.com/sponsors/isaacs" @@ -3371,28 +4982,46 @@ "node": ">=8" } }, + "node_modules/peowly": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/peowly/-/peowly-1.3.2.tgz", + "integrity": "sha512-BYIrwr8JCXY49jUZscgw311w9oGEKo7ux/s+BxrhKTQbiQ0iYNdZNJ5LgagaeercQdFHwnR7Z5IxxFWVQ+BasQ==", + "dev": true, + "engines": { + "node": ">=18.6.0" + } + }, "node_modules/picocolors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", - "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", "dev": true }, "node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz", + "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==", "dev": true, "engines": { - "node": ">=8.6" + "node": ">=12" }, "funding": { "url": "https://github.com/sponsors/jonschlinkert" } }, + "node_modules/possible-typed-array-names": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz", + "integrity": "sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/postcss": { - "version": "8.4.31", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz", - "integrity": "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==", + "version": "8.5.6", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz", + "integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==", "dev": true, "funding": [ { @@ -3409,9 +5038,9 @@ } ], "dependencies": { - "nanoid": "^3.3.6", - "picocolors": "^1.0.0", - "source-map-js": "^1.0.2" + "nanoid": "^3.3.11", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" }, "engines": { "node": "^10 || ^12 || >=14" @@ -3421,28 +5050,39 @@ "version": "0.2.3", "resolved": "https://registry.npmjs.org/postcss-media-query-parser/-/postcss-media-query-parser-0.2.3.tgz", "integrity": "sha512-3sOlxmbKcSHMjlUXQZKQ06jOswE7oVkXPxmZdoB1r5l0q6gTFTQSHxNxOrCccElbW7dxNytifNEo8qidX2Vsig==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/postcss-resolve-nested-selector": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/postcss-resolve-nested-selector/-/postcss-resolve-nested-selector-0.1.1.tgz", - "integrity": "sha512-HvExULSwLqHLgUy1rl3ANIqCsvMS0WHss2UOsXhXnQaZ9VCc2oBvIpXrl00IUFT5ZDITME0o6oiXeiHr2SAIfw==", + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/postcss-resolve-nested-selector/-/postcss-resolve-nested-selector-0.1.6.tgz", + "integrity": "sha512-0sglIs9Wmkzbr8lQwEyIzlDOOC9bGmfVKcJTaxv3vMmd3uo4o4DerC3En0bnmgceeql9BfC8hRkp7cg0fjdVqw==", "dev": true }, "node_modules/postcss-safe-parser": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/postcss-safe-parser/-/postcss-safe-parser-6.0.0.tgz", - "integrity": "sha512-FARHN8pwH+WiS2OPCxJI8FuRJpTVnn6ZNFiqAM2aeW2LwTHWWmWgIyKC6cUo0L8aeKiF/14MNvnpls6R2PBeMQ==", + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/postcss-safe-parser/-/postcss-safe-parser-7.0.1.tgz", + "integrity": "sha512-0AioNCJZ2DPYz5ABT6bddIqlhgwhpHZ/l65YAYo0BCIn0xiDpsnTHz0gnoTGk0OXZW0JRs+cDwL8u/teRdz+8A==", "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss-safe-parser" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], "engines": { - "node": ">=12.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" + "node": ">=18.0" }, "peerDependencies": { - "postcss": "^8.3.3" + "postcss": "^8.4.31" } }, "node_modules/postcss-scss": { @@ -3472,9 +5112,9 @@ } }, "node_modules/postcss-selector-parser": { - "version": "6.0.13", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.13.tgz", - "integrity": "sha512-EaV1Gl4mUEV4ddhDnv/xtj7sxwrwxdetHdWUGnT4VJQf+4d05v6lHYZr8N573k5Z0BViss7BDhfWtKS3+sfAqQ==", + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz", + "integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==", "dev": true, "dependencies": { "cssesc": "^3.0.0", @@ -3485,10 +5125,11 @@ } }, "node_modules/postcss-sorting": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/postcss-sorting/-/postcss-sorting-8.0.2.tgz", - "integrity": "sha512-M9dkSrmU00t/jK7rF6BZSZauA5MAaBW4i5EnJXspMwt4iqTh/L9j6fgMnbElEOfyRyfLfVbIHj/R52zHzAPe1Q==", + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/postcss-sorting/-/postcss-sorting-9.1.0.tgz", + "integrity": "sha512-Mn8KJ45HNNG6JBpBizXcyf6LqY/qyqetGcou/nprDnFwBFBLGj0j/sNKV2lj2KMOVOwdXu14aEzqJv8CIV6e8g==", "dev": true, + "license": "MIT", "peerDependencies": { "postcss": "^8.4.20" } @@ -3508,11 +5149,33 @@ "node": ">= 0.8.0" } }, + "node_modules/prop-types": { + "version": "15.8.1", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", + "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", + "dev": true, + "dependencies": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.13.1" + } + }, "node_modules/punycode": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/punycode.js": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode.js/-/punycode.js-2.3.1.tgz", + "integrity": "sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA==", + "dev": true, + "license": "MIT", "engines": { "node": ">=6" } @@ -3537,114 +5200,59 @@ } ] }, - "node_modules/quick-lru": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz", - "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/read-pkg": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-6.0.0.tgz", - "integrity": "sha512-X1Fu3dPuk/8ZLsMhEj5f4wFAF0DWoK7qhGJvgaijocXxBmSToKfbFtqbxMO7bVjNA1dmE5huAzjXj/ey86iw9Q==", - "dev": true, - "dependencies": { - "@types/normalize-package-data": "^2.4.0", - "normalize-package-data": "^3.0.2", - "parse-json": "^5.2.0", - "type-fest": "^1.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/read-pkg-up": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-8.0.0.tgz", - "integrity": "sha512-snVCqPczksT0HS2EC+SxUndvSzn6LRCwpfSvLrIfR5BKDQQZMaI6jPRC9dYvYFDRAuFEAnkwww8kBBNE/3VvzQ==", - "dev": true, - "dependencies": { - "find-up": "^5.0.0", - "read-pkg": "^6.0.0", - "type-fest": "^1.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/read-pkg-up/node_modules/type-fest": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-1.4.0.tgz", - "integrity": "sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/read-pkg/node_modules/type-fest": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-1.4.0.tgz", - "integrity": "sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } + "node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", + "dev": true }, "node_modules/readdirp": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.1.tgz", + "integrity": "sha512-h80JrZu/MHUZCyHu5ciuoI0+WxsCxzxJTILn6Fs8rxSnFPh+UVHYfeIxK1nVGugMqkfC4vJcBOYbkfkwYK0+gw==", "dev": true, - "dependencies": { - "picomatch": "^2.2.1" - }, "engines": { - "node": ">=8.10.0" - } - }, - "node_modules/redent": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/redent/-/redent-4.0.0.tgz", - "integrity": "sha512-tYkDkVVtYkSVhuQ4zBgfvciymHaeuel+zFKXShfDnFP5SyVEP7qo70Rf1jTOTCx3vGNAbnEi/xFkcfQVMIBWag==", - "dev": true, - "dependencies": { - "indent-string": "^5.0.0", - "strip-indent": "^4.0.0" - }, - "engines": { - "node": ">=12" + "node": ">= 14.18.0" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/reflect.getprototypeof": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.10.tgz", + "integrity": "sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.9", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.7", + "get-proto": "^1.0.1", + "which-builtin-type": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, "node_modules/regexp.prototype.flags": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.1.tgz", - "integrity": "sha512-sy6TXMN+hnP/wMy+ISxg3krXx7BAtWVO4UouuCN/ziM9UEne0euamVNafDfvC83bRNr95y0V5iijeDQFUNpvrg==", + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.4.tgz", + "integrity": "sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==", "dev": true, "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "set-function-name": "^2.0.0" + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-errors": "^1.3.0", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "set-function-name": "^2.0.2" }, "engines": { "node": ">= 0.4" @@ -3663,18 +5271,21 @@ } }, "node_modules/resolve": { - "version": "1.22.8", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", - "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", + "version": "1.22.10", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz", + "integrity": "sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==", "dev": true, "dependencies": { - "is-core-module": "^2.13.0", + "is-core-module": "^2.16.0", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, "bin": { "resolve": "bin/resolve" }, + "engines": { + "node": ">= 0.4" + }, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -3707,45 +5318,10 @@ "node": ">=0.10.0" } }, - "node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dev": true, - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/rimraf/node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "dev": true, - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/rtlcss": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/rtlcss/-/rtlcss-4.1.1.tgz", - "integrity": "sha512-/oVHgBtnPNcggP2aVXQjSy6N1mMAfHg4GSag0QtZBlD5bdDgAHwr4pydqJGd+SUCu9260+Pjqbjwtvu7EMH1KQ==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/rtlcss/-/rtlcss-4.3.0.tgz", + "integrity": "sha512-FI+pHEn7Wc4NqKXMXFM+VAYKEj/mRIcW4h24YVwVtyjI+EqGrLc2Hx/Ny0lrZ21cBWU2goLy36eqMcNj3AQJig==", "dev": true, "dependencies": { "escalade": "^3.1.1", @@ -3799,14 +5375,15 @@ } }, "node_modules/safe-array-concat": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.0.1.tgz", - "integrity": "sha512-6XbUAseYE2KtOuGueyeobCySj9L4+66Tn6KQMOPQJrAJEowYKW/YR/MGJZl7FdydUdaFu4LYyDZjxf4/Nmo23Q==", + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.3.tgz", + "integrity": "sha512-AURm5f0jYEOydBj7VQlVvDrjeFgthDdEF5H1dP+6mNpoXOMo1quQqJ4wvJDyRZ9+pO3kGWoOdmV08cSv2aJV6Q==", "dev": true, "dependencies": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.2.1", - "has-symbols": "^1.0.3", + "call-bind": "^1.0.8", + "call-bound": "^1.0.2", + "get-intrinsic": "^1.2.6", + "has-symbols": "^1.1.0", "isarray": "^2.0.5" }, "engines": { @@ -3816,28 +5393,47 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/safe-regex-test": { + "node_modules/safe-push-apply": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.0.tgz", - "integrity": "sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA==", + "resolved": "https://registry.npmjs.org/safe-push-apply/-/safe-push-apply-1.0.0.tgz", + "integrity": "sha512-iKE9w/Z7xCzUMIZqdBsp6pEQvwuEebH4vdpjcDWnyzaI6yl6O9FHvVpmGelvEHNsoY6wGblkxR6Zty/h00WiSA==", "dev": true, "dependencies": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.1.3", - "is-regex": "^1.1.4" + "es-errors": "^1.3.0", + "isarray": "^2.0.5" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/safe-regex-test": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.1.0.tgz", + "integrity": "sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==", + "dev": true, + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "is-regex": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/sass": { - "version": "1.69.5", - "resolved": "https://registry.npmjs.org/sass/-/sass-1.69.5.tgz", - "integrity": "sha512-qg2+UCJibLr2LCVOt3OlPhr/dqVHWOa9XtZf2OjbLs/T4VPSJ00udtgJxH3neXZm+QqX8B+3cU7RaLqp1iVfcQ==", + "version": "1.89.2", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.89.2.tgz", + "integrity": "sha512-xCmtksBKd/jdJ9Bt9p7nPKiuqrlBMBuuGkQlkhZjjQk3Ty48lv93k5Dq6OPkKt4XwxDJ7tvlfrTa1MPA9bf+QA==", "dev": true, "dependencies": { - "chokidar": ">=3.0.0 <4.0.0", - "immutable": "^4.0.0", + "chokidar": "^4.0.0", + "immutable": "^5.0.2", "source-map-js": ">=0.6.2 <2.0.0" }, "bin": { @@ -3845,41 +5441,64 @@ }, "engines": { "node": ">=14.0.0" + }, + "optionalDependencies": { + "@parcel/watcher": "^2.4.1" } }, "node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", "dev": true, "bin": { "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" } }, "node_modules/set-function-length": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.1.1.tgz", - "integrity": "sha512-VoaqjbBJKiWtg4yRcKBQ7g7wnGnLV3M8oLvVWwOk2PdYY6PEFegR1vezXR0tw6fZGF9csVakIRjrJiy2veSBFQ==", + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", + "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", "dev": true, "dependencies": { - "define-data-property": "^1.1.1", - "get-intrinsic": "^1.2.1", + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", "gopd": "^1.0.1", - "has-property-descriptors": "^1.0.0" + "has-property-descriptors": "^1.0.2" }, "engines": { "node": ">= 0.4" } }, "node_modules/set-function-name": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.1.tgz", - "integrity": "sha512-tMNCiqYVkXIZgc2Hnoy2IvC/f8ezc5koaRFkCjrpWzGpCd3qbZXPzVy9MAZzK1ch/X0jvSkojys3oqJN0qCmdA==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz", + "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==", "dev": true, "dependencies": { - "define-data-property": "^1.0.1", + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", "functions-have-names": "^1.2.3", - "has-property-descriptors": "^1.0.0" + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/set-proto": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/set-proto/-/set-proto-1.0.0.tgz", + "integrity": "sha512-RJRdvCo6IAnPdsvP/7m6bsQqNnn1FCBX5ZNtFL98MmFF/4xAIJTIg1YbHW5DC2W5SKZanrC6i4HsJqlajw/dZw==", + "dev": true, + "dependencies": { + "dunder-proto": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0" }, "engines": { "node": ">= 0.4" @@ -3907,14 +5526,72 @@ } }, "node_modules/side-channel": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", - "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", + "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", "dev": true, "dependencies": { - "call-bind": "^1.0.0", - "get-intrinsic": "^1.0.2", - "object-inspect": "^1.9.0" + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3", + "side-channel-list": "^1.0.0", + "side-channel-map": "^1.0.1", + "side-channel-weakmap": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-list": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz", + "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", + "dev": true, + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-map": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", + "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", + "dev": true, + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-weakmap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", + "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", + "dev": true, + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3", + "side-channel-map": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -3958,45 +5635,32 @@ "url": "https://github.com/chalk/slice-ansi?sponsor=1" } }, + "node_modules/smol-toml": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/smol-toml/-/smol-toml-1.3.4.tgz", + "integrity": "sha512-UOPtVuYkzYGee0Bd2Szz8d2G3RfMfJ2t3qVdZUAozZyAk+a0Sxa+QKix0YCwjL/A1RR0ar44nCxaoN9FxdJGwA==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">= 18" + }, + "funding": { + "url": "https://github.com/sponsors/cyyynthia" + } + }, "node_modules/source-map-js": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", - "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", "dev": true, "engines": { "node": ">=0.10.0" } }, - "node_modules/spdx-correct": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz", - "integrity": "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==", - "dev": true, - "dependencies": { - "spdx-expression-parse": "^3.0.0", - "spdx-license-ids": "^3.0.0" - } - }, - "node_modules/spdx-exceptions": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", - "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==", - "dev": true - }, - "node_modules/spdx-expression-parse": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", - "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", - "dev": true, - "dependencies": { - "spdx-exceptions": "^2.1.0", - "spdx-license-ids": "^3.0.0" - } - }, - "node_modules/spdx-license-ids": { - "version": "3.0.16", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.16.tgz", - "integrity": "sha512-eWN+LnM3GR6gPu35WxNgbGl8rmY1AEmoMDvL/QD6zYmPWgywxWqJWNdLGT+ke8dKNWrcYgYjPpG5gbTfghP8rw==", + "node_modules/stable-hash": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/stable-hash/-/stable-hash-0.0.4.tgz", + "integrity": "sha512-LjdcbuBeLcdETCrPn9i8AYAZ1eCtu4ECAWtP7UleOiZ9LzVxRzzUZEoZ8zB24nhkQnDWyET0I+3sWokSDS3E7g==", "dev": true }, "node_modules/string-width": { @@ -4004,6 +5668,7 @@ "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", "dev": true, + "license": "MIT", "dependencies": { "eastasianwidth": "^0.2.0", "emoji-regex": "^9.2.2", @@ -4022,6 +5687,7 @@ "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "dev": true, + "license": "MIT", "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", @@ -4035,13 +5701,15 @@ "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/string-width/node_modules/ansi-regex": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", - "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", + "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", "dev": true, + "license": "MIT", "engines": { "node": ">=12" }, @@ -4054,6 +5722,7 @@ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", "dev": true, + "license": "MIT", "dependencies": { "ansi-regex": "^6.0.1" }, @@ -4064,15 +5733,56 @@ "url": "https://github.com/chalk/strip-ansi?sponsor=1" } }, - "node_modules/string.prototype.trim": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.8.tgz", - "integrity": "sha512-lfjY4HcixfQXOfaqCvcBuOIapyaroTXhbkfJN3gcB1OtyupngWK4sEET9Knd0cXd28kTUqu/kHoV4HKSJdnjiQ==", + "node_modules/string.prototype.matchall": { + "version": "4.0.12", + "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.12.tgz", + "integrity": "sha512-6CC9uyBL+/48dYizRf7H7VAYCMCNTBeM78x/VTUe9bFEaxBepPJDa1Ow99LqI/1yF7kuy7Q3cQsYMrcjGUcskA==", "dev": true, "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1" + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.6", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.6", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "internal-slot": "^1.1.0", + "regexp.prototype.flags": "^1.5.3", + "set-function-name": "^2.0.2", + "side-channel": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.repeat": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/string.prototype.repeat/-/string.prototype.repeat-1.0.0.tgz", + "integrity": "sha512-0u/TldDbKD8bFCQ/4f5+mNRrXwZ8hg2w7ZR8wa16e8z9XpePWl3eGEcUD0OXpEH/VJH/2G3gjUtR3ZOiBe2S/w==", + "dev": true, + "dependencies": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.5" + } + }, + "node_modules/string.prototype.trim": { + "version": "1.2.10", + "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.10.tgz", + "integrity": "sha512-Rs66F0P/1kedk5lyYyH9uBzuiI/kNRmwJAR9quK6VOtIpZ2G+hMZd+HQbbv25MgCA6gEffoMZYxlTod4WcdrKA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.2", + "define-data-property": "^1.1.4", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-object-atoms": "^1.0.0", + "has-property-descriptors": "^1.0.2" }, "engines": { "node": ">= 0.4" @@ -4082,28 +5792,35 @@ } }, "node_modules/string.prototype.trimend": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.7.tgz", - "integrity": "sha512-Ni79DqeB72ZFq1uH/L6zJ+DKZTkOtPIHovb3YZHQViE+HDouuU4mBrLOLDn5Dde3RF8qw5qVETEjhu9locMLvA==", + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.9.tgz", + "integrity": "sha512-G7Ok5C6E/j4SGfyLCloXTrngQIQU3PWtXGst3yM7Bea9FRURf1S42ZHlZZtsNque2FN2PoUhfZXYLNWwEr4dLQ==", "dev": true, "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1" + "call-bind": "^1.0.8", + "call-bound": "^1.0.2", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/string.prototype.trimstart": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.7.tgz", - "integrity": "sha512-NGhtDFu3jCEm7B4Fy0DpLewdJQOZcQ0rGbwQ/+stjnrp2i+rlKeCvos9hOIeCmqwratM47OBxY7uFZzjxHXmrg==", + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz", + "integrity": "sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==", "dev": true, "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1" + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -4127,6 +5844,7 @@ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dev": true, + "license": "MIT", "dependencies": { "ansi-regex": "^5.0.1" }, @@ -4134,30 +5852,6 @@ "node": ">=8" } }, - "node_modules/strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/strip-indent": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-4.0.0.tgz", - "integrity": "sha512-mnVSV2l+Zv6BLpSD/8V87CW/y9EmmbYzGCIavsnsI6/nwn26DwffM/yztm30Z/I2DY9wdS3vXVCMnHDgZaVNoA==", - "dev": true, - "dependencies": { - "min-indent": "^1.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/strip-json-comments": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", @@ -4177,88 +5871,107 @@ "dev": true }, "node_modules/stylelint": { - "version": "15.11.0", - "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-15.11.0.tgz", - "integrity": "sha512-78O4c6IswZ9TzpcIiQJIN49K3qNoXTM8zEJzhaTE/xRTCZswaovSEVIa/uwbOltZrk16X4jAxjaOhzz/hTm1Kw==", + "version": "16.21.0", + "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-16.21.0.tgz", + "integrity": "sha512-ki3PpJGG7xhm3WtINoWGnlvqAmbqSexoRMbEMJzlwewSIOqPRKPlq452c22xAdEJISVi80r+I7KL9GPUiwFgbg==", "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/stylelint" + }, + { + "type": "github", + "url": "https://github.com/sponsors/stylelint" + } + ], "dependencies": { - "@csstools/css-parser-algorithms": "^2.3.1", - "@csstools/css-tokenizer": "^2.2.0", - "@csstools/media-query-list-parser": "^2.1.4", - "@csstools/selector-specificity": "^3.0.0", + "@csstools/css-parser-algorithms": "^3.0.5", + "@csstools/css-tokenizer": "^3.0.4", + "@csstools/media-query-list-parser": "^4.0.3", + "@csstools/selector-specificity": "^5.0.0", + "@dual-bundle/import-meta-resolve": "^4.1.0", "balanced-match": "^2.0.0", "colord": "^2.9.3", - "cosmiconfig": "^8.2.0", - "css-functions-list": "^3.2.1", - "css-tree": "^2.3.1", - "debug": "^4.3.4", - "fast-glob": "^3.3.1", + "cosmiconfig": "^9.0.0", + "css-functions-list": "^3.2.3", + "css-tree": "^3.1.0", + "debug": "^4.4.1", + "fast-glob": "^3.3.3", "fastest-levenshtein": "^1.0.16", - "file-entry-cache": "^7.0.0", + "file-entry-cache": "^10.1.1", "global-modules": "^2.0.0", "globby": "^11.1.0", "globjoin": "^0.1.4", "html-tags": "^3.3.1", - "ignore": "^5.2.4", - "import-lazy": "^4.0.0", + "ignore": "^7.0.5", "imurmurhash": "^0.1.4", "is-plain-object": "^5.0.0", - "known-css-properties": "^0.29.0", + "known-css-properties": "^0.37.0", "mathml-tag-names": "^2.1.3", - "meow": "^10.1.5", - "micromatch": "^4.0.5", + "meow": "^13.2.0", + "micromatch": "^4.0.8", "normalize-path": "^3.0.0", - "picocolors": "^1.0.0", - "postcss": "^8.4.28", - "postcss-resolve-nested-selector": "^0.1.1", - "postcss-safe-parser": "^6.0.0", - "postcss-selector-parser": "^6.0.13", + "picocolors": "^1.1.1", + "postcss": "^8.5.5", + "postcss-resolve-nested-selector": "^0.1.6", + "postcss-safe-parser": "^7.0.1", + "postcss-selector-parser": "^7.1.0", "postcss-value-parser": "^4.2.0", "resolve-from": "^5.0.0", "string-width": "^4.2.3", - "strip-ansi": "^6.0.1", - "style-search": "^0.1.0", - "supports-hyperlinks": "^3.0.0", + "supports-hyperlinks": "^3.2.0", "svg-tags": "^1.0.0", - "table": "^6.8.1", + "table": "^6.9.0", "write-file-atomic": "^5.0.1" }, "bin": { "stylelint": "bin/stylelint.mjs" }, "engines": { - "node": "^14.13.1 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/stylelint" + "node": ">=18.12.0" } }, "node_modules/stylelint-config-recommended": { - "version": "13.0.0", - "resolved": "https://registry.npmjs.org/stylelint-config-recommended/-/stylelint-config-recommended-13.0.0.tgz", - "integrity": "sha512-EH+yRj6h3GAe/fRiyaoO2F9l9Tgg50AOFhaszyfov9v6ayXJ1IkSHwTxd7lB48FmOeSGDPLjatjO11fJpmarkQ==", + "version": "16.0.0", + "resolved": "https://registry.npmjs.org/stylelint-config-recommended/-/stylelint-config-recommended-16.0.0.tgz", + "integrity": "sha512-4RSmPjQegF34wNcK1e1O3Uz91HN8P1aFdFzio90wNK9mjgAI19u5vsU868cVZboKzCaa5XbpvtTzAAGQAxpcXA==", "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/stylelint" + }, + { + "type": "github", + "url": "https://github.com/sponsors/stylelint" + } + ], + "license": "MIT", "engines": { - "node": "^14.13.1 || >=16.0.0" + "node": ">=18.12.0" }, "peerDependencies": { - "stylelint": "^15.10.0" + "stylelint": "^16.16.0" } }, "node_modules/stylelint-config-recommended-scss": { - "version": "13.1.0", - "resolved": "https://registry.npmjs.org/stylelint-config-recommended-scss/-/stylelint-config-recommended-scss-13.1.0.tgz", - "integrity": "sha512-8L5nDfd+YH6AOoBGKmhH8pLWF1dpfY816JtGMePcBqqSsLU+Ysawx44fQSlMOJ2xTfI9yTGpup5JU77c17w1Ww==", + "version": "15.0.1", + "resolved": "https://registry.npmjs.org/stylelint-config-recommended-scss/-/stylelint-config-recommended-scss-15.0.1.tgz", + "integrity": "sha512-V24bxkNkFGggqPVJlP9iXaBabwSGEG7QTz+PyxrRtjPkcF+/NsWtB3tKYvFYEmczRkWiIEfuFMhGpJFj9Fxe6Q==", "dev": true, + "license": "MIT", "dependencies": { "postcss-scss": "^4.0.9", - "stylelint-config-recommended": "^13.0.0", - "stylelint-scss": "^5.3.0" + "stylelint-config-recommended": "^16.0.0", + "stylelint-scss": "^6.12.0" + }, + "engines": { + "node": ">=20" }, "peerDependencies": { "postcss": "^8.3.3", - "stylelint": "^15.10.0" + "stylelint": "^16.16.0" }, "peerDependenciesMeta": { "postcss": { @@ -4267,48 +5980,109 @@ } }, "node_modules/stylelint-order": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/stylelint-order/-/stylelint-order-6.0.3.tgz", - "integrity": "sha512-1j1lOb4EU/6w49qZeT2SQVJXm0Ht+Qnq9GMfUa3pMwoyojIWfuA+JUDmoR97Bht1RLn4ei0xtLGy87M7d29B1w==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/stylelint-order/-/stylelint-order-7.0.0.tgz", + "integrity": "sha512-rSWxx0KscYfxU02wEskKXES9lkRzuuONMMNkZ7SUc6uiF3tDKm7e+sE0Ax/SBlG4TUf1sp1R6f3/SlsPGmzthg==", "dev": true, + "license": "MIT", "dependencies": { - "postcss": "^8.4.21", - "postcss-sorting": "^8.0.2" + "postcss": "^8.5.3", + "postcss-sorting": "^9.1.0" + }, + "engines": { + "node": ">=20.19.0" }, "peerDependencies": { - "stylelint": "^14.0.0 || ^15.0.0" + "stylelint": "^16.18.0" } }, "node_modules/stylelint-scss": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/stylelint-scss/-/stylelint-scss-5.3.1.tgz", - "integrity": "sha512-5I9ZDIm77BZrjOccma5WyW2nJEKjXDd4Ca8Kk+oBapSO4pewSlno3n+OyimcyVJJujQZkBN2D+xuMkIamSc6hA==", + "version": "6.12.0", + "resolved": "https://registry.npmjs.org/stylelint-scss/-/stylelint-scss-6.12.0.tgz", + "integrity": "sha512-U7CKhi1YNkM1pXUXl/GMUXi8xKdhl4Ayxdyceie1nZ1XNIdaUgMV6OArpooWcDzEggwgYD0HP/xIgVJo9a655w==", "dev": true, + "license": "MIT", "dependencies": { - "known-css-properties": "^0.29.0", + "css-tree": "^3.0.1", + "is-plain-object": "^5.0.0", + "known-css-properties": "^0.36.0", + "mdn-data": "^2.21.0", "postcss-media-query-parser": "^0.2.3", - "postcss-resolve-nested-selector": "^0.1.1", - "postcss-selector-parser": "^6.0.13", + "postcss-resolve-nested-selector": "^0.1.6", + "postcss-selector-parser": "^7.1.0", "postcss-value-parser": "^4.2.0" }, - "peerDependencies": { - "stylelint": "^14.5.1 || ^15.0.0" - } - }, - "node_modules/stylelint-stylistic": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/stylelint-stylistic/-/stylelint-stylistic-0.4.3.tgz", - "integrity": "sha512-WphmneK3MRrm5ixvRPWy7+c9+EQUh0FPvNMXW/N9VD85vyqtpxUejpD+mxubVVht0fRgidcqBxtW3s3tU2Ujhw==", - "dev": true, - "dependencies": { - "is-plain-object": "^5.0.0", - "postcss": "^8.4.21", - "postcss-media-query-parser": "^0.2.3", - "postcss-value-parser": "^4.2.0", - "style-search": "^0.1.0" + "engines": { + "node": ">=18.12.0" }, "peerDependencies": { - "stylelint": "^15.0.0" + "stylelint": "^16.0.2" + } + }, + "node_modules/stylelint-scss/node_modules/mdn-data": { + "version": "2.21.0", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.21.0.tgz", + "integrity": "sha512-+ZKPQezM5vYJIkCxaC+4DTnRrVZR1CgsKLu5zsQERQx6Tea8Y+wMx5A24rq8A8NepCeatIQufVAekKNgiBMsGQ==", + "dev": true, + "license": "CC0-1.0" + }, + "node_modules/stylelint-scss/node_modules/postcss-selector-parser": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.0.tgz", + "integrity": "sha512-8sLjZwK0R+JlxlYcTuVnyT2v+htpdrjDOKuMcOVdYjt52Lh8hWRYpxBPoKx/Zg+bcjc3wx6fmQevMmUztS/ccA==", + "dev": true, + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/stylelint/node_modules/@csstools/media-query-list-parser": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/@csstools/media-query-list-parser/-/media-query-list-parser-4.0.3.tgz", + "integrity": "sha512-HAYH7d3TLRHDOUQK4mZKf9k9Ph/m8Akstg66ywKR4SFAigjs3yBiUeZtFxywiTm5moZMAp/5W/ZuFnNXXYLuuQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@csstools/css-parser-algorithms": "^3.0.5", + "@csstools/css-tokenizer": "^3.0.4" + } + }, + "node_modules/stylelint/node_modules/@csstools/selector-specificity": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@csstools/selector-specificity/-/selector-specificity-5.0.0.tgz", + "integrity": "sha512-PCqQV3c4CoVm3kdPhyeZ07VmBRdH2EpMFA/pd9OASpOEC3aXNGoqPDAZ80D0cLpMBxnmk0+yNhGsEx31hq7Gtw==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss-selector-parser": "^7.0.0" } }, "node_modules/stylelint/node_modules/balanced-match": { @@ -4324,15 +6098,53 @@ "dev": true }, "node_modules/stylelint/node_modules/file-entry-cache": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-7.0.2.tgz", - "integrity": "sha512-TfW7/1iI4Cy7Y8L6iqNdZQVvdXn0f8B4QcIXmkIbtTIe/Okm/nSlHb4IwGzRVOd3WfSieCgvf5cMzEfySAIl0g==", + "version": "10.1.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-10.1.1.tgz", + "integrity": "sha512-zcmsHjg2B2zjuBgjdnB+9q0+cWcgWfykIcsDkWDB4GTPtl1eXUA+gTI6sO0u01AqK3cliHryTU55/b2Ow1hfZg==", "dev": true, "dependencies": { - "flat-cache": "^3.2.0" + "flat-cache": "^6.1.10" + } + }, + "node_modules/stylelint/node_modules/flat-cache": { + "version": "6.1.11", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-6.1.11.tgz", + "integrity": "sha512-zfOAns94mp7bHG/vCn9Ru2eDCmIxVQ5dELUHKjHfDEOJmHNzE+uGa6208kfkgmtym4a0FFjEuFksCXFacbVhSg==", + "dev": true, + "dependencies": { + "cacheable": "^1.10.1", + "flatted": "^3.3.3", + "hookified": "^1.10.0" + } + }, + "node_modules/stylelint/node_modules/ignore": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.5.tgz", + "integrity": "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/stylelint/node_modules/known-css-properties": { + "version": "0.37.0", + "resolved": "https://registry.npmjs.org/known-css-properties/-/known-css-properties-0.37.0.tgz", + "integrity": "sha512-JCDrsP4Z1Sb9JwG0aJ8Eo2r7k4Ou5MwmThS/6lcIe1ICyb7UBJKGRIUUdqc2ASdE/42lgz6zFUnzAIhtXnBVrQ==", + "dev": true + }, + "node_modules/stylelint/node_modules/postcss-selector-parser": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.0.tgz", + "integrity": "sha512-8sLjZwK0R+JlxlYcTuVnyT2v+htpdrjDOKuMcOVdYjt52Lh8hWRYpxBPoKx/Zg+bcjc3wx6fmQevMmUztS/ccA==", + "dev": true, + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" }, "engines": { - "node": ">=12.0.0" + "node": ">=4" } }, "node_modules/stylelint/node_modules/resolve-from": { @@ -4371,16 +6183,20 @@ } }, "node_modules/supports-hyperlinks": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-3.0.0.tgz", - "integrity": "sha512-QBDPHyPQDRTy9ku4URNGY5Lah8PAaXs6tAAwp55sL5WCsSW7GIfdf6W5ixfziW+t7wh3GVvHyHHyQ1ESsoRvaA==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-3.2.0.tgz", + "integrity": "sha512-zFObLMyZeEwzAoKCyu1B91U79K2t7ApXuQfo8OuxwXLDgcKxuwM+YvcbIhm6QWqz7mHUH1TVytR1PwVVjEuMig==", "dev": true, + "license": "MIT", "dependencies": { "has-flag": "^4.0.0", "supports-color": "^7.0.0" }, "engines": { "node": ">=14.18" + }, + "funding": { + "url": "https://github.com/chalk/supports-hyperlinks?sponsor=1" } }, "node_modules/supports-preserve-symlinks-flag": { @@ -4402,9 +6218,9 @@ "dev": true }, "node_modules/table": { - "version": "6.8.1", - "resolved": "https://registry.npmjs.org/table/-/table-6.8.1.tgz", - "integrity": "sha512-Y4X9zqrCftUhMeH2EptSSERdVKt/nEdijTOacGD/97EKjhQ/Qs8RTlEGABSJNNN8lac9kheH+af7yAkEWlgneA==", + "version": "6.9.0", + "resolved": "https://registry.npmjs.org/table/-/table-6.9.0.tgz", + "integrity": "sha512-9kY+CygyYM6j02t5YFHbNz2FN5QmYGv9zAjVp4lCDjlCw7amdckXlEt/bjMhUIfj4ThGRE4gCUH5+yGnNuPo5A==", "dev": true, "dependencies": { "ajv": "^8.0.1", @@ -4418,15 +6234,15 @@ } }, "node_modules/table/node_modules/ajv": { - "version": "8.12.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", - "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", "dev": true, "dependencies": { - "fast-deep-equal": "^3.1.1", + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" + "require-from-string": "^2.0.2" }, "funding": { "type": "github", @@ -4459,11 +6275,14 @@ "node": ">=8" } }, - "node_modules/text-table": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", - "dev": true + "node_modules/tapable": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", + "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==", + "dev": true, + "engines": { + "node": ">=6" + } }, "node_modules/to-regex-range": { "version": "5.0.1", @@ -4477,29 +6296,23 @@ "node": ">=8.0" } }, - "node_modules/trim-newlines": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-4.1.1.tgz", - "integrity": "sha512-jRKj0n0jXWo6kh62nA5TEh3+4igKDXLvzBJcPpiizP7oOolUrYIxmVBG9TOtHYFHoddUk6YvAkGeGoSVTXfQXQ==", + "node_modules/ts-api-utils": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.0.0.tgz", + "integrity": "sha512-xCt/TOAc+EOHS1XPnijD3/yzpH6qg2xppZO1YDqGoVsNXfQfzHpOdNuXwrwOU8u4ITXJyDCTyt8w5g1sZv9ynQ==", "dev": true, "engines": { - "node": ">=12" + "node": ">=18.12" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "peerDependencies": { + "typescript": ">=4.8.4" } }, - "node_modules/tsconfig-paths": { - "version": "3.14.2", - "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.14.2.tgz", - "integrity": "sha512-o/9iXgCYc5L/JxCHPe3Hvh8Q/2xm5Z+p18PESBU6Ff33695QnCHBEjcytY2q19ua7Mbl/DavtBOLq+oG0RCL+g==", - "dev": true, - "dependencies": { - "@types/json5": "^0.0.29", - "json5": "^1.0.2", - "minimist": "^1.2.6", - "strip-bom": "^3.0.0" - } + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "dev": true }, "node_modules/type-check": { "version": "0.4.0", @@ -4513,42 +6326,31 @@ "node": ">= 0.8.0" } }, - "node_modules/type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/typed-array-buffer": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.0.tgz", - "integrity": "sha512-Y8KTSIglk9OZEr8zywiIHG/kmQ7KWyjseXs1CbSo8vC42w7hg2HgYTxSWwP0+is7bWDc1H+Fo026CpHFwm8tkw==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.3.tgz", + "integrity": "sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==", "dev": true, "dependencies": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.2.1", - "is-typed-array": "^1.1.10" + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "is-typed-array": "^1.1.14" }, "engines": { "node": ">= 0.4" } }, "node_modules/typed-array-byte-length": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.0.tgz", - "integrity": "sha512-Or/+kvLxNpeQ9DtSydonMxCx+9ZXOswtwJn17SNLvhptaXYDJvkFFP5zbfU/uLmvnBJlI4yrnXRxpdWH/M5tNA==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.3.tgz", + "integrity": "sha512-BaXgOuIxz8n8pIq3e7Atg/7s+DpiYrxn4vdot3w9KbnBhcRQq6o3xemQdIfynqSeXeDrF32x+WvfzmOjPiY9lg==", "dev": true, "dependencies": { - "call-bind": "^1.0.2", + "call-bind": "^1.0.8", "for-each": "^0.3.3", - "has-proto": "^1.0.1", - "is-typed-array": "^1.1.10" + "gopd": "^1.2.0", + "has-proto": "^1.2.0", + "is-typed-array": "^1.1.14" }, "engines": { "node": ">= 0.4" @@ -4558,16 +6360,18 @@ } }, "node_modules/typed-array-byte-offset": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.0.tgz", - "integrity": "sha512-RD97prjEt9EL8YgAgpOkf3O4IF9lhJFr9g0htQkm0rchFp/Vx7LW5Q8fSXXub7BXAODyUQohRMyOc3faCPd0hg==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.4.tgz", + "integrity": "sha512-bTlAFB/FBYMcuX81gbL4OcpH5PmlFHqlCCpAl8AlEzMz5k53oNDvN8p1PNOWLEmI2x4orp3raOFB51tv9X+MFQ==", "dev": true, "dependencies": { - "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.2", + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.8", "for-each": "^0.3.3", - "has-proto": "^1.0.1", - "is-typed-array": "^1.1.10" + "gopd": "^1.2.0", + "has-proto": "^1.2.0", + "is-typed-array": "^1.1.15", + "reflect.getprototypeof": "^1.0.9" }, "engines": { "node": ">= 0.4" @@ -4577,35 +6381,81 @@ } }, "node_modules/typed-array-length": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.4.tgz", - "integrity": "sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng==", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.7.tgz", + "integrity": "sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg==", "dev": true, "dependencies": { - "call-bind": "^1.0.2", + "call-bind": "^1.0.7", "for-each": "^0.3.3", - "is-typed-array": "^1.1.9" + "gopd": "^1.0.1", + "is-typed-array": "^1.1.13", + "possible-typed-array-names": "^1.0.0", + "reflect.getprototypeof": "^1.0.6" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/uc.micro": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz", - "integrity": "sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==", - "dev": true + "node_modules/typescript": { + "version": "5.5.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.4.tgz", + "integrity": "sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==", + "dev": true, + "peer": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } }, - "node_modules/unbox-primitive": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", - "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", + "node_modules/typescript-eslint": { + "version": "8.20.0", + "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.20.0.tgz", + "integrity": "sha512-Kxz2QRFsgbWj6Xcftlw3Dd154b3cEPFqQC+qMZrMypSijPd4UanKKvoKDrJ4o8AIfZFKAF+7sMaEIR8mTElozA==", "dev": true, "dependencies": { - "call-bind": "^1.0.2", + "@typescript-eslint/eslint-plugin": "8.20.0", + "@typescript-eslint/parser": "8.20.0", + "@typescript-eslint/utils": "8.20.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <5.8.0" + } + }, + "node_modules/uc.micro": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-2.1.0.tgz", + "integrity": "sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==", + "dev": true, + "license": "MIT" + }, + "node_modules/unbox-primitive": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.1.0.tgz", + "integrity": "sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==", + "dev": true, + "dependencies": { + "call-bound": "^1.0.3", "has-bigints": "^1.0.2", - "has-symbols": "^1.0.3", - "which-boxed-primitive": "^1.0.2" + "has-symbols": "^1.1.0", + "which-boxed-primitive": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -4616,6 +6466,7 @@ "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "punycode": "^2.1.0" } @@ -4626,16 +6477,6 @@ "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", "dev": true }, - "node_modules/validate-npm-package-license": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", - "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", - "dev": true, - "dependencies": { - "spdx-correct": "^3.0.0", - "spdx-expression-parse": "^3.0.0" - } - }, "node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", @@ -4652,32 +6493,16 @@ } }, "node_modules/which-boxed-primitive": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", - "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.1.1.tgz", + "integrity": "sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==", "dev": true, "dependencies": { - "is-bigint": "^1.0.1", - "is-boolean-object": "^1.1.0", - "is-number-object": "^1.0.4", - "is-string": "^1.0.5", - "is-symbol": "^1.0.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/which-typed-array": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.13.tgz", - "integrity": "sha512-P5Nra0qjSncduVPEAr7xhoF5guty49ArDTwzJ/yNuPIbZppyRxFQsRCWrocxIY+CnMVG+qfbU2FmDKyvSGClow==", - "dev": true, - "dependencies": { - "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.4", - "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-tostringtag": "^1.0.0" + "is-bigint": "^1.1.0", + "is-boolean-object": "^1.2.1", + "is-number-object": "^1.1.1", + "is-string": "^1.1.1", + "is-symbol": "^1.1.1" }, "engines": { "node": ">= 0.4" @@ -4686,11 +6511,86 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/which-builtin-type": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/which-builtin-type/-/which-builtin-type-1.2.1.tgz", + "integrity": "sha512-6iBczoX+kDQ7a3+YJBnh3T+KZRxM/iYNPXicqk66/Qfm1b93iu+yOImkg0zHbj5LNOcNv1TEADiZ0xa34B4q6Q==", + "dev": true, + "dependencies": { + "call-bound": "^1.0.2", + "function.prototype.name": "^1.1.6", + "has-tostringtag": "^1.0.2", + "is-async-function": "^2.0.0", + "is-date-object": "^1.1.0", + "is-finalizationregistry": "^1.1.0", + "is-generator-function": "^1.0.10", + "is-regex": "^1.2.1", + "is-weakref": "^1.0.2", + "isarray": "^2.0.5", + "which-boxed-primitive": "^1.1.0", + "which-collection": "^1.0.2", + "which-typed-array": "^1.1.16" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-collection": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-collection/-/which-collection-1.0.2.tgz", + "integrity": "sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==", + "dev": true, + "dependencies": { + "is-map": "^2.0.3", + "is-set": "^2.0.3", + "is-weakmap": "^2.0.2", + "is-weakset": "^2.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-typed-array": { + "version": "1.1.18", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.18.tgz", + "integrity": "sha512-qEcY+KJYlWyLH9vNbsr6/5j59AXk5ni5aakf8ldzBvGde6Iz4sxZGkJyWSAueTG7QhOvNRYb1lDdFmL5Td0QKA==", + "dev": true, + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "for-each": "^0.3.3", + "gopd": "^1.2.0", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/word-wrap": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/wrap-ansi": { "version": "8.1.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", "dev": true, + "license": "MIT", "dependencies": { "ansi-styles": "^6.1.0", "string-width": "^5.0.1", @@ -4709,6 +6609,7 @@ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", "dev": true, + "license": "MIT", "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", @@ -4725,13 +6626,15 @@ "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/wrap-ansi-cjs/node_modules/string-width": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "dev": true, + "license": "MIT", "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", @@ -4742,10 +6645,11 @@ } }, "node_modules/wrap-ansi/node_modules/ansi-regex": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", - "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", + "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", "dev": true, + "license": "MIT", "engines": { "node": ">=12" }, @@ -4758,6 +6662,7 @@ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", "dev": true, + "license": "MIT", "engines": { "node": ">=12" }, @@ -4770,6 +6675,7 @@ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", "dev": true, + "license": "MIT", "dependencies": { "ansi-regex": "^6.0.1" }, @@ -4780,12 +6686,6 @@ "url": "https://github.com/chalk/strip-ansi?sponsor=1" } }, - "node_modules/wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "dev": true - }, "node_modules/write-file-atomic": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-5.0.1.tgz", @@ -4799,21 +6699,6 @@ "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, - "node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - }, - "node_modules/yargs-parser": { - "version": "20.2.9", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", - "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", - "dev": true, - "engines": { - "node": ">=10" - } - }, "node_modules/yocto-queue": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", diff --git a/package.json b/package.json index bb63ff0..316f9ff 100644 --- a/package.json +++ b/package.json @@ -1,5 +1,6 @@ { "name": "freshrss-extensions", + "type": "module", "description": "Extensions for FreshRSS", "homepage": "https://freshrss.org/", "readmeFilename": "README.md", @@ -16,11 +17,11 @@ }, "license": "see each extension", "engines": { - "node": ">=12" + "node": ">=18" }, "scripts": { - "eslint": "eslint --ext .js .", - "eslint_fix": "eslint --fix --ext .js .", + "eslint": "eslint .", + "eslint_fix": "eslint --fix .", "markdownlint": "markdownlint '**/*.md'", "markdownlint_fix": "markdownlint --fix '**/*.md'", "rtlcss": "npm run symbolic && rtlcss -d symbolic/ && find -L symbolic/ -type f -name '*.rtl.rtl.css' -delete", @@ -31,18 +32,17 @@ "fix": "npm run rtlcss && npm run stylelint_fix && npm run eslint_fix && npm run markdownlint_fix" }, "devDependencies": { - "eslint": "^8.54.0", - "eslint-config-standard": "^17.1.0", - "eslint-plugin-import": "^2.29.0", - "eslint-plugin-n": "^16.3.1", - "eslint-plugin-promise": "^6.1.1", - "markdownlint-cli": "^0.37.0", - "rtlcss": "^4.1.1", - "sass": "^1.69.5", - "stylelint": "^15.11.0", - "stylelint-config-recommended-scss": "^13.1.0", - "stylelint-order": "^6.0.3", - "stylelint-stylistic": "^0.4.3" + "eslint": "^9.30.1", + "@eslint/js": "^9.8.0", + "globals": "^16.3.0", + "markdownlint-cli": "^0.45.0", + "neostandard": "^0.12.1", + "rtlcss": "^4.3.0", + "sass": "^1.89.2", + "stylelint": "^16.21.0", + "stylelint-config-recommended-scss": "^15.0.1", + "stylelint-order": "^7.0.0", + "@stylistic/stylelint-plugin": "^3.1.3" }, "rtlcssConfig": {} } diff --git a/phpcs.xml b/phpcs.xml index 41dbfcd..6b28068 100644 --- a/phpcs.xml +++ b/phpcs.xml @@ -1,119 +1,113 @@ - - Created with the PHP Coding Standard Generator. https://edorian.github.com/php-coding-standard-generator/ - + + - ./lib/SimplePie/ - ./lib/PHPMailer/ - ./lib/http-conditional.php - ./lib/lib_phpQuery.php - ./node_modules/ + ./.git/ ./data/config.php + ./data/update.php ./data/users/*/config.php ./extensions/ + ./lib/http-conditional.php + ./lib/marienfressinaud/ + ./lib/phpgt/ + ./lib/phpmailer/ + ./lib/simplepie/ + ./node_modules/ ./p/scripts/vendor/ ./vendor/ - *.min.js$ - + + ./symbolic/ + ./third-party/ + ./tmp/ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - ./app/i18n/ - - *.phtml$ + /app/i18n/*\.php$ + *\.phtml$ - - - - - - - - - - - - - - - - + + - - - - - - - - - - - - - - - + + *\.phtml$ + /app/install.php - - - + + *\.phtml$ + /app/install.php + + + *\.phtml$ + + + - - - - - - - - + *\.phtml$ - + - - - + + *\.php$ + + + + *\.phtml$ + - + - + + *\.phtml$ + - - - - - .phtml$ - - - - - - .phtml$ - .js$ - - - - .phtml$ - diff --git a/phpstan-third-party.neon b/phpstan-third-party.neon new file mode 100644 index 0000000..d616007 --- /dev/null +++ b/phpstan-third-party.neon @@ -0,0 +1,27 @@ +parameters: + phpVersion: + min: 80100 # PHP 8.1 + max: 80499 # PHP 8.4 + level: 0 # https://phpstan.org/user-guide/rule-levels + fileExtensions: + - php + - phtml + paths: + - ../FreshRSS + - third-party/ + excludePaths: + analyse: + - ../FreshRSS + - third-party/*/vendor/*? + analyseAndScan: + - .git/*? + - node_modules/*? + - symbolic/*? + - third-party/*/tests/*? + - tmp/*? + - vendor/ + - xExtension-* + dynamicConstantNames: + - TYPE_GIT + reportMaybesInPropertyPhpDocTypes: false + treatPhpDocTypesAsCertain: false diff --git a/phpstan.dist.neon b/phpstan.dist.neon new file mode 100644 index 0000000..8146830 --- /dev/null +++ b/phpstan.dist.neon @@ -0,0 +1,43 @@ +parameters: + phpVersion: + min: 80100 # PHP 8.1 + max: 80499 # PHP 8.4 + level: 10 # https://phpstan.org/user-guide/rule-levels + fileExtensions: + - php + - phtml + paths: + - ../FreshRSS + - . + excludePaths: + analyse: + - ../FreshRSS + analyseAndScan: + - .git/*? + - node_modules/*? + - symbolic/*? + - third-party/*? + - tmp/*? + - vendor/ + dynamicConstantNames: + - TYPE_GIT + checkBenevolentUnionTypes: true + checkMissingOverrideMethodAttribute: true + checkTooWideReturnTypesInProtectedAndPublicMethods: true + reportAnyTypeWideningInVarTag: true + treatPhpDocTypesAsCertain: false + strictRules: + disallowedEmpty: false + disallowedLooseComparison: false + disallowedShortTernary: false + exceptions: + check: + missingCheckedExceptionInThrows: true + tooWideThrowType: true + implicitThrows: false + checkedExceptionClasses: + - 'Minz_Exception' + ignoreErrors: + - '#Only booleans are allowed in (a negated boolean|a ternary operator condition|an elseif condition|an if condition|&&|\|\|), (bool|false|int(<[0-9, max]+>)?|true|null|\|)+ given.*#' +includes: + - vendor/phpstan/phpstan-strict-rules/rules.neon diff --git a/phpstan.neon b/phpstan.neon deleted file mode 100644 index 8cac860..0000000 --- a/phpstan.neon +++ /dev/null @@ -1,39 +0,0 @@ -parameters: - # TODO: Increase rule-level https://phpstan.org/user-guide/rule-levels - level: 1 - treatPhpDocTypesAsCertain: false - fileExtensions: - - php - - phtml - paths: - - ../FreshRSS - - . - excludePaths: - analyse: - - ../FreshRSS - - vendor/ - analyseAndScan: - - .git/ - - node_modules/ - - symbolic/ - - tmp/ - - xExtension-TTRSS_API/ - dynamicConstantNames: - - TYPE_GIT - reportMaybesInPropertyPhpDocTypes: false - strictRules: - allRules: false - booleansInConditions: true - closureUsesThis: true - disallowedConstructs: false - disallowedLooseComparison: false - matchingInheritedMethodNames: true - noVariableVariables: true - numericOperandsInArithmeticOperators: true - overwriteVariablesWithLoop: true - requireParentConstructorCall: true - strictCalls: true - switchConditionsMatchingType: true - uselessCast: true -includes: - - vendor/phpstan/phpstan-strict-rules/rules.neon diff --git a/repositories.json b/repositories.json index d8b2759..d741e42 100644 --- a/repositories.json +++ b/repositories.json @@ -1,15 +1,6 @@ [{ "url": "https://github.com/FreshRSS/Extensions", "type": "git" -}, { - "url": "https://github.com/kevinpapst/freshrss-youtube", - "type": "git" -}, { - "url": "https://github.com/kevinpapst/freshrss-dilbert", - "type": "git" -}, { - "url": "https://github.com/kevinpapst/freshrss-teem", - "type": "git" }, { "url": "https://github.com/oyox/FreshRSS-extensions", "type": "git" @@ -28,9 +19,6 @@ }, { "url": "https://github.com/aledeg/xExtension-WhiteList", "type": "git" -}, { - "url": "https://framagit.org/Lapineige/FreshRSS_Extension-ReadingTime/", - "type": "git" }, { "url": "https://framagit.org/nicofrand/xextension-threepanesview", "type": "git" @@ -53,7 +41,7 @@ "url": "https://github.com/babico/xExtension-TwitchChannel2RssFeed", "type": "git" }, { - "url": "thttps://github.com/tunbridgep/freshrss-invidious", + "url": "https://github.com/tunbridgep/freshrss-invidious", "type": "git" }, { "url": "https://github.com/javerous/freshrss-greader-redate", @@ -65,6 +53,15 @@ "url": "https://github.com/christian-putzke/freshrss-pocket-button", "type": "git" }, { + "url": "https://github.com/huffstler/xExtension-StarToPocket", + "type": "git" +}, { + "url": "https://github.com/Joedmin/xExtension-readeck-button", + "type": "git" +}, { + "url": "https://github.com/Joedmin/xExtension-wallabag-button", + "type": "git" +},{ "url": "https://github.com/printfuck/xExtension-Readable", "type": "git" }, { @@ -82,12 +79,25 @@ }, { "url": "https://github.com/reply2future/xExtension-NewsAssistant", "type": "git" -}, -{ +}, { "url": "https://github.com/giventofly/freshrss-comicsinfeed", "type": "git" -}, -{ +}, { "url": "https://code.sitosis.com/rudism/freshrss-kagi-summarizer", "type": "git" +}, { + "url": "https://github.com/kalvn/freshrss-mark-previous-as-read", + "type": "git" +}, { + "url": "https://github.com/LiangWei88/xExtension-ArticleSummary", + "type": "git" +}, { + "url": "https://github.com/Niehztog/freshrss-af-readability", + "type": "git" +}, { + "url": "https://github.com/tryallthethings/freshvibes", + "type": "git" +}, { + "url": "https://github.com/pe1uca/xExtension-RateLimiter", + "type": "git" }] diff --git a/tests/phpstan-next.txt b/tests/phpstan-next.txt deleted file mode 100644 index 161cef4..0000000 --- a/tests/phpstan-next.txt +++ /dev/null @@ -1,7 +0,0 @@ -# List of files, which are not yet passing PHPStan level 9 https://phpstan.org/user-guide/rule-levels -# Used for automated tests to avoid regressions in files already passing that level. -# Can be regenerated with something like: -# find . -type d -name 'vendor' -prune -o -name '*.php' -exec sh -c 'vendor/bin/phpstan analyse --level 9 --memory-limit 512M {} >/dev/null 2>/dev/null || echo {}' \; - -./xExtension-ImageProxy/configure.phtml -./xExtension-ImageProxy/extension.php diff --git a/xExtension-ColorfulList/extension.php b/xExtension-ColorfulList/extension.php index b1814d5..6212126 100644 --- a/xExtension-ColorfulList/extension.php +++ b/xExtension-ColorfulList/extension.php @@ -2,9 +2,10 @@ declare(strict_types=1); -class ColorfulListExtension extends Minz_Extension +final class ColorfulListExtension extends Minz_Extension { + #[\Override] public function init(): void { - Minz_View::appendScript($this->getFileUrl('script.js', 'js')); + Minz_View::appendScript($this->getFileUrl('script.js')); } } diff --git a/xExtension-ColorfulList/metadata.json b/xExtension-ColorfulList/metadata.json index 945d2f5..f7887d7 100644 --- a/xExtension-ColorfulList/metadata.json +++ b/xExtension-ColorfulList/metadata.json @@ -2,7 +2,7 @@ "name": "Colorful List", "author": "Claud Xiao", "description": "Colorful Entry Title based on RSS source", - "version": 0.3, + "version": "0.3.2", "entrypoint": "ColorfulList", "type": "user" } diff --git a/xExtension-CustomCSS/README.md b/xExtension-CustomCSS/README.md deleted file mode 100644 index fc71979..0000000 --- a/xExtension-CustomCSS/README.md +++ /dev/null @@ -1,89 +0,0 @@ -# CustomCSS extension - -A FreshRSS extension which give ability to create user-specific CSS rules to apply in addition of the actual theme. - -To use it, upload this directory in your `./extensions` directory and enable it on the extension panel in FreshRSS. You can add CSS rules by clicking on the manage button. - -## Changelog - -- 0.2 added file permission check, added german translation, removed un-editable file static/style.css -- 0.1 initial version - -## Examples - -### Enhancing mobile view - -The following CSS rules let you have a more comfortable mobile view by hiding some icons (read/unread article, mark as favorite and RSS feed's favicon) and by reducing text size. It also displays the name of the subscribed feed, instead of the favicon: - -```css -@media (max-width: 840px) -{ - .flux_header .item.website - { - width:20%; - padding:3px; - } - - .flux .website .favicon, .flux_header .item.manage - { - display:none; - } - - - .flux_header .item.website span - { - display:inline; - font-size:0.7rem; - } -} -``` - -The result is shown below: - -Desktop screen resolution: - -![Desktop](desktop_resolution.png) - -Mobile screen resolution: - -![Mobile](mobile_resolution.png) - -#### Getting rid of Top Menu Items - -The Top Menu within the mobile view might look a little bit cluttered, depending on the theme. The following CSS rules allow to hide unnecessary top menu buttons or input boxes. -```css -@media (max-width: 840px) -{ - /* Hides "Actions" Menu in Mobile View */ - #nav_menu_actions { - display: none; - } - - /* Hides "Views" Menu in Mobile View */ - #nav_menu_views { - display: none; - } - - /* Hides "Search" Input Box in Mobile View */ - .nav_menu .item.search { - display: none; - } - - /* Hides the Dropdown Menu Button next to the "Mark all read" Button in Mobile View */ - #mark-read-menu .dropdown { - display: none; - } -} -``` - -### Sidebar: Move the unread count to the right side of a feed - -Some people prefer to have the unread count number of a feed on the right side after the feed's name, instead placing it between the favicon and the feeds name, as this is also the common location in other tools (e.g. e-mail inbox folder). Use this CSS code to move the number to the right side. -```css -.feed .item-title:not([data-unread="0"])::before { - display: none -} -.feed .item-title:not([data-unread="0"])::after { - content: " (" attr(data-unread) ")"; -} -``` diff --git a/xExtension-CustomCSS/configure.phtml b/xExtension-CustomCSS/configure.phtml deleted file mode 100644 index f3ccc73..0000000 --- a/xExtension-CustomCSS/configure.phtml +++ /dev/null @@ -1,24 +0,0 @@ - -
- -
- -
- -
-
- -
- permission_problem)) { ?> -

permission_problem) ?>

- -
- - -
- -
-
diff --git a/xExtension-CustomCSS/desktop_resolution.png b/xExtension-CustomCSS/desktop_resolution.png deleted file mode 100644 index 6ff036c..0000000 Binary files a/xExtension-CustomCSS/desktop_resolution.png and /dev/null differ diff --git a/xExtension-CustomCSS/extension.php b/xExtension-CustomCSS/extension.php deleted file mode 100644 index b0df7f1..0000000 --- a/xExtension-CustomCSS/extension.php +++ /dev/null @@ -1,45 +0,0 @@ -registerTranslates(); - - $current_user = Minz_Session::paramString('currentUser'); - $filename = 'style.' . $current_user . '.css'; - $filepath = join_path($this->getPath(), 'static', $filename); - - if (file_exists($filepath)) { - Minz_View::appendStyle($this->getFileUrl($filename, 'css')); - } - } - - public function handleConfigureAction(): void { - $this->registerTranslates(); - - $current_user = Minz_Session::paramString('currentUser'); - $filename = 'style.' . $current_user . '.css'; - $staticPath = join_path($this->getPath(), 'static'); - $filepath = join_path($staticPath, $filename); - - if (!file_exists($filepath) && !is_writable($staticPath)) { - $tmpPath = explode(EXTENSIONS_PATH . '/', $staticPath); - $this->permission_problem = $tmpPath[1] . '/'; - } elseif (file_exists($filepath) && !is_writable($filepath)) { - $tmpPath = explode(EXTENSIONS_PATH . '/', $filepath); - $this->permission_problem = $tmpPath[1]; - } elseif (Minz_Request::isPost()) { - $css_rules = html_entity_decode(Minz_Request::paramString('css-rules')); - file_put_contents($filepath, $css_rules); - } - - $this->css_rules = ''; - if (file_exists($filepath)) { - $this->css_rules = htmlentities(file_get_contents($filepath) ?: ''); - } - } -} diff --git a/xExtension-CustomCSS/i18n/de/ext.php b/xExtension-CustomCSS/i18n/de/ext.php deleted file mode 100644 index a0c704c..0000000 --- a/xExtension-CustomCSS/i18n/de/ext.php +++ /dev/null @@ -1,8 +0,0 @@ - array( - 'write_css' => 'Benutzerspezifische CSS Regeln', - 'permission_problem' => 'Deine CSS Datei ist nicht beschreibbar, bitte ändere die Berechtigungen von %s' - ), -); diff --git a/xExtension-CustomCSS/i18n/en/ext.php b/xExtension-CustomCSS/i18n/en/ext.php deleted file mode 100644 index c5f95ed..0000000 --- a/xExtension-CustomCSS/i18n/en/ext.php +++ /dev/null @@ -1,8 +0,0 @@ - array( - 'write_css' => 'Additional CSS rules', - 'permission_problem' => 'Your CSS file is not writable, please change the file permissions for %s', - ), -); diff --git a/xExtension-CustomCSS/i18n/fr/ext.php b/xExtension-CustomCSS/i18n/fr/ext.php deleted file mode 100644 index 3aa3c82..0000000 --- a/xExtension-CustomCSS/i18n/fr/ext.php +++ /dev/null @@ -1,8 +0,0 @@ - array( - 'write_css' => 'Règles CSS supplémentaires', - 'permission_problem' => 'Votre fichier CSS est en lecture seule ; veuillez adapter les permissions pour %s', - ), -); diff --git a/xExtension-CustomCSS/metadata.json b/xExtension-CustomCSS/metadata.json deleted file mode 100644 index a4ccfc7..0000000 --- a/xExtension-CustomCSS/metadata.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "name": "Custom CSS", - "author": "Marien Fressinaud", - "description": "Give possibility to overwrite the CSS with a user-specific rules.", - "version": "0.4", - "entrypoint": "CustomCSS", - "type": "user" -} diff --git a/xExtension-CustomCSS/mobile_resolution.png b/xExtension-CustomCSS/mobile_resolution.png deleted file mode 100644 index 6524b2b..0000000 Binary files a/xExtension-CustomCSS/mobile_resolution.png and /dev/null differ diff --git a/xExtension-CustomCSS/static/.gitignore b/xExtension-CustomCSS/static/.gitignore deleted file mode 100644 index b068666..0000000 --- a/xExtension-CustomCSS/static/.gitignore +++ /dev/null @@ -1 +0,0 @@ -style.*.css diff --git a/xExtension-CustomJS/README.md b/xExtension-CustomJS/README.md deleted file mode 100644 index 6227bbc..0000000 --- a/xExtension-CustomJS/README.md +++ /dev/null @@ -1,10 +0,0 @@ -# CustomJS extension - -A FreshRSS extension which give ability to create user-specific JS. - -To use it, upload this directory in your `./extensions` directory and enable it on the extension panel in FreshRSS. You can add JS by clicking on the manage button. - -## Changelog - -- 0.2 added file permission check and german translation -- 0.1 initial version diff --git a/xExtension-CustomJS/configure.phtml b/xExtension-CustomJS/configure.phtml deleted file mode 100644 index 1f065bb..0000000 --- a/xExtension-CustomJS/configure.phtml +++ /dev/null @@ -1,24 +0,0 @@ - -
- -
- -
- -
-
- -
- permission_problem)) { ?> -

permission_problem) ?>

- -
- - -
- -
-
diff --git a/xExtension-CustomJS/extension.php b/xExtension-CustomJS/extension.php deleted file mode 100644 index 6edbf38..0000000 --- a/xExtension-CustomJS/extension.php +++ /dev/null @@ -1,45 +0,0 @@ -registerTranslates(); - - $current_user = Minz_Session::paramString('currentUser'); - $filename = 'script.' . $current_user . '.js'; - $filepath = join_path($this->getPath(), 'static', $filename); - - if (file_exists($filepath)) { - Minz_View::appendScript($this->getFileUrl($filename, 'js')); - } - } - - public function handleConfigureAction(): void { - $this->registerTranslates(); - - $current_user = Minz_Session::paramString('currentUser'); - $filename = 'script.' . $current_user . '.js'; - $staticPath = join_path($this->getPath(), 'static'); - $filepath = join_path($staticPath, $filename); - - if (!file_exists($filepath) && !is_writable($staticPath)) { - $tmpPath = explode(EXTENSIONS_PATH . '/', $staticPath); - $this->permission_problem = $tmpPath[1] . '/'; - } elseif (file_exists($filepath) && !is_writable($filepath)) { - $tmpPath = explode(EXTENSIONS_PATH . '/', $filepath); - $this->permission_problem = $tmpPath[1]; - } elseif (Minz_Request::isPost()) { - $js_rules = html_entity_decode(Minz_Request::paramString('js-rules')); - file_put_contents($filepath, $js_rules); - } - - $this->js_rules = ''; - if (file_exists($filepath)) { - $this->js_rules = htmlentities(file_get_contents($filepath) ?: ''); - } - } -} diff --git a/xExtension-CustomJS/i18n/de/ext.php b/xExtension-CustomJS/i18n/de/ext.php deleted file mode 100644 index 882b655..0000000 --- a/xExtension-CustomJS/i18n/de/ext.php +++ /dev/null @@ -1,8 +0,0 @@ - array( - 'write_js' => 'Benutzerspezifische Javascript Regeln', - 'permission_problem' => 'Deine JS Datei ist nicht beschreibbar, bitte ändere die Berechtigungen von %s' - ), -); diff --git a/xExtension-CustomJS/i18n/en/ext.php b/xExtension-CustomJS/i18n/en/ext.php deleted file mode 100644 index fcf8538..0000000 --- a/xExtension-CustomJS/i18n/en/ext.php +++ /dev/null @@ -1,8 +0,0 @@ - array( - 'write_js' => 'Additional JS', - 'permission_problem' => 'Your JS file is not writable, please change the file permissions for %s', - ), -); diff --git a/xExtension-CustomJS/i18n/fr/ext.php b/xExtension-CustomJS/i18n/fr/ext.php deleted file mode 100644 index 7e6520d..0000000 --- a/xExtension-CustomJS/i18n/fr/ext.php +++ /dev/null @@ -1,8 +0,0 @@ - array( - 'write_js' => 'JS supplémentaires', - 'permission_problem' => 'Votre fichier JS est en lecture seule ; veuillez adapter les permissions pour %s', - ), -); diff --git a/xExtension-CustomJS/metadata.json b/xExtension-CustomJS/metadata.json deleted file mode 100644 index 614e3a5..0000000 --- a/xExtension-CustomJS/metadata.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "name": "Custom JS", - "author": "Frans de Jonge", - "description": "Apply custom JS.", - "version": "0.4", - "entrypoint": "CustomJS", - "type": "user" -} diff --git a/xExtension-CustomJS/static/.gitignore b/xExtension-CustomJS/static/.gitignore deleted file mode 100644 index 2980572..0000000 --- a/xExtension-CustomJS/static/.gitignore +++ /dev/null @@ -1 +0,0 @@ -script.*.js diff --git a/xExtension-ImageProxy/README.md b/xExtension-ImageProxy/README.md index 6277b80..ea38521 100644 --- a/xExtension-ImageProxy/README.md +++ b/xExtension-ImageProxy/README.md @@ -4,6 +4,11 @@ This FreshRSS extension allows you to get rid of insecure content warnings or di To use it, upload this entire directory to the FreshRSS `./extensions` directory on your server and enable it on the extension panel in FreshRSS. +## Changelog + +* 1.0 Breaking changes due to significant code upgrade: settings must be saved again +* 0.7.3 Turkish language support added + ## Configuration settings * `proxy_url` (default: `https://images.example.com/?url=`): the URL that is prependended to the original image URL diff --git a/xExtension-ImageProxy/configure.phtml b/xExtension-ImageProxy/configure.phtml index 0923d0a..1042e30 100644 --- a/xExtension-ImageProxy/configure.phtml +++ b/xExtension-ImageProxy/configure.phtml @@ -7,26 +7,30 @@
- +
- image_proxy_scheme_http ? 'checked' : '' ?>> + attributeBool('image_proxy_scheme_http') ? 'checked' : '' ?>>
- image_proxy_scheme_https ? 'checked' : '' ?>> + attributeBool('image_proxy_scheme_https') ? 'checked' : '' ?>>
image_proxy_scheme_include ? 'checked' : '' ?>> + attributeBool('image_proxy_scheme_include') ? 'checked' : '' ?>>
- image_proxy_url_encode ? 'checked' : '' ?>> + attributeBool('image_proxy_url_encode') ? 'checked' : '' ?>>
diff --git a/xExtension-ImageProxy/extension.php b/xExtension-ImageProxy/extension.php index 233bf5f..8f5150e 100644 --- a/xExtension-ImageProxy/extension.php +++ b/xExtension-ImageProxy/extension.php @@ -5,49 +5,45 @@ declare(strict_types=1); final class ImageProxyExtension extends Minz_Extension { // Defaults private const PROXY_URL = 'https://wsrv.nl/?url='; - private const SCHEME_HTTP = '1'; - private const SCHEME_HTTPS = ''; + private const SCHEME_HTTP = true; + private const SCHEME_HTTPS = false; private const SCHEME_DEFAULT = 'auto'; - private const SCHEME_INCLUDE = ''; - private const URL_ENCODE = '1'; + private const SCHEME_INCLUDE = false; + private const URL_ENCODE = true; + /** + * @throws FreshRSS_Context_Exception + */ + #[\Override] public function init(): void { if (!FreshRSS_Context::hasSystemConf()) { throw new FreshRSS_Context_Exception('System configuration not initialised!'); } - $this->registerHook( - 'entry_before_display', - array('ImageProxyExtension', 'setImageProxyHook') - ); + $this->registerHook('entry_before_display', [self::class, 'setImageProxyHook']); // Defaults $save = false; - if (is_null(FreshRSS_Context::userConf()->image_proxy_url)) { - FreshRSS_Context::userConf()->image_proxy_url = self::PROXY_URL; + if (FreshRSS_Context::userConf()->attributeString('image_proxy_url') == null) { + FreshRSS_Context::userConf()->_attribute('image_proxy_url', self::PROXY_URL); $save = true; } - if (is_null(FreshRSS_Context::userConf()->image_proxy_scheme_http)) { - FreshRSS_Context::userConf()->image_proxy_scheme_http = self::SCHEME_HTTP; + if (FreshRSS_Context::userConf()->attributeBool('image_proxy_scheme_http') === null) { + FreshRSS_Context::userConf()->_attribute('image_proxy_scheme_http', self::SCHEME_HTTP); $save = true; } - if (is_null(FreshRSS_Context::userConf()->image_proxy_scheme_https)) { - FreshRSS_Context::userConf()->image_proxy_scheme_https = self::SCHEME_HTTPS; - // Legacy - if (!is_null(FreshRSS_Context::userConf()->image_proxy_force)) { - FreshRSS_Context::userConf()->image_proxy_scheme_https = FreshRSS_Context::userConf()->image_proxy_force; - FreshRSS_Context::userConf()->image_proxy_force = null; // Minz -> unset - } + if (FreshRSS_Context::userConf()->attributeBool('image_proxy_scheme_https') === null) { + FreshRSS_Context::userConf()->_attribute('image_proxy_scheme_https', self::SCHEME_HTTPS); $save = true; } - if (is_null(FreshRSS_Context::userConf()->image_proxy_scheme_default)) { - FreshRSS_Context::userConf()->image_proxy_scheme_default = self::SCHEME_DEFAULT; + if (FreshRSS_Context::userConf()->attributeString('image_proxy_scheme_default') === null) { + FreshRSS_Context::userConf()->_attribute('image_proxy_scheme_default', self::SCHEME_DEFAULT); $save = true; } - if (is_null(FreshRSS_Context::userConf()->image_proxy_scheme_include)) { - FreshRSS_Context::userConf()->image_proxy_scheme_include = self::SCHEME_INCLUDE; + if (FreshRSS_Context::userConf()->attributeBool('image_proxy_scheme_include') === null) { + FreshRSS_Context::userConf()->_attribute('image_proxy_scheme_include', self::SCHEME_INCLUDE); $save = true; } - if (is_null(FreshRSS_Context::userConf()->image_proxy_url_encode)) { - FreshRSS_Context::userConf()->image_proxy_url_encode = self::URL_ENCODE; + if (FreshRSS_Context::userConf()->attributeBool('image_proxy_url_encode') === null) { + FreshRSS_Context::userConf()->_attribute('image_proxy_url_encode', self::URL_ENCODE); $save = true; } if ($save) { @@ -55,90 +51,128 @@ final class ImageProxyExtension extends Minz_Extension { } } + /** + * @throws FreshRSS_Context_Exception + */ + #[\Override] public function handleConfigureAction(): void { $this->registerTranslates(); if (Minz_Request::isPost()) { - FreshRSS_Context::userConf()->image_proxy_url = Minz_Request::paramString('image_proxy_url', true) ?: self::PROXY_URL; - FreshRSS_Context::userConf()->image_proxy_scheme_http = Minz_Request::paramString('image_proxy_scheme_http'); - FreshRSS_Context::userConf()->image_proxy_scheme_https = Minz_Request::paramString('image_proxy_scheme_https'); - FreshRSS_Context::userConf()->image_proxy_scheme_default = Minz_Request::paramString('image_proxy_scheme_default') ?: self::SCHEME_DEFAULT; - FreshRSS_Context::userConf()->image_proxy_scheme_include = Minz_Request::paramString('image_proxy_scheme_include'); - FreshRSS_Context::userConf()->image_proxy_url_encode = Minz_Request::paramString('image_proxy_url_encode'); + FreshRSS_Context::userConf()->_attribute('image_proxy_url', Minz_Request::paramString('image_proxy_url', plaintext: true) ?: self::PROXY_URL); + FreshRSS_Context::userConf()->_attribute('image_proxy_scheme_http', Minz_Request::paramBoolean('image_proxy_scheme_http')); + FreshRSS_Context::userConf()->_attribute('image_proxy_scheme_https', Minz_Request::paramBoolean('image_proxy_scheme_https')); + FreshRSS_Context::userConf()->_attribute('image_proxy_scheme_default', Minz_Request::paramString('image_proxy_scheme_default', plaintext: true) ?: self::SCHEME_DEFAULT); + FreshRSS_Context::userConf()->_attribute('image_proxy_scheme_include', Minz_Request::paramBoolean('image_proxy_scheme_include')); + FreshRSS_Context::userConf()->_attribute('image_proxy_url_encode', Minz_Request::paramBoolean('image_proxy_url_encode')); FreshRSS_Context::userConf()->save(); } } + /** + * @throws FreshRSS_Context_Exception + */ public static function getProxyImageUri(string $url): string { $parsed_url = parse_url($url); - $scheme = isset($parsed_url['scheme']) ? $parsed_url['scheme'] : null; + $scheme = $parsed_url['scheme'] ?? ''; if ($scheme === 'http') { - if (!FreshRSS_Context::userConf()->image_proxy_scheme_http) { + if (!FreshRSS_Context::userConf()->attributeBool('image_proxy_scheme_http')) { return $url; } - if (!FreshRSS_Context::userConf()->image_proxy_scheme_include) { - $url = substr($url, 7); // http:// + if (!FreshRSS_Context::userConf()->attributeBool('image_proxy_scheme_include')) { + $url = substr($url, 7); // http:// } } elseif ($scheme === 'https') { - if (!FreshRSS_Context::userConf()->image_proxy_scheme_https) { + if (!FreshRSS_Context::userConf()->attributeBool('image_proxy_scheme_https')) { return $url; } - if (!FreshRSS_Context::userConf()->image_proxy_scheme_include) { - $url = substr($url, 8); // https:// + if (!FreshRSS_Context::userConf()->attributeBool('image_proxy_scheme_include')) { + $url = substr($url, 8); // https:// } - } elseif (empty($scheme)) { - if (FreshRSS_Context::userConf()->image_proxy_scheme_default === 'auto') { - if (FreshRSS_Context::userConf()->image_proxy_scheme_include) { - $url = ((!empty($_SERVER['HTTPS']) && strtolower($_SERVER['HTTPS']) !== 'off') ? 'https:' : 'http:') . $url; + } elseif ($scheme === '') { + if (FreshRSS_Context::userConf()->attributeString('image_proxy_scheme_default') === 'auto') { + if (FreshRSS_Context::userConf()->attributeBool('image_proxy_scheme_include')) { + $url = ((is_string($_SERVER['HTTPS'] ?? null) && strtolower($_SERVER['HTTPS']) !== 'off') ? 'https:' : 'http:') . $url; } - } elseif (substr(FreshRSS_Context::userConf()->image_proxy_scheme_default, 0, 4) === 'http') { - if (FreshRSS_Context::userConf()->image_proxy_scheme_include) { - $url = FreshRSS_Context::userConf()->image_proxy_scheme_default . ':' . $url; + } elseif (str_starts_with(FreshRSS_Context::userConf()->attributeString('image_proxy_scheme_default') ?? '', 'http')) { + if (FreshRSS_Context::userConf()->attributeBool('image_proxy_scheme_include')) { + $url = FreshRSS_Context::userConf()->attributeString('image_proxy_scheme_default') . ':' . $url; } - } else { // do not proxy unschemed ("//path/...") URLs + } else { // do not proxy unschemed ("//path/...") URLs return $url; } - } else { // unknown/unsupported (non-http) scheme + } else { // unknown/unsupported (non-http) scheme return $url; } - if (FreshRSS_Context::userConf()->image_proxy_url_encode) { + if (FreshRSS_Context::userConf()->attributeBool('image_proxy_url_encode')) { $url = rawurlencode($url); } - return FreshRSS_Context::userConf()->image_proxy_url . $url; + return FreshRSS_Context::userConf()->attributeString('image_proxy_url') . $url; } /** * @param array $matches + * @throws FreshRSS_Context_Exception */ public static function getSrcSetUris(array $matches): string { return str_replace($matches[1], self::getProxyImageUri($matches[1]), $matches[0]); } + /** + * @throws FreshRSS_Context_Exception + */ public static function swapUris(string $content): string { - if (empty($content)) { + if ($content === '') { return $content; } $doc = new DOMDocument(); - libxml_use_internal_errors(true); // prevent tag soup errors from showing - $doc->loadHTML(mb_convert_encoding($content, 'HTML-ENTITIES', 'UTF-8')); + libxml_use_internal_errors(true); // prevent tag soup errors from showing + $content = mb_convert_encoding($content, 'HTML-ENTITIES', 'UTF-8'); + if (!is_string($content)) { + return ''; + } + $doc->loadHTML($content); $imgs = $doc->getElementsByTagName('img'); foreach ($imgs as $img) { + if (!($img instanceof DOMElement)) { + continue; + } if ($img->hasAttribute('src')) { - $newSrc = self::getProxyImageUri($img->getAttribute('src')); + $src = $img->getAttribute('src'); + $newSrc = self::getProxyImageUri($src); + /* + Due to the URL change, FreshRSS is not aware of already rendered enclosures. + Adding data-xextension-imageproxy-original-src / srcset ensures that original URLs are present in the content for the renderer check FreshRSS_Entry->containsLink. + */ + $img->setAttribute('data-xextension-imageproxy-original-src', $src); $img->setAttribute('src', $newSrc); } if ($img->hasAttribute('srcset')) { - $newSrcSet = preg_replace_callback('/(?:([^\s,]+)(\s*(?:\s+\d+[wx])(?:,\s*)?))/', fn (array $matches) => self::getSrcSetUris($matches), $img->getAttribute('srcset')); + $srcSet = $img->getAttribute('srcset'); + $newSrcSet = preg_replace_callback('/(?:([^\s,]+)(\s*(?:\s+\d+[wx])(?:,\s*)?))/', fn (array $matches) => self::getSrcSetUris($matches), $srcSet); if ($newSrcSet != null) { + $img->setAttribute('data-xextension-imageproxy-original-srcset', $srcSet); $img->setAttribute('srcset', $newSrcSet); } } } - return $doc->saveHTML() ?: ''; + $body = $doc->getElementsByTagName('body')->item(0); + + $output = $doc->saveHTML($body); + if ($output === false) { + return ''; + } + + $output = preg_replace('/^|<\/body>$/', '', $output) ?? ''; + + return $output; } + /** + * @throws FreshRSS_Context_Exception + */ public static function setImageProxyHook(FreshRSS_Entry $entry): FreshRSS_Entry { $entry->_content( self::swapUris($entry->content()) diff --git a/xExtension-ImageProxy/i18n/de/ext.php b/xExtension-ImageProxy/i18n/de/ext.php index a3337bc..5edfd73 100644 --- a/xExtension-ImageProxy/i18n/de/ext.php +++ b/xExtension-ImageProxy/i18n/de/ext.php @@ -5,7 +5,7 @@ return array( 'proxy_url' => 'Proxy-URL', 'scheme_http' => 'HTTP-Proxy', 'scheme_https' => 'HTTPS-Proxy', - 'scheme_default' => 'Proxy unspezifiziert', + 'scheme_default' => 'Proxy protokoll-relative URL', 'scheme_include' => 'http*:// in die URL einfügen', 'url_encode' => 'URL-Prozentkodierung' ), diff --git a/xExtension-ImageProxy/i18n/en/ext.php b/xExtension-ImageProxy/i18n/en/ext.php index 30720f7..1bca58a 100644 --- a/xExtension-ImageProxy/i18n/en/ext.php +++ b/xExtension-ImageProxy/i18n/en/ext.php @@ -5,7 +5,7 @@ return array( 'proxy_url' => 'Proxy URL', 'scheme_http' => 'Proxy HTTP', 'scheme_https' => 'Proxy HTTPS', - 'scheme_default' => 'Proxy unspecified', + 'scheme_default' => 'Proxy protocol-relative URL', 'scheme_include' => 'Include http*:// in URL', 'url_encode' => 'Encode the URL' ), diff --git a/xExtension-ImageProxy/i18n/fr/ext.php b/xExtension-ImageProxy/i18n/fr/ext.php index 67325e5..a04583f 100644 --- a/xExtension-ImageProxy/i18n/fr/ext.php +++ b/xExtension-ImageProxy/i18n/fr/ext.php @@ -5,7 +5,7 @@ return array( 'proxy_url' => 'URL du proxy', 'scheme_http' => 'Proxy HTTP', 'scheme_https' => 'Proxy HTTPS', - 'scheme_default' => 'Proxy indéterminé', + 'scheme_default' => 'Proxy URLs sans protocole', 'scheme_include' => 'Inclure http*:// dans l\'URL', 'url_encode' => 'Encoder l\'URL' ), diff --git a/xExtension-ImageProxy/i18n/nl/ext.php b/xExtension-ImageProxy/i18n/nl/ext.php new file mode 100644 index 0000000..5c11315 --- /dev/null +++ b/xExtension-ImageProxy/i18n/nl/ext.php @@ -0,0 +1,12 @@ + array( + 'proxy_url' => 'Proxy-url', + 'scheme_http' => 'Http proxyen', + 'scheme_https' => 'Https proxyen', + 'scheme_default' => 'Protocol-relatieve url’s proxyen', + 'scheme_include' => 'http*:// in url opnemen', + 'url_encode' => 'Url encoderen' + ), +); diff --git a/xExtension-ImageProxy/i18n/tr/ext.php b/xExtension-ImageProxy/i18n/tr/ext.php new file mode 100644 index 0000000..184645b --- /dev/null +++ b/xExtension-ImageProxy/i18n/tr/ext.php @@ -0,0 +1,12 @@ + array( + 'proxy_url' => 'Vekil Bağlantısı', + 'scheme_http' => 'HTTP Vekil Sunucusu', + 'scheme_https' => 'HTTPS Vekil Sunucusu', + 'scheme_default' => 'Belirtilmemiş Vekil URL Şeması', + 'scheme_include' => 'Bağlantıya http*:// ekle', + 'url_encode' => 'Bağlantıyı kodla', + ), +); diff --git a/xExtension-ImageProxy/metadata.json b/xExtension-ImageProxy/metadata.json index 621caa8..50db226 100644 --- a/xExtension-ImageProxy/metadata.json +++ b/xExtension-ImageProxy/metadata.json @@ -2,7 +2,7 @@ "name": "Image Proxy", "author": "Frans de Jonge", "description": "No insecure content warnings or disappearing images.", - "version": "0.7", + "version": "1.0", "entrypoint": "ImageProxy", "type": "user" } diff --git a/xExtension-QuickCollapse/Controllers/quickCollapseController.php b/xExtension-QuickCollapse/Controllers/quickCollapseController.php deleted file mode 100644 index b2c1332..0000000 --- a/xExtension-QuickCollapse/Controllers/quickCollapseController.php +++ /dev/null @@ -1,23 +0,0 @@ -view->icon_url_in = $extension->getFileUrl('in.svg', 'svg'); - $this->view->icon_url_out = $extension->getFileUrl('out.svg', 'svg'); - } - $this->view->i18n_toggle_collapse = _t('gen.js.toggle_collapse'); - $this->view->_layout(null); - $this->view->_path('quickCollapse/vars.js'); - header('Content-Type: application/javascript'); - } -} diff --git a/xExtension-QuickCollapse/Models/View.php b/xExtension-QuickCollapse/Models/View.php deleted file mode 100644 index 8d154d5..0000000 --- a/xExtension-QuickCollapse/Models/View.php +++ /dev/null @@ -1,12 +0,0 @@ -registerTranslates(); - $this->registerViews(); - $this->registerController('quickCollapse'); + $this->registerHook('js_vars', [$this, 'jsVars']); - Minz_View::appendStyle($this->getFileUrl('style.css', 'css')); - Minz_View::appendScript(_url('quickCollapse', 'jsVars') ?: '', false, true, false); - Minz_View::appendScript($this->getFileUrl('script.js', 'js'), false, true, false); + Minz_View::appendStyle($this->getFileUrl('style.css')); + Minz_View::appendScript($this->getFileUrl('script.js'), cond: false, defer: true, async: false); + } + + /** + * @param array $vars + * @return array + */ + public function jsVars(array $vars): array { + $vars['quick_collapse'] = [ + 'icon_url_in' => $this->getFileUrl('in.svg'), + 'icon_url_out' => $this->getFileUrl('out.svg'), + 'i18n' => [ + 'toggle_collapse' => _t('gen.js.toggle_collapse'), + ] + ]; + return $vars; } } diff --git a/xExtension-QuickCollapse/i18n/tr/gen.php b/xExtension-QuickCollapse/i18n/tr/gen.php new file mode 100644 index 0000000..2e54b35 --- /dev/null +++ b/xExtension-QuickCollapse/i18n/tr/gen.php @@ -0,0 +1,7 @@ + [ + 'toggle_collapse' => 'Daraltmayı değiştir', + ], +]; diff --git a/xExtension-QuickCollapse/metadata.json b/xExtension-QuickCollapse/metadata.json index 14dcbb3..d3c8604 100644 --- a/xExtension-QuickCollapse/metadata.json +++ b/xExtension-QuickCollapse/metadata.json @@ -2,7 +2,7 @@ "name": "Quick Collapse", "author": "romibi and Marien Fressinaud", "description": "Quickly change from folded to unfolded articles", - "version": "0.2", + "version": "1.0.2", "entrypoint": "QuickCollapse", "type": "user" } diff --git a/xExtension-QuickCollapse/static/script.js b/xExtension-QuickCollapse/static/script.js index 97810b7..d309639 100644 --- a/xExtension-QuickCollapse/static/script.js +++ b/xExtension-QuickCollapse/static/script.js @@ -1,4 +1,4 @@ -/* globals context, quick_collapse_vars */ +/* globals context */ (function () { function toggleCollapse() { @@ -26,15 +26,15 @@ } function syncWithContext() { - if (!window.context || !window.quick_collapse_vars) { + if (!window.context) { // The variables might not be available yet, so we need to wait for them. return setTimeout(syncWithContext, 10); } const toggleElem = document.getElementById('toggle-collapse'); - toggleElem.title = quick_collapse_vars.i18n.toggle_collapse; - toggleElem.innerHTML = `↕`; - toggleElem.innerHTML += `✖`; + toggleElem.title = context.extensions.quick_collapse.i18n.toggle_collapse; + toggleElem.innerHTML = `↕`; + toggleElem.innerHTML += `✖`; if (context.hide_posts) { toggleElem.classList.add('collapsed'); diff --git a/xExtension-QuickCollapse/views/quickCollapse/vars.js b/xExtension-QuickCollapse/views/quickCollapse/vars.js deleted file mode 100644 index 941fd3d..0000000 --- a/xExtension-QuickCollapse/views/quickCollapse/vars.js +++ /dev/null @@ -1,10 +0,0 @@ -/* exported quick_collapse_vars */ - -// eslint-disable-next-line no-unused-vars, no-var -var quick_collapse_vars = { - icon_url_in: 'icon_url_in ?>', - icon_url_out: 'icon_url_out ?>', - i18n: { - toggle_collapse: 'i18n_toggle_collapse ?>', - }, -}; diff --git a/xExtension-ReadingTime/LICENSE b/xExtension-ReadingTime/LICENSE index 1ec7ccd..64bef9d 100644 --- a/xExtension-ReadingTime/LICENSE +++ b/xExtension-ReadingTime/LICENSE @@ -1,6 +1,6 @@ The MIT License (MIT) -Copyright (c) 2016 Lapineige +Copyright (c) 2016 Lapineige, hkcomori Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/xExtension-ReadingTime/README.md b/xExtension-ReadingTime/README.md index 5c15f07..24fba01 100644 --- a/xExtension-ReadingTime/README.md +++ b/xExtension-ReadingTime/README.md @@ -1,8 +1,6 @@ Extension pour FreshRSS () -> **v1.3** - -Source: +> **v1.6** Ajoute une estimation du temps de lecture à côté de chaque article. Fonctionne sur les affichages de bureau et mobile. @@ -11,15 +9,13 @@ S'installe comme toute les extensions, soit via l'outil intégré dans l'interfa Aucune module externe. Une fois activée dans les préférences, l'extension doit fonctionner après avoir recharger la page. Un indicateur du temps de lecture doit s'afficher dans le nom du flux de chaque article. -Pour le moment la vitesse de lecture est réglée manuellement à 300 mots/min. À changer si besoin ici: +Vous pouvez définir la vitesse de lecture et la méthode de mesure du temps de lecture. --- Extension for FressRSS () -> **v1.3** - -Source: +> **v1.6** Add a reading time estimation next to each article. Works on both desktop and mobile displays. @@ -27,6 +23,4 @@ Works on both desktop and mobile displays. Install it the same way as any other extension, with the integrated tool in the interface (parameters icon -> extensions) or manually by copying this repository directly in the `extensions` folder of your FreshRSS install. No external module. Once activated in the preferences, this extension should be working after reloading the page. -A reading time -For the moment the reading speed is manually set to 300 words/min. If necessary, change it there: - +You can set reading speed and source metrics to estimate reading time. diff --git a/xExtension-ReadingTime/configure.phtml b/xExtension-ReadingTime/configure.phtml new file mode 100644 index 0000000..337d93f --- /dev/null +++ b/xExtension-ReadingTime/configure.phtml @@ -0,0 +1,30 @@ + +
+ +
+ +
+ +

+
+ + +
+ +

+
+
+ +
+
+ + +
+
+
diff --git a/xExtension-ReadingTime/extension.php b/xExtension-ReadingTime/extension.php index d1a9a63..bf375f4 100644 --- a/xExtension-ReadingTime/extension.php +++ b/xExtension-ReadingTime/extension.php @@ -2,8 +2,95 @@ declare(strict_types=1); -class ReadingTimeExtension extends Minz_Extension { +final class ReadingTimeExtension extends Minz_Extension { + private int $speed = 300; + private string $metrics = 'words'; + + /** + * @throws FreshRSS_Context_Exception + */ + #[\Override] public function init(): void { - Minz_View::appendScript($this->getFileUrl('readingtime.js', 'js')); + $this->registerTranslates(); + if (!FreshRSS_Context::hasUserConf()) { + return; + } + // Defaults + $speed = FreshRSS_Context::userConf()->attributeInt('reading_time_speed'); + if ($speed === null) { + FreshRSS_Context::userConf()->_attribute('reading_time_speed', $this->speed); + } else { + $this->speed = $speed; + } + $metrics = FreshRSS_Context::userConf()->attributeString('reading_time_metrics'); + if ($metrics === null) { + FreshRSS_Context::userConf()->_attribute('reading_time_metrics', $this->metrics); + } else { + $this->metrics = $metrics; + } + if (in_array(null, [$speed, $metrics], true)) { + FreshRSS_Context::userConf()->save(); + } + $this->registerHook('js_vars', [$this, 'getParams']); + Minz_View::appendScript($this->getFileUrl('readingtime.js')); + } + + public function getSpeed(): int { + return $this->speed; + } + + public function getMetrics(): string { + return $this->metrics; + } + + /** + * Called from js_vars hook + * + * Pass dynamic parameters to readingtime.js via `window.context.extensions`. + * Chain with other js_vars hooks via $vars. + * + * @param array $vars is the result of hooks chained in the previous step. + * @return array is passed to the hook chained to the next step. + */ + public function getParams(array $vars): array { + $vars['reading_time_speed'] = $this->speed; + $vars['reading_time_metrics'] = $this->metrics; + return $vars; + } + + /** + * @throws FreshRSS_Context_Exception + * @throws Minz_ConfigurationParamException + */ + #[\Override] + public function handleConfigureAction(): void { + $this->registerTranslates(); + + if (Minz_Request::isPost()) { + $speed = $this->validateSpeed(Minz_Request::paramInt('reading_time_speed')); + FreshRSS_Context::userConf()->_attribute('reading_time_speed', $speed); + $metrics = $this->validateMetrics(Minz_Request::paramString('reading_time_metrics')); + FreshRSS_Context::userConf()->_attribute('reading_time_metrics', $metrics); + FreshRSS_Context::userConf()->save(); + } + } + + /** @throws Minz_ConfigurationParamException */ + private function validateSpeed(int $speed): int { + if ($speed <= 0) { + throw new Minz_ConfigurationParamException('Reading speed must be greater than 0'); + } + return $speed; + } + + /** @throws Minz_ConfigurationParamException */ + private function validateMetrics(string $metrics): string { + switch ($metrics) { + case 'words': + case 'letters': + return $metrics; + default: + throw new Minz_ConfigurationParamException('Unsupported source metrics'); + } } } diff --git a/xExtension-ReadingTime/i18n/en/ext.php b/xExtension-ReadingTime/i18n/en/ext.php new file mode 100644 index 0000000..40a70f2 --- /dev/null +++ b/xExtension-ReadingTime/i18n/en/ext.php @@ -0,0 +1,16 @@ + array( + 'speed' => array( + 'label' => 'Reading speed', + 'help' => 'Conversion factor to reading time from metrics', + ), + 'metrics' => array( + 'label' => 'Source metrics', + 'help' => 'Source of reading time calculation', + 'words' => 'Number of words', + 'letters' => 'Number of letters', + ), + ), +); diff --git a/xExtension-ReadingTime/i18n/fr/ext.php b/xExtension-ReadingTime/i18n/fr/ext.php new file mode 100644 index 0000000..dc4403b --- /dev/null +++ b/xExtension-ReadingTime/i18n/fr/ext.php @@ -0,0 +1,16 @@ + array( + 'speed' => array( + 'label' => 'Vitesse de lecture', + 'help' => 'Paramètre de calcul, dépendant de la méthode', + ), + 'metrics' => array( + 'label' => 'Méthodes', + 'help' => 'Méthode de calcul du temps de lecture', + 'words' => 'Nombre de mots', + 'letters' => 'Nombre de lettres', + ), + ), +); diff --git a/xExtension-ReadingTime/i18n/ja/ext.php b/xExtension-ReadingTime/i18n/ja/ext.php new file mode 100644 index 0000000..1e85c60 --- /dev/null +++ b/xExtension-ReadingTime/i18n/ja/ext.php @@ -0,0 +1,16 @@ + array( + 'speed' => array( + 'label' => '読書速度', + 'help' => '基準値を読書時間に変換する係数', + ), + 'metrics' => array( + 'label' => '基準値', + 'help' => '読書時間を推定する基準値', + 'words' => '単語数', + 'letters' => '文字数', + ), + ), +); diff --git a/xExtension-ReadingTime/metadata.json b/xExtension-ReadingTime/metadata.json index fcd17b7..e05d0eb 100644 --- a/xExtension-ReadingTime/metadata.json +++ b/xExtension-ReadingTime/metadata.json @@ -1,8 +1,8 @@ { "name": "ReadingTime", - "author": "Lapineige", + "author": "Lapineige, hkcomori", "description": "Add a reading time estimation next to each article", - "version": "1.5", + "version": "1.6.1", "entrypoint": "ReadingTime", "type": "user" } diff --git a/xExtension-ReadingTime/static/readingtime.js b/xExtension-ReadingTime/static/readingtime.js index e6e956c..6c0e250 100644 --- a/xExtension-ReadingTime/static/readingtime.js +++ b/xExtension-ReadingTime/static/readingtime.js @@ -5,12 +5,15 @@ flux_list: null, flux: null, textContent: null, - words_count: null, + count: null, read_time: null, reading_time: null, init: function () { const flux_list = document.querySelectorAll('[id^="flux_"]'); + const speed = window.context.extensions.reading_time_speed; + const metrics = window.context.extensions.reading_time_metrics; + const language = window.context.i18n.language; for (let i = 0; i < flux_list.length; i++) { if ('readingTime' in flux_list[i].dataset) { @@ -19,9 +22,12 @@ reading_time.flux = flux_list[i]; - reading_time.words_count = reading_time.flux_words_count(flux_list[i]); // count the words - // change this number (in words) to your preferred reading speed: - reading_time.reading_time = reading_time.calc_read_time(reading_time.words_count, 300); + if (metrics == 'letters') { + reading_time.count = reading_time.flux_letters_count(flux_list[i], language); + } else { // words + reading_time.count = reading_time.flux_words_count(flux_list[i]); + } + reading_time.reading_time = reading_time.calc_read_time(reading_time.count, speed); flux_list[i].dataset.readingTime = reading_time.reading_time; @@ -50,8 +56,20 @@ return reading_time.textContent.split(' ').length; }, - calc_read_time: function calc_read_time(wd_count, speed) { - reading_time.read_time = Math.round(wd_count / speed); + flux_letters_count: function flux_letters_count(flux, language) { + const segmenter = new Intl.Segmenter(language, { granularity: 'grapheme' }); + + // get textContent, from the article itself (not the header, not the bottom line): + reading_time.textContent = flux.querySelector('.flux_content .content').textContent; + + // clean the text by removing excessive whitespace + reading_time.textContent = reading_time.textContent.replace(/\s/gi, ''); // exclude white-space + + return [...segmenter.segment(reading_time.textContent)].length; + }, + + calc_read_time: function calc_read_time(count, speed) { + reading_time.read_time = Math.round(count / speed); if (reading_time.read_time === 0) { reading_time.read_time = '<1'; @@ -66,11 +84,15 @@ document.body.addEventListener('freshrss:load-more', function (e) { reading_time.init(); }); + + if (window.console) { + console.log('ReadingTime init done.'); + } } - if (document.readyState && document.readyState !== 'loading') { + if (typeof window.context !== 'undefined' && typeof window.context.extensions !== 'undefined') { add_load_more_listener(); - } else if (document.addEventListener) { - document.addEventListener('DOMContentLoaded', add_load_more_listener, false); + } else { + document.addEventListener('freshrss:globalContextLoaded', add_load_more_listener, false); } }()); diff --git a/xExtension-ShareByEmail/Controllers/shareByEmailController.php b/xExtension-ShareByEmail/Controllers/shareByEmailController.php index cdeaedf..fbc6965 100644 --- a/xExtension-ShareByEmail/Controllers/shareByEmailController.php +++ b/xExtension-ShareByEmail/Controllers/shareByEmailController.php @@ -2,20 +2,30 @@ declare(strict_types=1); -class FreshExtension_shareByEmail_Controller extends Minz_ActionController { +final class FreshExtension_shareByEmail_Controller extends Minz_ActionController { public ?Minz_Extension $extension; - /** @var ShareByEmail\mailers\View */ + /** + * @var ShareByEmail\mailers\View + * @phpstan-ignore property.phpDocType + */ protected $view; public function __construct() { parent::__construct(ShareByEmail\mailers\View::class); } + #[\Override] public function init(): void { $this->extension = Minz_ExtensionManager::findExtension('Share By Email'); } + /** + * @throws FreshRSS_Context_Exception + * @throws Minz_ConfigurationException + * @throws Minz_ConfigurationNamespaceException + * @throws Minz_PDOConnectionException + */ public function shareAction(): void { if (!FreshRSS_Auth::hasAccess()) { Minz_Error::error(403); @@ -34,17 +44,17 @@ class FreshExtension_shareByEmail_Controller extends Minz_ActionController { } $this->view->entry = $entry; - if (FreshRSS_Context::$system_conf === null) { + if (!FreshRSS_Context::hasSystemConf()) { throw new FreshRSS_Context_Exception('System configuration not initialised!'); } $username = Minz_Session::paramString('currentUser') ?: '_'; - $service_name = FreshRSS_Context::$system_conf->title; - $service_url = FreshRSS_Context::$system_conf->base_url; + $service_name = FreshRSS_Context::systemConf()->title; + $service_url = FreshRSS_Context::systemConf()->base_url; Minz_View::prependTitle(_t('shareByEmail.share.title') . ' · '); if ($this->extension !== null) { - Minz_View::appendStyle($this->extension->getFileUrl('shareByEmail.css', 'css')); + Minz_View::appendStyle($this->extension->getFileUrl('shareByEmail.css')); } $this->view->_layout('simple'); $this->view->to = ''; diff --git a/xExtension-ShareByEmail/Models/View.php b/xExtension-ShareByEmail/Models/View.php index 15449bc..bca3c4c 100644 --- a/xExtension-ShareByEmail/Models/View.php +++ b/xExtension-ShareByEmail/Models/View.php @@ -4,7 +4,7 @@ declare(strict_types=1); namespace ShareByEmail\mailers; -class View extends \Minz_View { +final class View extends \Minz_View { public ?\FreshRSS_Entry $entry = null; public string $content = ''; diff --git a/xExtension-ShareByEmail/README.md b/xExtension-ShareByEmail/README.md index b873ae3..d1a0ffb 100644 --- a/xExtension-ShareByEmail/README.md +++ b/xExtension-ShareByEmail/README.md @@ -2,10 +2,19 @@ This FreshRSS extension allows to share articles by email, in a more powerful way than the simple `mailto` solution. +## How to install + To install this extension, you must upload this directory in your `./extensions` directory and enable it on the extension panel in FreshRSS. -You’ll have to configure the mailing system in FreshRSS. [See the documentation](https://freshrss.github.io/FreshRSS/en/admins/05_Configuring_email_validation.html#configure-the-smtp-server) +## How to configure + +After the installation the `Email` sharing service will added to the list of available sharing services. You need to add the `Email` sharing service to your individual sharing service list before it is available in the sharing menu. + +You will have to configure the mailing system in FreshRSS. [See the documentation](https://freshrss.github.io/FreshRSS/en/admins/05_Configuring_email_validation.html#configure-the-smtp-server) ## Changelog +- 0.3.2 With the new feature, Turkish language deficiencies have been corrected. +- 0.3.0 detail information about the mail system shown in the extension config +- 0.2.3 Turkish language support added - 0.1 initial version diff --git a/xExtension-ShareByEmail/configure.phtml b/xExtension-ShareByEmail/configure.phtml new file mode 100644 index 0000000..ac30a38 --- /dev/null +++ b/xExtension-ShareByEmail/configure.phtml @@ -0,0 +1,17 @@ + + +
+ +
+ mailer) { + 'mail' => _t('shareByEmail.share.manage.mail'), + 'smtp' => _t('shareByEmail.share.manage.smtp', FreshRSS_Context::systemConf()->smtp['from']), + default => _t('shareByEmail.share.manage.error') + } ?> +

+
+
diff --git a/xExtension-ShareByEmail/extension.php b/xExtension-ShareByEmail/extension.php index b058fac..3cc4c24 100644 --- a/xExtension-ShareByEmail/extension.php +++ b/xExtension-ShareByEmail/extension.php @@ -2,8 +2,12 @@ declare(strict_types=1); -class ShareByEmailExtension extends Minz_Extension { +final class ShareByEmailExtension extends Minz_Extension { + /** + * @throws Minz_ConfigurationException + */ + #[\Override] public function init(): void { $this->registerTranslates(); diff --git a/xExtension-ShareByEmail/i18n/de/shareByEmail.php b/xExtension-ShareByEmail/i18n/de/shareByEmail.php index 48307cf..d8961df 100755 --- a/xExtension-ShareByEmail/i18n/de/shareByEmail.php +++ b/xExtension-ShareByEmail/i18n/de/shareByEmail.php @@ -18,5 +18,12 @@ return [ ], 'intro' => 'Diesen Artikel per Mail versenden: “%s”', 'title' => 'Einen Artikel per Mail teilen.', + 'manage' => [ + 'mailer' => 'E-Mail-Versand', + 'mail' => 'via PHP mail()', + 'smtp' => 'via SMTP (versendet von %s)', + 'error' => 'Fehler', + 'help' => 'Versand zwischen PHP mail() und SMTP in config.php wechseln: siehe Dokumentation', + ] ], ]; diff --git a/xExtension-ShareByEmail/i18n/en/shareByEmail.php b/xExtension-ShareByEmail/i18n/en/shareByEmail.php index d08a1bb..49c8784 100644 --- a/xExtension-ShareByEmail/i18n/en/shareByEmail.php +++ b/xExtension-ShareByEmail/i18n/en/shareByEmail.php @@ -18,5 +18,12 @@ return [ ], 'intro' => 'You are about to share this article by email: “%s”', 'title' => 'Share an article by email', + 'manage' => [ + 'mailer' => 'Mailing system', + 'mail' => 'PHP mail()', + 'smtp' => 'SMTP (send from %s)', + 'error' => 'Error', + 'help' => 'Switch PHP mail()/SMTP connection in config.php: see documentation' + ], ], ]; diff --git a/xExtension-ShareByEmail/i18n/fr/shareByEmail.php b/xExtension-ShareByEmail/i18n/fr/shareByEmail.php index beb3e22..9343f35 100644 --- a/xExtension-ShareByEmail/i18n/fr/shareByEmail.php +++ b/xExtension-ShareByEmail/i18n/fr/shareByEmail.php @@ -18,5 +18,12 @@ return [ ], 'intro' => 'Vous êtes sur le point de partager cet article par courriel : « %s »', 'title' => 'Partager un article par courriel', + 'manage' => [ + 'mailer' => 'Système de messagerie', + 'mail' => 'PHP mail()', + 'smtp' => 'SMTP (envoyer en tant que %s)', + 'error' => 'Erreur', + 'help' => 'Éditer les paramètres SMTP ou PHP mail() dans config.php : voir la documentation', + ] ], ]; diff --git a/xExtension-ShareByEmail/i18n/tr/shareByEmail.php b/xExtension-ShareByEmail/i18n/tr/shareByEmail.php new file mode 100644 index 0000000..b2cca3f --- /dev/null +++ b/xExtension-ShareByEmail/i18n/tr/shareByEmail.php @@ -0,0 +1,29 @@ + [ + 'feedback' => [ + 'failed' => 'E-posta gönderilemiyor, lütfen yöneticinizle iletişime geçin.', + 'fields_required' => 'Tüm alanların doldurulması zorunludur.', + 'sent' => 'E-posta gönderildi.', + ], + 'form' => [ + 'cancel' => 'İptal', + 'content' => 'İçerik', + 'content_default' => "Merhaba,\n\nBu makaleyi oldukça ilginç bulabilirsiniz!\n\n%s – %s\n\n---\n\nBu e-posta %s tarafından %s ( %s ) aracılığıyla gönderildi", + 'send' => 'Gönder', + 'subject' => 'Konu', + 'subject_default' => 'Bu makaleyi ilginç buldum!', + 'to' => 'Kime', + ], + 'intro' => 'Bu makaleyi e-posta yoluyla paylaşmak üzeresiniz: “%s”', + 'title' => 'Bir makaleyi e-posta ile paylaşın', + 'manage' => [ + 'mailer' => 'Mail sistemi', + 'mail' => 'PHP mail()', + 'smtp' => 'SMTP (%s kaynağından gönder)', + 'error' => 'Hata', + 'help' => 'config.php dosyasındaki PHP mail()/SMTP bağlantısını değiştirin: belgelere bakın', + ] + ], +]; diff --git a/xExtension-ShareByEmail/mailers/Share.php b/xExtension-ShareByEmail/mailers/Share.php index 1caaf1e..8058b1d 100644 --- a/xExtension-ShareByEmail/mailers/Share.php +++ b/xExtension-ShareByEmail/mailers/Share.php @@ -6,20 +6,26 @@ namespace ShareByEmail\mailers; final class Share extends \Minz_Mailer { - /** @var View */ + /** + * @var View + * @phpstan-ignore property.phpDocType + */ protected $view; public function __construct() { parent::__construct(View::class); } + /** + * @throws \FreshRSS_Context_Exception + */ public function send_article(string $to, string $subject, string $content): bool { $this->view->_path('share_mailer/article.txt.php'); $this->view->content = $content; - if (isset(\FreshRSS_Context::$system_conf)) { - $subject_prefix = '[' . \FreshRSS_Context::$system_conf->title . ']'; + if (\FreshRSS_Context::hasSystemConf()) { + $subject_prefix = '[' . \FreshRSS_Context::systemConf()->title . ']'; } else { $subject_prefix = ''; } diff --git a/xExtension-ShareByEmail/metadata.json b/xExtension-ShareByEmail/metadata.json index 8f689f0..a8411ab 100644 --- a/xExtension-ShareByEmail/metadata.json +++ b/xExtension-ShareByEmail/metadata.json @@ -1,8 +1,8 @@ { - "name": "Share By Email", - "author": "Marien Fressinaud", - "description": "Improve the sharing by email system.", - "version": "0.2.1", - "entrypoint": "ShareByEmail", - "type": "user" + "name": "Share By Email", + "author": "Marien Fressinaud", + "description": "Improve the sharing by email system.", + "version": "0.3.3", + "entrypoint": "ShareByEmail", + "type": "user" } diff --git a/xExtension-ShareByEmail/views/shareByEmail/share.phtml b/xExtension-ShareByEmail/views/shareByEmail/share.phtml index 36edb7c..f157d8d 100644 --- a/xExtension-ShareByEmail/views/shareByEmail/share.phtml +++ b/xExtension-ShareByEmail/views/shareByEmail/share.phtml @@ -3,75 +3,75 @@ /** @var ShareByEmail\mailers\View $this */ ?>
-

+

-

- entry) ? $this->entry->title() : '') ?> -

+

+ entry) ? $this->entry->title() : '') ?> +

- +
diff --git a/xExtension-StickyFeeds/extension.php b/xExtension-StickyFeeds/extension.php index 1c064de..0663c75 100644 --- a/xExtension-StickyFeeds/extension.php +++ b/xExtension-StickyFeeds/extension.php @@ -2,9 +2,10 @@ declare(strict_types=1); -class StickyFeedsExtension extends Minz_Extension { +final class StickyFeedsExtension extends Minz_Extension { + #[\Override] public function init(): void { - Minz_View::appendStyle($this->getFileUrl('style.css', 'css')); - Minz_View::appendScript($this->getFileUrl('script.js', 'js')); + Minz_View::appendStyle($this->getFileUrl('style.css')); + Minz_View::appendScript($this->getFileUrl('script.js')); } } diff --git a/xExtension-StickyFeeds/metadata.json b/xExtension-StickyFeeds/metadata.json index 639ae9a..f0dea4e 100644 --- a/xExtension-StickyFeeds/metadata.json +++ b/xExtension-StickyFeeds/metadata.json @@ -2,7 +2,7 @@ "name": "Sticky Feeds", "author": "Marien Fressinaud", "description": "Set the feed aside in the main stream following the window scroll.", - "version": "0.2", + "version": "0.2.2", "entrypoint": "StickyFeeds", "type": "user" } diff --git a/xExtension-TTRSS_API/README.md b/xExtension-TTRSS_API/README.md deleted file mode 100644 index d73578c..0000000 --- a/xExtension-TTRSS_API/README.md +++ /dev/null @@ -1,11 +0,0 @@ -# TinyTinyRSS API extension - -This extension provides a TTRSS-compliant API. It means with this extension you can use applications made for TTRSS initially. - -Note the API is NOT FULLY SUPPORTED YET! - -Please be sure to enable API in the configuration and set an API password on your profile. - -URL to use is something like or . - -To use it, upload this directory in your `./extensions` directory and enable it on the extension panel in FreshRSS. diff --git a/xExtension-TTRSS_API/extension.php b/xExtension-TTRSS_API/extension.php deleted file mode 100644 index bce8bd0..0000000 --- a/xExtension-TTRSS_API/extension.php +++ /dev/null @@ -1,57 +0,0 @@ -registerHook( - 'post_update', - array($this, 'postUpdateHook') - ); - } - - public function install() { - $filename = 'ttrss.php'; - $file_source = join_path($this->getPath(), $filename); - $path_destination = join_path(PUBLIC_PATH, 'api'); - $file_destination = join_path($path_destination, $filename); - - if (!is_writable($path_destination)) { - return 'server cannot write in ' . $path_destination; - } - - if (file_exists($file_destination)) { - if (!unlink($file_destination)) { - return 'API file seems already existing but cannot be removed'; - } - } - - if (!file_exists($file_source)) { - return 'API file seems not existing in this extension. Try to download it again.'; - } - - if (!copy($file_source, $file_destination)) { - return 'the API file has failed during installation.'; - } - - return true; - } - - public function uninstall() { - $filename = 'ttrss.php'; - $file_destination = join_path(PUBLIC_PATH, 'api', $filename); - - if (file_exists($file_destination) && !unlink($file_destination)) { - return 'API file cannot be removed'; - } - - return true; - } - - public function postUpdateHook() { - $res = $this->install(); - - if ($res !== true) { - Minz_Log::warning('Problem during TTRSS API extension post update: ' . $res); - } - } -} diff --git a/xExtension-TTRSS_API/metadata.json b/xExtension-TTRSS_API/metadata.json deleted file mode 100644 index 4b7e286..0000000 --- a/xExtension-TTRSS_API/metadata.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "name": "TinyTinyRSS API", - "author": "Marien Fressinaud", - "description": "Provides an API compliant with TinyTinyRSS applications.", - "version": "0.1", - "entrypoint": "TTRSS_API", - "type": "system" -} diff --git a/xExtension-TTRSS_API/ttrss.php b/xExtension-TTRSS_API/ttrss.php deleted file mode 100644 index 3064cfe..0000000 --- a/xExtension-TTRSS_API/ttrss.php +++ /dev/null @@ -1,540 +0,0 @@ -prefix, $sql); - // Minz_Log::debug($sql); - return $this->bd->prepare($sql); - } -} - - -class FreshAPI_TTRSS { - const API_LEVEL = 11; - - const STATUS_OK = 0; - const STATUS_ERR = 1; - - private $seq = 0; - private $user = ''; - private $method = 'index'; - private $params = array(); - private $system_conf = null; - private $user_conf = null; - - public function __construct($params) { - $this->seq = isset($params['seq']) ? $params['seq'] : 0; - $this->user = Minz_Session::param('currentUser', ''); - $this->method = $params['op']; - $this->params = $params; - $this->system_conf = Minz_Configuration::get('system'); - if ($this->user != '') { - $this->user_conf = get_user_configuration($this->user); - } - } - - public function param($param, $default = false) { - if (isset($this->params[$param])) { - return $this->params[$param]; - } else { - return $default; - } - } - - public function good($reply) { - $this->response($reply, self::STATUS_OK); - } - - public function bad($reply) { - $this->response($reply, self::STATUS_ERR); - } - - private function response($reply, $status) { - header('Content-Type: text/json; charset=utf-8'); - $result = json_encode(array( - 'seq' => $this->seq, - 'status' => $status, - 'content' => $reply, - )); - - // Minz_Log::debug($result); - print($result); - exit(); - } - - public function handle() { - if (!$this->system_conf->api_enabled) { - $this->bad(array( - 'error' => 'API_DISABLED' - )); - } - - if ($this->user === '' && - !in_array($this->method, array('login', 'isloggedin'))) { - $this->bad(array( - 'error' => 'NOT_LOGGED_IN' - )); - } - - if (is_callable(array($this, $this->method))) { - call_user_func(array($this, $this->method)); - } else { - Minz_Log::warning('TTRSS API: ' . $this->method . '() method does not exist'); - } - } - - private function auth_user($username, $password) { - if (!function_exists('password_verify')) { - include_once(LIB_PATH . '/password_compat.php'); - } - - $user_conf = get_user_configuration($username); - if (is_null($user_conf)) { - return false; - } - - if ($user_conf->apiPasswordHash != '' && - password_verify($password, $user_conf->apiPasswordHash)) { - Minz_Session::_param('currentUser', $username); - return true; - } else { - return false; - } - } - - public function getApiLevel() { - $this->good(array( - 'level' => self::API_LEVEL - )); - } - - public function getVersion() { - $this->good(array( - 'version' => FRESHRSS_VERSION - )); - } - - public function login() { - $username = $this->param('user'); - $password = $this->param('password'); - $password_base64 = base64_decode($this->param('password')); - - if ($this->auth_user($username, $password) || - $this->auth_user($username, $password_base64)) { - $this->good(array( - 'session_id' => session_id(), - 'api_level' => self::API_LEVEL, - )); - } else { - Minz_Log::warning('TTRSS API: invalid user login: ' . $username); - $this->bad(array( - 'error' => 'LOGIN_ERROR' - )); - } - } - - public function logout() { - Minz_Session::_param('currentUser'); - $this->good(array( - 'status' => 'OK' - )); - } - - public function isLoggedIn() { - $this->good(array( - 'status' => $this->user !== '' - )); - } - - public function getCategories() { - $unread_only = $this->param('unread_only', false); - $include_empty = $this->param('include_empty', true); - // $enable_nested = $this->param('enable_nested', true); // not supported - - $pdo = new MyPDO(); - $sql = 'SELECT DISTINCT c.id, c.name, COUNT(f.id) AS nb_feeds,' - . ' (SELECT COUNT(e.id) FROM %_entry e WHERE e.id_feed = f.id AND e.is_read=0) AS unread' - . ' FROM `%_category` c' - . ' LEFT JOIN `%_feed` f ON c.id = f.category' - . ' GROUP BY c.id, c.name'; - $stm = $pdo->prepare($sql); - $stm->execute(); - $res = $stm->fetchAll(PDO::FETCH_ASSOC); - - $caterogies = array(); - foreach ($res as $cat) { - if ($unread_only && $cat['unread'] <= 0 || - !$include_empty && $cat['nb_feeds'] <= 0) { - continue; - } - - $caterogies[] = array( - 'id' => $cat['id'], - 'title' => $cat['name'], - 'unread' => $cat['unread'], - ); - } - - $this->good($caterogies); - } - - public function getFeeds() { - $cat_id = $this->param('cat_id'); - $unread_only = $this->param('unread_only', false); - $limit = (int)$this->param('limit', -1); - $offset = (int)$this->param('offset', -1); - // $include_nested = $this->param('include_nested', false) === true; // not supported - - $sql_values = array(); - - $sql_where = ''; - if ($cat_id >= 0) { - // special ids are not supported (yet?) - $sql_where = ' WHERE f.category = ?'; - $sql_values[] = $cat_id; - } - - $sql_limit = ''; - if ($limit >= 0 && $offset >= 0) { - $sql_limit = ' LIMIT ? OFFSET ?'; - $sql_values[] = $limit; - $sql_values[] = $offset; - } - - $pdo = new MyPDO(); - $sql = 'SELECT f.id, f.name, f.url, f.category, f.cache_nbUnreads AS unread, f.lastUpdate' - . ' FROM `%_feed` f' - . $sql_where - . $sql_limit; - $stm = $pdo->prepare($sql); - $stm->execute($sql_values); - $res = $stm->fetchAll(PDO::FETCH_ASSOC); - - $feeds = array(); - foreach ($res as $feed) { - if ($unread_only && $feed['unread'] <= 0) { - continue; - } - - $feeds[] = array( - 'id' => $feed['id'], - 'title' => $feed['name'], - 'feed_url' => $feed['url'], - 'unread' => $feed['unread'], - 'has_icon' => true, - 'cat_id' => $feed['category'], - 'last_updated' => $feed['lastUpdate'] - ); - } - - $this->good($feeds); - } - - public function getHeadlines() { - $feed_id = $this->param('feed_id'); - if ($feed_id === false) { - $this->bad(array( - 'error' => 'INCORRECT_USAGE' - )); - } - - $limit = min(200, (int)$this->param('limit', 200)); - $offset = (int)$this->param('skip', 0); - $is_cat = $this->param('is_cat', true); - $show_excerpt = $this->param('show_excerpt', false); - $show_content = $this->param('show_content', true); - $view_mode = $this->param('view_mode', 'all_articles'); - $since_id = $this->param('since_id', ''); - $order_by = $this->param('order_by', 'feed_dates'); - $search = $this->param('search', ''); - // $filter = $this->param('filter'); // not supported - // $include_attachments = $this->param('include_attachments'); // not supported - // $include_nested = $this->param('include_nested'); // not supported - // $force_update = $this->param('force_update', false); // not supported - // $sanitize = $this->param('sanitize', true); // not supported - // $has_sandbox = $this->param('has_sandbox', false); // not supported - // $search_mode = $this->param('search_mode', 'all_feeds'); // not supported - // $match_on = $this->param('match_on'); // not supported - - // Get the current state - $state = 0; - switch ($view_mode) { - case 'unread': - case 'adaptive': - $state = FreshRSS_Entry::STATE_NOT_READ; - break; - case 'marked': - $state = FreshRSS_Entry::STATE_FAVORITE; - break; - case 'updated': // not supported - case 'all_articles': - default: - $state = FreshRSS_Entry::STATE_ALL; - } - - // Get the current type - $id = ''; - $type = 'A'; - switch ($feed_id) { - case 0: // archived (not supported) - case -1: // starred - $type = 's'; - break; - case -2: // published (not supported) - case -3: // fresh (not supported) - case -4: // all articles - // nothing to do - break; - default: - // if ($is_cat) { - // $type = 'c'; - // } else { - // $type = 'f'; - // } - $type = 'f'; - $id = $feed_id; - } - - // Get the order - $order = 'DESC'; - if ($order_by === 'date_reverse') { - $order = 'ASC'; - } - - // Fix the limit: since we don't have any mechanism of offset in - // listWhere, it will be done in PHP. Limit has to be increased by - // the value of offset. - $limit += $offset; - - $entryDAO = FreshRSS_Factory::createEntryDao(); - $entries = $entryDAO->listWhere($type, $id, $state, $order, $limit, $since_id, $search, $since_id); - - $headlines = array(); - $nb_items = 0; - foreach ($entries as $item) { - if ($nb_items < $offset) { - $nb_items++; - continue; - } - - $feed = $item->feed(true); - $line = array( - 'id' => $item->id(), - 'unread' => !$item->isRead(), - 'marked' => $item->isFavorite(), - 'published' => true, - 'updated' => $item->date(true), - 'is_updated' => false, - 'title' => $item->title(), - 'link' => $item->link(), - 'tags' => $item->tags(), - 'author' => $item->author(), - 'feed_id' => $feed->id(), - 'feed_title' => $feed->name(), - ); - - if ($show_excerpt) { - // @todo add a facultative max char in content method to get - // an excerpt. - $line['excerpt'] = $item->content(); - } - - if ($show_content) { - $line['content'] = $item->content(); - } - - $headlines[] = $line; - } - - $this->good($headlines); - } - - public function updateArticle() { - $article_ids = $this->param('article_ids', ''); - $mode = $this->param('mode'); // 0 set to false, 1 set to true, - // 2 toggle but not supported. - $field = $this->param('field'); - // $data = $this->param('data'); // not supported - - $article_ids = explode(',', $article_ids); - $entryDAO = FreshRSS_Factory::createEntryDao(); - $number_article_updated = 0; - switch ($field) { - case 0: // starred - $number_article_updated = $entryDAO->markFavorite($article_ids, $mode); - break; - case 2: // unread - $number_article_updated = $entryDAO->markRead($article_ids, !$mode); - break; - case 1: // published (not supported) - case 3: // article note (not supported) - default: - // nothing to do - } - - $this->good(array( - 'status' => 'OK', - 'updated' => $number_article_updated, - )); - } - - public function catchupFeed() { - $id = $this->param('feed_id'); - $is_cat = $this->param('is_cat', true); - - $entryDAO = FreshRSS_Factory::createEntryDao(); - switch ($id) { - case -1: // starred - $entryDAO->markReadEntries(0, true); - break; - case -4: // all articles - $entryDAO->markReadEntries(); - break; - case 0: // archived (not supported) - case -2: // published (not supported) - case -3: // fresh (not supported) - break; - default: - // if ($is_cat) { - // $entryDAO->markReadCat($id); - // } else { - // $entryDAO->markReadFeed($id); - // } - $entryDAO->markReadFeed($id); - } - - $this->good(array( - 'status' => 'OK' - )); - } - - public function getCounters() { - $categoryDAO = new FreshRSS_CategoryDAO(); - $counters = array(); - $total_unreads = 0; - - // Get feed unread counters - $categories = $categoryDAO->listCategories(true, true); - foreach ($categories as $cat) { - foreach ($cat->feeds() as $feed) { - $counters[] = array( - 'id' => $feed->id(), - 'counter' => $feed->nbNotRead(), - ); - } - - $total_unreads += $cat->nbNotRead(); - } - - // Get global unread counter - $counters[] = array( - 'id' => 'global-unread', - 'counter' => $total_unreads, - ); - - // Get favorite unread counter - $entryDAO = FreshRSS_Factory::createEntryDao(); - $fav_counters = $entryDAO->countUnreadReadFavorites(); - $counters[] = array( - 'id' => -1, - 'counter' => $fav_counters['unread'], - ); - - $this->good($counters); - } - - public function getFeedTree() { - $include_empty = $this->param('include_empty', true); - $tree = array( - 'identifier' => 'id', - 'label' => 'name', - 'items' => array(), - ); - - $categoryDAO = new FreshRSS_CategoryDAO(); - $categories = $categoryDAO->listCategories(true, true); - foreach ($categories as $cat) { - $tree_cat = array( - 'id' => 'CAT:' . $cat->id(), - 'name' => $cat->name(), - 'unread' => $cat->nbNotRead(), - 'type' => 'category', - 'bare_id' => $cat->id(), - 'items' => array(), - ); - - foreach ($cat->feeds() as $feed) { - $tree_cat['items'][] = array( - 'id' => 'FEED:' . $feed->id(), - 'name' => $feed->name(), - 'unread' => $feed->nbNotRead(), - 'type' => 'feed', - 'error' => $feed->inError(), - 'updated' => $feed->lastUpdate(), - 'bare_id' => $feed->id(), - ); - } - - if (count($tree_cat['items']) > 0 || $include_empty) { - $tree['items'][] = $tree_cat; - } - } - - $this->good(array( - 'categories' => $tree - )); - } - - public function getUnread() { - Minz_Log::warning('TTRSS API: getUnread() not implemented'); - } - public function getArticle() { - Minz_Log::warning('TTRSS API: getArticle() not implemented'); - } - public function getConfig() { - Minz_Log::warning('TTRSS API: getConfig() not implemented'); - } - public function updateFeed() { - Minz_Log::warning('TTRSS API: updateFeed() not implemented'); - } - public function getPref() { - Minz_Log::warning('TTRSS API: getPref() not implemented'); - } - public function getLabels() { - Minz_Log::warning('TTRSS API: getLabels() not implemented'); - } - public function setArticleLabel() { - Minz_Log::warning('TTRSS API: setArticleLabel() not implemented'); - } - public function shareToPublish() { - Minz_Log::warning('TTRSS API: shareToPublish() not implemented'); - } - public function subscribeToFeed() { - Minz_Log::warning('TTRSS API: subscribeToFeed() not implemented'); - } - public function unsubscribeFeed() { - Minz_Log::warning('TTRSS API: unsubscribeFeed() not implemented'); - } -} - - -Minz_Configuration::register('system', - DATA_PATH . '/config.php', - DATA_PATH . '/config.default.php'); - -$input = file_get_contents("php://input"); -// Minz_Log::debug($input); -$input = json_decode($input, true); - -if (isset($input["sid"])) { - session_id($input["sid"]); -} - -Minz_Session::init('FreshRSS'); - -$api = new FreshAPI_TTRSS($input); -$api->handle(); diff --git a/xExtension-TitleWrap/README.md b/xExtension-TitleWrap/README.md index db170f1..8f6e973 100644 --- a/xExtension-TitleWrap/README.md +++ b/xExtension-TitleWrap/README.md @@ -3,10 +3,11 @@ FreshRSS extension which changes how article titles are being displayed. Instead of truncating a title when it overflows the display area, this extension applies a line-wrap to long article titles. -To use it, upload this directory in your `./extensions` directory and enable it on the extension panel in FreshRSS. If you need more control, use the xExtension-CustomCSS instead to specify your own css rules. +To use it, upload this directory in your `./extensions` directory and enable it on the extension panel in FreshRSS. If you need more control, use the *User CSS* extension instead to specify your own CSS rules. -The css code used to wrap long titles was originally [proposed](https://github.com/FreshRSS/FreshRSS/issues/2344) by ₣rans de Jonge. +The CSS code (since 0.3 legacy) used to wrap long titles was originally [proposed](https://github.com/FreshRSS/FreshRSS/issues/2344) by ₣rans de Jonge. ## Changelog +- 0.3 ready for FreshRSS 1.23.2-dev (April 2023) / upcoming 1.24.0 - 0.1 initial version diff --git a/xExtension-TitleWrap/extension.php b/xExtension-TitleWrap/extension.php index 7e6c179..64b74f4 100644 --- a/xExtension-TitleWrap/extension.php +++ b/xExtension-TitleWrap/extension.php @@ -2,8 +2,14 @@ declare(strict_types=1); -class TitleWrapExtension extends Minz_Extension { +final class TitleWrapExtension extends Minz_Extension { + #[\Override] public function init(): void { - Minz_View::appendStyle($this->getFileUrl('title_wrap.css', 'css')); + if (version_compare(FRESHRSS_VERSION, "1.23.1") > 0) { + Minz_View::appendStyle($this->getFileUrl('title_wrap.css')); + } else { + // legacy <1.24.0 (= 1.23.2-dev) + Minz_View::appendStyle($this->getFileUrl('title_wrap_legacy.css')); + } } } diff --git a/xExtension-TitleWrap/metadata.json b/xExtension-TitleWrap/metadata.json index b3fe2c1..2907e82 100644 --- a/xExtension-TitleWrap/metadata.json +++ b/xExtension-TitleWrap/metadata.json @@ -2,7 +2,7 @@ "name": "Title-Wrap", "author": "₣rans de Jonge, Joris Kinable", "description": "Applies a line-wrap to long article titles, as opposed to truncating the title when it overflows its display area.", - "version": "0.2", + "version": "0.3.1", "entrypoint": "TitleWrap", "type": "user" } diff --git a/xExtension-TitleWrap/static/title_wrap.css b/xExtension-TitleWrap/static/title_wrap.css index a25892a..84a104a 100644 --- a/xExtension-TitleWrap/static/title_wrap.css +++ b/xExtension-TitleWrap/static/title_wrap.css @@ -1,26 +1,33 @@ -.horizontal-list { - display: flex; +.flux .flux_header .item { + vertical-align: top; } -.horizontal-list.bottom { - display: table; -} - -.flux .item { - flex-shrink: 0; - line-height: normal; - padding: .3em 0; -} - -.flux .item > a { - white-space: normal; -} - -.flux:not(.current):hover .item.title { +.flux .flux_header .item .title { position: relative; - max-width: inherit; } -.flux_header .title { - flex: auto; +.flux .flux_header .item.website .websiteName, +.flux .flux_header .item .title { + white-space: wrap; +} + +.flux .flux_header .item .summary { + margin-top: -0.5rem; +} + +.flux:not(.current):hover .flux_header .item .date { + opacity: inherit; +} + +.flux:not(.current):hover .flux_header .item .title:has(~ .date) { + padding-right: 155px; + z-index: auto; +} + +@media (max-width: 840px) { + .flux:not(.current) .flux_header .item.titleAuthorSummaryDate .title:has(~ .date), + .flux:not(.current):hover .flux_header .item.titleAuthorSummaryDate .title:has(~ .date) { + padding-right: 0; + padding-left: 0; + } } diff --git a/xExtension-TitleWrap/static/title_wrap.rtl.css b/xExtension-TitleWrap/static/title_wrap.rtl.css index a25892a..4f5b4e4 100644 --- a/xExtension-TitleWrap/static/title_wrap.rtl.css +++ b/xExtension-TitleWrap/static/title_wrap.rtl.css @@ -1,26 +1,33 @@ -.horizontal-list { - display: flex; +.flux .flux_header .item { + vertical-align: top; } -.horizontal-list.bottom { - display: table; -} - -.flux .item { - flex-shrink: 0; - line-height: normal; - padding: .3em 0; -} - -.flux .item > a { - white-space: normal; -} - -.flux:not(.current):hover .item.title { +.flux .flux_header .item .title { position: relative; - max-width: inherit; } -.flux_header .title { - flex: auto; +.flux .flux_header .item.website .websiteName, +.flux .flux_header .item .title { + white-space: wrap; +} + +.flux .flux_header .item .summary { + margin-top: -0.5rem; +} + +.flux:not(.current):hover .flux_header .item .date { + opacity: inherit; +} + +.flux:not(.current):hover .flux_header .item .title:has(~ .date) { + padding-left: 155px; + z-index: auto; +} + +@media (max-width: 840px) { + .flux:not(.current) .flux_header .item.titleAuthorSummaryDate .title:has(~ .date), + .flux:not(.current):hover .flux_header .item.titleAuthorSummaryDate .title:has(~ .date) { + padding-left: 0; + padding-right: 0; + } } diff --git a/xExtension-TitleWrap/static/title_wrap_legacy.css b/xExtension-TitleWrap/static/title_wrap_legacy.css new file mode 100644 index 0000000..3bce8fb --- /dev/null +++ b/xExtension-TitleWrap/static/title_wrap_legacy.css @@ -0,0 +1,25 @@ +.horizontal-list { + display: flex; +} + +.horizontal-list.bottom { + display: table; +} + +.flux .flux_header .item { + flex-shrink: 0; + line-height: normal; +} + +.flux .flux_header .item > a { + white-space: normal; +} + +.flux:not(.current):hover .flux_header .item.title { + position: relative; + max-width: inherit; +} + +.flux .flux_header .title { + flex: auto; +} diff --git a/xExtension-TitleWrap/static/title_wrap_legacy.rtl.css b/xExtension-TitleWrap/static/title_wrap_legacy.rtl.css new file mode 100644 index 0000000..3bce8fb --- /dev/null +++ b/xExtension-TitleWrap/static/title_wrap_legacy.rtl.css @@ -0,0 +1,25 @@ +.horizontal-list { + display: flex; +} + +.horizontal-list.bottom { + display: table; +} + +.flux .flux_header .item { + flex-shrink: 0; + line-height: normal; +} + +.flux .flux_header .item > a { + white-space: normal; +} + +.flux:not(.current):hover .flux_header .item.title { + position: relative; + max-width: inherit; +} + +.flux .flux_header .title { + flex: auto; +} diff --git a/xExtension-CustomCSS/LICENSE b/xExtension-WordHighlighter/LICENSE similarity index 100% rename from xExtension-CustomCSS/LICENSE rename to xExtension-WordHighlighter/LICENSE diff --git a/xExtension-WordHighlighter/README.md b/xExtension-WordHighlighter/README.md new file mode 100644 index 0000000..fcc7924 --- /dev/null +++ b/xExtension-WordHighlighter/README.md @@ -0,0 +1,31 @@ +# WordHighlighter extension + +A FreshRSS extension which give ability to highlight user-defined words. + +## Usage + +To use it, upload this directory in your `./extensions` directory and enable it on the extension panel in FreshRSS. You can add words to be highlighted by clicking on the manage button ⚙️. +See also official docs at freshrss.github.io/FreshRSS/en/admins/15_extensions.html + +## Preview + +Light theme: + +![snapshot](./snapshot.png) + + +
+ click to see example screenshot in dark theme + +![snapshot-dark-theme](./snapshot-dark.png) + +
+ + +## Changelog + +- 0.0.3 Turkish language support added. +- 0.0.2 use `json` for storing configuration, add more configuration options + (enable_in_article, enable_logs, case_sensitive, separate_word_search) + and refactored & simplified code. +- 0.0.1 initial version (as a proper FreshRSS extension) diff --git a/xExtension-WordHighlighter/configure.phtml b/xExtension-WordHighlighter/configure.phtml new file mode 100644 index 0000000..ea2be03 --- /dev/null +++ b/xExtension-WordHighlighter/configure.phtml @@ -0,0 +1,88 @@ + +
+ + +
+ +
+ +
+
+ +
+ +
+ enable_in_article == '') { ?> + + + + + +
+
+ +
+ Click to see more advanced options + +
+ +
+ case_sensitive == '') { ?> + + + + +
+
+ +
+ +
+ separate_word_search == '') { ?> + + + + +
+
+ +
+ +
+ enable_logs == '') { ?> + + + + +
+ +
+
+ +
+ permission_problem !== '') { ?> +

permission_problem) ?>

+ +
+ + +
+ +
+ +
diff --git a/xExtension-WordHighlighter/extension.php b/xExtension-WordHighlighter/extension.php new file mode 100644 index 0000000..5c285dc --- /dev/null +++ b/xExtension-WordHighlighter/extension.php @@ -0,0 +1,102 @@ +registerTranslates(); + + // register CSS for WordHighlighter: + Minz_View::appendStyle($this->getFileUrl('style.css')); + + Minz_View::appendScript($this->getFileUrl('mark.min.js'), cond: false, defer: false, async: false); + + $current_user = Minz_Session::paramString('currentUser'); + + $staticPath = join_path($this->getPath(), 'static'); + $configFileJs = join_path($staticPath, 'config.' . $current_user . '.js'); + + if (file_exists($configFileJs)) { + Minz_View::appendScript($this->getFileUrl('config.' . $current_user . '.js')); + } + + Minz_View::appendScript($this->getFileUrl('word-highlighter.js')); + } + + #[\Override] + public function handleConfigureAction(): void + { + $this->registerTranslates(); + + $current_user = Minz_Session::paramString('currentUser'); + $staticPath = join_path($this->getPath(), 'static'); + + $configFileJson = join_path($staticPath, ('config.' . $current_user . '.json')); + + if (!file_exists($configFileJson) && !is_writable($staticPath)) { + $tmpPath = explode(EXTENSIONS_PATH . '/', $staticPath); + $this->permission_problem = $tmpPath[1] . '/'; + + } elseif (file_exists($configFileJson) && !is_writable($configFileJson)) { + $tmpPath = explode(EXTENSIONS_PATH . '/', $configFileJson); + $this->permission_problem = $tmpPath[1]; + + } elseif (Minz_Request::isPost()) { + $configWordList = html_entity_decode(Minz_Request::paramString('words_list')); + + $this->word_highlighter_conf = $configWordList; + $this->enable_in_article = (bool) Minz_Request::paramString('enable-in-article'); + $this->enable_logs = (bool) Minz_Request::paramString('enable_logs'); + $this->case_sensitive = (bool) Minz_Request::paramString('case_sensitive'); + $this->separate_word_search = (bool) Minz_Request::paramString('separate_word_search'); + + $configObj = [ + 'enable_in_article' => $this->enable_in_article, + 'enable_logs' => $this->enable_logs, + 'case_sensitive' => $this->case_sensitive, + 'separate_word_search' => $this->separate_word_search, + 'words' => preg_split("/\r\n|\n|\r/", $configWordList), + ]; + $configJson = json_encode($configObj, WordHighlighterExtension::JSON_ENCODE_CONF); + file_put_contents(join_path($staticPath, ('config.' . $current_user . '.json')), $configJson . PHP_EOL); + file_put_contents(join_path($staticPath, ('config.' . $current_user . '.js')), $this->jsonToJs($configJson) . PHP_EOL); + } + + if (file_exists($configFileJson)) { + try { + $confJson = json_decode(file_get_contents($configFileJson) ?: '', true, 8, JSON_THROW_ON_ERROR); + if (json_last_error() !== JSON_ERROR_NONE || !is_array($confJson)) { + return; + } + $this->enable_in_article = (bool) ($confJson['enable_in_article'] ?? false); + $this->enable_logs = (bool) ($confJson['enable_logs'] ?? false); + $this->case_sensitive = (bool) ($confJson['case_sensitive'] ?? false); + $this->separate_word_search = (bool) ($confJson['separate_word_search'] ?? false); + $this->word_highlighter_conf = implode("\n", (array) ($confJson['words'] ?? [])); + + } catch (Exception $exception) { + // probably nothing to do needed + } + } + } + + private function jsonToJs(string $jsonStr): string + { + $js = "window.WordHighlighterConf = " . + $jsonStr . ";\n" . + "window.WordHighlighterConf.enable_logs && console.log('WordHighlighter: loaded user config:', window.WordHighlighterConf);"; + return $js; + } +} diff --git a/xExtension-WordHighlighter/i18n/en/ext.php b/xExtension-WordHighlighter/i18n/en/ext.php new file mode 100644 index 0000000..9954541 --- /dev/null +++ b/xExtension-WordHighlighter/i18n/en/ext.php @@ -0,0 +1,15 @@ + array( + 'write_words' => 'Words to highlight', + 'write_words_more' => '(separated by newline)', + 'enable_in_article' => 'Enable highlighting also in article', + 'enable_in_article_more' => '(⚠️ may be slower with a lot of words)', + 'enable_logs' => 'Enable logs', + 'case_sensitive' => 'Case sensitive', + 'separate_word_search' => 'Separate word search', + 'test_highlighting_word' => 'highlight', + 'permission_problem' => 'Your config file is not writable, please change the file permissions for %s', + ), +); diff --git a/xExtension-WordHighlighter/i18n/fr/ext.php b/xExtension-WordHighlighter/i18n/fr/ext.php new file mode 100644 index 0000000..a78e090 --- /dev/null +++ b/xExtension-WordHighlighter/i18n/fr/ext.php @@ -0,0 +1,15 @@ + array( + 'write_words' => 'Mots à surligner', + 'write_words_more' => '(séparés par une nouvelle ligne)', + 'enable_in_article' => 'Activer la mise en évidence également dans l’article', + 'enable_in_article_more' => '(⚠️ peut être plus lent avec beaucoup de mots)', + 'enable_logs' => 'Activer les journaux', + 'case_sensitive' => 'Sensible à la casse', + 'separate_word_search' => 'Recherche de mots séparés', + 'test_highlighting_word' => 'surligner', + 'permission_problem' => 'Votre fichier de configuration n’est pas accessible en écriture, veuillez modifier les permissions du fichier %s', + ), +); diff --git a/xExtension-WordHighlighter/i18n/tr/ext.php b/xExtension-WordHighlighter/i18n/tr/ext.php new file mode 100644 index 0000000..d70d870 --- /dev/null +++ b/xExtension-WordHighlighter/i18n/tr/ext.php @@ -0,0 +1,15 @@ + array( + 'write_words' => 'Vurgulanacak kelimeler', + 'write_words_more' => '(yeni satırla ayrılmış)', + 'enable_in_article' => 'Makalede vurgulamayı da etkinleştir', + 'enable_in_article_more' => '(⚠️ çok fazla kelimeyle daha yavaş olabilir)', + 'enable_logs' => 'Günlükleri etkinleştir', + 'case_sensitive' => 'Harfe duyarlı', + 'separate_word_search' => 'Ayrı kelime araması', + 'test_highlighting_word' => 'vurgulamak', + 'permission_problem' => 'Yapılandırma dosyanız yazılabilir değil, lütfen %s için dosya izinlerini değiştirin', + ), +); diff --git a/xExtension-WordHighlighter/metadata.json b/xExtension-WordHighlighter/metadata.json new file mode 100644 index 0000000..f716b5c --- /dev/null +++ b/xExtension-WordHighlighter/metadata.json @@ -0,0 +1,8 @@ +{ + "name": "Word highlighter", + "author": "Lukas Melega", + "description": "Highlight specific words", + "version": "0.0.3", + "entrypoint": "WordHighlighter", + "type": "user" +} diff --git a/xExtension-WordHighlighter/snapshot-dark.png b/xExtension-WordHighlighter/snapshot-dark.png new file mode 100644 index 0000000..01dbd11 Binary files /dev/null and b/xExtension-WordHighlighter/snapshot-dark.png differ diff --git a/xExtension-WordHighlighter/snapshot.png b/xExtension-WordHighlighter/snapshot.png new file mode 100644 index 0000000..822084e Binary files /dev/null and b/xExtension-WordHighlighter/snapshot.png differ diff --git a/xExtension-WordHighlighter/static/.gitignore b/xExtension-WordHighlighter/static/.gitignore new file mode 100644 index 0000000..6d6756d --- /dev/null +++ b/xExtension-WordHighlighter/static/.gitignore @@ -0,0 +1,2 @@ +config-words.*.js +config-words.*.txt diff --git a/xExtension-WordHighlighter/static/mark.min.js b/xExtension-WordHighlighter/static/mark.min.js new file mode 100644 index 0000000..c725bc4 --- /dev/null +++ b/xExtension-WordHighlighter/static/mark.min.js @@ -0,0 +1,13 @@ +/** + * mark.js (Library for highlighting words) + * https://github.com/julkue/mark.js/blob/master/dist/mark.es6.min.js + */ +/* eslint-disable */ + +/*!*************************************************** +* mark.js v9.0.0 +* https://markjs.io/ +* Copyright (c) 2014–2018, Julian Kühnel +* Released under the MIT license https://git.io/vwTVl +*****************************************************/ +!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):e.Mark=t()}(this,function(){"use strict";class e{constructor(e,t=!0,s=[],r=5e3){this.ctx=e,this.iframes=t,this.exclude=s,this.iframesTimeout=r}static matches(e,t){const s="string"==typeof t?[t]:t,r=e.matches||e.matchesSelector||e.msMatchesSelector||e.mozMatchesSelector||e.oMatchesSelector||e.webkitMatchesSelector;if(r){let t=!1;return s.every(s=>!r.call(e,s)||(t=!0,!1)),t}return!1}getContexts(){let e,t=[];return(e=void 0!==this.ctx&&this.ctx?NodeList.prototype.isPrototypeOf(this.ctx)?Array.prototype.slice.call(this.ctx):Array.isArray(this.ctx)?this.ctx:"string"==typeof this.ctx?Array.prototype.slice.call(document.querySelectorAll(this.ctx)):[this.ctx]:[]).forEach(e=>{const s=t.filter(t=>t.contains(e)).length>0;-1!==t.indexOf(e)||s||t.push(e)}),t}getIframeContents(e,t,s=(()=>{})){let r;try{const t=e.contentWindow;if(r=t.document,!t||!r)throw new Error("iframe inaccessible")}catch(e){s()}r&&t(r)}isIframeBlank(e){const t="about:blank",s=e.getAttribute("src").trim();return e.contentWindow.location.href===t&&s!==t&&s}observeIframeLoad(e,t,s){let r=!1,i=null;const n=()=>{if(!r){r=!0,clearTimeout(i);try{this.isIframeBlank(e)||(e.removeEventListener("load",n),this.getIframeContents(e,t,s))}catch(e){s()}}};e.addEventListener("load",n),i=setTimeout(n,this.iframesTimeout)}onIframeReady(e,t,s){try{"complete"===e.contentWindow.document.readyState?this.isIframeBlank(e)?this.observeIframeLoad(e,t,s):this.getIframeContents(e,t,s):this.observeIframeLoad(e,t,s)}catch(e){s()}}waitForIframes(e,t){let s=0;this.forEachIframe(e,()=>!0,e=>{s++,this.waitForIframes(e.querySelector("html"),()=>{--s||t()})},e=>{e||t()})}forEachIframe(t,s,r,i=(()=>{})){let n=t.querySelectorAll("iframe"),o=n.length,a=0;n=Array.prototype.slice.call(n);const h=()=>{--o<=0&&i(a)};o||h(),n.forEach(t=>{e.matches(t,this.exclude)?h():this.onIframeReady(t,e=>{s(t)&&(a++,r(e)),h()},h)})}createIterator(e,t,s){return document.createNodeIterator(e,t,s,!1)}createInstanceOnIframe(t){return new e(t.querySelector("html"),this.iframes)}compareNodeIframe(e,t,s){if(e.compareDocumentPosition(s)&Node.DOCUMENT_POSITION_PRECEDING){if(null===t)return!0;if(t.compareDocumentPosition(s)&Node.DOCUMENT_POSITION_FOLLOWING)return!0}return!1}getIteratorNode(e){const t=e.previousNode();let s;return{prevNode:t,node:s=null===t?e.nextNode():e.nextNode()&&e.nextNode()}}checkIframeFilter(e,t,s,r){let i=!1,n=!1;return r.forEach((e,t)=>{e.val===s&&(i=t,n=e.handled)}),this.compareNodeIframe(e,t,s)?(!1!==i||n?!1===i||n||(r[i].handled=!0):r.push({val:s,handled:!0}),!0):(!1===i&&r.push({val:s,handled:!1}),!1)}handleOpenIframes(e,t,s,r){e.forEach(e=>{e.handled||this.getIframeContents(e.val,e=>{this.createInstanceOnIframe(e).forEachNode(t,s,r)})})}iterateThroughNodes(e,t,s,r,i){const n=this.createIterator(t,e,r);let o,a,h=[],c=[],l=()=>(({prevNode:a,node:o}=this.getIteratorNode(n)),o);for(;l();)this.iframes&&this.forEachIframe(t,e=>this.checkIframeFilter(o,a,e,h),t=>{this.createInstanceOnIframe(t).forEachNode(e,e=>c.push(e),r)}),c.push(o);c.forEach(e=>{s(e)}),this.iframes&&this.handleOpenIframes(h,e,s,r),i()}forEachNode(e,t,s,r=(()=>{})){const i=this.getContexts();let n=i.length;n||r(),i.forEach(i=>{const o=()=>{this.iterateThroughNodes(e,i,t,s,()=>{--n<=0&&r()})};this.iframes?this.waitForIframes(i,o):o()})}}class t{constructor(e){this.opt=Object.assign({},{diacritics:!0,synonyms:{},accuracy:"partially",caseSensitive:!1,ignoreJoiners:!1,ignorePunctuation:[],wildcards:"disabled"},e)}create(e){return"disabled"!==this.opt.wildcards&&(e=this.setupWildcardsRegExp(e)),e=this.escapeStr(e),Object.keys(this.opt.synonyms).length&&(e=this.createSynonymsRegExp(e)),(this.opt.ignoreJoiners||this.opt.ignorePunctuation.length)&&(e=this.setupIgnoreJoinersRegExp(e)),this.opt.diacritics&&(e=this.createDiacriticsRegExp(e)),e=this.createMergedBlanksRegExp(e),(this.opt.ignoreJoiners||this.opt.ignorePunctuation.length)&&(e=this.createJoinersRegExp(e)),"disabled"!==this.opt.wildcards&&(e=this.createWildcardsRegExp(e)),e=this.createAccuracyRegExp(e),new RegExp(e,`gm${this.opt.caseSensitive?"":"i"}`)}sortByLength(e){return e.sort((e,t)=>e.length===t.length?e>t?1:-1:t.length-e.length)}escapeStr(e){return e.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g,"\\$&")}createSynonymsRegExp(e){const t=this.opt.synonyms,s=this.opt.caseSensitive?"":"i",r=this.opt.ignoreJoiners||this.opt.ignorePunctuation.length?"\0":"";for(let i in t)if(t.hasOwnProperty(i)){let n=Array.isArray(t[i])?t[i]:[t[i]];n.unshift(i),(n=this.sortByLength(n).map(e=>("disabled"!==this.opt.wildcards&&(e=this.setupWildcardsRegExp(e)),e=this.escapeStr(e))).filter(e=>""!==e)).length>1&&(e=e.replace(new RegExp(`(${n.map(e=>this.escapeStr(e)).join("|")})`,`gm${s}`),r+`(${n.map(e=>this.processSynonyms(e)).join("|")})`+r))}return e}processSynonyms(e){return(this.opt.ignoreJoiners||this.opt.ignorePunctuation.length)&&(e=this.setupIgnoreJoinersRegExp(e)),e}setupWildcardsRegExp(e){return(e=e.replace(/(?:\\)*\?/g,e=>"\\"===e.charAt(0)?"?":"")).replace(/(?:\\)*\*/g,e=>"\\"===e.charAt(0)?"*":"")}createWildcardsRegExp(e){let t="withSpaces"===this.opt.wildcards;return e.replace(/\u0001/g,t?"[\\S\\s]?":"\\S?").replace(/\u0002/g,t?"[\\S\\s]*?":"\\S*")}setupIgnoreJoinersRegExp(e){return e.replace(/[^(|)\\]/g,(e,t,s)=>{let r=s.charAt(t+1);return/[(|)\\]/.test(r)||""===r?e:e+"\0"})}createJoinersRegExp(e){let t=[];const s=this.opt.ignorePunctuation;return Array.isArray(s)&&s.length&&t.push(this.escapeStr(s.join(""))),this.opt.ignoreJoiners&&t.push("\\u00ad\\u200b\\u200c\\u200d"),t.length?e.split(/\u0000+/).join(`[${t.join("")}]*`):e}createDiacriticsRegExp(e){const t=this.opt.caseSensitive?"":"i",s=this.opt.caseSensitive?["aàáảãạăằắẳẵặâầấẩẫậäåāą","AÀÁẢÃẠĂẰẮẲẴẶÂẦẤẨẪẬÄÅĀĄ","cçćč","CÇĆČ","dđď","DĐĎ","eèéẻẽẹêềếểễệëěēę","EÈÉẺẼẸÊỀẾỂỄỆËĚĒĘ","iìíỉĩịîïī","IÌÍỈĨỊÎÏĪ","lł","LŁ","nñňń","NÑŇŃ","oòóỏõọôồốổỗộơởỡớờợöøō","OÒÓỎÕỌÔỒỐỔỖỘƠỞỠỚỜỢÖØŌ","rř","RŘ","sšśșş","SŠŚȘŞ","tťțţ","TŤȚŢ","uùúủũụưừứửữựûüůū","UÙÚỦŨỤƯỪỨỬỮỰÛÜŮŪ","yýỳỷỹỵÿ","YÝỲỶỸỴŸ","zžżź","ZŽŻŹ"]:["aàáảãạăằắẳẵặâầấẩẫậäåāąAÀÁẢÃẠĂẰẮẲẴẶÂẦẤẨẪẬÄÅĀĄ","cçćčCÇĆČ","dđďDĐĎ","eèéẻẽẹêềếểễệëěēęEÈÉẺẼẸÊỀẾỂỄỆËĚĒĘ","iìíỉĩịîïīIÌÍỈĨỊÎÏĪ","lłLŁ","nñňńNÑŇŃ","oòóỏõọôồốổỗộơởỡớờợöøōOÒÓỎÕỌÔỒỐỔỖỘƠỞỠỚỜỢÖØŌ","rřRŘ","sšśșşSŠŚȘŞ","tťțţTŤȚŢ","uùúủũụưừứửữựûüůūUÙÚỦŨỤƯỪỨỬỮỰÛÜŮŪ","yýỳỷỹỵÿYÝỲỶỸỴŸ","zžżźZŽŻŹ"];let r=[];return e.split("").forEach(i=>{s.every(s=>{if(-1!==s.indexOf(i)){if(r.indexOf(s)>-1)return!1;e=e.replace(new RegExp(`[${s}]`,`gm${t}`),`[${s}]`),r.push(s)}return!0})}),e}createMergedBlanksRegExp(e){return e.replace(/[\s]+/gim,"[\\s]+")}createAccuracyRegExp(e){let t=this.opt.accuracy,s="string"==typeof t?t:t.value,r="string"==typeof t?[]:t.limiters,i="";switch(r.forEach(e=>{i+=`|${this.escapeStr(e)}`}),s){case"partially":default:return`()(${e})`;case"complementary":return`()([^${i="\\s"+(i||this.escapeStr("!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~¡¿"))}]*${e}[^${i}]*)`;case"exactly":return`(^|\\s${i})(${e})(?=$|\\s${i})`}}}class s{constructor(e){this.ctx=e,this.ie=!1;const t=window.navigator.userAgent;(t.indexOf("MSIE")>-1||t.indexOf("Trident")>-1)&&(this.ie=!0)}set opt(e){this._opt=Object.assign({},{element:"",className:"",exclude:[],iframes:!1,iframesTimeout:5e3,separateWordSearch:!0,acrossElements:!1,ignoreGroups:0,each:()=>{},noMatch:()=>{},filter:()=>!0,done:()=>{},debug:!1,log:window.console},e)}get opt(){return this._opt}get iterator(){return new e(this.ctx,this.opt.iframes,this.opt.exclude,this.opt.iframesTimeout)}log(e,t="debug"){const s=this.opt.log;this.opt.debug&&"object"==typeof s&&"function"==typeof s[t]&&s[t](`mark.js: ${e}`)}getSeparatedKeywords(e){let t=[];return e.forEach(e=>{this.opt.separateWordSearch?e.split(" ").forEach(e=>{e.trim()&&-1===t.indexOf(e)&&t.push(e)}):e.trim()&&-1===t.indexOf(e)&&t.push(e)}),{keywords:t.sort((e,t)=>t.length-e.length),length:t.length}}isNumeric(e){return Number(parseFloat(e))==e}checkRanges(e){if(!Array.isArray(e)||"[object Object]"!==Object.prototype.toString.call(e[0]))return this.log("markRanges() will only accept an array of objects"),this.opt.noMatch(e),[];const t=[];let s=0;return e.sort((e,t)=>e.start-t.start).forEach(e=>{let{start:r,end:i,valid:n}=this.callNoMatchOnInvalidRanges(e,s);n&&(e.start=r,e.length=i-r,t.push(e),s=i)}),t}callNoMatchOnInvalidRanges(e,t){let s,r,i=!1;return e&&void 0!==e.start?(r=(s=parseInt(e.start,10))+parseInt(e.length,10),this.isNumeric(e.start)&&this.isNumeric(e.length)&&r-t>0&&r-s>0?i=!0:(this.log("Ignoring invalid or overlapping range: "+`${JSON.stringify(e)}`),this.opt.noMatch(e))):(this.log(`Ignoring invalid range: ${JSON.stringify(e)}`),this.opt.noMatch(e)),{start:s,end:r,valid:i}}checkWhitespaceRanges(e,t,s){let r,i=!0,n=s.length,o=t-n,a=parseInt(e.start,10)-o;return(r=(a=a>n?n:a)+parseInt(e.length,10))>n&&(r=n,this.log(`End range automatically set to the max value of ${n}`)),a<0||r-a<0||a>n||r>n?(i=!1,this.log(`Invalid range: ${JSON.stringify(e)}`),this.opt.noMatch(e)):""===s.substring(a,r).replace(/\s+/g,"")&&(i=!1,this.log("Skipping whitespace only range: "+JSON.stringify(e)),this.opt.noMatch(e)),{start:a,end:r,valid:i}}getTextNodes(e){let t="",s=[];this.iterator.forEachNode(NodeFilter.SHOW_TEXT,e=>{s.push({start:t.length,end:(t+=e.textContent).length,node:e})},e=>this.matchesExclude(e.parentNode)?NodeFilter.FILTER_REJECT:NodeFilter.FILTER_ACCEPT,()=>{e({value:t,nodes:s})})}matchesExclude(t){return e.matches(t,this.opt.exclude.concat(["script","style","title","head","html"]))}wrapRangeInTextNode(e,t,s){const r=this.opt.element?this.opt.element:"mark",i=e.splitText(t),n=i.splitText(s-t);let o=document.createElement(r);return o.setAttribute("data-markjs","true"),this.opt.className&&o.setAttribute("class",this.opt.className),o.textContent=i.textContent,i.parentNode.replaceChild(o,i),n}wrapRangeInMappedTextNode(e,t,s,r,i){e.nodes.every((n,o)=>{const a=e.nodes[o+1];if(void 0===a||a.start>t){if(!r(n.node))return!1;const a=t-n.start,h=(s>n.end?n.end:s)-n.start,c=e.value.substr(0,n.start),l=e.value.substr(h+n.start);if(n.node=this.wrapRangeInTextNode(n.node,a,h),e.value=c+l,e.nodes.forEach((t,s)=>{s>=o&&(e.nodes[s].start>0&&s!==o&&(e.nodes[s].start-=h),e.nodes[s].end-=h)}),s-=h,i(n.node.previousSibling,n.start),!(s>n.end))return!1;t=n.end}return!0})}wrapGroups(e,t,s,r){return r((e=this.wrapRangeInTextNode(e,t,t+s)).previousSibling),e}separateGroups(e,t,s,r,i){let n=t.length;for(let s=1;s-1&&r(t[s],e)&&(e=this.wrapGroups(e,n,t[s].length,i))}return e}wrapMatches(e,t,s,r,i){const n=0===t?0:t+1;this.getTextNodes(t=>{t.nodes.forEach(t=>{let i;for(t=t.node;null!==(i=e.exec(t.textContent))&&""!==i[n];){if(this.opt.separateGroups)t=this.separateGroups(t,i,n,s,r);else{if(!s(i[n],t))continue;let e=i.index;if(0!==n)for(let t=1;t{let o;for(;null!==(o=e.exec(t.value))&&""!==o[n];){let i=o.index;if(0!==n)for(let e=1;es(o[n],e),(t,s)=>{e.lastIndex=s,r(t)})}i()})}wrapRangeFromIndex(e,t,s,r){this.getTextNodes(i=>{const n=i.value.length;e.forEach((e,r)=>{let{start:o,end:a,valid:h}=this.checkWhitespaceRanges(e,n,i.value);h&&this.wrapRangeInMappedTextNode(i,o,a,s=>t(s,e,i.value.substring(o,a),r),t=>{s(t,e)})}),r()})}unwrapMatches(e){const t=e.parentNode;let s=document.createDocumentFragment();for(;e.firstChild;)s.appendChild(e.removeChild(e.firstChild));t.replaceChild(s,e),this.ie?this.normalizeTextNode(t):t.normalize()}normalizeTextNode(e){if(e){if(3===e.nodeType)for(;e.nextSibling&&3===e.nextSibling.nodeType;)e.nodeValue+=e.nextSibling.nodeValue,e.parentNode.removeChild(e.nextSibling);else this.normalizeTextNode(e.firstChild);this.normalizeTextNode(e.nextSibling)}}markRegExp(e,t){this.opt=t,this.log(`Searching with expression "${e}"`);let s=0,r="wrapMatches";this.opt.acrossElements&&(r="wrapMatchesAcrossElements"),this[r](e,this.opt.ignoreGroups,(e,t)=>this.opt.filter(t,e,s),e=>{s++,this.opt.each(e)},()=>{0===s&&this.opt.noMatch(e),this.opt.done(s)})}mark(e,s){this.opt=s;let r=0,i="wrapMatches";const{keywords:n,length:o}=this.getSeparatedKeywords("string"==typeof e?[e]:e),a=e=>{const s=new t(this.opt).create(e);let h=0;this.log(`Searching with expression "${s}"`),this[i](s,1,(t,s)=>this.opt.filter(s,e,r,h),e=>{h++,r++,this.opt.each(e)},()=>{0===h&&this.opt.noMatch(e),n[o-1]===e?this.opt.done(r):a(n[n.indexOf(e)+1])})};this.opt.acrossElements&&(i="wrapMatchesAcrossElements"),0===o?this.opt.done(r):a(n[0])}markRanges(e,t){this.opt=t;let s=0,r=this.checkRanges(e);r&&r.length?(this.log("Starting to mark with the following ranges: "+JSON.stringify(r)),this.wrapRangeFromIndex(r,(e,t,s,r)=>this.opt.filter(e,t,s,r),(e,t)=>{s++,this.opt.each(e,t)},()=>{this.opt.done(s)})):this.opt.done(s)}unmark(t){this.opt=t;let s=this.opt.element?this.opt.element:"*";s+="[data-markjs]",this.opt.className&&(s+=`.${this.opt.className}`),this.log(`Removal selector "${s}"`),this.iterator.forEachNode(NodeFilter.SHOW_ELEMENT,e=>{this.unwrapMatches(e)},t=>{const r=e.matches(t,s),i=this.matchesExclude(t);return!r||i?NodeFilter.FILTER_REJECT:NodeFilter.FILTER_ACCEPT},this.opt.done)}}return function(e){const t=new s(e);return this.mark=((e,s)=>(t.mark(e,s),this)),this.markRegExp=((e,s)=>(t.markRegExp(e,s),this)),this.markRanges=((e,s)=>(t.markRanges(e,s),this)),this.unmark=(e=>(t.unmark(e),this)),this}}); diff --git a/xExtension-WordHighlighter/static/style.css b/xExtension-WordHighlighter/static/style.css new file mode 100644 index 0000000..6ad2b0b --- /dev/null +++ b/xExtension-WordHighlighter/static/style.css @@ -0,0 +1,14 @@ +/* WordHighlighter v0.0.2 (FreshRSS Extension) CSS */ +#stream mark { + padding: 2px; + padding-right: 0; /* because in case when part of word is highlighted */ + border-radius: 4px; +} + +#stream mark.mark-secondary { + background-color: rgba(255, 255, 0, 0.3) !important; +} + +html[class*="darkMode"] #stream mark.mark-secondary { + background-color: rgba(255, 255, 0, 0.5) !important; +} diff --git a/xExtension-WordHighlighter/static/style.rtl.css b/xExtension-WordHighlighter/static/style.rtl.css new file mode 100644 index 0000000..f5c89a1 --- /dev/null +++ b/xExtension-WordHighlighter/static/style.rtl.css @@ -0,0 +1,14 @@ +/* WordHighlighter v0.0.2 (FreshRSS Extension) CSS */ +#stream mark { + padding: 2px; + padding-left: 0; /* because in case when part of word is highlighted */ + border-radius: 4px; +} + +#stream mark.mark-secondary { + background-color: rgba(255, 255, 0, 0.3) !important; +} + +html[class*="darkMode"] #stream mark.mark-secondary { + background-color: rgba(255, 255, 0, 0.5) !important; +} diff --git a/xExtension-WordHighlighter/static/word-highlighter.js b/xExtension-WordHighlighter/static/word-highlighter.js new file mode 100644 index 0000000..97b3689 --- /dev/null +++ b/xExtension-WordHighlighter/static/word-highlighter.js @@ -0,0 +1,89 @@ +'use strict'; + +/* WordHighlighter v0.0.2 (FreshRSS Extension) */ + +function wordHighlighter(c /* console */, Mark, context, OPTIONS) { + const markConf = (done, counter) => ({ + caseSensitive: OPTIONS.case_sensitive || false, + separateWordSearch: OPTIONS.separate_word_search || false, + ignoreJoiners: OPTIONS.ignore_joiners || false, + exclude: [ + 'mark', + ...(OPTIONS.enable_in_article ? [] : ['article *']), + ], + done: (n) => (counter.value += n) && done(), + noMatch: done, + }); + + const m = new Mark(context); + const changePageListener = debounce(200, (x) => { + OPTIONS.enable_logs && c.group('WordHighlighter: page change'); + stopObserving(); + highlightWords(m, startObserving); + }); + + const mo = new MutationObserver(changePageListener); + mo.observe(context, { subtree: true, childList: true }); + + function startObserving() { + mo.observe(context, { subtree: true, childList: true }); + } + + function stopObserving() { + mo.disconnect(); + } + + function highlightWords(m, done) { + const start = performance.now(); + const hCounter = { value: 0 }; + + new Promise((resolve) => + m.mark(OPTIONS.words || [], { ...markConf(resolve, hCounter) }) + ) + .finally(() => { + if (OPTIONS.enable_logs) { + c.log(`WordHighlighter: ${hCounter.value} new highlights added in ${performance.now() - start}ms.`); + c.groupEnd(); + } + typeof done === 'function' && done(); + }); + } + + highlightWords(m); +} + +// MAIN: + +(function main() { + try { + const confName = 'WordHighlighterConf'; + const OPTIONS = window[confName] || { }; + const onMainPage = !(new URL(window.location)).searchParams.get('c'); + if (onMainPage) { + console.log('WordHighlighter: script load...'); + const context = document.querySelector('#stream'); + wordHighlighter(console, window.Mark || (Error('mark.js library is not loaded ❗️')), context, OPTIONS); + console.log('WordHighlighter: script loaded.✅'); + } else { + OPTIONS.enable_logs && console.log('WordHighlighter: ❗️ paused outside of feed page'); + } + return Promise.resolve(); + } catch (error) { + console.error('WordHighlighter: ❌', error); + return Promise.reject(error); + } +})(); + +// Util functions: + +function debounce(duration, func) { + let timeout; + return function (...args) { + const effect = () => { + timeout = null; + return func.apply(this, args); + }; + clearTimeout(timeout); + timeout = setTimeout(effect, duration); + }; +} diff --git a/xExtension-CustomJS/LICENSE b/xExtension-YouTube-wide/LICENSE similarity index 86% rename from xExtension-CustomJS/LICENSE rename to xExtension-YouTube-wide/LICENSE index cebe035..94a9ed0 100644 --- a/xExtension-CustomJS/LICENSE +++ b/xExtension-YouTube-wide/LICENSE @@ -1,5 +1,5 @@ -GNU AFFERO GENERAL PUBLIC LICENSE - Version 3, 19 November 2007 + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 Copyright (C) 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies @@ -7,15 +7,17 @@ GNU AFFERO GENERAL PUBLIC LICENSE Preamble - The GNU Affero General Public License is a free, copyleft license for -software and other kinds of works, specifically designed to ensure -cooperation with the community in the case of network server software. + The GNU General Public License is a free, copyleft license for +software and other kinds of works. The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, -our General Public Licenses are intended to guarantee your freedom to +the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free -software for all its users. +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you @@ -24,34 +26,44 @@ them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things. - Developers that use our General Public Licenses protect your rights -with two steps: (1) assert copyright on the software, and (2) offer -you this License which gives you legal permission to copy, distribute -and/or modify the software. + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. - A secondary benefit of defending all users' freedom is that -improvements made in alternate versions of the program, if they -receive widespread use, become available for other developers to -incorporate. Many developers of free software are heartened and -encouraged by the resulting cooperation. However, in the case of -software used on network servers, this result may fail to come about. -The GNU General Public License permits making a modified version and -letting the public access it on a server without ever releasing its -source code to the public. + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. - The GNU Affero General Public License is designed specifically to -ensure that, in such cases, the modified source code becomes available -to the community. It requires the operator of a network server to -provide the source code of the modified version running there to the -users of that server. Therefore, public use of a modified version, on -a publicly accessible server, gives the public access to the source -code of the modified version. + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. - An older license, called the Affero General Public License and -published by Affero, was designed to accomplish similar goals. This is -a different license, not a version of the Affero GPL, but Affero has -released a new version of the Affero GPL which permits relicensing under -this license. + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. The precise terms and conditions for copying, distribution and modification follow. @@ -60,7 +72,7 @@ modification follow. 0. Definitions. - "This License" refers to version 3 of the GNU Affero General Public License. + "This License" refers to version 3 of the GNU General Public License. "Copyright" also means copyright-like laws that apply to other kinds of works, such as semiconductor masks. @@ -537,45 +549,35 @@ to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program. - 13. Remote Network Interaction; Use with the GNU General Public License. - - Notwithstanding any other provision of this License, if you modify the -Program, your modified version must prominently offer all users -interacting with it remotely through a computer network (if your version -supports such interaction) an opportunity to receive the Corresponding -Source of your version by providing access to the Corresponding Source -from a network server at no charge, through some standard or customary -means of facilitating copying of software. This Corresponding Source -shall include the Corresponding Source for any work covered by version 3 -of the GNU General Public License that is incorporated pursuant to the -following paragraph. + 13. Use with the GNU Affero General Public License. Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed -under version 3 of the GNU General Public License into a single +under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, -but the work with which it is combined will remain governed by version -3 of the GNU General Public License. +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. 14. Revised Versions of this License. The Free Software Foundation may publish revised and/or new versions of -the GNU Affero General Public License from time to time. Such new versions -will be similar in spirit to the present version, but may differ in detail to +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the -Program specifies that a certain numbered version of the GNU Affero General +Program specifies that a certain numbered version of the GNU General Public License "or any later version" applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the -GNU Affero General Public License, you may choose any version ever published +GNU General Public License, you may choose any version ever published by the Free Software Foundation. If the Program specifies that a proxy can decide which future -versions of the GNU Affero General Public License can be used, that proxy's +versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program. @@ -633,30 +635,40 @@ the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software: you can redistribute it and/or modify - it under the terms of the GNU Affero General Public License as published - by the Free Software Foundation, either version 3 of the License, or + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Affero General Public License for more details. + GNU General Public License for more details. - You should have received a copy of the GNU Affero General Public License + You should have received a copy of the GNU General Public License along with this program. If not, see . Also add information on how to contact you by electronic and paper mail. - If your software can interact with users remotely through a computer -network, you should also make sure that it provides a way for users to -get its source. For example, if your program is a web application, its -interface could display a "Source" link that leads users to an archive -of the code. There are many ways you could offer source, and different -solutions will be better for different programs; see section 13 for the -specific requirements. + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". You should also get your employer (if you work as a programmer) or school, if any, to sign a "copyright disclaimer" for the program, if necessary. -For more information on this, and how to apply and follow the GNU AGPL, see +For more information on this, and how to apply and follow the GNU GPL, see . + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/xExtension-YouTube-wide/README.md b/xExtension-YouTube-wide/README.md new file mode 100644 index 0000000..a833090 --- /dev/null +++ b/xExtension-YouTube-wide/README.md @@ -0,0 +1,89 @@ +# FreshRSS - YouTube video extension + +This FreshRSS extension allows you to directly watch YouTube/PeerTube videos from within subscribed channel feeds. + +To use it, upload the ```xExtension-YouTube``` directory to the FreshRSS `./extensions` directory on your server and enable it on the extension panel in FreshRSS. + +## Features + +- Embeds Youtube videos directly in FreshRSS, instead of linking to the Youtube page +- Simplifies the subscription to channel URLs by automatically detecting the channels feed URL + +You can simply add Youtube video subscriptions by pasting URLs like: +- `https://www.youtube.com/channel/UCwbjxO5qQTMkSZVueqKwxuw` +- `https://www.youtube.com/user/AndrewTrials` + +## Screenshots + +With FreshRSS and an original Youtube Channel feed: +![screenshot before](https://github.com/kevinpapst/freshrss-youtube/blob/screenshot-readme/before.png?raw=true "Without this extension the video is not shown") + +With activated Youtube extension: +![screenshot after](https://github.com/kevinpapst/freshrss-youtube/blob/screenshot-readme/after.png?raw=true "After activating the extension you can enjoy your video directly in the FreshRSS stream") + +## Wide Version + +Use this one if you'd like to fill the whole pane or much of the browser window with the video, rather than specifying a fixed size. If you really want a large video, I suggest adding this User CSS, to prevent the duplication of info shown in the top item bar: + +``` +div.content > header { + display: none !important; +} +.flux_header { + font-size: 18px !important; +} + +.flux .flux_header .item .title { + font-size: 18px !important; +} + +.flux .flux_header .item .date { + font-size: 18px !important; +} +``` + +This hides the header nested within each item, and enlarges the header that already is shown. This is useful for non-video content, too. + + +## Changelog +0.14 +- Changed the embed code to allow relative sizing. You can simply specify a width (e.g. '100%') and it will scale via aspect-ratio. +- Fixed a bug where embedding the video didn't replace all of the content, just the first enclosure, leaving thumbnails and channel descriptions under the video. + +0.12: +- Turkish language support added + +0.11: +- Modernized codebase for latest FreshRSS release 1.23.1 +- Moved from [custom repo](https://github.com/kevinpapst/freshrss-youtube) to FreshRSS official extension repo + +0.10: +- Enhance feed content formatting when included +- Enhance YouTube URL matching + +0.9: +- Set the extension level at "user" (**users must re-enable the extension**) +- Fix calls to unset configuration variables +- Register translations when extension is disabled + +0.8: +- Automatically convert channel and username URLs to feed URLs + +0.7: +- Support for PeerTube feed + +0.6: +- Support cookie-less domain [youtube-nocookie.com](https://www.youtube-nocookie.com) for embedding + +0.5: +- Opened "API" for external usage + +0.4: +- Added option to display original feed content (currently Youtube inserts a download icon link to the video file) +- Fixed config loading + +0.3: +- Added installation hints + +0.2: +- Fixed "Use of undefined constant FreshRSS_Context" diff --git a/xExtension-YouTube-wide/configure.phtml b/xExtension-YouTube-wide/configure.phtml new file mode 100644 index 0000000..3bdada7 --- /dev/null +++ b/xExtension-YouTube-wide/configure.phtml @@ -0,0 +1,41 @@ + +
+ +
+ + +
+ +
+ + +
+ +
+ +
+ +
+ +
+ +
+
+ +
+
+ + +
+
+
+ diff --git a/xExtension-YouTube-wide/extension.php b/xExtension-YouTube-wide/extension.php new file mode 100644 index 0000000..d977002 --- /dev/null +++ b/xExtension-YouTube-wide/extension.php @@ -0,0 +1,267 @@ +getFileUrl('style.css', 'css')); + $this->registerHook('entry_before_display', [$this, 'embedYouTubeVideo']); + $this->registerHook('check_url_before_add', [self::class, 'convertYoutubeFeedUrl']); + $this->registerTranslates(); + } + + public static function convertYoutubeFeedUrl(string $url): string + { + $matches = []; + + if (preg_match('#^https?://www\.youtube\.com/channel/([0-9a-zA-Z_-]{6,36})#', $url, $matches) === 1) { + return 'https://www.youtube.com/feeds/videos.xml?channel_id=' . $matches[1]; + } + + if (preg_match('#^https?://www\.youtube\.com/user/([0-9a-zA-Z_-]{6,36})#', $url, $matches) === 1) { + return 'https://www.youtube.com/feeds/videos.xml?user=' . $matches[1]; + } + + return $url; + } + + /** + * Initializes the extension configuration, if the user context is available. + * Do not call that in your extensions init() method, it can't be used there. + * @throws FreshRSS_Context_Exception + */ + public function loadConfigValues(): void + { + if (!class_exists('FreshRSS_Context', false) || !FreshRSS_Context::hasUserConf()) { + return; + } + + $width = FreshRSS_Context::userConf()->attributeString('ytw_width'); + if ($width !== null) { + $this->width = $width; + } + + $height = FreshRSS_Context::userConf()->attributeString('ytw_height'); + if ($height !== null) { + $this->height = $height; + } + + $showContent = FreshRSS_Context::userConf()->attributeBool('ytw_show_content'); + if ($showContent !== null) { + $this->showContent = $showContent; + } + + $noCookie = FreshRSS_Context::userConf()->attributeBool('ytw_nocookie'); + if ($noCookie !== null) { + $this->useNoCookie = $noCookie; + } + } + + /** + * Returns the width in pixel for the YouTube player iframe. + * You have to call loadConfigValues() before this one, otherwise you get default values. + */ + public function getWidth(): string + { + return $this->width; + } + + /** + * Returns the height in pixel for the YouTube player iframe. + * You have to call loadConfigValues() before this one, otherwise you get default values. + */ + public function getHeight(): string + { + return $this->height; + } + + /** + * Returns whether this extension displays the content of the YouTube feed. + * You have to call loadConfigValues() before this one, otherwise you get default values. + */ + public function isShowContent(): bool + { + return $this->showContent; + } + + /** + * Returns if this extension should use youtube-nocookie.com instead of youtube.com. + * You have to call loadConfigValues() before this one, otherwise you get default values. + */ + public function isUseNoCookieDomain(): bool + { + return $this->useNoCookie; + } + + /** + * Inserts the YouTube video iframe into the content of an entry, if the entries link points to a YouTube watch URL. + * @throws FreshRSS_Context_Exception + */ + public function embedYouTubeVideo(FreshRSS_Entry $entry): FreshRSS_Entry + { + $link = $entry->link(); + + // if (preg_match('#^https?://www\.youtube\.com/watch\?v=|/videos/watch/[0-9a-f-]{36}$#', $link) !== 1) { +// return $entry; +// } + if (preg_match('#^https?://www\.youtube\.com/watch\?v=|/videos/watch/#', $link) !== 1) { + return $entry; + } + + $this->loadConfigValues(); + + if (stripos($entry->content(), ''; + + if ($this->showContent === True) { + $doc = new DOMDocument(); + $doc->encoding = 'UTF-8'; + $doc->recover = true; + $doc->strictErrorChecking = false; + + if ($doc->loadHTML('' . $entry->content())) { + $xpath = new DOMXPath($doc); + + /** @var DOMNodeList $titles */ + $titles = $xpath->evaluate("//*[@class='enclosure-title']"); + /** @var DOMNodeList $thumbnails */ + $thumbnails = $xpath->evaluate("//*[@class='enclosure-thumbnail']/@src"); + /** @var DOMNodeList $descriptions */ + $descriptions = $xpath->evaluate("//*[@class='enclosure-description']"); + + $content = '
'; + + // We hide the title so it doesn't appear in the final article, which would be redundant with the RSS article title, + // but we keep it in the content anyway, so RSS clients can extract it if needed. + if ($titles->length > 0 && $titles[0] instanceof DOMNode) { + $content .= ''; + } + + // We hide the thumbnail so it doesn't appear in the final article, which would be redundant with the YouTube player preview, + // but we keep it in the content anyway, so RSS clients can extract it to display a preview where it wants (in article listing, + // by example, like with Reeder). + if ($thumbnails->length > 0 && $thumbnails[0] instanceof DOMNode) { + $content .= ''; + } + + $content .= $iframe; + + if ($descriptions->length > 0 && $descriptions[0] instanceof DOMNode) { + $content .= '

' . nl2br(htmlspecialchars($descriptions[0]->nodeValue ?? '', ENT_COMPAT, 'UTF-8'), use_xhtml: true) . '

'; + } + + $content .= "
\n"; + } else { + $content = $iframe . $entry->content(); + } + } else { + $content = $iframe; + } + + return $content; + } + + /** + * This function is called by FreshRSS when the configuration page is loaded, and when configuration is saved. + * - We save configuration in case of a post. + * - We (re)load configuration in all case, so they are in-sync after a save and before a page load. + * @throws FreshRSS_Context_Exception + */ + #[\Override] + public function handleConfigureAction(): void + { + $this->registerTranslates(); + + if (Minz_Request::isPost()) { + FreshRSS_Context::userConf()->_attribute('ytw_height', Minz_Request::paramString('ytw_height')); + FreshRSS_Context::userConf()->_attribute('ytw_width', Minz_Request::paramString('ytw_width')); + FreshRSS_Context::userConf()->_attribute('ytw_show_content', Minz_Request::paramBoolean('ytw_show_content')); + FreshRSS_Context::userConf()->_attribute('ytw_nocookie', Minz_Request::paramInt('ytw_nocookie')); + FreshRSS_Context::userConf()->save(); + } + + $this->loadConfigValues(); + } +} diff --git a/xExtension-YouTube-wide/i18n/de/ext.php b/xExtension-YouTube-wide/i18n/de/ext.php new file mode 100644 index 0000000..e692670 --- /dev/null +++ b/xExtension-YouTube-wide/i18n/de/ext.php @@ -0,0 +1,11 @@ + array( + 'height' => 'Höhe des Players', + 'width' => 'Breite des Players', + 'updates' => 'Die neueste Version des Plugins findest Du bei', + 'show_content' => 'Zeige den Inhalt des Feeds an', + 'use_nocookie' => 'Verwende die Cookie-freie Domain www.youtube-nocookie.com', + ), +); diff --git a/xExtension-YouTube-wide/i18n/en/ext.php b/xExtension-YouTube-wide/i18n/en/ext.php new file mode 100644 index 0000000..5e38839 --- /dev/null +++ b/xExtension-YouTube-wide/i18n/en/ext.php @@ -0,0 +1,10 @@ + array( + 'height' => 'Player height (empty for auto)', + 'width' => 'Player width (int or string like 100%)', + 'show_content' => 'Display the feeds content', + 'use_nocookie' => 'Use the cookie-free domain www.youtube-nocookie.com', + ), +); diff --git a/xExtension-YouTube-wide/i18n/fr/ext.php b/xExtension-YouTube-wide/i18n/fr/ext.php new file mode 100644 index 0000000..3beee1b --- /dev/null +++ b/xExtension-YouTube-wide/i18n/fr/ext.php @@ -0,0 +1,11 @@ + array( + 'height' => 'Hauteur du lecteur', + 'width' => 'Largeur du lecteur', + 'updates' => 'Vous pouvez trouver la dernière mise à jour de l’extension sur ', + 'show_content' => 'Afficher le contenu du flux', + 'use_nocookie' => 'Utiliser le domaine www.youtube-nocookie.com pour éviter les cookies', + ), +); diff --git a/xExtension-YouTube-wide/i18n/tr/ext.php b/xExtension-YouTube-wide/i18n/tr/ext.php new file mode 100644 index 0000000..a206d2f --- /dev/null +++ b/xExtension-YouTube-wide/i18n/tr/ext.php @@ -0,0 +1,11 @@ + array( + 'height' => 'Oynatıcı yükseklik', + 'width' => 'Oynatıcı genişlik', + 'updates' => 'En son uzantı sürümünü şu adreste bulabilirsiniz:', + 'show_content' => 'Yayın içeriğini görüntüle', + 'use_nocookie' => 'Çerezsiz olan "www.youtube-nocookie.com" alan adını kullanın', + ), +); diff --git a/xExtension-YouTube-wide/metadata.json b/xExtension-YouTube-wide/metadata.json new file mode 100644 index 0000000..f1a9232 --- /dev/null +++ b/xExtension-YouTube-wide/metadata.json @@ -0,0 +1,8 @@ +{ + "name": "YouTube Video Feed Wide", + "author": "George Dorn", + "description": "Embed YouTube feeds inside article content with less rigid sizing.", + "version": "0.14", + "entrypoint": "YouTubeWide", + "type": "user" +} diff --git a/xExtension-YouTube-wide/static/style.css b/xExtension-YouTube-wide/static/style.css new file mode 100644 index 0000000..5be3738 --- /dev/null +++ b/xExtension-YouTube-wide/static/style.css @@ -0,0 +1,10 @@ +div.content:has(div.text:has(iframe.youtube-plugin-video)) > header { + display: none; + +} + +iframe.youtube-plugin-video { + width: 100%; + height: 100%; + aspect-ratio: 16 / 9; +} \ No newline at end of file diff --git a/xExtension-TTRSS_API/LICENSE b/xExtension-YouTube/LICENSE similarity index 86% rename from xExtension-TTRSS_API/LICENSE rename to xExtension-YouTube/LICENSE index cebe035..94a9ed0 100644 --- a/xExtension-TTRSS_API/LICENSE +++ b/xExtension-YouTube/LICENSE @@ -1,5 +1,5 @@ -GNU AFFERO GENERAL PUBLIC LICENSE - Version 3, 19 November 2007 + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 Copyright (C) 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies @@ -7,15 +7,17 @@ GNU AFFERO GENERAL PUBLIC LICENSE Preamble - The GNU Affero General Public License is a free, copyleft license for -software and other kinds of works, specifically designed to ensure -cooperation with the community in the case of network server software. + The GNU General Public License is a free, copyleft license for +software and other kinds of works. The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, -our General Public Licenses are intended to guarantee your freedom to +the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free -software for all its users. +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you @@ -24,34 +26,44 @@ them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things. - Developers that use our General Public Licenses protect your rights -with two steps: (1) assert copyright on the software, and (2) offer -you this License which gives you legal permission to copy, distribute -and/or modify the software. + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. - A secondary benefit of defending all users' freedom is that -improvements made in alternate versions of the program, if they -receive widespread use, become available for other developers to -incorporate. Many developers of free software are heartened and -encouraged by the resulting cooperation. However, in the case of -software used on network servers, this result may fail to come about. -The GNU General Public License permits making a modified version and -letting the public access it on a server without ever releasing its -source code to the public. + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. - The GNU Affero General Public License is designed specifically to -ensure that, in such cases, the modified source code becomes available -to the community. It requires the operator of a network server to -provide the source code of the modified version running there to the -users of that server. Therefore, public use of a modified version, on -a publicly accessible server, gives the public access to the source -code of the modified version. + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. - An older license, called the Affero General Public License and -published by Affero, was designed to accomplish similar goals. This is -a different license, not a version of the Affero GPL, but Affero has -released a new version of the Affero GPL which permits relicensing under -this license. + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. The precise terms and conditions for copying, distribution and modification follow. @@ -60,7 +72,7 @@ modification follow. 0. Definitions. - "This License" refers to version 3 of the GNU Affero General Public License. + "This License" refers to version 3 of the GNU General Public License. "Copyright" also means copyright-like laws that apply to other kinds of works, such as semiconductor masks. @@ -537,45 +549,35 @@ to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program. - 13. Remote Network Interaction; Use with the GNU General Public License. - - Notwithstanding any other provision of this License, if you modify the -Program, your modified version must prominently offer all users -interacting with it remotely through a computer network (if your version -supports such interaction) an opportunity to receive the Corresponding -Source of your version by providing access to the Corresponding Source -from a network server at no charge, through some standard or customary -means of facilitating copying of software. This Corresponding Source -shall include the Corresponding Source for any work covered by version 3 -of the GNU General Public License that is incorporated pursuant to the -following paragraph. + 13. Use with the GNU Affero General Public License. Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed -under version 3 of the GNU General Public License into a single +under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, -but the work with which it is combined will remain governed by version -3 of the GNU General Public License. +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. 14. Revised Versions of this License. The Free Software Foundation may publish revised and/or new versions of -the GNU Affero General Public License from time to time. Such new versions -will be similar in spirit to the present version, but may differ in detail to +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the -Program specifies that a certain numbered version of the GNU Affero General +Program specifies that a certain numbered version of the GNU General Public License "or any later version" applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the -GNU Affero General Public License, you may choose any version ever published +GNU General Public License, you may choose any version ever published by the Free Software Foundation. If the Program specifies that a proxy can decide which future -versions of the GNU Affero General Public License can be used, that proxy's +versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program. @@ -633,30 +635,40 @@ the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software: you can redistribute it and/or modify - it under the terms of the GNU Affero General Public License as published - by the Free Software Foundation, either version 3 of the License, or + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Affero General Public License for more details. + GNU General Public License for more details. - You should have received a copy of the GNU Affero General Public License + You should have received a copy of the GNU General Public License along with this program. If not, see . Also add information on how to contact you by electronic and paper mail. - If your software can interact with users remotely through a computer -network, you should also make sure that it provides a way for users to -get its source. For example, if your program is a web application, its -interface could display a "Source" link that leads users to an archive -of the code. There are many ways you could offer source, and different -solutions will be better for different programs; see section 13 for the -specific requirements. + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". You should also get your employer (if you work as a programmer) or school, if any, to sign a "copyright disclaimer" for the program, if necessary. -For more information on this, and how to apply and follow the GNU AGPL, see +For more information on this, and how to apply and follow the GNU GPL, see . + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/xExtension-YouTube/README.md b/xExtension-YouTube/README.md new file mode 100644 index 0000000..4116e36 --- /dev/null +++ b/xExtension-YouTube/README.md @@ -0,0 +1,62 @@ +# FreshRSS - YouTube video extension + +This FreshRSS extension allows you to directly watch YouTube/PeerTube videos from within subscribed channel feeds. + +To use it, upload the ```xExtension-YouTube``` directory to the FreshRSS `./extensions` directory on your server and enable it on the extension panel in FreshRSS. + +## Features + +- Embeds Youtube videos directly in FreshRSS, instead of linking to the Youtube page +- Simplifies the subscription to channel URLs by automatically detecting the channels feed URL + +You can simply add Youtube video subscriptions by pasting URLs like: +- `https://www.youtube.com/channel/UCwbjxO5qQTMkSZVueqKwxuw` +- `https://www.youtube.com/user/AndrewTrials` + +## Screenshots + +With FreshRSS and an original Youtube Channel feed: +![screenshot before](https://github.com/kevinpapst/freshrss-youtube/blob/screenshot-readme/before.png?raw=true "Without this extension the video is not shown") + +With activated Youtube extension: +![screenshot after](https://github.com/kevinpapst/freshrss-youtube/blob/screenshot-readme/after.png?raw=true "After activating the extension you can enjoy your video directly in the FreshRSS stream") + +## Changelog + +0.12: +- Turkish language support added + +0.11: +- Modernized codebase for latest FreshRSS release 1.23.1 +- Moved from [custom repo](https://github.com/kevinpapst/freshrss-youtube) to FreshRSS official extension repo + +0.10: +- Enhance feed content formatting when included +- Enhance YouTube URL matching + +0.9: +- Set the extension level at "user" (**users must re-enable the extension**) +- Fix calls to unset configuration variables +- Register translations when extension is disabled + +0.8: +- Automatically convert channel and username URLs to feed URLs + +0.7: +- Support for PeerTube feed + +0.6: +- Support cookie-less domain [youtube-nocookie.com](https://www.youtube-nocookie.com) for embedding + +0.5: +- Opened "API" for external usage + +0.4: +- Added option to display original feed content (currently Youtube inserts a download icon link to the video file) +- Fixed config loading + +0.3: +- Added installation hints + +0.2: +- Fixed "Use of undefined constant FreshRSS_Context" diff --git a/xExtension-YouTube/configure.phtml b/xExtension-YouTube/configure.phtml new file mode 100644 index 0000000..8828fe7 --- /dev/null +++ b/xExtension-YouTube/configure.phtml @@ -0,0 +1,45 @@ + +
+ +
+ + +
+ +
+ + +
+ +
+ +
+ +
+ +
+ +
+
+ +
+
+ + +
+
+
+ +

+ + GitHub. +

diff --git a/xExtension-YouTube/extension.php b/xExtension-YouTube/extension.php new file mode 100644 index 0000000..c8bec52 --- /dev/null +++ b/xExtension-YouTube/extension.php @@ -0,0 +1,264 @@ +registerHook('entry_before_display', [$this, 'embedYouTubeVideo']); + $this->registerHook('check_url_before_add', [self::class, 'convertYoutubeFeedUrl']); + $this->registerTranslates(); + } + + public static function convertYoutubeFeedUrl(string $url): string + { + $matches = []; + + if (preg_match('#^https?://www\.youtube\.com/channel/([0-9a-zA-Z_-]{6,36})#', $url, $matches) === 1) { + return 'https://www.youtube.com/feeds/videos.xml?channel_id=' . $matches[1]; + } + + if (preg_match('#^https?://www\.youtube\.com/user/([0-9a-zA-Z_-]{6,36})#', $url, $matches) === 1) { + return 'https://www.youtube.com/feeds/videos.xml?user=' . $matches[1]; + } + + return $url; + } + + /** + * Initializes the extension configuration, if the user context is available. + * Do not call that in your extensions init() method, it can't be used there. + * @throws FreshRSS_Context_Exception + */ + public function loadConfigValues(): void + { + if (!class_exists('FreshRSS_Context', false) || !FreshRSS_Context::hasUserConf()) { + return; + } + + $width = FreshRSS_Context::userConf()->attributeInt('yt_player_width'); + if ($width !== null) { + $this->width = $width; + } + + $height = FreshRSS_Context::userConf()->attributeInt('yt_player_height'); + if ($height !== null) { + $this->height = $height; + } + + $showContent = FreshRSS_Context::userConf()->attributeBool('yt_show_content'); + if ($showContent !== null) { + $this->showContent = $showContent; + } + + $noCookie = FreshRSS_Context::userConf()->attributeBool('yt_nocookie'); + if ($noCookie !== null) { + $this->useNoCookie = $noCookie; + } + } + + /** + * Returns the width in pixel for the YouTube player iframe. + * You have to call loadConfigValues() before this one, otherwise you get default values. + */ + public function getWidth(): int + { + return $this->width; + } + + /** + * Returns the height in pixel for the YouTube player iframe. + * You have to call loadConfigValues() before this one, otherwise you get default values. + */ + public function getHeight(): int + { + return $this->height; + } + + /** + * Returns whether this extension displays the content of the YouTube feed. + * You have to call loadConfigValues() before this one, otherwise you get default values. + */ + public function isShowContent(): bool + { + return $this->showContent; + } + + /** + * Returns if this extension should use youtube-nocookie.com instead of youtube.com. + * You have to call loadConfigValues() before this one, otherwise you get default values. + */ + public function isUseNoCookieDomain(): bool + { + return $this->useNoCookie; + } + + /** + * Inserts the YouTube video iframe into the content of an entry, if the entries link points to a YouTube watch URL. + * @throws FreshRSS_Context_Exception + */ + public function embedYouTubeVideo(FreshRSS_Entry $entry): FreshRSS_Entry + { + $link = $entry->link(); + + if (preg_match('#^https?://www\.youtube\.com/watch\?v=|/videos/watch/[0-9a-f-]{36}$#', $link) !== 1) { + return $entry; + } + + $this->loadConfigValues(); + + if (stripos($entry->content(), ''; + + if ($this->showContent) { + $doc = new DOMDocument(); + $doc->encoding = 'UTF-8'; + $doc->recover = true; + $doc->strictErrorChecking = false; + + if ($doc->loadHTML('' . $entry->content())) + { + $xpath = new DOMXPath($doc); + + /** @var DOMNodeList $titles */ + $titles = $xpath->evaluate("//*[@class='enclosure-title']"); + /** @var DOMNodeList $thumbnails */ + $thumbnails = $xpath->evaluate("//*[@class='enclosure-thumbnail']/@src"); + /** @var DOMNodeList $descriptions */ + $descriptions = $xpath->evaluate("//*[@class='enclosure-description']"); + + $content = '
'; + + // We hide the title so it doesn't appear in the final article, which would be redundant with the RSS article title, + // but we keep it in the content anyway, so RSS clients can extract it if needed. + if ($titles->length > 0 && $titles[0] instanceof DOMNode) { + $content .= ''; + } + + // We hide the thumbnail so it doesn't appear in the final article, which would be redundant with the YouTube player preview, + // but we keep it in the content anyway, so RSS clients can extract it to display a preview where it wants (in article listing, + // by example, like with Reeder). + if ($thumbnails->length > 0 && $thumbnails[0] instanceof DOMNode) { + $content .= ''; + } + + $content .= $iframe; + + if ($descriptions->length > 0 && $descriptions[0] instanceof DOMNode) { + $content .= '

' . nl2br(htmlspecialchars($descriptions[0]->nodeValue ?? '', ENT_COMPAT, 'UTF-8'), use_xhtml: true) . '

'; + } + + $content .= "
\n"; + } + else { + $content = $iframe . $entry->content(); + } + } + else { + $content = $iframe; + } + + return $content; + } + + /** + * This function is called by FreshRSS when the configuration page is loaded, and when configuration is saved. + * - We save configuration in case of a post. + * - We (re)load configuration in all case, so they are in-sync after a save and before a page load. + * @throws FreshRSS_Context_Exception + */ + #[\Override] + public function handleConfigureAction(): void + { + $this->registerTranslates(); + + if (Minz_Request::isPost()) { + FreshRSS_Context::userConf()->_attribute('yt_player_height', Minz_Request::paramInt('yt_height')); + FreshRSS_Context::userConf()->_attribute('yt_player_width', Minz_Request::paramInt('yt_width')); + FreshRSS_Context::userConf()->_attribute('yt_show_content', Minz_Request::paramBoolean('yt_show_content')); + FreshRSS_Context::userConf()->_attribute('yt_nocookie', Minz_Request::paramInt('yt_nocookie')); + FreshRSS_Context::userConf()->save(); + } + + $this->loadConfigValues(); + } +} diff --git a/xExtension-YouTube/i18n/de/ext.php b/xExtension-YouTube/i18n/de/ext.php new file mode 100644 index 0000000..e692670 --- /dev/null +++ b/xExtension-YouTube/i18n/de/ext.php @@ -0,0 +1,11 @@ + array( + 'height' => 'Höhe des Players', + 'width' => 'Breite des Players', + 'updates' => 'Die neueste Version des Plugins findest Du bei', + 'show_content' => 'Zeige den Inhalt des Feeds an', + 'use_nocookie' => 'Verwende die Cookie-freie Domain www.youtube-nocookie.com', + ), +); diff --git a/xExtension-YouTube/i18n/en/ext.php b/xExtension-YouTube/i18n/en/ext.php new file mode 100644 index 0000000..6f37c02 --- /dev/null +++ b/xExtension-YouTube/i18n/en/ext.php @@ -0,0 +1,11 @@ + array( + 'height' => 'Player height', + 'width' => 'Player width', + 'updates' => 'You can find the latest extension version at', + 'show_content' => 'Display the feeds content', + 'use_nocookie' => 'Use the cookie-free domain www.youtube-nocookie.com', + ), +); diff --git a/xExtension-YouTube/i18n/fr/ext.php b/xExtension-YouTube/i18n/fr/ext.php new file mode 100644 index 0000000..3beee1b --- /dev/null +++ b/xExtension-YouTube/i18n/fr/ext.php @@ -0,0 +1,11 @@ + array( + 'height' => 'Hauteur du lecteur', + 'width' => 'Largeur du lecteur', + 'updates' => 'Vous pouvez trouver la dernière mise à jour de l’extension sur ', + 'show_content' => 'Afficher le contenu du flux', + 'use_nocookie' => 'Utiliser le domaine www.youtube-nocookie.com pour éviter les cookies', + ), +); diff --git a/xExtension-YouTube/i18n/tr/ext.php b/xExtension-YouTube/i18n/tr/ext.php new file mode 100644 index 0000000..a206d2f --- /dev/null +++ b/xExtension-YouTube/i18n/tr/ext.php @@ -0,0 +1,11 @@ + array( + 'height' => 'Oynatıcı yükseklik', + 'width' => 'Oynatıcı genişlik', + 'updates' => 'En son uzantı sürümünü şu adreste bulabilirsiniz:', + 'show_content' => 'Yayın içeriğini görüntüle', + 'use_nocookie' => 'Çerezsiz olan "www.youtube-nocookie.com" alan adını kullanın', + ), +); diff --git a/xExtension-YouTube/metadata.json b/xExtension-YouTube/metadata.json new file mode 100644 index 0000000..2b709e2 --- /dev/null +++ b/xExtension-YouTube/metadata.json @@ -0,0 +1,8 @@ +{ + "name": "YouTube Video Feed", + "author": "Kevin Papst", + "description": "Embed YouTube feeds inside article content.", + "version": "0.13", + "entrypoint": "YouTube", + "type": "user" +} diff --git a/xExtension-showFeedID/README.md b/xExtension-showFeedID/README.md index 27d09fc..44f9dff 100644 --- a/xExtension-showFeedID/README.md +++ b/xExtension-showFeedID/README.md @@ -1,4 +1,4 @@ -Extension for FressRSS () +Extension for FreshRSS () It helps to find the feed IDs of each feed. diff --git a/xExtension-showFeedID/extension.php b/xExtension-showFeedID/extension.php index bf4abea..40fa6cc 100644 --- a/xExtension-showFeedID/extension.php +++ b/xExtension-showFeedID/extension.php @@ -2,8 +2,26 @@ declare(strict_types=1); -class ShowFeedIdExtension extends Minz_Extension { +final class ShowFeedIdExtension extends Minz_Extension { + #[\Override] public function init(): void { - Minz_View::appendScript($this->getFileUrl('showfeedid.js', 'js')); + if (Minz_Request::paramString('c') === 'subscription' + && Minz_Request::actionName() === 'index') { + $this->registerTranslates(); + $this->registerHook('js_vars', [$this, 'jsVars']); + Minz_View::appendScript($this->getFileUrl('showfeedid.js')); + } + } + + /** + * @param array $vars + * @return array + */ + public function jsVars(array $vars): array { + $vars['showfeedid_i18n'] = [ + 'show' => _t('ext.showfeedid.show'), + 'hide' => _t('ext.showfeedid.hide') + ]; + return $vars; } } diff --git a/xExtension-showFeedID/i18n/en/ext.php b/xExtension-showFeedID/i18n/en/ext.php new file mode 100644 index 0000000..923ddeb --- /dev/null +++ b/xExtension-showFeedID/i18n/en/ext.php @@ -0,0 +1,8 @@ + array( + 'show' => 'Show IDs', + 'hide' => 'Hide IDs', + ), +); diff --git a/xExtension-showFeedID/i18n/pl/ext.php b/xExtension-showFeedID/i18n/pl/ext.php new file mode 100644 index 0000000..8732f6c --- /dev/null +++ b/xExtension-showFeedID/i18n/pl/ext.php @@ -0,0 +1,9 @@ + array( + 'show' => 'Pokaż ID', + 'hide' => 'Ukryj ID', + ), +); + diff --git a/xExtension-showFeedID/metadata.json b/xExtension-showFeedID/metadata.json index 9b7e26b..fa341a2 100644 --- a/xExtension-showFeedID/metadata.json +++ b/xExtension-showFeedID/metadata.json @@ -1,8 +1,8 @@ { "name": "ShowFeedID", - "author": "math-GH", - "description": "Show the feed ID", - "version": "0.2", + "author": "math-GH, Inverle", + "description": "Show the ID of feed and category", + "version": "0.4.2", "entrypoint": "ShowFeedID", "type": "user" } diff --git a/xExtension-showFeedID/static/showfeedid.js b/xExtension-showFeedID/static/showfeedid.js index 6811f1e..2865202 100644 --- a/xExtension-showFeedID/static/showfeedid.js +++ b/xExtension-showFeedID/static/showfeedid.js @@ -1,26 +1,70 @@ 'use strict'; -const url = new URL(window.location); -if (url.searchParams.get('c') === 'subscription') { - const div = document.querySelector('h1 ~ div'); - const button = document.createElement('Button'); +window.addEventListener("load", function () { + // eslint-disable-next-line no-undef + const i18n = context.extensions.showfeedid_i18n; + + let div = document.querySelector('h1 ~ div'); + if (div.classList.contains('drop-section')) { + div = document.createElement('div'); + document.querySelector('h1').after(div); + } + + const button = document.createElement('a'); button.classList.add('btn'); + button.classList.add('btn-icon-text'); button.id = 'showFeedId'; - button.innerHTML = ' FeedID'; + button.innerHTML = ' ' + i18n.show + ''; + div.appendChild(button); - document.getElementById('showFeedId').addEventListener('click', function (e) { + const parent = button.parentElement; + parent.style.display = 'inline-flex'; + parent.style.flexWrap = 'wrap'; + parent.style.gap = '0.5rem'; + + // Check if only feeds with errors are being shown + if (document.querySelector('main.post > p.alert.alert-warn')) { + parent.style.flexDirection = 'column'; + button.style.marginTop = '0.5rem'; + } + + const buttonText = button.querySelector('span'); + + button.addEventListener('click', function () { + if (document.querySelector('.feed-id, .cat-id')) { + buttonText.innerText = i18n.show; + } else { + buttonText.innerText = i18n.hide; + } + const feeds = document.querySelectorAll('li.item.feed'); - let feedId; - let feedname_elem; feeds.forEach(function (feed) { - feedId = feed.dataset.feedId; - feedname_elem = feed.getElementsByClassName('item-title')[0]; + const feedId = feed.dataset.feedId; + const feedname_elem = feed.getElementsByClassName('item-title')[0]; if (feedname_elem) { - feedname_elem.innerHTML = feedname_elem.textContent + ' (ID: ' + feedId + ')'; + if (!feedname_elem.querySelector('.feed-id')) { + feedname_elem.insertAdjacentHTML('beforeend', ' (ID: ' + feedId + ')'); + return; + } + feedname_elem.querySelector('.feed-id').remove(); + } + }); + + const cats = document.querySelectorAll('div.box > ul.box-content'); + + cats.forEach(function (cat) { + const catId = cat.dataset.catId; + const catname_elem = cat.parentElement.querySelectorAll('div.box-title > h2')[0]; + if (catname_elem) { + if (!catname_elem.querySelector('.cat-id')) { + catname_elem.insertAdjacentHTML('beforeend', ' (ID: ' + catId + ')'); + return; + } + catname_elem.querySelector('.cat-id').remove(); } }); }); -} +});