diff --git a/.eslintignore b/.eslintignore deleted file mode 100644 index 24f4f1f599..0000000000 --- a/.eslintignore +++ /dev/null @@ -1,2 +0,0 @@ -modules/* -!modules/default/ \ No newline at end of file diff --git a/.eslintrc.json b/.eslintrc.json deleted file mode 100644 index dccd2ee2dc..0000000000 --- a/.eslintrc.json +++ /dev/null @@ -1,93 +0,0 @@ -{ - "extends": ["eslint:recommended", "plugin:@stylistic/all-extends", "plugin:import/recommended", "plugin:jest/recommended", "plugin:jsdoc/recommended"], - "plugins": ["unicorn"], - "env": { - "browser": true, - "es2024": true, - "jest/globals": true, - "node": true - }, - "globals": { - "config": true, - "Log": true, - "MM": true, - "Module": true, - "moment": true - }, - "parserOptions": { - "sourceType": "module", - "ecmaVersion": "latest", - "ecmaFeatures": { - "globalReturn": true - } - }, - "rules": { - "eqeqeq": "error", - "import/order": "error", - "import/extensions": "error", - "import/newline-after-import": "error", - "jest/consistent-test-it": "warn", - "jest/expect-expect": "warn", - "jest/no-done-callback": "warn", - "jest/prefer-expect-resolves": "warn", - "jest/prefer-mock-promise-shorthand": "warn", - "jest/prefer-to-be": "warn", - "jest/prefer-to-have-length": "warn", - "no-param-reassign": "error", - "no-prototype-builtins": "off", - "no-throw-literal": "error", - "no-unused-vars": "off", - "no-useless-return": "error", - "object-shorthand": ["error", "methods"], - "prefer-template": "error", - "@stylistic/array-element-newline": ["error", "consistent"], - "@stylistic/arrow-parens": ["error", "always"], - "@stylistic/brace-style": "off", - "@stylistic/comma-dangle": ["error", "never"], - "@stylistic/dot-location": ["error", "property"], - "@stylistic/function-call-argument-newline": ["error", "consistent"], - "@stylistic/function-paren-newline": ["error", "consistent"], - "@stylistic/implicit-arrow-linebreak": ["error", "beside"], - "@stylistic/max-statements-per-line": ["error", { "max": 2 }], - "@stylistic/multiline-ternary": ["error", "always-multiline"], - "@stylistic/newline-per-chained-call": ["error", { "ignoreChainWithDepth": 4 }], - "@stylistic/no-extra-parens": "off", - "@stylistic/no-tabs": "off", - "@stylistic/object-curly-spacing": ["error", "always"], - "@stylistic/object-property-newline": ["error", { "allowAllPropertiesOnSameLine": true }], - "@stylistic/operator-linebreak": ["error", "before"], - "@stylistic/padded-blocks": "off", - "@stylistic/quote-props": ["error", "as-needed"], - "@stylistic/quotes": ["error", "double"], - "@stylistic/indent": ["error", "tab"], - "@stylistic/semi": ["error", "always"], - "@stylistic/space-before-function-paren": ["error", "always"], - "@stylistic/spaced-comment": "off", - "unicorn/prefer-node-protocol": "error" - }, - "overrides": [ - { - "files": ["config/config.js*"], - "rules": { - "@stylistic/comma-dangle": "off", - "@stylistic/indent": "off", - "@stylistic/no-multi-spaces": "off" - } - }, - { - "files": ["tests/configs/modules/weather/*.js"], - "rules": { - "@stylistic/quotes": "off" - } - }, - { - "extends": ["plugin:package-json/recommended"], - "files": ["package.json"], - "parser": "jsonc-eslint-parser", - "plugins": ["package-json"], - "rules": { - "package-json/sort-collections": ["error", ["devDependencies", "dependencies", "peerDependencies", "config"]] - } - } - ] -} diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index 9fd4d4a921..360ea62189 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -12,7 +12,7 @@ We use prettier for automatic linting of all our files: `npm run lint:prettier`. We use [ESLint](https://eslint.org) on our JavaScript files. -Our ESLint configuration is in our `.eslintrc.json` and `.eslintignore` files. +The ESLint configuration is in our `eslint.config.mjs` file. To run ESLint, use `npm run lint:js`. diff --git a/.github/workflows/automated-tests.yaml b/.github/workflows/automated-tests.yaml index 9ac92f216a..e48acd9bcc 100644 --- a/.github/workflows/automated-tests.yaml +++ b/.github/workflows/automated-tests.yaml @@ -18,7 +18,7 @@ jobs: timeout-minutes: 30 strategy: matrix: - node-version: [20.x, 22.x] + node-version: [20.9.0, 20.x, 22.x] steps: - name: "Checkout code" uses: actions/checkout@v4 diff --git a/.github/workflows/depsreview.yaml b/.github/workflows/dep-review.yaml similarity index 90% rename from .github/workflows/depsreview.yaml rename to .github/workflows/dep-review.yaml index 141e821b9c..838f157ecb 100644 --- a/.github/workflows/depsreview.yaml +++ b/.github/workflows/dep-review.yaml @@ -16,3 +16,5 @@ jobs: uses: actions/checkout@v4 - name: "Dependency Review" uses: actions/dependency-review-action@v4 + with: + allow-ghsas: GHSA-8hc4-vh64-cxmj diff --git a/.github/workflows/electronRebuild.yaml b/.github/workflows/electron-rebuild.yaml similarity index 77% rename from .github/workflows/electronRebuild.yaml rename to .github/workflows/electron-rebuild.yaml index f9cc50957f..fa09f43d82 100644 --- a/.github/workflows/electronRebuild.yaml +++ b/.github/workflows/electron-rebuild.yaml @@ -8,7 +8,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - node-version: [20.x, 22.x] + node-version: [20.9.0, 20.x, 22.x] steps: - name: Checkout code uses: actions/checkout@v4 @@ -21,8 +21,10 @@ jobs: run: npm run install-mm - name: Install @electron/rebuild run: npm install @electron/rebuild + - name: Install node-libgpiod deps + run: sudo apt-get install gpiod libgpiod2 libgpiod-dev - name: Install some test library to be rebuilded - run: npm install onoff node-pty drivelist + run: npm install node-libgpiod node-pty drivelist - name: Run electron-rebuild run: npx electron-rebuild continue-on-error: false diff --git a/.github/workflows/enforce-pullrequest-rules.yaml b/.github/workflows/enforce-pullrequest-rules.yaml index 30c0d0ca08..77d3befb39 100644 --- a/.github/workflows/enforce-pullrequest-rules.yaml +++ b/.github/workflows/enforce-pullrequest-rules.yaml @@ -5,7 +5,7 @@ name: "Enforce Pull-Request Rules" on: - pull_request: + pull_request_target: types: [opened, synchronize, reopened, ready_for_review, labeled, unlabeled] jobs: @@ -25,4 +25,4 @@ jobs: echo "Please don't do this. Switch the branch to 'develop'." exit 1 env: - BASE_BRANCH: ${{ github.base_ref }} + BASE_BRANCH: ${{ github.event.pull_request.base.ref }} diff --git a/.gitignore b/.gitignore index 945c6c244b..7301472cce 100644 --- a/.gitignore +++ b/.gitignore @@ -81,3 +81,6 @@ Temporary Items *.orig *.rej *.bak + +# Ignore positions file (#3518) +js/positions.js diff --git a/.prettierignore b/.prettierignore index daa42fbebb..0315d69371 100644 --- a/.prettierignore +++ b/.prettierignore @@ -1,5 +1,5 @@ *.js -.eslintignore +*.mjs .husky/pre-commit .prettierignore /config diff --git a/CHANGELOG.md b/CHANGELOG.md index 9e882fd9ad..30de4cd9ba 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,11 +5,58 @@ This project adheres to [Semantic Versioning](https://semver.org/). ❤️ **Donate:** Enjoying MagicMirror²? [Please consider a donation!](https://magicmirror.builders/#donate) With your help we can continue to improve the MagicMirror². +## [2.29.0] - 2024-10-01 + +Thanks to: @bugsounet, @dkallen78, @jargordon, @khassel, @KristjanESPERANTO, @MarcLandis, @rejas, @ryan-d-williams, @sdetweil, @skpanagiotis. + +> ⚠️ This release needs nodejs version `v20` or `v22`, minimum version is `v20.9.0` + +### Added + +- [compliments] Added support for cron type date/time format entries mm hh DD MM dow (minutes/hours/days/months and day of week) see https://crontab.cronhub.io for construction (#3481) +- [core] Check config at every start of MagicMirror² (#3450) +- [core] Add spelling check (cspell): `npm run test:spelling` and handle spelling issues (#3544) +- [core] removed `config.paths.vendor` (could not work because `vendor` is hardcoded in `index.html`), renamed `config.paths.modules` to `config.foreignModulesDir`, added variable `MM_CUSTOMCSS_FILE` which - if set - overrides `config.customCss`, added variable `MM_MODULES_DIR` which - if set - overrides `config.foreignModulesDir`, added test for `MM_MODULES_DIR` (#3530) +- [core] elements are now removed from `index.html` when loading script or stylesheet files fails +- [core] Added `MODULE_DOM_UPDATED` notification each time the DOM is re-rendered via `updateDom` (#3534) +- [tests] added minimal needed node version to tests (currently v20.9.0) to avoid releases with wrong node version info +- [tests] Added `node-libgpiod` library to electron-rebuild tests (#3563) + +### Removed + +- [core] removed installer only files (#3492) +- [core] removed raspberry object from systeminformation (#3505) +- [linter] removed `eslint-plugin-import`, because it doesn't support ESLint v9. We will reenter it later when it does. +- [tests] removed `onoff` library from electron-rebuild tests (#3563) + +### Updated + +- [weather] Updated `apiVersion` default from 2.5 to 3.0 (#3424) +- [core] Updated dependencies including stylistic-eslint +- [core] nail down `node-ical` version to `0.18.0` with exception `allow-ghsas: GHSA-8hc4-vh64-cxmj` in `dep-review.yaml` (which should removed after next `node-ical` update) +- [core] Updated SocketIO catch all to new API +- [core] Allow custom modules positions by scanning index.html for the defined regions, instead of hard coded (PR #3518 fixes issue #3504) +- [core] Detail optimizations in `config_check.js` +- [core] Updated minimal needed node version in `package.json` (currently v20.9.0) (#3559) and except for v21 (no security updates) (#3561) +- [linter] Switch to ESLint v9 and flat config and replace `eslint-plugin-unicorn` by `@eslint/js` +- [core] fix discovering module positions twice after #3450 + +### Fixed + +- Fixed `checks` badge in README.md +- [weather] Fixed issue with the UK Met Office provider following a change in their API paths and header info. +- [core] add check for node_helper loading for multiple instances of same module (#3502) +- [weather] Fixed issue for respecting unit config on broadcasted notifications +- [tests] Fixes calendar test by moving it from e2e to electron with fixed date (#3532) +- [calendar] fixed sliceMultiDayEvents getting wrong count and displaying incorrect entries, Europe/Berlin (#3542) +- [tests] ignore `js/positions.js` when linting (this file is created at runtime) +- [calendar] fixed sliceMultiDayEvents showing previous day without config enabled + ## [2.28.0] - 2024-07-01 Thanks to: @btoconnor, @bugsounet, @JasonStieber, @khassel, @kleinmantara and @WallysWellies. -> ⚠️ This release needs nodejs version >= v20 +> ⚠️ This release needs nodejs version >= v20.9.0 ### Added @@ -31,7 +78,7 @@ Thanks to: @btoconnor, @bugsounet, @JasonStieber, @khassel, @kleinmantara and @W ### Fixed -- [core] Fixed crash possibility if `module: ` is not defined and on `postion: ` mistake (#3445) +- [core] Fixed crash possibility if `module: ` is not defined and on `position: ` mistake (#3445) - [weather] Fixed precipitationProbability in forecast for provider openmeteo (#3446) - [weather] Fixed type=daily for provider openmeteo having no data when running after 23:00 (#3449) - [weather] Fixed type=daily for provider openmeteo showing nightly icons in forecast when current time is "nightly" (#3458) @@ -70,7 +117,7 @@ For more info, please read the following post: [A New Chapter for MagicMirror: T ### Fixed -- Correct apibase of weathergov weatherprovider to match documentation (#2926) +- Correct apiBase of weathergov weatherProvider to match documentation (#2926) - Worked around several issues in the RRULE library that were causing deleted calender events to still show, some initial and recurring events to not show, and some event times to be off an hour. (#3291) - Skip changelog requirement when running tests for dependency updates (#3320) @@ -136,8 +183,8 @@ This release also marks the latest release by Michael Teeuw. For more info, plea - Fix issue template (#3167) - Fix #3256 filter out bad results from rrule.between - Fix calendar events sometimes not respecting deleted events (#3250) -- Fix electron loadurl locally on Windows when address "0.0.0.0" (#2550) -- Fix updatanotification (update_helper.js): catch error if response is not an JSON format (check PM2) +- Fix electron loadURL locally on Windows when address "0.0.0.0" (#2550) +- Fix updatenotification (update_helper.js): catch error if response is not an JSON format (check PM2) - Fix missing typeof in calendar module - Fix style issues after prettier update - Fix calendar test (#3291) by moving "Exdate check" from e2e to electron to run on a Thursday @@ -395,7 +442,7 @@ Special thanks to the following contributors: @eouia, @khassel, @kolbyjack, @Kri ### Added -- Added a new config option `httpHeaders` used by helmet (see https://helmetjs.github.io/). You can now set own httpHeaders which will override the defaults in `js/defauls.js` which is useful e.g. if you want to embed MagicMirror into annother website (solves #2847). +- Added a new config option `httpHeaders` used by helmet (see https://helmetjs.github.io/). You can now set own httpHeaders which will override the defaults in `js/defaults.js` which is useful e.g. if you want to embed MagicMirror into another website (solves #2847). - Show endDate for calendar events when dateHeader is enabled and showEnd is set to true (#2192). - Added the notification emitting from the weather module on information updated. - Use recommended file extension for YAML files (#2864). @@ -444,7 +491,7 @@ Special thanks to the following contributors: @10bias, @CFenner, @JHWelch, @k1rd - Fix minor console output issue for loading translations (#2814). - Don't adjust startDate for full day events if endDate is in the past. - Fix windspeed conversion error in openweathermap provider. (#2812) -- Fix conflicting parms turning off showEnd for full day events. (#2629) +- Fix conflicting parameter turning off showEnd for full day events. (#2629) - Fix regression, calendar.maximumEntries not used to filter calendar level entries (#2868) ## [2.18.0] - 2022-01-01 @@ -476,7 +523,7 @@ Special thanks to the following contributors: @AmpioRosso, @eouia, @fewieden, @j ### Fixed - Fixed wrong file `kr.json` to `ko.json`. Use language code 'ko' instead of 'kr' for Korean language. -- Fixed `feels_like` data from openweathermaps current weather being ignored (#2678). +- Fixed `feels_like` data from openweathermap's current weather being ignored (#2678). - Fixed chaotic newsfeed display after network connection loss thanks to @jalibu (#2638). - Fixed incorrect time zone correction of recurring full day events (#2632 and #2634). - Fixed e2e tests by increasing testTimeout. @@ -513,7 +560,7 @@ Special thanks to the following contributors: @apiontek, @eouia, @jupadin, @khas - Updated github templates. - Actually test all js and css files when lint script is run. - Updated jsdocs and print warnings during testing too. -- Updated weathergov provider to try fetching not just current, but also foreacst, when API URLs available. +- Updated weathergov provider to try fetching not just current, but also forecast, when API URLs available. - Refactored clock layout. - Refactored methods from weather-providers into weatherobject (isDaytime, updateSunTime). - Use of `logger.js` in jest tests. @@ -863,7 +910,7 @@ Special thanks to @sdetweil for all his great contributions! ### Updated - Updated lower bound of `lodash` and `helmet` dependencies for security patches. -- Updated compliments.js to handle newline in text, as textfields to not interpolate contents. +- Updated compliments.js to handle newline in text, as text fields to not interpolate contents. - Updated raspberry.sh installer script to handle new platform issues, split node/npm, pm2, and screen saver changes. - Improve handling for armv6l devices, where electron support has gone away, add optional serveronly config option. - Improved run-start.sh to handle for serveronly mode, by choice, or when electron not available. @@ -1084,7 +1131,7 @@ A huge, huge, huge thanks to user @fewieden for all his hard work on the new `we - Fixed close dates to be absolute, if no configured in the config.js - module Calendar - Fixed the updatenotification module message about new commits in the repository, so they can be correctly localized in singular and plural form. - Fix for weatherforecast rainfall rounding [#1374](https://github.com/MagicMirrorOrg/MagicMirror/issues/1374) -- Fix calendar parsing issue for Midori on RasperryPi Zero w, related to issue #694. +- Fix calendar parsing issue for Midori on Raspberry Pi Zero w, related to issue #694. - Fix weather city ID link in sample config - Fixed issue with clientonly not updating with IP address and port provided on command line. @@ -1139,7 +1186,7 @@ A huge, huge, huge thanks to user @fewieden for all his hard work on the new `we - Fixed weatherforecast to use dt_txt field instead of dt to handle timezones better - Newsfeed now remembers to show the description when `"ARTICLE_LESS_DETAILS"` is called if the user wants to always show the description. [#1282](https://github.com/MagicMirrorOrg/MagicMirror/issues/1282) - `clientonly/*.js` is now linted, and one linting error is fixed -- Fix issue #1196 by changing underscore to hyphen in locale id, in align with momentjs. +- Fix issue #1196 by changing underscore to hyphen in locale id, in align with moment.js. - Fixed issue where heat index and wind chill were reporting incorrect values in Kelvin. [#1263](https://github.com/MagicMirrorOrg/MagicMirror/issues/1263) ### Updated @@ -1164,7 +1211,7 @@ A huge, huge, huge thanks to user @fewieden for all his hard work on the new `we - Implement Danger.js to notify contributors when CHANGELOG.md is missing in PR. - Allow scrolling in full page article view of default newsfeed module with gesture events from [MMM-Gestures](https://github.com/thobach/MMM-Gestures) - Changed 'compliments.js' - Updated DOM if remote compliments are loaded instead of waiting one updateInterval to show custom compliments -- Automated unit tests utils, deprecated, translator, cloneObject(lockstrings) +- Automated unit tests utils, deprecated, translator, cloneObject(lockStrings) - Automated integration tests translations - Add advanced filtering to the excludedEvents configuration of the default calendar module - New currentweather module config option: `showFeelsLike`: Shows how it actually feels like. (wind chill or heat index) @@ -1268,7 +1315,7 @@ A huge, huge, huge thanks to user @fewieden for all his hard work on the new `we ### Fixed - Fixed issue with incorrect alignment of analog clock when displayed in the center column of the MM. -- Fixed ipWhitelist behaviour to make empty whitelist ([]) allow any and all hosts access to the MM. +- Fixed ipWhitelist behavior to make empty whitelist ([]) allow any and all hosts access to the MM. - Fixed issue with calendar module where 'excludedEvents' count towards 'maximumEntries'. - Fixed issue with calendar module where global configuration of maximumEntries was not overridden by calendar specific config (see module doc). - Fixed issue where `this.file(filename)` returns a path with two hashes. @@ -1373,7 +1420,7 @@ A huge, huge, huge thanks to user @fewieden for all his hard work on the new `we - Added multiple calendar icon support. - Added tests for Translations, dev argument, version, dev console. - Added test anytime feature compliments module. -- Added test ipwhitelist configuration directive. +- Added test ipWhitelist configuration directive. - Added test for calendar module: default, basic-auth, backward compatibility, fail-basic-auth. - Added meta tags to support fullscreen mode on iOS (for server mode) - Added `ignoreOldItems` and `ignoreOlderThan` options to the News Feed module diff --git a/Collaboration.md b/Collaboration.md index 6d2da4d6a3..a0c64bd9bc 100644 --- a/Collaboration.md +++ b/Collaboration.md @@ -15,24 +15,44 @@ This document describes how collaborators of this repository should work togethe ## Releases -Are done by @rejas or @khassel. +Are done by + +- [ ] @rejas +- [ ] @sdetweil +- [ ] @khassel + +### Pre-Deployment steps + +- [ ] update dependencies (a few days before) ### Deployment steps -- pull latest `develop` branch -- update `package.json` to reflect correct version number -- run `npm install` to generate new `package-lock.json` -- test `develop` branch -- update `CHANGELOG.md` (don't forget to add all contributor names) -- commit and push all changes -- after successful test run via github actions: create pull request to `master` branch -- after PR tests run without issues, merge PR -- create new release with corresponding version tag -- publish release notes with link to github release on forum in new locked topic +- [ ] pull latest `develop` branch +- [ ] update `package.json` and `package-lock.json` to reflect correct version number `2.xx.0` +- [ ] test `develop` branch +- [ ] update `CHANGELOG.md` + - [ ] add all contributor names: `...` + - [ ] add min. node version: > ⚠️ This release needs nodejs version `v20` or `v22`, minimum version is `v20.9.0` +- [ ] commit and push all changes +- [ ] after successful test run via github actions: create pull request from `develop` to `master` branch + - [ ] add label `mastermerge` + - [ ] title of the PR is `Release 2.xx.0` + - [ ] description of the PR is the section of the `CHANGELOG.md` +- [ ] after PR tests run without issues, merge PR +- [ ] create new release with + - [ ] corresponding version tag `v2.xx.0` + - [ ] a release name: `...` + - [ ] description of the PR is the section of the `CHANGELOG.md` ### Draft new development release -- checkout `develop` branch -- update `package.json` to reflect correct version number `2.xx.0-develop` -- draft new section in `CHANGELOG.md` -- commit and publish `develop` branch +- [ ] checkout `develop` branch +- [ ] update `package.json` and `package-lock.json` to reflect correct version number `2.xx.0-develop` +- [ ] draft new section in `CHANGELOG.md` +- [ ] commit and publish `develop` branch + +### After release + +- [ ] publish release notes with link to github release on forum in new locked topic +- [ ] close all issues with label `ready (coming with next release)` +- [ ] release new documentation by merging `develop` on `master` in documentation repository diff --git a/README.md b/README.md index 0221b79f40..751637ca8b 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ License GitHub Actions - Build Status + Build Status @@ -41,7 +41,7 @@ For the full contribution guidelines, check out: [https://docs.magicmirror.build ## Enjoying MagicMirror? Consider a donation! -MagicMirror² is opensource and free. That doesn't mean we don't need any money. +MagicMirror² is Open Source and free. That doesn't mean we don't need any money. Please consider a donation to help us cover the ongoing costs like webservers and email services. If we receive enough donations we might even be able to free up some working hours and spend some extra time improving the MagicMirror² core. diff --git a/cspell.config.json b/cspell.config.json new file mode 100644 index 0000000000..16addf44a9 --- /dev/null +++ b/cspell.config.json @@ -0,0 +1,227 @@ +{ + "version": "0.2", + "language": "en", + "words": [ + "aarch", + "Alvinger", + "Ampio", + "andrezibaia", + "angeldeejay", + "apiontek", + "armv", + "ashishtank", + "autoplay", + "beada", + "Binney", + "bluemanos", + "bnitkin", + "bokmål", + "Brasileiro", + "Brento", + "browserwindow", + "bryanzzhu", + "btoconnor", + "bugsounet", + "buxxi", + "byday", + "calendarfetcherutils", + "calendarutils", + "chamakura", + "cjbrunner", + "clientonly", + "clockfaces", + "cmdline", + "codac", + "Crazylegstoo", + "crazyscot", + "Creepin", + "currentweather", + "CUSTOMCSS", + "customregions", + "Cymraeg", + "dariom", + "darksky", + "dateheader", + "dateheaders", + "davide", + "DAYAFTERTOMORROW", + "DAYBEFOREYESTERDAY", + "defaultmodules", + "dgoth", + "DTEND", + "Duffman", + "earlman", + "easyas", + "eddiehung", + "Edgardos", + "Ekristoffe", + "envcanada", + "envsub", + "envsubst", + "eouia", + "exdate", + "expectedheaders", + "ezeholz", + "Faizan", + "feedme", + "feelslike", + "Fenner", + "fewieden", + "fixuppm", + "flopp", + "fontawesome", + "fontface", + "forecastweather", + "fortawesome", + "frameguard", + "Frysk", + "fulldate", + "fullday", + "fullscreen", + "Gevoelstemperatuur", + "ghsas", + "grenagit", + "Hirschberger", + "hourlyweather", + "Hwind", + "ical", + "illimarkangur", + "Ingan", + "ipfilter", + "ismarslomic", + "jakemulley", + "jakobsarwary", + "jalibu", + "jetson", + "jkriegshauser", + "jsdocs", + "jsonlint", + "jupadin", + "kaennchenstruggle", + "kenzal", + "Keyport", + "khassel", + "Kingdon", + "kioskmode", + "klaernie", + "kleinmantara", + "Kmph", + "Knapoc", + "Koepke", + "kolbyjack", + "krekos", + "Kristjan", + "krukle", + "larryare", + "letsencrypt", + "Lightspeed", + "locationforecast", + "lockstring", + "lstrip", + "Luciella", + "luxon", + "lxsession", + "magicmirror", + "martingron", + "marvai", + "mastermerge", + "Meteo", + "michaelteeuw", + "michmich", + "Midori", + "mirontoli", + "MISSINGLANG", + "MMPM", + "modernizr", + "modulename", + "multiday", + "Mystara", + "Ñandú", + "nathannaveen", + "naveensrinivasan", + "ndom", + "Nerfzooka", + "NEWSFEED", + "newsitems", + "nfogal", + "njwilliams", + "Norsk", + "nunjuck", + "odroid", + "oemel", + "onecall", + "onevent", + "openmeteo", + "openweathermap", + "oraclesean", + "oscarb", + "philnagel", + "Português", + "PRECIP", + "Problema", + "psieg", + "radokristof", + "rajniszp", + "Reis", + "rejas", + "Resig", + "roboto", + "rohitdharavath", + "Rosso", + "rrule", + "sdetweil", + "sendheaders", + "serveronly", + "SMHI", + "Snille", + "socketclient", + "socketio", + "spectron", + "Starinvest", + "sthuber", + "Stieber", + "stylelintrc", + "subclassing", + "sunaction", + "suncalc", + "suntimes", + "systeminformation", + "tada", + "taglist", + "Teeuw", + "thomasrockhu", + "tomzt", + "ukmetoffice", + "ukmetofficedatahub", + "unitless", + "unparseable", + "updatenotification", + "Vaice", + "veeck", + "VEVENT", + "vgtu", + "Voelt", + "vppencilsharpener", + "Wallys", + "Weatherbit", + "WEATHERDATA", + "Weatherflow", + "weatherforecast", + "weathergov", + "weathericons", + "weatherobject", + "weatherutils", + "windspeed", + "Woolridge", + "worktree", + "xlarge", + "xrandr", + "xsmall", + "xwindows", + "xxxe", + "Ybbet", + "yearmatchgroup" + ], + "ignorePaths": ["node_modules/**", "modules/**", "vendor/node_modules/**", "translations/**", "tests/mocks/**", "tests/e2e/modules/clock_es_spec.js", "fonts/roboto.css"], + "dictionaries": ["node"] +} diff --git a/eslint.config.mjs b/eslint.config.mjs new file mode 100644 index 0000000000..3338c1d786 --- /dev/null +++ b/eslint.config.mjs @@ -0,0 +1,121 @@ +import eslintPluginJest from "eslint-plugin-jest"; +import eslintPluginJs from "@eslint/js"; +import eslintPluginStylistic from "@stylistic/eslint-plugin"; +import globals from "globals"; + +const config = [ + eslintPluginJs.configs.recommended, + { + files: ["**/*.js"], + languageOptions: { + ecmaVersion: "latest", + globals: { + ...globals.browser, + ...globals.node, + ...globals.jest, + Log: "readonly", + MM: "readonly", + Module: "readonly", + config: "readonly", + moment: "readonly" + } + }, + plugins: { + ...eslintPluginStylistic.configs["all-flat"].plugins, + ...eslintPluginJest.configs["flat/recommended"].plugins + }, + rules: { + ...eslintPluginStylistic.configs["all-flat"].rules, + ...eslintPluginJest.configs["flat/recommended"].rules, + "@stylistic/array-element-newline": ["error", "consistent"], + "@stylistic/arrow-parens": ["error", "always"], + "@stylistic/brace-style": "off", + "@stylistic/comma-dangle": ["error", "never"], + "@stylistic/dot-location": ["error", "property"], + "@stylistic/function-call-argument-newline": ["error", "consistent"], + "@stylistic/function-paren-newline": ["error", "consistent"], + "@stylistic/implicit-arrow-linebreak": ["error", "beside"], + "@stylistic/indent": ["error", "tab"], + "@stylistic/max-statements-per-line": ["error", {max: 2}], + "@stylistic/multiline-comment-style": "off", + "@stylistic/multiline-ternary": ["error", "always-multiline"], + "@stylistic/newline-per-chained-call": ["error", {ignoreChainWithDepth: 4}], + "@stylistic/no-extra-parens": "off", + "@stylistic/no-tabs": "off", + "@stylistic/object-curly-spacing": ["error", "always"], + "@stylistic/object-property-newline": ["error", {allowAllPropertiesOnSameLine: true}], + "@stylistic/operator-linebreak": ["error", "before"], + "@stylistic/padded-blocks": "off", + "@stylistic/quote-props": ["error", "as-needed"], + "@stylistic/quotes": ["error", "double"], + "@stylistic/semi": ["error", "always"], + "@stylistic/space-before-function-paren": ["error", "always"], + "@stylistic/spaced-comment": "off", + eqeqeq: "error", + "id-length": "off", + "init-declarations": "off", + "jest/consistent-test-it": "warn", + "jest/no-done-callback": "warn", + "jest/prefer-expect-resolves": "warn", + "jest/prefer-mock-promise-shorthand": "warn", + "jest/prefer-to-be": "warn", + "jest/prefer-to-have-length": "warn", + "max-lines-per-function": ["warn", 350], + "max-statements": "off", + "no-global-assign": "off", + "no-inline-comments": "off", + "no-magic-numbers": "off", + "no-param-reassign": "error", + "no-plusplus": "off", + "no-prototype-builtins": "off", + "no-ternary": "off", + "no-throw-literal": "error", + "no-undefined": "off", + "no-unused-vars": "off", + "no-useless-return": "error", + "no-warning-comments": "off", + "object-shorthand": ["error", "methods"], + "one-var": "off", + "prefer-destructuring": "off", + "prefer-template": "error", + "sort-keys": "off" + } + }, + { + files: ["**/*.mjs"], + languageOptions: { + ecmaVersion: "latest", + globals: { + ...globals.node + }, + sourceType: "module" + }, + plugins: { + ...eslintPluginStylistic.configs["all-flat"].plugins + }, + rules: { + ...eslintPluginStylistic.configs["all-flat"].rules, + "@stylistic/array-element-newline": "off", + "@stylistic/indent": ["error", "tab"], + "@stylistic/padded-blocks": ["error", "never"], + "@stylistic/quote-props": ["error", "as-needed"], + "func-style": "off", + "import/namespace": "off", + "max-lines-per-function": ["error", 100], + "no-magic-numbers": "off", + "one-var": "off", + "prefer-destructuring": "off" + } + }, + { + files: ["tests/configs/modules/weather/*.js"], + rules: { + "@stylistic/quotes": "off" + } + }, + { + ignores: ["config/**", "modules/**", "!modules/default/**", "js/positions.js"] + } +]; + +export default config; diff --git a/fonts/package-lock.json b/fonts/package-lock.json index 287cd90e62..3acdd8c0a7 100644 --- a/fonts/package-lock.json +++ b/fonts/package-lock.json @@ -9,19 +9,21 @@ "version": "1.0.0", "license": "MIT", "dependencies": { - "@fontsource/roboto": "^5.0.13", - "@fontsource/roboto-condensed": "^5.0.16" + "@fontsource/roboto": "^5.1.0", + "@fontsource/roboto-condensed": "^5.1.0" } }, "node_modules/@fontsource/roboto": { - "version": "5.0.13", - "resolved": "https://registry.npmjs.org/@fontsource/roboto/-/roboto-5.0.13.tgz", - "integrity": "sha512-j61DHjsdUCKMXSdNLTOxcG701FWnF0jcqNNQi2iPCDxU8seN/sMxeh62dC++UiagCWq9ghTypX+Pcy7kX+QOeQ==" + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@fontsource/roboto/-/roboto-5.1.0.tgz", + "integrity": "sha512-cFRRC1s6RqPygeZ8Uw/acwVHqih8Czjt6Q0MwoUoDe9U3m4dH1HmNDRBZyqlMSFwgNAUKgFImncKdmDHyKpwdg==", + "license": "Apache-2.0" }, "node_modules/@fontsource/roboto-condensed": { - "version": "5.0.16", - "resolved": "https://registry.npmjs.org/@fontsource/roboto-condensed/-/roboto-condensed-5.0.16.tgz", - "integrity": "sha512-pjO80g5x/hkqzWCIafvkS3JrkBDxSiTjEy4LdqQKJYrmoGx8x2AlhSUMgzIzG/ge4kT98bA7+gmm7yquzrrZ/w==" + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@fontsource/roboto-condensed/-/roboto-condensed-5.1.0.tgz", + "integrity": "sha512-cTS62X9bgR6H+3qRtaDwt0I+3ocitMPalyr2OrzJtilIcuEo4my8UA4VVhOgr0OI2Sk9JNrNYcSxkv0k4XuKtQ==", + "license": "OFL-1.1" } } } diff --git a/fonts/package.json b/fonts/package.json index 09d7c153e6..0b6576f2f6 100644 --- a/fonts/package.json +++ b/fonts/package.json @@ -11,7 +11,7 @@ }, "license": "MIT", "dependencies": { - "@fontsource/roboto": "^5.0.13", - "@fontsource/roboto-condensed": "^5.0.16" + "@fontsource/roboto": "^5.1.0", + "@fontsource/roboto-condensed": "^5.1.0" } } diff --git a/index.html b/index.html index b97124be10..09addfe37f 100644 --- a/index.html +++ b/index.html @@ -55,6 +55,7 @@ + diff --git a/installers/mm.sh b/installers/mm.sh deleted file mode 100755 index d56ffca359..0000000000 --- a/installers/mm.sh +++ /dev/null @@ -1,4 +0,0 @@ -#!/bin/bash -# This file is still here to keep PM2 working on older installations. -cd ~/MagicMirror -DISPLAY=:0 npm start diff --git a/js/app.js b/js/app.js index f9313ed403..8ae002e9f0 100644 --- a/js/app.js +++ b/js/app.js @@ -9,6 +9,7 @@ const Log = require("logger"); const Server = require(`${__dirname}/server`); const Utils = require(`${__dirname}/utils`); const defaultModules = require(`${__dirname}/../modules/default/defaultmodules`); +const { getEnvVarsAsObj } = require(`${__dirname}/server_functions`); // Get version number. global.version = require(`${__dirname}/../package.json`).version; @@ -116,6 +117,8 @@ function App () { } } + require(`${global.root_path}/js/check_config.js`); + try { fs.accessSync(configFilename, fs.F_OK); const c = require(configFilename); @@ -159,10 +162,19 @@ function App () { function loadModule (module) { const elements = module.split("/"); const moduleName = elements[elements.length - 1]; - let moduleFolder = `${__dirname}/../modules/${module}`; + const env = getEnvVarsAsObj(); + let moduleFolder = `${__dirname}/../${env.modulesDir}/${module}`; if (defaultModules.includes(moduleName)) { - moduleFolder = `${__dirname}/../modules/default/${module}`; + const defaultModuleFolder = `${__dirname}/../modules/default/${module}`; + if (process.env.JEST_WORKER_ID === undefined) { + moduleFolder = defaultModuleFolder; + } else { + // running in Jest, allow defaultModules placed under moduleDir for testing + if (env.modulesDir === "modules") { + moduleFolder = defaultModuleFolder; + } + } } const moduleFile = `${moduleFolder}/${module}.js`; @@ -183,6 +195,7 @@ function App () { Log.log(`No helper found for module: ${moduleName}.`); } + // if the helper was found if (loadHelper) { const Module = require(helperPath); let m = new Module(); @@ -255,17 +268,23 @@ function App () { Log.setLogLevel(config.logLevel); + // get the used module positions + Utils.getModulePositions(); + let modules = []; for (const module of config.modules) { if (module.disabled) continue; if (module.module) { if (Utils.moduleHasValidPosition(module.position) || typeof (module.position) === "undefined") { - modules.push(module.module); + // Only add this module to be loaded if it is not a duplicate (repeated instance of the same module) + if (!modules.includes(module.module)) { + modules.push(module.module); + } } else { - Log.warn("Invalid module position found for this configuration:", module); + Log.warn("Invalid module position found for this configuration:" + `\n${JSON.stringify(module, null, 2)}`); } } else { - Log.warn("No module name found for this configuration:", module); + Log.warn("No module name found for this configuration:" + `\n${JSON.stringify(module, null, 2)}`); } } diff --git a/js/check_config.js b/js/check_config.js index 6a514de3eb..d159d9f45a 100644 --- a/js/check_config.js +++ b/js/check_config.js @@ -1,16 +1,16 @@ const path = require("node:path"); const fs = require("node:fs"); +const Ajv = require("ajv"); const colors = require("ansis"); +const globals = require("globals"); const { Linter } = require("eslint"); -const linter = new Linter(); - -const Ajv = require("ajv"); - -const ajv = new Ajv(); - const rootPath = path.resolve(`${__dirname}/../`); const Log = require(`${rootPath}/js/logger.js`); +const Utils = require(`${rootPath}/js/utils.js`); + +const linter = new Linter({ configType: "flat" }); +const ajv = new Ajv(); /** * Returns a string with path of configuration file. @@ -30,46 +30,55 @@ function checkConfigFile () { // Check if file is present if (fs.existsSync(configFileName) === false) { - Log.error(`File not found: ${configFileName}`); - throw new Error("No config file present!"); + throw new Error(`File not found: ${configFileName}\nNo config file present!`); } // Check permission try { fs.accessSync(configFileName, fs.F_OK); - } catch (e) { - Log.error(e); - throw new Error("No permission to access config file!"); + } catch (error) { + throw new Error(`${error}\nNo permission to access config file!`); } // Validate syntax of the configuration file. - Log.info("Checking file... ", configFileName); + Log.info(`Checking config file ${configFileName} ...`); // I'm not sure if all ever is utf-8 const configFile = fs.readFileSync(configFileName, "utf-8"); - // Explicitly tell linter that he might encounter es6 syntax ("let config = {...}") - const errors = linter.verify(configFile, { - env: { - es6: true - } - }); + const errors = linter.verify( + configFile, + { + languageOptions: { + ecmaVersion: "latest", + globals: { + ...globals.node + } + } + }, + configFileName + ); if (errors.length === 0) { Log.info(colors.green("Your configuration file doesn't contain syntax errors :)")); + validateModulePositions(configFileName); } else { - Log.error(colors.red("Your configuration file contains syntax errors :(")); + let errorMessage = "Your configuration file contains syntax errors :("; for (const error of errors) { - Log.error(`Line ${error.line} column ${error.column}: ${error.message}`); + errorMessage += `\nLine ${error.line} column ${error.column}: ${error.message}`; } - return; + throw new Error(errorMessage); } +} + +function validateModulePositions (configFileName) { + Log.info("Checking modules structure configuration ..."); - Log.info("Checking modules structure configuration... "); + const positionList = Utils.getModulePositions(); - // Make Ajv schema confguration of modules config - // only scan "module" and "position" + // Make Ajv schema configuration of modules config + // Only scan "module" and "position" const schema = { type: "object", properties: { @@ -83,21 +92,7 @@ function checkConfigFile () { }, position: { type: "string", - enum: [ - "top_bar", - "top_left", - "top_center", - "top_right", - "upper_third", - "middle_center", - "lower_third", - "bottom_left", - "bottom_center", - "bottom_right", - "bottom_bar", - "fullscreen_above", - "fullscreen_below" - ] + enum: positionList } }, required: ["module"] @@ -106,26 +101,31 @@ function checkConfigFile () { } }; - // scan all modules + // Scan all modules const validate = ajv.compile(schema); const data = require(configFileName); const valid = validate(data); - if (!valid) { - let module = validate.errors[0].instancePath.split("/")[2]; - let position = validate.errors[0].instancePath.split("/")[3]; - - Log.error(colors.red("This module configuration contains errors:")); - Log.error(data.modules[module]); + if (valid) { + Log.info(colors.green("Your modules structure configuration doesn't contain errors :)")); + } else { + const module = validate.errors[0].instancePath.split("/")[2]; + const position = validate.errors[0].instancePath.split("/")[3]; + let errorMessage = "This module configuration contains errors:"; + errorMessage += `\n${JSON.stringify(data.modules[module], null, 2)}`; if (position) { - Log.error(colors.red(`${position}: ${validate.errors[0].message}`)); - Log.error(validate.errors[0].params.allowedValues); + errorMessage += `\n${position}: ${validate.errors[0].message}`; + errorMessage += `\n${JSON.stringify(validate.errors[0].params.allowedValues, null, 2).slice(1, -1)}`; } else { - Log.error(colors.red(validate.errors[0].message)); + errorMessage += validate.errors[0].message; } - } else { - Log.info(colors.green("Your modules structure configuration doesn't contain errors :)")); + Log.error(errorMessage); } } -checkConfigFile(); +try { + checkConfigFile(); +} catch (error) { + Log.error(error.message); + process.exit(1); +} diff --git a/js/class.js b/js/class.js index c3a0ab22eb..9cfeee4ceb 100644 --- a/js/class.js +++ b/js/class.js @@ -1,6 +1,7 @@ /* global Class, xyz */ -/* Simple JavaScript Inheritance +/* + * Simple JavaScript Inheritance * By John Resig https://johnresig.com/ * * Inspired by base2 and Prototype @@ -22,8 +23,10 @@ Class.extend = function (prop) { let _super = this.prototype; - // Instantiate a base class (but only create the instance, - // don't run the init constructor) + /* + * Instantiate a base class (but only create the instance, + * don't run the init constructor) + */ initializing = true; const prototype = new this(); initializing = false; @@ -42,12 +45,16 @@ return function () { const tmp = this._super; - // Add a new ._super() method that is the same method - // but on the super-class + /* + * Add a new ._super() method that is the same method + * but on the super-class + */ this._super = _super[name]; - // The method only need to be bound temporarily, so we - // remove it when we're done executing + /* + * The method only need to be bound temporarily, so we + * remove it when we're done executing + */ const ret = fn.apply(this, arguments); this._super = tmp; diff --git a/js/defaults.js b/js/defaults.js index c4efa77e95..f3a894d6a9 100644 --- a/js/defaults.js +++ b/js/defaults.js @@ -19,6 +19,7 @@ const defaults = { units: "metric", zoom: 1, customCss: "css/custom.css", + foreignModulesDir: "modules", // httpHeaders used by helmet, see https://helmetjs.github.io/. You can add other/more object values by overriding this in config.js, // e.g. you need to add `frameguard: false` for embedding MagicMirror in another website, see https://github.com/MagicMirrorOrg/MagicMirror/issues/2847 httpHeaders: { contentSecurityPolicy: false, crossOriginOpenerPolicy: false, crossOriginEmbedderPolicy: false, crossOriginResourcePolicy: false, originAgentCluster: false }, @@ -72,12 +73,7 @@ const defaults = { text: "www.michaelteeuw.nl" } } - ], - - paths: { - modules: "modules", - vendor: "vendor" - } + ] }; /*************** DO NOT EDIT THE LINE BELOW ***************/ diff --git a/js/electron.js b/js/electron.js index 2dfde6728a..4bfe35427f 100644 --- a/js/electron.js +++ b/js/electron.js @@ -8,9 +8,12 @@ const Log = require("./logger"); let config = process.env.config ? JSON.parse(process.env.config) : {}; // Module to control application life. const app = electron.app; -// Per default electron is started with --disable-gpu flag, if you want the gpu enabled, -// you must set the env var ELECTRON_ENABLE_GPU=1 on startup. -// See https://www.electronjs.org/docs/latest/tutorial/offscreen-rendering for more info. + +/* + * Per default electron is started with --disable-gpu flag, if you want the gpu enabled, + * you must set the env var ELECTRON_ENABLE_GPU=1 on startup. + * See https://www.electronjs.org/docs/latest/tutorial/offscreen-rendering for more info. + */ if (process.env.ELECTRON_ENABLE_GPU !== "1") { app.disableHardwareAcceleration(); } @@ -18,16 +21,21 @@ if (process.env.ELECTRON_ENABLE_GPU !== "1") { // Module to create native browser window. const BrowserWindow = electron.BrowserWindow; -// Keep a global reference of the window object, if you don't, the window will -// be closed automatically when the JavaScript object is garbage collected. +/* + * Keep a global reference of the window object, if you don't, the window will + * be closed automatically when the JavaScript object is garbage collected. + */ let mainWindow; /** * */ function createWindow () { - // see https://www.electronjs.org/docs/latest/api/screen - // Create a window that fills the screen's available work area. + + /* + * see https://www.electronjs.org/docs/latest/api/screen + * Create a window that fills the screen's available work area. + */ let electronSize = (800, 600); try { electronSize = electron.screen.getPrimaryDisplay().workAreaSize; @@ -52,8 +60,10 @@ function createWindow () { backgroundColor: "#000000" }; - // DEPRECATED: "kioskmode" backwards compatibility, to be removed - // settings these options directly instead provides cleaner interface + /* + * DEPRECATED: "kioskmode" backwards compatibility, to be removed + * settings these options directly instead provides cleaner interface + */ if (config.kioskmode) { electronOptionsDefaults.kiosk = true; } else { @@ -69,8 +79,10 @@ function createWindow () { // Create the browser window. mainWindow = new BrowserWindow(electronOptions); - // and load the index.html of the app. - // If config.address is not defined or is an empty string (listening on all interfaces), connect to localhost + /* + * and load the index.html of the app. + * If config.address is not defined or is an empty string (listening on all interfaces), connect to localhost + */ let prefix; if ((config["tls"] !== null && config["tls"]) || config.useHttps) { @@ -149,14 +161,18 @@ app.on("window-all-closed", function () { }); app.on("activate", function () { - // On OS X it's common to re-create a window in the app when the - // dock icon is clicked and there are no other windows open. + + /* + * On OS X it's common to re-create a window in the app when the + * dock icon is clicked and there are no other windows open. + */ if (mainWindow === null) { createWindow(); } }); -/* This method will be called when SIGINT is received and will call +/* + * This method will be called when SIGINT is received and will call * each node_helper's stop function if it exists. Added to fix #1056 * * Note: this is only used if running Electron. Otherwise @@ -187,8 +203,10 @@ if (process.env.clientonly) { }); } -// Start the core application if server is run on localhost -// This starts all node helpers and starts the webserver. +/* + * Start the core application if server is run on localhost + * This starts all node helpers and starts the webserver. + */ if (["localhost", "127.0.0.1", "::1", "::ffff:127.0.0.1", undefined].includes(config.address)) { core.start().then((c) => { config = c; diff --git a/js/loader.js b/js/loader.js index e8dff1907c..9b42dd8493 100644 --- a/js/loader.js +++ b/js/loader.js @@ -10,6 +10,15 @@ const Loader = (function () { /* Private Methods */ + /** + * Retrieve object of env variables. + * @returns {object} with key: values as assembled in js/server_functions.js + */ + const getEnvVars = async function () { + const res = await fetch(`${location.protocol}//${location.host}/env`); + return JSON.parse(await res.text()); + }; + /** * Loops through all modules and requests start for every module. */ @@ -58,19 +67,28 @@ const Loader = (function () { * Generate array with module information including module paths. * @returns {object[]} Module information. */ - const getModuleData = function () { + const getModuleData = async function () { const modules = getAllModules(); const moduleFiles = []; + const envVars = await getEnvVars(); modules.forEach(function (moduleData, index) { const module = moduleData.module; const elements = module.split("/"); const moduleName = elements[elements.length - 1]; - let moduleFolder = `${config.paths.modules}/${module}`; + let moduleFolder = `${envVars.modulesDir}/${module}`; if (defaultModules.indexOf(moduleName) !== -1) { - moduleFolder = `${config.paths.modules}/default/${module}`; + const defaultModuleFolder = `modules/default/${module}`; + if (window.name !== "jsdom") { + moduleFolder = defaultModuleFolder; + } else { + // running in Jest, allow defaultModules placed under moduleDir for testing + if (envVars.modulesDir === "modules") { + moduleFolder = defaultModuleFolder; + } + } } if (moduleData.disabled === true) { @@ -166,6 +184,7 @@ const Loader = (function () { }; script.onerror = function () { Log.error("Error on loading script:", fileName); + script.remove(); resolve(); }; document.getElementsByTagName("body")[0].appendChild(script); @@ -183,6 +202,7 @@ const Loader = (function () { }; stylesheet.onerror = function () { Log.error("Error on loading stylesheet:", fileName); + stylesheet.remove(); resolve(); }; document.getElementsByTagName("head")[0].appendChild(stylesheet); @@ -197,7 +217,9 @@ const Loader = (function () { * Load all modules as defined in the config. */ async loadModules () { - let moduleData = getModuleData(); + let moduleData = await getModuleData(); + const envVars = await getEnvVars(); + const customCss = envVars.customCss; /** * @returns {Promise} when all modules are loaded @@ -212,7 +234,7 @@ const Loader = (function () { // All modules loaded. Load custom.css // This is done after all the modules so we can // overwrite all the defined styles. - await loadFile(config.customCss); + await loadFile(customCss); // custom.css loaded. Start all modules. await startModules(); } @@ -244,7 +266,7 @@ const Loader = (function () { // This file is available in the vendor folder. // Load it from this vendor folder. loadedFiles.push(fileName.toLowerCase()); - return loadFile(`${config.paths.vendor}/${vendor[fileName]}`); + return loadFile(`vendor/${vendor[fileName]}`); } // File not loaded yet. diff --git a/js/main.js b/js/main.js index bc69f0bb93..16aaa1b1b4 100644 --- a/js/main.js +++ b/js/main.js @@ -1,4 +1,4 @@ -/* global Loader, defaults, Translator, addAnimateCSS, removeAnimateCSS, AnimateCSSIn, AnimateCSSOut */ +/* global Loader, defaults, Translator, addAnimateCSS, removeAnimateCSS, AnimateCSSIn, AnimateCSSOut, modulePositions */ const MM = (function () { let modules = []; @@ -286,9 +286,9 @@ const MM = (function () { Log.debug(`${module.identifier} Force remove animateIn (in hide): ${module.hasAnimateIn}`); module.hasAnimateIn = false; } - // haveAnimateName for verify if we are using AninateCSS library + // haveAnimateName for verify if we are using AnimateCSS library // we check AnimateCSSOut Array for validate it - // and finaly return the animate name or `null` (for default MM² animation) + // and finally return the animate name or `null` (for default MM² animation) let haveAnimateName = null; // check if have valid animateOut in module definition (module.data.animateOut) if (module.data.animateOut && AnimateCSSOut.indexOf(module.data.animateOut) !== -1) haveAnimateName = module.data.animateOut; @@ -357,7 +357,7 @@ const MM = (function () { } } - // Check if there are no more lockstrings set, or the force option is set. + // Check if there are no more lockStrings set, or the force option is set. // Otherwise cancel show action. if (module.lockStrings.length !== 0 && options.force !== true) { Log.log(`Will not show ${module.name}. LockStrings active: ${module.lockStrings.join(",")}`); @@ -380,7 +380,7 @@ const MM = (function () { module.hidden = false; - // If forced show, clean current lockstrings. + // If forced show, clean current lockStrings. if (module.lockStrings.length !== 0 && options.force === true) { Log.log(`Force show of module: ${module.name}`); module.lockStrings = []; @@ -390,9 +390,9 @@ const MM = (function () { if (moduleWrapper !== null) { clearTimeout(module.showHideTimer); - // haveAnimateName for verify if we are using AninateCSS library + // haveAnimateName for verify if we are using AnimateCSS library // we check AnimateCSSIn Array for validate it - // and finaly return the animate name or `null` (for default MM² animation) + // and finally return the animate name or `null` (for default MM² animation) let haveAnimateName = null; // check if have valid animateOut in module definition (module.data.animateIn) if (module.data.animateIn && AnimateCSSIn.indexOf(module.data.animateIn) !== -1) haveAnimateName = module.data.animateIn; @@ -450,7 +450,6 @@ const MM = (function () { * an ugly top margin. By using this function, the top bar will be hidden if the * update notification is not visible. */ - const modulePositions = ["top_bar", "top_left", "top_center", "top_right", "upper_third", "middle_center", "lower_third", "bottom_left", "bottom_center", "bottom_right", "bottom_bar", "fullscreen_above", "fullscreen_below"]; const updateWrapperStates = function () { modulePositions.forEach(function (position) { @@ -667,7 +666,10 @@ const MM = (function () { } // Further implementation is done in the private method. - updateDom(module, updateOptions); + updateDom(module, updateOptions).then(function () { + // Once the update is complete and rendered, send a notification to the module that the DOM has been updated + sendNotification("MODULE_DOM_UPDATED", null, null, module); + }); }, /** @@ -703,7 +705,7 @@ const MM = (function () { showModule(module, speed, callback, options); }, - // return all available module postions. + // Return all available module positions. getAvailableModulePositions: modulePositions }; }()); diff --git a/js/module.js b/js/module.js index 71451763d0..3fc2cf3035 100644 --- a/js/module.js +++ b/js/module.js @@ -1,13 +1,16 @@ /* global Class, cloneObject, Loader, MMSocket, nunjucks, Translator */ -/* Module Blueprint. +/* + * Module Blueprint. * @typedef {Object} Module */ const Module = Class.extend({ - /********************************************************* + /** + ******************************************************** * All methods (and properties) below can be subclassed. * - *********************************************************/ + ******************************************************** + */ // Set the minimum MagicMirror² module version for this module. requiresVersion: "2.0.0", @@ -18,13 +21,17 @@ const Module = Class.extend({ // Timer reference used for showHide animation callbacks. showHideTimer: null, - // Array to store lockStrings. These strings are used to lock - // visibility when hiding and showing module. + /* + * Array to store lockStrings. These strings are used to lock + * visibility when hiding and showing module. + */ lockStrings: [], - // Storage of the nunjucks Environment, - // This should not be referenced directly. - // Use the nunjucksEnvironment() to get it. + /* + * Storage of the nunjucks Environment, + * This should not be referenced directly. + * Use the nunjucksEnvironment() to get it. + */ _nunjucksEnvironment: null, /** @@ -189,9 +196,11 @@ const Module = Class.extend({ Log.log(`${this.name} is resumed.`); }, - /********************************************* + /** + ******************************************** * The methods below don't need subclassing. * - *********************************************/ + ******************************************** + */ /** * Set the module data. diff --git a/js/node_helper.js b/js/node_helper.js index 42da0efcff..e1ecf632b5 100644 --- a/js/node_helper.js +++ b/js/node_helper.js @@ -49,7 +49,8 @@ const NodeHelper = Class.extend({ this.path = path; }, - /* sendSocketNotification(notification, payload) + /* + * sendSocketNotification(notification, payload) * Send a socket notification to the node helper. * * argument notification string - The identifier of the notification. @@ -59,7 +60,8 @@ const NodeHelper = Class.extend({ this.io.of(this.name).emit(notification, payload); }, - /* setExpressApp(app) + /* + * setExpressApp(app) * Sets the express app object for this module. * This allows you to host files from the created webserver. * @@ -71,7 +73,8 @@ const NodeHelper = Class.extend({ app.use(`/${this.name}`, express.static(`${this.path}/public`)); }, - /* setSocketIO(io) + /* + * setSocketIO(io) * Sets the socket io object for this module. * Binds message receiver. * @@ -83,20 +86,9 @@ const NodeHelper = Class.extend({ Log.log(`Connecting socket for: ${this.name}`); io.of(this.name).on("connection", (socket) => { - // add a catch all event. - const onevent = socket.onevent; - socket.onevent = function (packet) { - const args = packet.data || []; - onevent.call(this, packet); // original call - packet.data = ["*"].concat(args); - onevent.call(this, packet); // additional call to catch-all - }; - // register catch all. - socket.on("*", (notification, payload) => { - if (notification !== "*") { - this.socketNotificationReceived(notification, payload); - } + socket.onAny((notification, payload) => { + this.socketNotificationReceived(notification, payload); }); }); } diff --git a/js/server.js b/js/server.js index bfa0f911d7..42b3ff6692 100644 --- a/js/server.js +++ b/js/server.js @@ -8,8 +8,7 @@ const helmet = require("helmet"); const socketio = require("socket.io"); const Log = require("logger"); -const Utils = require("./utils"); -const { cors, getConfig, getHtml, getVersion, getStartup } = require("./server_functions"); +const { cors, getConfig, getHtml, getVersion, getStartup, getEnvVars } = require("./server_functions"); /** * Server @@ -73,8 +72,11 @@ function Server (config) { app.use(helmet(config.httpHeaders)); app.use("/js", express.static(__dirname)); - // TODO add tests directory only when running tests? - const directories = ["/config", "/css", "/fonts", "/modules", "/vendor", "/translations", "/tests/configs", "/tests/mocks"]; + let directories = ["/config", "/css", "/fonts", "/modules", "/vendor", "/translations"]; + if (process.env.JEST_WORKER_ID !== undefined) { + // add tests directories only when running tests + directories.push("/tests/configs", "/tests/mocks"); + } for (const directory of directories) { app.use(directory, express.static(path.resolve(global.root_path + directory))); } @@ -87,6 +89,8 @@ function Server (config) { app.get("/startup", (req, res) => getStartup(req, res)); + app.get("/env", (req, res) => getEnvVars(req, res)); + app.get("/", (req, res) => getHtml(req, res)); server.on("listening", () => { diff --git a/js/server_functions.js b/js/server_functions.js index 7d4358b2e5..65928d732e 100644 --- a/js/server_functions.js +++ b/js/server_functions.js @@ -45,12 +45,12 @@ async function cors (req, res) { url = match[1]; const headersToSend = getHeadersToSend(req.url); - const expectedRecievedHeaders = geExpectedRecievedHeaders(req.url); + const expectedReceivedHeaders = geExpectedReceivedHeaders(req.url); Log.log(`cors url: ${url}`); const response = await fetch(url, { headers: headersToSend }); - for (const header of expectedRecievedHeaders) { + for (const header of expectedReceivedHeaders) { const headerValue = response.headers.get(header); if (header) res.set(header, headerValue); } @@ -89,16 +89,16 @@ function getHeadersToSend (url) { * @param {string} url - The url containing the expected headers from the response. * @returns {string[]} headers - The name of the expected headers. */ -function geExpectedRecievedHeaders (url) { - const expectedRecievedHeaders = ["Content-Type"]; - const expectedRecievedHeadersMatch = new RegExp("expectedheaders=(.+?)(&|$)", "g").exec(url); - if (expectedRecievedHeadersMatch) { - const headers = expectedRecievedHeadersMatch[1].split(","); +function geExpectedReceivedHeaders (url) { + const expectedReceivedHeaders = ["Content-Type"]; + const expectedReceivedHeadersMatch = new RegExp("expectedheaders=(.+?)(&|$)", "g").exec(url); + if (expectedReceivedHeadersMatch) { + const headers = expectedReceivedHeadersMatch[1].split(","); for (const header of headers) { - expectedRecievedHeaders.push(header); + expectedReceivedHeaders.push(header); } } - return expectedRecievedHeaders; + return expectedReceivedHeaders; } /** @@ -128,4 +128,30 @@ function getVersion (req, res) { res.send(global.version); } -module.exports = { cors, getConfig, getHtml, getVersion, getStartup }; +/** + * Gets environment variables needed in the browser. + * @returns {object} environment variables key: values + */ +function getEnvVarsAsObj () { + const obj = { modulesDir: `${config.foreignModulesDir}`, customCss: `${config.customCss}` }; + if (process.env.MM_MODULES_DIR) { + obj.modulesDir = process.env.MM_MODULES_DIR.replace(`${global.root_path}/`, ""); + } + if (process.env.MM_CUSTOMCSS_FILE) { + obj.customCss = process.env.MM_CUSTOMCSS_FILE.replace(`${global.root_path}/`, ""); + } + + return obj; +} + +/** + * Gets environment variables needed in the browser. + * @param {Request} req - the request + * @param {Response} res - the result + */ +function getEnvVars (req, res) { + const obj = getEnvVarsAsObj(); + res.send(obj); +} + +module.exports = { cors, getConfig, getHtml, getVersion, getStartup, getEnvVars, getEnvVarsAsObj }; diff --git a/js/translator.js b/js/translator.js index e742eb9c3b..f420fbed1e 100644 --- a/js/translator.js +++ b/js/translator.js @@ -15,14 +15,14 @@ const Translator = (function () { xhr.onreadystatechange = function () { if (xhr.readyState === 4 && xhr.status === 200) { // needs error handler try/catch at least - let fileinfo = null; + let fileInfo = null; try { - fileinfo = JSON.parse(xhr.responseText); + fileInfo = JSON.parse(xhr.responseText); } catch (exception) { // nothing here, but don't die Log.error(` loading json file =${file} failed`); } - resolve(fileinfo); + resolve(fileInfo); } }; xhr.send(null); diff --git a/js/utils.js b/js/utils.js index 89784f6937..9536a1b070 100644 --- a/js/utils.js +++ b/js/utils.js @@ -1,7 +1,17 @@ const execSync = require("node:child_process").execSync; -const Log = require("logger"); +const path = require("node:path"); + +const rootPath = path.resolve(`${__dirname}/../`); +const Log = require(`${rootPath}/js/logger.js`); +const os = require("node:os"); +const fs = require("node:fs"); const si = require("systeminformation"); +const modulePositions = []; // will get list from index.html +const regionRegEx = /"region ([^"]*)/i; +const indexFileName = "index.html"; +const discoveredPositionsJSFilename = "js/positions.js"; + module.exports = { async logSystemInformation () { @@ -14,7 +24,7 @@ module.exports = { versions: "kernel, node, npm, pm2" }); let systemDataString = "System information:"; - systemDataString += `\n### SYSTEM: manufacturer: ${staticData["system"]["manufacturer"]}; model: ${staticData["system"]["model"]}; raspberry: ${staticData["system"]["raspberry"]}; virtual: ${staticData["system"]["virtual"]}`; + systemDataString += `\n### SYSTEM: manufacturer: ${staticData["system"]["manufacturer"]}; model: ${staticData["system"]["model"]}; virtual: ${staticData["system"]["virtual"]}`; systemDataString += `\n### OS: platform: ${staticData["osInfo"]["platform"]}; distro: ${staticData["osInfo"]["distro"]}; release: ${staticData["osInfo"]["release"]}; arch: ${staticData["osInfo"]["arch"]}; kernel: ${staticData["versions"]["kernel"]}`; systemDataString += `\n### VERSIONS: electron: ${process.versions.electron}; used node: ${staticData["versions"]["node"]}; installed node: ${installedNodeVersion}; npm: ${staticData["versions"]["npm"]}; pm2: ${staticData["versions"]["pm2"]}`; systemDataString += `\n### OTHER: timeZone: ${Intl.DateTimeFormat().resolvedOptions().timeZone}; ELECTRON_ENABLE_GPU: ${process.env.ELECTRON_ENABLE_GPU}`; @@ -29,12 +39,35 @@ module.exports = { // return all available module positions getAvailableModulePositions () { - return ["top_bar", "top_left", "top_center", "top_right", "upper_third", "middle_center", "lower_third", "bottom_left", "bottom_center", "bottom_right", "bottom_bar", "fullscreen_above", "fullscreen_below"]; + return modulePositions; }, - // return if postion is on modulePositions Array (true/false) + // return if position is on modulePositions Array (true/false) moduleHasValidPosition (position) { if (this.getAvailableModulePositions().indexOf(position) === -1) return false; return true; + }, + + getModulePositions () { + // if not already discovered + if (modulePositions.length === 0) { + // get the lines of the index.html + const lines = fs.readFileSync(indexFileName).toString().split(os.EOL); + // loop thru the lines + lines.forEach((line) => { + // run the regex on each line + const results = regionRegEx.exec(line); + // if the regex returned something + if (results && results.length > 0) { + // get the position parts and replace space with underscore + const positionName = results[1].replace(" ", "_"); + // add it to the list + modulePositions.push(positionName); + } + }); + fs.writeFileSync(discoveredPositionsJSFilename, `const modulePositions=${JSON.stringify(modulePositions)}`); + } + // return the list to the caller + return modulePositions; } }; diff --git a/modules/default/calendar/calendar.js b/modules/default/calendar/calendar.js index 4b0409c01c..31b863eb28 100644 --- a/modules/default/calendar/calendar.js +++ b/modules/default/calendar/calendar.js @@ -82,9 +82,12 @@ Module.register("calendar", { // Define required translations. getTranslations () { - // The translations for the default modules are defined in the core translation files. - // Therefore we can just return false. Otherwise we should have returned a dictionary. - // If you're trying to build your own module including translations, check out the documentation. + + /* + * The translations for the default modules are defined in the core translation files. + * Therefore we can just return false. Otherwise we should have returned a dictionary. + * If you're trying to build your own module including translations, check out the documentation. + */ return false; }, @@ -148,8 +151,10 @@ Module.register("calendar", { }; } - // tell helper to start a fetcher for this calendar - // fetcher till cycle + /* + * tell helper to start a fetcher for this calendar + * fetcher till cycle + */ this.addCalendar(calendar.url, calendar.auth, calendarConfig); }); @@ -627,10 +632,11 @@ Module.register("calendar", { event.tomorrow = !event.today && event.startDate >= today + ONE_DAY && event.startDate < today + 2 * ONE_DAY; event.dayAfterTomorrow = !event.tomorrow && event.startDate >= today + ONE_DAY * 2 && event.startDate < today + 3 * ONE_DAY; - /* if sliceMultiDayEvents is set to true, multiday events (events exceeding at least one midnight) are sliced into days, + /* + * if sliceMultiDayEvents is set to true, multiday events (events exceeding at least one midnight) are sliced into days, * otherwise, esp. in dateheaders mode it is not clear how long these events are. */ - const maxCount = Math.ceil((event.endDate - 1 - moment(event.startDate, "x").endOf("day").format("x")) / ONE_DAY) + 1; + const maxCount = Math.round((event.endDate - 1 - moment(event.startDate, "x").endOf("day").format("x")) / ONE_DAY) + 1; if (this.config.sliceMultiDayEvents && maxCount > 1) { const splitEvents = []; let midnight @@ -638,19 +644,20 @@ Module.register("calendar", { .clone() .startOf("day") .add(1, "day") + .endOf("day") .format("x"); let count = 1; while (event.endDate > midnight) { const thisEvent = JSON.parse(JSON.stringify(event)); // clone object thisEvent.today = thisEvent.startDate >= today && thisEvent.startDate < today + ONE_DAY; thisEvent.tomorrow = !thisEvent.today && thisEvent.startDate >= today + ONE_DAY && thisEvent.startDate < today + 2 * ONE_DAY; - thisEvent.endDate = midnight; + thisEvent.endDate = moment(midnight, "x").clone().subtract(1, "day").format("x"); thisEvent.title += ` (${count}/${maxCount})`; splitEvents.push(thisEvent); event.startDate = midnight; count += 1; - midnight = moment(midnight, "x").add(1, "day").format("x"); // next day + midnight = moment(midnight, "x").add(1, "day").endOf("day").format("x"); // next day } // Last day event.title += ` (${count}/${maxCount})`; @@ -677,16 +684,21 @@ Module.register("calendar", { return events; } - // Limit the number of days displayed - // If limitDays is set > 0, limit display to that number of days + /* + * Limit the number of days displayed + * If limitDays is set > 0, limit display to that number of days + */ if (this.config.limitDays > 0) { let newEvents = []; let lastDate = today.clone().subtract(1, "days").format("YYYYMMDD"); let days = 0; for (const ev of events) { let eventDate = moment(ev.startDate, "x").format("YYYYMMDD"); - // if date of event is later than lastdate - // check if we already are showing max unique days + + /* + * if date of event is later than lastdate + * check if we already are showing max unique days + */ if (eventDate > lastDate) { // if the only entry in the first day is a full day event that day is not counted as unique if (!this.config.limitDaysNeverSkip && newEvents.length === 1 && days === 1 && newEvents[0].fullDayEvent) { diff --git a/modules/default/calendar/debug.js b/modules/default/calendar/debug.js index 71ed2f4abd..74d48cd711 100644 --- a/modules/default/calendar/debug.js +++ b/modules/default/calendar/debug.js @@ -1,4 +1,5 @@ -/* CalendarFetcher Tester +/* + * CalendarFetcher Tester * use this script with `node debug.js` to test the fetcher without the need * of starting the MagicMirror² core. Adjust the values below to your desire. */ diff --git a/modules/default/compliments/compliments.js b/modules/default/compliments/compliments.js index c249f9915f..4c4bef471f 100644 --- a/modules/default/compliments/compliments.js +++ b/modules/default/compliments/compliments.js @@ -1,3 +1,5 @@ +/* global Cron */ + Module.register("compliments", { // Module config defaults. defaults: { @@ -21,10 +23,12 @@ Module.register("compliments", { lastIndexUsed: -1, // Set currentweather from module currentWeatherType: "", - + cron_regex: /^(((\d+,)+\d+|((\d+|[*])[/]\d+|((JAN|FEB|APR|MA[RY]|JU[LN]|AUG|SEP|OCT|NOV|DEC)(-(JAN|FEB|APR|MA[RY]|JU[LN]|AUG|SEP|OCT|NOV|DEC))?))|(\d+-\d+)|\d+(-\d+)?[/]\d+(-\d+)?|\d+|[*]|(MON|TUE|WED|THU|FRI|SAT|SUN)(-(MON|TUE|WED|THU|FRI|SAT|SUN))?) ?){5}$/i, + date_regex: "[1-9.][0-9.][0-9.]{2}-([0][1-9]|[1][0-2])-([1-2][0-9]|[0][1-9]|[3][0-1])", + pre_defined_types: ["anytime", "morning", "afternoon", "evening"], // Define required scripts. getScripts () { - return ["moment.js"]; + return ["croner.js", "moment.js"]; }, // Define start sequence. @@ -38,11 +42,45 @@ Module.register("compliments", { this.config.compliments = JSON.parse(response); this.updateDom(); } + let minute_sync_delay = 1; + // loop thru all the configured when events + for (let m of Object.keys(this.config.compliments)) { + // if it is a cron entry + if (this.isCronEntry(m)) { + // we need to synch our interval cycle to the minute + minute_sync_delay = (60 - (moment().second())) * 1000; + break; + } + } + // Schedule update timer. sync to the minute start (if needed), so minute based events happen on the minute start + setTimeout(() => { + setInterval(() => { + this.updateDom(this.config.fadeSpeed); + }, this.config.updateInterval); + }, + minute_sync_delay); + }, + + // check to see if this entry could be a cron entry wich contains spaces + isCronEntry (entry) { + return entry.includes(" "); + }, - // Schedule update timer. - setInterval(() => { - this.updateDom(this.config.fadeSpeed); - }, this.config.updateInterval); + /** + * @param {string} cronExpression The cron expression. See https://croner.56k.guru/usage/pattern/ + * @param {Date} [timestamp] The timestamp to check. Defaults to the current time. + * @returns {number} The number of seconds until the next cron run. + */ + getSecondsUntilNextCronRun (cronExpression, timestamp = new Date()) { + // Required for seconds precision + const adjustedTimestamp = new Date(timestamp.getTime() - 1000); + + // https://www.npmjs.com/package/croner + const cronJob = new Cron(cronExpression); + const nextRunTime = cronJob.nextRun(adjustedTimestamp); + + const secondsDelta = (nextRunTime - adjustedTimestamp) / 1000; + return secondsDelta; }, /** @@ -75,8 +113,9 @@ Module.register("compliments", { * @returns {string[]} array with compliments for the time of the day. */ complimentArray () { - const hour = moment().hour(); - const date = moment().format("YYYY-MM-DD"); + const now = moment(); + const hour = now.hour(); + const date = now.format("YYYY-MM-DD"); let compliments = []; // Add time of day compliments @@ -91,20 +130,49 @@ Module.register("compliments", { // Add compliments based on weather if (this.currentWeatherType in this.config.compliments) { Array.prototype.push.apply(compliments, this.config.compliments[this.currentWeatherType]); + // if the predefine list doesn't include it (yet) + if (!this.pre_defined_types.includes(this.currentWeatherType)) { + // add it + this.pre_defined_types.push(this.currentWeatherType); + } } // Add compliments for anytime Array.prototype.push.apply(compliments, this.config.compliments.anytime); - // Add compliments for special days - for (let entry in this.config.compliments) { - if (new RegExp(entry).test(date)) { - // Only display compliments configured for the day if specialDayUnique is set to true - if (this.config.specialDayUnique) { - compliments.length = 0; - } - Array.prototype.push.apply(compliments, this.config.compliments[entry]); + // get the list of just date entry keys + let temp_list = Object.keys(this.config.compliments).filter((k) => { + if (this.pre_defined_types.includes(k)) return false; + else return true; + }); + + let date_compliments = []; + // Add compliments for special day/times + for (let entry of temp_list) { + // check if this could be a cron type entry + if (this.isCronEntry(entry)) { + // make sure the regex is valid + if (new RegExp(this.cron_regex).test(entry)) { + // check if we are in the time range for the cron entry + if (this.getSecondsUntilNextCronRun(entry, now.set("seconds", 0).toDate()) <= 1) { + // if so, use its notice entries + Array.prototype.push.apply(date_compliments, this.config.compliments[entry]); + } + } else Log.error(`compliments cron syntax invalid=${JSON.stringify(entry)}`); + } else if (new RegExp(entry).test(date)) { + Array.prototype.push.apply(date_compliments, this.config.compliments[entry]); + } + } + + // if we found any date compliments + if (date_compliments.length) { + // and the special flag is true + if (this.config.specialDayUnique) { + // clear the non-date compliments if any + compliments.length = 0; } + // put the date based compliments on the list + Array.prototype.push.apply(compliments, date_compliments); } return compliments; diff --git a/modules/default/defaultmodules.js b/modules/default/defaultmodules.js index e28413ff7b..695bba4476 100644 --- a/modules/default/defaultmodules.js +++ b/modules/default/defaultmodules.js @@ -1,4 +1,5 @@ -/* Default Modules List +/* + * Default Modules List * Modules listed below can be loaded without the 'default/' prefix. Omitting the default folder name. */ const defaultModules = ["alert", "calendar", "clock", "compliments", "helloworld", "newsfeed", "updatenotification", "weather"]; diff --git a/modules/default/updatenotification/update_helper.js b/modules/default/updatenotification/update_helper.js index 0bf3868e7c..122b6b3567 100644 --- a/modules/default/updatenotification/update_helper.js +++ b/modules/default/updatenotification/update_helper.js @@ -4,7 +4,8 @@ const fs = require("node:fs"); const Log = require("logger"); -/* class Updater +/* + * class Updater * Allow to self updating 3rd party modules from command defined in config * * [constructor] read value in config: @@ -84,13 +85,15 @@ class Updater { return updater; } - // module updater with his proper command - // return object as result - //{ - // error: , // if error detected - // updated: , // if updated successfully - // needRestart: // if magicmirror restart required - //}; + /* + * module updater with his proper command + * return object as result + * { + * error: , // if error detected + * updated: , // if updated successfully + * needRestart: // if magicmirror restart required + * }; + */ updateProcess (module) { let Result = { error: false, diff --git a/modules/default/weather/providers/envcanada.js b/modules/default/weather/providers/envcanada.js index 7372e17689..8255802628 100644 --- a/modules/default/weather/providers/envcanada.js +++ b/modules/default/weather/providers/envcanada.js @@ -1,6 +1,7 @@ /* global WeatherProvider, WeatherObject, WeatherUtils */ -/* This class is a provider for Environment Canada MSC Datamart +/* + * This class is a provider for Environment Canada MSC Datamart * Note that this is only for Canadian locations and does not require an API key (access is anonymous) * * EC Documentation at following links: @@ -25,9 +26,7 @@ * * License to use Environment Canada (EC) data is detailed here: * https://eccc-msc.github.io/open-data/licence/readme_en/ - * */ - WeatherProvider.register("envcanada", { // Set the name of the provider for debugging and alerting purposes (eg. provide eye-catcher) providerName: "Environment Canada", @@ -39,10 +38,10 @@ WeatherProvider.register("envcanada", { provCode: "ON" }, - // - // Set config values (equates to weather module config values). Also set values pertaining to caching of - // Today's temperature forecast (for use in the Forecast functions below) - // + /* + * Set config values (equates to weather module config values). Also set values pertaining to caching of + * Today's temperature forecast (for use in the Forecast functions below) + */ setConfig (config) { this.config = config; @@ -52,17 +51,17 @@ WeatherProvider.register("envcanada", { this.cacheCurrentTemp = 999; }, - // - // Called when the weather provider is started - // + /* + * Called when the weather provider is started + */ start () { Log.info(`Weather provider: ${this.providerName} started.`); this.setFetchedLocation(this.config.location); }, - // - // Override the fetchCurrentWeather method to query EC and construct a Current weather object - // + /* + * Override the fetchCurrentWeather method to query EC and construct a Current weather object + */ fetchCurrentWeather () { this.fetchData(this.getUrl(), "xml") .then((data) => { @@ -80,9 +79,9 @@ WeatherProvider.register("envcanada", { .finally(() => this.updateAvailable()); }, - // - // Override the fetchWeatherForecast method to query EC and construct Forecast weather objects - // + /* + * Override the fetchWeatherForecast method to query EC and construct Forecast weather objects + */ fetchWeatherForecast () { this.fetchData(this.getUrl(), "xml") .then((data) => { @@ -100,9 +99,9 @@ WeatherProvider.register("envcanada", { .finally(() => this.updateAvailable()); }, - // - // Override the fetchWeatherHourly method to query EC and construct Forecast weather objects - // + /* + * Override the fetchWeatherHourly method to query EC and construct Forecast weather objects + */ fetchWeatherHourly () { this.fetchData(this.getUrl(), "xml") .then((data) => { @@ -120,36 +119,30 @@ WeatherProvider.register("envcanada", { .finally(() => this.updateAvailable()); }, - ////////////////////////////////////////////////////////////////////////////////// - // - // Environment Canada methods - not part of the standard Provider methods - // - ////////////////////////////////////////////////////////////////////////////////// - - // - // Build the EC URL based on the Site Code and Province Code specified in the config params. Note that the - // URL defaults to the English version simply because there is no language dependency in the data - // being accessed. This is only pertinent when using the EC data elements that contain a textual forecast. - // + /* + * Build the EC URL based on the Site Code and Province Code specified in the config params. Note that the + * URL defaults to the English version simply because there is no language dependency in the data + * being accessed. This is only pertinent when using the EC data elements that contain a textual forecast. + */ getUrl () { return `https://dd.weather.gc.ca/citypage_weather/xml/${this.config.provCode}/${this.config.siteCode}_e.xml`; }, - // - // Generate a WeatherObject based on current EC weather conditions - // - + /* + * Generate a WeatherObject based on current EC weather conditions + */ generateWeatherObjectFromCurrentWeather (ECdoc) { const currentWeather = new WeatherObject(); - // There are instances where EC will update weather data and current temperature will not be - // provided. While this is a defect in the EC systems, we need to accommodate to avoid a current temp - // of NaN being displayed. Therefore... whenever we get a valid current temp from EC, we will cache - // the value. Whenever EC data is missing current temp, we will provide the cached value - // instead. This is reasonable since the cached value will typically be accurate within the previous - // hour. The only time this does not work as expected is when MM is restarted and the first query to - // EC finds no current temp. In this scenario, MM will end up displaying a current temp of null; - + /* + * There are instances where EC will update weather data and current temperature will not be + * provided. While this is a defect in the EC systems, we need to accommodate to avoid a current temp + * of NaN being displayed. Therefore... whenever we get a valid current temp from EC, we will cache + * the value. Whenever EC data is missing current temp, we will provide the cached value + * instead. This is reasonable since the cached value will typically be accurate within the previous + * hour. The only time this does not work as expected is when MM is restarted and the first query to + * EC finds no current temp. In this scenario, MM will end up displaying a current temp of null; + */ if (ECdoc.querySelector("siteData currentConditions temperature").textContent) { currentWeather.temperature = ECdoc.querySelector("siteData currentConditions temperature").textContent; this.cacheCurrentTemp = currentWeather.temperature; @@ -163,19 +156,19 @@ WeatherProvider.register("envcanada", { currentWeather.humidity = ECdoc.querySelector("siteData currentConditions relativeHumidity").textContent; - // Ensure showPrecipitationAmount is forced to false. EC does not really provide POP for current day - // and this feature for the weather module (current only) is sort of broken in that it wants - // to say POP but will display precip as an accumulated amount vs. a percentage. - + /* + * Ensure showPrecipitationAmount is forced to false. EC does not really provide POP for current day + * and this feature for the weather module (current only) is sort of broken in that it wants + * to say POP but will display precip as an accumulated amount vs. a percentage. + */ this.config.showPrecipitationAmount = false; - // - // If the module config wants to showFeelsLike... default to the current temperature. - // Check for EC wind chill and humidex values and overwrite the feelsLikeTemp value. - // This assumes that the EC current conditions will never contain both a wind chill - // and humidex temperature. - // - + /* + * If the module config wants to showFeelsLike... default to the current temperature. + * Check for EC wind chill and humidex values and overwrite the feelsLikeTemp value. + * This assumes that the EC current conditions will never contain both a wind chill + * and humidex temperature. + */ if (this.config.showFeelsLike) { currentWeather.feelsLikeTemp = currentWeather.temperature; @@ -188,16 +181,10 @@ WeatherProvider.register("envcanada", { } } - // // Need to map EC weather icon to MM weatherType values - // - currentWeather.weatherType = this.convertWeatherType(ECdoc.querySelector("siteData currentConditions iconCode").textContent); - // // Capture the sunrise and sunset values from EC data - // - const sunList = ECdoc.querySelectorAll("siteData riseSet dateTime"); currentWeather.sunrise = moment(sunList[1].querySelector("timeStamp").textContent, "YYYYMMDDhhmmss"); @@ -206,13 +193,11 @@ WeatherProvider.register("envcanada", { return currentWeather; }, - // - // Generate an array of WeatherObjects based on EC weather forecast - // - + /* + * Generate an array of WeatherObjects based on EC weather forecast + */ generateWeatherObjectsFromForecast (ECdoc) { // Declare an array to hold each day's forecast object - const days = []; const weather = new WeatherObject(); @@ -226,37 +211,33 @@ WeatherProvider.register("envcanada", { weather.precipitationAmount = null; - // - // The EC forecast is held in a 12-element array - Elements 0 to 11 - with each day encompassing - // 2 elements. the first element for a day details the Today (daytime) forecast while the second - // element details the Tonight (nightime) forecast. Element 0 is always for the current day. - // - // However... the forecast is somewhat 'rolling'. - // - // If the EC forecast is queried in the morning, then Element 0 will contain Current - // Today and Element 1 will contain Current Tonight. From there, the next 5 days of forecast will be - // contained in Elements 2/3, 4/5, 6/7, 8/9, and 10/11. This module will create a 6-day forecast using - // all of these Elements. - // - // But, if the EC forecast is queried in late afternoon, the Current Today forecast will be rolled - // off and Element 0 will contain Current Tonight. From there, the next 5 days will be contained in - // Elements 1/2, 3/4, 5/6, 7/8, and 9/10. As well, Elelement 11 will contain a forecast for a 6th day, - // but only for the Today portion (not Tonight). This module will create a 6-day forecast using - // Elements 0 to 11, and will ignore the additional Todat forecast in Element 11. - // - // We need to determine if Element 0 is showing the forecast for Current Today or Current Tonight. - // This is required to understand how Min and Max temperature will be determined, and to understand - // where the next day's (aka Tomorrow's) forecast is located in the forecast array. - // - + /* + * The EC forecast is held in a 12-element array - Elements 0 to 11 - with each day encompassing + * 2 elements. the first element for a day details the Today (daytime) forecast while the second + * element details the Tonight (nightime) forecast. Element 0 is always for the current day. + * + * However... the forecast is somewhat 'rolling'. + * + * If the EC forecast is queried in the morning, then Element 0 will contain Current + * Today and Element 1 will contain Current Tonight. From there, the next 5 days of forecast will be + * contained in Elements 2/3, 4/5, 6/7, 8/9, and 10/11. This module will create a 6-day forecast using + * all of these Elements. + * + * But, if the EC forecast is queried in late afternoon, the Current Today forecast will be rolled + * off and Element 0 will contain Current Tonight. From there, the next 5 days will be contained in + * Elements 1/2, 3/4, 5/6, 7/8, and 9/10. As well, Elelement 11 will contain a forecast for a 6th day, + * but only for the Today portion (not Tonight). This module will create a 6-day forecast using + * Elements 0 to 11, and will ignore the additional Todat forecast in Element 11. + * + * We need to determine if Element 0 is showing the forecast for Current Today or Current Tonight. + * This is required to understand how Min and Max temperature will be determined, and to understand + * where the next day's (aka Tomorrow's) forecast is located in the forecast array. + */ let nextDay = 0; let lastDay = 0; const currentTemp = ECdoc.querySelector("siteData currentConditions temperature").textContent; - // // If the first Element is Current Today, look at Current Today and Current Tonight for the current day. - // - if (foreGroup[0].querySelector("period[textForecastName='Today']")) { this.todaytempCacheMin = 0; this.todaytempCacheMax = 0; @@ -266,167 +247,144 @@ WeatherProvider.register("envcanada", { this.setPrecipitation(weather, foreGroup, 0); - // - // Set the Element number that will reflect where the next day's forecast is located. Also set - // the Element number where the end of the forecast will be. This is important because of the - // rolling nature of the EC forecast. In the current scenario (Today and Tonight are present - // in elements 0 and 11, we know that we will have 6 full days of forecasts and we will use - // them. We will set lastDay such that we iterate through all 12 elements of the forecast. - // - + /* + * Set the Element number that will reflect where the next day's forecast is located. Also set + * the Element number where the end of the forecast will be. This is important because of the + * rolling nature of the EC forecast. In the current scenario (Today and Tonight are present + * in elements 0 and 11, we know that we will have 6 full days of forecasts and we will use + * them. We will set lastDay such that we iterate through all 12 elements of the forecast. + */ nextDay = 2; lastDay = 12; } - // // If the first Element is Current Tonight, look at Tonight only for the current day. - // if (foreGroup[0].querySelector("period[textForecastName='Tonight']")) { this.setMinMaxTemps(weather, foreGroup, 0, false, currentTemp); this.setPrecipitation(weather, foreGroup, 0); - // - // Set the Element number that will reflect where the next day's forecast is located. Also set - // the Element number where the end of the forecast will be. This is important because of the - // rolling nature of the EC forecast. In the current scenario (only Current Tonight is present - // in Element 0, we know that we will have 6 full days of forecasts PLUS a half-day and - // forecast in the final element. Because we will only use full day forecasts, we set the - // lastDay number to ensure we ignore that final half-day (in forecast Element 11). - // - + /* + * Set the Element number that will reflect where the next day's forecast is located. Also set + * the Element number where the end of the forecast will be. This is important because of the + * rolling nature of the EC forecast. In the current scenario (only Current Tonight is present + * in Element 0, we know that we will have 6 full days of forecasts PLUS a half-day and + * forecast in the final element. Because we will only use full day forecasts, we set the + * lastDay number to ensure we ignore that final half-day (in forecast Element 11). + */ nextDay = 1; lastDay = 11; } - // - // Need to map EC weather icon to MM weatherType values. Always pick the first Element's icon to - // reflect either Today or Tonight depending on what the forecast is showing in Element 0. - // - + /* + * Need to map EC weather icon to MM weatherType values. Always pick the first Element's icon to + * reflect either Today or Tonight depending on what the forecast is showing in Element 0. + */ weather.weatherType = this.convertWeatherType(foreGroup[0].querySelector("abbreviatedForecast iconCode").textContent); // Push the weather object into the forecast array. - days.push(weather); - // - // Now do the rest of the forecast starting at nextDay. We will process each day using 2 EC - // forecast Elements. This will address the fact that the EC forecast always includes Today and - // Tonight for each day. This is why we iterate through the forecast by a a count of 2, with each - // iteration looking at the current Element and the next Element. - // - + /* + * Now do the rest of the forecast starting at nextDay. We will process each day using 2 EC + * forecast Elements. This will address the fact that the EC forecast always includes Today and + * Tonight for each day. This is why we iterate through the forecast by a a count of 2, with each + * iteration looking at the current Element and the next Element. + */ let lastDate = moment(baseDate, "YYYYMMDDhhmmss"); for (let stepDay = nextDay; stepDay < lastDay; stepDay += 2) { let weather = new WeatherObject(); // Add 1 to the date to reflect the current forecast day we are building - lastDate = lastDate.add(1, "day"); weather.date = moment(lastDate); - // Capture the temperatures for the current Element and the next Element in order to set - // the Min and Max temperatures for the forecast - + /* + * Capture the temperatures for the current Element and the next Element in order to set + * the Min and Max temperatures for the forecast + */ this.setMinMaxTemps(weather, foreGroup, stepDay, true, currentTemp); weather.precipitationAmount = null; this.setPrecipitation(weather, foreGroup, stepDay); - // // Need to map EC weather icon to MM weatherType values. Always pick the first Element icon. - // - weather.weatherType = this.convertWeatherType(foreGroup[stepDay].querySelector("abbreviatedForecast iconCode").textContent); // Push the weather object into the forecast array. - days.push(weather); } return days; }, - // - // Generate an array of WeatherObjects based on EC hourly weather forecast - // - + /* + * Generate an array of WeatherObjects based on EC hourly weather forecast + */ generateWeatherObjectsFromHourly (ECdoc) { // Declare an array to hold each hour's forecast object - const hours = []; // Get local timezone UTC offset so that each hourly time can be calculated properly - const baseHours = ECdoc.querySelectorAll("siteData hourlyForecastGroup dateTime"); const hourOffset = baseHours[1].getAttribute("UTCOffset"); - // - // The EC hourly forecast is held in a 24-element array - Elements 0 to 23 - with Element 0 holding - // the forecast for the next 'on the hour' timeslot. This means the array is a rolling 24 hours. - // - + /* + * The EC hourly forecast is held in a 24-element array - Elements 0 to 23 - with Element 0 holding + * the forecast for the next 'on the hour' timeslot. This means the array is a rolling 24 hours. + */ const hourGroup = ECdoc.querySelectorAll("siteData hourlyForecastGroup hourlyForecast"); for (let stepHour = 0; stepHour < 24; stepHour += 1) { const weather = new WeatherObject(); // Determine local time by applying UTC offset to the forecast timestamp - const foreTime = moment(hourGroup[stepHour].getAttribute("dateTimeUTC"), "YYYYMMDDhhmmss"); const currTime = foreTime.add(hourOffset, "hours"); weather.date = moment(currTime); // Capture the temperature - weather.temperature = hourGroup[stepHour].querySelector("temperature").textContent; // Capture Likelihood of Precipitation (LOP) and unit-of-measure values - const precipLOP = hourGroup[stepHour].querySelector("lop").textContent * 1.0; if (precipLOP > 0) { weather.precipitationProbability = precipLOP; } - // // Need to map EC weather icon to MM weatherType values. Always pick the first Element icon. - // - weather.weatherType = this.convertWeatherType(hourGroup[stepHour].querySelector("iconCode").textContent); // Push the weather object into the forecast array. - hours.push(weather); } return hours; }, - // - // Determine Min and Max temp based on a supplied Forecast Element index and a boolen that denotes if - // the next Forecast element should be considered - i.e. look at Today *and* Tonight vs.Tonight-only - // + /* + * Determine Min and Max temp based on a supplied Forecast Element index and a boolen that denotes if + * the next Forecast element should be considered - i.e. look at Today *and* Tonight vs.Tonight-only + */ setMinMaxTemps (weather, foreGroup, today, fullDay, currentTemp) { const todayTemp = foreGroup[today].querySelector("temperatures temperature").textContent; const todayClass = foreGroup[today].querySelector("temperatures temperature").getAttribute("class"); - // - // The following logic is largely aimed at accommodating the Current day's forecast whereby we - // can have either Current Today+Current Tonight or only Current Tonight. - // - // If fullDay is false, then we only have Tonight for the current day's forecast - meaning we have - // lost a min or max temp value for the day. Therefore, we will see if we were able to cache the the - // Today forecast for the current day. If we have, we will use them. If we do not have the cached values, - // it means that MM or the Computer has been restarted since the time EC rolled off Today from the - // forecast. In this scenario, we will simply default to the Current Conditions temperature and then - // check the Tonight temperature. - // - + /* + * The following logic is largely aimed at accommodating the Current day's forecast whereby we + * can have either Current Today+Current Tonight or only Current Tonight. + * + * If fullDay is false, then we only have Tonight for the current day's forecast - meaning we have + * lost a min or max temp value for the day. Therefore, we will see if we were able to cache the the + * Today forecast for the current day. If we have, we will use them. If we do not have the cached values, + * it means that MM or the Computer has been restarted since the time EC rolled off Today from the + * forecast. In this scenario, we will simply default to the Current Conditions temperature and then + * check the Tonight temperature.x + */ if (fullDay === false) { if (this.todayCached === true) { weather.minTemperature = this.todayTempCacheMin; @@ -437,13 +395,12 @@ WeatherProvider.register("envcanada", { } } - // - // We will check to see if the current Element's temperature is Low or High and set weather values - // accordingly. We will also check the condition where fullDay is true *and* we are looking at forecast - // element 0. This is a special case where we will cache temperature values so that we have them later - // in the current day when the Current Today element rolls off and we have Current Tonight only. - // - + /* + * We will check to see if the current Element's temperature is Low or High and set weather values + * accordingly. We will also check the condition where fullDay is true *and* we are looking at forecast + * element 0. This is a special case where we will cache temperature values so that we have them later + * in the current day when the Current Today element rolls off and we have Current Tonight only. + */ if (todayClass === "low") { weather.minTemperature = todayTemp; if (today === 0 && fullDay === true) { @@ -473,25 +430,24 @@ WeatherProvider.register("envcanada", { } }, - // - // Check for a Precipitation forecast. EC can provide a forecast in 2 ways: either an accumulation figure - // or a POP percentage. If there is a POP, then that is what the module will show. If there is an accumulation, - // then it will be displayed ONLY if no POP is present. - // - // POP Logic: By default, we want to show the POP for 'daytime' since we are presuming that is what - // people are more interested in seeing. While EC provides a separate POP for daytime and nightime portions - // of each day, the weather module does not really allow for that view of a daily forecast. There we will - // ignore any nightime portion. There is an exception however! For the Current day, the EC data will only show - // the nightime forecast after a certain point in the afternoon. As such, we will be showing the nightime POP - // (if one exists) in that specific scenario. - // - // Accumulation Logic: Similar to POP, we want to show accumulation for 'daytime' since we presume that is what - // people are interested in seeing. While EC provides a separate accumulation for daytime and nightime portions - // of each day, the weather module does not really allow for that view of a daily forecast. There we will - // ignore any nightime portion. There is an exception however! For the Current day, the EC data will only show - // the nightime forecast after a certain point in that specific scenario. - // - + /* + * Check for a Precipitation forecast. EC can provide a forecast in 2 ways: either an accumulation figure + * or a POP percentage. If there is a POP, then that is what the module will show. If there is an accumulation, + * then it will be displayed ONLY if no POP is present. + * + * POP Logic: By default, we want to show the POP for 'daytime' since we are presuming that is what + * people are more interested in seeing. While EC provides a separate POP for daytime and nightime portions + * of each day, the weather module does not really allow for that view of a daily forecast. There we will + * ignore any nightime portion. There is an exception however! For the Current day, the EC data will only show + * the nightime forecast after a certain point in the afternoon. As such, we will be showing the nightime POP + * (if one exists) in that specific scenario. + * + * Accumulation Logic: Similar to POP, we want to show accumulation for 'daytime' since we presume that is what + * people are interested in seeing. While EC provides a separate accumulation for daytime and nightime portions + * of each day, the weather module does not really allow for that view of a daily forecast. There we will + * ignore any nightime portion. There is an exception however! For the Current day, the EC data will only show + * the nightime forecast after a certain point in that specific scenario. + */ setPrecipitation (weather, foreGroup, today) { if (foreGroup[today].querySelector("precipitation accumulation")) { weather.precipitationAmount = foreGroup[today].querySelector("precipitation accumulation amount").textContent * 1.0; @@ -505,9 +461,9 @@ WeatherProvider.register("envcanada", { } }, - // - // Convert the icons to a more usable name. - // + /* + * Convert the icons to a more usable name. + */ convertWeatherType (weatherType) { const weatherTypes = { "00": "day-sunny", diff --git a/modules/default/weather/providers/openmeteo.js b/modules/default/weather/providers/openmeteo.js index 6acddec763..07f17e935c 100644 --- a/modules/default/weather/providers/openmeteo.js +++ b/modules/default/weather/providers/openmeteo.js @@ -1,6 +1,7 @@ /* global WeatherProvider, WeatherObject */ -/* This class is a provider for Open-Meteo, +/* + * This class is a provider for Open-Meteo, * see https://open-meteo.com/ */ @@ -9,8 +10,11 @@ const GEOCODE_BASE = "https://api.bigdatacloud.net/data/reverse-geocode-client"; const OPEN_METEO_BASE = "https://api.open-meteo.com/v1"; WeatherProvider.register("openmeteo", { - // Set the name of the provider. - // Not strictly required, but helps for debugging. + + /* + * Set the name of the provider. + * Not strictly required, but helps for debugging. + */ providerName: "Open-Meteo", // Set the default config properties that is specific to this provider diff --git a/modules/default/weather/providers/openweathermap.js b/modules/default/weather/providers/openweathermap.js index 0999c83f0a..3f29ed5562 100644 --- a/modules/default/weather/providers/openweathermap.js +++ b/modules/default/weather/providers/openweathermap.js @@ -1,17 +1,21 @@ /* global WeatherProvider, WeatherObject */ -/* This class is a provider for Openweathermap, +/* + * This class is a provider for Openweathermap, * see https://openweathermap.org/ */ WeatherProvider.register("openweathermap", { - // Set the name of the provider. - // This isn't strictly necessary, since it will fallback to the provider identifier - // But for debugging (and future alerts) it would be nice to have the real name. + + /* + * Set the name of the provider. + * This isn't strictly necessary, since it will fallback to the provider identifier + * But for debugging (and future alerts) it would be nice to have the real name. + */ providerName: "OpenWeatherMap", // Set the default config properties that is specific to this provider defaults: { - apiVersion: "2.5", + apiVersion: "3.0", apiBase: "https://api.openweathermap.org/data/", weatherEndpoint: "", // can be "onecall", "forecast" or "weather" (for current) locationID: false, @@ -67,8 +71,11 @@ WeatherProvider.register("openweathermap", { this.fetchData(this.getUrl()) .then((data) => { if (!data) { - // Did not receive usable new data. - // Maybe this needs a better check? + + /* + * Did not receive usable new data. + * Maybe this needs a better check? + */ return; } @@ -206,8 +213,10 @@ WeatherProvider.register("openweathermap", { weather.weatherType = this.convertWeatherType(forecast.weather[0].icon); } - // the same day as before - // add values from forecast to corresponding variables + /* + * the same day as before + * add values from forecast to corresponding variables + */ minTemp.push(forecast.main.temp_min); maxTemp.push(forecast.main.temp_max); @@ -220,8 +229,10 @@ WeatherProvider.register("openweathermap", { } } - // last day - // calculate minimum/maximum temperature, specify rain amount + /* + * last day + * calculate minimum/maximum temperature, specify rain amount + */ weather.minTemperature = Math.min.apply(null, minTemp); weather.maxTemperature = Math.max.apply(null, maxTemp); weather.rain = rain; @@ -250,14 +261,18 @@ WeatherProvider.register("openweathermap", { weather.rain = 0; weather.snow = 0; - // forecast.rain not available if amount is zero - // The API always returns in millimeters + /* + * forecast.rain not available if amount is zero + * The API always returns in millimeters + */ if (forecast.hasOwnProperty("rain") && !isNaN(forecast.rain)) { weather.rain = forecast.rain; } - // forecast.snow not available if amount is zero - // The API always returns in millimeters + /* + * forecast.snow not available if amount is zero + * The API always returns in millimeters + */ if (forecast.hasOwnProperty("snow") && !isNaN(forecast.snow)) { weather.snow = forecast.snow; } @@ -402,7 +417,8 @@ WeatherProvider.register("openweathermap", { return weatherTypes.hasOwnProperty(weatherType) ? weatherTypes[weatherType] : null; }, - /* getParams(compliments) + /* + * getParams(compliments) * Generates an url with api parameters based on the config. * * return String - URL params. diff --git a/modules/default/weather/providers/pirateweather.js b/modules/default/weather/providers/pirateweather.js index dd20ccf47d..969912f4e1 100644 --- a/modules/default/weather/providers/pirateweather.js +++ b/modules/default/weather/providers/pirateweather.js @@ -1,11 +1,15 @@ /* global WeatherProvider, WeatherObject */ -/* This class is a provider for Pirate Weather, it is a replacement for Dark Sky (same api), +/* + * This class is a provider for Pirate Weather, it is a replacement for Dark Sky (same api), * see http://pirateweather.net/en/latest/ */ WeatherProvider.register("pirateweather", { - // Set the name of the provider. - // Not strictly required, but helps for debugging. + + /* + * Set the name of the provider. + * Not strictly required, but helps for debugging. + */ providerName: "pirateweather", // Set the default config properties that is specific to this provider diff --git a/modules/default/weather/providers/smhi.js b/modules/default/weather/providers/smhi.js index d7dcdf1b6f..14185c8649 100644 --- a/modules/default/weather/providers/smhi.js +++ b/modules/default/weather/providers/smhi.js @@ -1,6 +1,7 @@ /* global WeatherProvider, WeatherObject */ -/* This class is a provider for SMHI (Sweden only). +/* + * This class is a provider for SMHI (Sweden only). * Metric system is the only supported unit, * see https://www.smhi.se/ */ @@ -138,9 +139,11 @@ WeatherProvider.register("smhi", { currentWeather.weatherType = this.convertWeatherType(this.paramValue(weatherData, "Wsymb2"), currentWeather.isDayTime()); currentWeather.feelsLikeTemp = this.calculateApparentTemperature(weatherData); - // Determine the precipitation amount and category and update the - // weatherObject with it, the valuetype to use can be configured or uses - // median as default. + /* + * Determine the precipitation amount and category and update the + * weatherObject with it, the valuetype to use can be configured or uses + * median as default. + */ let precipitationValue = this.paramValue(weatherData, this.config.precipitationValue); switch (this.paramValue(weatherData, "pcat")) { // 0 = No precipitation diff --git a/modules/default/weather/providers/ukmetoffice.js b/modules/default/weather/providers/ukmetoffice.js index c2db4cda37..32c1888fca 100644 --- a/modules/default/weather/providers/ukmetoffice.js +++ b/modules/default/weather/providers/ukmetoffice.js @@ -1,12 +1,16 @@ /* global WeatherProvider, WeatherObject, WeatherUtils */ -/* This class is a provider for UK Met Office Datapoint, +/* + * This class is a provider for UK Met Office Datapoint, * see https://www.metoffice.gov.uk/ */ WeatherProvider.register("ukmetoffice", { - // Set the name of the provider. - // This isn't strictly necessary, since it will fallback to the provider identifier - // But for debugging (and future alerts) it would be nice to have the real name. + + /* + * Set the name of the provider. + * This isn't strictly necessary, since it will fallback to the provider identifier + * But for debugging (and future alerts) it would be nice to have the real name. + */ providerName: "UK Met Office", // Set the default config properties that is specific to this provider @@ -21,8 +25,11 @@ WeatherProvider.register("ukmetoffice", { this.fetchData(this.getUrl("3hourly")) .then((data) => { if (!data || !data.SiteRep || !data.SiteRep.DV || !data.SiteRep.DV.Location || !data.SiteRep.DV.Location.Period || data.SiteRep.DV.Location.Period.length === 0) { - // Did not receive usable new data. - // Maybe this needs a better check? + + /* + * Did not receive usable new data. + * Maybe this needs a better check? + */ return; } @@ -42,8 +49,11 @@ WeatherProvider.register("ukmetoffice", { this.fetchData(this.getUrl("daily")) .then((data) => { if (!data || !data.SiteRep || !data.SiteRep.DV || !data.SiteRep.DV.Location || !data.SiteRep.DV.Location.Period || data.SiteRep.DV.Location.Period.length === 0) { - // Did not receive usable new data. - // Maybe this needs a better check? + + /* + * Did not receive usable new data. + * Maybe this needs a better check? + */ return; } @@ -86,8 +96,11 @@ WeatherProvider.register("ukmetoffice", { if (periodDate.isSameOrAfter(moment.utc().startOf("day"))) { // check this is the period we want, after today the diff will be -ve if (moment().diff(periodDate, "minutes") > 0) { - // loop round the reports looking for the one we are in - // $ value specifies the time in minutes-of-the-day: 0, 180, 360,...1260 + + /* + * loop round the reports looking for the one we are in + * $ value specifies the time in minutes-of-the-day: 0, 180, 360,...1260 + */ for (const rep of period.Rep) { const p = rep.$; if (timeInMins >= p && timeInMins - 180 < p) { @@ -117,8 +130,10 @@ WeatherProvider.register("ukmetoffice", { generateWeatherObjectsFromForecast (forecasts) { const days = []; - // loop round the (5) periods getting the data - // for each period array, Day is [0], Night is [1] + /* + * loop round the (5) periods getting the data + * for each period array, Day is [0], Night is [1] + */ for (const period of forecasts.SiteRep.DV.Location.Period) { const weather = new WeatherObject(); diff --git a/modules/default/weather/providers/ukmetofficedatahub.js b/modules/default/weather/providers/ukmetofficedatahub.js index 1ca4da5c01..0a9d872c5b 100644 --- a/modules/default/weather/providers/ukmetofficedatahub.js +++ b/modules/default/weather/providers/ukmetofficedatahub.js @@ -1,6 +1,7 @@ /* global WeatherProvider, WeatherObject */ -/* This class is a provider for UK Met Office Data Hub (the replacement for their Data Point services). +/* + * This class is a provider for UK Met Office Data Hub (the replacement for their Data Point services). * For more information on Data Hub, see https://www.metoffice.gov.uk/services/data/datapoint/notifications/weather-datahub * Data available: * Hourly data for next 2 days ("hourly") - https://www.metoffice.gov.uk/binaries/content/assets/metofficegovuk/pdf/data/global-spot-data-hourly.pdf @@ -11,9 +12,8 @@ * This provider requires longitude/latitude coordinates, rather than a location ID (as with the previous Met Office provider) * Provide the following in your config.js file: * weatherProvider: "ukmetofficedatahub", - * apiBase: "https://api-metoffice.apiconnect.ibmcloud.com/metoffice/production/v0/forecasts/point/", + * apiBase: "https://data.hub.api.metoffice.gov.uk/sitespecific/v0/point/", * apiKey: "[YOUR API KEY]", - * apiSecret: "[YOUR API SECRET]", * lat: [LATITUDE (DECIMAL)], * lon: [LONGITUDE (DECIMAL)] * @@ -38,14 +38,13 @@ WeatherProvider.register("ukmetofficedatahub", { // Set the default config properties that is specific to this provider defaults: { - apiBase: "https://api-metoffice.apiconnect.ibmcloud.com/metoffice/production/v0/forecasts/point/", + apiBase: "https://data.hub.api.metoffice.gov.uk/sitespecific/v0/point/", apiKey: "", - apiSecret: "", lat: 0, lon: 0 }, - // Build URL with query strings according to DataHub API (https://metoffice.apiconnect.ibmcloud.com/metoffice/production/api) + // Build URL with query strings according to DataHub API (https://datahub.metoffice.gov.uk/docs/f/category/site-specific/type/site-specific/api-documentation#get-/point/hourly) getUrl (forecastType) { let queryStrings = "?"; queryStrings += `latitude=${this.config.lat}`; @@ -56,14 +55,15 @@ WeatherProvider.register("ukmetofficedatahub", { return this.config.apiBase + (this.config.apiBase.endsWith("/") ? "" : "/") + forecastType + queryStrings; }, - // Build the list of headers for the request - // For DataHub requests, the API key/secret are sent in the headers rather than as query strings. - // Headers defined according to Data Hub API (https://metoffice.apiconnect.ibmcloud.com/metoffice/production/api) + /* + * Build the list of headers for the request + * For DataHub requests, the API key/secret are sent in the headers rather than as query strings. + * Headers defined according to Data Hub API (https://datahub.metoffice.gov.uk/docs/f/category/site-specific/type/site-specific/api-documentation#get-/point/hourly) + */ getHeaders () { return { accept: "application/json", - "x-ibm-client-id": this.config.apiKey, - "x-ibm-client-secret": this.config.apiSecret + apikey: this.config.apiKey }; }, @@ -81,8 +81,11 @@ WeatherProvider.register("ukmetofficedatahub", { .then((data) => { // Check data is usable if (!data || !data.features || !data.features[0].properties || !data.features[0].properties.timeSeries || data.features[0].properties.timeSeries.length === 0) { - // Did not receive usable new data. - // Maybe this needs a better check? + + /* + * Did not receive usable new data. + * Maybe this needs a better check? + */ Log.error("Possibly bad current/hourly data?"); Log.error(data); return; @@ -130,15 +133,19 @@ WeatherProvider.register("ukmetofficedatahub", { currentWeather.precipitationProbability = forecastDataHours[hour].probOfPrecipitation; currentWeather.feelsLikeTemp = forecastDataHours[hour].feelsLikeTemperature; - // Pass on full details, so they can be used in custom templates - // Note the units of the supplied data when using this (see top of file) + /* + * Pass on full details, so they can be used in custom templates + * Note the units of the supplied data when using this (see top of file) + */ currentWeather.rawData = forecastDataHours[hour]; } } - // Determine the sunrise/sunset times - (still) not supplied in UK Met Office data - // Passes {longitude, latitude} to SunCalc, could pass height to, but - // SunCalc.getTimes doesn't take that into account + /* + * Determine the sunrise/sunset times - (still) not supplied in UK Met Office data + * Passes {longitude, latitude} to SunCalc, could pass height to, but + * SunCalc.getTimes doesn't take that into account + */ currentWeather.updateSunTime(this.config.lat, this.config.lon); return currentWeather; @@ -150,8 +157,11 @@ WeatherProvider.register("ukmetofficedatahub", { .then((data) => { // Check data is usable if (!data || !data.features || !data.features[0].properties || !data.features[0].properties.timeSeries || data.features[0].properties.timeSeries.length === 0) { - // Did not receive usable new data. - // Maybe this needs a better check? + + /* + * Did not receive usable new data. + * Maybe this needs a better check? + */ Log.error("Possibly bad forecast data?"); Log.error(data); return; @@ -206,8 +216,10 @@ WeatherProvider.register("ukmetofficedatahub", { forecastWeather.snow = forecastDataDays[day].dayProbabilityOfSnow; forecastWeather.feelsLikeTemp = forecastDataDays[day].dayMaxFeelsLikeTemp; - // Pass on full details, so they can be used in custom templates - // Note the units of the supplied data when using this (see top of file) + /* + * Pass on full details, so they can be used in custom templates + * Note the units of the supplied data when using this (see top of file) + */ forecastWeather.rawData = forecastDataDays[day]; dailyForecasts.push(forecastWeather); @@ -222,9 +234,11 @@ WeatherProvider.register("ukmetofficedatahub", { this.fetchedLocationName = name; }, - // Match the Met Office "significant weather code" to a weathericons.css icon - // Use: https://metoffice.apiconnect.ibmcloud.com/metoffice/production/node/264 - // and: https://erikflowers.github.io/weather-icons/ + /* + * Match the Met Office "significant weather code" to a weathericons.css icon + * Use: https://metoffice.apiconnect.ibmcloud.com/metoffice/production/node/264 + * and: https://erikflowers.github.io/weather-icons/ + */ convertWeatherType (weatherType) { const weatherTypes = { 0: "night-clear", diff --git a/modules/default/weather/providers/weatherbit.js b/modules/default/weather/providers/weatherbit.js index 7c01f5d6be..a36b92bd86 100644 --- a/modules/default/weather/providers/weatherbit.js +++ b/modules/default/weather/providers/weatherbit.js @@ -1,11 +1,15 @@ /* global WeatherProvider, WeatherObject */ -/* This class is a provider for Weatherbit, +/* + * This class is a provider for Weatherbit, * see https://www.weatherbit.io/ */ WeatherProvider.register("weatherbit", { - // Set the name of the provider. - // Not strictly required, but helps for debugging. + + /* + * Set the name of the provider. + * Not strictly required, but helps for debugging. + */ providerName: "Weatherbit", // Set the default config properties that is specific to this provider diff --git a/modules/default/weather/providers/weatherflow.js b/modules/default/weather/providers/weatherflow.js index 54066d7b40..6ffd5b669b 100644 --- a/modules/default/weather/providers/weatherflow.js +++ b/modules/default/weather/providers/weatherflow.js @@ -1,11 +1,15 @@ /* global WeatherProvider, WeatherObject, WeatherUtils */ -/* This class is a provider for Weatherflow. +/* + * This class is a provider for Weatherflow. * Note that the Weatherflow API does not provide snowfall. */ WeatherProvider.register("weatherflow", { - // Set the name of the provider. - // Not strictly required, but helps for debugging + + /* + * Set the name of the provider. + * Not strictly required, but helps for debugging + */ providerName: "WeatherFlow", // Set the default config properties that is specific to this provider diff --git a/modules/default/weather/providers/weathergov.js b/modules/default/weather/providers/weathergov.js index 8a65478465..d8fa621a85 100644 --- a/modules/default/weather/providers/weathergov.js +++ b/modules/default/weather/providers/weathergov.js @@ -1,6 +1,7 @@ /* global WeatherProvider, WeatherObject, WeatherUtils */ -/* Provider: weather.gov +/* + * Provider: weather.gov * https://weather-gov.github.io/api/general-faqs * * This class is a provider for weather.gov. @@ -9,9 +10,12 @@ */ WeatherProvider.register("weathergov", { - // Set the name of the provider. - // This isn't strictly necessary, since it will fallback to the provider identifier - // But for debugging (and future alerts) it would be nice to have the real name. + + /* + * Set the name of the provider. + * This isn't strictly necessary, since it will fallback to the provider identifier + * But for debugging (and future alerts) it would be nice to have the real name. + */ providerName: "Weather.gov", // Set the default config properties that is specific to this provider @@ -98,8 +102,11 @@ WeatherProvider.register("weathergov", { this.fetchData(this.forecastHourlyURL) .then((data) => { if (!data) { - // Did not receive usable new data. - // Maybe this needs a better check? + + /* + * Did not receive usable new data. + * Maybe this needs a better check? + */ return; } const hourly = this.generateWeatherObjectsFromHourly(data.properties.periods); @@ -282,14 +289,18 @@ WeatherProvider.register("weathergov", { weather.weatherType = this.convertWeatherType(forecast.shortForecast, forecast.isDaytime); } - // the same day as before - // add values from forecast to corresponding variables + /* + * the same day as before + * add values from forecast to corresponding variables + */ minTemp.push(forecast.temperature); maxTemp.push(forecast.temperature); } - // last day - // calculate minimum/maximum temperature + /* + * last day + * calculate minimum/maximum temperature + */ weather.minTemperature = Math.min.apply(null, minTemp); weather.maxTemperature = Math.max.apply(null, maxTemp); @@ -302,8 +313,11 @@ WeatherProvider.register("weathergov", { * Convert the icons to a more usable name. */ convertWeatherType (weatherType, isDaytime) { - //https://w1.weather.gov/xml/current_obs/weather.php - // There are way too many types to create, so lets just look for certain strings + + /* + * https://w1.weather.gov/xml/current_obs/weather.php + * There are way too many types to create, so lets just look for certain strings + */ if (weatherType.includes("Cloudy") || weatherType.includes("Partly")) { if (isDaytime) { diff --git a/modules/default/weather/providers/yr.js b/modules/default/weather/providers/yr.js index 35493a1653..f305a1c09d 100644 --- a/modules/default/weather/providers/yr.js +++ b/modules/default/weather/providers/yr.js @@ -1,6 +1,7 @@ /* global WeatherProvider, WeatherObject */ -/* This class is a provider for Yr.no, a norwegian weather service. +/* + * This class is a provider for Yr.no, a norwegian weather service. * Terms of service: https://developer.yr.no/doc/TermsOfService/ */ WeatherProvider.register("yr", { @@ -67,8 +68,11 @@ WeatherProvider.register("yr", { getWeatherData () { return new Promise((resolve, reject) => { - // If a user has several Yr-modules, for instance one current and one forecast, the API calls must be synchronized across classes. - // This is to avoid multiple similar calls to the API. + + /* + * If a user has several Yr-modules, for instance one current and one forecast, the API calls must be synchronized across classes. + * This is to avoid multiple similar calls to the API. + */ let shouldWait = localStorage.getItem("yrIsFetchingWeatherData"); if (shouldWait) { const checkForGo = setInterval(function () { @@ -201,8 +205,11 @@ WeatherProvider.register("yr", { }, getStellarData () { - // If a user has several Yr-modules, for instance one current and one forecast, the API calls must be synchronized across classes. - // This is to avoid multiple similar calls to the API. + + /* + * If a user has several Yr-modules, for instance one current and one forecast, the API calls must be synchronized across classes. + * This is to avoid multiple similar calls to the API. + */ return new Promise((resolve, reject) => { let shouldWait = localStorage.getItem("yrIsFetchingStellarData"); if (shouldWait) { diff --git a/modules/default/weather/weather.js b/modules/default/weather/weather.js index 224aba0647..369a720101 100644 --- a/modules/default/weather/weather.js +++ b/modules/default/weather/weather.js @@ -170,12 +170,19 @@ Module.register("weather", { } const notificationPayload = { - currentWeather: this.weatherProvider?.currentWeatherObject?.simpleClone() ?? null, - forecastArray: this.weatherProvider?.weatherForecastArray?.map((ar) => ar.simpleClone()) ?? [], - hourlyArray: this.weatherProvider?.weatherHourlyArray?.map((ar) => ar.simpleClone()) ?? [], + currentWeather: this.config.units === "imperial" + ? WeatherUtils.convertWeatherObjectToImperial(this.weatherProvider?.currentWeatherObject?.simpleClone()) ?? null + : this.weatherProvider?.currentWeatherObject?.simpleClone() ?? null, + forecastArray: this.config.units === "imperial" + ? this.weatherProvider?.weatherForecastArray?.map((ar) => WeatherUtils.convertWeatherObjectToImperial(ar.simpleClone())) ?? [] + : this.weatherProvider?.weatherForecastArray?.map((ar) => ar.simpleClone()) ?? [], + hourlyArray: this.config.units === "imperial" + ? this.weatherProvider?.weatherHourlyArray?.map((ar) => WeatherUtils.convertWeatherObjectToImperial(ar.simpleClone())) ?? [] + : this.weatherProvider?.weatherHourlyArray?.map((ar) => ar.simpleClone()) ?? [], locationName: this.weatherProvider?.fetchedLocationName, providerName: this.weatherProvider.providerName }; + this.sendNotification("WEATHER_UPDATED", notificationPayload); }, diff --git a/modules/default/weather/weatherutils.js b/modules/default/weather/weatherutils.js index e75baf20f7..4d6ce45bf9 100644 --- a/modules/default/weather/weatherutils.js +++ b/modules/default/weather/weatherutils.js @@ -30,8 +30,7 @@ const WeatherUtils = { let convertedValue = value; let conversionUnit = valueUnit; if (outputUnit === "imperial") { - if (valueUnit && valueUnit.toLowerCase() === "cm") convertedValue = convertedValue * 0.3937007874; - else convertedValue = convertedValue * 0.03937007874; + convertedValue = this.convertPrecipitationToInch(value, valueUnit); conversionUnit = "in"; } else { conversionUnit = valueUnit ? valueUnit : "mm"; @@ -40,6 +39,17 @@ const WeatherUtils = { return `${convertedValue.toFixed(2)} ${conversionUnit}`; }, + /** + * Convert precipitation value into inch + * @param {number} value the precipitation value for convert + * @param {string} valueUnit can be 'mm' or 'cm' + * @returns {number} the converted precipitation value + */ + convertPrecipitationToInch (value, valueUnit) { + if (valueUnit && valueUnit.toLowerCase() === "cm") return value * 0.3937007874; + else return value * 0.03937007874; + }, + /** * Convert temp (from degrees C) into imperial or metric unit depending on * your config @@ -129,6 +139,28 @@ const WeatherUtils = { } return ((feelsLike - 32) * 5) / 9; + }, + + /** + * Converts the Weather Object's values into imperial unit + * @param {object} weatherObject the weather object + * @returns {object} the weather object with converted values to imperial + */ + convertWeatherObjectToImperial (weatherObject) { + if (!weatherObject || Object.keys(weatherObject).length === 0) return null; + + let imperialWeatherObject = { ...weatherObject }; + + if (imperialWeatherObject) { + if (imperialWeatherObject.feelsLikeTemp) imperialWeatherObject.feelsLikeTemp = this.convertTemp(imperialWeatherObject.feelsLikeTemp, "imperial"); + if (imperialWeatherObject.maxTemperature) imperialWeatherObject.maxTemperature = this.convertTemp(imperialWeatherObject.maxTemperature, "imperial"); + if (imperialWeatherObject.minTemperature) imperialWeatherObject.minTemperature = this.convertTemp(imperialWeatherObject.minTemperature, "imperial"); + if (imperialWeatherObject.precipitationAmount) imperialWeatherObject.precipitationAmount = this.convertPrecipitationToInch(imperialWeatherObject.precipitationAmount, imperialWeatherObject.precipitationUnits); + if (imperialWeatherObject.temperature) imperialWeatherObject.temperature = this.convertTemp(imperialWeatherObject.temperature, "imperial"); + if (imperialWeatherObject.windSpeed) imperialWeatherObject.windSpeed = this.convertWind(imperialWeatherObject.windSpeed, "imperial"); + } + + return imperialWeatherObject; } }; diff --git a/package-lock.json b/package-lock.json index 5ed883c35e..e79a681f1a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,21 +1,21 @@ { "name": "magicmirror", - "version": "2.28.0", + "version": "2.29.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "magicmirror", - "version": "2.28.0", + "version": "2.29.0", "hasInstallScript": true, "license": "MIT", "dependencies": { - "ajv": "^8.16.0", - "ansis": "^3.2.0", + "ajv": "^8.17.1", + "ansis": "^3.3.2", "console-stamp": "^3.1.2", "envsub": "^4.1.0", - "eslint": "^8.57.0", - "express": "^4.19.2", + "eslint": "^9.11.1", + "express": "^4.21.0", "express-ipfilter": "^1.3.2", "feedme": "^2.0.2", "helmet": "^7.1.0", @@ -23,38 +23,45 @@ "iconv-lite": "^0.6.3", "module-alias": "^2.2.3", "moment": "^2.30.1", - "node-ical": "^0.18.0", - "pm2": "^5.4.1", - "socket.io": "^4.7.5", + "node-ical": "0.18.0", + "pm2": "^5.4.2", + "socket.io": "^4.8.0", "suncalc": "^1.9.0", - "systeminformation": "^5.22.11" + "systeminformation": "^5.23.5" }, "devDependencies": { - "@stylistic/eslint-plugin": "^1.8.1", - "eslint-plugin-import": "^2.29.1", - "eslint-plugin-jest": "^28.6.0", - "eslint-plugin-jsdoc": "^48.5.0", - "eslint-plugin-package-json": "^0.15.0", - "eslint-plugin-unicorn": "^54.0.0", + "@eslint/js": "^9.11.1", + "@stylistic/eslint-plugin": "^2.8.0", + "cspell": "^8.14.4", + "eslint-plugin-jest": "^28.8.3", + "eslint-plugin-jsdoc": "^50.3.0", + "eslint-plugin-package-json": "^0.15.3", "express-basic-auth": "^1.2.1", - "husky": "^9.0.11", + "husky": "^9.1.6", "jest": "^29.7.0", - "jsdom": "^24.1.0", - "lint-staged": "^15.2.7", - "playwright": "^1.45.0", - "prettier": "^3.3.2", - "sinon": "^18.0.0", - "stylelint": "^16.6.1", + "jsdom": "^25.0.1", + "lint-staged": "^15.2.10", + "playwright": "^1.47.2", + "prettier": "^3.3.3", + "sinon": "^19.0.2", + "stylelint": "^16.9.0", "stylelint-config-standard": "^36.0.1", - "stylelint-prettier": "^5.0.0" + "stylelint-prettier": "^5.0.2" }, "engines": { - "node": ">=20" + "node": ">=20.9.0 <21 || 22" }, "optionalDependencies": { - "electron": "^31.1.0" + "electron": "^31.6.0" } }, + "node_modules/@altano/repository-tools": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@altano/repository-tools/-/repository-tools-0.1.1.tgz", + "integrity": "sha512-5vbUs2A98CC3g1AlOBdkBE0BMukkLjLIsMHAtuxg6Pt9dQXxYWdLKOf66v6c/vIqtNcgTMv0oGtddLdMuH9X6w==", + "dev": true, + "license": "ISC" + }, "node_modules/@ampproject/remapping": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", @@ -84,9 +91,9 @@ } }, "node_modules/@babel/compat-data": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.24.7.tgz", - "integrity": "sha512-qJzAIcv03PyaWqxRgO4mSU3lihncDT296vnyuE2O8uA4w3UHWI4S3hgeZd1L8W1Bft40w9JxJ2b412iDUFFRhw==", + "version": "7.25.4", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.25.4.tgz", + "integrity": "sha512-+LGRog6RAsCJrrrg/IO6LGmpphNe5DiK30dGjCoxxeGv49B10/3XYGxPsAwrDlMFcFEvdAUavDT8r9k/hSyQqQ==", "dev": true, "license": "MIT", "engines": { @@ -94,22 +101,22 @@ } }, "node_modules/@babel/core": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.24.7.tgz", - "integrity": "sha512-nykK+LEK86ahTkX/3TgauT0ikKoNCfKHEaZYTUVupJdTLzGNvrblu4u6fa7DhZONAltdf8e662t/abY8idrd/g==", + "version": "7.25.2", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.25.2.tgz", + "integrity": "sha512-BBt3opiCOxUr9euZ5/ro/Xv8/V7yJ5bjYMqG/C1YAo8MIKAnumZalCN+msbci3Pigy4lIQfPUpfMM27HMGaYEA==", "dev": true, "license": "MIT", "dependencies": { "@ampproject/remapping": "^2.2.0", "@babel/code-frame": "^7.24.7", - "@babel/generator": "^7.24.7", - "@babel/helper-compilation-targets": "^7.24.7", - "@babel/helper-module-transforms": "^7.24.7", - "@babel/helpers": "^7.24.7", - "@babel/parser": "^7.24.7", - "@babel/template": "^7.24.7", - "@babel/traverse": "^7.24.7", - "@babel/types": "^7.24.7", + "@babel/generator": "^7.25.0", + "@babel/helper-compilation-targets": "^7.25.2", + "@babel/helper-module-transforms": "^7.25.2", + "@babel/helpers": "^7.25.0", + "@babel/parser": "^7.25.0", + "@babel/template": "^7.25.0", + "@babel/traverse": "^7.25.2", + "@babel/types": "^7.25.2", "convert-source-map": "^2.0.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", @@ -135,13 +142,13 @@ } }, "node_modules/@babel/generator": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.24.7.tgz", - "integrity": "sha512-oipXieGC3i45Y1A41t4tAqpnEZWgB/lC6Ehh6+rOviR5XWpTtMmLN+fGjz9vOiNRt0p6RtO6DtD0pdU3vpqdSA==", + "version": "7.25.6", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.25.6.tgz", + "integrity": "sha512-VPC82gr1seXOpkjAAKoLhP50vx4vGNlF4msF64dSFq1P8RfB+QAuJWGHPXXPc8QyfVWwwB/TNNU4+ayZmHNbZw==", "dev": true, "license": "MIT", "dependencies": { - "@babel/types": "^7.24.7", + "@babel/types": "^7.25.6", "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.25", "jsesc": "^2.5.1" @@ -150,29 +157,16 @@ "node": ">=6.9.0" } }, - "node_modules/@babel/generator/node_modules/jsesc": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", - "dev": true, - "license": "MIT", - "bin": { - "jsesc": "bin/jsesc" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/@babel/helper-compilation-targets": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.24.7.tgz", - "integrity": "sha512-ctSdRHBi20qWOfy27RUb4Fhp07KSJ3sXcuSvTrXrc4aG8NSYDo1ici3Vhg9bg69y5bj0Mr1lh0aeEgTvc12rMg==", + "version": "7.25.2", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.25.2.tgz", + "integrity": "sha512-U2U5LsSaZ7TAt3cfaymQ8WHh0pxvdHoEk6HVpaexxixjyEquMh0L0YNJNM6CTGKMXV1iksi0iZkGw4AcFkPaaw==", "dev": true, "license": "MIT", "dependencies": { - "@babel/compat-data": "^7.24.7", - "@babel/helper-validator-option": "^7.24.7", - "browserslist": "^4.22.2", + "@babel/compat-data": "^7.25.2", + "@babel/helper-validator-option": "^7.24.8", + "browserslist": "^4.23.1", "lru-cache": "^5.1.1", "semver": "^6.3.1" }, @@ -190,46 +184,6 @@ "semver": "bin/semver.js" } }, - "node_modules/@babel/helper-environment-visitor": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.24.7.tgz", - "integrity": "sha512-DoiN84+4Gnd0ncbBOM9AZENV4a5ZiL39HYMyZJGZ/AZEykHYdJw0wW3kdcsh9/Kn+BRXHLkkklZ51ecPKmI1CQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/types": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-function-name": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.24.7.tgz", - "integrity": "sha512-FyoJTsj/PEUWu1/TYRiXTIHc8lbw+TDYkZuoE43opPS5TrI7MyONBE1oNvfguEXAD9yhQRrVBnXdXzSLQl9XnA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/template": "^7.24.7", - "@babel/types": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-hoist-variables": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.24.7.tgz", - "integrity": "sha512-MJJwhkoGy5c4ehfoRyrJ/owKeMl19U54h27YYftT0o2teQ3FJ3nQUf/I3LlJsX4l3qlw7WRXUmiyajvHXoTubQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/types": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, "node_modules/@babel/helper-module-imports": { "version": "7.24.7", "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.24.7.tgz", @@ -245,17 +199,16 @@ } }, "node_modules/@babel/helper-module-transforms": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.24.7.tgz", - "integrity": "sha512-1fuJEwIrp+97rM4RWdO+qrRsZlAeL1lQJoPqtCYWv0NL115XM93hIH4CSRln2w52SqvmY5hqdtauB6QFCDiZNQ==", + "version": "7.25.2", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.25.2.tgz", + "integrity": "sha512-BjyRAbix6j/wv83ftcVJmBt72QtHI56C7JXZoG2xATiLpmoC7dpd8WnkikExHDVPpi/3qCmO6WY1EaXOluiecQ==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-environment-visitor": "^7.24.7", "@babel/helper-module-imports": "^7.24.7", "@babel/helper-simple-access": "^7.24.7", - "@babel/helper-split-export-declaration": "^7.24.7", - "@babel/helper-validator-identifier": "^7.24.7" + "@babel/helper-validator-identifier": "^7.24.7", + "@babel/traverse": "^7.25.2" }, "engines": { "node": ">=6.9.0" @@ -265,9 +218,9 @@ } }, "node_modules/@babel/helper-plugin-utils": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.7.tgz", - "integrity": "sha512-Rq76wjt7yz9AAc1KnlRKNAi/dMSVWgDRx43FHoJEbcYU6xOWaE2dVPwcdTukJrjxS65GITyfbvEYHvkirZ6uEg==", + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.8.tgz", + "integrity": "sha512-FFWx5142D8h2Mgr/iPVGH5G7w6jDn4jUSpZTyDnQO0Yn7Ks2Kuz6Pci8H6MPCoUJegd/UZQ3tAvfLCxQSnWWwg==", "dev": true, "license": "MIT", "engines": { @@ -288,23 +241,10 @@ "node": ">=6.9.0" } }, - "node_modules/@babel/helper-split-export-declaration": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.24.7.tgz", - "integrity": "sha512-oy5V7pD+UvfkEATUKvIjvIAH/xCzfsFVw7ygW2SI6NClZzquT+mwdTfgfdbUiceh6iQO0CHtCPsyze/MZ2YbAA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/types": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, "node_modules/@babel/helper-string-parser": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.7.tgz", - "integrity": "sha512-7MbVt6xrwFQbunH2DNQsAP5sTGxfqQtErvBIvIMi6EQnbgUOuVYanvREcmFrOPhoXBrTtjhhP+lW+o5UfK+tDg==", + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.8.tgz", + "integrity": "sha512-pO9KhhRcuUyGnJWwyEgnRJTSIZHiT+vMD0kPeD+so0l7mxkMT19g3pjY9GTnHySck/hDzq+dtW/4VgnMkippsQ==", "dev": true, "license": "MIT", "engines": { @@ -322,9 +262,9 @@ } }, "node_modules/@babel/helper-validator-option": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.24.7.tgz", - "integrity": "sha512-yy1/KvjhV/ZCL+SM7hBrvnZJ3ZuT9OuZgIJAGpPEToANvc3iM6iDvBnRjtElWibHU6n8/LPR/EjX9EtIEYO3pw==", + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.24.8.tgz", + "integrity": "sha512-xb8t9tD1MHLungh/AIoWYN+gVHaB9kwlu8gffXGSt3FFEIT7RjS+xWbc2vUD1UTZdIpKj/ab3rdqJ7ufngyi2Q==", "dev": true, "license": "MIT", "engines": { @@ -332,14 +272,14 @@ } }, "node_modules/@babel/helpers": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.24.7.tgz", - "integrity": "sha512-NlmJJtvcw72yRJRcnCmGvSi+3jDEg8qFu3z0AFoymmzLx5ERVWyzd9kVXr7Th9/8yIJi2Zc6av4Tqz3wFs8QWg==", + "version": "7.25.6", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.25.6.tgz", + "integrity": "sha512-Xg0tn4HcfTijTwfDwYlvVCl43V6h4KyVVX2aEm4qdO/PC6L2YvzLHFdmxhoeSA3eslcE6+ZVXHgWwopXYLNq4Q==", "dev": true, "license": "MIT", "dependencies": { - "@babel/template": "^7.24.7", - "@babel/types": "^7.24.7" + "@babel/template": "^7.25.0", + "@babel/types": "^7.25.6" }, "engines": { "node": ">=6.9.0" @@ -440,11 +380,14 @@ } }, "node_modules/@babel/parser": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.7.tgz", - "integrity": "sha512-9uUYRm6OqQrCqQdG1iCBwBPZgN8ciDBro2nIOFaiRz1/BCxaI7CNvQbDHvsArAC7Tw9Hda/B3U+6ui9u4HWXPw==", + "version": "7.25.6", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.25.6.tgz", + "integrity": "sha512-trGdfBdbD0l1ZPmcJ83eNxB9rbEax4ALFTF7fN386TMYbeCQbyme5cOEXQhbGXKebwGaB/J52w1mrklMcbgy6Q==", "dev": true, "license": "MIT", + "dependencies": { + "@babel/types": "^7.25.6" + }, "bin": { "parser": "bin/babel-parser.js" }, @@ -491,6 +434,38 @@ "@babel/core": "^7.0.0-0" } }, + "node_modules/@babel/plugin-syntax-class-static-block": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz", + "integrity": "sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-attributes": { + "version": "7.25.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.25.6.tgz", + "integrity": "sha512-sXaDXaJN9SNLymBdlWFA+bjzBhFD617ZaFiY13dGt7TVslVvVgA6fkZOP7Ki3IGElC45lwHdOTrCtKZGVAWeLQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.8" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, "node_modules/@babel/plugin-syntax-import-meta": { "version": "7.10.4", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", @@ -611,6 +586,22 @@ "@babel/core": "^7.0.0-0" } }, + "node_modules/@babel/plugin-syntax-private-property-in-object": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz", + "integrity": "sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, "node_modules/@babel/plugin-syntax-top-level-await": { "version": "7.14.5", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", @@ -628,13 +619,13 @@ } }, "node_modules/@babel/plugin-syntax-typescript": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.24.7.tgz", - "integrity": "sha512-c/+fVeJBB0FeKsFvwytYiUD+LBvhHjGSI0g446PRGdSVGZLRNArBUno2PETbAly3tpiNAQR5XaZ+JslxkotsbA==", + "version": "7.25.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.25.4.tgz", + "integrity": "sha512-uMOCoHVU52BsSWxPOMVv5qKRdeSlPuImUCB2dlPuBSU+W2/ROE7/Zg8F2Kepbk+8yBa68LlRKxO+xgEVWorsDg==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-plugin-utils": "^7.24.8" }, "engines": { "node": ">=6.9.0" @@ -644,35 +635,32 @@ } }, "node_modules/@babel/template": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.24.7.tgz", - "integrity": "sha512-jYqfPrU9JTF0PmPy1tLYHW4Mp4KlgxJD9l2nP9fD6yT/ICi554DmrWBAEYpIelzjHf1msDP3PxJIRt/nFNfBig==", + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.25.0.tgz", + "integrity": "sha512-aOOgh1/5XzKvg1jvVz7AVrx2piJ2XBi227DHmbY6y+bM9H2FlN+IfecYu4Xl0cNiiVejlsCri89LUsbj8vJD9Q==", "dev": true, "license": "MIT", "dependencies": { "@babel/code-frame": "^7.24.7", - "@babel/parser": "^7.24.7", - "@babel/types": "^7.24.7" + "@babel/parser": "^7.25.0", + "@babel/types": "^7.25.0" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/traverse": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.24.7.tgz", - "integrity": "sha512-yb65Ed5S/QAcewNPh0nZczy9JdYXkkAbIsEo+P7BE7yO3txAY30Y/oPa3QkQ5It3xVG2kpKMg9MsdxZaO31uKA==", + "version": "7.25.6", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.25.6.tgz", + "integrity": "sha512-9Vrcx5ZW6UwK5tvqsj0nGpp/XzqthkT0dqIc9g1AdtygFToNtTF67XzYS//dm+SAK9cp3B9R4ZO/46p63SCjlQ==", "dev": true, "license": "MIT", "dependencies": { "@babel/code-frame": "^7.24.7", - "@babel/generator": "^7.24.7", - "@babel/helper-environment-visitor": "^7.24.7", - "@babel/helper-function-name": "^7.24.7", - "@babel/helper-hoist-variables": "^7.24.7", - "@babel/helper-split-export-declaration": "^7.24.7", - "@babel/parser": "^7.24.7", - "@babel/types": "^7.24.7", + "@babel/generator": "^7.25.6", + "@babel/parser": "^7.25.6", + "@babel/template": "^7.25.0", + "@babel/types": "^7.25.6", "debug": "^4.3.1", "globals": "^11.1.0" }, @@ -691,13 +679,13 @@ } }, "node_modules/@babel/types": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.7.tgz", - "integrity": "sha512-XEFXSlxiG5td2EJRe8vOmRbaXVgfcBlszKujvVmWIK/UpywWljQCfzAv3RQCGujWQ1RD4YYWEAqDXfuJiy8f5Q==", + "version": "7.25.6", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.25.6.tgz", + "integrity": "sha512-/l42B1qxpG6RdfYf343Uw1vmDjeNhneUXtzhojE7pDgfpEypmRhI6j1kr17XCVv4Cgl9HdAiQY2x0GwKm7rWCw==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-string-parser": "^7.24.7", + "@babel/helper-string-parser": "^7.24.8", "@babel/helper-validator-identifier": "^7.24.7", "to-fast-properties": "^2.0.0" }, @@ -712,213 +700,808 @@ "dev": true, "license": "MIT" }, - "node_modules/@csstools/css-parser-algorithms": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/@csstools/css-parser-algorithms/-/css-parser-algorithms-2.6.3.tgz", - "integrity": "sha512-xI/tL2zxzEbESvnSxwFgwvy5HS00oCXxL4MLs6HUiDcYfwowsoQaABKxUElp1ARITrINzBnsECOc1q0eg2GOrA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "license": "MIT", - "engines": { - "node": "^14 || ^16 || >=18" + "node_modules/@cspell/cspell-bundled-dicts": { + "version": "8.14.4", + "resolved": "https://registry.npmjs.org/@cspell/cspell-bundled-dicts/-/cspell-bundled-dicts-8.14.4.tgz", + "integrity": "sha512-JHZOpCJzN6fPBapBOvoeMxZbr0ZA11ZAkwcqM4w0lKoacbi6TwK8GIYf66hHvwLmMeav75TNXWE6aPTvBLMMqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@cspell/dict-ada": "^4.0.2", + "@cspell/dict-aws": "^4.0.4", + "@cspell/dict-bash": "^4.1.4", + "@cspell/dict-companies": "^3.1.4", + "@cspell/dict-cpp": "^5.1.16", + "@cspell/dict-cryptocurrencies": "^5.0.0", + "@cspell/dict-csharp": "^4.0.2", + "@cspell/dict-css": "^4.0.13", + "@cspell/dict-dart": "^2.2.1", + "@cspell/dict-django": "^4.1.0", + "@cspell/dict-docker": "^1.1.7", + "@cspell/dict-dotnet": "^5.0.5", + "@cspell/dict-elixir": "^4.0.3", + "@cspell/dict-en_us": "^4.3.23", + "@cspell/dict-en-common-misspellings": "^2.0.4", + "@cspell/dict-en-gb": "1.1.33", + "@cspell/dict-filetypes": "^3.0.4", + "@cspell/dict-flutter": "^1.0.0", + "@cspell/dict-fonts": "^4.0.0", + "@cspell/dict-fsharp": "^1.0.1", + "@cspell/dict-fullstack": "^3.2.0", + "@cspell/dict-gaming-terms": "^1.0.5", + "@cspell/dict-git": "^3.0.0", + "@cspell/dict-golang": "^6.0.12", + "@cspell/dict-google": "^1.0.1", + "@cspell/dict-haskell": "^4.0.1", + "@cspell/dict-html": "^4.0.5", + "@cspell/dict-html-symbol-entities": "^4.0.0", + "@cspell/dict-java": "^5.0.7", + "@cspell/dict-julia": "^1.0.1", + "@cspell/dict-k8s": "^1.0.6", + "@cspell/dict-latex": "^4.0.0", + "@cspell/dict-lorem-ipsum": "^4.0.0", + "@cspell/dict-lua": "^4.0.3", + "@cspell/dict-makefile": "^1.0.0", + "@cspell/dict-monkeyc": "^1.0.6", + "@cspell/dict-node": "^5.0.1", + "@cspell/dict-npm": "^5.1.4", + "@cspell/dict-php": "^4.0.10", + "@cspell/dict-powershell": "^5.0.8", + "@cspell/dict-public-licenses": "^2.0.8", + "@cspell/dict-python": "^4.2.6", + "@cspell/dict-r": "^2.0.1", + "@cspell/dict-ruby": "^5.0.3", + "@cspell/dict-rust": "^4.0.5", + "@cspell/dict-scala": "^5.0.3", + "@cspell/dict-software-terms": "^4.1.3", + "@cspell/dict-sql": "^2.1.5", + "@cspell/dict-svelte": "^1.0.2", + "@cspell/dict-swift": "^2.0.1", + "@cspell/dict-terraform": "^1.0.1", + "@cspell/dict-typescript": "^3.1.6", + "@cspell/dict-vue": "^3.0.0" }, - "peerDependencies": { - "@csstools/css-tokenizer": "^2.3.1" - } - }, - "node_modules/@csstools/css-tokenizer": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/@csstools/css-tokenizer/-/css-tokenizer-2.3.1.tgz", - "integrity": "sha512-iMNHTyxLbBlWIfGtabT157LH9DUx9X8+Y3oymFEuMj8HNc+rpE3dPFGFgHjpKfjeFDjLjYIAIhXPGvS2lKxL9g==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "license": "MIT", "engines": { - "node": "^14 || ^16 || >=18" + "node": ">=18" } }, - "node_modules/@csstools/media-query-list-parser": { - "version": "2.1.11", - "resolved": "https://registry.npmjs.org/@csstools/media-query-list-parser/-/media-query-list-parser-2.1.11.tgz", - "integrity": "sha512-uox5MVhvNHqitPP+SynrB1o8oPxPMt2JLgp5ghJOWf54WGQ5OKu47efne49r1SWqs3wRP8xSWjnO9MBKxhB1dA==", + "node_modules/@cspell/cspell-json-reporter": { + "version": "8.14.4", + "resolved": "https://registry.npmjs.org/@cspell/cspell-json-reporter/-/cspell-json-reporter-8.14.4.tgz", + "integrity": "sha512-gJ6tQbGCNLyHS2iIimMg77as5MMAFv3sxU7W6tjLlZp8htiNZS7fS976g24WbT/hscsTT9Dd0sNHkpo8K3nvVw==", "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], "license": "MIT", - "engines": { - "node": "^14 || ^16 || >=18" + "dependencies": { + "@cspell/cspell-types": "8.14.4" }, - "peerDependencies": { - "@csstools/css-parser-algorithms": "^2.6.3", - "@csstools/css-tokenizer": "^2.3.1" - } - }, - "node_modules/@csstools/selector-specificity": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@csstools/selector-specificity/-/selector-specificity-3.1.1.tgz", - "integrity": "sha512-a7cxGcJ2wIlMFLlh8z2ONm+715QkPHiyJcxwQlKOz/03GPw1COpfhcmC9wm4xlZfp//jWHNNMwzjtqHXVWU9KA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "license": "MIT-0", "engines": { - "node": "^14 || ^16 || >=18" - }, - "peerDependencies": { - "postcss-selector-parser": "^6.0.13" + "node": ">=18" } }, - "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==", + "node_modules/@cspell/cspell-pipe": { + "version": "8.14.4", + "resolved": "https://registry.npmjs.org/@cspell/cspell-pipe/-/cspell-pipe-8.14.4.tgz", + "integrity": "sha512-CLLdouqfrQ4rqdQdPu0Oo+HHCU/oLYoEsK1nNPb28cZTFxnn0cuSPKB6AMPBJmMwdfJ6fMD0BCKNbEe1UNLHcw==", "dev": true, "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/@electron/get": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@electron/get/-/get-2.0.3.tgz", - "integrity": "sha512-Qkzpg2s9GnVV2I2BjRksUi43U5e6+zaQMcjoJy0C+C5oxaKl+fmckGDQFtRpZpZV0NQekuZZ+tGz7EA9TVnQtQ==", - "license": "MIT", - "optional": true, - "dependencies": { - "debug": "^4.1.1", - "env-paths": "^2.2.0", - "fs-extra": "^8.1.0", - "got": "^11.8.5", - "progress": "^2.0.3", - "semver": "^6.2.0", - "sumchecker": "^3.0.1" - }, "engines": { - "node": ">=12" - }, - "optionalDependencies": { - "global-agent": "^3.0.0" - } - }, - "node_modules/@electron/get/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "license": "ISC", - "optional": true, - "bin": { - "semver": "bin/semver.js" + "node": ">=18" } }, - "node_modules/@es-joy/jsdoccomment": { - "version": "0.43.1", - "resolved": "https://registry.npmjs.org/@es-joy/jsdoccomment/-/jsdoccomment-0.43.1.tgz", - "integrity": "sha512-I238eDtOolvCuvtxrnqtlBaw0BwdQuYqK7eA6XIonicMdOOOb75mqdIzkGDUbS04+1Di007rgm9snFRNeVrOog==", + "node_modules/@cspell/cspell-resolver": { + "version": "8.14.4", + "resolved": "https://registry.npmjs.org/@cspell/cspell-resolver/-/cspell-resolver-8.14.4.tgz", + "integrity": "sha512-s3uZyymJ04yn8+zlTp7Pt1WRSlAel6XVo+iZRxls3LSvIP819KK64DoyjCD2Uon0Vg9P/K7aAPt8GcxDcnJtgA==", "dev": true, "license": "MIT", "dependencies": { - "@types/eslint": "^8.56.5", - "@types/estree": "^1.0.5", - "@typescript-eslint/types": "^7.2.0", - "comment-parser": "1.4.1", - "esquery": "^1.5.0", - "jsdoc-type-pratt-parser": "~4.0.0" + "global-directory": "^4.0.1" }, "engines": { - "node": ">=16" + "node": ">=18" } }, - "node_modules/@es-joy/jsdoccomment/node_modules/@typescript-eslint/types": { - "version": "7.14.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.14.1.tgz", - "integrity": "sha512-mL7zNEOQybo5R3AavY+Am7KLv8BorIv7HCYS5rKoNZKQD9tsfGUpO4KdAn3sSUvTiS4PQkr2+K0KJbxj8H9NDg==", + "node_modules/@cspell/cspell-service-bus": { + "version": "8.14.4", + "resolved": "https://registry.npmjs.org/@cspell/cspell-service-bus/-/cspell-service-bus-8.14.4.tgz", + "integrity": "sha512-i3UG+ep63akNsDXZrtGgICNF3MLBHtvKe/VOIH6+L+NYaAaVHqqQvOY9MdUwt1HXh8ElzfwfoRp36wc5aAvt6g==", "dev": true, "license": "MIT", "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" + "node": ">=18" } }, - "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==", + "node_modules/@cspell/cspell-types": { + "version": "8.14.4", + "resolved": "https://registry.npmjs.org/@cspell/cspell-types/-/cspell-types-8.14.4.tgz", + "integrity": "sha512-VXwikqdHgjOVperVVCn2DOe8W3rPIswwZtMHfRYnagpzZo/TOntIjkXPJSfTtl/cFyx5DnCBsDH8ytKGlMeHkw==", + "dev": true, "license": "MIT", - "dependencies": { - "eslint-visitor-keys": "^3.3.0" - }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + "node": ">=18" } }, - "node_modules/@eslint-community/regexpp": { - "version": "4.11.0", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.11.0.tgz", - "integrity": "sha512-G/M/tIiMrTAxEWRfLfQJMmGNX28IxBg4PBz8XqQhqUHLFI6TL2htpIB1iQCj144V5ee/JaKyT9/WZ0MGZWfA7A==", - "license": "MIT", - "engines": { - "node": "^12.0.0 || ^14.0.0 || >=16.0.0" - } + "node_modules/@cspell/dict-ada": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@cspell/dict-ada/-/dict-ada-4.0.2.tgz", + "integrity": "sha512-0kENOWQeHjUlfyId/aCM/mKXtkEgV0Zu2RhUXCBr4hHo9F9vph+Uu8Ww2b0i5a4ZixoIkudGA+eJvyxrG1jUpA==", + "dev": true, + "license": "MIT" }, - "node_modules/@eslint/eslintrc": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", - "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", - "license": "MIT", - "dependencies": { - "ajv": "^6.12.4", - "debug": "^4.3.2", - "espree": "^9.6.0", - "globals": "^13.19.0", - "ignore": "^5.2.0", + "node_modules/@cspell/dict-aws": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@cspell/dict-aws/-/dict-aws-4.0.4.tgz", + "integrity": "sha512-6AWI/Kkf+RcX/J81VX8+GKLeTgHWEr/OMhGk3dHQzWK66RaqDJCGDqi7494ghZKcBB7dGa3U5jcKw2FZHL/u3w==", + "dev": true, + "license": "MIT" + }, + "node_modules/@cspell/dict-bash": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/@cspell/dict-bash/-/dict-bash-4.1.4.tgz", + "integrity": "sha512-W/AHoQcJYn3Vn/tUiXX2+6D/bhfzdDshwcbQWv9TdiNlXP9P6UJjDKWbxyA5ogJCsR2D0X9Kx11oV8E58siGKQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@cspell/dict-companies": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/@cspell/dict-companies/-/dict-companies-3.1.4.tgz", + "integrity": "sha512-y9e0amzEK36EiiKx3VAA+SHQJPpf2Qv5cCt5eTUSggpTkiFkCh6gRKQ97rVlrKh5GJrqinDwYIJtTsxuh2vy2Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/@cspell/dict-cpp": { + "version": "5.1.16", + "resolved": "https://registry.npmjs.org/@cspell/dict-cpp/-/dict-cpp-5.1.16.tgz", + "integrity": "sha512-32fU5RkuOM55IRcxjByiSoKbjr+C4danDfYjHaQNRWdvjzJzci3fLDGA2wTXiclkgDODxGiV8LCTUwCz+3TNWA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@cspell/dict-cryptocurrencies": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@cspell/dict-cryptocurrencies/-/dict-cryptocurrencies-5.0.0.tgz", + "integrity": "sha512-Z4ARIw5+bvmShL+4ZrhDzGhnc9znaAGHOEMaB/GURdS/jdoreEDY34wdN0NtdLHDO5KO7GduZnZyqGdRoiSmYA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@cspell/dict-csharp": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@cspell/dict-csharp/-/dict-csharp-4.0.2.tgz", + "integrity": "sha512-1JMofhLK+4p4KairF75D3A924m5ERMgd1GvzhwK2geuYgd2ZKuGW72gvXpIV7aGf52E3Uu1kDXxxGAiZ5uVG7g==", + "dev": true, + "license": "MIT" + }, + "node_modules/@cspell/dict-css": { + "version": "4.0.13", + "resolved": "https://registry.npmjs.org/@cspell/dict-css/-/dict-css-4.0.13.tgz", + "integrity": "sha512-WfOQkqlAJTo8eIQeztaH0N0P+iF5hsJVKFuhy4jmARPISy8Efcv8QXk2/IVbmjJH0/ZV7dKRdnY5JFVXuVz37g==", + "dev": true, + "license": "MIT" + }, + "node_modules/@cspell/dict-dart": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/@cspell/dict-dart/-/dict-dart-2.2.1.tgz", + "integrity": "sha512-yriKm7QkoPx3JPSSOcw6iX9gOb2N50bOo/wqWviqPYbhpMRh9Xiv6dkUy3+ot+21GuShZazO8X6U5+Vw67XEwg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@cspell/dict-data-science": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@cspell/dict-data-science/-/dict-data-science-2.0.1.tgz", + "integrity": "sha512-xeutkzK0eBe+LFXOFU2kJeAYO6IuFUc1g7iRLr7HeCmlC4rsdGclwGHh61KmttL3+YHQytYStxaRBdGAXWC8Lw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@cspell/dict-django": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@cspell/dict-django/-/dict-django-4.1.0.tgz", + "integrity": "sha512-bKJ4gPyrf+1c78Z0Oc4trEB9MuhcB+Yg+uTTWsvhY6O2ncFYbB/LbEZfqhfmmuK/XJJixXfI1laF2zicyf+l0w==", + "dev": true, + "license": "MIT" + }, + "node_modules/@cspell/dict-docker": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/@cspell/dict-docker/-/dict-docker-1.1.7.tgz", + "integrity": "sha512-XlXHAr822euV36GGsl2J1CkBIVg3fZ6879ZOg5dxTIssuhUOCiV2BuzKZmt6aIFmcdPmR14+9i9Xq+3zuxeX0A==", + "dev": true, + "license": "MIT" + }, + "node_modules/@cspell/dict-dotnet": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/@cspell/dict-dotnet/-/dict-dotnet-5.0.5.tgz", + "integrity": "sha512-gjg0L97ee146wX47dnA698cHm85e7EOpf9mVrJD8DmEaqoo/k1oPy2g7c7LgKxK9XnqwoXxhLNnngPrwXOoEtQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@cspell/dict-elixir": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/@cspell/dict-elixir/-/dict-elixir-4.0.3.tgz", + "integrity": "sha512-g+uKLWvOp9IEZvrIvBPTr/oaO6619uH/wyqypqvwpmnmpjcfi8+/hqZH8YNKt15oviK8k4CkINIqNhyndG9d9Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/@cspell/dict-en_us": { + "version": "4.3.23", + "resolved": "https://registry.npmjs.org/@cspell/dict-en_us/-/dict-en_us-4.3.23.tgz", + "integrity": "sha512-l0SoEQBsi3zDSl3OuL4/apBkxjuj4hLIg/oy6+gZ7LWh03rKdF6VNtSZNXWAmMY+pmb1cGA3ouleTiJIglbsIg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@cspell/dict-en-common-misspellings": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@cspell/dict-en-common-misspellings/-/dict-en-common-misspellings-2.0.4.tgz", + "integrity": "sha512-lvOiRjV/FG4pAGZL3PN2GCVHSTCE92cwhfLGGkOsQtxSmef6WCHfHwp9auafkBlX0yFQSKDfq6/TlpQbjbJBtQ==", + "dev": true, + "license": "CC BY-SA 4.0" + }, + "node_modules/@cspell/dict-en-gb": { + "version": "1.1.33", + "resolved": "https://registry.npmjs.org/@cspell/dict-en-gb/-/dict-en-gb-1.1.33.tgz", + "integrity": "sha512-tKSSUf9BJEV+GJQAYGw5e+ouhEe2ZXE620S7BLKe3ZmpnjlNG9JqlnaBhkIMxKnNFkLY2BP/EARzw31AZnOv4g==", + "dev": true, + "license": "MIT" + }, + "node_modules/@cspell/dict-filetypes": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@cspell/dict-filetypes/-/dict-filetypes-3.0.4.tgz", + "integrity": "sha512-IBi8eIVdykoGgIv5wQhOURi5lmCNJq0we6DvqKoPQJHthXbgsuO1qrHSiUVydMiQl/XvcnUWTMeAlVUlUClnVg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@cspell/dict-flutter": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@cspell/dict-flutter/-/dict-flutter-1.0.0.tgz", + "integrity": "sha512-W7k1VIc4KeV8BjEBxpA3cqpzbDWjfb7oXkEb0LecBCBp5Z7kcfnjT1YVotTx/U9PGyAOBhDaEdgZACVGNQhayw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@cspell/dict-fonts": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@cspell/dict-fonts/-/dict-fonts-4.0.0.tgz", + "integrity": "sha512-t9V4GeN/m517UZn63kZPUYP3OQg5f0OBLSd3Md5CU3eH1IFogSvTzHHnz4Wqqbv8NNRiBZ3HfdY/pqREZ6br3Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/@cspell/dict-fsharp": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@cspell/dict-fsharp/-/dict-fsharp-1.0.1.tgz", + "integrity": "sha512-23xyPcD+j+NnqOjRHgW3IU7Li912SX9wmeefcY0QxukbAxJ/vAN4rBpjSwwYZeQPAn3fxdfdNZs03fg+UM+4yQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@cspell/dict-fullstack": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/@cspell/dict-fullstack/-/dict-fullstack-3.2.0.tgz", + "integrity": "sha512-sIGQwU6G3rLTo+nx0GKyirR5dQSFeTIzFTOrURw51ISf+jKG9a3OmvsVtc2OANfvEAOLOC9Wfd8WYhmsO8KRDQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@cspell/dict-gaming-terms": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@cspell/dict-gaming-terms/-/dict-gaming-terms-1.0.5.tgz", + "integrity": "sha512-C3riccZDD3d9caJQQs1+MPfrUrQ+0KHdlj9iUR1QD92FgTOF6UxoBpvHUUZ9YSezslcmpFQK4xQQ5FUGS7uWfw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@cspell/dict-git": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@cspell/dict-git/-/dict-git-3.0.0.tgz", + "integrity": "sha512-simGS/lIiXbEaqJu9E2VPoYW1OTC2xrwPPXNXFMa2uo/50av56qOuaxDrZ5eH1LidFXwoc8HROCHYeKoNrDLSw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@cspell/dict-golang": { + "version": "6.0.12", + "resolved": "https://registry.npmjs.org/@cspell/dict-golang/-/dict-golang-6.0.12.tgz", + "integrity": "sha512-LEPeoqd+4O+vceHF73S7D7+LYfrAjOvp4Dqzh4MT30ruzlQ77yHRSuYOJtrFN1GK5ntAt/ILSVOKg9sgsz1Llg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@cspell/dict-google": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@cspell/dict-google/-/dict-google-1.0.1.tgz", + "integrity": "sha512-dQr4M3n95uOhtloNSgB9tYYGXGGEGEykkFyRtfcp5pFuEecYUa0BSgtlGKx9RXVtJtKgR+yFT/a5uQSlt8WjqQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@cspell/dict-haskell": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@cspell/dict-haskell/-/dict-haskell-4.0.1.tgz", + "integrity": "sha512-uRrl65mGrOmwT7NxspB4xKXFUenNC7IikmpRZW8Uzqbqcu7ZRCUfstuVH7T1rmjRgRkjcIjE4PC11luDou4wEQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@cspell/dict-html": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/@cspell/dict-html/-/dict-html-4.0.6.tgz", + "integrity": "sha512-cLWHfuOhE4wqwC12up6Doxo2u1xxVhX1A8zriR4CUD+osFQzUIcBK1ykNXppga+rt1WyypaJdTU2eV6OpzYrgQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@cspell/dict-html-symbol-entities": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@cspell/dict-html-symbol-entities/-/dict-html-symbol-entities-4.0.0.tgz", + "integrity": "sha512-HGRu+48ErJjoweR5IbcixxETRewrBb0uxQBd6xFGcxbEYCX8CnQFTAmKI5xNaIt2PKaZiJH3ijodGSqbKdsxhw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@cspell/dict-java": { + "version": "5.0.7", + "resolved": "https://registry.npmjs.org/@cspell/dict-java/-/dict-java-5.0.7.tgz", + "integrity": "sha512-ejQ9iJXYIq7R09BScU2y5OUGrSqwcD+J5mHFOKbduuQ5s/Eh/duz45KOzykeMLI6KHPVxhBKpUPBWIsfewECpQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@cspell/dict-julia": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@cspell/dict-julia/-/dict-julia-1.0.1.tgz", + "integrity": "sha512-4JsCLCRhhLMLiaHpmR7zHFjj1qOauzDI5ZzCNQS31TUMfsOo26jAKDfo0jljFAKgw5M2fEG7sKr8IlPpQAYrmQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@cspell/dict-k8s": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/@cspell/dict-k8s/-/dict-k8s-1.0.6.tgz", + "integrity": "sha512-srhVDtwrd799uxMpsPOQqeDJY+gEocgZpoK06EFrb4GRYGhv7lXo9Fb+xQMyQytzOW9dw4DNOEck++nacDuymg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@cspell/dict-latex": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@cspell/dict-latex/-/dict-latex-4.0.0.tgz", + "integrity": "sha512-LPY4y6D5oI7D3d+5JMJHK/wxYTQa2lJMSNxps2JtuF8hbAnBQb3igoWEjEbIbRRH1XBM0X8dQqemnjQNCiAtxQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@cspell/dict-lorem-ipsum": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@cspell/dict-lorem-ipsum/-/dict-lorem-ipsum-4.0.0.tgz", + "integrity": "sha512-1l3yjfNvMzZPibW8A7mQU4kTozwVZVw0AvFEdy+NcqtbxH+TvbSkNMqROOFWrkD2PjnKG0+Ea0tHI2Pi6Gchnw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@cspell/dict-lua": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/@cspell/dict-lua/-/dict-lua-4.0.3.tgz", + "integrity": "sha512-lDHKjsrrbqPaea13+G9s0rtXjMO06gPXPYRjRYawbNmo4E/e3XFfVzeci3OQDQNDmf2cPOwt9Ef5lu2lDmwfJg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@cspell/dict-makefile": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@cspell/dict-makefile/-/dict-makefile-1.0.0.tgz", + "integrity": "sha512-3W9tHPcSbJa6s0bcqWo6VisEDTSN5zOtDbnPabF7rbyjRpNo0uHXHRJQF8gAbFzoTzBBhgkTmrfSiuyQm7vBUQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@cspell/dict-monkeyc": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/@cspell/dict-monkeyc/-/dict-monkeyc-1.0.6.tgz", + "integrity": "sha512-oO8ZDu/FtZ55aq9Mb67HtaCnsLn59xvhO/t2mLLTHAp667hJFxpp7bCtr2zOrR1NELzFXmKln/2lw/PvxMSvrA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@cspell/dict-node": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@cspell/dict-node/-/dict-node-5.0.1.tgz", + "integrity": "sha512-lax/jGz9h3Dv83v8LHa5G0bf6wm8YVRMzbjJPG/9rp7cAGPtdrga+XANFq+B7bY5+jiSA3zvj10LUFCFjnnCCg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@cspell/dict-npm": { + "version": "5.1.5", + "resolved": "https://registry.npmjs.org/@cspell/dict-npm/-/dict-npm-5.1.5.tgz", + "integrity": "sha512-oAOGWuJYU3DlO+cAsStKMWN8YEkBue25cRC9EwdiL5Z84nchU20UIoYrLfIQejMlZca+1GyrNeyxRAgn4KiivA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@cspell/dict-php": { + "version": "4.0.10", + "resolved": "https://registry.npmjs.org/@cspell/dict-php/-/dict-php-4.0.10.tgz", + "integrity": "sha512-NfTZdp6kcZDF1PvgQ6cY0zE4FUO5rSwNmBH/iwCBuaLfJAFQ97rgjxo+D2bic4CFwNjyHutnHPtjJBRANO5XQw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@cspell/dict-powershell": { + "version": "5.0.9", + "resolved": "https://registry.npmjs.org/@cspell/dict-powershell/-/dict-powershell-5.0.9.tgz", + "integrity": "sha512-Vi0h0rlxS39tgTyUtxI6L3BPHH7MLPkLWCYkNfb/buQuNJYNFdHiF4bqoqVdJ/7ZrfIfNg4i6rzocnwGRn2ruw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@cspell/dict-public-licenses": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/@cspell/dict-public-licenses/-/dict-public-licenses-2.0.8.tgz", + "integrity": "sha512-Sup+tFS7cDV0fgpoKtUqEZ6+fA/H+XUgBiqQ/Fbs6vUE3WCjJHOIVsP+udHuyMH7iBfJ4UFYOYeORcY4EaKdMg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@cspell/dict-python": { + "version": "4.2.6", + "resolved": "https://registry.npmjs.org/@cspell/dict-python/-/dict-python-4.2.6.tgz", + "integrity": "sha512-Hkz399qDGEbfXi9GYa2hDl7GahglI86JmS2F1KP8sfjLXofUgtnknyC5NWc86nzHcP38pZiPqPbTigyDYw5y8A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@cspell/dict-data-science": "^2.0.1" + } + }, + "node_modules/@cspell/dict-r": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@cspell/dict-r/-/dict-r-2.0.1.tgz", + "integrity": "sha512-KCmKaeYMLm2Ip79mlYPc8p+B2uzwBp4KMkzeLd5E6jUlCL93Y5Nvq68wV5fRLDRTf7N1LvofkVFWfDcednFOgA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@cspell/dict-ruby": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/@cspell/dict-ruby/-/dict-ruby-5.0.3.tgz", + "integrity": "sha512-V1xzv9hN6u8r6SM4CkYdsxs4ov8gjXXo0Twfx5kWhLXbEVxTXDMt7ohLTqpy2XlF5mutixZdbHMeFiAww8v+Ug==", + "dev": true, + "license": "MIT" + }, + "node_modules/@cspell/dict-rust": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/@cspell/dict-rust/-/dict-rust-4.0.5.tgz", + "integrity": "sha512-DIvlPRDemjKQy8rCqftAgGNZxY5Bg+Ps7qAIJjxkSjmMETyDgl0KTVuaJPt7EK4jJt6uCZ4ILy96npsHDPwoXA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@cspell/dict-scala": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/@cspell/dict-scala/-/dict-scala-5.0.3.tgz", + "integrity": "sha512-4yGb4AInT99rqprxVNT9TYb1YSpq58Owzq7zi3ZS5T0u899Y4VsxsBiOgHnQ/4W+ygi+sp+oqef8w8nABR2lkg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@cspell/dict-software-terms": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/@cspell/dict-software-terms/-/dict-software-terms-4.1.4.tgz", + "integrity": "sha512-AHS25sYEzWze/aFglp9ODKSu+phjkuGx+OLwIcmOnvyn8axtSq5GCn9UqS4XG1/Qn0UG2Lgb4i5PJbZ0QNPNXQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@cspell/dict-sql": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@cspell/dict-sql/-/dict-sql-2.1.5.tgz", + "integrity": "sha512-FmxanytHXss7GAWAXmgaxl3icTCW7YxlimyOSPNfm+njqeUDjw3kEv4mFNDDObBJv8Ec5AWCbUDkWIpkE3IpKg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@cspell/dict-svelte": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@cspell/dict-svelte/-/dict-svelte-1.0.2.tgz", + "integrity": "sha512-rPJmnn/GsDs0btNvrRBciOhngKV98yZ9SHmg8qI6HLS8hZKvcXc0LMsf9LLuMK1TmS2+WQFAan6qeqg6bBxL2Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/@cspell/dict-swift": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@cspell/dict-swift/-/dict-swift-2.0.1.tgz", + "integrity": "sha512-gxrCMUOndOk7xZFmXNtkCEeroZRnS2VbeaIPiymGRHj5H+qfTAzAKxtv7jJbVA3YYvEzWcVE2oKDP4wcbhIERw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@cspell/dict-terraform": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@cspell/dict-terraform/-/dict-terraform-1.0.1.tgz", + "integrity": "sha512-29lmUUnZgPh+ieZ5hunick8hzNIpNRtiJh9vAusNskPCrig3RTW6u7F+GG1a8uyslbzSw+Irjf40PTOan1OJJA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@cspell/dict-typescript": { + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/@cspell/dict-typescript/-/dict-typescript-3.1.6.tgz", + "integrity": "sha512-1beC6O4P/j23VuxX+i0+F7XqPVc3hhiAzGJHEKqnWf5cWAXQtg0xz3xQJ5MvYx2a7iLaSa+lu7+05vG9UHyu9Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/@cspell/dict-vue": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@cspell/dict-vue/-/dict-vue-3.0.0.tgz", + "integrity": "sha512-niiEMPWPV9IeRBRzZ0TBZmNnkK3olkOPYxC1Ny2AX4TGlYRajcW0WUtoSHmvvjZNfWLSg2L6ruiBeuPSbjnG6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/@cspell/dynamic-import": { + "version": "8.14.4", + "resolved": "https://registry.npmjs.org/@cspell/dynamic-import/-/dynamic-import-8.14.4.tgz", + "integrity": "sha512-GjKsBJvPXp4dYRqsMn7n1zpnKbnpfJnlKLOVeoFBh8fi4n06G50xYr+G25CWX1WT3WFaALAavvVICEUPrVsuqg==", + "dev": true, + "license": "MIT", + "dependencies": { + "import-meta-resolve": "^4.1.0" + }, + "engines": { + "node": ">=18.0" + } + }, + "node_modules/@cspell/filetypes": { + "version": "8.14.4", + "resolved": "https://registry.npmjs.org/@cspell/filetypes/-/filetypes-8.14.4.tgz", + "integrity": "sha512-qd68dD7xTA4Mnf/wjIKYz2SkiTBshIM+yszOUtLa06YJm0aocoNQ25FHXyYEQYm9NQXCYnRWWA02sFMGs8Sv/w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/@cspell/strong-weak-map": { + "version": "8.14.4", + "resolved": "https://registry.npmjs.org/@cspell/strong-weak-map/-/strong-weak-map-8.14.4.tgz", + "integrity": "sha512-Uyfck64TfVU24wAP3BLGQ5EsAfzIZiLfN90NhttpEM7GlOBmbGrEJd4hNOwfpYsE/TT80eGWQVPRTLr5SDbXFA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/@cspell/url": { + "version": "8.14.4", + "resolved": "https://registry.npmjs.org/@cspell/url/-/url-8.14.4.tgz", + "integrity": "sha512-htHhNF8WrM/NfaLSWuTYw0NqVgFRVHYSyHlRT3i/Yv5xvErld8Gw7C6ldm+0TLjoGlUe6X1VV72JSir7+yLp/Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18.0" + } + }, + "node_modules/@csstools/css-parser-algorithms": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@csstools/css-parser-algorithms/-/css-parser-algorithms-3.0.1.tgz", + "integrity": "sha512-lSquqZCHxDfuTg/Sk2hiS0mcSFCEBuj49JfzPHJogDBT0mGCyY5A1AQzBWngitrp7i1/HAZpIgzF/VjhOEIJIg==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@csstools/css-tokenizer": "^3.0.1" + } + }, + "node_modules/@csstools/css-tokenizer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@csstools/css-tokenizer/-/css-tokenizer-3.0.1.tgz", + "integrity": "sha512-UBqaiu7kU0lfvaP982/o3khfXccVlHPWp0/vwwiIgDF0GmqqqxoiXC/6FCjlS9u92f7CoEz6nXKQnrn1kIAkOw==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/@csstools/media-query-list-parser": { + "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": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@csstools/css-parser-algorithms": "^3.0.1", + "@csstools/css-tokenizer": "^3.0.1" + } + }, + "node_modules/@csstools/selector-specificity": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@csstools/selector-specificity/-/selector-specificity-4.0.0.tgz", + "integrity": "sha512-189nelqtPd8++phaHNwYovKZI0FOzH1vQEE3QhHHkNIGrg5fSs9CbYP3RvfEH5geztnIA9Jwq91wyOIwAW5JIQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss-selector-parser": "^6.1.0" + } + }, + "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, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/@electron/get": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@electron/get/-/get-2.0.3.tgz", + "integrity": "sha512-Qkzpg2s9GnVV2I2BjRksUi43U5e6+zaQMcjoJy0C+C5oxaKl+fmckGDQFtRpZpZV0NQekuZZ+tGz7EA9TVnQtQ==", + "license": "MIT", + "optional": true, + "dependencies": { + "debug": "^4.1.1", + "env-paths": "^2.2.0", + "fs-extra": "^8.1.0", + "got": "^11.8.5", + "progress": "^2.0.3", + "semver": "^6.2.0", + "sumchecker": "^3.0.1" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "global-agent": "^3.0.0" + } + }, + "node_modules/@electron/get/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==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/@electron/get/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "license": "ISC", + "optional": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@es-joy/jsdoccomment": { + "version": "0.48.0", + "resolved": "https://registry.npmjs.org/@es-joy/jsdoccomment/-/jsdoccomment-0.48.0.tgz", + "integrity": "sha512-G6QUWIcC+KvSwXNsJyDTHvqUdNoAVJPPgkc3+Uk4WBKqZvoXhlvazOgm9aL0HwihJLQf0l+tOE2UFzXBqCqgDw==", + "dev": true, + "license": "MIT", + "dependencies": { + "comment-parser": "1.4.1", + "esquery": "^1.6.0", + "jsdoc-type-pratt-parser": "~4.1.0" + }, + "engines": { + "node": ">=16" + } + }, + "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==", + "license": "MIT", + "dependencies": { + "eslint-visitor-keys": "^3.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@eslint-community/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==", + "license": "Apache-2.0", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint-community/regexpp": { + "version": "4.11.1", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.11.1.tgz", + "integrity": "sha512-m4DVN9ZqskZoLU5GlWZadwDnYo3vAEydiUayB9widCl9ffWx2IvPnp6n3on5rJmziJSw9Bv+Z3ChDVdMwXCY8Q==", + "license": "MIT", + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/@eslint/config-array": { + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.18.0.tgz", + "integrity": "sha512-fTxvnS1sRMu3+JjXwJG0j/i4RT9u4qJ+lqS/yCGap4lH4zZGzQ7tu+xZqQmcMZq5OBZDL4QRxQzRjkWcGt8IVw==", + "license": "Apache-2.0", + "dependencies": { + "@eslint/object-schema": "^2.1.4", + "debug": "^4.3.1", + "minimatch": "^3.1.2" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/config-array/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/@eslint/config-array/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/@eslint/core": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.6.0.tgz", + "integrity": "sha512-8I2Q8ykA4J0x0o7cg67FPVnehcqWTBehu/lmY+bolPFHGjh49YzGBMXTvpqVgEbBdvNCSxj6iFgiIyHzf03lzg==", + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.1.0.tgz", + "integrity": "sha512-4Bfj15dVJdoy3RfZmmo86RK1Fwzn6SstsvK9JS+BaVKqC6QQQQyXekNaC+g+LKNgkQ+2VhGAzm6hO40AhMR3zQ==", + "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": "^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" @@ -969,49 +1552,33 @@ } }, "node_modules/@eslint/js": { - "version": "8.57.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.0.tgz", - "integrity": "sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==", + "version": "9.11.1", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.11.1.tgz", + "integrity": "sha512-/qu+TWz8WwPWc7/HcIJKi+c+MOm46GdVaSlTTQcaqaL53+GsoA6MxWp5PtTx48qbSP7ylM1Kn7nhvkugfJvRSA==", "license": "MIT", "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, - "node_modules/@humanwhocodes/config-array": { - "version": "0.11.14", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz", - "integrity": "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==", - "deprecated": "Use @eslint/config-array instead", + "node_modules/@eslint/object-schema": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.4.tgz", + "integrity": "sha512-BsWiH1yFGjXXS2yvrf5LyuoSIIbPrGUWob917o+BTKuZ7qJdxX8aJLRxs1fS9n6r7vESrq1OUqb68dANcFXuQQ==", "license": "Apache-2.0", - "dependencies": { - "@humanwhocodes/object-schema": "^2.0.2", - "debug": "^4.3.1", - "minimatch": "^3.0.5" - }, "engines": { - "node": ">=10.10.0" - } - }, - "node_modules/@humanwhocodes/config-array/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, - "node_modules/@humanwhocodes/config-array/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "license": "ISC", + "node_modules/@eslint/plugin-kit": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.2.0.tgz", + "integrity": "sha512-vH9PiIMMwvhCx31Af3HiGzsVNULDbyVkHXwlemn/B0TFj/00ho3y55efXrUZTfQipxoHC5u4xq6zblww1zm1Ig==", + "license": "Apache-2.0", "dependencies": { - "brace-expansion": "^1.1.7" + "levn": "^0.4.1" }, "engines": { - "node": "*" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, "node_modules/@humanwhocodes/module-importer": { @@ -1020,20 +1587,26 @@ "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", "license": "Apache-2.0", "engines": { - "node": ">=12.22" + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/retry": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.3.0.tgz", + "integrity": "sha512-d2CGZR2o7fS6sWB7DG/3a95bGKQyHMACZ5aW8qGkkqQpUoZV6C0X7Pc7l4ZNMZkfNBf4VWNe9E1jRsf0G146Ew==", + "license": "Apache-2.0", + "engines": { + "node": ">=18.18" }, "funding": { "type": "github", "url": "https://github.com/sponsors/nzakas" } }, - "node_modules/@humanwhocodes/object-schema": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz", - "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==", - "deprecated": "Use @eslint/object-schema instead", - "license": "BSD-3-Clause" - }, "node_modules/@istanbuljs/load-nyc-config": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", @@ -1131,16 +1704,6 @@ "node": ">=8" } }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/@istanbuljs/load-nyc-config/node_modules/sprintf-js": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", @@ -1224,18 +1787,25 @@ } } }, - "node_modules/@jest/core/node_modules/ci-info": { - "version": "3.9.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", - "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", + "node_modules/@jest/core/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/core/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/sibiraj-s" - } - ], "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, "engines": { "node": ">=8" } @@ -1361,6 +1931,29 @@ } } }, + "node_modules/@jest/reporters/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/reporters/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/@jest/schemas": { "version": "29.6.3", "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", @@ -1502,9 +2095,9 @@ } }, "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.4.15", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", - "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", + "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", "dev": true, "license": "MIT" }, @@ -1662,9 +2255,9 @@ "license": "ISC" }, "node_modules/@pm2/io": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/@pm2/io/-/io-6.0.0.tgz", - "integrity": "sha512-sKUEgZoQ5/jRwTyMB1I7u2wXL6dG0j/F/M4ANJ7dJCApfW8nWC0RElMW2siEKvZ79iplIPAaWV27oyBoerEflw==", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/@pm2/io/-/io-6.0.1.tgz", + "integrity": "sha512-KiA+shC6sULQAr9mGZ1pg+6KVW9MF8NpG99x26Lf/082/Qy8qsTCtnJy+HQReW1A9Rdf0C/404cz0RZGZro+IA==", "license": "Apache-2", "dependencies": { "async": "~2.6.1", @@ -1843,31 +2436,31 @@ } }, "node_modules/@sinonjs/samsam": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-8.0.0.tgz", - "integrity": "sha512-Bp8KUVlLp8ibJZrnvq2foVhP0IVX2CIprMJPK0vqGqgrDa0OHVKeZyBykqskkrdxV6yKBPmGasO8LVjAKR3Gew==", + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-8.0.2.tgz", + "integrity": "sha512-v46t/fwnhejRSFTGqbpn9u+LQ9xJDse10gNnPgAcxgdoCDMXj/G2asWAC/8Qs+BAZDicX+MNZouXT1A7c83kVw==", "dev": true, "license": "BSD-3-Clause", "dependencies": { - "@sinonjs/commons": "^2.0.0", + "@sinonjs/commons": "^3.0.1", "lodash.get": "^4.4.2", - "type-detect": "^4.0.8" + "type-detect": "^4.1.0" } }, - "node_modules/@sinonjs/samsam/node_modules/@sinonjs/commons": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-2.0.0.tgz", - "integrity": "sha512-uLa0j859mMrg2slwQYdO/AkrOfmH+X6LTVmNTS9CqexuE2IvVORIkSpJLqePAbEnKJ77aMmCwr1NUZ57120Xcg==", + "node_modules/@sinonjs/samsam/node_modules/type-detect": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.1.0.tgz", + "integrity": "sha512-Acylog8/luQ8L7il+geoSxhEkazvkslg7PSNKOX59mbB9cOveP5aq9h74Y7YU8yDpJwetzQQrfIwtf4Wp4LKcw==", "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "type-detect": "4.0.8" + "license": "MIT", + "engines": { + "node": ">=4" } }, "node_modules/@sinonjs/text-encoding": { - "version": "0.7.2", - "resolved": "https://registry.npmjs.org/@sinonjs/text-encoding/-/text-encoding-0.7.2.tgz", - "integrity": "sha512-sXXKG+uL9IrKqViTtao2Ws6dy0znu9sOaP1di/jKGW1M6VssO8vlpXCQcpZ+jisQ1tTFAC5Jo/EOzFbggBagFQ==", + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/@sinonjs/text-encoding/-/text-encoding-0.7.3.tgz", + "integrity": "sha512-DE427ROAphMQzU4ENbliGYrBSYPXF+TtLg9S8vzeA+OF4ZKzoDdzfL8sxuMUGS/lgRhM6j1URSk9ghf7Xo1tyA==", "dev": true, "license": "(Unlicense OR Apache-2.0)" }, @@ -1878,91 +2471,20 @@ "license": "MIT" }, "node_modules/@stylistic/eslint-plugin": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin/-/eslint-plugin-1.8.1.tgz", - "integrity": "sha512-64My6I7uCcmSQ//427Pfg2vjSf9SDzfsGIWohNFgISMLYdC5BzJqDo647iDDJzSxINh3WTC0Ql46ifiKuOoTyA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@stylistic/eslint-plugin-js": "1.8.1", - "@stylistic/eslint-plugin-jsx": "1.8.1", - "@stylistic/eslint-plugin-plus": "1.8.1", - "@stylistic/eslint-plugin-ts": "1.8.1", - "@types/eslint": "^8.56.10" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "peerDependencies": { - "eslint": ">=8.40.0" - } - }, - "node_modules/@stylistic/eslint-plugin-js": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin-js/-/eslint-plugin-js-1.8.1.tgz", - "integrity": "sha512-c5c2C8Mos5tTQd+NWpqwEu7VT6SSRooAguFPMj1cp2RkTYl1ynKoXo8MWy3k4rkbzoeYHrqC2UlUzsroAN7wtQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/eslint": "^8.56.10", - "acorn": "^8.11.3", - "escape-string-regexp": "^4.0.0", - "eslint-visitor-keys": "^3.4.3", - "espree": "^9.6.1" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "peerDependencies": { - "eslint": ">=8.40.0" - } - }, - "node_modules/@stylistic/eslint-plugin-jsx": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin-jsx/-/eslint-plugin-jsx-1.8.1.tgz", - "integrity": "sha512-k1Eb6rcjMP+mmjvj+vd9y5KUdWn1OBkkPLHXhsrHt5lCDFZxJEs0aVQzE5lpYrtVZVkpc5esTtss/cPJux0lfA==", + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin/-/eslint-plugin-2.8.0.tgz", + "integrity": "sha512-Ufvk7hP+bf+pD35R/QfunF793XlSRIC7USr3/EdgduK9j13i2JjmsM0LUz3/foS+jDYp2fzyWZA9N44CPur0Ow==", "dev": true, "license": "MIT", "dependencies": { - "@stylistic/eslint-plugin-js": "^1.8.1", - "@types/eslint": "^8.56.10", + "@typescript-eslint/utils": "^8.4.0", + "eslint-visitor-keys": "^4.0.0", + "espree": "^10.1.0", "estraverse": "^5.3.0", "picomatch": "^4.0.2" }, "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "peerDependencies": { - "eslint": ">=8.40.0" - } - }, - "node_modules/@stylistic/eslint-plugin-plus": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin-plus/-/eslint-plugin-plus-1.8.1.tgz", - "integrity": "sha512-4+40H3lHYTN8OWz+US8CamVkO+2hxNLp9+CAjorI7top/lHqemhpJvKA1LD9Uh+WMY9DYWiWpL2+SZ2wAXY9fQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/eslint": "^8.56.10", - "@typescript-eslint/utils": "^6.21.0" - }, - "peerDependencies": { - "eslint": "*" - } - }, - "node_modules/@stylistic/eslint-plugin-ts": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin-ts/-/eslint-plugin-ts-1.8.1.tgz", - "integrity": "sha512-/q1m+ZuO1JHfiSF16EATFzv7XSJkc5W6DocfvH5o9oB6WWYFMF77fVoBWnKT3wGptPOc2hkRupRKhmeFROdfWA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@stylistic/eslint-plugin-js": "1.8.1", - "@types/eslint": "^8.56.10", - "@typescript-eslint/utils": "^6.21.0" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "peerDependencies": { "eslint": ">=8.40.0" @@ -2060,22 +2582,10 @@ "@types/node": "*" } }, - "node_modules/@types/eslint": { - "version": "8.56.10", - "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.56.10.tgz", - "integrity": "sha512-Shavhk87gCtY2fhXDctcfS3e6FdxWkCx1iUZ9eEUbh7rTqlZT0/IzOkCOVt0fCjcFuZ9FPYfuezTBImfHCDBGQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/estree": "*", - "@types/json-schema": "*" - } - }, "node_modules/@types/estree": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", - "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", - "dev": true, + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz", + "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==", "license": "MIT" }, "node_modules/@types/glob": { @@ -2137,14 +2647,6 @@ "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/@types/json5": { - "version": "0.0.29", - "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", - "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", - "dev": true, "license": "MIT" }, "node_modules/@types/keyv": { @@ -2165,21 +2667,14 @@ "license": "MIT" }, "node_modules/@types/node": { - "version": "20.14.9", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.9.tgz", - "integrity": "sha512-06OCtnTXtWOZBJlRApleWndH4JsRVs1pDCc8dLSQp+7PpUpX3ePdHyeNSFTeSe7FtKyQkrlPvHwJOW3SLd8Oyg==", + "version": "20.16.10", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.16.10.tgz", + "integrity": "sha512-vQUKgWTjEIRFCvK6CyriPH3MZYiYlNy0fKiEYHWbcoWLEgs4opurGGKlebrTLqdSMIbXImH6XExNiIyNUv3WpA==", "license": "MIT", "dependencies": { - "undici-types": "~5.26.4" + "undici-types": "~6.19.2" } }, - "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, - "license": "MIT" - }, "node_modules/@types/responselike": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/@types/responselike/-/responselike-1.0.3.tgz", @@ -2190,13 +2685,6 @@ "@types/node": "*" } }, - "node_modules/@types/semver": { - "version": "7.5.8", - "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.8.tgz", - "integrity": "sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==", - "dev": true, - "license": "MIT" - }, "node_modules/@types/stack-utils": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.3.tgz", @@ -2205,9 +2693,9 @@ "license": "MIT" }, "node_modules/@types/yargs": { - "version": "17.0.32", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.32.tgz", - "integrity": "sha512-xQ67Yc/laOG5uMfX/093MRlGGCIBzZMarVa+gfNKJxWAIgykYpVGkBdbqEzGDDfCrVUj6Hiff4mTZ5BA6TmAog==", + "version": "17.0.33", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.33.tgz", + "integrity": "sha512-WpxBCKWPLr4xSsHgz511rFJAM+wS28w2zEO1QDNY5zM/S8ok70NNfztH0xwhqKyaK0OHCbN98LDAZuy1ctxDkA==", "dev": true, "license": "MIT", "dependencies": { @@ -2232,17 +2720,17 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "6.21.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.21.0.tgz", - "integrity": "sha512-OwLUIWZJry80O99zvqXVEioyniJMa+d2GrqpUTqi5/v5D5rOrppJVBPa0yKCblcigC0/aYAzxxqQ1B+DS2RYsg==", + "version": "8.7.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.7.0.tgz", + "integrity": "sha512-87rC0k3ZlDOuz82zzXRtQ7Akv3GKhHs0ti4YcbAJtaomllXoSO8hi7Ix3ccEvCd824dy9aIX+j3d2UMAfCtVpg==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "6.21.0", - "@typescript-eslint/visitor-keys": "6.21.0" + "@typescript-eslint/types": "8.7.0", + "@typescript-eslint/visitor-keys": "8.7.0" }, "engines": { - "node": "^16.0.0 || >=18.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", @@ -2250,13 +2738,13 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "6.21.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.21.0.tgz", - "integrity": "sha512-1kFmZ1rOm5epu9NZEZm1kckCDGj5UJEf7P1kliH4LKu/RkwpsfqqGmY2OOcUs18lSlQBKLDYBOGxRVtrMN5lpg==", + "version": "8.7.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.7.0.tgz", + "integrity": "sha512-LLt4BLHFwSfASHSF2K29SZ+ZCsbQOM+LuarPjRUuHm+Qd09hSe3GCeaQbcCr+Mik+0QFRmep/FyZBO6fJ64U3w==", "dev": true, "license": "MIT", "engines": { - "node": "^16.0.0 || >=18.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", @@ -2264,23 +2752,23 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "6.21.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.21.0.tgz", - "integrity": "sha512-6npJTkZcO+y2/kr+z0hc4HwNfrrP4kNYh57ek7yCNlrBjWQ1Y0OS7jiZTkgumrvkX5HkEKXFZkkdFNkaW2wmUQ==", + "version": "8.7.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.7.0.tgz", + "integrity": "sha512-MC8nmcGHsmfAKxwnluTQpNqceniT8SteVwd2voYlmiSWGOtjvGXdPl17dYu2797GVscK30Z04WRM28CrKS9WOg==", "dev": true, "license": "BSD-2-Clause", "dependencies": { - "@typescript-eslint/types": "6.21.0", - "@typescript-eslint/visitor-keys": "6.21.0", + "@typescript-eslint/types": "8.7.0", + "@typescript-eslint/visitor-keys": "8.7.0", "debug": "^4.3.4", - "globby": "^11.1.0", + "fast-glob": "^3.3.2", "is-glob": "^4.0.3", - "minimatch": "9.0.3", - "semver": "^7.5.4", - "ts-api-utils": "^1.0.1" + "minimatch": "^9.0.4", + "semver": "^7.6.0", + "ts-api-utils": "^1.3.0" }, "engines": { - "node": "^16.0.0 || >=18.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", @@ -2293,54 +2781,58 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "6.21.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.21.0.tgz", - "integrity": "sha512-NfWVaC8HP9T8cbKQxHcsJBY5YE1O33+jpMwN45qzWWaPDZgLIbo12toGMWnmhvCpd3sIxkpDw3Wv1B3dYrbDQQ==", + "version": "8.7.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.7.0.tgz", + "integrity": "sha512-ZbdUdwsl2X/s3CiyAu3gOlfQzpbuG3nTWKPoIvAu1pu5r8viiJvv2NPN2AqArL35NCYtw/lrPPfM4gxrMLNLPw==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", - "@types/json-schema": "^7.0.12", - "@types/semver": "^7.5.0", - "@typescript-eslint/scope-manager": "6.21.0", - "@typescript-eslint/types": "6.21.0", - "@typescript-eslint/typescript-estree": "6.21.0", - "semver": "^7.5.4" + "@typescript-eslint/scope-manager": "8.7.0", + "@typescript-eslint/types": "8.7.0", + "@typescript-eslint/typescript-estree": "8.7.0" }, "engines": { - "node": "^16.0.0 || >=18.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^7.0.0 || ^8.0.0" + "eslint": "^8.57.0 || ^9.0.0" } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "6.21.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.21.0.tgz", - "integrity": "sha512-JJtkDduxLi9bivAB+cYOVMtbkqdPOhZ+ZI5LC47MIRrDV4Yn2o+ZnW10Nkmr28xRpSpdJ6Sm42Hjf2+REYXm0A==", + "version": "8.7.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.7.0.tgz", + "integrity": "sha512-b1tx0orFCCh/THWPQa2ZwWzvOeyzzp36vkJYOpVg0u8UVOIsfVrnuC9FqAw9gRKn+rG2VmWQ/zDJZzkxUnj/XQ==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "6.21.0", - "eslint-visitor-keys": "^3.4.1" + "@typescript-eslint/types": "8.7.0", + "eslint-visitor-keys": "^3.4.3" }, "engines": { - "node": "^16.0.0 || >=18.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" } }, - "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==", - "license": "ISC" + "node_modules/@typescript-eslint/visitor-keys/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, + "license": "Apache-2.0", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } }, "node_modules/accepts": { "version": "1.3.8", @@ -2356,9 +2848,9 @@ } }, "node_modules/acorn": { - "version": "8.12.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.0.tgz", - "integrity": "sha512-RTvkC4w+KNXrM39/lWCUaG0IbRkWdCv7W/IOW9oU6SawyxulvkQy5HQPVTKxEjczcUvapcrw3cFx/60VN/NRNw==", + "version": "8.12.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz", + "integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==", "license": "MIT", "bin": { "acorn": "bin/acorn" @@ -2389,15 +2881,15 @@ } }, "node_modules/ajv": { - "version": "8.16.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.16.0.tgz", - "integrity": "sha512-F0twR8U1ZU67JIEtekUcLkXkoO5mMMmgGD8sK/xUFzJ805jxHQl92hImFAqqXMyMYjSPOyUPAwHYhB72g5sTXw==", + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", "license": "MIT", "dependencies": { "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.4.1" + "require-from-string": "^2.0.2" }, "funding": { "type": "github", @@ -2444,26 +2936,17 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/ansi-escapes/node_modules/type-fest": { - "version": "0.21.3", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", - "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "node_modules/ansi-regex": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", + "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", "dev": true, - "license": "(MIT OR CC0-1.0)", + "license": "MIT", "engines": { - "node": ">=10" + "node": ">=12" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "license": "MIT", - "engines": { - "node": ">=8" + "url": "https://github.com/chalk/ansi-regex?sponsor=1" } }, "node_modules/ansi-styles": { @@ -2482,9 +2965,9 @@ } }, "node_modules/ansis": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/ansis/-/ansis-3.2.0.tgz", - "integrity": "sha512-Yk3BkHH9U7oPyCN3gL5Tc7CpahG/+UFv/6UG03C311Vy9lzRmA5uoxDTpU9CO3rGHL6KzJz/pdDeXZCZ5Mu/Sg==", + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/ansis/-/ansis-3.3.2.tgz", + "integrity": "sha512-cFthbBlt+Oi0i9Pv/j6YdVWJh54CtjGACaMPCIrEV4Ha7HWsIjXDwseYV79TIL0B4+KfSwD5S70PeQDkPUd1rA==", "license": "ISC", "engines": { "node": ">=15" @@ -2521,101 +3004,24 @@ "integrity": "sha512-ixiS0nLNNG5jNQzgZJNoUpBKdo9yTYZMGJ+QgT2jmjR7G7+QHRCc4v6LQ3NgE7EBJq+o0ams3waJwkrlBom8Ig==", "dev": true, "license": "MIT", - "engines": { - "node": ">=14" - } - }, - "node_modules/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "license": "Python-2.0" - }, - "node_modules/array-buffer-byte-length": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.1.tgz", - "integrity": "sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==", - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.5", - "is-array-buffer": "^3.0.4" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/array-flatten": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", - "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==", - "license": "MIT" - }, - "node_modules/array-includes": { - "version": "3.1.8", - "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.8.tgz", - "integrity": "sha512-itaWrbYbqpGXkGhZPGUulwnhVf5Hpy1xiCFsGqyIGglbBxmG5vSjxQen3/WGOjPpNEv1RtBLKxbmVXm8HpJStQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "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": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/array-union": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", - "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/array.prototype.findlastindex": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.5.tgz", - "integrity": "sha512-zfETvRFA8o7EiNn++N5f/kaCw221hrpGsDmcpndVupkPzEc1Wuf3VgC0qby1BbHs7f5DVYjgtEU2LLh5bqeGfQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "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" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "engines": { + "node": ">=14" } }, - "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==", - "dev": true, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "license": "Python-2.0" + }, + "node_modules/array-buffer-byte-length": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.1.tgz", + "integrity": "sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==", "license": "MIT", "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.5", + "is-array-buffer": "^3.0.4" }, "engines": { "node": ">= 0.4" @@ -2624,23 +3030,27 @@ "url": "https://github.com/sponsors/ljharb" } }, - "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==", + "node_modules/array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==", + "license": "MIT" + }, + "node_modules/array-timsort": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/array-timsort/-/array-timsort-1.0.3.tgz", + "integrity": "sha512-/+3GRL7dDAGEfM6TseQk/U+mi18TU2Ms9I3UlLdUMhz2hbvGNTKdj9xniwXfUqgYhHxRx0+8UnKkvlNwVU+cWQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", "dev": true, "license": "MIT", - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "es-shim-unscopables": "^1.0.0" - }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=8" } }, "node_modules/arraybuffer.prototype.slice": { @@ -2678,9 +3088,9 @@ } }, "node_modules/ast-types/node_modules/tslib": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", - "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==", + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.7.0.tgz", + "integrity": "sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==", "license": "0BSD" }, "node_modules/astral-regex": { @@ -2694,9 +3104,9 @@ } }, "node_modules/async": { - "version": "3.2.5", - "resolved": "https://registry.npmjs.org/async/-/async-3.2.5.tgz", - "integrity": "sha512-baNZyqaaLhyLVKm/DlvdW051MSgO6b8eVfIezl9E5PqWxFgzLm/wQntEW4zOytVburDEr0JlALEpdOFwvErLsg==", + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.6.tgz", + "integrity": "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==", "license": "MIT" }, "node_modules/asynckit": { @@ -2814,24 +3224,27 @@ } }, "node_modules/babel-preset-current-node-syntax": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz", - "integrity": "sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.1.0.tgz", + "integrity": "sha512-ldYss8SbBlWva1bs28q78Ju5Zq1F+8BrqBZZ0VFhLBvhh6lCpC2o3gDJi/5DRLs9FgYZCnmPYIVFU4lRXCkyUw==", "dev": true, "license": "MIT", "dependencies": { "@babel/plugin-syntax-async-generators": "^7.8.4", "@babel/plugin-syntax-bigint": "^7.8.3", - "@babel/plugin-syntax-class-properties": "^7.8.3", - "@babel/plugin-syntax-import-meta": "^7.8.3", + "@babel/plugin-syntax-class-properties": "^7.12.13", + "@babel/plugin-syntax-class-static-block": "^7.14.5", + "@babel/plugin-syntax-import-attributes": "^7.24.7", + "@babel/plugin-syntax-import-meta": "^7.10.4", "@babel/plugin-syntax-json-strings": "^7.8.3", - "@babel/plugin-syntax-logical-assignment-operators": "^7.8.3", + "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", - "@babel/plugin-syntax-numeric-separator": "^7.8.3", + "@babel/plugin-syntax-numeric-separator": "^7.10.4", "@babel/plugin-syntax-object-rest-spread": "^7.8.3", "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", "@babel/plugin-syntax-optional-chaining": "^7.8.3", - "@babel/plugin-syntax-top-level-await": "^7.8.3" + "@babel/plugin-syntax-private-property-in-object": "^7.14.5", + "@babel/plugin-syntax-top-level-await": "^7.14.5" }, "peerDependencies": { "@babel/core": "^7.0.0" @@ -2935,9 +3348,9 @@ "license": "MIT" }, "node_modules/body-parser": { - "version": "1.20.2", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.2.tgz", - "integrity": "sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==", + "version": "1.20.3", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.3.tgz", + "integrity": "sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==", "license": "MIT", "dependencies": { "bytes": "3.1.2", @@ -2948,7 +3361,7 @@ "http-errors": "2.0.0", "iconv-lite": "0.4.24", "on-finished": "2.4.1", - "qs": "6.11.0", + "qs": "6.13.0", "raw-body": "2.5.2", "type-is": "~1.6.18", "unpipe": "1.0.0" @@ -3015,9 +3428,9 @@ } }, "node_modules/browserslist": { - "version": "4.23.1", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.1.tgz", - "integrity": "sha512-TUfofFo/KsK/bWZ9TWQ5O26tsWW4Uhmt8IYklbnUa70udB6P2wA7w7o4PY4muaEPBQaAX+CEnmmIA41NVHtPVw==", + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.0.tgz", + "integrity": "sha512-Rmb62sR1Zpjql25eSanFGEhAxcFwfA1K0GuQcLoaJBAcENegrQut3hYdhXFF1obQfiDyqIW/cLM5HSJ/9k884A==", "dev": true, "funding": [ { @@ -3035,10 +3448,10 @@ ], "license": "MIT", "dependencies": { - "caniuse-lite": "^1.0.30001629", - "electron-to-chromium": "^1.4.796", - "node-releases": "^2.0.14", - "update-browserslist-db": "^1.0.16" + "caniuse-lite": "^1.0.30001663", + "electron-to-chromium": "^1.5.28", + "node-releases": "^2.0.18", + "update-browserslist-db": "^1.1.0" }, "bin": { "browserslist": "cli.js" @@ -3073,19 +3486,6 @@ "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", "license": "MIT" }, - "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==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/bytes": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", @@ -3163,9 +3563,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001638", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001638.tgz", - "integrity": "sha512-5SuJUJ7cZnhPpeLHaH0c/HPAnAHZvS6ElWyHK9GSIbVOQABLzowiI2pjmpvZ1WEbkyz46iFd4UXlOHR5SqgfMQ==", + "version": "1.0.30001664", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001664.tgz", + "integrity": "sha512-AmE7k4dXiNKQipgn7a2xg558IRqPN3jMQY/rOsbxDhrd0tyChwbITBfiwtnqz8bi2M5mIWbxAYBvk7W7QBUS2g==", "dev": true, "funding": [ { @@ -3199,6 +3599,35 @@ "url": "https://github.com/chalk/chalk?sponsor=1" } }, + "node_modules/chalk-template": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/chalk-template/-/chalk-template-1.1.0.tgz", + "integrity": "sha512-T2VJbcDuZQ0Tb2EWwSotMPJjgpy1/tGee1BTpUNsGZ/qgNjV2t7Mvu+d4600U564nbLesN1x2dPL+xii174Ekg==", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^5.2.0" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/chalk/chalk-template?sponsor=1" + } + }, + "node_modules/chalk-template/node_modules/chalk": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", + "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, "node_modules/char-regex": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", @@ -3252,9 +3681,9 @@ } }, "node_modules/ci-info": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.0.0.tgz", - "integrity": "sha512-TdHqgGf9odd8SXNuxtUBVx8Nv+qZOejE6qyqiy5NtbYYQOeFa6zmHkxlPzmaLxWWHsU6nJmB7AETdVPi+2NBUg==", + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", + "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", "dev": true, "funding": [ { @@ -3268,9 +3697,9 @@ } }, "node_modules/cjs-module-lexer": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.3.1.tgz", - "integrity": "sha512-a3KdPAANPbNE4ZUv9h6LckSl9zLsYOP4MBmhIPkRaeyybt+r4UghLvq+xw/YwUcC1gqylCkL4rdVs3Lwupjm4Q==", + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.4.1.tgz", + "integrity": "sha512-cuSVIHi9/9E/+821Qjdvngor+xpnlwnuwIyZOaLmHBVdXL+gP+I6QQB9VkO7RI77YIcTV+S1W9AreJ5eN63JBA==", "dev": true, "license": "MIT" }, @@ -3285,40 +3714,34 @@ "node": ">=0.3.6" } }, - "node_modules/clean-regexp": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/clean-regexp/-/clean-regexp-1.0.0.tgz", - "integrity": "sha512-GfisEZEJvzKrmGWkvfhgzcz/BllN1USeqD2V6tg14OAOgaCD2Z/PUEuxnAZ/nPvmaHRG7a8y77p1T/IRQ4D1Hw==", + "node_modules/clear-module": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/clear-module/-/clear-module-4.1.2.tgz", + "integrity": "sha512-LWAxzHqdHsAZlPlEyJ2Poz6AIs384mPeqLVCru2p0BrP9G/kVGuhNyZYClLO6cXlnuJjzC8xtsJIuMjKqLXoAw==", "dev": true, "license": "MIT", "dependencies": { - "escape-string-regexp": "^1.0.5" + "parent-module": "^2.0.0", + "resolve-from": "^5.0.0" }, "engines": { - "node": ">=4" - } - }, - "node_modules/clean-regexp/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, - "license": "MIT", - "engines": { - "node": ">=0.8.0" + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/cli-cursor": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-4.0.0.tgz", - "integrity": "sha512-VGtlMu3x/4DOtIUwEkRezxUZ2lBacNJCHash0N0WeZDBS+7Ux1dm3XWAgWYxLJFMMdOeXMHXorshEFhbMSGelg==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-5.0.0.tgz", + "integrity": "sha512-aCj4O5wKyszjMmDT4tZj93kxyydN/K5zPWSCe6/0AV/AA1pqe5ZBIw0a2ZfPQV7lL5/yb5HsUreJ6UFAF1tEQw==", "dev": true, "license": "MIT", "dependencies": { - "restore-cursor": "^4.0.0" + "restore-cursor": "^5.0.0" }, "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -3380,6 +3803,16 @@ "node": ">=12" } }, + "node_modules/cliui/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/cliui/node_modules/emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", @@ -3412,6 +3845,19 @@ "node": ">=8" } }, + "node_modules/cliui/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/cliui/node_modules/wrap-ansi": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", @@ -3506,10 +3952,28 @@ } }, "node_modules/commander": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", - "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", + "version": "12.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-12.1.0.tgz", + "integrity": "sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/comment-json": { + "version": "4.2.5", + "resolved": "https://registry.npmjs.org/comment-json/-/comment-json-4.2.5.tgz", + "integrity": "sha512-bKw/r35jR3HGt5PEPm1ljsQQGyCrR8sFGNiN5L+ykDHdpO8Smxkrkla9Yi6NkQyUrb8V54PGhfMs6NrIwtxtdw==", + "dev": true, "license": "MIT", + "dependencies": { + "array-timsort": "^1.0.3", + "core-util-is": "^1.0.3", + "esprima": "^4.0.1", + "has-own-prop": "^2.0.0", + "repeat-string": "^1.6.1" + }, "engines": { "node": ">= 6" } @@ -3586,19 +4050,12 @@ "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==", "license": "MIT" }, - "node_modules/core-js-compat": { - "version": "3.37.1", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.37.1.tgz", - "integrity": "sha512-9TNiImhKvQqSUkOvk/mMRZzOANTiEVC7WaBNhHcKM7x+/5E1l5NvsysR19zuDQScE8k+kfQXWRN3AtS/eOSHpg==", + "node_modules/core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", "dev": true, - "license": "MIT", - "dependencies": { - "browserslist": "^4.23.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/core-js" - } + "license": "MIT" }, "node_modules/cors": { "version": "2.8.5", @@ -3640,6 +4097,16 @@ } } }, + "node_modules/cosmiconfig/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, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/create-jest": { "version": "29.7.0", "resolved": "https://registry.npmjs.org/create-jest/-/create-jest-29.7.0.tgz", @@ -3647,39 +4114,236 @@ "dev": true, "license": "MIT", "dependencies": { - "@jest/types": "^29.6.3", - "chalk": "^4.0.0", - "exit": "^0.1.2", - "graceful-fs": "^4.2.9", - "jest-config": "^29.7.0", - "jest-util": "^29.7.0", - "prompts": "^2.0.1" - }, - "bin": { - "create-jest": "bin/create-jest.js" + "@jest/types": "^29.6.3", + "chalk": "^4.0.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.9", + "jest-config": "^29.7.0", + "jest-util": "^29.7.0", + "prompts": "^2.0.1" + }, + "bin": { + "create-jest": "bin/create-jest.js" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/croner": { + "version": "4.1.97", + "resolved": "https://registry.npmjs.org/croner/-/croner-4.1.97.tgz", + "integrity": "sha512-/f6gpQuxDaqXu+1kwQYSckUglPaOrHdbIlBAu0YuW8/Cdb45XwXYNUBXg3r/9Mo6n540Kn/smKcZWko5x99KrQ==", + "license": "MIT" + }, + "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==", + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/cspell": { + "version": "8.14.4", + "resolved": "https://registry.npmjs.org/cspell/-/cspell-8.14.4.tgz", + "integrity": "sha512-R5Awb3i/RKaVVcZzFt8dkN3M6VnifIEDYBcbzbmYjZ/Eq+ASF+QTmI0E9WPhMEcFM1nd7YOyXnETo560yRdoKw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@cspell/cspell-json-reporter": "8.14.4", + "@cspell/cspell-pipe": "8.14.4", + "@cspell/cspell-types": "8.14.4", + "@cspell/dynamic-import": "8.14.4", + "@cspell/url": "8.14.4", + "chalk": "^5.3.0", + "chalk-template": "^1.1.0", + "commander": "^12.1.0", + "cspell-dictionary": "8.14.4", + "cspell-gitignore": "8.14.4", + "cspell-glob": "8.14.4", + "cspell-io": "8.14.4", + "cspell-lib": "8.14.4", + "fast-glob": "^3.3.2", + "fast-json-stable-stringify": "^2.1.0", + "file-entry-cache": "^9.1.0", + "get-stdin": "^9.0.0", + "semver": "^7.6.3", + "strip-ansi": "^7.1.0" + }, + "bin": { + "cspell": "bin.mjs", + "cspell-esm": "bin.mjs" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/streetsidesoftware/cspell?sponsor=1" + } + }, + "node_modules/cspell-config-lib": { + "version": "8.14.4", + "resolved": "https://registry.npmjs.org/cspell-config-lib/-/cspell-config-lib-8.14.4.tgz", + "integrity": "sha512-cnUeJfniTiebqCaQmIUnbSrPrTH7xzKRQjJDHAEV0WYnOG2MhRXI13OzytdFdhkVBdStmgTzTCJKE7x+kmU2NA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@cspell/cspell-types": "8.14.4", + "comment-json": "^4.2.5", + "yaml": "^2.5.1" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/cspell-dictionary": { + "version": "8.14.4", + "resolved": "https://registry.npmjs.org/cspell-dictionary/-/cspell-dictionary-8.14.4.tgz", + "integrity": "sha512-pZvQHxpAW5fZAnt3ZKKy3s7M+3CX2t8tCS3uJrpEHIynlCawpG0fPF78rVE5o+g0dON36Lguc/BUuSN4IWKLmQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@cspell/cspell-pipe": "8.14.4", + "@cspell/cspell-types": "8.14.4", + "cspell-trie-lib": "8.14.4", + "fast-equals": "^5.0.1" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/cspell-gitignore": { + "version": "8.14.4", + "resolved": "https://registry.npmjs.org/cspell-gitignore/-/cspell-gitignore-8.14.4.tgz", + "integrity": "sha512-RwfQEW5hD7CpYwS7m3b0ONG0nTLKP6bL2tvMdl7qtaYkL7ztGdsBTtLD1pmwqUsCbiN5RuaOxhYOYeRcpFRIkQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@cspell/url": "8.14.4", + "cspell-glob": "8.14.4", + "cspell-io": "8.14.4", + "find-up-simple": "^1.0.0" + }, + "bin": { + "cspell-gitignore": "bin.mjs" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/cspell-glob": { + "version": "8.14.4", + "resolved": "https://registry.npmjs.org/cspell-glob/-/cspell-glob-8.14.4.tgz", + "integrity": "sha512-C/xTS5nujMRMuguibq92qMVP767mtxrur7DcVolCvpzcivm1RB5NtIN0OctQxTyMbnmKeQv1t4epRKQ9A8vWRg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@cspell/url": "8.14.4", + "micromatch": "^4.0.8" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/cspell-grammar": { + "version": "8.14.4", + "resolved": "https://registry.npmjs.org/cspell-grammar/-/cspell-grammar-8.14.4.tgz", + "integrity": "sha512-yaSKAAJDiamsw3FChbw4HXb2RvTQrDsLelh1+T4MavarOIcAxXrqAJ8ysqm++g+S/ooJz2YO8YWIyzJKxcMf8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@cspell/cspell-pipe": "8.14.4", + "@cspell/cspell-types": "8.14.4" + }, + "bin": { + "cspell-grammar": "bin.mjs" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/cspell-io": { + "version": "8.14.4", + "resolved": "https://registry.npmjs.org/cspell-io/-/cspell-io-8.14.4.tgz", + "integrity": "sha512-o6OTWRyx/Az+PFhr1B0wMAwqG070hFC9g73Fkxd8+rHX0rfRS69QZH7LgSmZytqbZIMxCTDGdsLl33MFGWCbZQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@cspell/cspell-service-bus": "8.14.4", + "@cspell/url": "8.14.4" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": ">=18" } }, - "node_modules/croner": { - "version": "4.1.97", - "resolved": "https://registry.npmjs.org/croner/-/croner-4.1.97.tgz", - "integrity": "sha512-/f6gpQuxDaqXu+1kwQYSckUglPaOrHdbIlBAu0YuW8/Cdb45XwXYNUBXg3r/9Mo6n540Kn/smKcZWko5x99KrQ==", - "license": "MIT" + "node_modules/cspell-lib": { + "version": "8.14.4", + "resolved": "https://registry.npmjs.org/cspell-lib/-/cspell-lib-8.14.4.tgz", + "integrity": "sha512-qdkUkKtm+nmgpA4jQbmQTuepDfjHBDWvs3zDuEwVIVFq/h8gnXrRr75gJ3RYdTy+vOOqHPoLLqgxyqkUUrUGXA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@cspell/cspell-bundled-dicts": "8.14.4", + "@cspell/cspell-pipe": "8.14.4", + "@cspell/cspell-resolver": "8.14.4", + "@cspell/cspell-types": "8.14.4", + "@cspell/dynamic-import": "8.14.4", + "@cspell/filetypes": "8.14.4", + "@cspell/strong-weak-map": "8.14.4", + "@cspell/url": "8.14.4", + "clear-module": "^4.1.2", + "comment-json": "^4.2.5", + "cspell-config-lib": "8.14.4", + "cspell-dictionary": "8.14.4", + "cspell-glob": "8.14.4", + "cspell-grammar": "8.14.4", + "cspell-io": "8.14.4", + "cspell-trie-lib": "8.14.4", + "env-paths": "^3.0.0", + "fast-equals": "^5.0.1", + "gensequence": "^7.0.0", + "import-fresh": "^3.3.0", + "resolve-from": "^5.0.0", + "vscode-languageserver-textdocument": "^1.0.12", + "vscode-uri": "^3.0.8", + "xdg-basedir": "^5.1.0" + }, + "engines": { + "node": ">=18" + } }, - "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==", + "node_modules/cspell-trie-lib": { + "version": "8.14.4", + "resolved": "https://registry.npmjs.org/cspell-trie-lib/-/cspell-trie-lib-8.14.4.tgz", + "integrity": "sha512-zu8EJ33CH+FA5lwTRGqS//Q6phO0qtgEmODMR1KPlD7WlrfTFMb3bWFsLo/tiv5hjpsn7CM6dYDAAgBOSkoyhQ==", + "dev": true, "license": "MIT", "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" + "@cspell/cspell-pipe": "8.14.4", + "@cspell/cspell-types": "8.14.4", + "gensequence": "^7.0.0" }, "engines": { - "node": ">= 8" + "node": ">=18" + } + }, + "node_modules/cspell/node_modules/chalk": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", + "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" } }, "node_modules/css-functions-list": { @@ -3720,25 +4384,18 @@ } }, "node_modules/cssstyle": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-4.0.1.tgz", - "integrity": "sha512-8ZYiJ3A/3OkDd093CBT/0UKDWry7ak4BdPTFP2+QEP7cmhouyq/Up709ASSj2cK02BbZiMgk7kYjZNS4QP5qrQ==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-4.1.0.tgz", + "integrity": "sha512-h66W1URKpBS5YMI/V8PyXvTMFT8SupJ1IzoIV8IeBC/ji8WVmrO8dGlTi+2dh6whmdk6BiKJLD/ZBkhWbcg6nA==", "dev": true, "license": "MIT", "dependencies": { - "rrweb-cssom": "^0.6.0" + "rrweb-cssom": "^0.7.1" }, "engines": { "node": ">=18" } }, - "node_modules/cssstyle/node_modules/rrweb-cssom": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/rrweb-cssom/-/rrweb-cssom-0.6.0.tgz", - "integrity": "sha512-APM0Gt1KoXBz0iIkkdB/kfvGOwC4UuJFeG/c+yV7wSc7q96cG/kJ0HiYCnzivD9SB53cLV1MlHFNfOuPaadYSw==", - "dev": true, - "license": "MIT" - }, "node_modules/culvert": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/culvert/-/culvert-0.1.2.tgz", @@ -3829,18 +4486,18 @@ } }, "node_modules/dayjs": { - "version": "1.11.11", - "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.11.tgz", - "integrity": "sha512-okzr3f11N6WuqYtZSvm+F776mB41wRZMhKP+hc34YdW+KmtYYK9iqvHSwo2k9FEH3fhGXvOPV6yz2IcSrfRUDg==", + "version": "1.11.13", + "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.13.tgz", + "integrity": "sha512-oaMBel6gjolK862uaPQOVTA7q3TZhuSvuMQAAglQDOWYO9A91IrAOUJEyKVlqJlHE0vq5p5UXxzdPfMH/x6xNg==", "license": "MIT" }, "node_modules/debug": { - "version": "4.3.5", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz", - "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==", + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", + "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", "license": "MIT", "dependencies": { - "ms": "2.1.2" + "ms": "^2.1.3" }, "engines": { "node": ">=6.0" @@ -4062,18 +4719,6 @@ "node": ">=8" } }, - "node_modules/doctrine": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", - "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", - "license": "Apache-2.0", - "dependencies": { - "esutils": "^2.0.2" - }, - "engines": { - "node": ">=6.0.0" - } - }, "node_modules/dom-serializer": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", @@ -4136,9 +4781,9 @@ "license": "MIT" }, "node_modules/electron": { - "version": "31.1.0", - "resolved": "https://registry.npmjs.org/electron/-/electron-31.1.0.tgz", - "integrity": "sha512-TBOwqLxSxnx6+pH6GMri7R3JPH2AkuGJHfWZS0p1HsmN+Qr1T9b0IRJnnehSd/3NZAmAre4ft9Ljec7zjyKFJA==", + "version": "31.6.0", + "resolved": "https://registry.npmjs.org/electron/-/electron-31.6.0.tgz", + "integrity": "sha512-J64VtIF8DI/zsGgoYd3p5LbxAWjt59tk2cBSHJNzVhzgiVgDyPFkBwsqmN4gUvyv+6l6+WoYpYmYdapr2o4bPw==", "hasInstallScript": true, "license": "MIT", "optional": true, @@ -4155,9 +4800,9 @@ } }, "node_modules/electron-to-chromium": { - "version": "1.4.814", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.814.tgz", - "integrity": "sha512-GVulpHjFu1Y9ZvikvbArHmAhZXtm3wHlpjTMcXNGKl4IQ4jMQjlnz8yMQYYqdLHKi/jEL2+CBC2akWVCoIGUdw==", + "version": "1.5.29", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.29.tgz", + "integrity": "sha512-PF8n2AlIhCKXQ+gTpiJi0VhcHDb69kYX4MtCiivctc2QD3XuNZ/XIOlbGzt7WAjjEev0TtaH6Cu3arZExm5DOw==", "dev": true, "license": "ISC" }, @@ -4175,16 +4820,16 @@ } }, "node_modules/emoji-regex": { - "version": "10.3.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.3.0.tgz", - "integrity": "sha512-QpLs9D9v9kArv4lfDEgg1X/gN5XLnf/A6l9cs8SPZLRZR3ZkY9+kwIQTxm+fsSej5UMYGE8fdoaZVIBlqG0XTw==", + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.4.0.tgz", + "integrity": "sha512-EC+0oUMY1Rqm4O6LLrgjtYDvcVYTy7chDnM4Q7030tP4Kwj3u/pR6gP9ygnp2CJMK5Gq+9Q2oqmrFJAz01DXjw==", "dev": true, "license": "MIT" }, "node_modules/encodeurl": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", + "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", "license": "MIT", "engines": { "node": ">= 0.8" @@ -4201,9 +4846,9 @@ } }, "node_modules/engine.io": { - "version": "6.5.5", - "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.5.5.tgz", - "integrity": "sha512-C5Pn8Wk+1vKBoHghJODM63yk8MvrO9EWZUfkAt5HAqIgPE4/8FF0PEGHXtEd40l223+cE5ABWuPzm38PHFXfMA==", + "version": "6.6.1", + "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.6.1.tgz", + "integrity": "sha512-NEpDCw9hrvBW+hVEOK4T7v0jFJ++KgtPl4jKFwsZVfG1XhS0dCrSb3VMb9gPAd7VAdW52VT1EnaNiU2vM8C0og==", "license": "MIT", "dependencies": { "@types/cookie": "^0.4.1", @@ -4222,9 +4867,9 @@ } }, "node_modules/engine.io-parser": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.2.2.tgz", - "integrity": "sha512-RcyUFKA93/CXH20l4SoVvzZfrSDMOTUS3bWVpTt2FuFP+XYrL8i8oonHP7WInRyVHXh0n/ORtoeiE1os+8qkSw==", + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.2.3.tgz", + "integrity": "sha512-HqD3yTBfnBxIrbnM1DoD6Pcq8NECnh8d4As1Qgh0z5Gg3jRRIqijury0CL3ghu/edArpUYiYqQiDUQBIs4np3Q==", "license": "MIT", "engines": { "node": ">=10.0.0" @@ -4239,6 +4884,27 @@ "node": ">= 0.6" } }, + "node_modules/engine.io/node_modules/ws": { + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz", + "integrity": "sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==", + "license": "MIT", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, "node_modules/enquirer": { "version": "2.3.6", "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", @@ -4264,13 +4930,29 @@ } }, "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==", - "devOptional": true, + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-3.0.0.tgz", + "integrity": "sha512-dtJUTepzMW3Lm/NPxRf3wP4642UWhjL2sQxc+ym2YMj1m/H2zDNQOlezafzkHwn6sMstjHTwG6iQQsctDW/b1A==", + "dev": true, "license": "MIT", "engines": { - "node": ">=6" + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/environment": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/environment/-/environment-1.1.0.tgz", + "integrity": "sha512-xUtoPkMggbz0MPyPiIWr1Kp4aeWJjDZ6SMvURhimjdZgsRuDplF5/s9hcgGhyXMhs+6vpnuoiZ2kFiu3FMnS8Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/envsub": { @@ -4306,6 +4988,15 @@ "node": ">=8" } }, + "node_modules/envsub/node_modules/commander": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", + "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, "node_modules/error-ex": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", @@ -4430,16 +5121,6 @@ "node": ">= 0.4" } }, - "node_modules/es-shim-unscopables": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.2.tgz", - "integrity": "sha512-J3yBRXCzDu4ULnQwxyToo/OjdMx6akgVC7K6few0a7F/0wLtmKKN7I73AH5T2836UuXRqN7Qg+IIUw/+YJksRw==", - "dev": true, - "license": "MIT", - "dependencies": { - "hasown": "^2.0.0" - } - }, "node_modules/es-to-primitive": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", @@ -4465,9 +5146,9 @@ "optional": true }, "node_modules/escalade": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz", - "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", "dev": true, "license": "MIT", "engines": { @@ -4480,247 +5161,115 @@ "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", "license": "MIT" }, - "node_modules/escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/escodegen": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.1.0.tgz", - "integrity": "sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==", - "license": "BSD-2-Clause", - "dependencies": { - "esprima": "^4.0.1", - "estraverse": "^5.2.0", - "esutils": "^2.0.2" - }, - "bin": { - "escodegen": "bin/escodegen.js", - "esgenerate": "bin/esgenerate.js" - }, - "engines": { - "node": ">=6.0" - }, - "optionalDependencies": { - "source-map": "~0.6.1" - } - }, - "node_modules/eslint": { - "version": "8.57.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.0.tgz", - "integrity": "sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==", - "license": "MIT", - "dependencies": { - "@eslint-community/eslint-utils": "^4.2.0", - "@eslint-community/regexpp": "^4.6.1", - "@eslint/eslintrc": "^2.1.4", - "@eslint/js": "8.57.0", - "@humanwhocodes/config-array": "^0.11.14", - "@humanwhocodes/module-importer": "^1.0.1", - "@nodelib/fs.walk": "^1.2.8", - "@ungap/structured-clone": "^1.2.0", - "ajv": "^6.12.4", - "chalk": "^4.0.0", - "cross-spawn": "^7.0.2", - "debug": "^4.3.2", - "doctrine": "^3.0.0", - "escape-string-regexp": "^4.0.0", - "eslint-scope": "^7.2.2", - "eslint-visitor-keys": "^3.4.3", - "espree": "^9.6.1", - "esquery": "^1.4.2", - "esutils": "^2.0.2", - "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^6.0.1", - "find-up": "^5.0.0", - "glob-parent": "^6.0.2", - "globals": "^13.19.0", - "graphemer": "^1.4.0", - "ignore": "^5.2.0", - "imurmurhash": "^0.1.4", - "is-glob": "^4.0.0", - "is-path-inside": "^3.0.3", - "js-yaml": "^4.1.0", - "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.4.1", - "lodash.merge": "^4.6.2", - "minimatch": "^3.1.2", - "natural-compare": "^1.4.0", - "optionator": "^0.9.3", - "strip-ansi": "^6.0.1", - "text-table": "^0.2.0" - }, - "bin": { - "eslint": "bin/eslint.js" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint-import-resolver-node": { - "version": "0.3.9", - "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz", - "integrity": "sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==", - "dev": true, - "license": "MIT", - "dependencies": { - "debug": "^3.2.7", - "is-core-module": "^2.13.0", - "resolve": "^1.22.4" - } - }, - "node_modules/eslint-import-resolver-node/node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ms": "^2.1.1" - } - }, - "node_modules/eslint-module-utils": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.8.1.tgz", - "integrity": "sha512-rXDXR3h7cs7dy9RNpUlQf80nX31XWJEyGq1tRMo+6GsO5VmTe4UTwtmonAD4ZkAsrfMVDA2wlGJ3790Ys+D49Q==", - "dev": true, - "license": "MIT", - "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, - "license": "MIT", - "dependencies": { - "ms": "^2.1.1" - } - }, - "node_modules/eslint-plugin-import": { - "version": "2.29.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.29.1.tgz", - "integrity": "sha512-BbPC0cuExzhiMo4Ff1BTVwHpjjv28C5R+btTOGaCRC7UEz801up0JadwkeSk5Ued6TG34uaczuVuH6qyy5YUxw==", - "dev": true, - "license": "MIT", - "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", - "eslint-import-resolver-node": "^0.3.9", - "eslint-module-utils": "^2.8.0", - "hasown": "^2.0.0", - "is-core-module": "^2.13.1", - "is-glob": "^4.0.3", - "minimatch": "^3.1.2", - "object.fromentries": "^2.0.7", - "object.groupby": "^1.0.1", - "object.values": "^1.1.7", - "semver": "^6.3.1", - "tsconfig-paths": "^3.15.0" - }, - "engines": { - "node": ">=4" - }, - "peerDependencies": { - "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8" - } - }, - "node_modules/eslint-plugin-import/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "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, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", "license": "MIT", - "dependencies": { - "ms": "^2.1.1" + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/eslint-plugin-import/node_modules/doctrine": { + "node_modules/escodegen": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", - "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", - "dev": true, - "license": "Apache-2.0", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.1.0.tgz", + "integrity": "sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==", + "license": "BSD-2-Clause", "dependencies": { + "esprima": "^4.0.1", + "estraverse": "^5.2.0", "esutils": "^2.0.2" }, + "bin": { + "escodegen": "bin/escodegen.js", + "esgenerate": "bin/esgenerate.js" + }, "engines": { - "node": ">=0.10.0" + "node": ">=6.0" + }, + "optionalDependencies": { + "source-map": "~0.6.1" } }, - "node_modules/eslint-plugin-import/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "license": "ISC", + "node_modules/eslint": { + "version": "9.11.1", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.11.1.tgz", + "integrity": "sha512-MobhYKIoAO1s1e4VUrgx1l1Sk2JBR/Gqjjgw8+mfgoLE2xwsHur4gdfTxyTgShrhvdVFTaJSgMiQBl1jv/AWxg==", + "license": "MIT", "dependencies": { - "brace-expansion": "^1.1.7" + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.11.0", + "@eslint/config-array": "^0.18.0", + "@eslint/core": "^0.6.0", + "@eslint/eslintrc": "^3.1.0", + "@eslint/js": "9.11.1", + "@eslint/plugin-kit": "^0.2.0", + "@humanwhocodes/module-importer": "^1.0.1", + "@humanwhocodes/retry": "^0.3.0", + "@nodelib/fs.walk": "^1.2.8", + "@types/estree": "^1.0.6", + "@types/json-schema": "^7.0.15", + "ajv": "^6.12.4", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.3.2", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^8.0.2", + "eslint-visitor-keys": "^4.0.0", + "espree": "^10.1.0", + "esquery": "^1.5.0", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^8.0.0", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "is-path-inside": "^3.0.3", + "json-stable-stringify-without-jsonify": "^1.0.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" }, - "engines": { - "node": "*" - } - }, - "node_modules/eslint-plugin-import/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, - "license": "ISC", "bin": { - "semver": "bin/semver.js" + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://eslint.org/donate" + }, + "peerDependencies": { + "jiti": "*" + }, + "peerDependenciesMeta": { + "jiti": { + "optional": true + } } }, "node_modules/eslint-plugin-jest": { - "version": "28.6.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-28.6.0.tgz", - "integrity": "sha512-YG28E1/MIKwnz+e2H7VwYPzHUYU4aMa19w0yGcwXnnmJH6EfgHahTJ2un3IyraUxNfnz/KUhJAFXNNwWPo12tg==", + "version": "28.8.3", + "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-28.8.3.tgz", + "integrity": "sha512-HIQ3t9hASLKm2IhIOqnu+ifw7uLZkIlR7RYNv7fMcEi/p0CIiJmfriStQS2LDkgtY4nyLbIZAD+JL347Yc2ETQ==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/utils": "^6.0.0 || ^7.0.0" + "@typescript-eslint/utils": "^6.0.0 || ^7.0.0 || ^8.0.0" }, "engines": { "node": "^16.10.0 || ^18.12.0 || >=20.0.0" }, "peerDependencies": { - "@typescript-eslint/eslint-plugin": "^6.0.0 || ^7.0.0", + "@typescript-eslint/eslint-plugin": "^6.0.0 || ^7.0.0 || ^8.0.0", "eslint": "^7.0.0 || ^8.0.0 || ^9.0.0", "jest": "*" }, @@ -4734,22 +5283,23 @@ } }, "node_modules/eslint-plugin-jsdoc": { - "version": "48.5.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-48.5.0.tgz", - "integrity": "sha512-ukXPNpGby3KjCveCizIS8t1EbuJEHYEu/tBg8GCbn/YbHcXwphyvYCdvRZ/oMRfTscGSSzfsWoZ+ZkAP0/6YMQ==", + "version": "50.3.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-50.3.0.tgz", + "integrity": "sha512-P7qDB/RckdKETpBM4CtjHRQ5qXByPmFhRi86sN3E+J+tySchq+RSOGGhI2hDIefmmKFuTi/1ACjqsnDJDDDfzg==", "dev": true, "license": "BSD-3-Clause", "dependencies": { - "@es-joy/jsdoccomment": "~0.43.1", + "@es-joy/jsdoccomment": "~0.48.0", "are-docs-informative": "^0.0.2", "comment-parser": "1.4.1", - "debug": "^4.3.4", + "debug": "^4.3.6", "escape-string-regexp": "^4.0.0", - "esquery": "^1.5.0", - "parse-imports": "^2.1.0", - "semver": "^7.6.2", + "espree": "^10.1.0", + "esquery": "^1.6.0", + "parse-imports": "^2.1.1", + "semver": "^7.6.3", "spdx-expression-parse": "^4.0.0", - "synckit": "^0.9.0" + "synckit": "^0.9.1" }, "engines": { "node": ">=18" @@ -4759,15 +5309,16 @@ } }, "node_modules/eslint-plugin-package-json": { - "version": "0.15.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-package-json/-/eslint-plugin-package-json-0.15.0.tgz", - "integrity": "sha512-XPPehRGjoN2YPnwH/Vo9GTBTTSoJ9uveqKr7tCDskgKwXjtAfMIw4NyGvmTq4GLlnl+cw0VeKTC75863f2DBFw==", + "version": "0.15.3", + "resolved": "https://registry.npmjs.org/eslint-plugin-package-json/-/eslint-plugin-package-json-0.15.3.tgz", + "integrity": "sha512-NRUh+f5orM2/SynPjZqqNqSahdG3qzG5nf8s2S5nEwkhRbEE78S6sSMVGoSmrrtbhcbvZmLVHguVds4lY3Cwkw==", "dev": true, "license": "MIT", "dependencies": { + "@altano/repository-tools": "^0.1.1", "detect-indent": "6.1.0", "detect-newline": "3.1.0", - "package-json-validator": "^0.6.3", + "package-json-validator": "^0.6.5", "semver": "^7.5.4", "sort-object-keys": "^1.1.3", "sort-package-json": "^1.57.0", @@ -4781,57 +5332,27 @@ "jsonc-eslint-parser": "^2.0.0" } }, - "node_modules/eslint-plugin-unicorn": { - "version": "54.0.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-unicorn/-/eslint-plugin-unicorn-54.0.0.tgz", - "integrity": "sha512-XxYLRiYtAWiAjPv6z4JREby1TAE2byBC7wlh0V4vWDCpccOSU1KovWV//jqPXF6bq3WKxqX9rdjoRQ1EhdmNdQ==", - "dev": true, - "license": "MIT", + "node_modules/eslint-scope": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.1.0.tgz", + "integrity": "sha512-14dSvlhaVhKKsa9Fx1l8A17s7ah7Ef7wCakJ10LYk6+GYmP9yDti2oq2SEwcyndt6knfcZyhyxwY3i9yL78EQw==", + "license": "BSD-2-Clause", "dependencies": { - "@babel/helper-validator-identifier": "^7.24.5", - "@eslint-community/eslint-utils": "^4.4.0", - "@eslint/eslintrc": "^3.0.2", - "ci-info": "^4.0.0", - "clean-regexp": "^1.0.0", - "core-js-compat": "^3.37.0", - "esquery": "^1.5.0", - "indent-string": "^4.0.0", - "is-builtin-module": "^3.2.1", - "jsesc": "^3.0.2", - "pluralize": "^8.0.0", - "read-pkg-up": "^7.0.1", - "regexp-tree": "^0.1.27", - "regjsparser": "^0.10.0", - "semver": "^7.6.1", - "strip-indent": "^3.0.0" + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" }, "engines": { - "node": ">=18.18" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { - "url": "https://github.com/sindresorhus/eslint-plugin-unicorn?sponsor=1" - }, - "peerDependencies": { - "eslint": ">=8.56.0" + "url": "https://opencollective.com/eslint" } }, - "node_modules/eslint-plugin-unicorn/node_modules/@eslint/eslintrc": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.1.0.tgz", - "integrity": "sha512-4Bfj15dVJdoy3RfZmmo86RK1Fwzn6SstsvK9JS+BaVKqC6QQQQyXekNaC+g+LKNgkQ+2VhGAzm6hO40AhMR3zQ==", - "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" - }, + "node_modules/eslint-visitor-keys": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.1.0.tgz", + "integrity": "sha512-Q7lok0mqMUSf5a/AdAZkA5a/gHcO6snwQClVNNvFKCAVlxXucdU8pKydU5ZVZjBx5xr37vGbFFWtLQYreLzrZg==", + "license": "Apache-2.0", "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, @@ -4839,11 +5360,10 @@ "url": "https://opencollective.com/eslint" } }, - "node_modules/eslint-plugin-unicorn/node_modules/ajv": { + "node_modules/eslint/node_modules/ajv": { "version": "6.12.6", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.1", @@ -4856,73 +5376,60 @@ "url": "https://github.com/sponsors/epoberezkin" } }, - "node_modules/eslint-plugin-unicorn/node_modules/brace-expansion": { + "node_modules/eslint/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/eslint/node_modules/brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, "license": "MIT", "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, - "node_modules/eslint-plugin-unicorn/node_modules/eslint-visitor-keys": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.0.0.tgz", - "integrity": "sha512-OtIRv/2GyiF6o/d8K7MYKKbXrOUBIK6SfkIRM4Z0dY3w+LiQ0vy3F57m0Z71bjbyeiWFiHJ8brqnmE6H6/jEuw==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint-plugin-unicorn/node_modules/espree": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/espree/-/espree-10.1.0.tgz", - "integrity": "sha512-M1M6CpiE6ffoigIOWYO9UDP8TMUw9kqb21tf+08IgDYjCsOvCuDt4jQcZmoYxx+w7zlKw9/N0KXfto+I8/FrXA==", - "dev": true, - "license": "BSD-2-Clause", + "node_modules/eslint/node_modules/file-entry-cache": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", + "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", + "license": "MIT", "dependencies": { - "acorn": "^8.12.0", - "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^4.0.0" + "flat-cache": "^4.0.0" }, "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" + "node": ">=16.0.0" } }, - "node_modules/eslint-plugin-unicorn/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, + "node_modules/eslint/node_modules/flat-cache": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", + "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", "license": "MIT", - "engines": { - "node": ">=18" + "dependencies": { + "flatted": "^3.2.9", + "keyv": "^4.5.4" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "engines": { + "node": ">=16" } }, - "node_modules/eslint-plugin-unicorn/node_modules/json-schema-traverse": { + "node_modules/eslint/node_modules/json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true, "license": "MIT" }, - "node_modules/eslint-plugin-unicorn/node_modules/minimatch": { + "node_modules/eslint/node_modules/minimatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, "license": "ISC", "dependencies": { "brace-expansion": "^1.1.7" @@ -4931,90 +5438,30 @@ "node": "*" } }, - "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==", - "license": "BSD-2-Clause", - "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^5.2.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint-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==", - "license": "Apache-2.0", - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint/node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/eslint/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "node_modules/eslint/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "license": "MIT", "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/eslint/node_modules/json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "license": "MIT" - }, - "node_modules/eslint/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "license": "ISC", - "dependencies": { - "brace-expansion": "^1.1.7" + "ansi-regex": "^5.0.1" }, "engines": { - "node": "*" + "node": ">=8" } }, "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.2.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-10.2.0.tgz", + "integrity": "sha512-upbkBJbckcCNBDBDXEbuhjbP68n+scUd3k/U2EkyM9nw+I/jPiL4cLF/Al06CF96wRltFda16sxDFrxsI1v0/g==", "license": "BSD-2-Clause", "dependencies": { - "acorn": "^8.9.0", + "acorn": "^8.12.0", "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^3.4.1" + "eslint-visitor-keys": "^4.1.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" @@ -5034,9 +5481,9 @@ } }, "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==", "license": "BSD-3-Clause", "dependencies": { "estraverse": "^5.1.0" @@ -5161,37 +5608,37 @@ } }, "node_modules/express": { - "version": "4.19.2", - "resolved": "https://registry.npmjs.org/express/-/express-4.19.2.tgz", - "integrity": "sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q==", + "version": "4.21.0", + "resolved": "https://registry.npmjs.org/express/-/express-4.21.0.tgz", + "integrity": "sha512-VqcNGcj/Id5ZT1LZ/cfihi3ttTn+NJmkli2eZADigjq29qTlWi/hAQ43t/VLPq8+UX06FCEx3ByOYet6ZFblng==", "license": "MIT", "dependencies": { "accepts": "~1.3.8", "array-flatten": "1.1.1", - "body-parser": "1.20.2", + "body-parser": "1.20.3", "content-disposition": "0.5.4", "content-type": "~1.0.4", "cookie": "0.6.0", "cookie-signature": "1.0.6", "debug": "2.6.9", "depd": "2.0.0", - "encodeurl": "~1.0.2", + "encodeurl": "~2.0.0", "escape-html": "~1.0.3", "etag": "~1.8.1", - "finalhandler": "1.2.0", + "finalhandler": "1.3.1", "fresh": "0.5.2", "http-errors": "2.0.0", - "merge-descriptors": "1.0.1", + "merge-descriptors": "1.0.3", "methods": "~1.1.2", "on-finished": "2.4.1", "parseurl": "~1.3.3", - "path-to-regexp": "0.1.7", + "path-to-regexp": "0.1.10", "proxy-addr": "~2.0.7", - "qs": "6.11.0", + "qs": "6.13.0", "range-parser": "~1.2.1", "safe-buffer": "5.2.1", - "send": "0.18.0", - "serve-static": "1.15.0", + "send": "0.19.0", + "serve-static": "1.16.2", "setprototypeof": "1.2.0", "statuses": "2.0.1", "type-is": "~1.6.18", @@ -5285,6 +5732,16 @@ "dev": true, "license": "Apache-2.0" }, + "node_modules/fast-equals": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/fast-equals/-/fast-equals-5.0.1.tgz", + "integrity": "sha512-WF1Wi8PwwSY7/6Kx0vKXtw8RwuSGoM1bvDaJbu7MxDlR1vovZjIAKrnzyrThgAjm6JDTu0fVgWXDlMGspodfoQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, "node_modules/fast-glob": { "version": "3.3.2", "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", @@ -5333,6 +5790,12 @@ "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", "license": "MIT" }, + "node_modules/fast-uri": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.2.tgz", + "integrity": "sha512-GR6f0hD7XXyNJa25Tb9BuIdN0tdr+0BMi6/CJPH3wJO1JjNG3n/VsSw38AwRdKZABm8lGbPfakLRkYzx2V9row==", + "license": "MIT" + }, "node_modules/fastest-levenshtein": { "version": "1.0.16", "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz", @@ -5392,15 +5855,16 @@ } }, "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": "9.1.0", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-9.1.0.tgz", + "integrity": "sha512-/pqPFG+FdxWQj+/WSuzXSDaNzxgTLr/OrR1QuqfEZzDakpdYE70PwUxL7BPUa8hpjbvY1+qvCl8k+8Tq34xJgg==", + "dev": true, "license": "MIT", "dependencies": { - "flat-cache": "^3.0.4" + "flat-cache": "^5.0.0" }, "engines": { - "node": "^10.12.0 || >=12.0.0" + "node": ">=18" } }, "node_modules/fill-range": { @@ -5416,13 +5880,13 @@ } }, "node_modules/finalhandler": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", - "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.1.tgz", + "integrity": "sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ==", "license": "MIT", "dependencies": { "debug": "2.6.9", - "encodeurl": "~1.0.2", + "encodeurl": "~2.0.0", "escape-html": "~1.0.3", "on-finished": "2.4.1", "parseurl": "~1.3.3", @@ -5464,18 +5928,31 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/find-up-simple": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/find-up-simple/-/find-up-simple-1.0.0.tgz", + "integrity": "sha512-q7Us7kcjj2VMePAa02hDAF6d+MzsdsAWEwYyOpwUtlerRBkOEPBCRZrAV4XfcSN8fHAgaD0hP7miwoay6DCprw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "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": "5.0.0", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-5.0.0.tgz", + "integrity": "sha512-JrqFmyUl2PnPi1OvLyTVHnQvwQ0S+e6lGSwu8OkAZlSaNIZciTY2H/cOOROxsBA1m/LZNHDsqAgDZt6akWcjsQ==", + "dev": true, "license": "MIT", "dependencies": { - "flatted": "^3.2.9", - "keyv": "^4.5.3", - "rimraf": "^3.0.2" + "flatted": "^3.3.1", + "keyv": "^4.5.4" }, "engines": { - "node": "^10.12.0 || >=12.0.0" + "node": ">=18" } }, "node_modules/flatted": { @@ -5485,9 +5962,9 @@ "license": "ISC" }, "node_modules/follow-redirects": { - "version": "1.15.6", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz", - "integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==", + "version": "1.15.9", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.9.tgz", + "integrity": "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==", "funding": [ { "type": "individual", @@ -5564,6 +6041,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true, "license": "ISC" }, "node_modules/fsevents": { @@ -5616,6 +6094,16 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/gensequence": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/gensequence/-/gensequence-7.0.0.tgz", + "integrity": "sha512-47Frx13aZh01afHJTB3zTtKIlFI6vWY+MYCN9Qpew6i52rfKjnhCF/l1YlC8UmEMvvntZZ6z4PiCcmyuedR2aQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, "node_modules/gensync": { "version": "1.0.0-beta.2", "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", @@ -5678,6 +6166,19 @@ "node": ">=8.0.0" } }, + "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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/get-stream": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", @@ -5788,6 +6289,7 @@ "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", "deprecated": "Glob versions prior to v9 are no longer supported", + "dev": true, "license": "ISC", "dependencies": { "fs.realpath": "^1.0.0", @@ -5820,6 +6322,7 @@ "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, "license": "MIT", "dependencies": { "balanced-match": "^1.0.0", @@ -5830,6 +6333,7 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, "license": "ISC", "dependencies": { "brace-expansion": "^1.1.7" @@ -5856,6 +6360,22 @@ "node": ">=10.0" } }, + "node_modules/global-directory": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/global-directory/-/global-directory-4.0.1.tgz", + "integrity": "sha512-wHTUcDUoZ1H5/0iVqEudYW4/kAlN5cZ3j/bXn0Dpbizl9iaUVeWSHqiOjsgk6OW2bkLclbBjzewBz6weQ1zA2Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "ini": "4.1.1" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/global-modules": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-2.0.0.tgz", @@ -5884,6 +6404,13 @@ "node": ">=6" } }, + "node_modules/global-prefix/node_modules/ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "dev": true, + "license": "ISC" + }, "node_modules/global-prefix/node_modules/which": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", @@ -5898,15 +6425,12 @@ } }, "node_modules/globals": { - "version": "13.24.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", - "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", + "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", "license": "MIT", - "dependencies": { - "type-fest": "^0.20.2" - }, "engines": { - "node": ">=8" + "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -5929,24 +6453,23 @@ } }, "node_modules/globby": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", - "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-10.0.0.tgz", + "integrity": "sha512-3LifW9M4joGZasyYPz2A1U74zbC/45fvpXUvO/9KbSa+VV0aGZarWkfdgKyR9sExNP0t0x0ss/UMJpNpcaTspw==", "dev": true, "license": "MIT", "dependencies": { + "@types/glob": "^7.1.1", "array-union": "^2.1.0", "dir-glob": "^3.0.1", - "fast-glob": "^3.2.9", - "ignore": "^5.2.0", - "merge2": "^1.4.1", + "fast-glob": "^3.0.3", + "glob": "^7.1.3", + "ignore": "^5.1.1", + "merge2": "^1.2.3", "slash": "^3.0.0" }, "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=8" } }, "node_modules/globjoin": { @@ -6000,12 +6523,6 @@ "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", "license": "ISC" }, - "node_modules/graphemer": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", - "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", - "license": "MIT" - }, "node_modules/handlebars": { "version": "4.7.8", "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.8.tgz", @@ -6045,6 +6562,16 @@ "node": ">=8" } }, + "node_modules/has-own-prop": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-own-prop/-/has-own-prop-2.0.0.tgz", + "integrity": "sha512-Pq0h+hvsVm6dDEa8x82GnLSYHOzNDt7f0ddFa3FqcQlgzEiptPqL+XrOJNavjOzSYiYWIrgeVYYgGlLmnxwilQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/has-property-descriptors": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", @@ -6117,13 +6644,6 @@ "node": ">=16.0.0" } }, - "node_modules/hosted-git-info": { - "version": "2.8.9", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", - "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", - "dev": true, - "license": "ISC" - }, "node_modules/html-encoding-sniffer": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-4.0.0.tgz", @@ -6266,13 +6786,13 @@ } }, "node_modules/husky": { - "version": "9.0.11", - "resolved": "https://registry.npmjs.org/husky/-/husky-9.0.11.tgz", - "integrity": "sha512-AB6lFlbwwyIqMdHYhwPe+kjOC3Oc5P3nThEoW/AaO2BX3vJDjWPFxYLxokUZOo6RNX20He3AaT8sESs9NJcmEw==", + "version": "9.1.6", + "resolved": "https://registry.npmjs.org/husky/-/husky-9.1.6.tgz", + "integrity": "sha512-sqbjZKK7kf44hfdE94EoX8MZNk0n7HeW37O4YrVGCF4wzgQjp+akPAkfUK5LZ6KuR/6sqeAVuXHji+RzQgOn5A==", "dev": true, "license": "MIT", "bin": { - "husky": "bin.mjs" + "husky": "bin.js" }, "engines": { "node": ">=18" @@ -6294,9 +6814,9 @@ } }, "node_modules/ignore": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", - "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==", + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", "license": "MIT", "engines": { "node": ">= 4" @@ -6318,10 +6838,31 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/import-fresh/node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "license": "MIT", + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/import-fresh/node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, "node_modules/import-local": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz", - "integrity": "sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.2.0.tgz", + "integrity": "sha512-2SPlun1JUPWoM6t3F0dw0FkCF/jWY8kttcY4f599GLTSjh2OCuuhdTkJQsEcZzBqbXZGKMK2OqW1oZsjtf/gQA==", "dev": true, "license": "MIT", "dependencies": { @@ -6338,6 +6879,17 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/import-meta-resolve": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/import-meta-resolve/-/import-meta-resolve-4.1.0.tgz", + "integrity": "sha512-I6fiaX09Xivtk+THaMfAwnA3MVA5Big1WHF1Dfx9hFuvNIWpXnorlkzhcQf6ehrqQiiZECRt1poOAkPmer3ruw==", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/imurmurhash": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", @@ -6347,21 +6899,12 @@ "node": ">=0.8.19" } }, - "node_modules/indent-string": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", - "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "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==", "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", + "dev": true, "license": "ISC", "dependencies": { "once": "^1.3.0", @@ -6375,10 +6918,14 @@ "license": "ISC" }, "node_modules/ini": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", - "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", - "license": "ISC" + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ini/-/ini-4.1.1.tgz", + "integrity": "sha512-QQnnxNyfvmHFIsj7gkPcYymR8Jdw/o7mp5ZFihxn6h8Ci6fh3Dx4E1gPjpQEpIuPo9XVNY/ZUwh4BPMjGyL01g==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } }, "node_modules/internal-slot": { "version": "1.0.7", @@ -6500,22 +7047,6 @@ "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==", - "dev": true, - "license": "MIT", - "dependencies": { - "builtin-modules": "^3.3.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/is-callable": { "version": "1.2.7", "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", @@ -6529,9 +7060,9 @@ } }, "node_modules/is-core-module": { - "version": "2.14.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.14.0.tgz", - "integrity": "sha512-a5dFJih5ZLYlRtDc0dZWP7RiKr6xIKzmn/oAYCDvdLThadVgyJwlaoQPmRtMSpz+rk0OGAgIu+TcM9HUF0fk1A==", + "version": "2.15.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.15.1.tgz", + "integrity": "sha512-z0vtXSwucUJtANQWldhbtbt7BnL0vxiFjIdDLAatwhDYty2bad6s+rijD6Ri4YuYJubLzIJLUidCh09e1djEVQ==", "license": "MIT", "dependencies": { "hasown": "^2.0.2" @@ -6813,9 +7344,9 @@ } }, "node_modules/istanbul-lib-instrument": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-6.0.2.tgz", - "integrity": "sha512-1WUsZ9R1lA0HtBSohTkm39WTPlNKSJ5iFk7UwqXkBLoHQT+hfqPsfsTDVuZdKGaBwn7din9bS7SsnoAr943hvw==", + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-6.0.3.tgz", + "integrity": "sha512-Vtgk7L/R2JHyyGW07spoFlB8/lpjiOLTjMdms6AFMraYt3BaJauod/NGrfnVG/y4Ix1JEuMRPDPEj2ua+zz1/Q==", "dev": true, "license": "BSD-3-Clause", "dependencies": { @@ -7027,22 +7558,6 @@ } } }, - "node_modules/jest-config/node_modules/ci-info": { - "version": "3.9.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", - "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/sibiraj-s" - } - ], - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/jest-diff": { "version": "29.7.0", "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.7.0.tgz", @@ -7389,22 +7904,6 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/jest-util/node_modules/ci-info": { - "version": "3.9.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", - "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/sibiraj-s" - } - ], - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/jest-util/node_modules/picomatch": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", @@ -7539,9 +8038,9 @@ "license": "MIT" }, "node_modules/jsdoc-type-pratt-parser": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsdoc-type-pratt-parser/-/jsdoc-type-pratt-parser-4.0.0.tgz", - "integrity": "sha512-YtOli5Cmzy3q4dP26GraSOeAhqecewG04hoO8DY56CH4KJ9Fvv5qKWUCCo3HZob7esJQHCv6/+bnTy72xZZaVQ==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/jsdoc-type-pratt-parser/-/jsdoc-type-pratt-parser-4.1.0.tgz", + "integrity": "sha512-Hicd6JK5Njt2QB6XYFS7ok9e37O8AYk3jTcppG4YVQnYjOemymvTcmc7OWsmq/Qqj5TdRFO5/x/tIPmBeRtGHg==", "dev": true, "license": "MIT", "engines": { @@ -7549,32 +8048,32 @@ } }, "node_modules/jsdom": { - "version": "24.1.0", - "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-24.1.0.tgz", - "integrity": "sha512-6gpM7pRXCwIOKxX47cgOyvyQDN/Eh0f1MeKySBV2xGdKtqJBLj8P25eY3EVCWo2mglDDzozR2r2MW4T+JiNUZA==", + "version": "25.0.1", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-25.0.1.tgz", + "integrity": "sha512-8i7LzZj7BF8uplX+ZyOlIz86V6TAsSs+np6m1kpW9u0JWi4z/1t+FzcK1aek+ybTnAC4KhBL4uXCNT0wcUIeCw==", "dev": true, "license": "MIT", "dependencies": { - "cssstyle": "^4.0.1", + "cssstyle": "^4.1.0", "data-urls": "^5.0.0", "decimal.js": "^10.4.3", "form-data": "^4.0.0", "html-encoding-sniffer": "^4.0.0", "http-proxy-agent": "^7.0.2", - "https-proxy-agent": "^7.0.4", + "https-proxy-agent": "^7.0.5", "is-potential-custom-element-name": "^1.0.1", - "nwsapi": "^2.2.10", + "nwsapi": "^2.2.12", "parse5": "^7.1.2", - "rrweb-cssom": "^0.7.0", + "rrweb-cssom": "^0.7.1", "saxes": "^6.0.0", "symbol-tree": "^3.2.4", - "tough-cookie": "^4.1.4", + "tough-cookie": "^5.0.0", "w3c-xmlserializer": "^5.0.0", "webidl-conversions": "^7.0.0", "whatwg-encoding": "^3.1.1", "whatwg-mimetype": "^4.0.0", "whatwg-url": "^14.0.0", - "ws": "^8.17.0", + "ws": "^8.18.0", "xml-name-validator": "^5.0.0" }, "engines": { @@ -7590,16 +8089,16 @@ } }, "node_modules/jsesc": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.0.2.tgz", - "integrity": "sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==", + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", "dev": true, "license": "MIT", "bin": { "jsesc": "bin/jsesc" }, "engines": { - "node": ">=6" + "node": ">=4" } }, "node_modules/json-buffer": { @@ -7667,6 +8166,39 @@ "url": "https://github.com/sponsors/ota-meshi" } }, + "node_modules/jsonc-eslint-parser/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, + "license": "Apache-2.0", + "peer": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/jsonc-eslint-parser/node_modules/espree": { + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", + "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", + "dev": true, + "license": "BSD-2-Clause", + "peer": true, + "dependencies": { + "acorn": "^8.9.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^3.4.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, "node_modules/jsonfile": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", @@ -7714,9 +8246,9 @@ } }, "node_modules/known-css-properties": { - "version": "0.31.0", - "resolved": "https://registry.npmjs.org/known-css-properties/-/known-css-properties-0.31.0.tgz", - "integrity": "sha512-sBPIUGTNF0czz0mwGGUoKKJC8Q7On1GPbCSFPfyEsfHb2DyBG0Y4QtV+EVWpINSaiGKZblDNuF5AezxSgOhesQ==", + "version": "0.34.0", + "resolved": "https://registry.npmjs.org/known-css-properties/-/known-css-properties-0.34.0.tgz", + "integrity": "sha512-tBECoUqNFbyAY4RrbqsBQqDFpGXAEbdD5QKr8kACx3+rnArmuuR22nKQWKazvp07N9yjTyDZaw/20UIH8tL9DQ==", "dev": true, "license": "MIT" }, @@ -7782,22 +8314,22 @@ "license": "MIT" }, "node_modules/lint-staged": { - "version": "15.2.7", - "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-15.2.7.tgz", - "integrity": "sha512-+FdVbbCZ+yoh7E/RosSdqKJyUM2OEjTciH0TFNkawKgvFp1zbGlEC39RADg+xKBG1R4mhoH2j85myBQZ5wR+lw==", + "version": "15.2.10", + "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-15.2.10.tgz", + "integrity": "sha512-5dY5t743e1byO19P9I4b3x8HJwalIznL5E1FWYnU6OWw33KxNBSLAc6Cy7F2PsFEO8FKnLwjwm5hx7aMF0jzZg==", "dev": true, "license": "MIT", "dependencies": { "chalk": "~5.3.0", "commander": "~12.1.0", - "debug": "~4.3.4", + "debug": "~4.3.6", "execa": "~8.0.1", - "lilconfig": "~3.1.1", - "listr2": "~8.2.1", - "micromatch": "~4.0.7", + "lilconfig": "~3.1.2", + "listr2": "~8.2.4", + "micromatch": "~4.0.8", "pidtree": "~0.6.0", "string-argv": "~0.3.2", - "yaml": "~2.4.2" + "yaml": "~2.5.0" }, "bin": { "lint-staged": "bin/lint-staged.js" @@ -7817,19 +8349,9 @@ "license": "MIT", "engines": { "node": "^12.17.0 || ^14.13 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/lint-staged/node_modules/commander": { - "version": "12.1.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-12.1.0.tgz", - "integrity": "sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=18" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" } }, "node_modules/lint-staged/node_modules/execa": { @@ -7977,16 +8499,16 @@ } }, "node_modules/listr2": { - "version": "8.2.3", - "resolved": "https://registry.npmjs.org/listr2/-/listr2-8.2.3.tgz", - "integrity": "sha512-Lllokma2mtoniUOS94CcOErHWAug5iu7HOmDrvWgpw8jyQH2fomgB+7lZS4HWZxytUuQwkGOwe49FvwVaA85Xw==", + "version": "8.2.4", + "resolved": "https://registry.npmjs.org/listr2/-/listr2-8.2.4.tgz", + "integrity": "sha512-opevsywziHd3zHCVQGAj8zu+Z3yHNkkoYhWIGnq54RrCVwLz0MozotJEDnKsIBLvkfLGN6BLOyAeRrYI0pKA4g==", "dev": true, "license": "MIT", "dependencies": { "cli-truncate": "^4.0.0", "colorette": "^2.0.20", "eventemitter3": "^5.0.1", - "log-update": "^6.0.0", + "log-update": "^6.1.0", "rfdc": "^1.4.1", "wrap-ansi": "^9.0.0" }, @@ -8036,15 +8558,15 @@ "license": "MIT" }, "node_modules/log-update": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/log-update/-/log-update-6.0.0.tgz", - "integrity": "sha512-niTvB4gqvtof056rRIrTZvjNYE4rCUzO6X/X+kYjd7WFxXeJ0NwEFnRxX6ehkvv3jTwrXnNdtAak5XYZuIyPFw==", + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/log-update/-/log-update-6.1.0.tgz", + "integrity": "sha512-9ie8ItPR6tjY5uYJh8K/Zrv/RMZ5VOlOWvtZdEHYSTFKZfIBPQa9tOAEeAWhd+AnIneLJ22w5fjOYtoutpWq5w==", "dev": true, "license": "MIT", "dependencies": { - "ansi-escapes": "^6.2.0", - "cli-cursor": "^4.0.0", - "slice-ansi": "^7.0.0", + "ansi-escapes": "^7.0.0", + "cli-cursor": "^5.0.0", + "slice-ansi": "^7.1.0", "strip-ansi": "^7.1.0", "wrap-ansi": "^9.0.0" }, @@ -8056,29 +8578,19 @@ } }, "node_modules/log-update/node_modules/ansi-escapes": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-6.2.1.tgz", - "integrity": "sha512-4nJ3yixlEthEJ9Rk4vPcdBRkZvQZlYyu8j4/Mqz5sgIkddmEnH2Yj2ZrnP9S3tQOvSNRUIgVNF/1yPpRAGNRig==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-7.0.0.tgz", + "integrity": "sha512-GdYO7a61mR0fOlAsvC9/rIHf7L96sBc6dEWzeOu+KAea5bZyQRPIpojrVoI4AXGJS/ycu/fBTdLrUkA4ODrvjw==", "dev": true, "license": "MIT", - "engines": { - "node": ">=14.16" + "dependencies": { + "environment": "^1.0.0" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/log-update/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==", - "dev": true, - "license": "MIT", "engines": { - "node": ">=12" + "node": ">=18" }, "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/log-update/node_modules/ansi-styles": { @@ -8127,22 +8639,6 @@ "url": "https://github.com/chalk/slice-ansi?sponsor=1" } }, - "node_modules/log-update/node_modules/strip-ansi": { - "version": "7.1.0", - "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" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" - } - }, "node_modules/lowercase-keys": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", @@ -8243,10 +8739,13 @@ } }, "node_modules/merge-descriptors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", - "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==", - "license": "MIT" + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.3.tgz", + "integrity": "sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, "node_modules/merge-stream": { "version": "2.0.0", @@ -8275,9 +8774,9 @@ } }, "node_modules/micromatch": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.7.tgz", - "integrity": "sha512-LPP/3KorzCwBxfeUuZmaR6bG2kdeHSbe0P2tY3FLRU4vYrjYz5hI4QZwV0njUx3jeuKe67YukQ1LSPZBKDqO/Q==", + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", "dev": true, "license": "MIT", "dependencies": { @@ -8344,30 +8843,33 @@ "node": ">=6" } }, - "node_modules/mimic-response": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", - "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==", + "node_modules/mimic-function": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/mimic-function/-/mimic-function-5.0.1.tgz", + "integrity": "sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA==", + "dev": true, "license": "MIT", - "optional": true, "engines": { - "node": ">=4" + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/min-indent": { + "node_modules/mimic-response": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", - "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==", - "dev": true, + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", + "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==", "license": "MIT", + "optional": true, "engines": { "node": ">=4" } }, "node_modules/minimatch": { - "version": "9.0.3", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", - "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", "dev": true, "license": "ISC", "dependencies": { @@ -8435,9 +8937,9 @@ } }, "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==", "license": "MIT" }, "node_modules/mute-stream": { @@ -8534,35 +9036,38 @@ } }, "node_modules/nise": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/nise/-/nise-6.0.0.tgz", - "integrity": "sha512-K8ePqo9BFvN31HXwEtTNGzgrPpmvgciDsFz8aztFjt4LqKO/JeFD8tBOeuDiCMXrIl/m1YvfH8auSpxfaD09wg==", + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/nise/-/nise-6.1.1.tgz", + "integrity": "sha512-aMSAzLVY7LyeM60gvBS423nBmIPP+Wy7St7hsb+8/fc1HmeoHJfLO8CKse4u3BtOZvQLJghYPI2i/1WZrEj5/g==", "dev": true, "license": "BSD-3-Clause", "dependencies": { - "@sinonjs/commons": "^3.0.0", - "@sinonjs/fake-timers": "^11.2.2", - "@sinonjs/text-encoding": "^0.7.2", + "@sinonjs/commons": "^3.0.1", + "@sinonjs/fake-timers": "^13.0.1", + "@sinonjs/text-encoding": "^0.7.3", "just-extend": "^6.2.0", - "path-to-regexp": "^6.2.1" + "path-to-regexp": "^8.1.0" } }, "node_modules/nise/node_modules/@sinonjs/fake-timers": { - "version": "11.2.2", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-11.2.2.tgz", - "integrity": "sha512-G2piCSxQ7oWOxwGSAyFHfPIsyeJGXYtc6mFbnFA+kRXkiEnTl8c/8jul2S329iFBnDI9HGoeWWAZvuvOkZccgw==", + "version": "13.0.2", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-13.0.2.tgz", + "integrity": "sha512-4Bb+oqXZTSTZ1q27Izly9lv8B9dlV61CROxPiVtywwzv5SnytJqhvYe6FclHYuXml4cd1VHPo1zd5PmTeJozvA==", "dev": true, "license": "BSD-3-Clause", "dependencies": { - "@sinonjs/commons": "^3.0.0" + "@sinonjs/commons": "^3.0.1" } }, "node_modules/nise/node_modules/path-to-regexp": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-6.2.2.tgz", - "integrity": "sha512-GQX3SSMokngb36+whdpRXE+3f9V8UzyAorlYvOGx87ufGHehNTn5lCxrKtLyZ4Yl/wEKnNnr98ZzOwwDZV5ogw==", + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.2.0.tgz", + "integrity": "sha512-TdrF7fW9Rphjq4RjrW0Kp2AW0Ahwu9sRGTkS6bvDi0SCwZlEZYmcfDbEsTz8RVk0EHIS/Vd1bv3JhG+1xZuAyQ==", "dev": true, - "license": "MIT" + "license": "MIT", + "engines": { + "node": ">=16" + } }, "node_modules/node-ical": { "version": "0.18.0", @@ -8584,35 +9089,12 @@ "license": "MIT" }, "node_modules/node-releases": { - "version": "2.0.14", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz", - "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==", + "version": "2.0.18", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.18.tgz", + "integrity": "sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==", "dev": true, "license": "MIT" }, - "node_modules/normalize-package-data": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", - "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "hosted-git-info": "^2.1.4", - "resolve": "^1.10.0", - "semver": "2 || 3 || 4 || 5", - "validate-npm-package-license": "^3.0.1" - } - }, - "node_modules/normalize-package-data/node_modules/semver": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", - "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver" - } - }, "node_modules/normalize-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", @@ -8668,9 +9150,9 @@ "license": "MIT" }, "node_modules/nwsapi": { - "version": "2.2.10", - "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.10.tgz", - "integrity": "sha512-QK0sRs7MKv0tKe1+5uZIQk/C8XGza4DAnztJG8iD+TpJIORARrCxczA738awHrZoHeTjSSoHqao2teO0dC/gFQ==", + "version": "2.2.13", + "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.13.tgz", + "integrity": "sha512-cTGB9ptp9dY9A5VbMSe7fQBcl/tt22Vcqdq8+eN93rblOuE0aCFu4aZ2vMwct/2t+lFnosm8RkQW1I0Omb1UtQ==", "dev": true, "license": "MIT" }, @@ -8722,58 +9204,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "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, - "license": "MIT", - "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" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/object.groupby": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/object.groupby/-/object.groupby-1.0.3.tgz", - "integrity": "sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/object.values": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.2.0.tgz", - "integrity": "sha512-yBYjY9QX2hnRmZHAjG/f13MzmBzxzYgQhFrke06TTyKY5zSTEqkOeukBzIdVA3j3ulu8Qa3MbVFShV7T2RmGtQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "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" - } - }, "node_modules/on-finished": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", @@ -8790,6 +9220,7 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "devOptional": true, "license": "ISC", "dependencies": { "wrappy": "1" @@ -8939,9 +9370,9 @@ } }, "node_modules/package-json-validator": { - "version": "0.6.4", - "resolved": "https://registry.npmjs.org/package-json-validator/-/package-json-validator-0.6.4.tgz", - "integrity": "sha512-sp5bWr5eUoVgNV50vsJyil0XCluM+qMvtba8X4ug5Z/0YtYZsePka+tZgqiZnAyFyf5pwXaSDwYncFdSEzX7PA==", + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/package-json-validator/-/package-json-validator-0.6.5.tgz", + "integrity": "sha512-fEG8kM+EfX0j7TbTWAv6/0NRkid0fUHm2afJx35en3+IlrJ6dRQfKUCpuUl/bGM6MvQ0MxAlpaXkJtYVMp0F4A==", "dev": true, "dependencies": { "optimist": "~0.6.0" @@ -8957,23 +9388,24 @@ "license": "MIT" }, "node_modules/parent-module": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-2.0.0.tgz", + "integrity": "sha512-uo0Z9JJeWzv8BG+tRcapBKNJ0dro9cLyczGzulS6EfeyAdeC9sbojtW6XwvYxJkEne9En+J2XEl4zyglVeIwFg==", + "dev": true, "license": "MIT", "dependencies": { - "callsites": "^3.0.0" + "callsites": "^3.1.0" }, "engines": { - "node": ">=6" + "node": ">=8" } }, "node_modules/parse-imports": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/parse-imports/-/parse-imports-2.1.0.tgz", - "integrity": "sha512-JQWgmK2o4w8leUkZeZPatWdAny6vXGU/3siIUvMF6J2rDCud9aTt8h/px9oZJ6U3EcfhngBJ635uPFI0q0VAeA==", + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/parse-imports/-/parse-imports-2.2.1.tgz", + "integrity": "sha512-OL/zLggRp8mFhKL0rNORUTR4yBYujK/uU+xZL+/0Rgm2QE4nLO9v8PzEweSJEbMGKmDRjJE4R3IMJlL2di4JeQ==", "dev": true, - "license": "Apache 2.0", + "license": "Apache-2.0 AND MIT", "dependencies": { "es-module-lexer": "^1.5.3", "slashes": "^3.0.12" @@ -9049,6 +9481,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" @@ -9070,9 +9503,9 @@ "license": "MIT" }, "node_modules/path-to-regexp": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", - "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==", + "version": "0.1.10", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.10.tgz", + "integrity": "sha512-7lf7qcQidTku0Gu3YDPc8DJ1q7OOucfa/BSsIwjuh56VU7katFvuM8hULfkwB3Fns/rsVF7PwPKVw1sl5KQS9w==", "license": "MIT" }, "node_modules/path-type": { @@ -9102,9 +9535,9 @@ "optional": true }, "node_modules/picocolors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz", - "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.0.tgz", + "integrity": "sha512-TQ92mBOW0l3LeMeyLV6mzy/kWr8lkd/hp3mTg7wYK7zJhuBStmGMBG0BdeDZS/dZx1IukaX6Bk11zcln25o1Aw==", "dev": true, "license": "ISC" }, @@ -9226,13 +9659,13 @@ } }, "node_modules/playwright": { - "version": "1.45.0", - "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.45.0.tgz", - "integrity": "sha512-4z3ac3plDfYzGB6r0Q3LF8POPR20Z8D0aXcxbJvmfMgSSq1hkcgvFRXJk9rUq5H/MJ0Ktal869hhOdI/zUTeLA==", + "version": "1.47.2", + "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.47.2.tgz", + "integrity": "sha512-nx1cLMmQWqmA3UsnjaaokyoUpdVaaDhJhMoxX2qj3McpjnsqFHs516QAKYhqHAgOP+oCFTEOCOAaD1RgD/RQfA==", "dev": true, "license": "Apache-2.0", "dependencies": { - "playwright-core": "1.45.0" + "playwright-core": "1.47.2" }, "bin": { "playwright": "cli.js" @@ -9245,9 +9678,9 @@ } }, "node_modules/playwright-core": { - "version": "1.45.0", - "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.45.0.tgz", - "integrity": "sha512-lZmHlFQ0VYSpAs43dRq1/nJ9G/6SiTI7VPqidld9TDefL9tX87bTKExWZZUF5PeRyqtXqd8fQi2qmfIedkwsNQ==", + "version": "1.47.2", + "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.47.2.tgz", + "integrity": "sha512-3JvMfF+9LJfe16l7AbSmU555PaTl2tPyQsVInqm3id16pdDfvZ8TTZ/pyzmkbDrZTQefyzU7AIHlZqQnxpqHVQ==", "dev": true, "license": "Apache-2.0", "bin": { @@ -9272,24 +9705,14 @@ "node": "^8.16.0 || ^10.6.0 || >=11.0.0" } }, - "node_modules/pluralize": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-8.0.0.tgz", - "integrity": "sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, "node_modules/pm2": { - "version": "5.4.1", - "resolved": "https://registry.npmjs.org/pm2/-/pm2-5.4.1.tgz", - "integrity": "sha512-y9ndADjy78XfzdbVHISn4WiUTrcvmsO7ieCtM/oC80rwPgBDg+bHkkz1e4eaLOW5a7sJsnDfQjJe4AqxNnIw5Q==", + "version": "5.4.2", + "resolved": "https://registry.npmjs.org/pm2/-/pm2-5.4.2.tgz", + "integrity": "sha512-ynVpBwZampRH3YWLwRepZpQ7X3MvpwLIaqIdFEeBYEhaXbHmEx2KqOdxGV4T54wvKBhH3LixvU1j1bK4/sq7Tw==", "license": "AGPL-3.0", "dependencies": { "@pm2/agent": "~2.0.0", - "@pm2/io": "~6.0.0", + "@pm2/io": "~6.0.1", "@pm2/js-api": "~0.8.0", "@pm2/pm2-version-check": "latest", "async": "~3.2.0", @@ -9446,9 +9869,9 @@ } }, "node_modules/postcss": { - "version": "8.4.38", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.38.tgz", - "integrity": "sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==", + "version": "8.4.47", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.47.tgz", + "integrity": "sha512-56rxCq7G/XfB4EkXq9Egn5GCqugWvDFjafDOThIdMBsI15iqPqR5r15TfSr1YPYeEI19YeaXMCbY6u88Y76GLQ==", "dev": true, "funding": [ { @@ -9467,17 +9890,17 @@ "license": "MIT", "dependencies": { "nanoid": "^3.3.7", - "picocolors": "^1.0.0", - "source-map-js": "^1.2.0" + "picocolors": "^1.1.0", + "source-map-js": "^1.2.1" }, "engines": { "node": "^10 || ^12 || >=14" } }, "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, "license": "MIT" }, @@ -9509,9 +9932,9 @@ } }, "node_modules/postcss-selector-parser": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.0.tgz", - "integrity": "sha512-UMz42UD0UY0EApS0ZL9o1XnLhSTtvvvLe5Dc2H2O56fvRZi+KulDyf5ctDhhtYJBGKStV2FL1fy6253cmLgqVQ==", + "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, "license": "MIT", "dependencies": { @@ -9539,9 +9962,9 @@ } }, "node_modules/prettier": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.3.2.tgz", - "integrity": "sha512-rAVeHYMcv8ATV5d508CFdn+8/pHPpXeIid1DdrPwXnaAdH7cqjVbpJaT5eq4yRAFU/lsbwYwSF/n5iNrdJHPQA==", + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.3.3.tgz", + "integrity": "sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew==", "dev": true, "license": "MIT", "bin": { @@ -9675,17 +10098,10 @@ "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", "license": "MIT" }, - "node_modules/psl": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", - "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==", - "dev": true, - "license": "MIT" - }, "node_modules/pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.2.tgz", + "integrity": "sha512-tUPXtzlGM8FE3P0ZL6DVs/3P58k9nk8/jZeQCurTJylQA8qFYzHFfhBJkuqyE0FifOsQ0uKWekiZ5g8wtr28cw==", "license": "MIT", "optional": true, "dependencies": { @@ -9720,12 +10136,12 @@ "license": "MIT" }, "node_modules/qs": { - "version": "6.11.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", - "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz", + "integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==", "license": "BSD-3-Clause", "dependencies": { - "side-channel": "^1.0.4" + "side-channel": "^1.0.6" }, "engines": { "node": ">=0.6" @@ -9734,13 +10150,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/querystringify": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", - "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==", - "dev": true, - "license": "MIT" - }, "node_modules/queue-microtask": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", @@ -9777,179 +10186,69 @@ "node_modules/range_check": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/range_check/-/range_check-2.0.4.tgz", - "integrity": "sha512-aed0ocXXj+SIiNNN9b+mZWA3Ow2GXHtftOGk2xQwshK5GbEZAvUcPWNQBLTx/lPcdFRIUFlFCRtHTQNIFMqynQ==", - "license": "BSD-2-Clause", - "dependencies": { - "ip6": "^0.2.0", - "ipaddr.js": "^1.9.1" - }, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/range-parser": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", - "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/raw-body": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", - "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", - "license": "MIT", - "dependencies": { - "bytes": "3.1.2", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "unpipe": "1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/raw-body/node_modules/iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "license": "MIT", - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/react-is": { - "version": "18.3.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", - "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", - "dev": true, - "license": "MIT" - }, - "node_modules/read": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/read/-/read-1.0.7.tgz", - "integrity": "sha512-rSOKNYUmaxy0om1BNjMN4ezNT6VKK+2xF4GBhc81mkH7L60i6dp8qPYrkndNLT3QPphoII3maL9PVC9XmhHwVQ==", - "license": "ISC", - "dependencies": { - "mute-stream": "~0.0.4" - }, - "engines": { - "node": ">=0.8" - } - }, - "node_modules/read-pkg": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", - "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/normalize-package-data": "^2.4.0", - "normalize-package-data": "^2.5.0", - "parse-json": "^5.0.0", - "type-fest": "^0.6.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/read-pkg-up": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", - "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", - "dev": true, - "license": "MIT", - "dependencies": { - "find-up": "^4.1.0", - "read-pkg": "^5.2.0", - "type-fest": "^0.8.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/read-pkg-up/node_modules/find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, - "license": "MIT", + "integrity": "sha512-aed0ocXXj+SIiNNN9b+mZWA3Ow2GXHtftOGk2xQwshK5GbEZAvUcPWNQBLTx/lPcdFRIUFlFCRtHTQNIFMqynQ==", + "license": "BSD-2-Clause", "dependencies": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" + "ip6": "^0.2.0", + "ipaddr.js": "^1.9.1" }, "engines": { - "node": ">=8" + "node": ">=10.0.0" } }, - "node_modules/read-pkg-up/node_modules/locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, + "node_modules/range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", "license": "MIT", - "dependencies": { - "p-locate": "^4.1.0" - }, "engines": { - "node": ">=8" + "node": ">= 0.6" } }, - "node_modules/read-pkg-up/node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, + "node_modules/raw-body": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", + "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", "license": "MIT", "dependencies": { - "p-try": "^2.0.0" + "bytes": "3.1.2", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" }, "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">= 0.8" } }, - "node_modules/read-pkg-up/node_modules/p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dev": true, + "node_modules/raw-body/node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", "license": "MIT", "dependencies": { - "p-limit": "^2.2.0" + "safer-buffer": ">= 2.1.2 < 3" }, "engines": { - "node": ">=8" + "node": ">=0.10.0" } }, - "node_modules/read-pkg-up/node_modules/type-fest": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", - "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "node_modules/react-is": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", + "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", "dev": true, - "license": "(MIT OR CC0-1.0)", - "engines": { - "node": ">=8" - } + "license": "MIT" }, - "node_modules/read-pkg/node_modules/type-fest": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", - "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", - "dev": true, - "license": "(MIT OR CC0-1.0)", + "node_modules/read": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/read/-/read-1.0.7.tgz", + "integrity": "sha512-rSOKNYUmaxy0om1BNjMN4ezNT6VKK+2xF4GBhc81mkH7L60i6dp8qPYrkndNLT3QPphoII3maL9PVC9XmhHwVQ==", + "license": "ISC", + "dependencies": { + "mute-stream": "~0.0.4" + }, "engines": { - "node": ">=8" + "node": ">=0.8" } }, "node_modules/readdirp": { @@ -9976,16 +10275,6 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, - "node_modules/regexp-tree": { - "version": "0.1.27", - "resolved": "https://registry.npmjs.org/regexp-tree/-/regexp-tree-0.1.27.tgz", - "integrity": "sha512-iETxpjK6YoRWJG5o6hXLwvjYAoW+FEZn9os0PD/b6AP6xQwsa/Y7lCVgIixBbUPMfhu+i2LtdeAqVTgGlQarfA==", - "dev": true, - "license": "MIT", - "bin": { - "regexp-tree": "bin/regexp-tree" - } - }, "node_modules/regexp.prototype.flags": { "version": "1.5.2", "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.2.tgz", @@ -10004,26 +10293,14 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/regjsparser": { - "version": "0.10.0", - "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.10.0.tgz", - "integrity": "sha512-qx+xQGZVsy55CH0a1hiVwHmqjLryfh7wQyF5HO07XJ9f7dQMY/gPQHhlyDkIzJKC+x2fUCpCcUODUUUFrm7SHA==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "jsesc": "~0.5.0" - }, - "bin": { - "regjsparser": "bin/parser" - } - }, - "node_modules/regjsparser/node_modules/jsesc": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", - "integrity": "sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==", + "node_modules/repeat-string": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", + "integrity": "sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==", "dev": true, - "bin": { - "jsesc": "bin/jsesc" + "license": "MIT", + "engines": { + "node": ">=0.10" } }, "node_modules/replace-last": { @@ -10068,13 +10345,6 @@ "node": ">=6" } }, - "node_modules/requires-port": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", - "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==", - "dev": true, - "license": "MIT" - }, "node_modules/resolve": { "version": "1.22.8", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", @@ -10112,7 +10382,7 @@ "node": ">=8" } }, - "node_modules/resolve-cwd/node_modules/resolve-from": { + "node_modules/resolve-from": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", @@ -10122,15 +10392,6 @@ "node": ">=8" } }, - "node_modules/resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "license": "MIT", - "engines": { - "node": ">=4" - } - }, "node_modules/resolve.exports": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-2.0.2.tgz", @@ -10155,22 +10416,51 @@ } }, "node_modules/restore-cursor": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-4.0.0.tgz", - "integrity": "sha512-I9fPXU9geO9bHOt9pHHOhOkYerIMsmVaWB0rA2AI9ERh/+x/i7MV5HKBNrg+ljO5eoPVgCcnFuRjJ9uH6I/3eg==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-5.1.0.tgz", + "integrity": "sha512-oMA2dcrw6u0YfxJQXm342bFKX/E4sG9rbTzO9ptUcR/e8A33cHuvStiYOwH7fszkZlZ1z/ta9AAoPk2F4qIOHA==", "dev": true, "license": "MIT", "dependencies": { - "onetime": "^5.1.0", - "signal-exit": "^3.0.2" + "onetime": "^7.0.0", + "signal-exit": "^4.1.0" }, "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/restore-cursor/node_modules/onetime": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-7.0.0.tgz", + "integrity": "sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "mimic-function": "^5.0.0" + }, + "engines": { + "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/restore-cursor/node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/reusify": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", @@ -10188,22 +10478,6 @@ "dev": true, "license": "MIT" }, - "node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "deprecated": "Rimraf versions prior to v4 are no longer supported", - "license": "ISC", - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/roarr": { "version": "2.15.4", "resolved": "https://registry.npmjs.org/roarr/-/roarr-2.15.4.tgz", @@ -10232,9 +10506,9 @@ } }, "node_modules/rrule/node_modules/tslib": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", - "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==", + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.7.0.tgz", + "integrity": "sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==", "license": "0BSD" }, "node_modules/rrweb-cssom": { @@ -10380,9 +10654,9 @@ } }, "node_modules/semver": { - "version": "7.6.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", - "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", "license": "ISC", "bin": { "semver": "bin/semver.js" @@ -10399,9 +10673,9 @@ "optional": true }, "node_modules/send": { - "version": "0.18.0", - "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", - "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", + "version": "0.19.0", + "resolved": "https://registry.npmjs.org/send/-/send-0.19.0.tgz", + "integrity": "sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==", "license": "MIT", "dependencies": { "debug": "2.6.9", @@ -10437,11 +10711,14 @@ "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", "license": "MIT" }, - "node_modules/send/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "license": "MIT" + "node_modules/send/node_modules/encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } }, "node_modules/serialize-error": { "version": "7.0.1", @@ -10473,15 +10750,15 @@ } }, "node_modules/serve-static": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", - "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", + "version": "1.16.2", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.16.2.tgz", + "integrity": "sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw==", "license": "MIT", "dependencies": { - "encodeurl": "~1.0.2", + "encodeurl": "~2.0.0", "escape-html": "~1.0.3", "parseurl": "~1.3.3", - "send": "0.18.0" + "send": "0.19.0" }, "engines": { "node": ">= 0.8.0" @@ -10577,18 +10854,18 @@ "license": "ISC" }, "node_modules/sinon": { - "version": "18.0.0", - "resolved": "https://registry.npmjs.org/sinon/-/sinon-18.0.0.tgz", - "integrity": "sha512-+dXDXzD1sBO6HlmZDd7mXZCR/y5ECiEiGCBSGuFD/kZ0bDTofPYc6JaeGmPSF+1j1MejGUWkORbYOLDyvqCWpA==", + "version": "19.0.2", + "resolved": "https://registry.npmjs.org/sinon/-/sinon-19.0.2.tgz", + "integrity": "sha512-euuToqM+PjO4UgXeLETsfQiuoyPXlqFezr6YZDFwHR3t4qaX0fZUe1MfPMznTL5f8BWrVS89KduLdMUsxFCO6g==", "dev": true, "license": "BSD-3-Clause", "dependencies": { "@sinonjs/commons": "^3.0.1", - "@sinonjs/fake-timers": "^11.2.2", - "@sinonjs/samsam": "^8.0.0", - "diff": "^5.2.0", - "nise": "^6.0.0", - "supports-color": "^7" + "@sinonjs/fake-timers": "^13.0.2", + "@sinonjs/samsam": "^8.0.1", + "diff": "^7.0.0", + "nise": "^6.1.1", + "supports-color": "^7.2.0" }, "funding": { "type": "opencollective", @@ -10596,19 +10873,19 @@ } }, "node_modules/sinon/node_modules/@sinonjs/fake-timers": { - "version": "11.2.2", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-11.2.2.tgz", - "integrity": "sha512-G2piCSxQ7oWOxwGSAyFHfPIsyeJGXYtc6mFbnFA+kRXkiEnTl8c/8jul2S329iFBnDI9HGoeWWAZvuvOkZccgw==", + "version": "13.0.2", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-13.0.2.tgz", + "integrity": "sha512-4Bb+oqXZTSTZ1q27Izly9lv8B9dlV61CROxPiVtywwzv5SnytJqhvYe6FclHYuXml4cd1VHPo1zd5PmTeJozvA==", "dev": true, "license": "BSD-3-Clause", "dependencies": { - "@sinonjs/commons": "^3.0.0" + "@sinonjs/commons": "^3.0.1" } }, "node_modules/sinon/node_modules/diff": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-5.2.0.tgz", - "integrity": "sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-7.0.0.tgz", + "integrity": "sha512-PJWHUb1RFevKCwaFA9RlG5tCd+FO5iRh9A8HEtkmBH2Li03iJriB6m6JIN4rGz3K3JLawI7/veA1xzRKP6ISBw==", "dev": true, "license": "BSD-3-Clause", "engines": { @@ -10680,16 +10957,16 @@ } }, "node_modules/socket.io": { - "version": "4.7.5", - "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.7.5.tgz", - "integrity": "sha512-DmeAkF6cwM9jSfmp6Dr/5/mfMwb5Z5qRrSXLpo3Fq5SqyU8CMF15jIN4ZhfSwu35ksM1qmHZDQ/DK5XTccSTvA==", + "version": "4.8.0", + "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.8.0.tgz", + "integrity": "sha512-8U6BEgGjQOfGz3HHTYaC/L1GaxDCJ/KM0XTkJly0EhZ5U/du9uNEZy4ZgYzEzIqlx2CMm25CrCqr1ck899eLNA==", "license": "MIT", "dependencies": { "accepts": "~1.3.4", "base64id": "~2.0.0", "cors": "~2.8.5", "debug": "~4.3.2", - "engine.io": "~6.5.2", + "engine.io": "~6.6.0", "socket.io-adapter": "~2.5.2", "socket.io-parser": "~4.2.4" }, @@ -10707,6 +10984,27 @@ "ws": "~8.17.1" } }, + "node_modules/socket.io-adapter/node_modules/ws": { + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz", + "integrity": "sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==", + "license": "MIT", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, "node_modules/socket.io-parser": { "version": "4.2.4", "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.2.4.tgz", @@ -10773,26 +11071,6 @@ "sort-package-json": "cli.js" } }, - "node_modules/sort-package-json/node_modules/globby": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-10.0.0.tgz", - "integrity": "sha512-3LifW9M4joGZasyYPz2A1U74zbC/45fvpXUvO/9KbSa+VV0aGZarWkfdgKyR9sExNP0t0x0ss/UMJpNpcaTspw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/glob": "^7.1.1", - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.0.3", - "glob": "^7.1.3", - "ignore": "^5.1.1", - "merge2": "^1.2.3", - "slash": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", @@ -10803,9 +11081,9 @@ } }, "node_modules/source-map-js": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz", - "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==", + "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, "license": "BSD-3-Clause", "engines": { @@ -10823,28 +11101,6 @@ "source-map": "^0.6.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, - "license": "Apache-2.0", - "dependencies": { - "spdx-expression-parse": "^3.0.0", - "spdx-license-ids": "^3.0.0" - } - }, - "node_modules/spdx-correct/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, - "license": "MIT", - "dependencies": { - "spdx-exceptions": "^2.1.0", - "spdx-license-ids": "^3.0.0" - } - }, "node_modules/spdx-exceptions": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.5.0.tgz", @@ -10864,9 +11120,9 @@ } }, "node_modules/spdx-license-ids": { - "version": "3.0.18", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.18.tgz", - "integrity": "sha512-xxRs31BqRYHwiMzudOrpSiHtZ8i/GeionCBDSilhYRj+9gIcI8wCZTlXZKu9vZIVqViP3dcp9qE5G6AlIaD+TQ==", + "version": "3.0.20", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.20.tgz", + "integrity": "sha512-jg25NiDV/1fLtSgEgyvVyDunvaNHbuwF9lfNV17gSmPFAlYzdfNBlLtLzXTevwkPj7DhGbmN9VnmJIgLnhvaBw==", "dev": true, "license": "CC0-1.0" }, @@ -10932,51 +11188,45 @@ "node": ">=10" } }, - "node_modules/string-width": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.1.0.tgz", - "integrity": "sha512-SEIJCWiX7Kg4c129n48aDRwLbFb2LJmXXFrWBG4NGaRtMQ3myKPKbwrD1BKqQn74oCoNMBVrfDEr5M9YxCsrkw==", + "node_modules/string-length/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "dev": true, "license": "MIT", - "dependencies": { - "emoji-regex": "^10.3.0", - "get-east-asian-width": "^1.0.0", - "strip-ansi": "^7.1.0" - }, "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=8" } }, - "node_modules/string-width/node_modules/ansi-regex": { + "node_modules/string-length/node_modules/strip-ansi": { "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", - "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dev": true, "license": "MIT", - "engines": { - "node": ">=12" + "dependencies": { + "ansi-regex": "^5.0.1" }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" + "engines": { + "node": ">=8" } }, - "node_modules/string-width/node_modules/strip-ansi": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", - "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "node_modules/string-width": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", + "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", "dev": true, "license": "MIT", "dependencies": { - "ansi-regex": "^6.0.1" + "emoji-regex": "^10.3.0", + "get-east-asian-width": "^1.0.0", + "strip-ansi": "^7.1.0" }, "engines": { - "node": ">=12" + "node": ">=18" }, "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/string.prototype.matchall": { @@ -11055,15 +11305,19 @@ } }, "node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "version": "7.1.0", + "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": "^5.0.1" + "ansi-regex": "^6.0.1" }, "engines": { - "node": ">=8" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" } }, "node_modules/strip-bom": { @@ -11086,19 +11340,6 @@ "node": ">=6" } }, - "node_modules/strip-indent": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", - "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "min-indent": "^1.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/strip-json-comments": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", @@ -11112,9 +11353,9 @@ } }, "node_modules/stylelint": { - "version": "16.6.1", - "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-16.6.1.tgz", - "integrity": "sha512-yNgz2PqWLkhH2hw6X9AweV9YvoafbAD5ZsFdKN9BvSDVwGvPh+AUIrn7lYwy1S7IHmtFin75LLfX1m0D2tHu8Q==", + "version": "16.9.0", + "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-16.9.0.tgz", + "integrity": "sha512-31Nm3WjxGOBGpQqF43o3wO9L5AC36TPIe6030Lnm13H3vDMTcS21DrLh69bMX+DBilKqMMVLian4iG6ybBoNRQ==", "dev": true, "funding": [ { @@ -11128,17 +11369,17 @@ ], "license": "MIT", "dependencies": { - "@csstools/css-parser-algorithms": "^2.6.3", - "@csstools/css-tokenizer": "^2.3.1", - "@csstools/media-query-list-parser": "^2.1.11", - "@csstools/selector-specificity": "^3.1.1", + "@csstools/css-parser-algorithms": "^3.0.1", + "@csstools/css-tokenizer": "^3.0.1", + "@csstools/media-query-list-parser": "^3.0.1", + "@csstools/selector-specificity": "^4.0.0", "@dual-bundle/import-meta-resolve": "^4.1.0", "balanced-match": "^2.0.0", "colord": "^2.9.3", "cosmiconfig": "^9.0.0", "css-functions-list": "^3.2.2", "css-tree": "^2.3.1", - "debug": "^4.3.4", + "debug": "^4.3.6", "fast-glob": "^3.3.2", "fastest-levenshtein": "^1.0.16", "file-entry-cache": "^9.0.0", @@ -11146,24 +11387,24 @@ "globby": "^11.1.0", "globjoin": "^0.1.4", "html-tags": "^3.3.1", - "ignore": "^5.3.1", + "ignore": "^5.3.2", "imurmurhash": "^0.1.4", "is-plain-object": "^5.0.0", - "known-css-properties": "^0.31.0", + "known-css-properties": "^0.34.0", "mathml-tag-names": "^2.1.3", "meow": "^13.2.0", - "micromatch": "^4.0.7", + "micromatch": "^4.0.8", "normalize-path": "^3.0.0", "picocolors": "^1.0.1", - "postcss": "^8.4.38", - "postcss-resolve-nested-selector": "^0.1.1", + "postcss": "^8.4.41", + "postcss-resolve-nested-selector": "^0.1.6", "postcss-safe-parser": "^7.0.0", - "postcss-selector-parser": "^6.1.0", + "postcss-selector-parser": "^6.1.2", "postcss-value-parser": "^4.2.0", "resolve-from": "^5.0.0", "string-width": "^4.2.3", "strip-ansi": "^7.1.0", - "supports-hyperlinks": "^3.0.0", + "supports-hyperlinks": "^3.1.0", "svg-tags": "^1.0.0", "table": "^6.8.2", "write-file-atomic": "^5.0.1" @@ -11225,9 +11466,9 @@ } }, "node_modules/stylelint-prettier": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/stylelint-prettier/-/stylelint-prettier-5.0.0.tgz", - "integrity": "sha512-RHfSlRJIsaVg5Br94gZVdWlz/rBTyQzZflNE6dXvSxt/GthWMY3gEHsWZEBaVGg7GM+XrtVSp4RznFlB7i0oyw==", + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/stylelint-prettier/-/stylelint-prettier-5.0.2.tgz", + "integrity": "sha512-qJ+BN+1T2ZcKz9WIrv0x+eFGHzSUnXfXd5gL///T6XoJvr3D8/ztzz2fhtmXef7Vb8P33zBXmLTTveByr0nwBw==", "dev": true, "license": "MIT", "dependencies": { @@ -11241,6 +11482,16 @@ "stylelint": ">=16.0.0" } }, + "node_modules/stylelint/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/stylelint/node_modules/balanced-match": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-2.0.0.tgz", @@ -11255,31 +11506,25 @@ "dev": true, "license": "MIT" }, - "node_modules/stylelint/node_modules/file-entry-cache": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-9.0.0.tgz", - "integrity": "sha512-6MgEugi8p2tiUhqO7GnPsmbCCzj0YRCwwaTbpGRyKZesjRSzkqkAE9fPp7V2yMs5hwfgbQLgdvSSkGNg1s5Uvw==", + "node_modules/stylelint/node_modules/globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", "dev": true, "license": "MIT", "dependencies": { - "flat-cache": "^5.0.0" + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" }, "engines": { - "node": ">=18" - } - }, - "node_modules/stylelint/node_modules/flat-cache": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-5.0.0.tgz", - "integrity": "sha512-JrqFmyUl2PnPi1OvLyTVHnQvwQ0S+e6lGSwu8OkAZlSaNIZciTY2H/cOOROxsBA1m/LZNHDsqAgDZt6akWcjsQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "flatted": "^3.3.1", - "keyv": "^4.5.4" + "node": ">=10" }, - "engines": { - "node": ">=18" + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/stylelint/node_modules/is-fullwidth-code-point": { @@ -11292,16 +11537,6 @@ "node": ">=8" } }, - "node_modules/stylelint/node_modules/resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/stylelint/node_modules/signal-exit": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", @@ -11343,35 +11578,6 @@ "node": ">=8" } }, - "node_modules/stylelint/node_modules/strip-ansi": { - "version": "7.1.0", - "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" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" - } - }, - "node_modules/stylelint/node_modules/strip-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==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" - } - }, "node_modules/stylelint/node_modules/write-file-atomic": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-5.0.1.tgz", @@ -11417,9 +11623,9 @@ } }, "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.1.0", + "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-3.1.0.tgz", + "integrity": "sha512-2rn0BZ+/f7puLOHZm1HOJfwBggfaHXUpPUSSG/SWM4TWp5KCfmNYwnC3hruy2rZlMnmWZ+QAGpZfchu3f3695A==", "dev": true, "license": "MIT", "dependencies": { @@ -11428,6 +11634,9 @@ }, "engines": { "node": ">=14.18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/supports-preserve-symlinks-flag": { @@ -11456,9 +11665,9 @@ "license": "MIT" }, "node_modules/synckit": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.9.0.tgz", - "integrity": "sha512-7RnqIMq572L8PeEzKeBINYEJDDxpcH8JEgLwUqBd3TkofhFRbkq4QLR0u+36avGAhCRbk2nnmjcW9SE531hPDg==", + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.9.1.tgz", + "integrity": "sha512-7gr8p9TQP6RAHusBOSLs46F4564ZrjV8xFmw5zCmgmhGUcw2hxsShhJ6CEiHQMgPDwAQ1fWHPM0ypc4RMAig4A==", "dev": true, "license": "MIT", "dependencies": { @@ -11473,16 +11682,16 @@ } }, "node_modules/synckit/node_modules/tslib": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", - "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==", + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.7.0.tgz", + "integrity": "sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==", "dev": true, "license": "0BSD" }, "node_modules/systeminformation": { - "version": "5.22.11", - "resolved": "https://registry.npmjs.org/systeminformation/-/systeminformation-5.22.11.tgz", - "integrity": "sha512-aLws5yi4KCHTb0BVvbodQY5bY8eW4asMRDTxTW46hqw9lGjACX6TlLdJrkdoHYRB0qs+MekqEq1zG7WDnWE8Ug==", + "version": "5.23.5", + "resolved": "https://registry.npmjs.org/systeminformation/-/systeminformation-5.23.5.tgz", + "integrity": "sha512-PEpJwhRYxZgBCAlWZhWIgfMTjXLqfcaZ1pJsJn9snWNfBW/Z1YQg1mbIUSWrEV3ErAHF7l/OoVLQeaZDlPzkpA==", "license": "MIT", "os": [ "darwin", @@ -11522,6 +11731,16 @@ "node": ">=10.0.0" } }, + "node_modules/table/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/table/node_modules/emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", @@ -11572,6 +11791,19 @@ "node": ">=8" } }, + "node_modules/table/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/test-exclude": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", @@ -11617,6 +11849,26 @@ "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", "license": "MIT" }, + "node_modules/tldts": { + "version": "6.1.48", + "resolved": "https://registry.npmjs.org/tldts/-/tldts-6.1.48.tgz", + "integrity": "sha512-SPbnh1zaSzi/OsmHb1vrPNnYuwJbdWjwo5TbBYYMlTtH3/1DSb41t8bcSxkwDmmbG2q6VLPVvQc7Yf23T+1EEw==", + "dev": true, + "license": "MIT", + "dependencies": { + "tldts-core": "^6.1.48" + }, + "bin": { + "tldts": "bin/cli.js" + } + }, + "node_modules/tldts-core": { + "version": "6.1.48", + "resolved": "https://registry.npmjs.org/tldts-core/-/tldts-core-6.1.48.tgz", + "integrity": "sha512-3gD9iKn/n2UuFH1uilBviK9gvTNT6iYwdqrj1Vr5mh8FuelvpRNaYVH4pNYqUgOGU4aAdL9X35eLuuj0gRsx+A==", + "dev": true, + "license": "MIT" + }, "node_modules/tmpl": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", @@ -11656,29 +11908,16 @@ } }, "node_modules/tough-cookie": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.4.tgz", - "integrity": "sha512-Loo5UUvLD9ScZ6jh8beX1T6sO1w2/MpCRpEP7V280GKMVUQ0Jzar2U3UJPsrdbziLEMMhu3Ujnq//rhiFuIeag==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-5.0.0.tgz", + "integrity": "sha512-FRKsF7cz96xIIeMZ82ehjC3xW2E+O2+v11udrDYewUbszngYhsGa8z6YUMMzO9QJZzzyd0nGGXnML/TReX6W8Q==", "dev": true, "license": "BSD-3-Clause", "dependencies": { - "psl": "^1.1.33", - "punycode": "^2.1.1", - "universalify": "^0.2.0", - "url-parse": "^1.5.3" + "tldts": "^6.1.32" }, "engines": { - "node": ">=6" - } - }, - "node_modules/tough-cookie/node_modules/universalify": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz", - "integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 4.0.0" + "node": ">=16" } }, "node_modules/tr46": { @@ -11707,42 +11946,6 @@ "typescript": ">=4.2.0" } }, - "node_modules/tsconfig-paths": { - "version": "3.15.0", - "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz", - "integrity": "sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/json5": "^0.0.29", - "json5": "^1.0.2", - "minimist": "^1.2.6", - "strip-bom": "^3.0.0" - } - }, - "node_modules/tsconfig-paths/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==", - "dev": true, - "license": "MIT", - "dependencies": { - "minimist": "^1.2.0" - }, - "bin": { - "json5": "lib/cli.js" - } - }, - "node_modules/tsconfig-paths/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, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, "node_modules/tslib": { "version": "1.9.3", "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.9.3.tgz", @@ -11800,9 +12003,10 @@ } }, "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==", + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "dev": true, "license": "(MIT OR CC0-1.0)", "engines": { "node": ">=10" @@ -11898,9 +12102,9 @@ } }, "node_modules/typescript": { - "version": "5.5.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.2.tgz", - "integrity": "sha512-NcRtPEOsPFFWjobJEtfihkLCZCXZt/os3zf8nTxjVH3RvTSxjrCamJpbExGvYOF+tFHc3pA65qpdwPbzjohhew==", + "version": "5.6.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.6.2.tgz", + "integrity": "sha512-NW8ByodCSNCwZeghjN3o+JX5OFH0Ojg6sadjEKY4huZ52TqbJTJnDo5+Tw98lSy63NZvi4n+ez5m2u5d4PkZyw==", "dev": true, "license": "Apache-2.0", "peer": true, @@ -11913,9 +12117,9 @@ } }, "node_modules/uglify-js": { - "version": "3.18.0", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.18.0.tgz", - "integrity": "sha512-SyVVbcNBCk0dzr9XL/R/ySrmYf0s372K6/hFklzgcp2lBFyXtw4I7BOdDjlLhE1aVqaI/SHWXWmYdlZxuyF38A==", + "version": "3.19.3", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.19.3.tgz", + "integrity": "sha512-v3Xu+yuwBXisp6QYTcH4UbH+xYJXqnq2m/LtQVWKWzYc1iehYnLixoQDN9FH6/j9/oybfd6W9Ghwkl8+UMKTKQ==", "license": "BSD-2-Clause", "optional": true, "bin": { @@ -11941,9 +12145,9 @@ } }, "node_modules/undici-types": { - "version": "5.26.5", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", - "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", + "version": "6.19.8", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", + "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==", "license": "MIT" }, "node_modules/universalify": { @@ -11966,9 +12170,9 @@ } }, "node_modules/update-browserslist-db": { - "version": "1.0.16", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.16.tgz", - "integrity": "sha512-KVbTxlBYlckhF5wgfyZXTWnMn7MMZjMu9XG8bPlliUOP9ThaF4QnhP8qrjrH7DRzHfSk0oQv1wToW+iA5GajEQ==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.1.tgz", + "integrity": "sha512-R8UzCaa9Az+38REPiJ1tXlImTJXlVfgHZsglwBD/k6nj76ctsH1E3q4doGrukiLQd3sGQYu56r5+lo5r94l29A==", "dev": true, "funding": [ { @@ -11986,8 +12190,8 @@ ], "license": "MIT", "dependencies": { - "escalade": "^3.1.2", - "picocolors": "^1.0.1" + "escalade": "^3.2.0", + "picocolors": "^1.1.0" }, "bin": { "update-browserslist-db": "cli.js" @@ -12005,17 +12209,6 @@ "punycode": "^2.1.0" } }, - "node_modules/url-parse": { - "version": "1.5.10", - "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz", - "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "querystringify": "^2.1.1", - "requires-port": "^1.0.0" - } - }, "node_modules/util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", @@ -12060,28 +12253,6 @@ "node": ">=10.12.0" } }, - "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, - "license": "Apache-2.0", - "dependencies": { - "spdx-correct": "^3.0.0", - "spdx-expression-parse": "^3.0.0" - } - }, - "node_modules/validate-npm-package-license/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, - "license": "MIT", - "dependencies": { - "spdx-exceptions": "^2.1.0", - "spdx-license-ids": "^3.0.0" - } - }, "node_modules/validate-npm-package-name": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/validate-npm-package-name/-/validate-npm-package-name-5.0.1.tgz", @@ -12125,6 +12296,26 @@ "lodash": "^4.17.14" } }, + "node_modules/vizion/node_modules/ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "license": "ISC" + }, + "node_modules/vscode-languageserver-textdocument": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/vscode-languageserver-textdocument/-/vscode-languageserver-textdocument-1.0.12.tgz", + "integrity": "sha512-cxWNPesCnQCcMPeenjKKsOCKQZ/L6Tv19DTRIGuLWe32lyzWhihGVJ/rcckZXJxfdKCFvRLS3fpBIsV/ZGX4zA==", + "dev": true, + "license": "MIT" + }, + "node_modules/vscode-uri": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-3.0.8.tgz", + "integrity": "sha512-AyFQ0EVmsOZOlAnxoFOGOq1SQDWAB7C6aqMGS23svWAllfOaxbuFvcT8D1i8z3Gyn8fraVeZNNmN6e9bxxXkKw==", + "dev": true, + "license": "MIT" + }, "node_modules/w3c-xmlserializer": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-5.0.0.tgz", @@ -12278,19 +12469,6 @@ "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, - "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==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" - } - }, "node_modules/wrap-ansi/node_modules/ansi-styles": { "version": "6.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", @@ -12304,26 +12482,11 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/wrap-ansi/node_modules/strip-ansi": { - "version": "7.1.0", - "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" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "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==", + "devOptional": true, "license": "ISC" }, "node_modules/write-file-atomic": { @@ -12341,9 +12504,10 @@ } }, "node_modules/ws": { - "version": "8.17.1", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz", - "integrity": "sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==", + "version": "8.18.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz", + "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==", + "dev": true, "license": "MIT", "engines": { "node": ">=10.0.0" @@ -12361,6 +12525,19 @@ } } }, + "node_modules/xdg-basedir": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-5.1.0.tgz", + "integrity": "sha512-GCPAHLvrIH13+c0SuacwvRYj2SxJXQ4kaVTT5xgL3kPrz56XxkF21IGhjSE1+W0aw7gpBWRGXLCPnPby6lSpmQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/xml-name-validator": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-5.0.0.tgz", @@ -12396,9 +12573,9 @@ "license": "ISC" }, "node_modules/yaml": { - "version": "2.4.5", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.4.5.tgz", - "integrity": "sha512-aBx2bnqDzVOyNKfsysjA2ms5ZlnjSAW2eG3/L5G/CSujfjLJTJsEw1bGw8kCf04KodQWk1pxlGnZ56CRxiawmg==", + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.5.1.tgz", + "integrity": "sha512-bLQOjaX/ADgQ20isPJRvF0iRUHIxVhYvr53Of7wGcWlO2jvtUlH5m87DsmulFVxRpNLOnI4tB6p/oh8D7kpn9Q==", "dev": true, "license": "ISC", "bin": { @@ -12437,6 +12614,16 @@ "node": ">=12" } }, + "node_modules/yargs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/yargs/node_modules/emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", @@ -12469,6 +12656,19 @@ "node": ">=8" } }, + "node_modules/yargs/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/yauzl": { "version": "2.10.0", "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", diff --git a/package.json b/package.json index 55366ee296..7b80b4e277 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "magicmirror", - "version": "2.28.0", + "version": "2.29.0", "description": "The open source modular smart mirror platform.", "keywords": [ "magic mirror", @@ -41,6 +41,7 @@ "test:js": "eslint .", "test:css": "stylelint 'css/main.css' 'fonts/*.css' 'modules/default/**/*.css' 'vendor/*.css' --config .stylelintrc.json", "test:calendar": "node ./modules/default/calendar/debug.js", + "test:spelling": "cspell . --gitignore", "config:check": "node js/check_config.js", "lint:prettier": "prettier . --write", "lint:js": "eslint . --fix", @@ -54,12 +55,12 @@ "*.css": "stylelint --fix" }, "dependencies": { - "ajv": "^8.16.0", - "ansis": "^3.2.0", + "ajv": "^8.17.1", + "ansis": "^3.3.2", "console-stamp": "^3.1.2", "envsub": "^4.1.0", - "eslint": "^8.57.0", - "express": "^4.19.2", + "eslint": "^9.11.1", + "express": "^4.21.0", "express-ipfilter": "^1.3.2", "feedme": "^2.0.2", "helmet": "^7.1.0", @@ -67,36 +68,36 @@ "iconv-lite": "^0.6.3", "module-alias": "^2.2.3", "moment": "^2.30.1", - "node-ical": "^0.18.0", - "pm2": "^5.4.1", - "socket.io": "^4.7.5", + "node-ical": "0.18.0", + "pm2": "^5.4.2", + "socket.io": "^4.8.0", "suncalc": "^1.9.0", - "systeminformation": "^5.22.11" + "systeminformation": "^5.23.5" }, "devDependencies": { - "@stylistic/eslint-plugin": "^1.8.1", - "eslint-plugin-import": "^2.29.1", - "eslint-plugin-jest": "^28.6.0", - "eslint-plugin-jsdoc": "^48.5.0", - "eslint-plugin-package-json": "^0.15.0", - "eslint-plugin-unicorn": "^54.0.0", + "@eslint/js": "^9.11.1", + "@stylistic/eslint-plugin": "^2.8.0", + "cspell": "^8.14.4", + "eslint-plugin-jest": "^28.8.3", + "eslint-plugin-jsdoc": "^50.3.0", + "eslint-plugin-package-json": "^0.15.3", "express-basic-auth": "^1.2.1", - "husky": "^9.0.11", + "husky": "^9.1.6", "jest": "^29.7.0", - "jsdom": "^24.1.0", - "lint-staged": "^15.2.7", - "playwright": "^1.45.0", - "prettier": "^3.3.2", - "sinon": "^18.0.0", - "stylelint": "^16.6.1", + "jsdom": "^25.0.1", + "lint-staged": "^15.2.10", + "playwright": "^1.47.2", + "prettier": "^3.3.3", + "sinon": "^19.0.2", + "stylelint": "^16.9.0", "stylelint-config-standard": "^36.0.1", - "stylelint-prettier": "^5.0.0" + "stylelint-prettier": "^5.0.2" }, "optionalDependencies": { - "electron": "^31.1.0" + "electron": "^31.6.0" }, "engines": { - "node": ">=20" + "node": ">=20.9.0 <21 || 22" }, "_moduleAliases": { "node_helper": "js/node_helper.js", diff --git a/splashscreen/MagicMirror.plymouth b/splashscreen/MagicMirror.plymouth deleted file mode 100644 index b6887bf56b..0000000000 --- a/splashscreen/MagicMirror.plymouth +++ /dev/null @@ -1,8 +0,0 @@ -[Plymouth Theme] -Name=MagicMirror -Description=Mirror Splash -ModuleName=script - -[script] -ImageDir=/usr/share/plymouth/themes/MagicMirror -ScriptFile=/usr/share/plymouth/themes/MagicMirror/MagicMirror.script diff --git a/splashscreen/MagicMirror.script b/splashscreen/MagicMirror.script deleted file mode 100644 index 6e2f5643a9..0000000000 --- a/splashscreen/MagicMirror.script +++ /dev/null @@ -1,53 +0,0 @@ -screen_width = Window.GetWidth(); -screen_height = Window.GetHeight(); - -if (Plymouth.GetMode() != "shutdown") -{ - theme_image = Image("splash.png"); -} -else -{ - theme_image = Image("splash_halt.png"); -} - -image_width = theme_image.GetWidth(); -image_height = theme_image.GetHeight(); - -scale_x = image_width / screen_width; -scale_y = image_height / screen_height; - -if (scale_x > 1 || scale_y > 1) -{ - if (scale_x > scale_y) - { - resized_image = theme_image.Scale (screen_width, image_height / scale_x); - image_x = 0; - image_y = (screen_height - ((image_height * screen_width) / image_width)) / 2; - } - else - { - resized_image = theme_image.Scale (image_width / scale_y, screen_height); - image_x = (screen_width - ((image_width * screen_height) / image_height)) / 2; - image_y = 0; - } -} -else -{ - resized_image = theme_image.Scale (image_width, image_height); - image_x = (screen_width - image_width) / 2; - image_y = (screen_height - image_height) / 2; -} - -sprite = Sprite (resized_image); -sprite.SetPosition (image_x, image_y, -100); - -message_sprite = Sprite(); -message_sprite.SetPosition(screen_width * 0.1, screen_height * 0.9, 10000); - -fun message_callback (text) { - my_image = Image.Text(text, 1, 1, 1); - message_sprite.SetImage(my_image); - sprite.SetImage (resized_image); -} - -Plymouth.SetUpdateStatusFunction(message_callback); diff --git a/splashscreen/splash.png b/splashscreen/splash.png deleted file mode 100644 index b2acc49539..0000000000 Binary files a/splashscreen/splash.png and /dev/null differ diff --git a/splashscreen/splash_halt.png b/splashscreen/splash_halt.png deleted file mode 100644 index dcf9d8be0d..0000000000 Binary files a/splashscreen/splash_halt.png and /dev/null differ diff --git a/tests/configs/customregions.js b/tests/configs/customregions.js new file mode 100644 index 0000000000..5fe4ee28c4 --- /dev/null +++ b/tests/configs/customregions.js @@ -0,0 +1,23 @@ +let config = { + modules: + // Using exotic content. This is why don't accept go to JSON configuration file + (() => { + let positions = ["row3_left", "top3_left1"]; + let modules = Array(); + for (let idx in positions) { + modules.push({ + module: "helloworld", + position: positions[idx], + config: { + text: `Text in ${positions[idx]}` + } + }); + } + return modules; + })() +}; + +/*************** DO NOT EDIT THE LINE BELOW ***************/ +if (typeof module !== "undefined") { + module.exports = config; +} diff --git a/tests/configs/modules/calendar/exdate_la_at_midnight_dst.js b/tests/configs/modules/calendar/exdate_la_at_midnight_dst.js index 608c71da96..fb431ad7e6 100644 --- a/tests/configs/modules/calendar/exdate_la_at_midnight_dst.js +++ b/tests/configs/modules/calendar/exdate_la_at_midnight_dst.js @@ -1,4 +1,5 @@ -/* MagicMirror² Test calendar exdate +/* + * MagicMirror² Test calendar exdate * * By jkriegshauser * MIT Licensed. diff --git a/tests/configs/modules/calendar/exdate_la_at_midnight_std.js b/tests/configs/modules/calendar/exdate_la_at_midnight_std.js index 6128c97f50..b6ea3011dc 100644 --- a/tests/configs/modules/calendar/exdate_la_at_midnight_std.js +++ b/tests/configs/modules/calendar/exdate_la_at_midnight_std.js @@ -1,4 +1,5 @@ -/* MagicMirror² Test calendar exdate +/* + * MagicMirror² Test calendar exdate * * By jkriegshauser * MIT Licensed. diff --git a/tests/configs/modules/calendar/exdate_la_before_midnight.js b/tests/configs/modules/calendar/exdate_la_before_midnight.js index 8c886f775a..e5518df797 100644 --- a/tests/configs/modules/calendar/exdate_la_before_midnight.js +++ b/tests/configs/modules/calendar/exdate_la_before_midnight.js @@ -1,4 +1,5 @@ -/* MagicMirror² Test calendar exdate +/* + * MagicMirror² Test calendar exdate * * By jkriegshauser * MIT Licensed. diff --git a/tests/configs/modules/calendar/exdate_syd_at_midnight_dst.js b/tests/configs/modules/calendar/exdate_syd_at_midnight_dst.js index f98b75f4c7..e6287e2b02 100644 --- a/tests/configs/modules/calendar/exdate_syd_at_midnight_dst.js +++ b/tests/configs/modules/calendar/exdate_syd_at_midnight_dst.js @@ -1,4 +1,5 @@ -/* MagicMirror² Test calendar exdate +/* + * MagicMirror² Test calendar exdate * * By jkriegshauser * MIT Licensed. diff --git a/tests/configs/modules/calendar/exdate_syd_at_midnight_std.js b/tests/configs/modules/calendar/exdate_syd_at_midnight_std.js index 06c7ff5319..9000387998 100644 --- a/tests/configs/modules/calendar/exdate_syd_at_midnight_std.js +++ b/tests/configs/modules/calendar/exdate_syd_at_midnight_std.js @@ -1,4 +1,5 @@ -/* MagicMirror² Test calendar exdate +/* + * MagicMirror² Test calendar exdate * * By jkriegshauser * MIT Licensed. diff --git a/tests/configs/modules/calendar/exdate_syd_before_midnight.js b/tests/configs/modules/calendar/exdate_syd_before_midnight.js index 849c1f5363..3b176329ec 100644 --- a/tests/configs/modules/calendar/exdate_syd_before_midnight.js +++ b/tests/configs/modules/calendar/exdate_syd_before_midnight.js @@ -1,4 +1,5 @@ -/* MagicMirror² Test calendar exdate +/* + * MagicMirror² Test calendar exdate * * By jkriegshauser * MIT Licensed. diff --git a/tests/configs/modules/calendar/long-fullday-event.js b/tests/configs/modules/calendar/long-fullday-event.js index efbc244886..80137810d8 100644 --- a/tests/configs/modules/calendar/long-fullday-event.js +++ b/tests/configs/modules/calendar/long-fullday-event.js @@ -1,4 +1,5 @@ -/* MagicMirror² Test config for fullday calendar entries over multiple days +/* + * MagicMirror² Test config for fullday calendar entries over multiple days * * By Paranoid93 https://github.com/Paranoid93/ * MIT Licensed. diff --git a/tests/configs/modules/calendar/single-fullday-event.js b/tests/configs/modules/calendar/single-fullday-event.js index 9149d2d9ab..7dae36115f 100644 --- a/tests/configs/modules/calendar/single-fullday-event.js +++ b/tests/configs/modules/calendar/single-fullday-event.js @@ -1,4 +1,5 @@ -/* MagicMirror² Test config for fullday calendar entries over multiple days +/* + * MagicMirror² Test config for fullday calendar entries over multiple days * * By Paranoid93 https://github.com/Paranoid93/ * MIT Licensed. diff --git a/tests/configs/modules/calendar/sliceMultiDayEvents.js b/tests/configs/modules/calendar/sliceMultiDayEvents.js new file mode 100644 index 0000000000..ebcf2cec4f --- /dev/null +++ b/tests/configs/modules/calendar/sliceMultiDayEvents.js @@ -0,0 +1,30 @@ +let config = { + timeFormat: 12, + + modules: [ + { + module: "calendar", + position: "bottom_bar", + config: { + hideDuplicates: false, + maximumEntries: 100, + sliceMultiDayEvents: true, + calendars: [ + { + maximumEntries: 100, + url: "http://localhost:8080/tests/mocks/sliceMultiDayEvents.ics" + } + ] + } + } + ] +}; + +Date.now = () => { + return new Date("01 Sept 2024 10:38:00 GMT+2:00").valueOf(); +}; + +/*************** DO NOT EDIT THE LINE BELOW ***************/ +if (typeof module !== "undefined") { + module.exports = config; +} diff --git a/tests/configs/modules/compliments/compliments_cron_entry.js b/tests/configs/modules/compliments/compliments_cron_entry.js new file mode 100644 index 0000000000..59a6659293 --- /dev/null +++ b/tests/configs/modules/compliments/compliments_cron_entry.js @@ -0,0 +1,18 @@ +let config = { + modules: [ + { + module: "compliments", + position: "middle_center", + config: { + specialDayUnique: true, + compliments: { + anytime: ["just a test"], + "00-10 16-19 * * fri": ["just pub time"] + } + } + } + ] +}; + +/*************** DO NOT EDIT THE LINE BELOW ***************/ +if (typeof module !== "undefined") { module.exports = config; } diff --git a/tests/configs/modules/compliments/compliments_e2e_cron_entry.js b/tests/configs/modules/compliments/compliments_e2e_cron_entry.js new file mode 100644 index 0000000000..a4d1c5d8f2 --- /dev/null +++ b/tests/configs/modules/compliments/compliments_e2e_cron_entry.js @@ -0,0 +1,18 @@ +let config = { + modules: [ + { + module: "compliments", + position: "middle_center", + config: { + specialDayUnique: true, + compliments: { + anytime: ["just a test"], + "* * * * *": ["anytime cron"] + } + } + } + ] +}; + +/*************** DO NOT EDIT THE LINE BELOW ***************/ +if (typeof module !== "undefined") { module.exports = config; } diff --git a/tests/e2e/animateCSS_spec.js b/tests/e2e/animateCSS_spec.js index d7fcb52e44..b82a05712c 100644 --- a/tests/e2e/animateCSS_spec.js +++ b/tests/e2e/animateCSS_spec.js @@ -5,7 +5,7 @@ describe("AnimateCSS integration Test", () => { let testConfigFile = "tests/configs/modules/compliments/compliments_animateCSS.js"; // define config file to fallback to default: wrong animation name (must return no animation) let testConfigFileFallbackToDefault = "tests/configs/modules/compliments/compliments_animateCSS_fallbackToDefault.js"; - // define config file with an inversed name animation : in for out and vice versa (must return no animation) + // define config file with an inverted name animation : in for out and vice versa (must return no animation) let testConfigFileInvertedAnimationName = "tests/configs/modules/compliments/compliments_animateCSS_invertedAnimationName.js"; // define config file with no animation defined let testConfigByDefault = "tests/configs/modules/compliments/compliments_anytime.js"; diff --git a/tests/e2e/custom_module_regions_spec.js b/tests/e2e/custom_module_regions_spec.js new file mode 100644 index 0000000000..48d09712da --- /dev/null +++ b/tests/e2e/custom_module_regions_spec.js @@ -0,0 +1,30 @@ +const helpers = require("./helpers/global-setup"); + +describe("Custom Position of modules", () => { + beforeAll(async () => { + await helpers.fixupIndex(); + await helpers.startApplication("tests/configs/customregions.js"); + await helpers.getDocument(); + }); + afterAll(async () => { + await helpers.stopApplication(); + await helpers.restoreIndex(); + }); + + const positions = ["row3_left", "top3_left1"]; + let i = 0; + const className1 = positions[i].replace("_", "."); + let message1 = positions[i]; + it(`should show text in ${message1}`, async () => { + const elem = await helpers.waitForElement(`.${className1}`); + expect(elem).not.toBeNull(); + expect(elem.textContent).toContain(`Text in ${message1}`); + }); + i = 1; + const className2 = positions[i].replace("_", "."); + let message2 = positions[i]; + it(`should NOT show text in ${message2}`, async () => { + const elem = await helpers.waitForElement(`.${className2}`, "", 1500); + expect(elem).toBeNull(); + }, 1510); +}); diff --git a/tests/e2e/helpers/global-setup.js b/tests/e2e/helpers/global-setup.js index 31a3e036c2..ef90c0fdd9 100644 --- a/tests/e2e/helpers/global-setup.js +++ b/tests/e2e/helpers/global-setup.js @@ -1,5 +1,20 @@ +const os = require("node:os"); +const fs = require("node:fs"); const jsdom = require("jsdom"); +const indexFile = `${__dirname}/../../../index.html`; +const cssFile = `${__dirname}/../../../css/custom.css`; +const sampleCss = [ + ".region.row3 {", + " top: 0;", + "}", + ".region.row3.left {", + " top: 100%;", + "}" +]; +var indexData = []; +var cssData = []; + exports.startApplication = async (configFilename, exec) => { jest.resetModules(); if (global.app) { @@ -45,11 +60,12 @@ exports.getDocument = () => { }); }; -exports.waitForElement = (selector, ignoreValue = "") => { +exports.waitForElement = (selector, ignoreValue = "", timeout = 0) => { return new Promise((resolve) => { let oldVal = "dummy12345"; + let element = null; const interval = setInterval(() => { - const element = document.querySelector(selector); + element = document.querySelector(selector); if (element) { let newVal = element.textContent; if (newVal === oldVal) { @@ -64,6 +80,12 @@ exports.waitForElement = (selector, ignoreValue = "") => { } } }, 100); + if (timeout !== 0) { + setTimeout(() => { + if (interval) clearInterval(interval); + resolve(null); + }, timeout); + } }); }; @@ -91,3 +113,34 @@ exports.testMatch = async (element, regex) => { expect(elem.textContent).toMatch(regex); return true; }; + +exports.fixupIndex = async () => { + // read and save the git level index file + indexData = (await fs.promises.readFile(indexFile)).toString(); + // make lines of the content + let workIndexLines = indexData.split(os.EOL); + // loop thru the lines to find place to insert new region + for (let l in workIndexLines) { + if (workIndexLines[l].includes("region top right")) { + // insert a new line with new region definition + workIndexLines.splice(l, 0, "
"); + break; + } + } + // write out the new index.html file, not append + await fs.promises.writeFile(indexFile, workIndexLines.join(os.EOL), { flush: true }); + // read in the current custom.css + cssData = (await fs.promises.readFile(cssFile)).toString(); + // write out the custom.css for this testcase, matching the new region name + await fs.promises.writeFile(cssFile, sampleCss.join(os.EOL), { flush: true }); +}; + +exports.restoreIndex = async () => { + // if we read in data + if (indexData.length > 1) { + //write out saved index.html + await fs.promises.writeFile(indexFile, indexData, { flush: true }); + // write out saved custom.css + await fs.promises.writeFile(cssFile, cssData, { flush: true }); + } +}; diff --git a/tests/e2e/modules/calendar_spec.js b/tests/e2e/modules/calendar_spec.js index 0dcd562cd1..e88c003ad1 100644 --- a/tests/e2e/modules/calendar_spec.js +++ b/tests/e2e/modules/calendar_spec.js @@ -88,17 +88,6 @@ describe("Calendar module", () => { }); }); - describe("Events from multiple calendars", () => { - beforeAll(async () => { - await helpers.startApplication("tests/configs/modules/calendar/show-duplicates-in-calendar.js"); - await helpers.getDocument(); - }); - - it("should show multiple events with the same title and start time from different calendars", async () => { - await expect(testElementLength(".calendar .event", 22)).resolves.toBe(true); - }); - }); - //Will contain everyday an fullDayEvent that starts today and ends tomorrow, and one starting tomorrow and ending the day after tomorrow describe("FullDayEvent over several days should show how many days are left from the from the starting date on", () => { beforeAll(async () => { diff --git a/tests/e2e/modules/compliments_spec.js b/tests/e2e/modules/compliments_spec.js index 95b342577e..7763dc689b 100644 --- a/tests/e2e/modules/compliments_spec.js +++ b/tests/e2e/modules/compliments_spec.js @@ -77,5 +77,16 @@ describe("Compliments module", () => { await expect(doTest(["Special day message"])).resolves.toBe(true); }); }); + + describe("cron type key", () => { + beforeAll(async () => { + await helpers.startApplication("tests/configs/modules/compliments/compliments_e2e_cron_entry.js"); + await helpers.getDocument(); + }); + + it("compliments array contains only special value", async () => { + await expect(doTest(["anytime cron"])).resolves.toBe(true); + }); + }); }); }); diff --git a/tests/e2e/modules/newsfeed_spec.js b/tests/e2e/modules/newsfeed_spec.js index 141b880661..1c3c4d288d 100644 --- a/tests/e2e/modules/newsfeed_spec.js +++ b/tests/e2e/modules/newsfeed_spec.js @@ -1,10 +1,7 @@ +const fs = require("node:fs"); const helpers = require("../helpers/global-setup"); -describe("Newsfeed module", () => { - afterAll(async () => { - await helpers.stopApplication(); - }); - +const runTests = async () => { describe("Default configuration", () => { beforeAll(async () => { await helpers.startApplication("tests/configs/modules/newsfeed/default.js"); @@ -74,4 +71,28 @@ describe("Newsfeed module", () => { expect(elem.textContent).toContain("No news at the moment."); }); }); +}; + +describe("Newsfeed module", () => { + afterAll(async () => { + await helpers.stopApplication(); + }); + + runTests(); +}); + +describe("Newsfeed module located in config directory", () => { + beforeAll(() => { + const baseDir = `${__dirname}/../../..`; + if (!fs.existsSync(`${baseDir}/config/newsfeed`)) { + fs.cpSync(`${baseDir}/modules/default/newsfeed`, `${baseDir}/config/newsfeed`, { recursive: true }); + } + process.env.MM_MODULES_DIR = "config"; + }); + + afterAll(async () => { + await helpers.stopApplication(); + }); + + runTests(); }); diff --git a/tests/e2e/modules/weather_hourly_spec.js b/tests/e2e/modules/weather_hourly_spec.js index f61cee0546..861ff50f74 100644 --- a/tests/e2e/modules/weather_hourly_spec.js +++ b/tests/e2e/modules/weather_hourly_spec.js @@ -53,8 +53,8 @@ describe("Weather module: Weather Hourly Forecast", () => { }); describe("Shows precipitation probability", () => { - const propabilities = [undefined, undefined, "12 %", "36 %", "44 %"]; - for (const [index, pop] of propabilities.entries()) { + const probabilities = [undefined, undefined, "12 %", "36 %", "44 %"]; + for (const [index, pop] of probabilities.entries()) { if (pop) { it(`should render probability ${pop}`, async () => { await expect(weatherFunc.getText(`.weather table.small tr:nth-child(${index + 1}) td.precipitation-prob`, pop)).resolves.toBe(true); diff --git a/tests/e2e/modules_display_spec.js b/tests/e2e/modules_display_spec.js index c8dba6e9f8..88b9ff50be 100644 --- a/tests/e2e/modules_display_spec.js +++ b/tests/e2e/modules_display_spec.js @@ -12,7 +12,7 @@ describe("Display of modules", () => { it("should show the test header", async () => { const elem = await helpers.waitForElement("#module_0_helloworld .module-header"); expect(elem).not.toBeNull(); - // textContent gibt hier lowercase zurück, das uppercase wird durch css realisiert, was daher nicht in textContent landet + // textContent returns lowercase here, the uppercase is realized by CSS, which therefore does not end up in textContent expect(elem.textContent).toBe("test_header"); }); diff --git a/tests/e2e/serveronly_spec.js b/tests/e2e/serveronly_spec.js index c33a78d292..70db4aaa10 100644 --- a/tests/e2e/serveronly_spec.js +++ b/tests/e2e/serveronly_spec.js @@ -7,7 +7,7 @@ describe("App environment", () => { beforeAll(async () => { process.env.MM_CONFIG_FILE = "tests/configs/default.js"; serverProcess = await require("node:child_process").spawn("npm", ["run", "server"], { env: process.env, detached: true }); - // we have to wait until the server is startet + // we have to wait until the server is started await delay(2000); }); afterAll(async () => { diff --git a/tests/electron/modules/calendar_spec.js b/tests/electron/modules/calendar_spec.js index 4e6aee17a2..8731c3cd1a 100644 --- a/tests/electron/modules/calendar_spec.js +++ b/tests/electron/modules/calendar_spec.js @@ -13,6 +13,15 @@ describe("Calendar module", () => { return true; }; + const doTestCount = async () => { + expect(global.page).not.toBeNull(); + const loc = await global.page.locator(".calendar .event"); + const elem = loc.first(); + await elem.waitFor(); + expect(elem).not.toBeNull(); + return await loc.count(); + }; + afterEach(async () => { await helpers.stopApplication(); }); @@ -44,112 +53,98 @@ describe("Calendar module", () => { }); }); - /****************************/ - // RRULE TESTS: - // Add any tests that check rrule functionality here. + describe("Events from multiple calendars", () => { + it("should show multiple events with the same title and start time from different calendars", async () => { + await helpers.startApplication("tests/configs/modules/calendar/show-duplicates-in-calendar.js", "15 Sep 2024 12:30:00 GMT"); + await expect(doTestCount()).resolves.toBe(20); + }); + }); + + /* + * RRULE TESTS: + * Add any tests that check rrule functionality here. + */ describe("rrule", () => { it("Issue #3393 recurrence dates past rrule until date", async () => { await helpers.startApplication("tests/configs/modules/calendar/rrule_until.js", "07 Mar 2024 10:38:00 GMT-07:00", ["js/electron.js"], "America/Los_Angeles"); - expect(global.page).not.toBeNull(); - const loc = await global.page.locator(".calendar .event"); - const elem = loc.first(); - await elem.waitFor(); - expect(elem).not.toBeNull(); - const cnt = await loc.count(); - expect(cnt).toBe(1); + await expect(doTestCount()).resolves.toBe(1); }); }); - /****************************/ - // LOS ANGELES TESTS: - // In 2023, DST (GMT-7) was until 5 Nov, after which is standard (STD) (GMT-8) time. - // Test takes place on Thu 19 Oct, recurring event on a Wednesday. maximumNumberOfDays=28, so there should be - // 4 events (25 Oct, 1 Nov, (switch to STD), 8 Nov, Nov 15), but 1 Nov and 8 Nov are excluded. - // There are three separate tests: - // * before midnight GMT (3pm local time) - // * at midnight GMT in STD time (4pm local time) - // * at midnight GMT in DST time (5pm local time) + /* + * LOS ANGELES TESTS: + * In 2023, DST (GMT-7) was until 5 Nov, after which is standard (STD) (GMT-8) time. + * Test takes place on Thu 19 Oct, recurring event on a Wednesday. maximumNumberOfDays=28, so there should be + * 4 events (25 Oct, 1 Nov, (switch to STD), 8 Nov, Nov 15), but 1 Nov and 8 Nov are excluded. + * There are three separate tests: + * * before midnight GMT (3pm local time) + * * at midnight GMT in STD time (4pm local time) + * * at midnight GMT in DST time (5pm local time) + */ describe("Exdate: LA crossover DST before midnight GMT", () => { it("LA crossover DST before midnight GMT should have 2 events", async () => { await helpers.startApplication("tests/configs/modules/calendar/exdate_la_before_midnight.js", "19 Oct 2023 12:30:00 GMT-07:00", ["js/electron.js"], "America/Los_Angeles"); - expect(global.page).not.toBeNull(); - const loc = await global.page.locator(".calendar .event"); - const elem = loc.first(); - await elem.waitFor(); - expect(elem).not.toBeNull(); - const cnt = await loc.count(); - expect(cnt).toBe(2); + await expect(doTestCount()).resolves.toBe(2); }); }); describe("Exdate: LA crossover DST at midnight GMT local STD", () => { it("LA crossover DST before midnight GMT should have 2 events", async () => { await helpers.startApplication("tests/configs/modules/calendar/exdate_la_at_midnight_std.js", "19 Oct 2023 12:30:00 GMT-07:00", ["js/electron.js"], "America/Los_Angeles"); - expect(global.page).not.toBeNull(); - const loc = await global.page.locator(".calendar .event"); - const elem = loc.first(); - await elem.waitFor(); - expect(elem).not.toBeNull(); - const cnt = await loc.count(); - expect(cnt).toBe(2); + await expect(doTestCount()).resolves.toBe(2); }); }); describe("Exdate: LA crossover DST at midnight GMT local DST", () => { it("LA crossover DST before midnight GMT should have 2 events", async () => { await helpers.startApplication("tests/configs/modules/calendar/exdate_la_at_midnight_dst.js", "19 Oct 2023 12:30:00 GMT-07:00", ["js/electron.js"], "America/Los_Angeles"); - expect(global.page).not.toBeNull(); - const loc = await global.page.locator(".calendar .event"); - const elem = loc.first(); - await elem.waitFor(); - expect(elem).not.toBeNull(); - const cnt = await loc.count(); - expect(cnt).toBe(2); + await expect(doTestCount()).resolves.toBe(2); }); }); - /****************************/ - // SYDNEY TESTS: - // In 2023, standard time (STD) (GMT+10) was until 1 Oct, after which is DST (GMT+11). - // Test takes place on Thu 14 Sep, recurring event on a Wednesday. maximumNumberOfDays=28, so there should be - // 4 events (20 Sep, 27 Sep, (switch to DST), 4 Oct, 11 Oct), but 27 Sep and 4 Oct are excluded. - // There are three separate tests: - // * before midnight GMT (9am local time) - // * at midnight GMT in STD time (10am local time) - // * at midnight GMT in DST time (11am local time) + /* + * SYDNEY TESTS: + * In 2023, standard time (STD) (GMT+10) was until 1 Oct, after which is DST (GMT+11). + * Test takes place on Thu 14 Sep, recurring event on a Wednesday. maximumNumberOfDays=28, so there should be + * 4 events (20 Sep, 27 Sep, (switch to DST), 4 Oct, 11 Oct), but 27 Sep and 4 Oct are excluded. + * There are three separate tests: + * * before midnight GMT (9am local time) + * * at midnight GMT in STD time (10am local time) + * * at midnight GMT in DST time (11am local time) + */ describe("Exdate: SYD crossover DST before midnight GMT", () => { it("LA crossover DST before midnight GMT should have 2 events", async () => { await helpers.startApplication("tests/configs/modules/calendar/exdate_syd_before_midnight.js", "14 Sep 2023 12:30:00 GMT+10:00", ["js/electron.js"], "Australia/Sydney"); - expect(global.page).not.toBeNull(); - const loc = await global.page.locator(".calendar .event"); - const elem = loc.first(); - await elem.waitFor(); - expect(elem).not.toBeNull(); - const cnt = await loc.count(); - expect(cnt).toBe(2); + await expect(doTestCount()).resolves.toBe(2); }); }); describe("Exdate: SYD crossover DST at midnight GMT local STD", () => { it("LA crossover DST before midnight GMT should have 2 events", async () => { await helpers.startApplication("tests/configs/modules/calendar/exdate_syd_at_midnight_std.js", "14 Sep 2023 12:30:00 GMT+10:00", ["js/electron.js"], "Australia/Sydney"); - expect(global.page).not.toBeNull(); - const loc = await global.page.locator(".calendar .event"); - const elem = loc.first(); - await elem.waitFor(); - expect(elem).not.toBeNull(); - const cnt = await loc.count(); - expect(cnt).toBe(2); + await expect(doTestCount()).resolves.toBe(2); }); }); describe("Exdate: SYD crossover DST at midnight GMT local DST", () => { it("SYD crossover DST at midnight GMT local DST should have 2 events", async () => { await helpers.startApplication("tests/configs/modules/calendar/exdate_syd_at_midnight_dst.js", "14 Sep 2023 12:30:00 GMT+10:00", ["js/electron.js"], "Australia/Sydney"); + await expect(doTestCount()).resolves.toBe(2); + }); + }); + + /* + * RRULE TESTS: + * Add any tests that check rrule functionality here. + */ + describe("sliceMultiDayEvents", () => { + it("Issue #3452 split multiday in Europe", async () => { + await helpers.startApplication("tests/configs/modules/calendar/sliceMultiDayEvents.js", "01 Sept 2024 10:38:00 GMT+02:00", ["js/electron.js"], "Europe/Berlin"); expect(global.page).not.toBeNull(); const loc = await global.page.locator(".calendar .event"); const elem = loc.first(); await elem.waitFor(); expect(elem).not.toBeNull(); const cnt = await loc.count(); - expect(cnt).toBe(2); + expect(cnt).toBe(6); }); }); + }); diff --git a/tests/electron/modules/compliments_spec.js b/tests/electron/modules/compliments_spec.js index b4c4ed845b..15c3c37c08 100644 --- a/tests/electron/modules/compliments_spec.js +++ b/tests/electron/modules/compliments_spec.js @@ -43,5 +43,41 @@ describe("Compliments module", () => { await expect(doTest(["Happy new year!"])).resolves.toBe(true); }); }); + + describe("Test only custom date events shown with new property", () => { + it("shows 'Special day message' on May 6", async () => { + await helpers.startApplication("tests/configs/modules/compliments/compliments_specialDayUnique_true.js", "06 May 2022 10:00:00 GMT"); + await expect(doTest(["Special day message"])).resolves.toBe(true); + }); + }); + + describe("Test all date events shown without new property", () => { + it("shows 'any message' on May 6", async () => { + await helpers.startApplication("tests/configs/modules/compliments/compliments_specialDayUnique_false.js", "06 May 2022 10:00:00 GMT"); + await expect(doTest(["Special day message", "Typical message 1", "Typical message 2", "Typical message 3"])).resolves.toBe(true); + }); + }); + + describe("Test only custom cron date event shown with new property", () => { + it("shows 'any message' on May 6", async () => { + await helpers.startApplication("tests/configs/modules/compliments/compliments_cron_entry.js", "06 May 2022 17:03:00 GMT"); + await expect(doTest(["just pub time"])).resolves.toBe(true); + }); + }); + + describe("Test any event shows after time window", () => { + it("shows 'any message' on May 6", async () => { + await helpers.startApplication("tests/configs/modules/compliments/compliments_cron_entry.js", "06 May 2022 17:11:00 GMT"); + await expect(doTest(["just a test"])).resolves.toBe(true); + }); + }); + + describe("Test any event shows different day", () => { + it("shows 'any message' on May 5", async () => { + await helpers.startApplication("tests/configs/modules/compliments/compliments_cron_entry.js", "05 May 2022 17:00:00 GMT"); + await expect(doTest(["just a test"])).resolves.toBe(true); + }); + }); + }); }); diff --git a/tests/mocks/sliceMultiDayEvents.ics b/tests/mocks/sliceMultiDayEvents.ics new file mode 100644 index 0000000000..d477246f16 --- /dev/null +++ b/tests/mocks/sliceMultiDayEvents.ics @@ -0,0 +1,58 @@ +BEGIN:VCALENDAR +PRODID:-//Google Inc//Google Calendar 70.9054//EN +VERSION:2.0 +CALSCALE:GREGORIAN +METHOD:PUBLISH +X-WR-CALNAME:Dirk Test +X-WR-TIMEZONE:Europe/Berlin +BEGIN:VEVENT +DTSTART;VALUE=DATE:20240918 +DTEND;VALUE=DATE:20240919 +DTSTAMP:20240916T084410Z +UID:2crbv1ijljc2kt9jclkgu5hqa0@google.com +CREATED:20240916T083831Z +LAST-MODIFIED:20240916T083831Z +SEQUENCE:0 +STATUS:CONFIRMED +SUMMARY:1 day single +TRANSP:TRANSPARENT +END:VEVENT +BEGIN:VEVENT +DTSTART;VALUE=DATE:20240919 +DTEND;VALUE=DATE:20240920 +RRULE:FREQ=YEARLY +DTSTAMP:20240916T084410Z +UID:6gb19havnq6vp2qput51e5rmml@google.com +CREATED:20240916T083850Z +LAST-MODIFIED:20240916T083850Z +SEQUENCE:0 +STATUS:CONFIRMED +SUMMARY:1 day repeat +TRANSP:TRANSPARENT +END:VEVENT +BEGIN:VEVENT +DTSTART;VALUE=DATE:20240920 +DTEND;VALUE=DATE:20240922 +DTSTAMP:20240916T084410Z +UID:06e9u1trbqi3jbvstvq4qqutau@google.com +CREATED:20240916T083902Z +LAST-MODIFIED:20240916T083902Z +SEQUENCE:0 +STATUS:CONFIRMED +SUMMARY:2 day single +TRANSP:TRANSPARENT +END:VEVENT +BEGIN:VEVENT +DTSTART;VALUE=DATE:20240923 +DTEND;VALUE=DATE:20240925 +RRULE:FREQ=YEARLY +DTSTAMP:20240916T084410Z +UID:0ui78rk6hpcv8rmbb6nuonhmgg@google.com +CREATED:20240916T083919Z +LAST-MODIFIED:20240916T083919Z +SEQUENCE:0 +STATUS:CONFIRMED +SUMMARY:2 day repeat +TRANSP:TRANSPARENT +END:VEVENT +END:VCALENDAR \ No newline at end of file diff --git a/tests/unit/functions/server_functions_spec.js b/tests/unit/functions/server_functions_spec.js index f5fb98f2f0..d394d055c3 100644 --- a/tests/unit/functions/server_functions_spec.js +++ b/tests/unit/functions/server_functions_spec.js @@ -19,7 +19,7 @@ describe("server_functions tests", () => { }, text: fetchResponseHeadersText }; - // eslint-disable-next-line + fetch = jest.fn(); fetch.mockImplementation(() => fetchResponse); @@ -45,7 +45,7 @@ describe("server_functions tests", () => { expect(fetchMock.mock.calls[0][0]).toBe(urlToCall); }); - it("Forewards Content-Type if json", async () => { + it("Forwards Content-Type if json", async () => { fetchResponseHeadersGet.mockImplementation(() => "json"); await cors(request, corsResponse); @@ -58,7 +58,7 @@ describe("server_functions tests", () => { expect(corsResponse.set.mock.calls[0][1]).toBe("json"); }); - it("Forewards Content-Type if xml", async () => { + it("Forwards Content-Type if xml", async () => { fetchResponseHeadersGet.mockImplementation(() => "xml"); await cors(request, corsResponse); diff --git a/tests/unit/modules/default/weather/weather_utils_spec.js b/tests/unit/modules/default/weather/weather_utils_spec.js index a0c41edb05..979fba2fa8 100644 --- a/tests/unit/modules/default/weather/weather_utils_spec.js +++ b/tests/unit/modules/default/weather/weather_utils_spec.js @@ -47,7 +47,7 @@ describe("Weather utils tests", () => { expect(WeatherUtils.calculateFeelsLike(0, 20, 40)).toBe(-9.444444444444445); }); - it("should return a calculated feelsLike info (positiv value)", () => { + it("should return a calculated feelsLike info (positive value)", () => { expect(WeatherUtils.calculateFeelsLike(30, 0, 60)).toBe(32.8320322777777); }); }); diff --git a/vendor/package-lock.json b/vendor/package-lock.json index 2df570b22a..413d00ea06 100644 --- a/vendor/package-lock.json +++ b/vendor/package-lock.json @@ -9,8 +9,9 @@ "version": "1.0.0", "license": "MIT", "dependencies": { - "@fortawesome/fontawesome-free": "^6.5.2", + "@fortawesome/fontawesome-free": "^6.6.0", "animate.css": "^4.1.1", + "croner": "^8.1.2", "moment": "^2.30.1", "moment-timezone": "^0.5.45", "nunjucks": "^3.2.4", @@ -19,10 +20,10 @@ } }, "node_modules/@fortawesome/fontawesome-free": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-free/-/fontawesome-free-6.5.2.tgz", - "integrity": "sha512-hRILoInAx8GNT5IMkrtIt9blOdrqHOnPBH+k70aWUAqPZPgopb9G5EQJFpaBx/S8zp2fC+mPW349Bziuk1o28Q==", - "hasInstallScript": true, + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-free/-/fontawesome-free-6.6.0.tgz", + "integrity": "sha512-60G28ke/sXdtS9KZCpZSHHkCbdsOGEhIUGlwq6yhY74UpTiToIh8np7A8yphhM4BWsvNFtIvLpi4co+h9Mr9Ow==", + "license": "(CC-BY-4.0 AND OFL-1.1 AND MIT)", "engines": { "node": ">=6" } @@ -30,30 +31,44 @@ "node_modules/a-sync-waterfall": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/a-sync-waterfall/-/a-sync-waterfall-1.0.1.tgz", - "integrity": "sha512-RYTOHHdWipFUliRFMCS4X2Yn2X8M87V/OpSqWzKKOGhzqyUxzyVmhHDH9sAvG+ZuQf/TAOFsLCpMw09I1ufUnA==" + "integrity": "sha512-RYTOHHdWipFUliRFMCS4X2Yn2X8M87V/OpSqWzKKOGhzqyUxzyVmhHDH9sAvG+ZuQf/TAOFsLCpMw09I1ufUnA==", + "license": "MIT" }, "node_modules/animate.css": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/animate.css/-/animate.css-4.1.1.tgz", - "integrity": "sha512-+mRmCTv6SbCmtYJCN4faJMNFVNN5EuCTTprDTAo7YzIGji2KADmakjVA3+8mVDkZ2Bf09vayB35lSQIex2+QaQ==" + "integrity": "sha512-+mRmCTv6SbCmtYJCN4faJMNFVNN5EuCTTprDTAo7YzIGji2KADmakjVA3+8mVDkZ2Bf09vayB35lSQIex2+QaQ==", + "license": "MIT" }, "node_modules/asap": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", - "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==" + "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==", + "license": "MIT" }, "node_modules/commander": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/commander/-/commander-5.1.0.tgz", "integrity": "sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==", + "license": "MIT", "engines": { "node": ">= 6" } }, + "node_modules/croner": { + "version": "8.1.2", + "resolved": "https://registry.npmjs.org/croner/-/croner-8.1.2.tgz", + "integrity": "sha512-ypfPFcAXHuAZRCzo3vJL6ltENzniTjwe/qsLleH1V2/7SRDjgvRQyrLmumFTLmjFax4IuSxfGXEn79fozXcJog==", + "license": "MIT", + "engines": { + "node": ">=18.0" + } + }, "node_modules/moment": { "version": "2.30.1", "resolved": "https://registry.npmjs.org/moment/-/moment-2.30.1.tgz", "integrity": "sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how==", + "license": "MIT", "engines": { "node": "*" } @@ -62,6 +77,7 @@ "version": "0.5.45", "resolved": "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.5.45.tgz", "integrity": "sha512-HIWmqA86KcmCAhnMAN0wuDOARV/525R2+lOLotuGFzn4HO+FH+/645z2wx0Dt3iDv6/p61SIvKnDstISainhLQ==", + "license": "MIT", "dependencies": { "moment": "^2.29.4" }, @@ -73,6 +89,7 @@ "version": "3.2.4", "resolved": "https://registry.npmjs.org/nunjucks/-/nunjucks-3.2.4.tgz", "integrity": "sha512-26XRV6BhkgK0VOxfbU5cQI+ICFUtMLixv1noZn1tGU38kQH5A5nmmbk/O45xdyBhD1esk47nKrY0mvQpZIhRjQ==", + "license": "BSD-2-Clause", "dependencies": { "a-sync-waterfall": "^1.0.0", "asap": "^2.0.3", @@ -101,7 +118,8 @@ "node_modules/weathericons": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/weathericons/-/weathericons-2.1.0.tgz", - "integrity": "sha512-V45viuyuQQOuoePTqzxvP/wBpYALWkD695fkFvqpn+BiMyo64fFlyDbP2A8umZyFyz1cXFPNw1pWqeaSaQqJlQ==" + "integrity": "sha512-V45viuyuQQOuoePTqzxvP/wBpYALWkD695fkFvqpn+BiMyo64fFlyDbP2A8umZyFyz1cXFPNw1pWqeaSaQqJlQ==", + "license": "MIT" } } } diff --git a/vendor/package.json b/vendor/package.json index efaa4f151e..8e7365e2e7 100644 --- a/vendor/package.json +++ b/vendor/package.json @@ -11,8 +11,9 @@ }, "license": "MIT", "dependencies": { - "@fortawesome/fontawesome-free": "^6.5.2", + "@fortawesome/fontawesome-free": "^6.6.0", "animate.css": "^4.1.1", + "croner": "^8.1.2", "moment": "^2.30.1", "moment-timezone": "^0.5.45", "nunjucks": "^3.2.4", diff --git a/vendor/vendor.js b/vendor/vendor.js index b2d912d4de..ee3f0bb777 100644 --- a/vendor/vendor.js +++ b/vendor/vendor.js @@ -5,7 +5,8 @@ const vendor = { "weather-icons-wind.css": "node_modules/weathericons/css/weather-icons-wind.css", "font-awesome.css": "css/font-awesome.css", "nunjucks.js": "node_modules/nunjucks/browser/nunjucks.min.js", - "suncalc.js": "node_modules/suncalc/suncalc.js" + "suncalc.js": "node_modules/suncalc/suncalc.js", + "croner.js": "node_modules/croner/dist/croner.umd.min.js" }; if (typeof module !== "undefined") {