Compare commits

..

1 Commits

Author SHA1 Message Date
shamoon
15fa053b4d Enhancement: support completed field for jellyseer widget 2025-12-11 06:29:19 -08:00
86 changed files with 631 additions and 1410 deletions

View File

@@ -84,7 +84,7 @@ jobs:
latest=auto latest=auto
- name: Next.js build cache - name: Next.js build cache
uses: actions/cache@v5 uses: actions/cache@v4
with: with:
path: .next/cache path: .next/cache
key: nextjs-${{ runner.os }}-${{ hashFiles('pnpm-lock.yaml') }}-${{ hashFiles('**/*.js', '**/*.jsx') }} key: nextjs-${{ runner.os }}-${{ hashFiles('pnpm-lock.yaml') }}-${{ hashFiles('**/*.js', '**/*.jsx') }}

View File

@@ -37,7 +37,7 @@ jobs:
with: with:
python-version: 3.x python-version: 3.x
- run: echo "cache_id=$(date --utc '+%V')" >> $GITHUB_ENV - run: echo "cache_id=$(date --utc '+%V')" >> $GITHUB_ENV
- uses: actions/cache@v5 - uses: actions/cache@v4
with: with:
key: mkdocs-material-${{ env.cache_id }} key: mkdocs-material-${{ env.cache_id }}
path: .cache path: .cache
@@ -63,7 +63,7 @@ jobs:
with: with:
python-version: 3.x python-version: 3.x
- run: echo "cache_id=${{github.sha}}" >> $GITHUB_ENV - run: echo "cache_id=${{github.sha}}" >> $GITHUB_ENV
- uses: actions/cache@v5 - uses: actions/cache@v4
with: with:
key: mkdocs-material-${{ env.cache_id }} key: mkdocs-material-${{ env.cache_id }}
path: .cache path: .cache

View File

@@ -32,7 +32,7 @@ jobs:
name: 'Lock Old Threads' name: 'Lock Old Threads'
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: dessant/lock-threads@v6 - uses: dessant/lock-threads@v5
with: with:
issue-inactive-days: '30' issue-inactive-days: '30'
pr-inactive-days: '30' pr-inactive-days: '30'

View File

@@ -68,7 +68,7 @@ For configuration options, examples and more, [please check out the homepage doc
## Security Notice 🔒 ## Security Notice 🔒
Please note that when using features such as widgets, Homepage can access personal information (for example from your home automation system) and Homepage currently does not (and is not planned to) include any authentication layer itself. If Homepage is reachable from any untrusted network, it **must** sit behind a reverse proxy (and/or VPN) that enforces authentication, TLS, and strictly validates Host headers. The built-in host check in Homepage is a best-effort guard and should not be treated as security when exposed publicly. Please note that when using features such as widgets, Homepage can access personal information (for example from your home automation system) and Homepage currently does not (and is not planned to) include any authentication layer itself. Thus, we recommend homepage be deployed behind a reverse proxy including authentication, SSL etc, and / or behind a VPN.
## With Docker ## With Docker

View File

@@ -22,9 +22,7 @@ if [ "$HOSTNAME" = "::" ]; then
fi fi
# Check ownership before chown # Check ownership before chown
if [ "$PUID" = "0" ]; then if [ -e /app/config ]; then
echo "Skipping ownership changes for /app/config"
elif [ -e /app/config ]; then
CURRENT_UID=$(stat -c %u /app/config) CURRENT_UID=$(stat -c %u /app/config)
CURRENT_GID=$(stat -c %g /app/config) CURRENT_GID=$(stat -c %g /app/config)
@@ -41,9 +39,7 @@ else
fi fi
# Ensure /app/config/logs exists and is owned # Ensure /app/config/logs exists and is owned
if [ "$PUID" = "0" ]; then if [ -n "$PUID" ] && [ -n "$PGID" ]; then
echo "Skipping ownership changes for /app/config/logs"
elif [ -n "$PUID" ] && [ -n "$PGID" ]; then
mkdir -p /app/config/logs 2>/dev/null || true mkdir -p /app/config/logs 2>/dev/null || true
if [ -d /app/config/logs ]; then if [ -d /app/config/logs ]; then
LOG_UID=$(stat -c %u /app/config/logs) LOG_UID=$(stat -c %u /app/config/logs)

View File

@@ -189,8 +189,6 @@ labels: ...
- homepage.widgets[1].slug=youreventslughere - homepage.widgets[1].slug=youreventslughere
``` ```
To pass custom HTTP headers with a widget request when using labels, use the same dot-notation: `homepage.widget.headers.X-Auth-Key=secret` (or `homepage.widgets[0].headers.X-Auth-Key=secret` when multiple widgets are present).
You can add specify fields for e.g. the [CustomAPI](../widgets/services/customapi.md) widget by using array-style dot notation: You can add specify fields for e.g. the [CustomAPI](../widgets/services/customapi.md) widget by using array-style dot notation:
```yaml ```yaml

View File

@@ -94,7 +94,6 @@ metadata:
gethomepage.dev/name: Emby gethomepage.dev/name: Emby
gethomepage.dev/widget.type: "emby" gethomepage.dev/widget.type: "emby"
gethomepage.dev/widget.url: "https://emby.example.com" gethomepage.dev/widget.url: "https://emby.example.com"
gethomepage.dev/widget.headers.X-Auth-Key: "your-secret-here"
gethomepage.dev/pod-selector: "" gethomepage.dev/pod-selector: ""
gethomepage.dev/weight: 10 # optional gethomepage.dev/weight: 10 # optional
gethomepage.dev/instance: "public" # optional gethomepage.dev/instance: "public" # optional

View File

@@ -101,25 +101,6 @@ Each service can have multiple widgets attached to it, for example:
Multiple widgets per service are not yet supported with Kubernetes ingress annotations. Multiple widgets per service are not yet supported with Kubernetes ingress annotations.
#### Custom HTTP headers
Widgets that make HTTP calls support extra request headers via `headers`. This is useful when a reverse proxy expects a secret header.
```yaml
- UptimeRobot:
icon: uptimekuma.png
href: https://uptimerobot.com/
widget:
type: uptimerobot
url: https://api.uptimerobot.com
key: ${UPTIMEROBOT_API_KEY}
headers:
User-Agent: homepage
X-Auth-Key: your-secret-here
```
If you define services via Docker labels or Kubernetes annotations, use the same key with dot-notation (for example `homepage.widget.headers.X-Auth-Key=secret` or `gethomepage.dev/widget.headers.X-Auth-Key: "secret"`).
#### Field Visibility #### Field Visibility
Each widget can optionally provide a list of which fields should be visible via the `fields` widget property. If no fields are specified, then all fields will be displayed. The `fields` property must be a valid YAML array of strings. As an example, here is the entry for Sonarr showing only a couple of fields. Each widget can optionally provide a list of which fields should be visible via the `fields` widget property. If no fields are specified, then all fields will be displayed. The `fields` property must be a valid YAML array of strings. As an example, here is the entry for Sonarr showing only a couple of fields.

View File

@@ -37,4 +37,4 @@ The value is a comma-separated (no spaces) list of allowed hosts (sometimes with
If you are seeing errors about host validation, check the homepage logs and ensure that the host exactly as output in the logs is in the `HOMEPAGE_ALLOWED_HOSTS` list. If you are seeing errors about host validation, check the homepage logs and ensure that the host exactly as output in the logs is in the `HOMEPAGE_ALLOWED_HOSTS` list.
This can be disabled by setting `HOMEPAGE_ALLOWED_HOSTS` to `*` but this is not recommended. Public deployments must rely on a reverse proxy (and/or VPN) that enforces authentication, TLS, and unexpected Host headers; the built-in host check is a best-effort guard for local setups and is not a substitute for edge protections. This can be disabled by setting `HOMEPAGE_ALLOWED_HOSTS` to `*` but this is not recommended.

View File

@@ -12,6 +12,7 @@ hide:
- Check config/logs/homepage.log, on docker simply e.g. `docker logs homepage`. This may provide some insight into the reason for an error. - Check config/logs/homepage.log, on docker simply e.g. `docker logs homepage`. This may provide some insight into the reason for an error.
- Check the browser error console, this can also sometimes provide useful information. - Check the browser error console, this can also sometimes provide useful information.
- Consider setting the `ENV` variable `LOG_LEVEL` to `debug`. - Consider setting the `ENV` variable `LOG_LEVEL` to `debug`.
- If certain widgets are failing when connecting to public APIs, consider [disabling IPv6](#disabling-ipv6).
## Service Widget Errors ## Service Widget Errors
@@ -66,3 +67,17 @@ All service widgets work essentially the same, that is, homepage makes a proxied
## Missing custom icons ## Missing custom icons
If, after correctly adding and mapping your custom icons via the [Icons](../configs/services.md#icons) instructions, you are still unable to see your icons please try recreating your container. If, after correctly adding and mapping your custom icons via the [Icons](../configs/services.md#icons) instructions, you are still unable to see your icons please try recreating your container.
## Disabling IPv6 for http requests {#disabling-ipv6}
If you are having issues with certain widgets that are unable to reach public APIs (e.g. weather), in certain setups you may need to disable IPv6. You can set the environment variable `HOMEPAGE_PROXY_DISABLE_IPV6` to `true` to disable IPv6 for the homepage proxy.
Alternatively, you can use the `sysctls` option in your docker-compose file to disable IPv6 for the homepage container completely:
```yaml
services:
homepage:
...
sysctls:
- net.ipv6.conf.all.disable_ipv6=1
```

View File

@@ -1,16 +0,0 @@
---
title: Booklore
description: Booklore Widget Configuration
---
Learn more about [Booklore](https://github.com/booklore-app/booklore).
The widget authenticates with your Booklore credentials to surface total libraries, books, and reading progress counts for your account.
```yaml
widget:
type: booklore
url: https://booklore.host.or.ip
username: username
password: password
```

View File

@@ -3,8 +3,6 @@ title: Gatus
description: Gatus Widget Configuration description: Gatus Widget Configuration
--- ---
Learn more about [Gatus](https://github.com/TwiN/gatus).
Allowed fields: `["up", "down", "uptime"]`. Allowed fields: `["up", "down", "uptime"]`.
```yaml ```yaml

View File

@@ -17,7 +17,6 @@ You can also find a list of all available service widgets in the sidebar navigat
- [Azure DevOps](azuredevops.md) - [Azure DevOps](azuredevops.md)
- [Backrest](backrest.md) - [Backrest](backrest.md)
- [Bazarr](bazarr.md) - [Bazarr](bazarr.md)
- [Booklore](booklore.md)
- [Beszel](beszel.md) - [Beszel](beszel.md)
- [Caddy](caddy.md) - [Caddy](caddy.md)
- [Calendar](calendar.md) - [Calendar](calendar.md)

View File

@@ -7,8 +7,8 @@ Learn more about [Jellyseerr](https://github.com/Fallenbagel/jellyseerr).
Find your API key under `Settings > General > API Key`. Find your API key under `Settings > General > API Key`.
Allowed fields: `["pending", "approved", "available", "issues"]`. Allowed fields: `["pending", "approved", "available", "completed", "issues"]`.
Default fields: `["pending", "approved", "available"]`. Default fields: `["pending", "approved", "completed"]`.
```yaml ```yaml
widget: widget:

View File

@@ -9,17 +9,11 @@ _Note that the project was renamed from PiAlert to NetAlertX._
Allowed fields: `["total", "connected", "new_devices", "down_alerts"]`. Allowed fields: `["total", "connected", "new_devices", "down_alerts"]`.
Provide the `API_TOKEN` (f.k.a. `SYNC_api_token`) as the `key` in your config. If you have enabled a password on your NetAlertX instance, you will need to provide the `SYNC_api_token` as the `key` in your config.
| NetAlertX Version | Homepage Widget Version |
| ----------------- | ----------------------- |
| < v26.1.17 | 1 (default) |
| > v26.1.17 | 2 |
```yaml ```yaml
widget: widget:
type: netalertx type: netalertx
url: http://ip:port url: http://ip:port
key: yournetalertxapitoken key: netalertxsyncapitoken # optional, only if password is enabled
version: 2 # optional, default is 1
``` ```

View File

@@ -5,11 +5,6 @@ description: TrueNas Scale Widget Configuration
Learn more about [TrueNas](https://www.truenas.com/). Learn more about [TrueNas](https://www.truenas.com/).
| TrueNAS Version | Homepage widget version |
| ----------------------- | ----------------------- |
| < 26.04 (REST API) | 1 (default) |
| > 25.04 (Websocket API) | 2 |
Allowed fields: `["load", "uptime", "alerts"]`. Allowed fields: `["load", "uptime", "alerts"]`.
To create an API Key, follow [the official TrueNAS documentation](https://www.truenas.com/docs/scale/scaletutorials/toptoolbar/managingapikeys/). To create an API Key, follow [the official TrueNAS documentation](https://www.truenas.com/docs/scale/scaletutorials/toptoolbar/managingapikeys/).
@@ -22,7 +17,6 @@ To use the `enablePools` option with TrueNAS Core, the `nasType` parameter is re
widget: widget:
type: truenas type: truenas
url: http://truenas.host.or.ip url: http://truenas.host.or.ip
version: 2 # optional, defaults to 1
username: user # not required if using api key username: user # not required if using api key
password: pass # not required if using api key password: pass # not required if using api key
key: yourtruenasapikey # not required if using username / password key: yourtruenasapikey # not required if using username / password

View File

@@ -41,7 +41,6 @@ nav:
- widgets/services/azuredevops.md - widgets/services/azuredevops.md
- widgets/services/backrest.md - widgets/services/backrest.md
- widgets/services/bazarr.md - widgets/services/bazarr.md
- widgets/services/booklore.md
- widgets/services/beszel.md - widgets/services/beszel.md
- widgets/services/caddy.md - widgets/services/caddy.md
- widgets/services/calendar.md - widgets/services/calendar.md

View File

@@ -1,6 +1,6 @@
{ {
"name": "homepage", "name": "homepage",
"version": "1.9.0", "version": "1.7.0",
"private": true, "private": true,
"scripts": { "scripts": {
"preinstall": "npx only-allow pnpm", "preinstall": "npx only-allow pnpm",
@@ -20,12 +20,12 @@
"gamedig": "^5.3.2", "gamedig": "^5.3.2",
"i18next": "^25.5.3", "i18next": "^25.5.3",
"ical.js": "^2.1.0", "ical.js": "^2.1.0",
"js-yaml": "^4.1.1", "js-yaml": "^4.1.0",
"json-rpc-2.0": "^1.7.0", "json-rpc-2.0": "^1.7.0",
"luxon": "^3.6.1", "luxon": "^3.6.1",
"memory-cache": "^0.2.0", "memory-cache": "^0.2.0",
"minecraftstatuspinger": "^1.2.2", "minecraftstatuspinger": "^1.2.2",
"next": "^15.5.9", "next": "^15.5.7",
"next-i18next": "^12.1.0", "next-i18next": "^12.1.0",
"ping": "^0.4.4", "ping": "^0.4.4",
"pretty-bytes": "^7.1.0", "pretty-bytes": "^7.1.0",
@@ -33,19 +33,18 @@
"react": "^18.3.1", "react": "^18.3.1",
"react-dom": "^18.3.1", "react-dom": "^18.3.1",
"react-i18next": "^15.5.3", "react-i18next": "^15.5.3",
"react-icons": "^5.5.0", "react-icons": "^5.4.0",
"recharts": "^3.1.2", "recharts": "^3.1.2",
"swr": "^2.3.3", "swr": "^2.3.3",
"systeminformation": "^5.27.11", "systeminformation": "^5.27.11",
"tough-cookie": "^6.0.0", "tough-cookie": "^6.0.0",
"urbackup-server-api": "^0.91.0", "urbackup-server-api": "^0.8.9",
"winston": "^3.17.0", "winston": "^3.17.0",
"ws": "^8.18.3",
"xml-js": "^1.6.11" "xml-js": "^1.6.11"
}, },
"devDependencies": { "devDependencies": {
"@tailwindcss/forms": "^0.5.10", "@tailwindcss/forms": "^0.5.10",
"@tailwindcss/postcss": "^4.1.18", "@tailwindcss/postcss": "^4.1.14",
"eslint": "^9.25.1", "eslint": "^9.25.1",
"eslint-config-next": "^15.2.4", "eslint-config-next": "^15.2.4",
"eslint-config-prettier": "^10.1.8", "eslint-config-prettier": "^10.1.8",
@@ -66,7 +65,6 @@
}, },
"pnpm": { "pnpm": {
"onlyBuiltDependencies": [ "onlyBuiltDependencies": [
"@tailwindcss/oxide",
"osx-temperature-sensor", "osx-temperature-sensor",
"sharp" "sharp"
] ]

382
pnpm-lock.yaml generated
View File

@@ -36,8 +36,8 @@ importers:
specifier: ^2.1.0 specifier: ^2.1.0
version: 2.1.0 version: 2.1.0
js-yaml: js-yaml:
specifier: ^4.1.1 specifier: ^4.1.0
version: 4.1.1 version: 4.1.0
json-rpc-2.0: json-rpc-2.0:
specifier: ^1.7.0 specifier: ^1.7.0
version: 1.7.0 version: 1.7.0
@@ -51,11 +51,11 @@ importers:
specifier: ^1.2.2 specifier: ^1.2.2
version: 1.2.2 version: 1.2.2
next: next:
specifier: ^15.5.9 specifier: ^15.5.7
version: 15.5.9(react-dom@18.3.1(react@18.3.1))(react@18.3.1) version: 15.5.7(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
next-i18next: next-i18next:
specifier: ^12.1.0 specifier: ^12.1.0
version: 12.1.0(next@15.5.9(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) version: 12.1.0(next@15.5.7(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
ping: ping:
specifier: ^0.4.4 specifier: ^0.4.4
version: 0.4.4 version: 0.4.4
@@ -75,8 +75,8 @@ importers:
specifier: ^15.5.3 specifier: ^15.5.3
version: 15.5.3(i18next@25.5.3(typescript@5.7.3))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.7.3) version: 15.5.3(i18next@25.5.3(typescript@5.7.3))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.7.3)
react-icons: react-icons:
specifier: ^5.5.0 specifier: ^5.4.0
version: 5.5.0(react@18.3.1) version: 5.4.0(react@18.3.1)
recharts: recharts:
specifier: ^3.1.2 specifier: ^3.1.2
version: 3.1.2(@types/react@19.0.10)(react-dom@18.3.1(react@18.3.1))(react-is@18.3.1)(react@18.3.1)(redux@5.0.1) version: 3.1.2(@types/react@19.0.10)(react-dom@18.3.1(react@18.3.1))(react-is@18.3.1)(react@18.3.1)(redux@5.0.1)
@@ -90,14 +90,11 @@ importers:
specifier: ^6.0.0 specifier: ^6.0.0
version: 6.0.0 version: 6.0.0
urbackup-server-api: urbackup-server-api:
specifier: ^0.91.0 specifier: ^0.8.9
version: 0.91.0 version: 0.8.9
winston: winston:
specifier: ^3.17.0 specifier: ^3.17.0
version: 3.17.0 version: 3.17.0
ws:
specifier: ^8.18.3
version: 8.18.3
xml-js: xml-js:
specifier: ^1.6.11 specifier: ^1.6.11
version: 1.6.11 version: 1.6.11
@@ -106,8 +103,8 @@ importers:
specifier: ^0.5.10 specifier: ^0.5.10
version: 0.5.10(tailwindcss@4.0.9) version: 0.5.10(tailwindcss@4.0.9)
'@tailwindcss/postcss': '@tailwindcss/postcss':
specifier: ^4.1.18 specifier: ^4.1.14
version: 4.1.18 version: 4.1.14
eslint: eslint:
specifier: ^9.25.1 specifier: ^9.25.1
version: 9.25.1(jiti@2.6.1) version: 9.25.1(jiti@2.6.1)
@@ -469,8 +466,8 @@ packages:
'@napi-rs/wasm-runtime@0.2.8': '@napi-rs/wasm-runtime@0.2.8':
resolution: {integrity: sha512-OBlgKdX7gin7OIq4fadsjpg+cp2ZphvAIKucHsNfTdJiqdOmOEwQd/bHi0VwNrcw5xpBJyUw6cK/QilCqy1BSg==} resolution: {integrity: sha512-OBlgKdX7gin7OIq4fadsjpg+cp2ZphvAIKucHsNfTdJiqdOmOEwQd/bHi0VwNrcw5xpBJyUw6cK/QilCqy1BSg==}
'@next/env@15.5.9': '@next/env@15.5.7':
resolution: {integrity: sha512-4GlTZ+EJM7WaW2HEZcyU317tIQDjkQIyENDLxYJfSWlfqguN+dHkZgyQTV/7ykvobU7yEH5gKvreNrH4B6QgIg==} resolution: {integrity: sha512-4h6Y2NyEkIEN7Z8YxkA27pq6zTkS09bUSYC0xjd0NpwFxjnIKeZEeH591o5WECSmjpUhLn3H2QLJcDye3Uzcvg==}
'@next/eslint-plugin-next@15.2.4': '@next/eslint-plugin-next@15.2.4':
resolution: {integrity: sha512-O8ScvKtnxkp8kL9TpJTTKnMqlkZnS+QxwoQnJwPGBxjBbzd6OVVPEJ5/pMNrktSyXQD/chEfzfFzYLM6JANOOQ==} resolution: {integrity: sha512-O8ScvKtnxkp8kL9TpJTTKnMqlkZnS+QxwoQnJwPGBxjBbzd6OVVPEJ5/pMNrktSyXQD/chEfzfFzYLM6JANOOQ==}
@@ -656,65 +653,65 @@ packages:
peerDependencies: peerDependencies:
tailwindcss: '>=3.0.0 || >= 3.0.0-alpha.1 || >= 4.0.0-alpha.20 || >= 4.0.0-beta.1' tailwindcss: '>=3.0.0 || >= 3.0.0-alpha.1 || >= 4.0.0-alpha.20 || >= 4.0.0-beta.1'
'@tailwindcss/node@4.1.18': '@tailwindcss/node@4.1.14':
resolution: {integrity: sha512-DoR7U1P7iYhw16qJ49fgXUlry1t4CpXeErJHnQ44JgTSKMaZUdf17cfn5mHchfJ4KRBZRFA/Coo+MUF5+gOaCQ==} resolution: {integrity: sha512-hpz+8vFk3Ic2xssIA3e01R6jkmsAhvkQdXlEbRTk6S10xDAtiQiM3FyvZVGsucefq764euO/b8WUW9ysLdThHw==}
'@tailwindcss/oxide-android-arm64@4.1.18': '@tailwindcss/oxide-android-arm64@4.1.14':
resolution: {integrity: sha512-dJHz7+Ugr9U/diKJA0W6N/6/cjI+ZTAoxPf9Iz9BFRF2GzEX8IvXxFIi/dZBloVJX/MZGvRuFA9rqwdiIEZQ0Q==} resolution: {integrity: sha512-a94ifZrGwMvbdeAxWoSuGcIl6/DOP5cdxagid7xJv6bwFp3oebp7y2ImYsnZBMTwjn5Ev5xESvS3FFYUGgPODQ==}
engines: {node: '>= 10'} engines: {node: '>= 10'}
cpu: [arm64] cpu: [arm64]
os: [android] os: [android]
'@tailwindcss/oxide-darwin-arm64@4.1.18': '@tailwindcss/oxide-darwin-arm64@4.1.14':
resolution: {integrity: sha512-Gc2q4Qhs660bhjyBSKgq6BYvwDz4G+BuyJ5H1xfhmDR3D8HnHCmT/BSkvSL0vQLy/nkMLY20PQ2OoYMO15Jd0A==} resolution: {integrity: sha512-HkFP/CqfSh09xCnrPJA7jud7hij5ahKyWomrC3oiO2U9i0UjP17o9pJbxUN0IJ471GTQQmzwhp0DEcpbp4MZTA==}
engines: {node: '>= 10'} engines: {node: '>= 10'}
cpu: [arm64] cpu: [arm64]
os: [darwin] os: [darwin]
'@tailwindcss/oxide-darwin-x64@4.1.18': '@tailwindcss/oxide-darwin-x64@4.1.14':
resolution: {integrity: sha512-FL5oxr2xQsFrc3X9o1fjHKBYBMD1QZNyc1Xzw/h5Qu4XnEBi3dZn96HcHm41c/euGV+GRiXFfh2hUCyKi/e+yw==} resolution: {integrity: sha512-eVNaWmCgdLf5iv6Qd3s7JI5SEFBFRtfm6W0mphJYXgvnDEAZ5sZzqmI06bK6xo0IErDHdTA5/t7d4eTfWbWOFw==}
engines: {node: '>= 10'} engines: {node: '>= 10'}
cpu: [x64] cpu: [x64]
os: [darwin] os: [darwin]
'@tailwindcss/oxide-freebsd-x64@4.1.18': '@tailwindcss/oxide-freebsd-x64@4.1.14':
resolution: {integrity: sha512-Fj+RHgu5bDodmV1dM9yAxlfJwkkWvLiRjbhuO2LEtwtlYlBgiAT4x/j5wQr1tC3SANAgD+0YcmWVrj8R9trVMA==} resolution: {integrity: sha512-QWLoRXNikEuqtNb0dhQN6wsSVVjX6dmUFzuuiL09ZeXju25dsei2uIPl71y2Ic6QbNBsB4scwBoFnlBfabHkEw==}
engines: {node: '>= 10'} engines: {node: '>= 10'}
cpu: [x64] cpu: [x64]
os: [freebsd] os: [freebsd]
'@tailwindcss/oxide-linux-arm-gnueabihf@4.1.18': '@tailwindcss/oxide-linux-arm-gnueabihf@4.1.14':
resolution: {integrity: sha512-Fp+Wzk/Ws4dZn+LV2Nqx3IilnhH51YZoRaYHQsVq3RQvEl+71VGKFpkfHrLM/Li+kt5c0DJe/bHXK1eHgDmdiA==} resolution: {integrity: sha512-VB4gjQni9+F0VCASU+L8zSIyjrLLsy03sjcR3bM0V2g4SNamo0FakZFKyUQ96ZVwGK4CaJsc9zd/obQy74o0Fw==}
engines: {node: '>= 10'} engines: {node: '>= 10'}
cpu: [arm] cpu: [arm]
os: [linux] os: [linux]
'@tailwindcss/oxide-linux-arm64-gnu@4.1.18': '@tailwindcss/oxide-linux-arm64-gnu@4.1.14':
resolution: {integrity: sha512-S0n3jboLysNbh55Vrt7pk9wgpyTTPD0fdQeh7wQfMqLPM/Hrxi+dVsLsPrycQjGKEQk85Kgbx+6+QnYNiHalnw==} resolution: {integrity: sha512-qaEy0dIZ6d9vyLnmeg24yzA8XuEAD9WjpM5nIM1sUgQ/Zv7cVkharPDQcmm/t/TvXoKo/0knI3me3AGfdx6w1w==}
engines: {node: '>= 10'} engines: {node: '>= 10'}
cpu: [arm64] cpu: [arm64]
os: [linux] os: [linux]
'@tailwindcss/oxide-linux-arm64-musl@4.1.18': '@tailwindcss/oxide-linux-arm64-musl@4.1.14':
resolution: {integrity: sha512-1px92582HkPQlaaCkdRcio71p8bc8i/ap5807tPRDK/uw953cauQBT8c5tVGkOwrHMfc2Yh6UuxaH4vtTjGvHg==} resolution: {integrity: sha512-ISZjT44s59O8xKsPEIesiIydMG/sCXoMBCqsphDm/WcbnuWLxxb+GcvSIIA5NjUw6F8Tex7s5/LM2yDy8RqYBQ==}
engines: {node: '>= 10'} engines: {node: '>= 10'}
cpu: [arm64] cpu: [arm64]
os: [linux] os: [linux]
'@tailwindcss/oxide-linux-x64-gnu@4.1.18': '@tailwindcss/oxide-linux-x64-gnu@4.1.14':
resolution: {integrity: sha512-v3gyT0ivkfBLoZGF9LyHmts0Isc8jHZyVcbzio6Wpzifg/+5ZJpDiRiUhDLkcr7f/r38SWNe7ucxmGW3j3Kb/g==} resolution: {integrity: sha512-02c6JhLPJj10L2caH4U0zF8Hji4dOeahmuMl23stk0MU1wfd1OraE7rOloidSF8W5JTHkFdVo/O7uRUJJnUAJg==}
engines: {node: '>= 10'} engines: {node: '>= 10'}
cpu: [x64] cpu: [x64]
os: [linux] os: [linux]
'@tailwindcss/oxide-linux-x64-musl@4.1.18': '@tailwindcss/oxide-linux-x64-musl@4.1.14':
resolution: {integrity: sha512-bhJ2y2OQNlcRwwgOAGMY0xTFStt4/wyU6pvI6LSuZpRgKQwxTec0/3Scu91O8ir7qCR3AuepQKLU/kX99FouqQ==} resolution: {integrity: sha512-TNGeLiN1XS66kQhxHG/7wMeQDOoL0S33x9BgmydbrWAb9Qw0KYdd8o1ifx4HOGDWhVmJ+Ul+JQ7lyknQFilO3Q==}
engines: {node: '>= 10'} engines: {node: '>= 10'}
cpu: [x64] cpu: [x64]
os: [linux] os: [linux]
'@tailwindcss/oxide-wasm32-wasi@4.1.18': '@tailwindcss/oxide-wasm32-wasi@4.1.14':
resolution: {integrity: sha512-LffYTvPjODiP6PT16oNeUQJzNVyJl1cjIebq/rWWBF+3eDst5JGEFSc5cWxyRCJ0Mxl+KyIkqRxk1XPEs9x8TA==} resolution: {integrity: sha512-uZYAsaW/jS/IYkd6EWPJKW/NlPNSkWkBlaeVBi/WsFQNP05/bzkebUL8FH1pdsqx4f2fH/bWFcUABOM9nfiJkQ==}
engines: {node: '>=14.0.0'} engines: {node: '>=14.0.0'}
cpu: [wasm32] cpu: [wasm32]
bundledDependencies: bundledDependencies:
@@ -725,24 +722,24 @@ packages:
- '@emnapi/wasi-threads' - '@emnapi/wasi-threads'
- tslib - tslib
'@tailwindcss/oxide-win32-arm64-msvc@4.1.18': '@tailwindcss/oxide-win32-arm64-msvc@4.1.14':
resolution: {integrity: sha512-HjSA7mr9HmC8fu6bdsZvZ+dhjyGCLdotjVOgLA2vEqxEBZaQo9YTX4kwgEvPCpRh8o4uWc4J/wEoFzhEmjvPbA==} resolution: {integrity: sha512-Az0RnnkcvRqsuoLH2Z4n3JfAef0wElgzHD5Aky/e+0tBUxUhIeIqFBTMNQvmMRSP15fWwmvjBxZ3Q8RhsDnxAA==}
engines: {node: '>= 10'} engines: {node: '>= 10'}
cpu: [arm64] cpu: [arm64]
os: [win32] os: [win32]
'@tailwindcss/oxide-win32-x64-msvc@4.1.18': '@tailwindcss/oxide-win32-x64-msvc@4.1.14':
resolution: {integrity: sha512-bJWbyYpUlqamC8dpR7pfjA0I7vdF6t5VpUGMWRkXVE3AXgIZjYUYAK7II1GNaxR8J1SSrSrppRar8G++JekE3Q==} resolution: {integrity: sha512-ttblVGHgf68kEE4om1n/n44I0yGPkCPbLsqzjvybhpwa6mKKtgFfAzy6btc3HRmuW7nHe0OOrSeNP9sQmmH9XA==}
engines: {node: '>= 10'} engines: {node: '>= 10'}
cpu: [x64] cpu: [x64]
os: [win32] os: [win32]
'@tailwindcss/oxide@4.1.18': '@tailwindcss/oxide@4.1.14':
resolution: {integrity: sha512-EgCR5tTS5bUSKQgzeMClT6iCY3ToqE1y+ZB0AKldj809QXk1Y+3jB0upOYZrn9aGIzPtUsP7sX4QQ4XtjBB95A==} resolution: {integrity: sha512-23yx+VUbBwCg2x5XWdB8+1lkPajzLmALEfMb51zZUBYaYVPDQvBSD/WYDqiVyBIo2BZFa3yw1Rpy3G2Jp+K0dw==}
engines: {node: '>= 10'} engines: {node: '>= 10'}
'@tailwindcss/postcss@4.1.18': '@tailwindcss/postcss@4.1.14':
resolution: {integrity: sha512-Ce0GFnzAOuPyfV5SxjXGn0CubwGcuDB0zcdaPuCSzAa/2vII24JTkH+I6jcbXLb1ctjZMZZI6OjDaLPJQL1S0g==} resolution: {integrity: sha512-BdMjIxy7HUNThK87C7BC8I1rE8BVUsfNQSI5siQ4JK3iIa3w0XyVvVL9SXLWO//CtYTcp1v7zci0fYwJOjB+Zg==}
'@tanstack/react-virtual@3.13.12': '@tanstack/react-virtual@3.13.12':
resolution: {integrity: sha512-Gd13QdxPSukP8ZrkbgS2RwoZseTTbQPLnQEn7HY/rqtM+8Zt95f7xKC7N0EsKs7aoz0WzZ+fditZux+F8EzYxA==} resolution: {integrity: sha512-Gd13QdxPSukP8ZrkbgS2RwoZseTTbQPLnQEn7HY/rqtM+8Zt95f7xKC7N0EsKs7aoz0WzZ+fditZux+F8EzYxA==}
@@ -1038,8 +1035,8 @@ packages:
resolution: {integrity: sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA==} resolution: {integrity: sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA==}
engines: {node: '>= 0.4'} engines: {node: '>= 0.4'}
async-mutex@0.5.0: async-mutex@0.3.2:
resolution: {integrity: sha512-1A94B18jkJ3DYq284ohPxoXbfTA5HsQ7/Mf4DEhcyLx3Bz27Rh59iScbB6EPiP+B+joue6YCxcMXSbFC1tZKwA==} resolution: {integrity: sha512-HuTK7E7MT7jZEh1P9GtRW9+aTWiDWWi9InbZ5hjxrnRa39KS4BW04+xLBhYNS2aXhHUIKZSw3gj4Pn1pj+qGAA==}
async@3.2.6: async@3.2.6:
resolution: {integrity: sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==} resolution: {integrity: sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==}
@@ -1123,8 +1120,8 @@ packages:
resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==}
engines: {node: '>=6'} engines: {node: '>=6'}
caniuse-lite@1.0.30001760: caniuse-lite@1.0.30001759:
resolution: {integrity: sha512-7AAMPcueWELt1p3mi13HR/LHH0TJLT11cnwDJEs3xA4+CK/PLKeO9Kl1oru24htkyUKtkGCvAx4ohB0Ttry8Dw==} resolution: {integrity: sha512-Pzfx9fOKoKvevQf8oCXoyNRQ5QyxJj+3O0Rqx2V5oxT61KGx8+n6hV/IUyJeifUci2clnmmKVpvtiqRzgiWjSw==}
chalk@4.1.2: chalk@4.1.2:
resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==}
@@ -1323,6 +1320,10 @@ packages:
resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==} resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==}
engines: {node: '>=6'} engines: {node: '>=6'}
detect-libc@2.1.1:
resolution: {integrity: sha512-ecqj/sy1jcK1uWrwpR67UhYrIFQ+5WlGxth34WquCbamhFA6hkkwiu37o6J5xCHdo1oixJRfVRw+ywV+Hq/0Aw==}
engines: {node: '>=8'}
detect-libc@2.1.2: detect-libc@2.1.2:
resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==} resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==}
engines: {node: '>=8'} engines: {node: '>=8'}
@@ -1361,8 +1362,8 @@ packages:
end-of-stream@1.4.5: end-of-stream@1.4.5:
resolution: {integrity: sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==} resolution: {integrity: sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==}
enhanced-resolve@5.18.4: enhanced-resolve@5.18.3:
resolution: {integrity: sha512-LgQMM4WXU3QI+SYgEc2liRgznaD5ojbmY3sb8LxyguVkIg5FxdpTkvk72te2R38/TGKxH634oLxXRGY6d7AP+Q==} resolution: {integrity: sha512-d4lC8xfavMeBjzGr2vECC3fsGXziXZQyJxD868h2M/mBI3PwAuODxAkLkq5HYuvrPYcUtiLzsTo8U3PgX3Ocww==}
engines: {node: '>=10.13.0'} engines: {node: '>=10.13.0'}
es-abstract@1.23.9: es-abstract@1.23.9:
@@ -1965,8 +1966,8 @@ packages:
js-tokens@4.0.0: js-tokens@4.0.0:
resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==}
js-yaml@4.1.1: js-yaml@4.1.0:
resolution: {integrity: sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==} resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==}
hasBin: true hasBin: true
jsep@1.4.0: jsep@1.4.0:
@@ -2015,74 +2016,68 @@ packages:
resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==}
engines: {node: '>= 0.8.0'} engines: {node: '>= 0.8.0'}
lightningcss-android-arm64@1.30.2: lightningcss-darwin-arm64@1.30.1:
resolution: {integrity: sha512-BH9sEdOCahSgmkVhBLeU7Hc9DWeZ1Eb6wNS6Da8igvUwAe0sqROHddIlvU06q3WyXVEOYDZ6ykBZQnjTbmo4+A==} resolution: {integrity: sha512-c8JK7hyE65X1MHMN+Viq9n11RRC7hgin3HhYKhrMyaXflk5GVplZ60IxyoVtzILeKr+xAJwg6zK6sjTBJ0FKYQ==}
engines: {node: '>= 12.0.0'}
cpu: [arm64]
os: [android]
lightningcss-darwin-arm64@1.30.2:
resolution: {integrity: sha512-ylTcDJBN3Hp21TdhRT5zBOIi73P6/W0qwvlFEk22fkdXchtNTOU4Qc37SkzV+EKYxLouZ6M4LG9NfZ1qkhhBWA==}
engines: {node: '>= 12.0.0'} engines: {node: '>= 12.0.0'}
cpu: [arm64] cpu: [arm64]
os: [darwin] os: [darwin]
lightningcss-darwin-x64@1.30.2: lightningcss-darwin-x64@1.30.1:
resolution: {integrity: sha512-oBZgKchomuDYxr7ilwLcyms6BCyLn0z8J0+ZZmfpjwg9fRVZIR5/GMXd7r9RH94iDhld3UmSjBM6nXWM2TfZTQ==} resolution: {integrity: sha512-k1EvjakfumAQoTfcXUcHQZhSpLlkAuEkdMBsI/ivWw9hL+7FtilQc0Cy3hrx0AAQrVtQAbMI7YjCgYgvn37PzA==}
engines: {node: '>= 12.0.0'} engines: {node: '>= 12.0.0'}
cpu: [x64] cpu: [x64]
os: [darwin] os: [darwin]
lightningcss-freebsd-x64@1.30.2: lightningcss-freebsd-x64@1.30.1:
resolution: {integrity: sha512-c2bH6xTrf4BDpK8MoGG4Bd6zAMZDAXS569UxCAGcA7IKbHNMlhGQ89eRmvpIUGfKWNVdbhSbkQaWhEoMGmGslA==} resolution: {integrity: sha512-kmW6UGCGg2PcyUE59K5r0kWfKPAVy4SltVeut+umLCFoJ53RdCUWxcRDzO1eTaxf/7Q2H7LTquFHPL5R+Gjyig==}
engines: {node: '>= 12.0.0'} engines: {node: '>= 12.0.0'}
cpu: [x64] cpu: [x64]
os: [freebsd] os: [freebsd]
lightningcss-linux-arm-gnueabihf@1.30.2: lightningcss-linux-arm-gnueabihf@1.30.1:
resolution: {integrity: sha512-eVdpxh4wYcm0PofJIZVuYuLiqBIakQ9uFZmipf6LF/HRj5Bgm0eb3qL/mr1smyXIS1twwOxNWndd8z0E374hiA==} resolution: {integrity: sha512-MjxUShl1v8pit+6D/zSPq9S9dQ2NPFSQwGvxBCYaBYLPlCWuPh9/t1MRS8iUaR8i+a6w7aps+B4N0S1TYP/R+Q==}
engines: {node: '>= 12.0.0'} engines: {node: '>= 12.0.0'}
cpu: [arm] cpu: [arm]
os: [linux] os: [linux]
lightningcss-linux-arm64-gnu@1.30.2: lightningcss-linux-arm64-gnu@1.30.1:
resolution: {integrity: sha512-UK65WJAbwIJbiBFXpxrbTNArtfuznvxAJw4Q2ZGlU8kPeDIWEX1dg3rn2veBVUylA2Ezg89ktszWbaQnxD/e3A==} resolution: {integrity: sha512-gB72maP8rmrKsnKYy8XUuXi/4OctJiuQjcuqWNlJQ6jZiWqtPvqFziskH3hnajfvKB27ynbVCucKSm2rkQp4Bw==}
engines: {node: '>= 12.0.0'} engines: {node: '>= 12.0.0'}
cpu: [arm64] cpu: [arm64]
os: [linux] os: [linux]
lightningcss-linux-arm64-musl@1.30.2: lightningcss-linux-arm64-musl@1.30.1:
resolution: {integrity: sha512-5Vh9dGeblpTxWHpOx8iauV02popZDsCYMPIgiuw97OJ5uaDsL86cnqSFs5LZkG3ghHoX5isLgWzMs+eD1YzrnA==} resolution: {integrity: sha512-jmUQVx4331m6LIX+0wUhBbmMX7TCfjF5FoOH6SD1CttzuYlGNVpA7QnrmLxrsub43ClTINfGSYyHe2HWeLl5CQ==}
engines: {node: '>= 12.0.0'} engines: {node: '>= 12.0.0'}
cpu: [arm64] cpu: [arm64]
os: [linux] os: [linux]
lightningcss-linux-x64-gnu@1.30.2: lightningcss-linux-x64-gnu@1.30.1:
resolution: {integrity: sha512-Cfd46gdmj1vQ+lR6VRTTadNHu6ALuw2pKR9lYq4FnhvgBc4zWY1EtZcAc6EffShbb1MFrIPfLDXD6Xprbnni4w==} resolution: {integrity: sha512-piWx3z4wN8J8z3+O5kO74+yr6ze/dKmPnI7vLqfSqI8bccaTGY5xiSGVIJBDd5K5BHlvVLpUB3S2YCfelyJ1bw==}
engines: {node: '>= 12.0.0'} engines: {node: '>= 12.0.0'}
cpu: [x64] cpu: [x64]
os: [linux] os: [linux]
lightningcss-linux-x64-musl@1.30.2: lightningcss-linux-x64-musl@1.30.1:
resolution: {integrity: sha512-XJaLUUFXb6/QG2lGIW6aIk6jKdtjtcffUT0NKvIqhSBY3hh9Ch+1LCeH80dR9q9LBjG3ewbDjnumefsLsP6aiA==} resolution: {integrity: sha512-rRomAK7eIkL+tHY0YPxbc5Dra2gXlI63HL+v1Pdi1a3sC+tJTcFrHX+E86sulgAXeI7rSzDYhPSeHHjqFhqfeQ==}
engines: {node: '>= 12.0.0'} engines: {node: '>= 12.0.0'}
cpu: [x64] cpu: [x64]
os: [linux] os: [linux]
lightningcss-win32-arm64-msvc@1.30.2: lightningcss-win32-arm64-msvc@1.30.1:
resolution: {integrity: sha512-FZn+vaj7zLv//D/192WFFVA0RgHawIcHqLX9xuWiQt7P0PtdFEVaxgF9rjM/IRYHQXNnk61/H/gb2Ei+kUQ4xQ==} resolution: {integrity: sha512-mSL4rqPi4iXq5YVqzSsJgMVFENoa4nGTT/GjO2c0Yl9OuQfPsIfncvLrEW6RbbB24WtZ3xP/2CCmI3tNkNV4oA==}
engines: {node: '>= 12.0.0'} engines: {node: '>= 12.0.0'}
cpu: [arm64] cpu: [arm64]
os: [win32] os: [win32]
lightningcss-win32-x64-msvc@1.30.2: lightningcss-win32-x64-msvc@1.30.1:
resolution: {integrity: sha512-5g1yc73p+iAkid5phb4oVFMB45417DkRevRbt/El/gKXJk4jid+vPFF/AXbxn05Aky8PapwzZrdJShv5C0avjw==} resolution: {integrity: sha512-PVqXh48wh4T53F/1CCu8PIPCxLzWyCnn/9T5W1Jpmdy5h9Cwd+0YQS6/LwhHXSafuc61/xg9Lv5OrCby6a++jg==}
engines: {node: '>= 12.0.0'} engines: {node: '>= 12.0.0'}
cpu: [x64] cpu: [x64]
os: [win32] os: [win32]
lightningcss@1.30.2: lightningcss@1.30.1:
resolution: {integrity: sha512-utfs7Pr5uJyyvDETitgsaqSyjCb2qNRAtuqUeWIAKztsOYdcACf2KtARYXg2pSvhkt+9NfoaNY7fxjl6nuMjIQ==} resolution: {integrity: sha512-xi6IyHML+c9+Q3W0S4fCQJOym42pyurFiJUHEcEyHS0CeKzia4yZDEsLlqOFykxOdHpNy0NmvVO31vcSqAxJCg==}
engines: {node: '>= 12.0.0'} engines: {node: '>= 12.0.0'}
locate-path@6.0.0: locate-path@6.0.0:
@@ -2117,8 +2112,8 @@ packages:
resolution: {integrity: sha512-tJLxrKJhO2ukZ5z0gyjY1zPh3Rh88Ej9P7jNrZiHMUXHae1yvI2imgOZtL1TO8TW6biMMKfTtAOoEJANgtWBMQ==} resolution: {integrity: sha512-tJLxrKJhO2ukZ5z0gyjY1zPh3Rh88Ej9P7jNrZiHMUXHae1yvI2imgOZtL1TO8TW6biMMKfTtAOoEJANgtWBMQ==}
engines: {node: '>=12'} engines: {node: '>=12'}
magic-string@0.30.21: magic-string@0.30.19:
resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==} resolution: {integrity: sha512-2N21sPY9Ws53PZvsEpVtNuSW+ScYbQdp4b9qUaL+9QkHUrGFKo56Lg9Emg5s9V/qrtNBmiR01sYhUOwu3H+VOw==}
math-intrinsics@1.1.0: math-intrinsics@1.1.0:
resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==} resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==}
@@ -2181,6 +2176,10 @@ packages:
resolution: {integrity: sha512-umcy022ILvb5/3Djuu8LWeqUa8D68JaBzlttKeMWen48SjabqS3iY5w/vzeMzMUNhLDifyhbOwKDSznB1vvrwg==} resolution: {integrity: sha512-umcy022ILvb5/3Djuu8LWeqUa8D68JaBzlttKeMWen48SjabqS3iY5w/vzeMzMUNhLDifyhbOwKDSznB1vvrwg==}
engines: {node: '>= 18'} engines: {node: '>= 18'}
minizlib@3.1.0:
resolution: {integrity: sha512-KZxYo1BUkWD2TVFLr0MQoM8vUUigWD3LlD83a/75BqC+4qE0Hb1Vo5v1FgcfaNXvfXzr+5EhQ6ing/CaBijTlw==}
engines: {node: '>= 18'}
mkdirp-classic@0.5.3: mkdirp-classic@0.5.3:
resolution: {integrity: sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==} resolution: {integrity: sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==}
@@ -2213,8 +2212,8 @@ packages:
next: '>= 10.0.0' next: '>= 10.0.0'
react: '>= 16.8.0' react: '>= 16.8.0'
next@15.5.9: next@15.5.7:
resolution: {integrity: sha512-agNLK89seZEtC5zUHwtut0+tNrc0Xw4FT/Dg+B/VLEo9pAcS9rtTKpek3V6kVcVwsB2YlqMaHdfZL4eLEVYuCg==} resolution: {integrity: sha512-+t2/0jIJ48kUpGKkdlhgkv+zPTEOoXyr60qXe68eB/pl3CMJaLeIGjzp5D6Oqt25hCBiBTt8wEeeAzfJvUKnPQ==}
engines: {node: ^18.18.0 || ^19.8.0 || >= 20.0.0} engines: {node: ^18.18.0 || ^19.8.0 || >= 20.0.0}
hasBin: true hasBin: true
peerDependencies: peerDependencies:
@@ -2459,8 +2458,8 @@ packages:
typescript: typescript:
optional: true optional: true
react-icons@5.5.0: react-icons@5.4.0:
resolution: {integrity: sha512-MEFcXdkP3dLo8uumGI5xN3lDFNsRtrjbOEKDLD7yv76v4wpnEq2Lt2qeHaQOr34I/wPN3s3+N08WkQ+CW37Xiw==} resolution: {integrity: sha512-7eltJxgVt7X64oHh6wSWNwwbKTCtMfK35hcjvJS0yxEAhPM8oUKdS3+kqaW1vicIltw+kR2unHaa12S9pPALoQ==}
peerDependencies: peerDependencies:
react: '*' react: '*'
@@ -2806,11 +2805,11 @@ packages:
tailwindcss@4.0.9: tailwindcss@4.0.9:
resolution: {integrity: sha512-12laZu+fv1ONDRoNR9ipTOpUD7RN9essRVkX36sjxuRUInpN7hIiHN4lBd/SIFjbISvnXzp8h/hXzmU8SQQYhw==} resolution: {integrity: sha512-12laZu+fv1ONDRoNR9ipTOpUD7RN9essRVkX36sjxuRUInpN7hIiHN4lBd/SIFjbISvnXzp8h/hXzmU8SQQYhw==}
tailwindcss@4.1.18: tailwindcss@4.1.14:
resolution: {integrity: sha512-4+Z+0yiYyEtUVCScyfHCxOYP06L5Ne+JiHhY2IjR2KWMIWhJOYZKLSGZaP5HkZ8+bY0cxfzwDE5uOmzFXyIwxw==} resolution: {integrity: sha512-b7pCxjGO98LnxVkKjaZSDeNuljC4ueKUddjENJOADtubtdo8llTaJy7HwBMeLNSSo2N5QIAgklslK1+Ir8r6CA==}
tapable@2.3.0: tapable@2.2.3:
resolution: {integrity: sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg==} resolution: {integrity: sha512-ZL6DDuAlRlLGghwcfmSn9sK3Hr6ArtyudlSAiCqQ6IfE+b+HHbydbYDIG15IfS5do+7XQQBdBiubF/cV2dnDzg==}
engines: {node: '>=6'} engines: {node: '>=6'}
tar-fs@2.1.3: tar-fs@2.1.3:
@@ -2824,6 +2823,10 @@ packages:
resolution: {integrity: sha512-5S7Va8hKfV7W5U6g3aYxXmlPoZVAwUMy9AOKyF2fVuZa2UD3qZjg578OrLRt8PcNN1PleVaL/5/yYATNL0ICUw==} resolution: {integrity: sha512-5S7Va8hKfV7W5U6g3aYxXmlPoZVAwUMy9AOKyF2fVuZa2UD3qZjg578OrLRt8PcNN1PleVaL/5/yYATNL0ICUw==}
engines: {node: '>=18'} engines: {node: '>=18'}
tar@7.5.1:
resolution: {integrity: sha512-nlGpxf+hv0v7GkWBK2V9spgactGOp0qvfWRxUMjqHyzrt3SgwE48DIv/FhqPHJYLHpgW1opq3nERbz5Anq7n1g==}
engines: {node: '>=18'}
telnet-client@2.2.6: telnet-client@2.2.6:
resolution: {integrity: sha512-ZUYrLsPtQupQww3eSEORDVOb6ztdtKEghya6TVXPo2tg/UQq2pn5rHhvwuUvyYpbnsoqdNY1fyD1GNkXHR8dYA==} resolution: {integrity: sha512-ZUYrLsPtQupQww3eSEORDVOb6ztdtKEghya6TVXPo2tg/UQq2pn5rHhvwuUvyYpbnsoqdNY1fyD1GNkXHR8dYA==}
@@ -2927,8 +2930,8 @@ packages:
unrs-resolver@1.3.3: unrs-resolver@1.3.3:
resolution: {integrity: sha512-PFLAGQzYlyjniXdbmQ3dnGMZJXX5yrl2YS4DLRfR3BhgUsE1zpRIrccp9XMOGRfIHpdFvCn/nr5N1KMVda4x3A==} resolution: {integrity: sha512-PFLAGQzYlyjniXdbmQ3dnGMZJXX5yrl2YS4DLRfR3BhgUsE1zpRIrccp9XMOGRfIHpdFvCn/nr5N1KMVda4x3A==}
urbackup-server-api@0.91.0: urbackup-server-api@0.8.9:
resolution: {integrity: sha512-N1CSnGSCSHjwWfGOp6jE56mHYoZor/p++ii8yPsN9P/3cKLBgCvrAZxAbfi+IgK9FZpQEx/kPX1R8OTJRy+x6A==} resolution: {integrity: sha512-Igu6A0xSZeMsiN6PWT7zG4aD+iJR5fXT/j5+xwAvnD/vCNfvVrettIsXv6MftxOajvTmtlgaYu8KDoH1EJQ6DQ==}
uri-js@4.4.1: uri-js@4.4.1:
resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==}
@@ -3014,8 +3017,8 @@ packages:
wrappy@1.0.2: wrappy@1.0.2:
resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==}
ws@8.18.3: ws@8.18.0:
resolution: {integrity: sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==} resolution: {integrity: sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==}
engines: {node: '>=10.0.0'} engines: {node: '>=10.0.0'}
peerDependencies: peerDependencies:
bufferutil: ^4.0.1 bufferutil: ^4.0.1
@@ -3125,7 +3128,7 @@ snapshots:
globals: 14.0.0 globals: 14.0.0
ignore: 5.3.2 ignore: 5.3.2
import-fresh: 3.3.1 import-fresh: 3.3.1
js-yaml: 4.1.1 js-yaml: 4.1.0
minimatch: 3.1.2 minimatch: 3.1.2
strip-json-comments: 3.1.1 strip-json-comments: 3.1.1
transitivePeerDependencies: transitivePeerDependencies:
@@ -3348,8 +3351,8 @@ snapshots:
'@types/tar': 6.1.13 '@types/tar': 6.1.13
'@types/ws': 8.5.14 '@types/ws': 8.5.14
form-data: 4.0.2 form-data: 4.0.2
isomorphic-ws: 5.0.0(ws@8.18.3) isomorphic-ws: 5.0.0(ws@8.18.0)
js-yaml: 4.1.1 js-yaml: 4.1.0
jsonpath-plus: 10.3.0 jsonpath-plus: 10.3.0
node-fetch: 2.7.0 node-fetch: 2.7.0
openid-client: 6.3.0 openid-client: 6.3.0
@@ -3358,7 +3361,7 @@ snapshots:
tar: 7.4.3 tar: 7.4.3
tmp-promise: 3.0.3 tmp-promise: 3.0.3
tslib: 2.8.1 tslib: 2.8.1
ws: 8.18.3 ws: 8.18.0
transitivePeerDependencies: transitivePeerDependencies:
- bufferutil - bufferutil
- encoding - encoding
@@ -3371,7 +3374,7 @@ snapshots:
'@tybys/wasm-util': 0.9.0 '@tybys/wasm-util': 0.9.0
optional: true optional: true
'@next/env@15.5.9': {} '@next/env@15.5.7': {}
'@next/eslint-plugin-next@15.2.4': '@next/eslint-plugin-next@15.2.4':
dependencies: dependencies:
@@ -3531,74 +3534,77 @@ snapshots:
mini-svg-data-uri: 1.4.4 mini-svg-data-uri: 1.4.4
tailwindcss: 4.0.9 tailwindcss: 4.0.9
'@tailwindcss/node@4.1.18': '@tailwindcss/node@4.1.14':
dependencies: dependencies:
'@jridgewell/remapping': 2.3.5 '@jridgewell/remapping': 2.3.5
enhanced-resolve: 5.18.4 enhanced-resolve: 5.18.3
jiti: 2.6.1 jiti: 2.6.1
lightningcss: 1.30.2 lightningcss: 1.30.1
magic-string: 0.30.21 magic-string: 0.30.19
source-map-js: 1.2.1 source-map-js: 1.2.1
tailwindcss: 4.1.18 tailwindcss: 4.1.14
'@tailwindcss/oxide-android-arm64@4.1.18': '@tailwindcss/oxide-android-arm64@4.1.14':
optional: true optional: true
'@tailwindcss/oxide-darwin-arm64@4.1.18': '@tailwindcss/oxide-darwin-arm64@4.1.14':
optional: true optional: true
'@tailwindcss/oxide-darwin-x64@4.1.18': '@tailwindcss/oxide-darwin-x64@4.1.14':
optional: true optional: true
'@tailwindcss/oxide-freebsd-x64@4.1.18': '@tailwindcss/oxide-freebsd-x64@4.1.14':
optional: true optional: true
'@tailwindcss/oxide-linux-arm-gnueabihf@4.1.18': '@tailwindcss/oxide-linux-arm-gnueabihf@4.1.14':
optional: true optional: true
'@tailwindcss/oxide-linux-arm64-gnu@4.1.18': '@tailwindcss/oxide-linux-arm64-gnu@4.1.14':
optional: true optional: true
'@tailwindcss/oxide-linux-arm64-musl@4.1.18': '@tailwindcss/oxide-linux-arm64-musl@4.1.14':
optional: true optional: true
'@tailwindcss/oxide-linux-x64-gnu@4.1.18': '@tailwindcss/oxide-linux-x64-gnu@4.1.14':
optional: true optional: true
'@tailwindcss/oxide-linux-x64-musl@4.1.18': '@tailwindcss/oxide-linux-x64-musl@4.1.14':
optional: true optional: true
'@tailwindcss/oxide-wasm32-wasi@4.1.18': '@tailwindcss/oxide-wasm32-wasi@4.1.14':
optional: true optional: true
'@tailwindcss/oxide-win32-arm64-msvc@4.1.18': '@tailwindcss/oxide-win32-arm64-msvc@4.1.14':
optional: true optional: true
'@tailwindcss/oxide-win32-x64-msvc@4.1.18': '@tailwindcss/oxide-win32-x64-msvc@4.1.14':
optional: true optional: true
'@tailwindcss/oxide@4.1.18': '@tailwindcss/oxide@4.1.14':
dependencies:
detect-libc: 2.1.1
tar: 7.5.1
optionalDependencies: optionalDependencies:
'@tailwindcss/oxide-android-arm64': 4.1.18 '@tailwindcss/oxide-android-arm64': 4.1.14
'@tailwindcss/oxide-darwin-arm64': 4.1.18 '@tailwindcss/oxide-darwin-arm64': 4.1.14
'@tailwindcss/oxide-darwin-x64': 4.1.18 '@tailwindcss/oxide-darwin-x64': 4.1.14
'@tailwindcss/oxide-freebsd-x64': 4.1.18 '@tailwindcss/oxide-freebsd-x64': 4.1.14
'@tailwindcss/oxide-linux-arm-gnueabihf': 4.1.18 '@tailwindcss/oxide-linux-arm-gnueabihf': 4.1.14
'@tailwindcss/oxide-linux-arm64-gnu': 4.1.18 '@tailwindcss/oxide-linux-arm64-gnu': 4.1.14
'@tailwindcss/oxide-linux-arm64-musl': 4.1.18 '@tailwindcss/oxide-linux-arm64-musl': 4.1.14
'@tailwindcss/oxide-linux-x64-gnu': 4.1.18 '@tailwindcss/oxide-linux-x64-gnu': 4.1.14
'@tailwindcss/oxide-linux-x64-musl': 4.1.18 '@tailwindcss/oxide-linux-x64-musl': 4.1.14
'@tailwindcss/oxide-wasm32-wasi': 4.1.18 '@tailwindcss/oxide-wasm32-wasi': 4.1.14
'@tailwindcss/oxide-win32-arm64-msvc': 4.1.18 '@tailwindcss/oxide-win32-arm64-msvc': 4.1.14
'@tailwindcss/oxide-win32-x64-msvc': 4.1.18 '@tailwindcss/oxide-win32-x64-msvc': 4.1.14
'@tailwindcss/postcss@4.1.18': '@tailwindcss/postcss@4.1.14':
dependencies: dependencies:
'@alloc/quick-lru': 5.2.0 '@alloc/quick-lru': 5.2.0
'@tailwindcss/node': 4.1.18 '@tailwindcss/node': 4.1.14
'@tailwindcss/oxide': 4.1.18 '@tailwindcss/oxide': 4.1.14
postcss: 8.5.6 postcss: 8.5.6
tailwindcss: 4.1.18 tailwindcss: 4.1.14
'@tanstack/react-virtual@3.13.12(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': '@tanstack/react-virtual@3.13.12(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
dependencies: dependencies:
@@ -3925,7 +3931,7 @@ snapshots:
async-function@1.0.0: {} async-function@1.0.0: {}
async-mutex@0.5.0: async-mutex@0.3.2:
dependencies: dependencies:
tslib: 2.8.1 tslib: 2.8.1
@@ -4018,7 +4024,7 @@ snapshots:
callsites@3.1.0: {} callsites@3.1.0: {}
caniuse-lite@1.0.30001760: {} caniuse-lite@1.0.30001759: {}
chalk@4.1.2: chalk@4.1.2:
dependencies: dependencies:
@@ -4194,7 +4200,10 @@ snapshots:
dequal@2.0.3: {} dequal@2.0.3: {}
detect-libc@2.1.2: {} detect-libc@2.1.1: {}
detect-libc@2.1.2:
optional: true
docker-modem@5.0.6: docker-modem@5.0.6:
dependencies: dependencies:
@@ -4241,10 +4250,10 @@ snapshots:
dependencies: dependencies:
once: 1.4.0 once: 1.4.0
enhanced-resolve@5.18.4: enhanced-resolve@5.18.3:
dependencies: dependencies:
graceful-fs: 4.2.11 graceful-fs: 4.2.11
tapable: 2.3.0 tapable: 2.2.3
es-abstract@1.23.9: es-abstract@1.23.9:
dependencies: dependencies:
@@ -5036,9 +5045,9 @@ snapshots:
isexe@2.0.0: {} isexe@2.0.0: {}
isomorphic-ws@5.0.0(ws@8.18.3): isomorphic-ws@5.0.0(ws@8.18.0):
dependencies: dependencies:
ws: 8.18.3 ws: 8.18.0
iterator.prototype@1.1.5: iterator.prototype@1.1.5:
dependencies: dependencies:
@@ -5061,7 +5070,7 @@ snapshots:
js-tokens@4.0.0: {} js-tokens@4.0.0: {}
js-yaml@4.1.1: js-yaml@4.1.0:
dependencies: dependencies:
argparse: 2.0.1 argparse: 2.0.1
@@ -5109,54 +5118,50 @@ snapshots:
prelude-ls: 1.2.1 prelude-ls: 1.2.1
type-check: 0.4.0 type-check: 0.4.0
lightningcss-android-arm64@1.30.2: lightningcss-darwin-arm64@1.30.1:
optional: true optional: true
lightningcss-darwin-arm64@1.30.2: lightningcss-darwin-x64@1.30.1:
optional: true optional: true
lightningcss-darwin-x64@1.30.2: lightningcss-freebsd-x64@1.30.1:
optional: true optional: true
lightningcss-freebsd-x64@1.30.2: lightningcss-linux-arm-gnueabihf@1.30.1:
optional: true optional: true
lightningcss-linux-arm-gnueabihf@1.30.2: lightningcss-linux-arm64-gnu@1.30.1:
optional: true optional: true
lightningcss-linux-arm64-gnu@1.30.2: lightningcss-linux-arm64-musl@1.30.1:
optional: true optional: true
lightningcss-linux-arm64-musl@1.30.2: lightningcss-linux-x64-gnu@1.30.1:
optional: true optional: true
lightningcss-linux-x64-gnu@1.30.2: lightningcss-linux-x64-musl@1.30.1:
optional: true optional: true
lightningcss-linux-x64-musl@1.30.2: lightningcss-win32-arm64-msvc@1.30.1:
optional: true optional: true
lightningcss-win32-arm64-msvc@1.30.2: lightningcss-win32-x64-msvc@1.30.1:
optional: true optional: true
lightningcss-win32-x64-msvc@1.30.2: lightningcss@1.30.1:
optional: true
lightningcss@1.30.2:
dependencies: dependencies:
detect-libc: 2.1.2 detect-libc: 2.1.1
optionalDependencies: optionalDependencies:
lightningcss-android-arm64: 1.30.2 lightningcss-darwin-arm64: 1.30.1
lightningcss-darwin-arm64: 1.30.2 lightningcss-darwin-x64: 1.30.1
lightningcss-darwin-x64: 1.30.2 lightningcss-freebsd-x64: 1.30.1
lightningcss-freebsd-x64: 1.30.2 lightningcss-linux-arm-gnueabihf: 1.30.1
lightningcss-linux-arm-gnueabihf: 1.30.2 lightningcss-linux-arm64-gnu: 1.30.1
lightningcss-linux-arm64-gnu: 1.30.2 lightningcss-linux-arm64-musl: 1.30.1
lightningcss-linux-arm64-musl: 1.30.2 lightningcss-linux-x64-gnu: 1.30.1
lightningcss-linux-x64-gnu: 1.30.2 lightningcss-linux-x64-musl: 1.30.1
lightningcss-linux-x64-musl: 1.30.2 lightningcss-win32-arm64-msvc: 1.30.1
lightningcss-win32-arm64-msvc: 1.30.2 lightningcss-win32-x64-msvc: 1.30.1
lightningcss-win32-x64-msvc: 1.30.2
locate-path@6.0.0: locate-path@6.0.0:
dependencies: dependencies:
@@ -5187,7 +5192,7 @@ snapshots:
luxon@3.6.1: {} luxon@3.6.1: {}
magic-string@0.30.21: magic-string@0.30.19:
dependencies: dependencies:
'@jridgewell/sourcemap-codec': 1.5.5 '@jridgewell/sourcemap-codec': 1.5.5
@@ -5235,6 +5240,10 @@ snapshots:
minipass: 7.1.2 minipass: 7.1.2
rimraf: 5.0.10 rimraf: 5.0.10
minizlib@3.1.0:
dependencies:
minipass: 7.1.2
mkdirp-classic@0.5.3: {} mkdirp-classic@0.5.3: {}
mkdirp@3.0.1: {} mkdirp@3.0.1: {}
@@ -5250,7 +5259,7 @@ snapshots:
net@1.0.2: {} net@1.0.2: {}
next-i18next@12.1.0(next@15.5.9(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1): next-i18next@12.1.0(next@15.5.7(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1):
dependencies: dependencies:
'@babel/runtime': 7.26.9 '@babel/runtime': 7.26.9
'@types/hoist-non-react-statics': 3.3.6 '@types/hoist-non-react-statics': 3.3.6
@@ -5258,18 +5267,18 @@ snapshots:
hoist-non-react-statics: 3.3.2 hoist-non-react-statics: 3.3.2
i18next: 21.10.0 i18next: 21.10.0
i18next-fs-backend: 1.2.0 i18next-fs-backend: 1.2.0
next: 15.5.9(react-dom@18.3.1(react@18.3.1))(react@18.3.1) next: 15.5.7(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
react: 18.3.1 react: 18.3.1
react-i18next: 11.18.6(i18next@21.10.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) react-i18next: 11.18.6(i18next@21.10.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
transitivePeerDependencies: transitivePeerDependencies:
- react-dom - react-dom
- react-native - react-native
next@15.5.9(react-dom@18.3.1(react@18.3.1))(react@18.3.1): next@15.5.7(react-dom@18.3.1(react@18.3.1))(react@18.3.1):
dependencies: dependencies:
'@next/env': 15.5.9 '@next/env': 15.5.7
'@swc/helpers': 0.5.15 '@swc/helpers': 0.5.15
caniuse-lite: 1.0.30001760 caniuse-lite: 1.0.30001759
postcss: 8.4.31 postcss: 8.4.31
react: 18.3.1 react: 18.3.1
react-dom: 18.3.1(react@18.3.1) react-dom: 18.3.1(react@18.3.1)
@@ -5504,7 +5513,7 @@ snapshots:
react-dom: 18.3.1(react@18.3.1) react-dom: 18.3.1(react@18.3.1)
typescript: 5.7.3 typescript: 5.7.3
react-icons@5.5.0(react@18.3.1): react-icons@5.4.0(react@18.3.1):
dependencies: dependencies:
react: 18.3.1 react: 18.3.1
@@ -5927,9 +5936,9 @@ snapshots:
tailwindcss@4.0.9: {} tailwindcss@4.0.9: {}
tailwindcss@4.1.18: {} tailwindcss@4.1.14: {}
tapable@2.3.0: {} tapable@2.2.3: {}
tar-fs@2.1.3: tar-fs@2.1.3:
dependencies: dependencies:
@@ -5955,6 +5964,14 @@ snapshots:
mkdirp: 3.0.1 mkdirp: 3.0.1
yallist: 5.0.0 yallist: 5.0.0
tar@7.5.1:
dependencies:
'@isaacs/fs-minipass': 4.0.1
chownr: 3.0.0
minipass: 7.1.2
minizlib: 3.1.0
yallist: 5.0.0
telnet-client@2.2.6: telnet-client@2.2.6:
dependencies: dependencies:
net: 1.0.2 net: 1.0.2
@@ -6080,9 +6097,12 @@ snapshots:
'@unrs/resolver-binding-win32-ia32-msvc': 1.3.3 '@unrs/resolver-binding-win32-ia32-msvc': 1.3.3
'@unrs/resolver-binding-win32-x64-msvc': 1.3.3 '@unrs/resolver-binding-win32-x64-msvc': 1.3.3
urbackup-server-api@0.91.0: urbackup-server-api@0.8.9:
dependencies: dependencies:
async-mutex: 0.5.0 async-mutex: 0.3.2
node-fetch: 2.7.0
transitivePeerDependencies:
- encoding
uri-js@4.4.1: uri-js@4.4.1:
dependencies: dependencies:
@@ -6218,7 +6238,7 @@ snapshots:
wrappy@1.0.2: {} wrappy@1.0.2: {}
ws@8.18.3: {} ws@8.18.0: {}
xml-js@1.6.11: xml-js@1.6.11:
dependencies: dependencies:

View File

@@ -532,8 +532,7 @@
"child_bridges_status": "{{ok}}/{{total}}", "child_bridges_status": "{{ok}}/{{total}}",
"up": "Op", "up": "Op",
"pending": "Afwagtend", "pending": "Afwagtend",
"down": "Af", "down": "Af"
"ok": "Ok"
}, },
"healthchecks": { "healthchecks": {
"new": "Nuut", "new": "Nuut",
@@ -770,7 +769,7 @@
"gross_percent_today": "Vandag", "gross_percent_today": "Vandag",
"gross_percent_1y": "Een jaar", "gross_percent_1y": "Een jaar",
"gross_percent_max": "Alle tyd", "gross_percent_max": "Alle tyd",
"net_worth": "Netto Waarde" "net_worth": "Net Worth"
}, },
"audiobookshelf": { "audiobookshelf": {
"podcasts": "Podsendinge", "podcasts": "Podsendinge",
@@ -793,12 +792,6 @@
"categories": "Kategorieë", "categories": "Kategorieë",
"series": "Reekse" "series": "Reekse"
}, },
"booklore": {
"libraries": "Libraries",
"books": "Books",
"reading": "Reading",
"finished": "Finished"
},
"jdownloader": { "jdownloader": {
"downloadCount": "Tou", "downloadCount": "Tou",
"downloadBytesRemaining": "Oorblywende", "downloadBytesRemaining": "Oorblywende",

View File

@@ -532,8 +532,7 @@
"child_bridges_status": "{{ok}}/{{total}}", "child_bridges_status": "{{ok}}/{{total}}",
"up": "Up", "up": "Up",
"pending": "Pending", "pending": "Pending",
"down": "Down", "down": "Down"
"ok": "Ok"
}, },
"healthchecks": { "healthchecks": {
"new": "جديد(ة)", "new": "جديد(ة)",
@@ -793,12 +792,6 @@
"categories": "Categories", "categories": "Categories",
"series": "Series" "series": "Series"
}, },
"booklore": {
"libraries": "Libraries",
"books": "Books",
"reading": "Reading",
"finished": "Finished"
},
"jdownloader": { "jdownloader": {
"downloadCount": "Queue", "downloadCount": "Queue",
"downloadBytesRemaining": "Remaining", "downloadBytesRemaining": "Remaining",

View File

@@ -63,7 +63,7 @@
"wlan_users": "WLAN Потребители", "wlan_users": "WLAN Потребители",
"up": "UP", "up": "UP",
"down": "DOWN", "down": "DOWN",
"wait": "Моля изчакайте", "wait": "Please wait",
"empty_data": "Неизвестен статус на подсистема" "empty_data": "Неизвестен статус на подсистема"
}, },
"docker": { "docker": {
@@ -83,7 +83,7 @@
"partial": "Частично" "partial": "Частично"
}, },
"ping": { "ping": {
"error": "Грешка", "error": "Error",
"ping": "Пинг", "ping": "Пинг",
"down": "Down", "down": "Down",
"up": "Up", "up": "Up",
@@ -91,11 +91,11 @@
}, },
"siteMonitor": { "siteMonitor": {
"http_status": "HTTP статус", "http_status": "HTTP статус",
"error": "Грешка", "error": "Error",
"response": "Отговор", "response": "Отговор",
"down": "Down", "down": "Down",
"up": "Up", "up": "Up",
"not_available": "Не е налично" "not_available": "Not Available"
}, },
"emby": { "emby": {
"playing": "Възпроизвежда", "playing": "Възпроизвежда",
@@ -111,7 +111,7 @@
"offline": "Offline", "offline": "Offline",
"offline_alt": "Offline", "offline_alt": "Offline",
"online": "Онлайн", "online": "Онлайн",
"total": "Общо", "total": "Total",
"unknown": "Unknown" "unknown": "Unknown"
}, },
"evcc": { "evcc": {
@@ -133,7 +133,7 @@
"unread": "Непрочетени" "unread": "Непрочетени"
}, },
"fritzbox": { "fritzbox": {
"connectionStatus": "Статус", "connectionStatus": "Status",
"connectionStatusUnconfigured": "Неконфигуриран", "connectionStatusUnconfigured": "Неконфигуриран",
"connectionStatusConnecting": "Свързване", "connectionStatusConnecting": "Свързване",
"connectionStatusAuthenticating": "Удостоверяване", "connectionStatusAuthenticating": "Удостоверяване",
@@ -141,7 +141,7 @@
"connectionStatusDisconnecting": "Прекъсване на връзката", "connectionStatusDisconnecting": "Прекъсване на връзката",
"connectionStatusDisconnected": "Не е свързан", "connectionStatusDisconnected": "Не е свързан",
"connectionStatusConnected": "Свързан", "connectionStatusConnected": "Свързан",
"uptime": "Време на работа", "uptime": "Uptime",
"maxDown": "Макс сваляне", "maxDown": "Макс сваляне",
"maxUp": "Макс качване", "maxUp": "Макс качване",
"down": "Down", "down": "Down",
@@ -170,8 +170,8 @@
"tautulli": { "tautulli": {
"playing": "Playing", "playing": "Playing",
"transcoding": "Transcoding", "transcoding": "Transcoding",
"bitrate": "Битрейт", "bitrate": "Bitrate",
"no_active": "Няма активни потоци", "no_active": "No Active Streams",
"plex_connection_error": "Провери връзка с Plex" "plex_connection_error": "Провери връзка с Plex"
}, },
"omada": { "omada": {
@@ -189,7 +189,7 @@
"plex": { "plex": {
"streams": "Активни Потоци", "streams": "Активни Потоци",
"albums": "Албуми", "albums": "Албуми",
"movies": "Филми", "movies": "Movies",
"tv": "Сериали" "tv": "Сериали"
}, },
"sabnzbd": { "sabnzbd": {
@@ -362,8 +362,8 @@
}, },
"trilium": { "trilium": {
"version": "Version", "version": "Version",
"notesCount": "Бележки", "notesCount": "Notes",
"dbSize": "Размер на базата данни", "dbSize": "Database Size",
"unknown": "Unknown" "unknown": "Unknown"
}, },
"navidrome": { "navidrome": {
@@ -373,7 +373,7 @@
"npm": { "npm": {
"enabled": "Активирано", "enabled": "Активирано",
"disabled": "Деактивирано", "disabled": "Деактивирано",
"total": "Общо" "total": "Total"
}, },
"coinmarketcap": { "coinmarketcap": {
"configure": "Настрой за следене една или повече крипто валути", "configure": "Настрой за следене една или повече крипто валути",
@@ -384,7 +384,7 @@
}, },
"gotify": { "gotify": {
"apps": "Приложения", "apps": "Приложения",
"clients": "Клиенти", "clients": "Clients",
"messages": "Съобщения" "messages": "Съобщения"
}, },
"prowlarr": { "prowlarr": {
@@ -405,7 +405,7 @@
"transferRate": "Rate" "transferRate": "Rate"
}, },
"mastodon": { "mastodon": {
"user_count": "Потребители", "user_count": "Users",
"status_count": "Posts", "status_count": "Posts",
"domain_count": "Domains" "domain_count": "Domains"
}, },
@@ -416,17 +416,17 @@
}, },
"minecraft": { "minecraft": {
"players": "Играчи", "players": "Играчи",
"version": "Версия", "version": "Version",
"status": "Статус", "status": "Status",
"up": "Онлайн", "up": "Online",
"down": "Офлайн" "down": "Offline"
}, },
"miniflux": { "miniflux": {
"read": "Read", "read": "Read",
"unread": "Unread" "unread": "Unread"
}, },
"authentik": { "authentik": {
"users": "Потребители", "users": "Users",
"loginsLast24H": "Logins (24h)", "loginsLast24H": "Logins (24h)",
"failedLoginsLast24H": "Failed Logins (24h)" "failedLoginsLast24H": "Failed Logins (24h)"
}, },
@@ -532,8 +532,7 @@
"child_bridges_status": "{{ok}}/{{total}}", "child_bridges_status": "{{ok}}/{{total}}",
"up": "Up", "up": "Up",
"pending": "Pending", "pending": "Pending",
"down": "Down", "down": "Down"
"ok": "Ok"
}, },
"healthchecks": { "healthchecks": {
"new": "Нови", "new": "Нови",
@@ -793,12 +792,6 @@
"categories": "Categories", "categories": "Categories",
"series": "Series" "series": "Series"
}, },
"booklore": {
"libraries": "Libraries",
"books": "Books",
"reading": "Reading",
"finished": "Finished"
},
"jdownloader": { "jdownloader": {
"downloadCount": "Queue", "downloadCount": "Queue",
"downloadBytesRemaining": "Remaining", "downloadBytesRemaining": "Remaining",

View File

@@ -532,8 +532,7 @@
"child_bridges_status": "{{ok}}/{{total}}", "child_bridges_status": "{{ok}}/{{total}}",
"up": "Up", "up": "Up",
"pending": "Pending", "pending": "Pending",
"down": "Down", "down": "Down"
"ok": "Ok"
}, },
"healthchecks": { "healthchecks": {
"new": "Nou", "new": "Nou",
@@ -793,12 +792,6 @@
"categories": "Categories", "categories": "Categories",
"series": "Series" "series": "Series"
}, },
"booklore": {
"libraries": "Libraries",
"books": "Books",
"reading": "Reading",
"finished": "Finished"
},
"jdownloader": { "jdownloader": {
"downloadCount": "Queue", "downloadCount": "Queue",
"downloadBytesRemaining": "Remaining", "downloadBytesRemaining": "Remaining",

View File

@@ -532,8 +532,7 @@
"child_bridges_status": "{{ok}}/{{total}}", "child_bridges_status": "{{ok}}/{{total}}",
"up": "Up", "up": "Up",
"pending": "Pending", "pending": "Pending",
"down": "Down", "down": "Down"
"ok": "Ok"
}, },
"healthchecks": { "healthchecks": {
"new": "Nové", "new": "Nové",
@@ -793,12 +792,6 @@
"categories": "Categories", "categories": "Categories",
"series": "Series" "series": "Series"
}, },
"booklore": {
"libraries": "Libraries",
"books": "Books",
"reading": "Reading",
"finished": "Finished"
},
"jdownloader": { "jdownloader": {
"downloadCount": "Queue", "downloadCount": "Queue",
"downloadBytesRemaining": "Remaining", "downloadBytesRemaining": "Remaining",

View File

@@ -532,8 +532,7 @@
"child_bridges_status": "{{ok}}/{{total}}", "child_bridges_status": "{{ok}}/{{total}}",
"up": "Up", "up": "Up",
"pending": "Pending", "pending": "Pending",
"down": "Down", "down": "Down"
"ok": "Ok"
}, },
"healthchecks": { "healthchecks": {
"new": "Ny", "new": "Ny",
@@ -793,12 +792,6 @@
"categories": "Categories", "categories": "Categories",
"series": "Series" "series": "Series"
}, },
"booklore": {
"libraries": "Libraries",
"books": "Books",
"reading": "Reading",
"finished": "Finished"
},
"jdownloader": { "jdownloader": {
"downloadCount": "Queue", "downloadCount": "Queue",
"downloadBytesRemaining": "Remaining", "downloadBytesRemaining": "Remaining",

View File

@@ -45,9 +45,9 @@
"free": "Frei", "free": "Frei",
"used": "In Benutzung", "used": "In Benutzung",
"load": "Last", "load": "Last",
"temp": "Temp", "temp": "TEMP",
"max": "Max", "max": "Max",
"uptime": "Betriebszeit" "uptime": "BETRIEBSZEIT"
}, },
"unifi": { "unifi": {
"users": "Benutzer", "users": "Benutzer",
@@ -532,8 +532,7 @@
"child_bridges_status": "{{ok}}/{{total}}", "child_bridges_status": "{{ok}}/{{total}}",
"up": "Online", "up": "Online",
"pending": "Wartend", "pending": "Wartend",
"down": "Offline", "down": "Offline"
"ok": "Ok"
}, },
"healthchecks": { "healthchecks": {
"new": "Neu", "new": "Neu",
@@ -603,7 +602,7 @@
"pangolin": { "pangolin": {
"orgs": "Orgs", "orgs": "Orgs",
"sites": "Sites", "sites": "Sites",
"resources": "Ressourcen", "resources": "Resources",
"targets": "Targets", "targets": "Targets",
"traffic": "Traffic", "traffic": "Traffic",
"in": "In", "in": "In",
@@ -793,12 +792,6 @@
"categories": "Kategorien", "categories": "Kategorien",
"series": "Serien" "series": "Serien"
}, },
"booklore": {
"libraries": "Libraries",
"books": "Books",
"reading": "Reading",
"finished": "Finished"
},
"jdownloader": { "jdownloader": {
"downloadCount": "Warteschlange", "downloadCount": "Warteschlange",
"downloadBytesRemaining": "Verbleibend", "downloadBytesRemaining": "Verbleibend",

View File

@@ -532,8 +532,7 @@
"child_bridges_status": "{{ok}}/{{total}}", "child_bridges_status": "{{ok}}/{{total}}",
"up": "Up", "up": "Up",
"pending": "Pending", "pending": "Pending",
"down": "Down", "down": "Down"
"ok": "Ok"
}, },
"healthchecks": { "healthchecks": {
"new": "New", "new": "New",
@@ -793,12 +792,6 @@
"categories": "Categories", "categories": "Categories",
"series": "Series" "series": "Series"
}, },
"booklore": {
"libraries": "Libraries",
"books": "Books",
"reading": "Reading",
"finished": "Finished"
},
"jdownloader": { "jdownloader": {
"downloadCount": "Queue", "downloadCount": "Queue",
"downloadBytesRemaining": "Remaining", "downloadBytesRemaining": "Remaining",

View File

@@ -532,8 +532,7 @@
"child_bridges_status": "{{ok}}/{{total}}", "child_bridges_status": "{{ok}}/{{total}}",
"up": "Up", "up": "Up",
"pending": "Pending", "pending": "Pending",
"down": "Down", "down": "Down"
"ok": "Ok"
}, },
"healthchecks": { "healthchecks": {
"new": "New", "new": "New",
@@ -793,12 +792,6 @@
"categories": "Categories", "categories": "Categories",
"series": "Series" "series": "Series"
}, },
"booklore": {
"libraries": "Libraries",
"books": "Books",
"reading": "Reading",
"finished": "Finished"
},
"jdownloader": { "jdownloader": {
"downloadCount": "Queue", "downloadCount": "Queue",
"downloadBytesRemaining": "Remaining", "downloadBytesRemaining": "Remaining",

View File

@@ -532,8 +532,7 @@
"child_bridges_status": "{{ok}}/{{total}}", "child_bridges_status": "{{ok}}/{{total}}",
"up": "Up", "up": "Up",
"pending": "Pending", "pending": "Pending",
"down": "Down", "down": "Down"
"ok": "Ok"
}, },
"healthchecks": { "healthchecks": {
"new": "New", "new": "New",
@@ -793,12 +792,6 @@
"categories": "Categories", "categories": "Categories",
"series": "Series" "series": "Series"
}, },
"booklore": {
"libraries": "Libraries",
"books": "Books",
"reading": "Reading",
"finished": "Finished"
},
"jdownloader": { "jdownloader": {
"downloadCount": "Queue", "downloadCount": "Queue",
"downloadBytesRemaining": "Remaining", "downloadBytesRemaining": "Remaining",

View File

@@ -532,8 +532,7 @@
"child_bridges_status": "{{ok}}/{{total}}", "child_bridges_status": "{{ok}}/{{total}}",
"up": "Activo", "up": "Activo",
"pending": "Pendiente", "pending": "Pendiente",
"down": "Inactivo", "down": "Inactivo"
"ok": "Ok"
}, },
"healthchecks": { "healthchecks": {
"new": "Nuevo", "new": "Nuevo",
@@ -602,12 +601,12 @@
}, },
"pangolin": { "pangolin": {
"orgs": "Orgs", "orgs": "Orgs",
"sites": "Sitios", "sites": "Sites",
"resources": "Recursos", "resources": "Resources",
"targets": "Destinos", "targets": "Targets",
"traffic": "Tráfico", "traffic": "Traffic",
"in": "Entrante", "in": "In",
"out": "Saliente" "out": "Out"
}, },
"peanut": { "peanut": {
"battery_charge": "Carga de la batería", "battery_charge": "Carga de la batería",
@@ -770,7 +769,7 @@
"gross_percent_today": "Hoy", "gross_percent_today": "Hoy",
"gross_percent_1y": "Un año", "gross_percent_1y": "Un año",
"gross_percent_max": "Todo el tiempo", "gross_percent_max": "Todo el tiempo",
"net_worth": "Patrimonio neto" "net_worth": "Net Worth"
}, },
"audiobookshelf": { "audiobookshelf": {
"podcasts": "Podcasts", "podcasts": "Podcasts",
@@ -793,12 +792,6 @@
"categories": "Categorías", "categories": "Categorías",
"series": "Series" "series": "Series"
}, },
"booklore": {
"libraries": "Libraries",
"books": "Books",
"reading": "Reading",
"finished": "Finished"
},
"jdownloader": { "jdownloader": {
"downloadCount": "En cola", "downloadCount": "En cola",
"downloadBytesRemaining": "Restante", "downloadBytesRemaining": "Restante",

View File

@@ -532,8 +532,7 @@
"child_bridges_status": "{{ok}}/{{total}}", "child_bridges_status": "{{ok}}/{{total}}",
"up": "Up", "up": "Up",
"pending": "Pending", "pending": "Pending",
"down": "Down", "down": "Down"
"ok": "Ok"
}, },
"healthchecks": { "healthchecks": {
"new": "New", "new": "New",
@@ -793,12 +792,6 @@
"categories": "Categories", "categories": "Categories",
"series": "Series" "series": "Series"
}, },
"booklore": {
"libraries": "Libraries",
"books": "Books",
"reading": "Reading",
"finished": "Finished"
},
"jdownloader": { "jdownloader": {
"downloadCount": "Queue", "downloadCount": "Queue",
"downloadBytesRemaining": "Remaining", "downloadBytesRemaining": "Remaining",

View File

@@ -532,8 +532,7 @@
"child_bridges_status": "{{ok}}/{{total}}", "child_bridges_status": "{{ok}}/{{total}}",
"up": "Up", "up": "Up",
"pending": "Pending", "pending": "Pending",
"down": "Down", "down": "Down"
"ok": "Ok"
}, },
"healthchecks": { "healthchecks": {
"new": "New", "new": "New",
@@ -793,12 +792,6 @@
"categories": "Categories", "categories": "Categories",
"series": "Series" "series": "Series"
}, },
"booklore": {
"libraries": "Libraries",
"books": "Books",
"reading": "Reading",
"finished": "Finished"
},
"jdownloader": { "jdownloader": {
"downloadCount": "Queue", "downloadCount": "Queue",
"downloadBytesRemaining": "Remaining", "downloadBytesRemaining": "Remaining",

View File

@@ -532,8 +532,7 @@
"child_bridges_status": "{{ok}}/{{total}}", "child_bridges_status": "{{ok}}/{{total}}",
"up": "En ligne", "up": "En ligne",
"pending": "En attente", "pending": "En attente",
"down": "Hors ligne", "down": "Hors ligne"
"ok": "Ok"
}, },
"healthchecks": { "healthchecks": {
"new": "Nouveau", "new": "Nouveau",
@@ -793,12 +792,6 @@
"categories": "Catégories", "categories": "Catégories",
"series": "Séries" "series": "Séries"
}, },
"booklore": {
"libraries": "Libraries",
"books": "Books",
"reading": "Reading",
"finished": "Finished"
},
"jdownloader": { "jdownloader": {
"downloadCount": "File d'attente", "downloadCount": "File d'attente",
"downloadBytesRemaining": "Restant", "downloadBytesRemaining": "Restant",

View File

@@ -532,8 +532,7 @@
"child_bridges_status": "{{ok}}/{{total}}", "child_bridges_status": "{{ok}}/{{total}}",
"up": "למעלה", "up": "למעלה",
"pending": "ממתין", "pending": "ממתין",
"down": "למטה", "down": "למטה"
"ok": "Ok"
}, },
"healthchecks": { "healthchecks": {
"new": "חדש", "new": "חדש",
@@ -793,12 +792,6 @@
"categories": "קטגוריות", "categories": "קטגוריות",
"series": "סדרות" "series": "סדרות"
}, },
"booklore": {
"libraries": "Libraries",
"books": "Books",
"reading": "Reading",
"finished": "Finished"
},
"jdownloader": { "jdownloader": {
"downloadCount": "תור", "downloadCount": "תור",
"downloadBytesRemaining": "נותר", "downloadBytesRemaining": "נותר",

View File

@@ -532,8 +532,7 @@
"child_bridges_status": "{{ok}}/{{total}}", "child_bridges_status": "{{ok}}/{{total}}",
"up": "Up", "up": "Up",
"pending": "Pending", "pending": "Pending",
"down": "Down", "down": "Down"
"ok": "Ok"
}, },
"healthchecks": { "healthchecks": {
"new": "New", "new": "New",
@@ -793,12 +792,6 @@
"categories": "Categories", "categories": "Categories",
"series": "Series" "series": "Series"
}, },
"booklore": {
"libraries": "Libraries",
"books": "Books",
"reading": "Reading",
"finished": "Finished"
},
"jdownloader": { "jdownloader": {
"downloadCount": "Queue", "downloadCount": "Queue",
"downloadBytesRemaining": "Remaining", "downloadBytesRemaining": "Remaining",

View File

@@ -532,8 +532,7 @@
"child_bridges_status": "{{ok}}/{{total}}", "child_bridges_status": "{{ok}}/{{total}}",
"up": "Aktivno", "up": "Aktivno",
"pending": "U tijeku", "pending": "U tijeku",
"down": "Neaktivno", "down": "Neaktivno"
"ok": "Ok"
}, },
"healthchecks": { "healthchecks": {
"new": "Novo", "new": "Novo",
@@ -793,12 +792,6 @@
"categories": "Kategorije", "categories": "Kategorije",
"series": "Serije" "series": "Serije"
}, },
"booklore": {
"libraries": "Libraries",
"books": "Books",
"reading": "Reading",
"finished": "Finished"
},
"jdownloader": { "jdownloader": {
"downloadCount": "Red čekanja", "downloadCount": "Red čekanja",
"downloadBytesRemaining": "Preostalo", "downloadBytesRemaining": "Preostalo",

View File

@@ -532,8 +532,7 @@
"child_bridges_status": "{{ok}}/{{total}}", "child_bridges_status": "{{ok}}/{{total}}",
"up": "Fut", "up": "Fut",
"pending": "Függőben lévő", "pending": "Függőben lévő",
"down": "Leállt", "down": "Leállt"
"ok": "Ok"
}, },
"healthchecks": { "healthchecks": {
"new": "Új", "new": "Új",
@@ -793,12 +792,6 @@
"categories": "Categories", "categories": "Categories",
"series": "Series" "series": "Series"
}, },
"booklore": {
"libraries": "Libraries",
"books": "Books",
"reading": "Reading",
"finished": "Finished"
},
"jdownloader": { "jdownloader": {
"downloadCount": "Queue", "downloadCount": "Queue",
"downloadBytesRemaining": "Remaining", "downloadBytesRemaining": "Remaining",

View File

@@ -532,8 +532,7 @@
"child_bridges_status": "{{ok}}/{{total}}", "child_bridges_status": "{{ok}}/{{total}}",
"up": "Up", "up": "Up",
"pending": "Pending", "pending": "Pending",
"down": "Down", "down": "Down"
"ok": "Ok"
}, },
"healthchecks": { "healthchecks": {
"new": "Baru", "new": "Baru",
@@ -793,12 +792,6 @@
"categories": "Categories", "categories": "Categories",
"series": "Series" "series": "Series"
}, },
"booklore": {
"libraries": "Libraries",
"books": "Books",
"reading": "Reading",
"finished": "Finished"
},
"jdownloader": { "jdownloader": {
"downloadCount": "Queue", "downloadCount": "Queue",
"downloadBytesRemaining": "Remaining", "downloadBytesRemaining": "Remaining",

View File

@@ -532,8 +532,7 @@
"child_bridges_status": "{{ok}}/{{total}}", "child_bridges_status": "{{ok}}/{{total}}",
"up": "Up", "up": "Up",
"pending": "Pending", "pending": "Pending",
"down": "Down", "down": "Down"
"ok": "Ok"
}, },
"healthchecks": { "healthchecks": {
"new": "Nuovo", "new": "Nuovo",
@@ -793,12 +792,6 @@
"categories": "Categories", "categories": "Categories",
"series": "Series" "series": "Series"
}, },
"booklore": {
"libraries": "Libraries",
"books": "Books",
"reading": "Reading",
"finished": "Finished"
},
"jdownloader": { "jdownloader": {
"downloadCount": "Queue", "downloadCount": "Queue",
"downloadBytesRemaining": "Remaining", "downloadBytesRemaining": "Remaining",

View File

@@ -532,8 +532,7 @@
"child_bridges_status": "{{ok}}/{{total}}", "child_bridges_status": "{{ok}}/{{total}}",
"up": "Up", "up": "Up",
"pending": "Pending", "pending": "Pending",
"down": "Down", "down": "Down"
"ok": "Ok"
}, },
"healthchecks": { "healthchecks": {
"new": "新着", "new": "新着",
@@ -793,12 +792,6 @@
"categories": "Categories", "categories": "Categories",
"series": "Series" "series": "Series"
}, },
"booklore": {
"libraries": "Libraries",
"books": "Books",
"reading": "Reading",
"finished": "Finished"
},
"jdownloader": { "jdownloader": {
"downloadCount": "Queue", "downloadCount": "Queue",
"downloadBytesRemaining": "Remaining", "downloadBytesRemaining": "Remaining",

View File

@@ -532,8 +532,7 @@
"child_bridges_status": "{{ok}}/{{total}}", "child_bridges_status": "{{ok}}/{{total}}",
"up": "업", "up": "업",
"pending": "대기 중", "pending": "대기 중",
"down": "다운", "down": "다운"
"ok": "Ok"
}, },
"healthchecks": { "healthchecks": {
"new": "신규", "new": "신규",
@@ -793,12 +792,6 @@
"categories": "카테고리", "categories": "카테고리",
"series": "시리즈" "series": "시리즈"
}, },
"booklore": {
"libraries": "Libraries",
"books": "Books",
"reading": "Reading",
"finished": "Finished"
},
"jdownloader": { "jdownloader": {
"downloadCount": "대기열", "downloadCount": "대기열",
"downloadBytesRemaining": "남음", "downloadBytesRemaining": "남음",

View File

@@ -532,8 +532,7 @@
"child_bridges_status": "{{ok}}/{{total}}", "child_bridges_status": "{{ok}}/{{total}}",
"up": "Up", "up": "Up",
"pending": "Pending", "pending": "Pending",
"down": "Down", "down": "Down"
"ok": "Ok"
}, },
"healthchecks": { "healthchecks": {
"new": "New", "new": "New",
@@ -793,12 +792,6 @@
"categories": "Categories", "categories": "Categories",
"series": "Series" "series": "Series"
}, },
"booklore": {
"libraries": "Libraries",
"books": "Books",
"reading": "Reading",
"finished": "Finished"
},
"jdownloader": { "jdownloader": {
"downloadCount": "Queue", "downloadCount": "Queue",
"downloadBytesRemaining": "Remaining", "downloadBytesRemaining": "Remaining",

View File

@@ -532,8 +532,7 @@
"child_bridges_status": "{{ok}}/{{total}}", "child_bridges_status": "{{ok}}/{{total}}",
"up": "Up", "up": "Up",
"pending": "Pending", "pending": "Pending",
"down": "Down", "down": "Down"
"ok": "Ok"
}, },
"healthchecks": { "healthchecks": {
"new": "Baharu", "new": "Baharu",
@@ -793,12 +792,6 @@
"categories": "Categories", "categories": "Categories",
"series": "Series" "series": "Series"
}, },
"booklore": {
"libraries": "Libraries",
"books": "Books",
"reading": "Reading",
"finished": "Finished"
},
"jdownloader": { "jdownloader": {
"downloadCount": "Queue", "downloadCount": "Queue",
"downloadBytesRemaining": "Remaining", "downloadBytesRemaining": "Remaining",

View File

@@ -532,8 +532,7 @@
"child_bridges_status": "{{ok}}/{{total}}", "child_bridges_status": "{{ok}}/{{total}}",
"up": "Online", "up": "Online",
"pending": "In afwachting", "pending": "In afwachting",
"down": "Offline", "down": "Offline"
"ok": "Ok"
}, },
"healthchecks": { "healthchecks": {
"new": "Nieuw", "new": "Nieuw",
@@ -793,12 +792,6 @@
"categories": "Categorieën", "categories": "Categorieën",
"series": "Series" "series": "Series"
}, },
"booklore": {
"libraries": "Libraries",
"books": "Books",
"reading": "Reading",
"finished": "Finished"
},
"jdownloader": { "jdownloader": {
"downloadCount": "Wachtrij", "downloadCount": "Wachtrij",
"downloadBytesRemaining": "Resterend", "downloadBytesRemaining": "Resterend",

View File

@@ -532,8 +532,7 @@
"child_bridges_status": "{{ok}}/{{total}}", "child_bridges_status": "{{ok}}/{{total}}",
"up": "Up", "up": "Up",
"pending": "Pending", "pending": "Pending",
"down": "Down", "down": "Down"
"ok": "Ok"
}, },
"healthchecks": { "healthchecks": {
"new": "Ny", "new": "Ny",
@@ -793,12 +792,6 @@
"categories": "Categories", "categories": "Categories",
"series": "Series" "series": "Series"
}, },
"booklore": {
"libraries": "Libraries",
"books": "Books",
"reading": "Reading",
"finished": "Finished"
},
"jdownloader": { "jdownloader": {
"downloadCount": "Queue", "downloadCount": "Queue",
"downloadBytesRemaining": "Remaining", "downloadBytesRemaining": "Remaining",

View File

@@ -61,7 +61,7 @@
"wlan_devices": "Urządzenia WLAN", "wlan_devices": "Urządzenia WLAN",
"lan_users": "Użytkownicy LAN", "lan_users": "Użytkownicy LAN",
"wlan_users": "Użytkownicy WLAN", "wlan_users": "Użytkownicy WLAN",
"up": "DZIAŁA", "up": "UP",
"down": "Pobieranie", "down": "Pobieranie",
"wait": "Proszę czekać", "wait": "Proszę czekać",
"empty_data": "Status podsystemu nieznany" "empty_data": "Status podsystemu nieznany"
@@ -69,7 +69,7 @@
"docker": { "docker": {
"rx": "Rx", "rx": "Rx",
"tx": "Tx", "tx": "Tx",
"mem": "PAM", "mem": "MEM",
"cpu": "Procesor", "cpu": "Procesor",
"running": "Działa", "running": "Działa",
"offline": "Nieosiągalny", "offline": "Nieosiągalny",
@@ -93,8 +93,8 @@
"http_status": "Status HTTP", "http_status": "Status HTTP",
"error": "Błąd", "error": "Błąd",
"response": "Odpowiedź", "response": "Odpowiedź",
"down": "Nie działa", "down": "Down",
"up": "Działa", "up": "Up",
"not_available": "Niedostępny" "not_available": "Niedostępny"
}, },
"emby": { "emby": {
@@ -111,8 +111,8 @@
"offline": "Offline", "offline": "Offline",
"offline_alt": "Offline", "offline_alt": "Offline",
"online": "Dostępny", "online": "Dostępny",
"total": "Razem", "total": "Total",
"unknown": "Nieznany" "unknown": "Unknown"
}, },
"evcc": { "evcc": {
"pv_power": "Produkcja", "pv_power": "Produkcja",
@@ -141,11 +141,11 @@
"connectionStatusDisconnecting": "Rozłączanie", "connectionStatusDisconnecting": "Rozłączanie",
"connectionStatusDisconnected": "Rozłączono", "connectionStatusDisconnected": "Rozłączono",
"connectionStatusConnected": "Połączono", "connectionStatusConnected": "Połączono",
"uptime": "Czas działania", "uptime": "Uptime",
"maxDown": "Maks. Pobieranie", "maxDown": "Maks. Pobieranie",
"maxUp": "Maks. Wysyłanie", "maxUp": "Maks. Wysyłanie",
"down": "Nie działa", "down": "Down",
"up": "Działa", "up": "Up",
"received": "Odebrane", "received": "Odebrane",
"sent": "Wysłane", "sent": "Wysłane",
"externalIPAddress": "Pub. IP", "externalIPAddress": "Pub. IP",
@@ -168,10 +168,10 @@
"passes": "Przebiegi" "passes": "Przebiegi"
}, },
"tautulli": { "tautulli": {
"playing": "Odtwarza", "playing": "Playing",
"transcoding": "Transkoduje", "transcoding": "Transcoding",
"bitrate": "Bitrate", "bitrate": "Bitrate",
"no_active": "Brak aktywnych strumieni", "no_active": "No Active Streams",
"plex_connection_error": "Sprawdź połączenie z Plex" "plex_connection_error": "Sprawdź połączenie z Plex"
}, },
"omada": { "omada": {
@@ -193,24 +193,24 @@
"tv": "Seriale" "tv": "Seriale"
}, },
"sabnzbd": { "sabnzbd": {
"rate": "Szybkość", "rate": "Rate",
"queue": "Kolejka", "queue": "Kolejka",
"timeleft": "Pozostało" "timeleft": "Pozostało"
}, },
"rutorrent": { "rutorrent": {
"active": "Aktywny", "active": "Aktywny",
"upload": "Wysyłanie", "upload": "Upload",
"download": "Pobieranie" "download": "Pobieranie"
}, },
"transmission": { "transmission": {
"download": "Pobieranie", "download": "Pobieranie",
"upload": "Wysyłanie", "upload": "Upload",
"leech": "Leech", "leech": "Leech",
"seed": "Seed" "seed": "Seed"
}, },
"qbittorrent": { "qbittorrent": {
"download": "Pobieranie", "download": "Download",
"upload": "Wysyłanie", "upload": "Upload",
"leech": "Leech", "leech": "Leech",
"seed": "Seed" "seed": "Seed"
}, },
@@ -223,8 +223,8 @@
"invalid": "Nieprawidłowy" "invalid": "Nieprawidłowy"
}, },
"deluge": { "deluge": {
"download": "Pobieranie", "download": "Download",
"upload": "Wysyłanie", "upload": "Upload",
"leech": "Leech", "leech": "Leech",
"seed": "Seed" "seed": "Seed"
}, },
@@ -233,8 +233,8 @@
"cachemissbytes": "Straty cache'u" "cachemissbytes": "Straty cache'u"
}, },
"downloadstation": { "downloadstation": {
"download": "Pobieranie", "download": "Download",
"upload": "Wysyłanie", "upload": "Upload",
"leech": "Leech", "leech": "Leech",
"seed": "Seed" "seed": "Seed"
}, },
@@ -251,16 +251,16 @@
"queued": "W kolejce", "queued": "W kolejce",
"movies": "Filmy", "movies": "Filmy",
"queue": "Kolejka", "queue": "Kolejka",
"unknown": "Nieznane" "unknown": "Unknown"
}, },
"lidarr": { "lidarr": {
"wanted": "Poszukiwane", "wanted": "Wanted",
"queued": "W kolejce", "queued": "Queued",
"artists": "Artyści" "artists": "Artyści"
}, },
"readarr": { "readarr": {
"wanted": "Poszukiwane", "wanted": "Wanted",
"queued": "W kolejce", "queued": "Queued",
"books": "Książki" "books": "Książki"
}, },
"bazarr": { "bazarr": {
@@ -276,7 +276,7 @@
"pending": "Oczekujące", "pending": "Oczekujące",
"approved": "Zaakceptowane", "approved": "Zaakceptowane",
"available": "Dostępne", "available": "Dostępne",
"issues": "Otwarte zgłoszenia" "issues": "Open Issues"
}, },
"overseerr": { "overseerr": {
"pending": "Oczekujące", "pending": "Oczekujące",
@@ -285,8 +285,8 @@
"available": "Dostępne" "available": "Dostępne"
}, },
"netalertx": { "netalertx": {
"total": "Razem", "total": "Total",
"connected": "Połączono", "connected": "Connected",
"new_devices": "Nowe urządzenia", "new_devices": "Nowe urządzenia",
"down_alerts": "Alerty niedostępności" "down_alerts": "Alerty niedostępności"
}, },
@@ -303,20 +303,20 @@
"latency": "Opóźnienia" "latency": "Opóźnienia"
}, },
"speedtest": { "speedtest": {
"upload": "Wysyłanie", "upload": "Upload",
"download": "Pobieranie", "download": "Download",
"ping": "Ping" "ping": "Ping"
}, },
"portainer": { "portainer": {
"running": "Działa", "running": "Running",
"stopped": "Zatrzymane", "stopped": "Zatrzymane",
"total": "Razem" "total": "Total"
}, },
"suwayomi": { "suwayomi": {
"download": "Pobrano", "download": "Pobrano",
"nondownload": "Niepobrane", "nondownload": "Niepobrane",
"read": "Przeczytane", "read": "Read",
"unread": "Nieprzeczytane", "unread": "Unread",
"downloadedread": "Pobrane i przeczytane", "downloadedread": "Pobrane i przeczytane",
"downloadedunread": "Pobrane i nieprzeczytane", "downloadedunread": "Pobrane i nieprzeczytane",
"nondownloadedread": "Niepobrane i przeczytane", "nondownloadedread": "Niepobrane i przeczytane",
@@ -337,7 +337,7 @@
"ago": "{{value}} temu" "ago": "{{value}} temu"
}, },
"technitium": { "technitium": {
"totalQueries": "Zapytania", "totalQueries": "Queries",
"totalNoError": "Sukces", "totalNoError": "Sukces",
"totalServerFailure": "Porażki", "totalServerFailure": "Porażki",
"totalNxDomain": "Domeny NX", "totalNxDomain": "Domeny NX",
@@ -345,12 +345,12 @@
"totalAuthoritative": "Autorytatywne", "totalAuthoritative": "Autorytatywne",
"totalRecursive": "Rekursywne", "totalRecursive": "Rekursywne",
"totalCached": "Zbuforowane", "totalCached": "Zbuforowane",
"totalBlocked": "Zablokowane", "totalBlocked": "Blocked",
"totalDropped": "Upuszczone", "totalDropped": "Upuszczone",
"totalClients": "Klienci" "totalClients": "Klienci"
}, },
"tdarr": { "tdarr": {
"queue": "W kolejce", "queue": "Queue",
"processed": "Przetworzone", "processed": "Przetworzone",
"errored": "Błędne", "errored": "Błędne",
"saved": "Zapisane" "saved": "Zapisane"
@@ -364,7 +364,7 @@
"version": "Wersja", "version": "Wersja",
"notesCount": "Notatki", "notesCount": "Notatki",
"dbSize": "Rozmiar bazy danych", "dbSize": "Rozmiar bazy danych",
"unknown": "Nieznane" "unknown": "Unknown"
}, },
"navidrome": { "navidrome": {
"nothing_streaming": "Brak aktywnych strumieni", "nothing_streaming": "Brak aktywnych strumieni",
@@ -373,7 +373,7 @@
"npm": { "npm": {
"enabled": "Włączone", "enabled": "Włączone",
"disabled": "Wyłączone", "disabled": "Wyłączone",
"total": "Razem" "total": "Total"
}, },
"coinmarketcap": { "coinmarketcap": {
"configure": "Wybierz jedną lub więcej kryptowalut do śledzenia", "configure": "Wybierz jedną lub więcej kryptowalut do śledzenia",
@@ -390,19 +390,19 @@
"prowlarr": { "prowlarr": {
"enableIndexers": "Indeksery", "enableIndexers": "Indeksery",
"numberOfGrabs": "Pochwycenia", "numberOfGrabs": "Pochwycenia",
"numberOfQueries": "Zapytania", "numberOfQueries": "Queries",
"numberOfFailGrabs": "Nieudane pochwycenia", "numberOfFailGrabs": "Nieudane pochwycenia",
"numberOfFailQueries": "Nieudane zapytania" "numberOfFailQueries": "Nieudane zapytania"
}, },
"jackett": { "jackett": {
"configured": "Skonfigurowane", "configured": "Skonfigurowane",
"errored": "Z błędami" "errored": "Errored"
}, },
"strelaysrv": { "strelaysrv": {
"numActiveSessions": "Sesje", "numActiveSessions": "Sesje",
"numConnections": "Połączenia", "numConnections": "Połączenia",
"dataRelayed": "Przekazane", "dataRelayed": "Przekazane",
"transferRate": "Szybkość" "transferRate": "Rate"
}, },
"mastodon": { "mastodon": {
"user_count": "Użytkownicy", "user_count": "Użytkownicy",
@@ -410,9 +410,9 @@
"domain_count": "Domeny" "domain_count": "Domeny"
}, },
"medusa": { "medusa": {
"wanted": "Poszukiwane", "wanted": "Wanted",
"queued": "W kolejce", "queued": "Queued",
"series": "Seriale" "series": "Series"
}, },
"minecraft": { "minecraft": {
"players": "Gracze", "players": "Gracze",
@@ -423,7 +423,7 @@
}, },
"miniflux": { "miniflux": {
"read": "Przeczytane", "read": "Przeczytane",
"unread": "Nieprzeczytane" "unread": "Unread"
}, },
"authentik": { "authentik": {
"users": "Użytkownicy", "users": "Użytkownicy",
@@ -443,14 +443,14 @@
"temp": "TEMP.", "temp": "TEMP.",
"_temp": "Temperatura", "_temp": "Temperatura",
"warn": "Ostrzeżenie", "warn": "Ostrzeżenie",
"uptime": "DZIAŁA", "uptime": "UP",
"total": "Razem", "total": "Total",
"free": "Wolne", "free": "Wolne",
"used": "Użyte", "used": "Used",
"days": "d", "days": "d",
"hours": "godz", "hours": "h",
"crit": "Krytyczyny", "crit": "Krytyczyny",
"read": "Odczyt", "read": "Read",
"write": "Zapis", "write": "Zapis",
"gpu": "GPU", "gpu": "GPU",
"mem": "Pamięć", "mem": "Pamięć",
@@ -530,16 +530,15 @@
"up_to_date": "Aktualny", "up_to_date": "Aktualny",
"child_bridges": "Mostki podrzędne", "child_bridges": "Mostki podrzędne",
"child_bridges_status": "{{ok}}/{{total}}", "child_bridges_status": "{{ok}}/{{total}}",
"up": "Działa", "up": "Up",
"pending": "Oczekujące", "pending": "Pending",
"down": "Nie działa", "down": "Down"
"ok": "Ok"
}, },
"healthchecks": { "healthchecks": {
"new": "Nowy", "new": "Nowy",
"up": "Działa", "up": "Up",
"grace": "W okresie karencji", "grace": "W okresie karencji",
"down": "Nie działa", "down": "Down",
"paused": "Wstrzymane", "paused": "Wstrzymane",
"status": "Status", "status": "Status",
"last_ping": "Ostatni ping", "last_ping": "Ostatni ping",
@@ -551,63 +550,63 @@
"containers_failed": "Niepowodzenie" "containers_failed": "Niepowodzenie"
}, },
"autobrr": { "autobrr": {
"approvedPushes": "Zaakceptowane", "approvedPushes": "Approved",
"rejectedPushes": "Odrzucone", "rejectedPushes": "Odrzucone",
"filters": "Filtry", "filters": "Filtry",
"indexers": "Indeksery" "indexers": "Indexers"
}, },
"tubearchivist": { "tubearchivist": {
"downloads": "W kolejce", "downloads": "Queue",
"videos": "Pliki wideo", "videos": "Pliki wideo",
"channels": "Kanały", "channels": "Kanały",
"playlists": "Playlisty" "playlists": "Playlisty"
}, },
"truenas": { "truenas": {
"load": "Obciążenie systemu", "load": "Obciążenie systemu",
"uptime": "Czas działania", "uptime": "Uptime",
"alerts": "Alerty" "alerts": "Alerts"
}, },
"pyload": { "pyload": {
"speed": "Prędkość", "speed": "Prędkość",
"active": "Aktywne", "active": "Active",
"queue": "W kolejce", "queue": "Queue",
"total": "Razem" "total": "Total"
}, },
"gluetun": { "gluetun": {
"public_ip": "Adres publiczny", "public_ip": "Adres publiczny",
"region": "Region", "region": "Region",
"country": "Państwo", "country": "Państwo",
"port_forwarded": "Port otwarty" "port_forwarded": "Port Forwarded"
}, },
"hdhomerun": { "hdhomerun": {
"channels": "Kanały", "channels": "Channels",
"hd": "HD", "hd": "HD",
"tunerCount": "Tunery", "tunerCount": "Tunery",
"channelNumber": "Kanał", "channelNumber": "Kanał",
"channelNetwork": "Sieć", "channelNetwork": "Sieć",
"signalStrength": "Siła sygnału", "signalStrength": "Siła sygnału",
"signalQuality": "Jakość", "signalQuality": "Jakość",
"symbolQuality": "Jakość", "symbolQuality": "Quality",
"networkRate": "Bitrate", "networkRate": "Bitrate",
"clientIP": "Klient" "clientIP": "Klient"
}, },
"scrutiny": { "scrutiny": {
"passed": "Powodzenie", "passed": "Powodzenie",
"failed": "Nieudane", "failed": "Failed",
"unknown": "Nieznane" "unknown": "Unknown"
}, },
"paperlessngx": { "paperlessngx": {
"inbox": "Skrzynka odbiorcza", "inbox": "Skrzynka odbiorcza",
"total": "Razem" "total": "Total"
}, },
"pangolin": { "pangolin": {
"orgs": "Organizacje", "orgs": "Orgs",
"sites": "Strony", "sites": "Sites",
"resources": "Zasoby", "resources": "Resources",
"targets": "Cele", "targets": "Targets",
"traffic": "Ruch", "traffic": "Traffic",
"in": "Do", "in": "In",
"out": "Z" "out": "Out"
}, },
"peanut": { "peanut": {
"battery_charge": "Stan baterii", "battery_charge": "Stan baterii",
@@ -618,18 +617,18 @@
"low_battery": "Niski poziom baterii" "low_battery": "Niski poziom baterii"
}, },
"nextdns": { "nextdns": {
"wait": "Proszę czekać", "wait": "Please Wait",
"no_devices": "Nie otrzymano danych urządzenia" "no_devices": "Nie otrzymano danych urządzenia"
}, },
"mikrotik": { "mikrotik": {
"cpuLoad": "Obciążenie procesora", "cpuLoad": "Obciążenie procesora",
"memoryUsed": "Zużyta pamięć", "memoryUsed": "Zużyta pamięć",
"uptime": "Czas działania", "uptime": "Uptime",
"numberOfLeases": "Dzierżawy" "numberOfLeases": "Dzierżawy"
}, },
"xteve": { "xteve": {
"streams_all": "Wszystkie strumienie", "streams_all": "Wszystkie strumienie",
"streams_active": "Aktywne strumienie", "streams_active": "Active Streams",
"streams_xepg": "Kanały XEPG" "streams_xepg": "Kanały XEPG"
}, },
"opendtu": { "opendtu": {
@@ -664,9 +663,9 @@
"load": "Śr. Obciążenie", "load": "Śr. Obciążenie",
"memory": "Użycie pamięci", "memory": "Użycie pamięci",
"wanStatus": "Status WAN", "wanStatus": "Status WAN",
"up": "Działa", "up": "Up",
"down": "Nie działa", "down": "Down",
"temp": "Temperatura", "temp": "Temp",
"disk": "Użycie dysku", "disk": "Użycie dysku",
"wanIP": "WAN IP" "wanIP": "WAN IP"
}, },
@@ -677,38 +676,38 @@
"memory_usage": "Pamięć" "memory_usage": "Pamięć"
}, },
"immich": { "immich": {
"users": "Użytkownicy", "users": "Users",
"photos": "Zdjęcia", "photos": "Zdjęcia",
"videos": "Filmy", "videos": "Videos",
"storage": "Pamięć" "storage": "Pamięć"
}, },
"uptimekuma": { "uptimekuma": {
"up": "Działające", "up": "Działające",
"down": "Niedziałające", "down": "Niedziałające",
"uptime": "Czas działania", "uptime": "Uptime",
"incident": "Incydent", "incident": "Incydent",
"m": "min" "m": "m"
}, },
"atsumeru": { "atsumeru": {
"series": "Serie", "series": "Series",
"archives": "Archiwa", "archives": "Archiwa",
"chapters": "Rozdziały", "chapters": "Rozdziały",
"categories": "Kategorie" "categories": "Kategorie"
}, },
"komga": { "komga": {
"libraries": "Biblioteki", "libraries": "Biblioteki",
"series": "Serie", "series": "Series",
"books": "Książki" "books": "Books"
}, },
"diskstation": { "diskstation": {
"days": "Dni", "days": "Days",
"uptime": "Czas działania", "uptime": "Uptime",
"volumeAvailable": "Dostępne" "volumeAvailable": "Available"
}, },
"mylar": { "mylar": {
"series": "Seriale", "series": "Series",
"issues": "Zgłoszenia", "issues": "Zgłoszenia",
"wanted": "Poszukiwane" "wanted": "Wanted"
}, },
"photoprism": { "photoprism": {
"albums": "Albumy", "albums": "Albumy",
@@ -717,9 +716,9 @@
"people": "Ludzie" "people": "Ludzie"
}, },
"fileflows": { "fileflows": {
"queue": "W kolejce", "queue": "Queue",
"processing": "Przetwarzane", "processing": "Processing",
"processed": "Przetworzone", "processed": "Processed",
"time": "Czas" "time": "Czas"
}, },
"firefly": { "firefly": {
@@ -745,7 +744,7 @@
"size": "Rozmiar", "size": "Rozmiar",
"lastrun": "Ostatnie uruchomienie", "lastrun": "Ostatnie uruchomienie",
"nextrun": "Następne uruchomienie", "nextrun": "Następne uruchomienie",
"failed": "Nieudane" "failed": "Failed"
}, },
"unmanic": { "unmanic": {
"active_workers": "Aktywni pracownicy", "active_workers": "Aktywni pracownicy",
@@ -762,15 +761,15 @@
"targets_total": "Wszystkich Celi" "targets_total": "Wszystkich Celi"
}, },
"gatus": { "gatus": {
"up": "Działające strony", "up": "Sites Up",
"down": "Niedziałające strony", "down": "Sites Down",
"uptime": "Czas działania" "uptime": "Uptime"
}, },
"ghostfolio": { "ghostfolio": {
"gross_percent_today": "Dzisiaj", "gross_percent_today": "Dzisiaj",
"gross_percent_1y": "Rok", "gross_percent_1y": "Rok",
"gross_percent_max": "Od początku", "gross_percent_max": "Od początku",
"net_worth": "Wartość netto" "net_worth": "Net Worth"
}, },
"audiobookshelf": { "audiobookshelf": {
"podcasts": "Podcasty", "podcasts": "Podcasty",
@@ -785,28 +784,22 @@
}, },
"whatsupdocker": { "whatsupdocker": {
"monitoring": "Monitoring", "monitoring": "Monitoring",
"updates": "Aktualizacje" "updates": "Updates"
}, },
"calibreweb": { "calibreweb": {
"books": "Książki", "books": "Książki",
"authors": "Autorzy", "authors": "Autorzy",
"categories": "Kategorie", "categories": "Kategorie",
"series": "Serie" "series": "Series"
},
"booklore": {
"libraries": "Libraries",
"books": "Books",
"reading": "Reading",
"finished": "Finished"
}, },
"jdownloader": { "jdownloader": {
"downloadCount": "W kolejce", "downloadCount": "Queue",
"downloadBytesRemaining": "Pozostało", "downloadBytesRemaining": "Remaining",
"downloadTotalBytes": "Rozmiar", "downloadTotalBytes": "Size",
"downloadSpeed": "Prędkość" "downloadSpeed": "Prędkość"
}, },
"kavita": { "kavita": {
"seriesCount": "Serie", "seriesCount": "Series",
"totalFiles": "Pliki" "totalFiles": "Pliki"
}, },
"azuredevops": { "azuredevops": {
@@ -820,7 +813,7 @@
"inProgress": "W trakcie", "inProgress": "W trakcie",
"totalPrs": "Łącznie PRs", "totalPrs": "Łącznie PRs",
"myPrs": "Moje PRs", "myPrs": "Moje PRs",
"approved": "Zaakceptowane" "approved": "Approved"
}, },
"gamedig": { "gamedig": {
"status": "Status", "status": "Status",
@@ -848,33 +841,33 @@
}, },
"openmediavault": { "openmediavault": {
"downloading": "Pobieranie", "downloading": "Pobieranie",
"total": "Razem", "total": "Total",
"running": "Działające", "running": "Running",
"stopped": "Zatrzymane", "stopped": "Stopped",
"passed": "Zaliczony", "passed": "Passed",
"failed": "Nieudany" "failed": "Failed"
}, },
"openwrt": { "openwrt": {
"uptime": "Czas działania", "uptime": "Uptime",
"cpuLoad": "Śr. obciążenie CPU (5m)", "cpuLoad": "Śr. obciążenie CPU (5m)",
"up": "Działa", "up": "Up",
"down": "Nie działa", "down": "Down",
"bytesTx": "Przesłane", "bytesTx": "Przesłane",
"bytesRx": "Odebrano" "bytesRx": "Received"
}, },
"uptimerobot": { "uptimerobot": {
"status": "Status", "status": "Status",
"uptime": "Czas działania", "uptime": "Uptime",
"lastDown": "Ostatni downtime", "lastDown": "Ostatni downtime",
"downDuration": "Długość downtime'u", "downDuration": "Długość downtime'u",
"sitesUp": "Działające strony", "sitesUp": "Sites Up",
"sitesDown": "Niedziałające strony", "sitesDown": "Sites Down",
"paused": "Zatrzymane", "paused": "Paused",
"notyetchecked": "Nie sprawdzono", "notyetchecked": "Nie sprawdzono",
"up": "Działa", "up": "Up",
"seemsdown": "Możliwe, że wyłączony", "seemsdown": "Możliwe, że wyłączony",
"down": "Nie działa", "down": "Down",
"unknown": "Nieznane" "unknown": "Unknown"
}, },
"calendar": { "calendar": {
"inCinemas": "W kinach", "inCinemas": "W kinach",
@@ -893,10 +886,10 @@
"totalfilesize": "Rozmiar całkowity" "totalfilesize": "Rozmiar całkowity"
}, },
"mailcow": { "mailcow": {
"domains": "Domeny", "domains": "Domains",
"mailboxes": "Skrzynki", "mailboxes": "Skrzynki",
"mails": "Poczta", "mails": "Poczta",
"storage": "Pamięć" "storage": "Storage"
}, },
"netdata": { "netdata": {
"warnings": "Ostrzeżenia", "warnings": "Ostrzeżenia",
@@ -905,12 +898,12 @@
"plantit": { "plantit": {
"events": "Wydarzenia", "events": "Wydarzenia",
"plants": "Rośliny", "plants": "Rośliny",
"photos": "Zdjęcia", "photos": "Photos",
"species": "Gatunki" "species": "Gatunki"
}, },
"gitea": { "gitea": {
"notifications": "Powiadomienia", "notifications": "Powiadomienia",
"issues": "Zgłoszenia", "issues": "Issues",
"pulls": "Żądania Pull", "pulls": "Żądania Pull",
"repositories": "Repozytoria" "repositories": "Repozytoria"
}, },
@@ -926,13 +919,13 @@
"galleries": "Galerie", "galleries": "Galerie",
"performers": "Artyści", "performers": "Artyści",
"studios": "Studia", "studios": "Studia",
"movies": "Filmy", "movies": "Movies",
"tags": "Tagi", "tags": "Tags",
"oCount": "O Licznik" "oCount": "O Licznik"
}, },
"tandoor": { "tandoor": {
"users": "Użytkownicy", "users": "Users",
"recipes": "Przepisy", "recipes": "Recipes",
"keywords": "Słowa kluczowe" "keywords": "Słowa kluczowe"
}, },
"homebox": { "homebox": {
@@ -940,18 +933,18 @@
"totalWithWarranty": "Z gwarancją", "totalWithWarranty": "Z gwarancją",
"locations": "Lokalizacje", "locations": "Lokalizacje",
"labels": "Etykiety", "labels": "Etykiety",
"users": "Użytkownicy", "users": "Users",
"totalValue": "Wartość całkowita" "totalValue": "Wartość całkowita"
}, },
"crowdsec": { "crowdsec": {
"alerts": "Alerty", "alerts": "Alerts",
"bans": "Bany" "bans": "Bany"
}, },
"wgeasy": { "wgeasy": {
"connected": "Połączonych", "connected": "Connected",
"enabled": "Włączone", "enabled": "Enabled",
"disabled": "Wyłączone", "disabled": "Disabled",
"total": "Razem" "total": "Total"
}, },
"swagdashboard": { "swagdashboard": {
"proxied": "Proxy", "proxied": "Proxy",
@@ -973,7 +966,7 @@
}, },
"frigate": { "frigate": {
"cameras": "Kamery", "cameras": "Kamery",
"uptime": "Czas działania", "uptime": "Uptime",
"version": "Wersja" "version": "Wersja"
}, },
"linkwarden": { "linkwarden": {
@@ -983,7 +976,7 @@
}, },
"zabbix": { "zabbix": {
"unclassified": "Niezaklasyfikowane", "unclassified": "Niezaklasyfikowane",
"information": "Informacja", "information": "Information",
"warning": "Ostrzeżenie", "warning": "Ostrzeżenie",
"average": "Średnia", "average": "Średnia",
"high": "Wysokie", "high": "Wysokie",
@@ -1014,14 +1007,14 @@
"beszel": { "beszel": {
"name": "Nazwa", "name": "Nazwa",
"systems": "Systemy", "systems": "Systemy",
"up": "Działa", "up": "Up",
"down": "Nie działa", "down": "Down",
"paused": "Wstrzymane", "paused": "Paused",
"pending": "Oczekujące", "pending": "Pending",
"status": "Status", "status": "Status",
"updated": "Zaktualizowane", "updated": "Updated",
"cpu": "Procesor", "cpu": "Procesor",
"memory": "PAM", "memory": "MEM",
"disk": "Dysk", "disk": "Dysk",
"network": "NET" "network": "NET"
}, },
@@ -1029,14 +1022,14 @@
"apps": "Aplikacje", "apps": "Aplikacje",
"synced": "Synchronizowane", "synced": "Synchronizowane",
"outOfSync": "Bez synchronizacji", "outOfSync": "Bez synchronizacji",
"healthy": "Zdrowe", "healthy": "Healthy",
"degraded": "Zdegradowane", "degraded": "Zdegradowane",
"progressing": "Postępujące", "progressing": "Postępujące",
"missing": "Brakujące", "missing": "Missing",
"suspended": "Zawieszone" "suspended": "Zawieszone"
}, },
"spoolman": { "spoolman": {
"loading": "Ładowanie" "loading": "Loading"
}, },
"gitlab": { "gitlab": {
"groups": "Grupy", "groups": "Grupy",
@@ -1046,9 +1039,9 @@
}, },
"apcups": { "apcups": {
"status": "Status", "status": "Status",
"load": "Obciążenie", "load": "Load",
"bcharge": "Naładowanie baterii", "bcharge": "Battery Charge",
"timeleft": "Pozostały czas" "timeleft": "Time Left"
}, },
"karakeep": { "karakeep": {
"bookmarks": "Zakładki", "bookmarks": "Zakładki",
@@ -1059,11 +1052,11 @@
"tags": "Tagi" "tags": "Tagi"
}, },
"slskd": { "slskd": {
"slskStatus": "Sieć", "slskStatus": "Network",
"connected": "Połączono", "connected": "Connected",
"disconnected": "Rozłączono", "disconnected": "Disconnected",
"updateStatus": "Aktualizacja", "updateStatus": "Aktualizacja",
"update_yes": "Dostępne", "update_yes": "Available",
"update_no": "Aktualny", "update_no": "Aktualny",
"downloads": "Pobieranie", "downloads": "Pobieranie",
"uploads": "Przesyłanie", "uploads": "Przesyłanie",
@@ -1076,65 +1069,65 @@
"other": "Inne" "other": "Inne"
}, },
"checkmk": { "checkmk": {
"serviceErrors": "Problem z usługą", "serviceErrors": "Service issues",
"hostErrors": "Problemy hosta" "hostErrors": "Host issues"
}, },
"komodo": { "komodo": {
"total": "Razem", "total": "Total",
"running": "Działające", "running": "Running",
"stopped": "Zatrzymane", "stopped": "Stopped",
"down": "Nie działa", "down": "Down",
"unhealthy": "Uszkodzony", "unhealthy": "Unhealthy",
"unknown": "Nieznane", "unknown": "Unknown",
"servers": "Serwery", "servers": "Serwery",
"stacks": "Stosy", "stacks": "Stacks",
"containers": "Kontenery" "containers": "Containers"
}, },
"filebrowser": { "filebrowser": {
"available": "Dostępne", "available": "Available",
"used": "Użyte", "used": "Used",
"total": "Razem" "total": "Total"
}, },
"wallos": { "wallos": {
"activeSubscriptions": "Subskrypcje", "activeSubscriptions": "Subscriptions",
"thisMonthlyCost": "Ten Miesiąc", "thisMonthlyCost": "This Month",
"nextMonthlyCost": "Następny miesiąc", "nextMonthlyCost": "Next Month",
"previousMonthlyCost": "Poprzedni miesiąc", "previousMonthlyCost": "Prev. Month",
"nextRenewingSubscription": "Następna płatność" "nextRenewingSubscription": "Next Payment"
}, },
"unraid": { "unraid": {
"STARTED": "Rozpoczęte", "STARTED": "Started",
"STOPPED": "Zatrzymane", "STOPPED": "Stopped",
"NEW_ARRAY": "Nowa macierz", "NEW_ARRAY": "New Array",
"RECON_DISK": "Odbudowa dysku", "RECON_DISK": "Reconstructing Disk",
"DISABLE_DISK": "Dysk wyłączony", "DISABLE_DISK": "Disk Disabled",
"SWAP_DSBL": "Przestrzeń wymiany wyłączona", "SWAP_DSBL": "Swap Disable",
"INVALID_EXPANSION": "Nieprawidłowe rozszerzenie", "INVALID_EXPANSION": "Invalid Expansion",
"PARITY_NOT_BIGGEST": "Parzystość nie największa", "PARITY_NOT_BIGGEST": "Parity Not Biggest",
"TOO_MANY_MISSING_DISKS": "Zbyt wiele brakujących dysków", "TOO_MANY_MISSING_DISKS": "Too Many Missing Disks",
"NEW_DISK_TOO_SMALL": "Nowy dysk zbyt mały", "NEW_DISK_TOO_SMALL": "New Disk Too Small",
"NO_DATA_DISKS": "Brak dysków danych", "NO_DATA_DISKS": "No Data Disks",
"notifications": "Powiadomienia", "notifications": "Notifications",
"status": "Status", "status": "Status",
"cpu": "CPU", "cpu": "CPU",
"memoryUsed": "Użyta pamięć", "memoryUsed": "Memory Used",
"memoryAvailable": "Dostępna pamięć", "memoryAvailable": "Memory Available",
"arrayUsed": "Użyto macierzy", "arrayUsed": "Array Used",
"arrayFree": "Wolne na macierzy", "arrayFree": "Array Free",
"poolUsed": "Użyto {{pool}}", "poolUsed": "{{pool}} Used",
"poolFree": "{{pool}} Wolne" "poolFree": "{{pool}} Free"
}, },
"backrest": { "backrest": {
"num_plans": "Planowane", "num_plans": "Plans",
"num_success_30": "Powodzenia", "num_success_30": "Successes",
"num_failure_30": "Niepowodzenia", "num_failure_30": "Failures",
"num_success_latest": "Powodzenie", "num_success_latest": "Succeeding",
"num_failure_latest": "Niepowodzenie", "num_failure_latest": "Failing",
"bytes_added_30": "Dodane bajty" "bytes_added_30": "Bytes Added"
}, },
"yourspotify": { "yourspotify": {
"songs": "Piosenki", "songs": "Songs",
"time": "Czas", "time": "Time",
"artists": "Wykonawcy" "artists": "Artists"
} }
} }

View File

@@ -532,8 +532,7 @@
"child_bridges_status": "{{ok}}/{{total}}", "child_bridges_status": "{{ok}}/{{total}}",
"up": "Up", "up": "Up",
"pending": "Pending", "pending": "Pending",
"down": "Down", "down": "Down"
"ok": "Ok"
}, },
"healthchecks": { "healthchecks": {
"new": "Novo", "new": "Novo",
@@ -793,12 +792,6 @@
"categories": "Categories", "categories": "Categories",
"series": "Series" "series": "Series"
}, },
"booklore": {
"libraries": "Libraries",
"books": "Books",
"reading": "Reading",
"finished": "Finished"
},
"jdownloader": { "jdownloader": {
"downloadCount": "Queue", "downloadCount": "Queue",
"downloadBytesRemaining": "Remaining", "downloadBytesRemaining": "Remaining",

View File

@@ -532,8 +532,7 @@
"child_bridges_status": "{{ok}}/{{total}}", "child_bridges_status": "{{ok}}/{{total}}",
"up": "Ativo", "up": "Ativo",
"pending": "Pendente", "pending": "Pendente",
"down": "Inativo", "down": "Inativo"
"ok": "Ok"
}, },
"healthchecks": { "healthchecks": {
"new": "Novo", "new": "Novo",
@@ -793,12 +792,6 @@
"categories": "Categorias", "categories": "Categorias",
"series": "Séries" "series": "Séries"
}, },
"booklore": {
"libraries": "Libraries",
"books": "Books",
"reading": "Reading",
"finished": "Finished"
},
"jdownloader": { "jdownloader": {
"downloadCount": "Fila de espera", "downloadCount": "Fila de espera",
"downloadBytesRemaining": "Restante", "downloadBytesRemaining": "Restante",

View File

@@ -532,8 +532,7 @@
"child_bridges_status": "{{ok}}/{{total}}", "child_bridges_status": "{{ok}}/{{total}}",
"up": "Up", "up": "Up",
"pending": "Pending", "pending": "Pending",
"down": "Down", "down": "Down"
"ok": "Ok"
}, },
"healthchecks": { "healthchecks": {
"new": "Nou", "new": "Nou",
@@ -793,12 +792,6 @@
"categories": "Categories", "categories": "Categories",
"series": "Series" "series": "Series"
}, },
"booklore": {
"libraries": "Libraries",
"books": "Books",
"reading": "Reading",
"finished": "Finished"
},
"jdownloader": { "jdownloader": {
"downloadCount": "Queue", "downloadCount": "Queue",
"downloadBytesRemaining": "Remaining", "downloadBytesRemaining": "Remaining",

View File

@@ -532,8 +532,7 @@
"child_bridges_status": "{{ok}}/{{total}}", "child_bridges_status": "{{ok}}/{{total}}",
"up": "В сети", "up": "В сети",
"pending": "Ожидают", "pending": "Ожидают",
"down": "Не в сети", "down": "Не в сети"
"ok": "Ok"
}, },
"healthchecks": { "healthchecks": {
"new": "Новый", "new": "Новый",
@@ -793,12 +792,6 @@
"categories": "Категории", "categories": "Категории",
"series": "Серии" "series": "Серии"
}, },
"booklore": {
"libraries": "Libraries",
"books": "Books",
"reading": "Reading",
"finished": "Finished"
},
"jdownloader": { "jdownloader": {
"downloadCount": "Очередь", "downloadCount": "Очередь",
"downloadBytesRemaining": "Осталось", "downloadBytesRemaining": "Осталось",

View File

@@ -532,8 +532,7 @@
"child_bridges_status": "{{ok}}/{{total}}", "child_bridges_status": "{{ok}}/{{total}}",
"up": "Beží", "up": "Beží",
"pending": "Čakajúce", "pending": "Čakajúce",
"down": "Down", "down": "Down"
"ok": "Ok"
}, },
"healthchecks": { "healthchecks": {
"new": "Nový", "new": "Nový",
@@ -793,12 +792,6 @@
"categories": "Kategórie", "categories": "Kategórie",
"series": "Series" "series": "Series"
}, },
"booklore": {
"libraries": "Libraries",
"books": "Books",
"reading": "Reading",
"finished": "Finished"
},
"jdownloader": { "jdownloader": {
"downloadCount": "Poradie", "downloadCount": "Poradie",
"downloadBytesRemaining": "Zostávajúce", "downloadBytesRemaining": "Zostávajúce",

View File

@@ -532,8 +532,7 @@
"child_bridges_status": "{{ok}}/{{total}}", "child_bridges_status": "{{ok}}/{{total}}",
"up": "Up", "up": "Up",
"pending": "Pending", "pending": "Pending",
"down": "Down", "down": "Down"
"ok": "Ok"
}, },
"healthchecks": { "healthchecks": {
"new": "Nov", "new": "Nov",
@@ -793,12 +792,6 @@
"categories": "Categories", "categories": "Categories",
"series": "Series" "series": "Series"
}, },
"booklore": {
"libraries": "Libraries",
"books": "Books",
"reading": "Reading",
"finished": "Finished"
},
"jdownloader": { "jdownloader": {
"downloadCount": "Queue", "downloadCount": "Queue",
"downloadBytesRemaining": "Remaining", "downloadBytesRemaining": "Remaining",

View File

@@ -532,8 +532,7 @@
"child_bridges_status": "{{ok}}/{{total}}", "child_bridges_status": "{{ok}}/{{total}}",
"up": "Горе", "up": "Горе",
"pending": "На чекању", "pending": "На чекању",
"down": "Доле", "down": "Доле"
"ok": "Ok"
}, },
"healthchecks": { "healthchecks": {
"new": "Сада", "new": "Сада",
@@ -601,13 +600,13 @@
"total": "Укупно" "total": "Укупно"
}, },
"pangolin": { "pangolin": {
"orgs": "Организације", "orgs": "Orgs",
"sites": "Сајтови", "sites": "Sites",
"resources": "Ресурси", "resources": "Resources",
"targets": "Циљеви", "targets": "Targets",
"traffic": "Саобраћај", "traffic": "Traffic",
"in": "Улазак", "in": "In",
"out": "Излазак" "out": "Out"
}, },
"peanut": { "peanut": {
"battery_charge": "Напуњеност батерије", "battery_charge": "Напуњеност батерије",
@@ -793,12 +792,6 @@
"categories": "Категорије", "categories": "Категорије",
"series": "Серије" "series": "Серије"
}, },
"booklore": {
"libraries": "Libraries",
"books": "Books",
"reading": "Reading",
"finished": "Finished"
},
"jdownloader": { "jdownloader": {
"downloadCount": "Ред", "downloadCount": "Ред",
"downloadBytesRemaining": "Преостало", "downloadBytesRemaining": "Преостало",

View File

@@ -532,8 +532,7 @@
"child_bridges_status": "{{ok}}/{{total}}", "child_bridges_status": "{{ok}}/{{total}}",
"up": "Up", "up": "Up",
"pending": "Pending", "pending": "Pending",
"down": "Down", "down": "Down"
"ok": "Ok"
}, },
"healthchecks": { "healthchecks": {
"new": "New", "new": "New",
@@ -793,12 +792,6 @@
"categories": "Categories", "categories": "Categories",
"series": "Series" "series": "Series"
}, },
"booklore": {
"libraries": "Libraries",
"books": "Books",
"reading": "Reading",
"finished": "Finished"
},
"jdownloader": { "jdownloader": {
"downloadCount": "Queue", "downloadCount": "Queue",
"downloadBytesRemaining": "Remaining", "downloadBytesRemaining": "Remaining",

View File

@@ -532,8 +532,7 @@
"child_bridges_status": "{{ok}}/{{total}}", "child_bridges_status": "{{ok}}/{{total}}",
"up": "Up", "up": "Up",
"pending": "Pending", "pending": "Pending",
"down": "Down", "down": "Down"
"ok": "Ok"
}, },
"healthchecks": { "healthchecks": {
"new": "New", "new": "New",
@@ -793,12 +792,6 @@
"categories": "Categories", "categories": "Categories",
"series": "Series" "series": "Series"
}, },
"booklore": {
"libraries": "Libraries",
"books": "Books",
"reading": "Reading",
"finished": "Finished"
},
"jdownloader": { "jdownloader": {
"downloadCount": "Queue", "downloadCount": "Queue",
"downloadBytesRemaining": "Remaining", "downloadBytesRemaining": "Remaining",

View File

@@ -532,8 +532,7 @@
"child_bridges_status": "{{ok}}/{{total}}", "child_bridges_status": "{{ok}}/{{total}}",
"up": "Up", "up": "Up",
"pending": "Pending", "pending": "Pending",
"down": "Down", "down": "Down"
"ok": "Ok"
}, },
"healthchecks": { "healthchecks": {
"new": "New", "new": "New",
@@ -793,12 +792,6 @@
"categories": "Categories", "categories": "Categories",
"series": "Series" "series": "Series"
}, },
"booklore": {
"libraries": "Libraries",
"books": "Books",
"reading": "Reading",
"finished": "Finished"
},
"jdownloader": { "jdownloader": {
"downloadCount": "Queue", "downloadCount": "Queue",
"downloadBytesRemaining": "Remaining", "downloadBytesRemaining": "Remaining",

View File

@@ -532,8 +532,7 @@
"child_bridges_status": "{{ok}}/{{total}}", "child_bridges_status": "{{ok}}/{{total}}",
"up": "Çalışıyor", "up": "Çalışıyor",
"pending": "Bekleyen", "pending": "Bekleyen",
"down": "Çalışmayan", "down": "Çalışmayan"
"ok": "Ok"
}, },
"healthchecks": { "healthchecks": {
"new": "Yeni", "new": "Yeni",
@@ -793,12 +792,6 @@
"categories": "Kategoriler", "categories": "Kategoriler",
"series": "Seriler" "series": "Seriler"
}, },
"booklore": {
"libraries": "Libraries",
"books": "Books",
"reading": "Reading",
"finished": "Finished"
},
"jdownloader": { "jdownloader": {
"downloadCount": "Kuyruk", "downloadCount": "Kuyruk",
"downloadBytesRemaining": "Kalan", "downloadBytesRemaining": "Kalan",

View File

@@ -532,8 +532,7 @@
"child_bridges_status": "{{ok}}/{{total}}", "child_bridges_status": "{{ok}}/{{total}}",
"up": "Up", "up": "Up",
"pending": "Pending", "pending": "Pending",
"down": "Down", "down": "Down"
"ok": "Ok"
}, },
"healthchecks": { "healthchecks": {
"new": "Новий", "new": "Новий",
@@ -793,12 +792,6 @@
"categories": "Categories", "categories": "Categories",
"series": "Series" "series": "Series"
}, },
"booklore": {
"libraries": "Libraries",
"books": "Books",
"reading": "Reading",
"finished": "Finished"
},
"jdownloader": { "jdownloader": {
"downloadCount": "Queue", "downloadCount": "Queue",
"downloadBytesRemaining": "Remaining", "downloadBytesRemaining": "Remaining",

View File

@@ -532,8 +532,7 @@
"child_bridges_status": "{{ok}}/{{total}}", "child_bridges_status": "{{ok}}/{{total}}",
"up": "Up", "up": "Up",
"pending": "Pending", "pending": "Pending",
"down": "Down", "down": "Down"
"ok": "Ok"
}, },
"healthchecks": { "healthchecks": {
"new": "New", "new": "New",
@@ -793,12 +792,6 @@
"categories": "Categories", "categories": "Categories",
"series": "Series" "series": "Series"
}, },
"booklore": {
"libraries": "Libraries",
"books": "Books",
"reading": "Reading",
"finished": "Finished"
},
"jdownloader": { "jdownloader": {
"downloadCount": "Queue", "downloadCount": "Queue",
"downloadBytesRemaining": "Remaining", "downloadBytesRemaining": "Remaining",

View File

@@ -532,8 +532,7 @@
"child_bridges_status": "{{ok}}/{{total}}", "child_bridges_status": "{{ok}}/{{total}}",
"up": "Up", "up": "Up",
"pending": "Pending", "pending": "Pending",
"down": "Down", "down": "Down"
"ok": "Ok"
}, },
"healthchecks": { "healthchecks": {
"new": "新建立", "new": "新建立",
@@ -793,12 +792,6 @@
"categories": "Categories", "categories": "Categories",
"series": "Series" "series": "Series"
}, },
"booklore": {
"libraries": "Libraries",
"books": "Books",
"reading": "Reading",
"finished": "Finished"
},
"jdownloader": { "jdownloader": {
"downloadCount": "Queue", "downloadCount": "Queue",
"downloadBytesRemaining": "Remaining", "downloadBytesRemaining": "Remaining",

View File

@@ -364,7 +364,7 @@
"version": "版本", "version": "版本",
"notesCount": "笔记", "notesCount": "笔记",
"dbSize": "数据库大小", "dbSize": "数据库大小",
"unknown": "未知" "unknown": "Unknown"
}, },
"navidrome": { "navidrome": {
"nothing_streaming": "", "nothing_streaming": "",
@@ -532,8 +532,7 @@
"child_bridges_status": "{{ok}}/{{total}}", "child_bridges_status": "{{ok}}/{{total}}",
"up": "Up", "up": "Up",
"pending": "Pending", "pending": "Pending",
"down": "Down", "down": "Down"
"ok": "Ok"
}, },
"healthchecks": { "healthchecks": {
"new": "新建立", "new": "新建立",
@@ -793,12 +792,6 @@
"categories": "分类", "categories": "分类",
"series": "系列" "series": "系列"
}, },
"booklore": {
"libraries": "Libraries",
"books": "Books",
"reading": "Reading",
"finished": "Finished"
},
"jdownloader": { "jdownloader": {
"downloadCount": "队列", "downloadCount": "队列",
"downloadBytesRemaining": "剩余", "downloadBytesRemaining": "剩余",
@@ -807,7 +800,7 @@
}, },
"kavita": { "kavita": {
"seriesCount": "系列", "seriesCount": "系列",
"totalFiles": "文件" "totalFiles": "Files"
}, },
"azuredevops": { "azuredevops": {
"result": "Result", "result": "Result",
@@ -1104,7 +1097,7 @@
}, },
"unraid": { "unraid": {
"STARTED": "Started", "STARTED": "Started",
"STOPPED": "已停止", "STOPPED": "Stopped",
"NEW_ARRAY": "New Array", "NEW_ARRAY": "New Array",
"RECON_DISK": "Reconstructing Disk", "RECON_DISK": "Reconstructing Disk",
"DISABLE_DISK": "Disk Disabled", "DISABLE_DISK": "Disk Disabled",

View File

@@ -532,8 +532,7 @@
"child_bridges_status": "{{ok}}/{{total}}", "child_bridges_status": "{{ok}}/{{total}}",
"up": "Up", "up": "Up",
"pending": "Pending", "pending": "Pending",
"down": "Down", "down": "Down"
"ok": "Ok"
}, },
"healthchecks": { "healthchecks": {
"new": "新建", "new": "新建",
@@ -793,12 +792,6 @@
"categories": "Categories", "categories": "Categories",
"series": "Series" "series": "Series"
}, },
"booklore": {
"libraries": "Libraries",
"books": "Books",
"reading": "Reading",
"finished": "Finished"
},
"jdownloader": { "jdownloader": {
"downloadCount": "Queue", "downloadCount": "Queue",
"downloadBytesRemaining": "Remaining", "downloadBytesRemaining": "Remaining",

View File

@@ -24,12 +24,12 @@ export default function Resource({
wide ? " min-w-[120px]" : "min-w-[85px]" wide ? " min-w-[120px]" : "min-w-[85px]"
}`} }`}
> >
<div className="text-theme-800 dark:text-theme-200 text-xs flex flex-row justify-between gap-2"> <div className="text-theme-800 dark:text-theme-200 text-xs flex flex-row justify-between">
<div className="pl-0.5">{value}</div> <div className="pl-0.5">{value}</div>
<div className="pr-1">{label}</div> <div className="pr-1">{label}</div>
</div> </div>
{expanded && ( {expanded && (
<div className="text-theme-800 dark:text-theme-200 text-xs flex flex-row justify-between gap-2"> <div className="text-theme-800 dark:text-theme-200 text-xs flex flex-row justify-between">
<div className="pl-0.5">{expandedValue}</div> <div className="pl-0.5">{expandedValue}</div>
<div className="pr-1">{expandedLabel}</div> <div className="pr-1">{expandedLabel}</div>
</div> </div>

View File

@@ -59,7 +59,7 @@ export default async function handler(req, res) {
} }
if (type === "network") { if (type === "network") {
let networkData = await si.networkStats("*"); let networkData = await si.networkStats();
let interfaceDefault; let interfaceDefault;
logger.debug("networkData:", JSON.stringify(networkData)); logger.debug("networkData:", JSON.stringify(networkData));
if (interfaceName && interfaceName !== "default") { if (interfaceName && interfaceName !== "default") {

View File

@@ -554,29 +554,40 @@ export default function Wrapper({ initialSettings, fallback }) {
html.classList.add(desiredThemeClass); html.classList.add(desiredThemeClass);
} }
// Remove any previously applied inline styles if (backgroundImage) {
const safeBackgroundImage = backgroundImage.replace(/'/g, "\\'");
body.style.backgroundImage = `linear-gradient(rgb(var(--bg-color) / ${opacity}), rgb(var(--bg-color) / ${opacity})), url('${safeBackgroundImage}')`;
body.style.backgroundSize = "cover";
body.style.backgroundPosition = "center";
body.style.backgroundAttachment = "fixed";
body.style.backgroundRepeat = "no-repeat";
body.style.backgroundColor = "";
} else {
body.style.backgroundImage = "none";
body.style.backgroundColor = "rgb(var(--bg-color))";
body.style.backgroundSize = "";
body.style.backgroundPosition = "";
body.style.backgroundAttachment = "";
body.style.backgroundRepeat = "";
}
return () => {
body.style.backgroundImage = ""; body.style.backgroundImage = "";
body.style.backgroundColor = ""; body.style.backgroundColor = "";
body.style.backgroundSize = "";
body.style.backgroundPosition = "";
body.style.backgroundAttachment = ""; body.style.backgroundAttachment = "";
body.style.backgroundRepeat = "";
};
}, [backgroundImage, opacity, theme, color, initialSettings.color]); }, [backgroundImage, opacity, theme, color, initialSettings.color]);
return ( return (
<> <div id="page_wrapper" className="relative min-h-screen">
{backgroundImage && (
<div
id="background"
aria-hidden="true"
style={{
backgroundImage: `linear-gradient(rgb(var(--bg-color) / ${opacity}), rgb(var(--bg-color) / ${opacity})), url('${backgroundImage}')`,
}}
/>
)}
<div id="page_wrapper" className="relative h-full">
<div <div
id="inner_wrapper" id="inner_wrapper"
tabIndex="-1" tabIndex="-1"
className={classNames( className={classNames(
"w-full h-full overflow-auto", "w-full min-h-screen overflow-auto",
backgroundBlur && backgroundBlur &&
`backdrop-blur${initialSettings.background.blur?.length ? `-${initialSettings.background.blur}` : ""}`, `backdrop-blur${initialSettings.background.blur?.length ? `-${initialSettings.background.blur}` : ""}`,
backgroundSaturate && `backdrop-saturate-${initialSettings.background.saturate}`, backgroundSaturate && `backdrop-saturate-${initialSettings.background.saturate}`,
@@ -586,6 +597,5 @@ export default function Wrapper({ initialSettings, fallback }) {
<Index initialSettings={initialSettings} fallback={fallback} /> <Index initialSettings={initialSettings} fallback={fallback} />
</div> </div>
</div> </div>
</>
); );
} }

View File

@@ -30,18 +30,6 @@ body,
height: 100%; height: 100%;
margin: 0; margin: 0;
padding: 0; padding: 0;
background-color: rgb(var(--bg-color));
}
#background {
position: fixed;
inset: 0;
z-index: 0;
background-size: cover;
background-position: center;
background-repeat: no-repeat;
background-attachment: scroll;
pointer-events: none;
} }
html, html,

View File

@@ -35,7 +35,7 @@ function parseServicesToGroups(services) {
serviceGroupServices.push({ serviceGroupServices.push({
name: entryName, name: entryName,
...entries[entryName], ...entries[entryName],
weight: entries[entryName].weight ?? (serviceGroupServices.length + 1) * 100, // default weight weight: entries[entryName].weight || serviceGroupServices.length * 100, // default weight
type: "service", type: "service",
}); });
} }
@@ -107,7 +107,6 @@ export async function servicesFromDocker() {
constructedService = { constructedService = {
container: containerName.replace(/^\//, ""), container: containerName.replace(/^\//, ""),
server: serverName, server: serverName,
weight: 0,
type: "service", type: "service",
}; };
} }
@@ -314,7 +313,7 @@ export function cleanServiceGroups(groups) {
// gamedig // gamedig
gameToken, gameToken,
// authentik, beszel, glances, immich, komga, mealie, netalertx, pihole, pfsense, speedtest // authentik, beszel, glances, immich, komga, mealie, pihole, pfsense, speedtest
version, version,
// glances // glances
@@ -559,7 +558,6 @@ export function cleanServiceGroups(groups) {
"immich", "immich",
"komga", "komga",
"mealie", "mealie",
"netalertx",
"pfsense", "pfsense",
"pihole", "pihole",
"speedtest", "speedtest",

View File

@@ -27,9 +27,6 @@ export default async function credentialedProxyHandler(req, res, map) {
const headers = { const headers = {
"Content-Type": "application/json", "Content-Type": "application/json",
...(widgets[widget.type].headers ?? {}),
...(widget.headers ?? {}),
...(req.extraHeaders ?? {}),
}; };
if (widget.type === "stocks") { if (widget.type === "stocks") {

View File

@@ -25,11 +25,7 @@ export default async function genericProxyHandler(req, res, map) {
} }
const url = new URL(urlString); const url = new URL(urlString);
const headers = { const headers = req.extraHeaders ?? widget.headers ?? widgets[widget.type].headers ?? {};
...(widgets[widget.type].headers ?? {}),
...(widget.headers ?? {}),
...(req.extraHeaders ?? {}),
};
if (widget.username && widget.password) { if (widget.username && widget.password) {
headers.Authorization = `Basic ${Buffer.from(`${widget.username}:${widget.password}`).toString("base64")}`; headers.Authorization = `Basic ${Buffer.from(`${widget.username}:${widget.password}`).toString("base64")}`;

View File

@@ -1,43 +0,0 @@
import Block from "components/services/widget/block";
import Container from "components/services/widget/container";
import { useTranslation } from "next-i18next";
import useWidgetAPI from "utils/proxy/use-widget-api";
export default function Component({ service }) {
const { t } = useTranslation();
const { widget } = service;
const { data: bookloreData, error: bookloreError } = useWidgetAPI(widget);
if (bookloreError) {
return <Container service={service} error={bookloreError} />;
}
if (!bookloreData) {
return (
<Container service={service}>
<Block label="booklore.libraries" />
<Block label="booklore.books" />
<Block label="booklore.reading" />
<Block label="booklore.finished" />
</Container>
);
}
const stats = {
libraries: bookloreData.libraries ?? 0,
books: bookloreData.books ?? 0,
reading: bookloreData.reading ?? 0,
finished: bookloreData.finished ?? 0,
};
return (
<Container service={service}>
<Block label="booklore.libraries" value={t("common.number", { value: stats.libraries })} />
<Block label="booklore.books" value={t("common.number", { value: stats.books })} />
<Block label="booklore.reading" value={t("common.number", { value: stats.reading })} />
<Block label="booklore.finished" value={t("common.number", { value: stats.finished })} />
</Container>
);
}

View File

@@ -1,156 +0,0 @@
import cache from "memory-cache";
import getServiceWidget from "utils/config/service-helpers";
import createLogger from "utils/logger";
import { formatApiCall } from "utils/proxy/api-helpers";
import { httpProxy } from "utils/proxy/http";
import widgets from "widgets/widgets";
const proxyName = "bookloreProxyHandler";
const sessionTokenCacheKey = `${proxyName}__sessionToken`;
const logger = createLogger(proxyName);
async function login(widget, service) {
if (!widget.username || !widget.password) {
logger.debug("Missing credentials for Booklore service '%s'", service);
return { accessToken: false };
}
const api = widgets?.[widget.type]?.api;
const loginUrl = new URL(formatApiCall(api, { ...widget, endpoint: "auth/login" }));
const [status, , data] = await httpProxy(loginUrl, {
method: "POST",
headers: {
"Content-Type": "application/json",
accept: "application/json",
},
body: JSON.stringify({
username: widget.username,
password: widget.password,
}),
});
if (status !== 200) {
logger.debug("Booklore login failed for service '%s' with status %d", service, status);
return { accessToken: false };
}
try {
const { accessToken } = JSON.parse(data.toString());
if (accessToken) {
// access tokens are valid for ~10 hours; refresh 1 minute early.
cache.put(`${sessionTokenCacheKey}.${service}`, accessToken, 10 * 60 * 60 * 1000 - 60 * 1000);
return { accessToken };
}
} catch (e) {
logger.error("Unable to login to Booklore API: %s", e);
}
return { accessToken: false };
}
async function apiCall(widget, endpoint, service) {
const cacheKey = `${sessionTokenCacheKey}.${service}`;
let accessToken = cache.get(cacheKey);
if (!accessToken) {
({ accessToken } = await login(widget, service));
}
if (!accessToken) {
return { status: 401, data: null };
}
const headers = {
accept: "application/json",
Authorization: `Bearer ${accessToken}`,
};
const url = new URL(formatApiCall(widgets[widget.type].api, { ...widget, endpoint }));
let [status, , data] = await httpProxy(url, {
method: "GET",
headers,
});
if (status === 401 || status === 403) {
logger.debug("Booklore API rejected the request, attempting to obtain new session token");
const refreshedToken = (await login(widget, service)).accessToken;
if (!refreshedToken) {
return { status, data: null };
}
headers.Authorization = `Bearer ${refreshedToken}`;
[status, , data] = await httpProxy(url, {
method: "GET",
headers,
});
}
if (status !== 200) {
logger.error("Error getting data from Booklore: %s status %d. Data: %s", url, status, data);
return { status, data: null };
}
try {
return { status, data: JSON.parse(data.toString()) };
} catch (e) {
logger.error("Error parsing Booklore response: %s", e);
}
return { status, data: null };
}
function summarizeStatuses(books = []) {
return books.reduce(
(accumulator, book) => {
const status = (book?.readStatus || "").toString().toUpperCase();
if (status === "READING") accumulator.reading += 1;
else if (status === "READ") accumulator.finished += 1;
return accumulator;
},
{ reading: 0, finished: 0 },
);
}
export default async function bookloreProxyHandler(req, res) {
const { group, service, index } = req.query;
if (!group || !service) {
logger.debug("Invalid or missing service '%s' or group '%s'", service, group);
return res.status(400).json({ error: "Invalid proxy service type" });
}
const widget = await getServiceWidget(group, service, index);
if (!widget) {
logger.debug("Invalid or missing widget for service '%s' in group '%s'", service, group);
return res.status(400).json({ error: "Invalid proxy service type" });
}
if (!widget.username || !widget.password) {
logger.debug("Missing credentials for Booklore widget in service '%s'", service);
return res.status(400).json({ error: "Missing Booklore credentials" });
}
const { data: librariesData, status: librariesStatus } = await apiCall(widget, "libraries", service);
if (librariesStatus !== 200 || !Array.isArray(librariesData)) {
return res.status(librariesStatus || 500).send(librariesData || { error: "Error fetching libraries" });
}
const { data: booksData, status: booksStatus } = await apiCall(widget, "books", service);
if (booksStatus !== 200 || !Array.isArray(booksData)) {
return res.status(booksStatus || 500).send(booksData || { error: "Error fetching books" });
}
const { reading, finished } = summarizeStatuses(booksData);
return res.status(200).send({
libraries: librariesData.length,
books: booksData.length,
reading,
finished,
});
}

View File

@@ -1,8 +0,0 @@
import bookloreProxyHandler from "./proxy";
const widget = {
api: "{url}/api/v1/{endpoint}",
proxyHandler: bookloreProxyHandler,
};
export default widget;

View File

@@ -12,7 +12,6 @@ const components = {
backrest: dynamic(() => import("./backrest/component")), backrest: dynamic(() => import("./backrest/component")),
bazarr: dynamic(() => import("./bazarr/component")), bazarr: dynamic(() => import("./bazarr/component")),
beszel: dynamic(() => import("./beszel/component")), beszel: dynamic(() => import("./beszel/component")),
booklore: dynamic(() => import("./booklore/component")),
caddy: dynamic(() => import("./caddy/component")), caddy: dynamic(() => import("./caddy/component")),
calendar: dynamic(() => import("./calendar/component")), calendar: dynamic(() => import("./calendar/component")),
calibreweb: dynamic(() => import("./calibreweb/component")), calibreweb: dynamic(() => import("./calibreweb/component")),

View File

@@ -85,9 +85,6 @@ export default async function fritzboxProxyHandler(req, res) {
requestExternalIPv6Prefix ? requestEndpoint(apiBaseUrl, "WANIPConnection", "X_AVM_DE_GetIPv6Prefix") : null, requestExternalIPv6Prefix ? requestEndpoint(apiBaseUrl, "WANIPConnection", "X_AVM_DE_GetIPv6Prefix") : null,
]) ])
.then(([statusInfo, linkProperties, addonInfos, externalIPAddress, externalIPv6Address, externalIPv6Prefix]) => { .then(([statusInfo, linkProperties, addonInfos, externalIPAddress, externalIPv6Address, externalIPv6Prefix]) => {
const ipv6Prefix = externalIPv6Prefix?.NewIPv6Prefix;
const ipv6Len = externalIPv6Prefix?.NewPrefixLength;
res.status(200).json({ res.status(200).json({
connectionStatus: statusInfo?.NewConnectionStatus || "Unconfigured", connectionStatus: statusInfo?.NewConnectionStatus || "Unconfigured",
uptime: statusInfo?.NewUptime || 0, uptime: statusInfo?.NewUptime || 0,
@@ -99,7 +96,7 @@ export default async function fritzboxProxyHandler(req, res) {
sent: addonInfos?.NewX_AVM_DE_TotalBytesSent64 || 0, sent: addonInfos?.NewX_AVM_DE_TotalBytesSent64 || 0,
externalIPAddress: externalIPAddress?.NewExternalIPAddress || null, externalIPAddress: externalIPAddress?.NewExternalIPAddress || null,
externalIPv6Address: externalIPv6Address?.NewExternalIPv6Address || null, externalIPv6Address: externalIPv6Address?.NewExternalIPv6Address || null,
externalIPv6Prefix: ipv6Prefix && ipv6Len != null ? `${ipv6Prefix}/${ipv6Len}` : (ipv6Prefix ?? null), externalIPv6Prefix: externalIPv6Prefix?.NewIPv6Prefix || null,
}); });
}) })
.catch((error) => { .catch((error) => {

View File

@@ -3,12 +3,13 @@ import Container from "components/services/widget/container";
import useWidgetAPI from "utils/proxy/use-widget-api"; import useWidgetAPI from "utils/proxy/use-widget-api";
export const jellyseerrDefaultFields = ["pending", "approved", "available"]; export const jellyseerrDefaultFields = ["pending", "approved", "completed"];
const MAX_ALLOWED_FIELDS = 4;
export default function Component({ service }) { export default function Component({ service }) {
const { widget } = service; const { widget } = service;
widget.fields = widget?.fields?.length ? widget.fields : jellyseerrDefaultFields; widget.fields = widget?.fields?.length ? widget.fields.slice(0, MAX_ALLOWED_FIELDS) : jellyseerrDefaultFields;
const isIssueEnabled = widget.fields.includes("issues"); const isIssueEnabled = widget.fields.includes("issues");
const { data: statsData, error: statsError } = useWidgetAPI(widget, "request/count"); const { data: statsData, error: statsError } = useWidgetAPI(widget, "request/count");
@@ -23,16 +24,24 @@ export default function Component({ service }) {
<Block label="jellyseerr.pending" /> <Block label="jellyseerr.pending" />
<Block label="jellyseerr.approved" /> <Block label="jellyseerr.approved" />
<Block label="jellyseerr.available" /> <Block label="jellyseerr.available" />
<Block label="jellyseerr.completed" />
<Block label="jellyseerr.issues" /> <Block label="jellyseerr.issues" />
</Container> </Container>
); );
} }
if (statsData.completed === undefined) {
// Newer versions added "completed", fallback to available
widget.fields = widget.fields.filter((field) => field !== "completed");
widget.fields.push("available");
}
return ( return (
<Container service={service}> <Container service={service}>
<Block label="jellyseerr.pending" value={statsData.pending} /> <Block label="jellyseerr.pending" value={statsData.pending} />
<Block label="jellyseerr.approved" value={statsData.approved} /> <Block label="jellyseerr.approved" value={statsData.approved} />
<Block label="jellyseerr.available" value={statsData.available} /> <Block label="jellyseerr.available" value={statsData.available} />
<Block label="jellyseerr.completed" value={statsData.completed} />
<Block label="jellyseerr.issues" value={`${issueData?.open} / ${issueData?.total}`} /> <Block label="jellyseerr.issues" value={`${issueData?.open} / ${issueData?.total}`} />
</Container> </Container>
); );

View File

@@ -9,9 +9,7 @@ export default function Component({ service }) {
const { widget } = service; const { widget } = service;
const dataEndpoint = widget?.version > 1 ? "datav2" : "data"; const { data: netalertxData, error: netalertxError } = useWidgetAPI(widget, "data");
const { data: netalertxData, error: netalertxError } = useWidgetAPI(widget, dataEndpoint);
if (netalertxError) { if (netalertxError) {
return <Container service={service} error={netalertxError} />; return <Container service={service} error={netalertxError} />;

View File

@@ -1,15 +1,12 @@
import credentialedProxyHandler from "utils/proxy/handlers/credentialed"; import credentialedProxyHandler from "utils/proxy/handlers/credentialed";
const widget = { const widget = {
api: "{url}/{endpoint}", api: "{url}/php/server/devices.php?action=getDevicesTotals",
proxyHandler: credentialedProxyHandler, proxyHandler: credentialedProxyHandler,
mappings: { mappings: {
data: { data: {
endpoint: "php/server/devices.php?action=getDevicesTotals", endpoint: "data",
},
datav2: {
endpoint: "devices/totals",
}, },
}, },
}; };

View File

@@ -65,7 +65,7 @@ async function fetchFromPlexAPI(endpoint, widget) {
export default async function plexProxyHandler(req, res) { export default async function plexProxyHandler(req, res) {
const widget = await getWidget(req); const widget = await getWidget(req);
const { service, index } = req.query; const { service } = req.query;
if (!widget) { if (!widget) {
return res.status(400).json({ error: "Invalid proxy service type" }); return res.status(400).json({ error: "Invalid proxy service type" });
@@ -85,19 +85,19 @@ export default async function plexProxyHandler(req, res) {
streams = apiData.MediaContainer._attributes.size; streams = apiData.MediaContainer._attributes.size;
} }
let libraries = cache.get(`${librariesCacheKey}.${service}.${index}`); let libraries = cache.get(`${librariesCacheKey}.${service}`);
if (libraries === null) { if (libraries === null) {
logger.debug("Getting libraries from Plex API"); logger.debug("Getting libraries from Plex API");
[status, apiData] = await fetchFromPlexAPI("/library/sections", widget); [status, apiData] = await fetchFromPlexAPI("/library/sections", widget);
if (apiData && apiData.MediaContainer) { if (apiData && apiData.MediaContainer) {
libraries = [].concat(apiData.MediaContainer.Directory); libraries = [].concat(apiData.MediaContainer.Directory);
cache.put(`${librariesCacheKey}.${service}.${index}`, libraries, 1000 * 60 * 60 * 6); cache.put(`${librariesCacheKey}.${service}`, libraries, 1000 * 60 * 60 * 6);
} }
} }
let albums = cache.get(`${albumsCacheKey}.${service}.${index}`); let albums = cache.get(`${albumsCacheKey}.${service}`);
let movies = cache.get(`${moviesCacheKey}.${service}.${index}`); let movies = cache.get(`${moviesCacheKey}.${service}`);
let tv = cache.get(`${tvCacheKey}.${service}.${index}`); let tv = cache.get(`${tvCacheKey}.${service}`);
if (albums === null || movies === null || tv === null) { if (albums === null || movies === null || tv === null) {
albums = 0; albums = 0;
movies = 0; movies = 0;
@@ -123,9 +123,9 @@ export default async function plexProxyHandler(req, res) {
} }
}), }),
); );
cache.put(`${albumsCacheKey}.${service}.${index}`, albums, 1000 * 60 * 10); cache.put(`${albumsCacheKey}.${service}`, albums, 1000 * 60 * 10);
cache.put(`${tvCacheKey}.${service}.${index}`, tv, 1000 * 60 * 10); cache.put(`${tvCacheKey}.${service}`, tv, 1000 * 60 * 10);
cache.put(`${moviesCacheKey}.${service}.${index}`, movies, 1000 * 60 * 10); cache.put(`${moviesCacheKey}.${service}`, movies, 1000 * 60 * 10);
} }
const data = { const data = {

View File

@@ -11,15 +11,6 @@ const logger = createLogger(proxyName);
const sessionCacheKey = `${proxyName}__sessionId`; const sessionCacheKey = `${proxyName}__sessionId`;
const isNgCacheKey = `${proxyName}__isNg`; const isNgCacheKey = `${proxyName}__isNg`;
function parsePyloadResponse(url, data) {
try {
return JSON.parse(Buffer.from(data).toString());
} catch (e) {
logger.error(`Error communicating with pyload API at ${url}, returned: ${JSON.stringify(data)}`);
return data;
}
}
async function fetchFromPyloadAPI(url, sessionId, params, service) { async function fetchFromPyloadAPI(url, sessionId, params, service) {
const options = { const options = {
body: params body: params
@@ -42,33 +33,13 @@ async function fetchFromPyloadAPI(url, sessionId, params, service) {
// eslint-disable-next-line no-unused-vars // eslint-disable-next-line no-unused-vars
const [status, contentType, data, responseHeaders] = await httpProxy(url, options); const [status, contentType, data, responseHeaders] = await httpProxy(url, options);
const returnData = parsePyloadResponse(url, data); let returnData;
return [status, returnData, responseHeaders]; try {
} returnData = JSON.parse(Buffer.from(data).toString());
} catch (e) {
async function fetchFromPyloadAPIBasic(url, params, username, password) { logger.error(`Error communicating with pyload API at ${url}, returned: ${JSON.stringify(data)}`);
const parsedUrl = new URL(url); returnData = data;
const isGetRequest = !params || Object.keys(params).length === 0;
const options = {
method: isGetRequest ? "GET" : "POST",
headers: {
Authorization: `Basic ${Buffer.from(`${username}:${password}`).toString("base64")}`,
},
};
if (isGetRequest) {
if (params) {
Object.keys(params).forEach((key) => parsedUrl.searchParams.append(key, params[key]));
} }
} else {
options.headers["Content-Type"] = "application/json";
options.body = JSON.stringify(params);
}
// eslint-disable-next-line no-unused-vars
const [status, contentType, data, responseHeaders] = await httpProxy(parsedUrl, options);
const returnData = parsePyloadResponse(parsedUrl, data);
return [status, returnData, responseHeaders]; return [status, returnData, responseHeaders];
} }
@@ -95,43 +66,24 @@ async function login(loginUrl, service, username, password = "") {
return sessionId; return sessionId;
} }
export default async function pyloadProxyHandler(req, res, map = {}) { export default async function pyloadProxyHandler(req, res) {
const { group, service, endpoint, index } = req.query; const { group, service, endpoint, index } = req.query;
const { ngEndpoint } = map;
try { try {
if (group && service) { if (group && service) {
const widget = await getServiceWidget(group, service, index); const widget = await getServiceWidget(group, service, index);
if (widget) { if (widget) {
const apiTemplate = widgets[widget.type].api; const url = new URL(formatApiCall(widgets[widget.type].api, { endpoint, ...widget }));
const url = new URL(formatApiCall(apiTemplate, { endpoint, ...widget }));
const ngUrl = ngEndpoint ? new URL(formatApiCall(apiTemplate, { endpoint: ngEndpoint, ...widget })) : url;
const loginUrl = `${widget.url}/api/login`; const loginUrl = `${widget.url}/api/login`;
const hasCredentials = widget.username && widget.password;
if (hasCredentials) {
const [status, data] = await fetchFromPyloadAPIBasic(ngUrl, null, widget.username, widget.password);
if (status === 200 && !data?.error) {
cache.put(`${isNgCacheKey}.${service}`, true);
return res.json(data);
}
if (status === 401) {
return res
.status(status)
.send({ error: { message: "Invalid credentials communicating with Pyload API", data } });
}
}
let sessionId = let sessionId =
cache.get(`${sessionCacheKey}.${service}`) ?? cache.get(`${sessionCacheKey}.${service}`) ??
(await login(loginUrl, service, widget.username, widget.password)); (await login(loginUrl, service, widget.username, widget.password));
let [status, data] = await fetchFromPyloadAPI(url, sessionId, null, service); let [status, data] = await fetchFromPyloadAPI(url, sessionId, null, service);
if (status === 403 || status === 401 || (status === 400 && data?.error?.includes("CSRF token"))) { if (status === 403 || status === 401) {
logger.info("Failed to retrieve data from Pyload API with session auth, trying to login again..."); logger.info("Failed to retrieve data from Pyload API, trying to login again...");
cache.del(`${sessionCacheKey}.${service}`); cache.del(`${sessionCacheKey}.${service}`);
sessionId = await login(loginUrl, service, widget.username, widget.password); sessionId = await login(loginUrl, service, widget.username, widget.password);
[status, data] = await fetchFromPyloadAPI(url, sessionId, null, service); [status, data] = await fetchFromPyloadAPI(url, sessionId, null, service);

View File

@@ -7,7 +7,6 @@ const widget = {
mappings: { mappings: {
status: { status: {
endpoint: "statusServer", endpoint: "statusServer",
map: { ngEndpoint: "status_server" },
}, },
}, },
}; };

View File

@@ -12,8 +12,8 @@ export default function Component({ service }) {
const { data: alertData, error: alertError } = useWidgetAPI(widget, "alerts"); const { data: alertData, error: alertError } = useWidgetAPI(widget, "alerts");
const { data: statusData, error: statusError } = useWidgetAPI(widget, "status"); const { data: statusData, error: statusError } = useWidgetAPI(widget, "status");
const { data: poolsData, error: poolsError } = useWidgetAPI(widget, widget?.enablePools ? "pools" : ""); const { data: poolsData, error: poolsError } = useWidgetAPI(widget, widget?.enablePools ? "pools" : null);
const { data: datasetData, error: datasetError } = useWidgetAPI(widget, widget?.enablePools ? "dataset" : ""); const { data: datasetData, error: datasetError } = useWidgetAPI(widget, widget?.enablePools ? "dataset" : null);
if (alertError || statusError || poolsError) { if (alertError || statusError || poolsError) {
const finalError = alertError ?? statusError ?? poolsError ?? datasetError; const finalError = alertError ?? statusError ?? poolsError ?? datasetError;

View File

@@ -1,172 +0,0 @@
import WebSocket from "ws";
import getServiceWidget from "utils/config/service-helpers";
import createLogger from "utils/logger";
import { formatApiCall, sanitizeErrorURL } from "utils/proxy/api-helpers";
import credentialedProxyHandler from "utils/proxy/handlers/credentialed";
import validateWidgetData from "utils/proxy/validate-widget-data";
import widgets from "widgets/widgets";
const logger = createLogger("truenasProxyHandler");
function waitForEvent(ws, handler, { event = "message", parseJson = true } = {}) {
return new Promise((resolve, reject) => {
const timeout = setTimeout(() => {
cleanup();
reject(new Error("TrueNAS websocket wait timed out"));
}, 10000);
const handleEvent = (payload) => {
try {
let parsed = payload;
if (parseJson) {
if (Buffer.isBuffer(payload)) {
parsed = JSON.parse(payload.toString());
} else if (typeof payload === "string") {
parsed = JSON.parse(payload);
}
logger.info("Received TrueNAS websocket message: %o", parsed);
} else {
logger.info("Received TrueNAS websocket message: %o", payload);
}
const handlerResult = handler(parsed);
if (handlerResult !== undefined) {
cleanup();
if (handlerResult instanceof Error) {
reject(handlerResult);
} else {
resolve(handlerResult);
}
}
} catch (err) {
cleanup();
reject(err);
}
};
const handleError = (err) => {
cleanup();
logger.error("TrueNAS websocket error: %s", err?.message ?? err);
reject(err);
};
const handleClose = () => {
cleanup();
logger.error("TrueNAS websocket connection closed unexpectedly");
reject(new Error("TrueNAS websocket closed the connection"));
};
function cleanup() {
clearTimeout(timeout);
ws.off(event, handleEvent);
ws.off("error", handleError);
ws.off("close", handleClose);
}
ws.on(event, handleEvent);
ws.on("error", handleError);
ws.on("close", handleClose);
});
}
let nextId = 1;
async function sendMethod(ws, method, params = []) {
const id = nextId++;
const payload = { jsonrpc: "2.0", id, method, params };
logger.info("Sending TrueNAS websocket method %s with id %d", method, id);
ws.send(JSON.stringify(payload));
return waitForEvent(ws, (message) => {
if (message?.id !== id) return undefined;
if (message?.error) {
return new Error(message.error?.message || JSON.stringify(message.error));
}
return message?.result ?? message;
});
}
async function authenticate(ws, widget) {
if (widget?.key) {
try {
const apiKeyResult = await sendMethod(ws, "auth.login_with_api_key", [widget.key]);
if (apiKeyResult === true) return;
logger.warn("TrueNAS API key authentication failed, falling back to username/password when available.");
} catch (err) {
logger.warn("TrueNAS API key authentication failed: %s", err?.message ?? err);
}
}
if (widget?.username && widget?.password) {
const loginResult = await sendMethod(ws, "auth.login", [widget.username, widget.password]);
if (loginResult === true) return;
logger.warn("TrueNAS username/password authentication failed.");
}
throw new Error("TrueNAS authentication failed");
}
export default async function truenasProxyHandler(req, res, map) {
const { group, service, endpoint, index } = req.query;
if (!group || !service) {
logger.debug("Invalid or missing service '%s' or group '%s'", service, group);
return res.status(400).json({ error: "Invalid proxy service type" });
}
const widget = await getServiceWidget(group, service, index);
if (!widget) {
logger.debug("Invalid or missing widget for service '%s' in group '%s'", service, group);
return res.status(400).json({ error: "Invalid proxy service type" });
}
if (!endpoint) {
return res.status(204).end();
}
const version = Number(widget.version ?? 1);
if (Number.isNaN(version) || version < 2) {
// Use legacy REST proxy for version 1
return credentialedProxyHandler(req, res, map);
}
const mappingEntry = Object.values(widgets[widget.type].mappings).find((mapping) => mapping.endpoint === endpoint);
const wsMethod = mappingEntry.wsMethod;
if (!wsMethod) {
logger.debug("Missing wsMethod mapping for TrueNAS endpoint %s", endpoint);
return res.status(500).json({ error: "Missing wsMethod mapping." });
}
try {
let data;
const wsUrl = new URL(formatApiCall(widgets[widget.type].wsAPI, { ...widget }));
const useSecure = wsUrl.protocol === "https:" || Boolean(widget.key); // API key requires secure connection
if (useSecure && wsUrl.protocol !== "https:")
logger.info("Upgrading TrueNAS websocket connection to secure wss://");
wsUrl.protocol = useSecure ? "wss:" : "ws:";
logger.info("Connecting to TrueNAS websocket at %s", wsUrl);
const ws = new WebSocket(wsUrl, { rejectUnauthorized: false });
await waitForEvent(ws, () => true, { event: "open", parseJson: false }); // wait for open
logger.info("Connected to TrueNAS websocket at %s", wsUrl);
try {
await authenticate(ws, widget);
data = await sendMethod(ws, wsMethod);
} finally {
ws.close();
}
if (!validateWidgetData(widget, endpoint, data)) {
return res.status(500).json({ error: { message: "Invalid data", url: sanitizeErrorURL(widget.url), data } });
}
if (map) data = map(data);
return res.status(200).json(data);
} catch (err) {
if (err?.status) {
return res.status(err.status).json({ error: err.message });
}
logger.warn("Websocket call for TrueNAS failed: %s", err?.message ?? err);
return res.status(500).json({ error: err?.message ?? "TrueNAS websocket call failed" });
}
}

View File

@@ -1,43 +1,32 @@
import truenasProxyHandler from "./proxy";
import { asJson, jsonArrayFilter } from "utils/proxy/api-helpers"; import { asJson, jsonArrayFilter } from "utils/proxy/api-helpers";
import credentialedProxyHandler from "utils/proxy/handlers/credentialed";
const widget = { const widget = {
api: "{url}/api/v2.0/{endpoint}", api: "{url}/api/v2.0/{endpoint}",
wsAPI: "{url}/api/current", proxyHandler: credentialedProxyHandler,
proxyHandler: truenasProxyHandler,
mappings: { mappings: {
alerts: { alerts: {
endpoint: "alert/list", endpoint: "alert/list",
wsMethod: "alert.list", map: (data) => ({
map: (data) => { pending: jsonArrayFilter(data, (item) => item?.dismissed === false).length,
if (Array.isArray(data)) { }),
return { pending: data.filter((item) => item?.dismissed === false).length };
}
return { pending: jsonArrayFilter(data, (item) => item?.dismissed === false).length };
},
}, },
status: { status: {
endpoint: "system/info", endpoint: "system/info",
wsMethod: "system.info",
validate: ["loadavg", "uptime_seconds"], validate: ["loadavg", "uptime_seconds"],
}, },
pools: { pools: {
endpoint: "pool", endpoint: "pool",
wsMethod: "pool.query", map: (data) =>
map: (data) => { asJson(data).map((entry) => ({
const list = Array.isArray(data) ? data : asJson(data);
return list.map((entry) => ({
id: entry.name, id: entry.name,
name: entry.name, name: entry.name,
healthy: entry.healthy, healthy: entry.healthy,
})); })),
},
}, },
dataset: { dataset: {
endpoint: "pool/dataset", endpoint: "pool/dataset",
wsMethod: "pool.dataset.query",
}, },
}, },
}; };

View File

@@ -49,12 +49,10 @@ export default function Component({ service }) {
// single monitor // single monitor
const monitor = uptimerobotData.monitors[0]; const monitor = uptimerobotData.monitors[0];
const logs = Array.isArray(monitor.logs) ? monitor.logs : [];
const lastUpLog = logs.find((log) => log.type === 2);
const lastDownLog = logs.find((log) => log.type === 1);
let status; let status;
let uptime = 0; let uptime = 0;
let logIndex = 0;
const hasLogs = Array.isArray(monitor.logs) && monitor.logs.length > 0;
switch (monitor.status) { switch (monitor.status) {
case 0: case 0:
@@ -65,7 +63,8 @@ export default function Component({ service }) {
break; break;
case 2: case 2:
status = t("uptimerobot.up"); status = t("uptimerobot.up");
uptime = t("common.duration", { value: lastUpLog?.duration ?? 0 }); uptime = t("common.duration", { value: hasLogs ? monitor.logs[0].duration : 0 });
logIndex = 1;
break; break;
case 8: case 8:
status = t("uptimerobot.seemsdown"); status = t("uptimerobot.seemsdown");
@@ -78,14 +77,14 @@ export default function Component({ service }) {
break; break;
} }
const lastDown = lastDownLog ? new Date(lastDownLog.datetime * 1000).toLocaleString() : ""; const lastDown = hasLogs ? new Date(monitor.logs[logIndex].datetime * 1000).toLocaleString() : "";
const downDuration = t("common.duration", { value: lastDownLog?.duration ?? 0 }); const downDuration = t("common.duration", { value: hasLogs ? monitor.logs[logIndex].duration : 0 });
const hideDown = !lastDownLog; const hideDown = !hasLogs || (logIndex === 1 && monitor.logs[logIndex].type !== 1);
return ( return (
<Container service={service}> <Container service={service}>
<Block label="uptimerobot.status" value={status} /> <Block label="uptimerobot.status" value={status} />
<Block label="uptimerobot.uptime" value={uptime} /> {hasLogs && <Block label="uptimerobot.uptime" value={uptime} />}
{!hideDown && <Block label="uptimerobot.lastDown" value={lastDown} />} {!hideDown && <Block label="uptimerobot.lastDown" value={lastDown} />}
{!hideDown && <Block label="uptimerobot.downDuration" value={downDuration} />} {!hideDown && <Block label="uptimerobot.downDuration" value={downDuration} />}
</Container> </Container>

View File

@@ -6,17 +6,8 @@ import useWidgetAPI from "utils/proxy/use-widget-api";
const MAX_ALLOWED_FIELDS = 4; const MAX_ALLOWED_FIELDS = 4;
const todayDate = new Date();
function toApiMonthYear(offset = 0) {
// API expects 1-indexed months, wrap around if needed
const m = todayDate.getMonth() + 1 + offset;
return {
month: ((m + 11) % 12) + 1,
year: todayDate.getFullYear() + Math.floor((m - 1) / 12),
};
}
export default function Component({ service }) { export default function Component({ service }) {
const todayDate = new Date();
const { t } = useTranslation(); const { t } = useTranslation();
const { widget } = service; const { widget } = service;
@@ -38,19 +29,28 @@ export default function Component({ service }) {
const { data: subscriptionsThisMonthlyCostData, error: subscriptionsThisMonthlyCostError } = useWidgetAPI( const { data: subscriptionsThisMonthlyCostData, error: subscriptionsThisMonthlyCostError } = useWidgetAPI(
widget, widget,
subscriptionsThisMonthlyEndpoint, subscriptionsThisMonthlyEndpoint,
toApiMonthYear(), // this month {
month: todayDate.getMonth(),
year: todayDate.getFullYear(),
},
); );
const subscriptionsNextMonthlyEndpoint = widget.fields.includes("nextMonthlyCost") ? "get_monthly_cost" : ""; const subscriptionsNextMonthlyEndpoint = widget.fields.includes("nextMonthlyCost") ? "get_monthly_cost" : "";
const { data: subscriptionsNextMonthlyCostData, error: subscriptionsNextMonthlyCostError } = useWidgetAPI( const { data: subscriptionsNextMonthlyCostData, error: subscriptionsNextMonthlyCostError } = useWidgetAPI(
widget, widget,
subscriptionsNextMonthlyEndpoint, subscriptionsNextMonthlyEndpoint,
toApiMonthYear(1), // next month {
month: todayDate.getMonth() + 1,
year: todayDate.getFullYear(),
},
); );
const subscriptionsPreviousMonthlyEndpoint = widget.fields.includes("previousMonthlyCost") ? "get_monthly_cost" : ""; const subscriptionsPreviousMonthlyEndpoint = widget.fields.includes("previousMonthlyCost") ? "get_monthly_cost" : "";
const { data: subscriptionsPreviousMonthlyCostData, error: subscriptionsPreviousMonthlyCostError } = useWidgetAPI( const { data: subscriptionsPreviousMonthlyCostData, error: subscriptionsPreviousMonthlyCostError } = useWidgetAPI(
widget, widget,
subscriptionsPreviousMonthlyEndpoint, subscriptionsPreviousMonthlyEndpoint,
toApiMonthYear(-1), // previous month {
month: todayDate.getMonth() - 1,
year: todayDate.getFullYear(),
},
); );
if ( if (

View File

@@ -9,7 +9,6 @@ import azuredevops from "./azuredevops/widget";
import backrest from "./backrest/widget"; import backrest from "./backrest/widget";
import bazarr from "./bazarr/widget"; import bazarr from "./bazarr/widget";
import beszel from "./beszel/widget"; import beszel from "./beszel/widget";
import booklore from "./booklore/widget";
import caddy from "./caddy/widget"; import caddy from "./caddy/widget";
import calendar from "./calendar/widget"; import calendar from "./calendar/widget";
import calibreweb from "./calibreweb/widget"; import calibreweb from "./calibreweb/widget";
@@ -157,7 +156,6 @@ const widgets = {
azuredevops, azuredevops,
backrest, backrest,
bazarr, bazarr,
booklore,
beszel, beszel,
caddy, caddy,
calibreweb, calibreweb,