Sync build v0.9.331

Automated sync from private repository.
Commit: 9af4296bf76ec06701a74b45b977c9e0c17707a3
This commit is contained in:
GitHub Actions Bot
2026-07-08 00:55:53 +00:00
parent 2d961cef1a
commit 11a7a8392e
171 changed files with 1541 additions and 1640 deletions
+7 -1
View File
@@ -52,9 +52,15 @@ jobs:
fi
fi
- name: Resolve safe ref name
id: ref_name
run: |
SAFE_REF_NAME="$(echo "${{ github.ref_name }}" | tr '/:@' '---')"
echo "safe_name=$SAFE_REF_NAME" >> "$GITHUB_OUTPUT"
- name: Upload build artifacts (for inspection)
uses: actions/upload-artifact@v4
with:
name: pymc-ui-${{ github.ref_name }}
name: pymc-ui-${{ steps.ref_name.outputs.safe_name }}
path: frontend/dist/
retention-days: 7
+49 -49
View File
@@ -1,11 +1,11 @@
# pyMC Console
# openHop Console
[![GitHub Release](https://img.shields.io/github/v/release/dmduran12/pymc_console-dist)](https://github.com/dmduran12/pymc_console-dist/releases)
[![GitHub Release](https://img.shields.io/github/v/release/Treehouse-00/pymc_console)](https://github.com/Treehouse-00/pymc_console/releases)
[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE)
A real-time web dashboard for [MeshCore](https://meshcore.io/) LoRa mesh repeaters.
pyMC Console gives you full visibility into your mesh network — packet flow, topology, signal quality, RF metrics, and radio configuration — through a single browser tab. It layers on top of [pyMC_Repeater](https://github.com/pyMC-dev/pyMC_Repeater) without modifying it.
openHop Console gives you full visibility into your MeshCore network — packet flow, topology, signal quality, RF metrics, GPS diagnostics, and radio configuration — through a single browser tab. It layers on top of [openHop Repeater](https://github.com/openhop-dev/openhop_repeater) without replacing the Repeater service.
---
@@ -17,27 +17,27 @@ pyMC Console gives you full visibility into your mesh network — packet flow, t
- LoRa radio module (SX1262 or SX1276)
- Raspberry Pi OS (Bookworm recommended)
### Prerequisite: pyMC_Repeater
### Prerequisite: openHop Repeater
The Console dashboard plugs into an existing [pyMC_Repeater](https://github.com/pyMC-dev/pyMC_Repeater) install. If you don't already have it running, install it first using upstream's manage.sh:
The Console dashboard plugs into an existing [openHop Repeater](https://github.com/openhop-dev/openhop_repeater) install. If you don't already have it running, install Repeater first using the Repeater repo's `manage.sh`:
```bash
git clone https://github.com/pyMC-dev/pyMC_Repeater.git
cd pyMC_Repeater
sudo ./manage.sh install
git clone https://github.com/openhop-dev/openhop_repeater.git
cd openhop_repeater
sudo bash ./manage.sh install
```
Upstream handles system dependencies, pip install, radio/GPIO configuration, and the systemd service.
Repeater handles system dependencies, the `/opt/openhop_repeater` virtualenv, radio/GPIO configuration, `/etc/openhop_repeater/config.yaml`, and the `openhop-repeater` systemd service.
### Install the Console
```bash
git clone https://github.com/dmduran12/pymc_console-dist.git pymc_console
git clone https://github.com/Treehouse-00/pymc_console.git pymc_console
cd pymc_console
sudo bash manage.sh install
```
This downloads the latest Console release, extracts it to `/opt/pymc_console/web/html/`, and points pyMC_Repeater's `web.web_path` at it. Open `http://<your-pi-ip>:8000` in a browser.
This downloads the latest Console release, extracts it to `/opt/pymc_console/web/html/`, and points Repeater's `web.web_path` at it. Open `http://<your-repeater-ip>:8000` in a browser.
### Upgrade the Console
@@ -46,7 +46,7 @@ cd pymc_console
sudo bash manage.sh upgrade
```
Refreshes the dashboard assets in place. Your `web_path` setting is preserved. Repeater, core, and config are untouched. For upgrading pyMC_Repeater itself, use upstream's manage.sh.
Refreshes the dashboard assets in place. Your `web_path` setting is preserved. Repeater, core, and config are untouched. For upgrading openHop Repeater itself, use the Repeater repo's `manage.sh`.
### Uninstall the Console
@@ -55,7 +55,7 @@ cd pymc_console
sudo bash manage.sh uninstall
```
Removes `/opt/pymc_console` and this repo. pyMC_Repeater is **not** touched — use upstream's manage.sh to remove it.
Removes `/opt/pymc_console` and this repo. openHop Repeater is **not** touched — use the Repeater repo's `manage.sh` to remove it.
### Non-interactive Mode
@@ -72,7 +72,7 @@ ASSUME_YES=1 sudo -E bash manage.sh upgrade
```
┌─────────────────────────────────────────────────────────────┐
pyMC Console
openHop Console │
│ (this repo — web dashboard UI) │
│ │
│ • React SPA served on port 8000 │
@@ -81,8 +81,8 @@ ASSUME_YES=1 sudo -E bash manage.sh upgrade
└─────────────────────┬───────────────────────────────────────┘
│ uses API from
┌─────────────────────▼───────────────────────────────────────┐
pyMC_Repeater
(RightUp's repeater daemon) │
openHop Repeater │
(openHop repeater daemon)
│ │
│ • Python daemon running the LoRa repeater │
│ • REST API + WebSocket on port 8000 │
@@ -90,8 +90,8 @@ ASSUME_YES=1 sudo -E bash manage.sh upgrade
└─────────────────────┬───────────────────────────────────────┘
│ built on
┌─────────────────────▼───────────────────────────────────────┐
pyMC_core │
(RightUp's protocol library) │
openHop Core │
(MeshCore protocol library)
│ │
│ • Low-level MeshCore protocol implementation │
│ • Radio drivers (SX1262, SX1276) │
@@ -101,7 +101,7 @@ ASSUME_YES=1 sudo -E bash manage.sh upgrade
**Key points:**
- Console does **not** replace Repeater — they work together
- Repeater is installed separately using upstream's manage.sh; our `manage.sh` layers the Console on top
- Repeater is installed separately using openHop Repeater's `manage.sh`; Console's `manage.sh` only layers the dashboard on top
- You can upgrade Console independently without touching Repeater
---
@@ -189,7 +189,7 @@ Two polished color schemes and a built-in CLI for direct repeater interaction.
### manage.sh Commands
`manage.sh` is Console-only. Service control, status, logs, and radio/GPIO configuration are all handled by upstream pyMC_Repeater.
`manage.sh` is Console-only. Service control, status, logs, updates, and radio/GPIO configuration are all handled by openHop Repeater.
```bash
sudo bash manage.sh --help
@@ -197,24 +197,24 @@ sudo bash manage.sh --help
| Verb | Action |
|------|--------|
| `install` | Install the Console dashboard into `/opt/pymc_console` and point `web_path` at it. Requires pyMC_Repeater to be installed. |
| `upgrade` | Refresh the dashboard assets in place. Preserves your `web_path` and self-updates this repo from `origin/main`. |
| `uninstall` | Remove `/opt/pymc_console` and this repo. Does NOT touch pyMC_Repeater. |
| `install` | Install the Console dashboard into `/opt/pymc_console` and point `web_path` at it. Requires openHop Repeater to be installed. |
| `upgrade` | Refresh the dashboard assets in place. Preserves your `web_path` and self-updates this repo from `origin/main`. Repeater stays untouched. |
| `uninstall` | Remove `/opt/pymc_console` and this repo. Does NOT touch openHop Repeater. |
Flags: `--yes` / `-y` (or `ASSUME_YES=1`) auto-confirms prompts; `NO_COLOR=1` disables ANSI output.
### Radio & GPIO Configuration
Radio and GPIO settings are managed by upstream pyMC_Repeater:
Radio and GPIO settings are managed by openHop Repeater:
```bash
cd ~/pyMC_Repeater && sudo ./manage.sh
cd ~/openhop_repeater && sudo bash ./manage.sh
```
Or edit the config directly:
```yaml
# /etc/pymc_repeater/config.yaml
# /etc/openhop_repeater/config.yaml
radio:
frequency: 927875000 # Hz
spreading_factor: 7 # SF7SF12
@@ -240,15 +240,15 @@ radio:
### Service Management
Service lifecycle belongs to pyMC_Repeater's systemd unit. Use `systemctl` / `journalctl` directly:
Service lifecycle belongs to openHop Repeater's systemd unit. Use `systemctl` / `journalctl` directly:
```bash
sudo systemctl status pymc-repeater # Check status
sudo systemctl restart pymc-repeater # Restart
sudo journalctl -u pymc-repeater -f # Live logs
sudo systemctl status openhop-repeater # Check status
sudo systemctl restart openhop-repeater # Restart
sudo journalctl -u openhop-repeater -f # Live logs
```
`manage.sh` does not wrap these commands — they are upstream's responsibility.
`manage.sh` does not wrap these commands — they are Repeater's responsibility.
---
@@ -258,12 +258,12 @@ After installation:
```
~/pymc_console/ ← This repo (cloned by you)
~/pyMC_Repeater/ Upstream repeater source (cloned by you)
~/openhop_repeater/ ← openHop Repeater source (cloned by you)
/opt/pymc_repeater/ ← Installed repeater (owned by upstream manage.sh)
/opt/openhop_repeater/ ← Installed Repeater (owned by Repeater manage.sh)
/opt/pymc_console/web/html/ ← Installed dashboard (owned by our manage.sh)
/etc/pymc_repeater/config.yaml ← Radio + repeater config (we patch web.web_path only)
/var/log/pymc_repeater/ ← Log files (upstream)
/etc/openhop_repeater/config.yaml ← Radio + Repeater config (we patch web.web_path only)
/var/log/openhop_repeater/ ← Repeater log files
```
---
@@ -285,7 +285,7 @@ After installation:
### Connection
LoRa module connects via **SPI** with GPIO pins for reset, busy, and DIO1. Pin mapping is configured during installation via pyMC_Repeater's manage.sh.
LoRa module connects via **SPI** with GPIO pins for reset, busy, and DIO1. Pin mapping is configured during installation via openHop Repeater's manage.sh.
---
@@ -295,7 +295,7 @@ LoRa module connects via **SPI** with GPIO pins for reset, busy, and DIO1. Pin m
1. **Is the service running?**
```bash
sudo systemctl status pymc-repeater
sudo systemctl status openhop-repeater
```
2. **Is port 8000 responding?**
```bash
@@ -303,7 +303,7 @@ LoRa module connects via **SPI** with GPIO pins for reset, busy, and DIO1. Pin m
```
3. **Check for errors:**
```bash
sudo journalctl -u pymc-repeater -n 50
sudo journalctl -u openhop-repeater -n 50
```
### Login fails / "Error 200"
@@ -311,8 +311,8 @@ LoRa module connects via **SPI** with GPIO pins for reset, busy, and DIO1. Pin m
Usually caused by a version mismatch between Console and Repeater. Update both:
```bash
# Update pyMC_Repeater (upstream)
cd ~/pyMC_Repeater && sudo ./manage.sh upgrade
# Update openHop Repeater
cd ~/openhop_repeater && sudo bash ./manage.sh upgrade
# Update the Console dashboard
cd ~/pymc_console && sudo bash manage.sh upgrade
@@ -326,23 +326,23 @@ cd ~/pymc_console && sudo bash manage.sh upgrade
```
If no devices listed, enable SPI via `raspi-config` → Interface Options → SPI.
2. **GPIO correct?** Run pyMC_Repeater's manage.sh → Configure GPIO and verify pin assignments match your wiring.
2. **GPIO correct?** Run openHop Repeater's manage.sh → Configure GPIO and verify pin assignments match your wiring.
3. **Frequency match?** Confirm your radio frequency matches the rest of your mesh network.
4. **Check the logs:**
```bash
sudo journalctl -u pymc-repeater -n 100 | grep -i "error\|fail\|radio"
sudo journalctl -u openhop-repeater -n 100 | grep -i "error\|fail\|radio"
```
### Service won't start
```bash
# Check for config syntax errors
python3 -c "import yaml; yaml.safe_load(open('/etc/pymc_repeater/config.yaml'))"
python3 -c "import yaml; yaml.safe_load(open('/etc/openhop_repeater/config.yaml'))"
# Check for Python dependency issues
pip3 show pymc-repeater pymc-core
/opt/openhop_repeater/venv/bin/python -m pip show openhop_repeater openhop_core
```
### "Radio presets file not found" during install
@@ -351,7 +351,7 @@ Non-fatal warning. The installer fetches presets from an API; if unavailable, it
### Dashboard loads but shows no data
- The dashboard requires authentication. If you see the login page, use the credentials you set during pyMC_Repeater installation.
- The dashboard requires authentication. If you see the login page, use the credentials you set during openHop Repeater installation.
- If you're on a fresh install, allow 3060 seconds for the repeater to initialize and begin receiving packets.
- Check that WebSocket is connecting: open browser DevTools → Network → WS. You should see an active `/ws/packets` connection.
@@ -415,7 +415,7 @@ The frontend includes a complete TypeScript port of the MeshCore protocol — bi
## Standalone UI Installation
If you already have pyMC_Repeater running and just want the dashboard, see [INSTALL.md](INSTALL.md) for manual tar.gz installation without manage.sh.
If you already have openHop Repeater running and just want the dashboard, see [INSTALL.md](INSTALL.md) for manual tar.gz installation without manage.sh.
---
@@ -427,9 +427,9 @@ MIT — See [LICENSE](LICENSE)
Built on the work of:
- **[RightUp](https://github.com/rightup)** — Creator of pyMC_Repeater, pymc_core, and the MeshCore Python ecosystem
- **[pyMC_Repeater](https://github.com/pyMC-dev/pyMC_Repeater)** — Core repeater daemon
- **[pymc_core](https://github.com/rightup/pyMC_core)** — Protocol library
- **[RightUp](https://github.com/rightup)** — Creator of the original pyMC Repeater/Core projects and a maintainer of the MeshCore Python ecosystem
- **[openHop Repeater](https://github.com/openhop-dev/openhop_repeater)** — Core repeater daemon
- **[openHop Core](https://github.com/openhop-dev/openhop_core)** — Protocol library
- **[MeshCore](https://meshcore.io/)** — The MeshCore project and community
- **[d40cht/meshcore-connectivity-analysis](https://github.com/d40cht/meshcore-connectivity-analysis)** — Viterbi HMM approach for path disambiguation
- **[meshcore-bot](https://github.com/agessaman/meshcore-bot)** — Recency scoring and dual-hop anchor disambiguation
+120
View File
@@ -0,0 +1,120 @@
# openHop RepeaterUI Parity Inventory
Source references verified for this local branch work:
- React Console repo: `/home/yellowcooln/openhop-dev/pymc_console`, branch `feature/openhop-console-repeater-parity-local`.
- RepeaterUI reference: `/tmp/openHop_RepeaterUI_feat_update_branding`, branch `feat-update-branding`, inspected plan commit `ce4df83`.
- Repeater backend reference: `/tmp/openhop_repeater_reference`, inspected plan commit `60357f5`.
This file records code-verified implementation status. RepeaterUI and openhop_repeater are reference-only for this task.
## Default UI feature acceptance matrix
| Default UI file | Console target | Status | Acceptance criteria |
| --- | --- | --- | --- |
| `views/Dashboard.vue` | `/` / `frontend/src/pages/Dashboard.tsx` | complete | Existing richer Console dashboard remains the home route. |
| `views/Login.vue` | `/login` / `frontend/src/pages/Login.tsx` | complete | Login remains public and branded as openHop Console. |
| `views/Setup.vue` | `/setup` / `frontend/src/pages/Setup.tsx` | thin | First-run flow uses `/api/needs_setup`, hardware, presets, serial, and setup wizard helpers; further field-level parity can deepen without blocking shell route. |
| `views/Neighbors.vue` | `/neighbors` -> `/contacts` | mapped | Console Contacts map/topology stays the richer neighbor view. |
| `views/Statistics.vue` | `/statistics` | complete | Existing charts remain reachable. |
| `views/RfHealthCorrelation.vue` | `/rf-health-correlation` | thin | Page renders RF correlation inputs and graceful unsupported states; deeper visual correlation remains incremental. |
| `views/GPSDiagnostics.vue` | `/gps` | thin | GPS status/stream route exists with unsupported states. |
| `views/SystemStats.vue` | `/system-stats` -> `/system` | mapped | Existing System page remains the richer system stats target. |
| `views/Sensors.vue` | `/sensors` | thin | Sensor Readings route renders known/generic sensors and empty states. |
| `views/Configuration.vue` | `/configuration` | complete | Existing Console configuration preserved; default tab IDs are now discoverable through query/deep links. |
| `components/configuration/RadioSettings.vue` | `/configuration?tab=radio` | complete | Radio settings remain editable in the existing Configuration page. |
| `components/configuration/RadioHardwareSettings.vue` | `/radio-hardware`, `/configuration?tab=radio-hardware` | complete | Current hardware config, board presets, and serial ports are visible; no unsupported save button is shown. |
| `components/configuration/RepeaterSettings.vue` | `/configuration?tab=repeater` | complete | Node/location/repeater controls remain visible in Configuration. |
| `components/configuration/AdvertSettings.vue` | `/configuration?tab=advert` | mapped | Advert interval and advert rate limiting are represented by Configuration and `AdvertRateLimitCard`. |
| `components/configuration/DutyCycle.vue` | `/configuration?tab=duty` | complete | Duty cycle toggle/max airtime remain editable in Configuration. |
| `components/configuration/TransmissionDelays.vue` | `/configuration?tab=delays` | complete | Flood/direct TX delay factors are displayed as factors (`x`), not seconds. |
| `components/configuration/TransportKeys.vue` | `/configuration?tab=transport` | complete | Transport key tree, add/edit/delete, and unscoped flood policy remain present. |
| `components/configuration/APITokens.vue` | `/configuration?tab=api-tokens` | complete | Token creation/revocation remains present. |
| `components/configuration/WebSettings.vue` | `/configuration?tab=web` | complete | Web frontend, CORS, theme/app controls remain present. |
| `components/configuration/LetsMeshSettings.vue` | `/observer`, `/configuration?tab=observer` | complete | `/observer` manages repeater-side MQTT publisher/Observer; `/mqtt` remains Console browser-side subscriber/source tooling. |
| `components/configuration/PolicyEngineSettings.vue` | `/policy-engine`, `/policies`, `/configuration?tab=policy-engine` | complete | Policy document state, groups, entries, add/remove, and confirm-delete UI are available with graceful unsupported states. |
| `components/configuration/BackupRestore.vue` | `/backup`, `/backup-restore`, `/configuration?tab=backup` | complete | Settings export, full backup, import, and identity key export are available with HTTP/secret warnings and confirmations. |
| `components/configuration/DatabaseManagement.vue` | `/database`, `/database-management`, `/configuration?tab=database` | complete | DB stats, table row counts, vacuum, selected purge, and typed-confirm purge-all are available. |
| `components/configuration/MemoryDebug.vue` | `/memory`, `/configuration?tab=memory` | complete | Process/GC/allocation diagnostics load, refresh, and snapshot action are available with collapsed large details. |
| `views/CADCalibration.vue` | `/cad-calibration` | thin | CAD workflow route uses underscore endpoints and closes stream on navigation/stop. |
| `views/Sessions.vue` | `/sessions` | complete | Existing sessions page preserved. |
| `views/RoomServers.vue` | `/room-servers` -> `/room-server` | mapped | Existing Room Server page preserved. |
| `views/Companions.vue` | `/companions` -> `/companion` | mapped | WebUI Companion remains preserved. |
| `views/Logs.vue` | `/logs` | complete | Existing logs page preserved. |
| `views/Terminal.vue` | `/terminal` | complete | Existing browser terminal preserved. |
| `views/Help.vue` | `/help` | complete | Help describes default parity additions and Console-only extras. |
Console-only preserved features are not default UI gaps: `/contacts`, `/mqtt`, `/companion`, `/meshgraph`, `/raw`, `/test`, packet pipeline workers, WebUI Companion, external source tooling, and Signal Lab.
## Routes
| RepeaterUI route | Console route/status | Notes |
| --- | --- | --- |
| `/` | already present | Existing Dashboard preserved. |
| `/login` | already present | Branding pass only. |
| `/setup` | ported shell | Public route added with hardware/preset/serial/setup_wizard clients. |
| `/neighbors` | mapped | Redirects to existing `/contacts` to preserve Contacts map/topology. |
| `/statistics` | already present | Existing charts preserved. |
| `/rf-health-correlation` | ported shell | Uses packet stats, CRC, noise floor, metrics, and local packet cache when available. |
| `/rf-health` | mapped | Redirects to `/rf-health-correlation`. |
| `/gps` | ported shell | Uses `/api/gps` and `/api/gps_stream` with disabled/unsupported states. |
| `/gps-diagnostics` | mapped | Redirects to `/gps`. |
| `/system-stats` | mapped | Redirects to existing `/system`. |
| `/sensors` | ported shell | Renders generic `stats.sensors` as Sensor Readings; no raw JSON blobs for nested values. |
| `/configuration` | already present + additive hooks | Existing monolithic Console Configuration preserved; new API clients exported for future panels. |
| `/radio-hardware` | ported | Read-only current hardware, serial ports, and hardware presets. |
| `/observer` | ported | Adds RepeaterUI Observer identity + MQTT broker management; `/observers` and `/mqtt-management` redirect here. |
| `/policy-engine` | ported | Policy document state, groups, entries, add/remove, and confirm-delete UI. |
| `/database` | ported | Database stats, vacuum, selected purge, and typed-confirm purge all. |
| `/memory` | ported | Process memory, GC, top allocations, refresh, and diagnostic snapshot. |
| `/backup` | ported | Settings export, full backup, import, and identity key export with confirmations. |
| `/cad-calibration` | ported shell | Uses underscore CAD endpoints and closes SSE on unmount/stop. |
| `/cad` | mapped | Redirects to `/cad-calibration`. |
| `/sessions` | already present | Preserved. |
| `/room-servers` | mapped | Redirects to existing `/room-server`. |
| `/companions` | mapped | Redirects to existing `/companion`; WebUI Companion remains present. |
| `/logs` | already present | Preserved. |
| `/terminal` | already present | Preserved. |
| `/help` | ported | New Help page documenting Console/openHop compatibility boundaries. |
| `/raw` | Console-only preserved | Packet Observatory remains hidden/developer accessible. |
| `/meshgraph` | Console-only preserved | Visible in System group. |
| `/mqtt` | Console-only preserved | Sources/external DB/MQTT tooling remains visible. |
## Endpoint/client parity
| Area | Endpoint(s) | Status |
| --- | --- | --- |
| Setup | `/api/needs_setup`, `/api/hardware_options`, `/api/radio_presets`, `/api/serial_ports`, `/api/setup_wizard` | `frontend/src/commands/setup.ts` added. |
| GPS | `/api/gps`, `/api/gps_stream` | `frontend/src/commands/gps.ts` added; uses underscore stream endpoint. |
| CAD | `/api/cad_calibration_start`, `/api/cad_calibration_stop`, `/api/cad_calibration_stream`, `/api/save_cad_settings` | `frontend/src/commands/cad.ts` added; uses underscore endpoint names. |
| RF health | `/api/packet_stats`, `/api/noise_floor_history`, `/api/crc_error_count`, `/api/crc_error_history`, `/api/metrics_graph_data` | Existing stats commands reused by new page. |
| Database | `/api/db_stats`, `/api/db_purge`, `/api/db_vacuum` | `frontend/src/commands/maintenance.ts` added. |
| Memory | `/api/memory_debug` | `frontend/src/commands/maintenance.ts` added. |
| Backup/Restore | `/api/config_export`, `/api/config_import`, `/api/identity_export` | `frontend/src/commands/backup.ts` added. |
| Observer/MQTT | `/api/mqtt_status`, `/api/broker_presets`, `/api/update_mqtt_config` | `frontend/src/commands/maintenance.ts` typed helpers plus `/observer` management UI added. |
| Policy Engine | `/api/policy`, `/api/policy_groups`, `/api/policy_group_entries` | `frontend/src/commands/policy.ts` added. |
| Compatibility frontend check | `/api/check_pymc_console` | Existing system command preserved. |
## Configuration parity
The current `Configuration.tsx` is still monolithic and already contains important Console functionality: radio settings, repeater settings, duty cycle, transport keys, web frontend switching, API tokens, theme/app settings, software update, stealth location, and flood-loop detection. This pass did not replace it. Added client modules make the following panels ready for incremental extraction/porting:
- Radio hardware and serial ports.
- Observer/MQTT broker presets/status/configuration, now exposed at `/observer`.
- Policy Engine and policy groups/entries.
- Database stats/purge/vacuum.
- Memory diagnostics.
- CAD calibration link/page.
## Branding and compatibility notes
- User-facing app shell accessibility labels and web frontend text now say `openHop Console`.
- The legacy component export `PyMCConsoleLogo` is intentionally retained to avoid broad import churn, but it renders `openHop:Console`.
- Compatibility identifiers intentionally preserved: `/opt/pymc_console/web/html`, `/api/check_pymc_console`, `pymc_usb`, `pymc_tcp`, local storage/auth keys, protocol fields, and existing install/update paths unless the backend actually changes them.
- Current openHop Repeater runtime paths to prefer in new user-facing help/config copy: `/opt/openhop_repeater`, `/etc/openhop_repeater`, `/var/lib/openhop_repeater`, `/var/log/openhop_repeater`, `openhop-repeater.service`.
## Deferred work
- Full setup wizard validation/parity can be deepened once the target backend payload schema is locked.
- Full Configuration refactor into modular panels is intentionally deferred to avoid destabilizing the existing Console-only configuration features in one large edit.
- Browser smoke and endpoint live verification require a running Repeater target or local dev server; this local pass only adds graceful unsupported states.
+1 -1
View File
@@ -1 +1 @@
0.9.329
0.9.331
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
-1
View File
@@ -1 +0,0 @@
import{r as o}from"./index-DeL-WnAD.js";import{u as w}from"./maplibre-gl-BFLemsGw.js";const C={light:"https://basemaps.cartocdn.com/gl/positron-gl-style/style.json",dark:"https://basemaps.cartocdn.com/gl/dark-matter-gl-style/style.json"},x={light:"basemap-light-",dark:"basemap-dark-"},k={};async function E(i){if(k[i])return k[i];const t=await(await fetch(C[i])).json();return k[i]=t,t}function R({mode:i}){const{current:l}=w(),[t,b]=o.useState(null),u=o.useRef({light:!1,dark:!1}),m=o.useRef({light:[],dark:[]});o.useEffect(()=>{const e=()=>{var a;const s=(a=l==null?void 0:l.getMap)==null?void 0:a.call(l);s&&!t&&b(s)};e();const r=setInterval(e,50),c=setTimeout(()=>clearInterval(r),5e3);return()=>{clearInterval(r),clearTimeout(c)}},[l,t]);const g=o.useCallback(async(e,r,c)=>{var L,I;if(u.current[r])return;const s=x[r],a=await E(r),d=[];for(const[y,f]of Object.entries(a.sources||{})){const n=s+y;e.getSource(n)||e.addSource(n,f)}const v=(I=(((L=e.getStyle())==null?void 0:L.layers)||[]).find(y=>!y.id.startsWith("basemap-light-")&&!y.id.startsWith("basemap-dark-")))==null?void 0:I.id;for(const y of a.layers||[]){const f=s+y.id;if(d.push(f),e.getLayer(f))continue;const n={...y,id:f};"source"in n&&typeof n.source=="string"&&(n.source=s+n.source),n.layout||(n.layout={}),n.layout.visibility=c?"visible":"none";try{e.addLayer(n,v)}catch(S){console.warn(`[BasemapLayer] Failed to add layer ${f}:`,S)}}m.current[r]=d,u.current[r]=!0},[]),h=o.useCallback((e,r,c)=>{const s=m.current[r],a=c?"visible":"none";for(const d of s)if(e.getLayer(d))try{e.setLayoutProperty(d,"visibility",a)}catch{}},[]),p=o.useCallback(e=>{var s;const c=(((s=e.getStyle())==null?void 0:s.layers)||[]).filter(a=>!a.id.startsWith("basemap-light-")&&!a.id.startsWith("basemap-dark-"));for(const a of c)try{e.moveLayer(a.id)}catch{}},[]);return o.useEffect(()=>{if(!t)return;const e=r=>{t.hasImage(r.id)||t.addImage(r.id,{width:1,height:1,data:new Uint8Array([0,0,0,0])})};return t.on("styleimagemissing",e),()=>{t.off("styleimagemissing",e)}},[t]),o.useEffect(()=>{if(!t)return;let e=!1;const r=async()=>{if(!e)try{await Promise.all([g(t,"light",i==="light"),g(t,"dark",i==="dark")]),e||p(t)}catch(s){console.error("[BasemapLayer] Setup error:",s)}};t.isStyleLoaded()?r():(t.once("style.load",r),t.once("load",()=>{!e&&!u.current.light&&r()}));const c=()=>{e||setTimeout(()=>{!e&&u.current.light&&u.current.dark&&p(t)},100)};return t.on("styledata",c),()=>{e=!0,t.off("styledata",c)}},[t,g,p,i]),o.useEffect(()=>{t&&(!u.current.light||!u.current.dark||(h(t,"light",i==="light"),h(t,"dark",i==="dark")))},[t,i,h]),null}export{R as B};
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1 +1 @@
import{r as d,j as s,aC as x,aL as m,bZ as g,c as C,aD as f,eJ as j,B as o}from"./index-DeL-WnAD.js";const u={danger:"text-sys-red",warning:"text-sys-indigo",default:"text-sys-blue"},p={danger:"danger",warning:"warning",default:"primary"};function N({isOpen:n,title:r="Confirm",message:l,confirmLabel:t="Confirm",cancelLabel:i="Cancel",variant:a="default",onConfirm:c,onCancel:e}){return s.jsxs(x,{open:n,onClose:e,size:"sm",children:[s.jsx(m,{icon:s.jsx(g,{className:C("w-5 h-5",u[a])}),title:r,onClose:e}),s.jsx(f,{children:s.jsx("p",{className:"text-sm text-fg-secondary",children:l})}),s.jsxs(j,{children:[s.jsx(o,{color:"muted",onClick:e,className:"flex-1",children:i}),s.jsx(o,{color:p[a],onClick:c,className:"flex-1",children:t})]})]})}const y=d.memo(N);export{y as C};
import{r as d,j as s,ay as x,aH as m,bX as g,c as f,az as C,eO as j,B as o}from"./index-DSXi6v0o.js";const u={danger:"text-sys-red",warning:"text-sys-indigo",default:"text-sys-blue"},p={danger:"danger",warning:"warning",default:"primary"};function N({isOpen:n,title:r="Confirm",message:l,confirmLabel:t="Confirm",cancelLabel:i="Cancel",variant:a="default",onConfirm:c,onCancel:e}){return s.jsxs(x,{open:n,onClose:e,size:"sm",children:[s.jsx(m,{icon:s.jsx(g,{className:f("w-5 h-5",u[a])}),title:r,onClose:e}),s.jsx(C,{children:s.jsx("p",{className:"text-sm text-fg-secondary",children:l})}),s.jsxs(j,{children:[s.jsx(o,{color:"muted",onClick:e,className:"flex-1",children:i}),s.jsx(o,{color:p[a],onClick:c,className:"flex-1",children:t})]})]})}const y=d.memo(N);export{y as C};
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1 +1 @@
import{r as a,cZ as d,j as o,c_ as N}from"./index-DeL-WnAD.js";import{A as g}from"./index-h4zodNdb.js";const I=a.memo(function({value:t,format:e,prefix:r,suffix:s,className:n,priority:m="medium"}){const[u,p]=a.useState(!1),[f,l]=a.useState(t);a.useEffect(()=>d(()=>{p(!0),l(0)},m),[m]),a.useEffect(()=>{u&&l(t)},[u,t]);const A=`${r??""}${t.toLocaleString(void 0,e)}${s??""}`;return u?o.jsx(g,{className:`${n??""} overflow-hidden`,format:e,prefix:r,suffix:s,transition:N.numberTicker,children:f}):o.jsx("span",{className:n,children:A})}),x={",":"punc",".":"punc-period",":":"punc-colon","/":"punc-slash"},c=/([,\.:\/])/g;function j(i){return i.split(c).map((e,r)=>{const s=x[e];return s?o.jsx("span",{className:s,children:e},r):e})}const S=a.memo(function({children:t,className:e="",as:r="span"}){const s=a.useMemo(()=>{let n;return typeof t=="number"?n=t.toLocaleString():Array.isArray(t)?n=t.join(""):n=String(t??""),c.test(n)?(c.lastIndex=0,j(n)):n},[t]);return o.jsx(r,{className:`data-tight ${e}`.trim(),children:s})});export{I as A,S as D};
import{r as a,c_ as d,j as o,c$ as N}from"./index-DSXi6v0o.js";import{A as g}from"./index-Dv9K0xV1.js";const b=a.memo(function({value:t,format:e,prefix:r,suffix:s,className:n,priority:m="medium"}){const[u,p]=a.useState(!1),[f,l]=a.useState(t);a.useEffect(()=>d(()=>{p(!0),l(0)},m),[m]),a.useEffect(()=>{u&&l(t)},[u,t]);const A=`${r??""}${t.toLocaleString(void 0,e)}${s??""}`;return u?o.jsx(g,{className:`${n??""} overflow-hidden`,format:e,prefix:r,suffix:s,transition:N.numberTicker,children:f}):o.jsx("span",{className:n,children:A})}),x={",":"punc",".":"punc-period",":":"punc-colon","/":"punc-slash"},c=/([,\.:\/])/g;function j(i){return i.split(c).map((e,r)=>{const s=x[e];return s?o.jsx("span",{className:s,children:e},r):e})}const I=a.memo(function({children:t,className:e="",as:r="span"}){const s=a.useMemo(()=>{let n;return typeof t=="number"?n=t.toLocaleString():Array.isArray(t)?n=t.join(""):n=String(t??""),c.test(n)?(c.lastIndex=0,j(n)):n},[t]);return o.jsx(r,{className:`data-tight ${e}`.trim(),children:s})});export{b as A,I as D};
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1 +1 @@
import{r as b,j as c,c as d}from"./index-DeL-WnAD.js";const g={hero:{mobile:12},"hero-tall":{mobile:12},"hero-auto":{mobile:12},panel:{mobile:12,md:6},feature:{mobile:12,md:6,lg:4},standard:{mobile:12,sm:6,lg:4,xl:3},compact:{mobile:6,lg:3},widget:{mobile:6,sm:4,md:3,lg:2},auto:{mobile:12}},p={hero:"bento-row-hero","hero-tall":"bento-row-hero-tall","hero-auto":"bento-row-hero-auto",panel:"bento-row-panel",feature:"bento-row-feature",standard:"bento-row-standard",compact:"bento-row-compact",widget:"bento-row-widget",auto:"bento-row-auto"};function w({template:o,children:r,className:e,gap:n}){const t=g[o],m=p[o],a=n==="none"?"gap-0":n==="sm"?"bento-gap-sm":n==="lg"?"bento-gap-lg":"bento-gap",i=b.Children.map(r,l=>!b.isValidElement(l)||l.type===u?l:c.jsx(u,{span:t.mobile,sm:t.sm,md:t.md,lg:t.lg,xl:t.xl,children:l}));return c.jsx("div",{className:d("bento-row",m,a,e),children:i})}function s(o,r=""){const e=r?`${r}:`:"";return o==="full"?`${e}col-span-full`:o==="auto"?`${e}col-auto`:o===1.5?`${e}bento-col-1-5`:`${e}bento-col-${o}`}function u({children:o,span:r,sm:e,md:n,lg:t,xl:m,ratio:a,className:i}){const l=d("bento-cell",s(r),e&&s(e,"sm"),n&&s(n,"md"),t&&s(t,"lg"),m&&s(m,"xl"),i);return c.jsx("div",{className:l,"data-ratio":a??void 0,style:a?{"--cell-ratio":a}:void 0,children:o})}export{u as C,w as R};
import{r as b,j as c,c as d}from"./index-DSXi6v0o.js";const g={hero:{mobile:12},"hero-tall":{mobile:12},"hero-auto":{mobile:12},panel:{mobile:12,md:6},feature:{mobile:12,md:6,lg:4},standard:{mobile:12,sm:6,lg:4,xl:3},compact:{mobile:6,lg:3},widget:{mobile:6,sm:4,md:3,lg:2},auto:{mobile:12}},p={hero:"bento-row-hero","hero-tall":"bento-row-hero-tall","hero-auto":"bento-row-hero-auto",panel:"bento-row-panel",feature:"bento-row-feature",standard:"bento-row-standard",compact:"bento-row-compact",widget:"bento-row-widget",auto:"bento-row-auto"};function w({template:o,children:r,className:e,gap:n}){const t=g[o],m=p[o],a=n==="none"?"gap-0":n==="sm"?"bento-gap-sm":n==="lg"?"bento-gap-lg":"bento-gap",i=b.Children.map(r,l=>!b.isValidElement(l)||l.type===u?l:c.jsx(u,{span:t.mobile,sm:t.sm,md:t.md,lg:t.lg,xl:t.xl,children:l}));return c.jsx("div",{className:d("bento-row",m,a,e),children:i})}function s(o,r=""){const e=r?`${r}:`:"";return o==="full"?`${e}col-span-full`:o==="auto"?`${e}col-auto`:o===1.5?`${e}bento-col-1-5`:`${e}bento-col-${o}`}function u({children:o,span:r,sm:e,md:n,lg:t,xl:m,ratio:a,className:i}){const l=d("bento-cell",s(r),e&&s(e,"sm"),n&&s(n,"md"),t&&s(t,"lg"),m&&s(m,"xl"),i);return c.jsx("div",{className:l,"data-ratio":a??void 0,style:a?{"--cell-ratio":a}:void 0,children:o})}export{u as C,w as R};
@@ -1 +1 @@
import{r as l,j as t,Z as O}from"./index-DeL-WnAD.js";import{b as F,c as x}from"./keycap-sfx-ByZp-njj.js";const R={a:"24,3 76,3 83,7 76,11 24,11 17,7",b:"88,22 93,27 93,71 88,76 83,71 83,27",c:"88,106 93,111 93,155 88,160 83,155 83,111",d:"24,171 76,171 83,175 76,179 24,179 17,175",e:"12,106 17,111 17,155 12,160 7,155 7,111",f:"12,22 17,27 17,71 12,76 7,71 7,27",g:"24,86 76,86 83,91 76,96 24,96 17,91"},w=Object.keys(R),N={0:"abcdef",1:"bc",2:"abdeg",3:"abcdg",4:"bcfg",5:"acdfg",6:"acdefg",7:"abc",8:"abcdefg",9:"abcdfg",A:"abcefg",B:"cdefg",C:"adef",D:"bcdeg",E:"adefg",F:"aefg",G:"acdef",H:"bcefg",I:"ef",J:"bcde",L:"def",M:"abcefg",N:"ceg",O:"abcdef",P:"abefg",Q:"abcfg",R:"eg",S:"acdfg",T:"defg",U:"bcdef",V:"cde",Y:"bcdfg",Z:"abdeg",a:"abcefg",b:"cdefg",c:"deg",d:"bcdeg",e:"adefg",f:"aefg",g:"abcdfg",h:"cefg",i:"c",j:"bcde",l:"def",m:"abcef",n:"ceg",o:"cdeg",p:"abefg",r:"eg",s:"acdfg",t:"defg",u:"cde",v:"cde",y:"bcdfg"," ":"",_:"d","-":"g","=":"dg","°":"abfg",'"':"bf","'":"f","(":"adef",")":"abcd","[":"adef","]":"abcd","!":"bc",".":"d"},C=6,D=56,L=2;function B(){return w.filter(()=>Math.random()>.45).join("")}function $(r,i){const n=Array.from(r).map(a=>N[a.toUpperCase()]??N[a]??""),d=Math.max(0,(i??0)-r.length);for(let a=0;a<d;a++)n.push("");return n}function Y({text:r,color:i="currentColor",size:n=18,minChars:d,noCycle:a=!1,className:S}){const h=Math.round(n*.5494505494505495),M=document.documentElement.dataset.mode==="light"?.08:.16,[T,f]=l.useState(null);l.useEffect(()=>{if(a)return;const e=$(r,d),o=e.length,g=C+(o-1)*L;let y=0,b,E=!1;const k=()=>{if(!E){if(y++,y>=g){f(null);return}f(e.map((j,_)=>{const v=C+_*L;return y>=v?j:B()})),b=setTimeout(k,D)}};return k(),()=>{E=!0,clearTimeout(b)}},[r,d,a]);const c=(e,o)=>t.jsx("svg",{viewBox:"0 0 100 182",width:h,height:n,className:"seven-seg__char","aria-hidden":"true",children:w.map(g=>t.jsx("polygon",{points:R[g],fill:i,stroke:i,strokeWidth:4,strokeLinejoin:"round",opacity:e.includes(g)?1:M},g))},o),s=$(r,d),u=T??s;return t.jsxs("span",{className:`seven-seg${S?` ${S}`:""}`,children:[u.map((e,o)=>c(e,`${o}-${e}`)),t.jsx("span",{className:"sr-only",children:r})]})}const G={grey:"/assets/keycap.svg",red:"/assets/keycap-red.svg"},I=O[900],P="#FFDEB0";function Z({icon:r,variant:i="grey",onClick:n,onPress:d,sentDuration:a=2e3,title:S,disabled:h=!1,className:m,iconColor:M=I,iconActiveColor:T=P,indicators:f}){const c=!!d,[s,u]=l.useState("idle"),[e,o]=l.useState(!1),g=l.useRef(),y=c?s==="held":e,b=c&&(s==="sending"||s==="sent"),E=c?s==="held"||s==="sending":e;l.useEffect(()=>()=>clearTimeout(g.current),[]);const k=l.useCallback(()=>{h||b||(F(),c?u("held"):o(!0))},[h,b,c]),j=l.useCallback(async()=>{if(c){if(s!=="held")return;x(),u("sending");const p=await d();u(p?"sent":"idle"),p&&(g.current=setTimeout(()=>u("idle"),a))}else{if(!e)return;o(!1),x(),n==null||n()}},[c,s,d,a,e,n]),_=l.useCallback(()=>{c?s==="held"&&(x(),u("idle")):(e&&x(),o(!1))},[c,s,e]),v=t.jsx("button",{onMouseDown:k,onMouseUp:j,onMouseLeave:_,onTouchStart:k,onTouchEnd:j,onTouchCancel:_,disabled:h||b,className:`keycap-btn${i==="red"?" keycap-btn--red-cap":""}${E?" keycap-btn--pressed":""}${m&&!f?` ${m}`:""}`,title:S,children:t.jsxs("div",{className:"keycap-wrap",children:[t.jsx("img",{src:G[i],alt:"",className:"keycap-btn__img",draggable:!1}),t.jsx("span",{className:"keycap-icon-overlay",style:{color:y||s==="sending"?T:M},children:r})]})});return f!=null&&f.length?t.jsxs("div",{className:`keycap-group${m?` ${m}`:""}`,children:[v,t.jsx("div",{className:"indicator-key-pair",children:f.map(p=>{const A=p.trackPress?s:p.active?"active":"idle";return t.jsxs("div",{className:`indicator-key${A!=="idle"?` indicator-key--${A}`:""}`,children:[t.jsx("span",{className:"indicator-key__label",children:p.label}),t.jsx("span",{className:"indicator-key__led"})]},p.label)})})]}):v}export{Z as K,Y as S};
import{r as l,j as t,Z as O}from"./index-DSXi6v0o.js";import{b as F,c as x}from"./keycap-sfx-ByZp-njj.js";const R={a:"24,3 76,3 83,7 76,11 24,11 17,7",b:"88,22 93,27 93,71 88,76 83,71 83,27",c:"88,106 93,111 93,155 88,160 83,155 83,111",d:"24,171 76,171 83,175 76,179 24,179 17,175",e:"12,106 17,111 17,155 12,160 7,155 7,111",f:"12,22 17,27 17,71 12,76 7,71 7,27",g:"24,86 76,86 83,91 76,96 24,96 17,91"},w=Object.keys(R),N={0:"abcdef",1:"bc",2:"abdeg",3:"abcdg",4:"bcfg",5:"acdfg",6:"acdefg",7:"abc",8:"abcdefg",9:"abcdfg",A:"abcefg",B:"cdefg",C:"adef",D:"bcdeg",E:"adefg",F:"aefg",G:"acdef",H:"bcefg",I:"ef",J:"bcde",L:"def",M:"abcefg",N:"ceg",O:"abcdef",P:"abefg",Q:"abcfg",R:"eg",S:"acdfg",T:"defg",U:"bcdef",V:"cde",Y:"bcdfg",Z:"abdeg",a:"abcefg",b:"cdefg",c:"deg",d:"bcdeg",e:"adefg",f:"aefg",g:"abcdfg",h:"cefg",i:"c",j:"bcde",l:"def",m:"abcef",n:"ceg",o:"cdeg",p:"abefg",r:"eg",s:"acdfg",t:"defg",u:"cde",v:"cde",y:"bcdfg"," ":"",_:"d","-":"g","=":"dg","°":"abfg",'"':"bf","'":"f","(":"adef",")":"abcd","[":"adef","]":"abcd","!":"bc",".":"d"},C=6,D=56,L=2;function B(){return w.filter(()=>Math.random()>.45).join("")}function $(r,i){const n=Array.from(r).map(a=>N[a.toUpperCase()]??N[a]??""),d=Math.max(0,(i??0)-r.length);for(let a=0;a<d;a++)n.push("");return n}function Y({text:r,color:i="currentColor",size:n=18,minChars:d,noCycle:a=!1,className:S}){const h=Math.round(n*.5494505494505495),M=document.documentElement.dataset.mode==="light"?.08:.16,[T,f]=l.useState(null);l.useEffect(()=>{if(a)return;const e=$(r,d),o=e.length,g=C+(o-1)*L;let y=0,b,E=!1;const k=()=>{if(!E){if(y++,y>=g){f(null);return}f(e.map((j,_)=>{const v=C+_*L;return y>=v?j:B()})),b=setTimeout(k,D)}};return k(),()=>{E=!0,clearTimeout(b)}},[r,d,a]);const c=(e,o)=>t.jsx("svg",{viewBox:"0 0 100 182",width:h,height:n,className:"seven-seg__char","aria-hidden":"true",children:w.map(g=>t.jsx("polygon",{points:R[g],fill:i,stroke:i,strokeWidth:4,strokeLinejoin:"round",opacity:e.includes(g)?1:M},g))},o),s=$(r,d),u=T??s;return t.jsxs("span",{className:`seven-seg${S?` ${S}`:""}`,children:[u.map((e,o)=>c(e,`${o}-${e}`)),t.jsx("span",{className:"sr-only",children:r})]})}const G={grey:"/assets/keycap.svg",red:"/assets/keycap-red.svg"},I=O[900],P="#FFDEB0";function Z({icon:r,variant:i="grey",onClick:n,onPress:d,sentDuration:a=2e3,title:S,disabled:h=!1,className:m,iconColor:M=I,iconActiveColor:T=P,indicators:f}){const c=!!d,[s,u]=l.useState("idle"),[e,o]=l.useState(!1),g=l.useRef(),y=c?s==="held":e,b=c&&(s==="sending"||s==="sent"),E=c?s==="held"||s==="sending":e;l.useEffect(()=>()=>clearTimeout(g.current),[]);const k=l.useCallback(()=>{h||b||(F(),c?u("held"):o(!0))},[h,b,c]),j=l.useCallback(async()=>{if(c){if(s!=="held")return;x(),u("sending");const p=await d();u(p?"sent":"idle"),p&&(g.current=setTimeout(()=>u("idle"),a))}else{if(!e)return;o(!1),x(),n==null||n()}},[c,s,d,a,e,n]),_=l.useCallback(()=>{c?s==="held"&&(x(),u("idle")):(e&&x(),o(!1))},[c,s,e]),v=t.jsx("button",{onMouseDown:k,onMouseUp:j,onMouseLeave:_,onTouchStart:k,onTouchEnd:j,onTouchCancel:_,disabled:h||b,className:`keycap-btn${i==="red"?" keycap-btn--red-cap":""}${E?" keycap-btn--pressed":""}${m&&!f?` ${m}`:""}`,title:S,children:t.jsxs("div",{className:"keycap-wrap",children:[t.jsx("img",{src:G[i],alt:"",className:"keycap-btn__img",draggable:!1}),t.jsx("span",{className:"keycap-icon-overlay",style:{color:y||s==="sending"?T:M},children:r})]})});return f!=null&&f.length?t.jsxs("div",{className:`keycap-group${m?` ${m}`:""}`,children:[v,t.jsx("div",{className:"indicator-key-pair",children:f.map(p=>{const A=p.trackPress?s:p.active?"active":"idle";return t.jsxs("div",{className:`indicator-key${A!=="idle"?` indicator-key--${A}`:""}`,children:[t.jsx("span",{className:"indicator-key__label",children:p.label}),t.jsx("span",{className:"indicator-key__led"})]},p.label)})})]}):v}export{Z as K,Y as S};
@@ -1 +1 @@
import{r as y,j as t}from"./index-DeL-WnAD.js";const m="var(--sys-cyan)",k="var(--sys-blue)",v="var(--sys-indigo)",I="var(--sparkline-critical)",g="var(--fg-muted)";function C(d,o,e,s=2){if(d.length<2)return"";const r=d.map(n=>n.count),u=Math.max(...r,1),p=Math.min(...r),l=u-p||1,j=o-s*2,a=e-s*2,i=r.map((n,c)=>({x:s+c/(r.length-1)*j,y:s+a-(n-p)/l*a}));let x=`M ${i[0].x.toFixed(1)} ${i[0].y.toFixed(1)}`;for(let n=1;n<i.length;n++){const c=i[n-1],f=i[n],$=(c.x+f.x)/2;x+=` Q ${$.toFixed(1)} ${c.y.toFixed(1)} ${f.x.toFixed(1)} ${f.y.toFixed(1)}`}return x}const L=y.memo(function({data:o,width:e=48,height:s=16,color:r,invertScale:u=!1,isLoading:p=!1,className:l=""}){const a=`sl-${y.useId().replace(/:/g,"")}`,i=y.useMemo(()=>C(o,e,s),[o,e,s]),x=!r&&o.length>=2,n=r??(x?`url(#${a})`:g),c=l.includes("w-");return p&&o.length<2?t.jsx("div",{className:`flex items-center justify-center ${l}`,style:c?{height:s}:{width:e,height:s},children:t.jsx("div",{className:"rounded animate-pulse bg-subtle-fill-hover",style:c?{width:"100%",height:s-6}:{width:e-8,height:s-6}})}):o.length<2?t.jsx("svg",{width:e,height:s,viewBox:`0 0 ${e} ${s}`,className:l,"aria-hidden":"true",children:t.jsx("line",{x1:4,y1:s/2,x2:e-4,y2:s/2,stroke:I,strokeWidth:1.5,strokeDasharray:"3,2"})}):t.jsxs("svg",{width:e,height:s,viewBox:`0 0 ${e} ${s}`,preserveAspectRatio:"none",className:l,"aria-hidden":"true",style:{maxWidth:"100%"},children:[x&&t.jsx("defs",{children:t.jsxs("linearGradient",{id:a,gradientUnits:"userSpaceOnUse",x1:0,y1:2,x2:0,y2:s-2,children:[t.jsx("stop",{offset:"0%",stopColor:u?v:m}),t.jsx("stop",{offset:"50%",stopColor:k}),t.jsx("stop",{offset:"100%",stopColor:u?m:v})]})}),t.jsx("path",{d:i,fill:"none",stroke:n,strokeWidth:1.5,strokeLinecap:"round",strokeLinejoin:"round",vectorEffect:"non-scaling-stroke"})]})});export{L};
import{r as y,j as t}from"./index-DSXi6v0o.js";const m="var(--sys-cyan)",k="var(--sys-blue)",v="var(--sys-indigo)",I="var(--sparkline-critical)",g="var(--fg-muted)";function C(d,o,e,s=2){if(d.length<2)return"";const r=d.map(n=>n.count),u=Math.max(...r,1),p=Math.min(...r),l=u-p||1,j=o-s*2,a=e-s*2,i=r.map((n,c)=>({x:s+c/(r.length-1)*j,y:s+a-(n-p)/l*a}));let x=`M ${i[0].x.toFixed(1)} ${i[0].y.toFixed(1)}`;for(let n=1;n<i.length;n++){const c=i[n-1],f=i[n],$=(c.x+f.x)/2;x+=` Q ${$.toFixed(1)} ${c.y.toFixed(1)} ${f.x.toFixed(1)} ${f.y.toFixed(1)}`}return x}const L=y.memo(function({data:o,width:e=48,height:s=16,color:r,invertScale:u=!1,isLoading:p=!1,className:l=""}){const a=`sl-${y.useId().replace(/:/g,"")}`,i=y.useMemo(()=>C(o,e,s),[o,e,s]),x=!r&&o.length>=2,n=r??(x?`url(#${a})`:g),c=l.includes("w-");return p&&o.length<2?t.jsx("div",{className:`flex items-center justify-center ${l}`,style:c?{height:s}:{width:e,height:s},children:t.jsx("div",{className:"rounded animate-pulse bg-subtle-fill-hover",style:c?{width:"100%",height:s-6}:{width:e-8,height:s-6}})}):o.length<2?t.jsx("svg",{width:e,height:s,viewBox:`0 0 ${e} ${s}`,className:l,"aria-hidden":"true",children:t.jsx("line",{x1:4,y1:s/2,x2:e-4,y2:s/2,stroke:I,strokeWidth:1.5,strokeDasharray:"3,2"})}):t.jsxs("svg",{width:e,height:s,viewBox:`0 0 ${e} ${s}`,preserveAspectRatio:"none",className:l,"aria-hidden":"true",style:{maxWidth:"100%"},children:[x&&t.jsx("defs",{children:t.jsxs("linearGradient",{id:a,gradientUnits:"userSpaceOnUse",x1:0,y1:2,x2:0,y2:s-2,children:[t.jsx("stop",{offset:"0%",stopColor:u?v:m}),t.jsx("stop",{offset:"50%",stopColor:k}),t.jsx("stop",{offset:"100%",stopColor:u?m:v})]})}),t.jsx("path",{d:i,fill:"none",stroke:n,strokeWidth:1.5,strokeLinecap:"round",strokeLinejoin:"round",vectorEffect:"non-scaling-stroke"})]})});export{L};
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
-1
View File
@@ -1 +0,0 @@
import{dY as h,dZ as f,a5 as j,d_ as L,d$ as v,r as l,e0 as N,j as e,e1 as m,a7 as y,B as w,c as i,e2 as b,dN as C,m as S,e3 as E}from"./index-DeL-WnAD.js";import{P,a as R,B as k,C as B}from"./PageLayout-B5m1JzIf.js";import{C as I,a as T}from"./circle-stop-DJ8RnfMC.js";const D=l.memo(function({log:a}){return e.jsx(S.div,{initial:{opacity:0,y:6},animate:{opacity:1,y:0},transition:{duration:.15,ease:"easeOut"},className:"p-3 bg-subtle-fill/80 radius-inner depth-stroke-raised hover:bg-subtle-fill-strong transition-base",children:e.jsxs("div",{className:"flex items-baseline gap-3",children:[e.jsx("span",{className:i("type-data-sm w-14 shrink-0",E(a.level)),children:a.level}),e.jsxs("div",{className:"flex-1 min-w-0",children:[e.jsx("p",{className:"type-data-sm text-fg-primary break-words whitespace-pre-wrap",children:a.message}),e.jsx("p",{className:"type-data-xs text-fg-muted mt-1",children:new Date(a.timestamp).toLocaleString()})]})]})})});function M({showDebug:s,onToggle:a}){return e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("span",{className:i("type-data-sm",s?"text-sys-orange":"text-sys-cyan"),children:s?"DEBUG":"INFO"}),e.jsx(C,{enabled:s,onChange:a,size:"sm"})]})}function O(){const s=h(),a=f(),o=j(),r=L(),g=v(),[c,x]=l.useState(!1),u=l.useCallback(()=>{x(t=>!t)},[]),d=c?s:s.filter(t=>t.level!=="DEBUG"),n=l.useRef(r);return n.current=r,l.useEffect(()=>{if(!o)return;n.current();const t=setInterval(()=>n.current(),N.logs);return()=>clearInterval(t)},[o]),e.jsxs(P,{children:[e.jsx(R,{title:"System Logs",icon:e.jsx(m,{}),controls:e.jsx(M,{showDebug:c,onToggle:u})}),e.jsx(k,{ready:!0,children:e.jsxs(B,{neomorphic:!0,noPadding:!0,children:[e.jsx(y,{listHeader:!0,icon:e.jsx(m,{className:"icon-sm"}),title:"Log Entries",actions:e.jsx(w,{plain:!0,color:o?"danger":"primary",onClick:()=>g(!o),title:o?"Pause":"Resume",className:i(!o&&"animate-pulse-slow"),children:o?e.jsx(I,{"data-slot":"icon",className:"!w-5 !h-5"}):e.jsx(T,{"data-slot":"icon",className:"!w-5 !h-5"})})}),e.jsx("div",{className:"space-y-2 max-h-[calc(100dvh-226px)] sm:max-h-[calc(100dvh-234px)] lg:max-h-[calc(100vh-194px)] overflow-y-auto p-4",children:a&&s.length===0?e.jsx(b,{count:10}):d.length===0?e.jsx("div",{className:"text-center py-12 text-fg-muted",children:s.length===0?"No logs available":"No logs match selected filters"}):d.map((t,p)=>e.jsx(D,{log:t},`${t.timestamp}-${p}`))})]})})]})}export{O as default};
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+1
View File
@@ -0,0 +1 @@
import{r as d,d2 as x,u,j as t,c as o,$ as p,R as c}from"./index-DSXi6v0o.js";const j=d.memo(function({variant:l="inline",showChannel:r=!0,className:s}){const{active:m,iatas:e}=x(),a=u();if(!m)return null;const n=r&&e.length>0?e.length<=3?e.join(", "):`${e.slice(0,2).join(", ")} +${e.length-2}`:null,i=n?`MQTT · ${n}`:"MQTT";return l==="pill"?t.jsx("span",{onClick:()=>a("/mqtt"),className:o("cursor-pointer",s),children:t.jsxs(p,{color:"cyan",children:[t.jsx(c,{className:"w-3 h-3 mr-1"}),i]})}):t.jsxs("span",{className:o("inline-flex items-center gap-1 text-sys-cyan type-data-xs cursor-pointer","hover:text-sys-cyan/80 transition-colors",s),onClick:()=>a("/mqtt"),title:"MQTT mode active — click to manage",children:[t.jsx(c,{className:"w-3 h-3"}),t.jsx("span",{className:"font-medium",children:i})]})});export{j as M};
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
-1
View File
@@ -1 +0,0 @@
import{j as e,Y as d,c as m,aR as o,r as i,gy as f}from"./index-DeL-WnAD.js";function p({children:a,className:s}){return e.jsx("div",{className:m("section-gap",s),children:a})}function g({children:a,className:s,ready:n}){const r=o(),t=n??r,[x,c]=i.useState(!1);return i.useEffect(()=>{if(!t){c(!1);return}let l=!1;return requestAnimationFrame(()=>{requestAnimationFrame(()=>{l||i.startTransition(()=>c(!0))})}),()=>{l=!0}},[t]),e.jsx(f.Provider,{value:x,children:e.jsx("div",{className:m("bento-section",s),children:a})})}function j({title:a,icon:s,controls:n,leading:r,subtitle:t}){return e.jsxs("div",{className:"flex flex-col gap-2",children:[e.jsxs("div",{className:"flex items-center justify-between gap-3 min-h-9",children:[e.jsxs("div",{className:"flex items-center gap-2 min-w-0",children:[e.jsxs("h1",{className:"type-title text-fg-primary flex items-baseline gap-2 sm:gap-3 min-w-0",children:[s&&e.jsx("span",{className:"text-icon-page-title flex-shrink-0 translate-y-[0.1em] [&>svg]:h-[1em] [&>svg]:w-[1em] [&>svg]:stroke-[1.5]",children:s}),e.jsx("span",{className:"truncate",children:a})]}),r]}),n&&e.jsx("div",{className:"flex items-center gap-2 flex-shrink-0",children:n})]}),t&&e.jsx("div",{children:t})]})}function h({size:a,...s}){return e.jsx(d,{...s})}export{g as B,h as C,p as P,j as a};
+1
View File
@@ -0,0 +1 @@
import{j as e,c as m,aN as d,r as i,gF as o,a2 as f}from"./index-DSXi6v0o.js";function p({children:a,className:s}){return e.jsx("div",{className:m("section-gap",s),children:a})}function g({children:a,className:s,ready:n}){const r=d(),t=n??r,[x,c]=i.useState(!1);return i.useEffect(()=>{if(!t){c(!1);return}let l=!1;return requestAnimationFrame(()=>{requestAnimationFrame(()=>{l||i.startTransition(()=>c(!0))})}),()=>{l=!0}},[t]),e.jsx(o.Provider,{value:x,children:e.jsx("div",{className:m("bento-section",s),children:a})})}function j({title:a,icon:s,controls:n,leading:r,subtitle:t}){return e.jsxs("div",{className:"flex flex-col gap-2",children:[e.jsxs("div",{className:"flex items-center justify-between gap-3 min-h-9",children:[e.jsxs("div",{className:"flex items-center gap-2 min-w-0",children:[e.jsxs("h1",{className:"type-title text-fg-primary flex items-baseline gap-2 sm:gap-3 min-w-0",children:[s&&e.jsx("span",{className:"text-icon-page-title flex-shrink-0 translate-y-[0.1em] [&>svg]:h-[1em] [&>svg]:w-[1em] [&>svg]:stroke-[1.5]",children:s}),e.jsx("span",{className:"truncate",children:a})]}),r]}),n&&e.jsx("div",{className:"flex items-center gap-2 flex-shrink-0",children:n})]}),t&&e.jsx("div",{children:t})]})}function h({size:a,...s}){return e.jsx(f,{...s})}export{g as B,h as C,p as P,j as a};
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1,4 +1,4 @@
import{e as l,r as m,c as i,j as r,gq as j,dx as _,e8 as k}from"./index-DeL-WnAD.js";/**
import{e as l,r as m,c as i,j as r,gx as j,dI as _,eg as k}from"./index-DSXi6v0o.js";/**
* @license lucide-react v0.559.0 - ISC
*
* This source code is licensed under the ISC license.
@@ -23,4 +23,4 @@ import{e as l,r as m,c as i,j as r,gq as j,dx as _,e8 as k}from"./index-DeL-WnAD
*
* This source code is licensed under the ISC license.
* See the LICENSE file in the root directory of this source tree.
*/const B=[["path",{d:"M2 20h.01",key:"4haj6o"}],["path",{d:"M7 20v-4",key:"j294jx"}],["path",{d:"M12 20v-8",key:"i3yub9"}],["path",{d:"M17 20V8",key:"1tkaf5"}],["path",{d:"M22 4v16",key:"sih9yq"}]],R=l("signal",B),L={excellent:"color(display-p3 0.00 1.00 0.00)",good:"color(display-p3 0.55 0.90 0.15)",fair:"color(display-p3 1.00 0.85 0.00)",weak:"color(display-p3 1.00 0.55 0.15)",poor:"color(display-p3 1.00 0.20 0.20)"},E={excellent:"#4ADE80",good:"#A3E635",fair:"#FACC15",weak:"#FB923C",poor:"#EF4444"};function d(e){return e>=-90?"excellent":e>=-100?"good":e>=-110?"fair":e>=-120?"weak":"poor"}function F(e,t,a,s=0){const n=k(t,e,a,s);return n?I(n.finalGrade):d(e)}function I(e){switch(e){case"excellent":return"excellent";case"good":return"good";case"fair":return"fair";case"poor":return"weak";case"critical":return"poor"}}function O(e){switch(e){case"excellent":return"text-signal-excellent";case"good":return"text-signal-good";case"fair":return"text-signal-fair";case"weak":return"text-signal-poor";case"poor":return"text-signal-critical";default:return"text-fg-muted"}}function f(e,t,a=!0){return t?a?{backgroundColor:E[e],"--p3-color":L[e]}:{backgroundColor:"rgba(255, 255, 255, 0.25)"}:{backgroundColor:"rgba(255, 255, 255, 0.1)"}}function p(e,t=!0){return e&&t?"signal-bar-active":""}function q({rssi:e,className:t="w-4 h-4"}){const a=d(e),s=O(a),n=i(s,t);switch(a){case"excellent":return r.jsx(R,{className:n});case"good":return r.jsx(v,{className:n});case"fair":return r.jsx(A,{className:n});case"weak":return r.jsx(w,{className:n});case"poor":default:return r.jsx(b,{className:n})}}function $({rssi:e,snr:t,compact:a=!1,showValues:s=!0,radioConfig:n,nfPenalty:h=0,validated:c=!0}){const g=t!==void 0?F(e,t,n,h):d(e),x=4,u={excellent:4,good:3,fair:2,weak:1,poor:0}[g];return a?r.jsxs("div",{className:"flex items-center gap-1.5",children:[s&&r.jsx("span",{className:i("type-data-xs w-[32px] text-left",c?"text-fg-secondary":"text-fg-muted"),children:e}),r.jsx("div",{className:"flex items-center gap-[2px] h-3 w-[14px]",children:Array.from({length:x}).map((y,o)=>r.jsx("div",{className:i("w-[3px] h-full rounded-[1px] transition-colors",p(o<u,c)),style:f(g,o<u,c)},o))})]}):r.jsxs("div",{className:"flex items-center gap-2",children:[s&&r.jsxs("div",{className:"flex flex-col items-start w-[52px]",children:[r.jsxs("span",{className:i("type-data-xs leading-tight",c?"text-fg-secondary":"text-fg-muted"),children:[e," dBm"]}),t!==void 0&&r.jsxs("span",{className:"type-data-xs text-fg-muted leading-tight",children:[t.toFixed(1)," dB"]})]}),r.jsx("div",{className:"flex items-center gap-[2px] h-3.5 w-[14px]",children:Array.from({length:x}).map((y,o)=>r.jsx("div",{className:i("w-[3px] h-full rounded-[1px] transition-colors",p(o<u,c)),style:f(g,o<u,c)},o))})]})}const G=m.memo($);function P(e){const t=d(e);return t.charAt(0).toUpperCase()+t.slice(1)}function D(e){if(Array.isArray(e))return e;if(typeof e=="string"&&e.startsWith("["))try{const t=JSON.parse(e);return Array.isArray(t)?t:[]}catch{return[]}return[]}function H(e){const t=D(e.original_path),a=e.route??e.route_type;return j(a)?t.length===0:_(a)?t.length<=1:t.length===0}function z(e){return e.packet_origin==="tx_local"||e.packet_origin==="tx_forward"?!1:e._isZeroHop!=null?e._isZeroHop:H(e)}export{G as S,R as a,q as b,d as c,P as g,z as i};
*/const B=[["path",{d:"M2 20h.01",key:"4haj6o"}],["path",{d:"M7 20v-4",key:"j294jx"}],["path",{d:"M12 20v-8",key:"i3yub9"}],["path",{d:"M17 20V8",key:"1tkaf5"}],["path",{d:"M22 4v16",key:"sih9yq"}]],R=l("signal",B),L={excellent:"color(display-p3 0.00 1.00 0.00)",good:"color(display-p3 0.55 0.90 0.15)",fair:"color(display-p3 1.00 0.85 0.00)",weak:"color(display-p3 1.00 0.55 0.15)",poor:"color(display-p3 1.00 0.20 0.20)"},I={excellent:"#4ADE80",good:"#A3E635",fair:"#FACC15",weak:"#FB923C",poor:"#EF4444"};function d(e){return e>=-90?"excellent":e>=-100?"good":e>=-110?"fair":e>=-120?"weak":"poor"}function E(e,t,a,s=0){const n=k(t,e,a,s);return n?F(n.finalGrade):d(e)}function F(e){switch(e){case"excellent":return"excellent";case"good":return"good";case"fair":return"fair";case"poor":return"weak";case"critical":return"poor"}}function O(e){switch(e){case"excellent":return"text-signal-excellent";case"good":return"text-signal-good";case"fair":return"text-signal-fair";case"weak":return"text-signal-poor";case"poor":return"text-signal-critical";default:return"text-fg-muted"}}function f(e,t,a=!0){return t?a?{backgroundColor:I[e],"--p3-color":L[e]}:{backgroundColor:"rgba(255, 255, 255, 0.25)"}:{backgroundColor:"rgba(255, 255, 255, 0.1)"}}function p(e,t=!0){return e&&t?"signal-bar-active":""}function G({rssi:e,className:t="w-4 h-4"}){const a=d(e),s=O(a),n=i(s,t);switch(a){case"excellent":return r.jsx(R,{className:n});case"good":return r.jsx(v,{className:n});case"fair":return r.jsx(A,{className:n});case"weak":return r.jsx(w,{className:n});case"poor":default:return r.jsx(b,{className:n})}}function $({rssi:e,snr:t,compact:a=!1,showValues:s=!0,radioConfig:n,nfPenalty:h=0,validated:c=!0}){const g=t!==void 0?E(e,t,n,h):d(e),x=4,u={excellent:4,good:3,fair:2,weak:1,poor:0}[g];return a?r.jsxs("div",{className:"flex items-center gap-1.5",children:[s&&r.jsx("span",{className:i("type-data-xs w-[32px] text-left",c?"text-fg-secondary":"text-fg-muted"),children:e}),r.jsx("div",{className:"flex items-center gap-[2px] h-3 w-[14px]",children:Array.from({length:x}).map((y,o)=>r.jsx("div",{className:i("w-[3px] h-full rounded-[1px] transition-colors",p(o<u,c)),style:f(g,o<u,c)},o))})]}):r.jsxs("div",{className:"flex items-center gap-2",children:[s&&r.jsxs("div",{className:"flex flex-col items-start w-[52px]",children:[r.jsxs("span",{className:i("type-data-xs leading-tight",c?"text-fg-secondary":"text-fg-muted"),children:[e," dBm"]}),t!==void 0&&r.jsxs("span",{className:"type-data-xs text-fg-muted leading-tight",children:[t.toFixed(1)," dB"]})]}),r.jsx("div",{className:"flex items-center gap-[2px] h-3.5 w-[14px]",children:Array.from({length:x}).map((y,o)=>r.jsx("div",{className:i("w-[3px] h-full rounded-[1px] transition-colors",p(o<u,c)),style:f(g,o<u,c)},o))})]})}const P=m.memo($);function q(e){const t=d(e);return t.charAt(0).toUpperCase()+t.slice(1)}function D(e){if(Array.isArray(e))return e;if(typeof e=="string"&&e.startsWith("["))try{const t=JSON.parse(e);return Array.isArray(t)?t:[]}catch{return[]}return[]}function H(e){const t=D(e.original_path),a=e.route??e.route_type;return j(a)?t.length===0:_(a)?t.length<=1:t.length===0}function z(e){return e.packet_origin==="tx_local"||e.packet_origin==="tx_forward"?!1:e._isZeroHop!=null?e._isZeroHop:H(e)}export{P as S,R as a,G as b,d as c,q as g,z as i};
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1,4 +1,4 @@
import{e as t}from"./index-DeL-WnAD.js";/**
import{e as t}from"./index-DSXi6v0o.js";/**
* @license lucide-react v0.559.0 - ISC
*
* This source code is licensed under the ISC license.
@@ -1,4 +1,4 @@
import{e}from"./index-DeL-WnAD.js";/**
import{e}from"./index-DSXi6v0o.js";/**
* @license lucide-react v0.559.0 - ISC
*
* This source code is licensed under the ISC license.
@@ -1,4 +1,4 @@
import{e as o}from"./index-DeL-WnAD.js";/**
import{e as o}from"./index-DSXi6v0o.js";/**
* @license lucide-react v0.559.0 - ISC
*
* This source code is licensed under the ISC license.
@@ -1,4 +1,4 @@
import{e as o}from"./index-DeL-WnAD.js";/**
import{e as o}from"./index-DSXi6v0o.js";/**
* @license lucide-react v0.559.0 - ISC
*
* This source code is licensed under the ISC license.
@@ -1,4 +1,4 @@
import{e as o}from"./index-DeL-WnAD.js";/**
import{e as o}from"./index-DSXi6v0o.js";/**
* @license lucide-react v0.559.0 - ISC
*
* This source code is licensed under the ISC license.
+1
View File
@@ -0,0 +1 @@
import{dv as i}from"./index-DSXi6v0o.js";async function o(t=!1){return i(`/api/config_export${t?"?include_secrets=true":""}`)}async function r(t){return i("/api/config_import",{method:"POST",body:JSON.stringify({config:t})})}async function s(){return i("/api/identity_export")}export{s as a,o as e,r as i};
@@ -1,4 +1,4 @@
import{e as c}from"./index-DeL-WnAD.js";/**
import{e as c}from"./index-DSXi6v0o.js";/**
* @license lucide-react v0.559.0 - ISC
*
* This source code is licensed under the ISC license.
@@ -1 +1 @@
import{r as g,Z as d,O as l}from"./index-DeL-WnAD.js";function p(e){const n=parseInt(e.slice(1,3),16)/255,t=parseInt(e.slice(3,5),16)/255,r=parseInt(e.slice(5,7),16)/255,o=Math.max(n,t,r),i=Math.min(n,t,r),a=(o+i)/2;if(o===i)return[0,0,a];const s=o-i,u=a>.5?s/(2-o-i):s/(o+i);let c=0;return o===n?c=((t-r)/s+(t<r?6:0))/6:o===t?c=((r-n)/s+2)/6:c=((n-t)/s+4)/6,[c,u,a]}function E(e,n,t){if(n===0)return`#${Math.round(t*255).toString(16).padStart(2,"0").repeat(3)}`;const r=(s,u,c)=>(c<0&&(c+=1),c>1&&(c-=1),c<1/6?s+(u-s)*6*c:c<1/2?u:c<2/3?s+(u-s)*(2/3-c)*6:s),o=t<.5?t*(1+n):t+n-t*n,i=2*t-o,a=s=>Math.round(s*255).toString(16).padStart(2,"0");return`#${a(r(i,o,e+1/3))}${a(r(i,o,e))}${a(r(i,o,e-1/3))}`}function S(e,n,t){let r=n[0]-e[0];return r>.5&&(r-=1),r<-.5&&(r+=1),[(e[0]+r*t+1)%1,e[1]+(n[1]-e[1])*t,e[2]+(n[2]-e[2])*t]}const x=[l.red,l.orange,l.amber,l.green,l.teal,l.cyan,l.blue,l.indigo,l.purple,l.pink],m=4,h=[];{const e=x.map(p);for(let n=0;n<e.length;n++){const t=(n+1)%e.length;for(let r=0;r<m;r++){const[o,i,a]=S(e[n],e[t],r/m);h.push(E(o,i,a))}}}function j(e){let n=0;for(let t=0;t<e.length;t++)n=e.charCodeAt(t)+((n<<5)-n);return h[Math.abs(n)%h.length]}const f=new RegExp("(?:\\p{Emoji_Presentation}|\\p{Emoji}\\uFE0F)","gu");function N(e){const n=e.trim();if(!n)return 0;const t=n.match(f);return!t||t.length===0||t.length>3||n.replace(f,"").replace(/[\u200D\uFE0F\s]/g,"").length>0?0:t.length}function C(e){const n=e.match(f);if(n&&n.length>0){const t=n[0],r=e.replace(f,"").trim();return{emoji:t,cleanName:r||e}}return{emoji:null,cleanName:e}}function y(e){const{cleanName:n}=C(e),t=n.split(/[\s-_]+/).filter(Boolean);if(t.length>=2){const o=Array.from(t[0])[0]||"",i=Array.from(t[1])[0]||"";return(o+i).toUpperCase()}return Array.from(n).slice(0,2).join("").toUpperCase()}function M(e){return new Date(e*1e3).toLocaleTimeString([],{hour:"2-digit",minute:"2-digit",hour12:!1})}function T(e,n){const t=/@\[([^\]]+)\]/g,r=[];let o=0,i;const a=n!=null&&n.isOutgoing?d[200]:l.blue,s=n==null?void 0:n.onMentionClick;for(;(i=t.exec(e))!==null;){i.index>o&&r.push(e.slice(o,i.index));const u=i[1];r.push(g.createElement(s?"button":"span",{key:i.index,className:s?"font-bold hover:underline underline-offset-2 cursor-pointer":"font-bold",style:{color:a},...s&&{type:"button",onClick:c=>{c.stopPropagation(),s(u)}}},u)),o=i.index+i[0].length}return o<e.length&&r.push(e.slice(o)),r.length>0?r:e}export{y as a,M as b,N as c,C as e,T as f,j as g};
import{r as g,Z as d,V as l}from"./index-DSXi6v0o.js";function p(e){const n=parseInt(e.slice(1,3),16)/255,t=parseInt(e.slice(3,5),16)/255,r=parseInt(e.slice(5,7),16)/255,o=Math.max(n,t,r),i=Math.min(n,t,r),a=(o+i)/2;if(o===i)return[0,0,a];const s=o-i,u=a>.5?s/(2-o-i):s/(o+i);let c=0;return o===n?c=((t-r)/s+(t<r?6:0))/6:o===t?c=((r-n)/s+2)/6:c=((n-t)/s+4)/6,[c,u,a]}function E(e,n,t){if(n===0)return`#${Math.round(t*255).toString(16).padStart(2,"0").repeat(3)}`;const r=(s,u,c)=>(c<0&&(c+=1),c>1&&(c-=1),c<1/6?s+(u-s)*6*c:c<1/2?u:c<2/3?s+(u-s)*(2/3-c)*6:s),o=t<.5?t*(1+n):t+n-t*n,i=2*t-o,a=s=>Math.round(s*255).toString(16).padStart(2,"0");return`#${a(r(i,o,e+1/3))}${a(r(i,o,e))}${a(r(i,o,e-1/3))}`}function S(e,n,t){let r=n[0]-e[0];return r>.5&&(r-=1),r<-.5&&(r+=1),[(e[0]+r*t+1)%1,e[1]+(n[1]-e[1])*t,e[2]+(n[2]-e[2])*t]}const x=[l.red,l.orange,l.amber,l.green,l.teal,l.cyan,l.blue,l.indigo,l.purple,l.pink],m=4,h=[];{const e=x.map(p);for(let n=0;n<e.length;n++){const t=(n+1)%e.length;for(let r=0;r<m;r++){const[o,i,a]=S(e[n],e[t],r/m);h.push(E(o,i,a))}}}function j(e){let n=0;for(let t=0;t<e.length;t++)n=e.charCodeAt(t)+((n<<5)-n);return h[Math.abs(n)%h.length]}const f=new RegExp("(?:\\p{Emoji_Presentation}|\\p{Emoji}\\uFE0F)","gu");function N(e){const n=e.trim();if(!n)return 0;const t=n.match(f);return!t||t.length===0||t.length>3||n.replace(f,"").replace(/[\u200D\uFE0F\s]/g,"").length>0?0:t.length}function C(e){const n=e.match(f);if(n&&n.length>0){const t=n[0],r=e.replace(f,"").trim();return{emoji:t,cleanName:r||e}}return{emoji:null,cleanName:e}}function y(e){const{cleanName:n}=C(e),t=n.split(/[\s-_]+/).filter(Boolean);if(t.length>=2){const o=Array.from(t[0])[0]||"",i=Array.from(t[1])[0]||"";return(o+i).toUpperCase()}return Array.from(n).slice(0,2).join("").toUpperCase()}function M(e){return new Date(e*1e3).toLocaleTimeString([],{hour:"2-digit",minute:"2-digit",hour12:!1})}function T(e,n){const t=/@\[([^\]]+)\]/g,r=[];let o=0,i;const a=n!=null&&n.isOutgoing?d[200]:l.blue,s=n==null?void 0:n.onMentionClick;for(;(i=t.exec(e))!==null;){i.index>o&&r.push(e.slice(o,i.index));const u=i[1];r.push(g.createElement(s?"button":"span",{key:i.index,className:s?"font-bold hover:underline underline-offset-2 cursor-pointer":"font-bold",style:{color:a},...s&&{type:"button",onClick:c=>{c.stopPropagation(),s(u)}}},u)),o=i.index+i[0].length}return o<e.length&&r.push(e.slice(o)),r.length>0?r:e}export{y as a,M as b,N as c,C as e,T as f,j as g};
@@ -1,4 +1,4 @@
import{e}from"./index-DeL-WnAD.js";/**
import{e}from"./index-DSXi6v0o.js";/**
* @license lucide-react v0.559.0 - ISC
*
* This source code is licensed under the ISC license.
@@ -1,4 +1,4 @@
import{e as o}from"./index-DeL-WnAD.js";/**
import{e as o}from"./index-DSXi6v0o.js";/**
* @license lucide-react v0.559.0 - ISC
*
* This source code is licensed under the ISC license.
File diff suppressed because one or more lines are too long
@@ -1,4 +1,4 @@
import{e}from"./index-DeL-WnAD.js";/**
import{e}from"./index-DSXi6v0o.js";/**
* @license lucide-react v0.559.0 - ISC
*
* This source code is licensed under the ISC license.
@@ -1,4 +1,4 @@
import{e as c}from"./index-DeL-WnAD.js";/**
import{e as c}from"./index-DSXi6v0o.js";/**
* @license lucide-react v0.559.0 - ISC
*
* This source code is licensed under the ISC license.
@@ -1,4 +1,4 @@
import{e as c}from"./index-DeL-WnAD.js";/**
import{e as c}from"./index-DSXi6v0o.js";/**
* @license lucide-react v0.559.0 - ISC
*
* This source code is licensed under the ISC license.
@@ -1,4 +1,4 @@
import{e as c}from"./index-DeL-WnAD.js";/**
import{e as c}from"./index-DSXi6v0o.js";/**
* @license lucide-react v0.559.0 - ISC
*
* This source code is licensed under the ISC license.
@@ -1,4 +1,4 @@
import{e as c}from"./index-DeL-WnAD.js";/**
import{e as c}from"./index-DSXi6v0o.js";/**
* @license lucide-react v0.559.0 - ISC
*
* This source code is licensed under the ISC license.
@@ -1 +1 @@
import{ax as n,r as i}from"./index-DeL-WnAD.js";const p=t=>(t.type??t.payload_type)===n.ADVERT,l=t=>(t.type??t.payload_type)===n.TRACE,h=t=>(t.type??t.payload_type)===n.TXT_MSG,_=t=>(t.type??t.payload_type)===n.PATH,d=t=>(t.type??t.payload_type)===n.ACK,g=t=>{const e=t.type??t.payload_type;return e===n.GRP_TXT||e===n.GRP_DATA},m=t=>(t.path_length??(Array.isArray(t.original_path)?t.original_path.length:0))>0,A=t=>!!t.src_hash,T=t=>t.airtime_ms!=null,c=new Set,o=new Map;function a(t,e){return`${t}|${e}`}function u(t,e){const s=a(t,e);o.set(s,(o.get(s)??0)+1)}function y(t,e){const s=a(t,e),r=o.get(s)??0;r>1?o.set(s,r-1):o.delete(s)}function C(t){for(const e of t){const s=a(e.target,e.fn);c.has(s)||c.add(s)}}function P(t){i.useEffect(()=>{for(const e of t)u(e.target,e.fn);return()=>{for(const e of t)y(e.target,e.fn)}},[t])}export{m as a,A as b,h as c,d,p as e,l as f,_ as g,T as h,g as i,C as r,P as u};
import{c2 as n,r as i}from"./index-DSXi6v0o.js";const p=t=>(t.type??t.payload_type)===n.ADVERT,l=t=>(t.type??t.payload_type)===n.TRACE,h=t=>(t.type??t.payload_type)===n.TXT_MSG,_=t=>(t.type??t.payload_type)===n.PATH,d=t=>(t.type??t.payload_type)===n.ACK,g=t=>{const e=t.type??t.payload_type;return e===n.GRP_TXT||e===n.GRP_DATA},m=t=>(t.path_length??(Array.isArray(t.original_path)?t.original_path.length:0))>0,A=t=>!!t.src_hash,T=t=>t.airtime_ms!=null,c=new Set,o=new Map;function a(t,e){return`${t}|${e}`}function u(t,e){const s=a(t,e);o.set(s,(o.get(s)??0)+1)}function y(t,e){const s=a(t,e),r=o.get(s)??0;r>1?o.set(s,r-1):o.delete(s)}function C(t){for(const e of t){const s=a(e.target,e.fn);c.has(s)||c.add(s)}}function P(t){i.useEffect(()=>{for(const e of t)u(e.target,e.fn);return()=>{for(const e of t)y(e.target,e.fn)}},[t])}export{m as a,A as b,h as c,d,p as e,l as f,_ as g,T as h,g as i,C as r,P as u};
-6
View File
@@ -1,6 +0,0 @@
import{e as h}from"./index-DeL-WnAD.js";/**
* @license lucide-react v0.559.0 - ISC
*
* This source code is licensed under the ISC license.
* See the LICENSE file in the root directory of this source tree.
*/const t=[["path",{d:"M12 20v2",key:"1lh1kg"}],["path",{d:"M12 2v2",key:"tus03m"}],["path",{d:"M17 20v2",key:"1rnc9c"}],["path",{d:"M17 2v2",key:"11trls"}],["path",{d:"M2 12h2",key:"1t8f8n"}],["path",{d:"M2 17h2",key:"7oei6x"}],["path",{d:"M2 7h2",key:"asdhe0"}],["path",{d:"M20 12h2",key:"1q8mjw"}],["path",{d:"M20 17h2",key:"1fpfkl"}],["path",{d:"M20 7h2",key:"1o8tra"}],["path",{d:"M7 20v2",key:"4gnj0m"}],["path",{d:"M7 2v2",key:"1i4yhu"}],["rect",{x:"4",y:"4",width:"16",height:"16",rx:"2",key:"1vbyd7"}],["rect",{x:"8",y:"8",width:"8",height:"8",rx:"1",key:"z9xiuo"}]],d=h("cpu",t);export{d as C};
-6
View File
@@ -1,6 +0,0 @@
import{e}from"./index-DeL-WnAD.js";/**
* @license lucide-react v0.559.0 - ISC
*
* This source code is licensed under the ISC license.
* See the LICENSE file in the root directory of this source tree.
*/const a=[["ellipse",{cx:"12",cy:"5",rx:"9",ry:"3",key:"msslwz"}],["path",{d:"M3 5V19A9 3 0 0 0 21 19V5",key:"1wlel7"}],["path",{d:"M3 12A9 3 0 0 0 21 12",key:"mv7ke4"}]],t=e("database",a);export{t as D};
-1
View File
@@ -1 +0,0 @@
import{gT as s}from"./index-DeL-WnAD.js";const e=s(.65,0,.35,1),t=s(.33,1,.68,1),c=s(.33,.67,.67,1),u=s(.76,0,.24,1);export{t as a,e as b,c,u as e};
+1
View File
@@ -0,0 +1 @@
import{ha as a}from"./index-DSXi6v0o.js";const e=a(.65,0,.35,1),t=a(.33,1,.68,1),c=a(.33,.67,.67,1),u=a(.76,0,.24,1);export{t as a,e as b,c,u as e};
@@ -1 +1 @@
import{r as o,aU as p,d4 as v,gr as b,gs as $,dk as m,by as x}from"./index-DeL-WnAD.js";function y(e,t){return e!==null&&t!==null&&typeof e=="object"&&typeof t=="object"&&"id"in e&&"id"in t?e.id===t.id:e===t}function D(e=y){return o.useCallback((t,n)=>{if(typeof e=="string"){let u=e;return(t==null?void 0:t[u])===(n==null?void 0:n[u])}return e(t,n)},[e])}var w=(e=>(e[e.Left=0]="Left",e[e.Right=2]="Right",e))(w||{});function M(e){let t=o.useRef(null),n=p(l=>{t.current=l.pointerType,!v(l.currentTarget)&&l.pointerType==="mouse"&&l.button===w.Left&&(l.preventDefault(),e(l))}),u=p(l=>{t.current!=="mouse"&&(v(l.currentTarget)||e(l))});return{onPointerDown:n,onClick:u}}var R=(e=>(e[e.Ignore=0]="Ignore",e[e.Select=1]="Select",e[e.Close=2]="Close",e))(R||{});const E={Ignore:{kind:0},Select:e=>({kind:1,target:e}),Close:{kind:2}},I=200,k=5;function N(e,{trigger:t,action:n,close:u,select:l}){let r=o.useRef(null),i=o.useRef(null),c=o.useRef(null);b(e&&t!==null,"pointerdown",s=>{$(s==null?void 0:s.target)&&t!=null&&t.contains(s.target)&&(i.current=s.x,c.current=s.y,r.current=s.timeStamp)}),b(e&&t!==null,"pointerup",s=>{var a,d;let f=r.current;if(f===null||(r.current=null,!m(s.target))||Math.abs(s.x-((a=i.current)!=null?a:s.x))<k&&Math.abs(s.y-((d=c.current)!=null?d:s.y))<k)return;let g=n(s);switch(g.kind){case 0:return;case 1:{s.timeStamp-f>I&&(l(g.target),u());break}case 2:{u();break}}},{capture:!0})}function h(e){return[e.screenX,e.screenY]}function j(){let e=o.useRef([-1,-1]);return{wasMoved(t){let n=h(t);return e.current[0]===n[0]&&e.current[1]===n[1]?!1:(e.current=n,!0)},update(t){e.current=h(t)}}}function L(e){throw new Error("Unexpected object: "+e)}var S=(e=>(e[e.First=0]="First",e[e.Previous=1]="Previous",e[e.Next=2]="Next",e[e.Last=3]="Last",e[e.Specific=4]="Specific",e[e.Nothing=5]="Nothing",e))(S||{});function P(e,t){let n=t.resolveItems();if(n.length<=0)return null;let u=t.resolveActiveIndex(),l=u??-1;switch(e.focus){case 0:{for(let r=0;r<n.length;++r)if(!t.resolveDisabled(n[r],r,n))return r;return u}case 1:{l===-1&&(l=n.length);for(let r=l-1;r>=0;--r)if(!t.resolveDisabled(n[r],r,n))return r;return u}case 2:{for(let r=l+1;r<n.length;++r)if(!t.resolveDisabled(n[r],r,n))return r;return u}case 3:{for(let r=n.length-1;r>=0;--r)if(!t.resolveDisabled(n[r],r,n))return r;return u}case 4:{for(let r=0;r<n.length;++r)if(t.resolveId(n[r],r,n)===e.id)return r;return u}case 5:return null;default:L(e)}}const z={Idle:{kind:"Idle"},Tracked:e=>({kind:"Tracked",position:e}),Moved:{kind:"Moved"}};function T(e){let t=e.getBoundingClientRect();return`${t.x},${t.y}`}function F(e,t,n){let u=x();if(t.kind==="Tracked"){let l=function(){r!==T(e)&&(u.dispose(),n())},{position:r}=t,i=new ResizeObserver(l);i.observe(e),u.add(()=>i.disconnect()),u.addEventListener(window,"scroll",l,{passive:!0}),u.addEventListener(window,"resize",l)}return()=>u.dispose()}export{N as L,E as S,z as a,T as b,S as c,D as d,P as f,w as g,F as p,M as s,j as u};
import{r as o,aQ as p,da as v,gy as b,gz as $,dr as m,bu as x}from"./index-DSXi6v0o.js";function y(e,t){return e!==null&&t!==null&&typeof e=="object"&&typeof t=="object"&&"id"in e&&"id"in t?e.id===t.id:e===t}function D(e=y){return o.useCallback((t,n)=>{if(typeof e=="string"){let u=e;return(t==null?void 0:t[u])===(n==null?void 0:n[u])}return e(t,n)},[e])}var w=(e=>(e[e.Left=0]="Left",e[e.Right=2]="Right",e))(w||{});function M(e){let t=o.useRef(null),n=p(l=>{t.current=l.pointerType,!v(l.currentTarget)&&l.pointerType==="mouse"&&l.button===w.Left&&(l.preventDefault(),e(l))}),u=p(l=>{t.current!=="mouse"&&(v(l.currentTarget)||e(l))});return{onPointerDown:n,onClick:u}}var R=(e=>(e[e.Ignore=0]="Ignore",e[e.Select=1]="Select",e[e.Close=2]="Close",e))(R||{});const E={Ignore:{kind:0},Select:e=>({kind:1,target:e}),Close:{kind:2}},I=200,h=5;function N(e,{trigger:t,action:n,close:u,select:l}){let r=o.useRef(null),i=o.useRef(null),c=o.useRef(null);b(e&&t!==null,"pointerdown",s=>{$(s==null?void 0:s.target)&&t!=null&&t.contains(s.target)&&(i.current=s.x,c.current=s.y,r.current=s.timeStamp)}),b(e&&t!==null,"pointerup",s=>{var a,d;let f=r.current;if(f===null||(r.current=null,!m(s.target))||Math.abs(s.x-((a=i.current)!=null?a:s.x))<h&&Math.abs(s.y-((d=c.current)!=null?d:s.y))<h)return;let g=n(s);switch(g.kind){case 0:return;case 1:{s.timeStamp-f>I&&(l(g.target),u());break}case 2:{u();break}}},{capture:!0})}function k(e){return[e.screenX,e.screenY]}function j(){let e=o.useRef([-1,-1]);return{wasMoved(t){let n=k(t);return e.current[0]===n[0]&&e.current[1]===n[1]?!1:(e.current=n,!0)},update(t){e.current=k(t)}}}function L(e){throw new Error("Unexpected object: "+e)}var S=(e=>(e[e.First=0]="First",e[e.Previous=1]="Previous",e[e.Next=2]="Next",e[e.Last=3]="Last",e[e.Specific=4]="Specific",e[e.Nothing=5]="Nothing",e))(S||{});function z(e,t){let n=t.resolveItems();if(n.length<=0)return null;let u=t.resolveActiveIndex(),l=u??-1;switch(e.focus){case 0:{for(let r=0;r<n.length;++r)if(!t.resolveDisabled(n[r],r,n))return r;return u}case 1:{l===-1&&(l=n.length);for(let r=l-1;r>=0;--r)if(!t.resolveDisabled(n[r],r,n))return r;return u}case 2:{for(let r=l+1;r<n.length;++r)if(!t.resolveDisabled(n[r],r,n))return r;return u}case 3:{for(let r=n.length-1;r>=0;--r)if(!t.resolveDisabled(n[r],r,n))return r;return u}case 4:{for(let r=0;r<n.length;++r)if(t.resolveId(n[r],r,n)===e.id)return r;return u}case 5:return null;default:L(e)}}const P={Idle:{kind:"Idle"},Tracked:e=>({kind:"Tracked",position:e}),Moved:{kind:"Moved"}};function T(e){let t=e.getBoundingClientRect();return`${t.x},${t.y}`}function F(e,t,n){let u=x();if(t.kind==="Tracked"){let l=function(){r!==T(e)&&(u.dispose(),n())},{position:r}=t,i=new ResizeObserver(l);i.observe(e),u.add(()=>i.disconnect()),u.addEventListener(window,"scroll",l,{passive:!0}),u.addEventListener(window,"resize",l)}return()=>u.dispose()}export{N as L,E as S,P as a,T as b,S as c,D as d,z as f,w as g,F as p,M as s,j as u};
+1
View File
@@ -0,0 +1 @@
import{j as t,dV as l,c as i,a$ as n,fO as c}from"./index-DSXi6v0o.js";function x({disabled:e,className:s,children:a}){return t.jsx(l,{disabled:e,className:i("flex flex-col gap-2",s),children:a})}function m({required:e,className:s,children:a,...r}){return t.jsxs(n,{className:i("text-sm font-medium text-fg-primary select-none","data-[disabled]:opacity-50",r.title&&"cursor-help",s),...r,children:[a,e&&t.jsx("span",{className:"text-sys-red ml-0.5","aria-hidden":"true",children:"*"})]})}function o({className:e,children:s,...a}){return t.jsx(c,{className:i("text-sm text-fg-muted","data-[disabled]:opacity-50",e),...a,children:s})}export{o as D,x as F,m as L};
-1
View File
@@ -1 +0,0 @@
import{j as a,dM as l,c as i,b3 as n,fH as c}from"./index-DeL-WnAD.js";function x({disabled:e,className:s,children:t}){return a.jsx(l,{disabled:e,className:i("flex flex-col gap-2",s),children:t})}function m({required:e,className:s,children:t,...r}){return a.jsxs(n,{className:i("text-sm font-medium text-fg-primary select-none","data-[disabled]:opacity-50",r.title&&"cursor-help",s),...r,children:[t,e&&a.jsx("span",{className:"text-sys-red ml-0.5","aria-hidden":"true",children:"*"})]})}function o({className:e,children:s,...t}){return a.jsx(c,{className:i("text-sm text-fg-muted","data-[disabled]:opacity-50",e),...t,children:s})}export{o as D,x as F,m as L};
File diff suppressed because one or more lines are too long
+6
View File
@@ -0,0 +1,6 @@
import{e as a}from"./index-DSXi6v0o.js";/**
* @license lucide-react v0.559.0 - ISC
*
* This source code is licensed under the ISC license.
* See the LICENSE file in the root directory of this source tree.
*/const e=[["rect",{width:"8",height:"5",x:"14",y:"17",rx:"1",key:"19aais"}],["path",{d:"M10 20H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h3.9a2 2 0 0 1 1.69.9l.81 1.2a2 2 0 0 0 1.67.9H20a2 2 0 0 1 2 2v2.5",key:"1w6v7t"}],["path",{d:"M20 17v-2a2 2 0 1 0-4 0v2",key:"pwaxnr"}]],t=a("folder-lock",e);export{t as F};
@@ -1 +1 @@
import{bv as l,r as o}from"./index-DeL-WnAD.js";function a({children:t,freeze:e},n){let r=f(e,t);return o.isValidElement(r)?o.cloneElement(r,{ref:n}):l.createElement(l.Fragment,null,r)}const s=l.forwardRef(a);function f(t,e){let[n,r]=o.useState(e);return!t&&n!==e&&r(e),t?n:e}export{s,f as u};
import{br as l,r as o}from"./index-DSXi6v0o.js";function a({children:t,freeze:e},n){let r=f(e,t);return o.isValidElement(r)?o.cloneElement(r,{ref:n}):l.createElement(l.Fragment,null,r)}const s=l.forwardRef(a);function f(t,e){let[n,r]=o.useState(e);return!t&&n!==e&&r(e),t?n:e}export{s,f as u};
@@ -1,4 +1,4 @@
import{e}from"./index-DeL-WnAD.js";/**
import{e}from"./index-DSXi6v0o.js";/**
* @license lucide-react v0.559.0 - ISC
*
* This source code is licensed under the ISC license.
@@ -1,4 +1,4 @@
import{e as c}from"./index-DeL-WnAD.js";/**
import{e as c}from"./index-DSXi6v0o.js";/**
* @license lucide-react v0.559.0 - ISC
*
* This source code is licensed under the ISC license.
@@ -1,4 +1,4 @@
import{e}from"./index-DeL-WnAD.js";/**
import{e}from"./index-DSXi6v0o.js";/**
* @license lucide-react v0.559.0 - ISC
*
* This source code is licensed under the ISC license.
File diff suppressed because one or more lines are too long

Some files were not shown because too many files have changed in this diff Show More