Merge branch 'main' into feature/FixQBittorrentImportPath

This commit is contained in:
jwmann 2026-05-15 18:29:27 -04:00
commit cc977cfe29
No known key found for this signature in database
GPG key ID: FEAF88A73A68BD1B
9 changed files with 377 additions and 268 deletions

View file

@ -6,6 +6,17 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased
## [2.0.131] - 2026-05-14
### Changed
- Fixes to the rate limiting.
## [2.0.130] - 2026-04-28
### Changed
- Fixes to unit tests
- Upgraded .NET and Angular dependencies
- Added better qBittorrent capabilities for Cleanuparr
- Performance fixes
## [2.0.129] - 2026-04-06
### Added
- Optimized mobile views, thanks to @sylvaindd!

View file

@ -1,4 +1,4 @@
const minorOnly = ["eslint"];
const minorOnly = ["eslint", "typescript"];
const patchOnly = [];
module.exports = {

485
client/package-lock.json generated
View file

@ -8,42 +8,42 @@
"name": "client",
"version": "0.0.0",
"dependencies": {
"@angular/animations": "^21.2.4",
"@angular/cdk": "^21.2.2",
"@angular/common": "^21.2.4",
"@angular/compiler": "^21.2.4",
"@angular/core": "^21.2.4",
"@angular/forms": "^21.2.4",
"@angular/platform-browser": "^21.2.4",
"@angular/platform-browser-dynamic": "^21.2.4",
"@angular/router": "^21.2.4",
"@angular/animations": "^21.2.10",
"@angular/cdk": "^21.2.8",
"@angular/common": "^21.2.10",
"@angular/compiler": "^21.2.10",
"@angular/core": "^21.2.10",
"@angular/forms": "^21.2.10",
"@angular/platform-browser": "^21.2.10",
"@angular/platform-browser-dynamic": "^21.2.10",
"@angular/router": "^21.2.10",
"@fortawesome/fontawesome-free": "^7.2.0",
"@microsoft/signalr": "^10.0.0",
"bulma": "^1.0.4",
"curray": "^1.0.12",
"file-saver-es": "^2.0.5",
"filesize": "^11.0.13",
"filesize": "^11.0.17",
"rxjs": "^7.8.2",
"tslib": "^2.8.1",
"zone.js": "^0.16.1"
},
"devDependencies": {
"@angular-eslint/builder": "21.3.0",
"@angular-eslint/eslint-plugin": "21.3.0",
"@angular-eslint/eslint-plugin-template": "21.3.0",
"@angular-eslint/schematics": "21.3.0",
"@angular-eslint/template-parser": "21.3.0",
"@angular/build": "^21.2.2",
"@angular/cli": "^21.2.2",
"@angular/compiler-cli": "^21.2.4",
"@angular/language-service": "^21.2.4",
"@angular-eslint/builder": "21.3.1",
"@angular-eslint/eslint-plugin": "21.3.1",
"@angular-eslint/eslint-plugin-template": "21.3.1",
"@angular-eslint/schematics": "21.3.1",
"@angular-eslint/template-parser": "21.3.1",
"@angular/build": "^21.2.8",
"@angular/cli": "^21.2.8",
"@angular/compiler-cli": "^21.2.10",
"@angular/language-service": "^21.2.10",
"@types/file-saver": "^2.0.7",
"@types/file-saver-es": "^2.0.3",
"@types/node": "^25.5.0",
"@typescript-eslint/eslint-plugin": "^8.57.0",
"@typescript-eslint/parser": "^8.57.0",
"@types/node": "^25.6.0",
"@typescript-eslint/eslint-plugin": "^8.59.1",
"@typescript-eslint/parser": "^8.59.1",
"eslint": "^9.39.4",
"prettier": "^3.8.1",
"prettier": "^3.8.3",
"typescript": "5.9.3"
}
},
@ -271,13 +271,13 @@
}
},
"node_modules/@angular-devkit/architect": {
"version": "0.2102.2",
"resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.2102.2.tgz",
"integrity": "sha512-CDvFtXwyBtMRkTQnm+LfBNLL0yLV8ZGskrM1T6VkcGwXGFDott1FxUdj96ViodYsYL5fbJr0MNA6TlLcanV3kQ==",
"version": "0.2102.8",
"resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.2102.8.tgz",
"integrity": "sha512-b7su7AHIO5F2I6InEu/Bx/oXvGjdCP7kos2tGX73he/lPrTuizooils62OgAzgJ2UeKscyRNUjBPieFCy6XvHQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"@angular-devkit/core": "21.2.2",
"@angular-devkit/core": "21.2.8",
"rxjs": "7.8.2"
},
"bin": {
@ -290,16 +290,16 @@
}
},
"node_modules/@angular-devkit/core": {
"version": "21.2.2",
"resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-21.2.2.tgz",
"integrity": "sha512-xUeKGe4BDQpkz0E6fnAPIJXE0y0nqtap0KhJIBhvN7xi3NenIzTmoi6T9Yv5OOBUdLZbOm4SOel8MhdXiIBpAQ==",
"version": "21.2.8",
"resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-21.2.8.tgz",
"integrity": "sha512-DyxCILaaic/hfcfiBjAC/SdKE1ybSQIrU62/K5Msn3gZtThZj/T7cG0VHfbmpEFcgYkrQ9caUt6MCg8OoOVDzw==",
"dev": true,
"license": "MIT",
"dependencies": {
"ajv": "8.18.0",
"ajv-formats": "3.0.1",
"jsonc-parser": "3.3.1",
"picomatch": "4.0.3",
"picomatch": "4.0.4",
"rxjs": "7.8.2",
"source-map": "0.7.6"
},
@ -335,13 +335,13 @@
}
},
"node_modules/@angular-devkit/schematics": {
"version": "21.2.2",
"resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-21.2.2.tgz",
"integrity": "sha512-CCeyQxGUq+oyGnHd7PfcYIVbj9pRnqjQq0rAojoAqs1BJdtInx9weLBCLy+AjM3NHePeZrnwm+wEVr8apED8kg==",
"version": "21.2.8",
"resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-21.2.8.tgz",
"integrity": "sha512-UTEMM1JXzzxufLsTGDsWth2E7+8e9PaFT7nbjUvJ2qevltACkiqAbHEpiD2ISzrSRIO3OirJ+cZtnzXO0FyoBQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"@angular-devkit/core": "21.2.2",
"@angular-devkit/core": "21.2.8",
"jsonc-parser": "3.3.1",
"magic-string": "0.30.21",
"ora": "9.3.0",
@ -354,9 +354,9 @@
}
},
"node_modules/@angular-eslint/builder": {
"version": "21.3.0",
"resolved": "https://registry.npmjs.org/@angular-eslint/builder/-/builder-21.3.0.tgz",
"integrity": "sha512-26QUUouei52biUFAlJSrWNAU9tuF2miKwd8uHdxWwCF31xz+OxC5+NfudWvt1AFaYow7gWueX1QX3rNNtSPDrg==",
"version": "21.3.1",
"resolved": "https://registry.npmjs.org/@angular-eslint/builder/-/builder-21.3.1.tgz",
"integrity": "sha512-1f1Lyp5e7OH6txiV224HaY3G1uRCj91OSKq7hT2Vw9NRw6zWFc1anBpDeLVjpL9ptUxzUGIQR5jEV54hOPayoQ==",
"dev": true,
"license": "MIT",
"dependencies": {
@ -370,21 +370,21 @@
}
},
"node_modules/@angular-eslint/bundled-angular-compiler": {
"version": "21.3.0",
"resolved": "https://registry.npmjs.org/@angular-eslint/bundled-angular-compiler/-/bundled-angular-compiler-21.3.0.tgz",
"integrity": "sha512-l521I24J9gJxyMbRkrM24Tc7W8J8BP+TDAmVs2nT8+lXbS3kg8QpWBRtd+hNUgq6o+vt+lKBkytnEfu8OiqeRg==",
"version": "21.3.1",
"resolved": "https://registry.npmjs.org/@angular-eslint/bundled-angular-compiler/-/bundled-angular-compiler-21.3.1.tgz",
"integrity": "sha512-jjbnJPUXQeQBJ8RM+ahlbt4GH2emVN8JvG3AhFbPci1FrqXi9cOOfkbwLmvpoyTli4LF8gy7g4ctFqnlRgqryw==",
"dev": true,
"license": "MIT"
},
"node_modules/@angular-eslint/eslint-plugin": {
"version": "21.3.0",
"resolved": "https://registry.npmjs.org/@angular-eslint/eslint-plugin/-/eslint-plugin-21.3.0.tgz",
"integrity": "sha512-Whf/AUUBekOlfSJRS78m76YGrBQAZ3waXE7oOdlW5xEQvn8jBDN9EGuNnjg/syZzvzjK4ZpYC4g1XYXrc+fQIg==",
"version": "21.3.1",
"resolved": "https://registry.npmjs.org/@angular-eslint/eslint-plugin/-/eslint-plugin-21.3.1.tgz",
"integrity": "sha512-08NNTxwawRLTWPLl8dg1BnXMwimx93y4wMEwx2aWQpJbIt4pmNvwJzd+NgoD/Ag2VdLS/gOMadhJH5fgaYKsPQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"@angular-eslint/bundled-angular-compiler": "21.3.0",
"@angular-eslint/utils": "21.3.0",
"@angular-eslint/bundled-angular-compiler": "21.3.1",
"@angular-eslint/utils": "21.3.1",
"ts-api-utils": "^2.1.0"
},
"peerDependencies": {
@ -394,19 +394,19 @@
}
},
"node_modules/@angular-eslint/eslint-plugin-template": {
"version": "21.3.0",
"resolved": "https://registry.npmjs.org/@angular-eslint/eslint-plugin-template/-/eslint-plugin-template-21.3.0.tgz",
"integrity": "sha512-lVixd/KypPWgA/5/pUOhJV9MTcaHjYZEqyOi+IiLk+h+maGxn6/s6Ot+20n+XGS85zAgOY+qUw6EEQ11hoojIQ==",
"version": "21.3.1",
"resolved": "https://registry.npmjs.org/@angular-eslint/eslint-plugin-template/-/eslint-plugin-template-21.3.1.tgz",
"integrity": "sha512-ndPWJodkcEOu2PVUxlUwyz4D2u3r9KO7veWmStVNOLeNrICJA+nQvrz2BWCu0l48rO0K5ezsy0JFcQDVwE/5mw==",
"dev": true,
"license": "MIT",
"dependencies": {
"@angular-eslint/bundled-angular-compiler": "21.3.0",
"@angular-eslint/utils": "21.3.0",
"@angular-eslint/bundled-angular-compiler": "21.3.1",
"@angular-eslint/utils": "21.3.1",
"aria-query": "5.3.2",
"axobject-query": "4.1.0"
},
"peerDependencies": {
"@angular-eslint/template-parser": "21.3.0",
"@angular-eslint/template-parser": "21.3.1",
"@typescript-eslint/types": "^7.11.0 || ^8.0.0",
"@typescript-eslint/utils": "^7.11.0 || ^8.0.0",
"eslint": "^8.57.0 || ^9.0.0 || ^10.0.0",
@ -414,16 +414,16 @@
}
},
"node_modules/@angular-eslint/schematics": {
"version": "21.3.0",
"resolved": "https://registry.npmjs.org/@angular-eslint/schematics/-/schematics-21.3.0.tgz",
"integrity": "sha512-8deU/zVY9f8k8kAQQ9PL130ox2VlrZw3fMxgsPNAY5tjQ0xk0J2YVSszYHhcqdMGG1J01IsxIjvQaJ4pFfEmMw==",
"version": "21.3.1",
"resolved": "https://registry.npmjs.org/@angular-eslint/schematics/-/schematics-21.3.1.tgz",
"integrity": "sha512-1U2u4ZsZvwT30aXRLsIJf6tULIiioo9BtASNsldpYecU3/m/1+F61lCYG79qt7YWbif9KABPYZlFTJUFGN8HWA==",
"dev": true,
"license": "MIT",
"dependencies": {
"@angular-devkit/core": ">= 21.0.0 < 22.0.0",
"@angular-devkit/schematics": ">= 21.0.0 < 22.0.0",
"@angular-eslint/eslint-plugin": "21.3.0",
"@angular-eslint/eslint-plugin-template": "21.3.0",
"@angular-eslint/eslint-plugin": "21.3.1",
"@angular-eslint/eslint-plugin-template": "21.3.1",
"ignore": "7.0.5",
"semver": "7.7.4",
"strip-json-comments": "3.1.1"
@ -433,14 +433,14 @@
}
},
"node_modules/@angular-eslint/template-parser": {
"version": "21.3.0",
"resolved": "https://registry.npmjs.org/@angular-eslint/template-parser/-/template-parser-21.3.0.tgz",
"integrity": "sha512-ysyou1zAY6M6rSZNdIcYKGd4nk6TCapamyFNB3ivmTlVZ0O35TS9o/rJ0aUttuHgDp+Ysgs3ql+LA746PXgCyQ==",
"version": "21.3.1",
"resolved": "https://registry.npmjs.org/@angular-eslint/template-parser/-/template-parser-21.3.1.tgz",
"integrity": "sha512-moERVCTekQKOvR8RMuEOtWSO3VS1qrzA3keI1dPto/JVB8Nqp9w3R5ZpEoXHzh4zgEryosxmPgdi6UczJe2ouQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"@angular-eslint/bundled-angular-compiler": "21.3.0",
"eslint-scope": "^9.1.1"
"@angular-eslint/bundled-angular-compiler": "21.3.1",
"eslint-scope": "9.1.2"
},
"peerDependencies": {
"eslint": "^8.57.0 || ^9.0.0 || ^10.0.0",
@ -467,13 +467,13 @@
}
},
"node_modules/@angular-eslint/utils": {
"version": "21.3.0",
"resolved": "https://registry.npmjs.org/@angular-eslint/utils/-/utils-21.3.0.tgz",
"integrity": "sha512-oNigH6w3l+owTMboj/uFG0tHOy43uH8BpQRtBOQL1/s2+5in/BJ2Fjobv3SyizxTgeJ1FhRefbkT8GmVjK7jAA==",
"version": "21.3.1",
"resolved": "https://registry.npmjs.org/@angular-eslint/utils/-/utils-21.3.1.tgz",
"integrity": "sha512-Q3SGA1/36phZhmsp1mYrKzp/jcmqofRr861MYn46FaWIKSYXBYRzl+H3FIJKBu5CE36Bggu6hbNpwGPuUp+MCg==",
"dev": true,
"license": "MIT",
"dependencies": {
"@angular-eslint/bundled-angular-compiler": "21.3.0"
"@angular-eslint/bundled-angular-compiler": "21.3.1"
},
"peerDependencies": {
"@typescript-eslint/utils": "^7.11.0 || ^8.0.0",
@ -482,9 +482,9 @@
}
},
"node_modules/@angular/animations": {
"version": "21.2.4",
"resolved": "https://registry.npmjs.org/@angular/animations/-/animations-21.2.4.tgz",
"integrity": "sha512-hO1P7ks9n7lW3D31bzHohSuoAaj05xJUlK8rZgX8IkH5DLx4qhvfNh0t4bbLuBJLP2r1TaLsQ8KFcemCkFRO2w==",
"version": "21.2.10",
"resolved": "https://registry.npmjs.org/@angular/animations/-/animations-21.2.10.tgz",
"integrity": "sha512-sIzAcxwtRCJ/fu0tK4mo1ooiEaDxJ+Nl6s9nK1D1NP1em12VX03Jx8CMixp/kVtgh4mZnm1x6psBB0FUz3U3Ug==",
"license": "MIT",
"dependencies": {
"tslib": "^2.3.0"
@ -493,18 +493,18 @@
"node": "^20.19.0 || ^22.12.0 || >=24.0.0"
},
"peerDependencies": {
"@angular/core": "21.2.4"
"@angular/core": "21.2.10"
}
},
"node_modules/@angular/build": {
"version": "21.2.2",
"resolved": "https://registry.npmjs.org/@angular/build/-/build-21.2.2.tgz",
"integrity": "sha512-Vq2eIneNxzhHm1MwEmRqEJDwHU9ODfSRDaMWwtysGMhpoMQmLdfTqkQDmkC2qVUr8mV8Z1i5I+oe5ZJaMr/PlQ==",
"version": "21.2.8",
"resolved": "https://registry.npmjs.org/@angular/build/-/build-21.2.8.tgz",
"integrity": "sha512-t0PHT7ONDMLwcjC9GaClNF+gsUKN78ofBikw4huiu6np5Rwmxp8KKCrdoRx20lOiibSolXgjZ2Ny0xxjNdNdQA==",
"dev": true,
"license": "MIT",
"dependencies": {
"@ampproject/remapping": "2.3.0",
"@angular-devkit/architect": "0.2102.2",
"@angular-devkit/architect": "0.2102.8",
"@babel/core": "7.29.0",
"@babel/helper-annotate-as-pure": "7.27.3",
"@babel/helper-split-export-declaration": "7.24.7",
@ -520,15 +520,15 @@
"magic-string": "0.30.21",
"mrmime": "2.0.1",
"parse5-html-rewriting-stream": "8.0.0",
"picomatch": "4.0.3",
"picomatch": "4.0.4",
"piscina": "5.1.4",
"rolldown": "1.0.0-rc.4",
"sass": "1.97.3",
"semver": "7.7.4",
"source-map-support": "0.5.21",
"tinyglobby": "0.2.15",
"undici": "7.22.0",
"vite": "7.3.1",
"undici": "7.24.4",
"vite": "7.3.2",
"watchpack": "2.5.1"
},
"engines": {
@ -547,7 +547,7 @@
"@angular/platform-browser": "^21.0.0",
"@angular/platform-server": "^21.0.0",
"@angular/service-worker": "^21.0.0",
"@angular/ssr": "^21.2.2",
"@angular/ssr": "^21.2.8",
"karma": "^6.4.0",
"less": "^4.2.0",
"ng-packagr": "^21.0.0",
@ -597,9 +597,9 @@
}
},
"node_modules/@angular/cdk": {
"version": "21.2.2",
"resolved": "https://registry.npmjs.org/@angular/cdk/-/cdk-21.2.2.tgz",
"integrity": "sha512-9AsZkwqy07No7+0qPydcJfXB6SpA9qLDBanoesNj5KsiZJ62PJH3oIjVyNeQEEe1HQWmSwBnhwN12OPLNMUlnw==",
"version": "21.2.8",
"resolved": "https://registry.npmjs.org/@angular/cdk/-/cdk-21.2.8.tgz",
"integrity": "sha512-WdvMLpuFcRgDWLDyin3sw5a65PQYdI0Y+4BxiMxOkesoZ2RZTBAlLKIfQ9Nz5CY3LamUTO3Qel2T8ZhJ+Cqfuw==",
"license": "MIT",
"dependencies": {
"parse5": "^8.0.0",
@ -613,19 +613,19 @@
}
},
"node_modules/@angular/cli": {
"version": "21.2.2",
"resolved": "https://registry.npmjs.org/@angular/cli/-/cli-21.2.2.tgz",
"integrity": "sha512-eZo8/qX+ZIpIWc0CN+cCX13Lbgi/031wAp8DRVhDDO6SMVtcr/ObOQ2S16+pQdOMXxiG3vby6IhzJuz9WACzMQ==",
"version": "21.2.8",
"resolved": "https://registry.npmjs.org/@angular/cli/-/cli-21.2.8.tgz",
"integrity": "sha512-Y+/US12o+7X2774oeKPsEfHeeYM2SxwnyoXfcaLR8vrMn0zxUrhHebmlz9h83th4EJEuex1Qk0JtF7j5vcwrqQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"@angular-devkit/architect": "0.2102.2",
"@angular-devkit/core": "21.2.2",
"@angular-devkit/schematics": "21.2.2",
"@angular-devkit/architect": "0.2102.8",
"@angular-devkit/core": "21.2.8",
"@angular-devkit/schematics": "21.2.8",
"@inquirer/prompts": "7.10.1",
"@listr2/prompt-adapter-inquirer": "3.0.5",
"@modelcontextprotocol/sdk": "1.26.0",
"@schematics/angular": "21.2.2",
"@schematics/angular": "21.2.8",
"@yarnpkg/lockfile": "1.1.0",
"algoliasearch": "5.48.1",
"ini": "6.0.0",
@ -648,9 +648,9 @@
}
},
"node_modules/@angular/common": {
"version": "21.2.4",
"resolved": "https://registry.npmjs.org/@angular/common/-/common-21.2.4.tgz",
"integrity": "sha512-NrP6qOuUpo3fqq14UJ1b2bIRtWsfvxh1qLqOyFV4gfBrHhXd0XffU1LUlUw1qp4w1uBSgPJ0/N5bSPUWrAguVg==",
"version": "21.2.10",
"resolved": "https://registry.npmjs.org/@angular/common/-/common-21.2.10.tgz",
"integrity": "sha512-WLyi/CRLtgALg2mmaqIuKuPnE4i+8PGt/uuz26pVqx+ASh28/TWr5KSCAMomgxEc8kt4OE7lopoQsTihrQCfEw==",
"license": "MIT",
"dependencies": {
"tslib": "^2.3.0"
@ -659,14 +659,14 @@
"node": "^20.19.0 || ^22.12.0 || >=24.0.0"
},
"peerDependencies": {
"@angular/core": "21.2.4",
"@angular/core": "21.2.10",
"rxjs": "^6.5.3 || ^7.4.0"
}
},
"node_modules/@angular/compiler": {
"version": "21.2.4",
"resolved": "https://registry.npmjs.org/@angular/compiler/-/compiler-21.2.4.tgz",
"integrity": "sha512-9+ulVK3idIo/Tu4X2ic7/V0+Uj7pqrOAbOuIirYe6Ymm3AjexuFRiGBbfcH0VJhQ5cf8TvIJ1fuh+MI4JiRIxA==",
"version": "21.2.10",
"resolved": "https://registry.npmjs.org/@angular/compiler/-/compiler-21.2.10.tgz",
"integrity": "sha512-IrgdFuzzD7NTK3WQaSfowjAPxPbnTqsgR92NsOs5ZaWu3RgLl21dHThNc0BK1KwVwppLUSWmD4qePbcLW71VzQ==",
"license": "MIT",
"dependencies": {
"tslib": "^2.3.0"
@ -676,9 +676,9 @@
}
},
"node_modules/@angular/compiler-cli": {
"version": "21.2.4",
"resolved": "https://registry.npmjs.org/@angular/compiler-cli/-/compiler-cli-21.2.4.tgz",
"integrity": "sha512-vGjd7DZo/Ox50pQCm5EycmBu91JclimPtZoyNXu/2hSxz3oAkzwiHCwlHwk2g58eheSSp+lYtYRLmHAqSVZLjg==",
"version": "21.2.10",
"resolved": "https://registry.npmjs.org/@angular/compiler-cli/-/compiler-cli-21.2.10.tgz",
"integrity": "sha512-FDcnj3ogRmnTca4m2GbKP2khFOCtoVvWDZyfw2ZCPAf+zsQlKTyscKvx4GpTFo+KHrYXpawUpDIWHORFpuqFEA==",
"dev": true,
"license": "MIT",
"dependencies": {
@ -699,7 +699,7 @@
"node": "^20.19.0 || ^22.12.0 || >=24.0.0"
},
"peerDependencies": {
"@angular/compiler": "21.2.4",
"@angular/compiler": "21.2.10",
"typescript": ">=5.9 <6.1"
},
"peerDependenciesMeta": {
@ -709,9 +709,9 @@
}
},
"node_modules/@angular/core": {
"version": "21.2.4",
"resolved": "https://registry.npmjs.org/@angular/core/-/core-21.2.4.tgz",
"integrity": "sha512-2+gd67ZuXHpGOqeb2o7XZPueEWEP81eJza2tSHkT5QMV8lnYllDEmaNnkPxnIjSLGP1O3PmiXxo4z8ibHkLZwg==",
"version": "21.2.10",
"resolved": "https://registry.npmjs.org/@angular/core/-/core-21.2.10.tgz",
"integrity": "sha512-uxH+mbPiCE7rInWKYOPe9Ytas97+mFM6FhFORoN234yBK3b8he+iDuxX6dsbhEFCxhRmfS6hLxe7BdLY6U6kIA==",
"license": "MIT",
"dependencies": {
"tslib": "^2.3.0"
@ -720,7 +720,7 @@
"node": "^20.19.0 || ^22.12.0 || >=24.0.0"
},
"peerDependencies": {
"@angular/compiler": "21.2.4",
"@angular/compiler": "21.2.10",
"rxjs": "^6.5.3 || ^7.4.0",
"zone.js": "~0.15.0 || ~0.16.0"
},
@ -734,9 +734,9 @@
}
},
"node_modules/@angular/forms": {
"version": "21.2.4",
"resolved": "https://registry.npmjs.org/@angular/forms/-/forms-21.2.4.tgz",
"integrity": "sha512-1fOhctA9ADEBYjI3nPQUR5dHsK2+UWAjup37Ksldk/k0w8UpD5YsN7JVNvsDMZRFMucKYcGykPblU7pABtsqnQ==",
"version": "21.2.10",
"resolved": "https://registry.npmjs.org/@angular/forms/-/forms-21.2.10.tgz",
"integrity": "sha512-XOo9qkuBqCLzSBXmyga9ke2tSulxWl+E7Y9Uwqgz8sJtQUlyP/0GYJfu60jiC3NAYobk9K/6h6MsU8zftQKdaA==",
"license": "MIT",
"dependencies": {
"@standard-schema/spec": "^1.0.0",
@ -746,16 +746,16 @@
"node": "^20.19.0 || ^22.12.0 || >=24.0.0"
},
"peerDependencies": {
"@angular/common": "21.2.4",
"@angular/core": "21.2.4",
"@angular/platform-browser": "21.2.4",
"@angular/common": "21.2.10",
"@angular/core": "21.2.10",
"@angular/platform-browser": "21.2.10",
"rxjs": "^6.5.3 || ^7.4.0"
}
},
"node_modules/@angular/language-service": {
"version": "21.2.4",
"resolved": "https://registry.npmjs.org/@angular/language-service/-/language-service-21.2.4.tgz",
"integrity": "sha512-seWlXWhayTwuL62Cfz+Ky/Wv67oYLX+cXplYoIinDVJPgQaU9jXpakLfKq8RwdRXVmgTE0HQ5dyoTozuWgJ8Nw==",
"version": "21.2.10",
"resolved": "https://registry.npmjs.org/@angular/language-service/-/language-service-21.2.10.tgz",
"integrity": "sha512-9f5XgigqdscuCmUZ2WAbuCKgOZfq6dennEOsvqjfposnaU90Y01cD9O75xKf4ONEANOfTwVcQCqGZeZ6Cnpdvw==",
"dev": true,
"license": "MIT",
"engines": {
@ -763,9 +763,9 @@
}
},
"node_modules/@angular/platform-browser": {
"version": "21.2.4",
"resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-21.2.4.tgz",
"integrity": "sha512-1A9e/cQVu+3BkRCktLcO3RZGuw8NOTHw1frUUrpAz+iMyvIT4sDRFbL+U1g8qmOCZqRNC1Pi1HZfZ1kl6kvrcQ==",
"version": "21.2.10",
"resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-21.2.10.tgz",
"integrity": "sha512-5WMoHGU8BOV3eO9h3vGMIUDPf+3SHis7+X2dHKMtKfFBUtiO8m/lq2x3PzkkKj1782i7KYt92EqPHuADd/eWOw==",
"license": "MIT",
"dependencies": {
"tslib": "^2.3.0"
@ -774,9 +774,9 @@
"node": "^20.19.0 || ^22.12.0 || >=24.0.0"
},
"peerDependencies": {
"@angular/animations": "21.2.4",
"@angular/common": "21.2.4",
"@angular/core": "21.2.4"
"@angular/animations": "21.2.10",
"@angular/common": "21.2.10",
"@angular/core": "21.2.10"
},
"peerDependenciesMeta": {
"@angular/animations": {
@ -785,9 +785,9 @@
}
},
"node_modules/@angular/platform-browser-dynamic": {
"version": "21.2.4",
"resolved": "https://registry.npmjs.org/@angular/platform-browser-dynamic/-/platform-browser-dynamic-21.2.4.tgz",
"integrity": "sha512-LRJLnGh4rdgD0+S5xuDd4YRm5bV8WP2e6F1Pe5rIr6N4V9ofgpB0/uOjYy9se99FJZjoyPnpxaKsp8+XA753Zg==",
"version": "21.2.10",
"resolved": "https://registry.npmjs.org/@angular/platform-browser-dynamic/-/platform-browser-dynamic-21.2.10.tgz",
"integrity": "sha512-+/HMJSLnF87EODkHj0AKE3Q8AfYO/8jpTfr731QmplqBtCoLlA/1XR8aYow2hB9YKL9HZWDb2qGkRtCXhrtt+w==",
"license": "MIT",
"dependencies": {
"tslib": "^2.3.0"
@ -796,16 +796,16 @@
"node": "^20.19.0 || ^22.12.0 || >=24.0.0"
},
"peerDependencies": {
"@angular/common": "21.2.4",
"@angular/compiler": "21.2.4",
"@angular/core": "21.2.4",
"@angular/platform-browser": "21.2.4"
"@angular/common": "21.2.10",
"@angular/compiler": "21.2.10",
"@angular/core": "21.2.10",
"@angular/platform-browser": "21.2.10"
}
},
"node_modules/@angular/router": {
"version": "21.2.4",
"resolved": "https://registry.npmjs.org/@angular/router/-/router-21.2.4.tgz",
"integrity": "sha512-OjWze4XT8i2MThcBXMv7ru1k6/5L6QYZbcXuseqimFCHm2avEJ+mXPovY066fMBZJhqbXdjB82OhHAWkIHjglQ==",
"version": "21.2.10",
"resolved": "https://registry.npmjs.org/@angular/router/-/router-21.2.10.tgz",
"integrity": "sha512-4cHHwewIhFEAAaRgJ80371EOtNlydFHbjj/UENLZitjU0azal0mfFCBdkaEdVehd7+mH5xO7MRjy6eFTcTYR5Q==",
"license": "MIT",
"dependencies": {
"tslib": "^2.3.0"
@ -814,9 +814,9 @@
"node": "^20.19.0 || ^22.12.0 || >=24.0.0"
},
"peerDependencies": {
"@angular/common": "21.2.4",
"@angular/core": "21.2.4",
"@angular/platform-browser": "21.2.4",
"@angular/common": "21.2.10",
"@angular/core": "21.2.10",
"@angular/platform-browser": "21.2.10",
"rxjs": "^6.5.3 || ^7.4.0"
}
},
@ -1114,35 +1114,38 @@
}
},
"node_modules/@emnapi/core": {
"version": "1.9.0",
"resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.9.0.tgz",
"integrity": "sha512-0DQ98G9ZQZOxfUcQn1waV2yS8aWdZ6kJMbYCJB3oUBecjWYO1fqJ+a1DRfPF3O5JEkwqwP1A9QEN/9mYm2Yd0w==",
"version": "1.10.0",
"resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.10.0.tgz",
"integrity": "sha512-yq6OkJ4p82CAfPl0u9mQebQHKPJkY7WrIuk205cTYnYe+k2Z8YBh11FrbRG/H6ihirqcacOgl2BIO8oyMQLeXw==",
"dev": true,
"license": "MIT",
"optional": true,
"peer": true,
"dependencies": {
"@emnapi/wasi-threads": "1.2.0",
"@emnapi/wasi-threads": "1.2.1",
"tslib": "^2.4.0"
}
},
"node_modules/@emnapi/runtime": {
"version": "1.9.0",
"resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.9.0.tgz",
"integrity": "sha512-QN75eB0IH2ywSpRpNddCRfQIhmJYBCJ1x5Lb3IscKAL8bMnVAKnRg8dCoXbHzVLLH7P38N2Z3mtulB7W0J0FKw==",
"version": "1.10.0",
"resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.10.0.tgz",
"integrity": "sha512-ewvYlk86xUoGI0zQRNq/mC+16R1QeDlKQy21Ki3oSYXNgLb45GV1P6A0M+/s6nyCuNDqe5VpaY84BzXGwVbwFA==",
"dev": true,
"license": "MIT",
"optional": true,
"peer": true,
"dependencies": {
"tslib": "^2.4.0"
}
},
"node_modules/@emnapi/wasi-threads": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.2.0.tgz",
"integrity": "sha512-N10dEJNSsUx41Z6pZsXU8FjPjpBEplgH24sfkmITrBED1/U2Esum9F3lfLrMjKHHjmi557zQn7kR9R+XWXu5Rg==",
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.2.1.tgz",
"integrity": "sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w==",
"dev": true,
"license": "MIT",
"optional": true,
"peer": true,
"dependencies": {
"tslib": "^2.4.0"
}
@ -2938,20 +2941,22 @@
}
},
"node_modules/@napi-rs/wasm-runtime": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.1.1.tgz",
"integrity": "sha512-p64ah1M1ld8xjWv3qbvFwHiFVWrq1yFvV4f7w+mzaqiR4IlSgkqhcRdHwsGgomwzBH51sRY4NEowLxnaBjcW/A==",
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.1.4.tgz",
"integrity": "sha512-3NQNNgA1YSlJb/kMH1ildASP9HW7/7kYnRI2szWJaofaS1hWmbGI4H+d3+22aGzXXN9IJ+n+GiFVcGipJP18ow==",
"dev": true,
"license": "MIT",
"optional": true,
"dependencies": {
"@emnapi/core": "^1.7.1",
"@emnapi/runtime": "^1.7.1",
"@tybys/wasm-util": "^0.10.1"
},
"funding": {
"type": "github",
"url": "https://github.com/sponsors/Brooooooklyn"
},
"peerDependencies": {
"@emnapi/core": "^1.7.1",
"@emnapi/runtime": "^1.7.1"
}
},
"node_modules/@npmcli/agent": {
@ -4069,14 +4074,14 @@
]
},
"node_modules/@schematics/angular": {
"version": "21.2.2",
"resolved": "https://registry.npmjs.org/@schematics/angular/-/angular-21.2.2.tgz",
"integrity": "sha512-Ywa6HDtX7TRBQZTVMMnxX3Mk7yVnG8KtSFaXWrkx779+q8tqYdBwNwAqbNd4Zatr1GccKaz9xcptHJta5+DTxw==",
"version": "21.2.8",
"resolved": "https://registry.npmjs.org/@schematics/angular/-/angular-21.2.8.tgz",
"integrity": "sha512-Kx3PmuZIXhwQqAqoERAXqDCORHFbKTMd+eflXwZfpKkrbWJTVPqKpL4R9RVdEr2E6/VEXDFrdL1whIvGd1xmDg==",
"dev": true,
"license": "MIT",
"dependencies": {
"@angular-devkit/core": "21.2.2",
"@angular-devkit/schematics": "21.2.2",
"@angular-devkit/core": "21.2.8",
"@angular-devkit/schematics": "21.2.8",
"jsonc-parser": "3.3.1"
},
"engines": {
@ -4242,30 +4247,30 @@
"license": "MIT"
},
"node_modules/@types/node": {
"version": "25.5.0",
"resolved": "https://registry.npmjs.org/@types/node/-/node-25.5.0.tgz",
"integrity": "sha512-jp2P3tQMSxWugkCUKLRPVUpGaL5MVFwF8RDuSRztfwgN1wmqJeMSbKlnEtQqU8UrhTmzEmZdu2I6v2dpp7XIxw==",
"version": "25.6.0",
"resolved": "https://registry.npmjs.org/@types/node/-/node-25.6.0.tgz",
"integrity": "sha512-+qIYRKdNYJwY3vRCZMdJbPLJAtGjQBudzZzdzwQYkEPQd+PJGixUL5QfvCLDaULoLv+RhT3LDkwEfKaAkgSmNQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"undici-types": "~7.18.0"
"undici-types": "~7.19.0"
}
},
"node_modules/@typescript-eslint/eslint-plugin": {
"version": "8.57.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.57.0.tgz",
"integrity": "sha512-qeu4rTHR3/IaFORbD16gmjq9+rEs9fGKdX0kF6BKSfi+gCuG3RCKLlSBYzn/bGsY9Tj7KE/DAQStbp8AHJGHEQ==",
"version": "8.59.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.59.1.tgz",
"integrity": "sha512-BOziFIfE+6osHO9FoJG4zjoHUcvI7fTNBSpdAwrNH0/TLvzjsk2oo8XSSOT2HhqUyhZPfHv4UOffoJ9oEEQ7Ag==",
"dev": true,
"license": "MIT",
"dependencies": {
"@eslint-community/regexpp": "^4.12.2",
"@typescript-eslint/scope-manager": "8.57.0",
"@typescript-eslint/type-utils": "8.57.0",
"@typescript-eslint/utils": "8.57.0",
"@typescript-eslint/visitor-keys": "8.57.0",
"@typescript-eslint/scope-manager": "8.59.1",
"@typescript-eslint/type-utils": "8.59.1",
"@typescript-eslint/utils": "8.59.1",
"@typescript-eslint/visitor-keys": "8.59.1",
"ignore": "^7.0.5",
"natural-compare": "^1.4.0",
"ts-api-utils": "^2.4.0"
"ts-api-utils": "^2.5.0"
},
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@ -4275,22 +4280,22 @@
"url": "https://opencollective.com/typescript-eslint"
},
"peerDependencies": {
"@typescript-eslint/parser": "^8.57.0",
"@typescript-eslint/parser": "^8.59.1",
"eslint": "^8.57.0 || ^9.0.0 || ^10.0.0",
"typescript": ">=4.8.4 <6.0.0"
"typescript": ">=4.8.4 <6.1.0"
}
},
"node_modules/@typescript-eslint/parser": {
"version": "8.57.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.57.0.tgz",
"integrity": "sha512-XZzOmihLIr8AD1b9hL9ccNMzEMWt/dE2u7NyTY9jJG6YNiNthaD5XtUHVF2uCXZ15ng+z2hT3MVuxnUYhq6k1g==",
"version": "8.59.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.59.1.tgz",
"integrity": "sha512-HDQH9O/47Dxi1ceDhBXdaldtf/WV9yRYMjbjCuNk3qnaTD564qwv61Y7+gTxwxRKzSrgO5uhtw584igXVuuZkA==",
"dev": true,
"license": "MIT",
"dependencies": {
"@typescript-eslint/scope-manager": "8.57.0",
"@typescript-eslint/types": "8.57.0",
"@typescript-eslint/typescript-estree": "8.57.0",
"@typescript-eslint/visitor-keys": "8.57.0",
"@typescript-eslint/scope-manager": "8.59.1",
"@typescript-eslint/types": "8.59.1",
"@typescript-eslint/typescript-estree": "8.59.1",
"@typescript-eslint/visitor-keys": "8.59.1",
"debug": "^4.4.3"
},
"engines": {
@ -4302,18 +4307,18 @@
},
"peerDependencies": {
"eslint": "^8.57.0 || ^9.0.0 || ^10.0.0",
"typescript": ">=4.8.4 <6.0.0"
"typescript": ">=4.8.4 <6.1.0"
}
},
"node_modules/@typescript-eslint/project-service": {
"version": "8.57.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.57.0.tgz",
"integrity": "sha512-pR+dK0BlxCLxtWfaKQWtYr7MhKmzqZxuii+ZjuFlZlIGRZm22HnXFqa2eY+90MUz8/i80YJmzFGDUsi8dMOV5w==",
"version": "8.59.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.59.1.tgz",
"integrity": "sha512-+MuHQlHiEr00Of/IQbE/MmEoi44znZHbR/Pz7Opq4HryUOlRi+/44dro9Ycy8Fyo+/024IWtw8m4JUMCGTYxDg==",
"dev": true,
"license": "MIT",
"dependencies": {
"@typescript-eslint/tsconfig-utils": "^8.57.0",
"@typescript-eslint/types": "^8.57.0",
"@typescript-eslint/tsconfig-utils": "^8.59.1",
"@typescript-eslint/types": "^8.59.1",
"debug": "^4.4.3"
},
"engines": {
@ -4324,18 +4329,18 @@
"url": "https://opencollective.com/typescript-eslint"
},
"peerDependencies": {
"typescript": ">=4.8.4 <6.0.0"
"typescript": ">=4.8.4 <6.1.0"
}
},
"node_modules/@typescript-eslint/scope-manager": {
"version": "8.57.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.57.0.tgz",
"integrity": "sha512-nvExQqAHF01lUM66MskSaZulpPL5pgy5hI5RfrxviLgzZVffB5yYzw27uK/ft8QnKXI2X0LBrHJFr1TaZtAibw==",
"version": "8.59.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.59.1.tgz",
"integrity": "sha512-LwuHQI4pDOYVKvmH2dkaJo6YZCSgouVgnS/z7yBPKBMvgtBvyLqiLy9Z6b7+m/TRcX1NFYUqZetI5Y+aT4GEfg==",
"dev": true,
"license": "MIT",
"dependencies": {
"@typescript-eslint/types": "8.57.0",
"@typescript-eslint/visitor-keys": "8.57.0"
"@typescript-eslint/types": "8.59.1",
"@typescript-eslint/visitor-keys": "8.59.1"
},
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@ -4346,9 +4351,9 @@
}
},
"node_modules/@typescript-eslint/tsconfig-utils": {
"version": "8.57.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.57.0.tgz",
"integrity": "sha512-LtXRihc5ytjJIQEH+xqjB0+YgsV4/tW35XKX3GTZHpWtcC8SPkT/d4tqdf1cKtesryHm2bgp6l555NYcT2NLvA==",
"version": "8.59.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.59.1.tgz",
"integrity": "sha512-/0nEyPbX7gRsk0Uwfe4ALwwgxuA66d/l2mhRDNlAvaj4U3juhUtJNq0DsY8M2AYwwb9rEq2hrC3IcIcEt++iJA==",
"dev": true,
"license": "MIT",
"engines": {
@ -4359,21 +4364,21 @@
"url": "https://opencollective.com/typescript-eslint"
},
"peerDependencies": {
"typescript": ">=4.8.4 <6.0.0"
"typescript": ">=4.8.4 <6.1.0"
}
},
"node_modules/@typescript-eslint/type-utils": {
"version": "8.57.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.57.0.tgz",
"integrity": "sha512-yjgh7gmDcJ1+TcEg8x3uWQmn8ifvSupnPfjP21twPKrDP/pTHlEQgmKcitzF/rzPSmv7QjJ90vRpN4U+zoUjwQ==",
"version": "8.59.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.59.1.tgz",
"integrity": "sha512-klWPBR2ciQHS3f++ug/mVnWKPjBUo7icEL3FAO1lhAR1Z1i5NQYZ1EannMSRYcq5qCv5wNALlXr6fksRHyYl7w==",
"dev": true,
"license": "MIT",
"dependencies": {
"@typescript-eslint/types": "8.57.0",
"@typescript-eslint/typescript-estree": "8.57.0",
"@typescript-eslint/utils": "8.57.0",
"@typescript-eslint/types": "8.59.1",
"@typescript-eslint/typescript-estree": "8.59.1",
"@typescript-eslint/utils": "8.59.1",
"debug": "^4.4.3",
"ts-api-utils": "^2.4.0"
"ts-api-utils": "^2.5.0"
},
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@ -4384,13 +4389,13 @@
},
"peerDependencies": {
"eslint": "^8.57.0 || ^9.0.0 || ^10.0.0",
"typescript": ">=4.8.4 <6.0.0"
"typescript": ">=4.8.4 <6.1.0"
}
},
"node_modules/@typescript-eslint/types": {
"version": "8.57.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.57.0.tgz",
"integrity": "sha512-dTLI8PEXhjUC7B9Kre+u0XznO696BhXcTlOn0/6kf1fHaQW8+VjJAVHJ3eTI14ZapTxdkOmc80HblPQLaEeJdg==",
"version": "8.59.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.59.1.tgz",
"integrity": "sha512-ZDCjgccSdYPw5Bxh+my4Z0lJU96ZDN7jbBzvmEn0FZx3RtU1C7VWl6NbDx94bwY3V5YsgwRzJPOgeY2Q/nLG8A==",
"dev": true,
"license": "MIT",
"engines": {
@ -4402,21 +4407,21 @@
}
},
"node_modules/@typescript-eslint/typescript-estree": {
"version": "8.57.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.57.0.tgz",
"integrity": "sha512-m7faHcyVg0BT3VdYTlX8GdJEM7COexXxS6KqGopxdtkQRvBanK377QDHr4W/vIPAR+ah9+B/RclSW5ldVniO1Q==",
"version": "8.59.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.59.1.tgz",
"integrity": "sha512-OUd+vJS05sSkOip+BkZ/2NS8RMxrAAJemsC6vU3kmfLyeaJT0TftHkV9mcx2107MmsBVXXexhVu4F0TZXyMl4g==",
"dev": true,
"license": "MIT",
"dependencies": {
"@typescript-eslint/project-service": "8.57.0",
"@typescript-eslint/tsconfig-utils": "8.57.0",
"@typescript-eslint/types": "8.57.0",
"@typescript-eslint/visitor-keys": "8.57.0",
"@typescript-eslint/project-service": "8.59.1",
"@typescript-eslint/tsconfig-utils": "8.59.1",
"@typescript-eslint/types": "8.59.1",
"@typescript-eslint/visitor-keys": "8.59.1",
"debug": "^4.4.3",
"minimatch": "^10.2.2",
"semver": "^7.7.3",
"tinyglobby": "^0.2.15",
"ts-api-utils": "^2.4.0"
"ts-api-utils": "^2.5.0"
},
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@ -4426,20 +4431,20 @@
"url": "https://opencollective.com/typescript-eslint"
},
"peerDependencies": {
"typescript": ">=4.8.4 <6.0.0"
"typescript": ">=4.8.4 <6.1.0"
}
},
"node_modules/@typescript-eslint/utils": {
"version": "8.57.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.57.0.tgz",
"integrity": "sha512-5iIHvpD3CZe06riAsbNxxreP+MuYgVUsV0n4bwLH//VJmgtt54sQeY2GszntJ4BjYCpMzrfVh2SBnUQTtys2lQ==",
"version": "8.59.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.59.1.tgz",
"integrity": "sha512-3pIeoXhCeYH9FSCBI8P3iNwJlGuzPlYKkTlen2O9T1DSeeg8UG8jstq6BLk+Mda0qup7mgk4z4XL4OzRaxZ8LA==",
"dev": true,
"license": "MIT",
"dependencies": {
"@eslint-community/eslint-utils": "^4.9.1",
"@typescript-eslint/scope-manager": "8.57.0",
"@typescript-eslint/types": "8.57.0",
"@typescript-eslint/typescript-estree": "8.57.0"
"@typescript-eslint/scope-manager": "8.59.1",
"@typescript-eslint/types": "8.59.1",
"@typescript-eslint/typescript-estree": "8.59.1"
},
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@ -4450,17 +4455,17 @@
},
"peerDependencies": {
"eslint": "^8.57.0 || ^9.0.0 || ^10.0.0",
"typescript": ">=4.8.4 <6.0.0"
"typescript": ">=4.8.4 <6.1.0"
}
},
"node_modules/@typescript-eslint/visitor-keys": {
"version": "8.57.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.57.0.tgz",
"integrity": "sha512-zm6xx8UT/Xy2oSr2ZXD0pZo7Jx2XsCoID2IUh9YSTFRu7z+WdwYTRk6LhUftm1crwqbuoF6I8zAFeCMw0YjwDg==",
"version": "8.59.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.59.1.tgz",
"integrity": "sha512-LdDNl6C5iJExcM0Yh0PwAIBb9PrSiCsWamF/JyEZawm3kFDnRoaq3LGE4bpyRao/fWeGKKyw7icx0YxrLFC5Cg==",
"dev": true,
"license": "MIT",
"dependencies": {
"@typescript-eslint/types": "8.57.0",
"@typescript-eslint/types": "8.59.1",
"eslint-visitor-keys": "^5.0.0"
},
"engines": {
@ -6012,9 +6017,9 @@
"license": "MIT"
},
"node_modules/filesize": {
"version": "11.0.13",
"resolved": "https://registry.npmjs.org/filesize/-/filesize-11.0.13.tgz",
"integrity": "sha512-mYJ/qXKvREuO0uH8LTQJ6v7GsUvVOguqxg2VTwQUkyTPXXRRWPdjuUPVqdBrJQhvci48OHlNGRnux+Slr2Rnvw==",
"version": "11.0.17",
"resolved": "https://registry.npmjs.org/filesize/-/filesize-11.0.17.tgz",
"integrity": "sha512-oHLTvMLw6imZUl1se/RBQrFlyy50nXce4sU7yGR6Qc0JgCwqnfiFsAnEwotdGmfKLD7SArGUk2/5STU0k8LOBQ==",
"license": "BSD-3-Clause",
"engines": {
"node": ">= 10.8.0"
@ -7927,9 +7932,9 @@
"license": "ISC"
},
"node_modules/picomatch": {
"version": "4.0.3",
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz",
"integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==",
"version": "4.0.4",
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz",
"integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==",
"dev": true,
"license": "MIT",
"engines": {
@ -8036,9 +8041,9 @@
}
},
"node_modules/prettier": {
"version": "3.8.1",
"resolved": "https://registry.npmjs.org/prettier/-/prettier-3.8.1.tgz",
"integrity": "sha512-UOnG6LftzbdaHZcKoPFtOcCKztrQ57WkHDeRD9t/PTQtmT0NHSeWWepj6pS0z/N7+08BHFDQVUrfmfMRcZwbMg==",
"version": "3.8.3",
"resolved": "https://registry.npmjs.org/prettier/-/prettier-3.8.3.tgz",
"integrity": "sha512-7igPTM53cGHMW8xWuVTydi2KO233VFiTNyF5hLJqpilHfmn8C8gPf+PS7dUT64YcXFbiMGZxS9pCSxL/Dxm/Jw==",
"dev": true,
"license": "MIT",
"bin": {
@ -8922,9 +8927,9 @@
"license": "MIT"
},
"node_modules/ts-api-utils": {
"version": "2.4.0",
"resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.4.0.tgz",
"integrity": "sha512-3TaVTaAv2gTiMB35i3FiGJaRfwb3Pyn/j3m/bfAvGe8FB7CF6u+LMYqYlDh7reQf7UNvoTvdfAqHGmPGOSsPmA==",
"version": "2.5.0",
"resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.5.0.tgz",
"integrity": "sha512-OJ/ibxhPlqrMM0UiNHJ/0CKQkoKF243/AEmplt3qpRgkW8VG7IfOS41h7V8TjITqdByHzrjcS/2si+y4lIh8NA==",
"dev": true,
"license": "MIT",
"engines": {
@ -8998,9 +9003,9 @@
}
},
"node_modules/undici": {
"version": "7.22.0",
"resolved": "https://registry.npmjs.org/undici/-/undici-7.22.0.tgz",
"integrity": "sha512-RqslV2Us5BrllB+JeiZnK4peryVTndy9Dnqq62S3yYRRTj0tFQCwEniUy2167skdGOy3vqRzEvl1Dm4sV2ReDg==",
"version": "7.24.4",
"resolved": "https://registry.npmjs.org/undici/-/undici-7.24.4.tgz",
"integrity": "sha512-BM/JzwwaRXxrLdElV2Uo6cTLEjhSb3WXboncJamZ15NgUURmvlXvxa6xkwIOILIjPNo9i8ku136ZvWV0Uly8+w==",
"dev": true,
"license": "MIT",
"engines": {
@ -9008,9 +9013,9 @@
}
},
"node_modules/undici-types": {
"version": "7.18.2",
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.18.2.tgz",
"integrity": "sha512-AsuCzffGHJybSaRrmr5eHr81mwJU3kjw6M+uprWvCXiNeN9SOGwQ3Jn8jb8m3Z6izVgknn1R0FTCEAP2QrLY/w==",
"version": "7.19.2",
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.19.2.tgz",
"integrity": "sha512-qYVnV5OEm2AW8cJMCpdV20CDyaN3g0AjDlOGf1OW4iaDEx8MwdtChUp4zu4H0VP3nDRF/8RKWH+IPp9uW0YGZg==",
"dev": true,
"license": "MIT"
},
@ -9131,9 +9136,9 @@
}
},
"node_modules/vite": {
"version": "7.3.1",
"resolved": "https://registry.npmjs.org/vite/-/vite-7.3.1.tgz",
"integrity": "sha512-w+N7Hifpc3gRjZ63vYBXA56dvvRlNWRczTdmCBBa+CotUzAPf5b7YMdMR/8CQoeYE5LX3W4wj6RYTgonm1b9DA==",
"version": "7.3.2",
"resolved": "https://registry.npmjs.org/vite/-/vite-7.3.2.tgz",
"integrity": "sha512-Bby3NOsna2jsjfLVOHKes8sGwgl4TT0E6vvpYgnAYDIF/tie7MRaFthmKuHx1NSXjiTueXH3do80FMQgvEktRg==",
"dev": true,
"license": "MIT",
"dependencies": {

View file

@ -13,42 +13,42 @@
},
"private": true,
"dependencies": {
"@angular/animations": "^21.2.4",
"@angular/cdk": "^21.2.2",
"@angular/common": "^21.2.4",
"@angular/compiler": "^21.2.4",
"@angular/core": "^21.2.4",
"@angular/forms": "^21.2.4",
"@angular/platform-browser": "^21.2.4",
"@angular/platform-browser-dynamic": "^21.2.4",
"@angular/router": "^21.2.4",
"@angular/animations": "^21.2.10",
"@angular/cdk": "^21.2.8",
"@angular/common": "^21.2.10",
"@angular/compiler": "^21.2.10",
"@angular/core": "^21.2.10",
"@angular/forms": "^21.2.10",
"@angular/platform-browser": "^21.2.10",
"@angular/platform-browser-dynamic": "^21.2.10",
"@angular/router": "^21.2.10",
"@fortawesome/fontawesome-free": "^7.2.0",
"@microsoft/signalr": "^10.0.0",
"bulma": "^1.0.4",
"curray": "^1.0.12",
"file-saver-es": "^2.0.5",
"filesize": "^11.0.13",
"filesize": "^11.0.17",
"rxjs": "^7.8.2",
"tslib": "^2.8.1",
"zone.js": "^0.16.1"
},
"devDependencies": {
"@angular-eslint/builder": "21.3.0",
"@angular-eslint/eslint-plugin": "21.3.0",
"@angular-eslint/eslint-plugin-template": "21.3.0",
"@angular-eslint/schematics": "21.3.0",
"@angular-eslint/template-parser": "21.3.0",
"@angular/build": "^21.2.2",
"@angular/cli": "^21.2.2",
"@angular/compiler-cli": "^21.2.4",
"@angular/language-service": "^21.2.4",
"@angular-eslint/builder": "21.3.1",
"@angular-eslint/eslint-plugin": "21.3.1",
"@angular-eslint/eslint-plugin-template": "21.3.1",
"@angular-eslint/schematics": "21.3.1",
"@angular-eslint/template-parser": "21.3.1",
"@angular/build": "^21.2.8",
"@angular/cli": "^21.2.8",
"@angular/compiler-cli": "^21.2.10",
"@angular/language-service": "^21.2.10",
"@types/file-saver": "^2.0.7",
"@types/file-saver-es": "^2.0.3",
"@types/node": "^25.5.0",
"@typescript-eslint/eslint-plugin": "^8.57.0",
"@typescript-eslint/parser": "^8.57.0",
"@types/node": "^25.6.0",
"@typescript-eslint/eslint-plugin": "^8.59.1",
"@typescript-eslint/parser": "^8.59.1",
"eslint": "^9.39.4",
"prettier": "^3.8.1",
"prettier": "^3.8.3",
"typescript": "5.9.3"
}
}

View file

@ -1,12 +1,12 @@
import { Component, DestroyRef, OnInit, inject } from '@angular/core';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
import { Router } from '@angular/router';
import { TorrentService } from 'src/app/torrent.service';
import { DownloadType, Torrent, TorrentFileAvailability } from '../models/torrent.model';
import { SettingsService } from '../settings.service';
import { ActivatedRoute } from '@angular/router';
import { FormsModule } from '@angular/forms';
import { NgClass } from '@angular/common';
import { TorrentService } from '../torrent.service';
@Component({
selector: 'app-add-new-torrent',
@ -119,7 +119,8 @@ export class AddNewTorrentComponent implements OnInit {
this.includeRegex = settings.find((m) => m.key === 'Gui:Default:IncludeRegex')?.value as string;
this.excludeRegex = settings.find((m) => m.key === 'Gui:Default:ExcludeRegex')?.value as string;
this.torrentRetryAttempts = settings.find((m) => m.key === 'Gui:Default:TorrentRetryAttempts')?.value as number;
this.downloadRetryAttempts = settings.find((m) => m.key === 'Gui:Default:DownloadRetryAttempts')?.value as number;
this.downloadRetryAttempts = settings.find((m) => m.key === 'Gui:Default:DownloadRetryAttempts')
?.value as number;
this.torrentDeleteOnError = settings.find((m) => m.key === 'Gui:Default:DeleteOnError')?.value as number;
this.torrentLifetime = settings.find((m) => m.key === 'Gui:Default:TorrentLifetime')?.value as number;
this.priority = settings.find((m) => m.key === 'Gui:Default:Priority')?.value as number;

View file

@ -1,10 +1,10 @@
import { Component, OnInit, inject } from '@angular/core';
import { SettingsService } from 'src/app/settings.service';
import { Setting } from '../models/setting.model';
import { NgClass, KeyValuePipe } from '@angular/common';
import { FormsModule } from '@angular/forms';
import { Nl2BrPipe } from '../nl2br.pipe';
import { FileSizePipe } from '../filesize.pipe';
import { SettingsService } from '../settings.service';
@Component({
selector: 'app-settings',

View file

@ -0,0 +1,88 @@
using Microsoft.Extensions.Logging;
using Moq;
using RdtClient.Data.Data;
using RdtClient.Data.Enums;
using RdtClient.Data.Models.Data;
using RdtClient.Service.Helpers;
using RdtClient.Service.Services;
namespace RdtClient.Service.Test.Services;
public class TorrentRunnerTest
{
[Fact]
public async Task Tick_ShouldNotRequeueCompletedErrorTorrent()
{
var originalApiKey = Settings.Get.Provider.ApiKey;
var originalProvider = Settings.Get.Provider.Provider;
var originalMaxParallelDownloads = Settings.Get.Provider.MaxParallelDownloads;
var originalDownloadPath = Settings.Get.DownloadClient.DownloadPath;
TorrentRunner.ActiveDownloadClients.Clear();
TorrentRunner.ActiveUnpackClients.Clear();
try
{
Settings.Get.Provider.ApiKey = "test-api-key";
Settings.Get.Provider.Provider = Provider.RealDebrid;
Settings.Get.Provider.MaxParallelDownloads = 1;
Settings.Get.DownloadClient.DownloadPath = "/downloads";
var erroredTorrent = new Torrent
{
TorrentId = Guid.NewGuid(),
Hash = "hash-1",
RdName = "Torrent 1",
FileOrMagnet = "magnet:?xt=urn:btih:hash-1",
Type = DownloadType.Torrent,
RdStatus = TorrentStatus.Queued,
DeleteOnError = 10,
Error = "Could not add to provider: Infringing file",
Completed = DateTimeOffset.UtcNow.AddMinutes(-5),
Downloads = new List<Download>()
};
var torrentDataMock = new Mock<ITorrentData>(MockBehavior.Strict);
torrentDataMock.Setup(m => m.Get()).ReturnsAsync(new List<Torrent>
{
erroredTorrent
});
var torrents = new Torrents(Mock.Of<ILogger<Torrents>>(),
torrentDataMock.Object,
Mock.Of<IDownloads>(),
null!,
null!,
null!,
null!,
null!,
null!,
null!,
null!);
var torrentRunner = new TorrentRunner(Mock.Of<ILogger<TorrentRunner>>(),
torrents,
new Downloads(null!),
new RemoteService(null!, torrents),
Mock.Of<IHttpClientFactory>(),
new RateLimitCoordinator());
await torrentRunner.Tick();
torrentDataMock.Verify(m => m.UpdateComplete(It.IsAny<Guid>(),
It.IsAny<string?>(),
It.IsAny<DateTimeOffset?>(),
It.IsAny<bool>()),
Times.Never);
}
finally
{
Settings.Get.Provider.ApiKey = originalApiKey;
Settings.Get.Provider.Provider = originalProvider;
Settings.Get.Provider.MaxParallelDownloads = originalMaxParallelDownloads;
Settings.Get.DownloadClient.DownloadPath = originalDownloadPath;
TorrentRunner.ActiveDownloadClients.Clear();
TorrentRunner.ActiveUnpackClients.Clear();
}
}
}

View file

@ -1,4 +1,5 @@
using System.Reflection;
using Microsoft.Data.Sqlite;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
@ -39,6 +40,9 @@ public class Startup(IServiceProvider serviceProvider) : IHostedService
public Task StopAsync(CancellationToken cancellationToken)
{
Ready = false;
SqliteConnection.ClearAllPools();
return Task.CompletedTask;
}
}

View file

@ -367,7 +367,7 @@ public class TorrentRunner(
}
// Process torrents in DebridQueue
var torrentsToAddToProvider = allTorrents.Where(m => m.RdId == null && m.RdAdded == null && m.FileOrMagnet != null && m.RdStatus == TorrentStatus.Queued)
var torrentsToAddToProvider = allTorrents.Where(m => m.Completed == null && m.Error == null && m.RdId == null && m.RdAdded == null && m.FileOrMagnet != null && m.RdStatus == TorrentStatus.Queued)
.ToList();
if (torrentsToAddToProvider.Count != 0)