diff --git a/docs/content/docs/guides/networking/multiple-daemons.mdx b/docs/content/docs/guides/networking/multiple-daemons.mdx
index 57bdcb9..3aad8ec 100644
--- a/docs/content/docs/guides/networking/multiple-daemons.mdx
+++ b/docs/content/docs/guides/networking/multiple-daemons.mdx
@@ -5,25 +5,30 @@ description: How to run multiple Scanopy daemon instances on a single machine, e
This guide walks through running multiple daemon instances on a single host, each scanning different interfaces or network segments. For help deciding whether this is the right approach for your network, see [Planning Daemon Deployment](/setting-up-daemons/planning-daemon-deployment/).
-## How config namespacing works
+## How multiple daemons coexist
-Every daemon instance has a name. The default is `scanopy-daemon`. When you pass `--name`, the daemon stores its configuration in a subdirectory named after that value:
+Each `scanopy-daemon install` on a host takes its own **slot** — an independent install with its own config file, service, and log file. The first install takes the default slot (`scanopy-daemon`); each additional install takes the next number (`scanopy-daemon-2`, `scanopy-daemon-3`, …). The installer allocates the slot for you — you don't name it.
-| Name | Config path (Linux) |
-| --- | --- |
-| _(default)_ | `~/.config/scanopy/daemon/config.json` |
-| `--name eth0` | `~/.config/scanopy/daemon/eth0/config.json` |
-| `--name iot` | `~/.config/scanopy/daemon/iot/config.json` |
+| Slot | Service | Config (Linux) |
+| --- | --- | --- |
+| `scanopy-daemon` | `scanopy-daemon` | `/etc/scanopy/daemon/scanopy-daemon/config.json` |
+| `scanopy-daemon-2` | `scanopy-daemon-2` | `/etc/scanopy/daemon/scanopy-daemon-2/config.json` |
+| `scanopy-daemon-3` | `scanopy-daemon-3` | `/etc/scanopy/daemon/scanopy-daemon-3/config.json` |
+
+Each slot's config holds its own daemon ID, API key, server URL, and runtime state. Slots are fully independent — starting, stopping, or reconfiguring one does not affect the others. A slot is not the daemon's *name*: the name is assigned by the server and shown in the app, and can be changed there without moving the slot.
-Each named daemon gets its own config file with its own daemon ID, API key, server URL, and runtime state. They are fully independent — starting, stopping, or reconfiguring one does not affect the others.
+
+A daemon's display name comes from the server, so you never pass it at install time. Run `scanopy-daemon list` on the host to see each installed slot, its service, and its config path.
+
-**Platform paths:**
+**System config locations by platform** (service installs):
| Platform | Base directory |
| --- | --- |
-| Linux | `~/.config/scanopy/daemon/` |
-| macOS | `~/Library/Application Support/com.scanopy.daemon/` |
-| Windows | `%APPDATA%\scanopy\daemon\` |
+| Linux | `/etc/scanopy/daemon/` |
+| macOS | `/Library/Application Support/Scanopy/daemon/` |
+| Windows | `%ProgramData%\Scanopy\daemon\` |
+| FreeBSD | `/usr/local/etc/scanopy/daemon/` |
## Restricting daemons to specific interfaces
@@ -31,10 +36,10 @@ Use `--interfaces` to limit which network interfaces a daemon scans. Without it,
```bash
# Scan only eth0
-sudo scanopy-daemon install --name eth0 --interfaces eth0
+sudo scanopy-daemon install --interfaces eth0
# Scan two interfaces
-sudo scanopy-daemon install --name production --interfaces eth0,eth1
+sudo scanopy-daemon install --interfaces eth0,eth1
```
The same setting works as an environment variable or in the config file:
@@ -49,20 +54,16 @@ SCANOPY_INTERFACES=eth0,eth1
When `--interfaces` is set, the daemon only reports and scans subnets attached to those interfaces. This prevents overlap between daemon instances sharing the same host.
-## Configuring ports and bind addresses
+## Ports and bind addresses
-Every daemon instance runs an HTTP server that binds to `0.0.0.0:60073` by default. Because `0.0.0.0` binds all interfaces, the first daemon claims port 60073 on every address — subsequent instances on the same host will fail with a port conflict.
+Every daemon instance runs an HTTP server, bound to `0.0.0.0:60073` by default. Because `0.0.0.0` binds all interfaces, the first daemon claims port 60073 on every address — a second daemon can't reuse it.
-To fix this, give each instance a unique `--bind-address` (the IP of its specific interface) and a unique `--daemon-port`:
+The installer handles this for you: when you install another daemon and don't ask for a specific port, it picks the next free one (60074, 60075, …) so the new instance doesn't collide with one already on the host. You only need to set `--daemon-port` when you want a *specific* port — most importantly for a **ServerPoll** daemon, where the port is the one the server dials, so the install command already carries it and the installer leaves it alone.
-```bash
-# Daemon on eth0 (192.168.1.10) — uses default port
-sudo scanopy-daemon install --name eth0 --interfaces eth0 \
- --bind-address 192.168.1.10 --daemon-port 60073
+To pin a daemon's listener to one interface, give it that interface's IP with `--bind-address`:
-# Daemon on eth1 (10.0.0.10) — different port
-sudo scanopy-daemon install --name eth1 --interfaces eth1 \
- --bind-address 10.0.0.10 --daemon-port 60074
+```bash
+sudo scanopy-daemon install --interfaces eth0 --bind-address 192.168.1.10
```
The same settings work as environment variables or in the config file:
@@ -76,31 +77,30 @@ SCANOPY_DAEMON_PORT=60073
{ "bind_address": "192.168.1.10", "daemon_port": 60073 }
```
-
- Both `--bind-address` and `--daemon-port` are required when running multiple daemons on one host. Even if each daemon uses a different bind address, using the same port on `0.0.0.0` will cause a conflict.
-
-
## Setting up multiple daemons
-Create a separate daemon entry in **Discover > Scan > Daemons** for each instance. Each daemon gets its own API key and can target the same or different networks. During setup, use the **Advanced** tab to configure interface restrictions under Network Discovery. The app provides platform-specific install and run commands with your settings included.
+Create a separate daemon entry in **Discover > Scan > Daemons** for each instance. Each is provisioned with its own API key and can target the same or different networks. During setup, use the **Advanced** tab to set that instance's interface restrictions, bind address, and port under Network Discovery — they're baked into the install artifact the wizard gives you, so you don't have to add them by hand.
-Run `scanopy-daemon install --name ` for each instance. Each one registers its own background service — named `scanopy-daemon-` — and writes its namespaced config, so it starts immediately and on every reboot:
+Run each daemon's own install artifact on the host. Each run takes a fresh slot, so you can install several without them overwriting each other — no per-instance flags to remember:
```bash
-sudo scanopy-daemon install --name eth0 --interfaces eth0 \
- --bind-address 192.168.1.10 --daemon-port 60073 \
- --server-url https://scanopy.example.com --daemon-api-key
-sudo scanopy-daemon install --name iot --interfaces eth1 \
- --bind-address 10.0.0.10 --daemon-port 60074 \
- --server-url https://scanopy.example.com --daemon-api-key
+# First daemon — takes the scanopy-daemon slot
+sudo scanopy-daemon install --interfaces eth0
+
+# Second daemon — takes the scanopy-daemon-2 slot automatically
+sudo scanopy-daemon install --interfaces eth1
```
-Manage each instance by its service name — for example `sudo systemctl restart scanopy-daemon-eth0` (Linux), `sudo launchctl kickstart -k system/com.scanopy.daemon.eth0` (macOS), or `sc.exe stop scanopy-daemon-iot` (Windows). The bind address and port are persisted in each daemon's config file, so re-running `install` or restarting the service doesn't need them again.
+Each `install` registers a per-slot background service that starts immediately and on every reboot, and writes that slot's config. Manage each by its service — for example `sudo systemctl restart scanopy-daemon-2` (Linux) or `sc.exe stop scanopy-daemon-2` (Windows), where the service id matches the slot. On macOS the launchd label is `com.scanopy.daemon.` (for example `sudo launchctl kickstart -k system/com.scanopy.daemon.scanopy-daemon-2`). Run `scanopy-daemon list` to see each slot's exact service id. Interface, bind address, and port are persisted in each slot's config, so restarting or re-running `install` doesn't need them again.
+
+
+To re-run against an *existing* slot — reconfigure it, or re-key it after rebuilding the host — pass `--instance `, where the selector is the daemon's name, its slot, its service id, or its daemon id (all shown by `scanopy-daemon list`). Without a selector on a multi-daemon host, a non-interactive install allocates a new slot rather than guessing which one you meant, and an interactive one asks. The reconfigure command the app generates already includes the right `--instance`.
+
### systemd template (Linux, manual)
-Prefer `scanopy-daemon install --name ` above — it registers a per-instance service for you. The systemd template below is the manual alternative, kept for older daemons or hand-managed setups.
+Prefer `scanopy-daemon install` above — it registers a per-slot service for you. The systemd template below is the manual alternative, kept for older daemons or hand-managed setups.
Scanopy provides a [systemd template unit](https://github.com/scanopy/scanopy/blob/main/scanopy-daemon%40.service) for running multiple instances. Download and install it:
@@ -111,10 +111,10 @@ sudo curl -o /etc/systemd/system/scanopy-daemon@.service \
sudo systemctl daemon-reload
```
-The template uses the instance identifier as both `--name` and `--interfaces`. Each instance needs its own bind address and port — set these via environment overrides:
+The template uses the instance identifier as `--interfaces`. Each instance needs its own bind address and port — set these via environment overrides:
```ini
-ExecStart=/usr/local/bin/scanopy-daemon --name=%i --interfaces=%i
+ExecStart=/usr/local/bin/scanopy-daemon --interfaces=%i
SyslogIdentifier=scanopy-daemon-%i
```
@@ -155,41 +155,34 @@ journalctl -u scanopy-daemon@eth1
```
- The template ties the instance name to a single interface. If a daemon needs multiple interfaces, create a custom service file that passes `--interfaces eth0,eth1` and a descriptive `--name`.
+ The template ties the instance name to a single interface. If a daemon needs multiple interfaces, create a custom service file that passes `--interfaces eth0,eth1`.
-## Listing existing daemon configs
+## Listing installed daemons
-To see which named daemons are configured on a host, list the config directory:
+To see which daemons are installed on a host — their slots, services, config paths, and IDs — run:
```bash
-# Linux
-ls ~/.config/scanopy/daemon/
-
-# macOS
-ls ~/Library/Application\ Support/com.scanopy.daemon/
-
-# Windows
-dir %APPDATA%\scanopy\daemon\
+scanopy-daemon list
```
-Each subdirectory corresponds to a named daemon instance. A `config.json` at the top level is the default (unnamed) daemon.
+Each line is one installed slot. Use any of the values it prints as the `--instance` selector for `install` or the `--name` selector for `uninstall`.
## Upgrading and restarting
-All daemon instances share the same binary. Download the latest binary once (the app's **Update** button provides the command), then restart each instance's service:
+All daemon slots share the same binary. Download the latest binary once (the app's **Update** button provides the command), then restart each slot's service:
```bash
-# Instances installed with `scanopy-daemon install` (services named scanopy-daemon-)
-sudo systemctl restart scanopy-daemon-eth0
-sudo systemctl restart scanopy-daemon-iot
+# Slots installed with `scanopy-daemon install`
+sudo systemctl restart scanopy-daemon
+sudo systemctl restart scanopy-daemon-2
# Legacy systemd-template instances (scanopy-daemon@): stop, replace the binary, start
sudo systemctl stop scanopy-daemon@eth0 scanopy-daemon@eth1
sudo systemctl start scanopy-daemon@eth0 scanopy-daemon@eth1
```
-Configuration is preserved across upgrades — each daemon reads its settings from its own config file on startup.
+Configuration is preserved across upgrades — each slot reads its settings from its own config file on startup.
## Docker
diff --git a/docs/content/docs/reference/daemon-configuration.mdx b/docs/content/docs/reference/daemon-configuration.mdx
index fc945fe..4991b5d 100644
--- a/docs/content/docs/reference/daemon-configuration.mdx
+++ b/docs/content/docs/reference/daemon-configuration.mdx
@@ -40,12 +40,16 @@ environment:
**Configuration file**:
-The daemon automatically creates a config file at:
+A daemon you run yourself creates its config file under your user profile:
- **Linux**: `~/.config/scanopy/daemon/config.json`
- **macOS**: `~/Library/Application Support/com.scanopy.daemon/config.json`
- **Windows**: `%APPDATA%\scanopy\daemon\config.json`
+A daemon installed as a service uses a system directory instead. A background service runs under a different profile than whoever installed it, so `install` writes the config to a system location and points the service at it explicitly. The install command prints the config and log paths it settled on — read them off the output rather than guessing.
+
+Use `--config-dir` / `SCANOPY_CONFIG_DIR` to override the directory holding `config.json`.
+
The config file stores runtime state (daemon ID, host ID) alongside your settings. Command-line and environment variables take priority over the file.
## Parameter Reference
@@ -86,68 +90,17 @@ Seeded credentials are applied **only at first registration**. If the daemon is
There is no flag for scanning the local Docker or Podman socket. Local sockets are ordinary credentials — create a [Docker Socket](/guides/integrations/docker/) or [Podman Socket](/guides/integrations/podman/) credential and, if seeding it here, reference it with the loopback form above.
-## Deprecated in v0.15.0
-
-
-The following parameters are deprecated and will be removed in v0.16.0. Use [Docker Proxy credentials](/guides/integrations/docker/) instead. See the [migration guide](/guides/operations/unified-discovery-migration/#1-recreate-docker-proxy-configuration-as-a-credential) for steps.
-
-
-- `--docker-proxy` / `SCANOPY_DOCKER_PROXY`
-- `--docker-proxy-ssl-cert` / `SCANOPY_DOCKER_PROXY_SSL_CERT`
-- `--docker-proxy-ssl-key` / `SCANOPY_DOCKER_PROXY_SSL_KEY`
-- `--docker-proxy-ssl-chain` / `SCANOPY_DOCKER_PROXY_SSL_CHAIN`
-
-Scan speed settings (`--scan-rate-pps`, `--arp-rate-pps`, etc.) configured at the daemon level are no longer used. Scan speed is now configured per-discovery in the **Speed** tab. See the [migration guide](/guides/operations/unified-discovery-migration/#2-re-apply-scan-speed-overrides).
-
-## Concurrent Scans
-
-Controls how many hosts the daemon scans simultaneously during network discovery.
-
-**Default behavior**: Auto-detected based on system resources
-
-- Calculates based on available memory
-- Typical range: 10-20 for most systems
-- Adjusts to prevent memory exhaustion
-
-**When to set manually**:
+## Deprecated Parameters
-- System crashes during scans
-- Memory errors in logs
-- Very large networks (100+ hosts)
-- Resource-constrained devices (Raspberry Pi)
-
-**Recommended values**:
-
-- **Raspberry Pi 4 (4GB)**: 5-10
-- **Standard desktop**: 15-20
-- **Server**: 20-30+
-- **Low memory**: Start with 5, increase gradually
-
-**Setting**:
-
-```bash
-# CLI
-scanopy-daemon --concurrent-scans 10
-
-# Environment
-export SCANOPY_CONCURRENT_SCANS=10
-
-# Docker
-environment:
- - SCANOPY_CONCURRENT_SCANS=10
-```
+The Docker proxy parameters (`--docker-proxy`, `--docker-proxy-ssl-cert`, `--docker-proxy-ssl-key`, `--docker-proxy-ssl-chain`, and their `SCANOPY_*` equivalents) are superseded by [Docker Proxy credentials](/guides/integrations/docker/). See the [migration guide](/guides/operations/unified-discovery-migration/#1-recreate-docker-proxy-configuration-as-a-credential) for steps.
-**Symptoms of too high**:
+Scan speed settings (`--scan-rate-pps`, `--arp-rate-pps`, and similar) configured at the daemon level are no longer used. Scan speed is configured per-discovery in the **Speed** tab. See the [migration guide](/guides/operations/unified-discovery-migration/#2-re-apply-scan-speed-overrides).
-- Daemon crashes during scans
-- "CONCURRENT_SCANS too high for this system" error
-- Out of memory errors
-- System becomes unresponsive
+## Scan Concurrency
-**Impact**:
+The daemon decides how many hosts to scan simultaneously on its own, based on available memory and its file descriptor limit. There is no setting to configure it.
-- Lower value = slower scans, more stable
-- Higher value = faster scans, more memory usage
+If scans are slower than expected because concurrency has been clamped low, the usual cause is a restrictive file descriptor limit — see ["Too Many Open Files"](/setting-up-daemons/troubleshooting-scans/scan-performance/#too-many-open-files-error).
## Logging
diff --git a/docs/content/docs/reference/daemon-identity.mdx b/docs/content/docs/reference/daemon-identity.mdx
new file mode 100644
index 0000000..8ae3b75
--- /dev/null
+++ b/docs/content/docs/reference/daemon-identity.mdx
@@ -0,0 +1,84 @@
+---
+title: Daemon Identity
+description: How daemons are provisioned, how API keys bind to them, and how legacy shared keys behave.
+---
+
+Every daemon has a server-side record and an API key bound to it. This page describes how that
+binding is established and enforced. For the settings a daemon reads at runtime, see
+[Daemon Configuration](/reference/daemon-configuration/). For creating and managing daemons, see
+[Managing Daemons](/setting-up-daemons/managing-daemons/).
+
+## Provisioning
+
+Creating a daemon in **Discover > Scan > Daemons** provisions it:
+
+1. The server creates the daemon record.
+2. The server mints an API key and binds it to that record.
+3. The wizard emits an install artifact carrying the key.
+
+The key's plaintext is available only at the moment it is minted. It appears in the install
+artifact the wizard shows you and is not retrievable afterwards.
+
+You do not create daemon API keys yourself. The **Platform > API Keys** daemon tab lists keys but
+no longer creates them.
+
+## Key binding
+
+A provisioned key belongs to exactly one daemon, and a daemon has exactly one key.
+
+| Property | Behavior |
+| --------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| **Binding** | One key, one daemon. Enforced by the server, not by convention. |
+| **Re-provisioning** | Minting a new key for a daemon deletes the key it replaces. The old key stops authenticating immediately. |
+| **Plaintext storage** | ServerPoll only. The server holds the plaintext because it presents the key when it dials the daemon. DaemonPoll daemons carry their own key and the server stores only a hash. |
+
+## How the server identifies a daemon
+
+| Key type | Identity comes from | `X-Daemon-ID` header |
+| ----------------------- | ------------------- | ------------------------------------------------------------------------------------------------- |
+| Bound (1:1) | The key itself | Optional. If present and it doesn't match the key's daemon, the request is rejected as key reuse. |
+| Legacy (network-shared) | The header | Required. Without it the daemon is unidentifiable and the request is rejected. |
+
+## Version floor
+
+Server-provisioned identity requires **daemon version 0.17.5 or later**. A 0.17.5+ daemon starts
+with no identity of its own and learns which daemon it is from the key during its first handshake
+with the server.
+
+Daemons below 0.17.5 self-register against a network-shared key and identify themselves with the
+`X-Daemon-ID` header. Both models are accepted concurrently — which one applies is determined by
+the shape of the key presented, not by the daemon's version.
+
+## Legacy network-shared keys
+
+Keys minted before 1:1 provisioning are not bound to any daemon. A single such key is shared by
+every daemon on its network.
+
+- They continue to authenticate. Nothing expires them.
+- They cannot be created anymore.
+- They are marked as legacy in **Platform > API Keys**.
+- A daemon using one can be given a key of its own without losing its host, discovery jobs, or
+ history — see
+ [Binding a key to a legacy daemon](/setting-up-daemons/managing-daemons/#binding-a-key-to-a-legacy-daemon).
+
+## Fixed and editable properties
+
+Provisioning fixes the properties that define what a daemon _is_. The rest can be edited on the
+daemon record afterwards.
+
+| Property | |
+| -------------------- | ---------------------------------------------------------------------------------------- |
+| Network | Fixed at provision time |
+| Polling mode | Fixed at provision time |
+| Name | Fixed at provision time |
+| Host | Created at provision time |
+| Key binding | Maintained by provisioning |
+| Version | Self-reported by the daemon on each handshake |
+| Liveness and standby | Server-managed |
+| URL | Editable, ServerPoll only — a DaemonPoll daemon is never dialed, so it has no URL to set |
+| Maintainer, tags | Editable |
+
+
+A daemon's identity is tied to the machine it runs on, so there is no way to move one to a
+different host. See [Can I migrate a daemon?](/setting-up-daemons/managing-daemons/#can-i-migrate-a-daemon).
+
diff --git a/docs/content/docs/reference/daemon-status.mdx b/docs/content/docs/reference/daemon-status.mdx
index d36e5ce..b3a0732 100644
--- a/docs/content/docs/reference/daemon-status.mdx
+++ b/docs/content/docs/reference/daemon-status.mdx
@@ -3,18 +3,35 @@ title: Daemon Status
description: What each daemon status tag means and how to resolve issues.
---
-Scanopy monitors daemon health and displays status tags in the UI. A daemon with no issues shows no tag. When problems are detected, a colored tag appears next to the daemon name indicating the most important issue.
+Scanopy monitors daemon health and displays a status tag next to each daemon name in the UI. Every daemon carries exactly one tag, showing the most important condition that currently applies.
## Status Reference
| Status | Meaning |
| ------ | ------- |
| | Running current version, communicating normally |
+| | Provisioned, but the daemon has never contacted the server |
| | No discovery session in the last 30 days |
| | Server cannot reach the daemon |
| | Daemon version is no longer supported |
| | Newer daemon version available |
+## Awaiting Connection
+
+**Blue tag**. The daemon record exists but the daemon has never checked in.
+
+Every daemon passes through this state. Creating a daemon [provisions](/reference/daemon-identity/) its record on the server before the daemon itself exists, so the tag appears as soon as you finish the wizard and clears on first contact.
+
+**How to resolve**:
+
+1. Run the install artifact from the wizard on the daemon host — until you do, there is nothing to connect
+2. Confirm the daemon process or service is running (`systemctl status scanopy-daemon`, `launchctl print system/com.scanopy.daemon`, `Get-Service scanopy-daemon`, or `service scanopy-daemon status`)
+3. **DaemonPoll**: check the daemon can reach the server on port 60072
+4. **ServerPoll**: check the daemon's URL is correct and the server can reach it on port 60073
+5. Check the daemon logs for registration errors — `daemon_not_provisioned` means a 0.17.5+ daemon tried to register itself against a record that doesn't exist, which happens when it was installed by hand with a legacy shared key instead of from a provisioned daemon's install artifact
+
+If the tag persists, see [Daemon Troubleshooting](/setting-up-daemons/troubleshooting-setup).
+
## Standby
**Purple tag**. The daemon is registered but hasn't run a discovery session in over 30 days.
@@ -56,13 +73,13 @@ See [Daemon Troubleshooting](/setting-up-daemons/troubleshooting-setup) for deta
## Healthy
-No tag is shown. The daemon is running a current version and communicating with the server normally.
+**Green tag**. The daemon is running a current version and communicating with the server normally.
## Status Priority
-When multiple statuses apply, the UI shows the highest-priority one:
+When multiple conditions apply, the UI shows the highest-priority one:
-**Standby > Unreachable > Deprecated > Outdated**
+**Unreachable > Standby > Awaiting Connection > Deprecated > Outdated > Healthy**
The Home tab shows all active statuses across your daemons.
diff --git a/docs/content/docs/reference/faq.mdx b/docs/content/docs/reference/faq.mdx
index 0250cae..71907e2 100644
--- a/docs/content/docs/reference/faq.mdx
+++ b/docs/content/docs/reference/faq.mdx
@@ -72,6 +72,10 @@ Yes, but you'll miss some data. See [Layer 2 vs Layer 3](/reference/limitations/
For best results, deploy a daemon on each network segment. See [Planning Daemon Deployment](/setting-up-daemons/planning-daemon-deployment/).
+### When does a host show as stale?
+
+When discovery hasn't observed it within its network's staleness window — **28 days** by default, adjustable per network. See [Staleness](/using-scanopy/staleness/).
+
## Networking
### What ports does Scanopy use?
diff --git a/docs/content/docs/reference/limitations.mdx b/docs/content/docs/reference/limitations.mdx
index 1742068..a84e091 100644
--- a/docs/content/docs/reference/limitations.mdx
+++ b/docs/content/docs/reference/limitations.mdx
@@ -62,7 +62,7 @@ See [Service Detection](/reference/service-detection/) for how detection works a
## SNMP
-- **SNMPv3 is AuthPriv only** — authentication *and* privacy are required. AuthNoPriv and NoAuthNoPriv modes are not supported, and MD5 authentication is not available (use SHA-1 or SHA-256). SNMPv1 and SNMPv2c (community string) are also supported.
+- **SNMPv3 is AuthPriv only** — authentication _and_ privacy are required. AuthNoPriv and NoAuthNoPriv modes are not supported, and MD5 authentication is not available (use SHA-1 or SHA-256). SNMPv1 and SNMPv2c (community string) are also supported.
- **No trap/inform handling** — SNMP data is collected during discovery scans only (poll-based). Scanopy does not listen for SNMP traps or informs.
- **No custom MIB loading** — only a fixed set of standard MIBs are queried. See [SNMP reference](/reference/snmp/#queried-mibs) for the full list.
@@ -76,7 +76,7 @@ The Application perspective requires manual setup — you need to define applica
### Docker on macOS/Windows
-Docker Desktop on macOS and Windows doesn't support host networking — the container can't see your actual network. Install the daemon as a native service instead (`scanopy-daemon install`, or the signed MSI on Windows).
+Docker Desktop on macOS and Windows doesn't support host networking — the container can't see your actual network. Install the daemon as a native service instead (`scanopy-daemon install`).
## Requesting Features
diff --git a/docs/content/docs/reference/meta.json b/docs/content/docs/reference/meta.json
index 2f6a696..946687a 100644
--- a/docs/content/docs/reference/meta.json
+++ b/docs/content/docs/reference/meta.json
@@ -2,6 +2,7 @@
"title": "Reference",
"defaultOpen": true,
"pages": [
+ "daemon-identity",
"daemon-configuration",
"daemon-status",
"server-configuration",
diff --git a/docs/content/docs/reference/snmp.mdx b/docs/content/docs/reference/snmp.mdx
index 50cda08..830dff6 100644
--- a/docs/content/docs/reference/snmp.mdx
+++ b/docs/content/docs/reference/snmp.mdx
@@ -42,12 +42,17 @@ A successful SNMP run against a host populates the following entities in Scanopy
| Parameter | Default | Description |
| --------- | ------- | ----------- |
-| **Request timeout** | 5s | Timeout for a single SNMP GET or GETNEXT request |
+| **Probe timeout** | 2s | Liveness probe per credential, used to pick a working credential before collection |
+| **Request timeout** | 5s | Timeout for a single SNMP request |
| **Session timeout** | 5s | Timeout for establishing the UDP session |
-| **Walk timeout** | 30s | Maximum time for a full SNMP walk of a MIB table |
+| **Query timeout** | 30s | Ceiling on any single query, including a full walk of a MIB table |
| **Max entries** | 10,000 | Maximum rows returned from a single table walk |
| **Integration timeout** | 5m | Wall-clock budget for a full SNMP integration run against a single host (probe + all queries) |
+Candidate credentials are probed concurrently, so a host with several assigned credentials doesn't pay for each one in sequence.
+
+Every query is individually bounded, so a device that stops responding mid-collection costs 30 seconds rather than the whole 5-minute integration budget.
+
## Credential resolution order
When querying a host, the daemon resolves the SNMP credential (community string for v1/v2c, or USM parameters for v3) in this order:
@@ -57,3 +62,5 @@ When querying a host, the daemon resolves the SNMP credential (community string
3. **Fallback** — community string `public` (v2c)
If all credentials fail on both UDP 161 and 1161, the host is discovered without SNMP-sourced data. Individual query failures within a successful session are logged and skipped — they do not abort the rest of the collection.
+
+Partial results are kept. Interfaces are saved as soon as the interface table is read, before the neighbor, forwarding-table, and VLAN queries run, so a device that hangs partway through still yields its interface list rather than nothing.
diff --git a/docs/content/docs/self-hosted-server/troubleshooting.mdx b/docs/content/docs/self-hosted-server/troubleshooting.mdx
index 53694bf..44c627c 100644
--- a/docs/content/docs/self-hosted-server/troubleshooting.mdx
+++ b/docs/content/docs/self-hosted-server/troubleshooting.mdx
@@ -71,7 +71,7 @@ docker exec scanopy-daemon curl http://scanopy-server:60072/api/health
2. **Update compose file**: If gateway isn't `172.17.0.1`, update `SCANOPY_INTEGRATED_DAEMON_URL`
-3. **Check API key**: Ensure the integrated daemon has a valid API key in the database
+3. **Check the daemon record**: Server setup [provisions](/reference/daemon-identity/) the integrated daemon and its API key. Confirm the daemon appears in **Discover > Scan > Daemons** and that its `daemon-config` volume still holds the key — a wiped volume leaves the daemon with no identity to present.
## Database Issues
diff --git a/docs/content/docs/self-hosted-server/upgrading.mdx b/docs/content/docs/self-hosted-server/upgrading.mdx
index 3b9b9f7..a3bdc8f 100644
--- a/docs/content/docs/self-hosted-server/upgrading.mdx
+++ b/docs/content/docs/self-hosted-server/upgrading.mdx
@@ -13,13 +13,19 @@ docker compose up -d
```
-**Podman users**: If you pull the daemon image by tag (e.g., `podman pull …/daemon:v0.15.2`), add `--platform linux/amd64` (or `linux/arm64`) to avoid pulling the wrong architecture. See [Troubleshooting — Podman Pulls Wrong Daemon Version](/setting-up-daemons/troubleshooting-setup/#podman-pulls-wrong-daemon-version-amd64).
+ **Podman users**: If you pull the daemon image by tag (e.g., `podman pull …/daemon:v0.15.2`), add
+ `--platform linux/amd64` (or `linux/arm64`) to avoid pulling the wrong architecture. See
+ [Troubleshooting — Podman Pulls Wrong Daemon
+ Version](/setting-up-daemons/troubleshooting-setup/#podman-pulls-wrong-daemon-version-amd64).
This upgrades both the server and any daemons defined in your compose file. Volumes are preserved, so no re-registration or reconfiguration is needed.
-If you use the integrated daemon, do not delete the `daemon-config` volume during upgrades — it stores the daemon's identity (ID, API key, and network assignment). Only delete it if you need to re-register the daemon from scratch.
+ If you use the integrated daemon, do not delete the `daemon-config` volume during upgrades — it
+ stores the daemon's identity (ID, API key, and network assignment). That identity is [provisioned
+ once at server setup](/reference/daemon-identity/) and cannot be re-derived, so deleting the
+ volume means provisioning the daemon again from scratch.
After restarting, the daemon reports its new version to the server and the version status should immediately show **Current** in the UI.
diff --git a/docs/content/docs/setting-up-daemons/managing-daemons.mdx b/docs/content/docs/setting-up-daemons/managing-daemons.mdx
index 84fc1ca..07bb0b1 100644
--- a/docs/content/docs/setting-up-daemons/managing-daemons.mdx
+++ b/docs/content/docs/setting-up-daemons/managing-daemons.mdx
@@ -7,7 +7,7 @@ description: Create, upgrade, and remove daemons.
- **Linux**: Docker with host networking OR standalone binary (installable as a systemd service)
- **macOS**: Standalone binary — Docker Desktop doesn't allow access to host interfaces. Installs as a launchd service.
-- **Windows**: Standalone binary — Docker Desktop doesn't allow access to host interfaces. Installs as a Windows service (native SCM), or via the signed MSI.
+- **Windows**: Standalone binary — Docker Desktop doesn't allow access to host interfaces. Installs as a Windows service (native SCM).
- **FreeBSD**: Standalone binary, installable as an rc.d service.
On Linux, macOS, Windows, and FreeBSD the daemon installs as a native background service — see [Running as a Service](#running-as-a-service).
@@ -18,7 +18,23 @@ Go to **Discover > Scan > Daemons** and click **Create Daemon**. The wizard walk
1. **Setup** — network, polling mode, and daemon name
2. **Integrations** — optionally add SNMP, Docker, and Podman credentials, targeting all hosts or specific hosts. These are [auto-assigned](/using-scanopy/credentials/#auto-assignment) to discovered hosts after the first scan. See [Credentials](/using-scanopy/credentials/#during-daemon-setup-new-daemons) for details.
-3. **Install** — a ready-to-copy `scanopy-daemon install` command with the correct API key, server URL, daemon name, and any `--credential-id` flags
+3. **Install** — pick your platform and install method; the wizard builds the matching artifact for you
+
+Finishing the wizard [provisions](/reference/daemon-identity/) the daemon: the server creates its record and mints an API key bound to it. You don't create a key yourself.
+
+Choose an install method on the final step:
+
+| Method | What you get |
+| ------ | ------------ |
+| **Linux / macOS / FreeBSD** | A command that fetches the daemon binary and installs it as a native service |
+| **Windows** | A PowerShell command that downloads the binary and installs it as a Windows service |
+| **Docker** | A ready-to-run `docker-compose.yml` plus the `SCANOPY_*` environment variables it's configured with |
+
+
+The generated artifact carries the daemon's API key, and the key is shown only here. Copy it before leaving the wizard — you can't retrieve it afterwards. If you lose it before installing, you can mint a replacement from the daemon's management modal; once the daemon has connected, re-keying it is blocked, because a fresh key would cut off the running daemon.
+
+
+Any [advanced settings](/reference/daemon-configuration/) you set in the wizard are baked into the artifact, so the installed daemon comes up already configured.
For help choosing a polling mode and planning where to place daemons, see [Planning Daemon Deployment](/setting-up-daemons/planning-daemon-deployment/).
@@ -26,13 +42,9 @@ For help choosing a polling mode and planning where to place daemons, see [Plann
The recommended way to install the daemon is the **`scanopy-daemon install`** command. It places the binary, writes the daemon's `config.json`, and registers a native background service — **systemd** on Linux, **launchd** on macOS, the **Service Control Manager** on Windows, and **rc.d** on FreeBSD — that starts immediately and on every reboot. The install command shown on the wizard's **Install** step already includes this; copy and run it on the host.
-You can also run it yourself with the connection flags (the same flags the daemon accepts):
+`install` accepts the same connection and identity flags as the daemon itself, so you can also invoke it by hand. Get the invocation from the app rather than assembling it yourself — the wizard and the management modal build it against your server's own URL and the daemon's key.
-```bash
-sudo scanopy-daemon install --server-url https://scanopy.example.com --daemon-api-key
-```
-
-Everything else — network, interfaces, ports — is read from `config.json`, so no secrets appear in the service definition or process arguments. Re-running `install` is idempotent, and a non-elevated invocation prints the exact `sudo`/administrator command to re-run.
+Everything else — network, interfaces, ports — is read from `config.json`, so no secrets appear in the service definition or process arguments. Re-running `install` is idempotent, and a non-elevated invocation prints the exact `sudo`/administrator command to re-run. On success it prints the config and log paths it settled on.
Verify the service and view its logs:
@@ -44,18 +56,10 @@ Verify the service and view its logs:
To stop and remove the service, use `sudo scanopy-daemon uninstall` — see [Removing a Daemon](#removing-a-daemon).
-Prefer to run the daemon in the foreground (e.g. for a quick test)? Run `scanopy-daemon` directly with the same flags — it runs attached to your terminal and stops when the terminal closes. Running multiple daemons on one host? See [Running Multiple Daemons](/guides/networking/multiple-daemons/).
+Prefer to run the daemon in the foreground (e.g. for a quick test)? Run `scanopy-daemon` directly with the same flags — it runs attached to your terminal and stops when the terminal closes.
-### Windows MSI
-
-On Windows you can also install with the signed **MSI** — the platform-standard wizard. It installs the binary and registers the same service. For unattended deployment (GPO/Intune), install silently:
-
-```powershell
-msiexec /qn /i scanopy-daemon-windows-amd64.msi SERVERURL="https://scanopy.example.com" APIKEY=""
-```
-
-The MSI also handles upgrades in place and can be removed with `msiexec /qn /x scanopy-daemon-windows-amd64.msi`.
+Running several daemons on one host? Each `install` takes its own numbered **slot** (`scanopy-daemon`, `scanopy-daemon-2`, …) automatically, so installs don't overwrite each other. Run `scanopy-daemon list` to see what's installed. See [Scanning Isolated Networks from One Host](/guides/networking/multiple-daemons/) for the full workflow.
### Manually installed or older daemons
@@ -109,22 +113,43 @@ nssm start ScanopyDaemon
## Integrated Daemon (Self-Hosted)
-Self-hosted Docker Compose deployments include an **integrated daemon** that runs alongside the server. This daemon is managed as part of your Compose stack — it upgrades when you upgrade the server and doesn't need separate installation or API key setup. For upgrading the integrated daemon along with your server, see [Upgrading a Self-Hosted Server](/self-hosted-server/upgrading/).
+Self-hosted Docker Compose deployments include an **integrated daemon** that runs alongside the server. This daemon is managed as part of your Compose stack — it upgrades when you upgrade the server and needs no separate installation. Server setup provisions it and its API key for you, so there is nothing to configure by hand. For upgrading the integrated daemon along with your server, see [Upgrading a Self-Hosted Server](/self-hosted-server/upgrading/).
## Upgrading
-When an update is available, the daemon card in **Discover > Scan > Daemons** shows an **Update** button. Click it to see platform-specific upgrade steps: download the latest binary (or run the latest MSI on Windows), then restart the service (`systemctl restart` / `launchctl kickstart -k` / `sc.exe stop` + `start` / `service … restart`). Configuration is preserved across upgrades.
+When an update is available, the daemon card in **Discover > Scan > Daemons** shows an **Update** button. Click it to see platform-specific upgrade steps: download the latest binary, then restart the service (`systemctl restart` / `launchctl kickstart -k` / `sc.exe stop` + `start` / `service … restart`). Configuration is preserved across upgrades.
For upgrading self-hosted server and integrated daemon together, see [Upgrading](/self-hosted-server/upgrading).
## Updating Daemon Properties
-You can update daemon properties after creation by editing the [daemon config file](/reference/daemon-configuration). Restart the daemon's service for changes to take effect — `sudo systemctl restart scanopy-daemon` (Linux), `sudo launchctl kickstart -k system/com.scanopy.daemon` (macOS), `sc.exe stop scanopy-daemon` then `sc.exe start scanopy-daemon` (Windows), or `sudo service scanopy-daemon restart` (FreeBSD). For a foreground daemon, just restart the process.
+Click the edit icon on a daemon card in **Discover > Scan > Daemons** to open its management modal. The modal has two tabs: **Details** for the daemon record, and **API Key** for its key.
-The daemon's name is the only property that propagates to the server. All other config properties are local to the daemon.
+On the **Details** tab you can edit the maintainer, tags, and — for ServerPoll daemons — the URL the server dials. Network, polling mode, and name are shown read-only: they're set when the daemon is [provisioned](/reference/daemon-identity/) and define what the daemon is. A DaemonPoll daemon has no editable URL, because the server never dials it.
+
+Daemon-local settings — interfaces, ports, log level, scan tuning — live in the [daemon config file](/reference/daemon-configuration/) on the host, not on the server record. Change them either by [reconfiguring the daemon](#reconfiguring-a-daemon) from the modal or by editing `config.json` directly. Editing the file requires a service restart to take effect — `sudo systemctl restart scanopy-daemon` (Linux), `sudo launchctl kickstart -k system/com.scanopy.daemon` (macOS), `sc.exe stop scanopy-daemon` then `sc.exe start scanopy-daemon` (Windows), or `sudo service scanopy-daemon restart` (FreeBSD). For a foreground daemon, just restart the process.
Each daemon also reports its **capabilities** to the server: whether it has Docker or Podman socket access (for container discovery) and which subnets it has network interfaces on (for default scan targets). To update capabilities after changing the host's network configuration or Docker access, run a SelfReport discovery.
+## Reconfiguring a Daemon
+
+Changing a daemon's advanced settings in the management modal produces a **reconfigure** artifact — the way settings you change in the app reach a daemon that's already installed.
+
+A reconfigure differs from an install: it carries no API key and doesn't re-fetch the binary. It only re-asserts configuration, layering it over the `config.json` already on the host. For a Docker daemon you get just the environment variables that changed, to swap into your existing Compose file rather than replacing it — your own Compose customizations stay intact.
+
+Run the artifact on the daemon host, then restart the service.
+
+## Binding a Key to a Legacy Daemon
+
+Daemons set up before 1:1 provisioning authenticate with a key shared across every daemon on their network. They keep working indefinitely, but a shared key can't be rotated or revoked for one daemon without affecting the rest. Binding gives the daemon a key of its own, keeping its host, discovery jobs, and history.
+
+Open the daemon's management modal, go to the **API Key** tab, and click **Bind a Key**. What happens next depends on the polling mode:
+
+- **DaemonPoll** — the daemon keeps running on its shared key. You get a command to run on the daemon host to switch it over, and can do that whenever it suits you.
+- **ServerPoll** — a hard cutover. The server starts using the new key to connect immediately, so the daemon stops responding until you reconfigure it. Only do this when you can get to the host right away.
+
+Scanopy asks you to confirm before a ServerPoll cutover. See [Daemon Identity](/reference/daemon-identity/) for how the two key models coexist.
+
## Removing a Daemon
To fully remove a daemon, delete it from the UI and uninstall it from the host.
@@ -141,7 +166,9 @@ Deleting or uninstalling a daemon does not delete discovered data. Hosts, servic
sudo scanopy-daemon uninstall
```
-This stops and deregisters the service and deletes its `config.json`. Add `--purge` to also delete the installed binary, and `--name ` to target a specific instance. On Windows, run it from an elevated PowerShell, or uninstall the MSI: `msiexec /qn /x scanopy-daemon-windows-amd64.msi`.
+This stops and deregisters the service and deletes its `config.json`. Add `--purge` to also delete the installed binary and log files. On a host running several daemons, target one with `--name ` — the daemon's name, its slot, or its service id, all shown by `scanopy-daemon list` — or remove every one with `--all`. On Windows, run it from an elevated PowerShell.
+
+`uninstall` reports what it did for every item it touched — removed, left in place, or not found — so you can see exactly what remains. It's idempotent: uninstalling a daemon that was never installed succeeds and tells you there was nothing to remove.
Docker:
diff --git a/docs/content/docs/setting-up-daemons/planning-daemon-deployment.mdx b/docs/content/docs/setting-up-daemons/planning-daemon-deployment.mdx
index 3d834f9..3fc1310 100644
--- a/docs/content/docs/setting-up-daemons/planning-daemon-deployment.mdx
+++ b/docs/content/docs/setting-up-daemons/planning-daemon-deployment.mdx
@@ -100,22 +100,20 @@ flowchart TB
d2 -- "L2" --> vlan2["VLAN 2 - IoT 192.168.2.0/24"]
`} />
-Each instance gets a name and is restricted to specific interfaces so they don't overlap. Since every daemon binds an HTTP server, each instance also needs a unique `--bind-address` and `--daemon-port` to avoid port conflicts:
+Restrict each instance to specific interfaces so they don't overlap. Each `install` takes its own slot automatically, so you don't pass any per-instance identity — and since every daemon binds an HTTP server, the installer picks a non-conflicting port for each after the first:
```bash
-sudo scanopy-daemon install --name production --interfaces eth0 \
- --bind-address 192.168.1.10 --daemon-port 60073
-sudo scanopy-daemon install --name iot --interfaces eth1 \
- --bind-address 10.0.0.10 --daemon-port 60074
+sudo scanopy-daemon install --interfaces eth0
+sudo scanopy-daemon install --interfaces eth1
```
- Both `--bind-address` and `--daemon-port` are required when running multiple daemons on one host. Without them, the second instance will fail with a port binding error. See [Configuring ports and bind addresses](/guides/networking/multiple-daemons/#configuring-ports-and-bind-addresses) for details.
+ Set `--bind-address` only to pin a daemon's listener to one interface, and `--daemon-port` only when you need a specific port (for a ServerPoll daemon it's already in the install command). See [Ports and bind addresses](/guides/networking/multiple-daemons/#ports-and-bind-addresses) for details.
-Create a separate daemon entry in **Discover > Daemons** for each instance. Each gets its own API key and can target the same or different Scanopy networks.
+Create a separate daemon entry in **Discover > Daemons** for each instance. Each is provisioned with its own API key and can target the same or different Scanopy networks.
-This gives you Layer 2 discovery on each segment without needing a separate physical host per VLAN. See [Scanning Isolated Networks from One Host](/guides/networking/multiple-daemons/) for the full setup guide, including config namespacing, systemd templates, and Docker configuration.
+This gives you Layer 2 discovery on each segment without needing a separate physical host per VLAN. See [Scanning Isolated Networks from One Host](/guides/networking/multiple-daemons/) for the full setup guide, including how slots work, systemd templates, and Docker configuration.
**Best for:** Hypervisors, routers, or multi-NIC servers bridging isolated VLANs where deploying separate hosts isn't practical.
@@ -152,7 +150,7 @@ Each daemon uses a polling mode that determines which side initiates the connect
|---|---|---|
| **Connection direction** | Daemon → Server | Server → Daemon |
| **Firewall requirements** | Daemon needs outbound access to server | Server needs inbound access to daemon (port 60073) |
-| **Setup** | Daemon self-registers with an API key | Admin provisions the daemon in the UI and configures its URL |
+| **Setup** | Create the daemon in the UI, then run its install artifact on the host | Same, plus a reachable URL for the server to dial |
| **Best for** | Most deployments — works behind NAT and firewalls | DMZ or restricted environments where the daemon cannot make outbound connections |
**Use DaemonPoll unless your daemon cannot reach the server.** It's simpler to set up and requires no inbound firewall rules on the daemon host.
diff --git a/docs/content/docs/setting-up-daemons/troubleshooting-scans/credentials.mdx b/docs/content/docs/setting-up-daemons/troubleshooting-scans/credentials.mdx
index 00a15ca..81cdd60 100644
--- a/docs/content/docs/setting-up-daemons/troubleshooting-scans/credentials.mdx
+++ b/docs/content/docs/setting-up-daemons/troubleshooting-scans/credentials.mdx
@@ -79,7 +79,7 @@ If a credential type shows **0 hosts**, the credential was loaded but never succ
## Credential loaded but not assigned to hosts
-A credential can load from disk without errors but still show 0 hosts in the mapping summary. This happens when the actual authentication or connection attempt fails on the target device:
+A credential can load from disk without errors but still show 0 hosts in the mapping summary. Right after a daemon is installed this is normal: a host-targeted credential is assigned to a host only once a scan probes it there successfully, so it stays unassigned until the first scan runs. If it's still unassigned after a scan, the authentication or connection attempt is failing on the target device:
- **SNMP**: The credential was rejected by the device (wrong community string or SNMPv3 USM parameters, ACL blocking the daemon's IP, or that SNMP version disabled)
- **Docker Proxy**: The TLS handshake failed (expired cert, CA mismatch), the proxy refused the connection, or the proxy is blocking required API endpoints
diff --git a/docs/content/docs/setting-up-daemons/troubleshooting-scans/scan-performance.mdx b/docs/content/docs/setting-up-daemons/troubleshooting-scans/scan-performance.mdx
index 1786c3f..b26c90f 100644
--- a/docs/content/docs/setting-up-daemons/troubleshooting-scans/scan-performance.mdx
+++ b/docs/content/docs/setting-up-daemons/troubleshooting-scans/scan-performance.mdx
@@ -42,7 +42,7 @@ See [Daemon Configuration](/reference/daemon-configuration/) for the full parame
- **Remove it** if you don't need visibility on that segment.
- **Docker networks** (e.g. 172.17.0.0/16) should not be scanned over the network. Docker container discovery queries the Docker API directly and takes seconds.
-**If the slow subnet is interfaced**: The daemon should already be using ARP. If the subnet is reasonably sized, check `concurrent_scans` — a very low value serializes work across many hosts. See [Concurrent Scans](/reference/daemon-configuration/#concurrent-scans). If the subnet is large (/16 or bigger), see [Large Interfaced Subnets](#large-interfaced-subnets) below.
+**If the slow subnet is interfaced**: The daemon should already be using ARP. If the subnet is reasonably sized, check whether the daemon's scan concurrency has been clamped by a low file descriptor limit — see ["Too Many Open Files"](#too-many-open-files-error). If the subnet is large (/16 or bigger), see [Large Interfaced Subnets](#large-interfaced-subnets) below.
## Large Interfaced Subnets
@@ -67,57 +67,47 @@ Each scan performs up to 3 ARP rounds (1 initial + 2 retries by default). Subseq
Before increasing `arp_rate_pps`, check whether your switch has Dynamic ARP Inspection (DAI) enabled. High ARP rates can trigger rate limiting or port shutdown on managed switches. See [Switch Rate Limiting (DAI)](/setting-up-daemons/troubleshooting-scans/host-discovery/#switch-rate-limiting-dai).
-## Discovery Fails with "CONCURRENT_SCANS too high"
+## Discovery Finished with Hosts Unscanned
-**Symptoms**: Daemon crashes or runs out of memory during scans
+**Symptoms**: A run completes with a warning like `120 hosts not scanned (~35m remaining)`, and those hosts show stale data.
-**Solution**: Reduce concurrent scans in daemon configuration:
+**Cause**: The run hit **Max Discovery Duration** — the hard ceiling on a single discovery run, 6 hours by default. Scanopy completes the run rather than failing it, keeps what it collected, and leaves the rest for the next run.
-**Docker:**
-
-```yaml
-environment:
- - SCANOPY_CONCURRENT_SCANS=10 # Reduce from default
-```
-
-**Binary:**
+**Solutions**:
-```bash
-scanopy-daemon --concurrent-scans 10 ...
-```
+- **Fix the underlying slowness first**. Hitting a 6-hour ceiling usually means something above is wrong — non-interfaced subnets being TCP-probed, oversized targets, or deep scans on a large host count. Work through [Discovery Takes Hours](#discovery-takes-hours) before raising the limit.
+- **Narrow the targets** so a run covers less ground, or **add a daemon** on the slow segment.
+- **Raise the limit** in the discovery's **Detection** tab if your network genuinely needs longer than the default window.
-See [Daemon Configuration](/reference/daemon-configuration/#concurrent-scans) for recommended values.
+If the warning appears on every run, the scan is not keeping up with its schedule and each run is starting from a further-behind position.
## "Too Many Open Files" Error
-**Symptoms**: `Critical error scanning: Too many open files (os error 24)` in daemon logs
+**Symptoms**: `Critical error scanning: Too many open files (os error 24)` or `CONCURRENT_SCANS is likely too high for this system` in daemon logs, or scans that are far slower than expected because only one host is scanned at a time.
-**Causes**: System file descriptor limit is too low for the configured concurrent scans.
+**Cause**: The daemon's file descriptor limit is too low. Deep scanning a single host needs a few hundred descriptors, so a low limit forces concurrency down — sometimes to one host at a time.
-**Solutions**:
-
-1. **Reduce concurrent scans** (easiest):
+On Unix, the daemon raises its own soft limit at startup (up to the hard limit, capped at 10,240), which handles the common case of macOS defaulting to 256. If you still see this, the **hard** limit is what needs raising.
- ```yaml
- environment:
- - SCANOPY_CONCURRENT_SCANS=10
- ```
+**Solutions**:
-2. **Increase system file descriptor limit**:
+1. **Check what the daemon actually has**:
```bash
- # Check current limit
- ulimit -n
+ ulimit -Hn # hard limit — the ceiling the daemon can raise itself to
+ ulimit -n # current soft limit
+ ```
- # Increase temporarily
- ulimit -n 65535
+2. **Raise the hard limit** (add to `/etc/security/limits.conf`, then log out and back in):
- # Increase permanently (add to /etc/security/limits.conf)
+ ```
* soft nofile 65535
* hard nofile 65535
```
-3. **For Docker**: Add to your daemon container:
+ On macOS, raise it with `launchctl limit maxfiles`.
+
+3. **For Docker**, set it on the daemon container:
```yaml
ulimits:
nofile:
diff --git a/docs/content/docs/setting-up-daemons/troubleshooting-scans/snmp.mdx b/docs/content/docs/setting-up-daemons/troubleshooting-scans/snmp.mdx
index c868264..73ab2d6 100644
--- a/docs/content/docs/setting-up-daemons/troubleshooting-scans/snmp.mdx
+++ b/docs/content/docs/setting-up-daemons/troubleshooting-scans/snmp.mdx
@@ -56,6 +56,22 @@ For SNMP-specific log messages, enable debug logging and look for these messages
| `SNMP system info retrieved` with sys_descr/sys_name | Success |
| `No working SNMP credential found for {ip}` | All credentials tried, none worked |
+## Interfaces missing or incomplete
+
+**Symptoms**: A device's **ifEntry** tab shows fewer interfaces than the device has, or interfaces appear without their neighbor, VLAN, or learned-MAC data.
+
+**Cause**: The interface table walk was cut short. Scanopy caps a single table walk at 10,000 rows and bounds each query at 30 seconds, so a very large table — or a device that stalls partway through returning one — yields a partial result.
+
+Truncation is reported as a warning on the discovery session itself, so check the run in **Discover > Scan > Sessions** rather than only the daemon logs.
+
+Interfaces are saved as soon as the interface table is read, before the neighbor and VLAN queries run. So a device that hangs later in collection keeps its interface list but loses the enrichment — bare interfaces with no LLDP/CDP neighbor are the signature of that.
+
+**What to check**:
+
+- Whether the device responds to a full `snmpwalk` of the interface table from the daemon host, and how long it takes
+- Whether the device is under load or rate-limiting SNMP
+- Whether the interface count is genuinely near the 10,000-row cap (stacked chassis and large modular switches can be)
+
## Check host SNMP data
Open the host edit modal to inspect what SNMP has collected:
diff --git a/docs/content/docs/setting-up-daemons/troubleshooting-setup.mdx b/docs/content/docs/setting-up-daemons/troubleshooting-setup.mdx
index 56538cc..fb76693 100644
--- a/docs/content/docs/setting-up-daemons/troubleshooting-setup.mdx
+++ b/docs/content/docs/setting-up-daemons/troubleshooting-setup.mdx
@@ -71,7 +71,7 @@ Test-NetConnection -ComputerName your-server-hostname -Port 443
**Solutions**:
1. **Verify server URL**: Ensure `SCANOPY_SERVER_URL` is correct and reachable from the daemon host
-2. **Check API key**: Verify the API key is valid and not expired in **Platform > API Keys**
+2. **Check the API key**: Confirm the daemon's `config.json` holds the key from its install artifact. A daemon rejected with `daemon_not_provisioned` was installed by hand against a record that doesn't exist — create it in the UI and use the artifact that produces. See [Daemon Identity](/reference/daemon-identity/).
3. **Firewall rules**: Ensure outbound HTTPS (port 443) is allowed from the daemon host. On Windows, verify the daemon executable is allowed through **Windows Defender Firewall > Allow an app through firewall**.
## Permission Denied Errors (Linux)
@@ -110,7 +110,8 @@ podman pull --platform linux/amd64 ghcr.io/scanopy/scanopy/daemon:v0.15.2
For ARM hosts, use `--platform linux/arm64` instead.
-This only affects the daemon image. The server image uses explicit manifest creation and is not affected.
+ This only affects the daemon image. The server image uses explicit manifest creation and is not
+ affected.
## Getting Help
diff --git a/docs/content/docs/using-scanopy/credentials.mdx b/docs/content/docs/using-scanopy/credentials.mdx
index ff5f33f..5bbc817 100644
--- a/docs/content/docs/using-scanopy/credentials.mdx
+++ b/docs/content/docs/using-scanopy/credentials.mdx
@@ -36,7 +36,7 @@ When creating a new daemon, the **Integrations** step lets you add SNMP, Docker,
- **Target All Hosts** — the credential becomes a network default, tried on every host the daemon scans.
- **Target Specific Hosts** — the credential applies only to the hosts you name. Add the **daemon host** itself (its loopback address, `127.0.0.1` — used for local Docker and Podman sockets) or one or more **remote hosts** by IP.
-After the daemon's first scan discovers hosts at those IPs, host-targeted credentials are [auto-assigned](/using-scanopy/credentials/#auto-assignment) to the matching hosts and used in subsequent scans without manual assignment.
+Host-targeted credentials — including a daemon-host credential like a local Docker or Podman socket (`127.0.0.1`) — don't show as assigned the moment the daemon is installed. They're [auto-assigned](/using-scanopy/credentials/#auto-assignment) to a host only after the first scan probes them there successfully, and are then used in subsequent scans without manual assignment. Until that first scan runs, they're staged rather than assigned — that's expected, not a problem.
### From the discovery modal (existing daemons, new network segments)
diff --git a/docs/content/docs/using-scanopy/discovery.mdx b/docs/content/docs/using-scanopy/discovery.mdx
index f5ad220..bc9566e 100644
--- a/docs/content/docs/using-scanopy/discovery.mdx
+++ b/docs/content/docs/using-scanopy/discovery.mdx
@@ -138,6 +138,14 @@ Factors affecting speed:
If scan time is longer than expected, see [discovery takes hours](/setting-up-daemons/troubleshooting-scans/scan-performance/#discovery-takes-hours).
+### Time limit
+
+A single discovery run has a hard ceiling, set by **Max Discovery Duration** in the discovery's **Detection** settings. The default is 21,600 seconds (6 hours).
+
+When a run hits the ceiling it completes rather than failing. Hosts still queued are left unscanned and picked up by the next run, and the finished run carries a warning naming how many hosts were skipped and roughly how much time they needed. Data already collected is kept.
+
+Raise the limit for large networks that legitimately need a longer window. If a run is hitting the ceiling unexpectedly, the scan is slower than it should be — see [discovery finished with hosts unscanned](/setting-up-daemons/troubleshooting-scans/scan-performance/#discovery-finished-with-hosts-unscanned).
+
## Host Naming
When a host is discovered, Scanopy determines its name using this priority:
@@ -173,6 +181,8 @@ Scanopy primarily identifies duplicate hosts by comparing network interfaces. Tw
MAC addresses are available when the daemon is directly connected to the subnet being scanned (via ARP) or from Docker container network configuration. See [Layer 2 vs Layer 3](/reference/limitations/#layer-2-vs-layer-3) for details on when MAC addresses are collected.
+**Floating virtual IPs (CARP/VRRP).** A high-availability virtual IP has no hardware of its own — its only identity is the address it floats on, carried by a shared virtual-router MAC. Scanopy matches such an address on IP + subnet when it has no physical identity to match on, so a floating VIP is recognized as the same entity across scans instead of being recreated each time. The shared virtual MAC is never used to match, so the HA peers that host the VIP stay distinct rather than merging into one host.
+
### Docker Host Matching
Docker container discovery is local-only — it discovers containers on the daemon's own host (or on the host targeted by a Docker Proxy credential), not arbitrary remote machines. All discovered services are assigned to that host.
diff --git a/docs/content/docs/using-scanopy/meta.json b/docs/content/docs/using-scanopy/meta.json
index 1a3ac39..7ab61bc 100644
--- a/docs/content/docs/using-scanopy/meta.json
+++ b/docs/content/docs/using-scanopy/meta.json
@@ -1,5 +1,5 @@
{
"title": "Using Scanopy",
"defaultOpen": true,
- "pages": ["discovery", "credentials", "topology", "organization", "network-data", "dependencies"]
+ "pages": ["discovery", "credentials", "topology", "organization", "network-data", "staleness", "dependencies"]
}
diff --git a/docs/content/docs/using-scanopy/network-data.mdx b/docs/content/docs/using-scanopy/network-data.mdx
index 7621b04..26b066f 100644
--- a/docs/content/docs/using-scanopy/network-data.mdx
+++ b/docs/content/docs/using-scanopy/network-data.mdx
@@ -48,6 +48,10 @@ These relationships appear in the topology and host details, showing your virtua
Scanopy automatically detects 200+ services. See [Service Detection](/reference/service-detection/) for how detection works, confidence levels, and what to do when a service isn't found.
+### Stale Hosts
+
+Hosts discovery hasn't seen within their network's window carry a **Stale** badge, and the host list has a **Stale only** filter to isolate them. This flags devices that may have gone offline without deleting them. See [Staleness](/using-scanopy/staleness/) for how the window works and why an entity goes stale.
+
### Hiding Hosts
Mark hosts as hidden to flag them for exclusion from the topology. Hidden hosts remain in the database with all their services, interfaces, and discovery history intact.
@@ -69,6 +73,8 @@ The button turns blue when a host is hidden. Use the **Hidden** column filter to
Subnets represent network segments. Scanopy automatically detects subnets during discovery, but you can also create them manually. Assign a type (LAN, WiFi, DMZ, etc.) to label your subnets for filtering and organization.
+Like hosts and services, subnets can go [stale](/using-scanopy/staleness/) — carrying a **Stale** badge and a **Stale only** filter when discovery hasn't seen them within their network's window.
+
### Organizational Subnets
Two special subnet types use CIDR `0.0.0.0/0` and serve as organizational containers rather than real network segments:
diff --git a/docs/content/docs/using-scanopy/organization.mdx b/docs/content/docs/using-scanopy/organization.mdx
index 134e6e5..40485cc 100644
--- a/docs/content/docs/using-scanopy/organization.mdx
+++ b/docs/content/docs/using-scanopy/organization.mdx
@@ -32,6 +32,10 @@ Networks are the primary organizational unit. Each network represents a distinct
- One network per physical location
- Distinct networks for different security zones
+### Network Settings
+
+Open a network from **Assets > Networks** to edit its settings. Alongside its name and type, each network has a **Consider entities stale after** window — how long discovery can go without seeing a host, service, or subnet before it's flagged as [stale](/using-scanopy/staleness/). Enter it as days and hours, set it to comfortably exceed the network's scan interval, and leave it blank to use the default (28 days).
+
### Network Access
Users can be restricted to specific networks within an organization. When inviting a user, select which networks they may access — all data queries are filtered to those networks. This allows granting a contractor or external partner visibility into only the networks relevant to them while keeping other environments hidden.
@@ -44,7 +48,11 @@ Manage credentials via **Assets > Credentials**. See [Credentials](/using-scanop
## API Keys
-Each daemon requires its own API key. Create keys via **Platform > API Keys** or during daemon setup. Use one key per daemon — don't share keys between daemons.
+Each daemon gets its own API key, minted and bound to it automatically when you create the daemon. You don't create daemon keys by hand.
+
+**Platform > API Keys** lists them. Any key marked legacy predates 1:1 binding and is shared across a network's daemons; see [Daemon Identity](/reference/daemon-identity/) for how those behave and how to give a daemon a key of its own.
+
+User API keys, for programmatic access to the API, are created here too — see the [API reference](/api/).
## Tags
diff --git a/docs/content/docs/using-scanopy/staleness.mdx b/docs/content/docs/using-scanopy/staleness.mdx
new file mode 100644
index 0000000..8946df9
--- /dev/null
+++ b/docs/content/docs/using-scanopy/staleness.mdx
@@ -0,0 +1,30 @@
+---
+title: Staleness
+description: How Scanopy flags hosts, services, and subnets that discovery hasn't seen recently.
+---
+
+Scanopy marks an entity **Stale** when discovery hasn't observed it within its network's staleness window. Staleness is a signal that something may have gone quiet — a device powered off, a container removed, a host that moved — surfaced without deleting anything, so you decide what to do about it.
+
+Stale does **not** mean removed. A stale host might simply be switched off, on the road, or briefly unreachable during a scan. Scanopy never asserts that an entity is gone; it only reports how long it's been since discovery last saw it.
+
+## The staleness window
+
+Each network has its own window — how long an entity can go unobserved before it's flagged. Staleness is only meaningful relative to how often a network is scanned: a segment swept every 15 minutes and one swept monthly need very different thresholds, so the window lives on the network, not the whole organization.
+
+The default window is **28 days**. Set a network's own window in the network edit modal (**Assets > Networks** → select the network → **Consider entities stale after**), entered as days and hours. Set it to comfortably exceed the network's scan interval so a normal gap between scans never trips it. Leave it blank to use the default.
+
+See [Networks](/using-scanopy/organization/#networks) for where this fits among a network's settings.
+
+## What can go stale
+
+Only entities that discovery manages can go stale — hosts, services, and subnets that discovery found and keeps re-observing. Anything you created by hand never goes stale, because Scanopy has no scan timestamp to judge it against and won't flag your own curated records.
+
+Every entity is judged on **its own** last-seen time, independently of its parent. A service on a host that's gone quiet is only stale if that service itself hasn't been seen within the window — a recently observed service on an otherwise-dark host reads as current, and vice versa. This keeps a badge from ever contradicting its own "last seen" detail.
+
+## Where it shows up
+
+**Lists.** Hosts, services, and subnets each carry a **Stale** badge on rows past their window, and a **Stale only** filter to narrow the list to them. You can also sort by last-seen to bring the longest-unobserved entities to the top.
+
+**Topology.** Stale nodes carry a **Stale** tag on their card, with a "last seen" detail naming the entity and how long ago. A **By staleness** filter (Current / Stale) is available on the perspectives that show these entities, letting you fade everything except what's fallen behind. See [Customizing Views](/using-scanopy/topology/customizing-views/).
+
+The tag is **amber**, not red — matching the daemon status convention where red means broken and amber means behind. A stale entity may be perfectly healthy and simply unobserved, so the tag reads as "worth a look", not "error".
diff --git a/docs/content/docs/using-scanopy/topology/customizing-views.mdx b/docs/content/docs/using-scanopy/topology/customizing-views.mdx
index a454d7a..52808ad 100644
--- a/docs/content/docs/using-scanopy/topology/customizing-views.mdx
+++ b/docs/content/docs/using-scanopy/topology/customizing-views.mdx
@@ -33,6 +33,14 @@ Grouping rules change how things are organized in your topology. Use the **Group
Each perspective shows different connection types. Use the edge filter controls to toggle connection types on or off. Some connections are shown by default and others are available as overlays — toggle them on when you need the extra detail.
+Overlays available depend on the perspective. On L3 Logical, for example, **Same Container** links the addresses of a container attached to several bridge subnets (hidden by default), and **Container Runtime** connects each bridge subnet to its host.
+
+Clicking a connection highlights what it relates: for a relationship edge — such as Same Host or Same Container — the whole set of nodes it ties together lights up, while a point-to-point edge highlights only its own segment.
+
+## Metadata Filtering
+
+Beyond tags, some perspectives offer metadata filter groups that fade everything except the elements you're interested in. The **By staleness** group (Current / Stale) narrows the view to entities discovery hasn't seen within their network's window — see [Staleness](/using-scanopy/staleness/). Other groups include service category and, on Workloads, virtualization type. A filter group only appears when the entities in view actually differ on that dimension.
+
## Tag-Based Filtering
Filter your topology by tags to focus on what matters. Filtered elements fade to reduced opacity instead of disappearing, so the overall layout stays stable while your focus area stands out.
diff --git a/docs/content/docs/using-scanopy/topology/l3-logical.mdx b/docs/content/docs/using-scanopy/topology/l3-logical.mdx
index 70b8645..09bb3b5 100644
--- a/docs/content/docs/using-scanopy/topology/l3-logical.mdx
+++ b/docs/content/docs/using-scanopy/topology/l3-logical.mdx
@@ -17,6 +17,17 @@ This is the default perspective and the most general-purpose view of your networ
The L3 view is built from your discovered subnets and the IP addresses found on each host's interfaces. No manual setup is required — it appears as soon as discovery runs. [Dependencies](/using-scanopy/dependencies) configured with port-level detail surface as overlay connections on top of the structural layout.
+## Containers
+
+Container hosts (Docker, Podman) attach their containers to one or more bridge networks, and each bridge network is a subnet on this view. A container that joins several bridges appears in **each** of those subnets, so you can see everywhere it's attached rather than in just one place.
+
+Two overlays make container structure legible:
+
+- **Container Runtime** connects each bridge subnet back to its host, showing which host runs the containers on that bridge.
+- **Same Container** links the addresses of a single container that spans multiple bridge subnets, so a multi-attached container reads as one thing rather than as unrelated cards in separate subnet boxes. It's hidden by default — toggle it on when you need it.
+
+The **Container Bridges** grouping rule collapses a host's bridge subnets into a single group when they'd otherwise clutter the view. See [Customizing Views](/using-scanopy/topology/customizing-views/) for grouping rules and edge overlays.
+
## When to use it
- General-purpose situational awareness of the network
diff --git a/docs/package-lock.json b/docs/package-lock.json
index b8e8fda..a7b217d 100644
--- a/docs/package-lock.json
+++ b/docs/package-lock.json
@@ -329,9 +329,9 @@
}
},
"node_modules/@esbuild/aix-ppc64": {
- "version": "0.27.7",
- "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.27.7.tgz",
- "integrity": "sha512-EKX3Qwmhz1eMdEJokhALr0YiD0lhQNwDqkPYyPhiSwKrh7/4KRjQc04sZ8db+5DVVnZ1LmbNDI1uAMPEUBnQPg==",
+ "version": "0.28.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.28.1.tgz",
+ "integrity": "sha512-Svl7tq8k/08+p6CXPpRjQ1fKX+1odH/BQbb48fV6fj3CWHhsoIOoY87w1oHXm0qEpkIK3ZfVgp0hed3XBXzXMQ==",
"cpu": [
"ppc64"
],
@@ -345,9 +345,9 @@
}
},
"node_modules/@esbuild/android-arm": {
- "version": "0.27.7",
- "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.27.7.tgz",
- "integrity": "sha512-jbPXvB4Yj2yBV7HUfE2KHe4GJX51QplCN1pGbYjvsyCZbQmies29EoJbkEc+vYuU5o45AfQn37vZlyXy4YJ8RQ==",
+ "version": "0.28.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.28.1.tgz",
+ "integrity": "sha512-0k2F129Xdio1TdJfzJ8sy1Q47vUD2NnwdhiAf7drUN1EBTfPf4hsFCtmMgu/6m8JSzsBrlmVjudMBQqOfG8usQ==",
"cpu": [
"arm"
],
@@ -361,9 +361,9 @@
}
},
"node_modules/@esbuild/android-arm64": {
- "version": "0.27.7",
- "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.27.7.tgz",
- "integrity": "sha512-62dPZHpIXzvChfvfLJow3q5dDtiNMkwiRzPylSCfriLvZeq0a1bWChrGx/BbUbPwOrsWKMn8idSllklzBy+dgQ==",
+ "version": "0.28.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.28.1.tgz",
+ "integrity": "sha512-34EGEbCIAgosYz6goLcopX6Mo7NyGv9tfwEM2/7Ce2VcVRk568iSvniGWcUXIy7wEDR1wzolcxcriFVrWYcwBg==",
"cpu": [
"arm64"
],
@@ -377,9 +377,9 @@
}
},
"node_modules/@esbuild/android-x64": {
- "version": "0.27.7",
- "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.27.7.tgz",
- "integrity": "sha512-x5VpMODneVDb70PYV2VQOmIUUiBtY3D3mPBG8NxVk5CogneYhkR7MmM3yR/uMdITLrC1ml/NV1rj4bMJuy9MCg==",
+ "version": "0.28.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.28.1.tgz",
+ "integrity": "sha512-dbwY7ltSMDWsRatcRpCnES4F+im88OCUgGZjy52shC7GqHRE/cYlxNbB4Z4UpJswpcc4Qxd2oE/ufM0p61IKng==",
"cpu": [
"x64"
],
@@ -393,9 +393,9 @@
}
},
"node_modules/@esbuild/darwin-arm64": {
- "version": "0.27.7",
- "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.27.7.tgz",
- "integrity": "sha512-5lckdqeuBPlKUwvoCXIgI2D9/ABmPq3Rdp7IfL70393YgaASt7tbju3Ac+ePVi3KDH6N2RqePfHnXkaDtY9fkw==",
+ "version": "0.28.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.28.1.tgz",
+ "integrity": "sha512-TZbWkQY7kvTAXbXUT7uVACR5cMHsDiSz9z7ZKAX/RTq/WJEk3QyRr0wZpNhBDX+/0CtdqUIJlOiodQcta6tY3Q==",
"cpu": [
"arm64"
],
@@ -409,9 +409,9 @@
}
},
"node_modules/@esbuild/darwin-x64": {
- "version": "0.27.7",
- "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.27.7.tgz",
- "integrity": "sha512-rYnXrKcXuT7Z+WL5K980jVFdvVKhCHhUwid+dDYQpH+qu+TefcomiMAJpIiC2EM3Rjtq0sO3StMV/+3w3MyyqQ==",
+ "version": "0.28.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.28.1.tgz",
+ "integrity": "sha512-zfdzgK9ACBNZLI/CyHTOx81SyNbM6YXn7rxSgX97VjyiPl9W1i4Ka4fgKECEoFCKGpvBj5qArWIGgQjOwkgskQ==",
"cpu": [
"x64"
],
@@ -425,9 +425,9 @@
}
},
"node_modules/@esbuild/freebsd-arm64": {
- "version": "0.27.7",
- "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.27.7.tgz",
- "integrity": "sha512-B48PqeCsEgOtzME2GbNM2roU29AMTuOIN91dsMO30t+Ydis3z/3Ngoj5hhnsOSSwNzS+6JppqWsuhTp6E82l2w==",
+ "version": "0.28.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.28.1.tgz",
+ "integrity": "sha512-wG2EA8ENdEI0qhkSZMjfqrdY+ziCYCPMmtZjjIwOmXFjmyzEHn+UUxk5of+SYsjtfs3VpnlC7QLzSI5hY/rOAw==",
"cpu": [
"arm64"
],
@@ -441,9 +441,9 @@
}
},
"node_modules/@esbuild/freebsd-x64": {
- "version": "0.27.7",
- "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.27.7.tgz",
- "integrity": "sha512-jOBDK5XEjA4m5IJK3bpAQF9/Lelu/Z9ZcdhTRLf4cajlB+8VEhFFRjWgfy3M1O4rO2GQ/b2dLwCUGpiF/eATNQ==",
+ "version": "0.28.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.28.1.tgz",
+ "integrity": "sha512-i7dZ9vQgnvSCzi/rYCXNgtF/U+eKZNJBzu3eTQbRgHnM7tNSizLOkRFAl3qzVc/Op/u5YkHHa4pf/3DOYHthLQ==",
"cpu": [
"x64"
],
@@ -457,9 +457,9 @@
}
},
"node_modules/@esbuild/linux-arm": {
- "version": "0.27.7",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.27.7.tgz",
- "integrity": "sha512-RkT/YXYBTSULo3+af8Ib0ykH8u2MBh57o7q/DAs3lTJlyVQkgQvlrPTnjIzzRPQyavxtPtfg0EopvDyIt0j1rA==",
+ "version": "0.28.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.28.1.tgz",
+ "integrity": "sha512-qVXBOHQS+d5Y722GwJzJUtOLlX7km3CraOaGormF1pDtPd2C/l1SHRPgjLunLGe51Sh5YYWKMFDyV4SxgMQYTQ==",
"cpu": [
"arm"
],
@@ -473,9 +473,9 @@
}
},
"node_modules/@esbuild/linux-arm64": {
- "version": "0.27.7",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.27.7.tgz",
- "integrity": "sha512-RZPHBoxXuNnPQO9rvjh5jdkRmVizktkT7TCDkDmQ0W2SwHInKCAV95GRuvdSvA7w4VMwfCjUiPwDi0ZO6Nfe9A==",
+ "version": "0.28.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.28.1.tgz",
+ "integrity": "sha512-yHs+0uc8+nvEAfAfxrWQKK5peSNzBc4PegcMO0EJ2hT71uA7vB8Ihg2e77R2P7SG5uYjPbHlLLmve4LLLRCf0g==",
"cpu": [
"arm64"
],
@@ -489,9 +489,9 @@
}
},
"node_modules/@esbuild/linux-ia32": {
- "version": "0.27.7",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.27.7.tgz",
- "integrity": "sha512-GA48aKNkyQDbd3KtkplYWT102C5sn/EZTY4XROkxONgruHPU72l+gW+FfF8tf2cFjeHaRbWpOYa/uRBz/Xq1Pg==",
+ "version": "0.28.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.28.1.tgz",
+ "integrity": "sha512-d1z4ZuP0ajrfz/FhGT4vv278rX8KnPPJx8i5+AtK7TYbx9Le9F1hyzurZpkEyjkGa9dUGhQow4C1NmeGvqxN2w==",
"cpu": [
"ia32"
],
@@ -505,9 +505,9 @@
}
},
"node_modules/@esbuild/linux-loong64": {
- "version": "0.27.7",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.27.7.tgz",
- "integrity": "sha512-a4POruNM2oWsD4WKvBSEKGIiWQF8fZOAsycHOt6JBpZ+JN2n2JH9WAv56SOyu9X5IqAjqSIPTaJkqN8F7XOQ5Q==",
+ "version": "0.28.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.28.1.tgz",
+ "integrity": "sha512-M5sRjUVZrkm1OAPR3dlOYzNmN+loZKGVi1VUQGrwuqLcbR6qeAz+famMhjASeH3YVKvZz+zT1jlh/keC3Rj/lg==",
"cpu": [
"loong64"
],
@@ -521,9 +521,9 @@
}
},
"node_modules/@esbuild/linux-mips64el": {
- "version": "0.27.7",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.27.7.tgz",
- "integrity": "sha512-KabT5I6StirGfIz0FMgl1I+R1H73Gp0ofL9A3nG3i/cYFJzKHhouBV5VWK1CSgKvVaG4q1RNpCTR2LuTVB3fIw==",
+ "version": "0.28.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.28.1.tgz",
+ "integrity": "sha512-mRObBZeHh2OxcBFPWE/FjylkRgZdYuiTR3vaTozquCGOH14iP9oN4x4Ge81CoIDYQrXmIxpFumJBu5MtZpnQJQ==",
"cpu": [
"mips64el"
],
@@ -537,9 +537,9 @@
}
},
"node_modules/@esbuild/linux-ppc64": {
- "version": "0.27.7",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.27.7.tgz",
- "integrity": "sha512-gRsL4x6wsGHGRqhtI+ifpN/vpOFTQtnbsupUF5R5YTAg+y/lKelYR1hXbnBdzDjGbMYjVJLJTd2OFmMewAgwlQ==",
+ "version": "0.28.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.28.1.tgz",
+ "integrity": "sha512-slScBsMAb3GFDcdrCgLwZtPYRoH2H/youv10QiZyRjmsP48fznoveWytSgCI/R0ZcUgpc0ZhIUEx6LHts8yrfQ==",
"cpu": [
"ppc64"
],
@@ -553,9 +553,9 @@
}
},
"node_modules/@esbuild/linux-riscv64": {
- "version": "0.27.7",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.27.7.tgz",
- "integrity": "sha512-hL25LbxO1QOngGzu2U5xeXtxXcW+/GvMN3ejANqXkxZ/opySAZMrc+9LY/WyjAan41unrR3YrmtTsUpwT66InQ==",
+ "version": "0.28.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.28.1.tgz",
+ "integrity": "sha512-kw0owk1o0GFETUJyW0jc0G4Yzs0BHZn0JDZ8JRT088vjJYX777BAs1fDGxAC+q831qOs2DTC96mNsG2opdfyyQ==",
"cpu": [
"riscv64"
],
@@ -569,9 +569,9 @@
}
},
"node_modules/@esbuild/linux-s390x": {
- "version": "0.27.7",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.27.7.tgz",
- "integrity": "sha512-2k8go8Ycu1Kb46vEelhu1vqEP+UeRVj2zY1pSuPdgvbd5ykAw82Lrro28vXUrRmzEsUV0NzCf54yARIK8r0fdw==",
+ "version": "0.28.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.28.1.tgz",
+ "integrity": "sha512-/lAIjX8aYFRByhh6L5rYtPEDRqa9de/4V/juOXcta5frjvzXO4/sqEtyytse0g3zZFuWu5cDN0MkLz2qRDD2Ag==",
"cpu": [
"s390x"
],
@@ -585,9 +585,9 @@
}
},
"node_modules/@esbuild/linux-x64": {
- "version": "0.27.7",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.27.7.tgz",
- "integrity": "sha512-hzznmADPt+OmsYzw1EE33ccA+HPdIqiCRq7cQeL1Jlq2gb1+OyWBkMCrYGBJ+sxVzve2ZJEVeePbLM2iEIZSxA==",
+ "version": "0.28.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.28.1.tgz",
+ "integrity": "sha512-u/anNYF2mmVOEDwLtnQ1wOr3EZ9sTNGLWrsYGYwHWzGA3Si84IOkHXlbWTD1NB+9/1lcnweYKO54uhxZydNzfA==",
"cpu": [
"x64"
],
@@ -601,9 +601,9 @@
}
},
"node_modules/@esbuild/netbsd-arm64": {
- "version": "0.27.7",
- "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.27.7.tgz",
- "integrity": "sha512-b6pqtrQdigZBwZxAn1UpazEisvwaIDvdbMbmrly7cDTMFnw/+3lVxxCTGOrkPVnsYIosJJXAsILG9XcQS+Yu6w==",
+ "version": "0.28.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.28.1.tgz",
+ "integrity": "sha512-oks0DYbLwWMmaakTsCb+zL4E+aHRVLom9IJZOAthMQEPiQmydXHkziYEsGYRx0uNV/IjEKGAV941JzH02pflqw==",
"cpu": [
"arm64"
],
@@ -617,9 +617,9 @@
}
},
"node_modules/@esbuild/netbsd-x64": {
- "version": "0.27.7",
- "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.27.7.tgz",
- "integrity": "sha512-OfatkLojr6U+WN5EDYuoQhtM+1xco+/6FSzJJnuWiUw5eVcicbyK3dq5EeV/QHT1uy6GoDhGbFpprUiHUYggrw==",
+ "version": "0.28.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.28.1.tgz",
+ "integrity": "sha512-aeL6lAnN89Hz43Mlh1G8ARasbuoYvSITDEx0tHh5b7jJnHcssqgjy9Yx430GDpmCa6OyrKoS0aNRjKundRizGg==",
"cpu": [
"x64"
],
@@ -633,9 +633,9 @@
}
},
"node_modules/@esbuild/openbsd-arm64": {
- "version": "0.27.7",
- "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.27.7.tgz",
- "integrity": "sha512-AFuojMQTxAz75Fo8idVcqoQWEHIXFRbOc1TrVcFSgCZtQfSdc1RXgB3tjOn/krRHENUB4j00bfGjyl2mJrU37A==",
+ "version": "0.28.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.28.1.tgz",
+ "integrity": "sha512-MEFJe5C3R8pwXdZ5Y21oo6m7ePiS0d9pWucn99O/wvyJZChoIQKrQDxKrGeW8F5+T0okTHesAmDeiHDTIq0V/Q==",
"cpu": [
"arm64"
],
@@ -649,9 +649,9 @@
}
},
"node_modules/@esbuild/openbsd-x64": {
- "version": "0.27.7",
- "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.27.7.tgz",
- "integrity": "sha512-+A1NJmfM8WNDv5CLVQYJ5PshuRm/4cI6WMZRg1by1GwPIQPCTs1GLEUHwiiQGT5zDdyLiRM/l1G0Pv54gvtKIg==",
+ "version": "0.28.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.28.1.tgz",
+ "integrity": "sha512-i/ZLIOafE0Z8cI/XANJAixoJL/uRAoS2xOA3rb0xN+KK0K177cMAsQYkzHtBrtMXAKuAc7HGgcWiZ/sRC1Nxgw==",
"cpu": [
"x64"
],
@@ -665,9 +665,9 @@
}
},
"node_modules/@esbuild/openharmony-arm64": {
- "version": "0.27.7",
- "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.27.7.tgz",
- "integrity": "sha512-+KrvYb/C8zA9CU/g0sR6w2RBw7IGc5J2BPnc3dYc5VJxHCSF1yNMxTV5LQ7GuKteQXZtspjFbiuW5/dOj7H4Yw==",
+ "version": "0.28.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.28.1.tgz",
+ "integrity": "sha512-ge+Z7EXFNt2BO1oAMsVpiQ8EwndV9i1xXerAeTIK7AtPs3bKFXQM7nlRxDSIUIMeueR1CNXxqztLzdNeReKBJg==",
"cpu": [
"arm64"
],
@@ -681,9 +681,9 @@
}
},
"node_modules/@esbuild/sunos-x64": {
- "version": "0.27.7",
- "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.27.7.tgz",
- "integrity": "sha512-ikktIhFBzQNt/QDyOL580ti9+5mL/YZeUPKU2ivGtGjdTYoqz6jObj6nOMfhASpS4GU4Q/Clh1QtxWAvcYKamA==",
+ "version": "0.28.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.28.1.tgz",
+ "integrity": "sha512-BEjgtECkL3vY+SaSQ6nzVfiALUeFxpawyp8Jmf5PtYhf1Ug40N1h/hxlhts+f1FvSvarEigdxS3BlSMI2PJLcQ==",
"cpu": [
"x64"
],
@@ -697,9 +697,9 @@
}
},
"node_modules/@esbuild/win32-arm64": {
- "version": "0.27.7",
- "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.27.7.tgz",
- "integrity": "sha512-7yRhbHvPqSpRUV7Q20VuDwbjW5kIMwTHpptuUzV+AA46kiPze5Z7qgt6CLCK3pWFrHeNfDd1VKgyP4O+ng17CA==",
+ "version": "0.28.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.28.1.tgz",
+ "integrity": "sha512-lCv9eK/H6ZJWbE7bh2nw54CZ9M2nupBxJcTsdk/QQnWkdSjKGuxmmH8/GWrlT1eMmZfn4dGcCjRte397WqfQXA==",
"cpu": [
"arm64"
],
@@ -713,9 +713,9 @@
}
},
"node_modules/@esbuild/win32-ia32": {
- "version": "0.27.7",
- "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.27.7.tgz",
- "integrity": "sha512-SmwKXe6VHIyZYbBLJrhOoCJRB/Z1tckzmgTLfFYOfpMAx63BJEaL9ExI8x7v0oAO3Zh6D/Oi1gVxEYr5oUCFhw==",
+ "version": "0.28.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.28.1.tgz",
+ "integrity": "sha512-zvb/mB2bSCoJOpoCBgYKKpX6YM6mJBlBUVUtVj41DlZJVEB6/0CKlRYxP5wWl1C1ILiCoAU5wZZ4q1P3qeS6Eg==",
"cpu": [
"ia32"
],
@@ -729,9 +729,9 @@
}
},
"node_modules/@esbuild/win32-x64": {
- "version": "0.27.7",
- "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.27.7.tgz",
- "integrity": "sha512-56hiAJPhwQ1R4i+21FVF7V8kSD5zZTdHcVuRFMW0hn753vVfQN8xlx4uOPT4xoGH0Z/oVATuR82AiqSTDIpaHg==",
+ "version": "0.28.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.28.1.tgz",
+ "integrity": "sha512-bm4Mowrv+GXMlpWX++EcXw/iLyd1o3+bJkC2DkWXYVvgZCqD/bSj9ctZeAMC3cIxgjRVR2Dufaiu4YPxr5gW1A==",
"cpu": [
"x64"
],
@@ -1094,9 +1094,9 @@
}
},
"node_modules/@img/sharp-darwin-arm64": {
- "version": "0.34.5",
- "resolved": "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.34.5.tgz",
- "integrity": "sha512-imtQ3WMJXbMY4fxb/Ndp6HBTNVtWCUI0WdobyheGf5+ad6xX8VIDO8u2xE4qc/fr08CKG/7dDseFtn6M6g/r3w==",
+ "version": "0.35.3",
+ "resolved": "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.35.3.tgz",
+ "integrity": "sha512-RMnFX7YQsMoh7lWfcM4NEHHymBX/rLuKNPVM84XE9ONPcaSCDgE7CHIHpSgPcO2xcRthgBy1HfNO319mwhIAkg==",
"cpu": [
"arm64"
],
@@ -1106,19 +1106,19 @@
"darwin"
],
"engines": {
- "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ "node": ">=20.9.0"
},
"funding": {
"url": "https://opencollective.com/libvips"
},
"optionalDependencies": {
- "@img/sharp-libvips-darwin-arm64": "1.2.4"
+ "@img/sharp-libvips-darwin-arm64": "1.3.2"
}
},
"node_modules/@img/sharp-darwin-x64": {
- "version": "0.34.5",
- "resolved": "https://registry.npmjs.org/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.34.5.tgz",
- "integrity": "sha512-YNEFAF/4KQ/PeW0N+r+aVVsoIY0/qxxikF2SWdp+NRkmMB7y9LBZAVqQ4yhGCm/H3H270OSykqmQMKLBhBJDEw==",
+ "version": "0.35.3",
+ "resolved": "https://registry.npmjs.org/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.35.3.tgz",
+ "integrity": "sha512-Xo+5uFBtLN0BKqieTxiFzFPQAUlBbbH5iBKyRX/z1JrbnYsHTfKJnUfL8+p2TPXr1pXqao4eeL4Rl144uDpK9w==",
"cpu": [
"x64"
],
@@ -1128,19 +1128,38 @@
"darwin"
],
"engines": {
- "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ "node": ">=20.9.0"
},
"funding": {
"url": "https://opencollective.com/libvips"
},
"optionalDependencies": {
- "@img/sharp-libvips-darwin-x64": "1.2.4"
+ "@img/sharp-libvips-darwin-x64": "1.3.2"
+ }
+ },
+ "node_modules/@img/sharp-freebsd-wasm32": {
+ "version": "0.35.3",
+ "resolved": "https://registry.npmjs.org/@img/sharp-freebsd-wasm32/-/sharp-freebsd-wasm32-0.35.3.tgz",
+ "integrity": "sha512-lUxcqWIj2wMQ9BrwNjngcr1gWUr5xgaGThBRqPPalIC2n67Cqj1uPh8NnA/ZhAg8hUbKl+kVHKwgUIwe6ZYPrg==",
+ "license": "Apache-2.0",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "dependencies": {
+ "@img/sharp-wasm32": "0.35.3"
+ },
+ "engines": {
+ "node": ">=20.9.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
}
},
"node_modules/@img/sharp-libvips-darwin-arm64": {
- "version": "1.2.4",
- "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.2.4.tgz",
- "integrity": "sha512-zqjjo7RatFfFoP0MkQ51jfuFZBnVE2pRiaydKJ1G/rHZvnsrHAOcQALIi9sA5co5xenQdTugCvtb1cuf78Vf4g==",
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.3.2.tgz",
+ "integrity": "sha512-9J6ypZFpQBj4YnePGoq/S38w6nz+vqg5WZLrLGY4YuSemdMq47GMLBPO42MzwdGwpg/agZ7xzZcFHa48xlywfg==",
"cpu": [
"arm64"
],
@@ -1154,9 +1173,9 @@
}
},
"node_modules/@img/sharp-libvips-darwin-x64": {
- "version": "1.2.4",
- "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.2.4.tgz",
- "integrity": "sha512-1IOd5xfVhlGwX+zXv2N93k0yMONvUlANylbJw1eTah8K/Jtpi15KC+WSiaX/nBmbm2HxRM1gZ0nSdjSsrZbGKg==",
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.3.2.tgz",
+ "integrity": "sha512-m2pW1n6cns9VaubNwsZ+c3CRYjxNQWgJ5gPlnL1nbBcpkBvFm6SCFN5o0psFHI8w9n11NKhFkeEDns98tiqbEw==",
"cpu": [
"x64"
],
@@ -1170,9 +1189,9 @@
}
},
"node_modules/@img/sharp-libvips-linux-arm": {
- "version": "1.2.4",
- "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.2.4.tgz",
- "integrity": "sha512-bFI7xcKFELdiNCVov8e44Ia4u2byA+l3XtsAj+Q8tfCwO6BQ8iDojYdvoPMqsKDkuoOo+X6HZA0s0q11ANMQ8A==",
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.3.2.tgz",
+ "integrity": "sha512-1eMLzy92I4J6rmi4mAT8yC3HxOtniyGELlzGbNMLLeqe052ahFQ0h6LFq+lh5DsDIdYViIDst08abvSbcEdLXQ==",
"cpu": [
"arm"
],
@@ -1186,9 +1205,9 @@
}
},
"node_modules/@img/sharp-libvips-linux-arm64": {
- "version": "1.2.4",
- "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.2.4.tgz",
- "integrity": "sha512-excjX8DfsIcJ10x1Kzr4RcWe1edC9PquDRRPx3YVCvQv+U5p7Yin2s32ftzikXojb1PIFc/9Mt28/y+iRklkrw==",
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.3.2.tgz",
+ "integrity": "sha512-dqVSFynCox4C/J8kT16V7SIFAns0IjgLwkvYT7p8LQVmJ5OS5b6tI9IGflxTeuBS//zXeFIUbwt5dwxyZ17cnA==",
"cpu": [
"arm64"
],
@@ -1202,9 +1221,9 @@
}
},
"node_modules/@img/sharp-libvips-linux-ppc64": {
- "version": "1.2.4",
- "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-ppc64/-/sharp-libvips-linux-ppc64-1.2.4.tgz",
- "integrity": "sha512-FMuvGijLDYG6lW+b/UvyilUWu5Ayu+3r2d1S8notiGCIyYU/76eig1UfMmkZ7vwgOrzKzlQbFSuQfgm7GYUPpA==",
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-ppc64/-/sharp-libvips-linux-ppc64-1.3.2.tgz",
+ "integrity": "sha512-3z0NHDxD6n5I9gc05U1eW1AyRm+Gznzq3naMrthPNqE6oYykcogW0l/jfpJdjYnuNl8R7yI9pNbE1XiUeyq0Aw==",
"cpu": [
"ppc64"
],
@@ -1218,9 +1237,9 @@
}
},
"node_modules/@img/sharp-libvips-linux-riscv64": {
- "version": "1.2.4",
- "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-riscv64/-/sharp-libvips-linux-riscv64-1.2.4.tgz",
- "integrity": "sha512-oVDbcR4zUC0ce82teubSm+x6ETixtKZBh/qbREIOcI3cULzDyb18Sr/Wcyx7NRQeQzOiHTNbZFF1UwPS2scyGA==",
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-riscv64/-/sharp-libvips-linux-riscv64-1.3.2.tgz",
+ "integrity": "sha512-bsb4rI+NldGOsXuej2r8OdSS8+zXDVaCWxyWrcv6kneTOlgAHtZABRzBBCwdsPiD90J4myNJuHpg6kA20ImW/w==",
"cpu": [
"riscv64"
],
@@ -1234,9 +1253,9 @@
}
},
"node_modules/@img/sharp-libvips-linux-s390x": {
- "version": "1.2.4",
- "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.2.4.tgz",
- "integrity": "sha512-qmp9VrzgPgMoGZyPvrQHqk02uyjA0/QrTO26Tqk6l4ZV0MPWIW6LTkqOIov+J1yEu7MbFQaDpwdwJKhbJvuRxQ==",
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.3.2.tgz",
+ "integrity": "sha512-/ABshyj8gCpyIrNXnHn4LorDJ0HHm1VhXPBlxZ8zAtfVPAaSafXPGn+sUSIRiwaSBy0mmFjSjiXI5mkcwdChKQ==",
"cpu": [
"s390x"
],
@@ -1250,9 +1269,9 @@
}
},
"node_modules/@img/sharp-libvips-linux-x64": {
- "version": "1.2.4",
- "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.2.4.tgz",
- "integrity": "sha512-tJxiiLsmHc9Ax1bz3oaOYBURTXGIRDODBqhveVHonrHJ9/+k89qbLl0bcJns+e4t4rvaNBxaEZsFtSfAdquPrw==",
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.3.2.tgz",
+ "integrity": "sha512-ITPEtgffGJ0S6G9dRyw/366tJQqFRcHWPHhC+Stpg3Z8AEMrDrTr2lhdz4f/Y/HMbRh//7Z5mBzEpVdi62Oc3w==",
"cpu": [
"x64"
],
@@ -1266,9 +1285,9 @@
}
},
"node_modules/@img/sharp-libvips-linuxmusl-arm64": {
- "version": "1.2.4",
- "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.2.4.tgz",
- "integrity": "sha512-FVQHuwx1IIuNow9QAbYUzJ+En8KcVm9Lk5+uGUQJHaZmMECZmOlix9HnH7n1TRkXMS0pGxIJokIVB9SuqZGGXw==",
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.3.2.tgz",
+ "integrity": "sha512-zE9EdiUzUmg5mDT5a1rk5fYJ6GWPloTwWBYDS14naqHsL+EaMpDj1AWnpLgh3u0YCORv2Tt50wrcrpYqkP97Kw==",
"cpu": [
"arm64"
],
@@ -1282,9 +1301,9 @@
}
},
"node_modules/@img/sharp-libvips-linuxmusl-x64": {
- "version": "1.2.4",
- "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.2.4.tgz",
- "integrity": "sha512-+LpyBk7L44ZIXwz/VYfglaX/okxezESc6UxDSoyo2Ks6Jxc4Y7sGjpgU9s4PMgqgjj1gZCylTieNamqA1MF7Dg==",
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.3.2.tgz",
+ "integrity": "sha512-m0lrLiUt+lBYnCFr8qV/65yMR4E/c7/wf78I5eKTdkEakFAlZ9QlzEM3QIhhAwVeUhLAHLcCq7a7Vszq/oFNZQ==",
"cpu": [
"x64"
],
@@ -1298,9 +1317,9 @@
}
},
"node_modules/@img/sharp-linux-arm": {
- "version": "0.34.5",
- "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm/-/sharp-linux-arm-0.34.5.tgz",
- "integrity": "sha512-9dLqsvwtg1uuXBGZKsxem9595+ujv0sJ6Vi8wcTANSFpwV/GONat5eCkzQo/1O6zRIkh0m/8+5BjrRr7jDUSZw==",
+ "version": "0.35.3",
+ "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm/-/sharp-linux-arm-0.35.3.tgz",
+ "integrity": "sha512-affVWCTLooy8TSxbDx2qkzuDeaWLNVBA+P//FNBirHsXpP2fuBhk5AuboYUnrDnzoXes8GFjpTx0SBFOCRg+FA==",
"cpu": [
"arm"
],
@@ -1310,19 +1329,19 @@
"linux"
],
"engines": {
- "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ "node": ">=20.9.0"
},
"funding": {
"url": "https://opencollective.com/libvips"
},
"optionalDependencies": {
- "@img/sharp-libvips-linux-arm": "1.2.4"
+ "@img/sharp-libvips-linux-arm": "1.3.2"
}
},
"node_modules/@img/sharp-linux-arm64": {
- "version": "0.34.5",
- "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.34.5.tgz",
- "integrity": "sha512-bKQzaJRY/bkPOXyKx5EVup7qkaojECG6NLYswgktOZjaXecSAeCWiZwwiFf3/Y+O1HrauiE3FVsGxFg8c24rZg==",
+ "version": "0.35.3",
+ "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.35.3.tgz",
+ "integrity": "sha512-QgKDspHPnrU+GQ55XPhGwyhC8acLVOOSyAvo1oVfFmrIXLkDNmGWzAfDZ4xK8oSA1qBQrALcHX0G5UZni/SuFQ==",
"cpu": [
"arm64"
],
@@ -1332,19 +1351,19 @@
"linux"
],
"engines": {
- "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ "node": ">=20.9.0"
},
"funding": {
"url": "https://opencollective.com/libvips"
},
"optionalDependencies": {
- "@img/sharp-libvips-linux-arm64": "1.2.4"
+ "@img/sharp-libvips-linux-arm64": "1.3.2"
}
},
"node_modules/@img/sharp-linux-ppc64": {
- "version": "0.34.5",
- "resolved": "https://registry.npmjs.org/@img/sharp-linux-ppc64/-/sharp-linux-ppc64-0.34.5.tgz",
- "integrity": "sha512-7zznwNaqW6YtsfrGGDA6BRkISKAAE1Jo0QdpNYXNMHu2+0dTrPflTLNkpc8l7MUP5M16ZJcUvysVWWrMefZquA==",
+ "version": "0.35.3",
+ "resolved": "https://registry.npmjs.org/@img/sharp-linux-ppc64/-/sharp-linux-ppc64-0.35.3.tgz",
+ "integrity": "sha512-sMd8rDxmpLOwv/7N44klFjOD5DUO7FLdjiXDI0hoxYaf7Ar262dQIEkosE98bps+5HPLtp/EvNqeqQtOycP/IA==",
"cpu": [
"ppc64"
],
@@ -1354,19 +1373,19 @@
"linux"
],
"engines": {
- "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ "node": ">=20.9.0"
},
"funding": {
"url": "https://opencollective.com/libvips"
},
"optionalDependencies": {
- "@img/sharp-libvips-linux-ppc64": "1.2.4"
+ "@img/sharp-libvips-linux-ppc64": "1.3.2"
}
},
"node_modules/@img/sharp-linux-riscv64": {
- "version": "0.34.5",
- "resolved": "https://registry.npmjs.org/@img/sharp-linux-riscv64/-/sharp-linux-riscv64-0.34.5.tgz",
- "integrity": "sha512-51gJuLPTKa7piYPaVs8GmByo7/U7/7TZOq+cnXJIHZKavIRHAP77e3N2HEl3dgiqdD/w0yUfiJnII77PuDDFdw==",
+ "version": "0.35.3",
+ "resolved": "https://registry.npmjs.org/@img/sharp-linux-riscv64/-/sharp-linux-riscv64-0.35.3.tgz",
+ "integrity": "sha512-0Eob78yjlYPfL5vMNWAW55l3R9Y6BQS/gOfe0ZcP9mEz9ohhKSt4im1hayiknXgf8AWrFqMvJcKIdmLmEe7yeQ==",
"cpu": [
"riscv64"
],
@@ -1376,19 +1395,19 @@
"linux"
],
"engines": {
- "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ "node": ">=20.9.0"
},
"funding": {
"url": "https://opencollective.com/libvips"
},
"optionalDependencies": {
- "@img/sharp-libvips-linux-riscv64": "1.2.4"
+ "@img/sharp-libvips-linux-riscv64": "1.3.2"
}
},
"node_modules/@img/sharp-linux-s390x": {
- "version": "0.34.5",
- "resolved": "https://registry.npmjs.org/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.34.5.tgz",
- "integrity": "sha512-nQtCk0PdKfho3eC5MrbQoigJ2gd1CgddUMkabUj+rBevs8tZ2cULOx46E7oyX+04WGfABgIwmMC0VqieTiR4jg==",
+ "version": "0.35.3",
+ "resolved": "https://registry.npmjs.org/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.35.3.tgz",
+ "integrity": "sha512-KgAxQ0DxpNOq1rG2t5cgTgShJFGSuU7XO45cqC+1NVOuZnP6tlgZRuSYOfNupGkHID0o3cJOsw4DVeJpMovcGw==",
"cpu": [
"s390x"
],
@@ -1398,19 +1417,19 @@
"linux"
],
"engines": {
- "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ "node": ">=20.9.0"
},
"funding": {
"url": "https://opencollective.com/libvips"
},
"optionalDependencies": {
- "@img/sharp-libvips-linux-s390x": "1.2.4"
+ "@img/sharp-libvips-linux-s390x": "1.3.2"
}
},
"node_modules/@img/sharp-linux-x64": {
- "version": "0.34.5",
- "resolved": "https://registry.npmjs.org/@img/sharp-linux-x64/-/sharp-linux-x64-0.34.5.tgz",
- "integrity": "sha512-MEzd8HPKxVxVenwAa+JRPwEC7QFjoPWuS5NZnBt6B3pu7EG2Ge0id1oLHZpPJdn3OQK+BQDiw9zStiHBTJQQQQ==",
+ "version": "0.35.3",
+ "resolved": "https://registry.npmjs.org/@img/sharp-linux-x64/-/sharp-linux-x64-0.35.3.tgz",
+ "integrity": "sha512-8pqvxubL2PGdhlPy6GLqzDYMUjyRmKAwKHYKixpdJYBUK7PJ0C029XdsnpFIdgRZG68fZiGdHVWcKPvtiPB4cA==",
"cpu": [
"x64"
],
@@ -1420,19 +1439,19 @@
"linux"
],
"engines": {
- "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ "node": ">=20.9.0"
},
"funding": {
"url": "https://opencollective.com/libvips"
},
"optionalDependencies": {
- "@img/sharp-libvips-linux-x64": "1.2.4"
+ "@img/sharp-libvips-linux-x64": "1.3.2"
}
},
"node_modules/@img/sharp-linuxmusl-arm64": {
- "version": "0.34.5",
- "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.34.5.tgz",
- "integrity": "sha512-fprJR6GtRsMt6Kyfq44IsChVZeGN97gTD331weR1ex1c1rypDEABN6Tm2xa1wE6lYb5DdEnk03NZPqA7Id21yg==",
+ "version": "0.35.3",
+ "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.35.3.tgz",
+ "integrity": "sha512-Vz0iQjzzcSX3HCbfwFfCSG/9SCIqyO0mH2sXyiHaAYfBk0cRsCWXRyQYX0ovCK/PAQBbTzQ0dsPQHh5MAFL59w==",
"cpu": [
"arm64"
],
@@ -1442,19 +1461,19 @@
"linux"
],
"engines": {
- "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ "node": ">=20.9.0"
},
"funding": {
"url": "https://opencollective.com/libvips"
},
"optionalDependencies": {
- "@img/sharp-libvips-linuxmusl-arm64": "1.2.4"
+ "@img/sharp-libvips-linuxmusl-arm64": "1.3.2"
}
},
"node_modules/@img/sharp-linuxmusl-x64": {
- "version": "0.34.5",
- "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.34.5.tgz",
- "integrity": "sha512-Jg8wNT1MUzIvhBFxViqrEhWDGzqymo3sV7z7ZsaWbZNDLXRJZoRGrjulp60YYtV4wfY8VIKcWidjojlLcWrd8Q==",
+ "version": "0.35.3",
+ "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.35.3.tgz",
+ "integrity": "sha512-6O1NPKcDVj9QEdg7Hx549EX8U0rp6yXQERqru6yRN7fGBn32UvIRJUlWnk+8xDCiG76hXVBbX82NZ/ZKr0euIg==",
"cpu": [
"x64"
],
@@ -1464,38 +1483,54 @@
"linux"
],
"engines": {
- "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ "node": ">=20.9.0"
},
"funding": {
"url": "https://opencollective.com/libvips"
},
"optionalDependencies": {
- "@img/sharp-libvips-linuxmusl-x64": "1.2.4"
+ "@img/sharp-libvips-linuxmusl-x64": "1.3.2"
}
},
"node_modules/@img/sharp-wasm32": {
- "version": "0.34.5",
- "resolved": "https://registry.npmjs.org/@img/sharp-wasm32/-/sharp-wasm32-0.34.5.tgz",
- "integrity": "sha512-OdWTEiVkY2PHwqkbBI8frFxQQFekHaSSkUIJkwzclWZe64O1X4UlUjqqqLaPbUpMOQk6FBu/HtlGXNblIs0huw==",
+ "version": "0.35.3",
+ "resolved": "https://registry.npmjs.org/@img/sharp-wasm32/-/sharp-wasm32-0.35.3.tgz",
+ "integrity": "sha512-cZ0XkcYGpHZkqW6iCkqTcmUC0CD9DhD5d/qeZlZkfRBn6GnHniZXLUo5+9xw8Iv76YE6LQFN9YNBlKREcCG76w==",
+ "license": "Apache-2.0 AND LGPL-3.0-or-later AND MIT",
+ "optional": true,
+ "dependencies": {
+ "@emnapi/runtime": "^1.11.1"
+ },
+ "engines": {
+ "node": ">=20.9.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ }
+ },
+ "node_modules/@img/sharp-webcontainers-wasm32": {
+ "version": "0.35.3",
+ "resolved": "https://registry.npmjs.org/@img/sharp-webcontainers-wasm32/-/sharp-webcontainers-wasm32-0.35.3.tgz",
+ "integrity": "sha512-2rnq7bX3NzeR2T4YWgz8qiG4h3TSdMe+vN1iQXpJleSJ3SM5zQ8Fy2SyyXAWlbxpEZ2Y+Z4u1BePgJEYbSy80Q==",
"cpu": [
"wasm32"
],
- "license": "Apache-2.0 AND LGPL-3.0-or-later AND MIT",
+ "license": "Apache-2.0",
"optional": true,
"dependencies": {
- "@emnapi/runtime": "^1.7.0"
+ "@img/sharp-wasm32": "0.35.3"
},
"engines": {
- "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ "node": ">=20.9.0"
},
"funding": {
"url": "https://opencollective.com/libvips"
}
},
"node_modules/@img/sharp-win32-arm64": {
- "version": "0.34.5",
- "resolved": "https://registry.npmjs.org/@img/sharp-win32-arm64/-/sharp-win32-arm64-0.34.5.tgz",
- "integrity": "sha512-WQ3AgWCWYSb2yt+IG8mnC6Jdk9Whs7O0gxphblsLvdhSpSTtmu69ZG1Gkb6NuvxsNACwiPV6cNSZNzt0KPsw7g==",
+ "version": "0.35.3",
+ "resolved": "https://registry.npmjs.org/@img/sharp-win32-arm64/-/sharp-win32-arm64-0.35.3.tgz",
+ "integrity": "sha512-4bPwFdMbeC4JQ8L8LOyWp6nsHcboP5fxkp6iPOXz2Vg49R42TuMs2whkJ5OAP4/Ul035qOzy0AecOF9VOscn4w==",
"cpu": [
"arm64"
],
@@ -1505,16 +1540,16 @@
"win32"
],
"engines": {
- "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ "node": ">=20.9.0"
},
"funding": {
"url": "https://opencollective.com/libvips"
}
},
"node_modules/@img/sharp-win32-ia32": {
- "version": "0.34.5",
- "resolved": "https://registry.npmjs.org/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.34.5.tgz",
- "integrity": "sha512-FV9m/7NmeCmSHDD5j4+4pNI8Cp3aW+JvLoXcTUo0IqyjSfAZJ8dIUmijx1qaJsIiU+Hosw6xM5KijAWRJCSgNg==",
+ "version": "0.35.3",
+ "resolved": "https://registry.npmjs.org/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.35.3.tgz",
+ "integrity": "sha512-r53mXsBN6lFUDiST764SvgwUdHAqM4rPAiDzAmf4fLoB6X/rkfyTrLCg6+g17wJJiCmB3JYgHuUldCWUIRFSXw==",
"cpu": [
"ia32"
],
@@ -1524,16 +1559,16 @@
"win32"
],
"engines": {
- "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ "node": "^20.9.0"
},
"funding": {
"url": "https://opencollective.com/libvips"
}
},
"node_modules/@img/sharp-win32-x64": {
- "version": "0.34.5",
- "resolved": "https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.34.5.tgz",
- "integrity": "sha512-+29YMsqY2/9eFEiW93eqWnuLcWcufowXewwSNIT6UwZdUUCrM3oFjMWH/Z6/TMmb4hlFenmfAVbpWeup2jryCw==",
+ "version": "0.35.3",
+ "resolved": "https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.35.3.tgz",
+ "integrity": "sha512-D4y1vNeZrIIJCN+uHaWVtH86B+aCrdMYYjicy9pXHvbGZeGYLLSd3wdVuC37FxVXlU1ARsk84eKWfWMXGYEqvA==",
"cpu": [
"x64"
],
@@ -1543,7 +1578,7 @@
"win32"
],
"engines": {
- "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ "node": ">=20.9.0"
},
"funding": {
"url": "https://opencollective.com/libvips"
@@ -1676,9 +1711,9 @@
}
},
"node_modules/@next/env": {
- "version": "16.2.9",
- "resolved": "https://registry.npmjs.org/@next/env/-/env-16.2.9.tgz",
- "integrity": "sha512-ki5VxxXfzD/9TDe13wyeTKIjQTAwBVpnr8KhRDUr8ltMUq1/NBpWNT5tiPoxiGl+PHM4X2ahSOiPk6iAimIzPg==",
+ "version": "16.2.11",
+ "resolved": "https://registry.npmjs.org/@next/env/-/env-16.2.11.tgz",
+ "integrity": "sha512-0do5A3BJ2gxWr0ZCMcD6BhW+e595jyxdTl3rXTS6lOtD8ektMiW6CO+EPwt1Eca1DBnm90r/7GdiKWBKxH++DA==",
"license": "MIT"
},
"node_modules/@next/eslint-plugin-next": {
@@ -1692,9 +1727,9 @@
}
},
"node_modules/@next/swc-darwin-arm64": {
- "version": "16.2.9",
- "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-16.2.9.tgz",
- "integrity": "sha512-HkfxNYUCmcct0Xsqib5KxqMSHV4AHJq857BNRchyBDs4YS19aHzVfn1kDuBYKqLLQBjXgnkIsjV2Kd4d2wzYhw==",
+ "version": "16.2.11",
+ "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-16.2.11.tgz",
+ "integrity": "sha512-wryL4pjKmDwGv2ox6+GZDFxvmtSRLqApBR8kL1j4+vhB7Z5vJC/zAnXpiR9Xkfzl0AS8WLMnsuGV/UKI67/rrw==",
"cpu": [
"arm64"
],
@@ -1708,9 +1743,9 @@
}
},
"node_modules/@next/swc-darwin-x64": {
- "version": "16.2.9",
- "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-16.2.9.tgz",
- "integrity": "sha512-7IAtK4MeybpqRV9GRABWEhJ62mOS+rzWOzOTFie4cSEtm12xsoOMJRcECoZx3FHPzFAqN/IJtHqWAFOLfl152w==",
+ "version": "16.2.11",
+ "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-16.2.11.tgz",
+ "integrity": "sha512-aZl2j4f/fLyjQvOhv0Oe9UaMAQHolYpKhctsoYzplSumKJKPUmgjcf6545aBtysLTcu994TREd0+pSgNE4ohmg==",
"cpu": [
"x64"
],
@@ -1724,9 +1759,9 @@
}
},
"node_modules/@next/swc-linux-arm64-gnu": {
- "version": "16.2.9",
- "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-16.2.9.tgz",
- "integrity": "sha512-hBD75iWpUtkL9SmQmcRhmLomn9jgkPzCEkbOcLgHymPEKzv+6ONy13RRiIEz/iEObjkS2Jlb5gYS2XGoS3X4rw==",
+ "version": "16.2.11",
+ "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-16.2.11.tgz",
+ "integrity": "sha512-5jEriyEnH/LWFy27L2ZG0XaLlyEJIjhsImEsiS9P563PKEVp2BVups/xfOucIrsvVntp11oNcZwjHvaDPYVB5g==",
"cpu": [
"arm64"
],
@@ -1740,9 +1775,9 @@
}
},
"node_modules/@next/swc-linux-arm64-musl": {
- "version": "16.2.9",
- "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-16.2.9.tgz",
- "integrity": "sha512-qZTI3pf9SGc/obr8NkQAekBxmp1QK+kVm+VAf3BALLfFAj+1kUhkTxmrWpVos9R/UYIA8AWX2p6cGI5WdwzVUA==",
+ "version": "16.2.11",
+ "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-16.2.11.tgz",
+ "integrity": "sha512-eIjcpx2fnnFSSkZDbTxy74KnokUXDjfoLClpWelfgHLf621aTqswhwXQ7GkD5K5rplrS6LZ/Bj+mVuvzluBOEg==",
"cpu": [
"arm64"
],
@@ -1756,9 +1791,9 @@
}
},
"node_modules/@next/swc-linux-x64-gnu": {
- "version": "16.2.9",
- "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-16.2.9.tgz",
- "integrity": "sha512-xm0HfRNX+UkH4R3c18ynswjj5o5uEj/7iI9p9omdtTSIsRCzQqkGMA+10nzJ4EHnYC3as65IMhbbl5fWRUWHYg==",
+ "version": "16.2.11",
+ "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-16.2.11.tgz",
+ "integrity": "sha512-8WgzpaWMs46qJT9kiV47cje86L0x/Mu9t8/Gwj+pnbgW3rETVfCnaScPjlYUwNScpOozdcIMHWmAvuZJUonR2w==",
"cpu": [
"x64"
],
@@ -1772,9 +1807,9 @@
}
},
"node_modules/@next/swc-linux-x64-musl": {
- "version": "16.2.9",
- "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-16.2.9.tgz",
- "integrity": "sha512-QumimHkGEG6vM3PfEDWKyKen03NcqLOkeKB1EfcPe7VxzmEiCa4jNnMyBn/US5zcd/VE1CI+O8Ovb3lfjVHfGw==",
+ "version": "16.2.11",
+ "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-16.2.11.tgz",
+ "integrity": "sha512-I3UgPds7G4ZYnTb/H+5GBGuUT2DhAk6j0mL6A4s63RjFs74wB2hOWP0vaxsK+3NJraExt3eYEPQ/UtT0x/64Nw==",
"cpu": [
"x64"
],
@@ -1788,9 +1823,9 @@
}
},
"node_modules/@next/swc-win32-arm64-msvc": {
- "version": "16.2.9",
- "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-16.2.9.tgz",
- "integrity": "sha512-hzQpKZvw8rAwI6A2uQh6SacCSvNAXaIkPNsWwzqqfRiIMiXMfH936skDhz1OO6KpvdKkJrgHHtqQOq5PIXOvdQ==",
+ "version": "16.2.11",
+ "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-16.2.11.tgz",
+ "integrity": "sha512-n89CjtcThnjrwgJMAiI5xbqwLY51zvwC9tSlArmVndAJLYVl9T9UAdlkXTmZvE++idoXe8KdglQlhNRdUp1c6g==",
"cpu": [
"arm64"
],
@@ -1804,9 +1839,9 @@
}
},
"node_modules/@next/swc-win32-x64-msvc": {
- "version": "16.2.9",
- "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-16.2.9.tgz",
- "integrity": "sha512-qr2VL3Ce5QrwgO2yh1ujSBawrimjVKX8FGF/cOynmdYKJY0BdHpGVNIRK1tqONB10Vkm25Ub1BD2bkjWs4+96w==",
+ "version": "16.2.11",
+ "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-16.2.11.tgz",
+ "integrity": "sha512-md8CLNggS1Dx9pUgApzps5uAf+N8GN9xywzmNx9vHAWo94HtBwCCqkSnhIrdfQe83Dhz8Lfo/20Nb1Zxal092w==",
"cpu": [
"x64"
],
@@ -1820,9 +1855,9 @@
}
},
"node_modules/@nodable/entities": {
- "version": "2.2.0",
- "resolved": "https://registry.npmjs.org/@nodable/entities/-/entities-2.2.0.tgz",
- "integrity": "sha512-9uGyhaQavEUMC8AIddIjau4NsnsXhou+j5sBAGojCM1oxmQpVKTWR/9JxABD6UAv12vpIms55fPZKFQEhG6uBg==",
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/@nodable/entities/-/entities-3.0.0.tgz",
+ "integrity": "sha512-8L9xFeTYKhm49xfIypoe2W5wV1m/3Z58kT+7kR9A8OyFxcPduI4VmxaUMQyKYrRjUoLLSXv6EKKID5Tvj9cUVw==",
"funding": [
{
"type": "github",
@@ -3776,16 +3811,16 @@
}
},
"node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": {
- "version": "5.0.6",
- "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.6.tgz",
- "integrity": "sha512-kLpxurY4Z4r9sgMsyG0Z9uzsBlgiU/EFKhj/h91/8yHu0edo7XuixOIH3VcJ8kkxs6/jPzoI6U9Vj3WqbMQ94g==",
+ "version": "5.0.8",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.8.tgz",
+ "integrity": "sha512-JZyDyq3D4AUifKTPOB7DELf6XsB3WdPuNxCtob1vFXPsSXhdAiHBWJ/tJ8HAc9aH84BK+5JFZLNkJKx3G9kzQg==",
"dev": true,
"license": "MIT",
"dependencies": {
"balanced-match": "^4.0.2"
},
"engines": {
- "node": "18 || 20 || >=22"
+ "node": "20 || >=22"
}
},
"node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": {
@@ -4830,9 +4865,9 @@
}
},
"node_modules/brace-expansion": {
- "version": "1.1.15",
- "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.15.tgz",
- "integrity": "sha512-EwOCDEex4quD37XhqM3omwtMoJjr//isUZz1JopUNWms+4Z2ViyM/k1YIRePpoVNnQhENnxtFjLaxNHrT7xIUg==",
+ "version": "1.1.16",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.16.tgz",
+ "integrity": "sha512-IDw48K2/2kRkg9LdJxurvq3lV3aBgq0REY89duEqFRthjlPdXHKMj7EnQOXVckxzgisinf3nHfrcE2FufFLXMw==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -5919,9 +5954,9 @@
}
},
"node_modules/dompurify": {
- "version": "3.4.11",
- "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.4.11.tgz",
- "integrity": "sha512-zhlUV12GsaRzMsf9q5M254YhA4+VuF0fG+QFqu6aYpoGlKtz+w8//jBcGVYBgQkR5GHjUomejY84AV+/uPbWdw==",
+ "version": "3.4.12",
+ "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.4.12.tgz",
+ "integrity": "sha512-zQvGet8Z2sWbQhCmfFz/T5QWH2oBmjnqK3qvOjaqaNLrLEF912WamU+ohnTp0TCep/MFVHpdJuCZEdFOdTnEFg==",
"license": "(MPL-2.0 OR Apache-2.0)",
"optionalDependencies": {
"@types/trusted-types": "^2.0.7"
@@ -6228,9 +6263,9 @@
}
},
"node_modules/esbuild": {
- "version": "0.27.7",
- "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.27.7.tgz",
- "integrity": "sha512-IxpibTjyVnmrIQo5aqNpCgoACA/dTKLTlhMHihVHhdkxKyPO1uBBthumT0rdHmcsk9uMonIWS0m4FljWzILh3w==",
+ "version": "0.28.1",
+ "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.28.1.tgz",
+ "integrity": "sha512-HrJrvZv5ayxBzPfwphOoNzkzOIIlifzk0KJrGK2c8R4+LKpMtpYLQeUdjnwjWv/LZlkH2laZk+4w78pi99D4Vw==",
"hasInstallScript": true,
"license": "MIT",
"bin": {
@@ -6240,32 +6275,32 @@
"node": ">=18"
},
"optionalDependencies": {
- "@esbuild/aix-ppc64": "0.27.7",
- "@esbuild/android-arm": "0.27.7",
- "@esbuild/android-arm64": "0.27.7",
- "@esbuild/android-x64": "0.27.7",
- "@esbuild/darwin-arm64": "0.27.7",
- "@esbuild/darwin-x64": "0.27.7",
- "@esbuild/freebsd-arm64": "0.27.7",
- "@esbuild/freebsd-x64": "0.27.7",
- "@esbuild/linux-arm": "0.27.7",
- "@esbuild/linux-arm64": "0.27.7",
- "@esbuild/linux-ia32": "0.27.7",
- "@esbuild/linux-loong64": "0.27.7",
- "@esbuild/linux-mips64el": "0.27.7",
- "@esbuild/linux-ppc64": "0.27.7",
- "@esbuild/linux-riscv64": "0.27.7",
- "@esbuild/linux-s390x": "0.27.7",
- "@esbuild/linux-x64": "0.27.7",
- "@esbuild/netbsd-arm64": "0.27.7",
- "@esbuild/netbsd-x64": "0.27.7",
- "@esbuild/openbsd-arm64": "0.27.7",
- "@esbuild/openbsd-x64": "0.27.7",
- "@esbuild/openharmony-arm64": "0.27.7",
- "@esbuild/sunos-x64": "0.27.7",
- "@esbuild/win32-arm64": "0.27.7",
- "@esbuild/win32-ia32": "0.27.7",
- "@esbuild/win32-x64": "0.27.7"
+ "@esbuild/aix-ppc64": "0.28.1",
+ "@esbuild/android-arm": "0.28.1",
+ "@esbuild/android-arm64": "0.28.1",
+ "@esbuild/android-x64": "0.28.1",
+ "@esbuild/darwin-arm64": "0.28.1",
+ "@esbuild/darwin-x64": "0.28.1",
+ "@esbuild/freebsd-arm64": "0.28.1",
+ "@esbuild/freebsd-x64": "0.28.1",
+ "@esbuild/linux-arm": "0.28.1",
+ "@esbuild/linux-arm64": "0.28.1",
+ "@esbuild/linux-ia32": "0.28.1",
+ "@esbuild/linux-loong64": "0.28.1",
+ "@esbuild/linux-mips64el": "0.28.1",
+ "@esbuild/linux-ppc64": "0.28.1",
+ "@esbuild/linux-riscv64": "0.28.1",
+ "@esbuild/linux-s390x": "0.28.1",
+ "@esbuild/linux-x64": "0.28.1",
+ "@esbuild/netbsd-arm64": "0.28.1",
+ "@esbuild/netbsd-x64": "0.28.1",
+ "@esbuild/openbsd-arm64": "0.28.1",
+ "@esbuild/openbsd-x64": "0.28.1",
+ "@esbuild/openharmony-arm64": "0.28.1",
+ "@esbuild/sunos-x64": "0.28.1",
+ "@esbuild/win32-arm64": "0.28.1",
+ "@esbuild/win32-ia32": "0.28.1",
+ "@esbuild/win32-x64": "0.28.1"
}
},
"node_modules/escalade": {
@@ -6869,9 +6904,9 @@
"license": "MIT"
},
"node_modules/fast-uri": {
- "version": "3.1.2",
- "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.2.tgz",
- "integrity": "sha512-rVjf7ArG3LTk+FS6Yw81V1DLuZl1bRbNrev6Tmd/9RaroeeRRJhAt7jg/6YFxbvAQXUCavSoZhPPj6oOx+5KjQ==",
+ "version": "3.1.4",
+ "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.4.tgz",
+ "integrity": "sha512-8JnbkQ4juDyvYs4mgFGQqg4yCYtFDtUtmp2QIQq11ZZe5CFQ5wcqm1rqDgAh/QdMySuBnPzMUiJUNZG5N/AiQw==",
"funding": [
{
"type": "github",
@@ -6901,9 +6936,9 @@
}
},
"node_modules/fast-xml-parser": {
- "version": "5.9.3",
- "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-5.9.3.tgz",
- "integrity": "sha512-brCNCeScma/kqa54J4PIDriSSSLssRkuYaUCpvHJulGc3HGI/xxKUCTDcYkAdqJsyb//ydpbxecjC3hB9+tb/g==",
+ "version": "5.10.1",
+ "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-5.10.1.tgz",
+ "integrity": "sha512-IEMIf7298kXuZSRFoGfMYrl7is8LpavODgbNz1cwIudv7KwVFnuU+UsMporfq6PD6aXSlawZlARiA3UywCTfMw==",
"funding": [
{
"type": "github",
@@ -6912,17 +6947,32 @@
],
"license": "MIT",
"dependencies": {
- "@nodable/entities": "^2.2.0",
+ "@nodable/entities": "^3.0.0",
"fast-xml-builder": "^1.2.0",
- "is-unsafe": "^1.0.1",
- "path-expression-matcher": "^1.5.0",
+ "is-unsafe": "^2.0.0",
+ "path-expression-matcher": "^1.6.2",
"strnum": "^2.4.1",
- "xml-naming": "^0.1.0"
+ "xml-naming": "^0.3.0"
},
"bin": {
"fxparser": "src/cli/cli.js"
}
},
+ "node_modules/fast-xml-parser/node_modules/xml-naming": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/xml-naming/-/xml-naming-0.3.0.tgz",
+ "integrity": "sha512-ghig2TBE/H11aOVgmahA3MhimvkBr6JIYknH/Dhdk10nXwdbIqBJsbfMxpvFPG8bAw77gN29aQWvKpmVoPlvPQ==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/NaturalIntelligence"
+ }
+ ],
+ "license": "MIT",
+ "engines": {
+ "node": ">=16.0.0"
+ }
+ },
"node_modules/fastq": {
"version": "1.20.1",
"resolved": "https://registry.npmjs.org/fastq/-/fastq-1.20.1.tgz",
@@ -8270,9 +8320,9 @@
}
},
"node_modules/is-unsafe": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/is-unsafe/-/is-unsafe-1.0.1.tgz",
- "integrity": "sha512-CLK2+VdgERgD96EYm5lUQssZYlRg2tkZnbsxZoacmSiRxiFJ4Nk4SzjCl+Ur+v3kXIY9dTIdb3IH22y1mZ56LA==",
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/is-unsafe/-/is-unsafe-2.0.0.tgz",
+ "integrity": "sha512-2LdV822R+wmI86unXA93WCFpL6g+av8ynWk0nrHyJqGop5VoocYsSLFgN8jrfalT6iGeLNM4KXuVSsULP53kEA==",
"funding": [
{
"type": "github",
@@ -8408,9 +8458,9 @@
"license": "MIT"
},
"node_modules/js-yaml": {
- "version": "4.2.0",
- "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.2.0.tgz",
- "integrity": "sha512-ePWsvanv0DWuDRsW8dnt+R4jQ31SCRCQ7hhNcPXZPsoBZiemuZNYGf7adZdqX2D86j6rvKp3RpCxVTSb8WQlOw==",
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.3.0.tgz",
+ "integrity": "sha512-1td788aAnnZ5qs7V2QIRl1owjtYpbKt749Y3xauqQgwIIGF/xXWz1wMTEBx5O3LK3lXLVuqXPdPxj2BoFHaW9Q==",
"funding": [
{
"type": "github",
@@ -10215,13 +10265,13 @@
"license": "MIT"
},
"node_modules/next": {
- "version": "16.2.9",
- "resolved": "https://registry.npmjs.org/next/-/next-16.2.9.tgz",
- "integrity": "sha512-MEOJiq/UvuezAdqVSceHbqDgZt1kDw2tpGVOlsdIoJsQdbN2JY2hpVG4xnXGkbdJUOEWhnRfiu/O4Hpc9Juwww==",
+ "version": "16.2.11",
+ "resolved": "https://registry.npmjs.org/next/-/next-16.2.11.tgz",
+ "integrity": "sha512-B339zaqbyK8cmxhoAvLrcwoabwCP1wz21zSzfqxqXAemTu2BXnH7tQnfcglKv1vnMUIDBc+Hth7XODQriTZiRQ==",
"license": "MIT",
"peer": true,
"dependencies": {
- "@next/env": "16.2.9",
+ "@next/env": "16.2.11",
"@swc/helpers": "0.5.15",
"baseline-browser-mapping": "^2.9.19",
"caniuse-lite": "^1.0.30001579",
@@ -10235,14 +10285,14 @@
"node": ">=20.9.0"
},
"optionalDependencies": {
- "@next/swc-darwin-arm64": "16.2.9",
- "@next/swc-darwin-x64": "16.2.9",
- "@next/swc-linux-arm64-gnu": "16.2.9",
- "@next/swc-linux-arm64-musl": "16.2.9",
- "@next/swc-linux-x64-gnu": "16.2.9",
- "@next/swc-linux-x64-musl": "16.2.9",
- "@next/swc-win32-arm64-msvc": "16.2.9",
- "@next/swc-win32-x64-msvc": "16.2.9",
+ "@next/swc-darwin-arm64": "16.2.11",
+ "@next/swc-darwin-x64": "16.2.11",
+ "@next/swc-linux-arm64-gnu": "16.2.11",
+ "@next/swc-linux-arm64-musl": "16.2.11",
+ "@next/swc-linux-x64-gnu": "16.2.11",
+ "@next/swc-linux-x64-musl": "16.2.11",
+ "@next/swc-win32-arm64-msvc": "16.2.11",
+ "@next/swc-win32-x64-msvc": "16.2.11",
"sharp": "^0.34.5"
},
"peerDependencies": {
@@ -10599,9 +10649,9 @@
}
},
"node_modules/path-expression-matcher": {
- "version": "1.6.0",
- "resolved": "https://registry.npmjs.org/path-expression-matcher/-/path-expression-matcher-1.6.0.tgz",
- "integrity": "sha512-e5y7RCLHKjemsgQ4eqGJtPyr10ILz25HO7flzxhTV8bgvd5yHx98DGtCAtbVW9f2TqnYI/gEVZd+vz7snrdPTw==",
+ "version": "1.6.2",
+ "resolved": "https://registry.npmjs.org/path-expression-matcher/-/path-expression-matcher-1.6.2.tgz",
+ "integrity": "sha512-enSlaiat05iasnzmgNxRj8reFdj3puY2QpNgP1aPIaVfT6nn9ICuPoFlKHk8EN22HcwewshO+mN2DGbkCEOtqQ==",
"funding": [
{
"type": "github",
@@ -11521,48 +11571,53 @@
}
},
"node_modules/sharp": {
- "version": "0.34.5",
- "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.34.5.tgz",
- "integrity": "sha512-Ou9I5Ft9WNcCbXrU9cMgPBcCK8LiwLqcbywW3t4oDV37n1pzpuNLsYiAV8eODnjbtQlSDwZ2cUEeQz4E54Hltg==",
- "hasInstallScript": true,
+ "version": "0.35.3",
+ "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.35.3.tgz",
+ "integrity": "sha512-ej0zVHuZGHCiABXcNxeYhpRnPNPAcvbG8RMdBAhDAxLKkCRVSpK3Iyu7qbqw3JMzoj0REeM6f3tJLtVwl0023Q==",
"license": "Apache-2.0",
"optional": true,
"dependencies": {
- "@img/colour": "^1.0.0",
+ "@img/colour": "^1.1.0",
"detect-libc": "^2.1.2",
- "semver": "^7.7.3"
+ "semver": "^7.8.5"
},
"engines": {
- "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ "node": ">=20.9.0"
},
"funding": {
"url": "https://opencollective.com/libvips"
},
"optionalDependencies": {
- "@img/sharp-darwin-arm64": "0.34.5",
- "@img/sharp-darwin-x64": "0.34.5",
- "@img/sharp-libvips-darwin-arm64": "1.2.4",
- "@img/sharp-libvips-darwin-x64": "1.2.4",
- "@img/sharp-libvips-linux-arm": "1.2.4",
- "@img/sharp-libvips-linux-arm64": "1.2.4",
- "@img/sharp-libvips-linux-ppc64": "1.2.4",
- "@img/sharp-libvips-linux-riscv64": "1.2.4",
- "@img/sharp-libvips-linux-s390x": "1.2.4",
- "@img/sharp-libvips-linux-x64": "1.2.4",
- "@img/sharp-libvips-linuxmusl-arm64": "1.2.4",
- "@img/sharp-libvips-linuxmusl-x64": "1.2.4",
- "@img/sharp-linux-arm": "0.34.5",
- "@img/sharp-linux-arm64": "0.34.5",
- "@img/sharp-linux-ppc64": "0.34.5",
- "@img/sharp-linux-riscv64": "0.34.5",
- "@img/sharp-linux-s390x": "0.34.5",
- "@img/sharp-linux-x64": "0.34.5",
- "@img/sharp-linuxmusl-arm64": "0.34.5",
- "@img/sharp-linuxmusl-x64": "0.34.5",
- "@img/sharp-wasm32": "0.34.5",
- "@img/sharp-win32-arm64": "0.34.5",
- "@img/sharp-win32-ia32": "0.34.5",
- "@img/sharp-win32-x64": "0.34.5"
+ "@img/sharp-darwin-arm64": "0.35.3",
+ "@img/sharp-darwin-x64": "0.35.3",
+ "@img/sharp-freebsd-wasm32": "0.35.3",
+ "@img/sharp-libvips-darwin-arm64": "1.3.2",
+ "@img/sharp-libvips-darwin-x64": "1.3.2",
+ "@img/sharp-libvips-linux-arm": "1.3.2",
+ "@img/sharp-libvips-linux-arm64": "1.3.2",
+ "@img/sharp-libvips-linux-ppc64": "1.3.2",
+ "@img/sharp-libvips-linux-riscv64": "1.3.2",
+ "@img/sharp-libvips-linux-s390x": "1.3.2",
+ "@img/sharp-libvips-linux-x64": "1.3.2",
+ "@img/sharp-libvips-linuxmusl-arm64": "1.3.2",
+ "@img/sharp-libvips-linuxmusl-x64": "1.3.2",
+ "@img/sharp-linux-arm": "0.35.3",
+ "@img/sharp-linux-arm64": "0.35.3",
+ "@img/sharp-linux-ppc64": "0.35.3",
+ "@img/sharp-linux-riscv64": "0.35.3",
+ "@img/sharp-linux-s390x": "0.35.3",
+ "@img/sharp-linux-x64": "0.35.3",
+ "@img/sharp-linuxmusl-arm64": "0.35.3",
+ "@img/sharp-linuxmusl-x64": "0.35.3",
+ "@img/sharp-webcontainers-wasm32": "0.35.3",
+ "@img/sharp-win32-arm64": "0.35.3",
+ "@img/sharp-win32-ia32": "0.35.3",
+ "@img/sharp-win32-x64": "0.35.3"
+ },
+ "peerDependenciesMeta": {
+ "@types/node": {
+ "optional": true
+ }
}
},
"node_modules/sharp/node_modules/semver": {
diff --git a/docs/package.json b/docs/package.json
index 6c7dc70..2fd939b 100644
--- a/docs/package.json
+++ b/docs/package.json
@@ -41,10 +41,12 @@
"typescript": "^5.9.3"
},
"overrides": {
- "dompurify": "^3.4.11",
+ "dompurify": "^3.4.12",
"uuid": "^11.1.1",
- "fast-uri": "^3.1.2",
- "fast-xml-parser": "^5.7.0",
+ "fast-uri": "^3.1.4",
+ "fast-xml-parser": "^5.10.1",
+ "esbuild": "^0.28.1",
+ "sharp": "^0.35.3",
"next": {
"postcss": "^8.5.10"
}
diff --git a/docs/src/components/status-tag.tsx b/docs/src/components/status-tag.tsx
index 3feb762..f7991b1 100644
--- a/docs/src/components/status-tag.tsx
+++ b/docs/src/components/status-tag.tsx
@@ -1,4 +1,5 @@
const statusStyles: Record = {
+ 'Awaiting Connection': { bg: 'rgba(59, 130, 246, 0.15)', text: '#3b82f6' },
Standby: { bg: 'rgba(168, 85, 247, 0.15)', text: '#a855f7' },
Unreachable: { bg: 'rgba(239, 68, 68, 0.15)', text: '#ef4444' },
Deprecated: { bg: 'rgba(249, 115, 22, 0.15)', text: '#f97316' },
diff --git a/package-lock.json b/package-lock.json
index 3b22f36..3f5b74e 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -32,7 +32,7 @@
"prettier": "3.6.2",
"prettier-plugin-svelte": "^3.3.3",
"prettier-plugin-tailwindcss": "^0.6.11",
- "sharp": "^0.34.5",
+ "sharp": "^0.35.3",
"svelte": "^5.55.7",
"svelte-check": "^4.0.0",
"tailwindcss": "^3.4.17",
@@ -55,9 +55,9 @@
}
},
"node_modules/@emnapi/runtime": {
- "version": "1.11.1",
- "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.11.1.tgz",
- "integrity": "sha512-vgj7R3y3Wgx24IQaGPA/R6YFXLHVMOZ0uVEyIQPaWs+rd1AzfEMXlAC22FYwO1XkKR6NPsq7mUandH8oIRdZFw==",
+ "version": "1.11.2",
+ "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.11.2.tgz",
+ "integrity": "sha512-kyOl3X0DuTiT1h2ft8r2fYO8JYtU9a9Xis/zBSiGArNaagCOWx90N1k2wxp18czFDH+OgcWGb5ZP/XMt3dcyPA==",
"dev": true,
"license": "MIT",
"optional": true,
@@ -66,9 +66,9 @@
}
},
"node_modules/@esbuild/aix-ppc64": {
- "version": "0.27.7",
- "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.27.7.tgz",
- "integrity": "sha512-EKX3Qwmhz1eMdEJokhALr0YiD0lhQNwDqkPYyPhiSwKrh7/4KRjQc04sZ8db+5DVVnZ1LmbNDI1uAMPEUBnQPg==",
+ "version": "0.28.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.28.1.tgz",
+ "integrity": "sha512-Svl7tq8k/08+p6CXPpRjQ1fKX+1odH/BQbb48fV6fj3CWHhsoIOoY87w1oHXm0qEpkIK3ZfVgp0hed3XBXzXMQ==",
"cpu": [
"ppc64"
],
@@ -83,9 +83,9 @@
}
},
"node_modules/@esbuild/android-arm": {
- "version": "0.27.7",
- "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.27.7.tgz",
- "integrity": "sha512-jbPXvB4Yj2yBV7HUfE2KHe4GJX51QplCN1pGbYjvsyCZbQmies29EoJbkEc+vYuU5o45AfQn37vZlyXy4YJ8RQ==",
+ "version": "0.28.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.28.1.tgz",
+ "integrity": "sha512-0k2F129Xdio1TdJfzJ8sy1Q47vUD2NnwdhiAf7drUN1EBTfPf4hsFCtmMgu/6m8JSzsBrlmVjudMBQqOfG8usQ==",
"cpu": [
"arm"
],
@@ -100,9 +100,9 @@
}
},
"node_modules/@esbuild/android-arm64": {
- "version": "0.27.7",
- "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.27.7.tgz",
- "integrity": "sha512-62dPZHpIXzvChfvfLJow3q5dDtiNMkwiRzPylSCfriLvZeq0a1bWChrGx/BbUbPwOrsWKMn8idSllklzBy+dgQ==",
+ "version": "0.28.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.28.1.tgz",
+ "integrity": "sha512-34EGEbCIAgosYz6goLcopX6Mo7NyGv9tfwEM2/7Ce2VcVRk568iSvniGWcUXIy7wEDR1wzolcxcriFVrWYcwBg==",
"cpu": [
"arm64"
],
@@ -117,9 +117,9 @@
}
},
"node_modules/@esbuild/android-x64": {
- "version": "0.27.7",
- "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.27.7.tgz",
- "integrity": "sha512-x5VpMODneVDb70PYV2VQOmIUUiBtY3D3mPBG8NxVk5CogneYhkR7MmM3yR/uMdITLrC1ml/NV1rj4bMJuy9MCg==",
+ "version": "0.28.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.28.1.tgz",
+ "integrity": "sha512-dbwY7ltSMDWsRatcRpCnES4F+im88OCUgGZjy52shC7GqHRE/cYlxNbB4Z4UpJswpcc4Qxd2oE/ufM0p61IKng==",
"cpu": [
"x64"
],
@@ -134,9 +134,9 @@
}
},
"node_modules/@esbuild/darwin-arm64": {
- "version": "0.27.7",
- "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.27.7.tgz",
- "integrity": "sha512-5lckdqeuBPlKUwvoCXIgI2D9/ABmPq3Rdp7IfL70393YgaASt7tbju3Ac+ePVi3KDH6N2RqePfHnXkaDtY9fkw==",
+ "version": "0.28.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.28.1.tgz",
+ "integrity": "sha512-TZbWkQY7kvTAXbXUT7uVACR5cMHsDiSz9z7ZKAX/RTq/WJEk3QyRr0wZpNhBDX+/0CtdqUIJlOiodQcta6tY3Q==",
"cpu": [
"arm64"
],
@@ -151,9 +151,9 @@
}
},
"node_modules/@esbuild/darwin-x64": {
- "version": "0.27.7",
- "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.27.7.tgz",
- "integrity": "sha512-rYnXrKcXuT7Z+WL5K980jVFdvVKhCHhUwid+dDYQpH+qu+TefcomiMAJpIiC2EM3Rjtq0sO3StMV/+3w3MyyqQ==",
+ "version": "0.28.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.28.1.tgz",
+ "integrity": "sha512-zfdzgK9ACBNZLI/CyHTOx81SyNbM6YXn7rxSgX97VjyiPl9W1i4Ka4fgKECEoFCKGpvBj5qArWIGgQjOwkgskQ==",
"cpu": [
"x64"
],
@@ -168,9 +168,9 @@
}
},
"node_modules/@esbuild/freebsd-arm64": {
- "version": "0.27.7",
- "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.27.7.tgz",
- "integrity": "sha512-B48PqeCsEgOtzME2GbNM2roU29AMTuOIN91dsMO30t+Ydis3z/3Ngoj5hhnsOSSwNzS+6JppqWsuhTp6E82l2w==",
+ "version": "0.28.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.28.1.tgz",
+ "integrity": "sha512-wG2EA8ENdEI0qhkSZMjfqrdY+ziCYCPMmtZjjIwOmXFjmyzEHn+UUxk5of+SYsjtfs3VpnlC7QLzSI5hY/rOAw==",
"cpu": [
"arm64"
],
@@ -185,9 +185,9 @@
}
},
"node_modules/@esbuild/freebsd-x64": {
- "version": "0.27.7",
- "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.27.7.tgz",
- "integrity": "sha512-jOBDK5XEjA4m5IJK3bpAQF9/Lelu/Z9ZcdhTRLf4cajlB+8VEhFFRjWgfy3M1O4rO2GQ/b2dLwCUGpiF/eATNQ==",
+ "version": "0.28.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.28.1.tgz",
+ "integrity": "sha512-i7dZ9vQgnvSCzi/rYCXNgtF/U+eKZNJBzu3eTQbRgHnM7tNSizLOkRFAl3qzVc/Op/u5YkHHa4pf/3DOYHthLQ==",
"cpu": [
"x64"
],
@@ -202,9 +202,9 @@
}
},
"node_modules/@esbuild/linux-arm": {
- "version": "0.27.7",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.27.7.tgz",
- "integrity": "sha512-RkT/YXYBTSULo3+af8Ib0ykH8u2MBh57o7q/DAs3lTJlyVQkgQvlrPTnjIzzRPQyavxtPtfg0EopvDyIt0j1rA==",
+ "version": "0.28.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.28.1.tgz",
+ "integrity": "sha512-qVXBOHQS+d5Y722GwJzJUtOLlX7km3CraOaGormF1pDtPd2C/l1SHRPgjLunLGe51Sh5YYWKMFDyV4SxgMQYTQ==",
"cpu": [
"arm"
],
@@ -219,9 +219,9 @@
}
},
"node_modules/@esbuild/linux-arm64": {
- "version": "0.27.7",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.27.7.tgz",
- "integrity": "sha512-RZPHBoxXuNnPQO9rvjh5jdkRmVizktkT7TCDkDmQ0W2SwHInKCAV95GRuvdSvA7w4VMwfCjUiPwDi0ZO6Nfe9A==",
+ "version": "0.28.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.28.1.tgz",
+ "integrity": "sha512-yHs+0uc8+nvEAfAfxrWQKK5peSNzBc4PegcMO0EJ2hT71uA7vB8Ihg2e77R2P7SG5uYjPbHlLLmve4LLLRCf0g==",
"cpu": [
"arm64"
],
@@ -236,9 +236,9 @@
}
},
"node_modules/@esbuild/linux-ia32": {
- "version": "0.27.7",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.27.7.tgz",
- "integrity": "sha512-GA48aKNkyQDbd3KtkplYWT102C5sn/EZTY4XROkxONgruHPU72l+gW+FfF8tf2cFjeHaRbWpOYa/uRBz/Xq1Pg==",
+ "version": "0.28.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.28.1.tgz",
+ "integrity": "sha512-d1z4ZuP0ajrfz/FhGT4vv278rX8KnPPJx8i5+AtK7TYbx9Le9F1hyzurZpkEyjkGa9dUGhQow4C1NmeGvqxN2w==",
"cpu": [
"ia32"
],
@@ -253,9 +253,9 @@
}
},
"node_modules/@esbuild/linux-loong64": {
- "version": "0.27.7",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.27.7.tgz",
- "integrity": "sha512-a4POruNM2oWsD4WKvBSEKGIiWQF8fZOAsycHOt6JBpZ+JN2n2JH9WAv56SOyu9X5IqAjqSIPTaJkqN8F7XOQ5Q==",
+ "version": "0.28.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.28.1.tgz",
+ "integrity": "sha512-M5sRjUVZrkm1OAPR3dlOYzNmN+loZKGVi1VUQGrwuqLcbR6qeAz+famMhjASeH3YVKvZz+zT1jlh/keC3Rj/lg==",
"cpu": [
"loong64"
],
@@ -270,9 +270,9 @@
}
},
"node_modules/@esbuild/linux-mips64el": {
- "version": "0.27.7",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.27.7.tgz",
- "integrity": "sha512-KabT5I6StirGfIz0FMgl1I+R1H73Gp0ofL9A3nG3i/cYFJzKHhouBV5VWK1CSgKvVaG4q1RNpCTR2LuTVB3fIw==",
+ "version": "0.28.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.28.1.tgz",
+ "integrity": "sha512-mRObBZeHh2OxcBFPWE/FjylkRgZdYuiTR3vaTozquCGOH14iP9oN4x4Ge81CoIDYQrXmIxpFumJBu5MtZpnQJQ==",
"cpu": [
"mips64el"
],
@@ -287,9 +287,9 @@
}
},
"node_modules/@esbuild/linux-ppc64": {
- "version": "0.27.7",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.27.7.tgz",
- "integrity": "sha512-gRsL4x6wsGHGRqhtI+ifpN/vpOFTQtnbsupUF5R5YTAg+y/lKelYR1hXbnBdzDjGbMYjVJLJTd2OFmMewAgwlQ==",
+ "version": "0.28.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.28.1.tgz",
+ "integrity": "sha512-slScBsMAb3GFDcdrCgLwZtPYRoH2H/youv10QiZyRjmsP48fznoveWytSgCI/R0ZcUgpc0ZhIUEx6LHts8yrfQ==",
"cpu": [
"ppc64"
],
@@ -304,9 +304,9 @@
}
},
"node_modules/@esbuild/linux-riscv64": {
- "version": "0.27.7",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.27.7.tgz",
- "integrity": "sha512-hL25LbxO1QOngGzu2U5xeXtxXcW+/GvMN3ejANqXkxZ/opySAZMrc+9LY/WyjAan41unrR3YrmtTsUpwT66InQ==",
+ "version": "0.28.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.28.1.tgz",
+ "integrity": "sha512-kw0owk1o0GFETUJyW0jc0G4Yzs0BHZn0JDZ8JRT088vjJYX777BAs1fDGxAC+q831qOs2DTC96mNsG2opdfyyQ==",
"cpu": [
"riscv64"
],
@@ -321,9 +321,9 @@
}
},
"node_modules/@esbuild/linux-s390x": {
- "version": "0.27.7",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.27.7.tgz",
- "integrity": "sha512-2k8go8Ycu1Kb46vEelhu1vqEP+UeRVj2zY1pSuPdgvbd5ykAw82Lrro28vXUrRmzEsUV0NzCf54yARIK8r0fdw==",
+ "version": "0.28.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.28.1.tgz",
+ "integrity": "sha512-/lAIjX8aYFRByhh6L5rYtPEDRqa9de/4V/juOXcta5frjvzXO4/sqEtyytse0g3zZFuWu5cDN0MkLz2qRDD2Ag==",
"cpu": [
"s390x"
],
@@ -338,9 +338,9 @@
}
},
"node_modules/@esbuild/linux-x64": {
- "version": "0.27.7",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.27.7.tgz",
- "integrity": "sha512-hzznmADPt+OmsYzw1EE33ccA+HPdIqiCRq7cQeL1Jlq2gb1+OyWBkMCrYGBJ+sxVzve2ZJEVeePbLM2iEIZSxA==",
+ "version": "0.28.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.28.1.tgz",
+ "integrity": "sha512-u/anNYF2mmVOEDwLtnQ1wOr3EZ9sTNGLWrsYGYwHWzGA3Si84IOkHXlbWTD1NB+9/1lcnweYKO54uhxZydNzfA==",
"cpu": [
"x64"
],
@@ -355,9 +355,9 @@
}
},
"node_modules/@esbuild/netbsd-arm64": {
- "version": "0.27.7",
- "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.27.7.tgz",
- "integrity": "sha512-b6pqtrQdigZBwZxAn1UpazEisvwaIDvdbMbmrly7cDTMFnw/+3lVxxCTGOrkPVnsYIosJJXAsILG9XcQS+Yu6w==",
+ "version": "0.28.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.28.1.tgz",
+ "integrity": "sha512-oks0DYbLwWMmaakTsCb+zL4E+aHRVLom9IJZOAthMQEPiQmydXHkziYEsGYRx0uNV/IjEKGAV941JzH02pflqw==",
"cpu": [
"arm64"
],
@@ -372,9 +372,9 @@
}
},
"node_modules/@esbuild/netbsd-x64": {
- "version": "0.27.7",
- "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.27.7.tgz",
- "integrity": "sha512-OfatkLojr6U+WN5EDYuoQhtM+1xco+/6FSzJJnuWiUw5eVcicbyK3dq5EeV/QHT1uy6GoDhGbFpprUiHUYggrw==",
+ "version": "0.28.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.28.1.tgz",
+ "integrity": "sha512-aeL6lAnN89Hz43Mlh1G8ARasbuoYvSITDEx0tHh5b7jJnHcssqgjy9Yx430GDpmCa6OyrKoS0aNRjKundRizGg==",
"cpu": [
"x64"
],
@@ -389,9 +389,9 @@
}
},
"node_modules/@esbuild/openbsd-arm64": {
- "version": "0.27.7",
- "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.27.7.tgz",
- "integrity": "sha512-AFuojMQTxAz75Fo8idVcqoQWEHIXFRbOc1TrVcFSgCZtQfSdc1RXgB3tjOn/krRHENUB4j00bfGjyl2mJrU37A==",
+ "version": "0.28.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.28.1.tgz",
+ "integrity": "sha512-MEFJe5C3R8pwXdZ5Y21oo6m7ePiS0d9pWucn99O/wvyJZChoIQKrQDxKrGeW8F5+T0okTHesAmDeiHDTIq0V/Q==",
"cpu": [
"arm64"
],
@@ -406,9 +406,9 @@
}
},
"node_modules/@esbuild/openbsd-x64": {
- "version": "0.27.7",
- "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.27.7.tgz",
- "integrity": "sha512-+A1NJmfM8WNDv5CLVQYJ5PshuRm/4cI6WMZRg1by1GwPIQPCTs1GLEUHwiiQGT5zDdyLiRM/l1G0Pv54gvtKIg==",
+ "version": "0.28.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.28.1.tgz",
+ "integrity": "sha512-i/ZLIOafE0Z8cI/XANJAixoJL/uRAoS2xOA3rb0xN+KK0K177cMAsQYkzHtBrtMXAKuAc7HGgcWiZ/sRC1Nxgw==",
"cpu": [
"x64"
],
@@ -423,9 +423,9 @@
}
},
"node_modules/@esbuild/openharmony-arm64": {
- "version": "0.27.7",
- "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.27.7.tgz",
- "integrity": "sha512-+KrvYb/C8zA9CU/g0sR6w2RBw7IGc5J2BPnc3dYc5VJxHCSF1yNMxTV5LQ7GuKteQXZtspjFbiuW5/dOj7H4Yw==",
+ "version": "0.28.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.28.1.tgz",
+ "integrity": "sha512-ge+Z7EXFNt2BO1oAMsVpiQ8EwndV9i1xXerAeTIK7AtPs3bKFXQM7nlRxDSIUIMeueR1CNXxqztLzdNeReKBJg==",
"cpu": [
"arm64"
],
@@ -440,9 +440,9 @@
}
},
"node_modules/@esbuild/sunos-x64": {
- "version": "0.27.7",
- "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.27.7.tgz",
- "integrity": "sha512-ikktIhFBzQNt/QDyOL580ti9+5mL/YZeUPKU2ivGtGjdTYoqz6jObj6nOMfhASpS4GU4Q/Clh1QtxWAvcYKamA==",
+ "version": "0.28.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.28.1.tgz",
+ "integrity": "sha512-BEjgtECkL3vY+SaSQ6nzVfiALUeFxpawyp8Jmf5PtYhf1Ug40N1h/hxlhts+f1FvSvarEigdxS3BlSMI2PJLcQ==",
"cpu": [
"x64"
],
@@ -457,9 +457,9 @@
}
},
"node_modules/@esbuild/win32-arm64": {
- "version": "0.27.7",
- "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.27.7.tgz",
- "integrity": "sha512-7yRhbHvPqSpRUV7Q20VuDwbjW5kIMwTHpptuUzV+AA46kiPze5Z7qgt6CLCK3pWFrHeNfDd1VKgyP4O+ng17CA==",
+ "version": "0.28.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.28.1.tgz",
+ "integrity": "sha512-lCv9eK/H6ZJWbE7bh2nw54CZ9M2nupBxJcTsdk/QQnWkdSjKGuxmmH8/GWrlT1eMmZfn4dGcCjRte397WqfQXA==",
"cpu": [
"arm64"
],
@@ -474,9 +474,9 @@
}
},
"node_modules/@esbuild/win32-ia32": {
- "version": "0.27.7",
- "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.27.7.tgz",
- "integrity": "sha512-SmwKXe6VHIyZYbBLJrhOoCJRB/Z1tckzmgTLfFYOfpMAx63BJEaL9ExI8x7v0oAO3Zh6D/Oi1gVxEYr5oUCFhw==",
+ "version": "0.28.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.28.1.tgz",
+ "integrity": "sha512-zvb/mB2bSCoJOpoCBgYKKpX6YM6mJBlBUVUtVj41DlZJVEB6/0CKlRYxP5wWl1C1ILiCoAU5wZZ4q1P3qeS6Eg==",
"cpu": [
"ia32"
],
@@ -491,9 +491,9 @@
}
},
"node_modules/@esbuild/win32-x64": {
- "version": "0.27.7",
- "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.27.7.tgz",
- "integrity": "sha512-56hiAJPhwQ1R4i+21FVF7V8kSD5zZTdHcVuRFMW0hn753vVfQN8xlx4uOPT4xoGH0Z/oVATuR82AiqSTDIpaHg==",
+ "version": "0.28.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.28.1.tgz",
+ "integrity": "sha512-bm4Mowrv+GXMlpWX++EcXw/iLyd1o3+bJkC2DkWXYVvgZCqD/bSj9ctZeAMC3cIxgjRVR2Dufaiu4YPxr5gW1A==",
"cpu": [
"x64"
],
@@ -783,9 +783,9 @@
}
},
"node_modules/@img/sharp-darwin-arm64": {
- "version": "0.34.5",
- "resolved": "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.34.5.tgz",
- "integrity": "sha512-imtQ3WMJXbMY4fxb/Ndp6HBTNVtWCUI0WdobyheGf5+ad6xX8VIDO8u2xE4qc/fr08CKG/7dDseFtn6M6g/r3w==",
+ "version": "0.35.3",
+ "resolved": "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.35.3.tgz",
+ "integrity": "sha512-RMnFX7YQsMoh7lWfcM4NEHHymBX/rLuKNPVM84XE9ONPcaSCDgE7CHIHpSgPcO2xcRthgBy1HfNO319mwhIAkg==",
"cpu": [
"arm64"
],
@@ -796,19 +796,19 @@
"darwin"
],
"engines": {
- "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ "node": ">=20.9.0"
},
"funding": {
"url": "https://opencollective.com/libvips"
},
"optionalDependencies": {
- "@img/sharp-libvips-darwin-arm64": "1.2.4"
+ "@img/sharp-libvips-darwin-arm64": "1.3.2"
}
},
"node_modules/@img/sharp-darwin-x64": {
- "version": "0.34.5",
- "resolved": "https://registry.npmjs.org/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.34.5.tgz",
- "integrity": "sha512-YNEFAF/4KQ/PeW0N+r+aVVsoIY0/qxxikF2SWdp+NRkmMB7y9LBZAVqQ4yhGCm/H3H270OSykqmQMKLBhBJDEw==",
+ "version": "0.35.3",
+ "resolved": "https://registry.npmjs.org/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.35.3.tgz",
+ "integrity": "sha512-Xo+5uFBtLN0BKqieTxiFzFPQAUlBbbH5iBKyRX/z1JrbnYsHTfKJnUfL8+p2TPXr1pXqao4eeL4Rl144uDpK9w==",
"cpu": [
"x64"
],
@@ -819,19 +819,39 @@
"darwin"
],
"engines": {
- "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ "node": ">=20.9.0"
},
"funding": {
"url": "https://opencollective.com/libvips"
},
"optionalDependencies": {
- "@img/sharp-libvips-darwin-x64": "1.2.4"
+ "@img/sharp-libvips-darwin-x64": "1.3.2"
+ }
+ },
+ "node_modules/@img/sharp-freebsd-wasm32": {
+ "version": "0.35.3",
+ "resolved": "https://registry.npmjs.org/@img/sharp-freebsd-wasm32/-/sharp-freebsd-wasm32-0.35.3.tgz",
+ "integrity": "sha512-lUxcqWIj2wMQ9BrwNjngcr1gWUr5xgaGThBRqPPalIC2n67Cqj1uPh8NnA/ZhAg8hUbKl+kVHKwgUIwe6ZYPrg==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "dependencies": {
+ "@img/sharp-wasm32": "0.35.3"
+ },
+ "engines": {
+ "node": ">=20.9.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
}
},
"node_modules/@img/sharp-libvips-darwin-arm64": {
- "version": "1.2.4",
- "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.2.4.tgz",
- "integrity": "sha512-zqjjo7RatFfFoP0MkQ51jfuFZBnVE2pRiaydKJ1G/rHZvnsrHAOcQALIi9sA5co5xenQdTugCvtb1cuf78Vf4g==",
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.3.2.tgz",
+ "integrity": "sha512-9J6ypZFpQBj4YnePGoq/S38w6nz+vqg5WZLrLGY4YuSemdMq47GMLBPO42MzwdGwpg/agZ7xzZcFHa48xlywfg==",
"cpu": [
"arm64"
],
@@ -846,9 +866,9 @@
}
},
"node_modules/@img/sharp-libvips-darwin-x64": {
- "version": "1.2.4",
- "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.2.4.tgz",
- "integrity": "sha512-1IOd5xfVhlGwX+zXv2N93k0yMONvUlANylbJw1eTah8K/Jtpi15KC+WSiaX/nBmbm2HxRM1gZ0nSdjSsrZbGKg==",
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.3.2.tgz",
+ "integrity": "sha512-m2pW1n6cns9VaubNwsZ+c3CRYjxNQWgJ5gPlnL1nbBcpkBvFm6SCFN5o0psFHI8w9n11NKhFkeEDns98tiqbEw==",
"cpu": [
"x64"
],
@@ -863,9 +883,9 @@
}
},
"node_modules/@img/sharp-libvips-linux-arm": {
- "version": "1.2.4",
- "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.2.4.tgz",
- "integrity": "sha512-bFI7xcKFELdiNCVov8e44Ia4u2byA+l3XtsAj+Q8tfCwO6BQ8iDojYdvoPMqsKDkuoOo+X6HZA0s0q11ANMQ8A==",
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.3.2.tgz",
+ "integrity": "sha512-1eMLzy92I4J6rmi4mAT8yC3HxOtniyGELlzGbNMLLeqe052ahFQ0h6LFq+lh5DsDIdYViIDst08abvSbcEdLXQ==",
"cpu": [
"arm"
],
@@ -880,9 +900,9 @@
}
},
"node_modules/@img/sharp-libvips-linux-arm64": {
- "version": "1.2.4",
- "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.2.4.tgz",
- "integrity": "sha512-excjX8DfsIcJ10x1Kzr4RcWe1edC9PquDRRPx3YVCvQv+U5p7Yin2s32ftzikXojb1PIFc/9Mt28/y+iRklkrw==",
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.3.2.tgz",
+ "integrity": "sha512-dqVSFynCox4C/J8kT16V7SIFAns0IjgLwkvYT7p8LQVmJ5OS5b6tI9IGflxTeuBS//zXeFIUbwt5dwxyZ17cnA==",
"cpu": [
"arm64"
],
@@ -897,9 +917,9 @@
}
},
"node_modules/@img/sharp-libvips-linux-ppc64": {
- "version": "1.2.4",
- "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-ppc64/-/sharp-libvips-linux-ppc64-1.2.4.tgz",
- "integrity": "sha512-FMuvGijLDYG6lW+b/UvyilUWu5Ayu+3r2d1S8notiGCIyYU/76eig1UfMmkZ7vwgOrzKzlQbFSuQfgm7GYUPpA==",
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-ppc64/-/sharp-libvips-linux-ppc64-1.3.2.tgz",
+ "integrity": "sha512-3z0NHDxD6n5I9gc05U1eW1AyRm+Gznzq3naMrthPNqE6oYykcogW0l/jfpJdjYnuNl8R7yI9pNbE1XiUeyq0Aw==",
"cpu": [
"ppc64"
],
@@ -914,9 +934,9 @@
}
},
"node_modules/@img/sharp-libvips-linux-riscv64": {
- "version": "1.2.4",
- "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-riscv64/-/sharp-libvips-linux-riscv64-1.2.4.tgz",
- "integrity": "sha512-oVDbcR4zUC0ce82teubSm+x6ETixtKZBh/qbREIOcI3cULzDyb18Sr/Wcyx7NRQeQzOiHTNbZFF1UwPS2scyGA==",
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-riscv64/-/sharp-libvips-linux-riscv64-1.3.2.tgz",
+ "integrity": "sha512-bsb4rI+NldGOsXuej2r8OdSS8+zXDVaCWxyWrcv6kneTOlgAHtZABRzBBCwdsPiD90J4myNJuHpg6kA20ImW/w==",
"cpu": [
"riscv64"
],
@@ -931,9 +951,9 @@
}
},
"node_modules/@img/sharp-libvips-linux-s390x": {
- "version": "1.2.4",
- "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.2.4.tgz",
- "integrity": "sha512-qmp9VrzgPgMoGZyPvrQHqk02uyjA0/QrTO26Tqk6l4ZV0MPWIW6LTkqOIov+J1yEu7MbFQaDpwdwJKhbJvuRxQ==",
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.3.2.tgz",
+ "integrity": "sha512-/ABshyj8gCpyIrNXnHn4LorDJ0HHm1VhXPBlxZ8zAtfVPAaSafXPGn+sUSIRiwaSBy0mmFjSjiXI5mkcwdChKQ==",
"cpu": [
"s390x"
],
@@ -948,9 +968,9 @@
}
},
"node_modules/@img/sharp-libvips-linux-x64": {
- "version": "1.2.4",
- "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.2.4.tgz",
- "integrity": "sha512-tJxiiLsmHc9Ax1bz3oaOYBURTXGIRDODBqhveVHonrHJ9/+k89qbLl0bcJns+e4t4rvaNBxaEZsFtSfAdquPrw==",
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.3.2.tgz",
+ "integrity": "sha512-ITPEtgffGJ0S6G9dRyw/366tJQqFRcHWPHhC+Stpg3Z8AEMrDrTr2lhdz4f/Y/HMbRh//7Z5mBzEpVdi62Oc3w==",
"cpu": [
"x64"
],
@@ -965,9 +985,9 @@
}
},
"node_modules/@img/sharp-libvips-linuxmusl-arm64": {
- "version": "1.2.4",
- "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.2.4.tgz",
- "integrity": "sha512-FVQHuwx1IIuNow9QAbYUzJ+En8KcVm9Lk5+uGUQJHaZmMECZmOlix9HnH7n1TRkXMS0pGxIJokIVB9SuqZGGXw==",
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.3.2.tgz",
+ "integrity": "sha512-zE9EdiUzUmg5mDT5a1rk5fYJ6GWPloTwWBYDS14naqHsL+EaMpDj1AWnpLgh3u0YCORv2Tt50wrcrpYqkP97Kw==",
"cpu": [
"arm64"
],
@@ -982,9 +1002,9 @@
}
},
"node_modules/@img/sharp-libvips-linuxmusl-x64": {
- "version": "1.2.4",
- "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.2.4.tgz",
- "integrity": "sha512-+LpyBk7L44ZIXwz/VYfglaX/okxezESc6UxDSoyo2Ks6Jxc4Y7sGjpgU9s4PMgqgjj1gZCylTieNamqA1MF7Dg==",
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.3.2.tgz",
+ "integrity": "sha512-m0lrLiUt+lBYnCFr8qV/65yMR4E/c7/wf78I5eKTdkEakFAlZ9QlzEM3QIhhAwVeUhLAHLcCq7a7Vszq/oFNZQ==",
"cpu": [
"x64"
],
@@ -999,9 +1019,9 @@
}
},
"node_modules/@img/sharp-linux-arm": {
- "version": "0.34.5",
- "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm/-/sharp-linux-arm-0.34.5.tgz",
- "integrity": "sha512-9dLqsvwtg1uuXBGZKsxem9595+ujv0sJ6Vi8wcTANSFpwV/GONat5eCkzQo/1O6zRIkh0m/8+5BjrRr7jDUSZw==",
+ "version": "0.35.3",
+ "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm/-/sharp-linux-arm-0.35.3.tgz",
+ "integrity": "sha512-affVWCTLooy8TSxbDx2qkzuDeaWLNVBA+P//FNBirHsXpP2fuBhk5AuboYUnrDnzoXes8GFjpTx0SBFOCRg+FA==",
"cpu": [
"arm"
],
@@ -1012,19 +1032,19 @@
"linux"
],
"engines": {
- "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ "node": ">=20.9.0"
},
"funding": {
"url": "https://opencollective.com/libvips"
},
"optionalDependencies": {
- "@img/sharp-libvips-linux-arm": "1.2.4"
+ "@img/sharp-libvips-linux-arm": "1.3.2"
}
},
"node_modules/@img/sharp-linux-arm64": {
- "version": "0.34.5",
- "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.34.5.tgz",
- "integrity": "sha512-bKQzaJRY/bkPOXyKx5EVup7qkaojECG6NLYswgktOZjaXecSAeCWiZwwiFf3/Y+O1HrauiE3FVsGxFg8c24rZg==",
+ "version": "0.35.3",
+ "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.35.3.tgz",
+ "integrity": "sha512-QgKDspHPnrU+GQ55XPhGwyhC8acLVOOSyAvo1oVfFmrIXLkDNmGWzAfDZ4xK8oSA1qBQrALcHX0G5UZni/SuFQ==",
"cpu": [
"arm64"
],
@@ -1035,19 +1055,19 @@
"linux"
],
"engines": {
- "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ "node": ">=20.9.0"
},
"funding": {
"url": "https://opencollective.com/libvips"
},
"optionalDependencies": {
- "@img/sharp-libvips-linux-arm64": "1.2.4"
+ "@img/sharp-libvips-linux-arm64": "1.3.2"
}
},
"node_modules/@img/sharp-linux-ppc64": {
- "version": "0.34.5",
- "resolved": "https://registry.npmjs.org/@img/sharp-linux-ppc64/-/sharp-linux-ppc64-0.34.5.tgz",
- "integrity": "sha512-7zznwNaqW6YtsfrGGDA6BRkISKAAE1Jo0QdpNYXNMHu2+0dTrPflTLNkpc8l7MUP5M16ZJcUvysVWWrMefZquA==",
+ "version": "0.35.3",
+ "resolved": "https://registry.npmjs.org/@img/sharp-linux-ppc64/-/sharp-linux-ppc64-0.35.3.tgz",
+ "integrity": "sha512-sMd8rDxmpLOwv/7N44klFjOD5DUO7FLdjiXDI0hoxYaf7Ar262dQIEkosE98bps+5HPLtp/EvNqeqQtOycP/IA==",
"cpu": [
"ppc64"
],
@@ -1058,19 +1078,19 @@
"linux"
],
"engines": {
- "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ "node": ">=20.9.0"
},
"funding": {
"url": "https://opencollective.com/libvips"
},
"optionalDependencies": {
- "@img/sharp-libvips-linux-ppc64": "1.2.4"
+ "@img/sharp-libvips-linux-ppc64": "1.3.2"
}
},
"node_modules/@img/sharp-linux-riscv64": {
- "version": "0.34.5",
- "resolved": "https://registry.npmjs.org/@img/sharp-linux-riscv64/-/sharp-linux-riscv64-0.34.5.tgz",
- "integrity": "sha512-51gJuLPTKa7piYPaVs8GmByo7/U7/7TZOq+cnXJIHZKavIRHAP77e3N2HEl3dgiqdD/w0yUfiJnII77PuDDFdw==",
+ "version": "0.35.3",
+ "resolved": "https://registry.npmjs.org/@img/sharp-linux-riscv64/-/sharp-linux-riscv64-0.35.3.tgz",
+ "integrity": "sha512-0Eob78yjlYPfL5vMNWAW55l3R9Y6BQS/gOfe0ZcP9mEz9ohhKSt4im1hayiknXgf8AWrFqMvJcKIdmLmEe7yeQ==",
"cpu": [
"riscv64"
],
@@ -1081,19 +1101,19 @@
"linux"
],
"engines": {
- "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ "node": ">=20.9.0"
},
"funding": {
"url": "https://opencollective.com/libvips"
},
"optionalDependencies": {
- "@img/sharp-libvips-linux-riscv64": "1.2.4"
+ "@img/sharp-libvips-linux-riscv64": "1.3.2"
}
},
"node_modules/@img/sharp-linux-s390x": {
- "version": "0.34.5",
- "resolved": "https://registry.npmjs.org/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.34.5.tgz",
- "integrity": "sha512-nQtCk0PdKfho3eC5MrbQoigJ2gd1CgddUMkabUj+rBevs8tZ2cULOx46E7oyX+04WGfABgIwmMC0VqieTiR4jg==",
+ "version": "0.35.3",
+ "resolved": "https://registry.npmjs.org/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.35.3.tgz",
+ "integrity": "sha512-KgAxQ0DxpNOq1rG2t5cgTgShJFGSuU7XO45cqC+1NVOuZnP6tlgZRuSYOfNupGkHID0o3cJOsw4DVeJpMovcGw==",
"cpu": [
"s390x"
],
@@ -1104,19 +1124,19 @@
"linux"
],
"engines": {
- "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ "node": ">=20.9.0"
},
"funding": {
"url": "https://opencollective.com/libvips"
},
"optionalDependencies": {
- "@img/sharp-libvips-linux-s390x": "1.2.4"
+ "@img/sharp-libvips-linux-s390x": "1.3.2"
}
},
"node_modules/@img/sharp-linux-x64": {
- "version": "0.34.5",
- "resolved": "https://registry.npmjs.org/@img/sharp-linux-x64/-/sharp-linux-x64-0.34.5.tgz",
- "integrity": "sha512-MEzd8HPKxVxVenwAa+JRPwEC7QFjoPWuS5NZnBt6B3pu7EG2Ge0id1oLHZpPJdn3OQK+BQDiw9zStiHBTJQQQQ==",
+ "version": "0.35.3",
+ "resolved": "https://registry.npmjs.org/@img/sharp-linux-x64/-/sharp-linux-x64-0.35.3.tgz",
+ "integrity": "sha512-8pqvxubL2PGdhlPy6GLqzDYMUjyRmKAwKHYKixpdJYBUK7PJ0C029XdsnpFIdgRZG68fZiGdHVWcKPvtiPB4cA==",
"cpu": [
"x64"
],
@@ -1127,19 +1147,19 @@
"linux"
],
"engines": {
- "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ "node": ">=20.9.0"
},
"funding": {
"url": "https://opencollective.com/libvips"
},
"optionalDependencies": {
- "@img/sharp-libvips-linux-x64": "1.2.4"
+ "@img/sharp-libvips-linux-x64": "1.3.2"
}
},
"node_modules/@img/sharp-linuxmusl-arm64": {
- "version": "0.34.5",
- "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.34.5.tgz",
- "integrity": "sha512-fprJR6GtRsMt6Kyfq44IsChVZeGN97gTD331weR1ex1c1rypDEABN6Tm2xa1wE6lYb5DdEnk03NZPqA7Id21yg==",
+ "version": "0.35.3",
+ "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.35.3.tgz",
+ "integrity": "sha512-Vz0iQjzzcSX3HCbfwFfCSG/9SCIqyO0mH2sXyiHaAYfBk0cRsCWXRyQYX0ovCK/PAQBbTzQ0dsPQHh5MAFL59w==",
"cpu": [
"arm64"
],
@@ -1150,19 +1170,19 @@
"linux"
],
"engines": {
- "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ "node": ">=20.9.0"
},
"funding": {
"url": "https://opencollective.com/libvips"
},
"optionalDependencies": {
- "@img/sharp-libvips-linuxmusl-arm64": "1.2.4"
+ "@img/sharp-libvips-linuxmusl-arm64": "1.3.2"
}
},
"node_modules/@img/sharp-linuxmusl-x64": {
- "version": "0.34.5",
- "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.34.5.tgz",
- "integrity": "sha512-Jg8wNT1MUzIvhBFxViqrEhWDGzqymo3sV7z7ZsaWbZNDLXRJZoRGrjulp60YYtV4wfY8VIKcWidjojlLcWrd8Q==",
+ "version": "0.35.3",
+ "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.35.3.tgz",
+ "integrity": "sha512-6O1NPKcDVj9QEdg7Hx549EX8U0rp6yXQERqru6yRN7fGBn32UvIRJUlWnk+8xDCiG76hXVBbX82NZ/ZKr0euIg==",
"cpu": [
"x64"
],
@@ -1173,39 +1193,56 @@
"linux"
],
"engines": {
- "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ "node": ">=20.9.0"
},
"funding": {
"url": "https://opencollective.com/libvips"
},
"optionalDependencies": {
- "@img/sharp-libvips-linuxmusl-x64": "1.2.4"
+ "@img/sharp-libvips-linuxmusl-x64": "1.3.2"
}
},
"node_modules/@img/sharp-wasm32": {
- "version": "0.34.5",
- "resolved": "https://registry.npmjs.org/@img/sharp-wasm32/-/sharp-wasm32-0.34.5.tgz",
- "integrity": "sha512-OdWTEiVkY2PHwqkbBI8frFxQQFekHaSSkUIJkwzclWZe64O1X4UlUjqqqLaPbUpMOQk6FBu/HtlGXNblIs0huw==",
+ "version": "0.35.3",
+ "resolved": "https://registry.npmjs.org/@img/sharp-wasm32/-/sharp-wasm32-0.35.3.tgz",
+ "integrity": "sha512-cZ0XkcYGpHZkqW6iCkqTcmUC0CD9DhD5d/qeZlZkfRBn6GnHniZXLUo5+9xw8Iv76YE6LQFN9YNBlKREcCG76w==",
+ "dev": true,
+ "license": "Apache-2.0 AND LGPL-3.0-or-later AND MIT",
+ "optional": true,
+ "dependencies": {
+ "@emnapi/runtime": "^1.11.1"
+ },
+ "engines": {
+ "node": ">=20.9.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ }
+ },
+ "node_modules/@img/sharp-webcontainers-wasm32": {
+ "version": "0.35.3",
+ "resolved": "https://registry.npmjs.org/@img/sharp-webcontainers-wasm32/-/sharp-webcontainers-wasm32-0.35.3.tgz",
+ "integrity": "sha512-2rnq7bX3NzeR2T4YWgz8qiG4h3TSdMe+vN1iQXpJleSJ3SM5zQ8Fy2SyyXAWlbxpEZ2Y+Z4u1BePgJEYbSy80Q==",
"cpu": [
"wasm32"
],
"dev": true,
- "license": "Apache-2.0 AND LGPL-3.0-or-later AND MIT",
+ "license": "Apache-2.0",
"optional": true,
"dependencies": {
- "@emnapi/runtime": "^1.7.0"
+ "@img/sharp-wasm32": "0.35.3"
},
"engines": {
- "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ "node": ">=20.9.0"
},
"funding": {
"url": "https://opencollective.com/libvips"
}
},
"node_modules/@img/sharp-win32-arm64": {
- "version": "0.34.5",
- "resolved": "https://registry.npmjs.org/@img/sharp-win32-arm64/-/sharp-win32-arm64-0.34.5.tgz",
- "integrity": "sha512-WQ3AgWCWYSb2yt+IG8mnC6Jdk9Whs7O0gxphblsLvdhSpSTtmu69ZG1Gkb6NuvxsNACwiPV6cNSZNzt0KPsw7g==",
+ "version": "0.35.3",
+ "resolved": "https://registry.npmjs.org/@img/sharp-win32-arm64/-/sharp-win32-arm64-0.35.3.tgz",
+ "integrity": "sha512-4bPwFdMbeC4JQ8L8LOyWp6nsHcboP5fxkp6iPOXz2Vg49R42TuMs2whkJ5OAP4/Ul035qOzy0AecOF9VOscn4w==",
"cpu": [
"arm64"
],
@@ -1216,16 +1253,16 @@
"win32"
],
"engines": {
- "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ "node": ">=20.9.0"
},
"funding": {
"url": "https://opencollective.com/libvips"
}
},
"node_modules/@img/sharp-win32-ia32": {
- "version": "0.34.5",
- "resolved": "https://registry.npmjs.org/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.34.5.tgz",
- "integrity": "sha512-FV9m/7NmeCmSHDD5j4+4pNI8Cp3aW+JvLoXcTUo0IqyjSfAZJ8dIUmijx1qaJsIiU+Hosw6xM5KijAWRJCSgNg==",
+ "version": "0.35.3",
+ "resolved": "https://registry.npmjs.org/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.35.3.tgz",
+ "integrity": "sha512-r53mXsBN6lFUDiST764SvgwUdHAqM4rPAiDzAmf4fLoB6X/rkfyTrLCg6+g17wJJiCmB3JYgHuUldCWUIRFSXw==",
"cpu": [
"ia32"
],
@@ -1236,16 +1273,16 @@
"win32"
],
"engines": {
- "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ "node": "^20.9.0"
},
"funding": {
"url": "https://opencollective.com/libvips"
}
},
"node_modules/@img/sharp-win32-x64": {
- "version": "0.34.5",
- "resolved": "https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.34.5.tgz",
- "integrity": "sha512-+29YMsqY2/9eFEiW93eqWnuLcWcufowXewwSNIT6UwZdUUCrM3oFjMWH/Z6/TMmb4hlFenmfAVbpWeup2jryCw==",
+ "version": "0.35.3",
+ "resolved": "https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.35.3.tgz",
+ "integrity": "sha512-D4y1vNeZrIIJCN+uHaWVtH86B+aCrdMYYjicy9pXHvbGZeGYLLSd3wdVuC37FxVXlU1ARsk84eKWfWMXGYEqvA==",
"cpu": [
"x64"
],
@@ -1256,7 +1293,7 @@
"win32"
],
"engines": {
- "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ "node": ">=20.9.0"
},
"funding": {
"url": "https://opencollective.com/libvips"
@@ -2103,16 +2140,16 @@
}
},
"node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": {
- "version": "5.0.6",
- "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.6.tgz",
- "integrity": "sha512-kLpxurY4Z4r9sgMsyG0Z9uzsBlgiU/EFKhj/h91/8yHu0edo7XuixOIH3VcJ8kkxs6/jPzoI6U9Vj3WqbMQ94g==",
+ "version": "5.0.8",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.8.tgz",
+ "integrity": "sha512-JZyDyq3D4AUifKTPOB7DELf6XsB3WdPuNxCtob1vFXPsSXhdAiHBWJ/tJ8HAc9aH84BK+5JFZLNkJKx3G9kzQg==",
"dev": true,
"license": "MIT",
"dependencies": {
"balanced-match": "^4.0.2"
},
"engines": {
- "node": "18 || 20 || >=22"
+ "node": "20 || >=22"
}
},
"node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": {
@@ -2379,9 +2416,9 @@
}
},
"node_modules/brace-expansion": {
- "version": "1.1.15",
- "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.15.tgz",
- "integrity": "sha512-EwOCDEex4quD37XhqM3omwtMoJjr//isUZz1JopUNWms+4Z2ViyM/k1YIRePpoVNnQhENnxtFjLaxNHrT7xIUg==",
+ "version": "1.1.16",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.16.tgz",
+ "integrity": "sha512-IDw48K2/2kRkg9LdJxurvq3lV3aBgq0REY89duEqFRthjlPdXHKMj7EnQOXVckxzgisinf3nHfrcE2FufFLXMw==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -2672,9 +2709,9 @@
"license": "MIT"
},
"node_modules/dompurify": {
- "version": "3.4.11",
- "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.4.11.tgz",
- "integrity": "sha512-zhlUV12GsaRzMsf9q5M254YhA4+VuF0fG+QFqu6aYpoGlKtz+w8//jBcGVYBgQkR5GHjUomejY84AV+/uPbWdw==",
+ "version": "3.4.12",
+ "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.4.12.tgz",
+ "integrity": "sha512-zQvGet8Z2sWbQhCmfFz/T5QWH2oBmjnqK3qvOjaqaNLrLEF912WamU+ohnTp0TCep/MFVHpdJuCZEdFOdTnEFg==",
"license": "(MPL-2.0 OR Apache-2.0)",
"optionalDependencies": {
"@types/trusted-types": "^2.0.7"
@@ -2698,9 +2735,9 @@
}
},
"node_modules/esbuild": {
- "version": "0.27.7",
- "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.27.7.tgz",
- "integrity": "sha512-IxpibTjyVnmrIQo5aqNpCgoACA/dTKLTlhMHihVHhdkxKyPO1uBBthumT0rdHmcsk9uMonIWS0m4FljWzILh3w==",
+ "version": "0.28.1",
+ "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.28.1.tgz",
+ "integrity": "sha512-HrJrvZv5ayxBzPfwphOoNzkzOIIlifzk0KJrGK2c8R4+LKpMtpYLQeUdjnwjWv/LZlkH2laZk+4w78pi99D4Vw==",
"dev": true,
"hasInstallScript": true,
"license": "MIT",
@@ -2711,32 +2748,32 @@
"node": ">=18"
},
"optionalDependencies": {
- "@esbuild/aix-ppc64": "0.27.7",
- "@esbuild/android-arm": "0.27.7",
- "@esbuild/android-arm64": "0.27.7",
- "@esbuild/android-x64": "0.27.7",
- "@esbuild/darwin-arm64": "0.27.7",
- "@esbuild/darwin-x64": "0.27.7",
- "@esbuild/freebsd-arm64": "0.27.7",
- "@esbuild/freebsd-x64": "0.27.7",
- "@esbuild/linux-arm": "0.27.7",
- "@esbuild/linux-arm64": "0.27.7",
- "@esbuild/linux-ia32": "0.27.7",
- "@esbuild/linux-loong64": "0.27.7",
- "@esbuild/linux-mips64el": "0.27.7",
- "@esbuild/linux-ppc64": "0.27.7",
- "@esbuild/linux-riscv64": "0.27.7",
- "@esbuild/linux-s390x": "0.27.7",
- "@esbuild/linux-x64": "0.27.7",
- "@esbuild/netbsd-arm64": "0.27.7",
- "@esbuild/netbsd-x64": "0.27.7",
- "@esbuild/openbsd-arm64": "0.27.7",
- "@esbuild/openbsd-x64": "0.27.7",
- "@esbuild/openharmony-arm64": "0.27.7",
- "@esbuild/sunos-x64": "0.27.7",
- "@esbuild/win32-arm64": "0.27.7",
- "@esbuild/win32-ia32": "0.27.7",
- "@esbuild/win32-x64": "0.27.7"
+ "@esbuild/aix-ppc64": "0.28.1",
+ "@esbuild/android-arm": "0.28.1",
+ "@esbuild/android-arm64": "0.28.1",
+ "@esbuild/android-x64": "0.28.1",
+ "@esbuild/darwin-arm64": "0.28.1",
+ "@esbuild/darwin-x64": "0.28.1",
+ "@esbuild/freebsd-arm64": "0.28.1",
+ "@esbuild/freebsd-x64": "0.28.1",
+ "@esbuild/linux-arm": "0.28.1",
+ "@esbuild/linux-arm64": "0.28.1",
+ "@esbuild/linux-ia32": "0.28.1",
+ "@esbuild/linux-loong64": "0.28.1",
+ "@esbuild/linux-mips64el": "0.28.1",
+ "@esbuild/linux-ppc64": "0.28.1",
+ "@esbuild/linux-riscv64": "0.28.1",
+ "@esbuild/linux-s390x": "0.28.1",
+ "@esbuild/linux-x64": "0.28.1",
+ "@esbuild/netbsd-arm64": "0.28.1",
+ "@esbuild/netbsd-x64": "0.28.1",
+ "@esbuild/openbsd-arm64": "0.28.1",
+ "@esbuild/openbsd-x64": "0.28.1",
+ "@esbuild/openharmony-arm64": "0.28.1",
+ "@esbuild/sunos-x64": "0.28.1",
+ "@esbuild/win32-arm64": "0.28.1",
+ "@esbuild/win32-ia32": "0.28.1",
+ "@esbuild/win32-x64": "0.28.1"
}
},
"node_modules/escalade": {
@@ -3354,9 +3391,9 @@
}
},
"node_modules/js-yaml": {
- "version": "4.2.0",
- "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.2.0.tgz",
- "integrity": "sha512-ePWsvanv0DWuDRsW8dnt+R4jQ31SCRCQ7hhNcPXZPsoBZiemuZNYGf7adZdqX2D86j6rvKp3RpCxVTSb8WQlOw==",
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.3.0.tgz",
+ "integrity": "sha512-1td788aAnnZ5qs7V2QIRl1owjtYpbKt749Y3xauqQgwIIGF/xXWz1wMTEBx5O3LK3lXLVuqXPdPxj2BoFHaW9Q==",
"dev": true,
"funding": [
{
@@ -4460,48 +4497,53 @@
"license": "MIT"
},
"node_modules/sharp": {
- "version": "0.34.5",
- "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.34.5.tgz",
- "integrity": "sha512-Ou9I5Ft9WNcCbXrU9cMgPBcCK8LiwLqcbywW3t4oDV37n1pzpuNLsYiAV8eODnjbtQlSDwZ2cUEeQz4E54Hltg==",
+ "version": "0.35.3",
+ "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.35.3.tgz",
+ "integrity": "sha512-ej0zVHuZGHCiABXcNxeYhpRnPNPAcvbG8RMdBAhDAxLKkCRVSpK3Iyu7qbqw3JMzoj0REeM6f3tJLtVwl0023Q==",
"dev": true,
- "hasInstallScript": true,
"license": "Apache-2.0",
"dependencies": {
- "@img/colour": "^1.0.0",
+ "@img/colour": "^1.1.0",
"detect-libc": "^2.1.2",
- "semver": "^7.7.3"
+ "semver": "^7.8.5"
},
"engines": {
- "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ "node": ">=20.9.0"
},
"funding": {
"url": "https://opencollective.com/libvips"
},
"optionalDependencies": {
- "@img/sharp-darwin-arm64": "0.34.5",
- "@img/sharp-darwin-x64": "0.34.5",
- "@img/sharp-libvips-darwin-arm64": "1.2.4",
- "@img/sharp-libvips-darwin-x64": "1.2.4",
- "@img/sharp-libvips-linux-arm": "1.2.4",
- "@img/sharp-libvips-linux-arm64": "1.2.4",
- "@img/sharp-libvips-linux-ppc64": "1.2.4",
- "@img/sharp-libvips-linux-riscv64": "1.2.4",
- "@img/sharp-libvips-linux-s390x": "1.2.4",
- "@img/sharp-libvips-linux-x64": "1.2.4",
- "@img/sharp-libvips-linuxmusl-arm64": "1.2.4",
- "@img/sharp-libvips-linuxmusl-x64": "1.2.4",
- "@img/sharp-linux-arm": "0.34.5",
- "@img/sharp-linux-arm64": "0.34.5",
- "@img/sharp-linux-ppc64": "0.34.5",
- "@img/sharp-linux-riscv64": "0.34.5",
- "@img/sharp-linux-s390x": "0.34.5",
- "@img/sharp-linux-x64": "0.34.5",
- "@img/sharp-linuxmusl-arm64": "0.34.5",
- "@img/sharp-linuxmusl-x64": "0.34.5",
- "@img/sharp-wasm32": "0.34.5",
- "@img/sharp-win32-arm64": "0.34.5",
- "@img/sharp-win32-ia32": "0.34.5",
- "@img/sharp-win32-x64": "0.34.5"
+ "@img/sharp-darwin-arm64": "0.35.3",
+ "@img/sharp-darwin-x64": "0.35.3",
+ "@img/sharp-freebsd-wasm32": "0.35.3",
+ "@img/sharp-libvips-darwin-arm64": "1.3.2",
+ "@img/sharp-libvips-darwin-x64": "1.3.2",
+ "@img/sharp-libvips-linux-arm": "1.3.2",
+ "@img/sharp-libvips-linux-arm64": "1.3.2",
+ "@img/sharp-libvips-linux-ppc64": "1.3.2",
+ "@img/sharp-libvips-linux-riscv64": "1.3.2",
+ "@img/sharp-libvips-linux-s390x": "1.3.2",
+ "@img/sharp-libvips-linux-x64": "1.3.2",
+ "@img/sharp-libvips-linuxmusl-arm64": "1.3.2",
+ "@img/sharp-libvips-linuxmusl-x64": "1.3.2",
+ "@img/sharp-linux-arm": "0.35.3",
+ "@img/sharp-linux-arm64": "0.35.3",
+ "@img/sharp-linux-ppc64": "0.35.3",
+ "@img/sharp-linux-riscv64": "0.35.3",
+ "@img/sharp-linux-s390x": "0.35.3",
+ "@img/sharp-linux-x64": "0.35.3",
+ "@img/sharp-linuxmusl-arm64": "0.35.3",
+ "@img/sharp-linuxmusl-x64": "0.35.3",
+ "@img/sharp-webcontainers-wasm32": "0.35.3",
+ "@img/sharp-win32-arm64": "0.35.3",
+ "@img/sharp-win32-ia32": "0.35.3",
+ "@img/sharp-win32-x64": "0.35.3"
+ },
+ "peerDependenciesMeta": {
+ "@types/node": {
+ "optional": true
+ }
}
},
"node_modules/shebang-command": {
@@ -5070,14 +5112,14 @@
"license": "MIT"
},
"node_modules/vite": {
- "version": "7.3.5",
- "resolved": "https://registry.npmjs.org/vite/-/vite-7.3.5.tgz",
- "integrity": "sha512-KuOaNhcnGFN2zIPGA7wRmzF+lJA1sea7rHq17aiJ++9lzY1WWG6Jpwqwe1KNbRVPIqHmr8GLYx7jbrQcN/7/ww==",
+ "version": "7.3.6",
+ "resolved": "https://registry.npmjs.org/vite/-/vite-7.3.6.tgz",
+ "integrity": "sha512-4XP60spRGjSZFf1qYH+dJIkK2znL3zQfl9KkOV9MkkRR/3Dls0dxaBsQPTloEc5BLXWPL9vsOxopxyKoMmDueg==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
- "esbuild": "^0.27.0",
+ "esbuild": "^0.27.0 || ^0.28.0",
"fdir": "^6.5.0",
"picomatch": "^4.0.3",
"postcss": "^8.5.6",
diff --git a/package.json b/package.json
index 84dfc8b..8e627a1 100644
--- a/package.json
+++ b/package.json
@@ -43,7 +43,7 @@
"prettier": "3.6.2",
"prettier-plugin-svelte": "^3.3.3",
"prettier-plugin-tailwindcss": "^0.6.11",
- "sharp": "^0.34.5",
+ "sharp": "^0.35.3",
"svelte": "^5.55.7",
"svelte-check": "^4.0.0",
"tailwindcss": "^3.4.17",
diff --git a/src/lib/blog/automated-network-documentation.md b/src/lib/blog/automated-network-documentation.md
index 65c3d62..2275ffc 100644
--- a/src/lib/blog/automated-network-documentation.md
+++ b/src/lib/blog/automated-network-documentation.md
@@ -128,13 +128,13 @@ Most teams need all three, and one tool does not cover the others. Monitoring to
## Tools That Automate Network Documentation
-Several tools approach automated documentation from different angles. Some are dedicated documentation tools, others bundle mapping into a monitoring or asset management platform (for the full category overview, including open-source options, see our [network documentation software guide](/guides/network-documentation-software)):
+Several tools approach automated documentation from different angles. Some are dedicated documentation tools, others bundle mapping into a monitoring or asset management platform (for the full comparison, including pricing, see the [network documentation tools comparison](/comparisons/best-automated-network-diagram-tools), and for the free options, the [open-source network documentation guide](/guides/open-source-network-documentation)):
## What to Look for in an Automated Documentation Tool
-If you're evaluating tools, our [comparison of automated network diagram tools](/comparisons/best-automated-network-diagram-tools) covers specific products, pricing, and trade-offs. Six criteria:
+If you're evaluating tools, our [network documentation tools comparison](/comparisons/best-automated-network-diagram-tools) covers specific products, pricing, and trade-offs. Six criteria:
- **Lightweight deployment**: one scanner per network, not an agent on every device. You're solving a complexity problem; don't add more complexity
- **Protocol support**: SNMP, LLDP, and CDP at minimum. ARP and MAC table scanning for full topology
diff --git a/src/lib/blog/network-diagrams-wrong.md b/src/lib/blog/network-diagrams-wrong.md
index 57433d5..3ed7d4d 100644
--- a/src/lib/blog/network-diagrams-wrong.md
+++ b/src/lib/blog/network-diagrams-wrong.md
@@ -72,7 +72,7 @@ What to look for:
- **Intuitive visualization**: Not just a device list. An interactive map showing how things connect, that anyone can quickly get up to speed on.
- **Shareable output**: The whole team should benefit without everyone needing a login or a license.
-If you want to see how the options stack up on those criteria, we put together a [comparison of automated network diagram tools](/comparisons/best-automated-network-diagram-tools) covering discovery method, live updates, and list pricing.
+If you want to see how the options stack up on those criteria, we put together a [network documentation tools comparison](/comparisons/best-automated-network-diagram-tools) covering discovery method, live updates, and list pricing.
We built [Scanopy](/) because we had this exact problem. Deploy a lightweight daemon on your network, point it at your subnets, and it discovers devices, maps connections via SNMP, and generates a topology map that updates itself on every scan. It detects [over 200 services](/services) automatically. New device shows up? It's on the next map.
diff --git a/src/lib/blog/network-documentation-template.md b/src/lib/blog/network-documentation-template.md
index 2617b7a..ffc1365 100644
--- a/src/lib/blog/network-documentation-template.md
+++ b/src/lib/blog/network-documentation-template.md
@@ -2,7 +2,7 @@
title: Network Documentation Template (Free) + Why Templates Fail
description: Free network documentation template covering device inventory, IP addressing, and VLANs. Download it, then learn why templates always go stale.
date: 2026-03-04
-dateModified: 2026-07-14
+dateModified: 2026-07-21
keyword: network documentation template
slug: network-documentation-template
tldr: A network documentation template covering device inventory, IP addressing, VLANs, and connections. Templates are a reasonable starting point, but they go out of date within days. Automated discovery keeps documentation accurate without the upkeep.
@@ -51,6 +51,8 @@ Also, my homelab was simple.
### Topology Notes
+This is the part a table can't hold: how the segments connect, what's deliberately isolated from what, and the one or two decisions future-you will have forgotten the reason for. Keep it to a few lines. It's the section that saves you at 3am.
+
- Internet -> router01 -> LAN (flat network)
- WireGuard on beelink01 for remote access
- Guest network isolated by router, internet only
@@ -98,7 +100,7 @@ That is why I stopped maintaining a spreadsheet. And yes, you can embed your own
I built this for my homelab. Brandon Lee at VirtualizationHowTo [put it through its paces](https://www.virtualizationhowto.com/2025/12/stop-drawing-network-diagrams-manually-scanopy-does-it-for-you/) on a production network and came to the same conclusion: manual diagrams don't survive contact with a real environment.
-Scanopy isn't the only tool that does this. If you want to weigh the options, we [compared the best automated network diagram tools](/comparisons/best-automated-network-diagram-tools) by discovery method, pricing, and how often the map updates.
+Scanopy isn't the only tool that does this. If you want to weigh the options, we [compared network documentation tools](/comparisons/best-automated-network-diagram-tools) by discovery method, pricing, and how often the map updates.
The template gives you a snapshot of column headers. Scanopy gives you an interactive, shareable map you can embed anywhere, and it can't go stale because it's reading the network directly. If you still want the spreadsheet, Scanopy exports CSVs and has an API. Same data, always current.
diff --git a/src/lib/blog/network-person-leaves.md b/src/lib/blog/network-person-leaves.md
index 1f10405..a19d1e8 100644
--- a/src/lib/blog/network-person-leaves.md
+++ b/src/lib/blog/network-person-leaves.md
@@ -98,7 +98,7 @@ You don't need a month-long documentation initiative. Start with these:
2. **List the undocumented decisions.** Not the configs (those are in the devices) but the _why_ behind the configs. Why is the network segmented this way? Why does that rule exist? Write down the reasoning, not just the settings.
-3. **Run an automated discovery scan.** Even a single scan gives the next person a starting point. They'll know what's on the network without having to trace cables. If you're picking a tool, our [comparison of automated network diagram tools](/comparisons/best-automated-network-diagram-tools) breaks down discovery method and pricing across the main options.
+3. **Run an automated discovery scan.** Even a single scan gives the next person a starting point. They'll know what's on the network without having to trace cables. If you're picking a tool, our [network documentation tools comparison](/comparisons/best-automated-network-diagram-tools) breaks down discovery method and pricing across the main options.
4. **Export your current network state.** If your network topology lives in someone's head, get it out. A rough diagram is better than no diagram. An [auto-generated one](/blog/network-diagrams-wrong) is better than both.
diff --git a/src/lib/compare/alternatives-pages.ts b/src/lib/compare/alternatives-pages.ts
index 5d5e679..e92685c 100644
--- a/src/lib/compare/alternatives-pages.ts
+++ b/src/lib/compare/alternatives-pages.ts
@@ -102,6 +102,11 @@ export function buildAltIntro(vendor: Vendor): string {
const name = vendorDisplayName(vendor);
const parts: string[] = [];
+ // Lead with the singular "alternative" framing so the page covers both the singular
+ // query ("librenms alternative") and the plural one ("librenms alternatives"); the
+ // title, H1, and H2 already carry the plural.
+ parts.push(`Looking for a ${name} alternative?`);
+
if (vendor.bestFor) {
parts.push(`${name} is built for ${lowerFirst(trimSentence(vendor.bestFor))}.`);
}
diff --git a/src/lib/comparisons/best-automated-network-diagram-tools.md b/src/lib/comparisons/best-automated-network-diagram-tools.md
index d8ccde9..9c18bfc 100644
--- a/src/lib/comparisons/best-automated-network-diagram-tools.md
+++ b/src/lib/comparisons/best-automated-network-diagram-tools.md
@@ -1,18 +1,18 @@
---
-title: Best Automated Network Diagram Tools 2026 (Real Pricing)
-description: '13 automated network diagram tools compared on discovery method, live updates, and list pricing, including free and open-source options. Updated for 2026.'
-keyword: best automated network diagram tool
+title: 'Network Documentation Tools 2026: 13 Compared (Real Pricing)'
+description: '13 network documentation tools compared on discovery method, live updates, and real pricing, including free and open-source options. Updated for 2026.'
+keyword: network documentation tools
slug: best-automated-network-diagram-tools
date: 2026-04-01
-dateModified: 2026-07-14
+dateModified: 2026-07-21
style: comparison
-tldr: "The best automated network diagram tool for most IT teams is one that combines auto-discovery with exportable, shareable diagrams, not a monitoring dashboard with a map tab bolted on. Most tools marketed as 'automated' are either monitoring platforms that include mapping as a feature, or manual drawing tools with no discovery. Here's what each of the 13 tools does, what it costs, and which one fits your network."
+tldr: "The best network documentation tool for most IT teams combines automatic discovery with an exportable, shareable map, not a monitoring dashboard with a map tab bolted on. Most tools marketed as 'automated' are either monitoring platforms that include mapping as a feature, or manual drawing tools with no discovery. Here's what each of the 13 tools does, what it costs, and which one fits your network."
ctaDescription: Scanopy deploys a lightweight daemon that discovers your network and builds a live topology map. No per-device fees, unlimited hosts. It pairs with whatever monitoring tool you already use.
---
-## Three Categories: Monitoring Platforms, Dedicated Diagram Tools, and Manual Drawing Tools
+## Network Documentation Tools Fall Into Three Categories: Monitoring Platforms, Dedicated Tools, and Manual Drawing Tools
-There are three categories of network diagram tools: **monitoring platforms** that include mapping as a feature, **dedicated diagram tools** that focus only on documentation, and **manual diagramming tools** where you draw everything yourself. The right choice of network diagram software depends on whether you need monitoring bundled in, how often diagrams need to update, and your budget. If you think of this as building a live map rather than a static diagram, see our [network mapping software](/guides/network-mapping-software) guide.
+There are three categories of network documentation tools: **monitoring platforms** that include mapping as a feature, **dedicated documentation tools** that focus only on documenting the network, and **manual diagramming tools** where you draw everything yourself. The right choice depends on whether you need monitoring bundled in, how often the documentation needs to update, and your budget. If you think of this as building a live map rather than a static diagram, see our [network mapping software](/guides/network-mapping-software) guide.
| Scenario | Recommendation |
| ---------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
@@ -24,9 +24,19 @@ There are three categories of network diagram tools: **monitoring platforms** th
| Budget monitoring + mapping | [Domotz](#domotz) ($1.50/device/mo) or [ManageEngine](#manageengine-opmanager) ($95/yr) |
| Free and self-hosted | [LibreNMS](#librenms) for monitoring with basic maps. [NetDisco](#netdisco) for Layer 2 topology discovery. [Scanopy Community Edition](/community) for documentation-focused mapping. [draw.io](#drawio) for manual diagrams. All free. |
-## "Automated" Means the Tool Discovers the Network and Draws the Diagram for You
+## A Network Documentation Tool Answers Three Questions and Keeps the Answers Current
-"Automated" means the tool discovers your network and produces a diagram without you drawing anything. Most tools on this list do that. don't. They're manual diagramming tools, included because they are commonly recommended for this query. ([Here's a deeper look at how automated network documentation works](/blog/automated-network-documentation), and if you're weighing the broader category beyond diagrams (inventory, service detection, exports), see our [network documentation software guide](/guides/network-documentation-software).)
+Good network documentation software keeps the answers to three questions accurate as the network changes:
+
+- **What is on the network?** Hosts, their IP and MAC addresses, hostnames, and vendors. The deeper tools also fingerprint the services running on each host, so a box isn't just an IP, it's "the machine running Postgres, Nginx, and a stack of containers."
+- **How is it connected?** Physical links between switches, routers, and hosts, plus the logical layer of subnets and VLANs. This is the part manual diagrams get wrong first, because cabling and topology change without anyone updating the drawing.
+- **What changed?** A record you can trust over time, not a file someone last touched eighteen months ago.
+
+The output is usually a topology map plus a searchable inventory. A documentation tool derives that data from discovery; a drawing tool derives it from memory.
+
+## "Automated" Means the Tool Discovers the Network and Documents It for You
+
+"Automated" means the tool discovers your network and produces the documentation without you drawing anything. Most tools on this list do that. don't. They're manual diagramming tools, included because they are commonly recommended for this query. ([Here's a deeper look at how automated network documentation works](/blog/automated-network-documentation), and for the free, self-hosted options specifically, the [open-source network documentation guide](/guides/open-source-network-documentation).)
diff --git a/src/routes/comparisons/vs/[slug]/+page.svelte b/src/routes/comparisons/vs/[slug]/+page.svelte
index e6b4ef3..770f753 100644
--- a/src/routes/comparisons/vs/[slug]/+page.svelte
+++ b/src/routes/comparisons/vs/[slug]/+page.svelte
@@ -76,7 +76,7 @@
{
'@type': 'ListItem',
position: 2,
- name: `Best automated network diagram tools`,
+ name: `Network documentation tools`,
item: mainComparison
},
{ '@type': 'ListItem', position: 3, name: data.title, item: canonical }
@@ -177,7 +177,7 @@
best {data.vendorName} alternatives.{/if} For all 13 tools side by
side, see the
full comparison of automated network diagram toolsfull network documentation tools comparison.
diff --git a/src/routes/compliance/+page.svelte b/src/routes/compliance/+page.svelte
new file mode 100644
index 0000000..240a216
--- /dev/null
+++ b/src/routes/compliance/+page.svelte
@@ -0,0 +1,294 @@
+
+
+
+ {title}
+
+
+
+
+
+
+
+
+
+
+
+
+ {@html ``}
+ {@html ``}
+
+
+
+
+
+
+
+ Audit-ready network documentation,without the effort.
+
+
+ NIS2, ISO 27001, and HIPAA all expect network documentation that is accurate today, not last
+ year. Scanopy discovers your network and keeps the map and inventory current on a schedule,
+ so the evidence is ready before the auditor asks.
+
+ One scan produces four topology views, generated from the live network rather than redrawn
+ by hand. Each answers a question an assessor asks: what's on the network, how it's
+ segmented, what runs where, and how data moves between systems.
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Hand auditors evidence in whatever form they want
+
+
+ Producing the evidence stops being a scramble before each assessment. The current map is
+ always a click from a document, a live embed, a shared link, or a dated record.
+
+
+
+
+
+
+
+
+
+
+ Self-hosted keeps the data on your infrastructure
+
+
+ Run Scanopy fully self-hosted and the network data never leaves your infrastructure. How
+ Scanopy handles data in each deployment model, with subprocessors and security practices, is
+ on the security page.
+