diff --git a/server/public/assets/index-DOsCnBty.js b/server/public/assets/index-Bxy0t7bb.js similarity index 98% rename from server/public/assets/index-DOsCnBty.js rename to server/public/assets/index-Bxy0t7bb.js index 021ed7b0..8c294466 100644 --- a/server/public/assets/index-DOsCnBty.js +++ b/server/public/assets/index-Bxy0t7bb.js @@ -15,7 +15,7 @@ ${w}`}).join(` ---------------------------------------- `):""};return r.jsxs("div",{className:"space-y-0.5",children:[r.jsx("div",{className:"panel-muted text-xs uppercase",children:"Overseer Control"}),r.jsx("div",{className:"flex gap-0.5 text-xs",children:r.jsx("button",{type:"button",onClick:a,disabled:!!l,className:"button-danger disabled:cursor-not-allowed disabled:opacity-60",children:l?"Clearing...":"Clear Overseer History"})}),r.jsxs("div",{className:"surface flex flex-wrap gap-0.5 text-xs",children:[r.jsxs("span",{className:"surface-muted",children:["running: ",f.running?"yes":"no"]}),r.jsxs("span",{className:"surface-muted",children:["phase: ",f.phase||"--"]}),r.jsxs("span",{className:"surface-muted",children:["tick: ",f.tickCount??0]}),r.jsxs("span",{className:"surface-muted",children:["trigger: ",f.lastTriggerReason||"--"]}),r.jsxs("span",{className:"surface-muted",children:["name: ",p.name||"--"]}),r.jsxs("span",{className:"surface-muted",children:["model: ",p.model||"--"]}),r.jsxs("span",{className:"surface-muted",children:["observeOnly: ",p.observeOnly?"yes":"no"]}),r.jsxs("span",{className:"surface-muted",children:["decision: ",v.normalized||"--"]}),r.jsxs("span",{className:"surface-muted",children:["outcome: ",v.outcome||"--"]}),r.jsxs("span",{className:"surface-muted",children:["reason: ",v.reason||"--"]}),r.jsxs("span",{className:"surface-muted",children:["last gen: ",g.lastGenerationMs!=null?`${g.lastGenerationMs}ms`:"--"]})]}),r.jsxs("details",{className:"surface text-xs text-slate-200",open:!0,children:[r.jsx("summary",{className:"cursor-pointer select-none text-slate-300",children:"Latest Context"}),r.jsx("pre",{className:"mt-0.5 whitespace-pre-wrap break-words text-[0.72rem] text-slate-200",children:x.stateUpdate||""})]}),r.jsxs("details",{className:"surface text-xs text-slate-200",open:!0,children:[r.jsx("summary",{className:"cursor-pointer select-none text-slate-300",children:"Exact Model Input (messages[])"}),r.jsx("pre",{className:"mt-0.5 whitespace-pre-wrap break-words text-[0.72rem] text-slate-200",children:b()})]}),r.jsxs("details",{className:"surface text-xs text-slate-200",children:[r.jsx("summary",{className:"cursor-pointer select-none text-slate-300",children:"Exact System Prompt"}),r.jsx("pre",{className:"mt-0.5 whitespace-pre-wrap break-words text-[0.72rem] text-slate-200",children:x.systemPrompt||""})]}),r.jsxs("details",{className:"surface text-xs text-slate-200",children:[r.jsx("summary",{className:"cursor-pointer select-none text-slate-300",children:"Exact Transcript Rows"}),r.jsx("pre",{className:"mt-0.5 whitespace-pre-wrap break-words text-[0.72rem] text-slate-200",children:JSON.stringify(x.transcript||[],null,2)})]}),r.jsxs("details",{className:"surface text-xs text-slate-200",children:[r.jsx("summary",{className:"cursor-pointer select-none text-slate-300",children:"Tool Availability"}),r.jsx("pre",{className:"mt-0.5 whitespace-pre-wrap break-words text-[0.72rem] text-slate-200",children:JSON.stringify({available:x.availableTools,blocked:x.blockedTools},null,2)})]}),r.jsxs("details",{className:"surface text-xs text-slate-200",open:!0,children:[r.jsx("summary",{className:"cursor-pointer select-none text-slate-300",children:"Exact Model Output"}),r.jsx("pre",{className:"mt-0.5 whitespace-pre-wrap break-words text-[0.72rem] text-slate-200",children:v.raw||""})]}),r.jsxs("details",{className:"surface text-xs text-slate-200",open:!0,children:[r.jsx("summary",{className:"cursor-pointer select-none text-slate-300",children:"Live Tool Calls"}),r.jsx("pre",{className:"mt-0.5 whitespace-pre-wrap break-words text-[0.72rem] text-slate-200",children:JSON.stringify(v.liveToolCalls||[],null,2)})]}),r.jsxs("div",{className:"surface text-xs text-slate-200",children:[r.jsxs("div",{children:["Normalized decision: ",v.normalized||"--"]}),r.jsxs("div",{children:["Model input at: ",x.modelInputAt?new Date(x.modelInputAt).toLocaleString():"n/a"]}),r.jsxs("div",{children:["Model output at: ",v.outputAt?new Date(v.outputAt).toLocaleString():"n/a"]})]}),z.message?r.jsxs("div",{className:"surface text-xs text-red-300",children:["Error: ",z.message]}):null,r.jsxs("details",{className:"surface text-xs text-slate-200",children:[r.jsx("summary",{className:"cursor-pointer select-none text-slate-300",children:"Recent Runs"}),r.jsx("pre",{className:"mt-0.5 whitespace-pre-wrap break-words text-[0.72rem] text-slate-200",children:JSON.stringify(t.history||[],null,2)})]}),r.jsx("button",{type:"button",className:"button-dark text-xs",onClick:()=>u(y=>!y),children:s?"Hide Full Payload":"Show Full Payload"}),s?r.jsx("pre",{className:"surface whitespace-pre-wrap break-words text-[0.72rem] text-slate-200",children:JSON.stringify(t,null,2)}):null]})}function nQ({health:t,roster:a=[]}){if(!t)return null;const l=t.replay||{sources:[],readyCount:0,totalCount:0},s=t.snapshots||{rovers:[],rooms:[]},u=g=>a.find(x=>String(x.id)===String(g))?.color||null,f=`${l.readyCount}/${l.totalCount} sources ready`,p=s.rovers.filter(g=>g.stale).length,v=s.rooms.filter(g=>g.stale).length;return r.jsxs("div",{className:"space-y-0.5",children:[r.jsx("div",{className:"panel-muted text-xs uppercase",children:"Health"}),r.jsxs("div",{className:"surface space-y-0.5 text-xs text-slate-200",children:[r.jsxs("div",{className:"flex items-center justify-between",children:[r.jsx("span",{children:"Replay segments"}),r.jsx("span",{className:"text-slate-400",children:f})]}),r.jsxs("div",{className:"flex items-center justify-between",children:[r.jsx("span",{children:"Rover snapshots"}),r.jsxs("span",{className:p?"text-amber-300":"text-emerald-300",children:[s.rovers.length-p,"/",s.rovers.length," ok"]})]}),r.jsxs("div",{className:"flex items-center justify-between",children:[r.jsx("span",{children:"Room cameras"}),r.jsxs("span",{className:v?"text-amber-300":"text-emerald-300",children:[s.rooms.length-v,"/",s.rooms.length," ok"]})]})]}),r.jsx("div",{className:"space-y-0.5 text-xs text-slate-300",children:l.sources.map(g=>r.jsxs("div",{className:"flex items-center justify-between",children:[g.type==="rover"?r.jsx(V4,{name:g.label,color:u(g.id),fallback:g.id}):r.jsx("span",{children:g.label}),r.jsxs("span",{className:g.ready?"text-emerald-300":"text-amber-300",children:[g.recentCount,"/",g.neededCount]})]},`${g.type}:${g.id}`))}),r.jsx("div",{className:"space-y-0.5 text-xs text-slate-300",children:s.rovers.map(g=>r.jsxs("div",{className:"flex items-center justify-between",children:[r.jsx(V4,{name:g.name,color:u(g.id),fallback:g.id}),r.jsx("span",{className:g.stale?"text-amber-300":"text-emerald-300",children:g.stale?"stale":"ok"})]},`rover:${g.id}`))}),r.jsx("div",{className:"space-y-0.5 text-xs text-slate-300",children:s.rooms.map(g=>r.jsxs("div",{className:"flex items-center justify-between",children:[r.jsx("span",{children:g.name}),r.jsx("span",{className:g.stale?"text-amber-300":"text-emerald-300",children:g.error?"error":g.stale?"stale":"ok"})]},`room:${g.id}`))})]})}function lQ({entries:t}){const a=t||[];return r.jsxs(j1,{title:"Admin IP log",meta:a.length,bodyClassName:"space-y-0.5 text-base",children:[r.jsx("div",{className:"h-64 overflow-y-auto font-mono text-xs",children:a.length===0?r.jsx("p",{children:"No admin log entries yet."}):a.slice().reverse().map(l=>r.jsxs("div",{children:[r.jsx("span",{className:"text-amber-400",children:l.ts?new Date(l.ts).toLocaleTimeString():"--"})," ",l.label&&r.jsxs("span",{className:"text-teal-400",children:["[",l.label,"]"]})," ",r.jsx("span",{className:"text-slate-200",children:l.message})," ",l.ip&&r.jsx("span",{className:"text-cyan-300",children:l.ip})," ",l.meta&&r.jsx("span",{className:"text-slate-500",children:JSON.stringify(l.meta)})]},l.id))}),r.jsx("p",{className:"text-xs text-slate-500",children:"Admin-only log stream; IPs never appear in user data."})]})}const rQ=[{key:"open",label:"Open"},{key:"turns",label:"Turns"},{key:"admin",label:"Admin"},{key:"lockdown",label:"Lockdown"}];function iQ(){const{session:t,lockRover:a,setMode:l,requestControl:s,setGlobalObjective:u,setAdminReason:f,rebootRover:p,updateRover:v,rebootServer:g,setAudioLevels:x,setPrivateSafety:z,llmControl:b,overseerControl:y,adminLogs:H,llmCommentaryState:S,overseerControlState:C}=H0(),w=d.useMemo(()=>t?.roster??[],[t?.roster]),[A,V]=d.useState({}),[L,R]=d.useState({}),[q,j]=d.useState({}),[N,E]=d.useState(!1),[G,O]=d.useState(!1),[T,U]=d.useState(!1),s1=t?.health||null,n1=t?.globalObjective?.text||"",Q=t?.globalObjective?.updatedAt||null,[k,$]=d.useState(n1),t1=t?.adminReason?.text||"",f1=t?.adminReason?.updatedAt||null,[h1,F]=d.useState(t1),D=t?.audioLevels||{},[W,r1]=d.useState({hornGain:Number.isFinite(D.hornGain)?D.hornGain:1,ttsGain:Number.isFinite(D.ttsGain)?D.ttsGain:1,forwardGain:Number.isFinite(D.forwardGain)?D.forwardGain:1}),[m1,v1]=d.useState({}),A1=t?.role==="admin"||t?.role==="lockdown"||t?.role==="lockdown-admin",V1=t?.role==="lockdown"||t?.role==="lockdown-admin",L1=t?.mode??"open",$1=async(P,c1)=>{try{await a(P,c1),V(y1=>({...y1,[P]:c1}))}catch(y1){alert(y1.message)}},K1=async P=>{const c1=P.target.value;u1("admin_mode_change",{mode:c1,status:"started"});try{await l(c1),u1("admin_mode_change",{mode:c1,status:"accepted"})}catch(y1){u1("admin_mode_change",{mode:c1,status:"failed",reason:y1?.message||"unknown"}),alert(y1.message)}},T1=async P=>{u1("admin_force_control",{roverId:P,status:"started"});try{await s(P,{force:!0}),u1("admin_force_control",{roverId:P,status:"accepted"})}catch(c1){u1("admin_force_control",{roverId:P,status:"failed",reason:c1?.message||"unknown"}),alert(c1.message)}},x1=async P=>{if(!(!P?.id||!window.confirm(`Reboot rover "${P.name||P.id}" now?`))){R(y1=>({...y1,[P.id]:!0})),u1("rover_reboot_click",{roverId:P.id,scope:"admin"});try{await p(P.id),u1("rover_reboot_result",{roverId:P.id,scope:"admin",status:"accepted"})}catch(y1){u1("rover_reboot_result",{roverId:P.id,scope:"admin",status:"failed",reason:y1?.message||"unknown"}),alert(y1.message)}finally{R(y1=>({...y1,[P.id]:!1}))}}},X=async P=>{if(!(!P?.id||!window.confirm(`Update rover "${P.name||P.id}" now? The rover will git pull the repo, run the roverd installer, and may disconnect while services restart.`))){j(y1=>({...y1,[P.id]:!0})),u1("rover_update_click",{roverId:P.id});try{await v(P.id),u1("rover_update_result",{roverId:P.id,status:"accepted"})}catch(y1){u1("rover_update_result",{roverId:P.id,status:"failed",reason:y1?.message||"unknown"}),alert(y1.message)}finally{j(y1=>({...y1,[P.id]:!1}))}}},g1=async()=>{if(window.confirm("Reboot the server host now? This will disconnect all users.")){E(!0),u1("server_reboot_click",{status:"started"});try{await g(),u1("server_reboot_click",{status:"accepted"})}catch(c1){u1("server_reboot_click",{status:"failed",reason:c1?.message||"unknown"}),alert(c1.message),E(!1)}}},M1=async()=>{if(window.confirm("Clear LLM commentary history now? This resets chat context, bot memory, and rover activity metrics for narration.")){O(!0);try{await b("clearHistory")}catch(c1){alert(c1.message)}finally{O(!1)}}},p1=async()=>{if(window.confirm("Clear Overseer Control history now?")){U(!0);try{await y("clearHistory")}catch(c1){alert(c1.message)}finally{U(!1)}}},R1=async()=>{try{await u(k)}catch(P){alert(P.message)}},l2=async()=>{try{await u(null)}catch(P){alert(P.message)}},z1=async()=>{try{await f(h1)}catch(P){alert(P.message)}},b1=async()=>{try{await f(null)}catch(P){alert(P.message)}},D1=P=>c1=>{const y1=Number(c1.target.value);r1(r2=>({...r2||{},[P]:Number.isFinite(y1)?y1:1}))},S2=async()=>{try{await x(W)}catch(P){alert(P.message)}},P1=async()=>{window.dispatchEvent(new CustomEvent("buttonBox:rewardRunLocalTest",{detail:{rewardName:"Admin Mode",count:1e3,goal:1e3}}))};d.useEffect(()=>{$(n1)},[n1]),d.useEffect(()=>{F(t1)},[t1]),d.useEffect(()=>{r1({hornGain:Number.isFinite(D.hornGain)?D.hornGain:1,ttsGain:Number.isFinite(D.ttsGain)?D.ttsGain:1,forwardGain:Number.isFinite(D.forwardGain)?D.forwardGain:1})},[D.forwardGain,D.hornGain,D.ttsGain]),d.useEffect(()=>{const P={};(w||[]).forEach(c1=>{c1?.private?.enabled&&(P[c1.id]={speedLimitEnabled:!!c1?.private?.safety?.speedLimitEnabled,speedLimitMaxWheelSpeed:Number.isFinite(c1?.private?.safety?.speedLimitMaxWheelSpeed)?c1.private.safety.speedLimitMaxWheelSpeed:250,hardOvercurrentEnabled:!!c1?.private?.safety?.hardOvercurrentEnabled,overcurrentStopMs:Number.isFinite(c1?.private?.safety?.overcurrentStopMs)?c1.private.safety.overcurrentStopMs:300,hardBumpEnabled:!!c1?.private?.safety?.hardBumpEnabled,bumpBackoffSpeed:Number.isFinite(c1?.private?.safety?.bumpBackoffSpeed)?c1.private.safety.bumpBackoffSpeed:250,bumpBackoffMs:Number.isFinite(c1?.private?.safety?.bumpBackoffMs)?c1.private.safety.bumpBackoffMs:350,cliffEnabled:!!c1?.private?.safety?.cliffEnabled,cliffBackoffSpeed:Number.isFinite(c1?.private?.safety?.cliffBackoffSpeed)?c1.private.safety.cliffBackoffSpeed:250,cliffBackoffMs:Number.isFinite(c1?.private?.safety?.cliffBackoffMs)?c1.private.safety.cliffBackoffMs:500,triggerCooldownMs:Number.isFinite(c1?.private?.safety?.triggerCooldownMs)?c1.private.safety.triggerCooldownMs:800})}),v1(P)},[w]);const p2=d.useMemo(()=>{const P={};return w.forEach(c1=>{P[c1.id]=A[c1.id]??c1.locked}),P},[w,A]),W1=(P,c1={})=>{v1(y1=>({...y1||{},[P]:{...y1?.[P]||{},...c1||{}}}))},t2=async P=>{try{const c1=m1?.[P];if(!c1)return;await z(P,c1)}catch(c1){alert(c1.message)}};if(!A1)return null;const o1=r.jsx("select",{value:L1,onChange:K1,className:"field-input text-sm",children:rQ.map(P=>r.jsx("option",{value:P.key,children:P.label},P.key))});return r.jsxs(j1,{title:"Admin controls",actions:o1,bodyClassName:"space-y-0.5 text-base",children:[r.jsxs("div",{className:"flex gap-0.5 text-xs",children:[r.jsx("button",{type:"button",onClick:g1,disabled:N,className:"button-danger disabled:cursor-not-allowed disabled:opacity-60",children:N?"Server rebooting...":"Reboot Server"}),r.jsx("button",{type:"button",onClick:P1,className:"button-dark",children:"Test Reward Popup"})]}),r.jsxs("div",{className:"space-y-0.5",children:[r.jsxs("div",{className:"flex items-center justify-between text-xs text-slate-400",children:[r.jsx("span",{children:"Global audio levels"}),t?.audioLevels?.updatedAt?r.jsxs("span",{children:["Updated ",new Date(t.audioLevels.updatedAt).toLocaleString()]}):null]}),r.jsxs("label",{className:"grid gap-0.5 text-xs text-slate-200",children:[r.jsxs("div",{className:"flex items-center justify-between gap-0.5",children:[r.jsx("span",{children:"Horn gain"}),r.jsxs("span",{children:[W.hornGain.toFixed(2),"x"]})]}),r.jsx("input",{type:"range",min:"0",max:"4",step:"0.01",value:W.hornGain,onChange:D1("hornGain"),className:"w-full accent-emerald-500"})]}),r.jsxs("label",{className:"grid gap-0.5 text-xs text-slate-200",children:[r.jsxs("div",{className:"flex items-center justify-between gap-0.5",children:[r.jsx("span",{children:"TTS gain"}),r.jsxs("span",{children:[W.ttsGain.toFixed(2),"x"]})]}),r.jsx("input",{type:"range",min:"0",max:"4",step:"0.01",value:W.ttsGain,onChange:D1("ttsGain"),className:"w-full accent-emerald-500"})]}),r.jsxs("label",{className:"grid gap-0.5 text-xs text-slate-200",children:[r.jsxs("div",{className:"flex items-center justify-between gap-0.5",children:[r.jsx("span",{children:"Forward gain"}),r.jsxs("span",{children:[W.forwardGain.toFixed(2),"x"]})]}),r.jsx("input",{type:"range",min:"0",max:"4",step:"0.01",value:W.forwardGain,onChange:D1("forwardGain"),className:"w-full accent-emerald-500"})]}),r.jsx("div",{className:"flex gap-0.5 text-xs",children:r.jsx("button",{type:"button",onClick:S2,className:"button-dark",children:"Apply audio levels"})})]}),r.jsxs("div",{className:"space-y-0.5",children:[r.jsxs("div",{className:"flex items-center justify-between text-xs text-slate-400",children:[r.jsx("span",{children:"Global objective"}),Q?r.jsxs("span",{children:["Updated ",new Date(Q).toLocaleString()]}):null]}),r.jsx("input",{type:"text",value:k,onChange:P=>$(P.target.value),placeholder:"Set a global objective",className:"field-input text-sm"}),r.jsxs("div",{className:"flex gap-0.5 text-xs",children:[r.jsx("button",{type:"button",onClick:R1,className:"button-dark",children:"Set objective"}),r.jsx("button",{type:"button",onClick:l2,className:"button-danger",children:"Clear"})]})]}),r.jsxs("div",{className:"space-y-0.5",children:[r.jsxs("div",{className:"flex items-center justify-between text-xs text-slate-400",children:[r.jsx("span",{children:"Admin mode reason"}),f1?r.jsxs("span",{children:["Updated ",new Date(f1).toLocaleString()]}):null]}),r.jsx("textarea",{value:h1,onChange:P=>F(P.target.value),placeholder:"Set an admin mode reason",className:"field-input text-sm min-h-[3.5rem]"}),r.jsxs("div",{className:"flex gap-0.5 text-xs",children:[r.jsx("button",{type:"button",onClick:z1,className:"button-dark",children:"Set reason"}),r.jsx("button",{type:"button",onClick:b1,className:"button-danger",children:"Clear"})]})]}),r.jsx(WK,{roster:w,renderActions:P=>r.jsxs("div",{className:"flex flex-wrap items-center gap-0.5 text-xs",children:[r.jsx("button",{type:"button",onClick:()=>$1(P.id,!p2[P.id]),className:"button-dark",children:p2[P.id]?"Unlock":"Lock"}),r.jsx("button",{type:"button",onClick:()=>T1(P.id),className:"button-dark",children:"Force"}),r.jsx("button",{type:"button",onClick:()=>x1(P),disabled:!!L[P.id],className:"button-danger disabled:cursor-not-allowed disabled:opacity-60",children:L[P.id]?"Rebooting...":"Reboot"}),r.jsx("button",{type:"button",onClick:()=>X(P),disabled:!!q[P.id],className:"button-danger disabled:cursor-not-allowed disabled:opacity-60",children:q[P.id]?"Updating...":"Update"}),P?.private?.enabled?r.jsxs("div",{className:"w-full rounded border border-slate-700/70 p-0.5 space-y-0.5 text-[0.7rem]",children:[r.jsx("div",{className:"text-slate-300",children:"Private safety"}),r.jsxs("label",{className:"flex items-center gap-0.5",children:[r.jsx("input",{type:"checkbox",checked:!!m1?.[P.id]?.speedLimitEnabled,disabled:!V1,onChange:c1=>W1(P.id,{speedLimitEnabled:!!c1.target.checked})}),r.jsx("span",{children:"Speed limit"})]}),r.jsx("input",{type:"number",min:"1",max:"500",className:"field-input text-xs w-20",disabled:!V1,value:m1?.[P.id]?.speedLimitMaxWheelSpeed??250,onChange:c1=>W1(P.id,{speedLimitMaxWheelSpeed:Number(c1.target.value)||250})}),r.jsxs("label",{className:"flex items-center gap-0.5",children:[r.jsx("input",{type:"checkbox",checked:!!m1?.[P.id]?.hardOvercurrentEnabled,disabled:!V1,onChange:c1=>W1(P.id,{hardOvercurrentEnabled:!!c1.target.checked})}),r.jsx("span",{children:"Hard overcurrent"})]}),r.jsxs("label",{className:"flex items-center gap-0.5",children:[r.jsx("input",{type:"checkbox",checked:!!m1?.[P.id]?.hardBumpEnabled,disabled:!V1,onChange:c1=>W1(P.id,{hardBumpEnabled:!!c1.target.checked})}),r.jsx("span",{children:"Hard bump"})]}),r.jsxs("label",{className:"flex items-center gap-0.5",children:[r.jsx("input",{type:"checkbox",checked:!!m1?.[P.id]?.cliffEnabled,disabled:!V1,onChange:c1=>W1(P.id,{cliffEnabled:!!c1.target.checked})}),r.jsx("span",{children:"Cliff safety"})]}),r.jsx("button",{type:"button",disabled:!V1,onClick:()=>t2(P.id),className:"button-dark disabled:opacity-50",children:"Apply Safety"})]}):null]})}),r.jsx(nQ,{health:s1,roster:w}),r.jsx(cQ,{state:S,onClearHistory:M1,clearingHistory:G}),r.jsx(aQ,{state:C,onClearHistory:p1,clearingHistory:T}),r.jsx(lQ,{entries:H})]})}const sQ=[{id:"driveForward",label:"Drive Forward",group:"Driving"},{id:"driveBackward",label:"Drive Backward",group:"Driving"},{id:"driveLeft",label:"Turn Left",group:"Driving"},{id:"driveRight",label:"Turn Right",group:"Driving"},{id:"boostModifier",label:"Boost Modifier",group:"Driving"},{id:"slowModifier",label:"Slow Modifier",group:"Driving"},{id:"auxMainForward",label:"Main Brush Forward",group:"Aux Motors"},{id:"auxMainReverse",label:"Main Brush Reverse",group:"Aux Motors"},{id:"auxSideForward",label:"Side Brush Forward",group:"Aux Motors"},{id:"auxSideReverse",label:"Side Brush Reverse",group:"Aux Motors"},{id:"auxVacuumFast",label:"Vacuum Max",group:"Aux Motors"},{id:"auxVacuumSlow",label:"Vacuum Low",group:"Aux Motors"},{id:"auxAllForward",label:"All Aux Forward",group:"Aux Motors"},{id:"cameraUp",label:"Camera Up",group:"Camera"},{id:"cameraDown",label:"Camera Down",group:"Camera"},{id:"nightVisionToggle",label:"Toggle Night Vision",group:"Camera"},{id:"videoFilterCycle",label:"Cycle Video Filter",group:"Camera"},{id:"hornHonk",label:"Horn (Hold)",group:"Audio"},{id:"micPtt",label:"Mic Push To Talk",group:"Audio"},{id:"driveMacro",label:"Drive Macro",group:"Macros"},{id:"dockMacro",label:"Dock Macro",group:"Macros"},{id:"chatFocus",label:"Toggle Chat",group:"Chat"},{id:"songNoteUp",label:"Song Note Up",group:"Audio"},{id:"songNoteDown",label:"Song Note Down",group:"Audio"},{id:"homeAssistantOn",label:"Room Controls On (Cycle)",group:"Room Controls"},{id:"homeAssistantOff",label:"Room Controls Off (Cycle)",group:"Room Controls"}];function oQ(t){return t.reduce((a,l)=>((a[l.group]||(a[l.group]=[])).push(l),a),{})}function uQ(t,a){const l=Number(t);return Number.isFinite(l)?Math.max(0,Math.min(500,l)):a}const sa=5,T8=500,q8=1,oa=100;function hQ(t,a){const l=Number(t);return Number.isFinite(l)?Math.max(sa,Math.min(T8,l)):a}function Et(t,a){const l=Number(t);return Number.isFinite(l)?Math.max(q8,Math.min(oa,l)):a}function dQ(t){const l=(Et(t,t)-q8)/(oa-q8),s=T8-l*(T8-sa);return Math.round(s)}function fQ(t){const a=hQ(t,t),l=(T8-a)/(T8-sa),s=q8+l*(oa-q8);return Math.round(s)}function mQ(t){const[a,l]=d.useState(null),s=d.useCallback(p=>{D9(!0),l(p)},[]),u=d.useCallback(()=>{D9(!1),l(null)},[]),f=d.useCallback((p,v)=>{if(v.preventDefault(),v.stopPropagation(),v.key==="Escape"){u();return}const g=Z8(v.key??"");g&&(t(p,g,v),u())},[u,t]);return d.useEffect(()=>()=>D9(!1),[]),{active:a,startCapture:s,cancel:u,captureFromEvent:f}}function cc({children:t}){return r.jsx("p",{className:"mx-auto w-full max-w-lg text-sm font-semibold text-white",children:t})}function mt({label:t,description:a,value:l,onChange:s,min:u=0,max:f=500,step:p=5}){return r.jsxs("label",{className:"mx-auto block w-full max-w-lg rounded bg-neutral-800/80 px-1.5 py-1",children:[r.jsxs("div",{className:"grid grid-cols-[minmax(0,1fr)_4.75rem] items-start gap-1.5 text-sm text-white",children:[r.jsx("span",{className:"min-w-0 font-semibold text-white",children:t}),r.jsx("input",{type:"number",min:u,max:f,value:l,onChange:v=>s(v.target.value),className:"w-full rounded border border-neutral-600 bg-neutral-900 px-1 py-0.5 text-right text-xs font-mono text-white"})]}),a&&r.jsx("p",{className:"mt-0.5 text-xs leading-snug text-white",children:a}),r.jsxs("div",{className:"mt-1 flex items-center gap-1.5",children:[r.jsx("input",{type:"range",min:u,max:f,step:p,value:l,onChange:v=>s(v.target.value),className:"h-2 min-w-0 flex-1 accent-emerald-400"}),r.jsx("span",{className:"w-10 text-right text-xs font-mono text-white",children:l})]})]})}function vQ({action:t,value:a,isActive:l,onCaptureStart:s,onCancel:u,onCaptureKeyDown:f}){return r.jsxs("div",{className:"mx-auto grid w-full max-w-lg grid-cols-[minmax(0,1fr)_auto] items-center gap-1.5 rounded bg-neutral-800/80 px-1.5 py-1 text-sm max-[420px]:grid-cols-1",children:[r.jsxs("div",{className:"min-w-0",children:[r.jsx("p",{className:"font-semibold leading-snug text-white",children:t.label}),r.jsx("p",{className:"mt-0.5 text-xs leading-snug text-white",children:_2(a)})]}),r.jsxs("div",{className:"flex flex-wrap items-center justify-end gap-1 max-[420px]:justify-start",children:[l&&r.jsx("button",{type:"button",onClick:u,className:"button-danger px-1 py-0.5 text-xs",children:"Cancel"}),r.jsx("button",{type:"button",onClick:s,onKeyDown:l?f:void 0,autoFocus:l,className:`${l?"rounded-md bg-emerald-500 px-1 py-0.5 text-emerald-950 hover:bg-emerald-400":"button-dark px-1 py-0.5"} text-xs font-medium transition-colors`,children:l?"Press a key...":"Change"})]})]})}function pQ(){const t=k1(C=>C.state.keymap),{updateKeyBinding:a,resetKeyBindings:l}=x3(),{value:s,save:u}=F1("inputs",R4),f={...R4.keyboard,...s.keyboard??{}},p=d.useMemo(()=>typeof f.tiltSpeed=="number"?Et(f.tiltSpeed,R4.keyboard.tiltSpeed):typeof f.tiltIntervalMs=="number"?Et(fQ(f.tiltIntervalMs),R4.keyboard.tiltSpeed):R4.keyboard.tiltSpeed,[f.tiltIntervalMs,f.tiltSpeed]),v=d.useMemo(()=>oQ(sQ),[]),{active:g,startCapture:x,cancel:z,captureFromEvent:b}=mQ((C,w)=>{a(C,w)}),y=d.useCallback(C=>t?.[C]?.[0]||B8[C]?.[0]||"",[t]),H=d.useCallback((C,w)=>{const A=R4.keyboard,V=uQ(w,A[C]);u(L=>({...L??{},keyboard:{...L?.keyboard??A,[C]:V}}))},[u]),S=d.useCallback(C=>{const w=R4.keyboard,A=Et(C,w.tiltSpeed),V=dQ(A);u(L=>({...L??{},keyboard:{...L?.keyboard??w,tiltSpeed:A,tiltIntervalMs:V}}))},[u]);return r.jsxs(j1,{title:"Keyboard layout",meta:"Per-browser · click to change a binding",actions:r.jsx("button",{type:"button",onClick:()=>l(),className:"button-dark px-1 py-0.5 text-xs",children:"Reset defaults"}),bodyClassName:"space-y-2 p-1 text-sm",children:[r.jsxs("div",{className:"space-y-1",children:[r.jsx(cc,{children:"Keyboard speeds"}),r.jsxs("div",{className:"grid gap-1",children:[r.jsx(mt,{label:"Base speed",description:"Normal driving speed",value:f.baseSpeed,onChange:C=>H("baseSpeed",C)}),r.jsx(mt,{label:"Turbo speed",description:"Used when holding the boost modifier",value:f.turboSpeed,onChange:C=>H("turboSpeed",C)}),r.jsx(mt,{label:"Precision speed",description:"Used when holding the precision modifier",value:f.precisionSpeed,onChange:C=>H("precisionSpeed",C)})]})]}),r.jsxs("div",{className:"space-y-1",children:[r.jsx(cc,{children:"Camera tilt"}),r.jsx(mt,{label:"Tilt speed",description:"Higher = faster when holding tilt keys",value:p,onChange:S,min:1,max:100,step:1})]}),r.jsx("div",{className:"space-y-2",children:Object.entries(v).map(([C,w])=>r.jsxs("div",{className:"space-y-1",children:[r.jsx(cc,{children:C}),r.jsx("div",{className:"grid gap-1",children:w.map(A=>{const V=y(A.id),L=g===A.id;return r.jsx(vQ,{action:A,value:V,isActive:L,onCancel:()=>z(),onCaptureStart:()=>x(A.id),onCaptureKeyDown:R=>b(A.id,R)},A.id)})})]},C))})]})}const h3=new Intl.NumberFormat(void 0,{maximumFractionDigits:2}),gQ=[{id:"drive",label:"Drive stick",kind:"axisPair",section:"Driving",invertDefaults:{invertX:!1,invertY:!0}},{id:"cameraTilt",label:"Camera tilt",kind:"axis",section:"Camera",invertDefaults:{invert:!0}},{id:"mainBrush",label:"Main brush",kind:"axis",section:"Brushes",invertDefaults:{invert:!1}},{id:"sideBrush",label:"Side brush",kind:"axis",section:"Brushes",invertDefaults:{invert:!1}},{id:"vacuum",label:"Vacuum",kind:"button",section:"Aux buttons"},{id:"allAux",label:"All aux",kind:"button",section:"Aux buttons"},{id:"mainReverse",label:"Main reverse toggle",kind:"button",section:"Brush toggles"},{id:"sideReverse",label:"Side reverse toggle",kind:"button",section:"Brush toggles"},{id:"driveMacro",label:"Drive macro",kind:"button",section:"Mode macros"},{id:"dockMacro",label:"Dock macro",kind:"button",section:"Mode macros"},{id:"nightVisionToggle",label:"Night vision toggle",kind:"button",section:"Camera"}],ws=.45,xQ=.6;function H8({label:t,description:a,min:l,max:s,step:u,value:f,onChange:p}){return r.jsxs("label",{className:"mx-auto block w-full max-w-lg rounded bg-neutral-800/80 px-1.5 py-1",children:[r.jsxs("div",{className:"grid grid-cols-[minmax(0,1fr)_auto] items-start gap-1.5 text-sm text-white",children:[r.jsx("span",{className:"min-w-0 font-semibold text-white",children:t}),r.jsx("span",{className:"rounded bg-neutral-900 px-1 py-0.5 font-mono text-xs text-white",children:h3.format(f)})]}),a&&r.jsx("p",{className:"mt-0.5 text-xs leading-snug text-white",children:a}),r.jsx("input",{type:"range",min:l,max:s,step:u,value:f,onChange:v=>p(Number(v.target.value)),className:"mt-1 w-full accent-emerald-400"})]})}function zQ(t){if(!t)return"Unassigned";if(t.kind==="axisPair"){const a=`${t.invertX?"X inv ":""}${t.invertY?"Y inv":""}`.trim();return`Axes ${t.x}/${t.y}${a?` (${a})`:""}`}if(t.kind==="axis")return`Axis ${t.index}${t.invert?" (inv)":""}`;if(t.kind==="button")return`Button ${t.index}`;if(t.kind==="buttonAxis")return`Button ${t.index} (analog)`;if(t.kind==="axisButton"){const a=t.direction<0?"<":">";return`Axis ${t.index} ${a} ${h3.format(t.threshold??.6)}`}return"Unassigned"}function bQ(t){return t.reduce((a,l)=>((a[l.section]||(a[l.section]=[])).push(l),a),{})}function MQ(t,a){if(!t||t.length===0)return null;if(a){const l=t.find(s=>s.signature===a);if(l)return l}return t[0]}function yQ(t){return{axes:Array.from(t.axes??[]),buttons:(t.buttons??[]).map(a=>({pressed:!!a?.pressed,value:typeof a?.value=="number"?a.value:a?.pressed?1:0}))}}function wQ(t,a,l){const s=(t.axes??[]).map((f,p)=>({index:p,delta:Math.abs((f??0)-(a.axes?.[p]??0)),value:f}));if(s.sort((f,p)=>p.delta-f.delta),l.kind==="axisPair"){const f=s.filter(p=>p.delta>ws).slice(0,2);return f.length<2?null:{kind:"axisPair",x:f[0].index,y:f[1].index,...l.invertDefaults??{}}}const u=s.find(f=>f.delta>ws);return u?{kind:"axis",index:u.index,...l.invertDefaults??{}}:null}function CQ(t,a,l){const s=t.buttons??[];for(let f=0;fxQ)return l.kind==="axis"?{kind:"buttonAxis",index:f}:{kind:"button",index:f}}const u=t.axes??[];for(let f=0;f.7&&v>.5)return l.kind==="axis"?{kind:"axis",index:f,...l.invertDefaults??{}}:{kind:"axisButton",index:f,direction:p>=0?1:-1,threshold:.6}}return null}function HQ(t,a,l){if(!t)return null;if(l.kind==="axis"||l.kind==="axisPair"){const s=wQ(t,a,l);if(s)return s}return CQ(t,a,l)}function vt({children:t}){return r.jsx("p",{className:"mx-auto w-full max-w-lg text-sm font-semibold text-white",children:t})}function SQ({action:t,source:a,isCapturing:l,onClear:s,onCapture:u,onInvert:f}){return r.jsxs("div",{className:"mx-auto grid w-full max-w-lg grid-cols-[minmax(0,1fr)_auto] items-center gap-1.5 rounded bg-neutral-800/80 px-1.5 py-1 text-sm max-[520px]:grid-cols-1",children:[r.jsxs("div",{className:"min-w-0",children:[r.jsx("p",{className:"font-semibold leading-snug text-white",children:t.label}),r.jsx("p",{className:"mt-0.5 text-xs leading-snug text-white",children:zQ(a)})]}),r.jsxs("div",{className:"flex flex-wrap items-center justify-end gap-1 max-[520px]:justify-start",children:[t.kind==="axisPair"&&r.jsxs(r.Fragment,{children:[r.jsx("button",{type:"button",disabled:!a,onClick:()=>f(t,"invertX"),className:"button-dark px-1 py-0.5 text-xs font-medium disabled:opacity-50",children:"Invert X"}),r.jsx("button",{type:"button",disabled:!a,onClick:()=>f(t,"invertY"),className:"button-dark px-1 py-0.5 text-xs font-medium disabled:opacity-50",children:"Invert Y"})]}),t.kind==="axis"&&r.jsx("button",{type:"button",disabled:!a,onClick:()=>f(t),className:"button-dark px-1 py-0.5 text-xs font-medium disabled:opacity-50",children:"Invert"}),r.jsx("button",{type:"button",onClick:()=>s(t),className:"button-dark px-1 py-0.5 text-xs",children:"Clear"}),r.jsx("button",{type:"button",onClick:()=>u(t),className:`${l?"rounded-md bg-emerald-500 px-1 py-0.5 text-emerald-950 hover:bg-emerald-400":"button-dark px-1 py-0.5"} text-xs font-medium`,children:l?"Waiting...":"Capture"})]})]})}function AQ(){const t=MY(),{value:a,save:l}=F1("gamepad",Z3),[s,u]=d.useState(null),f=d.useRef(null),p=d.useMemo(()=>bQ(gQ),[]),v=d.useMemo(()=>MQ(t.pads,a.activeSignature),[t.pads,a.activeSignature]),g=v?.signature??null,x=d.useMemo(()=>g?a?.profiles?.[g]??a?.defaults?.profile??d3:a?.defaults?.profile??d3,[g,a?.defaults?.profile,a?.profiles]);d.useEffect(()=>{!v||!g||a?.profiles?.[g]||l(w=>{const A=w??Z3;if(A.profiles?.[g])return A;const V=A?.defaults?.profile??d3,L=zu(v,V);return{...A,profiles:{...A.profiles??{},[g]:L}}})},[v,g,a?.profiles,l]),d.useEffect(()=>{f.current=null},[s,g]),d.useEffect(()=>{if(!s||!v)return;if(!f.current){f.current=yQ(v);return}const w=HQ(v,f.current,s);w&&(l(A=>{const V=A??Z3,L=V.profiles?.[g]??V?.defaults?.profile??d3,R={...L,bindings:{...L.bindings??{},[s.id]:{...L.bindings?.[s.id]??{},kind:s.kind,sources:[w]}}};return{...V,profiles:{...V.profiles??{},[g]:R}}}),u(null))},[v,g,s,l]);const z=d.useCallback(w=>{l(A=>({...A??Z3,activeSignature:w||null}))},[l]),b=d.useCallback(w=>{l(A=>{const V=A??Z3,L=(g&&V.profiles?.[g])??V?.defaults?.profile??d3,R={...L,calibration:{...L.calibration??{},...w}};return g?{...V,profiles:{...V.profiles??{},[g]:R}}:{...V,defaults:{...V.defaults??{},profile:R}}})},[g,l]),y=d.useCallback((w,A)=>{l(V=>{const L=V??Z3,R=(g&&L.profiles?.[g])??L?.defaults?.profile??d3,q=A(R.bindings?.[w]??{}),j={...R,bindings:{...R.bindings??{},[w]:q}};return g?{...L,profiles:{...L.profiles??{},[g]:j}}:{...L,defaults:{...L.defaults??{},profile:j}}})},[g,l]),H=d.useCallback(w=>{y(w.id,A=>({...A,sources:[]}))},[y]),S=d.useCallback((w,A)=>{y(w.id,V=>{const L=Array.isArray(V.sources)?[...V.sources]:[];if(!L[0])return V;const R={...L[0]};return A==="invertX"?R.invertX=!R.invertX:A==="invertY"?R.invertY=!R.invertY:R.invert=!R.invert,L[0]=R,{...V,sources:L}})},[y]),C=d.useMemo(()=>v?{outputs:bu(v,x)}:null,[v,x]);return r.jsxs(j1,{title:"Controller",meta:v?"Move sticks or press buttons to bind":"Connect a controller to configure.",bodyClassName:"space-y-2 p-1 text-sm",children:[s&&r.jsxs("p",{className:"mx-auto w-full max-w-lg rounded bg-emerald-950/50 px-1.5 py-1 text-sm text-white",children:["Capturing ",s.label,"..."]}),r.jsxs("div",{className:"space-y-1",children:[r.jsx(vt,{children:"Connected controller"}),t.pads.length===0?r.jsx("p",{className:"mx-auto w-full max-w-lg text-sm text-white",children:"No controller detected."}):r.jsxs("div",{className:"mx-auto grid w-full max-w-lg grid-cols-[minmax(0,1fr)_auto] items-center gap-1.5 rounded bg-neutral-800/80 px-1.5 py-1 text-sm max-[420px]:grid-cols-1",children:[r.jsx("select",{value:g??"",onChange:w=>z(w.target.value),className:"min-w-0 rounded border border-neutral-600 bg-neutral-900 px-1 py-0.5 text-sm text-white",children:t.pads.map(w=>r.jsx("option",{value:w.signature,children:w.id||"Unknown controller"},w.signature))}),r.jsx("span",{className:"rounded bg-neutral-900 px-1 py-0.5 text-xs text-white",children:v?.mapping??"unknown"})]})]}),r.jsxs("div",{className:"space-y-1",children:[r.jsx(vt,{children:"Calibration"}),r.jsxs("div",{className:"grid gap-1",children:[r.jsx(H8,{label:"Drive deadzone",description:"Ignore small drive stick drift",min:0,max:.6,step:.01,value:x.calibration?.driveDeadzone??.18,onChange:w=>b({driveDeadzone:w})}),r.jsx(H8,{label:"Camera deadzone",description:"Ignore small camera tilt drift",min:0,max:.4,step:.01,value:x.calibration?.cameraDeadzone??.08,onChange:w=>b({cameraDeadzone:w})}),r.jsx(H8,{label:"Aux deadzone",description:"Ignore small trigger noise",min:0,max:.4,step:.01,value:x.calibration?.auxDeadzone??.05,onChange:w=>b({auxDeadzone:w})}),r.jsx(H8,{label:"Side brush scale",description:"Scale side brush output",min:.3,max:1,step:.05,value:x.calibration?.auxSideScale??.55,onChange:w=>b({auxSideScale:w})}),r.jsxs("label",{className:"mx-auto block w-full max-w-lg rounded bg-neutral-800/80 px-1.5 py-1",children:[r.jsxs("div",{className:"grid grid-cols-[minmax(0,1fr)_auto] items-start gap-1.5 text-sm text-white",children:[r.jsx("span",{className:"min-w-0 font-semibold text-white",children:"Camera mode"}),r.jsxs("select",{value:x.calibration?.cameraMode??"absolute",onChange:w=>b({cameraMode:w.target.value}),className:"rounded border border-neutral-600 bg-neutral-900 px-1 py-0.5 text-sm text-white",children:[r.jsx("option",{value:"absolute",children:"Absolute"}),r.jsx("option",{value:"velocity",children:"Velocity"})]})]}),r.jsx("p",{className:"mt-0.5 text-xs leading-snug text-white",children:"Absolute maps stick to angle; velocity moves over time."})]}),r.jsx(H8,{label:"Camera sensitivity",description:"Velocity mode degrees per second",min:10,max:180,step:5,value:x.calibration?.cameraSensitivity??60,onChange:w=>b({cameraSensitivity:w})})]})]}),r.jsx("div",{className:"space-y-2",children:Object.entries(p).map(([w,A])=>r.jsxs("div",{className:"space-y-1",children:[r.jsx(vt,{children:w}),r.jsx("div",{className:"grid gap-1",children:A.map(V=>{const R=x.bindings?.[V.id]?.sources?.[0]??null;return r.jsx(SQ,{action:V,source:R,isCapturing:s?.id===V.id,onClear:H,onCapture:u,onInvert:S},V.id)})})]},w))}),r.jsxs("div",{className:"space-y-1",children:[r.jsx(vt,{children:"Diagnostics"}),v?r.jsxs("div",{className:"mx-auto w-full max-w-lg space-y-1 rounded bg-neutral-900/70 px-1.5 py-1 text-xs text-white",children:[r.jsx("p",{className:"text-white",children:"Raw axes"}),r.jsx("div",{className:"grid grid-cols-2 gap-1",children:v.axes.map((w,A)=>r.jsxs("span",{className:"font-mono text-white",children:["A",A,": ",h3.format(w)]},`axis-${A}`))}),r.jsx("p",{className:"text-white",children:"Raw buttons"}),r.jsx("div",{className:"grid grid-cols-2 gap-1",children:v.buttons.map((w,A)=>r.jsxs("span",{className:"font-mono text-white",children:["B",A,": ",h3.format(w.value)," ",w.pressed?"●":""]},`btn-${A}`))}),C?.outputs&&r.jsxs(r.Fragment,{children:[r.jsx("p",{className:"text-white",children:"Mapped outputs"}),r.jsxs("div",{className:"grid grid-cols-2 gap-1",children:[r.jsxs("span",{className:"font-mono text-white",children:["Drive: ",h3.format(C.outputs.driveVector.x),","," ",h3.format(C.outputs.driveVector.y)]}),r.jsxs("span",{className:"font-mono text-white",children:["Camera: ",h3.format(C.outputs.cameraAxis)]}),r.jsxs("span",{className:"font-mono text-white",children:["Main: ",h3.format(C.outputs.auxAxis.main)]}),r.jsxs("span",{className:"font-mono text-white",children:["Side: ",h3.format(C.outputs.auxAxis.side)]})]})]})]}):r.jsx("p",{className:"mx-auto w-full max-w-lg text-sm text-white",children:"No controller detected."})]})]})}const VQ={drive:"Drive wheels",aux:"Aux motors"};function Cs(t){return Number.isFinite(t)?`${Math.round(t*100)}%`:"--"}function LQ({value:t,color:a="bg-emerald-500"}){const l=`${Math.round(Math.max(0,Math.min(1,t))*100)}%`;return r.jsx("div",{className:"h-2 w-full overflow-hidden rounded bg-slate-800",children:r.jsx("div",{className:`h-full ${a}`,style:{width:l}})})}function BQ(){const t=k1(s=>s.state.roverId),a=k1(s=>s.overcurrentLimiter),l=d.useMemo(()=>v6.map(s=>s.key),[]);return r.jsx(j1,{title:"Overcurrent limiter",meta:a?.adminImmune?"Admin immune":"Active",bodyClassName:"space-y-0.5 text-sm",children:t?r.jsxs("div",{className:"space-y-0.5",children:[l.map(s=>{const u=a?.caps?.[s]?.cap??0,f=a?.overcurrent?.groups?.[s]??!1,p=a?.scales?.perGroup?.[s]??1;return r.jsxs("div",{className:"space-y-0.5",children:[r.jsxs("div",{className:"flex items-center justify-between text-xs",children:[r.jsx("span",{className:"text-slate-200",children:VQ[s]||s}),r.jsx("span",{className:f?"text-red-300":"text-slate-400",children:f?"overcurrent":"ok"})]}),r.jsxs("div",{className:"space-y-0.5",children:[r.jsxs("div",{className:"flex items-center justify-between text-[0.7rem] text-slate-400",children:[r.jsx("span",{children:"Cap"}),r.jsx("span",{children:Cs(u)})]}),r.jsx(LQ,{value:u,color:"bg-amber-500"}),r.jsxs("div",{className:"flex items-center justify-between text-[0.7rem] text-slate-400",children:[r.jsx("span",{children:"Scale"}),r.jsx("span",{children:Cs(p)})]})]})]},s)}),r.jsxs("div",{className:"text-[0.7rem] text-slate-400",children:[r.jsx("div",{children:`Down rate ${a?.config?.downRatePerSec}/s · Up rate ${a?.config?.upRatePerSec}/s`}),r.jsx("div",{children:`Release delay ${a?.config?.releaseDelaySec}s`}),r.jsx("div",{children:`Output rate ${a?.config?.outputRateMs}ms`})]})]}):r.jsx("p",{className:"text-xs text-slate-500",children:"Assign a rover to view limiter status."})})}const jQ="pride-page-bg",C2="gap-0.5",x6="space-y-0.5",$u=d.createContext(null);function Gu(){const t=d.useContext($u);if(!t)throw new Error("Tabs components must be used within a provider.");return t}const Hs={primary:{base:"flex-1 px-0.5 py-0.5 text-sm font-medium focus-visible:outline focus-visible:outline-1 focus-visible:outline-offset-1 focus-visible:outline-slate-500 rounded-md border border-slate-800",active:"bg-sky-600 text-white border-white",inactive:"bg-zinc-900 text-slate-300 hover:bg-sky-500 hover:text-white"}},Ss={none:"",pink:"bg-pink-500 text-white border-pink-200 hover:bg-pink-400",green:"bg-emerald-500 text-white border-emerald-200 hover:bg-emerald-400",pinkblue:"bg-gradient-to-r from-lime-800 to-teal-800"},Iu="primary";function ua(...t){return t.filter(Boolean).join(" ")}function ha({children:t,defaultTab:a,currentTab:l,onTabChange:s,variant:u=Iu}){const[f,p]=d.useState(a??null),[v,g]=d.useState([]),x=d.useCallback(H=>H?(g(S=>S.includes(H)?S:[...S,H]),()=>g(S=>S.includes(H)?S.filter(C=>C!==H):S)):()=>{},[]),z=l??f??v[0]??null;d.useEffect(()=>{a&&l===void 0&&p(a)},[a,l]);const b=d.useCallback(H=>{H&&(l===void 0&&p(H),s&&s(H))},[l,s]),y=d.useMemo(()=>({activeTab:z,setActiveTab:b,registerTab:x,variant:u}),[z,b,x,u]);return r.jsx($u.Provider,{value:y,children:t})}function da({children:t,className:a=""}){return r.jsx("div",{className:ua("panel-section overflow-hidden border border-neutral-500/60 bg-neutral-900/95 p-0.5",a),children:r.jsx("div",{className:`flex ${C2}`,children:t})})}function K2({id:t,children:a,className:l="",disabled:s=!1,highlight:u="none"}){const{activeTab:f,setActiveTab:p,registerTab:v,variant:g}=Gu();d.useEffect(()=>v(t),[t,v]);const x=Hs[g]??Hs[Iu],z=f===t,b=Ss[u]||Ss.none,y=ua(x.base,b||(z?x.active:x.inactive),s?"cursor-not-allowed opacity-50":"",l);return r.jsx("button",{type:"button",className:y,onClick:()=>!s&&p(t),"aria-pressed":z,"aria-disabled":s,children:a})}function fa({children:t,className:a=""}){return r.jsx("div",{className:ua("mt-0",x6,a),children:t})}function Q2({id:t,children:a,keepMounted:l=!1}){const{activeTab:s}=Gu(),u=s===t;return!u&&!l?null:!u&&l?r.jsx("div",{hidden:!0,"aria-hidden":"true",children:a}):r.jsx(r.Fragment,{children:a})}function NQ(){const{session:t}=H0(),a=d.useMemo(()=>JSON.stringify(t??{},null,2),[t]);return r.jsx(j1,{title:"Session snapshot",className:"min-h-0",bodyClassName:"flex min-h-0 flex-col gap-0.5 text-xs",children:r.jsx("pre",{className:"min-h-0 flex-1 overflow-y-auto font-mono text-[0.7rem] text-lime-300",children:a})})}const As=300,Vs=240;function FQ(t,a){if(t===void 0)return"undefined";if(t===null)return"null";if(typeof t=="string")return t;if(typeof t=="number"||typeof t=="boolean")return String(t);if(typeof t=="function")return"[Function]";if(t instanceof Error)return`${t.name}: ${t.message}`;if(t instanceof Date)return t.toISOString();if(a||(a=new WeakSet),typeof t=="object"){if(a.has(t))return"[Circular]";a.add(t)}try{return JSON.stringify(t,(l,s)=>typeof s=="function"?"[Function]":s instanceof Error?`${s.name}: ${s.message}`:s,0)}catch{return String(t)}}function kQ(t){const l=t.map(s=>FQ(s)).join(" ");return l.length>Vs?`${l.slice(0,Vs)}…`:l}function RQ(){const t=E2(),[a,l]=d.useState([]),s=d.useMemo(()=>a.reduce((f,p)=>(p.direction==="in"&&(f.in+=1),p.direction==="out"&&(f.out+=1),f),{in:0,out:0}),[a]);d.useEffect(()=>{const f=(x,z,b)=>{l(y=>{const H=[...y,{id:`${Date.now()}-${Math.random().toString(16).slice(2)}`,direction:x,event:z,payload:kQ(b),timestamp:new Date().toLocaleTimeString()}];return H.length>As?H.slice(-As):H})},p=(x,...z)=>f("in",x,z),v=(x,...z)=>f("out",x,z);t.onAny(p);let g=null;if(typeof t.onAnyOutgoing=="function")t.onAnyOutgoing(v),g=()=>t.offAnyOutgoing(v);else{const x=t.emit.bind(t);t.emit=(z,...b)=>(v(z,...b),x(z,...b)),g=()=>{t.emit=x}}return()=>{t.offAny(p),g&&g()}},[t]);const u=r.jsxs("div",{className:"flex items-center gap-0.5 text-xs text-slate-400",children:[r.jsxs("span",{children:["in ",s.in]}),r.jsxs("span",{children:["out ",s.out]}),r.jsx("button",{type:"button",className:"button-dark text-xs",onClick:()=>l([]),children:"Clear"})]});return r.jsxs(j1,{title:"Socket activity",actions:u,bodyClassName:"space-y-0.5 text-base",children:[r.jsx("div",{className:"h-64 overflow-y-auto font-mono text-xs",children:a.length===0?r.jsx("p",{children:"No socket activity yet."}):a.slice().reverse().map(f=>r.jsxs("div",{children:[r.jsx("span",{className:"text-slate-400",children:f.timestamp})," ",r.jsxs("span",{className:f.direction==="in"?"text-emerald-400":"text-amber-400",children:["[",f.direction.toUpperCase(),"]"]})," ",r.jsx("span",{className:"text-cyan-300",children:f.event})," ",r.jsx("span",{className:"text-slate-200",children:f.payload})]},f.id))}),r.jsx("p",{className:"text-xs text-slate-500",children:"Logs are collected only while this panel is open."})]})}function Pt({label:t}){return t?r.jsx("span",{className:"rounded border border-white/40 px-1 text-[0.7rem] text-white",children:t}):null}const EQ=[{key:"start",label:"Start OI"},{key:"safe",label:"Safe"},{key:"full",label:"Full"},{key:"passive",label:"Passive"},{key:"dock",label:"Dock"}],Pu=[{key:"none",label:"Color"},{key:"grayscale",label:"Gray"},{key:"greenscale",label:"Green"}];function Ls(t){return Pu.some(a=>a.key===t)?t:S0.colorFilter}function o0({children:t,className:a=""}){return r.jsx("label",{className:`mx-auto grid w-full max-w-lg grid-cols-[minmax(0,1fr)_auto] items-center gap-1.5 rounded bg-neutral-800/80 px-1.5 py-1 text-sm text-white max-[420px]:grid-cols-1 ${a}`,children:t})}function pt({children:t}){return r.jsx("p",{className:"mx-auto w-full max-w-lg text-xs leading-snug text-white",children:t})}function gt({label:t,value:a,disabled:l=!1,onChange:s}){return r.jsxs("label",{className:"mx-auto block w-full max-w-lg rounded bg-neutral-800/80 px-1.5 py-1 text-sm text-white",children:[r.jsxs("div",{className:"grid grid-cols-[minmax(0,1fr)_auto] items-center gap-1.5",children:[r.jsx("span",{className:"min-w-0 font-semibold text-white",children:t}),r.jsxs("span",{className:"rounded bg-neutral-900 px-1 py-0.5 text-xs text-white",children:[Math.round(a*100),"%"]})]}),r.jsx("input",{type:"range",min:"0",max:"1",step:"0.01",value:a,onChange:s,className:"mt-1 w-full accent-emerald-500 disabled:opacity-50",disabled:l})]})}function Yu(){const t=k1(k=>k.state.keymap),a=k1(k=>k.state.roverId),{sendOiCommand:l,setSensorStream:s}=x3(),u=!!a,[f,p]=ku(),v=E2(),{value:g,save:x}=F1("page",{hudMapDesktop:!1,connectionTransport:"websocket",swapMobileControlColumns:!1,driveMacroBackoffEnabled:!0}),{value:z,save:b}=F1("audio",g2),{value:y,save:H}=F1("video",S0),S=g?.connectionTransport||"websocket",C=!!g?.swapMobileControlColumns,w=typeof g?.driveMacroBackoffEnabled=="boolean"?g.driveMacroBackoffEnabled:!0,A=Number.isFinite(z?.masterVolume)?z.masterVolume:g2.masterVolume,V=Number.isFinite(z?.alertVolume)?z.alertVolume:g2.alertVolume,L=Number.isFinite(z?.roverVolume)?z.roverVolume:g2.roverVolume,R=typeof z?.mainBrushDuckEnabled=="boolean"?z.mainBrushDuckEnabled:typeof z?.autoLevelEnabled=="boolean"?z.autoLevelEnabled:g2.mainBrushDuckEnabled,q=Number.isFinite(z?.mainBrushDuckAmount)?Math.max(0,Math.min(1,z.mainBrushDuckAmount)):g2.mainBrushDuckAmount,j=Ls(y?.colorFilter),N=_2(t?.videoFilterCycle?.[0]),E=d.useMemo(()=>[{key:"start",label:"Enable stream",enable:!0},{key:"stop",label:"Disable stream",enable:!1}],[]),G=k=>{a&&s(k)},O=k=>{const $=k.target.value;x(t1=>({...t1??{},connectionTransport:$})),u1("settings_change",{setting:"connection_transport",value:$}),v?.io?.opts&&(v.io.opts.transports=$==="polling"?["polling"]:["websocket","polling"],v.disconnect(),v.connect())},T=k=>$=>{const t1=Number($.target.value),f1=Number.isFinite(t1)?Math.max(0,Math.min(1,t1)):0;b(h1=>({...h1??{},[k]:f1})),v3("settings_change",{setting:k,value:f1},{key:`audio:${k}`,throttleMs:3*1e3})},U=k=>{const $=!!k.target.checked;b(t1=>({...t1??{},mainBrushDuckEnabled:$})),u1("settings_change",{setting:"mainBrushDuckEnabled",value:$})},s1=k=>{const $=!!k.target.checked;x(t1=>({...t1??{},swapMobileControlColumns:$})),u1("mobile_controls_swap",{enabled:$}),u1("settings_change",{setting:"swapMobileControlColumns",value:$})},n1=k=>{const $=!!k.target.checked;x(t1=>({...t1??{},driveMacroBackoffEnabled:$})),u1("settings_change",{setting:"driveMacroBackoffEnabled",value:$})},Q=k=>{const $=Ls(k.target.value);H(t1=>({...t1??{},colorFilter:$})),u1("settings_change",{setting:"videoColorFilter",value:$})};return r.jsxs(ha,{defaultTab:"keybindings",children:[r.jsxs(da,{children:[r.jsx(K2,{id:"keybindings",children:"Keybindings"}),r.jsx(K2,{id:"controller",children:"Controller"}),r.jsx(K2,{id:"page",children:"Page settings"}),r.jsx(K2,{id:"admin",children:"Admin"})]}),r.jsxs(fa,{children:[r.jsx(Q2,{id:"keybindings",children:r.jsx("div",{className:"space-y-0.5",children:r.jsx(pQ,{})})}),r.jsx(Q2,{id:"controller",children:r.jsx("div",{className:"space-y-0.5",children:r.jsx(AQ,{})})}),r.jsx(Q2,{id:"page",children:r.jsxs("div",{className:"grid gap-1.5 lg:grid-cols-2",children:[r.jsxs(j1,{title:"HUD",bodyClassName:"space-y-1 p-1 text-sm",children:[r.jsxs(o0,{className:"grid-cols-[auto_minmax(0,1fr)] max-[420px]:grid-cols-[auto_minmax(0,1fr)]",children:[r.jsx("input",{type:"checkbox",className:"h-3.5 w-3.5 accent-emerald-500",checked:f,onChange:k=>p(k.target.checked)}),r.jsx("span",{className:"font-semibold text-white",children:"Show top-down map in HUD (desktop)"})]}),r.jsx(pt,{children:"Mobile HUD keeps the map on by default."})]}),r.jsxs(j1,{title:"Video",bodyClassName:"space-y-1 p-1 text-sm",children:[r.jsxs(o0,{children:[r.jsx("span",{className:"font-semibold text-white",children:"Rover video filter"}),r.jsx("select",{value:j,onChange:Q,className:"field-input min-w-28 px-1 py-0.5 text-sm",children:Pu.map(k=>r.jsx("option",{value:k.key,children:k.label},k.key))})]}),r.jsx(pt,{children:r.jsxs("span",{className:"inline-flex flex-wrap items-center gap-1",children:[r.jsx("span",{children:"Use"}),N?r.jsx(Pt,{label:N}):null,r.jsx("span",{children:"to cycle filters. Applies only to rover camera pixels; HUD overlays stay full color."})]})})]}),r.jsx(j1,{title:"Mobile controls",bodyClassName:"space-y-1 p-1 text-sm",children:r.jsxs(o0,{className:"grid-cols-[auto_minmax(0,1fr)] max-[420px]:grid-cols-[auto_minmax(0,1fr)]",children:[r.jsx("input",{type:"checkbox",className:"h-3.5 w-3.5 accent-emerald-500",checked:C,onChange:s1}),r.jsx("span",{className:"font-semibold text-white",children:"Swap control columns (put joystick on the left)"})]})}),r.jsx(j1,{title:"Macros",bodyClassName:"space-y-1 p-1 text-sm",children:r.jsxs(o0,{className:"grid-cols-[auto_minmax(0,1fr)] max-[420px]:grid-cols-[auto_minmax(0,1fr)]",children:[r.jsx("input",{type:"checkbox",className:"h-3.5 w-3.5 accent-emerald-500",checked:w,onChange:n1}),r.jsx("span",{className:"font-semibold text-white",children:"Enable backward bump in drive macro"})]})}),r.jsxs(j1,{title:"Audio",className:"lg:col-span-2",bodyClassName:"space-y-1 p-1 text-sm",children:[r.jsx(gt,{label:"Master volume",value:A,onChange:T("masterVolume")}),r.jsx(gt,{label:"Alert/page sounds",value:V,onChange:T("alertVolume")}),r.jsx(gt,{label:"Rover audio",value:L,onChange:T("roverVolume")}),r.jsxs(o0,{children:[r.jsx("span",{className:"font-semibold text-white",children:"Main brush ducking"}),r.jsx("input",{type:"checkbox",className:"h-3.5 w-3.5 accent-emerald-500",checked:R,onChange:U})]}),r.jsx(gt,{label:"Main brush duck amount",value:q,onChange:T("mainBrushDuckAmount"),disabled:!R}),r.jsx(pt,{children:"Lowers rover audio only while the main brush is running."})]}),r.jsxs(j1,{title:"Connection",bodyClassName:"space-y-1 p-1 text-sm",children:[r.jsxs(o0,{children:[r.jsx("span",{className:"font-semibold text-white",children:"Transport"}),r.jsxs("select",{value:S,onChange:O,className:"field-input min-w-28 px-1 py-0.5 text-sm",children:[r.jsx("option",{value:"websocket",children:"WebSocket"}),r.jsx("option",{value:"polling",children:"Polling"})]})]}),r.jsx(pt,{children:"Switching reconnects your session."})]})]})}),r.jsx(Q2,{id:"admin",children:r.jsxs("div",{className:"space-y-0.5",children:[r.jsx(j1,{title:"Manual OI commands",bodyClassName:"space-y-0.5 text-sm",children:r.jsx("div",{className:"flex flex-wrap gap-0.5",children:EQ.map(k=>r.jsx("button",{type:"button",onClick:()=>l(k.key),disabled:!u,className:"button-dark text-xs disabled:opacity-30",children:k.label},k.key))})}),r.jsxs(j1,{title:"Sensor stream",bodyClassName:"space-y-0.5 text-sm",children:[r.jsx("div",{className:"flex gap-0.5",children:E.map(k=>r.jsx("button",{type:"button",onClick:()=>G(k.enable),disabled:!u,className:"flex-1 button-dark text-xs disabled:opacity-30",children:k.label},k.key))}),!u&&r.jsx("p",{className:"text-xs text-slate-500",children:"Assign a rover to toggle streams."})]}),r.jsx(Zu,{}),r.jsx(BQ,{}),r.jsx(iQ,{}),r.jsx(NQ,{}),r.jsx(RQ,{})]})})]})]})}const Bs={desktop:{main:[{type:"list",title:"Chat and nicknames",items:["Set a nickname in the user list panel, on the bottom left of the page below the rover video.",{segments:["Toggle chat focus with ",{action:"chatFocus"},". Press ",{action:"chatFocus"}," again to send."]}]},{type:"list",title:"Driving the rover",items:[{segments:['Press the "Start Driving" button onscreen, or press ',{action:"driveMacro"}," on your keyboard to put the rover into driving mode."]},"Refer to the controls for the controls for the rover."]},{type:"list",title:"Docking the rover",items:['If the rover shows "Docking in Progress", it is already auto-seeking the dock.',"To dock manually, enter Docking Assist from the drive panel.",{segments:['Press "Enter Docking Assist", or press ',{action:"dockMacro"},"."]},"In assist mode, camera tilts down and driving speed is limited for precise alignment."]}],aside:[{type:"keyboard",title:"Keyboard controls",footnote:"Per-browser; adjust bindings and speeds in Settings → Keybindings.",groups:[{id:"movement",title:"Movement",items:[{action:"driveForward",label:"Forward"},{action:"driveBackward",label:"Backward"},{action:"driveLeft",label:"Turn left"},{action:"driveRight",label:"Turn right"},{action:"boostModifier",label:"Boost speed"},{action:"slowModifier",label:"Precision speed"}]},{id:"macros",title:"Rover modes & chat",items:[{action:"driveMacro",label:"Drive macro"},{action:"dockMacro",label:"Docking assist toggle"},{action:"chatFocus",label:"Chat focus"}]},{id:"camera",title:"Camera",items:[{action:"cameraUp",label:"Tilt up"},{action:"cameraDown",label:"Tilt down"},{action:"nightVisionToggle",label:"Toggle night vision"}]},{id:"motors",title:"Rover Aux Motors",items:[{action:"auxMainForward",label:"Main brush forward"},{action:"auxMainReverse",label:"Main brush reverse"},{action:"auxSideForward",label:"Side brush forward"},{action:"auxSideReverse",label:"Side brush reverse"},{action:"auxVacuumFast",label:"Vacuum max"},{action:"auxVacuumSlow",label:"Vacuum low"},{action:"auxAllForward",label:"All motors forward"}]},{id:"audio",title:"Audio / Song",items:[{action:"songNoteUp",label:"Song note up"},{action:"songNoteDown",label:"Song note down"}]},{id:"room-controls",title:"Room Controls",items:[{action:"homeAssistantOn",label:"Next room control on"},{action:"homeAssistantOff",label:"Next room control off (reverse)"}]}]},{type:"gamepad",title:"Gamepad / joystick",items:["Gamepad controls are fully configurable to handle inconsistent browser mappings.","Use Settings → Controller to bind inputs, calibrate deadzones, and view diagnostics.","If inputs behave oddly, the diagnostics panel will show raw axis/button values."]}]},"mobile-portrait":{main:[{type:"list",title:"Chat and nicknames",items:["Set a nickname in the user list panel below.","Tap in the chat box to send messages in the chat."]},{type:"list",title:"Driving the rover",items:[{segments:['Press the "Start Driving" button onscreen to put the rover into driving mode.']},"Look below the rover video. Use the joystick column to move the rover, and hold the aux buttons in the other control column."]},{type:"list",title:"Docking the rover",items:['If you see "Docking in Progress", the rover is currently auto-seeking the dock.',{segments:['For manual docking, press "Enter Docking Assist".']},"Assist mode tilts camera down and limits speed for precise alignment."]}]},"mobile-landscape":{main:[{type:"list",title:"Chat and nicknames",items:["Scroll down to see more of the page.","Set a nickname in the user list panel below.","Tap in the chat box to send messages in the chat."]},{type:"list",title:"Driving the rover",items:[{segments:['Press the "Start Driving" button, or the "Drive" button to put the rover into driving mode.']},"Use the joystick column beside the video feed to move the rover, and hold the aux buttons in the other control column."]},{type:"list",title:"Docking the rover",items:['If you see "Docking in Progress", the rover is currently auto-seeking the dock.',{segments:['For manual docking, press "Enter Docking Assist" (or "Dock" button).']},"Assist mode tilts camera down and limits speed for precise alignment."]}]}};function TQ(t){return Bs[t]||Bs.desktop}function Ku({actionId:t,keymap:a}){const l=a?.[t]?.[0]??"";return r.jsx("span",{className:"rounded border border-slate-600 bg-slate-900/40 px-1 text-[0.7rem] text-slate-200",children:_2(l)})}function js(t,a){return t.map((l,s)=>typeof l=="string"?r.jsx("span",{children:l},`text-${s}`):l?.action?r.jsx(Ku,{actionId:l.action,keymap:a},`pill-${l.action}-${s}`):l?.text?r.jsx("span",{children:l.text},`span-${s}`):null)}function i7(t,a,l){if(typeof t=="string")return t;if(Array.isArray(t?.segments))return js(t.segments,a);if(t&&typeof t=="object"){if(typeof t.text=="string")return t.text;if(Array.isArray(t))return js(t,a)}return String(t??"")}function qQ({hero:t,keymap:a}){return t?r.jsxs("div",{className:"surface space-y-0.5 px-0.5 py-0.5",children:[r.jsxs("div",{className:"flex flex-wrap items-center justify-between gap-0.5",children:[r.jsxs("div",{children:[r.jsx("p",{className:"text-sm font-semibold text-white",children:t.title}),t.subtitle&&r.jsx("p",{className:"text-xs text-slate-300",children:t.subtitle})]}),t.chips&&r.jsx("div",{className:"flex flex-wrap gap-0.5 text-[0.7rem] text-slate-200",children:t.chips.map(l=>r.jsx("span",{className:"rounded border border-slate-700 px-1 py-[2px]",children:l},l))})]}),t.bullets&&r.jsx("ul",{className:"space-y-0.5 text-[0.85rem] text-slate-200",children:t.bullets.map((l,s)=>{const u=Array.isArray(l?.segments)?`hero-${s}`:`hero-${s}`;return r.jsx("li",{className:"surface-muted px-0.5 py-0.25",children:i7(l,a)},u)})})]}):null}function _Q({block:t,keymap:a}){return r.jsxs("div",{className:"space-y-0.5",children:[r.jsx("p",{className:"text-xs font-semibold text-slate-200",children:t.title}),r.jsx("ul",{className:"space-y-0.5 text-[0.8rem] text-slate-300",children:t.items.map((l,s)=>{const u=`item-${s}`;return r.jsx("li",{className:"surface-muted flex flex-wrap items-center gap-0.5 px-0.5 py-0.25",children:i7(l,a)},u)})})]})}function DQ({block:t}){const a=t.tone==="info"?"border-cyan-500/40":"border-slate-700";return r.jsxs("div",{className:`surface space-y-0.5 border ${a} px-0.5 py-0.5`,children:[r.jsx("p",{className:"text-xs font-semibold text-slate-100",children:t.title}),t.body&&r.jsx("ul",{className:"space-y-0.5 text-[0.8rem] text-slate-300",children:t.body.map((l,s)=>r.jsx("li",{className:"surface-muted px-0.5 py-0.25",children:i7(l,{})},`callout-${s}`))})]})}function OQ({group:t,keymap:a}){return r.jsxs("div",{className:"space-y-0.5 surface",children:[r.jsx("p",{className:"px-0.5 py-0.25 text-[0.75rem] font-semibold text-slate-200",children:t.title}),r.jsx("div",{className:"space-y-0.5 px-0.5 pb-0.25",children:t.items.map(l=>r.jsxs("div",{className:"surface-muted flex items-center justify-between gap-0.5 px-0.5 py-0.25 text-[0.8rem]",children:[r.jsx("span",{className:"text-slate-200",children:l.label}),r.jsx(Ku,{actionId:l.action,keymap:a})]},l.action))})]})}function UQ({block:t,keymap:a}){return t?r.jsxs("div",{className:"space-y-0.5",children:[r.jsxs("div",{className:"flex items-center justify-between text-xs text-slate-200",children:[r.jsx("span",{className:"font-semibold",children:t.title}),t.footnote&&r.jsx("span",{className:"text-[0.7rem] text-slate-400",children:t.footnote})]}),r.jsx("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-0.5",children:t.groups?.map(l=>r.jsx(OQ,{group:l,keymap:a},l.id))})]}):null}function ZQ({block:t}){return t?r.jsxs("div",{className:"space-y-0.5",children:[r.jsx("p",{className:"text-xs font-semibold text-slate-200",children:t.title}),r.jsx("ul",{className:"space-y-0.5 text-[0.8rem] text-slate-300",children:t.items?.map((a,l)=>r.jsx("li",{className:"surface-muted px-0.5 py-0.25",children:i7(a,{})},`gamepad-${l}`))})]}):null}function Ns({block:t,keymap:a}){if(!t)return null;switch(t.type){case"list":return r.jsx(_Q,{block:t,keymap:a});case"callout":return r.jsx(DQ,{block:t});case"keyboard":return r.jsx(UQ,{block:t,keymap:a});case"gamepad":return r.jsx(ZQ,{block:t});default:return null}}function Qu({layout:t,keymap:a}){const l=d.useMemo(()=>TQ(t),[t]),s=a||{},u=l.main||[],f=l.aside||[];return r.jsxs("div",{className:"space-y-0.5",children:[r.jsx(qQ,{hero:l.hero,keymap:s}),r.jsxs("div",{className:"grid gap-0.5",style:{gridTemplateColumns:"repeat(auto-fit, minmax(360px, 1fr))"},children:[r.jsx("div",{className:"space-y-0.5",children:u.map((p,v)=>r.jsx(Ns,{block:p,keymap:s},p.title||v))}),r.jsx("div",{className:"space-y-0.5",children:f.map((p,v)=>r.jsx(Ns,{block:p,keymap:s},p.title||v))})]})]})}function Xu({layout:t,onOpenOverlay:a}){const l=k1(u=>u.state.keymap),s=r.jsx("button",{type:"button",onClick:a,className:"button-dark px-1 py-0.25 text-[0.75rem]",children:"Open full help"});return r.jsx(j1,{title:"Help",actions:s,bodyClassName:"space-y-0.5 text-sm",children:r.jsx(Qu,{layout:t,keymap:l||{}})})}function s7({compact:t=!1}){const{setNickname:a}=G2(),{value:l,save:s}=F1("profile",{nickname:""}),[u,f]=d.useState(l.nickname||""),[p,v]=d.useState(!1);d.useEffect(()=>{f(l.nickname||"")},[l.nickname]);async function g(x){x.preventDefault();const z=(u||"").trim().slice(0,32);if(z){v(!0);try{await a(z),s({nickname:z}),u1("nickname_set",{length:z.length})}catch(b){alert(b.message)}finally{v(!1)}}}return r.jsxs("div",{className:"grid w-full min-w-0 grid-cols-[minmax(0,1fr)_auto] items-stretch gap-0.5",children:[r.jsx("input",{className:"field-input flex-1 min-w-0",value:u,onChange:x=>f(x.target.value),onKeyDown:x=>{x.key==="Enter"&&(x.preventDefault(),g(x))},maxLength:32,placeholder:"Enter a nickname"}),r.jsx("button",{type:"button",onClick:g,disabled:p,className:"button-dark h-full shrink-0 whitespace-nowrap px-0.5 py-0 disabled:opacity-50",children:p?"Saving…":t?"Set":"Save"})]})}const Fs=["kal","rms","slt","ksp","bdl"],ks=["sfg","iob","iog","iol","iom","tpc","tpd","tpf"],$Q=Array.from({length:10},(t,a)=>a*10),Rs=[.5,.75,1,1.25,1.5,1.75,2],Es=1,d0={engine:"flite",voice:"rms",pitch:50,googlePitch:Es,googleSpeed:Es};function GQ(t){return{engine:t?.engine||d0.engine,voice:t?.voice||d0.voice,pitch:Number.isFinite(t?.pitch)?t.pitch:d0.pitch,googlePitch:Number.isFinite(t?.googlePitch)?t.googlePitch:d0.googlePitch,googleSpeed:Number.isFinite(t?.googleSpeed)?t.googleSpeed:d0.googleSpeed}}function IQ(t){const a=d1(f=>f.session?.role||null),l=d1(f=>f.session?.assignment?.roverId||null),s=d1(f=>f.session?.roster??[]),u=d.useMemo(()=>s.find(f=>String(f.id)===String(l))||null,[l,s]);return{canChat:a!=="spectator"||t,ttsSupported:!!u?.audio?.ttsEnabled}}function PQ({fillHeight:t=!1}){const{messages:a,typing:l}=nY(),s=d.useRef(null),u=d.useMemo(()=>a.slice(-200),[a]),f=d.useMemo(()=>l||[],[l]),p=t?"flex-1 min-h-0 overflow-y-auto":"h-48 overflow-y-auto";return d.useEffect(()=>{s.current&&(s.current.scrollTop=s.current.scrollHeight)},[u,f]),r.jsxs("div",{className:`overflow-y-auto space-y-0.5 px-0 ${p}`,ref:s,children:[u.length===0&&f.length===0?r.jsx("p",{className:"text-sm text-slate-500",children:"No messages yet."}):u.map(v=>r.jsx(Qc,{message:v},v.id)),f.map(v=>r.jsx(Xo,{message:v},`typing-${v.typingId||v.id}`))]})}const YQ=d.memo(s7);function KQ({ttsSupported:t,speak:a,onSpeakChange:l,engine:s,voice:u,pitch:f,googlePitch:p,googleSpeed:v,saveTtsSettings:g}){if(!t)return null;const x="field-input min-w-0 max-w-full px-0 text-xs";return r.jsxs("div",{className:"chat-composer-tts",children:[r.jsxs("label",{className:"flex shrink-0 items-center gap-0.5 whitespace-nowrap text-xs text-slate-300",children:[r.jsx("input",{type:"checkbox",checked:a,onChange:z=>l(z.target.checked),className:"accent-cyan-500"}),r.jsx("span",{children:"Speak"})]}),r.jsxs("select",{value:s,onChange:z=>{const b=z.target.value,y=b==="chromegtts"&&!ks.includes(u)?"tpf":b==="flite"&&!Fs.includes(u)?"rms":u;g(H=>({...H||{},engine:b,voice:y}))},className:`${x} w-[5.5rem] shrink`,children:[r.jsx("option",{value:"flite",children:"flite"}),r.jsx("option",{value:"espeak",children:"espeak"}),r.jsx("option",{value:"chromegtts",children:"Google speech"})]}),s==="flite"||s==="chromegtts"?r.jsxs(r.Fragment,{children:[r.jsx("select",{value:u,onChange:z=>{const b=z.target.value;g(y=>({...y||{},voice:b}))},className:`${x} w-[3.25rem] shrink`,children:(s==="chromegtts"?ks:Fs).map(z=>r.jsx("option",{value:z,children:z},z))}),s==="chromegtts"&&r.jsxs(r.Fragment,{children:[r.jsx("select",{value:p,onChange:z=>{const b=Number(z.target.value);g(y=>({...y||{},googlePitch:b}))},className:`${x} w-[5rem] shrink`,children:Rs.map(z=>r.jsxs("option",{value:z,children:["pitch ",z.toFixed(2)]},`pitch-${z}`))}),r.jsx("select",{value:v,onChange:z=>{const b=Number(z.target.value);g(y=>({...y||{},googleSpeed:b}))},className:`${x} w-[5rem] shrink`,children:Rs.map(z=>r.jsxs("option",{value:z,children:["speed ",z.toFixed(2)]},`speed-${z}`))})]})]}):r.jsx("select",{value:f,onChange:z=>{const b=Number(z.target.value);g(y=>({...y||{},pitch:b}))},className:`${x} w-[4.5rem] shrink`,children:$Q.map(z=>r.jsxs("option",{value:z,children:["pitch ",z]},z))})]})}function QQ({allowSpectatorInput:t=!1,hideSpectatorNotice:a=!1}){const{sendMessage:l,registerInputRef:s,onInputFocus:u,onInputBlur:f,blurChat:p,setTypingActive:v}=ea(),{canChat:g,ttsSupported:x}=IQ(t),{value:z,save:b}=F1("tts",d0),{engine:y,voice:H,pitch:S,googlePitch:C,googleSpeed:w}=GQ(z),[A,V]=d.useState(""),[L,R]=d.useState(!1),[q,j]=d.useState(!0),N=x&&q,E=d.useMemo(()=>N?y==="espeak"?{speak:!0,engine:y,pitch:S}:y==="chromegtts"?{speak:!0,engine:y,voice:H,pitch:C,speed:w}:{speak:!0,engine:y,voice:H}:null,[N,y,C,w,S,H]);async function G(O){if(O.preventDefault(),!g)return;const U=A.replace(/\\n/g,` -`).trim();if(U){R(!0);try{await l(U,E),V(""),p(),v(!1)}catch(s1){alert(s1.message)}finally{R(!1)}}}return r.jsxs("form",{className:"chat-composer",onSubmit:G,children:[r.jsx("div",{className:"chat-composer-nickname",children:r.jsx(YQ,{compact:!0})}),r.jsx("input",{className:"field-input chat-composer-input",value:A,onChange:O=>{const T=O.target.value;V(T),v(!!T.trim())},onFocus:O=>{u(O),v(!!A.trim())},onBlur:O=>{f(O),v(!1)},onKeyDown:O=>{O.key==="Enter"&&!A.trim()&&(O.preventDefault(),p(),v(!1))},ref:O=>s(O,{target:"panel"}),placeholder:g?"Type a message…":a?"":"Spectators cannot chat",disabled:!g}),r.jsx("button",{type:"submit",disabled:!g||L,className:"button-dark chat-composer-send disabled:opacity-50",children:L?"...":"Send"}),r.jsx(KQ,{ttsSupported:x,speak:N,onSpeakChange:j,engine:y,voice:H,pitch:S,googlePitch:C,googleSpeed:w,saveTtsSettings:b})]})}const XQ=d.memo(PQ),JQ=d.memo(QQ);function G8({hideInput:t=!1,hideSpectatorNotice:a=!1,fillHeight:l=!1,allowSpectatorInput:s=!1,title:u="Chat and speech",minimal:f=!1}){const p=f||t,v=f?"":u;return r.jsxs(j1,{title:v,hideHeader:f||!v,fillHeight:l,bodyClassName:"space-y-0.5 text-base",children:[r.jsx(XQ,{fillHeight:l}),!p&&r.jsx(JQ,{allowSpectatorInput:s,hideSpectatorNotice:a})]})}function ma({className:t=""}){const a=d1(l=>l.session?.socials??[]).slice(0,4);return a.length?r.jsx("div",{className:`grid grid-cols-2 grid-rows-2 gap-0.5 ${t}`,children:a.map(l=>r.jsx(n7,{id:l?.id||l?.key||l?.service||null},`${l?.id||l?.label||"social"}-${l?.url||""}`))}):null}function WQ(){return r.jsx(j1,{title:"Links!",fillHeight:!0,bodyClassName:"flex flex-1 min-h-0 flex-col gap-0.5 text-base",children:r.jsx(ma,{className:"flex-1 min-h-0"})})}function ac(...t){return t.filter(Boolean).join(" ")}function tX(t){const a=t?.batteryState?.percentDisplay;return a==null?"--":`${a}%`}function eX(t){return t?.batteryState?t.batteryState.urgentActive?"text-red-400":t.batteryState.warnActive?"text-amber-300":"text-emerald-300":"text-slate-400"}function cX(t){switch(t){case"admin":case"lockdown":case"lockdown-admin":return"text-amber-300";case"spectator":return"text-slate-400";default:return"text-sky-300"}}function aX(t,a){if(!t)return"";const l=t.nickname||t.socketId?.slice(0,6)||"unknown";return t.socketId&&t.socketId===a?`${l} (you)`:l}function o7({title:t="Rovers"}){const a=d1(N=>N.session?.role||null),l=d1(N=>N.session?.roster??[]),s=d1(N=>N.session?.turnQueues??{}),u=d1(N=>N.session?.users??[]),f=d1(N=>N.session?.socketId||null),p=d1(N=>String(N.session?.assignment?.roverId||"").trim()),v=d1(N=>{const E=String(N.session?.assignment?.roverId||"").trim();return E?(N.session?.roster||[]).find(O=>String(O?.id)===E)?.name||E:""}),{requestControl:g,rebootOwnRover:x}=G2(),[z,b]=d.useState({}),[y,H]=d.useState(!1),S=d.useMemo(()=>a&&a!=="spectator",[a]),C=d.useMemo(()=>a==="admin"||a==="lockdown"||a==="lockdown-admin",[a]),w=d.useMemo(()=>Object.values(s||{}).some(N=>N?.deadline||N?.idleDeadline),[s]),A=U8(1e3,w),V=d.useMemo(()=>{const N=new Set(l.map(G=>String(G.id))),E=Object.keys(s||{}).filter(G=>!N.has(String(G))).map(G=>({id:G,name:G,locked:!1,batteryState:null}));return[...l,...E]},[l,s]);async function L(N){if(N){b(E=>({...E,[N]:!0})),u1("rover_queue_join",{roverId:N,alreadyAssigned:p===String(N)});try{await g(N),u1("rover_queue_join_result",{roverId:N,status:"accepted"})}catch(E){u1("rover_queue_join_result",{roverId:N,status:"failed",reason:E?.message||"unknown"}),alert(E.message)}finally{b(E=>({...E,[N]:!1}))}}}const R=N=>u.find(E=>E.socketId===N)||{socketId:N,nickname:null,role:null};async function q(){if(!(y||!window.confirm(`Reboot your rover "${v}" now?`))){H(!0),u1("rover_reboot_click",{roverId:p,scope:"own_rover"});try{await x(),u1("rover_reboot_result",{roverId:p,scope:"own_rover",status:"accepted"}),alert("Reboot command sent.")}catch(E){u1("rover_reboot_result",{roverId:p,scope:"own_rover",status:"failed",reason:E?.message||"unknown"}),alert(E.message)}finally{H(!1)}}}const j=a!=="spectator"&&p?r.jsx("button",{type:"button",onClick:q,disabled:y,className:"button-dark bg-amber-700/80 text-amber-50 hover:bg-amber-600 disabled:opacity-40",title:"Reboot your assigned rover",children:y?"Rebooting...":"Reboot My Rover"}):null;return r.jsx(j1,{title:t,actions:j,bodyClassName:"space-y-0.5 text-sm",children:V.length===0?r.jsx("p",{className:"text-sm text-slate-500",children:"No rovers registered."}):r.jsx("ul",{className:"space-y-0.5 text-sm",children:V.map(N=>{const E=String(N.id),G=s?.[E]||null,O=G?.queue||[],T=G?.idleDeadline||G?.deadline||null,U=T&&T>A?Math.ceil((T-A)/1e3):T?0:null,s1=G?.current||null,n1=s1?O.findIndex(v1=>v1===s1):-1,Q=O.length>1?n1>=0?O[(n1+1)%O.length]:O[0]:null,k=!!(f&&s1&&s1===f),$=!!(f&&Q&&Q===f),t1=U!=null&&(k||$),f1=!!(N?.private?.enabled&&N?.private?.open),h1=!!(N?.private?.enabled&&!N?.private?.open),F=!!N.locked,D=F&&!C&&!h1,W=N.lockReason?`locked: ${N.lockReason}`:"locked",r1=z[E]?"...":F&&!h1?W:"request",m1=S&&!D&&!z[E];return r.jsxs("li",{className:ac("surface flex flex-wrap items-start justify-between gap-0.5",m1&&"cursor-pointer",F?"bg-red-900/40":f1?"bg-amber-700/35 border border-amber-200/30":null),onClick:()=>{m1&&L(N.id)},children:[r.jsxs("div",{className:"flex min-w-0 flex-1 flex-col gap-0.5",children:[r.jsxs("div",{className:"flex items-center justify-between gap-0.5",children:[r.jsxs("div",{className:"flex min-w-0 items-center gap-0.5",children:[r.jsxs("p",{className:"min-w-0 flex items-center gap-0.5 whitespace-nowrap text-slate-200",children:[r.jsx(V4,{rover:N,fallback:E}),N.description?r.jsx("span",{className:"min-w-0 flex-1 truncate text-[0.7rem] text-slate-400",children:N.description}):null]}),t1?r.jsx("span",{className:"rounded bg-slate-800 px-1 text-[0.7rem] text-slate-200",children:k?`${U}s left`:`Your turn in ${U}s`}):null]}),r.jsx("span",{className:ac("text-[0.75rem] font-semibold",eX(N)),children:tX(N)})]}),O.length===0?r.jsx("p",{className:"text-[0.7rem] text-slate-500",children:"No queue."}):r.jsx("div",{className:"flex flex-wrap items-center gap-0.5",children:O.map((v1,A1)=>{const V1=R(v1),L1=v1===s1,$1=!!(Q&&v1===Q&&!L1),K1=L1?"bg-sky-600 text-white ring-2 ring-amber-300":$1?"bg-emerald-700/60 text-emerald-100 ring-1 ring-emerald-300/70":"bg-slate-800 text-slate-200";return r.jsxs("span",{className:`flex items-center gap-0.5 rounded px-1 text-[0.7rem] ${K1}`,children:[r.jsx("span",{className:`${cX(V1.role)} font-semibold`,children:aX(V1,f)}),L1&&r.jsx("span",{className:"text-[0.65rem] text-slate-200",children:"now"}),$1&&r.jsx("span",{className:"text-[0.65rem] text-emerald-100",children:"next"})]},`${E}-${v1}-${A1}`)})})]}),S?r.jsx("button",{type:"button",onClick:v1=>{v1.stopPropagation(),L(N.id)},disabled:z[E]||D,className:ac("button-dark disabled:opacity-40",F&&"bg-red-600/70 text-white hover:bg-red-600"),children:r1}):null]},N.id)})})})}function nX(t){switch(t){case"admin":case"lockdown":case"lockdown-admin":return"text-amber-300";case"spectator":return"text-slate-400";default:return"text-sky-300"}}function lX(t,a){if(!t)return"";const l=t.nickname||t.socketId?.slice(0,6)||"unknown";return t.socketId&&t.socketId===a?`${l} (you)`:l}function Yt({hideNicknameForm:t=!1,hideHeader:a=!1,className:l="",fillHeight:s=!1,compact:u=!1}){const f=d1(x=>x.session?.users??[]),p=d1(x=>x.session?.socketId||null),v=d.useMemo(()=>[...f].sort((x,z)=>x.socketId===p?-1:z.socketId===p?1:(x.nickname||"").localeCompare(z.nickname||"")),[p,f]),g=s?"flex-1 min-h-0 overflow-y-auto":u?"h-28 overflow-y-auto":"h-48 overflow-y-auto";return r.jsxs(j1,{title:a?"":"Users",hideHeader:a,fillHeight:s,className:l,bodyClassName:"space-y-0.5 text-base",children:[!t&&r.jsx("div",{className:"space-y-0.5",children:r.jsxs("div",{className:"grid gap-0.5 md:grid-cols-[minmax(0,1.4fr)_minmax(0,1fr)]",children:[r.jsx("div",{className:"min-w-0",children:r.jsx("div",{className:"flex w-full items-center px-0 py-0",children:r.jsx(s7,{compact:u})})}),r.jsx(ma,{})]})}),r.jsx("div",{className:`space-y-0.5 ${s?"flex flex-1 min-h-0 flex-col":""}`,children:r.jsx("div",{className:`flex flex-wrap content-start items-start gap-0.5 px-0 pb-0 ${g} ${u?"text-[0.8rem]":""}`,children:v.length===0?r.jsx("p",{className:"text-sm text-slate-500",children:"Waiting for users…"}):v.map(x=>r.jsx("span",{className:`rounded px-1 py-0.25 text-[0.7rem] ${nX(x.role)}`,children:lX(x,p)},x.socketId))})})]})}function xt(t){return typeof t!="number"||Number.isNaN(t)?"—":`${t>0?"+":""}${t.toFixed(1)}°`}function Ts({label:t}){return t?r.jsx("span",{className:"rounded bg-slate-800 px-1 py-0.5 text-[0.6rem] font-semibold text-slate-200",children:t}):null}function rX({value:t,min:a,max:l,step:s=.5,label:u="Camera Tilt",orientation:f="horizontal",onChange:p,onCommit:v,throttleMs:g=0,disabled:x=!1,keyDownLabel:z,keyUpLabel:b,className:y="",labelRowClass:H="",labelClass:S="",valueClass:C="",sliderClass:w="",endpointClass:A="",endpointLabelClass:V="",accentClass:L="",showValue:R=!0,showEndpoints:q}){const j=f==="vertical",E=typeof q=="boolean"?q:!j,[G,O]=d.useState(t),T=d.useRef(!1),U=d.useRef(null);d.useEffect(()=>{T.current||O(t)},[t]),d.useEffect(()=>()=>{U.current&&clearTimeout(U.current)},[]);const s1=t1=>{if(p){if(g>0){U.current&&clearTimeout(U.current),U.current=setTimeout(()=>{p(t1)},g);return}p(t1)}},n1=t1=>{const f1=Number.parseFloat(t1.target.value);Number.isNaN(f1)||(T.current=!0,O(f1),s1(f1))},Q=()=>{T.current=!1,U.current&&(clearTimeout(U.current),U.current=null),v?v(G):g>0&&p?.(G)};if(typeof a!="number"||typeof l!="number")return null;const k=[j?"h-28 w-5":"w-full",L,w].filter(Boolean).join(" "),$=r.jsx("input",{type:"range",orient:j?"vertical":void 0,min:a,max:l,step:s,value:Number.isFinite(G)?G:a,onChange:n1,onMouseUp:Q,onTouchEnd:Q,onPointerUp:Q,disabled:x,className:k,style:j?{writingMode:"bt-lr",WebkitAppearance:"slider-vertical"}:void 0});return j?r.jsxs("div",{className:`flex h-full flex-col items-center gap-0.5 ${y}`.trim(),children:[R?r.jsx("div",{className:`flex flex-col items-center ${H}`.trim(),children:r.jsx("span",{className:C,children:xt(t)})}):null,r.jsxs("div",{className:"flex min-h-0 flex-1 items-center gap-0.5",children:[r.jsx("span",{className:S,children:u}),$]})]}):r.jsxs("div",{className:`space-y-0.5 ${x?"opacity-50":""} ${y}`.trim(),children:[r.jsxs("div",{className:`flex items-center justify-between ${H}`.trim(),children:[r.jsx("span",{className:S,children:u}),R?r.jsx("span",{className:`rounded bg-slate-800 px-1 py-0.5 text-[0.7rem] font-semibold ${C}`.trim(),children:xt(t)}):null]}),r.jsxs("div",{children:[$,E?r.jsxs("div",{className:`mt-0 flex items-center justify-between ${A}`.trim(),children:[r.jsxs("span",{className:`flex items-center gap-0.5 ${V}`.trim(),children:[z?r.jsx(Ts,{label:z}):null,xt(a)]}),r.jsxs("span",{className:`flex items-center gap-0.5 ${V}`.trim(),children:[xt(l),b?r.jsx(Ts,{label:b}):null]})]}):null]})]})}const iX=/^cu_[a-f0-9]{32}$/,M0="field-input w-full max-w-sm text-left focus:ring-emerald-500",I8="mx-auto w-full max-w-xl flex justify-center",g0="mx-auto flex w-full max-w-md flex-col items-center space-y-0.5 text-center";function sX(t){const a=String(t||"").trim();return a?a.length<=10?`${a.slice(0,2)}***${a.slice(-2)}`:`${a.slice(0,6)}...${a.slice(-6)}`:""}const qs=8*1024*1024,f6=16e3,oX={iceServers:[{urls:"stun:stun.l.google.com:19302"}],bundlePolicy:"max-bundle",rtcpMuxPolicy:"require"};function _s(t){let a="";for(let s=0;s{if(!t||t.iceGatheringState==="complete"){l();return}const s=setTimeout(()=>{t.removeEventListener("icegatheringstatechange",u),l()},a);function u(){t.iceGatheringState==="complete"&&(clearTimeout(s),t.removeEventListener("icegatheringstatechange",u),l())}t.addEventListener("icegatheringstatechange",u)})}function Ds(t){if(!t)return!1;const a=t.connectionState,l=t.iceConnectionState;return a==="connected"||l==="connected"||l==="completed"}function fX(t,a=1e4){return new Promise((l,s)=>{if(!t){s(new Error("Peer connection missing"));return}if(Ds(t)){l();return}const u=setTimeout(()=>{p(),s(new Error("Peer connection timeout"))},a),f=()=>{Ds(t)?(p(),l()):(t.connectionState==="failed"||t.connectionState==="closed"||t.iceConnectionState==="failed")&&(p(),s(new Error(`Peer connection ${t.connectionState||t.iceConnectionState}`)))};function p(){clearTimeout(u),t.removeEventListener("connectionstatechange",f),t.removeEventListener("iceconnectionstatechange",f)}t.addEventListener("connectionstatechange",f),t.addEventListener("iceconnectionstatechange",f)})}async function mX(t){if(!t?.getParameters||!t?.setParameters)return;const a=t.getParameters()||{},l=a.encodings&&a.encodings[0]||{};a.encodings=[{...l,maxBitrate:64e3,dtx:"disabled"}];try{await t.setParameters(a)}catch{}}function vX(t,a=6e3){return new Promise((l,s)=>{if(!t){s(new Error("Peer connection missing"));return}const u=Date.now();let f=-1;const p=setInterval(async()=>{if(Date.now()-u>a){clearInterval(p),s(new Error("WHIP connected but no outbound audio flow"));return}try{const v=t.getSenders().filter(g=>g.track?.kind==="audio");for(const g of v){const x=await g.getStats();for(const z of x.values()){if(z.type!=="outbound-rtp"||z.kind!=="audio")continue;const b=Number(z.bytesSent||0),y=Number(z.packetsSent||0);if(f<0)f=b;else if(b>f+200||y>5){clearInterval(p),l();return}}}}catch{}},250)})}function pX(t){const a=t.reduce((u,f)=>u+f.length,0),l=new Float32Array(a);let s=0;for(const u of t)l.set(u,s),s+=u.length;return l}function gX(t){const a=new Int16Array(t.length);for(let l=0;l{for(let z=0;zz1.state.keymap),g=k1(z1=>!!z1.state.mic?.pttActive),{value:x,save:z}=F1("vipAudio",{openMicEnabled:!1,pttMode:"live"}),b=String(t||"").trim(),[y,H]=d.useState(null),[S,C]=d.useState(!1),w=!!x?.openMicEnabled,V=(x?.pttMode==="clip"?"clip":"live")==="clip",[L,R]=d.useState("idle"),[q,j]=d.useState("idle"),[N,E]=d.useState(""),G=d.useRef(null),O=d.useRef(null),T=d.useRef(null),U=d.useRef(!1),s1=d.useRef(""),n1=d.useRef(null),Q=d.useRef(null),k=d.useRef(null),$=d.useRef(null),t1=d.useRef(null),f1=d.useRef([]),h1=d.useRef(!1),F=d.useRef(f6),D=d.useMemo(()=>b&&a?.[b]||null,[a,b]),W=!!(D&&D.state!=="offline"&&!D.error),r1=D?.source==="upload"&&D?.state==="playing",m1=D?.source==="mic-whip"&&(D?.state==="starting"||D?.state==="playing"),v1=!!(!V&&O.current&&(w||g)),A1=!V&&(L==="live"||L==="starting"),V1=V&&q==="recording",L1=V&&q==="sending",$1=_2(v?.micPtt?.[0])||"M",K1=d.useCallback(z1=>{const b1=z1==="clip"?"clip":"live";z(D1=>({...D1||{},pttMode:b1})),u1("vip_ptt_mode_change",{mode:b1,roverId:b})},[b,z]),T1=async()=>{if(!b){E("Take control of your rover first.");return}if(!y){E("Select an audio file first.");return}if(y.size>qs){E(`File too large (max ${qs} bytes).`);return}C(!0),E(""),u1("vip_upload_play",{roverId:b,size:y.size,mime:y.type||""});try{const z1=await y.arrayBuffer(),b1=_s(new Uint8Array(z1));await l?.({roverId:b,name:y.name,mime:y.type||"",dataBase64:b1}),E("Upload playback started."),u1("vip_upload_play_result",{roverId:b,status:"accepted"})}catch(z1){u1("vip_upload_play_result",{roverId:b,status:"failed",reason:z1?.message||"unknown"}),E(z1?.message||"Failed to play upload.")}finally{C(!1)}},x1=async()=>{if(!b){E("Take control of your rover first.");return}C(!0),E(""),u1("vip_upload_stop",{roverId:b});try{await s?.(b),E("Upload playback stopped."),u1("vip_upload_stop_result",{roverId:b,status:"accepted"})}catch(z1){u1("vip_upload_stop_result",{roverId:b,status:"failed",reason:z1?.message||"unknown"}),E(z1?.message||"Failed to stop upload.")}finally{C(!1)}},X=d.useCallback(async z1=>{const b1=String(z1||s1.current||"").trim();if(U.current=!1,R("idle"),T.current){try{T.current.getSenders().forEach(D1=>D1.track?.stop())}catch{}try{T.current.close()}catch{}}if(T.current=null,G.current)try{G.current.getTracks().forEach(D1=>D1.stop())}catch{}if(G.current=null,O.current=null,b1)try{await p?.(b1)}catch{}s1.current=""},[p]),g1=d.useCallback(async z1=>{const b1=await u?.(z1),D1=String(b1?.whipUrl||"").trim(),S2=String(b1?.token||"").trim();if(!D1||!S2)throw new Error("WHIP endpoint unavailable");const P1=await navigator.mediaDevices.getUserMedia({audio:{channelCount:1,sampleRate:f6,echoCancellation:!1,noiseSuppression:!1,autoGainControl:!1}});G.current=P1;const p2=P1.getAudioTracks()?.[0];if(O.current=p2||null,p2&&(p2.enabled=!!(w||g)),p2?.applyConstraints)try{await p2.applyConstraints({channelCount:1,sampleRate:f6,echoCancellation:!1,noiseSuppression:!1,autoGainControl:!1})}catch{}const W1=new RTCPeerConnection(oX);T.current=W1,W1.onconnectionstatechange=()=>{if(!U.current)return;const c1=W1.connectionState;if(c1==="connected"){R("live");return}(c1==="failed"||c1==="disconnected"||c1==="closed")&&(R("error"),E(`WHIP transport ${c1}.`))},P1.getAudioTracks().forEach(c1=>{const y1=W1.addTrack(c1,P1);mX(y1)});const t2=await W1.createOffer({offerToReceiveAudio:!1,offerToReceiveVideo:!1});await W1.setLocalDescription(t2),await dX(W1,1800);const o1=await fetch(D1,{method:"POST",headers:{"Content-Type":"application/sdp",...hX(S2)},body:W1.localDescription?.sdp||t2.sdp});if(!o1.ok)throw new Error(`WHIP request failed: ${o1.status}`);const P=await o1.text();await W1.setRemoteDescription({type:"answer",sdp:P}),await fX(W1,1e4),await vX(W1,6e3),await f?.(z1)},[w,g,f,u]),M1=d.useCallback(async()=>{if(h1.current=!1,$.current){try{$.current.disconnect()}catch{}$.current.onaudioprocess=null}if(k.current)try{k.current.disconnect()}catch{}if(t1.current)try{t1.current.disconnect()}catch{}if(n1.current)try{n1.current.getTracks().forEach(z1=>z1.stop())}catch{}if(Q.current)try{await Q.current.close()}catch{}f1.current=[],$.current=null,k.current=null,t1.current=null,n1.current=null,Q.current=null,F.current=f6},[]),p1=d.useCallback(async()=>{if(n1.current&&Q.current&&$.current)return;j(p2=>p2==="recording"?p2:"arming");const z1=await navigator.mediaDevices.getUserMedia({audio:{channelCount:1,sampleRate:f6,echoCancellation:!1,noiseSuppression:!1,autoGainControl:!1}}),b1=new AudioContext({latencyHint:"interactive"}),D1=b1.createMediaStreamSource(z1),S2=b1.createScriptProcessor(1024,1,1),P1=b1.createGain();P1.gain.value=0,S2.onaudioprocess=p2=>{if(!h1.current)return;const W1=p2.inputBuffer.getChannelData(0);f1.current.push(new Float32Array(W1))},D1.connect(S2),S2.connect(P1),P1.connect(b1.destination),n1.current=z1,Q.current=b1,k.current=D1,$.current=S2,t1.current=P1,F.current=b1.sampleRate||f6},[]),R1=d.useCallback(async({send:z1})=>{const b1=h1.current;if(h1.current=!1,!b1){z1||j("idle");return}const D1=f1.current;if(f1.current=[],!z1){j("idle"),u1("vip_clip_record_cancel",{roverId:b});return}if(!b){j("idle"),u1("vip_clip_send",{roverId:b,status:"skipped_no_rover"});return}if(!D1.length){j("idle"),u1("vip_clip_send",{roverId:b,status:"skipped_empty"});return}j("sending"),u1("vip_clip_send",{roverId:b,status:"started"});try{const S2=pX(D1),P1=xX(S2,F.current||f6),p2=_s(P1);await l?.({roverId:b,name:`ptt-${Date.now()}.wav`,mime:"audio/wav",dataBase64:p2}),j("idle"),u1("vip_clip_send",{roverId:b,status:"accepted"})}catch(S2){j("error"),u1("vip_clip_send",{roverId:b,status:"failed",reason:S2?.message||"unknown"}),E(S2?.message||"Failed to send PTT clip.")}},[l,b]),l2=d.useCallback(async()=>{if(!b){E("Take control of your rover first.");return}await p1(),f1.current=[],h1.current=!0,j("recording"),u1("vip_clip_record_start",{roverId:b})},[p1,b]);return d.useEffect(()=>{let z1=!1;async function b1(){if(V){await X(s1.current||b);return}if(!b){await X(s1.current);return}if(!(U.current&&s1.current===b)&&!(!w&&!g))try{R("starting"),E(""),U.current=!0,s1.current=b,await g1(b),z1||(R("live"),u1("vip_live_mic_start",{roverId:b}))}catch(D1){z1||(R("error"),E(D1?.message||"Failed to start mic forwarding."),v3("vip_live_mic_error",{roverId:b,reason:D1?.message||"unknown"},{key:`${b}:${D1?.message||"unknown"}`,throttleMs:60*1e3})),await X(b)}}return b1(),()=>{z1=!0}},[V,w,g,b,g1,X]),d.useEffect(()=>{const z1=O.current;z1&&(z1.enabled=!!(!V&&(w||g)))},[V,w,g]),d.useEffect(()=>{let z1=!1;async function b1(){if(!V||!b){h1.current&&await R1({send:!1}),j("idle");return}try{await p1(),!z1&&!h1.current&&j("idle")}catch(D1){z1||(j("error"),E(D1?.message||"Microphone access failed for clip mode."))}}return b1(),()=>{z1=!0}},[V,p1,R1,b]),d.useEffect(()=>{let z1=!1;async function b1(){if(V){if(!b){h1.current&&await R1({send:!1});return}if(g){if(!h1.current)try{E(""),await l2()}catch(D1){z1||(j("error"),E(D1?.message||"Failed to start clip recording."))}}else h1.current&&await R1({send:!0})}}return b1(),()=>{z1=!0}},[V,R1,g,b,l2]),d.useEffect(()=>()=>{X(s1.current||b),M1()},[b,X,M1]),r.jsx(j1,{title:"Audio Controls",children:r.jsxs("div",{className:"grid gap-1",children:[r.jsx("section",{className:"surface",children:r.jsxs("div",{className:"flex items-center justify-center gap-0.5 py-0.25 text-xs text-slate-300",children:[r.jsx("span",{children:"Push-to-Talk Key"}),r.jsx(Pt,{label:$1})]})}),r.jsxs("div",{className:"grid gap-0.5 grid-cols-1 lg:grid-cols-2",children:[r.jsx("section",{className:"surface h-full",children:r.jsxs("div",{className:"grid h-full gap-0.5 grid-rows-[auto_auto_1fr]",children:[r.jsx("p",{className:"text-sm text-slate-200 text-center",children:"PTT Mode"}),r.jsx("p",{className:"text-xs text-slate-400 text-center",children:"Choose how holding your PTT key behaves: live mic stream, or record-and-send clip. If the live stream doesn't work, switch to clip mode."}),r.jsxs("div",{className:"grid grid-cols-2 gap-0.5",children:[r.jsx("button",{type:"button",className:`button-dark w-full text-sm ${V?"":"bg-emerald-500 text-white hover:bg-emerald-500"}`,onClick:()=>K1("live"),children:"Live Mic (WHIP)"}),r.jsx("button",{type:"button",className:`button-dark w-full text-sm ${V?"bg-emerald-500 text-white hover:bg-emerald-500":""}`,onClick:()=>K1("clip"),children:"Record Clip"})]})]})}),r.jsx("section",{className:"surface h-full",children:r.jsxs("div",{className:"grid h-full gap-0.5 grid-rows-[auto_1fr]",children:[r.jsx("p",{className:"text-sm text-slate-200 text-center",children:"PTT Clip Status"}),r.jsxs("div",{className:"grid gap-0.5 content-start",children:[r.jsx(H4,{label:"Mode",active:V,detail:V?"record clip":"live mic"}),r.jsx(H4,{label:"PTT hold",active:g,detail:g?"held":"released"}),r.jsx(H4,{label:"Recording",active:V1,detail:V1?"capturing":"idle"}),r.jsx(H4,{label:"Playback",active:V&&r1,detail:V&&r1?"playing":"idle"})]})]})})]}),r.jsxs("div",{className:"grid gap-0.5 grid-cols-1 lg:grid-cols-2",children:[r.jsx("section",{className:"surface h-full",children:r.jsxs("div",{className:"grid h-full gap-0.5 grid-rows-[auto_auto_1fr_auto]",children:[r.jsx("p",{className:"text-sm text-slate-200 text-center",children:"Audio Upload"}),r.jsxs("label",{className:"mx-auto grid w-full max-w-sm gap-0.5 text-xs text-slate-300 text-center",children:[r.jsx("span",{children:"Audio file (mp3 / wav / ogg)"}),r.jsx("input",{className:`${M0} text-center`,type:"file",accept:".mp3,.wav,.ogg,audio/mpeg,audio/wav,audio/ogg",disabled:S||!b,onChange:z1=>H(z1.target.files?.[0]||null)})]}),r.jsx("div",{className:"mx-auto w-full max-w-sm text-center",children:y?r.jsxs("div",{className:"surface-muted text-xs text-slate-300",children:[y.name," (",y.size," bytes)"]}):r.jsx("div",{className:"surface-muted text-xs text-slate-500",children:"No file selected"})}),r.jsxs("div",{className:"flex justify-center gap-0.5",children:[r.jsx("button",{type:"button",className:"button-dark text-sm",disabled:S||!b,onClick:T1,children:S?"Working...":"Play Upload"}),r.jsx("button",{type:"button",className:"button-dark text-sm",disabled:S||!b,onClick:x1,children:"Stop"})]})]})}),r.jsx("section",{className:"surface h-full",children:r.jsxs("div",{className:"grid h-full gap-0.5 grid-rows-[auto_auto_1fr]",children:[r.jsx("p",{className:"text-sm text-slate-200 text-center",children:"Live Microphone"}),r.jsxs("label",{className:"surface-muted mx-auto flex w-full max-w-sm items-center justify-center gap-0.5 px-0.5 py-0.5 text-xs text-slate-300",children:[r.jsx("input",{type:"checkbox",checked:w,disabled:!b||V,onChange:z1=>{const b1=!!z1.target.checked;z(D1=>({...D1||{},openMicEnabled:b1})),u1("vip_open_mic_change",{roverId:b,enabled:b1})}}),r.jsx("span",{children:V?"Open mic (live mode only)":"Open mic"})]}),r.jsxs("div",{className:"grid gap-0.5 content-start",children:[r.jsx(H4,{label:"WHIP link",active:A1,detail:L}),r.jsx(H4,{label:"Mic hot",active:v1,detail:v1?"transmitting":"muted"}),r.jsxs("div",{className:"surface-muted text-center text-xs text-slate-400",children:["Hold ",r.jsx(Pt,{label:$1})," to talk"]})]})]})})]}),r.jsx("section",{className:"surface",children:r.jsxs("div",{className:"space-y-0.5",children:[r.jsx("p",{className:"text-sm text-slate-200 text-center",children:"Audio Status"}),r.jsxs("div",{className:"grid gap-0.5 grid-cols-1 sm:grid-cols-2 lg:grid-cols-6",children:[r.jsx(H4,{label:"Forward pipe",active:W,detail:W?"connected":"offline"}),r.jsx(H4,{label:"Upload playback",active:r1,detail:r1?"playing":"idle"}),r.jsx(H4,{label:"Mic relay",active:m1,detail:m1?"active":"idle"}),r.jsx(H4,{label:"WHIP transport",active:A1,detail:L}),r.jsx(H4,{label:"Clip recording",active:V1,detail:V1?"recording":"idle"}),r.jsx(H4,{label:"Clip sending",active:L1,detail:L1?"sending":"idle"})]}),N?r.jsx("div",{className:"text-xs text-slate-400 text-center",children:N}):null]})})]})})}function bX({pendingRequestId:t,currentStoredKey:a,nickname:l,requestVerification:s,applyIdentityKey:u,onMessage:f,fullWidth:p=!1}){const[v,g]=d.useState(0),[x,z]=d.useState(""),[b,y]=d.useState(!1),[H,S]=d.useState(!1),C=()=>{g(1),z(a),y(!1),f?.(""),u1("vip_verify_flow_start",{hasNickname:!!l})},w=()=>{g(0),y(!1)},A=async L=>{if(L.preventDefault(),!b){f?.("Please confirm your nickname agreement before sending.");return}if(v<3){f?.("Complete all request steps before sending.");return}S(!0),f?.(""),u1("vip_verify_attempt",{hasNickname:!!l,hasIdentityKey:!!x});try{const R=await u(x);await s?.(),z(R),g(0),y(!1),f?.("Verification request sent to lockdown admins."),u1("vip_verify_result",{status:"accepted"})}catch(R){u1("vip_verify_result",{status:"failed",reason:R?.message||"unknown"}),f?.(R.message||"Failed to submit request.")}finally{S(!1)}},V=p?"w-full":I8;return t?r.jsx(j1,{title:"Verification",className:V,bodyClassName:"text-sm text-slate-300",children:r.jsxs("div",{className:g0,children:["Verification request pending: ",t]})}):v===0?r.jsx(j1,{title:"Verification",className:V,children:r.jsx("div",{className:g0,children:r.jsx("button",{type:"button",className:"button-dark text-sm",onClick:C,disabled:H,children:"Request Verification"})})}):r.jsx(j1,{title:"Request verification",className:V,children:r.jsx("form",{onSubmit:A,children:r.jsxs("div",{className:g0,children:[r.jsxs("p",{className:"text-xs text-slate-500",children:["Step ",v," of 3"]}),v===1?r.jsxs("div",{className:"space-y-0.5",children:[r.jsx("p",{className:"text-xs text-slate-400",children:"Confirm your nickname, which is used as part of the verification process. You can edit it here before requesting."}),r.jsx("div",{className:"mx-auto w-full max-w-sm",children:r.jsx(s7,{compact:!0})}),r.jsxs("div",{className:"surface-muted mx-auto w-full max-w-sm text-xs text-slate-300 text-center",children:["Current nickname: ",r.jsx("span",{className:"font-semibold",children:l||"(not set)"})]}),r.jsxs("label",{className:"flex items-center justify-center gap-0.5 text-xs text-slate-300 text-center",children:[r.jsx("input",{type:"checkbox",className:"accent-emerald-500",checked:b,onChange:L=>y(L.target.checked)}),r.jsx("span",{children:"I understand this nickname is tied to my verification."})]}),r.jsxs("div",{className:"flex justify-center gap-0.5",children:[r.jsx("button",{type:"button",className:"button-dark text-sm",disabled:!l||!b,onClick:()=>g(2),children:"Continue"}),r.jsx("button",{type:"button",className:"button-dark text-sm",onClick:w,children:"Cancel"})]})]}):null,v===2?r.jsxs("div",{className:"space-y-0.5",children:[r.jsx("p",{className:"text-xs text-slate-400",children:"Save your identity key in a safe place. You can use it to restore your identity in another browser."}),r.jsx("input",{className:M0,type:"password",name:"identity_key_request",autoComplete:"current-password",maxLength:35,value:x,onChange:L=>z(L.target.value.toLowerCase()),placeholder:"Identity key for this request"}),r.jsxs("div",{className:"flex justify-center gap-0.5",children:[r.jsx("button",{type:"button",className:"button-dark text-sm",disabled:!x,onClick:()=>navigator.clipboard?.writeText(x),children:"Copy Key"}),r.jsx("button",{type:"button",className:"button-dark text-sm",disabled:!x,onClick:()=>g(3),children:"Continue"}),r.jsx("button",{type:"button",className:"button-dark text-sm",onClick:()=>g(1),children:"Back"})]})]}):null,v===3?r.jsxs("div",{className:"space-y-0.5",children:[r.jsx("p",{className:"text-xs text-slate-400",children:"Final step: confirm and send your verification request."}),r.jsx("input",{className:M0,type:"password",name:"identity_key_request_final",autoComplete:"current-password",maxLength:35,value:x,onChange:L=>z(L.target.value.toLowerCase()),placeholder:"Identity key for this request"}),r.jsxs("div",{className:"flex justify-center gap-0.5",children:[r.jsx("button",{type:"submit",className:"button-dark text-sm",disabled:H||!x,children:"Confirm Request"}),r.jsx("button",{type:"button",className:"button-dark text-sm",onClick:()=>g(2),children:"Back"})]})]}):null]})})})}function MX({currentStoredKey:t,applyIdentityKey:a,onMessage:l,fullWidth:s=!1}){const[u,f]=d.useState(0),[p,v]=d.useState(""),[g,x]=d.useState(!1),z=()=>{f(1),v(""),l?.("")},b=()=>{f(0),v("")},y=async S=>{if(S.preventDefault(),!(u<2)){x(!0),l?.("");try{await a(p),f(0),v(""),l?.("Identity key restored.")}catch(C){l?.(C.message||"Failed to restore key.")}finally{x(!1)}}},H=s?"w-full":I8;return r.jsx(j1,{title:"Identity key",className:H,children:r.jsxs("div",{className:g0,children:[r.jsxs("p",{className:"text-xs text-slate-500",children:["Current: ",sX(t)||"not set yet"]}),r.jsx("input",{className:M0,type:"password",name:"identity_key_current",autoComplete:"current-password",maxLength:35,value:t,readOnly:!0,placeholder:"Identity key"}),u===0?r.jsxs("div",{className:"flex justify-center gap-0.5",children:[r.jsx("button",{type:"button",className:"button-dark text-sm",disabled:!t,onClick:()=>navigator.clipboard?.writeText(t),children:"Copy Key"}),r.jsx("button",{type:"button",className:"button-dark text-sm",onClick:z,disabled:g,children:"Restore Key"})]}):null,u===1?r.jsxs("div",{className:"space-y-0.5",children:[r.jsx("p",{className:"text-xs text-slate-400",children:"Restoring your key should only be done when needed. Use this to move your identity to another browser."}),r.jsxs("div",{className:"flex justify-center gap-0.5",children:[r.jsx("button",{type:"button",className:"button-dark text-sm",onClick:()=>f(2),children:"Continue"}),r.jsx("button",{type:"button",className:"button-dark text-sm",onClick:b,children:"Cancel"})]})]}):null,u===2?r.jsxs("form",{className:"space-y-0.5",onSubmit:y,children:[r.jsx("input",{className:M0,type:"password",name:"identity_key_restore",autoComplete:"current-password",maxLength:35,value:p,onChange:S=>v(S.target.value.toLowerCase()),placeholder:"Paste key to restore"}),r.jsxs("div",{className:"flex justify-center gap-0.5",children:[r.jsx("button",{type:"submit",className:"button-dark text-sm",disabled:g||!p,children:"Confirm Restore"}),r.jsx("button",{type:"button",className:"button-dark text-sm",onClick:()=>f(1),children:"Back"})]})]}):null]})})}function yX({requestableRovers:t=[],pendingRequests:a=[],requestPrivateRoverAccess:l,onMessage:s,fullWidth:u=!1}){const[f,p]=d.useState({}),v=d.useMemo(()=>{const z=new Map;return(a||[]).forEach(b=>{b?.roverId&&z.set(String(b.roverId),b)}),z},[a]),g=u?"w-full":I8,x=async z=>{if(z){p(b=>({...b,[z]:!0})),s?.(""),u1("vip_private_rover_request",{roverId:z,status:"started"});try{const b=await l?.(z);u1("vip_private_rover_request",{roverId:z,status:b?.existing?"existing":"accepted"}),b?.existing?s?.("You already have a pending request for that rover."):s?.("Private rover access request sent to lockdown admins.")}catch(b){u1("vip_private_rover_request",{roverId:z,status:"failed",reason:b?.message||"unknown"}),s?.(b.message||"Failed to send request.")}finally{p(b=>({...b,[z]:!1}))}}};return r.jsx(j1,{title:"Private rover access requests",className:g,bodyClassName:"text-sm text-slate-300",children:r.jsx("div",{className:g0,children:t.length===0?r.jsx("p",{className:"text-xs text-slate-500",children:"No closed private rovers are available to request right now."}):r.jsx("div",{className:"w-full space-y-0.5",children:t.map(z=>{const b=String(z.id),y=!!f[b],H=v.get(b);return r.jsxs("div",{className:"surface-muted flex items-center justify-between gap-0.5 px-1 py-0.5",children:[r.jsxs("div",{className:"min-w-0 text-left",children:[r.jsx("p",{className:"truncate text-xs",children:r.jsx(V4,{rover:z,fallback:b,className:"max-w-full truncate align-middle"})}),r.jsx("p",{className:"truncate text-[0.7rem] text-slate-500",children:b})]}),H?r.jsx("span",{className:"rounded bg-amber-700/30 px-1 py-0.5 text-[0.7rem] text-amber-200",children:"Pending"}):r.jsx("button",{type:"button",onClick:()=>x(b),disabled:y,className:"button-dark text-xs disabled:opacity-50",children:y?"Sending...":"Request"})]},b)})})})})}function Tt(t){return String(t||"").trim()}function wX(t){const a=Tt(t);return a?a.includes("DOCKINGRUNNING")?"Returning":a.includes("PAUSED")?"Paused":a.includes("HOUSECLEANINGRUNNING")?"Cleaning":a.includes("SPOTCLEANINGRUNNING")?"Spot cleaning":a.includes("STATE_START")?"Starting":a.includes("STATE_IDLE")||a.includes("STATE_STANDBY")?"Idle":a:"--"}function Ju(t){return t==="good"?"bg-emerald-600 text-white":t==="warn"?"bg-amber-500 text-slate-900":t==="danger"?"bg-rose-600 text-white":"bg-slate-700 text-slate-100"}function zt({label:t,value:a,tone:l="muted",valueClass:s="",hideLabel:u=!1}){return r.jsxs("div",{className:`rounded-md px-1 py-0.75 text-center ${Ju(l)}`,children:[u?null:r.jsx("div",{className:"text-[0.72rem] opacity-90",children:t}),r.jsx("div",{className:`text-sm font-semibold ${s}`,title:String(a||""),children:a})]})}function CX({neato:t,onStart:a,onSendHome:l,onLocate:s,onClearErrors:u,onPowerCycle:f,fullWidth:p=!1}){const[v,g]=d.useState(""),x=p?"w-full":"w-full max-w-xl",z=!!t?.configured,b=!!(t?.enabled&&t?.connected),y=!!t?.telemetry?.extPowerPresent,H=!!t?.telemetry?.chargingActive,S=wX(t?.telemetry?.uiState),C=Tt(t?.telemetry?.robotState)||"--",w=t?.telemetry?.batteryPercent,A=Number.isFinite(w)?`${w}%`:"--",V=t?.telemetry?.batteryVoltage,L=Number.isFinite(V)?`${V.toFixed(2)} V`:"--",R=Tt(t?.telemetry?.robotError)||"--",q=Tt(t?.telemetry?.robotAlert)||"--",j=t?.controls||{},N=!!j?.start?.available,E=!!j?.sendHome?.available,G=!!j?.locate?.available,O=!!j?.clearErrors?.available,T=!!j?.powerCycle?.available,U=z&&b&&N,s1=z&&b&&E,n1=z&&b&&G,Q=z&&b&&O,k=z&&b&&T,$=async(D,W)=>{if(W){g(D);try{await W()}catch{}finally{g("")}}},t1=z?b?"Online":"Offline":"Not configured",f1=z?b?"good":"danger":"warn",h1=w==null?"muted":w>=60?"good":w>=25?"warn":"danger",F=y?"Docked":S!=="--"?S:"Away from dock";return r.jsx(j1,{title:"Neato Controls",className:x,bodyClassName:"text-sm text-slate-200",actions:r.jsx("span",{className:`inline-flex w-auto rounded px-1 py-0.25 text-xs font-semibold ${Ju(f1)}`,children:t1}),children:r.jsxs("div",{className:"grid gap-0.5",children:[r.jsx("div",{className:"text-center",children:r.jsx("p",{className:"text-xs text-slate-400",children:"Control the autonomous Neato robovac. Be nice to him."})}),r.jsxs("div",{className:"grid grid-cols-1 lg:grid-cols-2 gap-0.5",children:[r.jsxs("div",{className:"surface-muted grid gap-0.5",children:[r.jsx("p",{className:"text-xs text-slate-300 text-center",children:"Controls"}),r.jsx("button",{type:"button",disabled:!U||!!v,onClick:()=>$("start",a),className:"rounded-md border border-sky-300 bg-emerald-600 px-1 py-1 text-base font-semibold text-white transition hover:border-sky-500 hover:bg-emerald-500 disabled:opacity-50",children:v==="start"?"Starting...":"Start cleaning"}),r.jsx("button",{type:"button",disabled:!s1||!!v,onClick:()=>$("sendHome",l),className:"rounded-md border border-sky-300 bg-sky-600 px-1 py-1 text-base font-semibold text-white transition hover:border-sky-500 hover:bg-sky-500 disabled:opacity-50",children:v==="sendHome"?"Sending...":"Send to dock"}),r.jsxs("div",{className:"grid grid-cols-3 gap-0.5",children:[r.jsx("button",{type:"button",disabled:!n1||!!v,onClick:()=>$("locate",s),className:"w-full rounded-md border border-sky-300 bg-fuchsia-600 px-1 py-0.5 text-xs font-semibold text-white transition hover:border-sky-500 hover:bg-fuchsia-500 disabled:opacity-50",children:v==="locate"?"Playing...":"Play sound"}),r.jsx("button",{type:"button",disabled:!Q||!!v,onClick:()=>$("clearErrors",u),className:"w-full rounded-md border border-sky-300 bg-amber-500 px-1 py-0.5 text-xs font-semibold text-slate-900 transition hover:border-sky-500 hover:bg-amber-400 disabled:opacity-50",children:v==="clearErrors"?"Clearing...":"Clear errors"}),r.jsx("button",{type:"button",disabled:!k||!!v,onClick:()=>$("powerCycle",f),className:"w-full rounded-md border border-rose-300 bg-rose-600 px-1 py-0.5 text-xs font-semibold text-white transition hover:border-rose-500 hover:bg-rose-500 disabled:opacity-50",children:v==="powerCycle"?"Cycling...":"Power cycle"})]}),r.jsxs("div",{className:"surface-muted grid gap-0.5 pt-0.25",children:[r.jsx("p",{className:"text-xs text-slate-300 text-center",children:"Power status"}),r.jsxs("div",{className:"grid grid-cols-2 gap-0.5",children:[r.jsx(zt,{label:"Battery",value:A,tone:h1}),r.jsx(zt,{label:"Voltage",value:L,tone:"muted"}),r.jsx(zt,{label:"Docked",value:y?"Docked":"Not docked",tone:y?"good":"muted",hideLabel:!0}),r.jsx(zt,{label:"Charging",value:H?"charging":"not charging",tone:H?"good":"muted",hideLabel:!0})]})]})]}),r.jsx("div",{className:"grid gap-0.5",children:r.jsxs("div",{className:"surface-muted grid gap-0.5",children:[r.jsx("p",{className:"text-xs text-slate-300 text-center",children:"Robot Status"}),r.jsxs("div",{className:"grid gap-0.5",children:[r.jsxs("div",{className:"rounded-md bg-slate-800 px-1 py-0.5",children:[r.jsx("div",{className:"text-[0.72rem] text-slate-300",children:"Robot state (raw)"}),r.jsx("div",{className:"font-mono text-sm text-slate-100 break-all",children:C})]}),r.jsxs("div",{className:"rounded-md bg-slate-800 px-1 py-0.5",children:[r.jsx("div",{className:"text-[0.72rem] text-slate-300",children:"Basic state"}),r.jsx("div",{className:"font-mono text-sm text-slate-100 break-all",children:F})]}),r.jsxs("div",{className:"rounded-md bg-slate-800 px-1 py-0.5",children:[r.jsx("div",{className:"text-[0.72rem] text-slate-300",children:"UI state"}),r.jsx("div",{className:"font-mono text-sm text-slate-100 break-all",children:S})]}),r.jsxs("div",{className:"rounded-md bg-slate-800 px-1 py-0.5",children:[r.jsx("div",{className:"text-[0.72rem] text-slate-300",children:"Robot error"}),r.jsx("div",{className:"font-mono text-sm text-slate-100 break-all",children:R})]}),r.jsxs("div",{className:"rounded-md bg-slate-800 px-1 py-0.5",children:[r.jsx("div",{className:"text-[0.72rem] text-slate-300",children:"Robot alert"}),r.jsx("div",{className:"font-mono text-sm text-slate-100 break-all",children:q})]})]})]})})]}),!z||!b||!N||!E||!G||!O||!T?r.jsx("p",{className:"text-xs text-slate-400 text-center",children:z?b?"Waiting for required Neato entities in Home Assistant.":"Home Assistant is offline.":"Set homeAssistant.neato.device in server config to enable Neato controls."}):null]})})}function HX(t){return t==="good"?"bg-emerald-600 text-white":t==="warn"?"bg-amber-500 text-slate-900":t==="danger"?"bg-rose-600 text-white":"bg-slate-700 text-slate-100"}function SX(t){return t==="up"?"Up":t==="down"?"Down":t==="stopped"?"Transitioning...":t==="conflict"?"Conflict":"--"}function AX({lift:t,onUp:a,onDown:l,fullWidth:s=!1}){const[u,f]=d.useState(""),[p,v]=d.useState(()=>Date.now()),g=s?"w-full":"w-full max-w-xl",x=!!t?.configured,z=!!(t?.enabled&&t?.connected),b=!!t?.busy,y=String(t?.target||"").toLowerCase(),H=String(t?.position||"").toLowerCase(),S=!!t?.availability?.upSwitch,C=!!t?.availability?.downSwitch,w=Number(t?.lastActionAt||0),A=Math.max(0,Number(t?.commandCooldownMs||0)),V=Math.max(0,w+A-p),L=!b&&V>0,R=b||L;d.useEffect(()=>{if(!R)return;const O=setInterval(()=>{v(Date.now())},100);return()=>clearInterval(O)},[R]),d.useEffect(()=>{v(Date.now())},[w,A,b]);const q=x?z?R?"Busy":"Ready":"Offline":"Not configured",j=x?z?R?"warn":"good":"danger":"warn",N=x&&z&&!R&&!u&&S&&C,E=d.useMemo(()=>Math.ceil(V/1e3),[V]),G=async(O,T)=>{if(T){f(O);try{await T()}catch{}finally{f("")}}};return r.jsxs(j1,{title:"Lift Controls",className:`relative ${g}`,bodyClassName:"text-sm text-slate-200",actions:r.jsx("span",{className:`inline-flex w-auto rounded px-1 py-0.25 text-xs font-semibold ${HX(j)}`,children:q}),children:[R?r.jsx("div",{className:"absolute inset-0 z-20 flex items-center justify-center rounded-md bg-slate-950/80 px-1.5 text-center",children:r.jsxs("div",{className:"space-y-0.25",children:[r.jsx("p",{className:"text-sm font-semibold text-slate-100",children:b?"Preparing to move":"Moving!"}),r.jsx("p",{className:"text-xs text-slate-300",children:"Controls are disabled while the lift is moving, otherwise its tiny brain would get confused."}),!b&&L?r.jsxs("p",{className:"text-xs text-slate-400",children:["About ",E,"s remaining."]}):null]})}):null,r.jsxs("div",{className:"grid gap-0.5",children:[r.jsx("div",{className:"text-center",children:r.jsx("p",{className:"text-xs text-slate-400",children:"Move the lift up and down. Please don't break anything..."})}),r.jsx("section",{className:"surface-muted px-0.5 py-0.5",children:r.jsxs("div",{className:"grid grid-cols-1 md:grid-cols-3 gap-0.5",children:[r.jsxs("div",{className:"rounded-md bg-slate-800 px-1 py-0.75 text-center",children:[r.jsx("div",{className:"text-xs text-slate-300",children:"Position"}),r.jsx("div",{className:"text-base font-semibold text-slate-100",children:SX(H)})]}),r.jsx("button",{type:"button",disabled:!N,onClick:()=>G("down",l),className:`button-dark w-full text-sm disabled:opacity-50 ${H==="down"||y==="down"?"bg-emerald-500 text-white hover:bg-emerald-500":""}`,children:u==="down"||y==="down"?"Lowering...":"Down"}),r.jsx("button",{type:"button",disabled:!N,onClick:()=>G("up",a),className:`button-dark w-full text-sm disabled:opacity-50 ${H==="up"||y==="up"?"bg-emerald-500 text-white hover:bg-emerald-500":""}`,children:u==="up"||y==="up"?"Raising...":"Up"})]})}),!x||!z||!S||!C?r.jsx("p",{className:"text-xs text-slate-400 text-center",children:x?z?"Waiting for required lift switch entities in Home Assistant.":"Home Assistant is offline.":"Set homeAssistant.lift.upSwitch and homeAssistant.lift.downSwitch in server config."}):null,t?.lastError?r.jsxs("p",{className:"text-xs text-rose-300 text-center",children:["Last error: ",t.lastError]}):null]})]})}function VX(t){const a=String(t||"").trim();if(!a)return"";try{const l=new URL(a),s=String(l.protocol||"").toLowerCase();return s!=="http:"&&s!=="https:"?"":l.toString()}catch{return""}}function LX({isVerified:t=!1,fullWidth:a=!1,onMessage:l}){const{value:s,save:u}=F1("profile",{nickname:"",profileImageUrl:""}),f=String(s?.profileImageUrl||"").trim(),[p,v]=d.useState(f),[g,x]=d.useState(!1);d.useEffect(()=>{v(f)},[f]);const z=d.useMemo(()=>VX(p),[p]),b=String(p||"").trim()!==f,y=!!(t&&b&&(z||!String(p||"").trim())),H=a?"w-full":I8,S=async C=>{if(C.preventDefault(),!t){l?.("Verify your account before setting a profile image URL.");return}x(!0),l?.("");try{const w=z||"";u(A=>({...A||{},profileImageUrl:w})),l?.(w?"Profile image URL saved.":"Profile image URL cleared.")}finally{x(!1)}};return r.jsx(j1,{title:"Chat profile image URL",className:H,bodyClassName:"text-sm text-slate-300",children:r.jsxs("form",{className:g0,onSubmit:S,children:[r.jsx("p",{className:"text-xs text-slate-500",children:"Verified users can set a custom avatar for chat and Discord bridge messages."}),r.jsx("input",{className:M0,type:"url",name:"vip_profile_image_url",placeholder:"https://example.com/avatar.png",value:p,onChange:C=>v(C.target.value),disabled:!t||g}),!z&&String(p||"").trim()?r.jsx("p",{className:"text-xs text-amber-300",children:"Enter a valid http/https image URL."}):null,r.jsxs("div",{className:"flex justify-center gap-0.5",children:[r.jsx("button",{type:"submit",className:"button-dark text-sm disabled:opacity-50",disabled:!y||g,children:g?"Saving...":"Save URL"}),r.jsx("button",{type:"button",className:"button-dark text-sm disabled:opacity-50",disabled:!t||g||!f,onClick:()=>v(""),children:"Clear"})]})]})})}function Wu({isActive:t=!0}){const a=d1(n1=>n1.session),{identifySession:l,requestVerification:s,requestPrivateRoverAccess:u,playUploadedAudio:f,stopUploadedAudio:p,startMicWhip:v,readyMicWhip:g,stopMicWhip:x,neatoStart:z,neatoSendHome:b,neatoLocate:y,neatoClearErrors:H,neatoPowerCycle:S,liftUp:C,liftDown:w}=G2(),{value:A,save:V}=F1("identity",{cookieUserId:""}),{value:L}=F1("profile",{nickname:""}),R=d.useMemo(()=>(A?.cookieUserId||"").trim(),[A?.cookieUserId]),q=(L?.nickname||"").trim(),j=!!a?.isVerified,N=a?.verification?.pendingRequestId||null,E=a?.privateRoverAccess?.requestableRovers||[],G=a?.privateRoverAccess?.pendingRequests||[],O=String(a?.assignment?.roverId||"").trim(),[T,U]=d.useState(""),s1=async n1=>{const Q=String(n1||"").trim().toLowerCase();if(!Q)throw new Error("Identity key required.");if(!iX.test(Q))throw new Error("Identity key must match format: cu_ + 32 lowercase hex chars.");return V(k=>({...k||{},cookieUserId:Q})),await l({cookieUserId:Q,nickname:q}),Q};return r.jsxs("section",{className:"space-y-2 text-base",children:[r.jsxs("div",{className:"grid gap-2 grid-cols-1 lg:grid-cols-[minmax(0,1.25fr)_minmax(0,0.9fr)]",children:[j?null:r.jsx("div",{className:"lg:col-span-2",children:r.jsx(bX,{pendingRequestId:N,currentStoredKey:R,nickname:q,requestVerification:s,applyIdentityKey:s1,onMessage:U,fullWidth:!0})}),r.jsx("div",{className:"lg:col-span-2",children:j?r.jsxs("div",{className:"space-y-2",children:[r.jsx(CX,{neato:a?.neato||null,onStart:z,onSendHome:b,onLocate:y,onClearErrors:H,onPowerCycle:S,fullWidth:!0}),r.jsx(AX,{lift:a?.lift||null,onUp:C,onDown:w,fullWidth:!0}),r.jsx(zX,{ownRoverId:O,audioForwardByRover:a?.audioForward||{},playUploadedAudio:f,stopUploadedAudio:p,startMicWhip:v,readyMicWhip:g,stopMicWhip:x})]}):r.jsx("section",{className:"surface h-full",children:r.jsx("div",{className:"flex h-full flex-col items-center justify-center text-center text-xs text-slate-400",children:"Verify your account to unlock VIP controls."})})}),r.jsx("div",{className:"lg:col-span-2",children:r.jsx(yX,{requestableRovers:E,pendingRequests:G,requestPrivateRoverAccess:u,onMessage:U,fullWidth:!0})}),r.jsx("div",{className:"lg:col-span-2",children:r.jsx(MX,{currentStoredKey:R,applyIdentityKey:s1,onMessage:U,fullWidth:!0})}),r.jsx("div",{className:"lg:col-span-2",children:r.jsx(LX,{isVerified:j,onMessage:U,fullWidth:!0})})]}),T?r.jsx("div",{className:I8,children:r.jsx("p",{className:"text-xs text-slate-400 text-center",children:T})}):null]})}const BX=420,jX=1200,NX={1:262,2:330,3:392,4:523};function Kt(){const t=d1(C=>C.session?.buttonBox?.buttons??[]),a=E2(),{value:l}=F1("audio",g2),s=Number.isFinite(l?.masterVolume)?l.masterVolume:g2.masterVolume,u=Number.isFinite(l?.alertVolume)?l.alertVolume:g2.alertVolume,f=Math.max(0,Math.min(1,s*u)),p=d.useMemo(()=>{const C=Array.isArray(t)?t:[];return C.length===4?C:[1,2,3,4].map(w=>C.find(A=>Number(A?.id)===w)||{id:w,count:0,goal:0,rewardName:null,rewardId:null,rewardNumber:null,lastRewardAt:null})},[t]),[v,g]=d.useState({}),[x,z]=d.useState({}),b=d.useRef(new Map),y=d.useRef(new Map),H=d.useRef({}),S=d.useRef(null);return d.useEffect(()=>{const C={};p.forEach(A=>{C[A.id]=Number(A.lastRewardAt||0)});const w=H.current||{};p.forEach(A=>{const V=Number(A.id),L=C[V]||0,R=Number(w[V]||0);if(L>0&&L!==R){z(N=>({...N,[V]:!0}));const q=y.current.get(V);q&&clearTimeout(q);const j=setTimeout(()=>{z(N=>({...N,[V]:!1})),y.current.delete(V)},jX);y.current.set(V,j)}}),H.current=C},[p]),d.useEffect(()=>{function C(A){const V=NX[A];if(!V||f<=0)return;let L=S.current;if(!L){const N=window.AudioContext||window.webkitAudioContext;if(!N)return;L=new N,S.current=L}const R=L.createOscillator(),q=L.createGain();R.type="square",R.frequency.value=V;const j=.14*f;q.gain.setValueAtTime(1e-4,L.currentTime),q.gain.exponentialRampToValueAtTime(Math.max(1e-4,j),L.currentTime+.01),q.gain.exponentialRampToValueAtTime(1e-4,L.currentTime+.2),R.connect(q),q.connect(L.destination),R.start(),R.stop(L.currentTime+.21)}function w(A={}){const V=Number(A.buttonId);if(!Number.isFinite(V)||V<1||V>4)return;g(q=>({...q,[V]:!0}));const L=b.current.get(V);L&&clearTimeout(L);const R=setTimeout(()=>{g(q=>({...q,[V]:!1})),b.current.delete(V)},BX);b.current.set(V,R),C(V)}return a.on("buttonBox:increment",w),()=>{a.off("buttonBox:increment",w)}},[f,a]),r.jsx(j1,{title:"Button Box",bodyClassName:"space-y-0.5 text-base",children:r.jsx("div",{className:"grid grid-cols-4 gap-0.5",children:p.map(C=>{const w=Number(C.id),A=Number.isFinite(C.count)?C.count:0,V=Number.isFinite(C.goal)?C.goal:0,L=typeof C.rewardName=="string"&&C.rewardName.trim()?C.rewardName.trim():"Unassigned",R=Number.isFinite(C.rewardNumber)?C.rewardNumber:"?",q=!!v[w],j=!!x[w];return r.jsx(Jo,{buttonId:w,count:A,goal:V,rewardNumber:R,rewardName:L,className:[q?"bg-cyan-900/45":"",j?"bg-fuchsia-900/45":""].filter(Boolean).join(" ")},w)})})})}const Os=10*1e3,FX=5*1e3,Vc={activeGameId:null,games:[],activeGame:null,participants:[],counters:{objects:[],rovers:[],codes:[]},recentEvents:[],ownPlayer:null};function Us(t={}){return{...Vc,...t&&typeof t=="object"?t:{},games:Array.isArray(t?.games)?t.games:[],participants:Array.isArray(t?.participants)?t.participants:[],counters:{...Vc.counters,...t?.counters&&typeof t.counters=="object"?t.counters:{}},recentEvents:Array.isArray(t?.recentEvents)?t.recentEvents:[]}}function th(){const t=E2(),[a,l]=d.useState(Vc),[s,u]=d.useState({connected:!!t.connected,stale:!0,lastReceivedAt:null});d.useEffect(()=>{let p=!1,v=null,g=null,x=0;function z(S={}){p||(x=Date.now(),l(Us(S)),u({connected:!!t.connected,stale:!1,lastReceivedAt:x}))}function b(){t.emit("barcodeGame:subscribe",{},(S={})=>{if(S.state){z(S.state);return}u(C=>({...C,connected:!!t.connected,stale:!x}))})}function y(){u(S=>({...S,connected:!0,stale:!x})),b()}function H(){u(S=>({...S,connected:!1,stale:!0}))}return t.on("barcodeGame:state",z),t.on("connect",y),t.on("disconnect",H),b(),v=window.setInterval(()=>{const S=!x||Date.now()-x>Os;u(C=>({...C,connected:!!t.connected,stale:S}))},1e3),g=window.setInterval(()=>{t.connected&&(!x||Date.now()-x>Os)&&b()},FX),()=>{p=!0,window.clearInterval(v),window.clearInterval(g),t.off("barcodeGame:state",z),t.off("connect",y),t.off("disconnect",H)}},[t]);const f=d.useCallback(p=>new Promise((v,g)=>{t.emit("barcodeGame:vote",{gameId:p},(x={})=>{if(x.error){g(new Error(x.error));return}x.state&&l(Us(x.state)),v(x)})}),[t]);return d.useMemo(()=>({state:a,connectionState:s,voteForGame:f}),[s,a,f])}function nc(t){return Number.isFinite(t)?Math.max(0,Math.min(255,Math.round(t))):null}function kX(t){const a=nc(t?.r),l=nc(t?.g),s=nc(t?.b);return a===null||l===null||s===null?null:{r:a,g:l,b:s}}function S8(t,a){return`rgba(${t.r}, ${t.g}, ${t.b}, ${a})`}function eh(t){const a=kX(t);return a?{textStyle:{color:S8(a,.96)},buttonStyle:{borderLeftColor:S8(a,.9)},selectedButtonStyle:{borderLeftColor:S8(a,1),backgroundColor:S8(a,.12)},titleBoxStyle:{borderLeftColor:S8(a,.88)}}:{textStyle:void 0,buttonStyle:void 0,titleBoxStyle:void 0,boxStyle:void 0}}function RX(t){const[a,l]=d.useState(()=>Date.now());return d.useEffect(()=>{if(!t)return;const s=window.setInterval(()=>{l(Date.now())},500);return()=>window.clearInterval(s)},[t]),a}function EX(t,a){if(!Number.isFinite(t))return null;const l=Math.max(0,Math.ceil((t-a)/1e3)),s=Math.floor(l/60),u=l%60;return s>0?`${s}:${String(u).padStart(2,"0")}`:`${u}s`}function TX({game:t,disabled:a,onVote:l}){const s=eh(t.themeColor),u=(t.active||t.selected)&&s.selectedButtonStyle||s.buttonStyle;return r.jsxs("button",{type:"button",disabled:a||t.active,onClick:()=>l(t.id),className:"surface flex min-h-[3.5rem] flex-col items-start justify-between border-l-4 border-l-neutral-600 px-1 py-0.75 text-left transition-colors hover:bg-neutral-700 disabled:cursor-not-allowed disabled:opacity-70",style:u,children:[r.jsxs("span",{className:"flex w-full items-start justify-between gap-1",children:[r.jsx("span",{className:"text-sm font-semibold leading-tight text-neutral-50",style:s.textStyle,children:t.title}),r.jsx("span",{className:"surface-muted shrink-0 px-1 py-0 text-center font-mono text-[0.72rem] text-neutral-200",children:t.voteCount||0})]}),r.jsx("span",{className:"mt-0.5 line-clamp-2 text-xs leading-snug text-neutral-300",children:t.description}),r.jsx("span",{className:"mt-0.5 text-[0.7rem] font-semibold text-neutral-400",children:t.active?"Active":t.selected?"Selected":t.actionLabel||"Vote"})]})}function qX({stats:t,theme:a}){return!Array.isArray(t)||!t.length?null:r.jsx("div",{className:"grid gap-0.5 sm:grid-cols-3",children:t.slice(0,6).map(l=>r.jsxs("div",{className:"surface px-1 py-0.75 text-center",children:[r.jsx("p",{className:"truncate text-[0.68rem] text-neutral-400",children:l.label}),r.jsx("p",{className:"mt-0.25 truncate text-base font-semibold leading-tight text-neutral-100",style:a.textStyle,children:l.value})]},l.label))})}function _X({participants:t,theme:a}){const l=Array.isArray(t)?t:[],s=l.map(u=>u?.nickname||u?.roverId).filter(Boolean);return r.jsxs("div",{className:"surface min-w-0 px-1 py-0.75",children:[r.jsx("p",{className:"text-sm font-semibold text-neutral-400",children:"Participants"}),r.jsx("p",{className:"font-mono text-xl font-semibold leading-tight text-neutral-50",style:a.textStyle,children:l.length}),r.jsx("p",{className:"truncate text-sm leading-tight text-neutral-300",children:s.length?s.join(", "):"Scan rover to join"})]})}function Zs({title:t,entries:a}){return!Array.isArray(a)||!a.length?null:r.jsxs("div",{children:[r.jsx("p",{className:"mb-0.5 text-xs font-semibold text-neutral-300",children:t}),r.jsx("div",{className:"grid gap-0.5",children:a.slice(0,4).map(l=>r.jsxs("div",{className:"surface-muted grid grid-cols-[minmax(0,1fr)_2.5rem] items-center gap-0.5 px-1 py-0.5 text-xs",children:[r.jsx("span",{className:"min-w-0 truncate text-neutral-200",children:l.label||l.entityId||l.code}),r.jsx("span",{className:"text-right font-mono text-neutral-200",children:l.count||0})]},`${l.entityId||l.code}-${l.type||"counter"}`))})]})}function DX({players:t,ownPlayer:a}){const l=a&&Number.isFinite(a.totalPoints);return r.jsx("div",{className:"space-y-1",children:r.jsxs("div",{className:"grid gap-0.5 sm:grid-cols-[minmax(0,0.8fr)_minmax(0,1.2fr)]",children:[r.jsxs("div",{className:"surface px-1 py-0.75",children:[r.jsx("p",{className:"text-xs text-neutral-400",children:"Your points"}),r.jsx("p",{className:"text-lg font-semibold leading-tight text-neutral-50",children:l?a.totalPoints:0}),a?.rank?r.jsxs("p",{className:"text-[0.7rem] text-neutral-400",children:["Rank ",a.rank]}):null]}),r.jsxs("div",{className:"surface px-1 py-0.75",children:[r.jsx("p",{className:"mb-0.5 text-xs font-semibold text-neutral-300",children:"Leaderboard"}),Array.isArray(t)&&t.length?r.jsx("div",{className:"space-y-0.5",children:t.slice(0,4).map((s,u)=>r.jsxs("div",{className:"grid grid-cols-[1.25rem_minmax(0,1fr)_auto] gap-1 text-xs",children:[r.jsx("span",{className:"font-mono text-neutral-500",children:u+1}),r.jsx("span",{className:"truncate text-neutral-200",children:s.nickname}),r.jsx("span",{className:"font-mono text-neutral-300",children:s.totalPoints})]},s.playerKey))}):r.jsx("p",{className:"text-xs text-neutral-500",children:"No points yet"})]})]})})}function ch(){const{state:t,connectionState:a,voteForGame:l}=th(),[s,u]=d.useState(null),f=d.useRef(""),p=d.useRef(0),v=t.activeGame,g=v?.display||{},x=t.phase==="joining"||t.phase==="starting"||t.phase==="running",z=g.timer?.endsAt,b=RX(Number.isFinite(z)),y=EX(z,b),H=d.useMemo(()=>Array.isArray(t.games)?t.games:[],[t.games]),S=Array.isArray(t.participants)?t.participants:[],C=eh(v?.themeColor);d.useEffect(()=>{!a.stale||!a.lastReceivedAt||u1("barcode_game_state_stale",{connected:a.connected,phase:t.phase||"unknown"})},[a.connected,a.lastReceivedAt,a.stale,t.phase]),d.useEffect(()=>{const A=`${v?.id||"none"}:${v?.status||t.phase||"unknown"}`;f.current!==A&&(f.current=A,u1("barcode_game_active_change",{gameId:v?.id||"",status:v?.status||"",phase:t.phase||"unknown"}),(v?.status==="ending"||t.phase==="ending")&&u1("barcode_game_round_end",{gameId:v?.id||"",participantCount:S.length}))},[v?.id,v?.status,S.length,t.phase]),d.useEffect(()=>{if(S.length<=p.current){p.current=S.length;return}p.current=S.length,u1("barcode_game_player_join",{gameId:v?.id||"",participantCount:S.length})},[v?.id,S.length]);const w=async A=>{u(A),u1("barcode_game_vote",{gameId:A,phase:t.phase||"unknown",status:"started"});try{await l(A),u1("barcode_game_vote",{gameId:A,phase:t.phase||"unknown",status:"accepted"})}catch(V){throw u1("barcode_game_vote",{gameId:A,phase:t.phase||"unknown",status:"failed",reason:V?.message||"unknown"}),V}finally{u(null)}};return r.jsxs(j1,{title:"Barcode games",bodyClassName:"space-y-1 p-0.5 text-sm",children:[r.jsx("div",{className:"grid gap-0.5 sm:grid-cols-2",children:H.map(A=>r.jsx(TX,{game:A,disabled:!!s||x,onVote:w},A.id))}),r.jsxs("section",{className:"space-y-1 border-t border-neutral-700 pt-1",children:[r.jsxs("div",{className:"grid items-stretch gap-0.5 lg:grid-cols-[minmax(0,1fr)_9rem_10rem]",children:[r.jsxs("div",{className:"surface min-w-0 border-l-4 border-neutral-700 px-1 py-0.75",style:C.titleBoxStyle,children:[r.jsx("p",{className:"break-words text-xl font-bold leading-tight text-neutral-50",style:C.textStyle,children:g.title||v?.title||"No game active"}),r.jsx("p",{className:"mt-0.5 break-words text-sm font-semibold leading-tight text-neutral-200",children:g.primary||"Vote for a game to start"}),g.secondary?r.jsx("p",{className:"mt-0.5 break-words text-xs leading-snug text-neutral-300",children:g.secondary}):null]}),r.jsxs("div",{className:"surface px-1 py-0.75 text-left lg:text-right",children:[r.jsx("p",{className:"text-xs font-semibold text-neutral-400",children:g.timer?.label||"Time"}),r.jsx("p",{className:"font-mono text-xl font-semibold leading-tight text-neutral-50",style:C.textStyle,children:y||"--"}),r.jsx("p",{className:"text-xs leading-tight text-neutral-500",children:y?"active timer":"no timer"})]}),r.jsx(_X,{participants:S,theme:C})]}),r.jsx(qX,{stats:g.stats,theme:C})]}),r.jsx(DX,{players:t.leaderboard,ownPlayer:t.ownPlayer}),r.jsxs("div",{className:"grid gap-0.5 border-t border-neutral-700 pt-1 sm:grid-cols-2",children:[r.jsx("div",{className:"surface px-1 py-0.75",children:r.jsx(Zs,{title:"Most scanned objects",entries:t.counters?.objects})}),r.jsx("div",{className:"surface px-1 py-0.75",children:r.jsx(Zs,{title:"Most scanned rovers",entries:t.counters?.rovers})})]})]})}function OX(t){const a=Number(t);if(!Number.isFinite(a)||a<=0)return null;const l=new Date(a);return Number.isNaN(l.getTime())?null:l.toLocaleTimeString([],{hour:"numeric",minute:"2-digit",second:"2-digit"})}function UX({memory:t,onClose:a}){const l=typeof t?.summary=="string"&&t.summary.trim()?t.summary:"Memory unavailable.",s=OX(t?.updatedAt);return r.jsx("div",{className:"fixed inset-0 z-40 flex items-center justify-center bg-black/75 p-1",onClick:a,children:r.jsx("div",{className:"w-full max-w-2xl",onClick:u=>u.stopPropagation(),children:r.jsx(j1,{title:"Overseer memory",meta:s?`Updated ${s}`:null,actions:r.jsx("button",{type:"button",onClick:a,className:"button-dark px-1 py-0.25 text-[0.75rem]",children:"Close"}),bodyClassName:"p-0.5 text-xs",children:r.jsx("pre",{className:"surface max-h-[70vh] overflow-y-auto whitespace-pre-wrap break-words font-mono text-[0.72rem] text-slate-200",children:l})})})})}function ZX(){const{identifySession:t}=G2(),a=d1(H=>H.session?.overseerVote||null),l=d1(H=>H.overseerMemory||null),{value:s}=F1("profile",{nickname:""}),{value:u}=F1("identity",{cookieUserId:""}),{value:f,save:p}=F1("overseerPreference",{enabled:!1}),[v,g]=d.useState(!1),x=!!f?.enabled,z=!!a?.running,b=async H=>{const S=!!H?.target?.checked;await p(C=>({...C||{},enabled:S})),await t({cookieUserId:String(u?.cookieUserId||"").trim(),nickname:String(s?.nickname||"").trim(),overseerEnabled:S})},y=r.jsx("button",{type:"button",onClick:()=>g(!0),className:"button-dark px-1 py-0.25 text-[0.75rem]",title:"View overseer memory",children:"Memory"});return r.jsxs(r.Fragment,{children:[r.jsxs(j1,{title:"Overseer vote",actions:y,bodyClassName:"space-y-0.5 text-center text-xs text-slate-200",children:[r.jsxs("label",{className:`flex items-center justify-center gap-1.5 rounded px-1 py-0.5 ${x?"bg-emerald-600/80 text-emerald-50":"bg-slate-600/70 text-slate-100"}`,children:[r.jsx("input",{type:"checkbox",checked:x,onChange:b}),r.jsxs("span",{children:["Your vote: ",x?"Yes":"No"]})]}),r.jsx("span",{className:"text-xs",children:"Enable a local LLM in chat"}),r.jsxs("div",{className:"mt-0.5 text-slate-400",children:["Yes!: ",Number(a?.yesCount||0),", No...: ",Number(a?.noCount||0)]}),r.jsx("div",{className:"mt-0.5 flex justify-center",children:r.jsx("span",{className:`inline-flex items-center rounded px-1.5 py-0.5 text-[0.7rem] font-medium ${z?"bg-emerald-600/80 text-emerald-50":"bg-slate-600/70 text-slate-100"}`,children:z?"Running!":"Stopped by vote."})})]}),v?r.jsx(UX,{memory:l,onClose:()=>g(!1)}):null]})}function ah(){return d1(a=>!!a.session?.overseerVote?.votingEnabled)?r.jsx(ZX,{}):null}const $X=224,GX=144,IX=300,PX=8;function YX(){const t=k1(l=>l.state.roverId),a=Z4(t,Zc,Eo);return r.jsx(j1,{title:"Roomba sensor view",children:r.jsx("div",{className:"aspect-square w-full",children:r.jsx(Eu,{mapTelemetry:a})})})}function KX(){const t=k1(U=>U.state.roverId),a=k1(U=>U.state.keymap),l=k1(U=>U.state.camera),s=k1(U=>U.state.horn),u=k1(U=>U.pipeline?.nightVision),f=k1(U=>U.pipeline?.nightVisionState),p=k1(U=>U.pipeline?.horn),{setServoAngle:v,setNightVision:g,startHorn:x,stopHorn:z}=x3(),b=A0(),y=Au(t),H=y.docked&&!y.driving,S=l?.config,C=!!(t&&l?.enabled&&S),w=!!(t&&u),A=!!(t&&p),V=s?.overheated,L=typeof S?.minAngle=="number"?S.minAngle:-30,R=typeof S?.maxAngle=="number"?S.maxAngle:30,q=typeof l?.angle=="number"?l.angle:typeof S?.homeAngle=="number"?S.homeAngle:(L+R)/2,j=_2(a?.nightVisionToggle?.[0]),N=_2(a?.hornHonk?.[0]),E=_2(a?.cameraUp?.[0]),G=_2(a?.cameraDown?.[0]),O=!!(!t||b.cameraLocked),T=d.useMemo(()=>({setNightVision:U=>{u1("night_vision_toggle",{roverId:t,source:"desktop_control",enabled:!!U}),g(U)},startHorn:()=>(u1("horn_start",{roverId:t,source:"desktop_control"}),x()),stopHorn:z}),[t,g,x,z]);return r.jsxs(j1,{hideHeader:!0,className:"h-full",bodyClassName:`grid h-full min-h-0 grid-rows-[minmax(0,1fr)_auto] ${C2}`,children:[r.jsx(Vu,{layout:"desktop",expand:!0,driveDockState:y}),H?null:r.jsxs("div",{className:`${x6} p-0 text-sm text-slate-200`,children:[w&&r.jsx(Hu,{nightVisionOn:f?.nightVisionOn,disabled:!t,onToggle:T.setNightVision,keyLabel:j}),A&&r.jsx(Cu,{disabled:!t||V,onStart:T.startHorn,onStop:T.stopHorn,keyLabel:N,active:s?.active,heat:s?.heat}),C&&r.jsx(rX,{value:q,min:L,max:R,label:"Camera tilt",disabled:O,onChange:v,keyDownLabel:G,keyUpLabel:E,className:`${x6} rounded-xl border-2 border-emerald-300/70 bg-emerald-900 px-1 py-1 text-emerald-50`,labelRowClass:"text-xs text-emerald-100",labelClass:"text-sm font-semibold",valueClass:"font-mono text-slate-100",sliderClass:"w-full",accentClass:"accent-emerald-400",endpointClass:"text-[0.7rem] text-emerald-100/80"})]})]})}function QX({layout:t,onOpenHelpOverlay:a}){const[l,s]=d.useState("telemetry"),u=d.useRef(null),[f,p]=d.useState($X),v=d1(L=>!!L.session?.isVerified),g=d1(L=>String(L.session?.assignment?.roverId||"").trim()),x=d1(L=>{const R=String(L.session?.assignment?.roverId||"").trim();return R&&L.session?.audioForward?.[R]||null}),z=k1(L=>!!L.state.mic?.pttActive),{value:b}=F1("vipAudio",{openMicEnabled:!1,pttMode:"live"}),y=v?"bg-emerald-400":"bg-red-600",H=!!b?.openMicEnabled,S=b?.pttMode==="clip"?"clip":"live",C=!!(g&&v&&(S==="clip"?z:H||z)),w=!!(g&&v&&S==="clip"&&x?.source==="upload"&&x?.state==="playing"),A=d1(L=>!!L.session?.overseerVote?.votingEnabled),V=d.useCallback(L=>{s(L),u1("tab_change",{tab:L,layout:t,surface:"desktop_right_pane"})},[t]);return d.useLayoutEffect(()=>{const L=u.current;if(!L)return;let R=0,q=0,j=0;const N=()=>{R=0;const{top:T}=L.getBoundingClientRect(),U=window.innerHeight-T-PX,s1=Math.round(Math.max(GX,Math.min(IX,U)));p(n1=>Math.abs(n1-s1)>1?s1:n1)},E=()=>{R||(R=window.requestAnimationFrame(N))},G=()=>{q=window.requestAnimationFrame(()=>{q=0,j=window.requestAnimationFrame(()=>{j=0,N()})})},O=typeof ResizeObserver=="function"?new ResizeObserver(()=>{E()}):null;return E(),G(),O&&L.parentElement&&O.observe(L.parentElement),window.addEventListener("resize",E),document.addEventListener("scroll",E,{capture:!0,passive:!0}),()=>{R&&window.cancelAnimationFrame(R),q&&window.cancelAnimationFrame(q),j&&window.cancelAnimationFrame(j),O?.disconnect(),window.removeEventListener("resize",E),document.removeEventListener("scroll",E,{capture:!0})}},[l]),r.jsx("section",{className:"text-base",children:r.jsxs(ha,{defaultTab:"telemetry",currentTab:l,onTabChange:V,children:[r.jsxs(da,{children:[r.jsx(K2,{id:"telemetry",children:"Controls"}),r.jsx(K2,{id:"activities",children:"Activities"}),r.jsx(K2,{id:"vip",highlight:w?"green":C?"pink":"none",children:r.jsxs("span",{className:"inline-flex items-center gap-2",children:[r.jsx("span",{children:"VIP"}),r.jsx("span",{className:`inline-block h-3 w-3 rounded-full ${y}`,"aria-hidden":"true",title:v?"Verified":"Not verified"})]})}),r.jsx(K2,{id:"help",children:"Help"}),r.jsx(K2,{id:"settings",children:"Settings"})]}),r.jsxs(fa,{children:[r.jsx(Q2,{id:"telemetry",children:r.jsxs("div",{className:`flex flex-col ${C2}`,children:[r.jsxs("div",{className:`flex flex-col ${C2}`,children:[r.jsxs("div",{className:`grid items-stretch ${C2} grid-cols-[minmax(0,1.35fr)_minmax(0,0.95fr)]`,children:[r.jsx(YX,{}),r.jsx(KX,{})]}),r.jsxs("div",{className:`grid ${C2} grid-cols-[minmax(0,1fr)_minmax(0,0.9fr)_minmax(0,0.75fr)]`,children:[r.jsx(o7,{}),r.jsx(Yc,{panelId:"replay-sources-desktop",fillHeight:!0}),r.jsx(WQ,{})]}),r.jsxs("div",{ref:u,className:`grid min-h-0 items-stretch ${C2} grid-cols-[minmax(0,1.3fr)_minmax(0,0.22fr)]`,style:{height:`${f}px`},children:[r.jsx(G8,{fillHeight:!0}),r.jsxs("div",{className:`grid min-h-0 ${C2} ${A?"grid-rows-[auto_minmax(0,1fr)]":"grid-rows-[minmax(0,1fr)]"}`,children:[A?r.jsx(ah,{}):null,r.jsx(Yt,{compact:!0,hideNicknameForm:!0,fillHeight:!0})]})]})]}),r.jsx(Uu,{}),r.jsx(la,{defaultOrientation:"horizontal",panelId:"rightpane-telemetry"})]})}),r.jsx(Q2,{id:"activities",children:r.jsxs("div",{className:`flex flex-col ${C2}`,children:[r.jsx(ch,{}),r.jsx(Kt,{}),r.jsx(ju,{})]})}),r.jsx(Q2,{id:"vip",keepMounted:!0,children:r.jsx(Wu,{isActive:l==="vip"})}),r.jsx(Q2,{id:"help",children:r.jsx(Xu,{layout:t,onOpenOverlay:a})}),r.jsx(Q2,{id:"settings",children:r.jsx(Yu,{})})]})]})})}const XX=new Set(["admin","lockdown","lockdown-admin"]),JX=new Set(["lockdown","lockdown-admin"]),WX=new Set(["admin","lockdown"]);function tJ(t="admin"){return t==="lockdown"?{title:"Lockdown mode active",description:"Only the server owners can access the interface at this time."}:{title:"Admin mode active"}}function eJ(){const t=d1(x=>x.session?.mode||null),a=d1(x=>x.session?.role||null),l=d1(x=>x.session?.adminReason?.text||""),s=d1(x=>x.session?.timezone||"UTC"),u=WX.has(t),f=t==="lockdown"?JX.has(a):XX.has(a),p=U8(1e3,u&&!f),v=d.useMemo(()=>{const x=new Date(p);try{return new Intl.DateTimeFormat("en-US",{timeZone:s,hour:"numeric",minute:"2-digit",second:"2-digit"}).format(x)}catch{return x.toLocaleTimeString()}},[p,s]);if(!u||f)return null;const g=tJ(t);return r.jsx("div",{className:"pointer-events-auto fixed inset-0 z-50 flex items-center justify-center bg-black px-0.5 py-0.5",children:r.jsxs("div",{className:"surface w-full max-w-md space-y-0.5 text-slate-100 shadow-2xl",children:[r.jsxs("div",{className:"space-y-0.5",children:[r.jsx("p",{className:"text-lg font-semibold",children:g.title}),r.jsx("p",{className:"text-sm text-slate-300",children:g.description})]}),r.jsxs("div",{className:"surface-muted space-y-0.5",children:[r.jsx("p",{className:"text-[0.7rem] tracking-wide text-slate-400",children:"Reason for locking:"}),r.jsx("p",{className:"text-lg font-semibold text-slate-100",children:l||"No reason set."}),r.jsxs("p",{className:"text-center text-sm text-slate-300",children:["Server time: ",v]})]}),r.jsx("div",{className:"surface-muted",children:r.jsx(Zu,{})}),r.jsx("div",{className:"w-full justify-center items-center",children:r.jsx(n7,{id:"discord",label:"Join our Discord server for updates!"})}),"You can still use the chat while the server is locked:",r.jsx("div",{className:"max-h-80 overflow-y-auto",children:r.jsx(G8,{nicknameLayout:"stacked"})})]})})}const cJ="/assets/turn_alert-DVO8EZJa.mp3";function aJ(t,a=1){const l=d.useRef(null);return d.useEffect(()=>{l.current=new Audio(t),l.current.volume=a,l.current.load()},[t,a]),()=>{l.current&&(l.current.volume=a,l.current.currentTime=0,l.current.play().catch(()=>{}))}}function nJ(){const t=d1(z=>z.session?.socketId||null),a=d1(z=>z.session?.turnQueues||{}),l=d1(z=>z.session?.roster||[]),{pushAlert:s}=G2(),{value:u}=F1("audio",g2),f=Number.isFinite(u?.masterVolume)?u.masterVolume:g2.masterVolume,p=Number.isFinite(u?.alertVolume)?u.alertVolume:g2.alertVolume,v=Math.max(0,Math.min(1,f*p)),g=aJ(cJ,v),x=d.useRef(new Set);return d.useEffect(()=>{if(!t)return;const z=[];Object.entries(a).forEach(([b,y])=>{!y||!y.current||y.current!==t||x.current.has(b)||(z.push(b),x.current.add(b))}),Object.keys(a).forEach(b=>{(!a[b]||a[b].current!==t)&&x.current.delete(b)}),z.length!==0&&(z.forEach(b=>{const y=l.find(H=>String(H.id)===String(b))?.name||b;s({title:"Your turn!",message:`You now control ${y}.`,color:"#ff5722"})}),g())},[a,g,s,l,t]),null}function lJ({visible:t,mode:a,onEnterFullscreen:l,onDismiss:s}){if(!t)return null;const u=a==="pwa-hint";return r.jsx("div",{className:"fixed inset-0 z-40 flex items-center justify-center p-1 pointer-events-none bg-black/20",children:r.jsx("div",{className:"pointer-events-auto w-full max-w-sm surface center",children:r.jsxs("div",{className:"space-y-0.5 p-1 text-sm text-slate-100",children:[r.jsx("h2",{className:"text-base font-semibold text-white border-b border-slate-700",children:"Better in fullscreen!"}),u?r.jsxs("p",{className:"text-slate-300",children:["For fullscreen on iOS, open Safari's share menu and pick ",r.jsx("strong",{children:"Add to Home Screen"}),". Launching from the home screen then makes it fullscreen."]}):r.jsx("p",{className:"text-slate-300",children:"Enable fullscreen to free up more space for the video feed and controls. You can exit fullscreen at any time via the system back or home gesture."}),r.jsx("p",{className:"text-xs border-t border-b border-slate-700 p-0.5 text-blue-300 text-center",children:"This will only show once just to let you know. There is a fullscreen button in the bottom right for later use."}),r.jsxs("div",{className:"flex justify-end gap-0.5 pt-1 text-sm",children:[r.jsx("button",{type:"button",className:"rounded border border-slate-600 px-3 py-1 text-slate-200",onClick:s,children:u?"Got it":"Not now"}),!u&&r.jsx("button",{type:"button",className:"rounded bg-cyan-500 px-3 py-1 font-semibold text-black hover:bg-cyan-400",onClick:l,children:"Enter fullscreen"})]})]})})})}function rJ({side:t="right",onClick:a}){const l=t==="left"?"left-2":"right-2";return r.jsx("button",{type:"button",onClick:a,className:`fixed bottom-2 ${l} z-30 flex h-10 w-10 items-center justify-center rounded-full border border-slate-700 bg-black text-slate-200 transition hover:bg-zinc-900 active:scale-95`,"aria-label":"Enter fullscreen",title:"Enter fullscreen",children:r.jsx("svg",{viewBox:"0 0 24 24",width:"18",height:"18","aria-hidden":"true",className:"pointer-events-none",children:r.jsx("path",{d:"M4 9V4h5M15 4h5v5M20 15v5h-5M9 20H4v-5",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"})})})}const iJ=new Set(["mobile-portrait","mobile-landscape"]),sJ=()=>{if(typeof navigator>"u")return!1;const t=navigator.userAgent||navigator.platform||"";return/iphone|ipad|ipod/i.test(t)},$s=()=>{if(typeof document>"u")return!1;const t=document;return!!(t.fullscreenEnabled||t.webkitFullscreenEnabled||t.mozFullScreenEnabled||t.msFullscreenEnabled)};function oJ(t){const{value:a,save:l,status:s}=F1("page",{fullscreenPromptShown:!1}),u=iJ.has(t),[f,p]=d.useState(!1),[v,g]=d.useState("native"),[x,z]=d.useState(!1),b=!!a?.fullscreenPromptShown,y=d.useMemo(()=>sJ(),[]),H=d.useMemo(()=>$s(),[]),S=d.useCallback(()=>{s==="ready"&&l(L=>L?.fullscreenPromptShown?L:{...L||{},fullscreenPromptShown:!0})},[l,s]),C=d.useCallback(()=>{if(s!=="ready"){p(!1);return}if(!u){p(!1),z(!1);return}if(!x&&b){p(!1);return}if(y){g("pwa-hint"),p(!0);return}if(!$s()){p(!1);return}if(typeof document<"u"&&document.fullscreenElement){p(!1);return}g("native"),p(!0)},[x,b,y,u,s]);d.useEffect(()=>{C()},[C]),d.useEffect(()=>{if(typeof document>"u")return;const L=()=>{if(document.fullscreenElement){z(!1),p(!1);return}C()};return document.addEventListener("fullscreenchange",L),document.addEventListener("webkitfullscreenchange",L),()=>{document.removeEventListener("fullscreenchange",L),document.removeEventListener("webkitfullscreenchange",L)}},[C]);const w=d.useCallback(()=>{S(),z(!1),p(!1)},[S]),A=d.useCallback(async()=>{if(!u||y||typeof document>"u")return!1;if(document.fullscreenElement)return!0;const L=document.documentElement;if(!L)return!1;const R=L.requestFullscreen||L.webkitRequestFullscreen||L.mozRequestFullScreen||L.msRequestFullscreen;if(!R)return!1;try{const q=R.call(L);return q&&typeof q.then=="function"&&await q,S(),z(!1),p(!1),!0}catch(q){return console.warn("Failed to enter fullscreen",q),!1}},[y,u,S]),V=d.useCallback(()=>{u&&(z(!0),g(y?"pwa-hint":"native"),p(!0))},[y,u]);return d.useEffect(()=>{u||(z(!1),p(!1))},[u]),{visible:f,mode:v,isIOS:y,nativeSupported:H,enterFullscreen:A,dismiss:w,showPrompt:V}}function uJ({visible:t,layout:a,onClose:l,showOnLoad:s,onToggleShowOnLoad:u}){const f=k1(v=>v.state.keymap);if(!t)return null;const p=v=>{const g=!v.target.checked;u?.(g)};return r.jsx("div",{className:"fixed inset-0 z-30 flex items-center justify-center bg-black/80 px-0.5 py-0.5",children:r.jsxs("div",{className:"pointer-events-auto surface w-full max-w-4xl max-h-[90vh] overflow-hidden shadow-2xl",children:[r.jsxs("div",{className:"flex items-center justify-between border-b border-slate-700 px-0.5 py-0.25 text-sm text-slate-200",children:[r.jsx("span",{className:"font-semibold",children:"Help & controls"}),r.jsxs("div",{className:"flex items-center gap-0.5 text-[0.8rem] text-slate-300",children:[r.jsxs("label",{className:"flex items-center gap-0.5",children:[r.jsx("input",{type:"checkbox",checked:!s,onChange:p,className:"accent-cyan-500"}),r.jsx("span",{children:"Don't show again"})]}),r.jsx("button",{type:"button",onClick:l,className:"button-dark px-2 py-0.25 text-[0.8rem]",children:"Close"})]})]}),r.jsx("div",{className:"max-h-[85vh] overflow-y-auto p-0.5",children:r.jsx(Qu,{layout:a,keymap:f||{}})})]})})}function u0({label:t,keyLabel:a}){return r.jsxs("div",{className:"surface-muted flex items-center justify-between gap-0.5 px-0.5 py-0.35 text-[0.8rem] text-slate-200",children:[r.jsx("span",{children:t}),r.jsx(Pt,{label:a})]})}function hJ({keymap:t}){return r.jsxs("div",{className:"space-y-0.5",children:[r.jsx("p",{className:"text-sm text-slate-200",children:'1. Press "Start Driving" put your rover into driving mode.'}),r.jsxs("div",{className:"space-y-0.5",children:[r.jsx("p",{className:"text-sm text-slate-200",children:"2. Use the drive controls to move your rover:"}),r.jsxs("div",{className:"space-y-0.5",children:[r.jsx(u0,{label:"Forward",keyLabel:_2(t?.driveForward?.[0])}),r.jsx(u0,{label:"Backward",keyLabel:_2(t?.driveBackward?.[0])}),r.jsx(u0,{label:"Turn Left",keyLabel:_2(t?.driveLeft?.[0])}),r.jsx(u0,{label:"Turn Right",keyLabel:_2(t?.driveRight?.[0])}),r.jsx(u0,{label:"Move faster",keyLabel:_2(t?.boostModifier?.[0])}),r.jsx(u0,{label:"Move slower",keyLabel:_2(t?.slowModifier?.[0])})]})]}),r.jsx("p",{className:"text-sm text-slate-200",children:'3. When done, enter "Docking Assist" and line up the front sensor with the dock sensor.'})]})}function dJ(){return r.jsxs("div",{className:"space-y-0.5 text-sm text-slate-200",children:[r.jsx("p",{children:'1. Press "Start Driving" put your rover into driving mode.'}),r.jsx("p",{children:"2. Touch and hold in Joystick area to move."}),r.jsx("p",{children:"3. Use the other column for motor, horn, and camera controls."}),r.jsx("p",{children:'4. When done, enter "Docking Assist" and line up the front sensor with the dock sensor.'})]})}function fJ({visible:t,layout:a,showOnLoad:l,onToggleShowOnLoad:s,onOpenHelp:u,onClose:f}){const p=k1(z=>z.state.keymap),v=a==="desktop",g=d.useMemo(()=>p||{},[p]);if(!t)return null;const x=z=>{const b=!z.target.checked;s?.(b)};return r.jsx("div",{className:"fixed inset-0 z-40 flex items-end justify-center bg-black/75 p-0.5 items-center",children:r.jsxs("div",{className:"pointer-events-auto surface w-full max-w-3xl overflow-hidden shadow-2xl",children:[r.jsx("div",{className:"flex items-center justify-between border-b border-slate-700 px-0.5 py-0.35 text-sm text-slate-200",children:r.jsx("span",{className:"font-semibold text-xl",children:"Welcome! To get started:"})}),r.jsxs("div",{className:`grid gap-0.5 p-0.5 ${v?"md:grid-cols-[minmax(0,1.5fr)_minmax(0,1fr)]":"grid-cols-1"}`,children:[r.jsx("section",{className:"space-y-0.5 border-b border-slate-700",children:v?r.jsx(hJ,{keymap:g}):r.jsx(dJ,{})}),r.jsxs("section",{className:"space-y-0.5",children:[r.jsx("p",{className:"text-left",children:"Next..."}),r.jsxs("div",{className:"surface space-y-0.5 p-0.5 border-b border-slate-700",children:[r.jsx("p",{className:"text-xl font-semibold text-slate-200",children:"Set your nickname"}),r.jsx("p",{className:"text-sm font-semibold text-slate-200",children:"Nicknames are assigned randomly by default, you can change yours here."}),r.jsx(s7,{compact:!0})]}),r.jsxs("div",{className:"surface p-0.5",children:[r.jsx("p",{className:"text-xl font-semibold text-slate-200",children:"Join our Discord server!"}),r.jsx("p",{className:"text-sm font-semibold text-slate-200",children:"We have an active and welcoming community :3"}),r.jsx(n7,{id:"discord",label:"Join Discord"})]})]})]}),r.jsxs("div",{className:"flex flex-wrap items-center justify-between gap-0.5 border-t border-slate-700 px-0.5 py-0.35 text-[0.8rem]",children:[r.jsxs("label",{className:"flex items-center gap-0.5 text-slate-300",children:[r.jsx("input",{type:"checkbox",checked:!l,onChange:x,className:"accent-cyan-500"}),r.jsx("span",{children:"Don't show again"})]}),r.jsx("div",{className:"flex items-center gap-0.5",children:r.jsx("button",{type:"button",onClick:f,className:"button-dark px-1 py-0.25 text-2xl bg-green-600 hover:bg-green-400 hover:border-green-100 border-green-400",children:"Got it! Let me in!"})})]})]})})}const mJ=`aroma +`).trim();if(U){R(!0);try{await l(U,E),V(""),p(),v(!1)}catch(s1){alert(s1.message)}finally{R(!1)}}}return r.jsxs("form",{className:"chat-composer",onSubmit:G,children:[r.jsx("div",{className:"chat-composer-nickname",children:r.jsx(YQ,{compact:!0})}),r.jsx("input",{className:"field-input chat-composer-input",value:A,onChange:O=>{const T=O.target.value;V(T),v(!!T.trim())},onFocus:O=>{u(O),v(!!A.trim())},onBlur:O=>{f(O),v(!1)},onKeyDown:O=>{O.key==="Enter"&&!A.trim()&&(O.preventDefault(),p(),v(!1))},ref:O=>s(O,{target:"panel"}),placeholder:g?"Type a message…":a?"":"Spectators cannot chat",disabled:!g}),r.jsx("button",{type:"submit",disabled:!g||L,className:"button-dark chat-composer-send disabled:opacity-50",children:L?"...":"Send"}),r.jsx(KQ,{ttsSupported:x,speak:N,onSpeakChange:j,engine:y,voice:H,pitch:S,googlePitch:C,googleSpeed:w,saveTtsSettings:b})]})}const XQ=d.memo(PQ),JQ=d.memo(QQ);function G8({hideInput:t=!1,hideSpectatorNotice:a=!1,fillHeight:l=!1,allowSpectatorInput:s=!1,title:u="Chat and speech",minimal:f=!1}){const p=f||t,v=f?"":u;return r.jsxs(j1,{title:v,hideHeader:f||!v,fillHeight:l,bodyClassName:"space-y-0.5 text-base",children:[r.jsx(XQ,{fillHeight:l}),!p&&r.jsx(JQ,{allowSpectatorInput:s,hideSpectatorNotice:a})]})}function ma({className:t=""}){const a=d1(l=>l.session?.socials??[]).slice(0,4);return a.length?r.jsx("div",{className:`grid grid-cols-2 grid-rows-2 gap-0.5 ${t}`,children:a.map(l=>r.jsx(n7,{id:l?.id||l?.key||l?.service||null},`${l?.id||l?.label||"social"}-${l?.url||""}`))}):null}function WQ(){return r.jsx(j1,{title:"Links!",fillHeight:!0,bodyClassName:"flex flex-1 min-h-0 flex-col gap-0.5 text-base",children:r.jsx(ma,{className:"flex-1 min-h-0"})})}function ac(...t){return t.filter(Boolean).join(" ")}function tX(t){const a=t?.batteryState?.percentDisplay;return a==null?"--":`${a}%`}function eX(t){return t?.batteryState?t.batteryState.urgentActive?"text-red-400":t.batteryState.warnActive?"text-amber-300":"text-emerald-300":"text-slate-400"}function cX(t){switch(t){case"admin":case"lockdown":case"lockdown-admin":return"text-amber-300";case"spectator":return"text-slate-400";default:return"text-sky-300"}}function aX(t,a){if(!t)return"";const l=t.nickname||t.socketId?.slice(0,6)||"unknown";return t.socketId&&t.socketId===a?`${l} (you)`:l}function o7({title:t="Rovers"}){const a=d1(N=>N.session?.role||null),l=d1(N=>N.session?.roster??[]),s=d1(N=>N.session?.turnQueues??{}),u=d1(N=>N.session?.users??[]),f=d1(N=>N.session?.socketId||null),p=d1(N=>String(N.session?.assignment?.roverId||"").trim()),v=d1(N=>{const E=String(N.session?.assignment?.roverId||"").trim();return E?(N.session?.roster||[]).find(O=>String(O?.id)===E)?.name||E:""}),{requestControl:g,rebootOwnRover:x}=G2(),[z,b]=d.useState({}),[y,H]=d.useState(!1),S=d.useMemo(()=>a&&a!=="spectator",[a]),C=d.useMemo(()=>a==="admin"||a==="lockdown"||a==="lockdown-admin",[a]),w=d.useMemo(()=>Object.values(s||{}).some(N=>N?.deadline||N?.idleDeadline),[s]),A=U8(1e3,w),V=d.useMemo(()=>{const N=new Set(l.map(G=>String(G.id))),E=Object.keys(s||{}).filter(G=>!N.has(String(G))).map(G=>({id:G,name:G,locked:!1,batteryState:null}));return[...l,...E]},[l,s]);async function L(N){if(N){b(E=>({...E,[N]:!0})),u1("rover_queue_join",{roverId:N,alreadyAssigned:p===String(N)});try{await g(N),u1("rover_queue_join_result",{roverId:N,status:"accepted"})}catch(E){u1("rover_queue_join_result",{roverId:N,status:"failed",reason:E?.message||"unknown"}),alert(E.message)}finally{b(E=>({...E,[N]:!1}))}}}const R=N=>u.find(E=>E.socketId===N)||{socketId:N,nickname:null,role:null};async function q(){if(!(y||!window.confirm(`Reboot your rover "${v}" now?`))){H(!0),u1("rover_reboot_click",{roverId:p,scope:"own_rover"});try{await x(),u1("rover_reboot_result",{roverId:p,scope:"own_rover",status:"accepted"}),alert("Reboot command sent.")}catch(E){u1("rover_reboot_result",{roverId:p,scope:"own_rover",status:"failed",reason:E?.message||"unknown"}),alert(E.message)}finally{H(!1)}}}const j=a!=="spectator"&&p?r.jsx("button",{type:"button",onClick:q,disabled:y,className:"button-dark bg-amber-700/80 text-amber-50 hover:bg-amber-600 disabled:opacity-40",title:"Reboot your assigned rover",children:y?"Rebooting...":"Reboot My Rover"}):null;return r.jsx(j1,{title:t,actions:j,bodyClassName:"space-y-0.5 text-sm",children:V.length===0?r.jsx("p",{className:"text-sm text-slate-500",children:"No rovers registered."}):r.jsx("ul",{className:"space-y-0.5 text-sm",children:V.map(N=>{const E=String(N.id),G=s?.[E]||null,O=G?.queue||[],T=G?.idleDeadline||G?.deadline||null,U=T&&T>A?Math.ceil((T-A)/1e3):T?0:null,s1=G?.current||null,n1=s1?O.findIndex(v1=>v1===s1):-1,Q=O.length>1?n1>=0?O[(n1+1)%O.length]:O[0]:null,k=!!(f&&s1&&s1===f),$=!!(f&&Q&&Q===f),t1=U!=null&&(k||$),f1=!!(N?.private?.enabled&&N?.private?.open),h1=!!(N?.private?.enabled&&!N?.private?.open),F=!!N.locked,D=F&&!C&&!h1,W=N.lockReason?`locked: ${N.lockReason}`:"locked",r1=z[E]?"...":F&&!h1?W:"request",m1=S&&!D&&!z[E];return r.jsxs("li",{className:ac("surface flex flex-wrap items-start justify-between gap-0.5",m1&&"cursor-pointer",F?"bg-red-900/40":f1?"bg-amber-700/35 border border-amber-200/30":null),onClick:()=>{m1&&L(N.id)},children:[r.jsxs("div",{className:"flex min-w-0 flex-1 flex-col gap-0.5",children:[r.jsxs("div",{className:"flex items-center justify-between gap-0.5",children:[r.jsxs("div",{className:"flex min-w-0 items-center gap-0.5",children:[r.jsxs("p",{className:"min-w-0 flex items-center gap-0.5 whitespace-nowrap text-slate-200",children:[r.jsx(V4,{rover:N,fallback:E}),N.description?r.jsx("span",{className:"min-w-0 flex-1 truncate text-[0.7rem] text-slate-400",children:N.description}):null]}),t1?r.jsx("span",{className:"rounded bg-slate-800 px-1 text-[0.7rem] text-slate-200",children:k?`${U}s left`:`Your turn in ${U}s`}):null]}),r.jsx("span",{className:ac("text-[0.75rem] font-semibold",eX(N)),children:tX(N)})]}),O.length===0?r.jsx("p",{className:"text-[0.7rem] text-slate-500",children:"No queue."}):r.jsx("div",{className:"flex flex-wrap items-center gap-0.5",children:O.map((v1,A1)=>{const V1=R(v1),L1=v1===s1,$1=!!(Q&&v1===Q&&!L1),K1=L1?"bg-sky-600 text-white ring-2 ring-amber-300":$1?"bg-emerald-700/60 text-emerald-100 ring-1 ring-emerald-300/70":"bg-slate-800 text-slate-200";return r.jsxs("span",{className:`flex items-center gap-0.5 rounded px-1 text-[0.7rem] ${K1}`,children:[r.jsx("span",{className:`${cX(V1.role)} font-semibold`,children:aX(V1,f)}),L1&&r.jsx("span",{className:"text-[0.65rem] text-slate-200",children:"now"}),$1&&r.jsx("span",{className:"text-[0.65rem] text-emerald-100",children:"next"})]},`${E}-${v1}-${A1}`)})})]}),S?r.jsx("button",{type:"button",onClick:v1=>{v1.stopPropagation(),L(N.id)},disabled:z[E]||D,className:ac("button-dark disabled:opacity-40",F&&"bg-red-600/70 text-white hover:bg-red-600"),children:r1}):null]},N.id)})})})}function nX(t){switch(t){case"admin":case"lockdown":case"lockdown-admin":return"text-amber-300";case"spectator":return"text-slate-400";default:return"text-sky-300"}}function lX(t,a){if(!t)return"";const l=t.nickname||t.socketId?.slice(0,6)||"unknown";return t.socketId&&t.socketId===a?`${l} (you)`:l}function Yt({hideNicknameForm:t=!1,hideHeader:a=!1,className:l="",fillHeight:s=!1,compact:u=!1}){const f=d1(x=>x.session?.users??[]),p=d1(x=>x.session?.socketId||null),v=d.useMemo(()=>[...f].sort((x,z)=>x.socketId===p?-1:z.socketId===p?1:(x.nickname||"").localeCompare(z.nickname||"")),[p,f]),g=s?"flex-1 min-h-0 overflow-y-auto":u?"h-28 overflow-y-auto":"h-48 overflow-y-auto";return r.jsxs(j1,{title:a?"":"Users",hideHeader:a,fillHeight:s,className:l,bodyClassName:"space-y-0.5 text-base",children:[!t&&r.jsx("div",{className:"space-y-0.5",children:r.jsxs("div",{className:"grid gap-0.5 md:grid-cols-[minmax(0,1.4fr)_minmax(0,1fr)]",children:[r.jsx("div",{className:"min-w-0",children:r.jsx("div",{className:"flex w-full items-center px-0 py-0",children:r.jsx(s7,{compact:u})})}),r.jsx(ma,{})]})}),r.jsx("div",{className:`space-y-0.5 ${s?"flex flex-1 min-h-0 flex-col":""}`,children:r.jsx("div",{className:`flex flex-wrap content-start items-start gap-0.5 px-0 pb-0 ${g} ${u?"text-[0.8rem]":""}`,children:v.length===0?r.jsx("p",{className:"text-sm text-slate-500",children:"Waiting for users…"}):v.map(x=>r.jsx("span",{className:`rounded px-1 py-0.25 text-[0.7rem] ${nX(x.role)}`,children:lX(x,p)},x.socketId))})})]})}function xt(t){return typeof t!="number"||Number.isNaN(t)?"—":`${t>0?"+":""}${t.toFixed(1)}°`}function Ts({label:t}){return t?r.jsx("span",{className:"rounded bg-slate-800 px-1 py-0.5 text-[0.6rem] font-semibold text-slate-200",children:t}):null}function rX({value:t,min:a,max:l,step:s=.5,label:u="Camera Tilt",orientation:f="horizontal",onChange:p,onCommit:v,throttleMs:g=0,disabled:x=!1,keyDownLabel:z,keyUpLabel:b,className:y="",labelRowClass:H="",labelClass:S="",valueClass:C="",sliderClass:w="",endpointClass:A="",endpointLabelClass:V="",accentClass:L="",showValue:R=!0,showEndpoints:q}){const j=f==="vertical",E=typeof q=="boolean"?q:!j,[G,O]=d.useState(t),T=d.useRef(!1),U=d.useRef(null);d.useEffect(()=>{T.current||O(t)},[t]),d.useEffect(()=>()=>{U.current&&clearTimeout(U.current)},[]);const s1=t1=>{if(p){if(g>0){U.current&&clearTimeout(U.current),U.current=setTimeout(()=>{p(t1)},g);return}p(t1)}},n1=t1=>{const f1=Number.parseFloat(t1.target.value);Number.isNaN(f1)||(T.current=!0,O(f1),s1(f1))},Q=()=>{T.current=!1,U.current&&(clearTimeout(U.current),U.current=null),v?v(G):g>0&&p?.(G)};if(typeof a!="number"||typeof l!="number")return null;const k=[j?"h-28 w-5":"w-full",L,w].filter(Boolean).join(" "),$=r.jsx("input",{type:"range",orient:j?"vertical":void 0,min:a,max:l,step:s,value:Number.isFinite(G)?G:a,onChange:n1,onMouseUp:Q,onTouchEnd:Q,onPointerUp:Q,disabled:x,className:k,style:j?{writingMode:"bt-lr",WebkitAppearance:"slider-vertical"}:void 0});return j?r.jsxs("div",{className:`flex h-full flex-col items-center gap-0.5 ${y}`.trim(),children:[R?r.jsx("div",{className:`flex flex-col items-center ${H}`.trim(),children:r.jsx("span",{className:C,children:xt(t)})}):null,r.jsxs("div",{className:"flex min-h-0 flex-1 items-center gap-0.5",children:[r.jsx("span",{className:S,children:u}),$]})]}):r.jsxs("div",{className:`space-y-0.5 ${x?"opacity-50":""} ${y}`.trim(),children:[r.jsxs("div",{className:`flex items-center justify-between ${H}`.trim(),children:[r.jsx("span",{className:S,children:u}),R?r.jsx("span",{className:`rounded bg-slate-800 px-1 py-0.5 text-[0.7rem] font-semibold ${C}`.trim(),children:xt(t)}):null]}),r.jsxs("div",{children:[$,E?r.jsxs("div",{className:`mt-0 flex items-center justify-between ${A}`.trim(),children:[r.jsxs("span",{className:`flex items-center gap-0.5 ${V}`.trim(),children:[z?r.jsx(Ts,{label:z}):null,xt(a)]}),r.jsxs("span",{className:`flex items-center gap-0.5 ${V}`.trim(),children:[xt(l),b?r.jsx(Ts,{label:b}):null]})]}):null]})]})}const iX=/^cu_[a-f0-9]{32}$/,M0="field-input w-full max-w-sm text-left focus:ring-emerald-500",I8="mx-auto w-full max-w-xl flex justify-center",g0="mx-auto flex w-full max-w-md flex-col items-center space-y-0.5 text-center";function sX(t){const a=String(t||"").trim();return a?a.length<=10?`${a.slice(0,2)}***${a.slice(-2)}`:`${a.slice(0,6)}...${a.slice(-6)}`:""}const qs=8*1024*1024,f6=16e3,oX={iceServers:[{urls:"stun:stun.l.google.com:19302"}],bundlePolicy:"max-bundle",rtcpMuxPolicy:"require"};function _s(t){let a="";for(let s=0;s{if(!t||t.iceGatheringState==="complete"){l();return}const s=setTimeout(()=>{t.removeEventListener("icegatheringstatechange",u),l()},a);function u(){t.iceGatheringState==="complete"&&(clearTimeout(s),t.removeEventListener("icegatheringstatechange",u),l())}t.addEventListener("icegatheringstatechange",u)})}function Ds(t){if(!t)return!1;const a=t.connectionState,l=t.iceConnectionState;return a==="connected"||l==="connected"||l==="completed"}function fX(t,a=1e4){return new Promise((l,s)=>{if(!t){s(new Error("Peer connection missing"));return}if(Ds(t)){l();return}const u=setTimeout(()=>{p(),s(new Error("Peer connection timeout"))},a),f=()=>{Ds(t)?(p(),l()):(t.connectionState==="failed"||t.connectionState==="closed"||t.iceConnectionState==="failed")&&(p(),s(new Error(`Peer connection ${t.connectionState||t.iceConnectionState}`)))};function p(){clearTimeout(u),t.removeEventListener("connectionstatechange",f),t.removeEventListener("iceconnectionstatechange",f)}t.addEventListener("connectionstatechange",f),t.addEventListener("iceconnectionstatechange",f)})}async function mX(t){if(!t?.getParameters||!t?.setParameters)return;const a=t.getParameters()||{},l=a.encodings&&a.encodings[0]||{};a.encodings=[{...l,maxBitrate:64e3,dtx:"disabled"}];try{await t.setParameters(a)}catch{}}function vX(t,a=6e3){return new Promise((l,s)=>{if(!t){s(new Error("Peer connection missing"));return}const u=Date.now();let f=-1;const p=setInterval(async()=>{if(Date.now()-u>a){clearInterval(p),s(new Error("WHIP connected but no outbound audio flow"));return}try{const v=t.getSenders().filter(g=>g.track?.kind==="audio");for(const g of v){const x=await g.getStats();for(const z of x.values()){if(z.type!=="outbound-rtp"||z.kind!=="audio")continue;const b=Number(z.bytesSent||0),y=Number(z.packetsSent||0);if(f<0)f=b;else if(b>f+200||y>5){clearInterval(p),l();return}}}}catch{}},250)})}function pX(t){const a=t.reduce((u,f)=>u+f.length,0),l=new Float32Array(a);let s=0;for(const u of t)l.set(u,s),s+=u.length;return l}function gX(t){const a=new Int16Array(t.length);for(let l=0;l{for(let z=0;zz1.state.keymap),g=k1(z1=>!!z1.state.mic?.pttActive),{value:x,save:z}=F1("vipAudio",{openMicEnabled:!1,pttMode:"live"}),b=String(t||"").trim(),[y,H]=d.useState(null),[S,C]=d.useState(!1),w=!!x?.openMicEnabled,V=(x?.pttMode==="clip"?"clip":"live")==="clip",[L,R]=d.useState("idle"),[q,j]=d.useState("idle"),[N,E]=d.useState(""),G=d.useRef(null),O=d.useRef(null),T=d.useRef(null),U=d.useRef(!1),s1=d.useRef(""),n1=d.useRef(null),Q=d.useRef(null),k=d.useRef(null),$=d.useRef(null),t1=d.useRef(null),f1=d.useRef([]),h1=d.useRef(!1),F=d.useRef(f6),D=d.useMemo(()=>b&&a?.[b]||null,[a,b]),W=!!(D&&D.state!=="offline"&&!D.error),r1=D?.source==="upload"&&D?.state==="playing",m1=D?.source==="mic-whip"&&(D?.state==="starting"||D?.state==="playing"),v1=!!(!V&&O.current&&(w||g)),A1=!V&&(L==="live"||L==="starting"),V1=V&&q==="recording",L1=V&&q==="sending",$1=_2(v?.micPtt?.[0])||"M",K1=d.useCallback(z1=>{const b1=z1==="clip"?"clip":"live";z(D1=>({...D1||{},pttMode:b1})),u1("vip_ptt_mode_change",{mode:b1,roverId:b})},[b,z]),T1=async()=>{if(!b){E("Take control of your rover first.");return}if(!y){E("Select an audio file first.");return}if(y.size>qs){E(`File too large (max ${qs} bytes).`);return}C(!0),E(""),u1("vip_upload_play",{roverId:b,size:y.size,mime:y.type||""});try{const z1=await y.arrayBuffer(),b1=_s(new Uint8Array(z1));await l?.({roverId:b,name:y.name,mime:y.type||"",dataBase64:b1}),E("Upload playback started."),u1("vip_upload_play_result",{roverId:b,status:"accepted"})}catch(z1){u1("vip_upload_play_result",{roverId:b,status:"failed",reason:z1?.message||"unknown"}),E(z1?.message||"Failed to play upload.")}finally{C(!1)}},x1=async()=>{if(!b){E("Take control of your rover first.");return}C(!0),E(""),u1("vip_upload_stop",{roverId:b});try{await s?.(b),E("Upload playback stopped."),u1("vip_upload_stop_result",{roverId:b,status:"accepted"})}catch(z1){u1("vip_upload_stop_result",{roverId:b,status:"failed",reason:z1?.message||"unknown"}),E(z1?.message||"Failed to stop upload.")}finally{C(!1)}},X=d.useCallback(async z1=>{const b1=String(z1||s1.current||"").trim();if(U.current=!1,R("idle"),T.current){try{T.current.getSenders().forEach(D1=>D1.track?.stop())}catch{}try{T.current.close()}catch{}}if(T.current=null,G.current)try{G.current.getTracks().forEach(D1=>D1.stop())}catch{}if(G.current=null,O.current=null,b1)try{await p?.(b1)}catch{}s1.current=""},[p]),g1=d.useCallback(async z1=>{const b1=await u?.(z1),D1=String(b1?.whipUrl||"").trim(),S2=String(b1?.token||"").trim();if(!D1||!S2)throw new Error("WHIP endpoint unavailable");const P1=await navigator.mediaDevices.getUserMedia({audio:{channelCount:1,sampleRate:f6,echoCancellation:!1,noiseSuppression:!1,autoGainControl:!1}});G.current=P1;const p2=P1.getAudioTracks()?.[0];if(O.current=p2||null,p2&&(p2.enabled=!!(w||g)),p2?.applyConstraints)try{await p2.applyConstraints({channelCount:1,sampleRate:f6,echoCancellation:!1,noiseSuppression:!1,autoGainControl:!1})}catch{}const W1=new RTCPeerConnection(oX);T.current=W1,W1.onconnectionstatechange=()=>{if(!U.current)return;const c1=W1.connectionState;if(c1==="connected"){R("live");return}(c1==="failed"||c1==="disconnected"||c1==="closed")&&(R("error"),E(`WHIP transport ${c1}.`))},P1.getAudioTracks().forEach(c1=>{const y1=W1.addTrack(c1,P1);mX(y1)});const t2=await W1.createOffer({offerToReceiveAudio:!1,offerToReceiveVideo:!1});await W1.setLocalDescription(t2),await dX(W1,1800);const o1=await fetch(D1,{method:"POST",headers:{"Content-Type":"application/sdp",...hX(S2)},body:W1.localDescription?.sdp||t2.sdp});if(!o1.ok)throw new Error(`WHIP request failed: ${o1.status}`);const P=await o1.text();await W1.setRemoteDescription({type:"answer",sdp:P}),await fX(W1,1e4),await vX(W1,6e3),await f?.(z1)},[w,g,f,u]),M1=d.useCallback(async()=>{if(h1.current=!1,$.current){try{$.current.disconnect()}catch{}$.current.onaudioprocess=null}if(k.current)try{k.current.disconnect()}catch{}if(t1.current)try{t1.current.disconnect()}catch{}if(n1.current)try{n1.current.getTracks().forEach(z1=>z1.stop())}catch{}if(Q.current)try{await Q.current.close()}catch{}f1.current=[],$.current=null,k.current=null,t1.current=null,n1.current=null,Q.current=null,F.current=f6},[]),p1=d.useCallback(async()=>{if(n1.current&&Q.current&&$.current)return;j(p2=>p2==="recording"?p2:"arming");const z1=await navigator.mediaDevices.getUserMedia({audio:{channelCount:1,sampleRate:f6,echoCancellation:!1,noiseSuppression:!1,autoGainControl:!1}}),b1=new AudioContext({latencyHint:"interactive"}),D1=b1.createMediaStreamSource(z1),S2=b1.createScriptProcessor(1024,1,1),P1=b1.createGain();P1.gain.value=0,S2.onaudioprocess=p2=>{if(!h1.current)return;const W1=p2.inputBuffer.getChannelData(0);f1.current.push(new Float32Array(W1))},D1.connect(S2),S2.connect(P1),P1.connect(b1.destination),n1.current=z1,Q.current=b1,k.current=D1,$.current=S2,t1.current=P1,F.current=b1.sampleRate||f6},[]),R1=d.useCallback(async({send:z1})=>{const b1=h1.current;if(h1.current=!1,!b1){z1||j("idle");return}const D1=f1.current;if(f1.current=[],!z1){j("idle"),u1("vip_clip_record_cancel",{roverId:b});return}if(!b){j("idle"),u1("vip_clip_send",{roverId:b,status:"skipped_no_rover"});return}if(!D1.length){j("idle"),u1("vip_clip_send",{roverId:b,status:"skipped_empty"});return}j("sending"),u1("vip_clip_send",{roverId:b,status:"started"});try{const S2=pX(D1),P1=xX(S2,F.current||f6),p2=_s(P1);await l?.({roverId:b,name:`ptt-${Date.now()}.wav`,mime:"audio/wav",dataBase64:p2}),j("idle"),u1("vip_clip_send",{roverId:b,status:"accepted"})}catch(S2){j("error"),u1("vip_clip_send",{roverId:b,status:"failed",reason:S2?.message||"unknown"}),E(S2?.message||"Failed to send PTT clip.")}},[l,b]),l2=d.useCallback(async()=>{if(!b){E("Take control of your rover first.");return}await p1(),f1.current=[],h1.current=!0,j("recording"),u1("vip_clip_record_start",{roverId:b})},[p1,b]);return d.useEffect(()=>{let z1=!1;async function b1(){if(V){await X(s1.current||b);return}if(!b){await X(s1.current);return}if(!(U.current&&s1.current===b)&&!(!w&&!g))try{R("starting"),E(""),U.current=!0,s1.current=b,await g1(b),z1||(R("live"),u1("vip_live_mic_start",{roverId:b}))}catch(D1){z1||(R("error"),E(D1?.message||"Failed to start mic forwarding."),v3("vip_live_mic_error",{roverId:b,reason:D1?.message||"unknown"},{key:`${b}:${D1?.message||"unknown"}`,throttleMs:60*1e3})),await X(b)}}return b1(),()=>{z1=!0}},[V,w,g,b,g1,X]),d.useEffect(()=>{const z1=O.current;z1&&(z1.enabled=!!(!V&&(w||g)))},[V,w,g]),d.useEffect(()=>{let z1=!1;async function b1(){if(!V||!b){h1.current&&await R1({send:!1}),j("idle");return}try{await p1(),!z1&&!h1.current&&j("idle")}catch(D1){z1||(j("error"),E(D1?.message||"Microphone access failed for clip mode."))}}return b1(),()=>{z1=!0}},[V,p1,R1,b]),d.useEffect(()=>{let z1=!1;async function b1(){if(V){if(!b){h1.current&&await R1({send:!1});return}if(g){if(!h1.current)try{E(""),await l2()}catch(D1){z1||(j("error"),E(D1?.message||"Failed to start clip recording."))}}else h1.current&&await R1({send:!0})}}return b1(),()=>{z1=!0}},[V,R1,g,b,l2]),d.useEffect(()=>()=>{X(s1.current||b),M1()},[b,X,M1]),r.jsx(j1,{title:"Audio Controls",children:r.jsxs("div",{className:"grid gap-1",children:[r.jsx("section",{className:"surface",children:r.jsxs("div",{className:"flex items-center justify-center gap-0.5 py-0.25 text-xs text-slate-300",children:[r.jsx("span",{children:"Push-to-Talk Key"}),r.jsx(Pt,{label:$1})]})}),r.jsxs("div",{className:"grid gap-0.5 grid-cols-1 lg:grid-cols-2",children:[r.jsx("section",{className:"surface h-full",children:r.jsxs("div",{className:"grid h-full gap-0.5 grid-rows-[auto_auto_1fr]",children:[r.jsx("p",{className:"text-sm text-slate-200 text-center",children:"PTT Mode"}),r.jsx("p",{className:"text-xs text-slate-400 text-center",children:"Choose how holding your PTT key behaves: live mic stream, or record-and-send clip. If the live stream doesn't work, switch to clip mode."}),r.jsxs("div",{className:"grid grid-cols-2 gap-0.5",children:[r.jsx("button",{type:"button",className:`button-dark w-full text-sm ${V?"":"bg-emerald-500 text-white hover:bg-emerald-500"}`,onClick:()=>K1("live"),children:"Live Mic (WHIP)"}),r.jsx("button",{type:"button",className:`button-dark w-full text-sm ${V?"bg-emerald-500 text-white hover:bg-emerald-500":""}`,onClick:()=>K1("clip"),children:"Record Clip"})]})]})}),r.jsx("section",{className:"surface h-full",children:r.jsxs("div",{className:"grid h-full gap-0.5 grid-rows-[auto_1fr]",children:[r.jsx("p",{className:"text-sm text-slate-200 text-center",children:"PTT Clip Status"}),r.jsxs("div",{className:"grid gap-0.5 content-start",children:[r.jsx(H4,{label:"Mode",active:V,detail:V?"record clip":"live mic"}),r.jsx(H4,{label:"PTT hold",active:g,detail:g?"held":"released"}),r.jsx(H4,{label:"Recording",active:V1,detail:V1?"capturing":"idle"}),r.jsx(H4,{label:"Playback",active:V&&r1,detail:V&&r1?"playing":"idle"})]})]})})]}),r.jsxs("div",{className:"grid gap-0.5 grid-cols-1 lg:grid-cols-2",children:[r.jsx("section",{className:"surface h-full",children:r.jsxs("div",{className:"grid h-full gap-0.5 grid-rows-[auto_auto_1fr_auto]",children:[r.jsx("p",{className:"text-sm text-slate-200 text-center",children:"Audio Upload"}),r.jsxs("label",{className:"mx-auto grid w-full max-w-sm gap-0.5 text-xs text-slate-300 text-center",children:[r.jsx("span",{children:"Audio file (mp3 / wav / ogg)"}),r.jsx("input",{className:`${M0} text-center`,type:"file",accept:".mp3,.wav,.ogg,audio/mpeg,audio/wav,audio/ogg",disabled:S||!b,onChange:z1=>H(z1.target.files?.[0]||null)})]}),r.jsx("div",{className:"mx-auto w-full max-w-sm text-center",children:y?r.jsxs("div",{className:"surface-muted text-xs text-slate-300",children:[y.name," (",y.size," bytes)"]}):r.jsx("div",{className:"surface-muted text-xs text-slate-500",children:"No file selected"})}),r.jsxs("div",{className:"flex justify-center gap-0.5",children:[r.jsx("button",{type:"button",className:"button-dark text-sm",disabled:S||!b,onClick:T1,children:S?"Working...":"Play Upload"}),r.jsx("button",{type:"button",className:"button-dark text-sm",disabled:S||!b,onClick:x1,children:"Stop"})]})]})}),r.jsx("section",{className:"surface h-full",children:r.jsxs("div",{className:"grid h-full gap-0.5 grid-rows-[auto_auto_1fr]",children:[r.jsx("p",{className:"text-sm text-slate-200 text-center",children:"Live Microphone"}),r.jsxs("label",{className:"surface-muted mx-auto flex w-full max-w-sm items-center justify-center gap-0.5 px-0.5 py-0.5 text-xs text-slate-300",children:[r.jsx("input",{type:"checkbox",checked:w,disabled:!b||V,onChange:z1=>{const b1=!!z1.target.checked;z(D1=>({...D1||{},openMicEnabled:b1})),u1("vip_open_mic_change",{roverId:b,enabled:b1})}}),r.jsx("span",{children:V?"Open mic (live mode only)":"Open mic"})]}),r.jsxs("div",{className:"grid gap-0.5 content-start",children:[r.jsx(H4,{label:"WHIP link",active:A1,detail:L}),r.jsx(H4,{label:"Mic hot",active:v1,detail:v1?"transmitting":"muted"}),r.jsxs("div",{className:"surface-muted text-center text-xs text-slate-400",children:["Hold ",r.jsx(Pt,{label:$1})," to talk"]})]})]})})]}),r.jsx("section",{className:"surface",children:r.jsxs("div",{className:"space-y-0.5",children:[r.jsx("p",{className:"text-sm text-slate-200 text-center",children:"Audio Status"}),r.jsxs("div",{className:"grid gap-0.5 grid-cols-1 sm:grid-cols-2 lg:grid-cols-6",children:[r.jsx(H4,{label:"Forward pipe",active:W,detail:W?"connected":"offline"}),r.jsx(H4,{label:"Upload playback",active:r1,detail:r1?"playing":"idle"}),r.jsx(H4,{label:"Mic relay",active:m1,detail:m1?"active":"idle"}),r.jsx(H4,{label:"WHIP transport",active:A1,detail:L}),r.jsx(H4,{label:"Clip recording",active:V1,detail:V1?"recording":"idle"}),r.jsx(H4,{label:"Clip sending",active:L1,detail:L1?"sending":"idle"})]}),N?r.jsx("div",{className:"text-xs text-slate-400 text-center",children:N}):null]})})]})})}function bX({pendingRequestId:t,currentStoredKey:a,nickname:l,requestVerification:s,applyIdentityKey:u,onMessage:f,fullWidth:p=!1}){const[v,g]=d.useState(0),[x,z]=d.useState(""),[b,y]=d.useState(!1),[H,S]=d.useState(!1),C=()=>{g(1),z(a),y(!1),f?.(""),u1("vip_verify_flow_start",{hasNickname:!!l})},w=()=>{g(0),y(!1)},A=async L=>{if(L.preventDefault(),!b){f?.("Please confirm your nickname agreement before sending.");return}if(v<3){f?.("Complete all request steps before sending.");return}S(!0),f?.(""),u1("vip_verify_attempt",{hasNickname:!!l,hasIdentityKey:!!x});try{const R=await u(x);await s?.(),z(R),g(0),y(!1),f?.("Verification request sent to lockdown admins."),u1("vip_verify_result",{status:"accepted"})}catch(R){u1("vip_verify_result",{status:"failed",reason:R?.message||"unknown"}),f?.(R.message||"Failed to submit request.")}finally{S(!1)}},V=p?"w-full":I8;return t?r.jsx(j1,{title:"Verification",className:V,bodyClassName:"text-sm text-slate-300",children:r.jsxs("div",{className:g0,children:["Verification request pending: ",t]})}):v===0?r.jsx(j1,{title:"Verification",className:V,children:r.jsx("div",{className:g0,children:r.jsx("button",{type:"button",className:"button-dark text-sm",onClick:C,disabled:H,children:"Request Verification"})})}):r.jsx(j1,{title:"Request verification",className:V,children:r.jsx("form",{onSubmit:A,children:r.jsxs("div",{className:g0,children:[r.jsxs("p",{className:"text-xs text-slate-500",children:["Step ",v," of 3"]}),v===1?r.jsxs("div",{className:"space-y-0.5",children:[r.jsx("p",{className:"text-xs text-slate-400",children:"Confirm your nickname, which is used as part of the verification process. You can edit it here before requesting."}),r.jsx("div",{className:"mx-auto w-full max-w-sm",children:r.jsx(s7,{compact:!0})}),r.jsxs("div",{className:"surface-muted mx-auto w-full max-w-sm text-xs text-slate-300 text-center",children:["Current nickname: ",r.jsx("span",{className:"font-semibold",children:l||"(not set)"})]}),r.jsxs("label",{className:"flex items-center justify-center gap-0.5 text-xs text-slate-300 text-center",children:[r.jsx("input",{type:"checkbox",className:"accent-emerald-500",checked:b,onChange:L=>y(L.target.checked)}),r.jsx("span",{children:"I understand this nickname is tied to my verification."})]}),r.jsxs("div",{className:"flex justify-center gap-0.5",children:[r.jsx("button",{type:"button",className:"button-dark text-sm",disabled:!l||!b,onClick:()=>g(2),children:"Continue"}),r.jsx("button",{type:"button",className:"button-dark text-sm",onClick:w,children:"Cancel"})]})]}):null,v===2?r.jsxs("div",{className:"space-y-0.5",children:[r.jsx("p",{className:"text-xs text-slate-400",children:"Save your identity key in a safe place. You can use it to restore your identity in another browser."}),r.jsx("input",{className:M0,type:"password",name:"identity_key_request",autoComplete:"current-password",maxLength:35,value:x,onChange:L=>z(L.target.value.toLowerCase()),placeholder:"Identity key for this request"}),r.jsxs("div",{className:"flex justify-center gap-0.5",children:[r.jsx("button",{type:"button",className:"button-dark text-sm",disabled:!x,onClick:()=>navigator.clipboard?.writeText(x),children:"Copy Key"}),r.jsx("button",{type:"button",className:"button-dark text-sm",disabled:!x,onClick:()=>g(3),children:"Continue"}),r.jsx("button",{type:"button",className:"button-dark text-sm",onClick:()=>g(1),children:"Back"})]})]}):null,v===3?r.jsxs("div",{className:"space-y-0.5",children:[r.jsx("p",{className:"text-xs text-slate-400",children:"Final step: confirm and send your verification request."}),r.jsx("input",{className:M0,type:"password",name:"identity_key_request_final",autoComplete:"current-password",maxLength:35,value:x,onChange:L=>z(L.target.value.toLowerCase()),placeholder:"Identity key for this request"}),r.jsxs("div",{className:"flex justify-center gap-0.5",children:[r.jsx("button",{type:"submit",className:"button-dark text-sm",disabled:H||!x,children:"Confirm Request"}),r.jsx("button",{type:"button",className:"button-dark text-sm",onClick:()=>g(2),children:"Back"})]})]}):null]})})})}function MX({currentStoredKey:t,applyIdentityKey:a,onMessage:l,fullWidth:s=!1}){const[u,f]=d.useState(0),[p,v]=d.useState(""),[g,x]=d.useState(!1),z=()=>{f(1),v(""),l?.("")},b=()=>{f(0),v("")},y=async S=>{if(S.preventDefault(),!(u<2)){x(!0),l?.("");try{await a(p),f(0),v(""),l?.("Identity key restored.")}catch(C){l?.(C.message||"Failed to restore key.")}finally{x(!1)}}},H=s?"w-full":I8;return r.jsx(j1,{title:"Identity key",className:H,children:r.jsxs("div",{className:g0,children:[r.jsxs("p",{className:"text-xs text-slate-500",children:["Current: ",sX(t)||"not set yet"]}),r.jsx("input",{className:M0,type:"password",name:"identity_key_current",autoComplete:"current-password",maxLength:35,value:t,readOnly:!0,placeholder:"Identity key"}),u===0?r.jsxs("div",{className:"flex justify-center gap-0.5",children:[r.jsx("button",{type:"button",className:"button-dark text-sm",disabled:!t,onClick:()=>navigator.clipboard?.writeText(t),children:"Copy Key"}),r.jsx("button",{type:"button",className:"button-dark text-sm",onClick:z,disabled:g,children:"Restore Key"})]}):null,u===1?r.jsxs("div",{className:"space-y-0.5",children:[r.jsx("p",{className:"text-xs text-slate-400",children:"Restoring your key should only be done when needed. Use this to move your identity to another browser."}),r.jsxs("div",{className:"flex justify-center gap-0.5",children:[r.jsx("button",{type:"button",className:"button-dark text-sm",onClick:()=>f(2),children:"Continue"}),r.jsx("button",{type:"button",className:"button-dark text-sm",onClick:b,children:"Cancel"})]})]}):null,u===2?r.jsxs("form",{className:"space-y-0.5",onSubmit:y,children:[r.jsx("input",{className:M0,type:"password",name:"identity_key_restore",autoComplete:"current-password",maxLength:35,value:p,onChange:S=>v(S.target.value.toLowerCase()),placeholder:"Paste key to restore"}),r.jsxs("div",{className:"flex justify-center gap-0.5",children:[r.jsx("button",{type:"submit",className:"button-dark text-sm",disabled:g||!p,children:"Confirm Restore"}),r.jsx("button",{type:"button",className:"button-dark text-sm",onClick:()=>f(1),children:"Back"})]})]}):null]})})}function yX({requestableRovers:t=[],pendingRequests:a=[],requestPrivateRoverAccess:l,onMessage:s,fullWidth:u=!1}){const[f,p]=d.useState({}),v=d.useMemo(()=>{const z=new Map;return(a||[]).forEach(b=>{b?.roverId&&z.set(String(b.roverId),b)}),z},[a]),g=u?"w-full":I8,x=async z=>{if(z){p(b=>({...b,[z]:!0})),s?.(""),u1("vip_private_rover_request",{roverId:z,status:"started"});try{const b=await l?.(z);u1("vip_private_rover_request",{roverId:z,status:b?.existing?"existing":"accepted"}),b?.existing?s?.("You already have a pending request for that rover."):s?.("Private rover access request sent to lockdown admins.")}catch(b){u1("vip_private_rover_request",{roverId:z,status:"failed",reason:b?.message||"unknown"}),s?.(b.message||"Failed to send request.")}finally{p(b=>({...b,[z]:!1}))}}};return r.jsx(j1,{title:"Private rover access requests",className:g,bodyClassName:"text-sm text-slate-300",children:r.jsx("div",{className:g0,children:t.length===0?r.jsx("p",{className:"text-xs text-slate-500",children:"No closed private rovers are available to request right now."}):r.jsx("div",{className:"w-full space-y-0.5",children:t.map(z=>{const b=String(z.id),y=!!f[b],H=v.get(b);return r.jsxs("div",{className:"surface-muted flex items-center justify-between gap-0.5 px-1 py-0.5",children:[r.jsxs("div",{className:"min-w-0 text-left",children:[r.jsx("p",{className:"truncate text-xs",children:r.jsx(V4,{rover:z,fallback:b,className:"max-w-full truncate align-middle"})}),r.jsx("p",{className:"truncate text-[0.7rem] text-slate-500",children:b})]}),H?r.jsx("span",{className:"rounded bg-amber-700/30 px-1 py-0.5 text-[0.7rem] text-amber-200",children:"Pending"}):r.jsx("button",{type:"button",onClick:()=>x(b),disabled:y,className:"button-dark text-xs disabled:opacity-50",children:y?"Sending...":"Request"})]},b)})})})})}function Tt(t){return String(t||"").trim()}function wX(t){const a=Tt(t);return a?a.includes("DOCKINGRUNNING")?"Returning":a.includes("PAUSED")?"Paused":a.includes("HOUSECLEANINGRUNNING")?"Cleaning":a.includes("SPOTCLEANINGRUNNING")?"Spot cleaning":a.includes("STATE_START")?"Starting":a.includes("STATE_IDLE")||a.includes("STATE_STANDBY")?"Idle":a:"--"}function Ju(t){return t==="good"?"bg-emerald-600 text-white":t==="warn"?"bg-amber-500 text-slate-900":t==="danger"?"bg-rose-600 text-white":"bg-slate-700 text-slate-100"}function zt({label:t,value:a,tone:l="muted",valueClass:s="",hideLabel:u=!1}){return r.jsxs("div",{className:`rounded-md px-1 py-0.75 text-center ${Ju(l)}`,children:[u?null:r.jsx("div",{className:"text-[0.72rem] opacity-90",children:t}),r.jsx("div",{className:`text-sm font-semibold ${s}`,title:String(a||""),children:a})]})}function CX({neato:t,onStart:a,onSendHome:l,onLocate:s,onClearErrors:u,onPowerCycle:f,fullWidth:p=!1}){const[v,g]=d.useState(""),x=p?"w-full":"w-full max-w-xl",z=!!t?.configured,b=!!(t?.enabled&&t?.connected),y=!!t?.telemetry?.extPowerPresent,H=!!t?.telemetry?.chargingActive,S=wX(t?.telemetry?.uiState),C=Tt(t?.telemetry?.robotState)||"--",w=t?.telemetry?.batteryPercent,A=Number.isFinite(w)?`${w}%`:"--",V=t?.telemetry?.batteryVoltage,L=Number.isFinite(V)?`${V.toFixed(2)} V`:"--",R=Tt(t?.telemetry?.robotError)||"--",q=Tt(t?.telemetry?.robotAlert)||"--",j=t?.controls||{},N=!!j?.start?.available,E=!!j?.sendHome?.available,G=!!j?.locate?.available,O=!!j?.clearErrors?.available,T=!!j?.powerCycle?.available,U=z&&b&&N,s1=z&&b&&E,n1=z&&b&&G,Q=z&&b&&O,k=z&&b&&T,$=async(D,W)=>{if(W){g(D);try{await W()}catch{}finally{g("")}}},t1=z?b?"Online":"Offline":"Not configured",f1=z?b?"good":"danger":"warn",h1=w==null?"muted":w>=60?"good":w>=25?"warn":"danger",F=y?"Docked":S!=="--"?S:"Away from dock";return r.jsx(j1,{title:"Neato Controls",className:x,bodyClassName:"text-sm text-slate-200",actions:r.jsx("span",{className:`inline-flex w-auto rounded px-1 py-0.25 text-xs font-semibold ${Ju(f1)}`,children:t1}),children:r.jsxs("div",{className:"grid gap-0.5",children:[r.jsx("div",{className:"text-center",children:r.jsx("p",{className:"text-xs text-slate-400",children:"Control the autonomous Neato robovac. Be nice to him."})}),r.jsxs("div",{className:"grid grid-cols-1 lg:grid-cols-2 gap-0.5",children:[r.jsxs("div",{className:"surface-muted grid gap-0.5",children:[r.jsx("p",{className:"text-xs text-slate-300 text-center",children:"Controls"}),r.jsx("button",{type:"button",disabled:!U||!!v,onClick:()=>$("start",a),className:"rounded-md border border-sky-300 bg-emerald-600 px-1 py-1 text-base font-semibold text-white transition hover:border-sky-500 hover:bg-emerald-500 disabled:opacity-50",children:v==="start"?"Starting...":"Start cleaning"}),r.jsx("button",{type:"button",disabled:!s1||!!v,onClick:()=>$("sendHome",l),className:"rounded-md border border-sky-300 bg-sky-600 px-1 py-1 text-base font-semibold text-white transition hover:border-sky-500 hover:bg-sky-500 disabled:opacity-50",children:v==="sendHome"?"Sending...":"Send to dock"}),r.jsxs("div",{className:"grid grid-cols-3 gap-0.5",children:[r.jsx("button",{type:"button",disabled:!n1||!!v,onClick:()=>$("locate",s),className:"w-full rounded-md border border-sky-300 bg-fuchsia-600 px-1 py-0.5 text-xs font-semibold text-white transition hover:border-sky-500 hover:bg-fuchsia-500 disabled:opacity-50",children:v==="locate"?"Playing...":"Play sound"}),r.jsx("button",{type:"button",disabled:!Q||!!v,onClick:()=>$("clearErrors",u),className:"w-full rounded-md border border-sky-300 bg-amber-500 px-1 py-0.5 text-xs font-semibold text-slate-900 transition hover:border-sky-500 hover:bg-amber-400 disabled:opacity-50",children:v==="clearErrors"?"Clearing...":"Clear errors"}),r.jsx("button",{type:"button",disabled:!k||!!v,onClick:()=>$("powerCycle",f),className:"w-full rounded-md border border-rose-300 bg-rose-600 px-1 py-0.5 text-xs font-semibold text-white transition hover:border-rose-500 hover:bg-rose-500 disabled:opacity-50",children:v==="powerCycle"?"Cycling...":"Power cycle"})]}),r.jsxs("div",{className:"surface-muted grid gap-0.5 pt-0.25",children:[r.jsx("p",{className:"text-xs text-slate-300 text-center",children:"Power status"}),r.jsxs("div",{className:"grid grid-cols-2 gap-0.5",children:[r.jsx(zt,{label:"Battery",value:A,tone:h1}),r.jsx(zt,{label:"Voltage",value:L,tone:"muted"}),r.jsx(zt,{label:"Docked",value:y?"Docked":"Not docked",tone:y?"good":"muted",hideLabel:!0}),r.jsx(zt,{label:"Charging",value:H?"charging":"not charging",tone:H?"good":"muted",hideLabel:!0})]})]})]}),r.jsx("div",{className:"grid gap-0.5",children:r.jsxs("div",{className:"surface-muted grid gap-0.5",children:[r.jsx("p",{className:"text-xs text-slate-300 text-center",children:"Robot Status"}),r.jsxs("div",{className:"grid gap-0.5",children:[r.jsxs("div",{className:"rounded-md bg-slate-800 px-1 py-0.5",children:[r.jsx("div",{className:"text-[0.72rem] text-slate-300",children:"Robot state (raw)"}),r.jsx("div",{className:"font-mono text-sm text-slate-100 break-all",children:C})]}),r.jsxs("div",{className:"rounded-md bg-slate-800 px-1 py-0.5",children:[r.jsx("div",{className:"text-[0.72rem] text-slate-300",children:"Basic state"}),r.jsx("div",{className:"font-mono text-sm text-slate-100 break-all",children:F})]}),r.jsxs("div",{className:"rounded-md bg-slate-800 px-1 py-0.5",children:[r.jsx("div",{className:"text-[0.72rem] text-slate-300",children:"UI state"}),r.jsx("div",{className:"font-mono text-sm text-slate-100 break-all",children:S})]}),r.jsxs("div",{className:"rounded-md bg-slate-800 px-1 py-0.5",children:[r.jsx("div",{className:"text-[0.72rem] text-slate-300",children:"Robot error"}),r.jsx("div",{className:"font-mono text-sm text-slate-100 break-all",children:R})]}),r.jsxs("div",{className:"rounded-md bg-slate-800 px-1 py-0.5",children:[r.jsx("div",{className:"text-[0.72rem] text-slate-300",children:"Robot alert"}),r.jsx("div",{className:"font-mono text-sm text-slate-100 break-all",children:q})]})]})]})})]}),!z||!b||!N||!E||!G||!O||!T?r.jsx("p",{className:"text-xs text-slate-400 text-center",children:z?b?"Waiting for required Neato entities in Home Assistant.":"Home Assistant is offline.":"Set homeAssistant.neato.device in server config to enable Neato controls."}):null]})})}function HX(t){return t==="good"?"bg-emerald-600 text-white":t==="warn"?"bg-amber-500 text-slate-900":t==="danger"?"bg-rose-600 text-white":"bg-slate-700 text-slate-100"}function SX(t){return t==="up"?"Up":t==="down"?"Down":t==="stopped"?"Transitioning...":t==="conflict"?"Conflict":"--"}function AX({lift:t,onUp:a,onDown:l,fullWidth:s=!1}){const[u,f]=d.useState(""),[p,v]=d.useState(()=>Date.now()),g=s?"w-full":"w-full max-w-xl",x=!!t?.configured,z=!!(t?.enabled&&t?.connected),b=!!t?.busy,y=String(t?.target||"").toLowerCase(),H=String(t?.position||"").toLowerCase(),S=!!t?.availability?.upSwitch,C=!!t?.availability?.downSwitch,w=Number(t?.lastActionAt||0),A=Math.max(0,Number(t?.commandCooldownMs||0)),V=Math.max(0,w+A-p),L=!b&&V>0,R=b||L;d.useEffect(()=>{if(!R)return;const O=setInterval(()=>{v(Date.now())},100);return()=>clearInterval(O)},[R]),d.useEffect(()=>{v(Date.now())},[w,A,b]);const q=x?z?R?"Busy":"Ready":"Offline":"Not configured",j=x?z?R?"warn":"good":"danger":"warn",N=x&&z&&!R&&!u&&S&&C,E=d.useMemo(()=>Math.ceil(V/1e3),[V]),G=async(O,T)=>{if(T){f(O);try{await T()}catch{}finally{f("")}}};return r.jsxs(j1,{title:"Lift Controls",className:`relative ${g}`,bodyClassName:"text-sm text-slate-200",actions:r.jsx("span",{className:`inline-flex w-auto rounded px-1 py-0.25 text-xs font-semibold ${HX(j)}`,children:q}),children:[R?r.jsx("div",{className:"absolute inset-0 z-20 flex items-center justify-center rounded-md bg-slate-950/80 px-1.5 text-center",children:r.jsxs("div",{className:"space-y-0.25",children:[r.jsx("p",{className:"text-sm font-semibold text-slate-100",children:b?"Preparing to move":"Moving!"}),r.jsx("p",{className:"text-xs text-slate-300",children:"Controls are disabled while the lift is moving, otherwise its tiny brain would get confused."}),!b&&L?r.jsxs("p",{className:"text-xs text-slate-400",children:["About ",E,"s remaining."]}):null]})}):null,r.jsxs("div",{className:"grid gap-0.5",children:[r.jsx("div",{className:"text-center",children:r.jsx("p",{className:"text-xs text-slate-400",children:"Move the lift up and down. Please don't break anything..."})}),r.jsx("section",{className:"surface-muted px-0.5 py-0.5",children:r.jsxs("div",{className:"grid grid-cols-1 md:grid-cols-3 gap-0.5",children:[r.jsxs("div",{className:"rounded-md bg-slate-800 px-1 py-0.75 text-center",children:[r.jsx("div",{className:"text-xs text-slate-300",children:"Position"}),r.jsx("div",{className:"text-base font-semibold text-slate-100",children:SX(H)})]}),r.jsx("button",{type:"button",disabled:!N,onClick:()=>G("down",l),className:`button-dark w-full text-sm disabled:opacity-50 ${H==="down"||y==="down"?"bg-emerald-500 text-white hover:bg-emerald-500":""}`,children:u==="down"||y==="down"?"Lowering...":"Down"}),r.jsx("button",{type:"button",disabled:!N,onClick:()=>G("up",a),className:`button-dark w-full text-sm disabled:opacity-50 ${H==="up"||y==="up"?"bg-emerald-500 text-white hover:bg-emerald-500":""}`,children:u==="up"||y==="up"?"Raising...":"Up"})]})}),!x||!z||!S||!C?r.jsx("p",{className:"text-xs text-slate-400 text-center",children:x?z?"Waiting for required lift switch entities in Home Assistant.":"Home Assistant is offline.":"Set homeAssistant.lift.upSwitch and homeAssistant.lift.downSwitch in server config."}):null,t?.lastError?r.jsxs("p",{className:"text-xs text-rose-300 text-center",children:["Last error: ",t.lastError]}):null]})]})}function VX(t){const a=String(t||"").trim();if(!a)return"";try{const l=new URL(a),s=String(l.protocol||"").toLowerCase();return s!=="http:"&&s!=="https:"?"":l.toString()}catch{return""}}function LX({isVerified:t=!1,fullWidth:a=!1,onMessage:l}){const{value:s,save:u}=F1("profile",{nickname:"",profileImageUrl:""}),f=String(s?.profileImageUrl||"").trim(),[p,v]=d.useState(f),[g,x]=d.useState(!1);d.useEffect(()=>{v(f)},[f]);const z=d.useMemo(()=>VX(p),[p]),b=String(p||"").trim()!==f,y=!!(t&&b&&(z||!String(p||"").trim())),H=a?"w-full":I8,S=async C=>{if(C.preventDefault(),!t){l?.("Verify your account before setting a profile image URL.");return}x(!0),l?.("");try{const w=z||"";u(A=>({...A||{},profileImageUrl:w})),l?.(w?"Profile image URL saved.":"Profile image URL cleared.")}finally{x(!1)}};return r.jsx(j1,{title:"Chat profile image URL",className:H,bodyClassName:"text-sm text-slate-300",children:r.jsxs("form",{className:g0,onSubmit:S,children:[r.jsx("p",{className:"text-xs text-slate-500",children:"Verified users can set a custom avatar for chat and Discord bridge messages."}),r.jsx("input",{className:M0,type:"url",name:"vip_profile_image_url",placeholder:"https://example.com/avatar.png",value:p,onChange:C=>v(C.target.value),disabled:!t||g}),!z&&String(p||"").trim()?r.jsx("p",{className:"text-xs text-amber-300",children:"Enter a valid http/https image URL."}):null,r.jsxs("div",{className:"flex justify-center gap-0.5",children:[r.jsx("button",{type:"submit",className:"button-dark text-sm disabled:opacity-50",disabled:!y||g,children:g?"Saving...":"Save URL"}),r.jsx("button",{type:"button",className:"button-dark text-sm disabled:opacity-50",disabled:!t||g||!f,onClick:()=>v(""),children:"Clear"})]})]})})}function Wu({isActive:t=!0}){const a=d1(n1=>n1.session),{identifySession:l,requestVerification:s,requestPrivateRoverAccess:u,playUploadedAudio:f,stopUploadedAudio:p,startMicWhip:v,readyMicWhip:g,stopMicWhip:x,neatoStart:z,neatoSendHome:b,neatoLocate:y,neatoClearErrors:H,neatoPowerCycle:S,liftUp:C,liftDown:w}=G2(),{value:A,save:V}=F1("identity",{cookieUserId:""}),{value:L}=F1("profile",{nickname:""}),R=d.useMemo(()=>(A?.cookieUserId||"").trim(),[A?.cookieUserId]),q=(L?.nickname||"").trim(),j=!!a?.isVerified,N=a?.verification?.pendingRequestId||null,E=a?.privateRoverAccess?.requestableRovers||[],G=a?.privateRoverAccess?.pendingRequests||[],O=String(a?.assignment?.roverId||"").trim(),[T,U]=d.useState(""),s1=async n1=>{const Q=String(n1||"").trim().toLowerCase();if(!Q)throw new Error("Identity key required.");if(!iX.test(Q))throw new Error("Identity key must match format: cu_ + 32 lowercase hex chars.");return V(k=>({...k||{},cookieUserId:Q})),await l({cookieUserId:Q,nickname:q}),Q};return r.jsxs("section",{className:"space-y-2 text-base",children:[r.jsxs("div",{className:"grid gap-2 grid-cols-1 lg:grid-cols-[minmax(0,1.25fr)_minmax(0,0.9fr)]",children:[j?null:r.jsx("div",{className:"lg:col-span-2",children:r.jsx(bX,{pendingRequestId:N,currentStoredKey:R,nickname:q,requestVerification:s,applyIdentityKey:s1,onMessage:U,fullWidth:!0})}),r.jsx("div",{className:"lg:col-span-2",children:j?r.jsxs("div",{className:"space-y-2",children:[r.jsx(CX,{neato:a?.neato||null,onStart:z,onSendHome:b,onLocate:y,onClearErrors:H,onPowerCycle:S,fullWidth:!0}),r.jsx(AX,{lift:a?.lift||null,onUp:C,onDown:w,fullWidth:!0}),r.jsx(zX,{ownRoverId:O,audioForwardByRover:a?.audioForward||{},playUploadedAudio:f,stopUploadedAudio:p,startMicWhip:v,readyMicWhip:g,stopMicWhip:x})]}):r.jsx("section",{className:"surface h-full",children:r.jsx("div",{className:"flex h-full flex-col items-center justify-center text-center text-xs text-slate-400",children:"Verify your account to unlock VIP controls."})})}),r.jsx("div",{className:"lg:col-span-2",children:r.jsx(yX,{requestableRovers:E,pendingRequests:G,requestPrivateRoverAccess:u,onMessage:U,fullWidth:!0})}),r.jsx("div",{className:"lg:col-span-2",children:r.jsx(MX,{currentStoredKey:R,applyIdentityKey:s1,onMessage:U,fullWidth:!0})}),r.jsx("div",{className:"lg:col-span-2",children:r.jsx(LX,{isVerified:j,onMessage:U,fullWidth:!0})})]}),T?r.jsx("div",{className:I8,children:r.jsx("p",{className:"text-xs text-slate-400 text-center",children:T})}):null]})}const BX=420,jX=1200,NX={1:262,2:330,3:392,4:523};function Kt(){const t=d1(C=>C.session?.buttonBox?.buttons??[]),a=E2(),{value:l}=F1("audio",g2),s=Number.isFinite(l?.masterVolume)?l.masterVolume:g2.masterVolume,u=Number.isFinite(l?.alertVolume)?l.alertVolume:g2.alertVolume,f=Math.max(0,Math.min(1,s*u)),p=d.useMemo(()=>{const C=Array.isArray(t)?t:[];return C.length===4?C:[1,2,3,4].map(w=>C.find(A=>Number(A?.id)===w)||{id:w,count:0,goal:0,rewardName:null,rewardId:null,rewardNumber:null,lastRewardAt:null})},[t]),[v,g]=d.useState({}),[x,z]=d.useState({}),b=d.useRef(new Map),y=d.useRef(new Map),H=d.useRef({}),S=d.useRef(null);return d.useEffect(()=>{const C={};p.forEach(A=>{C[A.id]=Number(A.lastRewardAt||0)});const w=H.current||{};p.forEach(A=>{const V=Number(A.id),L=C[V]||0,R=Number(w[V]||0);if(L>0&&L!==R){z(N=>({...N,[V]:!0}));const q=y.current.get(V);q&&clearTimeout(q);const j=setTimeout(()=>{z(N=>({...N,[V]:!1})),y.current.delete(V)},jX);y.current.set(V,j)}}),H.current=C},[p]),d.useEffect(()=>{function C(A){const V=NX[A];if(!V||f<=0)return;let L=S.current;if(!L){const N=window.AudioContext||window.webkitAudioContext;if(!N)return;L=new N,S.current=L}const R=L.createOscillator(),q=L.createGain();R.type="square",R.frequency.value=V;const j=.14*f;q.gain.setValueAtTime(1e-4,L.currentTime),q.gain.exponentialRampToValueAtTime(Math.max(1e-4,j),L.currentTime+.01),q.gain.exponentialRampToValueAtTime(1e-4,L.currentTime+.2),R.connect(q),q.connect(L.destination),R.start(),R.stop(L.currentTime+.21)}function w(A={}){const V=Number(A.buttonId);if(!Number.isFinite(V)||V<1||V>4)return;g(q=>({...q,[V]:!0}));const L=b.current.get(V);L&&clearTimeout(L);const R=setTimeout(()=>{g(q=>({...q,[V]:!1})),b.current.delete(V)},BX);b.current.set(V,R),C(V)}return a.on("buttonBox:increment",w),()=>{a.off("buttonBox:increment",w)}},[f,a]),r.jsx(j1,{title:"Button Box",bodyClassName:"space-y-0.5 text-base",children:r.jsx("div",{className:"grid grid-cols-4 gap-0.5",children:p.map(C=>{const w=Number(C.id),A=Number.isFinite(C.count)?C.count:0,V=Number.isFinite(C.goal)?C.goal:0,L=typeof C.rewardName=="string"&&C.rewardName.trim()?C.rewardName.trim():"Unassigned",R=Number.isFinite(C.rewardNumber)?C.rewardNumber:"?",q=!!v[w],j=!!x[w];return r.jsx(Jo,{buttonId:w,count:A,goal:V,rewardNumber:R,rewardName:L,className:[q?"bg-cyan-900/45":"",j?"bg-fuchsia-900/45":""].filter(Boolean).join(" ")},w)})})})}const Os=10*1e3,FX=5*1e3,Vc={activeGameId:null,games:[],activeGame:null,participants:[],counters:{objects:[],rovers:[],codes:[]},recentEvents:[],ownPlayer:null};function Us(t={}){return{...Vc,...t&&typeof t=="object"?t:{},games:Array.isArray(t?.games)?t.games:[],participants:Array.isArray(t?.participants)?t.participants:[],counters:{...Vc.counters,...t?.counters&&typeof t.counters=="object"?t.counters:{}},recentEvents:Array.isArray(t?.recentEvents)?t.recentEvents:[]}}function th(){const t=E2(),[a,l]=d.useState(Vc),[s,u]=d.useState({connected:!!t.connected,stale:!0,lastReceivedAt:null});d.useEffect(()=>{let p=!1,v=null,g=null,x=0;function z(S={}){p||(x=Date.now(),l(Us(S)),u({connected:!!t.connected,stale:!1,lastReceivedAt:x}))}function b(){t.emit("barcodeGame:subscribe",{},(S={})=>{if(S.state){z(S.state);return}u(C=>({...C,connected:!!t.connected,stale:!x}))})}function y(){u(S=>({...S,connected:!0,stale:!x})),b()}function H(){u(S=>({...S,connected:!1,stale:!0}))}return t.on("barcodeGame:state",z),t.on("connect",y),t.on("disconnect",H),b(),v=window.setInterval(()=>{const S=!x||Date.now()-x>Os;u(C=>({...C,connected:!!t.connected,stale:S}))},1e3),g=window.setInterval(()=>{t.connected&&(!x||Date.now()-x>Os)&&b()},FX),()=>{p=!0,window.clearInterval(v),window.clearInterval(g),t.off("barcodeGame:state",z),t.off("connect",y),t.off("disconnect",H)}},[t]);const f=d.useCallback(p=>new Promise((v,g)=>{t.emit("barcodeGame:vote",{gameId:p},(x={})=>{if(x.error){g(new Error(x.error));return}x.state&&l(Us(x.state)),v(x)})}),[t]);return d.useMemo(()=>({state:a,connectionState:s,voteForGame:f}),[s,a,f])}function nc(t){return Number.isFinite(t)?Math.max(0,Math.min(255,Math.round(t))):null}function kX(t){const a=nc(t?.r),l=nc(t?.g),s=nc(t?.b);return a===null||l===null||s===null?null:{r:a,g:l,b:s}}function S8(t,a){return`rgba(${t.r}, ${t.g}, ${t.b}, ${a})`}function eh(t){const a=kX(t);return a?{textStyle:{color:S8(a,.96)},buttonStyle:{borderLeftColor:S8(a,.9)},selectedButtonStyle:{borderLeftColor:S8(a,1),backgroundColor:S8(a,.12)},titleBoxStyle:{borderLeftColor:S8(a,.88)}}:{textStyle:void 0,buttonStyle:void 0,titleBoxStyle:void 0,boxStyle:void 0}}function RX(t){const[a,l]=d.useState(()=>Date.now());return d.useEffect(()=>{if(!t)return;const s=window.setInterval(()=>{l(Date.now())},500);return()=>window.clearInterval(s)},[t]),a}function EX(t,a){if(!Number.isFinite(t))return null;const l=Math.max(0,Math.ceil((t-a)/1e3)),s=Math.floor(l/60),u=l%60;return s>0?`${s}:${String(u).padStart(2,"0")}`:`${u}s`}function TX({game:t,disabled:a,onVote:l}){const s=eh(t.themeColor),u=(t.active||t.selected)&&s.selectedButtonStyle||s.buttonStyle;return r.jsxs("button",{type:"button",disabled:a||t.active,onClick:()=>l(t.id),className:"surface flex min-h-[3.5rem] flex-col items-start justify-between border-l-4 border-l-neutral-600 px-1 py-0.75 text-left transition-colors hover:bg-neutral-700 disabled:cursor-not-allowed disabled:opacity-70",style:u,children:[r.jsxs("span",{className:"flex w-full items-start justify-between gap-1",children:[r.jsx("span",{className:"text-sm font-semibold leading-tight text-neutral-50",style:s.textStyle,children:t.title}),r.jsx("span",{className:"surface-muted shrink-0 px-1 py-0 text-center font-mono text-[0.72rem] text-neutral-200",children:t.voteCount||0})]}),r.jsx("span",{className:"mt-0.5 line-clamp-2 text-xs leading-snug text-neutral-300",children:t.description}),r.jsx("span",{className:"mt-0.5 text-[0.7rem] font-semibold text-neutral-400",children:t.active?"Active":t.selected?"Selected":t.actionLabel||"Vote"})]})}function qX({stats:t,theme:a}){return!Array.isArray(t)||!t.length?null:r.jsx("div",{className:"grid gap-0.5 sm:grid-cols-3",children:t.slice(0,6).map(l=>r.jsxs("div",{className:"surface px-1 py-0.75 text-center",children:[r.jsx("p",{className:"truncate text-[0.68rem] text-neutral-400",children:l.label}),r.jsx("p",{className:"mt-0.25 truncate text-base font-semibold leading-tight text-neutral-100",style:a.textStyle,children:l.value})]},l.label))})}function _X({participants:t,theme:a}){const l=Array.isArray(t)?t:[],s=l.map(u=>u?.nickname||u?.roverId).filter(Boolean);return r.jsxs("div",{className:"surface min-w-0 px-1 py-0.75",children:[r.jsx("p",{className:"text-sm font-semibold text-neutral-400",children:"Participants"}),r.jsx("p",{className:"font-mono text-xl font-semibold leading-tight text-neutral-50",style:a.textStyle,children:l.length}),r.jsx("p",{className:"truncate text-sm leading-tight text-neutral-300",children:s.length?s.join(", "):"Scan rover to join"})]})}function Zs({title:t,entries:a}){return!Array.isArray(a)||!a.length?null:r.jsxs("div",{children:[r.jsx("p",{className:"mb-0.5 text-xs font-semibold text-neutral-300",children:t}),r.jsx("div",{className:"grid gap-0.5",children:a.slice(0,4).map(l=>r.jsxs("div",{className:"surface-muted grid grid-cols-[minmax(0,1fr)_2.5rem] items-center gap-0.5 px-1 py-0.5 text-xs",children:[r.jsx("span",{className:"min-w-0 truncate text-neutral-200",children:l.label||l.entityId||l.code}),r.jsx("span",{className:"text-right font-mono text-neutral-200",children:l.count||0})]},`${l.entityId||l.code}-${l.type||"counter"}`))})]})}function DX({players:t,ownPlayer:a}){const l=a&&Number.isFinite(a.totalPoints);return r.jsxs("div",{className:"space-y-1",children:[r.jsxs("div",{className:"surface grid grid-cols-[minmax(0,1fr)_auto] items-center gap-1 px-1 py-0.75",children:[r.jsxs("div",{className:"min-w-0",children:[r.jsx("p",{className:"text-xs font-semibold text-neutral-300",children:"Your points"}),r.jsx("p",{className:"truncate text-[0.7rem] text-neutral-400",children:a?.rank?`Rank ${a.rank}`:"No rank yet"})]}),r.jsx("p",{className:"font-mono text-xl font-semibold leading-tight text-neutral-50",children:l?a.totalPoints:0})]}),r.jsxs("div",{className:"surface px-1 py-0.75",children:[r.jsx("p",{className:"mb-0.5 text-xs font-semibold text-neutral-300",children:"Leaderboard"}),Array.isArray(t)&&t.length?r.jsx("div",{className:"grid gap-0.5",children:t.slice(0,4).map((s,u)=>r.jsxs("div",{className:"surface-muted grid grid-cols-[1.5rem_minmax(0,1fr)_3rem] items-center gap-0.5 px-1 py-0.5 text-xs",children:[r.jsx("span",{className:"font-mono text-neutral-500",children:u+1}),r.jsx("span",{className:"truncate text-neutral-200",children:s.nickname}),r.jsx("span",{className:"text-right font-mono text-neutral-200",children:s.totalPoints})]},s.playerKey))}):r.jsx("p",{className:"text-xs text-neutral-500",children:"No points yet"})]})]})}function ch(){const{state:t,connectionState:a,voteForGame:l}=th(),[s,u]=d.useState(null),f=d.useRef(""),p=d.useRef(0),v=t.activeGame,g=v?.display||{},x=t.phase==="joining"||t.phase==="starting"||t.phase==="running",z=g.timer?.endsAt,b=RX(Number.isFinite(z)),y=EX(z,b),H=d.useMemo(()=>Array.isArray(t.games)?t.games:[],[t.games]),S=Array.isArray(t.participants)?t.participants:[],C=eh(v?.themeColor);d.useEffect(()=>{!a.stale||!a.lastReceivedAt||u1("barcode_game_state_stale",{connected:a.connected,phase:t.phase||"unknown"})},[a.connected,a.lastReceivedAt,a.stale,t.phase]),d.useEffect(()=>{const A=`${v?.id||"none"}:${v?.status||t.phase||"unknown"}`;f.current!==A&&(f.current=A,u1("barcode_game_active_change",{gameId:v?.id||"",status:v?.status||"",phase:t.phase||"unknown"}),(v?.status==="ending"||t.phase==="ending")&&u1("barcode_game_round_end",{gameId:v?.id||"",participantCount:S.length}))},[v?.id,v?.status,S.length,t.phase]),d.useEffect(()=>{if(S.length<=p.current){p.current=S.length;return}p.current=S.length,u1("barcode_game_player_join",{gameId:v?.id||"",participantCount:S.length})},[v?.id,S.length]);const w=async A=>{u(A),u1("barcode_game_vote",{gameId:A,phase:t.phase||"unknown",status:"started"});try{await l(A),u1("barcode_game_vote",{gameId:A,phase:t.phase||"unknown",status:"accepted"})}catch(V){throw u1("barcode_game_vote",{gameId:A,phase:t.phase||"unknown",status:"failed",reason:V?.message||"unknown"}),V}finally{u(null)}};return r.jsxs(j1,{title:"Barcode games",bodyClassName:"space-y-1 p-0.5 text-sm",children:[r.jsx("div",{className:"grid gap-0.5 sm:grid-cols-2",children:H.map(A=>r.jsx(TX,{game:A,disabled:!!s||x,onVote:w},A.id))}),r.jsxs("section",{className:"space-y-1 border-t border-neutral-700 pt-1",children:[r.jsxs("div",{className:"grid items-stretch gap-0.5 lg:grid-cols-[minmax(0,1fr)_9rem_10rem]",children:[r.jsxs("div",{className:"surface min-w-0 border-l-4 border-neutral-700 px-1 py-0.75",style:C.titleBoxStyle,children:[r.jsx("p",{className:"break-words text-xl font-bold leading-tight text-neutral-50",style:C.textStyle,children:g.title||v?.title||"No game active"}),r.jsx("p",{className:"mt-0.5 break-words text-sm font-semibold leading-tight text-neutral-200",children:g.primary||"Vote for a game to start"}),g.secondary?r.jsx("p",{className:"mt-0.5 break-words text-xs leading-snug text-neutral-300",children:g.secondary}):null]}),r.jsxs("div",{className:"surface px-1 py-0.75 text-left lg:text-right",children:[r.jsx("p",{className:"text-xs font-semibold text-neutral-400",children:g.timer?.label||"Time"}),r.jsx("p",{className:"font-mono text-xl font-semibold leading-tight text-neutral-50",style:C.textStyle,children:y||"--"}),r.jsx("p",{className:"text-xs leading-tight text-neutral-500",children:y?"active timer":"no timer"})]}),r.jsx(_X,{participants:S,theme:C})]}),r.jsx(qX,{stats:g.stats,theme:C})]}),r.jsx(DX,{players:t.leaderboard,ownPlayer:t.ownPlayer}),r.jsxs("div",{className:"grid gap-0.5 border-t border-neutral-700 pt-1 sm:grid-cols-2",children:[r.jsx("div",{className:"surface px-1 py-0.75",children:r.jsx(Zs,{title:"Most scanned objects",entries:t.counters?.objects})}),r.jsx("div",{className:"surface px-1 py-0.75",children:r.jsx(Zs,{title:"Most scanned rovers",entries:t.counters?.rovers})})]})]})}function OX(t){const a=Number(t);if(!Number.isFinite(a)||a<=0)return null;const l=new Date(a);return Number.isNaN(l.getTime())?null:l.toLocaleTimeString([],{hour:"numeric",minute:"2-digit",second:"2-digit"})}function UX({memory:t,onClose:a}){const l=typeof t?.summary=="string"&&t.summary.trim()?t.summary:"Memory unavailable.",s=OX(t?.updatedAt);return r.jsx("div",{className:"fixed inset-0 z-40 flex items-center justify-center bg-black/75 p-1",onClick:a,children:r.jsx("div",{className:"w-full max-w-2xl",onClick:u=>u.stopPropagation(),children:r.jsx(j1,{title:"Overseer memory",meta:s?`Updated ${s}`:null,actions:r.jsx("button",{type:"button",onClick:a,className:"button-dark px-1 py-0.25 text-[0.75rem]",children:"Close"}),bodyClassName:"p-0.5 text-xs",children:r.jsx("pre",{className:"surface max-h-[70vh] overflow-y-auto whitespace-pre-wrap break-words font-mono text-[0.72rem] text-slate-200",children:l})})})})}function ZX(){const{identifySession:t}=G2(),a=d1(H=>H.session?.overseerVote||null),l=d1(H=>H.overseerMemory||null),{value:s}=F1("profile",{nickname:""}),{value:u}=F1("identity",{cookieUserId:""}),{value:f,save:p}=F1("overseerPreference",{enabled:!1}),[v,g]=d.useState(!1),x=!!f?.enabled,z=!!a?.running,b=async H=>{const S=!!H?.target?.checked;await p(C=>({...C||{},enabled:S})),await t({cookieUserId:String(u?.cookieUserId||"").trim(),nickname:String(s?.nickname||"").trim(),overseerEnabled:S})},y=r.jsx("button",{type:"button",onClick:()=>g(!0),className:"button-dark px-1 py-0.25 text-[0.75rem]",title:"View overseer memory",children:"Memory"});return r.jsxs(r.Fragment,{children:[r.jsxs(j1,{title:"Overseer vote",actions:y,bodyClassName:"space-y-0.5 text-center text-xs text-slate-200",children:[r.jsxs("label",{className:`flex items-center justify-center gap-1.5 rounded px-1 py-0.5 ${x?"bg-emerald-600/80 text-emerald-50":"bg-slate-600/70 text-slate-100"}`,children:[r.jsx("input",{type:"checkbox",checked:x,onChange:b}),r.jsxs("span",{children:["Your vote: ",x?"Yes":"No"]})]}),r.jsx("span",{className:"text-xs",children:"Enable a local LLM in chat"}),r.jsxs("div",{className:"mt-0.5 text-slate-400",children:["Yes!: ",Number(a?.yesCount||0),", No...: ",Number(a?.noCount||0)]}),r.jsx("div",{className:"mt-0.5 flex justify-center",children:r.jsx("span",{className:`inline-flex items-center rounded px-1.5 py-0.5 text-[0.7rem] font-medium ${z?"bg-emerald-600/80 text-emerald-50":"bg-slate-600/70 text-slate-100"}`,children:z?"Running!":"Stopped by vote."})})]}),v?r.jsx(UX,{memory:l,onClose:()=>g(!1)}):null]})}function ah(){return d1(a=>!!a.session?.overseerVote?.votingEnabled)?r.jsx(ZX,{}):null}const $X=224,GX=144,IX=300,PX=8;function YX(){const t=k1(l=>l.state.roverId),a=Z4(t,Zc,Eo);return r.jsx(j1,{title:"Roomba sensor view",children:r.jsx("div",{className:"aspect-square w-full",children:r.jsx(Eu,{mapTelemetry:a})})})}function KX(){const t=k1(U=>U.state.roverId),a=k1(U=>U.state.keymap),l=k1(U=>U.state.camera),s=k1(U=>U.state.horn),u=k1(U=>U.pipeline?.nightVision),f=k1(U=>U.pipeline?.nightVisionState),p=k1(U=>U.pipeline?.horn),{setServoAngle:v,setNightVision:g,startHorn:x,stopHorn:z}=x3(),b=A0(),y=Au(t),H=y.docked&&!y.driving,S=l?.config,C=!!(t&&l?.enabled&&S),w=!!(t&&u),A=!!(t&&p),V=s?.overheated,L=typeof S?.minAngle=="number"?S.minAngle:-30,R=typeof S?.maxAngle=="number"?S.maxAngle:30,q=typeof l?.angle=="number"?l.angle:typeof S?.homeAngle=="number"?S.homeAngle:(L+R)/2,j=_2(a?.nightVisionToggle?.[0]),N=_2(a?.hornHonk?.[0]),E=_2(a?.cameraUp?.[0]),G=_2(a?.cameraDown?.[0]),O=!!(!t||b.cameraLocked),T=d.useMemo(()=>({setNightVision:U=>{u1("night_vision_toggle",{roverId:t,source:"desktop_control",enabled:!!U}),g(U)},startHorn:()=>(u1("horn_start",{roverId:t,source:"desktop_control"}),x()),stopHorn:z}),[t,g,x,z]);return r.jsxs(j1,{hideHeader:!0,className:"h-full",bodyClassName:`grid h-full min-h-0 grid-rows-[minmax(0,1fr)_auto] ${C2}`,children:[r.jsx(Vu,{layout:"desktop",expand:!0,driveDockState:y}),H?null:r.jsxs("div",{className:`${x6} p-0 text-sm text-slate-200`,children:[w&&r.jsx(Hu,{nightVisionOn:f?.nightVisionOn,disabled:!t,onToggle:T.setNightVision,keyLabel:j}),A&&r.jsx(Cu,{disabled:!t||V,onStart:T.startHorn,onStop:T.stopHorn,keyLabel:N,active:s?.active,heat:s?.heat}),C&&r.jsx(rX,{value:q,min:L,max:R,label:"Camera tilt",disabled:O,onChange:v,keyDownLabel:G,keyUpLabel:E,className:`${x6} rounded-xl border-2 border-emerald-300/70 bg-emerald-900 px-1 py-1 text-emerald-50`,labelRowClass:"text-xs text-emerald-100",labelClass:"text-sm font-semibold",valueClass:"font-mono text-slate-100",sliderClass:"w-full",accentClass:"accent-emerald-400",endpointClass:"text-[0.7rem] text-emerald-100/80"})]})]})}function QX({layout:t,onOpenHelpOverlay:a}){const[l,s]=d.useState("telemetry"),u=d.useRef(null),[f,p]=d.useState($X),v=d1(L=>!!L.session?.isVerified),g=d1(L=>String(L.session?.assignment?.roverId||"").trim()),x=d1(L=>{const R=String(L.session?.assignment?.roverId||"").trim();return R&&L.session?.audioForward?.[R]||null}),z=k1(L=>!!L.state.mic?.pttActive),{value:b}=F1("vipAudio",{openMicEnabled:!1,pttMode:"live"}),y=v?"bg-emerald-400":"bg-red-600",H=!!b?.openMicEnabled,S=b?.pttMode==="clip"?"clip":"live",C=!!(g&&v&&(S==="clip"?z:H||z)),w=!!(g&&v&&S==="clip"&&x?.source==="upload"&&x?.state==="playing"),A=d1(L=>!!L.session?.overseerVote?.votingEnabled),V=d.useCallback(L=>{s(L),u1("tab_change",{tab:L,layout:t,surface:"desktop_right_pane"})},[t]);return d.useLayoutEffect(()=>{const L=u.current;if(!L)return;let R=0,q=0,j=0;const N=()=>{R=0;const{top:T}=L.getBoundingClientRect(),U=window.innerHeight-T-PX,s1=Math.round(Math.max(GX,Math.min(IX,U)));p(n1=>Math.abs(n1-s1)>1?s1:n1)},E=()=>{R||(R=window.requestAnimationFrame(N))},G=()=>{q=window.requestAnimationFrame(()=>{q=0,j=window.requestAnimationFrame(()=>{j=0,N()})})},O=typeof ResizeObserver=="function"?new ResizeObserver(()=>{E()}):null;return E(),G(),O&&L.parentElement&&O.observe(L.parentElement),window.addEventListener("resize",E),document.addEventListener("scroll",E,{capture:!0,passive:!0}),()=>{R&&window.cancelAnimationFrame(R),q&&window.cancelAnimationFrame(q),j&&window.cancelAnimationFrame(j),O?.disconnect(),window.removeEventListener("resize",E),document.removeEventListener("scroll",E,{capture:!0})}},[l]),r.jsx("section",{className:"text-base",children:r.jsxs(ha,{defaultTab:"telemetry",currentTab:l,onTabChange:V,children:[r.jsxs(da,{children:[r.jsx(K2,{id:"telemetry",children:"Controls"}),r.jsx(K2,{id:"activities",children:"Activities"}),r.jsx(K2,{id:"vip",highlight:w?"green":C?"pink":"none",children:r.jsxs("span",{className:"inline-flex items-center gap-2",children:[r.jsx("span",{children:"VIP"}),r.jsx("span",{className:`inline-block h-3 w-3 rounded-full ${y}`,"aria-hidden":"true",title:v?"Verified":"Not verified"})]})}),r.jsx(K2,{id:"help",children:"Help"}),r.jsx(K2,{id:"settings",children:"Settings"})]}),r.jsxs(fa,{children:[r.jsx(Q2,{id:"telemetry",children:r.jsxs("div",{className:`flex flex-col ${C2}`,children:[r.jsxs("div",{className:`flex flex-col ${C2}`,children:[r.jsxs("div",{className:`grid items-stretch ${C2} grid-cols-[minmax(0,1.35fr)_minmax(0,0.95fr)]`,children:[r.jsx(YX,{}),r.jsx(KX,{})]}),r.jsxs("div",{className:`grid ${C2} grid-cols-[minmax(0,1fr)_minmax(0,0.9fr)_minmax(0,0.75fr)]`,children:[r.jsx(o7,{}),r.jsx(Yc,{panelId:"replay-sources-desktop",fillHeight:!0}),r.jsx(WQ,{})]}),r.jsxs("div",{ref:u,className:`grid min-h-0 items-stretch ${C2} grid-cols-[minmax(0,1.3fr)_minmax(0,0.22fr)]`,style:{height:`${f}px`},children:[r.jsx(G8,{fillHeight:!0}),r.jsxs("div",{className:`grid min-h-0 ${C2} ${A?"grid-rows-[auto_minmax(0,1fr)]":"grid-rows-[minmax(0,1fr)]"}`,children:[A?r.jsx(ah,{}):null,r.jsx(Yt,{compact:!0,hideNicknameForm:!0,fillHeight:!0})]})]})]}),r.jsx(Uu,{}),r.jsx(la,{defaultOrientation:"horizontal",panelId:"rightpane-telemetry"})]})}),r.jsx(Q2,{id:"activities",children:r.jsxs("div",{className:`flex flex-col ${C2}`,children:[r.jsx(ch,{}),r.jsx(Kt,{}),r.jsx(ju,{})]})}),r.jsx(Q2,{id:"vip",keepMounted:!0,children:r.jsx(Wu,{isActive:l==="vip"})}),r.jsx(Q2,{id:"help",children:r.jsx(Xu,{layout:t,onOpenOverlay:a})}),r.jsx(Q2,{id:"settings",children:r.jsx(Yu,{})})]})]})})}const XX=new Set(["admin","lockdown","lockdown-admin"]),JX=new Set(["lockdown","lockdown-admin"]),WX=new Set(["admin","lockdown"]);function tJ(t="admin"){return t==="lockdown"?{title:"Lockdown mode active",description:"Only the server owners can access the interface at this time."}:{title:"Admin mode active"}}function eJ(){const t=d1(x=>x.session?.mode||null),a=d1(x=>x.session?.role||null),l=d1(x=>x.session?.adminReason?.text||""),s=d1(x=>x.session?.timezone||"UTC"),u=WX.has(t),f=t==="lockdown"?JX.has(a):XX.has(a),p=U8(1e3,u&&!f),v=d.useMemo(()=>{const x=new Date(p);try{return new Intl.DateTimeFormat("en-US",{timeZone:s,hour:"numeric",minute:"2-digit",second:"2-digit"}).format(x)}catch{return x.toLocaleTimeString()}},[p,s]);if(!u||f)return null;const g=tJ(t);return r.jsx("div",{className:"pointer-events-auto fixed inset-0 z-50 flex items-center justify-center bg-black px-0.5 py-0.5",children:r.jsxs("div",{className:"surface w-full max-w-md space-y-0.5 text-slate-100 shadow-2xl",children:[r.jsxs("div",{className:"space-y-0.5",children:[r.jsx("p",{className:"text-lg font-semibold",children:g.title}),r.jsx("p",{className:"text-sm text-slate-300",children:g.description})]}),r.jsxs("div",{className:"surface-muted space-y-0.5",children:[r.jsx("p",{className:"text-[0.7rem] tracking-wide text-slate-400",children:"Reason for locking:"}),r.jsx("p",{className:"text-lg font-semibold text-slate-100",children:l||"No reason set."}),r.jsxs("p",{className:"text-center text-sm text-slate-300",children:["Server time: ",v]})]}),r.jsx("div",{className:"surface-muted",children:r.jsx(Zu,{})}),r.jsx("div",{className:"w-full justify-center items-center",children:r.jsx(n7,{id:"discord",label:"Join our Discord server for updates!"})}),"You can still use the chat while the server is locked:",r.jsx("div",{className:"max-h-80 overflow-y-auto",children:r.jsx(G8,{nicknameLayout:"stacked"})})]})})}const cJ="/assets/turn_alert-DVO8EZJa.mp3";function aJ(t,a=1){const l=d.useRef(null);return d.useEffect(()=>{l.current=new Audio(t),l.current.volume=a,l.current.load()},[t,a]),()=>{l.current&&(l.current.volume=a,l.current.currentTime=0,l.current.play().catch(()=>{}))}}function nJ(){const t=d1(z=>z.session?.socketId||null),a=d1(z=>z.session?.turnQueues||{}),l=d1(z=>z.session?.roster||[]),{pushAlert:s}=G2(),{value:u}=F1("audio",g2),f=Number.isFinite(u?.masterVolume)?u.masterVolume:g2.masterVolume,p=Number.isFinite(u?.alertVolume)?u.alertVolume:g2.alertVolume,v=Math.max(0,Math.min(1,f*p)),g=aJ(cJ,v),x=d.useRef(new Set);return d.useEffect(()=>{if(!t)return;const z=[];Object.entries(a).forEach(([b,y])=>{!y||!y.current||y.current!==t||x.current.has(b)||(z.push(b),x.current.add(b))}),Object.keys(a).forEach(b=>{(!a[b]||a[b].current!==t)&&x.current.delete(b)}),z.length!==0&&(z.forEach(b=>{const y=l.find(H=>String(H.id)===String(b))?.name||b;s({title:"Your turn!",message:`You now control ${y}.`,color:"#ff5722"})}),g())},[a,g,s,l,t]),null}function lJ({visible:t,mode:a,onEnterFullscreen:l,onDismiss:s}){if(!t)return null;const u=a==="pwa-hint";return r.jsx("div",{className:"fixed inset-0 z-40 flex items-center justify-center p-1 pointer-events-none bg-black/20",children:r.jsx("div",{className:"pointer-events-auto w-full max-w-sm surface center",children:r.jsxs("div",{className:"space-y-0.5 p-1 text-sm text-slate-100",children:[r.jsx("h2",{className:"text-base font-semibold text-white border-b border-slate-700",children:"Better in fullscreen!"}),u?r.jsxs("p",{className:"text-slate-300",children:["For fullscreen on iOS, open Safari's share menu and pick ",r.jsx("strong",{children:"Add to Home Screen"}),". Launching from the home screen then makes it fullscreen."]}):r.jsx("p",{className:"text-slate-300",children:"Enable fullscreen to free up more space for the video feed and controls. You can exit fullscreen at any time via the system back or home gesture."}),r.jsx("p",{className:"text-xs border-t border-b border-slate-700 p-0.5 text-blue-300 text-center",children:"This will only show once just to let you know. There is a fullscreen button in the bottom right for later use."}),r.jsxs("div",{className:"flex justify-end gap-0.5 pt-1 text-sm",children:[r.jsx("button",{type:"button",className:"rounded border border-slate-600 px-3 py-1 text-slate-200",onClick:s,children:u?"Got it":"Not now"}),!u&&r.jsx("button",{type:"button",className:"rounded bg-cyan-500 px-3 py-1 font-semibold text-black hover:bg-cyan-400",onClick:l,children:"Enter fullscreen"})]})]})})})}function rJ({side:t="right",onClick:a}){const l=t==="left"?"left-2":"right-2";return r.jsx("button",{type:"button",onClick:a,className:`fixed bottom-2 ${l} z-30 flex h-10 w-10 items-center justify-center rounded-full border border-slate-700 bg-black text-slate-200 transition hover:bg-zinc-900 active:scale-95`,"aria-label":"Enter fullscreen",title:"Enter fullscreen",children:r.jsx("svg",{viewBox:"0 0 24 24",width:"18",height:"18","aria-hidden":"true",className:"pointer-events-none",children:r.jsx("path",{d:"M4 9V4h5M15 4h5v5M20 15v5h-5M9 20H4v-5",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"})})})}const iJ=new Set(["mobile-portrait","mobile-landscape"]),sJ=()=>{if(typeof navigator>"u")return!1;const t=navigator.userAgent||navigator.platform||"";return/iphone|ipad|ipod/i.test(t)},$s=()=>{if(typeof document>"u")return!1;const t=document;return!!(t.fullscreenEnabled||t.webkitFullscreenEnabled||t.mozFullScreenEnabled||t.msFullscreenEnabled)};function oJ(t){const{value:a,save:l,status:s}=F1("page",{fullscreenPromptShown:!1}),u=iJ.has(t),[f,p]=d.useState(!1),[v,g]=d.useState("native"),[x,z]=d.useState(!1),b=!!a?.fullscreenPromptShown,y=d.useMemo(()=>sJ(),[]),H=d.useMemo(()=>$s(),[]),S=d.useCallback(()=>{s==="ready"&&l(L=>L?.fullscreenPromptShown?L:{...L||{},fullscreenPromptShown:!0})},[l,s]),C=d.useCallback(()=>{if(s!=="ready"){p(!1);return}if(!u){p(!1),z(!1);return}if(!x&&b){p(!1);return}if(y){g("pwa-hint"),p(!0);return}if(!$s()){p(!1);return}if(typeof document<"u"&&document.fullscreenElement){p(!1);return}g("native"),p(!0)},[x,b,y,u,s]);d.useEffect(()=>{C()},[C]),d.useEffect(()=>{if(typeof document>"u")return;const L=()=>{if(document.fullscreenElement){z(!1),p(!1);return}C()};return document.addEventListener("fullscreenchange",L),document.addEventListener("webkitfullscreenchange",L),()=>{document.removeEventListener("fullscreenchange",L),document.removeEventListener("webkitfullscreenchange",L)}},[C]);const w=d.useCallback(()=>{S(),z(!1),p(!1)},[S]),A=d.useCallback(async()=>{if(!u||y||typeof document>"u")return!1;if(document.fullscreenElement)return!0;const L=document.documentElement;if(!L)return!1;const R=L.requestFullscreen||L.webkitRequestFullscreen||L.mozRequestFullScreen||L.msRequestFullscreen;if(!R)return!1;try{const q=R.call(L);return q&&typeof q.then=="function"&&await q,S(),z(!1),p(!1),!0}catch(q){return console.warn("Failed to enter fullscreen",q),!1}},[y,u,S]),V=d.useCallback(()=>{u&&(z(!0),g(y?"pwa-hint":"native"),p(!0))},[y,u]);return d.useEffect(()=>{u||(z(!1),p(!1))},[u]),{visible:f,mode:v,isIOS:y,nativeSupported:H,enterFullscreen:A,dismiss:w,showPrompt:V}}function uJ({visible:t,layout:a,onClose:l,showOnLoad:s,onToggleShowOnLoad:u}){const f=k1(v=>v.state.keymap);if(!t)return null;const p=v=>{const g=!v.target.checked;u?.(g)};return r.jsx("div",{className:"fixed inset-0 z-30 flex items-center justify-center bg-black/80 px-0.5 py-0.5",children:r.jsxs("div",{className:"pointer-events-auto surface w-full max-w-4xl max-h-[90vh] overflow-hidden shadow-2xl",children:[r.jsxs("div",{className:"flex items-center justify-between border-b border-slate-700 px-0.5 py-0.25 text-sm text-slate-200",children:[r.jsx("span",{className:"font-semibold",children:"Help & controls"}),r.jsxs("div",{className:"flex items-center gap-0.5 text-[0.8rem] text-slate-300",children:[r.jsxs("label",{className:"flex items-center gap-0.5",children:[r.jsx("input",{type:"checkbox",checked:!s,onChange:p,className:"accent-cyan-500"}),r.jsx("span",{children:"Don't show again"})]}),r.jsx("button",{type:"button",onClick:l,className:"button-dark px-2 py-0.25 text-[0.8rem]",children:"Close"})]})]}),r.jsx("div",{className:"max-h-[85vh] overflow-y-auto p-0.5",children:r.jsx(Qu,{layout:a,keymap:f||{}})})]})})}function u0({label:t,keyLabel:a}){return r.jsxs("div",{className:"surface-muted flex items-center justify-between gap-0.5 px-0.5 py-0.35 text-[0.8rem] text-slate-200",children:[r.jsx("span",{children:t}),r.jsx(Pt,{label:a})]})}function hJ({keymap:t}){return r.jsxs("div",{className:"space-y-0.5",children:[r.jsx("p",{className:"text-sm text-slate-200",children:'1. Press "Start Driving" put your rover into driving mode.'}),r.jsxs("div",{className:"space-y-0.5",children:[r.jsx("p",{className:"text-sm text-slate-200",children:"2. Use the drive controls to move your rover:"}),r.jsxs("div",{className:"space-y-0.5",children:[r.jsx(u0,{label:"Forward",keyLabel:_2(t?.driveForward?.[0])}),r.jsx(u0,{label:"Backward",keyLabel:_2(t?.driveBackward?.[0])}),r.jsx(u0,{label:"Turn Left",keyLabel:_2(t?.driveLeft?.[0])}),r.jsx(u0,{label:"Turn Right",keyLabel:_2(t?.driveRight?.[0])}),r.jsx(u0,{label:"Move faster",keyLabel:_2(t?.boostModifier?.[0])}),r.jsx(u0,{label:"Move slower",keyLabel:_2(t?.slowModifier?.[0])})]})]}),r.jsx("p",{className:"text-sm text-slate-200",children:'3. When done, enter "Docking Assist" and line up the front sensor with the dock sensor.'})]})}function dJ(){return r.jsxs("div",{className:"space-y-0.5 text-sm text-slate-200",children:[r.jsx("p",{children:'1. Press "Start Driving" put your rover into driving mode.'}),r.jsx("p",{children:"2. Touch and hold in Joystick area to move."}),r.jsx("p",{children:"3. Use the other column for motor, horn, and camera controls."}),r.jsx("p",{children:'4. When done, enter "Docking Assist" and line up the front sensor with the dock sensor.'})]})}function fJ({visible:t,layout:a,showOnLoad:l,onToggleShowOnLoad:s,onOpenHelp:u,onClose:f}){const p=k1(z=>z.state.keymap),v=a==="desktop",g=d.useMemo(()=>p||{},[p]);if(!t)return null;const x=z=>{const b=!z.target.checked;s?.(b)};return r.jsx("div",{className:"fixed inset-0 z-40 flex items-end justify-center bg-black/75 p-0.5 items-center",children:r.jsxs("div",{className:"pointer-events-auto surface w-full max-w-3xl overflow-hidden shadow-2xl",children:[r.jsx("div",{className:"flex items-center justify-between border-b border-slate-700 px-0.5 py-0.35 text-sm text-slate-200",children:r.jsx("span",{className:"font-semibold text-xl",children:"Welcome! To get started:"})}),r.jsxs("div",{className:`grid gap-0.5 p-0.5 ${v?"md:grid-cols-[minmax(0,1.5fr)_minmax(0,1fr)]":"grid-cols-1"}`,children:[r.jsx("section",{className:"space-y-0.5 border-b border-slate-700",children:v?r.jsx(hJ,{keymap:g}):r.jsx(dJ,{})}),r.jsxs("section",{className:"space-y-0.5",children:[r.jsx("p",{className:"text-left",children:"Next..."}),r.jsxs("div",{className:"surface space-y-0.5 p-0.5 border-b border-slate-700",children:[r.jsx("p",{className:"text-xl font-semibold text-slate-200",children:"Set your nickname"}),r.jsx("p",{className:"text-sm font-semibold text-slate-200",children:"Nicknames are assigned randomly by default, you can change yours here."}),r.jsx(s7,{compact:!0})]}),r.jsxs("div",{className:"surface p-0.5",children:[r.jsx("p",{className:"text-xl font-semibold text-slate-200",children:"Join our Discord server!"}),r.jsx("p",{className:"text-sm font-semibold text-slate-200",children:"We have an active and welcoming community :3"}),r.jsx(n7,{id:"discord",label:"Join Discord"})]})]})]}),r.jsxs("div",{className:"flex flex-wrap items-center justify-between gap-0.5 border-t border-slate-700 px-0.5 py-0.35 text-[0.8rem]",children:[r.jsxs("label",{className:"flex items-center gap-0.5 text-slate-300",children:[r.jsx("input",{type:"checkbox",checked:!l,onChange:x,className:"accent-cyan-500"}),r.jsx("span",{children:"Don't show again"})]}),r.jsx("div",{className:"flex items-center gap-0.5",children:r.jsx("button",{type:"button",onClick:f,className:"button-dark px-1 py-0.25 text-2xl bg-green-600 hover:bg-green-400 hover:border-green-100 border-green-400",children:"Got it! Let me in!"})})]})]})})}const mJ=`aroma bagel batter beans diff --git a/server/public/assets/index-CZM8e4sR.css b/server/public/assets/index-CZM8e4sR.css new file mode 100644 index 00000000..cf7e1c52 --- /dev/null +++ b/server/public/assets/index-CZM8e4sR.css @@ -0,0 +1 @@ +*,:before,:after{--tw-border-spacing-x: 0;--tw-border-spacing-y: 0;--tw-translate-x: 0;--tw-translate-y: 0;--tw-rotate: 0;--tw-skew-x: 0;--tw-skew-y: 0;--tw-scale-x: 1;--tw-scale-y: 1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness: proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-color: rgb(59 130 246 / .5);--tw-ring-offset-shadow: 0 0 #0000;--tw-ring-shadow: 0 0 #0000;--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }::backdrop{--tw-border-spacing-x: 0;--tw-border-spacing-y: 0;--tw-translate-x: 0;--tw-translate-y: 0;--tw-rotate: 0;--tw-skew-x: 0;--tw-skew-y: 0;--tw-scale-x: 1;--tw-scale-y: 1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness: proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-color: rgb(59 130 246 / .5);--tw-ring-offset-shadow: 0 0 #0000;--tw-ring-shadow: 0 0 #0000;--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }*,:before,:after{box-sizing:border-box;border-width:0;border-style:solid;border-color:#e5e7eb}:before,:after{--tw-content: ""}html,:host{line-height:1.5;-webkit-text-size-adjust:100%;-moz-tab-size:4;-o-tab-size:4;tab-size:4;font-family:ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji",Segoe UI Symbol,"Noto Color Emoji";font-feature-settings:normal;font-variation-settings:normal;-webkit-tap-highlight-color:transparent}body{margin:0;line-height:inherit}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-feature-settings:normal;font-variation-settings:normal;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}button,input,optgroup,select,textarea{font-family:inherit;font-feature-settings:inherit;font-variation-settings:inherit;font-size:100%;font-weight:inherit;line-height:inherit;letter-spacing:inherit;color:inherit;margin:0;padding:0}button,select{text-transform:none}button,input:where([type=button]),input:where([type=reset]),input:where([type=submit]){-webkit-appearance:button;background-color:transparent;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:baseline}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dl,dd,h1,h2,h3,h4,h5,h6,hr,figure,p,pre{margin:0}fieldset{margin:0;padding:0}legend{padding:0}ol,ul,menu{list-style:none;margin:0;padding:0}dialog{padding:0}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{opacity:1;color:#9ca3af}input::placeholder,textarea::placeholder{opacity:1;color:#9ca3af}button,[role=button]{cursor:pointer}:disabled{cursor:default}img,svg,video,canvas,audio,iframe,embed,object{display:block;vertical-align:middle}img,video{max-width:100%;height:auto}[hidden]:where(:not([hidden=until-found])){display:none}.\!container{width:100%!important}.container{width:100%}@media(min-width:640px){.\!container{max-width:640px!important}.container{max-width:640px}}@media(min-width:768px){.\!container{max-width:768px!important}.container{max-width:768px}}@media(min-width:1024px){.\!container{max-width:1024px!important}.container{max-width:1024px}}@media(min-width:1280px){.\!container{max-width:1280px!important}.container{max-width:1280px}}@media(min-width:1536px){.\!container{max-width:1536px!important}.container{max-width:1536px}}.pride-page-bg{background-color:#050505;background-image:linear-gradient(#0000,#0000),repeating-linear-gradient(45deg,#5bcefa 0 1.818%,#f5a9b8 1.818% 3.636%,#fff 3.636% 5.455%,#f5a9b8 5.455% 7.273%,#5bcefa 7.273% 9.091%,#e40303 9.091% 10.909%,#ff8c00 10.909% 12.727%,#ffed00 12.727% 14.545%,#00a651 14.545% 16.364%,#06f 16.364% 18.182%,#9b2fae 18.182% 20%);background-attachment:fixed}.panel{border-radius:.375rem;--tw-bg-opacity: 1;background-color:rgb(0 0 0 / var(--tw-bg-opacity));padding:0;--tw-text-opacity: 1;color:rgb(255 255 255 / var(--tw-text-opacity))}.panel-section{border-radius:.375rem;--tw-bg-opacity: 1;background-color:rgb(23 23 23 / var(--tw-bg-opacity));padding:0;--tw-text-opacity: 1;color:rgb(255 255 255 / var(--tw-text-opacity))}.panel-muted{border-radius:.375rem;font-size:.875rem;line-height:1.25rem;--tw-text-opacity: 1;color:rgb(148 163 184 / var(--tw-text-opacity))}.surface{border-radius:.375rem;--tw-bg-opacity: 1;background-color:rgb(38 38 38 / var(--tw-bg-opacity));padding:.125rem;--tw-text-opacity: 1;color:rgb(255 255 255 / var(--tw-text-opacity))}.surface-muted{border-radius:.375rem;--tw-bg-opacity: 1;background-color:rgb(64 64 64 / var(--tw-bg-opacity));padding:.125rem;--tw-text-opacity: 1;color:rgb(245 245 245 / var(--tw-text-opacity))}.field-input{border-radius:.375rem;border-width:1px;--tw-border-opacity: 1;border-color:rgb(82 82 82 / var(--tw-border-opacity));--tw-bg-opacity: 1;background-color:rgb(64 64 64 / var(--tw-bg-opacity));padding:.125rem;--tw-text-opacity: 1;color:rgb(255 255 255 / var(--tw-text-opacity))}.field-input::-moz-placeholder{--tw-text-opacity: 1;color:rgb(148 163 184 / var(--tw-text-opacity))}.field-input::placeholder{--tw-text-opacity: 1;color:rgb(148 163 184 / var(--tw-text-opacity))}.field-input:focus{outline:2px solid transparent;outline-offset:2px;--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000);--tw-ring-opacity: 1;--tw-ring-color: rgb(14 165 233 / var(--tw-ring-opacity))}.button-dark{border-radius:.375rem;border-width:1px;--tw-border-opacity: 1;border-color:rgb(125 211 252 / var(--tw-border-opacity));--tw-bg-opacity: 1;background-color:rgb(2 132 199 / var(--tw-bg-opacity));padding:.125rem;font-size:.875rem;line-height:1.25rem;font-weight:500;--tw-text-opacity: 1;color:rgb(255 255 255 / var(--tw-text-opacity));transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.button-dark:hover{--tw-border-opacity: 1;border-color:rgb(14 165 233 / var(--tw-border-opacity));--tw-bg-opacity: 1;background-color:rgb(14 165 233 / var(--tw-bg-opacity))}.button-danger{border-radius:.375rem;--tw-bg-opacity: 1;background-color:rgb(225 29 72 / var(--tw-bg-opacity));padding:.125rem;font-size:.875rem;line-height:1.25rem;font-weight:500;--tw-text-opacity: 1;color:rgb(255 255 255 / var(--tw-text-opacity));transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.button-danger:hover{--tw-bg-opacity: 1;background-color:rgb(244 63 94 / var(--tw-bg-opacity))}.chat-composer{container-type:inline-size;display:flex;flex-wrap:wrap;align-items:stretch;gap:.125rem;min-width:0;overflow:hidden}.chat-composer-nickname{flex:0 0 5rem;min-width:0;order:1}.chat-composer-input{flex:1 1 0%;min-width:0;order:2}.chat-composer-send{flex:0 0 auto;align-self:stretch;order:3}.chat-composer-tts{display:flex;flex:1 1 100%;align-items:center;gap:.125rem;min-width:0;overflow:hidden;order:4}@container (min-width: 44rem){.chat-composer{flex-wrap:nowrap}.chat-composer-nickname{flex-basis:7rem;order:1}.chat-composer-input{order:2}.chat-composer-tts{flex:0 1 auto;order:3}.chat-composer-send{order:4}}.pointer-events-none{pointer-events:none}.pointer-events-auto{pointer-events:auto}.\!visible{visibility:visible!important}.visible{visibility:visible}.collapse{visibility:collapse}.fixed{position:fixed}.absolute{position:absolute}.relative{position:relative}.sticky{position:sticky}.inset-0{inset:0}.inset-x-0{left:0;right:0}.inset-x-1{left:.25rem;right:.25rem}.bottom-0{bottom:0}.bottom-0\.5{bottom:.125rem}.bottom-1{bottom:.25rem}.bottom-2{bottom:.5rem}.bottom-4{bottom:1rem}.bottom-\[calc\(100\%\+0\.125rem\)\]{bottom:calc(100% + .125rem)}.left-0{left:0}.left-0\.5{left:.125rem}.left-1{left:.25rem}.left-1\/2{left:50%}.left-2{left:.5rem}.left-4{left:1rem}.right-0{right:0}.right-0\.5{right:.125rem}.right-1{right:.25rem}.right-2{right:.5rem}.top-0{top:0}.top-0\.5{top:.125rem}.top-1{top:.25rem}.top-1\/2{top:50%}.top-10{top:2.5rem}.top-6{top:1.5rem}.z-10{z-index:10}.z-20{z-index:20}.z-30{z-index:30}.z-40{z-index:40}.z-50{z-index:50}.z-\[1000\]{z-index:1000}.z-\[110\]{z-index:110}.z-\[120\]{z-index:120}.z-\[130\]{z-index:130}.z-\[70\]{z-index:70}.order-1{order:1}.order-2{order:2}.col-span-full{grid-column:1 / -1}.m-0{margin:0}.-mx-0\.5{margin-left:-.125rem;margin-right:-.125rem}.mx-auto{margin-left:auto;margin-right:auto}.my-\[-0\.125rem\]{margin-top:-.125rem;margin-bottom:-.125rem}.-mt-0\.5{margin-top:-.125rem}.mb-0\.5{margin-bottom:.125rem}.ml-1{margin-left:.25rem}.mr-0{margin-right:0}.mt-0{margin-top:0}.mt-0\.5{margin-top:.125rem}.mt-1{margin-top:.25rem}.mt-\[0\.35vh\]{margin-top:.35vh}.mt-auto{margin-top:auto}.line-clamp-2{overflow:hidden;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:2}.\!block{display:block!important}.block{display:block}.inline-block{display:inline-block}.inline{display:inline}.flex{display:flex}.inline-flex{display:inline-flex}.grid{display:grid}.hidden{display:none}.aspect-\[4\/3\]{aspect-ratio:4/3}.aspect-square{aspect-ratio:1 / 1}.aspect-video{aspect-ratio:16 / 9}.h-1{height:.25rem}.h-1\.5{height:.375rem}.h-10{height:2.5rem}.h-2{height:.5rem}.h-28{height:7rem}.h-3{height:.75rem}.h-3\.5{height:.875rem}.h-4{height:1rem}.h-40{height:10rem}.h-48{height:12rem}.h-5{height:1.25rem}.h-64{height:16rem}.h-\[2px\]{height:2px}.h-\[3\.5rem\]{height:3.5rem}.h-\[70\%\]{height:70%}.h-\[7rem\]{height:7rem}.h-\[8vh\]{height:8vh}.h-\[calc\(1rem\+0\.25rem\)\]{height:1.25rem}.h-\[min\(100svh\,32rem\)\]{height:min(100svh,32rem)}.h-\[min\(60svh\,24rem\)\]{height:min(60svh,24rem)}.h-full{height:100%}.h-px{height:1px}.h-screen{height:100vh}.max-h-32{max-height:8rem}.max-h-40{max-height:10rem}.max-h-52{max-height:13rem}.max-h-72{max-height:18rem}.max-h-80{max-height:20rem}.max-h-\[14rem\]{max-height:14rem}.max-h-\[70vh\]{max-height:70vh}.max-h-\[72vh\]{max-height:72vh}.max-h-\[85vh\]{max-height:85vh}.max-h-\[90vh\]{max-height:90vh}.max-h-screen{max-height:100vh}.min-h-0{min-height:0px}.min-h-5{min-height:1.25rem}.min-h-9{min-height:2.25rem}.min-h-\[10rem\]{min-height:10rem}.min-h-\[14rem\]{min-height:14rem}.min-h-\[16rem\]{min-height:16rem}.min-h-\[3\.5rem\]{min-height:3.5rem}.min-h-\[4rem\]{min-height:4rem}.min-h-\[5rem\]{min-height:5rem}.min-h-screen{min-height:100vh}.w-1{width:.25rem}.w-1\.5{width:.375rem}.w-1\/2{width:50%}.w-10{width:2.5rem}.w-2{width:.5rem}.w-20{width:5rem}.w-3{width:.75rem}.w-3\.5{width:.875rem}.w-4{width:1rem}.w-5{width:1.25rem}.w-6{width:1.5rem}.w-\[12\.5rem\]{width:12.5rem}.w-\[12rem\]{width:12rem}.w-\[20rem\]{width:20rem}.w-\[2px\]{width:2px}.w-\[3\.25rem\]{width:3.25rem}.w-\[4\.5rem\]{width:4.5rem}.w-\[5\.5rem\]{width:5.5rem}.w-\[5rem\]{width:5rem}.w-\[9rem\]{width:9rem}.w-\[calc\(1rem\+0\.25rem\)\]{width:1.25rem}.w-\[min\(20rem\,calc\(100vw-1rem\)\)\]{width:min(20rem,calc(100vw - 1rem))}.w-auto{width:auto}.w-fit{width:-moz-fit-content;width:fit-content}.w-full{width:100%}.w-max{width:-moz-max-content;width:max-content}.w-px{width:1px}.w-screen{width:100vw}.min-w-0{min-width:0px}.min-w-28{min-width:7rem}.min-w-\[0\]{min-width:0}.min-w-\[3\.7rem\]{min-width:3.7rem}.min-w-\[9\.5rem\]{min-width:9.5rem}.max-w-2xl{max-width:42rem}.max-w-3xl{max-width:48rem}.max-w-4xl{max-width:56rem}.max-w-\[40vw\]{max-width:40vw}.max-w-\[70vw\]{max-width:70vw}.max-w-\[80vw\]{max-width:80vw}.max-w-\[92\%\]{max-width:92%}.max-w-\[92vw\]{max-width:92vw}.max-w-\[94\%\]{max-width:94%}.max-w-full{max-width:100%}.max-w-lg{max-width:32rem}.max-w-md{max-width:28rem}.max-w-sm{max-width:24rem}.max-w-xl{max-width:36rem}.flex-1{flex:1 1 0%}.flex-\[0\.72\]{flex:.72}.flex-\[1\.1\]{flex:1.1}.flex-\[1\.22\]{flex:1.22}.flex-\[1\.28\]{flex:1.28}.shrink{flex-shrink:1}.shrink-0{flex-shrink:0}.origin-top-left{transform-origin:top left}.-translate-x-1\/2{--tw-translate-x: -50%;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.-translate-y-1\/2{--tw-translate-y: -50%;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.rotate-180{--tw-rotate: 180deg;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.transform{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}@keyframes pulse{50%{opacity:.5}}.animate-pulse{animation:pulse 2s cubic-bezier(.4,0,.6,1) infinite}.cursor-default{cursor:default}.cursor-not-allowed{cursor:not-allowed}.cursor-pointer{cursor:pointer}.select-none{-webkit-user-select:none;-moz-user-select:none;user-select:none}.resize{resize:both}.auto-rows-fr{grid-auto-rows:minmax(0,1fr)}.grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}.grid-cols-\[1\.5rem_minmax\(0\,1fr\)_3rem\]{grid-template-columns:1.5rem minmax(0,1fr) 3rem}.grid-cols-\[auto_minmax\(0\,1fr\)\]{grid-template-columns:auto minmax(0,1fr)}.grid-cols-\[minmax\(0\,0\.7fr\)_minmax\(0\,2\.1fr\)_minmax\(0\,0\.7fr\)\]{grid-template-columns:minmax(0,.7fr) minmax(0,2.1fr) minmax(0,.7fr)}.grid-cols-\[minmax\(0\,1\.2fr\)_repeat\(4\,minmax\(0\,1fr\)\)\]{grid-template-columns:minmax(0,1.2fr) repeat(4,minmax(0,1fr))}.grid-cols-\[minmax\(0\,1\.35fr\)_minmax\(0\,0\.95fr\)\]{grid-template-columns:minmax(0,1.35fr) minmax(0,.95fr)}.grid-cols-\[minmax\(0\,1\.3fr\)_minmax\(0\,0\.22fr\)\]{grid-template-columns:minmax(0,1.3fr) minmax(0,.22fr)}.grid-cols-\[minmax\(0\,1\.45fr\)_minmax\(0\,0\.85fr\)\]{grid-template-columns:minmax(0,1.45fr) minmax(0,.85fr)}.grid-cols-\[minmax\(0\,1fr\)\]{grid-template-columns:minmax(0,1fr)}.grid-cols-\[minmax\(0\,1fr\)_2\.5rem\]{grid-template-columns:minmax(0,1fr) 2.5rem}.grid-cols-\[minmax\(0\,1fr\)_4\.75rem\]{grid-template-columns:minmax(0,1fr) 4.75rem}.grid-cols-\[minmax\(0\,1fr\)_auto\]{grid-template-columns:minmax(0,1fr) auto}.grid-cols-\[minmax\(0\,1fr\)_minmax\(0\,0\.7fr\)_minmax\(0\,1\.9fr\)_minmax\(0\,0\.7fr\)\]{grid-template-columns:minmax(0,1fr) minmax(0,.7fr) minmax(0,1.9fr) minmax(0,.7fr)}.grid-cols-\[minmax\(0\,1fr\)_minmax\(0\,0\.9fr\)_minmax\(0\,0\.75fr\)\]{grid-template-columns:minmax(0,1fr) minmax(0,.9fr) minmax(0,.75fr)}.grid-cols-\[minmax\(0\,1fr\)_minmax\(0\,1\.4fr\)\]{grid-template-columns:minmax(0,1fr) minmax(0,1.4fr)}.grid-cols-\[minmax\(0\,1fr\)_minmax\(0\,1fr\)\]{grid-template-columns:minmax(0,1fr) minmax(0,1fr)}.grid-rows-2{grid-template-rows:repeat(2,minmax(0,1fr))}.grid-rows-3{grid-template-rows:repeat(3,minmax(0,1fr))}.grid-rows-\[auto_1fr\]{grid-template-rows:auto 1fr}.grid-rows-\[auto_auto_1fr\]{grid-template-rows:auto auto 1fr}.grid-rows-\[auto_auto_1fr_auto\]{grid-template-rows:auto auto 1fr auto}.grid-rows-\[auto_minmax\(0\,1fr\)\]{grid-template-rows:auto minmax(0,1fr)}.grid-rows-\[auto_minmax\(0\,1fr\)_auto\]{grid-template-rows:auto minmax(0,1fr) auto}.grid-rows-\[minmax\(0\,1fr\)\]{grid-template-rows:minmax(0,1fr)}.grid-rows-\[minmax\(0\,1fr\)_auto\]{grid-template-rows:minmax(0,1fr) auto}.grid-rows-\[minmax\(0\,1fr\)_minmax\(0\,1fr\)_minmax\(0\,1fr\)\]{grid-template-rows:minmax(0,1fr) minmax(0,1fr) minmax(0,1fr)}.\!flex-row{flex-direction:row!important}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.place-items-center{place-items:center}.content-center{align-content:center}.content-start{align-content:flex-start}.items-start{align-items:flex-start}.items-end{align-items:flex-end}.items-center{align-items:center}.items-baseline{align-items:baseline}.items-stretch{align-items:stretch}.justify-start{justify-content:flex-start}.justify-end{justify-content:flex-end}.justify-center{justify-content:center}.justify-between{justify-content:space-between}.justify-stretch{justify-content:stretch}.gap-0\.5{gap:.125rem}.gap-1{gap:.25rem}.gap-1\.5{gap:.375rem}.gap-2{gap:.5rem}.gap-4{gap:1rem}.gap-\[0\.55vh\]{gap:.55vh}.gap-\[0\.8vw\]{gap:.8vw}.gap-\[1vw\]{gap:1vw}.gap-\[3vh\]{gap:3vh}.gap-x-3{-moz-column-gap:.75rem;column-gap:.75rem}.space-y-0\.5>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.125rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.125rem * var(--tw-space-y-reverse))}.space-y-1>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.25rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.25rem * var(--tw-space-y-reverse))}.space-y-2>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.5rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.5rem * var(--tw-space-y-reverse))}.self-start{align-self:flex-start}.self-stretch{align-self:stretch}.overflow-hidden{overflow:hidden}.overflow-visible{overflow:visible}.overflow-y-auto{overflow-y:auto}.truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.whitespace-nowrap{white-space:nowrap}.whitespace-pre-wrap{white-space:pre-wrap}.break-words{overflow-wrap:break-word}.break-all{word-break:break-all}.rounded{border-radius:.25rem}.rounded-full{border-radius:9999px}.rounded-lg{border-radius:.5rem}.rounded-md{border-radius:.375rem}.rounded-none{border-radius:0}.rounded-sm{border-radius:.125rem}.rounded-xl{border-radius:.75rem}.rounded-t{border-top-left-radius:.25rem;border-top-right-radius:.25rem}.border{border-width:1px}.border-2{border-width:2px}.border-4{border-width:4px}.border-b{border-bottom-width:1px}.border-l{border-left-width:1px}.border-l-4{border-left-width:4px}.border-r{border-right-width:1px}.border-t{border-top-width:1px}.border-amber-200{--tw-border-opacity: 1;border-color:rgb(253 230 138 / var(--tw-border-opacity))}.border-amber-200\/30{border-color:#fde68a4d}.border-amber-200\/70{border-color:#fde68ab3}.border-amber-200\/90{border-color:#fde68ae6}.border-amber-300\/70{border-color:#fcd34db3}.border-amber-300\/80{border-color:#fcd34dcc}.border-amber-400\/30{border-color:#fbbf244d}.border-amber-400\/60{border-color:#fbbf2499}.border-amber-600\/60{border-color:#d9770699}.border-amber-700\/60{border-color:#b4530999}.border-blue-600{--tw-border-opacity: 1;border-color:rgb(37 99 235 / var(--tw-border-opacity))}.border-cyan-200{--tw-border-opacity: 1;border-color:rgb(165 243 252 / var(--tw-border-opacity))}.border-cyan-200\/90{border-color:#a5f3fce6}.border-cyan-300{--tw-border-opacity: 1;border-color:rgb(103 232 249 / var(--tw-border-opacity))}.border-cyan-300\/70{border-color:#67e8f9b3}.border-cyan-300\/80{border-color:#67e8f9cc}.border-cyan-500\/40{border-color:#06b6d466}.border-emerald-100\/80{border-color:#d1fae5cc}.border-emerald-200{--tw-border-opacity: 1;border-color:rgb(167 243 208 / var(--tw-border-opacity))}.border-emerald-200\/70{border-color:#a7f3d0b3}.border-emerald-200\/90{border-color:#a7f3d0e6}.border-emerald-300{--tw-border-opacity: 1;border-color:rgb(110 231 183 / var(--tw-border-opacity))}.border-emerald-300\/70{border-color:#6ee7b7b3}.border-emerald-400\/60{border-color:#34d39999}.border-emerald-500\/40{border-color:#10b98166}.border-emerald-700\/60{border-color:#04785799}.border-emerald-700\/70{border-color:#047857b3}.border-emerald-950{--tw-border-opacity: 1;border-color:rgb(2 44 34 / var(--tw-border-opacity))}.border-fuchsia-300\/70{border-color:#f0abfcb3}.border-green-400{--tw-border-opacity: 1;border-color:rgb(74 222 128 / var(--tw-border-opacity))}.border-indigo-200\/70{border-color:#c7d2feb3}.border-indigo-200\/95{border-color:#c7d2fef2}.border-indigo-300\/70{border-color:#a5b4fcb3}.border-indigo-400\/30{border-color:#818cf84d}.border-indigo-700{--tw-border-opacity: 1;border-color:rgb(67 56 202 / var(--tw-border-opacity))}.border-indigo-700\/60{border-color:#4338ca99}.border-neutral-500\/50{border-color:#73737380}.border-neutral-500\/60{border-color:#73737399}.border-neutral-600{--tw-border-opacity: 1;border-color:rgb(82 82 82 / var(--tw-border-opacity))}.border-neutral-700{--tw-border-opacity: 1;border-color:rgb(64 64 64 / var(--tw-border-opacity))}.border-pink-200{--tw-border-opacity: 1;border-color:rgb(251 207 232 / var(--tw-border-opacity))}.border-red-100{--tw-border-opacity: 1;border-color:rgb(254 226 226 / var(--tw-border-opacity))}.border-red-200{--tw-border-opacity: 1;border-color:rgb(254 202 202 / var(--tw-border-opacity))}.border-red-300\/90{border-color:#fca5a5e6}.border-red-400{--tw-border-opacity: 1;border-color:rgb(248 113 113 / var(--tw-border-opacity))}.border-red-400\/60{border-color:#f8717199}.border-rose-300{--tw-border-opacity: 1;border-color:rgb(253 164 175 / var(--tw-border-opacity))}.border-sky-300{--tw-border-opacity: 1;border-color:rgb(125 211 252 / var(--tw-border-opacity))}.border-sky-400\/50{border-color:#38bdf880}.border-slate-200\/30{border-color:#e2e8f04d}.border-slate-400{--tw-border-opacity: 1;border-color:rgb(148 163 184 / var(--tw-border-opacity))}.border-slate-400\/60{border-color:#94a3b899}.border-slate-500\/70{border-color:#64748bb3}.border-slate-600{--tw-border-opacity: 1;border-color:rgb(71 85 105 / var(--tw-border-opacity))}.border-slate-600\/40{border-color:#47556966}.border-slate-600\/60{border-color:#47556999}.border-slate-600\/70{border-color:#475569b3}.border-slate-600\/80{border-color:#475569cc}.border-slate-700{--tw-border-opacity: 1;border-color:rgb(51 65 85 / var(--tw-border-opacity))}.border-slate-700\/60{border-color:#33415599}.border-slate-700\/70{border-color:#334155b3}.border-slate-700\/80{border-color:#334155cc}.border-slate-800{--tw-border-opacity: 1;border-color:rgb(30 41 59 / var(--tw-border-opacity))}.border-slate-800\/60{border-color:#1e293b99}.border-slate-800\/80{border-color:#1e293bcc}.border-transparent{border-color:transparent}.border-white{--tw-border-opacity: 1;border-color:rgb(255 255 255 / var(--tw-border-opacity))}.border-white\/40{border-color:#fff6}.border-white\/80{border-color:#fffc}.border-l-neutral-600{--tw-border-opacity: 1;border-left-color:rgb(82 82 82 / var(--tw-border-opacity))}.bg-amber-100\/95{background-color:#fef3c7f2}.bg-amber-400{--tw-bg-opacity: 1;background-color:rgb(251 191 36 / var(--tw-bg-opacity))}.bg-amber-400\/80{background-color:#fbbf24cc}.bg-amber-500{--tw-bg-opacity: 1;background-color:rgb(245 158 11 / var(--tw-bg-opacity))}.bg-amber-500\/30{background-color:#f59e0b4d}.bg-amber-600{--tw-bg-opacity: 1;background-color:rgb(217 119 6 / var(--tw-bg-opacity))}.bg-amber-600\/70{background-color:#d97706b3}.bg-amber-700\/20{background-color:#b4530933}.bg-amber-700\/30{background-color:#b453094d}.bg-amber-700\/35{background-color:#b4530959}.bg-amber-700\/80{background-color:#b45309cc}.bg-amber-800{--tw-bg-opacity: 1;background-color:rgb(146 64 14 / var(--tw-bg-opacity))}.bg-amber-900{--tw-bg-opacity: 1;background-color:rgb(120 53 15 / var(--tw-bg-opacity))}.bg-amber-900\/40{background-color:#78350f66}.bg-amber-900\/60{background-color:#78350f99}.bg-amber-900\/90{background-color:#78350fe6}.bg-amber-950\/70{background-color:#451a03b3}.bg-black{--tw-bg-opacity: 1;background-color:rgb(0 0 0 / var(--tw-bg-opacity))}.bg-black\/20{background-color:#0003}.bg-black\/30{background-color:#0000004d}.bg-black\/40{background-color:#0006}.bg-black\/45{background-color:#00000073}.bg-black\/50{background-color:#00000080}.bg-black\/55{background-color:#0000008c}.bg-black\/60{background-color:#0009}.bg-black\/70{background-color:#000000b3}.bg-black\/75{background-color:#000000bf}.bg-black\/80{background-color:#000c}.bg-black\/95{background-color:#000000f2}.bg-blue-500{--tw-bg-opacity: 1;background-color:rgb(59 130 246 / var(--tw-bg-opacity))}.bg-cyan-300{--tw-bg-opacity: 1;background-color:rgb(103 232 249 / var(--tw-bg-opacity))}.bg-cyan-500{--tw-bg-opacity: 1;background-color:rgb(6 182 212 / var(--tw-bg-opacity))}.bg-cyan-500\/80{background-color:#06b6d4cc}.bg-cyan-900{--tw-bg-opacity: 1;background-color:rgb(22 78 99 / var(--tw-bg-opacity))}.bg-cyan-900\/45{background-color:#164e6373}.bg-cyan-900\/90{background-color:#164e63e6}.bg-emerald-200{--tw-bg-opacity: 1;background-color:rgb(167 243 208 / var(--tw-bg-opacity))}.bg-emerald-400{--tw-bg-opacity: 1;background-color:rgb(52 211 153 / var(--tw-bg-opacity))}.bg-emerald-500{--tw-bg-opacity: 1;background-color:rgb(16 185 129 / var(--tw-bg-opacity))}.bg-emerald-500\/45{background-color:#10b98173}.bg-emerald-500\/80{background-color:#10b981cc}.bg-emerald-600{--tw-bg-opacity: 1;background-color:rgb(5 150 105 / var(--tw-bg-opacity))}.bg-emerald-600\/70{background-color:#059669b3}.bg-emerald-600\/80{background-color:#059669cc}.bg-emerald-700{--tw-bg-opacity: 1;background-color:rgb(4 120 87 / var(--tw-bg-opacity))}.bg-emerald-700\/20{background-color:#04785733}.bg-emerald-700\/60{background-color:#04785799}.bg-emerald-800{--tw-bg-opacity: 1;background-color:rgb(6 95 70 / var(--tw-bg-opacity))}.bg-emerald-900{--tw-bg-opacity: 1;background-color:rgb(6 78 59 / var(--tw-bg-opacity))}.bg-emerald-900\/60{background-color:#064e3b99}.bg-emerald-900\/90{background-color:#064e3be6}.bg-emerald-950{--tw-bg-opacity: 1;background-color:rgb(2 44 34 / var(--tw-bg-opacity))}.bg-emerald-950\/50{background-color:#022c2280}.bg-fuchsia-200{--tw-bg-opacity: 1;background-color:rgb(245 208 254 / var(--tw-bg-opacity))}.bg-fuchsia-600{--tw-bg-opacity: 1;background-color:rgb(192 38 211 / var(--tw-bg-opacity))}.bg-fuchsia-700{--tw-bg-opacity: 1;background-color:rgb(162 28 175 / var(--tw-bg-opacity))}.bg-fuchsia-800{--tw-bg-opacity: 1;background-color:rgb(134 25 143 / var(--tw-bg-opacity))}.bg-fuchsia-900\/45{background-color:#701a7573}.bg-green-600{--tw-bg-opacity: 1;background-color:rgb(22 163 74 / var(--tw-bg-opacity))}.bg-indigo-600{--tw-bg-opacity: 1;background-color:rgb(79 70 229 / var(--tw-bg-opacity))}.bg-indigo-600\/70{background-color:#4f46e5b3}.bg-indigo-900{--tw-bg-opacity: 1;background-color:rgb(49 46 129 / var(--tw-bg-opacity))}.bg-indigo-900\/60{background-color:#312e8199}.bg-indigo-950{--tw-bg-opacity: 1;background-color:rgb(30 27 75 / var(--tw-bg-opacity))}.bg-indigo-950\/90{background-color:#1e1b4be6}.bg-neutral-700{--tw-bg-opacity: 1;background-color:rgb(64 64 64 / var(--tw-bg-opacity))}.bg-neutral-800{--tw-bg-opacity: 1;background-color:rgb(38 38 38 / var(--tw-bg-opacity))}.bg-neutral-800\/80{background-color:#262626cc}.bg-neutral-900{--tw-bg-opacity: 1;background-color:rgb(23 23 23 / var(--tw-bg-opacity))}.bg-neutral-900\/100{background-color:#171717}.bg-neutral-900\/70{background-color:#171717b3}.bg-neutral-900\/95{background-color:#171717f2}.bg-neutral-950{--tw-bg-opacity: 1;background-color:rgb(10 10 10 / var(--tw-bg-opacity))}.bg-pink-500{--tw-bg-opacity: 1;background-color:rgb(236 72 153 / var(--tw-bg-opacity))}.bg-red-500{--tw-bg-opacity: 1;background-color:rgb(239 68 68 / var(--tw-bg-opacity))}.bg-red-500\/45{background-color:#ef444473}.bg-red-600{--tw-bg-opacity: 1;background-color:rgb(220 38 38 / var(--tw-bg-opacity))}.bg-red-600\/70{background-color:#dc2626b3}.bg-red-700{--tw-bg-opacity: 1;background-color:rgb(185 28 28 / var(--tw-bg-opacity))}.bg-red-700\/20{background-color:#b91c1c33}.bg-red-700\/60{background-color:#b91c1c99}.bg-red-800{--tw-bg-opacity: 1;background-color:rgb(153 27 27 / var(--tw-bg-opacity))}.bg-red-900\/35{background-color:#7f1d1d59}.bg-red-900\/40{background-color:#7f1d1d66}.bg-red-900\/45{background-color:#7f1d1d73}.bg-red-900\/50{background-color:#7f1d1d80}.bg-red-900\/80{background-color:#7f1d1dcc}.bg-rose-500{--tw-bg-opacity: 1;background-color:rgb(244 63 94 / var(--tw-bg-opacity))}.bg-rose-600{--tw-bg-opacity: 1;background-color:rgb(225 29 72 / var(--tw-bg-opacity))}.bg-sky-600{--tw-bg-opacity: 1;background-color:rgb(2 132 199 / var(--tw-bg-opacity))}.bg-sky-700\/20{background-color:#0369a133}.bg-slate-300{--tw-bg-opacity: 1;background-color:rgb(203 213 225 / var(--tw-bg-opacity))}.bg-slate-500{--tw-bg-opacity: 1;background-color:rgb(100 116 139 / var(--tw-bg-opacity))}.bg-slate-600{--tw-bg-opacity: 1;background-color:rgb(71 85 105 / var(--tw-bg-opacity))}.bg-slate-600\/70{background-color:#475569b3}.bg-slate-700{--tw-bg-opacity: 1;background-color:rgb(51 65 85 / var(--tw-bg-opacity))}.bg-slate-700\/30{background-color:#3341554d}.bg-slate-700\/60{background-color:#33415599}.bg-slate-700\/70{background-color:#334155b3}.bg-slate-700\/80{background-color:#334155cc}.bg-slate-800{--tw-bg-opacity: 1;background-color:rgb(30 41 59 / var(--tw-bg-opacity))}.bg-slate-800\/60{background-color:#1e293b99}.bg-slate-800\/70{background-color:#1e293bb3}.bg-slate-800\/80{background-color:#1e293bcc}.bg-slate-900{--tw-bg-opacity: 1;background-color:rgb(15 23 42 / var(--tw-bg-opacity))}.bg-slate-900\/35{background-color:#0f172a59}.bg-slate-900\/40{background-color:#0f172a66}.bg-slate-900\/70{background-color:#0f172ab3}.bg-slate-950{--tw-bg-opacity: 1;background-color:rgb(2 6 23 / var(--tw-bg-opacity))}.bg-slate-950\/80{background-color:#020617cc}.bg-slate-950\/90{background-color:#020617e6}.bg-transparent{background-color:transparent}.bg-white{--tw-bg-opacity: 1;background-color:rgb(255 255 255 / var(--tw-bg-opacity))}.bg-white\/10{background-color:#ffffff1a}.bg-yellow-100{--tw-bg-opacity: 1;background-color:rgb(254 249 195 / var(--tw-bg-opacity))}.bg-yellow-500{--tw-bg-opacity: 1;background-color:rgb(234 179 8 / var(--tw-bg-opacity))}.bg-zinc-900{--tw-bg-opacity: 1;background-color:rgb(24 24 27 / var(--tw-bg-opacity))}.bg-zinc-900\/90{background-color:#18181be6}.bg-gradient-to-r{background-image:linear-gradient(to right,var(--tw-gradient-stops))}.from-lime-800{--tw-gradient-from: #3f6212 var(--tw-gradient-from-position);--tw-gradient-to: rgb(63 98 18 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to)}.from-neutral-800{--tw-gradient-from: #262626 var(--tw-gradient-from-position);--tw-gradient-to: rgb(38 38 38 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to)}.via-neutral-700{--tw-gradient-to: rgb(64 64 64 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), #404040 var(--tw-gradient-via-position), var(--tw-gradient-to)}.to-neutral-600{--tw-gradient-to: #525252 var(--tw-gradient-to-position)}.to-teal-800{--tw-gradient-to: #115e59 var(--tw-gradient-to-position)}.bg-cover{background-size:cover}.bg-center{background-position:center}.bg-no-repeat{background-repeat:no-repeat}.fill-slate-200{fill:#e2e8f0}.object-contain{-o-object-fit:contain;object-fit:contain}.object-cover{-o-object-fit:cover;object-fit:cover}.p-0{padding:0}.p-0\.5{padding:.125rem}.p-1{padding:.25rem}.p-2{padding:.5rem}.p-4{padding:1rem}.p-\[0\.85vw\]{padding:.85vw}.px-0{padding-left:0;padding-right:0}.px-0\.5{padding-left:.125rem;padding-right:.125rem}.px-1{padding-left:.25rem;padding-right:.25rem}.px-1\.5{padding-left:.375rem;padding-right:.375rem}.px-2{padding-left:.5rem;padding-right:.5rem}.px-3{padding-left:.75rem;padding-right:.75rem}.px-4{padding-left:1rem;padding-right:1rem}.px-6{padding-left:1.5rem;padding-right:1.5rem}.px-\[1\.6vw\]{padding-left:1.6vw;padding-right:1.6vw}.px-\[1vw\]{padding-left:1vw;padding-right:1vw}.px-\[3vw\]{padding-left:3vw;padding-right:3vw}.px-\[4vw\]{padding-left:4vw;padding-right:4vw}.py-0{padding-top:0;padding-bottom:0}.py-0\.5{padding-top:.125rem;padding-bottom:.125rem}.py-1{padding-top:.25rem;padding-bottom:.25rem}.py-1\.5{padding-top:.375rem;padding-bottom:.375rem}.py-2{padding-top:.5rem;padding-bottom:.5rem}.py-3{padding-top:.75rem;padding-bottom:.75rem}.py-4{padding-top:1rem;padding-bottom:1rem}.py-\[0\.55vh\]{padding-top:.55vh;padding-bottom:.55vh}.py-\[1px\]{padding-top:1px;padding-bottom:1px}.py-\[2\.5vh\]{padding-top:2.5vh;padding-bottom:2.5vh}.py-\[2px\]{padding-top:2px;padding-bottom:2px}.py-\[4vh\]{padding-top:4vh;padding-bottom:4vh}.pb-0{padding-bottom:0}.pb-1{padding-bottom:.25rem}.pb-3{padding-bottom:.75rem}.pr-0{padding-right:0}.pt-1{padding-top:.25rem}.pt-5{padding-top:1.25rem}.text-left{text-align:left}.text-center{text-align:center}.text-right{text-align:right}.align-top{vertical-align:top}.align-middle{vertical-align:middle}.font-mono{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace}.text-2xl{font-size:1.5rem;line-height:2rem}.text-3xl{font-size:1.875rem;line-height:2.25rem}.text-4xl{font-size:2.25rem;line-height:2.5rem}.text-5xl{font-size:3rem;line-height:1}.text-\[0\.45rem\]{font-size:.45rem}.text-\[0\.55em\]{font-size:.55em}.text-\[0\.55rem\]{font-size:.55rem}.text-\[0\.58rem\]{font-size:.58rem}.text-\[0\.5rem\]{font-size:.5rem}.text-\[0\.62rem\]{font-size:.62rem}.text-\[0\.65rem\]{font-size:.65rem}.text-\[0\.68rem\]{font-size:.68rem}.text-\[0\.6rem\]{font-size:.6rem}.text-\[0\.72rem\]{font-size:.72rem}.text-\[0\.75rem\]{font-size:.75rem}.text-\[0\.78rem\]{font-size:.78rem}.text-\[0\.7rem\]{font-size:.7rem}.text-\[0\.82rem\]{font-size:.82rem}.text-\[0\.85rem\]{font-size:.85rem}.text-\[0\.8rem\]{font-size:.8rem}.text-\[1\.1rem\]{font-size:1.1rem}.text-\[1\.5rem\]{font-size:1.5rem}.text-\[17vw\]{font-size:17vw}.text-\[1rem\]{font-size:1rem}.text-\[2\.5vw\]{font-size:2.5vw}.text-\[3vw\]{font-size:3vw}.text-\[4vw\]{font-size:4vw}.text-\[6vw\]{font-size:6vw}.text-\[7vw\]{font-size:7vw}.text-\[clamp\(1\.25rem\,2\.5vh\,2\.6rem\)\]{font-size:clamp(1.25rem,2.5vh,2.6rem)}.text-\[clamp\(1\.2rem\,2\.9vh\,3rem\)\]{font-size:clamp(1.2rem,2.9vh,3rem)}.text-\[clamp\(2\.5rem\,5\.3vh\,5\.8rem\)\]{font-size:clamp(2.5rem,5.3vh,5.8rem)}.text-\[clamp\(2\.5rem\,7vh\,7rem\)\]{font-size:clamp(2.5rem,7vh,7rem)}.text-\[clamp\(2\.5rem\,8vh\,8rem\)\]{font-size:clamp(2.5rem,8vh,8rem)}.text-\[clamp\(2rem\,5vh\,5\.2rem\)\]{font-size:clamp(2rem,5vh,5.2rem)}.text-\[clamp\(3\.2rem\,11vh\,11rem\)\]{font-size:clamp(3.2rem,11vh,11rem)}.text-base{font-size:1rem;line-height:1.5rem}.text-lg{font-size:1.125rem;line-height:1.75rem}.text-sm{font-size:.875rem;line-height:1.25rem}.text-xl{font-size:1.25rem;line-height:1.75rem}.text-xs{font-size:.75rem;line-height:1rem}.font-black{font-weight:900}.font-bold{font-weight:700}.font-medium{font-weight:500}.font-normal{font-weight:400}.font-semibold{font-weight:600}.uppercase{text-transform:uppercase}.lowercase{text-transform:lowercase}.capitalize{text-transform:capitalize}.italic{font-style:italic}.leading-\[0\.95\]{line-height:.95}.leading-none{line-height:1}.leading-snug{line-height:1.375}.leading-tight{line-height:1.25}.tracking-normal{letter-spacing:0em}.tracking-tight{letter-spacing:-.025em}.tracking-wide{letter-spacing:.025em}.text-amber-100{--tw-text-opacity: 1;color:rgb(254 243 199 / var(--tw-text-opacity))}.text-amber-200{--tw-text-opacity: 1;color:rgb(253 230 138 / var(--tw-text-opacity))}.text-amber-200\/80{color:#fde68acc}.text-amber-200\/85{color:#fde68ad9}.text-amber-300{--tw-text-opacity: 1;color:rgb(252 211 77 / var(--tw-text-opacity))}.text-amber-400{--tw-text-opacity: 1;color:rgb(251 191 36 / var(--tw-text-opacity))}.text-amber-50{--tw-text-opacity: 1;color:rgb(255 251 235 / var(--tw-text-opacity))}.text-amber-50\/90{color:#fffbebe6}.text-amber-950{--tw-text-opacity: 1;color:rgb(69 26 3 / var(--tw-text-opacity))}.text-black{--tw-text-opacity: 1;color:rgb(0 0 0 / var(--tw-text-opacity))}.text-blue-300{--tw-text-opacity: 1;color:rgb(147 197 253 / var(--tw-text-opacity))}.text-blue-400{--tw-text-opacity: 1;color:rgb(96 165 250 / var(--tw-text-opacity))}.text-blue-800{--tw-text-opacity: 1;color:rgb(30 64 175 / var(--tw-text-opacity))}.text-cyan-200{--tw-text-opacity: 1;color:rgb(165 243 252 / var(--tw-text-opacity))}.text-cyan-300{--tw-text-opacity: 1;color:rgb(103 232 249 / var(--tw-text-opacity))}.text-cyan-50{--tw-text-opacity: 1;color:rgb(236 254 255 / var(--tw-text-opacity))}.text-emerald-100{--tw-text-opacity: 1;color:rgb(209 250 229 / var(--tw-text-opacity))}.text-emerald-100\/80{color:#d1fae5cc}.text-emerald-200{--tw-text-opacity: 1;color:rgb(167 243 208 / var(--tw-text-opacity))}.text-emerald-300{--tw-text-opacity: 1;color:rgb(110 231 183 / var(--tw-text-opacity))}.text-emerald-400{--tw-text-opacity: 1;color:rgb(52 211 153 / var(--tw-text-opacity))}.text-emerald-50{--tw-text-opacity: 1;color:rgb(236 253 245 / var(--tw-text-opacity))}.text-emerald-50\/90{color:#ecfdf5e6}.text-emerald-950{--tw-text-opacity: 1;color:rgb(2 44 34 / var(--tw-text-opacity))}.text-fuchsia-50{--tw-text-opacity: 1;color:rgb(253 244 255 / var(--tw-text-opacity))}.text-fuchsia-900{--tw-text-opacity: 1;color:rgb(112 26 117 / var(--tw-text-opacity))}.text-indigo-200{--tw-text-opacity: 1;color:rgb(199 210 254 / var(--tw-text-opacity))}.text-indigo-50{--tw-text-opacity: 1;color:rgb(238 242 255 / var(--tw-text-opacity))}.text-indigo-50\/90{color:#eef2ffe6}.text-lime-300{--tw-text-opacity: 1;color:rgb(190 242 100 / var(--tw-text-opacity))}.text-lime-400{--tw-text-opacity: 1;color:rgb(163 230 53 / var(--tw-text-opacity))}.text-neutral-100{--tw-text-opacity: 1;color:rgb(245 245 245 / var(--tw-text-opacity))}.text-neutral-200{--tw-text-opacity: 1;color:rgb(229 229 229 / var(--tw-text-opacity))}.text-neutral-300{--tw-text-opacity: 1;color:rgb(212 212 212 / var(--tw-text-opacity))}.text-neutral-400{--tw-text-opacity: 1;color:rgb(163 163 163 / var(--tw-text-opacity))}.text-neutral-50{--tw-text-opacity: 1;color:rgb(250 250 250 / var(--tw-text-opacity))}.text-neutral-500{--tw-text-opacity: 1;color:rgb(115 115 115 / var(--tw-text-opacity))}.text-red-100{--tw-text-opacity: 1;color:rgb(254 226 226 / var(--tw-text-opacity))}.text-red-100\/90{color:#fee2e2e6}.text-red-100\/95{color:#fee2e2f2}.text-red-200{--tw-text-opacity: 1;color:rgb(254 202 202 / var(--tw-text-opacity))}.text-red-300{--tw-text-opacity: 1;color:rgb(252 165 165 / var(--tw-text-opacity))}.text-red-400{--tw-text-opacity: 1;color:rgb(248 113 113 / var(--tw-text-opacity))}.text-red-50{--tw-text-opacity: 1;color:rgb(254 242 242 / var(--tw-text-opacity))}.text-red-700{--tw-text-opacity: 1;color:rgb(185 28 28 / var(--tw-text-opacity))}.text-rose-300{--tw-text-opacity: 1;color:rgb(253 164 175 / var(--tw-text-opacity))}.text-sky-200{--tw-text-opacity: 1;color:rgb(186 230 253 / var(--tw-text-opacity))}.text-sky-300{--tw-text-opacity: 1;color:rgb(125 211 252 / var(--tw-text-opacity))}.text-slate-100{--tw-text-opacity: 1;color:rgb(241 245 249 / var(--tw-text-opacity))}.text-slate-200{--tw-text-opacity: 1;color:rgb(226 232 240 / var(--tw-text-opacity))}.text-slate-300{--tw-text-opacity: 1;color:rgb(203 213 225 / var(--tw-text-opacity))}.text-slate-400{--tw-text-opacity: 1;color:rgb(148 163 184 / var(--tw-text-opacity))}.text-slate-400\/60{color:#94a3b899}.text-slate-500{--tw-text-opacity: 1;color:rgb(100 116 139 / var(--tw-text-opacity))}.text-slate-900{--tw-text-opacity: 1;color:rgb(15 23 42 / var(--tw-text-opacity))}.text-slate-950{--tw-text-opacity: 1;color:rgb(2 6 23 / var(--tw-text-opacity))}.text-teal-400{--tw-text-opacity: 1;color:rgb(45 212 191 / var(--tw-text-opacity))}.text-white{--tw-text-opacity: 1;color:rgb(255 255 255 / var(--tw-text-opacity))}.text-white\/90{color:#ffffffe6}.text-yellow-400{--tw-text-opacity: 1;color:rgb(250 204 21 / var(--tw-text-opacity))}.underline{text-decoration-line:underline}.accent-cyan-500{accent-color:#06b6d4}.accent-emerald-400{accent-color:#34d399}.accent-emerald-500{accent-color:#10b981}.opacity-0{opacity:0}.opacity-100{opacity:1}.opacity-40{opacity:.4}.opacity-50{opacity:.5}.opacity-70{opacity:.7}.opacity-80{opacity:.8}.opacity-85{opacity:.85}.opacity-90{opacity:.9}.shadow{--tw-shadow: 0 1px 3px 0 rgb(0 0 0 / .1), 0 1px 2px -1px rgb(0 0 0 / .1);--tw-shadow-colored: 0 1px 3px 0 var(--tw-shadow-color), 0 1px 2px -1px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-2xl{--tw-shadow: 0 25px 50px -12px rgb(0 0 0 / .25);--tw-shadow-colored: 0 25px 50px -12px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-\[0_1px_0_rgba\(255\,255\,255\,0\.05\)_inset\,0_10px_24px_rgba\(0\,0\,0\,0\.28\)\]{--tw-shadow: 0 1px 0 rgba(255,255,255,.05) inset,0 10px 24px rgba(0,0,0,.28);--tw-shadow-colored: inset 0 1px 0 var(--tw-shadow-color), 0 10px 24px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-inner{--tw-shadow: inset 0 2px 4px 0 rgb(0 0 0 / .05);--tw-shadow-colored: inset 0 2px 4px 0 var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-lg{--tw-shadow: 0 10px 15px -3px rgb(0 0 0 / .1), 0 4px 6px -4px rgb(0 0 0 / .1);--tw-shadow-colored: 0 10px 15px -3px var(--tw-shadow-color), 0 4px 6px -4px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-md{--tw-shadow: 0 4px 6px -1px rgb(0 0 0 / .1), 0 2px 4px -2px rgb(0 0 0 / .1);--tw-shadow-colored: 0 4px 6px -1px var(--tw-shadow-color), 0 2px 4px -2px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-sm{--tw-shadow: 0 1px 2px 0 rgb(0 0 0 / .05);--tw-shadow-colored: 0 1px 2px 0 var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-xl{--tw-shadow: 0 20px 25px -5px rgb(0 0 0 / .1), 0 8px 10px -6px rgb(0 0 0 / .1);--tw-shadow-colored: 0 20px 25px -5px var(--tw-shadow-color), 0 8px 10px -6px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-black\/30{--tw-shadow-color: rgb(0 0 0 / .3);--tw-shadow: var(--tw-shadow-colored)}.shadow-cyan-950\/50{--tw-shadow-color: rgb(8 51 68 / .5);--tw-shadow: var(--tw-shadow-colored)}.ring-1{--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000)}.ring-2{--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000)}.ring-4{--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(4px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000)}.ring-amber-300{--tw-ring-opacity: 1;--tw-ring-color: rgb(252 211 77 / var(--tw-ring-opacity))}.ring-amber-300\/80{--tw-ring-color: rgb(252 211 77 / .8)}.ring-emerald-300\/70{--tw-ring-color: rgb(110 231 183 / .7)}.ring-red-500\/80{--tw-ring-color: rgb(239 68 68 / .8)}.ring-red-500\/90{--tw-ring-color: rgb(239 68 68 / .9)}.ring-sky-400\/80{--tw-ring-color: rgb(56 189 248 / .8)}.blur{--tw-blur: blur(8px);filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.grayscale{--tw-grayscale: grayscale(100%);filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.invert{--tw-invert: invert(100%);filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.sepia{--tw-sepia: sepia(100%);filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.filter{filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.backdrop-blur-sm{--tw-backdrop-blur: blur(4px);-webkit-backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia);backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia)}.transition{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-\[width\,height\]{transition-property:width,height;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-colors{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-opacity{transition-property:opacity;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-transform{transition-property:transform;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.duration-500{transition-duration:.5s}.duration-700{transition-duration:.7s}@keyframes batteryTickWarn{0%,49%{background-color:#fffffff2}50%,to{background-color:#ef4444f2}}.battery-tick-warn{animation:batteryTickWarn .4s steps(2,end) infinite}@keyframes batteryUrgentFlash{0%,49%{opacity:1}50%,to{opacity:.25}}.battery-urgent-flash{animation:batteryUrgentFlash .4s steps(2,end) infinite}.no-touch-select{-moz-user-select:none;user-select:none;-webkit-user-select:none;-ms-user-select:none;-webkit-touch-callout:none}.mobile-touch-control{user-select:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;-webkit-touch-callout:none;-webkit-tap-highlight-color:transparent;touch-action:manipulation;overscroll-behavior:contain}.mobile-drag-control{touch-action:none}.mobile-text-entry{font-size:16px;-webkit-text-size-adjust:100%;touch-action:manipulation}.\[writing-mode\:vertical-rl\]{writing-mode:vertical-rl}:root{font-family:Inter,system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,sans-serif;--tw-bg-opacity: 1;background-color:rgb(0 0 0 / var(--tw-bg-opacity));--tw-text-opacity: 1;color:rgb(241 245 249 / var(--tw-text-opacity))}body{margin:0;min-height:100vh;--tw-bg-opacity: 1;background-color:rgb(0 0 0 / var(--tw-bg-opacity));--tw-text-opacity: 1;color:rgb(241 245 249 / var(--tw-text-opacity))}html,body,*{scrollbar-width:thin;scrollbar-color:rgba(148,163,184,.55) transparent}@keyframes spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}*::-webkit-scrollbar{width:2px;height:2px}*::-webkit-scrollbar-track{background:transparent}*::-webkit-scrollbar-thumb{background-color:#94a3b88c;border-radius:9999px}@supports (scrollbar-width: thin){@media(pointer:coarse){html,body,*{scrollbar-width:none}}}.placeholder\:text-slate-400::-moz-placeholder{--tw-text-opacity: 1;color:rgb(148 163 184 / var(--tw-text-opacity))}.placeholder\:text-slate-400::placeholder{--tw-text-opacity: 1;color:rgb(148 163 184 / var(--tw-text-opacity))}.last\:mb-0:last-child{margin-bottom:0}.hover\:-translate-y-0\.5:hover{--tw-translate-y: -.125rem;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.hover\:scale-110:hover{--tw-scale-x: 1.1;--tw-scale-y: 1.1;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.hover\:border-green-100:hover{--tw-border-opacity: 1;border-color:rgb(220 252 231 / var(--tw-border-opacity))}.hover\:border-rose-500:hover{--tw-border-opacity: 1;border-color:rgb(244 63 94 / var(--tw-border-opacity))}.hover\:border-sky-500:hover{--tw-border-opacity: 1;border-color:rgb(14 165 233 / var(--tw-border-opacity))}.hover\:border-white:hover{--tw-border-opacity: 1;border-color:rgb(255 255 255 / var(--tw-border-opacity))}.hover\:border-white\/60:hover{border-color:#fff9}.hover\:bg-amber-400:hover{--tw-bg-opacity: 1;background-color:rgb(251 191 36 / var(--tw-bg-opacity))}.hover\:bg-amber-600:hover{--tw-bg-opacity: 1;background-color:rgb(217 119 6 / var(--tw-bg-opacity))}.hover\:bg-amber-800:hover{--tw-bg-opacity: 1;background-color:rgb(146 64 14 / var(--tw-bg-opacity))}.hover\:bg-cyan-400:hover{--tw-bg-opacity: 1;background-color:rgb(34 211 238 / var(--tw-bg-opacity))}.hover\:bg-cyan-800:hover{--tw-bg-opacity: 1;background-color:rgb(21 94 117 / var(--tw-bg-opacity))}.hover\:bg-emerald-400:hover{--tw-bg-opacity: 1;background-color:rgb(52 211 153 / var(--tw-bg-opacity))}.hover\:bg-emerald-500:hover{--tw-bg-opacity: 1;background-color:rgb(16 185 129 / var(--tw-bg-opacity))}.hover\:bg-emerald-700:hover{--tw-bg-opacity: 1;background-color:rgb(4 120 87 / var(--tw-bg-opacity))}.hover\:bg-fuchsia-500:hover{--tw-bg-opacity: 1;background-color:rgb(217 70 239 / var(--tw-bg-opacity))}.hover\:bg-green-400:hover{--tw-bg-opacity: 1;background-color:rgb(74 222 128 / var(--tw-bg-opacity))}.hover\:bg-indigo-500:hover{--tw-bg-opacity: 1;background-color:rgb(99 102 241 / var(--tw-bg-opacity))}.hover\:bg-indigo-800:hover{--tw-bg-opacity: 1;background-color:rgb(55 48 163 / var(--tw-bg-opacity))}.hover\:bg-neutral-700:hover{--tw-bg-opacity: 1;background-color:rgb(64 64 64 / var(--tw-bg-opacity))}.hover\:bg-pink-400:hover{--tw-bg-opacity: 1;background-color:rgb(244 114 182 / var(--tw-bg-opacity))}.hover\:bg-red-600:hover{--tw-bg-opacity: 1;background-color:rgb(220 38 38 / var(--tw-bg-opacity))}.hover\:bg-rose-500:hover{--tw-bg-opacity: 1;background-color:rgb(244 63 94 / var(--tw-bg-opacity))}.hover\:bg-sky-500:hover{--tw-bg-opacity: 1;background-color:rgb(14 165 233 / var(--tw-bg-opacity))}.hover\:bg-slate-600:hover{--tw-bg-opacity: 1;background-color:rgb(71 85 105 / var(--tw-bg-opacity))}.hover\:bg-slate-700\/70:hover{background-color:#334155b3}.hover\:bg-zinc-900:hover{--tw-bg-opacity: 1;background-color:rgb(24 24 27 / var(--tw-bg-opacity))}.hover\:text-blue-500:hover{--tw-text-opacity: 1;color:rgb(59 130 246 / var(--tw-text-opacity))}.hover\:text-white:hover{--tw-text-opacity: 1;color:rgb(255 255 255 / var(--tw-text-opacity))}.hover\:opacity-90:hover{opacity:.9}.hover\:shadow-xl:hover{--tw-shadow: 0 20px 25px -5px rgb(0 0 0 / .1), 0 8px 10px -6px rgb(0 0 0 / .1);--tw-shadow-colored: 0 20px 25px -5px var(--tw-shadow-color), 0 8px 10px -6px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.hover\:brightness-110:hover{--tw-brightness: brightness(1.1);filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.focus\:outline-none:focus{outline:2px solid transparent;outline-offset:2px}.focus\:ring-emerald-500:focus{--tw-ring-opacity: 1;--tw-ring-color: rgb(16 185 129 / var(--tw-ring-opacity))}.focus-visible\:outline-none:focus-visible{outline:2px solid transparent;outline-offset:2px}.focus-visible\:outline:focus-visible{outline-style:solid}.focus-visible\:outline-1:focus-visible{outline-width:1px}.focus-visible\:outline-offset-1:focus-visible{outline-offset:1px}.focus-visible\:outline-slate-500:focus-visible{outline-color:#64748b}.focus-visible\:ring-2:focus-visible{--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000)}.focus-visible\:ring-amber-300:focus-visible{--tw-ring-opacity: 1;--tw-ring-color: rgb(252 211 77 / var(--tw-ring-opacity))}.focus-visible\:ring-cyan-300:focus-visible{--tw-ring-opacity: 1;--tw-ring-color: rgb(103 232 249 / var(--tw-ring-opacity))}.focus-visible\:ring-emerald-200:focus-visible{--tw-ring-opacity: 1;--tw-ring-color: rgb(167 243 208 / var(--tw-ring-opacity))}.focus-visible\:ring-emerald-300:focus-visible{--tw-ring-opacity: 1;--tw-ring-color: rgb(110 231 183 / var(--tw-ring-opacity))}.focus-visible\:ring-indigo-300:focus-visible{--tw-ring-opacity: 1;--tw-ring-color: rgb(165 180 252 / var(--tw-ring-opacity))}.active\:scale-95:active{--tw-scale-x: .95;--tw-scale-y: .95;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.active\:scale-\[0\.99\]:active{--tw-scale-x: .99;--tw-scale-y: .99;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.active\:brightness-125:active{--tw-brightness: brightness(1.25);filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.disabled\:cursor-not-allowed:disabled{cursor:not-allowed}.disabled\:opacity-30:disabled{opacity:.3}.disabled\:opacity-40:disabled{opacity:.4}.disabled\:opacity-50:disabled{opacity:.5}.disabled\:opacity-60:disabled{opacity:.6}.disabled\:opacity-70:disabled{opacity:.7}@media(max-width:520px){.max-\[520px\]\:grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.max-\[520px\]\:justify-start{justify-content:flex-start}}@media(max-width:420px){.max-\[420px\]\:grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.max-\[420px\]\:grid-cols-\[auto_minmax\(0\,1fr\)\]{grid-template-columns:auto minmax(0,1fr)}.max-\[420px\]\:justify-start{justify-content:flex-start}}@media(min-width:640px){.sm\:block{display:block}.sm\:min-h-\[18rem\]{min-height:18rem}.sm\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.sm\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.sm\:text-2xl{font-size:1.5rem;line-height:2rem}.sm\:text-3xl{font-size:1.875rem;line-height:2.25rem}}@media(min-width:768px){.md\:h-full{height:100%}.md\:h-screen{height:100vh}.md\:min-h-0{min-height:0px}.md\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.md\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.md\:grid-cols-\[0\.9fr_1fr_1\.3fr\]{grid-template-columns:.9fr 1fr 1.3fr}.md\:grid-cols-\[minmax\(0\,1\.4fr\)_minmax\(0\,1fr\)\]{grid-template-columns:minmax(0,1.4fr) minmax(0,1fr)}.md\:grid-cols-\[minmax\(0\,1\.5fr\)_minmax\(0\,1fr\)\]{grid-template-columns:minmax(0,1.5fr) minmax(0,1fr)}.md\:grid-cols-\[minmax\(0\,1fr\)_18rem\]{grid-template-columns:minmax(0,1fr) 18rem}.md\:overflow-hidden{overflow:hidden}.md\:overflow-y-auto{overflow-y:auto}.md\:text-lg{font-size:1.125rem;line-height:1.75rem}.md\:text-xl{font-size:1.25rem;line-height:1.75rem}}@media(min-width:1024px){.lg\:col-span-2{grid-column:span 2 / span 2}.lg\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.lg\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.lg\:grid-cols-6{grid-template-columns:repeat(6,minmax(0,1fr))}.lg\:grid-cols-\[minmax\(0\,1\.25fr\)_minmax\(0\,0\.9fr\)\]{grid-template-columns:minmax(0,1.25fr) minmax(0,.9fr)}.lg\:grid-cols-\[minmax\(0\,1fr\)_20rem\]{grid-template-columns:minmax(0,1fr) 20rem}.lg\:grid-cols-\[minmax\(0\,1fr\)_9rem_10rem\]{grid-template-columns:minmax(0,1fr) 9rem 10rem}.lg\:text-right{text-align:right}} diff --git a/server/public/assets/index-iL5XsC62.css b/server/public/assets/index-iL5XsC62.css deleted file mode 100644 index 7da91a57..00000000 --- a/server/public/assets/index-iL5XsC62.css +++ /dev/null @@ -1 +0,0 @@ -*,:before,:after{--tw-border-spacing-x: 0;--tw-border-spacing-y: 0;--tw-translate-x: 0;--tw-translate-y: 0;--tw-rotate: 0;--tw-skew-x: 0;--tw-skew-y: 0;--tw-scale-x: 1;--tw-scale-y: 1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness: proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-color: rgb(59 130 246 / .5);--tw-ring-offset-shadow: 0 0 #0000;--tw-ring-shadow: 0 0 #0000;--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }::backdrop{--tw-border-spacing-x: 0;--tw-border-spacing-y: 0;--tw-translate-x: 0;--tw-translate-y: 0;--tw-rotate: 0;--tw-skew-x: 0;--tw-skew-y: 0;--tw-scale-x: 1;--tw-scale-y: 1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness: proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-color: rgb(59 130 246 / .5);--tw-ring-offset-shadow: 0 0 #0000;--tw-ring-shadow: 0 0 #0000;--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }*,:before,:after{box-sizing:border-box;border-width:0;border-style:solid;border-color:#e5e7eb}:before,:after{--tw-content: ""}html,:host{line-height:1.5;-webkit-text-size-adjust:100%;-moz-tab-size:4;-o-tab-size:4;tab-size:4;font-family:ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji",Segoe UI Symbol,"Noto Color Emoji";font-feature-settings:normal;font-variation-settings:normal;-webkit-tap-highlight-color:transparent}body{margin:0;line-height:inherit}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-feature-settings:normal;font-variation-settings:normal;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}button,input,optgroup,select,textarea{font-family:inherit;font-feature-settings:inherit;font-variation-settings:inherit;font-size:100%;font-weight:inherit;line-height:inherit;letter-spacing:inherit;color:inherit;margin:0;padding:0}button,select{text-transform:none}button,input:where([type=button]),input:where([type=reset]),input:where([type=submit]){-webkit-appearance:button;background-color:transparent;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:baseline}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dl,dd,h1,h2,h3,h4,h5,h6,hr,figure,p,pre{margin:0}fieldset{margin:0;padding:0}legend{padding:0}ol,ul,menu{list-style:none;margin:0;padding:0}dialog{padding:0}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{opacity:1;color:#9ca3af}input::placeholder,textarea::placeholder{opacity:1;color:#9ca3af}button,[role=button]{cursor:pointer}:disabled{cursor:default}img,svg,video,canvas,audio,iframe,embed,object{display:block;vertical-align:middle}img,video{max-width:100%;height:auto}[hidden]:where(:not([hidden=until-found])){display:none}.\!container{width:100%!important}.container{width:100%}@media(min-width:640px){.\!container{max-width:640px!important}.container{max-width:640px}}@media(min-width:768px){.\!container{max-width:768px!important}.container{max-width:768px}}@media(min-width:1024px){.\!container{max-width:1024px!important}.container{max-width:1024px}}@media(min-width:1280px){.\!container{max-width:1280px!important}.container{max-width:1280px}}@media(min-width:1536px){.\!container{max-width:1536px!important}.container{max-width:1536px}}.pride-page-bg{background-color:#050505;background-image:linear-gradient(#0000,#0000),repeating-linear-gradient(45deg,#5bcefa 0 1.818%,#f5a9b8 1.818% 3.636%,#fff 3.636% 5.455%,#f5a9b8 5.455% 7.273%,#5bcefa 7.273% 9.091%,#e40303 9.091% 10.909%,#ff8c00 10.909% 12.727%,#ffed00 12.727% 14.545%,#00a651 14.545% 16.364%,#06f 16.364% 18.182%,#9b2fae 18.182% 20%);background-attachment:fixed}.panel{border-radius:.375rem;--tw-bg-opacity: 1;background-color:rgb(0 0 0 / var(--tw-bg-opacity));padding:0;--tw-text-opacity: 1;color:rgb(255 255 255 / var(--tw-text-opacity))}.panel-section{border-radius:.375rem;--tw-bg-opacity: 1;background-color:rgb(23 23 23 / var(--tw-bg-opacity));padding:0;--tw-text-opacity: 1;color:rgb(255 255 255 / var(--tw-text-opacity))}.panel-muted{border-radius:.375rem;font-size:.875rem;line-height:1.25rem;--tw-text-opacity: 1;color:rgb(148 163 184 / var(--tw-text-opacity))}.surface{border-radius:.375rem;--tw-bg-opacity: 1;background-color:rgb(38 38 38 / var(--tw-bg-opacity));padding:.125rem;--tw-text-opacity: 1;color:rgb(255 255 255 / var(--tw-text-opacity))}.surface-muted{border-radius:.375rem;--tw-bg-opacity: 1;background-color:rgb(64 64 64 / var(--tw-bg-opacity));padding:.125rem;--tw-text-opacity: 1;color:rgb(245 245 245 / var(--tw-text-opacity))}.field-input{border-radius:.375rem;border-width:1px;--tw-border-opacity: 1;border-color:rgb(82 82 82 / var(--tw-border-opacity));--tw-bg-opacity: 1;background-color:rgb(64 64 64 / var(--tw-bg-opacity));padding:.125rem;--tw-text-opacity: 1;color:rgb(255 255 255 / var(--tw-text-opacity))}.field-input::-moz-placeholder{--tw-text-opacity: 1;color:rgb(148 163 184 / var(--tw-text-opacity))}.field-input::placeholder{--tw-text-opacity: 1;color:rgb(148 163 184 / var(--tw-text-opacity))}.field-input:focus{outline:2px solid transparent;outline-offset:2px;--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000);--tw-ring-opacity: 1;--tw-ring-color: rgb(14 165 233 / var(--tw-ring-opacity))}.button-dark{border-radius:.375rem;border-width:1px;--tw-border-opacity: 1;border-color:rgb(125 211 252 / var(--tw-border-opacity));--tw-bg-opacity: 1;background-color:rgb(2 132 199 / var(--tw-bg-opacity));padding:.125rem;font-size:.875rem;line-height:1.25rem;font-weight:500;--tw-text-opacity: 1;color:rgb(255 255 255 / var(--tw-text-opacity));transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.button-dark:hover{--tw-border-opacity: 1;border-color:rgb(14 165 233 / var(--tw-border-opacity));--tw-bg-opacity: 1;background-color:rgb(14 165 233 / var(--tw-bg-opacity))}.button-danger{border-radius:.375rem;--tw-bg-opacity: 1;background-color:rgb(225 29 72 / var(--tw-bg-opacity));padding:.125rem;font-size:.875rem;line-height:1.25rem;font-weight:500;--tw-text-opacity: 1;color:rgb(255 255 255 / var(--tw-text-opacity));transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.button-danger:hover{--tw-bg-opacity: 1;background-color:rgb(244 63 94 / var(--tw-bg-opacity))}.chat-composer{container-type:inline-size;display:flex;flex-wrap:wrap;align-items:stretch;gap:.125rem;min-width:0;overflow:hidden}.chat-composer-nickname{flex:0 0 5rem;min-width:0;order:1}.chat-composer-input{flex:1 1 0%;min-width:0;order:2}.chat-composer-send{flex:0 0 auto;align-self:stretch;order:3}.chat-composer-tts{display:flex;flex:1 1 100%;align-items:center;gap:.125rem;min-width:0;overflow:hidden;order:4}@container (min-width: 44rem){.chat-composer{flex-wrap:nowrap}.chat-composer-nickname{flex-basis:7rem;order:1}.chat-composer-input{order:2}.chat-composer-tts{flex:0 1 auto;order:3}.chat-composer-send{order:4}}.pointer-events-none{pointer-events:none}.pointer-events-auto{pointer-events:auto}.\!visible{visibility:visible!important}.visible{visibility:visible}.collapse{visibility:collapse}.fixed{position:fixed}.absolute{position:absolute}.relative{position:relative}.sticky{position:sticky}.inset-0{inset:0}.inset-x-0{left:0;right:0}.inset-x-1{left:.25rem;right:.25rem}.bottom-0{bottom:0}.bottom-0\.5{bottom:.125rem}.bottom-1{bottom:.25rem}.bottom-2{bottom:.5rem}.bottom-4{bottom:1rem}.bottom-\[calc\(100\%\+0\.125rem\)\]{bottom:calc(100% + .125rem)}.left-0{left:0}.left-0\.5{left:.125rem}.left-1{left:.25rem}.left-1\/2{left:50%}.left-2{left:.5rem}.left-4{left:1rem}.right-0{right:0}.right-0\.5{right:.125rem}.right-1{right:.25rem}.right-2{right:.5rem}.top-0{top:0}.top-0\.5{top:.125rem}.top-1{top:.25rem}.top-1\/2{top:50%}.top-10{top:2.5rem}.top-6{top:1.5rem}.z-10{z-index:10}.z-20{z-index:20}.z-30{z-index:30}.z-40{z-index:40}.z-50{z-index:50}.z-\[1000\]{z-index:1000}.z-\[110\]{z-index:110}.z-\[120\]{z-index:120}.z-\[130\]{z-index:130}.z-\[70\]{z-index:70}.order-1{order:1}.order-2{order:2}.col-span-full{grid-column:1 / -1}.m-0{margin:0}.-mx-0\.5{margin-left:-.125rem;margin-right:-.125rem}.mx-auto{margin-left:auto;margin-right:auto}.my-\[-0\.125rem\]{margin-top:-.125rem;margin-bottom:-.125rem}.-mt-0\.5{margin-top:-.125rem}.mb-0\.5{margin-bottom:.125rem}.ml-1{margin-left:.25rem}.mr-0{margin-right:0}.mt-0{margin-top:0}.mt-0\.5{margin-top:.125rem}.mt-1{margin-top:.25rem}.mt-\[0\.35vh\]{margin-top:.35vh}.mt-auto{margin-top:auto}.line-clamp-2{overflow:hidden;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:2}.\!block{display:block!important}.block{display:block}.inline-block{display:inline-block}.inline{display:inline}.flex{display:flex}.inline-flex{display:inline-flex}.grid{display:grid}.hidden{display:none}.aspect-\[4\/3\]{aspect-ratio:4/3}.aspect-square{aspect-ratio:1 / 1}.aspect-video{aspect-ratio:16 / 9}.h-1{height:.25rem}.h-1\.5{height:.375rem}.h-10{height:2.5rem}.h-2{height:.5rem}.h-28{height:7rem}.h-3{height:.75rem}.h-3\.5{height:.875rem}.h-4{height:1rem}.h-40{height:10rem}.h-48{height:12rem}.h-5{height:1.25rem}.h-64{height:16rem}.h-\[2px\]{height:2px}.h-\[3\.5rem\]{height:3.5rem}.h-\[70\%\]{height:70%}.h-\[7rem\]{height:7rem}.h-\[8vh\]{height:8vh}.h-\[calc\(1rem\+0\.25rem\)\]{height:1.25rem}.h-\[min\(100svh\,32rem\)\]{height:min(100svh,32rem)}.h-\[min\(60svh\,24rem\)\]{height:min(60svh,24rem)}.h-full{height:100%}.h-px{height:1px}.h-screen{height:100vh}.max-h-32{max-height:8rem}.max-h-40{max-height:10rem}.max-h-52{max-height:13rem}.max-h-72{max-height:18rem}.max-h-80{max-height:20rem}.max-h-\[14rem\]{max-height:14rem}.max-h-\[70vh\]{max-height:70vh}.max-h-\[72vh\]{max-height:72vh}.max-h-\[85vh\]{max-height:85vh}.max-h-\[90vh\]{max-height:90vh}.max-h-screen{max-height:100vh}.min-h-0{min-height:0px}.min-h-5{min-height:1.25rem}.min-h-9{min-height:2.25rem}.min-h-\[10rem\]{min-height:10rem}.min-h-\[14rem\]{min-height:14rem}.min-h-\[16rem\]{min-height:16rem}.min-h-\[3\.5rem\]{min-height:3.5rem}.min-h-\[4rem\]{min-height:4rem}.min-h-\[5rem\]{min-height:5rem}.min-h-screen{min-height:100vh}.w-1{width:.25rem}.w-1\.5{width:.375rem}.w-1\/2{width:50%}.w-10{width:2.5rem}.w-2{width:.5rem}.w-20{width:5rem}.w-3{width:.75rem}.w-3\.5{width:.875rem}.w-4{width:1rem}.w-5{width:1.25rem}.w-6{width:1.5rem}.w-\[12\.5rem\]{width:12.5rem}.w-\[12rem\]{width:12rem}.w-\[20rem\]{width:20rem}.w-\[2px\]{width:2px}.w-\[3\.25rem\]{width:3.25rem}.w-\[4\.5rem\]{width:4.5rem}.w-\[5\.5rem\]{width:5.5rem}.w-\[5rem\]{width:5rem}.w-\[9rem\]{width:9rem}.w-\[calc\(1rem\+0\.25rem\)\]{width:1.25rem}.w-\[min\(20rem\,calc\(100vw-1rem\)\)\]{width:min(20rem,calc(100vw - 1rem))}.w-auto{width:auto}.w-fit{width:-moz-fit-content;width:fit-content}.w-full{width:100%}.w-max{width:-moz-max-content;width:max-content}.w-px{width:1px}.w-screen{width:100vw}.min-w-0{min-width:0px}.min-w-28{min-width:7rem}.min-w-\[0\]{min-width:0}.min-w-\[3\.7rem\]{min-width:3.7rem}.min-w-\[9\.5rem\]{min-width:9.5rem}.max-w-2xl{max-width:42rem}.max-w-3xl{max-width:48rem}.max-w-4xl{max-width:56rem}.max-w-\[40vw\]{max-width:40vw}.max-w-\[70vw\]{max-width:70vw}.max-w-\[80vw\]{max-width:80vw}.max-w-\[92\%\]{max-width:92%}.max-w-\[92vw\]{max-width:92vw}.max-w-\[94\%\]{max-width:94%}.max-w-full{max-width:100%}.max-w-lg{max-width:32rem}.max-w-md{max-width:28rem}.max-w-sm{max-width:24rem}.max-w-xl{max-width:36rem}.flex-1{flex:1 1 0%}.flex-\[0\.72\]{flex:.72}.flex-\[1\.1\]{flex:1.1}.flex-\[1\.22\]{flex:1.22}.flex-\[1\.28\]{flex:1.28}.shrink{flex-shrink:1}.shrink-0{flex-shrink:0}.origin-top-left{transform-origin:top left}.-translate-x-1\/2{--tw-translate-x: -50%;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.-translate-y-1\/2{--tw-translate-y: -50%;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.rotate-180{--tw-rotate: 180deg;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.transform{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}@keyframes pulse{50%{opacity:.5}}.animate-pulse{animation:pulse 2s cubic-bezier(.4,0,.6,1) infinite}.cursor-default{cursor:default}.cursor-not-allowed{cursor:not-allowed}.cursor-pointer{cursor:pointer}.select-none{-webkit-user-select:none;-moz-user-select:none;user-select:none}.resize{resize:both}.auto-rows-fr{grid-auto-rows:minmax(0,1fr)}.grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}.grid-cols-\[1\.25rem_minmax\(0\,1fr\)_auto\]{grid-template-columns:1.25rem minmax(0,1fr) auto}.grid-cols-\[auto_minmax\(0\,1fr\)\]{grid-template-columns:auto minmax(0,1fr)}.grid-cols-\[minmax\(0\,0\.7fr\)_minmax\(0\,2\.1fr\)_minmax\(0\,0\.7fr\)\]{grid-template-columns:minmax(0,.7fr) minmax(0,2.1fr) minmax(0,.7fr)}.grid-cols-\[minmax\(0\,1\.2fr\)_repeat\(4\,minmax\(0\,1fr\)\)\]{grid-template-columns:minmax(0,1.2fr) repeat(4,minmax(0,1fr))}.grid-cols-\[minmax\(0\,1\.35fr\)_minmax\(0\,0\.95fr\)\]{grid-template-columns:minmax(0,1.35fr) minmax(0,.95fr)}.grid-cols-\[minmax\(0\,1\.3fr\)_minmax\(0\,0\.22fr\)\]{grid-template-columns:minmax(0,1.3fr) minmax(0,.22fr)}.grid-cols-\[minmax\(0\,1\.45fr\)_minmax\(0\,0\.85fr\)\]{grid-template-columns:minmax(0,1.45fr) minmax(0,.85fr)}.grid-cols-\[minmax\(0\,1fr\)\]{grid-template-columns:minmax(0,1fr)}.grid-cols-\[minmax\(0\,1fr\)_2\.5rem\]{grid-template-columns:minmax(0,1fr) 2.5rem}.grid-cols-\[minmax\(0\,1fr\)_4\.75rem\]{grid-template-columns:minmax(0,1fr) 4.75rem}.grid-cols-\[minmax\(0\,1fr\)_auto\]{grid-template-columns:minmax(0,1fr) auto}.grid-cols-\[minmax\(0\,1fr\)_minmax\(0\,0\.7fr\)_minmax\(0\,1\.9fr\)_minmax\(0\,0\.7fr\)\]{grid-template-columns:minmax(0,1fr) minmax(0,.7fr) minmax(0,1.9fr) minmax(0,.7fr)}.grid-cols-\[minmax\(0\,1fr\)_minmax\(0\,0\.9fr\)_minmax\(0\,0\.75fr\)\]{grid-template-columns:minmax(0,1fr) minmax(0,.9fr) minmax(0,.75fr)}.grid-cols-\[minmax\(0\,1fr\)_minmax\(0\,1\.4fr\)\]{grid-template-columns:minmax(0,1fr) minmax(0,1.4fr)}.grid-cols-\[minmax\(0\,1fr\)_minmax\(0\,1fr\)\]{grid-template-columns:minmax(0,1fr) minmax(0,1fr)}.grid-rows-2{grid-template-rows:repeat(2,minmax(0,1fr))}.grid-rows-3{grid-template-rows:repeat(3,minmax(0,1fr))}.grid-rows-\[auto_1fr\]{grid-template-rows:auto 1fr}.grid-rows-\[auto_auto_1fr\]{grid-template-rows:auto auto 1fr}.grid-rows-\[auto_auto_1fr_auto\]{grid-template-rows:auto auto 1fr auto}.grid-rows-\[auto_minmax\(0\,1fr\)\]{grid-template-rows:auto minmax(0,1fr)}.grid-rows-\[auto_minmax\(0\,1fr\)_auto\]{grid-template-rows:auto minmax(0,1fr) auto}.grid-rows-\[minmax\(0\,1fr\)\]{grid-template-rows:minmax(0,1fr)}.grid-rows-\[minmax\(0\,1fr\)_auto\]{grid-template-rows:minmax(0,1fr) auto}.grid-rows-\[minmax\(0\,1fr\)_minmax\(0\,1fr\)_minmax\(0\,1fr\)\]{grid-template-rows:minmax(0,1fr) minmax(0,1fr) minmax(0,1fr)}.\!flex-row{flex-direction:row!important}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.place-items-center{place-items:center}.content-center{align-content:center}.content-start{align-content:flex-start}.items-start{align-items:flex-start}.items-end{align-items:flex-end}.items-center{align-items:center}.items-baseline{align-items:baseline}.items-stretch{align-items:stretch}.justify-start{justify-content:flex-start}.justify-end{justify-content:flex-end}.justify-center{justify-content:center}.justify-between{justify-content:space-between}.justify-stretch{justify-content:stretch}.gap-0\.5{gap:.125rem}.gap-1{gap:.25rem}.gap-1\.5{gap:.375rem}.gap-2{gap:.5rem}.gap-4{gap:1rem}.gap-\[0\.55vh\]{gap:.55vh}.gap-\[0\.8vw\]{gap:.8vw}.gap-\[1vw\]{gap:1vw}.gap-\[3vh\]{gap:3vh}.gap-x-3{-moz-column-gap:.75rem;column-gap:.75rem}.space-y-0\.5>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.125rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.125rem * var(--tw-space-y-reverse))}.space-y-1>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.25rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.25rem * var(--tw-space-y-reverse))}.space-y-2>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.5rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.5rem * var(--tw-space-y-reverse))}.self-start{align-self:flex-start}.self-stretch{align-self:stretch}.overflow-hidden{overflow:hidden}.overflow-visible{overflow:visible}.overflow-y-auto{overflow-y:auto}.truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.whitespace-nowrap{white-space:nowrap}.whitespace-pre-wrap{white-space:pre-wrap}.break-words{overflow-wrap:break-word}.break-all{word-break:break-all}.rounded{border-radius:.25rem}.rounded-full{border-radius:9999px}.rounded-lg{border-radius:.5rem}.rounded-md{border-radius:.375rem}.rounded-none{border-radius:0}.rounded-sm{border-radius:.125rem}.rounded-xl{border-radius:.75rem}.rounded-t{border-top-left-radius:.25rem;border-top-right-radius:.25rem}.border{border-width:1px}.border-2{border-width:2px}.border-4{border-width:4px}.border-b{border-bottom-width:1px}.border-l{border-left-width:1px}.border-l-4{border-left-width:4px}.border-r{border-right-width:1px}.border-t{border-top-width:1px}.border-amber-200{--tw-border-opacity: 1;border-color:rgb(253 230 138 / var(--tw-border-opacity))}.border-amber-200\/30{border-color:#fde68a4d}.border-amber-200\/70{border-color:#fde68ab3}.border-amber-200\/90{border-color:#fde68ae6}.border-amber-300\/70{border-color:#fcd34db3}.border-amber-300\/80{border-color:#fcd34dcc}.border-amber-400\/30{border-color:#fbbf244d}.border-amber-400\/60{border-color:#fbbf2499}.border-amber-600\/60{border-color:#d9770699}.border-amber-700\/60{border-color:#b4530999}.border-blue-600{--tw-border-opacity: 1;border-color:rgb(37 99 235 / var(--tw-border-opacity))}.border-cyan-200{--tw-border-opacity: 1;border-color:rgb(165 243 252 / var(--tw-border-opacity))}.border-cyan-200\/90{border-color:#a5f3fce6}.border-cyan-300{--tw-border-opacity: 1;border-color:rgb(103 232 249 / var(--tw-border-opacity))}.border-cyan-300\/70{border-color:#67e8f9b3}.border-cyan-300\/80{border-color:#67e8f9cc}.border-cyan-500\/40{border-color:#06b6d466}.border-emerald-100\/80{border-color:#d1fae5cc}.border-emerald-200{--tw-border-opacity: 1;border-color:rgb(167 243 208 / var(--tw-border-opacity))}.border-emerald-200\/70{border-color:#a7f3d0b3}.border-emerald-200\/90{border-color:#a7f3d0e6}.border-emerald-300{--tw-border-opacity: 1;border-color:rgb(110 231 183 / var(--tw-border-opacity))}.border-emerald-300\/70{border-color:#6ee7b7b3}.border-emerald-400\/60{border-color:#34d39999}.border-emerald-500\/40{border-color:#10b98166}.border-emerald-700\/60{border-color:#04785799}.border-emerald-700\/70{border-color:#047857b3}.border-emerald-950{--tw-border-opacity: 1;border-color:rgb(2 44 34 / var(--tw-border-opacity))}.border-fuchsia-300\/70{border-color:#f0abfcb3}.border-green-400{--tw-border-opacity: 1;border-color:rgb(74 222 128 / var(--tw-border-opacity))}.border-indigo-200\/70{border-color:#c7d2feb3}.border-indigo-200\/95{border-color:#c7d2fef2}.border-indigo-300\/70{border-color:#a5b4fcb3}.border-indigo-400\/30{border-color:#818cf84d}.border-indigo-700{--tw-border-opacity: 1;border-color:rgb(67 56 202 / var(--tw-border-opacity))}.border-indigo-700\/60{border-color:#4338ca99}.border-neutral-500\/50{border-color:#73737380}.border-neutral-500\/60{border-color:#73737399}.border-neutral-600{--tw-border-opacity: 1;border-color:rgb(82 82 82 / var(--tw-border-opacity))}.border-neutral-700{--tw-border-opacity: 1;border-color:rgb(64 64 64 / var(--tw-border-opacity))}.border-pink-200{--tw-border-opacity: 1;border-color:rgb(251 207 232 / var(--tw-border-opacity))}.border-red-100{--tw-border-opacity: 1;border-color:rgb(254 226 226 / var(--tw-border-opacity))}.border-red-200{--tw-border-opacity: 1;border-color:rgb(254 202 202 / var(--tw-border-opacity))}.border-red-300\/90{border-color:#fca5a5e6}.border-red-400{--tw-border-opacity: 1;border-color:rgb(248 113 113 / var(--tw-border-opacity))}.border-red-400\/60{border-color:#f8717199}.border-rose-300{--tw-border-opacity: 1;border-color:rgb(253 164 175 / var(--tw-border-opacity))}.border-sky-300{--tw-border-opacity: 1;border-color:rgb(125 211 252 / var(--tw-border-opacity))}.border-sky-400\/50{border-color:#38bdf880}.border-slate-200\/30{border-color:#e2e8f04d}.border-slate-400{--tw-border-opacity: 1;border-color:rgb(148 163 184 / var(--tw-border-opacity))}.border-slate-400\/60{border-color:#94a3b899}.border-slate-500\/70{border-color:#64748bb3}.border-slate-600{--tw-border-opacity: 1;border-color:rgb(71 85 105 / var(--tw-border-opacity))}.border-slate-600\/40{border-color:#47556966}.border-slate-600\/60{border-color:#47556999}.border-slate-600\/70{border-color:#475569b3}.border-slate-600\/80{border-color:#475569cc}.border-slate-700{--tw-border-opacity: 1;border-color:rgb(51 65 85 / var(--tw-border-opacity))}.border-slate-700\/60{border-color:#33415599}.border-slate-700\/70{border-color:#334155b3}.border-slate-700\/80{border-color:#334155cc}.border-slate-800{--tw-border-opacity: 1;border-color:rgb(30 41 59 / var(--tw-border-opacity))}.border-slate-800\/60{border-color:#1e293b99}.border-slate-800\/80{border-color:#1e293bcc}.border-transparent{border-color:transparent}.border-white{--tw-border-opacity: 1;border-color:rgb(255 255 255 / var(--tw-border-opacity))}.border-white\/40{border-color:#fff6}.border-white\/80{border-color:#fffc}.border-l-neutral-600{--tw-border-opacity: 1;border-left-color:rgb(82 82 82 / var(--tw-border-opacity))}.bg-amber-100\/95{background-color:#fef3c7f2}.bg-amber-400{--tw-bg-opacity: 1;background-color:rgb(251 191 36 / var(--tw-bg-opacity))}.bg-amber-400\/80{background-color:#fbbf24cc}.bg-amber-500{--tw-bg-opacity: 1;background-color:rgb(245 158 11 / var(--tw-bg-opacity))}.bg-amber-500\/30{background-color:#f59e0b4d}.bg-amber-600{--tw-bg-opacity: 1;background-color:rgb(217 119 6 / var(--tw-bg-opacity))}.bg-amber-600\/70{background-color:#d97706b3}.bg-amber-700\/20{background-color:#b4530933}.bg-amber-700\/30{background-color:#b453094d}.bg-amber-700\/35{background-color:#b4530959}.bg-amber-700\/80{background-color:#b45309cc}.bg-amber-800{--tw-bg-opacity: 1;background-color:rgb(146 64 14 / var(--tw-bg-opacity))}.bg-amber-900{--tw-bg-opacity: 1;background-color:rgb(120 53 15 / var(--tw-bg-opacity))}.bg-amber-900\/40{background-color:#78350f66}.bg-amber-900\/60{background-color:#78350f99}.bg-amber-900\/90{background-color:#78350fe6}.bg-amber-950\/70{background-color:#451a03b3}.bg-black{--tw-bg-opacity: 1;background-color:rgb(0 0 0 / var(--tw-bg-opacity))}.bg-black\/20{background-color:#0003}.bg-black\/30{background-color:#0000004d}.bg-black\/40{background-color:#0006}.bg-black\/45{background-color:#00000073}.bg-black\/50{background-color:#00000080}.bg-black\/55{background-color:#0000008c}.bg-black\/60{background-color:#0009}.bg-black\/70{background-color:#000000b3}.bg-black\/75{background-color:#000000bf}.bg-black\/80{background-color:#000c}.bg-black\/95{background-color:#000000f2}.bg-blue-500{--tw-bg-opacity: 1;background-color:rgb(59 130 246 / var(--tw-bg-opacity))}.bg-cyan-300{--tw-bg-opacity: 1;background-color:rgb(103 232 249 / var(--tw-bg-opacity))}.bg-cyan-500{--tw-bg-opacity: 1;background-color:rgb(6 182 212 / var(--tw-bg-opacity))}.bg-cyan-500\/80{background-color:#06b6d4cc}.bg-cyan-900{--tw-bg-opacity: 1;background-color:rgb(22 78 99 / var(--tw-bg-opacity))}.bg-cyan-900\/45{background-color:#164e6373}.bg-cyan-900\/90{background-color:#164e63e6}.bg-emerald-200{--tw-bg-opacity: 1;background-color:rgb(167 243 208 / var(--tw-bg-opacity))}.bg-emerald-400{--tw-bg-opacity: 1;background-color:rgb(52 211 153 / var(--tw-bg-opacity))}.bg-emerald-500{--tw-bg-opacity: 1;background-color:rgb(16 185 129 / var(--tw-bg-opacity))}.bg-emerald-500\/45{background-color:#10b98173}.bg-emerald-500\/80{background-color:#10b981cc}.bg-emerald-600{--tw-bg-opacity: 1;background-color:rgb(5 150 105 / var(--tw-bg-opacity))}.bg-emerald-600\/70{background-color:#059669b3}.bg-emerald-600\/80{background-color:#059669cc}.bg-emerald-700{--tw-bg-opacity: 1;background-color:rgb(4 120 87 / var(--tw-bg-opacity))}.bg-emerald-700\/20{background-color:#04785733}.bg-emerald-700\/60{background-color:#04785799}.bg-emerald-800{--tw-bg-opacity: 1;background-color:rgb(6 95 70 / var(--tw-bg-opacity))}.bg-emerald-900{--tw-bg-opacity: 1;background-color:rgb(6 78 59 / var(--tw-bg-opacity))}.bg-emerald-900\/60{background-color:#064e3b99}.bg-emerald-900\/90{background-color:#064e3be6}.bg-emerald-950{--tw-bg-opacity: 1;background-color:rgb(2 44 34 / var(--tw-bg-opacity))}.bg-emerald-950\/50{background-color:#022c2280}.bg-fuchsia-200{--tw-bg-opacity: 1;background-color:rgb(245 208 254 / var(--tw-bg-opacity))}.bg-fuchsia-600{--tw-bg-opacity: 1;background-color:rgb(192 38 211 / var(--tw-bg-opacity))}.bg-fuchsia-700{--tw-bg-opacity: 1;background-color:rgb(162 28 175 / var(--tw-bg-opacity))}.bg-fuchsia-800{--tw-bg-opacity: 1;background-color:rgb(134 25 143 / var(--tw-bg-opacity))}.bg-fuchsia-900\/45{background-color:#701a7573}.bg-green-600{--tw-bg-opacity: 1;background-color:rgb(22 163 74 / var(--tw-bg-opacity))}.bg-indigo-600{--tw-bg-opacity: 1;background-color:rgb(79 70 229 / var(--tw-bg-opacity))}.bg-indigo-600\/70{background-color:#4f46e5b3}.bg-indigo-900{--tw-bg-opacity: 1;background-color:rgb(49 46 129 / var(--tw-bg-opacity))}.bg-indigo-900\/60{background-color:#312e8199}.bg-indigo-950{--tw-bg-opacity: 1;background-color:rgb(30 27 75 / var(--tw-bg-opacity))}.bg-indigo-950\/90{background-color:#1e1b4be6}.bg-neutral-700{--tw-bg-opacity: 1;background-color:rgb(64 64 64 / var(--tw-bg-opacity))}.bg-neutral-800{--tw-bg-opacity: 1;background-color:rgb(38 38 38 / var(--tw-bg-opacity))}.bg-neutral-800\/80{background-color:#262626cc}.bg-neutral-900{--tw-bg-opacity: 1;background-color:rgb(23 23 23 / var(--tw-bg-opacity))}.bg-neutral-900\/100{background-color:#171717}.bg-neutral-900\/70{background-color:#171717b3}.bg-neutral-900\/95{background-color:#171717f2}.bg-neutral-950{--tw-bg-opacity: 1;background-color:rgb(10 10 10 / var(--tw-bg-opacity))}.bg-pink-500{--tw-bg-opacity: 1;background-color:rgb(236 72 153 / var(--tw-bg-opacity))}.bg-red-500{--tw-bg-opacity: 1;background-color:rgb(239 68 68 / var(--tw-bg-opacity))}.bg-red-500\/45{background-color:#ef444473}.bg-red-600{--tw-bg-opacity: 1;background-color:rgb(220 38 38 / var(--tw-bg-opacity))}.bg-red-600\/70{background-color:#dc2626b3}.bg-red-700{--tw-bg-opacity: 1;background-color:rgb(185 28 28 / var(--tw-bg-opacity))}.bg-red-700\/20{background-color:#b91c1c33}.bg-red-700\/60{background-color:#b91c1c99}.bg-red-800{--tw-bg-opacity: 1;background-color:rgb(153 27 27 / var(--tw-bg-opacity))}.bg-red-900\/35{background-color:#7f1d1d59}.bg-red-900\/40{background-color:#7f1d1d66}.bg-red-900\/45{background-color:#7f1d1d73}.bg-red-900\/50{background-color:#7f1d1d80}.bg-red-900\/80{background-color:#7f1d1dcc}.bg-rose-500{--tw-bg-opacity: 1;background-color:rgb(244 63 94 / var(--tw-bg-opacity))}.bg-rose-600{--tw-bg-opacity: 1;background-color:rgb(225 29 72 / var(--tw-bg-opacity))}.bg-sky-600{--tw-bg-opacity: 1;background-color:rgb(2 132 199 / var(--tw-bg-opacity))}.bg-sky-700\/20{background-color:#0369a133}.bg-slate-300{--tw-bg-opacity: 1;background-color:rgb(203 213 225 / var(--tw-bg-opacity))}.bg-slate-500{--tw-bg-opacity: 1;background-color:rgb(100 116 139 / var(--tw-bg-opacity))}.bg-slate-600{--tw-bg-opacity: 1;background-color:rgb(71 85 105 / var(--tw-bg-opacity))}.bg-slate-600\/70{background-color:#475569b3}.bg-slate-700{--tw-bg-opacity: 1;background-color:rgb(51 65 85 / var(--tw-bg-opacity))}.bg-slate-700\/30{background-color:#3341554d}.bg-slate-700\/60{background-color:#33415599}.bg-slate-700\/70{background-color:#334155b3}.bg-slate-700\/80{background-color:#334155cc}.bg-slate-800{--tw-bg-opacity: 1;background-color:rgb(30 41 59 / var(--tw-bg-opacity))}.bg-slate-800\/60{background-color:#1e293b99}.bg-slate-800\/70{background-color:#1e293bb3}.bg-slate-800\/80{background-color:#1e293bcc}.bg-slate-900{--tw-bg-opacity: 1;background-color:rgb(15 23 42 / var(--tw-bg-opacity))}.bg-slate-900\/35{background-color:#0f172a59}.bg-slate-900\/40{background-color:#0f172a66}.bg-slate-900\/70{background-color:#0f172ab3}.bg-slate-950{--tw-bg-opacity: 1;background-color:rgb(2 6 23 / var(--tw-bg-opacity))}.bg-slate-950\/80{background-color:#020617cc}.bg-slate-950\/90{background-color:#020617e6}.bg-transparent{background-color:transparent}.bg-white{--tw-bg-opacity: 1;background-color:rgb(255 255 255 / var(--tw-bg-opacity))}.bg-white\/10{background-color:#ffffff1a}.bg-yellow-100{--tw-bg-opacity: 1;background-color:rgb(254 249 195 / var(--tw-bg-opacity))}.bg-yellow-500{--tw-bg-opacity: 1;background-color:rgb(234 179 8 / var(--tw-bg-opacity))}.bg-zinc-900{--tw-bg-opacity: 1;background-color:rgb(24 24 27 / var(--tw-bg-opacity))}.bg-zinc-900\/90{background-color:#18181be6}.bg-gradient-to-r{background-image:linear-gradient(to right,var(--tw-gradient-stops))}.from-lime-800{--tw-gradient-from: #3f6212 var(--tw-gradient-from-position);--tw-gradient-to: rgb(63 98 18 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to)}.from-neutral-800{--tw-gradient-from: #262626 var(--tw-gradient-from-position);--tw-gradient-to: rgb(38 38 38 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to)}.via-neutral-700{--tw-gradient-to: rgb(64 64 64 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), #404040 var(--tw-gradient-via-position), var(--tw-gradient-to)}.to-neutral-600{--tw-gradient-to: #525252 var(--tw-gradient-to-position)}.to-teal-800{--tw-gradient-to: #115e59 var(--tw-gradient-to-position)}.bg-cover{background-size:cover}.bg-center{background-position:center}.bg-no-repeat{background-repeat:no-repeat}.fill-slate-200{fill:#e2e8f0}.object-contain{-o-object-fit:contain;object-fit:contain}.object-cover{-o-object-fit:cover;object-fit:cover}.p-0{padding:0}.p-0\.5{padding:.125rem}.p-1{padding:.25rem}.p-2{padding:.5rem}.p-4{padding:1rem}.p-\[0\.85vw\]{padding:.85vw}.px-0{padding-left:0;padding-right:0}.px-0\.5{padding-left:.125rem;padding-right:.125rem}.px-1{padding-left:.25rem;padding-right:.25rem}.px-1\.5{padding-left:.375rem;padding-right:.375rem}.px-2{padding-left:.5rem;padding-right:.5rem}.px-3{padding-left:.75rem;padding-right:.75rem}.px-4{padding-left:1rem;padding-right:1rem}.px-6{padding-left:1.5rem;padding-right:1.5rem}.px-\[1\.6vw\]{padding-left:1.6vw;padding-right:1.6vw}.px-\[1vw\]{padding-left:1vw;padding-right:1vw}.px-\[3vw\]{padding-left:3vw;padding-right:3vw}.px-\[4vw\]{padding-left:4vw;padding-right:4vw}.py-0{padding-top:0;padding-bottom:0}.py-0\.5{padding-top:.125rem;padding-bottom:.125rem}.py-1{padding-top:.25rem;padding-bottom:.25rem}.py-1\.5{padding-top:.375rem;padding-bottom:.375rem}.py-2{padding-top:.5rem;padding-bottom:.5rem}.py-3{padding-top:.75rem;padding-bottom:.75rem}.py-4{padding-top:1rem;padding-bottom:1rem}.py-\[0\.55vh\]{padding-top:.55vh;padding-bottom:.55vh}.py-\[1px\]{padding-top:1px;padding-bottom:1px}.py-\[2\.5vh\]{padding-top:2.5vh;padding-bottom:2.5vh}.py-\[2px\]{padding-top:2px;padding-bottom:2px}.py-\[4vh\]{padding-top:4vh;padding-bottom:4vh}.pb-0{padding-bottom:0}.pb-1{padding-bottom:.25rem}.pb-3{padding-bottom:.75rem}.pr-0{padding-right:0}.pt-1{padding-top:.25rem}.pt-5{padding-top:1.25rem}.text-left{text-align:left}.text-center{text-align:center}.text-right{text-align:right}.align-top{vertical-align:top}.align-middle{vertical-align:middle}.font-mono{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace}.text-2xl{font-size:1.5rem;line-height:2rem}.text-3xl{font-size:1.875rem;line-height:2.25rem}.text-4xl{font-size:2.25rem;line-height:2.5rem}.text-5xl{font-size:3rem;line-height:1}.text-\[0\.45rem\]{font-size:.45rem}.text-\[0\.55em\]{font-size:.55em}.text-\[0\.55rem\]{font-size:.55rem}.text-\[0\.58rem\]{font-size:.58rem}.text-\[0\.5rem\]{font-size:.5rem}.text-\[0\.62rem\]{font-size:.62rem}.text-\[0\.65rem\]{font-size:.65rem}.text-\[0\.68rem\]{font-size:.68rem}.text-\[0\.6rem\]{font-size:.6rem}.text-\[0\.72rem\]{font-size:.72rem}.text-\[0\.75rem\]{font-size:.75rem}.text-\[0\.78rem\]{font-size:.78rem}.text-\[0\.7rem\]{font-size:.7rem}.text-\[0\.82rem\]{font-size:.82rem}.text-\[0\.85rem\]{font-size:.85rem}.text-\[0\.8rem\]{font-size:.8rem}.text-\[1\.1rem\]{font-size:1.1rem}.text-\[1\.5rem\]{font-size:1.5rem}.text-\[17vw\]{font-size:17vw}.text-\[1rem\]{font-size:1rem}.text-\[2\.5vw\]{font-size:2.5vw}.text-\[3vw\]{font-size:3vw}.text-\[4vw\]{font-size:4vw}.text-\[6vw\]{font-size:6vw}.text-\[7vw\]{font-size:7vw}.text-\[clamp\(1\.25rem\,2\.5vh\,2\.6rem\)\]{font-size:clamp(1.25rem,2.5vh,2.6rem)}.text-\[clamp\(1\.2rem\,2\.9vh\,3rem\)\]{font-size:clamp(1.2rem,2.9vh,3rem)}.text-\[clamp\(2\.5rem\,5\.3vh\,5\.8rem\)\]{font-size:clamp(2.5rem,5.3vh,5.8rem)}.text-\[clamp\(2\.5rem\,7vh\,7rem\)\]{font-size:clamp(2.5rem,7vh,7rem)}.text-\[clamp\(2\.5rem\,8vh\,8rem\)\]{font-size:clamp(2.5rem,8vh,8rem)}.text-\[clamp\(2rem\,5vh\,5\.2rem\)\]{font-size:clamp(2rem,5vh,5.2rem)}.text-\[clamp\(3\.2rem\,11vh\,11rem\)\]{font-size:clamp(3.2rem,11vh,11rem)}.text-base{font-size:1rem;line-height:1.5rem}.text-lg{font-size:1.125rem;line-height:1.75rem}.text-sm{font-size:.875rem;line-height:1.25rem}.text-xl{font-size:1.25rem;line-height:1.75rem}.text-xs{font-size:.75rem;line-height:1rem}.font-black{font-weight:900}.font-bold{font-weight:700}.font-medium{font-weight:500}.font-normal{font-weight:400}.font-semibold{font-weight:600}.uppercase{text-transform:uppercase}.lowercase{text-transform:lowercase}.capitalize{text-transform:capitalize}.italic{font-style:italic}.leading-\[0\.95\]{line-height:.95}.leading-none{line-height:1}.leading-snug{line-height:1.375}.leading-tight{line-height:1.25}.tracking-normal{letter-spacing:0em}.tracking-tight{letter-spacing:-.025em}.tracking-wide{letter-spacing:.025em}.text-amber-100{--tw-text-opacity: 1;color:rgb(254 243 199 / var(--tw-text-opacity))}.text-amber-200{--tw-text-opacity: 1;color:rgb(253 230 138 / var(--tw-text-opacity))}.text-amber-200\/80{color:#fde68acc}.text-amber-200\/85{color:#fde68ad9}.text-amber-300{--tw-text-opacity: 1;color:rgb(252 211 77 / var(--tw-text-opacity))}.text-amber-400{--tw-text-opacity: 1;color:rgb(251 191 36 / var(--tw-text-opacity))}.text-amber-50{--tw-text-opacity: 1;color:rgb(255 251 235 / var(--tw-text-opacity))}.text-amber-50\/90{color:#fffbebe6}.text-amber-950{--tw-text-opacity: 1;color:rgb(69 26 3 / var(--tw-text-opacity))}.text-black{--tw-text-opacity: 1;color:rgb(0 0 0 / var(--tw-text-opacity))}.text-blue-300{--tw-text-opacity: 1;color:rgb(147 197 253 / var(--tw-text-opacity))}.text-blue-400{--tw-text-opacity: 1;color:rgb(96 165 250 / var(--tw-text-opacity))}.text-blue-800{--tw-text-opacity: 1;color:rgb(30 64 175 / var(--tw-text-opacity))}.text-cyan-200{--tw-text-opacity: 1;color:rgb(165 243 252 / var(--tw-text-opacity))}.text-cyan-300{--tw-text-opacity: 1;color:rgb(103 232 249 / var(--tw-text-opacity))}.text-cyan-50{--tw-text-opacity: 1;color:rgb(236 254 255 / var(--tw-text-opacity))}.text-emerald-100{--tw-text-opacity: 1;color:rgb(209 250 229 / var(--tw-text-opacity))}.text-emerald-100\/80{color:#d1fae5cc}.text-emerald-200{--tw-text-opacity: 1;color:rgb(167 243 208 / var(--tw-text-opacity))}.text-emerald-300{--tw-text-opacity: 1;color:rgb(110 231 183 / var(--tw-text-opacity))}.text-emerald-400{--tw-text-opacity: 1;color:rgb(52 211 153 / var(--tw-text-opacity))}.text-emerald-50{--tw-text-opacity: 1;color:rgb(236 253 245 / var(--tw-text-opacity))}.text-emerald-50\/90{color:#ecfdf5e6}.text-emerald-950{--tw-text-opacity: 1;color:rgb(2 44 34 / var(--tw-text-opacity))}.text-fuchsia-50{--tw-text-opacity: 1;color:rgb(253 244 255 / var(--tw-text-opacity))}.text-fuchsia-900{--tw-text-opacity: 1;color:rgb(112 26 117 / var(--tw-text-opacity))}.text-indigo-200{--tw-text-opacity: 1;color:rgb(199 210 254 / var(--tw-text-opacity))}.text-indigo-50{--tw-text-opacity: 1;color:rgb(238 242 255 / var(--tw-text-opacity))}.text-indigo-50\/90{color:#eef2ffe6}.text-lime-300{--tw-text-opacity: 1;color:rgb(190 242 100 / var(--tw-text-opacity))}.text-lime-400{--tw-text-opacity: 1;color:rgb(163 230 53 / var(--tw-text-opacity))}.text-neutral-100{--tw-text-opacity: 1;color:rgb(245 245 245 / var(--tw-text-opacity))}.text-neutral-200{--tw-text-opacity: 1;color:rgb(229 229 229 / var(--tw-text-opacity))}.text-neutral-300{--tw-text-opacity: 1;color:rgb(212 212 212 / var(--tw-text-opacity))}.text-neutral-400{--tw-text-opacity: 1;color:rgb(163 163 163 / var(--tw-text-opacity))}.text-neutral-50{--tw-text-opacity: 1;color:rgb(250 250 250 / var(--tw-text-opacity))}.text-neutral-500{--tw-text-opacity: 1;color:rgb(115 115 115 / var(--tw-text-opacity))}.text-red-100{--tw-text-opacity: 1;color:rgb(254 226 226 / var(--tw-text-opacity))}.text-red-100\/90{color:#fee2e2e6}.text-red-100\/95{color:#fee2e2f2}.text-red-200{--tw-text-opacity: 1;color:rgb(254 202 202 / var(--tw-text-opacity))}.text-red-300{--tw-text-opacity: 1;color:rgb(252 165 165 / var(--tw-text-opacity))}.text-red-400{--tw-text-opacity: 1;color:rgb(248 113 113 / var(--tw-text-opacity))}.text-red-50{--tw-text-opacity: 1;color:rgb(254 242 242 / var(--tw-text-opacity))}.text-red-700{--tw-text-opacity: 1;color:rgb(185 28 28 / var(--tw-text-opacity))}.text-rose-300{--tw-text-opacity: 1;color:rgb(253 164 175 / var(--tw-text-opacity))}.text-sky-200{--tw-text-opacity: 1;color:rgb(186 230 253 / var(--tw-text-opacity))}.text-sky-300{--tw-text-opacity: 1;color:rgb(125 211 252 / var(--tw-text-opacity))}.text-slate-100{--tw-text-opacity: 1;color:rgb(241 245 249 / var(--tw-text-opacity))}.text-slate-200{--tw-text-opacity: 1;color:rgb(226 232 240 / var(--tw-text-opacity))}.text-slate-300{--tw-text-opacity: 1;color:rgb(203 213 225 / var(--tw-text-opacity))}.text-slate-400{--tw-text-opacity: 1;color:rgb(148 163 184 / var(--tw-text-opacity))}.text-slate-400\/60{color:#94a3b899}.text-slate-500{--tw-text-opacity: 1;color:rgb(100 116 139 / var(--tw-text-opacity))}.text-slate-900{--tw-text-opacity: 1;color:rgb(15 23 42 / var(--tw-text-opacity))}.text-slate-950{--tw-text-opacity: 1;color:rgb(2 6 23 / var(--tw-text-opacity))}.text-teal-400{--tw-text-opacity: 1;color:rgb(45 212 191 / var(--tw-text-opacity))}.text-white{--tw-text-opacity: 1;color:rgb(255 255 255 / var(--tw-text-opacity))}.text-white\/90{color:#ffffffe6}.text-yellow-400{--tw-text-opacity: 1;color:rgb(250 204 21 / var(--tw-text-opacity))}.underline{text-decoration-line:underline}.accent-cyan-500{accent-color:#06b6d4}.accent-emerald-400{accent-color:#34d399}.accent-emerald-500{accent-color:#10b981}.opacity-0{opacity:0}.opacity-100{opacity:1}.opacity-40{opacity:.4}.opacity-50{opacity:.5}.opacity-70{opacity:.7}.opacity-80{opacity:.8}.opacity-85{opacity:.85}.opacity-90{opacity:.9}.shadow{--tw-shadow: 0 1px 3px 0 rgb(0 0 0 / .1), 0 1px 2px -1px rgb(0 0 0 / .1);--tw-shadow-colored: 0 1px 3px 0 var(--tw-shadow-color), 0 1px 2px -1px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-2xl{--tw-shadow: 0 25px 50px -12px rgb(0 0 0 / .25);--tw-shadow-colored: 0 25px 50px -12px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-\[0_1px_0_rgba\(255\,255\,255\,0\.05\)_inset\,0_10px_24px_rgba\(0\,0\,0\,0\.28\)\]{--tw-shadow: 0 1px 0 rgba(255,255,255,.05) inset,0 10px 24px rgba(0,0,0,.28);--tw-shadow-colored: inset 0 1px 0 var(--tw-shadow-color), 0 10px 24px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-inner{--tw-shadow: inset 0 2px 4px 0 rgb(0 0 0 / .05);--tw-shadow-colored: inset 0 2px 4px 0 var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-lg{--tw-shadow: 0 10px 15px -3px rgb(0 0 0 / .1), 0 4px 6px -4px rgb(0 0 0 / .1);--tw-shadow-colored: 0 10px 15px -3px var(--tw-shadow-color), 0 4px 6px -4px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-md{--tw-shadow: 0 4px 6px -1px rgb(0 0 0 / .1), 0 2px 4px -2px rgb(0 0 0 / .1);--tw-shadow-colored: 0 4px 6px -1px var(--tw-shadow-color), 0 2px 4px -2px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-sm{--tw-shadow: 0 1px 2px 0 rgb(0 0 0 / .05);--tw-shadow-colored: 0 1px 2px 0 var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-xl{--tw-shadow: 0 20px 25px -5px rgb(0 0 0 / .1), 0 8px 10px -6px rgb(0 0 0 / .1);--tw-shadow-colored: 0 20px 25px -5px var(--tw-shadow-color), 0 8px 10px -6px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-black\/30{--tw-shadow-color: rgb(0 0 0 / .3);--tw-shadow: var(--tw-shadow-colored)}.shadow-cyan-950\/50{--tw-shadow-color: rgb(8 51 68 / .5);--tw-shadow: var(--tw-shadow-colored)}.ring-1{--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000)}.ring-2{--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000)}.ring-4{--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(4px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000)}.ring-amber-300{--tw-ring-opacity: 1;--tw-ring-color: rgb(252 211 77 / var(--tw-ring-opacity))}.ring-amber-300\/80{--tw-ring-color: rgb(252 211 77 / .8)}.ring-emerald-300\/70{--tw-ring-color: rgb(110 231 183 / .7)}.ring-red-500\/80{--tw-ring-color: rgb(239 68 68 / .8)}.ring-red-500\/90{--tw-ring-color: rgb(239 68 68 / .9)}.ring-sky-400\/80{--tw-ring-color: rgb(56 189 248 / .8)}.blur{--tw-blur: blur(8px);filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.grayscale{--tw-grayscale: grayscale(100%);filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.invert{--tw-invert: invert(100%);filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.sepia{--tw-sepia: sepia(100%);filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.filter{filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.backdrop-blur-sm{--tw-backdrop-blur: blur(4px);-webkit-backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia);backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia)}.transition{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-\[width\,height\]{transition-property:width,height;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-colors{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-opacity{transition-property:opacity;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-transform{transition-property:transform;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.duration-500{transition-duration:.5s}.duration-700{transition-duration:.7s}@keyframes batteryTickWarn{0%,49%{background-color:#fffffff2}50%,to{background-color:#ef4444f2}}.battery-tick-warn{animation:batteryTickWarn .4s steps(2,end) infinite}@keyframes batteryUrgentFlash{0%,49%{opacity:1}50%,to{opacity:.25}}.battery-urgent-flash{animation:batteryUrgentFlash .4s steps(2,end) infinite}.no-touch-select{-moz-user-select:none;user-select:none;-webkit-user-select:none;-ms-user-select:none;-webkit-touch-callout:none}.mobile-touch-control{user-select:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;-webkit-touch-callout:none;-webkit-tap-highlight-color:transparent;touch-action:manipulation;overscroll-behavior:contain}.mobile-drag-control{touch-action:none}.mobile-text-entry{font-size:16px;-webkit-text-size-adjust:100%;touch-action:manipulation}.\[writing-mode\:vertical-rl\]{writing-mode:vertical-rl}:root{font-family:Inter,system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,sans-serif;--tw-bg-opacity: 1;background-color:rgb(0 0 0 / var(--tw-bg-opacity));--tw-text-opacity: 1;color:rgb(241 245 249 / var(--tw-text-opacity))}body{margin:0;min-height:100vh;--tw-bg-opacity: 1;background-color:rgb(0 0 0 / var(--tw-bg-opacity));--tw-text-opacity: 1;color:rgb(241 245 249 / var(--tw-text-opacity))}html,body,*{scrollbar-width:thin;scrollbar-color:rgba(148,163,184,.55) transparent}@keyframes spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}*::-webkit-scrollbar{width:2px;height:2px}*::-webkit-scrollbar-track{background:transparent}*::-webkit-scrollbar-thumb{background-color:#94a3b88c;border-radius:9999px}@supports (scrollbar-width: thin){@media(pointer:coarse){html,body,*{scrollbar-width:none}}}.placeholder\:text-slate-400::-moz-placeholder{--tw-text-opacity: 1;color:rgb(148 163 184 / var(--tw-text-opacity))}.placeholder\:text-slate-400::placeholder{--tw-text-opacity: 1;color:rgb(148 163 184 / var(--tw-text-opacity))}.last\:mb-0:last-child{margin-bottom:0}.hover\:-translate-y-0\.5:hover{--tw-translate-y: -.125rem;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.hover\:scale-110:hover{--tw-scale-x: 1.1;--tw-scale-y: 1.1;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.hover\:border-green-100:hover{--tw-border-opacity: 1;border-color:rgb(220 252 231 / var(--tw-border-opacity))}.hover\:border-rose-500:hover{--tw-border-opacity: 1;border-color:rgb(244 63 94 / var(--tw-border-opacity))}.hover\:border-sky-500:hover{--tw-border-opacity: 1;border-color:rgb(14 165 233 / var(--tw-border-opacity))}.hover\:border-white:hover{--tw-border-opacity: 1;border-color:rgb(255 255 255 / var(--tw-border-opacity))}.hover\:border-white\/60:hover{border-color:#fff9}.hover\:bg-amber-400:hover{--tw-bg-opacity: 1;background-color:rgb(251 191 36 / var(--tw-bg-opacity))}.hover\:bg-amber-600:hover{--tw-bg-opacity: 1;background-color:rgb(217 119 6 / var(--tw-bg-opacity))}.hover\:bg-amber-800:hover{--tw-bg-opacity: 1;background-color:rgb(146 64 14 / var(--tw-bg-opacity))}.hover\:bg-cyan-400:hover{--tw-bg-opacity: 1;background-color:rgb(34 211 238 / var(--tw-bg-opacity))}.hover\:bg-cyan-800:hover{--tw-bg-opacity: 1;background-color:rgb(21 94 117 / var(--tw-bg-opacity))}.hover\:bg-emerald-400:hover{--tw-bg-opacity: 1;background-color:rgb(52 211 153 / var(--tw-bg-opacity))}.hover\:bg-emerald-500:hover{--tw-bg-opacity: 1;background-color:rgb(16 185 129 / var(--tw-bg-opacity))}.hover\:bg-emerald-700:hover{--tw-bg-opacity: 1;background-color:rgb(4 120 87 / var(--tw-bg-opacity))}.hover\:bg-fuchsia-500:hover{--tw-bg-opacity: 1;background-color:rgb(217 70 239 / var(--tw-bg-opacity))}.hover\:bg-green-400:hover{--tw-bg-opacity: 1;background-color:rgb(74 222 128 / var(--tw-bg-opacity))}.hover\:bg-indigo-500:hover{--tw-bg-opacity: 1;background-color:rgb(99 102 241 / var(--tw-bg-opacity))}.hover\:bg-indigo-800:hover{--tw-bg-opacity: 1;background-color:rgb(55 48 163 / var(--tw-bg-opacity))}.hover\:bg-neutral-700:hover{--tw-bg-opacity: 1;background-color:rgb(64 64 64 / var(--tw-bg-opacity))}.hover\:bg-pink-400:hover{--tw-bg-opacity: 1;background-color:rgb(244 114 182 / var(--tw-bg-opacity))}.hover\:bg-red-600:hover{--tw-bg-opacity: 1;background-color:rgb(220 38 38 / var(--tw-bg-opacity))}.hover\:bg-rose-500:hover{--tw-bg-opacity: 1;background-color:rgb(244 63 94 / var(--tw-bg-opacity))}.hover\:bg-sky-500:hover{--tw-bg-opacity: 1;background-color:rgb(14 165 233 / var(--tw-bg-opacity))}.hover\:bg-slate-600:hover{--tw-bg-opacity: 1;background-color:rgb(71 85 105 / var(--tw-bg-opacity))}.hover\:bg-slate-700\/70:hover{background-color:#334155b3}.hover\:bg-zinc-900:hover{--tw-bg-opacity: 1;background-color:rgb(24 24 27 / var(--tw-bg-opacity))}.hover\:text-blue-500:hover{--tw-text-opacity: 1;color:rgb(59 130 246 / var(--tw-text-opacity))}.hover\:text-white:hover{--tw-text-opacity: 1;color:rgb(255 255 255 / var(--tw-text-opacity))}.hover\:opacity-90:hover{opacity:.9}.hover\:shadow-xl:hover{--tw-shadow: 0 20px 25px -5px rgb(0 0 0 / .1), 0 8px 10px -6px rgb(0 0 0 / .1);--tw-shadow-colored: 0 20px 25px -5px var(--tw-shadow-color), 0 8px 10px -6px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.hover\:brightness-110:hover{--tw-brightness: brightness(1.1);filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.focus\:outline-none:focus{outline:2px solid transparent;outline-offset:2px}.focus\:ring-emerald-500:focus{--tw-ring-opacity: 1;--tw-ring-color: rgb(16 185 129 / var(--tw-ring-opacity))}.focus-visible\:outline-none:focus-visible{outline:2px solid transparent;outline-offset:2px}.focus-visible\:outline:focus-visible{outline-style:solid}.focus-visible\:outline-1:focus-visible{outline-width:1px}.focus-visible\:outline-offset-1:focus-visible{outline-offset:1px}.focus-visible\:outline-slate-500:focus-visible{outline-color:#64748b}.focus-visible\:ring-2:focus-visible{--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000)}.focus-visible\:ring-amber-300:focus-visible{--tw-ring-opacity: 1;--tw-ring-color: rgb(252 211 77 / var(--tw-ring-opacity))}.focus-visible\:ring-cyan-300:focus-visible{--tw-ring-opacity: 1;--tw-ring-color: rgb(103 232 249 / var(--tw-ring-opacity))}.focus-visible\:ring-emerald-200:focus-visible{--tw-ring-opacity: 1;--tw-ring-color: rgb(167 243 208 / var(--tw-ring-opacity))}.focus-visible\:ring-emerald-300:focus-visible{--tw-ring-opacity: 1;--tw-ring-color: rgb(110 231 183 / var(--tw-ring-opacity))}.focus-visible\:ring-indigo-300:focus-visible{--tw-ring-opacity: 1;--tw-ring-color: rgb(165 180 252 / var(--tw-ring-opacity))}.active\:scale-95:active{--tw-scale-x: .95;--tw-scale-y: .95;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.active\:scale-\[0\.99\]:active{--tw-scale-x: .99;--tw-scale-y: .99;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.active\:brightness-125:active{--tw-brightness: brightness(1.25);filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.disabled\:cursor-not-allowed:disabled{cursor:not-allowed}.disabled\:opacity-30:disabled{opacity:.3}.disabled\:opacity-40:disabled{opacity:.4}.disabled\:opacity-50:disabled{opacity:.5}.disabled\:opacity-60:disabled{opacity:.6}.disabled\:opacity-70:disabled{opacity:.7}@media(max-width:520px){.max-\[520px\]\:grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.max-\[520px\]\:justify-start{justify-content:flex-start}}@media(max-width:420px){.max-\[420px\]\:grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.max-\[420px\]\:grid-cols-\[auto_minmax\(0\,1fr\)\]{grid-template-columns:auto minmax(0,1fr)}.max-\[420px\]\:justify-start{justify-content:flex-start}}@media(min-width:640px){.sm\:block{display:block}.sm\:min-h-\[18rem\]{min-height:18rem}.sm\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.sm\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.sm\:grid-cols-\[minmax\(0\,0\.8fr\)_minmax\(0\,1\.2fr\)\]{grid-template-columns:minmax(0,.8fr) minmax(0,1.2fr)}.sm\:text-2xl{font-size:1.5rem;line-height:2rem}.sm\:text-3xl{font-size:1.875rem;line-height:2.25rem}}@media(min-width:768px){.md\:h-full{height:100%}.md\:h-screen{height:100vh}.md\:min-h-0{min-height:0px}.md\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.md\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.md\:grid-cols-\[0\.9fr_1fr_1\.3fr\]{grid-template-columns:.9fr 1fr 1.3fr}.md\:grid-cols-\[minmax\(0\,1\.4fr\)_minmax\(0\,1fr\)\]{grid-template-columns:minmax(0,1.4fr) minmax(0,1fr)}.md\:grid-cols-\[minmax\(0\,1\.5fr\)_minmax\(0\,1fr\)\]{grid-template-columns:minmax(0,1.5fr) minmax(0,1fr)}.md\:grid-cols-\[minmax\(0\,1fr\)_18rem\]{grid-template-columns:minmax(0,1fr) 18rem}.md\:overflow-hidden{overflow:hidden}.md\:overflow-y-auto{overflow-y:auto}.md\:text-lg{font-size:1.125rem;line-height:1.75rem}.md\:text-xl{font-size:1.25rem;line-height:1.75rem}}@media(min-width:1024px){.lg\:col-span-2{grid-column:span 2 / span 2}.lg\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.lg\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.lg\:grid-cols-6{grid-template-columns:repeat(6,minmax(0,1fr))}.lg\:grid-cols-\[minmax\(0\,1\.25fr\)_minmax\(0\,0\.9fr\)\]{grid-template-columns:minmax(0,1.25fr) minmax(0,.9fr)}.lg\:grid-cols-\[minmax\(0\,1fr\)_20rem\]{grid-template-columns:minmax(0,1fr) 20rem}.lg\:grid-cols-\[minmax\(0\,1fr\)_9rem_10rem\]{grid-template-columns:minmax(0,1fr) 9rem 10rem}.lg\:text-right{text-align:right}} diff --git a/server/public/index.html b/server/public/index.html index 27a34284..dedd9fce 100644 --- a/server/public/index.html +++ b/server/public/index.html @@ -78,8 +78,8 @@ Roomba Rover - - + +
diff --git a/server/src/services/barcodeGameService/games/mostItems.js b/server/src/services/barcodeGameService/games/mostItems.js index 099a5bec..15d89866 100644 --- a/server/src/services/barcodeGameService/games/mostItems.js +++ b/server/src/services/barcodeGameService/games/mostItems.js @@ -316,7 +316,7 @@ module.exports = { id: GAME_ID, title: 'Most items', description: 'Scan as many different known objects as possible.', - themeColor: { r: 16, g: 185, b: 129 }, + themeColor: { r: 255, g: 145, b: 71 }, createInitialState, normalizeState, activate, diff --git a/server/src/services/barcodeGameService/games/scanQuest.js b/server/src/services/barcodeGameService/games/scanQuest.js index 8a62b6e5..d890b2e6 100644 --- a/server/src/services/barcodeGameService/games/scanQuest.js +++ b/server/src/services/barcodeGameService/games/scanQuest.js @@ -301,7 +301,7 @@ module.exports = { id: GAME_ID, title: 'Scan quest', description: 'Scan one or two requested objects in order.', - themeColor: { r: 34, g: 211, b: 238 }, + themeColor: { r: 255, g: 150, b: 252 }, createInitialState, normalizeState, activate, diff --git a/server/src/services/barcodeGameService/games/scansPerSecond.js b/server/src/services/barcodeGameService/games/scansPerSecond.js index fb2072e1..6e698d82 100644 --- a/server/src/services/barcodeGameService/games/scansPerSecond.js +++ b/server/src/services/barcodeGameService/games/scansPerSecond.js @@ -319,7 +319,7 @@ module.exports = { id: GAME_ID, title: 'Scans per second', description: 'Count every scan for five minutes and save the world record.', - themeColor: { r: 245, g: 158, b: 11 }, + themeColor: { r: 72, g: 245, b: 66 }, createInitialState, normalizeState, activate, diff --git a/webui/src/components/BarcodeGamesPanel/index.jsx b/webui/src/components/BarcodeGamesPanel/index.jsx index a4539d1d..b15c4c23 100644 --- a/webui/src/components/BarcodeGamesPanel/index.jsx +++ b/webui/src/components/BarcodeGamesPanel/index.jsx @@ -154,35 +154,36 @@ function Leaderboard({ players, ownPlayer }) { const hasOwnPoints = ownPlayer && Number.isFinite(ownPlayer.totalPoints); return (
-
-
-

Your points

-

- {hasOwnPoints ? ownPlayer.totalPoints : 0} +

+
+

Your points

+

+ {ownPlayer?.rank ? `Rank ${ownPlayer.rank}` : 'No rank yet'}

- {ownPlayer?.rank ?

Rank {ownPlayer.rank}

: null} -
-
-

Leaderboard

- {Array.isArray(players) && players.length ? ( -
- {players.slice(0, 4).map((player, idx) => ( -
- {idx + 1} - {player.nickname} - {player.totalPoints} -
- ))} -
- ) : ( -

No points yet

- )}
+

+ {hasOwnPoints ? ownPlayer.totalPoints : 0} +

+
+
+

Leaderboard

+ {Array.isArray(players) && players.length ? ( +
+ {players.slice(0, 4).map((player, idx) => ( +
+ {idx + 1} + {player.nickname} + {player.totalPoints} +
+ ))} +
+ ) : ( +

No points yet

+ )}
); } - export default function BarcodeGamesPanel() { const { state, connectionState, voteForGame } = useBarcodeGameState(); const [pendingGameId, setPendingGameId] = useState(null);