livedesk 0.1.615 → 0.1.617
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/client/package.json +5 -5
- package/package.json +6 -6
- package/web/dist/app.webmanifest +1 -1
- package/web/dist/assets/{LiveDeskApp-D3LPrsCg.js → LiveDeskApp-HaQ9U3be.js} +1 -1
- package/web/dist/assets/{index-Dw4bFnPQ.js → index-CqZbwCrG.js} +2 -2
- package/web/dist/index.html +1 -1
- package/web/dist/livedesk-build-evidence.json +12 -12
- package/web/dist/sw.js +1 -1
package/client/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@livedesk/client",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.266",
|
|
4
4
|
"description": "VuvoDesk local remote client",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -42,10 +42,10 @@
|
|
|
42
42
|
"ws": "^8.18.3"
|
|
43
43
|
},
|
|
44
44
|
"optionalDependencies": {
|
|
45
|
-
"@livedesk/fast-linux-x64": "0.1.
|
|
46
|
-
"@livedesk/fast-osx-arm64": "0.1.
|
|
47
|
-
"@livedesk/fast-osx-x64": "0.1.
|
|
48
|
-
"@livedesk/fast-win-x64": "0.1.
|
|
45
|
+
"@livedesk/fast-linux-x64": "0.1.462",
|
|
46
|
+
"@livedesk/fast-osx-arm64": "0.1.462",
|
|
47
|
+
"@livedesk/fast-osx-x64": "0.1.462",
|
|
48
|
+
"@livedesk/fast-win-x64": "0.1.462"
|
|
49
49
|
},
|
|
50
50
|
"publishConfig": {
|
|
51
51
|
"access": "public"
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "livedesk",
|
|
3
|
-
"version": "0.1.
|
|
4
|
-
"livedeskClientVersion": "0.1.
|
|
3
|
+
"version": "0.1.617",
|
|
4
|
+
"livedeskClientVersion": "0.1.266",
|
|
5
5
|
"buildFlavor": "production",
|
|
6
6
|
"description": "VuvoDesk Hub and client launcher",
|
|
7
7
|
"type": "module",
|
|
@@ -51,10 +51,10 @@
|
|
|
51
51
|
"ws": "^8.18.3"
|
|
52
52
|
},
|
|
53
53
|
"optionalDependencies": {
|
|
54
|
-
"@livedesk/fast-linux-x64": "0.1.
|
|
55
|
-
"@livedesk/fast-osx-arm64": "0.1.
|
|
56
|
-
"@livedesk/fast-osx-x64": "0.1.
|
|
57
|
-
"@livedesk/fast-win-x64": "0.1.
|
|
54
|
+
"@livedesk/fast-linux-x64": "0.1.462",
|
|
55
|
+
"@livedesk/fast-osx-arm64": "0.1.462",
|
|
56
|
+
"@livedesk/fast-osx-x64": "0.1.462",
|
|
57
|
+
"@livedesk/fast-win-x64": "0.1.462"
|
|
58
58
|
},
|
|
59
59
|
"publishConfig": {
|
|
60
60
|
"access": "public"
|
package/web/dist/app.webmanifest
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{j as r,M as op,w as wv,D as rn,r as Ya,g as Gl,i as ru,h as We,c as bu,a as wu,n as yv,b as Yy,d as Xy,e as Kl,f as xv,k as Sv,l as Jy,m as Hf,p as Ms,P as zi,F as Sl}from"./index-Dw4bFnPQ.js";import{a as i,m as nc,k as sn,n as Xa,B as Zy,P as ip,X as Sn,o as lc,l as Ns,F as Wf,p as Rs,q as Cv,s as ex,t as zf,u as Vf,v as tx,D as uc,b as Fn,w as nx,x as kv,y as rx,z as sx,g as ls,c as dn,H as su,I as rc,J as au,K as is,O as cp,Q as ax,U as Mv,V as qf,Y as ox,Z as ix,_ as qa,W as yu,$ as cx,a0 as lx,a1 as ai,a2 as sc,a3 as ux,a4 as lp,S as ta,a5 as Av,a6 as Rv,a7 as dx,a8 as px,a9 as mx,aa as Hp,ab as fx,N as Wp,ac as Nv,ad as hx,ae as cs,af as Uf,C as zp,ag as xu,ah as dc,ai as ac,aj as Tv,ak as gx,al as Iv,am as vx,an as Pv,ao as bx,ap as jv,aq as wx,ar as up,as as Ev,at as yx,au as xx,av as Sx,aw as Cx,ax as Fv,ay as kx,az as Gf,aA as Mx,aB as Ax,aC as Rx,aD as Dv,f as Ql,T as Yl,A as Nx,E as Tx,aE as Kf,aF as kd,aG as Ix,aH as Qf,aI as Px,aJ as _v,aK as jx,aL as Ex,aM as Fx,G as Dx}from"./icons-tFaWqIIe.js";import{c as _x}from"./supabase-C7qjtLN3.js";import{r as Lx}from"./react-BQos8uGS.js";const Ox="https://otbyfkjxrkngvjziawki.supabase.co",$x="sb_publishable_NpUs0RDJH2YnllsqTKO6TQ_1jTdSsNQ",Bx={getItem:()=>null,setItem:()=>{},removeItem:()=>{}},Md=typeof window<"u"&&!!window.liveDesk,mt=_x(Ox,$x,{auth:{autoRefreshToken:!Md,persistSession:!Md,storage:Md?Bx:void 0,detectSessionInUrl:!0,flowType:"pkce",storageKey:"livedesk.mindexec.supabase.auth"}}),Hx=new Set(["browserLanguage","platform","online","viewport","timezone","screen"]),Wx={id:"browser-safe-v1",collect(){if(typeof navigator>"u")return{};const e={browserLanguage:navigator.language||"",platform:navigator.platform||"",online:navigator.onLine,timezone:typeof Intl>"u"?"":Intl.DateTimeFormat().resolvedOptions().timeZone||"",viewport:typeof window>"u"?void 0:{width:window.innerWidth,height:window.innerHeight},screen:typeof window>"u"?void 0:{width:window.screen.width,height:window.screen.height}};return Object.fromEntries(Object.entries(e).filter(([t,n])=>Hx.has(t)&&n!==void 0))}};function zx(e,t="Support request failed."){if(e&&typeof e=="object"&&"message"in e){const n=String(e.message||"").trim();if(n)return n.replace(/^.*Support request failed:\s*/i,"")}return e instanceof Error?e.message:t}function Vx(e=Wx){return e.collect()}async function qx(e,t="livedesk"){const{data:n,error:s}=await mt.from("app_admins").select("role").eq("user_id",e).limit(1);if(s)throw s;const a=n?.[0]?.role||"user";if(a!=="owner"){const{error:w}=await mt.rpc("register_product_access",{p_product_key:t,p_access_type:"free"});if(w)throw w}const[o,c,u]=await Promise.all([mt.from("products").select("id, product_key, name, description, sort_order").order("sort_order"),mt.from("product_admins").select("product_id, role").eq("user_id",e),mt.from("user_products").select("product_id").eq("user_id",e).eq("is_active",!0)]);if(o.error)throw o.error;if(c.error)throw c.error;if(u.error)throw u.error;const d=o.data||[],p=(c.data||[]).map(w=>String(w.product_id)),f=(u.data||[]).map(w=>String(w.product_id)),m=a==="owner",g=m?d.map(w=>w.id):[...new Set([...p,...f])];return{products:d,access:{userId:e,globalRole:a,accessibleProductIds:g,managedProductIds:m?d.map(w=>w.id):p,canViewAllProducts:m,canViewAllPrivatePosts:m,canManageAllProducts:m,canCreateAnnouncements:m||p.length>0}}}async function Ux(e=""){const{data:t,error:n}=await mt.rpc("search_support_posts",{p_query:e.trim()||null,p_limit:250});if(n)throw n;return t||[]}async function Gx(e){const{data:t,error:n}=await mt.from("support_attachments").select("*").eq("post_id",e).order("created_at");if(n)throw n;const s=t||[];return Promise.all(s.map(async a=>{const o=await mt.storage.from("support-attachments").createSignedUrl(a.storage_path,3600);return{...a,signed_url:o.data?.signedUrl||void 0}}))}async function Kx(){const{data:e,error:t}=await mt.from("support_notifications").select("*").order("created_at",{ascending:!1}).limit(30);if(t)throw t;return e||[]}async function Qx(e){const{error:t}=await mt.rpc("mark_support_notification_read",{p_notification_id:e});if(t)throw t}async function Yf(e){const{data:t,error:n}=await mt.from("support_comments").select("*").eq("post_id",e).order("created_at");if(n)throw n;return t||[]}async function Yx(e){const{data:t,error:n}=await mt.from("support_votes").select("post_id").eq("user_id",e);if(n)throw n;return new Set((t||[]).map(s=>String(s.post_id)))}async function Xx(e){const{data:t,error:n}=await mt.rpc("create_support_post",{p_product_id:e.productId,p_post_type:e.postType,p_title:e.title,p_body:e.body,p_visibility:e.visibility,p_app_version:e.appVersion||null,p_platform:typeof navigator>"u"?null:navigator.platform||null,p_os_version:typeof navigator>"u"?null:navigator.platform||null,p_environment:e.includeEnvironment?Vx():{}});if(n)throw n;const s=Array.isArray(t)?t[0]?.post_id:t?.post_id;if(!s)throw new Error("Support post was not created.");return String(s)}const Jx=new Set(["image/png","image/jpeg","image/webp","text/plain","text/markdown","application/json","application/pdf"]);async function Zx(e,t){if(!Jx.has(t.type))throw new Error("This file type is not allowed.");if(t.size<=0||t.size>10*1024*1024)throw new Error("Attachments must be smaller than 10 MB.");const n=t.name.replace(/[^a-zA-Z0-9._-]+/g,"-").replace(/^-+|-+$/g,"")||"attachment",s=typeof crypto<"u"&&"randomUUID"in crypto?crypto.randomUUID():`${Date.now()}-${Math.random().toString(16).slice(2)}`,a=`${e}/${s}-${n}`,o=await mt.storage.from("support-attachments").upload(a,t,{contentType:t.type,upsert:!1});if(o.error)throw o.error;const{data:c,error:u}=await mt.rpc("add_support_attachment",{p_post_id:e,p_storage_path:a,p_file_name:n,p_mime_type:t.type,p_size_bytes:t.size});if(u)throw await mt.storage.from("support-attachments").remove([a]),u;const d=Array.isArray(c)?c[0]?.attachment_id:c?.attachment_id;if(!d)throw new Error("Attachment metadata was not created.");return String(d)}async function eS(e,t,n,s){const{error:a}=await mt.rpc("update_support_post",{p_post_id:e,p_title:t,p_body:n,p_visibility:s});if(a)throw a}async function tS(e,t){const{error:n}=await mt.rpc("add_support_comment",{p_post_id:e,p_body:t});if(n)throw n}async function nS(e){const{data:t,error:n}=await mt.rpc("toggle_support_vote",{p_post_id:e});if(n)throw n;const s=Array.isArray(t)?t[0]:t;return{voted:!!s?.voted,totalVotes:Number(s?.total_votes||0)}}async function rS(e,t){const{error:n}=await mt.rpc("change_support_post_status",{p_post_id:e,p_target_status:t});if(n)throw n}async function sS(e){const{error:t}=await mt.rpc("set_support_post_hidden",{p_post_id:e,p_hidden:!0});if(t)throw t}async function aS(e,t){const{error:n}=await mt.rpc("set_support_post_locked",{p_post_id:e,p_locked:t});if(n)throw n}async function oS(e,t){const{error:n}=await mt.rpc("set_support_post_pinned",{p_post_id:e,p_pinned:t});if(n)throw n}async function iS(e,t){const{error:n}=await mt.rpc("mark_support_duplicate",{p_post_id:e,p_duplicate_of_post_id:t});if(n)throw n}async function cS(e,t){const{error:n}=await mt.rpc("accept_support_answer",{p_post_id:e,p_comment_id:t});if(n)throw n}async function lS(e,t=!0){const{error:n}=await mt.rpc("hide_support_comment",{p_comment_id:e,p_hidden:t});if(n)throw n}const dp=[{id:"question",label:"Questions",shortLabel:"Question"},{id:"issue",label:"Issues",shortLabel:"Issue"},{id:"feature",label:"Feature Requests",shortLabel:"Feature"},{id:"announcement",label:"Announcements",shortLabel:"Announcement"}],uS=[{id:"all",label:"All statuses"},{id:"needs-response",label:"Needs response"},{id:"open",label:"Open"},{id:"needs-info",label:"Needs more information"},{id:"in-progress",label:"In progress"},{id:"planned",label:"Planned"},{id:"released",label:"Released"},{id:"closed",label:"Closed"}],dS={question:["open","answered","resolved","closed"],issue:["open","needs-info","confirmed","in-progress","fixed","closed"],feature:["under-review","planned","in-progress","released","declined","closed"],announcement:["published","archived"]},pS={type:"all",product:"",status:"all",visibility:"all",sort:"recent",query:""};function Ad(){if(typeof window>"u")return pS;const e=new URLSearchParams(window.location.search),t=window.location.pathname.match(/^\/support\/(questions|issues|features|announcements)$/)?.[1],n=e.get("type")||t||"",s=n==="questions"||n==="question"?"question":n==="issues"||n==="issue"?"issue":n==="features"||n==="feature"?"feature":n==="announcements"||n==="announcement"?"announcement":"all",a=e.get("visibility"),o=e.get("sort");return{type:s,product:e.get("product")||"",status:e.get("status")||"all",visibility:a==="public"||a==="private"?a:"all",sort:o==="votes"||o==="newest"?o:"recent",query:e.get("q")||""}}function mS(e){return e==="all"?"":e==="question"?"questions":e==="issue"?"issues":e==="feature"?"features":"announcements"}function fS(e,t){const n={...e,...t},s=new URLSearchParams;n.product&&s.set("product",n.product),n.status!=="all"&&s.set("status",n.status),n.visibility!=="all"&&s.set("visibility",n.visibility),n.sort!=="recent"&&s.set("sort",n.sort),n.query&&s.set("q",n.query);const a=mS(n.type),o=s.toString();return`/support${a?`/${a}`:""}${o?`?${o}`:""}`}function Cl(e){const t=new Date(e);return Number.isFinite(t.getTime())?t.toLocaleString(void 0,{dateStyle:"medium",timeStyle:"short"}):e}function Rd(e){return e.replaceAll("-"," ").replace(/\b\w/g,t=>t.toUpperCase())}function Xf(e){return e==="question"?nx:e==="issue"?kv:e==="feature"?rx:sx}function Jf(e){return dp.find(t=>t.id===e)?.shortLabel||e}function Yn(e){const t=zx(e);return/relation .* does not exist|function .* does not exist|schema cache/i.test(t)?"Support Board database is not installed yet. Apply the latest Supabase migration first.":/not-authenticated|jwt/i.test(t)?"Sign in again to use Support.":/product-access-denied|product-not-found/i.test(t)?"You do not have access to this product.":t}function Lv({session:e,currentProductKey:t="livedesk",appVersion:n="",onSignIn:s}){const[a,o]=i.useState(()=>Ad()),[c,u]=i.useState(null),[d,p]=i.useState([]),[f,m]=i.useState([]),[g,w]=i.useState(""),[b,y]=i.useState([]),[C,A]=i.useState([]),[k,R]=i.useState([]),[_,E]=i.useState(()=>new Set),[L,M]=i.useState(!0),[U,V]=i.useState(""),[T,j]=i.useState(""),[$,Q]=i.useState(!1),[G,q]=i.useState(!1),[re,I]=i.useState(""),[X,le]=i.useState(()=>Ad().query),[K,ue]=i.useState(!1),[se,ve]=i.useState(!1),[Me,Te]=i.useState(""),[ke,pe]=i.useState(""),[J,Ie]=i.useState("free"),[_e,De]=i.useState(""),[Xe,ne]=i.useState(""),[ae,me]=i.useState("admin"),[oe,ee]=i.useState(""),[Se,de]=i.useState(""),[Fe,qe]=i.useState([]),[N,we]=i.useState({productId:"",postType:"question",title:"",body:"",visibility:"public",includeEnvironment:!0,files:[]}),Le=i.useCallback(F=>{const Pe={...a,...F};o(Pe),typeof window<"u"&&window.history.pushState({},"",fS(a,F))},[a]);i.useEffect(()=>{const F=()=>o(Ad());return window.addEventListener("popstate",F),()=>window.removeEventListener("popstate",F)},[]);const Je=i.useCallback(async()=>{const F=await Ux(a.query);return m(F),e?.user.id&&E(await Yx(e.user.id)),F},[a.query,e?.user.id]),Oe=i.useCallback(async()=>{if(!e?.user.id){u(null),p([]),m([]),w(""),R([]),M(!1);return}M(!0),j("");try{const F=await qx(e.user.id,t);u(F.access),p(F.products),await Je(),R(await Kx())}catch(F){j(Yn(F))}finally{M(!1)}},[t,Je,e?.user.id]);i.useEffect(()=>{Oe()},[Oe]);const $e=i.useMemo(()=>{if(!c)return[];const F=d.find(Pe=>Pe.product_key===t);return F?c.canViewAllProducts||c.accessibleProductIds.includes(F.id)?[F]:[]:[]},[c,t,d]),ft=$e[0]?.id||"",rt=i.useMemo(()=>{const F=new Map(d.map(Ue=>[Ue.id,Ue.product_key]));return[...f.filter(Ue=>a.type!=="all"&&Ue.post_type!==a.type||!ft||Ue.product_id!==ft||a.status==="needs-response"&&!["open","needs-info"].includes(Ue.status)||a.status!=="all"&&a.status!=="needs-response"&&Ue.status!==a.status||a.visibility!=="all"&&Ue.visibility!==a.visibility?!1:F.has(Ue.product_id))].sort((Ue,Ke)=>a.sort==="votes"?Ke.vote_count-Ue.vote_count||Ke.updated_at.localeCompare(Ue.updated_at):a.sort==="newest"?Ke.created_at.localeCompare(Ue.created_at):Number(Ke.is_pinned)-Number(Ue.is_pinned)||Ke.updated_at.localeCompare(Ue.updated_at))},[f,d,a.sort,a.status,a.type,a.visibility,ft]),ge=rt.find(F=>F.id===g)||rt[0]||null,ct=!!(ge&&c&&(c.canViewAllProducts||c.managedProductIds.includes(ge.product_id))),fe=!!(ge&&e?.user.id===ge.author_id)||ct;i.useEffect(()=>{if(!ge){w(""),y([]),q(!1);return}ge.id!==g&&w(ge.id)},[ge,g]),i.useEffect(()=>{let F=!0;return g?(Yf(g).then(Pe=>{F&&y(Pe)}).catch(Pe=>{F&&j(Yn(Pe))}),Gx(g).then(Pe=>{F&&A(Pe)}).catch(Pe=>{F&&j(Yn(Pe))}),()=>{F=!1}):(y([]),A([]),()=>{F=!1})},[g]),i.useEffect(()=>{!N.productId&&$e[0]&&we(F=>({...F,productId:ft||$e[0].id}))},[$e,N.productId,ft]),i.useEffect(()=>{le(a.query)},[a.query]),i.useEffect(()=>{!ke&&$e[0]&&pe($e[0].id),!Xe&&$e[0]&&ne($e[0].id)},[$e,ke,Xe]);const Z=F=>{ge&&m(Pe=>Pe.map(Ue=>Ue.id===ge.id?{...Ue,...F}:Ue))},D=async F=>{if(F.preventDefault(),!(!e||!N.productId)){V("create"),j("");try{const Pe=await Xx({productId:N.productId,postType:N.postType,title:N.title,body:N.body,visibility:N.postType==="announcement"?"public":N.visibility,appVersion:n,includeEnvironment:N.postType==="issue"&&N.includeEnvironment});for(const Ke of Fe)await Zx(Pe,Ke);const Ue=await Je();Q(!1),qe([]),we(Ke=>({...Ke,title:"",body:"",files:[]})),w(Pe),Ue.some(Ke=>Ke.id===Pe)||await Oe()}catch(Pe){j(Yn(Pe))}finally{V("")}}},Y=async F=>{if(F.preventDefault(),!!ge){V("edit"),j("");try{await eS(ge.id,ge.title,ge.body,ge.visibility),q(!1),await Je()}catch(Pe){j(Yn(Pe))}finally{V("")}}},ie=async F=>{if(F.preventDefault(),!(!ge||!re.trim())){V("comment"),j("");try{await tS(ge.id,re),I(""),y(await Yf(ge.id)),await Je()}catch(Pe){j(Yn(Pe))}finally{V("")}}},Re=async()=>{if(!(!ge||ge.post_type!=="feature")){V("vote"),j("");try{const F=await nS(ge.id);E(Pe=>{const Ue=new Set(Pe);return F.voted?Ue.add(ge.id):Ue.delete(ge.id),Ue}),Z({vote_count:F.totalVotes})}catch(F){j(Yn(F))}finally{V("")}}},P=async F=>{if(ge){V("status"),j("");try{await rS(ge.id,F),Z({status:F}),await Je()}catch(Pe){j(Yn(Pe))}finally{V("")}}},ce=async()=>{if(!(!ge||!window.confirm("Hide this Support post from the board?"))){V("hide"),j("");try{await sS(ge.id),w(""),await Je()}catch(F){j(Yn(F))}finally{V("")}}},be=async()=>{if(ge){V("lock"),j("");try{await aS(ge.id,!ge.is_locked),Z({is_locked:!ge.is_locked}),await Je()}catch(F){j(Yn(F))}finally{V("")}}},Be=async()=>{if(ge){V("pin"),j("");try{await oS(ge.id,!ge.is_pinned),Z({is_pinned:!ge.is_pinned}),await Je()}catch(F){j(Yn(F))}finally{V("")}}},nt=async F=>{if(ge){V(`accept-${F}`),j("");try{await cS(ge.id,F),Z({accepted_comment_id:F,status:ge.post_type==="question"?"answered":ge.status}),await Je()}catch(Pe){j(Yn(Pe))}finally{V("")}}},He=async()=>{if(!(!ge||!oe||oe===ge.id)){V("duplicate"),j("");try{await iS(ge.id,oe),w(""),ee(""),await Je()}catch(F){j(Yn(F))}finally{V("")}}},dt=async F=>{if(!F.read_at)try{await Qx(F.id),R(Pe=>Pe.map(Ue=>Ue.id===F.id?{...Ue,read_at:new Date().toISOString()}:Ue))}catch(Pe){j(Yn(Pe))}F.post_id&&w(F.post_id),ue(!1)};return e?L&&!c?r.jsxs("section",{className:"support-page support-loading",children:[r.jsx(Xa,{className:"support-spin",size:23})," Loading Support Board..."]}):r.jsxs("section",{className:"support-page",children:[r.jsx("header",{className:"support-page-header support-page-actions-only",children:r.jsxs("div",{className:"support-header-actions",children:[r.jsxs("div",{className:"support-notification-wrap",children:[r.jsxs("button",{className:"support-secondary-button",type:"button",onClick:()=>ue(F=>!F),title:"Notifications",children:[r.jsx(Zy,{size:16})," ",k.filter(F=>!F.read_at).length>0&&r.jsx("b",{children:k.filter(F=>!F.read_at).length})]}),K&&r.jsxs("div",{className:"support-notification-popover",children:[r.jsx("strong",{children:"Notifications"}),k.length===0?r.jsx("span",{className:"support-muted",children:"No notifications yet."}):k.map(F=>r.jsxs("button",{type:"button",className:F.read_at?"":"unread",onClick:()=>{dt(F)},children:[r.jsx("b",{children:F.title}),r.jsx("span",{children:F.body}),r.jsx("small",{children:Cl(F.created_at)})]},F.id))]})]}),c?.canViewAllProducts&&r.jsxs("button",{className:"support-secondary-button",type:"button",onClick:()=>ve(F=>!F),children:[r.jsx(sn,{size:16})," Admin"]}),r.jsxs("button",{className:"support-secondary-button",type:"button",onClick:()=>{Oe()},disabled:L,children:[r.jsx(Xa,{size:16,className:L?"support-spin":""})," Refresh"]}),r.jsxs("button",{className:"support-primary-button",type:"button",onClick:()=>Q(!0),disabled:$e.length===0,children:[r.jsx(ip,{size:17})," New request"]})]})}),T&&r.jsxs("div",{className:"support-error",role:"alert",children:[r.jsx(Sn,{size:17})," ",r.jsx("span",{children:T}),r.jsx("button",{type:"button",onClick:()=>j(""),"aria-label":"Dismiss error",children:r.jsx(Sn,{size:15})})]}),$&&r.jsxs("form",{className:"support-composer",onSubmit:F=>{D(F)},children:[r.jsxs("div",{className:"support-section-heading",children:[r.jsxs("div",{children:[r.jsx("span",{children:"New Support request"}),r.jsx("strong",{children:"Describe one actionable problem or idea."})]}),r.jsx("button",{className:"support-icon-button",type:"button",onClick:()=>Q(!1),"aria-label":"Close composer",children:r.jsx(Sn,{size:18})})]}),r.jsxs("div",{className:"support-form-grid",children:[r.jsxs("label",{children:[r.jsx("span",{children:"Type"}),r.jsx("select",{value:N.postType,onChange:F=>we(Pe=>({...Pe,postType:F.target.value})),children:dp.filter(F=>F.id!=="announcement"||c?.canCreateAnnouncements).map(F=>r.jsx("option",{value:F.id,children:F.label},F.id))})]}),r.jsxs("label",{className:"support-form-wide",children:[r.jsx("span",{children:"Title"}),r.jsx("input",{required:!0,minLength:3,maxLength:180,value:N.title,onChange:F=>we(Pe=>({...Pe,title:F.target.value})),placeholder:"A short, searchable summary"})]}),r.jsxs("label",{className:"support-form-wide",children:[r.jsx("span",{children:N.postType==="issue"?"What happened?":N.postType==="feature"?"Describe the desired behavior":N.postType==="announcement"?"Announcement":"Question"}),r.jsx("textarea",{required:!0,value:N.body,onChange:F=>we(Pe=>({...Pe,body:F.target.value})),placeholder:"Include the context another person needs to respond.",rows:6})]}),r.jsxs("label",{children:[r.jsx("span",{children:"Visibility"}),r.jsxs("select",{value:N.visibility,disabled:N.postType==="announcement",onChange:F=>we(Pe=>({...Pe,visibility:F.target.value})),children:[r.jsx("option",{value:"public",children:"Public"}),r.jsx("option",{value:"private",children:"Private"})]})]}),N.postType==="issue"&&r.jsxs("label",{className:"support-checkbox",children:[r.jsx("input",{type:"checkbox",checked:N.includeEnvironment,onChange:F=>we(Pe=>({...Pe,includeEnvironment:F.target.checked}))}),r.jsx("span",{children:"Attach safe browser/runtime details"})]}),r.jsxs("label",{className:"support-form-wide",children:[r.jsx("span",{children:"Attachments"}),r.jsx("input",{type:"file",multiple:!0,accept:"image/png,image/jpeg,image/webp,text/plain,text/markdown,application/json,application/pdf",onChange:F=>qe(Array.from(F.target.files||[]).slice(0,5))}),r.jsx("small",{className:"support-muted",children:"Up to 5 files, 10 MB each. Images, text, JSON, Markdown, and PDF."})]})]}),r.jsxs("div",{className:"support-composer-footer",children:[r.jsx("span",{children:Fe.length>0?`${Fe.length} attachment${Fe.length===1?"":"s"} selected.`:"Private posts are visible only to you and VuvoDesk Support."}),r.jsxs("button",{className:"support-primary-button",type:"submit",disabled:U==="create",children:[r.jsx(lc,{size:16})," ",U==="create"?"Submitting...":"Submit request"]})]})]}),r.jsxs("div",{className:"support-tabs",role:"tablist","aria-label":"Support post type",children:[r.jsx("button",{className:a.type==="all"?"active":"",type:"button",onClick:()=>Le({type:"all"}),children:"All"}),dp.map(F=>{const Pe=Xf(F.id);return r.jsxs("button",{className:a.type===F.id?"active":"",type:"button",onClick:()=>Le({type:F.id}),children:[r.jsx(Pe,{size:15})," ",F.label]},F.id)})]}),se&&c?.canViewAllProducts&&r.jsxs("section",{className:"support-admin-panel",children:[r.jsxs("div",{className:"support-section-heading",children:[r.jsxs("div",{children:[r.jsx("span",{children:"VuvoDesk owner controls"}),r.jsx("strong",{children:"Manage VuvoDesk support access and staff roles by email."})]}),r.jsx(sn,{size:19})]}),r.jsxs("div",{className:"support-admin-grid",children:[r.jsxs("form",{onSubmit:F=>{},children:[r.jsx("strong",{children:"Grant VuvoDesk access"}),r.jsx("input",{type:"email",required:!0,placeholder:"User email",value:Me,onChange:F=>Te(F.target.value)}),r.jsxs("select",{value:J,onChange:F=>Ie(F.target.value),children:[r.jsx("option",{value:"free",children:"Free"}),r.jsx("option",{value:"user",children:"User"}),r.jsx("option",{value:"paid",children:"Paid"}),r.jsx("option",{value:"beta",children:"Beta"}),r.jsx("option",{value:"staff",children:"Staff"})]}),r.jsxs("button",{className:"support-secondary-button",type:"submit",disabled:Se==="access",children:[r.jsx(Ns,{size:15})," Grant access"]})]}),r.jsxs("form",{onSubmit:F=>{},children:[r.jsx("strong",{children:"Assign VuvoDesk staff"}),r.jsx("input",{type:"email",required:!0,placeholder:"Staff email",value:_e,onChange:F=>De(F.target.value)}),r.jsxs("select",{value:ae,onChange:F=>me(F.target.value),children:[r.jsx("option",{value:"admin",children:"Admin"}),r.jsx("option",{value:"support",children:"Support"}),r.jsx("option",{value:"moderator",children:"Moderator"})]}),r.jsxs("button",{className:"support-secondary-button",type:"submit",disabled:Se==="product-admin",children:[r.jsx(sn,{size:15})," Assign staff"]})]})]})]}),r.jsxs("form",{className:"support-search-bar",onSubmit:F=>{F.preventDefault(),Le({query:X.trim()})},children:[r.jsxs("label",{children:[r.jsx("span",{children:"Search Support"}),r.jsx("input",{value:X,onChange:F=>le(F.target.value),placeholder:"Search titles and request details"})]}),r.jsxs("button",{className:"support-secondary-button",type:"submit",children:[r.jsx(Wf,{size:15})," Search"]}),a.query&&r.jsx("button",{className:"support-icon-button",type:"button",onClick:()=>{le(""),Le({query:""})},"aria-label":"Clear search",children:r.jsx(Sn,{size:16})})]}),r.jsxs("div",{className:"support-filter-bar",children:[r.jsxs("div",{className:"support-filter-title",children:[r.jsx(Wf,{size:16}),r.jsx("span",{children:"Filter"})]}),r.jsxs("label",{children:[r.jsx("span",{children:"Status"}),r.jsx("select",{value:a.status,onChange:F=>Le({status:F.target.value}),children:uS.map(F=>r.jsx("option",{value:F.id,children:F.label},F.id))})]}),r.jsxs("label",{children:[r.jsx("span",{children:"Visibility"}),r.jsxs("select",{value:a.visibility,onChange:F=>Le({visibility:F.target.value}),children:[r.jsx("option",{value:"all",children:"All visibility"}),r.jsx("option",{value:"public",children:"Public"}),r.jsx("option",{value:"private",children:"Private"})]})]}),r.jsxs("label",{children:[r.jsx("span",{children:"Sort"}),r.jsxs("select",{value:a.sort,onChange:F=>Le({sort:F.target.value}),children:[r.jsx("option",{value:"recent",children:"Recently updated"}),r.jsx("option",{value:"newest",children:"Newest"}),r.jsx("option",{value:"votes",children:"Most votes"})]})]})]}),c?.canViewAllProducts&&r.jsxs("div",{className:"support-admin-shortcuts",children:[r.jsxs("span",{children:[r.jsx(sn,{size:15})," VuvoDesk owner"]}),r.jsx("button",{type:"button",onClick:()=>Le({status:"needs-response"}),children:"Needs response"}),r.jsx("button",{type:"button",onClick:()=>Le({visibility:"private"}),children:"Private requests"}),r.jsx("button",{type:"button",onClick:()=>Le({type:"feature",status:"all",sort:"votes"}),children:"High-vote features"})]}),r.jsxs("div",{className:"support-board-layout",children:[r.jsxs("section",{className:"support-post-list","aria-label":"Support posts",children:[r.jsxs("div",{className:"support-list-heading",children:[r.jsxs("span",{children:[rt.length," request",rt.length===1?"":"s"]}),r.jsx("small",{children:"VuvoDesk"})]}),rt.length===0?r.jsxs("div",{className:"support-list-empty",children:[r.jsx(nc,{size:25}),r.jsx("strong",{children:"No posts match these filters."}),r.jsx("span",{children:"Start with a focused question, issue report, or feature request."}),$e.length>0&&r.jsxs("button",{className:"support-secondary-button",type:"button",onClick:()=>Q(!0),children:[r.jsx(ip,{size:16})," Create the first request"]})]}):rt.map(F=>{const Pe=Xf(F.post_type);return r.jsxs("button",{type:"button",className:`support-post-row ${F.id===ge?.id?"active":""}`,onClick:()=>{w(F.id),q(!1)},children:[r.jsx("span",{className:"support-post-row-icon",children:r.jsx(Pe,{size:17})}),r.jsxs("span",{className:"support-post-row-copy",children:[r.jsxs("span",{className:"support-post-row-meta",children:[r.jsx("em",{children:Jf(F.post_type)}),F.visibility==="private"&&r.jsx(Rs,{size:13})]}),r.jsx("strong",{children:F.title}),r.jsxs("small",{children:[Rd(F.status)," · ",Cl(F.updated_at)," · ",F.comment_count," comments"]})]}),F.post_type==="feature"&&r.jsxs("span",{className:"support-vote-count",children:[r.jsx(Cv,{size:14})," ",F.vote_count]})]},F.id)})]}),r.jsx("section",{className:"support-post-detail","aria-label":"Support post detail",children:ge?r.jsxs(r.Fragment,{children:[r.jsxs("div",{className:"support-detail-head",children:[r.jsxs("div",{className:"support-detail-badges",children:[r.jsx("span",{className:"support-type-badge",children:Jf(ge.post_type)}),r.jsx("span",{className:`support-status-badge status-${ge.status}`,children:Rd(ge.status)}),ge.visibility==="private"&&r.jsxs("span",{className:"support-private-badge",children:[r.jsx(Rs,{size:13})," Private"]})]}),r.jsxs("div",{className:"support-detail-actions",children:[fe&&r.jsx("button",{className:"support-icon-button",type:"button",onClick:()=>q(F=>!F),title:"Edit post",children:r.jsx(ex,{size:16})}),ct&&r.jsxs(r.Fragment,{children:[r.jsx("button",{className:"support-icon-button",type:"button",onClick:()=>{Be()},disabled:U==="pin",title:ge.is_pinned?"Unpin post":"Pin post",children:r.jsx(zf,{size:16})}),r.jsx("button",{className:"support-icon-button",type:"button",onClick:()=>{be()},disabled:U==="lock",title:ge.is_locked?"Unlock post":"Lock post",children:r.jsx(Rs,{size:16})}),r.jsx("button",{className:"support-icon-button danger",type:"button",onClick:()=>{ce()},disabled:U==="hide",title:"Hide post",children:r.jsx(Vf,{size:16})})]})]})]}),G?r.jsxs("form",{className:"support-edit-form",onSubmit:F=>{Y(F)},children:[r.jsx("input",{value:ge.title,onChange:F=>Z({title:F.target.value}),minLength:3,maxLength:180,required:!0}),r.jsx("textarea",{value:ge.body,onChange:F=>Z({body:F.target.value}),rows:9,required:!0}),r.jsxs("div",{className:"support-edit-actions",children:[r.jsxs("select",{value:ge.visibility,onChange:F=>Z({visibility:F.target.value}),children:[r.jsx("option",{value:"public",children:"Public"}),r.jsx("option",{value:"private",children:"Private"})]}),r.jsxs("button",{className:"support-primary-button",type:"submit",disabled:U==="edit",children:[r.jsx(Ns,{size:16})," Save changes"]})]})]}):r.jsxs(r.Fragment,{children:[r.jsx("h3",{children:ge.title}),r.jsx("div",{className:"support-detail-body",children:ge.body.split(`
|
|
1
|
+
import{j as r,M as op,w as wv,D as rn,r as Ya,g as Gl,i as ru,h as We,c as bu,a as wu,n as yv,b as Yy,d as Xy,e as Kl,f as xv,k as Sv,l as Jy,m as Hf,p as Ms,P as zi,F as Sl}from"./index-CqZbwCrG.js";import{a as i,m as nc,k as sn,n as Xa,B as Zy,P as ip,X as Sn,o as lc,l as Ns,F as Wf,p as Rs,q as Cv,s as ex,t as zf,u as Vf,v as tx,D as uc,b as Fn,w as nx,x as kv,y as rx,z as sx,g as ls,c as dn,H as su,I as rc,J as au,K as is,O as cp,Q as ax,U as Mv,V as qf,Y as ox,Z as ix,_ as qa,W as yu,$ as cx,a0 as lx,a1 as ai,a2 as sc,a3 as ux,a4 as lp,S as ta,a5 as Av,a6 as Rv,a7 as dx,a8 as px,a9 as mx,aa as Hp,ab as fx,N as Wp,ac as Nv,ad as hx,ae as cs,af as Uf,C as zp,ag as xu,ah as dc,ai as ac,aj as Tv,ak as gx,al as Iv,am as vx,an as Pv,ao as bx,ap as jv,aq as wx,ar as up,as as Ev,at as yx,au as xx,av as Sx,aw as Cx,ax as Fv,ay as kx,az as Gf,aA as Mx,aB as Ax,aC as Rx,aD as Dv,f as Ql,T as Yl,A as Nx,E as Tx,aE as Kf,aF as kd,aG as Ix,aH as Qf,aI as Px,aJ as _v,aK as jx,aL as Ex,aM as Fx,G as Dx}from"./icons-tFaWqIIe.js";import{c as _x}from"./supabase-C7qjtLN3.js";import{r as Lx}from"./react-BQos8uGS.js";const Ox="https://otbyfkjxrkngvjziawki.supabase.co",$x="sb_publishable_NpUs0RDJH2YnllsqTKO6TQ_1jTdSsNQ",Bx={getItem:()=>null,setItem:()=>{},removeItem:()=>{}},Md=typeof window<"u"&&!!window.liveDesk,mt=_x(Ox,$x,{auth:{autoRefreshToken:!Md,persistSession:!Md,storage:Md?Bx:void 0,detectSessionInUrl:!0,flowType:"pkce",storageKey:"livedesk.mindexec.supabase.auth"}}),Hx=new Set(["browserLanguage","platform","online","viewport","timezone","screen"]),Wx={id:"browser-safe-v1",collect(){if(typeof navigator>"u")return{};const e={browserLanguage:navigator.language||"",platform:navigator.platform||"",online:navigator.onLine,timezone:typeof Intl>"u"?"":Intl.DateTimeFormat().resolvedOptions().timeZone||"",viewport:typeof window>"u"?void 0:{width:window.innerWidth,height:window.innerHeight},screen:typeof window>"u"?void 0:{width:window.screen.width,height:window.screen.height}};return Object.fromEntries(Object.entries(e).filter(([t,n])=>Hx.has(t)&&n!==void 0))}};function zx(e,t="Support request failed."){if(e&&typeof e=="object"&&"message"in e){const n=String(e.message||"").trim();if(n)return n.replace(/^.*Support request failed:\s*/i,"")}return e instanceof Error?e.message:t}function Vx(e=Wx){return e.collect()}async function qx(e,t="livedesk"){const{data:n,error:s}=await mt.from("app_admins").select("role").eq("user_id",e).limit(1);if(s)throw s;const a=n?.[0]?.role||"user";if(a!=="owner"){const{error:w}=await mt.rpc("register_product_access",{p_product_key:t,p_access_type:"free"});if(w)throw w}const[o,c,u]=await Promise.all([mt.from("products").select("id, product_key, name, description, sort_order").order("sort_order"),mt.from("product_admins").select("product_id, role").eq("user_id",e),mt.from("user_products").select("product_id").eq("user_id",e).eq("is_active",!0)]);if(o.error)throw o.error;if(c.error)throw c.error;if(u.error)throw u.error;const d=o.data||[],p=(c.data||[]).map(w=>String(w.product_id)),f=(u.data||[]).map(w=>String(w.product_id)),m=a==="owner",g=m?d.map(w=>w.id):[...new Set([...p,...f])];return{products:d,access:{userId:e,globalRole:a,accessibleProductIds:g,managedProductIds:m?d.map(w=>w.id):p,canViewAllProducts:m,canViewAllPrivatePosts:m,canManageAllProducts:m,canCreateAnnouncements:m||p.length>0}}}async function Ux(e=""){const{data:t,error:n}=await mt.rpc("search_support_posts",{p_query:e.trim()||null,p_limit:250});if(n)throw n;return t||[]}async function Gx(e){const{data:t,error:n}=await mt.from("support_attachments").select("*").eq("post_id",e).order("created_at");if(n)throw n;const s=t||[];return Promise.all(s.map(async a=>{const o=await mt.storage.from("support-attachments").createSignedUrl(a.storage_path,3600);return{...a,signed_url:o.data?.signedUrl||void 0}}))}async function Kx(){const{data:e,error:t}=await mt.from("support_notifications").select("*").order("created_at",{ascending:!1}).limit(30);if(t)throw t;return e||[]}async function Qx(e){const{error:t}=await mt.rpc("mark_support_notification_read",{p_notification_id:e});if(t)throw t}async function Yf(e){const{data:t,error:n}=await mt.from("support_comments").select("*").eq("post_id",e).order("created_at");if(n)throw n;return t||[]}async function Yx(e){const{data:t,error:n}=await mt.from("support_votes").select("post_id").eq("user_id",e);if(n)throw n;return new Set((t||[]).map(s=>String(s.post_id)))}async function Xx(e){const{data:t,error:n}=await mt.rpc("create_support_post",{p_product_id:e.productId,p_post_type:e.postType,p_title:e.title,p_body:e.body,p_visibility:e.visibility,p_app_version:e.appVersion||null,p_platform:typeof navigator>"u"?null:navigator.platform||null,p_os_version:typeof navigator>"u"?null:navigator.platform||null,p_environment:e.includeEnvironment?Vx():{}});if(n)throw n;const s=Array.isArray(t)?t[0]?.post_id:t?.post_id;if(!s)throw new Error("Support post was not created.");return String(s)}const Jx=new Set(["image/png","image/jpeg","image/webp","text/plain","text/markdown","application/json","application/pdf"]);async function Zx(e,t){if(!Jx.has(t.type))throw new Error("This file type is not allowed.");if(t.size<=0||t.size>10*1024*1024)throw new Error("Attachments must be smaller than 10 MB.");const n=t.name.replace(/[^a-zA-Z0-9._-]+/g,"-").replace(/^-+|-+$/g,"")||"attachment",s=typeof crypto<"u"&&"randomUUID"in crypto?crypto.randomUUID():`${Date.now()}-${Math.random().toString(16).slice(2)}`,a=`${e}/${s}-${n}`,o=await mt.storage.from("support-attachments").upload(a,t,{contentType:t.type,upsert:!1});if(o.error)throw o.error;const{data:c,error:u}=await mt.rpc("add_support_attachment",{p_post_id:e,p_storage_path:a,p_file_name:n,p_mime_type:t.type,p_size_bytes:t.size});if(u)throw await mt.storage.from("support-attachments").remove([a]),u;const d=Array.isArray(c)?c[0]?.attachment_id:c?.attachment_id;if(!d)throw new Error("Attachment metadata was not created.");return String(d)}async function eS(e,t,n,s){const{error:a}=await mt.rpc("update_support_post",{p_post_id:e,p_title:t,p_body:n,p_visibility:s});if(a)throw a}async function tS(e,t){const{error:n}=await mt.rpc("add_support_comment",{p_post_id:e,p_body:t});if(n)throw n}async function nS(e){const{data:t,error:n}=await mt.rpc("toggle_support_vote",{p_post_id:e});if(n)throw n;const s=Array.isArray(t)?t[0]:t;return{voted:!!s?.voted,totalVotes:Number(s?.total_votes||0)}}async function rS(e,t){const{error:n}=await mt.rpc("change_support_post_status",{p_post_id:e,p_target_status:t});if(n)throw n}async function sS(e){const{error:t}=await mt.rpc("set_support_post_hidden",{p_post_id:e,p_hidden:!0});if(t)throw t}async function aS(e,t){const{error:n}=await mt.rpc("set_support_post_locked",{p_post_id:e,p_locked:t});if(n)throw n}async function oS(e,t){const{error:n}=await mt.rpc("set_support_post_pinned",{p_post_id:e,p_pinned:t});if(n)throw n}async function iS(e,t){const{error:n}=await mt.rpc("mark_support_duplicate",{p_post_id:e,p_duplicate_of_post_id:t});if(n)throw n}async function cS(e,t){const{error:n}=await mt.rpc("accept_support_answer",{p_post_id:e,p_comment_id:t});if(n)throw n}async function lS(e,t=!0){const{error:n}=await mt.rpc("hide_support_comment",{p_comment_id:e,p_hidden:t});if(n)throw n}const dp=[{id:"question",label:"Questions",shortLabel:"Question"},{id:"issue",label:"Issues",shortLabel:"Issue"},{id:"feature",label:"Feature Requests",shortLabel:"Feature"},{id:"announcement",label:"Announcements",shortLabel:"Announcement"}],uS=[{id:"all",label:"All statuses"},{id:"needs-response",label:"Needs response"},{id:"open",label:"Open"},{id:"needs-info",label:"Needs more information"},{id:"in-progress",label:"In progress"},{id:"planned",label:"Planned"},{id:"released",label:"Released"},{id:"closed",label:"Closed"}],dS={question:["open","answered","resolved","closed"],issue:["open","needs-info","confirmed","in-progress","fixed","closed"],feature:["under-review","planned","in-progress","released","declined","closed"],announcement:["published","archived"]},pS={type:"all",product:"",status:"all",visibility:"all",sort:"recent",query:""};function Ad(){if(typeof window>"u")return pS;const e=new URLSearchParams(window.location.search),t=window.location.pathname.match(/^\/support\/(questions|issues|features|announcements)$/)?.[1],n=e.get("type")||t||"",s=n==="questions"||n==="question"?"question":n==="issues"||n==="issue"?"issue":n==="features"||n==="feature"?"feature":n==="announcements"||n==="announcement"?"announcement":"all",a=e.get("visibility"),o=e.get("sort");return{type:s,product:e.get("product")||"",status:e.get("status")||"all",visibility:a==="public"||a==="private"?a:"all",sort:o==="votes"||o==="newest"?o:"recent",query:e.get("q")||""}}function mS(e){return e==="all"?"":e==="question"?"questions":e==="issue"?"issues":e==="feature"?"features":"announcements"}function fS(e,t){const n={...e,...t},s=new URLSearchParams;n.product&&s.set("product",n.product),n.status!=="all"&&s.set("status",n.status),n.visibility!=="all"&&s.set("visibility",n.visibility),n.sort!=="recent"&&s.set("sort",n.sort),n.query&&s.set("q",n.query);const a=mS(n.type),o=s.toString();return`/support${a?`/${a}`:""}${o?`?${o}`:""}`}function Cl(e){const t=new Date(e);return Number.isFinite(t.getTime())?t.toLocaleString(void 0,{dateStyle:"medium",timeStyle:"short"}):e}function Rd(e){return e.replaceAll("-"," ").replace(/\b\w/g,t=>t.toUpperCase())}function Xf(e){return e==="question"?nx:e==="issue"?kv:e==="feature"?rx:sx}function Jf(e){return dp.find(t=>t.id===e)?.shortLabel||e}function Yn(e){const t=zx(e);return/relation .* does not exist|function .* does not exist|schema cache/i.test(t)?"Support Board database is not installed yet. Apply the latest Supabase migration first.":/not-authenticated|jwt/i.test(t)?"Sign in again to use Support.":/product-access-denied|product-not-found/i.test(t)?"You do not have access to this product.":t}function Lv({session:e,currentProductKey:t="livedesk",appVersion:n="",onSignIn:s}){const[a,o]=i.useState(()=>Ad()),[c,u]=i.useState(null),[d,p]=i.useState([]),[f,m]=i.useState([]),[g,w]=i.useState(""),[b,y]=i.useState([]),[C,A]=i.useState([]),[k,R]=i.useState([]),[_,E]=i.useState(()=>new Set),[L,M]=i.useState(!0),[U,V]=i.useState(""),[T,j]=i.useState(""),[$,Q]=i.useState(!1),[G,q]=i.useState(!1),[re,I]=i.useState(""),[X,le]=i.useState(()=>Ad().query),[K,ue]=i.useState(!1),[se,ve]=i.useState(!1),[Me,Te]=i.useState(""),[ke,pe]=i.useState(""),[J,Ie]=i.useState("free"),[_e,De]=i.useState(""),[Xe,ne]=i.useState(""),[ae,me]=i.useState("admin"),[oe,ee]=i.useState(""),[Se,de]=i.useState(""),[Fe,qe]=i.useState([]),[N,we]=i.useState({productId:"",postType:"question",title:"",body:"",visibility:"public",includeEnvironment:!0,files:[]}),Le=i.useCallback(F=>{const Pe={...a,...F};o(Pe),typeof window<"u"&&window.history.pushState({},"",fS(a,F))},[a]);i.useEffect(()=>{const F=()=>o(Ad());return window.addEventListener("popstate",F),()=>window.removeEventListener("popstate",F)},[]);const Je=i.useCallback(async()=>{const F=await Ux(a.query);return m(F),e?.user.id&&E(await Yx(e.user.id)),F},[a.query,e?.user.id]),Oe=i.useCallback(async()=>{if(!e?.user.id){u(null),p([]),m([]),w(""),R([]),M(!1);return}M(!0),j("");try{const F=await qx(e.user.id,t);u(F.access),p(F.products),await Je(),R(await Kx())}catch(F){j(Yn(F))}finally{M(!1)}},[t,Je,e?.user.id]);i.useEffect(()=>{Oe()},[Oe]);const $e=i.useMemo(()=>{if(!c)return[];const F=d.find(Pe=>Pe.product_key===t);return F?c.canViewAllProducts||c.accessibleProductIds.includes(F.id)?[F]:[]:[]},[c,t,d]),ft=$e[0]?.id||"",rt=i.useMemo(()=>{const F=new Map(d.map(Ue=>[Ue.id,Ue.product_key]));return[...f.filter(Ue=>a.type!=="all"&&Ue.post_type!==a.type||!ft||Ue.product_id!==ft||a.status==="needs-response"&&!["open","needs-info"].includes(Ue.status)||a.status!=="all"&&a.status!=="needs-response"&&Ue.status!==a.status||a.visibility!=="all"&&Ue.visibility!==a.visibility?!1:F.has(Ue.product_id))].sort((Ue,Ke)=>a.sort==="votes"?Ke.vote_count-Ue.vote_count||Ke.updated_at.localeCompare(Ue.updated_at):a.sort==="newest"?Ke.created_at.localeCompare(Ue.created_at):Number(Ke.is_pinned)-Number(Ue.is_pinned)||Ke.updated_at.localeCompare(Ue.updated_at))},[f,d,a.sort,a.status,a.type,a.visibility,ft]),ge=rt.find(F=>F.id===g)||rt[0]||null,ct=!!(ge&&c&&(c.canViewAllProducts||c.managedProductIds.includes(ge.product_id))),fe=!!(ge&&e?.user.id===ge.author_id)||ct;i.useEffect(()=>{if(!ge){w(""),y([]),q(!1);return}ge.id!==g&&w(ge.id)},[ge,g]),i.useEffect(()=>{let F=!0;return g?(Yf(g).then(Pe=>{F&&y(Pe)}).catch(Pe=>{F&&j(Yn(Pe))}),Gx(g).then(Pe=>{F&&A(Pe)}).catch(Pe=>{F&&j(Yn(Pe))}),()=>{F=!1}):(y([]),A([]),()=>{F=!1})},[g]),i.useEffect(()=>{!N.productId&&$e[0]&&we(F=>({...F,productId:ft||$e[0].id}))},[$e,N.productId,ft]),i.useEffect(()=>{le(a.query)},[a.query]),i.useEffect(()=>{!ke&&$e[0]&&pe($e[0].id),!Xe&&$e[0]&&ne($e[0].id)},[$e,ke,Xe]);const Z=F=>{ge&&m(Pe=>Pe.map(Ue=>Ue.id===ge.id?{...Ue,...F}:Ue))},D=async F=>{if(F.preventDefault(),!(!e||!N.productId)){V("create"),j("");try{const Pe=await Xx({productId:N.productId,postType:N.postType,title:N.title,body:N.body,visibility:N.postType==="announcement"?"public":N.visibility,appVersion:n,includeEnvironment:N.postType==="issue"&&N.includeEnvironment});for(const Ke of Fe)await Zx(Pe,Ke);const Ue=await Je();Q(!1),qe([]),we(Ke=>({...Ke,title:"",body:"",files:[]})),w(Pe),Ue.some(Ke=>Ke.id===Pe)||await Oe()}catch(Pe){j(Yn(Pe))}finally{V("")}}},Y=async F=>{if(F.preventDefault(),!!ge){V("edit"),j("");try{await eS(ge.id,ge.title,ge.body,ge.visibility),q(!1),await Je()}catch(Pe){j(Yn(Pe))}finally{V("")}}},ie=async F=>{if(F.preventDefault(),!(!ge||!re.trim())){V("comment"),j("");try{await tS(ge.id,re),I(""),y(await Yf(ge.id)),await Je()}catch(Pe){j(Yn(Pe))}finally{V("")}}},Re=async()=>{if(!(!ge||ge.post_type!=="feature")){V("vote"),j("");try{const F=await nS(ge.id);E(Pe=>{const Ue=new Set(Pe);return F.voted?Ue.add(ge.id):Ue.delete(ge.id),Ue}),Z({vote_count:F.totalVotes})}catch(F){j(Yn(F))}finally{V("")}}},P=async F=>{if(ge){V("status"),j("");try{await rS(ge.id,F),Z({status:F}),await Je()}catch(Pe){j(Yn(Pe))}finally{V("")}}},ce=async()=>{if(!(!ge||!window.confirm("Hide this Support post from the board?"))){V("hide"),j("");try{await sS(ge.id),w(""),await Je()}catch(F){j(Yn(F))}finally{V("")}}},be=async()=>{if(ge){V("lock"),j("");try{await aS(ge.id,!ge.is_locked),Z({is_locked:!ge.is_locked}),await Je()}catch(F){j(Yn(F))}finally{V("")}}},Be=async()=>{if(ge){V("pin"),j("");try{await oS(ge.id,!ge.is_pinned),Z({is_pinned:!ge.is_pinned}),await Je()}catch(F){j(Yn(F))}finally{V("")}}},nt=async F=>{if(ge){V(`accept-${F}`),j("");try{await cS(ge.id,F),Z({accepted_comment_id:F,status:ge.post_type==="question"?"answered":ge.status}),await Je()}catch(Pe){j(Yn(Pe))}finally{V("")}}},He=async()=>{if(!(!ge||!oe||oe===ge.id)){V("duplicate"),j("");try{await iS(ge.id,oe),w(""),ee(""),await Je()}catch(F){j(Yn(F))}finally{V("")}}},dt=async F=>{if(!F.read_at)try{await Qx(F.id),R(Pe=>Pe.map(Ue=>Ue.id===F.id?{...Ue,read_at:new Date().toISOString()}:Ue))}catch(Pe){j(Yn(Pe))}F.post_id&&w(F.post_id),ue(!1)};return e?L&&!c?r.jsxs("section",{className:"support-page support-loading",children:[r.jsx(Xa,{className:"support-spin",size:23})," Loading Support Board..."]}):r.jsxs("section",{className:"support-page",children:[r.jsx("header",{className:"support-page-header support-page-actions-only",children:r.jsxs("div",{className:"support-header-actions",children:[r.jsxs("div",{className:"support-notification-wrap",children:[r.jsxs("button",{className:"support-secondary-button",type:"button",onClick:()=>ue(F=>!F),title:"Notifications",children:[r.jsx(Zy,{size:16})," ",k.filter(F=>!F.read_at).length>0&&r.jsx("b",{children:k.filter(F=>!F.read_at).length})]}),K&&r.jsxs("div",{className:"support-notification-popover",children:[r.jsx("strong",{children:"Notifications"}),k.length===0?r.jsx("span",{className:"support-muted",children:"No notifications yet."}):k.map(F=>r.jsxs("button",{type:"button",className:F.read_at?"":"unread",onClick:()=>{dt(F)},children:[r.jsx("b",{children:F.title}),r.jsx("span",{children:F.body}),r.jsx("small",{children:Cl(F.created_at)})]},F.id))]})]}),c?.canViewAllProducts&&r.jsxs("button",{className:"support-secondary-button",type:"button",onClick:()=>ve(F=>!F),children:[r.jsx(sn,{size:16})," Admin"]}),r.jsxs("button",{className:"support-secondary-button",type:"button",onClick:()=>{Oe()},disabled:L,children:[r.jsx(Xa,{size:16,className:L?"support-spin":""})," Refresh"]}),r.jsxs("button",{className:"support-primary-button",type:"button",onClick:()=>Q(!0),disabled:$e.length===0,children:[r.jsx(ip,{size:17})," New request"]})]})}),T&&r.jsxs("div",{className:"support-error",role:"alert",children:[r.jsx(Sn,{size:17})," ",r.jsx("span",{children:T}),r.jsx("button",{type:"button",onClick:()=>j(""),"aria-label":"Dismiss error",children:r.jsx(Sn,{size:15})})]}),$&&r.jsxs("form",{className:"support-composer",onSubmit:F=>{D(F)},children:[r.jsxs("div",{className:"support-section-heading",children:[r.jsxs("div",{children:[r.jsx("span",{children:"New Support request"}),r.jsx("strong",{children:"Describe one actionable problem or idea."})]}),r.jsx("button",{className:"support-icon-button",type:"button",onClick:()=>Q(!1),"aria-label":"Close composer",children:r.jsx(Sn,{size:18})})]}),r.jsxs("div",{className:"support-form-grid",children:[r.jsxs("label",{children:[r.jsx("span",{children:"Type"}),r.jsx("select",{value:N.postType,onChange:F=>we(Pe=>({...Pe,postType:F.target.value})),children:dp.filter(F=>F.id!=="announcement"||c?.canCreateAnnouncements).map(F=>r.jsx("option",{value:F.id,children:F.label},F.id))})]}),r.jsxs("label",{className:"support-form-wide",children:[r.jsx("span",{children:"Title"}),r.jsx("input",{required:!0,minLength:3,maxLength:180,value:N.title,onChange:F=>we(Pe=>({...Pe,title:F.target.value})),placeholder:"A short, searchable summary"})]}),r.jsxs("label",{className:"support-form-wide",children:[r.jsx("span",{children:N.postType==="issue"?"What happened?":N.postType==="feature"?"Describe the desired behavior":N.postType==="announcement"?"Announcement":"Question"}),r.jsx("textarea",{required:!0,value:N.body,onChange:F=>we(Pe=>({...Pe,body:F.target.value})),placeholder:"Include the context another person needs to respond.",rows:6})]}),r.jsxs("label",{children:[r.jsx("span",{children:"Visibility"}),r.jsxs("select",{value:N.visibility,disabled:N.postType==="announcement",onChange:F=>we(Pe=>({...Pe,visibility:F.target.value})),children:[r.jsx("option",{value:"public",children:"Public"}),r.jsx("option",{value:"private",children:"Private"})]})]}),N.postType==="issue"&&r.jsxs("label",{className:"support-checkbox",children:[r.jsx("input",{type:"checkbox",checked:N.includeEnvironment,onChange:F=>we(Pe=>({...Pe,includeEnvironment:F.target.checked}))}),r.jsx("span",{children:"Attach safe browser/runtime details"})]}),r.jsxs("label",{className:"support-form-wide",children:[r.jsx("span",{children:"Attachments"}),r.jsx("input",{type:"file",multiple:!0,accept:"image/png,image/jpeg,image/webp,text/plain,text/markdown,application/json,application/pdf",onChange:F=>qe(Array.from(F.target.files||[]).slice(0,5))}),r.jsx("small",{className:"support-muted",children:"Up to 5 files, 10 MB each. Images, text, JSON, Markdown, and PDF."})]})]}),r.jsxs("div",{className:"support-composer-footer",children:[r.jsx("span",{children:Fe.length>0?`${Fe.length} attachment${Fe.length===1?"":"s"} selected.`:"Private posts are visible only to you and VuvoDesk Support."}),r.jsxs("button",{className:"support-primary-button",type:"submit",disabled:U==="create",children:[r.jsx(lc,{size:16})," ",U==="create"?"Submitting...":"Submit request"]})]})]}),r.jsxs("div",{className:"support-tabs",role:"tablist","aria-label":"Support post type",children:[r.jsx("button",{className:a.type==="all"?"active":"",type:"button",onClick:()=>Le({type:"all"}),children:"All"}),dp.map(F=>{const Pe=Xf(F.id);return r.jsxs("button",{className:a.type===F.id?"active":"",type:"button",onClick:()=>Le({type:F.id}),children:[r.jsx(Pe,{size:15})," ",F.label]},F.id)})]}),se&&c?.canViewAllProducts&&r.jsxs("section",{className:"support-admin-panel",children:[r.jsxs("div",{className:"support-section-heading",children:[r.jsxs("div",{children:[r.jsx("span",{children:"VuvoDesk owner controls"}),r.jsx("strong",{children:"Manage VuvoDesk support access and staff roles by email."})]}),r.jsx(sn,{size:19})]}),r.jsxs("div",{className:"support-admin-grid",children:[r.jsxs("form",{onSubmit:F=>{},children:[r.jsx("strong",{children:"Grant VuvoDesk access"}),r.jsx("input",{type:"email",required:!0,placeholder:"User email",value:Me,onChange:F=>Te(F.target.value)}),r.jsxs("select",{value:J,onChange:F=>Ie(F.target.value),children:[r.jsx("option",{value:"free",children:"Free"}),r.jsx("option",{value:"user",children:"User"}),r.jsx("option",{value:"paid",children:"Paid"}),r.jsx("option",{value:"beta",children:"Beta"}),r.jsx("option",{value:"staff",children:"Staff"})]}),r.jsxs("button",{className:"support-secondary-button",type:"submit",disabled:Se==="access",children:[r.jsx(Ns,{size:15})," Grant access"]})]}),r.jsxs("form",{onSubmit:F=>{},children:[r.jsx("strong",{children:"Assign VuvoDesk staff"}),r.jsx("input",{type:"email",required:!0,placeholder:"Staff email",value:_e,onChange:F=>De(F.target.value)}),r.jsxs("select",{value:ae,onChange:F=>me(F.target.value),children:[r.jsx("option",{value:"admin",children:"Admin"}),r.jsx("option",{value:"support",children:"Support"}),r.jsx("option",{value:"moderator",children:"Moderator"})]}),r.jsxs("button",{className:"support-secondary-button",type:"submit",disabled:Se==="product-admin",children:[r.jsx(sn,{size:15})," Assign staff"]})]})]})]}),r.jsxs("form",{className:"support-search-bar",onSubmit:F=>{F.preventDefault(),Le({query:X.trim()})},children:[r.jsxs("label",{children:[r.jsx("span",{children:"Search Support"}),r.jsx("input",{value:X,onChange:F=>le(F.target.value),placeholder:"Search titles and request details"})]}),r.jsxs("button",{className:"support-secondary-button",type:"submit",children:[r.jsx(Wf,{size:15})," Search"]}),a.query&&r.jsx("button",{className:"support-icon-button",type:"button",onClick:()=>{le(""),Le({query:""})},"aria-label":"Clear search",children:r.jsx(Sn,{size:16})})]}),r.jsxs("div",{className:"support-filter-bar",children:[r.jsxs("div",{className:"support-filter-title",children:[r.jsx(Wf,{size:16}),r.jsx("span",{children:"Filter"})]}),r.jsxs("label",{children:[r.jsx("span",{children:"Status"}),r.jsx("select",{value:a.status,onChange:F=>Le({status:F.target.value}),children:uS.map(F=>r.jsx("option",{value:F.id,children:F.label},F.id))})]}),r.jsxs("label",{children:[r.jsx("span",{children:"Visibility"}),r.jsxs("select",{value:a.visibility,onChange:F=>Le({visibility:F.target.value}),children:[r.jsx("option",{value:"all",children:"All visibility"}),r.jsx("option",{value:"public",children:"Public"}),r.jsx("option",{value:"private",children:"Private"})]})]}),r.jsxs("label",{children:[r.jsx("span",{children:"Sort"}),r.jsxs("select",{value:a.sort,onChange:F=>Le({sort:F.target.value}),children:[r.jsx("option",{value:"recent",children:"Recently updated"}),r.jsx("option",{value:"newest",children:"Newest"}),r.jsx("option",{value:"votes",children:"Most votes"})]})]})]}),c?.canViewAllProducts&&r.jsxs("div",{className:"support-admin-shortcuts",children:[r.jsxs("span",{children:[r.jsx(sn,{size:15})," VuvoDesk owner"]}),r.jsx("button",{type:"button",onClick:()=>Le({status:"needs-response"}),children:"Needs response"}),r.jsx("button",{type:"button",onClick:()=>Le({visibility:"private"}),children:"Private requests"}),r.jsx("button",{type:"button",onClick:()=>Le({type:"feature",status:"all",sort:"votes"}),children:"High-vote features"})]}),r.jsxs("div",{className:"support-board-layout",children:[r.jsxs("section",{className:"support-post-list","aria-label":"Support posts",children:[r.jsxs("div",{className:"support-list-heading",children:[r.jsxs("span",{children:[rt.length," request",rt.length===1?"":"s"]}),r.jsx("small",{children:"VuvoDesk"})]}),rt.length===0?r.jsxs("div",{className:"support-list-empty",children:[r.jsx(nc,{size:25}),r.jsx("strong",{children:"No posts match these filters."}),r.jsx("span",{children:"Start with a focused question, issue report, or feature request."}),$e.length>0&&r.jsxs("button",{className:"support-secondary-button",type:"button",onClick:()=>Q(!0),children:[r.jsx(ip,{size:16})," Create the first request"]})]}):rt.map(F=>{const Pe=Xf(F.post_type);return r.jsxs("button",{type:"button",className:`support-post-row ${F.id===ge?.id?"active":""}`,onClick:()=>{w(F.id),q(!1)},children:[r.jsx("span",{className:"support-post-row-icon",children:r.jsx(Pe,{size:17})}),r.jsxs("span",{className:"support-post-row-copy",children:[r.jsxs("span",{className:"support-post-row-meta",children:[r.jsx("em",{children:Jf(F.post_type)}),F.visibility==="private"&&r.jsx(Rs,{size:13})]}),r.jsx("strong",{children:F.title}),r.jsxs("small",{children:[Rd(F.status)," · ",Cl(F.updated_at)," · ",F.comment_count," comments"]})]}),F.post_type==="feature"&&r.jsxs("span",{className:"support-vote-count",children:[r.jsx(Cv,{size:14})," ",F.vote_count]})]},F.id)})]}),r.jsx("section",{className:"support-post-detail","aria-label":"Support post detail",children:ge?r.jsxs(r.Fragment,{children:[r.jsxs("div",{className:"support-detail-head",children:[r.jsxs("div",{className:"support-detail-badges",children:[r.jsx("span",{className:"support-type-badge",children:Jf(ge.post_type)}),r.jsx("span",{className:`support-status-badge status-${ge.status}`,children:Rd(ge.status)}),ge.visibility==="private"&&r.jsxs("span",{className:"support-private-badge",children:[r.jsx(Rs,{size:13})," Private"]})]}),r.jsxs("div",{className:"support-detail-actions",children:[fe&&r.jsx("button",{className:"support-icon-button",type:"button",onClick:()=>q(F=>!F),title:"Edit post",children:r.jsx(ex,{size:16})}),ct&&r.jsxs(r.Fragment,{children:[r.jsx("button",{className:"support-icon-button",type:"button",onClick:()=>{Be()},disabled:U==="pin",title:ge.is_pinned?"Unpin post":"Pin post",children:r.jsx(zf,{size:16})}),r.jsx("button",{className:"support-icon-button",type:"button",onClick:()=>{be()},disabled:U==="lock",title:ge.is_locked?"Unlock post":"Lock post",children:r.jsx(Rs,{size:16})}),r.jsx("button",{className:"support-icon-button danger",type:"button",onClick:()=>{ce()},disabled:U==="hide",title:"Hide post",children:r.jsx(Vf,{size:16})})]})]})]}),G?r.jsxs("form",{className:"support-edit-form",onSubmit:F=>{Y(F)},children:[r.jsx("input",{value:ge.title,onChange:F=>Z({title:F.target.value}),minLength:3,maxLength:180,required:!0}),r.jsx("textarea",{value:ge.body,onChange:F=>Z({body:F.target.value}),rows:9,required:!0}),r.jsxs("div",{className:"support-edit-actions",children:[r.jsxs("select",{value:ge.visibility,onChange:F=>Z({visibility:F.target.value}),children:[r.jsx("option",{value:"public",children:"Public"}),r.jsx("option",{value:"private",children:"Private"})]}),r.jsxs("button",{className:"support-primary-button",type:"submit",disabled:U==="edit",children:[r.jsx(Ns,{size:16})," Save changes"]})]})]}):r.jsxs(r.Fragment,{children:[r.jsx("h3",{children:ge.title}),r.jsx("div",{className:"support-detail-body",children:ge.body.split(`
|
|
2
2
|
`).map((F,Pe)=>r.jsx("p",{children:F||" "},`${ge.id}-body-${Pe}`))})]}),r.jsxs("div",{className:"support-detail-meta",children:[r.jsxs("span",{children:["Opened ",Cl(ge.created_at)]}),ge.app_version&&r.jsxs("span",{children:["Version ",ge.app_version]}),ge.platform&&r.jsx("span",{children:ge.platform}),ge.is_locked&&r.jsxs("span",{children:[r.jsx(Rs,{size:13})," Locked"]}),ge.is_pinned&&r.jsxs("span",{children:[r.jsx(zf,{size:13})," Pinned"]})]}),r.jsxs("div",{className:"support-detail-controls",children:[ge.post_type==="feature"&&r.jsxs("button",{className:`support-vote-button ${_.has(ge.id)?"voted":""}`,type:"button",onClick:()=>{Re()},disabled:U==="vote",children:[r.jsx(tx,{size:16})," ",_.has(ge.id)?"Voted":"Vote"," ",r.jsx("b",{children:ge.vote_count})]}),ct&&r.jsxs("label",{className:"support-status-control",children:[r.jsx("span",{children:"Change status"}),r.jsx("select",{value:ge.status,onChange:F=>{P(F.target.value)},disabled:U==="status",children:(dS[ge.post_type]||[]).map(F=>r.jsx("option",{value:F,children:Rd(F)},F))})]}),ct&&r.jsxs(r.Fragment,{children:[r.jsxs("select",{className:"support-status-control",value:oe,onChange:F=>ee(F.target.value),children:[r.jsx("option",{value:"",children:"Duplicate of..."}),rt.filter(F=>F.id!==ge.id&&F.product_id===ge.product_id).map(F=>r.jsx("option",{value:F.id,children:F.title.slice(0,55)},F.id))]}),r.jsx("button",{className:"support-secondary-button",type:"button",onClick:()=>{He()},disabled:!oe||U==="duplicate",children:"Merge duplicate"})]})]}),C.length>0&&r.jsxs("div",{className:"support-attachments",children:[r.jsx("div",{className:"support-section-heading",children:r.jsxs("div",{children:[r.jsx("span",{children:"Attachments"}),r.jsxs("strong",{children:[C.length," file",C.length===1?"":"s"]})]})}),C.map(F=>r.jsxs("a",{href:F.signed_url,target:"_blank",rel:"noreferrer",children:[r.jsx(uc,{size:14})," ",F.file_name,r.jsxs("small",{children:[Math.ceil(F.size_bytes/1024)," KB"]})]},F.id))]}),r.jsxs("div",{className:"support-comments",children:[r.jsxs("div",{className:"support-section-heading",children:[r.jsxs("div",{children:[r.jsx("span",{children:"Discussion"}),r.jsxs("strong",{children:[b.length," comment",b.length===1?"":"s"]})]}),ge.is_locked&&r.jsxs("span",{className:"support-locked-label",children:[r.jsx(Rs,{size:14})," Locked"]})]}),b.length===0?r.jsx("p",{className:"support-muted",children:"No response yet. Keep the conversation focused on this request."}):r.jsx("div",{className:"support-comment-list",children:b.map(F=>r.jsxs("article",{className:`support-comment ${F.is_staff_answer?"staff":""} ${ge.accepted_comment_id===F.id?"accepted":""}`,children:[r.jsxs("div",{className:"support-comment-head",children:[r.jsx("strong",{children:F.is_staff_answer?"VuvoDesk Support":F.author_id===e.user.id?"You":"Support user"}),F.is_staff_answer&&r.jsxs("span",{children:[r.jsx(sn,{size:13})," Staff answer"]}),ge.accepted_comment_id===F.id&&r.jsxs("span",{children:[r.jsx(Fn,{size:13})," Accepted"]}),r.jsx("time",{children:Cl(F.created_at)})]}),r.jsx("p",{children:F.body}),r.jsxs("div",{className:"support-comment-actions",children:[(e.user.id===ge.author_id||ct)&&ge.post_type==="question"&&ge.accepted_comment_id!==F.id&&r.jsxs("button",{className:"support-secondary-button",type:"button",onClick:()=>{nt(F.id)},disabled:U===`accept-${F.id}`,children:[r.jsx(Ns,{size:14})," Accept answer"]}),ct&&r.jsx("button",{className:"support-icon-button danger",type:"button",onClick:()=>{lS(F.id)},title:"Hide comment",children:r.jsx(Vf,{size:14})})]})]},F.id))}),!ge.is_locked&&r.jsxs("form",{className:"support-comment-form",onSubmit:F=>{ie(F)},children:[r.jsx("textarea",{value:re,onChange:F=>I(F.target.value),placeholder:"Add a focused reply...",rows:3}),r.jsxs("button",{className:"support-primary-button",type:"submit",disabled:U==="comment"||!re.trim(),children:[r.jsx(lc,{size:15})," Reply"]})]})]})]}):r.jsxs("div",{className:"support-detail-empty",children:[r.jsx(nc,{size:28}),r.jsx("strong",{children:"Select a Support request"}),r.jsx("span",{children:"Its discussion and staff actions will appear here."})]})})]})]}):r.jsx("section",{className:"support-page support-auth-page",children:r.jsxs("div",{className:"support-empty-hero",children:[r.jsx("span",{className:"support-hero-icon",children:r.jsx(nc,{size:28})}),r.jsx("p",{className:"support-eyebrow",children:"VuvoDesk Support"}),r.jsx("h2",{children:"Get help, report issues, and shape the product."}),r.jsx("p",{children:"Sign in to view VuvoDesk support and submit a private or public request."}),r.jsxs("button",{className:"support-primary-button",type:"button",onClick:s,children:[r.jsx(sn,{size:17})," Sign in with Google"]})]})})}function hS(e){if(!e)return"Reading the installed version...";const t=String(e.errorCode||e.error||"");switch(e.state){case"checking":return"Checking for a newer VuvoDesk version...";case"available":return`Version ${e.availableVersion||""} is available.`;case"downloading":return`Downloading version ${e.availableVersion||""} (${Math.round(e.progress||0)}%).`;case"downloaded":return`Version ${e.availableVersion||""} is ready. Restart to install it.`;case"installing":return"Closing VuvoDesk safely and starting the update...";case"current":return"This computer has the latest VuvoDesk version.";case"error":return/runtime-recovery-failed/i.test(t)?"The local VuvoDesk service could not restart. Quit VuvoDesk completely and reopen it.":/owner-cleanup-stuck|owner-reset-failed/i.test(t)?"The Windows update service could not reset. Quit VuvoDesk completely, reopen it, and check again.":/installer-launch-failed/i.test(t)?"The installer could not start. VuvoDesk restored its local service so you can retry.":/version-mismatch/i.test(t)?"The downloaded update did not match the expected version. VuvoDesk will retry safely.":/stalled|timed-out/i.test(t)?"The update connection stopped responding. VuvoDesk will retry automatically.":"The update server could not be reached. VuvoDesk will retry automatically.";case"development":return"Desktop updates are available in an installed VuvoDesk build.";case"unavailable":return"Updates are not available for this desktop build.";default:return"VuvoDesk checks once when the desktop app starts."}}function Ov(){const e=window.liveDesk?.updates,[t,n]=i.useState(null),[s,a]=i.useState(!1);if(i.useEffect(()=>{if(!e)return;let f=!0;e.getStatus?.().then(g=>{f&&n(g)});const m=e.onStatus?.(g=>{f&&n(g)});return()=>{f=!1,m?.()}},[e]),!e)return null;const o=t?.state==="downloaded"||t?.downloaded===!0,c=!!t?.reopenRequired||/runtime-recovery-failed|owner-cleanup-stuck|owner-reset-failed/i.test(String(t?.errorCode||"")),u=s||t?.state==="checking"||t?.state==="downloading"||t?.state==="installing",d=t?.channel==="dev"?"Development":t?.channel==="stable"?"Stable":t?.channel||"Unknown",p=async()=>{a(!0);try{const f=o?await e.install?.():await e.check?.();f&&n(f)}finally{a(!1)}};return r.jsxs("section",{className:"settings-section-card desktop-update-card",children:[r.jsxs("div",{className:"settings-section-heading",children:[r.jsxs("div",{children:[r.jsx("span",{children:"Desktop app"}),r.jsx("h3",{children:"VuvoDesk updates"})]}),r.jsx(uc,{size:20})]}),r.jsx("p",{className:"settings-help","aria-live":"polite",children:hS(t)}),r.jsxs("div",{className:"desktop-update-meta",children:[r.jsx("span",{children:"Installed"}),r.jsx("strong",{children:t?.currentVersion||"Unknown"}),r.jsx("span",{children:"Channel"}),r.jsx("strong",{children:d}),t?.availableVersion&&r.jsxs(r.Fragment,{children:[r.jsx("span",{children:"Available"}),r.jsx("strong",{children:t.availableVersion})]})]}),r.jsxs("button",{className:"settings-reset desktop-update-action",onClick:()=>{p()},disabled:u||c,type:"button",children:[r.jsx(Xa,{size:15,className:u?"desktop-update-spin":""}),c?"Reopen VuvoDesk":o?"Restart and update":u?"Updating...":"Check for updates"]})]})}function kl(e){return!!e&&typeof e=="object"}function $v(e){let t=e;return kl(t)&&"data"in t&&(t=t.data),kl(t)&&"session"in t&&(t=t.session),!kl(t)||typeof t.access_token!="string"||!t.access_token||!kl(t.user)||typeof t.user.id!="string"||!t.user.id?null:t}function Zf(e){return e?.access_token?e.refresh_token?"":"refresh-token-required":"access-token-required"}const Bv={hub:"Use this computer as Hub. Hub connects to and manages Client computers.","switch-to-hub":"Switch this computer from Client to Hub. It will manage Client computers instead of sharing its own screen.",client:"Keep this computer in Client mode so its screens, files, audio, and remote controls remain available to the active Hub.",wall:"Show live thumbnails from every connected Client. Choose a display, change tile size, or move into Control without opening another connection.",control:"Open the selected Client at full resolution and send mouse and keyboard input through the existing Hub session.","share-files":"Browse files on the Hub, send files to selected Clients, and manage shared folders and transfer progress.",agents:"Run approved commands on connected Clients through the Hub-hosted Codex Agent and VuvoDesk permission controls."},pp={en:Bv,ko:{hub:"이 컴퓨터를 Hub로 사용합니다. Hub는 Client 컴퓨터를 연결하고 관리합니다.","switch-to-hub":"이 컴퓨터를 Client에서 Hub로 바꿉니다. 자신의 화면 공유를 멈추고 Client 컴퓨터를 관리합니다.",client:"이 컴퓨터를 Client 모드로 유지합니다. 화면, 파일, 오디오와 원격 제어 기능이 활성 Hub에서 계속 사용 가능하도록 연결합니다.",wall:"연결된 모든 Client의 실시간 화면을 한곳에 표시합니다. 모니터와 타일 크기를 선택하고 새 연결 없이 Control로 이동할 수 있습니다.",control:"선택한 Client 화면을 전체 해상도로 열고 기존 Hub 세션을 통해 마우스와 키보드 입력을 전송합니다.","share-files":"Hub의 파일을 탐색하고 선택한 Client로 전송하며 공유 폴더와 전송 진행 상태를 관리합니다.",agents:"Hub의 Codex가 연결된 Client에서 VuvoDesk 권한과 승인 범위 안의 명령을 실행합니다."},ja:{hub:"このコンピューターを VuvoDesk Hub として運用します。Hub は Client 接続、Wall、Control、ファイル共有、Agents を一か所で管理する統合コントロールセンターで、ネットワーク変更後に押すと安全な接続情報も更新します。","switch-to-hub":"このコンピューターを Client から Hub に切り替えます。新しい役割を保存して同じデスクトップランタイムを再起動し、Wall を開きます。Client としての共有は停止します。",client:"このコンピューターを Client モードで維持し、画面、ファイル、音声、リモート操作をアクティブ Hub から利用できるようにします。",wall:"接続中のすべての Client のライブ画面を一覧表示します。ディスプレイやタイルサイズを選び、新しい接続なしで Control に移動できます。",control:"選択した Client をフル解像度で開き、既存の Hub セッションからマウスとキーボード入力を送信します。","share-files":"Hub のファイルを参照し、選択した Client への送信、共有フォルダー、転送状況を管理します。",agents:"Hub の Codex Agent が、VuvoDesk の権限と承認の範囲内で接続中の Client にコマンドを実行します。"},zh:{hub:"将此电脑作为 VuvoDesk Hub 运行。Hub 是统一控制中心,可集中管理 Client 连接、Wall、Control、文件共享和 Agents;网络变化后按下此按钮还会刷新安全连接信息。","switch-to-hub":"将此电脑从 Client 切换为 Hub。VuvoDesk 保存新角色、重启同一桌面运行时并打开 Wall;此电脑将停止作为 Client 共享。",client:"让此电脑保持 Client 模式,使活动 Hub 可以继续使用它的屏幕、文件、音频和远程控制。",wall:"集中显示所有已连接 Client 的实时缩略图。可以选择显示器、调整磁贴大小,并在不新建连接的情况下进入 Control。",control:"以完整分辨率打开所选 Client,并通过现有 Hub 会话发送鼠标和键盘输入。","share-files":"浏览 Hub 文件、向所选 Client 发送文件,并管理共享文件夹和传输进度。",agents:"Hub 的 Codex Agent 会在 VuvoDesk 权限与批准范围内,对已连接的 Client 执行命令。"},"zh-TW":{hub:"將此電腦作為 VuvoDesk Hub 運作。Hub 是統一控制中心,可集中管理 Client 連線、Wall、Control、檔案分享與 Agents;網路變更後按下此按鈕也會更新安全連線資訊。","switch-to-hub":"將此電腦從 Client 切換為 Hub。VuvoDesk 會儲存新角色、重新啟動同一桌面執行階段並開啟 Wall;此電腦將停止以 Client 身分共享。",client:"讓此電腦維持 Client 模式,使作用中 Hub 可繼續使用它的畫面、檔案、音訊與遠端控制。",wall:"集中顯示所有已連線 Client 的即時縮圖。可選擇顯示器、調整圖塊大小,並在不建立新連線的情況下進入 Control。",control:"以完整解析度開啟所選 Client,並透過現有 Hub 工作階段傳送滑鼠與鍵盤輸入。","share-files":"瀏覽 Hub 檔案、傳送檔案到所選 Client,並管理共享資料夾與傳輸進度。",agents:"Hub 的 Codex Agent 會在 VuvoDesk 權限與核准範圍內,對已連線的 Client 執行命令。"},es:{hub:"Usa este equipo como VuvoDesk Hub. Hub es el centro de control unificado para conexiones Client, Wall, Control, archivos y Agents; púlsalo tras cambios de red para actualizar el acceso seguro.","switch-to-hub":"Cambia este equipo de Client a Hub. VuvoDesk guarda el nuevo rol, reinicia el mismo entorno de escritorio y abre Wall; el equipo deja de compartirse como Client.",client:"Mantiene este equipo en modo Client para que sus pantallas, archivos, audio y control remoto sigan disponibles desde el Hub activo.",wall:"Muestra miniaturas en vivo de todos los Clients conectados. Elige pantalla y tamaño, o entra en Control sin abrir otra conexión.",control:"Abre el Client seleccionado a resolución completa y envía ratón y teclado por la sesión Hub existente.","share-files":"Explora archivos del Hub, envíalos a los Clients seleccionados y administra carpetas compartidas y transferencias.",agents:"El Codex Agent del Hub ejecuta comandos en los Clients conectados dentro de los permisos y aprobaciones de VuvoDesk."},fr:{hub:"Utilise cet ordinateur comme VuvoDesk Hub. Hub est le centre de contrôle unifié des connexions Client, de Wall, Control, des fichiers et des Agents ; appuyez après un changement réseau pour actualiser l’accès sécurisé.","switch-to-hub":"Bascule cet ordinateur de Client vers Hub. VuvoDesk enregistre le nouveau rôle, redémarre le même environnement de bureau et ouvre Wall ; le partage Client s’arrête.",client:"Maintient cet ordinateur en mode Client afin que ses écrans, fichiers, sons et commandes à distance restent disponibles depuis le Hub actif.",wall:"Affiche les miniatures en direct de tous les Clients connectés. Choisissez l’écran et la taille, ou passez à Control sans nouvelle connexion.",control:"Ouvre le Client sélectionné en pleine résolution et transmet souris et clavier via la session Hub existante.","share-files":"Parcourez les fichiers du Hub, envoyez-les aux Clients sélectionnés et gérez dossiers partagés et transferts.",agents:"Le Codex Agent du Hub exécute des commandes sur les Clients connectés selon les permissions et approbations de VuvoDesk."},de:{hub:"Verwendet diesen Computer als VuvoDesk Hub. Hub ist die gemeinsame Steuerzentrale für Client-Verbindungen, Wall, Control, Dateien und Agents; nach Netzwerkänderungen aktualisiert ein Klick den sicheren Zugriff.","switch-to-hub":"Wechselt diesen Computer von Client zu Hub. VuvoDesk speichert die neue Rolle, startet dieselbe Desktop-Laufzeit neu und öffnet Wall; die Client-Freigabe endet.",client:"Hält diesen Computer im Client-Modus, damit Bildschirme, Dateien, Audio und Fernsteuerung am aktiven Hub verfügbar bleiben.",wall:"Zeigt Live-Vorschaubilder aller verbundenen Clients. Display und Kachelgröße wählen oder ohne neue Verbindung zu Control wechseln.",control:"Öffnet den gewählten Client in voller Auflösung und sendet Maus- und Tastatureingaben über die bestehende Hub-Sitzung.","share-files":"Dateien auf dem Hub durchsuchen, an gewählte Clients senden sowie Freigaben und Übertragungen verwalten.",agents:"Der Codex Agent des Hubs führt Befehle auf verbundenen Clients innerhalb der VuvoDesk-Berechtigungen und Freigaben aus."},"pt-BR":{hub:"Usa este computador como VuvoDesk Hub. Hub é o centro de controle unificado para conexões Client, Wall, Control, arquivos e Agents; após mudanças de rede, pressione para atualizar o acesso seguro.","switch-to-hub":"Muda este computador de Client para Hub. O VuvoDesk salva a nova função, reinicia o mesmo runtime de desktop e abre o Wall; o compartilhamento como Client é encerrado.",client:"Mantém este computador no modo Client para que telas, arquivos, áudio e controle remoto continuem disponíveis no Hub ativo.",wall:"Mostra miniaturas ao vivo de todos os Clients conectados. Escolha a tela e o tamanho ou entre em Control sem criar outra conexão.",control:"Abre o Client selecionado em resolução total e envia mouse e teclado pela sessão Hub existente.","share-files":"Navegue pelos arquivos do Hub, envie para Clients selecionados e gerencie pastas compartilhadas e transferências.",agents:"O Codex Agent do Hub executa comandos nos Clients conectados dentro das permissões e aprovações do VuvoDesk."},it:{hub:"Usa questo computer come VuvoDesk Hub. Hub è il centro di controllo unificato per connessioni Client, Wall, Control, file e Agents; dopo modifiche di rete, premilo per aggiornare l’accesso sicuro.","switch-to-hub":"Passa questo computer da Client a Hub. VuvoDesk salva il nuovo ruolo, riavvia lo stesso runtime desktop e apre Wall; la condivisione come Client termina.",client:"Mantiene questo computer in modalità Client, rendendo schermi, file, audio e controllo remoto disponibili all’Hub attivo.",wall:"Mostra le anteprime live di tutti i Client connessi. Scegli display e dimensione oppure passa a Control senza una nuova connessione.",control:"Apre il Client selezionato a piena risoluzione e invia mouse e tastiera tramite la sessione Hub esistente.","share-files":"Esplora i file dell’Hub, inviali ai Client selezionati e gestisci cartelle condivise e trasferimenti.",agents:"Il Codex Agent dell’Hub esegue comandi sui Client connessi entro i permessi e le approvazioni di VuvoDesk."},id:{hub:"Gunakan komputer ini sebagai VuvoDesk Hub. Hub adalah pusat kendali terpadu untuk koneksi Client, Wall, Control, file, dan Agents; tekan setelah perubahan jaringan untuk memperbarui akses aman.","switch-to-hub":"Alihkan komputer ini dari Client menjadi Hub. VuvoDesk menyimpan peran baru, memulai ulang runtime desktop yang sama, lalu membuka Wall; berbagi sebagai Client berhenti.",client:"Pertahankan komputer ini dalam mode Client agar layar, file, audio, dan kendali jarak jauh tetap tersedia bagi Hub aktif.",wall:"Tampilkan thumbnail live semua Client yang terhubung. Pilih layar dan ukuran tile atau masuk ke Control tanpa koneksi baru.",control:"Buka Client terpilih pada resolusi penuh dan kirim input mouse serta keyboard melalui sesi Hub yang ada.","share-files":"Jelajahi file Hub, kirim ke Client terpilih, serta kelola folder bersama dan progres transfer.",agents:"Codex Agent di Hub menjalankan perintah pada Client terhubung sesuai izin dan persetujuan VuvoDesk."},vi:{hub:"Dùng máy tính này làm VuvoDesk Hub. Hub là trung tâm điều khiển hợp nhất cho kết nối Client, Wall, Control, tệp và Agents; nhấn sau khi đổi mạng để làm mới quyền truy cập an toàn.","switch-to-hub":"Chuyển máy tính này từ Client sang Hub. VuvoDesk lưu vai trò mới, khởi động lại cùng môi trường desktop và mở Wall; việc chia sẻ dưới dạng Client sẽ dừng.",client:"Giữ máy tính này ở chế độ Client để màn hình, tệp, âm thanh và điều khiển từ xa luôn sẵn sàng cho Hub đang hoạt động.",wall:"Hiển thị ảnh thu nhỏ trực tiếp của mọi Client đã kết nối. Chọn màn hình, cỡ ô hoặc vào Control mà không tạo kết nối mới.",control:"Mở Client đã chọn ở độ phân giải đầy đủ và gửi chuột, bàn phím qua phiên Hub hiện có.","share-files":"Duyệt tệp trên Hub, gửi tới Client đã chọn và quản lý thư mục chia sẻ cùng tiến trình truyền.",agents:"Codex Agent trên Hub chạy lệnh trên các Client đã kết nối trong phạm vi quyền và phê duyệt của VuvoDesk."},th:{hub:"ใช้คอมพิวเตอร์เครื่องนี้เป็น VuvoDesk Hub โดย Hub คือศูนย์ควบคุมรวมสำหรับการเชื่อมต่อ Client, Wall, Control, ไฟล์ และ Agents และกดหลังเปลี่ยนเครือข่ายเพื่อรีเฟรชการเข้าถึงที่ปลอดภัย","switch-to-hub":"เปลี่ยนคอมพิวเตอร์นี้จาก Client เป็น Hub โดย VuvoDesk จะบันทึกบทบาทใหม่ รีสตาร์ต desktop runtime เดิม และเปิด Wall พร้อมหยุดแชร์ในฐานะ Client",client:"ให้คอมพิวเตอร์นี้อยู่ในโหมด Client เพื่อให้ Hub ที่ใช้งานเข้าถึงหน้าจอ ไฟล์ เสียง และการควบคุมระยะไกลได้ต่อเนื่อง",wall:"แสดงภาพสดแบบย่อของ Client ที่เชื่อมต่อทั้งหมด เลือกจอและขนาด tile หรือเข้า Control ได้โดยไม่เปิดการเชื่อมต่อใหม่",control:"เปิด Client ที่เลือกแบบความละเอียดเต็ม และส่งเมาส์กับคีย์บอร์ดผ่าน session ของ Hub ที่มีอยู่","share-files":"เรียกดูไฟล์บน Hub ส่งไปยัง Client ที่เลือก และจัดการโฟลเดอร์แชร์กับความคืบหน้าการโอน",agents:"Codex Agent บน Hub เรียกใช้คำสั่งบน Client ที่เชื่อมต่อภายใต้สิทธิ์และการอนุมัติของ VuvoDesk"},hi:{hub:"इस कंप्यूटर को VuvoDesk Hub के रूप में उपयोग करें। Hub, Client कनेक्शन, Wall, Control, फ़ाइल और Agents का एकीकृत नियंत्रण केंद्र है; नेटवर्क बदलने के बाद सुरक्षित पहुँच ताज़ा करने के लिए इसे दबाएँ।","switch-to-hub":"इस कंप्यूटर को Client से Hub में बदलता है। VuvoDesk नई भूमिका सहेजता है, उसी desktop runtime को restart करके Wall खोलता है और Client sharing रोक देता है।",client:"इस कंप्यूटर को Client मोड में रखता है ताकि इसकी स्क्रीन, फ़ाइलें, ऑडियो और remote control सक्रिय Hub पर उपलब्ध रहें।",wall:"सभी जुड़े Clients के live thumbnail दिखाता है। स्क्रीन और tile आकार चुनें या नया connection खोले बिना Control में जाएँ।",control:"चुने हुए Client को पूर्ण resolution में खोलता है और मौजूदा Hub session से mouse तथा keyboard input भेजता है।","share-files":"Hub की फ़ाइलें देखें, चुने हुए Clients को भेजें और shared folders तथा transfer progress प्रबंधित करें।",agents:"Hub का Codex Agent VuvoDesk permissions और approvals के भीतर जुड़े Clients पर commands चलाता है।"},ar:{hub:"استخدم هذا الكمبيوتر بوصفه VuvoDesk Hub. يمثّل Hub مركز التحكم الموحّد لاتصالات Client وWall وControl والملفات وAgents؛ اضغط عليه بعد تغييرات الشبكة لتحديث الوصول الآمن.","switch-to-hub":"يحوّل هذا الكمبيوتر من Client إلى Hub. يحفظ VuvoDesk الدور الجديد ويعيد تشغيل بيئة سطح المكتب نفسها ويفتح Wall، ويتوقف الجهاز عن المشاركة كـ Client.",client:"يبقي هذا الكمبيوتر في وضع Client لتظل شاشاته وملفاته وصوته والتحكم عن بعد متاحة من Hub النشط.",wall:"يعرض صورا حية مصغرة لكل Clients المتصلين. اختر الشاشة وحجم البلاطات أو انتقل إلى Control من دون اتصال جديد.",control:"يفتح Client المحدد بالدقة الكاملة ويرسل إدخال الماوس ولوحة المفاتيح عبر جلسة Hub الحالية.","share-files":"استعرض ملفات Hub وأرسلها إلى Clients المحددين وأدر المجلدات المشتركة وتقدم النقل.",agents:"يشغّل Codex Agent على Hub الأوامر في Clients المتصلين ضمن صلاحيات وموافقات VuvoDesk."},tr:{hub:"Bu bilgisayarı VuvoDesk Hub olarak kullanır. Hub; Client bağlantıları, Wall, Control, dosyalar ve Agents için birleşik kontrol merkezidir; ağ değişikliklerinden sonra güvenli erişimi yenilemek için basın.","switch-to-hub":"Bu bilgisayarı Client rolünden Hub rolüne geçirir. VuvoDesk yeni rolü kaydeder, aynı masaüstü runtime’ını yeniden başlatıp Wall’u açar; Client paylaşımı durur.",client:"Bu bilgisayarı Client modunda tutar; ekran, dosya, ses ve uzaktan kontrol özellikleri etkin Hub tarafından kullanılabilir kalır.",wall:"Bağlı tüm Client ekranlarının canlı küçük görüntülerini gösterir. Ekran ve kutu boyutunu seçin veya yeni bağlantı açmadan Control’e geçin.",control:"Seçili Client’ı tam çözünürlükte açar ve mevcut Hub oturumu üzerinden fare ile klavye girdisi gönderir.","share-files":"Hub dosyalarını gezin, seçili Client’lara gönderin ve paylaşılan klasörlerle aktarım ilerlemesini yönetin.",agents:"Hub Codex Agent, bağlı Client’larda VuvoDesk izinleri ve onayları kapsamında komut çalıştırır."}};function Su(e){const t=e?[e]:typeof navigator>"u"?["en"]:navigator.languages?.length?navigator.languages:[navigator.language];for(const n of t){const s=String(n||"").trim(),a=s.toLowerCase();if(!a)continue;if(a.startsWith("zh-tw")||a.startsWith("zh-hk"))return"zh-TW";if(a.startsWith("zh"))return"zh";if(a.startsWith("pt"))return"pt-BR";const o=a.split("-")[0];if(pp[s])return s;if(pp[o])return o}return"en"}function ou(e,t){const n=Su(t);return pp[n]?.[e]||Bv[e]}function mp(e,t,n){return`${e}
|
|
3
3
|
${ou(t,n)}`}const Hv={eyebrow:"Change computer role",title:"Switch this computer to Hub?",description:"VuvoDesk will stop sharing this computer as a Client, save the Hub role, restart the local runtime, and open Wall in this same window.",restartNotice:"Remote streams from this computer will end while VuvoDesk restarts.",cancel:"Cancel",confirm:"Switch to Hub",closeLabel:"Close Hub switch confirmation"},gS={en:Hv,ko:{eyebrow:"컴퓨터 역할 변경",title:"이 컴퓨터를 Hub로 전환하시겠습니까?",description:"이 컴퓨터의 Client 공유를 중지하고 Hub 역할을 저장한 뒤 로컬 런타임을 재시작하여 같은 창에서 Wall을 엽니다.",restartNotice:"VuvoDesk가 재시작되는 동안 이 컴퓨터의 원격 스트림이 종료됩니다.",cancel:"취소",confirm:"Hub로 전환",closeLabel:"Hub 전환 확인 닫기"},ja:{eyebrow:"コンピューターの役割を変更",title:"このコンピューターを Hub に切り替えますか?",description:"このコンピューターの Client 共有を停止し、Hub の役割を保存してローカルランタイムを再起動し、同じウィンドウで Wall を開きます。",restartNotice:"VuvoDesk の再起動中、このコンピューターのリモートストリームは終了します。",cancel:"キャンセル",confirm:"Hub に切り替える",closeLabel:"Hub 切り替え確認を閉じる"},zh:{eyebrow:"更改电脑角色",title:"将此电脑切换为 Hub?",description:"VuvoDesk 将停止此电脑的 Client 共享,保存 Hub 角色,重启本地运行时,并在同一窗口中打开 Wall。",restartNotice:"VuvoDesk 重启期间,此电脑的远程流将会结束。",cancel:"取消",confirm:"切换为 Hub",closeLabel:"关闭 Hub 切换确认"},"zh-TW":{eyebrow:"變更電腦角色",title:"要將此電腦切換為 Hub 嗎?",description:"VuvoDesk 將停止此電腦的 Client 分享、儲存 Hub 角色、重新啟動本機執行階段,並在同一視窗中開啟 Wall。",restartNotice:"VuvoDesk 重新啟動期間,此電腦的遠端串流將會結束。",cancel:"取消",confirm:"切換為 Hub",closeLabel:"關閉 Hub 切換確認"},es:{eyebrow:"Cambiar función del equipo",title:"¿Cambiar este equipo a Hub?",description:"VuvoDesk dejará de compartir este equipo como Client, guardará la función Hub, reiniciará el entorno local y abrirá Wall en esta misma ventana.",restartNotice:"Los streams remotos de este equipo terminarán mientras VuvoDesk se reinicia.",cancel:"Cancelar",confirm:"Cambiar a Hub",closeLabel:"Cerrar confirmación de cambio a Hub"},fr:{eyebrow:"Changer le rôle de l’ordinateur",title:"Basculer cet ordinateur vers Hub ?",description:"VuvoDesk arrêtera le partage Client de cet ordinateur, enregistrera le rôle Hub, redémarrera le runtime local et ouvrira Wall dans cette même fenêtre.",restartNotice:"Les flux distants de cet ordinateur prendront fin pendant le redémarrage de VuvoDesk.",cancel:"Annuler",confirm:"Basculer vers Hub",closeLabel:"Fermer la confirmation de bascule vers Hub"},de:{eyebrow:"Computerrolle ändern",title:"Diesen Computer auf Hub umstellen?",description:"VuvoDesk beendet die Client-Freigabe dieses Computers, speichert die Hub-Rolle, startet die lokale Laufzeit neu und öffnet Wall im selben Fenster.",restartNotice:"Die Remote-Streams dieses Computers enden während des VuvoDesk-Neustarts.",cancel:"Abbrechen",confirm:"Auf Hub umstellen",closeLabel:"Bestätigung für Hub-Wechsel schließen"},"pt-BR":{eyebrow:"Alterar função do computador",title:"Mudar este computador para Hub?",description:"O VuvoDesk interromperá o compartilhamento deste computador como Client, salvará a função Hub, reiniciará o runtime local e abrirá o Wall nesta mesma janela.",restartNotice:"Os streams remotos deste computador serão encerrados enquanto o VuvoDesk reinicia.",cancel:"Cancelar",confirm:"Mudar para Hub",closeLabel:"Fechar confirmação de mudança para Hub"},it:{eyebrow:"Cambia ruolo del computer",title:"Passare questo computer a Hub?",description:"VuvoDesk interromperà la condivisione Client di questo computer, salverà il ruolo Hub, riavvierà il runtime locale e aprirà Wall nella stessa finestra.",restartNotice:"Gli stream remoti di questo computer termineranno durante il riavvio di VuvoDesk.",cancel:"Annulla",confirm:"Passa a Hub",closeLabel:"Chiudi la conferma del passaggio a Hub"},id:{eyebrow:"Ubah peran komputer",title:"Alihkan komputer ini menjadi Hub?",description:"VuvoDesk akan menghentikan berbagi komputer ini sebagai Client, menyimpan peran Hub, memulai ulang runtime lokal, lalu membuka Wall di jendela yang sama.",restartNotice:"Stream jarak jauh dari komputer ini akan berakhir saat VuvoDesk dimulai ulang.",cancel:"Batal",confirm:"Alihkan ke Hub",closeLabel:"Tutup konfirmasi peralihan Hub"},vi:{eyebrow:"Đổi vai trò máy tính",title:"Chuyển máy tính này thành Hub?",description:"VuvoDesk sẽ dừng chia sẻ máy tính này dưới dạng Client, lưu vai trò Hub, khởi động lại runtime cục bộ và mở Wall trong cùng cửa sổ.",restartNotice:"Các luồng từ xa của máy tính này sẽ kết thúc trong khi VuvoDesk khởi động lại.",cancel:"Hủy",confirm:"Chuyển sang Hub",closeLabel:"Đóng xác nhận chuyển sang Hub"},th:{eyebrow:"เปลี่ยนบทบาทคอมพิวเตอร์",title:"เปลี่ยนคอมพิวเตอร์เครื่องนี้เป็น Hub หรือไม่",description:"VuvoDesk จะหยุดแชร์คอมพิวเตอร์เครื่องนี้ในฐานะ Client บันทึกบทบาท Hub รีสตาร์ทรันไทม์ภายในเครื่อง และเปิด Wall ในหน้าต่างเดิม",restartNotice:"สตรีมระยะไกลจากคอมพิวเตอร์เครื่องนี้จะสิ้นสุดลงระหว่างที่ VuvoDesk รีสตาร์ท",cancel:"ยกเลิก",confirm:"เปลี่ยนเป็น Hub",closeLabel:"ปิดการยืนยันการเปลี่ยนเป็น Hub"},hi:{eyebrow:"कंप्यूटर की भूमिका बदलें",title:"इस कंप्यूटर को Hub में बदलें?",description:"VuvoDesk इस कंप्यूटर की Client साझेदारी बंद करेगा, Hub भूमिका सहेजेगा, स्थानीय रनटाइम पुनः आरंभ करेगा और इसी विंडो में Wall खोलेगा।",restartNotice:"VuvoDesk के पुनः आरंभ होने के दौरान इस कंप्यूटर की रिमोट स्ट्रीम समाप्त हो जाएँगी।",cancel:"रद्द करें",confirm:"Hub में बदलें",closeLabel:"Hub परिवर्तन की पुष्टि बंद करें"},ar:{eyebrow:"تغيير دور الكمبيوتر",title:"هل تريد تحويل هذا الكمبيوتر إلى Hub؟",description:"سيوقف VuvoDesk مشاركة هذا الكمبيوتر كـ Client، ويحفظ دور Hub، ويعيد تشغيل وقت التشغيل المحلي، ثم يفتح Wall في النافذة نفسها.",restartNotice:"ستنتهي التدفقات البعيدة من هذا الكمبيوتر أثناء إعادة تشغيل VuvoDesk.",cancel:"إلغاء",confirm:"التحويل إلى Hub",closeLabel:"إغلاق تأكيد التحويل إلى Hub"},tr:{eyebrow:"Bilgisayar rolünü değiştir",title:"Bu bilgisayar Hub rolüne geçirilsin mi?",description:"VuvoDesk bu bilgisayarın Client paylaşımını durdurur, Hub rolünü kaydeder, yerel çalışma zamanını yeniden başlatır ve Wall’u aynı pencerede açar.",restartNotice:"VuvoDesk yeniden başlatılırken bu bilgisayarın uzak akışları sona erer.",cancel:"İptal",confirm:"Hub’a geçir",closeLabel:"Hub geçişi onayını kapat"}},Wv={eyebrow:"Computer role",title:"Use this computer as Hub?",description:"Hub connects to and manages Client computers.",restartNotice:"If another computer is Hub, this computer will become the new Hub.",cancel:"Cancel",confirm:"Use as Hub",closeLabel:"Close Hub confirmation"},vS={en:Wv,ko:{eyebrow:"컴퓨터 역할",title:"이 컴퓨터를 Hub로 사용할까요?",description:"Hub는 Client 컴퓨터를 연결하고 관리합니다.",restartNotice:"다른 컴퓨터가 Hub라면 이 컴퓨터가 새 Hub가 됩니다.",cancel:"취소",confirm:"Hub로 설정",closeLabel:"Hub 설정 확인 닫기"}};function bS(e){const t=Su(e);return gS[t]||Hv}function wS(e){const t=Su(e);return vS[t]||Wv}function yS(e=[]){return[...new Set(e.filter(t=>typeof t=="string").map(t=>t.trim()).filter(Boolean))]}function xS(e=[],t=new Set){return e.find(n=>!t.has(n))||""}const SS="client-runtime-connection-unavailable",CS="VuvoDesk Client is reconnecting to the service on this computer.",kS=/failed to fetch|fetch failed|network request failed|networkerror when attempting to fetch resource|load failed|signal timed out|operation was aborted due to timeout|the operation timed out/i;function zv(e,t){if(!e||typeof e!="object")return"";const n=e[t];return typeof n=="string"?n.trim():""}function fp(e){return typeof e=="string"?e.trim():zv(e,"message")||String(e??"").trim()}function eh(e){return/supabase-user-verification-failed:(401|403)/i.test(e)?"Saved sign-in needs refresh. VuvoDesk will retry it automatically.":e}function th(e){const t=fp(e)||"Client status could not be refreshed.",n=zv(e,"name").toLowerCase();return n==="timeouterror"||n==="aborterror"||kS.test(t)?{key:SS,message:CS}:{key:`client-status-poll:${t}`,message:t}}function MS({actionError:e="",discoveryWakeError:t=null,statusPollError:n=null,runtimeError:s=""}={}){const a=fp(e);if(a)return{key:`client-action:${a}`,message:eh(a)};if(t?.key&&t?.message)return t;if(n?.key&&n?.message)return n;const o=fp(s);return o?{key:`client-runtime:${o}`,message:eh(o)}:null}function AS(e,t){if(!t?.message)return{nextKey:"",message:null};const n=String(t.key||t.message).trim();return String(e||"")===n?{nextKey:n,message:null}:{nextKey:n,message:t.message}}const RS=[{id:"docs",label:"Doc",icon:su},{id:"support",label:"Support",icon:nc},{id:"pricing",label:"Pricing",icon:rc},{id:"settings",label:"Settings",icon:au}],nh=[0,1e3,2e3,5e3,1e4,2e4,3e4],NS=15e3;function TS(e=""){const t=e.trim().replace(/\/+$/,"");return t||(typeof window>"u"?"":window.location.port==="5179"?window.location.origin:"http://127.0.0.1:5179")}async function Oa(e,t=!1){const n=t?"":sessionStorage.getItem("livedesk.client.csrf");if(n)return n;const s=await fetch(`${e}/api/runtime/status`,{cache:"no-store"}),a=await s.json().catch(()=>({}));if(!s.ok)throw new Error(a.error||`Client runtime returned HTTP ${s.status}.`);const o=String(a.csrfToken||"");return o&&sessionStorage.setItem("livedesk.client.csrf",o),o}function hp(e){return`${Math.max(0,Math.min(100,Number(e||0))).toFixed(0)}%`}function Nd(e){return Number.isFinite(e)?`${Math.max(0,Math.min(100,Number(e))).toFixed(0)}%`:"—"}function Vv(e){return Number.isFinite(e)?hp(Number(e)):"0%"}function Ua(e){const t=Number(e);return!Number.isFinite(t)||t<0?"—":t>=1024**4?`${(t/1024**4).toFixed(t>=10*1024**4?0:1)} TB`:t>=1024**3?`${(t/1024**3).toFixed(t>=10*1024**3?0:1)} GB`:`${(t/1024**2).toFixed(0)} MB`}function rh(e){const t=Math.max(0,Number(e||0));return t>=1024**3?`${(t/1024**3).toFixed(1)} GB/s`:t>=1024**2?`${(t/1024**2).toFixed(1)} MB/s`:t>=1024?`${(t/1024).toFixed(1)} KB/s`:`${t.toFixed(0)} B/s`}function IS(e,t){const n=Number(e||0)/1073741824,s=Number(t||0)/1024**3;return s>0?`${n.toFixed(1)} / ${s.toFixed(1)} GB`:"Checking..."}function PS(e,t){return!Number.isFinite(t)||Number(t)<=0?"Dedicated memory unavailable":Number.isFinite(e)?`${Ua(e)} / ${Ua(t)}`:`${Ua(t)} available`}function jS(e){const t=Math.max(0,Math.floor(Number(e||0)/60)),n=Math.floor(t/1440),s=Math.floor(t%1440/60),a=t%60;return n>0?`${n}d ${s}h`:s>0?`${s}h ${a}m`:`${a}m`}function Ml({icon:e,label:t,value:n,detail:s,percent:a}){return r.jsxs("article",{className:"client-resource-metric",children:[r.jsxs("div",{className:"client-resource-metric-head",children:[r.jsx(e,{size:17}),r.jsx("span",{children:t}),r.jsx("strong",{children:n})]}),r.jsx("small",{title:s,children:s}),r.jsx("i",{"aria-hidden":"true",children:r.jsx("b",{style:{width:Vv(a)}})})]})}function ES(e,t){const n=e?.user.user_metadata||{},s=n.full_name||n.name||n.preferred_username||e?.user.email||e?.user.id||t?.userName||t?.auth?.name||t?.userEmail||t?.userId||"Account";return String(s).trim()||"Account"}function FS(e,t){const n=e?.user.user_metadata||{};return yS([n.avatar_url,n.picture,t?.userAvatarUrl,t?.auth?.avatarUrl])}function DS({page:e,status:t}){const s={docs:{label:"DOC",title:"Using this computer",body:"This computer connects to its assigned Hub automatically. Keep VuvoDesk running and manage screens, files, and remote control from the Hub."},pricing:{label:"PRICING",title:"VuvoDesk plans",body:"Plans are based on how many computers the Hub manages. This Client computer does not need a separate subscription or setup."},settings:{label:"SETTINGS",title:"Computer preferences",body:"VuvoDesk keeps the verified sign-in on this computer and reconnects to the assigned Hub automatically."}}[e];return r.jsxs("section",{className:"client-service-page",children:[r.jsx("span",{className:"client-unified-section-label",children:s.label}),r.jsx("h2",{children:s.title}),r.jsx("p",{children:s.body}),r.jsxs("div",{className:"client-service-page-card",children:[e==="docs"&&r.jsxs(r.Fragment,{children:[r.jsx("strong",{children:"Automatic connection"}),r.jsx("span",{children:"Start VuvoDesk. This computer signs in, finds the Hub, and becomes available without another action."})]}),e==="pricing"&&r.jsxs(r.Fragment,{children:[r.jsx("strong",{children:"One plan, managed at the Hub"}),r.jsx("span",{children:"Computer access follows the account and plan used by the Hub."})]}),e==="settings"&&r.jsxs(r.Fragment,{children:[r.jsx("strong",{children:"Saved sign-in"}),r.jsx("span",{children:t?.auth?.persisted?"Enabled on this computer":"Sign in once to enable automatic reconnection"})]})]}),e==="settings"&&r.jsx(Ov,{})]})}function _S({session:e,status:t,pin:n,roleChangeMessage:s,videoAccelerationBusy:a,slotInput:o,slotBusy:c,onSignIn:u,onPinChange:d,onSubmitPin:p,onSlotInputChange:f,onSaveSlot:m,onEnableVideoAcceleration:g}){const w=t?.connectionState==="connected",b=t?.videoAcceleration,y=a||b?.busy||b?.state==="installing",C=b?.ready?`${b.encoder||"H.264"} · ${b.driver||"VAAPI"}`:y?"Setting up…":b?.message||"Setup available",A=t?.system?.memoryTotalBytes?Number(t.system.memoryUsedBytes||0)/t.system.memoryTotalBytes*100:0,k=t?.system?.gpus||[],R=k.find($=>Number.isFinite($.usagePercent)||Number.isFinite($.memoryTotalBytes))||k[0],_=Number.isFinite(R?.usagePercent)?Number(R?.usagePercent):null,E=Number.isFinite(R?.memoryTotalBytes)&&Number(R?.memoryTotalBytes)>0&&Number.isFinite(R?.memoryUsedBytes)?Number(R?.memoryUsedBytes)/Number(R?.memoryTotalBytes)*100:null,L=t?.system?.disks||[],M=t?.system?.network,U=!!M?.sampledAt,V=M?.interfaces||[],T=[...new Set(V.map($=>$.name).filter(Boolean))],j=V.map($=>$.address).filter(Boolean);return r.jsxs("section",{className:"client-home-page",children:[r.jsxs("header",{className:"client-home-heading",children:[r.jsxs("div",{children:[r.jsx("p",{className:"client-unified-eyebrow",children:"THIS COMPUTER"}),r.jsx("h2",{children:t?.deviceName||"This Computer"})]}),r.jsxs("span",{className:`client-unified-role-chip ${w?"connected":""}`,children:[r.jsx(dn,{size:15})," ",w?"Online":"Connecting"]})]}),r.jsxs("div",{className:"client-home-layout",children:[r.jsxs("section",{className:"client-main-surface","aria-label":"Client computer",children:[r.jsxs("div",{className:"client-main-surface-head",children:[r.jsxs("div",{children:[r.jsx("span",{className:"client-unified-section-label",children:"SYSTEM STATUS"}),r.jsx("strong",{children:"Hardware at a glance"})]}),r.jsxs("small",{children:[r.jsx(Mv,{size:14})," Uptime ",jS(t?.system?.uptimeSeconds)]})]}),r.jsxs("div",{className:"client-system-dashboard",children:[r.jsxs("section",{className:"client-performance-panel","aria-label":"Performance",children:[r.jsxs("div",{className:"client-system-subhead",children:[r.jsxs("div",{children:[r.jsx("span",{className:"client-unified-section-label",children:"PERFORMANCE"}),r.jsx("strong",{children:"Live resources"})]}),r.jsx("small",{children:"Live updates"})]}),r.jsxs("div",{className:"client-live-metrics",children:[r.jsx(Ml,{icon:qf,label:"CPU",value:hp(t?.system?.cpuUsagePercent),detail:t?.system?.cpuLogicalCores?`${t.system.cpuLogicalCores} logical cores · Current processor usage`:"Current processor usage",percent:t?.system?.cpuUsagePercent}),r.jsx(Ml,{icon:ox,label:"Memory",value:hp(A),detail:IS(t?.system?.memoryUsedBytes,t?.system?.memoryTotalBytes),percent:A}),r.jsx(Ml,{icon:ix,label:"GPU",value:Nd(_),detail:R?.name||(t?.system?.hardwareCollecting?"Detecting graphics hardware…":"Graphics usage unavailable"),percent:_}),r.jsx(Ml,{icon:ls,label:"VRAM",value:Nd(E),detail:PS(R?.memoryUsedBytes,R?.memoryTotalBytes),percent:E})]})]}),r.jsxs("section",{className:"client-storage-panel","aria-label":"Local storage",children:[r.jsxs("div",{className:"client-system-subhead",children:[r.jsxs("div",{children:[r.jsx("span",{className:"client-unified-section-label",children:"STORAGE"}),r.jsx("strong",{children:"Local drives"})]}),r.jsx("small",{children:L.length>0?`${L.length} ${L.length===1?"drive":"drives"}`:t?.system?.hardwareCollecting?"Detecting…":"Unavailable"})]}),r.jsxs("div",{className:"client-disk-list",children:[L.map($=>r.jsxs("article",{className:"client-disk-row",children:[r.jsxs("div",{className:"client-disk-row-head",children:[r.jsxs("span",{children:[r.jsx(qa,{size:16}),r.jsx("strong",{children:$.mount||"Disk"}),r.jsx("small",{children:$.name||"Local disk"})]}),r.jsx("strong",{children:Nd($.usedPercent)})]}),r.jsxs("small",{children:[Ua($.freeBytes)," free · ",Ua($.totalBytes)," total"]}),r.jsx("i",{"aria-hidden":"true",children:r.jsx("b",{style:{width:Vv($.usedPercent)}})})]},`${$.mount}-${$.name||""}`)),L.length===0&&r.jsxs("div",{className:"client-disk-empty",children:[r.jsx(qa,{size:18}),r.jsx("span",{children:t?.system?.hardwareCollecting?"Detecting local drives…":"Storage information is not available."})]})]})]}),r.jsxs("section",{className:"client-network-panel","aria-label":"Network activity",children:[r.jsxs("div",{className:"client-system-subhead",children:[r.jsxs("div",{children:[r.jsx("span",{className:"client-unified-section-label",children:"NETWORK"}),r.jsx("strong",{children:"Live traffic"})]}),r.jsx("small",{children:T.length>0?T.join(", "):"Detecting adapter"})]}),r.jsxs("div",{className:"client-network-live",children:[r.jsxs("div",{className:"client-network-adapter",children:[r.jsx(yu,{size:18}),r.jsxs("span",{children:[r.jsx("strong",{children:T.join(", ")||"Network"}),r.jsx("small",{children:j.join(" / ")||"Checking active connection"})]})]}),r.jsxs("div",{className:"client-network-rate download",children:[r.jsx(cx,{size:17}),r.jsxs("span",{children:[r.jsx("small",{children:"Receive"}),r.jsx("strong",{children:rh(U?M?.receiveBytesPerSecond:void 0)})]})]}),r.jsxs("div",{className:"client-network-rate upload",children:[r.jsx(lx,{size:17}),r.jsxs("span",{children:[r.jsx("small",{children:"Send"}),r.jsx("strong",{children:rh(U?M?.sendBytesPerSecond:void 0)})]})]}),r.jsx("small",{className:"client-network-total",children:U?`Total ${Ua(M?.receivedBytes)} received / ${Ua(M?.sentBytes)} sent`:"Traffic has not been measured yet."})]})]})]})]}),r.jsxs("aside",{className:"client-connection-panel",children:[r.jsx("span",{className:"client-unified-section-label",children:"LIVEDESK SERVICES"}),r.jsx("h3",{children:w?"Connected to the Hub":t?.authenticated?"Finding the Hub":"Connect this computer"}),w?r.jsxs(r.Fragment,{children:[r.jsx("p",{className:"client-unified-copy",children:"This computer is available from the VuvoDesk Hub."}),r.jsxs("div",{className:"client-service-status-list",children:[r.jsxs("div",{children:[r.jsx(dn,{size:17}),r.jsxs("span",{children:[r.jsx("strong",{children:"Screen sharing"}),r.jsx("small",{children:t?.permissions?.screenCapture?"Active":"Waiting"})]})]}),r.jsxs("div",{children:[r.jsx(sn,{size:17}),r.jsxs("span",{children:[r.jsx("strong",{children:"Remote control"}),r.jsx("small",{children:t?.permissions?.remoteInput?"Available":"Unavailable"})]})]}),r.jsxs("div",{children:[r.jsx(ai,{size:17}),r.jsxs("span",{children:[r.jsx("strong",{children:"File delivery"}),r.jsx("small",{children:t?.permissions?.files?"Ready to receive":"Unavailable"})]})]}),r.jsxs("div",{children:[r.jsx(sc,{size:17}),r.jsxs("span",{children:[r.jsx("strong",{children:"Computer audio"}),r.jsx("small",{children:t?.permissions?.audio?"Available":"Unavailable"})]})]})]})]}):r.jsxs(r.Fragment,{children:[r.jsx("p",{className:"client-unified-copy",children:t?.authenticated?"VuvoDesk is checking the registered Hub endpoints. A temporary Hub PIN can be used as a fallback.":"Sign in once on this computer. VuvoDesk saves the verified session, finds the Hub, and starts screen sharing automatically."}),!e&&!t?.authenticated?r.jsxs("button",{className:"client-unified-primary",type:"button",onClick:u,children:[r.jsx(is,{size:16})," Sign in with Google"]}):r.jsxs("p",{className:"client-unified-success",children:[r.jsx(Fn,{size:16})," Signed in as ",e?.user.email||e?.user.id||t?.userEmail||t?.userId||"saved account"]}),r.jsxs("div",{className:"client-unified-pin-row",children:[r.jsx(ux,{size:16}),r.jsx("input",{value:n,onChange:$=>d($.target.value),placeholder:"6-digit Hub PIN",inputMode:"numeric","aria-label":"6-digit Hub PIN"}),r.jsx("button",{className:"client-unified-secondary",type:"button",onClick:p,disabled:n.length!==6,children:"Connect"})]})]}),b?.supported&&r.jsxs("div",{className:`client-video-acceleration state-${b.ready?"ready":b.state||"setup-required"}`,children:[r.jsx(qf,{size:17}),r.jsxs("span",{children:[r.jsx("strong",{children:"Hardware video"}),r.jsx("small",{children:C})]}),!b.ready&&b.canInstall&&r.jsx("button",{type:"button",onClick:g,disabled:y,title:"Install and verify Linux FFmpeg hardware video support",children:y?"Setting up":"Enable"})]}),s&&r.jsx("p",{className:"client-unified-success",children:s}),r.jsxs("div",{className:"client-slot-setting",children:[r.jsxs("label",{htmlFor:"client-slot-number",children:[r.jsx("span",{children:"Slot"}),r.jsx("input",{id:"client-slot-number",value:o,onChange:$=>f($.target.value),inputMode:"numeric",pattern:"[0-9]*",placeholder:"1-999","aria-label":"Wall slot number",disabled:!w||c})]}),r.jsxs("button",{type:"button",onClick:m,disabled:!w||c||!o,"aria-label":"Save slot number",title:"Save slot number",children:[r.jsx(au,{size:17}),r.jsx("span",{children:c?"Saving":"Set"})]})]})]})]})]})}function LS({runtimeBaseUrl:e=""}){const[t,n]=i.useState(null),[s,a]=i.useState(null),[o,c]=i.useState(!1),[u,d]=i.useState(""),[p,f]=i.useState(""),[m,g]=i.useState(null),[w,b]=i.useState(null),[y,C]=i.useState(""),[A,k]=i.useState(!1),[R,_]=i.useState(!1),[E,L]=i.useState(""),[M,U]=i.useState(!1),[V,T]=i.useState(null),[j,$]=i.useState(!1),[Q,G]=i.useState("computer"),[q,re]=i.useState(!1),I=i.useRef(null),X=i.useRef(null),le=i.useRef(!1),K=i.useRef(null),ue=i.useRef(null),se=i.useRef(!1),ve=i.useRef(!1),Me=i.useRef(0),Te=i.useRef(!1),ke=i.useRef(""),pe=i.useMemo(()=>TS(e),[e]),J=i.useMemo(()=>ES(s,t),[s,t]),Ie=i.useMemo(()=>FS(s,t),[s,t]),_e=JSON.stringify(Ie),[De,Xe]=i.useState(()=>new Set),ne=xS(Ie,De),ae=J.slice(0,1).toUpperCase()||"L";i.useEffect(()=>{Xe(new Set)},[_e]);const me=i.useCallback(D=>{Xe(Y=>{if(!D||Y.has(D))return Y;const ie=new Set(Y);return ie.add(D),ie})},[]),oe=i.useCallback(async()=>{if(f(""),window.liveDesk?.auth?.signInWithGoogle){const D=await window.liveDesk.auth.signInWithGoogle();return D?.ok===!1?(f(D.error||"VuvoDesk could not open the system browser for Google sign-in."),!1):!0}return window.location.assign(`${pe}/auth/google`),!0},[pe]),ee=i.useCallback(async()=>{ve.current||(ve.current=!0,f("Your saved Google sign-in is incomplete. VuvoDesk is reopening sign-in once to repair it."),await mt.auth.signOut({scope:"local"}).catch(()=>{}),a(null),await oe()||(ve.current=!1))},[oe]),Se=i.useCallback(async D=>{const Y=Zf(D);if(Y)throw new Error(Y);if(le.current)return!1;le.current=!0;try{if(window.liveDesk?.auth?.persistSession){const ie=await window.liveDesk.auth.persistSession(D);if(ie?.ok===!1)throw new Error(ie.error||"VuvoDesk could not validate the desktop session.");return f(""),!0}for(let ie=0;ie<2;ie+=1){const Re=await Oa(pe,ie>0),P=await fetch(`${pe}/api/auth/session`,{method:"POST",headers:{"Content-Type":"application/json","X-LiveDesk-CSRF":Re},signal:AbortSignal.timeout(1e4),body:JSON.stringify({accessToken:D.access_token,refreshToken:D.refresh_token,expiresAt:D.expires_at,user:{id:D.user.id,email:D.user.email}})}),ce=await P.json().catch(()=>({}));if(P.status===403&&ie===0){sessionStorage.removeItem("livedesk.client.csrf");continue}if(!P.ok)throw new Error(ce.error||`Client runtime returned HTTP ${P.status}.`);return f(""),!0}throw new Error("Client runtime rejected the session transfer.")}finally{le.current=!1}},[pe]),de=i.useCallback(()=>{const D=K.current;if(D)return D;const Y=(async()=>{try{const ie=await fetch(`${pe}/api/client/status`,{cache:"no-store",signal:AbortSignal.timeout(1500)}),Re=await ie.json().catch(()=>({}));if(!ie.ok)throw new Error(Re.error||`Client runtime returned HTTP ${ie.status}.`);if(Re.csrfToken&&sessionStorage.setItem("livedesk.client.csrf",Re.csrfToken),String(Re.role||"").toLowerCase()==="hub")throw new Error("This computer is assigned to the Hub role.");n(Re),g(null),b(null)}catch(ie){g(th(ie))}})();return K.current=Y,Y.finally(()=>{K.current===Y&&(K.current=null)}),Y},[pe]),Fe=i.useCallback(()=>{const D=ue.current;if(D)return D;const Y=(async()=>{const ie=await fetch(`${pe}/api/client/diagnostics`,{cache:"no-store",signal:AbortSignal.timeout(8e3)}),Re=await ie.json().catch(()=>({}));if(!ie.ok)throw new Error(Re.error||`Client diagnostics returned HTTP ${ie.status}.`);if(String(Re.role||"").toLowerCase()==="hub")throw new Error("This computer is assigned to the Hub role.");n(Re)})();return ue.current=Y,Y.finally(()=>{ue.current===Y&&(ue.current=null)}),Y},[pe]);i.useEffect(()=>{let D=!1,Y=null;const ie=async()=>{await de(),D||(Y=window.setTimeout(()=>{ie()},2e3))};return ie(),()=>{D=!0,Y!==null&&window.clearTimeout(Y)}},[de]),i.useEffect(()=>{if(Q!=="computer")return;let D=!1,Y=null;const ie=()=>{D||(Y=window.setTimeout(()=>{Re()},NS))},Re=async()=>{document.visibilityState==="visible"&&await Fe().catch(()=>{}),ie()},P=()=>{document.visibilityState==="visible"&&(Y!==null&&(window.clearTimeout(Y),Y=null),Re())};return document.addEventListener("visibilitychange",P),Re(),()=>{D=!0,document.removeEventListener("visibilitychange",P),Y!==null&&window.clearTimeout(Y)}},[Q,Fe]),i.useEffect(()=>{if(Te.current)return;const D=Number(t?.slotNumber||0);L(D>0?String(D):"")},[t?.slotNumber]),i.useEffect(()=>{if(!V)return;const D=window.setTimeout(()=>T(null),5e3);return()=>window.clearTimeout(D)},[V]),i.useEffect(()=>{const D=MS({actionError:p,discoveryWakeError:w,statusPollError:m,runtimeError:t?.lastError}),Y=AS(ke.current,D);ke.current=Y.nextKey,Y.message&&T({kind:"error",message:Y.message})},[w,p,m,t?.lastError]);const qe=i.useCallback(async()=>{const D=Date.now();if(!(!t?.authenticated||t.connectionState==="connected"||!["waiting","reconnecting"].includes(String(t.agent?.state||""))||D-Me.current<4e3)){Me.current=D;try{const Y=await fetch(`${pe}/api/client/reconnect`,{method:"POST",headers:{"Content-Type":"application/json","X-LiveDesk-CSRF":await Oa(pe)},body:JSON.stringify({onlyIfWaiting:!0,reason:"app-active"})});if(!Y.ok)throw new Error(`Client reconnect returned HTTP ${Y.status}.`);b(null),await de()}catch(Y){b(th(Y))}}},[pe,de,t]);i.useEffect(()=>{const D=()=>{qe()},Y=()=>{qe()},ie=()=>{document.visibilityState==="visible"&&qe()};return window.addEventListener("online",D),window.addEventListener("focus",Y),document.addEventListener("visibilitychange",ie),()=>{window.removeEventListener("online",D),window.removeEventListener("focus",Y),document.removeEventListener("visibilitychange",ie)}},[qe]),i.useEffect(()=>{if(!o||!t||!s?.access_token||t.authenticated)return;if(Zf(s)==="refresh-token-required"){ee().catch(P=>{ve.current=!1,f(P instanceof Error?P.message:String(P))});return}let D=!1,Y,ie=0;const Re=async()=>{if(D)return;try{const ce=await Se(s);if(await de(),ce)return}catch(ce){f(ce instanceof Error?ce.message:String(ce))}if(D)return;const P=nh[Math.min(ie,nh.length-1)];ie+=1,Y=window.setTimeout(()=>{Re()},P)};return Re(),()=>{D=!0,Y!==void 0&&window.clearTimeout(Y)}},[o,de,ee,s,t,Se]),i.useEffect(()=>{const D=new URLSearchParams(window.location.search),Y=D.get("auth_error");if(!Y)return;f(Y),D.delete("auth_error");const ie=D.toString();window.history.replaceState(window.history.state,"",`${window.location.pathname}${ie?`?${ie}`:""}${window.location.hash}`)},[]),i.useEffect(()=>{let D=!0;if(!window.liveDesk?.auth)return a(null),c(!0),de(),()=>{D=!1};const Y=window.liveDesk?.auth?.onComplete?.(Re=>{Re.ok&&Re.session?mt.auth.setSession(Re.session).catch(P=>f(P instanceof Error?P.message:String(P))):Re.ok&&Re.signedOut?(a(null),c(!0),mt.auth.signOut({scope:"local"})):Re.error&&f(Re.error)});(async()=>{try{const Re=window.liveDesk?.auth?.getSession?await window.liveDesk.auth.getSession():await mt.auth.getSession();if(!D)return;const P=$v(Re);a(P),de()}catch(Re){D&&f(Re instanceof Error?Re.message:String(Re))}finally{D&&c(!0)}})();const{data:ie}=mt.auth.onAuthStateChange((Re,P)=>{if(D){if(!P&&window.liveDesk?.auth){c(!0);return}a(P),c(!0),de()}});return()=>{D=!1,Y?.(),ie.subscription.unsubscribe()}},[de]),i.useEffect(()=>{if(!o||!t||se.current||ve.current||s||t.authenticated)return;const D=new URLSearchParams(window.location.search);if(!D.has("livedesk_launch"))return;se.current=!0,D.delete("livedesk_launch");const Y=D.toString();window.history.replaceState(window.history.state,"",`${window.location.pathname}${Y?`?${Y}`:""}${window.location.hash}`),oe().catch(ie=>f(ie instanceof Error?ie.message:String(ie)))},[o,s,oe,t]);const N=async()=>{re(!1),window.liveDesk?.auth?.signOut?(await mt.auth.signOut({scope:"local"}),(await window.liveDesk.auth.signOut())?.runtimeCleared===!1&&f("Signed out locally. The VuvoDesk runtime could not be reached to clear its session.")):await fetch(`${pe}/api/auth/session`,{method:"DELETE",headers:{"X-LiveDesk-CSRF":await Oa(pe)}}).catch(()=>{}),a(null),await de()};i.useEffect(()=>{if(!q)return;const D=ie=>{ie.target instanceof Element&&ie.target.closest(".account-popover, .rail-account")||re(!1)},Y=ie=>{ie.key==="Escape"&&re(!1)};return window.addEventListener("pointerdown",D),window.addEventListener("keydown",Y),()=>{window.removeEventListener("pointerdown",D),window.removeEventListener("keydown",Y)}},[q]);const we=i.useCallback((D=!0)=>{A||($(!1),D&&window.requestAnimationFrame(()=>X.current?.focus()))},[A]),Le=i.useCallback(()=>{A||!t?.authenticated||(X.current=document.activeElement instanceof HTMLElement?document.activeElement:null,C(""),$(!0))},[A,t?.authenticated]);i.useEffect(()=>{if(!j)return;const D=window.requestAnimationFrame(()=>I.current?.focus()),Y=Re=>{Re.target instanceof Element&&Re.target.closest(".client-hub-switch-popover, .client-hub-switch-trigger")||we(!1)},ie=Re=>{Re.key==="Escape"&&we()};return window.addEventListener("pointerdown",Y),window.addEventListener("keydown",ie),()=>{window.cancelAnimationFrame(D),window.removeEventListener("pointerdown",Y),window.removeEventListener("keydown",ie)}},[we,j]);const Je=async()=>{f("");try{const D=await fetch(`${pe}/api/client/pin`,{method:"POST",headers:{"Content-Type":"application/json","X-LiveDesk-CSRF":await Oa(pe)},body:JSON.stringify({pin:u})}),Y=await D.json().catch(()=>({}));if(!D.ok||Y?.ok===!1)throw new Error(Y?.error||"PIN could not be accepted.");d(""),await de()}catch(D){f(D instanceof Error?D.message:String(D))}},Oe=async()=>{$(!1),k(!0),C(""),f("");try{const D=await fetch(`${pe}/api/runtime/switch-role`,{method:"POST",headers:{"Content-Type":"application/json","X-LiveDesk-CSRF":await Oa(pe)},body:JSON.stringify({role:"hub"})}),Y=await D.json().catch(()=>({}));if(!D.ok||Y?.ok===!1)throw new Error(Y?.error||`Role change failed with HTTP ${D.status}.`);C("Hub role accepted. VuvoDesk is restarting this computer with the Hub Wall.");const ie=Number(t?.runtimePid||0);await wv({baseUrl:pe,targetRole:"hub",previousRuntimePid:ie,allowedStates:["running"]}),window.location.reload()}catch(D){f(D instanceof Error?D.message:String(D)),k(!1)}},$e=async()=>{if(M)return;const D=Number(E);if(!Number.isInteger(D)||D<1||D>999){T({kind:"error",message:"Enter a slot number from 1 to 999."});return}U(!0),T(null);try{const Y=await fetch(`${pe}/api/client/slot`,{method:"POST",headers:{"Content-Type":"application/json","X-LiveDesk-CSRF":await Oa(pe)},body:JSON.stringify({slotNumber:D})}),ie=await Y.json().catch(()=>({}));if(!Y.ok||ie.ok===!1){if(ie.error==="slot-taken"){const Re=ie.conflict?.deviceName||ie.conflict?.hostname||ie.conflict?.deviceId||"another computer";throw new Error(`Slot ${String(D).padStart(3,"0")} is already used by ${Re}.`)}throw new Error(ie.error||`Slot update failed with HTTP ${Y.status}.`)}Te.current=!1,L(String(D)),n(ie),T({kind:"success",message:`Slot ${String(D).padStart(3,"0")} saved. VuvoDesk is reconnecting this Client.`})}catch(Y){T({kind:"error",message:Y instanceof Error?Y.message:String(Y)})}finally{U(!1),await de()}},ft=async()=>{if(!R){_(!0),f("");try{const D=await fetch(`${pe}/api/client/video-acceleration/install`,{method:"POST",headers:{"Content-Type":"application/json","X-LiveDesk-CSRF":await Oa(pe)},body:JSON.stringify({confirm:!0})}),Y=await D.json().catch(()=>({}));if(n(Y),!D.ok||Y.videoAcceleration?.ready!==!0)throw new Error(Y.videoAcceleration?.error||Y.error||"Linux hardware video setup did not complete.")}catch(D){f(D instanceof Error?D.message:String(D))}finally{_(!1),await de()}}},rt=!!(t?.authenticated||s),ge=i.useMemo(()=>Su(),[]),ct=ou("switch-to-hub",ge),fe=ou("client",ge),Z=bS(ge);return r.jsxs("main",{className:"app-shell client-unified-shell",children:[r.jsxs("aside",{className:"tool-rail","aria-label":"VuvoDesk Client tools",children:[r.jsx("div",{className:"rail-brand",title:"VuvoDesk",children:r.jsx(op,{size:25})}),r.jsx("nav",{className:"rail-tools","aria-label":"Client navigation",children:r.jsxs("div",{className:"client-main-tool-slot",children:[r.jsxs("button",{className:"rail-tool client-main-tool client-hub-tool client-hub-switch-trigger accent-blue",type:"button",onClick:Le,disabled:A||!t?.authenticated,"aria-busy":A,"aria-expanded":j,"aria-haspopup":"dialog","aria-controls":j?"client-hub-switch-popover":void 0,"aria-label":`Hub. ${ct}`,"data-tooltip":j?void 0:mp("Hub","switch-to-hub",ge),children:[r.jsx(ls,{size:19}),r.jsx("span",{children:A?"Switching…":"Hub"})]}),r.jsxs("button",{className:`rail-tool client-main-tool accent-blue ${Q==="computer"?"active":""}`,type:"button",onClick:()=>G("computer"),"aria-current":Q==="computer"?"page":void 0,"aria-label":`Client. ${fe}`,"data-tooltip":mp("Client","client",ge),children:[r.jsx(dn,{size:19}),r.jsx("span",{children:"Client"})]})]})}),r.jsxs("div",{className:"rail-footer",children:[RS.map(D=>{const Y=D.icon;return r.jsxs("button",{className:`rail-tool compact ${Q===D.id?"active":""}`,type:"button",onClick:()=>G(D.id),title:D.label,children:[r.jsx(Y,{size:18}),r.jsx("span",{children:D.label})]},D.id)}),r.jsxs("button",{className:`rail-account ${rt?"signed-in":""}`,type:"button",onClick:()=>re(D=>!D),"aria-expanded":q,"aria-haspopup":"dialog",title:rt?"Account":"Sign in",children:[rt&&ne?r.jsx("img",{src:ne,alt:J,referrerPolicy:"no-referrer",onError:()=>me(ne)},ne):rt?r.jsx("span",{className:"avatar-fallback",children:ae}):r.jsx(is,{size:18}),r.jsx("span",{children:rt?"Account":"Sign in"})]})]})]}),j&&r.jsxs("section",{id:"client-hub-switch-popover",className:"client-hub-switch-popover",role:"dialog","aria-modal":"false","aria-labelledby":"client-hub-switch-title","aria-describedby":"client-hub-switch-description client-hub-switch-restart",children:[r.jsxs("header",{className:"client-hub-switch-head",children:[r.jsx("span",{className:"client-hub-switch-mark","aria-hidden":"true",children:r.jsx(ls,{size:19})}),r.jsx("span",{className:"client-hub-switch-eyebrow",children:Z.eyebrow}),r.jsx("button",{className:"client-hub-switch-close",type:"button",onClick:()=>we(),"aria-label":Z.closeLabel,children:r.jsx(Sn,{size:17})})]}),r.jsx("h2",{id:"client-hub-switch-title",children:Z.title}),r.jsx("p",{id:"client-hub-switch-description",children:Z.description}),r.jsxs("p",{id:"client-hub-switch-restart",className:"client-hub-switch-notice",children:[r.jsx(sn,{size:16,"aria-hidden":"true"}),r.jsx("span",{children:Z.restartNotice})]}),r.jsxs("div",{className:"client-hub-switch-actions",children:[r.jsx("button",{type:"button",onClick:()=>we(),children:Z.cancel}),r.jsxs("button",{ref:I,className:"primary",type:"button",onClick:()=>{Oe()},disabled:A||!t?.authenticated,children:[r.jsx(ls,{size:16}),Z.confirm]})]})]}),q&&r.jsxs("section",{className:"account-popover",role:"dialog","aria-label":"VuvoDesk account",children:[r.jsxs("div",{className:"account-popover-head",children:[r.jsx("div",{className:"account-popover-avatar",children:rt&&ne?r.jsx("img",{src:ne,alt:J,referrerPolicy:"no-referrer",onError:()=>me(ne)},ne):rt?r.jsx("span",{children:ae}):r.jsx(is,{size:18})}),r.jsxs("div",{children:[r.jsx("strong",{children:rt?J:"Account"}),r.jsx("p",{children:s?.user.email||t?.userEmail||t?.userId||"Not signed in"})]})]}),r.jsxs("dl",{className:"account-popover-facts",children:[r.jsx("dt",{children:"User"}),r.jsx("dd",{children:s?.user.email||t?.userEmail||t?.userId||"Not signed in"}),r.jsx("dt",{children:"Runtime"}),r.jsx("dd",{children:t?"Local app ready":"Checking local app"}),r.jsx("dt",{children:"Session"}),r.jsx("dd",{children:t?.auth?.persisted?"Saved on this computer":rt?"Active for this run":"Not saved"}),r.jsx("dt",{children:"Role"}),r.jsx("dd",{children:"Client"})]}),rt?r.jsxs("button",{className:"account-popover-action",onClick:()=>{N()},type:"button",children:[r.jsx(cp,{size:16}),"Logout"]}):r.jsxs("button",{className:"account-popover-action primary",onClick:()=>{re(!1),oe()},type:"button",children:[r.jsx(is,{size:16}),"Sign in with Google"]})]}),r.jsx("section",{className:"desk-stage client-unified-stage",children:Q==="support"?r.jsx("section",{className:"client-unified-page",children:r.jsx(Lv,{session:s,currentProductKey:"livedesk",appVersion:t?.appVersion||"",onSignIn:()=>{oe()}})}):Q!=="computer"?r.jsx("section",{className:"client-unified-page",children:r.jsx(DS,{page:Q,status:t})}):r.jsx(_S,{session:s,status:t,pin:u,roleChangeMessage:y,videoAccelerationBusy:R,slotInput:E,slotBusy:M,onSignIn:()=>{oe()},onPinChange:D=>d(D.replace(/\D/g,"").slice(0,6)),onSubmitPin:()=>{Je()},onSlotInputChange:D=>{Te.current=!0,L(D.replace(/\D/g,"").slice(0,3))},onSaveSlot:()=>{$e()},onEnableVideoAcceleration:()=>{ft()}})}),V&&r.jsxs("div",{className:`client-side-toast ${V.kind}`,role:V.kind==="error"?"alert":"status",children:[V.kind==="error"?r.jsx(ax,{size:18}):r.jsx(Fn,{size:18}),r.jsx("span",{children:V.message}),r.jsx("button",{type:"button",onClick:()=>T(null),"aria-label":"Dismiss notification",children:r.jsx(Sn,{size:16})})]})]})}function Ys(e,t,n){if(n<0||t<0||t+n>e.length)throw new Error("Invalid LZO1X block: input overrun.")}function Td(e,t,n){let s=0;for(;Ys(e,t.inputIndex,1),e[t.inputIndex]===0;)s+=1,t.inputIndex+=1;const a=s*255+n+e[t.inputIndex];return t.inputIndex+=1,a}function Al(e,t,n,s){if(Ys(e,t.inputIndex,s),t.outputIndex+s>n.length)throw new Error("Invalid LZO1X block: output overrun.");n.set(e.subarray(t.inputIndex,t.inputIndex+s),t.outputIndex),t.inputIndex+=s,t.outputIndex+=s}function OS(e,t,n,s){const a=t-n;if(a<=0||s<=0)throw new Error("Invalid LZO1X block: invalid match distance.");let o=Math.min(a,s);for(e.set(e.subarray(n,n+o),t);o<s;){const c=Math.min(o,s-o);e.copyWithin(t+o,t,t+c),o+=c}return t+s}function qv(e,t){if(!(e instanceof Uint8Array)||e.length<3||t<0)throw new Error("Invalid LZO1X block.");const n=new Uint8Array(t),s={inputIndex:0,outputIndex:0};let a=0,o=0;if(e[s.inputIndex]>=22){const c=e[s.inputIndex]-17;s.inputIndex+=1,Al(e,s,n,c),a=4}else e[s.inputIndex]>=18&&(a=e[s.inputIndex]-17,s.inputIndex+=1,Al(e,s,n,a));for(;;){Ys(e,s.inputIndex,1);const c=e[s.inputIndex];s.inputIndex+=1;let u,d;if((c&192)!==0)Ys(e,s.inputIndex,1),d=s.outputIndex-((e[s.inputIndex]<<3)+(c>>2&7)+1),s.inputIndex+=1,o=(c>>5)+1,u=c&3;else if((c&32)!==0){o=(c&31)+2,o===2&&(o+=Td(e,s,31)),Ys(e,s.inputIndex,2);const p=e[s.inputIndex]|e[s.inputIndex+1]<<8;s.inputIndex+=2,d=s.outputIndex-((p>>2)+1),u=p&3}else if((c&16)!==0){o=(c&7)+2,o===2&&(o+=Td(e,s,7)),Ys(e,s.inputIndex,2);const p=e[s.inputIndex]|e[s.inputIndex+1]<<8;if(s.inputIndex+=2,d=s.outputIndex-(((c&8)<<11)+(p>>2)),u=p&3,d===s.outputIndex)break;d-=16384}else if(a===0){let p=c+3;p===3&&(p+=Td(e,s,15)),Al(e,s,n,p),a=4;continue}else a!==4?(Ys(e,s.inputIndex,1),u=c&3,d=s.outputIndex-((c>>2)+(e[s.inputIndex]<<2)+1),s.inputIndex+=1,o=2):(Ys(e,s.inputIndex,1),u=c&3,d=s.outputIndex-((c>>2)+(e[s.inputIndex]<<2)+2049),s.inputIndex+=1,o=3);if(d<0||s.outputIndex+o+u>n.length)throw new Error("Invalid LZO1X block: lookbehind overrun.");s.outputIndex=OS(n,s.outputIndex,d,o),a=u,Al(e,s,n,u)}if(o!==3||s.inputIndex!==e.length||s.outputIndex!==n.length)throw new Error("Invalid LZO1X block: incomplete output.");return n}const sh=16,ah=8,$S=24*1024*1024,Uv=new Uint8Array(new Uint32Array([16909060]).buffer)[0]===4,gp=new Uint32Array(65536);for(let e=0;e<gp.length;e+=1){const t=Math.round((e>>11&31)*255/31),n=Math.round((e>>5&63)*255/63),s=Math.round((e&31)*255/31);gp[e]=Uv?(t|n<<8|s<<16|4278190080)>>>0:(t<<24|n<<16|s<<8|255)>>>0}function Us(e,t){return e[t]|e[t+1]<<8}function BS(e,t){const n=Number(t);if(!Number.isSafeInteger(n)||n<sh||n>$S)throw new Error(`Invalid Mode 5 packet length: ${t}.`);const s=e instanceof Uint8Array?e:new Uint8Array(e),a=qv(s,n);if(a[0]!==76||a[1]!==68||a[2]!==53||a[3]!==68)throw new Error("Invalid Mode 5 packet magic.");if(a[4]!==1)throw new Error(`Unsupported Mode 5 packet version: ${a[4]}.`);const o=(a[5]&1)!==0,c=Us(a,6),u=Us(a,8),d=Us(a,10),p=Us(a,12);if(c<=0||u<=0||c>3840||u>2160)throw new Error(`Invalid Mode 5 frame size: ${c}x${u}.`);if(d<=0||d>256||p>8192)throw new Error(`Invalid Mode 5 tile header: ${d}/${p}.`);const f=[];let m=sh;for(let g=0;g<p;g+=1){if(m+ah>a.length)throw new Error("Mode 5 tile header is truncated.");const w=Us(a,m),b=Us(a,m+2),y=Us(a,m+4),C=Us(a,m+6);m+=ah;const A=y*C*2;if(y<=0||C<=0||y>d||C>d||w+y>c||b+C>u||m+A>a.length)throw new Error(`Invalid Mode 5 tile ${g}.`);f.push({x:w,y:b,width:y,height:C,pixels:a.subarray(m,m+A)}),m+=A}if(m!==a.length)throw new Error(`Mode 5 packet has ${a.length-m} trailing bytes.`);return{keyFrame:o,width:c,height:u,tileSize:d,tiles:f}}function HS(e,t,n,s){if(!(e instanceof Uint8ClampedArray)||e.length!==t*n*4||s.width!==t||s.height!==n)throw new Error("Mode 5 canvas state does not match the packet dimensions.");let a=t,o=n,c=0,u=0;const d=new Uint32Array(e.buffer,e.byteOffset,e.byteLength>>>2);for(const p of s.tiles){const f=Uv&&(p.pixels.byteOffset&1)===0?new Uint16Array(p.pixels.buffer,p.pixels.byteOffset,p.pixels.byteLength>>>1):null;let m=0;for(let g=0;g<p.height;g+=1){let w=(p.y+g)*t+p.x;for(let b=0;b<p.width;b+=1){const y=m<<1,C=f?f[m]:p.pixels[y]|p.pixels[y+1]<<8;d[w]=gp[C],m+=1,w+=1}}a=Math.min(a,p.x),o=Math.min(o,p.y),c=Math.max(c,p.x+p.width),u=Math.max(u,p.y+p.height)}return s.tiles.length>0?{x:a,y:o,width:c-a,height:u-o}:null}function WS(e){if(!e)return!0;const t=Kt.get(e);return!t||t.hardwareAcceleration==="prefer-hardware"}const Kt=new WeakMap,oh=854,ih=480,zS=3840,VS=2160,qS=500,pc=new WeakMap,vp=new WeakMap,Ja=new Set,Ga=new Set,ra=new WeakMap,Ka=new Set,li=new WeakMap,bp=new WeakMap,wp=new WeakMap,iu=new WeakMap,Gv=4,US=2,ri=4,GS=2,KS=2,QS=18,YS=0,XS=250,Kv=80,JS=5,ZS=150,eC=1200,tC=18,nC=.65,Qv=80,Yv=125,rC=4,sC=2*1024*1024,aC=8,oC=16,iC=180,cC=3,Vp=2e3,Xv=64,Jv=32*1024*1024,lC=500,uC=25,dC=45,pC=20,Zv=new Uint8Array(0),qp=250,mC=globalThis.LIVEDESK_ENABLE_CANVAS_VISUAL_SAMPLING===!0;let eb=1,tb=0,nb=0,yp=0,rb=0;const Ji=[];let gc=0,sb=0,ab,ob=0,ib,cb;function vc(e,t){Ji.push({sequence:++rb,type:e,canvasId:li.get(t)||0,observedAt:Date.now(),activeDecoderCount:Ja.size,hardwareLeaseCount:Ga.size,hardwareReleaseGeneration:gc}),Ji.length>256&&Ji.splice(0,Ji.length-256)}let Is={h264DecodeAcceleration:"prefer-hardware"};function fC(e){e.h264DecodeAcceleration&&(Is={...Is,h264DecodeAcceleration:e.h264DecodeAcceleration})}function hC(e){return e.payload.byteLength===0?e:{...e,payload:Zv}}function lb(e,t){const n=String(e.streamPurpose||"").trim().toLowerCase();return n==="wall"?!0:n==="control"?!1:t>=45e3}function ub(e){try{return e.paintIsCancelled()}catch{return!0}}function Cu(e,t){const n=e.pendingFrames.get(t);if(n)return e.pendingFrames.delete(t),e.pendingFrameBytes=Math.max(0,e.pendingFrameBytes-n.encodedByteLength),e.pendingFrames.size===0&&e.pendingTrimTimer!==null&&(window.clearTimeout(e.pendingTrimTimer),e.pendingTrimTimer=null),n}function gC(e){const t=e.pendingFrames.entries().next().value;return t?Cu(e,t[0]):void 0}function db(e){e.pendingTrimTimer!==null&&(window.clearTimeout(e.pendingTrimTimer),e.pendingTrimTimer=null),e.pendingFrames.clear(),e.pendingFrameBytes=0,e.pendingFrameEvictedThroughTimestamp=-1}function ku(e,t=performance.now()){for(;e.pendingFrames.size>0;){const n=e.pendingFrames.entries().next().value;if(!n)break;const s=t-n[1].queuedAt>Vp,a=e.pendingFrames.size>Xv,o=e.pendingFrameBytes>Jv;if(!s&&!a&&!o)break;e.pendingFrameEvictedThroughTimestamp=Math.max(e.pendingFrameEvictedThroughTimestamp,n[0]),Cu(e,n[0]),e.pendingFrameEvictionCount+=1}}function vC(e,t,n,s,a,o=performance.now()){Cu(e,t);const c={frame:n,queuedAt:o,queueSize:s,encodedByteLength:Math.max(0,Math.floor(Number(n.payload.byteLength||0))),paintIsCancelled:a};e.pendingFrames.set(t,c),e.pendingFrameBytes+=c.encodedByteLength,ku(e,o),e.pendingFrameHighWaterMark=Math.max(e.pendingFrameHighWaterMark,e.pendingFrames.size),e.pendingFrameByteHighWaterMark=Math.max(e.pendingFrameByteHighWaterMark,e.pendingFrameBytes)}function pb(e,t){if(t.pendingTrimTimer!==null||t.pendingFrames.size===0)return;const n=t.pendingFrames.values().next().value;if(!n)return;const s=Math.max(1,Vp-(performance.now()-n.queuedAt)+1);t.pendingTrimTimer=window.setTimeout(()=>{t.pendingTrimTimer=null,Kt.get(e)===t&&(ku(t),pb(e,t))},s)}function mb(e){return Ga.delete(e)?(gc+=1,vc("hardware-release",e),!0):!1}function bC(e,t,n){if(t!=="prefer-hardware"||!n)return!1;const s=ra.get(e);return!s||s.requested!==t||s.actual!=="prefer-software"||gc<=s.failedHardwareReleaseGeneration?!1:(ra.delete(e),Ka.delete(e),sb+=1,ab=Date.now(),!0)}function xp(e,t=Is.h264DecodeAcceleration){const n=ra.get(e);return n?.requested===t?(n.actual!=="prefer-hardware"&&(Ga.delete(e),Ka.add(e)),n.actual):(n&&(ra.delete(e),Ka.delete(e)),t!=="prefer-hardware"?(mb(e),Ka.delete(e),t):(Ga.has(e)||Ga.add(e),"prefer-hardware"))}function Mu(e,t,n){if(t!=="prefer-hardware")return!1;const s=ra.get(e),a=Kt.get(e),o=Date.now();return li.has(e)||li.set(e,eb++),ra.set(e,{requested:t,actual:"prefer-software",reason:n,failedAt:o,failureCount:(s?.requested===t?s.failureCount:0)+1,codec:a?.codec||s?.codec||"",latencyMode:a?.latencyMode||s?.latencyMode||"smooth",inputCount:a?.inputSerial??s?.inputCount??0,outputCount:a?.outputSerial??s?.outputCount??0,lastInputAt:a?.lastInputAt??s?.lastInputAt??0,lastOutputAt:a?.lastOutputAt??s?.lastOutputAt??0,lastPaintAt:a?.lastPaintAt??s?.lastPaintAt??0,decodeQueueHighWaterMark:Math.max(a?.decodeQueueHighWaterMark??0,s?.decodeQueueHighWaterMark??0),decodeQueueOverflowSamples:Math.max(a?.decodeQueueOverflowSamples??0,s?.decodeQueueOverflowSamples??0),decodeQueueOverflowAgeMs:a?.decodeQueueOverflowStartedAt?Math.max(0,performance.now()-a.decodeQueueOverflowStartedAt):s?.decodeQueueOverflowAgeMs,failedHardwareReleaseGeneration:gc}),Ga.delete(e),Ka.add(e),ob+=1,ib=n,cb=o,!0}function sa(e){e.interactivePipelineFallbackTimer!==null&&(window.clearTimeout(e.interactivePipelineFallbackTimer),e.interactivePipelineFallbackTimer=null),e.interactivePipelineFallbackFrame!==null&&(window.cancelAnimationFrame(e.interactivePipelineFallbackFrame),e.interactivePipelineFallbackFrame=null),e.interactivePipelineRecoveryFrames=[],e.interactivePipelineRecoveryBytes=0,e.interactivePipelinePaintIsCancelled=void 0,e.interactivePipelineGuardTimestampUs=null}function fb(e,t){const n=t.interactivePipelineRecoveryFrames,s=t.interactivePipelinePaintIsCancelled,a=t.onBeforePaint,o=t.onPaint;if(sa(t),n.length===0||s?.()||Kt.get(e)!==t||t.hardwareAcceleration!=="prefer-hardware"||!Mu(e,t.requestedAcceleration,"interactive-pipeline-latency"))return!1;const c=t.requestedAcceleration,u=t.latencyMode;Jn(e);try{for(const d of n)Gp(e,d,o,c,u,s,!1,a)}catch{Jn(e)}return!0}function wC(e,t,n){const s=Math.max(0,Number(t.payload.byteLength||0));return e.interactivePipelineRecoveryFrames.length>=rC||e.interactivePipelineRecoveryBytes+s>sC?(sa(e),!1):(e.interactivePipelineRecoveryFrames.push({...t,payload:t.payload.slice()}),e.interactivePipelineRecoveryBytes+=s,e.interactivePipelinePaintIsCancelled=n,!0)}function yC(e,t,n,s,a=performance.now()){const o=()=>{if(!(Kt.get(e)!==t||t.interactivePipelineGuardTimestampUs!==n)){if(!t.pendingFrames.has(n)){sa(t);return}fb(e,t)}},c=u=>{if(t.interactivePipelineFallbackFrame=null,!(Kt.get(e)!==t||t.interactivePipelineGuardTimestampUs!==n)){if(!t.pendingFrames.has(n)){sa(t);return}if(u-a>=s){o();return}t.interactivePipelineFallbackFrame=window.requestAnimationFrame(c)}};t.interactivePipelineFallbackTimer=window.setTimeout(o,s),t.interactivePipelineFallbackFrame=window.requestAnimationFrame(c)}function xC(e,t,n,s=64){try{let a=bp.get(e);a||(a={canvas:document.createElement("canvas"),lastHash:"",initialized:!1},bp.set(e,a));const o=Math.max(8,Math.min(64,Math.round(s))),c=Math.max(1,Math.round(o*Math.max(1,n)/Math.max(1,t)));(a.canvas.width!==o||a.canvas.height!==c)&&(a.canvas.width=o,a.canvas.height=c);const u=a.canvas.getContext("2d",{willReadFrequently:!0});if(!u)return{visualHash:"",visualChanged:!0};u.drawImage(e,0,0,Math.max(1,t),Math.max(1,n),0,0,o,c);const d=u.getImageData(0,0,o,c).data;let p=2166136261;for(let g=0;g<d.length;g+=4)p^=d[g],p=Math.imul(p,16777619),p^=d[g+1],p=Math.imul(p,16777619),p^=d[g+2],p=Math.imul(p,16777619);const f=(p>>>0).toString(16).padStart(8,"0"),m=!a.initialized||f!==a.lastHash;return a.initialized=!0,a.lastHash=f,{visualHash:f,visualChanged:m}}catch{return{visualHash:"",visualChanged:!0}}}function Sp(e,t,n,s=qp,a=64,o){if(!mC&&o)return hb(e,o);let c=wp.get(e);c||(c={lastHash:"",initialized:!1,lastCanvasSampleAt:0},wp.set(e,c));const u=performance.now();if(c.initialized&&s>0&&u-c.lastCanvasSampleAt<s)return{visualHash:c.lastHash,visualChanged:!1};const d=xC(e,t,n,a);return c.initialized=!0,c.lastHash=d.visualHash,c.lastCanvasSampleAt=u,d}function hb(e,t){let n=iu.get(e);n||(n={lastHash:"",initialized:!1},iu.set(e,n));const s=String(t.contentHash||""),a=!n.initialized||!s||s!==n.lastHash;return n.initialized=!0,n.lastHash=s,{visualHash:s,visualChanged:a}}function gb(e,t,n=!1){const s=vp.get(e);if(s)return s;const a=e.getContext("2d",{alpha:!1,desynchronized:t==="interactive",willReadFrequently:n});if(a){const o=a.getContextAttributes?.(),c={context:a,presentation:o?.desynchronized?"desync":"sync"};return vp.set(e,c),c}return null}function SC(e){const t=String(e.frameMode||e.mode||"").toLowerCase(),n=String(e.compression||"").toLowerCase(),s=String(e.mimeType||"").toLowerCase();return t==="mode2-lzo"||n==="lzo1x"||s==="application/vnd.livedesk.lzo-rgb565"||t==="mode2-lz4"||String(e.compression||"").toLowerCase()==="lz4"||s==="application/vnd.livedesk.lz4-raw"}function CC(e){return String(e.frameMode||e.mode||"").toLowerCase()==="mode3-h264-hw"||String(e.codec||"").toLowerCase()==="h264"||String(e.mimeType||"").toLowerCase()==="video/h264"}function kC(e){const t=String(e.frameMode||e.mode||"").toLowerCase(),n=String(e.mimeType||"").toLowerCase();return t==="mode5-lzo-delta"||n==="application/vnd.livedesk.lzo-rgb565-delta"}function ch(e,t,n){let s=n,a=t;if(s===15){let o=255;for(;o===255;){if(a>=e.length)throw new Error("Invalid LZ4 block: length overrun.");o=e[a],a+=1,s+=o}}return{length:s,cursor:a}}function MC(e,t){const n=new Uint8Array(t);let s=0,a=0;for(;s<e.length;){const o=e[s];s+=1;const c=ch(e,s,o>>4);s=c.cursor;const u=c.length;if(s+u>e.length||a+u>n.length)throw new Error("Invalid LZ4 block: literal overrun.");if(n.set(e.subarray(s,s+u),a),s+=u,a+=u,s>=e.length)break;if(s+2>e.length)throw new Error("Invalid LZ4 block: missing offset.");const d=e[s]|e[s+1]<<8;if(s+=2,d<=0||d>a)throw new Error("Invalid LZ4 block: bad match offset.");const p=ch(e,s,o&15);s=p.cursor;const f=p.length+4;if(a+f>n.length)throw new Error("Invalid LZ4 block: match overrun.");let m=a-d;for(let g=0;g<f;g+=1)n[a]=n[m],a+=1,m+=1}if(a!==n.length)throw new Error("Invalid LZ4 block: incomplete output.");return n}function AC(e){const t=Math.max(1,Math.floor(e.width||0)),n=Math.max(1,Math.floor(e.height||0)),s=String(e.compression||"").toLowerCase(),a=String(e.pixelFormat||e.codec||"").toLowerCase();if(s==="lzo1x"||String(e.frameMode||e.mode||"").toLowerCase()==="mode2-lzo"||String(e.mimeType||"").toLowerCase()==="application/vnd.livedesk.lzo-rgb565"){const f=Math.max(1,Math.floor(e.bytesPerPixel||2)),m=t*n*2,g=Math.floor(e.uncompressedByteLength||m);if(f!==2||g!==m)throw new Error(`Invalid mode2 RGB565 frame size: ${g} for ${t}x${n}.`);if(a&&a!=="rgb565le"&&a!=="rgb565")throw new Error(`Unsupported mode2 pixel format: ${a}`);const w=qv(e.payload,m),b=new Uint8ClampedArray(t*n*4);for(let y=0,C=0;y<w.length;y+=2,C+=4){const A=w[y]|w[y+1]<<8,k=A>>11&31,R=A>>5&63,_=A&31;b[C]=k<<3|k>>2,b[C+1]=R<<2|R>>4,b[C+2]=_<<3|_>>2,b[C+3]=255}return new ImageData(b,t,n)}const c=Math.max(1,Math.floor(e.bytesPerPixel||4)),u=Math.max(t*n*c,Math.floor(e.uncompressedByteLength||0)),d=MC(e.payload,u);if(c!==4)throw new Error(`Unsupported mode2 pixel size: ${c}`);const p=new Uint8ClampedArray(t*n*4);if(a==="rgba32"||a==="rgba")p.set(d.subarray(0,p.length));else for(let f=0,m=0;m<p.length;f+=4,m+=4)p[m]=d[f+2],p[m+1]=d[f+1],p[m+2]=d[f],p[m+3]=d[f+3];return new ImageData(p,t,n)}function lh(e,t="smooth",n=Is.h264DecodeAcceleration){const s=window.VideoDecoder;if(!s||!window.EncodedVideoChunk)throw new Error("WebCodecs H.264 decode is not supported in this browser.");const a=Kt.get(e);if(a&&a.decoder.state!=="closed"&&a.latencyMode===t)return a;a&&Jn(e);let o;const c=new s({output:u=>{if(Kt.get(e)!==o){u.close();return}const d=Number(u.timestamp||0),p=performance.now();o.outputSerial+=1,ku(o,p);let f=Cu(o,d);if(!f&&d>o.pendingFrameEvictedThroughTimestamp&&o.pendingFrames.size>0&&(f=gC(o),o.timestampFallbacks+=1),!f){o.pendingFrameUnmatchedOutputCount+=1,o.droppedForLatency+=1,o.lastOutputAt=p,u.close();return}const m=o.interactivePipelineGuardTimestampUs===d;if(ub(f)){m&&sa(o),o.droppedForLatency+=1,o.lastOutputAt=p,u.close();return}const g=u.displayWidth||u.codedWidth||e.width||960,w=u.displayHeight||u.codedHeight||e.height||540,b=Number(f?.frame.durationUs||0),y=Number(u.duration||0),C=Math.max(16,Math.min(250,(b>0?b:y||83333)/1e3));o.targetPaintIntervalMs=C;const A=Math.max(0,p-f.queuedAt),R=lb(f.frame,b>0?b:Math.round(C*1e3))?Yv:Qv;if(o.latencyMode==="interactive"&&o.hardwareAcceleration==="prefer-hardware"&&m&&o.interactivePipelineRecoveryFrames.length>0&&A>R){u.close(),o.droppedForLatency+=1,fb(e,o);return}m&&sa(o),Math.abs(o.interactiveBurstOutputCadenceMs-C)>1&&(o.interactiveBurstOutputTimeCursor=0,o.interactiveBurstOutputTimeCount=0,o.interactiveBurstOutputCadenceMs=C,o.interactiveBurstOutputWindowMs=0),o.interactiveBurstOutputTimes[o.interactiveBurstOutputTimeCursor]=p,o.interactiveBurstOutputTimeCursor=(o.interactiveBurstOutputTimeCursor+1)%ri,o.interactiveBurstOutputTimeCount=Math.min(ri,o.interactiveBurstOutputTimeCount+1);const _=o.interactiveBurstOutputTimeCount>=ri?p-o.interactiveBurstOutputTimes[o.interactiveBurstOutputTimeCursor]:0;for(o.interactiveBurstOutputWindowMs=Math.max(0,_),o.decodedFrames.push({videoFrame:u,pending:f,decodedAt:p,width:g,height:w,durationMs:C}),o.latencyMode==="interactive"&&o.targetPaintIntervalMs>20&&o.interactiveBurstOutputTimeCount>=ri&&_<=Math.min(dC,Math.max(uC,o.targetPaintIntervalMs-5))&&(o.interactiveBurstTailHoldArmed=!0),o.lastOutputAt=p;o.decodedFrames.length>Up(o);)cu(o,o.decodedFrames.shift(),"capacity");o.renderQueueHighWaterMark=Math.max(o.renderQueueHighWaterMark,o.decodedFrames.length),bb(o),o.renderTimer!==null&&o.renderScheduledAt>0&&performance.now()-o.renderScheduledAt>lC&&(typeof document>"u"||document.visibilityState==="visible")&&(window.cancelAnimationFrame(o.renderTimer),o.renderTimer=null,o.renderScheduledAt=0),o.renderTimer!==null&&o.decodedFrames.length>=Gv&&(window.cancelAnimationFrame(o.renderTimer),o.renderTimer=null,o.renderScheduledAt=0),lu(e,o)},error:()=>{Kt.get(e)===o&&(Mu(e,o.requestedAcceleration,"decoder-error"),Jn(e))}});return tb+=1,li.has(e)||li.set(e,eb++),o={decoder:c,configured:!1,configKey:"",codec:"",requestedAcceleration:n,hardwareAcceleration:xp(e,n),latencyMode:t,keyFrameSeen:!1,droppedForLatency:0,pendingFrames:new Map,pendingFrameBytes:0,pendingFrameHighWaterMark:0,pendingFrameByteHighWaterMark:0,pendingFrameEvictionCount:0,pendingFrameUnmatchedOutputCount:0,pendingFrameEvictedThroughTimestamp:-1,pendingTrimTimer:null,decodedFrames:[],renderQueueHighWaterMark:0,renderQueueCapacityDropCount:0,renderQueueAgeDropCount:0,renderTimer:null,renderScheduledAt:0,flushTimer:null,flushInFlight:!1,flushCount:0,timestampFallbacks:0,inputSerial:0,outputSerial:0,lastFlushInputSerial:0,lastOutputAt:0,lastPaintAt:0,lastInputAt:0,interactiveBufferPrimed:!1,interactiveBufferStartedAt:0,interactiveBufferWaitCount:0,interactiveBufferWaitMs:0,interactiveQueueDrainCount:0,interactiveBurstTailHoldArmed:!1,interactiveBurstTailHoldCount:0,interactiveBurstOutputTimes:new Float64Array(ri),interactiveBurstOutputTimeCursor:0,interactiveBurstOutputTimeCount:0,interactiveBurstOutputCadenceMs:0,interactiveBurstOutputWindowMs:0,interactivePipelineFallbackTimer:null,interactivePipelineFallbackFrame:null,interactivePipelineGuardTimestampUs:null,interactivePipelineRecoveryFrames:[],interactivePipelineRecoveryBytes:0,interactivePipelinePaintIsCancelled:void 0,interactiveBackingWidth:0,interactiveBackingHeight:0,interactiveBackingSourceWidth:0,interactiveBackingSourceHeight:0,interactiveBackingMeasuredAt:0,lastInputFrameSeq:void 0,targetPaintIntervalMs:1e3/12,nextChunkTimestampUs:0,healthSampleStartedAt:performance.now(),healthInputSerial:0,healthOutputSerial:0,decodeQueueHighWaterMark:0,decodeQueueOverflowStartedAt:0,decodeQueueOverflowSamples:0},Kt.set(e,o),Ja.add(e),yp=Math.max(yp,Ja.size),vc("create",e),o}function vb(e){sa(e),e.renderTimer!==null&&(window.cancelAnimationFrame(e.renderTimer),e.renderTimer=null),e.renderScheduledAt=0,e.flushTimer!==null&&(window.clearTimeout(e.flushTimer),e.flushTimer=null),e.flushInFlight=!1;const t=e.decodedFrames;e.decodedFrames=[];for(const n of t)try{n.videoFrame.close()}catch{}e.interactiveBufferPrimed=!1,e.interactiveBufferStartedAt=0,e.interactiveBurstTailHoldArmed=!1,e.interactiveBurstOutputTimeCursor=0,e.interactiveBurstOutputTimeCount=0,e.interactiveBurstOutputCadenceMs=0,e.interactiveBurstOutputWindowMs=0}function cu(e,t,n="other"){t&&(t.videoFrame.close(),e.droppedForLatency+=1,n==="capacity"?e.renderQueueCapacityDropCount+=1:n==="age"&&(e.renderQueueAgeDropCount+=1))}function Up(e){return e.latencyMode==="interactive"?e.targetPaintIntervalMs<=20?GS:ri:String(e.decodedFrames[0]?.pending?.frame.frameMode||e.decodedFrames[0]?.pending?.frame.mode||"").toLowerCase()==="mode4-h264-atlas"?US:Gv}function bb(e,t=performance.now()){const n=Up(e);for(;e.decodedFrames.length>n;)cu(e,e.decodedFrames.shift(),"capacity");const s=e.latencyMode==="interactive"?Kv:XS;let a=e.decodedFrames[0];for(;e.decodedFrames.length>0&&a&&t-a.decodedAt>s;)cu(e,e.decodedFrames.shift(),"age"),a=e.decodedFrames[0]}function wb(e,t){if(t.hardwareAcceleration!=="prefer-hardware"||t.latencyMode==="interactive"||t.flushTimer!==null||t.flushInFlight)return;const n=ZS;t.flushTimer=window.setTimeout(async()=>{t.flushTimer=null;const s=performance.now();if(ku(t,s),Kt.get(e)!==t||t.decoder.state!=="configured"||t.pendingFrames.size===0||t.inputSerial<=t.lastFlushInputSerial||t.lastOutputAt>0&&s-t.lastOutputAt<n)return;const a=t.inputSerial;t.flushInFlight=!0,t.flushCount+=1,t.keyFrameSeen=!1;try{await t.decoder.flush(),t.lastFlushInputSerial=Math.max(t.lastFlushInputSerial,a)}catch{Kt.get(e)===t&&Xl(t)}finally{t.flushInFlight=!1,Kt.get(e)===t&&t.inputSerial>a&&t.pendingFrames.size>0&&performance.now()-t.lastOutputAt>=n&&wb(e,t)}},n)}function RC(e,t,n,s){const a=performance.now();if(t.interactiveBackingWidth>0&&t.interactiveBackingHeight>0&&a-t.interactiveBackingMeasuredAt<qS)return{width:Math.min(n,t.interactiveBackingWidth),height:Math.min(s,t.interactiveBackingHeight)};const o=typeof e.getBoundingClientRect=="function"?e.getBoundingClientRect():{width:Number(e.clientWidth||e.width||0),height:Number(e.clientHeight||e.height||0)},c=Math.max(1,Math.min(2,Number(globalThis.devicePixelRatio)||1)),u=Math.max(0,Number(e.width||0)),d=Math.max(0,Number(e.height||0)),p=o.width>0?Math.round(o.width*c):u||oh,f=o.height>0?Math.round(o.height*c):d||ih,m=Math.min(1,p/n,f/s),g=Math.min(1,Math.max(oh/n,ih/s)),w=Math.min(1,zS/n,VS/s),b=Math.max(.01,Math.min(w,Math.max(g,m)));return t.interactiveBackingWidth=Math.max(1,Math.round(n*b)),t.interactiveBackingHeight=Math.max(1,Math.round(s*b)),t.interactiveBackingMeasuredAt=a,{width:t.interactiveBackingWidth,height:t.interactiveBackingHeight}}function uh(e,t,n){const s=performance.now();try{if(!n.pending||ub(n.pending)){t.droppedForLatency+=1;return}let a=1;try{const f=t.onBeforePaint?.(n.pending.frame);typeof f=="number"&&Number.isFinite(f)&&(a=Math.max(.05,Math.min(1,f)))}catch{}const o=t.latencyMode==="interactive"?RC(e,t,n.width,n.height):{width:n.width,height:n.height},c=o.width,u=o.height,d=e.width!==c||e.height!==u;d&&(e.width=c,e.height=u);const p=gb(e,t.latencyMode,t.hardwareAcceleration==="prefer-software");if(p){const f=p.context.globalAlpha;p.context.globalAlpha=d||t.lastPaintAt<=0||t.hardwareAcceleration!=="prefer-hardware"?1:a;try{p.context.drawImage(n.videoFrame,0,0,n.width,n.height,0,0,c,u)}finally{p.context.globalAlpha=f}}if(n.pending){const f=performance.now(),g=t.latencyMode==="interactive"?hb(e,n.pending.frame):Sp(e,n.width,n.height,qp,64,n.pending.frame),w=hC(n.pending.frame);try{t.onPaint?.(w,{deviceId:w.deviceId,frameSeq:w.frameSeq,mode:w.frameMode||w.mode||w.codec||w.mimeType,width:n.width,height:n.height,byteLength:w.byteLength,queuedForMs:Math.max(0,s-n.pending.queuedAt),decodedForMs:Math.max(0,n.decodedAt-n.pending.queuedAt),scheduledForMs:Math.max(0,s-n.decodedAt),drawMs:Math.max(0,f-s),queueSize:n.pending.queueSize,renderQueueSize:t.decodedFrames.length,droppedForLatency:t.droppedForLatency,h264DecodeAcceleration:t.hardwareAcceleration,decoderLabel:t.hardwareAcceleration,decoderFlushCount:t.flushCount,decoderTimestampFallbacks:t.timestampFallbacks,decoderInputCount:t.inputSerial,decoderOutputCount:t.outputSerial,targetPaintIntervalMs:t.targetPaintIntervalMs,canvasPresentation:p?.presentation||"sync",interactiveBufferWaitCount:t.interactiveBufferWaitCount,interactiveBufferWaitMs:t.interactiveBufferWaitMs,interactiveQueueDrainCount:t.interactiveQueueDrainCount,interactiveBurstOutputWindowMs:t.interactiveBurstOutputWindowMs,interactiveBurstTailHoldCount:t.interactiveBurstTailHoldCount,visualHash:g.visualHash,visualChanged:g.visualChanged,paintedAt:f})}catch{}}t.lastPaintAt=performance.now()}finally{n.videoFrame.close()}}function lu(e,t){if(t.renderTimer!==null||t.decodedFrames.length===0)return;const n=Math.max(16,Math.min(250,t.targetPaintIntervalMs||1e3/12)),s=()=>{if(t.renderTimer=null,t.renderScheduledAt=0,t.decodedFrames.length===0)return;const a=performance.now();if(bb(t,a),t.decodedFrames.length===0){t.interactiveBurstTailHoldArmed=!1;return}if(t.latencyMode==="interactive"){const d=t.targetPaintIntervalMs<=20;if(d&&!t.interactiveBufferPrimed){t.interactiveBufferStartedAt<=0&&(t.interactiveBufferStartedAt=a,t.interactiveBufferWaitCount+=1);const f=t.decodedFrames.length>=KS,m=a-t.interactiveBufferStartedAt>=QS;if(!f&&!m){t.renderScheduledAt=performance.now(),t.renderTimer=window.requestAnimationFrame(s);return}t.interactiveBufferWaitMs+=Math.max(0,a-t.interactiveBufferStartedAt),t.interactiveBufferPrimed=!0}else d||(t.interactiveBufferPrimed=!0);if(!d&&t.interactiveBurstTailHoldArmed&&t.decodedFrames.length===1&&a-t.decodedFrames[0].decodedAt<=Kv-pC){t.interactiveBurstTailHoldArmed=!1,t.interactiveBurstTailHoldCount+=1,t.renderScheduledAt=performance.now(),t.renderTimer=window.requestAnimationFrame(s);return}const p=t.decodedFrames.shift();if(p)try{uh(e,t,p)}catch{}t.decodedFrames.length===0&&(t.interactiveQueueDrainCount+=1,t.interactiveBufferPrimed=!1,t.interactiveBufferStartedAt=0,t.interactiveBurstTailHoldArmed=!1),lu(e,t);return}const o=t.lastPaintAt>0?t.lastPaintAt+n:a+YS;if(!(a+JS>=o||t.decodedFrames.length>=Math.max(1,Up(t)-1))){t.renderScheduledAt=performance.now(),t.renderTimer=window.requestAnimationFrame(s);return}const u=t.decodedFrames.shift();if(u)try{uh(e,t,u)}catch{}lu(e,t)};t.renderScheduledAt=performance.now(),t.renderTimer=window.requestAnimationFrame(s)}function yb(e,t){if(Kt.get(e)!==t||t.decoder.state==="closed")return!1;for(t.renderTimer!==null&&(window.cancelAnimationFrame(t.renderTimer),t.renderTimer=null),t.renderScheduledAt=0;t.decodedFrames.length>1;)cu(t,t.decodedFrames.shift());return t.lastPaintAt=0,t.interactiveBufferPrimed=!1,t.interactiveBufferStartedAt=0,t.interactiveBurstTailHoldArmed=!1,t.interactiveBurstOutputTimeCursor=0,t.interactiveBurstOutputTimeCount=0,t.interactiveBurstOutputCadenceMs=0,t.interactiveBurstOutputWindowMs=0,lu(e,t),!0}function Id(){if(!(typeof document>"u"||document.visibilityState!=="visible"))for(const e of Ja){const t=Kt.get(e);if(!t||t.decoder.state==="closed"){Ja.delete(e);continue}yb(e,t)}}typeof document<"u"&&typeof window<"u"&&(document.addEventListener("visibilitychange",Id),window.addEventListener("focus",Id),window.addEventListener("pageshow",Id));function Jn(e){mb(e),Ja.delete(e),iu.delete(e);const t=Kt.get(e);if(t){Kt.delete(e),nb+=1,db(t),t.onBeforePaint=void 0,t.onPaint=void 0,vb(t);try{t.decoder.state!=="closed"&&t.decoder.reset()}catch{}try{t.decoder.state!=="closed"&&t.decoder.close()}catch{}vc("close",e)}}function Yo(e){e&&(ra.delete(e),Ka.delete(e),vp.delete(e),wp.delete(e),bp.delete(e),iu.delete(e),pc.delete(e),Jn(e))}function NC(e,t){const n=Kt.get(e),s=ra.get(e);if(!n&&!s)return null;const a=c=>c>0?Math.max(0,t-c):void 0,o=n?.pendingFrames.values().next().value;return{canvasId:li.get(e)||0,canvasWidth:Math.max(0,Number(e.width||0)),canvasHeight:Math.max(0,Number(e.height||0)),decoderState:n?.decoder.state||"fallback-pending",configured:n?.configured||!1,keyFrameSeen:n?.keyFrameSeen||!1,codec:n?.codec||s?.codec||"",requestedAcceleration:n?.requestedAcceleration||s?.requested||Is.h264DecodeAcceleration,configuredAcceleration:n?.hardwareAcceleration||s?.actual||Is.h264DecodeAcceleration,latencyMode:n?.latencyMode||s?.latencyMode||"smooth",decodeQueueSize:Math.max(0,Number(n?.decoder.decodeQueueSize||0)),decodeQueueHighWaterMark:Math.max(0,Number(n?.decodeQueueHighWaterMark??0),Number(s?.decodeQueueHighWaterMark??0)),decodeQueueOverflowSamples:Math.max(0,Number(n?.decodeQueueOverflowSamples??0),Number(s?.decodeQueueOverflowSamples??0)),decodeQueueOverflowAgeMs:n?.decodeQueueOverflowStartedAt?Math.max(0,t-n.decodeQueueOverflowStartedAt):s?.decodeQueueOverflowAgeMs,pendingFrameCount:n?.pendingFrames.size||0,pendingFrameBytes:n?.pendingFrameBytes||0,pendingFrameHighWaterMark:n?.pendingFrameHighWaterMark||0,pendingFrameByteHighWaterMark:n?.pendingFrameByteHighWaterMark||0,pendingFrameEvictionCount:n?.pendingFrameEvictionCount||0,pendingFrameUnmatchedOutputCount:n?.pendingFrameUnmatchedOutputCount||0,pendingFrameOldestAgeMs:o?Math.max(0,t-o.queuedAt):void 0,pendingFrameMaxCount:Xv,pendingFrameMaxBytes:Jv,pendingFrameMaxAgeMs:Vp,renderQueueSize:n?.decodedFrames.length||0,renderQueueHighWaterMark:n?.renderQueueHighWaterMark||0,renderQueueCapacityDropCount:n?.renderQueueCapacityDropCount||0,renderQueueAgeDropCount:n?.renderQueueAgeDropCount||0,interactiveBurstTailHoldCount:n?.interactiveBurstTailHoldCount||0,interactiveBurstOutputWindowMs:Math.max(0,Number(n?.interactiveBurstOutputWindowMs||0)),interactivePipelineRecoveryBytes:Math.max(0,Number(n?.interactivePipelineRecoveryBytes||0)),targetPaintIntervalMs:Math.max(0,Number(n?.targetPaintIntervalMs||0)),droppedForLatency:Math.max(0,Number(n?.droppedForLatency||0)),inputCount:n?.inputSerial??s?.inputCount??0,outputCount:n?.outputSerial??s?.outputCount??0,lastInputAgeMs:a(n?.lastInputAt??s?.lastInputAt??0),lastOutputAgeMs:a(n?.lastOutputAt??s?.lastOutputAt??0),lastPaintAgeMs:a(n?.lastPaintAt??s?.lastPaintAt??0),softwareFallbackReason:s?.reason,softwareFallbackAt:s?.failedAt,softwareFallbackCount:s?.failureCount||0}}function Rl(e,t={}){const n=performance.now(),a=(e?[e]:[...new Set([...Ja,...Ka])]).map(u=>NC(u,n)).filter(u=>u!==null),o=a.reduce((u,d)=>u+d.pendingFrameCount,0),c=a.reduce((u,d)=>u+d.pendingFrameBytes,0);return{capturedAt:Date.now(),hardwareRequestPolicy:"all-active",activeDecoderCount:a.filter(u=>u.decoderState!=="fallback-pending").length,hardwareLeaseCount:Ga.size,hardwareReleaseGeneration:gc,hardwareRecoveryProbeCount:sb,lastHardwareRecoveryProbeAt:ab,activeSoftwareFallbackCount:a.filter(u=>u.configuredAcceleration==="prefer-software"&&u.requestedAcceleration==="prefer-hardware").length,decoderCreateCount:tb,decoderCloseCount:nb,activeDecoderHighWaterMark:yp,decoderLifecycleSequence:rb,decoderLifecycleEvents:t.includeLifecycleEvents===!1?[]:Ji.map(u=>({...u})),softwareFallbackEventCount:ob,lastSoftwareFallbackReason:ib,lastSoftwareFallbackAt:cb,pendingFrameCount:o,pendingFrameBytes:c,canvases:a}}function Xl(e,t=1){try{e.decoder.state!=="closed"&&e.decoder.reset()}catch{}e.configured=!1,e.configKey="",e.keyFrameSeen=!1,db(e),vb(e),e.lastPaintAt=0,e.lastOutputAt=0,e.lastInputAt=0,e.interactiveBufferPrimed=!1,e.interactiveBufferStartedAt=0,e.lastInputFrameSeq=void 0,e.nextChunkTimestampUs=0,e.healthSampleStartedAt=performance.now(),e.healthInputSerial=e.inputSerial,e.healthOutputSerial=e.outputSerial,e.decodeQueueOverflowStartedAt=0,e.decodeQueueOverflowSamples=0,e.droppedForLatency+=Math.max(1,Math.min(1e4,Math.floor(t)))}function TC(e,t,n=performance.now()){const s=Math.max(0,Number.isFinite(t)?t:0);if(e.decodeQueueHighWaterMark=Math.max(e.decodeQueueHighWaterMark,s),s<=aC)return e.decodeQueueOverflowStartedAt=0,e.decodeQueueOverflowSamples=0,!1;e.decodeQueueOverflowStartedAt<=0?(e.decodeQueueOverflowStartedAt=n,e.decodeQueueOverflowSamples=1):e.decodeQueueOverflowSamples+=1;const a=Math.max(0,n-e.decodeQueueOverflowStartedAt);return s>=oC||e.decodeQueueOverflowSamples>=cC&&a>=iC}function IC(e,t,n,s,a,o){t.decoder.configure(n),t.configured=!0,t.configKey=s,t.codec=n.codec,t.requestedAcceleration=o,t.hardwareAcceleration=a,t.keyFrameSeen=!1,t.nextChunkTimestampUs=0,t.lastInputFrameSeq=void 0,vc("configure",e)}function PC(e,t){if(t.latencyMode!=="interactive"||t.hardwareAcceleration!=="prefer-hardware")return!1;const n=performance.now();if(n-t.healthSampleStartedAt<eC)return!1;const s=t.inputSerial-t.healthInputSerial,a=t.outputSerial-t.healthOutputSerial;return t.healthSampleStartedAt=n,t.healthInputSerial=t.inputSerial,t.healthOutputSerial=t.outputSerial,s<tC||a/Math.max(1,s)>=nC?!1:(Mu(e,t.requestedAcceleration,"interactive-health"),Jn(e),!0)}function Xo(e,t=1){if(!e)return!1;const n=Kt.get(e);return n?(n.droppedForLatency+=Math.max(1,Math.min(1e4,Math.floor(t))),Jn(e),!0):!1}function jC(e){if(!e)return!1;const t=Kt.get(e);return t?yb(e,t):!1}function EC(e,t,n,s="interactive",a){Jn(e);const o=performance.now(),c=BS(t.payload,t.uncompressedByteLength||0),u=String(t.streamId||"mode5");let d=pc.get(e);if(!d||d.streamId!==u||d.width!==c.width||d.height!==c.height){const C=new Uint8ClampedArray(c.width*c.height*4);for(let A=3;A<C.length;A+=4)C[A]=255;d={streamId:u,width:c.width,height:c.height,rgba:C,imageData:new ImageData(C,c.width,c.height),keyFrameSeen:!1,inputSerial:0,outputSerial:0},pc.set(e,d)}if(!d)throw new Error("Mode 5 canvas state could not be initialized.");d.inputSerial+=1;const f=Number(t.streamFrameSeq||0);if(f>0&&(d.lastStreamFrameSeq=f),!c.keyFrame&&!d.keyFrameSeen)return;c.keyFrame&&(d.keyFrameSeen=!0);const m=HS(d.rgba,d.width,d.height,c),g=performance.now();try{a?.(t)}catch{}(e.width!==d.width||e.height!==d.height)&&(e.width=d.width,e.height=d.height);const w=gb(e,s),b=performance.now();m&&w?.context.putImageData(d.imageData,0,0,m.x,m.y,m.width,m.height);const y=performance.now();d.outputSerial+=1,n?.(t,{deviceId:t.deviceId,frameSeq:t.frameSeq,mode:t.frameMode||t.mode||t.mimeType,width:d.width,height:d.height,byteLength:t.byteLength,queuedForMs:Math.max(0,y-o),decodedForMs:Math.max(0,g-o),scheduledForMs:0,drawMs:Math.max(0,y-b),queueSize:0,renderQueueSize:0,droppedForLatency:0,h264DecodeAcceleration:"prefer-software",decoderLabel:"lzo-rgb565-delta",decoderFlushCount:0,decoderTimestampFallbacks:0,decoderInputCount:d.inputSerial,decoderOutputCount:d.outputSerial,targetPaintIntervalMs:Math.max(1,Number(t.durationUs||0)/1e3||1e3/30),canvasPresentation:w?.presentation||"sync",interactiveBufferWaitCount:0,interactiveBufferWaitMs:0,interactiveQueueDrainCount:0,visualHash:String(t.contentHash||""),visualChanged:Number(t.deltaVisualTileCount||0)>0,paintedAt:y})}const Pd=[{code:30,maxFrameSize:1620,maxMacroblocksPerSecond:40500},{code:31,maxFrameSize:3600,maxMacroblocksPerSecond:108e3},{code:32,maxFrameSize:5120,maxMacroblocksPerSecond:216e3},{code:40,maxFrameSize:8192,maxMacroblocksPerSecond:245760},{code:41,maxFrameSize:8192,maxMacroblocksPerSecond:245760},{code:42,maxFrameSize:8704,maxMacroblocksPerSecond:522240},{code:50,maxFrameSize:22080,maxMacroblocksPerSecond:589824},{code:51,maxFrameSize:36864,maxMacroblocksPerSecond:983040},{code:52,maxFrameSize:36864,maxMacroblocksPerSecond:2073600}];function dh(e,t){for(let n=Math.max(0,t);n+3<e.length;n+=1)if(!(e[n]!==0||e[n+1]!==0)){if(e[n+2]===1)return{index:n,length:3};if(e[n+2]===0&&e[n+3]===1)return{index:n,length:4}}return null}function FC(e){let t=0;for(;t<e.length;){const n=dh(e,t);if(!n)break;const s=n.index+n.length,a=dh(e,s),o=a?.index??e.length;if(s<o&&(e[s]&31)===7){const c=[];let u=0;for(let d=s+1;d<o;d+=1){const p=e[d];if(u>=2&&p===3){u=0;continue}c.push(p),u=p===0?u+1:0}if(c.length>=3)return`avc1.${c.slice(0,3).map(d=>d.toString(16).toUpperCase().padStart(2,"0")).join("")}`}t=a?a.index:e.length}return""}function DC(e,t,n,s,a=""){const o=Math.ceil(e/16)*Math.ceil(t/16),c=n>0?1e6/n:30,u=o*c,d=Pd.find(p=>o<=p.maxFrameSize&&u<=p.maxMacroblocksPerSecond)||Pd[Pd.length-1];return FC(s)||a||`avc1.42E0${d.code.toString(16).toUpperCase().padStart(2,"0")}`}function Gp(e,t,n,s,a="smooth",o=()=>!1,c=!0,u){pc.delete(e);const d=String(t.h264Format||"").toLowerCase()==="avc"?"avc":"annexb",p=Math.max(1,Math.floor(t.width||960)),f=Math.max(1,Math.floor(t.height||540)),m=Math.max(1,Math.floor(t.durationUs||1e6/12)),g=s||Is.h264DecodeAcceleration,w=t.isKeyFrame===!0||String(t.chunkType||"").toLowerCase()==="key";bC(e,g,w);let b=lh(e,a,g);const y=DC(p,f,m,t.payload,b.codec);let C=xp(e,g),A="";const k=()=>{A=[t.streamId||"",t.commandId||"",p,f,y,d,g,C,a].join("|")};k(),b.onBeforePaint=u,b.onPaint=n,b.configured&&b.decoder.state!=="configured"&&(b.configured=!1,b.configKey=""),b.configured&&b.configKey!==A&&(Jn(e),b=lh(e,a,g),b.onBeforePaint=u,b.onPaint=n,C=xp(e,g),k());const R=()=>({codec:y,codedWidth:p,codedHeight:f,hardwareAcceleration:C,optimizeForLatency:!0,avc:{format:d}}),_=X=>b.hardwareAcceleration!=="prefer-hardware"||!Mu(e,b.requestedAcceleration,X)?!1:(Jn(e),c&&w&&Gp(e,t,n,g,a,o,!1,u),!0),E=()=>{try{return IC(e,b,R(),A,C,g),!0}catch(X){if(_("configure-error"))return!1;throw Jn(e),X}};if(!b.configured&&!E())return;const L=Number(t.streamFrameSeq||0);if(L>0&&b.lastInputFrameSeq!==void 0&&(L<=b.lastInputFrameSeq&&(!w||L===b.lastInputFrameSeq||(Xl(b,b.lastInputFrameSeq-L+1),!E()))||L>b.lastInputFrameSeq+1&&(Xl(b,L-b.lastInputFrameSeq-1),!w||!E()))||(L>0&&(b.lastInputFrameSeq=L),!w&&!b.keyFrameSeen))return;w&&(b.keyFrameSeen=!0);const M=Number(b.decoder.decodeQueueSize||0);if(TC(b,M)){if(b.latencyMode==="interactive"&&b.hardwareAcceleration==="prefer-hardware"){_("decode-queue-overflow");return}if(Xl(b),!w||!E())return;b.keyFrameSeen=!0}const U=b.nextChunkTimestampUs;b.nextChunkTimestampUs+=m,vC(b,U,t,M,o),pb(e,b),b.inputSerial+=1,b.lastInputAt=performance.now(),b.inputSerial===1&&vc("first-input",e);const V=t.payload.buffer,T=V instanceof ArrayBuffer?[V]:[],j=lb(t,m),$=!j&&b.outputSerial>0,Q=w&&b.latencyMode==="interactive"&&b.hardwareAcceleration==="prefer-hardware"&&(j||$),G=j?Yv:Qv;Q&&(sa(b),b.interactivePipelineGuardTimestampUs=U);const q=b.interactivePipelineGuardTimestampUs!==null&&b.interactivePipelineRecoveryFrames.length>0,re=Q||q?wC(b,t,o):!1,I=new EncodedVideoChunk({type:w?"key":"delta",timestamp:U,duration:m,data:t.payload,transfer:T});t.payload=Zv;try{b.decoder.decode(I)}catch(X){if(_("decode-error"))return;throw Jn(e),X}re&&Kt.get(e)===b&&b.interactivePipelineGuardTimestampUs===U&&Q&&yC(e,b,U,G),wb(e,b),PC(e,b)}async function jd(e,t,n,s,a,o="smooth",c=n,u){if(kC(t)){n()||EC(e,t,s,o,u);return}if(CC(t)){n()||Gp(e,t,s,a,o,c,!0,u);return}if(pc.delete(e),SC(t)){Jn(e);const w=AC(t);if(n())return;try{u?.(t)}catch{}(e.width!==w.width||e.height!==w.height)&&(e.width=w.width,e.height=w.height);const b=e.getContext("2d"),y=performance.now();b?.putImageData(w,0,0);const C=performance.now(),A=Sp(e,w.width,w.height,qp,64,t);s?.(t,{deviceId:t.deviceId,frameSeq:t.frameSeq,mode:t.frameMode||t.mode||t.codec||t.mimeType,width:w.width,height:w.height,byteLength:t.byteLength,queuedForMs:0,decodedForMs:0,scheduledForMs:0,drawMs:Math.max(0,C-y),queueSize:0,renderQueueSize:0,droppedForLatency:0,h264DecodeAcceleration:Is.h264DecodeAcceleration,decoderLabel:"lzo-rgb565",decoderFlushCount:0,decoderTimestampFallbacks:0,decoderInputCount:0,decoderOutputCount:0,targetPaintIntervalMs:0,canvasPresentation:"sync",interactiveBufferWaitCount:0,interactiveBufferWaitMs:0,interactiveQueueDrainCount:0,visualHash:A.visualHash,visualChanged:A.visualChanged,paintedAt:C});return}Jn(e);const d=new Blob([t.payload],{type:t.mimeType}),p=await createImageBitmap(d);if(n()){p.close();return}const f=t.width||p.width||960,m=t.height||p.height||540;try{u?.(t)}catch{}(e.width!==f||e.height!==m)&&(e.width=f,e.height=m);const g=e.getContext("2d");if(g){const w=performance.now();g.clearRect(0,0,f,m),g.drawImage(p,0,0,f,m);const b=performance.now(),y=Sp(e,f,m);s?.(t,{deviceId:t.deviceId,frameSeq:t.frameSeq,mode:t.frameMode||t.mode||t.codec||t.mimeType,width:f,height:m,byteLength:t.byteLength,queuedForMs:0,decodedForMs:0,scheduledForMs:0,drawMs:Math.max(0,b-w),queueSize:0,renderQueueSize:0,droppedForLatency:0,h264DecodeAcceleration:Is.h264DecodeAcceleration,decoderLabel:"image",decoderFlushCount:0,decoderTimestampFallbacks:0,decoderInputCount:0,decoderOutputCount:0,targetPaintIntervalMs:0,canvasPresentation:"sync",interactiveBufferWaitCount:0,interactiveBufferWaitMs:0,interactiveQueueDrainCount:0,visualHash:y.visualHash,visualChanged:y.visualChanged,paintedAt:b})}p.close()}function _C(e){queueMicrotask(e)}function LC(e){return e?(e.width=0,e.height=0,!0):!1}function Au(e,t){if(!e)return!1;try{t?.(e)}finally{LC(e)}return!0}function Kp(e,t){if(!e||!t)return 0;const n=Math.max(0,Number(e.get(t)||0))+1;return e.set(t,n),n}function OC(e,t){if(!e||!t)return 0;const n=Number(e.get(t)||0);return Number.isSafeInteger(n)&&n>0?n:Kp(e,t)}function ph(e,t){return Kp(e,t)}function mh(e,t,n){return!!e&&!!t&&Number(n)>0&&Number(e.get(t)||0)===Number(n)}function $C(e,t,n){if(!e||!e.has(t))return!1;const s=e.get(t);return e.delete(t),Au(s,n)}function BC(e,t,n){const s=new Set;for(const a of e||[])if(a){for(const o of a.values())o&&s.add(o);a.clear()}for(const a of t||[])a&&s.add(a);for(const a of s)Au(a,n);return s.size}function HC(e,{isCurrent:t,dispose:n,schedule:s=_C}){return!e||typeof t!="function"?!1:(s(()=>{t(e)||Au(e,n)}),!0)}const WC=new Uint8Array(0);function Va(e){if(!e||typeof e!="object")return e;const t=e.payload;return t instanceof Uint8Array&&t.byteLength===0?e:{...e,payload:WC}}function zC(e,t){const n=Va(t);return e.set(t.deviceId,n),n}function VC(e,t){for(const[n,s]of t.entries())e.set(n,Va(s));return t.clear(),new Map(e)}const qC=1500;function UC(e={}){const t=Math.max(10,Math.min(1e4,Number(e.closeDeadlineMs)||qC)),n=typeof e.setTimeout=="function"?e.setTimeout:setTimeout,s=typeof e.clearTimeout=="function"?e.clearTimeout:clearTimeout,a=new Set,o=new WeakMap;let c=0,u=0;const d=(p,f)=>{if(!p||p.settled)return!1;p.settled=!0,p.timer!==null&&(s(p.timer),p.timer=null);try{p.socket.removeEventListener?.("close",p.handleClose)}catch{}return a.delete(p),o.delete(p.entry),f&&(c+=1),!0};return Object.freeze({beginClosing(p,f="livedesk-frame-socket-release"){if(!p?.socket||o.has(p))return!1;const m=p.socket;if(Number(m.readyState)===3)return!1;const g={entry:p,socket:m,timer:null,settled:!1,handleClose:null};g.handleClose=()=>d(g,!1),o.set(p,g),a.add(g),u=Math.max(u,a.size);try{m.addEventListener?.("close",g.handleClose)}catch{}g.timer=n(()=>{if(!g.settled){try{m.close()}catch{}d(g,Number(m.readyState)!==3)}},t);try{Number(m.readyState)===0||Number(m.readyState)===1?m.close(1e3,f):m.close()}catch{try{m.close()}catch{}}return Number(m.readyState)===3&&d(g,!1),!0},snapshot(){return{closingSocketCount:a.size,closingSocketTimerCount:[...a].filter(p=>p.timer!==null).length,closingSocketTimeoutCount:c,maximumClosingSocketCount:u}}})}function GC(e,t="livedesk-frame-socket-release",n=null){if(!e)return 0;const s=[e],a=new Set;let o=0;for(;s.length>0;){const c=s.pop();if(!c||a.has(c))continue;a.add(c);const u=c.handoffFrom;c.handoffFrom=void 0,u&&!a.has(u)&&s.push(u);const d=c.disposed===!0;c.disposed=!0,c.handoffCompleted=!0;const p=c.detachListeners;c.detachListeners=void 0;try{p?.()}catch{}const f=c.releaseOwnedState;c.releaseOwnedState=void 0;try{f?.()}catch{}if(!d){if(n?.beginClosing)n.beginClosing(c,t);else try{c.socket.readyState===0||c.socket.readyState===1?c.socket.close(1e3,t):c.socket.close()}catch{try{c.socket.close()}catch{}}o+=1}}return o}const fh=Object.freeze(["nativeCaptureTelemetryAvailable","nativeCaptureTelemetryVersion","nativeEncoderHardwareAccelerationKnown","nativeEncoderHardwareAccelerated","nativeEncoderHardwareQueryStatus","nativeCaptureDisplayId","nativeCaptureFps","nativeCompressionFps","nativeEncodedFps","nativeCaptureSampleCount","nativeEncodableFrameCount","nativeSkippedFrameCount","nativeCompressionOutputCount","nativeEncodedFrameCount","nativeEncodeFramesInFlight","nativeEncodePendingFrameCount","nativeEncodeTimestampOwnerCount","nativeEncodeTimestampOwnerHighWatermark","nativeBackpressureCoalescedFrameCount","nativeBackpressureSkippedFrameCount","nativeEncodePendingReplacedFrameCount","nativeIdleSkippedFrameCount","nativeVideoToolboxActiveSessionCount","nativeVideoToolboxSessionHighWatermark","nativeOutputQueueDepth","nativeOutputQueueBytes","nativeOutputQueueOldestAgeMs","nativeOutputQueueHighWatermark","nativeOutputQueueDroppedCount","nativeOutputQueueAwaitingKeyFrame","nativeCopyTelemetryAvailable","nativeAnnexBAccessUnitAllocationCount","nativeAnnexBPayloadCopyCount","nativeAnnexBPayloadCopiedBytes","nativeAndPipeResidenceAgeMs","pipePayloadAllocationCount","pipePayloadCopyCount","pipePayloadCopiedBytes","handoffDroppedFrameCount","handoffRecoveryKeyFrameRequestCount","handoffOldestFrameAgeMs","nativeCaptureResourceTelemetryAvailable","nativeCaptureTelemetryAt"]),KC=Object.freeze(["nativeEncodeFramesInFlight","nativeEncodePendingFrameCount","nativeEncodeTimestampOwnerCount","nativeEncodeTimestampOwnerHighWatermark","nativeBackpressureCoalescedFrameCount","nativeBackpressureSkippedFrameCount","nativeEncodePendingReplacedFrameCount","nativeIdleSkippedFrameCount","nativeVideoToolboxActiveSessionCount","nativeVideoToolboxSessionHighWatermark","nativeOutputQueueDepth","nativeOutputQueueBytes","nativeOutputQueueOldestAgeMs","nativeOutputQueueHighWatermark","nativeOutputQueueDroppedCount","nativeOutputQueueAwaitingKeyFrame","nativeCopyTelemetryAvailable","nativeAnnexBAccessUnitAllocationCount","nativeAnnexBPayloadCopyCount","nativeAnnexBPayloadCopiedBytes","nativeAndPipeResidenceAgeMs","pipePayloadAllocationCount","pipePayloadCopyCount","pipePayloadCopiedBytes","handoffDroppedFrameCount","handoffRecoveryKeyFrameRequestCount","handoffOldestFrameAgeMs"]);function QC(e){return[String(e?.deviceId||""),String(e?.sessionId||""),String(e?.streamId||""),String(e?.commandId||""),String(Number(e?.captureGeneration||0)||0),String(Number.isFinite(Number(e?.monitorIndex))?Number(e.monitorIndex):-1),String(e?.streamPurpose||"")].join("\0")}function YC(e,t){return!!t&&String(e?.deviceId||"")===String(t.deviceId||"")&&String(e?.sessionId||"")===String(t.sessionId||"")&&String(e?.streamId||"")===String(t.streamId||"")&&String(e?.commandId||"")===String(t.commandId||"")&&(Number(e?.captureGeneration||0)||0)===(Number(t.captureGeneration||0)||0)&&(Number.isFinite(Number(e?.monitorIndex))?Number(e.monitorIndex):-1)===(Number.isFinite(Number(t.monitorIndex))?Number(t.monitorIndex):-1)&&String(e?.streamPurpose||"")===String(t.streamPurpose||"")}function XC(){return{ownerKey:"",values:Object.create(null)}}function hh(e){e&&(e.ownerKey="",e.values=Object.create(null))}function JC(e,t,n){if(!e||!t||!YC(e,n))return!1;const s=QC(n);if(t.ownerKey!==s&&(t.ownerKey=s,t.values=Object.create(null)),e.nativeCaptureTelemetryAvailable===!1){for(const a of fh)a!=="nativeCaptureTelemetryAvailable"&&(delete t.values[a],delete e[a]);return t.values.nativeCaptureTelemetryAvailable=!1,!0}if(e.nativeCaptureResourceTelemetryAvailable===!1)for(const a of KC)delete t.values[a],delete e[a];for(const a of fh)Object.prototype.hasOwnProperty.call(e,a)?t.values[a]=e[a]:Object.prototype.hasOwnProperty.call(t.values,a)&&(e[a]=t.values[a]);return!0}const xb=new ArrayBuffer(0);function ZC(e){return`${String(e?.streamId||"")}:${Number(e?.frameSeq||0)}`}function e0(e){return!e||typeof e!="object"||e.payload instanceof ArrayBuffer&&e.payload.byteLength===0?e:{...e,payload:xb}}function t0(){let e=null,t="";return{accept(n){e=e0(n)},publish(){const n=e;if(e=null,!n)return null;const s=ZC(n);return s===t?null:(t=s,n)},clear(){e=null,t=""},inspect(){return{pending:e?1:0,pendingPayloadBytes:Number(e?.payload?.byteLength||0),publishedKey:t}}}}const n0=0,r0=1,gh=3;function In(e){return Math.max(0,Math.floor(Number(e)||0))}function jr(e,t){return!t||t.active||t.socket!==null||t.audioContext!==null||t.statsTimer!==null||t.scheduledSourceCount!==0||t.pendingDecodeCount!==0||t.workletNodeCount!==0||t.workletPortCount!==0||t.pcmRingCapacityBytes!==0||t.pcmRingBufferedBytes!==0||t.pendingWorkletPacketCount!==0||t.pendingWorkletPacketBytes!==0||t.retainedFrameCount!==0||t.retainedPayloadBytes!==0?!1:e.delete(t)}function s0(){const e=new Set;let t=null;const n={ownerCount:0,socketCount:0,audioContextCount:0,workletNodeCount:0,workletPortCount:0},s=()=>{let a=0,o=0,c=0,u=0;for(const d of e){const p=Number(d.socket?.readyState);a+=d.socket&&p!==gh?1:0,o+=d.audioContext===null?0:1,c+=In(d.workletNodeCount),u+=In(d.workletPortCount)}n.ownerCount=Math.max(n.ownerCount,e.size),n.socketCount=Math.max(n.socketCount,a),n.audioContextCount=Math.max(n.audioContextCount,o),n.workletNodeCount=Math.max(n.workletNodeCount,c),n.workletPortCount=Math.max(n.workletPortCount,u)};return{createOwner({deviceId:a,socket:o,audioContext:c,statsTimer:u=null}){t=null;const d={deviceId:String(a||""),active:!0,socket:o||null,audioContext:c||null,statsTimer:u,scheduledSourceCount:0,pendingDecodeCount:0,workletNodeCount:0,workletPortCount:0,workletNodeCreateCount:0,pcmRingCapacityBytes:0,pcmRingBufferedBytes:0,pendingWorkletPacketCount:0,pendingWorkletPacketBytes:0,pendingWorkletPacketHighWater:0,pendingWorkletByteHighWater:0,retainedFrameCount:0,retainedPayloadBytes:0};return e.add(d),s(),d},recordTerminalFailure(a,o,c="playback"){return e.has(a)?(t={deviceId:a.deviceId,phase:String(c||"playback").slice(0,64),message:String(o||"Remote audio playback failed.").slice(0,512)},!0):!1},deactivate(a){return e.has(a)?(a.active=!1,jr(e,a)):!1},setSocket(a,o){return e.has(a)?(a.socket=o||null,s(),jr(e,a)):!1},setAudioContext(a,o){return e.has(a)?(a.audioContext=o||null,s(),jr(e,a)):!1},setStatsTimer(a,o){return e.has(a)?(a.statsTimer=o??null,jr(e,a)):!1},setScheduledSourceCount(a,o){return e.has(a)?(a.scheduledSourceCount=In(o),jr(e,a)):!1},setPendingDecodeCount(a,o){return e.has(a)?(a.pendingDecodeCount=In(o),jr(e,a)):!1},setWorkletNode(a,o,c,u=a?.workletNodeCreateCount){return e.has(a)?(a.workletNodeCount=In(o),a.workletPortCount=In(c),a.workletNodeCreateCount=In(u),s(),jr(e,a)):!1},setPcmRing(a,o,c){return e.has(a)?(a.pcmRingCapacityBytes=In(o),a.pcmRingBufferedBytes=Math.min(a.pcmRingCapacityBytes,In(c)),jr(e,a)):!1},setPendingWorkletPackets(a,o,c,u=a?.pendingWorkletPacketHighWater,d=a?.pendingWorkletByteHighWater){return e.has(a)?(a.pendingWorkletPacketCount=In(o),a.pendingWorkletPacketBytes=In(c),a.pendingWorkletPacketHighWater=Math.max(a.pendingWorkletPacketHighWater,In(u)),a.pendingWorkletByteHighWater=Math.max(a.pendingWorkletByteHighWater,In(d)),jr(e,a)):!1},setRetainedFrame(a,o,c=0){return e.has(a)?(a.retainedFrameCount=In(o),a.retainedPayloadBytes=In(c),jr(e,a)):!1},releaseIfDrained(a){return jr(e,a)},hasOwner(a){return e.has(a)},snapshot(){const a=[...e].map(c=>{const u=Number(c.socket?.readyState),d=c.socket&&u!==gh?1:0;return{deviceId:c.deviceId,active:c.active,socketCount:d,openSocketCount:u===r0?1:0,connectingSocketCount:u===n0?1:0,audioContextCount:c.audioContext===null?0:1,statsTimerCount:c.statsTimer===null?0:1,scheduledSourceCount:c.scheduledSourceCount,pendingDecodeCount:c.pendingDecodeCount,workletNodeCount:c.workletNodeCount,workletPortCount:c.workletPortCount,workletNodeCreateCount:c.workletNodeCreateCount,pcmRingCapacityBytes:c.pcmRingCapacityBytes,pcmRingBufferedBytes:c.pcmRingBufferedBytes,pendingWorkletPacketCount:c.pendingWorkletPacketCount,pendingWorkletPacketBytes:c.pendingWorkletPacketBytes,pendingWorkletPacketHighWater:c.pendingWorkletPacketHighWater,pendingWorkletByteHighWater:c.pendingWorkletByteHighWater,retainedFrameCount:c.retainedFrameCount,retainedPayloadBytes:c.retainedPayloadBytes}}),o=c=>a.reduce((u,d)=>u+In(d[c]),0);return{ownerCount:a.length,activeOwnerCount:a.filter(c=>c.active).length,socketCount:o("socketCount"),openSocketCount:o("openSocketCount"),connectingSocketCount:o("connectingSocketCount"),audioContextCount:o("audioContextCount"),statsTimerCount:o("statsTimerCount"),scheduledSourceCount:o("scheduledSourceCount"),pendingDecodeCount:o("pendingDecodeCount"),workletNodeCount:o("workletNodeCount"),workletPortCount:o("workletPortCount"),workletNodeCreateCount:o("workletNodeCreateCount"),pcmRingCapacityBytes:o("pcmRingCapacityBytes"),pcmRingBufferedBytes:o("pcmRingBufferedBytes"),pendingWorkletPacketCount:o("pendingWorkletPacketCount"),pendingWorkletPacketBytes:o("pendingWorkletPacketBytes"),pendingWorkletPacketHighWater:o("pendingWorkletPacketHighWater"),pendingWorkletByteHighWater:o("pendingWorkletByteHighWater"),retainedFrameCount:o("retainedFrameCount"),retainedPayloadBytes:o("retainedPayloadBytes"),ownerHighWater:n.ownerCount,socketHighWater:n.socketCount,audioContextHighWater:n.audioContextCount,workletNodeHighWater:n.workletNodeCount,workletPortHighWater:n.workletPortCount,lastTerminalFailure:t,owners:a}}}}const Zt=s0();function a0(){let e=Promise.resolve(),t=0,n=0,s=0;return{acquire(a){const o=++s;let c=!1,u=!1,d=!1,p;const f=new Promise(b=>{p=b}),m=Promise.resolve(e).catch(()=>{});e=m.then(()=>f);const g=()=>d?!1:(d=!0,c&&(t=Math.max(0,t-1)),p(),!0),w=m.then(async()=>{if(u||d)return g(),null;c=!0,t+=1,n=Math.max(n,t);try{return await a({ownerId:o,release:g})}catch(b){throw g(),b}});return{ownerId:o,ready:w,release:g,cancel(){u=!0,c||g()}}},snapshot(){return{activeOwnerCount:t,ownerHighWater:n,nextOwnerId:s}}}}const o0=a0(),vh=1e3;function i0({enabled:e,now:t,lastPublishedAt:n,intervalMs:s=vh}){if(!e)return!1;const a=Math.max(0,Number(t)||0),o=Math.max(0,Number(n)||0),c=Math.max(1,Number(s)||vh);return o<=0||a-o>=c}const Sb="livedesk-remote-audio-v1",c0=250,l0=160,Cp=4;function u0(e){const t=String(e||"").toLowerCase();return t.includes("audio/pcm")||t.includes("f32le")||t.includes("s16le")}function kp(e={},t={}){const n=String(t.deviceId||""),s=String(t.streamId||"");return!!n&&!!s&&String(e.deviceId||"")===n&&String(e.streamId||"")===s}function d0(e={},t={}){if(!kp(e,t))return{accepted:!1,reason:"owner-mismatch",nextFrameSeq:Math.max(0,Math.floor(Number(t.lastFrameSeq)||0))};const n=Math.max(0,Math.floor(Number(e.frameSeq)||0)),s=Math.max(0,Math.floor(Number(t.lastFrameSeq)||0));return n>0&&n<=s?{accepted:!1,reason:"sequence-not-newer",nextFrameSeq:s}:{accepted:!0,reason:"",nextFrameSeq:n}}function p0(e={}){const t=String(e.capturePhase||"").toLowerCase(),n=String(e.backendKind||"").toLowerCase(),s=e.captureAlive===!0?!0:e.captureAlive===!1?!1:null,a=e.helperAlive===!0?!0:e.helperAlive===!1?!1:null,o=Math.max(0,Math.floor(Number(e.helperPid)||0)),c=n==="windows-wasapi-in-process",u=n==="macos-screencapturekit-helper"||n==="linux-system-audio-helper",d=c||u,p=e.helperRequired===!0?!0:e.helperRequired===!1?!1:u?!0:c?!1:null,f=p===!1?!0:p===!0?a===!0&&o>0:!1,m=t==="starting"||t==="capture-active-awaiting-current-pcm",g=t==="active"&&s===!0&&d&&f,w=t==="failed"||t==="stopped"||s===!1||t==="active"&&(!d||!f);let b="";return m?b="awaiting-current-pcm":!c&&!u?b="backend-unknown":t!=="active"?b=t?`phase-${t}`:"phase-unknown":s!==!0?b="capture-not-alive":p===!0&&a!==!0?b="external-helper-not-alive":p===!0&&o<=0&&(b="external-helper-pid-missing"),{capturePhase:t,backendKind:n,captureAlive:s,helperAlive:a,helperPid:o,helperRequired:p,inProcessBackend:c,externalHelperBackend:u,backendKnown:d,helperReady:f,awaitingCurrentPcm:m,healthy:g,failed:w,reason:b}}function aa(e,t){const n=Math.floor(Number(e));return Number.isFinite(n)&&n>0?n:t}function Qp(e={}){const t=Math.max(8e3,Math.min(192e3,aa(e.sampleRate,48e3))),n=Math.max(1,Math.min(8,aa(e.channels,2))),s=String(e.mimeType||"").toLowerCase(),o=String(e.sampleFormat||"").toLowerCase()==="s16le"||s.includes("s16le")||s.includes("audio/l16")?"s16le":"f32le";return{sampleRate:t,channels:n,sampleFormat:o}}function Yp(e={}){const t=Qp(e),n=Math.max(1,Math.min(250,aa(e.maxDurationMs,250))),s=Math.max(1,Math.ceil(t.sampleRate*n/1e3));return{...t,maxDurationMs:n,capacityFrames:s,capacityBytes:s*t.channels*Float32Array.BYTES_PER_ELEMENT}}function m0(e={}){const t=Yp(e),n=Math.max(0,Math.min(t.maxDurationMs,aa(e.targetLeadMs,160))),s=Math.min(t.capacityFrames,Math.max(1,Math.ceil(t.sampleRate*n/1e3)));let a=new Float32Array(t.capacityFrames*t.channels),o=0,c=0,u=0,d=0,p=!1,f=!1,m=0,g=0,w=0;const b={acceptedFrames:0,droppedFrames:0},y=()=>(w+=1,{sampleRate:t.sampleRate,channels:t.channels,sampleFormat:t.sampleFormat,maxDurationMs:t.maxDurationMs,targetLeadMs:n,capacityFrames:f?0:t.capacityFrames,capacityBytes:f?0:t.capacityBytes,bufferedFrames:f?0:u,bufferedBytes:f?0:u*t.channels*Float32Array.BYTES_PER_ELEMENT,bufferedMs:f?0:u*1e3/t.sampleRate,droppedFrames:m,underflowCount:g,started:!f&&p,disposed:f}),C=()=>{o=0,c=0,u=0,d=0,p=!1},A=()=>{f||(C(),a=new Float32Array(0),f=!0)},k=(E,L=0,M,U=t.sampleFormat)=>{if(b.acceptedFrames=0,b.droppedFrames=0,f||!(E instanceof ArrayBuffer))return b;const V=Math.max(0,Math.floor(Number(L)||0)),T=Math.max(0,E.byteLength-V),j=Math.min(T,Math.max(0,Math.floor(Number(M??T)||0))),$=U==="s16le",Q=$?2:4,G=Q*t.channels,q=Math.floor(j/G);if(q<=0)return b;const re=Math.min(q,t.capacityFrames),I=q-re,X=Math.max(0,u+re-t.capacityFrames);X>0&&(o=(o+X)%t.capacityFrames,u-=X);const le=I+X;m+=le;const K=new DataView(E,V,j);for(let ue=I;ue<q;ue+=1){const se=c*t.channels,ve=ue*t.channels;for(let Me=0;Me<t.channels;Me+=1){const ke=(ve+Me)*Q,pe=$?K.getInt16(ke,!0)/32768:K.getFloat32(ke,!0);a[se+Me]=Number.isFinite(pe)?Math.max(-1,Math.min(1,pe)):0}c=(c+1)%t.capacityFrames}return u+=re,!p&&u>=s&&(p=!0),b.acceptedFrames=re,b.droppedFrames=le,b};return{writePcm:(E={})=>k(E.buffer,E.byteOffset,E.byteLength,E.sampleFormat),writePcmBuffer:k,readToChannels:(E,L=t.sampleRate)=>{if(!Array.isArray(E)||E.length===0)return;let M=Number.POSITIVE_INFINITY;for(let T=0;T<E.length;T+=1){const j=E[T];M=Math.min(M,j?.length||0)}if(f||!Number.isFinite(M)||M<=0||!p){for(let T=0;T<E.length;T+=1)E[T]?.fill?.(0);return}const U=Math.max(8e3,Math.min(192e3,aa(L,t.sampleRate))),V=t.sampleRate/U;for(let T=0;T<M;T+=1){if(u<=0){p=!1,g+=1,d=0;for(let Q=0;Q<E.length;Q+=1)E[Q].fill(0,T);break}const j=o*t.channels;for(let Q=0;Q<E.length;Q+=1){const G=Math.min(Q,t.channels-1);E[Q][T]=a[j+G]}d+=V;const $=Math.min(u,Math.floor(d));$>0&&(o=(o+$)%t.capacityFrames,u-=$,d-=$)}},flush:C,dispose:A,snapshot:y,getSnapshotCount:()=>w}}function f0(e={}){const t=Math.max(1,Math.min(Cp,aa(e.maxPendingPackets,Cp))),n=Math.max(1,aa(e.maxPendingBytes,1)),s=new Map;let a=0,o=0,c=0,u=0,d=0,p=!1;const f=()=>({terminal:p,maxPendingPackets:t,maxPendingBytes:n,pendingPacketCount:s.size,pendingPacketBytes:a,pendingPacketHighWater:o,pendingByteHighWater:c,acceptedCount:u,droppedCount:d});return{claim(m,g){const w=typeof m=="number"&&Number.isFinite(m)?m:String(m||""),b=Math.max(0,Math.floor(Number(g)||0));return p||!w||b<=0||s.has(w)||s.size>=t||a+b>n?(d+=1,!1):(s.set(w,b),a+=b,o=Math.max(o,s.size),c=Math.max(c,a),u+=1,!0)},acknowledge(m){const g=typeof m=="number"&&Number.isFinite(m)?m:String(m||""),w=s.get(g);return w===void 0?!1:(s.delete(g),a=Math.max(0,a-w),!0)},terminate(){return s.clear(),a=0,p=!0,f()},getPendingPacketCount:()=>s.size,getPendingPacketBytes:()=>a,getPendingPacketHighWater:()=>o,getPendingByteHighWater:()=>c,snapshot:f}}function Ru(e,t){const n=String(e?.name||"");if(!/^[A-Za-z_$][A-Za-z0-9_$]*$/.test(n)||!/^[A-Za-z_$][A-Za-z0-9_$]*$/.test(t))throw new Error("Remote Audio worklet function binding name is invalid.");const s=`const ${n} = ${Function.prototype.toString.call(e)};`;return n===t?s:`${s}
|
|
4
4
|
const ${t} = ${n};`}const h0=Ru(aa,"positiveInteger"),g0=Ru(Qp,"normalizeRemoteAudioPcmFormat"),v0=Ru(Yp,"remoteAudioPcmRingCapacity"),b0=Ru(m0,"createRemoteAudioPcmRing"),w0=`
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/LiveDeskApp-
|
|
1
|
+
const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/LiveDeskApp-HaQ9U3be.js","assets/icons-tFaWqIIe.js","assets/supabase-C7qjtLN3.js","assets/react-BQos8uGS.js","assets/LiveDeskApp-ChGXEkMA.css"])))=>i.map(i=>d[i]);
|
|
2
2
|
import{r as Ov,a as jn,A as Ut,M as Uv,C as Cd,S as _v,E as Bd,b as Sf,c as Wd,L as Mf,T as Nf,d as ku,e as $d,f as $u,W as Hv,R as Cv,g as Bv,D as Dt,N as Fd,h as qv,i as Rv,j as qd,k as wv,G as Id,l as Yv}from"./icons-tFaWqIIe.js";import{r as Gv}from"./react-BQos8uGS.js";(function(){const r=document.createElement("link").relList;if(r&&r.supports&&r.supports("modulepreload"))return;for(const T of document.querySelectorAll('link[rel="modulepreload"]'))s(T);new MutationObserver(T=>{for(const E of T)if(E.type==="childList")for(const A of E.addedNodes)A.tagName==="LINK"&&A.rel==="modulepreload"&&s(A)}).observe(document,{childList:!0,subtree:!0});function v(T){const E={};return T.integrity&&(E.integrity=T.integrity),T.referrerPolicy&&(E.referrerPolicy=T.referrerPolicy),T.crossOrigin==="use-credentials"?E.credentials="include":T.crossOrigin==="anonymous"?E.credentials="omit":E.credentials="same-origin",E}function s(T){if(T.ep)return;T.ep=!0;const E=v(T);fetch(T.href,E)}})();const Lv="modulepreload",Xv=function(d){return"/"+d},Rd={},Qv=function(r,v,s){let T=Promise.resolve();if(v&&v.length>0){let C=function(w){return Promise.all(w.map(ll=>Promise.resolve(ll).then(D=>({status:"fulfilled",value:D}),D=>({status:"rejected",reason:D}))))};document.getElementsByTagName("link");const A=document.querySelector("meta[property=csp-nonce]"),H=A?.nonce||A?.getAttribute("nonce");T=C(v.map(w=>{if(w=Xv(w),w in Rd)return;Rd[w]=!0;const ll=w.endsWith(".css"),D=ll?'[rel="stylesheet"]':"";if(document.querySelector(`link[href="${w}"]${D}`))return;const K=document.createElement("link");if(K.rel=ll?"stylesheet":Lv,ll||(K.as="script"),K.crossOrigin="",K.href=w,H&&K.setAttribute("nonce",H),document.head.appendChild(K),ll)return new Promise((Zl,Cl)=>{K.addEventListener("load",Zl),K.addEventListener("error",()=>Cl(new Error(`Unable to preload CSS for ${w}`)))})}))}function E(A){const H=new Event("vite:preloadError",{cancelable:!0});if(H.payload=A,window.dispatchEvent(H),!H.defaultPrevented)throw A}return T.then(A=>{for(const H of A||[])H.status==="rejected"&&E(H.reason);return r().catch(E)})};var bf={exports:{}},Sn={};var wd;function Vv(){if(wd)return Sn;wd=1;var d=Symbol.for("react.transitional.element"),r=Symbol.for("react.fragment");function v(s,T,E){var A=null;if(E!==void 0&&(A=""+E),T.key!==void 0&&(A=""+T.key),"key"in T){E={};for(var H in T)H!=="key"&&(E[H]=T[H])}else E=T;return T=E.ref,{$$typeof:d,type:s,key:A,ref:T!==void 0?T:null,props:E}}return Sn.Fragment=r,Sn.jsx=v,Sn.jsxs=v,Sn}var Yd;function Zv(){return Yd||(Yd=1,bf.exports=Vv()),bf.exports}var c=Zv(),pf={exports:{}},bn={},xf={exports:{}},jf={};var Gd;function Kv(){return Gd||(Gd=1,(function(d){function r(j,M){var B=j.length;j.push(M);l:for(;0<B;){var tl=B-1>>>1,al=j[tl];if(0<T(al,M))j[tl]=M,j[B]=al,B=tl;else break l}}function v(j){return j.length===0?null:j[0]}function s(j){if(j.length===0)return null;var M=j[0],B=j.pop();if(B!==M){j[0]=B;l:for(var tl=0,al=j.length,El=al>>>1;tl<El;){var cl=2*(tl+1)-1,k=j[cl],gl=cl+1,re=j[gl];if(0>T(k,B))gl<al&&0>T(re,k)?(j[tl]=re,j[gl]=B,tl=gl):(j[tl]=k,j[cl]=B,tl=cl);else if(gl<al&&0>T(re,B))j[tl]=re,j[gl]=B,tl=gl;else break l}}return M}function T(j,M){var B=j.sortIndex-M.sortIndex;return B!==0?B:j.id-M.id}if(d.unstable_now=void 0,typeof performance=="object"&&typeof performance.now=="function"){var E=performance;d.unstable_now=function(){return E.now()}}else{var A=Date,H=A.now();d.unstable_now=function(){return A.now()-H}}var C=[],w=[],ll=1,D=null,K=3,Zl=!1,Cl=!1,Kl=!1,Ht=!1,Ct=typeof setTimeout=="function"?setTimeout:null,za=typeof clearTimeout=="function"?clearTimeout:null,Jl=typeof setImmediate<"u"?setImmediate:null;function qe(j){for(var M=v(w);M!==null;){if(M.callback===null)s(w);else if(M.startTime<=j)s(w),M.sortIndex=M.expirationTime,r(C,M);else break;M=v(w)}}function st(j){if(Kl=!1,qe(j),!Cl)if(v(C)!==null)Cl=!0,oe||(oe=!0,kl());else{var M=v(w);M!==null&&ge(st,M.startTime-j)}}var oe=!1,ye=-1,ue=5,Bt=-1;function An(){return Ht?!0:!(d.unstable_now()-Bt<ue)}function qt(){if(Ht=!1,oe){var j=d.unstable_now();Bt=j;var M=!0;try{l:{Cl=!1,Kl&&(Kl=!1,za(ye),ye=-1),Zl=!0;var B=K;try{e:{for(qe(j),D=v(C);D!==null&&!(D.expirationTime>j&&An());){var tl=D.callback;if(typeof tl=="function"){D.callback=null,K=D.priorityLevel;var al=tl(D.expirationTime<=j);if(j=d.unstable_now(),typeof al=="function"){D.callback=al,qe(j),M=!0;break e}D===v(C)&&s(C),qe(j)}else s(C);D=v(C)}if(D!==null)M=!0;else{var El=v(w);El!==null&&ge(st,El.startTime-j),M=!1}}break l}finally{D=null,K=B,Zl=!1}M=void 0}}finally{M?kl():oe=!1}}}var kl;if(typeof Jl=="function")kl=function(){Jl(qt)};else if(typeof MessageChannel<"u"){var Mn=new MessageChannel,Ta=Mn.port2;Mn.port1.onmessage=qt,kl=function(){Ta.postMessage(null)}}else kl=function(){Ct(qt,0)};function ge(j,M){ye=Ct(function(){j(d.unstable_now())},M)}d.unstable_IdlePriority=5,d.unstable_ImmediatePriority=1,d.unstable_LowPriority=4,d.unstable_NormalPriority=3,d.unstable_Profiling=null,d.unstable_UserBlockingPriority=2,d.unstable_cancelCallback=function(j){j.callback=null},d.unstable_forceFrameRate=function(j){0>j||125<j?console.error("forceFrameRate takes a positive int between 0 and 125, forcing frame rates higher than 125 fps is not supported"):ue=0<j?Math.floor(1e3/j):5},d.unstable_getCurrentPriorityLevel=function(){return K},d.unstable_next=function(j){switch(K){case 1:case 2:case 3:var M=3;break;default:M=K}var B=K;K=M;try{return j()}finally{K=B}},d.unstable_requestPaint=function(){Ht=!0},d.unstable_runWithPriority=function(j,M){switch(j){case 1:case 2:case 3:case 4:case 5:break;default:j=3}var B=K;K=j;try{return M()}finally{K=B}},d.unstable_scheduleCallback=function(j,M,B){var tl=d.unstable_now();switch(typeof B=="object"&&B!==null?(B=B.delay,B=typeof B=="number"&&0<B?tl+B:tl):B=tl,j){case 1:var al=-1;break;case 2:al=250;break;case 5:al=1073741823;break;case 4:al=1e4;break;default:al=5e3}return al=B+al,j={id:ll++,callback:M,priorityLevel:j,startTime:B,expirationTime:al,sortIndex:-1},B>tl?(j.sortIndex=B,r(w,j),v(C)===null&&j===v(w)&&(Kl?(za(ye),ye=-1):Kl=!0,ge(st,B-tl))):(j.sortIndex=al,r(C,j),Cl||Zl||(Cl=!0,oe||(oe=!0,kl()))),j},d.unstable_shouldYield=An,d.unstable_wrapCallback=function(j){var M=K;return function(){var B=K;K=M;try{return j.apply(this,arguments)}finally{K=B}}}})(jf)),jf}var Ld;function Jv(){return Ld||(Ld=1,xf.exports=Kv()),xf.exports}var Xd;function kv(){if(Xd)return bn;Xd=1;var d=Jv(),r=Ov(),v=Gv();function s(l){var e="https://react.dev/errors/"+l;if(1<arguments.length){e+="?args[]="+encodeURIComponent(arguments[1]);for(var t=2;t<arguments.length;t++)e+="&args[]="+encodeURIComponent(arguments[t])}return"Minified React error #"+l+"; visit "+e+" for the full message or use the non-minified dev environment for full errors and additional helpful warnings."}function T(l){return!(!l||l.nodeType!==1&&l.nodeType!==9&&l.nodeType!==11)}function E(l){var e=l,t=l;if(l.alternate)for(;e.return;)e=e.return;else{l=e;do e=l,(e.flags&4098)!==0&&(t=e.return),l=e.return;while(l)}return e.tag===3?t:null}function A(l){if(l.tag===13){var e=l.memoizedState;if(e===null&&(l=l.alternate,l!==null&&(e=l.memoizedState)),e!==null)return e.dehydrated}return null}function H(l){if(l.tag===31){var e=l.memoizedState;if(e===null&&(l=l.alternate,l!==null&&(e=l.memoizedState)),e!==null)return e.dehydrated}return null}function C(l){if(E(l)!==l)throw Error(s(188))}function w(l){var e=l.alternate;if(!e){if(e=E(l),e===null)throw Error(s(188));return e!==l?null:l}for(var t=l,a=e;;){var n=t.return;if(n===null)break;var u=n.alternate;if(u===null){if(a=n.return,a!==null){t=a;continue}break}if(n.child===u.child){for(u=n.child;u;){if(u===t)return C(n),l;if(u===a)return C(n),e;u=u.sibling}throw Error(s(188))}if(t.return!==a.return)t=n,a=u;else{for(var i=!1,f=n.child;f;){if(f===t){i=!0,t=n,a=u;break}if(f===a){i=!0,a=n,t=u;break}f=f.sibling}if(!i){for(f=u.child;f;){if(f===t){i=!0,t=u,a=n;break}if(f===a){i=!0,a=u,t=n;break}f=f.sibling}if(!i)throw Error(s(189))}}if(t.alternate!==a)throw Error(s(190))}if(t.tag!==3)throw Error(s(188));return t.stateNode.current===t?l:e}function ll(l){var e=l.tag;if(e===5||e===26||e===27||e===6)return l;for(l=l.child;l!==null;){if(e=ll(l),e!==null)return e;l=l.sibling}return null}var D=Object.assign,K=Symbol.for("react.element"),Zl=Symbol.for("react.transitional.element"),Cl=Symbol.for("react.portal"),Kl=Symbol.for("react.fragment"),Ht=Symbol.for("react.strict_mode"),Ct=Symbol.for("react.profiler"),za=Symbol.for("react.consumer"),Jl=Symbol.for("react.context"),qe=Symbol.for("react.forward_ref"),st=Symbol.for("react.suspense"),oe=Symbol.for("react.suspense_list"),ye=Symbol.for("react.memo"),ue=Symbol.for("react.lazy"),Bt=Symbol.for("react.activity"),An=Symbol.for("react.memo_cache_sentinel"),qt=Symbol.iterator;function kl(l){return l===null||typeof l!="object"?null:(l=qt&&l[qt]||l["@@iterator"],typeof l=="function"?l:null)}var Mn=Symbol.for("react.client.reference");function Ta(l){if(l==null)return null;if(typeof l=="function")return l.$$typeof===Mn?null:l.displayName||l.name||null;if(typeof l=="string")return l;switch(l){case Kl:return"Fragment";case Ct:return"Profiler";case Ht:return"StrictMode";case st:return"Suspense";case oe:return"SuspenseList";case Bt:return"Activity"}if(typeof l=="object")switch(l.$$typeof){case Cl:return"Portal";case Jl:return l.displayName||"Context";case za:return(l._context.displayName||"Context")+".Consumer";case qe:var e=l.render;return l=l.displayName,l||(l=e.displayName||e.name||"",l=l!==""?"ForwardRef("+l+")":"ForwardRef"),l;case ye:return e=l.displayName||null,e!==null?e:Ta(l.type)||"Memo";case ue:e=l._payload,l=l._init;try{return Ta(l(e))}catch{}}return null}var ge=Array.isArray,j=r.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE,M=v.__DOM_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE,B={pending:!1,data:null,method:null,action:null},tl=[],al=-1;function El(l){return{current:l}}function cl(l){0>al||(l.current=tl[al],tl[al]=null,al--)}function k(l,e){al++,tl[al]=l.current,l.current=e}var gl=El(null),re=El(null),Re=El(null),Nn=El(null);function Dn(l,e){switch(k(Re,e),k(re,l),k(gl,null),e.nodeType){case 9:case 11:l=(l=e.documentElement)&&(l=l.namespaceURI)?ad(l):0;break;default:if(l=e.tagName,e=e.namespaceURI)e=ad(e),l=nd(e,l);else switch(l){case"svg":l=1;break;case"math":l=2;break;default:l=0}}cl(gl),k(gl,l)}function Rt(){cl(gl),cl(re),cl(Re)}function Iu(l){l.memoizedState!==null&&k(Nn,l);var e=gl.current,t=nd(e,l.type);e!==t&&(k(re,l),k(gl,t))}function On(l){re.current===l&&(cl(gl),cl(re)),Nn.current===l&&(cl(Nn),mn._currentValue=B)}var Pu,_f;function ot(l){if(Pu===void 0)try{throw Error()}catch(t){var e=t.stack.trim().match(/\n( *(at )?)/);Pu=e&&e[1]||"",_f=-1<t.stack.indexOf(`
|
|
3
3
|
at`)?" (<anonymous>)":-1<t.stack.indexOf("@")?"@unknown:0:0":""}return`
|
|
4
4
|
`+Pu+l+_f}var li=!1;function ei(l,e){if(!l||li)return"";li=!0;var t=Error.prepareStackTrace;Error.prepareStackTrace=void 0;try{var a={DetermineComponentFrameRoot:function(){try{if(e){var z=function(){throw Error()};if(Object.defineProperty(z.prototype,"props",{set:function(){throw Error()}}),typeof Reflect=="object"&&Reflect.construct){try{Reflect.construct(z,[])}catch(b){var S=b}Reflect.construct(l,[],z)}else{try{z.call()}catch(b){S=b}l.call(z.prototype)}}else{try{throw Error()}catch(b){S=b}(z=l())&&typeof z.catch=="function"&&z.catch(function(){})}}catch(b){if(b&&S&&typeof b.stack=="string")return[b.stack,S.stack]}return[null,null]}};a.DetermineComponentFrameRoot.displayName="DetermineComponentFrameRoot";var n=Object.getOwnPropertyDescriptor(a.DetermineComponentFrameRoot,"name");n&&n.configurable&&Object.defineProperty(a.DetermineComponentFrameRoot,"name",{value:"DetermineComponentFrameRoot"});var u=a.DetermineComponentFrameRoot(),i=u[0],f=u[1];if(i&&f){var o=i.split(`
|
|
@@ -11,4 +11,4 @@ Error generating stack: `+a.message+`
|
|
|
11
11
|
${this.session.accessToken}`:"",s=r?`${r.user.id}
|
|
12
12
|
${r.accessToken}`:"";this.session=r,v!==s&&this.disconnect("console-session-replaced")}preferRelay(){this.relayPreferred=!0}markDirectReachable(){this.relayPreferred=!1}resume(){this.session&&this.disconnect("console-resume")}shouldUseRelay(){return this.relayPreferred&&!!this.session?.accessToken}disconnect(r){const v=this.connectOwner;this.connectOwner=null,this.connectGeneration+=1,this.ready=!1,this.connectPromise=null;const s=this.socket;this.socket=null,v?.reject(new Error(r));try{s?.close(1e3,r)}catch{}this.failPending(new Error(r)),this.closeChannels(1006,r)}failPending(r){for(const[v,s]of this.pendingHttp)window.clearTimeout(s.timeout),s.detachAbort(),s.reject(r),this.pendingHttp.delete(v)}closeChannels(r,v){for(const s of[...this.channels.values()])s.relayClosed(r,v);this.channels.clear()}handleTextMessage(r){let v;try{v=JSON.parse(r)}catch{return}if(v.type==="relay-ready"&&v.role==="console"){this.ready=!0;return}if(v.type==="hub-offline"){this.closeChannels(1012,"hub-offline");return}const s=String(v.channelId||"");if(!s)return;const T=this.pendingHttp.get(s);if(v.type==="http-response"&&T){this.pendingHttp.delete(s),window.clearTimeout(T.timeout),T.detachAbort();const E=Number(v.status||502),A=v.bodyBase64?uy(v.bodyBase64):new TextEncoder().encode(JSON.stringify({ok:!1,error:v.error||"console-relay-failed"}));T.resolve(new Response(A,{status:E,statusText:String(v.statusText||""),headers:v.headers||{"content-type":"application/json"}}));return}if(v.type==="relay-error"&&T){this.pendingHttp.delete(s),window.clearTimeout(T.timeout),T.detachAbort(),T.reject(new Error(v.error||"console-relay-failed"));return}this.channels.get(s)?.relayMessage(v)}handleBinaryMessage(r){if(r.byteLength<zf)return;const v=new TextDecoder().decode(new Uint8Array(r,0,zf));if(v[0]!=="B")return;const s=v.slice(37,73);this.channels.get(s)?.relayBinary(r.slice(zf))}async connect(){if(this.socket?.readyState===WebSocket.OPEN&&this.ready)return;if(this.connectPromise)return this.connectPromise;const r=String(this.session?.accessToken||"");if(!r)throw new Error("Sign in before using the mobile Console relay.");const v=++this.connectGeneration,s=Pv();this.connectOwner=s,this.connectPromise=s.promise.finally(()=>{this.connectOwner===s&&(this.connectOwner=null),v===this.connectGeneration&&(this.connectPromise=null)});try{const T=new WebSocket(ay(),[Pd,`${ey}${r}`]);T.binaryType="arraybuffer",this.socket=T;const E=window.setTimeout(()=>{if(!s.settled){try{T.close(1e3,"console-relay-connect-timeout")}catch{}s.reject(new Error("Mobile Console relay connection timed out."))}},ty);s.bindTimeout(E),T.addEventListener("message",A=>{if(!(v!==this.connectGeneration||this.socket!==T))if(typeof A.data=="string"){this.handleTextMessage(A.data);let H=null;try{H=JSON.parse(A.data)}catch{H=null}!s.settled&&H?.type==="relay-ready"&&H.role==="console"&&s.resolve()}else A.data instanceof ArrayBuffer&&this.handleBinaryMessage(A.data)}),T.addEventListener("error",()=>{s.reject(new Error("Mobile Console relay connection failed."))}),T.addEventListener("close",A=>{v!==this.connectGeneration||this.socket!==T||(this.socket=null,this.ready=!1,this.connectPromise=null,this.failPending(new Error(`Mobile Console relay closed (${A.code}).`)),this.closeChannels(A.code||1006,A.reason||"console-relay-closed"),s.reject(new Error(`Mobile Console relay closed (${A.code}).`)))})}catch(T){s.reject(T)}return this.connectPromise}send(r){if(!this.socket||this.socket.readyState!==WebSocket.OPEN||!this.ready)throw new Error("Mobile Console relay is not connected.");this.socket.send(JSON.stringify(r))}async fetch(r,v,s){await this.connect();const T=crypto.randomUUID(),E=await iy(v?.body),A=new Promise((H,C)=>{const w=()=>{const D=this.pendingHttp.get(T);D&&(this.pendingHttp.delete(T),window.clearTimeout(D.timeout),C(v?.signal?.reason instanceof Error?v.signal.reason:new Error("Mobile Console request cancelled.")))};v?.signal?.addEventListener("abort",w,{once:!0});const ll=window.setTimeout(()=>{const D=this.pendingHttp.get(T);D&&(this.pendingHttp.delete(T),D.detachAbort(),C(new Error("Mobile Console request timed out.")))},s);this.pendingHttp.set(T,{resolve:H,reject:C,timeout:ll,detachAbort:()=>v?.signal?.removeEventListener("abort",w)})});try{this.send({type:"http-request",channelId:T,method:String(v?.method||"GET").toUpperCase(),path:r,headers:cy(v),bodyBase64:E.byteLength>0?ny(E):""})}catch(H){const C=this.pendingHttp.get(T);C&&(this.pendingHttp.delete(T),window.clearTimeout(C.timeout),C.detachAbort(),C.reject(H instanceof Error?H:new Error(String(H))))}return A}openWebSocket(r){const v=new sy(this,r);return this.channels.set(v.channelId,v),this.connect().then(()=>{this.channels.get(v.channelId)===v&&this.send({type:"ws-open",channelId:v.channelId,path:r})}).catch(s=>v.relayError(s instanceof Error?s.message:String(s))),v}removeChannel(r){this.channels.delete(r)}bufferedAmount(){return Number(this.socket?.bufferedAmount||0)}}class sy extends EventTarget{constructor(r,v){super(),this.relay=r,this.url=v}relay;channelId=crypto.randomUUID();url;protocol=Pd;extensions="";binaryType="blob";readyState=WebSocket.CONNECTING;onopen=null;onmessage=null;onerror=null;onclose=null;get bufferedAmount(){return this.relay.bufferedAmount()}emit(r,v){(r==="open"?this.onopen:this.onerror)?.call(this,v),this.dispatchEvent(v)}emitMessage(r){const v=new MessageEvent("message",{data:r});this.onmessage?.call(this,v),this.dispatchEvent(v)}emitClose(r,v){if(this.readyState===WebSocket.CLOSED)return;this.readyState=WebSocket.CLOSED,this.relay.removeChannel(this.channelId);const s=new CloseEvent("close",{code:r,reason:v,wasClean:r===1e3});this.onclose?.call(this,s),this.dispatchEvent(s)}send(r){if(this.readyState!==WebSocket.OPEN)throw new DOMException("WebSocket is not open.","InvalidStateError");if(typeof r!="string")throw new DOMException("Mobile Console input messages must be text.","NotSupportedError");this.relay.send({type:"ws-send",channelId:this.channelId,data:r})}close(r=1e3,v=""){if(this.readyState===WebSocket.CLOSED||this.readyState===WebSocket.CLOSING)return;const s=this.readyState===WebSocket.OPEN;if(this.readyState=WebSocket.CLOSING,s)try{this.relay.send({type:"ws-close",channelId:this.channelId,code:r,reason:v})}catch{}this.emitClose(r,v)}relayMessage(r){if(r.type==="ws-opened"){if(this.readyState!==WebSocket.CONNECTING)return;this.readyState=WebSocket.OPEN,this.emit("open",new Event("open"))}else r.type==="ws-message"?this.emitMessage(String(r.data||"")):r.type==="ws-error"||r.type==="relay-error"?this.relayError(r.error||"console-websocket-error"):r.type==="ws-closed"&&this.emitClose(Number(r.code||1e3),String(r.reason||""))}relayBinary(r){this.emitMessage(this.binaryType==="arraybuffer"?r:new Blob([r]))}relayError(r){this.readyState!==WebSocket.CLOSED&&(this.emit("error",new Event("error")),this.emitClose(1011,"console-websocket-error"))}relayClosed(r,v){this.emitClose(r,v)}}const _t=new fy;function oy(d){_t.configure(d)}function ry(){_t.markDirectReachable()}function Ky(){_t.resume()}function Zd(d,r,v){return _t.preferRelay(),_t.fetch(d,r,v)}function Jy(d,r){return _t.shouldUseRelay()?_t.openWebSocket(r):new WebSocket(d)}const pn=5179,zn=Tn(`http://127.0.0.1:${pn}`);function dy(d){const r=d.split(".").map(v=>Number(v));return r.length===4&&r.every(v=>Number.isInteger(v)&&v>=0&&v<=255)?r:[]}function lh(d){const r=d.trim().toLowerCase();return r==="localhost"||r==="127.0.0.1"||r==="::1"||r==="[::1]"}function hy(d){const r=d.trim().toLowerCase();return!r||r==="0.0.0.0"||r==="::"||r==="[::]"}function eh(d){const r=dy(d);return r.length===0?!1:r[0]===10||r[0]===172&&r[1]>=16&&r[1]<=31||r[0]===192&&r[1]===168}function my(d){return d.includes(":")&&!d.startsWith("[")?`[${d}]`:d}function vy(d){const r=String(d||"").trim();if(!r)return null;const v=/^[a-z][a-z\d+.-]*:\/\//i.test(r)?r:`tcp://${r}`;try{const s=new URL(v),T=s.hostname.replace(/^\[|\]$/g,""),E=Number(s.port);return!T||!Number.isInteger(E)||E<1||E>65535||hy(T)?null:{host:T,port:E}}catch{return null}}function Tn(d){const r=String(d||"").trim()||`http://127.0.0.1:${pn}`,v=/^[a-z][a-z\d+.-]*:\/\//i.test(r)?r:`http://${r}`;try{const s=new URL(v);return s.port||(s.port=String(pn)),s.hash="",s.search="",s.toString().replace(/\/+$/,"")}catch{return`http://127.0.0.1:${pn}`}}function yy(d){const r=vy(d);return r?Tn(`http://${my(r.host)}:${pn}`):""}function ky(d){const v=[d?.endpoint,...Array.isArray(d?.endpoint_candidates)?d.endpoint_candidates:[]].map(s=>yy(String(s||""))).filter(Boolean);return[...new Set(v)]}function gy(d=zn){if(!(typeof window>"u"||window.location.protocol!=="https:"))try{const r=new URL(d);if(r.protocol!=="http:")return;if(lh(r.hostname))return"loopback";if(eh(r.hostname))return"local"}catch{return}}function Wy(d,r=zn){const v=new URL(d,Tn(r));return v.protocol=v.protocol==="https:"?"wss:":"ws:",v.toString()}let xn=null,Kd="";const ja=new Map,Wu=new Map;function $y(d){const r=d?.accessToken&&d?.refreshToken&&d?.user?.id?d:null,v=r?`${r.user.id}
|
|
13
13
|
${r.accessToken}
|
|
14
|
-
${r.expiresAt||0}`:"";v!==Kd&&(ja.clear(),Wu.clear(),Kd=v),xn=r,oy(r?{accessToken:r.accessToken,user:{id:r.user.id}}:null)}function Sy(){if(typeof window>"u"||window.location.protocol!=="https:")return!1;const d=window.location.hostname.replace(/^\[|\]$/g,"");return!lh(d)&&!eh(d)}function Tf(d){const r=d.split("?")[0];return r==="/api/health"||r==="/api/runtime/status"||r==="/api/auth/status"||r==="/api/auth/session"}async function Df(d,r,v,s,T){const E=gy(v);return E&&(r.targetAddressSpace=E),Iv(T,s,async A=>{r.signal=A;try{return await fetch(`${v}${d}`,r)}catch(H){throw!A.aborted&&E?new Error("VuvoDesk Hub is not reachable at this local network address. If Chrome shows a local network prompt, allow it; otherwise restart the Hub so port 5179 is open on the network."):H}})}async function Jd(d,r=!1){const v=ja.get(d);if(!r&&v&&v.expiresAt>Date.now()+3e4)return;r&&ja.delete(d);const s=Wu.get(d);if(s)return s;const T=xn;if(!T)return;const E=(async()=>{const A=await Df("/api/auth/session",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({accessToken:T.accessToken,refreshToken:T.refreshToken,expiresAt:T.expiresAt,user:T.user}),credentials:"include",cache:"no-store"},d,Fu),H=await A.json().catch(()=>null);if(!A.ok)throw new Error(`${A.status} ${H?.error||A.statusText}`);const C=String(H?.uiSession?.csrfToken||"").trim(),w=Number(H?.uiSession?.expiresAt||0);if(!C||!Number.isFinite(w)||w<=Date.now())throw new Error("VuvoDesk Hub did not issue a valid UI session.");ja.set(d,{csrfToken:C,expiresAt:w})})().finally(()=>{Wu.delete(d)});return Wu.set(d,E),E}async function by(d,r,v=zn){const s=Tn(v),{timeoutMs:T=Fu,signal:E,transport:A="auto",...H}=r||{},C=!Tf(d),w=()=>{const ll=String(H.method||"GET").toUpperCase(),D=ja.get(s)?.csrfToken||"";return{...H,headers:{...H.headers||{},...!["GET","HEAD","OPTIONS"].includes(ll)&&D?{"X-LiveDesk-CSRF":D}:{}},credentials:"include",cache:"no-store"}};if(A==="relay"){if(E?.aborted)throw E.reason||new Error("VuvoDesk Hub request cancelled.");if(!xn||Tf(d))throw new Error("Mobile Console relay requires an authenticated management request.");return Zd(d,w(),T)}try{C&&await Jd(s);let ll=await Df(d,w(),s,T,E);if(ry(),C&&ll.status===401&&xn){const D=await ll.clone().json().catch(()=>null);/^hub-ui-session-(required|expired)$/.test(String(D?.error||""))&&(await Jd(s,!0),ll=await Df(d,w(),s,T,E))}return ll}catch(ll){if(E?.aborted||!xn||Tf(d))throw ll;return Zd(d,w(),T)}}async function py(d,r,v=zn){const s=Tn(v),T=await by(d,{...r||{},headers:{"Content-Type":"application/json",...r?.headers||{}}},v);let E=null;try{E=await T.json()}catch(A){if(r?.signal?.aborted)throw A;E=null}if(T.ok&&d.split("?")[0]==="/api/auth/session"&&E&&typeof E=="object"){const A=E.uiSession,H=String(A?.csrfToken||"").trim(),C=Number(A?.expiresAt||0);H&&Number.isFinite(C)&&C>Date.now()&&ja.set(s,{csrfToken:H,expiresAt:C})}if(!T.ok){const A=E&&typeof E=="object"&&"error"in E?String(E.error||""):"";throw new Error(`${T.status} ${A||T.statusText}`)}return E}async function Fy({baseUrl:d=zn,targetRole:r,previousRuntimePid:v=0,allowedStates:s=["running","waiting-auth"],timeoutMs:T=3e4}){const E=Date.now()+T;let A=null;for(;Date.now()<E;){try{const C=await py("/api/runtime/status",void 0,d),w=String(C.role||"").toLowerCase(),ll=String(C.state||"").toLowerCase(),D=Number(C.runtimePid||0),K=v>1?D>1&&D!==v:D>1;if(w===r&&s.map(Zl=>Zl.toLowerCase()).includes(ll)&&K)return C}catch(C){A=C}await new Promise(C=>setTimeout(C,300))}const H=A instanceof Error?` ${A.message}`:"";throw new Error(`VuvoDesk runtime did not become ${r} with a new process.${H}`)}function Iy(d,r=120){if(typeof window>"u")return;const v=new URL(window.location.href);v.port=String(d),v.pathname="/",v.search="",v.hash="";const s=v.toString();let T=0;const E=()=>{fetch(s,{cache:"no-store",mode:"no-cors"}).then(()=>window.location.replace(s)).catch(()=>{if(T+=1,T>=r){window.location.replace(s);return}window.setTimeout(E,250)})};E()}function Py(d){if(!d)return"-";const r=Date.now()-Date.parse(d);return Number.isFinite(r)?r<1e3?"now":r<6e4?`${Math.round(r/1e3)}s`:r<36e5?`${Math.round(r/6e4)}m`:`${Math.round(r/36e5)}h`:"-"}async function l0(d){await navigator.clipboard.writeText(d)}const th=5,Of=30,xy=Number.POSITIVE_INFINITY,se={free:{name:"Free",price:"$0",limit:th,audience:"Personal, ad-supported",note:"Up to 5 personal devices supported by a standard banner."},ltd:{name:"Plus",price:"$5",ltd:"$79 LTD",limit:Of,audience:"Creators and homelabs",note:"30 devices, no ads, personal use."},pro:{name:"Pro",price:"$15",ltd:"$199 LTD",limit:xy,audience:"Business and studios",note:"Commercial use and larger Client walls."}},jy="0.1.615",zy={version:jy},Ty=String(zy.version).trim();function ah({size:d=22}){return c.jsxs("svg",{width:d,height:d,viewBox:"0 0 28 28",fill:"none",xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",children:[c.jsx("rect",{x:"2.5",y:"4",width:"14",height:"9",rx:"1.5",stroke:"currentColor",strokeWidth:"1.7",opacity:"0.42"}),c.jsx("path",{d:"M7 16v1.5h5",stroke:"currentColor",strokeWidth:"1.7",strokeLinecap:"round",opacity:"0.42"}),c.jsx("rect",{x:"10.5",y:"2.5",width:"14",height:"9",rx:"1.5",stroke:"currentColor",strokeWidth:"1.7",opacity:"0.62"}),c.jsx("path",{d:"M15 14.5V16h5",stroke:"currentColor",strokeWidth:"1.7",strokeLinecap:"round",opacity:"0.62"}),c.jsx("rect",{x:"6.5",y:"8.5",width:"15",height:"10",rx:"1.7",fill:"currentColor",fillOpacity:"0.12",stroke:"currentColor",strokeWidth:"1.9"}),c.jsx("path",{d:"M12 21v1.5H9.5M16 21v1.5h2.5M9.5 22.5h9",stroke:"currentColor",strokeWidth:"1.9",strokeLinecap:"round"})]})}const kd="npx -y --prefer-online livedesk@latest",En="https://livedesk-desktop-updates.lovecrdm.workers.dev/download/dev",Ey=`${En}/windows/x64`,Ay=`${En}/macos/x64`,My=`${En}/macos/arm64`,Ny=`${En}/linux/x64`,Dy=`${En}/linux/x64/deb`;function Oy(){if(typeof window>"u")return"home";const d=window.location.pathname.replace(/\/+$/,"")||"/";return d==="/"?"home":d==="/download"?"download":d==="/pricing"?"pricing":"not-found"}function nh(){return c.jsxs("a",{className:"site-brand",href:"/","aria-label":"VuvoDesk home",children:[c.jsx("span",{className:"site-brand-mark",children:c.jsx(ah,{size:25})}),c.jsx("span",{children:"VuvoDesk"})]})}function Uy({page:d}){const r=[{label:"Product",href:"/#product",active:d==="home"},{label:"Pricing",href:"/pricing",active:d==="pricing"},{label:"Download",href:"/download",active:d==="download"},{label:"Support",href:"/support",active:!1}];return c.jsx("header",{className:"site-header",children:c.jsxs("div",{className:"site-header-inner",children:[c.jsx(nh,{}),c.jsx("nav",{className:"site-nav","aria-label":"Main navigation",children:r.map(v=>c.jsx("a",{className:v.active?"active":"",href:v.href,children:v.label},v.label))}),c.jsxs("div",{className:"site-header-actions",children:[c.jsx("a",{className:"site-text-link",href:"/app",children:"Open web console"}),c.jsxs("a",{className:"site-button site-button-small",href:"/download",children:["Get VuvoDesk ",c.jsx(Ut,{size:15})]})]}),c.jsxs("details",{className:"site-mobile-menu",children:[c.jsx("summary",{"aria-label":"Open navigation",children:c.jsx(Uv,{size:22})}),c.jsxs("nav",{"aria-label":"Mobile navigation",children:[r.map(v=>c.jsxs("a",{href:v.href,children:[v.label,c.jsx(Cd,{size:15})]},v.label)),c.jsxs("a",{href:"/app",children:["Open web console",c.jsx(Cd,{size:15})]})]})]})]})})}function _y(){return c.jsxs("footer",{className:"site-footer",children:[c.jsxs("div",{className:"site-footer-main",children:[c.jsxs("div",{children:[c.jsx(nh,{}),c.jsx("p",{children:"One calm command center for every computer you manage."})]}),c.jsxs("div",{className:"site-footer-links",children:[c.jsxs("div",{children:[c.jsx("strong",{children:"Product"}),c.jsx("a",{href:"/#product",children:"Overview"}),c.jsx("a",{href:"/pricing",children:"Pricing"}),c.jsx("a",{href:"/download",children:"Download"})]}),c.jsxs("div",{children:[c.jsx("strong",{children:"Use VuvoDesk"}),c.jsx("a",{href:"/app",children:"Web console"}),c.jsx("a",{href:"/support",children:"Support"})]}),c.jsxs("div",{children:[c.jsx("strong",{children:"Platforms"}),c.jsx("span",{children:"Windows"}),c.jsx("span",{children:"macOS"}),c.jsx("span",{children:"Linux"}),c.jsx("span",{children:"Mobile PWA"})]})]})]}),c.jsxs("div",{className:"site-footer-bottom",children:[c.jsx("span",{children:"© 2026 VuvoDesk"}),c.jsx("span",{children:"Built for people who run real work across many screens."})]})]})}function Hy(){const d=[{name:"Studio-01",status:"Online",className:"screen-blue",cpu:"42%",ram:"61%"},{name:"Render-Mac",status:"Online",className:"screen-purple",cpu:"67%",ram:"74%"},{name:"Linux-Build",status:"Online",className:"screen-green",cpu:"29%",ram:"48%"},{name:"Office-PC",status:"Idle",className:"screen-orange",cpu:"18%",ram:"37%"}];return c.jsxs("div",{className:"product-mockup","aria-label":"VuvoDesk screen wall preview",children:[c.jsxs("div",{className:"mockup-window-bar",children:[c.jsxs("div",{children:[c.jsx("i",{}),c.jsx("i",{}),c.jsx("i",{})]}),c.jsx("span",{children:"VuvoDesk · Wall"}),c.jsxs("span",{className:"mockup-online",children:[c.jsx("i",{})," 4 online"]})]}),c.jsxs("div",{className:"mockup-body",children:[c.jsxs("aside",{className:"mockup-rail","aria-hidden":"true",children:[c.jsx("span",{className:"active",children:c.jsx($d,{size:17})}),c.jsx("span",{children:c.jsx($u,{size:17})}),c.jsx("span",{children:c.jsx(Fd,{size:17})}),c.jsx("span",{children:c.jsx(Id,{size:17})})]}),c.jsx("div",{className:"mockup-wall",children:d.map(r=>c.jsxs("article",{className:"mockup-screen",children:[c.jsxs("div",{className:`mockup-screen-image ${r.className}`,children:[c.jsx("span",{className:"mockup-code-line wide"}),c.jsx("span",{className:"mockup-code-line"}),c.jsx("span",{className:"mockup-code-line short"}),c.jsx("span",{className:"mockup-panel-block"})]}),c.jsxs("div",{className:"mockup-screen-title",children:[c.jsx("strong",{children:r.name}),c.jsxs("span",{children:[c.jsx("i",{})," ",r.status]})]}),c.jsxs("div",{className:"mockup-metrics",children:[c.jsxs("span",{children:["CPU ",c.jsx("b",{children:r.cpu})]}),c.jsxs("span",{children:["RAM ",c.jsx("b",{children:r.ram})]})]})]},r.name))})]}),c.jsxs("div",{className:"mockup-control-card",children:[c.jsx($u,{size:18}),c.jsxs("span",{children:[c.jsx("small",{children:"Selected computer"}),c.jsx("strong",{children:"Render-Mac"})]}),c.jsx("button",{type:"button",children:"Control"})]})]})}function uh({compact:d=!1}){const r=[{key:"free",name:se.free.name,price:se.free.price,suffix:"forever",audience:se.free.audience,description:"A practical personal wall, supported by a standard banner.",features:[`Up to ${th} devices`,"Live wall and focused control","Standard banner"],action:"Start free",href:"/app"},{key:"plus",name:se.ltd.name,price:se.ltd.price,suffix:"/ month",audience:se.ltd.audience,description:"A clean personal command center for creators and homelabs.",features:[`Up to ${Of} devices`,"No standard banner","Personal use"],ltd:se.ltd.ltd,action:"Choose Plus",href:"/app?view=pricing"},{key:"pro",name:se.pro.name,price:se.pro.price,suffix:"/ month",audience:se.pro.audience,description:"Commercial monitoring for studios, offices, and growing fleets.",features:[`More than ${Of} Clients`,"Ad-free commercial use","Large screen walls"],ltd:se.pro.ltd,action:"Choose Pro",href:"/app?view=pricing"}];return c.jsx("div",{className:`site-pricing-grid ${d?"compact":""}`,children:r.map(v=>c.jsxs("article",{className:`site-price-card ${v.key==="plus"?"featured":""}`,children:[c.jsxs("div",{className:"site-price-heading",children:[c.jsx("span",{children:v.name}),v.key==="plus"&&c.jsx("em",{children:"Most popular"})]}),c.jsx("p",{className:"site-price-audience",children:v.audience}),c.jsxs("div",{className:"site-price",children:[c.jsx("strong",{children:v.price}),c.jsx("small",{children:v.suffix})]}),c.jsx("p",{children:v.description}),c.jsx("ul",{children:v.features.map(s=>c.jsxs("li",{children:[c.jsx(Yv,{size:16})," ",s]},s))}),v.ltd&&c.jsxs("div",{className:"site-ltd",children:[c.jsxs("span",{children:[v.name," LTD"]}),c.jsx("strong",{children:v.ltd.replace(" LTD","")}),c.jsx("small",{children:"one-time · available now"})]}),c.jsxs("a",{className:`site-price-action ${v.key==="plus"?"primary":""}`,href:v.href,children:[v.action,c.jsx(Ut,{size:15})]})]},v.key))})}function Cy(){return c.jsx(c.Fragment,{children:c.jsxs("main",{children:[c.jsxs("section",{className:"site-hero",children:[c.jsxs("div",{className:"site-hero-copy",children:[c.jsxs("span",{className:"site-kicker",children:[c.jsx(_v,{size:15})," The screen wall for real work"]}),c.jsxs("h1",{children:["Every computer.",c.jsx("br",{}),c.jsx("span",{children:"One calm command center."})]}),c.jsx("p",{children:"See every screen, focus the computer that needs you, and keep work moving from your desk or phone."}),c.jsxs("div",{className:"site-hero-actions",children:[c.jsxs("a",{className:"site-button",href:"/download",children:["Download VuvoDesk ",c.jsx(Ut,{size:17})]}),c.jsxs("a",{className:"site-button site-button-secondary",href:"/app",children:["Open web console ",c.jsx(Bd,{size:17})]})]}),c.jsxs("div",{className:"site-hero-notes",children:[c.jsxs("span",{children:[c.jsx(Sf,{size:15})," Free for 5 devices"]}),c.jsxs("span",{children:[c.jsx(Sf,{size:15})," No credit card"]}),c.jsxs("span",{children:[c.jsx(Sf,{size:15})," Windows · macOS · Linux"]})]})]}),c.jsxs("div",{className:"site-hero-visual",children:[c.jsx("div",{className:"site-orbit site-orbit-one"}),c.jsx("div",{className:"site-orbit site-orbit-two"}),c.jsx(Hy,{})]})]}),c.jsxs("section",{className:"platform-strip","aria-label":"Supported platforms",children:[c.jsx("span",{children:"Built for the computers you already run"}),c.jsxs("div",{children:[c.jsxs("strong",{children:[c.jsx(Wd,{size:18})," Windows"]}),c.jsxs("strong",{children:[c.jsx(Mf,{size:18})," macOS"]}),c.jsxs("strong",{children:[c.jsx(Nf,{size:18})," Linux"]}),c.jsxs("strong",{children:[c.jsx(ku,{size:18})," iPhone & Android"]}),c.jsxs("strong",{children:[c.jsx(Bd,{size:18})," Any browser"]})]})]}),c.jsxs("section",{className:"site-section site-value-section",id:"product",children:[c.jsxs("div",{className:"site-section-heading",children:[c.jsx("span",{children:"Why VuvoDesk"}),c.jsxs("h2",{children:["Spend less time finding the problem.",c.jsx("br",{}),"Spend more time fixing it."]}),c.jsx("p",{children:"VuvoDesk keeps the fleet visible without turning your desktop into a pile of remote windows."})]}),c.jsxs("div",{className:"site-value-grid",children:[c.jsxs("article",{className:"site-value-card large blue",children:[c.jsx("span",{className:"site-feature-icon",children:c.jsx($d,{size:23})}),c.jsx("h3",{children:"A wall that stays readable"}),c.jsx("p",{children:"Move from a compact list to large live previews. Keep the signal you need and hide the noise you do not."}),c.jsxs("div",{className:"feature-wall-demo",children:[c.jsx("i",{}),c.jsx("i",{}),c.jsx("i",{}),c.jsx("i",{}),c.jsx("i",{}),c.jsx("i",{})]})]}),c.jsxs("article",{className:"site-value-card mint",children:[c.jsx("span",{className:"site-feature-icon",children:c.jsx($u,{size:23})}),c.jsx("h3",{children:"Control without losing context"}),c.jsx("p",{children:"Jump from Wall to focused Control, then return to the same fleet view."}),c.jsxs("div",{className:"feature-cursor-demo",children:[c.jsx($u,{size:31}),c.jsx("span",{children:"Direct control"})]})]}),c.jsxs("article",{className:"site-value-card violet",children:[c.jsx("span",{className:"site-feature-icon",children:c.jsx(Hv,{size:23})}),c.jsx("h3",{children:"Your fleet in your pocket"}),c.jsx("p",{children:"Install the PWA on iPhone or Android and check the room before you walk back to it."}),c.jsxs("div",{className:"feature-phone-demo",children:[c.jsx("span",{}),c.jsxs("div",{children:[c.jsx("i",{}),c.jsx("i",{}),c.jsx("i",{})]})]})]}),c.jsxs("article",{className:"site-value-card wide dark",children:[c.jsxs("div",{children:[c.jsxs("span",{className:"site-kicker dark",children:[c.jsx(Cv,{size:14})," Local-first when possible"]}),c.jsx("h3",{children:"Fast where you work. Reachable when you leave."}),c.jsx("p",{children:"VuvoDesk prefers the shortest useful route and keeps the current screen moving instead of building a stale queue."})]}),c.jsxs("div",{className:"feature-route",children:[c.jsxs("span",{children:[c.jsx(Mf,{size:19})," Hub"]}),c.jsx("i",{}),c.jsxs("span",{children:[c.jsx(Bv,{size:19})," Clients"]}),c.jsx("i",{}),c.jsxs("span",{children:[c.jsx(ku,{size:19})," PWA"]})]})]})]})]}),c.jsxs("section",{className:"site-section site-workflow",children:[c.jsxs("div",{className:"site-section-heading centered",children:[c.jsx("span",{children:"Start in three steps"}),c.jsx("h2",{children:"From zero to a live wall in minutes."})]}),c.jsxs("div",{className:"workflow-grid",children:[c.jsxs("article",{children:[c.jsx("b",{children:"01"}),c.jsx("span",{children:c.jsx(Dt,{size:21})}),c.jsx("h3",{children:"Install the Hub"}),c.jsx("p",{children:"Choose the computer that will organize your VuvoDesk fleet."})]}),c.jsxs("article",{children:[c.jsx("b",{children:"02"}),c.jsx("span",{children:c.jsx(Fd,{size:21})}),c.jsx("h3",{children:"Connect Clients"}),c.jsx("p",{children:"Use one PIN to add the Windows, Mac, and Linux computers you manage."})]}),c.jsxs("article",{children:[c.jsx("b",{children:"03"}),c.jsx("span",{children:c.jsx(ku,{size:21})}),c.jsx("h3",{children:"Manage from anywhere"}),c.jsx("p",{children:"Open the web console or install the mobile PWA and keep every screen close."})]})]})]}),c.jsxs("section",{className:"site-section site-pricing-section",children:[c.jsxs("div",{className:"site-section-heading centered",children:[c.jsx("span",{children:"Simple pricing"}),c.jsx("h2",{children:"Start free. Upgrade when the wall earns its place."}),c.jsx("p",{children:"Monthly prices stay easy to understand. Lifetime offers are available separately below each paid plan."})]}),c.jsx(uh,{compact:!0}),c.jsxs("a",{className:"site-inline-link",href:"/pricing",children:["Compare every plan ",c.jsx(Ut,{size:15})]})]}),c.jsxs("section",{className:"site-final-cta",children:[c.jsxs("div",{children:[c.jsxs("span",{className:"site-kicker dark",children:[c.jsx(qv,{size:14})," Your fleet, one glance away"]}),c.jsxs("h2",{children:["Give every computer",c.jsx("br",{}),"one clear place to report."]})]}),c.jsxs("div",{children:[c.jsx("p",{children:"Start with five devices for free. Install the Hub, connect a Client, and open your first live wall."}),c.jsxs("div",{children:[c.jsxs("a",{className:"site-button light",href:"/download",children:["Get VuvoDesk ",c.jsx(Ut,{size:17})]}),c.jsx("a",{className:"site-button ghost",href:"/app",children:"Open console"})]})]})]})]})})}function By(){const[d,r]=jn.useState(!1),v=async()=>{try{await navigator.clipboard.writeText(kd),r(!0),window.setTimeout(()=>r(!1),1800)}catch{r(!1)}};return c.jsxs("main",{className:"site-subpage",children:[c.jsxs("section",{className:"site-subpage-hero download-hero",children:[c.jsxs("span",{className:"site-kicker",children:[c.jsx(Dt,{size:15})," Download VuvoDesk"]}),c.jsxs("h1",{children:["Turn one computer into",c.jsx("br",{}),c.jsx("span",{children:"your command center."})]}),c.jsx("p",{children:"Use the latest temporary installer for your computer. These preview links always follow the newest matching file published to the VuvoDesk download channel."})]}),c.jsxs("section",{className:"download-grid",children:[c.jsxs("article",{id:"windows",children:[c.jsx("span",{className:"download-platform-icon windows",children:c.jsx(Wd,{size:27})}),c.jsxs("div",{children:[c.jsx("small",{children:"Windows"}),c.jsx("span",{className:"download-version",children:"Latest temporary build · x64 Electron"}),c.jsx("span",{className:"download-preview-note",children:"Temporary installer · unsigned"}),c.jsx("h2",{children:"Install VuvoDesk for Windows"}),c.jsx("p",{children:"Download the normal Electron setup program. Windows SmartScreen may warn about this preview until code signing is ready."})]}),c.jsxs("a",{className:"download-installer-link",href:Ey,children:["Download Windows installer ",c.jsx(Dt,{size:16})]})]}),c.jsxs("article",{id:"macos",children:[c.jsx("span",{className:"download-platform-icon mac",children:c.jsx(Mf,{size:27})}),c.jsxs("div",{children:[c.jsx("small",{children:"macOS"}),c.jsx("span",{className:"download-version",children:"Latest temporary build · Intel & Apple silicon"}),c.jsx("span",{className:"download-preview-note",children:"Temporary installer · ad-hoc signed · not notarized"}),c.jsx("h2",{children:"Install VuvoDesk for macOS"}),c.jsx("p",{children:"Choose the chip in your Mac. On first launch, macOS may require Open Anyway in Privacy & Security because this preview is not Apple-notarized."})]}),c.jsxs("div",{className:"download-actions",children:[c.jsxs("a",{className:"download-installer-link",href:My,children:["Apple silicon ",c.jsx(Dt,{size:16})]}),c.jsxs("a",{className:"download-installer-link secondary",href:Ay,children:["Intel Mac ",c.jsx(Dt,{size:16})]})]})]}),c.jsxs("article",{id:"linux",children:[c.jsx("span",{className:"download-platform-icon linux",children:c.jsx(Nf,{size:27})}),c.jsxs("div",{children:[c.jsx("small",{children:"Linux"}),c.jsx("span",{className:"download-version",children:"Latest temporary build · x64 · X11"}),c.jsx("span",{className:"download-preview-note",children:"Temporary installer"}),c.jsx("h2",{children:"Install VuvoDesk for Linux"}),c.jsx("p",{children:"Use the DEB package on Ubuntu, Debian, or Mint. For other distributions, download AppImage, mark it executable, then open it."})]}),c.jsxs("div",{className:"download-actions",children:[c.jsxs("a",{className:"download-installer-link",href:Dy,children:["Download .deb ",c.jsx(Dt,{size:16})]}),c.jsxs("a",{className:"download-installer-link secondary",href:Ny,children:["Download AppImage ",c.jsx(Dt,{size:16})]})]})]})]}),c.jsxs("section",{className:"install-command-card",id:"install-command",children:[c.jsxs("div",{children:[c.jsxs("span",{children:[c.jsx(Nf,{size:18})," One command install"]}),c.jsx("h2",{children:"Terminal fallback and advanced setup"}),c.jsx("p",{children:"Use the npm package when you prefer a command-line install or the temporary desktop package does not suit your system."})]}),c.jsxs("div",{className:"install-command",children:[c.jsx("code",{children:kd}),c.jsxs("button",{type:"button",onClick:()=>{v()},children:[c.jsx(Rv,{size:17})," ",d?"Copied":"Copy"]})]}),c.jsxs("ol",{children:[c.jsxs("li",{children:[c.jsx("b",{children:"1"}),c.jsx("span",{children:"Run the command on the computer that will be your Hub."})]}),c.jsxs("li",{children:[c.jsx("b",{children:"2"}),c.jsx("span",{children:"Open Settings and create a Hub PIN."})]}),c.jsxs("li",{children:[c.jsx("b",{children:"3"}),c.jsx("span",{children:"Run the same package as a Client on the other computers."})]})]})]}),c.jsxs("section",{className:"mobile-install-section",id:"mobile",children:[c.jsxs("div",{className:"mobile-install-heading",children:[c.jsx("span",{children:c.jsx(ku,{size:26})}),c.jsxs("div",{children:[c.jsxs("small",{children:["iPhone & Android · PWA ",Ty]}),c.jsx("h2",{children:"No app store required."}),c.jsx("p",{children:"Open the public web address, sign in, then install VuvoDesk on the Home Screen. The PWA always starts directly in the console."})]})]}),c.jsxs("div",{className:"mobile-web-address",children:[c.jsx("span",{children:"Mobile web address"}),c.jsx("a",{href:"https://vuvodesk.com/app",children:"https://vuvodesk.com/app"}),c.jsxs("a",{className:"site-button",href:"/app",children:["Open mobile console ",c.jsx(Ut,{size:16})]})]}),c.jsxs("div",{className:"pwa-guide-grid",children:[c.jsxs("article",{children:[c.jsx("strong",{children:"iPhone & iPad"}),c.jsxs("ol",{children:[c.jsx("li",{children:"Open the address in Safari."}),c.jsx("li",{children:"Tap Share, then Add to Home Screen."}),c.jsx("li",{children:"Choose Open as Web App and add VuvoDesk."})]})]}),c.jsxs("article",{children:[c.jsx("strong",{children:"Android"}),c.jsxs("ol",{children:[c.jsx("li",{children:"Open the address in Chrome."}),c.jsx("li",{children:"Open the browser menu and tap Install app."}),c.jsx("li",{children:"Launch VuvoDesk from the Home Screen."})]})]})]})]})]})}function qy(){return c.jsxs("main",{className:"site-subpage pricing-subpage",children:[c.jsxs("section",{className:"site-subpage-hero",children:[c.jsxs("span",{className:"site-kicker",children:[c.jsx(qd,{size:15})," VuvoDesk pricing"]}),c.jsxs("h1",{children:["Clear plans for",c.jsx("br",{}),c.jsx("span",{children:"growing screen walls."})]}),c.jsx("p",{children:"Use VuvoDesk free on five personal computers. Choose Plus for a larger ad-free personal wall, or Pro for commercial work."})]}),c.jsx(uh,{}),c.jsxs("section",{className:"pricing-explainer",children:[c.jsxs("article",{children:[c.jsx(wv,{size:21}),c.jsxs("div",{children:[c.jsx("h3",{children:"Free stays useful"}),c.jsx("p",{children:"The standard banner helps keep a five-device personal wall available without a subscription."})]})]}),c.jsxs("article",{children:[c.jsx(qd,{size:21}),c.jsxs("div",{children:[c.jsx("h3",{children:"Monthly and lifetime are separate"}),c.jsx("p",{children:"$5 and $15 are monthly plan prices. Plus LTD $79 and Pro LTD $199 are one-time offers shown separately."})]})]}),c.jsxs("article",{children:[c.jsx(Id,{size:21}),c.jsxs("div",{children:[c.jsx("h3",{children:"Upgrade inside VuvoDesk"}),c.jsx("p",{children:"Sign in to the console, open Pricing, and choose the plan that matches the way you use the fleet."})]})]})]}),c.jsxs("section",{className:"pricing-bottom-cta",children:[c.jsxs("div",{children:[c.jsx("h2",{children:"Start with the computers you have today."}),c.jsx("p",{children:"No credit card is needed for Free."})]}),c.jsxs("a",{className:"site-button",href:"/app",children:["Start free ",c.jsx(Ut,{size:16})]})]})]})}function Ry(){return c.jsxs("main",{className:"site-not-found",children:[c.jsx("span",{className:"site-brand-mark",children:c.jsx(ah,{size:25})}),c.jsx("small",{children:"404"}),c.jsx("h1",{children:"This screen is not on the wall."}),c.jsx("p",{children:"The page may have moved, but your VuvoDesk console is still here."}),c.jsxs("div",{children:[c.jsx("a",{className:"site-button",href:"/",children:"VuvoDesk home"}),c.jsx("a",{className:"site-button site-button-secondary",href:"/app",children:"Open console"})]})]})}function wy(){const d=Oy();return jn.useEffect(()=>{const r={home:"VuvoDesk — Every computer. One calm command center.",download:"Download VuvoDesk — Windows, macOS, and Linux",pricing:"VuvoDesk Pricing — Free, Plus, and Pro","not-found":"Page not found — VuvoDesk"};return document.title=r[d],document.documentElement.classList.add("livedesk-marketing-active"),()=>document.documentElement.classList.remove("livedesk-marketing-active")},[d]),c.jsxs("div",{className:"marketing-site",children:[c.jsx(Uy,{page:d}),d==="home"?c.jsx(Cy,{}):d==="download"?c.jsx(By,{}):d==="pricing"?c.jsx(qy,{}):c.jsx(Ry,{}),c.jsx(_y,{})]})}function Yy(d){return!!d.navigatorStandalone||!!d.displayModeStandalone||!!d.displayModeFullscreen}function Gy({publicOrigin:d,electron:r,pathname:v,search:s="",navigatorStandalone:T=!1,displayModeStandalone:E=!1,displayModeFullscreen:A=!1,marketingPreview:H=!1}){if(r||!d&&!H)return{kind:"app",redirectPath:""};const C=new URLSearchParams(s),w=C.has("pwa")||Yy({navigatorStandalone:T,displayModeStandalone:E,displayModeFullscreen:A}),ll=v==="/app"||v.startsWith("/app/"),D=v==="/support"||v.startsWith("/support/"),K=C.has("checkout");return w||K?{kind:"app",redirectPath:ll?"":"/app"}:ll||D?{kind:"app",redirectPath:""}:{kind:"site",redirectPath:""}}const Ly=jn.lazy(()=>Qv(()=>import("./LiveDeskApp-D3LPrsCg.js"),__vite__mapDeps([0,1,2,3,4])).then(d=>({default:d.LiveDeskApp})));window.liveDesk&&document.documentElement.classList.add("livedesk-electron-desktop");const Ot=new URL(window.location.href),Xy=!!window.navigator.standalone,Uf=Gy({publicOrigin:Sy(),electron:!!window.liveDesk,pathname:Ot.pathname,search:Ot.search,navigatorStandalone:Xy,displayModeStandalone:window.matchMedia("(display-mode: standalone)").matches,displayModeFullscreen:window.matchMedia("(display-mode: fullscreen)").matches,marketingPreview:Ot.searchParams.get("site")==="1"});Uf.redirectPath&&(Ot.pathname=Uf.redirectPath,window.history.replaceState({},"",`${Ot.pathname}${Ot.search}${Ot.hash}`));$v.createRoot(document.getElementById("root")).render(c.jsx(jn.StrictMode,{children:Uf.kind==="site"?c.jsx(wy,{}):c.jsx(jn.Suspense,{fallback:c.jsx("main",{className:"runtime-role-boot","aria-label":"Starting VuvoDesk",children:c.jsx("strong",{children:"Starting VuvoDesk"})}),children:c.jsx(Ly,{})})}));const ih="serviceWorker"in navigator&&window.isSecureContext&&window.location.protocol==="https:";let Ef=null;function Af(){!ih||Ef||(Ef=(async()=>{await(await navigator.serviceWorker.register("/sw.js",{updateViaCache:"none"})).update();const r=await fetch(`/sw.js?pwa-release-check=${Date.now()}`,{cache:"no-store"});if(!r.ok)return;const s=(await r.text()).match(/const PWA_RELEASE = ['"](\d+\.\d+\.\d+)['"];/)?.[1],T=new URL(window.location.href);if(!s||!T.searchParams.has("pwa"))return;const E=T.pathname!=="/app",A=T.searchParams.get("pwa")!==s;!E&&!A||(T.pathname="/app",T.searchParams.set("pwa",s),window.location.replace(T.toString()))})().catch(d=>{console.warn("[VuvoDesk] PWA update check failed.",d)}).finally(()=>{Ef=null}))}ih&&(Af(),window.addEventListener("pageshow",Af),document.addEventListener("visibilitychange",()=>{document.visibilityState==="visible"&&Af()}));export{zn as D,th as F,ah as M,Of as P,Wy as a,Ky as b,Jy as c,Iy as d,l0 as e,Py as f,gy as g,py as h,Sy as i,c as j,by as k,$y as l,ky as m,Tn as n,se as p,Zy as r,Fy as w};
|
|
14
|
+
${r.expiresAt||0}`:"";v!==Kd&&(ja.clear(),Wu.clear(),Kd=v),xn=r,oy(r?{accessToken:r.accessToken,user:{id:r.user.id}}:null)}function Sy(){if(typeof window>"u"||window.location.protocol!=="https:")return!1;const d=window.location.hostname.replace(/^\[|\]$/g,"");return!lh(d)&&!eh(d)}function Tf(d){const r=d.split("?")[0];return r==="/api/health"||r==="/api/runtime/status"||r==="/api/auth/status"||r==="/api/auth/session"}async function Df(d,r,v,s,T){const E=gy(v);return E&&(r.targetAddressSpace=E),Iv(T,s,async A=>{r.signal=A;try{return await fetch(`${v}${d}`,r)}catch(H){throw!A.aborted&&E?new Error("VuvoDesk Hub is not reachable at this local network address. If Chrome shows a local network prompt, allow it; otherwise restart the Hub so port 5179 is open on the network."):H}})}async function Jd(d,r=!1){const v=ja.get(d);if(!r&&v&&v.expiresAt>Date.now()+3e4)return;r&&ja.delete(d);const s=Wu.get(d);if(s)return s;const T=xn;if(!T)return;const E=(async()=>{const A=await Df("/api/auth/session",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({accessToken:T.accessToken,refreshToken:T.refreshToken,expiresAt:T.expiresAt,user:T.user}),credentials:"include",cache:"no-store"},d,Fu),H=await A.json().catch(()=>null);if(!A.ok)throw new Error(`${A.status} ${H?.error||A.statusText}`);const C=String(H?.uiSession?.csrfToken||"").trim(),w=Number(H?.uiSession?.expiresAt||0);if(!C||!Number.isFinite(w)||w<=Date.now())throw new Error("VuvoDesk Hub did not issue a valid UI session.");ja.set(d,{csrfToken:C,expiresAt:w})})().finally(()=>{Wu.delete(d)});return Wu.set(d,E),E}async function by(d,r,v=zn){const s=Tn(v),{timeoutMs:T=Fu,signal:E,transport:A="auto",...H}=r||{},C=!Tf(d),w=()=>{const ll=String(H.method||"GET").toUpperCase(),D=ja.get(s)?.csrfToken||"";return{...H,headers:{...H.headers||{},...!["GET","HEAD","OPTIONS"].includes(ll)&&D?{"X-LiveDesk-CSRF":D}:{}},credentials:"include",cache:"no-store"}};if(A==="relay"){if(E?.aborted)throw E.reason||new Error("VuvoDesk Hub request cancelled.");if(!xn||Tf(d))throw new Error("Mobile Console relay requires an authenticated management request.");return Zd(d,w(),T)}try{C&&await Jd(s);let ll=await Df(d,w(),s,T,E);if(ry(),C&&ll.status===401&&xn){const D=await ll.clone().json().catch(()=>null);/^hub-ui-session-(required|expired)$/.test(String(D?.error||""))&&(await Jd(s,!0),ll=await Df(d,w(),s,T,E))}return ll}catch(ll){if(E?.aborted||!xn||Tf(d))throw ll;return Zd(d,w(),T)}}async function py(d,r,v=zn){const s=Tn(v),T=await by(d,{...r||{},headers:{"Content-Type":"application/json",...r?.headers||{}}},v);let E=null;try{E=await T.json()}catch(A){if(r?.signal?.aborted)throw A;E=null}if(T.ok&&d.split("?")[0]==="/api/auth/session"&&E&&typeof E=="object"){const A=E.uiSession,H=String(A?.csrfToken||"").trim(),C=Number(A?.expiresAt||0);H&&Number.isFinite(C)&&C>Date.now()&&ja.set(s,{csrfToken:H,expiresAt:C})}if(!T.ok){const A=E&&typeof E=="object"&&"error"in E?String(E.error||""):"";throw new Error(`${T.status} ${A||T.statusText}`)}return E}async function Fy({baseUrl:d=zn,targetRole:r,previousRuntimePid:v=0,allowedStates:s=["running","waiting-auth"],timeoutMs:T=3e4}){const E=Date.now()+T;let A=null;for(;Date.now()<E;){try{const C=await py("/api/runtime/status",void 0,d),w=String(C.role||"").toLowerCase(),ll=String(C.state||"").toLowerCase(),D=Number(C.runtimePid||0),K=v>1?D>1&&D!==v:D>1;if(w===r&&s.map(Zl=>Zl.toLowerCase()).includes(ll)&&K)return C}catch(C){A=C}await new Promise(C=>setTimeout(C,300))}const H=A instanceof Error?` ${A.message}`:"";throw new Error(`VuvoDesk runtime did not become ${r} with a new process.${H}`)}function Iy(d,r=120){if(typeof window>"u")return;const v=new URL(window.location.href);v.port=String(d),v.pathname="/",v.search="",v.hash="";const s=v.toString();let T=0;const E=()=>{fetch(s,{cache:"no-store",mode:"no-cors"}).then(()=>window.location.replace(s)).catch(()=>{if(T+=1,T>=r){window.location.replace(s);return}window.setTimeout(E,250)})};E()}function Py(d){if(!d)return"-";const r=Date.now()-Date.parse(d);return Number.isFinite(r)?r<1e3?"now":r<6e4?`${Math.round(r/1e3)}s`:r<36e5?`${Math.round(r/6e4)}m`:`${Math.round(r/36e5)}h`:"-"}async function l0(d){await navigator.clipboard.writeText(d)}const th=5,Of=30,xy=Number.POSITIVE_INFINITY,se={free:{name:"Free",price:"$0",limit:th,audience:"Personal, ad-supported",note:"Up to 5 personal devices supported by a standard banner."},ltd:{name:"Plus",price:"$5",ltd:"$79 LTD",limit:Of,audience:"Creators and homelabs",note:"30 devices, no ads, personal use."},pro:{name:"Pro",price:"$15",ltd:"$199 LTD",limit:xy,audience:"Business and studios",note:"Commercial use and larger Client walls."}},jy="0.1.617",zy={version:jy},Ty=String(zy.version).trim();function ah({size:d=22}){return c.jsxs("svg",{width:d,height:d,viewBox:"0 0 28 28",fill:"none",xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",children:[c.jsx("rect",{x:"2.5",y:"4",width:"14",height:"9",rx:"1.5",stroke:"currentColor",strokeWidth:"1.7",opacity:"0.42"}),c.jsx("path",{d:"M7 16v1.5h5",stroke:"currentColor",strokeWidth:"1.7",strokeLinecap:"round",opacity:"0.42"}),c.jsx("rect",{x:"10.5",y:"2.5",width:"14",height:"9",rx:"1.5",stroke:"currentColor",strokeWidth:"1.7",opacity:"0.62"}),c.jsx("path",{d:"M15 14.5V16h5",stroke:"currentColor",strokeWidth:"1.7",strokeLinecap:"round",opacity:"0.62"}),c.jsx("rect",{x:"6.5",y:"8.5",width:"15",height:"10",rx:"1.7",fill:"currentColor",fillOpacity:"0.12",stroke:"currentColor",strokeWidth:"1.9"}),c.jsx("path",{d:"M12 21v1.5H9.5M16 21v1.5h2.5M9.5 22.5h9",stroke:"currentColor",strokeWidth:"1.9",strokeLinecap:"round"})]})}const kd="npx -y --prefer-online livedesk@latest",En="https://livedesk-desktop-updates.lovecrdm.workers.dev/download/dev",Ey=`${En}/windows/x64`,Ay=`${En}/macos/x64`,My=`${En}/macos/arm64`,Ny=`${En}/linux/x64`,Dy=`${En}/linux/x64/deb`;function Oy(){if(typeof window>"u")return"home";const d=window.location.pathname.replace(/\/+$/,"")||"/";return d==="/"?"home":d==="/download"?"download":d==="/pricing"?"pricing":"not-found"}function nh(){return c.jsxs("a",{className:"site-brand",href:"/","aria-label":"VuvoDesk home",children:[c.jsx("span",{className:"site-brand-mark",children:c.jsx(ah,{size:25})}),c.jsx("span",{children:"VuvoDesk"})]})}function Uy({page:d}){const r=[{label:"Product",href:"/#product",active:d==="home"},{label:"Pricing",href:"/pricing",active:d==="pricing"},{label:"Download",href:"/download",active:d==="download"},{label:"Support",href:"/support",active:!1}];return c.jsx("header",{className:"site-header",children:c.jsxs("div",{className:"site-header-inner",children:[c.jsx(nh,{}),c.jsx("nav",{className:"site-nav","aria-label":"Main navigation",children:r.map(v=>c.jsx("a",{className:v.active?"active":"",href:v.href,children:v.label},v.label))}),c.jsxs("div",{className:"site-header-actions",children:[c.jsx("a",{className:"site-text-link",href:"/app",children:"Open web console"}),c.jsxs("a",{className:"site-button site-button-small",href:"/download",children:["Get VuvoDesk ",c.jsx(Ut,{size:15})]})]}),c.jsxs("details",{className:"site-mobile-menu",children:[c.jsx("summary",{"aria-label":"Open navigation",children:c.jsx(Uv,{size:22})}),c.jsxs("nav",{"aria-label":"Mobile navigation",children:[r.map(v=>c.jsxs("a",{href:v.href,children:[v.label,c.jsx(Cd,{size:15})]},v.label)),c.jsxs("a",{href:"/app",children:["Open web console",c.jsx(Cd,{size:15})]})]})]})]})})}function _y(){return c.jsxs("footer",{className:"site-footer",children:[c.jsxs("div",{className:"site-footer-main",children:[c.jsxs("div",{children:[c.jsx(nh,{}),c.jsx("p",{children:"One calm command center for every computer you manage."})]}),c.jsxs("div",{className:"site-footer-links",children:[c.jsxs("div",{children:[c.jsx("strong",{children:"Product"}),c.jsx("a",{href:"/#product",children:"Overview"}),c.jsx("a",{href:"/pricing",children:"Pricing"}),c.jsx("a",{href:"/download",children:"Download"})]}),c.jsxs("div",{children:[c.jsx("strong",{children:"Use VuvoDesk"}),c.jsx("a",{href:"/app",children:"Web console"}),c.jsx("a",{href:"/support",children:"Support"})]}),c.jsxs("div",{children:[c.jsx("strong",{children:"Platforms"}),c.jsx("span",{children:"Windows"}),c.jsx("span",{children:"macOS"}),c.jsx("span",{children:"Linux"}),c.jsx("span",{children:"Mobile PWA"})]})]})]}),c.jsxs("div",{className:"site-footer-bottom",children:[c.jsx("span",{children:"© 2026 VuvoDesk"}),c.jsx("span",{children:"Built for people who run real work across many screens."})]})]})}function Hy(){const d=[{name:"Studio-01",status:"Online",className:"screen-blue",cpu:"42%",ram:"61%"},{name:"Render-Mac",status:"Online",className:"screen-purple",cpu:"67%",ram:"74%"},{name:"Linux-Build",status:"Online",className:"screen-green",cpu:"29%",ram:"48%"},{name:"Office-PC",status:"Idle",className:"screen-orange",cpu:"18%",ram:"37%"}];return c.jsxs("div",{className:"product-mockup","aria-label":"VuvoDesk screen wall preview",children:[c.jsxs("div",{className:"mockup-window-bar",children:[c.jsxs("div",{children:[c.jsx("i",{}),c.jsx("i",{}),c.jsx("i",{})]}),c.jsx("span",{children:"VuvoDesk · Wall"}),c.jsxs("span",{className:"mockup-online",children:[c.jsx("i",{})," 4 online"]})]}),c.jsxs("div",{className:"mockup-body",children:[c.jsxs("aside",{className:"mockup-rail","aria-hidden":"true",children:[c.jsx("span",{className:"active",children:c.jsx($d,{size:17})}),c.jsx("span",{children:c.jsx($u,{size:17})}),c.jsx("span",{children:c.jsx(Fd,{size:17})}),c.jsx("span",{children:c.jsx(Id,{size:17})})]}),c.jsx("div",{className:"mockup-wall",children:d.map(r=>c.jsxs("article",{className:"mockup-screen",children:[c.jsxs("div",{className:`mockup-screen-image ${r.className}`,children:[c.jsx("span",{className:"mockup-code-line wide"}),c.jsx("span",{className:"mockup-code-line"}),c.jsx("span",{className:"mockup-code-line short"}),c.jsx("span",{className:"mockup-panel-block"})]}),c.jsxs("div",{className:"mockup-screen-title",children:[c.jsx("strong",{children:r.name}),c.jsxs("span",{children:[c.jsx("i",{})," ",r.status]})]}),c.jsxs("div",{className:"mockup-metrics",children:[c.jsxs("span",{children:["CPU ",c.jsx("b",{children:r.cpu})]}),c.jsxs("span",{children:["RAM ",c.jsx("b",{children:r.ram})]})]})]},r.name))})]}),c.jsxs("div",{className:"mockup-control-card",children:[c.jsx($u,{size:18}),c.jsxs("span",{children:[c.jsx("small",{children:"Selected computer"}),c.jsx("strong",{children:"Render-Mac"})]}),c.jsx("button",{type:"button",children:"Control"})]})]})}function uh({compact:d=!1}){const r=[{key:"free",name:se.free.name,price:se.free.price,suffix:"forever",audience:se.free.audience,description:"A practical personal wall, supported by a standard banner.",features:[`Up to ${th} devices`,"Live wall and focused control","Standard banner"],action:"Start free",href:"/app"},{key:"plus",name:se.ltd.name,price:se.ltd.price,suffix:"/ month",audience:se.ltd.audience,description:"A clean personal command center for creators and homelabs.",features:[`Up to ${Of} devices`,"No standard banner","Personal use"],ltd:se.ltd.ltd,action:"Choose Plus",href:"/app?view=pricing"},{key:"pro",name:se.pro.name,price:se.pro.price,suffix:"/ month",audience:se.pro.audience,description:"Commercial monitoring for studios, offices, and growing fleets.",features:[`More than ${Of} Clients`,"Ad-free commercial use","Large screen walls"],ltd:se.pro.ltd,action:"Choose Pro",href:"/app?view=pricing"}];return c.jsx("div",{className:`site-pricing-grid ${d?"compact":""}`,children:r.map(v=>c.jsxs("article",{className:`site-price-card ${v.key==="plus"?"featured":""}`,children:[c.jsxs("div",{className:"site-price-heading",children:[c.jsx("span",{children:v.name}),v.key==="plus"&&c.jsx("em",{children:"Most popular"})]}),c.jsx("p",{className:"site-price-audience",children:v.audience}),c.jsxs("div",{className:"site-price",children:[c.jsx("strong",{children:v.price}),c.jsx("small",{children:v.suffix})]}),c.jsx("p",{children:v.description}),c.jsx("ul",{children:v.features.map(s=>c.jsxs("li",{children:[c.jsx(Yv,{size:16})," ",s]},s))}),v.ltd&&c.jsxs("div",{className:"site-ltd",children:[c.jsxs("span",{children:[v.name," LTD"]}),c.jsx("strong",{children:v.ltd.replace(" LTD","")}),c.jsx("small",{children:"one-time · available now"})]}),c.jsxs("a",{className:`site-price-action ${v.key==="plus"?"primary":""}`,href:v.href,children:[v.action,c.jsx(Ut,{size:15})]})]},v.key))})}function Cy(){return c.jsx(c.Fragment,{children:c.jsxs("main",{children:[c.jsxs("section",{className:"site-hero",children:[c.jsxs("div",{className:"site-hero-copy",children:[c.jsxs("span",{className:"site-kicker",children:[c.jsx(_v,{size:15})," The screen wall for real work"]}),c.jsxs("h1",{children:["Every computer.",c.jsx("br",{}),c.jsx("span",{children:"One calm command center."})]}),c.jsx("p",{children:"See every screen, focus the computer that needs you, and keep work moving from your desk or phone."}),c.jsxs("div",{className:"site-hero-actions",children:[c.jsxs("a",{className:"site-button",href:"/download",children:["Download VuvoDesk ",c.jsx(Ut,{size:17})]}),c.jsxs("a",{className:"site-button site-button-secondary",href:"/app",children:["Open web console ",c.jsx(Bd,{size:17})]})]}),c.jsxs("div",{className:"site-hero-notes",children:[c.jsxs("span",{children:[c.jsx(Sf,{size:15})," Free for 5 devices"]}),c.jsxs("span",{children:[c.jsx(Sf,{size:15})," No credit card"]}),c.jsxs("span",{children:[c.jsx(Sf,{size:15})," Windows · macOS · Linux"]})]})]}),c.jsxs("div",{className:"site-hero-visual",children:[c.jsx("div",{className:"site-orbit site-orbit-one"}),c.jsx("div",{className:"site-orbit site-orbit-two"}),c.jsx(Hy,{})]})]}),c.jsxs("section",{className:"platform-strip","aria-label":"Supported platforms",children:[c.jsx("span",{children:"Built for the computers you already run"}),c.jsxs("div",{children:[c.jsxs("strong",{children:[c.jsx(Wd,{size:18})," Windows"]}),c.jsxs("strong",{children:[c.jsx(Mf,{size:18})," macOS"]}),c.jsxs("strong",{children:[c.jsx(Nf,{size:18})," Linux"]}),c.jsxs("strong",{children:[c.jsx(ku,{size:18})," iPhone & Android"]}),c.jsxs("strong",{children:[c.jsx(Bd,{size:18})," Any browser"]})]})]}),c.jsxs("section",{className:"site-section site-value-section",id:"product",children:[c.jsxs("div",{className:"site-section-heading",children:[c.jsx("span",{children:"Why VuvoDesk"}),c.jsxs("h2",{children:["Spend less time finding the problem.",c.jsx("br",{}),"Spend more time fixing it."]}),c.jsx("p",{children:"VuvoDesk keeps the fleet visible without turning your desktop into a pile of remote windows."})]}),c.jsxs("div",{className:"site-value-grid",children:[c.jsxs("article",{className:"site-value-card large blue",children:[c.jsx("span",{className:"site-feature-icon",children:c.jsx($d,{size:23})}),c.jsx("h3",{children:"A wall that stays readable"}),c.jsx("p",{children:"Move from a compact list to large live previews. Keep the signal you need and hide the noise you do not."}),c.jsxs("div",{className:"feature-wall-demo",children:[c.jsx("i",{}),c.jsx("i",{}),c.jsx("i",{}),c.jsx("i",{}),c.jsx("i",{}),c.jsx("i",{})]})]}),c.jsxs("article",{className:"site-value-card mint",children:[c.jsx("span",{className:"site-feature-icon",children:c.jsx($u,{size:23})}),c.jsx("h3",{children:"Control without losing context"}),c.jsx("p",{children:"Jump from Wall to focused Control, then return to the same fleet view."}),c.jsxs("div",{className:"feature-cursor-demo",children:[c.jsx($u,{size:31}),c.jsx("span",{children:"Direct control"})]})]}),c.jsxs("article",{className:"site-value-card violet",children:[c.jsx("span",{className:"site-feature-icon",children:c.jsx(Hv,{size:23})}),c.jsx("h3",{children:"Your fleet in your pocket"}),c.jsx("p",{children:"Install the PWA on iPhone or Android and check the room before you walk back to it."}),c.jsxs("div",{className:"feature-phone-demo",children:[c.jsx("span",{}),c.jsxs("div",{children:[c.jsx("i",{}),c.jsx("i",{}),c.jsx("i",{})]})]})]}),c.jsxs("article",{className:"site-value-card wide dark",children:[c.jsxs("div",{children:[c.jsxs("span",{className:"site-kicker dark",children:[c.jsx(Cv,{size:14})," Local-first when possible"]}),c.jsx("h3",{children:"Fast where you work. Reachable when you leave."}),c.jsx("p",{children:"VuvoDesk prefers the shortest useful route and keeps the current screen moving instead of building a stale queue."})]}),c.jsxs("div",{className:"feature-route",children:[c.jsxs("span",{children:[c.jsx(Mf,{size:19})," Hub"]}),c.jsx("i",{}),c.jsxs("span",{children:[c.jsx(Bv,{size:19})," Clients"]}),c.jsx("i",{}),c.jsxs("span",{children:[c.jsx(ku,{size:19})," PWA"]})]})]})]})]}),c.jsxs("section",{className:"site-section site-workflow",children:[c.jsxs("div",{className:"site-section-heading centered",children:[c.jsx("span",{children:"Start in three steps"}),c.jsx("h2",{children:"From zero to a live wall in minutes."})]}),c.jsxs("div",{className:"workflow-grid",children:[c.jsxs("article",{children:[c.jsx("b",{children:"01"}),c.jsx("span",{children:c.jsx(Dt,{size:21})}),c.jsx("h3",{children:"Install the Hub"}),c.jsx("p",{children:"Choose the computer that will organize your VuvoDesk fleet."})]}),c.jsxs("article",{children:[c.jsx("b",{children:"02"}),c.jsx("span",{children:c.jsx(Fd,{size:21})}),c.jsx("h3",{children:"Connect Clients"}),c.jsx("p",{children:"Use one PIN to add the Windows, Mac, and Linux computers you manage."})]}),c.jsxs("article",{children:[c.jsx("b",{children:"03"}),c.jsx("span",{children:c.jsx(ku,{size:21})}),c.jsx("h3",{children:"Manage from anywhere"}),c.jsx("p",{children:"Open the web console or install the mobile PWA and keep every screen close."})]})]})]}),c.jsxs("section",{className:"site-section site-pricing-section",children:[c.jsxs("div",{className:"site-section-heading centered",children:[c.jsx("span",{children:"Simple pricing"}),c.jsx("h2",{children:"Start free. Upgrade when the wall earns its place."}),c.jsx("p",{children:"Monthly prices stay easy to understand. Lifetime offers are available separately below each paid plan."})]}),c.jsx(uh,{compact:!0}),c.jsxs("a",{className:"site-inline-link",href:"/pricing",children:["Compare every plan ",c.jsx(Ut,{size:15})]})]}),c.jsxs("section",{className:"site-final-cta",children:[c.jsxs("div",{children:[c.jsxs("span",{className:"site-kicker dark",children:[c.jsx(qv,{size:14})," Your fleet, one glance away"]}),c.jsxs("h2",{children:["Give every computer",c.jsx("br",{}),"one clear place to report."]})]}),c.jsxs("div",{children:[c.jsx("p",{children:"Start with five devices for free. Install the Hub, connect a Client, and open your first live wall."}),c.jsxs("div",{children:[c.jsxs("a",{className:"site-button light",href:"/download",children:["Get VuvoDesk ",c.jsx(Ut,{size:17})]}),c.jsx("a",{className:"site-button ghost",href:"/app",children:"Open console"})]})]})]})]})})}function By(){const[d,r]=jn.useState(!1),v=async()=>{try{await navigator.clipboard.writeText(kd),r(!0),window.setTimeout(()=>r(!1),1800)}catch{r(!1)}};return c.jsxs("main",{className:"site-subpage",children:[c.jsxs("section",{className:"site-subpage-hero download-hero",children:[c.jsxs("span",{className:"site-kicker",children:[c.jsx(Dt,{size:15})," Download VuvoDesk"]}),c.jsxs("h1",{children:["Turn one computer into",c.jsx("br",{}),c.jsx("span",{children:"your command center."})]}),c.jsx("p",{children:"Use the latest temporary installer for your computer. These preview links always follow the newest matching file published to the VuvoDesk download channel."})]}),c.jsxs("section",{className:"download-grid",children:[c.jsxs("article",{id:"windows",children:[c.jsx("span",{className:"download-platform-icon windows",children:c.jsx(Wd,{size:27})}),c.jsxs("div",{children:[c.jsx("small",{children:"Windows"}),c.jsx("span",{className:"download-version",children:"Latest temporary build · x64 Electron"}),c.jsx("span",{className:"download-preview-note",children:"Temporary installer · unsigned"}),c.jsx("h2",{children:"Install VuvoDesk for Windows"}),c.jsx("p",{children:"Download the normal Electron setup program. Windows SmartScreen may warn about this preview until code signing is ready."})]}),c.jsxs("a",{className:"download-installer-link",href:Ey,children:["Download Windows installer ",c.jsx(Dt,{size:16})]})]}),c.jsxs("article",{id:"macos",children:[c.jsx("span",{className:"download-platform-icon mac",children:c.jsx(Mf,{size:27})}),c.jsxs("div",{children:[c.jsx("small",{children:"macOS"}),c.jsx("span",{className:"download-version",children:"Latest temporary build · Intel & Apple silicon"}),c.jsx("span",{className:"download-preview-note",children:"Temporary installer · ad-hoc signed · not notarized"}),c.jsx("h2",{children:"Install VuvoDesk for macOS"}),c.jsx("p",{children:"Choose the chip in your Mac. On first launch, macOS may require Open Anyway in Privacy & Security because this preview is not Apple-notarized."})]}),c.jsxs("div",{className:"download-actions",children:[c.jsxs("a",{className:"download-installer-link",href:My,children:["Apple silicon ",c.jsx(Dt,{size:16})]}),c.jsxs("a",{className:"download-installer-link secondary",href:Ay,children:["Intel Mac ",c.jsx(Dt,{size:16})]})]})]}),c.jsxs("article",{id:"linux",children:[c.jsx("span",{className:"download-platform-icon linux",children:c.jsx(Nf,{size:27})}),c.jsxs("div",{children:[c.jsx("small",{children:"Linux"}),c.jsx("span",{className:"download-version",children:"Latest temporary build · x64 · X11"}),c.jsx("span",{className:"download-preview-note",children:"Temporary installer"}),c.jsx("h2",{children:"Install VuvoDesk for Linux"}),c.jsx("p",{children:"Use the DEB package on Ubuntu, Debian, or Mint. For other distributions, download AppImage, mark it executable, then open it."})]}),c.jsxs("div",{className:"download-actions",children:[c.jsxs("a",{className:"download-installer-link",href:Dy,children:["Download .deb ",c.jsx(Dt,{size:16})]}),c.jsxs("a",{className:"download-installer-link secondary",href:Ny,children:["Download AppImage ",c.jsx(Dt,{size:16})]})]})]})]}),c.jsxs("section",{className:"install-command-card",id:"install-command",children:[c.jsxs("div",{children:[c.jsxs("span",{children:[c.jsx(Nf,{size:18})," One command install"]}),c.jsx("h2",{children:"Terminal fallback and advanced setup"}),c.jsx("p",{children:"Use the npm package when you prefer a command-line install or the temporary desktop package does not suit your system."})]}),c.jsxs("div",{className:"install-command",children:[c.jsx("code",{children:kd}),c.jsxs("button",{type:"button",onClick:()=>{v()},children:[c.jsx(Rv,{size:17})," ",d?"Copied":"Copy"]})]}),c.jsxs("ol",{children:[c.jsxs("li",{children:[c.jsx("b",{children:"1"}),c.jsx("span",{children:"Run the command on the computer that will be your Hub."})]}),c.jsxs("li",{children:[c.jsx("b",{children:"2"}),c.jsx("span",{children:"Open Settings and create a Hub PIN."})]}),c.jsxs("li",{children:[c.jsx("b",{children:"3"}),c.jsx("span",{children:"Run the same package as a Client on the other computers."})]})]})]}),c.jsxs("section",{className:"mobile-install-section",id:"mobile",children:[c.jsxs("div",{className:"mobile-install-heading",children:[c.jsx("span",{children:c.jsx(ku,{size:26})}),c.jsxs("div",{children:[c.jsxs("small",{children:["iPhone & Android · PWA ",Ty]}),c.jsx("h2",{children:"No app store required."}),c.jsx("p",{children:"Open the public web address, sign in, then install VuvoDesk on the Home Screen. The PWA always starts directly in the console."})]})]}),c.jsxs("div",{className:"mobile-web-address",children:[c.jsx("span",{children:"Mobile web address"}),c.jsx("a",{href:"https://vuvodesk.com/app",children:"https://vuvodesk.com/app"}),c.jsxs("a",{className:"site-button",href:"/app",children:["Open mobile console ",c.jsx(Ut,{size:16})]})]}),c.jsxs("div",{className:"pwa-guide-grid",children:[c.jsxs("article",{children:[c.jsx("strong",{children:"iPhone & iPad"}),c.jsxs("ol",{children:[c.jsx("li",{children:"Open the address in Safari."}),c.jsx("li",{children:"Tap Share, then Add to Home Screen."}),c.jsx("li",{children:"Choose Open as Web App and add VuvoDesk."})]})]}),c.jsxs("article",{children:[c.jsx("strong",{children:"Android"}),c.jsxs("ol",{children:[c.jsx("li",{children:"Open the address in Chrome."}),c.jsx("li",{children:"Open the browser menu and tap Install app."}),c.jsx("li",{children:"Launch VuvoDesk from the Home Screen."})]})]})]})]})]})}function qy(){return c.jsxs("main",{className:"site-subpage pricing-subpage",children:[c.jsxs("section",{className:"site-subpage-hero",children:[c.jsxs("span",{className:"site-kicker",children:[c.jsx(qd,{size:15})," VuvoDesk pricing"]}),c.jsxs("h1",{children:["Clear plans for",c.jsx("br",{}),c.jsx("span",{children:"growing screen walls."})]}),c.jsx("p",{children:"Use VuvoDesk free on five personal computers. Choose Plus for a larger ad-free personal wall, or Pro for commercial work."})]}),c.jsx(uh,{}),c.jsxs("section",{className:"pricing-explainer",children:[c.jsxs("article",{children:[c.jsx(wv,{size:21}),c.jsxs("div",{children:[c.jsx("h3",{children:"Free stays useful"}),c.jsx("p",{children:"The standard banner helps keep a five-device personal wall available without a subscription."})]})]}),c.jsxs("article",{children:[c.jsx(qd,{size:21}),c.jsxs("div",{children:[c.jsx("h3",{children:"Monthly and lifetime are separate"}),c.jsx("p",{children:"$5 and $15 are monthly plan prices. Plus LTD $79 and Pro LTD $199 are one-time offers shown separately."})]})]}),c.jsxs("article",{children:[c.jsx(Id,{size:21}),c.jsxs("div",{children:[c.jsx("h3",{children:"Upgrade inside VuvoDesk"}),c.jsx("p",{children:"Sign in to the console, open Pricing, and choose the plan that matches the way you use the fleet."})]})]})]}),c.jsxs("section",{className:"pricing-bottom-cta",children:[c.jsxs("div",{children:[c.jsx("h2",{children:"Start with the computers you have today."}),c.jsx("p",{children:"No credit card is needed for Free."})]}),c.jsxs("a",{className:"site-button",href:"/app",children:["Start free ",c.jsx(Ut,{size:16})]})]})]})}function Ry(){return c.jsxs("main",{className:"site-not-found",children:[c.jsx("span",{className:"site-brand-mark",children:c.jsx(ah,{size:25})}),c.jsx("small",{children:"404"}),c.jsx("h1",{children:"This screen is not on the wall."}),c.jsx("p",{children:"The page may have moved, but your VuvoDesk console is still here."}),c.jsxs("div",{children:[c.jsx("a",{className:"site-button",href:"/",children:"VuvoDesk home"}),c.jsx("a",{className:"site-button site-button-secondary",href:"/app",children:"Open console"})]})]})}function wy(){const d=Oy();return jn.useEffect(()=>{const r={home:"VuvoDesk — Every computer. One calm command center.",download:"Download VuvoDesk — Windows, macOS, and Linux",pricing:"VuvoDesk Pricing — Free, Plus, and Pro","not-found":"Page not found — VuvoDesk"};return document.title=r[d],document.documentElement.classList.add("livedesk-marketing-active"),()=>document.documentElement.classList.remove("livedesk-marketing-active")},[d]),c.jsxs("div",{className:"marketing-site",children:[c.jsx(Uy,{page:d}),d==="home"?c.jsx(Cy,{}):d==="download"?c.jsx(By,{}):d==="pricing"?c.jsx(qy,{}):c.jsx(Ry,{}),c.jsx(_y,{})]})}function Yy(d){return!!d.navigatorStandalone||!!d.displayModeStandalone||!!d.displayModeFullscreen}function Gy({publicOrigin:d,electron:r,pathname:v,search:s="",navigatorStandalone:T=!1,displayModeStandalone:E=!1,displayModeFullscreen:A=!1,marketingPreview:H=!1}){if(r||!d&&!H)return{kind:"app",redirectPath:""};const C=new URLSearchParams(s),w=C.has("pwa")||Yy({navigatorStandalone:T,displayModeStandalone:E,displayModeFullscreen:A}),ll=v==="/app"||v.startsWith("/app/"),D=v==="/support"||v.startsWith("/support/"),K=C.has("checkout");return w||K?{kind:"app",redirectPath:ll?"":"/app"}:ll||D?{kind:"app",redirectPath:""}:{kind:"site",redirectPath:""}}const Ly=jn.lazy(()=>Qv(()=>import("./LiveDeskApp-HaQ9U3be.js"),__vite__mapDeps([0,1,2,3,4])).then(d=>({default:d.LiveDeskApp})));window.liveDesk&&document.documentElement.classList.add("livedesk-electron-desktop");const Ot=new URL(window.location.href),Xy=!!window.navigator.standalone,Uf=Gy({publicOrigin:Sy(),electron:!!window.liveDesk,pathname:Ot.pathname,search:Ot.search,navigatorStandalone:Xy,displayModeStandalone:window.matchMedia("(display-mode: standalone)").matches,displayModeFullscreen:window.matchMedia("(display-mode: fullscreen)").matches,marketingPreview:Ot.searchParams.get("site")==="1"});Uf.redirectPath&&(Ot.pathname=Uf.redirectPath,window.history.replaceState({},"",`${Ot.pathname}${Ot.search}${Ot.hash}`));$v.createRoot(document.getElementById("root")).render(c.jsx(jn.StrictMode,{children:Uf.kind==="site"?c.jsx(wy,{}):c.jsx(jn.Suspense,{fallback:c.jsx("main",{className:"runtime-role-boot","aria-label":"Starting VuvoDesk",children:c.jsx("strong",{children:"Starting VuvoDesk"})}),children:c.jsx(Ly,{})})}));const ih="serviceWorker"in navigator&&window.isSecureContext&&window.location.protocol==="https:";let Ef=null;function Af(){!ih||Ef||(Ef=(async()=>{await(await navigator.serviceWorker.register("/sw.js",{updateViaCache:"none"})).update();const r=await fetch(`/sw.js?pwa-release-check=${Date.now()}`,{cache:"no-store"});if(!r.ok)return;const s=(await r.text()).match(/const PWA_RELEASE = ['"](\d+\.\d+\.\d+)['"];/)?.[1],T=new URL(window.location.href);if(!s||!T.searchParams.has("pwa"))return;const E=T.pathname!=="/app",A=T.searchParams.get("pwa")!==s;!E&&!A||(T.pathname="/app",T.searchParams.set("pwa",s),window.location.replace(T.toString()))})().catch(d=>{console.warn("[VuvoDesk] PWA update check failed.",d)}).finally(()=>{Ef=null}))}ih&&(Af(),window.addEventListener("pageshow",Af),document.addEventListener("visibilitychange",()=>{document.visibilityState==="visible"&&Af()}));export{zn as D,th as F,ah as M,Of as P,Wy as a,Ky as b,Jy as c,Iy as d,l0 as e,Py as f,gy as g,py as h,Sy as i,c as j,by as k,$y as l,ky as m,Tn as n,se as p,Zy as r,Fy as w};
|
package/web/dist/index.html
CHANGED
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
<link rel="icon" href="/favicon.ico" sizes="any" />
|
|
19
19
|
<link rel="apple-touch-icon" href="/apple-touch-icon.png" />
|
|
20
20
|
<title>VuvoDesk — Every computer. One calm command center.</title>
|
|
21
|
-
<script type="module" crossorigin src="/assets/index-
|
|
21
|
+
<script type="module" crossorigin src="/assets/index-CqZbwCrG.js"></script>
|
|
22
22
|
<link rel="modulepreload" crossorigin href="/assets/icons-tFaWqIIe.js">
|
|
23
23
|
<link rel="modulepreload" crossorigin href="/assets/react-BQos8uGS.js">
|
|
24
24
|
<link rel="stylesheet" crossorigin href="/assets/index-CKNX8KEY.css">
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schemaVersion": 2,
|
|
3
3
|
"kind": "livedesk-production-web-source-evidence",
|
|
4
|
-
"generatedAt": "2026-08-
|
|
5
|
-
"pwaRelease": "0.1.
|
|
6
|
-
"sourceHash": "
|
|
4
|
+
"generatedAt": "2026-08-25T13:43:58.576Z",
|
|
5
|
+
"pwaRelease": "0.1.617",
|
|
6
|
+
"sourceHash": "a0e11b0d1151af7b5e74c74aa3fdc3f4534cce13b5fcd653c0346ab4dabbea3c",
|
|
7
7
|
"sourceFileCount": 167,
|
|
8
|
-
"sourceBytes":
|
|
8
|
+
"sourceBytes": 2402615,
|
|
9
9
|
"viteEnvironmentHash": "4f53cda18c2baa0c0354bb5f9a3ecbe5ed12ab4d8e11ba873c2f11161202b945",
|
|
10
|
-
"outputHash": "
|
|
10
|
+
"outputHash": "1dd93fc78e32745b3eef31242b50c71ad6a65174e284c41a7e60b96f7962b310",
|
|
11
11
|
"outputFileCount": 20,
|
|
12
12
|
"outputBytes": 1710277,
|
|
13
13
|
"outputManifest": [
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
{
|
|
20
20
|
"path": "app.webmanifest",
|
|
21
21
|
"bytes": 841,
|
|
22
|
-
"sha256": "
|
|
22
|
+
"sha256": "b64d4ef5c8490cf173370d24691914519cb1382d9b8883d3637eb68d37ecb2dc"
|
|
23
23
|
},
|
|
24
24
|
{
|
|
25
25
|
"path": "apple-touch-icon.png",
|
|
@@ -37,9 +37,9 @@
|
|
|
37
37
|
"sha256": "c24afe589f9797df9b81d3009bd90e14f4cec87860bebc2f7aba6e08fb971c6c"
|
|
38
38
|
},
|
|
39
39
|
{
|
|
40
|
-
"path": "assets/index-
|
|
40
|
+
"path": "assets/index-CqZbwCrG.js",
|
|
41
41
|
"bytes": 224826,
|
|
42
|
-
"sha256": "
|
|
42
|
+
"sha256": "c59a5dbdb8517033342ab355802cd4d481e344f8af23eb3182a178275cf55025"
|
|
43
43
|
},
|
|
44
44
|
{
|
|
45
45
|
"path": "assets/LiveDeskApp-ChGXEkMA.css",
|
|
@@ -47,9 +47,9 @@
|
|
|
47
47
|
"sha256": "7a0fd24bdd85c2df6493ef78c5fb3dc92a1b32bb4adaf1092728c11fc9420163"
|
|
48
48
|
},
|
|
49
49
|
{
|
|
50
|
-
"path": "assets/LiveDeskApp-
|
|
50
|
+
"path": "assets/LiveDeskApp-HaQ9U3be.js",
|
|
51
51
|
"bytes": 820859,
|
|
52
|
-
"sha256": "
|
|
52
|
+
"sha256": "82a562210e198a99a8580e0e6fa3411fa727b6da6d9fd597605e99a129bfb2d9"
|
|
53
53
|
},
|
|
54
54
|
{
|
|
55
55
|
"path": "assets/react-BQos8uGS.js",
|
|
@@ -84,7 +84,7 @@
|
|
|
84
84
|
{
|
|
85
85
|
"path": "index.html",
|
|
86
86
|
"bytes": 1684,
|
|
87
|
-
"sha256": "
|
|
87
|
+
"sha256": "5b9313fa14fa58099869e10795146c2c3de8fde2f519a046fc88ba581b83a5ff"
|
|
88
88
|
},
|
|
89
89
|
{
|
|
90
90
|
"path": "offline.html",
|
|
@@ -109,7 +109,7 @@
|
|
|
109
109
|
{
|
|
110
110
|
"path": "sw.js",
|
|
111
111
|
"bytes": 1460,
|
|
112
|
-
"sha256": "
|
|
112
|
+
"sha256": "eb80d10aa2a4dfcd6dca0e224083c31db38f5ef19a9b3905274b4297bc7121ad"
|
|
113
113
|
}
|
|
114
114
|
]
|
|
115
115
|
}
|
package/web/dist/sw.js
CHANGED