@nelsonlongxiang/dsh-open-a2a-net 0.7.0 → 0.8.1-preview.1
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/LICENSE +21 -0
- package/README.md +109 -94
- package/README_zh.md +64 -66
- package/THIRD_PARTY_NOTICES.md +12 -0
- package/assets/nexusDist/assets/index-BuidhKVr.css +1 -0
- package/assets/nexusDist/assets/index-YtYrkDJi.js +9 -0
- package/assets/nexusDist/index.html +2 -2
- package/cli/a2a.mjs +349 -20
- package/cordis.patch.yml +167 -0
- package/docs/licenses/dsh-superagent-MIT.txt +21 -0
- package/lib/a2a-client.js +12 -4
- package/lib/card.js +2 -0
- package/lib/cli-deposit.js +75 -4
- package/lib/config.js +1 -2
- package/lib/direct-forward.js +23 -1
- package/lib/faces/admin.js +31 -48
- package/lib/faces/wire.js +110 -71
- package/lib/followup-admission.js +47 -0
- package/lib/followup-delivery.js +19 -2
- package/lib/index.js +618 -389
- package/lib/node-self.js +1 -1
- package/lib/outbound-scope.js +10 -0
- package/lib/peer-directory.js +3 -1
- package/lib/queue-guard.js +1 -1
- package/lib/receipt.js +24 -2
- package/lib/skill/SKILL.md +1 -0
- package/lib/skill/references/cli.md +193 -21
- package/lib/skill/references/collaboration.md +3 -2
- package/lib/skill/references/superagent.md +106 -0
- package/lib/superagent/a2a-watch.js +587 -0
- package/lib/superagent/contract.js +1 -0
- package/lib/superagent/host/a2a-source.js +251 -0
- package/lib/superagent/host/executor.js +520 -0
- package/lib/superagent/host/index.js +1107 -0
- package/lib/superagent/host/policy.js +308 -0
- package/lib/superagent/host/pr-follow.js +158 -0
- package/lib/superagent/host/review-requests.js +77 -0
- package/lib/superagent/host/role-tools.js +137 -0
- package/lib/superagent/host/store.js +136 -0
- package/lib/superagent/host/tools.js +297 -0
- package/lib/superagent/source-types.js +22 -0
- package/lib/superagent/upstream/dsh-superagent/src/core/assignments.js +160 -0
- package/lib/superagent/upstream/dsh-superagent/src/core/engine.js +244 -0
- package/lib/superagent/upstream/dsh-superagent/src/core/errors.js +63 -0
- package/lib/superagent/upstream/dsh-superagent/src/core/evals.js +381 -0
- package/lib/superagent/upstream/dsh-superagent/src/core/ids.js +5 -0
- package/lib/superagent/upstream/dsh-superagent/src/core/index.js +9 -0
- package/lib/superagent/upstream/dsh-superagent/src/core/intake.js +68 -0
- package/lib/superagent/upstream/dsh-superagent/src/core/memory.js +51 -0
- package/lib/superagent/upstream/dsh-superagent/src/core/model.js +79 -0
- package/lib/superagent/upstream/dsh-superagent/src/core/part.js +71 -0
- package/lib/superagent/upstream/dsh-superagent/src/core/ports.js +1 -0
- package/lib/superagent/upstream/dsh-superagent/src/core/reasons.js +35 -0
- package/lib/superagent/upstream/dsh-superagent/src/core/replies.js +94 -0
- package/lib/superagent/upstream/dsh-superagent/src/core/stage.js +27 -0
- package/lib/superagent/upstream/dsh-superagent/src/core/tickets.js +487 -0
- package/lib/superagent/upstream/snapshot-8c32a9d.js +62 -0
- package/lib/task-auth.js +21 -0
- package/lib/task-ledger-rows.js +4 -0
- package/lib/task-ledger.js +69 -3
- package/lib/tools/info.js +13 -7
- package/lib/types/a2a-client.d.ts +0 -7
- package/lib/types/cli-deposit.d.ts +65 -1
- package/lib/types/config.d.ts +6 -20
- package/lib/types/direct-forward.d.ts +14 -0
- package/lib/types/faces/admin.d.ts +5 -0
- package/lib/types/faces/wire.d.ts +20 -57
- package/lib/types/followup-admission.d.ts +13 -0
- package/lib/types/followup-delivery.d.ts +1 -1
- package/lib/types/index.d.ts +0 -2
- package/lib/types/outbound-scope.d.ts +1 -0
- package/lib/types/queue-guard.d.ts +2 -0
- package/lib/types/receipt.d.ts +21 -1
- package/lib/types/superagent/a2a-watch.d.ts +227 -0
- package/lib/types/superagent/contract.d.ts +36 -0
- package/lib/types/superagent/host/a2a-source.d.ts +90 -0
- package/lib/types/superagent/host/executor.d.ts +132 -0
- package/lib/types/superagent/host/index.d.ts +340 -0
- package/lib/types/superagent/host/policy.d.ts +128 -0
- package/lib/types/superagent/host/pr-follow.d.ts +51 -0
- package/lib/types/superagent/host/review-requests.d.ts +36 -0
- package/lib/types/superagent/host/role-tools.d.ts +85 -0
- package/lib/types/superagent/host/store.d.ts +61 -0
- package/lib/types/superagent/host/tools.d.ts +32 -0
- package/lib/types/superagent/source-types.d.ts +218 -0
- package/lib/types/superagent/upstream/dsh-superagent/src/core/assignments.d.ts +53 -0
- package/lib/types/superagent/upstream/dsh-superagent/src/core/engine.d.ts +191 -0
- package/lib/types/superagent/upstream/dsh-superagent/src/core/errors.d.ts +58 -0
- package/lib/types/superagent/upstream/dsh-superagent/src/core/evals.d.ts +99 -0
- package/lib/types/superagent/upstream/dsh-superagent/src/core/ids.d.ts +1 -0
- package/lib/types/superagent/upstream/dsh-superagent/src/core/index.d.ts +9 -0
- package/lib/types/superagent/upstream/dsh-superagent/src/core/intake.d.ts +15 -0
- package/lib/types/superagent/upstream/dsh-superagent/src/core/memory.d.ts +40 -0
- package/lib/types/superagent/upstream/dsh-superagent/src/core/model.d.ts +432 -0
- package/lib/types/superagent/upstream/dsh-superagent/src/core/part.d.ts +49 -0
- package/lib/types/superagent/upstream/dsh-superagent/src/core/ports.d.ts +217 -0
- package/lib/types/superagent/upstream/dsh-superagent/src/core/reasons.d.ts +36 -0
- package/lib/types/superagent/upstream/dsh-superagent/src/core/replies.d.ts +55 -0
- package/lib/types/superagent/upstream/dsh-superagent/src/core/stage.d.ts +18 -0
- package/lib/types/superagent/upstream/dsh-superagent/src/core/tickets.d.ts +151 -0
- package/lib/types/superagent/upstream/snapshot-8c32a9d.d.ts +317 -0
- package/lib/types/task-auth.d.ts +9 -0
- package/lib/types/task-ledger-rows.d.ts +21 -4
- package/lib/types/task-ledger.d.ts +9 -0
- package/lib/types/types.d.ts +7 -4
- package/nexus-stage/scripts/mockhost.py +2 -2
- package/nexus-stage/src/main.ts +27 -0
- package/nexus-stage/src/planning-card-text.ts +1 -1
- package/nexus-stage/src/planning-team-roles.ts +80 -0
- package/nexus-stage/src/planning-types.ts +2 -0
- package/nexus-stage/src/planning-view.ts +1 -0
- package/nexus-stage/src/planning.css +29 -9
- package/nexus-stage/src/wb-superagent.ts +518 -0
- package/nexus-stage/src/workbench.css +32 -0
- package/nexus-stage/src/workbench.ts +25 -3
- package/nexus-stage/src/world.ts +1 -1
- package/package.json +8 -2
- package/assets/nexusDist/assets/index-C7HagaGy.css +0 -1
- package/assets/nexusDist/assets/index-CA_YZTWG.js +0 -9
- package/assets/stageDist/assets/index-Bj7S2pA1.css +0 -1
- package/assets/stageDist/assets/index-C-28k_o5.js +0 -974
- package/assets/stageDist/assets/interiors-CQGBjffT.png +0 -0
- package/assets/stageDist/assets/office-tileset-CHQT-uYL.png +0 -0
- package/assets/stageDist/index.html +0 -13
- package/lib/legacy/teams-bridge-inbound.js +0 -156
- package/lib/teams-bridge.js +0 -18
- package/lib/types/legacy/teams-bridge-inbound.d.ts +0 -94
- package/lib/types/teams-bridge.d.ts +0 -112
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
var Yo=Object.defineProperty;var Wo=(e,t,n)=>t in e?Yo(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n;var Ft=(e,t,n)=>Wo(e,typeof t!="symbol"?t+"":t,n);(function(){const t=document.createElement("link").relList;if(t&&t.supports&&t.supports("modulepreload"))return;for(const o of document.querySelectorAll('link[rel="modulepreload"]'))s(o);new MutationObserver(o=>{for(const r of o)if(r.type==="childList")for(const i of r.addedNodes)i.tagName==="LINK"&&i.rel==="modulepreload"&&s(i)}).observe(document,{childList:!0,subtree:!0});function n(o){const r={};return o.integrity&&(r.integrity=o.integrity),o.referrerPolicy&&(r.referrerPolicy=o.referrerPolicy),o.crossOrigin==="use-credentials"?r.credentials="include":o.crossOrigin==="anonymous"?r.credentials="omit":r.credentials="same-origin",r}function s(o){if(o.ep)return;o.ep=!0;const r=n(o);fetch(o.href,r)}})();const vn=6e4;function qo(e,t,n=Date.now){let s=-vn;return{fault(o){const r=n();r-s>=vn&&(t(`[nexus] ${o}`),s=r),e.show(o)},clear(){e.hide(),s=-vn}}}function xt(e){return e.name??e.team??e.label??""}function xo(e,t){var r,i;const n=(c,d)=>c!==void 0&&c.trim()!==""?{name:c,remote:d}:void 0,s=(e.sessions??[]).find(c=>c.team===t);if(s!==void 0)return n(xt(s),!1);const o=(e.remote??[]).find(c=>c.team===t);return o!==void 0?n(xt(o),!0):n((i=(((r=e.canvas)==null?void 0:r.teams)??[]).find(c=>c.team===t))==null?void 0:i.name,!1)}function Ko(e,t){const n=xo(e,t);return n===void 0?t:n.remote?`${n.name}(远端)`:n.name}function rn(e,t,n,s=""){const o=xo(t,n);if(e.textContent=`${s}${(o==null?void 0:o.name)??n}`,e.title=n,(o==null?void 0:o.remote)===!0){const r=e.appendChild(document.createElement("span"));r.className="wb-row-remote",r.textContent="远端",r.title="名字由对端自行发布"}}const Xo=60*6e4;function Dt(e){var t;return e.direction==="inbound"||e.direction===void 0&&((t=e.peer)==null?void 0:t.startsWith("local:"))===!0}function Yn(e){var t;return((t=e.peer)==null?void 0:t.startsWith("local:"))===!0?e.peer.slice(6):void 0}function Ut(e,t){return e.settleable!==void 0?e.settleable===!1:t-e.startedAt>=Xo}function Nn(e,t){const n=(e.tasks??[]).filter(i=>i.receiptExpected!==!1),s=n.filter(i=>!Dt(i)&&Ut(i,t)),o=n.filter(i=>Dt(i)&&Ut(i,t)),r=e.tasksDead??[];return{stale:s,owedOverdue:o,deadLetters:r.filter(i=>i.reason!=="fire-forget"),expired:r.filter(i=>i.reason==="fire-forget")}}function Oe(e,t){const n=document.createElement(e);return t!==void 0&&(n.className=t),n}function Wn(e,t){const n=Math.max(0,Math.round((t-e)/1e3));if(n<90)return`${n}s`;const s=Math.round(n/60);if(s<90)return`${s}m`;const o=Math.round(s/60);return o<48?`${o}h`:`${Math.round(o/24)}d`}function Vt(e,t,n,s,o){const r=Oe("div",`wb-led-tile${o!==void 0?` is-${o}`:""}`);r.title=s,r.appendChild(Oe("span","wb-led-tile-v")).textContent=String(n),r.appendChild(Oe("span","wb-led-tile-k")).textContent=t,e.appendChild(r)}const Sn=[{key:"completed",label:"完成",tone:"completed"},{key:"sync_completed",label:"同步完成",tone:"completed"},{key:"rejected",label:"拒绝",tone:"rejected"},{key:"failed",label:"失败",tone:"failed"},{key:"expired",label:"过期",tone:"abandoned"},{key:"abandoned",label:"放弃",tone:"abandoned"},{key:"unknown",label:"结论不明",tone:"unclassified"},{key:"unclassified",label:"未分类",tone:"unclassified"}];function Uo(e,t,n){const s=Oe("div","wb-led-split"),o=Oe("div","wb-led-split-bar");o.setAttribute("role","img");const r=Oe("div","wb-led-split-legend"),i=new Set(Sn.map(u=>u.key)),c=Sn.map(u=>[u.tone,u.label,t[u.key]??0]);for(const[u,h]of Object.entries(t))i.has(u)||c.push(["other",u,h]);const d=[];for(const[u,h,m]of c){if(m<=0)continue;const $=Oe("span",`wb-led-seg is-${u}`);$.style.width=`${Math.max(2,m/n*100)}%`,o.appendChild($);const N=Oe("span","wb-led-split-item");N.appendChild(Oe("i",`wb-led-swatch is-${u}`)),N.appendChild(document.createTextNode(`${h} ${m}`)),r.appendChild(N),d.push(`${h} ${m}`)}o.setAttribute("aria-label",`归档结局:${d.join(",")}`),s.append(o,r),e.appendChild(s)}function Jo(e,t){var Le;e.replaceChildren();const{state:n,now:s}=t,o=n.tasks??[],r=n.tasksDead??[],i=n.archivedCount??0,c=Nn(n,s),d=o.filter(R=>R.receiptExpected===!1),u=o.filter(R=>R.receiptExpected!==!1),h=u.filter(R=>Dt(R)),m=u.filter(R=>!Dt(R)),$=c.stale,N=m.filter(R=>!Ut(R,s)),te=c.stale.length,le=Oe("div","wb-led-tiles");Vt(le,"待回执",u.length,`要回执、仍未结算的任务(含陈旧与本机欠对方的入站行)${d.length>0?`;另有免回执 ${d.length} 条不计`:""}`),Vt(le,"陈旧",te,"我方派发、要回执、已等待 ≥1h 仍未回执(可催办);本机欠对方的入站行在「待本机回执」组另计,免回执行不算陈旧",te>0?"warn":void 0),Vt(le,"死信",c.deadLetters.length,"超过 24h TTL 仍未结算(unconsumed);需清账(abandon)才能移出。免回执到期另列,不算死信",c.deadLetters.length>0?"danger":void 0),Vt(le,"已归档",i,"已离开台账并留档的任务(结算、拒绝或放弃),用于审计"),e.appendChild(le),i>0&&n.archivedSplit!==void 0&&Uo(e,n.archivedSplit,i);const ie=(R,se)=>{const be=Oe("div",`wb-led-card is-${se.tone}`),Ue=Oe("div","wb-led-card-head");Ue.appendChild(Oe("span",`wb-led-dir${se.inbound?" is-in":""}`)).textContent=se.inbound?"↙":"↗";const w=Oe("span","wb-led-brief");w.textContent=se.brief!==void 0&&se.brief!==""?se.brief:"(无摘要——派发未带 brief)",(se.brief===void 0||se.brief==="")&&w.classList.add("is-missing"),Ue.appendChild(w),be.appendChild(Ue);const A=Oe("div","wb-led-meta"),oe=A.appendChild(Oe("span","wb-led-team"));se.inbound?se.sender!==void 0?rn(oe,n,se.sender,"来自 "):oe.textContent="来自 对端":rn(oe,n,se.team,"发往 "),se.inbound&&rn(A.appendChild(Oe("span","wb-led-to")),n,se.team,"至 "),A.appendChild(Oe("span")).textContent=se.atText,A.appendChild(Oe("span","wb-led-task")).textContent=se.taskId;for(const I of se.chips)A.appendChild(Oe("span","wb-led-chip")).textContent=I;if(be.appendChild(A),be.title=`${se.taskId}
|
|
2
|
+
${se.team}`,se.dead!==void 0){const I=se.dead,T=I.reason==="fire-forget",W=Oe("button",`wb-btn wb-led-abandon${T?" is-quiet":""}`);W.type="button",W.textContent=T?"移出":"清账",W.title=T?"可选:把这条已过期的免回执记录移出台账(不是失败,不处理也无妨)":"从台账移出这条死信(abandon)",W.addEventListener("click",q=>{q.stopPropagation(),W.disabled=!0,t.abandon(I.taskId,"workbench dead-letter cleanup").then(K=>{W.disabled=!1,W.textContent=K?"已清":"失败"})}),be.appendChild(W)}if(t.canOpenTeam(se.team)){be.classList.add("is-link"),be.setAttribute("role","button"),be.tabIndex=0,be.setAttribute("aria-label",`${w.textContent},打开 ${se.team} 的对话`);const I=()=>{t.openTeam(se.team)};be.addEventListener("click",I),be.addEventListener("keydown",T=>{(T.key==="Enter"||T.key===" ")&&(T.preventDefault(),I())})}R.appendChild(be)},S=(R,se,be,Ue)=>{if(se===0)return null;const w=Oe("div",`wb-led-group is-${be}`);w.dataset.group=R;const A=Oe("div","wb-led-group-head");return A.appendChild(Oe("span")).textContent=`${R} · ${se}`,A.appendChild(Oe("span","wb-led-group-hint")).textContent=Ue,w.appendChild(A),e.appendChild(w),w},E=(R,se)=>{const be=Dt(R);return{brief:R.brief,team:R.team,sender:Yn(R),taskId:R.taskId,atText:`${Wn(R.startedAt,s)} 前${be?"收到":"派发"}`,inbound:be,tone:se,chips:[...R.settleable===!0?["可结算"]:[],...R.receiptExpected===!1?["无回执债"]:[],...be?["入站"]:[],...R.status!=="pending"?[R.status]:[]]}},L=(R,se,be)=>({brief:R.brief,team:R.team,sender:Yn(R),taskId:R.taskId,atText:`${Wn(R.deadAt,s)} 前${be}`,inbound:Dt(R),tone:se,dead:R,chips:R.reason!==void 0&&R.reason!==""&&R.reason!=="unspecified"&&R.reason!=="fire-forget"?[R.reason]:[]}),C=S("死信",c.deadLetters.length,"danger","需清账");if(C!==null)for(const R of[...c.deadLetters].sort((se,be)=>be.deadAt-se.deadAt))ie(C,L(R,"danger","死信"));const ce=S("陈旧",$.length,"warn","我方派发 ≥1 小时仍无回执,可催办");if(ce!==null)for(const R of[...$].sort((se,be)=>se.startedAt-be.startedAt))ie(ce,E(R,"warn"));const x=c.owedOverdue.length,f=S("待本机回执",h.length,x>0?"warn":"quiet",x>0?`对方在等本机回执 · ${x} 条超过 1 小时`:"对方在等本机回执");if(f!==null)for(const R of[...h].sort((se,be)=>se.startedAt-be.startedAt))ie(f,E(R,Ut(R,s)?"warn":"quiet"));const M=S("等待回执",N.length,"quiet","1 小时内");if(M!==null)for(const R of[...N].sort((se,be)=>be.startedAt-se.startedAt))ie(M,E(R,"quiet"));const p=S("免回执",d.length,"muted","不等回执,24h 后自动归档");if(p!==null)for(const R of d)ie(p,E(R,"muted"));const H=S("已过期(免回执)",c.expired.length,"muted","正常记账,不是失败");if(H!==null)for(const R of[...c.expired].sort((se,be)=>be.deadAt-se.deadAt))ie(H,L(R,"muted","过期"));o.length+r.length===0&&(e.appendChild(Oe("div","wb-led-empty")).textContent="台账为空——没有待回执的任务");const z=n.idempotency,G=(Le=n.reconcile)==null?void 0:Le.state;if(z!==void 0||G!==void 0){const R=Oe("details","wb-led-forensics wb-forensics");R.appendChild(Oe("summary")).textContent="取证";const se=Oe("div","wb-led-forensics-body");z!==void 0&&(se.appendChild(Oe("div")).textContent=`幂等 claims ${z.claimsFresh??0} · replays ${z.replays??0} · conflicts ${z.conflicts??0}`),G!==void 0&&(se.appendChild(Oe("div")).textContent=`reconcile ${G}`),R.appendChild(se),e.appendChild(R)}const Ee=u.length+c.deadLetters.length;return{badge:Ee>0?String(Ee):"",tone:c.deadLetters.length>0?"danger":te>0||x>0?"warn":void 0}}const Yt=4e3,zo=32;function Ae(e,t){const n=document.createElement(e);return t!==void 0&&(n.className=t),n}function Gt(e,t,n=""){const s=Ae("button",`wb-icon-btn wb-chat-act ${n}`.trim());return s.type="button",s.setAttribute("aria-label",e),s.title=e,s.textContent=t,s}function yn(e,t){const n=Math.max(0,Math.round((t-e)/1e3));if(n<60)return"刚刚";const s=Math.round(n/60);if(s<60)return`${s} 分钟前`;const o=Math.round(s/60);return o<48?`${o} 小时前`:`${Math.round(o/24)} 天前`}function Vo(e){return e>=1e6?`${(e/1e6).toFixed(1)} MB`:e>=1e3?`${Math.round(e/1e3)} KB`:`${e} B`}function wn(e){const t=e.kind==="session"||e.kind==="remote"?e.team:void 0;return t!==void 0&&t!==""?t:void 0}function qn(e){return e.kind==="remote"?`remote:${e.team}`:`${e.kind}:${e.id}`}function Go(e){let t=null,n=null,s=!1,o=!1;const r=new Map,i=new Map,c=new Map,d=new Map,u=new Set,h=new Map,m=new Map,$=Ae("aside","wb-chat");$.setAttribute("aria-label","对话");const N=Ae("div","wb-chat-head"),te=Gt("返回会话列表","‹","wb-chat-back"),le=Ae("span","wb-chat-dot"),ie=Ae("div","wb-chat-titles"),S=Ae("span","wb-chat-title"),E=Ae("span","wb-chat-sub");ie.append(S,E);const L=Gt("刷新对话","↻","wb-chat-refresh"),C=Gt("会话详情","ⓘ","wb-chat-info-btn");C.setAttribute("aria-expanded","false");const ce=Gt("关闭对话","✕","wb-chat-close");N.append(te,le,ie,L,C,ce);const x=Ae("div","wb-chat-info");x.hidden=!0;const f=Ae("div","wb-chat-thread");f.setAttribute("role","log"),f.setAttribute("aria-live","polite"),f.tabIndex=0;const M=Ae("div","wb-chat-notice"),p=Ae("div","wb-chat-log"),H=Ae("div","wb-chat-sent");f.append(M,p,H);const z=Ae("div","wb-chat-foot");$.append(N,x,f,z),te.addEventListener("click",()=>{(t==null?void 0:t.kind)==="peer"&&(t.picked=void 0,Re())}),L.addEventListener("click",()=>{if(t===null)return;const l=G(t);l!==void 0&&r.delete(l),t.kind==="peer"&&t.picked===void 0&&t.url!==void 0&&c.delete(`peer:${t.url}`),W(!0)}),C.addEventListener("click",()=>{o=!o,x.hidden=!o,C.setAttribute("aria-expanded",String(o))}),ce.addEventListener("click",()=>Et()),f.addEventListener("scroll",()=>{const l=t!==null?G(t):void 0;l!==void 0&&i.set(l,f.scrollTop)}),document.addEventListener("keydown",l=>{if(l.key!=="Escape"||!$.classList.contains("is-open"))return;const O=l.target;if(O instanceof HTMLElement){if(!$.contains(O)){const F=O instanceof HTMLTextAreaElement||O instanceof HTMLInputElement||O.isContentEditable,ue=O.closest(".wb-stage-board")!==null;if(F||ue)return}Et()}});function G(l){if(l.kind==="session"||l.kind==="log")return e.sessionLog!==void 0?`local:${l.id}`:void 0;if(l.kind==="remote")return e.remoteSessionLog!==void 0?`remote:${l.team}`:void 0;if(l.picked!==void 0&&l.url!==void 0&&e.remoteSessionLog!==void 0)return`peer:${l.url}:${l.picked}`}function Ee(l){var O,F,ue;return l.kind==="session"||l.kind==="log"?((O=e.sessionLog)==null?void 0:O.call(e,l.id))??Promise.resolve({ok:!1,error:"sessionLog unavailable"}):l.kind==="remote"?((F=e.remoteSessionLog)==null?void 0:F.call(e,{team:l.team}))??Promise.resolve({ok:!1,error:"remoteSessionLog unavailable"}):((ue=e.remoteSessionLog)==null?void 0:ue.call(e,{peer:l.url,id:l.picked}))??Promise.resolve({ok:!1,error:"remoteSessionLog unavailable"})}function Le(){const l=t;if(l===null)return;const O=l.kind==="log"||l.kind==="remote"||l.kind==="session"&&l.live===!1;le.className=`wb-chat-dot ${l.kind==="peer"?"is-peer":O?"is-cold":"is-live"}`,le.title=l.kind==="peer"?"对端主机":l.kind==="log"?"只读日志":l.kind==="remote"?"远端会话":l.live===!1?"冷会话":"在线",S.textContent=l.kind==="peer"&&l.picked!==void 0?`…${l.picked.slice(-12)}`:l.title,E.textContent=l.kind==="peer"&&l.picked!==void 0?l.title:l.sub,te.hidden=!(l.kind==="peer"&&l.picked!==void 0)}function R(l,O){const F=Ae("div","wb-kv");F.appendChild(Ae("span","wb-kv-k")).textContent=l,F.appendChild(Ae("span","wb-kv-v")).textContent=O,x.appendChild(F)}function se(){var O,F,ue;x.replaceChildren();const l=t;l!==null&&(l.kind==="session"?(R("会话",l.id),l.team!==void 0&&R("路由",l.team),R("来源","本机会话日志")):l.kind==="log"?(R("会话",l.id),R("来源","本机会话日志(不在网络目录)")):l.kind==="remote"?(R("路由",l.team),((O=l.row)==null?void 0:O.origin)!==void 0&&R("来源",l.row.origin),((F=l.row)==null?void 0:F.via)!==void 0&&R("经",l.row.via),((ue=l.row)==null?void 0:ue.workspace)!==void 0&&R("工作区",l.row.workspace)):(R("对端",l.url??l.sub),l.picked!==void 0&&R("会话",l.picked),R("来源","经本机代理读取对端 /a2a/log")))}function be(l){return l.kind==="log"?"只读日志 —— 此会话当前不在网络目录(可能已归档或未入网)。":l.kind==="remote"?e.remoteSessionLog!==void 0?"远端会话 —— 经本机代理从对端 /a2a/log 读取最近对话。":"远端节点的对话记录在对端机器上;本页的代理读取面未启用。":l.kind==="peer"?l.url===void 0||e.remoteSessionLog===void 0?`对端主机节点(${l.sub})—— 会话记录存放在对端机器上,本页只读本机会话日志。`:l.picked===void 0?"对端主机 —— 选择一个会话阅读(经本机代理读取对端 /a2a/log)。":"":e.sessionLog===void 0?"本页未接入会话日志读取,只显示从这里发出的消息。":""}function Ue(){return f.scrollHeight-f.scrollTop-f.clientHeight<=zo}function w(l){const O=()=>{f.scrollTop=f.scrollHeight};O(),requestAnimationFrame(O)}function A(l,O){const F=Ae("div",`wb-chat-empty${O==="error"?" is-error":""}`);return F.textContent=l,F}function oe(l,O){const F=l==="user",ue=Ae("div",`wb-msg ${F?"wb-msg-user":"wb-msg-assistant"}`),U=Ae("span","wb-msg-who");U.textContent=F?"问":"答";const xe=Ae("div","wb-msg-text");return xe.textContent=O,ue.append(U,xe),ue}function I(l){if(p.replaceChildren(),l===void 0){p.appendChild(A("读取中…"));return}if(l.ok!==!0||l.messages===void 0){p.appendChild(A(`无法读取(${l.error??"未知错误"})`,"error"));return}if(l.messages.length===0){p.appendChild(A("暂无对话记录"));return}for(const O of l.messages)p.appendChild(oe(O.role,O.text))}function T(l,O){if(p.replaceChildren(),O===void 0){p.appendChild(A("读取中…"));return}if(O.ok!==!0||O.sessions===void 0){p.appendChild(A(`无法读取(${O.error??"未知错误"})`,"error"));return}if(O.sessions.length===0){p.appendChild(A("对端没有可读会话"));return}const F=Ae("div","wb-chat-sessions"),ue=e.now();for(const U of O.sessions){const xe=Ae("button","wb-chat-session");xe.type="button",xe.appendChild(Ae("span","wb-chat-session-id")).textContent=`…${U.id.slice(-12)}`;const Ce=[U.mtimeMs!==void 0?yn(U.mtimeMs,ue):"",Vo(U.sizeBytes)].filter(Boolean).join(" · ");xe.appendChild(Ae("span","wb-chat-session-meta")).textContent=Ce,xe.title=U.id,xe.addEventListener("click",()=>{(t==null?void 0:t.kind)!=="peer"||t.url!==l||(t.picked=U.id,Re())}),F.appendChild(xe)}p.appendChild(F)}function W(l=!1){const O=t;if(O===null)return;if(M.textContent=be(O),M.hidden=M.textContent==="",O.kind==="peer"&&O.picked===void 0){if(O.url===void 0||e.remoteSessionLog===void 0){p.replaceChildren();return}const U=O.url,xe=`peer:${U}`;if(!l&&c.has(xe)){T(U,c.get(xe));return}c.set(xe,void 0),T(U,void 0),e.remoteSessionLog({peer:U}).then(Ce=>{c.set(xe,Ce),(t==null?void 0:t.kind)==="peer"&&t.url===U&&t.picked===void 0&&T(U,Ce)},Ce=>{const Se={ok:!1,error:Ce instanceof Error?Ce.message:String(Ce)};c.set(xe,Se),(t==null?void 0:t.kind)==="peer"&&t.url===U&&t.picked===void 0&&T(U,Se)});return}const F=G(O);if(F===void 0){p.replaceChildren(),qe(!0);return}const ue=()=>{const U=i.get(F);U===void 0||l?w():(f.scrollTop=U,requestAnimationFrame(()=>{t!==null&&G(t)===F&&(f.scrollTop=U)}))};if(!l&&r.has(F)&&r.get(F)!==void 0){I(r.get(F)),qe(!0),ue();return}l&&i.delete(F),r.set(F,void 0),I(void 0),qe(!0),Ee(O).then(U=>{var xe;r.set(F,U),(U==null?void 0:U.ok)===!0&&U.messages!==void 0&&((xe=e.onTranscript)==null||xe.call(e,O,U.messages)),!(t===null||G(t)!==F)&&(I(U),qe(),ue())},U=>{const xe={ok:!1,error:U instanceof Error?U.message:String(U)};r.set(F,xe),t!==null&&G(t)===F&&I(xe)})}function q(l){return((n==null?void 0:n.tasks)??[]).filter(O=>O.team===l)}function K(l){return((n==null?void 0:n.tasksDead)??[]).filter(O=>O.team===l)}let Z="";function ne(l){return l.reason==="fire-forget"?{text:"已过期(免回执)",tone:"muted",hint:"免回执消息到 24h TTL 归档,属正常记账"}:{text:"死信",tone:"danger",hint:l.reason!==void 0&&l.reason!=="unspecified"?`${l.reason}:超过 24h TTL 仍未结算,需在台账清账`:"超过 24h TTL 仍未结算,需在台账清账"}}function ve(l,O){const F=l.direction==="inbound";if(l.receiptExpected===!1)return{text:F?"来信 · 无需回执":"已送达 · 无回执",tone:"muted",hint:"免回执消息:不等回执,24h 后自动归档"};const ue=Ut(l,O),U=F?ue?"待本机回执 · 超 1 小时":"待本机回执":ue?"陈旧":"待回执",xe=l.status!=="pending"?` · ${l.status}`:"";return{text:`${U}${xe}`,tone:ue?"warn":"wait",hint:`${F?"对方等待本机回执;":""}${F?"收到":"派发"}于 ${yn(l.startedAt,O)}`}}function Pe(l,O){const F=`结算于 ${yn(l.resolvedAt,O)}`;if(l.receiptExpected===!1&&l.endedBy==="abandoned")return l.late===!0?{text:"已移出(免回执) · 回执迟到",tone:"warn",hint:`${F};免回执消息本机移出后对方回执才到,结局不改写`}:{text:"已移出(免回执)",tone:"muted",hint:`${F};免回执消息,本机移出台账,不是失败`};if(l.endedBy==="abandoned"||l.endedBy==="cancelled"){const Ce=l.endedBy==="cancelled"?"撤回":"放弃";return l.late===!0?{text:`已${Ce} · 回执迟到`,tone:"warn",hint:`${F};本机${Ce}之后对方回执才到,结局不改写`}:{text:`已${Ce}`,tone:"muted",hint:`${F};本机${Ce},未等到回执`}}if(l.endedBy==="echo")return{text:"已结算 · 内容回显",tone:"ok",hint:`${F};对方回了内容但未带正式回执,按内容回显结算`};if(l.endedBy===void 0&&l.outcome==="abandoned")return{text:"已放弃(本机或对方)",tone:"muted",hint:`${F};本机放弃或撤回,或对方回执报告放弃`};const ue=l.summary!==void 0&&l.summary!==""?` · ${l.summary}`:"";if(l.outcome==="abandoned")return{text:"已回执 · 对方放弃",tone:"warn",hint:`${F};对方回执报告放弃${ue}`};const U=Sn.find(Ce=>Ce.key===l.outcome),xe=(U==null?void 0:U.tone)==="completed"?"ok":(U==null?void 0:U.tone)==="failed"?"danger":(U==null?void 0:U.tone)==="rejected"?"warn":"muted";return l.outcome==="unclassified"?{text:"已回执",tone:"ok",hint:`${F};回执未带结论${ue}`}:{text:`已回执 · ${(U==null?void 0:U.label)??l.outcome}`,tone:xe,hint:`${F}${ue}`}}function ye(l,O,F){const ue=K(O).find(Ce=>Ce.taskId===l);if(ue!==void 0)return ne(ue);const U=q(O).find(Ce=>Ce.taskId===l);if(U!==void 0)return ve(U,F);const xe=((n==null?void 0:n.archived)??[]).find(Ce=>Ce.taskId===l&&Ce.team===O);return xe!==void 0?Pe(xe,F):u.has(l)?{text:"已离开台账",tone:"muted",hint:"已结算、放弃或撤回之一;主机未给出这条的结局(旧主机,或已超出最近 64 条归档)"}:{text:"已派发",tone:"muted",hint:"异步送达;回执到达后进台账"}}function rt(l){const O=e.now(),F=d.get(l)??[],ue=new Set(F.map(fe=>fe.taskId).filter(fe=>fe!==void 0)),U=fe=>fe!==void 0&&fe!==""?fe:"(无摘要)",xe=q(l).filter(fe=>!ue.has(fe.taskId)).map(fe=>({at:fe.startedAt,side:fe.direction==="inbound"?"theirs":"mine",text:U(fe.brief),status:ve(fe,O),taskId:fe.taskId})),Ce=K(l).filter(fe=>!ue.has(fe.taskId)).map(fe=>{var Ke;const nt=fe.direction??h.get(fe.taskId)??(((Ke=fe.peer)==null?void 0:Ke.startsWith("local:"))===!0?"inbound":void 0);return{at:fe.startedAt,side:nt==="inbound"?"theirs":nt==="outbound"?"mine":"system",text:U(fe.brief),status:ne(fe),taskId:fe.taskId}}),Se=F.map(fe=>({at:fe.at,side:"mine",text:fe.text,status:fe.state==="sending"?{text:"发送中…",tone:"muted"}:fe.state==="failed"?{text:`失败:${fe.error??"未知原因"}`,tone:"danger"}:fe.taskId!==void 0?ye(fe.taskId,l,O):{text:"已派发",tone:"muted"},taskId:fe.taskId}));return[...xe,...Ce,...Se].sort((fe,nt)=>fe.at-nt.at)}function qe(l=!1){const O=t,F=O!==null?wn(O):void 0,ue=F!==void 0?rt(F):[],U=JSON.stringify([F??"",...ue.map(Se=>[Se.taskId??"",Se.side,Se.text,Se.status.text])]);if(!l&&U===Z)return;Z=U;const xe=Ue();if(H.replaceChildren(),ue.length===0)return;const Ce=Ae("div","wb-chat-divider");Ce.textContent="台账往来 · 异步送达,回执进台账",H.appendChild(Ce);for(const Se of ue){const fe=Se.side==="mine"?"wb-msg wb-msg-user wb-msg-out":Se.side==="theirs"?"wb-msg wb-msg-assistant wb-msg-in":"wb-msg wb-msg-ledger",nt=Ae("div",fe);nt.appendChild(Ae("span","wb-msg-who")).textContent=Se.side==="mine"?"我":Se.side==="theirs"?"对方":"台账记录",nt.appendChild(Ae("div","wb-msg-text")).textContent=Se.text;const Ke=Ae("div","wb-msg-meta");Se.taskId!==void 0&&(Ke.appendChild(Ae("span","wb-msg-task")).textContent=Se.taskId);const ze=Ae("span",`wb-msg-status is-${Se.status.tone}`);ze.textContent=Se.status.text,Se.status.hint!==void 0&&(ze.title=Se.status.hint),Ke.appendChild(ze),nt.appendChild(Ke),H.appendChild(nt)}xe&&w()}function Je(l){const O=l.text.value.length;l.note.classList.remove("is-error"),l.note.textContent=O>Yt*.9?`${O}/${Yt}`:"Enter 发送 · Shift+Enter 换行",O>Yt&&l.note.classList.add("is-error"),l.submit.disabled=l.text.value.trim()===""||O>Yt}function Ge(l){l.style.height="auto",l.style.height=`${Math.min(l.scrollHeight,160)}px`}function $e(l){const O=Ae("form","wb-dispatch-form wb-chat-composer"),F=document.createElement("textarea");F.className="wb-dispatch-text",F.rows=1,F.placeholder="发一句话任务给这个节点…",F.setAttribute("aria-label","发送消息");const ue=Ae("button","wb-dispatch-submit");ue.type="submit",ue.textContent="发送",ue.setAttribute("aria-label","发送");const U=Ae("div","wb-dispatch-note");U.setAttribute("aria-live","polite");const xe=Ae("div","wb-chat-composer-row");xe.append(F,ue),O.append(xe,U);const Ce={team:l,form:O,text:F,note:U,submit:ue};return F.addEventListener("input",()=>{Ge(F),Je(Ce)}),F.addEventListener("keydown",Se=>{Se.key!=="Enter"||Se.shiftKey||Se.ctrlKey||Se.altKey||Se.metaKey||Se.isComposing||(Se.preventDefault(),O.requestSubmit())}),O.addEventListener("submit",Se=>{Se.preventDefault();const fe=F.value.trim();if(fe===""||fe.length>Yt||e.dispatchQuick===void 0)return;const nt={text:fe,at:e.now(),state:"sending"},Ke=d.get(l)??[];Ke.push(nt),d.set(l,Ke),F.value="",Ge(F),Je(Ce),F.focus({preventScroll:!0}),qe(),w(),e.dispatchQuick(l,fe).then(ze=>ze,ze=>({ok:!1,error:ze instanceof Error?ze.message:String(ze)})).then(ze=>{ze.ok===!0?(nt.state="sent",nt.taskId=ze.task_id,U.classList.remove("is-error"),U.textContent=`已派发${ze.task_id!==void 0?` · ${ze.task_id}`:""} · 回执将入台账`):(nt.state="failed",nt.error=ze.error??"未知原因",F.value===""&&(F.value=fe,Ge(F)),U.classList.add("is-error"),U.textContent=`失败:${nt.error}`,ue.disabled=F.value.trim()===""),t!==null&&wn(t)===l&&qe()})}),Je(Ce),Ce}function Fe(){const l=t;if(z.replaceChildren(),l===null)return;const O=wn(l);if(O!==void 0&&e.dispatchQuick!==void 0){let ue=m.get(O);ue===void 0&&(ue=$e(O),m.set(O,ue)),z.appendChild(ue.form),s&&(s=!1,ue.text.focus({preventScroll:!0}));return}s=!1;const F=Ae("div","wb-chat-readonly");F.textContent=l.kind==="log"?"只读日志:此会话不在网络目录,不能从这里派发。":l.kind==="peer"?"对端主机:选择会话阅读;要派发请打开它的远端会话节点。":"此节点没有可派发的路由。",z.appendChild(F)}function Re(){Le(),se(),W(),Fe()}function gt(l){const O=t!==null&&qn(t)===qn(l);t=l,O||(s=!0),Re(),$.classList.add("is-open")}function Et(){t=null,$.classList.remove("is-open")}function mt(l){n=l;for(const F of(l==null?void 0:l.tasks)??[])u.add(F.taskId),h.set(F.taskId,F.direction==="inbound"?"inbound":"outbound");const O=t;if(O!==null){if(O.kind==="session"&&l!==null){const F=(l.sessions??[]).find(ue=>ue.id===O.id);F!==void 0&&(O.title=xt(F),O.live=F.live)}Le(),qe()}}return{root:$,open:gt,close:Et,isOpen:()=>t!==null,update:mt}}function Qo(e,t,n){const s=document.createElement("section"),o=document.createElement("h4");o.textContent="会话席位名(仅人工设定)",s.appendChild(o);const r=document.createElement("p");r.className="wb-hint",r.textContent="稳定展示名,不改变会话标题、路由句柄或准入。留空并保存可清除。",s.appendChild(r);const i=document.createElement("select");i.setAttribute("aria-label","选择命名的本机会话");for(const N of new Set([...e.map(te=>te.id),...Object.keys(t)])){const te=e.find(ie=>ie.id===N),le=document.createElement("option");le.value=N,le.textContent=(t[N]??(te==null?void 0:te.name)??(te==null?void 0:te.label)??N)+" · "+N,i.appendChild(le)}const c=document.createElement("input");c.type="text",c.maxLength=64,c.setAttribute("aria-label","人工席位名"),c.placeholder="例如:开发席";const d=document.createElement("button");d.type="submit",d.textContent="保存席位名",d.className="wb-member-submit";const u=document.createElement("form");u.className="wb-member-add",u.append(i,c,d);const h=document.createElement("p");h.className="wb-hint",h.setAttribute("role","status"),h.setAttribute("aria-live","polite");let m=!1;const $=()=>{c.value=t[i.value]??"",d.disabled=m||i.value===""};return i.addEventListener("change",$),$(),u.addEventListener("submit",async N=>{if(N.preventDefault(),m||i.value==="")return;const te=i.value,le=c.value.trim(),ie={...t};le===""?delete ie[te]:ie[te]=le,m=!0,d.disabled=!0,i.disabled=!0,c.disabled=!0;try{const S=await n(ie);S.ok?(delete t[te],le!==""&&(t[te]=le),h.textContent="席位名已保存;目录将随状态刷新。"):h.textContent=S.error??"保存失败"}catch(S){h.textContent="保存失败:"+String(S)}finally{m=!1,i.disabled=!1,c.disabled=!1,$()}}),s.append(u,h),s}function Zo(e,t){const n=document.createElement("form");n.className="wb-cli-home";const s=document.createElement("button");s.type="button",s.textContent="指定 home",s.className="wb-member-submit";const o=document.createElement("select");o.className="wb-member-pick",o.setAttribute("aria-label","选择 CLI home 主机"),o.hidden=!0;const r=document.createElement("button");r.type="submit",r.textContent="确认 home",r.className="wb-member-submit",r.hidden=!0,r.disabled=!0;const i=document.createElement("div");i.className="wb-hint",i.setAttribute("role","status"),i.setAttribute("aria-live","polite"),i.textContent="home 未确定;点击指定 home 现读已链接主机名片。";let c=!1;return s.addEventListener("click",async()=>{var d;if(!c){c=!0,s.disabled=!0,r.disabled=!0,i.textContent="正在现读主机名片…";try{const u=await e();if(!u.ok)throw Error(u.error??"候选读取失败");if(u.held){s.hidden=!0,o.hidden=!0,r.hidden=!0,o.replaceChildren(),i.textContent="本机持有,无需指定";return}o.replaceChildren(new Option("请选择 home 主机…","",!0,!0));for(const m of u.homes??[])o.appendChild(new Option(m,m));o.hidden=!1,r.hidden=!1,s.textContent="刷新候选";const h=((d=u.homes)==null?void 0:d.length)??0;i.textContent=(u.unreadable?"有 "+u.unreadable+" 台对端名片读不到;":"")+(h>1?"多台已链接主机列出该句柄,请显式选择。":h===1?"找到 1 台已链接主机;仍需你显式确认。":"当前没有已链接且列出该句柄的可选主机。")}catch(u){i.textContent="读取失败:"+String(u),o.hidden=!0,r.hidden=!0}finally{c=!1,s.disabled=!1}}}),o.addEventListener("change",()=>{r.disabled=c||o.value===""}),n.addEventListener("submit",async d=>{if(d.preventDefault(),!(c||o.value==="")){c=!0,s.disabled=!0,o.disabled=!0,r.disabled=!0;try{i.textContent=await t(o.value)?"home 已指定:"+o.value:"指定失败:主机可能已离线或不再列出该句柄,请刷新后重选。"}catch(u){i.textContent="指定失败:"+String(u)}finally{c=!1,s.disabled=!1,o.disabled=!1,r.disabled=o.value===""}}}),n.append(s,o,r,i),n}function es(e,t){const n=document.createElement("form");n.className="wb-member-provenance";const s=document.createElement("select");s.setAttribute("aria-label","确认成员来源"),s.appendChild(new Option("明确选择来源…","")),e.forEach((i,c)=>s.appendChild(new Option(i.label,String(c))));const o=document.createElement("button");o.type="submit",o.textContent="确认来源";const r=document.createElement("span");return r.textContent="确认不等于恢复;已暂停槽位仍保持暂停",n.append(s,o,r),n.addEventListener("submit",async i=>{if(i.preventDefault(),s.value==="")return;const c=e[Number(s.value)];if(!c)return;o.disabled=!0;const d=await t(c);d.ok?r.textContent="来源已确认;等待状态刷新(暂停状态不变)":(o.disabled=!1,r.textContent=d.error??"来源无法验证,原槽位保留")}),n}const Co="dsh-a2a.rail.tab";function ts(){try{return window.localStorage.getItem(Co)}catch{return null}}function ns(e){try{window.localStorage.setItem(Co,e)}catch{}}function os(e,t={}){var ie;const n=document.createElement("aside");n.className="wb-rail";const s=document.createElement("div");s.className="wb-tabs",s.setAttribute("role","tablist"),s.setAttribute("aria-label","工作台侧栏");const o=document.createElement("div");o.className="wb-tabpanels",n.append(s,o);const r=new Map,i=new Map,c=new Map,d=new Set;for(const S of e){const E=document.createElement("button");E.type="button",E.className="wb-tab",E.id=`wb-tab-${S.key}`,E.dataset.sec=S.key,E.setAttribute("role","tab"),E.setAttribute("aria-controls",`wb-panel-${S.key}`);const L=document.createElement("span");L.className="wb-tab-label",L.textContent=S.label;const C=document.createElement("span");C.className="wb-tab-badge",E.append(L,C),E.addEventListener("click",()=>N(S.key)),s.appendChild(E);const ce=document.createElement("section");ce.className="wb-tabpanel",ce.id=`wb-panel-${S.key}`,ce.dataset.sec=S.key,ce.setAttribute("role","tabpanel"),ce.setAttribute("aria-labelledby",E.id),ce.tabIndex=-1,o.appendChild(ce),r.set(S.key,E),i.set(S.key,ce),c.set(S.key,C)}const u=()=>e.map(S=>S.key).filter(S=>!d.has(S)),h=ts();let m=((ie=e.find(S=>S.key===h))==null?void 0:ie.key)??e[0].key;s.addEventListener("keydown",S=>{const E=u(),L=E.indexOf(m);let C;S.key==="ArrowRight"?C=E[(L+1)%E.length]:S.key==="ArrowLeft"?C=E[(L-1+E.length)%E.length]:S.key==="Home"?C=E[0]:S.key==="End"&&(C=E[E.length-1]),C!==void 0&&(S.preventDefault(),N(C,{focus:!0}))});function $(){for(const S of e){const E=S.key===m,L=r.get(S.key);L.setAttribute("aria-selected",String(E)),L.tabIndex=E?0:-1,L.classList.toggle("is-active",E),L.hidden=d.has(S.key),i.get(S.key).hidden=!E}}function N(S,E={}){var C;if(d.has(S))return;const L=S!==m;m=S,ns(S),$(),E.focus===!0&&r.get(S).focus(),L&&((C=t.onChange)==null||C.call(t,S))}function te(S,E,L){const C=c.get(S);C.textContent=E,C.className=`wb-tab-badge${L!==void 0?` is-${L}`:""}`}function le(S,E){E?d.add(S):d.delete(S),d.has(m)&&(m=u()[0]??e[0].key),$()}return $(),{root:n,panel:S=>i.get(S),select:N,selected:()=>m,setBadge:te,setHidden:le}}const ss=[{key:"person",label:"待你处理"},{key:"request",label:"提需求"},{key:"tickets",label:"工单"},{key:"team",label:"团队"},{key:"settings",label:"设置"}],rs={answer:"待你回答",review:"待你查看结果",blocked:"受阻",failed:"失败",delivery:"投递失败"};function is(e){if(e.ended!==void 0)return`已结束 · ${e.ended.outcome}`;const t=e.stage;return t===null?"已结束":t.stage==="person"?rs[t.action??""]??"待你处理":t.stage==="working"?t.action==="queued"?"排队等成员":"进行中":t.stage==="idle"?"等待中":t.stage}function Kn(e,t){const n=[];e.error!==void 0&&n.push({tone:"danger",text:`团队记录读不出来,写入已停止:${e.error}`}),e.settings.canvas===void 0?n.push({tone:"danger",text:"团队还没有绑定画布团队:先在画布上建队(总工 + 成员),再到「设置」里绑定"}):e.canvasProblem!==void 0&&n.push({tone:"danger",text:`画布团队「${e.settings.canvas}」不能作为团队运行:${e.canvasProblem}`}),e.servesProblem!==void 0&&n.push({tone:"danger",text:`本机为别的团队服务的会话不能接活:${e.servesProblem}`}),e.settings.router===void 0&&n.push({tone:"danger",text:"还没有指定总工:需求会停在候选里,没人决定(到「设置」里选)"}),e.settings.members.length===0&&e.settings.remoteMembers.length===0&&n.push({tone:"warn",text:"成员池是空的:在画布团队里加成员,接下的工单才有人做"}),e.settings.paused&&n.push({tone:"warn",text:"执行已暂停:新工单不会派给成员"}),e.pullRequestProblem!==void 0&&n.push({tone:"warn",text:`读取 PR 状态失败,稍后重试:${e.pullRequestProblem}`});for(const[s,o]of Object.entries(e.a2a.health))o.state==="error"&&n.push({tone:"danger",text:`A2A Source(${s})出错:${o.detail??""}`});for(const s of e.threads){s.evaluating!==null&&Date.parse(s.evaluating.deadline)<t&&n.push({tone:"warn",text:`「${cs(s)}」等总工决定已超时`});for(const o of s.replies)o.status==="dropped"&&n.push({tone:"warn",text:`回复没能送达:${o.reason??o.message.text}`})}return n}function xn(e){return e.tickets.filter(t=>{var n;return t.ended===void 0&&((n=t.stage)==null?void 0:n.stage)==="person"}).sort((t,n)=>t.updatedAt.localeCompare(n.updatedAt))}function as(e){var t;return(t=e.channels.find(n=>n.source==="workbench"))==null?void 0:t.thread}function cs(e){var n;const t=((n=e.triggers[0])==null?void 0:n.text)??e.ref.id;return t.length>40?`${t.slice(0,40)}…`:t}function ds(e){for(let t=e.assignments.length-1;t>=0;t--){const n=e.assignments[t].report;if(n!==void 0)return n}}function ae(e,t,n){const s=document.createElement(e);return t!==void 0&&(s.className=t),n!==void 0&&(s.textContent=n),s}function He(e,t,n){const s=ae("div","wb-kv");s.append(ae("span","wb-kv-k",t),ae("span","wb-kv-v",n)),e.appendChild(s)}function Xn(e){return e.length>16?`${e.slice(0,12)}…`:e}function Qt(e,t){const n=Math.max(0,Math.round((t-Date.parse(e))/1e3));if(!Number.isFinite(n))return e;if(n<90)return`${n}s 前`;const s=Math.round(n/60);if(s<90)return`${s}m 前`;const o=Math.round(s/60);return o<48?`${o}h 前`:`${Math.round(o/24)}d 前`}function ls(e){const t=ae("section","wb-pane wb-sa"),n=ae("div","wb-filters wb-sa-nav");n.setAttribute("role","tablist"),n.setAttribute("aria-label","团队视图");const s=ae("div","wb-sa-body"),o=ae("div","wb-sa-note");o.setAttribute("role","status"),t.append(ae("div","wb-pane-head","superagent 团队"),n,o,s);let r="person",i,c=[],d=Date.now(),u="",h=0,m=!1;const $=new Map;for(const w of ss){const A=ae("button","wb-filter",w.label);A.type="button",A.setAttribute("role","tab"),A.dataset.view=w.key,A.addEventListener("click",()=>{R(w.key)}),$.set(w.key,A),n.appendChild(A)}const N=ae("textarea","wb-sa-input");N.rows=3,N.placeholder="向团队提一个需求:说清楚要什么、范围多大",N.setAttribute("aria-label","需求内容");const te=ae("button","wb-btn wb-btn-primary","提交需求");te.type="button",te.addEventListener("click",()=>{C({action:"request",text:N.value},()=>{N.value=""},"需求已提交,等总工决定")});const le=new Map,ie=(w,A)=>{let oe=le.get(w);return oe===void 0&&(oe=ae("textarea","wb-sa-input"),oe.rows=2,le.set(w,oe)),oe.placeholder=A,oe};let S,E=!1;function L(w,A){o.textContent=w,o.classList.toggle("is-danger",A==="danger")}async function C(w,A,oe="已提交"){try{const I=await e.act(w);if(I.ok===!0)return A==null||A(),L(oe),e.refresh(),!0;L(`没有成功:${String(I.error??I.code??"未知原因")}`,"danger")}catch(I){L(`没有成功:${String(I)}`,"danger")}return!1}function ce(w){const A=c.find(oe=>oe.id===w);return(A==null?void 0:A.name)!==void 0&&A.name!==""?`${A.name}(${w.replace(/^session-/,"").slice(0,8)})`:w}function x(w,A={}){var K,Z,ne,ve,Pe;const oe=((K=w.stage)==null?void 0:K.stage)==="person",I=ae("div",`wb-led-card wb-sa-ticket${oe?" is-warn":""}${w.ended!==void 0?" is-muted":""}`);I.dataset.ticket=w.id;const T=ae("div","wb-sa-ticket-head");T.append(ae("strong","wb-sa-title",w.title),ae("span","wb-sa-stage",is(w))),I.appendChild(T),He(I,"范围",w.mandate.scope),He(I,"授权",`${w.mandate.strength==="explicit"?"明确请求":"推断"} · ${w.mandate.actor.source}:${w.mandate.actor.id}`);const W=i==null?void 0:i.executor.bindings.find(ye=>ye.ticketId===w.id);W!==void 0&&He(I,"成员",ce(W.member));for(const ye of w.follows??[])ye.thread.startsWith("github:")&&He(I,"PR",`${ye.thread.slice(7)}${ye.closed!==void 0?` · ${ye.closed.outcome==="merged"?"已合并":"已关闭"}`:" · 等待合并"}`);for(const ye of(i==null?void 0:i.reviews)??[])ye.ticketId===w.id&&He(I,"评审",`${ye.head.slice(0,7)} · ${ye.verdict===void 0?"等待评审":ye.verdict.pass?"PASS":"未通过"}`);w.attention!==void 0&&He(I,"问题",w.attention.question),w.delivery!==void 0&&He(I,"投递",w.delivery.error);const q=ds(w);if(q!==void 0&&He(I,"报告",`${us[q.state]??q.state} · ${q.summary}`),((Z=w.ended)==null?void 0:Z.reason)!==void 0&&He(I,"结束",w.ended.reason),He(I,"更新",`${Qt(w.updatedAt,d)} · ${w.id}`),w.ended===void 0){const ye=ae("div","wb-sa-actions"),rt=as(w);if(A.answer===!0&&((ne=w.stage)==null?void 0:ne.action)==="answer")if(rt!==void 0){const Ge=ie(rt,"回答这个问题(会作为这条需求的后续消息送给成员)"),$e=ae("button","wb-btn wb-btn-primary","回答");$e.type="button",$e.addEventListener("click",()=>{C({action:"request",text:Ge.value,thread:rt},()=>{Ge.value=""},"回答已送出")}),I.appendChild(Ge),ye.appendChild($e)}else{const Ge=ie(`ticket:${w.id}`,"回答这个问题(请求方是 agent,由你来答,答复会送给成员)"),$e=ae("button","wb-btn wb-btn-primary","回答");$e.type="button",$e.addEventListener("click",()=>{C({action:"answer",ticket_id:w.id,text:Ge.value},()=>{Ge.value=""},"回答已送出")}),I.appendChild(Ge),ye.appendChild($e)}if(w.delivery!==void 0||oe&&(((ve=w.stage)==null?void 0:ve.action)==="blocked"||((Pe=w.stage)==null?void 0:Pe.action)==="failed")){const Ge=ae("button","wb-btn","重试");Ge.type="button",Ge.addEventListener("click",()=>{C({action:"retry",ticket_id:w.id},void 0,"已重试")}),ye.appendChild(Ge)}const Je=ae("button","wb-btn","停止");Je.type="button",Je.addEventListener("click",()=>{typeof window.confirm=="function"&&!window.confirm(`停止工单「${w.title}」?成员会被告知不再做它。`)||C({action:"stop",ticket_id:w.id,reason:"属主在工作台停止"},void 0,"已停止")}),ye.appendChild(Je),I.appendChild(ye)}return I}function f(w,A,oe,I){const T=ae("div",`wb-led-group ${A}`.trim()),W=ae("div","wb-led-group-head");return W.append(ae("span",void 0,w),ae("span","wb-led-group-hint",String(oe.length))),T.appendChild(W),oe.length===0&&I!==void 0&&T.appendChild(ae("div","wb-sa-hint",I)),T.append(...oe),T}function M(w){const A=Kn(w,d).map(oe=>ae("div",`wb-led-card is-${oe.tone}`,oe.text));A.length>0&&s.appendChild(f("问题","is-danger",A)),s.appendChild(f("待你处理的工单","is-warn",xn(w).map(oe=>x(oe,{answer:!0})),"没有需要你处理的工单"))}function p(w){const A=ae("div","wb-sa-form");A.append(N,te),w.settings.sources.workbench||A.appendChild(ae("div","wb-sa-hint","工作台 Source 已关闭:需求不会被受理(到「设置」里打开)")),s.appendChild(A);const I=w.threads.filter(T=>T.ref.source==="workbench").sort((T,W)=>(W.lastAt??W.createdAt).localeCompare(T.lastAt??T.createdAt)).map(T=>{const W=ae("div","wb-led-card wb-sa-thread");W.dataset.thread=T.ref.id;for(const ne of T.triggers){const ve=ae("div","wb-sa-msg");ve.append(ae("span","wb-sa-who","你"),ae("span","wb-sa-text",ne.text),ae("span","wb-sa-when",Qt(ne.at,d))),W.appendChild(ve)}for(const ne of T.decisions){const ve=typeof ne.reason=="string"?ne.reason:(ne.reason??[]).map(ye=>{var rt;return ye.text??((rt=ye.values)==null?void 0:rt.text)??ye.code??""}).filter(Boolean).join(";"),Pe=ae("div","wb-sa-decision",`总工:${ms[ne.kind]??ne.kind}${ve!==""?` · ${ve}`:""}${ne.ticketId!==void 0?` · ${ne.ticketId}`:""}`);if((ne.kind==="ignore"||ne.kind==="unavailable")&&T.evaluating===null&&(ne.triggerIds??[]).length>0){const ye=ae("button","wb-btn wb-sa-reevaluate","重新判断");ye.type="button",ye.addEventListener("click",()=>{ye.disabled=!0;for(const rt of ne.triggerIds??[])C({action:"reevaluate",trigger_id:rt},void 0,"已请总工重新判断")}),Pe.appendChild(ye)}W.appendChild(Pe)}T.evaluating!==null&&W.appendChild(ae("div","wb-sa-hint","等总工决定…"));for(const ne of T.replies){const ve=ae("div",`wb-sa-msg is-reply${ne.status==="dropped"?" is-danger":""}`);ve.append(ae("span","wb-sa-who","团队"),ae("span","wb-sa-text",ne.message.text),ae("span","wb-sa-when",ne.status==="sent"?"":ne.status)),W.appendChild(ve)}const q=ie(T.ref.id,"在这条需求下追加(补充、回答、或要求停止)"),K=ae("button","wb-btn","追加");K.type="button",K.addEventListener("click",()=>{C({action:"request",text:q.value,thread:T.ref.id},()=>{q.value=""},"已追加")});const Z=ae("div","wb-sa-actions");return Z.appendChild(K),W.append(q,Z),W});s.appendChild(f("我的需求","",I,"还没有提过需求"))}function H(w){const A=w.tickets.filter(I=>I.ended===void 0);s.appendChild(f("待你处理","is-warn",xn(w).map(I=>x(I)))),s.appendChild(f("进行中","",A.filter(I=>{var T;return((T=I.stage)==null?void 0:T.stage)!=="person"}).sort((I,T)=>T.updatedAt.localeCompare(I.updatedAt)).map(I=>x(I))));const oe=w.tickets.filter(I=>I.ended!==void 0).sort((I,T)=>{var W,q;return(((W=T.ended)==null?void 0:W.at)??"").localeCompare(((q=I.ended)==null?void 0:q.at)??"")}).slice(0,20);s.appendChild(f("已结束(最近 20)","",oe.map(I=>x(I)),"还没有结束的工单"))}function z(w){const A=w.settings,oe=ae("div","wb-led-card");He(oe,"画布团队",A.canvas??"未绑定"),He(oe,"总工",A.router===void 0?"未指定":ce(A.router)),He(oe,"接单模式",Un[A.acceptMode]??A.acceptMode),He(oe,"A2A 地址",w.a2a.address??(A.sources.a2a?"创建中…":"未开启")),He(oe,"策略版本",w.policyVersion),A.paused&&He(oe,"执行","已暂停"),s.appendChild(f("团队","",[oe]));const I=Z=>{const ne=w.executor.bindings.find(Pe=>Pe.member===Z);if(ne===void 0)return"空闲";const ve=w.tickets.find(Pe=>Pe.id===ne.ticketId);return`在做「${(ve==null?void 0:ve.title)??ne.ticketId}」 · ${Qt(ne.at,d)}`},T=(Z,ne)=>{var Pe;const ve=(Pe=A.repos)==null?void 0:Pe[Z];ve!==void 0&&He(ne,"仓库",ve)},W=A.members.map(Z=>{const ne=ae("div","wb-led-card");return He(ne,"成员",ce(Z)),T(Z,ne),He(ne,"槽位",I(Z)),ne}),q=A.remoteMembers.map(Z=>{const ne=ae("div","wb-led-card");return He(ne,"远端成员",Z.ref),T(Z.ref,ne),He(ne,"主机",Z.url),He(ne,"钉住公钥",Xn(Z.key)),He(ne,"槽位",I(Z.ref)),ne});s.appendChild(f("成员池","",[...W,...q],"没有成员"));const K=w.tickets.filter(Z=>{var ne;return Z.ended===void 0&&((ne=Z.stage)==null?void 0:ne.stage)==="working"&&Z.stage.action==="queued"});if(K.length>0&&s.appendChild(f("排队","is-warn",K.map(Z=>ae("div","wb-led-card",`${Z.title} · ${Qt(Z.createdAt,d)}`)))),A.serves!==void 0){const Z=ae("div","wb-led-card");A.serves.team!==void 0&&He(Z,"画布团队",A.serves.team),He(Z,"团队宿主",A.serves.url),He(Z,"钉住公钥",Xn(A.serves.key)),He(Z,"本机成员",A.serves.members.map(ce).join("、")||"无"),s.appendChild(f("本机为别的团队干活","",[Z]))}}function G(w){(S===void 0||!E)&&(S=Ee(w.settings,w.canvases??[])),s.appendChild(S)}function Ee(w,A){const oe=ae("div","wb-sa-form wb-sa-settings"),I=c.filter($e=>$e.joined===!0),T=()=>{E=!0},W=($e,Fe)=>{const Re=ae("label","wb-sa-field");return Re.append(ae("span","wb-kv-k",$e),Fe),Re},q=ae("select","wb-sa-select");q.setAttribute("aria-label","画布团队"),q.appendChild(new Option("(不绑定)",""));for(const $e of A)q.appendChild(new Option($e,$e,!1,$e===w.canvas));w.canvas!==void 0&&!A.includes(w.canvas)&&q.appendChild(new Option(`${w.canvas}(已不存在)`,w.canvas,!1,!0)),q.addEventListener("change",T),oe.appendChild(W("画布团队",q));const K=ae("select","wb-sa-select");K.setAttribute("aria-label","总工"),K.appendChild(new Option("(不指定)",""));for(const $e of I)K.appendChild(new Option(ce($e.id),$e.id,!1,$e.id===w.router));w.router!==void 0&&!I.some($e=>$e.id===w.router)&&K.appendChild(new Option(`${w.router}(不在线)`,w.router,!1,!0)),K.addEventListener("change",T),oe.appendChild(W("总工",K));const Z=ae("div","wb-sa-hint",w.members.length+w.remoteMembers.length===0?"(画布团队里除总工外还没有成员)":[...w.members.map(ce),...w.remoteMembers.map($e=>$e.ref)].join("、"));Z.setAttribute("aria-label","成员"),oe.appendChild(W("成员(来自画布)",Z));const ne=ae("select","wb-sa-select");ne.setAttribute("aria-label","接单模式");for(const[$e,Fe]of Object.entries(Un))ne.appendChild(new Option(Fe,$e,!1,$e===w.acceptMode));ne.addEventListener("change",T),oe.appendChild(W("接单模式",ne));const ve=($e,Fe)=>{const Re=ae("input");return Re.type="checkbox",Re.checked=Fe,Re.addEventListener("change",T),oe.appendChild(W($e,Re)),Re},Pe=ve("工作台 Source",w.sources.workbench),ye=ve("A2A Source",w.sources.a2a),rt=ve("暂停执行",w.paused),qe=ae("button","wb-btn wb-btn-primary","保存");qe.type="button",qe.addEventListener("click",()=>{const $e={canvas:q.value===""?null:q.value,router:K.value===""?null:K.value,acceptMode:ne.value,sources:{workbench:Pe.checked,a2a:ye.checked},paused:rt.checked};C({action:"settings",settings:$e},()=>{E=!1},"设置已保存")});const Je=ae("button","wb-btn","放弃修改");Je.type="button",Je.addEventListener("click",()=>{E=!1,Le()});const Ge=ae("div","wb-sa-actions");return Ge.append(qe,Je),oe.append(Ge,ae("div","wb-sa-hint","团队就是一支画布团队:在画布上建队、增删成员(含远端成员),这里只绑定画布并从中指定总工。总工用 superagent-router 预设,本机成员用 superagent-member 预设;团队里的会话不再加入别的画布。")),oe}function Le(){for(const[w,A]of $){const oe=w===r;A.classList.toggle("is-active",oe),A.setAttribute("aria-selected",String(oe))}if(s.replaceChildren(),u=be(),h=d,i===void 0){s.appendChild(ae("div","wb-sa-hint","正在读取团队状态…"));return}if(i===null){s.appendChild(ae("div","wb-sa-hint","这台主机没有运行 superagent 团队"));return}r==="person"?M(i):r==="request"?p(i):r==="tickets"?H(i):r==="team"?z(i):G(i)}function R(w){r=w,Le()}function se(w){try{return w.matches(":focus-visible")}catch{return!1}}function be(){const w=i==null?i??null:{...i,a2a:{...i.a2a,health:Object.fromEntries(Object.entries(i.a2a.health).map(([A,oe])=>[A,{state:oe.state,detail:oe.detail}]))}};return JSON.stringify([r,w,c])}function Ue(w,A,oe){i=w,c=A,d=oe;const I=document.activeElement,T=I instanceof HTMLElement&&t.contains(I)&&(I.tagName==="TEXTAREA"||I.tagName==="SELECT"||I.tagName==="INPUT"),W=I instanceof HTMLElement&&s.contains(I)&&se(I),q=m||T||W;if((be()!==u||oe-h>=6e4)&&!q&&Le(),w===null)return{badge:""};const Z=xn(w).length,ne=Kn(w,oe);return ne.some(ve=>ve.tone==="danger")?{badge:String(Z+ne.length),tone:"danger"}:Z+ne.length>0?{badge:String(Z+ne.length),tone:"warn"}:{badge:""}}t.addEventListener("pointerdown",()=>{m=!0});for(const w of["pointerup","pointercancel"])document.addEventListener(w,()=>{m=!1});return Le(),{root:t,update:Ue,select:R}}const us={progress:"进展",waiting:"等待",ready:"已就绪",blocked:"受阻",failed:"失败",dropped:"无需做"},ms={accept:"接单",attach:"并入工单",stop:"停止",ignore:"不接",reopen:"重开",unavailable:"暂时无法判断"},Un={off:"关(只接明确请求)",observe:"观察(推断的只记录)",auto:"自动(按规则接推断的)"},Mn="application/x-dsh-session";function fs(e,t){e.draggable=!0,e.classList.add("is-draggable"),e.title=`${e.title===""?t:e.title} · 可拖入画布队`,e.addEventListener("dragstart",n=>{n.dataTransfer!==null&&(n.dataTransfer.setData(Mn,t),n.dataTransfer.effectAllowed="copy")})}function ps(e,t){const n=o=>o.dataTransfer!==null&&[...o.dataTransfer.types].includes(Mn),s=o=>{for(const[r,i]of t.frames())i.classList.toggle("drop-target",r===o)};e.addEventListener("dragover",o=>{if(!n(o))return;const r=t.frameAt(o.clientX,o.clientY);s(r),r!==void 0&&(o.preventDefault(),o.dataTransfer.dropEffect="copy")},t.signal),e.addEventListener("dragleave",o=>{n(o)&&(o.relatedTarget===null||!e.contains(o.relatedTarget))&&s(void 0)},t.signal),e.ownerDocument.addEventListener("dragend",()=>s(void 0),t.signal),e.addEventListener("drop",o=>{if(!n(o))return;s(void 0);const r=t.frameAt(o.clientX,o.clientY),i=o.dataTransfer.getData(Mn);r===void 0||i===""||(o.preventDefault(),t.drop(r,i))},t.signal)}const hs=[{key:"all",label:"全部",hint:"不过滤:目录全部条目"},{key:"local",label:"本机",hint:"本机会话节点(现场 + 冷启动)"},{key:"canvas",label:"队",hint:"画布队(人类手工分配的组队)"},{key:"remote",label:"远端",hint:"远端会话队(来自对端卡片)"},{key:"logs",label:"日志",hint:"本机日志:不在网络目录里的会话档案"}];function lt(e,t){const n=document.createElement(e);return t!==void 0&&(n.className=t),n}function Zt(...e){const t=[];for(const n of e)n!==void 0&&(typeof n=="string"?t.push(n):t.push(...n));return t.join(" ").toLowerCase()}function bs(e,t){const n=Math.max(0,Math.round((t-e)/1e3));if(n<60)return"刚刚";const s=Math.round(n/60);if(s<60)return`${s} 分钟前`;const o=Math.round(s/60);return o<48?`${o} 小时前`:`${Math.round(o/24)} 天前`}function Jn(e){return e>=1e6?`${(e/1e6).toFixed(1)} MB`:e>=1e3?`${Math.round(e/1e3)} KB`:`${e} B`}function gs(e,t){const n=new Date(t);n.setHours(0,0,0,0);const s=n.getTime();return e>=s?"今天":e>=s-864e5?"昨天":"更早"}function vs(e,t){var L,C,ce;e.replaceChildren();const{state:n,search:s,filter:o}=t,r=s!==""||o!=="all",i=(x,f)=>(o==="all"||o===x)&&(s===""||f.includes(s)),c=(x,f,M)=>{const p=lt("div","wb-dir-group"),H=lt("div","wb-dir-head");return H.appendChild(lt("span","wb-dir-head-label")).textContent=`${x} · ${f}`,M!==void 0&&(H.appendChild(lt("span","wb-dir-head-note")).textContent=M),p.appendChild(H),e.appendChild(p),p},d=(x,f,M,p,H,z,G)=>{const Ee=lt("button","wb-item");Ee.type="button",Ee.appendChild(lt("span",`wb-dot ${f}`)).textContent=M;const Le=lt("span","wb-item-text");return Le.appendChild(lt("span","wb-item-label")).textContent=p,H!==""&&(Le.appendChild(lt("span","wb-item-sub")).textContent=H),Ee.appendChild(Le),G!==void 0&&(Ee.title=G),Ee.addEventListener("click",z),x.appendChild(Ee),Ee},u=(x,f)=>{if(f===void 0||f.length===0)return;const M=lt("span","wb-item-badge"),p=f.map(H=>H.slice(H.lastIndexOf("/")+1));M.textContent=`▤ ${p.slice(0,2).join(" ")}${p.length>2?` +${p.length-2}`:""}`,M.title=`画布队:${f.join(" · ")}`,x.appendChild(M)},h=(n.sessions??[]).filter(x=>i("local",Zt(xt(x),x.team,x.label,x.id,x.canvasTeams))),m=h.filter(x=>x.live===!0),$=h.filter(x=>x.live!==!0);if(h.length>0){const x=c("本机会话",h.length,$.length>0?`${m.length} 在线 · ${$.length} 冷`:void 0);for(const f of[...m,...$]){const M=f.live===!0,p=f.nodePromptMissing===!0,H=d(x,M?"wb-dot-live":"wb-dot-cold",M?"●":"○",xt(f),M?f.team:`冷 · ${f.team}`,()=>t.openChat({kind:"session",id:f.id,title:xt(f),sub:f.team,team:f.team,live:f.live}),f.id);if(p){H.classList.add("is-node-prompt-missing");const z=lt("span","wb-node-warning");z.textContent="本会话的组装不含节点段",(L=H.querySelector(".wb-item-text"))==null||L.appendChild(z)}u(H,f.canvasTeams),fs(H,f.id)}}const N=(((C=n.canvas)==null?void 0:C.teams)??[]).filter(x=>i("canvas",Zt(x.name,x.team,x.members.map(f=>f.team??f.id))));if(N.length>0){const x=c("画布队",N.length);for(const f of N){const M=f.members.filter(p=>p.remote===!0).length;d(x,"wb-dot-canvas","▤",f.name,`${f.members.length} 成员${M>0?` · ${M} 远端`:""}`,()=>t.selectCanvas(f),f.team)}}const te=(n.remote??[]).filter(x=>i("remote",Zt(xt(x),x.team,x.origin,x.workspace,x.canvasTeams)));if(te.length>0){const x=c("远端节点",te.length);for(const f of te){const M=d(x,"wb-dot-remote","◇",xt(f),f.origin!==void 0&&f.origin!==""?f.origin:f.team,()=>t.openChat({kind:"remote",team:f.team,title:xt(f),sub:f.team,row:f}),f.team);if(f.unreachable===!0){M.classList.add("is-unreachable");const p=lt("span","wb-unreachable-note");p.textContent="对端未应答(显示的是最后已知状态)",(ce=M.querySelector(".wb-item-text"))==null||ce.appendChild(p)}u(M,f.canvasTeams)}}const le=new Set((n.sessions??[]).map(x=>x.id)),ie=t.logs.filter(x=>!le.has(x.id)&&i("logs",Zt(x.id,t.titles.get(x.id))));if(ie.length>0){const x=t.logTotal!==void 0&&t.logTotal>t.logs.length,f=c("本机日志",ie.length,x?`显示 ${t.logs.length} / 共 ${t.logTotal}`:void 0);let M="";for(const p of[...ie].sort((H,z)=>z.mtimeMs-H.mtimeMs)){const H=gs(p.mtimeMs,t.now);H!==M&&(M=H,f.appendChild(lt("div","wb-dir-day")).textContent=H);const z=t.titles.get(p.id),G=d(f,"wb-dot-log","❐",z??`会话 …${p.id.slice(-12)}`,`${bs(p.mtimeMs,t.now)} · ${Jn(p.sizeBytes)}`,()=>t.openChat({kind:"log",id:p.id,title:z??`…${p.id.slice(-12)}`,sub:"本机日志"}),`${p.id}
|
|
3
|
+
${new Date(p.mtimeMs).toLocaleString()} · ${Jn(p.sizeBytes)}`);z===void 0&&G.classList.add("is-untitled")}}h.length+N.length+te.length+ie.length===0&&(e.appendChild(lt("div","wb-dir-empty")).textContent=r?"无匹配条目":"目录为空");const S=n.sessions??[];return`${S.filter(x=>x.live===!0).length}/${S.length}`}const ko="dsh-a2a.logtitles",ys=300,zn=60;function ws(){try{const e=window.localStorage.getItem(ko),t=e===null?null:JSON.parse(e);if(t!==null&&typeof t=="object")return new Map(Object.entries(t).filter(n=>typeof n[1]=="string"))}catch{}return new Map}function xs(e,t,n){const s=n.find(i=>i.role==="user"&&i.text.trim()!=="")??n.find(i=>i.text.trim()!=="");if(s===void 0)return!1;const o=s.text.trim().split(`
|
|
4
|
+
`)[0].trim(),r=o.length>zn?`${o.slice(0,zn-1)}…`:o;if(e.get(t)===r)return!1;for(e.delete(t),e.set(t,r);e.size>ys;)e.delete(e.keys().next().value);try{window.localStorage.setItem(ko,JSON.stringify(Object.fromEntries(e)))}catch{}return!0}function ht(e){return e.name??e.team??e.label??""}function Wt(e,t){const n=Math.max(0,Math.round((t-e)/1e3));if(n<90)return`${n}s`;const s=Math.round(n/60);if(s<90)return`${s}m`;const o=Math.round(s/60);return o<48?`${o}h`:`${Math.round(o/24)}d`}function _(e,t){const n=document.createElement(e);return t!==void 0&&(n.className=t),n}function Vn(e,t,n){const s=_("div","wb-kv");s.appendChild(_("span","wb-kv-k")).textContent=t,s.appendChild(_("span","wb-kv-v")).textContent=n,e.appendChild(s)}function Cs(e){try{return new URL(e).host}catch{return e}}const ks=[{key:"directory",label:"目录"},{key:"hosts",label:"主机"},{key:"ledger",label:"台账"},{key:"activity",label:"活动"},{key:"plan",label:"规划"},{key:"team",label:"团队"}];function Es(e){const t=e.board;let n="data",s,o=null,r="",i="all",c=null;const d=new Map,u=new Map;let h=null,m=[],$;const N=ws();let te=!1;const le=_("div","wb");le.setAttribute("data-testid","wb-root");const ie=_("header","wb-header"),S=_("button","wb-icon-btn wb-menu");S.type="button",S.dataset.testid="wb-menu",S.setAttribute("aria-label","打开目录抽屉"),S.textContent="☰",S.addEventListener("click",()=>le.classList.toggle("is-rail-open")),ie.appendChild(S);const E=_("div","wb-title");E.appendChild(_("span","wb-title-main")).textContent="A2A 工作台";const L=_("span","wb-badge");E.appendChild(L),ie.appendChild(E);const C=_("button","wb-icon-btn wb-owner-btn");C.type="button",C.dataset.testid="wb-owner-btn",C.setAttribute("aria-label","主人设置"),C.title="主人设置:席位名 / 入网白名单 / 可见性 / 发布",C.textContent="⚙",C.addEventListener("click",()=>{U=!U,Ce()}),ie.appendChild(C);const ce=_("div","wb-header-stats");ie.appendChild(ce);const x=_("button","wb-icon-btn wb-rail-toggle");x.type="button",x.dataset.testid="wb-rail-toggle",x.setAttribute("aria-label","折叠/展开侧栏"),x.textContent="◧",x.addEventListener("click",()=>{le.classList.toggle("is-rail-collapsed"),n==="canvas"&&t!==void 0&&t.activate()}),ie.appendChild(x);const f=_("div","wb-body"),M=os(ks),p=M.root,H=_("div","wb-directory"),z=_("div","wb-dir-tools"),G=document.createElement("input");G.className="wb-search",G.type="search",G.placeholder="搜索:名称 / 队 / 会话 / 节点",G.setAttribute("aria-label","统一搜索目录"),G.addEventListener("input",()=>{r=G.value.trim().toLowerCase(),qe()}),z.appendChild(G);const Ee=_("div","wb-filters");for(const k of hs){const g=_("button","wb-filter");g.type="button",g.textContent=k.label,g.dataset.filter=k.key,g.title=k.hint,g.addEventListener("click",()=>{i=k.key,qe()}),Ee.appendChild(g)}z.appendChild(Ee),M.panel("directory").appendChild(z),M.panel("directory").appendChild(H);const Le=_("section","wb-pane"),R=_("section","wb-pane"),se=_("section","wb-pane"),be=_("section","wb-pane"),Ue=e.superagent===void 0?void 0:ls(e.superagent);let w=!1;const A=[["ledger",Le],["activity",R],["plan",se],["hosts",be],...Ue!==void 0?[["team",Ue.root]]:[]];M.setHidden("team",!0);const oe=_("main","wb-stage"),I=_("section","wb-stage-board");t!==void 0&&(I.appendChild(t.root),oe.appendChild(I));const T=_("div","wb-data"),W=_("aside","wb-inspector"),q=_("div","wb-inspector-head");q.appendChild(_("span","wb-inspector-title")).textContent="详情";const K=_("button","wb-icon-btn");K.type="button",K.setAttribute("aria-label","关闭详情"),K.textContent="✕",K.addEventListener("click",()=>rt(void 0)),q.appendChild(K),W.appendChild(q);const Z=_("div","wb-inspector-body");W.appendChild(Z);const ne=Go({now:e.now,sessionLog:e.sessionLog,remoteSessionLog:e.remoteSessionLog,dispatchQuick:e.dispatchQuick,onTranscript:(k,g)=>{k.kind!=="log"&&k.kind!=="session"||xs(N,k.id,g)&&qe()}});oe.appendChild(T),f.appendChild(p),f.appendChild(oe),f.appendChild(W),f.appendChild(ne.root),le.appendChild(ie),le.appendChild(f);function ve(k){for(const[g,B]of A){const P=k==="canvas"?M.panel(g):T,Y=g==="team"&&!w;M.setHidden(g,k!=="canvas"||Y),B.classList.toggle("is-hidden",Y),B.parentElement!==P&&P.appendChild(B)}}function Pe(){const g=t!==void 0&&t.available()?"canvas":"data";le.dataset.mode=g,I.classList.toggle("is-hidden",g!=="canvas"),T.classList.toggle("is-hidden",g==="canvas"),ve(g),g!==n&&(t!==void 0&&(g==="canvas"?t.activate():t.deactivate()),n=g)}function ye(k){for(;k.firstChild!==null;)k.removeChild(k.firstChild);return k}function rt(k){s=k,((k==null?void 0:k.kind)!=="canvas"||(c==null?void 0:c.name)!==k.row.name)&&(c=null),(k==null?void 0:k.kind)!=="canvas"&&(h=null),fe(),le.classList.remove("is-rail-open")}function qe(){for(let g=0;g<Ee.children.length;g++){const B=Ee.children[g];B.classList.toggle("is-active",B.dataset.filter===i)}if(o===null){H.replaceChildren(_("div","wb-muted")),H.firstElementChild.textContent="载入中…",M.setBadge("directory","");return}const k=vs(H,{state:o,logs:m,logTotal:$,titles:N,search:r,filter:i,now:e.now(),openChat:ze,selectCanvas:g=>rt({kind:"canvas",row:g})});M.setBadge("directory",k)}function Je(){const k=ye(be);if(o===null){M.setBadge("hosts","");return}const g=e.now(),B=[...o.peers??[]].sort((P,Y)=>{const Q=de=>de.link==="linked"?0:1;return Q(P)-Q(Y)||(Y.score??0)-(P.score??0)});if(M.setBadge("hosts",B.length>0?`${B.filter(P=>P.link==="linked").length}/${B.length}`:""),B.length===0){k.appendChild(_("div","wb-nodelist-empty")).textContent="暂无 tracked peer——配 peers 种子或等 referral 到达";return}for(const P of B){const Y=Cs(P.url),Q=_("div","wb-host-row"),de=_("span","wb-host-lamp"),pe=P.lastContactAt,ee=pe===void 0?void 0:g-pe,Me=P.lastContactOk;ee===void 0?de.classList.add("is-unknown"):Me===!1&&ee<=5*6e4?de.classList.add("is-fail"):ee<=6e4?de.classList.add("is-live"):ee<=5*6e4?de.classList.add("is-warm"):de.classList.add("is-cold"),de.title=pe===void 0?"尚无接触记录":`最近接触 ${Wt(pe,g)}${Me===!1?"(失败)":Me===!0?"(成功)":""}`,Q.appendChild(de),Q.appendChild(_("span","wb-host-name")).textContent=P.name!==void 0&&P.name!==""?P.name:Y;const Xe=_("span",`wb-host-badge ${P.link==="linked"?"is-linked":"is-stranger"}`);Xe.textContent=`${P.link==="linked"?"linked":"stranger"} ${P.verified===!0?"✓":"✗"}`,Xe.title=P.link==="linked"?`已建立运营者链接(互种或 canvas 引用);${P.verified===!0?"验签有效":"尚未持有验签通过的卡片"}`:"无运营者关系(验签 ≠ 关系)",Q.appendChild(Xe),P.version!==void 0&&P.version!==""&&(Q.appendChild(_("span","wb-host-ver")).textContent=P.version),Q.appendChild(_("span","wb-host-url mono")).textContent=Y,Q.setAttribute("role","button"),Q.tabIndex=0,Q.title=`${P.url} · score ${String(P.score??0)}`;const Be=()=>{ze({kind:"peer",id:`peer-${Y}`,title:P.name!==void 0&&P.name!==""?P.name:Y,sub:Y,url:P.url})};Q.addEventListener("click",Be),Q.addEventListener("keydown",ct=>{(ct.key==="Enter"||ct.key===" ")&&(ct.preventDefault(),Be())}),k.appendChild(Q)}}function Ge(){if(o===null){Le.replaceChildren(),M.setBadge("ledger","");return}const k=o,g=P=>{const Y=(k.sessions??[]).find(de=>de.team===P);if(Y!==void 0)return{kind:"session",id:Y.id,title:ht(Y),sub:Y.team,team:Y.team,live:Y.live};const Q=(k.remote??[]).find(de=>de.team===P);if(Q!==void 0)return{kind:"remote",team:Q.team,title:ht(Q),sub:Q.team,row:Q}},B=Jo(Le,{state:k,now:e.now(),abandon:(P,Y)=>e.abandon(P,Y),canOpenTeam:P=>g(P)!==void 0,openTeam:P=>{const Y=g(P);return Y===void 0?!1:(ze(Y),!0)}});M.setBadge("ledger",B.badge,B.tone)}function $e(k,g,B){rn(k.appendChild(_("span","wb-row-team")),g,B)}function Fe(){var de;const k=ye(R);if(o===null)return;const g=e.now(),B=o.inFlight??[];M.setBadge("activity",B.length>0?String(B.length):"",B.length>0?"accent":void 0);const P=_("div","wb-pane-head");if(P.textContent=`在途 ${B.length} · 活动 ${((de=o.activity)==null?void 0:de.length)??0}`,k.appendChild(P),B.length>0){const pe=_("div","wb-pane-subhead");pe.textContent="在途路由",k.appendChild(pe);for(const ee of B){const Me=_("div","wb-row");Me.appendChild(_("span","wb-row-dir")).textContent="→",$e(Me,o,ee.team),Me.appendChild(_("span","wb-row-meta")).textContent=`${ee.peer} · ${Wt(ee.startedAt,g)}`,k.appendChild(Me)}}const Y=_("div","wb-pane-subhead");Y.textContent="活动环(最新在前)",k.appendChild(Y);const Q=o.activity??[];if(Q.length===0){k.appendChild(_("div","wb-muted")).textContent="暂无活动";return}for(const pe of Q){const ee=_("div","wb-row"),Me=_("span","wb-row-dir");Me.textContent=pe.dir==="fwd"?"⇢":pe.dir==="out"?"→":"←",pe.ok!==!0&&Me.classList.add("is-fail"),ee.appendChild(Me),$e(ee,o,pe.team),ee.appendChild(_("span","wb-row-meta")).textContent=`${pe.peer} · ${Wt(pe.ts,g)}`,ee.appendChild(_("span","wb-row-badges")).textContent=pe.ok===!0?"":"失败",k.appendChild(ee)}}function Re(k){var de,pe;const g=e.now(),B=[],P=Nn(k,g);P.deadLetters.length>0&&B.push({severity:"high",text:`清账 ${P.deadLetters.length} 条死信(目标早已离开或死信化,无回执可期)`});for(const ee of P.stale){const Me=ee.brief===void 0||ee.brief===""?"":`「${ee.brief}」`;B.push({severity:"normal",text:`催办 ${ee.taskId} → ${Ko(k,ee.team)}(等待 ${Wt(ee.startedAt,g)} 无回执)${Me}`,brief:`a2a_route 催收回执:task ${ee.taskId}(team ${ee.team})${Me===""?"":`原任务「${ee.brief}」`}已派发 ${Wt(ee.startedAt,g)},请回报结果或回执。`})}const Y=(k.sessions??[]).filter(ee=>ee.live!==!0).map(ee=>ht(ee));if(Y.length>0){const ee=Y.slice(0,3).join("、")+(Y.length>3?` 等 ${Y.length} 个`:"");B.push({severity:"normal",text:`冷会话 ${Y.length} 个(${ee}):在 GUI 打开即可唤醒加入面`})}for(const ee of((de=k.reconcile)==null?void 0:de.rows)??[])if(ee.needsRepair===!0){const Me=(k.sessions??[]).find(Be=>Be.id===ee.id),Xe=Me!==void 0?`${ht(Me)}(${ee.id})`:ee.id;B.push({severity:"high",text:`reconcile 需修复:${Xe} ${ee.error}`})}const Q=((pe=k.idempotency)==null?void 0:pe.conflicts)??0;return Q>0&&B.push({severity:"high",text:`幂等冲突 ${Q} 例:人工核查 UNIQUE-ization 流量`}),B}function gt(){const k=ye(se);if(o===null)return;const g=Re(o);M.setBadge("plan",g.length>0?String(g.length):"",g.some(Y=>Y.severity==="high")?"danger":void 0);const B=_("div","wb-pane-head");B.textContent=g.length===0?"网络健康——无待办行动":`待办行动 ${g.length}`,k.appendChild(B);for(const Y of g){const Q=_("div",`wb-action${Y.severity==="high"?" wb-action-high":""}`);if(Q.appendChild(_("span","wb-action-text")).textContent=Y.text,Y.brief!==void 0){const de=_("button","wb-btn");de.type="button",de.textContent="复制催办",de.addEventListener("click",()=>e.copy(Y.brief??"")),Q.appendChild(de)}k.appendChild(Q)}const P=_("div","wb-pane-subhead");P.textContent="派单起草(复制后在任一会话粘贴执行)",k.appendChild(P),k.appendChild(Et)}const Et=_("div","wb-draft"),mt=document.createElement("select");mt.className="wb-select";const l=document.createElement("textarea");l.className="wb-textarea",l.rows=3,l.placeholder="任务正文:目标、验收、期限…";const O=_("button","wb-btn wb-btn-primary");O.type="button",O.textContent="复制任务书",O.addEventListener("click",()=>{const k=mt.value,g=l.value.trim();k===""||g===""||e.copy(`a2a_route 派单 → ${k}:
|
|
5
|
+
${g}`)}),Et.appendChild(mt),Et.appendChild(l),Et.appendChild(O);function F(){var Y;const k=mt.value;ye(mt);const g=document.createElement("option");if(g.value="",g.textContent="选择目标队…",mt.appendChild(g),o===null)return;const B=o,P=new Map;for(const Q of B.sessions??[])Q.team!==void 0&&Q.team!==""&&P.set(Q.team,`${ht(Q)}(会话队)`);for(const Q of((Y=B.canvas)==null?void 0:Y.teams)??[])P.set(Q.team,`${Q.name}(canvas 队)`);for(const Q of B.remote??[])P.set(Q.team,`${ht(Q)}(远端)`);for(const[Q,de]of P){const pe=document.createElement("option");pe.value=Q,pe.textContent=`${de} · ${Q}`,mt.appendChild(pe)}k!==""&&P.has(k)&&(mt.value=k)}let ue,U=!1,xe=null;function Ce(){var k;fe(),U&&((k=e.ownerSettingsRead)==null||k.call(e).then(g=>{if(U){if(g.ok!==!0){xe=null,fe();return}ue=void 0,xe={seatNames:g.seatNames??{},teamJoinAllowlist:g.teamJoinAllowlist??[],teamScopeInfo:g.teamScopeInfo!==!1,announce:g.announce===!0,announceRestartPending:g.announceRestartPending===!0},fe()}}))}function Se(k){const g=_("div","wb-card"),B=_("div","wb-inspector-head");B.appendChild(_("span","wb-inspector-title")).textContent="主人设置";const P=_("button","wb-icon-btn");if(P.type="button",P.setAttribute("aria-label","关闭主人设置"),P.textContent="✕",P.addEventListener("click",()=>{U=!1,fe()}),B.appendChild(P),g.appendChild(B),e.ownerSettingsRead===void 0){const he=_("div","wb-hint");he.textContent="此宿主未提供主人设置面(旧版本)——升级后可用。",g.appendChild(he),k.appendChild(g);return}if(xe===null){const he=_("div","wb-hint");he.textContent="读取中…",g.appendChild(he),k.appendChild(g);return}const Y=xe;ue??(ue=Qo((o==null?void 0:o.sessions)??[],Y.seatNames,async he=>{var _e;const Ie=await((_e=e.ownerSettingsWrite)==null?void 0:_e.call(e,{seatNames:he}));return Ie!=null&&Ie.ok?(Y.seatNames=he,{ok:!0}):{ok:!1,error:(Ie==null?void 0:Ie.error)??"保存失败"}})),g.appendChild(ue);const Q=_("div","wb-side-head");Q.textContent="入网白名单(精确团队名)",g.appendChild(Q);for(const he of Y.teamJoinAllowlist){const Ie=_("div","wb-member-row");Ie.appendChild(_("span","wb-member-label")).textContent=he;const _e=_("button","wb-member-remove");_e.type="button",_e.textContent="移除",_e.addEventListener("click",()=>{var it;(it=e.ownerSettingsWrite)==null||it.call(e,{teamJoinAllowlist:Y.teamJoinAllowlist.filter(Qe=>Qe!==he)}).then(()=>Ce())}),Ie.appendChild(_e),g.appendChild(Ie)}const de=_("div","wb-member-add"),pe=_("input","wb-member-manual");pe.type="text",pe.placeholder="dsh/团队名(精确,无通配)",pe.setAttribute("aria-label","新增白名单团队名");const ee=_("button","wb-member-submit");ee.type="button",ee.textContent="加入";const Me=()=>{var Ie;const he=pe.value.trim();he===""||Y.teamJoinAllowlist.includes(he)||(Ie=e.ownerSettingsWrite)==null||Ie.call(e,{teamJoinAllowlist:[...Y.teamJoinAllowlist,he]}).then(()=>Ce())};ee.addEventListener("click",Me),pe.addEventListener("keydown",he=>{he.key==="Enter"&&Me()}),de.append(pe,ee),g.appendChild(de);const Xe=_("div","wb-side-head");Xe.textContent="目录可见性(teamScopeInfo)",g.appendChild(Xe);const Be=_("div","wb-member-row"),ct=_("button","wb-member-submit");ct.type="button",ct.textContent=Y.teamScopeInfo?"已开:仅显示已加入团队(点击放开为全舰队可见)":"已关:全舰队可见(点击收窄为已加入团队)",ct.addEventListener("click",()=>{var he;(he=e.ownerSettingsWrite)==null||he.call(e,{teamScopeInfo:!Y.teamScopeInfo}).then(()=>Ce())}),Be.appendChild(ct),g.appendChild(Be);const $t=_("div","wb-hint");$t.textContent="精度说明:teamScopeInfo 只管「目录显示范围」。关上它不会解锁任何通信准入——会话入网(S3)与目标级路由(F5)规则原样生效。",g.appendChild($t);const Nt=_("div","wb-side-head");Nt.textContent="节点发布(announce)",g.appendChild(Nt);const Mt=_("div","wb-member-row"),X=_("button","wb-member-submit");if(X.type="button",X.textContent=Y.announce?"已开:本节点发布签名卡(点击关闭)":"已关:本节点不发布(点击开启——重启宿主后生效)",X.addEventListener("click",()=>{var he;(he=e.ownerSettingsWrite)==null||he.call(e,{announce:!Y.announce}).then(()=>Ce())}),Mt.appendChild(X),g.appendChild(Mt),Y.announceRestartPending){const he=_("div","wb-hint");he.textContent="有 announce 变更待生效:重启宿主后按新配置发布。",g.appendChild(he)}k.appendChild(g)}function fe(){var P,Y,Q,de,pe;const k=ye(Z);if(U){W.classList.add("is-open"),Se(k);return}if(W.classList.toggle("is-open",s!==void 0),s===void 0)return;const g=s,B=_("div","wb-card");if(g.kind==="canvas"){const ee=(((P=o==null?void 0:o.canvas)==null?void 0:P.teams)??[]).find(X=>X.name===g.row.name)??g.row;Vn(B,"Canvas 队",ee.name),Vn(B,"路由队",ee.team);const Me=_("div","wb-side-head");if(Me.textContent=`成员 · ${ee.members.length}`,B.appendChild(Me),ee.members.length===0){const X=_("div","wb-muted");X.textContent="空队——用下方表单添加成员",B.appendChild(X)}for(const X of ee.members){const he=_("div","wb-member-row"),Ie=X.cliHeld===!0?"本机持有,无需指定":X.remote===!0?X.cliHome===null?"◇ 远端 · home 未确定":"◇ 远端":X.live===!0?"● 现场":X.joined===!0?"○ 冷启":"· 未入网";he.appendChild(_("span","wb-member-dot")).textContent=Ie+(X.provenance?" · 来源未确认"+(X.provenance==="legacy-inferred"?"(兼容推断)":""):"");const _e=_("span","wb-member-label"),it=((o==null?void 0:o.sessions)??[]).find(Te=>Te.id===X.id);_e.textContent=X.remote===!0?X.id:it!==void 0?ht(it):X.id,_e.title=X.cliHeld===!0?"本机持有,无需指定":X.cliHome!==void 0?X.cliHome??"home 未确定":X.team??X.id,he.appendChild(_e);const Qe=_("button","wb-member-remove");if(Qe.type="button",Qe.textContent="移除",Qe.addEventListener("click",async()=>{Qe.disabled=!0,await e.canvasOp("remove-member",ee.name,X.id)||(Qe.disabled=!1)}),he.appendChild(Qe),B.appendChild(he),X.cliHomeCleared===!0){const Te=_("div","wb-hint");Te.textContent="本机落户已清除旧 home 钉;户口离线后也不会恢复旧钉。",B.appendChild(Te)}if(X.cliHome===null&&X.cliHeld!==!0&&e.cliHomeOptions!==void 0){const Te=JSON.stringify([ee.name,X.id]);let St=d.get(Te);St===void 0&&(St=Zo(()=>e.cliHomeOptions(ee.name,X.id),Bt=>e.canvasOp("add-member",ee.name,X.id,Bt)),d.set(Te,St)),B.appendChild(St)}}const Xe=(((Y=o==null?void 0:o.canvas)==null?void 0:Y.retainedMembers)??[]).filter(X=>X.team===ee.name);for(const X of Xe){const he=_("div","wb-member-row");if(he.appendChild(_("span","wb-member-dot")).textContent=X.suspended?"已暂停 · 不参与路由":"来源未确认 · 窗口关闭",he.appendChild(_("span","wb-member-label")).textContent=X.member,X.suspended&&e.regulateSuspended&&((Q=o==null?void 0:o.canvas)==null?void 0:Q.revision)!==void 0)for(const Ie of["restore-suspended","delete-suspended"]){const _e=_("button","wb-member-remove");_e.type="button",_e.textContent=Ie==="restore-suspended"?"显式恢复":"删除暂停位";const it=o.canvas.revision;_e.addEventListener("click",async()=>{_e.disabled=!0;const Qe=await e.regulateSuspended(Ie,ee.name,X.member,it,X.records);Qe.ok||(_e.disabled=!1,_e.title=Qe.error??"状态已变,请刷新后重试")}),he.appendChild(_e)}B.appendChild(he)}for(const X of((de=o==null?void 0:o.canvas)==null?void 0:de.memberSlots)??[]){if(X.name!==ee.name||X.provenance!=="unknown"||!e.confirmMember||((pe=o==null?void 0:o.canvas)==null?void 0:pe.revision)===void 0)continue;const he=_("div","wb-hint");he.textContent=X.member+" · 来源未确认"+(X.compatibilityInference?" · 兼容推断中":"")+(X.suspended?" · 已暂停":""),B.appendChild(he);const Ie=(o.sessions??[]).filter(Te=>Te.joined===!0).map(Te=>({replacement:Te.id,label:ht(Te)+" — 本机完整会话"}));for(const Te of o.remote??[])Te.team.includes("/")&&Te.via&&Ie.push({replacement:Te.team,label:ht(Te)+" — "+Te.via,peer:Te.via});const _e=o.canvas.revision,it=JSON.stringify([ee.name,X.member,_e,X.ownerKey,Ie]);let Qe=u.get(it);Qe||(Qe=es(Ie,Te=>e.confirmMember(ee.name,X.member,Te.replacement,_e,X.ownerKey,Te.peer)),u.set(it,Qe)),B.appendChild(Qe)}if((c==null?void 0:c.name)!==ee.name){const X=_("form","wb-member-add"),he=document.createElement("select");he.className="wb-member-pick",he.setAttribute("aria-label","选择成员");const Ie=document.createElement("input");Ie.type="text",Ie.className="wb-member-manual",Ie.placeholder="或输入远端句柄 zone/id8",Ie.setAttribute("aria-label","远端成员句柄");const _e=_("button","wb-member-submit");_e.type="submit",_e.textContent="添加",X.appendChild(he),X.appendChild(Ie),X.appendChild(_e),X.addEventListener("submit",async it=>{it.preventDefault();const Qe=Ie.value.trim(),Te=Qe!==""?void 0:he.selectedOptions[0],St=Qe!==""?Qe:(Te==null?void 0:Te.dataset.member)??he.value;if(St==="")return;_e.disabled=!0;const Bt=await e.canvasOp("add-member",ee.name,St,void 0,Te==null?void 0:Te.dataset.peer);_e.disabled=!1,Bt&&(Ie.value="")}),c={name:ee.name,form:X,pick:he,manual:Ie}}const Be=c.pick,ct=Be.value;ye(Be),Be.appendChild(new Option("本机会话(现场/冷启动)…","",!0,!0));const $t=new Set(ee.members.map(X=>X.id));for(const X of(o==null?void 0:o.sessions)??[])$t.has(X.id)||Be.appendChild(new Option(`${ht(X)} — 本机`,X.id));let Nt=!1;for(const X of(o==null?void 0:o.remote)??[]){if(!X.team.includes("/")||$t.has(X.team))continue;Nt||(Be.appendChild(new Option("远端会话队(目录卡片)…","",!0,!1)),Nt=!0);const he=new Option(`${ht(X)} — ${X.via??"来源未确认"}`,JSON.stringify([X.team,X.via]));he.dataset.member=X.team,X.via&&(he.dataset.peer=X.via),Be.appendChild(he)}Nt||Be.appendChild(new Option("(暂无可拉入的远端会话队——见下方说明)","",!0,!1)),ct!==""&&Array.from(Be.options).some(X=>X.value===ct)&&(Be.value=ct),B.appendChild(c.form);const Mt=_("div","wb-hint");Mt.textContent="成员由人类明确分配。本机写完整会话;远端必须通过已链接主机的有效名片核实并记录完整公钥来源。最小卡、离线或第三方无法验证时保留待确认,不能手输裸句柄绕过来源校验。来源确认不恢复暂停;默认兼容窗口不自动关闭。",B.appendChild(Mt),e.dispatchQuick!==void 0&&B.appendChild(Ke(ee.team))}k.appendChild(B)}function nt(k){const g=_("form","wb-dispatch-form"),B=document.createElement("textarea");B.className="wb-dispatch-text",B.placeholder="一句话任务…(≤4000 字符,异步送达,回执进台账)",B.setAttribute("aria-label","快派消息");const P=_("button","wb-dispatch-submit");P.type="submit",P.textContent="发送";const Y=_("div","wb-dispatch-note");return g.appendChild(B),g.appendChild(P),g.appendChild(Y),B.addEventListener("keydown",Q=>{Q.key!=="Enter"||Q.shiftKey||Q.ctrlKey||Q.altKey||Q.metaKey||Q.isComposing||(Q.preventDefault(),P.disabled||g.requestSubmit())}),g.addEventListener("submit",async Q=>{var ee;Q.preventDefault();const de=B.value.trim();if(de===""||P.disabled)return;P.disabled=!0,Y.textContent="派发中…";let pe;try{pe=await(((ee=e.dispatchQuick)==null?void 0:ee.call(e,k,de))??Promise.resolve({ok:!1,error:"dispatch unavailable"}))}catch(Me){pe={ok:!1,error:Me instanceof Error?Me.message:String(Me)}}P.disabled=!1,pe.ok===!0&&(B.value=""),B.focus({preventScroll:!0}),Y.textContent=pe.ok===!0?`已派发${pe.task_id!==void 0?` · ${pe.task_id}`:""} · 回执将入台账(待回执)`:`失败:${pe.error??"未知原因"}`}),{form:g,text:B,note:Y}}function Ke(k){const g=_("div","wb-dispatch"),B=_("div","wb-side-head");return B.textContent="快派",g.appendChild(B),(h==null?void 0:h.team)!==k&&(h={team:k,...nt(k)}),g.appendChild(h.form),g}function ze(k){ne.open(k),le.classList.remove("is-rail-open")}function zt(k){if(o===null)return;const g=(o.sessions??[]).find(P=>P.id===k);if(g!==void 0){ze({kind:"session",id:k,title:ht(g),sub:g.team,team:g.team,live:g.live});return}if(k.startsWith("peer-")){const P=k.slice(5),Y=(o.peers??[]).find(Q=>Q.url.includes(P));ze({kind:"peer",id:k,title:Y!==void 0?Y.url:P,sub:P,url:Y==null?void 0:Y.url});return}m.find(P=>P.id===k)!==void 0&&ze({kind:"log",id:k,title:`…${k.slice(-12)}`,sub:"档案"})}function dt(){var ee,Me;L.textContent=(o==null?void 0:o.version)!==void 0?`v${o.version}`:"",L.hidden=(o==null?void 0:o.version)===void 0;const k=ye(ce);if(o===null)return;const g=[],B=Nn(o,e.now()),P=B.deadLetters.length;P>0&&g.push({text:`死信 ${P}`,tone:"danger",title:"超过 24h TTL 仍未结算的任务(unconsumed),需在台账清账",tab:"ledger",group:"死信"});const Y=B.stale.length;Y>0&&g.push({text:`陈旧 ${Y}`,tone:"warn",title:"我方派发、要回执、已等待 ≥1h 仍未回执(可催办;免回执行不算)",tab:"ledger",group:"陈旧"});const Q=B.owedOverdue.length;Q>0&&g.push({text:`欠回执 ${Q}`,tone:"warn",title:"对方投递给本机、已等待本机回执超过 1 小时",tab:"ledger",group:"待本机回执"});const de=((ee=o.idempotency)==null?void 0:ee.conflicts)??0;de>0&&g.push({text:`幂等冲突 ${de}`,tone:"danger",title:"同一幂等键对应了不同载荷,需人工核查",tab:"ledger",group:"取证"});const pe=(((Me=o.reconcile)==null?void 0:Me.rows)??[]).filter(Xe=>Xe.needsRepair===!0).length;if(pe>0&&g.push({text:`需修复 ${pe}`,tone:"danger",title:"reconcile 无法自动恢复的会话,见行动计划",tab:"plan"}),g.length===0){k.appendChild(_("span","wb-header-ok")).textContent="● 无异常";return}for(const Xe of g){const Be=_("button",`wb-alert wb-alert-${Xe.tone}`);Be.type="button",Be.textContent=Xe.text,Be.title=`${Xe.title}(点击查看)`,Be.addEventListener("click",()=>vt(Xe.tab,Xe.group)),k.appendChild(Be)}}function vt(k,g){var Y;const B=A.find(([Q])=>Q===k)[1];n==="canvas"&&(le.classList.add("is-rail-open"),M.select(k,{focus:!1}));const P=g===void 0?B:g==="取证"?B.querySelector("details.wb-led-forensics"):Array.from(B.querySelectorAll(".wb-led-group")).find(Q=>Q.dataset.group===g)??null;P!==null&&(P instanceof HTMLDetailsElement&&(P.open=!0),(Y=P.scrollIntoView)==null||Y.call(P,{block:"start",behavior:"smooth"}))}function It(k){var P,Y,Q;const g=new Set((((P=k==null?void 0:k.canvas)==null?void 0:P.teams)??[]).flatMap(de=>de.members.filter(pe=>pe.cliHome===null&&pe.cliHeld!==!0).map(pe=>JSON.stringify([de.name,pe.id]))));for(const de of d.keys())g.has(de)||d.delete(de);const B=((Y=k==null?void 0:k.canvas)==null?void 0:Y.memberSlots)??[];for(const de of u.keys()){const[pe,ee,Me]=JSON.parse(de);(Me!==((Q=k==null?void 0:k.canvas)==null?void 0:Q.revision)||!B.some(Xe=>Xe.name===pe&&Xe.member===ee&&Xe.provenance==="unknown"))&&u.delete(de)}o=k,e.sessionLogList!==void 0&&!te&&(te=!0,e.sessionLogList().then(de=>{m=de.ok&&de.sessions!==void 0?de.sessions:[],$=de.ok?de.count:void 0}).catch(()=>{}).finally(()=>{te=!1,qe()})),dt(),qe(),F(),Je(),Ge(),ne.update(k),Fe(),gt(),fe(),Pe()}function Tt(k){if(k==="board"){Pe();return}M.select(k)}function yt(k){if(Ue===void 0)return;w=k!==null;const g=Ue.update(k,(o==null?void 0:o.sessions)??[],e.now());M.setBadge("team",g.badge,g.tone),ve(n)}return It(null),{root:le,update:It,updateSuperagent:yt,mode:()=>n,selectTab:Tt,openNodeChat:zt}}const $s=e=>`member-${e.replace(/[^a-z0-9-]/gi,"-")}`;function Ns(e){const t=e==null?void 0:e.settings;if(!(t===void 0||t.canvas===void 0))return{canvas:t.canvas,...t.router!==void 0?{router:t.router}:{},members:new Map(t.members.map(n=>{var s;return[n,(s=t.repos)==null?void 0:s[n]]})),remote:new Map(t.remoteMembers.map(n=>{var s;return[$s(n.ref),(s=t.repos)==null?void 0:s[n.ref]]}))}}const Ss=e=>e.replace(/ · [^/(]+\//," · ");function Ms(e,t){if(e===void 0)return;if(e.router===t)return"总工";if(e.remote.has(t)){const s=e.remote.get(t);return s!==void 0?`成员 · ${s}(远端)`:"成员(远端)"}if(!e.members.has(t))return;const n=e.members.get(t);return n!==void 0?`成员 · ${n}`:"成员"}function As(){let e,t,n;const s=(r,i,c,d)=>{let u=r.querySelector(`:scope > .${i}`);if(c===void 0){u==null||u.remove();return}u===null&&(u=document.createElement("span"),u.className=i,r.appendChild(u)),u.textContent!==c&&(u.textContent=c),d!==void 0&&u.title!==d&&(u.title=d)},o=()=>{for(const[r,i]of t??[]){const c=(e==null?void 0:e.canvas)===r;i.classList.toggle("is-superagent-team",c);const d=i.querySelector(".p-frame-head");d!==null&&s(d,"sa-team",c?"superagent 团队":void 0)}for(const[r,i]of n??[]){const c=Ms(e,r);i.classList.toggle("is-superagent-router",c==="总工"),i.classList.toggle("is-superagent-member",(c==null?void 0:c.startsWith("成员"))===!0),s(i,"sa-role",c===void 0?void 0:Ss(c),c)}};return{update(r){e=Ns(r),o()},decorate(r,i){t=r,n=i,o()}}}const At=1e6,On=.25,Pn=3,Eo=256,$o=96;function jt(e){const t=typeof e=="number"?e:Number.NaN;if(Number.isFinite(t))return Math.max(-At,Math.min(At,Math.round(t)))}function No(e){if(e===null||typeof e!="object")return;const t=e,n=jt(t.x),s=jt(t.y);return n===void 0||s===void 0?void 0:{x:n,y:s}}function Ls(e){const t=No(e);if(t===void 0)return;const n=e,s=jt(n.w),o=jt(n.h);if(!(s===void 0||o===void 0||s<=0||o<=0))return{...t,w:Math.min(s,At),h:Math.min(o,At)}}const So=e=>e!==""&&!e.includes("/")&&(e.startsWith("roster:")?e.length>7&&e.length<=47:e.length<=40);function Mo(e){if(e===null||typeof e!="object")return;const t=e;if(t.version!==1)return;const n=t.viewport;if(n===null||typeof n!="object")return;const s=n,o=jt(s.x),r=jt(s.y),i=s.scale,c=typeof i=="number"?i:Number.NaN;if(o===void 0||r===void 0||!Number.isFinite(c))return;const d=Math.max(On,Math.min(Pn,c)),u={};if(t.nodes!==null&&typeof t.nodes=="object")for(const[m,$]of Object.entries(t.nodes)){if(typeof m!="string"||m===""||m.length>128)continue;const N=No($);if(N!==void 0&&(u[m]=N),Object.keys(u).length>=Eo)break}const h={};if(t.frames!==null&&typeof t.frames=="object")for(const[m,$]of Object.entries(t.frames)){if(!So(m))continue;const N=Ls($);if(N!==void 0&&(h[m]=N),Object.keys(h).length>=$o)break}return{version:1,viewport:{x:o,y:r,scale:d},nodes:u,frames:h}}function Is(e,t,n){const s=i=>Math.max(-At,Math.min(At,Math.round(i))),o={};for(const[i,c]of t)if(!(typeof i!="string"||i===""||i.length>128)&&(o[i]={x:s(c.x),y:s(c.y)},Object.keys(o).length>=Eo))break;const r={};for(const[i,c]of n){if(!So(i))continue;const d=s(c.w),u=s(c.h);if(!(d<=0||u<=0)&&(r[i]={x:s(c.x),y:s(c.y),w:Math.min(d,At),h:Math.min(u,At)},Object.keys(r).length>=$o))break}return{version:1,viewport:{x:s(e.x),y:s(e.y),scale:Math.max(On,Math.min(Pn,e.scale))},nodes:o,frames:r}}function Ao(e){let t=2166136261;for(let n=0;n<e.length;n++)t^=e.charCodeAt(n),t=Math.imul(t,16777619)>>>0;return t>>>0}const st=172,et=68,_t=[150,290,430],bt=16;function Ts(e){const t=Ao(e),n=Math.floor(t/bt)%_t.length,o=t%bt/bt*Math.PI*2+n*(Math.PI/bt),r=_t[n];return{x:Math.round(Math.cos(o)*r),y:Math.round(Math.sin(o)*r*.6)}}function Lo(e){const t=new Map;for(const n of e)for(const s of n.members)t.has(s.id)||t.set(s.id,n.name);return t}const Gn=64,Qn=24,Zn=20,_s=4,eo=24,to=44,Os=24;function Ps(e,t,n=Number.POSITIVE_INFINITY){const s=new Set(t),o=Lo(e),r=e.map(m=>[...new Set(m.members.map($=>$.id))].filter($=>s.has($)&&o.get($)===m.name));r.push(t.filter(m=>!o.has(m)));const i=new Map;let c=0,d=0,u=0,h=0;for(const m of r){if(m.length===0)continue;const $=Math.min(3,Math.max(m.length>1?2:1,Math.ceil(Math.sqrt(m.length)))),N=Math.ceil(m.length/$),te=Math.max(260,$*st+($-1)*Qn+eo*2),le=Math.max(160,N*et+(N-1)*Zn+to+Os);h>0&&(h%_s===0||c+te>n)&&(c=0,d+=u+Gn,u=0),m.forEach((ie,S)=>{const E=S%$,L=Math.floor(S/$);i.set(ie,{x:c+eo+st/2+E*(st+Qn),y:d+to+et/2+L*(et+Zn)})}),c+=te+Gn,u=Math.max(u,le),h+=1}return i}const en=12;function Io(e,t){const n=d=>t.every(u=>Math.abs(u.x-d.x)>=st+en||Math.abs(u.y-d.y)>=et+en),s=Ts(e);if(n(s))return s;const o=Ao(e),r=bt*_t.length,i=Math.floor(o/bt)%_t.length*bt+o%bt;for(let d=1;d<r;d++){const u=(i+d)%r,h=Math.floor(u/bt),m=u%bt/bt*Math.PI*2+h*(Math.PI/bt),$=_t[h],N={x:Math.round(Math.cos(m)*$),y:Math.round(Math.sin(m)*$*.6)};if(n(N))return N}const c=_t[_t.length-1];for(let d=0;;d++)for(let u=0;u<6;u++){const h={x:Math.round(-c+u*(st+en)),y:Math.round(c*.6+et*2+d*(et+en))};if(n(h))return h}}function kt(e){return{x:e.x-st/2,y:e.y-et/2,w:st,h:et}}function Fn(e){if(e.length===0)return{x:0,y:0,w:260,h:160};let t=Number.POSITIVE_INFINITY,n=Number.POSITIVE_INFINITY,s=Number.NEGATIVE_INFINITY,o=Number.NEGATIVE_INFINITY;for(const h of e)t=Math.min(t,h.x),n=Math.min(n,h.y),s=Math.max(s,h.x+h.w),o=Math.max(o,h.y+h.h);const r=24,i=44,c=24,d=Math.max(260,Math.round(s-t+r*2)),u=Math.max(160,Math.round(o-n+i+c));return{x:Math.round(t-r),y:Math.round(n-i),w:d,h:u}}class Rn{constructor(){Ft(this,"revisionCounter",0);Ft(this,"nodes",new Map);Ft(this,"frames",new Map);Ft(this,"selection",new Set);Ft(this,"viewport",{x:0,y:0,scale:1})}get revision(){return this.revisionCounter}getNode(t){return this.nodes.get(t)}allNodes(){return[...this.nodes.values()]}nodeIds(){return[...this.nodes.keys()]}getFrame(t){return this.frames.get(t)}allFrames(){return[...this.frames.entries()]}isSelected(t){return this.selection.has(t)}selectedIds(){return[...this.selection]}bump(){this.revisionCounter+=1}dragNodes(t,n,s){let o=!1;for(const r of t){const i=this.nodes.get(r);i!==void 0&&(i.x+=n,i.y+=s,o=!0)}o&&this.bump()}beginFrameDrag(t){const n=this.frames.get(t);if(n!==void 0)return{name:t,rect:{...n}}}applyFrameDrag(t,n,s){const o=this.frames.get(t.name);o!==void 0&&(o.x=t.rect.x+n,o.y=t.rect.y+s,this.bump())}nudge(t,n,s){this.dragNodes(t,n,s)}marqueeSelect(t,n){n||this.selection.clear();for(const s of this.nodes.values()){const o=kt(s);o.x<t.x+t.w&&o.x+o.w>t.x&&o.y<t.y+t.h&&o.y+o.h>t.y&&this.selection.add(s.id)}this.bump()}setSelection(t){this.selection=new Set(t),this.bump()}upsertNode(t){const n=this.nodes.get(t.id);if(n===void 0){this.nodes.set(t.id,t),this.bump();return}n.label=t.label,n.name=t.name,n.description=t.description,n.live=t.live,n.memberships=t.memberships,this.bump()}removeNode(t){this.nodes.delete(t)&&(this.selection.delete(t),this.bump())}setFrame(t,n){this.frames.set(t,n),this.bump()}removeFrame(t){this.frames.delete(t)&&this.bump()}upsertScore(t,n){const s=this.nodes.get(t);s===void 0||s.score===n||(s.score=n,this.bump())}positions(){const t=new Map;for(const[n,s]of this.nodes)t.set(n,{x:s.x,y:s.y});return t}frameRects(){const t=new Map;for(const[n,s]of this.frames)t.set(n,{...s});return t}teamMemberIds(t){const n=[];for(const s of this.nodes.values()){const o=s.memberships.find(r=>r.team===t);o!==void 0&&n.push({id:s.id,index:o.index})}return n.sort((s,o)=>s.index-o.index).map(s=>s.id)}setTeamMembers(t,n){for(const s of this.nodes.values()){const o=s.memberships.filter(i=>i.team!==t),r=n.indexOf(s.id);r>=0&&o.push({team:t,index:r}),s.memberships=o}this.bump()}contentBounds(){let t=Number.POSITIVE_INFINITY,n=Number.POSITIVE_INFINITY,s=Number.NEGATIVE_INFINITY,o=Number.NEGATIVE_INFINITY;const r=i=>{t=Math.min(t,i.x),n=Math.min(n,i.y),s=Math.max(s,i.x+i.w),o=Math.max(o,i.y+i.h)};for(const i of this.nodes.values())i.remote!==!0&&r(kt(i));for(const i of this.frames.values())r(i);return t===Number.POSITIVE_INFINITY?null:{minX:t,minY:n,maxX:s,maxY:o}}static fromState(t){const n=new Rn,s=Mo(t.layout),o=new Map;for(const r of t.teams)for(let i=0;i<r.members.length;i++){const c=r.members[i].id,d=o.get(c)??[];d.push({team:r.name,index:i}),o.set(c,d)}for(const r of t.sessions){if(r.joined!==!0)continue;const i=s==null?void 0:s.nodes[r.id];let c,d;if(i!==void 0&&typeof i.x=="number"&&typeof i.y=="number")c=i.x,d=i.y;else{const u=Io(r.id,[...n.nodes.values()]);c=u.x,d=u.y}n.nodes.set(r.id,{id:r.id,x:c,y:d,label:r.label,team:r.team,name:r.name,description:r.description,live:r.live!==!1,memberships:o.get(r.id)??[]})}for(const r of t.teams){const i=s==null?void 0:s.frames[r.name];if(i!==void 0){n.frames.set(r.name,{x:i.x,y:i.y,w:i.w,h:i.h});continue}const c=[];for(const d of r.members){const u=n.nodes.get(d.id);u!==void 0&&c.push(kt(u))}c.length>0&&n.frames.set(r.name,Fn(c))}return n.viewport=s!==void 0?{...s.viewport}:{x:0,y:0,scale:1},n}}const Fs=24,To=-13,Rs=To+Fs;function Ds(e,t,n){const s=[],o=new Set;for(const r of e){const i=t.get(r.name);if(i===void 0)continue;const c=i.x+i.w/2,d=i.y+Rs;for(const u of r.members){const h=n.get(u.id);if(h===void 0)continue;const m=o.has(u.id);o.add(u.id),s.push({x1:c,y1:d,x2:h.x,y2:h.y-et/2,dashed:m,team:r.name,id:u.id})}}return s}function js(e,t){for(;e.firstChild!==null;)e.firstChild.remove();const n=t.allFrames().map(([s])=>({name:s,members:t.teamMemberIds(s).map(o=>({id:o}))}));for(const s of Ds(n,new Map(t.allFrames()),t.positions())){const o=document.createElementNS("http://www.w3.org/2000/svg","line");o.setAttribute("class","e-member"+(s.dashed?" dashed":"")),o.setAttribute("x1",String(s.x1)),o.setAttribute("y1",String(s.y1)),o.setAttribute("x2",String(s.x2)),o.setAttribute("y2",String(s.y2)),e.appendChild(o)}}function Hs(e){return`peer-${Ct(e).replace(/[^A-Za-z0-9.:\[\]-]/g,"-")}`}function Ct(e){try{return new URL(e).host}catch{return e}}function Bs(e){const t=new Map;for(const n of e){const s=n.via!==void 0&&n.via!==""?Ct(n.via):"",o=t.get(s)??[];o.push(n),t.set(s,o)}return t}const Ys=140,Ws=200,qs=90,Ks=20,tn=60;function Xs(e,t){const n=t!==null?t.maxX+Ys:Ws,s=t!==null?t.minY:0;return e.map((o,r)=>({url:o.url,score:o.score,x:n,y:s+r*qs}))}function Us(e,t,n,s){const o=new Map;for(const i of e){if(!t.has(i.team))continue;const c=`${i.team}\0${i.peer}`,d=o.get(c);d===void 0?o.set(c,{team:i.team,peer:i.peer,startedAt:i.startedAt,count:1}):(d.startedAt=Math.min(d.startedAt,i.startedAt),d.count+=1)}const r=[];for(const i of o.values()){const c=t.get(i.team);if(c===void 0)continue;const d=n.find(h=>{try{return new URL(h.url).host===i.peer}catch{return!1}});if(d===void 0)continue;const u=Math.max(0,Math.round((s-i.startedAt)/1e3));r.push({x1:c.x,y1:c.y,x2:d.x,y2:d.y,label:`a2a_route · ${i.peer} · ${u}s`+(i.count>1?` ×${i.count}`:"")})}return r}function Js(e,t){const n=t!==null?{x:t.maxX+Ks,y:e.length>0?(e[0].y+e[e.length-1].y)/2:(t.minY+t.maxY)/2}:{x:-80,y:0};return e.map((s,o)=>({x1:n.x,y1:n.y,x2:s.x,y2:s.y,label:o===0?"gns referral":""}))}function zs(e,t){if(e===null&&t.length===0)return null;let n=e!==null?e.minX:Number.POSITIVE_INFINITY,s=e!==null?e.minY:Number.POSITIVE_INFINITY,o=e!==null?e.maxX:Number.NEGATIVE_INFINITY,r=e!==null?e.maxY:Number.NEGATIVE_INFINITY;for(const i of t)n=Math.min(n,i.x-tn),s=Math.min(s,i.y-tn),o=Math.max(o,i.x+tn),r=Math.max(r,i.y+tn);return{minX:n,minY:s,maxX:o,maxY:r}}const Vs=11;function Gs(e,t){let n=[],s=[],o=[];function r(c){for(const h of n)h.remove();n=[];const d=t.allNodes().filter(h=>h.remote===!0).map(h=>({url:h.peerUrl??h.id.slice(5),score:h.score,x:h.x,y:h.y}));s=d;const u=t.contentBounds();if(u!==null){const h=new Map;for(const[m,$]of t.allFrames())h.set(m,{name:m,x:$.x+$.w/2,y:$.y+Vs});for(const m of Us(o,h,d,c))n.push(...i(m,"e-activity",m.label));for(const m of Js(d,u))n.push(...i(m,"e-federal",m.label))}}function i(c,d,u){const h=document.createElementNS("http://www.w3.org/2000/svg","line");h.setAttribute("class",d),h.setAttribute("x1",String(c.x1)),h.setAttribute("y1",String(c.y1)),h.setAttribute("x2",String(c.x2)),h.setAttribute("y2",String(c.y2)),e.appendChild(h);const m=[h];if(u!==""){const $=document.createElementNS("http://www.w3.org/2000/svg","text");$.setAttribute("class","edge-label mono"),$.setAttribute("x",String((c.x1+c.x2)/2+14)),$.setAttribute("y",String((c.y1+c.y2)/2+18)),$.textContent=u,e.appendChild($),m.push($)}return m}return{render:r,flyTo(c){return c(),s},placements:()=>s,setInFlight:c=>{o=c}}}function _o(e,t){const n=new Map,s=new Set;for(const r of e){if(r.joined!==!0)continue;const i=r.team.lastIndexOf("/");if(i<=0||r.team.slice(i+1)!==r.id.replace(/^session-/,"").slice(0,8))continue;const c=r.team;t.has(c)||s.has(c)||(n.has(c)?(n.delete(c),s.add(c)):n.set(c,r.id))}const o=new Map;for(const r of e)if(r.joined===!0&&r.memberRef){const i=o.get(r.memberRef)??[];i.push(r.id),o.set(r.memberRef,i)}for(const[r,i]of o)i.length===1&&n.set(r,i[0]);return n}function Qs(e,t,n,s){var i;const o=t.get(e);return o!==void 0?o:e.includes("/")?`member-${e.replace(/[^a-z0-9-]/gi,"-")}`:`member-${((i=n==null?void 0:n.find(c=>c.via===s))==null?void 0:i.team.split("/")[0])??"dsh"}-${e.replace(/^session-/,"").slice(0,8)}`}function Zs(e){const t=new Map;for(const n of e)for(let s=0;s<n.members.length;s++){const o=n.members[s].id,r=t.get(o)??[];r.push({team:n.name,index:s}),t.set(o,r)}return t}function er(e,t,n){const s=_o(t,new Set((n??[]).map(r=>r.team))),o=new Set;for(const r of e)for(const i of r.org)for(const c of i.members){const d=s.get(c);d!==void 0&&o.add(d)}return o}const no={x:0,y:0,scale:1};function un(e){return Math.max(On,Math.min(Pn,e))}function Rt(e){const t=Number.isFinite(e.scale)?e.scale:1,n=Number.isFinite(e.x)?e.x:0,s=Number.isFinite(e.y)?e.y:0;return{x:n,y:s,scale:un(t)}}function wt(e,t,n){return{x:e.x+t/e.scale,y:e.y+n/e.scale}}function Cn(e,t,n){return{x:e.x+t/e.scale,y:e.y+n/e.scale,scale:e.scale}}function oo(e,t,n,s){const o=un(e.scale*t);return o===e.scale?e:{x:e.x+n/e.scale-n/o,y:e.y+s/e.scale-s/o,scale:o}}const tr=680,nr=.8,or=.6,so=16;function Dn(e,t,n,s=Number.POSITIVE_INFINITY){if(e===null||t<=0||n<=0)return no;const o=e.maxX-e.minX,r=e.maxY-e.minY;if(!(o>0)||!(r>0))return no;const i=.9*Math.min(t/o,n/r),c=Math.min(s,i),d=t<tr?nr:or;if(i<d){const h=un(Math.min(s,d));return{x:e.minX-so/h,y:e.minY-so/h,scale:h}}const u=un(c);return{x:(e.minX+e.maxX)/2-t/(2*u),y:(e.minY+e.maxY)/2-n/(2*u),scale:u}}function sr(e){return`translate(${-e.x*e.scale}px, ${-e.y*e.scale}px) scale(${e.scale})`}function ro(e,t){let n=e===null?null:{...e,minY:e.minY+To};for(const s of t){if(s.remote!==!0)continue;const o=kt(s);n=n===null?{minX:o.x,minY:o.y,maxX:o.x+o.w,maxY:o.y+o.h}:{minX:Math.min(n.minX,o.x),minY:Math.min(n.minY,o.y),maxX:Math.max(n.maxX,o.x+o.w),maxY:Math.max(n.maxY,o.y+o.h)}}return n}function io(e,t,n,s){const o=s>0&&s<n/2?s:0,r=Dn(e,t,n-o,1);return o===0||e===null?r:{...r,y:r.y-o/r.scale}}function ao(...e){const t=Math.max(0,...e.map(n=>n.offsetHeight>0?n.offsetTop+n.offsetHeight:0));return t>0?t+8:0}function Jt(e){return e.type==="join-network"||e.type==="leave-network"?"$network":e.type==="create-team"||e.type==="remove-team"?e.name:e.team}function rr(e,t){if(t.type==="create-team"){const o=t.ids.map(r=>e.getNode(r)).filter(r=>r!==void 0).map(r=>kt(r));return o.length>0&&e.setFrame(t.name,Fn(o)),e.setTeamMembers(t.name,t.ids),()=>{e.setTeamMembers(t.name,e.teamMemberIds(t.name).filter(r=>!t.ids.includes(r))),e.removeFrame(t.name)}}if(t.type==="add-member"){const o=e.teamMemberIds(t.team),r=t.ids.filter(i=>!o.includes(i));return e.setTeamMembers(t.team,[...o,...r]),()=>{e.setTeamMembers(t.team,e.teamMemberIds(t.team).filter(i=>!r.includes(i)))}}if(t.type==="remove-member"){const o=e.teamMemberIds(t.team);return e.setTeamMembers(t.team,o.filter(r=>!t.ids.includes(r))),()=>{const r=e.teamMemberIds(t.team);e.setTeamMembers(t.team,[...r,...t.ids.filter(i=>!r.includes(i))])}}if(t.type==="remove-team"){const o=e.teamMemberIds(t.name),r=e.getFrame(t.name),i=r!==void 0?{...r}:void 0;return e.setTeamMembers(t.name,[]),e.removeFrame(t.name),()=>{i!==void 0&&e.setFrame(t.name,i),e.setTeamMembers(t.name,o)}}if(t.type==="join-network"||t.type==="leave-network")return()=>{};const n=e.teamMemberIds(t.team);let s=[...n];for(const o of t.ops)o.op==="remove"?s=s.filter(r=>r!==o.id):s.push(o.id);return e.setTeamMembers(t.team,s),()=>{let o=e.teamMemberIds(t.team);for(let r=0;r<n.length;r++){const i=n[r];o[r]!==i&&o.includes(i)&&(o=o.filter(c=>c!==i),o.push(i))}e.setTeamMembers(t.team,o)}}function co(e,t,n,s,o){if(n||s(),!(t.type==="remove-team"&&n||t.type==="create-team"&&!n&&t.created===!0)||o===void 0||e.getFrame(Jt(t))!==void 0)return o;const i={...o.frames};return delete i[Jt(t)],{...o,frames:i}}function An(e,t){const n=[...e],s=[];for(let o=0;o<t.length;o++){const r=t[o];n[o]!==r&&n.includes(r)&&(s.push({op:"remove",id:r}),s.push({op:"add",id:r}),n.splice(n.indexOf(r),1),n.push(r))}return s}function ir(e,t){return e.teamMemberIds(t).map(n=>{var s;return{id:n,y:((s=e.getNode(n))==null?void 0:s.y)??0}}).sort((n,s)=>n.y-s.y).map(n=>n.id)}function nn(e,t){let n,s=Number.POSITIVE_INFINITY;for(const[o,r]of e){if(t.x<r.x||t.x>r.x+r.w||t.y<r.y||t.y>r.y+r.h)continue;const i=r.w*r.h;i<s&&(n=o,s=i)}return n}const lo=[9133302,3900150,1357990,16096779,15485081,8702998];function ar(e){let t=0;for(let c=0;c<e.length;c++)t=(t*31+e.charCodeAt(c)&268435455)>>>0;const n=lo[t%lo.length],s="#"+n.toString(16).padStart(6,"0"),o=n>>16&255,r=n>>8&255,i=n&255;return{line:s,bg:`rgba(${o},${r},${i},0.05)`}}const mn="roster:",Oo=e=>e.startsWith(mn)?e.slice(mn.length):void 0,Kt=e=>mn+e,fn=e=>{const t=Oo(e);return t===void 0?e:`网络队 · roster · ${t}`};function cr(e,t){return e.flatMap(n=>{if(t===""||!n.team.startsWith(t+"/")||!Array.isArray(n.members))return[];const s=n.team.slice(t.length+1);return s===""||s.length>40||s.includes("/")||s.startsWith(mn)||s.includes("*")?[]:[{name:Kt(s),team:n.team,kind:"roster",members:n.members.filter(o=>typeof o=="string"&&o!=="").map(o=>({id:o}))}]})}function dr(e){const{root:t,netBtn:n,signal:s,model:o}=e,r=x=>e.isRoster(x)?fn(x):x;function i(){return o.selectedIds().map(x=>{var f;return{id:x,y:((f=o.getNode(x))==null?void 0:f.y)??0}}).sort((x,f)=>x.y-f.y).map(x=>x.id)}function c(){if(d!==null)return;const x=i().filter(f=>{const M=o.getNode(f);return M===void 0?!1:M.remote!==!0||M.remoteHandle!==void 0&&M.remoteHandle!==""});if(x.length<2){e.notice("info","框选至少 2 个会话节点");return}u(x)}let d=null;function u(x){const f=document.createElement("div");f.className="p-dialog";const M=document.createElement("div");M.className="p-dialog-panel",M.setAttribute("role","dialog"),M.setAttribute("aria-modal","true"),M.setAttribute("aria-labelledby","p-dialog-title");const p=document.createElement("div");p.id="p-dialog-title",p.className="p-dialog-title",p.textContent=`组建团队(${x.length} 个节点,自上而下即优先级)`;const H={value:"canvas"},z=document.createElement("div");z.className="p-dialog-kind",z.setAttribute("role","radiogroup"),z.setAttribute("aria-label","团队类型");const G=document.createElement("div");G.className="p-dialog-hint";const Ee={canvas:"canvas 队:画布上的协作组,可以加入远端成员。",roster:"roster 网络队:只收本机已入网的会话;队名会写进属主的精确允许名单。"},Le=["canvas","roster"].map(q=>{const K=document.createElement("button");return K.type="button",K.dataset.kind=q,K.setAttribute("role","radio"),K.textContent=q==="canvas"?"canvas 队":"roster 网络队",K.addEventListener("click",()=>R(q)),z.appendChild(K),K});function R(q){H.value=q;for(const K of Le){const Z=K.dataset.kind===q;K.setAttribute("aria-checked",String(Z)),K.tabIndex=Z?0:-1}G.textContent=Ee[q],be.textContent=""}z.addEventListener("keydown",q=>{var Z;const K=q;["ArrowLeft","ArrowRight","ArrowUp","ArrowDown"].includes(K.key)&&(K.preventDefault(),R(H.value==="canvas"?"roster":"canvas"),(Z=Le.find(ne=>ne.dataset.kind===H.value))==null||Z.focus())});const se=document.createElement("input");se.className="p-dialog-input",se.maxLength=40,se.setAttribute("aria-label","团队名");const be=document.createElement("div");be.className="p-dialog-err",be.setAttribute("aria-live","polite");const Ue=document.createElement("div");Ue.className="p-dialog-row";const w=document.createElement("button");w.type="button",w.textContent="组建";const A=document.createElement("button");A.type="button",A.textContent="取消",Ue.append(w,A),R("canvas"),M.append(p,z,G,se,be,Ue),f.appendChild(M),t.appendChild(f);const oe=document.activeElement,I=()=>{f.remove(),d=null,oe==null||oe.focus()},T=()=>{const q=se.value.trim();return q===""||q.length>40||q.includes("/")||q.startsWith("roster:")||H.value==="roster"&&q.includes("*")||/^\d+$/.test(q)?"队名需 1..40 字,不含“/”、通配符或保留前缀,不为纯数字":H.value==="roster"&&o.getFrame(q)!==void 0?"同名 canvas 队已存在,不能创建 roster 队":H.value==="roster"&&o.getFrame(Kt(q))!==void 0&&!e.isRoster(Kt(q))?"roster 框名已被 canvas 或镜像队占用":H.value==="canvas"&&o.getFrame(Kt(q))!==void 0?"同名 roster 队已存在,不能创建 canvas 队":H.value==="roster"&&x.some(K=>{var Z;return((Z=o.getNode(K))==null?void 0:Z.remote)===!0||!e.joined(K)})?"roster 仅接受本机已入网的会话":null},W=()=>{const q=T();if(q!==null){be.textContent=q,se.focus();return}const K=H.value==="roster"?Kt(se.value.trim()):se.value.trim();if(I(),o.getFrame(K)!==void 0){e.notice("info",`已加入现有团队「${H.value==="roster"?fn(K):K}」`),e.emit({type:"add-member",team:K,ids:x});return}e.emit({type:"create-team",name:K,ids:x,created:!0,...H.value==="roster"?{roster:!0}:{}})};w.addEventListener("click",W),A.addEventListener("click",I),se.addEventListener("keydown",q=>{const K=q;K.key==="Enter"&&(K.preventDefault(),W()),K.key==="Escape"&&(K.preventDefault(),I())}),f.addEventListener("keydown",q=>{const K=q;if(K.key==="Escape"){K.preventDefault(),K.stopPropagation(),I();return}if(K.key!=="Tab")return;K.preventDefault();const Z=Array.from(M.querySelectorAll('input, select, button:not([tabindex="-1"])')),ne=Z.indexOf(document.activeElement),ve=K.shiftKey?Z[(ne-1+Z.length)%Z.length]:Z[(ne+1)%Z.length];ve==null||ve.focus()},s),d={wrap:f,restoreFocus:oe},se.focus()}let h=null,m="root",$=null,N=null,te=[];function le(){N==null||N.remove(),N=null}function ie(){var M;if(N!==null){le();return}if(te.length===0)return;const x=document.createElement("div");x.className="p-menu p-netmenu",x.setAttribute("role","menu"),x.setAttribute("aria-label","未入网会话");for(const p of te)x.appendChild(E(`${p.name!==void 0&&p.name!==""?p.name:p.label} — 入网`,!0,()=>{le(),e.emit({type:"join-network",id:p.id})}));N=x,t.appendChild(x);const f=n.getBoundingClientRect();x.style.left=`${String(Math.min(f.left,window.innerWidth-220))}px`,x.style.top=`${String(Math.max(8,f.top-(te.length*30+10)))}px`,x.addEventListener("keydown",p=>{p.key==="Escape"&&(p.stopPropagation(),le(),n.focus())}),(M=x.querySelector("button"))==null||M.focus(),document.addEventListener("pointerdown",p=>{if(N===null)return;const H=p.target;H!==null&&(H.closest(".p-netmenu")!==null||H===n||n.contains(H))||le()},s)}function S(){h==null||h.remove(),h=null,m="root",$!==null&&$.isConnected?$.focus():t.focus(),$=null}function E(x,f,M){const p=document.createElement("button");return p.type="button",p.setAttribute("role","menuitem"),p.textContent=x,f?p.addEventListener("click",()=>{S(),M()}):(p.disabled=!0,p.setAttribute("aria-disabled","true")),p}function L(x,f,M,p="root",H){var Le,R,se,be,Ue,w,A,oe;H!==void 0&&($=H),$===null&&($=e.anchorFor(M)),h==null||h.remove(),m=p;const z=document.createElement("div");z.className="p-menu",z.setAttribute("role","menu"),z.setAttribute("aria-label","团队操作");let G=[];if(M.kind==="frame")G=[E(`解散团队「${r(M.name)}」`,!0,()=>e.emit({type:"remove-team",name:M.name}))];else{const I=M.id;if(p==="root"){const T=E("组成团队…",o.selectedIds().length>=2,()=>u(i()));T.title="先框选或 Shift 加选至少 2 个节点",G.push(T);const W=((Le=o.getNode(I))==null?void 0:Le.memberships.map(q=>q.team))??[];e.teams().length>0&&(G.push(E("加入团队 ▸",!0,()=>L(x,f,M,"join"))),W.length>0&&G.push(E("置顶路由 ▸",!0,()=>L(x,f,M,"promote")))),W.length>0&&G.push(E("离队 ▸",!0,()=>L(x,f,M,"leave"))),((R=o.getNode(I))==null?void 0:R.remote)!==!0&&G.push(E("退网",!0,()=>e.emit({type:"leave-network",id:I})))}else{G.push(E("‹ 返回",!0,()=>L(x,f,M,"root")));for(const T of e.teams())if(p==="join"){const W=((se=o.getNode(I))==null?void 0:se.memberships.some(Z=>Z.team===T.name))??!0,q=!e.isRoster(T.name)||e.joined(I)&&((be=o.getNode(I))==null?void 0:be.remote)!==!0,K=E(W?`${r(T.name)}(已加入)`:r(T.name),!W&&q,()=>e.emit({type:"add-member",team:T.name,ids:[I]}));q||(K.title="roster 只接受本机已入网会话"),G.push(K)}else if(p==="leave"){const W=((Ue=o.getNode(I))==null?void 0:Ue.memberships.some(q=>q.team===T.name))??!1;G.push(E(r(T.name),W,()=>e.emit({type:"remove-member",team:T.name,ids:[I]})))}else{const W=((w=o.getNode(I))==null?void 0:w.memberships.some(q=>q.team===T.name))??!1;if(e.isRoster(T.name))continue;G.push(E(r(T.name),W,()=>{const q=o.teamMemberIds(T.name),K=[I,...q.filter(Z=>Z!==I)];e.emit({type:"reorder",team:T.name,ops:An(q,K)})}))}if(p==="leave"){const T=new Set(e.teams().map(W=>W.name));for(const W of((A=o.getNode(I))==null?void 0:A.memberships)??[])T.has(W.team)||G.push(E(r(W.team),!0,()=>e.emit({type:"remove-member",team:W.team,ids:[I]})))}}}z.append(...G),z.style.left=`${Math.min(x,window.innerWidth-200)}px`;const Ee=G.length*30+8;z.style.top=`${Math.max(8,Math.min(f,window.innerHeight-Ee-8))}px`,z.addEventListener("keydown",I=>{var K,Z,ne,ve;const T=I,W=Array.from(z.querySelectorAll("[role=menuitem]")),q=W.indexOf(document.activeElement);T.key==="ArrowDown"?(T.preventDefault(),(K=W[(q+1+W.length)%W.length])==null||K.focus()):T.key==="ArrowUp"?(T.preventDefault(),(Z=W[(q-1+W.length)%W.length])==null||Z.focus()):T.key==="Home"?(T.preventDefault(),(ne=W[0])==null||ne.focus()):T.key==="End"?(T.preventDefault(),(ve=W[W.length-1])==null||ve.focus()):T.key==="Escape"&&(T.preventDefault(),T.stopPropagation(),m!=="root"?L(x,f,M,"root"):S())}),t.appendChild(z),h=z,(oe=G[0])==null||oe.focus()}function C(x,f,M){if(d!==null)return;const p=(M==null?void 0:M.closest(".p-node"))??null;if(p!==null){const G=o.getNode(p.dataset.id??"");if((G==null?void 0:G.remote)===!0&&(G.remoteHandle===void 0||G.remoteHandle===""))return}const H=p,z=(M==null?void 0:M.closest(".p-frame-head"))??null;if(H!==null){const G=H.dataset.id??"";o.isSelected(G)||o.setSelection([G]),$=H,L(x,f,{kind:"node",id:G})}else z!==null&&($=z,L(x,f,{kind:"frame",name:z.dataset.frame??""}))}function ce(x){te=x,n.textContent=`未入网${te.length>0?`(${String(te.length)})`:""}`,n.disabled=te.length===0,n.setAttribute("aria-disabled",String(te.length===0)),te.length===0&&le()}return{menuItem:E,isMenuOpen:()=>h!==null,isDialogOpen:()=>d!==null,closeMenu:S,openMenu:L,contextMenuAt:C,openNameDialog:u,startCreateFromSelection:c,toggleNetMenu:ie,setUnjoined:ce}}function lr(e,t){const n=t.trim().toLowerCase();return n===""?[]:e.filter(s=>s.name.toLowerCase().includes(n)||s.team.toLowerCase().includes(n)||(s.host??"").toLowerCase().includes(n)).slice(0,8)}function ur(e,t){return e.allNodes().map(n=>{const s=n.id.slice(5),o=n.id.startsWith("member-")?n.name!==void 0&&n.name!==""?n.name:n.team:n.remote===!0?s:t(n);return{id:n.id,name:o,team:n.team,...n.remote===!0?{host:s}:{}}})}function mr(e,t=1200){e!==void 0&&(e.classList.add("pulse"),setTimeout(()=>e.classList.remove("pulse"),t))}function fr(e){return t=>{const n=e.model.getNode(t);if(n===void 0)return;const s=e.viewSize();e.setVp(Dn({minX:n.x,minY:n.y,maxX:n.x+st,maxY:n.y+et},s.w,s.h,1)),e.applyViewport(),e.markDirty(),mr(e.cardEl(t))}}function pr(e,t,n,s){const o=hr({onPick:s});return e.appendChild(o.root),{...o,refresh:()=>o.setIndex(ur(t,n))}}function hr(e){const t=document.createElement("div");t.className="p-search";const n=document.createElement("input");n.type="search",n.className="p-search-input",n.placeholder="🔍 搜索(Ctrl+K)",n.title="搜索名字 / 句柄 / 宿主(Ctrl+K 聚焦,Esc 清空)",n.setAttribute("aria-label","搜索画板节点:名字、句柄或宿主");const s=document.createElement("div");s.className="p-search-list";let o=[],r=[],i=0;const c=()=>{s.style.display="none",s.textContent=""},d=()=>{if(s.textContent="",r.length===0){c();return}r.forEach((m,$)=>{const N=document.createElement("div");N.className="p-search-hit"+($===i?" active":""),N.dataset.id=m.id,N.textContent=m.name===m.team?m.name:`${m.name} · ${m.team}`,N.addEventListener("mousedown",te=>{te.preventDefault(),e.onPick(m.id),u()}),s.appendChild(N)}),s.style.display="block"},u=()=>{n.value="",r=[],c()},h=()=>{r=lr(o,n.value),i=0,d()};return n.addEventListener("input",h),n.addEventListener("keydown",m=>{if(m.key==="Escape"){u(),n.blur(),m.stopPropagation();return}if(m.key==="ArrowDown"||m.key==="ArrowUp"){if(r.length===0)return;m.preventDefault(),i=(i+(m.key==="ArrowDown"?1:r.length-1))%r.length,d();return}m.key==="Enter"&&r.length>0&&(m.preventDefault(),e.onPick(r[i].id),u())}),t.append(n,s),{root:t,setIndex(m){o=m,n.value!==""&&h()},focus(){n.focus(),n.select()},clear(){u()}}}const on=28,uo=16,mo=14,fo=48,br=4,gr=180,vr=90,yr=1600;function wr(e){const t=e.wrapWidth??yr,n=e.frames.map(d=>{const u=Math.max(d.soleIds.length,1),h=Math.min(br,Math.max(1,Math.ceil(Math.sqrt(u)))),m=Math.ceil(u/h),$=Math.max(gr,on*2+h*st+(h-1)*uo),N=Math.max(vr,on*2+m*et+(m-1)*mo);return{name:d.name,w:$,h:N,rows:m,perRow:h,soleIds:d.soleIds}}),s=[],o=[];let r=0,i=0,c=0;for(const d of n){r>0&&r+d.w>t&&(r=0,i+=c+fo,c=0);const u={x:r,y:i,w:d.w,h:d.h};s.push({name:d.name,rect:u});const h=u.x+on+st/2;let m=u.y+on+et/2;d.soleIds.forEach(($,N)=>{const te=N%d.perRow;N>0&&te===0&&(m+=et+mo),o.push({id:$,x:h+te*(st+uo),y:m})}),r+=d.w+fo,c=Math.max(c,d.h)}return{frames:s,seats:o}}function xr(e,t){const n=[];for(const[o,r]of e.allFrames()){if(t.has(o))continue;const i=e.teamMemberIds(o).map(c=>e.getNode(c)).filter(c=>c!==void 0).filter(c=>c.memberships.length===1).map(c=>c.id);n.push({name:o,rect:r,soleIds:i})}if(n.length===0)return!1;const s=wr({frames:n});for(const o of s.frames)e.setFrame(o.name,o.rect);for(const o of s.seats){const r=e.getNode(o.id);r!==void 0&&e.dragNodes([o.id],o.x-r.x,o.y-r.y)}return!0}function Cr(e,t){if(e===void 0)return;const n=Ct(e);return{text:t?`同步中… · ${n}`:`镜像 · ${n}`,title:t?`已把改动交给属主 ${n},等待它确认`:`这个团队属于 ${n},这里显示的是它的镜像;拖入或移出成员会经中继交给 ${n} 执行`,syncing:t}}const kr=1e4;function Er(e=Date.now){const t=(s,o)=>`${s}\0${o}`,n=new Map;return{fork(s,o){return n.set(t(o,s.name),{url:o,name:s.name}),{...s,fleetPeer:o}},settled(s,o){if(s.type!=="remove-team"||s.name===void 0||s.fleetPeer===void 0)return;const r=n.get(t(s.fleetPeer,s.name));r!==void 0&&(o?r.acceptedAt=e():n.delete(t(s.fleetPeer,s.name)))},hides(s,o){return n.has(t(o,s))},sweep(s){var o;for(const[r,i]of n)(!(((o=s.find(d=>d.url===i.url))==null?void 0:o.org.some(d=>d.name===i.name))===!0)||i.acceptedAt!==void 0&&e()-i.acceptedAt>kr)&&n.delete(r)}}}const Ot=24,$r=200,an=(e,t)=>e.x<t.x+t.w&&t.x<e.x+e.w&&e.y<t.y+t.h&&t.y<e.y+e.h;function Nr(e,t){const n=t.x+t.w+Ot-e.x,s=t.x-Ot-(e.x+e.w),o=t.y+t.h+Ot-e.y,r=t.y-Ot-(e.y+e.h),i=Math.abs(n)<=Math.abs(s)?n:s,c=Math.abs(o)<=Math.abs(r)?o:r;return Math.abs(i)<=Math.abs(c)?{dx:i,dy:0}:{dx:0,dy:c}}function Sr(e,t,n,s){const o=e.beginFrameDrag(t);o!==void 0&&e.applyFrameDrag(o,n,s)}function Mr(e,t,n){let s=!1;for(let o=0;o<$r;o++){const r=e.allFrames();let i;for(let S=0;S<r.length&&i===void 0;S++)for(let E=S+1;E<r.length;E++){const[L,C]=r[S],[ce,x]=r[E];if(!(t.has(L)&&t.has(ce))&&an(C,x)){i=[L,C,ce,x];break}}if(i===void 0)return s;const[c,d,u,h]=i,m=S=>t.has(S)?2:S===n?1:0,[$,N,te]=m(c)<m(u)?[c,d,h]:[u,h,d],{dx:le,dy:ie}=Nr(N,te);Sr(e,$,le,ie),s=!0}return s}const Lt=28,cn=16,pn=14;function Ar(e){const t=[];for(let n=e.y+Lt;n+et<=e.y+e.h-Lt;n+=et+pn)for(let s=e.x+Lt;s+st<=e.x+e.w-Lt;s+=st+cn)t.push({x:s+st/2,y:n+et/2});return t}function Lr(e){let t=!1;const n=e.allFrames(),s=new Map(n);for(const o of e.allNodes()){const r=new Set(o.memberships.map(ie=>ie.team)),i=n.find(([ie,S])=>!r.has(ie)&&an(kt(o),S));if(i===void 0)continue;const c=i[1],d=ie=>{const S=kt(ie);return n.every(([E,L])=>r.has(E)||!an(S,L))&&e.allNodes().every(E=>E.id===o.id||!an(S,kt(E)))},h=o.memberships.map(ie=>s.get(ie.team)).filter(ie=>ie!==void 0).flatMap(Ar).find(d),m={x:c.x+c.w+Ot+st/2,y:o.y},$={x:o.x,y:c.y+c.h+Ot+et/2},N=Math.max(...n.map(([,ie])=>ie.x+ie.w))+Ot+st/2,te=Array.from({length:2*e.allNodes().length+1},(ie,S)=>({x:N,y:c.y+et/2+S*(et+pn)})),le=h??[m,$,...te].find(d)??te[te.length-1];e.dragNodes([o.id],le.x-o.x,le.y-o.y),t=!0}return t}function sn(e,t,n){const s=Mr(e,t,n),o=Lr(e);return s||o}function Ir(e){for(const[t,n]of e.allFrames()){const s=e.teamMemberIds(t).map(u=>e.getNode(u)).filter(u=>u!==void 0).filter(u=>u.memberships.length===1);if(s.length===0)continue;const o=Math.max(1,Math.floor((n.w-2*Lt+cn)/(st+cn))),r=Math.ceil(s.length/o),i=Lt*2+r*et+(r-1)*pn;i>n.h&&e.setFrame(t,{...n,h:Math.min(i,n.h+400)});const c=n.x+Lt+st/2;let d=n.y+Lt+et/2;s.forEach((u,h)=>{const m=h%o;h>0&&m===0&&(d+=et+pn);const $=c+m*(st+cn);e.dragNodes([u.id],$-u.x,d-u.y)})}}const Tr=30;function _r(e){const t=[],n=()=>({nodes:new Map(e.allNodes().map(r=>[r.id,{x:r.x,y:r.y}])),frames:new Map(e.allFrames().map(([r,i])=>[r,{...i}]))}),s=r=>e.allNodes().some(i=>{const c=r.nodes.get(i.id);return c!==void 0&&(c.x!==i.x||c.y!==i.y)})||e.allFrames().some(([i,c])=>{const d=r.frames.get(i);return d!==void 0&&(d.x!==c.x||d.y!==c.y||d.w!==c.w||d.h!==c.h)}),o=r=>{for(const i of e.allNodes()){const c=r.nodes.get(i.id);c!==void 0&&(c.x!==i.x||c.y!==i.y)&&e.dragNodes([i.id],c.x-i.x,c.y-i.y)}for(const[i,c]of e.allFrames()){const d=r.frames.get(i);d!==void 0&&(d.x!==c.x||d.y!==c.y||d.w!==c.w||d.h!==c.h)&&e.setFrame(i,{...d})}};return{capture:n,commit(r){s(r)&&(t.push(r),t.length>Tr&&t.shift())},undo(){const r=t.pop();return r===void 0?!1:(o(r),!0)},revert(r){return s(r)?(o(r),!0):!1},get depth(){return t.length}}}function Or(e){const{root:t,trigger:n,signal:s,model:o}=e;let r=null,i="",c=null;function d(){c==null||c.remove(),c=null}function u(){d(),r==null||r.remove(),r=null}function h(){if(r!==null){u();return}const E=document.createElement("div");E.className="p-menu p-nodelist",E.setAttribute("role","dialog"),E.setAttribute("aria-label","节点清单"),r=E,t.appendChild(E);const L=n.getBoundingClientRect();E.style.left=`${String(Math.min(L.left,window.innerWidth-340))}px`,E.style.top=`${String(Math.max(8,L.top-320))}px`,E.addEventListener("keydown",C=>{C.key==="Escape"&&(C.stopPropagation(),u(),n.focus())}),m()}function m(){var M;const E=r;if(E===null)return;d(),E.textContent="";const L=document.createElement("div");L.className="p-nodelist-head";const C=document.createElement("span");C.className="p-nodelist-title",C.textContent="节点";const ce=document.createElement("select");ce.className="p-nodesel",ce.setAttribute("aria-label","选择 host 或对等节点");const x=document.createElement("option");x.value="",x.textContent="本机",ce.appendChild(x);for(const[p,H]of e.facts().remoteTeams){if(p==="")continue;const z=document.createElement("option");z.value=p,z.textContent=((M=H[0])==null?void 0:M.origin)!==void 0&&H[0].origin!==""?`${H[0].origin}(${p})`:p,ce.appendChild(z)}i!==""&&!e.facts().remoteTeams.has(i)&&(i=""),ce.value=i,ce.addEventListener("change",()=>{i=ce.value,m()}),L.append(C,ce);const f=document.createElement("div");f.className="p-nodelist-body",E.append(L,f),i===""?ie(f):S(f,e.facts().remoteTeams.get(i)??[])}function $(E,L){const C=document.createElement("span");return C.className="p-nodedot"+(L!==!0?" off":E===!1?" cold":""),C}function N(E,L){const C=document.createElement("button");return C.type="button",C.className="p-listbtn",C.textContent=E,C.addEventListener("click",ce=>{ce.stopPropagation(),L()}),C}function te(E,L){const C=document.createElement("div");if(C.className="p-nodelist-group",C.textContent=E,L!==void 0){const ce=document.createElement("span");ce.className="p-nodelist-note",ce.textContent=L,C.appendChild(ce)}return C}function le(E,L){var x,f;d();const C=document.createElement("div");C.className="p-menu",C.setAttribute("role","menu"),C.setAttribute("aria-label","加入团队");for(const M of e.facts().teams){const p=((x=o.getNode(L))==null?void 0:x.memberships.some(H=>H.team===M.name))??!1;C.appendChild(e.menuItem(p?`${M.name}(已加入)`:M.name,!p,()=>{u(),e.emit({type:"add-member",team:M.name,ids:[L]})}))}C.appendChild(e.menuItem("新团队…",!0,()=>{u(),e.openNameDialog([L])})),c=C,t.appendChild(C);const ce=E.getBoundingClientRect();C.style.left=`${String(Math.min(ce.right+4,window.innerWidth-180))}px`,C.style.top=`${String(Math.max(8,ce.top-60))}px`,C.addEventListener("keydown",M=>{M.key==="Escape"&&(M.stopPropagation(),d(),E.focus())}),(f=C.querySelector("button"))==null||f.focus()}function ie(E){var f,M;const L=new Set(e.facts().canvasMemberIds);for(const p of e.facts().sessions)p.teams!==void 0&&p.teams.length>0&&L.add(p.id);const C=e.facts().sessions.filter(p=>p.joined===!0&&!L.has(p.id)),ce=e.facts().sessions.filter(p=>p.joined!==!0),x=e.facts().sessions.filter(p=>p.joined===!0&&L.has(p.id));E.appendChild(te(`未组队 (${String(C.length)})`,"无网络能力"));for(const p of C){const H=document.createElement("div");H.className="p-noderow";const z=document.createElement("span");z.className="p-nodename",z.textContent=p.name!==void 0&&p.name!==""?p.name:p.label,z.title=p.team;const G=document.createElement("span");G.className="p-nonet",G.textContent="无网络能力";const Ee=N("入队▸",()=>le(Ee,p.id));H.append($(p.live,!0),z,G,Ee,N("退网",()=>{u(),e.emit({type:"leave-network",id:p.id})})),E.appendChild(H)}E.appendChild(te(`未入网 (${String(ce.length)})`));for(const p of ce){const H=document.createElement("div");H.className="p-noderow";const z=document.createElement("span");z.className="p-nodename",z.textContent=p.name!==void 0&&p.name!==""?p.name:p.label,z.title=p.id,H.append($(p.live,!1),z,N("入网",()=>{u(),e.emit({type:"join-network",id:p.id})})),E.appendChild(H)}E.appendChild(te(`已组队 (${String(x.length)})`,"画布展示"));for(const p of x){const H=document.createElement("div");H.className="p-noderow";const z=document.createElement("span");z.className="p-nodename",z.textContent=p.name!==void 0&&p.name!==""?p.name:p.label,z.title=p.team;const G=((f=o.getNode(p.id))==null?void 0:f.memberships.length)??0,Ee=((M=p.teams)==null?void 0:M.length)??0,Le=document.createElement("span");Le.className="p-teamcount",Le.textContent=`队×${String(Math.max(G,0)+Ee)}`,H.append($(p.live,!0),z,Le,N("定位",()=>{e.locate(p.id)})),E.appendChild(H)}if(e.facts().sessions.length===0){const p=document.createElement("div");p.className="p-nodelist-empty",p.textContent="无会话节点",E.appendChild(p)}}function S(E,L){var x;const C=L.filter(f=>f.teams===void 0||f.teams.length===0),ce=L.filter(f=>f.teams!==void 0&&f.teams.length>0);E.appendChild(te(`未组队 (${String(C.length)})`,"无网络能力 · 只读"));for(const f of C){const M=document.createElement("div");M.className="p-noderow";const p=document.createElement("span");p.className="p-nodename",p.textContent=f.name!==void 0&&f.name!==""?f.name:f.team,p.title=f.team;const H=document.createElement("span");H.className="p-nonet",H.textContent="无网络能力",M.append($(!0,!0),p,H),E.appendChild(M)}E.appendChild(te(`已组队 (${String(ce.length)})`,"只读"));for(const f of ce){const M=document.createElement("div");M.className="p-noderow";const p=document.createElement("span");p.className="p-nodename",p.textContent=f.name!==void 0&&f.name!==""?f.name:f.team,p.title=f.team;const H=document.createElement("span");H.className="p-teamcount",H.textContent=`队×${String(((x=f.teams)==null?void 0:x.length)??0)}`,M.append($(!0,!0),p,H),E.appendChild(M)}if(L.length===0){const f=document.createElement("div");f.className="p-nodelist-empty",f.textContent="该节点未发布会话",E.appendChild(f)}}return document.addEventListener("pointerdown",E=>{if(r===null)return;const L=E.target;if(L===null){u();return}L.closest(".p-nodelist")!==null||L.closest(".p-menu")!==null||L===n||n.contains(L)||u()},s),{toggle:h,close:u,refresh:()=>{r!==null&&m()}}}function Pr(e){let t=e;const n=t.search(/\|| ```|^```/);return n>=0&&(t=t.slice(0,n)),t.replace(/\[([^\]]*)\]\([^)]*\)/g,"$1").replace(/(^|\s)#{1,6}\s+/g,"$1").replace(/\*\*|__|`/g,"").replace(/\s+/g," ").trim()}function Fr(e,t){const n=e.map(r=>r.name!==void 0&&r.name!==""?r.name:r.team),s=n.slice(0,2).join("、"),o=n.length>2?` +${n.length-2}`:"";return(t!==void 0?`score ${t} · `:"")+`${e.length} 远端团队`+(s!==""?`:${s}${o}`:"")}function Rr(e,t,n){if(e.id.startsWith("member-"))return{title:e.name!==void 0&&e.name!==""?e.name:e.team,sub:e.team,tip:e.team};if(e.remote===!0){const d=e.id.slice(5),u=t.length===1&&t[0].name!==void 0&&t[0].name!==""?t[0].name:void 0,h=Fr(t,n);return u!==void 0?{title:u,sub:`${d} · ${h}`,tip:`${u}
|
|
6
|
+
${d}
|
|
7
|
+
${h}`}:{title:d,sub:h,tip:`${d}
|
|
8
|
+
${h}`}}const s=xt(e),o=e.team+(e.name!==void 0&&e.name!==""?" · "+e.name:""),r=Pr(e.description??""),i=r!==""?r:o===s?"":e.team,c=(e.memberships.length>1?` · 跨队×${e.memberships.length}`:"")+(e.teams!==void 0&&e.teams.length>0?` · 网络队×${e.teams.length}`:"");return{title:s,sub:i+c,tip:r!==""?`${o}
|
|
9
|
+
${r}`:o}}function Dr(e){if((e==null?void 0:e.status)===void 0)return"";const t=e.status==="running"?"工作中":"空闲";return typeof e.queued=="number"&&e.queued>0?`${t} · 排队 ${String(e.queued)}`:t}function jr(e){const t=document.createElement("div");t.className="p-node",t.dataset.id=e,t.tabIndex=0;const n=document.createElement("div");n.className="nm";const s=document.createElement("span");s.className="dot";const o=document.createElement("span");o.className="nm-text",n.append(s,o);const r=document.createElement("div");r.className="sub mono";const i=document.createElement("span");i.className="prio mono";const c=document.createElement("span");c.className="work";const d=document.createElement("div");return d.className="sub-row",d.append(r,c),t.append(n,d,i),t}function Hr(e,t,n){if(t.remote===!0){const s=(n==null?void 0:n.link)==="linked"?"lnk-linked":(n==null?void 0:n.link)==="stranger"?"lnk-stranger":"";e.className!==`prio mono ${s}`.trim()&&(e.className=`prio mono ${s}`.trim());const o=n===void 0?"":n.verified===!0?"✓":"✗",r=(t.id.startsWith("member-")?"成员":(n==null?void 0:n.link)??"peer")+o;e.textContent!==r&&(e.textContent=r)}else{e.className!=="prio mono"&&(e.className="prio mono");const s=t.memberships[0]!==void 0?`P${t.memberships[0].index}`:"";e.textContent!==s&&(e.textContent=s)}}const po="dsh-a2a.board.legend";function Br(){const e=document.createElement("details");e.className="p-legend";const t=document.createElement("summary");t.textContent="图例",t.title="边的含义(点击展开 / 收起)";const n=document.createElement("div");n.className="p-legend-rows";const s=(o,r,i)=>{const c=document.createElement("span"),d=document.createElement("i");o&&(d.className="dashed"),i!==void 0&&(d.style.borderTopColor=i),c.append(d,document.createTextNode(r)),n.appendChild(c)};s(!1,"成员边(星形,框→成员)"),s(!0,"跨队多属(虚线)"),s(!0,"roster 网络队框(双线边框)"),s(!1,"活动边(inFlight 路由,瞬时)","var(--accent)"),s(!0,"联邦线(→peer)","var(--federal)"),e.append(t,n);try{e.open=window.localStorage.getItem(po)==="open"}catch{}return e.addEventListener("toggle",()=>{try{window.localStorage.setItem(po,e.open?"open":"closed")}catch{}}),e}const dn="对端未应答(显示的是最后已知状态)";function ho(e){const t=new Set;for(const s of e.remoteTeams??[])s.unreachable===!0&&s.via&&t.add(Ct(s.via));for(const s of e.peerOrg??[])s.unreachable===!0&&t.add(Ct(s.url));const n=new Set;for(const s of e.remoteTeams??[])s.via&&t.has(Ct(s.via))&&n.add(`member-${s.team.replace(/[^a-z0-9-]/gi,"-")}`);return{hosts:t,members:n}}function Yr(e,t){e.classList.toggle("is-unreachable",t);const n=e.querySelector(".p-frame-unreachable");if(t&&n===null){const s=document.createElement("span");s.className="p-frame-unreachable",s.textContent=dn,e.appendChild(s)}else t||n==null||n.remove()}function Wr(e){return e<680?"narrow":e<1024?"medium":"wide"}function qr(e){const t=new Rn;let n,s={...t.viewport},o={kind:"none"},r=!1,i=-1,c=!0,d=!1;const u=_r(t);let h,m=!1;const $=()=>Wr(globalThis.innerWidth||Pe),N=()=>{var a;(a=e.viewportStore)==null||a.set($(),s),e.onDirty()},te=e.now??Date.now,le=new AbortController,ie=[];let S=null,E=!1;const L={signal:le.signal},C=document.createElement("section");C.id="dsh-plan",C.setAttribute("role","tabpanel"),C.setAttribute("aria-label","A2A 规划画布"),C.tabIndex=0,C.style.display="none";const ce=document.createElement("div");ce.className="p-grid";const x=document.createElement("div");x.className="p-world";const f=document.createElementNS("http://www.w3.org/2000/svg","svg");f.setAttribute("class","p-edges");const M=document.createElement("div");M.className="p-layer p-frames";let p;const H=a=>{var b,v;p!==void 0&&((b=Re.get(p))==null||b.classList.remove("selected")),p=a,a!==void 0&&((v=Re.get(a))==null||v.classList.add("selected"))},z=document.createElement("div");z.className="p-layer p-nodes",z.setAttribute("role","listbox"),z.setAttribute("aria-multiselectable","true"),z.setAttribute("aria-label","会话节点"),x.append(f,M,z);const G=document.createElement("div");G.className="p-marquee";const Ee=document.createElement("div");Ee.className="p-toolbar";const Le=document.createElement("span");Le.className="p-zoom mono",Le.textContent="100%";const R=(a,b,v)=>{const D=document.createElement("button");return D.type="button",D.textContent=a,D.title=b,D.addEventListener("click",v,L),D},se=()=>{const a=document.createElement("span");return a.className="p-sep",a.setAttribute("role","separator"),a.setAttribute("aria-orientation","vertical"),a};Ee.append(R("适配","适配视图(快捷键 0)",()=>Mt()),R("-","缩小",()=>$t(1/1.2)),Le,R("+","放大",()=>$t(1.2)),se(),R("建队","组成团队(G):先框选至少 2 个节点",()=>g.startCreateFromSelection()),R("整理成员","每队框内仅属一队的成员自动排齐(多队成员不动)",()=>Ge()),R("一键重排","全板队框+成员重排:框尺寸随内容自适应、框位行流式平铺(远端队框与多归属成员不动)",()=>$e()),R("撤销","撤销上一次布局改动:拖动、缩放、整理、重排、载入时避让(Ctrl+Z;入队离队不撤销)",()=>Nt()));const be=R("未入网","未入网会话(点击选择入网)",()=>g.toggleNetMenu());be.className="p-netbtn",be.setAttribute("aria-haspopup","menu"),Ee.append(se(),be);const Ue=pr(Ee,t,xt,a=>fe(a)),w=R("节点","节点清单:本机与对等节点(未组队/未入网在此管理)",()=>Y.toggle());w.className="p-nodebtn",w.setAttribute("aria-haspopup","dialog"),Ee.appendChild(w);const A=document.createElement("span");A.setAttribute("aria-live","polite"),A.className="p-lamp";const oe=document.createElement("i"),I=document.createElement("span");I.textContent="布局",A.append(oe,I),A.addEventListener("click",()=>{A.classList.contains("error")&&e.onLampClick()},L),A.addEventListener("keydown",a=>{const b=a;(b.key==="Enter"||b.key===" ")&&A.classList.contains("error")&&(b.preventDefault(),e.onLampClick())},L),Ee.appendChild(A);const T=document.createElement("div");T.className="p-status";const W=document.createElement("span"),q=document.createElement("span"),K=document.createElement("span");K.className="mut";const Z=document.createElement("span");Z.className="mut",T.append(W,q,K,Z),T.tabIndex=0,T.setAttribute("role","button"),T.setAttribute("aria-label","定位在途路由与联邦对端"),T.title="定位在途与联邦(回车)",T.addEventListener("click",()=>Se(),L),T.addEventListener("keydown",a=>{const b=a;(b.key==="Enter"||b.key===" ")&&(b.preventDefault(),Se())},L);const ne=Br(),ve=document.createElement("div");ve.className="p-notice-stack",ve.setAttribute("role","log"),ve.setAttribute("aria-live","polite"),C.append(ce,x,G,Ee,T,ne,ve);let Pe=0,ye=0;const rt=()=>e.viewSize?e.viewSize():{w:C.clientWidth,h:C.clientHeight},qe=()=>{const a=rt();Pe=a.w,ye=a.h};function Je(){x.style.transform=sr(s);const a=24*s.scale;ce.style.backgroundSize=`${a}px ${a}px`,ce.style.backgroundPosition=`${-s.x*s.scale}px ${-s.y*s.scale}px`,Le.textContent=`${Math.round(s.scale*100)}%`}function Ge(){const a=u.capture();Ir(t),sn(t,new Set(dt.keys())),u.commit(a),N(),Fe()}function $e(){const a=u.capture();xr(t,new Set(dt.keys()))&&(sn(t,new Set(dt.keys())),u.commit(a),N(),Fe())}function Fe(){var a;Je(),t.revision!==i&&(i=t.revision,Et(),mt(),(a=e.decorate)==null||a.call(e,Re,gt),js(f,t)),Ce()}const Re=new Map,gt=new Map;function Et(){var b;const a=new Set;for(const[v,D]of t.allFrames()){a.add(v);let j=Re.get(v);if(j===void 0){j=document.createElement("div"),j.className="p-frame",j.dataset.name=v;const me=document.createElement("div");me.className="p-frame-head",me.dataset.frame=v,me.tabIndex=0,me.setAttribute("role","button"),me.setAttribute("aria-haspopup","menu"),me.setAttribute("aria-label",`团队框 ${v}(拖动整组,回车菜单)`);const Ve=document.createElement("span");Ve.className="ttl";const at=document.createElement("span");at.className="cnt mono";const ft=document.createElement("span");ft.className="route mono",me.append(Ve,at,ft),j.appendChild(me);for(const pt of["n","s","e","w","ne","nw","se","sw"]){const Pt=document.createElement("div");Pt.className=`p-frame-handle p-h-${pt}`,Pt.dataset.frame=v,Pt.dataset.dir=pt,j.appendChild(Pt)}M.appendChild(j),Re.set(v,j)}const we=ar(v);j.style.setProperty("--frame-line",we.line),j.style.setProperty("--frame-bg",we.bg),j.style.left=`${D.x}px`,j.style.top=`${D.y}px`,j.style.width=`${D.w}px`,j.style.height=`${D.h}px`;const V=j.querySelector(".ttl"),J=j.querySelector(".cnt"),re=j.querySelector(".route"),ge=vt.has(v),Ye=ge?fn(v):v;V.textContent!==Ye&&(V.textContent=Ye),j.classList.toggle("is-roster",ge);let We=0,De=0;for(const me of t.allNodes())me.memberships.find(at=>at.team===v)!==void 0&&(We+=1,me.memberships.length>1&&(De+=1));const ot=`${We} 成员`+(De>0?` +${De} 跨队`:"");J.textContent!==ot&&(J.textContent=ot);const y=Cr(dt.get(v),Ke.has(v)),Ne=y!==void 0&&It.hosts.has(Ct(dt.get(v))),ke=(y==null?void 0:y.text)??((b=it.find(me=>me.name===v))==null?void 0:b.team)??v;re.textContent!==ke&&(re.textContent=ke),re.title=`${(y==null?void 0:y.title)??""}${Ne?` · ${dn}`:""}`,Yr(j,Ne),j.classList.toggle("is-mirror",y!==void 0),j.classList.toggle("is-syncing",(y==null?void 0:y.syncing)===!0);const tt=`团队框 ${v}${y!==void 0?`(${y.text})`:""}${Ne?`(${dn})`:""}(拖动整组,回车菜单)`,je=j.querySelector(".p-frame-head");je.getAttribute("aria-label")!==tt&&je.setAttribute("aria-label",tt)}for(const[v,D]of[...Re])a.has(v)||(D.remove(),Re.delete(v))}function mt(){const a=new Set;for(const b of t.allNodes()){a.add(b.id);let v=gt.get(b.id);v===void 0&&(v=jr(b.id),z.appendChild(v),gt.set(b.id,v));const D=kt(b);v.style.left=`${D.x}px`,v.style.top=`${D.y}px`,v.classList.toggle("cold",!b.live),v.classList.toggle("remote",b.remote===!0);const j=b.live&&b.remote!==!0?F.get(b.id):void 0;v.classList.toggle("is-working",(j==null?void 0:j.status)==="running");const we=Dr(j),V=v.querySelector(".work");V.textContent!==we&&(V.textContent=we),v.classList.toggle("selected",t.isSelected(b.id)),v.setAttribute("aria-selected",String(t.isSelected(b.id)));const J=b.id.slice(5),re=Rr(b,b.remote===!0?O.get(J)??[]:[],ue.get(J)),ge=b.remote===!0&&(b.id.startsWith("member-")?It.members.has(b.id):It.hosts.has(J));v.classList.toggle("is-unreachable",ge);const Ye=v.querySelector(".nm-text");Ye.textContent!==re.title&&(Ye.textContent=re.title);const We=v.querySelector(".sub"),De=ge?`未应答 · ${re.sub}`:re.sub;We.textContent!==De&&(We.textContent=De);const ot=ge?`${re.tip} · ${dn}`:re.tip;v.title!==ot&&(v.title=ot);const y=b.id.startsWith("member-")?xe.get(b.remoteHandle??""):J;Hr(v.querySelector(".prio"),b,b.remote===!0&&y!==void 0?U.get(y):void 0)}for(const[b,v]of[...gt])a.has(b)||(v.remove(),gt.delete(b));Ue.refresh()}const l=Gs(f,t);let O=new Map,F=new Map;const ue=new Map,U=new Map;let xe=new Map;function Ce(){l.render(te())}function Se(){s=Dn(zs(t.contentBounds(),l.placements()),C.clientWidth||Pe,C.clientHeight||ye),Je(),N()}const fe=fr({model:t,viewSize:rt,setVp:a=>{s=a},applyViewport:Je,markDirty:N,cardEl:a=>gt.get(a)});function nt(a){var D;const b=a.sessions.filter(j=>j.live!==!1).length,v=(j,we,V)=>{const J=document.createElement("b");J.className=we,J.textContent=V,j.replaceChildren(J)};v(W,"ok",`● ${b} live`),v(q,"warn",`● ${a.sessions.length-b} cold`),K.textContent=`${((D=a.inFlight)==null?void 0:D.length)??0} inFlight`,Z.className="mut",Z.textContent=`${a.teams.length} 队 · ${a.peerCount} peer`}const Ke=new Map,ze=a=>{Ke.set(a,(Ke.get(a)??0)+1),i=-1},zt=a=>{i=-1;const b=(Ke.get(a)??0)-1;b<=0?Ke.delete(a):Ke.set(a,b)};let dt=new Map,vt=new Set,It=ho({});const Tt=Er(e.now);function yt(a){const b=a.type==="create-team"&&a.roster===!0||vt.has(Jt(a));if(b&&a.type==="remove-team"&&!window.confirm(`解散网络队「${fn(a.name)}」并撤回成员与白名单?`))return;if(b&&a.type==="reorder"){k("error","roster 队不支持置顶路由");return}if(b&&(a.type==="create-team"||a.type==="add-member")&&a.ids.some(V=>{var J;return((J=t.getNode(V))==null?void 0:J.remote)===!0||!B.some(re=>re.id===V&&re.joined===!0)})){k("error","roster 只接受本机已入网会话,远端或未入网成员未写入");return}function v(V){const J=re=>{var Ye;const ge=[];for(const We of re){if(!We.startsWith("peer-")&&!We.startsWith("member-")){ge.push(We);continue}const De=(Ye=t.getNode(We))==null?void 0:Ye.remoteHandle;De!==void 0&&De!==""&&ge.push(De)}return ge};if(V.type==="add-member"||V.type==="remove-member"||V.type==="create-team"){const re=J(V.ids),ge=V.type!=="create-team"?dt.get(V.team):void 0;return re.length>0||ge!==void 0?{...V,ids:re,...ge!==void 0?{fleetPeer:ge}:{}}:V}return V.type==="remove-team"&&dt.has(V.name)?Tt.fork(V,dt.get(V.name)):V}if(a.type==="add-member"||a.type==="remove-member"||a.type==="reorder"||a.type==="create-team"){const V=a.type==="reorder"?a.ops.map(J=>J.id):[...a.ids];for(const J of V){if(J===""||J.startsWith("peer-")||J.startsWith("member-")||t.getNode(J)!==void 0)continue;const re=B.find(We=>We.id===J);if(re===void 0)continue;const ge=n==null?void 0:n.nodes[J],Ye=ge!==void 0?{x:ge.x,y:ge.y}:Te(J);t.upsertNode({id:J,x:Ye.x,y:Ye.y,label:re.label,team:re.team,name:re.name,description:re.description,live:re.live!==!1,memberships:[],...re.teams!==void 0&&re.teams.length>0?{teams:re.teams}:{}})}}b&&a.type==="create-team"&&vt.add(a.name);const D=rr(t,a),j=Jt(a);ze(j),Fe();const we=v(b?{...a,roster:!0}:a);e.onCanvasAction(we).then(V=>{zt(j),!V&&a.type==="create-team"&&b&&vt.delete(j),n=co(t,a,V,D,n),N(),Tt.settled(we,V),Fe()},()=>{zt(j),a.type==="create-team"&&b&&vt.delete(j),n=co(t,a,!1,D,n),N(),Tt.settled(we,!1),k("error","操作通道异常,已回滚"),Fe()})}function k(a,b){var D;for(;ve.childElementCount>=3;)(D=ve.firstElementChild)==null||D.remove();const v=document.createElement("div");v.className="p-notice"+(a==="error"?" error":""),v.setAttribute("role",a==="error"?"alert":"status"),v.textContent=b,ve.appendChild(v),ie.push(setTimeout(()=>v.remove(),4e3))}const g=dr({root:C,netBtn:be,signal:L,model:t,teams:()=>it,joined:a=>B.some(b=>b.id===a&&b.joined===!0),isRoster:a=>vt.has(a),anchorFor:a=>(a.kind==="node"?gt.get(a.id):Re.get(a.name))??null,emit:yt,notice:k});let B=[],P=new Set;const Y=Or({root:C,trigger:w,signal:L,model:t,facts:()=>({sessions:B,canvasMemberIds:P,remoteTeams:O,teams:it}),menuItem:g.menuItem,emit:yt,openNameDialog:g.openNameDialog,locate:Q});ps(C,{signal:L,frames:()=>Re,frameAt:(a,b)=>{const v=de({clientX:a,clientY:b});return nn(new Map(t.allFrames()),wt(s,v.x,v.y))},drop:(a,b)=>{var v;return((v=t.getNode(b))==null?void 0:v.memberships.some(D=>D.team===a))===!0?k("info","该会话已在这个队里"):yt({type:"add-member",team:a,ids:[b]})}});function Q(a){var D;const b=t.getNode(a);if(b===void 0)return;Y.close();const v=((D=e.viewSize)==null?void 0:D.call(e))??{w:C.clientWidth>0?C.clientWidth:800,h:C.clientHeight>0?C.clientHeight:600};s=Rt({scale:s.scale,x:b.x-v.w/(2*s.scale),y:b.y-v.h/(2*s.scale)}),Je(),i=-1,Fe()}function de(a){const b=C.getBoundingClientRect();return{x:a.clientX-b.left,y:a.clientY-b.top}}function pe(a,b){var V;const v=de(b),D=wt(s,v.x,v.y),j=nn(new Map(t.allFrames()),D),we=a.ids.filter(J=>{const re=t.getNode(J);return re===void 0?!1:re.remote!==!0?!0:re.remoteHandle!==void 0&&re.remoteHandle!==""});if(j!==void 0){const J=we.filter(re=>{var ge;return!((ge=t.getNode(re))!=null&&ge.memberships.some(Ye=>Ye.team===j))});if(J.length>0){yt({type:"add-member",team:j,ids:J});return}if(a.ids.length===1&&((V=t.getNode(a.clicked))==null?void 0:V.remote)!==!0){const re=t.teamMemberIds(j),ge=ir(t,j);ge.join("\0")!==re.join("\0")&&yt({type:"reorder",team:j,ops:An(re,ge)})}}if(a.rosterOrigin!==void 0&&j!==a.rosterOrigin){const J=a.ids.filter(re=>t.teamMemberIds(a.rosterOrigin).includes(re));J.length>0&&yt({type:"remove-member",team:a.rosterOrigin,ids:J})}}function ee(a){if(Pe===0&&qe(),g.isDialogOpen()){a.preventDefault();return}const b=a.target;if(g.isMenuOpen()){if(b!==null&&b.closest(".p-menu")!==null)return;g.closeMenu(),a.preventDefault();return}if(b!==null&&b.closest("button, input, textarea, select, .p-toolbar, .p-search, .p-lamp, .p-status, .p-legend")!==null)return;h=u.capture();const v=de(a);if(a.button===2){S={x:v.x,y:v.y,target:a.target,moved:!1},a.preventDefault();try{C.setPointerCapture(a.pointerId??0)}catch{}return}const D=b!==null?b.closest(".p-node"):null,j=b!==null?b.closest(".p-frame-head"):null;if((D!==null||j!==null)&&a.button===1){o={kind:"pan",last:v,moved:!1},a.preventDefault();try{C.setPointerCapture(a.pointerId??0)}catch{}return}const we=b!==null?b.closest(".p-frame-handle"):null;if(p!==void 0){const V=Re.get(p),J=b!==null&&V!==void 0&&(V.contains(b)||V===b),re=j!==null&&j.dataset.frame===p;!J&&!re&&H(void 0)}if(we!==null&&a.button===0){const V=we.dataset.frame??"";H(V);const J=t.getFrame(V);if(J===void 0)return;o={kind:"frame-resize",name:V,dir:we.dataset.dir??"se",startRect:{...J},origin:wt(s,v.x,v.y),moved:!1},a.preventDefault();try{C.setPointerCapture(a.pointerId??0)}catch{}return}if(D!==null){if(a.button!==0)return;const V=D.dataset.id??"",J=t.isSelected(V);!J&&!a.shiftKey&&t.setSelection([V]);const re=a.shiftKey||J?t.isSelected(V)?t.selectedIds():[...t.selectedIds(),V]:[V],ge=nn(new Map(t.allFrames()),wt(s,v.x,v.y));o={kind:"node",clicked:V,ids:re,...ge&&vt.has(ge)&&t.teamMemberIds(ge).includes(V)?{rosterOrigin:ge}:{},last:wt(s,v.x,v.y),moved:!1,el:D},D.classList.add("dragging")}else if(j!==null){if(a.button!==0)return;const V=j.dataset.frame??"";H(V);const J=t.beginFrameDrag(V);if(J===void 0)return;o={kind:"frame",name:V,snap:J,origin:wt(s,v.x,v.y),moved:!1}}else if(a.button===1||a.button===0&&r)o={kind:"pan",last:v,moved:!1};else if(a.button===0)o={kind:"marquee",origin:v,last:v,additive:a.shiftKey},G.style.display="block",G.style.left=`${v.x}px`,G.style.top=`${v.y}px`,G.style.width="0px",G.style.height="0px";else return;a.preventDefault();try{C.setPointerCapture(a.pointerId??0)}catch{}}function Me(a){const b=de(a);if(S!==null){const v=b.x-S.x,D=b.y-S.y;Math.hypot(v,D)>4&&(S.moved=!0,s=Rt(Cn(s,-v,-D)),S.x=b.x,S.y=b.y,Je());return}if(o.kind==="node"){const v=wt(s,b.x,b.y),D=v.x-o.last.x,j=v.y-o.last.y;if(D===0&&j===0)return;o.moved=!0,o.last=v,t.dragNodes(o.ids,D,j);const we=nn(new Map(t.allFrames()),v),V=o.ids.filter(re=>{const ge=t.getNode(re);return ge===void 0?!1:ge.remote!==!0||ge.remoteHandle!==void 0&&ge.remoteHandle!==""}),J=we!==void 0&&V.length>0;for(const[re,ge]of Re)ge.classList.toggle("drop-target",J&&re===we);Fe()}else if(o.kind==="frame"){const v=wt(s,b.x,b.y),D=v.x-o.origin.x,j=v.y-o.origin.y;if(!o.moved&&D===0&&j===0)return;o.moved=!0,t.applyFrameDrag(o.snap,D,j),Fe()}else if(o.kind==="frame-resize"){const v=wt(s,b.x,b.y),D=v.x-o.origin.x,j=v.y-o.origin.y;if(!o.moved&&D===0&&j===0)return;o.moved=!0;const we=220,V=120,J={...o.startRect};let{x:re,y:ge,w:Ye,h:We}=J;o.dir.includes("e")&&(Ye=Math.max(we,J.w+D)),o.dir.includes("s")&&(We=Math.max(V,J.h+j)),o.dir.includes("w")&&(Ye=Math.max(we,J.w-D),re=J.x+(J.w-Ye)),o.dir.includes("n")&&(We=Math.max(V,J.h-j),ge=J.y+(J.h-We)),t.setFrame(o.name,{x:Math.round(re),y:Math.round(ge),w:Math.round(Ye),h:Math.round(We)}),Fe()}else if(o.kind==="pan")s=Cn(s,b.x-o.last.x,b.y-o.last.y),o.last=b,o.moved=!0,Je();else if(o.kind==="marquee"){const v=Math.min(o.origin.x,b.x),D=Math.min(o.origin.y,b.y);G.style.left=`${v}px`,G.style.top=`${D}px`,G.style.width=`${Math.abs(b.x-o.origin.x)}px`,G.style.height=`${Math.abs(b.y-o.origin.y)}px`,o.last=b}}function Xe(a){var b,v;if(S!==null){const D=S.moved,j=S.target,we=S.x,V=S.y;S=null,D?(E=!0,N()):j!==null&&g.contextMenuAt(we,V,j);return}if(o.kind==="node"){const D=o.clicked;if(o.moved)pe(o,a),N();else if(a.shiftKey){const j=t.selectedIds();t.setSelection(j.includes(D)?j.filter(we=>we!==D):[...j,D])}else t.setSelection([D]),(b=e.onNodePick)==null||b.call(e,D);for(const j of Re.values())j.classList.remove("drop-target");(v=o.el)==null||v.classList.remove("dragging"),Fe()}else if(o.kind==="frame"||o.kind==="frame-resize")o.moved&&(sn(t,new Set(dt.keys()),o.name),N(),Fe());else if(o.kind==="pan")o.moved&&N();else if(o.kind==="marquee"){const D=o.last,j=wt(s,Math.min(o.origin.x,D.x),Math.min(o.origin.y,D.y)),we=wt(s,Math.max(o.origin.x,D.x),Math.max(o.origin.y,D.y));t.marqueeSelect({x:j.x,y:j.y,w:we.x-j.x,h:we.y-j.y},o.additive),G.style.display="none",Fe()}o={kind:"none"},h!==void 0&&(u.commit(h),h=void 0);try{C.releasePointerCapture(a.pointerId??0)}catch{}}function Be(a){var v;for(const D of Re.values())D.classList.remove("drop-target");o.kind==="node"&&((v=o.el)==null||v.classList.remove("dragging"));const b=o.kind==="pan"&&o.moved||(S==null?void 0:S.moved)===!0;G.style.display="none",S=null,o={kind:"none"},h!==void 0&&u.revert(h)&&Fe(),b&&N(),h=void 0;try{C.releasePointerCapture(a.pointerId??0)}catch{}}function ct(a){g.isMenuOpen()&&g.closeMenu();const b=de(a);if(a.shiftKey&&!a.ctrlKey){const v=a.deltaMode===1?16:1;s=Rt(Cn(s,(a.deltaX??0)*v,(a.deltaY??0)*v))}else{const v=a.deltaMode===1?16:1,D=Math.exp(-((a.deltaY??0)*v)*.0015);s=oo(s,D,b.x,b.y)}a.preventDefault(),Je(),N()}function $t(a){qe(),s=oo(s,a,Pe/2,ye/2),Je(),N()}function Nt(){u.undo()?(N(),Fe()):k("info","没有可撤销的布局改动")}function Mt(){qe(),s=io(ro(t.contentBounds(),t.allNodes()),Pe,ye,ao(Ee,T)),Je(),N()}function X(a){var we,V,J,re,ge,Ye,We;if(g.isDialogOpen()||((V=(we=a.target)==null?void 0:we.closest)==null?void 0:V.call(we,".p-search"))!==null)return;if((a.ctrlKey||a.metaKey)&&a.key.toLowerCase()==="k"){a.preventDefault(),Ue.focus();return}if((a.ctrlKey||a.metaKey)&&!a.shiftKey&&a.key.toLowerCase()==="z"){a.preventDefault(),Nt();return}if(a.ctrlKey||a.metaKey)return;if(g.isMenuOpen()){a.key==="Escape"&&(g.closeMenu(),a.preventDefault());return}if(a.key===" "&&a.target===C){r=!0,a.preventDefault();return}const b=((re=(J=a.target)==null?void 0:J.closest)==null?void 0:re.call(J,".p-frame-head"))??null;if((a.key==="Enter"||a.key===" ")&&b!==null){a.preventDefault();const De=b.getBoundingClientRect();g.contextMenuAt(De.left+De.width/2,De.top+De.height/2,b);return}if(a.key===" "&&((Ye=(ge=a.target)==null?void 0:ge.classList)!=null&&Ye.contains("p-node"))){const ot=a.target.dataset.id??"",y=t.selectedIds();t.setSelection(y.includes(ot)?y.filter(Ne=>Ne!==ot):[...y,ot]),Fe(),a.preventDefault();return}if(a.key==="F10"&&a.shiftKey||a.key==="ContextMenu"){a.preventDefault();const De=document.activeElement??null,ot=((We=De==null?void 0:De.getBoundingClientRect)==null?void 0:We.call(De))??{left:0,top:0,width:0,height:0};g.contextMenuAt(ot.left+ot.width/2,ot.top+ot.height/2,De);return}if(a.key==="Delete"||a.key==="Backspace"){a.preventDefault(),he();return}if(a.altKey&&(a.key==="ArrowUp"||a.key==="ArrowDown")){a.preventDefault(),Ie(a.key==="ArrowUp");return}if(a.key==="g"||a.key==="G"){g.startCreateFromSelection();return}if(a.key==="0"){Mt();return}if(a.key==="="||a.key==="+"){$t(1.2);return}if(a.key==="-"){$t(1/1.2);return}if(a.key==="Escape"){if(g.isMenuOpen()){g.closeMenu(),Fe();return}t.setSelection([]),Fe();return}const v=a.shiftKey?40:8,j={ArrowLeft:[-v,0],ArrowRight:[v,0],ArrowUp:[0,-v],ArrowDown:[0,v]}[a.key];if(j!==void 0){a.preventDefault();const De=t.selectedIds();if(De.length>0){const ot=u.capture();t.nudge(De,j[0],j[1]),u.commit(ot),Fe(),N()}}}function he(){var D,j,we;const a=document.activeElement,b=((D=a==null?void 0:a.closest)==null?void 0:D.call(a,".p-frame-head"))??null,v=((j=a==null?void 0:a.closest)==null?void 0:j.call(a,".p-node"))??null;if(b!==null){yt({type:"remove-team",name:b.dataset.frame??""});return}if(v!==null){const V=v.dataset.id??"",J=((we=t.getNode(V))==null?void 0:we.memberships.map(re=>re.team))??[];if(J.length===0){k("info","该节点未加入任何团队");return}if(J.length===1){yt({type:"remove-member",team:J[0],ids:[V]});return}g.openMenu(window.innerWidth/2,window.innerHeight/2,{kind:"node",id:V},"leave",v);return}k("info","焦点不在节点或团队框上")}function Ie(a){var Ye,We;const b=document.activeElement,v=((Ye=b==null?void 0:b.closest)==null?void 0:Ye.call(b,".p-node"))??null;if(v===null)return;const D=v.dataset.id??"",j=((We=t.getNode(D))==null?void 0:We.memberships)??[];if(j.length!==1)return;const we=j[0].team,V=t.teamMemberIds(we),J=V.indexOf(D),re=a?Math.max(0,J-1):Math.min(V.length-1,J+1);if(re===J)return;const ge=[...V];ge.splice(J,1),ge.splice(re,0,D),yt({type:"reorder",team:we,ops:An(V,ge)})}function _e(a){a.key===" "&&(r=!1)}C.addEventListener("pointerdown",a=>ee(a),L),C.addEventListener("pointermove",a=>Me(a),L),C.addEventListener("pointerup",a=>Xe(a),L),C.addEventListener("pointercancel",a=>Be(a),L),C.addEventListener("wheel",a=>ct(a),{...L,passive:!1}),C.addEventListener("keydown",a=>X(a),L),C.addEventListener("keyup",a=>_e(a),L),C.addEventListener("contextmenu",a=>{var v,D;const b=a;if(((D=(v=b.target)==null?void 0:v.closest)==null?void 0:D.call(v,"input, textarea, .p-search"))==null){if(b.preventDefault(),E){E=!1;return}g.contextMenuAt(b.clientX,b.clientY,b.target)}},L);let it=[];function Qe(a){var ot;it=a.teams,vt=new Set([...a.teams.filter(y=>y.kind==="roster").map(y=>y.name),...[...vt].filter(y=>Ke.has(y))]),a.peers,l.setInFlight(a.inFlight??[]),B=a.sessions,g.setUnjoined(a.sessions.filter(y=>y.joined!==!0&&!y.id.startsWith("peer-")));const b=Zs(a.teams);P=new Set(b.keys());const v=new Set,D=y=>{const Ne=b.get(y)??[];if(Ke.size===0)return Ne;const ke=Ne.filter(je=>!Ke.has(je.team)),tt=[];for(const[je]of Ke){const Ve=t.teamMemberIds(je).indexOf(y);Ve>=0&&tt.push({team:je,index:Ve})}return[...ke,...tt]};let j;if(n===void 0&&!t.allNodes().some(y=>y.remote!==!0)){const y=a.sessions.filter(Ne=>{var ke;return Ne.joined===!0&&(D(Ne.id).length>0||(((ke=Ne.teams)==null?void 0:ke.length)??0)>0)}).map(Ne=>Ne.id);qe(),j=Ps(a.teams,y,Pe>0?Pe:void 0)}const we=a.peerOrg!==void 0?er(a.peerOrg,a.sessions,a.remoteTeams):new Set;a.peerOrg!==void 0&&(P=new Set([...P,...we]));for(const y of a.sessions){if(y.joined!==!0)continue;const Ne=D(y.id);if(!(Ne.length===0&&(y.teams===void 0||y.teams.length===0)&&!we.has(y.id)))if(v.add(y.id),t.getNode(y.id)!==void 0)t.upsertNode({id:y.id,x:t.getNode(y.id).x,y:t.getNode(y.id).y,label:y.label,team:y.team,name:y.name,description:y.description,live:y.live!==!1,memberships:Ne,...y.teams!==void 0&&y.teams.length>0?{teams:y.teams}:{}});else{const ke=n==null?void 0:n.nodes[y.id];let tt,je;if(ke!==void 0)tt=ke.x,je=ke.y;else{const me=(j==null?void 0:j.get(y.id))??Te(y.id);tt=me.x,je=me.y}t.upsertNode({id:y.id,x:tt,y:je,label:y.label,team:y.team,name:y.name,description:y.description,live:y.live!==!1,memberships:Ne,...y.teams!==void 0&&y.teams.length>0?{teams:y.teams}:{}})}}for(const y of t.nodeIds())!v.has(y)&&!y.startsWith("peer-")&&!y.startsWith("member-")&&t.removeNode(y);const V=new Set;O=Bs(a.remoteTeams??[]),xe=new Map([...O].flatMap(([y,Ne])=>Ne.map(ke=>[ke.team,y]))),F=new Map(a.sessions.map(y=>[y.id,{status:y.status,queued:y.queued}])),It=ho(a),ue.clear();for(const y of a.peers??[])ue.set(Ct(y.url),y.score),U.set(Ct(y.url),{link:y.link,verified:y.verified});if(a.peers!==void 0){const y=t.contentBounds(),Ne=Xs(a.peers,y);a.peers.forEach((ke,tt)=>{var jn,Hn,Bn;const je=Hs(ke.url);V.add(je);const me=n==null?void 0:n.nodes[je],Ve=t.getNode(je),at=Ve!==void 0?{x:Ve.x,y:Ve.y}:me!==void 0?{x:me.x,y:me.y}:{x:((jn=Ne[tt])==null?void 0:jn.x)??200,y:((Hn=Ne[tt])==null?void 0:Hn.y)??0},ft=Ct(ke.url),pt=(Bn=O.get(ft))==null?void 0:Bn.find(Bo=>Bo.team.includes("/")),Pt=(pt==null?void 0:pt.memberRef)??(pt==null?void 0:pt.team);t.upsertNode({id:je,x:at.x,y:at.y,label:ke.url,team:"",name:ke.url,peerUrl:ke.url,remoteHandle:Pt,live:!0,remote:!0,memberships:[]}),t.upsertScore(je,ke.score)})}for(const y of t.nodeIds())y.startsWith("peer-")&&!V.has(y)&&t.removeNode(y);const J=new Set;for(const[y,Ne]of O){const ke=t.allNodes().find(me=>me.remote===!0&&Ct(me.peerUrl??"")===y&&!me.id.startsWith("member-")),tt=((ke==null?void 0:ke.x)??400)+190;let je=(ke==null?void 0:ke.y)??0;for(const me of Ne){if(!me.team.includes("/"))continue;const Ve=`member-${(me.memberRef??me.team).replace(/[^a-z0-9-]/gi,"-")}`;if(J.has(Ve))continue;J.add(Ve);const at=n==null?void 0:n.nodes[Ve],ft=t.getNode(Ve),pt=ft!==void 0?{x:ft.x,y:ft.y}:at!==void 0?{x:at.x,y:at.y}:{x:tt,y:je};je+=92,t.upsertNode({id:Ve,x:pt.x,y:pt.y,label:me.team,team:me.team,name:me.name!==void 0&&me.name!==""?me.name:me.team,remoteHandle:me.memberRef??me.team,live:!0,remote:!0,memberships:[]})}}for(const y of t.nodeIds())y.startsWith("member-")&&!J.has(y)&&t.removeNode(y);const re=new Map;for(const y of t.allNodes())y.remote!==!0||y.remoteHandle===void 0||y.remoteHandle===""||(!re.has(y.remoteHandle)||y.id.startsWith("member-"))&&re.set(y.remoteHandle,y.id);for(const y of a.teams){if(Ke.has(y.name))continue;const Ne=[];for(const je of y.members){const me=re.get(je.id)??je.id;t.getNode(me)!==void 0&&Ne.push(me)}const ke=[...t.teamMemberIds(y.name)].sort().join("|"),tt=[...Ne].sort().join("|");ke!==tt&&t.setTeamMembers(y.name,Ne)}const ge=new Map,Ye=dt;if(dt=ge,a.peerOrg!==void 0){let y=0;const Ne=new Set(a.teams.map(ke=>ke.name));Tt.sweep(a.peerOrg);for(const ke of a.peerOrg){const tt=new Set((a.remoteTeams??[]).map(me=>me.team)),je=_o(a.sessions,tt);for(const me of ke.org){if(me.name===""||Ne.has(me.name)||Tt.hides(me.name,ke.url))continue;const Ve=me.members.map(ft=>Qs(ft,je,a.remoteTeams,ke.url)).filter(ft=>t.getNode(ft)!==void 0),at=(ot=n==null?void 0:n.frames)==null?void 0:ot[me.name];t.getFrame(me.name)===void 0&&t.setFrame(me.name,at!==void 0?{x:at.x,y:at.y,w:at.w,h:at.h}:{x:200+y%4*280,y:940+Math.floor(y/4)*160,w:250,h:130}),t.setTeamMembers(me.name,Ve),ge.set(me.name,ke.url),y+=1}}}for(const[y,Ne]of Ye)ge.has(y)||t.removeFrame(y);const We=new Map;for(const y of t.allNodes())y.remote===!0&&y.remoteHandle!==void 0&&y.remoteHandle!==""&&We.set(y.remoteHandle,y.id);const De=Lo(a.teams);for(const y of a.teams){if(t.getFrame(y.name)!==void 0||Ke.has(y.name))continue;const Ne=n==null?void 0:n.frames[y.name];if(Ne!==void 0){t.setFrame(y.name,{...Ne});continue}const ke=[],tt=[];for(const me of y.members){const Ve=t.getNode(We.get(me.id)??me.id);Ve!==void 0&&(tt.push(kt(Ve)),De.get(Ve.id)===y.name&&ke.push(kt(Ve)))}const je=ke.length>0?ke:tt;je.length>0&&t.setFrame(y.name,Fn(je))}for(const[y]of t.allFrames())Ke.has(y)||!a.teams.some(Ne=>Ne.name===y)&&!ge.has(y)&&t.removeFrame(y);if(Y.refresh(),nt(a),!d&&o.kind==="none"&&t.nodeIds().length>0){d=!0;const y=u.capture();sn(t,new Set(dt.keys())),u.commit(y)}c&&o.kind==="none"&&t.nodeIds().length>0&&(qe(),Pe>0&&ye>0&&(c=!1,s=io(ro(t.contentBounds(),t.allNodes()),Pe,ye,ao(Ee,T)))),Fe()}function Te(a){return Io(a,t.allNodes().filter(b=>b.remote!==!0))}function St(a){const b=Mo(a);if(b===void 0)return;n=b;const v=e.viewportStore;if(v===void 0)c=!1,o.kind==="none"&&(s=Rt({...b.viewport}));else if(!m&&o.kind==="none"){m=!0;const D=v.get($());D!=null&&Number.isFinite(D.x)&&Number.isFinite(D.y)&&Number.isFinite(D.scale)?(s=Rt({x:D.x,y:D.y,scale:D.scale}),c=!1):$()==="wide"&&(s=Rt({...b.viewport}),c=!1)}i=-1,Fe()}function Bt(){return Is(s,t.positions(),t.frameRects())}function Ro(a,b){A.classList.remove("pending","saved","error"),a==="pending"&&A.classList.add("pending"),a==="saved"&&A.classList.add("saved"),a==="error"&&A.classList.add("error"),a==="error"?(A.tabIndex=0,A.setAttribute("role","button"),A.setAttribute("aria-label","布局保存失败,按回车重试")):(A.removeAttribute("tabindex"),A.removeAttribute("role"),A.removeAttribute("aria-label"));const v=a==="pending"?"布局待保存…":a==="saved"?`布局已保存 ${b??""}`.trimEnd():a==="error"?"保存失败 · 回车重试":"布局";I.textContent=v}function Do(){C.style.display="block",qe(),Je(),C.focus()}function jo(){C.style.display="none"}function Ho(){le.abort();for(const a of ie)clearTimeout(a)}return{root:C,reconcile:Qe,activate:Do,deactivate:jo,adoptExternalLayout:St,snapshotDoc:Bt,setLamp:Ro,notice:k,destroy:Ho,seam:{pointerDown:ee,pointerMove:Me,pointerUp:Xe,pointerCancel:Be,wheel:ct,key:X,keyUp:_e,contextMenu(a){a.preventDefault(),g.contextMenuAt(a.clientX,a.clientY,a.target)}}}}const Kr=800;function Xr(e){let t,n=!1,s=!1,o=!1,r="idle";function i(h){h!==r&&(r=h,e.onLamp(h))}function c(){t!==void 0&&(t(),t=void 0)}function d(){c(),t=e.schedule(()=>{t=void 0,u(!1)},Kr)}async function u(h){if(n){s=!0;return}n=!0,c();const m=e.snapshot();let $;try{$=JSON.stringify(m)}catch{n=!1,i("error"),e.onHttpError("layout document is not JSON-serializable");return}try{const N=await e.send(m,{keepalive:h});if(N===null||typeof N!="object"||N.ok!==!0){i("error");const te=N!==null&&typeof N=="object"&&typeof N.error=="string"?N.error:"layout save refused";e.onHttpError(`layout save: ${te}`)}else JSON.stringify(e.snapshot())===$&&(e.onAdopt(N.layout),i("saved"))}catch(N){i("error"),e.onHttpError(`layout save unreachable: ${String((N==null?void 0:N.message)??N).slice(0,80)}`)}if(n=!1,r==="error"){o=!1;return}if(o){o=!1,u(!0);return}s&&(s=!1,i("pending"),d())}return{markDirty(){if(s=!1,i("pending"),n){s=!0;return}d()},retry(){r!=="error"||n||(i("pending"),u(!1))},flush(){if(n){o=!0,s=!0;return}c(),u(!0)},isBusy(){return n},dispose(){c()}}}function bo(e){return e!=null&&typeof e.error=="string"?e.error:void 0}function Ur(e){const t=new Map;let n=0;function s(i,c){n+=1;const d=t.get(i)??Promise.resolve(),u=async()=>{try{return await c()}finally{n-=1}},h=d.then(u,u);return t.set(i,h.then(()=>{},()=>{})),h}async function o(i){var le,ie,S,E;let c;try{c=await e.send(i)}catch(L){const C=String((L==null?void 0:L.message)??L).slice(0,80);return e.onNotice("error",`画布不可达:${C}`),!1}if(c.status>=400)return e.onNotice("error",bo(c.body)??`HTTP ${c.status}`),!1;if(((le=c.body)==null?void 0:le.ok)===!0)return!0;const d=c.body!=null&&typeof c.body=="object"?bo(c.body):void 0;if(d!==void 0)return e.onNotice("error",d),!1;const u=String(i.name??""),h=String(i.id??""),m=(ie=c.body)==null?void 0:ie.members,$=(S=c.body)==null?void 0:S.teams,N=Array.isArray(m)&&m.every(L=>typeof L=="string"),te=Array.isArray($)&&$.every(L=>typeof L=="string");return((E=c.body)==null?void 0:E.ok)===!1&&(i.action==="add-member"&&N&&m.includes(h)||i.action==="remove-member"&&N&&!m.includes(h)||i.action==="remove"&&te&&!$.includes(u))?!0:(e.onNotice("error","画布操作未确认:"+String(i.action)+"(可能队伍/成员已达上限,请重试)"),!1)}async function r(i,c){for(const d of c)if(!await o({...i,id:d}))return!1;return!0}return{createTeam(i,c){return s(i,async()=>{if(!await o({action:"create",name:i}))return!1;for(let d=0;d<c.length;d++)if(!await o({action:"add-member",name:i,id:c[d]}))return!1;return!0})},addMembers(i,c){return s(i,()=>r({action:"add-member",name:i},c))},removeMembers(i,c){return s(i,()=>r({action:"remove-member",name:i},c))},runRosterOps(i,c){return s(i,async()=>{for(const d of c){const u=d.op==="remove"?{action:"remove-member",name:i,id:d.id}:{action:"add-member",name:i,id:d.id};if(!await o(u))return!1}return!0})},removeTeam(i){return s(i,()=>o({action:"remove",name:i}))},hasPending(){return n>0}}}const Po=document.getElementById("app"),Jr=(()=>{try{return window.sessionStorage.getItem("dsh_a2a_key")??""}catch{return""}})(),Ln=window.__DSH_A2A_KEY__??Jr,Ze=(e,t={})=>fetch(e,{...t,headers:{...t.headers??{},...Ln!==""?{"X-API-Key":Ln}:{}}});Ln===""&&Ze("/__dsh_a2a/owner-settings").then(e=>{if(e.status!==401)return;const t=document.createElement("div");t.className="nexus-keygate",t.style.cssText="position:fixed;inset:0;display:flex;align-items:center;justify-content:center;flex-direction:column;gap:10px;background:#fff;z-index:9999;font:14px/1.5 system-ui,sans-serif;color:#000";const n=document.createElement("div");n.textContent="此面板经远程面打开(密钥不随页面下发)——输入控制密钥";const s=document.createElement("input");s.type="password",s.placeholder="X-API-Key",s.setAttribute("aria-label","控制密钥");const o=document.createElement("button");o.type="button",o.textContent="进入面板";const r=document.createElement("div");r.style.color="#b00";const i=()=>{const c=s.value.trim();c!==""&&fetch("/__dsh_a2a/owner-settings",{headers:{"X-API-Key":c}}).then(d=>{if(d.status===401){r.textContent="密钥不对,再试一次";return}try{window.sessionStorage.setItem("dsh_a2a_key",c)}catch{}window.location.reload()})};o.addEventListener("click",i),s.addEventListener("keydown",c=>{c.key==="Enter"&&i()}),t.append(n,s,o,r),document.body.appendChild(t)});const Xt=document.createElement("div");Xt.className="nexus-fault";Po.appendChild(Xt);const{fault:In,clear:zr}=qo({show(e){Xt.textContent=e,Xt.style.display="block"},hide(){Xt.style.display="none"}},e=>console.error(e));let ln;const go="dsh-a2a.viewport.",Vr={get(e){try{const t=window.localStorage.getItem(go+e);return t===null?void 0:JSON.parse(t)}catch{return}},set(e,t){try{window.localStorage.setItem(go+e,JSON.stringify({x:t.x,y:t.y,scale:t.scale}))}catch{}}},Tn=As(),ut=qr({decorate:(e,t)=>Tn.decorate(e,t),viewportStore:Vr,onDirty:()=>hn.markDirty(),onLampClick:()=>hn.retry(),onNodePick:e=>{ln==null||ln(e)},onCanvasAction:async e=>{const t=await Qr(e);return gn(),t}}),hn=Xr({snapshot:()=>ut.snapshotDoc(),send:(e,t)=>Ze("/__dsh_a2a/canvas-layout",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({action:"save",layout:e}),cache:"no-store",keepalive:t.keepalive}).then(async n=>await n.json()),schedule:(e,t)=>{const n=setTimeout(e,t);return()=>{clearTimeout(n)}},now:Date.now,onLamp:e=>{_n=e;const t=new Date,n=String(t.getHours()).padStart(2,"0")+":"+String(t.getMinutes()).padStart(2,"0");ut.setLamp(e,n)},onAdopt:e=>{ut.adoptExternalLayout(e)},onHttpError:e=>In(e)});window.addEventListener("pagehide",()=>hn.flush());const qt=Ur({send:async e=>{const t=await Ze("/__dsh_a2a/canvas",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(e),cache:"no-store"});return{status:t.status,body:await t.json()}},onNotice:(e,t)=>ut.notice(e,t)});async function vo(e,t,n,s){const o=await Ze("/__dsh_a2a/fleet-canvas-op",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({peer:e,op:t,name:n,...s!==void 0?{id:s}:{}}),cache:"no-store"}).catch(()=>{}),r=o!==void 0?await o.json().catch(()=>{}):void 0;return(r==null?void 0:r.ok)===!0&&t==="remove"&&r.removed===!1&&ut.notice("info",`属主那边已没有「${n}」,无需解散`),(r==null?void 0:r.ok)===!0?!0:(ut.notice("error",`跨主机团队操作失败:${String((r==null?void 0:r.error)??"对端无响应")}`),!1)}async function Gr(e,t){const n=async s=>{const o=await Ze("/__dsh_a2a/roster-op",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({name:t,...s})}).catch(()=>{}),r=o!==void 0?await o.json().catch(()=>{}):void 0;return o!=null&&o.ok&&(r==null?void 0:r.ok)===!0?!0:(ut.notice("error",`roster 操作失败:${String((r==null?void 0:r.error)??(o?`HTTP ${o.status}`:"无响应"))}`),!1)};if(e.type==="create-team")return n({op:"create",ids:e.ids});if(e.type==="remove-team")return n({op:"dissolve"});if(e.type==="add-member"||e.type==="remove-member"){for(const s of e.ids)if(!await n({op:e.type,id:s}))return!1;return!0}return ut.notice("error","roster 不支持该操作"),!1}function Qr(e){if((e.type==="add-member"||e.type==="remove-member")&&e.fleetPeer!==void 0){const t=e.fleetPeer;return(async()=>{for(const n of e.ids)if(!await vo(t,e.type,e.team,n))return!1;return!0})()}if(e.type==="remove-team"&&e.fleetPeer!==void 0)return vo(e.fleetPeer,"remove",e.name);if(e.roster===!0){const t=Oo(Jt(e));return t!==void 0?Gr(e,t):(ut.notice("error","无效的 roster 框名"),Promise.resolve(!1))}switch(e.type){case"create-team":return qt.createTeam(e.name,e.ids,e.created);case"add-member":return qt.addMembers(e.team,e.ids);case"remove-member":return qt.removeMembers(e.team,e.ids);case"remove-team":return qt.removeTeam(e.name);case"reorder":return qt.runRosterOps(e.team,e.ops);case"join-network":case"leave-network":return Zr(e.type==="join-network"?"join":"leave",e.id)}}async function Zr(e,t){const n=await Ze(`/__dsh_a2a/${e}`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({id:t}),cache:"no-store"}).catch(()=>{});return n!==void 0&&n.ok}let _n="idle",kn=new Set,yo=0,bn=!1,wo,En=!1;async function ei(){const e=await Ze("/__dsh_a2a/canvas-layout",{cache:"no-store"});if(!e.ok)throw new Error(`/__dsh_a2a/canvas-layout ${e.status}`);return(await e.json()).layout??null}const Ht=Es({now:()=>Date.now(),superagent:{async act(e){const t=await Ze("/__dsh_a2a/superagent",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(e)});try{return await t.json()}catch{return{ok:!1,error:`HTTP ${t.status}`}}},refresh(){Fo()}},async ownerSettingsRead(){try{return await(await Ze("/__dsh_a2a/owner-settings")).json()}catch{return{ok:!1,error:"unreachable"}}},async ownerSettingsWrite(e){try{return await(await Ze("/__dsh_a2a/owner-settings",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(e)})).json()}catch{return{ok:!1,error:"unreachable"}}},async abandon(e,t){try{return(await Ze("/__dsh_a2a/tasks/abandon",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({task_id:e,reason:t})})).ok}catch{return!1}},copy(e){var t;(t=navigator.clipboard)==null||t.writeText(e).catch(()=>{})},async cliHomeOptions(e,t){try{const n=await Ze("/__dsh_a2a/canvas",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({action:"cli-home-options",name:e,id:t})}),s=await n.json();return{...s,ok:n.ok&&s.ok===!0}}catch(n){return{ok:!1,error:String(n)}}},async confirmMember(e,t,n,s,o,r){try{const i=await Ze("/__dsh_a2a/canvas",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({action:"confirm-member",name:e,id:t,replacement:n,revision:s,expectedOwner:o,...r?{peer:r}:{}})}),c=await i.json();return{ok:i.ok&&c.ok===!0,error:c.error}}catch(i){return{ok:!1,error:String(i)}}},async regulateSuspended(e,t,n,s,o){try{const r=await Ze("/__dsh_a2a/canvas",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({action:e,name:t,id:n,revision:s,expected:o})}),i=await r.json();return{ok:r.ok&&i.ok===!0,error:i.error}}catch(r){return{ok:!1,error:String(r)}}},async canvasOp(e,t,n,s,o){try{const r=await Ze("/__dsh_a2a/canvas",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({action:e,name:t,id:n,...s===void 0?{}:{home:s},...o===void 0?{}:{peer:o}})}),i=await r.json().catch(()=>({}));return r.ok&&i.ok!==!1?!0:(console.warn(`canvas ${e} ${t}: ${i.error??`HTTP ${r.status}`}`),!1)}catch{return!1}},async dispatchQuick(e,t){try{const n=await Ze("/__dsh_a2a/dispatch",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({team:e,message:t})}),s=await n.json().catch(()=>({}));return{ok:n.ok&&s.ok===!0,task_id:s.task_id,reply:s.reply,error:s.error??`HTTP ${n.status}`}}catch(n){return{ok:!1,error:n instanceof Error?n.message:String(n)}}},async sessionLog(e){try{const t=await Ze(`/__dsh_a2a/session-log?id=${encodeURIComponent(e)}`),n=await t.json().catch(()=>({}));return{ok:t.ok&&n.ok===!0,messages:n.messages,error:n.error??(t.ok?void 0:`HTTP ${t.status}`)}}catch(t){return{ok:!1,error:t instanceof Error?t.message:String(t)}}},async sessionLogList(){try{const e=await Ze("/__dsh_a2a/session-log"),t=await e.json().catch(()=>({}));return{ok:e.ok&&t.ok===!0,sessions:t.sessions,count:typeof t.count=="number"?t.count:void 0,error:t.error??(e.ok?void 0:`HTTP ${e.status}`)}}catch(e){return{ok:!1,error:e instanceof Error?e.message:String(e)}}},async remoteSessionLog(e){try{const t=new URLSearchParams;e.team!==void 0&&t.set("team",e.team),e.peer!==void 0&&t.set("peer",e.peer),e.id!==void 0&&t.set("id",e.id),e.limit!==void 0&&t.set("limit",String(e.limit));const n=await Ze(`/__dsh_a2a/remote-session-log?${t.toString()}`),s=await n.json().catch(()=>({}));return{ok:n.ok&&s.ok===!0,messages:s.messages,sessions:s.sessions,error:s.error??(n.ok?void 0:`HTTP ${n.status}`),via:s.via}}catch(t){return{ok:!1,error:t instanceof Error?t.message:String(t)}}},board:{root:ut.root,activate:()=>ut.activate(),deactivate:()=>ut.deactivate(),available:()=>bn}});Po.appendChild(Ht.root);ln=e=>{Ht.openNodeChat(e)};if(new URLSearchParams(window.location.search).get("mode")==="plan"){const e=window.setInterval(()=>{bn&&(Ht.selectTab("board"),window.clearInterval(e))},300);window.setTimeout(()=>window.clearInterval(e),3e4)}let $n=!1;async function Fo(){if(!$n){$n=!0;try{const e=await Ze("/__dsh_a2a/superagent",{cache:"no-store"}),t=e.ok?await e.json():null;Ht.updateSuperagent(t),Tn.update(t)}catch{Ht.updateSuperagent(null),Tn.update(null)}finally{$n=!1}}}async function gn(){var e,t;try{const n=await Ze("/__dsh_a2a/state",{cache:"no-store"});if(!n.ok)throw new Error(`/__dsh_a2a/state ${n.status}`);const s=await n.json();if(Date.now()-yo>=15e3){yo=Date.now();try{const m=await Ze("/__dsh_a2a/nodes",{cache:"no-store"});if(!m.ok)throw new Error(`nodes ${m.status}`);const $=await m.json();kn=new Set(($.bindings??[]).filter(N=>N.mounted!==null&&N.effective!==null&&(N.effective.core===!1||N.effective.mutable===!1)).map(N=>N.session))}catch{kn.clear()}}const o={...s,sessions:(s.sessions??[]).map(m=>({...m,...kn.has(m.id)?{nodePromptMissing:!0}:{}}))};if(zr(),bn=s.canvas!==void 0,Ht.update(o),Fo(),bn)try{const m=await ei(),$=JSON.stringify(m??null);$!==wo&&(wo=$,(_n==="idle"||_n==="saved")&&!hn.isBusy()&&ut.adoptExternalLayout(m)),En=!0}catch(m){if(!En){In(`canvas layout 获取失败:${String(m)}`);return}}else En=!0;const r=(s.sessions??[]).map(m=>({...m,joined:m.joined===!0})),i=[...((e=s.canvas)==null?void 0:e.teams)??[],...cr(((t=s.registry)==null?void 0:t.teams)??[],s.zone??"")],c=(s.peers??[]).filter(m=>m!==null&&typeof m=="object"&&typeof m.url=="string"),d=(s.inFlight??[]).filter(m=>m!==null&&typeof m=="object"&&typeof m.team=="string"&&typeof m.peer=="string"&&Number.isFinite(m.startedAt)),u=(s.remote??[]).filter(m=>m!==null&&typeof m=="object"&&typeof m.team=="string"&&typeof m.via=="string").map(m=>({team:m.team,memberRef:m.memberRef,name:m.name,via:m.via,workspace:m.workspace,...m.unreachable===!0?{unreachable:!0}:{},...typeof m.origin=="string"&&m.origin!==""?{origin:m.origin}:{},...Array.isArray(m.teams)&&m.teams.length>0?{teams:m.teams.filter($=>typeof $=="string"&&$!=="")}:{}})),h=(s.peerOrg??[]).filter(m=>m!==null&&typeof m=="object").filter(m=>typeof m.url=="string"&&Array.isArray(m.org)).map(m=>({url:m.url,...m.unreachable===!0?{unreachable:!0}:{},org:m.org.filter($=>$!==null&&typeof $=="object").filter($=>typeof $.team=="string"&&$.team!=="").map($=>({name:typeof $.name=="string"?$.name:"",team:$.team,members:Array.isArray($.members)?$.members.filter(N=>typeof N=="string"):[]}))}));ut.reconcile({sessions:r,teams:i,peerCount:c.length,peers:c,inFlight:d,remoteTeams:u,peerOrg:h})}catch(n){In(`state 轮询失败:${String(n)}`)}}gn();window.setInterval(()=>{document.hidden||gn()},3e3);document.addEventListener("visibilitychange",()=>{document.hidden||gn()});
|
|
@@ -18,8 +18,8 @@ html,body{margin:0;height:100%;background:var(--n-bg);color:var(--n-ink);
|
|
|
18
18
|
font-family:"Segoe UI",system-ui,sans-serif;}
|
|
19
19
|
#app{width:100%;height:100%;position:relative}
|
|
20
20
|
</style>
|
|
21
|
-
<script type="module" crossorigin src="./assets/index-
|
|
22
|
-
<link rel="stylesheet" crossorigin href="./assets/index-
|
|
21
|
+
<script type="module" crossorigin src="./assets/index-YtYrkDJi.js"></script>
|
|
22
|
+
<link rel="stylesheet" crossorigin href="./assets/index-BuidhKVr.css">
|
|
23
23
|
</head>
|
|
24
24
|
<body>
|
|
25
25
|
<div id="app"></div>
|