cicy-desktop 2.1.225 → 2.1.226
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
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cicy-desktop",
|
|
3
|
-
"version": "2.1.
|
|
3
|
+
"version": "2.1.226",
|
|
4
4
|
"description": "CiCy - AI-powered operating system browser",
|
|
5
5
|
"main": "src/main.js",
|
|
6
6
|
"bin": {
|
|
@@ -144,11 +144,11 @@
|
|
|
144
144
|
"//optionalDependencies": "(2026-06 回调): mac/linux 改回 native cicy-code(:8008,colima 在 16G mac 上压垮内存)→ 重新内置 cicy-code-<plat> / cicy-mihomo-<plat>,localbin.fromBundle 零网络 seed(npm 仅作更新通道,带 npmmirror→npmjs 回退)。这些由 scripts/sync-runtime-deps.cjs 在 tag-push 时同步到最新版。npm 的 os/cpu 字段保证每个平台只装自己那份。Windows 仍走 docker(WSL :8009),它那份 cicy-code-windows 用不到但 bundle 着无害。",
|
|
145
145
|
"optionalDependencies": {
|
|
146
146
|
"electron": "41.0.3",
|
|
147
|
-
"cicy-code-darwin-x64": "2.3.
|
|
148
|
-
"cicy-code-darwin-arm64": "2.3.
|
|
149
|
-
"cicy-code-linux-x64": "2.3.
|
|
150
|
-
"cicy-code-linux-arm64": "2.3.
|
|
151
|
-
"cicy-code-windows-x64": "2.3.
|
|
147
|
+
"cicy-code-darwin-x64": "2.3.180",
|
|
148
|
+
"cicy-code-darwin-arm64": "2.3.180",
|
|
149
|
+
"cicy-code-linux-x64": "2.3.180",
|
|
150
|
+
"cicy-code-linux-arm64": "2.3.180",
|
|
151
|
+
"cicy-code-windows-x64": "2.3.180",
|
|
152
152
|
"cicy-mihomo-darwin-x64": "1.10.4",
|
|
153
153
|
"cicy-mihomo-darwin-arm64": "1.10.4",
|
|
154
154
|
"cicy-mihomo-linux-x64": "1.10.4",
|
|
@@ -374,4 +374,4 @@ Error generating stack: `+l.message+`
|
|
|
374
374
|
`};function tp(s){return s.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">")}function Ll(s){return tp(s).replace(/\*\*([^*]+)\*\*/g,"<strong>$1</strong>").replace(/`([^`]+)`/g,"<code>$1</code>")}function ym(s){return s.trim().replace(/^\|/,"").replace(/\|$/,"").split("|").map(g=>g.trim())}function ep(s){const g=String(s||"").replace(/\r\n/g,`
|
|
375
375
|
`).split(`
|
|
376
376
|
`),S=[];let d=0;for(;d<g.length;){const j=g[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 D=Math.min(M[1].length,6);S.push(`<h${D}>${Ll(M[2])}</h${D}>`),d++;continue}if(j.trim().startsWith("|")&&d+1<g.length&&/^\s*\|?[\s:|-]+\|?\s*$/.test(g[d+1])&&g[d+1].includes("-")){const D=ym(j);d+=2;const R=[];for(;d<g.length&&g[d].trim().startsWith("|");)R.push(ym(g[d])),d++;let w="<table><thead><tr>";w+=D.map(h=>`<th>${Ll(h)}</th>`).join(""),w+="</tr></thead><tbody>";for(const h of R)w+="<tr>"+h.map(Z=>`<td>${Ll(Z)}</td>`).join("")+"</tr>";w+="</tbody></table>",S.push(w);continue}if(j.trim().startsWith(">")){const D=[];for(;d<g.length&&g[d].trim().startsWith(">");)D.push(g[d].replace(/^\s*>\s?/,"")),d++;S.push(`<blockquote>${D.map(Ll).join("<br/>")}</blockquote>`);continue}if(/^\s*-\s+/.test(j)){const D=[];for(;d<g.length&&/^\s*-\s+/.test(g[d]);)D.push(`<li>${Ll(g[d].replace(/^\s*-\s+/,""))}</li>`),d++;S.push(`<ul>${D.join("")}</ul>`);continue}if(/^\s*\d+\.\s+/.test(j)){const D=[];for(;d<g.length&&/^\s*\d+\.\s+/.test(g[d]);)D.push(`<li>${Ll(g[d].replace(/^\s*\d+\.\s+/,""))}</li>`),d++;S.push(`<ol>${D.join("")}</ol>`);continue}S.push(`<p>${Ll(j)}</p>`),d++}return S.join(`
|
|
377
|
-
`)}const r=(s,g,S)=>{var j,M;const d=D=>S&&typeof D=="string"?D.replace(/\{\{\s*(\w+)\s*\}\}/g,(R,w)=>S[w]!=null?String(S[w]):R):D;try{const D=(M=(j=window.cicyI18n)==null?void 0:j.t)==null?void 0:M.call(j,s,S);return d(D&&D!==s?D:g)}catch{return d(g)}},jn="cicy_token",Uu="cicy_access_token",Ru="cicy_user_id",ql="https://cicy-ai.com",ap=1;async function _i(s){var S,d,j,M,D,R,w,h;const g=`${ql}/dash${s}`;try{if((d=(S=window.cicy)==null?void 0:S.tabs)!=null&&d.openIn){await window.cicy.tabs.openIn(ap,g,"cicy-ai");return}(D=(M=(j=window.cicy)==null?void 0:j.shell)==null?void 0:M.openExternal)==null||D.call(M,g)}catch{try{(h=(w=(R=window.cicy)==null?void 0:R.shell)==null?void 0:w.openExternal)==null||h.call(w,g)}catch{}}}const lo=new Set;let lp=0,xl=[];const vi=new Map;function pm(){lo.forEach(s=>s(xl))}const St={show(s={}){const g=s.id||`t${++lp}`,S=xl.find(M=>M.id===g),d={id:g,status:"running",...S,...s};xl=S?xl.map(M=>M.id===g?d:M):[...xl,d],pm();const j=vi.get(g);return j&&(clearTimeout(j),vi.delete(g)),s.ttl&&vi.set(g,setTimeout(()=>St.dismiss(g),s.ttl)),g},dismiss(s){xl=xl.filter(S=>S.id!==s);const g=vi.get(s);g&&(clearTimeout(g),vi.delete(s)),pm()}};function np(){const[s,g]=v.useState(xl);return v.useEffect(()=>(lo.add(g),()=>{lo.delete(g)}),[]),s.length?u.jsx("div",{className:"toast-host","data-id":"ToastHost",children:s.map(S=>u.jsxs("div",{className:"toast","data-id":`Toast-${S.id}`,"data-status":S.status||"running",children:[u.jsx("button",{type:"button",className:"toast__x","data-id":"Toast-dismiss",onClick:()=>St.dismiss(S.id),"aria-label":"dismiss",children:"×"}),u.jsxs("span",{className:"toast__msg",children:[S.message,Number.isFinite(S.progress)?` ${S.progress}%`:""]}),Number.isFinite(S.progress)&&u.jsx("span",{className:"toast__bar",children:u.jsx("span",{style:{width:`${Math.min(100,S.progress)}%`}})})]},S.id))}):null}const no=new Set;let Ps=0,Kt=null;function Sl(){no.forEach(s=>s(Kt))}function xi(){return new Date().toTimeString().slice(0,8)}const ye={open({teamId:s,fromVer:g,toVer:S,onRetry:d,title:j,kind:M}={}){Kt={teamId:s,title:j||null,fromVer:g||null,toVer:S||null,kind:M||"sidecar",status:"running",phase:"download",progress:null,onInstall:null,logs:[],onRetry:d||null,lastAt:Date.now()},Sl()},setProgress(s){Kt&&(Kt={...Kt,status:"running",progress:s||Kt.progress,lastAt:Date.now()},Sl())},ready({onInstall:s,message:g}={}){if(!Kt)return;const S={id:++Ps,t:xi(),phase:"done",status:"done",message:g||r("updateBanner.readyDrawer","下载完成,点「安装」重启更新")};Kt={...Kt,status:"ready",phase:"done",progress:{...Kt.progress||{},percent:100},onInstall:s||null,minimized:!1,logs:[...Kt.logs,S],lastAt:Date.now()},Sl()},push(s={}){if(!Kt)return;const g={id:++Ps,t:xi(),phase:s.phase||Kt.phase,status:s.status||"running",message:s.message||""};Kt={...Kt,phase:s.phase||Kt.phase,toVer:s.toVer||Kt.toVer,logs:[...Kt.logs,g],lastAt:Date.now()},Sl()},minimize(){Kt&&(Kt={...Kt,minimized:!0},Sl())},restore(){Kt&&(Kt={...Kt,minimized:!1},Sl())},finish({ok:s,message:g}={}){if(!Kt)return;const S=s?"done":"error",d={id:++Ps,t:xi(),phase:"done",status:S,message:g||(s?r("updateDrawer.done","更新完成"):r("updateDrawer.failed","更新失败"))};Kt={...Kt,status:S,phase:"done",minimized:!1,logs:[...Kt.logs,d],lastAt:Date.now()},Sl()},close(){Kt=null,Sl()}},to=["download","swap","done"],gm=s=>({download:r("updateDrawer.phaseDownload","下载"),swap:r("updateDrawer.phaseSwap","切换"),done:r("updateDrawer.phaseDone","完成")})[s]||s;function ip(){var R;const[s,g]=v.useState(Kt);v.useEffect(()=>(no.add(g),()=>{no.delete(g)}),[]);const S=v.useRef(null);v.useEffect(()=>{const w=S.current;w&&(w.scrollTop=w.scrollHeight)},[(R=s==null?void 0:s.logs)==null?void 0:R.length]);const[d,j]=v.useState(!1);if(v.useEffect(()=>{if(!s||s.status!=="running"){j(!1);return}const w=setInterval(()=>j(Date.now()-(s.lastAt||0)>25e3),3e3);return()=>clearInterval(w)},[s==null?void 0:s.lastAt,s==null?void 0:s.status]),!s)return null;const M=s.status==="running",D=to.findIndex(w=>w===s.phase);return s.minimized?u.jsxs("button",{type:"button",className:`drawer-min drawer-min--${s.status}`,"data-id":"UpdateDrawer-restore",onClick:()=>ye.restore(),children:[u.jsx("span",{className:"drawer-min__spark",children:M?u.jsx(Ge,{}):s.status==="done"?"✓":s.status==="reboot"?"⟳":"!"}),u.jsxs("span",{className:"drawer-min__label",children:[s.title||r("updateDrawer.title","更新 cicy-code"),s.toVer?` · v${s.toVer}`:""]})]}):u.jsx("div",{className:"drawer-scrim","data-id":"UpdateDrawer-scrim",onClick:()=>M?ye.minimize():ye.close(),children:u.jsxs("div",{className:"drawer","data-id":"UpdateDrawer","data-status":s.status,onClick:w=>w.stopPropagation(),children:[u.jsxs("div",{className:"drawer__head",children:[u.jsxs("div",{className:"drawer__title",children:[u.jsx("span",{className:`drawer__spark drawer__spark--${s.status}`,children:M?u.jsx(Ge,{}):s.status==="done"?"✓":s.status==="reboot"?"⟳":"!"}),u.jsxs("div",{children:[u.jsx("div",{className:"drawer__h",children:s.title||r("updateDrawer.title","更新 cicy-code")}),u.jsxs("div",{className:"drawer__sub",children:[s.fromVer?`v${s.fromVer}`:r("updateDrawer.current","当前")," → ",s.toVer?`v${s.toVer}`:r("updateDrawer.latest","最新版")]})]})]}),u.jsx("div",{className:"drawer__headbtns",children:u.jsx("button",{type:"button",className:"drawer__x","data-id":"UpdateDrawer-min",title:r("updateDrawer.minimize","最小化"),onClick:()=>ye.minimize(),"aria-label":"minimize",children:"‒"})})]}),s.kind!=="app"&&u.jsx("div",{className:"drawer__steps","data-id":"UpdateDrawer-steps",children:to.map((w,h)=>{const Z=gm(w),A=s.status==="done"||h<D,W=h===D&&M,L=s.status==="error"&&h===D;return u.jsxs("div",{className:`drawer__step${W?" is-active":""}${A?" is-done":""}${L?" is-error":""}`,children:[u.jsx("span",{className:"drawer__step-dot",children:A?"✓":L?"!":h+1}),u.jsx("span",{className:"drawer__step-label",children:Z}),h<to.length-1&&u.jsx("span",{className:"drawer__step-bar"})]},w)})}),s.progress&&(()=>{const w=s.progress,h=Z=>Z?(Z/1048576).toFixed(1):"0";return u.jsxs("div",{className:"drawer__dl","data-id":"UpdateDrawer-dl",children:[u.jsxs("div",{className:"drawer__dl-head",children:[u.jsxs("span",{className:"drawer__dl-pct",children:[w.percent||0,"%"]}),u.jsxs("span",{className:"drawer__dl-stats",children:[w.total?`${h(w.transferred)} / ${h(w.total)} MB`:`${h(w.transferred)} MB`,w.bytesPerSec?` · ${h(w.bytesPerSec)} MB/s`:"",w.etaSec?` · ${r("updateBanner.eta","剩 {{s}}s",{s:w.etaSec})}`:""]})]}),u.jsx("div",{className:"drawer__dl-track",children:u.jsx("span",{className:"drawer__dl-fill",style:{width:`${w.percent||0}%`}})})]})})(),u.jsx("div",{className:"drawer__log","data-id":"UpdateDrawer-log",ref:S,children:s.logs.length===0?u.jsx("div",{className:"drawer__log-empty",children:r("updateDrawer.preparing","准备中…")}):s.logs.map(w=>u.jsxs("div",{className:"drawer__line","data-status":w.status,children:[u.jsx("span",{className:"drawer__t",children:w.t}),u.jsx("span",{className:`drawer__badge drawer__badge--${w.phase}`,children:gm(w.phase)}),u.jsx("span",{className:"drawer__linemsg",children:w.message})]},w.id))}),d&&M&&u.jsx("div",{className:"drawer__hint","data-id":"UpdateDrawer-stuck",children:r("updateDrawer.stuckHint","正在等待新版本就绪,耗时比平常久。可以放到后台继续,完成或失败都会提示。")}),u.jsx("div",{className:"drawer__foot",children:M?u.jsx(u.Fragment,{children:u.jsx("span",{className:"drawer__foot-status",children:s.kind==="app"?r("updateBanner.downloading","正在下载更新")+"…":r("updateDrawer.inProgress","更新进行中…")})}):s.status==="ready"?u.jsxs(u.Fragment,{children:[u.jsx("span",{className:"drawer__foot-status is-done",children:r("updateBanner.readyShort","下载完成")}),u.jsx("button",{type:"button",className:"drawer__btn is-accent","data-id":"UpdateDrawer-install",onClick:()=>s.onInstall&&s.onInstall(),children:r("updateBanner.installBtn","立即安装")}),u.jsx("button",{type:"button",className:"drawer__btn","data-id":"UpdateDrawer-later",onClick:()=>ye.close(),children:r("updateBanner.later","稍后")})]}):s.status==="error"?u.jsxs(u.Fragment,{children:[u.jsx("span",{className:"drawer__foot-status is-error",children:r("updateDrawer.failed","更新失败")}),s.onRetry&&u.jsx("button",{type:"button",className:"drawer__btn is-accent","data-id":"UpdateDrawer-retry",onClick:()=>s.onRetry(),children:r("common.retry","重试")}),u.jsx("button",{type:"button",className:"drawer__btn","data-id":"UpdateDrawer-dismiss",onClick:()=>ye.close(),children:r("common.close","关闭")})]}):u.jsxs(u.Fragment,{children:[u.jsx("span",{className:"drawer__foot-status is-done",children:r("updateDrawer.updatedLatest","已更新到最新")}),u.jsx("button",{type:"button",className:"drawer__btn is-accent","data-id":"UpdateDrawer-finish",onClick:()=>ye.close(),children:r("common.done","完成")})]})})]})})}function up(){const[s,g]=v.useState(void 0);v.useEffect(()=>{var C,Y;if(!((Y=(C=window.cicy)==null?void 0:C.terms)!=null&&Y.status)){g(!0);return}window.cicy.terms.status(Am).then(B=>g(!!(B!=null&&B.accepted))).catch(()=>g(!0))},[]),v.useEffect(()=>{var B,J,et,Vt;const C=document.documentElement;try{C.setAttribute("data-platform",((B=window.cicy)==null?void 0:B.platform)||"linux")}catch{}C.setAttribute("data-fullscreen","0");let Y;try{Y=(Vt=(et=(J=window.cicy)==null?void 0:J.window)==null?void 0:et.onFullscreen)==null?void 0:Vt.call(et,Ct=>C.setAttribute("data-fullscreen",Ct?"1":"0"))}catch{}return()=>{try{Y&&Y()}catch{}}},[]),v.useEffect(()=>{var Y,B;if(!((B=(Y=window.cicy)==null?void 0:Y.docker)!=null&&B.onAppProgress))return;const C=window.cicy.docker.onAppProgress(J=>{!J||J.phase==="open"||(Bt||Et.open({source:"auto"}),(Bt==null?void 0:Bt.source)==="auto"&&(J.phase==="done"&&(J.status==="done"||J.status==="reboot")?Et.finish({ok:J.status==="done",status:J.status==="reboot"?"reboot":void 0,message:J.message}):J.status==="error"?Et.finish({ok:!1,message:J.message}):Et.push(J)))});return()=>{try{C&&C()}catch{}}},[]);const[S,d]=v.useState(()=>Si(jn)),[j,M]=v.useState(()=>Si(Uu)),[D,R]=v.useState(()=>Si(Ru)),[w,h]=v.useState(()=>!Si(jn)),[Z,A]=v.useState(!1),[W,L]=v.useState(!1),[I,V]=v.useState(""),[ht,xt]=v.useState(""),[Jt,dt]=v.useState(!1),[Lt,ut]=v.useState(""),[bt,X]=v.useState(""),[ot,q]=v.useState(null),[Zt,le]=v.useState(null),[Pt,ve]=v.useState(!1),[oe,Qt]=v.useState(""),z=v.useRef(!1),[G,rt]=v.useState(null),[At,Tt]=v.useState(!1),[m,k]=v.useState(!1),[K,F]=v.useState({}),mt=v.useCallback(async()=>{var C,Y,B;try{const J=await((B=(Y=(C=window.cicy)==null?void 0:C.localTeams)==null?void 0:Y.avatars)==null?void 0:B.call(Y));F(J&&typeof J=="object"?J:{})}catch{}},[]),[yt,_t]=v.useState(!1),[ne,Ut]=v.useState(!1),[Qe,$]=v.useState(""),[qt,de]=v.useState(""),[Wt,De]=v.useState(!1),[Te,Le]=v.useState(""),[ke,ca]=v.useState("all"),Me=v.useCallback(async(C,Y)=>{var J,et,Vt,Ct;if(!C)return;if(!((et=(J=window.cicy)==null?void 0:J.cloud)!=null&&et.fetch)){Qt("cloud fetch bridge missing");return}ve(!0),Qt("");const B={Authorization:`Bearer ${C}`};try{const[Pe,qe]=await Promise.all([window.cicy.cloud.fetch(`${ql}/api/user/self`,{headers:B}),window.cicy.cloud.fetch(`${ql}/api/teams`,{headers:B})]);if((qe==null?void 0:qe.status)===401){if(!z.current&&((Ct=(Vt=window.cicy)==null?void 0:Vt.auth)!=null&&Ct.loginStart)){z.current=!0,Qt(r("auth.sessionExpired","会话已过期,正在重新登录…"));try{await window.cicy.auth.loginStart()}catch{}}return}if(qe!=null&&qe.ok){const Ee=JSON.parse(qe.body||"{}");le(Array.isArray(Ee==null?void 0:Ee.teams)?Ee.teams:[])}if(Pe!=null&&Pe.ok)try{const Ee=JSON.parse(Pe.body||"{}");q((Ee==null?void 0:Ee.success)===!1?null:(Ee==null?void 0:Ee.data)||null)}catch{q(null)}else q(null)}catch{Qt("")}finally{ve(!1)}},[]),Ie=v.useRef("");v.useEffect(()=>{Ie.current=S||j||""},[S,j]);const fe=v.useCallback(async()=>{var Y,B;const C=Ie.current;if(!(!C||!((B=(Y=window.cicy)==null?void 0:Y.cloud)!=null&&B.fetch)))try{const J=await window.cicy.cloud.fetch(`${ql}/api/teams`,{headers:{Authorization:`Bearer ${C}`}});if(J!=null&&J.ok){const et=JSON.parse(J.body||"{}");Array.isArray(et==null?void 0:et.teams)&&le(et.teams)}}catch{}},[]),sa=v.useCallback(async(C,Y)=>{var et,Vt;const B=Ie.current,J=String(Y||"").trim();if(!B||!((Vt=(et=window.cicy)==null?void 0:et.cloud)!=null&&Vt.fetch)||!J)return{ok:!1,error:"no session / empty"};try{const Ct=await window.cicy.cloud.fetch(`${ql}/api/teams/${C}`,{method:"PATCH",headers:{Authorization:`Bearer ${B}`,"Content-Type":"application/json"},body:JSON.stringify({title:J})});return Ct!=null&&Ct.ok?(await fe(),{ok:!0}):{ok:!1,error:`${(Ct==null?void 0:Ct.status)||"?"} ${(Ct==null?void 0:Ct.error)||""}`}}catch(Ct){return{ok:!1,error:Ct.message}}},[fe]),pe=v.useCallback(async(C,Y)=>{var et,Vt;const B=Ie.current,J=String(Y||"").trim();if(!B||!((Vt=(et=window.cicy)==null?void 0:et.cloud)!=null&&Vt.fetch)||!J)return{ok:!1,error:"no session / empty"};try{new URL(J)}catch{return{ok:!1,error:"地址格式不对(需 http(s)://…)"}}try{const Ct=await window.cicy.cloud.fetch(`${ql}/api/teams/${C}`,{method:"PATCH",headers:{Authorization:`Bearer ${B}`,"Content-Type":"application/json"},body:JSON.stringify({hostUrl:J})});return Ct!=null&&Ct.ok?(await fe(),{ok:!0}):{ok:!1,error:`${(Ct==null?void 0:Ct.status)||"?"} ${(Ct==null?void 0:Ct.error)||""}`}}catch(Ct){return{ok:!1,error:Ct.message}}},[fe]),H=v.useCallback(async C=>{var B,J;const Y=Ie.current;if(!Y||!((J=(B=window.cicy)==null?void 0:B.cloud)!=null&&J.fetch)){St.show({message:r("common.noAuth","未登录"),status:"error",ttl:5e3});return}try{const et=await window.cicy.cloud.fetch(`${ql}/api/teams/${C.id}`,{method:"DELETE",headers:{Authorization:`Bearer ${Y}`}});et!=null&&et.ok||(et==null?void 0:et.status)===200||(et==null?void 0:et.status)===204?(St.show({message:r("teamCard.deleted","团队已删除"),status:"done",ttl:3e3}),await fe()):St.show({message:`${r("teamCard.deleteFailed","删除失败")}: ${(et==null?void 0:et.status)||"?"} ${(et==null?void 0:et.error)||""}`,status:"error",ttl:7e3})}catch(et){St.show({message:`${r("teamCard.deleteFailed","删除失败")}: ${et.message}`,status:"error",ttl:7e3})}},[fe]);v.useEffect(()=>{const C=S||j;C&&Me(C,D)},[S,j,D,Me]);const P=v.useCallback(async()=>{var C,Y;if((Y=(C=window.cicy)==null?void 0:C.localTeams)!=null&&Y.list){Tt(!0);try{const B=await window.cicy.localTeams.list({refresh:!0});rt(Array.isArray(B)?B:[])}catch{rt([])}finally{Tt(!1),k(!0)}}},[]);async function lt(){if(Wt)return;const C=qt.trim();if(!C){Le(r("teams.urlRequired","请输入地址 URL"));return}try{new URL(C)}catch{Le(r("teams.badUrl","URL 无效(需含 http(s)://)"));return}Le(""),De(!0);try{const Y=await window.cicy.localTeams.add({base_url:C,name:Qe.trim(),failIfExists:!0});if(!Y||Y.ok===!1){Le((Y==null?void 0:Y.error)==="exists"?r("teams.urlExists","该地址已存在"):Wa((Y==null?void 0:Y.error)||"add failed"));return}Ut(!1),$(""),de(""),await P()}catch(Y){Le(Wa((Y==null?void 0:Y.message)||String(Y)))}finally{De(!1)}}const it=v.useCallback(async(C,Y)=>{var J,et;if(!((et=(J=window.cicy)==null?void 0:J.localTeams)!=null&&et.update))return{ok:!1,error:"no_bridge"};let B;try{B=await window.cicy.localTeams.update(C,{name:String(Y||"").trim()||r("localTeams.unnamed","未命名")})}catch(Vt){B={ok:!1,error:(Vt==null?void 0:Vt.message)||String(Vt)}}return await P(),B||{ok:!1,error:"no_result"}},[P]);v.useEffect(()=>{let C,Y=!1;const B=3e3,J=3e4,et=async()=>{var Pe,qe,Ee;try{await((Ee=(qe=(Pe=window.cicy)==null?void 0:Pe.localTeams)==null?void 0:qe.syncCloud)==null?void 0:Ee.call(qe))}catch{}await Promise.all([P(),fe(),mt()])},Vt=()=>{if(Y)return;const Pe=document.visibilityState==="visible";C=setTimeout(async()=>{document.visibilityState==="visible"?await et():await P(),Vt()},Pe?B:J)};et(),Vt();const Ct=()=>{document.visibilityState==="visible"&&et()};return document.addEventListener("visibilitychange",Ct),window.addEventListener("focus",Ct),()=>{Y=!0,clearTimeout(C),document.removeEventListener("visibilitychange",Ct),window.removeEventListener("focus",Ct)}},[P,fe]),v.useEffect(()=>{var Y,B;if(!((B=(Y=window.cicy)==null?void 0:Y.localTeams)!=null&&B.onWebviewRelay))return;const C=window.cicy.localTeams.onWebviewRelay(async({reqId:J,msg:et})=>{let Vt={ok:!1,error:"unknown relay type"};try{(et==null?void 0:et.type)==="localTeams:add"?Vt=await window.cicy.localTeams.add(et.spec||{}):(et==null?void 0:et.type)==="localTeams:remove"?Vt=await window.cicy.localTeams.remove(et.id):(et==null?void 0:et.type)==="localTeams:update"?Vt=await window.cicy.localTeams.update(et.id,et.patch||{}):(et==null?void 0:et.type)==="localTeams:upgrade"?Vt=await window.cicy.localTeams.upgrade(et.id):(et==null?void 0:et.type)==="localTeams:list"&&(Vt={ok:!0,teams:await window.cicy.localTeams.list({refresh:!0})}),P()}catch(Ct){Vt={ok:!1,error:(Ct==null?void 0:Ct.message)||String(Ct)}}try{window.cicy.localTeams.replyWebviewRelay(J,Vt)}catch{}});return()=>{try{C==null||C()}catch{}}},[P]);const Nt=v.useCallback(async C=>{var Y,B;if((B=(Y=window.cicy)==null?void 0:Y.localTeams)!=null&&B.open)try{await window.cicy.localTeams.open(C)}catch{}},[]);v.useEffect(()=>{var Y,B;if(Si(jn)){h(!1);return}if(!((B=(Y=window.cicy)==null?void 0:Y.auth)!=null&&B.getSaved)){h(!1);return}let C=!1;return(async()=>{try{const J=await window.cicy.auth.getSaved();if(C)return;if(J!=null&&J.token){try{localStorage.setItem(jn,J.token)}catch{}if(d(J.token),J.accessToken){try{localStorage.setItem(Uu,J.accessToken)}catch{}M(J.accessToken)}if(J.userId){try{localStorage.setItem(Ru,String(J.userId))}catch{}R(String(J.userId))}}}catch{}finally{C||h(!1)}})(),()=>{C=!0}},[]),v.useEffect(()=>{var C,Y;if((Y=(C=window.cicy)==null?void 0:C.auth)!=null&&Y.onComplete)return window.cicy.auth.onComplete(B=>{if(A(!1),dt(!1),B!=null&&B.error){ut(Wa(B.error));return}if(B!=null&&B.token){z.current=!1,Qt("");try{localStorage.setItem(jn,B.token)}catch{}if(d(B.token),B.accessToken){try{localStorage.setItem(Uu,B.accessToken)}catch{}M(B.accessToken)}if(B.userId){try{localStorage.setItem(Ru,String(B.userId))}catch{}R(String(B.userId))}ut(""),X(B.reused?r("auth.welcomeBack","已恢复你之前的登录"):r("auth.loginSuccess","登录成功")),setTimeout(()=>X(""),3e3)}})},[]);async function Rt(){var C,Y;if(!(W||Z)){if(!((Y=(C=window.cicy)==null?void 0:C.auth)!=null&&Y.loginStart)){ut("auth bridge missing");return}ut(""),L(!0);try{const B=await window.cicy.auth.loginStart();if(!(B!=null&&B.ok)){ut(Wa((B==null?void 0:B.error)||"login start failed"));return}V(B.url||""),A(!0)}catch(B){ut(Wa((B==null?void 0:B.message)||String(B)))}finally{L(!1)}}}async function ie(){var Y,B;if(W)return;if(!((B=(Y=window.cicy)==null?void 0:Y.auth)!=null&&B.emailLoginStart)){ut("auth bridge missing");return}const C=ht.trim();if(!/^[^@\s]+@[^@\s]+\.[^@\s]+$/.test(C)){ut(r("auth.badEmail","请输入有效的邮箱地址"));return}ut(""),L(!0);try{const J=await window.cicy.auth.emailLoginStart(C);if(!(J!=null&&J.ok)){ut(Wa((J==null?void 0:J.error)||"email login failed"));return}dt(!0)}catch(J){ut(Wa((J==null?void 0:J.message)||String(J)))}finally{L(!1)}}function b(){var C,Y,B;try{localStorage.removeItem(jn),localStorage.removeItem(Uu),localStorage.removeItem(Ru)}catch{}try{(B=(Y=(C=window.cicy)==null?void 0:C.auth)==null?void 0:Y.logout)==null||B.call(Y)}catch{}d(null),M(null),R(null),q(null),le(null),ut(""),Qt("")}if(s===void 0)return u.jsxs("div",{className:"shell","data-id":"TermsCheckingSplash",children:[u.jsx("div",{className:"glow","aria-hidden":!0}),u.jsxs("div",{className:"card",children:[u.jsx(ao,{}),u.jsx("div",{className:"spinner-row",children:u.jsx(Ge,{})})]})]});if(!s)return u.jsx(Nm,{onAgree:()=>g(!0)});if(!S&&w)return u.jsxs("div",{className:"shell","data-id":"AuthRestoringSplash",children:[u.jsx("div",{className:"glow","aria-hidden":!0}),u.jsxs("div",{className:"card",children:[u.jsx(ao,{}),u.jsxs("div",{className:"spinner-row",children:[u.jsx(Ge,{}),u.jsx("span",{children:r("auth.restoring","正在恢复登录…")})]})]})]});if(!S)return u.jsxs("div",{className:"shell",children:[u.jsx("div",{className:"glow","aria-hidden":!0}),u.jsxs("div",{className:"card",children:[u.jsx(ao,{}),!Z&&!Jt&&u.jsxs(u.Fragment,{children:[u.jsx("p",{className:"tagline",children:r("auth.tagline","登录以同步你的团队、配置与 AI 助手")}),u.jsx("label",{className:"login-label","data-id":"EmailLoginLabel",htmlFor:"cicy-email-login",children:r("auth.emailLabel","输入邮箱,用邮件链接登录")}),u.jsx("input",{id:"cicy-email-login",type:"email",className:"login-email-input","data-id":"EmailLoginInput",value:ht,onChange:C=>xt(C.target.value),onKeyDown:C=>{C.key==="Enter"&&ie()},placeholder:r("auth.emailPlaceholder","you@example.com"),autoComplete:"email",spellCheck:!1,autoFocus:!0}),u.jsx("button",{className:"btn-primary","data-id":"EmailLoginSubmit",onClick:ie,disabled:W,children:W?u.jsxs(u.Fragment,{children:[u.jsx(Ge,{}),u.jsx("span",{children:r("auth.sending","发送中…")})]}):u.jsxs(u.Fragment,{children:[u.jsx("span",{children:r("auth.emailLogin","发送登录链接")}),u.jsx(Hu,{})]})}),u.jsx("p",{className:"hint",children:r("auth.emailHint","手机上点邮件里的链接,也能登录这台电脑")}),u.jsx("div",{className:"login-divider","data-id":"LoginDivider",children:u.jsx("span",{children:r("auth.or","或")})}),u.jsx("button",{className:"btn-ghost","data-id":"BrowserLoginBtn",onClick:Rt,disabled:W,children:W?r("auth.opening","打开中…"):r("auth.browserLogin","用浏览器登录(Google / SSO,仅同一台电脑)")})]}),Jt&&u.jsxs(u.Fragment,{children:[u.jsx("p",{className:"tagline","data-id":"EmailSentTagline",children:r("auth.emailSentTagline","登录邮件已发送")}),u.jsxs("p",{className:"hint","data-id":"EmailSentHint",style:{textAlign:"center"},children:[r("auth.emailSentHint","到邮箱打开链接即可(手机、电脑都行),这里会自动登录。"),u.jsx("br",{}),ht]}),u.jsxs("div",{className:"spinner-row",children:[u.jsx(Ge,{}),u.jsx("span",{children:r("auth.emailWaiting","等待确认…")})]}),u.jsx("button",{className:"btn-ghost","data-id":"EmailSentCancel",onClick:()=>{var C,Y,B;(B=(Y=(C=window.cicy)==null?void 0:C.auth)==null?void 0:Y.emailLoginCancel)==null||B.call(Y),dt(!1)},children:r("auth.cancel","取消")})]}),Z&&u.jsxs(u.Fragment,{children:[u.jsx("p",{className:"tagline",children:r("auth.waitingTagline","已在浏览器打开登录页,等待你完成…")}),u.jsxs("div",{className:"spinner-row",children:[u.jsx(Ge,{}),u.jsx("span",{children:r("auth.waitingCallback","等待回调")})]}),I&&u.jsxs("div",{className:"login-fallback","data-id":"LoginUrlFallback",style:{marginTop:10,textAlign:"center"},children:[u.jsx("p",{className:"hint",style:{marginBottom:6},children:r("auth.browserNotOpened","浏览器没自动打开?")}),u.jsx("button",{className:"btn-ghost","data-id":"LoginUrlFallback-open",onClick:()=>{var C,Y,B;try{(B=(Y=(C=window.cicy)==null?void 0:C.shell)==null?void 0:Y.openExternal)==null||B.call(Y,I)}catch{}},children:r("auth.openManually","手动打开登录页")}),u.jsx("button",{className:"btn-ghost","data-id":"LoginUrlFallback-copy",onClick:()=>{var C;try{(C=navigator.clipboard)==null||C.writeText(I),X(r("auth.linkCopied","链接已复制,粘到浏览器打开")),setTimeout(()=>X(""),2500)}catch{}},children:r("auth.copyLink","复制链接")}),u.jsx("p",{className:"hint","data-id":"LoginUrlFallback-url",style:{wordBreak:"break-all",marginTop:6,fontSize:11,opacity:.7,userSelect:"text"},children:I})]}),u.jsx("button",{className:"btn-ghost",onClick:()=>{var C,Y,B;(B=(Y=(C=window.cicy)==null?void 0:C.auth)==null?void 0:Y.loginCancel)==null||B.call(Y),A(!1),V("")},children:r("auth.cancel","取消")})]}),Lt&&u.jsx("div",{className:"error",children:Lt})]})]});const Q=(G||[]).find(C=>xm(C.base_url))||null,tt=Q&&Q.cloud_team_id?(Zt||[]).find(C=>String(C.teamId||C.id)===String(Q.cloud_team_id)):null,at=C=>{if(!C)return null;const Y=(Zt||[]).find(B=>String(B.teamId||B.id)===String(C));return Y&&Y.code||null},ct=(G||[]).filter(C=>uo(C.base_url)),pt=(G||[]).filter(C=>!uo(C.base_url)&&!xm(C.base_url)),zt=ct.length,ze=pt.length,oa=(Zt||[]).filter(C=>!C.is_local&&C.kind!=="local"&&(C.kind==="private"||C.team_kind==="personal")),Ca=oa.length,$t=ke==="all"||ke==="local",Ce=ke==="all"||ke==="custom",Na=ke==="all"||ke==="cloud",ra=G===null&&Zt===null;return u.jsxs("div",{className:"shell shell--app",children:[u.jsx("div",{className:"glow glow--app","aria-hidden":!0}),u.jsxs("div",{className:"shell__left",children:[u.jsx(op,{me:ot,welcome:bt,onLogout:b,mitmTeam:ct.length>0?ct[0]:null}),u.jsx(pp,{}),u.jsxs("main",{className:"main",children:[u.jsxs("div",{className:"app__tabsrow",children:[u.jsx("div",{className:"app__tabs",children:[{k:"all",label:r("teamFilter.all","全部"),n:zt+ze+Ca},{k:"local",label:r("teamFilter.local","本地"),n:zt},{k:"cloud",label:r("teamFilter.cloud","私有云"),n:Ca},{k:"custom",label:r("teamFilter.custom","自定义"),n:ze}].map(({k:C,label:Y,n:B})=>u.jsxs("button",{type:"button",className:`app__tab ${ke===C?"is-active":""}`,onClick:()=>ca(C),children:[Y,u.jsx("span",{className:"app__tab-count",children:B})]},C))}),u.jsxs("div",{"data-id":"AddTeamWrap",style:{position:"relative"},children:[u.jsxs("button",{type:"button","data-id":"AddTeamButton",className:"app__add-team",title:r("teams.addHint","添加团队"),onClick:()=>_t(C=>!C),children:["+ ",r("teams.add","新加团队")]}),yt&&u.jsxs(u.Fragment,{children:[u.jsx("div",{onClick:()=>_t(!1),style:{position:"fixed",inset:0,zIndex:40}}),u.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:[u.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:()=>{_t(!1),Le(""),Ut(!0)},children:[u.jsx("div",{style:{fontSize:13,fontWeight:600},children:r("teams.addCustom","自定义团队")}),u.jsx("div",{style:{fontSize:11,opacity:.6,marginTop:2},children:r("teams.addCustomSub","手动输入地址和名称")})]}),u.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:()=>{_t(!1),_i("?tab=private")},children:[u.jsx("div",{style:{fontSize:13,fontWeight:600},children:r("teams.addPrivate","私有云团队")}),u.jsx("div",{style:{fontSize:11,opacity:.6,marginTop:2},children:r("teams.addPrivateSub","去云端团队中心添加")})]})]})]})]})]}),ne&&u.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:C=>{!Wt&&C.target===C.currentTarget&&Ut(!1)},children:u.jsxs("div",{onClick:C=>C.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:[u.jsx("div",{style:{fontSize:16,fontWeight:700,marginBottom:4},children:r("teams.customTitle","添加自定义团队")}),u.jsx("div",{style:{fontSize:12,opacity:.6,marginBottom:16},children:r("teams.customSub","连接到一个已有的 cicy-code 地址")}),u.jsx("label",{style:{display:"block",fontSize:12,opacity:.75,marginBottom:6},children:r("teams.customNameLabel","名称")}),u.jsx("input",{"data-id":"CustomTeamModal-title",className:"login-email-input",style:{width:"100%",marginBottom:14},value:Qe,onChange:C=>$(C.target.value),placeholder:r("teams.customNamePlaceholder","我的团队"),spellCheck:!1,autoFocus:!0}),u.jsx("label",{style:{display:"block",fontSize:12,opacity:.75,marginBottom:6},children:r("teams.customUrlLabel","地址 URL")}),u.jsx("input",{"data-id":"CustomTeamModal-url",className:"login-email-input",style:{width:"100%",marginBottom:6},value:qt,onChange:C=>de(C.target.value),placeholder:"https://example.com:8008",spellCheck:!1,onKeyDown:C=>{C.key==="Enter"&<()}}),Te&&u.jsx("div",{className:"error",style:{marginTop:10},children:Te}),u.jsxs("div",{className:"modal-actions",children:[u.jsx("button",{type:"button",className:"btn-ghost","data-id":"CustomTeamModal-cancel",disabled:Wt,onClick:()=>Ut(!1),children:r("common.cancel","取消")}),u.jsx("button",{type:"button",className:"btn-primary","data-id":"CustomTeamModal-submit",disabled:Wt,onClick:lt,children:Wt?r("teams.adding","添加中…"):r("teams.addAction","添加")})]})]})}),oe&&u.jsxs("div",{className:"error",style:{marginBottom:12},children:[r("common.cloud","云端"),": ",oe,u.jsx("button",{className:"btn-ghost",style:{marginLeft:8},onClick:()=>Me(S||j,D),children:r("common.retry","重试")})]}),u.jsxs("div",{className:"app__grid",children:[ra&&[0,1,2].map(C=>u.jsx(gp,{},"skc"+C)),!ra&&$t&&ct.map(C=>u.jsx(Sm,{team:C,cloudCode:at(C.cloud_team_id),onOpen:()=>Nt(C.id),onRename:it,onRefresh:P},"local:"+C.id)),!ra&&$t&&u.jsx(hp,{dockerTeam:Q,onOpen:async()=>{var C,Y,B;try{const J=await((B=(Y=(C=window.cicy)==null?void 0:C.docker)==null?void 0:Y.appOpen)==null?void 0:B.call(Y));J!=null&&J.ok||St.show({id:"docker-open",status:"error",ttl:6e3,message:r("docker.openNoToken","服务还没就绪,稍等几秒再点「打开」(或用卡片菜单「重启」)。")})}catch(J){console.warn("[DockerCard] open",J)}},cloudTitle:tt==null?void 0:tt.title,cloudCode:tt==null?void 0:tt.code,onRename:Q!=null&&Q.cloud_team_id?(C=>sa(Q.cloud_team_id,C)):void 0,onRefresh:P}),Ce&&pt.map(C=>u.jsx(Sm,{team:C,cloudCode:at(C.cloud_team_id),onOpen:()=>Nt(C.id),onRename:it,onRefresh:P},"custom:"+C.id)),Na&&oa.map(C=>u.jsx(yp,{team:C,onOpen:()=>{var B,J,et;const Y=C.kind==="private"?C.host_url:C.workspace_url||C.workspace_direct_url;Y&&((et=(J=(B=window.cicy)==null?void 0:B.tabs)==null?void 0:J.open)==null||et.call(J,Y,C.name||C.title||"",K[C.id]||"",!0,C.id))},avatar:K[C.id]||"",onAvatar:mt,onRename:sa,onEditUrl:pe,onDelete:H},"cloud:"+C.id))]}),!Pt&&!oe&&Zt&&Zt.length===0&&!(G!=null&&G.length)&&u.jsx("div",{className:"empty",style:{marginTop:14},children:r("teams.emptyHint","还没有团队 — 安装本地 cicy-code 起一个本地 team,或在云端创建。")})]})]}),u.jsx(np,{}),u.jsx(ip,{}),u.jsx(mp,{})]})}function cp({onClose:s}){const[g,S]=v.useState(null),[d,j]=v.useState(""),[M,D]=v.useState(!1),[R,w]=v.useState(""),h=typeof window<"u"&&window.cicy&&window.cicy.trustedOrigins||null,Z=v.useCallback(async()=>{try{S(h&&await h.list()||[])}catch{S([])}},[h]);v.useEffect(()=>{Z()},[Z]);const A=async()=>{const I=d.trim();if(!(!I||M||!h)){D(!0),w("");try{const V=await h.add(I);V&&V.ok===!1?w(V.error||r("trustedSites.addFailed","添加失败")):(j(""),S(V&&V.origins||await h.list()))}catch(V){w(String(V&&V.message||V))}finally{D(!1)}}},W=async I=>{if(!(M||!h)){D(!0),w("");try{const V=await h.remove(I);V&&V.ok===!1?w(V.error||r("trustedSites.removeFailed","删除失败")):S(V&&V.origins||await h.list())}catch(V){w(String(V&&V.message||V))}finally{D(!1)}}},L={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:I=>({flex:1,fontFamily:"ui-monospace,SFMono-Regular,Menlo,monospace",fontSize:13,color:I?"#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 xa.createPortal(u.jsx("div",{style:L.overlay,onMouseDown:I=>{I.target===I.currentTarget&&s()},"data-id":"TrustedSitesModal",children:u.jsxs("div",{style:L.card,onClick:I=>I.stopPropagation(),children:[u.jsxs("div",{style:L.head,children:[u.jsx("h2",{style:L.title,children:r("trustedSites.title","受信任站点")}),u.jsx("button",{type:"button",style:L.x,onClick:s,"aria-label":"close",children:"✕"})]}),u.jsx("div",{style:L.warn,children:r("trustedSites.warn","⚠ 列表中的站点可以在你的电脑上执行命令(exec)。只添加你完全信任的地址。")}),u.jsxs("div",{style:L.addRow,children:[u.jsx("input",{"data-id":"trusted-sites-input",style:L.input,value:d,onChange:I=>j(I.target.value),onKeyDown:I=>{I.key==="Enter"&&A()},placeholder:r("trustedSites.placeholder","添加站点,如 app.cicy-ai.com 或 my-cloud.example.org")}),u.jsx("button",{type:"button","data-id":"trusted-sites-add",style:{...L.addBtn,opacity:M||!d.trim()?.5:1},onClick:A,disabled:M||!d.trim(),children:r("trustedSites.add","添加")})]}),R&&u.jsx("div",{style:L.err,children:R}),u.jsx("div",{style:L.listWrap,children:g===null?u.jsx("div",{style:L.muted,children:r("trustedSites.loading","加载中…")}):g.length===0?u.jsx("div",{style:L.muted,children:r("trustedSites.empty","暂无")}):g.map(I=>u.jsxs("div",{style:L.row,"data-id":"trusted-sites-row",children:[u.jsx("span",{style:L.host(I.builtin),children:I.host}),I.builtin?u.jsx("span",{style:L.tag,children:r("trustedSites.builtin","系统")}):u.jsx("button",{type:"button",style:L.rm,onClick:()=>W(I.host),disabled:M,children:r("trustedSites.remove","删除")})]},I.host))})]})}),document.body)}function sp({onClose:s}){const[g,S]=v.useState(null),[d,j]=v.useState(""),[M,D]=v.useState(""),[R,w]=v.useState(!1),h=typeof window<"u"&&window.cicy&&window.cicy.rpcAudit||null,Z=v.useCallback(async()=>{w(!0),j("");try{const q=h&&await h.tail(400);!q||q.ok===!1?(j(q&&q.error||r("audit.loadFailed","读取失败")),S([])):(S(q.entries||[]),D(q.path||""))}catch(q){j(String(q&&q.message||q)),S([])}finally{w(!1)}},[h]);v.useEffect(()=>{Z()},[Z]);const[A,W]=v.useState("all"),[L,I]=v.useState(""),V=q=>{try{return new Date(q).toLocaleString()}catch{return q||""}},ht=q=>{if(q.kind==="auth"){const Zt=/deny/.test(q.decision||"");return{text:q.decision||"auth",color:Zt?"#fca5a5":"#86efac",bg:Zt?"rgba(239,68,68,.14)":"rgba(34,197,94,.14)"}}if(q.kind==="rpc"){const Zt=q.ok!==!1&&!q.error;return{text:Zt?"ok":"err",color:Zt?"#86efac":"#fca5a5",bg:Zt?"rgba(34,197,94,.14)":"rgba(239,68,68,.14)"}}return{text:q.kind||"log",color:"#a1a1aa",bg:"rgba(255,255,255,.06)"}},xt=q=>q.kind==="auth"?`${q.gate||""}${q.decision?" · "+q.decision:""}`:q.kind==="rpc"?`${q.tool||""}${q.dangerous?" ⚠":""}`:q.kind||"",Jt=q=>q.error||q.args||(q.kind==="rpc"?q.channel:"")||"",dt=g||[],Lt=L.trim().toLowerCase(),ut=dt.filter(q=>A!=="all"&&q.kind!==A?!1:Lt?[q.origin,q.host,q.tool,q.gate,q.decision,q.channel,q.args,q.error,q.kind].filter(Boolean).join(" ").toLowerCase().includes(Lt):!0),bt="186px 104px minmax(160px,1.1fr) minmax(150px,1.1fr) minmax(220px,1.8fr)",X={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:q=>({background:q?"rgba(255,255,255,.14)":"transparent",border:"1px solid rgba(255,255,255,.12)",borderRadius:999,padding:"6px 16px",color:q?"#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:bt,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:bt,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:q=>({justifySelf:"start",fontSize:11.5,color:q.color,background:q.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}},ot=q=>u.jsx("div",{children:q});return xa.createPortal(u.jsx("div",{style:X.overlay,onMouseDown:q=>{q.target===q.currentTarget&&s()},"data-id":"AuditLogModal",children:u.jsxs("div",{style:X.card,onClick:q=>q.stopPropagation(),children:[u.jsxs("div",{style:X.head,children:[u.jsxs("div",{style:X.titleWrap,children:[u.jsx("h2",{style:X.title,children:r("audit.title","审计日志")}),M&&u.jsx("p",{style:X.subtitle,children:M})]}),u.jsxs("span",{style:X.count,children:[r("audit.count","共")," ",ut.length,A!=="all"||Lt?` / ${dt.length}`:""]}),u.jsx("button",{type:"button","data-id":"audit-refresh",style:{...X.refresh,opacity:R?.5:1},onClick:Z,disabled:R,children:r("audit.refresh","刷新")}),u.jsx("button",{type:"button",style:X.x,onClick:s,"aria-label":"close",children:"✕"})]}),u.jsxs("div",{style:X.toolbar,children:[u.jsxs("div",{style:X.chips,children:[u.jsx("button",{type:"button",style:X.chip(A==="all"),onClick:()=>W("all"),children:r("audit.all","全部")}),u.jsx("button",{type:"button",style:X.chip(A==="rpc"),onClick:()=>W("rpc"),children:r("audit.rpc","RPC 调用")}),u.jsx("button",{type:"button",style:X.chip(A==="auth"),onClick:()=>W("auth"),children:r("audit.auth","授权决定")})]}),u.jsx("input",{"data-id":"audit-search",style:X.search,value:L,onChange:q=>I(q.target.value),placeholder:r("audit.search","搜索来源 / 工具 / 命令…")})]}),d&&u.jsx("div",{style:X.err,children:d}),u.jsxs("div",{style:X.tableWrap,children:[u.jsxs("div",{style:X.theadRow,children:[ot(r("audit.colTime","时间")),ot(r("audit.colType","类型")),ot(r("audit.colSource","来源")),ot(r("audit.colOp","操作")),ot(r("audit.colDetail","详情"))]}),g===null?u.jsx("div",{style:X.muted,children:r("audit.loading","加载中…")}):ut.length===0?u.jsx("div",{style:X.muted,children:dt.length===0?r("audit.empty","暂无审计记录"):r("audit.noMatch","无匹配记录")}):ut.map((q,Zt)=>{const le=ht(q);return u.jsxs("div",{style:X.row,"data-id":"audit-row",children:[u.jsx("span",{style:X.time,children:V(q.ts)}),u.jsx("span",{style:X.badge(le),children:le.text}),u.jsx("span",{style:X.cell,children:q.origin||q.host||"—"}),u.jsx("span",{style:X.cell,children:xt(q)||"—"}),u.jsx("span",{style:X.detail,children:Jt(q)||"—"})]},Zt)})]})]})}),document.body)}function op({me:s,welcome:g,onLogout:S,mitmTeam:d}){const j=(s==null?void 0:s.display_name)||(s==null?void 0:s.username)||"…",M=j.slice(0,1).toUpperCase(),[D,R]=v.useState(!1),[w,h]=v.useState(!1),[Z,A]=v.useState(!1),[W,L]=v.useState(!1),[I,V]=v.useState(!1),[ht,xt]=v.useState(""),Jt=v.useRef(null);v.useEffect(()=>{var bt,X,ot;let ut=!0;return(ot=(X=(bt=window.cicy)==null?void 0:bt.app)==null?void 0:X.getVersion)==null||ot.call(X).then(q=>{ut&&xt(typeof q=="string"?q:String((q==null?void 0:q.desktop)||""))}).catch(()=>{}),()=>{ut=!1}},[]),v.useEffect(()=>{if(!D)return;const ut=bt=>{Jt.current&&!Jt.current.contains(bt.target)&&R(!1)};return document.addEventListener("mousedown",ut),()=>document.removeEventListener("mousedown",ut)},[D]);const dt=ut=>{_i(ut),R(!1)},Lt=async()=>{var ut,bt,X;R(!1),V(!0),St.show({id:"app-update",message:r("updateBanner.checking","正在检查更新…"),status:"running"});try{const ot=await((X=(bt=(ut=window.cicy)==null?void 0:ut.app)==null?void 0:bt.checkUpdate)==null?void 0:X.call(bt));(ot==null?void 0:ot.status)==="available"?St.show({id:"app-update",message:r("updateBanner.available","发现新版本 v{{v}}",{v:ot.version}),status:"done",ttl:4e3}):(ot==null?void 0:ot.status)==="up-to-date"?St.show({id:"app-update",message:r("updateBanner.upToDate","已是最新版本 v{{v}}",{v:ot.version||ot.current}),status:"done",ttl:3e3}):St.show({id:"app-update",message:r("updateBanner.error","更新失败")+(ot!=null&&ot.error?`:${ot.error}`:""),status:"error",ttl:5e3})}catch(ot){St.show({id:"app-update",message:ot.message,status:"error",ttl:5e3})}finally{V(!1)}};return u.jsxs(u.Fragment,{children:[u.jsx("header",{className:"topbar",children:u.jsxs("div",{className:"user-chip","data-id":"UserChip",ref:Jt,children:[g&&u.jsx("span",{className:"welcome",children:g}),s?u.jsxs("button",{type:"button","data-id":"UserChip-trigger",className:`user-chip__trigger${D?" is-open":""}`,onClick:()=>R(ut=>!ut),children:[u.jsx("div",{className:"avatar",children:M}),u.jsx("span",{className:"user-name",children:j}),u.jsx("span",{className:"user-chip__caret","aria-hidden":!0,children:"▾"})]}):u.jsxs("div",{className:"user-chip__trigger user-chip__trigger--skel","data-id":"UserChip-skeleton","aria-hidden":!0,children:[u.jsx("div",{className:"skel skel--avatar"}),u.jsx("div",{className:"skel skel--name"})]}),D&&u.jsxs("div",{className:"user-chip__menu","data-id":"UserChip-menu",role:"menu",children:[u.jsx("button",{type:"button","data-id":"UserChip-wallet",className:"user-chip__menu-item",onClick:()=>dt("?view=wallet"),children:r("userMenu.wallet","我的钱包")}),u.jsx("button",{type:"button","data-id":"UserChip-billing",className:"user-chip__menu-item",onClick:()=>dt("?view=usage"),children:r("userMenu.billing","我的账单")}),u.jsx("button",{type:"button","data-id":"UserChip-trusted-sites",className:"user-chip__menu-item",onClick:()=>{R(!1),h(!0)},children:r("trustedSites.menu","受信任站点")}),u.jsx("button",{type:"button","data-id":"UserChip-audit-log",className:"user-chip__menu-item",onClick:()=>{R(!1),A(!0)},children:r("audit.menu","审计日志")}),u.jsx("button",{type:"button","data-id":"UserChip-terms",className:"user-chip__menu-item",onClick:()=>{R(!1),L(!0)},children:r("firstRunTerms.menu","用户协议")}),u.jsx("button",{type:"button","data-id":"UserChip-check-update",className:"user-chip__menu-item",disabled:I,onClick:Lt,children:I?r("updateBanner.checkingShort","检查中…"):r("updateBanner.checkBtn","检查更新")}),!1,u.jsx("div",{className:"user-chip__menu-sep","aria-hidden":!0}),u.jsx("button",{type:"button","data-id":"UserChip-logout",className:"user-chip__menu-item is-danger",onClick:()=>{R(!1),S()},children:r("userMenu.logout","退出")}),u.jsxs("div",{className:"user-chip__menu-version","data-id":"UserChip-version",children:["CiCy Desktop ",ht?`v${ht}`:"…"]})]})]})}),w&&u.jsx(cp,{onClose:()=>h(!1)}),Z&&u.jsx(sp,{onClose:()=>A(!1)}),W&&u.jsx(Nm,{onClose:()=>L(!1)})]})}function Nm({onAgree:s,onClose:g}){var I;const[S,d]=v.useState(!1),[j,M]=v.useState(!1),D=(((I=window.cicyI18n)==null?void 0:I.locale)||"en").startsWith("zh")?"zh-CN":"en",R=(V,ht)=>r(`firstRunTerms.${V}`,ht),w=!!g,h=v.useMemo(()=>ep(Py(D)),[D]),Z=V=>{const ht=V.currentTarget;ht.scrollHeight-ht.scrollTop-ht.clientHeight<24&&d(!0)},A=v.useRef(null);v.useEffect(()=>{const V=A.current;V&&V.scrollHeight<=V.clientHeight+24&&d(!0)},[]);const W=async()=>{var V,ht,xt;if(!(j||!S)){M(!0);try{await((xt=(ht=(V=window.cicy)==null?void 0:V.terms)==null?void 0:ht.agree)==null?void 0:xt.call(ht,Am)),s==null||s()}catch{s==null||s()}}},L=()=>{var V,ht,xt;try{(xt=(ht=(V=window.cicy)==null?void 0:V.terms)==null?void 0:ht.decline)==null||xt.call(ht)}catch{}};return u.jsxs("div",{className:w?"terms-gate terms-gate--review":"shell terms-gate","data-id":"FirstRunTermsGate",style:w?{position:"fixed",inset:0,zIndex:1e3,background:"rgba(8,9,14,.72)",backdropFilter:"blur(4px)"}:void 0,onClick:w?V=>{V.target===V.currentTarget&&g()}:void 0,children:[u.jsx("div",{className:"glow","aria-hidden":!0}),u.jsxs("div",{className:"terms-gate__panel",children:[u.jsx("h1",{className:"terms-gate__title","data-id":"FirstRunTermsGate-title",children:R("title","用户协议与授权说明")}),u.jsx("p",{className:"terms-gate__subtitle",children:R("subtitle","使用 CiCy Desktop 前,请阅读并同意以下条款")}),u.jsx("div",{className:"terms-gate__body",ref:A,onScroll:Z,"data-id":"FirstRunTermsGate-body",children:u.jsx("div",{className:"terms-md","data-id":"FirstRunTermsGate-md",dangerouslySetInnerHTML:{__html:h}})}),w?u.jsx("div",{className:"terms-gate__actions",children:u.jsx("button",{"data-id":"FirstRunTermsGate-close",className:"terms-gate__btn",onClick:g,children:R("close","关闭")})}):u.jsxs(u.Fragment,{children:[!S&&u.jsx("div",{className:"terms-gate__scrollhint","data-id":"FirstRunTermsGate-scrollhint",children:R("scrollHint","请阅读至底部以继续")}),u.jsxs("div",{className:"terms-gate__actions",children:[u.jsx("button",{"data-id":"FirstRunTermsGate-decline",className:"terms-gate__btn terms-gate__btn--ghost",onClick:L,children:R("decline","不同意并退出")}),u.jsx("button",{"data-id":"FirstRunTermsGate-agree",className:"terms-gate__btn",disabled:!S||j,title:S?"":R("mustAgree","未同意则无法使用本软件。"),onClick:W,children:R("agree","同意并继续")})]})]})]})]})}const io=new Set;let bm=0,Bt=null;function zn(){io.forEach(s=>s(Bt))}const Et={open({onRetry:s,kind:g,source:S}={}){Bt={status:"running",phase:"install-docker",kind:g||"install",source:S||"op",logs:[],bars:{},minimized:!1,onRetry:s||null,lastAt:Date.now()},zn()},minimize(){Bt&&(Bt={...Bt,minimized:!0},zn())},restore(){Bt&&(Bt={...Bt,minimized:!1},zn())},push(s={}){var D;if(!Bt)return;const g=s.phase==="health"?"container":s.phase||Bt.phase,S={...Bt,phase:g,lastAt:Date.now()},d=Number.isFinite(s.progress),j=g==="install-docker"||g==="image";if(j&&(d||s.dest||s.url)){const R=((D=Bt.bars)==null?void 0:D[g])||{},w=d?s.progress:s.status==="skip"||s.status==="done"?100:R.progress;S.bars={...Bt.bars,[g]:{progress:w,received:s.received??R.received,total:s.total??R.total,url:s.url||R.url,dest:s.dest||R.dest}}}if(!(s.status==="running"&&d&&j)){const R=Bt.logs[Bt.logs.length-1],w=s.status||"running",h=s.message||"";if(!(R&&R.phase===g&&R.status===w&&R.message===h)){const Z={id:++bm,t:xi(),phase:g,status:w,message:h};S.logs=[...Bt.logs,Z]}}Bt=S,zn()},finish({ok:s,message:g,status:S}={}){if(!Bt||Bt.status!=="running")return;const d=S||(s?"done":"error"),j=d==="error"?Bt.phase:"done",M={id:++bm,t:xi(),phase:j,status:d,message:g||(s?"完成":"失败")};Bt={...Bt,status:d,phase:j,minimized:!1,logs:[...Bt.logs,M],lastAt:Date.now()},zn()},close(){Bt=null,zn()}},eo=[["install-docker","准备环境"],["image","下载运行环境"],["container","启动服务"],["done","完成"]],rp={"install-docker":"准备",image:"下载",container:"启动",health:"启动",done:"完成",open:"打开"},dp={"install-docker":"Docker Desktop",image:"基础镜像"};function vm(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 fp({phaseKey:s,bar:g}){const S=Number.isFinite(g==null?void 0:g.progress)?Math.max(0,Math.min(100,g.progress)):0,d=S>=100;return u.jsxs("div",{className:"dlbar","data-id":`DockerDrawer-dlbar-${s}`,children:[u.jsxs("div",{className:"dlbar__head",children:[u.jsx("span",{className:"dlbar__name",children:dp[s]||s}),u.jsxs("span",{className:"dlbar__pct",children:[S,"%",g!=null&&g.total?` · ${vm(g.received)} / ${vm(g.total)}`:""]})]}),u.jsx("div",{className:"dlbar__track",children:u.jsx("div",{className:`dlbar__fill${d?" is-done":""}`,style:{width:`${S}%`}})}),(g==null?void 0:g.url)&&u.jsxs("div",{className:"dlbar__url",title:g.url,children:[u.jsx("span",{className:"dlbar__urlk",children:"源"})," ",g.url]}),(g==null?void 0:g.dest)&&u.jsxs("div",{className:"dlbar__url",title:g.dest,children:[u.jsx("span",{className:"dlbar__urlk",children:"存"})," ",g.dest]})]})}function mp(){var w;const[s,g]=v.useState(Bt);v.useEffect(()=>(io.add(g),()=>{io.delete(g)}),[]);const S=v.useRef(null);if(v.useEffect(()=>{const h=S.current;h&&(h.scrollTop=h.scrollHeight)},[(w=s==null?void 0:s.logs)==null?void 0:w.length]),!s)return null;const d=s.status==="running",j=s.kind==="open",M=eo.findIndex(([h])=>h===s.phase),D=j?[]:["install-docker","image"].filter(h=>{var Z;return(Z=s.bars)==null?void 0:Z[h]}),R=j?r("docker.openTitle","打开 Docker 团队"):r("docker.setupTitle","安装 Docker cicy-code");if(s.minimized){const h=D.map(A=>{var W;return(W=s.bars[A])==null?void 0:W.progress}).filter(Number.isFinite),Z=h.length?Math.round(h.reduce((A,W)=>A+W,0)/h.length):null;return u.jsxs("button",{type:"button",className:`drawer-min drawer-min--${s.status}`,"data-id":"DockerDrawer-restore",onClick:()=>Et.restore(),children:[u.jsx("span",{className:"drawer-min__spark",children:d?u.jsx(Ge,{}):s.status==="done"?"✓":s.status==="reboot"?"⟳":"!"}),u.jsxs("span",{className:"drawer-min__label",children:[R,Z!=null?` · ${Z}%`:""]})]})}return u.jsx("div",{className:"drawer-scrim","data-id":"DockerDrawer-scrim",onClick:()=>d?Et.minimize():Et.close(),children:u.jsxs("div",{className:"drawer","data-id":"DockerDrawer","data-status":s.status,onClick:h=>h.stopPropagation(),children:[u.jsxs("div",{className:"drawer__head",children:[u.jsxs("div",{className:"drawer__title",children:[u.jsx("span",{className:`drawer__spark drawer__spark--${s.status}`,children:d?u.jsx(Ge,{}):s.status==="done"?"✓":s.status==="reboot"?"⟳":"!"}),u.jsxs("div",{children:[u.jsx("div",{className:"drawer__h",children:R}),u.jsx("div",{className:"drawer__sub",children:"127.0.0.1:8008"})]})]}),u.jsx("div",{className:"drawer__headbtns",children:u.jsx("button",{type:"button",className:"drawer__x","data-id":"DockerDrawer-min",title:r("common.minimize","最小化"),onClick:()=>Et.minimize(),"aria-label":"minimize",children:"‒"})})]}),!j&&u.jsx("div",{className:"drawer__steps","data-id":"DockerDrawer-steps",children:eo.map(([h,Z],A)=>{const W=s.status==="done"||M>=0&&A<M,L=A===M&&d,I=s.status==="error"&&A===M;return u.jsxs("div",{className:`drawer__step${L?" is-active":""}${W?" is-done":""}${I?" is-error":""}`,children:[u.jsx("span",{className:"drawer__step-dot",children:W?"✓":I?"!":A+1}),u.jsx("span",{className:"drawer__step-label",children:Z}),A<eo.length-1&&u.jsx("span",{className:"drawer__step-bar"})]},h)})}),D.length>0&&u.jsx("div",{className:"drawer__dlbars","data-id":"DockerDrawer-dlbars",children:D.map(h=>u.jsx(fp,{phaseKey:h,bar:s.bars[h]},h))}),d&&s.logs.length>0&&u.jsxs("div",{className:"drawer__now","data-id":"DockerDrawer-now",children:[u.jsx(Ge,{}),u.jsx("span",{children:s.logs[s.logs.length-1].message})]}),u.jsx("div",{className:"drawer__log drawer__log--scroll","data-id":"DockerDrawer-log",ref:S,children:s.logs.length===0?u.jsx("div",{className:"drawer__log-empty",children:r("docker.preparing","准备中…")}):s.logs.map(h=>u.jsxs("div",{className:"drawer__line","data-status":h.status,children:[u.jsx("span",{className:"drawer__t",children:h.t}),u.jsx("span",{className:`drawer__badge drawer__badge--${h.phase}`,children:r(`dockerBadge.${h.phase}`,rp[h.phase]||h.phase)}),u.jsx("span",{className:"drawer__linemsg",children:h.message})]},h.id))}),u.jsx("div",{className:"drawer__foot",children:d?u.jsx(u.Fragment,{children:u.jsx("span",{className:"drawer__foot-status",children:j?r("docker.opening","打开中…"):r("docker.installing2","安装进行中…")})}):s.status==="reboot"?u.jsxs(u.Fragment,{children:[u.jsx("span",{className:"drawer__foot-status is-reboot",children:r("docker.rebootShort","需重启 Windows")}),s.onRetry&&u.jsx("button",{type:"button",className:"drawer__btn is-accent","data-id":"DockerDrawer-retry",onClick:()=>s.onRetry(),children:r("common.retry","重试")}),u.jsx("button",{type:"button",className:"drawer__btn","data-id":"DockerDrawer-dismiss",onClick:()=>Et.close(),children:r("common.close","关闭")})]}):s.status==="error"?u.jsxs(u.Fragment,{children:[u.jsx("span",{className:"drawer__foot-status is-error",children:j?r("docker.openFailed","打开失败"):r("docker.failed","安装失败")}),s.onRetry&&u.jsx("button",{type:"button",className:"drawer__btn is-accent","data-id":"DockerDrawer-retry",onClick:()=>s.onRetry(),children:r("common.retry","重试")}),u.jsx("button",{type:"button",className:"drawer__btn","data-id":"DockerDrawer-dismiss",onClick:()=>Et.close(),children:r("common.close","关闭")})]}):u.jsxs(u.Fragment,{children:[u.jsx("span",{className:"drawer__foot-status is-done",children:r("docker.ready","已就绪")}),u.jsx("button",{type:"button",className:"drawer__btn is-accent","data-id":"DockerDrawer-finish",onClick:()=>Et.close(),children:r("common.done","完成")})]})})]})})}function hp({dockerTeam:s,cloudTitle:g,cloudCode:S,onOpen:d,onRename:j,onRefresh:M}){var pe;const[D,R]=v.useState(null),[w,h]=v.useState(""),[Z,A]=v.useState(!1),[W,L]=v.useState(!1),[I,V]=v.useState(!1),[ht,xt]=v.useState(!1),[Jt,dt]=v.useState([]),[Lt,ut]=v.useState(!1),[bt,X]=v.useState(""),[ot,q]=v.useState(!1),[Zt,le]=v.useState(""),Pt=g||"Docker 团队",ve=H=>{var P;(P=H==null?void 0:H.stopPropagation)==null||P.call(H),le(Pt),q(!0)},oe=async()=>{q(!1);const H=String(Zt||"").trim();if(!(!H||H===Pt||!j))try{await j(H),M==null||M()}catch{}},[Qt,z]=v.useState({top:0,left:0}),G=v.useRef(null),rt=v.useRef(null),At=184,Tt="#2496ed",m=v.useCallback(async()=>{var H,P,lt;try{const it=await((lt=(P=(H=window.cicy)==null?void 0:H.docker)==null?void 0:P.appStatus)==null?void 0:lt.call(P));R(it);const Nt=Date.now()-((Bt==null?void 0:Bt.lastAt)||0)>3e4;it!=null&&it.running&&Bt&&Bt.status==="running"&&Bt.kind!=="open"&&Nt&&Et.finish({ok:!0,message:"Docker cicy-code 已就绪"})}catch(it){console.warn("[DockerCard]",it)}},[]);v.useEffect(()=>{m();const H=setInterval(()=>{w||m()},12e3);return()=>clearInterval(H)},[m,w]);const k=v.useCallback(async()=>{var H,P,lt;A(!1),X("");try{const it=await((lt=(P=(H=window.cicy)==null?void 0:H.docker)==null?void 0:P.getPorts)==null?void 0:lt.call(P));dt(((it==null?void 0:it.ports)||[]).map(String))}catch{dt([])}xt(!0)},[]),K=v.useCallback(async()=>{var it,Nt,Rt,ie,b,Q,tt,at,ct;const H=new Set,P=[];for(const pt of Jt){const zt=String(pt).trim();if(!zt)continue;const ze=Number(zt);if(!Number.isInteger(ze)||ze<1||ze>65535||ze===8008||H.has(ze)){X(r("docker.ports.invalid","有端口无效(1-65535,不能是 8008,不能重复)"));return}H.add(ze),P.push(ze)}X(""),ut(!0),xt(!1),h("recreate"),Et.open({onRetry:K});const lt=(Rt=(Nt=(it=window.cicy)==null?void 0:it.docker)==null?void 0:Nt.onAppProgress)==null?void 0:Rt.call(Nt,pt=>Et.push(pt));try{const pt=await((Q=(b=(ie=window.cicy)==null?void 0:ie.docker)==null?void 0:b.setPorts)==null?void 0:Q.call(b,P));if(Et.finish({ok:!!(pt!=null&&pt.ok),message:pt!=null&&pt.ok?r("docker.ports.save","保存并重建")+" ✅":(pt==null?void 0:pt.error)||r("docker.opFailed","操作失败")}),pt!=null&&pt.ok)try{const zt=await((ct=(at=(tt=window.cicy)==null?void 0:tt.docker)==null?void 0:at.appRedetect)==null?void 0:ct.call(at));zt&&R(zt)}catch{}}catch(pt){Et.finish({ok:!1,message:pt.message})}finally{try{lt&<()}catch{}ut(!1),h(""),m()}},[Jt,m]);v.useEffect(()=>{if(!Z)return;const H=lt=>{var it,Nt;(it=G.current)!=null&&it.contains(lt.target)||(Nt=rt.current)!=null&&Nt.contains(lt.target)||A(!1)},P=lt=>{lt.key==="Escape"&&A(!1)};return document.addEventListener("mousedown",H),document.addEventListener("keydown",P),()=>{document.removeEventListener("mousedown",H),document.removeEventListener("keydown",P)}},[Z]);const F=()=>{if(!Z&&G.current){const H=G.current.getBoundingClientRect(),P=Math.max(8,Math.min(H.right-At,window.innerWidth-At-8));z({top:Math.round(H.bottom+4),left:Math.round(P)})}A(H=>!H)},mt=v.useCallback(async()=>{var P,lt,it,Nt,Rt,ie;h("bootstrap"),Et.open({onRetry:mt});const H=(it=(lt=(P=window.cicy)==null?void 0:P.docker)==null?void 0:lt.onAppProgress)==null?void 0:it.call(lt,b=>Et.push(b));try{const b=await((ie=(Rt=(Nt=window.cicy)==null?void 0:Nt.docker)==null?void 0:Rt.appBootstrap)==null?void 0:ie.call(Rt));(b==null?void 0:b.reason)==="installer_launched"?Et.finish({status:"reboot",message:r("docker.installerLaunched","已打开 Docker 安装程序——请完成安装(会装 WSL2、可能需重启),装好后点「重试」")}):(b==null?void 0:b.reason)==="wsl_reboot_required"?Et.finish({status:"reboot",message:r("docker.rebootNeeded","WSL2 已安装,请【重启 Windows】后回来点「重试」继续")}):Et.finish({ok:!!(b!=null&&b.ok),message:b!=null&&b.ok?r("docker.ready","Docker cicy-code 已就绪"):(b==null?void 0:b.error)||r("docker.failed","安装失败")}),b!=null&&b.ok&&(M==null||M())}catch(b){Et.finish({ok:!1,message:b.message})}finally{try{H&&H()}catch{}h(""),m()}},[m,M]),yt=v.useCallback(async()=>{var P,lt,it,Nt,Rt,ie;h("repair"),Et.open({onRetry:yt});const H=(it=(lt=(P=window.cicy)==null?void 0:P.docker)==null?void 0:lt.onAppProgress)==null?void 0:it.call(lt,b=>Et.push(b));try{const b=await((ie=(Rt=(Nt=window.cicy)==null?void 0:Nt.docker)==null?void 0:Rt.appRepairWsl)==null?void 0:ie.call(Rt));b!=null&&b.needsReboot?Et.finish({status:"reboot",message:r("docker.wslNeedReboot","WSL 服务卡死,请【重启 Windows】;重启后打开 CiCy 会自动修复(旧数据已改名备份,不删)。")}):b!=null&&b.ok?(Et.finish({ok:!0,message:r("docker.wslRepaired","WSL 已修复 ✅")}),M==null||M()):Et.finish({ok:!1,message:(b==null?void 0:b.error)||r("docker.repairFailed","修复失败")})}catch(b){Et.finish({ok:!1,message:b.message})}finally{try{H&&H()}catch{}h(""),m()}},[m,M]),_t=v.useCallback(async()=>{var P,lt,it,Nt,Rt,ie;A(!1),h("upgrade"),Et.open({onRetry:_t});const H=(it=(lt=(P=window.cicy)==null?void 0:P.docker)==null?void 0:lt.onAppProgress)==null?void 0:it.call(lt,b=>Et.push(b));try{const b=await((ie=(Rt=(Nt=window.cicy)==null?void 0:Nt.docker)==null?void 0:Rt.appUpgrade)==null?void 0:ie.call(Rt));(b==null?void 0:b.reason)==="wsl_reboot_required"?Et.finish({status:"reboot",message:r("docker.rebootNeeded","WSL2 已安装,请【重启 Windows】后回来点「重试」继续")}):Et.finish({ok:!!(b!=null&&b.ok),message:b!=null&&b.ok?r("docker.upgraded","已升级到最新"):(b==null?void 0:b.error)||r("docker.upgradeFailed","升级失败")}),b!=null&&b.ok&&(M==null||M())}catch(b){Et.finish({ok:!1,message:b.message})}finally{try{H&&H()}catch{}h(""),m()}},[m,M]),ne=v.useCallback(async()=>{var P,lt,it,Nt,Rt,ie,b,Q,tt,at,ct,pt;A(!1),h("update"),Et.open({onRetry:ne});const H=(it=(lt=(P=window.cicy)==null?void 0:P.docker)==null?void 0:lt.onAppProgress)==null?void 0:it.call(lt,zt=>Et.push(zt));try{const zt=await((ie=(Rt=(Nt=window.cicy)==null?void 0:Nt.docker)==null?void 0:Rt.appUpdate)==null?void 0:ie.call(Rt));if(Et.finish({ok:!!(zt!=null&&zt.ok),message:zt!=null&&zt.ok?r("docker.updated","cicy-code 已更新到最新"):(zt==null?void 0:zt.error)||r("docker.updateFailed","更新失败")}),zt!=null&&zt.ok){M==null||M();try{(tt=(Q=(b=window.cicy)==null?void 0:b.tabs)==null?void 0:Q.reloadIfOpen)==null||tt.call(Q,"http://127.0.0.1:8008",r("docker.teamTab","Docker 团队"))}catch{}try{const ze=await((pt=(ct=(at=window.cicy)==null?void 0:at.docker)==null?void 0:ct.appRedetect)==null?void 0:pt.call(ct));ze&&R(ze)}catch{}}}catch(zt){Et.finish({ok:!1,message:zt.message})}finally{try{H&&H()}catch{}h(""),m()}},[m,M]),Ut=v.useCallback(async(H,P,lt)=>{A(!1),h(H),St.show({id:"docker-op",message:r(`docker.${H}ing`,H==="restart"?"重启中…":H==="reload"?"刷新中…":"停止中…"),status:"running"});try{const it=await P();it!=null&&it.ok?St.show({id:"docker-op",message:lt,status:"done",ttl:2500}):St.show({id:"docker-op",message:(it==null?void 0:it.error)||r("docker.opFailed","操作失败"),status:"error",ttl:6e3})}catch(it){St.show({id:"docker-op",message:it.message,status:"error",ttl:6e3})}finally{h(""),m()}},[m]),Qe=v.useCallback(async()=>{A(!1),h("authssh"),St.show({id:"docker-op",message:r("docker.authorizingHost","授权容器访问 Mac(配置 SSH)…"),status:"running"});try{const H=await window.cicy.docker.appAuthorizeHostSsh();H!=null&&H.ok?St.show({id:"docker-op",message:H.verified?r("docker.authorizedHostOk","已授权:容器内 `ssh mac` 可访问 Mac ✅"):r("docker.authorizedHostPartial","公钥已写入 Mac(未验证成功,可在容器内手动 `ssh mac` 试)"),status:H.verified?"done":"error",ttl:5e3}):St.show({id:"docker-op",message:(H==null?void 0:H.error)||r("docker.opFailed","操作失败"),status:"error",ttl:6e3})}catch(H){St.show({id:"docker-op",message:H.message,status:"error",ttl:6e3})}finally{h(""),m()}},[m]),$=((pe=window.cicy)==null?void 0:pe.platform)||(D==null?void 0:D.platform);if($!=="win32")return null;const qt=D?!!D.running:(s==null?void 0:s.status)==="running",de=!!(D!=null&&D.dockerRunning),Wt=!!(D!=null&&D.installed),De=!!(D!=null&&D.unknown)&&!qt&&!de&&!Wt,Te=!!(D!=null&&D.wslUnmanaged),Le=!!(D!=null&&D.wslWedged),ke=qt&&!Te,ca=ke?"ok":Le||Te||de||Wt||De?"warn":"off",Me=!!w;Le?r("docker.wslWedged","WSL 卡死 · 点「修复 WSL」"):Te?r("docker.wslBrokenRepair","WSL 管理异常 · 点「修复 WSL」重装"):qt?r("docker.running","运行中"):de?r("docker.notRunning","未启动 · 点「启动」"):Wt?r("docker.engineDown","Docker 未运行 · 点启动"):De?r("docker.wslUnresponsive","WSL 未响应 · 点「重试检测」"):r("docker.notInstalled","Docker Desktop 未安装");const Ie=w==="open"?r("docker.opening","打开中…"):w==="probe"?r("docker.probing","检测中…"):Me?r("docker.working","处理中…"):ke?r("localTeams.open","打开"):Le||Te?r("docker.repairWsl","修复 WSL"):de?r("docker.start","启动"):Wt?r("docker.startDocker","启动 Docker"):De?r("docker.retryProbe","重试检测"):r("docker.install","下载安装"),fe=async()=>{var H,P,lt,it,Nt,Rt,ie,b,Q,tt,at,ct;if(!Me){if(Le){yt();return}if(Te){mt();return}if(ke){try{const zt=await((lt=(P=(H=window.cicy)==null?void 0:H.tabs)==null?void 0:P.activateIfOpen)==null?void 0:lt.call(P,"http://127.0.0.1:8008"));if(zt!=null&&zt.active)return}catch{}h("open");let pt=null;try{pt=await((Rt=(Nt=(it=window.cicy)==null?void 0:it.docker)==null?void 0:Nt.appOpen)==null?void 0:Rt.call(Nt))}catch(zt){pt={ok:!1,hint:(zt==null?void 0:zt.message)||r("docker.openFailed","打开失败"),log:[]}}h(""),pt&&pt.ok===!1&&(Et.open({onRetry:fe,kind:"open"}),(pt.log||[]).forEach(zt=>Et.push(zt)),Et.finish({ok:!1,message:pt.hint||pt.error||r("docker.openFailed","打开失败")}));return}if(De){h("probe");try{const pt=await(((Q=(b=(ie=window.cicy)==null?void 0:ie.docker)==null?void 0:b.appRedetect)==null?void 0:Q.call(b))??((ct=(at=(tt=window.cicy)==null?void 0:tt.docker)==null?void 0:at.appStatus)==null?void 0:ct.call(at)));pt&&R(pt),pt!=null&&pt.unknown&&St.show({id:"docker-probe",status:"error",message:r("docker.wslStillStuck","WSL 仍无响应 —— 多半要重启 Windows 后再试"),ttl:6e3})}catch{St.show({id:"docker-probe",status:"error",message:r("docker.probeFailed","检测失败,请重试"),ttl:5e3})}finally{h("")}return}mt()}},sa=qt;return u.jsxs("div",{"data-id":"DockerCard",className:`bcard bcard--docker${qt?" bcard--online":""}`,children:[u.jsx("div",{className:"bcard__accent",style:{background:Tt}}),u.jsxs("div",{className:"bcard__top",children:[u.jsxs("div",{className:"bcard__pill",style:{color:Tt},children:[u.jsx("span",{className:"bcard__dot","data-tone":ca}),u.jsx("svg",{style:{width:18,height:18},viewBox:"0 0 24 24",fill:"currentColor","aria-hidden":!0,children:u.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"})})]}),sa&&u.jsxs("div",{className:"bcard__menuwrap",onClick:H=>H.stopPropagation(),children:[u.jsx("button",{type:"button",ref:G,"data-id":"DockerCard-menu-btn",className:"bcard__kebab",title:r("docker.manage","管理 Docker cicy-code"),disabled:Me,onClick:F,children:Me?u.jsx(Ge,{}):u.jsx(oo,{})}),Z&&xa.createPortal(u.jsxs("div",{className:"bcard__menu bcard__menu--portal","data-id":"DockerCard-menu",role:"menu",ref:rt,style:{position:"fixed",top:Qt.top,left:Qt.left,width:At},onClick:H=>H.stopPropagation(),children:[u.jsx("button",{type:"button","data-id":"DockerCard-update",className:"bcard__menu-item is-accent",onClick:ne,children:r("docker.update","更新 cicy-code")}),u.jsx("button",{type:"button","data-id":"DockerCard-restart",className:"bcard__menu-item",onClick:()=>Ut("restart",()=>window.cicy.docker.appRestart(),r("docker.restarted","已重启 cicy-code")),children:r("docker.restart","重启 cicy-code")}),u.jsx("button",{type:"button","data-id":"DockerCard-stop",className:"bcard__menu-item is-danger",onClick:()=>Ut("stop",()=>window.cicy.docker.appStop(),r("docker.stopped","已停止 cicy-code")),children:r("docker.stop","停止 cicy-code")}),u.jsx("button",{type:"button","data-id":"DockerCard-reload",className:"bcard__menu-item",onClick:H=>{var P,lt,it;H.stopPropagation(),A(!1),(it=(lt=(P=window.cicy)==null?void 0:P.tabs)==null?void 0:lt.reloadIfOpen)==null||it.call(lt,"http://127.0.0.1:8008","Docker 团队")},children:r("docker.reloadWindow","刷新窗口")}),u.jsx("button",{type:"button","data-id":"DockerCard-cft",className:"bcard__menu-item",title:r("sidecar.cftHint","用 Cloudflare 命名隧道把 cicy-code 暴露到固定公网域名(需要 Cloudflare connector token);切换会自动重启 cicy-code"),onClick:H=>{H.stopPropagation(),A(!1),L(!0)},children:r("sidecar.cftMenu","Cloudflare 隧道")}),u.jsx("button",{type:"button","data-id":"DockerCard-open-dir",className:"bcard__menu-item",onClick:H=>{var P,lt,it;H.stopPropagation(),A(!1),(it=(lt=(P=window.cicy)==null?void 0:P.docker)==null?void 0:lt.openDir)==null||it.call(lt)},children:r("docker.openWslDir","打开 WSL 目录")}),u.jsx("button",{type:"button","data-id":"DockerCard-open-projects",className:"bcard__menu-item",onClick:H=>{var P,lt,it;H.stopPropagation(),A(!1),(it=(lt=(P=window.cicy)==null?void 0:P.docker)==null?void 0:lt.openDir)==null||it.call(lt,"projects")},children:r("docker.openProjectsDir","打开项目目录")}),u.jsx("button",{type:"button","data-id":"DockerCard-billing",className:"bcard__menu-item",onClick:()=>{A(!1),_i(S||s!=null&&s.cloud_team_id?`?team=${encodeURIComponent(S||s.cloud_team_id)}`:"?view=usage")},children:r("docker.billing","帐单")}),u.jsx("div",{className:"bcard__menu-sep","data-id":"DockerCard-menu-sep",role:"separator","aria-hidden":!0}),$==="darwin"&&u.jsx("button",{type:"button","data-id":"DockerCard-authorize-host-ssh",className:"bcard__menu-item",title:r("docker.authorizeHostHint","把容器公钥加到 Mac 的 authorized_keys,容器内 `ssh mac` 即可访问本机"),onClick:Qe,children:r("docker.authorizeHost","授权容器访问 Mac")}),u.jsx("button",{type:"button","data-id":"DockerCard-docker-restart",className:"bcard__menu-item",onClick:()=>Ut("restart",()=>window.cicy.docker.appDockerRestart(),r("docker.dockerRestarted","已重启 Docker 容器")),children:r("docker.dockerRestart","重启 Docker")}),u.jsx("button",{type:"button","data-id":"DockerCard-ports",className:"bcard__menu-item",onClick:H=>{H.stopPropagation(),k()},children:r("docker.ports.menu","端口设置")}),u.jsx("button",{type:"button","data-id":"DockerCard-recreate",className:"bcard__menu-item is-danger",onClick:H=>{H.stopPropagation(),A(!1),V(!0)},children:r("docker.recreate","重建 Docker")})]}),document.body)]})]}),u.jsxs("div",{className:"bcard__body",children:[u.jsxs("div",{style:{height:28,display:"flex",alignItems:"center",gap:8},children:[u.jsx(so,{size:24,avatar:s==null?void 0:s.avatar,name:Pt,teamId:s==null?void 0:s.id,onChanged:M}),ot?u.jsx("input",{"data-id":"DockerCard-rename-input",autoFocus:!0,value:Zt,onChange:H=>le(H.target.value),onFocus:H=>H.target.select(),onBlur:oe,onClick:H=>H.stopPropagation(),onKeyDown:H=>{H.nativeEvent.isComposing||H.keyCode===229||(H.key==="Enter"?oe():H.key==="Escape"&&q(!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"}}):u.jsxs("h3",{className:"bcard__name",title:j?r("localTeams.renameHint","点名字或 ✎ 改名"):Pt,style:{display:"flex",alignItems:"center",gap:6,flex:1,minWidth:0,margin:0},onDoubleClick:j?ve:void 0,children:[u.jsx("span",{onClick:j?ve:void 0,style:{overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap",cursor:j?"text":"default"},children:Pt}),j&&u.jsx("button",{type:"button","data-id":"DockerCard-rename-btn",title:r("localTeams.rename","重命名"),onClick:ve,style:{flex:"none",cursor:"pointer",border:"none",background:"transparent",color:"#8b949e",fontSize:13,padding:0,lineHeight:1},children:"✎"})]})]}),u.jsxs("div",{className:"bcard__meta",children:[u.jsx("span",{className:"bcard__chip",children:"Docker"}),(D==null?void 0:D.version)&&u.jsxs("span",{className:"bcard__ver","data-id":"DockerCard-ver",style:{marginLeft:8,fontSize:11,opacity:.6},children:["v",D.version]})]})]}),u.jsxs("button",{type:"button",className:"bcard__cta","data-id":"DockerCard-cta",disabled:Me,onClick:fe,style:qt?void 0:{background:Tt,color:"white"},children:[Me?u.jsx(Ge,{}):u.jsx(Hu,{}),u.jsx("span",{children:Ie})]}),u.jsx(km,{open:W,onClose:()=>L(!1),toastId:"docker-op"}),I&&xa.createPortal(u.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:H=>{H.target===H.currentTarget&&V(!1)},children:u.jsxs("div",{onClick:H=>H.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:[u.jsx("h3",{style:{margin:"0 0 8px",fontSize:16,color:"#e6edf3"},children:r("docker.recreate","重建 Docker")}),u.jsx("p",{style:{margin:"0 0 18px",fontSize:13,lineHeight:1.6,color:"#9aa4b2"},children:r("docker.recreateConfirm","会删除当前容器并重新创建(volume 数据保留),用于切换为独立 team 的网关 key。确定重建?")}),u.jsxs("div",{style:{display:"flex",justifyContent:"flex-end",gap:10},children:[u.jsx("button",{type:"button","data-id":"DockerCard-recreate-cancel",onClick:()=>V(!1),style:{padding:"7px 16px",borderRadius:8,border:"1px solid #30363d",background:"transparent",color:"#c9d1d9",cursor:"pointer",fontSize:13},children:r("common.cancel","取消")}),u.jsx("button",{type:"button","data-id":"DockerCard-recreate-confirm",onClick:()=>{V(!1),Ut("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),ht&&xa.createPortal(u.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:H=>{H.target===H.currentTarget&&xt(!1)},children:u.jsxs("div",{onClick:H=>H.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:[u.jsx("h3",{style:{margin:"0 0 6px",fontSize:16,color:"#e6edf3"},children:r("docker.ports.title","端口设置")}),u.jsx("p",{style:{margin:"0 0 14px",fontSize:12.5,lineHeight:1.6,color:"#9aa4b2"},children:r("docker.ports.sub","除 :8008 外,额外发布、可从 Windows 直达容器内服务的端口")}),u.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(固定)")]}),u.jsxs("div",{style:{display:"flex",flexDirection:"column",gap:8,maxHeight:220,overflowY:"auto"},children:[Jt.length===0&&u.jsx("div",{style:{fontSize:12.5,color:"#6e7681",padding:"4px 2px"},children:r("docker.ports.none","暂无额外端口")}),Jt.map((H,P)=>u.jsxs("div",{style:{display:"flex",alignItems:"center",gap:8},children:[u.jsx("input",{"data-id":`DockerCard-port-input-${P}`,type:"text",inputMode:"numeric",value:H,placeholder:r("docker.ports.ph","端口号 1-65535"),onChange:lt=>{const it=lt.target.value.replace(/[^0-9]/g,"");dt(Nt=>Nt.map((Rt,ie)=>ie===P?it:Rt)),X("")},style:{flex:1,padding:"7px 10px",borderRadius:8,border:"1px solid #30363d",background:"#0d1117",color:"#e6edf3",fontSize:13,fontFamily:"var(--mono)"}}),u.jsx("button",{type:"button","data-id":`DockerCard-port-remove-${P}`,title:r("docker.ports.remove","移除"),onClick:()=>{dt(lt=>lt.filter((it,Nt)=>Nt!==P)),X("")},style:{padding:"6px 10px",borderRadius:8,border:"1px solid #30363d",background:"transparent",color:"#da3633",cursor:"pointer",fontSize:14},children:"✕"})]},P))]}),u.jsx("button",{type:"button","data-id":"DockerCard-port-add",onClick:()=>dt(H=>[...H,""]),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","+ 添加端口")}),bt&&u.jsx("div",{style:{marginTop:10,fontSize:12.5,color:"#f85149"},children:bt}),u.jsx("p",{style:{margin:"12px 0 16px",fontSize:11.5,lineHeight:1.5,color:"#6e7681"},children:r("docker.ports.hint","保存会重建容器(volume 数据保留),会有短暂中断")}),u.jsxs("div",{style:{display:"flex",justifyContent:"flex-end",gap:10},children:[u.jsx("button",{type:"button","data-id":"DockerCard-ports-cancel",disabled:Lt,onClick:()=>xt(!1),style:{padding:"7px 16px",borderRadius:8,border:"1px solid #30363d",background:"transparent",color:"#c9d1d9",cursor:"pointer",fontSize:13},children:r("docker.ports.cancel","取消")}),u.jsx("button",{type:"button","data-id":"DockerCard-ports-save",disabled:Lt,onClick:K,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 Sm({team:s,cloudCode:g,onOpen:S,onRename:d,onRefresh:j}){var it,Nt,Rt,ie;const D=(wm[s.status]||wm.error).tone,[R,w]=v.useState(!1),[h,Z]=v.useState(s.name||""),[A,W]=v.useState(null),[L,I]=v.useState(""),V=A??s.name;v.useEffect(()=>{A!=null&&s.name===A&&W(null)},[s.name,A]);const ht=b=>{var Q;(Q=b==null?void 0:b.stopPropagation)==null||Q.call(b),Z(V||""),w(!0)},xt=async()=>{w(!1);const b=String(h||"").trim();if(!d||!b||b===V)return;W(b),I("saving");let Q;try{Q=await d(s.id,b)}catch(tt){Q={ok:!1,error:tt==null?void 0:tt.message}}W(null),Q&&Q.ok?(I("saved"),setTimeout(()=>I(tt=>tt==="saved"?"":tt),1500)):(I(""),St.show({message:r("localTeams.renameFailed","改名没保存,已恢复"),status:"error",ttl:4e3}))},dt=!!((Nt=(it=window.cicy)==null?void 0:it.sidecar)!=null&&Nt.restart)&&uo(s.base_url),Lt=s.status==="running",[ut,bt]=v.useState(""),[X,ot]=v.useState(!1),[q,Zt]=v.useState(!1),[le,Pt]=v.useState(!1);v.useEffect(()=>{var b,Q;!dt||!((Q=(b=window.cicy)==null?void 0:b.sidecar)!=null&&Q.getPublic)||window.cicy.sidecar.getPublic().then(tt=>Pt(!!(tt!=null&&tt.public))).catch(()=>{})},[dt]);const[ve,oe]=v.useState({running:void 0,latest:null,installed:null}),Qt=ve.latest,z=ve.running,[G,rt]=v.useState(!1),At=v.useRef(null),Tt=v.useRef(null),m=v.useRef(null),[k,K]=v.useState({top:0,left:0}),F=184,mt=()=>{if(!X&&Tt.current){const b=Tt.current.getBoundingClientRect(),Q=Math.max(8,Math.min(b.right-F,window.innerWidth-F-8));K({top:Math.round(b.bottom+4),left:Math.round(Q)})}ot(b=>!b)},yt=v.useCallback(async(b=!1)=>{var Q,tt;if(!(!dt||!((tt=(Q=window.cicy)==null?void 0:Q.sidecar)!=null&&tt.versions))){b&&rt(!0);try{const at=await window.cicy.sidecar.versions();oe({running:(at==null?void 0:at.running)??null,latest:(at==null?void 0:at.latest)??null,installed:(at==null?void 0:at.installed)??null}),b&&(at!=null&&at.running&&(at!=null&&at.latest)&&_m(at.latest,at.running)>0?St.show({message:`${r("sidecar.found","发现新版本")} v${at.latest}`,status:"done",ttl:2500}):at!=null&&at.running?St.show({message:`${r("sidecar.upToDate","已是最新")} v${at.running}`,status:"done",ttl:2500}):St.show({message:r("sidecar.notRunning","cicy-code 未运行"),status:"error",ttl:4e3}))}catch{b&&St.show({message:r("sidecar.checkFailed","检查更新失败"),status:"error",ttl:5e3})}finally{b&&rt(!1)}}},[dt]);v.useEffect(()=>{yt(!1)},[yt]),v.useEffect(()=>{Lt&&yt(!1)},[Lt,yt]);const _t=!!(dt&&Qt&&z&&_m(Qt,z)>0),ne=!dt&&!!((ie=(Rt=window.cicy)==null?void 0:Rt.localTeams)!=null&&ie.remove),Ut=dt||ne,[Qe,$]=v.useState(!1),[qt,de]=v.useState(!1),[Wt,De]=v.useState(""),[Te,Le]=v.useState(!1),[ke,ca]=v.useState("");v.useEffect(()=>{if(!X)return;const b=Q=>{var tt,at;(tt=Tt.current)!=null&&tt.contains(Q.target)||(at=m.current)!=null&&at.contains(Q.target)||ot(!1)};return document.addEventListener("mousedown",b),()=>document.removeEventListener("mousedown",b)},[X]);const Me=async()=>{var Q,tt,at;if(Te)return;const b=String(Wt||"").trim();if(!b||b===(s.base_url||"")){de(!1);return}try{new URL(b)}catch{ca(r("teams.badUrl","URL 无效(需含 http(s)://)"));return}ca(""),Le(!0);try{const ct=await((at=(tt=(Q=window.cicy)==null?void 0:Q.localTeams)==null?void 0:tt.update)==null?void 0:at.call(tt,s.id,{base_url:b}));ct!=null&&ct.ok?(de(!1),j==null||j()):ca(Wa((ct==null?void 0:ct.error)||"update failed"))}catch(ct){ca(Wa((ct==null?void 0:ct.message)||String(ct)))}Le(!1)},Ie=async()=>{var Q,tt,at;if(ut)return;$(!1),bt("remove");const b="op-"+Date.now();St.show({id:b,message:r("localTeams.removing","删除中…"),status:"running"});try{const ct=await((at=(tt=(Q=window.cicy)==null?void 0:Q.localTeams)==null?void 0:tt.remove)==null?void 0:at.call(tt,s.id));ct!=null&&ct.ok?St.show({id:b,message:r("localTeams.removed","已删除"),status:"done",ttl:3e3}):St.show({id:b,message:r("localTeams.removeFailed","删除失败")+(ct!=null&&ct.error?": "+ct.error:""),status:"error",ttl:7e3})}catch(ct){St.show({id:b,message:r("localTeams.removeFailed","删除失败")+": "+((ct==null?void 0:ct.message)||ct),status:"error",ttl:7e3})}bt(""),j==null||j()},fe=`sidecar-op:${s.id}`,sa=async(b,Q,tt)=>{var pt,zt,ze,oa,Ca;if(ot(!1),ut)return;bt(b);const at=b==="update";let ct=null;at?(ye.open({teamId:s.id,fromVer:z,toVer:Qt,onRetry:()=>sa("update",Q,tt)}),(zt=(pt=window.cicy)==null?void 0:pt.sidecar)!=null&&zt.onOpProgress&&(ct=window.cicy.sidecar.onOpProgress($t=>{($t==null?void 0:$t.op)==="update"&&ye.push($t)}))):St.show({id:fe,message:pe[b]||`${b}…`,status:"running",progress:void 0});try{const $t=await Q(),Ce=!!($t!=null&&$t.ok),Na=$t!=null&&$t.warning?`${tt}(${$t.warning})`:tt,ra=r("sidecar.failed","操作失败")+($t!=null&&$t.error?`: ${$t.error}`:"");if(at){if(ye.finish({ok:Ce,message:Ce?Na:ra}),Ce)try{await((Ca=(oa=(ze=window.cicy)==null?void 0:ze.localTeams)==null?void 0:oa.reload)==null?void 0:Ca.call(oa,s.id,{ignoreCache:!0}))}catch{}}else St.show({id:fe,message:Ce?Na:ra,progress:void 0,status:Ce?"done":"error",ttl:Ce?4e3:8e3})}catch($t){const Ce=r("sidecar.failed","操作失败")+`: ${($t==null?void 0:$t.message)||$t}`;at?ye.finish({ok:!1,message:Ce}):St.show({id:fe,message:Ce,progress:void 0,status:"error",ttl:8e3})}finally{try{ct&&ct()}catch{}bt(""),j==null||j(),(b==="update"||b==="restart"||b==="start")&&yt(!1)}},pe={start:r("busy.start","启动中…"),restart:r("busy.restart","重启中…"),update:r("busy.update","更新中…"),stop:r("busy.stop","停止中…")},H=async()=>{var tt,at,ct;bt("start"),ye.open({teamId:s.id,title:r("sidecar.startTitle","启动 cicy-code"),onRetry:H}),ye.push({phase:"download",status:"running",message:r("sidecar.starting","启动 cicy-code(首次需安装 Node + 依赖,日志见下)…")});const b=(ct=(at=(tt=window.cicy)==null?void 0:tt.sidecar)==null?void 0:at.onOpProgress)==null?void 0:ct.call(at,pt=>ye.push(pt));let Q;try{Q=await window.cicy.sidecar.start()}catch(pt){Q={ok:!1,error:(pt==null?void 0:pt.message)||String(pt)}}try{b==null||b()}catch{}return bt(""),j==null||j(),!(Q!=null&&Q.ok)||Q!=null&&Q.warning?(ye.finish({ok:!1,message:r("sidecar.startFailed","启动失败")+(Q!=null&&Q.error?`: ${Q.error}`:Q!=null&&Q.warning?`: ${Q.warning}`:"")}),!1):(ye.finish({ok:!0,message:r("sidecar.startedOk","cicy-code 已就绪")}),!0)},P=async()=>{var b,Q;ut||!Lt&&dt&&((Q=(b=window.cicy)==null?void 0:b.sidecar)!=null&&Q.start)&&!await H()||S()},lt=Lt?r("localTeams.open","打开"):dt?r("localTeams.startOpen","启动并打开"):r("localTeams.open","打开");return u.jsxs(u.Fragment,{children:[u.jsxs("div",{"data-id":"LocalTeamCard",className:`bcard ${dt?"bcard--local":"bcard--custom"}${D==="ok"?" bcard--online":""}`,children:[u.jsx("div",{className:"bcard__accent"}),u.jsxs("div",{className:"bcard__top",children:[u.jsxs("div",{className:"bcard__pill",children:[u.jsx("span",{className:"bcard__dot","data-tone":D}),u.jsx(xp,{})]}),Ut&&u.jsxs("div",{className:"bcard__menuwrap",ref:At,onClick:b=>b.stopPropagation(),children:[u.jsx("button",{type:"button",ref:Tt,"data-id":"LocalTeamCard-menu-btn",className:`bcard__kebab${_t?" has-dot":""}`,title:dt?r("localTeams.manage","管理本地 cicy-code"):r("localTeams.more","更多"),disabled:!!ut,onClick:mt,children:ut?u.jsx(Ge,{}):u.jsx(oo,{})}),X&&xa.createPortal(u.jsxs("div",{className:"bcard__menu bcard__menu--portal","data-id":"LocalTeamCard-menu",role:"menu",ref:m,style:{position:"fixed",top:k.top,left:k.left,width:F},onClick:b=>b.stopPropagation(),children:[dt&&u.jsx("button",{type:"button","data-id":"LocalTeamCard-check-update",className:"bcard__menu-item",disabled:G,onClick:b=>{b.stopPropagation(),yt(!0)},children:G?r("sidecar.checking2","检查中…"):r("sidecar.checkUpdate","检查更新")}),_t&&u.jsxs("button",{type:"button","data-id":"LocalTeamCard-update",className:"bcard__menu-item is-accent",onClick:()=>sa("update",()=>window.cicy.sidecar.update(),r("sidecar.updated","已更新到最新")),children:[r("sidecar.updateTo","更新到")," v",Qt]}),s.base_url&&u.jsx("button",{type:"button","data-id":"LocalTeamCard-reload",className:"bcard__menu-item",onClick:b=>{var Q,tt,at;b.stopPropagation(),ot(!1),(at=(tt=(Q=window.cicy)==null?void 0:Q.tabs)==null?void 0:tt.reloadIfOpen)==null||at.call(tt,s.base_url,s.name)},children:r("localTeams.reloadWindow","刷新窗口")}),dt&&!Lt&&u.jsx("button",{type:"button","data-id":"LocalTeamCard-start",className:"bcard__menu-item is-accent",onClick:()=>sa("start",()=>window.cicy.sidecar.start(),r("sidecar.started","已启动")),children:r("sidecar.start","启动")}),dt&&Lt&&u.jsxs(u.Fragment,{children:[u.jsx("button",{type:"button","data-id":"LocalTeamCard-restart",className:"bcard__menu-item",onClick:()=>sa("restart",()=>window.cicy.sidecar.restart(),r("sidecar.restarted","已重启")),children:r("sidecar.restart","重启")}),u.jsx("button",{type:"button","data-id":"LocalTeamCard-stop",className:"bcard__menu-item is-danger",onClick:()=>sa("stop",()=>window.cicy.sidecar.stop(),r("sidecar.stoppedDone","已停止")),children:r("sidecar.stop","停止")}),u.jsxs("button",{type:"button","data-id":"LocalTeamCard-lan",className:"bcard__menu-item",title:r("sidecar.lanHint","开启后同局域网设备可用本机 IP 访问(api_token 仍校验);切换会自动重启 cicy-code"),disabled:ut==="lan",onClick:async()=>{if(ut)return;const b=!le;ot(!1),bt("lan"),Pt(b),St.show({id:fe,message:b?r("sidecar.lanEnabling","开启局域网访问,重启中…"):r("sidecar.lanDisabling","关闭局域网访问,重启中…"),status:"running",progress:void 0});try{const Q=await window.cicy.sidecar.setPublic(b);Q!=null&&Q.ok?St.show({id:fe,message:b?r("sidecar.lanOn","已开启局域网访问"):r("sidecar.lanOff","已关闭局域网访问"),status:"done",ttl:3e3}):St.show({id:fe,message:r("sidecar.lanFailed","设置失败")+(Q!=null&&Q.error?`: ${Q.error}`:""),status:"error",ttl:7e3})}catch(Q){St.show({id:fe,message:r("sidecar.lanFailed","设置失败")+`: ${(Q==null?void 0:Q.message)||Q}`,status:"error",ttl:7e3})}try{const Q=await window.cicy.sidecar.getPublic();Pt(!!(Q!=null&&Q.public))}catch{}bt(""),j==null||j()},children:[r("sidecar.lanAccess","局域网访问")," · ",le?r("common.on","开"):r("common.off","关")]}),u.jsx("button",{type:"button","data-id":"LocalTeamCard-cft",className:"bcard__menu-item",title:r("sidecar.cftHint","用 Cloudflare 命名隧道把本机 cicy-code 暴露到固定公网域名(需要 Cloudflare connector token);切换会自动重启 cicy-code"),onClick:b=>{b.stopPropagation(),ot(!1),Zt(!0)},children:r("sidecar.cftMenu","Cloudflare 隧道")})]}),s.cloud_team_id&&u.jsx("button",{type:"button","data-id":"LocalTeamCard-billing",className:"bcard__menu-item",onClick:b=>{b.stopPropagation(),ot(!1),_i(`?team=${encodeURIComponent(g||s.cloud_team_id)}`)},children:r("localTeams.billing","账单")}),ne&&u.jsxs(u.Fragment,{children:[u.jsx("button",{type:"button","data-id":"LocalTeamCard-edit-url",className:"bcard__menu-item",onClick:b=>{b.stopPropagation(),ot(!1),de(!0),De(s.base_url||"")},children:r("teamCard.editUrl","更改访问地址")}),u.jsx("button",{type:"button","data-id":"LocalTeamCard-remove",className:"bcard__menu-item is-danger",onClick:()=>{ot(!1),$(!0)},children:r("localTeams.remove","删除")})]}),(z||s.version)&&u.jsxs("div",{"data-id":"LocalTeamCard-version",className:"bcard__menu-item",style:{cursor:"default",color:"#8b949e",fontSize:12},children:[r("localTeams.version","版本")," v",z||s.version]})]}),document.body)]})]}),u.jsxs("div",{className:"bcard__body",children:[u.jsxs("div",{style:{height:28,display:"flex",alignItems:"center",gap:8},children:[u.jsx(so,{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}),R?u.jsx("input",{"data-id":"LocalTeamCard-rename-input",autoFocus:!0,value:h,onChange:b=>Z(b.target.value),onFocus:b=>b.target.select(),onBlur:xt,onClick:b=>b.stopPropagation(),onKeyDown:b=>{b.nativeEvent.isComposing||b.keyCode===229||(b.key==="Enter"?xt():b.key==="Escape"&&w(!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"}}):u.jsxs("h3",{className:"bcard__name",title:r("localTeams.renameHint","点名字或 ✎ 改名"),style:{display:"flex",alignItems:"center",gap:6,flex:1,minWidth:0,margin:0},onDoubleClick:ht,children:[u.jsx("span",{"data-id":"LocalTeamCard-name-text",onClick:ht,style:{overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap",cursor:"text"},children:V}),L==="saving"&&u.jsx("span",{"data-id":"LocalTeamCard-save-state",title:r("localTeams.saving","保存中…"),style:{flex:"none",display:"inline-flex"},children:u.jsx(Ge,{})}),L==="saved"&&u.jsx("span",{"data-id":"LocalTeamCard-save-state",title:r("localTeams.saved","已保存"),style:{flex:"none",color:"#3fb950",fontSize:13,lineHeight:1},children:"✓"}),!L&&u.jsx("button",{type:"button","data-id":"LocalTeamCard-rename-btn",title:r("localTeams.rename","重命名"),onClick:ht,style:{flex:"none",cursor:"pointer",border:"none",background:"transparent",color:"#8b949e",fontSize:13,padding:0,lineHeight:1},children:"✎"})]})]}),u.jsx("div",{className:"bcard__meta",children:u.jsx("span",{className:"bcard__chip","data-id":"LocalTeamCard-kind",children:dt?r("localTeams.kindLocal","本地"):r("localTeams.kindCustom","自定义")})})]}),u.jsxs("button",{type:"button",className:"bcard__cta","data-id":"LocalTeamCard-open",disabled:!!ut||!s.base_url,onClick:P,children:[ut&&ut!=="stop"?u.jsx(Ge,{}):u.jsx(Hu,{}),u.jsx("span",{children:ut&&pe[ut]||lt})]})]}),qt&&xa.createPortal(u.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:b=>{!Te&&b.target===b.currentTarget&&de(!1)},children:u.jsxs("div",{onClick:b=>b.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:[u.jsx("div",{style:{fontSize:16,fontWeight:700,marginBottom:4},children:r("teamCard.editUrl","更改访问地址")}),u.jsx("div",{style:{fontSize:12,opacity:.6,marginBottom:16},children:s.name}),u.jsx("textarea",{"data-id":"LocalTeamCard-url-input",autoFocus:!0,rows:3,className:"login-email-input",style:{width:"100%",resize:"vertical",lineHeight:1.5,fontFamily:"var(--mono)"},value:Wt,placeholder:"https://example.com:8008",spellCheck:!1,disabled:Te,onChange:b=>De(b.target.value.replace(/[\r\n]+/g,"")),onKeyDown:b=>{b.nativeEvent.isComposing||b.keyCode===229||(b.key==="Enter"?(b.preventDefault(),Me()):b.key==="Escape"&&de(!1))}}),ke&&u.jsx("div",{className:"error",style:{marginTop:8,fontSize:12},children:ke}),u.jsxs("div",{className:"modal-actions",children:[u.jsx("button",{type:"button",className:"btn-ghost",disabled:Te,onClick:()=>de(!1),children:r("common.cancel","取消")}),u.jsx("button",{type:"button",className:"btn-primary","data-id":"LocalTeamCard-url-save",disabled:Te,onClick:Me,children:Te?r("common.saving","保存中…"):r("common.save","保存")})]})]})}),document.body),u.jsx(km,{open:q,onClose:()=>Zt(!1),toastId:fe}),u.jsx(Dm,{open:Qe,title:r("localTeams.deleteTitle","删除团队"),message:r("localTeams.deleteMsg","确定删除「{{name}}」?此操作不可撤销。",{name:s.name}),confirmLabel:r("common.delete","删除"),danger:!0,onConfirm:Ie,onCancel:()=>$(!1)})]})}function uo(s){var g;try{if(((g=window.cicy)==null?void 0:g.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 xm(s){var g;try{if(((g=window.cicy)==null?void 0:g.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 _m(s,g){const S=String(s).split("."),d=String(g).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 wm={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 Dm({open:s,title:g,message:S,confirmLabel:d,danger:j,onConfirm:M,onCancel:D}){return s?xa.createPortal(u.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:R=>{R.target===R.currentTarget&&(D==null||D())},children:u.jsxs("div",{onClick:R=>R.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:[u.jsx("div",{style:{fontSize:16,fontWeight:700,marginBottom:6},children:g}),S&&u.jsx("div",{style:{fontSize:13,opacity:.7,marginBottom:16},children:S}),u.jsxs("div",{className:"modal-actions",children:[u.jsx("button",{type:"button",className:"btn-ghost",onClick:D,children:r("common.cancel","取消")}),u.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 yp({team:s,onOpen:g,onRename:S,onEditUrl:d,onDelete:j,avatar:M,onAvatar:D}){const R=s.kind==="private",w=s.status==="active",h=s.name||s.title||"—",[Z,A]=v.useState(!1),[W,L]=v.useState(""),[I,V]=v.useState(null),ht=I??h;v.useEffect(()=>{I!=null&&h===I&&V(null)},[h,I]);const xt=$=>{var qt;(qt=$==null?void 0:$.stopPropagation)==null||qt.call($),L(ht==="—"?"":ht),A(!0)},Jt=async()=>{A(!1);const $=String(W||"").trim();if(!(!S||!$||$===ht)){V($);try{const qt=await S(s.id,$);qt!=null&&qt.ok||V(null)}catch{V(null)}}},dt=s.host_url||"",[Lt,ut]=v.useState(!1),[bt,X]=v.useState(""),[ot,q]=v.useState(null),Zt=ot??dt;v.useEffect(()=>{ot!=null&&dt===ot&&q(null)},[dt,ot]);const le=s.teamId||s.id,Pt=R?r("teamKind.private","私有云"):s.team_kind==="personal"?r("teamKind.personal","个人"):r("teamKind.shared","共享"),ve=R?Zt:s.workspace_url||s.workspace_direct_url,oe=!!ve,[Qt,z]=v.useState(!1),[G,rt]=v.useState(!1),[At,Tt]=v.useState({top:0,left:0}),m=v.useRef(null),k=v.useRef(null),K=v.useRef(null),F=184,mt=()=>{if(!Qt&&k.current){const $=k.current.getBoundingClientRect(),qt=Math.max(8,Math.min($.right-F,window.innerWidth-F-8));Tt({top:Math.round($.bottom+4),left:Math.round(qt)})}z($=>!$)};v.useEffect(()=>{if(!Qt)return;const $=qt=>{var de,Wt;(de=k.current)!=null&&de.contains(qt.target)||(Wt=K.current)!=null&&Wt.contains(qt.target)||z(!1)};return document.addEventListener("mousedown",$),()=>document.removeEventListener("mousedown",$)},[Qt]);const yt=$=>{var qt,de,Wt,De;(qt=$==null?void 0:$.stopPropagation)==null||qt.call($),oe&&(z(!1),(De=(Wt=(de=window.cicy)==null?void 0:de.tabs)==null?void 0:Wt.reloadIfOpen)==null||De.call(Wt,ve,ht))},[_t,ne]=v.useState(!1),Ut=()=>{X(dt),ut(!0),z(!1)},Qe=async()=>{ut(!1);const $=String(bt||"").trim();if(!(!d||!$||$===dt)){q($);try{const qt=await d(s.id,$);qt!=null&&qt.ok||q(null)}catch{q(null)}}};return u.jsxs(u.Fragment,{children:[u.jsxs("div",{"data-id":"TeamCard",className:`bcard bcard--cloud${w?" bcard--online":""}`,children:[u.jsx("div",{className:"bcard__accent"}),u.jsxs("div",{className:"bcard__top",children:[u.jsxs("div",{className:"bcard__pill",children:[u.jsx("span",{className:"bcard__dot","data-tone":w?"ok":"off"}),u.jsx(_p,{})]}),u.jsxs("div",{className:"bcard__top-right",children:[s.is_trial&&u.jsx("span",{className:"bcard__badge",children:"trial"}),(oe||le!=null||R&&d)&&u.jsxs("div",{className:"bcard__menuwrap",ref:m,onClick:$=>$.stopPropagation(),children:[u.jsx("button",{type:"button",ref:k,"data-id":"TeamCard-menu-btn",className:"bcard__kebab",title:r("localTeams.more","更多"),disabled:G,onClick:mt,children:G?u.jsx(Ge,{}):u.jsx(oo,{})}),Qt&&xa.createPortal(u.jsxs("div",{className:"bcard__menu bcard__menu--portal","data-id":"TeamCard-menu",role:"menu",ref:K,style:{position:"fixed",top:At.top,left:At.left,width:F},onClick:$=>$.stopPropagation(),children:[oe&&u.jsx("button",{type:"button","data-id":"TeamCard-reload",className:"bcard__menu-item",onClick:yt,children:r("localTeams.reloadWindow","刷新窗口")}),le!=null&&u.jsx("button",{type:"button","data-id":"TeamCard-billing",className:"bcard__menu-item",onClick:$=>{$.stopPropagation(),z(!1),_i(`?team=${encodeURIComponent(le)}`)},children:r("localTeams.billing","账单")}),R&&d&&u.jsx("button",{type:"button","data-id":"TeamCard-edit-url",className:"bcard__menu-item",onClick:$=>{$.stopPropagation(),Ut()},children:dt?r("teamCard.editUrl","更改访问地址"):r("teamCard.setUrl","填写访问地址")}),R&&j&&u.jsx("button",{type:"button","data-id":"TeamCard-delete",className:"bcard__menu-item is-danger",onClick:$=>{$.stopPropagation(),z(!1),ne(!0)},children:r("teamCard.delete","删除")})]}),document.body)]})]})]}),u.jsxs("div",{className:"bcard__body",children:[u.jsxs("div",{style:{height:28,display:"flex",alignItems:"center",gap:8},children:[u.jsx(so,{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:D}),Z?u.jsx("input",{"data-id":"TeamCard-rename-input",autoFocus:!0,value:W,onChange:$=>L($.target.value),onFocus:$=>$.target.select(),onBlur:Jt,onClick:$=>$.stopPropagation(),onKeyDown:$=>{$.nativeEvent.isComposing||$.keyCode===229||($.key==="Enter"?Jt():$.key==="Escape"&&A(!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"}}):u.jsxs("h3",{className:"bcard__name",title:S?r("localTeams.renameHint","点名字或 ✎ 改名"):ht,style:{display:"flex",alignItems:"center",gap:6,flex:1,minWidth:0,margin:0},onDoubleClick:S?xt:void 0,children:[u.jsx("span",{onClick:S?xt:void 0,style:{overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap",cursor:S?"text":"default"},children:ht}),S&&u.jsx("button",{type:"button","data-id":"TeamCard-rename-btn",title:r("localTeams.rename","重命名"),onClick:xt,style:{flex:"none",cursor:"pointer",border:"none",background:"transparent",color:"#8b949e",fontSize:13,padding:0,lineHeight:1},children:"✎"})]})]}),u.jsxs("div",{className:"bcard__meta",children:[u.jsx("span",{className:"bcard__chip",children:Pt}),!R&&s.membership_status&&s.membership_status!=="active"&&u.jsx("span",{className:"bcard__chip",children:s.membership_status})]})]}),u.jsxs("button",{type:"button",className:"bcard__cta",onClick:g,disabled:!oe,children:[u.jsx(Hu,{}),u.jsx("span",{children:oe?r("localTeams.open","打开"):R?r("teamCard.noHost","未填访问地址"):r("teamCard.noUrl","无 URL")})]})]}),Lt&&xa.createPortal(u.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:$=>{$.target===$.currentTarget&&ut(!1)},children:u.jsxs("div",{onClick:$=>$.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:[u.jsx("div",{style:{fontSize:16,fontWeight:700,marginBottom:4},children:dt?r("teamCard.editUrl","更改访问地址"):r("teamCard.setUrl","填写访问地址")}),u.jsx("div",{style:{fontSize:12,opacity:.6,marginBottom:16},children:ht}),u.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:bt,placeholder:"https://你的私有云地址:端口",spellCheck:!1,onChange:$=>X($.target.value.replace(/[\r\n]+/g,"")),onKeyDown:$=>{$.nativeEvent.isComposing||$.keyCode===229||($.key==="Enter"?($.preventDefault(),Qe()):$.key==="Escape"&&ut(!1))}}),u.jsxs("div",{className:"modal-actions",children:[u.jsx("button",{type:"button",className:"btn-ghost",onClick:()=>ut(!1),children:r("common.cancel","取消")}),u.jsx("button",{type:"button",className:"btn-primary","data-id":"TeamCard-url-save",onClick:Qe,children:r("common.save","保存")})]})]})}),document.body),u.jsx(Dm,{open:_t,title:r("localTeams.deleteTitle","删除团队"),message:r("localTeams.deleteMsg","确定删除「{{name}}」?此操作不可撤销。",{name:ht}),confirmLabel:r("common.delete","删除"),danger:!0,onConfirm:async()=>{ne(!1),j&&await j(s)},onCancel:()=>ne(!1)})]})}function ao(){return u.jsxs("div",{className:"brand",children:[u.jsx("div",{className:"brand-mark",children:u.jsx(Sp,{})}),u.jsxs("div",{className:"brand-text",children:[u.jsx("div",{className:"brand-name",children:"CiCy Desktop"}),u.jsx("div",{className:"brand-sub",children:r("app.brandSub","团队 AI 协作工作台")})]})]})}function pp(){const[s,g]=v.useState(null),[S,d]=v.useState(!1),j=v.useRef(!1);v.useEffect(()=>{var h,Z,A,W,L,I;let R=!0;(A=(Z=(h=window.cicy)==null?void 0:h.app)==null?void 0:Z.updateState)==null||A.call(Z).then(V=>{R&&g(V)}).catch(()=>{});const w=(I=(L=(W=window.cicy)==null?void 0:W.app)==null?void 0:L.onUpdateState)==null?void 0:I.call(L,V=>{g(V),j.current&&(V.status==="downloading"?ye.setProgress(V.progress||{}):V.status==="ready"?ye.ready({onInstall:()=>{var ht,xt,Jt;return(Jt=(xt=(ht=window.cicy)==null?void 0:ht.app)==null?void 0:xt.installUpdate)==null?void 0:Jt.call(xt)}}):V.status==="error"&&(ye.finish({ok:!1,message:V.error||r("updateBanner.error","更新失败")}),j.current=!1))});return()=>{R=!1;try{w&&w()}catch{}}},[]);const M=s==null?void 0:s.status;v.useEffect(()=>{d(!1)},[M]);const D=()=>{var R,w,h;j.current=!0,d(!0),ye.open({kind:"app",title:r("updateBanner.drawerTitle","应用更新"),fromVer:s==null?void 0:s.current,toVer:s==null?void 0:s.version,onRetry:D}),ye.push({phase:"download",status:"running",message:r("updateBanner.startDl","开始下载安装包…")}),ye.setProgress({percent:0}),(h=(w=(R=window.cicy)==null?void 0:R.app)==null?void 0:w.downloadUpdate)==null||h.call(w)};return M!=="available"||S?null:xa.createPortal(u.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:R=>{R.target===R.currentTarget&&d(!0)},children:u.jsxs("div",{onClick:R=>R.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:[u.jsx("div",{style:{fontSize:34,lineHeight:1,marginBottom:12},"aria-hidden":!0,children:"🚀"}),u.jsx("h3",{style:{margin:"0 0 8px",fontSize:17,color:"#e6edf3"},"data-id":"UpdateBanner-text",children:r("updateBanner.available","发现新版本 v{{v}}",{v:s.version})}),u.jsx("p",{style:{margin:"0 0 20px",fontSize:13,lineHeight:1.6,color:"#9aa4b2"},children:r("updateBanner.modalSub","建议尽快更新到最新版本")}),u.jsxs("div",{style:{display:"flex",gap:10,justifyContent:"center"},children:[u.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","稍后")}),u.jsx("button",{type:"button","data-id":"UpdateBanner-download",onClick:D,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 gp(){return u.jsxs("div",{className:"bcard bcard--skeleton","data-id":"SkeletonCard","aria-hidden":!0,children:[u.jsx("div",{className:"bcard__accent",style:{background:"rgba(255,255,255,.08)",opacity:1}}),u.jsxs("div",{className:"bcard__top",children:[u.jsx("div",{className:"skel",style:{width:84,height:26,borderRadius:999}}),u.jsx("div",{className:"skel",style:{width:22,height:22,borderRadius:6}})]}),u.jsxs("div",{style:{flex:1,minHeight:0,marginTop:14},children:[u.jsxs("div",{style:{display:"flex",alignItems:"center",gap:8},children:[u.jsx("div",{className:"skel",style:{width:24,height:24,borderRadius:6,flex:"0 0 auto"}}),u.jsx("div",{className:"skel skel--line",style:{width:"55%"}})]}),u.jsx("div",{className:"skel",style:{width:60,height:18,borderRadius:6,marginTop:12}})]}),u.jsx("div",{className:"skel skel--cta",style:{marginTop:0}})]})}const Tm=["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 bp(s){s=String(s??"");let g=0;for(let S=0;S<s.length;S++)g=(g*31+s.charCodeAt(S))%100003;return g}function vp(s){return Tm[bp(s)%Tm.length]}function km({open:s,onClose:g,toastId:S="cft-op"}){const[d,j]=v.useState(!1),[M,D]=v.useState(""),[R,w]=v.useState({enabled:!1,token:"",host:""});v.useEffect(()=>{var A,W;!s||!((W=(A=window.cicy)==null?void 0:A.sidecar)!=null&&W.getCft)||(D(""),window.cicy.sidecar.getCft().then(L=>{L!=null&&L.cft&&w({enabled:!!L.cft.enabled,token:L.cft.token||"",host:L.cft.host||""})}).catch(()=>{}))},[s]);const h=async()=>{var A,W;if(!d){if(R.enabled){if(!String(R.token).trim()){D(r("sidecar.cftNeedToken","开启需要填 Tunnel Token"));return}if(!String(R.host).trim()){D(r("sidecar.cftNeedHost","公网域名 Host 不能为空"));return}}j(!0),D(""),St.show({id:S,message:r("sidecar.cftApplying","应用 Cloudflare Tunnel,重启中…"),status:"running",progress:void 0});try{const L=await window.cicy.sidecar.setCft(R);L!=null&&L.ok?(L.cft&&w(L.cft),(A=L.cft)!=null&&A.enabled&&!L.tunnelUp?(D(r("sidecar.cftTunnelDown","隧道未连上:Token 可能无效/过期,或域名未在 Cloudflare 配好路由")),St.show({id:S,message:r("sidecar.cftTunnelDown","隧道未连上:Token 可能无效…"),status:"error",ttl:7e3})):(g&&g(),St.show({id:S,message:(W=L.cft)!=null&&W.enabled?r("sidecar.cftConnected","隧道已连接")+(L.url?`: ${L.url}`:""):r("sidecar.cftOff","Cloudflare Tunnel 已关闭"),status:"done",ttl:4e3}))):(D((L==null?void 0:L.error)||r("sidecar.cftFailed","设置失败")),St.show({id:S,message:r("sidecar.cftFailed","设置失败")+(L!=null&&L.error?`: ${L.error}`:""),status:"error",ttl:6e3}))}catch(L){D((L==null?void 0:L.message)||String(L)),St.show({id:S,message:r("sidecar.cftFailed","设置失败")+`: ${(L==null?void 0:L.message)||L}`,status:"error",ttl:6e3})}finally{j(!1)}}},Z=A=>{g&&g()};return s?u.jsx(u.Fragment,{children:xa.createPortal(u.jsx("div",{"data-id":"cft-modal",style:{position:"fixed",inset:0,zIndex:66,display:"flex",alignItems:"center",justifyContent:"center",background:"rgba(0,0,0,.5)"},onMouseDown:A=>{!d&&A.target===A.currentTarget&&Z()},children:u.jsxs("div",{onClick:A=>A.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:[u.jsx("div",{style:{fontSize:16,fontWeight:700,marginBottom:4},children:r("sidecar.cftTitle","Cloudflare 隧道")}),u.jsx("div",{style:{fontSize:12,opacity:.6,marginBottom:16},children:r("sidecar.cftSubtitle","把本机 cicy-code 通过 Cloudflare 命名隧道暴露到固定公网域名")}),u.jsxs("label",{"data-id":"cft-toggle-row",style:{display:"flex",alignItems:"center",gap:10,cursor:d?"default":"pointer",marginBottom:16},children:[u.jsx("input",{type:"checkbox","data-id":"cft-toggle",checked:R.enabled,disabled:d,onChange:A=>w(W=>({...W,enabled:A.target.checked}))}),u.jsx("span",{style:{fontSize:14,fontWeight:600},children:r("sidecar.cftEnable","开启隧道")})]}),u.jsx("div",{style:{fontSize:12,opacity:.7,marginBottom:6},children:r("sidecar.cftToken","Tunnel Token")}),u.jsx("textarea",{"data-id":"cft-token",rows:3,className:"login-email-input",style:{width:"100%",resize:"vertical",lineHeight:1.4,fontFamily:"var(--mono)",wordBreak:"break-all"},value:R.token,placeholder:"eyJhIjoi…(粘贴 Cloudflare connector token)",spellCheck:!1,disabled:d,onChange:A=>w(W=>({...W,token:A.target.value.replace(/\s+/g,"")}))}),u.jsx("div",{style:{fontSize:12,opacity:.7,margin:"12px 0 6px"},children:r("sidecar.cftHost","公网域名 Host")}),u.jsx("input",{"data-id":"cft-host",className:"login-email-input",style:{width:"100%",fontFamily:"var(--mono)"},value:R.host,placeholder:"cloudshell.cicy-ai.com",spellCheck:!1,disabled:d,onChange:A=>w(W=>({...W,host:A.target.value.replace(/[\r\n\s]+/g,"").trim()})),onKeyDown:A=>{A.key==="Escape"&&!d&&Z()}}),M&&u.jsx("div",{className:"error",style:{marginTop:8,fontSize:12},children:M}),u.jsxs("div",{className:"modal-actions",children:[u.jsx("button",{type:"button",className:"btn-ghost",disabled:d,onClick:()=>Z(),children:r("common.cancel","取消")}),u.jsx("button",{type:"button",className:"btn-primary","data-id":"cft-save",disabled:d,onClick:h,children:d?r("common.saving","保存中…"):r("common.save","保存")})]})]})}),document.body)}):null}function so({avatar:s,name:g,teamId:S,onChanged:d,size:j=34}){const M=v.useRef(null),D=((g||"?").trim()[0]||"?").toUpperCase(),R=vp(S||g||""),w=h=>{const Z=h.target.files&&h.target.files[0];if(h.target.value="",!Z)return;const A=new FileReader;A.onload=async()=>{var W,L,I;try{await((I=(L=(W=window.cicy)==null?void 0:W.localTeams)==null?void 0:L.setAvatar)==null?void 0:I.call(L,S,A.result)),d&&d()}catch{}},A.readAsDataURL(Z)};return u.jsxs("div",{"data-id":"TeamAvatar",className:"team-avatar",title:S?r("teamCard.changeAvatar","点击更换头像"):"",onClick:S?h=>{h.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":R,color:"#fff",fontWeight:700,fontSize:Math.round(j*.42),userSelect:"none"},children:[s?u.jsx("img",{src:s,alt:"",style:{width:"100%",height:"100%",objectFit:"cover"}}):D,S&&u.jsx("input",{ref:M,type:"file",accept:"image/*",style:{display:"none"},onChange:w})]})}function Sp(){return u.jsx("svg",{width:"22",height:"22",viewBox:"0 0 96 96",fill:"none",children:u.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",fill:"white",stroke:"white",strokeWidth:"8",strokeLinejoin:"round",strokeLinecap:"round"})})}function Hu(){return u.jsxs("svg",{width:"16",height:"16",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2.2",strokeLinecap:"round",strokeLinejoin:"round",children:[u.jsx("line",{x1:"5",y1:"12",x2:"19",y2:"12"}),u.jsx("polyline",{points:"12 5 19 12 12 19"})]})}function Ge(){return u.jsx("svg",{className:"spin",width:"16",height:"16",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2.4",strokeLinecap:"round",children:u.jsx("path",{d:"M21 12a9 9 0 1 1-6.2-8.55"})})}function xp(){return u.jsxs("svg",{width:"12",height:"12",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:[u.jsx("rect",{x:"3",y:"4",width:"18",height:"12",rx:"2"}),u.jsx("line",{x1:"2",y1:"20",x2:"22",y2:"20"})]})}function oo(){return u.jsxs("svg",{width:"16",height:"16",viewBox:"0 0 24 24",fill:"currentColor","aria-hidden":!0,children:[u.jsx("circle",{cx:"12",cy:"5",r:"1.7"}),u.jsx("circle",{cx:"12",cy:"12",r:"1.7"}),u.jsx("circle",{cx:"12",cy:"19",r:"1.7"})]})}function _p(){return u.jsxs("svg",{width:"12",height:"12",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:[u.jsx("circle",{cx:"12",cy:"12",r:"10"}),u.jsx("line",{x1:"2",y1:"12",x2:"22",y2:"12"}),u.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 Si(s){try{return localStorage.getItem(s)||null}catch{return null}}function Wa(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 Cm;const wp=((Cm=window.cicy)==null?void 0:Cm.platform)||(()=>{const s=navigator.userAgent||"";return/Mac/i.test(s)?"darwin":/Windows/i.test(s)?"win32":"linux"})();document.documentElement.dataset.platform=wp;document.documentElement.dataset.fullscreen="0";var jm,zm;(zm=(jm=window.cicy)==null?void 0:jm.window)!=null&&zm.onFullscreen&&window.cicy.window.onFullscreen(s=>{document.documentElement.dataset.fullscreen=s?"1":"0"});Iy.createRoot(document.getElementById("root")).render(u.jsx(up,{}));
|
|
377
|
+
`)}const r=(s,g,S)=>{var j,M;const d=D=>S&&typeof D=="string"?D.replace(/\{\{\s*(\w+)\s*\}\}/g,(R,w)=>S[w]!=null?String(S[w]):R):D;try{const D=(M=(j=window.cicyI18n)==null?void 0:j.t)==null?void 0:M.call(j,s,S);return d(D&&D!==s?D:g)}catch{return d(g)}},jn="cicy_token",Uu="cicy_access_token",Ru="cicy_user_id",ql="https://cicy-ai.com",ap=1;async function _i(s){var S,d,j,M,D,R,w,h;const g=`${ql}/dash${s}`;try{if((d=(S=window.cicy)==null?void 0:S.tabs)!=null&&d.openIn){await window.cicy.tabs.openIn(ap,g,"cicy-ai");return}(D=(M=(j=window.cicy)==null?void 0:j.shell)==null?void 0:M.openExternal)==null||D.call(M,g)}catch{try{(h=(w=(R=window.cicy)==null?void 0:R.shell)==null?void 0:w.openExternal)==null||h.call(w,g)}catch{}}}const lo=new Set;let lp=0,xl=[];const vi=new Map;function pm(){lo.forEach(s=>s(xl))}const St={show(s={}){const g=s.id||`t${++lp}`,S=xl.find(M=>M.id===g),d={id:g,status:"running",...S,...s};xl=S?xl.map(M=>M.id===g?d:M):[...xl,d],pm();const j=vi.get(g);return j&&(clearTimeout(j),vi.delete(g)),s.ttl&&vi.set(g,setTimeout(()=>St.dismiss(g),s.ttl)),g},dismiss(s){xl=xl.filter(S=>S.id!==s);const g=vi.get(s);g&&(clearTimeout(g),vi.delete(s)),pm()}};function np(){const[s,g]=v.useState(xl);return v.useEffect(()=>(lo.add(g),()=>{lo.delete(g)}),[]),s.length?u.jsx("div",{className:"toast-host","data-id":"ToastHost",children:s.map(S=>u.jsxs("div",{className:"toast","data-id":`Toast-${S.id}`,"data-status":S.status||"running",children:[u.jsx("button",{type:"button",className:"toast__x","data-id":"Toast-dismiss",onClick:()=>St.dismiss(S.id),"aria-label":"dismiss",children:"×"}),u.jsxs("span",{className:"toast__msg",children:[S.message,Number.isFinite(S.progress)?` ${S.progress}%`:""]}),Number.isFinite(S.progress)&&u.jsx("span",{className:"toast__bar",children:u.jsx("span",{style:{width:`${Math.min(100,S.progress)}%`}})})]},S.id))}):null}const no=new Set;let Ps=0,Kt=null;function Sl(){no.forEach(s=>s(Kt))}function xi(){return new Date().toTimeString().slice(0,8)}const ye={open({teamId:s,fromVer:g,toVer:S,onRetry:d,title:j,kind:M}={}){Kt={teamId:s,title:j||null,fromVer:g||null,toVer:S||null,kind:M||"sidecar",status:"running",phase:"download",progress:null,onInstall:null,logs:[],onRetry:d||null,lastAt:Date.now()},Sl()},setProgress(s){Kt&&(Kt={...Kt,status:"running",progress:s||Kt.progress,lastAt:Date.now()},Sl())},ready({onInstall:s,message:g}={}){if(!Kt)return;const S={id:++Ps,t:xi(),phase:"done",status:"done",message:g||r("updateBanner.readyDrawer","下载完成,点「安装」重启更新")};Kt={...Kt,status:"ready",phase:"done",progress:{...Kt.progress||{},percent:100},onInstall:s||null,minimized:!1,logs:[...Kt.logs,S],lastAt:Date.now()},Sl()},push(s={}){if(!Kt)return;const g={id:++Ps,t:xi(),phase:s.phase||Kt.phase,status:s.status||"running",message:s.message||""};Kt={...Kt,phase:s.phase||Kt.phase,toVer:s.toVer||Kt.toVer,logs:[...Kt.logs,g],lastAt:Date.now()},Sl()},minimize(){Kt&&(Kt={...Kt,minimized:!0},Sl())},restore(){Kt&&(Kt={...Kt,minimized:!1},Sl())},finish({ok:s,message:g}={}){if(!Kt)return;const S=s?"done":"error",d={id:++Ps,t:xi(),phase:"done",status:S,message:g||(s?r("updateDrawer.done","更新完成"):r("updateDrawer.failed","更新失败"))};Kt={...Kt,status:S,phase:"done",minimized:!1,logs:[...Kt.logs,d],lastAt:Date.now()},Sl()},close(){Kt=null,Sl()}},to=["download","swap","done"],gm=s=>({download:r("updateDrawer.phaseDownload","下载"),swap:r("updateDrawer.phaseSwap","切换"),done:r("updateDrawer.phaseDone","完成")})[s]||s;function ip(){var R;const[s,g]=v.useState(Kt);v.useEffect(()=>(no.add(g),()=>{no.delete(g)}),[]);const S=v.useRef(null);v.useEffect(()=>{const w=S.current;w&&(w.scrollTop=w.scrollHeight)},[(R=s==null?void 0:s.logs)==null?void 0:R.length]);const[d,j]=v.useState(!1);if(v.useEffect(()=>{if(!s||s.status!=="running"){j(!1);return}const w=setInterval(()=>j(Date.now()-(s.lastAt||0)>25e3),3e3);return()=>clearInterval(w)},[s==null?void 0:s.lastAt,s==null?void 0:s.status]),!s)return null;const M=s.status==="running",D=to.findIndex(w=>w===s.phase);return s.minimized?u.jsxs("button",{type:"button",className:`drawer-min drawer-min--${s.status}`,"data-id":"UpdateDrawer-restore",onClick:()=>ye.restore(),children:[u.jsx("span",{className:"drawer-min__spark",children:M?u.jsx(Ge,{}):s.status==="done"?"✓":s.status==="reboot"?"⟳":"!"}),u.jsxs("span",{className:"drawer-min__label",children:[s.title||r("updateDrawer.title","更新 cicy-code"),s.toVer?` · v${s.toVer}`:""]})]}):u.jsx("div",{className:"drawer-scrim","data-id":"UpdateDrawer-scrim",onClick:()=>M?ye.minimize():ye.close(),children:u.jsxs("div",{className:"drawer","data-id":"UpdateDrawer","data-status":s.status,onClick:w=>w.stopPropagation(),children:[u.jsxs("div",{className:"drawer__head",children:[u.jsxs("div",{className:"drawer__title",children:[u.jsx("span",{className:`drawer__spark drawer__spark--${s.status}`,children:M?u.jsx(Ge,{}):s.status==="done"?"✓":s.status==="reboot"?"⟳":"!"}),u.jsxs("div",{children:[u.jsx("div",{className:"drawer__h",children:s.title||r("updateDrawer.title","更新 cicy-code")}),u.jsxs("div",{className:"drawer__sub",children:[s.fromVer?`v${s.fromVer}`:r("updateDrawer.current","当前")," → ",s.toVer?`v${s.toVer}`:r("updateDrawer.latest","最新版")]})]})]}),u.jsx("div",{className:"drawer__headbtns",children:u.jsx("button",{type:"button",className:"drawer__x","data-id":"UpdateDrawer-min",title:r("updateDrawer.minimize","最小化"),onClick:()=>ye.minimize(),"aria-label":"minimize",children:"‒"})})]}),s.kind!=="app"&&u.jsx("div",{className:"drawer__steps","data-id":"UpdateDrawer-steps",children:to.map((w,h)=>{const Z=gm(w),A=s.status==="done"||h<D,W=h===D&&M,L=s.status==="error"&&h===D;return u.jsxs("div",{className:`drawer__step${W?" is-active":""}${A?" is-done":""}${L?" is-error":""}`,children:[u.jsx("span",{className:"drawer__step-dot",children:A?"✓":L?"!":h+1}),u.jsx("span",{className:"drawer__step-label",children:Z}),h<to.length-1&&u.jsx("span",{className:"drawer__step-bar"})]},w)})}),s.progress&&(()=>{const w=s.progress,h=Z=>Z?(Z/1048576).toFixed(1):"0";return u.jsxs("div",{className:"drawer__dl","data-id":"UpdateDrawer-dl",children:[u.jsxs("div",{className:"drawer__dl-head",children:[u.jsxs("span",{className:"drawer__dl-pct",children:[w.percent||0,"%"]}),u.jsxs("span",{className:"drawer__dl-stats",children:[w.total?`${h(w.transferred)} / ${h(w.total)} MB`:`${h(w.transferred)} MB`,w.bytesPerSec?` · ${h(w.bytesPerSec)} MB/s`:"",w.etaSec?` · ${r("updateBanner.eta","剩 {{s}}s",{s:w.etaSec})}`:""]})]}),u.jsx("div",{className:"drawer__dl-track",children:u.jsx("span",{className:"drawer__dl-fill",style:{width:`${w.percent||0}%`}})})]})})(),u.jsx("div",{className:"drawer__log","data-id":"UpdateDrawer-log",ref:S,children:s.logs.length===0?u.jsx("div",{className:"drawer__log-empty",children:r("updateDrawer.preparing","准备中…")}):s.logs.map(w=>u.jsxs("div",{className:"drawer__line","data-status":w.status,children:[u.jsx("span",{className:"drawer__t",children:w.t}),u.jsx("span",{className:`drawer__badge drawer__badge--${w.phase}`,children:gm(w.phase)}),u.jsx("span",{className:"drawer__linemsg",children:w.message})]},w.id))}),d&&M&&u.jsx("div",{className:"drawer__hint","data-id":"UpdateDrawer-stuck",children:r("updateDrawer.stuckHint","正在等待新版本就绪,耗时比平常久。可以放到后台继续,完成或失败都会提示。")}),u.jsx("div",{className:"drawer__foot",children:M?u.jsx(u.Fragment,{children:u.jsx("span",{className:"drawer__foot-status",children:s.kind==="app"?r("updateBanner.downloading","正在下载更新")+"…":r("updateDrawer.inProgress","更新进行中…")})}):s.status==="ready"?u.jsxs(u.Fragment,{children:[u.jsx("span",{className:"drawer__foot-status is-done",children:r("updateBanner.readyShort","下载完成")}),u.jsx("button",{type:"button",className:"drawer__btn is-accent","data-id":"UpdateDrawer-install",onClick:()=>s.onInstall&&s.onInstall(),children:r("updateBanner.installBtn","立即安装")}),u.jsx("button",{type:"button",className:"drawer__btn","data-id":"UpdateDrawer-later",onClick:()=>ye.close(),children:r("updateBanner.later","稍后")})]}):s.status==="error"?u.jsxs(u.Fragment,{children:[u.jsx("span",{className:"drawer__foot-status is-error",children:r("updateDrawer.failed","更新失败")}),s.onRetry&&u.jsx("button",{type:"button",className:"drawer__btn is-accent","data-id":"UpdateDrawer-retry",onClick:()=>s.onRetry(),children:r("common.retry","重试")}),u.jsx("button",{type:"button",className:"drawer__btn","data-id":"UpdateDrawer-dismiss",onClick:()=>ye.close(),children:r("common.close","关闭")})]}):u.jsxs(u.Fragment,{children:[u.jsx("span",{className:"drawer__foot-status is-done",children:r("updateDrawer.updatedLatest","已更新到最新")}),u.jsx("button",{type:"button",className:"drawer__btn is-accent","data-id":"UpdateDrawer-finish",onClick:()=>ye.close(),children:r("common.done","完成")})]})})]})})}function up(){const[s,g]=v.useState(void 0);v.useEffect(()=>{var C,Y;if(!((Y=(C=window.cicy)==null?void 0:C.terms)!=null&&Y.status)){g(!0);return}window.cicy.terms.status(Am).then(B=>g(!!(B!=null&&B.accepted))).catch(()=>g(!0))},[]),v.useEffect(()=>{var B,J,et,Vt;const C=document.documentElement;try{C.setAttribute("data-platform",((B=window.cicy)==null?void 0:B.platform)||"linux")}catch{}C.setAttribute("data-fullscreen","0");let Y;try{Y=(Vt=(et=(J=window.cicy)==null?void 0:J.window)==null?void 0:et.onFullscreen)==null?void 0:Vt.call(et,Ct=>C.setAttribute("data-fullscreen",Ct?"1":"0"))}catch{}return()=>{try{Y&&Y()}catch{}}},[]),v.useEffect(()=>{var Y,B;if(!((B=(Y=window.cicy)==null?void 0:Y.docker)!=null&&B.onAppProgress))return;const C=window.cicy.docker.onAppProgress(J=>{!J||J.phase==="open"||(Bt||Et.open({source:"auto"}),(Bt==null?void 0:Bt.source)==="auto"&&(J.phase==="done"&&(J.status==="done"||J.status==="reboot")?Et.finish({ok:J.status==="done",status:J.status==="reboot"?"reboot":void 0,message:J.message}):J.status==="error"?Et.finish({ok:!1,message:J.message}):Et.push(J)))});return()=>{try{C&&C()}catch{}}},[]);const[S,d]=v.useState(()=>Si(jn)),[j,M]=v.useState(()=>Si(Uu)),[D,R]=v.useState(()=>Si(Ru)),[w,h]=v.useState(()=>!Si(jn)),[Z,A]=v.useState(!1),[W,L]=v.useState(!1),[I,V]=v.useState(""),[ht,xt]=v.useState(""),[Jt,dt]=v.useState(!1),[Lt,ut]=v.useState(""),[bt,X]=v.useState(""),[ot,q]=v.useState(null),[Zt,le]=v.useState(null),[Pt,ve]=v.useState(!1),[oe,Qt]=v.useState(""),z=v.useRef(!1),[G,rt]=v.useState(null),[At,Tt]=v.useState(!1),[m,k]=v.useState(!1),[K,F]=v.useState({}),mt=v.useCallback(async()=>{var C,Y,B;try{const J=await((B=(Y=(C=window.cicy)==null?void 0:C.localTeams)==null?void 0:Y.avatars)==null?void 0:B.call(Y));F(J&&typeof J=="object"?J:{})}catch{}},[]),[yt,_t]=v.useState(!1),[ne,Ut]=v.useState(!1),[Qe,$]=v.useState(""),[qt,de]=v.useState(""),[Wt,De]=v.useState(!1),[Te,Le]=v.useState(""),[ke,ca]=v.useState("all"),Me=v.useCallback(async(C,Y)=>{var J,et,Vt,Ct;if(!C)return;if(!((et=(J=window.cicy)==null?void 0:J.cloud)!=null&&et.fetch)){Qt("cloud fetch bridge missing");return}ve(!0),Qt("");const B={Authorization:`Bearer ${C}`};try{const[Pe,qe]=await Promise.all([window.cicy.cloud.fetch(`${ql}/api/user/self`,{headers:B}),window.cicy.cloud.fetch(`${ql}/api/teams`,{headers:B})]);if((qe==null?void 0:qe.status)===401){if(!z.current&&((Ct=(Vt=window.cicy)==null?void 0:Vt.auth)!=null&&Ct.loginStart)){z.current=!0,Qt(r("auth.sessionExpired","会话已过期,正在重新登录…"));try{await window.cicy.auth.loginStart()}catch{}}return}if(qe!=null&&qe.ok){const Ee=JSON.parse(qe.body||"{}");le(Array.isArray(Ee==null?void 0:Ee.teams)?Ee.teams:[])}if(Pe!=null&&Pe.ok)try{const Ee=JSON.parse(Pe.body||"{}");q((Ee==null?void 0:Ee.success)===!1?null:(Ee==null?void 0:Ee.data)||null)}catch{q(null)}else q(null)}catch{Qt("")}finally{ve(!1)}},[]),Ie=v.useRef("");v.useEffect(()=>{Ie.current=S||j||""},[S,j]);const fe=v.useCallback(async()=>{var Y,B;const C=Ie.current;if(!(!C||!((B=(Y=window.cicy)==null?void 0:Y.cloud)!=null&&B.fetch)))try{const J=await window.cicy.cloud.fetch(`${ql}/api/teams`,{headers:{Authorization:`Bearer ${C}`}});if(J!=null&&J.ok){const et=JSON.parse(J.body||"{}");Array.isArray(et==null?void 0:et.teams)&&le(et.teams)}}catch{}},[]),sa=v.useCallback(async(C,Y)=>{var et,Vt;const B=Ie.current,J=String(Y||"").trim();if(!B||!((Vt=(et=window.cicy)==null?void 0:et.cloud)!=null&&Vt.fetch)||!J)return{ok:!1,error:"no session / empty"};try{const Ct=await window.cicy.cloud.fetch(`${ql}/api/teams/${C}`,{method:"PATCH",headers:{Authorization:`Bearer ${B}`,"Content-Type":"application/json"},body:JSON.stringify({title:J})});return Ct!=null&&Ct.ok?(await fe(),{ok:!0}):{ok:!1,error:`${(Ct==null?void 0:Ct.status)||"?"} ${(Ct==null?void 0:Ct.error)||""}`}}catch(Ct){return{ok:!1,error:Ct.message}}},[fe]),pe=v.useCallback(async(C,Y)=>{var et,Vt;const B=Ie.current,J=String(Y||"").trim();if(!B||!((Vt=(et=window.cicy)==null?void 0:et.cloud)!=null&&Vt.fetch)||!J)return{ok:!1,error:"no session / empty"};try{new URL(J)}catch{return{ok:!1,error:"地址格式不对(需 http(s)://…)"}}try{const Ct=await window.cicy.cloud.fetch(`${ql}/api/teams/${C}`,{method:"PATCH",headers:{Authorization:`Bearer ${B}`,"Content-Type":"application/json"},body:JSON.stringify({hostUrl:J})});return Ct!=null&&Ct.ok?(await fe(),{ok:!0}):{ok:!1,error:`${(Ct==null?void 0:Ct.status)||"?"} ${(Ct==null?void 0:Ct.error)||""}`}}catch(Ct){return{ok:!1,error:Ct.message}}},[fe]),H=v.useCallback(async C=>{var B,J;const Y=Ie.current;if(!Y||!((J=(B=window.cicy)==null?void 0:B.cloud)!=null&&J.fetch)){St.show({message:r("common.noAuth","未登录"),status:"error",ttl:5e3});return}try{const et=await window.cicy.cloud.fetch(`${ql}/api/teams/${C.id}`,{method:"DELETE",headers:{Authorization:`Bearer ${Y}`}});et!=null&&et.ok||(et==null?void 0:et.status)===200||(et==null?void 0:et.status)===204?(St.show({message:r("teamCard.deleted","团队已删除"),status:"done",ttl:3e3}),await fe()):St.show({message:`${r("teamCard.deleteFailed","删除失败")}: ${(et==null?void 0:et.status)||"?"} ${(et==null?void 0:et.error)||""}`,status:"error",ttl:7e3})}catch(et){St.show({message:`${r("teamCard.deleteFailed","删除失败")}: ${et.message}`,status:"error",ttl:7e3})}},[fe]);v.useEffect(()=>{const C=S||j;C&&Me(C,D)},[S,j,D,Me]);const P=v.useCallback(async()=>{var C,Y;if((Y=(C=window.cicy)==null?void 0:C.localTeams)!=null&&Y.list){Tt(!0);try{const B=await window.cicy.localTeams.list({refresh:!0});rt(Array.isArray(B)?B:[])}catch{rt([])}finally{Tt(!1),k(!0)}}},[]);async function lt(){if(Wt)return;const C=qt.trim();if(!C){Le(r("teams.urlRequired","请输入地址 URL"));return}try{new URL(C)}catch{Le(r("teams.badUrl","URL 无效(需含 http(s)://)"));return}Le(""),De(!0);try{const Y=await window.cicy.localTeams.add({base_url:C,name:Qe.trim(),failIfExists:!0});if(!Y||Y.ok===!1){Le((Y==null?void 0:Y.error)==="exists"?r("teams.urlExists","该地址已存在"):Wa((Y==null?void 0:Y.error)||"add failed"));return}await P(),$(""),de(""),Ut(!1)}catch(Y){Le(Wa((Y==null?void 0:Y.message)||String(Y)))}finally{De(!1)}}const it=v.useCallback(async(C,Y)=>{var J,et;if(!((et=(J=window.cicy)==null?void 0:J.localTeams)!=null&&et.update))return{ok:!1,error:"no_bridge"};let B;try{B=await window.cicy.localTeams.update(C,{name:String(Y||"").trim()||r("localTeams.unnamed","未命名")})}catch(Vt){B={ok:!1,error:(Vt==null?void 0:Vt.message)||String(Vt)}}return await P(),B||{ok:!1,error:"no_result"}},[P]);v.useEffect(()=>{let C,Y=!1;const B=3e3,J=3e4,et=async()=>{var Pe,qe,Ee;try{await((Ee=(qe=(Pe=window.cicy)==null?void 0:Pe.localTeams)==null?void 0:qe.syncCloud)==null?void 0:Ee.call(qe))}catch{}await Promise.all([P(),fe(),mt()])},Vt=()=>{if(Y)return;const Pe=document.visibilityState==="visible";C=setTimeout(async()=>{document.visibilityState==="visible"?await et():await P(),Vt()},Pe?B:J)};et(),Vt();const Ct=()=>{document.visibilityState==="visible"&&et()};return document.addEventListener("visibilitychange",Ct),window.addEventListener("focus",Ct),()=>{Y=!0,clearTimeout(C),document.removeEventListener("visibilitychange",Ct),window.removeEventListener("focus",Ct)}},[P,fe]),v.useEffect(()=>{var Y,B;if(!((B=(Y=window.cicy)==null?void 0:Y.localTeams)!=null&&B.onWebviewRelay))return;const C=window.cicy.localTeams.onWebviewRelay(async({reqId:J,msg:et})=>{let Vt={ok:!1,error:"unknown relay type"};try{(et==null?void 0:et.type)==="localTeams:add"?Vt=await window.cicy.localTeams.add(et.spec||{}):(et==null?void 0:et.type)==="localTeams:remove"?Vt=await window.cicy.localTeams.remove(et.id):(et==null?void 0:et.type)==="localTeams:update"?Vt=await window.cicy.localTeams.update(et.id,et.patch||{}):(et==null?void 0:et.type)==="localTeams:upgrade"?Vt=await window.cicy.localTeams.upgrade(et.id):(et==null?void 0:et.type)==="localTeams:list"&&(Vt={ok:!0,teams:await window.cicy.localTeams.list({refresh:!0})}),P()}catch(Ct){Vt={ok:!1,error:(Ct==null?void 0:Ct.message)||String(Ct)}}try{window.cicy.localTeams.replyWebviewRelay(J,Vt)}catch{}});return()=>{try{C==null||C()}catch{}}},[P]);const Nt=v.useCallback(async C=>{var Y,B;if((B=(Y=window.cicy)==null?void 0:Y.localTeams)!=null&&B.open)try{await window.cicy.localTeams.open(C)}catch{}},[]);v.useEffect(()=>{var Y,B;if(Si(jn)){h(!1);return}if(!((B=(Y=window.cicy)==null?void 0:Y.auth)!=null&&B.getSaved)){h(!1);return}let C=!1;return(async()=>{try{const J=await window.cicy.auth.getSaved();if(C)return;if(J!=null&&J.token){try{localStorage.setItem(jn,J.token)}catch{}if(d(J.token),J.accessToken){try{localStorage.setItem(Uu,J.accessToken)}catch{}M(J.accessToken)}if(J.userId){try{localStorage.setItem(Ru,String(J.userId))}catch{}R(String(J.userId))}}}catch{}finally{C||h(!1)}})(),()=>{C=!0}},[]),v.useEffect(()=>{var C,Y;if((Y=(C=window.cicy)==null?void 0:C.auth)!=null&&Y.onComplete)return window.cicy.auth.onComplete(B=>{if(A(!1),dt(!1),B!=null&&B.error){ut(Wa(B.error));return}if(B!=null&&B.token){z.current=!1,Qt("");try{localStorage.setItem(jn,B.token)}catch{}if(d(B.token),B.accessToken){try{localStorage.setItem(Uu,B.accessToken)}catch{}M(B.accessToken)}if(B.userId){try{localStorage.setItem(Ru,String(B.userId))}catch{}R(String(B.userId))}ut(""),X(B.reused?r("auth.welcomeBack","已恢复你之前的登录"):r("auth.loginSuccess","登录成功")),setTimeout(()=>X(""),3e3)}})},[]);async function Rt(){var C,Y;if(!(W||Z)){if(!((Y=(C=window.cicy)==null?void 0:C.auth)!=null&&Y.loginStart)){ut("auth bridge missing");return}ut(""),L(!0);try{const B=await window.cicy.auth.loginStart();if(!(B!=null&&B.ok)){ut(Wa((B==null?void 0:B.error)||"login start failed"));return}V(B.url||""),A(!0)}catch(B){ut(Wa((B==null?void 0:B.message)||String(B)))}finally{L(!1)}}}async function ie(){var Y,B;if(W)return;if(!((B=(Y=window.cicy)==null?void 0:Y.auth)!=null&&B.emailLoginStart)){ut("auth bridge missing");return}const C=ht.trim();if(!/^[^@\s]+@[^@\s]+\.[^@\s]+$/.test(C)){ut(r("auth.badEmail","请输入有效的邮箱地址"));return}ut(""),L(!0);try{const J=await window.cicy.auth.emailLoginStart(C);if(!(J!=null&&J.ok)){ut(Wa((J==null?void 0:J.error)||"email login failed"));return}dt(!0)}catch(J){ut(Wa((J==null?void 0:J.message)||String(J)))}finally{L(!1)}}function b(){var C,Y,B;try{localStorage.removeItem(jn),localStorage.removeItem(Uu),localStorage.removeItem(Ru)}catch{}try{(B=(Y=(C=window.cicy)==null?void 0:C.auth)==null?void 0:Y.logout)==null||B.call(Y)}catch{}d(null),M(null),R(null),q(null),le(null),ut(""),Qt("")}if(s===void 0)return u.jsxs("div",{className:"shell","data-id":"TermsCheckingSplash",children:[u.jsx("div",{className:"glow","aria-hidden":!0}),u.jsxs("div",{className:"card",children:[u.jsx(ao,{}),u.jsx("div",{className:"spinner-row",children:u.jsx(Ge,{})})]})]});if(!s)return u.jsx(Nm,{onAgree:()=>g(!0)});if(!S&&w)return u.jsxs("div",{className:"shell","data-id":"AuthRestoringSplash",children:[u.jsx("div",{className:"glow","aria-hidden":!0}),u.jsxs("div",{className:"card",children:[u.jsx(ao,{}),u.jsxs("div",{className:"spinner-row",children:[u.jsx(Ge,{}),u.jsx("span",{children:r("auth.restoring","正在恢复登录…")})]})]})]});if(!S)return u.jsxs("div",{className:"shell",children:[u.jsx("div",{className:"glow","aria-hidden":!0}),u.jsxs("div",{className:"card",children:[u.jsx(ao,{}),!Z&&!Jt&&u.jsxs(u.Fragment,{children:[u.jsx("p",{className:"tagline",children:r("auth.tagline","登录以同步你的团队、配置与 AI 助手")}),u.jsx("label",{className:"login-label","data-id":"EmailLoginLabel",htmlFor:"cicy-email-login",children:r("auth.emailLabel","输入邮箱,用邮件链接登录")}),u.jsx("input",{id:"cicy-email-login",type:"email",className:"login-email-input","data-id":"EmailLoginInput",value:ht,onChange:C=>xt(C.target.value),onKeyDown:C=>{C.key==="Enter"&&ie()},placeholder:r("auth.emailPlaceholder","you@example.com"),autoComplete:"email",spellCheck:!1,autoFocus:!0}),u.jsx("button",{className:"btn-primary","data-id":"EmailLoginSubmit",onClick:ie,disabled:W,children:W?u.jsxs(u.Fragment,{children:[u.jsx(Ge,{}),u.jsx("span",{children:r("auth.sending","发送中…")})]}):u.jsxs(u.Fragment,{children:[u.jsx("span",{children:r("auth.emailLogin","发送登录链接")}),u.jsx(Hu,{})]})}),u.jsx("p",{className:"hint",children:r("auth.emailHint","手机上点邮件里的链接,也能登录这台电脑")}),u.jsx("div",{className:"login-divider","data-id":"LoginDivider",children:u.jsx("span",{children:r("auth.or","或")})}),u.jsx("button",{className:"btn-ghost","data-id":"BrowserLoginBtn",onClick:Rt,disabled:W,children:W?r("auth.opening","打开中…"):r("auth.browserLogin","用浏览器登录(Google / SSO,仅同一台电脑)")})]}),Jt&&u.jsxs(u.Fragment,{children:[u.jsx("p",{className:"tagline","data-id":"EmailSentTagline",children:r("auth.emailSentTagline","登录邮件已发送")}),u.jsxs("p",{className:"hint","data-id":"EmailSentHint",style:{textAlign:"center"},children:[r("auth.emailSentHint","到邮箱打开链接即可(手机、电脑都行),这里会自动登录。"),u.jsx("br",{}),ht]}),u.jsxs("div",{className:"spinner-row",children:[u.jsx(Ge,{}),u.jsx("span",{children:r("auth.emailWaiting","等待确认…")})]}),u.jsx("button",{className:"btn-ghost","data-id":"EmailSentCancel",onClick:()=>{var C,Y,B;(B=(Y=(C=window.cicy)==null?void 0:C.auth)==null?void 0:Y.emailLoginCancel)==null||B.call(Y),dt(!1)},children:r("auth.cancel","取消")})]}),Z&&u.jsxs(u.Fragment,{children:[u.jsx("p",{className:"tagline",children:r("auth.waitingTagline","已在浏览器打开登录页,等待你完成…")}),u.jsxs("div",{className:"spinner-row",children:[u.jsx(Ge,{}),u.jsx("span",{children:r("auth.waitingCallback","等待回调")})]}),I&&u.jsxs("div",{className:"login-fallback","data-id":"LoginUrlFallback",style:{marginTop:10,textAlign:"center"},children:[u.jsx("p",{className:"hint",style:{marginBottom:6},children:r("auth.browserNotOpened","浏览器没自动打开?")}),u.jsx("button",{className:"btn-ghost","data-id":"LoginUrlFallback-open",onClick:()=>{var C,Y,B;try{(B=(Y=(C=window.cicy)==null?void 0:C.shell)==null?void 0:Y.openExternal)==null||B.call(Y,I)}catch{}},children:r("auth.openManually","手动打开登录页")}),u.jsx("button",{className:"btn-ghost","data-id":"LoginUrlFallback-copy",onClick:()=>{var C;try{(C=navigator.clipboard)==null||C.writeText(I),X(r("auth.linkCopied","链接已复制,粘到浏览器打开")),setTimeout(()=>X(""),2500)}catch{}},children:r("auth.copyLink","复制链接")}),u.jsx("p",{className:"hint","data-id":"LoginUrlFallback-url",style:{wordBreak:"break-all",marginTop:6,fontSize:11,opacity:.7,userSelect:"text"},children:I})]}),u.jsx("button",{className:"btn-ghost",onClick:()=>{var C,Y,B;(B=(Y=(C=window.cicy)==null?void 0:C.auth)==null?void 0:Y.loginCancel)==null||B.call(Y),A(!1),V("")},children:r("auth.cancel","取消")})]}),Lt&&u.jsx("div",{className:"error",children:Lt})]})]});const Q=(G||[]).find(C=>xm(C.base_url))||null,tt=Q&&Q.cloud_team_id?(Zt||[]).find(C=>String(C.teamId||C.id)===String(Q.cloud_team_id)):null,at=C=>{if(!C)return null;const Y=(Zt||[]).find(B=>String(B.teamId||B.id)===String(C));return Y&&Y.code||null},ct=(G||[]).filter(C=>uo(C.base_url)),pt=(G||[]).filter(C=>!uo(C.base_url)&&!xm(C.base_url)),zt=ct.length,ze=pt.length,oa=(Zt||[]).filter(C=>!C.is_local&&C.kind!=="local"&&(C.kind==="private"||C.team_kind==="personal")),Ca=oa.length,$t=ke==="all"||ke==="local",Ce=ke==="all"||ke==="custom",Na=ke==="all"||ke==="cloud",ra=G===null&&Zt===null;return u.jsxs("div",{className:"shell shell--app",children:[u.jsx("div",{className:"glow glow--app","aria-hidden":!0}),u.jsxs("div",{className:"shell__left",children:[u.jsx(op,{me:ot,welcome:bt,onLogout:b,mitmTeam:ct.length>0?ct[0]:null}),u.jsx(pp,{}),u.jsxs("main",{className:"main",children:[u.jsxs("div",{className:"app__tabsrow",children:[u.jsx("div",{className:"app__tabs",children:[{k:"all",label:r("teamFilter.all","全部"),n:zt+ze+Ca},{k:"local",label:r("teamFilter.local","本地"),n:zt},{k:"cloud",label:r("teamFilter.cloud","私有云"),n:Ca},{k:"custom",label:r("teamFilter.custom","自定义"),n:ze}].map(({k:C,label:Y,n:B})=>u.jsxs("button",{type:"button",className:`app__tab ${ke===C?"is-active":""}`,onClick:()=>ca(C),children:[Y,u.jsx("span",{className:"app__tab-count",children:B})]},C))}),u.jsxs("div",{"data-id":"AddTeamWrap",style:{position:"relative"},children:[u.jsxs("button",{type:"button","data-id":"AddTeamButton",className:"app__add-team",title:r("teams.addHint","添加团队"),onClick:()=>_t(C=>!C),children:["+ ",r("teams.add","新加团队")]}),yt&&u.jsxs(u.Fragment,{children:[u.jsx("div",{onClick:()=>_t(!1),style:{position:"fixed",inset:0,zIndex:40}}),u.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:[u.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:()=>{_t(!1),Le(""),Ut(!0)},children:[u.jsx("div",{style:{fontSize:13,fontWeight:600},children:r("teams.addCustom","自定义团队")}),u.jsx("div",{style:{fontSize:11,opacity:.6,marginTop:2},children:r("teams.addCustomSub","手动输入地址和名称")})]}),u.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:()=>{_t(!1),_i("?tab=private")},children:[u.jsx("div",{style:{fontSize:13,fontWeight:600},children:r("teams.addPrivate","私有云团队")}),u.jsx("div",{style:{fontSize:11,opacity:.6,marginTop:2},children:r("teams.addPrivateSub","去云端团队中心添加")})]})]})]})]})]}),ne&&u.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:C=>{!Wt&&C.target===C.currentTarget&&Ut(!1)},children:u.jsxs("div",{onClick:C=>C.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:[u.jsx("div",{style:{fontSize:16,fontWeight:700,marginBottom:4},children:r("teams.customTitle","添加自定义团队")}),u.jsx("div",{style:{fontSize:12,opacity:.6,marginBottom:16},children:r("teams.customSub","连接到一个已有的 cicy-code 地址")}),u.jsx("label",{style:{display:"block",fontSize:12,opacity:.75,marginBottom:6},children:r("teams.customNameLabel","名称")}),u.jsx("input",{"data-id":"CustomTeamModal-title",className:"login-email-input",style:{width:"100%",marginBottom:14},value:Qe,onChange:C=>$(C.target.value),placeholder:r("teams.customNamePlaceholder","我的团队"),spellCheck:!1,autoFocus:!0}),u.jsx("label",{style:{display:"block",fontSize:12,opacity:.75,marginBottom:6},children:r("teams.customUrlLabel","地址 URL")}),u.jsx("input",{"data-id":"CustomTeamModal-url",className:"login-email-input",style:{width:"100%",marginBottom:6},value:qt,onChange:C=>de(C.target.value),placeholder:"https://example.com:8008",spellCheck:!1,onKeyDown:C=>{C.key==="Enter"&<()}}),Te&&u.jsx("div",{className:"error",style:{marginTop:10},children:Te}),u.jsxs("div",{className:"modal-actions",children:[u.jsx("button",{type:"button",className:"btn-ghost","data-id":"CustomTeamModal-cancel",disabled:Wt,onClick:()=>Ut(!1),children:r("common.cancel","取消")}),u.jsx("button",{type:"button",className:"btn-primary","data-id":"CustomTeamModal-submit",disabled:Wt,onClick:lt,children:Wt?r("teams.adding","添加中…"):r("teams.addAction","添加")})]})]})}),oe&&u.jsxs("div",{className:"error",style:{marginBottom:12},children:[r("common.cloud","云端"),": ",oe,u.jsx("button",{className:"btn-ghost",style:{marginLeft:8},onClick:()=>Me(S||j,D),children:r("common.retry","重试")})]}),u.jsxs("div",{className:"app__grid",children:[ra&&[0,1,2].map(C=>u.jsx(gp,{},"skc"+C)),!ra&&$t&&ct.map(C=>u.jsx(Sm,{team:C,cloudCode:at(C.cloud_team_id),onOpen:()=>Nt(C.id),onRename:it,onRefresh:P},"local:"+C.id)),!ra&&$t&&u.jsx(hp,{dockerTeam:Q,onOpen:async()=>{var C,Y,B;try{const J=await((B=(Y=(C=window.cicy)==null?void 0:C.docker)==null?void 0:Y.appOpen)==null?void 0:B.call(Y));J!=null&&J.ok||St.show({id:"docker-open",status:"error",ttl:6e3,message:r("docker.openNoToken","服务还没就绪,稍等几秒再点「打开」(或用卡片菜单「重启」)。")})}catch(J){console.warn("[DockerCard] open",J)}},cloudTitle:tt==null?void 0:tt.title,cloudCode:tt==null?void 0:tt.code,onRename:Q!=null&&Q.cloud_team_id?(C=>sa(Q.cloud_team_id,C)):void 0,onRefresh:P}),Ce&&pt.map(C=>u.jsx(Sm,{team:C,cloudCode:at(C.cloud_team_id),onOpen:()=>Nt(C.id),onRename:it,onRefresh:P},"custom:"+C.id)),Na&&oa.map(C=>u.jsx(yp,{team:C,onOpen:()=>{var B,J,et;const Y=C.kind==="private"?C.host_url:C.workspace_url||C.workspace_direct_url;Y&&((et=(J=(B=window.cicy)==null?void 0:B.tabs)==null?void 0:J.open)==null||et.call(J,Y,C.name||C.title||"",K[C.id]||"",!0,C.id))},avatar:K[C.id]||"",onAvatar:mt,onRename:sa,onEditUrl:pe,onDelete:H},"cloud:"+C.id))]}),!Pt&&!oe&&Zt&&Zt.length===0&&!(G!=null&&G.length)&&u.jsx("div",{className:"empty",style:{marginTop:14},children:r("teams.emptyHint","还没有团队 — 安装本地 cicy-code 起一个本地 team,或在云端创建。")})]})]}),u.jsx(np,{}),u.jsx(ip,{}),u.jsx(mp,{})]})}function cp({onClose:s}){const[g,S]=v.useState(null),[d,j]=v.useState(""),[M,D]=v.useState(!1),[R,w]=v.useState(""),h=typeof window<"u"&&window.cicy&&window.cicy.trustedOrigins||null,Z=v.useCallback(async()=>{try{S(h&&await h.list()||[])}catch{S([])}},[h]);v.useEffect(()=>{Z()},[Z]);const A=async()=>{const I=d.trim();if(!(!I||M||!h)){D(!0),w("");try{const V=await h.add(I);V&&V.ok===!1?w(V.error||r("trustedSites.addFailed","添加失败")):(j(""),S(V&&V.origins||await h.list()))}catch(V){w(String(V&&V.message||V))}finally{D(!1)}}},W=async I=>{if(!(M||!h)){D(!0),w("");try{const V=await h.remove(I);V&&V.ok===!1?w(V.error||r("trustedSites.removeFailed","删除失败")):S(V&&V.origins||await h.list())}catch(V){w(String(V&&V.message||V))}finally{D(!1)}}},L={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:I=>({flex:1,fontFamily:"ui-monospace,SFMono-Regular,Menlo,monospace",fontSize:13,color:I?"#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 xa.createPortal(u.jsx("div",{style:L.overlay,onMouseDown:I=>{I.target===I.currentTarget&&s()},"data-id":"TrustedSitesModal",children:u.jsxs("div",{style:L.card,onClick:I=>I.stopPropagation(),children:[u.jsxs("div",{style:L.head,children:[u.jsx("h2",{style:L.title,children:r("trustedSites.title","受信任站点")}),u.jsx("button",{type:"button",style:L.x,onClick:s,"aria-label":"close",children:"✕"})]}),u.jsx("div",{style:L.warn,children:r("trustedSites.warn","⚠ 列表中的站点可以在你的电脑上执行命令(exec)。只添加你完全信任的地址。")}),u.jsxs("div",{style:L.addRow,children:[u.jsx("input",{"data-id":"trusted-sites-input",style:L.input,value:d,onChange:I=>j(I.target.value),onKeyDown:I=>{I.key==="Enter"&&A()},placeholder:r("trustedSites.placeholder","添加站点,如 app.cicy-ai.com 或 my-cloud.example.org")}),u.jsx("button",{type:"button","data-id":"trusted-sites-add",style:{...L.addBtn,opacity:M||!d.trim()?.5:1},onClick:A,disabled:M||!d.trim(),children:r("trustedSites.add","添加")})]}),R&&u.jsx("div",{style:L.err,children:R}),u.jsx("div",{style:L.listWrap,children:g===null?u.jsx("div",{style:L.muted,children:r("trustedSites.loading","加载中…")}):g.length===0?u.jsx("div",{style:L.muted,children:r("trustedSites.empty","暂无")}):g.map(I=>u.jsxs("div",{style:L.row,"data-id":"trusted-sites-row",children:[u.jsx("span",{style:L.host(I.builtin),children:I.host}),I.builtin?u.jsx("span",{style:L.tag,children:r("trustedSites.builtin","系统")}):u.jsx("button",{type:"button",style:L.rm,onClick:()=>W(I.host),disabled:M,children:r("trustedSites.remove","删除")})]},I.host))})]})}),document.body)}function sp({onClose:s}){const[g,S]=v.useState(null),[d,j]=v.useState(""),[M,D]=v.useState(""),[R,w]=v.useState(!1),h=typeof window<"u"&&window.cicy&&window.cicy.rpcAudit||null,Z=v.useCallback(async()=>{w(!0),j("");try{const q=h&&await h.tail(400);!q||q.ok===!1?(j(q&&q.error||r("audit.loadFailed","读取失败")),S([])):(S(q.entries||[]),D(q.path||""))}catch(q){j(String(q&&q.message||q)),S([])}finally{w(!1)}},[h]);v.useEffect(()=>{Z()},[Z]);const[A,W]=v.useState("all"),[L,I]=v.useState(""),V=q=>{try{return new Date(q).toLocaleString()}catch{return q||""}},ht=q=>{if(q.kind==="auth"){const Zt=/deny/.test(q.decision||"");return{text:q.decision||"auth",color:Zt?"#fca5a5":"#86efac",bg:Zt?"rgba(239,68,68,.14)":"rgba(34,197,94,.14)"}}if(q.kind==="rpc"){const Zt=q.ok!==!1&&!q.error;return{text:Zt?"ok":"err",color:Zt?"#86efac":"#fca5a5",bg:Zt?"rgba(34,197,94,.14)":"rgba(239,68,68,.14)"}}return{text:q.kind||"log",color:"#a1a1aa",bg:"rgba(255,255,255,.06)"}},xt=q=>q.kind==="auth"?`${q.gate||""}${q.decision?" · "+q.decision:""}`:q.kind==="rpc"?`${q.tool||""}${q.dangerous?" ⚠":""}`:q.kind||"",Jt=q=>q.error||q.args||(q.kind==="rpc"?q.channel:"")||"",dt=g||[],Lt=L.trim().toLowerCase(),ut=dt.filter(q=>A!=="all"&&q.kind!==A?!1:Lt?[q.origin,q.host,q.tool,q.gate,q.decision,q.channel,q.args,q.error,q.kind].filter(Boolean).join(" ").toLowerCase().includes(Lt):!0),bt="186px 104px minmax(160px,1.1fr) minmax(150px,1.1fr) minmax(220px,1.8fr)",X={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:q=>({background:q?"rgba(255,255,255,.14)":"transparent",border:"1px solid rgba(255,255,255,.12)",borderRadius:999,padding:"6px 16px",color:q?"#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:bt,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:bt,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:q=>({justifySelf:"start",fontSize:11.5,color:q.color,background:q.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}},ot=q=>u.jsx("div",{children:q});return xa.createPortal(u.jsx("div",{style:X.overlay,onMouseDown:q=>{q.target===q.currentTarget&&s()},"data-id":"AuditLogModal",children:u.jsxs("div",{style:X.card,onClick:q=>q.stopPropagation(),children:[u.jsxs("div",{style:X.head,children:[u.jsxs("div",{style:X.titleWrap,children:[u.jsx("h2",{style:X.title,children:r("audit.title","审计日志")}),M&&u.jsx("p",{style:X.subtitle,children:M})]}),u.jsxs("span",{style:X.count,children:[r("audit.count","共")," ",ut.length,A!=="all"||Lt?` / ${dt.length}`:""]}),u.jsx("button",{type:"button","data-id":"audit-refresh",style:{...X.refresh,opacity:R?.5:1},onClick:Z,disabled:R,children:r("audit.refresh","刷新")}),u.jsx("button",{type:"button",style:X.x,onClick:s,"aria-label":"close",children:"✕"})]}),u.jsxs("div",{style:X.toolbar,children:[u.jsxs("div",{style:X.chips,children:[u.jsx("button",{type:"button",style:X.chip(A==="all"),onClick:()=>W("all"),children:r("audit.all","全部")}),u.jsx("button",{type:"button",style:X.chip(A==="rpc"),onClick:()=>W("rpc"),children:r("audit.rpc","RPC 调用")}),u.jsx("button",{type:"button",style:X.chip(A==="auth"),onClick:()=>W("auth"),children:r("audit.auth","授权决定")})]}),u.jsx("input",{"data-id":"audit-search",style:X.search,value:L,onChange:q=>I(q.target.value),placeholder:r("audit.search","搜索来源 / 工具 / 命令…")})]}),d&&u.jsx("div",{style:X.err,children:d}),u.jsxs("div",{style:X.tableWrap,children:[u.jsxs("div",{style:X.theadRow,children:[ot(r("audit.colTime","时间")),ot(r("audit.colType","类型")),ot(r("audit.colSource","来源")),ot(r("audit.colOp","操作")),ot(r("audit.colDetail","详情"))]}),g===null?u.jsx("div",{style:X.muted,children:r("audit.loading","加载中…")}):ut.length===0?u.jsx("div",{style:X.muted,children:dt.length===0?r("audit.empty","暂无审计记录"):r("audit.noMatch","无匹配记录")}):ut.map((q,Zt)=>{const le=ht(q);return u.jsxs("div",{style:X.row,"data-id":"audit-row",children:[u.jsx("span",{style:X.time,children:V(q.ts)}),u.jsx("span",{style:X.badge(le),children:le.text}),u.jsx("span",{style:X.cell,children:q.origin||q.host||"—"}),u.jsx("span",{style:X.cell,children:xt(q)||"—"}),u.jsx("span",{style:X.detail,children:Jt(q)||"—"})]},Zt)})]})]})}),document.body)}function op({me:s,welcome:g,onLogout:S,mitmTeam:d}){const j=(s==null?void 0:s.display_name)||(s==null?void 0:s.username)||"…",M=j.slice(0,1).toUpperCase(),[D,R]=v.useState(!1),[w,h]=v.useState(!1),[Z,A]=v.useState(!1),[W,L]=v.useState(!1),[I,V]=v.useState(!1),[ht,xt]=v.useState(""),Jt=v.useRef(null);v.useEffect(()=>{var bt,X,ot;let ut=!0;return(ot=(X=(bt=window.cicy)==null?void 0:bt.app)==null?void 0:X.getVersion)==null||ot.call(X).then(q=>{ut&&xt(typeof q=="string"?q:String((q==null?void 0:q.desktop)||""))}).catch(()=>{}),()=>{ut=!1}},[]),v.useEffect(()=>{if(!D)return;const ut=bt=>{Jt.current&&!Jt.current.contains(bt.target)&&R(!1)};return document.addEventListener("mousedown",ut),()=>document.removeEventListener("mousedown",ut)},[D]);const dt=ut=>{_i(ut),R(!1)},Lt=async()=>{var ut,bt,X;R(!1),V(!0),St.show({id:"app-update",message:r("updateBanner.checking","正在检查更新…"),status:"running"});try{const ot=await((X=(bt=(ut=window.cicy)==null?void 0:ut.app)==null?void 0:bt.checkUpdate)==null?void 0:X.call(bt));(ot==null?void 0:ot.status)==="available"?St.show({id:"app-update",message:r("updateBanner.available","发现新版本 v{{v}}",{v:ot.version}),status:"done",ttl:4e3}):(ot==null?void 0:ot.status)==="up-to-date"?St.show({id:"app-update",message:r("updateBanner.upToDate","已是最新版本 v{{v}}",{v:ot.version||ot.current}),status:"done",ttl:3e3}):St.show({id:"app-update",message:r("updateBanner.error","更新失败")+(ot!=null&&ot.error?`:${ot.error}`:""),status:"error",ttl:5e3})}catch(ot){St.show({id:"app-update",message:ot.message,status:"error",ttl:5e3})}finally{V(!1)}};return u.jsxs(u.Fragment,{children:[u.jsx("header",{className:"topbar",children:u.jsxs("div",{className:"user-chip","data-id":"UserChip",ref:Jt,children:[g&&u.jsx("span",{className:"welcome",children:g}),s?u.jsxs("button",{type:"button","data-id":"UserChip-trigger",className:`user-chip__trigger${D?" is-open":""}`,onClick:()=>R(ut=>!ut),children:[u.jsx("div",{className:"avatar",children:M}),u.jsx("span",{className:"user-name",children:j}),u.jsx("span",{className:"user-chip__caret","aria-hidden":!0,children:"▾"})]}):u.jsxs("div",{className:"user-chip__trigger user-chip__trigger--skel","data-id":"UserChip-skeleton","aria-hidden":!0,children:[u.jsx("div",{className:"skel skel--avatar"}),u.jsx("div",{className:"skel skel--name"})]}),D&&u.jsxs("div",{className:"user-chip__menu","data-id":"UserChip-menu",role:"menu",children:[u.jsx("button",{type:"button","data-id":"UserChip-wallet",className:"user-chip__menu-item",onClick:()=>dt("?view=wallet"),children:r("userMenu.wallet","我的钱包")}),u.jsx("button",{type:"button","data-id":"UserChip-billing",className:"user-chip__menu-item",onClick:()=>dt("?view=usage"),children:r("userMenu.billing","我的账单")}),u.jsx("button",{type:"button","data-id":"UserChip-trusted-sites",className:"user-chip__menu-item",onClick:()=>{R(!1),h(!0)},children:r("trustedSites.menu","受信任站点")}),u.jsx("button",{type:"button","data-id":"UserChip-audit-log",className:"user-chip__menu-item",onClick:()=>{R(!1),A(!0)},children:r("audit.menu","审计日志")}),u.jsx("button",{type:"button","data-id":"UserChip-terms",className:"user-chip__menu-item",onClick:()=>{R(!1),L(!0)},children:r("firstRunTerms.menu","用户协议")}),u.jsx("button",{type:"button","data-id":"UserChip-check-update",className:"user-chip__menu-item",disabled:I,onClick:Lt,children:I?r("updateBanner.checkingShort","检查中…"):r("updateBanner.checkBtn","检查更新")}),!1,u.jsx("div",{className:"user-chip__menu-sep","aria-hidden":!0}),u.jsx("button",{type:"button","data-id":"UserChip-logout",className:"user-chip__menu-item is-danger",onClick:()=>{R(!1),S()},children:r("userMenu.logout","退出")}),u.jsxs("div",{className:"user-chip__menu-version","data-id":"UserChip-version",children:["CiCy Desktop ",ht?`v${ht}`:"…"]})]})]})}),w&&u.jsx(cp,{onClose:()=>h(!1)}),Z&&u.jsx(sp,{onClose:()=>A(!1)}),W&&u.jsx(Nm,{onClose:()=>L(!1)})]})}function Nm({onAgree:s,onClose:g}){var I;const[S,d]=v.useState(!1),[j,M]=v.useState(!1),D=(((I=window.cicyI18n)==null?void 0:I.locale)||"en").startsWith("zh")?"zh-CN":"en",R=(V,ht)=>r(`firstRunTerms.${V}`,ht),w=!!g,h=v.useMemo(()=>ep(Py(D)),[D]),Z=V=>{const ht=V.currentTarget;ht.scrollHeight-ht.scrollTop-ht.clientHeight<24&&d(!0)},A=v.useRef(null);v.useEffect(()=>{const V=A.current;V&&V.scrollHeight<=V.clientHeight+24&&d(!0)},[]);const W=async()=>{var V,ht,xt;if(!(j||!S)){M(!0);try{await((xt=(ht=(V=window.cicy)==null?void 0:V.terms)==null?void 0:ht.agree)==null?void 0:xt.call(ht,Am)),s==null||s()}catch{s==null||s()}}},L=()=>{var V,ht,xt;try{(xt=(ht=(V=window.cicy)==null?void 0:V.terms)==null?void 0:ht.decline)==null||xt.call(ht)}catch{}};return u.jsxs("div",{className:w?"terms-gate terms-gate--review":"shell terms-gate","data-id":"FirstRunTermsGate",style:w?{position:"fixed",inset:0,zIndex:1e3,background:"rgba(8,9,14,.72)",backdropFilter:"blur(4px)"}:void 0,onClick:w?V=>{V.target===V.currentTarget&&g()}:void 0,children:[u.jsx("div",{className:"glow","aria-hidden":!0}),u.jsxs("div",{className:"terms-gate__panel",children:[u.jsx("h1",{className:"terms-gate__title","data-id":"FirstRunTermsGate-title",children:R("title","用户协议与授权说明")}),u.jsx("p",{className:"terms-gate__subtitle",children:R("subtitle","使用 CiCy Desktop 前,请阅读并同意以下条款")}),u.jsx("div",{className:"terms-gate__body",ref:A,onScroll:Z,"data-id":"FirstRunTermsGate-body",children:u.jsx("div",{className:"terms-md","data-id":"FirstRunTermsGate-md",dangerouslySetInnerHTML:{__html:h}})}),w?u.jsx("div",{className:"terms-gate__actions",children:u.jsx("button",{"data-id":"FirstRunTermsGate-close",className:"terms-gate__btn",onClick:g,children:R("close","关闭")})}):u.jsxs(u.Fragment,{children:[!S&&u.jsx("div",{className:"terms-gate__scrollhint","data-id":"FirstRunTermsGate-scrollhint",children:R("scrollHint","请阅读至底部以继续")}),u.jsxs("div",{className:"terms-gate__actions",children:[u.jsx("button",{"data-id":"FirstRunTermsGate-decline",className:"terms-gate__btn terms-gate__btn--ghost",onClick:L,children:R("decline","不同意并退出")}),u.jsx("button",{"data-id":"FirstRunTermsGate-agree",className:"terms-gate__btn",disabled:!S||j,title:S?"":R("mustAgree","未同意则无法使用本软件。"),onClick:W,children:R("agree","同意并继续")})]})]})]})]})}const io=new Set;let bm=0,Bt=null;function zn(){io.forEach(s=>s(Bt))}const Et={open({onRetry:s,kind:g,source:S}={}){Bt={status:"running",phase:"install-docker",kind:g||"install",source:S||"op",logs:[],bars:{},minimized:!1,onRetry:s||null,lastAt:Date.now()},zn()},minimize(){Bt&&(Bt={...Bt,minimized:!0},zn())},restore(){Bt&&(Bt={...Bt,minimized:!1},zn())},push(s={}){var D;if(!Bt)return;const g=s.phase==="health"?"container":s.phase||Bt.phase,S={...Bt,phase:g,lastAt:Date.now()},d=Number.isFinite(s.progress),j=g==="install-docker"||g==="image";if(j&&(d||s.dest||s.url)){const R=((D=Bt.bars)==null?void 0:D[g])||{},w=d?s.progress:s.status==="skip"||s.status==="done"?100:R.progress;S.bars={...Bt.bars,[g]:{progress:w,received:s.received??R.received,total:s.total??R.total,url:s.url||R.url,dest:s.dest||R.dest}}}if(!(s.status==="running"&&d&&j)){const R=Bt.logs[Bt.logs.length-1],w=s.status||"running",h=s.message||"";if(!(R&&R.phase===g&&R.status===w&&R.message===h)){const Z={id:++bm,t:xi(),phase:g,status:w,message:h};S.logs=[...Bt.logs,Z]}}Bt=S,zn()},finish({ok:s,message:g,status:S}={}){if(!Bt||Bt.status!=="running")return;const d=S||(s?"done":"error"),j=d==="error"?Bt.phase:"done",M={id:++bm,t:xi(),phase:j,status:d,message:g||(s?"完成":"失败")};Bt={...Bt,status:d,phase:j,minimized:!1,logs:[...Bt.logs,M],lastAt:Date.now()},zn()},close(){Bt=null,zn()}},eo=[["install-docker","准备环境"],["image","下载运行环境"],["container","启动服务"],["done","完成"]],rp={"install-docker":"准备",image:"下载",container:"启动",health:"启动",done:"完成",open:"打开"},dp={"install-docker":"Docker Desktop",image:"基础镜像"};function vm(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 fp({phaseKey:s,bar:g}){const S=Number.isFinite(g==null?void 0:g.progress)?Math.max(0,Math.min(100,g.progress)):0,d=S>=100;return u.jsxs("div",{className:"dlbar","data-id":`DockerDrawer-dlbar-${s}`,children:[u.jsxs("div",{className:"dlbar__head",children:[u.jsx("span",{className:"dlbar__name",children:dp[s]||s}),u.jsxs("span",{className:"dlbar__pct",children:[S,"%",g!=null&&g.total?` · ${vm(g.received)} / ${vm(g.total)}`:""]})]}),u.jsx("div",{className:"dlbar__track",children:u.jsx("div",{className:`dlbar__fill${d?" is-done":""}`,style:{width:`${S}%`}})}),(g==null?void 0:g.url)&&u.jsxs("div",{className:"dlbar__url",title:g.url,children:[u.jsx("span",{className:"dlbar__urlk",children:"源"})," ",g.url]}),(g==null?void 0:g.dest)&&u.jsxs("div",{className:"dlbar__url",title:g.dest,children:[u.jsx("span",{className:"dlbar__urlk",children:"存"})," ",g.dest]})]})}function mp(){var w;const[s,g]=v.useState(Bt);v.useEffect(()=>(io.add(g),()=>{io.delete(g)}),[]);const S=v.useRef(null);if(v.useEffect(()=>{const h=S.current;h&&(h.scrollTop=h.scrollHeight)},[(w=s==null?void 0:s.logs)==null?void 0:w.length]),!s)return null;const d=s.status==="running",j=s.kind==="open",M=eo.findIndex(([h])=>h===s.phase),D=j?[]:["install-docker","image"].filter(h=>{var Z;return(Z=s.bars)==null?void 0:Z[h]}),R=j?r("docker.openTitle","打开 Docker 团队"):r("docker.setupTitle","安装 Docker cicy-code");if(s.minimized){const h=D.map(A=>{var W;return(W=s.bars[A])==null?void 0:W.progress}).filter(Number.isFinite),Z=h.length?Math.round(h.reduce((A,W)=>A+W,0)/h.length):null;return u.jsxs("button",{type:"button",className:`drawer-min drawer-min--${s.status}`,"data-id":"DockerDrawer-restore",onClick:()=>Et.restore(),children:[u.jsx("span",{className:"drawer-min__spark",children:d?u.jsx(Ge,{}):s.status==="done"?"✓":s.status==="reboot"?"⟳":"!"}),u.jsxs("span",{className:"drawer-min__label",children:[R,Z!=null?` · ${Z}%`:""]})]})}return u.jsx("div",{className:"drawer-scrim","data-id":"DockerDrawer-scrim",onClick:()=>d?Et.minimize():Et.close(),children:u.jsxs("div",{className:"drawer","data-id":"DockerDrawer","data-status":s.status,onClick:h=>h.stopPropagation(),children:[u.jsxs("div",{className:"drawer__head",children:[u.jsxs("div",{className:"drawer__title",children:[u.jsx("span",{className:`drawer__spark drawer__spark--${s.status}`,children:d?u.jsx(Ge,{}):s.status==="done"?"✓":s.status==="reboot"?"⟳":"!"}),u.jsxs("div",{children:[u.jsx("div",{className:"drawer__h",children:R}),u.jsx("div",{className:"drawer__sub",children:"127.0.0.1:8008"})]})]}),u.jsx("div",{className:"drawer__headbtns",children:u.jsx("button",{type:"button",className:"drawer__x","data-id":"DockerDrawer-min",title:r("common.minimize","最小化"),onClick:()=>Et.minimize(),"aria-label":"minimize",children:"‒"})})]}),!j&&u.jsx("div",{className:"drawer__steps","data-id":"DockerDrawer-steps",children:eo.map(([h,Z],A)=>{const W=s.status==="done"||M>=0&&A<M,L=A===M&&d,I=s.status==="error"&&A===M;return u.jsxs("div",{className:`drawer__step${L?" is-active":""}${W?" is-done":""}${I?" is-error":""}`,children:[u.jsx("span",{className:"drawer__step-dot",children:W?"✓":I?"!":A+1}),u.jsx("span",{className:"drawer__step-label",children:Z}),A<eo.length-1&&u.jsx("span",{className:"drawer__step-bar"})]},h)})}),D.length>0&&u.jsx("div",{className:"drawer__dlbars","data-id":"DockerDrawer-dlbars",children:D.map(h=>u.jsx(fp,{phaseKey:h,bar:s.bars[h]},h))}),d&&s.logs.length>0&&u.jsxs("div",{className:"drawer__now","data-id":"DockerDrawer-now",children:[u.jsx(Ge,{}),u.jsx("span",{children:s.logs[s.logs.length-1].message})]}),u.jsx("div",{className:"drawer__log drawer__log--scroll","data-id":"DockerDrawer-log",ref:S,children:s.logs.length===0?u.jsx("div",{className:"drawer__log-empty",children:r("docker.preparing","准备中…")}):s.logs.map(h=>u.jsxs("div",{className:"drawer__line","data-status":h.status,children:[u.jsx("span",{className:"drawer__t",children:h.t}),u.jsx("span",{className:`drawer__badge drawer__badge--${h.phase}`,children:r(`dockerBadge.${h.phase}`,rp[h.phase]||h.phase)}),u.jsx("span",{className:"drawer__linemsg",children:h.message})]},h.id))}),u.jsx("div",{className:"drawer__foot",children:d?u.jsx(u.Fragment,{children:u.jsx("span",{className:"drawer__foot-status",children:j?r("docker.opening","打开中…"):r("docker.installing2","安装进行中…")})}):s.status==="reboot"?u.jsxs(u.Fragment,{children:[u.jsx("span",{className:"drawer__foot-status is-reboot",children:r("docker.rebootShort","需重启 Windows")}),s.onRetry&&u.jsx("button",{type:"button",className:"drawer__btn is-accent","data-id":"DockerDrawer-retry",onClick:()=>s.onRetry(),children:r("common.retry","重试")}),u.jsx("button",{type:"button",className:"drawer__btn","data-id":"DockerDrawer-dismiss",onClick:()=>Et.close(),children:r("common.close","关闭")})]}):s.status==="error"?u.jsxs(u.Fragment,{children:[u.jsx("span",{className:"drawer__foot-status is-error",children:j?r("docker.openFailed","打开失败"):r("docker.failed","安装失败")}),s.onRetry&&u.jsx("button",{type:"button",className:"drawer__btn is-accent","data-id":"DockerDrawer-retry",onClick:()=>s.onRetry(),children:r("common.retry","重试")}),u.jsx("button",{type:"button",className:"drawer__btn","data-id":"DockerDrawer-dismiss",onClick:()=>Et.close(),children:r("common.close","关闭")})]}):u.jsxs(u.Fragment,{children:[u.jsx("span",{className:"drawer__foot-status is-done",children:r("docker.ready","已就绪")}),u.jsx("button",{type:"button",className:"drawer__btn is-accent","data-id":"DockerDrawer-finish",onClick:()=>Et.close(),children:r("common.done","完成")})]})})]})})}function hp({dockerTeam:s,cloudTitle:g,cloudCode:S,onOpen:d,onRename:j,onRefresh:M}){var pe;const[D,R]=v.useState(null),[w,h]=v.useState(""),[Z,A]=v.useState(!1),[W,L]=v.useState(!1),[I,V]=v.useState(!1),[ht,xt]=v.useState(!1),[Jt,dt]=v.useState([]),[Lt,ut]=v.useState(!1),[bt,X]=v.useState(""),[ot,q]=v.useState(!1),[Zt,le]=v.useState(""),Pt=g||"Docker 团队",ve=H=>{var P;(P=H==null?void 0:H.stopPropagation)==null||P.call(H),le(Pt),q(!0)},oe=async()=>{q(!1);const H=String(Zt||"").trim();if(!(!H||H===Pt||!j))try{await j(H),M==null||M()}catch{}},[Qt,z]=v.useState({top:0,left:0}),G=v.useRef(null),rt=v.useRef(null),At=184,Tt="#2496ed",m=v.useCallback(async()=>{var H,P,lt;try{const it=await((lt=(P=(H=window.cicy)==null?void 0:H.docker)==null?void 0:P.appStatus)==null?void 0:lt.call(P));R(it);const Nt=Date.now()-((Bt==null?void 0:Bt.lastAt)||0)>3e4;it!=null&&it.running&&Bt&&Bt.status==="running"&&Bt.kind!=="open"&&Nt&&Et.finish({ok:!0,message:"Docker cicy-code 已就绪"})}catch(it){console.warn("[DockerCard]",it)}},[]);v.useEffect(()=>{m();const H=setInterval(()=>{w||m()},12e3);return()=>clearInterval(H)},[m,w]);const k=v.useCallback(async()=>{var H,P,lt;A(!1),X("");try{const it=await((lt=(P=(H=window.cicy)==null?void 0:H.docker)==null?void 0:P.getPorts)==null?void 0:lt.call(P));dt(((it==null?void 0:it.ports)||[]).map(String))}catch{dt([])}xt(!0)},[]),K=v.useCallback(async()=>{var it,Nt,Rt,ie,b,Q,tt,at,ct;const H=new Set,P=[];for(const pt of Jt){const zt=String(pt).trim();if(!zt)continue;const ze=Number(zt);if(!Number.isInteger(ze)||ze<1||ze>65535||ze===8008||H.has(ze)){X(r("docker.ports.invalid","有端口无效(1-65535,不能是 8008,不能重复)"));return}H.add(ze),P.push(ze)}X(""),ut(!0),xt(!1),h("recreate"),Et.open({onRetry:K});const lt=(Rt=(Nt=(it=window.cicy)==null?void 0:it.docker)==null?void 0:Nt.onAppProgress)==null?void 0:Rt.call(Nt,pt=>Et.push(pt));try{const pt=await((Q=(b=(ie=window.cicy)==null?void 0:ie.docker)==null?void 0:b.setPorts)==null?void 0:Q.call(b,P));if(Et.finish({ok:!!(pt!=null&&pt.ok),message:pt!=null&&pt.ok?r("docker.ports.save","保存并重建")+" ✅":(pt==null?void 0:pt.error)||r("docker.opFailed","操作失败")}),pt!=null&&pt.ok)try{const zt=await((ct=(at=(tt=window.cicy)==null?void 0:tt.docker)==null?void 0:at.appRedetect)==null?void 0:ct.call(at));zt&&R(zt)}catch{}}catch(pt){Et.finish({ok:!1,message:pt.message})}finally{try{lt&<()}catch{}ut(!1),h(""),m()}},[Jt,m]);v.useEffect(()=>{if(!Z)return;const H=lt=>{var it,Nt;(it=G.current)!=null&&it.contains(lt.target)||(Nt=rt.current)!=null&&Nt.contains(lt.target)||A(!1)},P=lt=>{lt.key==="Escape"&&A(!1)};return document.addEventListener("mousedown",H),document.addEventListener("keydown",P),()=>{document.removeEventListener("mousedown",H),document.removeEventListener("keydown",P)}},[Z]);const F=()=>{if(!Z&&G.current){const H=G.current.getBoundingClientRect(),P=Math.max(8,Math.min(H.right-At,window.innerWidth-At-8));z({top:Math.round(H.bottom+4),left:Math.round(P)})}A(H=>!H)},mt=v.useCallback(async()=>{var P,lt,it,Nt,Rt,ie;h("bootstrap"),Et.open({onRetry:mt});const H=(it=(lt=(P=window.cicy)==null?void 0:P.docker)==null?void 0:lt.onAppProgress)==null?void 0:it.call(lt,b=>Et.push(b));try{const b=await((ie=(Rt=(Nt=window.cicy)==null?void 0:Nt.docker)==null?void 0:Rt.appBootstrap)==null?void 0:ie.call(Rt));(b==null?void 0:b.reason)==="installer_launched"?Et.finish({status:"reboot",message:r("docker.installerLaunched","已打开 Docker 安装程序——请完成安装(会装 WSL2、可能需重启),装好后点「重试」")}):(b==null?void 0:b.reason)==="wsl_reboot_required"?Et.finish({status:"reboot",message:r("docker.rebootNeeded","WSL2 已安装,请【重启 Windows】后回来点「重试」继续")}):Et.finish({ok:!!(b!=null&&b.ok),message:b!=null&&b.ok?r("docker.ready","Docker cicy-code 已就绪"):(b==null?void 0:b.error)||r("docker.failed","安装失败")}),b!=null&&b.ok&&(M==null||M())}catch(b){Et.finish({ok:!1,message:b.message})}finally{try{H&&H()}catch{}h(""),m()}},[m,M]),yt=v.useCallback(async()=>{var P,lt,it,Nt,Rt,ie;h("repair"),Et.open({onRetry:yt});const H=(it=(lt=(P=window.cicy)==null?void 0:P.docker)==null?void 0:lt.onAppProgress)==null?void 0:it.call(lt,b=>Et.push(b));try{const b=await((ie=(Rt=(Nt=window.cicy)==null?void 0:Nt.docker)==null?void 0:Rt.appRepairWsl)==null?void 0:ie.call(Rt));b!=null&&b.needsReboot?Et.finish({status:"reboot",message:r("docker.wslNeedReboot","WSL 服务卡死,请【重启 Windows】;重启后打开 CiCy 会自动修复(旧数据已改名备份,不删)。")}):b!=null&&b.ok?(Et.finish({ok:!0,message:r("docker.wslRepaired","WSL 已修复 ✅")}),M==null||M()):Et.finish({ok:!1,message:(b==null?void 0:b.error)||r("docker.repairFailed","修复失败")})}catch(b){Et.finish({ok:!1,message:b.message})}finally{try{H&&H()}catch{}h(""),m()}},[m,M]),_t=v.useCallback(async()=>{var P,lt,it,Nt,Rt,ie;A(!1),h("upgrade"),Et.open({onRetry:_t});const H=(it=(lt=(P=window.cicy)==null?void 0:P.docker)==null?void 0:lt.onAppProgress)==null?void 0:it.call(lt,b=>Et.push(b));try{const b=await((ie=(Rt=(Nt=window.cicy)==null?void 0:Nt.docker)==null?void 0:Rt.appUpgrade)==null?void 0:ie.call(Rt));(b==null?void 0:b.reason)==="wsl_reboot_required"?Et.finish({status:"reboot",message:r("docker.rebootNeeded","WSL2 已安装,请【重启 Windows】后回来点「重试」继续")}):Et.finish({ok:!!(b!=null&&b.ok),message:b!=null&&b.ok?r("docker.upgraded","已升级到最新"):(b==null?void 0:b.error)||r("docker.upgradeFailed","升级失败")}),b!=null&&b.ok&&(M==null||M())}catch(b){Et.finish({ok:!1,message:b.message})}finally{try{H&&H()}catch{}h(""),m()}},[m,M]),ne=v.useCallback(async()=>{var P,lt,it,Nt,Rt,ie,b,Q,tt,at,ct,pt;A(!1),h("update"),Et.open({onRetry:ne});const H=(it=(lt=(P=window.cicy)==null?void 0:P.docker)==null?void 0:lt.onAppProgress)==null?void 0:it.call(lt,zt=>Et.push(zt));try{const zt=await((ie=(Rt=(Nt=window.cicy)==null?void 0:Nt.docker)==null?void 0:Rt.appUpdate)==null?void 0:ie.call(Rt));if(Et.finish({ok:!!(zt!=null&&zt.ok),message:zt!=null&&zt.ok?r("docker.updated","cicy-code 已更新到最新"):(zt==null?void 0:zt.error)||r("docker.updateFailed","更新失败")}),zt!=null&&zt.ok){M==null||M();try{(tt=(Q=(b=window.cicy)==null?void 0:b.tabs)==null?void 0:Q.reloadIfOpen)==null||tt.call(Q,"http://127.0.0.1:8008",r("docker.teamTab","Docker 团队"))}catch{}try{const ze=await((pt=(ct=(at=window.cicy)==null?void 0:at.docker)==null?void 0:ct.appRedetect)==null?void 0:pt.call(ct));ze&&R(ze)}catch{}}}catch(zt){Et.finish({ok:!1,message:zt.message})}finally{try{H&&H()}catch{}h(""),m()}},[m,M]),Ut=v.useCallback(async(H,P,lt)=>{A(!1),h(H),St.show({id:"docker-op",message:r(`docker.${H}ing`,H==="restart"?"重启中…":H==="reload"?"刷新中…":"停止中…"),status:"running"});try{const it=await P();it!=null&&it.ok?St.show({id:"docker-op",message:lt,status:"done",ttl:2500}):St.show({id:"docker-op",message:(it==null?void 0:it.error)||r("docker.opFailed","操作失败"),status:"error",ttl:6e3})}catch(it){St.show({id:"docker-op",message:it.message,status:"error",ttl:6e3})}finally{h(""),m()}},[m]),Qe=v.useCallback(async()=>{A(!1),h("authssh"),St.show({id:"docker-op",message:r("docker.authorizingHost","授权容器访问 Mac(配置 SSH)…"),status:"running"});try{const H=await window.cicy.docker.appAuthorizeHostSsh();H!=null&&H.ok?St.show({id:"docker-op",message:H.verified?r("docker.authorizedHostOk","已授权:容器内 `ssh mac` 可访问 Mac ✅"):r("docker.authorizedHostPartial","公钥已写入 Mac(未验证成功,可在容器内手动 `ssh mac` 试)"),status:H.verified?"done":"error",ttl:5e3}):St.show({id:"docker-op",message:(H==null?void 0:H.error)||r("docker.opFailed","操作失败"),status:"error",ttl:6e3})}catch(H){St.show({id:"docker-op",message:H.message,status:"error",ttl:6e3})}finally{h(""),m()}},[m]),$=((pe=window.cicy)==null?void 0:pe.platform)||(D==null?void 0:D.platform);if($!=="win32")return null;const qt=D?!!D.running:(s==null?void 0:s.status)==="running",de=!!(D!=null&&D.dockerRunning),Wt=!!(D!=null&&D.installed),De=!!(D!=null&&D.unknown)&&!qt&&!de&&!Wt,Te=!!(D!=null&&D.wslUnmanaged),Le=!!(D!=null&&D.wslWedged),ke=qt&&!Te,ca=ke?"ok":Le||Te||de||Wt||De?"warn":"off",Me=!!w;Le?r("docker.wslWedged","WSL 卡死 · 点「修复 WSL」"):Te?r("docker.wslBrokenRepair","WSL 管理异常 · 点「修复 WSL」重装"):qt?r("docker.running","运行中"):de?r("docker.notRunning","未启动 · 点「启动」"):Wt?r("docker.engineDown","Docker 未运行 · 点启动"):De?r("docker.wslUnresponsive","WSL 未响应 · 点「重试检测」"):r("docker.notInstalled","Docker Desktop 未安装");const Ie=w==="open"?r("docker.opening","打开中…"):w==="probe"?r("docker.probing","检测中…"):Me?r("docker.working","处理中…"):ke?r("localTeams.open","打开"):Le||Te?r("docker.repairWsl","修复 WSL"):de?r("docker.start","启动"):Wt?r("docker.startDocker","启动 Docker"):De?r("docker.retryProbe","重试检测"):r("docker.install","下载安装"),fe=async()=>{var H,P,lt,it,Nt,Rt,ie,b,Q,tt,at,ct;if(!Me){if(Le){yt();return}if(Te){mt();return}if(ke){try{const zt=await((lt=(P=(H=window.cicy)==null?void 0:H.tabs)==null?void 0:P.activateIfOpen)==null?void 0:lt.call(P,"http://127.0.0.1:8008"));if(zt!=null&&zt.active)return}catch{}h("open");let pt=null;try{pt=await((Rt=(Nt=(it=window.cicy)==null?void 0:it.docker)==null?void 0:Nt.appOpen)==null?void 0:Rt.call(Nt))}catch(zt){pt={ok:!1,hint:(zt==null?void 0:zt.message)||r("docker.openFailed","打开失败"),log:[]}}h(""),pt&&pt.ok===!1&&(Et.open({onRetry:fe,kind:"open"}),(pt.log||[]).forEach(zt=>Et.push(zt)),Et.finish({ok:!1,message:pt.hint||pt.error||r("docker.openFailed","打开失败")}));return}if(De){h("probe");try{const pt=await(((Q=(b=(ie=window.cicy)==null?void 0:ie.docker)==null?void 0:b.appRedetect)==null?void 0:Q.call(b))??((ct=(at=(tt=window.cicy)==null?void 0:tt.docker)==null?void 0:at.appStatus)==null?void 0:ct.call(at)));pt&&R(pt),pt!=null&&pt.unknown&&St.show({id:"docker-probe",status:"error",message:r("docker.wslStillStuck","WSL 仍无响应 —— 多半要重启 Windows 后再试"),ttl:6e3})}catch{St.show({id:"docker-probe",status:"error",message:r("docker.probeFailed","检测失败,请重试"),ttl:5e3})}finally{h("")}return}mt()}},sa=qt;return u.jsxs("div",{"data-id":"DockerCard",className:`bcard bcard--docker${qt?" bcard--online":""}`,children:[u.jsx("div",{className:"bcard__accent",style:{background:Tt}}),u.jsxs("div",{className:"bcard__top",children:[u.jsxs("div",{className:"bcard__pill",style:{color:Tt},children:[u.jsx("span",{className:"bcard__dot","data-tone":ca}),u.jsx("svg",{style:{width:18,height:18},viewBox:"0 0 24 24",fill:"currentColor","aria-hidden":!0,children:u.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"})})]}),sa&&u.jsxs("div",{className:"bcard__menuwrap",onClick:H=>H.stopPropagation(),children:[u.jsx("button",{type:"button",ref:G,"data-id":"DockerCard-menu-btn",className:"bcard__kebab",title:r("docker.manage","管理 Docker cicy-code"),disabled:Me,onClick:F,children:Me?u.jsx(Ge,{}):u.jsx(oo,{})}),Z&&xa.createPortal(u.jsxs("div",{className:"bcard__menu bcard__menu--portal","data-id":"DockerCard-menu",role:"menu",ref:rt,style:{position:"fixed",top:Qt.top,left:Qt.left,width:At},onClick:H=>H.stopPropagation(),children:[u.jsx("button",{type:"button","data-id":"DockerCard-update",className:"bcard__menu-item is-accent",onClick:ne,children:r("docker.update","更新 cicy-code")}),u.jsx("button",{type:"button","data-id":"DockerCard-restart",className:"bcard__menu-item",onClick:()=>Ut("restart",()=>window.cicy.docker.appRestart(),r("docker.restarted","已重启 cicy-code")),children:r("docker.restart","重启 cicy-code")}),u.jsx("button",{type:"button","data-id":"DockerCard-stop",className:"bcard__menu-item is-danger",onClick:()=>Ut("stop",()=>window.cicy.docker.appStop(),r("docker.stopped","已停止 cicy-code")),children:r("docker.stop","停止 cicy-code")}),u.jsx("button",{type:"button","data-id":"DockerCard-reload",className:"bcard__menu-item",onClick:H=>{var P,lt,it;H.stopPropagation(),A(!1),(it=(lt=(P=window.cicy)==null?void 0:P.tabs)==null?void 0:lt.reloadIfOpen)==null||it.call(lt,"http://127.0.0.1:8008","Docker 团队")},children:r("docker.reloadWindow","刷新窗口")}),u.jsx("button",{type:"button","data-id":"DockerCard-cft",className:"bcard__menu-item",title:r("sidecar.cftHint","用 Cloudflare 命名隧道把 cicy-code 暴露到固定公网域名(需要 Cloudflare connector token);切换会自动重启 cicy-code"),onClick:H=>{H.stopPropagation(),A(!1),L(!0)},children:r("sidecar.cftMenu","Cloudflare 隧道")}),u.jsx("button",{type:"button","data-id":"DockerCard-open-dir",className:"bcard__menu-item",onClick:H=>{var P,lt,it;H.stopPropagation(),A(!1),(it=(lt=(P=window.cicy)==null?void 0:P.docker)==null?void 0:lt.openDir)==null||it.call(lt)},children:r("docker.openWslDir","打开 WSL 目录")}),u.jsx("button",{type:"button","data-id":"DockerCard-open-projects",className:"bcard__menu-item",onClick:H=>{var P,lt,it;H.stopPropagation(),A(!1),(it=(lt=(P=window.cicy)==null?void 0:P.docker)==null?void 0:lt.openDir)==null||it.call(lt,"projects")},children:r("docker.openProjectsDir","打开项目目录")}),u.jsx("button",{type:"button","data-id":"DockerCard-billing",className:"bcard__menu-item",onClick:()=>{A(!1),_i(S||s!=null&&s.cloud_team_id?`?team=${encodeURIComponent(S||s.cloud_team_id)}`:"?view=usage")},children:r("docker.billing","帐单")}),u.jsx("div",{className:"bcard__menu-sep","data-id":"DockerCard-menu-sep",role:"separator","aria-hidden":!0}),$==="darwin"&&u.jsx("button",{type:"button","data-id":"DockerCard-authorize-host-ssh",className:"bcard__menu-item",title:r("docker.authorizeHostHint","把容器公钥加到 Mac 的 authorized_keys,容器内 `ssh mac` 即可访问本机"),onClick:Qe,children:r("docker.authorizeHost","授权容器访问 Mac")}),u.jsx("button",{type:"button","data-id":"DockerCard-docker-restart",className:"bcard__menu-item",onClick:()=>Ut("restart",()=>window.cicy.docker.appDockerRestart(),r("docker.dockerRestarted","已重启 Docker 容器")),children:r("docker.dockerRestart","重启 Docker")}),u.jsx("button",{type:"button","data-id":"DockerCard-ports",className:"bcard__menu-item",onClick:H=>{H.stopPropagation(),k()},children:r("docker.ports.menu","端口设置")}),u.jsx("button",{type:"button","data-id":"DockerCard-recreate",className:"bcard__menu-item is-danger",onClick:H=>{H.stopPropagation(),A(!1),V(!0)},children:r("docker.recreate","重建 Docker")})]}),document.body)]})]}),u.jsxs("div",{className:"bcard__body",children:[u.jsxs("div",{style:{height:28,display:"flex",alignItems:"center",gap:8},children:[u.jsx(so,{size:24,avatar:s==null?void 0:s.avatar,name:Pt,teamId:s==null?void 0:s.id,onChanged:M}),ot?u.jsx("input",{"data-id":"DockerCard-rename-input",autoFocus:!0,value:Zt,onChange:H=>le(H.target.value),onFocus:H=>H.target.select(),onBlur:oe,onClick:H=>H.stopPropagation(),onKeyDown:H=>{H.nativeEvent.isComposing||H.keyCode===229||(H.key==="Enter"?oe():H.key==="Escape"&&q(!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"}}):u.jsxs("h3",{className:"bcard__name",title:j?r("localTeams.renameHint","点名字或 ✎ 改名"):Pt,style:{display:"flex",alignItems:"center",gap:6,flex:1,minWidth:0,margin:0},onDoubleClick:j?ve:void 0,children:[u.jsx("span",{onClick:j?ve:void 0,style:{overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap",cursor:j?"text":"default"},children:Pt}),j&&u.jsx("button",{type:"button","data-id":"DockerCard-rename-btn",title:r("localTeams.rename","重命名"),onClick:ve,style:{flex:"none",cursor:"pointer",border:"none",background:"transparent",color:"#8b949e",fontSize:13,padding:0,lineHeight:1},children:"✎"})]})]}),u.jsxs("div",{className:"bcard__meta",children:[u.jsx("span",{className:"bcard__chip",children:"Docker"}),(D==null?void 0:D.version)&&u.jsxs("span",{className:"bcard__ver","data-id":"DockerCard-ver",style:{marginLeft:8,fontSize:11,opacity:.6},children:["v",D.version]})]})]}),u.jsxs("button",{type:"button",className:"bcard__cta","data-id":"DockerCard-cta",disabled:Me,onClick:fe,style:qt?void 0:{background:Tt,color:"white"},children:[Me?u.jsx(Ge,{}):u.jsx(Hu,{}),u.jsx("span",{children:Ie})]}),u.jsx(km,{open:W,onClose:()=>L(!1),toastId:"docker-op"}),I&&xa.createPortal(u.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:H=>{H.target===H.currentTarget&&V(!1)},children:u.jsxs("div",{onClick:H=>H.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:[u.jsx("h3",{style:{margin:"0 0 8px",fontSize:16,color:"#e6edf3"},children:r("docker.recreate","重建 Docker")}),u.jsx("p",{style:{margin:"0 0 18px",fontSize:13,lineHeight:1.6,color:"#9aa4b2"},children:r("docker.recreateConfirm","会删除当前容器并重新创建(volume 数据保留),用于切换为独立 team 的网关 key。确定重建?")}),u.jsxs("div",{style:{display:"flex",justifyContent:"flex-end",gap:10},children:[u.jsx("button",{type:"button","data-id":"DockerCard-recreate-cancel",onClick:()=>V(!1),style:{padding:"7px 16px",borderRadius:8,border:"1px solid #30363d",background:"transparent",color:"#c9d1d9",cursor:"pointer",fontSize:13},children:r("common.cancel","取消")}),u.jsx("button",{type:"button","data-id":"DockerCard-recreate-confirm",onClick:()=>{V(!1),Ut("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),ht&&xa.createPortal(u.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:H=>{H.target===H.currentTarget&&xt(!1)},children:u.jsxs("div",{onClick:H=>H.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:[u.jsx("h3",{style:{margin:"0 0 6px",fontSize:16,color:"#e6edf3"},children:r("docker.ports.title","端口设置")}),u.jsx("p",{style:{margin:"0 0 14px",fontSize:12.5,lineHeight:1.6,color:"#9aa4b2"},children:r("docker.ports.sub","除 :8008 外,额外发布、可从 Windows 直达容器内服务的端口")}),u.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(固定)")]}),u.jsxs("div",{style:{display:"flex",flexDirection:"column",gap:8,maxHeight:220,overflowY:"auto"},children:[Jt.length===0&&u.jsx("div",{style:{fontSize:12.5,color:"#6e7681",padding:"4px 2px"},children:r("docker.ports.none","暂无额外端口")}),Jt.map((H,P)=>u.jsxs("div",{style:{display:"flex",alignItems:"center",gap:8},children:[u.jsx("input",{"data-id":`DockerCard-port-input-${P}`,type:"text",inputMode:"numeric",value:H,placeholder:r("docker.ports.ph","端口号 1-65535"),onChange:lt=>{const it=lt.target.value.replace(/[^0-9]/g,"");dt(Nt=>Nt.map((Rt,ie)=>ie===P?it:Rt)),X("")},style:{flex:1,padding:"7px 10px",borderRadius:8,border:"1px solid #30363d",background:"#0d1117",color:"#e6edf3",fontSize:13,fontFamily:"var(--mono)"}}),u.jsx("button",{type:"button","data-id":`DockerCard-port-remove-${P}`,title:r("docker.ports.remove","移除"),onClick:()=>{dt(lt=>lt.filter((it,Nt)=>Nt!==P)),X("")},style:{padding:"6px 10px",borderRadius:8,border:"1px solid #30363d",background:"transparent",color:"#da3633",cursor:"pointer",fontSize:14},children:"✕"})]},P))]}),u.jsx("button",{type:"button","data-id":"DockerCard-port-add",onClick:()=>dt(H=>[...H,""]),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","+ 添加端口")}),bt&&u.jsx("div",{style:{marginTop:10,fontSize:12.5,color:"#f85149"},children:bt}),u.jsx("p",{style:{margin:"12px 0 16px",fontSize:11.5,lineHeight:1.5,color:"#6e7681"},children:r("docker.ports.hint","保存会重建容器(volume 数据保留),会有短暂中断")}),u.jsxs("div",{style:{display:"flex",justifyContent:"flex-end",gap:10},children:[u.jsx("button",{type:"button","data-id":"DockerCard-ports-cancel",disabled:Lt,onClick:()=>xt(!1),style:{padding:"7px 16px",borderRadius:8,border:"1px solid #30363d",background:"transparent",color:"#c9d1d9",cursor:"pointer",fontSize:13},children:r("docker.ports.cancel","取消")}),u.jsx("button",{type:"button","data-id":"DockerCard-ports-save",disabled:Lt,onClick:K,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 Sm({team:s,cloudCode:g,onOpen:S,onRename:d,onRefresh:j}){var it,Nt,Rt,ie;const D=(wm[s.status]||wm.error).tone,[R,w]=v.useState(!1),[h,Z]=v.useState(s.name||""),[A,W]=v.useState(null),[L,I]=v.useState(""),V=A??s.name;v.useEffect(()=>{A!=null&&s.name===A&&W(null)},[s.name,A]);const ht=b=>{var Q;(Q=b==null?void 0:b.stopPropagation)==null||Q.call(b),Z(V||""),w(!0)},xt=async()=>{w(!1);const b=String(h||"").trim();if(!d||!b||b===V)return;W(b),I("saving");let Q;try{Q=await d(s.id,b)}catch(tt){Q={ok:!1,error:tt==null?void 0:tt.message}}W(null),Q&&Q.ok?(I("saved"),setTimeout(()=>I(tt=>tt==="saved"?"":tt),1500)):(I(""),St.show({message:r("localTeams.renameFailed","改名没保存,已恢复"),status:"error",ttl:4e3}))},dt=!!((Nt=(it=window.cicy)==null?void 0:it.sidecar)!=null&&Nt.restart)&&uo(s.base_url),Lt=s.status==="running",[ut,bt]=v.useState(""),[X,ot]=v.useState(!1),[q,Zt]=v.useState(!1),[le,Pt]=v.useState(!1);v.useEffect(()=>{var b,Q;!dt||!((Q=(b=window.cicy)==null?void 0:b.sidecar)!=null&&Q.getPublic)||window.cicy.sidecar.getPublic().then(tt=>Pt(!!(tt!=null&&tt.public))).catch(()=>{})},[dt]);const[ve,oe]=v.useState({running:void 0,latest:null,installed:null}),Qt=ve.latest,z=ve.running,[G,rt]=v.useState(!1),At=v.useRef(null),Tt=v.useRef(null),m=v.useRef(null),[k,K]=v.useState({top:0,left:0}),F=184,mt=()=>{if(!X&&Tt.current){const b=Tt.current.getBoundingClientRect(),Q=Math.max(8,Math.min(b.right-F,window.innerWidth-F-8));K({top:Math.round(b.bottom+4),left:Math.round(Q)})}ot(b=>!b)},yt=v.useCallback(async(b=!1)=>{var Q,tt;if(!(!dt||!((tt=(Q=window.cicy)==null?void 0:Q.sidecar)!=null&&tt.versions))){b&&rt(!0);try{const at=await window.cicy.sidecar.versions();oe({running:(at==null?void 0:at.running)??null,latest:(at==null?void 0:at.latest)??null,installed:(at==null?void 0:at.installed)??null}),b&&(at!=null&&at.running&&(at!=null&&at.latest)&&_m(at.latest,at.running)>0?St.show({message:`${r("sidecar.found","发现新版本")} v${at.latest}`,status:"done",ttl:2500}):at!=null&&at.running?St.show({message:`${r("sidecar.upToDate","已是最新")} v${at.running}`,status:"done",ttl:2500}):St.show({message:r("sidecar.notRunning","cicy-code 未运行"),status:"error",ttl:4e3}))}catch{b&&St.show({message:r("sidecar.checkFailed","检查更新失败"),status:"error",ttl:5e3})}finally{b&&rt(!1)}}},[dt]);v.useEffect(()=>{yt(!1)},[yt]),v.useEffect(()=>{Lt&&yt(!1)},[Lt,yt]);const _t=!!(dt&&Qt&&z&&_m(Qt,z)>0),ne=!dt&&!!((ie=(Rt=window.cicy)==null?void 0:Rt.localTeams)!=null&&ie.remove),Ut=dt||ne,[Qe,$]=v.useState(!1),[qt,de]=v.useState(!1),[Wt,De]=v.useState(""),[Te,Le]=v.useState(!1),[ke,ca]=v.useState("");v.useEffect(()=>{if(!X)return;const b=Q=>{var tt,at;(tt=Tt.current)!=null&&tt.contains(Q.target)||(at=m.current)!=null&&at.contains(Q.target)||ot(!1)};return document.addEventListener("mousedown",b),()=>document.removeEventListener("mousedown",b)},[X]);const Me=async()=>{var Q,tt,at;if(Te)return;const b=String(Wt||"").trim();if(!b||b===(s.base_url||"")){de(!1);return}try{new URL(b)}catch{ca(r("teams.badUrl","URL 无效(需含 http(s)://)"));return}ca(""),Le(!0);try{const ct=await((at=(tt=(Q=window.cicy)==null?void 0:Q.localTeams)==null?void 0:tt.update)==null?void 0:at.call(tt,s.id,{base_url:b}));ct!=null&&ct.ok?(de(!1),j==null||j()):ca(Wa((ct==null?void 0:ct.error)||"update failed"))}catch(ct){ca(Wa((ct==null?void 0:ct.message)||String(ct)))}Le(!1)},Ie=async()=>{var Q,tt,at;if(ut)return;$(!1),bt("remove");const b="op-"+Date.now();St.show({id:b,message:r("localTeams.removing","删除中…"),status:"running"});try{const ct=await((at=(tt=(Q=window.cicy)==null?void 0:Q.localTeams)==null?void 0:tt.remove)==null?void 0:at.call(tt,s.id));ct!=null&&ct.ok?St.show({id:b,message:r("localTeams.removed","已删除"),status:"done",ttl:3e3}):St.show({id:b,message:r("localTeams.removeFailed","删除失败")+(ct!=null&&ct.error?": "+ct.error:""),status:"error",ttl:7e3})}catch(ct){St.show({id:b,message:r("localTeams.removeFailed","删除失败")+": "+((ct==null?void 0:ct.message)||ct),status:"error",ttl:7e3})}bt(""),j==null||j()},fe=`sidecar-op:${s.id}`,sa=async(b,Q,tt)=>{var pt,zt,ze,oa,Ca;if(ot(!1),ut)return;bt(b);const at=b==="update";let ct=null;at?(ye.open({teamId:s.id,fromVer:z,toVer:Qt,onRetry:()=>sa("update",Q,tt)}),(zt=(pt=window.cicy)==null?void 0:pt.sidecar)!=null&&zt.onOpProgress&&(ct=window.cicy.sidecar.onOpProgress($t=>{($t==null?void 0:$t.op)==="update"&&ye.push($t)}))):St.show({id:fe,message:pe[b]||`${b}…`,status:"running",progress:void 0});try{const $t=await Q(),Ce=!!($t!=null&&$t.ok),Na=$t!=null&&$t.warning?`${tt}(${$t.warning})`:tt,ra=r("sidecar.failed","操作失败")+($t!=null&&$t.error?`: ${$t.error}`:"");if(at){if(ye.finish({ok:Ce,message:Ce?Na:ra}),Ce)try{await((Ca=(oa=(ze=window.cicy)==null?void 0:ze.localTeams)==null?void 0:oa.reload)==null?void 0:Ca.call(oa,s.id,{ignoreCache:!0}))}catch{}}else St.show({id:fe,message:Ce?Na:ra,progress:void 0,status:Ce?"done":"error",ttl:Ce?4e3:8e3})}catch($t){const Ce=r("sidecar.failed","操作失败")+`: ${($t==null?void 0:$t.message)||$t}`;at?ye.finish({ok:!1,message:Ce}):St.show({id:fe,message:Ce,progress:void 0,status:"error",ttl:8e3})}finally{try{ct&&ct()}catch{}bt(""),j==null||j(),(b==="update"||b==="restart"||b==="start")&&yt(!1)}},pe={start:r("busy.start","启动中…"),restart:r("busy.restart","重启中…"),update:r("busy.update","更新中…"),stop:r("busy.stop","停止中…")},H=async()=>{var tt,at,ct;bt("start"),ye.open({teamId:s.id,title:r("sidecar.startTitle","启动 cicy-code"),onRetry:H}),ye.push({phase:"download",status:"running",message:r("sidecar.starting","启动 cicy-code(首次需安装 Node + 依赖,日志见下)…")});const b=(ct=(at=(tt=window.cicy)==null?void 0:tt.sidecar)==null?void 0:at.onOpProgress)==null?void 0:ct.call(at,pt=>ye.push(pt));let Q;try{Q=await window.cicy.sidecar.start()}catch(pt){Q={ok:!1,error:(pt==null?void 0:pt.message)||String(pt)}}try{b==null||b()}catch{}return bt(""),j==null||j(),!(Q!=null&&Q.ok)||Q!=null&&Q.warning?(ye.finish({ok:!1,message:r("sidecar.startFailed","启动失败")+(Q!=null&&Q.error?`: ${Q.error}`:Q!=null&&Q.warning?`: ${Q.warning}`:"")}),!1):(ye.finish({ok:!0,message:r("sidecar.startedOk","cicy-code 已就绪")}),!0)},P=async()=>{var b,Q;ut||!Lt&&dt&&((Q=(b=window.cicy)==null?void 0:b.sidecar)!=null&&Q.start)&&!await H()||S()},lt=Lt?r("localTeams.open","打开"):dt?r("localTeams.startOpen","启动并打开"):r("localTeams.open","打开");return u.jsxs(u.Fragment,{children:[u.jsxs("div",{"data-id":"LocalTeamCard",className:`bcard ${dt?"bcard--local":"bcard--custom"}${D==="ok"?" bcard--online":""}`,children:[u.jsx("div",{className:"bcard__accent"}),u.jsxs("div",{className:"bcard__top",children:[u.jsxs("div",{className:"bcard__pill",children:[u.jsx("span",{className:"bcard__dot","data-tone":D}),u.jsx(xp,{})]}),Ut&&u.jsxs("div",{className:"bcard__menuwrap",ref:At,onClick:b=>b.stopPropagation(),children:[u.jsx("button",{type:"button",ref:Tt,"data-id":"LocalTeamCard-menu-btn",className:`bcard__kebab${_t?" has-dot":""}`,title:dt?r("localTeams.manage","管理本地 cicy-code"):r("localTeams.more","更多"),disabled:!!ut,onClick:mt,children:ut?u.jsx(Ge,{}):u.jsx(oo,{})}),X&&xa.createPortal(u.jsxs("div",{className:"bcard__menu bcard__menu--portal","data-id":"LocalTeamCard-menu",role:"menu",ref:m,style:{position:"fixed",top:k.top,left:k.left,width:F},onClick:b=>b.stopPropagation(),children:[dt&&u.jsx("button",{type:"button","data-id":"LocalTeamCard-check-update",className:"bcard__menu-item",disabled:G,onClick:b=>{b.stopPropagation(),yt(!0)},children:G?r("sidecar.checking2","检查中…"):r("sidecar.checkUpdate","检查更新")}),_t&&u.jsxs("button",{type:"button","data-id":"LocalTeamCard-update",className:"bcard__menu-item is-accent",onClick:()=>sa("update",()=>window.cicy.sidecar.update(),r("sidecar.updated","已更新到最新")),children:[r("sidecar.updateTo","更新到")," v",Qt]}),s.base_url&&u.jsx("button",{type:"button","data-id":"LocalTeamCard-reload",className:"bcard__menu-item",onClick:b=>{var Q,tt,at;b.stopPropagation(),ot(!1),(at=(tt=(Q=window.cicy)==null?void 0:Q.tabs)==null?void 0:tt.reloadIfOpen)==null||at.call(tt,s.base_url,s.name)},children:r("localTeams.reloadWindow","刷新窗口")}),dt&&!Lt&&u.jsx("button",{type:"button","data-id":"LocalTeamCard-start",className:"bcard__menu-item is-accent",onClick:()=>sa("start",()=>window.cicy.sidecar.start(),r("sidecar.started","已启动")),children:r("sidecar.start","启动")}),dt&&Lt&&u.jsxs(u.Fragment,{children:[u.jsx("button",{type:"button","data-id":"LocalTeamCard-restart",className:"bcard__menu-item",onClick:()=>sa("restart",()=>window.cicy.sidecar.restart(),r("sidecar.restarted","已重启")),children:r("sidecar.restart","重启")}),u.jsx("button",{type:"button","data-id":"LocalTeamCard-stop",className:"bcard__menu-item is-danger",onClick:()=>sa("stop",()=>window.cicy.sidecar.stop(),r("sidecar.stoppedDone","已停止")),children:r("sidecar.stop","停止")}),u.jsxs("button",{type:"button","data-id":"LocalTeamCard-lan",className:"bcard__menu-item",title:r("sidecar.lanHint","开启后同局域网设备可用本机 IP 访问(api_token 仍校验);切换会自动重启 cicy-code"),disabled:ut==="lan",onClick:async()=>{if(ut)return;const b=!le;ot(!1),bt("lan"),Pt(b),St.show({id:fe,message:b?r("sidecar.lanEnabling","开启局域网访问,重启中…"):r("sidecar.lanDisabling","关闭局域网访问,重启中…"),status:"running",progress:void 0});try{const Q=await window.cicy.sidecar.setPublic(b);Q!=null&&Q.ok?St.show({id:fe,message:b?r("sidecar.lanOn","已开启局域网访问"):r("sidecar.lanOff","已关闭局域网访问"),status:"done",ttl:3e3}):St.show({id:fe,message:r("sidecar.lanFailed","设置失败")+(Q!=null&&Q.error?`: ${Q.error}`:""),status:"error",ttl:7e3})}catch(Q){St.show({id:fe,message:r("sidecar.lanFailed","设置失败")+`: ${(Q==null?void 0:Q.message)||Q}`,status:"error",ttl:7e3})}try{const Q=await window.cicy.sidecar.getPublic();Pt(!!(Q!=null&&Q.public))}catch{}bt(""),j==null||j()},children:[r("sidecar.lanAccess","局域网访问")," · ",le?r("common.on","开"):r("common.off","关")]}),u.jsx("button",{type:"button","data-id":"LocalTeamCard-cft",className:"bcard__menu-item",title:r("sidecar.cftHint","用 Cloudflare 命名隧道把本机 cicy-code 暴露到固定公网域名(需要 Cloudflare connector token);切换会自动重启 cicy-code"),onClick:b=>{b.stopPropagation(),ot(!1),Zt(!0)},children:r("sidecar.cftMenu","Cloudflare 隧道")})]}),s.cloud_team_id&&u.jsx("button",{type:"button","data-id":"LocalTeamCard-billing",className:"bcard__menu-item",onClick:b=>{b.stopPropagation(),ot(!1),_i(`?team=${encodeURIComponent(g||s.cloud_team_id)}`)},children:r("localTeams.billing","账单")}),ne&&u.jsxs(u.Fragment,{children:[u.jsx("button",{type:"button","data-id":"LocalTeamCard-edit-url",className:"bcard__menu-item",onClick:b=>{b.stopPropagation(),ot(!1),de(!0),De(s.base_url||"")},children:r("teamCard.editUrl","更改访问地址")}),u.jsx("button",{type:"button","data-id":"LocalTeamCard-remove",className:"bcard__menu-item is-danger",onClick:()=>{ot(!1),$(!0)},children:r("localTeams.remove","删除")})]}),(z||s.version)&&u.jsxs("div",{"data-id":"LocalTeamCard-version",className:"bcard__menu-item",style:{cursor:"default",color:"#8b949e",fontSize:12},children:[r("localTeams.version","版本")," v",z||s.version]})]}),document.body)]})]}),u.jsxs("div",{className:"bcard__body",children:[u.jsxs("div",{style:{height:28,display:"flex",alignItems:"center",gap:8},children:[u.jsx(so,{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}),R?u.jsx("input",{"data-id":"LocalTeamCard-rename-input",autoFocus:!0,value:h,onChange:b=>Z(b.target.value),onFocus:b=>b.target.select(),onBlur:xt,onClick:b=>b.stopPropagation(),onKeyDown:b=>{b.nativeEvent.isComposing||b.keyCode===229||(b.key==="Enter"?xt():b.key==="Escape"&&w(!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"}}):u.jsxs("h3",{className:"bcard__name",title:r("localTeams.renameHint","点名字或 ✎ 改名"),style:{display:"flex",alignItems:"center",gap:6,flex:1,minWidth:0,margin:0},onDoubleClick:ht,children:[u.jsx("span",{"data-id":"LocalTeamCard-name-text",onClick:ht,style:{overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap",cursor:"text"},children:V}),L==="saving"&&u.jsx("span",{"data-id":"LocalTeamCard-save-state",title:r("localTeams.saving","保存中…"),style:{flex:"none",display:"inline-flex"},children:u.jsx(Ge,{})}),L==="saved"&&u.jsx("span",{"data-id":"LocalTeamCard-save-state",title:r("localTeams.saved","已保存"),style:{flex:"none",color:"#3fb950",fontSize:13,lineHeight:1},children:"✓"}),!L&&u.jsx("button",{type:"button","data-id":"LocalTeamCard-rename-btn",title:r("localTeams.rename","重命名"),onClick:ht,style:{flex:"none",cursor:"pointer",border:"none",background:"transparent",color:"#8b949e",fontSize:13,padding:0,lineHeight:1},children:"✎"})]})]}),u.jsx("div",{className:"bcard__meta",children:u.jsx("span",{className:"bcard__chip","data-id":"LocalTeamCard-kind",children:dt?r("localTeams.kindLocal","本地"):r("localTeams.kindCustom","自定义")})})]}),u.jsxs("button",{type:"button",className:"bcard__cta","data-id":"LocalTeamCard-open",disabled:!!ut||!s.base_url,onClick:P,children:[ut&&ut!=="stop"?u.jsx(Ge,{}):u.jsx(Hu,{}),u.jsx("span",{children:ut&&pe[ut]||lt})]})]}),qt&&xa.createPortal(u.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:b=>{!Te&&b.target===b.currentTarget&&de(!1)},children:u.jsxs("div",{onClick:b=>b.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:[u.jsx("div",{style:{fontSize:16,fontWeight:700,marginBottom:4},children:r("teamCard.editUrl","更改访问地址")}),u.jsx("div",{style:{fontSize:12,opacity:.6,marginBottom:16},children:s.name}),u.jsx("textarea",{"data-id":"LocalTeamCard-url-input",autoFocus:!0,rows:3,className:"login-email-input",style:{width:"100%",resize:"vertical",lineHeight:1.5,fontFamily:"var(--mono)"},value:Wt,placeholder:"https://example.com:8008",spellCheck:!1,disabled:Te,onChange:b=>De(b.target.value.replace(/[\r\n]+/g,"")),onKeyDown:b=>{b.nativeEvent.isComposing||b.keyCode===229||(b.key==="Enter"?(b.preventDefault(),Me()):b.key==="Escape"&&de(!1))}}),ke&&u.jsx("div",{className:"error",style:{marginTop:8,fontSize:12},children:ke}),u.jsxs("div",{className:"modal-actions",children:[u.jsx("button",{type:"button",className:"btn-ghost",disabled:Te,onClick:()=>de(!1),children:r("common.cancel","取消")}),u.jsx("button",{type:"button",className:"btn-primary","data-id":"LocalTeamCard-url-save",disabled:Te,onClick:Me,children:Te?r("common.saving","保存中…"):r("common.save","保存")})]})]})}),document.body),u.jsx(km,{open:q,onClose:()=>Zt(!1),toastId:fe}),u.jsx(Dm,{open:Qe,title:r("localTeams.deleteTitle","删除团队"),message:r("localTeams.deleteMsg","确定删除「{{name}}」?此操作不可撤销。",{name:s.name}),confirmLabel:r("common.delete","删除"),danger:!0,onConfirm:Ie,onCancel:()=>$(!1)})]})}function uo(s){var g;try{if(((g=window.cicy)==null?void 0:g.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 xm(s){var g;try{if(((g=window.cicy)==null?void 0:g.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 _m(s,g){const S=String(s).split("."),d=String(g).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 wm={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 Dm({open:s,title:g,message:S,confirmLabel:d,danger:j,onConfirm:M,onCancel:D}){return s?xa.createPortal(u.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:R=>{R.target===R.currentTarget&&(D==null||D())},children:u.jsxs("div",{onClick:R=>R.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:[u.jsx("div",{style:{fontSize:16,fontWeight:700,marginBottom:6},children:g}),S&&u.jsx("div",{style:{fontSize:13,opacity:.7,marginBottom:16},children:S}),u.jsxs("div",{className:"modal-actions",children:[u.jsx("button",{type:"button",className:"btn-ghost",onClick:D,children:r("common.cancel","取消")}),u.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 yp({team:s,onOpen:g,onRename:S,onEditUrl:d,onDelete:j,avatar:M,onAvatar:D}){const R=s.kind==="private",w=s.status==="active",h=s.name||s.title||"—",[Z,A]=v.useState(!1),[W,L]=v.useState(""),[I,V]=v.useState(null),ht=I??h;v.useEffect(()=>{I!=null&&h===I&&V(null)},[h,I]);const xt=$=>{var qt;(qt=$==null?void 0:$.stopPropagation)==null||qt.call($),L(ht==="—"?"":ht),A(!0)},Jt=async()=>{A(!1);const $=String(W||"").trim();if(!(!S||!$||$===ht)){V($);try{const qt=await S(s.id,$);qt!=null&&qt.ok||V(null)}catch{V(null)}}},dt=s.host_url||"",[Lt,ut]=v.useState(!1),[bt,X]=v.useState(""),[ot,q]=v.useState(null),Zt=ot??dt;v.useEffect(()=>{ot!=null&&dt===ot&&q(null)},[dt,ot]);const le=s.teamId||s.id,Pt=R?r("teamKind.private","私有云"):s.team_kind==="personal"?r("teamKind.personal","个人"):r("teamKind.shared","共享"),ve=R?Zt:s.workspace_url||s.workspace_direct_url,oe=!!ve,[Qt,z]=v.useState(!1),[G,rt]=v.useState(!1),[At,Tt]=v.useState({top:0,left:0}),m=v.useRef(null),k=v.useRef(null),K=v.useRef(null),F=184,mt=()=>{if(!Qt&&k.current){const $=k.current.getBoundingClientRect(),qt=Math.max(8,Math.min($.right-F,window.innerWidth-F-8));Tt({top:Math.round($.bottom+4),left:Math.round(qt)})}z($=>!$)};v.useEffect(()=>{if(!Qt)return;const $=qt=>{var de,Wt;(de=k.current)!=null&&de.contains(qt.target)||(Wt=K.current)!=null&&Wt.contains(qt.target)||z(!1)};return document.addEventListener("mousedown",$),()=>document.removeEventListener("mousedown",$)},[Qt]);const yt=$=>{var qt,de,Wt,De;(qt=$==null?void 0:$.stopPropagation)==null||qt.call($),oe&&(z(!1),(De=(Wt=(de=window.cicy)==null?void 0:de.tabs)==null?void 0:Wt.reloadIfOpen)==null||De.call(Wt,ve,ht))},[_t,ne]=v.useState(!1),Ut=()=>{X(dt),ut(!0),z(!1)},Qe=async()=>{ut(!1);const $=String(bt||"").trim();if(!(!d||!$||$===dt)){q($);try{const qt=await d(s.id,$);qt!=null&&qt.ok||q(null)}catch{q(null)}}};return u.jsxs(u.Fragment,{children:[u.jsxs("div",{"data-id":"TeamCard",className:`bcard bcard--cloud${w?" bcard--online":""}`,children:[u.jsx("div",{className:"bcard__accent"}),u.jsxs("div",{className:"bcard__top",children:[u.jsxs("div",{className:"bcard__pill",children:[u.jsx("span",{className:"bcard__dot","data-tone":w?"ok":"off"}),u.jsx(_p,{})]}),u.jsxs("div",{className:"bcard__top-right",children:[s.is_trial&&u.jsx("span",{className:"bcard__badge",children:"trial"}),(oe||le!=null||R&&d)&&u.jsxs("div",{className:"bcard__menuwrap",ref:m,onClick:$=>$.stopPropagation(),children:[u.jsx("button",{type:"button",ref:k,"data-id":"TeamCard-menu-btn",className:"bcard__kebab",title:r("localTeams.more","更多"),disabled:G,onClick:mt,children:G?u.jsx(Ge,{}):u.jsx(oo,{})}),Qt&&xa.createPortal(u.jsxs("div",{className:"bcard__menu bcard__menu--portal","data-id":"TeamCard-menu",role:"menu",ref:K,style:{position:"fixed",top:At.top,left:At.left,width:F},onClick:$=>$.stopPropagation(),children:[oe&&u.jsx("button",{type:"button","data-id":"TeamCard-reload",className:"bcard__menu-item",onClick:yt,children:r("localTeams.reloadWindow","刷新窗口")}),le!=null&&u.jsx("button",{type:"button","data-id":"TeamCard-billing",className:"bcard__menu-item",onClick:$=>{$.stopPropagation(),z(!1),_i(`?team=${encodeURIComponent(le)}`)},children:r("localTeams.billing","账单")}),R&&d&&u.jsx("button",{type:"button","data-id":"TeamCard-edit-url",className:"bcard__menu-item",onClick:$=>{$.stopPropagation(),Ut()},children:dt?r("teamCard.editUrl","更改访问地址"):r("teamCard.setUrl","填写访问地址")}),R&&j&&u.jsx("button",{type:"button","data-id":"TeamCard-delete",className:"bcard__menu-item is-danger",onClick:$=>{$.stopPropagation(),z(!1),ne(!0)},children:r("teamCard.delete","删除")})]}),document.body)]})]})]}),u.jsxs("div",{className:"bcard__body",children:[u.jsxs("div",{style:{height:28,display:"flex",alignItems:"center",gap:8},children:[u.jsx(so,{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:D}),Z?u.jsx("input",{"data-id":"TeamCard-rename-input",autoFocus:!0,value:W,onChange:$=>L($.target.value),onFocus:$=>$.target.select(),onBlur:Jt,onClick:$=>$.stopPropagation(),onKeyDown:$=>{$.nativeEvent.isComposing||$.keyCode===229||($.key==="Enter"?Jt():$.key==="Escape"&&A(!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"}}):u.jsxs("h3",{className:"bcard__name",title:S?r("localTeams.renameHint","点名字或 ✎ 改名"):ht,style:{display:"flex",alignItems:"center",gap:6,flex:1,minWidth:0,margin:0},onDoubleClick:S?xt:void 0,children:[u.jsx("span",{onClick:S?xt:void 0,style:{overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap",cursor:S?"text":"default"},children:ht}),S&&u.jsx("button",{type:"button","data-id":"TeamCard-rename-btn",title:r("localTeams.rename","重命名"),onClick:xt,style:{flex:"none",cursor:"pointer",border:"none",background:"transparent",color:"#8b949e",fontSize:13,padding:0,lineHeight:1},children:"✎"})]})]}),u.jsxs("div",{className:"bcard__meta",children:[u.jsx("span",{className:"bcard__chip",children:Pt}),!R&&s.membership_status&&s.membership_status!=="active"&&u.jsx("span",{className:"bcard__chip",children:s.membership_status})]})]}),u.jsxs("button",{type:"button",className:"bcard__cta",onClick:g,disabled:!oe,children:[u.jsx(Hu,{}),u.jsx("span",{children:oe?r("localTeams.open","打开"):R?r("teamCard.noHost","未填访问地址"):r("teamCard.noUrl","无 URL")})]})]}),Lt&&xa.createPortal(u.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:$=>{$.target===$.currentTarget&&ut(!1)},children:u.jsxs("div",{onClick:$=>$.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:[u.jsx("div",{style:{fontSize:16,fontWeight:700,marginBottom:4},children:dt?r("teamCard.editUrl","更改访问地址"):r("teamCard.setUrl","填写访问地址")}),u.jsx("div",{style:{fontSize:12,opacity:.6,marginBottom:16},children:ht}),u.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:bt,placeholder:"https://你的私有云地址:端口",spellCheck:!1,onChange:$=>X($.target.value.replace(/[\r\n]+/g,"")),onKeyDown:$=>{$.nativeEvent.isComposing||$.keyCode===229||($.key==="Enter"?($.preventDefault(),Qe()):$.key==="Escape"&&ut(!1))}}),u.jsxs("div",{className:"modal-actions",children:[u.jsx("button",{type:"button",className:"btn-ghost",onClick:()=>ut(!1),children:r("common.cancel","取消")}),u.jsx("button",{type:"button",className:"btn-primary","data-id":"TeamCard-url-save",onClick:Qe,children:r("common.save","保存")})]})]})}),document.body),u.jsx(Dm,{open:_t,title:r("localTeams.deleteTitle","删除团队"),message:r("localTeams.deleteMsg","确定删除「{{name}}」?此操作不可撤销。",{name:ht}),confirmLabel:r("common.delete","删除"),danger:!0,onConfirm:async()=>{ne(!1),j&&await j(s)},onCancel:()=>ne(!1)})]})}function ao(){return u.jsxs("div",{className:"brand",children:[u.jsx("div",{className:"brand-mark",children:u.jsx(Sp,{})}),u.jsxs("div",{className:"brand-text",children:[u.jsx("div",{className:"brand-name",children:"CiCy Desktop"}),u.jsx("div",{className:"brand-sub",children:r("app.brandSub","团队 AI 协作工作台")})]})]})}function pp(){const[s,g]=v.useState(null),[S,d]=v.useState(!1),j=v.useRef(!1);v.useEffect(()=>{var h,Z,A,W,L,I;let R=!0;(A=(Z=(h=window.cicy)==null?void 0:h.app)==null?void 0:Z.updateState)==null||A.call(Z).then(V=>{R&&g(V)}).catch(()=>{});const w=(I=(L=(W=window.cicy)==null?void 0:W.app)==null?void 0:L.onUpdateState)==null?void 0:I.call(L,V=>{g(V),j.current&&(V.status==="downloading"?ye.setProgress(V.progress||{}):V.status==="ready"?ye.ready({onInstall:()=>{var ht,xt,Jt;return(Jt=(xt=(ht=window.cicy)==null?void 0:ht.app)==null?void 0:xt.installUpdate)==null?void 0:Jt.call(xt)}}):V.status==="error"&&(ye.finish({ok:!1,message:V.error||r("updateBanner.error","更新失败")}),j.current=!1))});return()=>{R=!1;try{w&&w()}catch{}}},[]);const M=s==null?void 0:s.status;v.useEffect(()=>{d(!1)},[M]);const D=()=>{var R,w,h;j.current=!0,d(!0),ye.open({kind:"app",title:r("updateBanner.drawerTitle","应用更新"),fromVer:s==null?void 0:s.current,toVer:s==null?void 0:s.version,onRetry:D}),ye.push({phase:"download",status:"running",message:r("updateBanner.startDl","开始下载安装包…")}),ye.setProgress({percent:0}),(h=(w=(R=window.cicy)==null?void 0:R.app)==null?void 0:w.downloadUpdate)==null||h.call(w)};return M!=="available"||S?null:xa.createPortal(u.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:R=>{R.target===R.currentTarget&&d(!0)},children:u.jsxs("div",{onClick:R=>R.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:[u.jsx("div",{style:{fontSize:34,lineHeight:1,marginBottom:12},"aria-hidden":!0,children:"🚀"}),u.jsx("h3",{style:{margin:"0 0 8px",fontSize:17,color:"#e6edf3"},"data-id":"UpdateBanner-text",children:r("updateBanner.available","发现新版本 v{{v}}",{v:s.version})}),u.jsx("p",{style:{margin:"0 0 20px",fontSize:13,lineHeight:1.6,color:"#9aa4b2"},children:r("updateBanner.modalSub","建议尽快更新到最新版本")}),u.jsxs("div",{style:{display:"flex",gap:10,justifyContent:"center"},children:[u.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","稍后")}),u.jsx("button",{type:"button","data-id":"UpdateBanner-download",onClick:D,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 gp(){return u.jsxs("div",{className:"bcard bcard--skeleton","data-id":"SkeletonCard","aria-hidden":!0,children:[u.jsx("div",{className:"bcard__accent",style:{background:"rgba(255,255,255,.08)",opacity:1}}),u.jsxs("div",{className:"bcard__top",children:[u.jsx("div",{className:"skel",style:{width:84,height:26,borderRadius:999}}),u.jsx("div",{className:"skel",style:{width:22,height:22,borderRadius:6}})]}),u.jsxs("div",{style:{flex:1,minHeight:0,marginTop:14},children:[u.jsxs("div",{style:{display:"flex",alignItems:"center",gap:8},children:[u.jsx("div",{className:"skel",style:{width:24,height:24,borderRadius:6,flex:"0 0 auto"}}),u.jsx("div",{className:"skel skel--line",style:{width:"55%"}})]}),u.jsx("div",{className:"skel",style:{width:60,height:18,borderRadius:6,marginTop:12}})]}),u.jsx("div",{className:"skel skel--cta",style:{marginTop:0}})]})}const Tm=["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 bp(s){s=String(s??"");let g=0;for(let S=0;S<s.length;S++)g=(g*31+s.charCodeAt(S))%100003;return g}function vp(s){return Tm[bp(s)%Tm.length]}function km({open:s,onClose:g,toastId:S="cft-op"}){const[d,j]=v.useState(!1),[M,D]=v.useState(""),[R,w]=v.useState({enabled:!1,token:"",host:""});v.useEffect(()=>{var A,W;!s||!((W=(A=window.cicy)==null?void 0:A.sidecar)!=null&&W.getCft)||(D(""),window.cicy.sidecar.getCft().then(L=>{L!=null&&L.cft&&w({enabled:!!L.cft.enabled,token:L.cft.token||"",host:L.cft.host||""})}).catch(()=>{}))},[s]);const h=async()=>{var A,W;if(!d){if(R.enabled){if(!String(R.token).trim()){D(r("sidecar.cftNeedToken","开启需要填 Tunnel Token"));return}if(!String(R.host).trim()){D(r("sidecar.cftNeedHost","公网域名 Host 不能为空"));return}}j(!0),D(""),St.show({id:S,message:r("sidecar.cftApplying","应用 Cloudflare Tunnel,重启中…"),status:"running",progress:void 0});try{const L=await window.cicy.sidecar.setCft(R);L!=null&&L.ok?(L.cft&&w(L.cft),(A=L.cft)!=null&&A.enabled&&!L.tunnelUp?(D(r("sidecar.cftTunnelDown","隧道未连上:Token 可能无效/过期,或域名未在 Cloudflare 配好路由")),St.show({id:S,message:r("sidecar.cftTunnelDown","隧道未连上:Token 可能无效…"),status:"error",ttl:7e3})):(g&&g(),St.show({id:S,message:(W=L.cft)!=null&&W.enabled?r("sidecar.cftConnected","隧道已连接")+(L.url?`: ${L.url}`:""):r("sidecar.cftOff","Cloudflare Tunnel 已关闭"),status:"done",ttl:4e3}))):(D((L==null?void 0:L.error)||r("sidecar.cftFailed","设置失败")),St.show({id:S,message:r("sidecar.cftFailed","设置失败")+(L!=null&&L.error?`: ${L.error}`:""),status:"error",ttl:6e3}))}catch(L){D((L==null?void 0:L.message)||String(L)),St.show({id:S,message:r("sidecar.cftFailed","设置失败")+`: ${(L==null?void 0:L.message)||L}`,status:"error",ttl:6e3})}finally{j(!1)}}},Z=A=>{g&&g()};return s?u.jsx(u.Fragment,{children:xa.createPortal(u.jsx("div",{"data-id":"cft-modal",style:{position:"fixed",inset:0,zIndex:66,display:"flex",alignItems:"center",justifyContent:"center",background:"rgba(0,0,0,.5)"},onMouseDown:A=>{!d&&A.target===A.currentTarget&&Z()},children:u.jsxs("div",{onClick:A=>A.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:[u.jsx("div",{style:{fontSize:16,fontWeight:700,marginBottom:4},children:r("sidecar.cftTitle","Cloudflare 隧道")}),u.jsx("div",{style:{fontSize:12,opacity:.6,marginBottom:16},children:r("sidecar.cftSubtitle","把本机 cicy-code 通过 Cloudflare 命名隧道暴露到固定公网域名")}),u.jsxs("label",{"data-id":"cft-toggle-row",style:{display:"flex",alignItems:"center",gap:10,cursor:d?"default":"pointer",marginBottom:16},children:[u.jsx("input",{type:"checkbox","data-id":"cft-toggle",checked:R.enabled,disabled:d,onChange:A=>w(W=>({...W,enabled:A.target.checked}))}),u.jsx("span",{style:{fontSize:14,fontWeight:600},children:r("sidecar.cftEnable","开启隧道")})]}),u.jsx("div",{style:{fontSize:12,opacity:.7,marginBottom:6},children:r("sidecar.cftToken","Tunnel Token")}),u.jsx("textarea",{"data-id":"cft-token",rows:3,className:"login-email-input",style:{width:"100%",resize:"vertical",lineHeight:1.4,fontFamily:"var(--mono)",wordBreak:"break-all"},value:R.token,placeholder:"eyJhIjoi…(粘贴 Cloudflare connector token)",spellCheck:!1,disabled:d,onChange:A=>w(W=>({...W,token:A.target.value.replace(/\s+/g,"")}))}),u.jsx("div",{style:{fontSize:12,opacity:.7,margin:"12px 0 6px"},children:r("sidecar.cftHost","公网域名 Host")}),u.jsx("input",{"data-id":"cft-host",className:"login-email-input",style:{width:"100%",fontFamily:"var(--mono)"},value:R.host,placeholder:"cloudshell.cicy-ai.com",spellCheck:!1,disabled:d,onChange:A=>w(W=>({...W,host:A.target.value.replace(/[\r\n\s]+/g,"").trim()})),onKeyDown:A=>{A.key==="Escape"&&!d&&Z()}}),M&&u.jsx("div",{className:"error",style:{marginTop:8,fontSize:12},children:M}),u.jsxs("div",{className:"modal-actions",children:[u.jsx("button",{type:"button",className:"btn-ghost",disabled:d,onClick:()=>Z(),children:r("common.cancel","取消")}),u.jsx("button",{type:"button",className:"btn-primary","data-id":"cft-save",disabled:d,onClick:h,children:d?r("common.saving","保存中…"):r("common.save","保存")})]})]})}),document.body)}):null}function so({avatar:s,name:g,teamId:S,onChanged:d,size:j=34}){const M=v.useRef(null),D=((g||"?").trim()[0]||"?").toUpperCase(),R=vp(S||g||""),w=h=>{const Z=h.target.files&&h.target.files[0];if(h.target.value="",!Z)return;const A=new FileReader;A.onload=async()=>{var W,L,I;try{await((I=(L=(W=window.cicy)==null?void 0:W.localTeams)==null?void 0:L.setAvatar)==null?void 0:I.call(L,S,A.result)),d&&d()}catch{}},A.readAsDataURL(Z)};return u.jsxs("div",{"data-id":"TeamAvatar",className:"team-avatar",title:S?r("teamCard.changeAvatar","点击更换头像"):"",onClick:S?h=>{h.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":R,color:"#fff",fontWeight:700,fontSize:Math.round(j*.42),userSelect:"none"},children:[s?u.jsx("img",{src:s,alt:"",style:{width:"100%",height:"100%",objectFit:"cover"}}):D,S&&u.jsx("input",{ref:M,type:"file",accept:"image/*",style:{display:"none"},onChange:w})]})}function Sp(){return u.jsx("svg",{width:"22",height:"22",viewBox:"0 0 96 96",fill:"none",children:u.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",fill:"white",stroke:"white",strokeWidth:"8",strokeLinejoin:"round",strokeLinecap:"round"})})}function Hu(){return u.jsxs("svg",{width:"16",height:"16",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2.2",strokeLinecap:"round",strokeLinejoin:"round",children:[u.jsx("line",{x1:"5",y1:"12",x2:"19",y2:"12"}),u.jsx("polyline",{points:"12 5 19 12 12 19"})]})}function Ge(){return u.jsx("svg",{className:"spin",width:"16",height:"16",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2.4",strokeLinecap:"round",children:u.jsx("path",{d:"M21 12a9 9 0 1 1-6.2-8.55"})})}function xp(){return u.jsxs("svg",{width:"12",height:"12",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:[u.jsx("rect",{x:"3",y:"4",width:"18",height:"12",rx:"2"}),u.jsx("line",{x1:"2",y1:"20",x2:"22",y2:"20"})]})}function oo(){return u.jsxs("svg",{width:"16",height:"16",viewBox:"0 0 24 24",fill:"currentColor","aria-hidden":!0,children:[u.jsx("circle",{cx:"12",cy:"5",r:"1.7"}),u.jsx("circle",{cx:"12",cy:"12",r:"1.7"}),u.jsx("circle",{cx:"12",cy:"19",r:"1.7"})]})}function _p(){return u.jsxs("svg",{width:"12",height:"12",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:[u.jsx("circle",{cx:"12",cy:"12",r:"10"}),u.jsx("line",{x1:"2",y1:"12",x2:"22",y2:"12"}),u.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 Si(s){try{return localStorage.getItem(s)||null}catch{return null}}function Wa(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 Cm;const wp=((Cm=window.cicy)==null?void 0:Cm.platform)||(()=>{const s=navigator.userAgent||"";return/Mac/i.test(s)?"darwin":/Windows/i.test(s)?"win32":"linux"})();document.documentElement.dataset.platform=wp;document.documentElement.dataset.fullscreen="0";var jm,zm;(zm=(jm=window.cicy)==null?void 0:jm.window)!=null&&zm.onFullscreen&&window.cicy.window.onFullscreen(s=>{document.documentElement.dataset.fullscreen=s?"1":"0"});Iy.createRoot(document.getElementById("root")).render(u.jsx(up,{}));
|
|
@@ -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-WFj0s8TL.js"></script>
|
|
10
10
|
<link rel="stylesheet" crossorigin href="./assets/index-C6Zrdgc0.css">
|
|
11
11
|
</head>
|
|
12
12
|
<body>
|
|
@@ -553,14 +553,16 @@ async function pullCustomTeams() {
|
|
|
553
553
|
const nodes = readNodes();
|
|
554
554
|
const stripUrl = (u) => { let s = String(u || "").trim(); try { const x = new URL(s); x.search = ""; x.hash = ""; s = x.toString(); } catch {} return normaliseUrl(s.replace(/\/$/, "")); };
|
|
555
555
|
const have = new Set(Object.values(nodes).map((n) => stripUrl(n?.base_url)).filter(Boolean));
|
|
556
|
-
|
|
556
|
+
// cloud_team_id 用 String 归一比较 —— 云端返回 number、本地可能存成 number/string,不归一
|
|
557
|
+
// 会漏判(dedup 失效 → 又 materialize 一次,可能按派生 id 覆盖掉用户刚改过 URL 的那张卡)。
|
|
558
|
+
const haveCloudIds = new Set(Object.values(nodes).map((n) => (n?.cloud_team_id != null ? String(n.cloud_team_id) : null)).filter(Boolean));
|
|
557
559
|
let n = 0;
|
|
558
560
|
for (const t of list.teams) {
|
|
559
561
|
if (t.kind !== "custom") continue;
|
|
560
562
|
const host = String(t.host_url || t.hostUrl || "").trim();
|
|
561
563
|
if (!host) continue;
|
|
562
564
|
const tid = t.teamId || t.id || null;
|
|
563
|
-
if (have.has(stripUrl(host)) || (tid && haveCloudIds.has(tid))) continue; // 本地已有
|
|
565
|
+
if (have.has(stripUrl(host)) || (tid != null && haveCloudIds.has(String(tid)))) continue; // 本地已有
|
|
564
566
|
try {
|
|
565
567
|
const r = await addTeam({ base_url: host, name: t.title || t.name || host, cloud_team_id: tid });
|
|
566
568
|
if (r && r.ok) { n++; log.info(`[local-teams] materialized custom team ${host} (cloud teamId=${tid})`); }
|
|
@@ -597,11 +599,14 @@ async function addTeam(spec) {
|
|
|
597
599
|
const baseUrlRaw = String(spec.base_url || "").trim();
|
|
598
600
|
if (!baseUrlRaw) return { ok: false, error: "base_url required" };
|
|
599
601
|
try { new URL(baseUrlRaw); } catch { return { ok: false, error: "bad base_url" }; }
|
|
600
|
-
// base_url
|
|
601
|
-
//
|
|
602
|
-
//
|
|
602
|
+
// **本地团队**(localhost/127.0.0.1/::1)才把 base_url 剥成干净 origin —— 它 token 从
|
|
603
|
+
// global.json 实时读,URL 里存 ?token= 快照会陈旧、打开还会双拼。**自定义远程团队相反**:
|
|
604
|
+
// token 只在用户给的 URL 里,原样保留、绝不剥 query/hash(主人:不要动原始的 url),否则
|
|
605
|
+
// token 丢、节点打不开。isLocalUrl 在这里算一次,下面复用。
|
|
606
|
+
let isLocalUrl = false;
|
|
607
|
+
try { const h = new URL(baseUrlRaw).hostname; isLocalUrl = h === "127.0.0.1" || h === "localhost" || h === "::1"; } catch {}
|
|
603
608
|
let baseUrl = baseUrlRaw.replace(/\/$/, "");
|
|
604
|
-
try { const u = new URL(baseUrl); u.search = ""; u.hash = ""; baseUrl = u.toString().replace(/\/$/, ""); } catch {}
|
|
609
|
+
if (isLocalUrl) { try { const u = new URL(baseUrl); u.search = ""; u.hash = ""; baseUrl = u.toString().replace(/\/$/, ""); } catch {} }
|
|
605
610
|
const baseUrlKey = normaliseUrl(baseUrl);
|
|
606
611
|
let port = null;
|
|
607
612
|
try { port = parseInt(new URL(baseUrl).port, 10) || null; } catch {}
|
|
@@ -609,9 +614,7 @@ async function addTeam(spec) {
|
|
|
609
614
|
// 本地团队的 token **不存进 teams.json**: localhost/127.0.0.1/::1 的 cicy-code 与
|
|
610
615
|
// cicy-desktop 共用同一份 ~/cicy-ai/global.json,openTeam 打开时**实时读 global.json**(token
|
|
611
616
|
// 轮换即时跟上)。存一份快照只会陈旧 → ?token= 旧值 → :8008 拒 → 卡登录。所以本地一律存 ""
|
|
612
|
-
// (与 :8008 docker 的 skipTokenAutofill 同理),不再自动回填。
|
|
613
|
-
let isLocalUrl = false;
|
|
614
|
-
try { const h = new URL(baseUrl).hostname; isLocalUrl = h === "127.0.0.1" || h === "localhost" || h === "::1"; } catch {}
|
|
617
|
+
// (与 :8008 docker 的 skipTokenAutofill 同理),不再自动回填。isLocalUrl 已在上面算过。
|
|
615
618
|
|
|
616
619
|
// base_url is the dedupe key: if a team with the same URL already exists
|
|
617
620
|
// we upsert it (refresh token + install meta), never create a duplicate.
|
|
@@ -714,9 +717,12 @@ async function updateTeam(id, patch) {
|
|
|
714
717
|
if (k === "base_url") {
|
|
715
718
|
if (!v) return { ok: false, error: "base_url cannot be empty" };
|
|
716
719
|
try { new URL(String(v)); } catch { return { ok: false, error: "bad base_url" }; }
|
|
717
|
-
// 和 addTeam
|
|
720
|
+
// 和 addTeam 一致:本地团队剥成干净 origin;自定义远程团队**原样保留**(含 ?token=,
|
|
721
|
+
// 主人:不要动原始的 url)——token 只在 URL 里,剥了就打不开。
|
|
718
722
|
let bu = String(v).replace(/\/$/, "");
|
|
719
|
-
|
|
723
|
+
let localU = false;
|
|
724
|
+
try { const h = new URL(bu).hostname; localU = h === "127.0.0.1" || h === "localhost" || h === "::1"; } catch {}
|
|
725
|
+
if (localU) { try { const u = new URL(bu); u.search = ""; u.hash = ""; bu = u.toString().replace(/\/$/, ""); } catch {} }
|
|
720
726
|
filtered[k] = bu;
|
|
721
727
|
} else if (k === "api_token") {
|
|
722
728
|
filtered[k] = String(v || "");
|
|
@@ -751,9 +757,9 @@ async function updateTeam(id, patch) {
|
|
|
751
757
|
});
|
|
752
758
|
if (!existed) return { ok: false, error: "team not found" };
|
|
753
759
|
log.info(`[local-teams] update ${id} → ${Object.keys(filtered).join(",")}`);
|
|
754
|
-
//
|
|
755
|
-
//
|
|
756
|
-
if (isRename) syncNameToCloud(id).catch(() => {});
|
|
760
|
+
// 改名 或 改 base_url(自定义团队换址)都要同步到云端:改名走 title,换址走 host_url
|
|
761
|
+
// (custom 分支 PATCH host_url)。否则云端留着旧 URL,下次 pull 又把旧地址拉回来 = 改了白改。
|
|
762
|
+
if (isRename || filtered.base_url) syncNameToCloud(id).catch(() => {});
|
|
757
763
|
const next = readNodes()[id] || {};
|
|
758
764
|
let port = null;
|
|
759
765
|
try { port = parseInt(new URL(next.base_url || "").port, 10) || null; } catch {}
|
|
@@ -550,8 +550,10 @@ export default function App() {
|
|
|
550
550
|
try {
|
|
551
551
|
const r = await window.cicy.localTeams.add({ base_url: url, name: customTitle.trim(), failIfExists: true });
|
|
552
552
|
if (!r || r.ok === false) { setCustomErr(r?.error === "exists" ? tr("teams.urlExists", "该地址已存在") : humanError(r?.error || "add failed")); return; }
|
|
553
|
-
|
|
553
|
+
// 先刷新列表(loading 全程覆盖到新卡出现),成功后再关 modal —— 否则关了之后到卡片
|
|
554
|
+
// 刷出来之间那段没 loading。
|
|
554
555
|
await fetchLocalTeams();
|
|
556
|
+
setCustomTitle(""); setCustomUrl(""); setCustomOpen(false);
|
|
555
557
|
} catch (e) {
|
|
556
558
|
setCustomErr(humanError(e?.message || String(e)));
|
|
557
559
|
} finally {
|