signalk-wyoming 0.1.1 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,27 +1,57 @@
1
1
  # signalk-wyoming
2
2
 
3
- > **Status: ALPHA** This SignalK Wyoming system is 100% vibecoded slop. I don't have the right hardware yet to test it, so I'm putting it out there for people to test in the meantime. It _should_ work. File issues for anything that doestn.
4
-
5
- An offline voice assistant for your boat, built on [Signal K](https://signalk.org) and the [Wyoming protocol](https://github.com/rhasspy/wyoming) (the voice ecosystem behind Home Assistant's Assist: Whisper, Piper, openWakeWord). This plugin is the **orchestrator** of a small family: it routes spoken announcements to speakers around the boat (`say()`), runs the wake-word → speech-to-text pipeline, publishes voice commands to `voice.command`, manages satellite (mic/speaker) devices, and ships a webapp for status and audio testing. Everything runs in containers on the boat — no cloud, no internet required after first model download.
6
-
7
- The full architecture (topology diagram, pipeline flows, concurrency rules) lives in **[SPEC.md](SPEC.md)** §2; design rationale in **[DECISIONS.md](DECISIONS.md)**.
8
-
9
- ## The plugin family
10
-
11
- | Plugin | Role | Default port | Standalone? |
12
- | ---------------------------------------------------------------------- | -------------------------------------------------------------------------------- | ----------------------- | ----------------------------------------------------- |
13
- | **signalk-wyoming** (this repo) | Orchestrator: pipelines, satellite manager, TTS routing, `voice.*` paths, webapp | 10700/10800 (satellite) | needs ≥1 of the services below + an audio endpoint |
14
- | [signalk-piper](https://github.com/hoeken/signalk-piper) | Text-to-speech (Wyoming Piper) | 10200 | ✅ usable by any Wyoming client, incl. Home Assistant |
15
- | [signalk-whisper](https://github.com/hoeken/signalk-whisper) | Speech-to-text (Wyoming faster-whisper) | 10300 | ✅ |
16
- | [signalk-openwakeword](https://github.com/hoeken/signalk-openwakeword) | Wake word detection (Wyoming openWakeWord) | 10400 | ✅ |
17
-
18
- Audio endpoints are **satellites** — devices running [our containerized wyoming-satellite image](https://github.com/hoeken/wyoming-satellite) (`ghcr.io/hoeken/wyoming-satellite`) or upstream `wyoming-satellite` installs — anywhere on the boat LAN. The orchestrator can also run a **local satellite** container for a mic/speaker plugged into the Signal K server box itself.
3
+ > **Status: ALPHA.** This SignalK Wyoming system is 100% vibecoded slop. I
4
+ > don't have the right hardware yet to test it, so I'm putting it out there
5
+ > for people to test in the meantime. It _should_ work. File issues for
6
+ > anything that doesn't.
7
+
8
+ ## What is this?
9
+
10
+ An offline voice assistant for your boat, built on
11
+ [Signal K](https://signalk.org) and the
12
+ [Wyoming protocol](https://github.com/rhasspy/wyoming) (the voice ecosystem
13
+ behind Home Assistant's Assist). It gives your boat a voice and ears:
14
+
15
+ - **The boat talks** — spoken announcements to speakers around the boat.
16
+ Your anchor alarm, dead-man's switch, or any other plugin can say
17
+ _"Anchor alarm: drag detected"_ out loud, on every speaker or just the
18
+ cockpit one.
19
+ - **The boat listens** — say a wake word ("okay nabu"), speak a command,
20
+ and the transcribed text is published to Signal K for other plugins to
21
+ act on.
22
+
23
+ Everything runs in containers **on the boat** — no cloud account, no
24
+ internet required after the first model download.
25
+
26
+ This plugin is the **orchestrator** of a small family. It connects the
27
+ pieces: routes announcements, runs the wake-word → speech-to-text pipeline,
28
+ manages your microphone/speaker devices (satellites), and ships a webapp
29
+ for status and audio testing.
30
+
31
+ | Plugin | Role | Needed for |
32
+ | ---------------------------------------------------------------------- | -------------------------------- | ------------------------------------- |
33
+ | **signalk-wyoming** (this one) | Orchestrator, satellites, webapp | everything |
34
+ | [signalk-piper](https://github.com/hoeken/signalk-piper) | Text-to-speech (Piper) | announcements ("the boat talks") |
35
+ | [signalk-whisper](https://github.com/hoeken/signalk-whisper) | Speech-to-text (Whisper) | voice commands ("the boat listens") |
36
+ | [signalk-openwakeword](https://github.com/hoeken/signalk-openwakeword) | Wake word detection | hands-free listening ("okay nabu, …") |
37
+
38
+ Audio in/out happens through **satellites** — devices running the
39
+ [wyoming-satellite image](https://github.com/hoeken/wyoming-satellite)
40
+ (`ghcr.io/hoeken/wyoming-satellite`) or an upstream wyoming-satellite
41
+ install — anywhere on the boat network. A mic/speaker plugged into the
42
+ Signal K server box itself works too: enable the built-in **local
43
+ satellite** and the plugin runs the container for you.
19
44
 
20
45
  ## Requirements
21
46
 
22
47
  - **Signal K server** on Node **≥ 24**.
23
- - **[signalk-container](https://www.npmjs.com/package/signalk-container)** — the container runtime manager (this plugin declares it via `signalk.requires`). All services run as Docker/Podman containers managed through it and [signalk-container-helper](https://github.com/hoeken/signalk-container-helper). When Signal K itself runs in a container, services launch as sibling containers via the host Docker socket — the Signal K container needs no audio access.
24
- - RAM budget (resident, per SPEC §1.4):
48
+ - **[signalk-container](https://www.npmjs.com/package/signalk-container)**
49
+ with a working docker or podman runtime. All voice services run as
50
+ containers managed through it — you never touch docker yourself. When
51
+ Signal K itself runs in a container, services launch as sibling
52
+ containers via the host Docker socket; the Signal K container needs no
53
+ audio access.
54
+ - Enough RAM for the services you install:
25
55
 
26
56
  | Component | Approx. resident RAM |
27
57
  | ------------------- | ------------------------------------------------ |
@@ -31,19 +61,29 @@ Audio endpoints are **satellites** — devices running [our containerized wyomin
31
61
  | satellite container | ~50 MB |
32
62
  | orchestrator | negligible (runs inside Signal K's Node process) |
33
63
 
34
- **TTS-only install** (piper + orchestrator — the recommended starter) runs comfortably alongside Signal K on a Pi 4 / 2 GB. **Full stack** (all four plugins + local satellite): Pi 4/5 with 4 GB. Container memory caps keep a misbehaving service from OOMing the boat server.
64
+ A **TTS-only install** (piper + this plugin — the recommended starter) runs
65
+ comfortably alongside Signal K on a Pi 4 / 2 GB. The **full stack** (all
66
+ four plugins + a local satellite) wants a Pi 4/5 with 4 GB. Container
67
+ memory caps keep a misbehaving service from starving the boat server.
35
68
 
36
69
  ## Quick start (TTS-only — "the boat talks")
37
70
 
38
71
  The recommended first install needs zero microphones:
39
72
 
40
- 1. Install **signalk-container** (and configure its runtime), then **signalk-piper** and **signalk-wyoming** from the Signal K App Store. Enable both plugins.
41
- 2. signalk-piper starts the Piper container; first start downloads the voice (~60 MB — plugin status shows progress). The orchestrator discovers it automatically (`services.tts: "auto"`).
42
- 3. Give the orchestrator an audio endpoint — either:
43
- - enable **Local satellite** in the plugin config (mic/speaker on the server box; set `micDevice: "none"` for output-only), or
44
- - add a **remote satellite**: any device on the LAN running `ghcr.io/hoeken/wyoming-satellite` (or upstream wyoming-satellite), entered as `{id, host, port}` add `hasControlApi: true` when it runs our image so the webapp Audio screen and record-and-transcribe can reach its control API.
45
- 4. Open the webapp (Signal K admin UI → Webapps → **Voice (Wyoming)**), go to **Test**, type something, press _Say it_.
46
- 5. From anywhere else:
73
+ 1. Install **signalk-container** (and configure its runtime), then
74
+ **signalk-piper** and **signalk-wyoming** from the Signal K App Store.
75
+ Enable all of them.
76
+ 2. signalk-piper starts the Piper container; the first start downloads the
77
+ voice (~60 MBits plugin status shows progress). This plugin discovers
78
+ it automatically nothing to configure.
79
+ 3. Give the orchestrator a speaker — either:
80
+ - enable the **Local satellite** in the plugin config (mic/speaker on
81
+ the server box; set the microphone device to `none` for output-only), or
82
+ - add a **remote satellite**: any device on the network running the
83
+ satellite image, entered by host/port in the config panel.
84
+ 4. Open the webapp (Signal K admin UI → Webapps → **Voice (Wyoming)**), go
85
+ to **Test**, type something, press _Say it_.
86
+ 5. Make it useful — from any other software:
47
87
 
48
88
  ```bash
49
89
  curl -X POST http://localhost:3000/plugins/signalk-wyoming/api/say \
@@ -51,167 +91,211 @@ The recommended first install needs zero microphones:
51
91
  -d '{"text": "Anchor alarm: drag detected", "priority": "urgent"}'
52
92
  ```
53
93
 
54
- Add **signalk-whisper** later for voice commands (test them via the webapp's record-and-transcribe — no wake word needed), and **signalk-openwakeword** for hands-free wake words.
94
+ Add **signalk-whisper** later for voice commands (test them from the
95
+ webapp's record-and-transcribe — no wake word needed), and
96
+ **signalk-openwakeword** for hands-free wake words.
55
97
 
56
98
  ## Configuration
57
99
 
58
- Edited in the Signal K plugin config UI (Server → Plugin Config → _Voice (Wyoming)_). Shape and defaults (see `src/config.ts`):
59
-
60
- ```js
61
- {
62
- satellites: [ // remote satellites the orchestrator connects to
63
- {
64
- id: 'cockpit', // required; ^[a-zA-Z0-9_-]+$ becomes voice.satellites.<id>
65
- // and a REST URL segment ('local' is reserved)
66
- name: 'Cockpit', // display name (default: id)
67
- host: '10.10.10.21', // required
68
- port: 10700, // Wyoming satellite port
69
- wakeWords: ['okay_nabu'], // openWakeWord model names; empty = announce-only
70
- hasControlApi: true, // satellite runs our image → webapp Audio screen,
71
- controlPort: 10800 // record/play tests, record-and-transcribe
72
- } // (setting controlPort alone implies hasControlApi)
73
- ],
74
- localSatellite: { // mic/speaker on the Signal K server box
75
- enabled: false, // opt-in, off by default
76
- micDevice: 'auto', // ALSA device string ('none' = no microphone);
77
- sndDevice: 'auto', // find strings on the webapp Audio screen
78
- wakeWords: [],
79
- audioMode: 'alsa', // 'alsa' (/dev/snd, headless hosts) | 'pulse-socket' (desktop)
80
- feedbackSounds: true, // awake/done sounds on wake interactions
81
- hostPulseSocket: '/run/user/1000/pulse/native', // pulse-socket mode only
82
- noiseSuppression: undefined, // 0-4 (image default when unset)
83
- autoGain: undefined, // 0-31 dbFS
84
- micVolume: undefined, // multiplier
85
- tag: 'auto' // ghcr.io/hoeken/wyoming-satellite tag; 'auto' = pinned release
86
- },
87
- services: { // 'auto' = discover from the sibling plugins;
88
- asr: 'auto', // or a manual URI, e.g. 'tcp://gpubox:10300'
89
- tts: 'auto', // (lets an off-boat GPU box or a Home Assistant
90
- wake: 'auto' // add-on stand in for the sibling plugins)
91
- },
92
- defaults: {
93
- language: 'en',
94
- voice: '' // default piper voice (22.05 kHz voices only);
95
- }, // '' = the TTS service's configured voice
96
- advanced: { // endpointing + pipeline tunables
97
- silenceMs: 800, // end-of-utterance silence
98
- maxUtteranceMs: 10000,
99
- minUtteranceMs: 300,
100
- wakeDedupMs: 2000, // first wake detection wins; others ignored this long
101
- pipelineTimeoutMs: 30000,
102
- wakeRefractorySeconds: 3.0 // satellite image wake refractory
103
- }
104
- }
105
- ```
106
-
107
- ## Signal K paths
108
-
109
- Under `vessels.self` (SPEC §4.1):
110
-
111
- | Path | Value | Notes |
112
- | --------------------------------- | --------------------------------------------------------- | ---------------------------------------------------------------------------------------------------- |
113
- | `voice.command` | `{id, text, satellite, language, wakeWord?, durationMs?}` | one delta per utterance; `$source` = `signalk-wyoming.<satelliteId>` |
114
- | `voice.satellites.<id>.connected` | `boolean` | |
115
- | `voice.satellites.<id>.state` | `idle \| listening \| transcribing \| speaking` | |
116
- | `voice.say` | write-only PUT target | value: a plain string or the `say()` opts object |
117
- | `voice.muted` | `boolean`, PUT-able | `true` suppresses `normal` announcements; `urgent` plays through. Defaults to `false`; not persisted |
118
-
119
- ## REST API
120
-
121
- All routes under `/plugins/signalk-wyoming`; they respect Signal K access control (read for GETs, write for POSTs; image-update routes are admin-only).
100
+ The plugin ships a graphical configuration panel (Server → Plugin Config →
101
+ _Voice (Wyoming)_): live satellite and service status, a remote-satellite
102
+ editor, wake-word checkboxes listing what your wake service actually
103
+ offers, a voice dropdown listing your installed Piper voices, and — for the
104
+ local satellite container a version dropdown plus one-click update
105
+ check/apply. On servers without custom-panel support you get a plain
106
+ settings form with the same options.
122
107
 
123
- | Method & path | Body / result |
124
- | -------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------ |
125
- | `POST /api/say` | `{text, targets?, voice?, priority?}` → `202` `{ok, queued, errors?, suppressed?}`; `503` when nothing could be queued |
126
- | `GET /api/satellites` | `[{id, name, connected, state, host, port, hasControlApi, queueDepth}]` |
127
- | `GET /api/services` | `{asr, tts, wake}` → each `{uri, status, source, plugin?}`; `wake` gains `models` (available wake-word names) when ready |
128
- | `GET /api/voices` | piper voices `[{name, languages, description}]`; `503` until TTS is available |
129
- | `POST /api/satellites/:id/test` | queue a test tone → `202` |
130
- | `GET /api/satellites/:id/devices` | control-API proxy → `{capture: [{card, device, id, name}], playback: [...]}` (`404` if the satellite has no control API) |
131
- | `POST /api/satellites/:id/record` | `{seconds?}` (1–10, control-API limit) → `audio/wav` (proxied; briefly pauses the satellite) |
132
- | `POST /api/satellites/:id/play` | `{type: 'tone', frequency?, durationMs?}` or `{type: 'wav', data: base64}` (proxied) |
133
- | `GET /api/satellites/:id/vu` | SSE stream of `{rms, peak}` mic levels (proxied) |
134
- | `POST /api/transcribe` | `{satellite, seconds?}` (1–10 s) → record via control API → whisper → `{text, latencyMs}`; `503` until ASR is available |
135
- | `POST /api/mute` | `{muted: boolean}` → `{muted}` (same switch as the `voice.muted` PUT) |
136
- | `GET /api/log` | ring buffer of recent events `[{at, kind, data}]` |
137
- | `GET /api/events` | SSE: `state`, `command`, `announcement`, `detection`, `service`, `error` |
138
- | `GET /api/update/check` / `POST /api/update/apply` | local-satellite image updates (admin) |
108
+ ### Remote satellites
139
109
 
140
- ## The `say()` API for other plugins
110
+ One entry per mic/speaker device on the network:
141
111
 
142
- The same `say()` behind REST and PUT is also published in-process via PropertyValues (SPEC §4.2.3) — an anchor-alarm or notification-bridge plugin makes the boat speak with no HTTP round-trip:
112
+ | Setting | Default | Notes |
113
+ | ------------------------------------------------ | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
114
+ | `id` | — | Required; letters/digits/`_`/`-`. Names the satellite everywhere: `voice.satellites.<id>`, REST URLs, announcement targets. `local` is reserved. |
115
+ | `name` | the id | Display name. |
116
+ | `host` / `port` | —/10700 | Where the satellite listens. |
117
+ | `wakeWords` | none | Wake word models this satellite listens for (e.g. `okay_nabu`). Leave empty for an announce-only speaker. |
118
+ | `hasControlApi` (+ `controlPort`, default 10800) | off | Turn on when the satellite runs [our image](https://github.com/hoeken/wyoming-satellite) — unlocks the webapp Audio screen, record/play tests and record-and-transcribe for it. |
143
119
 
144
- ```js
145
- // In another Signal K plugin:
146
- app.onPropertyValues("signalk-wyoming.api", (values) => {
147
- const latest = values.at(-1)?.value; // {version: 1, say}
148
- if (!latest) return;
149
- latest
150
- .say({
151
- text: "Anchor alarm: drag detected",
152
- priority: "urgent", // jumps every queue, bypasses mute
153
- targets: ["cockpit"], // omit for all satellites
154
- })
155
- .then((result) => {
156
- // resolves on ENQUEUE: {ok, queued: ['cockpit'], errors?, suppressed?}
157
- })
158
- .catch((err) => {
159
- // rejects only when NOTHING could be queued (TTS down, no targets,
160
- // or "signalk-wyoming is stopped" — the facade stays safe across restarts)
161
- });
162
- });
163
- ```
120
+ ### Local satellite
164
121
 
165
- Semantics (all three surfaces): promise resolves on enqueue, never on playback; partial failure resolves with `ok: false` + per-satellite `errors`; text is capped at 500 characters; `wait: true` is reserved for v1.x and rejects loudly.
122
+ A mic/speaker plugged into the Signal K server box; the plugin runs the
123
+ satellite container for you. Off by default.
166
124
 
167
- ## Webapp
125
+ | Setting | Default | Notes |
126
+ | --------------------------------------------- | -------------- | ----------------------------------------------------------------------------------------------------------------- |
127
+ | `micDevice` / `sndDevice` | `auto` | ALSA device strings — find them on the webapp **Audio** screen. `auto` = image default; mic `none` = output-only. |
128
+ | `wakeWords` | none | As above. |
129
+ | `audioMode` | `alsa` | `alsa` for headless boxes (/dev/snd passthrough); `pulse-socket` for desktop hosts (set `hostPulseSocket`). |
130
+ | `feedbackSounds` | on | Awake/done chimes on wake-word interactions. |
131
+ | `noiseSuppression` / `autoGain` / `micVolume` | image defaults | Audio tuning, under "Audio tuning" in the panel. |
132
+ | `tag` | `auto` | Satellite image version. `auto` runs the pinned, tested release and follows plugin updates. |
168
133
 
169
- Signal K admin UI → Webapps → **Voice (Wyoming)** (`/signalk-wyoming`). Three screens, live-updated over SSE:
134
+ ### Services
170
135
 
171
- - **Status** services table (discovery status, URIs, wake models), satellites table (connection, state, queue depth, test-tone button), recent activity log (announcements, commands, detections, errors).
172
- - **Audio** for satellites running our image: device enumeration (`arecord -l`/`aplay -l` as dropdowns — pick one to get the ALSA device string to paste into the plugin config), _record 3 s & play back_, _play tone_, live VU meter. Recording/VU briefly pause the satellite (~2 s) to free the mic device. The webapp cannot write plugin config in v1 (SPEC §4.4).
173
- - **Test** type-and-say (target multi-select, voice picker, urgent, mute toggle), **record-and-transcribe** (STT testing before any wake word exists, with per-utterance latency the real-hardware benchmark for choosing a whisper model), and a live wake-word detection feed.
136
+ Where the voice services live. `auto` (the default) finds the sibling
137
+ plugins on this server automatically. Set a manual `tcp://host:port` URI to
138
+ use a service running elsewherean off-boat GPU box, or a Home Assistant
139
+ Wyoming add-on, can stand in for any of them (`asr` 10300, `tts` 10200,
140
+ `wake` 10400).
174
141
 
175
- Works over plain LAN HTTP (no `getUserMedia`/HTTPS requirements); requests ride the Signal K session — if you see "not authorized", log in via the Signal K admin UI.
142
+ ### Defaults & advanced
176
143
 
177
- ## Security read this
144
+ | Setting | Default | Notes |
145
+ | ------------------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ |
146
+ | `defaults.language` | `en` | Spoken language code. |
147
+ | `defaults.voice` | — | Default Piper voice for announcements (22.05 kHz voices only); empty uses the TTS service's own. |
148
+ | `advanced.*` | sane | Endpointing and pipeline timing knobs (silence detection, utterance limits, wake dedup, timeouts). Leave alone unless commands cut off too early/late. |
178
149
 
179
- **Wyoming has no authentication, and a satellite is an open live microphone.** Any client that can reach a satellite's `:10700` can connect and stream cabin audio — treat every satellite port like a **baby monitor**. Mitigations:
150
+ ## Using it
180
151
 
181
- - Our satellite image accepts a **single Wyoming client** at a time, and the orchestrator's always-held connection occupies that slot a rogue LAN client finds the mic busy. **Honest gap:** the slot frees on disconnect, so a rogue client can seize the mic during the reconnect window after a drop (the orchestrator's first reconnect attempt is near-immediate to shrink it).
182
- - whisper/piper bind to localhost/docker network by default — only the orchestrator needs them. openwakeword must be LAN-reachable for remote satellites.
183
- - Isolate satellite ports from marina wifi: firewall them, or put satellites on their own VLAN / WireGuard network.
184
- - REST/PUT surfaces respect Signal K access control; TLS/auth on the Wyoming links themselves is out of scope for v1.
152
+ ### Announcementsthree ways in
185
153
 
186
- ## Degraded modes (first-class)
154
+ - **REST**: `POST /plugins/signalk-wyoming/api/say` with
155
+ `{text, targets?, voice?, priority?}` (see the curl example above).
156
+ - **Signal K PUT** to `voice.say` — a plain string or the same options
157
+ object.
158
+ - **From another plugin**, in-process with no HTTP round-trip — see
159
+ [DEVELOPERS.md](DEVELOPERS.md#the-in-process-say-api).
187
160
 
188
- - **TTS-only** (no whisper): announcements work; record-and-transcribe returns `503` with a hint. The recommended starter install.
189
- - **STT-only** (no piper): voice commands publish to `voice.command`; `say()` rejects with "TTS unavailable".
190
- - **Wake words configured but no wake service:** plugin-status warning + `notifications.voice.wake` alarm; clears when openwakeword appears.
191
- - **Service down mid-flight:** `notifications.voice.<service>` alarm + plugin status; `say()` fails loudly (never a silent drop); pipelines abort after `pipelineTimeoutMs`.
192
- - **Local satellite without `/dev/snd` support:** current signalk-container releases can't pass audio devices through yet — the plugin starts the container anyway, detects the empty device list, and reports it plainly in the plugin status and webapp instead of failing silently.
193
- - `voice.muted` suppresses normal announcements; `urgent` always plays.
161
+ `priority: "urgent"` jumps every queue, interrupts whatever is playing, and
162
+ bypasses mute use it for alarms. Normal announcements queue per satellite
163
+ and respect the `voice.muted` switch. Failures are loud: if nothing could
164
+ be played you get an error back, never a silent drop.
194
165
 
195
- ## Development
166
+ ### Voice commands
167
+
168
+ Say a wake word, speak, pause. The transcribed utterance is published as
169
+ one delta on **`voice.command`** — build your own automations on top with
170
+ any plugin or client that subscribes to it (a command-handling plugin can
171
+ answer back through `say()`).
172
+
173
+ ### Signal K paths
196
174
 
197
- ```bash
198
- npm install
199
- npm run build # tsc → dist/
200
- npm test # typecheck tests + vitest
201
- npm run ci-lint # eslint + prettier --check
202
- npm run format # prettier --write + eslint --fix
203
- ```
175
+ Under `vessels.self`:
204
176
 
205
- - **No real audio or containers needed for tests.** The Wyoming protocol implementation and a scriptable mock server live in this package and are exported as subpaths:
206
- - `signalk-wyoming/protocol` framing (`encodeEvent`/`EventDecoder`), typed events, TCP client (`WyomingConnection`, `probeWyoming`);
207
- - `signalk-wyoming/mock` `MockWyomingServer` with scriptable asr/tts/wake/satellite roles, injectable delays/disconnects/malformed frames, and an event log.
177
+ | Path | Value | Notes |
178
+ | --------------------------------- | --------------------------------------------------------- | ----------------------------------------------------------------------------------------------------- |
179
+ | `voice.command` | `{id, text, satellite, language, wakeWord?, durationMs?}` | one delta per utterance; `$source` = `signalk-wyoming.<satelliteId>` |
180
+ | `voice.satellites.<id>.connected` | `boolean` | |
181
+ | `voice.satellites.<id>.state` | `idle \| listening \| transcribing \| speaking` | |
182
+ | `voice.say` | write-only PUT target | value: a plain string or the `say()` options object |
183
+ | `voice.muted` | `boolean`, PUT-able | `true` suppresses `normal` announcements; `urgent` plays through. Defaults to `false`; not persisted. |
208
184
 
209
- The sibling service plugins consume these as **devDependencies** for their protocol tests (their production code embeds a tiny self-contained describe ping instead).
185
+ Problems surface as notifications under `notifications.voice.*` (e.g. a
186
+ wake word configured with no wake service installed, or a service going
187
+ down mid-flight).
188
+
189
+ ### REST API
190
+
191
+ All routes under `/plugins/signalk-wyoming`; they respect Signal K access
192
+ control (read access for GETs, write for POSTs; image-update routes are
193
+ admin-only).
194
+
195
+ | Method & path | Body / result |
196
+ | -------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------ |
197
+ | `POST /api/say` | `{text, targets?, voice?, priority?}` → `202` `{ok, queued, errors?, suppressed?}`; `503` when nothing could be queued |
198
+ | `GET /api/satellites` | `[{id, name, connected, state, host, port, hasControlApi, queueDepth}]` |
199
+ | `GET /api/services` | `{asr, tts, wake}` → each `{uri, status, source, plugin?}`; `wake` gains `models` (available wake-word names) when ready |
200
+ | `GET /api/voices` | piper voices `[{name, languages, description}]`; `503` until TTS is available |
201
+ | `POST /api/satellites/:id/test` | queue a test tone → `202` |
202
+ | `GET /api/satellites/:id/devices` | audio devices `{capture: [{card, device, id, name}], playback: [...]}` (`404` if the satellite has no control API) |
203
+ | `POST /api/satellites/:id/record` | `{seconds?}` (1–10) → `audio/wav` (briefly pauses the satellite) |
204
+ | `POST /api/satellites/:id/play` | `{type: 'tone', frequency?, durationMs?}` or `{type: 'wav', data: base64}` |
205
+ | `GET /api/satellites/:id/vu` | SSE stream of `{rms, peak}` mic levels |
206
+ | `POST /api/transcribe` | `{satellite, seconds?}` (1–10 s) → record → whisper → `{text, latencyMs}`; `503` until STT is available |
207
+ | `POST /api/mute` | `{muted: boolean}` → `{muted}` (same switch as the `voice.muted` PUT) |
208
+ | `GET /api/log` | recent events `[{at, kind, data}]` |
209
+ | `GET /api/events` | SSE: `state`, `command`, `announcement`, `detection`, `service`, `error` |
210
+ | `GET /api/versions` | local-satellite image versions `{versions: [{tag, prerelease?}]}` (works while the plugin is disabled) |
211
+ | `GET /api/update/check` / `POST /api/update/apply` | local-satellite image updates (admin) |
212
+
213
+ `say()` semantics (all three surfaces): the call succeeds when the
214
+ announcement is **queued**, not when it finishes playing; partial failure
215
+ returns `ok: false` with per-satellite errors; text is capped at 500
216
+ characters.
217
+
218
+ ## The webapp
219
+
220
+ Signal K admin UI → Webapps → **Voice (Wyoming)** (`/signalk-wyoming`).
221
+ Three screens, live-updated:
222
+
223
+ - **Status** — services (discovery status, addresses, wake models),
224
+ satellites (connection, state, queue depth, test-tone button), and a
225
+ recent activity log (announcements, commands, detections, errors).
226
+ - **Audio** — for satellites running our image: list the device's
227
+ microphones and speakers (pick one to get the device string for the
228
+ plugin config), _record 3 s & play back_, _play tone_, and a live VU
229
+ meter. Recording briefly pauses the satellite (~2 s) to free the mic.
230
+ - **Test** — type-and-say (target select, voice picker, urgent, mute
231
+ toggle), **record-and-transcribe** (test speech-to-text before any wake
232
+ word exists — the latency figure it shows is the practical benchmark for
233
+ choosing a whisper model), and a live wake-word detection feed.
234
+
235
+ Works over plain LAN HTTP; requests ride your Signal K session — if you see
236
+ "not authorized", log in via the Signal K admin UI.
237
+
238
+ ## Updates & offline use
239
+
240
+ - The **local satellite container** updates from the plugin config panel:
241
+ pick a version from the dropdown (or leave `auto` to follow tested
242
+ releases) and use _Check for updates_ / one-click apply. The version list
243
+ comes from GitHub and keeps showing the last list it saw when you're
244
+ offline.
245
+ - The voice services (piper/whisper/openwakeword) update the same way from
246
+ **their own** plugin panels.
247
+ - After first setup nothing needs the internet: models and images are on
248
+ the boat. Do first starts and version changes **while you have
249
+ connectivity** — a never-downloaded model can't load at sea, and the
250
+ plugins will tell you so rather than sit silent.
251
+
252
+ ## Security — read this
253
+
254
+ **Wyoming has no authentication, and a satellite is an open live
255
+ microphone.** Any device that can reach a satellite's port `10700` can
256
+ connect and stream cabin audio — treat every satellite port like a **baby
257
+ monitor**:
258
+
259
+ - Our satellite image accepts a **single client** at a time, and the
260
+ orchestrator's always-held connection occupies that slot — a rogue LAN
261
+ client finds the mic busy. **Honest gap:** the slot frees on disconnect,
262
+ so a rogue client can seize the mic during the reconnect window after a
263
+ drop (the first reconnect attempt is near-immediate to shrink it).
264
+ - whisper/piper stay on localhost by default — only this plugin needs
265
+ them. openwakeword must be LAN-reachable for remote satellites.
266
+ - Keep satellite ports away from marina wifi: firewall them, or put
267
+ satellites on their own VLAN or WireGuard network.
268
+ - The REST/PUT surfaces respect Signal K access control; there is no
269
+ TLS/auth on the Wyoming connections themselves.
270
+
271
+ ## When things are missing (degraded modes)
272
+
273
+ Partial installs are normal and supported:
274
+
275
+ - **TTS-only** (no whisper): announcements work; record-and-transcribe
276
+ answers `503` with a hint. The recommended starter.
277
+ - **STT-only** (no piper): voice commands work; `say()` fails with "TTS
278
+ unavailable".
279
+ - **Wake words configured but no wake service**: a plugin-status warning
280
+ and a `notifications.voice.wake` alarm; clears by itself when
281
+ openwakeword appears.
282
+ - **Service goes down mid-flight**: `notifications.voice.<service>` alarm +
283
+ plugin status; announcements fail loudly, pipelines time out cleanly.
284
+ - **Local satellite without audio-device support**: current
285
+ signalk-container releases can't pass `/dev/snd` through yet — the plugin
286
+ starts the container anyway, detects the empty device list, and says so
287
+ plainly in the plugin status and webapp instead of failing silently.
288
+
289
+ ## Development
210
290
 
211
- - **Publishing note:** until `signalk-wyoming` is on npm, the sibling repos reference it as `file:../signalk-wyoming` devDependencies — those must flip to a semver range before any of them publish, and their standalone CI stays red until then.
212
- - The webapp (`public/`) is vanilla ES modules with no build step; it is linted/formatted with the same eslint/prettier setup (browser globals).
213
- - Layout: `src/` (orchestrator modules `api.ts` is the REST contract, `pipeline.ts` the wake→ASR engine, `queue.ts`/`say.ts` the announcement rules), `test/` (vitest; mock-server e2e + fake-timer unit suites), `public/` (webapp).
291
+ Technical documentation code layout, architecture, the protocol library
292
+ and mock server, the in-process `say()` API for plugin authors, config
293
+ panel build noteslives in [DEVELOPERS.md](DEVELOPERS.md). The full
294
+ design spec is [SPEC.md](SPEC.md); design rationale in
295
+ [DECISIONS.md](DECISIONS.md).
214
296
 
215
297
  ## License
216
298
 
217
- Apache-2.0. The [wyoming-satellite image repo](https://github.com/hoeken/wyoming-satellite) is MIT (it packages upstream MIT code).
299
+ Apache-2.0 © hoeken. The
300
+ [wyoming-satellite image repo](https://github.com/hoeken/wyoming-satellite)
301
+ is MIT (it packages upstream MIT code).
package/dist/api.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAGH,OAAO,EAGL,KAAK,qBAAqB,EAC3B,MAAM,UAAU,CAAC;AAGlB,OAAO,KAAK,EAAE,IAAI,EAAY,MAAM,sBAAsB,CAAC;AAC3D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AACvD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AACpD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACtD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAMhD,MAAM,WAAW,UAAU;IACzB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,EAAE,CAAC,CAAC,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,IAAI,GAAG,OAAO,CAAC;CACpD;AAED,MAAM,WAAW,WAAW;IAC1B,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,CAAC;IAClC,IAAI,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO,CAAC;IAC7B,IAAI,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO,CAAC;IAC7B,SAAS,CAAC,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC;IACjD,SAAS,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC;IACxE,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;IACvC,GAAG,IAAI,OAAO,CAAC;CAChB;AAED,MAAM,MAAM,UAAU,GAAG,CACvB,GAAG,EAAE,UAAU,EACf,GAAG,EAAE,WAAW,KACb,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;AAE1B,MAAM,WAAW,SAAS;IACxB,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC;IAChD,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC;IACjD,qEAAqE;IACrE,MAAM,CAAC,CAAC,KAAK,EAAE,WAAW,GAAG,UAAU,GAAG,SAAS,CAAC;CACrD;AAMD,MAAM,WAAW,cAAc;IAC7B,SAAS,EAAE,eAAe,CAAC;IAC3B,KAAK,EAAE,iBAAiB,CAAC;CAC1B;AAED,MAAM,WAAW,sBAAsB;IACrC,cAAc,IAAI,OAAO,CAAC,OAAO,CAAC,CAAC;IACnC,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACnD,cAAc,EAAE,MAAM,GAAG,SAAS,CAAC;CACpC;AAED,MAAM,WAAW,OAAO;IACtB,OAAO,IAAI,OAAO,CAAC;IACnB,GAAG,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACrD,SAAS,IAAI,gBAAgB,GAAG,IAAI,CAAC;IACrC,UAAU,IAAI,GAAG,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;IAC1C,GAAG,IAAI,QAAQ,GAAG,IAAI,CAAC;IACvB,QAAQ,IAAI,OAAO,CAAC;IACpB,QAAQ,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI,CAAC;IAC/B,cAAc,IAAI,sBAAsB,GAAG,IAAI,CAAC;IAChD,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,KAAK,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,SAAS,CAAC,EAAE,OAAO,KAAK,CAAC;IACzB,gEAAgE;IAChE,KAAK,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACvC,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;IACnB,uEAAuE;IACvE,QAAQ,CAAC,EAAE,MAAM,MAAM,CAAC;IACxB,0DAA0D;IAC1D,OAAO,CAAC,EAAE,CACR,GAAG,EAAE,MAAM,EACX,IAAI,EAAE;QAAE,QAAQ,CAAC,EAAE,MAAM,CAAA;KAAE,KACxB,OAAO,CAAC,qBAAqB,CAAC,CAAC;CACrC;AAMD;;;GAGG;AACH,wBAAgB,YAAY,CAC1B,IAAI,GAAE;IAAE,WAAW,CAAC,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAA;CAAO,GACvD,aAAa,CAkBf;AAED;;;;GAIG;AACH,eAAO,MAAM,kBAAkB,KAAK,CAAC;AAUrC,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,SAAS,EAAE,IAAI,EAAE,OAAO,GAAG,IAAI,CA2fxE"}
package/dist/api.js CHANGED
@@ -14,6 +14,7 @@
14
14
  */
15
15
  import { randomUUID } from "node:crypto";
16
16
  import { TranscribeSession, wavToPcm, } from "./asr.js";
17
+ import { fetchSatelliteVersions } from "./local-satellite.js";
17
18
  import { probeWyoming } from "./protocol/client.js";
18
19
  // ---------------------------------------------------------------------------
19
20
  // Tone generator (for /api/satellites/:id/test)
@@ -415,6 +416,21 @@ export function registerApiRoutes(router, deps) {
415
416
  }
416
417
  hub.addClient({ on: (event, listener) => req.on?.(event, listener) }, res);
417
418
  }));
419
+ // --- local satellite image versions (config-panel dropdown) --------------
420
+ // Deliberately NOT guarded by the running flag: the operator picks a tag
421
+ // while the plugin is still disabled, and the route only reaches out to
422
+ // GitHub on demand.
423
+ access("readonly").get("/api/versions", async (_req, res) => {
424
+ try {
425
+ const versions = await fetchSatelliteVersions(fetchImpl);
426
+ res.status(200).json({ versions });
427
+ }
428
+ catch (err) {
429
+ res.status(502).json({
430
+ error: err instanceof Error ? err.message : String(err),
431
+ });
432
+ }
433
+ });
418
434
  // --- local satellite image updates (admin-only: no access() wrapper) ----------
419
435
  // Thin delegation to the helper's update surface: the ManagedContainer is
420
436
  // created per-start, but routes register once, so we can't call
package/dist/api.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"api.js","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"api.js","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EACL,iBAAiB,EACjB,QAAQ,GAET,MAAM,UAAU,CAAC;AAClB,OAAO,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;AAC9D,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AA+EpD,8EAA8E;AAC9E,gDAAgD;AAChD,8EAA8E;AAE9E;;;GAGG;AACH,MAAM,UAAU,YAAY,CAC1B,OAAsD,EAAE;IAExD,MAAM,WAAW,GAAG,IAAI,CAAC,WAAW,IAAI,GAAG,CAAC;IAC5C,MAAM,UAAU,GAAG,IAAI,CAAC,UAAU,IAAI,IAAI,CAAC;IAC3C,MAAM,MAAM,GAAG,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,CAAC;IACtD,MAAM,YAAY,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,IAAI,GAAG,UAAU,CAAC,GAAG,IAAI,CAAC,CAAC;IACnE,MAAM,GAAG,GAAG,MAAM,CAAC,KAAK,CAAC,YAAY,GAAG,CAAC,CAAC,CAAC;IAC3C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,YAAY,EAAE,CAAC,EAAE,EAAE,CAAC;QACtC,MAAM,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC;QAC1B,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,EAAE,GAAG,WAAW,GAAG,CAAC,CAAC,CAAC;QACrD,0DAA0D;QAC1D,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC;QAC1C,GAAG,CAAC,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IACtD,CAAC;IACD,MAAM,MAAM,GAAa,EAAE,CAAC;IAC5B,KAAK,IAAI,GAAG,GAAG,CAAC,EAAE,GAAG,GAAG,GAAG,CAAC,MAAM,EAAE,GAAG,IAAI,IAAI,EAAE,CAAC;QAChD,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC,GAAG,GAAG,IAAI,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;IACnE,CAAC;IACD,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC;AAC5B,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,EAAE,CAAC;AAErC,SAAS,kBAAkB,CAAC,OAAe;IACzC,OAAO,IAAI,CAAC,GAAG,CAAC,kBAAkB,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC;AAC5D,CAAC;AAED,8EAA8E;AAC9E,sBAAsB;AACtB,8EAA8E;AAE9E,MAAM,UAAU,iBAAiB,CAAC,MAAiB,EAAE,IAAa;IAChE,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,IAAI,KAAK,CAAC;IAC1C,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,IAAI,CAAC,CAAC,GAAW,EAAE,EAAE,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC;IACjE,MAAM,OAAO,GACX,IAAI,CAAC,OAAO;QACZ,CAAC,CAAC,GAAW,EAAE,IAA2B,EAAE,EAAE,CAC5C,iBAAiB,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC,CAAC;IAEvC,IAAI,YAAY,GAAG,KAAK,CAAC;IACzB,MAAM,MAAM,GAAG,CAAC,KAA+B,EAAa,EAAE;QAC5D,IAAI,OAAO,MAAM,CAAC,MAAM,KAAK,UAAU;YAAE,OAAO,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QACrE,IAAI,CAAC,YAAY,EAAE,CAAC;YAClB,YAAY,GAAG,IAAI,CAAC;YACpB,IAAI,CAAC,GAAG,CACN,iFAAiF,CAClF,CAAC;QACJ,CAAC;QACD,OAAO,MAAM,CAAC;IAChB,CAAC,CAAC;IAEF,oEAAoE;IACpE,MAAM,OAAO,GACX,CAAC,OAAmB,EAAc,EAAE,CACpC,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE;QACjB,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,CAAC;YACpB,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,4BAA4B,EAAE,CAAC,CAAC;YAC9D,OAAO;QACT,CAAC;QACD,IAAI,CAAC;YACH,MAAM,OAAO,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;QAC1B,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YACjE,IAAI,CAAC,KAAK,CAAC,cAAc,OAAO,EAAE,CAAC,CAAC;YACpC,IAAI,CAAC;gBACH,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,CAAC;YAC3C,CAAC;YAAC,MAAM,CAAC;gBACP,4CAA4C;YAC9C,CAAC;QACH,CAAC;IACH,CAAC,CAAC;IAEJ,MAAM,aAAa,GAAG,CACpB,GAAe,EACf,GAAgB,EACO,EAAE;QACzB,MAAM,EAAE,GAAG,GAAG,CAAC,MAAM,EAAE,EAAE,IAAI,EAAE,CAAC;QAChC,MAAM,KAAK,GAAG,IAAI,CAAC,UAAU,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACxC,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YACxB,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,sBAAsB,EAAE,GAAG,EAAE,CAAC,CAAC;YAC7D,OAAO,IAAI,CAAC;QACd,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC,CAAC;IAEF,MAAM,iBAAiB,GAAG,CACxB,GAAe,EACf,GAAgB,EACgC,EAAE;QAClD,MAAM,KAAK,GAAG,aAAa,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;QACtC,IAAI,KAAK,KAAK,IAAI;YAAE,OAAO,IAAI,CAAC;QAChC,MAAM,EAAE,SAAS,EAAE,GAAG,KAAK,CAAC;QAC5B,IAAI,CAAC,SAAS,CAAC,aAAa,IAAI,SAAS,CAAC,WAAW,KAAK,SAAS,EAAE,CAAC;YACpE,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;gBACnB,KAAK,EAAE,cAAc,SAAS,CAAC,EAAE,sBAAsB;aACxD,CAAC,CAAC;YACH,OAAO,IAAI,CAAC;QACd,CAAC;QACD,OAAO;YACL,KAAK;YACL,IAAI,EAAE,UAAU,SAAS,CAAC,IAAI,IAAI,SAAS,CAAC,WAAW,EAAE;SAC1D,CAAC;IACJ,CAAC,CAAC;IAEF,2EAA2E;IAE3E,MAAM,CAAC,WAAW,CAAC,CAAC,IAAI,CACtB,UAAU,EACV,OAAO,CAAC,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE;QACzB,MAAM,IAAI,GACR,GAAG,CAAC,IAAI,KAAK,IAAI,IAAI,OAAO,GAAG,CAAC,IAAI,KAAK,QAAQ;YAC/C,CAAC,CAAE,GAAG,CAAC,IAAgC;YACvC,CAAC,CAAC,EAAE,CAAC;QACT,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;YACpC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAC/B,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;gBACnB,EAAE,EAAE,KAAK;gBACT,KAAK,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC;aACxD,CAAC,CAAC;QACL,CAAC;IACH,CAAC,CAAC,CACH,CAAC;IAEF,2EAA2E;IAE3E,MAAM,CAAC,UAAU,CAAC,CAAC,GAAG,CACpB,iBAAiB,EACjB,OAAO,CAAC,CAAC,IAAI,EAAE,GAAG,EAAE,EAAE;QACpB,MAAM,IAAI,GAAG,CAAC,GAAG,IAAI,CAAC,UAAU,EAAE,CAAC,MAAM,EAAE,CAAC,CAAC,GAAG,CAC9C,CAAC,EAAE,SAAS,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,CAAC;YACzB,EAAE,EAAE,SAAS,CAAC,EAAE;YAChB,IAAI,EAAE,SAAS,CAAC,IAAI;YACpB,SAAS,EAAE,SAAS,CAAC,SAAS;YAC9B,KAAK,EAAE,SAAS,CAAC,KAAK;YACtB,IAAI,EAAE,SAAS,CAAC,IAAI;YACpB,IAAI,EAAE,SAAS,CAAC,IAAI;YACpB,aAAa,EAAE,SAAS,CAAC,aAAa;YACtC,UAAU,EAAE,KAAK,CAAC,KAAK;SACxB,CAAC,CACH,CAAC;QACF,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC7B,CAAC,CAAC,CACH,CAAC;IAEF,MAAM,CAAC,UAAU,CAAC,CAAC,GAAG,CACpB,eAAe,EACf,OAAO,CAAC,KAAK,EAAE,IAAI,EAAE,GAAG,EAAE,EAAE;QAC1B,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,EAAE,CAAC;QACnC,IAAI,SAAS,KAAK,IAAI,EAAE,CAAC;YACvB,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,+BAA+B,EAAE,CAAC,CAAC;YACjE,OAAO;QACT,CAAC;QACD,MAAM,QAAQ,GAAG,SAAS,CAAC,QAAQ,EAGlC,CAAC;QACF,oEAAoE;QACpE,qDAAqD;QACrD,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAI,CAAC;QAC3B,IACE,IAAI,KAAK,SAAS;YAClB,OAAO,IAAI,CAAC,GAAG,KAAK,QAAQ;YAC5B,IAAI,CAAC,MAAM,KAAK,OAAO,EACvB,CAAC;YACD,IAAI,CAAC;gBACH,MAAM,IAAI,GAAG,MAAM,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;gBACnC,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAC1C,CAAC,OAAO,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAClD,CAAC;YACJ,CAAC;YAAC,MAAM,CAAC;gBACP,mDAAmD;YACrD,CAAC;QACH,CAAC;QACD,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IACjC,CAAC,CAAC,CACH,CAAC;IAEF,MAAM,CAAC,UAAU,CAAC,CAAC,GAAG,CACpB,aAAa,EACb,OAAO,CAAC,KAAK,EAAE,IAAI,EAAE,GAAG,EAAE,EAAE;QAC1B,MAAM,GAAG,GAAG,IAAI,CAAC,SAAS,EAAE,EAAE,GAAG,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC;QACjD,IAAI,GAAG,KAAK,IAAI,EAAE,CAAC;YACjB,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,iBAAiB,EAAE,CAAC,CAAC;YACnD,OAAO;QACT,CAAC;QACD,IAAI,IAAU,CAAC;QACf,IAAI,CAAC;YACH,IAAI,GAAG,MAAM,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAC9B,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;gBACnB,KAAK,EAAE,wBAAwB,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE;aAClF,CAAC,CAAC;YACH,OAAO;QACT,CAAC;QACD,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAC1C,CAAC,OAAO,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,KAAe,EAAE,EAAE,CAAC,CAAC;YAC/C,IAAI,EAAE,KAAK,CAAC,IAAI;YAChB,SAAS,EAAE,KAAK,CAAC,SAAS,IAAI,EAAE;YAChC,WAAW,EAAE,KAAK,CAAC,WAAW,IAAI,IAAI;SACvC,CAAC,CAAC,CACJ,CAAC;QACF,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAC/B,CAAC,CAAC,CACH,CAAC;IAEF,6EAA6E;IAE7E,MAAM,CAAC,WAAW,CAAC,CAAC,IAAI,CACtB,0BAA0B,EAC1B,OAAO,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE;QACnB,MAAM,KAAK,GAAG,aAAa,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;QACtC,IAAI,KAAK,KAAK,IAAI;YAAE,OAAO;QAC3B,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,SAAS,EAAE,CAAC;YAC/B,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;gBACnB,KAAK,EAAE,cAAc,KAAK,CAAC,SAAS,CAAC,EAAE,oBAAoB;aAC5D,CAAC,CAAC;YACH,OAAO;QACT,CAAC;QACD,MAAM,IAAI,GAAG;YACX,EAAE,EAAE,UAAU,EAAE;YAChB,KAAK,EAAE,YAAY,EAAE;YACrB,QAAQ,EAAE,QAAiB;YAC3B,IAAI,EAAE,aAAa;YACnB,UAAU,EAAE,CAAC,IAAI,CAAC,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC,EAAE;SACrC,CAAC;QACF,IAAI,CAAC;YACH,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QAC5B,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;gBACnB,KAAK,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC;aACxD,CAAC,CAAC;YACH,OAAO;QACT,CAAC;QACD,IAAI,CAAC,GAAG,EAAE,EAAE,IAAI,CAAC,cAAc,EAAE;YAC/B,SAAS,EAAE,KAAK,CAAC,SAAS,CAAC,EAAE;YAC7B,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,QAAQ,EAAE,IAAI,CAAC,QAAQ;SACxB,CAAC,CAAC;QACH,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,KAAK,CAAC,SAAS,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;IACnE,CAAC,CAAC,CACH,CAAC;IAEF,6EAA6E;IAE7E,MAAM,CAAC,UAAU,CAAC,CAAC,GAAG,CACpB,6BAA6B,EAC7B,OAAO,CAAC,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE;QACzB,MAAM,MAAM,GAAG,iBAAiB,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;QAC3C,IAAI,MAAM,KAAK,IAAI;YAAE,OAAO;QAC5B,MAAM,QAAQ,GAAG,MAAM,SAAS,CAAC,GAAG,MAAM,CAAC,IAAI,UAAU,EAAE;YACzD,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,KAAK,CAAC;SACnC,CAAC,CAAC;QACH,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;QACnC,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACzC,CAAC,CAAC,CACH,CAAC;IAEF,MAAM,CAAC,WAAW,CAAC,CAAC,IAAI,CACtB,4BAA4B,EAC5B,OAAO,CAAC,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE;QACzB,MAAM,MAAM,GAAG,iBAAiB,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;QAC3C,IAAI,MAAM,KAAK,IAAI;YAAE,OAAO;QAC5B,MAAM,IAAI,GACR,GAAG,CAAC,IAAI,KAAK,IAAI,IAAI,OAAO,GAAG,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;QACpE,MAAM,UAAU,GAAI,IAAgC,CAAC,OAAO,CAAC;QAC7D,MAAM,OAAO,GACX,OAAO,UAAU,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,UAAU,CAAC;YAC3D,CAAC,CAAC,kBAAkB,CAAC,UAAU,CAAC;YAChC,CAAC,CAAC,CAAC,CAAC;QACR,MAAM,QAAQ,GAAG,MAAM,SAAS,CAAC,GAAG,MAAM,CAAC,IAAI,cAAc,EAAE;YAC7D,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;YAC/C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,OAAO,EAAE,CAAC;YACjC,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,OAAO,GAAG,IAAI,GAAG,KAAK,CAAC;SACpD,CAAC,CAAC;QACH,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACjB,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC;gBAC/B,KAAK,EAAE,8BAA8B,QAAQ,CAAC,MAAM,GAAG;aACxD,CAAC,CAAC;YACH,OAAO;QACT,CAAC;QACD,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,QAAQ,CAAC,WAAW,EAAE,CAAC,CAAC;QACtD,GAAG,CAAC,SAAS,EAAE,CAAC,cAAc,EAAE,WAAW,CAAC,CAAC;QAC7C,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAC5B,CAAC,CAAC,CACH,CAAC;IAEF,MAAM,CAAC,WAAW,CAAC,CAAC,IAAI,CACtB,0BAA0B,EAC1B,OAAO,CAAC,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE;QACzB,MAAM,MAAM,GAAG,iBAAiB,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;QAC3C,IAAI,MAAM,KAAK,IAAI;YAAE,OAAO;QAC5B,MAAM,QAAQ,GAAG,MAAM,SAAS,CAAC,GAAG,MAAM,CAAC,IAAI,YAAY,EAAE;YAC3D,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;YAC/C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;YAClD,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,KAAK,CAAC;SACnC,CAAC,CAAC;QACH,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QACrD,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACzC,CAAC,CAAC,CACH,CAAC;IAEF,MAAM,CAAC,UAAU,CAAC,CAAC,GAAG,CACpB,wBAAwB,EACxB,OAAO,CAAC,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE;QACzB,MAAM,MAAM,GAAG,iBAAiB,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;QAC3C,IAAI,MAAM,KAAK,IAAI;YAAE,OAAO;QAC5B,MAAM,UAAU,GAAG,IAAI,eAAe,EAAE,CAAC;QACzC,GAAG,CAAC,EAAE,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,UAAU,CAAC,KAAK,EAAE,CAAC,CAAC;QAC5C,IAAI,QAAkB,CAAC;QACvB,IAAI,CAAC;YACH,QAAQ,GAAG,MAAM,SAAS,CAAC,GAAG,MAAM,CAAC,IAAI,KAAK,EAAE;gBAC9C,MAAM,EAAE,UAAU,CAAC,MAAM;aAC1B,CAAC,CAAC;QACL,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;gBACnB,KAAK,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC;aACxD,CAAC,CAAC;YACH,OAAO;QACT,CAAC;QACD,IAAI,CAAC,QAAQ,CAAC,EAAE,IAAI,QAAQ,CAAC,IAAI,KAAK,IAAI,EAAE,CAAC;YAC3C,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,mCAAmC,EAAE,CAAC,CAAC;YACrE,OAAO;QACT,CAAC;QACD,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE;YACjB,cAAc,EAAE,mBAAmB;YACnC,eAAe,EAAE,UAAU;YAC3B,UAAU,EAAE,YAAY;SACzB,CAAC,CAAC;QACH,IAAI,CAAC;YACH,IAAI,KAAK,EAAE,MAAM,KAAK,IAAI,QAAQ,CAAC,IAA4C,EAAE,CAAC;gBAChF,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;YAChC,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,mDAAmD;QACrD,CAAC;gBAAS,CAAC;YACT,UAAU,CAAC,KAAK,EAAE,CAAC;YACnB,GAAG,CAAC,GAAG,EAAE,CAAC;QACZ,CAAC;IACH,CAAC,CAAC,CACH,CAAC;IAEF,6EAA6E;IAE7E,MAAM,CAAC,WAAW,CAAC,CAAC,IAAI,CACtB,iBAAiB,EACjB,OAAO,CAAC,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE;QACzB,MAAM,IAAI,GACR,GAAG,CAAC,IAAI,KAAK,IAAI,IAAI,OAAO,GAAG,CAAC,IAAI,KAAK,QAAQ;YAC/C,CAAC,CAAE,GAAG,CAAC,IAAgC;YACvC,CAAC,CAAC,EAAE,CAAC;QACT,MAAM,WAAW,GACf,OAAO,IAAI,CAAC,SAAS,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC;QAC3D,IAAI,WAAW,KAAK,EAAE,EAAE,CAAC;YACvB,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;gBACnB,KAAK,EAAE,oDAAoD;aAC5D,CAAC,CAAC;YACH,OAAO;QACT,CAAC;QACD,MAAM,GAAG,GAAG,IAAI,CAAC,SAAS,EAAE,EAAE,GAAG,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC;QACjD,IAAI,GAAG,KAAK,IAAI,EAAE,CAAC;YACjB,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;gBACnB,KAAK,EACH,6EAA6E;aAChF,CAAC,CAAC;YACH,OAAO;QACT,CAAC;QACD,MAAM,KAAK,GAAG,IAAI,CAAC,UAAU,EAAE,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;QACjD,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YACxB,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,sBAAsB,WAAW,GAAG,EAAE,CAAC,CAAC;YACtE,OAAO;QACT,CAAC;QACD,MAAM,EAAE,SAAS,EAAE,GAAG,KAAK,CAAC;QAC5B,IAAI,CAAC,SAAS,CAAC,aAAa,IAAI,SAAS,CAAC,WAAW,KAAK,SAAS,EAAE,CAAC;YACpE,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;gBACnB,KAAK,EAAE,cAAc,SAAS,CAAC,EAAE,sBAAsB;aACxD,CAAC,CAAC;YACH,OAAO;QACT,CAAC;QACD,MAAM,OAAO,GACX,OAAO,IAAI,CAAC,OAAO,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC;YAC/D,CAAC,CAAC,kBAAkB,CAAC,IAAI,CAAC,OAAO,CAAC;YAClC,CAAC,CAAC,CAAC,CAAC;QACR,MAAM,QAAQ,GAAG,MAAM,SAAS,CAC9B,UAAU,SAAS,CAAC,IAAI,IAAI,SAAS,CAAC,WAAW,cAAc,EAC/D;YACE,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;YAC/C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,OAAO,EAAE,CAAC;YACjC,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,OAAO,GAAG,IAAI,GAAG,KAAK,CAAC;SACpD,CACF,CAAC;QACF,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACjB,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;gBACnB,KAAK,EAAE,8BAA8B,QAAQ,CAAC,MAAM,GAAG;aACxD,CAAC,CAAC;YACH,OAAO;QACT,CAAC;QACD,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,QAAQ,CAAC,WAAW,EAAE,CAAC,CAAC;QACtD,IAAI,GAAgC,CAAC;QACrC,IAAI,CAAC;YACH,GAAG,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC;QACtB,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;gBACnB,KAAK,EAAE,iCAAiC,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE;aAC3F,CAAC,CAAC;YACH,OAAO;QACT,CAAC;QACD,qEAAqE;QACrE,2CAA2C;QAC3C,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC;QACjC,MAAM,SAAS,GAAG,GAAG,EAAE,CAAC;QACxB,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,EAAE,EAAE,CAAC,CAAC;QACxE,IAAI,IAAY,CAAC;QACjB,IAAI,CAAC;YACH,KAAK,IAAI,GAAG,GAAG,CAAC,EAAE,GAAG,GAAG,GAAG,CAAC,GAAG,CAAC,MAAM,EAAE,GAAG,IAAI,IAAI,EAAE,CAAC;gBACpD,OAAO,CAAC,IAAI,CACV,GAAG,CAAC,GAAG,CAAC,QAAQ,CAAC,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC,GAAG,GAAG,IAAI,EAAE,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,EAC3D,GAAG,CAAC,MAAM,CACX,CAAC;YACJ,CAAC;YACD,CAAC,EAAE,IAAI,EAAE,GAAG,MAAM,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;QAC3C,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,CAAC,KAAK,EAAE,CAAC;YAChB,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;gBACnB,KAAK,EAAE,yBAAyB,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE;aACnF,CAAC,CAAC;YACH,OAAO;QACT,CAAC;QACD,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC,EAAE,CAAC,CAAC;IAC3E,CAAC,CAAC,CACH,CAAC;IAEF,+EAA+E;IAE/E,MAAM,CAAC,WAAW,CAAC,CAAC,IAAI,CACtB,WAAW,EACX,OAAO,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE;QACnB,MAAM,IAAI,GACR,GAAG,CAAC,IAAI,KAAK,IAAI,IAAI,OAAO,GAAG,CAAC,IAAI,KAAK,QAAQ;YAC/C,CAAC,CAAE,GAAG,CAAC,IAAgC;YACvC,CAAC,CAAC,EAAE,CAAC;QACT,IAAI,OAAO,IAAI,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;YACpC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,+BAA+B,EAAE,CAAC,CAAC;YACjE,OAAO;QACT,CAAC;QACD,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC1B,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;IACnD,CAAC,CAAC,CACH,CAAC;IAEF,iFAAiF;IAEjF,MAAM,CAAC,UAAU,CAAC,CAAC,GAAG,CACpB,UAAU,EACV,OAAO,CAAC,CAAC,IAAI,EAAE,GAAG,EAAE,EAAE;QACpB,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACvB,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC;IACvD,CAAC,CAAC,CACH,CAAC;IAEF,MAAM,CAAC,UAAU,CAAC,CAAC,GAAG,CACpB,aAAa,EACb,OAAO,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE;QACnB,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACvB,IAAI,GAAG,KAAK,IAAI,EAAE,CAAC;YACjB,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,uBAAuB,EAAE,CAAC,CAAC;YACzD,OAAO;QACT,CAAC;QACD,GAAG,CAAC,SAAS,CACX,EAAE,EAAE,EAAE,CAAC,KAAK,EAAE,QAAQ,EAAE,EAAE,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,KAAK,EAAE,QAAQ,CAAC,EAAE,EACtD,GAAG,CACJ,CAAC;IACJ,CAAC,CAAC,CACH,CAAC;IAEF,4EAA4E;IAC5E,yEAAyE;IACzE,wEAAwE;IACxE,oBAAoB;IAEpB,MAAM,CAAC,UAAU,CAAC,CAAC,GAAG,CAAC,eAAe,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,EAAE,EAAE;QAC1D,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,MAAM,sBAAsB,CAAC,SAAS,CAAC,CAAC;YACzD,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC;QACrC,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;gBACnB,KAAK,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC;aACxD,CAAC,CAAC;QACL,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,iFAAiF;IACjF,0EAA0E;IAC1E,gEAAgE;IAChE,yCAAyC;IAEzC,MAAM,CAAC,GAAG,CACR,mBAAmB,EACnB,OAAO,CAAC,KAAK,EAAE,IAAI,EAAE,GAAG,EAAE,EAAE;QAC1B,MAAM,SAAS,GAAG,IAAI,CAAC,cAAc,EAAE,CAAC;QACxC,IAAI,SAAS,KAAK,IAAI,EAAE,CAAC;YACvB,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,gCAAgC,EAAE,CAAC,CAAC;YAClE,OAAO;QACT,CAAC;QACD,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,MAAM,SAAS,CAAC,cAAc,EAAE,CAAC,CAAC;IACzD,CAAC,CAAC,CACH,CAAC;IAEF,MAAM,CAAC,IAAI,CACT,mBAAmB,EACnB,OAAO,CAAC,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE;QACzB,MAAM,SAAS,GAAG,IAAI,CAAC,cAAc,EAAE,CAAC;QACxC,IAAI,SAAS,KAAK,IAAI,EAAE,CAAC;YACvB,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,gCAAgC,EAAE,CAAC,CAAC;YAClE,OAAO;QACT,CAAC;QACD,MAAM,IAAI,GACR,GAAG,CAAC,IAAI,KAAK,IAAI,IAAI,OAAO,GAAG,CAAC,IAAI,KAAK,QAAQ;YAC/C,CAAC,CAAE,GAAG,CAAC,IAAgC;YACvC,CAAC,CAAC,EAAE,CAAC;QACT,MAAM,GAAG,GACP,OAAO,IAAI,CAAC,GAAG,KAAK,QAAQ,IAAI,IAAI,CAAC,GAAG,KAAK,EAAE;YAC7C,CAAC,CAAC,IAAI,CAAC,GAAG;YACV,CAAC,CAAC,CAAC,SAAS,CAAC,cAAc,IAAI,MAAM,CAAC,CAAC;QAC3C,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,MAAM,SAAS,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;YACjD,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,GAAG,EAAE,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;QAC5D,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;gBACnB,KAAK,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC;aACxD,CAAC,CAAC;QACL,CAAC;IACH,CAAC,CAAC,CACH,CAAC;AACJ,CAAC"}
@@ -36,6 +36,24 @@ export declare function containerWakeUri(uri: string): string;
36
36
  export declare function buildLocalSatelliteEnv(inputs: LocalSatelliteBuildInputs): Record<string, string>;
37
37
  /** Full ContainerConfig for a tag (pure — unit-tested directly). */
38
38
  export declare function buildLocalSatelliteConfig(tag: string, inputs: LocalSatelliteBuildInputs): ContainerConfig;
39
+ /**
40
+ * GitHub tags for the satellite image. The publish workflow builds an image
41
+ * tag (bare semver, `v` stripped by docker/metadata-action) for every `v*`
42
+ * git tag; the repo has no GitHub Releases, so the helper's stock
43
+ * `githubReleases` source would see nothing.
44
+ */
45
+ export declare const SATELLITE_TAGS_URL = "https://api.github.com/repos/hoeken/wyoming-satellite/tags?per_page=25";
46
+ export interface SatelliteVersion {
47
+ tag: string;
48
+ prerelease?: boolean;
49
+ }
50
+ /**
51
+ * Image tags published for the local satellite, newest first — feeds both
52
+ * GET /api/versions (the panel's VersionSelect) and the update-detection
53
+ * VersionSource. Throws on network/HTTP failure (e.g. offline, or GitHub's
54
+ * anonymous rate limit); callers surface the message, never crash.
55
+ */
56
+ export declare function fetchSatelliteVersions(fetchImpl?: typeof fetch): Promise<SatelliteVersion[]>;
39
57
  export interface LocalSatelliteAddresses {
40
58
  /** Wyoming endpoint. */
41
59
  host: string;
@@ -1 +1 @@
1
- {"version":3,"file":"local-satellite.d.ts","sourceRoot":"","sources":["../src/local-satellite.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EACL,gBAAgB,EAChB,KAAK,eAAe,EACrB,MAAM,0BAA0B,CAAC;AAClC,OAAO,KAAK,EAAE,cAAc,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAIxE,eAAO,MAAM,qBAAqB,qCAAqC,CAAC;AACxE,eAAO,MAAM,0BAA0B,UAAU,CAAC;AAClD,eAAO,MAAM,8BAA8B,sBAAsB,CAAC;AAClE,0EAA0E;AAC1E,eAAO,MAAM,aAAa,WAAW,CAAC;AAGtC,MAAM,WAAW,yBAAyB;IACxC,KAAK,EAAE,oBAAoB,CAAC;IAC5B,QAAQ,EAAE,cAAc,CAAC;IACzB,6EAA6E;IAC7E,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;CACxB;AAID;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAUpD;AAED,uEAAuE;AACvE,wBAAgB,sBAAsB,CACpC,MAAM,EAAE,yBAAyB,GAChC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAuBxB;AAED,oEAAoE;AACpE,wBAAgB,yBAAyB,CACvC,GAAG,EAAE,MAAM,EACX,MAAM,EAAE,yBAAyB,GAChC,eAAe,CA6BjB;AAED,MAAM,WAAW,uBAAuB;IACtC,wBAAwB;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,4BAA4B;IAC5B,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,qBAAqB;IACpC,KAAK,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;CACnC;AAED,MAAM,WAAW,kBAAkB;IACjC,GAAG,EAAE,qBAAqB,CAAC;IAC3B,KAAK,EAAE,oBAAoB,CAAC;IAC5B,QAAQ,EAAE,cAAc,CAAC;IACzB;;;;OAIG;IACH,OAAO,EAAE,MAAM,MAAM,GAAG,IAAI,CAAC;IAC7B,SAAS,CAAC,EAAE,OAAO,KAAK,CAAC;CAC1B;AAED,MAAM,WAAW,oBAAoB;IACnC,SAAS,EAAE,gBAAgB,CAAC;IAC5B,uEAAuE;IACvE,KAAK,IAAI,OAAO,CAAC,uBAAuB,CAAC,CAAC;IAC1C,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACtB;;;;;OAKG;IACH,YAAY,IAAI,OAAO,CAAC;IACxB;;;;OAIG;IACH,iBAAiB,CAAC,SAAS,EAAE,uBAAuB,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;CAC/E;AAED,wBAAgB,oBAAoB,CAClC,IAAI,EAAE,kBAAkB,GACvB,oBAAoB,CAkFtB"}
1
+ {"version":3,"file":"local-satellite.d.ts","sourceRoot":"","sources":["../src/local-satellite.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EACL,gBAAgB,EAChB,KAAK,eAAe,EAErB,MAAM,0BAA0B,CAAC;AAClC,OAAO,KAAK,EAAE,cAAc,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAIxE,eAAO,MAAM,qBAAqB,qCAAqC,CAAC;AACxE,eAAO,MAAM,0BAA0B,UAAU,CAAC;AAClD,eAAO,MAAM,8BAA8B,sBAAsB,CAAC;AAClE,0EAA0E;AAC1E,eAAO,MAAM,aAAa,WAAW,CAAC;AAGtC,MAAM,WAAW,yBAAyB;IACxC,KAAK,EAAE,oBAAoB,CAAC;IAC5B,QAAQ,EAAE,cAAc,CAAC;IACzB,6EAA6E;IAC7E,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;CACxB;AAID;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAUpD;AAED,uEAAuE;AACvE,wBAAgB,sBAAsB,CACpC,MAAM,EAAE,yBAAyB,GAChC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAuBxB;AAED,oEAAoE;AACpE,wBAAgB,yBAAyB,CACvC,GAAG,EAAE,MAAM,EACX,MAAM,EAAE,yBAAyB,GAChC,eAAe,CA6BjB;AAMD;;;;;GAKG;AACH,eAAO,MAAM,kBAAkB,2EAC2C,CAAC;AAE3E,MAAM,WAAW,gBAAgB;IAC/B,GAAG,EAAE,MAAM,CAAC;IACZ,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAgBD;;;;;GAKG;AACH,wBAAsB,sBAAsB,CAC1C,SAAS,GAAE,OAAO,KAAa,GAC9B,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAmB7B;AAoBD,MAAM,WAAW,uBAAuB;IACtC,wBAAwB;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,4BAA4B;IAC5B,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,qBAAqB;IACpC,KAAK,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;CACnC;AAED,MAAM,WAAW,kBAAkB;IACjC,GAAG,EAAE,qBAAqB,CAAC;IAC3B,KAAK,EAAE,oBAAoB,CAAC;IAC5B,QAAQ,EAAE,cAAc,CAAC;IACzB;;;;OAIG;IACH,OAAO,EAAE,MAAM,MAAM,GAAG,IAAI,CAAC;IAC7B,SAAS,CAAC,EAAE,OAAO,KAAK,CAAC;CAC1B;AAED,MAAM,WAAW,oBAAoB;IACnC,SAAS,EAAE,gBAAgB,CAAC;IAC5B,uEAAuE;IACvE,KAAK,IAAI,OAAO,CAAC,uBAAuB,CAAC,CAAC;IAC1C,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACtB;;;;;OAKG;IACH,YAAY,IAAI,OAAO,CAAC;IACxB;;;;OAIG;IACH,iBAAiB,CAAC,SAAS,EAAE,uBAAuB,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;CAC/E;AAED,wBAAgB,oBAAoB,CAClC,IAAI,EAAE,kBAAkB,GACvB,oBAAoB,CA0FtB"}
@@ -98,6 +98,73 @@ export function buildLocalSatelliteConfig(tag, inputs) {
98
98
  forward.groupAdd = ["audio"];
99
99
  return config;
100
100
  }
101
+ // ---------------------------------------------------------------------------
102
+ // Image versions — the config panel's dropdown and update detection
103
+ // ---------------------------------------------------------------------------
104
+ /**
105
+ * GitHub tags for the satellite image. The publish workflow builds an image
106
+ * tag (bare semver, `v` stripped by docker/metadata-action) for every `v*`
107
+ * git tag; the repo has no GitHub Releases, so the helper's stock
108
+ * `githubReleases` source would see nothing.
109
+ */
110
+ export const SATELLITE_TAGS_URL = "https://api.github.com/repos/hoeken/wyoming-satellite/tags?per_page=25";
111
+ const IMAGE_TAG = /^(\d+)\.(\d+)\.(\d+)(-[0-9A-Za-z.-]+)?$/;
112
+ /** Numeric-descending on the x.y.z triple; stable before prerelease. */
113
+ function compareTagsDesc(a, b) {
114
+ const pa = IMAGE_TAG.exec(a);
115
+ const pb = IMAGE_TAG.exec(b);
116
+ if (pa === null || pb === null)
117
+ return 0;
118
+ for (let i = 1; i <= 3; i += 1) {
119
+ const d = Number(pb[i]) - Number(pa[i]);
120
+ if (d !== 0)
121
+ return d;
122
+ }
123
+ return (pa[4] === undefined ? 0 : 1) - (pb[4] === undefined ? 0 : 1);
124
+ }
125
+ /**
126
+ * Image tags published for the local satellite, newest first — feeds both
127
+ * GET /api/versions (the panel's VersionSelect) and the update-detection
128
+ * VersionSource. Throws on network/HTTP failure (e.g. offline, or GitHub's
129
+ * anonymous rate limit); callers surface the message, never crash.
130
+ */
131
+ export async function fetchSatelliteVersions(fetchImpl = fetch) {
132
+ const res = await fetchImpl(SATELLITE_TAGS_URL, {
133
+ signal: AbortSignal.timeout(10_000),
134
+ headers: { accept: "application/vnd.github+json" },
135
+ });
136
+ if (!res.ok) {
137
+ throw new Error(`GitHub answered HTTP ${res.status}`);
138
+ }
139
+ const body = (await res.json());
140
+ return (Array.isArray(body) ? body : [])
141
+ .map((entry) => (typeof entry?.name === "string" ? entry.name : ""))
142
+ .map((name) => (name.startsWith("v") ? name.slice(1) : name))
143
+ .filter((tag) => IMAGE_TAG.test(tag))
144
+ .sort(compareTagsDesc)
145
+ .map((tag) => {
146
+ const version = { tag };
147
+ if (IMAGE_TAG.exec(tag)?.[4] !== undefined)
148
+ version.prerelease = true;
149
+ return version;
150
+ });
151
+ }
152
+ /** Update-detection strategy: latest stable image tag from GitHub. */
153
+ async function latestSatelliteVersion(fetchImpl) {
154
+ try {
155
+ const versions = await fetchSatelliteVersions(fetchImpl);
156
+ const stable = versions.find((v) => v.prerelease !== true);
157
+ return stable !== undefined
158
+ ? { kind: "version", latest: stable.tag }
159
+ : { kind: "error", error: "no release tags found" };
160
+ }
161
+ catch (err) {
162
+ return {
163
+ kind: "error",
164
+ error: err instanceof Error ? err.message : String(err),
165
+ };
166
+ }
167
+ }
101
168
  export function createLocalSatellite(deps) {
102
169
  const fetchImpl = deps.fetchImpl ?? fetch;
103
170
  const currentInputs = () => ({
@@ -117,6 +184,13 @@ export function createLocalSatellite(deps) {
117
184
  buildConfig: (tag) => buildLocalSatelliteConfig(tag, currentInputs()),
118
185
  // Control API is HTTP — helper readiness applies (unlike Wyoming TCP).
119
186
  readiness: { port: SATELLITE_CONTROL_PORT, path: "/health" },
187
+ updates: {
188
+ versionSource: {
189
+ custom: { fetch: () => latestSatelliteVersion(fetchImpl) },
190
+ },
191
+ // Compare the resolved tag — "auto" is an alias, not a version.
192
+ currentTag: () => deps.local.tag === "auto" ? LOCAL_SATELLITE_PINNED_TAG : deps.local.tag,
193
+ },
120
194
  });
121
195
  return {
122
196
  container,
@@ -1 +1 @@
1
- {"version":3,"file":"local-satellite.js","sourceRoot":"","sources":["../src/local-satellite.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"local-satellite.js","sourceRoot":"","sources":["../src/local-satellite.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "signalk-wyoming",
3
- "version": "0.1.1",
3
+ "version": "0.2.0",
4
4
  "description": "Wyoming protocol voice assistant orchestrator for Signal K — voice commands in, spoken announcements out.",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -26,7 +26,7 @@
26
26
  "LICENSE"
27
27
  ],
28
28
  "scripts": {
29
- "build": "tsc",
29
+ "build": "tsc && webpack",
30
30
  "test": "npm run typecheck:test && vitest run",
31
31
  "test:watch": "vitest",
32
32
  "typecheck": "tsc --noEmit",
@@ -53,6 +53,7 @@
53
53
  "stt",
54
54
  "marine",
55
55
  "signalk-node-server-plugin",
56
+ "signalk-plugin-configurator",
56
57
  "signalk-webapp",
57
58
  "signalk-category-utility"
58
59
  ],
@@ -72,20 +73,27 @@
72
73
  "node": ">=24"
73
74
  },
74
75
  "dependencies": {
75
- "signalk-container-helper": "^0.1.0"
76
+ "signalk-container-helper": "^0.2.1"
76
77
  },
77
78
  "devDependencies": {
79
+ "@babel/core": "^7.29.0",
80
+ "@babel/preset-react": "^7.28.5",
78
81
  "@eslint/js": "^10.0.1",
79
82
  "@signalk/server-api": "^2.30.0",
80
83
  "@types/node": "^24.0.0",
84
+ "babel-loader": "^10.1.1",
81
85
  "eslint": "^10.2.0",
82
86
  "eslint-config-prettier": "^10.1.8",
83
87
  "globals": "^17.4.0",
84
88
  "husky": "^9.1.7",
85
89
  "lint-staged": "^16.4.0",
86
90
  "prettier": "^3.8.1",
91
+ "react": "^19.2.4",
92
+ "react-dom": "^19.2.4",
87
93
  "typescript": "^5.5.0",
88
94
  "typescript-eslint": "^8.58.0",
89
- "vitest": "^4.1.10"
95
+ "vitest": "^4.1.10",
96
+ "webpack": "^5.105.4",
97
+ "webpack-cli": "^7.0.2"
90
98
  }
91
99
  }
package/public/540.mjs ADDED
@@ -0,0 +1,2 @@
1
+ /*! For license information please see 540.mjs.LICENSE.txt */
2
+ export const __webpack_esm_id__=540;export const __webpack_esm_ids__=[540];export const __webpack_esm_modules__={869(e,t){var n=Symbol.for("react.transitional.element"),r=Symbol.for("react.portal"),o=Symbol.for("react.fragment"),u=Symbol.for("react.strict_mode"),c=Symbol.for("react.profiler"),s=Symbol.for("react.consumer"),i=Symbol.for("react.context"),a=Symbol.for("react.forward_ref"),f=Symbol.for("react.suspense"),l=Symbol.for("react.memo"),p=Symbol.for("react.lazy"),y=Symbol.for("react.activity"),d=Symbol.iterator,_={isMounted:function(){return!1},enqueueForceUpdate:function(){},enqueueReplaceState:function(){},enqueueSetState:function(){}},h=Object.assign,m={};function b(e,t,n){this.props=e,this.context=t,this.refs=m,this.updater=n||_}function v(){}function S(e,t,n){this.props=e,this.context=t,this.refs=m,this.updater=n||_}b.prototype.isReactComponent={},b.prototype.setState=function(e,t){if("object"!=typeof e&&"function"!=typeof e&&null!=e)throw Error("takes an object of state variables to update or a function which returns an object of state variables.");this.updater.enqueueSetState(this,e,t,"setState")},b.prototype.forceUpdate=function(e){this.updater.enqueueForceUpdate(this,e,"forceUpdate")},v.prototype=b.prototype;var E=S.prototype=new v;E.constructor=S,h(E,b.prototype),E.isPureReactComponent=!0;var w=Array.isArray;function g(){}var k={H:null,A:null,T:null,S:null},H=Object.prototype.hasOwnProperty;function j(e,t,r){var o=r.ref;return{$$typeof:n,type:e,key:t,ref:void 0!==o?o:null,props:r}}function R(e){return"object"==typeof e&&null!==e&&e.$$typeof===n}var C=/\/+/g;function $(e,t){return"object"==typeof e&&null!==e&&null!=e.key?(n=""+e.key,r={"=":"=0",":":"=2"},"$"+n.replace(/[=:]/g,function(e){return r[e]})):t.toString(36);var n,r}function x(e,t,o,u,c){var s=typeof e;"undefined"!==s&&"boolean"!==s||(e=null);var i,a,f=!1;if(null===e)f=!0;else switch(s){case"bigint":case"string":case"number":f=!0;break;case"object":switch(e.$$typeof){case n:case r:f=!0;break;case p:return x((f=e._init)(e._payload),t,o,u,c)}}if(f)return c=c(e),f=""===u?"."+$(e,0):u,w(c)?(o="",null!=f&&(o=f.replace(C,"$&/")+"/"),x(c,t,o,"",function(e){return e})):null!=c&&(R(c)&&(i=c,a=o+(null==c.key||e&&e.key===c.key?"":(""+c.key).replace(C,"$&/")+"/")+f,c=j(i.type,a,i.props)),t.push(c)),1;f=0;var l,y=""===u?".":u+":";if(w(e))for(var _=0;_<e.length;_++)f+=x(u=e[_],t,o,s=y+$(u,_),c);else if("function"==typeof(_=null===(l=e)||"object"!=typeof l?null:"function"==typeof(l=d&&l[d]||l["@@iterator"])?l:null))for(e=_.call(e),_=0;!(u=e.next()).done;)f+=x(u=u.value,t,o,s=y+$(u,_++),c);else if("object"===s){if("function"==typeof e.then)return x(function(e){switch(e.status){case"fulfilled":return e.value;case"rejected":throw e.reason;default:switch("string"==typeof e.status?e.then(g,g):(e.status="pending",e.then(function(t){"pending"===e.status&&(e.status="fulfilled",e.value=t)},function(t){"pending"===e.status&&(e.status="rejected",e.reason=t)})),e.status){case"fulfilled":return e.value;case"rejected":throw e.reason}}throw e}(e),t,o,u,c);throw t=String(e),Error("Objects are not valid as a React child (found: "+("[object Object]"===t?"object with keys {"+Object.keys(e).join(", ")+"}":t)+"). If you meant to render a collection of children, use an array instead.")}return f}function T(e,t,n){if(null==e)return e;var r=[],o=0;return x(e,r,"","",function(e){return t.call(n,e,o++)}),r}function A(e){if(-1===e._status){var t=e._result;(t=t()).then(function(t){0!==e._status&&-1!==e._status||(e._status=1,e._result=t)},function(t){0!==e._status&&-1!==e._status||(e._status=2,e._result=t)}),-1===e._status&&(e._status=0,e._result=t)}if(1===e._status)return e._result.default;throw e._result}var O="function"==typeof reportError?reportError:function(e){if("object"==typeof window&&"function"==typeof window.ErrorEvent){var t=new window.ErrorEvent("error",{bubbles:!0,cancelable:!0,message:"object"==typeof e&&null!==e&&"string"==typeof e.message?String(e.message):String(e),error:e});if(!window.dispatchEvent(t))return}else if("object"==typeof process&&"function"==typeof process.emit)return void process.emit("uncaughtException",e);console.error(e)},I={map:T,forEach:function(e,t,n){T(e,function(){t.apply(this,arguments)},n)},count:function(e){var t=0;return T(e,function(){t++}),t},toArray:function(e){return T(e,function(e){return e})||[]},only:function(e){if(!R(e))throw Error("React.Children.only expected to receive a single React element child.");return e}};t.Activity=y,t.Children=I,t.Component=b,t.Fragment=o,t.Profiler=c,t.PureComponent=S,t.StrictMode=u,t.Suspense=f,t.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE=k,t.__COMPILER_RUNTIME={__proto__:null,c:function(e){return k.H.useMemoCache(e)}},t.cache=function(e){return function(){return e.apply(null,arguments)}},t.cacheSignal=function(){return null},t.cloneElement=function(e,t,n){if(null==e)throw Error("The argument must be a React element, but you passed "+e+".");var r=h({},e.props),o=e.key;if(null!=t)for(u in void 0!==t.key&&(o=""+t.key),t)!H.call(t,u)||"key"===u||"__self"===u||"__source"===u||"ref"===u&&void 0===t.ref||(r[u]=t[u]);var u=arguments.length-2;if(1===u)r.children=n;else if(1<u){for(var c=Array(u),s=0;s<u;s++)c[s]=arguments[s+2];r.children=c}return j(e.type,o,r)},t.createContext=function(e){return(e={$$typeof:i,_currentValue:e,_currentValue2:e,_threadCount:0,Provider:null,Consumer:null}).Provider=e,e.Consumer={$$typeof:s,_context:e},e},t.createElement=function(e,t,n){var r,o={},u=null;if(null!=t)for(r in void 0!==t.key&&(u=""+t.key),t)H.call(t,r)&&"key"!==r&&"__self"!==r&&"__source"!==r&&(o[r]=t[r]);var c=arguments.length-2;if(1===c)o.children=n;else if(1<c){for(var s=Array(c),i=0;i<c;i++)s[i]=arguments[i+2];o.children=s}if(e&&e.defaultProps)for(r in c=e.defaultProps)void 0===o[r]&&(o[r]=c[r]);return j(e,u,o)},t.createRef=function(){return{current:null}},t.forwardRef=function(e){return{$$typeof:a,render:e}},t.isValidElement=R,t.lazy=function(e){return{$$typeof:p,_payload:{_status:-1,_result:e},_init:A}},t.memo=function(e,t){return{$$typeof:l,type:e,compare:void 0===t?null:t}},t.startTransition=function(e){var t=k.T,n={};k.T=n;try{var r=e(),o=k.S;null!==o&&o(n,r),"object"==typeof r&&null!==r&&"function"==typeof r.then&&r.then(g,O)}catch(e){O(e)}finally{null!==t&&null!==n.types&&(t.types=n.types),k.T=t}},t.unstable_useCacheRefresh=function(){return k.H.useCacheRefresh()},t.use=function(e){return k.H.use(e)},t.useActionState=function(e,t,n){return k.H.useActionState(e,t,n)},t.useCallback=function(e,t){return k.H.useCallback(e,t)},t.useContext=function(e){return k.H.useContext(e)},t.useDebugValue=function(){},t.useDeferredValue=function(e,t){return k.H.useDeferredValue(e,t)},t.useEffect=function(e,t){return k.H.useEffect(e,t)},t.useEffectEvent=function(e){return k.H.useEffectEvent(e)},t.useId=function(){return k.H.useId()},t.useImperativeHandle=function(e,t,n){return k.H.useImperativeHandle(e,t,n)},t.useInsertionEffect=function(e,t){return k.H.useInsertionEffect(e,t)},t.useLayoutEffect=function(e,t){return k.H.useLayoutEffect(e,t)},t.useMemo=function(e,t){return k.H.useMemo(e,t)},t.useOptimistic=function(e,t){return k.H.useOptimistic(e,t)},t.useReducer=function(e,t,n){return k.H.useReducer(e,t,n)},t.useRef=function(e){return k.H.useRef(e)},t.useState=function(e){return k.H.useState(e)},t.useSyncExternalStore=function(e,t,n){return k.H.useSyncExternalStore(e,t,n)},t.useTransition=function(){return k.H.useTransition()},t.version="19.2.8"},540(e,t,n){e.exports=n(869)}};
@@ -0,0 +1,9 @@
1
+ /**
2
+ * @license React
3
+ * react.production.js
4
+ *
5
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
6
+ *
7
+ * This source code is licensed under the MIT license found in the
8
+ * LICENSE file in the root directory of this source tree.
9
+ */
package/public/786.mjs ADDED
@@ -0,0 +1 @@
1
+ export const __webpack_esm_id__=786;export const __webpack_esm_ids__=[786];export const __webpack_esm_modules__={786(e,t,r){r.d(t,{VI:()=>m,$n:()=>b,iV:()=>p,RU:()=>d,_x:()=>s,LB:()=>f,JK:()=>u,_j:()=>k,t7:()=>h});var n=r(231),a=r(10),o=r(273);function l(e){const{runningTag:t,tagKind:r,currentVersion:n,latestVersion:a,updateAvailable:o,reason:l,fromCache:i,lastSuccessfulCheckAt:s}=e??{};return"offline"===l?i&&s?`Offline — last checked ${function(e){try{const t=new Date(e).getTime(),r=Math.max(0,Math.floor((Date.now()-t)/1e3));if(r<5)return"just now";if(r<60)return`${r}s ago`;const n=Math.floor(r/60);if(n<60)return`${n}m ago`;const a=Math.floor(n/60);return a<24?`${a}h ago`:`${Math.floor(a/24)}d ago`}catch{return e}}(s)}: ${o?"update available":"up to date"}`:"Offline — never checked yet":"newer-version"===l?`Update available: ${n} → ${a}`:"digest-drift"===l?`Image rebuild available for :${t}${a?` (latest stable: ${a})`:""}`:"up-to-date"===l?"floating"===r&&a?`Up to date with :${t} (latest stable: ${a})`:`Up to date (${n||t})`:"older-than-pinned"===l?`Pinned to ${n}; latest stable is ${a}`:"error"===l?`Check error: ${e?.error||"unknown"}`:`State: ${l||"unknown"}`}var i=r(890);function s({children:e}){return n.createElement("div",{style:a.z.sectionTitle},e)}function c({children:e,color:t}){return n.createElement("span",{style:{...a.z.hint,...t?{color:t}:{}}},e)}function d({label:e,hint:t,hintColor:r,children:o}){return n.createElement("div",{style:a.z.fieldRow},n.createElement("span",{style:a.z.label},e),o,null!=t&&""!==t&&n.createElement(c,{color:r},t))}function f({state:e="ok",color:t,title:r,style:o}){return n.createElement("div",{style:{...a.z.stateIndicator,background:t??a.o[e],...o},title:r})}function u({icon:e,iconBackground:t,iconColor:r,title:o,meta:l,state:i="ok",stateTitle:s,link:c,children:d}){const u="error"===i&&!t;return n.createElement("div",{style:a.z.card},n.createElement("div",{style:{...a.z.cardIcon,background:u?"#fef2f2":t??"#3b82f6",color:u?a.o.error:r??"#fff"}},e),n.createElement("div",{style:a.z.cardInfo},n.createElement("div",{style:a.z.cardTitle},o),null!=l&&n.createElement("div",{style:a.z.cardMeta},l)),d,c&&n.createElement("a",{href:c.href,target:"_blank",rel:"noopener noreferrer",style:a.z.link},c.label),n.createElement(f,{state:i,title:s}))}function p({title:e,defaultOpen:t=!1,children:r}){const[o,l]=(0,n.useState)(t);return n.createElement("div",null,n.createElement("button",{type:"button","aria-expanded":o,style:{...a.z.sectionTitle,cursor:"pointer",userSelect:"none",display:"flex",alignItems:"center",gap:6,width:"100%",textAlign:"left",background:"none",border:"none",padding:0},onClick:()=>l(!o)},n.createElement("span",{style:{fontSize:10,transition:"transform 0.15s",transform:o?"rotate(90deg)":"rotate(0deg)"}},"▶"),e),o&&n.createElement("div",{style:{marginBottom:16}},r))}const g={primary:a.z.btnPrimary,secondary:a.z.btnSecondary,warn:a.z.btnWarn,danger:a.z.btnDanger};function b({variant:e="primary",small:t=!1,busy:r=!1,busyLabel:o,disabled:l=!1,onClick:i,title:s,style:c,children:d}){const f=l||r;return n.createElement("button",{type:"button",style:{...a.z.btn,...g[e],...t?a.z.btnSmall:{},...f?a.z.btnDisabled:{},...c},onClick:i,disabled:f,title:s},r?o??d:d)}function m({message:e,error:t=!1,style:r}){return e?n.createElement("div",{style:{...a.z.status,color:t?a.o.error:a.o.ok,marginTop:16,...r}},e):null}const y=[{tag:"latest",label:"latest (recommended)"}];function h({value:e,onChange:t,versions:r,floatingOptions:l=y,stableCount:i,preCount:s,loading:d=!1,error:f,onRefresh:u,disabled:p=!1,style:g}){const m={stableCount:i,preCount:s},{prVersions:h,stableVersions:k,preVersions:x}=(0,o.Gf)(r,m),S=(0,o.US)(e,r,l.map(e=>e.tag),m);return n.createElement(n.Fragment,null,n.createElement("select",{style:{...a.z.select,...g},value:e,onChange:e=>t(e.target.value),disabled:p},l.map(e=>n.createElement("option",{key:e.tag,value:e.tag},e.label??e.tag)),x.map(e=>n.createElement("option",{key:e.tag,value:e.tag},e.tag," (pre-release)")),k.map((e,t)=>n.createElement("option",{key:e.tag,value:e.tag},e.tag,0===t?" (current stable)":"")),h.length>0&&n.createElement("optgroup",{label:"PR test images"},h.map(e=>n.createElement("option",{key:e.tag,value:e.tag},e.tag,e.title?` — ${e.title}`:""))),S&&n.createElement("option",{value:S},S," (running)")),d&&n.createElement(c,null,"loading releases..."),u&&n.createElement(b,{small:!0,style:{padding:"4px 10px",fontSize:11},onClick:u,title:"Refresh available versions"},"↻"),f&&n.createElement(c,{color:a.o.error},f))}function k({checkUrl:e,applyUrl:t,tag:r,onApplied:o,updateLabel:s="Update",disabled:c=!1,style:d}){const f=(0,i.ZA)({checkUrl:e,applyUrl:t}),[u,p]=(0,n.useState)("");return n.createElement("div",{style:{display:"flex",alignItems:"center",gap:10,marginBottom:12,...d}},f.result?.updateAvailable?n.createElement(n.Fragment,null,n.createElement("span",{style:{fontSize:13}},l(f.result)),n.createElement(b,{small:!0,variant:"warn",busy:f.applying,busyLabel:"Updating...",disabled:c||f.checking,onClick:()=>{(async()=>{p("");const e=await f.apply(r);e.ok&&(p(e.tag?`Updated to ${e.tag}.`:"Updated."),o?.(e.tag))})()},title:"Pull the image and recreate the container"},s)):f.result?n.createElement("span",{style:{fontSize:12,color:"#888"}},l(f.result)):n.createElement(b,{small:!0,variant:"secondary",busy:f.checking,busyLabel:"Checking...",disabled:c||f.applying,onClick:()=>{f.check()}},"Check for updates"),u&&n.createElement("span",{style:{fontSize:12,color:a.o.ok}},u),f.error&&n.createElement("span",{style:{fontSize:12,color:a.o.error}},f.error))}},890(e,t,r){r.d(t,{ZA:()=>i,ZV:()=>o,jh:()=>l});var n=r(231),a=r(273);function o(e,t={}){const{intervalMs:r=5e3}=t,[a,o]=(0,n.useState)(null),[l,i]=(0,n.useState)(!0),s=(0,n.useRef)(0),c=(0,n.useRef)(t.fallback??null),d=(0,n.useCallback)(async t=>{const r=++s.current;let n=c.current;try{const r=await fetch(e,{signal:t}),a=await r.json().catch(()=>null);a&&"object"==typeof a&&(n=a)}catch{}r===s.current&&(o(n),i(!1))},[e]);return(0,n.useEffect)(()=>{let e=!1,t=null;const n=new AbortController,a=async()=>{await d(n.signal),!e&&r>0&&(t=setTimeout(a,r))};return a(),()=>{e=!0,n.abort(),t&&clearTimeout(t)}},[d,r]),{status:a,loading:l,refresh:()=>d()}}function l(e){const[t,r]=(0,n.useState)([]),[o,l]=(0,n.useState)(""),[i,s]=(0,n.useState)(!1),c=(0,n.useRef)(0),d=(0,n.useCallback)(async()=>{const t=++c.current;s(!0);try{const n=await fetch(e),o=await n.json().catch(()=>null),i=(0,a.KP)(n.ok,o);if(t!==c.current)return;null!==i.versions&&r(i.versions),l(i.versionsError)}catch{if(t!==c.current)return;l("⚠ Offline — showing last known versions")}s(!1)},[e]);return(0,n.useEffect)(()=>{d()},[d]),{versions:t,versionsError:o,loading:i,refresh:d}}function i(e){const{checkUrl:t,applyUrl:r}=e,[a,o]=(0,n.useState)(!1),[l,i]=(0,n.useState)(!1),[s,c]=(0,n.useState)(null),[d,f]=(0,n.useState)("");return{checking:a,applying:l,result:s,error:d,check:(0,n.useCallback)(async()=>{o(!0),f("");try{const e=await fetch(t),r=await e.json().catch(()=>null);if(e.ok&&r&&"object"==typeof r)c(r);else{const t=r?.error??`HTTP ${e.status}`;f(`Check failed: ${t}`)}}catch(e){f(`Check failed: ${e instanceof Error?e.message:String(e)}`)}o(!1)},[t]),apply:(0,n.useCallback)(async e=>{let t;i(!0),f("");try{const n=await fetch(r,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(e?{tag:e}:{})}),a=await n.json().catch(()=>null);n.ok?(t={ok:!0,tag:a?.tag},c(null)):(t={ok:!1,error:a?.error??`HTTP ${n.status}`},f(`Update failed: ${t.error}`))}catch(e){t={ok:!1,error:e instanceof Error?e.message:String(e)},f(`Update failed: ${t.error}`)}return i(!1),t},[r])}}},10(e,t,r){r.d(t,["o",0,{ok:"#10b981",warn:"#f59e0b",error:"#ef4444"},"z",0,{root:{fontFamily:'-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif',color:"#333",padding:"16px 0"},sectionTitle:{fontSize:13,fontWeight:600,color:"#888",textTransform:"uppercase",letterSpacing:"0.05em",marginBottom:10,marginTop:24},btn:{display:"inline-flex",alignItems:"center",gap:8,padding:"8px 16px",border:"none",borderRadius:6,fontSize:13,fontWeight:600,cursor:"pointer"},btnPrimary:{background:"#3b82f6",color:"#fff"},btnSecondary:{background:"#f1f5f9",color:"#475569",border:"1px solid #e2e8f0"},btnWarn:{background:"#f59e0b",color:"#fff"},btnDanger:{background:"#ef4444",color:"#fff"},btnDisabled:{opacity:.5,cursor:"not-allowed"},btnSmall:{padding:"4px 12px",fontSize:12},status:{marginTop:8,fontSize:12,minHeight:18},card:{display:"flex",alignItems:"center",gap:14,padding:"14px 18px",background:"#f8f9fa",border:"1px solid #e0e0e0",borderRadius:10,marginBottom:12},cardIcon:{width:44,height:44,borderRadius:10,display:"flex",alignItems:"center",justifyContent:"center",fontSize:20,fontWeight:700,flexShrink:0},cardInfo:{flex:1},cardTitle:{fontSize:15,fontWeight:600,color:"#333"},cardMeta:{fontSize:12,color:"#888"},stateIndicator:{width:10,height:10,borderRadius:"50%",flexShrink:0},fieldRow:{display:"flex",alignItems:"center",gap:12,marginBottom:10},label:{fontSize:13,fontWeight:500,color:"#555",width:180,flexShrink:0},select:{padding:"6px 10px",borderRadius:6,border:"1px solid #ccc",fontSize:13,background:"#fff",color:"#333",minWidth:200},input:{padding:"6px 10px",borderRadius:6,border:"1px solid #ccc",fontSize:13,background:"#fff",color:"#333",width:200},inputSmall:{padding:"6px 10px",borderRadius:6,border:"1px solid #ccc",fontSize:13,background:"#fff",color:"#333",width:80},checkbox:{width:16,height:16,accentColor:"#3b82f6"},hint:{fontSize:11,color:"#aaa",marginLeft:8},link:{color:"#3b82f6",textDecoration:"none",fontSize:13,fontWeight:600},textarea:{padding:"6px 10px",borderRadius:6,border:"1px solid #ccc",fontSize:13,fontFamily:"monospace",background:"#fff",color:"#333",width:"100%",minHeight:70,boxSizing:"border-box",resize:"vertical"},empty:{textAlign:"center",padding:"30px 16px",color:"#999",fontSize:13},tag:{display:"inline-block",padding:"2px 8px",borderRadius:4,fontSize:10,fontWeight:600,marginLeft:8},tagPre:{background:"#fef3c7",color:"#92400e"},tagLatest:{background:"#dcfce7",color:"#166534"},warnBanner:{padding:"12px 16px",background:"#fef2f2",border:"1px solid #fecaca",borderRadius:10,marginBottom:12,fontSize:13,color:"#991b1b",lineHeight:1.5},warnBannerTitle:{fontWeight:700,marginBottom:4},infoBanner:{padding:"12px 16px",background:"#fffbeb",border:"1px solid #fde68a",borderRadius:10,marginBottom:12,fontSize:13,color:"#92400e",lineHeight:1.5},bannerCode:{display:"block",marginTop:8,padding:"8px 10px",background:"#fff",border:"1px solid #fecaca",borderRadius:6,fontFamily:"monospace",fontSize:12,color:"#7f1d1d",whiteSpace:"pre-wrap",wordBreak:"break-word"},statsGrid:{display:"grid",gridTemplateColumns:"repeat(auto-fit, minmax(140px, 1fr))",gap:10,marginBottom:12},statCard:{padding:"12px 16px",background:"#f8f9fa",border:"1px solid #e0e0e0",borderRadius:10,textAlign:"center"},statValue:{fontSize:22,fontWeight:700,color:"#333"},statLabel:{fontSize:11,color:"#888",marginTop:2}}])},273(e,t,r){function n(e,t){if(!e)return{versions:null,versionsError:"⚠ Could not reach GitHub — showing last known versions, retry"};const r=t&&"object"==typeof t?t:{},n=Array.isArray(r)?r:Array.isArray(r.versions)?r.versions:[],a=!Array.isArray(r)&&r.sources&&"object"==typeof r.sources?r.sources:{};let o="";return"rate-limited"===a.prImages?o="⚠ GitHub rate-limited — PR test images temporarily unavailable, retry shortly":"rate-limited"===a.releases?o="⚠ GitHub rate-limited — some versions temporarily unavailable, retry shortly":"error"!==a.prImages&&"error"!==a.releases||(o="⚠ Could not fetch some versions from GitHub, retry"),{versions:n,versionsError:o}}function a(e,t={}){const{stableCount:r=5,preCount:n=3}=t,a=e.filter(e=>"number"==typeof e.pr),o=e.filter(e=>"number"!=typeof e.pr);return{prVersions:a,stableVersions:o.filter(e=>!e.prerelease).slice(0,r),preVersions:o.filter(e=>e.prerelease).slice(0,n)}}function o(e,t,r=["latest"],n={}){return e?function(e,t=["latest"],r={}){const{prVersions:n,stableVersions:o,preVersions:l}=a(e,r);return new Set([...t,...l.map(e=>e.tag),...o.map(e=>e.tag),...n.map(e=>e.tag)])}(t,r,n).has(e)?null:e:null}r.d(t,{Gf:()=>a,KP:()=>n,US:()=>o})}};
package/public/967.mjs ADDED
@@ -0,0 +1 @@
1
+ export const __webpack_esm_id__=967;export const __webpack_esm_ids__=[967];export const __webpack_esm_modules__={967(e,t,n){n.r(t),n.d(t,{default:()=>b});var a=n(231),l=n(10),o=n(890),r=n(786);const i="/plugins/signalk-wyoming",s=/^[a-zA-Z0-9_-]+$/,c="local",u=10700,d=10800,m={silenceMs:800,maxUtteranceMs:1e4,minUtteranceMs:300,wakeDedupMs:2e3,pipelineTimeoutMs:3e4,wakeRefractorySeconds:3},p="/run/user/1000/pulse/native",h=[{key:"silenceMs",label:"End-of-utterance silence (ms)",hint:"silence that ends a spoken command"},{key:"maxUtteranceMs",label:"Max utterance (ms)",hint:"hard cap on a single command recording"},{key:"minUtteranceMs",label:"Min utterance (ms)",hint:"shorter recordings are discarded as noise"},{key:"wakeDedupMs",label:"Wake dedup window (ms)",hint:"repeat detections inside the window are ignored"},{key:"pipelineTimeoutMs",label:"Pipeline timeout (ms)",hint:"wake → transcript deadline before the pipeline aborts"},{key:"wakeRefractorySeconds",label:"Wake refractory (s)",hint:"satellite-side cooldown after each detection"}],g=[{key:"asr",label:"Speech-to-text (whisper)",port:10300},{key:"tts",label:"Text-to-speech (piper)",port:10200},{key:"wake",label:"Wake word (openwakeword)",port:10400}];function y(e){const t=e&&"object"==typeof e?e:{};return{id:"string"==typeof t.id?t.id:"",name:"string"==typeof t.name?t.name:"",host:"string"==typeof t.host?t.host:"",port:"number"==typeof t.port?String(t.port):"",wakeWords:Array.isArray(t.wakeWords)?t.wakeWords.filter(e=>"string"==typeof e&&""!==e):[],hasControlApi:!0===t.hasControlApi||void 0!==t.controlPort&&null!==t.controlPort,controlPort:"number"==typeof t.controlPort?String(t.controlPort):""}}function v(e,t){if(""===e.trim())return t;const n=Number(e);return Number.isInteger(n)&&n>=1&&n<=65535?n:NaN}function k({value:e,onChange:t,knownWords:n}){const[o,i]=(0,a.useState)(""),s=[...n,...e.filter(e=>!n.includes(e))],c=()=>{const n=o.trim();i(""),""===n||e.includes(n)||t([...e,n])};return a.createElement("div",{style:{display:"flex",flexWrap:"wrap",alignItems:"center",gap:"6px 16px"}},s.map(n=>a.createElement("label",{key:n,style:{display:"inline-flex",alignItems:"center",gap:6,fontSize:13}},a.createElement("input",{style:l.z.checkbox,type:"checkbox",checked:e.includes(n),onChange:()=>(n=>{t(e.includes(n)?e.filter(e=>e!==n):[...e,n])})(n)}),n)),a.createElement("span",{style:{display:"inline-flex",alignItems:"center",gap:6}},a.createElement("input",{style:{...l.z.input,width:140},value:o,onChange:e=>i(e.target.value),onKeyDown:e=>{"Enter"===e.key&&(e.preventDefault(),c())},placeholder:"model_name"}),a.createElement(r.$n,{variant:"secondary",small:!0,onClick:c},"Add")))}function f({sat:e,live:t,knownWords:n,onChange:o,onRemove:i}){const s=t=>o({...e,...t});return a.createElement("div",{style:{border:"1px solid #e2e8f0",borderRadius:8,padding:"10px 12px",marginBottom:10}},a.createElement("div",{style:{display:"flex",alignItems:"center",gap:8,marginBottom:8}},null!==t&&a.createElement(r.LB,{state:t.connected?"ok":"error",title:t.state}),a.createElement("span",{style:{fontSize:13,fontWeight:600,flex:1}},e.name||e.id||"new satellite",null!==t&&a.createElement("span",{style:{color:"#888",fontWeight:400}}," ","— ",t.state)),a.createElement(r.$n,{variant:"danger",small:!0,onClick:i},"Remove")),a.createElement(r.RU,{label:"Id",hint:"letters/digits/_/- only; becomes voice.satellites.<id>"},a.createElement("input",{style:{...l.z.input,width:140},value:e.id,onChange:e=>s({id:e.target.value}),placeholder:"cockpit"})),a.createElement(r.RU,{label:"Name",hint:"display name; defaults to the id"},a.createElement("input",{style:{...l.z.input,width:180},value:e.name,onChange:e=>s({name:e.target.value})})),a.createElement(r.RU,{label:"Host"},a.createElement("input",{style:{...l.z.input,width:180},value:e.host,onChange:e=>s({host:e.target.value}),placeholder:"192.168.1.50"})),a.createElement(r.RU,{label:"Port"},a.createElement("input",{style:{...l.z.input,width:90},type:"number",value:e.port,onChange:e=>s({port:e.target.value}),placeholder:String(u)})),a.createElement(r.RU,{label:"Wake words",hint:"leave empty for announce-only satellites"},a.createElement(k,{value:e.wakeWords,onChange:e=>s({wakeWords:e}),knownWords:n})),a.createElement(r.RU,{label:"Runs our satellite image",hint:"unlocks the webapp Audio screen, record/play tests and record-and-transcribe"},a.createElement("input",{style:l.z.checkbox,type:"checkbox",checked:e.hasControlApi,onChange:e=>s({hasControlApi:e.target.checked})}),e.hasControlApi&&a.createElement("span",{style:{display:"inline-flex",alignItems:"center",gap:6}},a.createElement("span",{style:{fontSize:13,color:"#555"}},"Control port"),a.createElement("input",{style:{...l.z.input,width:90},type:"number",value:e.controlPort,onChange:e=>s({controlPort:e.target.value}),placeholder:String(d)}))))}function b({configuration:e,save:t}){const n=e||{},b=n.localSatellite&&"object"==typeof n.localSatellite?n.localSatellite:{},w=n.services&&"object"==typeof n.services?n.services:{},E=n.defaults&&"object"==typeof n.defaults?n.defaults:{},S=n.advanced&&"object"==typeof n.advanced?n.advanced:{},[C,x]=(0,a.useState)(()=>(Array.isArray(n.satellites)?n.satellites:[]).map(y)),[A,$]=(0,a.useState)(()=>({enabled:!0===b.enabled,micDevice:"string"==typeof b.micDevice&&""!==b.micDevice?b.micDevice:"auto",sndDevice:"string"==typeof b.sndDevice&&""!==b.sndDevice?b.sndDevice:"auto",wakeWords:Array.isArray(b.wakeWords)?b.wakeWords.filter(e=>"string"==typeof e&&""!==e):[],audioMode:"pulse-socket"===b.audioMode?"pulse-socket":"alsa",feedbackSounds:!1!==b.feedbackSounds,hostPulseSocket:"string"==typeof b.hostPulseSocket&&""!==b.hostPulseSocket?b.hostPulseSocket:p,noiseSuppression:"number"==typeof b.noiseSuppression?String(b.noiseSuppression):"",autoGain:"number"==typeof b.autoGain?String(b.autoGain):"",micVolume:"number"==typeof b.micVolume?String(b.micVolume):"",tag:"string"==typeof b.tag&&""!==b.tag?b.tag:"auto"})),[W,z]=(0,a.useState)(()=>({asr:"string"==typeof w.asr?w.asr:"auto",tts:"string"==typeof w.tts?w.tts:"auto",wake:"string"==typeof w.wake?w.wake:"auto"})),[R,_]=(0,a.useState)("string"==typeof E.language&&""!==E.language?E.language:"en"),[U,M]=(0,a.useState)("string"==typeof E.voice?E.voice:""),[D,N]=(0,a.useState)(()=>{const e={};for(const{key:t}of h)e[t]="number"==typeof S[t]?String(S[t]):String(m[t]);return e}),[P,V]=(0,a.useState)(""),[T,j]=(0,a.useState)(!1),I=(0,o.ZV)(`${i}/api/services`,{fallback:null}),G=(0,o.ZV)(`${i}/api/satellites`,{fallback:null}),L=(0,o.jh)(`${i}/api/versions`),B=I.status&&"object"==typeof I.status&&!Array.isArray(I.status)&&void 0!==I.status.tts?I.status:null,F=Array.isArray(G.status)?G.status:null,H=null!==B,K=null!==B&&"ready"===B.tts?.status,[Z,J]=(0,a.useState)(null);(0,a.useEffect)(()=>{if(!K)return;let e=!1;return(async()=>{try{const t=await fetch(`${i}/api/voices`,{credentials:"include"});if(!t.ok)return;const n=await t.json();!e&&Array.isArray(n)&&J(n.filter(e=>e&&"string"==typeof e.name))}catch{}})(),()=>{e=!0}},[K]);const O=null!==B&&Array.isArray(B.wake?.models)?B.wake.models.filter(e=>"string"==typeof e&&""!==e):[],q=null===F?0:F.filter(e=>e&&!0===e.connected).length,Q=I.loading?"Checking...":H?`${q}/${null===F?0:F.length} satellites connected; `+g.map(({key:e})=>`${e}: ${B[e]?.status??"—"}`).join(", "):"Not running",X=null===F?null:F.find(e=>e&&e.id===c)??null,Y=null!==Z&&(""===U||Z.some(e=>e.name===U)),ee=""!==U&&function(e){return e.endsWith("-low")||e.endsWith("-x_low")}(U);return a.createElement("div",{style:l.z.root},a.createElement(r._x,null,"Voice orchestrator status"),a.createElement(r.JK,{icon:"V",iconBackground:H?"#7c3aed":void 0,title:"Wyoming voice orchestrator",meta:Q,state:H?"ok":"error",stateTitle:H?"running":"not running",link:H?{href:"/signalk-wyoming",label:"Open webapp ↗"}:void 0}),a.createElement(r._x,null,"Remote satellites"),0===C.length&&a.createElement("div",{style:{...l.z.empty,padding:"8px 0",textAlign:"left"}},"No remote satellites — the local satellite below covers a mic/speaker on the server box itself."),C.map((e,t)=>a.createElement(f,{key:t,sat:e,live:null===F?null:F.find(t=>t&&t.id===e.id)??null,knownWords:O,onChange:e=>x(n=>n.map((n,a)=>a===t?e:n)),onRemove:()=>x(e=>e.filter((e,n)=>n!==t))})),a.createElement(r.$n,{variant:"secondary",onClick:()=>x(e=>[...e,{id:"",name:"",host:"",port:"",wakeWords:[],hasControlApi:!1,controlPort:""}])},"Add satellite"),a.createElement(r._x,null,"Local satellite (mic/speaker on this server)"),a.createElement(r.RU,{label:"Enabled",hint:"runs ghcr.io/hoeken/wyoming-satellite in a container on this box"},a.createElement("input",{style:l.z.checkbox,type:"checkbox",checked:A.enabled,onChange:e=>$({...A,enabled:e.target.checked})})),A.enabled&&a.createElement(a.Fragment,null,null!==X&&a.createElement(r.JK,{icon:"S",iconBackground:X.connected?"#7c3aed":void 0,title:"Local satellite container",meta:X.connected?`connected at ${X.host}:${X.port} — ${X.state}`:`not connected — ${X.state}`,state:X.connected?"ok":"warn",stateTitle:X.state}),null!==X&&a.createElement(r._j,{checkUrl:`${i}/api/update/check`,applyUrl:`${i}/api/update/apply`,tag:A.tag,onApplied:()=>{G.refresh()}}),a.createElement(r.RU,{label:"Microphone device",hint:"ALSA device string (see the webapp Audio screen); 'auto' = image default, 'none' = no microphone"},a.createElement("input",{style:{...l.z.input,width:180},value:A.micDevice,onChange:e=>$({...A,micDevice:e.target.value}),placeholder:"auto"})),a.createElement(r.RU,{label:"Speaker device",hint:"ALSA device string; 'auto' = image default"},a.createElement("input",{style:{...l.z.input,width:180},value:A.sndDevice,onChange:e=>$({...A,sndDevice:e.target.value}),placeholder:"auto"})),a.createElement(r.RU,{label:"Wake words",hint:"openWakeWord model names"},a.createElement(k,{value:A.wakeWords,onChange:e=>$({...A,wakeWords:e}),knownWords:O})),a.createElement(r.RU,{label:"Audio mode",hint:"pulse-socket"===A.audioMode?"mounts the host sound-server socket (desktop hosts)":"/dev/snd passthrough (headless hosts)"},a.createElement("select",{style:l.z.select,value:A.audioMode,onChange:e=>$({...A,audioMode:e.target.value})},a.createElement("option",{value:"alsa"},"alsa"),a.createElement("option",{value:"pulse-socket"},"pulse-socket"))),"pulse-socket"===A.audioMode&&a.createElement(r.RU,{label:"Host pulse socket",hint:"sound-server socket path on the host"},a.createElement("input",{style:{...l.z.input,width:260},value:A.hostPulseSocket,onChange:e=>$({...A,hostPulseSocket:e.target.value}),placeholder:p})),a.createElement(r.RU,{label:"Feedback sounds",hint:"play awake/done sounds on wake word interactions"},a.createElement("input",{style:l.z.checkbox,type:"checkbox",checked:A.feedbackSounds,onChange:e=>$({...A,feedbackSounds:e.target.checked})})),a.createElement(r.RU,{label:"Image version"},a.createElement(r.t7,{value:A.tag,onChange:e=>$({...A,tag:e}),versions:L.versions,floatingOptions:[{tag:"auto",label:"auto (pinned release, recommended)"}],loading:L.loading,error:L.versionsError,onRefresh:L.refresh})),a.createElement(r.iV,{title:"Audio tuning"},a.createElement(r.RU,{label:"Noise suppression",hint:"webrtc level 0-4; empty = image default"},a.createElement("input",{style:{...l.z.input,width:90},type:"number",min:"0",max:"4",step:"1",value:A.noiseSuppression,onChange:e=>$({...A,noiseSuppression:e.target.value})})),a.createElement(r.RU,{label:"Auto gain",hint:"0-31 dbFS; empty = image default"},a.createElement("input",{style:{...l.z.input,width:90},type:"number",min:"0",max:"31",step:"1",value:A.autoGain,onChange:e=>$({...A,autoGain:e.target.value})})),a.createElement(r.RU,{label:"Mic volume",hint:"multiplier; empty = image default"},a.createElement("input",{style:{...l.z.input,width:90},type:"number",step:"0.1",value:A.micVolume,onChange:e=>$({...A,micVolume:e.target.value})})))),a.createElement(r._x,null,"Services"),g.map(({key:e,label:t,port:n})=>{const o=null===B?null:B[e]??null,i=W[e],s=""===i.trim()||"auto"===i.trim();return a.createElement(r.RU,{key:e,label:t,hint:s?null!==o&&null!==o.uri?`discovered: ${o.uri} (${o.status})`:`'auto' discovers the sibling plugin; or a manual tcp://host:${n} URI`:"manual override — 'auto' discovers the sibling plugin"},null!==o&&a.createElement(r.LB,{state:"ready"===o.status?"ok":"starting"===o.status?"warn":"error",title:o.status??"not discovered"}),a.createElement("input",{style:{...l.z.input,width:220},value:i,onChange:t=>z(n=>({...n,[e]:t.target.value})),placeholder:"auto"}))}),a.createElement(r._x,null,"Defaults"),a.createElement(r.RU,{label:"Language",hint:"spoken language code, e.g. en, de, fr"},a.createElement("input",{style:{...l.z.input,width:90},value:R,onChange:e=>_(e.target.value),placeholder:"en"})),a.createElement(r.RU,{label:"Voice",hint:ee?`${U} is a 16 kHz voice — use -medium or -high (22.05 kHz)`:"default piper voice (22.05 kHz voices only); empty = the TTS service's configured voice",hintColor:ee?l.o.warn:void 0},null!==Z&&Z.length>0?a.createElement("select",{style:l.z.select,value:U,onChange:e=>M(e.target.value)},a.createElement("option",{value:""},"TTS service default"),Z.map(e=>a.createElement("option",{key:e.name,value:e.name},e.name)),!Y&&a.createElement("option",{value:U},U," (saved)")):a.createElement("input",{style:{...l.z.input,width:220},value:U,onChange:e=>M(e.target.value),placeholder:"TTS service default"})),a.createElement(r.iV,{title:"Advanced"},h.map(({key:e,label:t,hint:n})=>a.createElement(r.RU,{key:e,label:t,hint:n},a.createElement("input",{style:{...l.z.input,width:90},type:"number",value:D[e],onChange:t=>((e,t)=>N(n=>({...n,[e]:t})))(e,t.target.value),placeholder:String(m[e])})))),a.createElement("div",{style:{marginTop:24}},a.createElement(r.$n,{onClick:()=>{const e=(()=>{const e=new Set;for(const t of C){const n=""!==t.id?`"${t.id}"`:"a satellite";if(""===t.id.trim())return"every satellite needs an id";if(!s.test(t.id))return`satellite id "${t.id}" must match ^[a-zA-Z0-9_-]+$`;if(e.has(t.id))return`duplicate satellite id "${t.id}"`;if(e.add(t.id),""===t.host.trim())return`satellite ${n} needs a host`;if(Number.isNaN(v(t.port,u)))return`satellite ${n}: port must be an integer 1-65535`;if(t.hasControlApi&&Number.isNaN(v(t.controlPort,d)))return`satellite ${n}: control port must be an integer 1-65535`}if(A.enabled&&e.has(c))return`satellite id "${c}" is reserved for the local satellite`;for(const e of["noiseSuppression","autoGain","micVolume"])if(""!==A[e]&&!Number.isFinite(Number(A[e])))return`local satellite: ${e} must be a number`;for(const{key:e,label:t}of h){const n=Number(D[e]);if(""!==D[e]&&(!Number.isFinite(n)||n<=0))return`${t} must be a number > 0`}return null})();if(null!==e)return j(!0),void V(`Not saved: ${e}`);const a=C.map(e=>{const t={id:e.id.trim(),host:e.host.trim(),port:v(e.port,u),wakeWords:e.wakeWords};return""!==e.name.trim()&&(t.name=e.name.trim()),e.hasControlApi&&(t.hasControlApi=!0,t.controlPort=v(e.controlPort,d)),t}),l={enabled:A.enabled,micDevice:A.micDevice.trim()||"auto",sndDevice:A.sndDevice.trim()||"auto",wakeWords:A.wakeWords,audioMode:A.audioMode,feedbackSounds:A.feedbackSounds,hostPulseSocket:A.hostPulseSocket.trim()||p,tag:A.tag};for(const e of["noiseSuppression","autoGain","micVolume"])""!==A[e]&&(l[e]=Number(A[e]));const o={};for(const{key:e}of h)o[e]=""===D[e]?m[e]:Number(D[e]);t({...n,satellites:a,localSatellite:l,services:{asr:W.asr.trim()||"auto",tts:W.tts.trim()||"auto",wake:W.wake.trim()||"auto"},defaults:{language:R.trim()||"en",voice:U},advanced:o}),j(!1),V("Saved. Signal K restarts the plugin with the new configuration.")}},"Save Configuration")),a.createElement(r.VI,{message:P,error:T}))}}};
@@ -0,0 +1 @@
1
+ var e={980(){}};const t={};function o(r){const s=t[r];if(void 0!==s)return s.exports;const n=t[r]={exports:{}};return e[r](n,n.exports,o),n.exports}o.m=e,o.c=t,o.f={},o.e=e=>Promise.all(Object.keys(o.f).reduce((t,r)=>(o.f[r](e,t),t),[])),o.u=e=>e+".mjs",o.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),(()=>{o.S={};const e={},t={};o.I=(r,s)=>{s||(s=[]);let n=t[r];if(n||(n=t[r]={}),s.indexOf(n)>=0)return;if(s.push(n),e[r])return e[r];o.o(o.S,r)||(o.S[r]={});const i=o.S[r],c="signalk-wyoming",_=[];return"default"===r&&((e,t,r,s)=>{const n=i[e]=i[e]||{},_=n[t];(!_||!_.loaded&&(1!=!_.eager?s:c>_.from))&&(n[t]={get:()=>o.e(540).then(()=>()=>o(540)),from:c,eager:!1})})("react","19.2.8"),e[r]=_.length?Promise.all(_).then(()=>e[r]=1):1}})(),(()=>{const e={792:0},t=t=>{let{__webpack_esm_ids__:r,__webpack_esm_modules__:s,__webpack_esm_runtime__:n}=t;var i,c,_=0;for(i in s)o.o(s,i)&&(o.m[i]=s[i]);for(n&&n(o);_<r.length;_++)c=r[_],o.o(e,c)&&e[c]&&e[c][0](),e[r[_]]=0};o.f.j=(r,s)=>{let n=o.o(e,r)?e[r]:void 0;if(0!==n)if(n)s.push(n[1]);else{let i=import("./"+o.u(r)).then(t,t=>{throw 0!==e[r]&&(e[r]=void 0),t});i=Promise.race([i,new Promise(t=>n=e[r]=[t])]),s.push(n[1]=i)}}})(),o(980);
@@ -0,0 +1 @@
1
+ var e={623(e,r,t){const n={"./PluginConfigurationPanel":()=>Promise.all([t.e(786),t.e(967)]).then(()=>()=>t(967))},o=(e,r)=>(t.R=r,r=t.o(n,e)?n[e]():Promise.resolve().then(()=>{throw new Error('Module "'+e+'" does not exist in container.')}),t.R=void 0,r),i=(e,r)=>{if(!t.S)return;const n="default",o=t.S[n];if(o&&o!==e)throw new Error("Container initialization failed as it has already been initialized with a different share scope");return t.S[n]=e,t.I(n,r)};t.d(r,{get:()=>o,init:()=>i})}};const r={};function t(n){const o=r[n];if(void 0!==o)return o.exports;const i=r[n]={exports:{}};return e[n](i,i.exports,t),i.exports}t.m=e,t.c=r,t.d=(e,r)=>{if(Array.isArray(r))for(var n=0;n<r.length;){var o=r[n++],i=r[n++];t.o(e,o)?0===i&&n++:0===i?Object.defineProperty(e,o,{enumerable:!0,value:r[n++]}):Object.defineProperty(e,o,{enumerable:!0,get:i})}else for(var o in r)t.o(r,o)&&!t.o(e,o)&&Object.defineProperty(e,o,{enumerable:!0,get:r[o]})},t.f={},t.e=e=>Promise.all(Object.keys(t.f).reduce((r,n)=>(t.f[n](e,r),r),[])),t.u=e=>e+".mjs",t.o=(e,r)=>Object.prototype.hasOwnProperty.call(e,r),t.r=e=>{Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},(()=>{t.S={};const e={},r={};t.I=(n,o)=>{o||(o=[]);let i=r[n];if(i||(i=r[n]={}),o.indexOf(i)>=0)return;if(o.push(i),e[n])return e[n];t.o(t.S,n)||(t.S[n]={});const s=t.S[n],a="signalk-wyoming",u=[];return"default"===n&&((e,r,n,o)=>{const i=s[e]=s[e]||{},u=i[r];(!u||!u.loaded&&(1!=!u.eager?o:a>u.from))&&(i[r]={get:()=>t.e(540).then(()=>()=>t(540)),from:a,eager:!1})})("react","19.2.8"),e[n]=u.length?Promise.all(u).then(()=>e[n]=1):1}})(),(()=>{var e=e=>{var r=e=>e.split(".").map(e=>+e==e?+e:e),t=/^([^-+]+)?(?:-([^+]+))?(?:\+(.+))?$/.exec(e),n=t[1]?r(t[1]):[];return t[2]&&(n.length++,n.push.apply(n,r(t[2]))),t[3]&&(n.push([]),n.push.apply(n,r(t[3]))),n},r=e=>{var t=e[0],n="";if(1===e.length)return"*";if(t+.5){n+=0==t?">=":-1==t?"<":1==t?"^":2==t?"~":t>0?"=":"!=";for(var o=1,i=1;i<e.length;i++)o--,n+="u"==(typeof(a=e[i]))[0]?"-":(o>0?".":"")+(o=2,a);return n}var s=[];for(i=1;i<e.length;i++){var a=e[i];s.push(0===a?"not("+u()+")":1===a?"("+u()+" || "+u()+")":2===a?s.pop()+" "+s.pop():r(a))}return u();function u(){return s.pop().replace(/^\((.+)\)$/,"$1")}},n=(r,t)=>{if(0 in r){t=e(t);var o=r[0],i=o<0;i&&(o=-o-1);for(var s=0,a=1,u=!0;;a++,s++){var f,l,c=a<r.length?(typeof r[a])[0]:"";if(s>=t.length||"o"==(l=(typeof(f=t[s]))[0]))return!u||("u"==c?a>o&&!i:""==c!=i);if("u"==l){if(!u||"u"!=c)return!1}else if(u)if(c==l)if(a<=o){if(f!=r[a])return!1}else{if(i?f>r[a]:f<r[a])return!1;f!=r[a]&&(u=!1)}else if("s"!=c&&"n"!=c){if(i||a<=o)return!1;u=!1,a--}else{if(a<=o||l<c!=i)return!1;u=!1}else"s"!=c&&"n"!=c&&(u=!1,a--)}}var p=[],d=p.pop.bind(p);for(s=1;s<r.length;s++){var h=r[s];p.push(1==h?d()|d():2==h?d()&d():h?n(h,t):!d())}return!!d()};const o=(r,t,n)=>{const o=n?(e=>Object.keys(e).reduce((r,t)=>(e[t].eager&&(r[t]=e[t]),r),{}))(r[t]):r[t];return Object.keys(o).reduce((r,t)=>!r||!o[r].loaded&&((r,t)=>{r=e(r),t=e(t);for(var n=0;;){if(n>=r.length)return n<t.length&&"u"!=(typeof t[n])[0];var o=r[n],i=(typeof o)[0];if(n>=t.length)return"u"==i;var s=t[n],a=(typeof s)[0];if(i!=a)return"o"==i&&"n"==a||"s"==a||"u"==i;if("o"!=i&&"u"!=i&&o!=s)return o<s;n++}})(r,t)?t:r,0)},i=(e,r,t)=>t?t():((e,r)=>(e=>{throw new Error(e)})("Shared module "+r+" doesn't exist in shared scope "+e))(e,r),s=(e=>function(r,n,o,i,s){const a=t.I(r);return a?.then&&!o?a.then(e.bind(e,r,t.S[r],n,!1,i,s)):e(r,t.S[r],n,o,i,s)})((e,s,a,u,f,l)=>{if(!((e,r)=>e&&t.o(e,r))(s,a))return i(e,a,l);const c=o(s,a,u);return n(f,c)||(d=((e,t,n,o)=>"Unsatisfied version "+n+" from "+(n&&e[t][n].from)+" of shared singleton module "+t+" (required "+r(o)+")")(s,a,c,f),"undefined"!=typeof console&&console.warn&&console.warn(d)),(p=s[a][c]).loaded=1,p.get();var p,d}),a={},u={231:()=>s("default","react",!1,[1,19],()=>t.e(540).then(()=>()=>t(540)))},f={967:[231]},l={};t.f.consumes=(e,r)=>{t.o(f,e)&&f[e].forEach(e=>{if(t.o(a,e))return r.push(a[e]);if(!l[e]){const n=r=>{a[e]=0,t.m[e]=n=>{delete t.c[e],n.exports=r()}};l[e]=!0;const o=r=>{delete a[e],t.m[e]=n=>{throw delete t.c[e],r}};try{const t=u[e]();t.then?r.push(a[e]=t.then(n).catch(o)):n(t)}catch(e){o(e)}}})}})(),(()=>{const e={675:0},r=r=>{let{__webpack_esm_ids__:n,__webpack_esm_modules__:o,__webpack_esm_runtime__:i}=r;var s,a,u=0;for(s in o)t.o(o,s)&&(t.m[s]=o[s]);for(i&&i(t);u<n.length;u++)a=n[u],t.o(e,a)&&e[a]&&e[a][0](),e[n[u]]=0};t.f.j=(n,o)=>{let i=t.o(e,n)?e[n]:void 0;if(0!==i)if(i)o.push(i[1]);else{let s=import("./"+t.u(n)).then(r,r=>{throw 0!==e[n]&&(e[n]=void 0),r});s=Promise.race([s,new Promise(r=>i=e[n]=[r])]),o.push(i[1]=s)}}})();let n=t(623);const o=n.get,i=n.init;export{o as get,i as init};