cicy-desktop 2.1.317 → 2.1.319
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/backends/homepage-react/assets/{index-1rHgzzS_.js → index-CriNT9kd.js} +1 -1
- package/src/backends/homepage-react/index.html +1 -1
- package/src/backends/local-teams.js +8 -2
- package/src/backends/sidecar-ipc.js +10 -2
- package/src/main.js +2 -2
- package/test/cicy-runtime-health.test.js +17 -0
- package/workers/render/src/App.jsx +5 -2
package/package.json
CHANGED
|
@@ -374,4 +374,4 @@ Error generating stack: `+l.message+`
|
|
|
374
374
|
`};function Pp(s){return s.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">")}function Ll(s){return Pp(s).replace(/\*\*([^*]+)\*\*/g,"<strong>$1</strong>").replace(/`([^`]+)`/g,"<code>$1</code>")}function mm(s){return s.trim().replace(/^\|/,"").replace(/\|$/,"").split("|").map(b=>b.trim())}function ty(s){const b=String(s||"").replace(/\r\n/g,`
|
|
375
375
|
`).split(`
|
|
376
376
|
`),S=[];let d=0;for(;d<b.length;){const j=b[d];if(!j.trim()){d++;continue}if(/^---+\s*$/.test(j)){S.push("<hr/>"),d++;continue}const M=/^(#{1,6})\s+(.*)$/.exec(j);if(M){const k=Math.min(M[1].length,6);S.push(`<h${k}>${Ll(M[2])}</h${k}>`),d++;continue}if(j.trim().startsWith("|")&&d+1<b.length&&/^\s*\|?[\s:|-]+\|?\s*$/.test(b[d+1])&&b[d+1].includes("-")){const k=mm(j);d+=2;const Y=[];for(;d<b.length&&b[d].trim().startsWith("|");)Y.push(mm(b[d])),d++;let T="<table><thead><tr>";T+=k.map(m=>`<th>${Ll(m)}</th>`).join(""),T+="</tr></thead><tbody>";for(const m of Y)T+="<tr>"+m.map(B=>`<td>${Ll(B)}</td>`).join("")+"</tr>";T+="</tbody></table>",S.push(T);continue}if(j.trim().startsWith(">")){const k=[];for(;d<b.length&&b[d].trim().startsWith(">");)k.push(b[d].replace(/^\s*>\s?/,"")),d++;S.push(`<blockquote>${k.map(Ll).join("<br/>")}</blockquote>`);continue}if(/^\s*-\s+/.test(j)){const k=[];for(;d<b.length&&/^\s*-\s+/.test(b[d]);)k.push(`<li>${Ll(b[d].replace(/^\s*-\s+/,""))}</li>`),d++;S.push(`<ul>${k.join("")}</ul>`);continue}if(/^\s*\d+\.\s+/.test(j)){const k=[];for(;d<b.length&&/^\s*\d+\.\s+/.test(b[d]);)k.push(`<li>${Ll(b[d].replace(/^\s*\d+\.\s+/,""))}</li>`),d++;S.push(`<ol>${k.join("")}</ol>`);continue}S.push(`<p>${Ll(j)}</p>`),d++}return S.join(`
|
|
377
|
-
`)}function ey({title:s,url:b}={}){const S=String(s||"").trim();return S?{ok:!0,patch:{name:S,base_url:String(b||"").trim()}}:{ok:!1,error:"title_required"}}const r=(s,b,S)=>{var j,M;const d=k=>S&&typeof k=="string"?k.replace(/\{\{\s*(\w+)\s*\}\}/g,(Y,T)=>S[T]!=null?String(S[T]):Y):k;try{const k=(M=(j=window.cicyI18n)==null?void 0:j.t)==null?void 0:M.call(j,s,S);return d(k&&k!==s?k:b)}catch{return d(b)}},jn="cicy_token",Ru="cicy_access_token",Si="cicy_user_id",ay="cicy_guest",ql="https://cicy-ai.com",ly=1;async function Em(s){var S,d,j,M,k,Y,T,m;const b=`${ql}/dash${s}`;try{if((d=(S=window.cicy)==null?void 0:S.tabs)!=null&&d.openIn){await window.cicy.tabs.openIn(ly,b,"cicy-ai");return}(k=(M=(j=window.cicy)==null?void 0:j.shell)==null?void 0:M.openExternal)==null||k.call(M,b)}catch{try{(m=(T=(Y=window.cicy)==null?void 0:Y.shell)==null?void 0:T.openExternal)==null||m.call(T,b)}catch{}}}const eo=new Set;let ny=0,Sl=[];const xi=new Map;function hm(){eo.forEach(s=>s(Sl))}const Tt={show(s={}){const b=s.id||`t${++ny}`,S=Sl.find(M=>M.id===b),d={id:b,status:"running",...S,...s};Sl=S?Sl.map(M=>M.id===b?d:M):[...Sl,d],hm();const j=xi.get(b);return j&&(clearTimeout(j),xi.delete(b)),s.ttl&&xi.set(b,setTimeout(()=>Tt.dismiss(b),s.ttl)),b},dismiss(s){Sl=Sl.filter(S=>S.id!==s);const b=xi.get(s);b&&(clearTimeout(b),xi.delete(s)),hm()}};function iy(){const[s,b]=v.useState(Sl);return v.useEffect(()=>(eo.add(b),()=>{eo.delete(b)}),[]),s.length?c.jsx("div",{className:"toast-host","data-id":"ToastHost",children:s.map(S=>c.jsxs("div",{className:"toast","data-id":`Toast-${S.id}`,"data-status":S.status||"running",children:[c.jsx("button",{type:"button",className:"toast__x","data-id":"Toast-dismiss",onClick:()=>Tt.dismiss(S.id),"aria-label":"dismiss",children:"×"}),c.jsxs("span",{className:"toast__msg",children:[S.message,Number.isFinite(S.progress)?` ${S.progress}%`:""]}),Number.isFinite(S.progress)&&c.jsx("span",{className:"toast__bar",children:c.jsx("span",{style:{width:`${Math.min(100,S.progress)}%`}})})]},S.id))}):null}const ao=new Set;let Is=0,Ft=null;function vl(){ao.forEach(s=>s(Ft))}function _i(){return new Date().toTimeString().slice(0,8)}const me={open({teamId:s,fromVer:b,toVer:S,onRetry:d,title:j,kind:M}={}){Ft={teamId:s,title:j||null,fromVer:b||null,toVer:S||null,kind:M||"sidecar",status:"running",phase:"download",progress:null,onInstall:null,logs:[],onRetry:d||null,lastAt:Date.now()},vl()},setProgress(s){Ft&&(Ft={...Ft,status:"running",progress:s||Ft.progress,lastAt:Date.now()},vl())},ready({onInstall:s,message:b}={}){if(!Ft)return;const S={id:++Is,t:_i(),phase:"done",status:"done",message:b||r("updateBanner.readyDrawer","下载完成,点「安装」重启更新")};Ft={...Ft,status:"ready",phase:"done",progress:{...Ft.progress||{},percent:100},onInstall:s||null,minimized:!1,logs:[...Ft.logs,S],lastAt:Date.now()},vl()},push(s={}){if(!Ft)return;const b={id:++Is,t:_i(),phase:s.phase||Ft.phase,status:s.status||"running",message:s.message||""};Ft={...Ft,phase:s.phase||Ft.phase,toVer:s.toVer||Ft.toVer,logs:[...Ft.logs,b],lastAt:Date.now()},vl()},minimize(){Ft&&(Ft={...Ft,minimized:!0},vl())},restore(){Ft&&(Ft={...Ft,minimized:!1},vl())},finish({ok:s,message:b}={}){if(!Ft)return;const S=s?"done":"error",d={id:++Is,t:_i(),phase:"done",status:S,message:b||(s?r("updateDrawer.done","更新完成"):r("updateDrawer.failed","更新失败"))};Ft={...Ft,status:S,phase:"done",minimized:!1,logs:[...Ft.logs,d],lastAt:Date.now()},vl()},close(){Ft=null,vl()}},Ps=["download","swap","done"],pm=s=>({download:r("updateDrawer.phaseDownload","下载"),swap:r("updateDrawer.phaseSwap","切换"),done:r("updateDrawer.phaseDone","完成")})[s]||s;function uy(){var Y;const[s,b]=v.useState(Ft);v.useEffect(()=>(ao.add(b),()=>{ao.delete(b)}),[]);const S=v.useRef(null);v.useEffect(()=>{const T=S.current;T&&(T.scrollTop=T.scrollHeight)},[(Y=s==null?void 0:s.logs)==null?void 0:Y.length]);const[d,j]=v.useState(!1);if(v.useEffect(()=>{if(!s||s.status!=="running"){j(!1);return}const T=setInterval(()=>j(Date.now()-(s.lastAt||0)>25e3),3e3);return()=>clearInterval(T)},[s==null?void 0:s.lastAt,s==null?void 0:s.status]),!s)return null;const M=s.status==="running",k=Ps.findIndex(T=>T===s.phase);return s.minimized?c.jsxs("button",{type:"button",className:`drawer-min drawer-min--${s.status}`,"data-id":"UpdateDrawer-restore",onClick:()=>me.restore(),children:[c.jsx("span",{className:"drawer-min__spark",children:M?c.jsx(ca,{}):s.status==="done"?"✓":s.status==="reboot"?"⟳":"!"}),c.jsxs("span",{className:"drawer-min__label",children:[s.title||r("updateDrawer.title","更新 cicy-code"),s.toVer?` · v${s.toVer}`:""]})]}):c.jsx("div",{className:"drawer-scrim","data-id":"UpdateDrawer-scrim",onClick:()=>M?me.minimize():me.close(),children:c.jsxs("div",{className:"drawer","data-id":"UpdateDrawer","data-status":s.status,onClick:T=>T.stopPropagation(),children:[c.jsxs("div",{className:"drawer__head",children:[c.jsxs("div",{className:"drawer__title",children:[c.jsx("span",{className:`drawer__spark drawer__spark--${s.status}`,children:M?c.jsx(ca,{}):s.status==="done"?"✓":s.status==="reboot"?"⟳":"!"}),c.jsxs("div",{children:[c.jsx("div",{className:"drawer__h",children:s.title||r("updateDrawer.title","更新 cicy-code")}),c.jsxs("div",{className:"drawer__sub",children:[s.fromVer?`v${s.fromVer}`:r("updateDrawer.current","当前")," → ",s.toVer?`v${s.toVer}`:r("updateDrawer.latest","最新版")]})]})]}),c.jsx("div",{className:"drawer__headbtns",children:c.jsx("button",{type:"button",className:"drawer__x","data-id":"UpdateDrawer-min",title:r("updateDrawer.minimize","最小化"),onClick:()=>me.minimize(),"aria-label":"minimize",children:"‒"})})]}),s.kind!=="app"&&c.jsx("div",{className:"drawer__steps","data-id":"UpdateDrawer-steps",children:Ps.map((T,m)=>{const B=pm(T),E=s.status==="done"||m<k,F=m===k&&M,H=s.status==="error"&&m===k;return c.jsxs("div",{className:`drawer__step${F?" is-active":""}${E?" is-done":""}${H?" is-error":""}`,children:[c.jsx("span",{className:"drawer__step-dot",children:E?"✓":H?"!":m+1}),c.jsx("span",{className:"drawer__step-label",children:B}),m<Ps.length-1&&c.jsx("span",{className:"drawer__step-bar"})]},T)})}),s.progress&&(()=>{const T=s.progress,m=B=>B?(B/1048576).toFixed(1):"0";return c.jsxs("div",{className:"drawer__dl","data-id":"UpdateDrawer-dl",children:[c.jsxs("div",{className:"drawer__dl-head",children:[c.jsxs("span",{className:"drawer__dl-pct",children:[T.percent||0,"%"]}),c.jsxs("span",{className:"drawer__dl-stats",children:[T.total?`${m(T.transferred)} / ${m(T.total)} MB`:`${m(T.transferred)} MB`,T.bytesPerSec?` · ${m(T.bytesPerSec)} MB/s`:"",T.etaSec?` · ${r("updateBanner.eta","剩 {{s}}s",{s:T.etaSec})}`:""]})]}),c.jsx("div",{className:"drawer__dl-track",children:c.jsx("span",{className:"drawer__dl-fill",style:{width:`${T.percent||0}%`}})})]})})(),c.jsx("div",{className:"drawer__log","data-id":"UpdateDrawer-log",ref:S,children:s.logs.length===0?c.jsx("div",{className:"drawer__log-empty",children:r("updateDrawer.preparing","准备中…")}):s.logs.map(T=>c.jsxs("div",{className:"drawer__line","data-status":T.status,children:[c.jsx("span",{className:"drawer__t",children:T.t}),c.jsx("span",{className:`drawer__badge drawer__badge--${T.phase}`,children:pm(T.phase)}),c.jsx("span",{className:"drawer__linemsg",children:T.message})]},T.id))}),d&&M&&c.jsx("div",{className:"drawer__hint","data-id":"UpdateDrawer-stuck",children:r("updateDrawer.stuckHint","正在等待新版本就绪,耗时比平常久。可以放到后台继续,完成或失败都会提示。")}),c.jsx("div",{className:"drawer__foot",children:M?c.jsx(c.Fragment,{children:c.jsx("span",{className:"drawer__foot-status",children:s.kind==="app"?r("updateBanner.downloading","正在下载更新")+"…":r("updateDrawer.inProgress","更新进行中…")})}):s.status==="ready"?c.jsxs(c.Fragment,{children:[c.jsx("span",{className:"drawer__foot-status is-done",children:r("updateBanner.readyShort","下载完成")}),c.jsx("button",{type:"button",className:"drawer__btn is-accent","data-id":"UpdateDrawer-install",onClick:()=>s.onInstall&&s.onInstall(),children:r("updateBanner.installBtn","立即安装")}),c.jsx("button",{type:"button",className:"drawer__btn","data-id":"UpdateDrawer-later",onClick:()=>me.close(),children:r("updateBanner.later","稍后")})]}):s.status==="error"?c.jsxs(c.Fragment,{children:[c.jsx("span",{className:"drawer__foot-status is-error",children:r("updateDrawer.failed","更新失败")}),s.onRetry&&c.jsx("button",{type:"button",className:"drawer__btn is-accent","data-id":"UpdateDrawer-retry",onClick:()=>s.onRetry(),children:r("common.retry","重试")}),c.jsx("button",{type:"button",className:"drawer__btn","data-id":"UpdateDrawer-dismiss",onClick:()=>me.close(),children:r("common.close","关闭")})]}):c.jsxs(c.Fragment,{children:[c.jsx("span",{className:"drawer__foot-status is-done",children:r("updateDrawer.updatedLatest","已更新到最新")}),c.jsx("button",{type:"button",className:"drawer__btn is-accent","data-id":"UpdateDrawer-finish",onClick:()=>me.close(),children:r("common.done","完成")})]})})]})})}function cy(){const[s,b]=v.useState(void 0);v.useEffect(()=>{var D,V;if(!((V=(D=window.cicy)==null?void 0:D.terms)!=null&&V.status)){b(!0);return}window.cicy.terms.status(Am).then(K=>b(!!(K!=null&&K.accepted))).catch(()=>b(!0))},[]),v.useEffect(()=>{var K,et,tt,$t;const D=document.documentElement;try{D.setAttribute("data-platform",((K=window.cicy)==null?void 0:K.platform)||"linux")}catch{}D.setAttribute("data-fullscreen","0");let V;try{V=($t=(tt=(et=window.cicy)==null?void 0:et.window)==null?void 0:tt.onFullscreen)==null?void 0:$t.call(tt,Et=>D.setAttribute("data-fullscreen",Et?"1":"0"))}catch{}return()=>{try{V&&V()}catch{}}},[]),v.useEffect(()=>{var V,K;if(!((K=(V=window.cicy)==null?void 0:V.docker)!=null&&K.onAppProgress))return;const D=window.cicy.docker.onAppProgress(et=>{!et||et.phase==="open"||(Qt||Ot.open({source:"auto"}),(Qt==null?void 0:Qt.source)==="auto"&&(et.phase==="done"&&(et.status==="done"||et.status==="reboot")?Ot.finish({ok:et.status==="done",status:et.status==="reboot"?"reboot":void 0,message:et.message}):et.status==="error"?Ot.finish({ok:!1,message:et.message}):Ot.push(et)))});return()=>{try{D&&D()}catch{}}},[]);const[S,d]=v.useState(()=>An(jn)),[j,M]=v.useState(()=>An(Ru)),[k,Y]=v.useState(()=>An(Si)),[T,m]=v.useState(()=>!An(jn)),[B,E]=v.useState(!0),F=()=>E(!0),[H,$]=v.useState(!1),[Q,yt]=v.useState(!1),[Nt,ce]=v.useState(""),[ot,Lt]=v.useState(""),[ct,xt]=v.useState(!1),[G,gt]=v.useState(""),[L,ht]=v.useState(""),[Ct,jt]=v.useState(null),[bt,kt]=v.useState(null),[Jt,C]=v.useState(!1),[q,nt]=v.useState(""),zt=v.useRef(!1),[_t,h]=v.useState(null),[N,Z]=v.useState(!1),[W,ft]=v.useState(!1),[vt,Ut]=v.useState({}),ne=v.useCallback(async()=>{var D,V,K;try{const et=await((K=(V=(D=window.cicy)==null?void 0:D.localTeams)==null?void 0:V.avatars)==null?void 0:K.call(V));Ut(et&&typeof et=="object"?et:{})}catch{}},[]),[Zt,ke]=v.useState(!1),[J,Rt]=v.useState(!1),[je,se]=v.useState(""),[Me,ve]=v.useState(""),[Ye,sa]=v.useState(!1),[Le,ye]=v.useState(""),[Ge,Qe]=v.useState("all"),Pe=v.useCallback(async(D,V)=>{var et,tt,$t,Et;if(!D)return;if(!((tt=(et=window.cicy)==null?void 0:et.cloud)!=null&&tt.fetch)){nt("cloud fetch bridge missing");return}C(!0),nt("");const K={Authorization:`Bearer ${D}`};try{const[Ze,ze]=await Promise.all([window.cicy.cloud.fetch(`${ql}/api/user/self`,{headers:K}),window.cicy.cloud.fetch(`${ql}/api/teams`,{headers:K})]);if((ze==null?void 0:ze.status)===401){if(!zt.current&&((Et=($t=window.cicy)==null?void 0:$t.auth)!=null&&Et.loginStart)){zt.current=!0,nt(r("auth.sessionExpired","会话已过期,正在重新登录…"));try{await window.cicy.auth.loginStart()}catch{}}return}if(ze!=null&&ze.ok){const xe=JSON.parse(ze.body||"{}");kt(Array.isArray(xe==null?void 0:xe.teams)?xe.teams:[])}else kt(xe=>xe===null?[]:xe);if(Ze!=null&&Ze.ok)try{const xe=JSON.parse(Ze.body||"{}");jt((xe==null?void 0:xe.success)===!1?null:(xe==null?void 0:xe.data)||null)}catch{jt(null)}else jt(null)}catch{nt(""),kt(ze=>ze===null?[]:ze)}finally{C(!1)}},[]),oe=v.useRef("");v.useEffect(()=>{oe.current=S||j||""},[S,j]);const R=v.useCallback(async()=>{var V,K;const D=oe.current;if(!(!D||!((K=(V=window.cicy)==null?void 0:V.cloud)!=null&&K.fetch)))try{const et=await window.cicy.cloud.fetch(`${ql}/api/teams`,{headers:{Authorization:`Bearer ${D}`}});if(et!=null&&et.ok){const tt=JSON.parse(et.body||"{}");Array.isArray(tt==null?void 0:tt.teams)&&kt(tt.teams)}}catch{}},[]),it=v.useCallback(async(D,V)=>{var tt,$t;const K=oe.current,et=String(V||"").trim();if(!K||!(($t=(tt=window.cicy)==null?void 0:tt.cloud)!=null&&$t.fetch)||!et)return{ok:!1,error:"no session / empty"};try{const Et=await window.cicy.cloud.fetch(`${ql}/api/teams/${D}`,{method:"PATCH",headers:{Authorization:`Bearer ${K}`,"Content-Type":"application/json"},body:JSON.stringify({title:et})});return Et!=null&&Et.ok?(await R(),{ok:!0}):{ok:!1,error:`${(Et==null?void 0:Et.status)||"?"} ${(Et==null?void 0:Et.error)||""}`}}catch(Et){return{ok:!1,error:Et.message}}},[R]),at=v.useCallback(async(D,V)=>{var tt,$t;const K=oe.current,et=String(V||"").trim();if(!K||!(($t=(tt=window.cicy)==null?void 0:tt.cloud)!=null&&$t.fetch)||!et)return{ok:!1,error:"no session / empty"};try{new URL(et)}catch{return{ok:!1,error:"地址格式不对(需 http(s)://…)"}}try{const Et=await window.cicy.cloud.fetch(`${ql}/api/teams/${D}`,{method:"PATCH",headers:{Authorization:`Bearer ${K}`,"Content-Type":"application/json"},body:JSON.stringify({hostUrl:et})});return Et!=null&&Et.ok?(await R(),{ok:!0}):{ok:!1,error:`${(Et==null?void 0:Et.status)||"?"} ${(Et==null?void 0:Et.error)||""}`}}catch(Et){return{ok:!1,error:Et.message}}},[R]),ut=v.useCallback(async D=>{var K,et;const V=oe.current;if(!V||!((et=(K=window.cicy)==null?void 0:K.cloud)!=null&&et.fetch)){Tt.show({message:r("common.noAuth","未登录"),status:"error",ttl:5e3});return}try{const tt=await window.cicy.cloud.fetch(`${ql}/api/teams/${D.id}`,{method:"DELETE",headers:{Authorization:`Bearer ${V}`}});tt!=null&&tt.ok||(tt==null?void 0:tt.status)===200||(tt==null?void 0:tt.status)===204?(Tt.show({message:r("teamCard.deleted","团队已删除"),status:"done",ttl:3e3}),await R()):Tt.show({message:`${r("teamCard.deleteFailed","删除失败")}: ${(tt==null?void 0:tt.status)||"?"} ${(tt==null?void 0:tt.error)||""}`,status:"error",ttl:7e3})}catch(tt){Tt.show({message:`${r("teamCard.deleteFailed","删除失败")}: ${tt.message}`,status:"error",ttl:7e3})}},[R]);v.useEffect(()=>{const D=S||j;D?Pe(D,k):kt(V=>V===null?[]:V)},[S,j,k,Pe]);const St=v.useCallback(async()=>{var D,V;if((V=(D=window.cicy)==null?void 0:D.localTeams)!=null&&V.list){Z(!0);try{const K=await window.cicy.localTeams.list({refresh:!0,uid:An(Si)||""});h(Array.isArray(K)?K:[])}catch{h([])}finally{Z(!1),ft(!0)}}},[]);async function qt(){if(Ye)return;const D=Me.trim();if(!D){ye(r("teams.urlRequired","请输入地址 URL"));return}try{new URL(D)}catch{ye(r("teams.badUrl","URL 无效(需含 http(s)://)"));return}ye(""),sa(!0);try{const V=await window.cicy.localTeams.add({base_url:D,name:je.trim(),failIfExists:!0});if(!V||V.ok===!1){ye((V==null?void 0:V.error)==="exists"?r("teams.urlExists","该地址已存在"):wi((V==null?void 0:V.error)||"add failed"));return}await St(),se(""),ve(""),Rt(!1)}catch(V){ye(wi((V==null?void 0:V.message)||String(V)))}finally{sa(!1)}}const ie=v.useCallback(async(D,V)=>{var et,tt;if(!((tt=(et=window.cicy)==null?void 0:et.localTeams)!=null&&tt.update))return{ok:!1,error:"no_bridge"};let K;try{K=await window.cicy.localTeams.update(D,{name:String(V||"").trim()||r("localTeams.unnamed","未命名")})}catch($t){K={ok:!1,error:($t==null?void 0:$t.message)||String($t)}}return await St(),K||{ok:!1,error:"no_result"}},[St]);v.useEffect(()=>{let D,V=!1;const K=3e3,et=3e4,tt=async()=>{var Ze,ze,xe;try{await((xe=(ze=(Ze=window.cicy)==null?void 0:Ze.localTeams)==null?void 0:ze.syncCloud)==null?void 0:xe.call(ze))}catch{}await Promise.all([St(),R(),ne()])},$t=()=>{if(V)return;const Ze=document.visibilityState==="visible";D=setTimeout(async()=>{document.visibilityState==="visible"?await tt():await St(),$t()},Ze?K:et)};tt(),$t();const Et=()=>{document.visibilityState==="visible"&&tt()};return document.addEventListener("visibilitychange",Et),window.addEventListener("focus",Et),()=>{V=!0,clearTimeout(D),document.removeEventListener("visibilitychange",Et),window.removeEventListener("focus",Et)}},[St,R]),v.useEffect(()=>{var V,K;if(!((K=(V=window.cicy)==null?void 0:V.localTeams)!=null&&K.onWebviewRelay))return;const D=window.cicy.localTeams.onWebviewRelay(async({reqId:et,msg:tt})=>{let $t={ok:!1,error:"unknown relay type"};try{(tt==null?void 0:tt.type)==="localTeams:add"?$t=await window.cicy.localTeams.add(tt.spec||{}):(tt==null?void 0:tt.type)==="localTeams:remove"?$t=await window.cicy.localTeams.remove(tt.id):(tt==null?void 0:tt.type)==="localTeams:update"?$t=await window.cicy.localTeams.update(tt.id,tt.patch||{}):(tt==null?void 0:tt.type)==="localTeams:upgrade"?$t=await window.cicy.localTeams.upgrade(tt.id):(tt==null?void 0:tt.type)==="localTeams:list"&&($t={ok:!0,teams:await window.cicy.localTeams.list({refresh:!0})}),St()}catch(Et){$t={ok:!1,error:(Et==null?void 0:Et.message)||String(Et)}}try{window.cicy.localTeams.replyWebviewRelay(et,$t)}catch{}});return()=>{try{D==null||D()}catch{}}},[St]);const g=v.useCallback(async D=>{var V,K;if((K=(V=window.cicy)==null?void 0:V.localTeams)!=null&&K.open)try{await window.cicy.localTeams.open(D)}catch{}},[]);v.useEffect(()=>{var V,K;if(An(jn)){m(!1);return}if(!((K=(V=window.cicy)==null?void 0:V.auth)!=null&&K.getSaved)){m(!1);return}let D=!1;return(async()=>{try{const et=await window.cicy.auth.getSaved();if(D)return;if(et!=null&&et.token){try{localStorage.setItem(jn,et.token)}catch{}if(d(et.token),et.accessToken){try{localStorage.setItem(Ru,et.accessToken)}catch{}M(et.accessToken)}if(et.userId){try{localStorage.setItem(Si,String(et.userId))}catch{}Y(String(et.userId))}}}catch{}finally{D||m(!1)}})(),()=>{D=!0}},[]),v.useEffect(()=>{var D,V;if((V=(D=window.cicy)==null?void 0:D.auth)!=null&&V.onComplete)return window.cicy.auth.onComplete(K=>{if($(!1),xt(!1),K!=null&&K.error){gt(wi(K.error));return}if(K!=null&&K.token){zt.current=!1,nt("");try{localStorage.setItem(jn,K.token)}catch{}d(K.token);try{localStorage.removeItem(ay)}catch{}if(K.accessToken){try{localStorage.setItem(Ru,K.accessToken)}catch{}M(K.accessToken)}if(K.userId){try{localStorage.setItem(Si,String(K.userId))}catch{}Y(String(K.userId))}gt(""),ht(K.reused?r("auth.welcomeBack","已恢复你之前的登录"):r("auth.loginSuccess","登录成功")),setTimeout(()=>ht(""),3e3)}})},[]);function X(){var D,V,K;try{localStorage.removeItem(jn),localStorage.removeItem(Ru),localStorage.removeItem(Si)}catch{}try{(K=(V=(D=window.cicy)==null?void 0:D.auth)==null?void 0:V.logout)==null||K.call(V)}catch{}d(null),M(null),Y(null),jt(null),kt(null),gt(""),nt("")}if(s===void 0)return c.jsxs("div",{className:"shell","data-id":"TermsCheckingSplash",children:[c.jsx("div",{className:"glow","aria-hidden":!0}),c.jsxs("div",{className:"card",children:[c.jsx(_m,{}),c.jsx("div",{className:"spinner-row",children:c.jsx(ca,{})})]})]});if(!s)return c.jsx(Dm,{onAgree:()=>b(!0)});if(!S&&T)return c.jsxs("div",{className:"shell","data-id":"AuthRestoringSplash",children:[c.jsx("div",{className:"glow","aria-hidden":!0}),c.jsxs("div",{className:"card",children:[c.jsx(_m,{}),c.jsxs("div",{className:"spinner-row",children:[c.jsx(ca,{}),c.jsx("span",{children:r("auth.restoring","正在恢复登录…")})]})]})]});const I=(_t||[]).find(D=>vm(D.base_url))||null,P=I&&I.cloud_team_id?(bt||[]).find(D=>String(D.teamId||D.id)===String(I.cloud_team_id)):null,rt=D=>{if(!D)return null;const V=(bt||[]).find(K=>String(K.teamId||K.id)===String(D));return V&&V.code||null},mt=(_t||[]).filter(D=>no(D.base_url)),Mt=(_t||[]).filter(D=>!no(D.base_url)&&!vm(D.base_url)),Ee=mt.length+(I?1:0),oa=Mt.length,Ta=(bt||[]).filter(D=>!D.is_local&&D.kind!=="local"&&(D.kind==="private"||D.team_kind==="personal")),It=Ta.length,Se=Ge==="all"||Ge==="local",Da=Ge==="all"||Ge==="custom",Ca=Ge==="all"||Ge==="cloud",xl=_t===null||bt===null;return c.jsxs("div",{className:"shell shell--app",children:[c.jsx("div",{className:"glow glow--app","aria-hidden":!0}),c.jsxs("div",{className:"shell__left",children:[c.jsx(ry,{me:Ct,welcome:L,onLogout:X,guest:!S&&B,onLogin:F,mitmTeam:mt.length>0?mt[0]:null}),c.jsx(gy,{}),c.jsxs("main",{className:"main",children:[c.jsxs("div",{className:"app__tabsrow",children:[c.jsx("div",{className:"app__tabs",children:[{k:"all",label:r("teamFilter.all","全部"),n:Ee+oa+It},{k:"local",label:r("teamFilter.local","本地"),n:Ee},{k:"cloud",label:r("teamFilter.cloud","私有云"),n:It},{k:"custom",label:r("teamFilter.custom","自定义"),n:oa}].filter(({k:D})=>D!=="cloud"||S).map(({k:D,label:V,n:K})=>c.jsxs("button",{type:"button",className:`app__tab ${Ge===D?"is-active":""}`,onClick:()=>Qe(D),children:[V,c.jsx("span",{className:"app__tab-count",children:K})]},D))}),c.jsxs("div",{"data-id":"AddTeamWrap",style:{position:"relative"},children:[c.jsxs("button",{type:"button","data-id":"AddTeamButton",className:"app__add-team",title:r("teams.addHint","添加团队"),onClick:()=>ke(D=>!D),children:["+ ",r("teams.add","新加团队")]}),Zt&&c.jsxs(c.Fragment,{children:[c.jsx("div",{onClick:()=>ke(!1),style:{position:"fixed",inset:0,zIndex:40}}),c.jsxs("div",{"data-id":"AddTeamMenu",role:"menu",style:{position:"absolute",top:"calc(100% + 6px)",right:0,zIndex:41,minWidth:240,background:"var(--card, #1b1d22)",border:"1px solid var(--border, #2c2f36)",borderRadius:10,boxShadow:"0 10px 30px rgba(0,0,0,.45)",overflow:"hidden"},children:[c.jsxs("button",{type:"button","data-id":"AddTeamMenu-custom",className:"bcard__menu-item",style:{display:"block",width:"100%",textAlign:"left",padding:"11px 14px",border:"none",background:"transparent",cursor:"pointer",color:"inherit"},onClick:()=>{ke(!1),ye(""),Rt(!0)},children:[c.jsx("div",{style:{fontSize:13,fontWeight:600},children:r("teams.addCustom","自定义团队")}),c.jsx("div",{style:{fontSize:11,opacity:.6,marginTop:2},children:r("teams.addCustomSub","手动输入地址和名称(只存本地)")})]}),S&&c.jsxs("button",{type:"button","data-id":"AddTeamMenu-private",className:"bcard__menu-item",style:{display:"block",width:"100%",textAlign:"left",padding:"11px 14px",border:"none",borderTop:"1px solid var(--border, #2c2f36)",background:"transparent",cursor:"pointer",color:"inherit"},onClick:()=>{ke(!1),Em("?tab=private")},children:[c.jsx("div",{style:{fontSize:13,fontWeight:600},children:r("teams.addPrivate","私有云团队")}),c.jsx("div",{style:{fontSize:11,opacity:.6,marginTop:2},children:r("teams.addPrivateSub","去云端团队中心添加")})]})]})]})]})]}),J&&c.jsx("div",{"data-id":"CustomTeamModal",style:{position:"fixed",inset:0,zIndex:60,display:"flex",alignItems:"center",justifyContent:"center",background:"rgba(0,0,0,.5)"},onMouseDown:D=>{!Ye&&D.target===D.currentTarget&&Rt(!1)},children:c.jsxs("div",{onClick:D=>D.stopPropagation(),style:{width:400,maxWidth:"92vw",background:"var(--card, #1b1d22)",border:"1px solid var(--border, #2c2f36)",borderRadius:14,padding:22,boxShadow:"0 20px 60px rgba(0,0,0,.5)"},children:[c.jsx("div",{style:{fontSize:16,fontWeight:700,marginBottom:4},children:r("teams.customTitle","添加自定义团队")}),c.jsx("div",{style:{fontSize:12,opacity:.6,marginBottom:16},children:r("teams.customSub","连接到一个已有的 cicy-code 地址")}),c.jsx("label",{style:{display:"block",fontSize:12,opacity:.75,marginBottom:6},children:r("teams.customNameLabel","名称")}),c.jsx("input",{"data-id":"CustomTeamModal-title",className:"login-email-input",style:{width:"100%",marginBottom:14},value:je,onChange:D=>se(D.target.value),placeholder:r("teams.customNamePlaceholder","我的团队"),spellCheck:!1,autoFocus:!0}),c.jsx("label",{style:{display:"block",fontSize:12,opacity:.75,marginBottom:6},children:r("teams.customUrlLabel","地址 URL")}),c.jsx("input",{"data-id":"CustomTeamModal-url",className:"login-email-input",style:{width:"100%",marginBottom:6},value:Me,onChange:D=>ve(D.target.value),placeholder:"https://example.com:8008",spellCheck:!1,onKeyDown:D=>{D.key==="Enter"&&qt()}}),Le&&c.jsx("div",{className:"error",style:{marginTop:10},children:Le}),c.jsxs("div",{className:"modal-actions",children:[c.jsx("button",{type:"button",className:"btn-ghost","data-id":"CustomTeamModal-cancel",disabled:Ye,onClick:()=>Rt(!1),children:r("common.cancel","取消")}),c.jsx("button",{type:"button",className:"btn-primary","data-id":"CustomTeamModal-submit",disabled:Ye,onClick:qt,children:Ye?r("teams.adding","添加中…"):r("teams.addAction","添加")})]})]})}),q&&c.jsxs("div",{className:"error",style:{marginBottom:12},children:[r("common.cloud","云端"),": ",q,c.jsx("button",{className:"btn-ghost",style:{marginLeft:8},onClick:()=>Pe(S||j,k),children:r("common.retry","重试")})]}),c.jsxs("div",{className:"app__grid",children:[xl&&[0,1,2].map(D=>c.jsx(by,{},"skc"+D)),!xl&&Se&&mt.map(D=>c.jsx(bm,{team:D,cloudCode:rt(D.cloud_team_id),onOpen:()=>g(D.id),onRename:ie,onRefresh:St},"local:"+D.id)),!xl&&Se&&c.jsx(py,{dockerTeam:I,onOpen:async()=>{var D,V,K;try{const et=await((K=(V=(D=window.cicy)==null?void 0:D.docker)==null?void 0:V.appOpen)==null?void 0:K.call(V));et!=null&&et.ok||Tt.show({id:"docker-open",status:"error",ttl:6e3,message:r("docker.openNoToken","服务还没就绪,稍等几秒再点「打开」(或用卡片菜单「重启」)。")})}catch(et){console.warn("[DockerCard] open",et)}},cloudTitle:P==null?void 0:P.title,cloudCode:P==null?void 0:P.code,onRename:I!=null&&I.cloud_team_id?(D=>it(I.cloud_team_id,D)):void 0,onRefresh:St}),!xl&&Da&&Mt.map(D=>c.jsx(bm,{team:D,cloudCode:rt(D.cloud_team_id),onOpen:()=>g(D.id),onRename:ie,onRefresh:St},"custom:"+D.id)),!xl&&Ca&&Ta.map(D=>c.jsx(yy,{team:D,onOpen:()=>{var K,et,tt;const V=D.kind==="private"?D.host_url:D.workspace_url||D.workspace_direct_url;V&&((tt=(et=(K=window.cicy)==null?void 0:K.tabs)==null?void 0:et.open)==null||tt.call(et,V,D.name||D.title||"",vt[D.id]||"",!0,D.id))},avatar:vt[D.id]||"",onAvatar:ne,onRename:it,onEditUrl:at,onDelete:ut},"cloud:"+D.id))]}),!Jt&&!q&&bt&&bt.length===0&&!(_t!=null&&_t.length)&&c.jsx("div",{className:"empty",style:{marginTop:14},children:r("teams.emptyHint","还没有团队 — 安装本地 cicy-code 起一个本地 team,或在云端创建。")})]})]}),c.jsx(iy,{}),c.jsx(uy,{}),c.jsx(hy,{})]})}function sy({onClose:s}){const[b,S]=v.useState(null),[d,j]=v.useState(""),[M,k]=v.useState(!1),[Y,T]=v.useState(""),m=typeof window<"u"&&window.cicy&&window.cicy.trustedOrigins||null,B=v.useCallback(async()=>{try{S(m&&await m.list()||[])}catch{S([])}},[m]);v.useEffect(()=>{B()},[B]);const E=async()=>{const $=d.trim();if(!(!$||M||!m)){k(!0),T("");try{const Q=await m.add($);Q&&Q.ok===!1?T(Q.error||r("trustedSites.addFailed","添加失败")):(j(""),S(Q&&Q.origins||await m.list()))}catch(Q){T(String(Q&&Q.message||Q))}finally{k(!1)}}},F=async $=>{if(!(M||!m)){k(!0),T("");try{const Q=await m.remove($);Q&&Q.ok===!1?T(Q.error||r("trustedSites.removeFailed","删除失败")):S(Q&&Q.origins||await m.list())}catch(Q){T(String(Q&&Q.message||Q))}finally{k(!1)}}},H={overlay:{position:"fixed",inset:0,zIndex:2e3,display:"flex",alignItems:"center",justifyContent:"center",background:"rgba(0,0,0,.62)",backdropFilter:"blur(3px)"},card:{width:560,maxWidth:"94vw",maxHeight:"82vh",display:"flex",flexDirection:"column",background:"#101012",border:"1px solid rgba(255,255,255,.09)",borderRadius:16,boxShadow:"0 24px 64px rgba(0,0,0,.55)",overflow:"hidden",color:"#e4e4e7"},head:{display:"flex",alignItems:"center",gap:8,padding:"14px 16px",borderBottom:"1px solid rgba(255,255,255,.06)"},title:{margin:0,fontSize:15,fontWeight:600,flex:1},x:{background:"transparent",border:"none",color:"#a1a1aa",fontSize:16,cursor:"pointer",lineHeight:1,padding:4},warn:{margin:"14px 16px 0",padding:"10px 12px",fontSize:12.5,lineHeight:1.55,color:"#fca5a5",background:"rgba(239,68,68,.08)",border:"1px solid rgba(239,68,68,.25)",borderRadius:10},addRow:{display:"flex",gap:8,padding:"12px 16px 4px"},input:{flex:1,minWidth:0,background:"#161618",border:"1px solid rgba(255,255,255,.1)",borderRadius:9,padding:"9px 11px",color:"#e4e4e7",fontSize:13,outline:"none"},addBtn:{background:"rgba(255,255,255,.1)",border:"none",borderRadius:9,padding:"0 16px",color:"#fff",fontSize:13,fontWeight:500,cursor:"pointer"},err:{margin:"6px 16px 0",fontSize:12,color:"#fca5a5"},listWrap:{margin:"10px 16px 16px",border:"1px solid rgba(255,255,255,.07)",borderRadius:10,overflow:"auto",flex:1,minHeight:80},row:{display:"flex",alignItems:"center",gap:10,padding:"9px 12px",borderTop:"1px solid rgba(255,255,255,.05)"},host:$=>({flex:1,fontFamily:"ui-monospace,SFMono-Regular,Menlo,monospace",fontSize:13,color:$?"#71717a":"#e4e4e7",wordBreak:"break-all"}),tag:{fontSize:11,color:"#71717a",background:"rgba(255,255,255,.05)",borderRadius:6,padding:"2px 7px"},rm:{background:"transparent",border:"none",color:"#a1a1aa",fontSize:12,cursor:"pointer",padding:"3px 6px",borderRadius:6},muted:{padding:"16px",textAlign:"center",color:"#71717a",fontSize:12.5}};return Sa.createPortal(c.jsx("div",{style:H.overlay,onMouseDown:$=>{$.target===$.currentTarget&&s()},"data-id":"TrustedSitesModal",children:c.jsxs("div",{style:H.card,onClick:$=>$.stopPropagation(),children:[c.jsxs("div",{style:H.head,children:[c.jsx("h2",{style:H.title,children:r("trustedSites.title","受信任站点")}),c.jsx("button",{type:"button",style:H.x,onClick:s,"aria-label":"close",children:"✕"})]}),c.jsx("div",{style:H.warn,children:r("trustedSites.warn","⚠ 列表中的站点可以在你的电脑上执行命令(exec)。只添加你完全信任的地址。")}),c.jsxs("div",{style:H.addRow,children:[c.jsx("input",{"data-id":"trusted-sites-input",style:H.input,value:d,onChange:$=>j($.target.value),onKeyDown:$=>{$.key==="Enter"&&E()},placeholder:r("trustedSites.placeholder","添加站点,如 app.cicy-ai.com 或 my-cloud.example.org")}),c.jsx("button",{type:"button","data-id":"trusted-sites-add",style:{...H.addBtn,opacity:M||!d.trim()?.5:1},onClick:E,disabled:M||!d.trim(),children:r("trustedSites.add","添加")})]}),Y&&c.jsx("div",{style:H.err,children:Y}),c.jsx("div",{style:H.listWrap,children:b===null?c.jsx("div",{style:H.muted,children:r("trustedSites.loading","加载中…")}):b.length===0?c.jsx("div",{style:H.muted,children:r("trustedSites.empty","暂无")}):b.map($=>c.jsxs("div",{style:H.row,"data-id":"trusted-sites-row",children:[c.jsx("span",{style:H.host($.builtin),children:$.host}),$.builtin?c.jsx("span",{style:H.tag,children:r("trustedSites.builtin","系统")}):c.jsx("button",{type:"button",style:H.rm,onClick:()=>F($.host),disabled:M,children:r("trustedSites.remove","删除")})]},$.host))})]})}),document.body)}function oy({onClose:s}){const[b,S]=v.useState(null),[d,j]=v.useState(""),[M,k]=v.useState(""),[Y,T]=v.useState(!1),m=typeof window<"u"&&window.cicy&&window.cicy.rpcAudit||null,B=v.useCallback(async()=>{T(!0),j("");try{const L=m&&await m.tail(400);!L||L.ok===!1?(j(L&&L.error||r("audit.loadFailed","读取失败")),S([])):(S(L.entries||[]),k(L.path||""))}catch(L){j(String(L&&L.message||L)),S([])}finally{T(!1)}},[m]);v.useEffect(()=>{B()},[B]);const[E,F]=v.useState("all"),[H,$]=v.useState(""),Q=L=>{try{return new Date(L).toLocaleString()}catch{return L||""}},yt=L=>{if(L.kind==="auth"){const ht=/deny/.test(L.decision||"");return{text:L.decision||"auth",color:ht?"#fca5a5":"#86efac",bg:ht?"rgba(239,68,68,.14)":"rgba(34,197,94,.14)"}}if(L.kind==="rpc"){const ht=L.ok!==!1&&!L.error;return{text:ht?"ok":"err",color:ht?"#86efac":"#fca5a5",bg:ht?"rgba(34,197,94,.14)":"rgba(239,68,68,.14)"}}return{text:L.kind||"log",color:"#a1a1aa",bg:"rgba(255,255,255,.06)"}},Nt=L=>L.kind==="auth"?`${L.gate||""}${L.decision?" · "+L.decision:""}`:L.kind==="rpc"?`${L.tool||""}${L.dangerous?" ⚠":""}`:L.kind||"",ce=L=>L.error||L.args||(L.kind==="rpc"?L.channel:"")||"",ot=b||[],Lt=H.trim().toLowerCase(),ct=ot.filter(L=>E!=="all"&&L.kind!==E?!1:Lt?[L.origin,L.host,L.tool,L.gate,L.decision,L.channel,L.args,L.error,L.kind].filter(Boolean).join(" ").toLowerCase().includes(Lt):!0),xt="186px 104px minmax(160px,1.1fr) minmax(150px,1.1fr) minmax(220px,1.8fr)",G={overlay:{position:"fixed",inset:0,zIndex:2e3,display:"flex",alignItems:"center",justifyContent:"center",background:"rgba(0,0,0,.66)",backdropFilter:"blur(4px)"},card:{width:"96vw",height:"92vh",maxWidth:1480,display:"flex",flexDirection:"column",background:"#0d0d0f",border:"1px solid rgba(255,255,255,.09)",borderRadius:18,boxShadow:"0 32px 80px rgba(0,0,0,.6)",overflow:"hidden",color:"#e4e4e7"},head:{display:"flex",alignItems:"center",gap:14,padding:"20px 24px",borderBottom:"1px solid rgba(255,255,255,.07)"},titleWrap:{flex:1,minWidth:0},title:{margin:0,fontSize:21,fontWeight:650,letterSpacing:.2},subtitle:{margin:"3px 0 0",fontSize:12.5,color:"#71717a",fontFamily:"ui-monospace,SFMono-Regular,Menlo,monospace",wordBreak:"break-all"},count:{fontSize:12.5,color:"#a1a1aa",whiteSpace:"nowrap"},refresh:{background:"rgba(255,255,255,.1)",border:"none",borderRadius:9,padding:"9px 16px",color:"#fff",fontSize:13,fontWeight:500,cursor:"pointer"},x:{background:"transparent",border:"none",color:"#a1a1aa",fontSize:20,cursor:"pointer",lineHeight:1,padding:6},toolbar:{display:"flex",alignItems:"center",gap:10,padding:"14px 24px",borderBottom:"1px solid rgba(255,255,255,.05)"},chips:{display:"flex",gap:6},chip:L=>({background:L?"rgba(255,255,255,.14)":"transparent",border:"1px solid rgba(255,255,255,.12)",borderRadius:999,padding:"6px 16px",color:L?"#fff":"#a1a1aa",fontSize:13,cursor:"pointer"}),search:{flex:1,minWidth:0,background:"#161618",border:"1px solid rgba(255,255,255,.1)",borderRadius:10,padding:"10px 14px",color:"#e4e4e7",fontSize:13.5,outline:"none"},err:{margin:"10px 24px 0",fontSize:12.5,color:"#fca5a5"},tableWrap:{flex:1,overflow:"auto",margin:"0"},theadRow:{position:"sticky",top:0,zIndex:1,display:"grid",gridTemplateColumns:xt,gap:16,padding:"12px 24px",background:"#141417",borderBottom:"1px solid rgba(255,255,255,.08)",fontSize:11.5,letterSpacing:.6,textTransform:"uppercase",color:"#71717a",fontWeight:600},row:{display:"grid",gridTemplateColumns:xt,gap:16,padding:"13px 24px",borderBottom:"1px solid rgba(255,255,255,.045)",alignItems:"center"},time:{fontSize:12.5,color:"#a1a1aa",fontFamily:"ui-monospace,SFMono-Regular,Menlo,monospace",whiteSpace:"nowrap"},badge:L=>({justifySelf:"start",fontSize:11.5,color:L.color,background:L.bg,borderRadius:7,padding:"3px 10px",whiteSpace:"nowrap",fontWeight:500}),cell:{fontSize:13,color:"#d4d4d8",fontFamily:"ui-monospace,SFMono-Regular,Menlo,monospace",wordBreak:"break-all"},detail:{fontSize:12.5,color:"#8b8b93",wordBreak:"break-all"},muted:{padding:"60px 24px",textAlign:"center",color:"#71717a",fontSize:14}},gt=L=>c.jsx("div",{children:L});return Sa.createPortal(c.jsx("div",{style:G.overlay,onMouseDown:L=>{L.target===L.currentTarget&&s()},"data-id":"AuditLogModal",children:c.jsxs("div",{style:G.card,onClick:L=>L.stopPropagation(),children:[c.jsxs("div",{style:G.head,children:[c.jsxs("div",{style:G.titleWrap,children:[c.jsx("h2",{style:G.title,children:r("audit.title","审计日志")}),M&&c.jsx("p",{style:G.subtitle,children:M})]}),c.jsxs("span",{style:G.count,children:[r("audit.count","共")," ",ct.length,E!=="all"||Lt?` / ${ot.length}`:""]}),c.jsx("button",{type:"button","data-id":"audit-refresh",style:{...G.refresh,opacity:Y?.5:1},onClick:B,disabled:Y,children:r("audit.refresh","刷新")}),c.jsx("button",{type:"button",style:G.x,onClick:s,"aria-label":"close",children:"✕"})]}),c.jsxs("div",{style:G.toolbar,children:[c.jsxs("div",{style:G.chips,children:[c.jsx("button",{type:"button",style:G.chip(E==="all"),onClick:()=>F("all"),children:r("audit.all","全部")}),c.jsx("button",{type:"button",style:G.chip(E==="rpc"),onClick:()=>F("rpc"),children:r("audit.rpc","RPC 调用")}),c.jsx("button",{type:"button",style:G.chip(E==="auth"),onClick:()=>F("auth"),children:r("audit.auth","授权决定")})]}),c.jsx("input",{"data-id":"audit-search",style:G.search,value:H,onChange:L=>$(L.target.value),placeholder:r("audit.search","搜索来源 / 工具 / 命令…")})]}),d&&c.jsx("div",{style:G.err,children:d}),c.jsxs("div",{style:G.tableWrap,children:[c.jsxs("div",{style:G.theadRow,children:[gt(r("audit.colTime","时间")),gt(r("audit.colType","类型")),gt(r("audit.colSource","来源")),gt(r("audit.colOp","操作")),gt(r("audit.colDetail","详情"))]}),b===null?c.jsx("div",{style:G.muted,children:r("audit.loading","加载中…")}):ct.length===0?c.jsx("div",{style:G.muted,children:ot.length===0?r("audit.empty","暂无审计记录"):r("audit.noMatch","无匹配记录")}):ct.map((L,ht)=>{const Ct=yt(L);return c.jsxs("div",{style:G.row,"data-id":"audit-row",children:[c.jsx("span",{style:G.time,children:Q(L.ts)}),c.jsx("span",{style:G.badge(Ct),children:Ct.text}),c.jsx("span",{style:G.cell,children:L.origin||L.host||"—"}),c.jsx("span",{style:G.cell,children:Nt(L)||"—"}),c.jsx("span",{style:G.detail,children:ce(L)||"—"})]},ht)})]})]})}),document.body)}function ry({me:s,welcome:b,onLogout:S,mitmTeam:d,guest:j=!1,onLogin:M}){const k=(s==null?void 0:s.display_name)||(s==null?void 0:s.username)||"…",Y=k.slice(0,1).toUpperCase(),[T,m]=v.useState(!1),[B,E]=v.useState("");v.useEffect(()=>{var bt,kt;if(!((kt=(bt=window.cicy)==null?void 0:bt.sidecar)!=null&&kt.tunnelStatus))return;let ht=!1;const Ct=()=>window.cicy.sidecar.tunnelStatus().then(Jt=>{if(ht||!(Jt!=null&&Jt.ok))return;let C=Jt.tier;if(!C){const q=Number(Jt.tunnelLimit??Jt.tunnel_limit);Number.isFinite(q)&&(C=q<0?"enterprise":q>0?"team":"personal")}C&&E(String(C))}).catch(()=>{});Ct();const jt=setInterval(Ct,6e4);return()=>{ht=!0,clearInterval(jt)}},[]);const[F,H]=v.useState(!1),[$,Q]=v.useState(!1),[yt,Nt]=v.useState(!1),[ce,ot]=v.useState(!1),[Lt,ct]=v.useState(""),xt=v.useRef(null);v.useEffect(()=>{var Ct,jt,bt;let ht=!0;return(bt=(jt=(Ct=window.cicy)==null?void 0:Ct.app)==null?void 0:jt.getVersion)==null||bt.call(jt).then(kt=>{ht&&ct(typeof kt=="string"?kt:String((kt==null?void 0:kt.desktop)||""))}).catch(()=>{}),()=>{ht=!1}},[]),v.useEffect(()=>{if(!T)return;const ht=Ct=>{xt.current&&!xt.current.contains(Ct.target)&&m(!1)};return document.addEventListener("mousedown",ht),()=>document.removeEventListener("mousedown",ht)},[T]);const G=async()=>{var Ct,jt;const ht=String((s==null?void 0:s.email)||"").trim();if(ht)try{(jt=(Ct=window.cicy)==null?void 0:Ct.clipboard)!=null&&jt.write?await window.cicy.clipboard.write(ht):await navigator.clipboard.writeText(ht),m(!1),Tt.show({message:r("userMenu.emailCopied","邮箱已复制"),status:"done",ttl:2500})}catch{Tt.show({message:r("userMenu.emailCopyFailed","邮箱复制失败"),status:"error",ttl:3500})}},gt=async()=>{var ht,Ct,jt;m(!1),ot(!0),Tt.show({id:"app-update",message:r("updateBanner.checking","正在检查更新…"),status:"running"});try{const bt=await((jt=(Ct=(ht=window.cicy)==null?void 0:ht.app)==null?void 0:Ct.checkUpdate)==null?void 0:jt.call(Ct));(bt==null?void 0:bt.status)==="available"?Tt.show({id:"app-update",message:r("updateBanner.available","发现新版本 v{{v}}",{v:bt.version}),status:"done",ttl:4e3}):(bt==null?void 0:bt.status)==="up-to-date"?Tt.show({id:"app-update",message:r("updateBanner.upToDate","已是最新版本 v{{v}}",{v:bt.version||bt.current}),status:"done",ttl:3e3}):Tt.show({id:"app-update",message:r("updateBanner.error","更新失败")+(bt!=null&&bt.error?`:${bt.error}`:""),status:"error",ttl:5e3})}catch(bt){Tt.show({id:"app-update",message:bt.message,status:"error",ttl:5e3})}finally{ot(!1)}},L=(()=>{const ht=String(B||"").toLowerCase().trim();return ht?{personal:r("plan.personal","个人版"),team:r("plan.team","团队版"),enterprise:r("plan.enterprise","企业版")}[ht]||ht:""})();return c.jsxs(c.Fragment,{children:[c.jsx("header",{className:"topbar",children:c.jsxs("div",{className:"user-chip","data-id":"UserChip",ref:xt,children:[b&&c.jsx("span",{className:"welcome",children:b}),L&&c.jsx("span",{"data-id":"UserChip-plan",className:"plan-badge",title:r("plan.hint","当前账号版本"),style:{fontSize:11,fontWeight:600,lineHeight:1.6,padding:"2px 9px",borderRadius:999,whiteSpace:"nowrap",background:"var(--accent-soft, rgba(120,140,255,.16))",color:"var(--accent, #9db0ff)"},children:L}),j?c.jsxs("button",{type:"button","data-id":"UserChip-trigger",className:`user-chip__trigger${T?" is-open":""}`,onClick:()=>m(ht=>!ht),children:[c.jsx("div",{className:"avatar",style:{background:"var(--border, #2c2f36)",color:"var(--muted, #8b8b92)"},children:"?"}),c.jsx("span",{className:"user-name",children:r("auth.localName","本机")}),c.jsx("span",{className:"user-chip__caret","aria-hidden":!0,children:"▾"})]}):s?c.jsxs("button",{type:"button","data-id":"UserChip-trigger",className:`user-chip__trigger${T?" is-open":""}`,onClick:()=>m(ht=>!ht),children:[c.jsx("div",{className:"avatar",children:Y}),c.jsx("span",{className:"user-name",children:k}),c.jsx("span",{className:"user-chip__caret","aria-hidden":!0,children:"▾"})]}):c.jsxs("div",{className:"user-chip__trigger user-chip__trigger--skel","data-id":"UserChip-skeleton","aria-hidden":!0,children:[c.jsx("div",{className:"skel skel--avatar"}),c.jsx("div",{className:"skel skel--name"})]}),T&&c.jsxs("div",{className:"user-chip__menu","data-id":"UserChip-menu",role:"menu",children:[!j&&(s==null?void 0:s.email)&&c.jsx("button",{type:"button","data-id":"UserChip-email-copy",className:"user-chip__menu-item",title:r("userMenu.copyEmail","点击复制邮箱"),onClick:G,style:{overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"},children:s.email}),c.jsx("button",{type:"button","data-id":"UserChip-trusted-sites",className:"user-chip__menu-item",onClick:()=>{m(!1),H(!0)},children:r("trustedSites.menu","受信任站点")}),c.jsx("button",{type:"button","data-id":"UserChip-audit-log",className:"user-chip__menu-item",onClick:()=>{m(!1),Q(!0)},children:r("audit.menu","审计日志")}),c.jsx("button",{type:"button","data-id":"UserChip-terms",className:"user-chip__menu-item",onClick:()=>{m(!1),Nt(!0)},children:r("firstRunTerms.menu","用户协议")}),c.jsx("button",{type:"button","data-id":"UserChip-check-update",className:"user-chip__menu-item",disabled:ce,onClick:gt,children:ce?r("updateBanner.checkingShort","检查中…"):r("updateBanner.checkBtn","检查更新")}),!1,c.jsx("div",{className:"user-chip__menu-sep","aria-hidden":!0}),!j&&c.jsx("button",{type:"button","data-id":"UserChip-logout",className:"user-chip__menu-item is-danger",onClick:()=>{m(!1),S()},children:r("userMenu.logout","退出")}),c.jsxs("div",{className:"user-chip__menu-version","data-id":"UserChip-version",children:["CiCy Desktop ",Lt?`v${Lt}`:"…"]})]})]})}),F&&c.jsx(sy,{onClose:()=>H(!1)}),$&&c.jsx(oy,{onClose:()=>Q(!1)}),yt&&c.jsx(Dm,{onClose:()=>Nt(!1)})]})}function Dm({onAgree:s,onClose:b}){var $;const[S,d]=v.useState(!1),[j,M]=v.useState(!1),k=((($=window.cicyI18n)==null?void 0:$.locale)||"en").startsWith("zh")?"zh-CN":"en",Y=(Q,yt)=>r(`firstRunTerms.${Q}`,yt),T=!!b,m=v.useMemo(()=>ty(Ip(k)),[k]),B=Q=>{const yt=Q.currentTarget;yt.scrollHeight-yt.scrollTop-yt.clientHeight<24&&d(!0)},E=v.useRef(null);v.useEffect(()=>{const Q=E.current;Q&&Q.scrollHeight<=Q.clientHeight+24&&d(!0)},[]);const F=async()=>{var Q,yt,Nt;if(!(j||!S)){M(!0);try{await((Nt=(yt=(Q=window.cicy)==null?void 0:Q.terms)==null?void 0:yt.agree)==null?void 0:Nt.call(yt,Am)),s==null||s()}catch{s==null||s()}}},H=()=>{var Q,yt,Nt;try{(Nt=(yt=(Q=window.cicy)==null?void 0:Q.terms)==null?void 0:yt.decline)==null||Nt.call(yt)}catch{}};return c.jsxs("div",{className:T?"terms-gate terms-gate--review":"shell terms-gate","data-id":"FirstRunTermsGate",style:T?{position:"fixed",inset:0,zIndex:1e3,background:"rgba(8,9,14,.72)",backdropFilter:"blur(4px)"}:void 0,onClick:T?Q=>{Q.target===Q.currentTarget&&b()}:void 0,children:[c.jsx("div",{className:"glow","aria-hidden":!0}),c.jsxs("div",{className:"terms-gate__panel",children:[c.jsx("h1",{className:"terms-gate__title","data-id":"FirstRunTermsGate-title",children:Y("title","用户协议与授权说明")}),c.jsx("p",{className:"terms-gate__subtitle",children:Y("subtitle","使用 CiCy Desktop 前,请阅读并同意以下条款")}),c.jsx("div",{className:"terms-gate__body",ref:E,onScroll:B,"data-id":"FirstRunTermsGate-body",children:c.jsx("div",{className:"terms-md","data-id":"FirstRunTermsGate-md",dangerouslySetInnerHTML:{__html:m}})}),T?c.jsx("div",{className:"terms-gate__actions",children:c.jsx("button",{"data-id":"FirstRunTermsGate-close",className:"terms-gate__btn",onClick:b,children:Y("close","关闭")})}):c.jsxs(c.Fragment,{children:[!S&&c.jsx("div",{className:"terms-gate__scrollhint","data-id":"FirstRunTermsGate-scrollhint",children:Y("scrollHint","请阅读至底部以继续")}),c.jsxs("div",{className:"terms-gate__actions",children:[c.jsx("button",{"data-id":"FirstRunTermsGate-decline",className:"terms-gate__btn terms-gate__btn--ghost",onClick:H,children:Y("decline","不同意并退出")}),c.jsx("button",{"data-id":"FirstRunTermsGate-agree",className:"terms-gate__btn",disabled:!S||j,title:S?"":Y("mustAgree","未同意则无法使用本软件。"),onClick:F,children:Y("agree","同意并继续")})]})]})]})]})}const lo=new Set;let ym=0,Qt=null;function zn(){lo.forEach(s=>s(Qt))}const Ot={open({onRetry:s,kind:b,source:S}={}){Qt={status:"running",phase:"install-docker",kind:b||"install",source:S||"op",logs:[],bars:{},minimized:!1,onRetry:s||null,lastAt:Date.now()},zn()},minimize(){Qt&&(Qt={...Qt,minimized:!0},zn())},restore(){Qt&&(Qt={...Qt,minimized:!1},zn())},push(s={}){var k;if(!Qt)return;const b=s.phase==="health"?"container":s.phase||Qt.phase,S={...Qt,phase:b,lastAt:Date.now()},d=Number.isFinite(s.progress),j=b==="install-docker"||b==="image";if(j&&(d||s.dest||s.url)){const Y=((k=Qt.bars)==null?void 0:k[b])||{},T=d?s.progress:s.status==="skip"||s.status==="done"?100:Y.progress;S.bars={...Qt.bars,[b]:{progress:T,received:s.received??Y.received,total:s.total??Y.total,url:s.url||Y.url,dest:s.dest||Y.dest}}}if(!(s.status==="running"&&d&&j)){const Y=Qt.logs[Qt.logs.length-1],T=s.status||"running",m=s.message||"";if(!(Y&&Y.phase===b&&Y.status===T&&Y.message===m)){const B={id:++ym,t:_i(),phase:b,status:T,message:m};S.logs=[...Qt.logs,B]}}Qt=S,zn()},finish({ok:s,message:b,status:S}={}){if(!Qt||Qt.status!=="running")return;const d=S||(s?"done":"error"),j=d==="error"?Qt.phase:"done",M={id:++ym,t:_i(),phase:j,status:d,message:b||(s?"完成":"失败")};Qt={...Qt,status:d,phase:j,minimized:!1,logs:[...Qt.logs,M],lastAt:Date.now()},zn()},close(){Qt=null,zn()}},to=[["install-docker","准备环境"],["image","下载运行环境"],["container","启动服务"],["done","完成"]],dy={"install-docker":"准备",image:"下载",container:"启动",health:"启动",done:"完成",open:"打开"},fy={"install-docker":"Docker Desktop",image:"基础镜像"};function gm(s){return Number.isFinite(s)?s<1024?s+" B":s<1048576?(s/1024).toFixed(0)+" KB":s<1073741824?(s/1048576).toFixed(1)+" MB":(s/1073741824).toFixed(2)+" GB":"?"}function my({phaseKey:s,bar:b}){const S=Number.isFinite(b==null?void 0:b.progress)?Math.max(0,Math.min(100,b.progress)):0,d=S>=100;return c.jsxs("div",{className:"dlbar","data-id":`DockerDrawer-dlbar-${s}`,children:[c.jsxs("div",{className:"dlbar__head",children:[c.jsx("span",{className:"dlbar__name",children:fy[s]||s}),c.jsxs("span",{className:"dlbar__pct",children:[S,"%",b!=null&&b.total?` · ${gm(b.received)} / ${gm(b.total)}`:""]})]}),c.jsx("div",{className:"dlbar__track",children:c.jsx("div",{className:`dlbar__fill${d?" is-done":""}`,style:{width:`${S}%`}})}),(b==null?void 0:b.url)&&c.jsxs("div",{className:"dlbar__url",title:b.url,children:[c.jsx("span",{className:"dlbar__urlk",children:"源"})," ",b.url]}),(b==null?void 0:b.dest)&&c.jsxs("div",{className:"dlbar__url",title:b.dest,children:[c.jsx("span",{className:"dlbar__urlk",children:"存"})," ",b.dest]})]})}function hy(){var T;const[s,b]=v.useState(Qt);v.useEffect(()=>(lo.add(b),()=>{lo.delete(b)}),[]);const S=v.useRef(null);if(v.useEffect(()=>{const m=S.current;m&&(m.scrollTop=m.scrollHeight)},[(T=s==null?void 0:s.logs)==null?void 0:T.length]),!s)return null;const d=s.status==="running",j=s.kind==="open",M=to.findIndex(([m])=>m===s.phase),k=j?[]:["install-docker","image"].filter(m=>{var B;return(B=s.bars)==null?void 0:B[m]}),Y=j?r("docker.openTitle","打开 Docker 团队"):r("docker.setupTitle","安装 Docker cicy-code");if(s.minimized){const m=k.map(E=>{var F;return(F=s.bars[E])==null?void 0:F.progress}).filter(Number.isFinite),B=m.length?Math.round(m.reduce((E,F)=>E+F,0)/m.length):null;return c.jsxs("button",{type:"button",className:`drawer-min drawer-min--${s.status}`,"data-id":"DockerDrawer-restore",onClick:()=>Ot.restore(),children:[c.jsx("span",{className:"drawer-min__spark",children:d?c.jsx(ca,{}):s.status==="done"?"✓":s.status==="reboot"?"⟳":"!"}),c.jsxs("span",{className:"drawer-min__label",children:[Y,B!=null?` · ${B}%`:""]})]})}return c.jsx("div",{className:"drawer-scrim","data-id":"DockerDrawer-scrim",onClick:()=>d?Ot.minimize():Ot.close(),children:c.jsxs("div",{className:"drawer","data-id":"DockerDrawer","data-status":s.status,onClick:m=>m.stopPropagation(),children:[c.jsxs("div",{className:"drawer__head",children:[c.jsxs("div",{className:"drawer__title",children:[c.jsx("span",{className:`drawer__spark drawer__spark--${s.status}`,children:d?c.jsx(ca,{}):s.status==="done"?"✓":s.status==="reboot"?"⟳":"!"}),c.jsxs("div",{children:[c.jsx("div",{className:"drawer__h",children:Y}),c.jsx("div",{className:"drawer__sub",children:"127.0.0.1:8008"})]})]}),c.jsx("div",{className:"drawer__headbtns",children:c.jsx("button",{type:"button",className:"drawer__x","data-id":"DockerDrawer-min",title:r("common.minimize","最小化"),onClick:()=>Ot.minimize(),"aria-label":"minimize",children:"‒"})})]}),!j&&c.jsx("div",{className:"drawer__steps","data-id":"DockerDrawer-steps",children:to.map(([m,B],E)=>{const F=s.status==="done"||M>=0&&E<M,H=E===M&&d,$=s.status==="error"&&E===M;return c.jsxs("div",{className:`drawer__step${H?" is-active":""}${F?" is-done":""}${$?" is-error":""}`,children:[c.jsx("span",{className:"drawer__step-dot",children:F?"✓":$?"!":E+1}),c.jsx("span",{className:"drawer__step-label",children:B}),E<to.length-1&&c.jsx("span",{className:"drawer__step-bar"})]},m)})}),k.length>0&&c.jsx("div",{className:"drawer__dlbars","data-id":"DockerDrawer-dlbars",children:k.map(m=>c.jsx(my,{phaseKey:m,bar:s.bars[m]},m))}),d&&s.logs.length>0&&c.jsxs("div",{className:"drawer__now","data-id":"DockerDrawer-now",children:[c.jsx(ca,{}),c.jsx("span",{children:s.logs[s.logs.length-1].message})]}),c.jsx("div",{className:"drawer__log drawer__log--scroll","data-id":"DockerDrawer-log",ref:S,children:s.logs.length===0?c.jsx("div",{className:"drawer__log-empty",children:r("docker.preparing","准备中…")}):s.logs.map(m=>c.jsxs("div",{className:"drawer__line","data-status":m.status,children:[c.jsx("span",{className:"drawer__t",children:m.t}),c.jsx("span",{className:`drawer__badge drawer__badge--${m.phase}`,children:r(`dockerBadge.${m.phase}`,dy[m.phase]||m.phase)}),c.jsx("span",{className:"drawer__linemsg",children:m.message})]},m.id))}),c.jsx("div",{className:"drawer__foot",children:d?c.jsx(c.Fragment,{children:c.jsx("span",{className:"drawer__foot-status",children:j?r("docker.opening","打开中…"):r("docker.installing2","安装进行中…")})}):s.status==="reboot"?c.jsxs(c.Fragment,{children:[c.jsx("span",{className:"drawer__foot-status is-reboot",children:r("docker.rebootAuto","需重启 Windows(90 秒后自动重启,登录后自动继续)")}),c.jsx("button",{type:"button",className:"drawer__btn is-accent","data-id":"DockerDrawer-reboot-now",onClick:()=>{var m,B,E;return(E=(B=(m=window.cicy)==null?void 0:m.docker)==null?void 0:B.rebootNow)==null?void 0:E.call(B)},children:r("docker.rebootNow","立即重启")}),c.jsx("button",{type:"button",className:"drawer__btn","data-id":"DockerDrawer-reboot-cancel",onClick:()=>{var m,B,E;(E=(B=(m=window.cicy)==null?void 0:m.docker)==null?void 0:B.rebootCancel)==null||E.call(B),Ot.close()},children:r("docker.rebootCancel","取消自动重启")})]}):s.status==="error"?c.jsxs(c.Fragment,{children:[c.jsx("span",{className:"drawer__foot-status is-error",children:j?r("docker.openFailed","打开失败"):r("docker.failed","安装失败")}),s.onRetry&&c.jsx("button",{type:"button",className:"drawer__btn is-accent","data-id":"DockerDrawer-retry",onClick:()=>s.onRetry(),children:r("common.retry","重试")}),c.jsx("button",{type:"button",className:"drawer__btn","data-id":"DockerDrawer-dismiss",onClick:()=>Ot.close(),children:r("common.close","关闭")})]}):c.jsxs(c.Fragment,{children:[c.jsx("span",{className:"drawer__foot-status is-done",children:r("docker.ready","已就绪")}),c.jsx("button",{type:"button",className:"drawer__btn is-accent","data-id":"DockerDrawer-finish",onClick:()=>Ot.close(),children:r("common.done","完成")})]})})]})})}function py({dockerTeam:s,cloudTitle:b,cloudCode:S,onOpen:d,onRename:j,onRefresh:M}){var oe;const[k,Y]=v.useState(null),[T,m]=v.useState(""),[B,E]=v.useState(!1),[F,H]=v.useState(!1),[$,Q]=v.useState(!1),[yt,Nt]=v.useState(!1),[ce,ot]=v.useState([]),[Lt,ct]=v.useState(!1),[xt,G]=v.useState(""),[gt,L]=v.useState(!1),[ht,Ct]=v.useState(""),jt=b||"Docker 团队",bt=R=>{var it;(it=R==null?void 0:R.stopPropagation)==null||it.call(R),Ct(jt),L(!0)},kt=async()=>{L(!1);const R=String(ht||"").trim();if(!(!R||R===jt||!j))try{await j(R),M==null||M()}catch{}},[Jt,C]=v.useState({top:0,left:0}),q=v.useRef(null),nt=v.useRef(null),zt=184,_t="#2496ed",h=v.useCallback(async()=>{var R,it,at;try{const ut=await((at=(it=(R=window.cicy)==null?void 0:R.docker)==null?void 0:it.appStatus)==null?void 0:at.call(it));Y(ut);const St=Date.now()-((Qt==null?void 0:Qt.lastAt)||0)>3e4;ut!=null&&ut.running&&Qt&&Qt.status==="running"&&Qt.kind!=="open"&&St&&Ot.finish({ok:!0,message:"Docker cicy-code 已就绪"})}catch(ut){console.warn("[DockerCard]",ut)}},[]);v.useEffect(()=>{h();const R=setInterval(()=>{T||h()},12e3);return()=>clearInterval(R)},[h,T]);const N=v.useCallback(async()=>{var R,it,at;E(!1),G("");try{const ut=await((at=(it=(R=window.cicy)==null?void 0:R.docker)==null?void 0:it.getPorts)==null?void 0:at.call(it));ot(((ut==null?void 0:ut.ports)||[]).map(String))}catch{ot([])}Nt(!0)},[]),Z=v.useCallback(async()=>{var ut,St,qt,ie,g,X,I,P,rt;const R=new Set,it=[];for(const mt of ce){const Mt=String(mt).trim();if(!Mt)continue;const Ee=Number(Mt);if(!Number.isInteger(Ee)||Ee<1||Ee>65535||Ee===8008||R.has(Ee)){G(r("docker.ports.invalid","有端口无效(1-65535,不能是 8008,不能重复)"));return}R.add(Ee),it.push(Ee)}G(""),ct(!0),Nt(!1),m("recreate"),Ot.open({onRetry:Z});const at=(qt=(St=(ut=window.cicy)==null?void 0:ut.docker)==null?void 0:St.onAppProgress)==null?void 0:qt.call(St,mt=>Ot.push(mt));try{const mt=await((X=(g=(ie=window.cicy)==null?void 0:ie.docker)==null?void 0:g.setPorts)==null?void 0:X.call(g,it));if(Ot.finish({ok:!!(mt!=null&&mt.ok),message:mt!=null&&mt.ok?r("docker.ports.save","保存并重建")+" ✅":(mt==null?void 0:mt.error)||r("docker.opFailed","操作失败")}),mt!=null&&mt.ok)try{const Mt=await((rt=(P=(I=window.cicy)==null?void 0:I.docker)==null?void 0:P.appRedetect)==null?void 0:rt.call(P));Mt&&Y(Mt)}catch{}}catch(mt){Ot.finish({ok:!1,message:mt.message})}finally{try{at&&at()}catch{}ct(!1),m(""),h()}},[ce,h]);v.useEffect(()=>{if(!B)return;const R=at=>{var ut,St;(ut=q.current)!=null&&ut.contains(at.target)||(St=nt.current)!=null&&St.contains(at.target)||E(!1)},it=at=>{at.key==="Escape"&&E(!1)};return document.addEventListener("mousedown",R),document.addEventListener("keydown",it),()=>{document.removeEventListener("mousedown",R),document.removeEventListener("keydown",it)}},[B]);const W=()=>{if(!B&&q.current){const R=q.current.getBoundingClientRect(),it=Math.max(8,Math.min(R.right-zt,window.innerWidth-zt-8));C({top:Math.round(R.bottom+4),left:Math.round(it)})}E(R=>!R)},ft=v.useCallback(async()=>{var it,at,ut,St,qt,ie;m("bootstrap"),Ot.open({onRetry:ft});const R=(ut=(at=(it=window.cicy)==null?void 0:it.docker)==null?void 0:at.onAppProgress)==null?void 0:ut.call(at,g=>Ot.push(g));try{const g=await((ie=(qt=(St=window.cicy)==null?void 0:St.docker)==null?void 0:qt.appBootstrap)==null?void 0:ie.call(qt));(g==null?void 0:g.reason)==="installer_launched"?Ot.finish({status:"reboot",message:r("docker.installerLaunched","已打开 Docker 安装程序——请完成安装(会装 WSL2、可能需重启),装好后点「重试」")}):(g==null?void 0:g.reason)==="wsl_reboot_required"?Ot.finish({status:"reboot",message:r("docker.rebootNeeded","WSL2 已安装,请【重启 Windows】后回来点「重试」继续")}):Ot.finish({ok:!!(g!=null&&g.ok),message:g!=null&&g.ok?r("docker.ready","Docker cicy-code 已就绪"):(g==null?void 0:g.error)||r("docker.failed","安装失败")}),g!=null&&g.ok&&(M==null||M())}catch(g){Ot.finish({ok:!1,message:g.message})}finally{try{R&&R()}catch{}m(""),h()}},[h,M]),vt=v.useCallback(async()=>{var it,at,ut,St,qt,ie;m("repair"),Ot.open({onRetry:vt});const R=(ut=(at=(it=window.cicy)==null?void 0:it.docker)==null?void 0:at.onAppProgress)==null?void 0:ut.call(at,g=>Ot.push(g));try{const g=await((ie=(qt=(St=window.cicy)==null?void 0:St.docker)==null?void 0:qt.appRepairWsl)==null?void 0:ie.call(qt));g!=null&&g.needsReboot?Ot.finish({status:"reboot",message:r("docker.wslNeedReboot","WSL 服务卡死,请【重启 Windows】;重启后打开 CiCy 会自动修复(旧数据已改名备份,不删)。")}):g!=null&&g.ok?(Ot.finish({ok:!0,message:r("docker.wslRepaired","WSL 已修复 ✅")}),M==null||M()):Ot.finish({ok:!1,message:(g==null?void 0:g.error)||r("docker.repairFailed","修复失败")})}catch(g){Ot.finish({ok:!1,message:g.message})}finally{try{R&&R()}catch{}m(""),h()}},[h,M]),Ut=v.useCallback(async()=>{var it,at,ut,St,qt,ie;E(!1),m("upgrade"),Ot.open({onRetry:Ut});const R=(ut=(at=(it=window.cicy)==null?void 0:it.docker)==null?void 0:at.onAppProgress)==null?void 0:ut.call(at,g=>Ot.push(g));try{const g=await((ie=(qt=(St=window.cicy)==null?void 0:St.docker)==null?void 0:qt.appUpgrade)==null?void 0:ie.call(qt));(g==null?void 0:g.reason)==="wsl_reboot_required"?Ot.finish({status:"reboot",message:r("docker.rebootNeeded","WSL2 已安装,请【重启 Windows】后回来点「重试」继续")}):Ot.finish({ok:!!(g!=null&&g.ok),message:g!=null&&g.ok?r("docker.upgraded","已升级到最新"):(g==null?void 0:g.error)||r("docker.upgradeFailed","升级失败")}),g!=null&&g.ok&&(M==null||M())}catch(g){Ot.finish({ok:!1,message:g.message})}finally{try{R&&R()}catch{}m(""),h()}},[h,M]),ne=v.useCallback(async()=>{var it,at,ut,St,qt,ie,g,X,I,P,rt,mt;E(!1),m("update"),Ot.open({onRetry:ne});const R=(ut=(at=(it=window.cicy)==null?void 0:it.docker)==null?void 0:at.onAppProgress)==null?void 0:ut.call(at,Mt=>Ot.push(Mt));try{const Mt=await((ie=(qt=(St=window.cicy)==null?void 0:St.docker)==null?void 0:qt.appUpdate)==null?void 0:ie.call(qt));if(Ot.finish({ok:!!(Mt!=null&&Mt.ok),message:Mt!=null&&Mt.ok?r("docker.updated","cicy-code 已更新到最新"):(Mt==null?void 0:Mt.error)||r("docker.updateFailed","更新失败")}),Mt!=null&&Mt.ok){M==null||M();try{(I=(X=(g=window.cicy)==null?void 0:g.tabs)==null?void 0:X.reloadIfOpen)==null||I.call(X,"http://127.0.0.1:8008",r("docker.teamTab","Docker 团队"))}catch{}try{const Ee=await((mt=(rt=(P=window.cicy)==null?void 0:P.docker)==null?void 0:rt.appRedetect)==null?void 0:mt.call(rt));Ee&&Y(Ee)}catch{}}}catch(Mt){Ot.finish({ok:!1,message:Mt.message})}finally{try{R&&R()}catch{}m(""),h()}},[h,M]),Zt=v.useCallback(async(R,it,at)=>{E(!1),m(R),Tt.show({id:"docker-op",message:r(`docker.${R}ing`,R==="restart"?"重启中…":R==="reload"?"刷新中…":"停止中…"),status:"running"});try{const ut=await it();ut!=null&&ut.ok?Tt.show({id:"docker-op",message:at,status:"done",ttl:2500}):Tt.show({id:"docker-op",message:(ut==null?void 0:ut.error)||r("docker.opFailed","操作失败"),status:"error",ttl:6e3})}catch(ut){Tt.show({id:"docker-op",message:ut.message,status:"error",ttl:6e3})}finally{m(""),h()}},[h]),ke=v.useCallback(async()=>{E(!1),m("authssh"),Tt.show({id:"docker-op",message:r("docker.authorizingHost","授权容器访问 Mac(配置 SSH)…"),status:"running"});try{const R=await window.cicy.docker.appAuthorizeHostSsh();R!=null&&R.ok?Tt.show({id:"docker-op",message:R.verified?r("docker.authorizedHostOk","已授权:容器内 `ssh mac` 可访问 Mac ✅"):r("docker.authorizedHostPartial","公钥已写入 Mac(未验证成功,可在容器内手动 `ssh mac` 试)"),status:R.verified?"done":"error",ttl:5e3}):Tt.show({id:"docker-op",message:(R==null?void 0:R.error)||r("docker.opFailed","操作失败"),status:"error",ttl:6e3})}catch(R){Tt.show({id:"docker-op",message:R.message,status:"error",ttl:6e3})}finally{m(""),h()}},[h]),J=((oe=window.cicy)==null?void 0:oe.platform)||(k==null?void 0:k.platform);if(J!=="win32")return null;const Rt=k?!!k.running:(s==null?void 0:s.status)==="running",je=!!(k!=null&&k.dockerRunning),se=!!(k!=null&&k.installed),Me=!!(k!=null&&k.unknown)&&!Rt&&!je&&!se,ve=!!(k!=null&&k.wslUnmanaged),Ye=!!(k!=null&&k.wslWedged),sa=Rt&&!ve,Le=sa?"ok":Ye||ve||je||se||Me?"warn":"off",ye=!!T;Ye?r("docker.wslWedged","WSL 卡死 · 点「修复 WSL」"):ve?r("docker.wslBrokenRepair","WSL 管理异常 · 点「修复 WSL」重装"):Rt?r("docker.running","运行中"):je?r("docker.notRunning","未启动 · 点「启动」"):se?r("docker.engineDown","Docker 未运行 · 点启动"):Me?r("docker.wslUnresponsive","WSL 未响应 · 点「重试检测」"):r("docker.notInstalled","Docker Desktop 未安装");const Ge=T==="open"?r("docker.opening","打开中…"):T==="probe"?r("docker.probing","检测中…"):ye?r("docker.working","处理中…"):sa?r("localTeams.open","打开"):Ye||ve?r("docker.repairWsl","修复 WSL"):je?r("docker.start","启动"):se?r("docker.startDocker","启动 Docker"):Me?r("docker.retryProbe","重试检测"):r("docker.install","下载安装"),Qe=async()=>{var R,it,at,ut,St,qt,ie,g,X,I,P,rt;if(!ye){if(Ye){vt();return}if(ve){ft();return}if(sa){try{const Mt=await((at=(it=(R=window.cicy)==null?void 0:R.tabs)==null?void 0:it.activateIfOpen)==null?void 0:at.call(it,"http://127.0.0.1:8008"));if(Mt!=null&&Mt.active)return}catch{}m("open");let mt=null;try{mt=await((qt=(St=(ut=window.cicy)==null?void 0:ut.docker)==null?void 0:St.appOpen)==null?void 0:qt.call(St))}catch(Mt){mt={ok:!1,hint:(Mt==null?void 0:Mt.message)||r("docker.openFailed","打开失败"),log:[]}}m(""),mt&&mt.ok===!1&&(Ot.open({onRetry:Qe,kind:"open"}),(mt.log||[]).forEach(Mt=>Ot.push(Mt)),Ot.finish({ok:!1,message:mt.hint||mt.error||r("docker.openFailed","打开失败")}));return}if(Me){m("probe");try{const mt=await(((X=(g=(ie=window.cicy)==null?void 0:ie.docker)==null?void 0:g.appRedetect)==null?void 0:X.call(g))??((rt=(P=(I=window.cicy)==null?void 0:I.docker)==null?void 0:P.appStatus)==null?void 0:rt.call(P)));mt&&Y(mt),mt!=null&&mt.unknown&&Tt.show({id:"docker-probe",status:"error",message:r("docker.wslStillStuck","WSL 仍无响应 —— 多半要重启 Windows 后再试"),ttl:6e3})}catch{Tt.show({id:"docker-probe",status:"error",message:r("docker.probeFailed","检测失败,请重试"),ttl:5e3})}finally{m("")}return}ft()}},Pe=Rt;return c.jsxs("div",{"data-id":"DockerCard",className:`bcard bcard--docker${Rt?" bcard--online":""}`,children:[c.jsx("div",{className:"bcard__accent",style:{background:_t}}),c.jsxs("div",{className:"bcard__top",children:[c.jsxs("div",{className:"bcard__pill",style:{color:_t},children:[c.jsx("span",{className:"bcard__dot","data-tone":Le}),c.jsx("svg",{style:{width:18,height:18},viewBox:"0 0 24 24",fill:"currentColor","aria-hidden":!0,children:c.jsx("path",{d:"M21.81 10.25c-.06-.05-.67-.51-1.95-.51-.34 0-.68.03-1.01.09-.25-1.69-1.64-2.51-1.7-2.55l-.34-.2-.22.32a4.5 4.5 0 0 0-.59 1.4c-.23.94-.09 1.83.39 2.59-.58.32-1.51.4-1.7.41H2.62a.61.61 0 0 0-.61.61 9.32 9.32 0 0 0 .57 3.35 4.9 4.9 0 0 0 1.95 2.53c.92.52 2.42.82 4.12.82.77 0 1.54-.07 2.3-.21a9.6 9.6 0 0 0 3-1.09 8.3 8.3 0 0 0 2.05-1.68c.98-1.11 1.56-2.35 1.99-3.45h.17c1.36 0 2.2-.55 2.66-1l.13-.16zM4.7 11.33h1.78a.16.16 0 0 0 .16-.16V9.58a.16.16 0 0 0-.16-.16H4.7a.16.16 0 0 0-.16.16v1.59c0 .09.07.16.16.16m2.46 0h1.78a.16.16 0 0 0 .16-.16V9.58a.16.16 0 0 0-.16-.16H7.16a.16.16 0 0 0-.16.16v1.59c0 .09.07.16.16.16m2.5 0h1.78a.16.16 0 0 0 .16-.16V9.58a.16.16 0 0 0-.16-.16H9.66a.16.16 0 0 0-.16.16v1.59c0 .09.07.16.16.16m2.47 0h1.78a.16.16 0 0 0 .16-.16V9.58a.16.16 0 0 0-.16-.16h-1.78a.16.16 0 0 0-.16.16v1.59c0 .09.07.16.16.16M7.16 9.06h1.78a.16.16 0 0 0 .16-.16V7.31a.16.16 0 0 0-.16-.16H7.16a.16.16 0 0 0-.16.16v1.59c0 .09.07.16.16.16m2.5 0h1.78a.16.16 0 0 0 .16-.16V7.31a.16.16 0 0 0-.16-.16H9.66a.16.16 0 0 0-.16.16v1.59c0 .09.07.16.16.16m2.47 0h1.78a.16.16 0 0 0 .16-.16V7.31a.16.16 0 0 0-.16-.16h-1.78a.16.16 0 0 0-.16.16v1.59c0 .09.07.16.16.16"})})]}),Pe&&c.jsxs("div",{className:"bcard__menuwrap",onClick:R=>R.stopPropagation(),children:[c.jsx("button",{type:"button",ref:q,"data-id":"DockerCard-menu-btn",className:"bcard__kebab",title:r("docker.manage","管理 Docker cicy-code"),disabled:ye,onClick:W,children:ye?c.jsx(ca,{}):c.jsx(so,{})}),B&&Sa.createPortal(c.jsxs("div",{className:"bcard__menu bcard__menu--portal","data-id":"DockerCard-menu",role:"menu",ref:nt,style:{position:"fixed",top:Jt.top,left:Jt.left,width:zt},onClick:R=>R.stopPropagation(),children:[c.jsx("button",{type:"button","data-id":"DockerCard-update",className:"bcard__menu-item is-accent",onClick:ne,children:r("docker.update","更新 cicy-code")}),c.jsx("button",{type:"button","data-id":"DockerCard-restart",className:"bcard__menu-item",onClick:()=>Zt("restart",()=>window.cicy.docker.appRestart(),r("docker.restarted","已重启 cicy-code")),children:r("docker.restart","重启 cicy-code")}),c.jsx("button",{type:"button","data-id":"DockerCard-stop",className:"bcard__menu-item is-danger",onClick:()=>Zt("stop",()=>window.cicy.docker.appStop(),r("docker.stopped","已停止 cicy-code")),children:r("docker.stop","停止 cicy-code")}),c.jsx("button",{type:"button","data-id":"DockerCard-reload",className:"bcard__menu-item",onClick:R=>{var it,at,ut;R.stopPropagation(),E(!1),(ut=(at=(it=window.cicy)==null?void 0:it.tabs)==null?void 0:at.reloadIfOpen)==null||ut.call(at,"http://127.0.0.1:8008","Docker 团队")},children:r("docker.reloadWindow","刷新窗口")}),c.jsx("button",{type:"button","data-id":"DockerCard-open-dir",className:"bcard__menu-item",onClick:R=>{var it,at,ut;R.stopPropagation(),E(!1),(ut=(at=(it=window.cicy)==null?void 0:it.docker)==null?void 0:at.openDir)==null||ut.call(at)},children:r("docker.openWslDir","打开 WSL 目录")}),c.jsx("button",{type:"button","data-id":"DockerCard-open-projects",className:"bcard__menu-item",onClick:R=>{var it,at,ut;R.stopPropagation(),E(!1),(ut=(at=(it=window.cicy)==null?void 0:it.docker)==null?void 0:at.openDir)==null||ut.call(at,"projects")},children:r("docker.openProjectsDir","打开项目目录")}),c.jsx("button",{type:"button","data-id":"DockerCard-dood",className:"bcard__menu-item",title:r("dood.hint","把宿主 Docker + docker 客户端挂进容器,容器内 agent 能直接跑 docker(切换会重建容器,秒生效、无需下载)"),onClick:R=>{R.stopPropagation(),E(!1),H(!0)},children:r("dood.menu","容器内使用 Docker")}),c.jsx("div",{className:"bcard__menu-sep","data-id":"DockerCard-menu-sep",role:"separator","aria-hidden":!0}),J==="darwin"&&c.jsx("button",{type:"button","data-id":"DockerCard-authorize-host-ssh",className:"bcard__menu-item",title:r("docker.authorizeHostHint","把容器公钥加到 Mac 的 authorized_keys,容器内 `ssh mac` 即可访问本机"),onClick:ke,children:r("docker.authorizeHost","授权容器访问 Mac")}),c.jsx("button",{type:"button","data-id":"DockerCard-docker-restart",className:"bcard__menu-item",onClick:()=>Zt("restart",()=>window.cicy.docker.appDockerRestart(),r("docker.dockerRestarted","已重启 Docker 容器")),children:r("docker.dockerRestart","重启 Docker")}),c.jsx("button",{type:"button","data-id":"DockerCard-ports",className:"bcard__menu-item",onClick:R=>{R.stopPropagation(),N()},children:r("docker.ports.menu","端口设置")}),c.jsx("button",{type:"button","data-id":"DockerCard-recreate",className:"bcard__menu-item is-danger",onClick:R=>{R.stopPropagation(),E(!1),Q(!0)},children:r("docker.recreate","重建 Docker")})]}),document.body)]})]}),c.jsxs("div",{className:"bcard__body",children:[c.jsxs("div",{style:{height:28,display:"flex",alignItems:"center",gap:8},children:[c.jsx(uo,{size:24,avatar:s==null?void 0:s.avatar,name:jt,teamId:s==null?void 0:s.id,onChanged:M}),gt?c.jsx("input",{"data-id":"DockerCard-rename-input",autoFocus:!0,value:ht,onChange:R=>Ct(R.target.value),onFocus:R=>R.target.select(),onBlur:kt,onClick:R=>R.stopPropagation(),onKeyDown:R=>{R.nativeEvent.isComposing||R.keyCode===229||(R.key==="Enter"?kt():R.key==="Escape"&&L(!1))},style:{flex:1,width:"100%",font:"inherit",fontWeight:600,padding:"2px 6px",border:"1px solid #3b82f6",borderRadius:6,background:"#0d1117",color:"#e6edf3",boxSizing:"border-box"}}):c.jsxs("h3",{className:"bcard__name",title:j?r("localTeams.renameHint","点名字或 ✎ 改名"):jt,style:{display:"flex",alignItems:"center",gap:6,flex:1,minWidth:0,margin:0},onDoubleClick:j?bt:void 0,children:[c.jsx("span",{onClick:j?bt:void 0,style:{overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap",cursor:j?"text":"default"},children:jt}),j&&c.jsx("button",{type:"button","data-id":"DockerCard-rename-btn",title:r("localTeams.rename","重命名"),onClick:bt,style:{flex:"none",cursor:"pointer",border:"none",background:"transparent",color:"#8b949e",fontSize:13,padding:0,lineHeight:1},children:"✎"})]})]}),c.jsxs("div",{className:"bcard__meta",children:[c.jsx("span",{className:"bcard__chip",children:"Docker"}),(k==null?void 0:k.version)&&c.jsxs("span",{className:"bcard__ver","data-id":"DockerCard-ver",style:{marginLeft:8,fontSize:11,opacity:.6},children:["v",k.version]})]})]}),c.jsxs("button",{type:"button",className:"bcard__cta","data-id":"DockerCard-cta",disabled:ye,onClick:Qe,style:Rt?void 0:{background:_t,color:"white"},children:[ye?c.jsx(ca,{}):c.jsx(co,{}),c.jsx("span",{children:Ge})]}),c.jsx(xy,{open:F,onClose:()=>H(!1),toastId:"docker-op"}),$&&Sa.createPortal(c.jsx("div",{"data-id":"DockerCard-recreate-modal",style:{position:"fixed",inset:0,zIndex:9999,background:"rgba(0,0,0,0.55)",display:"flex",alignItems:"center",justifyContent:"center"},onMouseDown:R=>{R.target===R.currentTarget&&Q(!1)},children:c.jsxs("div",{onClick:R=>R.stopPropagation(),style:{width:360,maxWidth:"90vw",background:"#161b22",border:"1px solid #30363d",borderRadius:12,padding:"20px 22px",boxShadow:"0 12px 40px rgba(0,0,0,0.5)"},children:[c.jsx("h3",{style:{margin:"0 0 8px",fontSize:16,color:"#e6edf3"},children:r("docker.recreate","重建 Docker")}),c.jsx("p",{style:{margin:"0 0 18px",fontSize:13,lineHeight:1.6,color:"#9aa4b2"},children:r("docker.recreateConfirm","会删除当前容器并重新创建(volume 数据保留),用于切换为独立 team 的网关 key。确定重建?")}),c.jsxs("div",{style:{display:"flex",justifyContent:"flex-end",gap:10},children:[c.jsx("button",{type:"button","data-id":"DockerCard-recreate-cancel",onClick:()=>Q(!1),style:{padding:"7px 16px",borderRadius:8,border:"1px solid #30363d",background:"transparent",color:"#c9d1d9",cursor:"pointer",fontSize:13},children:r("common.cancel","取消")}),c.jsx("button",{type:"button","data-id":"DockerCard-recreate-confirm",onClick:()=>{Q(!1),Zt("restart",()=>window.cicy.docker.appRecreate(),r("docker.recreated","已重建 Docker 容器"))},style:{padding:"7px 16px",borderRadius:8,border:"none",background:"#da3633",color:"white",cursor:"pointer",fontSize:13,fontWeight:600},children:r("docker.recreateOk","确定重建")})]})]})}),document.body),yt&&Sa.createPortal(c.jsx("div",{"data-id":"DockerCard-ports-modal",style:{position:"fixed",inset:0,zIndex:9999,background:"rgba(0,0,0,0.55)",display:"flex",alignItems:"center",justifyContent:"center"},onMouseDown:R=>{R.target===R.currentTarget&&Nt(!1)},children:c.jsxs("div",{onClick:R=>R.stopPropagation(),style:{width:420,maxWidth:"92vw",background:"#161b22",border:"1px solid #30363d",borderRadius:12,padding:"20px 22px",boxShadow:"0 12px 40px rgba(0,0,0,0.5)"},children:[c.jsx("h3",{style:{margin:"0 0 6px",fontSize:16,color:"#e6edf3"},children:r("docker.ports.title","端口设置")}),c.jsx("p",{style:{margin:"0 0 14px",fontSize:12.5,lineHeight:1.6,color:"#9aa4b2"},children:r("docker.ports.sub","除 :8008 外,额外发布、可从 Windows 直达容器内服务的端口")}),c.jsxs("div",{style:{display:"flex",alignItems:"center",gap:8,padding:"8px 10px",marginBottom:10,borderRadius:8,background:"#0d1117",border:"1px solid #21262d",color:"#7d8590",fontSize:13},children:["🔒 ",r("docker.ports.mainFixed",":8008 · cicy-code(固定)")]}),c.jsxs("div",{style:{display:"flex",flexDirection:"column",gap:8,maxHeight:220,overflowY:"auto"},children:[ce.length===0&&c.jsx("div",{style:{fontSize:12.5,color:"#6e7681",padding:"4px 2px"},children:r("docker.ports.none","暂无额外端口")}),ce.map((R,it)=>c.jsxs("div",{style:{display:"flex",alignItems:"center",gap:8},children:[c.jsx("input",{"data-id":`DockerCard-port-input-${it}`,type:"text",inputMode:"numeric",value:R,placeholder:r("docker.ports.ph","端口号 1-65535"),onChange:at=>{const ut=at.target.value.replace(/[^0-9]/g,"");ot(St=>St.map((qt,ie)=>ie===it?ut:qt)),G("")},style:{flex:1,padding:"7px 10px",borderRadius:8,border:"1px solid #30363d",background:"#0d1117",color:"#e6edf3",fontSize:13,fontFamily:"var(--mono)"}}),c.jsx("button",{type:"button","data-id":`DockerCard-port-remove-${it}`,title:r("docker.ports.remove","移除"),onClick:()=>{ot(at=>at.filter((ut,St)=>St!==it)),G("")},style:{padding:"6px 10px",borderRadius:8,border:"1px solid #30363d",background:"transparent",color:"#da3633",cursor:"pointer",fontSize:14},children:"✕"})]},it))]}),c.jsx("button",{type:"button","data-id":"DockerCard-port-add",onClick:()=>ot(R=>[...R,""]),style:{marginTop:10,padding:"7px 12px",borderRadius:8,border:"1px dashed #30363d",background:"transparent",color:"#58a6ff",cursor:"pointer",fontSize:13,width:"100%"},children:r("docker.ports.add","+ 添加端口")}),xt&&c.jsx("div",{style:{marginTop:10,fontSize:12.5,color:"#f85149"},children:xt}),c.jsx("p",{style:{margin:"12px 0 16px",fontSize:11.5,lineHeight:1.5,color:"#6e7681"},children:r("docker.ports.hint","保存会重建容器(volume 数据保留),会有短暂中断")}),c.jsxs("div",{style:{display:"flex",justifyContent:"flex-end",gap:10},children:[c.jsx("button",{type:"button","data-id":"DockerCard-ports-cancel",disabled:Lt,onClick:()=>Nt(!1),style:{padding:"7px 16px",borderRadius:8,border:"1px solid #30363d",background:"transparent",color:"#c9d1d9",cursor:"pointer",fontSize:13},children:r("docker.ports.cancel","取消")}),c.jsx("button",{type:"button","data-id":"DockerCard-ports-save",disabled:Lt,onClick:Z,style:{padding:"7px 16px",borderRadius:8,border:"none",background:"#238636",color:"white",cursor:"pointer",fontSize:13,fontWeight:600},children:Lt?r("docker.ports.saving","保存中…"):r("docker.ports.save","保存并重建")})]})]})}),document.body)]})}function bm({team:s,cloudCode:b,onOpen:S,onRename:d,onRefresh:j}){var ut,St,qt,ie;const k=(xm[s.status]||xm.error).tone,[Y,T]=v.useState(!1),[m,B]=v.useState(s.name||""),[E,F]=v.useState(null),[H,$]=v.useState(""),Q=E??s.name;v.useEffect(()=>{E!=null&&s.name===E&&F(null)},[s.name,E]);const yt=g=>{var X;(X=g==null?void 0:g.stopPropagation)==null||X.call(g),B(Q||""),T(!0)},Nt=async()=>{T(!1);const g=String(m||"").trim();if(!d||!g||g===Q)return;F(g),$("saving");let X;try{X=await d(s.id,g)}catch(I){X={ok:!1,error:I==null?void 0:I.message}}F(null),X&&X.ok?($("saved"),setTimeout(()=>$(I=>I==="saved"?"":I),1500)):($(""),Tt.show({message:r("localTeams.renameFailed","改名没保存,已恢复"),status:"error",ttl:4e3}))},ot=!!((St=(ut=window.cicy)==null?void 0:ut.sidecar)!=null&&St.restart)&&no(s.base_url),Lt=s.status==="running",[ct,xt]=v.useState(""),[G,gt]=v.useState(!1),[L,ht]=v.useState(!1);v.useEffect(()=>{var g,X;!ot||!((X=(g=window.cicy)==null?void 0:g.sidecar)!=null&&X.getPublic)||window.cicy.sidecar.getPublic().then(I=>ht(!!(I!=null&&I.public))).catch(()=>{})},[ot]);const[Ct,jt]=v.useState({running:void 0,latest:null,installed:null}),bt=Ct.latest,kt=Ct.running,[Jt,C]=v.useState(!1),q=v.useRef(null),nt=v.useRef(null),zt=v.useRef(null),[_t,h]=v.useState({top:0,left:0}),N=184,Z=()=>{if(!G&&nt.current){const g=nt.current.getBoundingClientRect(),X=Math.max(8,Math.min(g.right-N,window.innerWidth-N-8));h({top:Math.round(g.bottom+4),left:Math.round(X)})}gt(g=>!g)},W=v.useCallback(async(g=!1)=>{var X,I;if(!(!ot||!((I=(X=window.cicy)==null?void 0:X.sidecar)!=null&&I.versions))){g&&C(!0);try{const P=await window.cicy.sidecar.versions();jt({running:(P==null?void 0:P.running)??null,latest:(P==null?void 0:P.latest)??null,installed:(P==null?void 0:P.installed)??null}),g&&(P!=null&&P.running&&(P!=null&&P.latest)&&Sm(P.latest,P.running)>0?Tt.show({message:`${r("sidecar.found","发现新版本")} v${P.latest}`,status:"done",ttl:2500}):P!=null&&P.running?Tt.show({message:`${r("sidecar.upToDate","已是最新")} v${P.running}`,status:"done",ttl:2500}):Tt.show({message:r("sidecar.notRunning","cicy-code 未运行"),status:"error",ttl:4e3}))}catch{g&&Tt.show({message:r("sidecar.checkFailed","检查更新失败"),status:"error",ttl:5e3})}finally{g&&C(!1)}}},[ot]);v.useEffect(()=>{W(!1)},[W]),v.useEffect(()=>{Lt&&W(!1)},[Lt,W]);const ft=!!(ot&&bt&&kt&&Sm(bt,kt)>0),vt=!ot&&!!((ie=(qt=window.cicy)==null?void 0:qt.localTeams)!=null&&ie.remove),Ut=ot||vt,[ne,Zt]=v.useState(!1),[ke,J]=v.useState(!1),[Rt,je]=v.useState(""),[se,Me]=v.useState(""),[ve,Ye]=v.useState(!1),[sa,Le]=v.useState("");v.useEffect(()=>{if(!G)return;const g=X=>{var I,P;(I=nt.current)!=null&&I.contains(X.target)||(P=zt.current)!=null&&P.contains(X.target)||gt(!1)};return document.addEventListener("mousedown",g),()=>document.removeEventListener("mousedown",g)},[G]);const ye=async()=>{var X,I,P;if(ve)return;const g=ey({title:Rt,url:se});if(!g.ok){Le(r("teams.titleRequired","请输入自定义标题"));return}if(!g.patch.base_url){Le(r("teams.urlRequired","请输入地址 URL"));return}try{new URL(g.patch.base_url)}catch{Le(r("teams.badUrl","URL 无效(需含 http(s)://)"));return}if(g.patch.name===(s.name||"")&&g.patch.base_url===(s.base_url||"")){J(!1);return}Le(""),Ye(!0);try{const rt=await((P=(I=(X=window.cicy)==null?void 0:X.localTeams)==null?void 0:I.update)==null?void 0:P.call(I,s.id,g.patch));rt!=null&&rt.ok?(J(!1),j==null||j()):Le(wi((rt==null?void 0:rt.error)||"update failed"))}catch(rt){Le(wi((rt==null?void 0:rt.message)||String(rt)))}Ye(!1)},Ge=async()=>{var X,I,P;if(ct)return;Zt(!1),xt("remove");const g="op-"+Date.now();Tt.show({id:g,message:r("localTeams.removing","删除中…"),status:"running"});try{const rt=await((P=(I=(X=window.cicy)==null?void 0:X.localTeams)==null?void 0:I.remove)==null?void 0:P.call(I,s.id));rt!=null&&rt.ok?Tt.show({id:g,message:r("localTeams.removed","已删除"),status:"done",ttl:3e3}):Tt.show({id:g,message:r("localTeams.removeFailed","删除失败")+(rt!=null&&rt.error?": "+rt.error:""),status:"error",ttl:7e3})}catch(rt){Tt.show({id:g,message:r("localTeams.removeFailed","删除失败")+": "+((rt==null?void 0:rt.message)||rt),status:"error",ttl:7e3})}xt(""),j==null||j()},Qe=`sidecar-op:${s.id}`,Pe=async(g,X,I)=>{var mt,Mt,Ee,oa,Ta;if(gt(!1),ct)return;xt(g);const P=g==="update";let rt=null;P?(me.open({teamId:s.id,fromVer:kt,toVer:bt,onRetry:()=>Pe("update",X,I)}),(Mt=(mt=window.cicy)==null?void 0:mt.sidecar)!=null&&Mt.onOpProgress&&(rt=window.cicy.sidecar.onOpProgress(It=>{(It==null?void 0:It.op)==="update"&&me.push(It)}))):Tt.show({id:Qe,message:oe[g]||`${g}…`,status:"running",progress:void 0});try{const It=await X(),Se=!!(It!=null&&It.ok),Da=It!=null&&It.warning?`${I}(${It.warning})`:I,Ca=r("sidecar.failed","操作失败")+(It!=null&&It.error?`: ${It.error}`:"");if(P){if(me.finish({ok:Se,message:Se?Da:Ca}),Se)try{await((Ta=(oa=(Ee=window.cicy)==null?void 0:Ee.localTeams)==null?void 0:oa.reload)==null?void 0:Ta.call(oa,s.id,{ignoreCache:!0}))}catch{}}else Tt.show({id:Qe,message:Se?Da:Ca,progress:void 0,status:Se?"done":"error",ttl:Se?4e3:8e3})}catch(It){const Se=r("sidecar.failed","操作失败")+`: ${(It==null?void 0:It.message)||It}`;P?me.finish({ok:!1,message:Se}):Tt.show({id:Qe,message:Se,progress:void 0,status:"error",ttl:8e3})}finally{try{rt&&rt()}catch{}xt(""),j==null||j(),(g==="update"||g==="restart"||g==="start")&&W(!1)}},oe={start:r("busy.start","启动中…"),restart:r("busy.restart","重启中…"),update:r("busy.update","更新中…"),stop:r("busy.stop","停止中…")},R=async()=>{var I,P,rt;xt("start"),me.open({teamId:s.id,title:r("sidecar.startTitle","启动 cicy-code"),onRetry:R}),me.push({phase:"download",status:"running",message:r("sidecar.starting","启动 cicy-code(首次需安装 Node + 依赖,日志见下)…")});const g=(rt=(P=(I=window.cicy)==null?void 0:I.sidecar)==null?void 0:P.onOpProgress)==null?void 0:rt.call(P,mt=>me.push(mt));let X;try{X=await window.cicy.sidecar.start()}catch(mt){X={ok:!1,error:(mt==null?void 0:mt.message)||String(mt)}}try{g==null||g()}catch{}return xt(""),j==null||j(),!(X!=null&&X.ok)||X!=null&&X.warning?(me.finish({ok:!1,message:r("sidecar.startFailed","启动失败")+(X!=null&&X.error?`: ${X.error}`:X!=null&&X.warning?`: ${X.warning}`:"")}),!1):(me.finish({ok:!0,message:r("sidecar.startedOk","cicy-code 已就绪")}),!0)},it=async()=>{var g,X;ct||!Lt&&ot&&((X=(g=window.cicy)==null?void 0:g.sidecar)!=null&&X.start)&&!await R()||S()},at=Lt?r("localTeams.open","打开"):ot?r("localTeams.startOpen","启动并打开"):r("localTeams.open","打开");return c.jsxs(c.Fragment,{children:[c.jsxs("div",{"data-id":"LocalTeamCard",className:`bcard ${ot?"bcard--local":"bcard--custom"}${k==="ok"?" bcard--online":""}`,children:[c.jsx("div",{className:"bcard__accent"}),c.jsxs("div",{className:"bcard__top",children:[c.jsxs("div",{className:"bcard__pill",children:[c.jsx("span",{className:"bcard__dot","data-tone":k}),c.jsx(wy,{})]}),Ut&&c.jsxs("div",{className:"bcard__menuwrap",ref:q,onClick:g=>g.stopPropagation(),children:[c.jsx("button",{type:"button",ref:nt,"data-id":"LocalTeamCard-menu-btn",className:`bcard__kebab${ft?" has-dot":""}`,title:ot?r("localTeams.manage","管理本地 cicy-code"):r("localTeams.more","更多"),disabled:!!ct,onClick:Z,children:ct?c.jsx(ca,{}):c.jsx(so,{})}),G&&Sa.createPortal(c.jsxs("div",{className:"bcard__menu bcard__menu--portal","data-id":"LocalTeamCard-menu",role:"menu",ref:zt,style:{position:"fixed",top:_t.top,left:_t.left,width:N},onClick:g=>g.stopPropagation(),children:[ot&&c.jsx("button",{type:"button","data-id":"LocalTeamCard-check-update",className:"bcard__menu-item",disabled:Jt,onClick:g=>{g.stopPropagation(),W(!0)},children:Jt?r("sidecar.checking2","检查中…"):r("sidecar.checkUpdate","检查更新")}),ft&&c.jsxs("button",{type:"button","data-id":"LocalTeamCard-update",className:"bcard__menu-item is-accent",onClick:()=>Pe("update",()=>window.cicy.sidecar.update(),r("sidecar.updated","已更新到最新")),children:[r("sidecar.updateTo","更新到")," v",bt]}),s.base_url&&c.jsx("button",{type:"button","data-id":"LocalTeamCard-reload",className:"bcard__menu-item",onClick:g=>{var X,I,P;g.stopPropagation(),gt(!1),(P=(I=(X=window.cicy)==null?void 0:X.tabs)==null?void 0:I.reloadIfOpen)==null||P.call(I,s.base_url,s.name)},children:r("localTeams.reloadWindow","刷新窗口")}),ot&&!Lt&&c.jsx("button",{type:"button","data-id":"LocalTeamCard-start",className:"bcard__menu-item is-accent",onClick:()=>Pe("start",()=>window.cicy.sidecar.start(),r("sidecar.started","已启动")),children:r("sidecar.start","启动")}),ot&&Lt&&c.jsxs(c.Fragment,{children:[c.jsx("button",{type:"button","data-id":"LocalTeamCard-restart",className:"bcard__menu-item",onClick:()=>Pe("restart",()=>window.cicy.sidecar.restart(),r("sidecar.restarted","已重启")),children:r("sidecar.restart","重启")}),c.jsx("button",{type:"button","data-id":"LocalTeamCard-stop",className:"bcard__menu-item is-danger",onClick:()=>Pe("stop",()=>window.cicy.sidecar.stop(),r("sidecar.stoppedDone","已停止")),children:r("sidecar.stop","停止")}),c.jsxs("button",{type:"button","data-id":"LocalTeamCard-lan",className:"bcard__menu-item",title:r("sidecar.lanHint","开启后同局域网设备可用本机 IP 访问(api_token 仍校验);切换会自动重启 cicy-code"),disabled:ct==="lan",onClick:async()=>{if(ct)return;const g=!L;gt(!1),xt("lan"),ht(g),Tt.show({id:Qe,message:g?r("sidecar.lanEnabling","开启局域网访问,重启中…"):r("sidecar.lanDisabling","关闭局域网访问,重启中…"),status:"running",progress:void 0});try{const X=await window.cicy.sidecar.setPublic(g);X!=null&&X.ok?Tt.show({id:Qe,message:g?r("sidecar.lanOn","已开启局域网访问"):r("sidecar.lanOff","已关闭局域网访问"),status:"done",ttl:3e3}):Tt.show({id:Qe,message:r("sidecar.lanFailed","设置失败")+(X!=null&&X.error?`: ${X.error}`:""),status:"error",ttl:7e3})}catch(X){Tt.show({id:Qe,message:r("sidecar.lanFailed","设置失败")+`: ${(X==null?void 0:X.message)||X}`,status:"error",ttl:7e3})}try{const X=await window.cicy.sidecar.getPublic();ht(!!(X!=null&&X.public))}catch{}xt(""),j==null||j()},children:[r("sidecar.lanAccess","局域网访问")," · ",L?r("common.on","开"):r("common.off","关")]})]}),vt&&c.jsxs(c.Fragment,{children:[c.jsx("button",{type:"button","data-id":"LocalTeamCard-edit-url",className:"bcard__menu-item",onClick:g=>{g.stopPropagation(),gt(!1),J(!0),je(s.name||""),Me(s.base_url||""),Le("")},children:r("teamCard.editUrl","更改访问地址")}),c.jsx("button",{type:"button","data-id":"LocalTeamCard-remove",className:"bcard__menu-item is-danger",onClick:()=>{gt(!1),Zt(!0)},children:r("localTeams.remove","删除")})]}),(kt||s.version)&&c.jsxs("div",{"data-id":"LocalTeamCard-version",className:"bcard__menu-item",style:{cursor:"default",color:"#8b949e",fontSize:12},children:[r("localTeams.version","版本")," v",kt||s.version]})]}),document.body)]})]}),c.jsxs("div",{className:"bcard__body",children:[c.jsxs("div",{style:{height:28,display:"flex",alignItems:"center",gap:8},children:[c.jsx(uo,{size:24,avatar:s==null?void 0:s.avatar,name:s==null?void 0:s.name,teamId:s==null?void 0:s.id,onChanged:j}),Y?c.jsx("input",{"data-id":"LocalTeamCard-rename-input",autoFocus:!0,value:m,onChange:g=>B(g.target.value),onFocus:g=>g.target.select(),onBlur:Nt,onClick:g=>g.stopPropagation(),onKeyDown:g=>{g.nativeEvent.isComposing||g.keyCode===229||(g.key==="Enter"?Nt():g.key==="Escape"&&T(!1))},style:{flex:1,width:"100%",font:"inherit",fontWeight:600,padding:"2px 6px",border:"1px solid #3b82f6",borderRadius:6,background:"#0d1117",color:"#e6edf3",boxSizing:"border-box"}}):c.jsxs("h3",{className:"bcard__name",title:r("localTeams.renameHint","点名字或 ✎ 改名"),style:{display:"flex",alignItems:"center",gap:6,flex:1,minWidth:0,margin:0},onDoubleClick:yt,children:[c.jsx("span",{"data-id":"LocalTeamCard-name-text",onClick:yt,style:{overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap",cursor:"text"},children:Q}),H==="saving"&&c.jsx("span",{"data-id":"LocalTeamCard-save-state",title:r("localTeams.saving","保存中…"),style:{flex:"none",display:"inline-flex"},children:c.jsx(ca,{})}),H==="saved"&&c.jsx("span",{"data-id":"LocalTeamCard-save-state",title:r("localTeams.saved","已保存"),style:{flex:"none",color:"#3fb950",fontSize:13,lineHeight:1},children:"✓"}),!H&&c.jsx("button",{type:"button","data-id":"LocalTeamCard-rename-btn",title:r("localTeams.rename","重命名"),onClick:yt,style:{flex:"none",cursor:"pointer",border:"none",background:"transparent",color:"#8b949e",fontSize:13,padding:0,lineHeight:1},children:"✎"})]})]}),c.jsx("div",{className:"bcard__meta",children:c.jsx("span",{className:"bcard__chip","data-id":"LocalTeamCard-kind",children:ot?r("localTeams.kindLocal","本地"):r("localTeams.kindCustom","自定义")})})]}),c.jsxs("button",{type:"button",className:"bcard__cta","data-id":"LocalTeamCard-open",disabled:!!ct||!s.base_url,onClick:it,children:[ct&&ct!=="stop"?c.jsx(ca,{}):c.jsx(co,{}),c.jsx("span",{children:ct&&oe[ct]||at})]})]}),ke&&Sa.createPortal(c.jsx("div",{"data-id":"LocalTeamCard-url-modal",style:{position:"fixed",inset:0,zIndex:65,display:"flex",alignItems:"center",justifyContent:"center",background:"rgba(0,0,0,.5)"},onMouseDown:g=>{!ve&&g.target===g.currentTarget&&J(!1)},children:c.jsxs("div",{onClick:g=>g.stopPropagation(),style:{width:400,maxWidth:"92vw",background:"var(--card, #1b1d22)",border:"1px solid var(--border, #2c2f36)",borderRadius:14,padding:22,boxShadow:"0 20px 60px rgba(0,0,0,.5)"},children:[c.jsx("div",{style:{fontSize:16,fontWeight:700,marginBottom:16},children:r("teamCard.editCustom","编辑自定义团队")}),c.jsx("label",{style:{display:"block",fontSize:12,opacity:.75,marginBottom:6},children:r("teams.customNameLabel","自定义标题")}),c.jsx("input",{"data-id":"LocalTeamCard-title-input",autoFocus:!0,className:"login-email-input",style:{width:"100%",marginBottom:14},value:Rt,placeholder:r("teams.customNamePlaceholder","我的团队"),spellCheck:!1,disabled:ve,onChange:g=>je(g.target.value),onKeyDown:g=>{g.nativeEvent.isComposing||g.keyCode===229||(g.key==="Enter"?(g.preventDefault(),ye()):g.key==="Escape"&&J(!1))}}),c.jsx("label",{style:{display:"block",fontSize:12,opacity:.75,marginBottom:6},children:r("teams.customUrlLabel","地址 URL")}),c.jsx("textarea",{"data-id":"LocalTeamCard-url-input",rows:3,className:"login-email-input",style:{width:"100%",resize:"vertical",lineHeight:1.5,fontFamily:"var(--mono)"},value:se,placeholder:"https://example.com:8008",spellCheck:!1,disabled:ve,onChange:g=>Me(g.target.value.replace(/[\r\n]+/g,"")),onKeyDown:g=>{g.nativeEvent.isComposing||g.keyCode===229||(g.key==="Enter"?(g.preventDefault(),ye()):g.key==="Escape"&&J(!1))}}),sa&&c.jsx("div",{className:"error",style:{marginTop:8,fontSize:12},children:sa}),c.jsxs("div",{className:"modal-actions",children:[c.jsx("button",{type:"button",className:"btn-ghost",disabled:ve,onClick:()=>J(!1),children:r("common.cancel","取消")}),c.jsx("button",{type:"button",className:"btn-primary","data-id":"LocalTeamCard-url-save",disabled:ve,onClick:ye,children:ve?r("common.saving","保存中…"):r("common.save","保存")})]})]})}),document.body),c.jsx(Nm,{open:ne,title:r("localTeams.deleteTitle","删除团队"),message:r("localTeams.deleteMsg","确定删除「{{name}}」?此操作不可撤销。",{name:s.name}),confirmLabel:r("common.delete","删除"),danger:!0,onConfirm:Ge,onCancel:()=>Zt(!1)})]})}function no(s){var b;try{if(((b=window.cicy)==null?void 0:b.platform)==="win32")return!1;const S=new URL(s);return(S.hostname==="127.0.0.1"||S.hostname==="localhost"||S.hostname==="::1")&&(S.port==="8008"||S.port==="")}catch{return!1}}function vm(s){var b;try{if(((b=window.cicy)==null?void 0:b.platform)!=="win32")return!1;const S=new URL(s);return(S.hostname==="127.0.0.1"||S.hostname==="localhost"||S.hostname==="::1")&&S.port==="8008"}catch{return!1}}function Sm(s,b){const S=String(s).split("."),d=String(b).split(".");for(let j=0;j<Math.max(S.length,d.length);j++){const M=(parseInt(S[j],10)||0)-(parseInt(d[j],10)||0);if(M)return M>0?1:-1}return 0}const xm={running:{tone:"ok",label:"running",cta:r("localStatus.open","打开")},stopped:{tone:"off",label:"stopped",cta:r("localStatus.notRunning","未运行")},auth_error:{tone:"warn",label:"auth error",cta:r("localStatus.tokenInvalid","Token 失效")},misconfigured:{tone:"err",label:"bad config",cta:r("localStatus.badUrl","URL 错误")},error:{tone:"err",label:"error",cta:r("localStatus.error","异常")}};function Nm({open:s,title:b,message:S,confirmLabel:d,danger:j,onConfirm:M,onCancel:k}){return s?Sa.createPortal(c.jsx("div",{"data-id":"ConfirmModal",style:{position:"fixed",inset:0,zIndex:70,display:"flex",alignItems:"center",justifyContent:"center",background:"rgba(0,0,0,.5)"},onMouseDown:Y=>{Y.target===Y.currentTarget&&(k==null||k())},children:c.jsxs("div",{onClick:Y=>Y.stopPropagation(),style:{width:360,maxWidth:"92vw",background:"var(--card, #1b1d22)",border:"1px solid var(--border, #2c2f36)",borderRadius:14,padding:22,boxShadow:"0 20px 60px rgba(0,0,0,.5)"},children:[c.jsx("div",{style:{fontSize:16,fontWeight:700,marginBottom:6},children:b}),S&&c.jsx("div",{style:{fontSize:13,opacity:.7,marginBottom:16},children:S}),c.jsxs("div",{className:"modal-actions",children:[c.jsx("button",{type:"button",className:"btn-ghost",onClick:k,children:r("common.cancel","取消")}),c.jsx("button",{type:"button",className:"btn-primary","data-id":"ConfirmModal-ok",style:j?{background:"#dc2626",borderColor:"#dc2626"}:{},onClick:M,children:d||r("common.confirm","确认")})]})]})}),document.body):null}function yy({team:s,onOpen:b,onRename:S,onEditUrl:d,onDelete:j,avatar:M,onAvatar:k}){const Y=s.kind==="private",T=s.status==="active",m=s.name||s.title||"—",[B,E]=v.useState(!1),[F,H]=v.useState(""),[$,Q]=v.useState(null),yt=$??m;v.useEffect(()=>{$!=null&&m===$&&Q(null)},[m,$]);const Nt=J=>{var Rt;(Rt=J==null?void 0:J.stopPropagation)==null||Rt.call(J),H(yt==="—"?"":yt),E(!0)},ce=async()=>{E(!1);const J=String(F||"").trim();if(!(!S||!J||J===yt)){Q(J);try{const Rt=await S(s.id,J);Rt!=null&&Rt.ok||Q(null)}catch{Q(null)}}},ot=s.host_url||"",[Lt,ct]=v.useState(!1),[xt,G]=v.useState(""),[gt,L]=v.useState(null),ht=gt??ot;v.useEffect(()=>{gt!=null&&ot===gt&&L(null)},[ot,gt]);const Ct=s.teamId||s.id,jt=Y?r("teamKind.private","私有云"):s.team_kind==="personal"?r("teamKind.personal","个人"):r("teamKind.shared","共享"),bt=Y?ht:s.workspace_url||s.workspace_direct_url,kt=!!bt,[Jt,C]=v.useState(!1),[q,nt]=v.useState(!1),[zt,_t]=v.useState({top:0,left:0}),h=v.useRef(null),N=v.useRef(null),Z=v.useRef(null),W=184,ft=()=>{if(!Jt&&N.current){const J=N.current.getBoundingClientRect(),Rt=Math.max(8,Math.min(J.right-W,window.innerWidth-W-8));_t({top:Math.round(J.bottom+4),left:Math.round(Rt)})}C(J=>!J)};v.useEffect(()=>{if(!Jt)return;const J=Rt=>{var je,se;(je=N.current)!=null&&je.contains(Rt.target)||(se=Z.current)!=null&&se.contains(Rt.target)||C(!1)};return document.addEventListener("mousedown",J),()=>document.removeEventListener("mousedown",J)},[Jt]);const vt=J=>{var Rt,je,se,Me;(Rt=J==null?void 0:J.stopPropagation)==null||Rt.call(J),kt&&(C(!1),(Me=(se=(je=window.cicy)==null?void 0:je.tabs)==null?void 0:se.reloadIfOpen)==null||Me.call(se,bt,yt))},[Ut,ne]=v.useState(!1),Zt=()=>{G(ot),ct(!0),C(!1)},ke=async()=>{ct(!1);const J=String(xt||"").trim();if(!(!d||!J||J===ot)){L(J);try{const Rt=await d(s.id,J);Rt!=null&&Rt.ok||L(null)}catch{L(null)}}};return c.jsxs(c.Fragment,{children:[c.jsxs("div",{"data-id":"TeamCard",className:`bcard bcard--cloud${T?" bcard--online":""}`,children:[c.jsx("div",{className:"bcard__accent"}),c.jsxs("div",{className:"bcard__top",children:[c.jsxs("div",{className:"bcard__pill",children:[c.jsx("span",{className:"bcard__dot","data-tone":T?"ok":"off"}),c.jsx(Ty,{})]}),c.jsxs("div",{className:"bcard__top-right",children:[s.is_trial&&c.jsx("span",{className:"bcard__badge",children:"trial"}),(kt||Ct!=null||Y&&d)&&c.jsxs("div",{className:"bcard__menuwrap",ref:h,onClick:J=>J.stopPropagation(),children:[c.jsx("button",{type:"button",ref:N,"data-id":"TeamCard-menu-btn",className:"bcard__kebab",title:r("localTeams.more","更多"),disabled:q,onClick:ft,children:q?c.jsx(ca,{}):c.jsx(so,{})}),Jt&&Sa.createPortal(c.jsxs("div",{className:"bcard__menu bcard__menu--portal","data-id":"TeamCard-menu",role:"menu",ref:Z,style:{position:"fixed",top:zt.top,left:zt.left,width:W},onClick:J=>J.stopPropagation(),children:[kt&&c.jsx("button",{type:"button","data-id":"TeamCard-reload",className:"bcard__menu-item",onClick:vt,children:r("localTeams.reloadWindow","刷新窗口")}),Ct!=null&&c.jsx("button",{type:"button","data-id":"TeamCard-billing",className:"bcard__menu-item",onClick:J=>{J.stopPropagation(),C(!1),Em(`?team=${encodeURIComponent(Ct)}`)},children:r("localTeams.billing","账单")}),Y&&d&&c.jsx("button",{type:"button","data-id":"TeamCard-edit-url",className:"bcard__menu-item",onClick:J=>{J.stopPropagation(),Zt()},children:ot?r("teamCard.editUrl","更改访问地址"):r("teamCard.setUrl","填写访问地址")}),Y&&j&&c.jsx("button",{type:"button","data-id":"TeamCard-delete",className:"bcard__menu-item is-danger",onClick:J=>{J.stopPropagation(),C(!1),ne(!0)},children:r("teamCard.delete","删除")})]}),document.body)]})]})]}),c.jsxs("div",{className:"bcard__body",children:[c.jsxs("div",{style:{height:28,display:"flex",alignItems:"center",gap:8},children:[c.jsx(uo,{size:24,avatar:M,name:(s==null?void 0:s.name)||(s==null?void 0:s.title),teamId:s==null?void 0:s.id,onChanged:k}),B?c.jsx("input",{"data-id":"TeamCard-rename-input",autoFocus:!0,value:F,onChange:J=>H(J.target.value),onFocus:J=>J.target.select(),onBlur:ce,onClick:J=>J.stopPropagation(),onKeyDown:J=>{J.nativeEvent.isComposing||J.keyCode===229||(J.key==="Enter"?ce():J.key==="Escape"&&E(!1))},style:{flex:1,width:"100%",font:"inherit",fontWeight:600,padding:"2px 6px",border:"1px solid #3b82f6",borderRadius:6,background:"#0d1117",color:"#e6edf3",boxSizing:"border-box"}}):c.jsxs("h3",{className:"bcard__name",title:S?r("localTeams.renameHint","点名字或 ✎ 改名"):yt,style:{display:"flex",alignItems:"center",gap:6,flex:1,minWidth:0,margin:0},onDoubleClick:S?Nt:void 0,children:[c.jsx("span",{onClick:S?Nt:void 0,style:{overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap",cursor:S?"text":"default"},children:yt}),S&&c.jsx("button",{type:"button","data-id":"TeamCard-rename-btn",title:r("localTeams.rename","重命名"),onClick:Nt,style:{flex:"none",cursor:"pointer",border:"none",background:"transparent",color:"#8b949e",fontSize:13,padding:0,lineHeight:1},children:"✎"})]})]}),c.jsxs("div",{className:"bcard__meta",children:[c.jsx("span",{className:"bcard__chip",children:jt}),!Y&&s.membership_status&&s.membership_status!=="active"&&c.jsx("span",{className:"bcard__chip",children:s.membership_status})]})]}),c.jsxs("button",{type:"button",className:"bcard__cta",onClick:b,disabled:!kt,children:[c.jsx(co,{}),c.jsx("span",{children:kt?r("localTeams.open","打开"):Y?r("teamCard.noHost","未填访问地址"):r("teamCard.noUrl","无 URL")})]})]}),Lt&&Sa.createPortal(c.jsx("div",{"data-id":"TeamCard-url-modal",style:{position:"fixed",inset:0,zIndex:65,display:"flex",alignItems:"center",justifyContent:"center",background:"rgba(0,0,0,.5)"},onMouseDown:J=>{J.target===J.currentTarget&&ct(!1)},children:c.jsxs("div",{onClick:J=>J.stopPropagation(),style:{width:400,maxWidth:"92vw",background:"var(--card, #1b1d22)",border:"1px solid var(--border, #2c2f36)",borderRadius:14,padding:22,boxShadow:"0 20px 60px rgba(0,0,0,.5)"},children:[c.jsx("div",{style:{fontSize:16,fontWeight:700,marginBottom:4},children:ot?r("teamCard.editUrl","更改访问地址"):r("teamCard.setUrl","填写访问地址")}),c.jsx("div",{style:{fontSize:12,opacity:.6,marginBottom:16},children:yt}),c.jsx("textarea",{"data-id":"TeamCard-url-input",autoFocus:!0,rows:3,className:"login-email-input",style:{width:"100%",resize:"vertical",lineHeight:1.5,fontFamily:"var(--mono)"},value:xt,placeholder:"https://你的私有云地址:端口",spellCheck:!1,onChange:J=>G(J.target.value.replace(/[\r\n]+/g,"")),onKeyDown:J=>{J.nativeEvent.isComposing||J.keyCode===229||(J.key==="Enter"?(J.preventDefault(),ke()):J.key==="Escape"&&ct(!1))}}),c.jsxs("div",{className:"modal-actions",children:[c.jsx("button",{type:"button",className:"btn-ghost",onClick:()=>ct(!1),children:r("common.cancel","取消")}),c.jsx("button",{type:"button",className:"btn-primary","data-id":"TeamCard-url-save",onClick:ke,children:r("common.save","保存")})]})]})}),document.body),c.jsx(Nm,{open:Ut,title:r("localTeams.deleteTitle","删除团队"),message:r("localTeams.deleteMsg","确定删除「{{name}}」?此操作不可撤销。",{name:yt}),confirmLabel:r("common.delete","删除"),danger:!0,onConfirm:async()=>{ne(!1),j&&await j(s)},onCancel:()=>ne(!1)})]})}function _m(){return c.jsxs("div",{className:"brand",children:[c.jsx("div",{className:"brand-mark",children:c.jsx(_y,{})}),c.jsxs("div",{className:"brand-text",children:[c.jsx("div",{className:"brand-name",children:"CiCy Desktop"}),c.jsx("div",{className:"brand-sub",children:r("app.brandSub","团队 AI 协作工作台")})]})]})}function gy(){const[s,b]=v.useState(null),[S,d]=v.useState(!1),[j,M]=v.useState(!1),k=v.useRef(!1),Y=B=>{var E,F,H;M(B),(H=(F=(E=window.cicy)==null?void 0:E.app)==null?void 0:F.setAutoUpdate)==null||H.call(F,B).catch(()=>{})};v.useEffect(()=>{var F,H,$,Q,yt,Nt,ce,ot,Lt;let B=!0;($=(H=(F=window.cicy)==null?void 0:F.app)==null?void 0:H.updateState)==null||$.call(H).then(ct=>{B&&b(ct)}).catch(()=>{}),(Nt=(yt=(Q=window.cicy)==null?void 0:Q.app)==null?void 0:yt.getAutoUpdate)==null||Nt.call(yt).then(ct=>{B&&M(ct===!0)}).catch(()=>{});const E=(Lt=(ot=(ce=window.cicy)==null?void 0:ce.app)==null?void 0:ot.onUpdateState)==null?void 0:Lt.call(ot,ct=>{b(ct),typeof(ct==null?void 0:ct.autoUpdate)=="boolean"&&M(ct.autoUpdate),ct!=null&&ct.auto&&!k.current&&(ct.status==="downloading"||ct.status==="ready")&&(k.current=!0,d(!0),me.open({kind:"app",title:r("updateBanner.drawerTitle","应用更新"),fromVer:ct.current,toVer:ct.version,onRetry:()=>{var xt,G,gt;return(gt=(G=(xt=window.cicy)==null?void 0:xt.app)==null?void 0:G.downloadUpdate)==null?void 0:gt.call(G)}}),me.push({phase:"download",status:"running",message:r("updateBanner.autoDl","已开启自动更新,正在下载安装包…")})),k.current&&(ct.status==="downloading"?me.setProgress(ct.progress||{}):ct.status==="ready"?me.ready({onInstall:()=>{var xt,G,gt;return(gt=(G=(xt=window.cicy)==null?void 0:xt.app)==null?void 0:G.installUpdate)==null?void 0:gt.call(G)}}):ct.status==="error"&&(me.finish({ok:!1,message:ct.error||r("updateBanner.error","更新失败")}),k.current=!1))});return()=>{B=!1;try{E&&E()}catch{}}},[]);const T=s==null?void 0:s.status;v.useEffect(()=>{d(!1)},[T]);const m=()=>{var B,E,F;k.current=!0,d(!0),me.open({kind:"app",title:r("updateBanner.drawerTitle","应用更新"),fromVer:s==null?void 0:s.current,toVer:s==null?void 0:s.version,onRetry:m}),me.push({phase:"download",status:"running",message:r("updateBanner.startDl","开始下载安装包…")}),me.setProgress({percent:0}),(F=(E=(B=window.cicy)==null?void 0:B.app)==null?void 0:E.downloadUpdate)==null||F.call(E)};return T!=="available"||S?null:Sa.createPortal(c.jsx("div",{"data-id":"UpdateBanner",style:{position:"fixed",inset:0,zIndex:1e4,background:"rgba(0,0,0,0.6)",backdropFilter:"blur(3px)",display:"flex",alignItems:"center",justifyContent:"center"},onMouseDown:B=>{B.target===B.currentTarget&&d(!0)},children:c.jsxs("div",{onClick:B=>B.stopPropagation(),style:{width:380,maxWidth:"90vw",background:"#161b22",border:"1px solid #30363d",borderRadius:14,padding:"24px 24px 20px",boxShadow:"0 20px 60px rgba(0,0,0,0.55)",textAlign:"center"},children:[c.jsx("div",{style:{fontSize:34,lineHeight:1,marginBottom:12},"aria-hidden":!0,children:"🚀"}),c.jsx("h3",{style:{margin:"0 0 8px",fontSize:17,color:"#e6edf3"},"data-id":"UpdateBanner-text",children:r("updateBanner.available","发现新版本 v{{v}}",{v:s.version})}),c.jsx("p",{style:{margin:"0 0 14px",fontSize:13,lineHeight:1.6,color:"#9aa4b2"},children:r("updateBanner.modalSub","建议尽快更新到最新版本")}),c.jsxs("label",{"data-id":"UpdateBanner-auto",style:{display:"flex",alignItems:"center",justifyContent:"center",gap:7,margin:"0 0 18px",fontSize:12.5,color:"#c9d1d9",cursor:"pointer",userSelect:"none"},children:[c.jsx("input",{type:"checkbox",checked:j,onChange:B=>Y(B.target.checked),style:{accentColor:"#238636",width:15,height:15,margin:0,cursor:"pointer"}}),r("updateBanner.autoNext","以后发现新版本自动更新,不再询问")]}),c.jsxs("div",{style:{display:"flex",gap:10,justifyContent:"center"},children:[c.jsx("button",{type:"button","data-id":"UpdateBanner-later",onClick:()=>d(!0),style:{flex:1,padding:"9px 16px",borderRadius:9,border:"1px solid #30363d",background:"transparent",color:"#c9d1d9",cursor:"pointer",fontSize:14},children:r("updateBanner.later","稍后")}),c.jsx("button",{type:"button","data-id":"UpdateBanner-download",onClick:m,style:{flex:1,padding:"9px 16px",borderRadius:9,border:"none",background:"#238636",color:"white",cursor:"pointer",fontSize:14,fontWeight:600},children:r("updateBanner.updateNow","立即更新")})]})]})}),document.body)}function by(){return c.jsxs("div",{className:"bcard bcard--skeleton","data-id":"SkeletonCard","aria-hidden":!0,children:[c.jsx("div",{className:"bcard__accent",style:{background:"rgba(255,255,255,.08)",opacity:1}}),c.jsxs("div",{className:"bcard__top",children:[c.jsx("div",{className:"skel",style:{width:84,height:26,borderRadius:999}}),c.jsx("div",{className:"skel",style:{width:22,height:22,borderRadius:6}})]}),c.jsxs("div",{style:{flex:1,minHeight:0,marginTop:14},children:[c.jsxs("div",{style:{display:"flex",alignItems:"center",gap:8},children:[c.jsx("div",{className:"skel",style:{width:24,height:24,borderRadius:6,flex:"0 0 auto"}}),c.jsx("div",{className:"skel skel--line",style:{width:"55%"}})]}),c.jsx("div",{className:"skel",style:{width:60,height:18,borderRadius:6,marginTop:12}})]}),c.jsx("div",{className:"skel skel--cta",style:{marginTop:0}})]})}const wm=["hsl(2 68% 48%)","hsl(26 72% 46%)","hsl(45 70% 42%)","hsl(96 55% 38%)","hsl(140 58% 40%)","hsl(168 62% 36%)","hsl(192 70% 42%)","hsl(210 72% 50%)","hsl(232 62% 56%)","hsl(266 55% 55%)","hsl(292 58% 50%)","hsl(324 66% 50%)"];function vy(s){s=String(s??"");let b=0;for(let S=0;S<s.length;S++)b=(b*31+s.charCodeAt(S))%100003;return b}function Sy(s){return wm[vy(s)%wm.length]}function xy({open:s,onClose:b,toastId:S="dood-op"}){const[d,j]=v.useState(!1),[M,k]=v.useState(""),[Y,T]=v.useState(!1),[m,B]=v.useState("");v.useEffect(()=>{var H,$;!s||!(($=(H=window.cicy)==null?void 0:H.sidecar)!=null&&$.getDood)||(k(""),B(""),window.cicy.sidecar.getDood().then(Q=>T(!!(Q!=null&&Q.dood))).catch(()=>{}))},[s]),v.useEffect(()=>{var H,$;if(!(!s||!d||!(($=(H=window.cicy)==null?void 0:H.sidecar)!=null&&$.onOpProgress)))return window.cicy.sidecar.onOpProgress(Q=>{Q!=null&&Q.message&&B(String(Q.message))})},[s,d]);const E=async()=>{if(!d){j(!0),k(""),B(""),Tt.show({id:S,message:Y?r("dood.applying","开启容器 Docker 访问,重建容器中…"):r("dood.disabling","关闭中…"),status:"running",progress:void 0});try{const H=await window.cicy.sidecar.setDood(Y);H!=null&&H.ok?(b&&b(),Tt.show({id:S,message:Y?r("dood.onDone","容器 Docker 访问已开启"):r("dood.offDone","容器 Docker 访问已关闭"),status:"done",ttl:4e3})):(k((H==null?void 0:H.error)||r("dood.failed","设置失败")),Tt.show({id:S,message:r("dood.failed","设置失败")+(H!=null&&H.error?`: ${H.error}`:""),status:"error",ttl:6e3}))}catch(H){k((H==null?void 0:H.message)||String(H)),Tt.show({id:S,message:r("dood.failed","设置失败")+`: ${(H==null?void 0:H.message)||H}`,status:"error",ttl:6e3})}finally{j(!1)}}},F=H=>{b&&b()};return s?c.jsx(c.Fragment,{children:Sa.createPortal(c.jsx("div",{"data-id":"dood-modal",style:{position:"fixed",inset:0,zIndex:66,display:"flex",alignItems:"center",justifyContent:"center",background:"rgba(0,0,0,.5)"},onMouseDown:H=>{!d&&H.target===H.currentTarget&&F()},children:c.jsxs("div",{onClick:H=>H.stopPropagation(),style:{width:440,maxWidth:"92vw",background:"var(--card, #1b1d22)",border:"1px solid var(--border, #2c2f36)",borderRadius:14,padding:22,boxShadow:"0 20px 60px rgba(0,0,0,.5)"},children:[c.jsx("div",{style:{fontSize:16,fontWeight:700,marginBottom:4},children:r("dood.title","容器内使用 Docker")}),c.jsx("div",{style:{fontSize:12,opacity:.6,marginBottom:16},children:r("dood.subtitle","把宿主 Docker + docker 客户端挂进容器,容器内 agent 就能直接跑 docker(秒生效,无需下载)")}),c.jsxs("label",{"data-id":"dood-toggle-row",style:{display:"flex",alignItems:"center",gap:10,cursor:d?"default":"pointer",marginBottom:12},children:[c.jsx("input",{type:"checkbox","data-id":"dood-toggle",checked:Y,disabled:d,onChange:H=>T(H.target.checked)}),c.jsx("span",{style:{fontSize:14,fontWeight:600},children:r("dood.enable","允许容器内使用 Docker")})]}),d&&m&&c.jsx("div",{"data-id":"dood-progress",style:{fontSize:11,opacity:.7,fontFamily:"var(--mono)",wordBreak:"break-all",margin:"0 0 8px",maxHeight:60,overflow:"hidden"},children:m}),M&&c.jsx("div",{className:"error",style:{marginTop:8,fontSize:12},children:M}),c.jsxs("div",{className:"modal-actions",children:[c.jsx("button",{type:"button",className:"btn-ghost",disabled:d,onClick:()=>F(),children:r("common.cancel","取消")}),c.jsx("button",{type:"button",className:"btn-primary","data-id":"dood-save",disabled:d,onClick:E,children:d?r("common.saving","保存中…"):r("common.save","保存")})]})]})}),document.body)}):null}function uo({avatar:s,name:b,teamId:S,onChanged:d,size:j=34}){const M=v.useRef(null),k=((b||"?").trim()[0]||"?").toUpperCase(),Y=Sy(S||b||""),T=m=>{const B=m.target.files&&m.target.files[0];if(m.target.value="",!B)return;const E=new FileReader;E.onload=async()=>{var F,H,$;try{await(($=(H=(F=window.cicy)==null?void 0:F.localTeams)==null?void 0:H.setAvatar)==null?void 0:$.call(H,S,E.result)),d&&d()}catch{}},E.readAsDataURL(B)};return c.jsxs("div",{"data-id":"TeamAvatar",className:"team-avatar",title:S?r("teamCard.changeAvatar","点击更换头像"):"",onClick:S?m=>{m.stopPropagation(),M.current&&M.current.click()}:void 0,style:{width:j,height:j,borderRadius:9,flex:"none",overflow:"hidden",display:"flex",alignItems:"center",justifyContent:"center",cursor:S?"pointer":"default",background:s?"#0d1117":Y,color:"#fff",fontWeight:700,fontSize:Math.round(j*.42),userSelect:"none"},children:[s?c.jsx("img",{src:s,alt:"",style:{width:"100%",height:"100%",objectFit:"cover"}}):k,S&&c.jsx("input",{ref:M,type:"file",accept:"image/*",style:{display:"none"},onChange:T})]})}function _y(){return c.jsxs("svg",{width:"22",height:"22",viewBox:"0 0 96 96",fill:"none",children:[c.jsx("path",{d:"M48 11L39.5 33.3L16 29.5L31 48L16 66.5L39.5 62.7L48 85L56.5 62.7L80 66.5L65 48L80 29.5L56.5 33.3Z",stroke:"white",strokeWidth:"10",strokeLinejoin:"round",strokeLinecap:"round"}),c.jsx("circle",{cx:"48",cy:"48",r:"6",fill:"white"})]})}function co(){return c.jsxs("svg",{width:"16",height:"16",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2.2",strokeLinecap:"round",strokeLinejoin:"round",children:[c.jsx("line",{x1:"5",y1:"12",x2:"19",y2:"12"}),c.jsx("polyline",{points:"12 5 19 12 12 19"})]})}function ca(){return c.jsx("svg",{className:"spin",width:"16",height:"16",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2.4",strokeLinecap:"round",children:c.jsx("path",{d:"M21 12a9 9 0 1 1-6.2-8.55"})})}function wy(){return c.jsxs("svg",{width:"12",height:"12",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:[c.jsx("rect",{x:"3",y:"4",width:"18",height:"12",rx:"2"}),c.jsx("line",{x1:"2",y1:"20",x2:"22",y2:"20"})]})}function so(){return c.jsxs("svg",{width:"16",height:"16",viewBox:"0 0 24 24",fill:"currentColor","aria-hidden":!0,children:[c.jsx("circle",{cx:"12",cy:"5",r:"1.7"}),c.jsx("circle",{cx:"12",cy:"12",r:"1.7"}),c.jsx("circle",{cx:"12",cy:"19",r:"1.7"})]})}function Ty(){return c.jsxs("svg",{width:"12",height:"12",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:[c.jsx("circle",{cx:"12",cy:"12",r:"10"}),c.jsx("line",{x1:"2",y1:"12",x2:"22",y2:"12"}),c.jsx("path",{d:"M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z"})]})}function An(s){try{return localStorage.getItem(s)||null}catch{return null}}function wi(s){return s?/timeout/i.test(s)?"登录超时,请重新点击 Login。":/state/i.test(s)?"校验失败,请重新登录。":/no token/i.test(s)?"登录未完成,请重试。":/bridge missing/i.test(s)?"无法连接到登录服务(preload 未就绪)。":s:""}var Tm;const Cy=((Tm=window.cicy)==null?void 0:Tm.platform)||(()=>{const s=navigator.userAgent||"";return/Mac/i.test(s)?"darwin":/Windows/i.test(s)?"win32":"linux"})();document.documentElement.dataset.platform=Cy;document.documentElement.dataset.fullscreen="0";var Cm,jm;(jm=(Cm=window.cicy)==null?void 0:Cm.window)!=null&&jm.onFullscreen&&window.cicy.window.onFullscreen(s=>{document.documentElement.dataset.fullscreen=s?"1":"0"});Fp.createRoot(document.getElementById("root")).render(c.jsx(cy,{}));
|
|
377
|
+
`)}function ey({title:s,url:b}={}){const S=String(s||"").trim();return S?{ok:!0,patch:{name:S,base_url:String(b||"").trim()}}:{ok:!1,error:"title_required"}}const r=(s,b,S)=>{var j,M;const d=k=>S&&typeof k=="string"?k.replace(/\{\{\s*(\w+)\s*\}\}/g,(Y,T)=>S[T]!=null?String(S[T]):Y):k;try{const k=(M=(j=window.cicyI18n)==null?void 0:j.t)==null?void 0:M.call(j,s,S);return d(k&&k!==s?k:b)}catch{return d(b)}},jn="cicy_token",Ru="cicy_access_token",Si="cicy_user_id",ay="cicy_guest",ql="https://cicy-ai.com",ly=1;async function Em(s){var S,d,j,M,k,Y,T,m;const b=`${ql}/dash${s}`;try{if((d=(S=window.cicy)==null?void 0:S.tabs)!=null&&d.openIn){await window.cicy.tabs.openIn(ly,b,"cicy-ai");return}(k=(M=(j=window.cicy)==null?void 0:j.shell)==null?void 0:M.openExternal)==null||k.call(M,b)}catch{try{(m=(T=(Y=window.cicy)==null?void 0:Y.shell)==null?void 0:T.openExternal)==null||m.call(T,b)}catch{}}}const eo=new Set;let ny=0,Sl=[];const xi=new Map;function hm(){eo.forEach(s=>s(Sl))}const Tt={show(s={}){const b=s.id||`t${++ny}`,S=Sl.find(M=>M.id===b),d={id:b,status:"running",...S,...s};Sl=S?Sl.map(M=>M.id===b?d:M):[...Sl,d],hm();const j=xi.get(b);return j&&(clearTimeout(j),xi.delete(b)),s.ttl&&xi.set(b,setTimeout(()=>Tt.dismiss(b),s.ttl)),b},dismiss(s){Sl=Sl.filter(S=>S.id!==s);const b=xi.get(s);b&&(clearTimeout(b),xi.delete(s)),hm()}};function iy(){const[s,b]=v.useState(Sl);return v.useEffect(()=>(eo.add(b),()=>{eo.delete(b)}),[]),s.length?c.jsx("div",{className:"toast-host","data-id":"ToastHost",children:s.map(S=>c.jsxs("div",{className:"toast","data-id":`Toast-${S.id}`,"data-status":S.status||"running",children:[c.jsx("button",{type:"button",className:"toast__x","data-id":"Toast-dismiss",onClick:()=>Tt.dismiss(S.id),"aria-label":"dismiss",children:"×"}),c.jsxs("span",{className:"toast__msg",children:[S.message,Number.isFinite(S.progress)?` ${S.progress}%`:""]}),Number.isFinite(S.progress)&&c.jsx("span",{className:"toast__bar",children:c.jsx("span",{style:{width:`${Math.min(100,S.progress)}%`}})})]},S.id))}):null}const ao=new Set;let Is=0,Ft=null;function vl(){ao.forEach(s=>s(Ft))}function _i(){return new Date().toTimeString().slice(0,8)}const me={open({teamId:s,fromVer:b,toVer:S,onRetry:d,title:j,kind:M}={}){Ft={teamId:s,title:j||null,fromVer:b||null,toVer:S||null,kind:M||"sidecar",status:"running",phase:"download",progress:null,onInstall:null,logs:[],onRetry:d||null,lastAt:Date.now()},vl()},setProgress(s){Ft&&(Ft={...Ft,status:"running",progress:s||Ft.progress,lastAt:Date.now()},vl())},ready({onInstall:s,message:b}={}){if(!Ft)return;const S={id:++Is,t:_i(),phase:"done",status:"done",message:b||r("updateBanner.readyDrawer","下载完成,点「安装」重启更新")};Ft={...Ft,status:"ready",phase:"done",progress:{...Ft.progress||{},percent:100},onInstall:s||null,minimized:!1,logs:[...Ft.logs,S],lastAt:Date.now()},vl()},push(s={}){if(!Ft)return;const b={id:++Is,t:_i(),phase:s.phase||Ft.phase,status:s.status||"running",message:s.message||""};Ft={...Ft,phase:s.phase||Ft.phase,toVer:s.toVer||Ft.toVer,logs:[...Ft.logs,b],lastAt:Date.now()},vl()},minimize(){Ft&&(Ft={...Ft,minimized:!0},vl())},restore(){Ft&&(Ft={...Ft,minimized:!1},vl())},finish({ok:s,message:b}={}){if(!Ft)return;const S=s?"done":"error",d={id:++Is,t:_i(),phase:"done",status:S,message:b||(s?r("updateDrawer.done","更新完成"):r("updateDrawer.failed","更新失败"))};Ft={...Ft,status:S,phase:"done",minimized:!1,logs:[...Ft.logs,d],lastAt:Date.now()},vl()},close(){Ft=null,vl()}},Ps=["download","swap","done"],pm=s=>({download:r("updateDrawer.phaseDownload","下载"),swap:r("updateDrawer.phaseSwap","切换"),done:r("updateDrawer.phaseDone","完成")})[s]||s;function uy(){var Y;const[s,b]=v.useState(Ft);v.useEffect(()=>(ao.add(b),()=>{ao.delete(b)}),[]);const S=v.useRef(null);v.useEffect(()=>{const T=S.current;T&&(T.scrollTop=T.scrollHeight)},[(Y=s==null?void 0:s.logs)==null?void 0:Y.length]);const[d,j]=v.useState(!1);if(v.useEffect(()=>{if(!s||s.status!=="running"){j(!1);return}const T=setInterval(()=>j(Date.now()-(s.lastAt||0)>25e3),3e3);return()=>clearInterval(T)},[s==null?void 0:s.lastAt,s==null?void 0:s.status]),!s)return null;const M=s.status==="running",k=Ps.findIndex(T=>T===s.phase);return s.minimized?c.jsxs("button",{type:"button",className:`drawer-min drawer-min--${s.status}`,"data-id":"UpdateDrawer-restore",onClick:()=>me.restore(),children:[c.jsx("span",{className:"drawer-min__spark",children:M?c.jsx(ca,{}):s.status==="done"?"✓":s.status==="reboot"?"⟳":"!"}),c.jsxs("span",{className:"drawer-min__label",children:[s.title||r("updateDrawer.title","更新 cicy-code"),s.toVer?` · v${s.toVer}`:""]})]}):c.jsx("div",{className:"drawer-scrim","data-id":"UpdateDrawer-scrim",onClick:()=>M?me.minimize():me.close(),children:c.jsxs("div",{className:"drawer","data-id":"UpdateDrawer","data-status":s.status,onClick:T=>T.stopPropagation(),children:[c.jsxs("div",{className:"drawer__head",children:[c.jsxs("div",{className:"drawer__title",children:[c.jsx("span",{className:`drawer__spark drawer__spark--${s.status}`,children:M?c.jsx(ca,{}):s.status==="done"?"✓":s.status==="reboot"?"⟳":"!"}),c.jsxs("div",{children:[c.jsx("div",{className:"drawer__h",children:s.title||r("updateDrawer.title","更新 cicy-code")}),c.jsxs("div",{className:"drawer__sub",children:[s.fromVer?`v${s.fromVer}`:r("updateDrawer.current","当前")," → ",s.toVer?`v${s.toVer}`:r("updateDrawer.latest","最新版")]})]})]}),c.jsx("div",{className:"drawer__headbtns",children:c.jsx("button",{type:"button",className:"drawer__x","data-id":"UpdateDrawer-min",title:r("updateDrawer.minimize","最小化"),onClick:()=>me.minimize(),"aria-label":"minimize",children:"‒"})})]}),s.kind!=="app"&&c.jsx("div",{className:"drawer__steps","data-id":"UpdateDrawer-steps",children:Ps.map((T,m)=>{const B=pm(T),E=s.status==="done"||m<k,F=m===k&&M,H=s.status==="error"&&m===k;return c.jsxs("div",{className:`drawer__step${F?" is-active":""}${E?" is-done":""}${H?" is-error":""}`,children:[c.jsx("span",{className:"drawer__step-dot",children:E?"✓":H?"!":m+1}),c.jsx("span",{className:"drawer__step-label",children:B}),m<Ps.length-1&&c.jsx("span",{className:"drawer__step-bar"})]},T)})}),s.progress&&(()=>{const T=s.progress,m=B=>B?(B/1048576).toFixed(1):"0";return c.jsxs("div",{className:"drawer__dl","data-id":"UpdateDrawer-dl",children:[c.jsxs("div",{className:"drawer__dl-head",children:[c.jsxs("span",{className:"drawer__dl-pct",children:[T.percent||0,"%"]}),c.jsxs("span",{className:"drawer__dl-stats",children:[T.total?`${m(T.transferred)} / ${m(T.total)} MB`:`${m(T.transferred)} MB`,T.bytesPerSec?` · ${m(T.bytesPerSec)} MB/s`:"",T.etaSec?` · ${r("updateBanner.eta","剩 {{s}}s",{s:T.etaSec})}`:""]})]}),c.jsx("div",{className:"drawer__dl-track",children:c.jsx("span",{className:"drawer__dl-fill",style:{width:`${T.percent||0}%`}})})]})})(),c.jsx("div",{className:"drawer__log","data-id":"UpdateDrawer-log",ref:S,children:s.logs.length===0?c.jsx("div",{className:"drawer__log-empty",children:r("updateDrawer.preparing","准备中…")}):s.logs.map(T=>c.jsxs("div",{className:"drawer__line","data-status":T.status,children:[c.jsx("span",{className:"drawer__t",children:T.t}),c.jsx("span",{className:`drawer__badge drawer__badge--${T.phase}`,children:pm(T.phase)}),c.jsx("span",{className:"drawer__linemsg",children:T.message})]},T.id))}),d&&M&&c.jsx("div",{className:"drawer__hint","data-id":"UpdateDrawer-stuck",children:r("updateDrawer.stuckHint","正在等待新版本就绪,耗时比平常久。可以放到后台继续,完成或失败都会提示。")}),c.jsx("div",{className:"drawer__foot",children:M?c.jsx(c.Fragment,{children:c.jsx("span",{className:"drawer__foot-status",children:s.kind==="app"?r("updateBanner.downloading","正在下载更新")+"…":r("updateDrawer.inProgress","更新进行中…")})}):s.status==="ready"?c.jsxs(c.Fragment,{children:[c.jsx("span",{className:"drawer__foot-status is-done",children:r("updateBanner.readyShort","下载完成")}),c.jsx("button",{type:"button",className:"drawer__btn is-accent","data-id":"UpdateDrawer-install",onClick:()=>s.onInstall&&s.onInstall(),children:r("updateBanner.installBtn","立即安装")}),c.jsx("button",{type:"button",className:"drawer__btn","data-id":"UpdateDrawer-later",onClick:()=>me.close(),children:r("updateBanner.later","稍后")})]}):s.status==="error"?c.jsxs(c.Fragment,{children:[c.jsx("span",{className:"drawer__foot-status is-error",children:r("updateDrawer.failed","更新失败")}),s.onRetry&&c.jsx("button",{type:"button",className:"drawer__btn is-accent","data-id":"UpdateDrawer-retry",onClick:()=>s.onRetry(),children:r("common.retry","重试")}),c.jsx("button",{type:"button",className:"drawer__btn","data-id":"UpdateDrawer-dismiss",onClick:()=>me.close(),children:r("common.close","关闭")})]}):c.jsxs(c.Fragment,{children:[c.jsx("span",{className:"drawer__foot-status is-done",children:r("updateDrawer.updatedLatest","已更新到最新")}),c.jsx("button",{type:"button",className:"drawer__btn is-accent","data-id":"UpdateDrawer-finish",onClick:()=>me.close(),children:r("common.done","完成")})]})})]})})}function cy(){const[s,b]=v.useState(void 0);v.useEffect(()=>{var D,V;if(!((V=(D=window.cicy)==null?void 0:D.terms)!=null&&V.status)){b(!0);return}window.cicy.terms.status(Am).then(K=>b(!!(K!=null&&K.accepted))).catch(()=>b(!0))},[]),v.useEffect(()=>{var K,et,tt,$t;const D=document.documentElement;try{D.setAttribute("data-platform",((K=window.cicy)==null?void 0:K.platform)||"linux")}catch{}D.setAttribute("data-fullscreen","0");let V;try{V=($t=(tt=(et=window.cicy)==null?void 0:et.window)==null?void 0:tt.onFullscreen)==null?void 0:$t.call(tt,Et=>D.setAttribute("data-fullscreen",Et?"1":"0"))}catch{}return()=>{try{V&&V()}catch{}}},[]),v.useEffect(()=>{var V,K;if(!((K=(V=window.cicy)==null?void 0:V.docker)!=null&&K.onAppProgress))return;const D=window.cicy.docker.onAppProgress(et=>{!et||et.phase==="open"||(Qt||Ot.open({source:"auto"}),(Qt==null?void 0:Qt.source)==="auto"&&(et.phase==="done"&&(et.status==="done"||et.status==="reboot")?Ot.finish({ok:et.status==="done",status:et.status==="reboot"?"reboot":void 0,message:et.message}):et.status==="error"?Ot.finish({ok:!1,message:et.message}):Ot.push(et)))});return()=>{try{D&&D()}catch{}}},[]);const[S,d]=v.useState(()=>An(jn)),[j,M]=v.useState(()=>An(Ru)),[k,Y]=v.useState(()=>An(Si)),[T,m]=v.useState(()=>!An(jn)),[B,E]=v.useState(!0),F=()=>E(!0),[H,$]=v.useState(!1),[Q,yt]=v.useState(!1),[Nt,ce]=v.useState(""),[ot,Lt]=v.useState(""),[ct,xt]=v.useState(!1),[G,gt]=v.useState(""),[L,ht]=v.useState(""),[Ct,jt]=v.useState(null),[bt,kt]=v.useState(null),[Jt,C]=v.useState(!1),[q,nt]=v.useState(""),zt=v.useRef(!1),[_t,h]=v.useState(null),[N,Z]=v.useState(!1),[W,ft]=v.useState(!1),[vt,Ut]=v.useState({}),ne=v.useCallback(async()=>{var D,V,K;try{const et=await((K=(V=(D=window.cicy)==null?void 0:D.localTeams)==null?void 0:V.avatars)==null?void 0:K.call(V));Ut(et&&typeof et=="object"?et:{})}catch{}},[]),[Zt,ke]=v.useState(!1),[J,Rt]=v.useState(!1),[je,se]=v.useState(""),[Me,ve]=v.useState(""),[Ye,sa]=v.useState(!1),[Le,ye]=v.useState(""),[Ge,Qe]=v.useState("all"),Pe=v.useCallback(async(D,V)=>{var et,tt,$t,Et;if(!D)return;if(!((tt=(et=window.cicy)==null?void 0:et.cloud)!=null&&tt.fetch)){nt("cloud fetch bridge missing");return}C(!0),nt("");const K={Authorization:`Bearer ${D}`};try{const[Ze,ze]=await Promise.all([window.cicy.cloud.fetch(`${ql}/api/user/self`,{headers:K}),window.cicy.cloud.fetch(`${ql}/api/teams`,{headers:K})]);if((ze==null?void 0:ze.status)===401){if(!zt.current&&((Et=($t=window.cicy)==null?void 0:$t.auth)!=null&&Et.loginStart)){zt.current=!0,nt(r("auth.sessionExpired","会话已过期,正在重新登录…"));try{await window.cicy.auth.loginStart()}catch{}}return}if(ze!=null&&ze.ok){const xe=JSON.parse(ze.body||"{}");kt(Array.isArray(xe==null?void 0:xe.teams)?xe.teams:[])}else kt(xe=>xe===null?[]:xe);if(Ze!=null&&Ze.ok)try{const xe=JSON.parse(Ze.body||"{}");jt((xe==null?void 0:xe.success)===!1?null:(xe==null?void 0:xe.data)||null)}catch{jt(null)}else jt(null)}catch{nt(""),kt(ze=>ze===null?[]:ze)}finally{C(!1)}},[]),oe=v.useRef("");v.useEffect(()=>{oe.current=S||j||""},[S,j]);const R=v.useCallback(async()=>{var V,K;const D=oe.current;if(!(!D||!((K=(V=window.cicy)==null?void 0:V.cloud)!=null&&K.fetch)))try{const et=await window.cicy.cloud.fetch(`${ql}/api/teams`,{headers:{Authorization:`Bearer ${D}`}});if(et!=null&&et.ok){const tt=JSON.parse(et.body||"{}");Array.isArray(tt==null?void 0:tt.teams)&&kt(tt.teams)}}catch{}},[]),it=v.useCallback(async(D,V)=>{var tt,$t;const K=oe.current,et=String(V||"").trim();if(!K||!(($t=(tt=window.cicy)==null?void 0:tt.cloud)!=null&&$t.fetch)||!et)return{ok:!1,error:"no session / empty"};try{const Et=await window.cicy.cloud.fetch(`${ql}/api/teams/${D}`,{method:"PATCH",headers:{Authorization:`Bearer ${K}`,"Content-Type":"application/json"},body:JSON.stringify({title:et})});return Et!=null&&Et.ok?(await R(),{ok:!0}):{ok:!1,error:`${(Et==null?void 0:Et.status)||"?"} ${(Et==null?void 0:Et.error)||""}`}}catch(Et){return{ok:!1,error:Et.message}}},[R]),at=v.useCallback(async(D,V)=>{var tt,$t;const K=oe.current,et=String(V||"").trim();if(!K||!(($t=(tt=window.cicy)==null?void 0:tt.cloud)!=null&&$t.fetch)||!et)return{ok:!1,error:"no session / empty"};try{new URL(et)}catch{return{ok:!1,error:"地址格式不对(需 http(s)://…)"}}try{const Et=await window.cicy.cloud.fetch(`${ql}/api/teams/${D}`,{method:"PATCH",headers:{Authorization:`Bearer ${K}`,"Content-Type":"application/json"},body:JSON.stringify({hostUrl:et})});return Et!=null&&Et.ok?(await R(),{ok:!0}):{ok:!1,error:`${(Et==null?void 0:Et.status)||"?"} ${(Et==null?void 0:Et.error)||""}`}}catch(Et){return{ok:!1,error:Et.message}}},[R]),ut=v.useCallback(async D=>{var K,et;const V=oe.current;if(!V||!((et=(K=window.cicy)==null?void 0:K.cloud)!=null&&et.fetch)){Tt.show({message:r("common.noAuth","未登录"),status:"error",ttl:5e3});return}try{const tt=await window.cicy.cloud.fetch(`${ql}/api/teams/${D.id}`,{method:"DELETE",headers:{Authorization:`Bearer ${V}`}});tt!=null&&tt.ok||(tt==null?void 0:tt.status)===200||(tt==null?void 0:tt.status)===204?(Tt.show({message:r("teamCard.deleted","团队已删除"),status:"done",ttl:3e3}),await R()):Tt.show({message:`${r("teamCard.deleteFailed","删除失败")}: ${(tt==null?void 0:tt.status)||"?"} ${(tt==null?void 0:tt.error)||""}`,status:"error",ttl:7e3})}catch(tt){Tt.show({message:`${r("teamCard.deleteFailed","删除失败")}: ${tt.message}`,status:"error",ttl:7e3})}},[R]);v.useEffect(()=>{const D=S||j;D?Pe(D,k):kt(V=>V===null?[]:V)},[S,j,k,Pe]);const St=v.useCallback(async()=>{var D,V;if((V=(D=window.cicy)==null?void 0:D.localTeams)!=null&&V.list){Z(!0);try{const K=await window.cicy.localTeams.list({refresh:!0,uid:An(Si)||""});h(Array.isArray(K)?K:[])}catch{h([])}finally{Z(!1),ft(!0)}}},[]);async function qt(){if(Ye)return;const D=Me.trim();if(!D){ye(r("teams.urlRequired","请输入地址 URL"));return}try{new URL(D)}catch{ye(r("teams.badUrl","URL 无效(需含 http(s)://)"));return}ye(""),sa(!0);try{const V=await window.cicy.localTeams.add({base_url:D,name:je.trim(),failIfExists:!0});if(!V||V.ok===!1){ye((V==null?void 0:V.error)==="exists"?r("teams.urlExists","该地址已存在"):wi((V==null?void 0:V.error)||"add failed"));return}await St(),se(""),ve(""),Rt(!1)}catch(V){ye(wi((V==null?void 0:V.message)||String(V)))}finally{sa(!1)}}const ie=v.useCallback(async(D,V)=>{var et,tt;if(!((tt=(et=window.cicy)==null?void 0:et.localTeams)!=null&&tt.update))return{ok:!1,error:"no_bridge"};let K;try{K=await window.cicy.localTeams.update(D,{name:String(V||"").trim()||r("localTeams.unnamed","未命名")})}catch($t){K={ok:!1,error:($t==null?void 0:$t.message)||String($t)}}return await St(),K||{ok:!1,error:"no_result"}},[St]);v.useEffect(()=>{let D,V=!1;const K=3e4,et=12e4,tt=async()=>{var Ze,ze,xe;try{await((xe=(ze=(Ze=window.cicy)==null?void 0:Ze.localTeams)==null?void 0:ze.syncCloud)==null?void 0:xe.call(ze))}catch{}await Promise.all([St(),R(),ne()])},$t=()=>{if(V)return;const Ze=document.visibilityState==="visible";D=setTimeout(async()=>{document.visibilityState==="visible"?await tt():await St(),$t()},Ze?K:et)};tt(),$t();const Et=()=>{document.visibilityState==="visible"&&tt()};return document.addEventListener("visibilitychange",Et),window.addEventListener("focus",Et),()=>{V=!0,clearTimeout(D),document.removeEventListener("visibilitychange",Et),window.removeEventListener("focus",Et)}},[St,R]),v.useEffect(()=>{var V,K;if(!((K=(V=window.cicy)==null?void 0:V.localTeams)!=null&&K.onWebviewRelay))return;const D=window.cicy.localTeams.onWebviewRelay(async({reqId:et,msg:tt})=>{let $t={ok:!1,error:"unknown relay type"};try{(tt==null?void 0:tt.type)==="localTeams:add"?$t=await window.cicy.localTeams.add(tt.spec||{}):(tt==null?void 0:tt.type)==="localTeams:remove"?$t=await window.cicy.localTeams.remove(tt.id):(tt==null?void 0:tt.type)==="localTeams:update"?$t=await window.cicy.localTeams.update(tt.id,tt.patch||{}):(tt==null?void 0:tt.type)==="localTeams:upgrade"?$t=await window.cicy.localTeams.upgrade(tt.id):(tt==null?void 0:tt.type)==="localTeams:list"&&($t={ok:!0,teams:await window.cicy.localTeams.list({refresh:!0})}),St()}catch(Et){$t={ok:!1,error:(Et==null?void 0:Et.message)||String(Et)}}try{window.cicy.localTeams.replyWebviewRelay(et,$t)}catch{}});return()=>{try{D==null||D()}catch{}}},[St]);const g=v.useCallback(async D=>{var V,K;if((K=(V=window.cicy)==null?void 0:V.localTeams)!=null&&K.open)try{await window.cicy.localTeams.open(D)}catch{}},[]);v.useEffect(()=>{var V,K;if(An(jn)){m(!1);return}if(!((K=(V=window.cicy)==null?void 0:V.auth)!=null&&K.getSaved)){m(!1);return}let D=!1;return(async()=>{try{const et=await window.cicy.auth.getSaved();if(D)return;if(et!=null&&et.token){try{localStorage.setItem(jn,et.token)}catch{}if(d(et.token),et.accessToken){try{localStorage.setItem(Ru,et.accessToken)}catch{}M(et.accessToken)}if(et.userId){try{localStorage.setItem(Si,String(et.userId))}catch{}Y(String(et.userId))}}}catch{}finally{D||m(!1)}})(),()=>{D=!0}},[]),v.useEffect(()=>{var D,V;if((V=(D=window.cicy)==null?void 0:D.auth)!=null&&V.onComplete)return window.cicy.auth.onComplete(K=>{if($(!1),xt(!1),K!=null&&K.error){gt(wi(K.error));return}if(K!=null&&K.token){zt.current=!1,nt("");try{localStorage.setItem(jn,K.token)}catch{}d(K.token);try{localStorage.removeItem(ay)}catch{}if(K.accessToken){try{localStorage.setItem(Ru,K.accessToken)}catch{}M(K.accessToken)}if(K.userId){try{localStorage.setItem(Si,String(K.userId))}catch{}Y(String(K.userId))}gt(""),ht(K.reused?r("auth.welcomeBack","已恢复你之前的登录"):r("auth.loginSuccess","登录成功")),setTimeout(()=>ht(""),3e3)}})},[]);function X(){var D,V,K;try{localStorage.removeItem(jn),localStorage.removeItem(Ru),localStorage.removeItem(Si)}catch{}try{(K=(V=(D=window.cicy)==null?void 0:D.auth)==null?void 0:V.logout)==null||K.call(V)}catch{}d(null),M(null),Y(null),jt(null),kt(null),gt(""),nt("")}if(s===void 0)return c.jsxs("div",{className:"shell","data-id":"TermsCheckingSplash",children:[c.jsx("div",{className:"glow","aria-hidden":!0}),c.jsxs("div",{className:"card",children:[c.jsx(_m,{}),c.jsx("div",{className:"spinner-row",children:c.jsx(ca,{})})]})]});if(!s)return c.jsx(Dm,{onAgree:()=>b(!0)});if(!S&&T)return c.jsxs("div",{className:"shell","data-id":"AuthRestoringSplash",children:[c.jsx("div",{className:"glow","aria-hidden":!0}),c.jsxs("div",{className:"card",children:[c.jsx(_m,{}),c.jsxs("div",{className:"spinner-row",children:[c.jsx(ca,{}),c.jsx("span",{children:r("auth.restoring","正在恢复登录…")})]})]})]});const I=(_t||[]).find(D=>vm(D.base_url))||null,P=I&&I.cloud_team_id?(bt||[]).find(D=>String(D.teamId||D.id)===String(I.cloud_team_id)):null,rt=D=>{if(!D)return null;const V=(bt||[]).find(K=>String(K.teamId||K.id)===String(D));return V&&V.code||null},mt=(_t||[]).filter(D=>no(D.base_url)),Mt=(_t||[]).filter(D=>!no(D.base_url)&&!vm(D.base_url)),Ee=mt.length+(I?1:0),oa=Mt.length,Ta=(bt||[]).filter(D=>!D.is_local&&D.kind!=="local"&&(D.kind==="private"||D.team_kind==="personal")),It=Ta.length,Se=Ge==="all"||Ge==="local",Da=Ge==="all"||Ge==="custom",Ca=Ge==="all"||Ge==="cloud",xl=_t===null||bt===null;return c.jsxs("div",{className:"shell shell--app",children:[c.jsx("div",{className:"glow glow--app","aria-hidden":!0}),c.jsxs("div",{className:"shell__left",children:[c.jsx(ry,{me:Ct,welcome:L,onLogout:X,guest:!S&&B,onLogin:F,mitmTeam:mt.length>0?mt[0]:null}),c.jsx(gy,{}),c.jsxs("main",{className:"main",children:[c.jsxs("div",{className:"app__tabsrow",children:[c.jsx("div",{className:"app__tabs",children:[{k:"all",label:r("teamFilter.all","全部"),n:Ee+oa+It},{k:"local",label:r("teamFilter.local","本地"),n:Ee},{k:"cloud",label:r("teamFilter.cloud","私有云"),n:It},{k:"custom",label:r("teamFilter.custom","自定义"),n:oa}].filter(({k:D})=>D!=="cloud"||S).map(({k:D,label:V,n:K})=>c.jsxs("button",{type:"button",className:`app__tab ${Ge===D?"is-active":""}`,onClick:()=>Qe(D),children:[V,c.jsx("span",{className:"app__tab-count",children:K})]},D))}),c.jsxs("div",{"data-id":"AddTeamWrap",style:{position:"relative"},children:[c.jsxs("button",{type:"button","data-id":"AddTeamButton",className:"app__add-team",title:r("teams.addHint","添加团队"),onClick:()=>ke(D=>!D),children:["+ ",r("teams.add","新加团队")]}),Zt&&c.jsxs(c.Fragment,{children:[c.jsx("div",{onClick:()=>ke(!1),style:{position:"fixed",inset:0,zIndex:40}}),c.jsxs("div",{"data-id":"AddTeamMenu",role:"menu",style:{position:"absolute",top:"calc(100% + 6px)",right:0,zIndex:41,minWidth:240,background:"var(--card, #1b1d22)",border:"1px solid var(--border, #2c2f36)",borderRadius:10,boxShadow:"0 10px 30px rgba(0,0,0,.45)",overflow:"hidden"},children:[c.jsxs("button",{type:"button","data-id":"AddTeamMenu-custom",className:"bcard__menu-item",style:{display:"block",width:"100%",textAlign:"left",padding:"11px 14px",border:"none",background:"transparent",cursor:"pointer",color:"inherit"},onClick:()=>{ke(!1),ye(""),Rt(!0)},children:[c.jsx("div",{style:{fontSize:13,fontWeight:600},children:r("teams.addCustom","自定义团队")}),c.jsx("div",{style:{fontSize:11,opacity:.6,marginTop:2},children:r("teams.addCustomSub","手动输入地址和名称(只存本地)")})]}),S&&c.jsxs("button",{type:"button","data-id":"AddTeamMenu-private",className:"bcard__menu-item",style:{display:"block",width:"100%",textAlign:"left",padding:"11px 14px",border:"none",borderTop:"1px solid var(--border, #2c2f36)",background:"transparent",cursor:"pointer",color:"inherit"},onClick:()=>{ke(!1),Em("?tab=private")},children:[c.jsx("div",{style:{fontSize:13,fontWeight:600},children:r("teams.addPrivate","私有云团队")}),c.jsx("div",{style:{fontSize:11,opacity:.6,marginTop:2},children:r("teams.addPrivateSub","去云端团队中心添加")})]})]})]})]})]}),J&&c.jsx("div",{"data-id":"CustomTeamModal",style:{position:"fixed",inset:0,zIndex:60,display:"flex",alignItems:"center",justifyContent:"center",background:"rgba(0,0,0,.5)"},onMouseDown:D=>{!Ye&&D.target===D.currentTarget&&Rt(!1)},children:c.jsxs("div",{onClick:D=>D.stopPropagation(),style:{width:400,maxWidth:"92vw",background:"var(--card, #1b1d22)",border:"1px solid var(--border, #2c2f36)",borderRadius:14,padding:22,boxShadow:"0 20px 60px rgba(0,0,0,.5)"},children:[c.jsx("div",{style:{fontSize:16,fontWeight:700,marginBottom:4},children:r("teams.customTitle","添加自定义团队")}),c.jsx("div",{style:{fontSize:12,opacity:.6,marginBottom:16},children:r("teams.customSub","连接到一个已有的 cicy-code 地址")}),c.jsx("label",{style:{display:"block",fontSize:12,opacity:.75,marginBottom:6},children:r("teams.customNameLabel","名称")}),c.jsx("input",{"data-id":"CustomTeamModal-title",className:"login-email-input",style:{width:"100%",marginBottom:14},value:je,onChange:D=>se(D.target.value),placeholder:r("teams.customNamePlaceholder","我的团队"),spellCheck:!1,autoFocus:!0}),c.jsx("label",{style:{display:"block",fontSize:12,opacity:.75,marginBottom:6},children:r("teams.customUrlLabel","地址 URL")}),c.jsx("input",{"data-id":"CustomTeamModal-url",className:"login-email-input",style:{width:"100%",marginBottom:6},value:Me,onChange:D=>ve(D.target.value),placeholder:"https://example.com:8008",spellCheck:!1,onKeyDown:D=>{D.key==="Enter"&&qt()}}),Le&&c.jsx("div",{className:"error",style:{marginTop:10},children:Le}),c.jsxs("div",{className:"modal-actions",children:[c.jsx("button",{type:"button",className:"btn-ghost","data-id":"CustomTeamModal-cancel",disabled:Ye,onClick:()=>Rt(!1),children:r("common.cancel","取消")}),c.jsx("button",{type:"button",className:"btn-primary","data-id":"CustomTeamModal-submit",disabled:Ye,onClick:qt,children:Ye?r("teams.adding","添加中…"):r("teams.addAction","添加")})]})]})}),q&&c.jsxs("div",{className:"error",style:{marginBottom:12},children:[r("common.cloud","云端"),": ",q,c.jsx("button",{className:"btn-ghost",style:{marginLeft:8},onClick:()=>Pe(S||j,k),children:r("common.retry","重试")})]}),c.jsxs("div",{className:"app__grid",children:[xl&&[0,1,2].map(D=>c.jsx(by,{},"skc"+D)),!xl&&Se&&mt.map(D=>c.jsx(bm,{team:D,cloudCode:rt(D.cloud_team_id),onOpen:()=>g(D.id),onRename:ie,onRefresh:St},"local:"+D.id)),!xl&&Se&&c.jsx(py,{dockerTeam:I,onOpen:async()=>{var D,V,K;try{const et=await((K=(V=(D=window.cicy)==null?void 0:D.docker)==null?void 0:V.appOpen)==null?void 0:K.call(V));et!=null&&et.ok||Tt.show({id:"docker-open",status:"error",ttl:6e3,message:r("docker.openNoToken","服务还没就绪,稍等几秒再点「打开」(或用卡片菜单「重启」)。")})}catch(et){console.warn("[DockerCard] open",et)}},cloudTitle:P==null?void 0:P.title,cloudCode:P==null?void 0:P.code,onRename:I!=null&&I.cloud_team_id?(D=>it(I.cloud_team_id,D)):void 0,onRefresh:St}),!xl&&Da&&Mt.map(D=>c.jsx(bm,{team:D,cloudCode:rt(D.cloud_team_id),onOpen:()=>g(D.id),onRename:ie,onRefresh:St},"custom:"+D.id)),!xl&&Ca&&Ta.map(D=>c.jsx(yy,{team:D,onOpen:()=>{var K,et,tt;const V=D.kind==="private"?D.host_url:D.workspace_url||D.workspace_direct_url;V&&((tt=(et=(K=window.cicy)==null?void 0:K.tabs)==null?void 0:et.open)==null||tt.call(et,V,D.name||D.title||"",vt[D.id]||"",!0,D.id))},avatar:vt[D.id]||"",onAvatar:ne,onRename:it,onEditUrl:at,onDelete:ut},"cloud:"+D.id))]}),!Jt&&!q&&bt&&bt.length===0&&!(_t!=null&&_t.length)&&c.jsx("div",{className:"empty",style:{marginTop:14},children:r("teams.emptyHint","还没有团队 — 安装本地 cicy-code 起一个本地 team,或在云端创建。")})]})]}),c.jsx(iy,{}),c.jsx(uy,{}),c.jsx(hy,{})]})}function sy({onClose:s}){const[b,S]=v.useState(null),[d,j]=v.useState(""),[M,k]=v.useState(!1),[Y,T]=v.useState(""),m=typeof window<"u"&&window.cicy&&window.cicy.trustedOrigins||null,B=v.useCallback(async()=>{try{S(m&&await m.list()||[])}catch{S([])}},[m]);v.useEffect(()=>{B()},[B]);const E=async()=>{const $=d.trim();if(!(!$||M||!m)){k(!0),T("");try{const Q=await m.add($);Q&&Q.ok===!1?T(Q.error||r("trustedSites.addFailed","添加失败")):(j(""),S(Q&&Q.origins||await m.list()))}catch(Q){T(String(Q&&Q.message||Q))}finally{k(!1)}}},F=async $=>{if(!(M||!m)){k(!0),T("");try{const Q=await m.remove($);Q&&Q.ok===!1?T(Q.error||r("trustedSites.removeFailed","删除失败")):S(Q&&Q.origins||await m.list())}catch(Q){T(String(Q&&Q.message||Q))}finally{k(!1)}}},H={overlay:{position:"fixed",inset:0,zIndex:2e3,display:"flex",alignItems:"center",justifyContent:"center",background:"rgba(0,0,0,.62)",backdropFilter:"blur(3px)"},card:{width:560,maxWidth:"94vw",maxHeight:"82vh",display:"flex",flexDirection:"column",background:"#101012",border:"1px solid rgba(255,255,255,.09)",borderRadius:16,boxShadow:"0 24px 64px rgba(0,0,0,.55)",overflow:"hidden",color:"#e4e4e7"},head:{display:"flex",alignItems:"center",gap:8,padding:"14px 16px",borderBottom:"1px solid rgba(255,255,255,.06)"},title:{margin:0,fontSize:15,fontWeight:600,flex:1},x:{background:"transparent",border:"none",color:"#a1a1aa",fontSize:16,cursor:"pointer",lineHeight:1,padding:4},warn:{margin:"14px 16px 0",padding:"10px 12px",fontSize:12.5,lineHeight:1.55,color:"#fca5a5",background:"rgba(239,68,68,.08)",border:"1px solid rgba(239,68,68,.25)",borderRadius:10},addRow:{display:"flex",gap:8,padding:"12px 16px 4px"},input:{flex:1,minWidth:0,background:"#161618",border:"1px solid rgba(255,255,255,.1)",borderRadius:9,padding:"9px 11px",color:"#e4e4e7",fontSize:13,outline:"none"},addBtn:{background:"rgba(255,255,255,.1)",border:"none",borderRadius:9,padding:"0 16px",color:"#fff",fontSize:13,fontWeight:500,cursor:"pointer"},err:{margin:"6px 16px 0",fontSize:12,color:"#fca5a5"},listWrap:{margin:"10px 16px 16px",border:"1px solid rgba(255,255,255,.07)",borderRadius:10,overflow:"auto",flex:1,minHeight:80},row:{display:"flex",alignItems:"center",gap:10,padding:"9px 12px",borderTop:"1px solid rgba(255,255,255,.05)"},host:$=>({flex:1,fontFamily:"ui-monospace,SFMono-Regular,Menlo,monospace",fontSize:13,color:$?"#71717a":"#e4e4e7",wordBreak:"break-all"}),tag:{fontSize:11,color:"#71717a",background:"rgba(255,255,255,.05)",borderRadius:6,padding:"2px 7px"},rm:{background:"transparent",border:"none",color:"#a1a1aa",fontSize:12,cursor:"pointer",padding:"3px 6px",borderRadius:6},muted:{padding:"16px",textAlign:"center",color:"#71717a",fontSize:12.5}};return Sa.createPortal(c.jsx("div",{style:H.overlay,onMouseDown:$=>{$.target===$.currentTarget&&s()},"data-id":"TrustedSitesModal",children:c.jsxs("div",{style:H.card,onClick:$=>$.stopPropagation(),children:[c.jsxs("div",{style:H.head,children:[c.jsx("h2",{style:H.title,children:r("trustedSites.title","受信任站点")}),c.jsx("button",{type:"button",style:H.x,onClick:s,"aria-label":"close",children:"✕"})]}),c.jsx("div",{style:H.warn,children:r("trustedSites.warn","⚠ 列表中的站点可以在你的电脑上执行命令(exec)。只添加你完全信任的地址。")}),c.jsxs("div",{style:H.addRow,children:[c.jsx("input",{"data-id":"trusted-sites-input",style:H.input,value:d,onChange:$=>j($.target.value),onKeyDown:$=>{$.key==="Enter"&&E()},placeholder:r("trustedSites.placeholder","添加站点,如 app.cicy-ai.com 或 my-cloud.example.org")}),c.jsx("button",{type:"button","data-id":"trusted-sites-add",style:{...H.addBtn,opacity:M||!d.trim()?.5:1},onClick:E,disabled:M||!d.trim(),children:r("trustedSites.add","添加")})]}),Y&&c.jsx("div",{style:H.err,children:Y}),c.jsx("div",{style:H.listWrap,children:b===null?c.jsx("div",{style:H.muted,children:r("trustedSites.loading","加载中…")}):b.length===0?c.jsx("div",{style:H.muted,children:r("trustedSites.empty","暂无")}):b.map($=>c.jsxs("div",{style:H.row,"data-id":"trusted-sites-row",children:[c.jsx("span",{style:H.host($.builtin),children:$.host}),$.builtin?c.jsx("span",{style:H.tag,children:r("trustedSites.builtin","系统")}):c.jsx("button",{type:"button",style:H.rm,onClick:()=>F($.host),disabled:M,children:r("trustedSites.remove","删除")})]},$.host))})]})}),document.body)}function oy({onClose:s}){const[b,S]=v.useState(null),[d,j]=v.useState(""),[M,k]=v.useState(""),[Y,T]=v.useState(!1),m=typeof window<"u"&&window.cicy&&window.cicy.rpcAudit||null,B=v.useCallback(async()=>{T(!0),j("");try{const L=m&&await m.tail(400);!L||L.ok===!1?(j(L&&L.error||r("audit.loadFailed","读取失败")),S([])):(S(L.entries||[]),k(L.path||""))}catch(L){j(String(L&&L.message||L)),S([])}finally{T(!1)}},[m]);v.useEffect(()=>{B()},[B]);const[E,F]=v.useState("all"),[H,$]=v.useState(""),Q=L=>{try{return new Date(L).toLocaleString()}catch{return L||""}},yt=L=>{if(L.kind==="auth"){const ht=/deny/.test(L.decision||"");return{text:L.decision||"auth",color:ht?"#fca5a5":"#86efac",bg:ht?"rgba(239,68,68,.14)":"rgba(34,197,94,.14)"}}if(L.kind==="rpc"){const ht=L.ok!==!1&&!L.error;return{text:ht?"ok":"err",color:ht?"#86efac":"#fca5a5",bg:ht?"rgba(34,197,94,.14)":"rgba(239,68,68,.14)"}}return{text:L.kind||"log",color:"#a1a1aa",bg:"rgba(255,255,255,.06)"}},Nt=L=>L.kind==="auth"?`${L.gate||""}${L.decision?" · "+L.decision:""}`:L.kind==="rpc"?`${L.tool||""}${L.dangerous?" ⚠":""}`:L.kind||"",ce=L=>L.error||L.args||(L.kind==="rpc"?L.channel:"")||"",ot=b||[],Lt=H.trim().toLowerCase(),ct=ot.filter(L=>E!=="all"&&L.kind!==E?!1:Lt?[L.origin,L.host,L.tool,L.gate,L.decision,L.channel,L.args,L.error,L.kind].filter(Boolean).join(" ").toLowerCase().includes(Lt):!0),xt="186px 104px minmax(160px,1.1fr) minmax(150px,1.1fr) minmax(220px,1.8fr)",G={overlay:{position:"fixed",inset:0,zIndex:2e3,display:"flex",alignItems:"center",justifyContent:"center",background:"rgba(0,0,0,.66)",backdropFilter:"blur(4px)"},card:{width:"96vw",height:"92vh",maxWidth:1480,display:"flex",flexDirection:"column",background:"#0d0d0f",border:"1px solid rgba(255,255,255,.09)",borderRadius:18,boxShadow:"0 32px 80px rgba(0,0,0,.6)",overflow:"hidden",color:"#e4e4e7"},head:{display:"flex",alignItems:"center",gap:14,padding:"20px 24px",borderBottom:"1px solid rgba(255,255,255,.07)"},titleWrap:{flex:1,minWidth:0},title:{margin:0,fontSize:21,fontWeight:650,letterSpacing:.2},subtitle:{margin:"3px 0 0",fontSize:12.5,color:"#71717a",fontFamily:"ui-monospace,SFMono-Regular,Menlo,monospace",wordBreak:"break-all"},count:{fontSize:12.5,color:"#a1a1aa",whiteSpace:"nowrap"},refresh:{background:"rgba(255,255,255,.1)",border:"none",borderRadius:9,padding:"9px 16px",color:"#fff",fontSize:13,fontWeight:500,cursor:"pointer"},x:{background:"transparent",border:"none",color:"#a1a1aa",fontSize:20,cursor:"pointer",lineHeight:1,padding:6},toolbar:{display:"flex",alignItems:"center",gap:10,padding:"14px 24px",borderBottom:"1px solid rgba(255,255,255,.05)"},chips:{display:"flex",gap:6},chip:L=>({background:L?"rgba(255,255,255,.14)":"transparent",border:"1px solid rgba(255,255,255,.12)",borderRadius:999,padding:"6px 16px",color:L?"#fff":"#a1a1aa",fontSize:13,cursor:"pointer"}),search:{flex:1,minWidth:0,background:"#161618",border:"1px solid rgba(255,255,255,.1)",borderRadius:10,padding:"10px 14px",color:"#e4e4e7",fontSize:13.5,outline:"none"},err:{margin:"10px 24px 0",fontSize:12.5,color:"#fca5a5"},tableWrap:{flex:1,overflow:"auto",margin:"0"},theadRow:{position:"sticky",top:0,zIndex:1,display:"grid",gridTemplateColumns:xt,gap:16,padding:"12px 24px",background:"#141417",borderBottom:"1px solid rgba(255,255,255,.08)",fontSize:11.5,letterSpacing:.6,textTransform:"uppercase",color:"#71717a",fontWeight:600},row:{display:"grid",gridTemplateColumns:xt,gap:16,padding:"13px 24px",borderBottom:"1px solid rgba(255,255,255,.045)",alignItems:"center"},time:{fontSize:12.5,color:"#a1a1aa",fontFamily:"ui-monospace,SFMono-Regular,Menlo,monospace",whiteSpace:"nowrap"},badge:L=>({justifySelf:"start",fontSize:11.5,color:L.color,background:L.bg,borderRadius:7,padding:"3px 10px",whiteSpace:"nowrap",fontWeight:500}),cell:{fontSize:13,color:"#d4d4d8",fontFamily:"ui-monospace,SFMono-Regular,Menlo,monospace",wordBreak:"break-all"},detail:{fontSize:12.5,color:"#8b8b93",wordBreak:"break-all"},muted:{padding:"60px 24px",textAlign:"center",color:"#71717a",fontSize:14}},gt=L=>c.jsx("div",{children:L});return Sa.createPortal(c.jsx("div",{style:G.overlay,onMouseDown:L=>{L.target===L.currentTarget&&s()},"data-id":"AuditLogModal",children:c.jsxs("div",{style:G.card,onClick:L=>L.stopPropagation(),children:[c.jsxs("div",{style:G.head,children:[c.jsxs("div",{style:G.titleWrap,children:[c.jsx("h2",{style:G.title,children:r("audit.title","审计日志")}),M&&c.jsx("p",{style:G.subtitle,children:M})]}),c.jsxs("span",{style:G.count,children:[r("audit.count","共")," ",ct.length,E!=="all"||Lt?` / ${ot.length}`:""]}),c.jsx("button",{type:"button","data-id":"audit-refresh",style:{...G.refresh,opacity:Y?.5:1},onClick:B,disabled:Y,children:r("audit.refresh","刷新")}),c.jsx("button",{type:"button",style:G.x,onClick:s,"aria-label":"close",children:"✕"})]}),c.jsxs("div",{style:G.toolbar,children:[c.jsxs("div",{style:G.chips,children:[c.jsx("button",{type:"button",style:G.chip(E==="all"),onClick:()=>F("all"),children:r("audit.all","全部")}),c.jsx("button",{type:"button",style:G.chip(E==="rpc"),onClick:()=>F("rpc"),children:r("audit.rpc","RPC 调用")}),c.jsx("button",{type:"button",style:G.chip(E==="auth"),onClick:()=>F("auth"),children:r("audit.auth","授权决定")})]}),c.jsx("input",{"data-id":"audit-search",style:G.search,value:H,onChange:L=>$(L.target.value),placeholder:r("audit.search","搜索来源 / 工具 / 命令…")})]}),d&&c.jsx("div",{style:G.err,children:d}),c.jsxs("div",{style:G.tableWrap,children:[c.jsxs("div",{style:G.theadRow,children:[gt(r("audit.colTime","时间")),gt(r("audit.colType","类型")),gt(r("audit.colSource","来源")),gt(r("audit.colOp","操作")),gt(r("audit.colDetail","详情"))]}),b===null?c.jsx("div",{style:G.muted,children:r("audit.loading","加载中…")}):ct.length===0?c.jsx("div",{style:G.muted,children:ot.length===0?r("audit.empty","暂无审计记录"):r("audit.noMatch","无匹配记录")}):ct.map((L,ht)=>{const Ct=yt(L);return c.jsxs("div",{style:G.row,"data-id":"audit-row",children:[c.jsx("span",{style:G.time,children:Q(L.ts)}),c.jsx("span",{style:G.badge(Ct),children:Ct.text}),c.jsx("span",{style:G.cell,children:L.origin||L.host||"—"}),c.jsx("span",{style:G.cell,children:Nt(L)||"—"}),c.jsx("span",{style:G.detail,children:ce(L)||"—"})]},ht)})]})]})}),document.body)}function ry({me:s,welcome:b,onLogout:S,mitmTeam:d,guest:j=!1,onLogin:M}){const k=(s==null?void 0:s.display_name)||(s==null?void 0:s.username)||"…",Y=k.slice(0,1).toUpperCase(),[T,m]=v.useState(!1),[B,E]=v.useState("");v.useEffect(()=>{var bt,kt;if(!((kt=(bt=window.cicy)==null?void 0:bt.sidecar)!=null&&kt.tunnelStatus))return;let ht=!1;const Ct=()=>window.cicy.sidecar.tunnelStatus().then(Jt=>{if(ht||!(Jt!=null&&Jt.ok))return;let C=Jt.tier;if(!C){const q=Number(Jt.tunnelLimit??Jt.tunnel_limit);Number.isFinite(q)&&(C=q<0?"enterprise":q>0?"team":"personal")}C&&E(String(C))}).catch(()=>{});Ct();const jt=setInterval(Ct,6e4);return()=>{ht=!0,clearInterval(jt)}},[]);const[F,H]=v.useState(!1),[$,Q]=v.useState(!1),[yt,Nt]=v.useState(!1),[ce,ot]=v.useState(!1),[Lt,ct]=v.useState(""),xt=v.useRef(null);v.useEffect(()=>{var Ct,jt,bt;let ht=!0;return(bt=(jt=(Ct=window.cicy)==null?void 0:Ct.app)==null?void 0:jt.getVersion)==null||bt.call(jt).then(kt=>{ht&&ct(typeof kt=="string"?kt:String((kt==null?void 0:kt.desktop)||""))}).catch(()=>{}),()=>{ht=!1}},[]),v.useEffect(()=>{if(!T)return;const ht=Ct=>{xt.current&&!xt.current.contains(Ct.target)&&m(!1)};return document.addEventListener("mousedown",ht),()=>document.removeEventListener("mousedown",ht)},[T]);const G=async()=>{var Ct,jt;const ht=String((s==null?void 0:s.email)||"").trim();if(ht)try{(jt=(Ct=window.cicy)==null?void 0:Ct.clipboard)!=null&&jt.write?await window.cicy.clipboard.write(ht):await navigator.clipboard.writeText(ht),m(!1),Tt.show({message:r("userMenu.emailCopied","邮箱已复制"),status:"done",ttl:2500})}catch{Tt.show({message:r("userMenu.emailCopyFailed","邮箱复制失败"),status:"error",ttl:3500})}},gt=async()=>{var ht,Ct,jt;m(!1),ot(!0),Tt.show({id:"app-update",message:r("updateBanner.checking","正在检查更新…"),status:"running"});try{const bt=await((jt=(Ct=(ht=window.cicy)==null?void 0:ht.app)==null?void 0:Ct.checkUpdate)==null?void 0:jt.call(Ct));(bt==null?void 0:bt.status)==="available"?Tt.show({id:"app-update",message:r("updateBanner.available","发现新版本 v{{v}}",{v:bt.version}),status:"done",ttl:4e3}):(bt==null?void 0:bt.status)==="up-to-date"?Tt.show({id:"app-update",message:r("updateBanner.upToDate","已是最新版本 v{{v}}",{v:bt.version||bt.current}),status:"done",ttl:3e3}):Tt.show({id:"app-update",message:r("updateBanner.error","更新失败")+(bt!=null&&bt.error?`:${bt.error}`:""),status:"error",ttl:5e3})}catch(bt){Tt.show({id:"app-update",message:bt.message,status:"error",ttl:5e3})}finally{ot(!1)}},L=(()=>{const ht=String(B||"").toLowerCase().trim();return ht?{personal:r("plan.personal","个人版"),team:r("plan.team","团队版"),enterprise:r("plan.enterprise","企业版")}[ht]||ht:""})();return c.jsxs(c.Fragment,{children:[c.jsx("header",{className:"topbar",children:c.jsxs("div",{className:"user-chip","data-id":"UserChip",ref:xt,children:[b&&c.jsx("span",{className:"welcome",children:b}),L&&c.jsx("span",{"data-id":"UserChip-plan",className:"plan-badge",title:r("plan.hint","当前账号版本"),style:{fontSize:11,fontWeight:600,lineHeight:1.6,padding:"2px 9px",borderRadius:999,whiteSpace:"nowrap",background:"var(--accent-soft, rgba(120,140,255,.16))",color:"var(--accent, #9db0ff)"},children:L}),j?c.jsxs("button",{type:"button","data-id":"UserChip-trigger",className:`user-chip__trigger${T?" is-open":""}`,onClick:()=>m(ht=>!ht),children:[c.jsx("div",{className:"avatar",style:{background:"var(--border, #2c2f36)",color:"var(--muted, #8b8b92)"},children:"?"}),c.jsx("span",{className:"user-name",children:r("auth.localName","本机")}),c.jsx("span",{className:"user-chip__caret","aria-hidden":!0,children:"▾"})]}):s?c.jsxs("button",{type:"button","data-id":"UserChip-trigger",className:`user-chip__trigger${T?" is-open":""}`,onClick:()=>m(ht=>!ht),children:[c.jsx("div",{className:"avatar",children:Y}),c.jsx("span",{className:"user-name",children:k}),c.jsx("span",{className:"user-chip__caret","aria-hidden":!0,children:"▾"})]}):c.jsxs("div",{className:"user-chip__trigger user-chip__trigger--skel","data-id":"UserChip-skeleton","aria-hidden":!0,children:[c.jsx("div",{className:"skel skel--avatar"}),c.jsx("div",{className:"skel skel--name"})]}),T&&c.jsxs("div",{className:"user-chip__menu","data-id":"UserChip-menu",role:"menu",children:[!j&&(s==null?void 0:s.email)&&c.jsx("button",{type:"button","data-id":"UserChip-email-copy",className:"user-chip__menu-item",title:r("userMenu.copyEmail","点击复制邮箱"),onClick:G,style:{overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"},children:s.email}),c.jsx("button",{type:"button","data-id":"UserChip-trusted-sites",className:"user-chip__menu-item",onClick:()=>{m(!1),H(!0)},children:r("trustedSites.menu","受信任站点")}),c.jsx("button",{type:"button","data-id":"UserChip-audit-log",className:"user-chip__menu-item",onClick:()=>{m(!1),Q(!0)},children:r("audit.menu","审计日志")}),c.jsx("button",{type:"button","data-id":"UserChip-terms",className:"user-chip__menu-item",onClick:()=>{m(!1),Nt(!0)},children:r("firstRunTerms.menu","用户协议")}),c.jsx("button",{type:"button","data-id":"UserChip-check-update",className:"user-chip__menu-item",disabled:ce,onClick:gt,children:ce?r("updateBanner.checkingShort","检查中…"):r("updateBanner.checkBtn","检查更新")}),!1,c.jsx("div",{className:"user-chip__menu-sep","aria-hidden":!0}),!j&&c.jsx("button",{type:"button","data-id":"UserChip-logout",className:"user-chip__menu-item is-danger",onClick:()=>{m(!1),S()},children:r("userMenu.logout","退出")}),c.jsxs("div",{className:"user-chip__menu-version","data-id":"UserChip-version",children:["CiCy Desktop ",Lt?`v${Lt}`:"…"]})]})]})}),F&&c.jsx(sy,{onClose:()=>H(!1)}),$&&c.jsx(oy,{onClose:()=>Q(!1)}),yt&&c.jsx(Dm,{onClose:()=>Nt(!1)})]})}function Dm({onAgree:s,onClose:b}){var $;const[S,d]=v.useState(!1),[j,M]=v.useState(!1),k=((($=window.cicyI18n)==null?void 0:$.locale)||"en").startsWith("zh")?"zh-CN":"en",Y=(Q,yt)=>r(`firstRunTerms.${Q}`,yt),T=!!b,m=v.useMemo(()=>ty(Ip(k)),[k]),B=Q=>{const yt=Q.currentTarget;yt.scrollHeight-yt.scrollTop-yt.clientHeight<24&&d(!0)},E=v.useRef(null);v.useEffect(()=>{const Q=E.current;Q&&Q.scrollHeight<=Q.clientHeight+24&&d(!0)},[]);const F=async()=>{var Q,yt,Nt;if(!(j||!S)){M(!0);try{await((Nt=(yt=(Q=window.cicy)==null?void 0:Q.terms)==null?void 0:yt.agree)==null?void 0:Nt.call(yt,Am)),s==null||s()}catch{s==null||s()}}},H=()=>{var Q,yt,Nt;try{(Nt=(yt=(Q=window.cicy)==null?void 0:Q.terms)==null?void 0:yt.decline)==null||Nt.call(yt)}catch{}};return c.jsxs("div",{className:T?"terms-gate terms-gate--review":"shell terms-gate","data-id":"FirstRunTermsGate",style:T?{position:"fixed",inset:0,zIndex:1e3,background:"rgba(8,9,14,.72)",backdropFilter:"blur(4px)"}:void 0,onClick:T?Q=>{Q.target===Q.currentTarget&&b()}:void 0,children:[c.jsx("div",{className:"glow","aria-hidden":!0}),c.jsxs("div",{className:"terms-gate__panel",children:[c.jsx("h1",{className:"terms-gate__title","data-id":"FirstRunTermsGate-title",children:Y("title","用户协议与授权说明")}),c.jsx("p",{className:"terms-gate__subtitle",children:Y("subtitle","使用 CiCy Desktop 前,请阅读并同意以下条款")}),c.jsx("div",{className:"terms-gate__body",ref:E,onScroll:B,"data-id":"FirstRunTermsGate-body",children:c.jsx("div",{className:"terms-md","data-id":"FirstRunTermsGate-md",dangerouslySetInnerHTML:{__html:m}})}),T?c.jsx("div",{className:"terms-gate__actions",children:c.jsx("button",{"data-id":"FirstRunTermsGate-close",className:"terms-gate__btn",onClick:b,children:Y("close","关闭")})}):c.jsxs(c.Fragment,{children:[!S&&c.jsx("div",{className:"terms-gate__scrollhint","data-id":"FirstRunTermsGate-scrollhint",children:Y("scrollHint","请阅读至底部以继续")}),c.jsxs("div",{className:"terms-gate__actions",children:[c.jsx("button",{"data-id":"FirstRunTermsGate-decline",className:"terms-gate__btn terms-gate__btn--ghost",onClick:H,children:Y("decline","不同意并退出")}),c.jsx("button",{"data-id":"FirstRunTermsGate-agree",className:"terms-gate__btn",disabled:!S||j,title:S?"":Y("mustAgree","未同意则无法使用本软件。"),onClick:F,children:Y("agree","同意并继续")})]})]})]})]})}const lo=new Set;let ym=0,Qt=null;function zn(){lo.forEach(s=>s(Qt))}const Ot={open({onRetry:s,kind:b,source:S}={}){Qt={status:"running",phase:"install-docker",kind:b||"install",source:S||"op",logs:[],bars:{},minimized:!1,onRetry:s||null,lastAt:Date.now()},zn()},minimize(){Qt&&(Qt={...Qt,minimized:!0},zn())},restore(){Qt&&(Qt={...Qt,minimized:!1},zn())},push(s={}){var k;if(!Qt)return;const b=s.phase==="health"?"container":s.phase||Qt.phase,S={...Qt,phase:b,lastAt:Date.now()},d=Number.isFinite(s.progress),j=b==="install-docker"||b==="image";if(j&&(d||s.dest||s.url)){const Y=((k=Qt.bars)==null?void 0:k[b])||{},T=d?s.progress:s.status==="skip"||s.status==="done"?100:Y.progress;S.bars={...Qt.bars,[b]:{progress:T,received:s.received??Y.received,total:s.total??Y.total,url:s.url||Y.url,dest:s.dest||Y.dest}}}if(!(s.status==="running"&&d&&j)){const Y=Qt.logs[Qt.logs.length-1],T=s.status||"running",m=s.message||"";if(!(Y&&Y.phase===b&&Y.status===T&&Y.message===m)){const B={id:++ym,t:_i(),phase:b,status:T,message:m};S.logs=[...Qt.logs,B]}}Qt=S,zn()},finish({ok:s,message:b,status:S}={}){if(!Qt||Qt.status!=="running")return;const d=S||(s?"done":"error"),j=d==="error"?Qt.phase:"done",M={id:++ym,t:_i(),phase:j,status:d,message:b||(s?"完成":"失败")};Qt={...Qt,status:d,phase:j,minimized:!1,logs:[...Qt.logs,M],lastAt:Date.now()},zn()},close(){Qt=null,zn()}},to=[["install-docker","准备环境"],["image","下载运行环境"],["container","启动服务"],["done","完成"]],dy={"install-docker":"准备",image:"下载",container:"启动",health:"启动",done:"完成",open:"打开"},fy={"install-docker":"Docker Desktop",image:"基础镜像"};function gm(s){return Number.isFinite(s)?s<1024?s+" B":s<1048576?(s/1024).toFixed(0)+" KB":s<1073741824?(s/1048576).toFixed(1)+" MB":(s/1073741824).toFixed(2)+" GB":"?"}function my({phaseKey:s,bar:b}){const S=Number.isFinite(b==null?void 0:b.progress)?Math.max(0,Math.min(100,b.progress)):0,d=S>=100;return c.jsxs("div",{className:"dlbar","data-id":`DockerDrawer-dlbar-${s}`,children:[c.jsxs("div",{className:"dlbar__head",children:[c.jsx("span",{className:"dlbar__name",children:fy[s]||s}),c.jsxs("span",{className:"dlbar__pct",children:[S,"%",b!=null&&b.total?` · ${gm(b.received)} / ${gm(b.total)}`:""]})]}),c.jsx("div",{className:"dlbar__track",children:c.jsx("div",{className:`dlbar__fill${d?" is-done":""}`,style:{width:`${S}%`}})}),(b==null?void 0:b.url)&&c.jsxs("div",{className:"dlbar__url",title:b.url,children:[c.jsx("span",{className:"dlbar__urlk",children:"源"})," ",b.url]}),(b==null?void 0:b.dest)&&c.jsxs("div",{className:"dlbar__url",title:b.dest,children:[c.jsx("span",{className:"dlbar__urlk",children:"存"})," ",b.dest]})]})}function hy(){var T;const[s,b]=v.useState(Qt);v.useEffect(()=>(lo.add(b),()=>{lo.delete(b)}),[]);const S=v.useRef(null);if(v.useEffect(()=>{const m=S.current;m&&(m.scrollTop=m.scrollHeight)},[(T=s==null?void 0:s.logs)==null?void 0:T.length]),!s)return null;const d=s.status==="running",j=s.kind==="open",M=to.findIndex(([m])=>m===s.phase),k=j?[]:["install-docker","image"].filter(m=>{var B;return(B=s.bars)==null?void 0:B[m]}),Y=j?r("docker.openTitle","打开 Docker 团队"):r("docker.setupTitle","安装 Docker cicy-code");if(s.minimized){const m=k.map(E=>{var F;return(F=s.bars[E])==null?void 0:F.progress}).filter(Number.isFinite),B=m.length?Math.round(m.reduce((E,F)=>E+F,0)/m.length):null;return c.jsxs("button",{type:"button",className:`drawer-min drawer-min--${s.status}`,"data-id":"DockerDrawer-restore",onClick:()=>Ot.restore(),children:[c.jsx("span",{className:"drawer-min__spark",children:d?c.jsx(ca,{}):s.status==="done"?"✓":s.status==="reboot"?"⟳":"!"}),c.jsxs("span",{className:"drawer-min__label",children:[Y,B!=null?` · ${B}%`:""]})]})}return c.jsx("div",{className:"drawer-scrim","data-id":"DockerDrawer-scrim",onClick:()=>d?Ot.minimize():Ot.close(),children:c.jsxs("div",{className:"drawer","data-id":"DockerDrawer","data-status":s.status,onClick:m=>m.stopPropagation(),children:[c.jsxs("div",{className:"drawer__head",children:[c.jsxs("div",{className:"drawer__title",children:[c.jsx("span",{className:`drawer__spark drawer__spark--${s.status}`,children:d?c.jsx(ca,{}):s.status==="done"?"✓":s.status==="reboot"?"⟳":"!"}),c.jsxs("div",{children:[c.jsx("div",{className:"drawer__h",children:Y}),c.jsx("div",{className:"drawer__sub",children:"127.0.0.1:8008"})]})]}),c.jsx("div",{className:"drawer__headbtns",children:c.jsx("button",{type:"button",className:"drawer__x","data-id":"DockerDrawer-min",title:r("common.minimize","最小化"),onClick:()=>Ot.minimize(),"aria-label":"minimize",children:"‒"})})]}),!j&&c.jsx("div",{className:"drawer__steps","data-id":"DockerDrawer-steps",children:to.map(([m,B],E)=>{const F=s.status==="done"||M>=0&&E<M,H=E===M&&d,$=s.status==="error"&&E===M;return c.jsxs("div",{className:`drawer__step${H?" is-active":""}${F?" is-done":""}${$?" is-error":""}`,children:[c.jsx("span",{className:"drawer__step-dot",children:F?"✓":$?"!":E+1}),c.jsx("span",{className:"drawer__step-label",children:B}),E<to.length-1&&c.jsx("span",{className:"drawer__step-bar"})]},m)})}),k.length>0&&c.jsx("div",{className:"drawer__dlbars","data-id":"DockerDrawer-dlbars",children:k.map(m=>c.jsx(my,{phaseKey:m,bar:s.bars[m]},m))}),d&&s.logs.length>0&&c.jsxs("div",{className:"drawer__now","data-id":"DockerDrawer-now",children:[c.jsx(ca,{}),c.jsx("span",{children:s.logs[s.logs.length-1].message})]}),c.jsx("div",{className:"drawer__log drawer__log--scroll","data-id":"DockerDrawer-log",ref:S,children:s.logs.length===0?c.jsx("div",{className:"drawer__log-empty",children:r("docker.preparing","准备中…")}):s.logs.map(m=>c.jsxs("div",{className:"drawer__line","data-status":m.status,children:[c.jsx("span",{className:"drawer__t",children:m.t}),c.jsx("span",{className:`drawer__badge drawer__badge--${m.phase}`,children:r(`dockerBadge.${m.phase}`,dy[m.phase]||m.phase)}),c.jsx("span",{className:"drawer__linemsg",children:m.message})]},m.id))}),c.jsx("div",{className:"drawer__foot",children:d?c.jsx(c.Fragment,{children:c.jsx("span",{className:"drawer__foot-status",children:j?r("docker.opening","打开中…"):r("docker.installing2","安装进行中…")})}):s.status==="reboot"?c.jsxs(c.Fragment,{children:[c.jsx("span",{className:"drawer__foot-status is-reboot",children:r("docker.rebootAuto","需重启 Windows(90 秒后自动重启,登录后自动继续)")}),c.jsx("button",{type:"button",className:"drawer__btn is-accent","data-id":"DockerDrawer-reboot-now",onClick:()=>{var m,B,E;return(E=(B=(m=window.cicy)==null?void 0:m.docker)==null?void 0:B.rebootNow)==null?void 0:E.call(B)},children:r("docker.rebootNow","立即重启")}),c.jsx("button",{type:"button",className:"drawer__btn","data-id":"DockerDrawer-reboot-cancel",onClick:()=>{var m,B,E;(E=(B=(m=window.cicy)==null?void 0:m.docker)==null?void 0:B.rebootCancel)==null||E.call(B),Ot.close()},children:r("docker.rebootCancel","取消自动重启")})]}):s.status==="error"?c.jsxs(c.Fragment,{children:[c.jsx("span",{className:"drawer__foot-status is-error",children:j?r("docker.openFailed","打开失败"):r("docker.failed","安装失败")}),s.onRetry&&c.jsx("button",{type:"button",className:"drawer__btn is-accent","data-id":"DockerDrawer-retry",onClick:()=>s.onRetry(),children:r("common.retry","重试")}),c.jsx("button",{type:"button",className:"drawer__btn","data-id":"DockerDrawer-dismiss",onClick:()=>Ot.close(),children:r("common.close","关闭")})]}):c.jsxs(c.Fragment,{children:[c.jsx("span",{className:"drawer__foot-status is-done",children:r("docker.ready","已就绪")}),c.jsx("button",{type:"button",className:"drawer__btn is-accent","data-id":"DockerDrawer-finish",onClick:()=>Ot.close(),children:r("common.done","完成")})]})})]})})}function py({dockerTeam:s,cloudTitle:b,cloudCode:S,onOpen:d,onRename:j,onRefresh:M}){var oe;const[k,Y]=v.useState(null),[T,m]=v.useState(""),[B,E]=v.useState(!1),[F,H]=v.useState(!1),[$,Q]=v.useState(!1),[yt,Nt]=v.useState(!1),[ce,ot]=v.useState([]),[Lt,ct]=v.useState(!1),[xt,G]=v.useState(""),[gt,L]=v.useState(!1),[ht,Ct]=v.useState(""),jt=b||"Docker 团队",bt=R=>{var it;(it=R==null?void 0:R.stopPropagation)==null||it.call(R),Ct(jt),L(!0)},kt=async()=>{L(!1);const R=String(ht||"").trim();if(!(!R||R===jt||!j))try{await j(R),M==null||M()}catch{}},[Jt,C]=v.useState({top:0,left:0}),q=v.useRef(null),nt=v.useRef(null),zt=184,_t="#2496ed",h=v.useCallback(async()=>{var R,it,at;try{const ut=await((at=(it=(R=window.cicy)==null?void 0:R.docker)==null?void 0:it.appStatus)==null?void 0:at.call(it));Y(ut);const St=Date.now()-((Qt==null?void 0:Qt.lastAt)||0)>3e4;ut!=null&&ut.running&&Qt&&Qt.status==="running"&&Qt.kind!=="open"&&St&&Ot.finish({ok:!0,message:"Docker cicy-code 已就绪"})}catch(ut){console.warn("[DockerCard]",ut)}},[]);v.useEffect(()=>{h();const R=setInterval(()=>{T||h()},12e3);return()=>clearInterval(R)},[h,T]);const N=v.useCallback(async()=>{var R,it,at;E(!1),G("");try{const ut=await((at=(it=(R=window.cicy)==null?void 0:R.docker)==null?void 0:it.getPorts)==null?void 0:at.call(it));ot(((ut==null?void 0:ut.ports)||[]).map(String))}catch{ot([])}Nt(!0)},[]),Z=v.useCallback(async()=>{var ut,St,qt,ie,g,X,I,P,rt;const R=new Set,it=[];for(const mt of ce){const Mt=String(mt).trim();if(!Mt)continue;const Ee=Number(Mt);if(!Number.isInteger(Ee)||Ee<1||Ee>65535||Ee===8008||R.has(Ee)){G(r("docker.ports.invalid","有端口无效(1-65535,不能是 8008,不能重复)"));return}R.add(Ee),it.push(Ee)}G(""),ct(!0),Nt(!1),m("recreate"),Ot.open({onRetry:Z});const at=(qt=(St=(ut=window.cicy)==null?void 0:ut.docker)==null?void 0:St.onAppProgress)==null?void 0:qt.call(St,mt=>Ot.push(mt));try{const mt=await((X=(g=(ie=window.cicy)==null?void 0:ie.docker)==null?void 0:g.setPorts)==null?void 0:X.call(g,it));if(Ot.finish({ok:!!(mt!=null&&mt.ok),message:mt!=null&&mt.ok?r("docker.ports.save","保存并重建")+" ✅":(mt==null?void 0:mt.error)||r("docker.opFailed","操作失败")}),mt!=null&&mt.ok)try{const Mt=await((rt=(P=(I=window.cicy)==null?void 0:I.docker)==null?void 0:P.appRedetect)==null?void 0:rt.call(P));Mt&&Y(Mt)}catch{}}catch(mt){Ot.finish({ok:!1,message:mt.message})}finally{try{at&&at()}catch{}ct(!1),m(""),h()}},[ce,h]);v.useEffect(()=>{if(!B)return;const R=at=>{var ut,St;(ut=q.current)!=null&&ut.contains(at.target)||(St=nt.current)!=null&&St.contains(at.target)||E(!1)},it=at=>{at.key==="Escape"&&E(!1)};return document.addEventListener("mousedown",R),document.addEventListener("keydown",it),()=>{document.removeEventListener("mousedown",R),document.removeEventListener("keydown",it)}},[B]);const W=()=>{if(!B&&q.current){const R=q.current.getBoundingClientRect(),it=Math.max(8,Math.min(R.right-zt,window.innerWidth-zt-8));C({top:Math.round(R.bottom+4),left:Math.round(it)})}E(R=>!R)},ft=v.useCallback(async()=>{var it,at,ut,St,qt,ie;m("bootstrap"),Ot.open({onRetry:ft});const R=(ut=(at=(it=window.cicy)==null?void 0:it.docker)==null?void 0:at.onAppProgress)==null?void 0:ut.call(at,g=>Ot.push(g));try{const g=await((ie=(qt=(St=window.cicy)==null?void 0:St.docker)==null?void 0:qt.appBootstrap)==null?void 0:ie.call(qt));(g==null?void 0:g.reason)==="installer_launched"?Ot.finish({status:"reboot",message:r("docker.installerLaunched","已打开 Docker 安装程序——请完成安装(会装 WSL2、可能需重启),装好后点「重试」")}):(g==null?void 0:g.reason)==="wsl_reboot_required"?Ot.finish({status:"reboot",message:r("docker.rebootNeeded","WSL2 已安装,请【重启 Windows】后回来点「重试」继续")}):Ot.finish({ok:!!(g!=null&&g.ok),message:g!=null&&g.ok?r("docker.ready","Docker cicy-code 已就绪"):(g==null?void 0:g.error)||r("docker.failed","安装失败")}),g!=null&&g.ok&&(M==null||M())}catch(g){Ot.finish({ok:!1,message:g.message})}finally{try{R&&R()}catch{}m(""),h()}},[h,M]),vt=v.useCallback(async()=>{var it,at,ut,St,qt,ie;m("repair"),Ot.open({onRetry:vt});const R=(ut=(at=(it=window.cicy)==null?void 0:it.docker)==null?void 0:at.onAppProgress)==null?void 0:ut.call(at,g=>Ot.push(g));try{const g=await((ie=(qt=(St=window.cicy)==null?void 0:St.docker)==null?void 0:qt.appRepairWsl)==null?void 0:ie.call(qt));g!=null&&g.needsReboot?Ot.finish({status:"reboot",message:r("docker.wslNeedReboot","WSL 服务卡死,请【重启 Windows】;重启后打开 CiCy 会自动修复(旧数据已改名备份,不删)。")}):g!=null&&g.ok?(Ot.finish({ok:!0,message:r("docker.wslRepaired","WSL 已修复 ✅")}),M==null||M()):Ot.finish({ok:!1,message:(g==null?void 0:g.error)||r("docker.repairFailed","修复失败")})}catch(g){Ot.finish({ok:!1,message:g.message})}finally{try{R&&R()}catch{}m(""),h()}},[h,M]),Ut=v.useCallback(async()=>{var it,at,ut,St,qt,ie;E(!1),m("upgrade"),Ot.open({onRetry:Ut});const R=(ut=(at=(it=window.cicy)==null?void 0:it.docker)==null?void 0:at.onAppProgress)==null?void 0:ut.call(at,g=>Ot.push(g));try{const g=await((ie=(qt=(St=window.cicy)==null?void 0:St.docker)==null?void 0:qt.appUpgrade)==null?void 0:ie.call(qt));(g==null?void 0:g.reason)==="wsl_reboot_required"?Ot.finish({status:"reboot",message:r("docker.rebootNeeded","WSL2 已安装,请【重启 Windows】后回来点「重试」继续")}):Ot.finish({ok:!!(g!=null&&g.ok),message:g!=null&&g.ok?r("docker.upgraded","已升级到最新"):(g==null?void 0:g.error)||r("docker.upgradeFailed","升级失败")}),g!=null&&g.ok&&(M==null||M())}catch(g){Ot.finish({ok:!1,message:g.message})}finally{try{R&&R()}catch{}m(""),h()}},[h,M]),ne=v.useCallback(async()=>{var it,at,ut,St,qt,ie,g,X,I,P,rt,mt;E(!1),m("update"),Ot.open({onRetry:ne});const R=(ut=(at=(it=window.cicy)==null?void 0:it.docker)==null?void 0:at.onAppProgress)==null?void 0:ut.call(at,Mt=>Ot.push(Mt));try{const Mt=await((ie=(qt=(St=window.cicy)==null?void 0:St.docker)==null?void 0:qt.appUpdate)==null?void 0:ie.call(qt));if(Ot.finish({ok:!!(Mt!=null&&Mt.ok),message:Mt!=null&&Mt.ok?r("docker.updated","cicy-code 已更新到最新"):(Mt==null?void 0:Mt.error)||r("docker.updateFailed","更新失败")}),Mt!=null&&Mt.ok){M==null||M();try{(I=(X=(g=window.cicy)==null?void 0:g.tabs)==null?void 0:X.reloadIfOpen)==null||I.call(X,"http://127.0.0.1:8008",r("docker.teamTab","Docker 团队"))}catch{}try{const Ee=await((mt=(rt=(P=window.cicy)==null?void 0:P.docker)==null?void 0:rt.appRedetect)==null?void 0:mt.call(rt));Ee&&Y(Ee)}catch{}}}catch(Mt){Ot.finish({ok:!1,message:Mt.message})}finally{try{R&&R()}catch{}m(""),h()}},[h,M]),Zt=v.useCallback(async(R,it,at)=>{E(!1),m(R),Tt.show({id:"docker-op",message:r(`docker.${R}ing`,R==="restart"?"重启中…":R==="reload"?"刷新中…":"停止中…"),status:"running"});try{const ut=await it();ut!=null&&ut.ok?Tt.show({id:"docker-op",message:at,status:"done",ttl:2500}):Tt.show({id:"docker-op",message:(ut==null?void 0:ut.error)||r("docker.opFailed","操作失败"),status:"error",ttl:6e3})}catch(ut){Tt.show({id:"docker-op",message:ut.message,status:"error",ttl:6e3})}finally{m(""),h()}},[h]),ke=v.useCallback(async()=>{E(!1),m("authssh"),Tt.show({id:"docker-op",message:r("docker.authorizingHost","授权容器访问 Mac(配置 SSH)…"),status:"running"});try{const R=await window.cicy.docker.appAuthorizeHostSsh();R!=null&&R.ok?Tt.show({id:"docker-op",message:R.verified?r("docker.authorizedHostOk","已授权:容器内 `ssh mac` 可访问 Mac ✅"):r("docker.authorizedHostPartial","公钥已写入 Mac(未验证成功,可在容器内手动 `ssh mac` 试)"),status:R.verified?"done":"error",ttl:5e3}):Tt.show({id:"docker-op",message:(R==null?void 0:R.error)||r("docker.opFailed","操作失败"),status:"error",ttl:6e3})}catch(R){Tt.show({id:"docker-op",message:R.message,status:"error",ttl:6e3})}finally{m(""),h()}},[h]),J=((oe=window.cicy)==null?void 0:oe.platform)||(k==null?void 0:k.platform);if(J!=="win32")return null;const Rt=k?!!k.running:(s==null?void 0:s.status)==="running",je=!!(k!=null&&k.dockerRunning),se=!!(k!=null&&k.installed),Me=!!(k!=null&&k.unknown)&&!Rt&&!je&&!se,ve=!!(k!=null&&k.wslUnmanaged),Ye=!!(k!=null&&k.wslWedged),sa=Rt&&!ve,Le=sa?"ok":Ye||ve||je||se||Me?"warn":"off",ye=!!T;Ye?r("docker.wslWedged","WSL 卡死 · 点「修复 WSL」"):ve?r("docker.wslBrokenRepair","WSL 管理异常 · 点「修复 WSL」重装"):Rt?r("docker.running","运行中"):je?r("docker.notRunning","未启动 · 点「启动」"):se?r("docker.engineDown","Docker 未运行 · 点启动"):Me?r("docker.wslUnresponsive","WSL 未响应 · 点「重试检测」"):r("docker.notInstalled","Docker Desktop 未安装");const Ge=T==="open"?r("docker.opening","打开中…"):T==="probe"?r("docker.probing","检测中…"):ye?r("docker.working","处理中…"):sa?r("localTeams.open","打开"):Ye||ve?r("docker.repairWsl","修复 WSL"):je?r("docker.start","启动"):se?r("docker.startDocker","启动 Docker"):Me?r("docker.retryProbe","重试检测"):r("docker.install","下载安装"),Qe=async()=>{var R,it,at,ut,St,qt,ie,g,X,I,P,rt;if(!ye){if(Ye){vt();return}if(ve){ft();return}if(sa){try{const Mt=await((at=(it=(R=window.cicy)==null?void 0:R.tabs)==null?void 0:it.activateIfOpen)==null?void 0:at.call(it,"http://127.0.0.1:8008"));if(Mt!=null&&Mt.active)return}catch{}m("open");let mt=null;try{mt=await((qt=(St=(ut=window.cicy)==null?void 0:ut.docker)==null?void 0:St.appOpen)==null?void 0:qt.call(St))}catch(Mt){mt={ok:!1,hint:(Mt==null?void 0:Mt.message)||r("docker.openFailed","打开失败"),log:[]}}m(""),mt&&mt.ok===!1&&(Ot.open({onRetry:Qe,kind:"open"}),(mt.log||[]).forEach(Mt=>Ot.push(Mt)),Ot.finish({ok:!1,message:mt.hint||mt.error||r("docker.openFailed","打开失败")}));return}if(Me){m("probe");try{const mt=await(((X=(g=(ie=window.cicy)==null?void 0:ie.docker)==null?void 0:g.appRedetect)==null?void 0:X.call(g))??((rt=(P=(I=window.cicy)==null?void 0:I.docker)==null?void 0:P.appStatus)==null?void 0:rt.call(P)));mt&&Y(mt),mt!=null&&mt.unknown&&Tt.show({id:"docker-probe",status:"error",message:r("docker.wslStillStuck","WSL 仍无响应 —— 多半要重启 Windows 后再试"),ttl:6e3})}catch{Tt.show({id:"docker-probe",status:"error",message:r("docker.probeFailed","检测失败,请重试"),ttl:5e3})}finally{m("")}return}ft()}},Pe=Rt;return c.jsxs("div",{"data-id":"DockerCard",className:`bcard bcard--docker${Rt?" bcard--online":""}`,children:[c.jsx("div",{className:"bcard__accent",style:{background:_t}}),c.jsxs("div",{className:"bcard__top",children:[c.jsxs("div",{className:"bcard__pill",style:{color:_t},children:[c.jsx("span",{className:"bcard__dot","data-tone":Le}),c.jsx("svg",{style:{width:18,height:18},viewBox:"0 0 24 24",fill:"currentColor","aria-hidden":!0,children:c.jsx("path",{d:"M21.81 10.25c-.06-.05-.67-.51-1.95-.51-.34 0-.68.03-1.01.09-.25-1.69-1.64-2.51-1.7-2.55l-.34-.2-.22.32a4.5 4.5 0 0 0-.59 1.4c-.23.94-.09 1.83.39 2.59-.58.32-1.51.4-1.7.41H2.62a.61.61 0 0 0-.61.61 9.32 9.32 0 0 0 .57 3.35 4.9 4.9 0 0 0 1.95 2.53c.92.52 2.42.82 4.12.82.77 0 1.54-.07 2.3-.21a9.6 9.6 0 0 0 3-1.09 8.3 8.3 0 0 0 2.05-1.68c.98-1.11 1.56-2.35 1.99-3.45h.17c1.36 0 2.2-.55 2.66-1l.13-.16zM4.7 11.33h1.78a.16.16 0 0 0 .16-.16V9.58a.16.16 0 0 0-.16-.16H4.7a.16.16 0 0 0-.16.16v1.59c0 .09.07.16.16.16m2.46 0h1.78a.16.16 0 0 0 .16-.16V9.58a.16.16 0 0 0-.16-.16H7.16a.16.16 0 0 0-.16.16v1.59c0 .09.07.16.16.16m2.5 0h1.78a.16.16 0 0 0 .16-.16V9.58a.16.16 0 0 0-.16-.16H9.66a.16.16 0 0 0-.16.16v1.59c0 .09.07.16.16.16m2.47 0h1.78a.16.16 0 0 0 .16-.16V9.58a.16.16 0 0 0-.16-.16h-1.78a.16.16 0 0 0-.16.16v1.59c0 .09.07.16.16.16M7.16 9.06h1.78a.16.16 0 0 0 .16-.16V7.31a.16.16 0 0 0-.16-.16H7.16a.16.16 0 0 0-.16.16v1.59c0 .09.07.16.16.16m2.5 0h1.78a.16.16 0 0 0 .16-.16V7.31a.16.16 0 0 0-.16-.16H9.66a.16.16 0 0 0-.16.16v1.59c0 .09.07.16.16.16m2.47 0h1.78a.16.16 0 0 0 .16-.16V7.31a.16.16 0 0 0-.16-.16h-1.78a.16.16 0 0 0-.16.16v1.59c0 .09.07.16.16.16"})})]}),Pe&&c.jsxs("div",{className:"bcard__menuwrap",onClick:R=>R.stopPropagation(),children:[c.jsx("button",{type:"button",ref:q,"data-id":"DockerCard-menu-btn",className:"bcard__kebab",title:r("docker.manage","管理 Docker cicy-code"),disabled:ye,onClick:W,children:ye?c.jsx(ca,{}):c.jsx(so,{})}),B&&Sa.createPortal(c.jsxs("div",{className:"bcard__menu bcard__menu--portal","data-id":"DockerCard-menu",role:"menu",ref:nt,style:{position:"fixed",top:Jt.top,left:Jt.left,width:zt},onClick:R=>R.stopPropagation(),children:[c.jsx("button",{type:"button","data-id":"DockerCard-update",className:"bcard__menu-item is-accent",onClick:ne,children:r("docker.update","更新 cicy-code")}),c.jsx("button",{type:"button","data-id":"DockerCard-restart",className:"bcard__menu-item",onClick:()=>Zt("restart",()=>window.cicy.docker.appRestart(),r("docker.restarted","已重启 cicy-code")),children:r("docker.restart","重启 cicy-code")}),c.jsx("button",{type:"button","data-id":"DockerCard-stop",className:"bcard__menu-item is-danger",onClick:()=>Zt("stop",()=>window.cicy.docker.appStop(),r("docker.stopped","已停止 cicy-code")),children:r("docker.stop","停止 cicy-code")}),c.jsx("button",{type:"button","data-id":"DockerCard-reload",className:"bcard__menu-item",onClick:R=>{var it,at,ut;R.stopPropagation(),E(!1),(ut=(at=(it=window.cicy)==null?void 0:it.tabs)==null?void 0:at.reloadIfOpen)==null||ut.call(at,"http://127.0.0.1:8008","Docker 团队")},children:r("docker.reloadWindow","刷新窗口")}),c.jsx("button",{type:"button","data-id":"DockerCard-open-dir",className:"bcard__menu-item",onClick:R=>{var it,at,ut;R.stopPropagation(),E(!1),(ut=(at=(it=window.cicy)==null?void 0:it.docker)==null?void 0:at.openDir)==null||ut.call(at)},children:r("docker.openWslDir","打开 WSL 目录")}),c.jsx("button",{type:"button","data-id":"DockerCard-open-projects",className:"bcard__menu-item",onClick:R=>{var it,at,ut;R.stopPropagation(),E(!1),(ut=(at=(it=window.cicy)==null?void 0:it.docker)==null?void 0:at.openDir)==null||ut.call(at,"projects")},children:r("docker.openProjectsDir","打开项目目录")}),c.jsx("button",{type:"button","data-id":"DockerCard-dood",className:"bcard__menu-item",title:r("dood.hint","把宿主 Docker + docker 客户端挂进容器,容器内 agent 能直接跑 docker(切换会重建容器,秒生效、无需下载)"),onClick:R=>{R.stopPropagation(),E(!1),H(!0)},children:r("dood.menu","容器内使用 Docker")}),c.jsx("div",{className:"bcard__menu-sep","data-id":"DockerCard-menu-sep",role:"separator","aria-hidden":!0}),J==="darwin"&&c.jsx("button",{type:"button","data-id":"DockerCard-authorize-host-ssh",className:"bcard__menu-item",title:r("docker.authorizeHostHint","把容器公钥加到 Mac 的 authorized_keys,容器内 `ssh mac` 即可访问本机"),onClick:ke,children:r("docker.authorizeHost","授权容器访问 Mac")}),c.jsx("button",{type:"button","data-id":"DockerCard-docker-restart",className:"bcard__menu-item",onClick:()=>Zt("restart",()=>window.cicy.docker.appDockerRestart(),r("docker.dockerRestarted","已重启 Docker 容器")),children:r("docker.dockerRestart","重启 Docker")}),c.jsx("button",{type:"button","data-id":"DockerCard-ports",className:"bcard__menu-item",onClick:R=>{R.stopPropagation(),N()},children:r("docker.ports.menu","端口设置")}),c.jsx("button",{type:"button","data-id":"DockerCard-recreate",className:"bcard__menu-item is-danger",onClick:R=>{R.stopPropagation(),E(!1),Q(!0)},children:r("docker.recreate","重建 Docker")})]}),document.body)]})]}),c.jsxs("div",{className:"bcard__body",children:[c.jsxs("div",{style:{height:28,display:"flex",alignItems:"center",gap:8},children:[c.jsx(uo,{size:24,avatar:s==null?void 0:s.avatar,name:jt,teamId:s==null?void 0:s.id,onChanged:M}),gt?c.jsx("input",{"data-id":"DockerCard-rename-input",autoFocus:!0,value:ht,onChange:R=>Ct(R.target.value),onFocus:R=>R.target.select(),onBlur:kt,onClick:R=>R.stopPropagation(),onKeyDown:R=>{R.nativeEvent.isComposing||R.keyCode===229||(R.key==="Enter"?kt():R.key==="Escape"&&L(!1))},style:{flex:1,width:"100%",font:"inherit",fontWeight:600,padding:"2px 6px",border:"1px solid #3b82f6",borderRadius:6,background:"#0d1117",color:"#e6edf3",boxSizing:"border-box"}}):c.jsxs("h3",{className:"bcard__name",title:j?r("localTeams.renameHint","点名字或 ✎ 改名"):jt,style:{display:"flex",alignItems:"center",gap:6,flex:1,minWidth:0,margin:0},onDoubleClick:j?bt:void 0,children:[c.jsx("span",{onClick:j?bt:void 0,style:{overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap",cursor:j?"text":"default"},children:jt}),j&&c.jsx("button",{type:"button","data-id":"DockerCard-rename-btn",title:r("localTeams.rename","重命名"),onClick:bt,style:{flex:"none",cursor:"pointer",border:"none",background:"transparent",color:"#8b949e",fontSize:13,padding:0,lineHeight:1},children:"✎"})]})]}),c.jsxs("div",{className:"bcard__meta",children:[c.jsx("span",{className:"bcard__chip",children:"Docker"}),(k==null?void 0:k.version)&&c.jsxs("span",{className:"bcard__ver","data-id":"DockerCard-ver",style:{marginLeft:8,fontSize:11,opacity:.6},children:["v",k.version]})]})]}),c.jsxs("button",{type:"button",className:"bcard__cta","data-id":"DockerCard-cta",disabled:ye,onClick:Qe,style:Rt?void 0:{background:_t,color:"white"},children:[ye?c.jsx(ca,{}):c.jsx(co,{}),c.jsx("span",{children:Ge})]}),c.jsx(xy,{open:F,onClose:()=>H(!1),toastId:"docker-op"}),$&&Sa.createPortal(c.jsx("div",{"data-id":"DockerCard-recreate-modal",style:{position:"fixed",inset:0,zIndex:9999,background:"rgba(0,0,0,0.55)",display:"flex",alignItems:"center",justifyContent:"center"},onMouseDown:R=>{R.target===R.currentTarget&&Q(!1)},children:c.jsxs("div",{onClick:R=>R.stopPropagation(),style:{width:360,maxWidth:"90vw",background:"#161b22",border:"1px solid #30363d",borderRadius:12,padding:"20px 22px",boxShadow:"0 12px 40px rgba(0,0,0,0.5)"},children:[c.jsx("h3",{style:{margin:"0 0 8px",fontSize:16,color:"#e6edf3"},children:r("docker.recreate","重建 Docker")}),c.jsx("p",{style:{margin:"0 0 18px",fontSize:13,lineHeight:1.6,color:"#9aa4b2"},children:r("docker.recreateConfirm","会删除当前容器并重新创建(volume 数据保留),用于切换为独立 team 的网关 key。确定重建?")}),c.jsxs("div",{style:{display:"flex",justifyContent:"flex-end",gap:10},children:[c.jsx("button",{type:"button","data-id":"DockerCard-recreate-cancel",onClick:()=>Q(!1),style:{padding:"7px 16px",borderRadius:8,border:"1px solid #30363d",background:"transparent",color:"#c9d1d9",cursor:"pointer",fontSize:13},children:r("common.cancel","取消")}),c.jsx("button",{type:"button","data-id":"DockerCard-recreate-confirm",onClick:()=>{Q(!1),Zt("restart",()=>window.cicy.docker.appRecreate(),r("docker.recreated","已重建 Docker 容器"))},style:{padding:"7px 16px",borderRadius:8,border:"none",background:"#da3633",color:"white",cursor:"pointer",fontSize:13,fontWeight:600},children:r("docker.recreateOk","确定重建")})]})]})}),document.body),yt&&Sa.createPortal(c.jsx("div",{"data-id":"DockerCard-ports-modal",style:{position:"fixed",inset:0,zIndex:9999,background:"rgba(0,0,0,0.55)",display:"flex",alignItems:"center",justifyContent:"center"},onMouseDown:R=>{R.target===R.currentTarget&&Nt(!1)},children:c.jsxs("div",{onClick:R=>R.stopPropagation(),style:{width:420,maxWidth:"92vw",background:"#161b22",border:"1px solid #30363d",borderRadius:12,padding:"20px 22px",boxShadow:"0 12px 40px rgba(0,0,0,0.5)"},children:[c.jsx("h3",{style:{margin:"0 0 6px",fontSize:16,color:"#e6edf3"},children:r("docker.ports.title","端口设置")}),c.jsx("p",{style:{margin:"0 0 14px",fontSize:12.5,lineHeight:1.6,color:"#9aa4b2"},children:r("docker.ports.sub","除 :8008 外,额外发布、可从 Windows 直达容器内服务的端口")}),c.jsxs("div",{style:{display:"flex",alignItems:"center",gap:8,padding:"8px 10px",marginBottom:10,borderRadius:8,background:"#0d1117",border:"1px solid #21262d",color:"#7d8590",fontSize:13},children:["🔒 ",r("docker.ports.mainFixed",":8008 · cicy-code(固定)")]}),c.jsxs("div",{style:{display:"flex",flexDirection:"column",gap:8,maxHeight:220,overflowY:"auto"},children:[ce.length===0&&c.jsx("div",{style:{fontSize:12.5,color:"#6e7681",padding:"4px 2px"},children:r("docker.ports.none","暂无额外端口")}),ce.map((R,it)=>c.jsxs("div",{style:{display:"flex",alignItems:"center",gap:8},children:[c.jsx("input",{"data-id":`DockerCard-port-input-${it}`,type:"text",inputMode:"numeric",value:R,placeholder:r("docker.ports.ph","端口号 1-65535"),onChange:at=>{const ut=at.target.value.replace(/[^0-9]/g,"");ot(St=>St.map((qt,ie)=>ie===it?ut:qt)),G("")},style:{flex:1,padding:"7px 10px",borderRadius:8,border:"1px solid #30363d",background:"#0d1117",color:"#e6edf3",fontSize:13,fontFamily:"var(--mono)"}}),c.jsx("button",{type:"button","data-id":`DockerCard-port-remove-${it}`,title:r("docker.ports.remove","移除"),onClick:()=>{ot(at=>at.filter((ut,St)=>St!==it)),G("")},style:{padding:"6px 10px",borderRadius:8,border:"1px solid #30363d",background:"transparent",color:"#da3633",cursor:"pointer",fontSize:14},children:"✕"})]},it))]}),c.jsx("button",{type:"button","data-id":"DockerCard-port-add",onClick:()=>ot(R=>[...R,""]),style:{marginTop:10,padding:"7px 12px",borderRadius:8,border:"1px dashed #30363d",background:"transparent",color:"#58a6ff",cursor:"pointer",fontSize:13,width:"100%"},children:r("docker.ports.add","+ 添加端口")}),xt&&c.jsx("div",{style:{marginTop:10,fontSize:12.5,color:"#f85149"},children:xt}),c.jsx("p",{style:{margin:"12px 0 16px",fontSize:11.5,lineHeight:1.5,color:"#6e7681"},children:r("docker.ports.hint","保存会重建容器(volume 数据保留),会有短暂中断")}),c.jsxs("div",{style:{display:"flex",justifyContent:"flex-end",gap:10},children:[c.jsx("button",{type:"button","data-id":"DockerCard-ports-cancel",disabled:Lt,onClick:()=>Nt(!1),style:{padding:"7px 16px",borderRadius:8,border:"1px solid #30363d",background:"transparent",color:"#c9d1d9",cursor:"pointer",fontSize:13},children:r("docker.ports.cancel","取消")}),c.jsx("button",{type:"button","data-id":"DockerCard-ports-save",disabled:Lt,onClick:Z,style:{padding:"7px 16px",borderRadius:8,border:"none",background:"#238636",color:"white",cursor:"pointer",fontSize:13,fontWeight:600},children:Lt?r("docker.ports.saving","保存中…"):r("docker.ports.save","保存并重建")})]})]})}),document.body)]})}function bm({team:s,cloudCode:b,onOpen:S,onRename:d,onRefresh:j}){var ut,St,qt,ie;const k=(xm[s.status]||xm.error).tone,[Y,T]=v.useState(!1),[m,B]=v.useState(s.name||""),[E,F]=v.useState(null),[H,$]=v.useState(""),Q=E??s.name;v.useEffect(()=>{E!=null&&s.name===E&&F(null)},[s.name,E]);const yt=g=>{var X;(X=g==null?void 0:g.stopPropagation)==null||X.call(g),B(Q||""),T(!0)},Nt=async()=>{T(!1);const g=String(m||"").trim();if(!d||!g||g===Q)return;F(g),$("saving");let X;try{X=await d(s.id,g)}catch(I){X={ok:!1,error:I==null?void 0:I.message}}F(null),X&&X.ok?($("saved"),setTimeout(()=>$(I=>I==="saved"?"":I),1500)):($(""),Tt.show({message:r("localTeams.renameFailed","改名没保存,已恢复"),status:"error",ttl:4e3}))},ot=!!((St=(ut=window.cicy)==null?void 0:ut.sidecar)!=null&&St.restart)&&no(s.base_url),Lt=s.status==="running",[ct,xt]=v.useState(""),[G,gt]=v.useState(!1),[L,ht]=v.useState(!1);v.useEffect(()=>{var g,X;!ot||!((X=(g=window.cicy)==null?void 0:g.sidecar)!=null&&X.getPublic)||window.cicy.sidecar.getPublic().then(I=>ht(!!(I!=null&&I.public))).catch(()=>{})},[ot]);const[Ct,jt]=v.useState({running:void 0,latest:null,installed:null}),bt=Ct.latest,kt=Ct.running,[Jt,C]=v.useState(!1),q=v.useRef(null),nt=v.useRef(null),zt=v.useRef(null),[_t,h]=v.useState({top:0,left:0}),N=184,Z=()=>{if(!G&&nt.current){const g=nt.current.getBoundingClientRect(),X=Math.max(8,Math.min(g.right-N,window.innerWidth-N-8));h({top:Math.round(g.bottom+4),left:Math.round(X)})}gt(g=>!g)},W=v.useCallback(async(g=!1)=>{var X,I;if(!(!ot||!((I=(X=window.cicy)==null?void 0:X.sidecar)!=null&&I.versions))){g&&C(!0);try{const P=await window.cicy.sidecar.versions();jt({running:(P==null?void 0:P.running)??null,latest:(P==null?void 0:P.latest)??null,installed:(P==null?void 0:P.installed)??null}),g&&(P!=null&&P.running&&(P!=null&&P.latest)&&Sm(P.latest,P.running)>0?Tt.show({message:`${r("sidecar.found","发现新版本")} v${P.latest}`,status:"done",ttl:2500}):P!=null&&P.running?Tt.show({message:`${r("sidecar.upToDate","已是最新")} v${P.running}`,status:"done",ttl:2500}):Tt.show({message:r("sidecar.notRunning","cicy-code 未运行"),status:"error",ttl:4e3}))}catch{g&&Tt.show({message:r("sidecar.checkFailed","检查更新失败"),status:"error",ttl:5e3})}finally{g&&C(!1)}}},[ot]);v.useEffect(()=>{W(!1)},[W]),v.useEffect(()=>{Lt&&W(!1)},[Lt,W]);const ft=!!(ot&&bt&&kt&&Sm(bt,kt)>0),vt=!ot&&!!((ie=(qt=window.cicy)==null?void 0:qt.localTeams)!=null&&ie.remove),Ut=ot||vt,[ne,Zt]=v.useState(!1),[ke,J]=v.useState(!1),[Rt,je]=v.useState(""),[se,Me]=v.useState(""),[ve,Ye]=v.useState(!1),[sa,Le]=v.useState("");v.useEffect(()=>{if(!G)return;const g=X=>{var I,P;(I=nt.current)!=null&&I.contains(X.target)||(P=zt.current)!=null&&P.contains(X.target)||gt(!1)};return document.addEventListener("mousedown",g),()=>document.removeEventListener("mousedown",g)},[G]);const ye=async()=>{var X,I,P;if(ve)return;const g=ey({title:Rt,url:se});if(!g.ok){Le(r("teams.titleRequired","请输入自定义标题"));return}if(!g.patch.base_url){Le(r("teams.urlRequired","请输入地址 URL"));return}try{new URL(g.patch.base_url)}catch{Le(r("teams.badUrl","URL 无效(需含 http(s)://)"));return}if(g.patch.name===(s.name||"")&&g.patch.base_url===(s.base_url||"")){J(!1);return}Le(""),Ye(!0);try{const rt=await((P=(I=(X=window.cicy)==null?void 0:X.localTeams)==null?void 0:I.update)==null?void 0:P.call(I,s.id,g.patch));rt!=null&&rt.ok?(J(!1),j==null||j()):Le(wi((rt==null?void 0:rt.error)||"update failed"))}catch(rt){Le(wi((rt==null?void 0:rt.message)||String(rt)))}Ye(!1)},Ge=async()=>{var X,I,P;if(ct)return;Zt(!1),xt("remove");const g="op-"+Date.now();Tt.show({id:g,message:r("localTeams.removing","删除中…"),status:"running"});try{const rt=await((P=(I=(X=window.cicy)==null?void 0:X.localTeams)==null?void 0:I.remove)==null?void 0:P.call(I,s.id));rt!=null&&rt.ok?Tt.show({id:g,message:r("localTeams.removed","已删除"),status:"done",ttl:3e3}):Tt.show({id:g,message:r("localTeams.removeFailed","删除失败")+(rt!=null&&rt.error?": "+rt.error:""),status:"error",ttl:7e3})}catch(rt){Tt.show({id:g,message:r("localTeams.removeFailed","删除失败")+": "+((rt==null?void 0:rt.message)||rt),status:"error",ttl:7e3})}xt(""),j==null||j()},Qe=`sidecar-op:${s.id}`,Pe=async(g,X,I)=>{var mt,Mt,Ee,oa,Ta;if(gt(!1),ct)return;xt(g);const P=g==="update";let rt=null;P?(me.open({teamId:s.id,fromVer:kt,toVer:bt,onRetry:()=>Pe("update",X,I)}),(Mt=(mt=window.cicy)==null?void 0:mt.sidecar)!=null&&Mt.onOpProgress&&(rt=window.cicy.sidecar.onOpProgress(It=>{(It==null?void 0:It.op)==="update"&&me.push(It)}))):Tt.show({id:Qe,message:oe[g]||`${g}…`,status:"running",progress:void 0});try{const It=await X(),Se=!!(It!=null&&It.ok),Da=It!=null&&It.warning?`${I}(${It.warning})`:I,Ca=r("sidecar.failed","操作失败")+(It!=null&&It.error?`: ${It.error}`:"");if(P){if(me.finish({ok:Se,message:Se?Da:Ca}),Se)try{await((Ta=(oa=(Ee=window.cicy)==null?void 0:Ee.localTeams)==null?void 0:oa.reload)==null?void 0:Ta.call(oa,s.id,{ignoreCache:!0}))}catch{}}else Tt.show({id:Qe,message:Se?Da:Ca,progress:void 0,status:Se?"done":"error",ttl:Se?4e3:8e3})}catch(It){const Se=r("sidecar.failed","操作失败")+`: ${(It==null?void 0:It.message)||It}`;P?me.finish({ok:!1,message:Se}):Tt.show({id:Qe,message:Se,progress:void 0,status:"error",ttl:8e3})}finally{try{rt&&rt()}catch{}xt(""),j==null||j(),(g==="update"||g==="restart"||g==="start")&&W(!1)}},oe={start:r("busy.start","启动中…"),restart:r("busy.restart","重启中…"),update:r("busy.update","更新中…"),stop:r("busy.stop","停止中…")},R=async()=>{var I,P,rt;xt("start"),me.open({teamId:s.id,title:r("sidecar.startTitle","启动 cicy-code"),onRetry:R}),me.push({phase:"download",status:"running",message:r("sidecar.starting","启动 cicy-code(首次需安装 Node + 依赖,日志见下)…")});const g=(rt=(P=(I=window.cicy)==null?void 0:I.sidecar)==null?void 0:P.onOpProgress)==null?void 0:rt.call(P,mt=>me.push(mt));let X;try{X=await window.cicy.sidecar.start()}catch(mt){X={ok:!1,error:(mt==null?void 0:mt.message)||String(mt)}}try{g==null||g()}catch{}return xt(""),j==null||j(),!(X!=null&&X.ok)||X!=null&&X.warning?(me.finish({ok:!1,message:r("sidecar.startFailed","启动失败")+(X!=null&&X.error?`: ${X.error}`:X!=null&&X.warning?`: ${X.warning}`:"")}),!1):(me.finish({ok:!0,message:r("sidecar.startedOk","cicy-code 已就绪")}),!0)},it=async()=>{var g,X;ct||!Lt&&ot&&((X=(g=window.cicy)==null?void 0:g.sidecar)!=null&&X.start)&&!await R()||S()},at=Lt?r("localTeams.open","打开"):ot?r("localTeams.startOpen","启动并打开"):r("localTeams.open","打开");return c.jsxs(c.Fragment,{children:[c.jsxs("div",{"data-id":"LocalTeamCard",className:`bcard ${ot?"bcard--local":"bcard--custom"}${k==="ok"?" bcard--online":""}`,children:[c.jsx("div",{className:"bcard__accent"}),c.jsxs("div",{className:"bcard__top",children:[c.jsxs("div",{className:"bcard__pill",children:[c.jsx("span",{className:"bcard__dot","data-tone":k}),c.jsx(wy,{})]}),Ut&&c.jsxs("div",{className:"bcard__menuwrap",ref:q,onClick:g=>g.stopPropagation(),children:[c.jsx("button",{type:"button",ref:nt,"data-id":"LocalTeamCard-menu-btn",className:`bcard__kebab${ft?" has-dot":""}`,title:ot?r("localTeams.manage","管理本地 cicy-code"):r("localTeams.more","更多"),disabled:!!ct,onClick:Z,children:ct?c.jsx(ca,{}):c.jsx(so,{})}),G&&Sa.createPortal(c.jsxs("div",{className:"bcard__menu bcard__menu--portal","data-id":"LocalTeamCard-menu",role:"menu",ref:zt,style:{position:"fixed",top:_t.top,left:_t.left,width:N},onClick:g=>g.stopPropagation(),children:[ot&&c.jsx("button",{type:"button","data-id":"LocalTeamCard-check-update",className:"bcard__menu-item",disabled:Jt,onClick:g=>{g.stopPropagation(),W(!0)},children:Jt?r("sidecar.checking2","检查中…"):r("sidecar.checkUpdate","检查更新")}),ft&&c.jsxs("button",{type:"button","data-id":"LocalTeamCard-update",className:"bcard__menu-item is-accent",onClick:()=>Pe("update",()=>window.cicy.sidecar.update(),r("sidecar.updated","已更新到最新")),children:[r("sidecar.updateTo","更新到")," v",bt]}),s.base_url&&c.jsx("button",{type:"button","data-id":"LocalTeamCard-reload",className:"bcard__menu-item",onClick:g=>{var X,I,P;g.stopPropagation(),gt(!1),(P=(I=(X=window.cicy)==null?void 0:X.tabs)==null?void 0:I.reloadIfOpen)==null||P.call(I,s.base_url,s.name)},children:r("localTeams.reloadWindow","刷新窗口")}),ot&&!Lt&&c.jsx("button",{type:"button","data-id":"LocalTeamCard-start",className:"bcard__menu-item is-accent",onClick:()=>Pe("start",()=>window.cicy.sidecar.start(),r("sidecar.started","已启动")),children:r("sidecar.start","启动")}),ot&&Lt&&c.jsxs(c.Fragment,{children:[c.jsx("button",{type:"button","data-id":"LocalTeamCard-restart",className:"bcard__menu-item",onClick:()=>Pe("restart",()=>window.cicy.sidecar.restart(),r("sidecar.restarted","已重启")),children:r("sidecar.restart","重启")}),c.jsx("button",{type:"button","data-id":"LocalTeamCard-stop",className:"bcard__menu-item is-danger",onClick:()=>Pe("stop",()=>window.cicy.sidecar.stop(),r("sidecar.stoppedDone","已停止")),children:r("sidecar.stop","停止")}),c.jsxs("button",{type:"button","data-id":"LocalTeamCard-lan",className:"bcard__menu-item",title:r("sidecar.lanHint","开启后同局域网设备可用本机 IP 访问(api_token 仍校验);切换会自动重启 cicy-code"),disabled:ct==="lan",onClick:async()=>{if(ct)return;const g=!L;gt(!1),xt("lan"),ht(g),Tt.show({id:Qe,message:g?r("sidecar.lanEnabling","开启局域网访问,重启中…"):r("sidecar.lanDisabling","关闭局域网访问,重启中…"),status:"running",progress:void 0});try{const X=await window.cicy.sidecar.setPublic(g);X!=null&&X.ok?Tt.show({id:Qe,message:g?r("sidecar.lanOn","已开启局域网访问"):r("sidecar.lanOff","已关闭局域网访问"),status:"done",ttl:3e3}):Tt.show({id:Qe,message:r("sidecar.lanFailed","设置失败")+(X!=null&&X.error?`: ${X.error}`:""),status:"error",ttl:7e3})}catch(X){Tt.show({id:Qe,message:r("sidecar.lanFailed","设置失败")+`: ${(X==null?void 0:X.message)||X}`,status:"error",ttl:7e3})}try{const X=await window.cicy.sidecar.getPublic();ht(!!(X!=null&&X.public))}catch{}xt(""),j==null||j()},children:[r("sidecar.lanAccess","局域网访问")," · ",L?r("common.on","开"):r("common.off","关")]})]}),vt&&c.jsxs(c.Fragment,{children:[c.jsx("button",{type:"button","data-id":"LocalTeamCard-edit-url",className:"bcard__menu-item",onClick:g=>{g.stopPropagation(),gt(!1),J(!0),je(s.name||""),Me(s.base_url||""),Le("")},children:r("teamCard.editUrl","更改访问地址")}),c.jsx("button",{type:"button","data-id":"LocalTeamCard-remove",className:"bcard__menu-item is-danger",onClick:()=>{gt(!1),Zt(!0)},children:r("localTeams.remove","删除")})]}),(kt||s.version)&&c.jsxs("div",{"data-id":"LocalTeamCard-version",className:"bcard__menu-item",style:{cursor:"default",color:"#8b949e",fontSize:12},children:[r("localTeams.version","版本")," v",kt||s.version]})]}),document.body)]})]}),c.jsxs("div",{className:"bcard__body",children:[c.jsxs("div",{style:{height:28,display:"flex",alignItems:"center",gap:8},children:[c.jsx(uo,{size:24,avatar:s==null?void 0:s.avatar,name:s==null?void 0:s.name,teamId:s==null?void 0:s.id,onChanged:j}),Y?c.jsx("input",{"data-id":"LocalTeamCard-rename-input",autoFocus:!0,value:m,onChange:g=>B(g.target.value),onFocus:g=>g.target.select(),onBlur:Nt,onClick:g=>g.stopPropagation(),onKeyDown:g=>{g.nativeEvent.isComposing||g.keyCode===229||(g.key==="Enter"?Nt():g.key==="Escape"&&T(!1))},style:{flex:1,width:"100%",font:"inherit",fontWeight:600,padding:"2px 6px",border:"1px solid #3b82f6",borderRadius:6,background:"#0d1117",color:"#e6edf3",boxSizing:"border-box"}}):c.jsxs("h3",{className:"bcard__name",title:r("localTeams.renameHint","点名字或 ✎ 改名"),style:{display:"flex",alignItems:"center",gap:6,flex:1,minWidth:0,margin:0},onDoubleClick:yt,children:[c.jsx("span",{"data-id":"LocalTeamCard-name-text",onClick:yt,style:{overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap",cursor:"text"},children:Q}),H==="saving"&&c.jsx("span",{"data-id":"LocalTeamCard-save-state",title:r("localTeams.saving","保存中…"),style:{flex:"none",display:"inline-flex"},children:c.jsx(ca,{})}),H==="saved"&&c.jsx("span",{"data-id":"LocalTeamCard-save-state",title:r("localTeams.saved","已保存"),style:{flex:"none",color:"#3fb950",fontSize:13,lineHeight:1},children:"✓"}),!H&&c.jsx("button",{type:"button","data-id":"LocalTeamCard-rename-btn",title:r("localTeams.rename","重命名"),onClick:yt,style:{flex:"none",cursor:"pointer",border:"none",background:"transparent",color:"#8b949e",fontSize:13,padding:0,lineHeight:1},children:"✎"})]})]}),c.jsx("div",{className:"bcard__meta",children:c.jsx("span",{className:"bcard__chip","data-id":"LocalTeamCard-kind",children:ot?r("localTeams.kindLocal","本地"):r("localTeams.kindCustom","自定义")})})]}),c.jsxs("button",{type:"button",className:"bcard__cta","data-id":"LocalTeamCard-open",disabled:!!ct||!s.base_url,onClick:it,children:[ct&&ct!=="stop"?c.jsx(ca,{}):c.jsx(co,{}),c.jsx("span",{children:ct&&oe[ct]||at})]})]}),ke&&Sa.createPortal(c.jsx("div",{"data-id":"LocalTeamCard-url-modal",style:{position:"fixed",inset:0,zIndex:65,display:"flex",alignItems:"center",justifyContent:"center",background:"rgba(0,0,0,.5)"},onMouseDown:g=>{!ve&&g.target===g.currentTarget&&J(!1)},children:c.jsxs("div",{onClick:g=>g.stopPropagation(),style:{width:400,maxWidth:"92vw",background:"var(--card, #1b1d22)",border:"1px solid var(--border, #2c2f36)",borderRadius:14,padding:22,boxShadow:"0 20px 60px rgba(0,0,0,.5)"},children:[c.jsx("div",{style:{fontSize:16,fontWeight:700,marginBottom:16},children:r("teamCard.editCustom","编辑自定义团队")}),c.jsx("label",{style:{display:"block",fontSize:12,opacity:.75,marginBottom:6},children:r("teams.customNameLabel","自定义标题")}),c.jsx("input",{"data-id":"LocalTeamCard-title-input",autoFocus:!0,className:"login-email-input",style:{width:"100%",marginBottom:14},value:Rt,placeholder:r("teams.customNamePlaceholder","我的团队"),spellCheck:!1,disabled:ve,onChange:g=>je(g.target.value),onKeyDown:g=>{g.nativeEvent.isComposing||g.keyCode===229||(g.key==="Enter"?(g.preventDefault(),ye()):g.key==="Escape"&&J(!1))}}),c.jsx("label",{style:{display:"block",fontSize:12,opacity:.75,marginBottom:6},children:r("teams.customUrlLabel","地址 URL")}),c.jsx("textarea",{"data-id":"LocalTeamCard-url-input",rows:3,className:"login-email-input",style:{width:"100%",resize:"vertical",lineHeight:1.5,fontFamily:"var(--mono)"},value:se,placeholder:"https://example.com:8008",spellCheck:!1,disabled:ve,onChange:g=>Me(g.target.value.replace(/[\r\n]+/g,"")),onKeyDown:g=>{g.nativeEvent.isComposing||g.keyCode===229||(g.key==="Enter"?(g.preventDefault(),ye()):g.key==="Escape"&&J(!1))}}),sa&&c.jsx("div",{className:"error",style:{marginTop:8,fontSize:12},children:sa}),c.jsxs("div",{className:"modal-actions",children:[c.jsx("button",{type:"button",className:"btn-ghost",disabled:ve,onClick:()=>J(!1),children:r("common.cancel","取消")}),c.jsx("button",{type:"button",className:"btn-primary","data-id":"LocalTeamCard-url-save",disabled:ve,onClick:ye,children:ve?r("common.saving","保存中…"):r("common.save","保存")})]})]})}),document.body),c.jsx(Nm,{open:ne,title:r("localTeams.deleteTitle","删除团队"),message:r("localTeams.deleteMsg","确定删除「{{name}}」?此操作不可撤销。",{name:s.name}),confirmLabel:r("common.delete","删除"),danger:!0,onConfirm:Ge,onCancel:()=>Zt(!1)})]})}function no(s){var b;try{if(((b=window.cicy)==null?void 0:b.platform)==="win32")return!1;const S=new URL(s);return(S.hostname==="127.0.0.1"||S.hostname==="localhost"||S.hostname==="::1")&&(S.port==="8008"||S.port==="")}catch{return!1}}function vm(s){var b;try{if(((b=window.cicy)==null?void 0:b.platform)!=="win32")return!1;const S=new URL(s);return(S.hostname==="127.0.0.1"||S.hostname==="localhost"||S.hostname==="::1")&&S.port==="8008"}catch{return!1}}function Sm(s,b){const S=String(s).split("."),d=String(b).split(".");for(let j=0;j<Math.max(S.length,d.length);j++){const M=(parseInt(S[j],10)||0)-(parseInt(d[j],10)||0);if(M)return M>0?1:-1}return 0}const xm={running:{tone:"ok",label:"running",cta:r("localStatus.open","打开")},stopped:{tone:"off",label:"stopped",cta:r("localStatus.notRunning","未运行")},auth_error:{tone:"warn",label:"auth error",cta:r("localStatus.tokenInvalid","Token 失效")},misconfigured:{tone:"err",label:"bad config",cta:r("localStatus.badUrl","URL 错误")},error:{tone:"err",label:"error",cta:r("localStatus.error","异常")}};function Nm({open:s,title:b,message:S,confirmLabel:d,danger:j,onConfirm:M,onCancel:k}){return s?Sa.createPortal(c.jsx("div",{"data-id":"ConfirmModal",style:{position:"fixed",inset:0,zIndex:70,display:"flex",alignItems:"center",justifyContent:"center",background:"rgba(0,0,0,.5)"},onMouseDown:Y=>{Y.target===Y.currentTarget&&(k==null||k())},children:c.jsxs("div",{onClick:Y=>Y.stopPropagation(),style:{width:360,maxWidth:"92vw",background:"var(--card, #1b1d22)",border:"1px solid var(--border, #2c2f36)",borderRadius:14,padding:22,boxShadow:"0 20px 60px rgba(0,0,0,.5)"},children:[c.jsx("div",{style:{fontSize:16,fontWeight:700,marginBottom:6},children:b}),S&&c.jsx("div",{style:{fontSize:13,opacity:.7,marginBottom:16},children:S}),c.jsxs("div",{className:"modal-actions",children:[c.jsx("button",{type:"button",className:"btn-ghost",onClick:k,children:r("common.cancel","取消")}),c.jsx("button",{type:"button",className:"btn-primary","data-id":"ConfirmModal-ok",style:j?{background:"#dc2626",borderColor:"#dc2626"}:{},onClick:M,children:d||r("common.confirm","确认")})]})]})}),document.body):null}function yy({team:s,onOpen:b,onRename:S,onEditUrl:d,onDelete:j,avatar:M,onAvatar:k}){const Y=s.kind==="private",T=s.status==="active",m=s.name||s.title||"—",[B,E]=v.useState(!1),[F,H]=v.useState(""),[$,Q]=v.useState(null),yt=$??m;v.useEffect(()=>{$!=null&&m===$&&Q(null)},[m,$]);const Nt=J=>{var Rt;(Rt=J==null?void 0:J.stopPropagation)==null||Rt.call(J),H(yt==="—"?"":yt),E(!0)},ce=async()=>{E(!1);const J=String(F||"").trim();if(!(!S||!J||J===yt)){Q(J);try{const Rt=await S(s.id,J);Rt!=null&&Rt.ok||Q(null)}catch{Q(null)}}},ot=s.host_url||"",[Lt,ct]=v.useState(!1),[xt,G]=v.useState(""),[gt,L]=v.useState(null),ht=gt??ot;v.useEffect(()=>{gt!=null&&ot===gt&&L(null)},[ot,gt]);const Ct=s.teamId||s.id,jt=Y?r("teamKind.private","私有云"):s.team_kind==="personal"?r("teamKind.personal","个人"):r("teamKind.shared","共享"),bt=Y?ht:s.workspace_url||s.workspace_direct_url,kt=!!bt,[Jt,C]=v.useState(!1),[q,nt]=v.useState(!1),[zt,_t]=v.useState({top:0,left:0}),h=v.useRef(null),N=v.useRef(null),Z=v.useRef(null),W=184,ft=()=>{if(!Jt&&N.current){const J=N.current.getBoundingClientRect(),Rt=Math.max(8,Math.min(J.right-W,window.innerWidth-W-8));_t({top:Math.round(J.bottom+4),left:Math.round(Rt)})}C(J=>!J)};v.useEffect(()=>{if(!Jt)return;const J=Rt=>{var je,se;(je=N.current)!=null&&je.contains(Rt.target)||(se=Z.current)!=null&&se.contains(Rt.target)||C(!1)};return document.addEventListener("mousedown",J),()=>document.removeEventListener("mousedown",J)},[Jt]);const vt=J=>{var Rt,je,se,Me;(Rt=J==null?void 0:J.stopPropagation)==null||Rt.call(J),kt&&(C(!1),(Me=(se=(je=window.cicy)==null?void 0:je.tabs)==null?void 0:se.reloadIfOpen)==null||Me.call(se,bt,yt))},[Ut,ne]=v.useState(!1),Zt=()=>{G(ot),ct(!0),C(!1)},ke=async()=>{ct(!1);const J=String(xt||"").trim();if(!(!d||!J||J===ot)){L(J);try{const Rt=await d(s.id,J);Rt!=null&&Rt.ok||L(null)}catch{L(null)}}};return c.jsxs(c.Fragment,{children:[c.jsxs("div",{"data-id":"TeamCard",className:`bcard bcard--cloud${T?" bcard--online":""}`,children:[c.jsx("div",{className:"bcard__accent"}),c.jsxs("div",{className:"bcard__top",children:[c.jsxs("div",{className:"bcard__pill",children:[c.jsx("span",{className:"bcard__dot","data-tone":T?"ok":"off"}),c.jsx(Ty,{})]}),c.jsxs("div",{className:"bcard__top-right",children:[s.is_trial&&c.jsx("span",{className:"bcard__badge",children:"trial"}),(kt||Ct!=null||Y&&d)&&c.jsxs("div",{className:"bcard__menuwrap",ref:h,onClick:J=>J.stopPropagation(),children:[c.jsx("button",{type:"button",ref:N,"data-id":"TeamCard-menu-btn",className:"bcard__kebab",title:r("localTeams.more","更多"),disabled:q,onClick:ft,children:q?c.jsx(ca,{}):c.jsx(so,{})}),Jt&&Sa.createPortal(c.jsxs("div",{className:"bcard__menu bcard__menu--portal","data-id":"TeamCard-menu",role:"menu",ref:Z,style:{position:"fixed",top:zt.top,left:zt.left,width:W},onClick:J=>J.stopPropagation(),children:[kt&&c.jsx("button",{type:"button","data-id":"TeamCard-reload",className:"bcard__menu-item",onClick:vt,children:r("localTeams.reloadWindow","刷新窗口")}),Ct!=null&&c.jsx("button",{type:"button","data-id":"TeamCard-billing",className:"bcard__menu-item",onClick:J=>{J.stopPropagation(),C(!1),Em(`?team=${encodeURIComponent(Ct)}`)},children:r("localTeams.billing","账单")}),Y&&d&&c.jsx("button",{type:"button","data-id":"TeamCard-edit-url",className:"bcard__menu-item",onClick:J=>{J.stopPropagation(),Zt()},children:ot?r("teamCard.editUrl","更改访问地址"):r("teamCard.setUrl","填写访问地址")}),Y&&j&&c.jsx("button",{type:"button","data-id":"TeamCard-delete",className:"bcard__menu-item is-danger",onClick:J=>{J.stopPropagation(),C(!1),ne(!0)},children:r("teamCard.delete","删除")})]}),document.body)]})]})]}),c.jsxs("div",{className:"bcard__body",children:[c.jsxs("div",{style:{height:28,display:"flex",alignItems:"center",gap:8},children:[c.jsx(uo,{size:24,avatar:M,name:(s==null?void 0:s.name)||(s==null?void 0:s.title),teamId:s==null?void 0:s.id,onChanged:k}),B?c.jsx("input",{"data-id":"TeamCard-rename-input",autoFocus:!0,value:F,onChange:J=>H(J.target.value),onFocus:J=>J.target.select(),onBlur:ce,onClick:J=>J.stopPropagation(),onKeyDown:J=>{J.nativeEvent.isComposing||J.keyCode===229||(J.key==="Enter"?ce():J.key==="Escape"&&E(!1))},style:{flex:1,width:"100%",font:"inherit",fontWeight:600,padding:"2px 6px",border:"1px solid #3b82f6",borderRadius:6,background:"#0d1117",color:"#e6edf3",boxSizing:"border-box"}}):c.jsxs("h3",{className:"bcard__name",title:S?r("localTeams.renameHint","点名字或 ✎ 改名"):yt,style:{display:"flex",alignItems:"center",gap:6,flex:1,minWidth:0,margin:0},onDoubleClick:S?Nt:void 0,children:[c.jsx("span",{onClick:S?Nt:void 0,style:{overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap",cursor:S?"text":"default"},children:yt}),S&&c.jsx("button",{type:"button","data-id":"TeamCard-rename-btn",title:r("localTeams.rename","重命名"),onClick:Nt,style:{flex:"none",cursor:"pointer",border:"none",background:"transparent",color:"#8b949e",fontSize:13,padding:0,lineHeight:1},children:"✎"})]})]}),c.jsxs("div",{className:"bcard__meta",children:[c.jsx("span",{className:"bcard__chip",children:jt}),!Y&&s.membership_status&&s.membership_status!=="active"&&c.jsx("span",{className:"bcard__chip",children:s.membership_status})]})]}),c.jsxs("button",{type:"button",className:"bcard__cta",onClick:b,disabled:!kt,children:[c.jsx(co,{}),c.jsx("span",{children:kt?r("localTeams.open","打开"):Y?r("teamCard.noHost","未填访问地址"):r("teamCard.noUrl","无 URL")})]})]}),Lt&&Sa.createPortal(c.jsx("div",{"data-id":"TeamCard-url-modal",style:{position:"fixed",inset:0,zIndex:65,display:"flex",alignItems:"center",justifyContent:"center",background:"rgba(0,0,0,.5)"},onMouseDown:J=>{J.target===J.currentTarget&&ct(!1)},children:c.jsxs("div",{onClick:J=>J.stopPropagation(),style:{width:400,maxWidth:"92vw",background:"var(--card, #1b1d22)",border:"1px solid var(--border, #2c2f36)",borderRadius:14,padding:22,boxShadow:"0 20px 60px rgba(0,0,0,.5)"},children:[c.jsx("div",{style:{fontSize:16,fontWeight:700,marginBottom:4},children:ot?r("teamCard.editUrl","更改访问地址"):r("teamCard.setUrl","填写访问地址")}),c.jsx("div",{style:{fontSize:12,opacity:.6,marginBottom:16},children:yt}),c.jsx("textarea",{"data-id":"TeamCard-url-input",autoFocus:!0,rows:3,className:"login-email-input",style:{width:"100%",resize:"vertical",lineHeight:1.5,fontFamily:"var(--mono)"},value:xt,placeholder:"https://你的私有云地址:端口",spellCheck:!1,onChange:J=>G(J.target.value.replace(/[\r\n]+/g,"")),onKeyDown:J=>{J.nativeEvent.isComposing||J.keyCode===229||(J.key==="Enter"?(J.preventDefault(),ke()):J.key==="Escape"&&ct(!1))}}),c.jsxs("div",{className:"modal-actions",children:[c.jsx("button",{type:"button",className:"btn-ghost",onClick:()=>ct(!1),children:r("common.cancel","取消")}),c.jsx("button",{type:"button",className:"btn-primary","data-id":"TeamCard-url-save",onClick:ke,children:r("common.save","保存")})]})]})}),document.body),c.jsx(Nm,{open:Ut,title:r("localTeams.deleteTitle","删除团队"),message:r("localTeams.deleteMsg","确定删除「{{name}}」?此操作不可撤销。",{name:yt}),confirmLabel:r("common.delete","删除"),danger:!0,onConfirm:async()=>{ne(!1),j&&await j(s)},onCancel:()=>ne(!1)})]})}function _m(){return c.jsxs("div",{className:"brand",children:[c.jsx("div",{className:"brand-mark",children:c.jsx(_y,{})}),c.jsxs("div",{className:"brand-text",children:[c.jsx("div",{className:"brand-name",children:"CiCy Desktop"}),c.jsx("div",{className:"brand-sub",children:r("app.brandSub","团队 AI 协作工作台")})]})]})}function gy(){const[s,b]=v.useState(null),[S,d]=v.useState(!1),[j,M]=v.useState(!1),k=v.useRef(!1),Y=B=>{var E,F,H;M(B),(H=(F=(E=window.cicy)==null?void 0:E.app)==null?void 0:F.setAutoUpdate)==null||H.call(F,B).catch(()=>{})};v.useEffect(()=>{var F,H,$,Q,yt,Nt,ce,ot,Lt;let B=!0;($=(H=(F=window.cicy)==null?void 0:F.app)==null?void 0:H.updateState)==null||$.call(H).then(ct=>{B&&b(ct)}).catch(()=>{}),(Nt=(yt=(Q=window.cicy)==null?void 0:Q.app)==null?void 0:yt.getAutoUpdate)==null||Nt.call(yt).then(ct=>{B&&M(ct===!0)}).catch(()=>{});const E=(Lt=(ot=(ce=window.cicy)==null?void 0:ce.app)==null?void 0:ot.onUpdateState)==null?void 0:Lt.call(ot,ct=>{b(ct),typeof(ct==null?void 0:ct.autoUpdate)=="boolean"&&M(ct.autoUpdate),ct!=null&&ct.auto&&!k.current&&(ct.status==="downloading"||ct.status==="ready")&&(k.current=!0,d(!0),me.open({kind:"app",title:r("updateBanner.drawerTitle","应用更新"),fromVer:ct.current,toVer:ct.version,onRetry:()=>{var xt,G,gt;return(gt=(G=(xt=window.cicy)==null?void 0:xt.app)==null?void 0:G.downloadUpdate)==null?void 0:gt.call(G)}}),me.push({phase:"download",status:"running",message:r("updateBanner.autoDl","已开启自动更新,正在下载安装包…")})),k.current&&(ct.status==="downloading"?me.setProgress(ct.progress||{}):ct.status==="ready"?me.ready({onInstall:()=>{var xt,G,gt;return(gt=(G=(xt=window.cicy)==null?void 0:xt.app)==null?void 0:G.installUpdate)==null?void 0:gt.call(G)}}):ct.status==="error"&&(me.finish({ok:!1,message:ct.error||r("updateBanner.error","更新失败")}),k.current=!1))});return()=>{B=!1;try{E&&E()}catch{}}},[]);const T=s==null?void 0:s.status;v.useEffect(()=>{d(!1)},[T]);const m=()=>{var B,E,F;k.current=!0,d(!0),me.open({kind:"app",title:r("updateBanner.drawerTitle","应用更新"),fromVer:s==null?void 0:s.current,toVer:s==null?void 0:s.version,onRetry:m}),me.push({phase:"download",status:"running",message:r("updateBanner.startDl","开始下载安装包…")}),me.setProgress({percent:0}),(F=(E=(B=window.cicy)==null?void 0:B.app)==null?void 0:E.downloadUpdate)==null||F.call(E)};return T!=="available"||S?null:Sa.createPortal(c.jsx("div",{"data-id":"UpdateBanner",style:{position:"fixed",inset:0,zIndex:1e4,background:"rgba(0,0,0,0.6)",backdropFilter:"blur(3px)",display:"flex",alignItems:"center",justifyContent:"center"},onMouseDown:B=>{B.target===B.currentTarget&&d(!0)},children:c.jsxs("div",{onClick:B=>B.stopPropagation(),style:{width:380,maxWidth:"90vw",background:"#161b22",border:"1px solid #30363d",borderRadius:14,padding:"24px 24px 20px",boxShadow:"0 20px 60px rgba(0,0,0,0.55)",textAlign:"center"},children:[c.jsx("div",{style:{fontSize:34,lineHeight:1,marginBottom:12},"aria-hidden":!0,children:"🚀"}),c.jsx("h3",{style:{margin:"0 0 8px",fontSize:17,color:"#e6edf3"},"data-id":"UpdateBanner-text",children:r("updateBanner.available","发现新版本 v{{v}}",{v:s.version})}),c.jsx("p",{style:{margin:"0 0 14px",fontSize:13,lineHeight:1.6,color:"#9aa4b2"},children:r("updateBanner.modalSub","建议尽快更新到最新版本")}),c.jsxs("label",{"data-id":"UpdateBanner-auto",style:{display:"flex",alignItems:"center",justifyContent:"center",gap:7,margin:"0 0 18px",fontSize:12.5,color:"#c9d1d9",cursor:"pointer",userSelect:"none"},children:[c.jsx("input",{type:"checkbox",checked:j,onChange:B=>Y(B.target.checked),style:{accentColor:"#238636",width:15,height:15,margin:0,cursor:"pointer"}}),r("updateBanner.autoNext","以后发现新版本自动更新,不再询问")]}),c.jsxs("div",{style:{display:"flex",gap:10,justifyContent:"center"},children:[c.jsx("button",{type:"button","data-id":"UpdateBanner-later",onClick:()=>d(!0),style:{flex:1,padding:"9px 16px",borderRadius:9,border:"1px solid #30363d",background:"transparent",color:"#c9d1d9",cursor:"pointer",fontSize:14},children:r("updateBanner.later","稍后")}),c.jsx("button",{type:"button","data-id":"UpdateBanner-download",onClick:m,style:{flex:1,padding:"9px 16px",borderRadius:9,border:"none",background:"#238636",color:"white",cursor:"pointer",fontSize:14,fontWeight:600},children:r("updateBanner.updateNow","立即更新")})]})]})}),document.body)}function by(){return c.jsxs("div",{className:"bcard bcard--skeleton","data-id":"SkeletonCard","aria-hidden":!0,children:[c.jsx("div",{className:"bcard__accent",style:{background:"rgba(255,255,255,.08)",opacity:1}}),c.jsxs("div",{className:"bcard__top",children:[c.jsx("div",{className:"skel",style:{width:84,height:26,borderRadius:999}}),c.jsx("div",{className:"skel",style:{width:22,height:22,borderRadius:6}})]}),c.jsxs("div",{style:{flex:1,minHeight:0,marginTop:14},children:[c.jsxs("div",{style:{display:"flex",alignItems:"center",gap:8},children:[c.jsx("div",{className:"skel",style:{width:24,height:24,borderRadius:6,flex:"0 0 auto"}}),c.jsx("div",{className:"skel skel--line",style:{width:"55%"}})]}),c.jsx("div",{className:"skel",style:{width:60,height:18,borderRadius:6,marginTop:12}})]}),c.jsx("div",{className:"skel skel--cta",style:{marginTop:0}})]})}const wm=["hsl(2 68% 48%)","hsl(26 72% 46%)","hsl(45 70% 42%)","hsl(96 55% 38%)","hsl(140 58% 40%)","hsl(168 62% 36%)","hsl(192 70% 42%)","hsl(210 72% 50%)","hsl(232 62% 56%)","hsl(266 55% 55%)","hsl(292 58% 50%)","hsl(324 66% 50%)"];function vy(s){s=String(s??"");let b=0;for(let S=0;S<s.length;S++)b=(b*31+s.charCodeAt(S))%100003;return b}function Sy(s){return wm[vy(s)%wm.length]}function xy({open:s,onClose:b,toastId:S="dood-op"}){const[d,j]=v.useState(!1),[M,k]=v.useState(""),[Y,T]=v.useState(!1),[m,B]=v.useState("");v.useEffect(()=>{var H,$;!s||!(($=(H=window.cicy)==null?void 0:H.sidecar)!=null&&$.getDood)||(k(""),B(""),window.cicy.sidecar.getDood().then(Q=>T(!!(Q!=null&&Q.dood))).catch(()=>{}))},[s]),v.useEffect(()=>{var H,$;if(!(!s||!d||!(($=(H=window.cicy)==null?void 0:H.sidecar)!=null&&$.onOpProgress)))return window.cicy.sidecar.onOpProgress(Q=>{Q!=null&&Q.message&&B(String(Q.message))})},[s,d]);const E=async()=>{if(!d){j(!0),k(""),B(""),Tt.show({id:S,message:Y?r("dood.applying","开启容器 Docker 访问,重建容器中…"):r("dood.disabling","关闭中…"),status:"running",progress:void 0});try{const H=await window.cicy.sidecar.setDood(Y);H!=null&&H.ok?(b&&b(),Tt.show({id:S,message:Y?r("dood.onDone","容器 Docker 访问已开启"):r("dood.offDone","容器 Docker 访问已关闭"),status:"done",ttl:4e3})):(k((H==null?void 0:H.error)||r("dood.failed","设置失败")),Tt.show({id:S,message:r("dood.failed","设置失败")+(H!=null&&H.error?`: ${H.error}`:""),status:"error",ttl:6e3}))}catch(H){k((H==null?void 0:H.message)||String(H)),Tt.show({id:S,message:r("dood.failed","设置失败")+`: ${(H==null?void 0:H.message)||H}`,status:"error",ttl:6e3})}finally{j(!1)}}},F=H=>{b&&b()};return s?c.jsx(c.Fragment,{children:Sa.createPortal(c.jsx("div",{"data-id":"dood-modal",style:{position:"fixed",inset:0,zIndex:66,display:"flex",alignItems:"center",justifyContent:"center",background:"rgba(0,0,0,.5)"},onMouseDown:H=>{!d&&H.target===H.currentTarget&&F()},children:c.jsxs("div",{onClick:H=>H.stopPropagation(),style:{width:440,maxWidth:"92vw",background:"var(--card, #1b1d22)",border:"1px solid var(--border, #2c2f36)",borderRadius:14,padding:22,boxShadow:"0 20px 60px rgba(0,0,0,.5)"},children:[c.jsx("div",{style:{fontSize:16,fontWeight:700,marginBottom:4},children:r("dood.title","容器内使用 Docker")}),c.jsx("div",{style:{fontSize:12,opacity:.6,marginBottom:16},children:r("dood.subtitle","把宿主 Docker + docker 客户端挂进容器,容器内 agent 就能直接跑 docker(秒生效,无需下载)")}),c.jsxs("label",{"data-id":"dood-toggle-row",style:{display:"flex",alignItems:"center",gap:10,cursor:d?"default":"pointer",marginBottom:12},children:[c.jsx("input",{type:"checkbox","data-id":"dood-toggle",checked:Y,disabled:d,onChange:H=>T(H.target.checked)}),c.jsx("span",{style:{fontSize:14,fontWeight:600},children:r("dood.enable","允许容器内使用 Docker")})]}),d&&m&&c.jsx("div",{"data-id":"dood-progress",style:{fontSize:11,opacity:.7,fontFamily:"var(--mono)",wordBreak:"break-all",margin:"0 0 8px",maxHeight:60,overflow:"hidden"},children:m}),M&&c.jsx("div",{className:"error",style:{marginTop:8,fontSize:12},children:M}),c.jsxs("div",{className:"modal-actions",children:[c.jsx("button",{type:"button",className:"btn-ghost",disabled:d,onClick:()=>F(),children:r("common.cancel","取消")}),c.jsx("button",{type:"button",className:"btn-primary","data-id":"dood-save",disabled:d,onClick:E,children:d?r("common.saving","保存中…"):r("common.save","保存")})]})]})}),document.body)}):null}function uo({avatar:s,name:b,teamId:S,onChanged:d,size:j=34}){const M=v.useRef(null),k=((b||"?").trim()[0]||"?").toUpperCase(),Y=Sy(S||b||""),T=m=>{const B=m.target.files&&m.target.files[0];if(m.target.value="",!B)return;const E=new FileReader;E.onload=async()=>{var F,H,$;try{await(($=(H=(F=window.cicy)==null?void 0:F.localTeams)==null?void 0:H.setAvatar)==null?void 0:$.call(H,S,E.result)),d&&d()}catch{}},E.readAsDataURL(B)};return c.jsxs("div",{"data-id":"TeamAvatar",className:"team-avatar",title:S?r("teamCard.changeAvatar","点击更换头像"):"",onClick:S?m=>{m.stopPropagation(),M.current&&M.current.click()}:void 0,style:{width:j,height:j,borderRadius:9,flex:"none",overflow:"hidden",display:"flex",alignItems:"center",justifyContent:"center",cursor:S?"pointer":"default",background:s?"#0d1117":Y,color:"#fff",fontWeight:700,fontSize:Math.round(j*.42),userSelect:"none"},children:[s?c.jsx("img",{src:s,alt:"",style:{width:"100%",height:"100%",objectFit:"cover"}}):k,S&&c.jsx("input",{ref:M,type:"file",accept:"image/*",style:{display:"none"},onChange:T})]})}function _y(){return c.jsxs("svg",{width:"22",height:"22",viewBox:"0 0 96 96",fill:"none",children:[c.jsx("path",{d:"M48 11L39.5 33.3L16 29.5L31 48L16 66.5L39.5 62.7L48 85L56.5 62.7L80 66.5L65 48L80 29.5L56.5 33.3Z",stroke:"white",strokeWidth:"10",strokeLinejoin:"round",strokeLinecap:"round"}),c.jsx("circle",{cx:"48",cy:"48",r:"6",fill:"white"})]})}function co(){return c.jsxs("svg",{width:"16",height:"16",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2.2",strokeLinecap:"round",strokeLinejoin:"round",children:[c.jsx("line",{x1:"5",y1:"12",x2:"19",y2:"12"}),c.jsx("polyline",{points:"12 5 19 12 12 19"})]})}function ca(){return c.jsx("svg",{className:"spin",width:"16",height:"16",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2.4",strokeLinecap:"round",children:c.jsx("path",{d:"M21 12a9 9 0 1 1-6.2-8.55"})})}function wy(){return c.jsxs("svg",{width:"12",height:"12",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:[c.jsx("rect",{x:"3",y:"4",width:"18",height:"12",rx:"2"}),c.jsx("line",{x1:"2",y1:"20",x2:"22",y2:"20"})]})}function so(){return c.jsxs("svg",{width:"16",height:"16",viewBox:"0 0 24 24",fill:"currentColor","aria-hidden":!0,children:[c.jsx("circle",{cx:"12",cy:"5",r:"1.7"}),c.jsx("circle",{cx:"12",cy:"12",r:"1.7"}),c.jsx("circle",{cx:"12",cy:"19",r:"1.7"})]})}function Ty(){return c.jsxs("svg",{width:"12",height:"12",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:[c.jsx("circle",{cx:"12",cy:"12",r:"10"}),c.jsx("line",{x1:"2",y1:"12",x2:"22",y2:"12"}),c.jsx("path",{d:"M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z"})]})}function An(s){try{return localStorage.getItem(s)||null}catch{return null}}function wi(s){return s?/timeout/i.test(s)?"登录超时,请重新点击 Login。":/state/i.test(s)?"校验失败,请重新登录。":/no token/i.test(s)?"登录未完成,请重试。":/bridge missing/i.test(s)?"无法连接到登录服务(preload 未就绪)。":s:""}var Tm;const Cy=((Tm=window.cicy)==null?void 0:Tm.platform)||(()=>{const s=navigator.userAgent||"";return/Mac/i.test(s)?"darwin":/Windows/i.test(s)?"win32":"linux"})();document.documentElement.dataset.platform=Cy;document.documentElement.dataset.fullscreen="0";var Cm,jm;(jm=(Cm=window.cicy)==null?void 0:Cm.window)!=null&&jm.onFullscreen&&window.cicy.window.onFullscreen(s=>{document.documentElement.dataset.fullscreen=s?"1":"0"});Fp.createRoot(document.getElementById("root")).render(c.jsx(cy,{}));
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
<link rel="icon" type="image/svg+xml" href="./favicon.svg" />
|
|
7
7
|
<link rel="icon" type="image/png" sizes="256x256" href="./favicon-256.png" />
|
|
8
8
|
<title>CiCy Desktop</title>
|
|
9
|
-
<script type="module" crossorigin src="./assets/index-
|
|
9
|
+
<script type="module" crossorigin src="./assets/index-CriNT9kd.js"></script>
|
|
10
10
|
<link rel="stylesheet" crossorigin href="./assets/index-C6Zrdgc0.css">
|
|
11
11
|
</head>
|
|
12
12
|
<body>
|
|
@@ -663,7 +663,13 @@ async function pullCustomTeams() {
|
|
|
663
663
|
// this code) — register to cloud without needing a manual rename to trigger it.
|
|
664
664
|
// create/rename still sync individually; this is the catch-up for the rest.
|
|
665
665
|
// Best-effort, fully non-blocking, no-op when logged out.
|
|
666
|
-
|
|
666
|
+
// 防抖:主页对账 IPC + 30s 定时器 + 登录/启动钩子都会调这里,每次对每个团队发一个云端请求。
|
|
667
|
+
// 60s 内只真正跑一次(force:true 绕过,用于登录/启动后的首次同步),避免 Windows 端口被
|
|
668
|
+
// TIME_WAIT 耗尽。
|
|
669
|
+
let _lastSyncAllAt = 0;
|
|
670
|
+
async function syncAllLocalTeams({ force = false } = {}) {
|
|
671
|
+
if (!force && Date.now() - _lastSyncAllAt < 60_000) return;
|
|
672
|
+
_lastSyncAllAt = Date.now();
|
|
667
673
|
try {
|
|
668
674
|
const cc = require("../cloud/cloud-client");
|
|
669
675
|
if (!cc.loginToken || !cc.loginToken()) return; // logged out → no-op
|
|
@@ -674,7 +680,7 @@ async function syncAllLocalTeams() {
|
|
|
674
680
|
for (const id of ids) {
|
|
675
681
|
try { await syncNameToCloud(id); } catch {}
|
|
676
682
|
}
|
|
677
|
-
if (ids.length) log.info(`[local-teams]
|
|
683
|
+
if (ids.length) log.info(`[local-teams] cloud-sync of ${ids.length} team(s)`);
|
|
678
684
|
// 自定义团队只本地,不再 pullCustomTeams。
|
|
679
685
|
} catch (e) { log.warn(`[local-teams] startup cloud-sync failed: ${e.message}`); }
|
|
680
686
|
}
|
|
@@ -172,7 +172,15 @@ function register({ sidecarLogPath } = {}) {
|
|
|
172
172
|
let _rebootScheduled = false;
|
|
173
173
|
let _tcpRepairDone = false; // Windows 端口修复每次进程只做一次(需要 UAC)
|
|
174
174
|
let _relayMissesAfterRepair = 0; // 端口修复后仍连不上的轮数 → 3 轮自动重启
|
|
175
|
-
let _relayMisses = 0
|
|
175
|
+
let _relayMisses = 0; // WSL localhost 转发自愈(见 daemon 循环)
|
|
176
|
+
// 「每次开机只 wsl --shutdown 一次」必须跨进程持久化:桌面端自动更新/崩溃重开后内存标记归零,
|
|
177
|
+
// 实测 XS-MASTER 上每隔几分钟就 shutdown 一次,把容器和所有 agent 一起杀掉,还引发 :8008 的
|
|
178
|
+
// 重连风暴(14k TIME_WAIT → 端口耗尽 → 误判不通 → 再 shutdown)的死循环。按开机时间戳存文件。
|
|
179
|
+
const RELAY_RESET_FILE = path.join(os.homedir(), "cicy-ai", "db", "wsl-relay-reset.json");
|
|
180
|
+
const bootStamp = () => Math.round((Date.now() - os.uptime() * 1000) / 60000); // 开机分钟戳(±1 分钟抖动无所谓)
|
|
181
|
+
const relayResetDoneThisBoot = () => { try { const j = JSON.parse(fs.readFileSync(RELAY_RESET_FILE, "utf8")); return Math.abs(Number(j.boot) - bootStamp()) <= 2; } catch { return false; } };
|
|
182
|
+
const markRelayReset = () => { try { fs.mkdirSync(path.dirname(RELAY_RESET_FILE), { recursive: true }); fs.writeFileSync(RELAY_RESET_FILE, JSON.stringify({ boot: bootStamp(), ts: Date.now() })); } catch {} };
|
|
183
|
+
let _relayResetDone = relayResetDoneThisBoot();
|
|
176
184
|
let _unknownStreak = 0, _wslRepairDone = false; // WSL 卡死自愈(见 daemon 循环)
|
|
177
185
|
let _softRetryAt = 0; // 非硬失败(如 docker_install_failed)也退避 2 分钟,别每 35 秒重跑一遍
|
|
178
186
|
// 防重启循环:WSL 始终起不来时不能每次开机都重启。计数存 db/wsl-reboots.json,最多自动重启 2 次
|
|
@@ -271,7 +279,7 @@ function register({ sidecarLogPath } = {}) {
|
|
|
271
279
|
if (inside) {
|
|
272
280
|
_relayMisses += 1;
|
|
273
281
|
if (_relayMisses >= 2 && !_relayResetDone) {
|
|
274
|
-
_relayResetDone = true;
|
|
282
|
+
_relayResetDone = true; markRelayReset();
|
|
275
283
|
auditDestructiveIpc(log, "docker:self-heal-localhost-relay", null, { container: APP_CONTAINER, misses: _relayMisses });
|
|
276
284
|
log.warn("[docker-daemon] container healthy inside WSL but 127.0.0.1:8008 unreachable from Windows → wsl --shutdown once to rebuild the localhost relay");
|
|
277
285
|
try { await appDocker.wslShutdown(); } catch (e) { log.warn(`[docker-daemon] wsl --shutdown failed: ${e.message}`); }
|
package/src/main.js
CHANGED
|
@@ -1095,7 +1095,7 @@ electronApp.whenReady().then(async () => {
|
|
|
1095
1095
|
// Chain them so syncAllLocalTeams only runs after the device exists.
|
|
1096
1096
|
require("./cloud/cloud-client")
|
|
1097
1097
|
.registerDevice()
|
|
1098
|
-
.then(() => require("./backends/local-teams").syncAllLocalTeams())
|
|
1098
|
+
.then(() => require("./backends/local-teams").syncAllLocalTeams({ force: true }))
|
|
1099
1099
|
.catch((e) => log.warn(`[cloud] device/team register (on login) failed: ${e.message}`));
|
|
1100
1100
|
} catch (e) { log.warn(`[cloud] device register hook failed: ${e.message}`); }
|
|
1101
1101
|
}
|
|
@@ -1208,7 +1208,7 @@ electronApp.whenReady().then(async () => {
|
|
|
1208
1208
|
try { sysLang = (electronApp.getLocale && electronApp.getLocale()) || ""; } catch (_) {}
|
|
1209
1209
|
cc.detectAndPersistDeviceInfo({ systemLanguage: sysLang })
|
|
1210
1210
|
.then(() => cc.registerDevice())
|
|
1211
|
-
.then(() => require("./backends/local-teams").syncAllLocalTeams())
|
|
1211
|
+
.then(() => require("./backends/local-teams").syncAllLocalTeams({ force: true }))
|
|
1212
1212
|
.catch((e) => log.warn(`[cloud] device-info/register (on launch) failed: ${e.message}`));
|
|
1213
1213
|
} catch (e) { log.warn(`[cloud] device-info launch hook failed: ${e.message}`); }
|
|
1214
1214
|
|
|
@@ -45,3 +45,20 @@ test("relay still broken after wsl reset → one-shot elevated Windows TCP repai
|
|
|
45
45
|
assert.match(block, /appDocker\.elevatedTcpRepair\(/);
|
|
46
46
|
assert.match(block, /_relayMissesAfterRepair >= 3[\s\S]*?scheduleReboot\(90/);
|
|
47
47
|
});
|
|
48
|
+
|
|
49
|
+
test("cloud title reconcile is rate-limited (no TIME_WAIT storm on Windows)", () => {
|
|
50
|
+
const app = readSrc("workers/render/src/App.jsx");
|
|
51
|
+
assert.match(app, /const VISIBLE_MS = 30_000;/);
|
|
52
|
+
assert.match(app, /const HIDDEN_MS = 120_000;/);
|
|
53
|
+
const lt = readSrc("src/backends/local-teams.js");
|
|
54
|
+
assert.match(lt, /if \(!force && Date\.now\(\) - _lastSyncAllAt < 60_000\) return;/);
|
|
55
|
+
const main = readSrc("src/main.js");
|
|
56
|
+
assert.equal((main.match(/syncAllLocalTeams\(\{ force: true \}\)/g) || []).length, 2);
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
test("the once-per-boot wsl --shutdown relay reset is persisted across desktop restarts", () => {
|
|
60
|
+
const s = readSrc("src/backends/sidecar-ipc.js");
|
|
61
|
+
assert.match(s, /wsl-relay-reset\.json/);
|
|
62
|
+
assert.match(s, /let _relayResetDone = relayResetDoneThisBoot\(\);/);
|
|
63
|
+
assert.match(s, /_relayResetDone = true; markRelayReset\(\);/);
|
|
64
|
+
});
|
|
@@ -597,8 +597,11 @@ export default function App() {
|
|
|
597
597
|
useEffect(() => {
|
|
598
598
|
let timer;
|
|
599
599
|
let stopped = false;
|
|
600
|
-
|
|
601
|
-
|
|
600
|
+
// 3s 对账 = 每分钟几十个新 TCP 连接(每个团队一个云端请求),Windows 上 TIME_WAIT 堆到上万把
|
|
601
|
+
// 动态端口耗尽(实测 15165 个 TIME_WAIT → 连 127.0.0.1:8008 都 EADDRINUSE)。改 30s/120s,
|
|
602
|
+
// 切回可见/聚焦仍立即对账一次。
|
|
603
|
+
const VISIBLE_MS = 30_000;
|
|
604
|
+
const HIDDEN_MS = 120_000;
|
|
602
605
|
|
|
603
606
|
// 一发对账:本地 title 拉进 teams.json + 刷新本地列表 + 重拉云端团队(私有云
|
|
604
607
|
// host_url/名字/状态的同步)。三件事并行。
|