From 284b1bdf1c90ac50d803bb0a72af25cd730a1afb Mon Sep 17 00:00:00 2001
From: Claude
Date: Sun, 27 Sep 2026 01:07:48 +0000
Subject: [PATCH] Name Print Screen, Menu and media keys as the backends do;
repair more legacy names
The recorders named any key without a rule after its DOM code, so Print
Screen was saved as KEY_PRINTSCREEN, the Menu key as KEY_CONTEXTMENU and
Mute as KEY_AUDIOVOLUMEMUTE. No backend reports those names, so such a
shortcut could never fire. They now map to KEY_SYSRQ, KEY_COMPOSE and the
evdev media names, with readable keycap labels.
Loading now also repairs those DOM names, KEY_NUMPADENTER, and letters the
old TTS stop key recorder saved without the underscore (KEYV -> KEY_V), in
both the stop key and bindings.toml. KEY_* stays as it is: it could be the
keypad * or Shift+8.
The portal translates every key in keymap::NAMES now (Print, Menu, Pause,
Num/Scroll Lock, the ISO 102nd key and the media keys), and two new tests
keep the three sides in step: the recorder's output is checked against
keymap::NAMES, and every name there must have a portal keysym.
Co-Authored-By: Claude Opus 5.5
Claude-Session: https://claude.ai/code/session_015v84hAqhDBdwy7Q49gAWBR
---
crates/voxctrl-config/src/migrate.rs | 32 +++++-
crates/voxctrl-config/src/store.rs | 5 +-
crates/voxctrl-config/src/tests.rs | 18 +++
crates/voxctrl-hotkeys/src/trigger.rs | 37 ++++++
.../{index-ywDg7bM0.js => index-lCQNFkWj.js} | 108 +++++++++---------
dist/index.html | 2 +-
src/lib/Wizard/wizard-data.ts | 10 ++
src/lib/keys.ts | 16 +++
tests/svelte/keys.test.ts | 85 ++++++++++++++
9 files changed, 254 insertions(+), 59 deletions(-)
rename dist/assets/{index-ywDg7bM0.js => index-lCQNFkWj.js} (70%)
create mode 100644 tests/svelte/keys.test.ts
diff --git a/crates/voxctrl-config/src/migrate.rs b/crates/voxctrl-config/src/migrate.rs
index ea147b3..ae7abce 100644
--- a/crates/voxctrl-config/src/migrate.rs
+++ b/crates/voxctrl-config/src/migrate.rs
@@ -59,8 +59,13 @@ pub(crate) fn migrate_cloned_voices_dir() {
/// could never fire. The unshifted and shifted characters of a US layout are
/// both mapped, since Shift changes the character typed on the same key.
///
+/// - Keys whose DOM name differs from evdev's were saved under the DOM name
+/// (`KEY_PRINTSCREEN`, `KEY_AUDIOVOLUMEMUTE`, `KEY_NUMPADENTER`).
+/// - The TTS stop key recorder saved letters without the underscore (`KEYV`).
+///
/// Numpad digits were saved as the top-row digit (`KEY_1`), which is a real
-/// key name, so those cannot be told apart and are left alone.
+/// key name, so those cannot be told apart and are left alone. So is `KEY_*`,
+/// which could be the keypad `*` or Shift+8.
pub fn canonical_key_name(name: &str) -> Option<&'static str> {
Some(match name {
"KEY_ESCAPE" => "KEY_ESC",
@@ -75,10 +80,33 @@ pub fn canonical_key_name(name: &str) -> Option<&'static str> {
"KEY_[" | "KEY_{" => "KEY_LEFTBRACE",
"KEY_]" | "KEY_}" => "KEY_RIGHTBRACE",
"KEY_\\" | "KEY_|" => "KEY_BACKSLASH",
- _ => return None,
+ "KEY_PRINTSCREEN" => "KEY_SYSRQ",
+ "KEY_CONTEXTMENU" => "KEY_COMPOSE",
+ "KEY_NUMPADENTER" => "KEY_KPENTER",
+ "KEY_AUDIOVOLUMEMUTE" => "KEY_MUTE",
+ "KEY_AUDIOVOLUMEDOWN" => "KEY_VOLUMEDOWN",
+ "KEY_AUDIOVOLUMEUP" => "KEY_VOLUMEUP",
+ "KEY_MEDIATRACKNEXT" => "KEY_NEXTSONG",
+ "KEY_MEDIATRACKPREVIOUS" => "KEY_PREVIOUSSONG",
+ "KEY_MEDIASTOP" => "KEY_STOPCD",
+ "KEY_MEDIAPLAYPAUSE" => "KEY_PLAYPAUSE",
+ _ => return legacy_letter(name),
})
}
+/// `KEYA` … `KEYZ`, as the old TTS stop key recorder wrote letters.
+fn legacy_letter(name: &str) -> Option<&'static str> {
+ const LETTERS: [&str; 26] = [
+ "KEY_A", "KEY_B", "KEY_C", "KEY_D", "KEY_E", "KEY_F", "KEY_G", "KEY_H", "KEY_I", "KEY_J",
+ "KEY_K", "KEY_L", "KEY_M", "KEY_N", "KEY_O", "KEY_P", "KEY_Q", "KEY_R", "KEY_S", "KEY_T",
+ "KEY_U", "KEY_V", "KEY_W", "KEY_X", "KEY_Y", "KEY_Z",
+ ];
+ match name.strip_prefix("KEY")?.as_bytes() {
+ [c @ b'A'..=b'Z'] => Some(LETTERS[usize::from(c - b'A')]),
+ _ => None,
+ }
+}
+
/// Rewrite every legacy key name in `keys` to its canonical spelling,
/// returning whether anything changed.
pub fn canonicalize_key_names(keys: &mut [String]) -> bool {
diff --git a/crates/voxctrl-config/src/store.rs b/crates/voxctrl-config/src/store.rs
index f63a447..1be49ae 100644
--- a/crates/voxctrl-config/src/store.rs
+++ b/crates/voxctrl-config/src/store.rs
@@ -96,8 +96,9 @@ impl Config {
migrated = true;
}
- // Legacy key names in the stop key ("KEY_ESCAPE", or a punctuation key
- // saved as e.g. "KEY_.") → the evdev names the backends report.
+ // Legacy key names in the stop key ("KEY_ESCAPE", a punctuation key
+ // saved as e.g. "KEY_.", a letter saved as "KEYV") → the evdev names
+ // the backends report. See `canonical_key_name`.
migrated |= canonicalize_key_names(&mut data.tts.stop_key);
// Migrate legacy default OpenAI timeout (8s) to the new default (30s) to prevent timeouts
diff --git a/crates/voxctrl-config/src/tests.rs b/crates/voxctrl-config/src/tests.rs
index 3cc9376..e72a510 100644
--- a/crates/voxctrl-config/src/tests.rs
+++ b/crates/voxctrl-config/src/tests.rs
@@ -590,3 +590,21 @@ fn legacy_key_names_become_the_names_the_backends_report() {
assert_eq!(keys, vec!["KEY_LEFTCTRL", "KEY_SLASH"]);
assert!(!canonicalize_key_names(&mut keys), "a second pass changes nothing");
}
+
+#[test]
+fn legacy_dom_names_and_underscoreless_letters_are_repaired() {
+ assert_eq!(canonical_key_name("KEYV"), Some("KEY_V"), "old TTS stop key letter");
+ assert_eq!(canonical_key_name("KEYA"), Some("KEY_A"));
+ assert_eq!(canonical_key_name("KEYZ"), Some("KEY_Z"));
+ assert_eq!(canonical_key_name("KEY_PRINTSCREEN"), Some("KEY_SYSRQ"));
+ assert_eq!(canonical_key_name("KEY_CONTEXTMENU"), Some("KEY_COMPOSE"));
+ assert_eq!(canonical_key_name("KEY_NUMPADENTER"), Some("KEY_KPENTER"));
+ assert_eq!(canonical_key_name("KEY_AUDIOVOLUMEMUTE"), Some("KEY_MUTE"));
+ assert_eq!(canonical_key_name("KEY_MEDIAPLAYPAUSE"), Some("KEY_PLAYPAUSE"));
+
+ // Real names that happen to start with KEY and one letter are untouched.
+ for name in ["KEY_A", "KEY_KP1", "KEY_F5", "KEYBOARD", "KEY"] {
+ assert_eq!(canonical_key_name(name), None, "{name}");
+ }
+ assert_eq!(canonical_key_name("KEY_*"), None, "keypad * or Shift+8: ambiguous");
+}
diff --git a/crates/voxctrl-hotkeys/src/trigger.rs b/crates/voxctrl-hotkeys/src/trigger.rs
index 1b8d72c..278ae45 100644
--- a/crates/voxctrl-hotkeys/src/trigger.rs
+++ b/crates/voxctrl-hotkeys/src/trigger.rs
@@ -150,6 +150,20 @@ fn keysym_name(key: &str) -> Option {
"LEFTBRACE" => "bracketleft".to_string(),
"RIGHTBRACE" => "bracketright".to_string(),
"CAPSLOCK" => "Caps_Lock".to_string(),
+ "NUMLOCK" => "Num_Lock".to_string(),
+ "SCROLLLOCK" => "Scroll_Lock".to_string(),
+ "PAUSE" => "Pause".to_string(),
+ "SYSRQ" => "Print".to_string(),
+ "COMPOSE" => "Menu".to_string(),
+ // The extra ISO key beside left Shift; `less` on a US-based layout.
+ "102ND" => "less".to_string(),
+ "MUTE" => "XF86AudioMute".to_string(),
+ "VOLUMEDOWN" => "XF86AudioLowerVolume".to_string(),
+ "VOLUMEUP" => "XF86AudioRaiseVolume".to_string(),
+ "NEXTSONG" => "XF86AudioNext".to_string(),
+ "PREVIOUSSONG" => "XF86AudioPrev".to_string(),
+ "STOPCD" => "XF86AudioStop".to_string(),
+ "PLAYPAUSE" => "XF86AudioPlay".to_string(),
"KPPLUS" => "KP_Add".to_string(),
"KPMINUS" => "KP_Subtract".to_string(),
"KPASTERISK" => "KP_Multiply".to_string(),
@@ -360,6 +374,29 @@ mod tests {
}
}
+ /// Every key the other backends can match must register through the portal
+ /// too, or a shortcut that works under evdev is refused in portal mode.
+ /// `keymap::NAMES` is also the vocabulary the Settings recorder is checked
+ /// against (`tests/svelte/keys.test.ts`), so this covers every key a user
+ /// can record.
+ #[test]
+ fn every_backend_key_translates_to_a_keysym() {
+ let untranslated: Vec<&str> = crate::win_keys::keymap::NAMES
+ .iter()
+ .copied()
+ .filter(|k| modifier_name(k).is_none() && keysym_name(k).is_none())
+ .collect();
+ assert_eq!(untranslated, Vec::<&str>::new());
+ for (key, sym) in [
+ ("KEY_SYSRQ", "Print"),
+ ("KEY_COMPOSE", "Menu"),
+ ("KEY_MUTE", "XF86AudioMute"),
+ ("KEY_PLAYPAUSE", "XF86AudioPlay"),
+ ] {
+ assert_eq!(keysym_name(key).as_deref(), Some(sym), "{key}");
+ }
+ }
+
#[test]
fn an_unmappable_key_names_itself() {
let err = accelerator(&keys(&["KEY_FN_F1"])).unwrap_err();
diff --git a/dist/assets/index-ywDg7bM0.js b/dist/assets/index-lCQNFkWj.js
similarity index 70%
rename from dist/assets/index-ywDg7bM0.js
rename to dist/assets/index-lCQNFkWj.js
index b69104c..9e36940 100644
--- a/dist/assets/index-ywDg7bM0.js
+++ b/dist/assets/index-lCQNFkWj.js
@@ -1,28 +1,28 @@
-var $o=Object.defineProperty;var vl=s=>{throw TypeError(s)};var Go=(s,a,t)=>a in s?$o(s,a,{enumerable:!0,configurable:!0,writable:!0,value:t}):s[a]=t;var Va=(s,a,t)=>Go(s,typeof a!="symbol"?a+"":a,t),or=(s,a,t)=>a.has(s)||vl("Cannot "+t);var F=(s,a,t)=>(or(s,a,"read from private field"),t?t.call(s):a.get(s)),lt=(s,a,t)=>a.has(s)?vl("Cannot add the same private member more than once"):a instanceof WeakSet?a.add(s):a.set(s,t),_t=(s,a,t,r)=>(or(s,a,"write to private field"),r?r.call(s,t):a.set(s,t),t),Vt=(s,a,t)=>(or(s,a,"access private method"),t);(function(){const a=document.createElement("link").relList;if(a&&a.supports&&a.supports("modulepreload"))return;for(const l of document.querySelectorAll('link[rel="modulepreload"]'))r(l);new MutationObserver(l=>{for(const c of l)if(c.type==="childList")for(const u of c.addedNodes)u.tagName==="LINK"&&u.rel==="modulepreload"&&r(u)}).observe(document,{childList:!0,subtree:!0});function t(l){const c={};return l.integrity&&(c.integrity=l.integrity),l.referrerPolicy&&(c.referrerPolicy=l.referrerPolicy),l.crossOrigin==="use-credentials"?c.credentials="include":l.crossOrigin==="anonymous"?c.credentials="omit":c.credentials="same-origin",c}function r(l){if(l.ep)return;l.ep=!0;const c=t(l);fetch(l.href,c)}})();const Yo="5";var Ll,Rl,Nl;typeof window<"u"&&((Nl=(Rl=(Ll=window.__svelte)!=null?Ll:window.__svelte={}).v)!=null?Nl:Rl.v=new Set).add(Yo);let Vn=!1,Jo=!1;function Xo(){Vn=!0}Xo();const Zo=1,Qo=2,Bl=4,ec=8,tc=16,ac=1,sc=2,nc=4,ic=8,rc=16,lc=1,oc=2,ba=Symbol("uninitialized"),ql="http://www.w3.org/1999/xhtml",cc="http://www.w3.org/2000/svg",dc="http://www.w3.org/1998/Math/MathML",jl=!1;var Ur=Array.isArray,vc=Array.prototype.indexOf,zn=Array.prototype.includes,Ji=Array.from,Ul=Object.defineProperty,wn=Object.getOwnPropertyDescriptor,uc=Object.getOwnPropertyDescriptors,pc=Object.prototype,fc=Array.prototype,Kl=Object.getPrototypeOf,ul=Object.isExtensible;const Ps=()=>{};function Hl(s){for(var a=0;a{s=r,a=l});return{promise:t,resolve:s,reject:a}}function pl(s,a){if(Array.isArray(s))return s;if(!(Symbol.iterator in s))return Array.from(s);const t=[];for(const r of s)if(t.push(r),t.length===a)break;return t}const Ma=2,In=4,Xi=8,$l=1<<24,us=16,_s=32,Us=64,wr=128,ss=512,ya=1024,Sa=2048,ws=4096,Na=8192,ns=16384,un=32768,kr=1<<25,On=65536,Bi=1<<17,_c=1<<18,Fn=1<<19,hc=1<<20,bs=1<<25,on=65536,qi=1<<21,kn=1<<22,Bs=1<<23,sn=Symbol("$state"),gc=Symbol("legacy props"),mc=Symbol(""),Pi=Symbol("attributes"),xr=Symbol("class"),Tr=Symbol("style"),jn=Symbol("text"),Di=Symbol("form reset"),Zi=new class extends Error{constructor(){super(...arguments);Va(this,"name","StaleReactionError");Va(this,"message","The reaction that called `getAbortSignal()` was re-run or destroyed")}};var Vl;const bc=!!((Vl=globalThis.document)!=null&&Vl.contentType)&&globalThis.document.contentType.includes("xml");function Gl(s){throw new Error("https://svelte.dev/e/lifecycle_outside_component")}function yc(){throw new Error("https://svelte.dev/e/async_derived_orphan")}function wc(s,a,t){throw new Error("https://svelte.dev/e/each_key_duplicate")}function kc(s){throw new Error("https://svelte.dev/e/effect_in_teardown")}function xc(){throw new Error("https://svelte.dev/e/effect_in_unowned_derived")}function Tc(s){throw new Error("https://svelte.dev/e/effect_orphan")}function Sc(){throw new Error("https://svelte.dev/e/effect_update_depth_exceeded")}function Ec(s){throw new Error("https://svelte.dev/e/props_invalid_value")}function Cc(){throw new Error("https://svelte.dev/e/state_descriptors_fixed")}function Ac(){throw new Error("https://svelte.dev/e/state_prototype_fixed")}function Mc(){throw new Error("https://svelte.dev/e/state_unsafe_mutation")}function Pc(){throw new Error("https://svelte.dev/e/svelte_boundary_reset_onerror")}function Dc(){console.warn("https://svelte.dev/e/derived_inert")}function zc(){console.warn("https://svelte.dev/e/select_multiple_invalid_value")}function Ic(){console.warn("https://svelte.dev/e/svelte_boundary_reset_noop")}function Yl(s){return s===this.v}function Jl(s,a){return s!=s?a==a:s!==a||s!==null&&typeof s=="object"||typeof s=="function"}function Xl(s){return!Jl(s,this.v)}let da=null;function Ln(s){da=s}function Tt(s,a=!1,t){da={p:da,i:!1,c:null,e:null,s,x:null,r:xt,l:Vn&&!a?{s:null,u:null,$:[]}:null}}function St(s){var a=da,t=a.e;if(t!==null){a.e=null;for(var r of t)bo(r)}return a.i=!0,da=a.p,{}}function mi(){return!Vn||da!==null&&da.l===null}let Ys=[];function Zl(){var s=Ys;Ys=[],Hl(s)}function qs(s){if(Ys.length===0&&!Gn){var a=Ys;queueMicrotask(()=>{a===Ys&&Zl()})}Ys.push(s)}function Oc(){for(;Ys.length>0;)Zl()}function Ql(s){var a=xt;if(a===null)return Pt.f|=Bs,s;if(!(a.f&un)&&!(a.f&In))throw s;Vs(s,a)}function Vs(s,a){for(;a!==null;){if(a.f&wr){if(!(a.f&un))throw s;try{a.b.error(s);return}catch(t){s=t}}a=a.parent}throw s}const Lc=-7169;function ca(s,a){s.f=s.f&Lc|a}function Kr(s){s.f&ss||s.deps===null?ca(s,ya):ca(s,ws)}function eo(s){if(s!==null)for(const a of s)!(a.f&Ma)||!(a.f&on)||(a.f^=on,eo(a.deps))}function to(s,a,t){s.f&Sa?a.add(s):s.f&ws&&t.add(s),eo(s.deps),ca(s,ya)}function Hr(s,a,t){if(s==null)return a(void 0),t&&t(void 0),Ps;const r=Ts(()=>s.subscribe(a,t));return r.unsubscribe?()=>r.unsubscribe():r}const pn=[];function Rc(s,a){return{subscribe:bi(s,a).subscribe}}function bi(s,a=Ps){let t=null;const r=new Set;function l(v){if(Jl(s,v)&&(s=v,t)){const f=!pn.length;for(const h of r)h[1](),pn.push(h,s);if(f){for(let h=0;h{r.delete(h),r.size===0&&t&&(t(),t=null)}}return{set:l,update:c,subscribe:u}}function yi(s,a,t){const r=!Array.isArray(s),l=r?[s]:s;if(!l.every(Boolean))throw new Error("derived() expects stores as input, got a falsy value");const c=a.length<2;return Rc(t,(u,v)=>{let f=!1;const h=[];let b=0,m=Ps;const _=()=>{if(b)return;m();const A=a(r?h[0]:h,u,v);c?u(A):m=typeof A=="function"?A:Ps},x=l.map((A,q)=>Hr(A,T=>{h[q]=T,b&=~(1<{b|=1<a=t)(),a}let Sr=!1,Un=!1,Er=Symbol("unmounted");function Zt(s,a,t){var c;const r=(c=t[a])!=null?c:t[a]={store:null,source:uo(void 0),unsubscribe:Ps};if(r.store!==s&&!(Er in t))if(r.unsubscribe(),r.store=s!=null?s:null,s==null)r.source.v=void 0,r.unsubscribe=Ps;else{var l=!0;r.unsubscribe=Hr(s,u=>{l?r.source.v=u:o(r.source,u)}),l=!1}return s&&Er in t?bn(s):e(r.source)}function Ws(s,a){return Nc(s,a),a}function Ea(){const s={};function a(){er(()=>{for(var t in s)s[t].unsubscribe();Ul(s,Er,{enumerable:!1,value:!0})})}return[s,a]}function Nc(s,a){Sr=!0;try{s.set(a)}finally{Sr=!1}}function $s(){Un=!0}function Vc(s){var a=Un;try{return Un=!1,[s(),Un]}finally{Un=a}}let cr=null,fn=null,ot=null,$n=null,Aa=null,Cr=null,Gn=!1,dr=!1,yn=null,zi=null;var fl=0;let Fc=1;var Sn,Ls,Zs,En,Cn,Qs,An,Es,ti,Wa,ai,Rs,hs,gs,Mn,Pn,Bt,Ar,Kn,Mr,ao,so,Ii,Bc,Pr,gn;const $i=class $i{constructor(){lt(this,Bt);Va(this,"id",Fc++);lt(this,Sn,!1);Va(this,"linked",!0);lt(this,Ls,null);lt(this,Zs,null);Va(this,"async_deriveds",new Map);Va(this,"current",new Map);Va(this,"previous",new Map);Va(this,"unblocked",new Set);lt(this,En,new Set);lt(this,Cn,new Set);lt(this,Qs,new Set);lt(this,An,0);lt(this,Es,new Map);lt(this,ti,null);lt(this,Wa,[]);lt(this,ai,[]);lt(this,Rs,new Set);lt(this,hs,new Set);lt(this,gs,new Map);lt(this,Mn,new Set);Va(this,"is_fork",!1);lt(this,Pn,!1)}skip_effect(a){F(this,gs).has(a)||F(this,gs).set(a,{d:[],m:[]}),F(this,Mn).delete(a)}unskip_effect(a,t=r=>this.schedule(r)){var r=F(this,gs).get(a);if(r){F(this,gs).delete(a);for(var l of r.d)ca(l,Sa),t(l);for(l of r.m)ca(l,ws),t(l)}F(this,Mn).add(a)}capture(a,t,r=!1){a.v!==ba&&!this.previous.has(a)&&this.previous.set(a,a.v),a.f&Bs||(this.current.set(a,[t,r]),Aa==null||Aa.set(a,t)),this.is_fork||(a.v=t)}activate(){ot=this}deactivate(){ot=null,Aa=null}flush(){try{dr=!0,ot=this,Vt(this,Bt,Kn).call(this)}finally{fl=0,Cr=null,yn=null,zi=null,dr=!1,ot=null,Aa=null,nn.clear()}}discard(){for(const a of F(this,Cn))a(this);F(this,Cn).clear(),F(this,Qs).clear(),Vt(this,Bt,gn).call(this)}register_created_effect(a){F(this,ai).push(a)}increment(a,t){var r;if(_t(this,An,F(this,An)+1),a){let l=(r=F(this,Es).get(t))!=null?r:0;F(this,Es).set(t,l+1)}}decrement(a,t){var r;if(_t(this,An,F(this,An)-1),a){let l=(r=F(this,Es).get(t))!=null?r:0;l===1?F(this,Es).delete(t):F(this,Es).set(t,l-1)}F(this,Pn)||(_t(this,Pn,!0),qs(()=>{_t(this,Pn,!1),this.linked&&this.flush()}))}transfer_effects(a,t){for(const r of a)F(this,Rs).add(r);for(const r of t)F(this,hs).add(r);a.clear(),t.clear()}oncommit(a){F(this,En).add(a)}ondiscard(a){F(this,Cn).add(a)}on_fork_commit(a){F(this,Qs).add(a)}run_fork_commit_callbacks(){for(const a of F(this,Qs))a(this);F(this,Qs).clear()}settled(){var a;return((a=F(this,ti))!=null?a:_t(this,ti,Wl())).promise}static ensure(){var a;if(ot===null){const t=ot=new $i;Vt(a=t,Bt,Pr).call(a),!dr&&!Gn&&qs(()=>{F(t,Sn)||t.flush()})}return ot}apply(){{Aa=null;return}}schedule(a){var l;if(Cr=a,(l=a.b)!=null&&l.is_pending&&a.f&(In|Xi|$l)&&!(a.f&un)){a.b.defer_effect(a);return}for(var t=a;t.parent!==null;){t=t.parent;var r=t.f;if(yn!==null&&t===xt&&(Pt===null||!(Pt.f&Ma))&&!Sr)return;if(r&(Us|_s)){if(!(r&ya))return;t.f^=ya}}F(this,Wa).push(t)}};Sn=new WeakMap,Ls=new WeakMap,Zs=new WeakMap,En=new WeakMap,Cn=new WeakMap,Qs=new WeakMap,An=new WeakMap,Es=new WeakMap,ti=new WeakMap,Wa=new WeakMap,ai=new WeakMap,Rs=new WeakMap,hs=new WeakMap,gs=new WeakMap,Mn=new WeakMap,Pn=new WeakMap,Bt=new WeakSet,Ar=function(){if(this.is_fork)return!0;for(const r of F(this,Es).keys()){for(var a=r,t=!1;a.parent!==null;){if(F(this,gs).has(a)){t=!0;break}a=a.parent}if(!t)return!0}return!1},Kn=function(){var f,h,b,m;if(_t(this,Sn,!0),fl++>1e3&&(Vt(this,Bt,gn).call(this),jc()),!Vt(this,Bt,Ar).call(this)){for(const _ of F(this,Rs))F(this,hs).delete(_),ca(_,Sa),this.schedule(_);for(const _ of F(this,hs))ca(_,ws),this.schedule(_)}const a=F(this,Wa);_t(this,Wa,[]),this.apply();var t=yn=[],r=[],l=zi=[];for(const _ of a)try{Vt(this,Bt,Mr).call(this,_,t,r)}catch(x){throw ro(_),x}if(ot=null,l.length>0){var c=$i.ensure();for(const _ of l)c.schedule(_)}if(yn=null,zi=null,Vt(this,Bt,Ar).call(this)){Vt(this,Bt,Ii).call(this,r),Vt(this,Bt,Ii).call(this,t);for(const[_,x]of F(this,gs))io(_,x);l.length>0&&Vt(f=ot,Bt,Kn).call(f);return}const u=Vt(this,Bt,ao).call(this);if(u){Vt(h=u,Bt,so).call(h,this);return}F(this,Rs).clear(),F(this,hs).clear();for(const _ of F(this,En))_(this);F(this,En).clear(),$n=this,_l(r),_l(t),$n=null,(b=F(this,ti))==null||b.resolve();var v=ot;if(this.linked&&F(this,An)===0&&Vt(this,Bt,gn).call(this),F(this,Wa).length>0){v===null&&(v=this,Vt(this,Bt,Pr).call(this));const _=v;F(_,Wa).push(...F(this,Wa).filter(x=>!F(_,Wa).includes(x)))}v!==null&&Vt(m=v,Bt,Kn).call(m)},Mr=function(a,t,r){a.f^=ya;for(var l=a.first;l!==null;){var c=l.f,u=(c&(_s|Us))!==0,v=u&&(c&ya)!==0,f=v||(c&Na)!==0||F(this,gs).has(l);if(!f&&l.fn!==null){u?l.f^=ya:c&In?t.push(l):ki(l)&&(c&us&&F(this,hs).add(l),Nn(l));var h=l.first;if(h!==null){l=h;continue}}for(;l!==null;){var b=l.next;if(b!==null){l=b;break}l=l.parent}}},ao=function(){for(var a=F(this,Ls);a!==null;){if(!a.is_fork){for(const[t,[,r]]of this.current)if(a.current.has(t)&&!r)return a}a=F(a,Ls)}return null},so=function(a){var r;for(const[l,c]of a.current)!this.previous.has(l)&&a.previous.has(l)&&this.previous.set(l,a.previous.get(l)),this.current.set(l,c);for(const[l,c]of a.async_deriveds){const u=this.async_deriveds.get(l);u&&c.promise.then(u.resolve)}const t=l=>{var c=l.reactions;if(c!==null)for(const f of c){var u=f.f;if(u&Ma)t(f);else{var v=f;u&(kn|us)&&!this.async_deriveds.has(v)&&(F(this,hs).delete(v),ca(v,Sa),this.schedule(v))}}};for(const l of this.current.keys())t(l);this.oncommit(()=>a.discard()),Vt(r=a,Bt,gn).call(r),ot=this,Vt(this,Bt,Kn).call(this)},Ii=function(a){for(var t=0;t!this.current.has(_));if(l.length===0)a&&m.discard();else if(t.length>0){if(a)for(const _ of F(this,Mn))m.unskip_effect(_,x=>{var A;x.f&(us|kn)?m.schedule(x):Vt(A=m,Bt,Ii).call(A,[x])});m.activate();var c=new Set,u=new Map;for(var v of t)no(v,l,c,u);u=new Map;var f=[...m.current.keys()].filter(_=>this.current.has(_)?this.current.get(_)[0]!==_.v:!0);if(f.length>0)for(const _ of F(this,ai))!(_.f&(ns|Na|Bi))&&Wr(_,f,u)&&(_.f&(kn|us)?(ca(_,Sa),m.schedule(_)):F(m,Rs).add(_));if(F(m,Wa).length>0){m.apply();for(var h of F(m,Wa))Vt(b=m,Bt,Mr).call(b,h,[],[]);_t(m,Wa,[])}m.deactivate()}}}},Pr=function(){fn===null?cr=fn=this:(_t(fn,Zs,this),_t(this,Ls,fn)),fn=this},gn=function(){var a=F(this,Ls),t=F(this,Zs);a===null?cr=t:_t(a,Zs,t),t===null?fn=a:_t(t,Ls,a),this.linked=!1};let cn=$i;function qc(s){var a=Gn;Gn=!0;try{for(var t;;){if(Oc(),ot===null)return t;ot.flush()}}finally{Gn=a}}function jc(){try{Sc()}catch(s){Vs(s,Cr)}}let os=null;function _l(s){var a=s.length;if(a!==0){for(var t=0;t0)){nn.clear();for(const l of os){if(l.f&(ns|Na))continue;const c=[l];let u=l.parent;for(;u!==null;)os.has(u)&&(os.delete(u),c.push(u)),u=u.parent;for(let v=c.length-1;v>=0;v--){const f=c[v];f.f&(ns|Na)||Nn(f)}}os.clear()}}os=null}}function no(s,a,t,r){if(!t.has(s)&&(t.add(s),s.reactions!==null))for(const l of s.reactions){const c=l.f;c&Ma?no(l,a,t,r):c&(kn|us)&&!(c&Sa)&&Wr(l,a,r)&&(ca(l,Sa),$r(l))}}function Wr(s,a,t){const r=t.get(s);if(r!==void 0)return r;if(s.deps!==null)for(const l of s.deps){if(zn.call(a,l))return!0;if(l.f&Ma&&Wr(l,a,t))return t.set(l,!0),!0}return t.set(s,!1),!1}function $r(s){ot.schedule(s)}function io(s,a){if(!(s.f&_s&&s.f&ya)){s.f&Sa?a.d.push(s):s.f&ws&&a.m.push(s),ca(s,ya);for(var t=s.first;t!==null;)io(t,a),t=t.next}}function ro(s){ca(s,ya);for(var a=s.first;a!==null;)ro(a),a=a.next}function Uc(s){let a=0,t=dn(0),r;return()=>{Xr()&&(e(t),tr(()=>(a===0&&(r=Ts(()=>s(()=>Yn(t)))),a+=1,()=>{qs(()=>{a-=1,a===0&&(r==null||r(),r=void 0,Yn(t))})})))}}var Kc=On|Fn;function Hc(s,a,t,r){new Wc(s,a,t,r)}var Za,jr,Qa,en,Fa,es,Ra,$a,Cs,tn,Ns,Dn,si,ni,As,Gi,va,$c,Gc,Yc,Dr,Oi,Li,zr,Ir;class Wc{constructor(a,t,r,l){lt(this,va);Va(this,"parent");Va(this,"is_pending",!1);Va(this,"transform_error");lt(this,Za);lt(this,jr,null);lt(this,Qa);lt(this,en);lt(this,Fa);lt(this,es,null);lt(this,Ra,null);lt(this,$a,null);lt(this,Cs,null);lt(this,tn,0);lt(this,Ns,0);lt(this,Dn,!1);lt(this,si,new Set);lt(this,ni,new Set);lt(this,As,null);lt(this,Gi,Uc(()=>(_t(this,As,dn(F(this,tn))),()=>{_t(this,As,null)})));var c,u;_t(this,Za,a),_t(this,Qa,t),_t(this,en,v=>{var f=xt;f.b=this,f.f|=wr,r(v)}),this.parent=xt.b,this.transform_error=(u=l!=null?l:(c=this.parent)==null?void 0:c.transform_error)!=null?u:v=>v,_t(this,Fa,Zr(()=>{Vt(this,va,Dr).call(this)},Kc))}defer_effect(a){to(a,F(this,si),F(this,ni))}is_rendered(){return!this.is_pending&&(!this.parent||this.parent.is_rendered())}has_pending_snippet(){return!!F(this,Qa).pending}update_pending_count(a,t){Vt(this,va,zr).call(this,a,t),_t(this,tn,F(this,tn)+a),!(!F(this,As)||F(this,Dn))&&(_t(this,Dn,!0),qs(()=>{_t(this,Dn,!1),F(this,As)&&Rn(F(this,As),F(this,tn))}))}get_effect_pending(){return F(this,Gi).call(this),e(F(this,As))}error(a){if(!F(this,Qa).onerror&&!F(this,Qa).failed)throw a;ot!=null&&ot.is_fork?(F(this,es)&&ot.skip_effect(F(this,es)),F(this,Ra)&&ot.skip_effect(F(this,Ra)),F(this,$a)&&ot.skip_effect(F(this,$a)),ot.on_fork_commit(()=>{Vt(this,va,Ir).call(this,a)})):Vt(this,va,Ir).call(this,a)}}Za=new WeakMap,jr=new WeakMap,Qa=new WeakMap,en=new WeakMap,Fa=new WeakMap,es=new WeakMap,Ra=new WeakMap,$a=new WeakMap,Cs=new WeakMap,tn=new WeakMap,Ns=new WeakMap,Dn=new WeakMap,si=new WeakMap,ni=new WeakMap,As=new WeakMap,Gi=new WeakMap,va=new WeakSet,$c=function(){try{_t(this,es,ts(()=>F(this,en).call(this,F(this,Za))))}catch(a){this.error(a)}},Gc=function(a){const t=F(this,Qa).failed;t&&_t(this,$a,ts(()=>{t(F(this,Za),()=>a,()=>()=>{})}))},Yc=function(){const a=F(this,Qa).pending;a&&(this.is_pending=!0,_t(this,Ra,ts(()=>a(F(this,Za)))),qs(()=>{var t=_t(this,Cs,document.createDocumentFragment()),r=Ds();t.append(r),_t(this,es,Vt(this,va,Li).call(this,()=>ts(()=>F(this,en).call(this,r)))),F(this,Ns)===0&&(F(this,Za).before(t),_t(this,Cs,null),rn(F(this,Ra),()=>{_t(this,Ra,null)}),Vt(this,va,Oi).call(this,ot))}))},Dr=function(){try{if(this.is_pending=this.has_pending_snippet(),_t(this,Ns,0),_t(this,tn,0),_t(this,es,ts(()=>{F(this,en).call(this,F(this,Za))})),F(this,Ns)>0){var a=_t(this,Cs,document.createDocumentFragment());tl(F(this,es),a);const t=F(this,Qa).pending;_t(this,Ra,ts(()=>t(F(this,Za))))}else Vt(this,va,Oi).call(this,ot)}catch(t){this.error(t)}},Oi=function(a){this.is_pending=!1,a.transfer_effects(F(this,si),F(this,ni))},Li=function(a){var t=xt,r=Pt,l=da;ks(F(this,Fa)),rs(F(this,Fa)),Ln(F(this,Fa).ctx);try{return cn.ensure(),a()}catch(c){return Ql(c),null}finally{ks(t),rs(r),Ln(l)}},zr=function(a,t){var r;if(!this.has_pending_snippet()){this.parent&&Vt(r=this.parent,va,zr).call(r,a,t);return}_t(this,Ns,F(this,Ns)+a),F(this,Ns)===0&&(Vt(this,va,Oi).call(this,t),F(this,Ra)&&rn(F(this,Ra),()=>{_t(this,Ra,null)}),F(this,Cs)&&(F(this,Za).before(F(this,Cs)),_t(this,Cs,null)))},Ir=function(a){F(this,es)&&(qa(F(this,es)),_t(this,es,null)),F(this,Ra)&&(qa(F(this,Ra)),_t(this,Ra,null)),F(this,$a)&&(qa(F(this,$a)),_t(this,$a,null));var t=F(this,Qa).onerror;let r=F(this,Qa).failed;var l=!1,c=!1;const u=()=>{if(l){Ic();return}l=!0,c&&Pc(),F(this,$a)!==null&&rn(F(this,$a),()=>{_t(this,$a,null)}),Vt(this,va,Li).call(this,()=>{Vt(this,va,Dr).call(this)})},v=f=>{try{c=!0,t==null||t(f,u),c=!1}catch(h){Vs(h,F(this,Fa)&&F(this,Fa).parent)}r&&_t(this,$a,Vt(this,va,Li).call(this,()=>{try{return ts(()=>{var h=xt;h.b=this,h.f|=wr,r(F(this,Za),()=>f,()=>u)})}catch(h){return Vs(h,F(this,Fa).parent),null}}))};qs(()=>{var f;try{f=this.transform_error(a)}catch(h){Vs(h,F(this,Fa)&&F(this,Fa).parent);return}f!==null&&typeof f=="object"&&typeof f.then=="function"?f.then(v,h=>Vs(h,F(this,Fa)&&F(this,Fa).parent)):v(f)})};function Jc(s,a,t,r){const l=mi()?Zn:Gr;var c=s.filter(_=>!_.settled);if(t.length===0&&c.length===0){r(a.map(l));return}var u=xt,v=Xc(),f=c.length===1?c[0].promise:c.length>1?Promise.all(c.map(_=>_.promise)):null;function h(_){if(!(u.f&ns)){v();try{r(_)}catch(x){Vs(x,u)}ji()}}var b=lo();if(t.length===0){f.then(()=>h(a.map(l))).finally(b);return}function m(){Promise.all(t.map(_=>Zc(_))).then(_=>h([...a.map(l),..._])).catch(_=>Vs(_,u)).finally(b)}f?f.then(()=>{v(),m(),ji()}):m()}function Xc(){var s=xt,a=Pt,t=da,r=ot;return function(c=!0){ks(s),rs(a),Ln(t),c&&!(s.f&ns)&&(r==null||r.activate(),r==null||r.apply())}}function ji(s=!0){ks(null),rs(null),Ln(null),s&&(ot==null||ot.deactivate())}function lo(){var s=xt,a=s.b,t=ot,r=a.is_rendered();return a.update_pending_count(1,t),t.increment(r,s),()=>{a.update_pending_count(-1,t),t.decrement(r,s)}}function Zn(s){var a=Ma|Sa;return xt!==null&&(xt.f|=Fn),{ctx:da,deps:null,effects:null,equals:Yl,f:a,fn:s,reactions:null,rv:0,v:ba,wv:0,parent:xt,ac:null}}const Si=Symbol("obsolete");function Zc(s,a,t){let r=xt;r===null&&yc();var l=void 0,c=dn(ba),u=!Pt,v=new Set;return cd(()=>{var x;var f=xt,h=Wl();l=h.promise;try{Promise.resolve(s()).then(h.resolve,A=>{A!==Zi&&h.reject(A)}).finally(ji)}catch(A){h.reject(A),ji()}var b=ot;if(u){if(f.f&un)var m=lo();if(r.b.is_rendered())(x=b.async_deriveds.get(f))==null||x.reject(Si);else for(const A of v.values())A.reject(Si);v.add(h),b.async_deriveds.set(f,h)}const _=(A,q=void 0)=>{m==null||m(),v.delete(h),q!==Si&&(b.activate(),q?(c.f|=Bs,Rn(c,q)):(c.f&Bs&&(c.f^=Bs),Rn(c,A)),b.deactivate())};h.promise.then(_,A=>_(null,A||"unknown"))}),er(()=>{for(const f of v)f.reject(Si)}),new Promise(f=>{function h(b){function m(){b===l?f(c):h(l)}b.then(m,m)}h(l)})}function ce(s){const a=Zn(s);return So(a),a}function Gr(s){const a=Zn(s);return a.equals=Xl,a}function Qc(s){var a=s.effects;if(a!==null){s.effects=null;for(var t=0;t0&&!vo&&td()}return a}function td(){vo=!1;for(const s of Ui){s.f&ya&&ca(s,ws);let a;try{a=ki(s)}catch{a=!0}a&&Nn(s)}Ui.clear()}function Yn(s){o(s,s.v+1)}function po(s,a,t){var r=s.reactions;if(r!==null)for(var l=mi(),c=r.length,u=0;u{if(ln===c)return v();var f=Pt,h=ln;rs(null),bl(c);var b=v();return rs(f),bl(h),b};return r&&t.set("length",S(s.length)),new Proxy(s,{defineProperty(v,f,h){(!("value"in h)||h.configurable===!1||h.enumerable===!1||h.writable===!1)&&Cc();var b=t.get(f);return b===void 0?u(()=>{var m=S(h.value);return t.set(f,m),m}):o(b,h.value,!0),!0},deleteProperty(v,f){var h=t.get(f);if(h===void 0){if(f in v){const b=u(()=>S(ba));t.set(f,b),Yn(l)}}else o(h,ba),Yn(l);return!0},get(v,f,h){var x;if(f===sn)return s;var b=t.get(f),m=f in v;if(b===void 0&&(!m||(x=wn(v,f))!=null&&x.writable)&&(b=u(()=>{var A=yt(m?v[f]:ba),q=S(A);return q}),t.set(f,b)),b!==void 0){var _=e(b);return _===ba?void 0:_}return Reflect.get(v,f,h)},getOwnPropertyDescriptor(v,f){var h=Reflect.getOwnPropertyDescriptor(v,f);if(h&&"value"in h){var b=t.get(f);b&&(h.value=e(b))}else if(h===void 0){var m=t.get(f),_=m==null?void 0:m.v;if(m!==void 0&&_!==ba)return{enumerable:!0,configurable:!0,value:_,writable:!0}}return h},has(v,f){var _;if(f===sn)return!0;var h=t.get(f),b=h!==void 0&&h.v!==ba||Reflect.has(v,f);if(h!==void 0||xt!==null&&(!b||(_=wn(v,f))!=null&&_.writable)){h===void 0&&(h=u(()=>{var x=b?yt(v[f]):ba,A=S(x);return A}),t.set(f,h));var m=e(h);if(m===ba)return!1}return b},set(v,f,h,b){var ne;var m=t.get(f),_=f in v;if(r&&f==="length")for(var x=h;xS(ba)),t.set(x+"",A))}if(m===void 0)(!_||(ne=wn(v,f))!=null&&ne.writable)&&(m=u(()=>S(void 0)),o(m,yt(h)),t.set(f,m));else{_=m.v!==ba;var q=u(()=>yt(h));o(m,q)}var T=Reflect.getOwnPropertyDescriptor(v,f);if(T!=null&&T.set&&T.set.call(b,h),!_){if(r&&typeof f=="string"){var D=t.get("length"),se=Number(f);Number.isInteger(se)&&se>=D.v&&o(D,se+1)}Yn(l)}return!0},ownKeys(v){e(l);var f=Reflect.ownKeys(v).filter(m=>{var _=t.get(m);return _===void 0||_.v!==ba});for(var[h,b]of t)b.v!==ba&&!(h in v)&&f.push(h);return f},setPrototypeOf(){Ac()}})}function hl(s){try{if(s!==null&&typeof s=="object"&&sn in s)return s[sn]}catch{}return s}function ad(s,a){return Object.is(hl(s),hl(a))}var Or,fo,_o,ho;function sd(){if(Or===void 0){Or=window,fo=/Firefox/.test(navigator.userAgent);var s=Element.prototype,a=Node.prototype,t=Text.prototype;_o=wn(a,"firstChild").get,ho=wn(a,"nextSibling").get,ul(s)&&(s[xr]=void 0,s[Pi]=null,s[Tr]=void 0,s.__e=void 0),ul(t)&&(t[jn]=void 0)}}function Ds(s=""){return document.createTextNode(s)}function ys(s){return _o.call(s)}function wi(s){return ho.call(s)}function n(s,a){return ys(s)}function ht(s,a=!1){{var t=ys(s);return t instanceof Comment&&t.data===""?wi(t):t}}function i(s,a=1,t=!1){let r=s;for(;a--;)r=wi(r);return r}function nd(s){s.textContent=""}function go(){return!1}function mo(s,a,t){return document.createElementNS(a!=null?a:ql,s,void 0)}let gl=!1;function id(){gl||(gl=!0,document.addEventListener("reset",s=>{Promise.resolve().then(()=>{var a;if(!s.defaultPrevented)for(const t of s.target.elements)(a=t[Di])==null||a.call(t)})},{capture:!0}))}function Qi(s){var a=Pt,t=xt;rs(null),ks(null);try{return s()}finally{rs(a),ks(t)}}function Jr(s,a,t,r=t){s.addEventListener(a,()=>Qi(t));const l=s[Di];l?s[Di]=()=>{l(),r(!0)}:s[Di]=()=>r(!0),id()}function rd(s){xt===null&&(Pt===null&&Tc(),xc()),zs&&kc()}function ld(s,a){var t=a.last;t===null?a.last=a.first=s:(t.next=s,s.prev=t,a.last=s)}function Is(s,a){var u;var t=xt;t!==null&&t.f&Na&&(s|=Na);var r={ctx:da,deps:null,nodes:null,f:s|Sa|ss,first:null,fn:a,last:null,next:null,parent:t,b:t&&t.b,prev:null,teardown:null,wv:0,ac:null};ot==null||ot.register_created_effect(r);var l=r;if(s&In)yn!==null?yn.push(r):cn.ensure().schedule(r);else if(a!==null){try{Nn(r)}catch(v){throw qa(r),v}l.deps===null&&l.teardown===null&&l.nodes===null&&l.first===l.last&&!(l.f&Fn)&&(l=l.first,s&us&&s&On&&l!==null&&(l.f|=On))}if(l!==null&&(l.parent=t,t!==null&&ld(l,t),Pt!==null&&Pt.f&Ma&&!(s&Us))){var c=Pt;((u=c.effects)!=null?u:c.effects=[]).push(l)}return r}function Xr(){return Pt!==null&&!ps}function er(s){const a=Is(Xi,null);return ca(a,ya),a.teardown=s,a}function pa(s){var l;rd();var a=xt.f,t=!Pt&&(a&_s)!==0&&(a&un)===0;if(t){var r=da;((l=r.e)!=null?l:r.e=[]).push(s)}else return bo(s)}function bo(s){return Is(In|hc,s)}function od(s){cn.ensure();const a=Is(Us|Fn,s);return(t={})=>new Promise(r=>{t.outro?rn(a,()=>{qa(a),r(void 0)}):(qa(a),r(void 0))})}function Ms(s){return Is(In,s)}function cd(s){return Is(kn|Fn,s)}function tr(s,a=0){return Is(Xi|a,s)}function w(s,a=[],t=[],r=[]){Jc(r,a,t,l=>{Is(Xi,()=>s(...l.map(e)))})}function Zr(s,a=0){var t=Is(us|a,s);return t}function ts(s){return Is(_s|Fn,s)}function yo(s){var a=s.teardown;if(a!==null){const t=zs,r=Pt;ml(!0),rs(null);try{a.call(null)}finally{ml(t),rs(r)}}}function Qr(s,a=!1){var t=s.first;for(s.first=s.last=null;t!==null;){const l=t.ac;l!==null&&Qi(()=>{l.abort(Zi)});var r=t.next;t.f&Us?t.parent=null:qa(t,a),t=r}}function dd(s){for(var a=s.first;a!==null;){var t=a.next;a.f&_s||qa(a),a=t}}function qa(s,a=!0){var t=!1;(a||s.f&_c)&&s.nodes!==null&&s.nodes.end!==null&&(wo(s.nodes.start,s.nodes.end),t=!0),ca(s,kr),Qr(s,a&&!t),Qn(s,0);var r=s.nodes&&s.nodes.t;if(r!==null)for(const c of r)c.stop();yo(s),s.f^=kr,s.f|=ns;var l=s.parent;l!==null&&l.first!==null&&ko(s),s.next=s.prev=s.teardown=s.ctx=s.deps=s.fn=s.nodes=s.ac=s.b=null}function wo(s,a){for(;s!==null;){var t=s===a?null:wi(s);s.remove(),s=t}}function ko(s){var a=s.parent,t=s.prev,r=s.next;t!==null&&(t.next=r),r!==null&&(r.prev=t),a!==null&&(a.first===s&&(a.first=r),a.last===s&&(a.last=t))}function rn(s,a,t=!0){var r=[];xo(s,r,!0);var l=()=>{t&&qa(s),a&&a()},c=r.length;if(c>0){var u=()=>--c||l();for(var v of r)v.out(u)}else l()}function xo(s,a,t){if(!(s.f&Na)){s.f^=Na;var r=s.nodes&&s.nodes.t;if(r!==null)for(const v of r)(v.is_global||t)&&a.push(v);for(var l=s.first;l!==null;){var c=l.next;if(!(l.f&Us)){var u=(l.f&On)!==0||(l.f&_s)!==0&&(s.f&us)!==0;xo(l,a,u?t:!1)}l=c}}}function el(s){To(s,!0)}function To(s,a){if(s.f&Na){s.f^=Na,s.f&ya||(ca(s,Sa),cn.ensure().schedule(s));for(var t=s.first;t!==null;){var r=t.next,l=(t.f&On)!==0||(t.f&_s)!==0;To(t,l?a:!1),t=r}var c=s.nodes&&s.nodes.t;if(c!==null)for(const u of c)(u.is_global||a)&&u.in()}}function tl(s,a){if(s.nodes)for(var t=s.nodes.start,r=s.nodes.end;t!==null;){var l=t===r?null:wi(t);a.append(t),t=l}}let Ri=!1,zs=!1;function ml(s){zs=s}let Pt=null,ps=!1;function rs(s){Pt=s}let xt=null;function ks(s){xt=s}let is=null;function So(s){Pt!==null&&(is===null?is=[s]:is.push(s))}let Ba=null,Ka=0,Xa=null;function vd(s){Xa=s}let Eo=1,Js=0,ln=Js;function bl(s){ln=s}function Co(){return++Eo}function ki(s){var a=s.f;if(a&Sa)return!0;if(a&Ma&&(s.f&=~on),a&ws){for(var t=s.deps,r=t.length,l=0;ls.wv)return!0}a&ss&&Aa===null&&ca(s,ya)}return!1}function Ao(s,a,t=!0){var r=s.reactions;if(r!==null&&!(is!==null&&zn.call(is,s)))for(var l=0;l{s.ac.abort(Zi)}),s.ac=null);try{s.f|=qi;var b=s.fn,m=b();s.f|=un;var _=s.deps,x=ot==null?void 0:ot.is_fork;if(Ba!==null){var A;if(x||Qn(s,Ka),_!==null&&Ka>0)for(_.length=Ka+Ba.length,A=0;At==null?void 0:t.call(this,c))}return s.startsWith("pointer")||s.startsWith("touch")||s==="wheel"?qs(()=>{a.addEventListener(s,l,r)}):a.addEventListener(s,l,r),l}function xs(s,a,t,r,l){var c={capture:r,passive:l},u=fd(s,a,t,c);(a===document.body||a===window||a===document||a instanceof HTMLMediaElement)&&er(()=>{a.removeEventListener(s,u,c)})}function N(s,a,t){var r;((r=a[Xs])!=null?r:a[Xs]={})[s]=t}function Qt(s){for(var a=0;a{throw se});throw _}}finally{s[Xs]=a,delete s.currentTarget,rs(b),ks(m)}}}var Fl;const vr=((Fl=globalThis==null?void 0:globalThis.window)==null?void 0:Fl.trustedTypes)&&globalThis.window.trustedTypes.createPolicy("svelte-trusted-html",{createHTML:s=>s});function _d(s){var a;return(a=vr==null?void 0:vr.createHTML(s))!=null?a:s}function Io(s){var a=mo("template");return a.innerHTML=_d(s.replaceAll("","")),a.content}function vn(s,a){var t=xt;t.nodes===null&&(t.nodes={start:s,end:a,a:null,t:null})}function p(s,a){var t=(a&lc)!==0,r=(a&oc)!==0,l,c=!s.startsWith("");return()=>{l===void 0&&(l=Io(c?s:""+s),t||(l=ys(l)));var u=r||fo?document.importNode(l,!0):l.cloneNode(!0);if(t){var v=ys(u),f=u.lastChild;vn(v,f)}else vn(u,u);return u}}function hd(s,a,t="svg"){var r=!s.startsWith(""),l=`<${t}>${r?s:""+s}${t}>`,c;return()=>{if(!c){var u=Io(l),v=ys(u);c=ys(v)}var f=c.cloneNode(!0);return vn(f,f),f}}function Oo(s,a){return hd(s,a,"svg")}function Be(s=""){{var a=Ds(s+"");return vn(a,a),a}}function xi(){var s=document.createDocumentFragment(),a=document.createComment(""),t=Ds();return s.append(a,t),vn(a,t),s}function d(s,a){s!==null&&s.before(a)}const gd=["touchstart","touchmove"];function md(s){return gd.includes(s)}function y(s,a){var r;var t=a==null?"":typeof a=="object"?`${a}`:a;t!==((r=s[jn])!=null?r:s[jn]=s.nodeValue)&&(s[jn]=t,s.nodeValue=`${t}`)}function bd(s,a){return yd(s,a)}const Ei=new Map;function yd(s,{target:a,anchor:t,props:r={},events:l,context:c,intro:u=!0,transformError:v}){sd();var f=void 0,h=od(()=>{var b=t!=null?t:a.appendChild(Ds());Hc(b,{pending:()=>{}},x=>{Tt({});var A=da;c&&(A.c=c),l&&(r.$$events=l),f=s(x,r)||{},St()},v);var m=new Set,_=x=>{for(var A=0;A{var T;for(var x of m)for(const D of[a,document]){var A=Ei.get(D),q=A.get(x);--q==0?(D.removeEventListener(x,Rr),A.delete(x),A.size===0&&Ei.delete(D)):A.set(x,q)}Lr.delete(_),b!==t&&((T=b.parentNode)==null||T.removeChild(b))}});return wd.set(f,h),f}let wd=new WeakMap;var vs,ms,Ga,an,ii,ri,Yi;class kd{constructor(a,t=!0){Va(this,"anchor");lt(this,vs,new Map);lt(this,ms,new Map);lt(this,Ga,new Map);lt(this,an,new Set);lt(this,ii,!0);lt(this,ri,a=>{if(F(this,vs).has(a)){var t=F(this,vs).get(a),r=F(this,ms).get(t);if(r)el(r),F(this,an).delete(t);else{var l=F(this,Ga).get(t);l&&(F(this,ms).set(t,l.effect),F(this,Ga).delete(t),l.fragment.lastChild.remove(),this.anchor.before(l.fragment),r=l.effect)}for(const[c,u]of F(this,vs)){if(F(this,vs).delete(c),c===a)break;const v=F(this,Ga).get(u);v&&(qa(v.effect),F(this,Ga).delete(u))}for(const[c,u]of F(this,ms)){if(c===t||F(this,an).has(c))continue;const v=()=>{if(Array.from(F(this,vs).values()).includes(c)){var h=document.createDocumentFragment();tl(u,h),h.append(Ds()),F(this,Ga).set(c,{effect:u,fragment:h})}else qa(u);F(this,an).delete(c),F(this,ms).delete(c)};F(this,ii)||!r?(F(this,an).add(c),rn(u,v,!1)):v()}}});lt(this,Yi,a=>{F(this,vs).delete(a);const t=Array.from(F(this,vs).values());for(const[r,l]of F(this,Ga))t.includes(r)||(qa(l.effect),F(this,Ga).delete(r))});this.anchor=a,_t(this,ii,t)}ensure(a,t){var r=ot,l=go();if(t&&!F(this,ms).has(a)&&!F(this,Ga).has(a))if(l){var c=document.createDocumentFragment(),u=Ds();c.append(u),F(this,Ga).set(a,{effect:ts(()=>t(u)),fragment:c})}else F(this,ms).set(a,ts(()=>t(this.anchor)));if(F(this,vs).set(r,a),l){for(const[v,f]of F(this,ms))v===a?r.unskip_effect(f):r.skip_effect(f);for(const[v,f]of F(this,Ga))v===a?r.unskip_effect(f.effect):r.skip_effect(f.effect);r.oncommit(F(this,ri)),r.ondiscard(F(this,Yi))}else F(this,ri).call(this,r)}}vs=new WeakMap,ms=new WeakMap,Ga=new WeakMap,an=new WeakMap,ii=new WeakMap,ri=new WeakMap,Yi=new WeakMap;function qt(s){da===null&&Gl(),Vn&&da.l!==null?xd(da).m.push(s):pa(()=>{const a=Ts(s);if(typeof a=="function")return a})}function ar(s){da===null&&Gl(),qt(()=>()=>Ts(s))}function xd(s){var t;var a=s.l;return(t=a.u)!=null?t:a.u={a:[],b:[],m:[]}}function k(s,a,t=!1){var r=new kd(s),l=t?On:0;function c(u,v){r.ensure(u,v)}Zr(()=>{var u=!1;a((v,f=0)=>{u=!0,c(f,v)}),u||c(-1,null)},l)}function ft(s,a){return a}function Td(s,a,t){var m;for(var r=[],l=a.length,c,u=a.length,v=0;v{if(c){if(c.pending.delete(_),c.done.add(_),c.pending.size===0){var x=s.outrogroups;Nr(s,Ji(c.done)),x.delete(c),x.size===0&&(s.outrogroups=null)}}else u-=1},!1)}if(u===0){var f=r.length===0&&t!==null;if(f){var h=t,b=h.parentNode;nd(b),b.append(h),s.items.clear()}Nr(s,a,!f)}else c={pending:new Set(a),done:new Set},((m=s.outrogroups)!=null?m:s.outrogroups=new Set).add(c)}function Nr(s,a,t=!0){var r;if(s.pending.size>0){r=new Set;for(const u of s.pending.values())for(const v of u)r.add(s.items.get(v).e)}for(var l=0;l{var ne=t();return Ur(ne)?ne:ne==null?[]:Ji(ne)}),_,x=new Map,A=!0;function q(ne){se.effect.f&ns||(se.pending.delete(ne),se.fallback=b,Sd(se,_,u,a,r),b!==null&&(_.length===0?b.f&bs?(b.f^=bs,Hn(b,null,u)):el(b):rn(b,()=>{b=null})))}function T(ne){se.pending.delete(ne)}var D=Zr(()=>{_=e(m);for(var ne=_.length,fe=new Set,Q=ot,z=go(),I=0;Ic(u)):(b=ts(()=>c(_n!=null?_n:_n=Ds())),b.f|=bs)),ne>fe.size&&wc(),!A)if(x.set(Q,fe),z){for(const[j,V]of v)fe.has(j)||Q.skip_effect(V.e);Q.oncommit(q),Q.ondiscard(T)}else q(Q);e(m)}),se={effect:D,items:v,pending:x,outrogroups:null,fallback:b};A=!1}function qn(s){for(;s!==null&&!(s.f&_s);)s=s.next;return s}function Sd(s,a,t,r,l){var ee,j,V,oe,R,B,be,Pe,ue;var c=(r&ec)!==0,u=a.length,v=s.items,f=qn(s.effect.first),h,b=null,m,_=[],x=[],A,q,T,D;if(c)for(D=0;D0){var ge=r&Bl&&u===0?t:null;if(c){for(D=0;D{var K,J;if(m!==void 0)for(T of m)(J=(K=T.nodes)==null?void 0:K.a)==null||J.apply()})}function Ed(s,a,t,r,l,c,u,v){var f=u&Zo?u&tc?dn(t):uo(t,!1,!1):null,h=u&Qo?dn(l):null;return{v:f,i:h,e:ts(()=>(c(a,f!=null?f:t,h!=null?h:l,v),()=>{s.delete(r)}))}}function Hn(s,a,t){if(s.nodes)for(var r=s.nodes.start,l=s.nodes.end,c=a&&!(a.f&bs)?a.nodes.start:t;r!==null;){var u=wi(r);if(c.before(r),r===l)return;r=u}}function Os(s,a,t){a===null?s.effect.first=t:a.next=t,t===null?s.effect.last=a:t.prev=a}function wl(s,a,t=!1,r=!1,l=!1,c=!1){var u=s,v="";if(t)var f=s;w(()=>{var x;var h=xt;if(v!==(v=(x=a())!=null?x:"")){if(t){h.nodes=null,f.innerHTML=v,v!==""&&vn(ys(f),f.lastChild);return}if(h.nodes!==null&&(wo(h.nodes.start,h.nodes.end),h.nodes=null),v!==""){var b=r?cc:l?dc:void 0,m=mo(r?"svg":l?"math":"template",b);m.innerHTML=v;var _=r||l?m:m.content;if(vn(ys(_),_.lastChild),r||l)for(;ys(_);)u.before(ys(_));else u.before(_)}}})}function Fs(s,a,t){Ms(()=>{var r=Ts(()=>a(s,t==null?void 0:t())||{});if(r!=null&&r.destroy)return()=>r.destroy()})}function Lo(s){var a,t,r="";if(typeof s=="string"||typeof s=="number")r+=s;else if(typeof s=="object")if(Array.isArray(s)){var l=s.length;for(a=0;a=0;){var v=u+c;(u===0||kl.includes(r[u-1]))&&(v===r.length||kl.includes(r[v]))?r=(u===0?"":r.substring(0,u))+r.substring(v+1):u=v}}return r===""?null:r}function xl(s,a=!1){var t=a?" !important;":";",r="";for(var l of Object.keys(s)){var c=s[l];c!=null&&c!==""&&(r+=" "+l+": "+c+t)}return r}function ur(s){return s[0]!=="-"||s[1]!=="-"?s.toLowerCase():s}function Md(s,a){if(a){var t="",r,l;if(Array.isArray(a)?(r=a[0],l=a[1]):r=a,s){s=String(s).replaceAll(/\s*\/\*.*?\*\/\s*/g,"").trim();var c=!1,u=0,v=!1,f=[];r&&f.push(...Object.keys(r).map(ur)),l&&f.push(...Object.keys(l).map(ur));var h=0,b=-1;const q=s.length;for(var m=0;m{Ro(s,s.__value)});a.observe(s,{childList:!0,subtree:!0,attributes:!0,attributeFilter:["value"]}),er(()=>{a.disconnect()})}function Tl(s,a,t=a){var r=new WeakSet,l=!0;Jr(s,"change",c=>{var h;var u=c?"[selected]":":checked",v;if(s.multiple)v=[].map.call(s.querySelectorAll(u),Jn);else{var f=(h=s.querySelector(u))!=null?h:s.querySelector("option:not([disabled])");v=f&&Jn(f)}t(v),s.__value=v,ot!==null&&r.add(ot)}),Ms(()=>{var c=a();if(s===document.activeElement){var u=ot;if(r.has(u))return}if(Ro(s,c,l),l&&c===void 0){var v=s.querySelector(":checked");v!==null&&(c=Jn(v),t(c))}s.__value=c,l=!1}),Pd(s)}function Jn(s){return"__value"in s?s.__value:s.value}const Dd=Symbol("is custom element"),zd=Symbol("is html"),Id=bc?"progress":"PROGRESS";function sr(s,a){var t=al(s);t.value===(t.value=a!=null?a:void 0)||s.value===a&&(a!==0||s.nodeName!==Id)||(s.value=a!=null?a:"")}function Od(s,a){var t=al(s);t.checked!==(t.checked=a!=null?a:void 0)&&(s.checked=a)}function mt(s,a,t,r){var l=al(s);l[a]!==(l[a]=t)&&(a==="loading"&&(s[mc]=t),t==null?s.removeAttribute(a):typeof t!="string"&&Ld(s).includes(a)?s[a]=t:s.setAttribute(a,t))}function al(s){var a;return(a=s[Pi])!=null?a:s[Pi]={[Dd]:s.nodeName.includes("-"),[zd]:s.namespaceURI===ql}}var Sl=new Map;function Ld(s){var a=s.getAttribute("is")||s.nodeName,t=Sl.get(a);if(t)return t;Sl.set(a,t=[]);for(var r,l=s,c=Element.prototype;c!==l;){r=uc(l);for(var u in r)r[u].set&&u!=="innerHTML"&&u!=="textContent"&&u!=="innerText"&&t.push(u);l=Kl(l)}return t}function We(s,a,t=a){var r=new WeakSet;Jr(s,"input",async l=>{var c=l?s.defaultValue:s.value;if(c=fr(s)?_r(c):c,t(c),ot!==null&&r.add(ot),await pd(),c!==(c=a())){var u=s.selectionStart,v=s.selectionEnd,f=s.value.length;if(s.value=c!=null?c:"",v!==null){var h=s.value.length;u===v&&v===f&&h>f?(s.selectionStart=h,s.selectionEnd=h):(s.selectionStart=u,s.selectionEnd=Math.min(v,h))}}}),Ts(a)==null&&s.value&&(t(fr(s)?_r(s.value):s.value),ot!==null&&r.add(ot)),tr(()=>{var l=a();if(s===document.activeElement){var c=ot;if(r.has(c))return}fr(s)&&l===_r(s.value)||s.type==="date"&&!l&&!s.value||l!==s.value&&(s.value=l!=null?l:"")})}function Xt(s,a,t=a){Jr(s,"change",r=>{var l=r?s.defaultChecked:s.checked;t(l)}),Ts(a)==null&&t(s.checked),tr(()=>{var r=a();s.checked=!!r})}function fr(s){var a=s.type;return a==="number"||a==="range"}function _r(s){return s===""?null:+s}function hr(s,a){return s===a||(s==null?void 0:s[sn])===a}function sl(s={},a,t,r){var l=da.r,c=xt;return Ms(()=>{var u,v;return tr(()=>{u=v,v=[],Ts(()=>{hr(t(...v),s)||(a(s,...v),u&&hr(t(...u),s)&&a(null,...u))})}),()=>{let f=c;for(;f!==l&&f.parent!==null&&f.parent.f&kr;)f=f.parent;const h=()=>{v&&hr(t(...v),s)&&a(null,...v)},b=f.teardown;f.teardown=()=>{h(),b==null||b()}}}),s}function Ct(s,a,t,r){var fe,Q;var l=!Vn||(t&sc)!==0,c=(t&ic)!==0,u=(t&rc)!==0,v=r,f=!0,h=void 0,b=()=>u&&l?(h!=null||(h=Zn(r)),e(h)):(f&&(f=!1,v=u?Ts(r):r),v);let m;if(c){var _=sn in s||gc in s;m=(Q=(fe=wn(s,a))==null?void 0:fe.set)!=null?Q:_&&a in s?z=>s[a]=z:void 0}var x,A=!1;c?[x,A]=Vc(()=>s[a]):x=s[a],x===void 0&&r!==void 0&&(x=b(),m&&(l&&Ec(),m(x)));var q;if(l?q=()=>{var z=s[a];return z===void 0?b():(f=!0,z)}:q=()=>{var z=s[a];return z!==void 0&&(v=void 0),z===void 0?v:z},l&&!(t&nc))return q;if(m){var T=s.$$legacy;return function(z,I){return arguments.length>0?((!l||!I||T||A)&&m(I?q():z),z):q()}}var D=!1,se=(t&ac?Zn:Gr)(()=>(D=!1,q()));c&&e(se);var ne=xt;return function(z,I){if(arguments.length>0){const L=I?e(se):l&&c?yt(z):z;return o(se,L),D=!0,v!==void 0&&(v=L),z}return zs&&D||ne.f&ns?se.v:e(se)}}const Rd="modulepreload",Nd=function(s){return"/"+s},El={},Vd=function(a,t,r){let l=Promise.resolve();if(t&&t.length>0){document.getElementsByTagName("link");const u=document.querySelector("meta[property=csp-nonce]"),v=(u==null?void 0:u.nonce)||(u==null?void 0:u.getAttribute("nonce"));l=Promise.allSettled(t.map(f=>{if(f=Nd(f),f in El)return;El[f]=!0;const h=f.endsWith(".css"),b=h?'[rel="stylesheet"]':"";if(document.querySelector(`link[href="${f}"]${b}`))return;const m=document.createElement("link");if(m.rel=h?"stylesheet":Rd,h||(m.as="script"),m.crossOrigin="",m.href=f,v&&m.setAttribute("nonce",v),document.head.appendChild(m),h)return new Promise((_,x)=>{m.addEventListener("load",_),m.addEventListener("error",()=>x(new Error(`Unable to preload CSS for ${f}`)))})}))}function c(u){const v=new Event("vite:preloadError",{cancelable:!0});if(v.payload=u,window.dispatchEvent(v),!v.defaultPrevented)throw u}return l.then(u=>{for(const v of u||[])v.status==="rejected"&&c(v.reason);return a().catch(c)})},nr="/assets/app_icon-CfHainhY.png";function Fd(s,a,t,r){if(typeof a=="function"?s!==a||!r:!a.has(s))throw new TypeError("Cannot read private member from an object whose class did not declare it");return t==="m"?r:t==="a"?r.call(s):r?r.value:a.get(s)}function Bd(s,a,t,r,l){if(typeof a=="function"?s!==a||!0:!a.has(s))throw new TypeError("Cannot write private member to an object whose class did not declare it");return a.set(s,t),t}var Ni;const ls="__TAURI_TO_IPC_KEY__";function qd(s,a=!1){return window.__TAURI_INTERNALS__.transformCallback(s,a)}async function E(s,a={},t){return window.__TAURI_INTERNALS__.invoke(s,a,t)}class jd{get rid(){return Fd(this,Ni,"f")}constructor(a){Ni.set(this,void 0),Bd(this,Ni,a)}async close(){return E("plugin:resources|close",{rid:this.rid})}}Ni=new WeakMap;var Ha;(function(s){s.WINDOW_RESIZED="tauri://resize",s.WINDOW_MOVED="tauri://move",s.WINDOW_CLOSE_REQUESTED="tauri://close-requested",s.WINDOW_DESTROYED="tauri://destroyed",s.WINDOW_FOCUS="tauri://focus",s.WINDOW_BLUR="tauri://blur",s.WINDOW_SCALE_FACTOR_CHANGED="tauri://scale-change",s.WINDOW_THEME_CHANGED="tauri://theme-changed",s.WINDOW_CREATED="tauri://window-created",s.WINDOW_SUSPENDED="tauri://suspended",s.WINDOW_RESUMED="tauri://resumed",s.WEBVIEW_CREATED="tauri://webview-created",s.DRAG_ENTER="tauri://drag-enter",s.DRAG_OVER="tauri://drag-over",s.DRAG_DROP="tauri://drag-drop",s.DRAG_LEAVE="tauri://drag-leave"})(Ha||(Ha={}));async function No(s,a){window.__TAURI_EVENT_PLUGIN_INTERNALS__.unregisterListener(s,a),await E("plugin:event|unlisten",{event:s,eventId:a})}async function ha(s,a,t){var r;const l=typeof(t==null?void 0:t.target)=="string"?{kind:"AnyLabel",label:t.target}:(r=t==null?void 0:t.target)!==null&&r!==void 0?r:{kind:"Any"};return E("plugin:event|listen",{event:s,target:l,handler:qd(a)}).then(c=>async()=>No(s,c))}async function Ud(s,a,t){return ha(s,r=>{No(s,r.id),a(r)},t)}async function Vo(s,a){await E("plugin:event|emit",{event:s,payload:a})}async function Kd(s,a,t){await E("plugin:event|emit_to",{target:typeof s=="string"?{kind:"AnyLabel",label:s}:s,event:a,payload:t})}const Hd={engine:{backend:"whisper-cpp",whisper_cpp:{model_dir:"",model_size:"tiny",device:"auto",threads:0,language:"auto"},moonshine:{model_size:"base",language:"en"},parakeet:{model_size:"tdt-0.6b-v3",language:"auto"},remote_openai:{endpoint:"http://localhost:8000/v1",api_key:null,model:"whisper-1",language:"",timeout_secs:30},s1_mini:{enabled:!1,styling:"semi-formal"}},audio:{vad_threshold:.5,input_device_index:null,evdev_device:null,noise_suppression:!1,gain:1,dynamic_stream:!0},ui:{show_overlay:!0,overlay_style:"mono_bars",overlay_position:"center",overlay_monitor:"primary",auto_show_settings:!1,show_notification:!1,show_command_overlay:!0,command_overlay_duration_secs:3},features:{remove_fillers:!0,custom_vocabulary:["VoxCtrl","Hey Vox"],spoken_punctuation:!0,auto_format_lists:!0,snippets:{},early_command_detection:!0},openai:{enabled:!1,model:"llama3.2:1b",mode:"clean",custom_prompt:null,system_prompt:"Fix grammar and punctuation only. Return only the corrected text, no commentary.",user_prompt:"{text}",endpoint:"http://localhost:11434",api_key:null,timeout_secs:8},tts:{enabled:!1,engine:"espeak",voice:"en-us-lessac-medium",voice_dir:"",stop_key:["KEY_ESCAPE"],response_overlay:!0,speed:1,gpu:!1,hf_token:null,pocket_tts:{voice:"alba",prewarm:!1,voice_dir:"",gpu:!1},inflect_micro:{model_dir:"",seed:0,noise_scale:.667,prewarm:!1},breeze_tts_2:{voice_mode:"prompt",cloned_voice:"alba",speaker_prompt:"A calm and clear female voice speaking at a natural pace",model_dir:"",prewarm:!1,gpu:!1},vox_cpm_2:{voice_mode:"prompt",cloned_voice:"alba",voice_dir:"",speaker_prompt:"A calm young female voice speaking clearly with a gentle tone.",ultimate_cloning:!1,model_dir:"",prewarm:!1,gpu:!1},memory_mode:"always_loaded",idle_unload_secs:900,snippets:{VoxCtrl:"Vox Control"}},mcp:{server_enabled:!1,record_timeout:15,visual_feedback:!0}},Ot=bi(Hd),Ss=bi(!1),Ki=bi(!1);let ei=!1,gr=null;async function Wd(){try{const s=await E("get_config");Ot.set(s),Ss.set(!1),Ki.set(!0),setTimeout(()=>{ei=!0},0)}catch(s){console.error("loadConfig:",s),Ki.set(!0),setTimeout(()=>{ei=!0},0)}}async function nl(s){await E("save_config",{newConfig:s}),Ss.set(!1)}Ot.subscribe(s=>{ei&&(gr&&clearTimeout(gr),gr=setTimeout(async()=>{try{await nl(s),console.log("Config auto-saved successfully!")}catch(a){console.error("Auto-saving config failed:",a)}},400))});Wd();ha("config-changed",s=>{ei=!1,Ot.set(s.payload),setTimeout(()=>{ei=!0},0)}).catch(s=>{console.error("Failed to setup config-changed listener:",s)});const ga=bi({recording:!1,processing:!1,speaking:!1,mcp_recording:!1,audio_ready:!0,word_count:0,active_target_id:"default",active_target_label:"Focused Window"}),$d=yi(ga,s=>s.recording),Gd=yi(ga,s=>s.speaking),Yd=yi(ga,s=>s.mcp_recording);yi(ga,s=>s.word_count);yi(ga,s=>{var a;return(a=s.active_target_label)!=null?a:"Focused Window"});let Fo=0;ha("status-tick",s=>{Fo=Date.now(),ga.set(s.payload)});E("get_status").then(ga.set).catch(console.error);const Jd=2e3,Xd=1e3;setInterval(()=>{Date.now()-Fo{})},Xd);var Zd=p('
'),Qd=p(`
Using the HF_TOKEN environment variable. It takes precedence over a saved
+var Yo=Object.defineProperty;var vl=s=>{throw TypeError(s)};var $o=(s,a,t)=>a in s?Yo(s,a,{enumerable:!0,configurable:!0,writable:!0,value:t}):s[a]=t;var Va=(s,a,t)=>$o(s,typeof a!="symbol"?a+"":a,t),or=(s,a,t)=>a.has(s)||vl("Cannot "+t);var F=(s,a,t)=>(or(s,a,"read from private field"),t?t.call(s):a.get(s)),lt=(s,a,t)=>a.has(s)?vl("Cannot add the same private member more than once"):a instanceof WeakSet?a.add(s):a.set(s,t),_t=(s,a,t,r)=>(or(s,a,"write to private field"),r?r.call(s,t):a.set(s,t),t),Vt=(s,a,t)=>(or(s,a,"access private method"),t);(function(){const a=document.createElement("link").relList;if(a&&a.supports&&a.supports("modulepreload"))return;for(const l of document.querySelectorAll('link[rel="modulepreload"]'))r(l);new MutationObserver(l=>{for(const c of l)if(c.type==="childList")for(const u of c.addedNodes)u.tagName==="LINK"&&u.rel==="modulepreload"&&r(u)}).observe(document,{childList:!0,subtree:!0});function t(l){const c={};return l.integrity&&(c.integrity=l.integrity),l.referrerPolicy&&(c.referrerPolicy=l.referrerPolicy),l.crossOrigin==="use-credentials"?c.credentials="include":l.crossOrigin==="anonymous"?c.credentials="omit":c.credentials="same-origin",c}function r(l){if(l.ep)return;l.ep=!0;const c=t(l);fetch(l.href,c)}})();const Go="5";var Ll,Rl,Nl;typeof window<"u"&&((Nl=(Rl=(Ll=window.__svelte)!=null?Ll:window.__svelte={}).v)!=null?Nl:Rl.v=new Set).add(Go);let Vn=!1,Jo=!1;function Xo(){Vn=!0}Xo();const Zo=1,Qo=2,Bl=4,ec=8,tc=16,ac=1,sc=2,nc=4,ic=8,rc=16,lc=1,oc=2,ba=Symbol("uninitialized"),ql="http://www.w3.org/1999/xhtml",cc="http://www.w3.org/2000/svg",dc="http://www.w3.org/1998/Math/MathML",Kl=!1;var Ur=Array.isArray,vc=Array.prototype.indexOf,zn=Array.prototype.includes,Ji=Array.from,Ul=Object.defineProperty,wn=Object.getOwnPropertyDescriptor,uc=Object.getOwnPropertyDescriptors,pc=Object.prototype,fc=Array.prototype,jl=Object.getPrototypeOf,ul=Object.isExtensible;const As=()=>{};function Hl(s){for(var a=0;a{s=r,a=l});return{promise:t,resolve:s,reject:a}}function pl(s,a){if(Array.isArray(s))return s;if(!(Symbol.iterator in s))return Array.from(s);const t=[];for(const r of s)if(t.push(r),t.length===a)break;return t}const Pa=2,In=4,Xi=8,Yl=1<<24,us=16,_s=32,Us=64,wr=128,ss=512,ya=1024,Sa=2048,ws=4096,Na=8192,ns=16384,un=32768,kr=1<<25,On=65536,Bi=1<<17,_c=1<<18,Fn=1<<19,hc=1<<20,bs=1<<25,on=65536,qi=1<<21,kn=1<<22,Bs=1<<23,sn=Symbol("$state"),gc=Symbol("legacy props"),mc=Symbol(""),Ai=Symbol("attributes"),xr=Symbol("class"),Tr=Symbol("style"),Kn=Symbol("text"),Di=Symbol("form reset"),Zi=new class extends Error{constructor(){super(...arguments);Va(this,"name","StaleReactionError");Va(this,"message","The reaction that called `getAbortSignal()` was re-run or destroyed")}};var Vl;const bc=!!((Vl=globalThis.document)!=null&&Vl.contentType)&&globalThis.document.contentType.includes("xml");function $l(s){throw new Error("https://svelte.dev/e/lifecycle_outside_component")}function yc(){throw new Error("https://svelte.dev/e/async_derived_orphan")}function wc(s,a,t){throw new Error("https://svelte.dev/e/each_key_duplicate")}function kc(s){throw new Error("https://svelte.dev/e/effect_in_teardown")}function xc(){throw new Error("https://svelte.dev/e/effect_in_unowned_derived")}function Tc(s){throw new Error("https://svelte.dev/e/effect_orphan")}function Sc(){throw new Error("https://svelte.dev/e/effect_update_depth_exceeded")}function Ec(s){throw new Error("https://svelte.dev/e/props_invalid_value")}function Cc(){throw new Error("https://svelte.dev/e/state_descriptors_fixed")}function Mc(){throw new Error("https://svelte.dev/e/state_prototype_fixed")}function Pc(){throw new Error("https://svelte.dev/e/state_unsafe_mutation")}function Ac(){throw new Error("https://svelte.dev/e/svelte_boundary_reset_onerror")}function Dc(){console.warn("https://svelte.dev/e/derived_inert")}function zc(){console.warn("https://svelte.dev/e/select_multiple_invalid_value")}function Ic(){console.warn("https://svelte.dev/e/svelte_boundary_reset_noop")}function Gl(s){return s===this.v}function Jl(s,a){return s!=s?a==a:s!==a||s!==null&&typeof s=="object"||typeof s=="function"}function Xl(s){return!Jl(s,this.v)}let da=null;function Ln(s){da=s}function Tt(s,a=!1,t){da={p:da,i:!1,c:null,e:null,s,x:null,r:xt,l:Vn&&!a?{s:null,u:null,$:[]}:null}}function St(s){var a=da,t=a.e;if(t!==null){a.e=null;for(var r of t)bo(r)}return a.i=!0,da=a.p,{}}function mi(){return!Vn||da!==null&&da.l===null}let Gs=[];function Zl(){var s=Gs;Gs=[],Hl(s)}function qs(s){if(Gs.length===0&&!$n){var a=Gs;queueMicrotask(()=>{a===Gs&&Zl()})}Gs.push(s)}function Oc(){for(;Gs.length>0;)Zl()}function Ql(s){var a=xt;if(a===null)return At.f|=Bs,s;if(!(a.f&un)&&!(a.f&In))throw s;Vs(s,a)}function Vs(s,a){for(;a!==null;){if(a.f&wr){if(!(a.f&un))throw s;try{a.b.error(s);return}catch(t){s=t}}a=a.parent}throw s}const Lc=-7169;function ca(s,a){s.f=s.f&Lc|a}function jr(s){s.f&ss||s.deps===null?ca(s,ya):ca(s,ws)}function eo(s){if(s!==null)for(const a of s)!(a.f&Pa)||!(a.f&on)||(a.f^=on,eo(a.deps))}function to(s,a,t){s.f&Sa?a.add(s):s.f&ws&&t.add(s),eo(s.deps),ca(s,ya)}function Hr(s,a,t){if(s==null)return a(void 0),t&&t(void 0),As;const r=Ts(()=>s.subscribe(a,t));return r.unsubscribe?()=>r.unsubscribe():r}const pn=[];function Rc(s,a){return{subscribe:bi(s,a).subscribe}}function bi(s,a=As){let t=null;const r=new Set;function l(v){if(Jl(s,v)&&(s=v,t)){const f=!pn.length;for(const h of r)h[1](),pn.push(h,s);if(f){for(let h=0;h{r.delete(h),r.size===0&&t&&(t(),t=null)}}return{set:l,update:c,subscribe:u}}function yi(s,a,t){const r=!Array.isArray(s),l=r?[s]:s;if(!l.every(Boolean))throw new Error("derived() expects stores as input, got a falsy value");const c=a.length<2;return Rc(t,(u,v)=>{let f=!1;const h=[];let b=0,m=As;const _=()=>{if(b)return;m();const M=a(r?h[0]:h,u,v);c?u(M):m=typeof M=="function"?M:As},x=l.map((M,q)=>Hr(M,T=>{h[q]=T,b&=~(1<{b|=1<a=t)(),a}let Sr=!1,Un=!1,Er=Symbol("unmounted");function Zt(s,a,t){var c;const r=(c=t[a])!=null?c:t[a]={store:null,source:uo(void 0),unsubscribe:As};if(r.store!==s&&!(Er in t))if(r.unsubscribe(),r.store=s!=null?s:null,s==null)r.source.v=void 0,r.unsubscribe=As;else{var l=!0;r.unsubscribe=Hr(s,u=>{l?r.source.v=u:o(r.source,u)}),l=!1}return s&&Er in t?bn(s):e(r.source)}function Ws(s,a){return Nc(s,a),a}function Ea(){const s={};function a(){er(()=>{for(var t in s)s[t].unsubscribe();Ul(s,Er,{enumerable:!1,value:!0})})}return[s,a]}function Nc(s,a){Sr=!0;try{s.set(a)}finally{Sr=!1}}function Ys(){Un=!0}function Vc(s){var a=Un;try{return Un=!1,[s(),Un]}finally{Un=a}}let cr=null,fn=null,ot=null,Yn=null,Ma=null,Cr=null,$n=!1,dr=!1,yn=null,zi=null;var fl=0;let Fc=1;var Sn,Ls,Zs,En,Cn,Qs,Mn,Es,ti,Wa,ai,Rs,hs,gs,Pn,An,Bt,Mr,jn,Pr,ao,so,Ii,Bc,Ar,gn;const Yi=class Yi{constructor(){lt(this,Bt);Va(this,"id",Fc++);lt(this,Sn,!1);Va(this,"linked",!0);lt(this,Ls,null);lt(this,Zs,null);Va(this,"async_deriveds",new Map);Va(this,"current",new Map);Va(this,"previous",new Map);Va(this,"unblocked",new Set);lt(this,En,new Set);lt(this,Cn,new Set);lt(this,Qs,new Set);lt(this,Mn,0);lt(this,Es,new Map);lt(this,ti,null);lt(this,Wa,[]);lt(this,ai,[]);lt(this,Rs,new Set);lt(this,hs,new Set);lt(this,gs,new Map);lt(this,Pn,new Set);Va(this,"is_fork",!1);lt(this,An,!1)}skip_effect(a){F(this,gs).has(a)||F(this,gs).set(a,{d:[],m:[]}),F(this,Pn).delete(a)}unskip_effect(a,t=r=>this.schedule(r)){var r=F(this,gs).get(a);if(r){F(this,gs).delete(a);for(var l of r.d)ca(l,Sa),t(l);for(l of r.m)ca(l,ws),t(l)}F(this,Pn).add(a)}capture(a,t,r=!1){a.v!==ba&&!this.previous.has(a)&&this.previous.set(a,a.v),a.f&Bs||(this.current.set(a,[t,r]),Ma==null||Ma.set(a,t)),this.is_fork||(a.v=t)}activate(){ot=this}deactivate(){ot=null,Ma=null}flush(){try{dr=!0,ot=this,Vt(this,Bt,jn).call(this)}finally{fl=0,Cr=null,yn=null,zi=null,dr=!1,ot=null,Ma=null,nn.clear()}}discard(){for(const a of F(this,Cn))a(this);F(this,Cn).clear(),F(this,Qs).clear(),Vt(this,Bt,gn).call(this)}register_created_effect(a){F(this,ai).push(a)}increment(a,t){var r;if(_t(this,Mn,F(this,Mn)+1),a){let l=(r=F(this,Es).get(t))!=null?r:0;F(this,Es).set(t,l+1)}}decrement(a,t){var r;if(_t(this,Mn,F(this,Mn)-1),a){let l=(r=F(this,Es).get(t))!=null?r:0;l===1?F(this,Es).delete(t):F(this,Es).set(t,l-1)}F(this,An)||(_t(this,An,!0),qs(()=>{_t(this,An,!1),this.linked&&this.flush()}))}transfer_effects(a,t){for(const r of a)F(this,Rs).add(r);for(const r of t)F(this,hs).add(r);a.clear(),t.clear()}oncommit(a){F(this,En).add(a)}ondiscard(a){F(this,Cn).add(a)}on_fork_commit(a){F(this,Qs).add(a)}run_fork_commit_callbacks(){for(const a of F(this,Qs))a(this);F(this,Qs).clear()}settled(){var a;return((a=F(this,ti))!=null?a:_t(this,ti,Wl())).promise}static ensure(){var a;if(ot===null){const t=ot=new Yi;Vt(a=t,Bt,Ar).call(a),!dr&&!$n&&qs(()=>{F(t,Sn)||t.flush()})}return ot}apply(){{Ma=null;return}}schedule(a){var l;if(Cr=a,(l=a.b)!=null&&l.is_pending&&a.f&(In|Xi|Yl)&&!(a.f&un)){a.b.defer_effect(a);return}for(var t=a;t.parent!==null;){t=t.parent;var r=t.f;if(yn!==null&&t===xt&&(At===null||!(At.f&Pa))&&!Sr)return;if(r&(Us|_s)){if(!(r&ya))return;t.f^=ya}}F(this,Wa).push(t)}};Sn=new WeakMap,Ls=new WeakMap,Zs=new WeakMap,En=new WeakMap,Cn=new WeakMap,Qs=new WeakMap,Mn=new WeakMap,Es=new WeakMap,ti=new WeakMap,Wa=new WeakMap,ai=new WeakMap,Rs=new WeakMap,hs=new WeakMap,gs=new WeakMap,Pn=new WeakMap,An=new WeakMap,Bt=new WeakSet,Mr=function(){if(this.is_fork)return!0;for(const r of F(this,Es).keys()){for(var a=r,t=!1;a.parent!==null;){if(F(this,gs).has(a)){t=!0;break}a=a.parent}if(!t)return!0}return!1},jn=function(){var f,h,b,m;if(_t(this,Sn,!0),fl++>1e3&&(Vt(this,Bt,gn).call(this),Kc()),!Vt(this,Bt,Mr).call(this)){for(const _ of F(this,Rs))F(this,hs).delete(_),ca(_,Sa),this.schedule(_);for(const _ of F(this,hs))ca(_,ws),this.schedule(_)}const a=F(this,Wa);_t(this,Wa,[]),this.apply();var t=yn=[],r=[],l=zi=[];for(const _ of a)try{Vt(this,Bt,Pr).call(this,_,t,r)}catch(x){throw ro(_),x}if(ot=null,l.length>0){var c=Yi.ensure();for(const _ of l)c.schedule(_)}if(yn=null,zi=null,Vt(this,Bt,Mr).call(this)){Vt(this,Bt,Ii).call(this,r),Vt(this,Bt,Ii).call(this,t);for(const[_,x]of F(this,gs))io(_,x);l.length>0&&Vt(f=ot,Bt,jn).call(f);return}const u=Vt(this,Bt,ao).call(this);if(u){Vt(h=u,Bt,so).call(h,this);return}F(this,Rs).clear(),F(this,hs).clear();for(const _ of F(this,En))_(this);F(this,En).clear(),Yn=this,_l(r),_l(t),Yn=null,(b=F(this,ti))==null||b.resolve();var v=ot;if(this.linked&&F(this,Mn)===0&&Vt(this,Bt,gn).call(this),F(this,Wa).length>0){v===null&&(v=this,Vt(this,Bt,Ar).call(this));const _=v;F(_,Wa).push(...F(this,Wa).filter(x=>!F(_,Wa).includes(x)))}v!==null&&Vt(m=v,Bt,jn).call(m)},Pr=function(a,t,r){a.f^=ya;for(var l=a.first;l!==null;){var c=l.f,u=(c&(_s|Us))!==0,v=u&&(c&ya)!==0,f=v||(c&Na)!==0||F(this,gs).has(l);if(!f&&l.fn!==null){u?l.f^=ya:c&In?t.push(l):ki(l)&&(c&us&&F(this,hs).add(l),Nn(l));var h=l.first;if(h!==null){l=h;continue}}for(;l!==null;){var b=l.next;if(b!==null){l=b;break}l=l.parent}}},ao=function(){for(var a=F(this,Ls);a!==null;){if(!a.is_fork){for(const[t,[,r]]of this.current)if(a.current.has(t)&&!r)return a}a=F(a,Ls)}return null},so=function(a){var r;for(const[l,c]of a.current)!this.previous.has(l)&&a.previous.has(l)&&this.previous.set(l,a.previous.get(l)),this.current.set(l,c);for(const[l,c]of a.async_deriveds){const u=this.async_deriveds.get(l);u&&c.promise.then(u.resolve)}const t=l=>{var c=l.reactions;if(c!==null)for(const f of c){var u=f.f;if(u&Pa)t(f);else{var v=f;u&(kn|us)&&!this.async_deriveds.has(v)&&(F(this,hs).delete(v),ca(v,Sa),this.schedule(v))}}};for(const l of this.current.keys())t(l);this.oncommit(()=>a.discard()),Vt(r=a,Bt,gn).call(r),ot=this,Vt(this,Bt,jn).call(this)},Ii=function(a){for(var t=0;t!this.current.has(_));if(l.length===0)a&&m.discard();else if(t.length>0){if(a)for(const _ of F(this,Pn))m.unskip_effect(_,x=>{var M;x.f&(us|kn)?m.schedule(x):Vt(M=m,Bt,Ii).call(M,[x])});m.activate();var c=new Set,u=new Map;for(var v of t)no(v,l,c,u);u=new Map;var f=[...m.current.keys()].filter(_=>this.current.has(_)?this.current.get(_)[0]!==_.v:!0);if(f.length>0)for(const _ of F(this,ai))!(_.f&(ns|Na|Bi))&&Wr(_,f,u)&&(_.f&(kn|us)?(ca(_,Sa),m.schedule(_)):F(m,Rs).add(_));if(F(m,Wa).length>0){m.apply();for(var h of F(m,Wa))Vt(b=m,Bt,Pr).call(b,h,[],[]);_t(m,Wa,[])}m.deactivate()}}}},Ar=function(){fn===null?cr=fn=this:(_t(fn,Zs,this),_t(this,Ls,fn)),fn=this},gn=function(){var a=F(this,Ls),t=F(this,Zs);a===null?cr=t:_t(a,Zs,t),t===null?fn=a:_t(t,Ls,a),this.linked=!1};let cn=Yi;function qc(s){var a=$n;$n=!0;try{for(var t;;){if(Oc(),ot===null)return t;ot.flush()}}finally{$n=a}}function Kc(){try{Sc()}catch(s){Vs(s,Cr)}}let os=null;function _l(s){var a=s.length;if(a!==0){for(var t=0;t0)){nn.clear();for(const l of os){if(l.f&(ns|Na))continue;const c=[l];let u=l.parent;for(;u!==null;)os.has(u)&&(os.delete(u),c.push(u)),u=u.parent;for(let v=c.length-1;v>=0;v--){const f=c[v];f.f&(ns|Na)||Nn(f)}}os.clear()}}os=null}}function no(s,a,t,r){if(!t.has(s)&&(t.add(s),s.reactions!==null))for(const l of s.reactions){const c=l.f;c&Pa?no(l,a,t,r):c&(kn|us)&&!(c&Sa)&&Wr(l,a,r)&&(ca(l,Sa),Yr(l))}}function Wr(s,a,t){const r=t.get(s);if(r!==void 0)return r;if(s.deps!==null)for(const l of s.deps){if(zn.call(a,l))return!0;if(l.f&Pa&&Wr(l,a,t))return t.set(l,!0),!0}return t.set(s,!1),!1}function Yr(s){ot.schedule(s)}function io(s,a){if(!(s.f&_s&&s.f&ya)){s.f&Sa?a.d.push(s):s.f&ws&&a.m.push(s),ca(s,ya);for(var t=s.first;t!==null;)io(t,a),t=t.next}}function ro(s){ca(s,ya);for(var a=s.first;a!==null;)ro(a),a=a.next}function Uc(s){let a=0,t=dn(0),r;return()=>{Xr()&&(e(t),tr(()=>(a===0&&(r=Ts(()=>s(()=>Gn(t)))),a+=1,()=>{qs(()=>{a-=1,a===0&&(r==null||r(),r=void 0,Gn(t))})})))}}var jc=On|Fn;function Hc(s,a,t,r){new Wc(s,a,t,r)}var Za,Kr,Qa,en,Fa,es,Ra,Ya,Cs,tn,Ns,Dn,si,ni,Ms,$i,va,Yc,$c,Gc,Dr,Oi,Li,zr,Ir;class Wc{constructor(a,t,r,l){lt(this,va);Va(this,"parent");Va(this,"is_pending",!1);Va(this,"transform_error");lt(this,Za);lt(this,Kr,null);lt(this,Qa);lt(this,en);lt(this,Fa);lt(this,es,null);lt(this,Ra,null);lt(this,Ya,null);lt(this,Cs,null);lt(this,tn,0);lt(this,Ns,0);lt(this,Dn,!1);lt(this,si,new Set);lt(this,ni,new Set);lt(this,Ms,null);lt(this,$i,Uc(()=>(_t(this,Ms,dn(F(this,tn))),()=>{_t(this,Ms,null)})));var c,u;_t(this,Za,a),_t(this,Qa,t),_t(this,en,v=>{var f=xt;f.b=this,f.f|=wr,r(v)}),this.parent=xt.b,this.transform_error=(u=l!=null?l:(c=this.parent)==null?void 0:c.transform_error)!=null?u:v=>v,_t(this,Fa,Zr(()=>{Vt(this,va,Dr).call(this)},jc))}defer_effect(a){to(a,F(this,si),F(this,ni))}is_rendered(){return!this.is_pending&&(!this.parent||this.parent.is_rendered())}has_pending_snippet(){return!!F(this,Qa).pending}update_pending_count(a,t){Vt(this,va,zr).call(this,a,t),_t(this,tn,F(this,tn)+a),!(!F(this,Ms)||F(this,Dn))&&(_t(this,Dn,!0),qs(()=>{_t(this,Dn,!1),F(this,Ms)&&Rn(F(this,Ms),F(this,tn))}))}get_effect_pending(){return F(this,$i).call(this),e(F(this,Ms))}error(a){if(!F(this,Qa).onerror&&!F(this,Qa).failed)throw a;ot!=null&&ot.is_fork?(F(this,es)&&ot.skip_effect(F(this,es)),F(this,Ra)&&ot.skip_effect(F(this,Ra)),F(this,Ya)&&ot.skip_effect(F(this,Ya)),ot.on_fork_commit(()=>{Vt(this,va,Ir).call(this,a)})):Vt(this,va,Ir).call(this,a)}}Za=new WeakMap,Kr=new WeakMap,Qa=new WeakMap,en=new WeakMap,Fa=new WeakMap,es=new WeakMap,Ra=new WeakMap,Ya=new WeakMap,Cs=new WeakMap,tn=new WeakMap,Ns=new WeakMap,Dn=new WeakMap,si=new WeakMap,ni=new WeakMap,Ms=new WeakMap,$i=new WeakMap,va=new WeakSet,Yc=function(){try{_t(this,es,ts(()=>F(this,en).call(this,F(this,Za))))}catch(a){this.error(a)}},$c=function(a){const t=F(this,Qa).failed;t&&_t(this,Ya,ts(()=>{t(F(this,Za),()=>a,()=>()=>{})}))},Gc=function(){const a=F(this,Qa).pending;a&&(this.is_pending=!0,_t(this,Ra,ts(()=>a(F(this,Za)))),qs(()=>{var t=_t(this,Cs,document.createDocumentFragment()),r=Ds();t.append(r),_t(this,es,Vt(this,va,Li).call(this,()=>ts(()=>F(this,en).call(this,r)))),F(this,Ns)===0&&(F(this,Za).before(t),_t(this,Cs,null),rn(F(this,Ra),()=>{_t(this,Ra,null)}),Vt(this,va,Oi).call(this,ot))}))},Dr=function(){try{if(this.is_pending=this.has_pending_snippet(),_t(this,Ns,0),_t(this,tn,0),_t(this,es,ts(()=>{F(this,en).call(this,F(this,Za))})),F(this,Ns)>0){var a=_t(this,Cs,document.createDocumentFragment());tl(F(this,es),a);const t=F(this,Qa).pending;_t(this,Ra,ts(()=>t(F(this,Za))))}else Vt(this,va,Oi).call(this,ot)}catch(t){this.error(t)}},Oi=function(a){this.is_pending=!1,a.transfer_effects(F(this,si),F(this,ni))},Li=function(a){var t=xt,r=At,l=da;ks(F(this,Fa)),rs(F(this,Fa)),Ln(F(this,Fa).ctx);try{return cn.ensure(),a()}catch(c){return Ql(c),null}finally{ks(t),rs(r),Ln(l)}},zr=function(a,t){var r;if(!this.has_pending_snippet()){this.parent&&Vt(r=this.parent,va,zr).call(r,a,t);return}_t(this,Ns,F(this,Ns)+a),F(this,Ns)===0&&(Vt(this,va,Oi).call(this,t),F(this,Ra)&&rn(F(this,Ra),()=>{_t(this,Ra,null)}),F(this,Cs)&&(F(this,Za).before(F(this,Cs)),_t(this,Cs,null)))},Ir=function(a){F(this,es)&&(qa(F(this,es)),_t(this,es,null)),F(this,Ra)&&(qa(F(this,Ra)),_t(this,Ra,null)),F(this,Ya)&&(qa(F(this,Ya)),_t(this,Ya,null));var t=F(this,Qa).onerror;let r=F(this,Qa).failed;var l=!1,c=!1;const u=()=>{if(l){Ic();return}l=!0,c&&Ac(),F(this,Ya)!==null&&rn(F(this,Ya),()=>{_t(this,Ya,null)}),Vt(this,va,Li).call(this,()=>{Vt(this,va,Dr).call(this)})},v=f=>{try{c=!0,t==null||t(f,u),c=!1}catch(h){Vs(h,F(this,Fa)&&F(this,Fa).parent)}r&&_t(this,Ya,Vt(this,va,Li).call(this,()=>{try{return ts(()=>{var h=xt;h.b=this,h.f|=wr,r(F(this,Za),()=>f,()=>u)})}catch(h){return Vs(h,F(this,Fa).parent),null}}))};qs(()=>{var f;try{f=this.transform_error(a)}catch(h){Vs(h,F(this,Fa)&&F(this,Fa).parent);return}f!==null&&typeof f=="object"&&typeof f.then=="function"?f.then(v,h=>Vs(h,F(this,Fa)&&F(this,Fa).parent)):v(f)})};function Jc(s,a,t,r){const l=mi()?Zn:$r;var c=s.filter(_=>!_.settled);if(t.length===0&&c.length===0){r(a.map(l));return}var u=xt,v=Xc(),f=c.length===1?c[0].promise:c.length>1?Promise.all(c.map(_=>_.promise)):null;function h(_){if(!(u.f&ns)){v();try{r(_)}catch(x){Vs(x,u)}Ki()}}var b=lo();if(t.length===0){f.then(()=>h(a.map(l))).finally(b);return}function m(){Promise.all(t.map(_=>Zc(_))).then(_=>h([...a.map(l),..._])).catch(_=>Vs(_,u)).finally(b)}f?f.then(()=>{v(),m(),Ki()}):m()}function Xc(){var s=xt,a=At,t=da,r=ot;return function(c=!0){ks(s),rs(a),Ln(t),c&&!(s.f&ns)&&(r==null||r.activate(),r==null||r.apply())}}function Ki(s=!0){ks(null),rs(null),Ln(null),s&&(ot==null||ot.deactivate())}function lo(){var s=xt,a=s.b,t=ot,r=a.is_rendered();return a.update_pending_count(1,t),t.increment(r,s),()=>{a.update_pending_count(-1,t),t.decrement(r,s)}}function Zn(s){var a=Pa|Sa;return xt!==null&&(xt.f|=Fn),{ctx:da,deps:null,effects:null,equals:Gl,f:a,fn:s,reactions:null,rv:0,v:ba,wv:0,parent:xt,ac:null}}const Si=Symbol("obsolete");function Zc(s,a,t){let r=xt;r===null&&yc();var l=void 0,c=dn(ba),u=!At,v=new Set;return cd(()=>{var x;var f=xt,h=Wl();l=h.promise;try{Promise.resolve(s()).then(h.resolve,M=>{M!==Zi&&h.reject(M)}).finally(Ki)}catch(M){h.reject(M),Ki()}var b=ot;if(u){if(f.f&un)var m=lo();if(r.b.is_rendered())(x=b.async_deriveds.get(f))==null||x.reject(Si);else for(const M of v.values())M.reject(Si);v.add(h),b.async_deriveds.set(f,h)}const _=(M,q=void 0)=>{m==null||m(),v.delete(h),q!==Si&&(b.activate(),q?(c.f|=Bs,Rn(c,q)):(c.f&Bs&&(c.f^=Bs),Rn(c,M)),b.deactivate())};h.promise.then(_,M=>_(null,M||"unknown"))}),er(()=>{for(const f of v)f.reject(Si)}),new Promise(f=>{function h(b){function m(){b===l?f(c):h(l)}b.then(m,m)}h(l)})}function ce(s){const a=Zn(s);return So(a),a}function $r(s){const a=Zn(s);return a.equals=Xl,a}function Qc(s){var a=s.effects;if(a!==null){s.effects=null;for(var t=0;t0&&!vo&&td()}return a}function td(){vo=!1;for(const s of Ui){s.f&ya&&ca(s,ws);let a;try{a=ki(s)}catch{a=!0}a&&Nn(s)}Ui.clear()}function Gn(s){o(s,s.v+1)}function po(s,a,t){var r=s.reactions;if(r!==null)for(var l=mi(),c=r.length,u=0;u{if(ln===c)return v();var f=At,h=ln;rs(null),bl(c);var b=v();return rs(f),bl(h),b};return r&&t.set("length",S(s.length)),new Proxy(s,{defineProperty(v,f,h){(!("value"in h)||h.configurable===!1||h.enumerable===!1||h.writable===!1)&&Cc();var b=t.get(f);return b===void 0?u(()=>{var m=S(h.value);return t.set(f,m),m}):o(b,h.value,!0),!0},deleteProperty(v,f){var h=t.get(f);if(h===void 0){if(f in v){const b=u(()=>S(ba));t.set(f,b),Gn(l)}}else o(h,ba),Gn(l);return!0},get(v,f,h){var x;if(f===sn)return s;var b=t.get(f),m=f in v;if(b===void 0&&(!m||(x=wn(v,f))!=null&&x.writable)&&(b=u(()=>{var M=yt(m?v[f]:ba),q=S(M);return q}),t.set(f,b)),b!==void 0){var _=e(b);return _===ba?void 0:_}return Reflect.get(v,f,h)},getOwnPropertyDescriptor(v,f){var h=Reflect.getOwnPropertyDescriptor(v,f);if(h&&"value"in h){var b=t.get(f);b&&(h.value=e(b))}else if(h===void 0){var m=t.get(f),_=m==null?void 0:m.v;if(m!==void 0&&_!==ba)return{enumerable:!0,configurable:!0,value:_,writable:!0}}return h},has(v,f){var _;if(f===sn)return!0;var h=t.get(f),b=h!==void 0&&h.v!==ba||Reflect.has(v,f);if(h!==void 0||xt!==null&&(!b||(_=wn(v,f))!=null&&_.writable)){h===void 0&&(h=u(()=>{var x=b?yt(v[f]):ba,M=S(x);return M}),t.set(f,h));var m=e(h);if(m===ba)return!1}return b},set(v,f,h,b){var ne;var m=t.get(f),_=f in v;if(r&&f==="length")for(var x=h;xS(ba)),t.set(x+"",M))}if(m===void 0)(!_||(ne=wn(v,f))!=null&&ne.writable)&&(m=u(()=>S(void 0)),o(m,yt(h)),t.set(f,m));else{_=m.v!==ba;var q=u(()=>yt(h));o(m,q)}var T=Reflect.getOwnPropertyDescriptor(v,f);if(T!=null&&T.set&&T.set.call(b,h),!_){if(r&&typeof f=="string"){var D=t.get("length"),se=Number(f);Number.isInteger(se)&&se>=D.v&&o(D,se+1)}Gn(l)}return!0},ownKeys(v){e(l);var f=Reflect.ownKeys(v).filter(m=>{var _=t.get(m);return _===void 0||_.v!==ba});for(var[h,b]of t)b.v!==ba&&!(h in v)&&f.push(h);return f},setPrototypeOf(){Mc()}})}function hl(s){try{if(s!==null&&typeof s=="object"&&sn in s)return s[sn]}catch{}return s}function ad(s,a){return Object.is(hl(s),hl(a))}var Or,fo,_o,ho;function sd(){if(Or===void 0){Or=window,fo=/Firefox/.test(navigator.userAgent);var s=Element.prototype,a=Node.prototype,t=Text.prototype;_o=wn(a,"firstChild").get,ho=wn(a,"nextSibling").get,ul(s)&&(s[xr]=void 0,s[Ai]=null,s[Tr]=void 0,s.__e=void 0),ul(t)&&(t[Kn]=void 0)}}function Ds(s=""){return document.createTextNode(s)}function ys(s){return _o.call(s)}function wi(s){return ho.call(s)}function n(s,a){return ys(s)}function ht(s,a=!1){{var t=ys(s);return t instanceof Comment&&t.data===""?wi(t):t}}function i(s,a=1,t=!1){let r=s;for(;a--;)r=wi(r);return r}function nd(s){s.textContent=""}function go(){return!1}function mo(s,a,t){return document.createElementNS(a!=null?a:ql,s,void 0)}let gl=!1;function id(){gl||(gl=!0,document.addEventListener("reset",s=>{Promise.resolve().then(()=>{var a;if(!s.defaultPrevented)for(const t of s.target.elements)(a=t[Di])==null||a.call(t)})},{capture:!0}))}function Qi(s){var a=At,t=xt;rs(null),ks(null);try{return s()}finally{rs(a),ks(t)}}function Jr(s,a,t,r=t){s.addEventListener(a,()=>Qi(t));const l=s[Di];l?s[Di]=()=>{l(),r(!0)}:s[Di]=()=>r(!0),id()}function rd(s){xt===null&&(At===null&&Tc(),xc()),zs&&kc()}function ld(s,a){var t=a.last;t===null?a.last=a.first=s:(t.next=s,s.prev=t,a.last=s)}function Is(s,a){var u;var t=xt;t!==null&&t.f&Na&&(s|=Na);var r={ctx:da,deps:null,nodes:null,f:s|Sa|ss,first:null,fn:a,last:null,next:null,parent:t,b:t&&t.b,prev:null,teardown:null,wv:0,ac:null};ot==null||ot.register_created_effect(r);var l=r;if(s&In)yn!==null?yn.push(r):cn.ensure().schedule(r);else if(a!==null){try{Nn(r)}catch(v){throw qa(r),v}l.deps===null&&l.teardown===null&&l.nodes===null&&l.first===l.last&&!(l.f&Fn)&&(l=l.first,s&us&&s&On&&l!==null&&(l.f|=On))}if(l!==null&&(l.parent=t,t!==null&&ld(l,t),At!==null&&At.f&Pa&&!(s&Us))){var c=At;((u=c.effects)!=null?u:c.effects=[]).push(l)}return r}function Xr(){return At!==null&&!ps}function er(s){const a=Is(Xi,null);return ca(a,ya),a.teardown=s,a}function pa(s){var l;rd();var a=xt.f,t=!At&&(a&_s)!==0&&(a&un)===0;if(t){var r=da;((l=r.e)!=null?l:r.e=[]).push(s)}else return bo(s)}function bo(s){return Is(In|hc,s)}function od(s){cn.ensure();const a=Is(Us|Fn,s);return(t={})=>new Promise(r=>{t.outro?rn(a,()=>{qa(a),r(void 0)}):(qa(a),r(void 0))})}function Ps(s){return Is(In,s)}function cd(s){return Is(kn|Fn,s)}function tr(s,a=0){return Is(Xi|a,s)}function w(s,a=[],t=[],r=[]){Jc(r,a,t,l=>{Is(Xi,()=>s(...l.map(e)))})}function Zr(s,a=0){var t=Is(us|a,s);return t}function ts(s){return Is(_s|Fn,s)}function yo(s){var a=s.teardown;if(a!==null){const t=zs,r=At;ml(!0),rs(null);try{a.call(null)}finally{ml(t),rs(r)}}}function Qr(s,a=!1){var t=s.first;for(s.first=s.last=null;t!==null;){const l=t.ac;l!==null&&Qi(()=>{l.abort(Zi)});var r=t.next;t.f&Us?t.parent=null:qa(t,a),t=r}}function dd(s){for(var a=s.first;a!==null;){var t=a.next;a.f&_s||qa(a),a=t}}function qa(s,a=!0){var t=!1;(a||s.f&_c)&&s.nodes!==null&&s.nodes.end!==null&&(wo(s.nodes.start,s.nodes.end),t=!0),ca(s,kr),Qr(s,a&&!t),Qn(s,0);var r=s.nodes&&s.nodes.t;if(r!==null)for(const c of r)c.stop();yo(s),s.f^=kr,s.f|=ns;var l=s.parent;l!==null&&l.first!==null&&ko(s),s.next=s.prev=s.teardown=s.ctx=s.deps=s.fn=s.nodes=s.ac=s.b=null}function wo(s,a){for(;s!==null;){var t=s===a?null:wi(s);s.remove(),s=t}}function ko(s){var a=s.parent,t=s.prev,r=s.next;t!==null&&(t.next=r),r!==null&&(r.prev=t),a!==null&&(a.first===s&&(a.first=r),a.last===s&&(a.last=t))}function rn(s,a,t=!0){var r=[];xo(s,r,!0);var l=()=>{t&&qa(s),a&&a()},c=r.length;if(c>0){var u=()=>--c||l();for(var v of r)v.out(u)}else l()}function xo(s,a,t){if(!(s.f&Na)){s.f^=Na;var r=s.nodes&&s.nodes.t;if(r!==null)for(const v of r)(v.is_global||t)&&a.push(v);for(var l=s.first;l!==null;){var c=l.next;if(!(l.f&Us)){var u=(l.f&On)!==0||(l.f&_s)!==0&&(s.f&us)!==0;xo(l,a,u?t:!1)}l=c}}}function el(s){To(s,!0)}function To(s,a){if(s.f&Na){s.f^=Na,s.f&ya||(ca(s,Sa),cn.ensure().schedule(s));for(var t=s.first;t!==null;){var r=t.next,l=(t.f&On)!==0||(t.f&_s)!==0;To(t,l?a:!1),t=r}var c=s.nodes&&s.nodes.t;if(c!==null)for(const u of c)(u.is_global||a)&&u.in()}}function tl(s,a){if(s.nodes)for(var t=s.nodes.start,r=s.nodes.end;t!==null;){var l=t===r?null:wi(t);a.append(t),t=l}}let Ri=!1,zs=!1;function ml(s){zs=s}let At=null,ps=!1;function rs(s){At=s}let xt=null;function ks(s){xt=s}let is=null;function So(s){At!==null&&(is===null?is=[s]:is.push(s))}let Ba=null,ja=0,Xa=null;function vd(s){Xa=s}let Eo=1,Js=0,ln=Js;function bl(s){ln=s}function Co(){return++Eo}function ki(s){var a=s.f;if(a&Sa)return!0;if(a&Pa&&(s.f&=~on),a&ws){for(var t=s.deps,r=t.length,l=0;ls.wv)return!0}a&ss&&Ma===null&&ca(s,ya)}return!1}function Mo(s,a,t=!0){var r=s.reactions;if(r!==null&&!(is!==null&&zn.call(is,s)))for(var l=0;l{s.ac.abort(Zi)}),s.ac=null);try{s.f|=qi;var b=s.fn,m=b();s.f|=un;var _=s.deps,x=ot==null?void 0:ot.is_fork;if(Ba!==null){var M;if(x||Qn(s,ja),_!==null&&ja>0)for(_.length=ja+Ba.length,M=0;Mt==null?void 0:t.call(this,c))}return s.startsWith("pointer")||s.startsWith("touch")||s==="wheel"?qs(()=>{a.addEventListener(s,l,r)}):a.addEventListener(s,l,r),l}function xs(s,a,t,r,l){var c={capture:r,passive:l},u=fd(s,a,t,c);(a===document.body||a===window||a===document||a instanceof HTMLMediaElement)&&er(()=>{a.removeEventListener(s,u,c)})}function N(s,a,t){var r;((r=a[Xs])!=null?r:a[Xs]={})[s]=t}function Qt(s){for(var a=0;a{throw se});throw _}}finally{s[Xs]=a,delete s.currentTarget,rs(b),ks(m)}}}var Fl;const vr=((Fl=globalThis==null?void 0:globalThis.window)==null?void 0:Fl.trustedTypes)&&globalThis.window.trustedTypes.createPolicy("svelte-trusted-html",{createHTML:s=>s});function _d(s){var a;return(a=vr==null?void 0:vr.createHTML(s))!=null?a:s}function Io(s){var a=mo("template");return a.innerHTML=_d(s.replaceAll("","")),a.content}function vn(s,a){var t=xt;t.nodes===null&&(t.nodes={start:s,end:a,a:null,t:null})}function p(s,a){var t=(a&lc)!==0,r=(a&oc)!==0,l,c=!s.startsWith("");return()=>{l===void 0&&(l=Io(c?s:""+s),t||(l=ys(l)));var u=r||fo?document.importNode(l,!0):l.cloneNode(!0);if(t){var v=ys(u),f=u.lastChild;vn(v,f)}else vn(u,u);return u}}function hd(s,a,t="svg"){var r=!s.startsWith(""),l=`<${t}>${r?s:""+s}${t}>`,c;return()=>{if(!c){var u=Io(l),v=ys(u);c=ys(v)}var f=c.cloneNode(!0);return vn(f,f),f}}function Oo(s,a){return hd(s,a,"svg")}function Be(s=""){{var a=Ds(s+"");return vn(a,a),a}}function xi(){var s=document.createDocumentFragment(),a=document.createComment(""),t=Ds();return s.append(a,t),vn(a,t),s}function d(s,a){s!==null&&s.before(a)}const gd=["touchstart","touchmove"];function md(s){return gd.includes(s)}function y(s,a){var r;var t=a==null?"":typeof a=="object"?`${a}`:a;t!==((r=s[Kn])!=null?r:s[Kn]=s.nodeValue)&&(s[Kn]=t,s.nodeValue=`${t}`)}function bd(s,a){return yd(s,a)}const Ei=new Map;function yd(s,{target:a,anchor:t,props:r={},events:l,context:c,intro:u=!0,transformError:v}){sd();var f=void 0,h=od(()=>{var b=t!=null?t:a.appendChild(Ds());Hc(b,{pending:()=>{}},x=>{Tt({});var M=da;c&&(M.c=c),l&&(r.$$events=l),f=s(x,r)||{},St()},v);var m=new Set,_=x=>{for(var M=0;M{var T;for(var x of m)for(const D of[a,document]){var M=Ei.get(D),q=M.get(x);--q==0?(D.removeEventListener(x,Rr),M.delete(x),M.size===0&&Ei.delete(D)):M.set(x,q)}Lr.delete(_),b!==t&&((T=b.parentNode)==null||T.removeChild(b))}});return wd.set(f,h),f}let wd=new WeakMap;var vs,ms,$a,an,ii,ri,Gi;class kd{constructor(a,t=!0){Va(this,"anchor");lt(this,vs,new Map);lt(this,ms,new Map);lt(this,$a,new Map);lt(this,an,new Set);lt(this,ii,!0);lt(this,ri,a=>{if(F(this,vs).has(a)){var t=F(this,vs).get(a),r=F(this,ms).get(t);if(r)el(r),F(this,an).delete(t);else{var l=F(this,$a).get(t);l&&(F(this,ms).set(t,l.effect),F(this,$a).delete(t),l.fragment.lastChild.remove(),this.anchor.before(l.fragment),r=l.effect)}for(const[c,u]of F(this,vs)){if(F(this,vs).delete(c),c===a)break;const v=F(this,$a).get(u);v&&(qa(v.effect),F(this,$a).delete(u))}for(const[c,u]of F(this,ms)){if(c===t||F(this,an).has(c))continue;const v=()=>{if(Array.from(F(this,vs).values()).includes(c)){var h=document.createDocumentFragment();tl(u,h),h.append(Ds()),F(this,$a).set(c,{effect:u,fragment:h})}else qa(u);F(this,an).delete(c),F(this,ms).delete(c)};F(this,ii)||!r?(F(this,an).add(c),rn(u,v,!1)):v()}}});lt(this,Gi,a=>{F(this,vs).delete(a);const t=Array.from(F(this,vs).values());for(const[r,l]of F(this,$a))t.includes(r)||(qa(l.effect),F(this,$a).delete(r))});this.anchor=a,_t(this,ii,t)}ensure(a,t){var r=ot,l=go();if(t&&!F(this,ms).has(a)&&!F(this,$a).has(a))if(l){var c=document.createDocumentFragment(),u=Ds();c.append(u),F(this,$a).set(a,{effect:ts(()=>t(u)),fragment:c})}else F(this,ms).set(a,ts(()=>t(this.anchor)));if(F(this,vs).set(r,a),l){for(const[v,f]of F(this,ms))v===a?r.unskip_effect(f):r.skip_effect(f);for(const[v,f]of F(this,$a))v===a?r.unskip_effect(f.effect):r.skip_effect(f.effect);r.oncommit(F(this,ri)),r.ondiscard(F(this,Gi))}else F(this,ri).call(this,r)}}vs=new WeakMap,ms=new WeakMap,$a=new WeakMap,an=new WeakMap,ii=new WeakMap,ri=new WeakMap,Gi=new WeakMap;function qt(s){da===null&&$l(),Vn&&da.l!==null?xd(da).m.push(s):pa(()=>{const a=Ts(s);if(typeof a=="function")return a})}function ar(s){da===null&&$l(),qt(()=>()=>Ts(s))}function xd(s){var t;var a=s.l;return(t=a.u)!=null?t:a.u={a:[],b:[],m:[]}}function k(s,a,t=!1){var r=new kd(s),l=t?On:0;function c(u,v){r.ensure(u,v)}Zr(()=>{var u=!1;a((v,f=0)=>{u=!0,c(f,v)}),u||c(-1,null)},l)}function ft(s,a){return a}function Td(s,a,t){var m;for(var r=[],l=a.length,c,u=a.length,v=0;v{if(c){if(c.pending.delete(_),c.done.add(_),c.pending.size===0){var x=s.outrogroups;Nr(s,Ji(c.done)),x.delete(c),x.size===0&&(s.outrogroups=null)}}else u-=1},!1)}if(u===0){var f=r.length===0&&t!==null;if(f){var h=t,b=h.parentNode;nd(b),b.append(h),s.items.clear()}Nr(s,a,!f)}else c={pending:new Set(a),done:new Set},((m=s.outrogroups)!=null?m:s.outrogroups=new Set).add(c)}function Nr(s,a,t=!0){var r;if(s.pending.size>0){r=new Set;for(const u of s.pending.values())for(const v of u)r.add(s.items.get(v).e)}for(var l=0;l{var ne=t();return Ur(ne)?ne:ne==null?[]:Ji(ne)}),_,x=new Map,M=!0;function q(ne){se.effect.f&ns||(se.pending.delete(ne),se.fallback=b,Sd(se,_,u,a,r),b!==null&&(_.length===0?b.f&bs?(b.f^=bs,Hn(b,null,u)):el(b):rn(b,()=>{b=null})))}function T(ne){se.pending.delete(ne)}var D=Zr(()=>{_=e(m);for(var ne=_.length,fe=new Set,Q=ot,z=go(),I=0;Ic(u)):(b=ts(()=>c(_n!=null?_n:_n=Ds())),b.f|=bs)),ne>fe.size&&wc(),!M)if(x.set(Q,fe),z){for(const[K,V]of v)fe.has(K)||Q.skip_effect(V.e);Q.oncommit(q),Q.ondiscard(T)}else q(Q);e(m)}),se={effect:D,items:v,pending:x,outrogroups:null,fallback:b};M=!1}function qn(s){for(;s!==null&&!(s.f&_s);)s=s.next;return s}function Sd(s,a,t,r,l){var ee,K,V,oe,R,B,be,Ae,ue;var c=(r&ec)!==0,u=a.length,v=s.items,f=qn(s.effect.first),h,b=null,m,_=[],x=[],M,q,T,D;if(c)for(D=0;D0){var ge=r&Bl&&u===0?t:null;if(c){for(D=0;D{var j,J;if(m!==void 0)for(T of m)(J=(j=T.nodes)==null?void 0:j.a)==null||J.apply()})}function Ed(s,a,t,r,l,c,u,v){var f=u&Zo?u&tc?dn(t):uo(t,!1,!1):null,h=u&Qo?dn(l):null;return{v:f,i:h,e:ts(()=>(c(a,f!=null?f:t,h!=null?h:l,v),()=>{s.delete(r)}))}}function Hn(s,a,t){if(s.nodes)for(var r=s.nodes.start,l=s.nodes.end,c=a&&!(a.f&bs)?a.nodes.start:t;r!==null;){var u=wi(r);if(c.before(r),r===l)return;r=u}}function Os(s,a,t){a===null?s.effect.first=t:a.next=t,t===null?s.effect.last=a:t.prev=a}function wl(s,a,t=!1,r=!1,l=!1,c=!1){var u=s,v="";if(t)var f=s;w(()=>{var x;var h=xt;if(v!==(v=(x=a())!=null?x:"")){if(t){h.nodes=null,f.innerHTML=v,v!==""&&vn(ys(f),f.lastChild);return}if(h.nodes!==null&&(wo(h.nodes.start,h.nodes.end),h.nodes=null),v!==""){var b=r?cc:l?dc:void 0,m=mo(r?"svg":l?"math":"template",b);m.innerHTML=v;var _=r||l?m:m.content;if(vn(ys(_),_.lastChild),r||l)for(;ys(_);)u.before(ys(_));else u.before(_)}}})}function Fs(s,a,t){Ps(()=>{var r=Ts(()=>a(s,t==null?void 0:t())||{});if(r!=null&&r.destroy)return()=>r.destroy()})}function Lo(s){var a,t,r="";if(typeof s=="string"||typeof s=="number")r+=s;else if(typeof s=="object")if(Array.isArray(s)){var l=s.length;for(a=0;a=0;){var v=u+c;(u===0||kl.includes(r[u-1]))&&(v===r.length||kl.includes(r[v]))?r=(u===0?"":r.substring(0,u))+r.substring(v+1):u=v}}return r===""?null:r}function xl(s,a=!1){var t=a?" !important;":";",r="";for(var l of Object.keys(s)){var c=s[l];c!=null&&c!==""&&(r+=" "+l+": "+c+t)}return r}function ur(s){return s[0]!=="-"||s[1]!=="-"?s.toLowerCase():s}function Pd(s,a){if(a){var t="",r,l;if(Array.isArray(a)?(r=a[0],l=a[1]):r=a,s){s=String(s).replaceAll(/\s*\/\*.*?\*\/\s*/g,"").trim();var c=!1,u=0,v=!1,f=[];r&&f.push(...Object.keys(r).map(ur)),l&&f.push(...Object.keys(l).map(ur));var h=0,b=-1;const q=s.length;for(var m=0;m{Ro(s,s.__value)});a.observe(s,{childList:!0,subtree:!0,attributes:!0,attributeFilter:["value"]}),er(()=>{a.disconnect()})}function Tl(s,a,t=a){var r=new WeakSet,l=!0;Jr(s,"change",c=>{var h;var u=c?"[selected]":":checked",v;if(s.multiple)v=[].map.call(s.querySelectorAll(u),Jn);else{var f=(h=s.querySelector(u))!=null?h:s.querySelector("option:not([disabled])");v=f&&Jn(f)}t(v),s.__value=v,ot!==null&&r.add(ot)}),Ps(()=>{var c=a();if(s===document.activeElement){var u=ot;if(r.has(u))return}if(Ro(s,c,l),l&&c===void 0){var v=s.querySelector(":checked");v!==null&&(c=Jn(v),t(c))}s.__value=c,l=!1}),Ad(s)}function Jn(s){return"__value"in s?s.__value:s.value}const Dd=Symbol("is custom element"),zd=Symbol("is html"),Id=bc?"progress":"PROGRESS";function sr(s,a){var t=al(s);t.value===(t.value=a!=null?a:void 0)||s.value===a&&(a!==0||s.nodeName!==Id)||(s.value=a!=null?a:"")}function Od(s,a){var t=al(s);t.checked!==(t.checked=a!=null?a:void 0)&&(s.checked=a)}function mt(s,a,t,r){var l=al(s);l[a]!==(l[a]=t)&&(a==="loading"&&(s[mc]=t),t==null?s.removeAttribute(a):typeof t!="string"&&Ld(s).includes(a)?s[a]=t:s.setAttribute(a,t))}function al(s){var a;return(a=s[Ai])!=null?a:s[Ai]={[Dd]:s.nodeName.includes("-"),[zd]:s.namespaceURI===ql}}var Sl=new Map;function Ld(s){var a=s.getAttribute("is")||s.nodeName,t=Sl.get(a);if(t)return t;Sl.set(a,t=[]);for(var r,l=s,c=Element.prototype;c!==l;){r=uc(l);for(var u in r)r[u].set&&u!=="innerHTML"&&u!=="textContent"&&u!=="innerText"&&t.push(u);l=jl(l)}return t}function We(s,a,t=a){var r=new WeakSet;Jr(s,"input",async l=>{var c=l?s.defaultValue:s.value;if(c=fr(s)?_r(c):c,t(c),ot!==null&&r.add(ot),await pd(),c!==(c=a())){var u=s.selectionStart,v=s.selectionEnd,f=s.value.length;if(s.value=c!=null?c:"",v!==null){var h=s.value.length;u===v&&v===f&&h>f?(s.selectionStart=h,s.selectionEnd=h):(s.selectionStart=u,s.selectionEnd=Math.min(v,h))}}}),Ts(a)==null&&s.value&&(t(fr(s)?_r(s.value):s.value),ot!==null&&r.add(ot)),tr(()=>{var l=a();if(s===document.activeElement){var c=ot;if(r.has(c))return}fr(s)&&l===_r(s.value)||s.type==="date"&&!l&&!s.value||l!==s.value&&(s.value=l!=null?l:"")})}function Xt(s,a,t=a){Jr(s,"change",r=>{var l=r?s.defaultChecked:s.checked;t(l)}),Ts(a)==null&&t(s.checked),tr(()=>{var r=a();s.checked=!!r})}function fr(s){var a=s.type;return a==="number"||a==="range"}function _r(s){return s===""?null:+s}function hr(s,a){return s===a||(s==null?void 0:s[sn])===a}function sl(s={},a,t,r){var l=da.r,c=xt;return Ps(()=>{var u,v;return tr(()=>{u=v,v=[],Ts(()=>{hr(t(...v),s)||(a(s,...v),u&&hr(t(...u),s)&&a(null,...u))})}),()=>{let f=c;for(;f!==l&&f.parent!==null&&f.parent.f&kr;)f=f.parent;const h=()=>{v&&hr(t(...v),s)&&a(null,...v)},b=f.teardown;f.teardown=()=>{h(),b==null||b()}}}),s}function Ct(s,a,t,r){var fe,Q;var l=!Vn||(t&sc)!==0,c=(t&ic)!==0,u=(t&rc)!==0,v=r,f=!0,h=void 0,b=()=>u&&l?(h!=null||(h=Zn(r)),e(h)):(f&&(f=!1,v=u?Ts(r):r),v);let m;if(c){var _=sn in s||gc in s;m=(Q=(fe=wn(s,a))==null?void 0:fe.set)!=null?Q:_&&a in s?z=>s[a]=z:void 0}var x,M=!1;c?[x,M]=Vc(()=>s[a]):x=s[a],x===void 0&&r!==void 0&&(x=b(),m&&(l&&Ec(),m(x)));var q;if(l?q=()=>{var z=s[a];return z===void 0?b():(f=!0,z)}:q=()=>{var z=s[a];return z!==void 0&&(v=void 0),z===void 0?v:z},l&&!(t&nc))return q;if(m){var T=s.$$legacy;return function(z,I){return arguments.length>0?((!l||!I||T||M)&&m(I?q():z),z):q()}}var D=!1,se=(t&ac?Zn:$r)(()=>(D=!1,q()));c&&e(se);var ne=xt;return function(z,I){if(arguments.length>0){const L=I?e(se):l&&c?yt(z):z;return o(se,L),D=!0,v!==void 0&&(v=L),z}return zs&&D||ne.f&ns?se.v:e(se)}}const Rd="modulepreload",Nd=function(s){return"/"+s},El={},Vd=function(a,t,r){let l=Promise.resolve();if(t&&t.length>0){document.getElementsByTagName("link");const u=document.querySelector("meta[property=csp-nonce]"),v=(u==null?void 0:u.nonce)||(u==null?void 0:u.getAttribute("nonce"));l=Promise.allSettled(t.map(f=>{if(f=Nd(f),f in El)return;El[f]=!0;const h=f.endsWith(".css"),b=h?'[rel="stylesheet"]':"";if(document.querySelector(`link[href="${f}"]${b}`))return;const m=document.createElement("link");if(m.rel=h?"stylesheet":Rd,h||(m.as="script"),m.crossOrigin="",m.href=f,v&&m.setAttribute("nonce",v),document.head.appendChild(m),h)return new Promise((_,x)=>{m.addEventListener("load",_),m.addEventListener("error",()=>x(new Error(`Unable to preload CSS for ${f}`)))})}))}function c(u){const v=new Event("vite:preloadError",{cancelable:!0});if(v.payload=u,window.dispatchEvent(v),!v.defaultPrevented)throw u}return l.then(u=>{for(const v of u||[])v.status==="rejected"&&c(v.reason);return a().catch(c)})},nr="/assets/app_icon-CfHainhY.png";function Fd(s,a,t,r){if(typeof a=="function"?s!==a||!r:!a.has(s))throw new TypeError("Cannot read private member from an object whose class did not declare it");return t==="m"?r:t==="a"?r.call(s):r?r.value:a.get(s)}function Bd(s,a,t,r,l){if(typeof a=="function"?s!==a||!0:!a.has(s))throw new TypeError("Cannot write private member to an object whose class did not declare it");return a.set(s,t),t}var Ni;const ls="__TAURI_TO_IPC_KEY__";function qd(s,a=!1){return window.__TAURI_INTERNALS__.transformCallback(s,a)}async function E(s,a={},t){return window.__TAURI_INTERNALS__.invoke(s,a,t)}class Kd{get rid(){return Fd(this,Ni,"f")}constructor(a){Ni.set(this,void 0),Bd(this,Ni,a)}async close(){return E("plugin:resources|close",{rid:this.rid})}}Ni=new WeakMap;var Ha;(function(s){s.WINDOW_RESIZED="tauri://resize",s.WINDOW_MOVED="tauri://move",s.WINDOW_CLOSE_REQUESTED="tauri://close-requested",s.WINDOW_DESTROYED="tauri://destroyed",s.WINDOW_FOCUS="tauri://focus",s.WINDOW_BLUR="tauri://blur",s.WINDOW_SCALE_FACTOR_CHANGED="tauri://scale-change",s.WINDOW_THEME_CHANGED="tauri://theme-changed",s.WINDOW_CREATED="tauri://window-created",s.WINDOW_SUSPENDED="tauri://suspended",s.WINDOW_RESUMED="tauri://resumed",s.WEBVIEW_CREATED="tauri://webview-created",s.DRAG_ENTER="tauri://drag-enter",s.DRAG_OVER="tauri://drag-over",s.DRAG_DROP="tauri://drag-drop",s.DRAG_LEAVE="tauri://drag-leave"})(Ha||(Ha={}));async function No(s,a){window.__TAURI_EVENT_PLUGIN_INTERNALS__.unregisterListener(s,a),await E("plugin:event|unlisten",{event:s,eventId:a})}async function ha(s,a,t){var r;const l=typeof(t==null?void 0:t.target)=="string"?{kind:"AnyLabel",label:t.target}:(r=t==null?void 0:t.target)!==null&&r!==void 0?r:{kind:"Any"};return E("plugin:event|listen",{event:s,target:l,handler:qd(a)}).then(c=>async()=>No(s,c))}async function Ud(s,a,t){return ha(s,r=>{No(s,r.id),a(r)},t)}async function Vo(s,a){await E("plugin:event|emit",{event:s,payload:a})}async function jd(s,a,t){await E("plugin:event|emit_to",{target:typeof s=="string"?{kind:"AnyLabel",label:s}:s,event:a,payload:t})}const Hd={engine:{backend:"whisper-cpp",whisper_cpp:{model_dir:"",model_size:"tiny",device:"auto",threads:0,language:"auto"},moonshine:{model_size:"base",language:"en"},parakeet:{model_size:"tdt-0.6b-v3",language:"auto"},remote_openai:{endpoint:"http://localhost:8000/v1",api_key:null,model:"whisper-1",language:"",timeout_secs:30},s1_mini:{enabled:!1,styling:"semi-formal"}},audio:{vad_threshold:.5,input_device_index:null,evdev_device:null,noise_suppression:!1,gain:1,dynamic_stream:!0},ui:{show_overlay:!0,overlay_style:"mono_bars",overlay_position:"center",overlay_monitor:"primary",auto_show_settings:!1,show_notification:!1,show_command_overlay:!0,command_overlay_duration_secs:3},features:{remove_fillers:!0,custom_vocabulary:["VoxCtrl","Hey Vox"],spoken_punctuation:!0,auto_format_lists:!0,snippets:{},early_command_detection:!0},openai:{enabled:!1,model:"llama3.2:1b",mode:"clean",custom_prompt:null,system_prompt:"Fix grammar and punctuation only. Return only the corrected text, no commentary.",user_prompt:"{text}",endpoint:"http://localhost:11434",api_key:null,timeout_secs:8},tts:{enabled:!1,engine:"espeak",voice:"en-us-lessac-medium",voice_dir:"",stop_key:["KEY_ESCAPE"],response_overlay:!0,speed:1,gpu:!1,hf_token:null,pocket_tts:{voice:"alba",prewarm:!1,voice_dir:"",gpu:!1},inflect_micro:{model_dir:"",seed:0,noise_scale:.667,prewarm:!1},breeze_tts_2:{voice_mode:"prompt",cloned_voice:"alba",speaker_prompt:"A calm and clear female voice speaking at a natural pace",model_dir:"",prewarm:!1,gpu:!1},vox_cpm_2:{voice_mode:"prompt",cloned_voice:"alba",voice_dir:"",speaker_prompt:"A calm young female voice speaking clearly with a gentle tone.",ultimate_cloning:!1,model_dir:"",prewarm:!1,gpu:!1},memory_mode:"always_loaded",idle_unload_secs:900,snippets:{VoxCtrl:"Vox Control"}},mcp:{server_enabled:!1,record_timeout:15,visual_feedback:!0}},Ot=bi(Hd),Ss=bi(!1),ji=bi(!1);let ei=!1,gr=null;async function Wd(){try{const s=await E("get_config");Ot.set(s),Ss.set(!1),ji.set(!0),setTimeout(()=>{ei=!0},0)}catch(s){console.error("loadConfig:",s),ji.set(!0),setTimeout(()=>{ei=!0},0)}}async function nl(s){await E("save_config",{newConfig:s}),Ss.set(!1)}Ot.subscribe(s=>{ei&&(gr&&clearTimeout(gr),gr=setTimeout(async()=>{try{await nl(s),console.log("Config auto-saved successfully!")}catch(a){console.error("Auto-saving config failed:",a)}},400))});Wd();ha("config-changed",s=>{ei=!1,Ot.set(s.payload),setTimeout(()=>{ei=!0},0)}).catch(s=>{console.error("Failed to setup config-changed listener:",s)});const ga=bi({recording:!1,processing:!1,speaking:!1,mcp_recording:!1,audio_ready:!0,word_count:0,active_target_id:"default",active_target_label:"Focused Window"}),Yd=yi(ga,s=>s.recording),$d=yi(ga,s=>s.speaking),Gd=yi(ga,s=>s.mcp_recording);yi(ga,s=>s.word_count);yi(ga,s=>{var a;return(a=s.active_target_label)!=null?a:"Focused Window"});let Fo=0;ha("status-tick",s=>{Fo=Date.now(),ga.set(s.payload)});E("get_status").then(ga.set).catch(console.error);const Jd=2e3,Xd=1e3;setInterval(()=>{Date.now()-Fo{})},Xd);var Zd=p('
'),Qd=p(`
Using the HF_TOKEN environment variable. It takes precedence over a saved
token and is not written to your config.
`),ev=p('
'),tv=p(`
`),av=p('
'),sv=p(`
General
Setup
Run the first-launch setup wizard again
Walks through the engine, model, hotkey, overlay and voice choices in one flow, and downloads
whatever it needs. Your current settings stay in place until you change them in the wizard.
Hugging Face Access Token
Hugging Face access token
Used by every gated model VoxCtrl can download — Pocket-TTS, Breeze-TTS-2, and VoxCPM2 in
the TTS tab. Create a token at huggingface.co/settings/tokens and accept each
model's license on its Hugging Face page before downloading. Enter it once here; the setup
wizard reads and writes the same token, so the two always match.
Updates
VoxCtrl never checks for updates on its own. Press "Check now" to ask GitHub whether a newer
release has been published — that request carries nothing about you or your machine.
Check now
MCP Server
How long transcribe_voice listens when the calling agent does not ask for a
- specific timeout. An explicit timeout_seconds in the tool call still wins.
`);function nv(s,a){Tt(a,!0);let t=Ct(a,"cfg",15);function r(){Ot.set(t()),Ss.set(!0)}let l=S(null);const c=ce(()=>!!e(l)),u=ce(()=>{var O,X;return(X=(O=e(l))!=null?O:t().tts.hf_token)!=null?X:""});function v(O){if(e(c))return;const X=O.target.value;t(t().tts.hf_token=X.trim()?X.trim():null,!0),r()}let f=S(null),h=S(!1),b=S(null),m=S(null);async function _(){o(h,!0),o(m,null),o(b,null);try{o(b,await E("check_for_update"),!0)}catch(O){o(m,`${O}`)}finally{o(h,!1)}}async function x(){try{await E("open_update_window")}catch(O){o(m,`${O}`)}}async function A(){o(f,null);try{await E("open_setup_wizard")}catch(O){o(f,`${O}`)}}qt(()=>{E("hf_token_env").then(O=>o(l,O&&O.trim()?O.trim():null,!0)).catch(()=>o(l,null))});var q=sv(),T=i(n(q),2),D=i(n(T),2),se=i(n(D),2),ne=i(D,4);{var fe=O=>{var X=Zd(),ve=n(X);w(()=>{var Ae;return y(ve,`Could not open the wizard: ${(Ae=e(f))!=null?Ae:""}`)}),d(O,X)};k(ne,O=>{e(f)&&O(fe)})}var Q=i(T,2),z=i(n(Q),2),I=i(n(z),2),L=i(z,2);{var ge=O=>{var X=Qd();d(O,X)};k(L,O=>{e(c)&&O(ge)})}var ee=i(Q,2),j=i(n(ee),4),V=i(n(j),2),oe=n(V),R=i(j,2);{var B=O=>{var X=ev(),ve=n(X);w(()=>{var Ae;return y(ve,`VoxCtrl ${(Ae=e(b).current_version)!=null?Ae:""} is the latest release.`)}),d(O,X)},be=O=>{var X=tv(),ve=n(X),Ae=i(ve);w(()=>{var Fe,he;return y(ve,`Version ${(Fe=e(b).update.version)!=null?Fe:""} is available (you have
- ${(he=e(b).update.current_version)!=null?he:""}). `)}),N("click",Ae,x),d(O,X)};k(R,O=>{var X;e(b)&&!e(b).update?O(B):(X=e(b))!=null&&X.update&&O(be,1)})}var Pe=i(R,2);{var ue=O=>{var X=av(),ve=n(X);w(()=>{var Ae;return y(ve,`Could not check for updates: ${(Ae=e(m))!=null?Ae:""}`)}),d(O,X)};k(Pe,O=>{e(m)&&O(ue)})}var K=i(ee,2),J=i(n(K),2),Se=i(n(J),2),De=i(J,2),le=i(n(De),2),W=i(De,2),ae=i(n(W),2);w(()=>{sr(I,e(u)),I.readOnly=e(c),mt(I,"title",e(c)?"Set by the HF_TOKEN environment variable":void 0),V.disabled=e(h),y(oe,e(h)?"Checking…":"Check for updates")}),N("click",se,A),N("input",I,v),N("click",V,_),N("change",Se,r),Xt(Se,()=>t().mcp.server_enabled,O=>t(t().mcp.server_enabled=O,!0)),N("change",le,r),Xt(le,()=>t().mcp.visual_feedback,O=>t(t().mcp.visual_feedback=O,!0)),N("change",ae,r),We(ae,()=>t().mcp.record_timeout,O=>t(t().mcp.record_timeout=O,!0)),d(s,q),St()}Qt(["click","input","change"]);var iv=p(''),rv=p(''),lv=p('
Design your own overlay style by adding a folder with an index.html and style.css to the folder below — it
+ specific timeout. An explicit timeout_seconds in the tool call still wins.
`);function nv(s,a){Tt(a,!0);let t=Ct(a,"cfg",15);function r(){Ot.set(t()),Ss.set(!0)}let l=S(null);const c=ce(()=>!!e(l)),u=ce(()=>{var O,X;return(X=(O=e(l))!=null?O:t().tts.hf_token)!=null?X:""});function v(O){if(e(c))return;const X=O.target.value;t(t().tts.hf_token=X.trim()?X.trim():null,!0),r()}let f=S(null),h=S(!1),b=S(null),m=S(null);async function _(){o(h,!0),o(m,null),o(b,null);try{o(b,await E("check_for_update"),!0)}catch(O){o(m,`${O}`)}finally{o(h,!1)}}async function x(){try{await E("open_update_window")}catch(O){o(m,`${O}`)}}async function M(){o(f,null);try{await E("open_setup_wizard")}catch(O){o(f,`${O}`)}}qt(()=>{E("hf_token_env").then(O=>o(l,O&&O.trim()?O.trim():null,!0)).catch(()=>o(l,null))});var q=sv(),T=i(n(q),2),D=i(n(T),2),se=i(n(D),2),ne=i(D,4);{var fe=O=>{var X=Zd(),ve=n(X);w(()=>{var Me;return y(ve,`Could not open the wizard: ${(Me=e(f))!=null?Me:""}`)}),d(O,X)};k(ne,O=>{e(f)&&O(fe)})}var Q=i(T,2),z=i(n(Q),2),I=i(n(z),2),L=i(z,2);{var ge=O=>{var X=Qd();d(O,X)};k(L,O=>{e(c)&&O(ge)})}var ee=i(Q,2),K=i(n(ee),4),V=i(n(K),2),oe=n(V),R=i(K,2);{var B=O=>{var X=ev(),ve=n(X);w(()=>{var Me;return y(ve,`VoxCtrl ${(Me=e(b).current_version)!=null?Me:""} is the latest release.`)}),d(O,X)},be=O=>{var X=tv(),ve=n(X),Me=i(ve);w(()=>{var Fe,he;return y(ve,`Version ${(Fe=e(b).update.version)!=null?Fe:""} is available (you have
+ ${(he=e(b).update.current_version)!=null?he:""}). `)}),N("click",Me,x),d(O,X)};k(R,O=>{var X;e(b)&&!e(b).update?O(B):(X=e(b))!=null&&X.update&&O(be,1)})}var Ae=i(R,2);{var ue=O=>{var X=av(),ve=n(X);w(()=>{var Me;return y(ve,`Could not check for updates: ${(Me=e(m))!=null?Me:""}`)}),d(O,X)};k(Ae,O=>{e(m)&&O(ue)})}var j=i(ee,2),J=i(n(j),2),Se=i(n(J),2),De=i(J,2),le=i(n(De),2),W=i(De,2),ae=i(n(W),2);w(()=>{sr(I,e(u)),I.readOnly=e(c),mt(I,"title",e(c)?"Set by the HF_TOKEN environment variable":void 0),V.disabled=e(h),y(oe,e(h)?"Checking…":"Check for updates")}),N("click",se,M),N("input",I,v),N("click",V,_),N("change",Se,r),Xt(Se,()=>t().mcp.server_enabled,O=>t(t().mcp.server_enabled=O,!0)),N("change",le,r),Xt(le,()=>t().mcp.visual_feedback,O=>t(t().mcp.visual_feedback=O,!0)),N("change",ae,r),We(ae,()=>t().mcp.record_timeout,O=>t(t().mcp.record_timeout=O,!0)),d(s,q),St()}Qt(["click","input","change"]);var iv=p(''),rv=p(''),lv=p('
Design your own overlay style by adding a folder with an index.html and style.css to the folder below — it
shows up here as a selectable style automatically. A working example
(a copy of Voice Card, ready to duplicate) and a README covering the
- format live there already.
Custom overlay styles:
`,1),vv=p('
Visual & Feedback
Overlay & HUD
Alerts & OS Integration
Application Window
');function uv(s,a){Tt(a,!0);let t=Ct(a,"cfg",15),r=S(yt([])),l=S(yt([])),c=S(""),u=ce(()=>[{value:"voice_card",label:"Voice Card"},{value:"waveform",label:"Waveform"},{value:"pulse",label:"Pulse Ring"},{value:"blue_wave",label:"Ocean Wave"},{value:"mono_bars",label:"Mono Bars"},{value:"spectrum",label:"Neon Spectrum"},{value:"terminal",label:"Retro Terminal"},{value:"vinyl",label:"Analog VU"},...e(r).map(J=>({value:J.name,label:J.name}))]);const v=[{value:"top",label:"Top of screen"},{value:"center",label:"Center of screen"},{value:"bottom",label:"Bottom of screen"}];let f=ce(()=>[{value:"primary",label:"Primary Monitor"},...e(l).filter(J=>J.name).map(J=>({value:J.name,label:`${J.name} (${J.width}x${J.height})${J.is_primary?" [Primary]":""}`}))]);qt(async()=>{try{o(r,await E("get_custom_overlays"),!0)}catch(J){console.error("Failed to fetch custom overlays:",J)}try{o(l,await E("get_available_monitors"),!0)}catch(J){console.error("Failed to fetch available monitors:",J)}try{o(c,await E("get_custom_overlays_dir"),!0)}catch(J){console.error("Failed to fetch custom overlays directory:",J)}});function h(){Ot.set(t()),Ss.set(!0)}function b(J){h(),Vo("overlay-style-selected",J)}var m=vv(),_=i(n(m),2),x=i(n(_),2),A=i(n(x),2),q=i(x,2),T=i(n(q),2),D=i(q,2);{var se=J=>{var Se=ov(),De=i(n(Se),2);N("change",De,h),We(De,()=>t().ui.command_overlay_duration_secs,le=>t(t().ui.command_overlay_duration_secs=le,!0)),d(J,Se)};k(D,J=>{t().ui.show_command_overlay&&J(se)})}var ne=i(D,2),fe=i(n(ne),2);sa(fe,{get options(){return e(u)},onchange:b,get value(){return t().ui.overlay_style},set value(J){t(t().ui.overlay_style=J,!0)}});var Q=i(ne,2),z=i(n(Q),2);sa(z,{get options(){return v},onchange:h,get value(){return t().ui.overlay_position},set value(J){t(t().ui.overlay_position=J,!0)}});var I=i(Q,2),L=i(n(I),2);sa(L,{get options(){return e(f)},onchange:h,get value(){return t().ui.overlay_monitor},set value(J){t(t().ui.overlay_monitor=J,!0)}});var ge=i(I,2);{var ee=J=>{var Se=cv(),De=n(Se),le=n(De);w(()=>{var W;return y(le,`⚠️ Configured monitor "${(W=t().ui.overlay_monitor)!=null?W:""}" is disconnected. Using Primary Monitor.`)}),d(J,Se)},j=ce(()=>t().ui.overlay_monitor!=="primary"&&e(l).length>0&&!e(l).some(J=>J.name===t().ui.overlay_monitor));k(ge,J=>{e(j)&&J(ee)})}var V=i(ge,2);{var oe=J=>{var Se=dv(),De=i(ht(Se),2),le=i(n(De)),W=n(le);w(()=>y(W,e(c))),d(J,Se)};k(V,J=>{e(c)&&J(oe)})}var R=i(_,2),B=i(n(R),2),be=i(n(B),2),Pe=i(R,2),ue=i(n(Pe),2),K=i(n(ue),2);N("change",A,h),Xt(A,()=>t().ui.show_overlay,J=>t(t().ui.show_overlay=J,!0)),N("change",T,h),Xt(T,()=>t().ui.show_command_overlay,J=>t(t().ui.show_command_overlay=J,!0)),N("change",be,h),Xt(be,()=>t().ui.show_notification,J=>t(t().ui.show_notification=J,!0)),N("change",K,h),Xt(K,()=>t().ui.auto_show_settings,J=>t(t().ui.auto_show_settings=J,!0)),d(s,m),St()}Qt(["change"]);var pv=p(`
⚠️
Voice Model Not Downloaded
The configuration specifies a voice model () that is not currently downloaded. Please select the model size to
+ format live there already.
Custom overlay styles:
`,1),vv=p('
Visual & Feedback
Overlay & HUD
Alerts & OS Integration
Application Window
');function uv(s,a){Tt(a,!0);let t=Ct(a,"cfg",15),r=S(yt([])),l=S(yt([])),c=S(""),u=ce(()=>[{value:"voice_card",label:"Voice Card"},{value:"waveform",label:"Waveform"},{value:"pulse",label:"Pulse Ring"},{value:"blue_wave",label:"Ocean Wave"},{value:"mono_bars",label:"Mono Bars"},{value:"spectrum",label:"Neon Spectrum"},{value:"terminal",label:"Retro Terminal"},{value:"vinyl",label:"Analog VU"},...e(r).map(J=>({value:J.name,label:J.name}))]);const v=[{value:"top",label:"Top of screen"},{value:"center",label:"Center of screen"},{value:"bottom",label:"Bottom of screen"}];let f=ce(()=>[{value:"primary",label:"Primary Monitor"},...e(l).filter(J=>J.name).map(J=>({value:J.name,label:`${J.name} (${J.width}x${J.height})${J.is_primary?" [Primary]":""}`}))]);qt(async()=>{try{o(r,await E("get_custom_overlays"),!0)}catch(J){console.error("Failed to fetch custom overlays:",J)}try{o(l,await E("get_available_monitors"),!0)}catch(J){console.error("Failed to fetch available monitors:",J)}try{o(c,await E("get_custom_overlays_dir"),!0)}catch(J){console.error("Failed to fetch custom overlays directory:",J)}});function h(){Ot.set(t()),Ss.set(!0)}function b(J){h(),Vo("overlay-style-selected",J)}var m=vv(),_=i(n(m),2),x=i(n(_),2),M=i(n(x),2),q=i(x,2),T=i(n(q),2),D=i(q,2);{var se=J=>{var Se=ov(),De=i(n(Se),2);N("change",De,h),We(De,()=>t().ui.command_overlay_duration_secs,le=>t(t().ui.command_overlay_duration_secs=le,!0)),d(J,Se)};k(D,J=>{t().ui.show_command_overlay&&J(se)})}var ne=i(D,2),fe=i(n(ne),2);sa(fe,{get options(){return e(u)},onchange:b,get value(){return t().ui.overlay_style},set value(J){t(t().ui.overlay_style=J,!0)}});var Q=i(ne,2),z=i(n(Q),2);sa(z,{get options(){return v},onchange:h,get value(){return t().ui.overlay_position},set value(J){t(t().ui.overlay_position=J,!0)}});var I=i(Q,2),L=i(n(I),2);sa(L,{get options(){return e(f)},onchange:h,get value(){return t().ui.overlay_monitor},set value(J){t(t().ui.overlay_monitor=J,!0)}});var ge=i(I,2);{var ee=J=>{var Se=cv(),De=n(Se),le=n(De);w(()=>{var W;return y(le,`⚠️ Configured monitor "${(W=t().ui.overlay_monitor)!=null?W:""}" is disconnected. Using Primary Monitor.`)}),d(J,Se)},K=ce(()=>t().ui.overlay_monitor!=="primary"&&e(l).length>0&&!e(l).some(J=>J.name===t().ui.overlay_monitor));k(ge,J=>{e(K)&&J(ee)})}var V=i(ge,2);{var oe=J=>{var Se=dv(),De=i(ht(Se),2),le=i(n(De)),W=n(le);w(()=>y(W,e(c))),d(J,Se)};k(V,J=>{e(c)&&J(oe)})}var R=i(_,2),B=i(n(R),2),be=i(n(B),2),Ae=i(R,2),ue=i(n(Ae),2),j=i(n(ue),2);N("change",M,h),Xt(M,()=>t().ui.show_overlay,J=>t(t().ui.show_overlay=J,!0)),N("change",T,h),Xt(T,()=>t().ui.show_command_overlay,J=>t(t().ui.show_command_overlay=J,!0)),N("change",be,h),Xt(be,()=>t().ui.show_notification,J=>t(t().ui.show_notification=J,!0)),N("change",j,h),Xt(j,()=>t().ui.auto_show_settings,J=>t(t().ui.auto_show_settings=J,!0)),d(s,m),St()}Qt(["change"]);var pv=p(`
⚠️
Voice Model Not Downloaded
The configuration specifies a voice model () that is not currently downloaded. Please select the model size to
use and download it below, or choose another model.
`),fv=p('⏳ Checking local model files...'),_v=p(''),hv=p('✔ Model downloaded and ready'),gv=p('
❌ Model file missing
'),mv=p('
'),bv=p(`
Whisper.cpp Settings
Model directory (leave blank for default)
Language code (e.g. en, da, fr) to force transcription in that
language, or auto to let whisper.cpp detect it. Forcing a language helps short phrases
that auto-detect sometimes misidentifies.
Default model directory: ~/.local/share/voxctrl/models/
`),yv=p(`
⚠️
Moonshine backend not included in this build
This build was compiled without Moonshine, so selecting it will fall
back to Whisper.cpp (using the Whisper model configured above).
Rebuild with --features moonshine to enable it.
`),wv=p(`
🖥️
Moonshine runs on the CPU in this build
ONNX Runtime, which Moonshine uses, has no Vulkan backend, so the
Device setting above applies to Whisper.cpp only. Moonshine holds
- its weights in RAM as fp32 — roughly 530 MB for base, 240 MB for tiny
`),kv=p('⏳ Checking local model files...'),xv=p(''),Tv=p('✔ Model downloaded'),Sv=p('
Model not downloaded
'),Ev=p(''),Cv=p('
Moonshine Settings
'),Av=p(`
⚠️
Parakeet backend not included in this build
This build was compiled without Parakeet, so selecting it will fall
- back to Whisper.cpp. Rebuild with --features parakeet to enable it.
`),Mv=p('⏳ Checking local model files...'),Pv=p(''),Dv=p('✔ Model downloaded and ready'),zv=p('
Model not downloaded
'),Iv=p(''),Ov=p('
Parakeet Settings
NVIDIA FastConformer TDT 0.6B with 128-mel ONNX preprocessor and INT8 quantization (~665 MB total).
'),Lv=p(''),Rv=p('
Discovered models from server:
'),Nv=p(""),Vv=p(`
Remote Speech Engine Settings
Connect to a network speech-to-text service supporting the OpenAI /v1/audio/transcriptions API (e.g., Faster-Whisper-Server, vLLM, LocalAI, Whisper-standalone, or OpenAI Whisper).
- Audio will begin streaming to the endpoint as soon as your keybind is triggered.
Base URL or full transcriptions path (e.g. http://192.168.1.50:8000/v1 or https://api.openai.com/v1).
Leave blank if your local network server does not require authentication.
Language code (e.g. en, es, fr) or leave blank/auto for automatic detection.
`),Fv=p('
Inference Engine
Backend
');function Bv(s,a){Tt(a,!0);let t=Ct(a,"cfg",15);function r(){Ot.set(t()),Ss.set(!0)}const l=["tiny","tiny.en","base","base.en","small","small.en","medium","medium.en","large-v2","large-v3","large-v3-turbo"];let c=S(null),u=S(null),v=S(null);const f={cuda:"CUDA (NVIDIA)",vulkan:"Vulkan (AMD/Intel/NVIDIA)",coreml:"CoreML (Apple)",webgpu:"WebGPU (AMD/Intel/NVIDIA)"},h=Y=>{var _e;return(_e=f[Y])!=null?_e:Y};let b=ce(()=>[{value:"whisper-cpp",label:"Whisper.cpp"},{value:"moonshine",label:e(u)?`Moonshine (${h(e(u))})`:"Moonshine (CPU only)"},{value:"parakeet",label:e(v)?`Parakeet TDT (${h(e(v))})`:"Parakeet TDT (CPU only)"},{value:"remote-openai",label:"Remote Speech Engine (OpenAI API)"}]),m=ce(()=>l.map(Y=>({value:Y,label:`${Y}${e(q)[Y]?" ✔":""}`}))),_=ce(()=>[{value:"auto",label:e(c)?`Auto (${h(e(c))})`:"Auto"},...e(c)?[{value:e(c),label:h(e(c))}]:[],{value:"cpu",label:"CPU"}]);const x=[{value:"base",label:"Base"},{value:"tiny",label:"Tiny"}],A=[{value:"tdt-0.6b-v3",label:"TDT 0.6B v3 (INT8, ~665 MB)"}];let q=S(yt({})),T=S(!1),D=S(!1),se=S(null),ne=S(!0),fe=S(yt({})),Q=S(!1),z=S(!1),I=S(!0),L=S(yt({})),ge=S(!1),ee=S(!1);async function j(){o(ge,!0);const Y={};for(const _e of A)try{Y[_e.value]=await E("check_parakeet_downloaded",{modelSize:_e.value})}catch(me){console.error("Failed to check Parakeet download status for "+_e.value,me),Y[_e.value]=!1}o(L,Y,!0),o(ge,!1)}async function V(Y){if(!e(ee)){o(ee,!0);try{await E("download_parakeet_model",{modelSize:Y}),e(L)[Y]=!0}catch(_e){alert(`Failed to download Parakeet model: ${_e}`)}finally{o(ee,!1)}}}async function oe(){var _e,me;r();const Y=(me=(_e=t().engine.parakeet)==null?void 0:_e.model_size)!=null?me:"tdt-0.6b-v3";e(I)&&!e(L)[Y]&&await V(Y)}let R=S(!1),B=S(null),be=S(yt([]));function Pe(){t().engine.remote_openai||t(t().engine.remote_openai={endpoint:"http://localhost:8000/v1",api_key:null,model:"whisper-1",language:"",timeout_secs:30},!0)}async function ue(){if(Pe(),!e(R)){o(R,!0),o(B,null);try{const Y=await E("test_remote_stt",{endpoint:t().engine.remote_openai.endpoint||"http://localhost:8000/v1",apiKey:t().engine.remote_openai.api_key||null,model:t().engine.remote_openai.model||"whisper-1",timeoutSecs:t().engine.remote_openai.timeout_secs||30});o(B,{success:Y.success,message:Y.message},!0),Y.models&&Y.models.length>0&&(o(be,Y.models,!0),t().engine.remote_openai.model||(t(t().engine.remote_openai.model=Y.models[0],!0),r()))}catch(Y){o(B,{success:!1,message:Y.toString()},!0)}finally{o(R,!1)}}}async function K(){o(Q,!0);const Y={};for(const _e of x)try{Y[_e.value]=await E("check_moonshine_downloaded",{modelSize:_e.value})}catch(me){console.error("Failed to check Moonshine download status for "+_e.value,me),Y[_e.value]=!1}o(fe,Y,!0),o(Q,!1)}async function J(Y){if(!e(z)){o(z,!0);try{await E("download_moonshine_model",{modelSize:Y}),e(fe)[Y]=!0}catch(_e){alert(`Failed to download Moonshine model: ${_e}`)}finally{o(z,!1)}}}async function Se(){r();const Y=t().engine.moonshine.model_size;e(ne)&&!e(fe)[Y]&&await J(Y)}async function De(){o(T,!0);const Y={};for(const _e of l)try{Y[_e]=await E("check_model_downloaded",{modelSize:_e,modelDir:t().engine.whisper_cpp.model_dir})}catch(me){console.error("Failed to check download status for model "+_e,me),Y[_e]=!1}o(q,Y,!0),o(T,!1)}async function le(Y){if(!e(D)){o(D,!0);try{await E("download_model",{modelSize:Y,modelDir:t().engine.whisper_cpp.model_dir}),e(q)[Y]=!0}catch(_e){alert(`Failed to download model: ${_e}`)}finally{o(D,!1)}}}async function W(){r();const Y=t().engine.whisper_cpp.model_size;e(q)[Y]||await le(Y)}async function ae(){const Y=t().engine.whisper_cpp.model_dir;if(!Y){o(se,null);return}const _e=await E("check_directory_exists",{path:Y});o(se,_e?null:"This folder does not exist. Please create it first or leave blank for the default location.",!0),e(se)||await De()}function O(){r()}function X(Y){Y.key==="Enter"&&Y.currentTarget.blur()}qt(async()=>{var _e,me,pe;De();try{o(ne,await E("moonshine_available"),!0)}catch(ze){console.error("Failed to query Moonshine availability",ze)}K();try{o(I,await E("parakeet_available"),!0)}catch(ze){console.error("Failed to query Parakeet availability",ze)}j();try{const ze=await E("accelerator_support");o(c,(_e=ze.whisper_gpu)!=null?_e:null,!0),o(u,(me=ze.moonshine_gpu)!=null?me:null,!0),o(v,(pe=ze.parakeet_gpu)!=null?pe:null,!0)}catch(ze){console.error("Failed to query GPU support",ze)}const Y=t().engine.whisper_cpp.device;Y!=="auto"&&Y!=="cpu"&&Y!==e(c)&&(t(t().engine.whisper_cpp.device="auto",!0),r())});var ve=Fv(),Ae=i(n(ve),2);{var Fe=Y=>{var _e=pv(),me=i(n(_e),2),pe=i(n(me),2),ze=i(n(pe)),$e=n(ze);w(()=>y($e,t().engine.whisper_cpp.model_size)),d(Y,_e)};k(Ae,Y=>{t().engine.backend==="whisper-cpp"&&!e(T)&&!e(q)[t().engine.whisper_cpp.model_size]&&Y(Fe)})}var he=i(Ae,2),re=i(n(he),2),we=i(n(re),2);sa(we,{get options(){return e(b)},onchange:r,get value(){return t().engine.backend},set value(Y){t(t().engine.backend=Y,!0)}});var Je=i(he,2);{var de=Y=>{var _e=bv(),me=i(n(_e),2),pe=i(n(me),2);sa(pe,{get options(){return e(m)},onchange:W,get value(){return t().engine.whisper_cpp.model_size},set value(Ee){t(t().engine.whisper_cpp.model_size=Ee,!0)}});var ze=i(me,2),$e=n(ze);{var st=Ee=>{var Ge=fv();d(Ee,Ge)},it=Ee=>{var Ge=_v(),ct=n(Ge);w(()=>{var vt;return y(ct,`⏳ Downloading ${(vt=t().engine.whisper_cpp.model_size)!=null?vt:""} (GGUF format)...`)}),d(Ee,Ge)},H=Ee=>{var Ge=hv();d(Ee,Ge)},M=Ee=>{var Ge=gv(),ct=i(n(Ge),2);N("click",ct,()=>le(t().engine.whisper_cpp.model_size)),d(Ee,Ge)};k($e,Ee=>{e(T)?Ee(st):e(D)?Ee(it,1):e(q)[t().engine.whisper_cpp.model_size]?Ee(H,2):Ee(M,-1)})}var C=i(ze,2),ke=i(n(C),2);sa(ke,{get options(){return e(_)},onchange:r,get value(){return t().engine.whisper_cpp.device},set value(Ee){t(t().engine.whisper_cpp.device=Ee,!0)}});var Ke=i(C,2),ye=i(n(Ke),2);let Ie;var Ye=i(ye,2);{var Ze=Ee=>{var Ge=mv(),ct=n(Ge);w(()=>y(ct,e(se))),d(Ee,Ge)};k(Ye,Ee=>{e(se)&&Ee(Ze)})}var Ve=i(Ke,2),at=i(n(Ve),2),et=i(Ve,2),rt=i(n(et),2);w(()=>Ie=Te(ye,1,"svelte-nfi4ak",null,Ie,{"field-input-error":!!e(se)})),N("change",ye,O),xs("blur",ye,ae),N("keydown",ye,X),We(ye,()=>t().engine.whisper_cpp.model_dir,Ee=>t(t().engine.whisper_cpp.model_dir=Ee,!0)),N("change",at,r),We(at,()=>t().engine.whisper_cpp.threads,Ee=>t(t().engine.whisper_cpp.threads=Ee,!0)),N("change",rt,r),We(rt,()=>t().engine.whisper_cpp.language,Ee=>t(t().engine.whisper_cpp.language=Ee,!0)),d(Y,_e)},$=Y=>{var _e=Cv(),me=i(n(_e),2);{var pe=Ke=>{var ye=yv();d(Ke,ye)};k(me,Ke=>{e(ne)||Ke(pe)})}var ze=i(me,2);{var $e=Ke=>{var ye=wv(),Ie=i(n(ye),2),Ye=i(n(Ie),2),Ze=i(n(Ye),8);w(Ve=>y(Ze,` —
+ its weights in RAM as fp32 — roughly 530 MB for base, 240 MB for tiny
`),kv=p('⏳ Checking local model files...'),xv=p(''),Tv=p('✔ Model downloaded'),Sv=p('
Model not downloaded
'),Ev=p(''),Cv=p('
Moonshine Settings
'),Mv=p(`
⚠️
Parakeet backend not included in this build
This build was compiled without Parakeet, so selecting it will fall
+ back to Whisper.cpp. Rebuild with --features parakeet to enable it.
`),Pv=p('⏳ Checking local model files...'),Av=p(''),Dv=p('✔ Model downloaded and ready'),zv=p('
Model not downloaded
'),Iv=p(''),Ov=p('
Parakeet Settings
NVIDIA FastConformer TDT 0.6B with 128-mel ONNX preprocessor and INT8 quantization (~665 MB total).
'),Lv=p(''),Rv=p('
Discovered models from server:
'),Nv=p(""),Vv=p(`
Remote Speech Engine Settings
Connect to a network speech-to-text service supporting the OpenAI /v1/audio/transcriptions API (e.g., Faster-Whisper-Server, vLLM, LocalAI, Whisper-standalone, or OpenAI Whisper).
+ Audio will begin streaming to the endpoint as soon as your keybind is triggered.
Base URL or full transcriptions path (e.g. http://192.168.1.50:8000/v1 or https://api.openai.com/v1).
Leave blank if your local network server does not require authentication.
Language code (e.g. en, es, fr) or leave blank/auto for automatic detection.
`),Fv=p('
Inference Engine
Backend
');function Bv(s,a){Tt(a,!0);let t=Ct(a,"cfg",15);function r(){Ot.set(t()),Ss.set(!0)}const l=["tiny","tiny.en","base","base.en","small","small.en","medium","medium.en","large-v2","large-v3","large-v3-turbo"];let c=S(null),u=S(null),v=S(null);const f={cuda:"CUDA (NVIDIA)",vulkan:"Vulkan (AMD/Intel/NVIDIA)",coreml:"CoreML (Apple)",webgpu:"WebGPU (AMD/Intel/NVIDIA)"},h=G=>{var _e;return(_e=f[G])!=null?_e:G};let b=ce(()=>[{value:"whisper-cpp",label:"Whisper.cpp"},{value:"moonshine",label:e(u)?`Moonshine (${h(e(u))})`:"Moonshine (CPU only)"},{value:"parakeet",label:e(v)?`Parakeet TDT (${h(e(v))})`:"Parakeet TDT (CPU only)"},{value:"remote-openai",label:"Remote Speech Engine (OpenAI API)"}]),m=ce(()=>l.map(G=>({value:G,label:`${G}${e(q)[G]?" ✔":""}`}))),_=ce(()=>[{value:"auto",label:e(c)?`Auto (${h(e(c))})`:"Auto"},...e(c)?[{value:e(c),label:h(e(c))}]:[],{value:"cpu",label:"CPU"}]);const x=[{value:"base",label:"Base"},{value:"tiny",label:"Tiny"}],M=[{value:"tdt-0.6b-v3",label:"TDT 0.6B v3 (INT8, ~665 MB)"}];let q=S(yt({})),T=S(!1),D=S(!1),se=S(null),ne=S(!0),fe=S(yt({})),Q=S(!1),z=S(!1),I=S(!0),L=S(yt({})),ge=S(!1),ee=S(!1);async function K(){o(ge,!0);const G={};for(const _e of M)try{G[_e.value]=await E("check_parakeet_downloaded",{modelSize:_e.value})}catch(me){console.error("Failed to check Parakeet download status for "+_e.value,me),G[_e.value]=!1}o(L,G,!0),o(ge,!1)}async function V(G){if(!e(ee)){o(ee,!0);try{await E("download_parakeet_model",{modelSize:G}),e(L)[G]=!0}catch(_e){alert(`Failed to download Parakeet model: ${_e}`)}finally{o(ee,!1)}}}async function oe(){var _e,me;r();const G=(me=(_e=t().engine.parakeet)==null?void 0:_e.model_size)!=null?me:"tdt-0.6b-v3";e(I)&&!e(L)[G]&&await V(G)}let R=S(!1),B=S(null),be=S(yt([]));function Ae(){t().engine.remote_openai||t(t().engine.remote_openai={endpoint:"http://localhost:8000/v1",api_key:null,model:"whisper-1",language:"",timeout_secs:30},!0)}async function ue(){if(Ae(),!e(R)){o(R,!0),o(B,null);try{const G=await E("test_remote_stt",{endpoint:t().engine.remote_openai.endpoint||"http://localhost:8000/v1",apiKey:t().engine.remote_openai.api_key||null,model:t().engine.remote_openai.model||"whisper-1",timeoutSecs:t().engine.remote_openai.timeout_secs||30});o(B,{success:G.success,message:G.message},!0),G.models&&G.models.length>0&&(o(be,G.models,!0),t().engine.remote_openai.model||(t(t().engine.remote_openai.model=G.models[0],!0),r()))}catch(G){o(B,{success:!1,message:G.toString()},!0)}finally{o(R,!1)}}}async function j(){o(Q,!0);const G={};for(const _e of x)try{G[_e.value]=await E("check_moonshine_downloaded",{modelSize:_e.value})}catch(me){console.error("Failed to check Moonshine download status for "+_e.value,me),G[_e.value]=!1}o(fe,G,!0),o(Q,!1)}async function J(G){if(!e(z)){o(z,!0);try{await E("download_moonshine_model",{modelSize:G}),e(fe)[G]=!0}catch(_e){alert(`Failed to download Moonshine model: ${_e}`)}finally{o(z,!1)}}}async function Se(){r();const G=t().engine.moonshine.model_size;e(ne)&&!e(fe)[G]&&await J(G)}async function De(){o(T,!0);const G={};for(const _e of l)try{G[_e]=await E("check_model_downloaded",{modelSize:_e,modelDir:t().engine.whisper_cpp.model_dir})}catch(me){console.error("Failed to check download status for model "+_e,me),G[_e]=!1}o(q,G,!0),o(T,!1)}async function le(G){if(!e(D)){o(D,!0);try{await E("download_model",{modelSize:G,modelDir:t().engine.whisper_cpp.model_dir}),e(q)[G]=!0}catch(_e){alert(`Failed to download model: ${_e}`)}finally{o(D,!1)}}}async function W(){r();const G=t().engine.whisper_cpp.model_size;e(q)[G]||await le(G)}async function ae(){const G=t().engine.whisper_cpp.model_dir;if(!G){o(se,null);return}const _e=await E("check_directory_exists",{path:G});o(se,_e?null:"This folder does not exist. Please create it first or leave blank for the default location.",!0),e(se)||await De()}function O(){r()}function X(G){G.key==="Enter"&&G.currentTarget.blur()}qt(async()=>{var _e,me,pe;De();try{o(ne,await E("moonshine_available"),!0)}catch(ze){console.error("Failed to query Moonshine availability",ze)}j();try{o(I,await E("parakeet_available"),!0)}catch(ze){console.error("Failed to query Parakeet availability",ze)}K();try{const ze=await E("accelerator_support");o(c,(_e=ze.whisper_gpu)!=null?_e:null,!0),o(u,(me=ze.moonshine_gpu)!=null?me:null,!0),o(v,(pe=ze.parakeet_gpu)!=null?pe:null,!0)}catch(ze){console.error("Failed to query GPU support",ze)}const G=t().engine.whisper_cpp.device;G!=="auto"&&G!=="cpu"&&G!==e(c)&&(t(t().engine.whisper_cpp.device="auto",!0),r())});var ve=Fv(),Me=i(n(ve),2);{var Fe=G=>{var _e=pv(),me=i(n(_e),2),pe=i(n(me),2),ze=i(n(pe)),Ye=n(ze);w(()=>y(Ye,t().engine.whisper_cpp.model_size)),d(G,_e)};k(Me,G=>{t().engine.backend==="whisper-cpp"&&!e(T)&&!e(q)[t().engine.whisper_cpp.model_size]&&G(Fe)})}var he=i(Me,2),re=i(n(he),2),we=i(n(re),2);sa(we,{get options(){return e(b)},onchange:r,get value(){return t().engine.backend},set value(G){t(t().engine.backend=G,!0)}});var Je=i(he,2);{var de=G=>{var _e=bv(),me=i(n(_e),2),pe=i(n(me),2);sa(pe,{get options(){return e(m)},onchange:W,get value(){return t().engine.whisper_cpp.model_size},set value(Ee){t(t().engine.whisper_cpp.model_size=Ee,!0)}});var ze=i(me,2),Ye=n(ze);{var st=Ee=>{var $e=fv();d(Ee,$e)},it=Ee=>{var $e=_v(),ct=n($e);w(()=>{var vt;return y(ct,`⏳ Downloading ${(vt=t().engine.whisper_cpp.model_size)!=null?vt:""} (GGUF format)...`)}),d(Ee,$e)},H=Ee=>{var $e=hv();d(Ee,$e)},P=Ee=>{var $e=gv(),ct=i(n($e),2);N("click",ct,()=>le(t().engine.whisper_cpp.model_size)),d(Ee,$e)};k(Ye,Ee=>{e(T)?Ee(st):e(D)?Ee(it,1):e(q)[t().engine.whisper_cpp.model_size]?Ee(H,2):Ee(P,-1)})}var C=i(ze,2),ke=i(n(C),2);sa(ke,{get options(){return e(_)},onchange:r,get value(){return t().engine.whisper_cpp.device},set value(Ee){t(t().engine.whisper_cpp.device=Ee,!0)}});var je=i(C,2),ye=i(n(je),2);let Ie;var Ge=i(ye,2);{var Ze=Ee=>{var $e=mv(),ct=n($e);w(()=>y(ct,e(se))),d(Ee,$e)};k(Ge,Ee=>{e(se)&&Ee(Ze)})}var Ve=i(je,2),at=i(n(Ve),2),et=i(Ve,2),rt=i(n(et),2);w(()=>Ie=Te(ye,1,"svelte-nfi4ak",null,Ie,{"field-input-error":!!e(se)})),N("change",ye,O),xs("blur",ye,ae),N("keydown",ye,X),We(ye,()=>t().engine.whisper_cpp.model_dir,Ee=>t(t().engine.whisper_cpp.model_dir=Ee,!0)),N("change",at,r),We(at,()=>t().engine.whisper_cpp.threads,Ee=>t(t().engine.whisper_cpp.threads=Ee,!0)),N("change",rt,r),We(rt,()=>t().engine.whisper_cpp.language,Ee=>t(t().engine.whisper_cpp.language=Ee,!0)),d(G,_e)},Y=G=>{var _e=Cv(),me=i(n(_e),2);{var pe=je=>{var ye=yv();d(je,ye)};k(me,je=>{e(ne)||je(pe)})}var ze=i(me,2);{var Ye=je=>{var ye=wv(),Ie=i(n(ye),2),Ge=i(n(Ie),2),Ze=i(n(Ge),8);w(Ve=>y(Ze,` —
where Whisper.cpp${Ve!=null?Ve:""}. Pick Whisper.cpp if memory
- matters more than Moonshine's latency.`),[()=>e(c)?` puts a quantized model in VRAM via ${h(e(c))}`:" uses a smaller quantized model"]),d(Ke,ye)};k(ze,Ke=>{e(ne)&&!e(u)&&Ke($e)})}var st=i(ze,2),it=i(n(st),2);sa(it,{get options(){return x},onchange:Se,get value(){return t().engine.moonshine.model_size},set value(Ke){t(t().engine.moonshine.model_size=Ke,!0)}});var H=i(st,2);{var M=Ke=>{var ye=Ev(),Ie=n(ye);{var Ye=et=>{var rt=kv();d(et,rt)},Ze=et=>{var rt=xv(),Ee=n(rt);w(()=>{var Ge;return y(Ee,`⏳ Downloading Moonshine ${(Ge=t().engine.moonshine.model_size)!=null?Ge:""} (ONNX)...`)}),d(et,rt)},Ve=et=>{var rt=Tv();d(et,rt)},at=et=>{var rt=Sv(),Ee=i(n(rt),2),Ge=n(Ee);w(()=>{var ct;return y(Ge,`Download ${(ct=t().engine.moonshine.model_size)!=null?ct:""}`)}),N("click",Ee,()=>J(t().engine.moonshine.model_size)),d(et,rt)};k(Ie,et=>{e(Q)?et(Ye):e(z)?et(Ze,1):e(fe)[t().engine.moonshine.model_size]?et(Ve,2):et(at,-1)})}d(Ke,ye)};k(H,Ke=>{e(ne)&&Ke(M)})}var C=i(H,2),ke=i(n(C),2);N("change",ke,r),We(ke,()=>t().engine.moonshine.language,Ke=>t(t().engine.moonshine.language=Ke,!0)),d(Y,_e)},U=Y=>{var _e=Ov(),me=i(n(_e),2);{var pe=C=>{var ke=Av();d(C,ke)};k(me,C=>{e(I)||C(pe)})}var ze=i(me,2),$e=i(n(ze),2);sa($e,{get options(){return A},onchange:oe,get value(){return t().engine.parakeet.model_size},set value(C){t(t().engine.parakeet.model_size=C,!0)}});var st=i(ze,2);{var it=C=>{var ke=Iv(),Ke=n(ke);{var ye=Ve=>{var at=Mv();d(Ve,at)},Ie=Ve=>{var at=Pv(),et=n(at);w(()=>{var rt;return y(et,`⏳ Downloading Parakeet ${(rt=t().engine.parakeet.model_size)!=null?rt:""} (ONNX INT8)...`)}),d(Ve,at)},Ye=Ve=>{var at=Dv();d(Ve,at)},Ze=Ve=>{var at=zv(),et=i(n(at),2),rt=n(et);w(()=>{var Ee;return y(rt,`Download ${(Ee=t().engine.parakeet.model_size)!=null?Ee:""}`)}),N("click",et,()=>V(t().engine.parakeet.model_size)),d(Ve,at)};k(Ke,Ve=>{e(ge)?Ve(ye):e(ee)?Ve(Ie,1):e(L)[t().engine.parakeet.model_size]?Ve(Ye,2):Ve(Ze,-1)})}d(C,ke)};k(st,C=>{e(I)&&C(it)})}var H=i(st,2),M=i(n(H),2);N("change",M,r),We(M,()=>t().engine.parakeet.language,C=>t(t().engine.parakeet.language=C,!0)),d(Y,_e)},te=Y=>{var _e=Vv(),me=i(n(_e),4),pe=i(n(me),2),ze=i(me,4),$e=i(n(ze),2),st=i(ze,4),it=i(n(st),2),H=i(st,2);{var M=Ee=>{var Ge=Rv(),ct=i(n(Ge),2);pt(ct,21,()=>e(be),ft,(vt,nt)=>{var wt=Lv();let dt;var Et=n(wt);w(()=>{dt=Te(wt,1,"tag-btn svelte-nfi4ak",null,dt,{active:t().engine.remote_openai.model===e(nt)}),y(Et,e(nt))}),N("click",wt,()=>{t(t().engine.remote_openai.model=e(nt),!0),r()}),d(vt,wt)}),d(Ee,Ge)};k(H,Ee=>{e(be).length>0&&Ee(M)})}var C=i(H,2),ke=i(n(C),2),Ke=i(C,4),ye=i(n(Ke),2),Ie=i(Ke,2),Ye=n(Ie),Ze=n(Ye);{var Ve=Ee=>{var Ge=Be("⏳ Testing Connection...");d(Ee,Ge)},at=Ee=>{var Ge=Be("🧪 Test Connection");d(Ee,Ge)};k(Ze,Ee=>{e(R)?Ee(Ve):Ee(at,-1)})}var et=i(Ye,2);{var rt=Ee=>{var Ge=Nv();let ct;var vt=n(Ge);{var nt=dt=>{var Et=Be();w(()=>{var Kt;return y(Et,`✔ ${(Kt=e(B).message)!=null?Kt:""}`)}),d(dt,Et)},wt=dt=>{var Et=Be();w(()=>{var Kt;return y(Et,`⚠️ ${(Kt=e(B).message)!=null?Kt:""}`)}),d(dt,Et)};k(vt,dt=>{e(B).success?dt(nt):dt(wt,-1)})}w(()=>ct=Te(Ge,1,"status-pill svelte-nfi4ak",null,ct,{success:e(B).success,error:!e(B).success})),d(Ee,Ge)};k(et,Ee=>{e(B)&&Ee(rt)})}w(()=>Ye.disabled=e(R)),N("change",pe,r),We(pe,()=>t().engine.remote_openai.endpoint,Ee=>t(t().engine.remote_openai.endpoint=Ee,!0)),N("change",$e,r),We($e,()=>t().engine.remote_openai.api_key,Ee=>t(t().engine.remote_openai.api_key=Ee,!0)),N("change",it,r),We(it,()=>t().engine.remote_openai.model,Ee=>t(t().engine.remote_openai.model=Ee,!0)),N("change",ke,r),We(ke,()=>t().engine.remote_openai.language,Ee=>t(t().engine.remote_openai.language=Ee,!0)),N("change",ye,r),We(ye,()=>t().engine.remote_openai.timeout_secs,Ee=>t(t().engine.remote_openai.timeout_secs=Ee,!0)),N("click",Ye,ue),d(Y,_e)};k(Je,Y=>{t().engine.backend==="whisper-cpp"?Y(de):t().engine.backend==="moonshine"?Y($,1):t().engine.backend==="parakeet"?Y(U,2):t().engine.backend==="remote-openai"&&Y(te,3)})}d(s,ve),St()}Qt(["click","change","keydown"]);var qv=p(""),jv=p(''),Uv=p(`
Audio
Input Device
Microphone Monitor
Only opens the microphone stream when recording is triggered, which saves power but cannot capture anything spoken while the microphone is still opening. Turn this off to keep the stream open: the last 300ms before you trigger recording is then kept and included, so a first word spoken early — the one carrying a voice command's "Hey Vox" or "Vox Control" — is not lost.
Voice Activity Detection
Processing
Removes steady background noise (fans, hiss, hum) from the microphone before
- transcription, keeping speech intact. Takes effect on the next recording — no restart needed.
Types dictated text into your active application by default. If your dictation contains Hey Vox <target_name> <text> or Vox Control <target_name> <text> (for example, "Hey Vox, Notes Hello world" or "Vox Control Notes Hello world"), VoxCtrl dynamically reroutes the text to that target instead.
'),$v=p(''),Gv=p('
Shell Executor Settings
Terminal CommandShell command
Use inside the command string as a placeholder to substitute transcribed speech.
'),Yv=p(''),Jv=p('
Each line starts with:
'),Xv=p(`
A strftime pattern, written in UTC. Common pieces: %Y year (2026), %m month (09), %d day (04), %H hour (17), %M minute, %S second, %b month name (Sep), %a weekday (Fri), %p AM/PM, %Z zone (UTC), %% a literal percent. Anything else is written as typed.
+ matters more than Moonshine's latency.`),[()=>e(c)?` puts a quantized model in VRAM via ${h(e(c))}`:" uses a smaller quantized model"]),d(je,ye)};k(ze,je=>{e(ne)&&!e(u)&&je(Ye)})}var st=i(ze,2),it=i(n(st),2);sa(it,{get options(){return x},onchange:Se,get value(){return t().engine.moonshine.model_size},set value(je){t(t().engine.moonshine.model_size=je,!0)}});var H=i(st,2);{var P=je=>{var ye=Ev(),Ie=n(ye);{var Ge=et=>{var rt=kv();d(et,rt)},Ze=et=>{var rt=xv(),Ee=n(rt);w(()=>{var $e;return y(Ee,`⏳ Downloading Moonshine ${($e=t().engine.moonshine.model_size)!=null?$e:""} (ONNX)...`)}),d(et,rt)},Ve=et=>{var rt=Tv();d(et,rt)},at=et=>{var rt=Sv(),Ee=i(n(rt),2),$e=n(Ee);w(()=>{var ct;return y($e,`Download ${(ct=t().engine.moonshine.model_size)!=null?ct:""}`)}),N("click",Ee,()=>J(t().engine.moonshine.model_size)),d(et,rt)};k(Ie,et=>{e(Q)?et(Ge):e(z)?et(Ze,1):e(fe)[t().engine.moonshine.model_size]?et(Ve,2):et(at,-1)})}d(je,ye)};k(H,je=>{e(ne)&&je(P)})}var C=i(H,2),ke=i(n(C),2);N("change",ke,r),We(ke,()=>t().engine.moonshine.language,je=>t(t().engine.moonshine.language=je,!0)),d(G,_e)},U=G=>{var _e=Ov(),me=i(n(_e),2);{var pe=C=>{var ke=Mv();d(C,ke)};k(me,C=>{e(I)||C(pe)})}var ze=i(me,2),Ye=i(n(ze),2);sa(Ye,{get options(){return M},onchange:oe,get value(){return t().engine.parakeet.model_size},set value(C){t(t().engine.parakeet.model_size=C,!0)}});var st=i(ze,2);{var it=C=>{var ke=Iv(),je=n(ke);{var ye=Ve=>{var at=Pv();d(Ve,at)},Ie=Ve=>{var at=Av(),et=n(at);w(()=>{var rt;return y(et,`⏳ Downloading Parakeet ${(rt=t().engine.parakeet.model_size)!=null?rt:""} (ONNX INT8)...`)}),d(Ve,at)},Ge=Ve=>{var at=Dv();d(Ve,at)},Ze=Ve=>{var at=zv(),et=i(n(at),2),rt=n(et);w(()=>{var Ee;return y(rt,`Download ${(Ee=t().engine.parakeet.model_size)!=null?Ee:""}`)}),N("click",et,()=>V(t().engine.parakeet.model_size)),d(Ve,at)};k(je,Ve=>{e(ge)?Ve(ye):e(ee)?Ve(Ie,1):e(L)[t().engine.parakeet.model_size]?Ve(Ge,2):Ve(Ze,-1)})}d(C,ke)};k(st,C=>{e(I)&&C(it)})}var H=i(st,2),P=i(n(H),2);N("change",P,r),We(P,()=>t().engine.parakeet.language,C=>t(t().engine.parakeet.language=C,!0)),d(G,_e)},te=G=>{var _e=Vv(),me=i(n(_e),4),pe=i(n(me),2),ze=i(me,4),Ye=i(n(ze),2),st=i(ze,4),it=i(n(st),2),H=i(st,2);{var P=Ee=>{var $e=Rv(),ct=i(n($e),2);pt(ct,21,()=>e(be),ft,(vt,nt)=>{var wt=Lv();let dt;var Et=n(wt);w(()=>{dt=Te(wt,1,"tag-btn svelte-nfi4ak",null,dt,{active:t().engine.remote_openai.model===e(nt)}),y(Et,e(nt))}),N("click",wt,()=>{t(t().engine.remote_openai.model=e(nt),!0),r()}),d(vt,wt)}),d(Ee,$e)};k(H,Ee=>{e(be).length>0&&Ee(P)})}var C=i(H,2),ke=i(n(C),2),je=i(C,4),ye=i(n(je),2),Ie=i(je,2),Ge=n(Ie),Ze=n(Ge);{var Ve=Ee=>{var $e=Be("⏳ Testing Connection...");d(Ee,$e)},at=Ee=>{var $e=Be("🧪 Test Connection");d(Ee,$e)};k(Ze,Ee=>{e(R)?Ee(Ve):Ee(at,-1)})}var et=i(Ge,2);{var rt=Ee=>{var $e=Nv();let ct;var vt=n($e);{var nt=dt=>{var Et=Be();w(()=>{var jt;return y(Et,`✔ ${(jt=e(B).message)!=null?jt:""}`)}),d(dt,Et)},wt=dt=>{var Et=Be();w(()=>{var jt;return y(Et,`⚠️ ${(jt=e(B).message)!=null?jt:""}`)}),d(dt,Et)};k(vt,dt=>{e(B).success?dt(nt):dt(wt,-1)})}w(()=>ct=Te($e,1,"status-pill svelte-nfi4ak",null,ct,{success:e(B).success,error:!e(B).success})),d(Ee,$e)};k(et,Ee=>{e(B)&&Ee(rt)})}w(()=>Ge.disabled=e(R)),N("change",pe,r),We(pe,()=>t().engine.remote_openai.endpoint,Ee=>t(t().engine.remote_openai.endpoint=Ee,!0)),N("change",Ye,r),We(Ye,()=>t().engine.remote_openai.api_key,Ee=>t(t().engine.remote_openai.api_key=Ee,!0)),N("change",it,r),We(it,()=>t().engine.remote_openai.model,Ee=>t(t().engine.remote_openai.model=Ee,!0)),N("change",ke,r),We(ke,()=>t().engine.remote_openai.language,Ee=>t(t().engine.remote_openai.language=Ee,!0)),N("change",ye,r),We(ye,()=>t().engine.remote_openai.timeout_secs,Ee=>t(t().engine.remote_openai.timeout_secs=Ee,!0)),N("click",Ge,ue),d(G,_e)};k(Je,G=>{t().engine.backend==="whisper-cpp"?G(de):t().engine.backend==="moonshine"?G(Y,1):t().engine.backend==="parakeet"?G(U,2):t().engine.backend==="remote-openai"&&G(te,3)})}d(s,ve),St()}Qt(["click","change","keydown"]);var qv=p("
"),Kv=p(''),Uv=p(`
Audio
Input Device
Microphone Monitor
Only opens the microphone stream when recording is triggered, which saves power but cannot capture anything spoken while the microphone is still opening. Turn this off to keep the stream open: the last 300ms before you trigger recording is then kept and included, so a first word spoken early — the one carrying a voice command's "Hey Vox" or "Vox Control" — is not lost.
Voice Activity Detection
Processing
Removes steady background noise (fans, hiss, hum) from the microphone before
+ transcription, keeping speech intact. Takes effect on the next recording — no restart needed.
Types dictated text into your active application by default. If your dictation contains Hey Vox <target_name> <text> or Vox Control <target_name> <text> (for example, "Hey Vox, Notes Hello world" or "Vox Control Notes Hello world"), VoxCtrl dynamically reroutes the text to that target instead.
'),Yv=p(''),$v=p('
Shell Executor Settings
Terminal CommandShell command
Use inside the command string as a placeholder to substitute transcribed speech.
'),Gv=p(''),Jv=p('
Each line starts with:
'),Xv=p(`
A strftime pattern, written in UTC. Common pieces: %Y year (2026), %m month (09), %d day (04), %H hour (17), %M minute, %S second, %b month name (Sep), %a weekday (Fri), %p AM/PM, %Z zone (UTC), %% a literal percent. Anything else is written as typed.
Default:
`,1),Zv=p('
Local File Writer Settings
'),Qv=p('
Network Socket settings
'),eu=p('
FIFO Named Pipe settings
'),tu=p('
Linux DBus emitter settings
'),au=p(''),su=p(''),nu=p(''),iu=p('
Method
Custom Post BodyJSON Template
Must be valid JSON. Use to substitute transcribed speech.
',1),ru=p(''),lu=p('
Webhook Secret Token (HMAC)
Custom Webhook BodyJSON Template
Must be valid JSON. Use to substitute transcribed speech.
',1),ou=p('
API Endpoint Client settings
REST endpoint URL
'),cu=p(''),du=p('
MCP Server Client settings
Custom Socket/Pipe PathOptional override
Leave empty to use defaults (/tmp/voxctrl-mcp.sock on Linux, \\\\.\\pipe\\voxctrl-mcp on Windows).
MCP Tool Name
Custom Tool ArgumentsJSON Template
Must be valid JSON. Use to substitute transcribed speech.
'),vu=p(''),uu=p(''),pu=p(''),fu=p(""),_u=p(`
Discards this target's stored conversation so the next dictation starts a new
thread. History is in-memory only and is never written to disk.
`),hu=p(`
Conversational LLM settings
Sends each dictation to an OpenAI-compatible /v1/chat/completions endpoint — Hermes, Ollama, llama.cpp —
carrying the running conversation so the model keeps its context between turns.
Server Base URL
The /v1 suffix is optional — it is added automatically.
Model
Press Test & fetch models to confirm the server is reachable and
@@ -30,26 +30,26 @@ var $o=Object.defineProperty;var vl=s=>{throw TypeError(s)};var Go=(s,a,t)=>a in
Casing and punctuation are ignored.
`),gu=p('
Output
'),mu=p(`
Names this target in the app, and is what you say to send dictation here through a
Voice Command Router target: “Hey Vox, ,
buy milk tomorrow” (or “VoxCtrl, ...”). The Target ID works as a spoken name too, so pick something
- easy to say and easy for speech recognition to catch.
`);function Bo(s,a){Tt(a,!0);let t=Ct(a,"editingTarget",15),r=Ct(a,"isNested",3,!1),l=S(""),c=S(""),u=S(""),v=S(yt([])),f=S(!1),h=S(""),b=S(!1);const m="%Y-%m-%dT%H:%M:%SZ";let _=S(""),x=S(null);pa(()=>{var V,oe;const ee=(oe=(V=t())==null?void 0:V.file_timestamp_format)!=null?oe:"";if(!t()||t().delivery!=="file"||!t().file_timestamp){o(x,null),o(_,"");return}let j=!1;return E("preview_timestamp_format",{format:ee}).then(R=>{j||(o(_,R,!0),o(x,null))}).catch(R=>{j||(o(_,""),o(x,`${R}`))}),()=>{j=!0}});let A=ce(()=>!t()||t().delivery!=="exec"||(t().command||"").includes("{text}")?null:"Command must contain '{text}' placeholder."),q=ce(()=>{if(!e(l).trim())return null;try{JSON.parse(e(l))}catch(ee){return"Invalid JSON format: "+ee.message}return e(l).includes("{text}")?null:"Arguments must contain '{text}' placeholder."}),T=ce(()=>{if(!e(c).trim())return null;try{JSON.parse(e(c))}catch(ee){return"Invalid JSON format: "+ee.message}return e(c).includes("{text}")?null:"JSON template must contain '{text}' placeholder."}),D=ce(()=>{if(!e(u).trim())return null;try{JSON.parse(e(u))}catch(ee){return"Invalid JSON format: "+ee.message}return e(u).includes("{text}")?null:"JSON template must contain '{text}' placeholder."}),se=ce(()=>{if(!t()||t().delivery!=="chat")return null;const ee=(t().chat_url||"").trim();return ee?/^https?:\/\//i.test(ee)?null:"URL must start with http:// or https://":"A server base URL is required."}),ne=ce(()=>!t()||t().delivery!=="chat"||(t().chat_model||"").trim()?null:"A model name is required.");async function fe(){if(t()){o(f,!0);try{const ee=await E("test_chat_target",{target:t()});o(v,ee.models,!0),o(h,ee.message,!0),o(b,ee.success,!0),ee.success&&!t().chat_model&&ee.models.length>0&&t(t().chat_model=ee.models[0],!0)}catch(ee){o(v,[],!0),o(h,String(ee),!0),o(b,!1)}finally{o(f,!1)}}}async function Q(){if(t())try{const ee=await E("reset_chat_conversation",{targetId:t().id});o(h,`Conversation cleared (${ee} message(s) discarded).`),o(b,!0)}catch(ee){o(h,String(ee),!0),o(b,!1)}}qt(()=>{var ee,j,V,oe,R;t()&&(t().processing||t(t().processing={},!0),t().file_mode||t(t().file_mode="append",!0),t().file_timestamp_format||t(t().file_timestamp_format=m,!0),t((j=(ee=t()).chat_max_history)!=null?j:ee.chat_max_history=20,!0),t((oe=(V=t()).chat_timeout_secs)!=null?oe:V.chat_timeout_secs=120,!0),t((R=t()).chat_reply_mode||(R.chat_reply_mode="speak"),!0),o(l,t().mcp_args?JSON.stringify(t().mcp_args,null,2):`{
+ easy to say and easy for speech recognition to catch.
`);function Bo(s,a){Tt(a,!0);let t=Ct(a,"editingTarget",15),r=Ct(a,"isNested",3,!1),l=S(""),c=S(""),u=S(""),v=S(yt([])),f=S(!1),h=S(""),b=S(!1);const m="%Y-%m-%dT%H:%M:%SZ";let _=S(""),x=S(null);pa(()=>{var V,oe;const ee=(oe=(V=t())==null?void 0:V.file_timestamp_format)!=null?oe:"";if(!t()||t().delivery!=="file"||!t().file_timestamp){o(x,null),o(_,"");return}let K=!1;return E("preview_timestamp_format",{format:ee}).then(R=>{K||(o(_,R,!0),o(x,null))}).catch(R=>{K||(o(_,""),o(x,`${R}`))}),()=>{K=!0}});let M=ce(()=>!t()||t().delivery!=="exec"||(t().command||"").includes("{text}")?null:"Command must contain '{text}' placeholder."),q=ce(()=>{if(!e(l).trim())return null;try{JSON.parse(e(l))}catch(ee){return"Invalid JSON format: "+ee.message}return e(l).includes("{text}")?null:"Arguments must contain '{text}' placeholder."}),T=ce(()=>{if(!e(c).trim())return null;try{JSON.parse(e(c))}catch(ee){return"Invalid JSON format: "+ee.message}return e(c).includes("{text}")?null:"JSON template must contain '{text}' placeholder."}),D=ce(()=>{if(!e(u).trim())return null;try{JSON.parse(e(u))}catch(ee){return"Invalid JSON format: "+ee.message}return e(u).includes("{text}")?null:"JSON template must contain '{text}' placeholder."}),se=ce(()=>{if(!t()||t().delivery!=="chat")return null;const ee=(t().chat_url||"").trim();return ee?/^https?:\/\//i.test(ee)?null:"URL must start with http:// or https://":"A server base URL is required."}),ne=ce(()=>!t()||t().delivery!=="chat"||(t().chat_model||"").trim()?null:"A model name is required.");async function fe(){if(t()){o(f,!0);try{const ee=await E("test_chat_target",{target:t()});o(v,ee.models,!0),o(h,ee.message,!0),o(b,ee.success,!0),ee.success&&!t().chat_model&&ee.models.length>0&&t(t().chat_model=ee.models[0],!0)}catch(ee){o(v,[],!0),o(h,String(ee),!0),o(b,!1)}finally{o(f,!1)}}}async function Q(){if(t())try{const ee=await E("reset_chat_conversation",{targetId:t().id});o(h,`Conversation cleared (${ee} message(s) discarded).`),o(b,!0)}catch(ee){o(h,String(ee),!0),o(b,!1)}}qt(()=>{var ee,K,V,oe,R;t()&&(t().processing||t(t().processing={},!0),t().file_mode||t(t().file_mode="append",!0),t().file_timestamp_format||t(t().file_timestamp_format=m,!0),t((K=(ee=t()).chat_max_history)!=null?K:ee.chat_max_history=20,!0),t((oe=(V=t()).chat_timeout_secs)!=null?oe:V.chat_timeout_secs=120,!0),t((R=t()).chat_reply_mode||(R.chat_reply_mode="speak"),!0),o(l,t().mcp_args?JSON.stringify(t().mcp_args,null,2):`{
"text": "{text}"
}`,!0),o(c,t().http_json_template?JSON.stringify(t().http_json_template,null,2):`{
"text": "{text}"
}`,!0),o(u,t().webhook_json_template?JSON.stringify(t().webhook_json_template,null,2):`{
"text": "{text}"
-}`,!0))});function z(){if(t()){if(t().id.trim()===""){alert("Target ID cannot be empty.");return}if(t().delivery==="file"&&t().file_timestamp&&e(x)){alert("Validation Error: "+e(x));return}if(t().delivery==="exec"&&e(A)){alert("Validation Error: "+e(A));return}if(t().delivery==="mcp"){if(e(q)){alert("Validation Error: "+e(q));return}try{t(t().mcp_args=JSON.parse(e(l)),!0)}catch{alert("Invalid JSON format in MCP Custom Tool Arguments.");return}}if(t().delivery==="http"){if(e(T)){alert("Validation Error: "+e(T));return}try{t(t().http_json_template=JSON.parse(e(c)),!0)}catch{alert("Invalid JSON format in HTTP Custom Post Body.");return}}if(t().delivery==="webhook"){if(e(D)){alert("Validation Error: "+e(D));return}try{t(t().webhook_json_template=JSON.parse(e(u)),!0)}catch{alert("Invalid JSON format in Webhook Custom Post Body.");return}}if(t().delivery==="chat"){const ee=e(se)||e(ne);if(ee){alert("Validation Error: "+ee);return}t(t().chat_max_history=Number(t().chat_max_history)||0,!0),t(t().chat_timeout_secs=Number(t().chat_timeout_secs)||120,!0)}a.onSave()}}var I=xi(),L=ht(I);{var ge=ee=>{var j=mu(),V=n(j),oe=n(V),R=n(oe),B=n(R),be=i(R,2),Pe=i(oe,2),ue=n(Pe);{var K=ye=>{var Ie=Hv(),Ye=i(n(Ie),2);w(()=>Ye.disabled=!a.isNew),We(Ye,()=>t().id,Ze=>t(t().id=Ze,!0)),d(ye,Ie)};k(ue,ye=>{r()||ye(K)})}var J=i(ue,2),Se=i(n(J),2),De=i(J,2),le=i(n(De)),W=n(le),ae=i(le,2),O=n(ae),X=i(De,2),ve=i(n(X),2);sa(ve,{options:[{value:"command",label:"Voice Command Router (Hey Vox / Vox Control keyword)"},{value:"inject",label:"Inject Text Directly (Simulate keyboard)"},{value:"clipboard",label:"Save to Clipboard"},{value:"exec",label:"Execute Command"},{value:"file",label:"Write to File"},{value:"pipe",label:"FIFO Named Pipe"},{value:"socket",label:"TCP / Unix Socket"},{value:"dbus",label:"DBus Signal"},{value:"http",label:"HTTP Custom Client"},{value:"webhook",label:"Send Webhook Event"},{value:"mcp",label:"Call MCP Server Tool"},{value:"speak",label:"Speak Text Aloud (TTS)"},{value:"chat",label:"Chat with a Local LLM (Hermes / OpenAI-compatible)"}],get value(){return t().delivery},set value(ye){t(t().delivery=ye,!0)}});var Ae=i(X,2);{var Fe=ye=>{var Ie=Wv();d(ye,Ie)};k(Ae,ye=>{t().delivery==="command"&&ye(Fe)})}var he=i(Ae,2);{var re=ye=>{var Ie=Gv(),Ye=i(n(Ie),2),Ze=i(n(Ye),2);mt(Ze,"placeholder","e.g. xdg-open {text}");var Ve=i(Ze,2),at=i(n(Ve));at.textContent="{text}";var et=i(Ve,2);{var rt=Ee=>{var Ge=$v(),ct=n(Ge);w(()=>{var vt;return y(ct,`⚠️ ${(vt=e(A))!=null?vt:""}`)}),d(Ee,Ge)};k(et,Ee=>{e(A)&&Ee(rt)})}w(()=>Te(Ze,1,`full-width-input ${e(A)?"border-red-500! ring-2! ring-red-500/20! focus:border-red-500! focus:ring-red-500/20!":""}`,"svelte-oc07pw")),We(Ze,()=>t().command,Ee=>t(t().command=Ee,!0)),d(ye,Ie)};k(he,ye=>{t().delivery==="exec"&&ye(re)})}var we=i(he,2);{var Je=ye=>{var Ie=Zv(),Ye=i(n(Ie),2),Ze=i(n(Ye),2),Ve=i(Ye,2),at=i(n(Ve),2);sa(at,{options:[{value:"append",label:"Append (Add to end of file)"},{value:"prepend",label:"Prepend (Add to beginning of file)"}],get value(){return t().file_mode},set value(nt){t(t().file_mode=nt,!0)}});var et=i(Ve,2),rt=i(n(et),2),Ee=i(et,2),Ge=n(Ee),ct=i(Ee,2);{var vt=nt=>{var wt=Xv(),dt=ht(wt),Et=i(n(dt),2);mt(Et,"placeholder",m);var Kt=i(dt,2),ia=i(n(Kt),25);ia.textContent="%Y-%m-%dT%H:%M:%SZ";var ra=i(Kt,2);{var bt=Lt=>{var Ht=Yv(),ta=n(Ht);w(()=>{var Oe;return y(ta,`⚠️ ${(Oe=e(x))!=null?Oe:""}`)}),d(Lt,Ht)},ea=Lt=>{var Ht=Jv(),ta=i(n(Ht)),Oe=n(ta);w(()=>{var qe;return y(Oe,`[${(qe=e(_))!=null?qe:""}]`)}),d(Lt,Ht)};k(ra,Lt=>{e(x)?Lt(bt):e(_)&&Lt(ea,1)})}w(()=>Te(Et,1,Ia(e(x)?"border-red-500! ring-2! ring-red-500/20! focus:border-red-500! focus:ring-red-500/20!":""))),We(Et,()=>t().file_timestamp_format,Lt=>t(t().file_timestamp_format=Lt,!0)),d(nt,wt)};k(ct,nt=>{t().file_timestamp&&nt(vt)})}We(Ze,()=>t().file_path,nt=>t(t().file_path=nt,!0)),We(rt,()=>t().file_prefix,nt=>t(t().file_prefix=nt,!0)),Xt(Ge,()=>t().file_timestamp,nt=>t(t().file_timestamp=nt,!0)),d(ye,Ie)};k(we,ye=>{t().delivery==="file"&&ye(Je)})}var de=i(we,2);{var $=ye=>{var Ie=Qv(),Ye=i(n(Ie),2),Ze=i(n(Ye),2),Ve=i(Ye,2),at=i(n(Ve),2),et=i(Ve,2),rt=i(n(et),2);We(Ze,()=>t().socket_host,Ee=>t(t().socket_host=Ee,!0)),We(at,()=>t().socket_port,Ee=>t(t().socket_port=Ee,!0)),We(rt,()=>t().socket_unix,Ee=>t(t().socket_unix=Ee,!0)),d(ye,Ie)};k(de,ye=>{t().delivery==="socket"&&ye($)})}var U=i(de,2);{var te=ye=>{var Ie=eu(),Ye=i(n(Ie),2),Ze=i(n(Ye),2),Ve=i(Ye,2),at=i(n(Ve),2);We(Ze,()=>t().pipe_path,et=>t(t().pipe_path=et,!0)),We(at,()=>t().response_pipe,et=>t(t().response_pipe=et,!0)),d(ye,Ie)};k(U,ye=>{t().delivery==="pipe"&&ye(te)})}var Y=i(U,2);{var _e=ye=>{var Ie=tu(),Ye=i(n(Ie),2),Ze=i(n(Ye),2);We(Ze,()=>t().dbus_signal,Ve=>t(t().dbus_signal=Ve,!0)),d(ye,Ie)};k(Y,ye=>{t().delivery==="dbus"&&ye(_e)})}var me=i(Y,2);{var pe=ye=>{var Ie=ou(),Ye=i(n(Ie),2),Ze=i(n(Ye),2);{var Ve=Ge=>{var ct=au();We(ct,()=>t().http_url,vt=>t(t().http_url=vt,!0)),d(Ge,ct)},at=Ge=>{var ct=su();We(ct,()=>t().webhook_url,vt=>t(t().webhook_url=vt,!0)),d(Ge,ct)};k(Ze,Ge=>{t().delivery==="http"?Ge(Ve):Ge(at,-1)})}var et=i(Ye,2);{var rt=Ge=>{var ct=iu(),vt=ht(ct),nt=i(n(vt),2);sa(nt,{options:[{value:"POST",label:"POST"},{value:"GET",label:"GET"},{value:"PUT",label:"PUT"}],get value(){return t().http_method},set value(bt){t(t().http_method=bt,!0)}});var wt=i(vt,2),dt=i(n(wt),2);mt(dt,"placeholder",'{"text": "{text}"}'),Ms(()=>We(dt,()=>e(c),bt=>o(c,bt))),Fs(dt,bt=>ua==null?void 0:ua(bt));var Et=i(dt,2),Kt=i(n(Et));Kt.textContent="{text}";var ia=i(Et,2);{var ra=bt=>{var ea=nu(),Lt=n(ea);w(()=>{var Ht;return y(Lt,`⚠️ ${(Ht=e(T))!=null?Ht:""}`)}),d(bt,ea)};k(ia,bt=>{e(T)&&bt(ra)})}w(()=>Te(dt,1,Ia(e(T)?"border-red-500! ring-2! ring-red-500/20! focus:border-red-500! focus:ring-red-500/20!":""),"svelte-oc07pw")),d(Ge,ct)},Ee=Ge=>{var ct=lu(),vt=ht(ct),nt=i(n(vt),2),wt=i(vt,2),dt=i(n(wt),2);mt(dt,"placeholder",'{"text": "{text}"}'),Ms(()=>We(dt,()=>e(u),bt=>o(u,bt))),Fs(dt,bt=>ua==null?void 0:ua(bt));var Et=i(dt,2),Kt=i(n(Et));Kt.textContent="{text}";var ia=i(Et,2);{var ra=bt=>{var ea=ru(),Lt=n(ea);w(()=>{var Ht;return y(Lt,`⚠️ ${(Ht=e(D))!=null?Ht:""}`)}),d(bt,ea)};k(ia,bt=>{e(D)&&bt(ra)})}w(()=>Te(dt,1,Ia(e(D)?"border-red-500! ring-2! ring-red-500/20! focus:border-red-500! focus:ring-red-500/20!":""),"svelte-oc07pw")),We(nt,()=>t().webhook_secret,bt=>t(t().webhook_secret=bt,!0)),d(Ge,ct)};k(et,Ge=>{t().delivery==="http"?Ge(rt):Ge(Ee,-1)})}d(ye,Ie)};k(me,ye=>{(t().delivery==="http"||t().delivery==="webhook")&&ye(pe)})}var ze=i(me,2);{var $e=ye=>{var Ie=du(),Ye=i(n(Ie),2),Ze=i(n(Ye),2),Ve=i(Ye,2),at=i(n(Ve),2),et=i(Ve,2),rt=i(n(et),2);mt(rt,"placeholder",'{"text": "{text}"}'),Ms(()=>We(rt,()=>e(l),nt=>o(l,nt))),Fs(rt,nt=>ua==null?void 0:ua(nt));var Ee=i(rt,2),Ge=i(n(Ee));Ge.textContent="{text}";var ct=i(Ee,2);{var vt=nt=>{var wt=cu(),dt=n(wt);w(()=>{var Et;return y(dt,`⚠️ ${(Et=e(q))!=null?Et:""}`)}),d(nt,wt)};k(ct,nt=>{e(q)&&nt(vt)})}w(()=>Te(rt,1,Ia(e(q)?"border-red-500! ring-2! ring-red-500/20! focus:border-red-500! focus:ring-red-500/20!":""),"svelte-oc07pw")),We(Ze,()=>t().mcp_path,nt=>t(t().mcp_path=nt,!0)),We(at,()=>t().mcp_tool,nt=>t(t().mcp_tool=nt,!0)),d(ye,Ie)};k(ze,ye=>{t().delivery==="mcp"&&ye($e)})}var st=i(ze,2);{var it=ye=>{var Ie=hu(),Ye=i(n(Ie),4),Ze=i(n(Ye),2),Ve=i(Ze,4);{var at=ie=>{var xe=vu(),Ce=n(xe);w(()=>{var He;return y(Ce,`⚠️ ${(He=e(se))!=null?He:""}`)}),d(ie,xe)};k(Ve,ie=>{e(se)&&ie(at)})}var et=i(Ye,2),rt=n(et),Ee=i(n(rt),2),Ge=n(Ee),ct=i(rt,2);{var vt=ie=>{{let xe=ce(()=>e(v).map(Ce=>({value:Ce,label:Ce})));sa(ie,{get options(){return e(xe)},get value(){return t().chat_model},set value(Ce){t(t().chat_model=Ce,!0)}})}},nt=ie=>{var xe=uu();w(()=>Te(xe,1,`full-width-input ${e(ne)?"border-red-500! ring-2! ring-red-500/20!":""}`,"svelte-oc07pw")),We(xe,()=>t().chat_model,Ce=>t(t().chat_model=Ce,!0)),d(ie,xe)};k(ct,ie=>{e(v).length>0?ie(vt):ie(nt,-1)})}var wt=i(ct,4);{var dt=ie=>{var xe=pu(),Ce=n(xe);w(()=>{var He;return y(Ce,`⚠️ ${(He=e(ne))!=null?He:""}`)}),d(ie,xe)};k(wt,ie=>{e(ne)&&ie(dt)})}var Et=i(wt,2);{var Kt=ie=>{var xe=fu(),Ce=n(xe);w(()=>{Te(xe,1,`chat-status ${e(b)?"ok":"bad"}`,"svelte-oc07pw"),y(Ce,e(h))}),d(ie,xe)};k(Et,ie=>{e(h)&&ie(Kt)})}var ia=i(et,2),ra=i(n(ia),2),bt=i(ia,2),ea=i(n(bt),2);Ms(()=>We(ea,()=>t().chat_system_prompt,ie=>t(t().chat_system_prompt=ie,!0))),Fs(ea,ie=>ua==null?void 0:ua(ie));var Lt=i(bt,2),Ht=i(n(Lt),2);sa(Ht,{options:[{value:"speak",label:"Speak the reply aloud (TTS)"},{value:"inject",label:"Type the reply into the focused window"},{value:"clipboard",label:"Copy the reply to the clipboard"},{value:"none",label:"Discard the reply (fire and forget)"}],get value(){return t().chat_reply_mode},set value(ie){t(t().chat_reply_mode=ie,!0)}});var ta=i(Lt,2),Oe=i(n(ta),2),qe=i(ta,2),G=i(n(qe),2),g=i(qe,2),P=i(n(g),2),Me=i(g,2);{var Ue=ie=>{var xe=_u(),Ce=n(xe),He=n(Ce);N("click",He,Q),d(ie,xe)};k(Me,ie=>{a.isNew||ie(Ue)})}w(()=>{Te(Ze,1,`full-width-input ${e(se)?"border-red-500! ring-2! ring-red-500/20!":""}`,"svelte-oc07pw"),Ee.disabled=e(f),y(Ge,e(f)?"Connecting…":"Test & fetch models")}),We(Ze,()=>t().chat_url,ie=>t(t().chat_url=ie,!0)),N("click",Ee,fe),We(ra,()=>t().chat_api_key,ie=>t(t().chat_api_key=ie,!0)),We(Oe,()=>t().chat_max_history,ie=>t(t().chat_max_history=ie,!0)),We(G,()=>t().chat_timeout_secs,ie=>t(t().chat_timeout_secs=ie,!0)),We(P,()=>t().chat_reset_phrase,ie=>t(t().chat_reset_phrase=ie,!0)),d(ye,Ie)};k(st,ye=>{t().delivery==="chat"&&ye(it)})}var H=i(st,2);{var M=ye=>{var Ie=gu(),Ye=i(n(Ie),2),Ze=n(Ye);Xt(Ze,()=>t().strip_newlines,Ve=>t(t().strip_newlines=Ve,!0)),d(ye,Ie)};k(H,ye=>{(t().delivery==="inject"||t().delivery==="command")&&ye(M)})}var C=i(Pe,2),ke=n(C),Ke=i(ke,2);w(()=>{Te(j,1,`modal-backdrop ${r()?"target-modal-backdrop":""}`,"svelte-oc07pw"),y(B,a.isNew?"Create Target":"Edit Target"),y(W,t().label||"Obsidian Notes"),y(O,t().label||"Obsidian Notes")}),N("click",be,function(...ye){var Ie;(Ie=a.onCancel)==null||Ie.apply(this,ye)}),We(Se,()=>t().label,ye=>t(t().label=ye,!0)),N("click",ke,function(...ye){var Ie;(Ie=a.onCancel)==null||Ie.apply(this,ye)}),N("click",Ke,z),d(ee,j)};k(L,ee=>{t()&&ee(ge)})}d(s,I),St()}Qt(["click"]);var bu=p(`Your desktop decides which keys VoxCtrl may claim, and may ask you to confirm them.
+}`,!0))});function z(){if(t()){if(t().id.trim()===""){alert("Target ID cannot be empty.");return}if(t().delivery==="file"&&t().file_timestamp&&e(x)){alert("Validation Error: "+e(x));return}if(t().delivery==="exec"&&e(M)){alert("Validation Error: "+e(M));return}if(t().delivery==="mcp"){if(e(q)){alert("Validation Error: "+e(q));return}try{t(t().mcp_args=JSON.parse(e(l)),!0)}catch{alert("Invalid JSON format in MCP Custom Tool Arguments.");return}}if(t().delivery==="http"){if(e(T)){alert("Validation Error: "+e(T));return}try{t(t().http_json_template=JSON.parse(e(c)),!0)}catch{alert("Invalid JSON format in HTTP Custom Post Body.");return}}if(t().delivery==="webhook"){if(e(D)){alert("Validation Error: "+e(D));return}try{t(t().webhook_json_template=JSON.parse(e(u)),!0)}catch{alert("Invalid JSON format in Webhook Custom Post Body.");return}}if(t().delivery==="chat"){const ee=e(se)||e(ne);if(ee){alert("Validation Error: "+ee);return}t(t().chat_max_history=Number(t().chat_max_history)||0,!0),t(t().chat_timeout_secs=Number(t().chat_timeout_secs)||120,!0)}a.onSave()}}var I=xi(),L=ht(I);{var ge=ee=>{var K=mu(),V=n(K),oe=n(V),R=n(oe),B=n(R),be=i(R,2),Ae=i(oe,2),ue=n(Ae);{var j=ye=>{var Ie=Hv(),Ge=i(n(Ie),2);w(()=>Ge.disabled=!a.isNew),We(Ge,()=>t().id,Ze=>t(t().id=Ze,!0)),d(ye,Ie)};k(ue,ye=>{r()||ye(j)})}var J=i(ue,2),Se=i(n(J),2),De=i(J,2),le=i(n(De)),W=n(le),ae=i(le,2),O=n(ae),X=i(De,2),ve=i(n(X),2);sa(ve,{options:[{value:"command",label:"Voice Command Router (Hey Vox / Vox Control keyword)"},{value:"inject",label:"Inject Text Directly (Simulate keyboard)"},{value:"clipboard",label:"Save to Clipboard"},{value:"exec",label:"Execute Command"},{value:"file",label:"Write to File"},{value:"pipe",label:"FIFO Named Pipe"},{value:"socket",label:"TCP / Unix Socket"},{value:"dbus",label:"DBus Signal"},{value:"http",label:"HTTP Custom Client"},{value:"webhook",label:"Send Webhook Event"},{value:"mcp",label:"Call MCP Server Tool"},{value:"speak",label:"Speak Text Aloud (TTS)"},{value:"chat",label:"Chat with a Local LLM (Hermes / OpenAI-compatible)"}],get value(){return t().delivery},set value(ye){t(t().delivery=ye,!0)}});var Me=i(X,2);{var Fe=ye=>{var Ie=Wv();d(ye,Ie)};k(Me,ye=>{t().delivery==="command"&&ye(Fe)})}var he=i(Me,2);{var re=ye=>{var Ie=$v(),Ge=i(n(Ie),2),Ze=i(n(Ge),2);mt(Ze,"placeholder","e.g. xdg-open {text}");var Ve=i(Ze,2),at=i(n(Ve));at.textContent="{text}";var et=i(Ve,2);{var rt=Ee=>{var $e=Yv(),ct=n($e);w(()=>{var vt;return y(ct,`⚠️ ${(vt=e(M))!=null?vt:""}`)}),d(Ee,$e)};k(et,Ee=>{e(M)&&Ee(rt)})}w(()=>Te(Ze,1,`full-width-input ${e(M)?"border-red-500! ring-2! ring-red-500/20! focus:border-red-500! focus:ring-red-500/20!":""}`,"svelte-oc07pw")),We(Ze,()=>t().command,Ee=>t(t().command=Ee,!0)),d(ye,Ie)};k(he,ye=>{t().delivery==="exec"&&ye(re)})}var we=i(he,2);{var Je=ye=>{var Ie=Zv(),Ge=i(n(Ie),2),Ze=i(n(Ge),2),Ve=i(Ge,2),at=i(n(Ve),2);sa(at,{options:[{value:"append",label:"Append (Add to end of file)"},{value:"prepend",label:"Prepend (Add to beginning of file)"}],get value(){return t().file_mode},set value(nt){t(t().file_mode=nt,!0)}});var et=i(Ve,2),rt=i(n(et),2),Ee=i(et,2),$e=n(Ee),ct=i(Ee,2);{var vt=nt=>{var wt=Xv(),dt=ht(wt),Et=i(n(dt),2);mt(Et,"placeholder",m);var jt=i(dt,2),ia=i(n(jt),25);ia.textContent="%Y-%m-%dT%H:%M:%SZ";var ra=i(jt,2);{var bt=Lt=>{var Ht=Gv(),ta=n(Ht);w(()=>{var Oe;return y(ta,`⚠️ ${(Oe=e(x))!=null?Oe:""}`)}),d(Lt,Ht)},ea=Lt=>{var Ht=Jv(),ta=i(n(Ht)),Oe=n(ta);w(()=>{var qe;return y(Oe,`[${(qe=e(_))!=null?qe:""}]`)}),d(Lt,Ht)};k(ra,Lt=>{e(x)?Lt(bt):e(_)&&Lt(ea,1)})}w(()=>Te(Et,1,Ia(e(x)?"border-red-500! ring-2! ring-red-500/20! focus:border-red-500! focus:ring-red-500/20!":""))),We(Et,()=>t().file_timestamp_format,Lt=>t(t().file_timestamp_format=Lt,!0)),d(nt,wt)};k(ct,nt=>{t().file_timestamp&&nt(vt)})}We(Ze,()=>t().file_path,nt=>t(t().file_path=nt,!0)),We(rt,()=>t().file_prefix,nt=>t(t().file_prefix=nt,!0)),Xt($e,()=>t().file_timestamp,nt=>t(t().file_timestamp=nt,!0)),d(ye,Ie)};k(we,ye=>{t().delivery==="file"&&ye(Je)})}var de=i(we,2);{var Y=ye=>{var Ie=Qv(),Ge=i(n(Ie),2),Ze=i(n(Ge),2),Ve=i(Ge,2),at=i(n(Ve),2),et=i(Ve,2),rt=i(n(et),2);We(Ze,()=>t().socket_host,Ee=>t(t().socket_host=Ee,!0)),We(at,()=>t().socket_port,Ee=>t(t().socket_port=Ee,!0)),We(rt,()=>t().socket_unix,Ee=>t(t().socket_unix=Ee,!0)),d(ye,Ie)};k(de,ye=>{t().delivery==="socket"&&ye(Y)})}var U=i(de,2);{var te=ye=>{var Ie=eu(),Ge=i(n(Ie),2),Ze=i(n(Ge),2),Ve=i(Ge,2),at=i(n(Ve),2);We(Ze,()=>t().pipe_path,et=>t(t().pipe_path=et,!0)),We(at,()=>t().response_pipe,et=>t(t().response_pipe=et,!0)),d(ye,Ie)};k(U,ye=>{t().delivery==="pipe"&&ye(te)})}var G=i(U,2);{var _e=ye=>{var Ie=tu(),Ge=i(n(Ie),2),Ze=i(n(Ge),2);We(Ze,()=>t().dbus_signal,Ve=>t(t().dbus_signal=Ve,!0)),d(ye,Ie)};k(G,ye=>{t().delivery==="dbus"&&ye(_e)})}var me=i(G,2);{var pe=ye=>{var Ie=ou(),Ge=i(n(Ie),2),Ze=i(n(Ge),2);{var Ve=$e=>{var ct=au();We(ct,()=>t().http_url,vt=>t(t().http_url=vt,!0)),d($e,ct)},at=$e=>{var ct=su();We(ct,()=>t().webhook_url,vt=>t(t().webhook_url=vt,!0)),d($e,ct)};k(Ze,$e=>{t().delivery==="http"?$e(Ve):$e(at,-1)})}var et=i(Ge,2);{var rt=$e=>{var ct=iu(),vt=ht(ct),nt=i(n(vt),2);sa(nt,{options:[{value:"POST",label:"POST"},{value:"GET",label:"GET"},{value:"PUT",label:"PUT"}],get value(){return t().http_method},set value(bt){t(t().http_method=bt,!0)}});var wt=i(vt,2),dt=i(n(wt),2);mt(dt,"placeholder",'{"text": "{text}"}'),Ps(()=>We(dt,()=>e(c),bt=>o(c,bt))),Fs(dt,bt=>ua==null?void 0:ua(bt));var Et=i(dt,2),jt=i(n(Et));jt.textContent="{text}";var ia=i(Et,2);{var ra=bt=>{var ea=nu(),Lt=n(ea);w(()=>{var Ht;return y(Lt,`⚠️ ${(Ht=e(T))!=null?Ht:""}`)}),d(bt,ea)};k(ia,bt=>{e(T)&&bt(ra)})}w(()=>Te(dt,1,Ia(e(T)?"border-red-500! ring-2! ring-red-500/20! focus:border-red-500! focus:ring-red-500/20!":""),"svelte-oc07pw")),d($e,ct)},Ee=$e=>{var ct=lu(),vt=ht(ct),nt=i(n(vt),2),wt=i(vt,2),dt=i(n(wt),2);mt(dt,"placeholder",'{"text": "{text}"}'),Ps(()=>We(dt,()=>e(u),bt=>o(u,bt))),Fs(dt,bt=>ua==null?void 0:ua(bt));var Et=i(dt,2),jt=i(n(Et));jt.textContent="{text}";var ia=i(Et,2);{var ra=bt=>{var ea=ru(),Lt=n(ea);w(()=>{var Ht;return y(Lt,`⚠️ ${(Ht=e(D))!=null?Ht:""}`)}),d(bt,ea)};k(ia,bt=>{e(D)&&bt(ra)})}w(()=>Te(dt,1,Ia(e(D)?"border-red-500! ring-2! ring-red-500/20! focus:border-red-500! focus:ring-red-500/20!":""),"svelte-oc07pw")),We(nt,()=>t().webhook_secret,bt=>t(t().webhook_secret=bt,!0)),d($e,ct)};k(et,$e=>{t().delivery==="http"?$e(rt):$e(Ee,-1)})}d(ye,Ie)};k(me,ye=>{(t().delivery==="http"||t().delivery==="webhook")&&ye(pe)})}var ze=i(me,2);{var Ye=ye=>{var Ie=du(),Ge=i(n(Ie),2),Ze=i(n(Ge),2),Ve=i(Ge,2),at=i(n(Ve),2),et=i(Ve,2),rt=i(n(et),2);mt(rt,"placeholder",'{"text": "{text}"}'),Ps(()=>We(rt,()=>e(l),nt=>o(l,nt))),Fs(rt,nt=>ua==null?void 0:ua(nt));var Ee=i(rt,2),$e=i(n(Ee));$e.textContent="{text}";var ct=i(Ee,2);{var vt=nt=>{var wt=cu(),dt=n(wt);w(()=>{var Et;return y(dt,`⚠️ ${(Et=e(q))!=null?Et:""}`)}),d(nt,wt)};k(ct,nt=>{e(q)&&nt(vt)})}w(()=>Te(rt,1,Ia(e(q)?"border-red-500! ring-2! ring-red-500/20! focus:border-red-500! focus:ring-red-500/20!":""),"svelte-oc07pw")),We(Ze,()=>t().mcp_path,nt=>t(t().mcp_path=nt,!0)),We(at,()=>t().mcp_tool,nt=>t(t().mcp_tool=nt,!0)),d(ye,Ie)};k(ze,ye=>{t().delivery==="mcp"&&ye(Ye)})}var st=i(ze,2);{var it=ye=>{var Ie=hu(),Ge=i(n(Ie),4),Ze=i(n(Ge),2),Ve=i(Ze,4);{var at=ie=>{var xe=vu(),Ce=n(xe);w(()=>{var He;return y(Ce,`⚠️ ${(He=e(se))!=null?He:""}`)}),d(ie,xe)};k(Ve,ie=>{e(se)&&ie(at)})}var et=i(Ge,2),rt=n(et),Ee=i(n(rt),2),$e=n(Ee),ct=i(rt,2);{var vt=ie=>{{let xe=ce(()=>e(v).map(Ce=>({value:Ce,label:Ce})));sa(ie,{get options(){return e(xe)},get value(){return t().chat_model},set value(Ce){t(t().chat_model=Ce,!0)}})}},nt=ie=>{var xe=uu();w(()=>Te(xe,1,`full-width-input ${e(ne)?"border-red-500! ring-2! ring-red-500/20!":""}`,"svelte-oc07pw")),We(xe,()=>t().chat_model,Ce=>t(t().chat_model=Ce,!0)),d(ie,xe)};k(ct,ie=>{e(v).length>0?ie(vt):ie(nt,-1)})}var wt=i(ct,4);{var dt=ie=>{var xe=pu(),Ce=n(xe);w(()=>{var He;return y(Ce,`⚠️ ${(He=e(ne))!=null?He:""}`)}),d(ie,xe)};k(wt,ie=>{e(ne)&&ie(dt)})}var Et=i(wt,2);{var jt=ie=>{var xe=fu(),Ce=n(xe);w(()=>{Te(xe,1,`chat-status ${e(b)?"ok":"bad"}`,"svelte-oc07pw"),y(Ce,e(h))}),d(ie,xe)};k(Et,ie=>{e(h)&&ie(jt)})}var ia=i(et,2),ra=i(n(ia),2),bt=i(ia,2),ea=i(n(bt),2);Ps(()=>We(ea,()=>t().chat_system_prompt,ie=>t(t().chat_system_prompt=ie,!0))),Fs(ea,ie=>ua==null?void 0:ua(ie));var Lt=i(bt,2),Ht=i(n(Lt),2);sa(Ht,{options:[{value:"speak",label:"Speak the reply aloud (TTS)"},{value:"inject",label:"Type the reply into the focused window"},{value:"clipboard",label:"Copy the reply to the clipboard"},{value:"none",label:"Discard the reply (fire and forget)"}],get value(){return t().chat_reply_mode},set value(ie){t(t().chat_reply_mode=ie,!0)}});var ta=i(Lt,2),Oe=i(n(ta),2),qe=i(ta,2),$=i(n(qe),2),g=i(qe,2),A=i(n(g),2),Pe=i(g,2);{var Ue=ie=>{var xe=_u(),Ce=n(xe),He=n(Ce);N("click",He,Q),d(ie,xe)};k(Pe,ie=>{a.isNew||ie(Ue)})}w(()=>{Te(Ze,1,`full-width-input ${e(se)?"border-red-500! ring-2! ring-red-500/20!":""}`,"svelte-oc07pw"),Ee.disabled=e(f),y($e,e(f)?"Connecting…":"Test & fetch models")}),We(Ze,()=>t().chat_url,ie=>t(t().chat_url=ie,!0)),N("click",Ee,fe),We(ra,()=>t().chat_api_key,ie=>t(t().chat_api_key=ie,!0)),We(Oe,()=>t().chat_max_history,ie=>t(t().chat_max_history=ie,!0)),We($,()=>t().chat_timeout_secs,ie=>t(t().chat_timeout_secs=ie,!0)),We(A,()=>t().chat_reset_phrase,ie=>t(t().chat_reset_phrase=ie,!0)),d(ye,Ie)};k(st,ye=>{t().delivery==="chat"&&ye(it)})}var H=i(st,2);{var P=ye=>{var Ie=gu(),Ge=i(n(Ie),2),Ze=n(Ge);Xt(Ze,()=>t().strip_newlines,Ve=>t(t().strip_newlines=Ve,!0)),d(ye,Ie)};k(H,ye=>{(t().delivery==="inject"||t().delivery==="command")&&ye(P)})}var C=i(Ae,2),ke=n(C),je=i(ke,2);w(()=>{Te(K,1,`modal-backdrop ${r()?"target-modal-backdrop":""}`,"svelte-oc07pw"),y(B,a.isNew?"Create Target":"Edit Target"),y(W,t().label||"Obsidian Notes"),y(O,t().label||"Obsidian Notes")}),N("click",be,function(...ye){var Ie;(Ie=a.onCancel)==null||Ie.apply(this,ye)}),We(Se,()=>t().label,ye=>t(t().label=ye,!0)),N("click",ke,function(...ye){var Ie;(Ie=a.onCancel)==null||Ie.apply(this,ye)}),N("click",je,z),d(ee,K)};k(L,ee=>{t()&&ee(ge)})}d(s,I),St()}Qt(["click"]);var bu=p(`Your desktop decides which keys VoxCtrl may claim, and may ask you to confirm them.
If a shortcut below shows different keys than you chose, that is your desktop's
- choice and it wins.`),yu=p('
'),wu=p('
'),ku=p(''),xu=p('
'),Tu=p('
'),Su=p(" ",1);function Eu(s,a){Tt(a,!0);let t=S(!1),r=S(!1),l=S(!1),c=S(null);async function u(){var _;o(l,!0),o(c,null);try{await E("open_shortcut_settings")}catch(x){o(c,(_=x==null?void 0:x.toString())!=null?_:"Could not open shortcut settings.",!0)}finally{o(l,!1)}}var v=Su(),f=ht(v);{var h=_=>{var x=wu();let A;var q=n(x),T=n(q),D=n(T),se=i(T,2),ne=n(se);{var fe=oe=>{var R=Be("Your desktop is handling these shortcuts");d(oe,R)},Q=oe=>{var R=Be("Reading keystrokes with a keyboard hook");d(oe,R)},z=oe=>{var R=Be("Reading input devices directly");d(oe,R)},I=oe=>{var R=Be("Starting up…");d(oe,R)},L=oe=>{var R=Be("Global shortcuts are not available");d(oe,R)};k(ne,oe=>{a.status.backend==="portal"?oe(fe):a.status.backend==="windows_hook"?oe(Q,1):a.status.backend==="evdev"?oe(z,2):a.status.backend==="starting"?oe(I,3):oe(L,-1)})}var ge=i(se,2);let ee;var j=i(q,2);{var V=oe=>{var R=yu(),B=n(R),be=n(B),Pe=i(B,2);{var ue=K=>{var J=bu();d(K,J)};k(Pe,K=>{a.status.backend==="portal"&&K(ue)})}w(()=>y(be,a.status.detail)),d(oe,R)};k(j,oe=>{e(t)&&oe(V)})}w(()=>{A=Te(x,1,"backend-banner svelte-1hl6idm",null,A,{private:a.status.is_private,warn:!a.status.is_private&&a.status.is_active,broken:!a.status.is_active}),mt(q,"aria-expanded",e(t)),y(D,a.status.is_private?"🔒":a.status.is_active?"⚠️":"⛔"),ee=Te(ge,0,"banner-chevron svelte-1hl6idm",null,ee,{expanded:e(t)})}),N("click",q,()=>o(t,!e(t))),d(_,x)};k(f,_=>{a.status&&_(h)})}var b=i(f,2);{var m=_=>{var x=Tu(),A=n(x),q=i(n(A),4);let T;var D=i(A,2);{var se=ne=>{var fe=xu(),Q=n(fe),z=n(Q),I=i(Q,2),L=n(I),ge=n(L),ee=i(I,2);{var j=V=>{var oe=ku(),R=n(oe);w(()=>y(R,e(c))),d(V,oe)};k(ee,V=>{e(c)&&V(j)})}w(()=>{y(z,a.status.manual_enable_hint),L.disabled=e(l),y(ge,e(l)?"Opening…":"Open Shortcut Settings")}),N("click",L,u),d(ne,fe)};k(D,ne=>{e(r)&&ne(se)})}w(()=>{mt(A,"aria-expanded",e(r)),T=Te(q,0,"banner-chevron svelte-1hl6idm",null,T,{expanded:e(r)})}),N("click",A,()=>o(r,!e(r))),d(_,x)};k(b,_=>{var x;(x=a.status)!=null&&x.needs_manual_enable&&_(m)})}d(s,v),St()}Qt(["click"]);function qo(){return{id:"new_target_"+Math.random().toString(36).substring(2,6),label:"New Target",delivery:"inject",file_prefix:"- ",file_timestamp:!0,file_timestamp_format:"%Y-%m-%dT%H:%M:%SZ",file_mode:"append",http_method:"POST",http_json_template:{text:"{text}"},webhook_json_template:{text:"{text}"},mcp_tool:"speak_text",mcp_args:{text:"{text}"},chat_max_history:20,chat_timeout_secs:120,chat_reply_mode:"speak",strip_newlines:!1,processing:{}}}const Cl={hold:"Hold keys to dictate (Release to transcribe)",toggle:"Tap once to start recording, tap again to finish",double_tap:"Double-tap hotkey to trigger recording",double_tap_hold:"Double-tap & hold keys to dictate (Release to transcribe)"},mr=["hold","toggle","double_tap","double_tap_hold"];function Gs(s,a){const t=[...s].sort().join(",");return`${a}:${t}`}function Al(s,a){return[...s].sort().join(",")===[...a].sort().join(",")}function Ml(s,a=!1){const t=new Map;for(const r of s){if(a&&r.disabled||!r.keys||r.keys.length===0)continue;const l=Gs(r.keys,r.gesture);t.set(l,(t.get(l)||0)+1)}return new Set([...t].filter(([,r])=>r>1).map(([r])=>r))}function Cu(s,a){const t=a.find(r=>r.id===s);return t?t.label:s==="default"?"Focused Window":s}function Au(s,a){return(s.target_ids&&s.target_ids.length>0?s.target_ids:[s.target_id]).map(r=>Cu(r,a)).join(", ")}function Mu(s,a){const t=a.find(r=>r.id===s);return t?`${t.label} (${t.delivery})`:s==="default"?"Focused Window":s}const Pu={ControlLeft:"KEY_LEFTCTRL",ControlRight:"KEY_RIGHTCTRL",AltLeft:"KEY_LEFTALT",AltRight:"KEY_RIGHTALT",ShiftLeft:"KEY_LEFTSHIFT",ShiftRight:"KEY_RIGHTSHIFT",MetaLeft:"KEY_LEFTMETA",MetaRight:"KEY_RIGHTMETA",OSLeft:"KEY_LEFTMETA",OSRight:"KEY_RIGHTMETA",Minus:"KEY_MINUS",Equal:"KEY_EQUAL",BracketLeft:"KEY_LEFTBRACE",BracketRight:"KEY_RIGHTBRACE",Backslash:"KEY_BACKSLASH",Semicolon:"KEY_SEMICOLON",Quote:"KEY_APOSTROPHE",Backquote:"KEY_GRAVE",Comma:"KEY_COMMA",Period:"KEY_DOT",Slash:"KEY_SLASH",IntlBackslash:"KEY_102ND",Numpad0:"KEY_KP0",Numpad1:"KEY_KP1",Numpad2:"KEY_KP2",Numpad3:"KEY_KP3",Numpad4:"KEY_KP4",Numpad5:"KEY_KP5",Numpad6:"KEY_KP6",Numpad7:"KEY_KP7",Numpad8:"KEY_KP8",Numpad9:"KEY_KP9",NumpadAdd:"KEY_KPPLUS",NumpadSubtract:"KEY_KPMINUS",NumpadMultiply:"KEY_KPASTERISK",NumpadDivide:"KEY_KPSLASH",NumpadDecimal:"KEY_KPDOT",NumpadEnter:"KEY_KPENTER",NumpadEqual:"KEY_KPEQUAL"};function il(s,a){const t=Pu[a];if(t)return t;const r=a.toUpperCase();return s==="Control"?"KEY_LEFTCTRL":s==="Alt"?"KEY_LEFTALT":s==="Shift"?"KEY_LEFTSHIFT":s==="Meta"||s==="OS"||s==="Super"?"KEY_LEFTMETA":r==="SPACE"?"KEY_SPACE":r==="ENTER"?"KEY_ENTER":r==="ESCAPE"||r==="ESC"?"KEY_ESC":r==="TAB"?"KEY_TAB":r==="BACKSPACE"?"KEY_BACKSPACE":r==="DELETE"?"KEY_DELETE":/^KEY[A-Z]$/.test(r)?`KEY_${r.slice(3)}`:r.startsWith("KEY")?r:r.startsWith("DIGIT")?`KEY_${r.replace("DIGIT","")}`:r.startsWith("ARROW")?`KEY_${r.replace("ARROW","")}`:r.startsWith("F")&&r.length>1?`KEY_${r}`:s.length===1?`KEY_${s.toUpperCase()}`:`KEY_${r}`}const Du=new Set(["KEY_LEFTCTRL","KEY_RIGHTCTRL","KEY_LEFTALT","KEY_RIGHTALT","KEY_LEFTSHIFT","KEY_RIGHTSHIFT","KEY_LEFTMETA","KEY_RIGHTMETA"]);function Vr(s){return s.length>0&&s.every(a=>Du.has(a))}var zu=p('
⚠️Conflict detected: Some key bindings share the same key combination and gesture type. Disabling one of the conflicting binds will fix the problem.
'),Iu=p('CONFLICT'),Ou=p('LLM'),Lu=p('S1-mini'),Ru=p(''),Nu=p('needs a regular key'),Vu=p('not bound by your desktop'),Fu=p(''),Bu=p('Delete? ',1),qu=p(''),ju=p('
'),Uu=p('
⌨
No keyboard bindings defined. Create a binding to link a physical hotkey to a routing target!
'),Ku=p(''),Hu=p('
',1),Wu=p(''),$u=p('
'),Gu=p(''),Yu=p(`⚠️ This binding uses a gesture this system cannot deliver, so it will not fire.
+ choice and it wins.`),yu=p('
'),wu=p('
'),ku=p(''),xu=p('
'),Tu=p('
'),Su=p(" ",1);function Eu(s,a){Tt(a,!0);let t=S(!1),r=S(!1),l=S(!1),c=S(null);async function u(){var _;o(l,!0),o(c,null);try{await E("open_shortcut_settings")}catch(x){o(c,(_=x==null?void 0:x.toString())!=null?_:"Could not open shortcut settings.",!0)}finally{o(l,!1)}}var v=Su(),f=ht(v);{var h=_=>{var x=wu();let M;var q=n(x),T=n(q),D=n(T),se=i(T,2),ne=n(se);{var fe=oe=>{var R=Be("Your desktop is handling these shortcuts");d(oe,R)},Q=oe=>{var R=Be("Reading keystrokes with a keyboard hook");d(oe,R)},z=oe=>{var R=Be("Reading input devices directly");d(oe,R)},I=oe=>{var R=Be("Starting up…");d(oe,R)},L=oe=>{var R=Be("Global shortcuts are not available");d(oe,R)};k(ne,oe=>{a.status.backend==="portal"?oe(fe):a.status.backend==="windows_hook"?oe(Q,1):a.status.backend==="evdev"?oe(z,2):a.status.backend==="starting"?oe(I,3):oe(L,-1)})}var ge=i(se,2);let ee;var K=i(q,2);{var V=oe=>{var R=yu(),B=n(R),be=n(B),Ae=i(B,2);{var ue=j=>{var J=bu();d(j,J)};k(Ae,j=>{a.status.backend==="portal"&&j(ue)})}w(()=>y(be,a.status.detail)),d(oe,R)};k(K,oe=>{e(t)&&oe(V)})}w(()=>{M=Te(x,1,"backend-banner svelte-1hl6idm",null,M,{private:a.status.is_private,warn:!a.status.is_private&&a.status.is_active,broken:!a.status.is_active}),mt(q,"aria-expanded",e(t)),y(D,a.status.is_private?"🔒":a.status.is_active?"⚠️":"⛔"),ee=Te(ge,0,"banner-chevron svelte-1hl6idm",null,ee,{expanded:e(t)})}),N("click",q,()=>o(t,!e(t))),d(_,x)};k(f,_=>{a.status&&_(h)})}var b=i(f,2);{var m=_=>{var x=Tu(),M=n(x),q=i(n(M),4);let T;var D=i(M,2);{var se=ne=>{var fe=xu(),Q=n(fe),z=n(Q),I=i(Q,2),L=n(I),ge=n(L),ee=i(I,2);{var K=V=>{var oe=ku(),R=n(oe);w(()=>y(R,e(c))),d(V,oe)};k(ee,V=>{e(c)&&V(K)})}w(()=>{y(z,a.status.manual_enable_hint),L.disabled=e(l),y(ge,e(l)?"Opening…":"Open Shortcut Settings")}),N("click",L,u),d(ne,fe)};k(D,ne=>{e(r)&&ne(se)})}w(()=>{mt(M,"aria-expanded",e(r)),T=Te(q,0,"banner-chevron svelte-1hl6idm",null,T,{expanded:e(r)})}),N("click",M,()=>o(r,!e(r))),d(_,x)};k(b,_=>{var x;(x=a.status)!=null&&x.needs_manual_enable&&_(m)})}d(s,v),St()}Qt(["click"]);function qo(){return{id:"new_target_"+Math.random().toString(36).substring(2,6),label:"New Target",delivery:"inject",file_prefix:"- ",file_timestamp:!0,file_timestamp_format:"%Y-%m-%dT%H:%M:%SZ",file_mode:"append",http_method:"POST",http_json_template:{text:"{text}"},webhook_json_template:{text:"{text}"},mcp_tool:"speak_text",mcp_args:{text:"{text}"},chat_max_history:20,chat_timeout_secs:120,chat_reply_mode:"speak",strip_newlines:!1,processing:{}}}const Cl={hold:"Hold keys to dictate (Release to transcribe)",toggle:"Tap once to start recording, tap again to finish",double_tap:"Double-tap hotkey to trigger recording",double_tap_hold:"Double-tap & hold keys to dictate (Release to transcribe)"},mr=["hold","toggle","double_tap","double_tap_hold"];function $s(s,a){const t=[...s].sort().join(",");return`${a}:${t}`}function Ml(s,a){return[...s].sort().join(",")===[...a].sort().join(",")}function Pl(s,a=!1){const t=new Map;for(const r of s){if(a&&r.disabled||!r.keys||r.keys.length===0)continue;const l=$s(r.keys,r.gesture);t.set(l,(t.get(l)||0)+1)}return new Set([...t].filter(([,r])=>r>1).map(([r])=>r))}function Cu(s,a){const t=a.find(r=>r.id===s);return t?t.label:s==="default"?"Focused Window":s}function Mu(s,a){return(s.target_ids&&s.target_ids.length>0?s.target_ids:[s.target_id]).map(r=>Cu(r,a)).join(", ")}function Pu(s,a){const t=a.find(r=>r.id===s);return t?`${t.label} (${t.delivery})`:s==="default"?"Focused Window":s}const Au={ControlLeft:"KEY_LEFTCTRL",ControlRight:"KEY_RIGHTCTRL",AltLeft:"KEY_LEFTALT",AltRight:"KEY_RIGHTALT",ShiftLeft:"KEY_LEFTSHIFT",ShiftRight:"KEY_RIGHTSHIFT",MetaLeft:"KEY_LEFTMETA",MetaRight:"KEY_RIGHTMETA",OSLeft:"KEY_LEFTMETA",OSRight:"KEY_RIGHTMETA",Minus:"KEY_MINUS",Equal:"KEY_EQUAL",BracketLeft:"KEY_LEFTBRACE",BracketRight:"KEY_RIGHTBRACE",Backslash:"KEY_BACKSLASH",Semicolon:"KEY_SEMICOLON",Quote:"KEY_APOSTROPHE",Backquote:"KEY_GRAVE",Comma:"KEY_COMMA",Period:"KEY_DOT",Slash:"KEY_SLASH",IntlBackslash:"KEY_102ND",Numpad0:"KEY_KP0",Numpad1:"KEY_KP1",Numpad2:"KEY_KP2",Numpad3:"KEY_KP3",Numpad4:"KEY_KP4",Numpad5:"KEY_KP5",Numpad6:"KEY_KP6",Numpad7:"KEY_KP7",Numpad8:"KEY_KP8",Numpad9:"KEY_KP9",NumpadAdd:"KEY_KPPLUS",NumpadSubtract:"KEY_KPMINUS",NumpadMultiply:"KEY_KPASTERISK",NumpadDivide:"KEY_KPSLASH",NumpadDecimal:"KEY_KPDOT",NumpadEnter:"KEY_KPENTER",NumpadEqual:"KEY_KPEQUAL",PrintScreen:"KEY_SYSRQ",ContextMenu:"KEY_COMPOSE",AudioVolumeMute:"KEY_MUTE",AudioVolumeDown:"KEY_VOLUMEDOWN",AudioVolumeUp:"KEY_VOLUMEUP",MediaTrackNext:"KEY_NEXTSONG",MediaTrackPrevious:"KEY_PREVIOUSSONG",MediaStop:"KEY_STOPCD",MediaPlayPause:"KEY_PLAYPAUSE"};function il(s,a){const t=Au[a];if(t)return t;const r=a.toUpperCase();return s==="Control"?"KEY_LEFTCTRL":s==="Alt"?"KEY_LEFTALT":s==="Shift"?"KEY_LEFTSHIFT":s==="Meta"||s==="OS"||s==="Super"?"KEY_LEFTMETA":r==="SPACE"?"KEY_SPACE":r==="ENTER"?"KEY_ENTER":r==="ESCAPE"||r==="ESC"?"KEY_ESC":r==="TAB"?"KEY_TAB":r==="BACKSPACE"?"KEY_BACKSPACE":r==="DELETE"?"KEY_DELETE":/^KEY[A-Z]$/.test(r)?`KEY_${r.slice(3)}`:r.startsWith("KEY")?r:r.startsWith("DIGIT")?`KEY_${r.replace("DIGIT","")}`:r.startsWith("ARROW")?`KEY_${r.replace("ARROW","")}`:r.startsWith("F")&&r.length>1?`KEY_${r}`:s.length===1?`KEY_${s.toUpperCase()}`:`KEY_${r}`}const Du=new Set(["KEY_LEFTCTRL","KEY_RIGHTCTRL","KEY_LEFTALT","KEY_RIGHTALT","KEY_LEFTSHIFT","KEY_RIGHTSHIFT","KEY_LEFTMETA","KEY_RIGHTMETA"]);function Vr(s){return s.length>0&&s.every(a=>Du.has(a))}var zu=p('
⚠️Conflict detected: Some key bindings share the same key combination and gesture type. Disabling one of the conflicting binds will fix the problem.
'),Iu=p('CONFLICT'),Ou=p('LLM'),Lu=p('S1-mini'),Ru=p(''),Nu=p('needs a regular key'),Vu=p('not bound by your desktop'),Fu=p(''),Bu=p('Delete? ',1),qu=p(''),Ku=p('
'),Uu=p('
⌨
No keyboard bindings defined. Create a binding to link a physical hotkey to a routing target!
'),ju=p(''),Hu=p('
',1),Wu=p(''),Yu=p('
'),$u=p(''),Gu=p(`⚠️ This binding uses a gesture this system cannot deliver, so it will not fire.
Pick one of the styles above.`),Ju=p(''),Xu=p(``),Zu=p(''),Qu=p('
',1),ep=p(''),tp=p(' (Click / Tab here to record)',1),ap=p(''),sp=p('
🚫That combination was not accepted.
'),np=p('
⚠️
'),ip=p('Your desktop will register this as .'),rp=p('⚠️ Warning: This key combination and gesture type conflicts with another existing binding.'),lp=p('⚠️ Validation Error: Prompt template MUST contain the placeholder.'),op=p('
Prompt template MUST contain the placeholder. Leave empty to inherit the default user prompt.
'),cp=p('
System Prompt OverrideLLM Prompt
Overrides the default system prompt configured in Settings → OpenAI API. Leave empty to inherit it.
User Prompt TemplateLLM Prompt
'),dp=p('
Assign to Output Commands
Hotkey Keybind Selection
OpenAI API LLM Post-Processing
S1-mini Dictation Cleanup
When enabled, remaining text after command processing is normalized by S1-mini before delivery.
'),vp=p('
Hotkey Bindings
Bind keyboard combinations to your output targets. Each hotkey supports customizable triggers (double-taps, holding keys, etc.)
',1);function up(s,a){Tt(a,!0);const t=()=>Zt(Ot,"$config",r),[r,l]=Ea();let c=S(yt([])),u=S(yt([])),v=S(null),f=S(!1),h=S(null),b=S(null),m=S(null),_=S(!1),x=S(null),A=S(null),q=S(!1),T=S(!1),D=S(""),se=S("custom"),ne=S(""),fe=S(""),Q=ce(()=>Ml(e(u))),z=ce(()=>Ml(e(u),!0)),I=ce(()=>{if(!e(v)||!e(v).keys||e(v).keys.length===0)return!1;const M=Gs(e(v).keys,e(v).gesture);return e(u).some(C=>C.id!==e(v).id&&Gs(C.keys,C.gesture)===M)}),L=S(null);async function ge(){try{o(L,await E("check_hotkey_status"),!0)}catch(M){console.error("Failed to read hotkey status:",M)}}let ee=ce(()=>{var C,ke;const M=new Map;for(const Ke of(ke=(C=e(L))==null?void 0:C.shortcuts)!=null?ke:[])for(const ye of Ke.binding_ids)M.set(ye,Ke);return M});const j=ce(()=>{var M,C;return(C=(M=e(L))==null?void 0:M.supported_gestures)!=null&&C.length?mr.filter(ke=>e(L).supported_gestures.includes(ke)):mr}),V=ce(()=>mr.length-e(j).length),oe=ce(()=>{var ke,Ke;const M=e(j).map(ye=>({value:ye,label:Cl[ye]})),C=(ke=e(v))==null?void 0:ke.gesture;return C&&!e(j).includes(C)&&M.push({value:C,label:`${(Ke=Cl[C])!=null?Ke:C} — not supported on this system`}),M});qt(async()=>{o(c,await E("get_targets"),!0),o(u,await E("get_bindings"),!0),await ge()});async function R(){try{await E("save_targets",{targets:e(c)}),console.log("Targets auto-saved successfully!")}catch(M){console.error("Failed to save targets:",M)}}async function B(){try{await E("save_bindings",{bindings:e(u)}),console.log("Bindings auto-saved successfully!"),await ge()}catch(M){console.error("Failed to save bindings:",M)}}const be=M=>Au(M,e(c)),Pe=M=>Mu(M,e(c));function ue(){var M,C,ke,Ke;if(e(c).length===0){alert("Please create at least one Output Command before making a hotkey binding.");return}o(f,!0),o(X,null),o(O,[],!0),o(q,(Ke=(ke=(C=(M=t())==null?void 0:M.engine)==null?void 0:C.s1_mini)==null?void 0:ke.enabled)!=null?Ke:!1,!0),o(T,!1),o(D,""),o(se,"custom"),o(ne,""),o(fe,""),o(v,{id:"binding_"+Math.random().toString(36).substring(2,6),label:"New Binding",keys:[],gesture:e(j).includes("hold")?"hold":e(j)[0],target_id:e(c)[0].id,target_ids:[e(c)[0].id],tap_ms:300,hold_threshold_ms:200,disabled:!1,openai_enabled:!1,openai_model:"",openai_mode:"custom",openai_prompt:"",openai_system_prompt:"",s1_mini_enabled:e(q)},!0)}function K(M){var ke,Ke,ye,Ie;o(f,!1),o(X,null),o(O,[...M.keys],!0);const C=JSON.parse(JSON.stringify(M));C.target_ids||(C.target_ids=C.target_id?[C.target_id]:[]),C.s1_mini_enabled!==void 0&&C.s1_mini_enabled!==null?o(q,C.s1_mini_enabled,!0):o(q,(Ie=(ye=(Ke=(ke=t())==null?void 0:ke.engine)==null?void 0:Ke.s1_mini)==null?void 0:ye.enabled)!=null?Ie:!1,!0),o(T,C.openai_enabled===!0),o(D,C.openai_model||"",!0),o(se,C.openai_mode||"custom",!0),o(ne,C.openai_prompt||"",!0),o(fe,C.openai_system_prompt||"",!0),o(v,C,!0)}async function J(M){o(u,e(u).map(C=>C.id===M?{...C,disabled:!C.disabled}:C),!0),await B()}function Se(){if(!e(v))return;e(v).target_ids||(e(v).target_ids=[e(v).target_id]);const M=e(c).find(ke=>!e(v).target_ids.includes(ke.id)),C=M?M.id:e(c)[0].id;e(v).target_ids=[...e(v).target_ids,C]}function De(M){!e(v)||!e(v).target_ids||(e(v).target_ids=e(v).target_ids.filter((C,ke)=>ke!==M))}async function le(){var C;if(!e(v))return;if(e(v).id.trim()===""){alert("Binding ID cannot be empty.");return}if(e(v).keys.length===0){alert("Please capture at least one hotkey before saving.");return}if(!(!e(f)&&Al(e(v).keys,e(O))))try{const ke=await E("check_hotkey_keys",{keys:e(v).keys});if(!ke.accepted){o(X,ke,!0),alert((C=ke.message)!=null?C:"This key combination cannot be used as a shortcut.");return}}catch(ke){console.error("Failed to validate hotkey keys before saving:",ke)}if(e(T)&&e(se)==="custom"&&!e(ne).includes("{text}")){alert(`LLM Configuration Error:
+ double-taps get missed; lower it if they fire when you did not mean them to.`),Zu=p(''),Qu=p('
',1),ep=p(''),tp=p(' (Click / Tab here to record)',1),ap=p(''),sp=p('
🚫That combination was not accepted.
'),np=p('
⚠️
'),ip=p('Your desktop will register this as .'),rp=p('⚠️ Warning: This key combination and gesture type conflicts with another existing binding.'),lp=p('⚠️ Validation Error: Prompt template MUST contain the placeholder.'),op=p('
Prompt template MUST contain the placeholder. Leave empty to inherit the default user prompt.
'),cp=p('
System Prompt OverrideLLM Prompt
Overrides the default system prompt configured in Settings → OpenAI API. Leave empty to inherit it.
User Prompt TemplateLLM Prompt
'),dp=p('
Assign to Output Commands
Hotkey Keybind Selection
OpenAI API LLM Post-Processing
S1-mini Dictation Cleanup
When enabled, remaining text after command processing is normalized by S1-mini before delivery.
'),vp=p('
Hotkey Bindings
Bind keyboard combinations to your output targets. Each hotkey supports customizable triggers (double-taps, holding keys, etc.)
',1);function up(s,a){Tt(a,!0);const t=()=>Zt(Ot,"$config",r),[r,l]=Ea();let c=S(yt([])),u=S(yt([])),v=S(null),f=S(!1),h=S(null),b=S(null),m=S(null),_=S(!1),x=S(null),M=S(null),q=S(!1),T=S(!1),D=S(""),se=S("custom"),ne=S(""),fe=S(""),Q=ce(()=>Pl(e(u))),z=ce(()=>Pl(e(u),!0)),I=ce(()=>{if(!e(v)||!e(v).keys||e(v).keys.length===0)return!1;const P=$s(e(v).keys,e(v).gesture);return e(u).some(C=>C.id!==e(v).id&&$s(C.keys,C.gesture)===P)}),L=S(null);async function ge(){try{o(L,await E("check_hotkey_status"),!0)}catch(P){console.error("Failed to read hotkey status:",P)}}let ee=ce(()=>{var C,ke;const P=new Map;for(const je of(ke=(C=e(L))==null?void 0:C.shortcuts)!=null?ke:[])for(const ye of je.binding_ids)P.set(ye,je);return P});const K=ce(()=>{var P,C;return(C=(P=e(L))==null?void 0:P.supported_gestures)!=null&&C.length?mr.filter(ke=>e(L).supported_gestures.includes(ke)):mr}),V=ce(()=>mr.length-e(K).length),oe=ce(()=>{var ke,je;const P=e(K).map(ye=>({value:ye,label:Cl[ye]})),C=(ke=e(v))==null?void 0:ke.gesture;return C&&!e(K).includes(C)&&P.push({value:C,label:`${(je=Cl[C])!=null?je:C} — not supported on this system`}),P});qt(async()=>{o(c,await E("get_targets"),!0),o(u,await E("get_bindings"),!0),await ge()});async function R(){try{await E("save_targets",{targets:e(c)}),console.log("Targets auto-saved successfully!")}catch(P){console.error("Failed to save targets:",P)}}async function B(){try{await E("save_bindings",{bindings:e(u)}),console.log("Bindings auto-saved successfully!"),await ge()}catch(P){console.error("Failed to save bindings:",P)}}const be=P=>Mu(P,e(c)),Ae=P=>Pu(P,e(c));function ue(){var P,C,ke,je;if(e(c).length===0){alert("Please create at least one Output Command before making a hotkey binding.");return}o(f,!0),o(X,null),o(O,[],!0),o(q,(je=(ke=(C=(P=t())==null?void 0:P.engine)==null?void 0:C.s1_mini)==null?void 0:ke.enabled)!=null?je:!1,!0),o(T,!1),o(D,""),o(se,"custom"),o(ne,""),o(fe,""),o(v,{id:"binding_"+Math.random().toString(36).substring(2,6),label:"New Binding",keys:[],gesture:e(K).includes("hold")?"hold":e(K)[0],target_id:e(c)[0].id,target_ids:[e(c)[0].id],tap_ms:300,hold_threshold_ms:200,disabled:!1,openai_enabled:!1,openai_model:"",openai_mode:"custom",openai_prompt:"",openai_system_prompt:"",s1_mini_enabled:e(q)},!0)}function j(P){var ke,je,ye,Ie;o(f,!1),o(X,null),o(O,[...P.keys],!0);const C=JSON.parse(JSON.stringify(P));C.target_ids||(C.target_ids=C.target_id?[C.target_id]:[]),C.s1_mini_enabled!==void 0&&C.s1_mini_enabled!==null?o(q,C.s1_mini_enabled,!0):o(q,(Ie=(ye=(je=(ke=t())==null?void 0:ke.engine)==null?void 0:je.s1_mini)==null?void 0:ye.enabled)!=null?Ie:!1,!0),o(T,C.openai_enabled===!0),o(D,C.openai_model||"",!0),o(se,C.openai_mode||"custom",!0),o(ne,C.openai_prompt||"",!0),o(fe,C.openai_system_prompt||"",!0),o(v,C,!0)}async function J(P){o(u,e(u).map(C=>C.id===P?{...C,disabled:!C.disabled}:C),!0),await B()}function Se(){if(!e(v))return;e(v).target_ids||(e(v).target_ids=[e(v).target_id]);const P=e(c).find(ke=>!e(v).target_ids.includes(ke.id)),C=P?P.id:e(c)[0].id;e(v).target_ids=[...e(v).target_ids,C]}function De(P){!e(v)||!e(v).target_ids||(e(v).target_ids=e(v).target_ids.filter((C,ke)=>ke!==P))}async function le(){var C;if(!e(v))return;if(e(v).id.trim()===""){alert("Binding ID cannot be empty.");return}if(e(v).keys.length===0){alert("Please capture at least one hotkey before saving.");return}if(!(!e(f)&&Ml(e(v).keys,e(O))))try{const ke=await E("check_hotkey_keys",{keys:e(v).keys});if(!ke.accepted){o(X,ke,!0),alert((C=ke.message)!=null?C:"This key combination cannot be used as a shortcut.");return}}catch(ke){console.error("Failed to validate hotkey keys before saving:",ke)}if(e(T)&&e(se)==="custom"&&!e(ne).includes("{text}")){alert(`LLM Configuration Error:
Your custom prompt template MUST contain the '{text}' placeholder so the model knows where to insert the transcribed text.
Example:
-write a haiku about {text}`);return}if(e(v).openai_enabled=e(T),e(v).openai_model=e(D),e(v).openai_mode=e(se),e(v).openai_prompt=e(ne),e(v).openai_system_prompt=e(fe),e(v).s1_mini_enabled=e(q),e(v).target_ids&&e(v).target_ids.length>0){if(e(v).target_ids=e(v).target_ids.filter(Ke=>Ke.trim()!==""),e(v).target_ids.length===0){alert("Please assign at least one Output Command.");return}if(new Set(e(v).target_ids).size!==e(v).target_ids.length){alert(`Duplicate commands detected.
-You cannot assign the same Output Command multiple times to a single keybind.`);return}e(v).target_id=e(v).target_ids[0]}else e(v).target_id="",e(v).target_ids=[];if(e(f)){if(e(u).some(ke=>ke.id===e(v).id)){alert("Binding with this ID already exists.");return}o(u,[...e(u),e(v)],!0)}else o(u,e(u).map(ke=>ke.id===e(v).id?e(v):ke),!0);o(v,null),o(h,null),await B()}async function W(M){o(u,e(u).filter(C=>C.id!==M),!0),await B()}let ae=S(yt([])),O=S(yt([]));pa(()=>{E("set_hotkeys_inhibited",{inhibited:e(h)==="keys"}).catch(M=>console.error("Failed to set hotkeys inhibited:",M))});let X=S(null),ve=ce(()=>e(L)===null||e(L).backend==="portal"||e(L).backend==="starting"),Ae=ce(()=>e(h)!=="keys"||!Vr(e(ae))||!e(ve)?null:"Keep holding and add a regular key — modifiers alone cannot be a shortcut.");async function Fe(M){if(!e(v)||M.length===0)return;if(Al(M,e(O))){o(X,null),e(v).keys=[...M];return}let C;try{C=await E("check_hotkey_keys",{keys:M})}catch(ke){console.error("Failed to validate hotkey keys:",ke),e(v).keys=[...M];return}o(X,C,!0),C.accepted&&e(v)&&(e(v).keys=[...M])}function he(M){if(!e(h)||!e(v))return;M.preventDefault(),M.stopPropagation();const C=il(M.key,M.code);if(e(h)==="keys"&&(e(ae).includes(C)||o(ae,[...e(ae),C],!0),M.key==="Escape")){const ke=[...e(ae)];o(ae,[],!0),o(h,null),Fe(ke)}}function re(M){if(!(!e(h)||!e(v))&&(M.preventDefault(),M.stopPropagation(),e(h)==="keys")){const C=[...e(ae)];o(ae,[],!0),o(h,null),Fe(C)}}function we(){if(e(h)){if(e(h)==="keys"&&e(ae).length>0){const M=[...e(ae)];o(ae,[],!0),Fe(M)}o(h,null)}}function Je(M){o(x,M,!0),o(_,!0),o(m,qo(),!0)}function de(){o(m,null),o(x,null)}async function $(){if(e(m)){if(e(c).some(M=>M.id===e(m).id)){alert("Target with this ID already exists.");return}o(c,[...e(c),e(m)],!0),e(x)!==null&&e(v)&&(e(v).target_ids||(e(v).target_ids=[]),e(v).target_ids[e(x)]=e(m).id),o(m,null),o(x,null),await R()}}var U=vp(),te=ht(U),Y=i(n(te),2);Eu(Y,{get status(){return e(L)}});var _e=i(Y,2),me=i(_e,2);{var pe=M=>{var C=zu();d(M,C)};k(me,M=>{e(Q).size>0&&M(pe)})}var ze=i(me,2);pt(ze,21,()=>e(u),ft,(M,C)=>{var ke=ju();let Ke;var ye=n(ke);{var Ie=ie=>{var xe=Iu();d(ie,xe)},Ye=ce(()=>!e(C).disabled&&e(C).keys&&e(C).keys.length>0&&e(z).has(Gs(e(C).keys,e(C).gesture)));k(ye,ie=>{e(Ye)&&ie(Ie)})}var Ze=i(ye,2),Ve=n(Ze),at=n(Ve);let et;var rt=n(at),Ee=i(at,2);{var Ge=ie=>{var xe=Ou();d(ie,xe)};k(Ee,ie=>{e(C).openai_enabled&&ie(Ge)})}var ct=i(Ee,2);{var vt=ie=>{var xe=Lu();d(ie,xe)};k(ct,ie=>{var xe,Ce,He,Xe;((Xe=e(C).s1_mini_enabled)!=null?Xe:(He=(Ce=(xe=t())==null?void 0:xe.engine)==null?void 0:Ce.s1_mini)!=null&&He.enabled)&&ie(vt)})}var nt=i(Ve,2),wt=n(nt);pt(wt,21,()=>e(C).keys,ft,(ie,xe)=>{var Ce=Ru(),He=n(Ce);w(Xe=>y(He,Xe),[()=>e(xe).replace("KEY_","")]),d(ie,Ce)});var dt=i(wt,2),Et=n(dt),Kt=i(dt,2);{var ia=ie=>{var xe=Nu();d(ie,xe)},ra=ce(()=>e(ve)&&Vr(e(C).keys));k(Kt,ie=>{e(ra)&&ie(ia)})}var bt=i(Kt,2);{var ea=ie=>{const xe=ce(()=>e(ee).get(e(C).id));var Ce=xi(),He=ht(Ce);{var Xe=zt=>{var Ft=Vu();d(zt,Ft)},Dt=zt=>{var Ft=Fu(),Wt=n(Ft);w(()=>{var $t;return y(Wt,`desktop: ${($t=e(xe).trigger_description)!=null?$t:""}`)}),d(zt,Ft)};k(He,zt=>{e(xe).bound?e(xe).trigger_description&&zt(Dt,1):zt(Xe)})}d(ie,Ce)},Lt=ce(()=>{var ie;return((ie=e(L))==null?void 0:ie.backend)==="portal"&&!e(C).disabled&&e(ee).get(e(C).id)});k(bt,ie=>{e(Lt)&&ie(ea)})}var Ht=i(nt,2),ta=n(Ht),Oe=i(Ht,2),qe=n(Oe),G=n(qe),g=i(qe,2),P=i(g,2);{var Me=ie=>{var xe=Bu(),Ce=i(ht(xe),2),He=i(Ce,2);N("click",Ce,()=>{W(e(C).id),o(b,null)}),N("click",He,()=>o(b,null)),d(ie,xe)},Ue=ie=>{var xe=qu();N("click",xe,()=>o(b,e(C).id,!0)),d(ie,xe)};k(P,ie=>{e(b)===e(C).id?ie(Me):ie(Ue,-1)})}w((ie,xe,Ce)=>{Ke=Te(ke,1,"binding-item glass svelte-w4d8v7",null,Ke,ie),et=Te(at,1,"binding-title svelte-w4d8v7",null,et,xe),y(rt,e(C).label||e(C).id),y(Et,e(C).gesture),y(ta,Ce),y(G,e(C).disabled?"Enable":"Disable")},[()=>({disabled:e(C).disabled,"has-conflict":e(C).keys&&e(C).keys.length>0&&e(Q).has(Gs(e(C).keys,e(C).gesture)),"active-conflict":!e(C).disabled&&e(C).keys&&e(C).keys.length>0&&e(z).has(Gs(e(C).keys,e(C).gesture))}),()=>({"has-conflict":!e(C).disabled&&e(C).keys&&e(C).keys.length>0&&e(z).has(Gs(e(C).keys,e(C).gesture))}),()=>be(e(C))]),N("click",qe,()=>J(e(C).id)),N("click",g,()=>K(e(C))),d(M,ke)},M=>{var C=Uu();d(M,C)});var $e=i(te,2);{var st=M=>{var C=dp(),ke=n(C),Ke=n(ke),ye=n(Ke),Ie=n(ye),Ye=i(ye,2),Ze=i(Ke,2),Ve=n(Ze),at=i(n(Ve),2),et=i(Ve,2),rt=i(n(et),2),Ee=i(et,2),Ge=n(Ee),ct=i(n(Ge),2),vt=i(Ge,2);pt(vt,21,()=>e(v).target_ids||[],ft,(tt,gt,It)=>{var ut=$u(),At=n(ut),jt=n(At),wa=n(jt),oa=i(jt,2);{var La=Le=>{var je=Hu(),Re=ht(je),Qe=i(Re,2),Jt=n(Qe);pt(Jt,17,()=>e(c),ft,(ka,xa)=>{var Ta=Ku(),la=n(Ta);w(_a=>{var Pa,Ca;Ta.disabled=_a,y(la,`${(Pa=e(xa).label)!=null?Pa:""} (${(Ca=e(xa).delivery)!=null?Ca:""})`)},[()=>e(v).target_ids.includes(e(xa).id)&&e(xa).id!==e(gt)]),N("click",Ta,_a=>{_a.preventDefault(),_a.stopPropagation(),e(v).target_ids[It]=e(xa).id,o(A,null)}),d(ka,Ta)});var Gt=i(Jt,2);N("click",Re,()=>o(A,null)),N("click",Gt,ka=>{ka.preventDefault(),ka.stopPropagation(),o(A,null),Je(It)}),d(Le,je)};k(oa,Le=>{e(A)===It&&Le(La)})}var ja=i(At,2);{var Z=Le=>{var je=Wu();N("click",je,()=>De(It)),d(Le,je)};k(ja,Le=>{It>0&&Le(Z)})}w(Le=>y(wa,Le),[()=>Pe(e(gt))]),N("click",jt,()=>o(A,e(A)===It?null:It,!0)),d(tt,ut)});var nt=i(Ee,2),wt=i(n(nt),2);sa(wt,{get options(){return e(oe)},get value(){return e(v).gesture},set value(tt){e(v).gesture=tt}});var dt=i(wt,2);{var Et=tt=>{var gt=Gu(),It=n(gt);w(()=>{var ut;return y(It,((ut=e(L))==null?void 0:ut.backend)==="mint_dbus"?"Your desktop delivers VoxCtrl's shortcuts itself and only reports the key going down, never coming back up — so hold and double-tap styles cannot work here and are not offered.":`${e(V)} gesture style${e(V)===1?"":"s"} are hidden because the way this system delivers shortcuts cannot produce them.`)}),d(tt,gt)};k(dt,tt=>{e(V)>0&&tt(Et)})}var Kt=i(dt,2);{var ia=tt=>{var gt=Yu();d(tt,gt)},ra=ce(()=>e(v).gesture&&!e(j).includes(e(v).gesture));k(Kt,tt=>{e(ra)&&tt(ia)})}var bt=i(nt,2);{var ea=tt=>{var gt=Ju(),It=i(n(gt),2),ut=i(It,2),At=n(ut);w(()=>y(At,e(v).gesture==="double_tap_hold"?"How long the second tap must stay held before recording starts. Keeps a plain double-tap from being read as a double-tap-and-hold.":"Minimum duration to keep keys pressed to count as a 'hold'.")),We(It,()=>e(v).hold_threshold_ms,jt=>e(v).hold_threshold_ms=jt),d(tt,gt)};k(bt,tt=>{(e(v).gesture==="hold"||e(v).gesture==="double_tap_hold")&&tt(ea)})}var Lt=i(bt,2);{var Ht=tt=>{var gt=Xu(),It=i(n(gt),2);We(It,()=>e(v).tap_ms,ut=>e(v).tap_ms=ut),d(tt,gt)};k(Lt,tt=>{(e(v).gesture==="double_tap"||e(v).gesture==="double_tap_hold")&&tt(Ht)})}var ta=i(Lt,2),Oe=n(ta),qe=i(n(Oe),2),G=n(qe);{var g=tt=>{var gt=Qu(),It=ht(gt),ut=i(n(It),2),At=n(ut),jt=i(It,2);{var wa=oa=>{var La=Zu(),ja=n(La);w(()=>y(ja,e(Ae))),d(oa,La)};k(jt,oa=>{e(Ae)&&oa(wa)})}w(oa=>y(At,oa),[()=>e(ae).length>0?e(ae).join(" + ").replace(/KEY_/g,""):"Press your physical shortcut combination now..."]),d(tt,gt)},P=tt=>{var gt=ap(),It=n(gt);{var ut=jt=>{var wa=tp(),oa=ht(wa);pt(oa,21,()=>e(v).keys,ft,(La,ja)=>{var Z=ep(),Le=n(Z);w(je=>y(Le,je),[()=>e(ja).replace("KEY_","")]),d(La,Z)}),d(jt,wa)},At=jt=>{var wa=Be("⚠️ Click/Focus here to press keys!");d(jt,wa)};k(It,jt=>{e(v).keys.length>0?jt(ut):jt(At,-1)})}d(tt,gt)};k(G,tt=>{e(h)==="keys"?tt(g):tt(P,-1)})}var Me=i(Oe,2);{var Ue=tt=>{var gt=sp(),It=i(n(gt),2),ut=i(n(It));w(()=>{var At;return y(ut,` ${(At=e(X).message)!=null?At:""}`)}),d(tt,gt)},ie=tt=>{var gt=np(),It=i(n(gt),2),ut=n(It);w(()=>y(ut,e(X).message)),d(tt,gt)},xe=tt=>{var gt=ip(),It=i(n(gt)),ut=n(It);w(()=>y(ut,e(X).accelerator)),d(tt,gt)};k(Me,tt=>{var gt;e(X)&&!e(X).accepted?tt(Ue):e(X)&&e(X).problem?tt(ie,1):(gt=e(X))!=null&>.accelerator&&e(ve)&&tt(xe,2)})}var Ce=i(Me,2);{var He=tt=>{var gt=rp();d(tt,gt)};k(Ce,tt=>{e(I)&&tt(He)})}var Xe=i(ta,2),Dt=i(n(Xe),2),zt=n(Dt),Ft=i(Dt,2);{var Wt=tt=>{var gt=cp(),It=n(gt),ut=i(n(It),2),At=i(It,2),jt=i(n(At),2);Ms(()=>We(jt,()=>e(fe),je=>o(fe,je))),Fs(jt,je=>ua==null?void 0:ua(je));var wa=i(At,2),oa=i(n(wa),2);mt(oa,"placeholder","e.g. write a haiku about {text}"),Ms(()=>We(oa,()=>e(ne),je=>o(ne,je))),Fs(oa,je=>ua==null?void 0:ua(je));var La=i(oa,2);{var ja=je=>{var Re=lp(),Qe=i(n(Re));Qe.textContent="{text}",d(je,Re)},Z=ce(()=>e(ne)&&!e(ne).includes("{text}")),Le=je=>{var Re=op(),Qe=i(n(Re));Qe.textContent="{text}",d(je,Re)};k(La,je=>{e(Z)?je(ja):je(Le,-1)})}w(je=>Te(oa,1,je,"svelte-w4d8v7"),[()=>Ia(e(ne)&&!e(ne).includes("{text}")?"border-red-500! ring-2! ring-red-500/20! focus:border-red-500! focus:ring-red-500/20!":"")]),We(ut,()=>e(D),je=>o(D,je)),d(tt,gt)};k(Ft,tt=>{e(T)&&tt(Wt)})}var $t=i(Xe,2),fa=i(n($t),2),Yt=n(fa),ma=i(Ze,2),Oa=n(ma),Ya=i(Oa,2);w(tt=>{y(Ie,e(f)?"Create Hotkey Binding":"Edit Hotkey Binding"),at.disabled=!e(f),Te(qe,1,tt,"svelte-w4d8v7")},[()=>Ia(["border-2 rounded-desktop p-4 text-center cursor-pointer outline-none transition-all duration-200 flex flex-col items-center justify-center min-h-[70px]",e(h)==="keys"?"border-solid border-[#f43f5e] bg-[rgba(244,63,94,0.05)] animate-border-pulse":e(I)?"border-solid border-[#fbbf24] bg-[rgba(251,191,36,0.05)] hover:border-[#fbbf24]/80":"border-dashed border-white/5 bg-black/25 hover:border-accent-blue hover:bg-black/35 focus:border-accent-blue focus:bg-black/35"].join(" "))]),N("click",Ye,()=>{o(v,null),o(h,null)}),We(at,()=>e(v).id,tt=>e(v).id=tt),We(rt,()=>e(v).label,tt=>e(v).label=tt),N("click",ct,Se),N("click",qe,()=>o(h,"keys")),xs("focus",qe,()=>o(h,"keys")),xs("blur",qe,()=>we()),N("keydown",qe,he),N("keyup",qe,re),Xt(zt,()=>e(T),tt=>o(T,tt)),Xt(Yt,()=>e(q),tt=>o(q,tt)),N("click",Oa,()=>{o(v,null),o(h,null)}),N("click",Ya,le),d(M,C)};k($e,M=>{e(v)&&M(st)})}var it=i($e,2);{var H=M=>{Bo(M,{isNew:!0,get existingTargets(){return e(c)},isNested:!0,onSave:$,onCancel:de,get editingTarget(){return e(m)},set editingTarget(C){o(m,C,!0)}})};k(it,M=>{e(m)&&M(H)})}N("click",_e,ue),d(s,U),St(),l()}Qt(["click","keydown","keyup"]);var pp=p('
'),fp=p('
'),_p=p('
'),hp=p('
'),gp=p('
'),mp=p('
'),bp=p('
Speech: Plays transcribed text via TTS
'),yp=p('
'),wp=p('Delete? ',1),kp=p(''),xp=p('
'),Tp=p('
🎯
No output targets defined. Create one to route your transcription output!
'),Sp=p(`
Output Commands
Define routing destinations where transcribed text is typed, copied, piped, or sent over network sockets.
Saying a command by name. Start dictation and say “Hey Vox,” (or “VoxCtrl” / “Vox Control”), then the command's name, then what you want to send — for
+write a haiku about {text}`);return}if(e(v).openai_enabled=e(T),e(v).openai_model=e(D),e(v).openai_mode=e(se),e(v).openai_prompt=e(ne),e(v).openai_system_prompt=e(fe),e(v).s1_mini_enabled=e(q),e(v).target_ids&&e(v).target_ids.length>0){if(e(v).target_ids=e(v).target_ids.filter(je=>je.trim()!==""),e(v).target_ids.length===0){alert("Please assign at least one Output Command.");return}if(new Set(e(v).target_ids).size!==e(v).target_ids.length){alert(`Duplicate commands detected.
+You cannot assign the same Output Command multiple times to a single keybind.`);return}e(v).target_id=e(v).target_ids[0]}else e(v).target_id="",e(v).target_ids=[];if(e(f)){if(e(u).some(ke=>ke.id===e(v).id)){alert("Binding with this ID already exists.");return}o(u,[...e(u),e(v)],!0)}else o(u,e(u).map(ke=>ke.id===e(v).id?e(v):ke),!0);o(v,null),o(h,null),await B()}async function W(P){o(u,e(u).filter(C=>C.id!==P),!0),await B()}let ae=S(yt([])),O=S(yt([]));pa(()=>{E("set_hotkeys_inhibited",{inhibited:e(h)==="keys"}).catch(P=>console.error("Failed to set hotkeys inhibited:",P))});let X=S(null),ve=ce(()=>e(L)===null||e(L).backend==="portal"||e(L).backend==="starting"),Me=ce(()=>e(h)!=="keys"||!Vr(e(ae))||!e(ve)?null:"Keep holding and add a regular key — modifiers alone cannot be a shortcut.");async function Fe(P){if(!e(v)||P.length===0)return;if(Ml(P,e(O))){o(X,null),e(v).keys=[...P];return}let C;try{C=await E("check_hotkey_keys",{keys:P})}catch(ke){console.error("Failed to validate hotkey keys:",ke),e(v).keys=[...P];return}o(X,C,!0),C.accepted&&e(v)&&(e(v).keys=[...P])}function he(P){if(!e(h)||!e(v))return;P.preventDefault(),P.stopPropagation();const C=il(P.key,P.code);if(e(h)==="keys"&&(e(ae).includes(C)||o(ae,[...e(ae),C],!0),P.key==="Escape")){const ke=[...e(ae)];o(ae,[],!0),o(h,null),Fe(ke)}}function re(P){if(!(!e(h)||!e(v))&&(P.preventDefault(),P.stopPropagation(),e(h)==="keys")){const C=[...e(ae)];o(ae,[],!0),o(h,null),Fe(C)}}function we(){if(e(h)){if(e(h)==="keys"&&e(ae).length>0){const P=[...e(ae)];o(ae,[],!0),Fe(P)}o(h,null)}}function Je(P){o(x,P,!0),o(_,!0),o(m,qo(),!0)}function de(){o(m,null),o(x,null)}async function Y(){if(e(m)){if(e(c).some(P=>P.id===e(m).id)){alert("Target with this ID already exists.");return}o(c,[...e(c),e(m)],!0),e(x)!==null&&e(v)&&(e(v).target_ids||(e(v).target_ids=[]),e(v).target_ids[e(x)]=e(m).id),o(m,null),o(x,null),await R()}}var U=vp(),te=ht(U),G=i(n(te),2);Eu(G,{get status(){return e(L)}});var _e=i(G,2),me=i(_e,2);{var pe=P=>{var C=zu();d(P,C)};k(me,P=>{e(Q).size>0&&P(pe)})}var ze=i(me,2);pt(ze,21,()=>e(u),ft,(P,C)=>{var ke=Ku();let je;var ye=n(ke);{var Ie=ie=>{var xe=Iu();d(ie,xe)},Ge=ce(()=>!e(C).disabled&&e(C).keys&&e(C).keys.length>0&&e(z).has($s(e(C).keys,e(C).gesture)));k(ye,ie=>{e(Ge)&&ie(Ie)})}var Ze=i(ye,2),Ve=n(Ze),at=n(Ve);let et;var rt=n(at),Ee=i(at,2);{var $e=ie=>{var xe=Ou();d(ie,xe)};k(Ee,ie=>{e(C).openai_enabled&&ie($e)})}var ct=i(Ee,2);{var vt=ie=>{var xe=Lu();d(ie,xe)};k(ct,ie=>{var xe,Ce,He,Xe;((Xe=e(C).s1_mini_enabled)!=null?Xe:(He=(Ce=(xe=t())==null?void 0:xe.engine)==null?void 0:Ce.s1_mini)!=null&&He.enabled)&&ie(vt)})}var nt=i(Ve,2),wt=n(nt);pt(wt,21,()=>e(C).keys,ft,(ie,xe)=>{var Ce=Ru(),He=n(Ce);w(Xe=>y(He,Xe),[()=>e(xe).replace("KEY_","")]),d(ie,Ce)});var dt=i(wt,2),Et=n(dt),jt=i(dt,2);{var ia=ie=>{var xe=Nu();d(ie,xe)},ra=ce(()=>e(ve)&&Vr(e(C).keys));k(jt,ie=>{e(ra)&&ie(ia)})}var bt=i(jt,2);{var ea=ie=>{const xe=ce(()=>e(ee).get(e(C).id));var Ce=xi(),He=ht(Ce);{var Xe=zt=>{var Ft=Vu();d(zt,Ft)},Dt=zt=>{var Ft=Fu(),Wt=n(Ft);w(()=>{var Yt;return y(Wt,`desktop: ${(Yt=e(xe).trigger_description)!=null?Yt:""}`)}),d(zt,Ft)};k(He,zt=>{e(xe).bound?e(xe).trigger_description&&zt(Dt,1):zt(Xe)})}d(ie,Ce)},Lt=ce(()=>{var ie;return((ie=e(L))==null?void 0:ie.backend)==="portal"&&!e(C).disabled&&e(ee).get(e(C).id)});k(bt,ie=>{e(Lt)&&ie(ea)})}var Ht=i(nt,2),ta=n(Ht),Oe=i(Ht,2),qe=n(Oe),$=n(qe),g=i(qe,2),A=i(g,2);{var Pe=ie=>{var xe=Bu(),Ce=i(ht(xe),2),He=i(Ce,2);N("click",Ce,()=>{W(e(C).id),o(b,null)}),N("click",He,()=>o(b,null)),d(ie,xe)},Ue=ie=>{var xe=qu();N("click",xe,()=>o(b,e(C).id,!0)),d(ie,xe)};k(A,ie=>{e(b)===e(C).id?ie(Pe):ie(Ue,-1)})}w((ie,xe,Ce)=>{je=Te(ke,1,"binding-item glass svelte-w4d8v7",null,je,ie),et=Te(at,1,"binding-title svelte-w4d8v7",null,et,xe),y(rt,e(C).label||e(C).id),y(Et,e(C).gesture),y(ta,Ce),y($,e(C).disabled?"Enable":"Disable")},[()=>({disabled:e(C).disabled,"has-conflict":e(C).keys&&e(C).keys.length>0&&e(Q).has($s(e(C).keys,e(C).gesture)),"active-conflict":!e(C).disabled&&e(C).keys&&e(C).keys.length>0&&e(z).has($s(e(C).keys,e(C).gesture))}),()=>({"has-conflict":!e(C).disabled&&e(C).keys&&e(C).keys.length>0&&e(z).has($s(e(C).keys,e(C).gesture))}),()=>be(e(C))]),N("click",qe,()=>J(e(C).id)),N("click",g,()=>j(e(C))),d(P,ke)},P=>{var C=Uu();d(P,C)});var Ye=i(te,2);{var st=P=>{var C=dp(),ke=n(C),je=n(ke),ye=n(je),Ie=n(ye),Ge=i(ye,2),Ze=i(je,2),Ve=n(Ze),at=i(n(Ve),2),et=i(Ve,2),rt=i(n(et),2),Ee=i(et,2),$e=n(Ee),ct=i(n($e),2),vt=i($e,2);pt(vt,21,()=>e(v).target_ids||[],ft,(tt,gt,It)=>{var ut=Yu(),Mt=n(ut),Kt=n(Mt),wa=n(Kt),oa=i(Kt,2);{var La=Le=>{var Ke=Hu(),Re=ht(Ke),Qe=i(Re,2),Jt=n(Qe);pt(Jt,17,()=>e(c),ft,(ka,xa)=>{var Ta=ju(),la=n(Ta);w(_a=>{var Aa,Ca;Ta.disabled=_a,y(la,`${(Aa=e(xa).label)!=null?Aa:""} (${(Ca=e(xa).delivery)!=null?Ca:""})`)},[()=>e(v).target_ids.includes(e(xa).id)&&e(xa).id!==e(gt)]),N("click",Ta,_a=>{_a.preventDefault(),_a.stopPropagation(),e(v).target_ids[It]=e(xa).id,o(M,null)}),d(ka,Ta)});var $t=i(Jt,2);N("click",Re,()=>o(M,null)),N("click",$t,ka=>{ka.preventDefault(),ka.stopPropagation(),o(M,null),Je(It)}),d(Le,Ke)};k(oa,Le=>{e(M)===It&&Le(La)})}var Ka=i(Mt,2);{var Z=Le=>{var Ke=Wu();N("click",Ke,()=>De(It)),d(Le,Ke)};k(Ka,Le=>{It>0&&Le(Z)})}w(Le=>y(wa,Le),[()=>Ae(e(gt))]),N("click",Kt,()=>o(M,e(M)===It?null:It,!0)),d(tt,ut)});var nt=i(Ee,2),wt=i(n(nt),2);sa(wt,{get options(){return e(oe)},get value(){return e(v).gesture},set value(tt){e(v).gesture=tt}});var dt=i(wt,2);{var Et=tt=>{var gt=$u(),It=n(gt);w(()=>{var ut;return y(It,((ut=e(L))==null?void 0:ut.backend)==="mint_dbus"?"Your desktop delivers VoxCtrl's shortcuts itself and only reports the key going down, never coming back up — so hold and double-tap styles cannot work here and are not offered.":`${e(V)} gesture style${e(V)===1?"":"s"} are hidden because the way this system delivers shortcuts cannot produce them.`)}),d(tt,gt)};k(dt,tt=>{e(V)>0&&tt(Et)})}var jt=i(dt,2);{var ia=tt=>{var gt=Gu();d(tt,gt)},ra=ce(()=>e(v).gesture&&!e(K).includes(e(v).gesture));k(jt,tt=>{e(ra)&&tt(ia)})}var bt=i(nt,2);{var ea=tt=>{var gt=Ju(),It=i(n(gt),2),ut=i(It,2),Mt=n(ut);w(()=>y(Mt,e(v).gesture==="double_tap_hold"?"How long the second tap must stay held before recording starts. Keeps a plain double-tap from being read as a double-tap-and-hold.":"Minimum duration to keep keys pressed to count as a 'hold'.")),We(It,()=>e(v).hold_threshold_ms,Kt=>e(v).hold_threshold_ms=Kt),d(tt,gt)};k(bt,tt=>{(e(v).gesture==="hold"||e(v).gesture==="double_tap_hold")&&tt(ea)})}var Lt=i(bt,2);{var Ht=tt=>{var gt=Xu(),It=i(n(gt),2);We(It,()=>e(v).tap_ms,ut=>e(v).tap_ms=ut),d(tt,gt)};k(Lt,tt=>{(e(v).gesture==="double_tap"||e(v).gesture==="double_tap_hold")&&tt(Ht)})}var ta=i(Lt,2),Oe=n(ta),qe=i(n(Oe),2),$=n(qe);{var g=tt=>{var gt=Qu(),It=ht(gt),ut=i(n(It),2),Mt=n(ut),Kt=i(It,2);{var wa=oa=>{var La=Zu(),Ka=n(La);w(()=>y(Ka,e(Me))),d(oa,La)};k(Kt,oa=>{e(Me)&&oa(wa)})}w(oa=>y(Mt,oa),[()=>e(ae).length>0?e(ae).join(" + ").replace(/KEY_/g,""):"Press your physical shortcut combination now..."]),d(tt,gt)},A=tt=>{var gt=ap(),It=n(gt);{var ut=Kt=>{var wa=tp(),oa=ht(wa);pt(oa,21,()=>e(v).keys,ft,(La,Ka)=>{var Z=ep(),Le=n(Z);w(Ke=>y(Le,Ke),[()=>e(Ka).replace("KEY_","")]),d(La,Z)}),d(Kt,wa)},Mt=Kt=>{var wa=Be("⚠️ Click/Focus here to press keys!");d(Kt,wa)};k(It,Kt=>{e(v).keys.length>0?Kt(ut):Kt(Mt,-1)})}d(tt,gt)};k($,tt=>{e(h)==="keys"?tt(g):tt(A,-1)})}var Pe=i(Oe,2);{var Ue=tt=>{var gt=sp(),It=i(n(gt),2),ut=i(n(It));w(()=>{var Mt;return y(ut,` ${(Mt=e(X).message)!=null?Mt:""}`)}),d(tt,gt)},ie=tt=>{var gt=np(),It=i(n(gt),2),ut=n(It);w(()=>y(ut,e(X).message)),d(tt,gt)},xe=tt=>{var gt=ip(),It=i(n(gt)),ut=n(It);w(()=>y(ut,e(X).accelerator)),d(tt,gt)};k(Pe,tt=>{var gt;e(X)&&!e(X).accepted?tt(Ue):e(X)&&e(X).problem?tt(ie,1):(gt=e(X))!=null&>.accelerator&&e(ve)&&tt(xe,2)})}var Ce=i(Pe,2);{var He=tt=>{var gt=rp();d(tt,gt)};k(Ce,tt=>{e(I)&&tt(He)})}var Xe=i(ta,2),Dt=i(n(Xe),2),zt=n(Dt),Ft=i(Dt,2);{var Wt=tt=>{var gt=cp(),It=n(gt),ut=i(n(It),2),Mt=i(It,2),Kt=i(n(Mt),2);Ps(()=>We(Kt,()=>e(fe),Ke=>o(fe,Ke))),Fs(Kt,Ke=>ua==null?void 0:ua(Ke));var wa=i(Mt,2),oa=i(n(wa),2);mt(oa,"placeholder","e.g. write a haiku about {text}"),Ps(()=>We(oa,()=>e(ne),Ke=>o(ne,Ke))),Fs(oa,Ke=>ua==null?void 0:ua(Ke));var La=i(oa,2);{var Ka=Ke=>{var Re=lp(),Qe=i(n(Re));Qe.textContent="{text}",d(Ke,Re)},Z=ce(()=>e(ne)&&!e(ne).includes("{text}")),Le=Ke=>{var Re=op(),Qe=i(n(Re));Qe.textContent="{text}",d(Ke,Re)};k(La,Ke=>{e(Z)?Ke(Ka):Ke(Le,-1)})}w(Ke=>Te(oa,1,Ke,"svelte-w4d8v7"),[()=>Ia(e(ne)&&!e(ne).includes("{text}")?"border-red-500! ring-2! ring-red-500/20! focus:border-red-500! focus:ring-red-500/20!":"")]),We(ut,()=>e(D),Ke=>o(D,Ke)),d(tt,gt)};k(Ft,tt=>{e(T)&&tt(Wt)})}var Yt=i(Xe,2),fa=i(n(Yt),2),Gt=n(fa),ma=i(Ze,2),Oa=n(ma),Ga=i(Oa,2);w(tt=>{y(Ie,e(f)?"Create Hotkey Binding":"Edit Hotkey Binding"),at.disabled=!e(f),Te(qe,1,tt,"svelte-w4d8v7")},[()=>Ia(["border-2 rounded-desktop p-4 text-center cursor-pointer outline-none transition-all duration-200 flex flex-col items-center justify-center min-h-[70px]",e(h)==="keys"?"border-solid border-[#f43f5e] bg-[rgba(244,63,94,0.05)] animate-border-pulse":e(I)?"border-solid border-[#fbbf24] bg-[rgba(251,191,36,0.05)] hover:border-[#fbbf24]/80":"border-dashed border-white/5 bg-black/25 hover:border-accent-blue hover:bg-black/35 focus:border-accent-blue focus:bg-black/35"].join(" "))]),N("click",Ge,()=>{o(v,null),o(h,null)}),We(at,()=>e(v).id,tt=>e(v).id=tt),We(rt,()=>e(v).label,tt=>e(v).label=tt),N("click",ct,Se),N("click",qe,()=>o(h,"keys")),xs("focus",qe,()=>o(h,"keys")),xs("blur",qe,()=>we()),N("keydown",qe,he),N("keyup",qe,re),Xt(zt,()=>e(T),tt=>o(T,tt)),Xt(Gt,()=>e(q),tt=>o(q,tt)),N("click",Oa,()=>{o(v,null),o(h,null)}),N("click",Ga,le),d(P,C)};k(Ye,P=>{e(v)&&P(st)})}var it=i(Ye,2);{var H=P=>{Bo(P,{isNew:!0,get existingTargets(){return e(c)},isNested:!0,onSave:Y,onCancel:de,get editingTarget(){return e(m)},set editingTarget(C){o(m,C,!0)}})};k(it,P=>{e(m)&&P(H)})}N("click",_e,ue),d(s,U),St(),l()}Qt(["click","keydown","keyup"]);var pp=p('
'),fp=p('
'),_p=p('
'),hp=p('
'),gp=p('
'),mp=p('
'),bp=p('
Speech: Plays transcribed text via TTS
'),yp=p('
'),wp=p('Delete? ',1),kp=p(''),xp=p('
'),Tp=p('
🎯
No output targets defined. Create one to route your transcription output!
'),Sp=p(`
Output Commands
Define routing destinations where transcribed text is typed, copied, piped, or sent over network sockets.
Saying a command by name. Start dictation and say “Hey Vox,” (or “VoxCtrl” / “Vox Control”), then the command's name, then what you want to send — for
example “Hey Vox, notes, remember to call the plumber” or “VoxCtrl notes, remember to call the plumber” routes remember to call the plumber to the command named notes.
Everything after the name is the text. Natural phrasing works too
(“Hey Vox, add this to my notes: …”). Say nothing of the sort and
- dictation goes wherever your hotkey already points.
`,1);function Ep(s,a){Tt(a,!0);let t=S(yt([])),r=S(yt([])),l=S(null),c=S(!1),u=S(null),v=S(null);qt(async()=>{o(t,await E("get_targets"),!0),o(r,await E("get_bindings"),!0)});async function f(){try{await E("save_targets",{targets:e(t)}),console.log("Targets auto-saved successfully!")}catch(Q){console.error("Failed to save targets:",Q)}}async function h(){try{await E("save_bindings",{bindings:e(r)}),console.log("Bindings auto-saved successfully!")}catch(Q){console.error("Failed to save bindings:",Q)}}function b(){o(c,!0),o(l,qo(),!0)}function m(Q){o(c,!1),o(u,Q.id,!0);const z=JSON.parse(JSON.stringify(Q));z.processing||(z.processing={}),z.file_mode||(z.file_mode="append"),o(l,z,!0)}function _(){o(l,null),o(u,null)}async function x(){if(e(l)){if(e(c))o(t,[...e(t),e(l)],!0);else{if(e(u)&&e(u)!==e(l).id){let Q=!1;o(r,e(r).map(z=>{let I=!1,L=z.target_ids?[...z.target_ids]:[z.target_id];for(let ge=0;geQ.id===e(u)?e(l):Q),!0)}o(l,null),o(u,null),await f()}}async function A(Q){const z=e(r).filter(I=>(I.target_ids&&I.target_ids.length>0?I.target_ids:[I.target_id]).includes(Q)).map(I=>I.label||I.id);if(z.length>0){alert(`Cannot delete target. It is currently being used by hotkeys: ${z.join(", ")}`);return}o(t,e(t).filter(I=>I.id!==Q),!0),await f()}var q=Sp(),T=ht(q),D=i(n(T),4),se=i(D,2);pt(se,21,()=>e(t),ft,(Q,z)=>{var I=xp(),L=n(I),ge=n(L),ee=n(ge),j=n(ee),V=i(ee,2),oe=n(V),R=i(ge,2);{var B=de=>{var $=pp(),U=n($);w(()=>{var te;return y(U,`Cmd: ${(te=e(z).command)!=null?te:""}`)}),d(de,$)};k(R,de=>{e(z).delivery==="exec"&&de(B)})}var be=i(R,2);{var Pe=de=>{var $=fp(),U=n($);w(()=>{var te;return y(U,`File: ${(te=e(z).file_path)!=null?te:""}`)}),d(de,$)};k(be,de=>{e(z).delivery==="file"&&de(Pe)})}var ue=i(be,2);{var K=de=>{var $=_p(),U=n($);w(()=>{var te,Y;return y(U,`Socket: ${(te=e(z).socket_host)!=null?te:""}:${(Y=e(z).socket_port)!=null?Y:""}`)}),d(de,$)};k(ue,de=>{e(z).delivery==="socket"&&de(K)})}var J=i(ue,2);{var Se=de=>{var $=hp(),U=n($),te=i(U);{var Y=_e=>{var me=Be();w(()=>{var pe;return y(me,`→ ${(pe=e(z).response_pipe)!=null?pe:""}`)}),d(_e,me)};k(te,_e=>{e(z).response_pipe&&_e(Y)})}w(()=>{var _e;return y(U,`Pipe: ${(_e=e(z).pipe_path)!=null?_e:""} `)}),d(de,$)};k(J,de=>{e(z).delivery==="pipe"&&de(Se)})}var De=i(J,2);{var le=de=>{var $=gp(),U=n($);w(()=>{var te;return y(U,`API: ${(te=e(z).http_url||e(z).webhook_url)!=null?te:""}`)}),d(de,$)};k(De,de=>{(e(z).delivery==="http"||e(z).delivery==="webhook")&&de(le)})}var W=i(De,2);{var ae=de=>{var $=mp(),U=n($);w(()=>{var te;return y(U,`MCP Tool: ${(te=e(z).mcp_tool||"speak_text")!=null?te:""}`)}),d(de,$)};k(W,de=>{e(z).delivery==="mcp"&&de(ae)})}var O=i(W,2);{var X=de=>{var $=bp();d(de,$)};k(O,de=>{e(z).delivery==="speak"&&de(X)})}var ve=i(O,2);{var Ae=de=>{var $=yp(),U=n($);w(()=>{var te,Y,_e;return y(U,`Chat: ${(te=e(z).chat_model||"no model")!=null?te:""} @ ${(Y=e(z).chat_url||"no endpoint")!=null?Y:""} → ${(_e=e(z).chat_reply_mode||"speak")!=null?_e:""}`)}),d(de,$)};k(ve,de=>{e(z).delivery==="chat"&&de(Ae)})}var Fe=i(ve,2),he=n(Fe),re=i(he,2);{var we=de=>{var $=wp(),U=i(ht($),2),te=i(U,2);N("click",U,()=>{A(e(z).id),o(v,null)}),N("click",te,()=>o(v,null)),d(de,$)},Je=de=>{var $=kp();N("click",$,()=>o(v,e(z).id,!0)),d(de,$)};k(re,de=>{e(v)===e(z).id?de(we):de(Je,-1)})}w(()=>{y(j,e(z).label),y(oe,e(z).delivery)}),N("click",he,()=>m(e(z))),d(Q,I)},Q=>{var z=Tp();d(Q,z)});var ne=i(T,2);{var fe=Q=>{Bo(Q,{get isNew(){return e(c)},get existingTargets(){return e(t)},isNested:!1,onSave:x,onCancel:_,get editingTarget(){return e(l)},set editingTarget(z){o(l,z,!0)}})};k(ne,Q=>{e(l)&&Q(fe)})}N("click",D,b),d(s,q),St()}Qt(["click"]);var Cp=p('
Runs through audio.cpp with optional Vulkan acceleration. Supports reference Voice Cloning and Ultimate Cloning (reference audio + transcript matching). Licensed under Apache 2.0.
Voice Design (prompt-based) isn't offered here: audio.cpp's current VoxCPM2 build doesn't
act on the prompt yet, an upstream limitation. Voice Cloning below works correctly.
When enabled, VoxCPM2 reads a companion .txt transcript file next to the .wav reference audio (e.g. voice_name.txt alongside voice_name.wav) for maximum phoneme alignment, nuanced breathing, and exact prosodic preservation.
VoxCPM2 model files are hosted on HuggingFace at huggingface.co/openbmb/VoxCPM2.
An optional token can avoid anonymous download rate limits — set it once in the General tab.
Loads the model at startup so the first reply doesn't pay the load cost.
`),Qp=p('⏳ Checking local model files...'),ef=p('⏳ Downloading Breeze-TTS-2 model weights from HuggingFace...'),tf=p('
'),af=p(`
Breeze-TTS-2 Voice
⚠️Non-Commercial License Warning
Breeze-TTS-2 model weights are released under the BreezeBlue Research and Non-Commercial License.
Commercial use requires a personal or commercial license directly from the creator (RESONIA, INC.).
Voice Design (prompt-based) isn't offered here: it doesn't reliably apply the described
@@ -67,19 +67,19 @@ You cannot assign the same Output Command multiple times to a single keybind.`);
there is no voice to choose. Needs espeak-ng installed for phonemization.
The model is deterministic for a fixed seed, so the same text always produces identical
audio. Change it to resample the prosody.
Higher values give more expressive but less predictable delivery. Default is 0.667.
Loads the ONNX graphs at launch so the first spoken response has no load delay.
Model directory (leave blank for default)
Point this at an existing copy of the model to skip downloading. Default: ~/.local/share/voxctrl/models/inflect-micro/
Model diagnostics
Reports the tensor names the downloaded export declares. Useful if synthesis fails with a
message about an input that could not be mapped.
`),hf=p('
',1),gf=p(`
The model stays in memory for the whole session — the fastest possible response, at
- the cost of holding its memory even while TTS sits unused.
`),mf=p('
Text to Speech
TTS Engine
Model Memory
Playback
Stop Key Bind
Press a key combo to immediately stop TTS playback — works even when this window is hidden.
');function bf(s,a){Tt(a,!0);let t=Ct(a,"cfg",15);function r(){Ot.set(t()),Ss.set(!0)}let l=S(null),c=S(0),u=S(!1),v=null,f=null,h=null,b=null,m=S(!1),_=S(null),x=0;function A(){o(u,!0),o(c,0),o(l,null),x=performance.now(),v&&clearInterval(v),v=setInterval(()=>{o(c,Math.round(performance.now()-x),!0),e(c)>1e4&&(clearInterval(v),o(u,!1),o(l,null))},10)}const q=["en-us-libritts-high","en-us-amy-low","en-us-kathleen-low","en-gb-southern_english_female-low","en-us-ryan-high","en-us-ryan-medium","en-us-ryan-low","en-us-lessac-medium","en-us-lessac-low","en-us-danny-low","en-gb-alan-low"];let T=S(yt({})),D=S(!1),se=S(!1),ne=S(!1),fe=S(null);async function Q(){o(D,!0);const Z={};for(const Le of q)try{Z[Le]=await E("check_voice_downloaded",{voiceName:Le,voiceDir:t().tts.voice_dir})}catch(je){console.error("Failed to check download status for voice "+Le,je),Z[Le]=!1}o(T,Z,!0),o(D,!1)}async function z(Z){if(!e(se)){o(se,!0);try{await E("download_voice",{voiceName:Z,voiceDir:t().tts.voice_dir}),e(T)[Z]=!0}catch(Le){alert(`Failed to download voice: ${Le}`)}finally{o(se,!1)}}}async function I(){const Z=t().tts.voice_dir;if(!Z){o(fe,null);return}const Le=await E("check_directory_exists",{path:Z});o(fe,Le?null:"This folder does not exist. Please create it first or leave blank for the default location.",!0),e(fe)||await Q()}function L(){r()}function ge(Z){Z.key==="Enter"&&Z.currentTarget.blur()}async function ee(){r()}async function j(){if(e(ne))return;try{await nl(t())}catch(Re){o(_,`Failed to save configuration: ${Re}`);return}if(e(m)){o(m,!1);try{await E("stop_tts")}catch(Re){console.error("Failed to stop TTS:",Re)}}o(ne,!0),o(_,null),A();let Z="TTS",Le=null;t().tts.engine==="piper"?(Z="Piper",Le=t().tts.voice):t().tts.engine==="pocket_tts"?(Z="Pocket-TTS",Le=t().tts.pocket_tts.voice):t().tts.engine==="breeze_tts_2"?(Z="Breeze-TTS-2",Le=null):t().tts.engine==="vox_cpm_2"?(Z="VoxCPM2",Le=null):t().tts.engine==="inflect_micro"?(Z="Inflect Micro",Le=null):t().tts.engine==="espeak"&&(Z="eSpeak-NG",Le=null);const je=`Hi this is ${Z} speaking from VoxCtrl`;try{await E("speak_text",{text:je,voice:Le})}catch(Re){o(_,`${Re}`),clearInterval(v),o(u,!1),o(ne,!1)}}let V=S(!1);function oe(){if(!t().tts.enabled)return"Enable text-to-speech above first.";if(e(V))return"Switching engine...";if(e(m))return null;if(e(ne))return"Already speaking.";if(t().tts.engine==="inflect_micro"){if(!e(Fe))return"This build was compiled without the `inflect-micro` feature, so this engine cannot synthesize. Rebuild with: npm run tauri dev -- --features inflect-micro";if(e(re))return"Checking local model files...";if(e(we))return"Downloading the model...";if(!e(he))return"Download the model first."}if(t().tts.engine==="breeze_tts_2"){if(e(Ye))return"Checking local model files...";if(e(Ze))return"Downloading the model...";if(!e(Ie))return"Download the model first."}if(t().tts.engine==="vox_cpm_2"){if(e(C))return"Checking local model files...";if(e(ke))return"Downloading the model...";if(!e(M))return"Download the model first."}return null}function R(){return!t().tts.enabled||e(V)?!0:e(m)?!1:e(ne)?!0:t().tts.engine==="piper"?e(D)||e(se)||!e(T)[t().tts.voice]:t().tts.engine==="pocket_tts"?e(ze)||e($e)||!e(pe):t().tts.engine==="breeze_tts_2"?e(Ye)||e(Ze)||!e(Ie):t().tts.engine==="vox_cpm_2"?e(C)||e(ke)||!e(M):t().tts.engine==="inflect_micro"?e(re)||e(we)||!e(he)||!e(Fe):!1}let B=S(yt([])),be=S(null);function Pe(){return t().tts.engine==="vox_cpm_2"?t().tts.vox_cpm_2.voice_dir||"":t().tts.engine==="breeze_tts_2"?t().tts.breeze_tts_2.voice_dir||"":t().tts.pocket_tts.voice_dir||""}function ue(){if(!e(B)||e(B).length===0)return;const Z=e(B)[0].id;let Le=!1;(!t().tts.vox_cpm_2.cloned_voice||!e(B).some(je=>je.id===t().tts.vox_cpm_2.cloned_voice))&&(t(t().tts.vox_cpm_2.cloned_voice=Z,!0),Le=!0),(!t().tts.breeze_tts_2.cloned_voice||!e(B).some(je=>je.id===t().tts.breeze_tts_2.cloned_voice))&&(t(t().tts.breeze_tts_2.cloned_voice=Z,!0),Le=!0),(!t().tts.pocket_tts.voice||!e(B).some(je=>je.id===t().tts.pocket_tts.voice))&&(t(t().tts.pocket_tts.voice=Z,!0),Le=!0),Le&&r()}pa(()=>{ue(),t().tts.vox_cpm_2.voice_mode!=="clone"&&(t(t().tts.vox_cpm_2.voice_mode="clone",!0),r()),t().tts.breeze_tts_2.voice_mode!=="clone"&&(t(t().tts.breeze_tts_2.voice_mode="clone",!0),r())});async function K(){try{o(B,await E("list_pocket_tts_voices",{voiceDir:Pe()}),!0),ue()}catch(Z){console.error("list_pocket_tts_voices:",Z)}}async function J(Z){const Le=typeof Z=="string"?Z:Pe();if(!Le){o(be,null),await K();return}const je=await E("check_directory_exists",{path:Le});o(be,je?null:"This folder does not exist. Please create it first or leave blank for the default location.",!0),e(be)||await K()}function Se(){r()}function De(Z){Z.key==="Enter"&&Z.currentTarget.blur()}let le=ce(()=>q.map(Z=>({value:Z,label:`${Z}${e(T)[Z]?" ✔":""}`}))),W=ce(()=>e(B).map(Z=>({value:Z.id,label:Z.label})));const ae=[{value:"always_loaded",label:"Always loaded (fastest response)"},{value:"on_demand",label:"Load when needed, unload when idle (saves memory)"}];let O=ce(()=>{var Z;return Math.round(((Z=t().tts.idle_unload_secs)!=null?Z:900)/60)});function X(){t().tts.memory_mode==="on_demand"&&!t().tts.idle_unload_secs&&t(t().tts.idle_unload_secs=900,!0),r()}function ve(Z){const Le=Number(Z.currentTarget.value),je=Math.min(480,Math.max(1,Math.round(Le)||15));t(t().tts.idle_unload_secs=je*60,!0),r()}const Ae=[{value:"vox_cpm_2",label:"VoxCPM2 (neural, voice cloning & design)"},{value:"breeze_tts_2",label:"Breeze-TTS-2 (neural, voice design)"},{value:"pocket_tts",label:"Pocket-TTS (neural, voice cloning)"},{value:"piper",label:"Piper (neural, high quality)"},{value:"inflect_micro",label:"Inflect Micro (neural, 38 MB)"},{value:"espeak",label:"eSpeak-NG (lightweight)"}];let Fe=S(!0),he=S(!1),re=S(!1),we=S(!1),Je=S(null),de=S(!1),$=S(null);async function U(){try{o(Fe,await E("inflect_micro_available"),!0)}catch(Z){console.error("inflect_micro_available:",Z),o(Fe,!1)}}async function te(){o(re,!0);try{o(he,await E("check_inflect_micro_downloaded",{modelDir:t().tts.inflect_micro.model_dir}),!0)}catch(Z){console.error("check_inflect_micro_downloaded:",Z),o(he,!1)}finally{o(re,!1)}}async function Y(){if(!e(we)){o(we,!0),o($,null);try{await E("download_inflect_micro",{modelDir:t().tts.inflect_micro.model_dir}),o(he,!0)}catch(Z){o($,`${Z}`)}finally{o(we,!1)}}}async function _e(){if(!e(de)){o(de,!0),o(Je,null);try{const Z=await E("inflect_micro_inspect",{modelDir:t().tts.inflect_micro.model_dir});o(Je,JSON.stringify(Z,null,2),!0)}catch(Z){o(Je,`${Z}`)}finally{o(de,!1)}}}function me(){r()}let pe=S(!1),ze=S(!1),$e=S(!1);async function st(){o(ze,!0);try{o(pe,await E("check_pocket_tts_ready",{voice:t().tts.pocket_tts.voice,voiceDir:t().tts.pocket_tts.voice_dir}),!0)}catch(Z){console.error("check_pocket_tts_ready:",Z),o(pe,!1)}finally{o(ze,!1)}}async function it(){if(!e($e)){o($e,!0);try{await E("download_pocket_tts",{voice:t().tts.pocket_tts.voice,voiceDir:t().tts.pocket_tts.voice_dir,hfToken:t().tts.hf_token}),o(pe,!0)}catch(Z){alert(`Failed to download Pocket-TTS assets: ${Z}`)}finally{o($e,!1)}}}function H(){r(),o(pe,!1),st()}let M=S(!1),C=S(!1),ke=S(!1);async function Ke(){o(C,!0);try{o(M,await E("check_vox_cpm_2_ready",{modelDir:t().tts.vox_cpm_2.model_dir}),!0)}catch(Z){console.error("check_vox_cpm_2_ready:",Z),o(M,!1)}finally{o(C,!1)}}async function ye(){if(!e(ke)){o(ke,!0);try{const Z=t().tts.hf_token;await E("download_vox_cpm_2",{modelDir:t().tts.vox_cpm_2.model_dir,hfToken:Z}),o(M,!0)}catch(Z){alert(`Failed to download VoxCPM2 assets: ${Z}`)}finally{o(ke,!1)}}}let Ie=S(!1),Ye=S(!1),Ze=S(!1);async function Ve(){o(Ye,!0);try{o(Ie,await E("check_breeze_tts_2_ready",{modelDir:t().tts.breeze_tts_2.model_dir}),!0)}catch(Z){console.error("check_breeze_tts_2_ready:",Z),o(Ie,!1)}finally{o(Ye,!1)}}async function at(){if(!e(Ze)){o(Ze,!0);try{const Z=t().tts.hf_token;await E("download_breeze_tts_2",{modelDir:t().tts.breeze_tts_2.model_dir,hfToken:Z}),o(Ie,!0)}catch(Z){alert(`Failed to download Breeze-TTS-2 assets: ${Z}`)}finally{o(Ze,!1)}}}let et=S(null);const rt=ce(()=>!!e(et));async function Ee(){r(),o(V,!0);try{t().tts.engine==="vox_cpm_2"?(t(t().tts.vox_cpm_2.voice_mode="clone",!0),o(M,!1),await Ke(),await K()):t().tts.engine==="breeze_tts_2"?(t(t().tts.breeze_tts_2.voice_mode="clone",!0),o(Ie,!1),await Ve(),await K()):t().tts.engine==="pocket_tts"?(o(pe,!1),await K(),await st()):t().tts.engine==="inflect_micro"?(o(he,!1),await U(),await te()):t().tts.engine==="piper"&&(t().tts.voice_dir?await I():await Q())}finally{setTimeout(()=>{o(V,!1)},400)}}qt(async()=>{E("hf_token_env").then(Z=>o(et,Z&&Z.trim()?Z.trim():null,!0)).catch(()=>o(et,null)),t().tts.voice_dir?I():Q(),K(),t().tts.engine==="vox_cpm_2"&&Ke(),t().tts.engine==="breeze_tts_2"&&Ve(),t().tts.engine==="pocket_tts"&&st(),t().tts.engine==="inflect_micro"&&(await U(),te()),f=await ha("tts-playback-start",()=>{e(u)&&(clearInterval(v),o(l,e(c),!0),o(u,!1)),o(ne,!1),o(m,!0)}),h=await ha("tts-playback-end",()=>{o(m,!1),e(ne)&&(clearInterval(v),o(u,!1),o(ne,!1))}),b=await ha("tts-error",Z=>{o(_,Z.payload,!0),clearInterval(v),o(u,!1),o(l,null),o(ne,!1),o(m,!1)})}),ar(()=>{v&&clearInterval(v),f&&f(),h&&h(),b&&b()});var Ge=mf(),ct=i(n(Ge),2),vt=i(n(ct),2),nt=i(n(vt),2),wt=i(vt,2),dt=i(n(wt),2);sa(dt,{get options(){return Ae},onchange:Ee,get value(){return t().tts.engine},set value(Z){t(t().tts.engine=Z,!0)}});var Et=i(wt,2);{var Kt=Z=>{var Le=Rp(),je=ht(Le),Re=i(n(je),2);N("change",Re,r),Xt(Re,()=>t().tts.gpu,Qe=>t(t().tts.gpu=Qe,!0)),d(Z,Le)},ia=Z=>{var Le=Np(),je=ht(Le),Re=i(n(je),2);N("change",Re,r),Xt(Re,()=>t().tts.pocket_tts.gpu,Qe=>t(t().tts.pocket_tts.gpu=Qe,!0)),d(Z,Le)},ra=Z=>{var Le=Vp(),je=ht(Le),Re=i(n(je),2);N("change",Re,r),Xt(Re,()=>t().tts.breeze_tts_2.gpu,Qe=>t(t().tts.breeze_tts_2.gpu=Qe,!0)),d(Z,Le)},bt=Z=>{var Le=Fp(),je=ht(Le),Re=i(n(je),2);N("change",Re,r),Xt(Re,()=>t().tts.vox_cpm_2.gpu,Qe=>t(t().tts.vox_cpm_2.gpu=Qe,!0)),d(Z,Le)};k(Et,Z=>{t().tts.engine==="piper"?Z(Kt):t().tts.engine==="pocket_tts"?Z(ia,1):t().tts.engine==="breeze_tts_2"?Z(ra,2):t().tts.engine==="vox_cpm_2"&&Z(bt,3)})}var ea=i(Et,2),Lt=n(ea),Ht=n(Lt),ta=i(Lt,2),Oe=i(ea,2),qe=n(Oe),G=n(qe),g=i(qe,2);{var P=Z=>{var Le=Bp(),je=i(n(Le),2);let Re;var Qe=n(je);w(()=>{Re=Te(je,1,"run-speed-value svelte-1q9seip",null,Re,{counting:e(u)}),y(Qe,e(u)?`${e(c)} ms`:`${e(l)} ms`)}),d(Z,Le)};k(g,Z=>{(e(u)||e(l)!==null)&&Z(P)})}var Me=i(Oe,2);{var Ue=Z=>{var Le=qp(),je=n(Le);w(()=>{var Re;return y(je,`❌ ${(Re=e(_))!=null?Re:""}`)}),d(Z,Le)};k(Me,Z=>{e(_)&&Z(Ue)})}var ie=i(Me,2);{var xe=Z=>{var Le=jp(),je=n(Le);w(Re=>y(je,`Test TTS unavailable: ${Re!=null?Re:""}`),[()=>oe()]),d(Z,Le)},Ce=ce(()=>!e(_)&&R()&&oe());k(ie,Z=>{e(Ce)&&Z(xe)})}var He=i(ct,2);{var Xe=Z=>{var Le=$p(),je=i(n(Le),2),Re=i(n(je),2);sa(Re,{get options(){return e(le)},onchange:ee,get value(){return t().tts.voice},set value(Ut){t(t().tts.voice=Ut,!0)}});var Qe=i(je,2),Jt=n(Qe);{var Gt=Ut=>{var Mt=Up();d(Ut,Mt)},ka=Ut=>{var Mt=Kp(),kt=n(Mt);w(()=>{var aa;return y(kt,`⏳ Downloading ${(aa=t().tts.voice)!=null?aa:""} (model + config)...`)}),d(Ut,Mt)},xa=Ut=>{var Mt=Hp(),kt=n(Mt),aa=n(kt),Da=i(kt,2),Ua=n(Da);w(()=>{Te(kt,1,Ia(e(T)[t().tts.voice]?"status-downloaded":"status-missing"),"svelte-1q9seip"),y(aa,e(T)[t().tts.voice]?"✔ Voice downloaded and ready":"❌ Voice files missing"),Da.disabled=e(T)[t().tts.voice]||e(se),y(Ua,e(T)[t().tts.voice]?"Downloaded":"📥 Download")}),N("click",Da,()=>z(t().tts.voice)),d(Ut,Mt)};k(Jt,Ut=>{e(D)?Ut(Gt):e(se)?Ut(ka,1):Ut(xa,-1)})}var Ta=i(Qe,2),la=i(n(Ta),2);let _a;var Pa=i(la,2);{var Ca=Ut=>{var Mt=Wp(),kt=n(Mt);w(()=>y(kt,e(fe))),d(Ut,Mt)};k(Pa,Ut=>{e(fe)&&Ut(Ca)})}w(()=>_a=Te(la,1,"svelte-1q9seip",null,_a,{"field-input-error":!!e(fe)})),N("change",la,L),xs("blur",la,I),N("keydown",la,ge),We(la,()=>t().tts.voice_dir,Ut=>t(t().tts.voice_dir=Ut,!0)),d(Z,Le)};k(He,Z=>{t().tts.engine==="piper"&&Z(Xe)})}var Dt=i(He,2);{var zt=Z=>{var Le=Zp(),je=i(n(Le),6),Re=i(n(je),2);sa(Re,{get options(){return e(W)},defaultToFirst:!0,onchange:r,get value(){return t().tts.vox_cpm_2.cloned_voice},set value(Rt){t(t().tts.vox_cpm_2.cloned_voice=Rt,!0)}});var Qe=i(je,2),Jt=i(n(Qe),2),Gt=i(Qe,4),ka=i(n(Gt),2),xa=i(Gt,4),Ta=n(xa);{var la=Rt=>{var Ja=Gp();d(Rt,Ja)},_a=Rt=>{var Ja=Yp();d(Rt,Ja)},Pa=Rt=>{var Ja=Jp(),Bn=n(Ja),rr=n(Bn),Nt=i(Bn,2),za=n(Nt);w(()=>{Te(Bn,1,Ia(e(M)?"status-downloaded":"status-missing"),"svelte-1q9seip"),y(rr,e(M)?"✔ Model weights downloaded and ready":"❌ Model files missing"),Nt.disabled=e(M)||e(ke),y(za,e(M)?"Downloaded":"📥 Download")}),N("click",Nt,ye),d(Rt,Ja)};k(Ta,Rt=>{e(C)?Rt(la):e(ke)?Rt(_a,1):Rt(Pa,-1)})}var Ca=i(xa,2),Ut=i(n(Ca),5);{var Mt=Rt=>{var Ja=Xp();d(Rt,Ja)};k(Ut,Rt=>{e(rt)&&Rt(Mt)})}var kt=i(Ca,2),aa=i(n(kt),2),Da=i(kt,4),Ua=i(n(Da),2);N("change",Jt,()=>{r(),J(t().tts.vox_cpm_2.voice_dir)}),We(Jt,()=>t().tts.vox_cpm_2.voice_dir,Rt=>t(t().tts.vox_cpm_2.voice_dir=Rt,!0)),N("change",ka,r),Xt(ka,()=>t().tts.vox_cpm_2.ultimate_cloning,Rt=>t(t().tts.vox_cpm_2.ultimate_cloning=Rt,!0)),N("change",aa,r),We(aa,()=>t().tts.vox_cpm_2.model_dir,Rt=>t(t().tts.vox_cpm_2.model_dir=Rt,!0)),N("change",Ua,r),Xt(Ua,()=>t().tts.vox_cpm_2.prewarm,Rt=>t(t().tts.vox_cpm_2.prewarm=Rt,!0)),d(Z,Le)};k(Dt,Z=>{t().tts.engine==="vox_cpm_2"&&Z(zt)})}var Ft=i(Dt,2);{var Wt=Z=>{var Le=af(),je=i(n(Le),6),Re=i(n(je),2);sa(Re,{get options(){return e(W)},defaultToFirst:!0,onchange:r,get value(){return t().tts.breeze_tts_2.cloned_voice},set value(Mt){t(t().tts.breeze_tts_2.cloned_voice=Mt,!0)}});var Qe=i(je,2),Jt=i(n(Qe),2),Gt=i(Qe,6),ka=n(Gt);{var xa=Mt=>{var kt=Qp();d(Mt,kt)},Ta=Mt=>{var kt=ef();d(Mt,kt)},la=Mt=>{var kt=tf(),aa=n(kt),Da=n(aa),Ua=i(aa,2),Rt=n(Ua);w(()=>{Te(aa,1,Ia(e(Ie)?"status-downloaded":"status-missing"),"svelte-1q9seip"),y(Da,e(Ie)?"✔ Model weights downloaded and ready":"❌ Model files missing"),Ua.disabled=e(Ie)||e(Ze),y(Rt,e(Ie)?"Downloaded":"📥 Download")}),N("click",Ua,at),d(Mt,kt)};k(ka,Mt=>{e(Ye)?Mt(xa):e(Ze)?Mt(Ta,1):Mt(la,-1)})}var _a=i(Gt,4),Pa=i(n(_a),2),Ca=i(_a,4),Ut=i(n(Ca),2);N("change",Jt,()=>{r(),J(t().tts.breeze_tts_2.voice_dir)}),We(Jt,()=>t().tts.breeze_tts_2.voice_dir,Mt=>t(t().tts.breeze_tts_2.voice_dir=Mt,!0)),N("change",Pa,r),We(Pa,()=>t().tts.breeze_tts_2.model_dir,Mt=>t(t().tts.breeze_tts_2.model_dir=Mt,!0)),N("change",Ut,r),Xt(Ut,()=>t().tts.breeze_tts_2.prewarm,Mt=>t(t().tts.breeze_tts_2.prewarm=Mt,!0)),d(Z,Le)};k(Ft,Z=>{t().tts.engine==="breeze_tts_2"&&Z(Wt)})}var $t=i(Ft,2);{var fa=Z=>{var Le=of(),je=i(n(Le),2),Re=i(n(je),2);sa(Re,{get options(){return e(W)},defaultToFirst:!0,onchange:H,get value(){return t().tts.pocket_tts.voice},set value(kt){t(t().tts.pocket_tts.voice=kt,!0)}});var Qe=i(je,2),Jt=n(Qe);{var Gt=kt=>{var aa=sf();d(kt,aa)},ka=kt=>{var aa=nf();d(kt,aa)},xa=kt=>{var aa=rf(),Da=n(aa),Ua=n(Da),Rt=i(Da,2),Ja=n(Rt);w(()=>{Te(Da,1,Ia(e(pe)?"status-downloaded":"status-missing"),"svelte-1q9seip"),y(Ua,e(pe)?"✔ Model and voice clip downloaded and ready":"❌ Model files missing"),Rt.disabled=e(pe)||e($e),y(Ja,e(pe)?"Downloaded":"📥 Download")}),N("click",Rt,it),d(kt,aa)};k(Jt,kt=>{e(ze)?kt(Gt):e($e)?kt(ka,1):kt(xa,-1)})}var Ta=i(Qe,4),la=i(n(Ta),2);let _a;var Pa=i(la,2);{var Ca=kt=>{var aa=lf(),Da=n(aa);w(()=>y(Da,e(be))),d(kt,aa)};k(Pa,kt=>{e(be)&&kt(Ca)})}var Ut=i(Ta,4),Mt=i(n(Ut),2);w(()=>_a=Te(la,1,"svelte-1q9seip",null,_a,{"field-input-error":!!e(be)})),N("change",la,Se),xs("blur",la,J),N("keydown",la,De),We(la,()=>t().tts.pocket_tts.voice_dir,kt=>t(t().tts.pocket_tts.voice_dir=kt,!0)),N("change",Mt,r),Xt(Mt,()=>t().tts.pocket_tts.prewarm,kt=>t(t().tts.pocket_tts.prewarm=kt,!0)),d(Z,Le)};k($t,Z=>{t().tts.engine==="pocket_tts"&&Z(fa)})}var Yt=i($t,2);{var ma=Z=>{var Le=_f(),je=i(n(Le),4);{var Re=Nt=>{var za=cf();d(Nt,za)};k(je,Nt=>{e(Fe)||Nt(Re)})}var Qe=i(je,2),Jt=n(Qe);{var Gt=Nt=>{var za=df();d(Nt,za)},ka=Nt=>{var za=vf();d(Nt,za)},xa=Nt=>{var za=uf(),Hs=n(za),Ti=n(Hs),lr=i(Hs,2),Wo=n(lr);w(()=>{Te(Hs,1,Ia(e(he)?"status-downloaded":"status-missing"),"svelte-1q9seip"),y(Ti,e(he)?"✔ Model downloaded and ready":"❌ Model files missing"),lr.disabled=e(he)||e(we),y(Wo,e(he)?"Downloaded":"📥 Download")}),N("click",lr,Y),d(Nt,za)};k(Jt,Nt=>{e(re)?Nt(Gt):e(we)?Nt(ka,1):Nt(xa,-1)})}var Ta=i(Qe,2);{var la=Nt=>{var za=pf(),Hs=n(za);w(()=>{var Ti;return y(Hs,`❌ ${(Ti=e($))!=null?Ti:""}`)}),d(Nt,za)};k(Ta,Nt=>{e($)&&Nt(la)})}var _a=i(Ta,2),Pa=i(n(_a),2),Ca=i(_a,4),Ut=i(n(Ca),2),Mt=i(Ca,4),kt=i(n(Mt),2),aa=i(Mt,4),Da=i(n(aa),2),Ua=i(aa,4),Rt=i(n(Ua),2),Ja=n(Rt),Bn=i(Ua,4);{var rr=Nt=>{var za=ff(),Hs=n(za);w(()=>y(Hs,e(Je))),d(Nt,za)};k(Bn,Nt=>{e(Je)&&Nt(rr)})}w(()=>{Rt.disabled=!e(he)||e(de),y(Ja,e(de)?"Inspecting...":"🔍 Inspect graphs")}),N("change",Pa,me),We(Pa,()=>t().tts.inflect_micro.seed,Nt=>t(t().tts.inflect_micro.seed=Nt,!0)),N("change",Ut,me),We(Ut,()=>t().tts.inflect_micro.noise_scale,Nt=>t(t().tts.inflect_micro.noise_scale=Nt,!0)),N("change",kt,me),Xt(kt,()=>t().tts.inflect_micro.prewarm,Nt=>t(t().tts.inflect_micro.prewarm=Nt,!0)),N("change",Da,me),We(Da,()=>t().tts.inflect_micro.model_dir,Nt=>t(t().tts.inflect_micro.model_dir=Nt,!0)),N("click",Rt,_e),d(Z,Le)};k(Yt,Z=>{t().tts.engine==="inflect_micro"&&Z(ma)})}var Oa=i(Yt,2),Ya=i(n(Oa),2),tt=i(n(Ya),2);sa(tt,{get options(){return ae},onchange:X,get value(){return t().tts.memory_mode},set value(Z){t(t().tts.memory_mode=Z,!0)}});var gt=i(Ya,2);{var It=Z=>{var Le=hf(),je=ht(Le),Re=i(n(je),2),Qe=i(je,2),Jt=n(Qe);w(()=>{var Gt;sr(Re,e(O)),y(Jt,`The model is loaded the moment VoxCtrl knows it will be needed — as soon as you start
+ the cost of holding its memory even while TTS sits unused.`),mf=p('
Text to Speech
TTS Engine
Model Memory
Playback
Stop Key Bind
Press a key combo to immediately stop TTS playback — works even when this window is hidden.
');function bf(s,a){Tt(a,!0);let t=Ct(a,"cfg",15);function r(){Ot.set(t()),Ss.set(!0)}let l=S(null),c=S(0),u=S(!1),v=null,f=null,h=null,b=null,m=S(!1),_=S(null),x=0;function M(){o(u,!0),o(c,0),o(l,null),x=performance.now(),v&&clearInterval(v),v=setInterval(()=>{o(c,Math.round(performance.now()-x),!0),e(c)>1e4&&(clearInterval(v),o(u,!1),o(l,null))},10)}const q=["en-us-libritts-high","en-us-amy-low","en-us-kathleen-low","en-gb-southern_english_female-low","en-us-ryan-high","en-us-ryan-medium","en-us-ryan-low","en-us-lessac-medium","en-us-lessac-low","en-us-danny-low","en-gb-alan-low"];let T=S(yt({})),D=S(!1),se=S(!1),ne=S(!1),fe=S(null);async function Q(){o(D,!0);const Z={};for(const Le of q)try{Z[Le]=await E("check_voice_downloaded",{voiceName:Le,voiceDir:t().tts.voice_dir})}catch(Ke){console.error("Failed to check download status for voice "+Le,Ke),Z[Le]=!1}o(T,Z,!0),o(D,!1)}async function z(Z){if(!e(se)){o(se,!0);try{await E("download_voice",{voiceName:Z,voiceDir:t().tts.voice_dir}),e(T)[Z]=!0}catch(Le){alert(`Failed to download voice: ${Le}`)}finally{o(se,!1)}}}async function I(){const Z=t().tts.voice_dir;if(!Z){o(fe,null);return}const Le=await E("check_directory_exists",{path:Z});o(fe,Le?null:"This folder does not exist. Please create it first or leave blank for the default location.",!0),e(fe)||await Q()}function L(){r()}function ge(Z){Z.key==="Enter"&&Z.currentTarget.blur()}async function ee(){r()}async function K(){if(e(ne))return;try{await nl(t())}catch(Re){o(_,`Failed to save configuration: ${Re}`);return}if(e(m)){o(m,!1);try{await E("stop_tts")}catch(Re){console.error("Failed to stop TTS:",Re)}}o(ne,!0),o(_,null),M();let Z="TTS",Le=null;t().tts.engine==="piper"?(Z="Piper",Le=t().tts.voice):t().tts.engine==="pocket_tts"?(Z="Pocket-TTS",Le=t().tts.pocket_tts.voice):t().tts.engine==="breeze_tts_2"?(Z="Breeze-TTS-2",Le=null):t().tts.engine==="vox_cpm_2"?(Z="VoxCPM2",Le=null):t().tts.engine==="inflect_micro"?(Z="Inflect Micro",Le=null):t().tts.engine==="espeak"&&(Z="eSpeak-NG",Le=null);const Ke=`Hi this is ${Z} speaking from VoxCtrl`;try{await E("speak_text",{text:Ke,voice:Le})}catch(Re){o(_,`${Re}`),clearInterval(v),o(u,!1),o(ne,!1)}}let V=S(!1);function oe(){if(!t().tts.enabled)return"Enable text-to-speech above first.";if(e(V))return"Switching engine...";if(e(m))return null;if(e(ne))return"Already speaking.";if(t().tts.engine==="inflect_micro"){if(!e(Fe))return"This build was compiled without the `inflect-micro` feature, so this engine cannot synthesize. Rebuild with: npm run tauri dev -- --features inflect-micro";if(e(re))return"Checking local model files...";if(e(we))return"Downloading the model...";if(!e(he))return"Download the model first."}if(t().tts.engine==="breeze_tts_2"){if(e(Ge))return"Checking local model files...";if(e(Ze))return"Downloading the model...";if(!e(Ie))return"Download the model first."}if(t().tts.engine==="vox_cpm_2"){if(e(C))return"Checking local model files...";if(e(ke))return"Downloading the model...";if(!e(P))return"Download the model first."}return null}function R(){return!t().tts.enabled||e(V)?!0:e(m)?!1:e(ne)?!0:t().tts.engine==="piper"?e(D)||e(se)||!e(T)[t().tts.voice]:t().tts.engine==="pocket_tts"?e(ze)||e(Ye)||!e(pe):t().tts.engine==="breeze_tts_2"?e(Ge)||e(Ze)||!e(Ie):t().tts.engine==="vox_cpm_2"?e(C)||e(ke)||!e(P):t().tts.engine==="inflect_micro"?e(re)||e(we)||!e(he)||!e(Fe):!1}let B=S(yt([])),be=S(null);function Ae(){return t().tts.engine==="vox_cpm_2"?t().tts.vox_cpm_2.voice_dir||"":t().tts.engine==="breeze_tts_2"?t().tts.breeze_tts_2.voice_dir||"":t().tts.pocket_tts.voice_dir||""}function ue(){if(!e(B)||e(B).length===0)return;const Z=e(B)[0].id;let Le=!1;(!t().tts.vox_cpm_2.cloned_voice||!e(B).some(Ke=>Ke.id===t().tts.vox_cpm_2.cloned_voice))&&(t(t().tts.vox_cpm_2.cloned_voice=Z,!0),Le=!0),(!t().tts.breeze_tts_2.cloned_voice||!e(B).some(Ke=>Ke.id===t().tts.breeze_tts_2.cloned_voice))&&(t(t().tts.breeze_tts_2.cloned_voice=Z,!0),Le=!0),(!t().tts.pocket_tts.voice||!e(B).some(Ke=>Ke.id===t().tts.pocket_tts.voice))&&(t(t().tts.pocket_tts.voice=Z,!0),Le=!0),Le&&r()}pa(()=>{ue(),t().tts.vox_cpm_2.voice_mode!=="clone"&&(t(t().tts.vox_cpm_2.voice_mode="clone",!0),r()),t().tts.breeze_tts_2.voice_mode!=="clone"&&(t(t().tts.breeze_tts_2.voice_mode="clone",!0),r())});async function j(){try{o(B,await E("list_pocket_tts_voices",{voiceDir:Ae()}),!0),ue()}catch(Z){console.error("list_pocket_tts_voices:",Z)}}async function J(Z){const Le=typeof Z=="string"?Z:Ae();if(!Le){o(be,null),await j();return}const Ke=await E("check_directory_exists",{path:Le});o(be,Ke?null:"This folder does not exist. Please create it first or leave blank for the default location.",!0),e(be)||await j()}function Se(){r()}function De(Z){Z.key==="Enter"&&Z.currentTarget.blur()}let le=ce(()=>q.map(Z=>({value:Z,label:`${Z}${e(T)[Z]?" ✔":""}`}))),W=ce(()=>e(B).map(Z=>({value:Z.id,label:Z.label})));const ae=[{value:"always_loaded",label:"Always loaded (fastest response)"},{value:"on_demand",label:"Load when needed, unload when idle (saves memory)"}];let O=ce(()=>{var Z;return Math.round(((Z=t().tts.idle_unload_secs)!=null?Z:900)/60)});function X(){t().tts.memory_mode==="on_demand"&&!t().tts.idle_unload_secs&&t(t().tts.idle_unload_secs=900,!0),r()}function ve(Z){const Le=Number(Z.currentTarget.value),Ke=Math.min(480,Math.max(1,Math.round(Le)||15));t(t().tts.idle_unload_secs=Ke*60,!0),r()}const Me=[{value:"vox_cpm_2",label:"VoxCPM2 (neural, voice cloning & design)"},{value:"breeze_tts_2",label:"Breeze-TTS-2 (neural, voice design)"},{value:"pocket_tts",label:"Pocket-TTS (neural, voice cloning)"},{value:"piper",label:"Piper (neural, high quality)"},{value:"inflect_micro",label:"Inflect Micro (neural, 38 MB)"},{value:"espeak",label:"eSpeak-NG (lightweight)"}];let Fe=S(!0),he=S(!1),re=S(!1),we=S(!1),Je=S(null),de=S(!1),Y=S(null);async function U(){try{o(Fe,await E("inflect_micro_available"),!0)}catch(Z){console.error("inflect_micro_available:",Z),o(Fe,!1)}}async function te(){o(re,!0);try{o(he,await E("check_inflect_micro_downloaded",{modelDir:t().tts.inflect_micro.model_dir}),!0)}catch(Z){console.error("check_inflect_micro_downloaded:",Z),o(he,!1)}finally{o(re,!1)}}async function G(){if(!e(we)){o(we,!0),o(Y,null);try{await E("download_inflect_micro",{modelDir:t().tts.inflect_micro.model_dir}),o(he,!0)}catch(Z){o(Y,`${Z}`)}finally{o(we,!1)}}}async function _e(){if(!e(de)){o(de,!0),o(Je,null);try{const Z=await E("inflect_micro_inspect",{modelDir:t().tts.inflect_micro.model_dir});o(Je,JSON.stringify(Z,null,2),!0)}catch(Z){o(Je,`${Z}`)}finally{o(de,!1)}}}function me(){r()}let pe=S(!1),ze=S(!1),Ye=S(!1);async function st(){o(ze,!0);try{o(pe,await E("check_pocket_tts_ready",{voice:t().tts.pocket_tts.voice,voiceDir:t().tts.pocket_tts.voice_dir}),!0)}catch(Z){console.error("check_pocket_tts_ready:",Z),o(pe,!1)}finally{o(ze,!1)}}async function it(){if(!e(Ye)){o(Ye,!0);try{await E("download_pocket_tts",{voice:t().tts.pocket_tts.voice,voiceDir:t().tts.pocket_tts.voice_dir,hfToken:t().tts.hf_token}),o(pe,!0)}catch(Z){alert(`Failed to download Pocket-TTS assets: ${Z}`)}finally{o(Ye,!1)}}}function H(){r(),o(pe,!1),st()}let P=S(!1),C=S(!1),ke=S(!1);async function je(){o(C,!0);try{o(P,await E("check_vox_cpm_2_ready",{modelDir:t().tts.vox_cpm_2.model_dir}),!0)}catch(Z){console.error("check_vox_cpm_2_ready:",Z),o(P,!1)}finally{o(C,!1)}}async function ye(){if(!e(ke)){o(ke,!0);try{const Z=t().tts.hf_token;await E("download_vox_cpm_2",{modelDir:t().tts.vox_cpm_2.model_dir,hfToken:Z}),o(P,!0)}catch(Z){alert(`Failed to download VoxCPM2 assets: ${Z}`)}finally{o(ke,!1)}}}let Ie=S(!1),Ge=S(!1),Ze=S(!1);async function Ve(){o(Ge,!0);try{o(Ie,await E("check_breeze_tts_2_ready",{modelDir:t().tts.breeze_tts_2.model_dir}),!0)}catch(Z){console.error("check_breeze_tts_2_ready:",Z),o(Ie,!1)}finally{o(Ge,!1)}}async function at(){if(!e(Ze)){o(Ze,!0);try{const Z=t().tts.hf_token;await E("download_breeze_tts_2",{modelDir:t().tts.breeze_tts_2.model_dir,hfToken:Z}),o(Ie,!0)}catch(Z){alert(`Failed to download Breeze-TTS-2 assets: ${Z}`)}finally{o(Ze,!1)}}}let et=S(null);const rt=ce(()=>!!e(et));async function Ee(){r(),o(V,!0);try{t().tts.engine==="vox_cpm_2"?(t(t().tts.vox_cpm_2.voice_mode="clone",!0),o(P,!1),await je(),await j()):t().tts.engine==="breeze_tts_2"?(t(t().tts.breeze_tts_2.voice_mode="clone",!0),o(Ie,!1),await Ve(),await j()):t().tts.engine==="pocket_tts"?(o(pe,!1),await j(),await st()):t().tts.engine==="inflect_micro"?(o(he,!1),await U(),await te()):t().tts.engine==="piper"&&(t().tts.voice_dir?await I():await Q())}finally{setTimeout(()=>{o(V,!1)},400)}}qt(async()=>{E("hf_token_env").then(Z=>o(et,Z&&Z.trim()?Z.trim():null,!0)).catch(()=>o(et,null)),t().tts.voice_dir?I():Q(),j(),t().tts.engine==="vox_cpm_2"&&je(),t().tts.engine==="breeze_tts_2"&&Ve(),t().tts.engine==="pocket_tts"&&st(),t().tts.engine==="inflect_micro"&&(await U(),te()),f=await ha("tts-playback-start",()=>{e(u)&&(clearInterval(v),o(l,e(c),!0),o(u,!1)),o(ne,!1),o(m,!0)}),h=await ha("tts-playback-end",()=>{o(m,!1),e(ne)&&(clearInterval(v),o(u,!1),o(ne,!1))}),b=await ha("tts-error",Z=>{o(_,Z.payload,!0),clearInterval(v),o(u,!1),o(l,null),o(ne,!1),o(m,!1)})}),ar(()=>{v&&clearInterval(v),f&&f(),h&&h(),b&&b()});var $e=mf(),ct=i(n($e),2),vt=i(n(ct),2),nt=i(n(vt),2),wt=i(vt,2),dt=i(n(wt),2);sa(dt,{get options(){return Me},onchange:Ee,get value(){return t().tts.engine},set value(Z){t(t().tts.engine=Z,!0)}});var Et=i(wt,2);{var jt=Z=>{var Le=Rp(),Ke=ht(Le),Re=i(n(Ke),2);N("change",Re,r),Xt(Re,()=>t().tts.gpu,Qe=>t(t().tts.gpu=Qe,!0)),d(Z,Le)},ia=Z=>{var Le=Np(),Ke=ht(Le),Re=i(n(Ke),2);N("change",Re,r),Xt(Re,()=>t().tts.pocket_tts.gpu,Qe=>t(t().tts.pocket_tts.gpu=Qe,!0)),d(Z,Le)},ra=Z=>{var Le=Vp(),Ke=ht(Le),Re=i(n(Ke),2);N("change",Re,r),Xt(Re,()=>t().tts.breeze_tts_2.gpu,Qe=>t(t().tts.breeze_tts_2.gpu=Qe,!0)),d(Z,Le)},bt=Z=>{var Le=Fp(),Ke=ht(Le),Re=i(n(Ke),2);N("change",Re,r),Xt(Re,()=>t().tts.vox_cpm_2.gpu,Qe=>t(t().tts.vox_cpm_2.gpu=Qe,!0)),d(Z,Le)};k(Et,Z=>{t().tts.engine==="piper"?Z(jt):t().tts.engine==="pocket_tts"?Z(ia,1):t().tts.engine==="breeze_tts_2"?Z(ra,2):t().tts.engine==="vox_cpm_2"&&Z(bt,3)})}var ea=i(Et,2),Lt=n(ea),Ht=n(Lt),ta=i(Lt,2),Oe=i(ea,2),qe=n(Oe),$=n(qe),g=i(qe,2);{var A=Z=>{var Le=Bp(),Ke=i(n(Le),2);let Re;var Qe=n(Ke);w(()=>{Re=Te(Ke,1,"run-speed-value svelte-1q9seip",null,Re,{counting:e(u)}),y(Qe,e(u)?`${e(c)} ms`:`${e(l)} ms`)}),d(Z,Le)};k(g,Z=>{(e(u)||e(l)!==null)&&Z(A)})}var Pe=i(Oe,2);{var Ue=Z=>{var Le=qp(),Ke=n(Le);w(()=>{var Re;return y(Ke,`❌ ${(Re=e(_))!=null?Re:""}`)}),d(Z,Le)};k(Pe,Z=>{e(_)&&Z(Ue)})}var ie=i(Pe,2);{var xe=Z=>{var Le=Kp(),Ke=n(Le);w(Re=>y(Ke,`Test TTS unavailable: ${Re!=null?Re:""}`),[()=>oe()]),d(Z,Le)},Ce=ce(()=>!e(_)&&R()&&oe());k(ie,Z=>{e(Ce)&&Z(xe)})}var He=i(ct,2);{var Xe=Z=>{var Le=Yp(),Ke=i(n(Le),2),Re=i(n(Ke),2);sa(Re,{get options(){return e(le)},onchange:ee,get value(){return t().tts.voice},set value(Ut){t(t().tts.voice=Ut,!0)}});var Qe=i(Ke,2),Jt=n(Qe);{var $t=Ut=>{var Pt=Up();d(Ut,Pt)},ka=Ut=>{var Pt=jp(),kt=n(Pt);w(()=>{var aa;return y(kt,`⏳ Downloading ${(aa=t().tts.voice)!=null?aa:""} (model + config)...`)}),d(Ut,Pt)},xa=Ut=>{var Pt=Hp(),kt=n(Pt),aa=n(kt),Da=i(kt,2),Ua=n(Da);w(()=>{Te(kt,1,Ia(e(T)[t().tts.voice]?"status-downloaded":"status-missing"),"svelte-1q9seip"),y(aa,e(T)[t().tts.voice]?"✔ Voice downloaded and ready":"❌ Voice files missing"),Da.disabled=e(T)[t().tts.voice]||e(se),y(Ua,e(T)[t().tts.voice]?"Downloaded":"📥 Download")}),N("click",Da,()=>z(t().tts.voice)),d(Ut,Pt)};k(Jt,Ut=>{e(D)?Ut($t):e(se)?Ut(ka,1):Ut(xa,-1)})}var Ta=i(Qe,2),la=i(n(Ta),2);let _a;var Aa=i(la,2);{var Ca=Ut=>{var Pt=Wp(),kt=n(Pt);w(()=>y(kt,e(fe))),d(Ut,Pt)};k(Aa,Ut=>{e(fe)&&Ut(Ca)})}w(()=>_a=Te(la,1,"svelte-1q9seip",null,_a,{"field-input-error":!!e(fe)})),N("change",la,L),xs("blur",la,I),N("keydown",la,ge),We(la,()=>t().tts.voice_dir,Ut=>t(t().tts.voice_dir=Ut,!0)),d(Z,Le)};k(He,Z=>{t().tts.engine==="piper"&&Z(Xe)})}var Dt=i(He,2);{var zt=Z=>{var Le=Zp(),Ke=i(n(Le),6),Re=i(n(Ke),2);sa(Re,{get options(){return e(W)},defaultToFirst:!0,onchange:r,get value(){return t().tts.vox_cpm_2.cloned_voice},set value(Rt){t(t().tts.vox_cpm_2.cloned_voice=Rt,!0)}});var Qe=i(Ke,2),Jt=i(n(Qe),2),$t=i(Qe,4),ka=i(n($t),2),xa=i($t,4),Ta=n(xa);{var la=Rt=>{var Ja=$p();d(Rt,Ja)},_a=Rt=>{var Ja=Gp();d(Rt,Ja)},Aa=Rt=>{var Ja=Jp(),Bn=n(Ja),rr=n(Bn),Nt=i(Bn,2),za=n(Nt);w(()=>{Te(Bn,1,Ia(e(P)?"status-downloaded":"status-missing"),"svelte-1q9seip"),y(rr,e(P)?"✔ Model weights downloaded and ready":"❌ Model files missing"),Nt.disabled=e(P)||e(ke),y(za,e(P)?"Downloaded":"📥 Download")}),N("click",Nt,ye),d(Rt,Ja)};k(Ta,Rt=>{e(C)?Rt(la):e(ke)?Rt(_a,1):Rt(Aa,-1)})}var Ca=i(xa,2),Ut=i(n(Ca),5);{var Pt=Rt=>{var Ja=Xp();d(Rt,Ja)};k(Ut,Rt=>{e(rt)&&Rt(Pt)})}var kt=i(Ca,2),aa=i(n(kt),2),Da=i(kt,4),Ua=i(n(Da),2);N("change",Jt,()=>{r(),J(t().tts.vox_cpm_2.voice_dir)}),We(Jt,()=>t().tts.vox_cpm_2.voice_dir,Rt=>t(t().tts.vox_cpm_2.voice_dir=Rt,!0)),N("change",ka,r),Xt(ka,()=>t().tts.vox_cpm_2.ultimate_cloning,Rt=>t(t().tts.vox_cpm_2.ultimate_cloning=Rt,!0)),N("change",aa,r),We(aa,()=>t().tts.vox_cpm_2.model_dir,Rt=>t(t().tts.vox_cpm_2.model_dir=Rt,!0)),N("change",Ua,r),Xt(Ua,()=>t().tts.vox_cpm_2.prewarm,Rt=>t(t().tts.vox_cpm_2.prewarm=Rt,!0)),d(Z,Le)};k(Dt,Z=>{t().tts.engine==="vox_cpm_2"&&Z(zt)})}var Ft=i(Dt,2);{var Wt=Z=>{var Le=af(),Ke=i(n(Le),6),Re=i(n(Ke),2);sa(Re,{get options(){return e(W)},defaultToFirst:!0,onchange:r,get value(){return t().tts.breeze_tts_2.cloned_voice},set value(Pt){t(t().tts.breeze_tts_2.cloned_voice=Pt,!0)}});var Qe=i(Ke,2),Jt=i(n(Qe),2),$t=i(Qe,6),ka=n($t);{var xa=Pt=>{var kt=Qp();d(Pt,kt)},Ta=Pt=>{var kt=ef();d(Pt,kt)},la=Pt=>{var kt=tf(),aa=n(kt),Da=n(aa),Ua=i(aa,2),Rt=n(Ua);w(()=>{Te(aa,1,Ia(e(Ie)?"status-downloaded":"status-missing"),"svelte-1q9seip"),y(Da,e(Ie)?"✔ Model weights downloaded and ready":"❌ Model files missing"),Ua.disabled=e(Ie)||e(Ze),y(Rt,e(Ie)?"Downloaded":"📥 Download")}),N("click",Ua,at),d(Pt,kt)};k(ka,Pt=>{e(Ge)?Pt(xa):e(Ze)?Pt(Ta,1):Pt(la,-1)})}var _a=i($t,4),Aa=i(n(_a),2),Ca=i(_a,4),Ut=i(n(Ca),2);N("change",Jt,()=>{r(),J(t().tts.breeze_tts_2.voice_dir)}),We(Jt,()=>t().tts.breeze_tts_2.voice_dir,Pt=>t(t().tts.breeze_tts_2.voice_dir=Pt,!0)),N("change",Aa,r),We(Aa,()=>t().tts.breeze_tts_2.model_dir,Pt=>t(t().tts.breeze_tts_2.model_dir=Pt,!0)),N("change",Ut,r),Xt(Ut,()=>t().tts.breeze_tts_2.prewarm,Pt=>t(t().tts.breeze_tts_2.prewarm=Pt,!0)),d(Z,Le)};k(Ft,Z=>{t().tts.engine==="breeze_tts_2"&&Z(Wt)})}var Yt=i(Ft,2);{var fa=Z=>{var Le=of(),Ke=i(n(Le),2),Re=i(n(Ke),2);sa(Re,{get options(){return e(W)},defaultToFirst:!0,onchange:H,get value(){return t().tts.pocket_tts.voice},set value(kt){t(t().tts.pocket_tts.voice=kt,!0)}});var Qe=i(Ke,2),Jt=n(Qe);{var $t=kt=>{var aa=sf();d(kt,aa)},ka=kt=>{var aa=nf();d(kt,aa)},xa=kt=>{var aa=rf(),Da=n(aa),Ua=n(Da),Rt=i(Da,2),Ja=n(Rt);w(()=>{Te(Da,1,Ia(e(pe)?"status-downloaded":"status-missing"),"svelte-1q9seip"),y(Ua,e(pe)?"✔ Model and voice clip downloaded and ready":"❌ Model files missing"),Rt.disabled=e(pe)||e(Ye),y(Ja,e(pe)?"Downloaded":"📥 Download")}),N("click",Rt,it),d(kt,aa)};k(Jt,kt=>{e(ze)?kt($t):e(Ye)?kt(ka,1):kt(xa,-1)})}var Ta=i(Qe,4),la=i(n(Ta),2);let _a;var Aa=i(la,2);{var Ca=kt=>{var aa=lf(),Da=n(aa);w(()=>y(Da,e(be))),d(kt,aa)};k(Aa,kt=>{e(be)&&kt(Ca)})}var Ut=i(Ta,4),Pt=i(n(Ut),2);w(()=>_a=Te(la,1,"svelte-1q9seip",null,_a,{"field-input-error":!!e(be)})),N("change",la,Se),xs("blur",la,J),N("keydown",la,De),We(la,()=>t().tts.pocket_tts.voice_dir,kt=>t(t().tts.pocket_tts.voice_dir=kt,!0)),N("change",Pt,r),Xt(Pt,()=>t().tts.pocket_tts.prewarm,kt=>t(t().tts.pocket_tts.prewarm=kt,!0)),d(Z,Le)};k(Yt,Z=>{t().tts.engine==="pocket_tts"&&Z(fa)})}var Gt=i(Yt,2);{var ma=Z=>{var Le=_f(),Ke=i(n(Le),4);{var Re=Nt=>{var za=cf();d(Nt,za)};k(Ke,Nt=>{e(Fe)||Nt(Re)})}var Qe=i(Ke,2),Jt=n(Qe);{var $t=Nt=>{var za=df();d(Nt,za)},ka=Nt=>{var za=vf();d(Nt,za)},xa=Nt=>{var za=uf(),Hs=n(za),Ti=n(Hs),lr=i(Hs,2),Wo=n(lr);w(()=>{Te(Hs,1,Ia(e(he)?"status-downloaded":"status-missing"),"svelte-1q9seip"),y(Ti,e(he)?"✔ Model downloaded and ready":"❌ Model files missing"),lr.disabled=e(he)||e(we),y(Wo,e(he)?"Downloaded":"📥 Download")}),N("click",lr,G),d(Nt,za)};k(Jt,Nt=>{e(re)?Nt($t):e(we)?Nt(ka,1):Nt(xa,-1)})}var Ta=i(Qe,2);{var la=Nt=>{var za=pf(),Hs=n(za);w(()=>{var Ti;return y(Hs,`❌ ${(Ti=e(Y))!=null?Ti:""}`)}),d(Nt,za)};k(Ta,Nt=>{e(Y)&&Nt(la)})}var _a=i(Ta,2),Aa=i(n(_a),2),Ca=i(_a,4),Ut=i(n(Ca),2),Pt=i(Ca,4),kt=i(n(Pt),2),aa=i(Pt,4),Da=i(n(aa),2),Ua=i(aa,4),Rt=i(n(Ua),2),Ja=n(Rt),Bn=i(Ua,4);{var rr=Nt=>{var za=ff(),Hs=n(za);w(()=>y(Hs,e(Je))),d(Nt,za)};k(Bn,Nt=>{e(Je)&&Nt(rr)})}w(()=>{Rt.disabled=!e(he)||e(de),y(Ja,e(de)?"Inspecting...":"🔍 Inspect graphs")}),N("change",Aa,me),We(Aa,()=>t().tts.inflect_micro.seed,Nt=>t(t().tts.inflect_micro.seed=Nt,!0)),N("change",Ut,me),We(Ut,()=>t().tts.inflect_micro.noise_scale,Nt=>t(t().tts.inflect_micro.noise_scale=Nt,!0)),N("change",kt,me),Xt(kt,()=>t().tts.inflect_micro.prewarm,Nt=>t(t().tts.inflect_micro.prewarm=Nt,!0)),N("change",Da,me),We(Da,()=>t().tts.inflect_micro.model_dir,Nt=>t(t().tts.inflect_micro.model_dir=Nt,!0)),N("click",Rt,_e),d(Z,Le)};k(Gt,Z=>{t().tts.engine==="inflect_micro"&&Z(ma)})}var Oa=i(Gt,2),Ga=i(n(Oa),2),tt=i(n(Ga),2);sa(tt,{get options(){return ae},onchange:X,get value(){return t().tts.memory_mode},set value(Z){t(t().tts.memory_mode=Z,!0)}});var gt=i(Ga,2);{var It=Z=>{var Le=hf(),Ke=ht(Le),Re=i(n(Ke),2),Qe=i(Ke,2),Jt=n(Qe);w(()=>{var $t;sr(Re,e(O)),y(Jt,`The model is loaded the moment VoxCtrl knows it will be needed — as soon as you start
dictating to a target that speaks — and stays primed while you keep using it. The
- countdown restarts on every use, so it only unloads after ${(Gt=e(O))!=null?Gt:""}
+ countdown restarts on every use, so it only unloads after ${($t=e(O))!=null?$t:""}
${e(O)===1?"minute":"minutes"} of no speech. The first reply after an
- unload takes a few seconds longer while the model loads again.`)}),N("change",Re,ve),d(Z,Le)},ut=Z=>{var Le=gf();d(Z,Le)};k(gt,Z=>{t().tts.memory_mode==="on_demand"?Z(It):Z(ut,-1)})}var At=i(Oa,2),jt=i(n(At),2),wa=i(n(jt),2),oa=i(jt,2),La=i(n(oa),4);Lp(La,{onchange:r,get keys(){return t().tts.stop_key},set keys(Z){t(t().tts.stop_key=Z,!0)}});var ja=i(At,2);jo(ja,{class:"mt-6",onchange:r,title:"TTS Snippets (Pronunciation Guide)",hint:'Type a word (e.g. "voxctrl") ➔ its spoken expansion/pronunciation (e.g. "vox control"). Only affects speech playback.',addLabel:"Add Pronunciation",keyPlaceholder:"Word / Abbreviation",valuePlaceholder:"Spoken pronunciation",emptyText:"No pronunciation snippets defined.",get value(){return t().tts.snippets},set value(Z){t(t().tts.snippets=Z,!0)}}),w((Z,Le,je)=>{y(Ht,`Speed (${Z!=null?Z:""}×)`),qe.disabled=Le,mt(qe,"title",je),y(G,e(ne)?"Speaking...":e(m)?"⏹ Stop & Test":"Test TTS")},[()=>t().tts.speed.toFixed(2),()=>R(),()=>{var Z;return(Z=oe())!=null?Z:"Speak a test phrase"}]),N("change",nt,r),Xt(nt,()=>t().tts.enabled,Z=>t(t().tts.enabled=Z,!0)),N("change",ta,r),We(ta,()=>t().tts.speed,Z=>t(t().tts.speed=Z,!0)),N("click",qe,j),N("change",wa,r),Xt(wa,()=>t().tts.response_overlay,Z=>t(t().tts.response_overlay=Z,!0)),d(s,Ge),St()}Qt(["change","click","keydown"]);var yf=p(''),wf=p(`⚠️ The model isn't available on this server. Post-processing will fail with a 404 — pick a model from the list above or pull it on the server.`),kf=p(""),xf=p('Select the Custom preset to edit the system and user prompts.'),Tf=p('⚠️ The user prompt must contain the placeholder.'),Sf=p('Use where your dictated speech should be inserted.'),Ef=p(`
OpenAI API LLM Post-Processing
Connect to any OpenAI-compatible API server — a local server or a hosted
+ unload takes a few seconds longer while the model loads again.`)}),N("change",Re,ve),d(Z,Le)},ut=Z=>{var Le=gf();d(Z,Le)};k(gt,Z=>{t().tts.memory_mode==="on_demand"?Z(It):Z(ut,-1)})}var Mt=i(Oa,2),Kt=i(n(Mt),2),wa=i(n(Kt),2),oa=i(Kt,2),La=i(n(oa),4);Lp(La,{onchange:r,get keys(){return t().tts.stop_key},set keys(Z){t(t().tts.stop_key=Z,!0)}});var Ka=i(Mt,2);Ko(Ka,{class:"mt-6",onchange:r,title:"TTS Snippets (Pronunciation Guide)",hint:'Type a word (e.g. "voxctrl") ➔ its spoken expansion/pronunciation (e.g. "vox control"). Only affects speech playback.',addLabel:"Add Pronunciation",keyPlaceholder:"Word / Abbreviation",valuePlaceholder:"Spoken pronunciation",emptyText:"No pronunciation snippets defined.",get value(){return t().tts.snippets},set value(Z){t(t().tts.snippets=Z,!0)}}),w((Z,Le,Ke)=>{y(Ht,`Speed (${Z!=null?Z:""}×)`),qe.disabled=Le,mt(qe,"title",Ke),y($,e(ne)?"Speaking...":e(m)?"⏹ Stop & Test":"Test TTS")},[()=>t().tts.speed.toFixed(2),()=>R(),()=>{var Z;return(Z=oe())!=null?Z:"Speak a test phrase"}]),N("change",nt,r),Xt(nt,()=>t().tts.enabled,Z=>t(t().tts.enabled=Z,!0)),N("change",ta,r),We(ta,()=>t().tts.speed,Z=>t(t().tts.speed=Z,!0)),N("click",qe,K),N("change",wa,r),Xt(wa,()=>t().tts.response_overlay,Z=>t(t().tts.response_overlay=Z,!0)),d(s,$e),St()}Qt(["change","click","keydown"]);var yf=p(''),wf=p(`⚠️ The model isn't available on this server. Post-processing will fail with a 404 — pick a model from the list above or pull it on the server.`),kf=p(""),xf=p('Select the Custom preset to edit the system and user prompts.'),Tf=p('⚠️ The user prompt must contain the placeholder.'),Sf=p('Use where your dictated speech should be inserted.'),Ef=p(`
OpenAI API LLM Post-Processing
Connect to any OpenAI-compatible API server — a local server or a hosted
provider. The URL defaults to a local server; point it anywhere you like and
supply an API key when the server requires one.
Connection
Default Prompts
The system prompt tells the model how to transform your speech. The user
prompt is the message sent to the model — it must contain , which is replaced with whatever you dictate.
Built-in presets are read-only; choose Custom to edit the
- prompts yourself.
System Prompt
User Prompt
`);function Cf(s,a){Tt(a,!0);let t=Ct(a,"cfg",15);function r(){Ot.set(t()),Ss.set(!0)}let l=S(!1),c=S(null),u=S(yt([])),v=ce(()=>[...e(u).map(he=>({value:he,label:he})),...t().openai.model&&!e(u).includes(t().openai.model)?[{value:t().openai.model,label:`${t().openai.model} (not found)`}]:[]]);const f=[{value:"clean",label:"Clean (grammar fix)"},{value:"formal",label:"Formal"},{value:"casual",label:"Casual"},{value:"bullet",label:"Bullet points"},{value:"concise",label:"Concise (summarize)"},{value:"custom",label:"Custom (editable)"}],h={clean:"Fix grammar and punctuation only. Return only the corrected text, no commentary.",formal:"Rewrite the user's text in formal professional language. Return only the result.",casual:"Rewrite the user's text in casual conversational language. Return only the result.",bullet:"Convert the user's text to a bullet-point list. Return only the list.",concise:"Summarize the user's text concisely in 1-2 sentences. Return only the summary."};let b=ce(()=>t().openai.mode==="custom");function m(){const he=h[t().openai.mode];he!==void 0&&(t(t().openai.system_prompt=he,!0),t(t().openai.user_prompt="{text}",!0)),r()}let _=ce(()=>t().openai.user_prompt.includes("{text}")),x=ce(()=>e(u).length>0&&!!t().openai.model&&!e(u).includes(t().openai.model));async function A(){o(l,!0),o(c,null);try{const he=await E("test_openai",{endpoint:t().openai.endpoint,apiKey:t().openai.api_key,timeoutSecs:t().openai.timeout_secs});o(c,{success:he.success,message:he.message},!0),he.success&&(o(u,he.models,!0),!t().openai.model&&he.models.length>0&&(t(t().openai.model=he.models[0],!0),r()))}catch(he){o(c,{success:!1,message:he.toString()},!0)}finally{o(l,!1)}}qt(()=>{A()});var q=Ef(),T=i(n(q),4),D=i(n(T),2),se=i(n(D),2),ne=i(D,2),fe=i(n(ne),2),Q=i(ne,2),z=i(n(Q),2);{var I=he=>{sa(he,{get options(){return e(v)},onchange:r,get value(){return t().openai.model},set value(re){t(t().openai.model=re,!0)}})},L=he=>{var re=yf();N("change",re,r),We(re,()=>t().openai.model,we=>t(t().openai.model=we,!0)),d(he,re)};k(z,he=>{e(u).length>0?he(I):he(L,-1)})}var ge=i(Q,2);{var ee=he=>{var re=wf(),we=i(n(re)),Je=n(we);w(()=>y(Je,t().openai.model)),d(he,re)};k(ge,he=>{e(x)&&he(ee)})}var j=i(ge,2),V=i(n(j),2),oe=i(j,2),R=n(oe),B=n(R),be=i(R,2);{var Pe=he=>{var re=kf(),we=n(re);w(()=>{Te(re,1,`status-msg ${e(c).success?"success":"error"}`,"svelte-1bvctpo"),y(we,e(c).message)}),d(he,re)};k(be,he=>{e(c)&&he(Pe)})}var ue=i(T,2),K=i(n(ue),2),J=i(n(K));J.textContent="{text}";var Se=i(K,2),De=i(n(Se),2);sa(De,{get options(){return f},onchange:m,get value(){return t().openai.mode},set value(he){t(t().openai.mode=he,!0)}});var le=i(Se,2),W=i(n(le),2),ae=i(le,2),O=i(n(ae),2);mt(O,"placeholder","{text}");var X=i(O,2);{var ve=he=>{var re=xf();d(he,re)},Ae=he=>{var re=Tf(),we=i(n(re));we.textContent="{text}",d(he,re)},Fe=he=>{var re=Sf(),we=i(n(re));we.textContent="{text}",d(he,re)};k(X,he=>{e(b)?e(_)?he(Fe,-1):he(Ae,1):he(ve)})}w(()=>{R.disabled=e(l),y(B,e(l)?"⏳ Testing...":"🔌 Test Connection"),W.readOnly=!e(b),Te(W,1,Ia(e(b)?"":"locked"),"svelte-1bvctpo"),O.readOnly=!e(b),Te(O,1,Ia(e(b)?e(_)?"":"invalid":"locked"),"svelte-1bvctpo")}),N("change",se,r),We(se,()=>t().openai.endpoint,he=>t(t().openai.endpoint=he,!0)),N("change",fe,r),We(fe,()=>t().openai.api_key,he=>t(t().openai.api_key=he,!0)),N("change",V,r),We(V,()=>t().openai.timeout_secs,he=>t(t().openai.timeout_secs=he,!0)),N("click",R,A),N("change",W,r),We(W,()=>t().openai.system_prompt,he=>t(t().openai.system_prompt=he,!0)),N("change",O,r),We(O,()=>t().openai.user_prompt,he=>t(t().openai.user_prompt=he,!0)),d(s,q),St()}Qt(["change","click"]);var Af=p(''),Mf=p('⏳ Downloading'),Pf=p('Missing'),Df=p('⏳ Checking S1-mini model files...'),zf=p('⏳ Downloading S1-mini model (s1-mini-q4_k_m.gguf & tokenizer.json)...'),If=p(''),Of=p('
❌ Model files missing
'),Lf=p(' ',1),Rf=p('
These features are covered by S1-mini when enabled.
'),Nf=p(`
Post-Processing
S1-mini Dictation Cleanup
Note: S1-Mini is a ~480 MB download.
Basic Text Cleanup
Voice Commands
Transcribes the first few seconds of each recording early, so a command like
+ prompts yourself.
System Prompt
User Prompt
`);function Cf(s,a){Tt(a,!0);let t=Ct(a,"cfg",15);function r(){Ot.set(t()),Ss.set(!0)}let l=S(!1),c=S(null),u=S(yt([])),v=ce(()=>[...e(u).map(he=>({value:he,label:he})),...t().openai.model&&!e(u).includes(t().openai.model)?[{value:t().openai.model,label:`${t().openai.model} (not found)`}]:[]]);const f=[{value:"clean",label:"Clean (grammar fix)"},{value:"formal",label:"Formal"},{value:"casual",label:"Casual"},{value:"bullet",label:"Bullet points"},{value:"concise",label:"Concise (summarize)"},{value:"custom",label:"Custom (editable)"}],h={clean:"Fix grammar and punctuation only. Return only the corrected text, no commentary.",formal:"Rewrite the user's text in formal professional language. Return only the result.",casual:"Rewrite the user's text in casual conversational language. Return only the result.",bullet:"Convert the user's text to a bullet-point list. Return only the list.",concise:"Summarize the user's text concisely in 1-2 sentences. Return only the summary."};let b=ce(()=>t().openai.mode==="custom");function m(){const he=h[t().openai.mode];he!==void 0&&(t(t().openai.system_prompt=he,!0),t(t().openai.user_prompt="{text}",!0)),r()}let _=ce(()=>t().openai.user_prompt.includes("{text}")),x=ce(()=>e(u).length>0&&!!t().openai.model&&!e(u).includes(t().openai.model));async function M(){o(l,!0),o(c,null);try{const he=await E("test_openai",{endpoint:t().openai.endpoint,apiKey:t().openai.api_key,timeoutSecs:t().openai.timeout_secs});o(c,{success:he.success,message:he.message},!0),he.success&&(o(u,he.models,!0),!t().openai.model&&he.models.length>0&&(t(t().openai.model=he.models[0],!0),r()))}catch(he){o(c,{success:!1,message:he.toString()},!0)}finally{o(l,!1)}}qt(()=>{M()});var q=Ef(),T=i(n(q),4),D=i(n(T),2),se=i(n(D),2),ne=i(D,2),fe=i(n(ne),2),Q=i(ne,2),z=i(n(Q),2);{var I=he=>{sa(he,{get options(){return e(v)},onchange:r,get value(){return t().openai.model},set value(re){t(t().openai.model=re,!0)}})},L=he=>{var re=yf();N("change",re,r),We(re,()=>t().openai.model,we=>t(t().openai.model=we,!0)),d(he,re)};k(z,he=>{e(u).length>0?he(I):he(L,-1)})}var ge=i(Q,2);{var ee=he=>{var re=wf(),we=i(n(re)),Je=n(we);w(()=>y(Je,t().openai.model)),d(he,re)};k(ge,he=>{e(x)&&he(ee)})}var K=i(ge,2),V=i(n(K),2),oe=i(K,2),R=n(oe),B=n(R),be=i(R,2);{var Ae=he=>{var re=kf(),we=n(re);w(()=>{Te(re,1,`status-msg ${e(c).success?"success":"error"}`,"svelte-1bvctpo"),y(we,e(c).message)}),d(he,re)};k(be,he=>{e(c)&&he(Ae)})}var ue=i(T,2),j=i(n(ue),2),J=i(n(j));J.textContent="{text}";var Se=i(j,2),De=i(n(Se),2);sa(De,{get options(){return f},onchange:m,get value(){return t().openai.mode},set value(he){t(t().openai.mode=he,!0)}});var le=i(Se,2),W=i(n(le),2),ae=i(le,2),O=i(n(ae),2);mt(O,"placeholder","{text}");var X=i(O,2);{var ve=he=>{var re=xf();d(he,re)},Me=he=>{var re=Tf(),we=i(n(re));we.textContent="{text}",d(he,re)},Fe=he=>{var re=Sf(),we=i(n(re));we.textContent="{text}",d(he,re)};k(X,he=>{e(b)?e(_)?he(Fe,-1):he(Me,1):he(ve)})}w(()=>{R.disabled=e(l),y(B,e(l)?"⏳ Testing...":"🔌 Test Connection"),W.readOnly=!e(b),Te(W,1,Ia(e(b)?"":"locked"),"svelte-1bvctpo"),O.readOnly=!e(b),Te(O,1,Ia(e(b)?e(_)?"":"invalid":"locked"),"svelte-1bvctpo")}),N("change",se,r),We(se,()=>t().openai.endpoint,he=>t(t().openai.endpoint=he,!0)),N("change",fe,r),We(fe,()=>t().openai.api_key,he=>t(t().openai.api_key=he,!0)),N("change",V,r),We(V,()=>t().openai.timeout_secs,he=>t(t().openai.timeout_secs=he,!0)),N("click",R,M),N("change",W,r),We(W,()=>t().openai.system_prompt,he=>t(t().openai.system_prompt=he,!0)),N("change",O,r),We(O,()=>t().openai.user_prompt,he=>t(t().openai.user_prompt=he,!0)),d(s,q),St()}Qt(["change","click"]);var Mf=p(''),Pf=p('⏳ Downloading'),Af=p('Missing'),Df=p('⏳ Checking S1-mini model files...'),zf=p('⏳ Downloading S1-mini model (s1-mini-q4_k_m.gguf & tokenizer.json)...'),If=p(''),Of=p('
❌ Model files missing
'),Lf=p(' ',1),Rf=p('
These features are covered by S1-mini when enabled.
'),Nf=p(`
Post-Processing
S1-mini Dictation Cleanup
Note: S1-Mini is a ~480 MB download.
Basic Text Cleanup
Voice Commands
Transcribes the first few seconds of each recording early, so a command like
“Hey Vox, say …” shows its overlay and starts loading the voice before you let go
of the hotkey. Where the text goes is still decided by the full transcript. Turn
- this off to save the extra transcription work.
Custom Dictionary
Provide a comma-separated list of words (e.g. names or jargon like "Waylin, Rufer, Enola, Kenz") that are hard to spell. The transcription process will correct these in the final text.
`);function Vf(s,a){Tt(a,!0);let t=Ct(a,"cfg",15);t().engine&&!t().engine.s1_mini&&t(t().engine.s1_mini={enabled:!1,styling:"semi-formal"},!0);function r(){Ot.set(t()),Ss.set(!0)}let l=S(!1),c=S(!1),u=S(!1),v=S(null);const f={cuda:"CUDA (NVIDIA)",vulkan:"Vulkan (AMD/Intel/NVIDIA)",coreml:"CoreML (Apple)",webgpu:"WebGPU (AMD/Intel/NVIDIA)"},h=ve=>{var Ae;return(Ae=f[ve])!=null?Ae:ve};function b(){t().engine.s1_mini||t(t().engine.s1_mini={enabled:!1,styling:"semi-formal"},!0)}async function m(){o(c,!0);try{o(l,await E("check_s1_mini_downloaded"),!0)}catch(ve){console.error("Failed to check S1-mini download status",ve),o(l,!1)}finally{o(c,!1)}}async function _(){if(!e(u)){o(u,!0);try{await E("download_s1_mini_model"),o(l,!0)}catch(ve){alert(`Failed to download S1-mini model: ${ve}`)}finally{o(u,!1)}}}async function x(){b(),r(),t().engine.s1_mini.enabled&&!e(l)&&await _()}let A=ce(()=>{var ve;return!!((ve=t().engine.s1_mini)!=null&&ve.enabled)});qt(async()=>{var ve;b(),m();try{const Ae=await E("accelerator_support");o(v,(ve=Ae.s1_mini_gpu)!=null?ve:null,!0)}catch(Ae){console.error("Failed to query GPU support",Ae)}});let q=ce(()=>t().features.custom_vocabulary?t().features.custom_vocabulary.join(", "):"");function T(ve){const Ae=ve.target;t(t().features.custom_vocabulary=Ae.value.split(",").map(Fe=>Fe.trim()).filter(Fe=>Fe.length>0),!0),r()}var D=Nf(),se=i(n(D),2),ne=n(se),fe=i(n(ne),2);{var Q=ve=>{var Ae=Af(),Fe=n(Ae);w(he=>y(Fe,`✔ Ready ${he!=null?he:""}`),[()=>e(v)?`(${h(e(v))})`:"(CPU)"]),d(ve,Ae)},z=ve=>{var Ae=Mf();d(ve,Ae)},I=ve=>{var Ae=Pf();d(ve,Ae)};k(fe,ve=>{e(l)?ve(Q):e(u)?ve(z,1):e(A)&&ve(I,2)})}var L=i(ne,2),ge=i(n(L),2),ee=i(L,4);{var j=ve=>{var Ae=Lf(),Fe=ht(Ae),he=n(Fe);{var re=te=>{var Y=Df();d(te,Y)},we=te=>{var Y=zf();d(te,Y)},Je=te=>{var Y=If(),_e=n(Y);w(me=>y(_e,`✔ Model downloaded and ready ${me!=null?me:""}`),[()=>e(v)?`(${h(e(v))} GPU accelerated)`:"on CPU"]),d(te,Y)},de=te=>{var Y=Of(),_e=i(n(Y),2);N("click",_e,_),d(te,Y)};k(he,te=>{e(c)?te(re):e(u)?te(we,1):e(l)?te(Je,2):te(de,-1)})}var $=i(Fe,2),U=i(n($),2);sa(U,{options:[{value:"semi-formal",label:"Semi-formal (Default)"},{value:"casual",label:"Casual"},{value:"formal",label:"Formal"},{value:"verbatim",label:"Verbatim"},{value:"concise",label:"Concise"}],onchange:r,get value(){return t().engine.s1_mini.styling},set value(te){t(t().engine.s1_mini.styling=te,!0)}}),d(ve,Ae)};k(ee,ve=>{e(A)&&ve(j)})}var V=i(se,2);let oe;var R=i(n(V),2);{var B=ve=>{var Ae=Rf();d(ve,Ae)};k(R,ve=>{e(A)&&ve(B)})}var be=i(R,2),Pe=i(n(be),2),ue=i(be,2),K=i(n(ue),2),J=i(ue,2),Se=i(n(J),2),De=i(V,2),le=i(n(De),2),W=i(n(le),2),ae=i(De,2),O=i(n(ae),4);Fs(O,ve=>ua==null?void 0:ua(ve));var X=i(ae,2);jo(X,{onchange:r,title:"Snippets",hint:"Type a trigger word → it expands to the replacement text.",addLabel:"Add Snippet",keyPlaceholder:"Trigger word",valuePlaceholder:"Expansion text",emptyText:"No snippets defined.",get value(){return t().features.snippets},set value(ve){t(t().features.snippets=ve,!0)}}),w(()=>{oe=Te(V,1,"field-group svelte-1s1a8xn",null,oe,{"disabled-section":e(A)}),Pe.disabled=e(A),K.disabled=e(A),Se.disabled=e(A),sr(O,e(q))}),N("change",ge,x),Xt(ge,()=>t().engine.s1_mini.enabled,ve=>t(t().engine.s1_mini.enabled=ve,!0)),N("change",Pe,r),Xt(Pe,()=>t().features.remove_fillers,ve=>t(t().features.remove_fillers=ve,!0)),N("change",K,r),Xt(K,()=>t().features.spoken_punctuation,ve=>t(t().features.spoken_punctuation=ve,!0)),N("change",Se,r),Xt(Se,()=>t().features.auto_format_lists,ve=>t(t().features.auto_format_lists=ve,!0)),N("change",W,r),Xt(W,()=>t().features.early_command_detection,ve=>t(t().features.early_command_detection=ve,!0)),N("input",O,T),d(s,D),St()}Qt(["change","click","input"]);async function Uo(s,a){await E("plugin:shell|open",{path:s,with:a})}async function Ff(s={}){return typeof s=="object"&&Object.freeze(s),await E("plugin:dialog|save",{options:s})}var Bf=p(""),qf=p(""),jf=p('
'),Uf=p('
'),Kf=p(''),Hf=p('
Building the report…
'),Wf=p('
'),$f=p('
Title: · Report ID
',1),Gf=p('
Fill in the summary and description above and the finished report appears here.
'),Yf=p(''),Jf=p(''),Xf=p(''),Zf=p(''),Qf=p('
'),e_=p('
'),t_=p("Send report files it for you — no GitHub account needed.",1),a_=p("This build has no automatic submission set up, so the routes below are the ones to use. Submit bug report opens the pre-filled issue form on GitHub and copies the report to your clipboard so you can submit directly.",1),s_=p('
Saved to
'),n_=p(''),i_=p("
"),r_=p(`
Report a Bug
VoxCtrl 0.5.0 added a Windows build, and a Windows GPU build is on its way. Neither has been
+ this off to save the extra transcription work.
Custom Dictionary
Provide a comma-separated list of words (e.g. names or jargon like "Waylin, Rufer, Enola, Kenz") that are hard to spell. The transcription process will correct these in the final text.
`);function Vf(s,a){Tt(a,!0);let t=Ct(a,"cfg",15);t().engine&&!t().engine.s1_mini&&t(t().engine.s1_mini={enabled:!1,styling:"semi-formal"},!0);function r(){Ot.set(t()),Ss.set(!0)}let l=S(!1),c=S(!1),u=S(!1),v=S(null);const f={cuda:"CUDA (NVIDIA)",vulkan:"Vulkan (AMD/Intel/NVIDIA)",coreml:"CoreML (Apple)",webgpu:"WebGPU (AMD/Intel/NVIDIA)"},h=ve=>{var Me;return(Me=f[ve])!=null?Me:ve};function b(){t().engine.s1_mini||t(t().engine.s1_mini={enabled:!1,styling:"semi-formal"},!0)}async function m(){o(c,!0);try{o(l,await E("check_s1_mini_downloaded"),!0)}catch(ve){console.error("Failed to check S1-mini download status",ve),o(l,!1)}finally{o(c,!1)}}async function _(){if(!e(u)){o(u,!0);try{await E("download_s1_mini_model"),o(l,!0)}catch(ve){alert(`Failed to download S1-mini model: ${ve}`)}finally{o(u,!1)}}}async function x(){b(),r(),t().engine.s1_mini.enabled&&!e(l)&&await _()}let M=ce(()=>{var ve;return!!((ve=t().engine.s1_mini)!=null&&ve.enabled)});qt(async()=>{var ve;b(),m();try{const Me=await E("accelerator_support");o(v,(ve=Me.s1_mini_gpu)!=null?ve:null,!0)}catch(Me){console.error("Failed to query GPU support",Me)}});let q=ce(()=>t().features.custom_vocabulary?t().features.custom_vocabulary.join(", "):"");function T(ve){const Me=ve.target;t(t().features.custom_vocabulary=Me.value.split(",").map(Fe=>Fe.trim()).filter(Fe=>Fe.length>0),!0),r()}var D=Nf(),se=i(n(D),2),ne=n(se),fe=i(n(ne),2);{var Q=ve=>{var Me=Mf(),Fe=n(Me);w(he=>y(Fe,`✔ Ready ${he!=null?he:""}`),[()=>e(v)?`(${h(e(v))})`:"(CPU)"]),d(ve,Me)},z=ve=>{var Me=Pf();d(ve,Me)},I=ve=>{var Me=Af();d(ve,Me)};k(fe,ve=>{e(l)?ve(Q):e(u)?ve(z,1):e(M)&&ve(I,2)})}var L=i(ne,2),ge=i(n(L),2),ee=i(L,4);{var K=ve=>{var Me=Lf(),Fe=ht(Me),he=n(Fe);{var re=te=>{var G=Df();d(te,G)},we=te=>{var G=zf();d(te,G)},Je=te=>{var G=If(),_e=n(G);w(me=>y(_e,`✔ Model downloaded and ready ${me!=null?me:""}`),[()=>e(v)?`(${h(e(v))} GPU accelerated)`:"on CPU"]),d(te,G)},de=te=>{var G=Of(),_e=i(n(G),2);N("click",_e,_),d(te,G)};k(he,te=>{e(c)?te(re):e(u)?te(we,1):e(l)?te(Je,2):te(de,-1)})}var Y=i(Fe,2),U=i(n(Y),2);sa(U,{options:[{value:"semi-formal",label:"Semi-formal (Default)"},{value:"casual",label:"Casual"},{value:"formal",label:"Formal"},{value:"verbatim",label:"Verbatim"},{value:"concise",label:"Concise"}],onchange:r,get value(){return t().engine.s1_mini.styling},set value(te){t(t().engine.s1_mini.styling=te,!0)}}),d(ve,Me)};k(ee,ve=>{e(M)&&ve(K)})}var V=i(se,2);let oe;var R=i(n(V),2);{var B=ve=>{var Me=Rf();d(ve,Me)};k(R,ve=>{e(M)&&ve(B)})}var be=i(R,2),Ae=i(n(be),2),ue=i(be,2),j=i(n(ue),2),J=i(ue,2),Se=i(n(J),2),De=i(V,2),le=i(n(De),2),W=i(n(le),2),ae=i(De,2),O=i(n(ae),4);Fs(O,ve=>ua==null?void 0:ua(ve));var X=i(ae,2);Ko(X,{onchange:r,title:"Snippets",hint:"Type a trigger word → it expands to the replacement text.",addLabel:"Add Snippet",keyPlaceholder:"Trigger word",valuePlaceholder:"Expansion text",emptyText:"No snippets defined.",get value(){return t().features.snippets},set value(ve){t(t().features.snippets=ve,!0)}}),w(()=>{oe=Te(V,1,"field-group svelte-1s1a8xn",null,oe,{"disabled-section":e(M)}),Ae.disabled=e(M),j.disabled=e(M),Se.disabled=e(M),sr(O,e(q))}),N("change",ge,x),Xt(ge,()=>t().engine.s1_mini.enabled,ve=>t(t().engine.s1_mini.enabled=ve,!0)),N("change",Ae,r),Xt(Ae,()=>t().features.remove_fillers,ve=>t(t().features.remove_fillers=ve,!0)),N("change",j,r),Xt(j,()=>t().features.spoken_punctuation,ve=>t(t().features.spoken_punctuation=ve,!0)),N("change",Se,r),Xt(Se,()=>t().features.auto_format_lists,ve=>t(t().features.auto_format_lists=ve,!0)),N("change",W,r),Xt(W,()=>t().features.early_command_detection,ve=>t(t().features.early_command_detection=ve,!0)),N("input",O,T),d(s,D),St()}Qt(["change","click","input"]);async function Uo(s,a){await E("plugin:shell|open",{path:s,with:a})}async function Ff(s={}){return typeof s=="object"&&Object.freeze(s),await E("plugin:dialog|save",{options:s})}var Bf=p(""),qf=p(""),Kf=p('
'),Uf=p('
'),jf=p(''),Hf=p('
Building the report…
'),Wf=p('
'),Yf=p('
Title: · Report ID
',1),$f=p('
Fill in the summary and description above and the finished report appears here.
'),Gf=p(''),Jf=p(''),Xf=p(''),Zf=p(''),Qf=p('
'),e_=p('
'),t_=p("Send report files it for you — no GitHub account needed.",1),a_=p("This build has no automatic submission set up, so the routes below are the ones to use. Submit bug report opens the pre-filled issue form on GitHub and copies the report to your clipboard so you can submit directly.",1),s_=p('
Saved to
'),n_=p(''),i_=p("
"),r_=p(`
Report a Bug
VoxCtrl 0.5.0 added a Windows build, and a Windows GPU build is on its way. Neither has been
through anyone's hands but the developer's yet, so if something is broken, this page is the
fastest way to say so — and it is the only part of VoxCtrl that ever sends anything about
your machine anywhere.
What gets sent
✓ Included
What you write below. This is the only text of yours that travels.
Version and build — which VoxCtrl, installed how, with which GPU features compiled in.
Operating system, kernel or Windows build, and CPU architecture.
Hardware — CPU model, core count, total memory, display adapter name.
Desktop and session (Linux), and your language, e.g. en.
Settings, with everything below stripped out first.
Output targets and hotkeys — how many, of which kinds, which keys. Not their names or contents.
The tail of VoxCtrl's log, up to 400 lines.
✕ Never included
Anything you have dictated. The log is written so transcribed text cannot reach it in the first place.
API keys and access tokens. Reported only as set or not set.
Your name, username, hostname, email or IP address.
File paths. A folder setting is reported as "default" or "custom", never as a path.
Custom vocabulary, snippets and prompts. Counted, never quoted.
Target names, shell commands, URLs and webhook secrets.
Audio. No recording, no sample, ever.
Nothing here happens on its own. There is no telemetry, no background reporting, and nothing
@@ -89,16 +89,16 @@ You cannot assign the same Output Command multiple times to a single keybind.`);
press Submit there. Save, Copy and Email put the report in your
hands to send however you like — attach the saved file to an email to .
Limits and the ID that enforces them
Report ID — a random value made on
this machine, used only to count reports. It is derived from nothing about you or your
- computer, and resetting it starts a fresh count.
`);function l_(s,a){Tt(a,!0);const t=["Recording / hotkeys","Transcription accuracy or speed","Audio input or devices","Text-to-speech","Output targets / routing","Settings window or overlay","Installing or updating","Crash or freeze","Something else"],r=[{value:"always",label:"Every time"},{value:"sometimes",label:"Sometimes"},{value:"once",label:"It happened once"}];let l=yt({summary:"",description:"",area:t[0],frequency:"always"}),c=S(null),u=S(null),v=S(!1),f=S(null),h=S(!1),b=S(!1),m=S(null),_=S(null),x=S(null),A=S(!1),q=S(!1);const T=ce(()=>l.description.trim().length),D=ce(()=>{var G,g;return(g=(G=e(c))==null?void 0:G.limits.min_description_chars)!=null?g:30}),se=ce(()=>{var G,g;return(g=(G=e(c))==null?void 0:G.limits.max_description_chars)!=null?g:4e3}),ne=ce(()=>l.summary.trim().length>0&&e(T)>=e(D)&&e(T)<=e(se));async function fe(){try{o(c,await E("bug_report_context"),!0)}catch(G){console.error("Failed to read bug report context:",G)}}qt(fe);let Q;pa(()=>{const G={...l};if(!e(ne)){o(u,null);return}return Q&&clearTimeout(Q),Q=setTimeout(()=>z(G),400),()=>{Q&&clearTimeout(Q)}});async function z(G){o(v,!0),o(f,null);try{o(u,await E("preview_bug_report",{statement:G}),!0)}catch(g){o(f,String(g),!0),o(u,null)}finally{o(v,!1)}}async function I(){return e(u)||await z({...l}),e(u)}async function L(){var g,P,Me,Ue,ie,xe,Ce,He;if(!l.summary.trim()){o(_,{type:"error",message:"Please provide a one-line summary above before submitting."},!0);return}if(e(T)o(A,!1),2500)}catch(P){o(_,{type:"error",message:`Could not copy the report: ${P}`},!0)}}async function V(){var P,Me;if(!l.summary.trim()||e(T)o(q,!1),3e3),e(c)&&o(c,{...e(c),install_id:G,submissions_last_day:0,submissions_last_month:0},!0)}catch(G){o(f,`Could not reset the report ID: ${G}`)}}var be=r_(),Pe=i(n(be),4),ue=i(n(Pe),4),K=i(n(ue)),J=n(K),Se=i(Pe,2),De=i(n(Se),2),le=i(n(De),2),W=i(De,2),ae=n(W),O=i(n(ae),2);pt(O,21,()=>t,ft,(G,g)=>{var P=Bf(),Me=n(P),Ue={};w(()=>{var ie;y(Me,e(g)),Ue!==(Ue=e(g))&&(P.value=(ie=P.__value=e(g))!=null?ie:"")}),d(G,P)});var X=i(ae,2),ve=i(n(X),2);pt(ve,21,()=>r,ft,(G,g)=>{var P=qf(),Me=n(P),Ue={};w(()=>{var ie;y(Me,e(g).label),Ue!==(Ue=e(g).value)&&(P.value=(ie=P.__value=e(g).value)!=null?ie:"")}),d(G,P)});var Ae=i(W,2),Fe=i(n(Ae),2);mt(Fe,"placeholder",`1. I pressed my dictation hotkey and spoke for ten seconds.
+ computer, and resetting it starts a fresh count. `);function l_(s,a){Tt(a,!0);const t=["Recording / hotkeys","Transcription accuracy or speed","Audio input or devices","Text-to-speech","Output targets / routing","Settings window or overlay","Installing or updating","Crash or freeze","Something else"],r=[{value:"always",label:"Every time"},{value:"sometimes",label:"Sometimes"},{value:"once",label:"It happened once"}];let l=yt({summary:"",description:"",area:t[0],frequency:"always"}),c=S(null),u=S(null),v=S(!1),f=S(null),h=S(!1),b=S(!1),m=S(null),_=S(null),x=S(null),M=S(!1),q=S(!1);const T=ce(()=>l.description.trim().length),D=ce(()=>{var $,g;return(g=($=e(c))==null?void 0:$.limits.min_description_chars)!=null?g:30}),se=ce(()=>{var $,g;return(g=($=e(c))==null?void 0:$.limits.max_description_chars)!=null?g:4e3}),ne=ce(()=>l.summary.trim().length>0&&e(T)>=e(D)&&e(T)<=e(se));async function fe(){try{o(c,await E("bug_report_context"),!0)}catch($){console.error("Failed to read bug report context:",$)}}qt(fe);let Q;pa(()=>{const $={...l};if(!e(ne)){o(u,null);return}return Q&&clearTimeout(Q),Q=setTimeout(()=>z($),400),()=>{Q&&clearTimeout(Q)}});async function z($){o(v,!0),o(f,null);try{o(u,await E("preview_bug_report",{statement:$}),!0)}catch(g){o(f,String(g),!0),o(u,null)}finally{o(v,!1)}}async function I(){return e(u)||await z({...l}),e(u)}async function L(){var g,A,Pe,Ue,ie,xe,Ce,He;if(!l.summary.trim()){o(_,{type:"error",message:"Please provide a one-line summary above before submitting."},!0);return}if(e(T)o(M,!1),2500)}catch(A){o(_,{type:"error",message:`Could not copy the report: ${A}`},!0)}}async function V(){var A,Pe;if(!l.summary.trim()||e(T)o(q,!1),3e3),e(c)&&o(c,{...e(c),install_id:$,submissions_last_day:0,submissions_last_month:0},!0)}catch($){o(f,`Could not reset the report ID: ${$}`)}}var be=r_(),Ae=i(n(be),4),ue=i(n(Ae),4),j=i(n(ue)),J=n(j),Se=i(Ae,2),De=i(n(Se),2),le=i(n(De),2),W=i(De,2),ae=n(W),O=i(n(ae),2);pt(O,21,()=>t,ft,($,g)=>{var A=Bf(),Pe=n(A),Ue={};w(()=>{var ie;y(Pe,e(g)),Ue!==(Ue=e(g))&&(A.value=(ie=A.__value=e(g))!=null?ie:"")}),d($,A)});var X=i(ae,2),ve=i(n(X),2);pt(ve,21,()=>r,ft,($,g)=>{var A=qf(),Pe=n(A),Ue={};w(()=>{var ie;y(Pe,e(g).label),Ue!==(Ue=e(g).value)&&(A.value=(ie=A.__value=e(g).value)!=null?ie:"")}),d($,A)});var Me=i(W,2),Fe=i(n(Me),2);mt(Fe,"placeholder",`1. I pressed my dictation hotkey and spoke for ten seconds.
2. The overlay appeared but no text arrived.
-3. I expected the text to be typed into my editor.`);var he=i(Fe,2);let re;var we=n(he),Je=i(we);{var de=G=>{var g=Be();w(()=>{var P;return y(g,`— at least ${(P=e(D))!=null?P:""} please; steps to reproduce are worth more than anything else here`)}),d(G,g)};k(Je,G=>{e(T){var g=jf(),P=n(g);w(()=>y(P,e(f))),d(G,g)};k($,G=>{e(f)&&G(U)})}var te=i($,2);{var Y=G=>{var g=Uf(),P=n(g);w(()=>y(P,e(u).blocked_reason)),d(G,g)};k(te,G=>{var g;(g=e(u))!=null&&g.blocked_reason&&G(Y)})}var _e=i(te,2),me=n(_e),pe=i(n(me),2);{var ze=G=>{var g=Kf(),P=n(g);w(()=>y(P,e(h)?"Hide":"Show me exactly what will be sent")),N("click",g,()=>o(h,!e(h))),d(G,g)};k(pe,G=>{e(u)&&G(ze)})}var $e=i(me,2);{var st=G=>{var g=Hf();d(G,g)},it=G=>{var g=$f(),P=ht(g),Me=i(n(P)),Ue=n(Me),ie=i(Me,2),xe=n(ie),Ce=i(P,2);{var He=Xe=>{var Dt=Wf(),zt=n(Dt);w(()=>y(zt,e(u).markdown)),d(Xe,Dt)};k(Ce,Xe=>{e(h)&&Xe(He)})}w(Xe=>{y(Ue,e(u).title),y(xe,Xe)},[()=>e(u).fingerprint.slice(0,12)]),d(G,g)},H=G=>{var g=Gf();d(G,g)};k($e,G=>{e(v)&&!e(u)?G(st):e(u)?G(it,1):G(H,-1)})}var M=i($e,2),C=n(M);{var ke=G=>{var g=Yf(),P=n(g);w(()=>{g.disabled=e(b)||e(u)&&!e(u).can_submit,y(P,e(b)?"Sending…":"Send report")}),N("click",g,L),d(G,g)},Ke=G=>{var g=Jf(),P=n(g);w(()=>{g.disabled=e(b),y(P,e(b)?"Submitting…":"Submit bug report")}),N("click",g,L),d(G,g)};k(C,G=>{var g;(g=e(c))!=null&&g.relay_configured?G(ke):G(Ke,-1)})}var ye=i(C,2),Ie=i(ye,2),Ye=i(Ie,2),Ze=n(Ye),Ve=i(Ye,2),at=i(M,2);{var et=G=>{var g=e_(),P=n(g),Me=n(P),Ue=n(Me),ie=i(Me,2);{var xe=Ce=>{var He=Qf(),Xe=n(He);{var Dt=Wt=>{var $t=Xf();N("click",$t,()=>oe(e(_).path)),d(Wt,$t)};k(Xe,Wt=>{e(_).path&&Wt(Dt)})}var zt=i(Xe,2);{var Ft=Wt=>{var $t=Zf();N("click",$t,()=>R(e(_).url)),d(Wt,$t)};k(zt,Wt=>{e(_).url&&Wt(Ft)})}d(Ce,He)};k(ie,Ce=>{(e(_).path||e(_).url)&&Ce(xe)})}w(()=>{Te(g,1,Ia(e(_).type==="ok"?"ok-alert":"warning-alert"),"svelte-7vrdzs"),y(Ue,e(_).message)}),d(G,g)};k(at,G=>{e(_)&&G(et)})}var rt=i(at,2),Ee=n(rt);{var Ge=G=>{var g=t_();d(G,g)},ct=G=>{var g=a_();d(G,g)};k(Ee,G=>{var g;(g=e(c))!=null&&g.relay_configured?G(Ge):G(ct,-1)})}var vt=i(Ee,10),nt=n(vt),wt=i(rt,2);{var dt=G=>{var g=s_(),P=i(n(g)),Me=n(P);w(()=>y(Me,e(x))),d(G,g)};k(wt,G=>{e(x)&&!e(_)&&G(dt)})}var Et=i(wt,2);{var Kt=G=>{var g=i_();let P;var Me=n(g),Ue=i(Me);{var ie=xe=>{var Ce=n_();N("click",Ce,()=>R(e(m).issue_url)),d(xe,Ce)};k(Ue,xe=>{e(m).issue_url&&xe(ie)})}w(()=>{var xe;P=Te(g,1,"svelte-7vrdzs",null,P,{"ok-alert":e(m).ok,"warning-alert":!e(m).ok}),y(Me,`${(xe=e(m).message)!=null?xe:""} `)}),d(G,g)};k(Et,G=>{e(m)&&G(Kt)})}var ia=i(_e,2),ra=i(n(ia),2),bt=n(ra),ea=i(ra,2),Lt=n(ea),Ht=i(n(Lt)),ta=n(Ht),Oe=i(Lt,2),qe=n(Oe);w((G,g)=>{var P,Me,Ue,ie,xe,Ce,He,Xe,Dt,zt,Ft,Wt,$t,fa,Yt,ma,Oa,Ya;y(J,(Me=(P=e(c))==null?void 0:P.log_path)!=null?Me:"…"),mt(Fe,"maxlength",e(se)),re=Te(he,1,"counter svelte-7vrdzs",null,re,{short:e(T)>0&&e(T){var g=Be();w(()=>{var A;return y(g,`— at least ${(A=e(D))!=null?A:""} please; steps to reproduce are worth more than anything else here`)}),d($,g)};k(Je,$=>{e(T){var g=Kf(),A=n(g);w(()=>y(A,e(f))),d($,g)};k(Y,$=>{e(f)&&$(U)})}var te=i(Y,2);{var G=$=>{var g=Uf(),A=n(g);w(()=>y(A,e(u).blocked_reason)),d($,g)};k(te,$=>{var g;(g=e(u))!=null&&g.blocked_reason&&$(G)})}var _e=i(te,2),me=n(_e),pe=i(n(me),2);{var ze=$=>{var g=jf(),A=n(g);w(()=>y(A,e(h)?"Hide":"Show me exactly what will be sent")),N("click",g,()=>o(h,!e(h))),d($,g)};k(pe,$=>{e(u)&&$(ze)})}var Ye=i(me,2);{var st=$=>{var g=Hf();d($,g)},it=$=>{var g=Yf(),A=ht(g),Pe=i(n(A)),Ue=n(Pe),ie=i(Pe,2),xe=n(ie),Ce=i(A,2);{var He=Xe=>{var Dt=Wf(),zt=n(Dt);w(()=>y(zt,e(u).markdown)),d(Xe,Dt)};k(Ce,Xe=>{e(h)&&Xe(He)})}w(Xe=>{y(Ue,e(u).title),y(xe,Xe)},[()=>e(u).fingerprint.slice(0,12)]),d($,g)},H=$=>{var g=$f();d($,g)};k(Ye,$=>{e(v)&&!e(u)?$(st):e(u)?$(it,1):$(H,-1)})}var P=i(Ye,2),C=n(P);{var ke=$=>{var g=Gf(),A=n(g);w(()=>{g.disabled=e(b)||e(u)&&!e(u).can_submit,y(A,e(b)?"Sending…":"Send report")}),N("click",g,L),d($,g)},je=$=>{var g=Jf(),A=n(g);w(()=>{g.disabled=e(b),y(A,e(b)?"Submitting…":"Submit bug report")}),N("click",g,L),d($,g)};k(C,$=>{var g;(g=e(c))!=null&&g.relay_configured?$(ke):$(je,-1)})}var ye=i(C,2),Ie=i(ye,2),Ge=i(Ie,2),Ze=n(Ge),Ve=i(Ge,2),at=i(P,2);{var et=$=>{var g=e_(),A=n(g),Pe=n(A),Ue=n(Pe),ie=i(Pe,2);{var xe=Ce=>{var He=Qf(),Xe=n(He);{var Dt=Wt=>{var Yt=Xf();N("click",Yt,()=>oe(e(_).path)),d(Wt,Yt)};k(Xe,Wt=>{e(_).path&&Wt(Dt)})}var zt=i(Xe,2);{var Ft=Wt=>{var Yt=Zf();N("click",Yt,()=>R(e(_).url)),d(Wt,Yt)};k(zt,Wt=>{e(_).url&&Wt(Ft)})}d(Ce,He)};k(ie,Ce=>{(e(_).path||e(_).url)&&Ce(xe)})}w(()=>{Te(g,1,Ia(e(_).type==="ok"?"ok-alert":"warning-alert"),"svelte-7vrdzs"),y(Ue,e(_).message)}),d($,g)};k(at,$=>{e(_)&&$(et)})}var rt=i(at,2),Ee=n(rt);{var $e=$=>{var g=t_();d($,g)},ct=$=>{var g=a_();d($,g)};k(Ee,$=>{var g;(g=e(c))!=null&&g.relay_configured?$($e):$(ct,-1)})}var vt=i(Ee,10),nt=n(vt),wt=i(rt,2);{var dt=$=>{var g=s_(),A=i(n(g)),Pe=n(A);w(()=>y(Pe,e(x))),d($,g)};k(wt,$=>{e(x)&&!e(_)&&$(dt)})}var Et=i(wt,2);{var jt=$=>{var g=i_();let A;var Pe=n(g),Ue=i(Pe);{var ie=xe=>{var Ce=n_();N("click",Ce,()=>R(e(m).issue_url)),d(xe,Ce)};k(Ue,xe=>{e(m).issue_url&&xe(ie)})}w(()=>{var xe;A=Te(g,1,"svelte-7vrdzs",null,A,{"ok-alert":e(m).ok,"warning-alert":!e(m).ok}),y(Pe,`${(xe=e(m).message)!=null?xe:""} `)}),d($,g)};k(Et,$=>{e(m)&&$(jt)})}var ia=i(_e,2),ra=i(n(ia),2),bt=n(ra),ea=i(ra,2),Lt=n(ea),Ht=i(n(Lt)),ta=n(Ht),Oe=i(Lt,2),qe=n(Oe);w(($,g)=>{var A,Pe,Ue,ie,xe,Ce,He,Xe,Dt,zt,Ft,Wt,Yt,fa,Gt,ma,Oa,Ga;y(J,(Pe=(A=e(c))==null?void 0:A.log_path)!=null?Pe:"…"),mt(Fe,"maxlength",e(se)),re=Te(he,1,"counter svelte-7vrdzs",null,re,{short:e(T)>0&&e(T){var G,g;return Math.round(((g=(G=e(c))==null?void 0:G.limits.cooldown_seconds)!=null?g:120)/60)},()=>{var G,g,P;return(P=(g=(G=e(c))==null?void 0:G.install_id)==null?void 0:g.slice(0,12))!=null?P:"…"}]),We(le,()=>l.summary,G=>l.summary=G),Tl(O,()=>l.area,G=>l.area=G),Tl(ve,()=>l.frequency,G=>l.frequency=G),We(Fe,()=>l.description,G=>l.description=G),N("click",ye,ge),N("click",Ie,ee),N("click",Ye,j),N("click",Ve,V),N("click",Oe,B),d(s,be),St()}Qt(["click"]);class Xn extends jd{constructor(a){super(a)}static async new(a,t,r){return E("plugin:image|new",{rgba:Hi(a),width:t,height:r}).then(l=>new Xn(l))}static async fromBytes(a){return E("plugin:image|from_bytes",{bytes:Hi(a)}).then(t=>new Xn(t))}static async fromPath(a){return E("plugin:image|from_path",{path:a}).then(t=>new Xn(t))}async rgba(){return E("plugin:image|rgba",{rid:this.rid}).then(a=>new Uint8Array(a))}async size(){return E("plugin:image|size",{rid:this.rid})}}function Hi(s){return s==null?null:typeof s=="string"?s:s instanceof Xn?s.rid:s}var Pl;(function(s){s.Nsis="nsis",s.Msi="msi",s.Deb="deb",s.Rpm="rpm",s.AppImage="appimage",s.App="app"})(Pl||(Pl={}));async function o_(){return E("plugin:app|version")}const c_="/assets/voxctrl-CDHFw5hI.gif";var d_=p('
Custom overlays
'),v_=p('
Cloned TTS voices
'),u_=p(`
About VoxCtrl
VoxCtrl
Native, on-device voice-to-text for Linux and Windows.
+ ${(Gt=(fa=(Yt=e(c))==null?void 0:Yt.submissions_last_day)!=null?fa:0)!=null?Gt:""} in the last day and
+ ${(Ga=(Oa=(ma=e(c))==null?void 0:ma.submissions_last_month)!=null?Oa:0)!=null?Ga:""} in the last month. Saving to a file is never limited.`),y(ta,g),y(qe,e(q)?"Reset ✓":"Reset ID")},[()=>{var $,g;return Math.round(((g=($=e(c))==null?void 0:$.limits.cooldown_seconds)!=null?g:120)/60)},()=>{var $,g,A;return(A=(g=($=e(c))==null?void 0:$.install_id)==null?void 0:g.slice(0,12))!=null?A:"…"}]),We(le,()=>l.summary,$=>l.summary=$),Tl(O,()=>l.area,$=>l.area=$),Tl(ve,()=>l.frequency,$=>l.frequency=$),We(Fe,()=>l.description,$=>l.description=$),N("click",ye,ge),N("click",Ie,ee),N("click",Ge,K),N("click",Ve,V),N("click",Oe,B),d(s,be),St()}Qt(["click"]);class Xn extends Kd{constructor(a){super(a)}static async new(a,t,r){return E("plugin:image|new",{rgba:Hi(a),width:t,height:r}).then(l=>new Xn(l))}static async fromBytes(a){return E("plugin:image|from_bytes",{bytes:Hi(a)}).then(t=>new Xn(t))}static async fromPath(a){return E("plugin:image|from_path",{path:a}).then(t=>new Xn(t))}async rgba(){return E("plugin:image|rgba",{rid:this.rid}).then(a=>new Uint8Array(a))}async size(){return E("plugin:image|size",{rid:this.rid})}}function Hi(s){return s==null?null:typeof s=="string"?s:s instanceof Xn?s.rid:s}var Al;(function(s){s.Nsis="nsis",s.Msi="msi",s.Deb="deb",s.Rpm="rpm",s.AppImage="appimage",s.App="app"})(Al||(Al={}));async function o_(){return E("plugin:app|version")}const c_="/assets/voxctrl-CDHFw5hI.gif";var d_=p('
Custom overlays
'),v_=p('
Cloned TTS voices
'),u_=p(`
About VoxCtrl
VoxCtrl
Native, on-device voice-to-text for Linux and Windows.
Uses whisper.cpp, Moonshine,
- and NVIDIA Parakeet for offline transcription and routes speech to any destination.
System
FrontendSvelte 5 + Tauri 2
BackendRust (Tokio async)
Inferencewhisper.cpp, Moonshine & Parakeet TDT
Config~/.config/voxctrl/
Models~/.local/share/voxctrl/models/
MCP socket/tmp/voxctrl-mcp.sock
Open Source Attributions
This application is built possible by these outstanding open-source projects:
You may be prompted for your administrator password.
'),ih=p('
Checking VoxCtrl setup…
'),rh=p('
'),lh=p('
',1),oh=p(`
🔒 VoxCtrl asked your desktop to register its shortcuts and is told nothing
+ and NVIDIA Parakeet for offline transcription and routes speech to any destination.
System
FrontendSvelte 5 + Tauri 2
BackendRust (Tokio async)
Inferencewhisper.cpp, Moonshine & Parakeet TDT
Config~/.config/voxctrl/
Models~/.local/share/voxctrl/models/
MCP socket/tmp/voxctrl-mcp.sock
Open Source Attributions
This application is built possible by these outstanding open-source projects:
You may be prompted for your administrator password.
'),ih=p('
Checking VoxCtrl setup…
'),rh=p('
'),lh=p('
',1),oh=p(`
🔒 VoxCtrl asked your desktop to register its shortcuts and is told nothing
else. It does not read your keyboard, cannot see what you type in other
applications, and needed no special permissions to set up.
`),ch=p(''),dh=p('not accepted by your desktop'),vh=p(""),uh=p('
'),ph=p(`
Your desktop does not offer the global-shortcuts portal, so VoxCtrl is
reading key events from the X server instead. This needed no permissions
@@ -116,41 +116,41 @@ You cannot assign the same Output Command multiple times to a single keybind.`);
anywhere; if you would rather it did not happen at all, a desktop with
portal support (KDE Plasma, GNOME 48+, Hyprland) avoids it entirely.
`),hh=p('
'),gh=p(`
Global shortcuts require approval from your system. If you closed or cancelled
the desktop keybind prompt without approving, click below to show the prompt again.
`,1),mh=p('
'),bh=p('
Global shortcuts require approval or registration from your system. VoxCtrl will not grant itself keyboard access to work around this.
',1),yh=p(''),wh=p(''),kh=p(` is missing, so transcriptions cannot be
- typed into the focused window.`,1),xh=p(''),Th=p(''),Sh=p('
'),Eh=p('
',1),Ch=p(' is downloaded and ready.',1),Ah=p('Downloading in the background — no action needed.',1),Mh=p(' is not downloaded yet, so dictation produces no text.',1),Ph=p('
'),Dh=p('
❌
'),zh=p('
Global shortcuts
Typing text into other windows
Speech model
'),Ih=p('');function Oh(s,a){Tt(a,!0);let t=S(null),r=S(!1),l=S(!1),c=S(null),u=S(!1),v=S(!1),f=S(!1),h=S(null),b=S(!1),m=S(null),_;async function x(){try{o(t,await E("get_setup_status"),!0)}catch(R){console.error("Failed to read setup status:",R)}}qt(()=>{x(),_=setInterval(x,2e3)}),ar(()=>{_&&clearInterval(_)});async function A(){try{await ol().close()}catch(R){console.error("Failed to close window natively:",R)}}async function q(){var R;o(r,!0),o(c,null);try{await E("install_system_integration"),await x()}catch(B){o(c,(R=B==null?void 0:B.toString())!=null?R:"Install failed",!0),o(u,!0)}finally{o(r,!1)}}async function T(){var R;o(l,!0),o(c,null);try{await E("download_configured_model"),await x()}catch(B){o(c,(R=B==null?void 0:B.toString())!=null?R:"Download failed",!0)}finally{o(l,!1)}}async function D(){try{await E("open_settings_tab",{tab:"engine"})}catch(R){console.error("Failed to open the Engine settings tab:",R)}}async function se(){var R;o(f,!0),o(h,null);try{await E("open_shortcut_settings")}catch(B){o(h,(R=B==null?void 0:B.toString())!=null?R:"Could not open shortcut settings.",!0)}finally{o(f,!1)}}async function ne(){var R;o(b,!0),o(m,null);try{await E("approve_shortcuts"),await x()}catch(B){o(m,(R=B==null?void 0:B.toString())!=null?R:"Failed to configure shortcuts for your desktop.",!0),await x()}finally{o(b,!1)}}async function fe(){if(e(t))try{await navigator.clipboard.writeText(e(t).manual_package_commands),o(v,!0),setTimeout(()=>o(v,!1),2e3)}catch(R){console.error("Clipboard write failed:",R)}}const Q=ce(()=>e(t)?e(t).hotkeys.backend==="starting"?"busy":e(t).hotkeys_active?"ok":"todo":"busy"),z=ce(()=>e(t)?e(t).missing_injection_tool?"todo":"ok":"busy"),I=ce(()=>e(t)?e(t).model_ready?"ok":e(t).model_auto_downloads?"busy":"todo":"busy"),L=R=>R==="ok"?"✅":R==="busy"?"⏳":"⚠️";var ge=Ih(),ee=n(ge);{var j=R=>{var B=nh();d(R,B)},V=R=>{var B=ih();d(R,B)},oe=R=>{var B=zh(),be=n(B),Pe=n(be),ue=n(Pe),K=i(Pe,2),J=n(K),Se=n(J),De=i(J,2),le=n(De),W=i(be,2),ae=n(W);let O;var X=n(ae),ve=n(X),Ae=i(X,2),Fe=i(n(Ae),2),he=n(Fe),re=i(Fe,2);{var we=Oe=>{var qe=lh(),G=ht(qe),g=n(G),P=i(G,2),Me=n(P),Ue=n(Me),ie=i(P,2);{var xe=Ce=>{var He=rh(),Xe=n(He);w(()=>y(Xe,e(h))),d(Ce,He)};k(ie,Ce=>{e(h)&&Ce(xe)})}w(()=>{var Ce;y(g,`🔧 One more step on KDE: ${(Ce=e(t).hotkeys.manual_enable_hint)!=null?Ce:""}`),Me.disabled=e(f),y(Ue,e(f)?"Opening…":"Open Shortcut Settings")}),N("click",Me,se),d(Oe,qe)};k(re,Oe=>{e(t).hotkeys.needs_manual_enable&&Oe(we)})}var Je=i(re,2);{var de=Oe=>{var qe=oh();d(Oe,qe)};k(Je,Oe=>{(e(t).hotkeys.backend==="portal"||e(t).hotkeys.backend==="mint_dbus")&&Oe(de)})}var $=i(Je,2);{var U=Oe=>{var qe=uh();pt(qe,21,()=>e(t).hotkeys.shortcuts,ft,(G,g)=>{var P=vh();let Me;var Ue=n(P);{var ie=Ce=>{var He=ch(),Xe=n(He);w(()=>y(Xe,e(g).trigger_description||e(g).requested||"chosen in your desktop settings")),d(Ce,He)},xe=Ce=>{var He=dh();d(Ce,He)};k(Ue,Ce=>{e(g).bound?Ce(ie):Ce(xe,-1)})}w(()=>Me=Te(P,1,"svelte-45v8pc",null,Me,{unbound:!e(g).bound})),d(G,P)}),d(Oe,qe)};k($,Oe=>{e(t).hotkeys_active&&e(t).hotkeys.shortcuts.length>0&&Oe(U)})}var te=i($,2);{var Y=Oe=>{var qe=ph();d(Oe,qe)},_e=Oe=>{var qe=fh();d(Oe,qe)},me=Oe=>{var qe=_h();d(Oe,qe)},pe=Oe=>{var qe=gh(),G=i(ht(qe),2),g=n(G),P=n(g),Me=i(G,2);{var Ue=ie=>{var xe=hh(),Ce=n(xe);w(()=>y(Ce,e(m))),d(ie,xe)};k(Me,ie=>{e(m)&&ie(Ue)})}w(()=>{g.disabled=e(b),y(P,e(b)?"Configuring…":"Approve Keybinds")}),N("click",g,ne),d(Oe,qe)},ze=Oe=>{var qe=bh(),G=i(ht(qe),2),g=n(G),P=n(g),Me=i(G,2);{var Ue=ie=>{var xe=mh(),Ce=n(xe);w(()=>y(Ce,e(m))),d(ie,xe)};k(Me,ie=>{e(m)&&ie(Ue)})}w(()=>{g.disabled=e(b),y(P,e(b)?"Configuring…":"Approve Shortcuts")}),N("click",g,ne),d(Oe,qe)};k(te,Oe=>{e(t).hotkeys.backend==="x11"?Oe(Y):e(t).hotkeys.backend==="mint_dbus"?Oe(_e,1):e(t).hotkeys.backend==="evdev"?Oe(me,2):e(t).hotkeys.portal_refused?Oe(pe,3):e(t).hotkeys.backend!=="starting"&&Oe(ze,4)})}var $e=i(te,2);{var st=Oe=>{var qe=yh(),G=n(qe);w(()=>{var g;return y(G,`Portal reported: ${(g=e(t).hotkeys.portal_error)!=null?g:""}`)}),d(Oe,qe)};k($e,Oe=>{e(t).hotkeys.portal_error&&e(t).hotkeys.backend!=="portal"&&e(t).hotkeys.backend!=="evdev"&&Oe(st)})}var it=i($e,2);{var H=Oe=>{var qe=wh(),G=n(qe);w(()=>{var g;return y(G,`X11 shortcuts: ${(g=e(t).hotkeys.x11_error)!=null?g:""}`)}),d(Oe,qe)};k(it,Oe=>{e(t).hotkeys.x11_error&&e(t).hotkeys.backend!=="x11"&&e(t).hotkeys.backend!=="portal"&&Oe(H)})}var M=i(ae,2);let C;var ke=n(M),Ke=n(ke),ye=i(ke,2),Ie=i(n(ye),2),Ye=n(Ie);{var Ze=Oe=>{var qe=kh(),G=ht(qe),g=n(G);w(()=>y(g,e(t).missing_injection_tool)),d(Oe,qe)},Ve=Oe=>{var qe=Be("Ready — transcriptions can be typed straight into the focused window.");d(Oe,qe)};k(Ye,Oe=>{e(t).missing_injection_tool?Oe(Ze):Oe(Ve,-1)})}var at=i(Ie,2);{var et=Oe=>{var qe=Eh(),G=ht(qe),g=n(G);{var P=Ce=>{var He=xh();N("click",He,q),d(Ce,He)};k(g,Ce=>{e(t).pkexec_available&&e(t).manual_package_commands&&Ce(P)})}var Me=i(g,2);{var Ue=Ce=>{var He=Th(),Xe=n(He);w(()=>y(Xe,e(u)?"Hide manual commands":"Install it manually")),N("click",He,()=>o(u,!e(u))),d(Ce,He)};k(Me,Ce=>{e(t).manual_package_commands&&Ce(Ue)})}var ie=i(G,2);{var xe=Ce=>{var He=Sh(),Xe=n(He),Dt=n(Xe),zt=i(Xe,2),Ft=n(zt);w(()=>{y(Dt,e(t).manual_package_commands),y(Ft,e(v)?"Copied":"Copy commands")}),N("click",zt,fe),d(Ce,He)};k(ie,Ce=>{e(u)&&Ce(xe)})}d(Oe,qe)};k(at,Oe=>{e(t).missing_injection_tool&&Oe(et)})}var rt=i(M,2);let Ee;var Ge=n(rt),ct=n(Ge),vt=i(Ge,2),nt=i(n(vt),2),wt=n(nt);{var dt=Oe=>{var qe=Ch(),G=ht(qe),g=n(G);w(()=>y(g,e(t).model_size)),d(Oe,qe)},Et=Oe=>{var qe=Ah(),G=i(ht(qe)),g=n(G);w(()=>y(g,e(t).model_size)),d(Oe,qe)},Kt=Oe=>{var qe=Mh(),G=ht(qe),g=n(G);w(()=>y(g,e(t).model_size)),d(Oe,qe)};k(wt,Oe=>{e(t).model_ready?Oe(dt):e(t).model_auto_downloads?Oe(Et,1):Oe(Kt,-1)})}var ia=i(nt,2);{var ra=Oe=>{var qe=Ph(),G=n(qe),g=n(G),P=i(G,2);w(()=>{G.disabled=e(l),y(g,e(l)?"Downloading…":`Download ${e(t).model_size}`)}),N("click",G,T),N("click",P,D),d(Oe,qe)};k(ia,Oe=>{!e(t).model_ready&&!e(t).model_auto_downloads&&Oe(ra)})}var bt=i(W,2);{var ea=Oe=>{var qe=Dh(),G=i(n(qe),2),g=n(G);w(()=>y(g,e(c))),d(Oe,qe)};k(bt,Oe=>{e(c)&&Oe(ea)})}var Lt=i(bt,2),Ht=n(Lt),ta=n(Ht);w((Oe,qe,G)=>{y(ue,e(t).is_complete?"✅":"🛠️"),y(Se,e(t).is_complete?"VoxCtrl is ready":"Finish setting up VoxCtrl"),y(le,e(t).is_complete?"Press your shortcut anywhere to dictate.":"Dictation is not ready yet — the steps below say why."),O=Te(ae,1,"step svelte-45v8pc",null,O,{done:e(Q)==="ok"}),y(ve,Oe),y(he,e(t).hotkeys.detail),C=Te(M,1,"step svelte-45v8pc",null,C,{done:e(z)==="ok"}),y(Ke,qe),Ee=Te(rt,1,"step svelte-45v8pc",null,Ee,{done:e(I)==="ok"}),y(ct,G),y(ta,e(t).is_complete?"Close":"Continue anyway")},[()=>L(e(Q)),()=>L(e(z)),()=>L(e(I))]),N("click",Ht,A),d(R,B)};k(ee,R=>{e(r)?R(j):e(t)?R(oe,-1):R(V,1)})}d(s,ge),St()}Qt(["click"]);const Lh=[{id:"tiny",mb:75,speed:.96,accuracy:.58},{id:"base",mb:142,speed:.88,accuracy:.68},{id:"small",mb:466,speed:.68,accuracy:.8},{id:"medium",mb:1500,speed:.42,accuracy:.9},{id:"large-v3",mb:3100,speed:.22,accuracy:.97}],Rh=[{id:"tiny",mb:100,speed:.98,accuracy:.64},{id:"base",mb:250,speed:.92,accuracy:.77}],Nh=[{id:"tdt-0.6b-v3",mb:665,speed:.95,accuracy:.94}],Vh=[{id:"remote",mb:0,speed:.95,accuracy:.95}],Ai=[{id:"whisper-cpp",name:"whisper.cpp",glyph:"∇",tagline:"Reference-grade accuracy in quiet spaces. Five model sizes from 75 MB to 3.1 GB. CUDA, Vulkan or CPU.",models:Lh,gpu:!0,noiseRetention:.64},{id:"moonshine",name:"Moonshine",glyph:"↯",tagline:"Streaming ONNX model tuned for real rooms — fans, keyboards, traffic. Fast on any CPU, tiny download.",models:Rh,gpu:!1,noiseRetention:.93},{id:"parakeet",name:"Parakeet TDT",glyph:"⚡",tagline:"NVIDIA FastConformer TDT 0.6B. Ultra-fast non-autoregressive transcription, SOTA accuracy, no repetition loops.",models:Nh,gpu:!0,noiseRetention:.88},{id:"remote-openai",name:"Remote Speech Engine",glyph:"🌐",tagline:"Connect to an OpenAI-compatible speech-to-text server on your network or cloud (Faster-Whisper, vLLM, etc.).",models:Vh,gpu:!1,noiseRetention:.92}],xn=[{id:"toggle",name:"Tap to talk",verb:"tap",desc:"Press once to start, press again to stop. Hands stay free while you speak.",key:[[1,1],[8,0],[1,1],[3,0]],mic:[[1,0],[9,1],[4,0]]},{id:"double_tap",name:"Double-tap to talk",verb:"double-tap",desc:"Two quick presses start dictation; one press stops. Hard to trigger by accident.",key:[[1,1],[.7,0],[1,1],[7,0],[1,1],[3,0]],mic:[[2.7,0],[7.3,1],[4,0]]},{id:"hold",name:"Hold to talk",verb:"hold",desc:"Hold the keys down while speaking, release to stop. Like a walkie-talkie.",key:[[1,0],[9,1],[4,0]],mic:[[1,0],[9,1],[4,0]]},{id:"double_tap_hold",name:"Double-tap & hold",verb:"double-tap and hold",desc:"Tap once, then press and hold. Release to stop. Never collides with a plain shortcut.",key:[[1,1],[.7,0],[8.3,1],[4,0]],mic:[[2.7,0],[6.3,1],[4,0]]}],mn=[{id:"blue_wave",name:"Ocean Wave",meta:"default · tide-pool waves",glyph:"⊟"},{id:"voice_card",name:"Voice Card",meta:"20×6 LED VU matrix",glyph:"⊟"},{id:"waveform",name:"Waveform",meta:"scrolling oscilloscope",glyph:"⌇"},{id:"pulse",name:"Pulse Ring",meta:"sonar sweep · target lock",glyph:"◌"},{id:"mono_bars",name:"Mono Bars",meta:"black & white 5-bar meter",glyph:"▥"},{id:"spectrum",name:"Neon Spectrum",meta:"16-band equalizer",glyph:"▦"},{id:"terminal",name:"Retro Terminal",meta:"DOS-blue ASCII meter",glyph:"▸"},{id:"vinyl",name:"Analog VU",meta:"vintage needle meter",glyph:"◔"}],Fh=[{id:"top",label:"Top",glyph:"⤒"},{id:"center",label:"Center",glyph:"⊡"},{id:"bottom",label:"Bottom",glyph:"⤓"}],cs=[{id:"vox_cpm_2",name:"VoxCPM2",kind:"neural · 2B autoregressive",quality:.98,speed:.25,mb:2950,note:"2B autoregressive diffusion. SOTA voice realism & cloning. Runs via audio.cpp, best on a Vulkan GPU."},{id:"breeze_tts_2",name:"Breeze-TTS-2",kind:"neural · expressive",quality:.96,speed:.32,mb:5080,note:"Most natural prosody. Runs via audio.cpp, best on a Vulkan GPU or fast CPU.",nonCommercial:!0,licenceUrl:"huggingface.co/BreezeBlue/Breeze-TTS-2"},{id:"pocket_tts",name:"Pocket TTS",kind:"neural · voice cloning",quality:.86,speed:.55,mb:130,note:"Cloned voices, downloaded in-app. Runs via audio.cpp with optional Vulkan acceleration."},{id:"piper",name:"Piper TTS",kind:"onnx · ~11 voices",quality:.72,speed:.8,mb:60,note:"The sweet spot for most machines. Per-voice ~60 MB."},{id:"inflect_micro",name:"Inflect Micro",kind:"compact neural",quality:.55,speed:.92,mb:38,note:"Tiny footprint, still human-ish. Good for laptops."},{id:"espeak",name:"eSpeak-NG",kind:"formant synth",quality:.3,speed:.99,mb:0,note:"Instant, robotic, runs anywhere. Zero download."}],ds=["Welcome","Engine","Hotkey","Overlay","Test","Voice","Done"];function Tn(s){return s<=0?"none":s>=1e3?`${(s/1e3).toFixed(1)} GB`:`${Math.round(s)} MB`}function Bh(s,a=cs){const t=Math.max(0,...a.map(r=>r.mb));return t<=0||s<=0?0:Math.min(100,s/t*100)}function Fi(s){return`${Math.round(s*100)}%`}function qh(s){return s>.85?"instant":s>.6?"< 1 s":s>.35?"1–3 s":"3–8 s"}function jh(s){return s>.9?"instant":s>.7?"< 0.5 s":s>.5?"~1 s":"2–4 s"}function Mi(s,a){return Array.from({length:s},(t,r)=>{const l=(r+1)/s;return{h:Math.max(8,Math.round(100*a*(.55+.45*Math.sin(r*1.7+a*5)))),o:l<=a?1:.18}})}function Ho(s){return Array.from({length:s},(a,t)=>({d:(.6+t*7%5*.12).toFixed(2),dl:(t*.07).toFixed(2)}))}const Uh={KEY_LEFTCTRL:"Ctrl",KEY_RIGHTCTRL:"Ctrl",KEY_LEFTALT:"Alt",KEY_RIGHTALT:"Alt",KEY_LEFTSHIFT:"Shift",KEY_RIGHTSHIFT:"Shift",KEY_LEFTMETA:"Super",KEY_RIGHTMETA:"Super",KEY_SPACE:"Space",KEY_ESC:"Esc",KEY_ENTER:"Enter",KEY_TAB:"Tab",KEY_BACKSPACE:"Backspace",KEY_DELETE:"Delete",KEY_MINUS:"-",KEY_EQUAL:"=",KEY_LEFTBRACE:"[",KEY_RIGHTBRACE:"]",KEY_BACKSLASH:"\\",KEY_SEMICOLON:";",KEY_APOSTROPHE:"'",KEY_GRAVE:"`",KEY_COMMA:",",KEY_DOT:".",KEY_SLASH:"/",KEY_KPPLUS:"Num +",KEY_KPMINUS:"Num -",KEY_KPASTERISK:"Num *",KEY_KPSLASH:"Num /",KEY_KPDOT:"Num .",KEY_KPENTER:"Num Enter",KEY_KPEQUAL:"Num ="};function dl(s){var t;const a=/^KEY_KP(\d)$/.exec(s);return a?`Num ${a[1]}`:(t=Uh[s])!=null?t:s.replace(/^KEY_/,"")}const yr="default_hold",Wn="command",Kh="Command";function Hh(s){return{...s,id:Wn,label:Kh,delivery:"command",command:null}}var li,oi,ci,di,vi,ui,pi,fi,_i,hi,gi;class Wh{constructor(){lt(this,li,S(0));lt(this,oi,S(0));lt(this,ci,S(!1));lt(this,di,S("hold"));lt(this,vi,S(null));lt(this,ui,S(!1));lt(this,pi,S(yt([])));lt(this,fi,S(null));lt(this,_i,S(yt([])));lt(this,hi,S(!1));lt(this,gi,S(!1))}get step(){return e(F(this,li))}set step(a){o(F(this,li),a,!0)}get visited(){return e(F(this,oi))}set visited(a){o(F(this,oi),a,!0)}get leaving(){return e(F(this,ci))}set leaving(a){o(F(this,ci),a,!0)}get gesture(){return e(F(this,di))}set gesture(a){o(F(this,di),a,!0)}get combo(){return e(F(this,vi))}set combo(a){o(F(this,vi),a,!0)}get recording(){return e(F(this,ui))}set recording(a){o(F(this,ui),a,!0)}get held(){return e(F(this,pi))}set held(a){o(F(this,pi),a,!0)}get captureHint(){return e(F(this,fi))}set captureHint(a){o(F(this,fi),a,!0)}get issues(){return e(F(this,_i))}set issues(a){o(F(this,_i),a,!0)}get engineChosen(){return e(F(this,hi))}set engineChosen(a){o(F(this,hi),a,!0)}get modelChosen(){return e(F(this,gi))}set modelChosen(a){o(F(this,gi),a,!0)}get gestureInfo(){var a;return(a=xn.find(t=>t.id===this.gesture))!=null?a:xn[2]}get displayKeys(){var a;return this.recording?this.held:(a=this.combo)!=null?a:[]}recordIssue(a){this.issues=[...this.issues.filter(t=>t.id!==a.id),a]}clearIssue(a){this.issues=this.issues.filter(t=>t.id!==a)}goTo(a){a===this.step||this.leaving||a<0||a>=ds.length||(this.leaving=!0,this.recording=!1,setTimeout(()=>{this.step=a,this.visited=Math.max(this.visited,a),this.leaving=!1},200))}async ensureCommandTarget(){var l;const a=await E("get_targets");if(a.some(c=>c.id===Wn&&c.delivery==="command"))return Wn;const t=(l=a.find(c=>c.delivery==="inject"))!=null?l:a[0];if(!t)return"default";const r=[...a.filter(c=>c.id!==Wn),Hh(t)];return await E("save_targets",{targets:r}),Wn}async saveBinding(){if(!this.combo||this.combo.length===0)return;const a=await this.ensureCommandTarget(),t=await E("get_bindings").catch(()=>[]),r=this.gestureInfo,l={id:yr,label:`Dictate (${r.name})`,keys:[...this.combo],gesture:this.gesture,target_id:a,target_ids:[a],tap_ms:300,hold_threshold_ms:200,disabled:!1,openai_enabled:!1,openai_model:"",openai_mode:"custom",openai_prompt:"",openai_system_prompt:""},c=t.filter(u=>u.id!==yr&&u.id!=="default_toggle"&&u.id!=="__tts_stop__");await E("save_bindings",{bindings:[l,...c]})}async loadBinding(){var a;try{const t=await E("get_bindings"),r=(a=t.find(l=>l.id===yr))!=null?a:t.find(l=>l.id!=="__tts_stop__");r&&r.keys.length>0&&(this.combo=[...r.keys],xn.some(l=>l.id===r.gesture)&&(this.gesture=r.gesture))}catch(t){console.error("Wizard: failed to read existing bindings:",t)}}reset(){this.step=0,this.visited=0,this.leaving=!1,this.gesture="hold",this.combo=null,this.recording=!1,this.held=[],this.captureHint=null,this.issues=[],this.engineChosen=!1,this.modelChosen=!1}}li=new WeakMap,oi=new WeakMap,ci=new WeakMap,di=new WeakMap,vi=new WeakMap,ui=new WeakMap,pi=new WeakMap,fi=new WeakMap,_i=new WeakMap,hi=new WeakMap,gi=new WeakMap;const Ne=new Wh;function fs(s){const a={...bn(Ot)};s(a),Ot.set(a)}var $h=p('
'),Gh=p(`
// welcome
Speak to anything on your machine.
A few minutes of setup. Pick a transcription engine, bind a hotkey, choose how VoxCtrl shows
- itself, and test it end to end. Everything runs on this device — nothing leaves it.
↺ Nothing is permanent — every choice can be changed later in Settings.
`);function Yh(s){const a=[{glyph:"∇",n:"01",title:"Transcription engine",desc:"whisper.cpp or Moonshine, sized to your hardware."},{glyph:"⌁",n:"02",title:"Hotkey",desc:"A gesture and a key combo to start talking."},{glyph:"⌬",n:"03",title:"Overlay",desc:"A visual signal while the mic is live — or none."},{glyph:"◉",n:"04",title:"Live test",desc:"Dictate into a box and watch it land."},{glyph:"⊕",n:"05",title:"Voice output",desc:"Optional: let agents talk back through your speakers."}];var t=Gh(),r=n(t),l=n(r),c=i(n(l),4),u=i(r,2);pt(u,5,()=>a,ft,(v,f)=>{var h=$h(),b=n(h),m=n(b),_=n(m),x=i(m,2),A=n(x),q=i(b,2),T=n(q),D=i(q,2),se=n(D);w(()=>{y(_,e(f).glyph),y(A,e(f).n),y(T,e(f).title),y(se,e(f).desc)}),d(v,h)}),w(()=>mt(c,"src",nr)),d(s,t)}var Jh=p(''),Xh=p('
Discovered models from server:
'),Zh=p(""),Qh=p('✔ Tested & verified successfully'),eg=p('⚠️ Test connection required to proceed'),tg=p(`
🌐
Remote Speech Engine Settings
Connect to a network speech-to-text service supporting the OpenAI /v1/audio/transcriptions API (e.g., Faster-Whisper-Server, vLLM, LocalAI, Whisper-standalone, or OpenAI Whisper).
- Audio will begin streaming to the endpoint as soon as your keybind is triggered.
Base URL or full transcriptions path (e.g. http://192.168.1.50:8000/v1 or https://api.openai.com/v1).
Leave blank if your local network server does not require authentication.
Language code (e.g. en, es, fr) or leave blank/auto for automatic detection.
This build was compiled without the Moonshine backend — choosing it runs whisper.cpp
+ typed into the focused window.`,1),xh=p(''),Th=p(''),Sh=p('
'),Eh=p('
',1),Ch=p(' is downloaded and ready.',1),Mh=p('Downloading in the background — no action needed.',1),Ph=p(' is not downloaded yet, so dictation produces no text.',1),Ah=p('
'),Dh=p('
❌
'),zh=p('
Global shortcuts
Typing text into other windows
Speech model
'),Ih=p('');function Oh(s,a){Tt(a,!0);let t=S(null),r=S(!1),l=S(!1),c=S(null),u=S(!1),v=S(!1),f=S(!1),h=S(null),b=S(!1),m=S(null),_;async function x(){try{o(t,await E("get_setup_status"),!0)}catch(R){console.error("Failed to read setup status:",R)}}qt(()=>{x(),_=setInterval(x,2e3)}),ar(()=>{_&&clearInterval(_)});async function M(){try{await ol().close()}catch(R){console.error("Failed to close window natively:",R)}}async function q(){var R;o(r,!0),o(c,null);try{await E("install_system_integration"),await x()}catch(B){o(c,(R=B==null?void 0:B.toString())!=null?R:"Install failed",!0),o(u,!0)}finally{o(r,!1)}}async function T(){var R;o(l,!0),o(c,null);try{await E("download_configured_model"),await x()}catch(B){o(c,(R=B==null?void 0:B.toString())!=null?R:"Download failed",!0)}finally{o(l,!1)}}async function D(){try{await E("open_settings_tab",{tab:"engine"})}catch(R){console.error("Failed to open the Engine settings tab:",R)}}async function se(){var R;o(f,!0),o(h,null);try{await E("open_shortcut_settings")}catch(B){o(h,(R=B==null?void 0:B.toString())!=null?R:"Could not open shortcut settings.",!0)}finally{o(f,!1)}}async function ne(){var R;o(b,!0),o(m,null);try{await E("approve_shortcuts"),await x()}catch(B){o(m,(R=B==null?void 0:B.toString())!=null?R:"Failed to configure shortcuts for your desktop.",!0),await x()}finally{o(b,!1)}}async function fe(){if(e(t))try{await navigator.clipboard.writeText(e(t).manual_package_commands),o(v,!0),setTimeout(()=>o(v,!1),2e3)}catch(R){console.error("Clipboard write failed:",R)}}const Q=ce(()=>e(t)?e(t).hotkeys.backend==="starting"?"busy":e(t).hotkeys_active?"ok":"todo":"busy"),z=ce(()=>e(t)?e(t).missing_injection_tool?"todo":"ok":"busy"),I=ce(()=>e(t)?e(t).model_ready?"ok":e(t).model_auto_downloads?"busy":"todo":"busy"),L=R=>R==="ok"?"✅":R==="busy"?"⏳":"⚠️";var ge=Ih(),ee=n(ge);{var K=R=>{var B=nh();d(R,B)},V=R=>{var B=ih();d(R,B)},oe=R=>{var B=zh(),be=n(B),Ae=n(be),ue=n(Ae),j=i(Ae,2),J=n(j),Se=n(J),De=i(J,2),le=n(De),W=i(be,2),ae=n(W);let O;var X=n(ae),ve=n(X),Me=i(X,2),Fe=i(n(Me),2),he=n(Fe),re=i(Fe,2);{var we=Oe=>{var qe=lh(),$=ht(qe),g=n($),A=i($,2),Pe=n(A),Ue=n(Pe),ie=i(A,2);{var xe=Ce=>{var He=rh(),Xe=n(He);w(()=>y(Xe,e(h))),d(Ce,He)};k(ie,Ce=>{e(h)&&Ce(xe)})}w(()=>{var Ce;y(g,`🔧 One more step on KDE: ${(Ce=e(t).hotkeys.manual_enable_hint)!=null?Ce:""}`),Pe.disabled=e(f),y(Ue,e(f)?"Opening…":"Open Shortcut Settings")}),N("click",Pe,se),d(Oe,qe)};k(re,Oe=>{e(t).hotkeys.needs_manual_enable&&Oe(we)})}var Je=i(re,2);{var de=Oe=>{var qe=oh();d(Oe,qe)};k(Je,Oe=>{(e(t).hotkeys.backend==="portal"||e(t).hotkeys.backend==="mint_dbus")&&Oe(de)})}var Y=i(Je,2);{var U=Oe=>{var qe=uh();pt(qe,21,()=>e(t).hotkeys.shortcuts,ft,($,g)=>{var A=vh();let Pe;var Ue=n(A);{var ie=Ce=>{var He=ch(),Xe=n(He);w(()=>y(Xe,e(g).trigger_description||e(g).requested||"chosen in your desktop settings")),d(Ce,He)},xe=Ce=>{var He=dh();d(Ce,He)};k(Ue,Ce=>{e(g).bound?Ce(ie):Ce(xe,-1)})}w(()=>Pe=Te(A,1,"svelte-45v8pc",null,Pe,{unbound:!e(g).bound})),d($,A)}),d(Oe,qe)};k(Y,Oe=>{e(t).hotkeys_active&&e(t).hotkeys.shortcuts.length>0&&Oe(U)})}var te=i(Y,2);{var G=Oe=>{var qe=ph();d(Oe,qe)},_e=Oe=>{var qe=fh();d(Oe,qe)},me=Oe=>{var qe=_h();d(Oe,qe)},pe=Oe=>{var qe=gh(),$=i(ht(qe),2),g=n($),A=n(g),Pe=i($,2);{var Ue=ie=>{var xe=hh(),Ce=n(xe);w(()=>y(Ce,e(m))),d(ie,xe)};k(Pe,ie=>{e(m)&&ie(Ue)})}w(()=>{g.disabled=e(b),y(A,e(b)?"Configuring…":"Approve Keybinds")}),N("click",g,ne),d(Oe,qe)},ze=Oe=>{var qe=bh(),$=i(ht(qe),2),g=n($),A=n(g),Pe=i($,2);{var Ue=ie=>{var xe=mh(),Ce=n(xe);w(()=>y(Ce,e(m))),d(ie,xe)};k(Pe,ie=>{e(m)&&ie(Ue)})}w(()=>{g.disabled=e(b),y(A,e(b)?"Configuring…":"Approve Shortcuts")}),N("click",g,ne),d(Oe,qe)};k(te,Oe=>{e(t).hotkeys.backend==="x11"?Oe(G):e(t).hotkeys.backend==="mint_dbus"?Oe(_e,1):e(t).hotkeys.backend==="evdev"?Oe(me,2):e(t).hotkeys.portal_refused?Oe(pe,3):e(t).hotkeys.backend!=="starting"&&Oe(ze,4)})}var Ye=i(te,2);{var st=Oe=>{var qe=yh(),$=n(qe);w(()=>{var g;return y($,`Portal reported: ${(g=e(t).hotkeys.portal_error)!=null?g:""}`)}),d(Oe,qe)};k(Ye,Oe=>{e(t).hotkeys.portal_error&&e(t).hotkeys.backend!=="portal"&&e(t).hotkeys.backend!=="evdev"&&Oe(st)})}var it=i(Ye,2);{var H=Oe=>{var qe=wh(),$=n(qe);w(()=>{var g;return y($,`X11 shortcuts: ${(g=e(t).hotkeys.x11_error)!=null?g:""}`)}),d(Oe,qe)};k(it,Oe=>{e(t).hotkeys.x11_error&&e(t).hotkeys.backend!=="x11"&&e(t).hotkeys.backend!=="portal"&&Oe(H)})}var P=i(ae,2);let C;var ke=n(P),je=n(ke),ye=i(ke,2),Ie=i(n(ye),2),Ge=n(Ie);{var Ze=Oe=>{var qe=kh(),$=ht(qe),g=n($);w(()=>y(g,e(t).missing_injection_tool)),d(Oe,qe)},Ve=Oe=>{var qe=Be("Ready — transcriptions can be typed straight into the focused window.");d(Oe,qe)};k(Ge,Oe=>{e(t).missing_injection_tool?Oe(Ze):Oe(Ve,-1)})}var at=i(Ie,2);{var et=Oe=>{var qe=Eh(),$=ht(qe),g=n($);{var A=Ce=>{var He=xh();N("click",He,q),d(Ce,He)};k(g,Ce=>{e(t).pkexec_available&&e(t).manual_package_commands&&Ce(A)})}var Pe=i(g,2);{var Ue=Ce=>{var He=Th(),Xe=n(He);w(()=>y(Xe,e(u)?"Hide manual commands":"Install it manually")),N("click",He,()=>o(u,!e(u))),d(Ce,He)};k(Pe,Ce=>{e(t).manual_package_commands&&Ce(Ue)})}var ie=i($,2);{var xe=Ce=>{var He=Sh(),Xe=n(He),Dt=n(Xe),zt=i(Xe,2),Ft=n(zt);w(()=>{y(Dt,e(t).manual_package_commands),y(Ft,e(v)?"Copied":"Copy commands")}),N("click",zt,fe),d(Ce,He)};k(ie,Ce=>{e(u)&&Ce(xe)})}d(Oe,qe)};k(at,Oe=>{e(t).missing_injection_tool&&Oe(et)})}var rt=i(P,2);let Ee;var $e=n(rt),ct=n($e),vt=i($e,2),nt=i(n(vt),2),wt=n(nt);{var dt=Oe=>{var qe=Ch(),$=ht(qe),g=n($);w(()=>y(g,e(t).model_size)),d(Oe,qe)},Et=Oe=>{var qe=Mh(),$=i(ht(qe)),g=n($);w(()=>y(g,e(t).model_size)),d(Oe,qe)},jt=Oe=>{var qe=Ph(),$=ht(qe),g=n($);w(()=>y(g,e(t).model_size)),d(Oe,qe)};k(wt,Oe=>{e(t).model_ready?Oe(dt):e(t).model_auto_downloads?Oe(Et,1):Oe(jt,-1)})}var ia=i(nt,2);{var ra=Oe=>{var qe=Ah(),$=n(qe),g=n($),A=i($,2);w(()=>{$.disabled=e(l),y(g,e(l)?"Downloading…":`Download ${e(t).model_size}`)}),N("click",$,T),N("click",A,D),d(Oe,qe)};k(ia,Oe=>{!e(t).model_ready&&!e(t).model_auto_downloads&&Oe(ra)})}var bt=i(W,2);{var ea=Oe=>{var qe=Dh(),$=i(n(qe),2),g=n($);w(()=>y(g,e(c))),d(Oe,qe)};k(bt,Oe=>{e(c)&&Oe(ea)})}var Lt=i(bt,2),Ht=n(Lt),ta=n(Ht);w((Oe,qe,$)=>{y(ue,e(t).is_complete?"✅":"🛠️"),y(Se,e(t).is_complete?"VoxCtrl is ready":"Finish setting up VoxCtrl"),y(le,e(t).is_complete?"Press your shortcut anywhere to dictate.":"Dictation is not ready yet — the steps below say why."),O=Te(ae,1,"step svelte-45v8pc",null,O,{done:e(Q)==="ok"}),y(ve,Oe),y(he,e(t).hotkeys.detail),C=Te(P,1,"step svelte-45v8pc",null,C,{done:e(z)==="ok"}),y(je,qe),Ee=Te(rt,1,"step svelte-45v8pc",null,Ee,{done:e(I)==="ok"}),y(ct,$),y(ta,e(t).is_complete?"Close":"Continue anyway")},[()=>L(e(Q)),()=>L(e(z)),()=>L(e(I))]),N("click",Ht,M),d(R,B)};k(ee,R=>{e(r)?R(K):e(t)?R(oe,-1):R(V,1)})}d(s,ge),St()}Qt(["click"]);const Lh=[{id:"tiny",mb:75,speed:.96,accuracy:.58},{id:"base",mb:142,speed:.88,accuracy:.68},{id:"small",mb:466,speed:.68,accuracy:.8},{id:"medium",mb:1500,speed:.42,accuracy:.9},{id:"large-v3",mb:3100,speed:.22,accuracy:.97}],Rh=[{id:"tiny",mb:100,speed:.98,accuracy:.64},{id:"base",mb:250,speed:.92,accuracy:.77}],Nh=[{id:"tdt-0.6b-v3",mb:665,speed:.95,accuracy:.94}],Vh=[{id:"remote",mb:0,speed:.95,accuracy:.95}],Mi=[{id:"whisper-cpp",name:"whisper.cpp",glyph:"∇",tagline:"Reference-grade accuracy in quiet spaces. Five model sizes from 75 MB to 3.1 GB. CUDA, Vulkan or CPU.",models:Lh,gpu:!0,noiseRetention:.64},{id:"moonshine",name:"Moonshine",glyph:"↯",tagline:"Streaming ONNX model tuned for real rooms — fans, keyboards, traffic. Fast on any CPU, tiny download.",models:Rh,gpu:!1,noiseRetention:.93},{id:"parakeet",name:"Parakeet TDT",glyph:"⚡",tagline:"NVIDIA FastConformer TDT 0.6B. Ultra-fast non-autoregressive transcription, SOTA accuracy, no repetition loops.",models:Nh,gpu:!0,noiseRetention:.88},{id:"remote-openai",name:"Remote Speech Engine",glyph:"🌐",tagline:"Connect to an OpenAI-compatible speech-to-text server on your network or cloud (Faster-Whisper, vLLM, etc.).",models:Vh,gpu:!1,noiseRetention:.92}],xn=[{id:"toggle",name:"Tap to talk",verb:"tap",desc:"Press once to start, press again to stop. Hands stay free while you speak.",key:[[1,1],[8,0],[1,1],[3,0]],mic:[[1,0],[9,1],[4,0]]},{id:"double_tap",name:"Double-tap to talk",verb:"double-tap",desc:"Two quick presses start dictation; one press stops. Hard to trigger by accident.",key:[[1,1],[.7,0],[1,1],[7,0],[1,1],[3,0]],mic:[[2.7,0],[7.3,1],[4,0]]},{id:"hold",name:"Hold to talk",verb:"hold",desc:"Hold the keys down while speaking, release to stop. Like a walkie-talkie.",key:[[1,0],[9,1],[4,0]],mic:[[1,0],[9,1],[4,0]]},{id:"double_tap_hold",name:"Double-tap & hold",verb:"double-tap and hold",desc:"Tap once, then press and hold. Release to stop. Never collides with a plain shortcut.",key:[[1,1],[.7,0],[8.3,1],[4,0]],mic:[[2.7,0],[6.3,1],[4,0]]}],mn=[{id:"blue_wave",name:"Ocean Wave",meta:"default · tide-pool waves",glyph:"⊟"},{id:"voice_card",name:"Voice Card",meta:"20×6 LED VU matrix",glyph:"⊟"},{id:"waveform",name:"Waveform",meta:"scrolling oscilloscope",glyph:"⌇"},{id:"pulse",name:"Pulse Ring",meta:"sonar sweep · target lock",glyph:"◌"},{id:"mono_bars",name:"Mono Bars",meta:"black & white 5-bar meter",glyph:"▥"},{id:"spectrum",name:"Neon Spectrum",meta:"16-band equalizer",glyph:"▦"},{id:"terminal",name:"Retro Terminal",meta:"DOS-blue ASCII meter",glyph:"▸"},{id:"vinyl",name:"Analog VU",meta:"vintage needle meter",glyph:"◔"}],Fh=[{id:"top",label:"Top",glyph:"⤒"},{id:"center",label:"Center",glyph:"⊡"},{id:"bottom",label:"Bottom",glyph:"⤓"}],cs=[{id:"vox_cpm_2",name:"VoxCPM2",kind:"neural · 2B autoregressive",quality:.98,speed:.25,mb:2950,note:"2B autoregressive diffusion. SOTA voice realism & cloning. Runs via audio.cpp, best on a Vulkan GPU."},{id:"breeze_tts_2",name:"Breeze-TTS-2",kind:"neural · expressive",quality:.96,speed:.32,mb:5080,note:"Most natural prosody. Runs via audio.cpp, best on a Vulkan GPU or fast CPU.",nonCommercial:!0,licenceUrl:"huggingface.co/BreezeBlue/Breeze-TTS-2"},{id:"pocket_tts",name:"Pocket TTS",kind:"neural · voice cloning",quality:.86,speed:.55,mb:130,note:"Cloned voices, downloaded in-app. Runs via audio.cpp with optional Vulkan acceleration."},{id:"piper",name:"Piper TTS",kind:"onnx · ~11 voices",quality:.72,speed:.8,mb:60,note:"The sweet spot for most machines. Per-voice ~60 MB."},{id:"inflect_micro",name:"Inflect Micro",kind:"compact neural",quality:.55,speed:.92,mb:38,note:"Tiny footprint, still human-ish. Good for laptops."},{id:"espeak",name:"eSpeak-NG",kind:"formant synth",quality:.3,speed:.99,mb:0,note:"Instant, robotic, runs anywhere. Zero download."}],ds=["Welcome","Engine","Hotkey","Overlay","Test","Voice","Done"];function Tn(s){return s<=0?"none":s>=1e3?`${(s/1e3).toFixed(1)} GB`:`${Math.round(s)} MB`}function Bh(s,a=cs){const t=Math.max(0,...a.map(r=>r.mb));return t<=0||s<=0?0:Math.min(100,s/t*100)}function Fi(s){return`${Math.round(s*100)}%`}function qh(s){return s>.85?"instant":s>.6?"< 1 s":s>.35?"1–3 s":"3–8 s"}function Kh(s){return s>.9?"instant":s>.7?"< 0.5 s":s>.5?"~1 s":"2–4 s"}function Pi(s,a){return Array.from({length:s},(t,r)=>{const l=(r+1)/s;return{h:Math.max(8,Math.round(100*a*(.55+.45*Math.sin(r*1.7+a*5)))),o:l<=a?1:.18}})}function Ho(s){return Array.from({length:s},(a,t)=>({d:(.6+t*7%5*.12).toFixed(2),dl:(t*.07).toFixed(2)}))}const Uh={KEY_LEFTCTRL:"Ctrl",KEY_RIGHTCTRL:"Ctrl",KEY_LEFTALT:"Alt",KEY_RIGHTALT:"Alt",KEY_LEFTSHIFT:"Shift",KEY_RIGHTSHIFT:"Shift",KEY_LEFTMETA:"Super",KEY_RIGHTMETA:"Super",KEY_SPACE:"Space",KEY_ESC:"Esc",KEY_ENTER:"Enter",KEY_TAB:"Tab",KEY_BACKSPACE:"Backspace",KEY_DELETE:"Delete",KEY_MINUS:"-",KEY_EQUAL:"=",KEY_LEFTBRACE:"[",KEY_RIGHTBRACE:"]",KEY_BACKSLASH:"\\",KEY_SEMICOLON:";",KEY_APOSTROPHE:"'",KEY_GRAVE:"`",KEY_COMMA:",",KEY_DOT:".",KEY_SLASH:"/",KEY_KPPLUS:"Num +",KEY_KPMINUS:"Num -",KEY_KPASTERISK:"Num *",KEY_KPSLASH:"Num /",KEY_KPDOT:"Num .",KEY_KPENTER:"Num Enter",KEY_KPEQUAL:"Num =",KEY_102ND:"<",KEY_SYSRQ:"PrtSc",KEY_COMPOSE:"Menu",KEY_MUTE:"Mute",KEY_VOLUMEDOWN:"Vol -",KEY_VOLUMEUP:"Vol +",KEY_NEXTSONG:"Next",KEY_PREVIOUSSONG:"Prev",KEY_STOPCD:"Stop",KEY_PLAYPAUSE:"Play/Pause"};function dl(s){var t;const a=/^KEY_KP(\d)$/.exec(s);return a?`Num ${a[1]}`:(t=Uh[s])!=null?t:s.replace(/^KEY_/,"")}const yr="default_hold",Wn="command",jh="Command";function Hh(s){return{...s,id:Wn,label:jh,delivery:"command",command:null}}var li,oi,ci,di,vi,ui,pi,fi,_i,hi,gi;class Wh{constructor(){lt(this,li,S(0));lt(this,oi,S(0));lt(this,ci,S(!1));lt(this,di,S("hold"));lt(this,vi,S(null));lt(this,ui,S(!1));lt(this,pi,S(yt([])));lt(this,fi,S(null));lt(this,_i,S(yt([])));lt(this,hi,S(!1));lt(this,gi,S(!1))}get step(){return e(F(this,li))}set step(a){o(F(this,li),a,!0)}get visited(){return e(F(this,oi))}set visited(a){o(F(this,oi),a,!0)}get leaving(){return e(F(this,ci))}set leaving(a){o(F(this,ci),a,!0)}get gesture(){return e(F(this,di))}set gesture(a){o(F(this,di),a,!0)}get combo(){return e(F(this,vi))}set combo(a){o(F(this,vi),a,!0)}get recording(){return e(F(this,ui))}set recording(a){o(F(this,ui),a,!0)}get held(){return e(F(this,pi))}set held(a){o(F(this,pi),a,!0)}get captureHint(){return e(F(this,fi))}set captureHint(a){o(F(this,fi),a,!0)}get issues(){return e(F(this,_i))}set issues(a){o(F(this,_i),a,!0)}get engineChosen(){return e(F(this,hi))}set engineChosen(a){o(F(this,hi),a,!0)}get modelChosen(){return e(F(this,gi))}set modelChosen(a){o(F(this,gi),a,!0)}get gestureInfo(){var a;return(a=xn.find(t=>t.id===this.gesture))!=null?a:xn[2]}get displayKeys(){var a;return this.recording?this.held:(a=this.combo)!=null?a:[]}recordIssue(a){this.issues=[...this.issues.filter(t=>t.id!==a.id),a]}clearIssue(a){this.issues=this.issues.filter(t=>t.id!==a)}goTo(a){a===this.step||this.leaving||a<0||a>=ds.length||(this.leaving=!0,this.recording=!1,setTimeout(()=>{this.step=a,this.visited=Math.max(this.visited,a),this.leaving=!1},200))}async ensureCommandTarget(){var l;const a=await E("get_targets");if(a.some(c=>c.id===Wn&&c.delivery==="command"))return Wn;const t=(l=a.find(c=>c.delivery==="inject"))!=null?l:a[0];if(!t)return"default";const r=[...a.filter(c=>c.id!==Wn),Hh(t)];return await E("save_targets",{targets:r}),Wn}async saveBinding(){if(!this.combo||this.combo.length===0)return;const a=await this.ensureCommandTarget(),t=await E("get_bindings").catch(()=>[]),r=this.gestureInfo,l={id:yr,label:`Dictate (${r.name})`,keys:[...this.combo],gesture:this.gesture,target_id:a,target_ids:[a],tap_ms:300,hold_threshold_ms:200,disabled:!1,openai_enabled:!1,openai_model:"",openai_mode:"custom",openai_prompt:"",openai_system_prompt:""},c=t.filter(u=>u.id!==yr&&u.id!=="default_toggle"&&u.id!=="__tts_stop__");await E("save_bindings",{bindings:[l,...c]})}async loadBinding(){var a;try{const t=await E("get_bindings"),r=(a=t.find(l=>l.id===yr))!=null?a:t.find(l=>l.id!=="__tts_stop__");r&&r.keys.length>0&&(this.combo=[...r.keys],xn.some(l=>l.id===r.gesture)&&(this.gesture=r.gesture))}catch(t){console.error("Wizard: failed to read existing bindings:",t)}}reset(){this.step=0,this.visited=0,this.leaving=!1,this.gesture="hold",this.combo=null,this.recording=!1,this.held=[],this.captureHint=null,this.issues=[],this.engineChosen=!1,this.modelChosen=!1}}li=new WeakMap,oi=new WeakMap,ci=new WeakMap,di=new WeakMap,vi=new WeakMap,ui=new WeakMap,pi=new WeakMap,fi=new WeakMap,_i=new WeakMap,hi=new WeakMap,gi=new WeakMap;const Ne=new Wh;function fs(s){const a={...bn(Ot)};s(a),Ot.set(a)}var Yh=p('
'),$h=p(`
// welcome
Speak to anything on your machine.
A few minutes of setup. Pick a transcription engine, bind a hotkey, choose how VoxCtrl shows
+ itself, and test it end to end. Everything runs on this device — nothing leaves it.
↺ Nothing is permanent — every choice can be changed later in Settings.
`);function Gh(s){const a=[{glyph:"∇",n:"01",title:"Transcription engine",desc:"whisper.cpp or Moonshine, sized to your hardware."},{glyph:"⌁",n:"02",title:"Hotkey",desc:"A gesture and a key combo to start talking."},{glyph:"⌬",n:"03",title:"Overlay",desc:"A visual signal while the mic is live — or none."},{glyph:"◉",n:"04",title:"Live test",desc:"Dictate into a box and watch it land."},{glyph:"⊕",n:"05",title:"Voice output",desc:"Optional: let agents talk back through your speakers."}];var t=$h(),r=n(t),l=n(r),c=i(n(l),4),u=i(r,2);pt(u,5,()=>a,ft,(v,f)=>{var h=Yh(),b=n(h),m=n(b),_=n(m),x=i(m,2),M=n(x),q=i(b,2),T=n(q),D=i(q,2),se=n(D);w(()=>{y(_,e(f).glyph),y(M,e(f).n),y(T,e(f).title),y(se,e(f).desc)}),d(v,h)}),w(()=>mt(c,"src",nr)),d(s,t)}var Jh=p(''),Xh=p('
Discovered models from server:
'),Zh=p(""),Qh=p('✔ Tested & verified successfully'),eg=p('⚠️ Test connection required to proceed'),tg=p(`
🌐
Remote Speech Engine Settings
Connect to a network speech-to-text service supporting the OpenAI /v1/audio/transcriptions API (e.g., Faster-Whisper-Server, vLLM, LocalAI, Whisper-standalone, or OpenAI Whisper).
+ Audio will begin streaming to the endpoint as soon as your keybind is triggered.
Base URL or full transcriptions path (e.g. http://192.168.1.50:8000/v1 or https://api.openai.com/v1).
Leave blank if your local network server does not require authentication.
Language code (e.g. en, es, fr) or leave blank/auto for automatic detection.
This build was compiled without the Moonshine backend — choosing it runs whisper.cpp
with the model above instead.
`),ng=p(`
This build was compiled without the Parakeet backend — choosing it runs whisper.cpp
with the model above instead.
`),ig=p('
'),rg=p('
server configuration
URL
Model
Status
',1),lg=p(''),og=p('
'),cg=p('
model size
',1),dg=p(''),vg=p(''),ug=p('
✓
◌ quiet room
≋ noisy room
'),pg=p(''),fg=p(''),_g=p(' Checking local models…'),hg=p(''),gg=p('⚠️ Test connection required before continuing'),mg=p(''),bg=p('◇ Pick an engine and a model size — they download before the next step'),yg=p(''),wg=p(`
// 01 · transcription engine
Which ears should VoxCtrl use?
Choose between on-device engines (whisper.cpp, Moonshine, Parakeet TDT) or connect to a Remote Speech Engine over your network.
- Pick a model size inside each card or configure your remote endpoint to get started.
`);function kg(s,a){Tt(a,!0);const t=()=>Zt(Ot,"$config",r),[r,l]=Ea(),c=1;let u=S(!0),v=S(!0),f=S(null),h=S(yt({})),b=S(yt({})),m=S(yt({})),_=S(null),x=S(null),A=S(!1),q=S(!1),T=S(!1);const D=ce(()=>t().engine.backend==="remote-openai"?"remote-openai":t().engine.backend==="parakeet"?"parakeet":t().engine.backend==="moonshine"?"moonshine":"whisper-cpp"),se={cuda:"CUDA",vulkan:"Vulkan",coreml:"CoreML"},ne=ce(()=>!!e(f)&&t().engine.whisper_cpp.device!=="cpu"),fe=ce(()=>{var H;return e(f)?(H=se[e(f)])!=null?H:e(f):""}),Q=ce(()=>{var H;return e(D)==="remote-openai"?((H=t().engine.remote_openai)==null?void 0:H.model)||"whisper-1":e(D)==="parakeet"&&e(v)?t().engine.parakeet.model_size:e(D)==="moonshine"&&e(u)?t().engine.moonshine.model_size:t().engine.whisper_cpp.model_size}),z=ce(()=>e(D)==="remote-openai"?e(T):e(D)==="parakeet"&&e(v)?!!e(m)[e(Q)]:e(D)==="moonshine"&&e(u)?!!e(b)[e(Q)]:!!e(h)[e(Q)]);function I(H,M){var C;return H!==e(D)?!1:M.id===(H==="remote-openai"?((C=t().engine.remote_openai)==null?void 0:C.model)||"whisper-1":H==="parakeet"?t().engine.parakeet.model_size:H==="moonshine"?t().engine.moonshine.model_size:t().engine.whisper_cpp.model_size)}function L(H,M){return H==="remote-openai"?e(T):H==="parakeet"?!!e(m)[M.id]:H==="moonshine"?!!e(b)[M.id]:!!e(h)[M.id]}function ge(H){fs(M=>{M.engine.backend=H,H==="remote-openai"&&!M.engine.remote_openai&&(M.engine.remote_openai={endpoint:"http://localhost:8000/v1",api_key:null,model:"whisper-1",language:"",timeout_secs:30})}),Ne.engineChosen=!0,H==="remote-openai"&&(Ne.modelChosen=!0,o(q,!0))}function ee(H,M){fs(C=>{C.engine.backend=H,H==="parakeet"?C.engine.parakeet.model_size=M.id:H==="moonshine"?C.engine.moonshine.model_size=M.id:H==="remote-openai"?C.engine.remote_openai?C.engine.remote_openai.model=M.id:C.engine.remote_openai={endpoint:"http://localhost:8000/v1",api_key:null,model:M.id,language:"",timeout_secs:30}:C.engine.whisper_cpp.model_size=M.id}),o(x,null),Ne.engineChosen=!0,Ne.modelChosen=!0}function j(){e(f)&&fs(H=>{H.engine.whisper_cpp.device=e(ne)?"cpu":"auto"})}async function V(){const H=t().engine.whisper_cpp.model_dir,M={};for(const C of Ai[0].models)try{M[C.id]=await E("check_model_downloaded",{modelSize:C.id,modelDir:H})}catch(ke){console.error("Wizard: whisper model check failed for",C.id,ke),M[C.id]=!1}o(h,M,!0)}async function oe(){const H={},M=Ai.find(C=>C.id==="moonshine");if(M)for(const C of M.models)try{H[C.id]=await E("check_moonshine_downloaded",{modelSize:C.id})}catch(ke){console.error("Wizard: moonshine model check failed for",C.id,ke),H[C.id]=!1}o(b,H,!0)}async function R(){const H={},M=Ai.find(C=>C.id==="parakeet");if(M)for(const C of M.models)try{H[C.id]=await E("check_parakeet_downloaded",{modelSize:C.id})}catch(ke){console.error("Wizard: parakeet model check failed for",C.id,ke),H[C.id]=!1}o(m,H,!0)}async function B(){if(e(D)==="remote-openai")return e(T)?!0:(a.setBlocker(c,"Test the remote connection successfully to continue."),o(q,!0),!1);if(e(z))return!0;const H=e(D),M=e(Q);o(_,M,!0),o(x,null);try{return H==="parakeet"&&e(v)?(await E("download_parakeet_model",{modelSize:M}),o(m,{...e(m),[M]:!0},!0)):H==="moonshine"&&e(u)?(await E("download_moonshine_model",{modelSize:M}),o(b,{...e(b),[M]:!0},!0)):(await E("download_model",{modelSize:M,modelDir:t().engine.whisper_cpp.model_dir}),o(h,{...e(h),[M]:!0},!0)),Ne.clearIssue("model-download"),!0}catch(C){return o(x,`${C}`),Ne.recordIssue({id:"model-download",step:c,title:`Speech model "${M}" could not be downloaded — dictation will produce no text.`,detail:`engine=${H} model=${M} model_dir=${t().engine.whisper_cpp.model_dir||"(default)"}
-${C}`}),!1}finally{o(_,null)}}pa(()=>{e(_)?a.setBlocker(c,`Downloading ${e(_)}…`):e(A)?e(D)==="remote-openai"&&!e(T)?a.setBlocker(c,"Test the remote connection successfully to continue."):e(z)?a.setBlocker(c,null):Ne.engineChosen?Ne.modelChosen?a.setBlocker(c,null):a.setBlocker(c,"Choose a model size to continue."):a.setBlocker(c,"Choose a transcription engine to continue."):a.setBlocker(c,"Checking which models are already on disk…")});async function be(){o(A,!1),await Promise.all([V(),oe(),R()]),o(A,!0)}qt(()=>(a.registerGate(c,B),E("moonshine_available").then(H=>o(u,H,!0)).catch(()=>o(u,!1)),E("parakeet_available").then(H=>o(v,H,!0)).catch(()=>o(v,!1)),E("accelerator_support").then(H=>{var M;return o(f,(M=H==null?void 0:H.whisper_gpu)!=null?M:null,!0)}).catch(()=>o(f,null)),be(),()=>{a.registerGate(c,null),a.setBlocker(c,null)}));function Pe(H){var Ye,Ze;if(H.id==="remote-openai")return{model:{id:((Ye=t().engine.remote_openai)==null?void 0:Ye.model)||"whisper-1",mb:0,speed:.95,accuracy:.95},rows:[{label:"speed",pct:95,value:"network",color:"var(--vx-cyan-0)",dim:!1},{label:"accuracy",pct:95,value:"server",color:"var(--vx-cyan-2)",dim:!1},{label:"RAM",pct:2,value:"offloaded",color:"var(--vx-gold-1)",dim:!1},{label:"VRAM",pct:0,value:"0 MB",color:"var(--vx-gold-0)",dim:!0}],quiet:Mi(12,.95),noisy:Mi(12,.92),quietPct:"server",noisyPct:"server"};const M=H.id==="parakeet"?t().engine.parakeet.model_size:H.id==="moonshine"?t().engine.moonshine.model_size:t().engine.whisper_cpp.model_size,C=(Ze=H.models.find(Ve=>Ve.id===M))!=null?Ze:H.models[0],ke=H.gpu&&e(ne),Ke=Math.min(1,C.speed+(ke?.3:0)),ye=ke?C.mb*.3:C.mb,Ie=ke?C.mb*1.1:0;return{model:C,rows:[{label:"speed",pct:Math.round(Ke*100),value:qh(Ke),color:"var(--vx-cyan-0)",dim:!1},{label:"accuracy",pct:Math.round(C.accuracy*100),value:Fi(C.accuracy),color:"var(--vx-cyan-2)",dim:!1},{label:"RAM",pct:Math.max(2,Math.min(100,Math.round(ye/3400*100))),value:Tn(ye),color:"var(--vx-gold-1)",dim:!1},{label:"VRAM",pct:Ie?Math.max(2,Math.min(100,Math.round(Ie/3400*100))):0,value:Ie?Tn(Ie):H.gpu?"off":"cpu only",color:"var(--vx-gold-0)",dim:!Ie}],quiet:Mi(12,C.accuracy),noisy:Mi(12,C.accuracy*H.noiseRetention),quietPct:Fi(C.accuracy),noisyPct:Fi(C.accuracy*H.noiseRetention)}}var ue=wg(),K=n(ue),J=i(n(K),2);let Se;var De=n(J);let le;var W=i(De,2),ae=n(W),O=i(n(ae),2);let X;var ve=n(O);{var Ae=H=>{var M=Be("UNAVAILABLE · CPU BUILD");d(H,M)},Fe=H=>{var M=Be();w(()=>{var C;return y(M,`ON · ${(C=e(fe))!=null?C:""}`)}),d(H,M)},he=H=>{var M=Be("OFF · CPU");d(H,M)};k(ve,H=>{e(f)?e(ne)?H(Fe,1):H(he,-1):H(Ae)})}var re=i(ae,2),we=n(re);{var Je=H=>{var M=Be(`Moves whisper.cpp weights from RAM to your GPU: faster, less RAM, uses VRAM. Moonshine is
- CPU-native and unaffected.`);d(H,M)},de=H=>{var M=Be(`This build has no GPU backend compiled in, so both engines run on the CPU. The Vulkan
- download accelerates whisper.cpp; Moonshine is CPU-native either way.`);d(H,M)};k(we,H=>{e(f)?H(Je):H(de,-1)})}var $=i(K,2);pt($,21,()=>Ai,ft,(H,M)=>{const C=ce(()=>Pe(e(M))),ke=ce(()=>e(D)===e(M).id);var Ke=ug();let ye;var Ie=i(n(Ke),2),Ye=n(Ie),Ze=n(Ye),Ve=n(Ze),at=i(Ze,2),et=n(at),rt=i(Ye,2),Ee=n(rt),Ge=i(rt,2);{var ct=g=>{var P=sg();d(g,P)},vt=g=>{var P=ng();d(g,P)};k(Ge,g=>{e(M).id==="moonshine"&&!e(u)?g(ct):e(M).id==="parakeet"&&!e(v)&&g(vt,1)})}var nt=i(Ie,2),wt=n(nt);{var dt=g=>{var P=rg(),Me=i(ht(P),2),Ue=n(Me),ie=i(n(Ue),2),xe=n(ie),Ce=i(Ue,2),He=i(n(Ce),2),Xe=n(He),Dt=i(Ce,2),zt=i(n(Dt),2);let Ft;var Wt=n(zt);{var $t=ut=>{var At=Be("✔ Verified");d(ut,At)},fa=ut=>{var At=Be("⚠️ Untested");d(ut,At)};k(Wt,ut=>{e(T)?ut($t):ut(fa,-1)})}var Yt=i(Me,2),ma=n(Yt);let Oa;var Ya=n(ma);{var tt=ut=>{var At=Be("⚙ Configure Server");d(ut,At)},gt=ut=>{var At=Be("⚡ Setup & Test");d(ut,At)};k(Ya,ut=>{e(T)?ut(tt):ut(gt,-1)})}var It=i(Yt,2);pt(It,21,()=>e(C).rows,ft,(ut,At)=>{var jt=ig();let wa;var oa=n(jt),La=n(oa),ja=n(La),Z=i(La),Le=n(Z),je=i(oa,2),Re=n(je);let Qe;w(()=>{var Jt;wa=Te(jt,1,"metric svelte-xv54mf",null,wa,{dim:e(At).dim}),y(ja,e(At).label),y(Le,e(At).value),Qe=na(Re,"",Qe,{width:`${(Jt=e(At).pct)!=null?Jt:""}%`,background:e(At).color})}),d(ut,jt)}),w(()=>{var ut,At,jt;mt(ie,"title",((ut=t().engine.remote_openai)==null?void 0:ut.endpoint)||"http://localhost:8000/v1"),y(xe,((At=t().engine.remote_openai)==null?void 0:At.endpoint)||"http://localhost:8000/v1"),y(Xe,((jt=t().engine.remote_openai)==null?void 0:jt.model)||"whisper-1"),Ft=Te(zt,1,"remote-v svelte-xv54mf",null,Ft,{"remote-v-ok":e(T),"remote-v-warn":!e(T)}),Oa=Te(ma,1,"vx-btn vx-btn-sm remote-cfg-btn svelte-xv54mf",null,Oa,{"vx-primary":!e(T)})}),N("click",ma,ut=>{ut.stopPropagation(),ge("remote-openai"),o(q,!0)}),d(g,P)},Et=g=>{var P=cg(),Me=i(ht(P),2);pt(Me,21,()=>e(M).models,ft,(ie,xe)=>{var Ce=lg();let He;var Xe=n(Ce),Dt=n(Xe),zt=i(Xe,2),Ft=n(zt);w((Wt,$t,fa)=>{He=Te(Ce,1,"size svelte-xv54mf",null,He,Wt),y(Dt,e(xe).id),y(Ft,`${$t!=null?$t:""}${fa!=null?fa:""}`)},[()=>({on:I(e(M).id,e(xe))}),()=>Tn(e(xe).mb),()=>L(e(M).id,e(xe))?" ✔":""]),N("click",Ce,Wt=>{Wt.stopPropagation(),ee(e(M).id,e(xe))}),d(ie,Ce)});var Ue=i(Me,2);pt(Ue,21,()=>e(C).rows,ft,(ie,xe)=>{var Ce=og();let He;var Xe=n(Ce),Dt=n(Xe),zt=n(Dt),Ft=i(Dt),Wt=n(Ft),$t=i(Xe,2),fa=n($t);let Yt;w(()=>{var ma;He=Te(Ce,1,"metric svelte-xv54mf",null,He,{dim:e(xe).dim}),y(zt,e(xe).label),y(Wt,e(xe).value),Yt=na(fa,"",Yt,{width:`${(ma=e(xe).pct)!=null?ma:""}%`,background:e(xe).color})}),d(ie,Ce)}),d(g,P)};k(wt,g=>{e(M).id==="remote-openai"?g(dt):g(Et,-1)})}var Kt=i(nt,2),ia=n(Kt),ra=n(ia),bt=i(n(ra)),ea=n(bt),Lt=i(ra,2);pt(Lt,21,()=>e(C).quiet,ft,(g,P)=>{var Me=dg();let Ue;w(()=>{var ie;return Ue=na(Me,"",Ue,{height:`${(ie=e(P).h)!=null?ie:""}%`,opacity:e(P).o})}),d(g,Me)});var Ht=i(ia,2),ta=n(Ht),Oe=i(n(ta)),qe=n(Oe),G=i(ta,2);pt(G,21,()=>e(C).noisy,ft,(g,P)=>{var Me=vg();let Ue;w(()=>{var ie;return Ue=na(Me,"",Ue,{height:`${(ie=e(P).h)!=null?ie:""}%`,opacity:e(P).o})}),d(g,Me)}),w(()=>{ye=Te(Ke,1,"vx-card engine-card svelte-xv54mf",null,ye,{"vx-on":e(ke)}),mt(Ke,"aria-checked",e(ke)),y(Ve,e(M).glyph),y(et,e(M).name),y(Ee,e(M).tagline),y(ea,e(C).quietPct),y(qe,e(C).noisyPct)}),N("click",Ke,()=>{ge(e(M).id),e(M).id==="remote-openai"&&o(q,!0)}),N("keydown",Ke,g=>{(g.key==="Enter"||g.key===" ")&&(g.preventDefault(),ge(e(M).id),e(M).id==="remote-openai"&&o(q,!0))}),d(H,Ke)});var U=i($,2),te=n(U);{var Y=H=>{var M=pg(),C=i(n(M));w(()=>{var ke;return y(C,` Downloading ${(ke=e(_))!=null?ke:""} — this can take a few minutes`)}),d(H,M)},_e=H=>{var M=fg(),C=n(M);w(()=>{var ke;return y(C,`✕ Download failed: ${(ke=e(x))!=null?ke:""}`)}),d(H,M)},me=H=>{var M=_g();d(H,M)},pe=H=>{var M=xi(),C=ht(M);{var ke=ye=>{var Ie=hg(),Ye=n(Ie);w(()=>{var Ze;return y(Ye,`✓ Remote engine connected (${(Ze=e(Q))!=null?Ze:""})`)}),d(ye,Ie)},Ke=ye=>{var Ie=gg();d(ye,Ie)};k(C,ye=>{e(T)?ye(ke):ye(Ke,-1)})}d(H,M)},ze=H=>{var M=mg(),C=n(M);w(()=>{var ke;return y(C,`✓ ${(ke=e(Q))!=null?ke:""} is on disk and ready`)}),d(H,M)},$e=H=>{var M=bg();d(H,M)},st=H=>{var M=yg(),C=n(M);w(()=>{var ke;return y(C,`↓ ${(ke=e(Q))!=null?ke:""} will download when you continue`)}),d(H,M)};k(te,H=>{e(_)?H(Y):e(x)?H(_e,1):e(A)?e(D)==="remote-openai"?H(pe,3):e(z)?H(ze,4):!Ne.engineChosen||!Ne.modelChosen?H($e,5):H(st,-1):H(me,2)})}var it=i(U,2);ag(it,{onSuccess:()=>{o(T,!0)},get isOpen(){return e(q)},set isOpen(H){o(q,H,!0)}}),w(()=>{Se=Te(J,1,"vx-card gpu-toggle svelte-xv54mf",null,Se,{"vx-on":e(ne)}),J.disabled=!e(f),le=Te(De,1,"switch svelte-xv54mf",null,le,{on:e(ne)}),X=Te(O,1,"state svelte-xv54mf",null,X,{on:e(ne)})}),N("click",J,j),d(s,ue),St(),l()}Qt(["click","keydown"]);var xg=p(""),Tg=p(""),Sg=p(''),Eg=p('
'),Cg=p(''),Ag=p('+'),Mg=p("
",1),Pg=p('
'),Dg=p(' Asking…',1),zg=p('
'),Ig=p('
'),Og=p(`
// 02 · first key binding
How do you want to start talking?
Pick a gesture, then record the keys. Taps keep your hands free while speaking; holds can't be
- left running by accident. Double-taps avoid clashes with shortcuts you already use.
`);function Lg(s,a){Tt(a,!0);const t=2;let r=S(null),l=S(!1),c=S(null);const u=ce(()=>{var W,ae;return(ae=(W=e(r))==null?void 0:W.supported_gestures)!=null&&ae.length?xn.filter(O=>e(r).supported_gestures.includes(O.id)):xn}),v=ce(()=>xn.length-e(u).length),f=ce(()=>{var W;return((W=e(r))==null?void 0:W.is_active)===!0}),h=ce(()=>!!Ne.combo&&Ne.combo.length>0&&e(r)!==null&&!e(r).is_active),b=ce(()=>Ne.recording&&Vr(Ne.held)?"Keep holding and add a regular key — modifiers alone cannot be a shortcut.":null);async function m(){try{o(r,await E("check_hotkey_status"),!0),e(r).is_active&&Ne.clearIssue("shortcut-register")}catch(W){console.error("Wizard: failed to read hotkey status:",W)}}function _(){Ne.recording=!0,Ne.held=[],Ne.captureHint=null,E("set_hotkeys_inhibited",{inhibited:!0}).catch(()=>{})}function x(){Ne.recording=!1,Ne.held=[],E("set_hotkeys_inhibited",{inhibited:!1}).catch(()=>{})}async function A(W){var O;if(W.length===0)return;let ae;try{ae=await E("check_hotkey_keys",{keys:W})}catch(X){console.error("Wizard: hotkey validation failed:",X),Ne.combo=[...W];return}ae.accepted?(Ne.combo=[...W],Ne.captureHint=null,await D()):Ne.captureHint=(O=ae.message)!=null?O:"This key combination cannot be used as a shortcut. Try another."}function q(W){if(!Ne.recording)return;W.preventDefault(),W.stopPropagation();const ae=il(W.key,W.code);if(W.key==="Escape"&&Ne.held.length===0){x();return}Ne.held.includes(ae)||(Ne.held=[...Ne.held,ae])}function T(W){if(!Ne.recording)return;W.preventDefault(),W.stopPropagation();const ae=[...Ne.held];x(),A(ae)}async function D(){var W;try{await Ne.saveBinding()}catch(ae){console.error("Wizard: failed to save binding:",ae),o(c,`Could not save the binding: ${ae}`),Ne.recordIssue({id:"binding-save",step:t,title:"The hotkey binding could not be written — no shortcut will start dictation.",detail:`keys=${((W=Ne.combo)!=null?W:[]).join("+")} gesture=${Ne.gesture}
-${ae}`});return}Ne.clearIssue("binding-save"),await m()}async function se(){var W,ae,O,X,ve,Ae;o(l,!0),o(c,null);try{o(r,await E("approve_shortcuts"),!0)}catch(Fe){o(c,`${Fe}`),Ne.recordIssue({id:"shortcut-register",step:t,title:"Your desktop refused to register the global shortcut.",detail:`backend=${(ae=(W=e(r))==null?void 0:W.backend)!=null?ae:"unknown"} portal_refused=${(X=(O=e(r))==null?void 0:O.portal_refused)!=null?X:"?"}
-portal_error=${(Ae=(ve=e(r))==null?void 0:ve.portal_error)!=null?Ae:"(none)"}
-${Fe}`}),await m()}finally{o(l,!1)}}async function ne(){try{await E("open_shortcut_settings")}catch(W){o(c,`${W}`)}}pa(()=>{let W=null;Ne.recording?W="Press the keys you want to use.":!Ne.combo||Ne.combo.length===0?W="Record a key combination first.":e(h)&&(W="Register the shortcut with your desktop to continue."),a.setBlocker(t,W)}),pa(()=>{const W=e(u);W.length>0&&!W.some(ae=>ae.id===Ne.gesture)&&(Ne.gesture=W[0].id)}),qt(()=>{a.registerGate(t,async()=>{var O;return await D(),((O=e(r))==null?void 0:O.is_active)!==!1}),Ne.loadBinding(),m();const W=ha("setup-status-changed",()=>void m()),ae=setInterval(()=>{Ne.recording||m()},3e3);return window.addEventListener("keydown",q,!0),window.addEventListener("keyup",T,!0),()=>{clearInterval(ae),W.then(O=>O()).catch(()=>{}),window.removeEventListener("keydown",q,!0),window.removeEventListener("keyup",T,!0),Ne.recording&&x(),a.registerGate(t,null),a.setBlocker(t,null)}});const fe=ce(()=>{var W,ae,O,X;return Ne.recording?{label:"listening for keys",hint:(ae=(W=Ne.captureHint)!=null?W:e(b))!=null?ae:"Hold one or more modifiers, then press a key. Esc to cancel.",tone:"rec"}:Ne.combo&&Ne.combo.length>0?{label:"binding captured",hint:(O=Ne.captureHint)!=null?O:"Click anywhere in this area to record a different combination.",tone:"done"}:{label:"click to record",hint:(X=Ne.captureHint)!=null?X:"Needs at least one modifier (Ctrl, Alt, Shift or Super) plus a regular key — e.g. Super + Space.",tone:"idle"}});var Q=Og(),z=i(n(Q),2),I=n(z),L=n(I);pt(L,17,()=>e(u),ft,(W,ae)=>{const O=ce(()=>Ne.gesture===e(ae).id);var X=Sg();let ve;var Ae=n(X),Fe=n(Ae),he=n(Fe),re=i(Fe,2),we=n(re),Je=i(Ae,2),de=n(Je),$=i(n(de),2);pt($,21,()=>e(ae).key,ft,(Y,_e)=>{var me=ce(()=>pl(e(_e),2));let pe=()=>e(me)[0],ze=()=>e(me)[1];var $e=xg();let st,it;w(()=>{st=Te($e,1,"svelte-1fbfhk3",null,st,{on:ze()&&e(O),lit:ze()}),it=na($e,"",it,{flex:pe()})}),d(Y,$e)});var U=i(de,2),te=i(n(U),2);pt(te,21,()=>e(ae).mic,ft,(Y,_e)=>{var me=ce(()=>pl(e(_e),2));let pe=()=>e(me)[0],ze=()=>e(me)[1];var $e=Tg();let st,it;w(()=>{st=Te($e,1,"svelte-1fbfhk3",null,st,{on:ze()&&e(O),lit:ze()}),it=na($e,"",it,{flex:pe()})}),d(Y,$e)}),w(()=>{ve=Te(X,1,"vx-card gesture svelte-1fbfhk3",null,ve,{"vx-on":e(O)}),y(he,e(ae).name),y(we,e(ae).desc)}),N("click",X,()=>Ne.gesture=e(ae).id),d(W,X)});var ge=i(L,2);{var ee=W=>{var ae=Eg(),O=n(ae);w(()=>{var X;return y(O,`${(X=e(v))!=null?X:""} gesture${e(v)===1?"":"s"} hidden — this desktop's shortcut
- backend only tells VoxCtrl that a shortcut fired, so it cannot time a hold.`)}),d(W,ae)};k(ge,W=>{e(v)>0&&W(ee)})}var j=i(I,2),V=n(j);let oe;var R=n(V);{var B=W=>{var ae=Cg();d(W,ae)};k(R,W=>{Ne.recording&&W(B)})}var be=i(R,2),Pe=i(n(be),1,!0),ue=i(be,2);pt(ue,21,()=>Ne.displayKeys,ft,(W,ae,O)=>{var X=Mg(),ve=ht(X);let Ae;var Fe=n(ve),he=i(ve,2);{var re=we=>{var Je=Ag();d(we,Je)};k(he,we=>{O{Ae=Te(ve,1,"vx-keycap",null,Ae,{"vx-hot":Ne.recording||e(fe).tone==="done"}),y(Fe,we)},[()=>dl(e(ae))]),d(W,X)});var K=i(ue,2);let J;var Se=n(K),De=i(V,2);{var le=W=>{var ae=Ig();let O;var X=n(ae),ve=n(X),Ae=i(X,2),Fe=n(Ae),he=n(Fe),re=i(Fe,2),we=n(re);{var Je=me=>{var pe=Be("The binding is registered system-wide. Continue to choose an overlay.");d(me,pe)},de=me=>{var pe=Be();w(()=>y(pe,e(r).portal_error)),d(me,pe)},$=me=>{var pe=Be(`Wayland desktops ask you to confirm global shortcuts. Click below and approve the
- dialog your desktop shows — you come straight back here.`);d(me,pe)};k(we,me=>{var pe;e(f)?me(Je):(pe=e(r))!=null&&pe.portal_error?me(de,1):me($,-1)})}var U=i(re,2);{var te=me=>{var pe=Pg(),ze=n(pe);w(()=>y(ze,e(c))),d(me,pe)};k(U,me=>{e(c)&&me(te)})}var Y=i(Ae,2);{var _e=me=>{var pe=zg(),ze=n(pe),$e=i(ze,2),st=n($e);{var it=M=>{var C=Dg();d(M,C)},H=M=>{var C=Be("Register →");d(M,C)};k(st,M=>{e(l)?M(it):M(H,-1)})}w(()=>$e.disabled=e(l)),N("click",ze,ne),N("click",$e,se),d(me,pe)};k(Y,me=>{e(f)||me(_e)})}w(()=>{var me,pe;O=Te(ae,1,"sys svelte-1fbfhk3",null,O,{ok:e(f)}),y(ve,e(f)?"✓":"⌬"),y(he,e(f)?`Shortcuts are live (${(pe=(me=e(r))==null?void 0:me.backend)!=null?pe:"ready"})`:"Your desktop still needs to approve the shortcut")}),d(W,ae)};k(De,W=>{Ne.combo&&Ne.combo.length>0&&W(le)})}w(()=>{oe=Te(V,1,"recorder svelte-1fbfhk3",null,oe,{rec:e(fe).tone==="rec",done:e(fe).tone==="done"}),y(Pe,e(fe).label),J=Te(K,1,"rec-hint svelte-1fbfhk3",null,J,{bad:!!Ne.captureHint}),y(Se,e(fe).hint)}),N("click",V,()=>Ne.recording?x():_()),d(s,Q),St()}Qt(["click"]);const Rg="/assets/blue_wave-DGfyQFFo.webm",Ng="/assets/mono_bars-1wA0h3Fz.webm",Vg="/assets/pulse-Cdnh-rAb.webm",Fg="/assets/spectrum-CLEHMZrI.webm",Bg="/assets/terminal-CvV88uWw.webm",qg="/assets/vinyl-BG1f8NO1.webm",jg="/assets/voice_card-BZZeHAB9.webm",Ug="/assets/waveform-DUI2x_EP.webm",Kg="/assets/blue_wave-OqjJ-fxD.webp",Hg="/assets/mono_bars-CPLx02Ku.webp",Wg="/assets/pulse-ESYJH4j2.webp",$g="/assets/spectrum-DV9agKUG.webp",Gg="/assets/terminal-DhrByqCl.webp",Yg="/assets/vinyl-BfHn3C6g.webp",Jg="/assets/voice_card-QnCU8RiM.webp",Xg="/assets/waveform-B5-owbWT.webp";var Zg=p(''),Qg=p(''),em=Oo(''),tm=p('
The overlay appears the moment your hotkey fires and shows live mic level plus the active
+ Pick a model size inside each card or configure your remote endpoint to get started.
`);function kg(s,a){Tt(a,!0);const t=()=>Zt(Ot,"$config",r),[r,l]=Ea(),c=1;let u=S(!0),v=S(!0),f=S(null),h=S(yt({})),b=S(yt({})),m=S(yt({})),_=S(null),x=S(null),M=S(!1),q=S(!1),T=S(!1);const D=ce(()=>t().engine.backend==="remote-openai"?"remote-openai":t().engine.backend==="parakeet"?"parakeet":t().engine.backend==="moonshine"?"moonshine":"whisper-cpp"),se={cuda:"CUDA",vulkan:"Vulkan",coreml:"CoreML"},ne=ce(()=>!!e(f)&&t().engine.whisper_cpp.device!=="cpu"),fe=ce(()=>{var H;return e(f)?(H=se[e(f)])!=null?H:e(f):""}),Q=ce(()=>{var H;return e(D)==="remote-openai"?((H=t().engine.remote_openai)==null?void 0:H.model)||"whisper-1":e(D)==="parakeet"&&e(v)?t().engine.parakeet.model_size:e(D)==="moonshine"&&e(u)?t().engine.moonshine.model_size:t().engine.whisper_cpp.model_size}),z=ce(()=>e(D)==="remote-openai"?e(T):e(D)==="parakeet"&&e(v)?!!e(m)[e(Q)]:e(D)==="moonshine"&&e(u)?!!e(b)[e(Q)]:!!e(h)[e(Q)]);function I(H,P){var C;return H!==e(D)?!1:P.id===(H==="remote-openai"?((C=t().engine.remote_openai)==null?void 0:C.model)||"whisper-1":H==="parakeet"?t().engine.parakeet.model_size:H==="moonshine"?t().engine.moonshine.model_size:t().engine.whisper_cpp.model_size)}function L(H,P){return H==="remote-openai"?e(T):H==="parakeet"?!!e(m)[P.id]:H==="moonshine"?!!e(b)[P.id]:!!e(h)[P.id]}function ge(H){fs(P=>{P.engine.backend=H,H==="remote-openai"&&!P.engine.remote_openai&&(P.engine.remote_openai={endpoint:"http://localhost:8000/v1",api_key:null,model:"whisper-1",language:"",timeout_secs:30})}),Ne.engineChosen=!0,H==="remote-openai"&&(Ne.modelChosen=!0,o(q,!0))}function ee(H,P){fs(C=>{C.engine.backend=H,H==="parakeet"?C.engine.parakeet.model_size=P.id:H==="moonshine"?C.engine.moonshine.model_size=P.id:H==="remote-openai"?C.engine.remote_openai?C.engine.remote_openai.model=P.id:C.engine.remote_openai={endpoint:"http://localhost:8000/v1",api_key:null,model:P.id,language:"",timeout_secs:30}:C.engine.whisper_cpp.model_size=P.id}),o(x,null),Ne.engineChosen=!0,Ne.modelChosen=!0}function K(){e(f)&&fs(H=>{H.engine.whisper_cpp.device=e(ne)?"cpu":"auto"})}async function V(){const H=t().engine.whisper_cpp.model_dir,P={};for(const C of Mi[0].models)try{P[C.id]=await E("check_model_downloaded",{modelSize:C.id,modelDir:H})}catch(ke){console.error("Wizard: whisper model check failed for",C.id,ke),P[C.id]=!1}o(h,P,!0)}async function oe(){const H={},P=Mi.find(C=>C.id==="moonshine");if(P)for(const C of P.models)try{H[C.id]=await E("check_moonshine_downloaded",{modelSize:C.id})}catch(ke){console.error("Wizard: moonshine model check failed for",C.id,ke),H[C.id]=!1}o(b,H,!0)}async function R(){const H={},P=Mi.find(C=>C.id==="parakeet");if(P)for(const C of P.models)try{H[C.id]=await E("check_parakeet_downloaded",{modelSize:C.id})}catch(ke){console.error("Wizard: parakeet model check failed for",C.id,ke),H[C.id]=!1}o(m,H,!0)}async function B(){if(e(D)==="remote-openai")return e(T)?!0:(a.setBlocker(c,"Test the remote connection successfully to continue."),o(q,!0),!1);if(e(z))return!0;const H=e(D),P=e(Q);o(_,P,!0),o(x,null);try{return H==="parakeet"&&e(v)?(await E("download_parakeet_model",{modelSize:P}),o(m,{...e(m),[P]:!0},!0)):H==="moonshine"&&e(u)?(await E("download_moonshine_model",{modelSize:P}),o(b,{...e(b),[P]:!0},!0)):(await E("download_model",{modelSize:P,modelDir:t().engine.whisper_cpp.model_dir}),o(h,{...e(h),[P]:!0},!0)),Ne.clearIssue("model-download"),!0}catch(C){return o(x,`${C}`),Ne.recordIssue({id:"model-download",step:c,title:`Speech model "${P}" could not be downloaded — dictation will produce no text.`,detail:`engine=${H} model=${P} model_dir=${t().engine.whisper_cpp.model_dir||"(default)"}
+${C}`}),!1}finally{o(_,null)}}pa(()=>{e(_)?a.setBlocker(c,`Downloading ${e(_)}…`):e(M)?e(D)==="remote-openai"&&!e(T)?a.setBlocker(c,"Test the remote connection successfully to continue."):e(z)?a.setBlocker(c,null):Ne.engineChosen?Ne.modelChosen?a.setBlocker(c,null):a.setBlocker(c,"Choose a model size to continue."):a.setBlocker(c,"Choose a transcription engine to continue."):a.setBlocker(c,"Checking which models are already on disk…")});async function be(){o(M,!1),await Promise.all([V(),oe(),R()]),o(M,!0)}qt(()=>(a.registerGate(c,B),E("moonshine_available").then(H=>o(u,H,!0)).catch(()=>o(u,!1)),E("parakeet_available").then(H=>o(v,H,!0)).catch(()=>o(v,!1)),E("accelerator_support").then(H=>{var P;return o(f,(P=H==null?void 0:H.whisper_gpu)!=null?P:null,!0)}).catch(()=>o(f,null)),be(),()=>{a.registerGate(c,null),a.setBlocker(c,null)}));function Ae(H){var Ge,Ze;if(H.id==="remote-openai")return{model:{id:((Ge=t().engine.remote_openai)==null?void 0:Ge.model)||"whisper-1",mb:0,speed:.95,accuracy:.95},rows:[{label:"speed",pct:95,value:"network",color:"var(--vx-cyan-0)",dim:!1},{label:"accuracy",pct:95,value:"server",color:"var(--vx-cyan-2)",dim:!1},{label:"RAM",pct:2,value:"offloaded",color:"var(--vx-gold-1)",dim:!1},{label:"VRAM",pct:0,value:"0 MB",color:"var(--vx-gold-0)",dim:!0}],quiet:Pi(12,.95),noisy:Pi(12,.92),quietPct:"server",noisyPct:"server"};const P=H.id==="parakeet"?t().engine.parakeet.model_size:H.id==="moonshine"?t().engine.moonshine.model_size:t().engine.whisper_cpp.model_size,C=(Ze=H.models.find(Ve=>Ve.id===P))!=null?Ze:H.models[0],ke=H.gpu&&e(ne),je=Math.min(1,C.speed+(ke?.3:0)),ye=ke?C.mb*.3:C.mb,Ie=ke?C.mb*1.1:0;return{model:C,rows:[{label:"speed",pct:Math.round(je*100),value:qh(je),color:"var(--vx-cyan-0)",dim:!1},{label:"accuracy",pct:Math.round(C.accuracy*100),value:Fi(C.accuracy),color:"var(--vx-cyan-2)",dim:!1},{label:"RAM",pct:Math.max(2,Math.min(100,Math.round(ye/3400*100))),value:Tn(ye),color:"var(--vx-gold-1)",dim:!1},{label:"VRAM",pct:Ie?Math.max(2,Math.min(100,Math.round(Ie/3400*100))):0,value:Ie?Tn(Ie):H.gpu?"off":"cpu only",color:"var(--vx-gold-0)",dim:!Ie}],quiet:Pi(12,C.accuracy),noisy:Pi(12,C.accuracy*H.noiseRetention),quietPct:Fi(C.accuracy),noisyPct:Fi(C.accuracy*H.noiseRetention)}}var ue=wg(),j=n(ue),J=i(n(j),2);let Se;var De=n(J);let le;var W=i(De,2),ae=n(W),O=i(n(ae),2);let X;var ve=n(O);{var Me=H=>{var P=Be("UNAVAILABLE · CPU BUILD");d(H,P)},Fe=H=>{var P=Be();w(()=>{var C;return y(P,`ON · ${(C=e(fe))!=null?C:""}`)}),d(H,P)},he=H=>{var P=Be("OFF · CPU");d(H,P)};k(ve,H=>{e(f)?e(ne)?H(Fe,1):H(he,-1):H(Me)})}var re=i(ae,2),we=n(re);{var Je=H=>{var P=Be(`Moves whisper.cpp weights from RAM to your GPU: faster, less RAM, uses VRAM. Moonshine is
+ CPU-native and unaffected.`);d(H,P)},de=H=>{var P=Be(`This build has no GPU backend compiled in, so both engines run on the CPU. The Vulkan
+ download accelerates whisper.cpp; Moonshine is CPU-native either way.`);d(H,P)};k(we,H=>{e(f)?H(Je):H(de,-1)})}var Y=i(j,2);pt(Y,21,()=>Mi,ft,(H,P)=>{const C=ce(()=>Ae(e(P))),ke=ce(()=>e(D)===e(P).id);var je=ug();let ye;var Ie=i(n(je),2),Ge=n(Ie),Ze=n(Ge),Ve=n(Ze),at=i(Ze,2),et=n(at),rt=i(Ge,2),Ee=n(rt),$e=i(rt,2);{var ct=g=>{var A=sg();d(g,A)},vt=g=>{var A=ng();d(g,A)};k($e,g=>{e(P).id==="moonshine"&&!e(u)?g(ct):e(P).id==="parakeet"&&!e(v)&&g(vt,1)})}var nt=i(Ie,2),wt=n(nt);{var dt=g=>{var A=rg(),Pe=i(ht(A),2),Ue=n(Pe),ie=i(n(Ue),2),xe=n(ie),Ce=i(Ue,2),He=i(n(Ce),2),Xe=n(He),Dt=i(Ce,2),zt=i(n(Dt),2);let Ft;var Wt=n(zt);{var Yt=ut=>{var Mt=Be("✔ Verified");d(ut,Mt)},fa=ut=>{var Mt=Be("⚠️ Untested");d(ut,Mt)};k(Wt,ut=>{e(T)?ut(Yt):ut(fa,-1)})}var Gt=i(Pe,2),ma=n(Gt);let Oa;var Ga=n(ma);{var tt=ut=>{var Mt=Be("⚙ Configure Server");d(ut,Mt)},gt=ut=>{var Mt=Be("⚡ Setup & Test");d(ut,Mt)};k(Ga,ut=>{e(T)?ut(tt):ut(gt,-1)})}var It=i(Gt,2);pt(It,21,()=>e(C).rows,ft,(ut,Mt)=>{var Kt=ig();let wa;var oa=n(Kt),La=n(oa),Ka=n(La),Z=i(La),Le=n(Z),Ke=i(oa,2),Re=n(Ke);let Qe;w(()=>{var Jt;wa=Te(Kt,1,"metric svelte-xv54mf",null,wa,{dim:e(Mt).dim}),y(Ka,e(Mt).label),y(Le,e(Mt).value),Qe=na(Re,"",Qe,{width:`${(Jt=e(Mt).pct)!=null?Jt:""}%`,background:e(Mt).color})}),d(ut,Kt)}),w(()=>{var ut,Mt,Kt;mt(ie,"title",((ut=t().engine.remote_openai)==null?void 0:ut.endpoint)||"http://localhost:8000/v1"),y(xe,((Mt=t().engine.remote_openai)==null?void 0:Mt.endpoint)||"http://localhost:8000/v1"),y(Xe,((Kt=t().engine.remote_openai)==null?void 0:Kt.model)||"whisper-1"),Ft=Te(zt,1,"remote-v svelte-xv54mf",null,Ft,{"remote-v-ok":e(T),"remote-v-warn":!e(T)}),Oa=Te(ma,1,"vx-btn vx-btn-sm remote-cfg-btn svelte-xv54mf",null,Oa,{"vx-primary":!e(T)})}),N("click",ma,ut=>{ut.stopPropagation(),ge("remote-openai"),o(q,!0)}),d(g,A)},Et=g=>{var A=cg(),Pe=i(ht(A),2);pt(Pe,21,()=>e(P).models,ft,(ie,xe)=>{var Ce=lg();let He;var Xe=n(Ce),Dt=n(Xe),zt=i(Xe,2),Ft=n(zt);w((Wt,Yt,fa)=>{He=Te(Ce,1,"size svelte-xv54mf",null,He,Wt),y(Dt,e(xe).id),y(Ft,`${Yt!=null?Yt:""}${fa!=null?fa:""}`)},[()=>({on:I(e(P).id,e(xe))}),()=>Tn(e(xe).mb),()=>L(e(P).id,e(xe))?" ✔":""]),N("click",Ce,Wt=>{Wt.stopPropagation(),ee(e(P).id,e(xe))}),d(ie,Ce)});var Ue=i(Pe,2);pt(Ue,21,()=>e(C).rows,ft,(ie,xe)=>{var Ce=og();let He;var Xe=n(Ce),Dt=n(Xe),zt=n(Dt),Ft=i(Dt),Wt=n(Ft),Yt=i(Xe,2),fa=n(Yt);let Gt;w(()=>{var ma;He=Te(Ce,1,"metric svelte-xv54mf",null,He,{dim:e(xe).dim}),y(zt,e(xe).label),y(Wt,e(xe).value),Gt=na(fa,"",Gt,{width:`${(ma=e(xe).pct)!=null?ma:""}%`,background:e(xe).color})}),d(ie,Ce)}),d(g,A)};k(wt,g=>{e(P).id==="remote-openai"?g(dt):g(Et,-1)})}var jt=i(nt,2),ia=n(jt),ra=n(ia),bt=i(n(ra)),ea=n(bt),Lt=i(ra,2);pt(Lt,21,()=>e(C).quiet,ft,(g,A)=>{var Pe=dg();let Ue;w(()=>{var ie;return Ue=na(Pe,"",Ue,{height:`${(ie=e(A).h)!=null?ie:""}%`,opacity:e(A).o})}),d(g,Pe)});var Ht=i(ia,2),ta=n(Ht),Oe=i(n(ta)),qe=n(Oe),$=i(ta,2);pt($,21,()=>e(C).noisy,ft,(g,A)=>{var Pe=vg();let Ue;w(()=>{var ie;return Ue=na(Pe,"",Ue,{height:`${(ie=e(A).h)!=null?ie:""}%`,opacity:e(A).o})}),d(g,Pe)}),w(()=>{ye=Te(je,1,"vx-card engine-card svelte-xv54mf",null,ye,{"vx-on":e(ke)}),mt(je,"aria-checked",e(ke)),y(Ve,e(P).glyph),y(et,e(P).name),y(Ee,e(P).tagline),y(ea,e(C).quietPct),y(qe,e(C).noisyPct)}),N("click",je,()=>{ge(e(P).id),e(P).id==="remote-openai"&&o(q,!0)}),N("keydown",je,g=>{(g.key==="Enter"||g.key===" ")&&(g.preventDefault(),ge(e(P).id),e(P).id==="remote-openai"&&o(q,!0))}),d(H,je)});var U=i(Y,2),te=n(U);{var G=H=>{var P=pg(),C=i(n(P));w(()=>{var ke;return y(C,` Downloading ${(ke=e(_))!=null?ke:""} — this can take a few minutes`)}),d(H,P)},_e=H=>{var P=fg(),C=n(P);w(()=>{var ke;return y(C,`✕ Download failed: ${(ke=e(x))!=null?ke:""}`)}),d(H,P)},me=H=>{var P=_g();d(H,P)},pe=H=>{var P=xi(),C=ht(P);{var ke=ye=>{var Ie=hg(),Ge=n(Ie);w(()=>{var Ze;return y(Ge,`✓ Remote engine connected (${(Ze=e(Q))!=null?Ze:""})`)}),d(ye,Ie)},je=ye=>{var Ie=gg();d(ye,Ie)};k(C,ye=>{e(T)?ye(ke):ye(je,-1)})}d(H,P)},ze=H=>{var P=mg(),C=n(P);w(()=>{var ke;return y(C,`✓ ${(ke=e(Q))!=null?ke:""} is on disk and ready`)}),d(H,P)},Ye=H=>{var P=bg();d(H,P)},st=H=>{var P=yg(),C=n(P);w(()=>{var ke;return y(C,`↓ ${(ke=e(Q))!=null?ke:""} will download when you continue`)}),d(H,P)};k(te,H=>{e(_)?H(G):e(x)?H(_e,1):e(M)?e(D)==="remote-openai"?H(pe,3):e(z)?H(ze,4):!Ne.engineChosen||!Ne.modelChosen?H(Ye,5):H(st,-1):H(me,2)})}var it=i(U,2);ag(it,{onSuccess:()=>{o(T,!0)},get isOpen(){return e(q)},set isOpen(H){o(q,H,!0)}}),w(()=>{Se=Te(J,1,"vx-card gpu-toggle svelte-xv54mf",null,Se,{"vx-on":e(ne)}),J.disabled=!e(f),le=Te(De,1,"switch svelte-xv54mf",null,le,{on:e(ne)}),X=Te(O,1,"state svelte-xv54mf",null,X,{on:e(ne)})}),N("click",J,K),d(s,ue),St(),l()}Qt(["click","keydown"]);var xg=p(""),Tg=p(""),Sg=p(''),Eg=p('
'),Cg=p(''),Mg=p('+'),Pg=p("
",1),Ag=p('
'),Dg=p(' Asking…',1),zg=p('
'),Ig=p('
'),Og=p(`
// 02 · first key binding
How do you want to start talking?
Pick a gesture, then record the keys. Taps keep your hands free while speaking; holds can't be
+ left running by accident. Double-taps avoid clashes with shortcuts you already use.
`);function Lg(s,a){Tt(a,!0);const t=2;let r=S(null),l=S(!1),c=S(null);const u=ce(()=>{var W,ae;return(ae=(W=e(r))==null?void 0:W.supported_gestures)!=null&&ae.length?xn.filter(O=>e(r).supported_gestures.includes(O.id)):xn}),v=ce(()=>xn.length-e(u).length),f=ce(()=>{var W;return((W=e(r))==null?void 0:W.is_active)===!0}),h=ce(()=>!!Ne.combo&&Ne.combo.length>0&&e(r)!==null&&!e(r).is_active),b=ce(()=>Ne.recording&&Vr(Ne.held)?"Keep holding and add a regular key — modifiers alone cannot be a shortcut.":null);async function m(){try{o(r,await E("check_hotkey_status"),!0),e(r).is_active&&Ne.clearIssue("shortcut-register")}catch(W){console.error("Wizard: failed to read hotkey status:",W)}}function _(){Ne.recording=!0,Ne.held=[],Ne.captureHint=null,E("set_hotkeys_inhibited",{inhibited:!0}).catch(()=>{})}function x(){Ne.recording=!1,Ne.held=[],E("set_hotkeys_inhibited",{inhibited:!1}).catch(()=>{})}async function M(W){var O;if(W.length===0)return;let ae;try{ae=await E("check_hotkey_keys",{keys:W})}catch(X){console.error("Wizard: hotkey validation failed:",X),Ne.combo=[...W];return}ae.accepted?(Ne.combo=[...W],Ne.captureHint=null,await D()):Ne.captureHint=(O=ae.message)!=null?O:"This key combination cannot be used as a shortcut. Try another."}function q(W){if(!Ne.recording)return;W.preventDefault(),W.stopPropagation();const ae=il(W.key,W.code);if(W.key==="Escape"&&Ne.held.length===0){x();return}Ne.held.includes(ae)||(Ne.held=[...Ne.held,ae])}function T(W){if(!Ne.recording)return;W.preventDefault(),W.stopPropagation();const ae=[...Ne.held];x(),M(ae)}async function D(){var W;try{await Ne.saveBinding()}catch(ae){console.error("Wizard: failed to save binding:",ae),o(c,`Could not save the binding: ${ae}`),Ne.recordIssue({id:"binding-save",step:t,title:"The hotkey binding could not be written — no shortcut will start dictation.",detail:`keys=${((W=Ne.combo)!=null?W:[]).join("+")} gesture=${Ne.gesture}
+${ae}`});return}Ne.clearIssue("binding-save"),await m()}async function se(){var W,ae,O,X,ve,Me;o(l,!0),o(c,null);try{o(r,await E("approve_shortcuts"),!0)}catch(Fe){o(c,`${Fe}`),Ne.recordIssue({id:"shortcut-register",step:t,title:"Your desktop refused to register the global shortcut.",detail:`backend=${(ae=(W=e(r))==null?void 0:W.backend)!=null?ae:"unknown"} portal_refused=${(X=(O=e(r))==null?void 0:O.portal_refused)!=null?X:"?"}
+portal_error=${(Me=(ve=e(r))==null?void 0:ve.portal_error)!=null?Me:"(none)"}
+${Fe}`}),await m()}finally{o(l,!1)}}async function ne(){try{await E("open_shortcut_settings")}catch(W){o(c,`${W}`)}}pa(()=>{let W=null;Ne.recording?W="Press the keys you want to use.":!Ne.combo||Ne.combo.length===0?W="Record a key combination first.":e(h)&&(W="Register the shortcut with your desktop to continue."),a.setBlocker(t,W)}),pa(()=>{const W=e(u);W.length>0&&!W.some(ae=>ae.id===Ne.gesture)&&(Ne.gesture=W[0].id)}),qt(()=>{a.registerGate(t,async()=>{var O;return await D(),((O=e(r))==null?void 0:O.is_active)!==!1}),Ne.loadBinding(),m();const W=ha("setup-status-changed",()=>void m()),ae=setInterval(()=>{Ne.recording||m()},3e3);return window.addEventListener("keydown",q,!0),window.addEventListener("keyup",T,!0),()=>{clearInterval(ae),W.then(O=>O()).catch(()=>{}),window.removeEventListener("keydown",q,!0),window.removeEventListener("keyup",T,!0),Ne.recording&&x(),a.registerGate(t,null),a.setBlocker(t,null)}});const fe=ce(()=>{var W,ae,O,X;return Ne.recording?{label:"listening for keys",hint:(ae=(W=Ne.captureHint)!=null?W:e(b))!=null?ae:"Hold one or more modifiers, then press a key. Esc to cancel.",tone:"rec"}:Ne.combo&&Ne.combo.length>0?{label:"binding captured",hint:(O=Ne.captureHint)!=null?O:"Click anywhere in this area to record a different combination.",tone:"done"}:{label:"click to record",hint:(X=Ne.captureHint)!=null?X:"Needs at least one modifier (Ctrl, Alt, Shift or Super) plus a regular key — e.g. Super + Space.",tone:"idle"}});var Q=Og(),z=i(n(Q),2),I=n(z),L=n(I);pt(L,17,()=>e(u),ft,(W,ae)=>{const O=ce(()=>Ne.gesture===e(ae).id);var X=Sg();let ve;var Me=n(X),Fe=n(Me),he=n(Fe),re=i(Fe,2),we=n(re),Je=i(Me,2),de=n(Je),Y=i(n(de),2);pt(Y,21,()=>e(ae).key,ft,(G,_e)=>{var me=ce(()=>pl(e(_e),2));let pe=()=>e(me)[0],ze=()=>e(me)[1];var Ye=xg();let st,it;w(()=>{st=Te(Ye,1,"svelte-1fbfhk3",null,st,{on:ze()&&e(O),lit:ze()}),it=na(Ye,"",it,{flex:pe()})}),d(G,Ye)});var U=i(de,2),te=i(n(U),2);pt(te,21,()=>e(ae).mic,ft,(G,_e)=>{var me=ce(()=>pl(e(_e),2));let pe=()=>e(me)[0],ze=()=>e(me)[1];var Ye=Tg();let st,it;w(()=>{st=Te(Ye,1,"svelte-1fbfhk3",null,st,{on:ze()&&e(O),lit:ze()}),it=na(Ye,"",it,{flex:pe()})}),d(G,Ye)}),w(()=>{ve=Te(X,1,"vx-card gesture svelte-1fbfhk3",null,ve,{"vx-on":e(O)}),y(he,e(ae).name),y(we,e(ae).desc)}),N("click",X,()=>Ne.gesture=e(ae).id),d(W,X)});var ge=i(L,2);{var ee=W=>{var ae=Eg(),O=n(ae);w(()=>{var X;return y(O,`${(X=e(v))!=null?X:""} gesture${e(v)===1?"":"s"} hidden — this desktop's shortcut
+ backend only tells VoxCtrl that a shortcut fired, so it cannot time a hold.`)}),d(W,ae)};k(ge,W=>{e(v)>0&&W(ee)})}var K=i(I,2),V=n(K);let oe;var R=n(V);{var B=W=>{var ae=Cg();d(W,ae)};k(R,W=>{Ne.recording&&W(B)})}var be=i(R,2),Ae=i(n(be),1,!0),ue=i(be,2);pt(ue,21,()=>Ne.displayKeys,ft,(W,ae,O)=>{var X=Pg(),ve=ht(X);let Me;var Fe=n(ve),he=i(ve,2);{var re=we=>{var Je=Mg();d(we,Je)};k(he,we=>{O{Me=Te(ve,1,"vx-keycap",null,Me,{"vx-hot":Ne.recording||e(fe).tone==="done"}),y(Fe,we)},[()=>dl(e(ae))]),d(W,X)});var j=i(ue,2);let J;var Se=n(j),De=i(V,2);{var le=W=>{var ae=Ig();let O;var X=n(ae),ve=n(X),Me=i(X,2),Fe=n(Me),he=n(Fe),re=i(Fe,2),we=n(re);{var Je=me=>{var pe=Be("The binding is registered system-wide. Continue to choose an overlay.");d(me,pe)},de=me=>{var pe=Be();w(()=>y(pe,e(r).portal_error)),d(me,pe)},Y=me=>{var pe=Be(`Wayland desktops ask you to confirm global shortcuts. Click below and approve the
+ dialog your desktop shows — you come straight back here.`);d(me,pe)};k(we,me=>{var pe;e(f)?me(Je):(pe=e(r))!=null&&pe.portal_error?me(de,1):me(Y,-1)})}var U=i(re,2);{var te=me=>{var pe=Ag(),ze=n(pe);w(()=>y(ze,e(c))),d(me,pe)};k(U,me=>{e(c)&&me(te)})}var G=i(Me,2);{var _e=me=>{var pe=zg(),ze=n(pe),Ye=i(ze,2),st=n(Ye);{var it=P=>{var C=Dg();d(P,C)},H=P=>{var C=Be("Register →");d(P,C)};k(st,P=>{e(l)?P(it):P(H,-1)})}w(()=>Ye.disabled=e(l)),N("click",ze,ne),N("click",Ye,se),d(me,pe)};k(G,me=>{e(f)||me(_e)})}w(()=>{var me,pe;O=Te(ae,1,"sys svelte-1fbfhk3",null,O,{ok:e(f)}),y(ve,e(f)?"✓":"⌬"),y(he,e(f)?`Shortcuts are live (${(pe=(me=e(r))==null?void 0:me.backend)!=null?pe:"ready"})`:"Your desktop still needs to approve the shortcut")}),d(W,ae)};k(De,W=>{Ne.combo&&Ne.combo.length>0&&W(le)})}w(()=>{oe=Te(V,1,"recorder svelte-1fbfhk3",null,oe,{rec:e(fe).tone==="rec",done:e(fe).tone==="done"}),y(Ae,e(fe).label),J=Te(j,1,"rec-hint svelte-1fbfhk3",null,J,{bad:!!Ne.captureHint}),y(Se,e(fe).hint)}),N("click",V,()=>Ne.recording?x():_()),d(s,Q),St()}Qt(["click"]);const Rg="/assets/blue_wave-DGfyQFFo.webm",Ng="/assets/mono_bars-1wA0h3Fz.webm",Vg="/assets/pulse-Cdnh-rAb.webm",Fg="/assets/spectrum-CLEHMZrI.webm",Bg="/assets/terminal-CvV88uWw.webm",qg="/assets/vinyl-BG1f8NO1.webm",Kg="/assets/voice_card-BZZeHAB9.webm",Ug="/assets/waveform-DUI2x_EP.webm",jg="/assets/blue_wave-OqjJ-fxD.webp",Hg="/assets/mono_bars-CPLx02Ku.webp",Wg="/assets/pulse-ESYJH4j2.webp",Yg="/assets/spectrum-DV9agKUG.webp",$g="/assets/terminal-DhrByqCl.webp",Gg="/assets/vinyl-BfHn3C6g.webp",Jg="/assets/voice_card-QnCU8RiM.webp",Xg="/assets/waveform-B5-owbWT.webp";var Zg=p(''),Qg=p(''),em=Oo(''),tm=p('
The overlay appears the moment your hotkey fires and shows live mic level plus the active
target — so you know VoxCtrl is hearing you, and where the words are going. Turn it off for
- a silent setup.
Click into the box, then your binding and speak. Your words land where
the cursor is.
▸ test.txt
Nothing happening? The overlay and tray icon show whether VoxCtrl heard the key. You can
- continue and come back to this from Settings → Hotkeys at any time.
'),Om=p('Needs a HuggingFace access token — enter one above to unlock this voice.'),Lm=p(''),Rm=p(`Already downloaded — the token is only needed to fetch the weights, so this voice
+ continue and come back to this from Settings → Hotkeys at any time.
'),Om=p('Needs a HuggingFace access token — enter one above to unlock this voice.'),Lm=p(''),Rm=p(`Already downloaded — the token is only needed to fetch the weights, so this voice
works without one.`),Nm=p('This build was compiled without the `inflect-micro` feature, so this engine cannot\n synthesize.'),Vm=p('
'),Fm=p('
'),Bm=p(`
// 05 · text to speech · optional
Should VoxCtrl talk back?
Agents can stream replies back through a response pipe and VoxCtrl speaks them aloud. Richer
- voices need bigger models and more time per sentence; lighter engines answer instantly.
HuggingFace access tokenoptional — speeds up downloads if you have one
`);function qm(s,a){Tt(a,!0);const t=()=>Zt(Ot,"$config",r),[r,l]=Ea(),c=5,u=ce(()=>t().tts.enabled),v=ce(()=>t().tts.engine),f=ce(()=>{var g;return(g=cs.find(P=>P.id===e(v)))!=null?g:cs[0]});let h=S(yt({espeak:!0})),b=S(yt({})),m=S(null),_=S(yt({})),x=S(!0),A=S(null);const q=ce(()=>!!e(A)),T=ce(()=>{var g,P;return(P=e(A))!=null?P:((g=t().tts.hf_token)!=null?g:"").trim()}),D=ce(()=>e(T).length>0),se=cs.filter(g=>g.needsHfToken);function ne(g){e(q)||(o(Q,!1),fs(P=>{P.tts.hf_token=g.trim()?g.trim():null}))}function fe(g){const P=cs.find(Me=>Me.id===g);return!!(P!=null&&P.needsHfToken)&&!e(D)&&!e(h)[g]}let Q=S(!1);const z="hf-token-rejected";function I(g){return`${g}`.toLowerCase().includes(z)}let L=S(null),ge=S(null);const ee=Ho(12);let j=null,V=null,oe=0,R=!1;const B=300,be=1500,Pe=3e4;function ue(){j&&(clearTimeout(j),j=null),V&&(clearInterval(V),V=null)}function K(){o(L,null),ue()}async function J(){if(!e(L))return;let g;try{g=await E("get_status")}catch(P){console.error("Wizard: status poll failed:",P);return}if(g&&ga.set(g),g!=null&&g.speaking){R=!0;return}(R||Date.now()-oe>be)&&K()}function Se(g,P){const Me={...e(_)};P?Me[g]=P:delete Me[g],o(_,Me,!0)}async function De(g){var Me,Ue,ie,xe,Ce,He;const P=bn(Ot);try{switch(g){case"espeak":return!0;case"piper":return await E("check_voice_downloaded",{voiceName:P.tts.voice,voiceDir:P.tts.voice_dir});case"pocket_tts":return await E("check_pocket_tts_ready",{voice:P.tts.pocket_tts.voice,voiceDir:P.tts.pocket_tts.voice_dir});case"inflect_micro":return await E("check_inflect_micro_downloaded",{modelDir:(Ue=(Me=P.tts.inflect_micro)==null?void 0:Me.model_dir)!=null?Ue:""});case"breeze_tts_2":return await E("check_breeze_tts_2_ready",{modelDir:(xe=(ie=P.tts.breeze_tts_2)==null?void 0:ie.model_dir)!=null?xe:""});case"vox_cpm_2":return await E("check_vox_cpm_2_ready",{modelDir:(He=(Ce=P.tts.vox_cpm_2)==null?void 0:Ce.model_dir)!=null?He:""})}}catch(Xe){return console.error("Wizard: TTS readiness check failed for",g,Xe),!1}}async function le(){await Promise.all(cs.map(async g=>{o(b,{...e(b),[g.id]:!0},!0);const P=await De(g.id);o(h,{...e(h),[g.id]:P},!0),o(b,{...e(b),[g.id]:!1},!0)}))}async function W(g){var Me,Ue,ie,xe,Ce,He,Xe,Dt,zt,Ft,Wt,$t;if(e(m))return;o(m,g,!0),Se(g,null);const P=bn(Ot);try{switch(g){case"piper":await E("download_voice",{voiceName:P.tts.voice,voiceDir:P.tts.voice_dir});break;case"pocket_tts":await E("download_pocket_tts",{voice:(Me=P.tts.pocket_tts)==null?void 0:Me.voice,voiceDir:(Ue=P.tts.pocket_tts)==null?void 0:Ue.voice_dir,hfToken:P.tts.hf_token});break;case"inflect_micro":await E("download_inflect_micro",{modelDir:(xe=(ie=P.tts.inflect_micro)==null?void 0:ie.model_dir)!=null?xe:""});break;case"breeze_tts_2":await E("download_breeze_tts_2",{modelDir:(He=(Ce=P.tts.breeze_tts_2)==null?void 0:Ce.model_dir)!=null?He:"",hfToken:P.tts.hf_token});break;case"vox_cpm_2":await E("download_vox_cpm_2",{modelDir:(Dt=(Xe=P.tts.vox_cpm_2)==null?void 0:Xe.model_dir)!=null?Dt:"",hfToken:P.tts.hf_token});break;case"espeak":break}o(Q,!1),o(h,{...e(h),[g]:!0},!0),Ne.clearIssue(`tts-download-${g}`)}catch(fa){const Yt=cs.find(Oa=>Oa.id===g),ma=I(fa);ma&&o(Q,!0),Se(g,ma?`HuggingFace did not accept that access token, so ${(zt=Yt==null?void 0:Yt.name)!=null?zt:g} could not be downloaded. Check the token is a valid read token, and that the same account has accepted the licence at ${(Ft=Yt==null?void 0:Yt.licenceUrl)!=null?Ft:"huggingface.co"}.`:`${fa}`),Ne.recordIssue({id:`tts-download-${g}`,step:c,title:ma?`${(Wt=Yt==null?void 0:Yt.name)!=null?Wt:g} could not be downloaded — HuggingFace did not accept the access token.`:`${($t=Yt==null?void 0:Yt.name)!=null?$t:g} could not be downloaded — speech output will stay silent.`,detail:`engine=${g}
-${fa}`})}finally{o(m,null)}}const ae=["pocket_tts","breeze_tts_2","vox_cpm_2"],O=ce(()=>ae.includes(e(v))),X=ce(()=>e(v)==="pocket_tts"?t().tts.pocket_tts.gpu:e(v)==="breeze_tts_2"?t().tts.breeze_tts_2.gpu:e(v)==="vox_cpm_2"?t().tts.vox_cpm_2.gpu:!1);function ve(g){fs(P=>{e(v)==="pocket_tts"?P.tts.pocket_tts.gpu=g:e(v)==="breeze_tts_2"?P.tts.breeze_tts_2.gpu=g:e(v)==="vox_cpm_2"&&(P.tts.vox_cpm_2.gpu=g)})}function Ae(g){fe(g)||fs(P=>{P.tts.enabled=!0,P.tts.engine=g})}function Fe(g){fs(P=>{P.tts.enabled=g})}async function he(g){if(e(L)){K(),E("stop_tts").catch(()=>{});return}Ae(g),o(ge,null),o(L,g,!0),oe=Date.now(),R=!1,ue(),V=setInterval(()=>void J(),B),j=setTimeout(()=>{K(),o(ge,"The sample never finished playing. The engine may have failed silently — check Settings → TTS, or try another voice.")},Pe);const P=bn(Ot),Me=cs.find(ie=>ie.id===g),Ue=g==="piper"?P.tts.voice:g==="pocket_tts"?P.tts.pocket_tts.voice:null;try{await E("save_config",{newConfig:P}),await E("speak_text",{text:`Hi this is ${Me.name} speaking from VoxCtrl`,voice:Ue})}catch(ie){o(ge,`${ie}`),K(),Ne.recordIssue({id:`tts-speak-${g}`,step:c,title:`${Me.name} failed to speak the sample.`,detail:`engine=${g} voice=${Ue!=null?Ue:"(fixed)"}
-${ie}`})}}pa(()=>{var g;if(!e(u)){a.setBlocker(c,null);return}if(e(m)){a.setBlocker(c,`Downloading ${(g=cs.find(P=>P.id===e(m)))==null?void 0:g.name}…`);return}if(fe(e(v))){a.setBlocker(c,"Enter a HuggingFace access token, or pick a voice that does not need one.");return}if(e(v)==="inflect_micro"&&!e(x)){a.setBlocker(c,"This build has no Inflect Micro engine — pick another voice or skip.");return}a.setBlocker(c,e(h)[e(v)]?null:"Download the voice you picked, or turn speech output off to continue.")}),qt(()=>{le(),E("hf_token_env").then(P=>o(A,P&&P.trim()?P.trim():null,!0)).catch(()=>o(A,null)),E("inflect_micro_available").then(P=>o(x,P,!0)).catch(()=>o(x,!1));const g=[ha("tts-playback-end",()=>K()),ha("tts-error",P=>{o(ge,P.payload,!0),K(),Ne.recordIssue({id:"tts-runtime",step:c,title:"The text-to-speech engine reported an error while speaking.",detail:`engine=${bn(Ot).tts.engine}
-${P.payload}`})})];return()=>{a.setBlocker(c,null),ue();for(const P of g)P.then(Me=>Me()).catch(()=>{});E("stop_tts").catch(()=>{})}});const re=ce(()=>!!e(h)[e(v)]),we=ce(()=>fe(e(v))),Je=ce(()=>e(v)==="inflect_micro"&&!e(x)),de=ce(()=>e(re)&&!e(Je)&&!e(we)&&!e(m));var $=Bm(),U=n($),te=i(n(U),2),Y=n(te);let _e;var me=i(Y,2);let pe;var ze=i(U,2),$e=n(ze),st=n($e);let it;var H=n(st);{var M=g=>{var P=ym(),Me=i(ht(P),4);pt(Me,21,()=>ee,ft,(Ue,ie)=>{var xe=bm();let Ce;w(()=>{var He,Xe;return Ce=na(xe,"",Ce,{"animation-duration":`${(He=e(ie).d)!=null?He:""}s`,"animation-delay":`${(Xe=e(ie).dl)!=null?Xe:""}s`})}),d(Ue,xe)}),d(g,P)},C=g=>{var P=wm();d(g,P)};k(H,g=>{e(L)?g(M):g(C,-1)})}var ke=i(st,2),Ke=n(ke),ye=n(Ke),Ie=i(Ke,2),Ye=n(Ie);{var Ze=g=>{var P=km();d(g,P)},Ve=g=>{var P=xm();d(g,P)},at=g=>{var P=Tm();d(g,P)},et=g=>{var P=Sm();d(g,P)},rt=g=>{var P=Em();d(g,P)};k(Ye,g=>{e(L)?g(Ze):e(m)?g(Ve,1):e(we)?g(at,2):e(re)?g(et,3):g(rt,-1)})}var Ee=i($e,2);let Ge;var ct=i(n(Ee),2),vt=n(ct),nt=i(vt,2);let wt;var dt=n(nt);{var Et=g=>{var P=Be("did not accept this token");d(g,P)},Kt=g=>{var P=Be("HF_TOKEN environment variable");d(g,P)},ia=g=>{var P=Be("✓ token saved");d(g,P)},ra=g=>{var P=Be("token required for gated voices");d(g,P)};k(dt,g=>{e(Q)?g(Et):e(q)?g(Kt,1):e(D)?g(ia,2):g(ra,-1)})}var bt=i(ze,2);{var ea=g=>{var P=Cm(),Me=i(n(P));w(()=>{var Ue;return y(Me,` ${(Ue=e(f).name)!=null?Ue:""} weights are released under a research/non-commercial license. Commercial
- use requires a separate license from the model's publisher.`)}),d(g,P)};k(bt,g=>{e(u)&&e(f).nonCommercial&&!e(h)[e(v)]&&g(ea)})}var Lt=i(bt,2);{var Ht=g=>{var P=Am(),Me=n(P),Ue=i(Me,2),ie=n(Ue);w(()=>{var xe;Od(Me,e(X)),y(ie,`Vulkan GPU acceleration for ${(xe=e(f).name)!=null?xe:""}`)}),N("change",Me,xe=>ve(xe.currentTarget.checked)),d(g,P)};k(Lt,g=>{e(u)&&e(O)&&g(Ht)})}var ta=i(Lt,2);let Oe;pt(ta,21,()=>cs,ft,(g,P)=>{const Me=ce(()=>e(u)&&e(v)===e(P).id),Ue=ce(()=>!!e(h)[e(P).id]),ie=ce(()=>e(m)===e(P).id),xe=ce(()=>e(P).id==="inflect_micro"&&!e(x)),Ce=ce(()=>fe(e(P).id));var He=Vm();let Xe;var Dt=n(He),zt=n(Dt),Ft=n(zt),Wt=n(Ft),$t=i(Ft,2),fa=n($t),Yt=i(zt,2),ma=n(Yt),Oa=n(ma),Ya=i(Dt,2),tt=n(Ya);{var gt=Re=>{var Qe=Mm();d(Re,Qe)},It=Re=>{var Qe=Pm();d(Re,Qe)},ut=Re=>{var Qe=Dm(),Jt=n(Qe);w(Gt=>y(Jt,`✓ Downloaded (${Gt!=null?Gt:""})`),[()=>Tn(e(P).mb)]),d(Re,Qe)},At=Re=>{var Qe=zm(),Jt=n(Qe);w(Gt=>{Qe.disabled=!!e(m)||e(xe)||e(Ce),y(Jt,`↓ Download ${Gt!=null?Gt:""}`)},[()=>Tn(e(P).mb)]),N("click",Qe,Gt=>{Gt.stopPropagation(),W(e(P).id)}),d(Re,Qe)};k(tt,Re=>{e(P).mb===0?Re(gt):e(ie)?Re(It,1):e(Ue)?Re(ut,2):Re(At,-1)})}var jt=i(Ya,2);pt(jt,21,()=>[{label:"quality",pct:Math.round(e(P).quality*100),value:Fi(e(P).quality),color:"var(--vx-cyan-0)"},{label:"speed",pct:Math.round(e(P).speed*100),value:jh(e(P).speed),color:"var(--vx-cyan-2)"},{label:"model size",pct:Bh(e(P).mb),value:Tn(e(P).mb),color:"var(--vx-gold-1)"}],ft,(Re,Qe)=>{var Jt=Im(),Gt=n(Jt),ka=n(Gt),xa=n(ka),Ta=i(ka),la=n(Ta),_a=i(Gt,2),Pa=n(_a);let Ca;w(()=>{var Ut;y(xa,e(Qe).label),y(la,e(Qe).value),Ca=na(Pa,"",Ca,{width:`${(Ut=e(Qe).pct)!=null?Ut:""}%`,background:e(Qe).color})}),d(Re,Jt)});var wa=i(jt,2),oa=n(wa);{var La=Re=>{var Qe=Om();d(Re,Qe)},ja=Re=>{var Qe=Lm(),Jt=n(Qe);w(()=>y(Jt,e(_)[e(P).id])),d(Re,Qe)},Z=Re=>{var Qe=Rm();d(Re,Qe)},Le=Re=>{var Qe=Nm();d(Re,Qe)},je=Re=>{var Qe=Be();w(()=>y(Qe,e(P).note)),d(Re,Qe)};k(oa,Re=>{e(Ce)?Re(La):e(_)[e(P).id]?Re(ja,1):e(P).needsHfToken&&!e(D)&&e(Ue)?Re(Z,2):e(xe)?Re(Le,3):Re(je,-1)})}w(()=>{Xe=Te(He,1,"vx-card card svelte-1yghr3b",null,Xe,{"vx-on":e(Me),locked:e(Ce)}),mt(He,"aria-disabled",e(Ce)),mt(He,"aria-checked",e(Me)),y(Wt,e(P).name),y(fa,e(P).kind),y(Oa,e(Me)?"✓":"")}),N("click",He,()=>Ae(e(P).id)),N("keydown",He,Re=>{(Re.key==="Enter"||Re.key===" ")&&(Re.preventDefault(),Ae(e(P).id))}),d(g,He)});var qe=i(ta,2);{var G=g=>{var P=Fm(),Me=n(P);w(()=>{var Ue;return y(Me,`⚠ ${(Ue=e(ge))!=null?Ue:""}`)}),d(g,P)};k(qe,g=>{e(ge)&&g(G)})}w(g=>{var P;_e=Te(Y,1,"vx-card mode svelte-1yghr3b",null,_e,{"vx-on":e(u)}),pe=Te(me,1,"vx-card mode svelte-1yghr3b",null,pe,{"off-on":!e(u)}),it=Te(st,1,"vx-btn audition-btn svelte-1yghr3b",null,it,{playing:!!e(L)}),st.disabled=!e(de)&&!e(L),mt(st,"title",e(L)?"Stop":e(re)?"Play a sample":e(we)?"Needs a HuggingFace access token":"Download this voice first"),y(ye,`Audition: ${(P=e(f).name)!=null?P:""}`),Ge=Te(Ee,1,"hf-bar svelte-1yghr3b",null,Ge,g),vt.readOnly=e(q),mt(vt,"title",e(q)?"Set by the HF_TOKEN environment variable":"Enter a HuggingFace read token for gated models"),sr(vt,e(T)),wt=Te(nt,1,"hf-state svelte-1yghr3b",null,wt,{ok:e(D)&&!e(Q),bad:e(Q)}),Oe=Te(ta,1,"grid svelte-1yghr3b",null,Oe,{muted:!e(u)})},[()=>({needed:e(u)&&(e(Q)||se.some(g=>fe(g.id)))})]),N("click",Y,()=>Fe(!0)),N("click",me,()=>Fe(!1)),N("click",st,()=>{e(L)?(K(),E("stop_tts").catch(()=>{})):he(e(v))}),N("input",vt,g=>ne(g.currentTarget.value)),d(s,$),St(),l()}Qt(["click","input","change","keydown"]);const jm="/assets/record_off-DqBdWxcg.png";var Um=p('VoxCtrl is ready.',1),Km=p('Setup is incomplete.',1),Hm=p('
'),Wm=Oo(''),$m=p('
'),Gm=p('
click me↓
'),Ym=p(`
where everything lives
Every choice is editable
Nothing you picked here is locked in. Settings holds the same options plus the ones the
+ voices need bigger models and more time per sentence; lighter engines answer instantly.
HuggingFace access tokenoptional — speeds up downloads if you have one
`);function qm(s,a){Tt(a,!0);const t=()=>Zt(Ot,"$config",r),[r,l]=Ea(),c=5,u=ce(()=>t().tts.enabled),v=ce(()=>t().tts.engine),f=ce(()=>{var g;return(g=cs.find(A=>A.id===e(v)))!=null?g:cs[0]});let h=S(yt({espeak:!0})),b=S(yt({})),m=S(null),_=S(yt({})),x=S(!0),M=S(null);const q=ce(()=>!!e(M)),T=ce(()=>{var g,A;return(A=e(M))!=null?A:((g=t().tts.hf_token)!=null?g:"").trim()}),D=ce(()=>e(T).length>0),se=cs.filter(g=>g.needsHfToken);function ne(g){e(q)||(o(Q,!1),fs(A=>{A.tts.hf_token=g.trim()?g.trim():null}))}function fe(g){const A=cs.find(Pe=>Pe.id===g);return!!(A!=null&&A.needsHfToken)&&!e(D)&&!e(h)[g]}let Q=S(!1);const z="hf-token-rejected";function I(g){return`${g}`.toLowerCase().includes(z)}let L=S(null),ge=S(null);const ee=Ho(12);let K=null,V=null,oe=0,R=!1;const B=300,be=1500,Ae=3e4;function ue(){K&&(clearTimeout(K),K=null),V&&(clearInterval(V),V=null)}function j(){o(L,null),ue()}async function J(){if(!e(L))return;let g;try{g=await E("get_status")}catch(A){console.error("Wizard: status poll failed:",A);return}if(g&&ga.set(g),g!=null&&g.speaking){R=!0;return}(R||Date.now()-oe>be)&&j()}function Se(g,A){const Pe={...e(_)};A?Pe[g]=A:delete Pe[g],o(_,Pe,!0)}async function De(g){var Pe,Ue,ie,xe,Ce,He;const A=bn(Ot);try{switch(g){case"espeak":return!0;case"piper":return await E("check_voice_downloaded",{voiceName:A.tts.voice,voiceDir:A.tts.voice_dir});case"pocket_tts":return await E("check_pocket_tts_ready",{voice:A.tts.pocket_tts.voice,voiceDir:A.tts.pocket_tts.voice_dir});case"inflect_micro":return await E("check_inflect_micro_downloaded",{modelDir:(Ue=(Pe=A.tts.inflect_micro)==null?void 0:Pe.model_dir)!=null?Ue:""});case"breeze_tts_2":return await E("check_breeze_tts_2_ready",{modelDir:(xe=(ie=A.tts.breeze_tts_2)==null?void 0:ie.model_dir)!=null?xe:""});case"vox_cpm_2":return await E("check_vox_cpm_2_ready",{modelDir:(He=(Ce=A.tts.vox_cpm_2)==null?void 0:Ce.model_dir)!=null?He:""})}}catch(Xe){return console.error("Wizard: TTS readiness check failed for",g,Xe),!1}}async function le(){await Promise.all(cs.map(async g=>{o(b,{...e(b),[g.id]:!0},!0);const A=await De(g.id);o(h,{...e(h),[g.id]:A},!0),o(b,{...e(b),[g.id]:!1},!0)}))}async function W(g){var Pe,Ue,ie,xe,Ce,He,Xe,Dt,zt,Ft,Wt,Yt;if(e(m))return;o(m,g,!0),Se(g,null);const A=bn(Ot);try{switch(g){case"piper":await E("download_voice",{voiceName:A.tts.voice,voiceDir:A.tts.voice_dir});break;case"pocket_tts":await E("download_pocket_tts",{voice:(Pe=A.tts.pocket_tts)==null?void 0:Pe.voice,voiceDir:(Ue=A.tts.pocket_tts)==null?void 0:Ue.voice_dir,hfToken:A.tts.hf_token});break;case"inflect_micro":await E("download_inflect_micro",{modelDir:(xe=(ie=A.tts.inflect_micro)==null?void 0:ie.model_dir)!=null?xe:""});break;case"breeze_tts_2":await E("download_breeze_tts_2",{modelDir:(He=(Ce=A.tts.breeze_tts_2)==null?void 0:Ce.model_dir)!=null?He:"",hfToken:A.tts.hf_token});break;case"vox_cpm_2":await E("download_vox_cpm_2",{modelDir:(Dt=(Xe=A.tts.vox_cpm_2)==null?void 0:Xe.model_dir)!=null?Dt:"",hfToken:A.tts.hf_token});break;case"espeak":break}o(Q,!1),o(h,{...e(h),[g]:!0},!0),Ne.clearIssue(`tts-download-${g}`)}catch(fa){const Gt=cs.find(Oa=>Oa.id===g),ma=I(fa);ma&&o(Q,!0),Se(g,ma?`HuggingFace did not accept that access token, so ${(zt=Gt==null?void 0:Gt.name)!=null?zt:g} could not be downloaded. Check the token is a valid read token, and that the same account has accepted the licence at ${(Ft=Gt==null?void 0:Gt.licenceUrl)!=null?Ft:"huggingface.co"}.`:`${fa}`),Ne.recordIssue({id:`tts-download-${g}`,step:c,title:ma?`${(Wt=Gt==null?void 0:Gt.name)!=null?Wt:g} could not be downloaded — HuggingFace did not accept the access token.`:`${(Yt=Gt==null?void 0:Gt.name)!=null?Yt:g} could not be downloaded — speech output will stay silent.`,detail:`engine=${g}
+${fa}`})}finally{o(m,null)}}const ae=["pocket_tts","breeze_tts_2","vox_cpm_2"],O=ce(()=>ae.includes(e(v))),X=ce(()=>e(v)==="pocket_tts"?t().tts.pocket_tts.gpu:e(v)==="breeze_tts_2"?t().tts.breeze_tts_2.gpu:e(v)==="vox_cpm_2"?t().tts.vox_cpm_2.gpu:!1);function ve(g){fs(A=>{e(v)==="pocket_tts"?A.tts.pocket_tts.gpu=g:e(v)==="breeze_tts_2"?A.tts.breeze_tts_2.gpu=g:e(v)==="vox_cpm_2"&&(A.tts.vox_cpm_2.gpu=g)})}function Me(g){fe(g)||fs(A=>{A.tts.enabled=!0,A.tts.engine=g})}function Fe(g){fs(A=>{A.tts.enabled=g})}async function he(g){if(e(L)){j(),E("stop_tts").catch(()=>{});return}Me(g),o(ge,null),o(L,g,!0),oe=Date.now(),R=!1,ue(),V=setInterval(()=>void J(),B),K=setTimeout(()=>{j(),o(ge,"The sample never finished playing. The engine may have failed silently — check Settings → TTS, or try another voice.")},Ae);const A=bn(Ot),Pe=cs.find(ie=>ie.id===g),Ue=g==="piper"?A.tts.voice:g==="pocket_tts"?A.tts.pocket_tts.voice:null;try{await E("save_config",{newConfig:A}),await E("speak_text",{text:`Hi this is ${Pe.name} speaking from VoxCtrl`,voice:Ue})}catch(ie){o(ge,`${ie}`),j(),Ne.recordIssue({id:`tts-speak-${g}`,step:c,title:`${Pe.name} failed to speak the sample.`,detail:`engine=${g} voice=${Ue!=null?Ue:"(fixed)"}
+${ie}`})}}pa(()=>{var g;if(!e(u)){a.setBlocker(c,null);return}if(e(m)){a.setBlocker(c,`Downloading ${(g=cs.find(A=>A.id===e(m)))==null?void 0:g.name}…`);return}if(fe(e(v))){a.setBlocker(c,"Enter a HuggingFace access token, or pick a voice that does not need one.");return}if(e(v)==="inflect_micro"&&!e(x)){a.setBlocker(c,"This build has no Inflect Micro engine — pick another voice or skip.");return}a.setBlocker(c,e(h)[e(v)]?null:"Download the voice you picked, or turn speech output off to continue.")}),qt(()=>{le(),E("hf_token_env").then(A=>o(M,A&&A.trim()?A.trim():null,!0)).catch(()=>o(M,null)),E("inflect_micro_available").then(A=>o(x,A,!0)).catch(()=>o(x,!1));const g=[ha("tts-playback-end",()=>j()),ha("tts-error",A=>{o(ge,A.payload,!0),j(),Ne.recordIssue({id:"tts-runtime",step:c,title:"The text-to-speech engine reported an error while speaking.",detail:`engine=${bn(Ot).tts.engine}
+${A.payload}`})})];return()=>{a.setBlocker(c,null),ue();for(const A of g)A.then(Pe=>Pe()).catch(()=>{});E("stop_tts").catch(()=>{})}});const re=ce(()=>!!e(h)[e(v)]),we=ce(()=>fe(e(v))),Je=ce(()=>e(v)==="inflect_micro"&&!e(x)),de=ce(()=>e(re)&&!e(Je)&&!e(we)&&!e(m));var Y=Bm(),U=n(Y),te=i(n(U),2),G=n(te);let _e;var me=i(G,2);let pe;var ze=i(U,2),Ye=n(ze),st=n(Ye);let it;var H=n(st);{var P=g=>{var A=ym(),Pe=i(ht(A),4);pt(Pe,21,()=>ee,ft,(Ue,ie)=>{var xe=bm();let Ce;w(()=>{var He,Xe;return Ce=na(xe,"",Ce,{"animation-duration":`${(He=e(ie).d)!=null?He:""}s`,"animation-delay":`${(Xe=e(ie).dl)!=null?Xe:""}s`})}),d(Ue,xe)}),d(g,A)},C=g=>{var A=wm();d(g,A)};k(H,g=>{e(L)?g(P):g(C,-1)})}var ke=i(st,2),je=n(ke),ye=n(je),Ie=i(je,2),Ge=n(Ie);{var Ze=g=>{var A=km();d(g,A)},Ve=g=>{var A=xm();d(g,A)},at=g=>{var A=Tm();d(g,A)},et=g=>{var A=Sm();d(g,A)},rt=g=>{var A=Em();d(g,A)};k(Ge,g=>{e(L)?g(Ze):e(m)?g(Ve,1):e(we)?g(at,2):e(re)?g(et,3):g(rt,-1)})}var Ee=i(Ye,2);let $e;var ct=i(n(Ee),2),vt=n(ct),nt=i(vt,2);let wt;var dt=n(nt);{var Et=g=>{var A=Be("did not accept this token");d(g,A)},jt=g=>{var A=Be("HF_TOKEN environment variable");d(g,A)},ia=g=>{var A=Be("✓ token saved");d(g,A)},ra=g=>{var A=Be("token required for gated voices");d(g,A)};k(dt,g=>{e(Q)?g(Et):e(q)?g(jt,1):e(D)?g(ia,2):g(ra,-1)})}var bt=i(ze,2);{var ea=g=>{var A=Cm(),Pe=i(n(A));w(()=>{var Ue;return y(Pe,` ${(Ue=e(f).name)!=null?Ue:""} weights are released under a research/non-commercial license. Commercial
+ use requires a separate license from the model's publisher.`)}),d(g,A)};k(bt,g=>{e(u)&&e(f).nonCommercial&&!e(h)[e(v)]&&g(ea)})}var Lt=i(bt,2);{var Ht=g=>{var A=Mm(),Pe=n(A),Ue=i(Pe,2),ie=n(Ue);w(()=>{var xe;Od(Pe,e(X)),y(ie,`Vulkan GPU acceleration for ${(xe=e(f).name)!=null?xe:""}`)}),N("change",Pe,xe=>ve(xe.currentTarget.checked)),d(g,A)};k(Lt,g=>{e(u)&&e(O)&&g(Ht)})}var ta=i(Lt,2);let Oe;pt(ta,21,()=>cs,ft,(g,A)=>{const Pe=ce(()=>e(u)&&e(v)===e(A).id),Ue=ce(()=>!!e(h)[e(A).id]),ie=ce(()=>e(m)===e(A).id),xe=ce(()=>e(A).id==="inflect_micro"&&!e(x)),Ce=ce(()=>fe(e(A).id));var He=Vm();let Xe;var Dt=n(He),zt=n(Dt),Ft=n(zt),Wt=n(Ft),Yt=i(Ft,2),fa=n(Yt),Gt=i(zt,2),ma=n(Gt),Oa=n(ma),Ga=i(Dt,2),tt=n(Ga);{var gt=Re=>{var Qe=Pm();d(Re,Qe)},It=Re=>{var Qe=Am();d(Re,Qe)},ut=Re=>{var Qe=Dm(),Jt=n(Qe);w($t=>y(Jt,`✓ Downloaded (${$t!=null?$t:""})`),[()=>Tn(e(A).mb)]),d(Re,Qe)},Mt=Re=>{var Qe=zm(),Jt=n(Qe);w($t=>{Qe.disabled=!!e(m)||e(xe)||e(Ce),y(Jt,`↓ Download ${$t!=null?$t:""}`)},[()=>Tn(e(A).mb)]),N("click",Qe,$t=>{$t.stopPropagation(),W(e(A).id)}),d(Re,Qe)};k(tt,Re=>{e(A).mb===0?Re(gt):e(ie)?Re(It,1):e(Ue)?Re(ut,2):Re(Mt,-1)})}var Kt=i(Ga,2);pt(Kt,21,()=>[{label:"quality",pct:Math.round(e(A).quality*100),value:Fi(e(A).quality),color:"var(--vx-cyan-0)"},{label:"speed",pct:Math.round(e(A).speed*100),value:Kh(e(A).speed),color:"var(--vx-cyan-2)"},{label:"model size",pct:Bh(e(A).mb),value:Tn(e(A).mb),color:"var(--vx-gold-1)"}],ft,(Re,Qe)=>{var Jt=Im(),$t=n(Jt),ka=n($t),xa=n(ka),Ta=i(ka),la=n(Ta),_a=i($t,2),Aa=n(_a);let Ca;w(()=>{var Ut;y(xa,e(Qe).label),y(la,e(Qe).value),Ca=na(Aa,"",Ca,{width:`${(Ut=e(Qe).pct)!=null?Ut:""}%`,background:e(Qe).color})}),d(Re,Jt)});var wa=i(Kt,2),oa=n(wa);{var La=Re=>{var Qe=Om();d(Re,Qe)},Ka=Re=>{var Qe=Lm(),Jt=n(Qe);w(()=>y(Jt,e(_)[e(A).id])),d(Re,Qe)},Z=Re=>{var Qe=Rm();d(Re,Qe)},Le=Re=>{var Qe=Nm();d(Re,Qe)},Ke=Re=>{var Qe=Be();w(()=>y(Qe,e(A).note)),d(Re,Qe)};k(oa,Re=>{e(Ce)?Re(La):e(_)[e(A).id]?Re(Ka,1):e(A).needsHfToken&&!e(D)&&e(Ue)?Re(Z,2):e(xe)?Re(Le,3):Re(Ke,-1)})}w(()=>{Xe=Te(He,1,"vx-card card svelte-1yghr3b",null,Xe,{"vx-on":e(Pe),locked:e(Ce)}),mt(He,"aria-disabled",e(Ce)),mt(He,"aria-checked",e(Pe)),y(Wt,e(A).name),y(fa,e(A).kind),y(Oa,e(Pe)?"✓":"")}),N("click",He,()=>Me(e(A).id)),N("keydown",He,Re=>{(Re.key==="Enter"||Re.key===" ")&&(Re.preventDefault(),Me(e(A).id))}),d(g,He)});var qe=i(ta,2);{var $=g=>{var A=Fm(),Pe=n(A);w(()=>{var Ue;return y(Pe,`⚠ ${(Ue=e(ge))!=null?Ue:""}`)}),d(g,A)};k(qe,g=>{e(ge)&&g($)})}w(g=>{var A;_e=Te(G,1,"vx-card mode svelte-1yghr3b",null,_e,{"vx-on":e(u)}),pe=Te(me,1,"vx-card mode svelte-1yghr3b",null,pe,{"off-on":!e(u)}),it=Te(st,1,"vx-btn audition-btn svelte-1yghr3b",null,it,{playing:!!e(L)}),st.disabled=!e(de)&&!e(L),mt(st,"title",e(L)?"Stop":e(re)?"Play a sample":e(we)?"Needs a HuggingFace access token":"Download this voice first"),y(ye,`Audition: ${(A=e(f).name)!=null?A:""}`),$e=Te(Ee,1,"hf-bar svelte-1yghr3b",null,$e,g),vt.readOnly=e(q),mt(vt,"title",e(q)?"Set by the HF_TOKEN environment variable":"Enter a HuggingFace read token for gated models"),sr(vt,e(T)),wt=Te(nt,1,"hf-state svelte-1yghr3b",null,wt,{ok:e(D)&&!e(Q),bad:e(Q)}),Oe=Te(ta,1,"grid svelte-1yghr3b",null,Oe,{muted:!e(u)})},[()=>({needed:e(u)&&(e(Q)||se.some(g=>fe(g.id)))})]),N("click",G,()=>Fe(!0)),N("click",me,()=>Fe(!1)),N("click",st,()=>{e(L)?(j(),E("stop_tts").catch(()=>{})):he(e(v))}),N("input",vt,g=>ne(g.currentTarget.value)),d(s,Y),St(),l()}Qt(["click","input","change","keydown"]);const Km="/assets/record_off-DqBdWxcg.png";var Um=p('VoxCtrl is ready.',1),jm=p('Setup is incomplete.',1),Hm=p('
'),Wm=Oo(''),Ym=p('
'),$m=p('
click me↓
'),Gm=p(`
where everything lives
Every choice is editable
Nothing you picked here is locked in. Settings holds the same options plus the ones the
wizard skipped — output targets, per-binding LLM cleanup, audio devices and the MCP server.
⌁ Hotkeys gestures & bindings
∇ Engine model & device
⌬ Visual overlay style & position
⊕ TTS voice output
⊳ Output Commands where text goes
`),Jm=p(''),Xm=p('
'),Zm=p(''),Qm=p('
'),eb=p('
What still needs fixing
'),tb=p('
system tray
Find VoxCtrl in the tray
Click the icon to open Settings, diagnostics, or toggle TTS memory. Try it:
📶🔊ᛒ
⌃
');function ab(s,a){Tt(a,!0);const t=()=>Zt(Ot,"$config",r),[r,l]=Ea();let c=S(!1),u=S(!1),v=S(!0),f=S(!1),h=S(null),b=S(null),m=S(!1);async function _(){o(m,!0);try{o(b,await E("get_setup_status"),!0)}catch(U){console.error("Wizard: could not read setup status:",U),o(b,null)}finally{o(m,!1)}}const x=ce(()=>{var te;if(!e(b))return[];const U=[];return e(b).hotkeys_active||U.push({id:"sys-hotkeys",step:2,title:"No global shortcut is active — pressing your hotkey will do nothing.",detail:`backend=${e(b).hotkeys.backend} portal_refused=${e(b).hotkeys.portal_refused}
portal_error=${(te=e(b).hotkeys.portal_error)!=null?te:"(none)"}`}),!e(b).model_ready&&!e(b).model_auto_downloads&&U.push({id:"sys-model",step:1,title:`Speech model "${e(b).model_size}" is not on disk — dictation will record but produce no text.`,detail:`model_size=${e(b).model_size} model_ready=false auto_downloads=${e(b).model_auto_downloads}`}),e(b).missing_injection_tool&&U.push({id:"sys-inject",step:4,title:`"${e(b).missing_injection_tool}" is not installed — VoxCtrl cannot type text into other windows.`,detail:`missing_injection_tool=${e(b).missing_injection_tool}
-install with: ${e(b).manual_package_commands||"(unknown package manager)"}`}),U}),A=ce(()=>{const U=new Set(Ne.issues.map(te=>te.id));return[...Ne.issues,...e(x).filter(te=>!U.has(te.id))]}),q=ce(()=>e(A).length===0),T=ce(()=>{var U;return((U=Ne.combo)!=null?U:[]).map(dl).join(" + ")||"not set"}),D=ce(()=>{var U,te,Y,_e,me;return[{k:"engine",v:t().engine.backend==="remote-openai"?`Remote Speech Engine · ${((U=t().engine.remote_openai)==null?void 0:U.model)||"whisper-1"}`:t().engine.backend==="parakeet"?`Parakeet TDT · ${t().engine.parakeet.model_size}`:t().engine.backend==="moonshine"?`Moonshine · ${t().engine.moonshine.model_size}`:`whisper.cpp · ${t().engine.whisper_cpp.model_size}`},{k:"hotkey",v:`${e(T)} · ${Ne.gestureInfo.name}`},{k:"overlay",v:t().ui.show_overlay?`${(Y=(te=mn.find(pe=>pe.id===t().ui.overlay_style))==null?void 0:te.name)!=null?Y:t().ui.overlay_style} · ${t().ui.overlay_position}`:"off"},{k:"voice output",v:t().tts.enabled?(me=(_e=cs.find(pe=>pe.id===t().tts.engine))==null?void 0:_e.name)!=null?me:t().tts.engine:"off"}]}),se=ce(()=>{var U,te,Y;return["VoxCtrl setup report",`engine: ${t().engine.backend} / ${t().engine.backend==="remote-openai"?((U=t().engine.remote_openai)==null?void 0:U.model)||"whisper-1":t().engine.backend==="parakeet"?t().engine.parakeet.model_size:t().engine.backend==="moonshine"?t().engine.moonshine.model_size:t().engine.whisper_cpp.model_size}`,`device: ${t().engine.whisper_cpp.device}`,`hotkey: ${e(T)} (${Ne.gesture})`,`overlay: ${t().ui.show_overlay?`${t().ui.overlay_style} / ${t().ui.overlay_position}`:"off"}`,`tts: ${t().tts.enabled?t().tts.engine:"off"}`,`shortcut backend: ${(Y=(te=e(b))==null?void 0:te.hotkeys.backend)!=null?Y:"unknown"}`,"",...e(A).map(_e=>{var me;return`[${(me=ds[_e.step])!=null?me:"setup"}] ${_e.title}
+install with: ${e(b).manual_package_commands||"(unknown package manager)"}`}),U}),M=ce(()=>{const U=new Set(Ne.issues.map(te=>te.id));return[...Ne.issues,...e(x).filter(te=>!U.has(te.id))]}),q=ce(()=>e(M).length===0),T=ce(()=>{var U;return((U=Ne.combo)!=null?U:[]).map(dl).join(" + ")||"not set"}),D=ce(()=>{var U,te,G,_e,me;return[{k:"engine",v:t().engine.backend==="remote-openai"?`Remote Speech Engine · ${((U=t().engine.remote_openai)==null?void 0:U.model)||"whisper-1"}`:t().engine.backend==="parakeet"?`Parakeet TDT · ${t().engine.parakeet.model_size}`:t().engine.backend==="moonshine"?`Moonshine · ${t().engine.moonshine.model_size}`:`whisper.cpp · ${t().engine.whisper_cpp.model_size}`},{k:"hotkey",v:`${e(T)} · ${Ne.gestureInfo.name}`},{k:"overlay",v:t().ui.show_overlay?`${(G=(te=mn.find(pe=>pe.id===t().ui.overlay_style))==null?void 0:te.name)!=null?G:t().ui.overlay_style} · ${t().ui.overlay_position}`:"off"},{k:"voice output",v:t().tts.enabled?(me=(_e=cs.find(pe=>pe.id===t().tts.engine))==null?void 0:_e.name)!=null?me:t().tts.engine:"off"}]}),se=ce(()=>{var U,te,G;return["VoxCtrl setup report",`engine: ${t().engine.backend} / ${t().engine.backend==="remote-openai"?((U=t().engine.remote_openai)==null?void 0:U.model)||"whisper-1":t().engine.backend==="parakeet"?t().engine.parakeet.model_size:t().engine.backend==="moonshine"?t().engine.moonshine.model_size:t().engine.whisper_cpp.model_size}`,`device: ${t().engine.whisper_cpp.device}`,`hotkey: ${e(T)} (${Ne.gesture})`,`overlay: ${t().ui.show_overlay?`${t().ui.overlay_style} / ${t().ui.overlay_position}`:"off"}`,`tts: ${t().tts.enabled?t().tts.engine:"off"}`,`shortcut backend: ${(G=(te=e(b))==null?void 0:te.hotkeys.backend)!=null?G:"unknown"}`,"",...e(M).map(_e=>{var me;return`[${(me=ds[_e.step])!=null?me:"setup"}] ${_e.title}
${_e.detail}
`})].join(`
-`)});async function ne(){try{await navigator.clipboard.writeText(e(se)),o(u,!0),setTimeout(()=>o(u,!1),2e3)}catch(U){console.error("Wizard: clipboard write failed:",U)}}async function fe(){o(f,!0),o(h,null);try{const U=await E("wizard_failure_log");try{await navigator.clipboard.writeText(U)}catch(me){console.error("Wizard: clipboard write failed:",me)}const te=encodeURIComponent("VoxCtrl Bug Report"),Y=encodeURIComponent(`Paste the log contents below and I will get back to you with a fix ASAP.
+`)});async function ne(){try{await navigator.clipboard.writeText(e(se)),o(u,!0),setTimeout(()=>o(u,!1),2e3)}catch(U){console.error("Wizard: clipboard write failed:",U)}}async function fe(){o(f,!0),o(h,null);try{const U=await E("wizard_failure_log");try{await navigator.clipboard.writeText(U)}catch(me){console.error("Wizard: clipboard write failed:",me)}const te=encodeURIComponent("VoxCtrl Bug Report"),G=encodeURIComponent(`Paste the log contents below and I will get back to you with a fix ASAP.
-`),_e=`mailto:jrufer@gmail.com?subject=${te}&body=${Y}`;await E("send_bug_report_email",{mailtoUrl:_e,attachmentPath:null}),o(h,"Log copied to your clipboard — paste it into the email that just opened.")}catch(U){o(h,`Could not open your email app: ${U}`)}finally{o(f,!1)}}async function Q(){try{await E("open_settings_tab",{tab:"general"})}catch(U){console.error("Wizard: could not open Settings:",U)}}qt(()=>{var U;_(),((U=t().tts)==null?void 0:U.memory_mode)!==void 0&&o(v,t().tts.memory_mode==="on_demand")});function z(){o(v,!e(v)),Ot.update(U=>(U.tts&&(U.tts.memory_mode=e(v)?"on_demand":"always_loaded"),U))}var I=tb(),L=n(I),ge=n(L);let ee;var j=n(ge),V=i(ge,2),oe=n(V),R=i(V,2),B=n(R);{var be=U=>{var te=Um();d(U,te)},Pe=U=>{var te=Km();d(U,te)};k(B,U=>{e(q)?U(be):U(Pe,-1)})}var ue=i(R,2),K=n(ue);{var J=U=>{var te=Be(`This window can close. VoxCtrl keeps running quietly in your system tray and listens for
- your hotkey in any app.`);d(U,te)},Se=U=>{var te=Be();w(()=>{var Y;return y(te,`Sorry about that — ${(Y=e(A).length)!=null?Y:""} problem${e(A).length===1?"":"s"} came up during setup
+`),_e=`mailto:jrufer@gmail.com?subject=${te}&body=${G}`;await E("send_bug_report_email",{mailtoUrl:_e,attachmentPath:null}),o(h,"Log copied to your clipboard — paste it into the email that just opened.")}catch(U){o(h,`Could not open your email app: ${U}`)}finally{o(f,!1)}}async function Q(){try{await E("open_settings_tab",{tab:"general"})}catch(U){console.error("Wizard: could not open Settings:",U)}}qt(()=>{var U;_(),((U=t().tts)==null?void 0:U.memory_mode)!==void 0&&o(v,t().tts.memory_mode==="on_demand")});function z(){o(v,!e(v)),Ot.update(U=>(U.tts&&(U.tts.memory_mode=e(v)?"on_demand":"always_loaded"),U))}var I=tb(),L=n(I),ge=n(L);let ee;var K=n(ge),V=i(ge,2),oe=n(V),R=i(V,2),B=n(R);{var be=U=>{var te=Um();d(U,te)},Ae=U=>{var te=jm();d(U,te)};k(B,U=>{e(q)?U(be):U(Ae,-1)})}var ue=i(R,2),j=n(ue);{var J=U=>{var te=Be(`This window can close. VoxCtrl keeps running quietly in your system tray and listens for
+ your hotkey in any app.`);d(U,te)},Se=U=>{var te=Be();w(()=>{var G;return y(te,`Sorry about that — ${(G=e(M).length)!=null?G:""} problem${e(M).length===1?"":"s"} came up during setup
and will stop VoxCtrl working end to end. Your choices are still saved. The details are on
- the right — fix them here or in Settings, or send us the log and we'll take it from there.`)}),d(U,te)};k(K,U=>{e(q)?U(J):U(Se,-1)})}var De=i(ue,2);pt(De,21,()=>e(D),ft,(U,te)=>{var Y=Hm(),_e=n(Y),me=n(_e),pe=i(_e,2),ze=n(pe);w(()=>{y(me,e(te).k),y(ze,e(te).v)}),d(U,Y)});var le=i(L,2),W=i(n(le),6),ae=n(W);{var O=U=>{var te=$m(),Y=n(te),_e=i(Y,2),me=i(_e,2),pe=n(me),ze=n(pe);let $e;var st=n(ze);{var it=M=>{var C=Wm();d(M,C)};k(st,M=>{e(v)&&M(it)})}var H=i(me,4);w(()=>$e=Te(ze,1,"chk svelte-ujy0nl",null,$e,{on:e(v)})),N("click",Y,Q),N("click",_e,()=>{o(c,!1),_()}),N("click",me,z),N("click",H,()=>o(c,!1)),d(U,te)};k(ae,U=>{e(c)&&U(O)})}var X=i(ae,2),ve=i(n(X),6),Ae=n(ve);let Fe;var he=n(Ae),re=i(Ae,2);{var we=U=>{var te=Gm();d(U,te)};k(re,U=>{e(c)||U(we)})}var Je=i(le,2);{var de=U=>{var te=Ym(),Y=i(n(te),8);N("click",Y,Q),d(U,te)},$=U=>{var te=eb(),Y=n(te),_e=n(Y),me=n(_e),pe=n(me),ze=i(_e,2),$e=n(ze);{var st=Ve=>{var at=Jm();d(Ve,at)};k($e,Ve=>{e(m)&&Ve(st)})}var it=i(Y,2);pt(it,21,()=>e(A),Ve=>Ve.id,(Ve,at)=>{var et=Xm(),rt=n(et),Ee=n(rt),Ge=n(Ee),ct=i(Ee,2),vt=n(ct),nt=i(rt,2),wt=n(nt);w(()=>{var dt;y(Ge,(dt=ds[e(at).step])!=null?dt:"setup"),y(vt,e(at).title),y(wt,e(at).detail)}),d(Ve,et)});var H=i(it,2),M=n(H),C=n(M),ke=i(M,2),Ke=i(ke,2),ye=n(Ke);{var Ie=Ve=>{var at=Zm();d(Ve,at)};k(ye,Ve=>{e(f)&&Ve(Ie)})}var Ye=i(H,2);{var Ze=Ve=>{var at=Qm(),et=n(at);w(()=>y(et,e(h))),d(Ve,at)};k(Ye,Ve=>{e(h)&&Ve(Ze)})}w(()=>{var Ve;y(pe,`problems · ${(Ve=e(A).length)!=null?Ve:""}`),ze.disabled=e(m),y(C,e(u)?"✓ Copied":"Copy diagnostics"),Ke.disabled=e(f)}),N("click",ze,_),N("click",M,ne),N("click",ke,Q),N("click",Ke,fe),d(U,te)};k(Je,U=>{e(q)?U(de):U($,-1)})}w(()=>{ee=Te(ge,1,"tick svelte-ujy0nl",null,ee,{warn:!e(q)}),y(j,e(q)?"✓":"!"),y(oe,e(q)?"// configured":"// finished with problems"),Fe=Te(Ae,1,"tray-btn svelte-ujy0nl",null,Fe,{on:e(c)}),mt(he,"src",jm)}),N("click",Ae,()=>o(c,!e(c))),d(s,I),St(),l()}Qt(["click"]);var sb=p('
Loading your settings…
'),nb=p(''),ib=p(''),rb=p('
'),lb=p('
'),ob=p(''),cb=p(' Working…',1),db=p('
'),vb=p('
voxctrl// setup
');function ub(s,a){Tt(a,!0);const t=()=>Zt(Ot,"$config",l),r=()=>Zt(Ki,"$configLoaded",l),[l,c]=Ea();let u={};function v($,U){U?u[$]=U:delete u[$]}let f=S(yt({}));function h($,U){var te;((te=e(f)[$])!=null?te:null)!==U&&o(f,{...e(f),[$]:U},!0)}let b=S(!1),m=S(null);const _=ce(()=>Ne.step),x=ce(()=>{var $;return($=e(f)[e(_)])!=null?$:null}),A=ce(()=>e(_)===0?"Get started →":e(_)===5&&!t().tts.enabled?"Skip →":e(_)===ds.length-1?Ne.issues.length>0?"Finish anyway":"Finish":"Continue →");async function q(){if(e(b))return;if(o(m,null),e(_)===ds.length-1){await se();return}const $=u[e(_)];if($){o(b,!0);try{if(!await $())return}catch(U){o(m,`${U}`);return}finally{o(b,!1)}}Ne.goTo(e(_)+1)}function T(){e(b)||(o(m,null),Ne.goTo(e(_)-1))}let D=S(!1);async function se(){if(!e(D)){o(D,!0);try{await E("save_config",{newConfig:t()}),await E("finish_setup_wizard",{openSettings:!1})}catch($){o(m,`Could not finish setup: ${$}`),o(D,!1)}}}async function ne(){await se()}function fe($){Ne.recordIssue({id:`uncaught-${Ne.issues.filter(U=>U.id.startsWith("uncaught-")).length}`,step:Ne.step,title:"Something went wrong during setup that the wizard did not expect.",detail:$})}qt(()=>{const $=te=>{var Y;fe(((Y=te.error)==null?void 0:Y.stack)||te.message||String(te))},U=te=>{var Y,_e;fe(((Y=te.reason)==null?void 0:Y.stack)||((_e=te.reason)==null?void 0:_e.message)||String(te.reason))};return window.addEventListener("error",$),window.addEventListener("unhandledrejection",U),E("wizard_error_test_active").then(te=>{te&&(Ne.recordIssue({id:"simulated-test-failure",step:4,title:"Simulated failure (--simulate-wizard-error) — the live test did not detect any transcribed audio.",detail:"This is a test fixture, not a real failure: it exists so the wizard's error screen (apology, log capture, copy-to-clipboard, email-us) can be verified without needing a genuinely broken hotkey or microphone."}),Ne.visited=ds.length-1,Ne.step=ds.length-1)}).catch(te=>console.error("Wizard: could not check for the error-test flag:",te)),()=>{window.removeEventListener("error",$),window.removeEventListener("unhandledrejection",U)}});var Q=vb(),z=n(Q),I=n(z),L=i(I,8),ge=n(L),ee=i(z,2);let j;var V=n(ee);{var oe=$=>{var U=sb();d($,U)},R=$=>{Yh($)},B=$=>{kg($,{registerGate:v,setBlocker:h})},be=$=>{Lg($,{registerGate:v,setBlocker:h})},Pe=$=>{vm($,{})},ue=$=>{mm($,{})},K=$=>{qm($,{setBlocker:h})},J=$=>{ab($,{})};k(V,$=>{r()?e(_)===0?$(R,1):e(_)===1?$(B,2):e(_)===2?$(be,3):e(_)===3?$(Pe,4):e(_)===4?$(ue,5):e(_)===5?$(K,6):$(J,-1):$(oe)})}var Se=i(ee,2),De=n(Se),le=n(De);{var W=$=>{var U=nb();w(()=>U.disabled=e(b)),N("click",U,T),d($,U)},ae=$=>{var U=ib();w(()=>U.disabled=e(D)),N("click",U,ne),d($,U)};k(le,$=>{e(_)>0?$(W):$(ae,-1)})}var O=i(De,2);pt(O,21,()=>ds,ft,($,U,te)=>{var Y=lb();let _e;var me=n(Y);let pe;var ze=n(me),$e=n(ze),st=i(ze,2),it=n(st),H=i(me,2);{var M=C=>{var ke=rb(),Ke=n(ke);let ye;w(()=>ye=na(Ke,"",ye,{width:te{te{_e=na(Y,"",_e,{flex:teNe.visited||e(b),y($e,C),y(it,e(U))},[()=>teNe.goTo(te)),d($,Y)});var X=i(O,2),ve=n(X);{var Ae=$=>{var U=ob(),te=n(U);w(()=>{mt(U,"title",e(x)),y(te,e(x))}),d($,U)};k(ve,$=>{e(x)&&!e(b)&&$(Ae)})}var Fe=i(ve,2),he=n(Fe);{var re=$=>{var U=cb();d($,U)},we=$=>{var U=Be();w(()=>y(U,e(A))),d($,U)};k(he,$=>{e(b)||e(D)?$(re):$(we,-1)})}var Je=i(Se,2);{var de=$=>{var U=db(),te=n(U),Y=n(te),_e=i(te,2);w(()=>{var me;return y(Y,`⚠ ${(me=e(m))!=null?me:""}`)}),N("click",_e,()=>o(m,null)),d($,U)};k(Je,$=>{e(m)&&$(de)})}w(()=>{var $;mt(I,"src",nr),y(ge,`step ${e(_)+1} / ${($=ds.length)!=null?$:""} · every choice editable later in Settings`),j=Te(ee,1,"vx-screen svelte-18pn5kx",null,j,{"vx-leaving":Ne.leaving}),Fe.disabled=e(b)||e(D)||!!e(x)}),N("click",Fe,q),d(s,Q),St(),c()}Qt(["click"]);function Ol(s){if(!s||s<0)return"";if(s<1024)return`${s} B`;const a=["KB","MB","GB"];let t=s/1024,r=0;for(;t>=1024&&r
'),_b=p('
'),hb=p('
Asking GitHub for the latest release…
'),gb=p('
Nothing to install. Check again any time from Settings → General.
'),mb=p(`
What's new
`),bb=p('
'),yb=p('
VoxCtrl keeps running until the download is verified. Nothing is replaced before then.
'),wb=p('
The new version is installed. VoxCtrl is closing and will start again in a moment.
'),kb=p('
'),xb=p('
Your current version is untouched and still working.
',1),Tb=p(" ",1),Sb=p('
'),Eb=p(''),Cb=p(''),Ab=p(''),Mb=p(''),Pb=p('
',1),Db=p(''),zb=p('
');function Ib(s,a){Tt(a,!0);let t=S("checking"),r=S(null),l=S(""),c=S(null),u=S(null),v=[];const f=ce(()=>pb(e(c)));qt(async()=>{v.push(await ha("update-progress",le=>{o(c,le.payload,!0)})),v.push(await ha("update-installed",()=>{o(t,"installed")})),v.push(await ha("update-failed",le=>{o(t,"failed"),o(u,le.payload,!0)})),await h()}),ar(()=>{v.forEach(le=>le())});async function h(){try{let le=await E("get_pending_update");le.update||(le=await E("check_for_update")),o(l,le.current_version,!0),o(r,le.update,!0),o(t,le.update?"available":"up-to-date",!0)}catch(le){o(t,"failed"),o(u,`${le}`)}}async function b(){var le;if((le=e(r))!=null&&le.can_self_update){o(t,"installing"),o(u,null),o(c,{downloaded:0,total:e(r).download_size},!0);try{await E("install_update")}catch(W){o(t,"failed"),o(u,`${W}`)}}}async function m(){await E("dismiss_update")}async function _(){var le,W;try{await Uo((W=(le=e(r))==null?void 0:le.release_url)!=null?W:"https://github.com/JRufer/VoxCtrl/releases/latest")}catch(ae){console.error("Could not open the release page:",ae)}}var x=zb(),A=n(x),q=n(A),T=n(q),D=i(T,2),se=n(D),ne=n(se);{var fe=le=>{var W=Be("VoxCtrl is up to date");d(le,W)},Q=le=>{var W=Be();w(()=>{var ae,O;return y(W,`Restarting into ${(O=(ae=e(r))==null?void 0:ae.version)!=null?O:""}`)}),d(le,W)},z=le=>{var W=Be();w(()=>{var ae,O;return y(W,`Updating to ${(O=(ae=e(r))==null?void 0:ae.version)!=null?O:""}`)}),d(le,W)},I=le=>{var W=Be();w(()=>{var ae;return y(W,`VoxCtrl ${(ae=e(r).version)!=null?ae:""} is available`)}),d(le,W)},L=le=>{var W=Be("Checking for updates…");d(le,W)};k(ne,le=>{e(t)==="up-to-date"?le(fe):e(t)==="installed"?le(Q,1):e(t)==="installing"?le(z,2):e(r)?le(I,3):le(L,-1)})}var ge=i(se,2);{var ee=le=>{var W=fb(),ae=n(W);w(()=>{var O,X;return y(ae,`You have ${(O=e(r).current_version)!=null?O:""} — ${(X=e(r).version)!=null?X:""} is the latest release.`)}),d(le,W)},j=le=>{var W=_b(),ae=n(W);w(()=>{var O;return y(ae,`Version ${(O=e(l))!=null?O:""} is the latest release.`)}),d(le,W)};k(ge,le=>{e(r)&&e(t)!=="up-to-date"?le(ee):e(t)==="up-to-date"&&le(j,1)})}var V=i(q,2);{var oe=le=>{var W=hb();d(le,W)},R=le=>{var W=gb();d(le,W)},B=le=>{var W=Tb(),ae=ht(W);{var O=de=>{var $=mb(),U=i(n($),2),te=n(U);w(()=>y(te,e(r).notes)),d(de,$)};k(ae,de=>{e(r).notes&&de(O)})}var X=i(ae,2);{var ve=de=>{var $=bb(),U=n($);w(()=>y(U,e(r).unsupported_reason)),d(de,$)};k(X,de=>{!e(r).can_self_update&&e(r).unsupported_reason&&de(ve)})}var Ae=i(X,2);{var Fe=de=>{var $=yb(),U=n($);let te;var Y=n(U),_e=i(U,2),me=n(_e);{var pe=$e=>{var st=Be();w(()=>{var it,H;return y(st,`Downloading ${(H=(it=e(r).asset_name)!=null?it:"the update")!=null?H:""}…`)}),d($e,st)},ze=$e=>{var st=Be();w(it=>{var H;return y(st,`Downloading — ${(H=e(f))!=null?H:""}% of ${it!=null?it:""}`)},[()=>{var it,H;return Ol((H=(it=e(c))==null?void 0:it.total)!=null?H:e(r).download_size)}]),d($e,st)};k(me,$e=>{e(f)===null?$e(pe):$e(ze,-1)})}w(()=>{te=Te(U,1,"bar svelte-15mrihi",null,te,{indeterminate:e(f)===null}),na(Y,e(f)===null?"":`width: ${e(f)}%`)}),d(de,$)},he=de=>{var $=wb();d(de,$)},re=de=>{var $=kb(),U=n($);w(te=>y(U,`VoxCtrl will download ${te!=null?te:""}, verify it against the checksum
+ the right — fix them here or in Settings, or send us the log and we'll take it from there.`)}),d(U,te)};k(j,U=>{e(q)?U(J):U(Se,-1)})}var De=i(ue,2);pt(De,21,()=>e(D),ft,(U,te)=>{var G=Hm(),_e=n(G),me=n(_e),pe=i(_e,2),ze=n(pe);w(()=>{y(me,e(te).k),y(ze,e(te).v)}),d(U,G)});var le=i(L,2),W=i(n(le),6),ae=n(W);{var O=U=>{var te=Ym(),G=n(te),_e=i(G,2),me=i(_e,2),pe=n(me),ze=n(pe);let Ye;var st=n(ze);{var it=P=>{var C=Wm();d(P,C)};k(st,P=>{e(v)&&P(it)})}var H=i(me,4);w(()=>Ye=Te(ze,1,"chk svelte-ujy0nl",null,Ye,{on:e(v)})),N("click",G,Q),N("click",_e,()=>{o(c,!1),_()}),N("click",me,z),N("click",H,()=>o(c,!1)),d(U,te)};k(ae,U=>{e(c)&&U(O)})}var X=i(ae,2),ve=i(n(X),6),Me=n(ve);let Fe;var he=n(Me),re=i(Me,2);{var we=U=>{var te=$m();d(U,te)};k(re,U=>{e(c)||U(we)})}var Je=i(le,2);{var de=U=>{var te=Gm(),G=i(n(te),8);N("click",G,Q),d(U,te)},Y=U=>{var te=eb(),G=n(te),_e=n(G),me=n(_e),pe=n(me),ze=i(_e,2),Ye=n(ze);{var st=Ve=>{var at=Jm();d(Ve,at)};k(Ye,Ve=>{e(m)&&Ve(st)})}var it=i(G,2);pt(it,21,()=>e(M),Ve=>Ve.id,(Ve,at)=>{var et=Xm(),rt=n(et),Ee=n(rt),$e=n(Ee),ct=i(Ee,2),vt=n(ct),nt=i(rt,2),wt=n(nt);w(()=>{var dt;y($e,(dt=ds[e(at).step])!=null?dt:"setup"),y(vt,e(at).title),y(wt,e(at).detail)}),d(Ve,et)});var H=i(it,2),P=n(H),C=n(P),ke=i(P,2),je=i(ke,2),ye=n(je);{var Ie=Ve=>{var at=Zm();d(Ve,at)};k(ye,Ve=>{e(f)&&Ve(Ie)})}var Ge=i(H,2);{var Ze=Ve=>{var at=Qm(),et=n(at);w(()=>y(et,e(h))),d(Ve,at)};k(Ge,Ve=>{e(h)&&Ve(Ze)})}w(()=>{var Ve;y(pe,`problems · ${(Ve=e(M).length)!=null?Ve:""}`),ze.disabled=e(m),y(C,e(u)?"✓ Copied":"Copy diagnostics"),je.disabled=e(f)}),N("click",ze,_),N("click",P,ne),N("click",ke,Q),N("click",je,fe),d(U,te)};k(Je,U=>{e(q)?U(de):U(Y,-1)})}w(()=>{ee=Te(ge,1,"tick svelte-ujy0nl",null,ee,{warn:!e(q)}),y(K,e(q)?"✓":"!"),y(oe,e(q)?"// configured":"// finished with problems"),Fe=Te(Me,1,"tray-btn svelte-ujy0nl",null,Fe,{on:e(c)}),mt(he,"src",Km)}),N("click",Me,()=>o(c,!e(c))),d(s,I),St(),l()}Qt(["click"]);var sb=p('
Loading your settings…
'),nb=p(''),ib=p(''),rb=p('
'),lb=p('
'),ob=p(''),cb=p(' Working…',1),db=p('
'),vb=p('
voxctrl// setup
');function ub(s,a){Tt(a,!0);const t=()=>Zt(Ot,"$config",l),r=()=>Zt(ji,"$configLoaded",l),[l,c]=Ea();let u={};function v(Y,U){U?u[Y]=U:delete u[Y]}let f=S(yt({}));function h(Y,U){var te;((te=e(f)[Y])!=null?te:null)!==U&&o(f,{...e(f),[Y]:U},!0)}let b=S(!1),m=S(null);const _=ce(()=>Ne.step),x=ce(()=>{var Y;return(Y=e(f)[e(_)])!=null?Y:null}),M=ce(()=>e(_)===0?"Get started →":e(_)===5&&!t().tts.enabled?"Skip →":e(_)===ds.length-1?Ne.issues.length>0?"Finish anyway":"Finish":"Continue →");async function q(){if(e(b))return;if(o(m,null),e(_)===ds.length-1){await se();return}const Y=u[e(_)];if(Y){o(b,!0);try{if(!await Y())return}catch(U){o(m,`${U}`);return}finally{o(b,!1)}}Ne.goTo(e(_)+1)}function T(){e(b)||(o(m,null),Ne.goTo(e(_)-1))}let D=S(!1);async function se(){if(!e(D)){o(D,!0);try{await E("save_config",{newConfig:t()}),await E("finish_setup_wizard",{openSettings:!1})}catch(Y){o(m,`Could not finish setup: ${Y}`),o(D,!1)}}}async function ne(){await se()}function fe(Y){Ne.recordIssue({id:`uncaught-${Ne.issues.filter(U=>U.id.startsWith("uncaught-")).length}`,step:Ne.step,title:"Something went wrong during setup that the wizard did not expect.",detail:Y})}qt(()=>{const Y=te=>{var G;fe(((G=te.error)==null?void 0:G.stack)||te.message||String(te))},U=te=>{var G,_e;fe(((G=te.reason)==null?void 0:G.stack)||((_e=te.reason)==null?void 0:_e.message)||String(te.reason))};return window.addEventListener("error",Y),window.addEventListener("unhandledrejection",U),E("wizard_error_test_active").then(te=>{te&&(Ne.recordIssue({id:"simulated-test-failure",step:4,title:"Simulated failure (--simulate-wizard-error) — the live test did not detect any transcribed audio.",detail:"This is a test fixture, not a real failure: it exists so the wizard's error screen (apology, log capture, copy-to-clipboard, email-us) can be verified without needing a genuinely broken hotkey or microphone."}),Ne.visited=ds.length-1,Ne.step=ds.length-1)}).catch(te=>console.error("Wizard: could not check for the error-test flag:",te)),()=>{window.removeEventListener("error",Y),window.removeEventListener("unhandledrejection",U)}});var Q=vb(),z=n(Q),I=n(z),L=i(I,8),ge=n(L),ee=i(z,2);let K;var V=n(ee);{var oe=Y=>{var U=sb();d(Y,U)},R=Y=>{Gh(Y)},B=Y=>{kg(Y,{registerGate:v,setBlocker:h})},be=Y=>{Lg(Y,{registerGate:v,setBlocker:h})},Ae=Y=>{vm(Y,{})},ue=Y=>{mm(Y,{})},j=Y=>{qm(Y,{setBlocker:h})},J=Y=>{ab(Y,{})};k(V,Y=>{r()?e(_)===0?Y(R,1):e(_)===1?Y(B,2):e(_)===2?Y(be,3):e(_)===3?Y(Ae,4):e(_)===4?Y(ue,5):e(_)===5?Y(j,6):Y(J,-1):Y(oe)})}var Se=i(ee,2),De=n(Se),le=n(De);{var W=Y=>{var U=nb();w(()=>U.disabled=e(b)),N("click",U,T),d(Y,U)},ae=Y=>{var U=ib();w(()=>U.disabled=e(D)),N("click",U,ne),d(Y,U)};k(le,Y=>{e(_)>0?Y(W):Y(ae,-1)})}var O=i(De,2);pt(O,21,()=>ds,ft,(Y,U,te)=>{var G=lb();let _e;var me=n(G);let pe;var ze=n(me),Ye=n(ze),st=i(ze,2),it=n(st),H=i(me,2);{var P=C=>{var ke=rb(),je=n(ke);let ye;w(()=>ye=na(je,"",ye,{width:te{te{_e=na(G,"",_e,{flex:teNe.visited||e(b),y(Ye,C),y(it,e(U))},[()=>teNe.goTo(te)),d(Y,G)});var X=i(O,2),ve=n(X);{var Me=Y=>{var U=ob(),te=n(U);w(()=>{mt(U,"title",e(x)),y(te,e(x))}),d(Y,U)};k(ve,Y=>{e(x)&&!e(b)&&Y(Me)})}var Fe=i(ve,2),he=n(Fe);{var re=Y=>{var U=cb();d(Y,U)},we=Y=>{var U=Be();w(()=>y(U,e(M))),d(Y,U)};k(he,Y=>{e(b)||e(D)?Y(re):Y(we,-1)})}var Je=i(Se,2);{var de=Y=>{var U=db(),te=n(U),G=n(te),_e=i(te,2);w(()=>{var me;return y(G,`⚠ ${(me=e(m))!=null?me:""}`)}),N("click",_e,()=>o(m,null)),d(Y,U)};k(Je,Y=>{e(m)&&Y(de)})}w(()=>{var Y;mt(I,"src",nr),y(ge,`step ${e(_)+1} / ${(Y=ds.length)!=null?Y:""} · every choice editable later in Settings`),K=Te(ee,1,"vx-screen svelte-18pn5kx",null,K,{"vx-leaving":Ne.leaving}),Fe.disabled=e(b)||e(D)||!!e(x)}),N("click",Fe,q),d(s,Q),St(),c()}Qt(["click"]);function Ol(s){if(!s||s<0)return"";if(s<1024)return`${s} B`;const a=["KB","MB","GB"];let t=s/1024,r=0;for(;t>=1024&&r '),_b=p('
'),hb=p('
Asking GitHub for the latest release…
'),gb=p('
Nothing to install. Check again any time from Settings → General.
'),mb=p(`
What's new
`),bb=p('
'),yb=p('
VoxCtrl keeps running until the download is verified. Nothing is replaced before then.
'),wb=p('
The new version is installed. VoxCtrl is closing and will start again in a moment.
'),kb=p('
'),xb=p('
Your current version is untouched and still working.
',1),Tb=p(" ",1),Sb=p('
'),Eb=p(''),Cb=p(''),Mb=p(''),Pb=p(''),Ab=p('
',1),Db=p(''),zb=p('
');function Ib(s,a){Tt(a,!0);let t=S("checking"),r=S(null),l=S(""),c=S(null),u=S(null),v=[];const f=ce(()=>pb(e(c)));qt(async()=>{v.push(await ha("update-progress",le=>{o(c,le.payload,!0)})),v.push(await ha("update-installed",()=>{o(t,"installed")})),v.push(await ha("update-failed",le=>{o(t,"failed"),o(u,le.payload,!0)})),await h()}),ar(()=>{v.forEach(le=>le())});async function h(){try{let le=await E("get_pending_update");le.update||(le=await E("check_for_update")),o(l,le.current_version,!0),o(r,le.update,!0),o(t,le.update?"available":"up-to-date",!0)}catch(le){o(t,"failed"),o(u,`${le}`)}}async function b(){var le;if((le=e(r))!=null&&le.can_self_update){o(t,"installing"),o(u,null),o(c,{downloaded:0,total:e(r).download_size},!0);try{await E("install_update")}catch(W){o(t,"failed"),o(u,`${W}`)}}}async function m(){await E("dismiss_update")}async function _(){var le,W;try{await Uo((W=(le=e(r))==null?void 0:le.release_url)!=null?W:"https://github.com/JRufer/VoxCtrl/releases/latest")}catch(ae){console.error("Could not open the release page:",ae)}}var x=zb(),M=n(x),q=n(M),T=n(q),D=i(T,2),se=n(D),ne=n(se);{var fe=le=>{var W=Be("VoxCtrl is up to date");d(le,W)},Q=le=>{var W=Be();w(()=>{var ae,O;return y(W,`Restarting into ${(O=(ae=e(r))==null?void 0:ae.version)!=null?O:""}`)}),d(le,W)},z=le=>{var W=Be();w(()=>{var ae,O;return y(W,`Updating to ${(O=(ae=e(r))==null?void 0:ae.version)!=null?O:""}`)}),d(le,W)},I=le=>{var W=Be();w(()=>{var ae;return y(W,`VoxCtrl ${(ae=e(r).version)!=null?ae:""} is available`)}),d(le,W)},L=le=>{var W=Be("Checking for updates…");d(le,W)};k(ne,le=>{e(t)==="up-to-date"?le(fe):e(t)==="installed"?le(Q,1):e(t)==="installing"?le(z,2):e(r)?le(I,3):le(L,-1)})}var ge=i(se,2);{var ee=le=>{var W=fb(),ae=n(W);w(()=>{var O,X;return y(ae,`You have ${(O=e(r).current_version)!=null?O:""} — ${(X=e(r).version)!=null?X:""} is the latest release.`)}),d(le,W)},K=le=>{var W=_b(),ae=n(W);w(()=>{var O;return y(ae,`Version ${(O=e(l))!=null?O:""} is the latest release.`)}),d(le,W)};k(ge,le=>{e(r)&&e(t)!=="up-to-date"?le(ee):e(t)==="up-to-date"&&le(K,1)})}var V=i(q,2);{var oe=le=>{var W=hb();d(le,W)},R=le=>{var W=gb();d(le,W)},B=le=>{var W=Tb(),ae=ht(W);{var O=de=>{var Y=mb(),U=i(n(Y),2),te=n(U);w(()=>y(te,e(r).notes)),d(de,Y)};k(ae,de=>{e(r).notes&&de(O)})}var X=i(ae,2);{var ve=de=>{var Y=bb(),U=n(Y);w(()=>y(U,e(r).unsupported_reason)),d(de,Y)};k(X,de=>{!e(r).can_self_update&&e(r).unsupported_reason&&de(ve)})}var Me=i(X,2);{var Fe=de=>{var Y=yb(),U=n(Y);let te;var G=n(U),_e=i(U,2),me=n(_e);{var pe=Ye=>{var st=Be();w(()=>{var it,H;return y(st,`Downloading ${(H=(it=e(r).asset_name)!=null?it:"the update")!=null?H:""}…`)}),d(Ye,st)},ze=Ye=>{var st=Be();w(it=>{var H;return y(st,`Downloading — ${(H=e(f))!=null?H:""}% of ${it!=null?it:""}`)},[()=>{var it,H;return Ol((H=(it=e(c))==null?void 0:it.total)!=null?H:e(r).download_size)}]),d(Ye,st)};k(me,Ye=>{e(f)===null?Ye(pe):Ye(ze,-1)})}w(()=>{te=Te(U,1,"bar svelte-15mrihi",null,te,{indeterminate:e(f)===null}),na(G,e(f)===null?"":`width: ${e(f)}%`)}),d(de,Y)},he=de=>{var Y=wb();d(de,Y)},re=de=>{var Y=kb(),U=n(Y);w(te=>y(U,`VoxCtrl will download ${te!=null?te:""}, verify it against the checksum
GitHub published, replace itself and restart. Your settings, models and voices are not
- touched.`),[()=>Ol(e(r).download_size)]),d(de,$)};k(Ae,de=>{e(t)==="installing"?de(Fe):e(t)==="installed"?de(he,1):e(r).can_self_update&&de(re,2)})}var we=i(Ae,2);{var Je=de=>{var $=xb(),U=ht($),te=n(U);w(()=>y(te,e(u))),d(de,$)};k(we,de=>{e(t)==="failed"&&e(u)&&de(Je)})}d(le,W)},be=le=>{var W=Sb(),ae=n(W);w(()=>y(ae,e(u))),d(le,W)};k(V,le=>{e(t)==="checking"?le(oe):e(t)==="up-to-date"?le(R,1):e(r)?le(B,2):e(t)==="failed"&&e(u)&&le(be,3)})}var Pe=i(V,2),ue=n(Pe);{var K=le=>{var W=Eb();w(()=>W.disabled=e(t)==="installing"),N("click",W,m),d(le,W)},J=le=>{var W=Cb();N("click",W,m),d(le,W)},Se=le=>{var W=Pb(),ae=ht(W),O=n(ae),X=i(ae,2),ve=n(X),Ae=i(ve,2);{var Fe=re=>{var we=Ab();N("click",we,b),d(re,we)},he=re=>{var we=Mb();N("click",we,_),d(re,we)};k(Ae,re=>{e(r).can_self_update?re(Fe):re(he,-1)})}N("click",O,_),N("click",ve,m),d(le,W)},De=le=>{var W=Db();N("click",W,m),d(le,W)};k(ue,le=>{e(t)==="installing"||e(t)==="installed"?le(K):e(t)==="up-to-date"?le(J,1):e(r)?le(Se,2):le(De,-1)})}w(()=>mt(T,"src",nr)),d(s,x),St()}Qt(["click"]);function Ob(s){const a=window.location.pathname;function t(){return a.startsWith("/overlay")?"overlay":a.startsWith("/udev-warning")?"udev-warning":a.startsWith("/wizard")?"wizard":a.startsWith("/update")?"update":"settings"}const r=t();r==="overlay"&&(document.documentElement.classList.add("overlay-window"),document.body.classList.add("overlay-window"));var l=xi(),c=ht(l);{var u=m=>{X_(m,{})},v=m=>{Oh(m,{})},f=m=>{ub(m,{})},h=m=>{Ib(m,{})},b=m=>{y_(m,{})};k(c,m=>{r==="overlay"?m(u):r==="udev-warning"?m(v,1):r==="wizard"?m(f,2):r==="update"?m(h,3):m(b,-1)})}d(s,l)}bd(Ob,{target:document.getElementById("app")});
+ touched.`),[()=>Ol(e(r).download_size)]),d(de,Y)};k(Me,de=>{e(t)==="installing"?de(Fe):e(t)==="installed"?de(he,1):e(r).can_self_update&&de(re,2)})}var we=i(Me,2);{var Je=de=>{var Y=xb(),U=ht(Y),te=n(U);w(()=>y(te,e(u))),d(de,Y)};k(we,de=>{e(t)==="failed"&&e(u)&&de(Je)})}d(le,W)},be=le=>{var W=Sb(),ae=n(W);w(()=>y(ae,e(u))),d(le,W)};k(V,le=>{e(t)==="checking"?le(oe):e(t)==="up-to-date"?le(R,1):e(r)?le(B,2):e(t)==="failed"&&e(u)&&le(be,3)})}var Ae=i(V,2),ue=n(Ae);{var j=le=>{var W=Eb();w(()=>W.disabled=e(t)==="installing"),N("click",W,m),d(le,W)},J=le=>{var W=Cb();N("click",W,m),d(le,W)},Se=le=>{var W=Ab(),ae=ht(W),O=n(ae),X=i(ae,2),ve=n(X),Me=i(ve,2);{var Fe=re=>{var we=Mb();N("click",we,b),d(re,we)},he=re=>{var we=Pb();N("click",we,_),d(re,we)};k(Me,re=>{e(r).can_self_update?re(Fe):re(he,-1)})}N("click",O,_),N("click",ve,m),d(le,W)},De=le=>{var W=Db();N("click",W,m),d(le,W)};k(ue,le=>{e(t)==="installing"||e(t)==="installed"?le(j):e(t)==="up-to-date"?le(J,1):e(r)?le(Se,2):le(De,-1)})}w(()=>mt(T,"src",nr)),d(s,x),St()}Qt(["click"]);function Ob(s){const a=window.location.pathname;function t(){return a.startsWith("/overlay")?"overlay":a.startsWith("/udev-warning")?"udev-warning":a.startsWith("/wizard")?"wizard":a.startsWith("/update")?"update":"settings"}const r=t();r==="overlay"&&(document.documentElement.classList.add("overlay-window"),document.body.classList.add("overlay-window"));var l=xi(),c=ht(l);{var u=m=>{X_(m,{})},v=m=>{Oh(m,{})},f=m=>{ub(m,{})},h=m=>{Ib(m,{})},b=m=>{y_(m,{})};k(c,m=>{r==="overlay"?m(u):r==="udev-warning"?m(v,1):r==="wizard"?m(f,2):r==="update"?m(h,3):m(b,-1)})}d(s,l)}bd(Ob,{target:document.getElementById("app")});
diff --git a/dist/index.html b/dist/index.html
index e36c89e..91845bc 100644
--- a/dist/index.html
+++ b/dist/index.html
@@ -16,7 +16,7 @@
-
+
diff --git a/src/lib/Wizard/wizard-data.ts b/src/lib/Wizard/wizard-data.ts
index fd592db..3542ac4 100644
--- a/src/lib/Wizard/wizard-data.ts
+++ b/src/lib/Wizard/wizard-data.ts
@@ -384,6 +384,16 @@ const KEYCAP_LABELS: Record = {
KEY_KPDOT: "Num .",
KEY_KPENTER: "Num Enter",
KEY_KPEQUAL: "Num =",
+ KEY_102ND: "<",
+ KEY_SYSRQ: "PrtSc",
+ KEY_COMPOSE: "Menu",
+ KEY_MUTE: "Mute",
+ KEY_VOLUMEDOWN: "Vol -",
+ KEY_VOLUMEUP: "Vol +",
+ KEY_NEXTSONG: "Next",
+ KEY_PREVIOUSSONG: "Prev",
+ KEY_STOPCD: "Stop",
+ KEY_PLAYPAUSE: "Play/Pause",
};
/** Human label for an evdev key name, for keycaps and summaries. */
diff --git a/src/lib/keys.ts b/src/lib/keys.ts
index ac17a89..c2b5461 100644
--- a/src/lib/keys.ts
+++ b/src/lib/keys.ts
@@ -55,8 +55,24 @@ const CODE_TO_EVDEV: Record = {
NumpadDecimal: "KEY_KPDOT",
NumpadEnter: "KEY_KPENTER",
NumpadEqual: "KEY_KPEQUAL",
+
+ // Keys whose DOM name is not evdev's.
+ PrintScreen: "KEY_SYSRQ",
+ ContextMenu: "KEY_COMPOSE",
+
+ // Media keys, when the webview delivers them at all.
+ AudioVolumeMute: "KEY_MUTE",
+ AudioVolumeDown: "KEY_VOLUMEDOWN",
+ AudioVolumeUp: "KEY_VOLUMEUP",
+ MediaTrackNext: "KEY_NEXTSONG",
+ MediaTrackPrevious: "KEY_PREVIOUSSONG",
+ MediaStop: "KEY_STOPCD",
+ MediaPlayPause: "KEY_PLAYPAUSE",
};
+/** The `code` values mapped through the table above, for tests. */
+export const MAPPED_CODES: readonly string[] = Object.keys(CODE_TO_EVDEV);
+
/**
* Map a browser key event onto the evdev name VoxCtrl stores in bindings.toml.
*
diff --git a/tests/svelte/keys.test.ts b/tests/svelte/keys.test.ts
new file mode 100644
index 0000000..657bdf9
--- /dev/null
+++ b/tests/svelte/keys.test.ts
@@ -0,0 +1,85 @@
+import { readFileSync } from "node:fs";
+import { resolve } from "node:path";
+import { describe, test, expect } from "vitest";
+import { MAPPED_CODES, mapBrowserKeyToEvdev } from "../../src/lib/keys";
+import { keycapLabel } from "../../src/lib/Wizard/wizard-data";
+
+/**
+ * The backends' key vocabulary, read out of `keymap::NAMES` in the Rust source
+ * so the recorder and the backends cannot drift apart unnoticed. The Linux
+ * backends take their names from the evdev crate, and this table spells out
+ * the same names for Windows.
+ */
+function backendKeyNames(): Set {
+ // Vitest runs from the repository root.
+ const path = resolve(process.cwd(), "crates/voxctrl-hotkeys/src/win_keys.rs");
+ const src = readFileSync(path, "utf8");
+ const table = /pub const NAMES: &\[&str\] = &\[([\s\S]*?)\];/.exec(src);
+ if (!table) throw new Error("keymap::NAMES not found in win_keys.rs");
+ return new Set([...table[1].matchAll(/"(KEY_[A-Z0-9_]+)"/g)].map((m) => m[1]));
+}
+
+/**
+ * Valid evdev names the Windows table has no scan code for. They work on
+ * Linux, which is where the keys exist in practice.
+ */
+const LINUX_ONLY = new Set(["KEY_KPEQUAL"]);
+
+describe("mapBrowserKeyToEvdev against the backends' key table", () => {
+ const known = backendKeyNames();
+
+ test("the table was read", () => {
+ expect(known.size).toBeGreaterThan(90);
+ });
+
+ test("every key the recorder can name is one a backend reports", () => {
+ const codes = [
+ ...MAPPED_CODES,
+ ...[..."ABCDEFGHIJKLMNOPQRSTUVWXYZ"].map((c) => `Key${c}`),
+ ...[..."0123456789"].map((d) => `Digit${d}`),
+ // F13–F24 are valid evdev names too, but the Windows table stops at F12.
+ ...Array.from({ length: 12 }, (_, i) => `F${i + 1}`),
+ "Space",
+ "Enter",
+ "Escape",
+ "Tab",
+ "Backspace",
+ "Delete",
+ "Insert",
+ "Home",
+ "End",
+ "PageUp",
+ "PageDown",
+ "ArrowUp",
+ "ArrowDown",
+ "ArrowLeft",
+ "ArrowRight",
+ "CapsLock",
+ "NumLock",
+ "ScrollLock",
+ "Pause",
+ "PrintScreen",
+ "ContextMenu",
+ "AudioVolumeMute",
+ "MediaPlayPause",
+ ];
+ const unknown = codes
+ .map((code) => [code, mapBrowserKeyToEvdev("", code)] as const)
+ .filter(([, name]) => !known.has(name) && !LINUX_ONLY.has(name));
+ expect(unknown).toEqual([]);
+ });
+
+ test("keys whose DOM name differs from evdev's use evdev's", () => {
+ expect(mapBrowserKeyToEvdev("PrintScreen", "PrintScreen")).toBe("KEY_SYSRQ");
+ expect(mapBrowserKeyToEvdev("ContextMenu", "ContextMenu")).toBe("KEY_COMPOSE");
+ expect(mapBrowserKeyToEvdev("AudioVolumeMute", "AudioVolumeMute")).toBe("KEY_MUTE");
+ expect(mapBrowserKeyToEvdev("MediaPlayPause", "MediaPlayPause")).toBe("KEY_PLAYPAUSE");
+ });
+
+ test("every mapped key has a readable keycap", () => {
+ for (const code of MAPPED_CODES) {
+ const label = keycapLabel(mapBrowserKeyToEvdev("", code));
+ expect(label, code).not.toMatch(/^(KEY_|KP|AUDIO|MEDIA)/);
+ }
+ });
+});