@nelsonlongxiang/dsh-open-a2a-net 0.6.32 → 0.6.34

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.
Files changed (64) hide show
  1. package/README.md +12 -3
  2. package/README_zh.md +12 -3
  3. package/assets/nexusDist/assets/index-D2BGWOeU.js +9 -0
  4. package/assets/nexusDist/assets/index-z33lHtLw.css +1 -0
  5. package/assets/nexusDist/index.html +2 -2
  6. package/cli/a2a.mjs +5 -2
  7. package/lib/a2a-client.js +9 -2
  8. package/lib/auth-observer.js +1 -1
  9. package/lib/canvas-store.js +50 -6
  10. package/lib/card.js +2 -1
  11. package/lib/cli-home.js +44 -0
  12. package/lib/client/A2aControl.js +1 -1
  13. package/lib/client.js +65 -65
  14. package/lib/client.js.map +1 -1
  15. package/lib/direct-forward.js +61 -0
  16. package/lib/faces/admin.js +84 -9
  17. package/lib/faces/wire.js +57 -16
  18. package/lib/index.js +118 -67
  19. package/lib/layout-store.js +3 -2
  20. package/lib/outbound-scope.js +25 -0
  21. package/lib/queue-guard.js +37 -0
  22. package/lib/roster-op.js +104 -0
  23. package/lib/skill/references/cli.md +6 -5
  24. package/lib/skill/references/pitfalls.md +1 -4
  25. package/lib/skill/references/router.md +1 -1
  26. package/lib/task-auth.js +52 -3
  27. package/lib/task-ledger.js +4 -1
  28. package/lib/team-store.js +49 -1
  29. package/lib/tools/info.js +19 -3
  30. package/lib/types/a2a-client.d.ts +1 -1
  31. package/lib/types/auth-observer.d.ts +2 -2
  32. package/lib/types/canvas-store.d.ts +14 -1
  33. package/lib/types/cli-home.d.ts +24 -0
  34. package/lib/types/client/A2aControl.d.ts +1 -1
  35. package/lib/types/direct-forward.d.ts +32 -0
  36. package/lib/types/faces/admin.d.ts +9 -1
  37. package/lib/types/faces/wire.d.ts +13 -4
  38. package/lib/types/index.d.ts +4 -0
  39. package/lib/types/outbound-scope.d.ts +21 -0
  40. package/lib/types/queue-guard.d.ts +32 -0
  41. package/lib/types/roster-op.d.ts +21 -0
  42. package/lib/types/runtime.d.ts +1 -1
  43. package/lib/types/task-auth.d.ts +17 -2
  44. package/lib/types/task-ledger.d.ts +6 -1
  45. package/lib/types/team-store.d.ts +7 -0
  46. package/lib/types/types.d.ts +8 -0
  47. package/nexus-stage/src/canvas-ops.ts +2 -1
  48. package/nexus-stage/src/cli-home-picker.ts +42 -0
  49. package/nexus-stage/src/layout-doc.ts +6 -4
  50. package/nexus-stage/src/main.ts +36 -4
  51. package/nexus-stage/src/planning-card.ts +61 -0
  52. package/nexus-stage/src/planning-frame-hue.ts +13 -0
  53. package/nexus-stage/src/planning-legend.ts +1 -0
  54. package/nexus-stage/src/planning-menus.ts +63 -12
  55. package/nexus-stage/src/planning-roster.ts +15 -0
  56. package/nexus-stage/src/planning-types.ts +1 -1
  57. package/nexus-stage/src/planning-view.ts +43 -59
  58. package/nexus-stage/src/planning.css +19 -0
  59. package/nexus-stage/src/workbench.css +4 -0
  60. package/nexus-stage/src/workbench.ts +24 -5
  61. package/nexus-stage/src/world.ts +5 -1
  62. package/package.json +4 -2
  63. package/assets/nexusDist/assets/index-D5H8R8de.js +0 -9
  64. package/assets/nexusDist/assets/index-D9GYZyGZ.css +0 -1
@@ -1,9 +0,0 @@
1
- var xo=Object.defineProperty;var Co=(e,t,n)=>t in e?xo(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n;var Ct=(e,t,n)=>Co(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 i of o)if(i.type==="childList")for(const r of i.addedNodes)r.tagName==="LINK"&&r.rel==="modulepreload"&&s(r)}).observe(document,{childList:!0,subtree:!0});function n(o){const i={};return o.integrity&&(i.integrity=o.integrity),o.referrerPolicy&&(i.referrerPolicy=o.referrerPolicy),o.crossOrigin==="use-credentials"?i.credentials="include":o.crossOrigin==="anonymous"?i.credentials="omit":i.credentials="same-origin",i}function s(o){if(o.ep)return;o.ep=!0;const i=n(o);fetch(o.href,i)}})();const Zt=6e4;function ko(e,t,n=Date.now){let s=-Zt;return{fault(o){const i=n();i-s>=Zt&&(t(`[nexus] ${o}`),s=i),e.show(o)},clear(){e.hide(),s=-Zt}}}function ot(e){return e.name??e.team??e.label??""}function eo(e,t){var i,r;const n=(l,u)=>l!==void 0&&l.trim()!==""?{name:l,remote:u}:void 0,s=(e.sessions??[]).find(l=>l.team===t);if(s!==void 0)return n(ot(s),!1);const o=(e.remote??[]).find(l=>l.team===t);return o!==void 0?n(ot(o),!0):n((r=(((i=e.canvas)==null?void 0:i.teams)??[]).find(l=>l.team===t))==null?void 0:r.name,!1)}function Eo(e,t){const n=eo(e,t);return n===void 0?t:n.remote?`${n.name}(远端)`:n.name}function jt(e,t,n,s=""){const o=eo(t,n);if(e.textContent=`${s}${(o==null?void 0:o.name)??n}`,e.title=n,(o==null?void 0:o.remote)===!0){const i=e.appendChild(document.createElement("span"));i.className="wb-row-remote",i.textContent="远端",i.title="名字由对端自行发布"}}const $o=60*6e4;function Et(e){var t;return e.direction==="inbound"||e.direction===void 0&&((t=e.peer)==null?void 0:t.startsWith("local:"))===!0}function En(e){var t;return((t=e.peer)==null?void 0:t.startsWith("local:"))===!0?e.peer.slice(6):void 0}function It(e,t){return e.settleable!==void 0?e.settleable===!1:t-e.startedAt>=$o}function rn(e,t){const n=(e.tasks??[]).filter(r=>r.receiptExpected!==!1),s=n.filter(r=>!Et(r)&&It(r,t)),o=n.filter(r=>Et(r)&&It(r,t)),i=e.tasksDead??[];return{stale:s,owedOverdue:o,deadLetters:i.filter(r=>r.reason!=="fire-forget"),expired:i.filter(r=>r.reason==="fire-forget")}}function Ne(e,t){const n=document.createElement(e);return t!==void 0&&(n.className=t),n}function $n(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 Ot(e,t,n,s,o){const i=Ne("div",`wb-led-tile${o!==void 0?` is-${o}`:""}`);i.title=s,i.appendChild(Ne("span","wb-led-tile-v")).textContent=String(n),i.appendChild(Ne("span","wb-led-tile-k")).textContent=t,e.appendChild(i)}const an=[{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 No(e,t,n){const s=Ne("div","wb-led-split"),o=Ne("div","wb-led-split-bar");o.setAttribute("role","img");const i=Ne("div","wb-led-split-legend"),r=new Set(an.map(m=>m.key)),l=an.map(m=>[m.tone,m.label,t[m.key]??0]);for(const[m,d]of Object.entries(t))r.has(m)||l.push(["other",m,d]);const u=[];for(const[m,d,h]of l){if(h<=0)continue;const M=Ne("span",`wb-led-seg is-${m}`);M.style.width=`${Math.max(2,h/n*100)}%`,o.appendChild(M);const $=Ne("span","wb-led-split-item");$.appendChild(Ne("i",`wb-led-swatch is-${m}`)),$.appendChild(document.createTextNode(`${d} ${h}`)),i.appendChild($),u.push(`${d} ${h}`)}o.setAttribute("aria-label",`归档结局:${u.join(",")}`),s.append(o,i),e.appendChild(s)}function Mo(e,t){var Me;e.replaceChildren();const{state:n,now:s}=t,o=n.tasks??[],i=n.tasksDead??[],r=n.archivedCount??0,l=rn(n,s),u=o.filter(P=>P.receiptExpected===!1),m=o.filter(P=>P.receiptExpected!==!1),d=m.filter(P=>Et(P)),h=m.filter(P=>!Et(P)),M=l.stale,$=h.filter(P=>!It(P,s)),J=l.stale.length,he=Ne("div","wb-led-tiles");Ot(he,"待回执",m.length,`要回执、仍未结算的任务(含陈旧与本机欠对方的入站行)${u.length>0?`;另有免回执 ${u.length} 条不计`:""}`),Ot(he,"陈旧",J,"我方派发、要回执、已等待 ≥1h 仍未回执(可催办);本机欠对方的入站行在「待本机回执」组另计,免回执行不算陈旧",J>0?"warn":void 0),Ot(he,"死信",l.deadLetters.length,"超过 24h TTL 仍未结算(unconsumed);需清账(abandon)才能移出。免回执到期另列,不算死信",l.deadLetters.length>0?"danger":void 0),Ot(he,"已归档",r,"已离开台账并留档的任务(结算、拒绝或放弃),用于审计"),e.appendChild(he),r>0&&n.archivedSplit!==void 0&&No(e,n.archivedSplit,r);const Q=(P,q)=>{const ie=Ne("div",`wb-led-card is-${q.tone}`),Se=Ne("div","wb-led-card-head");Se.appendChild(Ne("span",`wb-led-dir${q.inbound?" is-in":""}`)).textContent=q.inbound?"↙":"↗";const G=Ne("span","wb-led-brief");G.textContent=q.brief!==void 0&&q.brief!==""?q.brief:"(无摘要——派发未带 brief)",(q.brief===void 0||q.brief==="")&&G.classList.add("is-missing"),Se.appendChild(G),ie.appendChild(Se);const j=Ne("div","wb-led-meta"),xe=j.appendChild(Ne("span","wb-led-team"));q.inbound?q.sender!==void 0?jt(xe,n,q.sender,"来自 "):xe.textContent="来自 对端":jt(xe,n,q.team,"发往 "),q.inbound&&jt(j.appendChild(Ne("span","wb-led-to")),n,q.team,"至 "),j.appendChild(Ne("span")).textContent=q.atText,j.appendChild(Ne("span","wb-led-task")).textContent=q.taskId;for(const ue of q.chips)j.appendChild(Ne("span","wb-led-chip")).textContent=ue;if(ie.appendChild(j),ie.title=`${q.taskId}
2
- ${q.team}`,q.dead!==void 0){const ue=q.dead,ke=ue.reason==="fire-forget",Te=Ne("button",`wb-btn wb-led-abandon${ke?" is-quiet":""}`);Te.type="button",Te.textContent=ke?"移出":"清账",Te.title=ke?"可选:把这条已过期的免回执记录移出台账(不是失败,不处理也无妨)":"从台账移出这条死信(abandon)",Te.addEventListener("click",et=>{et.stopPropagation(),Te.disabled=!0,t.abandon(ue.taskId,"workbench dead-letter cleanup").then(qe=>{Te.disabled=!1,Te.textContent=qe?"已清":"失败"})}),ie.appendChild(Te)}if(t.canOpenTeam(q.team)){ie.classList.add("is-link"),ie.setAttribute("role","button"),ie.tabIndex=0,ie.setAttribute("aria-label",`${G.textContent},打开 ${q.team} 的对话`);const ue=()=>{t.openTeam(q.team)};ie.addEventListener("click",ue),ie.addEventListener("keydown",ke=>{(ke.key==="Enter"||ke.key===" ")&&(ke.preventDefault(),ue())})}P.appendChild(ie)},E=(P,q,ie,Se)=>{if(q===0)return null;const G=Ne("div",`wb-led-group is-${ie}`);G.dataset.group=P;const j=Ne("div","wb-led-group-head");return j.appendChild(Ne("span")).textContent=`${P} · ${q}`,j.appendChild(Ne("span","wb-led-group-hint")).textContent=Se,G.appendChild(j),e.appendChild(G),G},k=(P,q)=>{const ie=Et(P);return{brief:P.brief,team:P.team,sender:En(P),taskId:P.taskId,atText:`${$n(P.startedAt,s)} 前${ie?"收到":"派发"}`,inbound:ie,tone:q,chips:[...P.settleable===!0?["可结算"]:[],...P.receiptExpected===!1?["无回执债"]:[],...ie?["入站"]:[],...P.status!=="pending"?[P.status]:[]]}},I=(P,q,ie)=>({brief:P.brief,team:P.team,sender:En(P),taskId:P.taskId,atText:`${$n(P.deadAt,s)} 前${ie}`,inbound:Et(P),tone:q,dead:P,chips:P.reason!==void 0&&P.reason!==""&&P.reason!=="unspecified"&&P.reason!=="fire-forget"?[P.reason]:[]}),x=E("死信",l.deadLetters.length,"danger","需清账");if(x!==null)for(const P of[...l.deadLetters].sort((q,ie)=>ie.deadAt-q.deadAt))Q(x,I(P,"danger","死信"));const T=E("陈旧",M.length,"warn","我方派发 ≥1 小时仍无回执,可催办");if(T!==null)for(const P of[...M].sort((q,ie)=>q.startedAt-ie.startedAt))Q(T,k(P,"warn"));const y=l.owedOverdue.length,p=E("待本机回执",d.length,y>0?"warn":"quiet",y>0?`对方在等本机回执 · ${y} 条超过 1 小时`:"对方在等本机回执");if(p!==null)for(const P of[...d].sort((q,ie)=>q.startedAt-ie.startedAt))Q(p,k(P,It(P,s)?"warn":"quiet"));const _=E("等待回执",$.length,"quiet","1 小时内");if(_!==null)for(const P of[...$].sort((q,ie)=>ie.startedAt-q.startedAt))Q(_,k(P,"quiet"));const b=E("免回执",u.length,"muted","不等回执,24h 后自动归档");if(b!==null)for(const P of u)Q(b,k(P,"muted"));const D=E("已过期(免回执)",l.expired.length,"muted","正常记账,不是失败");if(D!==null)for(const P of[...l.expired].sort((q,ie)=>ie.deadAt-q.deadAt))Q(D,I(P,"muted","过期"));o.length+i.length===0&&(e.appendChild(Ne("div","wb-led-empty")).textContent="台账为空——没有待回执的任务");const B=n.idempotency,se=(Me=n.reconcile)==null?void 0:Me.state;if(B!==void 0||se!==void 0){const P=Ne("details","wb-led-forensics wb-forensics");P.appendChild(Ne("summary")).textContent="取证";const q=Ne("div","wb-led-forensics-body");B!==void 0&&(q.appendChild(Ne("div")).textContent=`幂等 claims ${B.claimsFresh??0} · replays ${B.replays??0} · conflicts ${B.conflicts??0}`),se!==void 0&&(q.appendChild(Ne("div")).textContent=`reconcile ${se}`),P.appendChild(q),e.appendChild(P)}const pe=m.length+l.deadLetters.length;return{badge:pe>0?String(pe):"",tone:l.deadLetters.length>0?"danger":J>0||y>0?"warn":void 0}}const Mt=4e3,So=32;function ve(e,t){const n=document.createElement(e);return t!==void 0&&(n.className=t),n}function Ft(e,t,n=""){const s=ve("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 en(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 Ao(e){return e>=1e6?`${(e/1e6).toFixed(1)} MB`:e>=1e3?`${Math.round(e/1e3)} KB`:`${e} B`}function tn(e){const t=e.kind==="session"||e.kind==="remote"?e.team:void 0;return t!==void 0&&t!==""?t:void 0}function Nn(e){return e.kind==="remote"?`remote:${e.team}`:`${e.kind}:${e.id}`}function Lo(e){let t=null,n=null,s=!1,o=!1;const i=new Map,r=new Map,l=new Map,u=new Map,m=new Set,d=new Map,h=new Map,M=ve("aside","wb-chat");M.setAttribute("aria-label","对话");const $=ve("div","wb-chat-head"),J=Ft("返回会话列表","‹","wb-chat-back"),he=ve("span","wb-chat-dot"),Q=ve("div","wb-chat-titles"),E=ve("span","wb-chat-title"),k=ve("span","wb-chat-sub");Q.append(E,k);const I=Ft("刷新对话","↻","wb-chat-refresh"),x=Ft("会话详情","ⓘ","wb-chat-info-btn");x.setAttribute("aria-expanded","false");const T=Ft("关闭对话","✕","wb-chat-close");$.append(J,he,Q,I,x,T);const y=ve("div","wb-chat-info");y.hidden=!0;const p=ve("div","wb-chat-thread");p.setAttribute("role","log"),p.setAttribute("aria-live","polite"),p.tabIndex=0;const _=ve("div","wb-chat-notice"),b=ve("div","wb-chat-log"),D=ve("div","wb-chat-sent");p.append(_,b,D);const B=ve("div","wb-chat-foot");M.append($,y,p,B),J.addEventListener("click",()=>{(t==null?void 0:t.kind)==="peer"&&(t.picked=void 0,Pe())}),I.addEventListener("click",()=>{if(t===null)return;const c=se(t);c!==void 0&&i.delete(c),t.kind==="peer"&&t.picked===void 0&&t.url!==void 0&&l.delete(`peer:${t.url}`),Te(!0)}),x.addEventListener("click",()=>{o=!o,y.hidden=!o,x.setAttribute("aria-expanded",String(o))}),T.addEventListener("click",()=>vt()),p.addEventListener("scroll",()=>{const c=t!==null?se(t):void 0;c!==void 0&&r.set(c,p.scrollTop)}),document.addEventListener("keydown",c=>{if(c.key!=="Escape"||!M.classList.contains("is-open"))return;const A=c.target;if(A instanceof HTMLElement){if(!M.contains(A)){const L=A instanceof HTMLTextAreaElement||A instanceof HTMLInputElement||A.isContentEditable,z=A.closest(".wb-stage-board")!==null;if(L||z)return}vt()}});function se(c){if(c.kind==="session"||c.kind==="log")return e.sessionLog!==void 0?`local:${c.id}`:void 0;if(c.kind==="remote")return e.remoteSessionLog!==void 0?`remote:${c.team}`:void 0;if(c.picked!==void 0&&c.url!==void 0&&e.remoteSessionLog!==void 0)return`peer:${c.url}:${c.picked}`}function pe(c){var A,L,z;return c.kind==="session"||c.kind==="log"?((A=e.sessionLog)==null?void 0:A.call(e,c.id))??Promise.resolve({ok:!1,error:"sessionLog unavailable"}):c.kind==="remote"?((L=e.remoteSessionLog)==null?void 0:L.call(e,{team:c.team}))??Promise.resolve({ok:!1,error:"remoteSessionLog unavailable"}):((z=e.remoteSessionLog)==null?void 0:z.call(e,{peer:c.url,id:c.picked}))??Promise.resolve({ok:!1,error:"remoteSessionLog unavailable"})}function Me(){const c=t;if(c===null)return;const A=c.kind==="log"||c.kind==="remote"||c.kind==="session"&&c.live===!1;he.className=`wb-chat-dot ${c.kind==="peer"?"is-peer":A?"is-cold":"is-live"}`,he.title=c.kind==="peer"?"对端主机":c.kind==="log"?"只读日志":c.kind==="remote"?"远端会话":c.live===!1?"冷会话":"在线",E.textContent=c.kind==="peer"&&c.picked!==void 0?`…${c.picked.slice(-12)}`:c.title,k.textContent=c.kind==="peer"&&c.picked!==void 0?c.title:c.sub,J.hidden=!(c.kind==="peer"&&c.picked!==void 0)}function P(c,A){const L=ve("div","wb-kv");L.appendChild(ve("span","wb-kv-k")).textContent=c,L.appendChild(ve("span","wb-kv-v")).textContent=A,y.appendChild(L)}function q(){var A,L,z;y.replaceChildren();const c=t;c!==null&&(c.kind==="session"?(P("会话",c.id),c.team!==void 0&&P("路由",c.team),P("来源","本机会话日志")):c.kind==="log"?(P("会话",c.id),P("来源","本机会话日志(不在网络目录)")):c.kind==="remote"?(P("路由",c.team),((A=c.row)==null?void 0:A.origin)!==void 0&&P("来源",c.row.origin),((L=c.row)==null?void 0:L.via)!==void 0&&P("经",c.row.via),((z=c.row)==null?void 0:z.workspace)!==void 0&&P("工作区",c.row.workspace)):(P("对端",c.url??c.sub),c.picked!==void 0&&P("会话",c.picked),P("来源","经本机代理读取对端 /a2a/log")))}function ie(c){return c.kind==="log"?"只读日志 —— 此会话当前不在网络目录(可能已归档或未入网)。":c.kind==="remote"?e.remoteSessionLog!==void 0?"远端会话 —— 经本机代理从对端 /a2a/log 读取最近对话。":"远端节点的对话记录在对端机器上;本页的代理读取面未启用。":c.kind==="peer"?c.url===void 0||e.remoteSessionLog===void 0?`对端主机节点(${c.sub})—— 会话记录存放在对端机器上,本页只读本机会话日志。`:c.picked===void 0?"对端主机 —— 选择一个会话阅读(经本机代理读取对端 /a2a/log)。":"":e.sessionLog===void 0?"本页未接入会话日志读取,只显示从这里发出的消息。":""}function Se(){return p.scrollHeight-p.scrollTop-p.clientHeight<=So}function G(c){const A=()=>{p.scrollTop=p.scrollHeight};A(),requestAnimationFrame(A)}function j(c,A){const L=ve("div",`wb-chat-empty${A==="error"?" is-error":""}`);return L.textContent=c,L}function xe(c,A){const L=c==="user",z=ve("div",`wb-msg ${L?"wb-msg-user":"wb-msg-assistant"}`),Y=ve("span","wb-msg-who");Y.textContent=L?"问":"答";const me=ve("div","wb-msg-text");return me.textContent=A,z.append(Y,me),z}function ue(c){if(b.replaceChildren(),c===void 0){b.appendChild(j("读取中…"));return}if(c.ok!==!0||c.messages===void 0){b.appendChild(j(`无法读取(${c.error??"未知错误"})`,"error"));return}if(c.messages.length===0){b.appendChild(j("暂无对话记录"));return}for(const A of c.messages)b.appendChild(xe(A.role,A.text))}function ke(c,A){if(b.replaceChildren(),A===void 0){b.appendChild(j("读取中…"));return}if(A.ok!==!0||A.sessions===void 0){b.appendChild(j(`无法读取(${A.error??"未知错误"})`,"error"));return}if(A.sessions.length===0){b.appendChild(j("对端没有可读会话"));return}const L=ve("div","wb-chat-sessions"),z=e.now();for(const Y of A.sessions){const me=ve("button","wb-chat-session");me.type="button",me.appendChild(ve("span","wb-chat-session-id")).textContent=`…${Y.id.slice(-12)}`;const ce=[Y.mtimeMs!==void 0?en(Y.mtimeMs,z):"",Ao(Y.sizeBytes)].filter(Boolean).join(" · ");me.appendChild(ve("span","wb-chat-session-meta")).textContent=ce,me.title=Y.id,me.addEventListener("click",()=>{(t==null?void 0:t.kind)!=="peer"||t.url!==c||(t.picked=Y.id,Pe())}),L.appendChild(me)}b.appendChild(L)}function Te(c=!1){const A=t;if(A===null)return;if(_.textContent=ie(A),_.hidden=_.textContent==="",A.kind==="peer"&&A.picked===void 0){if(A.url===void 0||e.remoteSessionLog===void 0){b.replaceChildren();return}const Y=A.url,me=`peer:${Y}`;if(!c&&l.has(me)){ke(Y,l.get(me));return}l.set(me,void 0),ke(Y,void 0),e.remoteSessionLog({peer:Y}).then(ce=>{l.set(me,ce),(t==null?void 0:t.kind)==="peer"&&t.url===Y&&t.picked===void 0&&ke(Y,ce)},ce=>{const ye={ok:!1,error:ce instanceof Error?ce.message:String(ce)};l.set(me,ye),(t==null?void 0:t.kind)==="peer"&&t.url===Y&&t.picked===void 0&&ke(Y,ye)});return}const L=se(A);if(L===void 0){b.replaceChildren(),je(!0);return}const z=()=>{const Y=r.get(L);Y===void 0||c?G():(p.scrollTop=Y,requestAnimationFrame(()=>{t!==null&&se(t)===L&&(p.scrollTop=Y)}))};if(!c&&i.has(L)&&i.get(L)!==void 0){ue(i.get(L)),je(!0),z();return}c&&r.delete(L),i.set(L,void 0),ue(void 0),je(!0),pe(A).then(Y=>{var me;i.set(L,Y),(Y==null?void 0:Y.ok)===!0&&Y.messages!==void 0&&((me=e.onTranscript)==null||me.call(e,A,Y.messages)),!(t===null||se(t)!==L)&&(ue(Y),je(),z())},Y=>{const me={ok:!1,error:Y instanceof Error?Y.message:String(Y)};i.set(L,me),t!==null&&se(t)===L&&ue(me)})}function et(c){return((n==null?void 0:n.tasks)??[]).filter(A=>A.team===c)}function qe(c){return((n==null?void 0:n.tasksDead)??[]).filter(A=>A.team===c)}let Ke="";function ht(c){return c.reason==="fire-forget"?{text:"已过期(免回执)",tone:"muted",hint:"免回执消息到 24h TTL 归档,属正常记账"}:{text:"死信",tone:"danger",hint:c.reason!==void 0&&c.reason!=="unspecified"?`${c.reason}:超过 24h TTL 仍未结算,需在台账清账`:"超过 24h TTL 仍未结算,需在台账清账"}}function He(c,A){const L=c.direction==="inbound";if(c.receiptExpected===!1)return{text:L?"来信 · 无需回执":"已送达 · 无回执",tone:"muted",hint:"免回执消息:不等回执,24h 后自动归档"};const z=It(c,A),Y=L?z?"待本机回执 · 超 1 小时":"待本机回执":z?"陈旧":"待回执",me=c.status!=="pending"?` · ${c.status}`:"";return{text:`${Y}${me}`,tone:z?"warn":"wait",hint:`${L?"对方等待本机回执;":""}${L?"收到":"派发"}于 ${en(c.startedAt,A)}`}}function Ve(c,A){const L=`结算于 ${en(c.resolvedAt,A)}`;if(c.receiptExpected===!1&&c.endedBy==="abandoned")return c.late===!0?{text:"已移出(免回执) · 回执迟到",tone:"warn",hint:`${L};免回执消息本机移出后对方回执才到,结局不改写`}:{text:"已移出(免回执)",tone:"muted",hint:`${L};免回执消息,本机移出台账,不是失败`};if(c.endedBy==="abandoned"||c.endedBy==="cancelled"){const ce=c.endedBy==="cancelled"?"撤回":"放弃";return c.late===!0?{text:`已${ce} · 回执迟到`,tone:"warn",hint:`${L};本机${ce}之后对方回执才到,结局不改写`}:{text:`已${ce}`,tone:"muted",hint:`${L};本机${ce},未等到回执`}}if(c.endedBy==="echo")return{text:"已结算 · 内容回显",tone:"ok",hint:`${L};对方回了内容但未带正式回执,按内容回显结算`};if(c.endedBy===void 0&&c.outcome==="abandoned")return{text:"已放弃(本机或对方)",tone:"muted",hint:`${L};本机放弃或撤回,或对方回执报告放弃`};const z=c.summary!==void 0&&c.summary!==""?` · ${c.summary}`:"";if(c.outcome==="abandoned")return{text:"已回执 · 对方放弃",tone:"warn",hint:`${L};对方回执报告放弃${z}`};const Y=an.find(ce=>ce.key===c.outcome),me=(Y==null?void 0:Y.tone)==="completed"?"ok":(Y==null?void 0:Y.tone)==="failed"?"danger":(Y==null?void 0:Y.tone)==="rejected"?"warn":"muted";return c.outcome==="unclassified"?{text:"已回执",tone:"ok",hint:`${L};回执未带结论${z}`}:{text:`已回执 · ${(Y==null?void 0:Y.label)??c.outcome}`,tone:me,hint:`${L}${z}`}}function at(c,A,L){const z=qe(A).find(ce=>ce.taskId===c);if(z!==void 0)return ht(z);const Y=et(A).find(ce=>ce.taskId===c);if(Y!==void 0)return He(Y,L);const me=((n==null?void 0:n.archived)??[]).find(ce=>ce.taskId===c&&ce.team===A);return me!==void 0?Ve(me,L):m.has(c)?{text:"已离开台账",tone:"muted",hint:"已结算、放弃或撤回之一;主机未给出这条的结局(旧主机,或已超出最近 64 条归档)"}:{text:"已派发",tone:"muted",hint:"异步送达;回执到达后进台账"}}function bt(c){const A=e.now(),L=u.get(c)??[],z=new Set(L.map(oe=>oe.taskId).filter(oe=>oe!==void 0)),Y=oe=>oe!==void 0&&oe!==""?oe:"(无摘要)",me=et(c).filter(oe=>!z.has(oe.taskId)).map(oe=>({at:oe.startedAt,side:oe.direction==="inbound"?"theirs":"mine",text:Y(oe.brief),status:He(oe,A),taskId:oe.taskId})),ce=qe(c).filter(oe=>!z.has(oe.taskId)).map(oe=>{var Je;const $e=oe.direction??d.get(oe.taskId)??(((Je=oe.peer)==null?void 0:Je.startsWith("local:"))===!0?"inbound":void 0);return{at:oe.startedAt,side:$e==="inbound"?"theirs":$e==="outbound"?"mine":"system",text:Y(oe.brief),status:ht(oe),taskId:oe.taskId}}),ye=L.map(oe=>({at:oe.at,side:"mine",text:oe.text,status:oe.state==="sending"?{text:"发送中…",tone:"muted"}:oe.state==="failed"?{text:`失败:${oe.error??"未知原因"}`,tone:"danger"}:oe.taskId!==void 0?at(oe.taskId,c,A):{text:"已派发",tone:"muted"},taskId:oe.taskId}));return[...me,...ce,...ye].sort((oe,$e)=>oe.at-$e.at)}function je(c=!1){const A=t,L=A!==null?tn(A):void 0,z=L!==void 0?bt(L):[],Y=JSON.stringify([L??"",...z.map(ye=>[ye.taskId??"",ye.side,ye.text,ye.status.text])]);if(!c&&Y===Ke)return;Ke=Y;const me=Se();if(D.replaceChildren(),z.length===0)return;const ce=ve("div","wb-chat-divider");ce.textContent="台账往来 · 异步送达,回执进台账",D.appendChild(ce);for(const ye of z){const oe=ye.side==="mine"?"wb-msg wb-msg-user wb-msg-out":ye.side==="theirs"?"wb-msg wb-msg-assistant wb-msg-in":"wb-msg wb-msg-ledger",$e=ve("div",oe);$e.appendChild(ve("span","wb-msg-who")).textContent=ye.side==="mine"?"我":ye.side==="theirs"?"对方":"台账记录",$e.appendChild(ve("div","wb-msg-text")).textContent=ye.text;const Je=ve("div","wb-msg-meta");ye.taskId!==void 0&&(Je.appendChild(ve("span","wb-msg-task")).textContent=ye.taskId);const De=ve("span",`wb-msg-status is-${ye.status.tone}`);De.textContent=ye.status.text,ye.status.hint!==void 0&&(De.title=ye.status.hint),Je.appendChild(De),$e.appendChild(Je),D.appendChild($e)}me&&G()}function Ye(c){const A=c.text.value.length;c.note.classList.remove("is-error"),c.note.textContent=A>Mt*.9?`${A}/${Mt}`:"Enter 发送 · Shift+Enter 换行",A>Mt&&c.note.classList.add("is-error"),c.submit.disabled=c.text.value.trim()===""||A>Mt}function gt(c){c.style.height="auto",c.style.height=`${Math.min(c.scrollHeight,160)}px`}function mt(c){const A=ve("form","wb-dispatch-form wb-chat-composer"),L=document.createElement("textarea");L.className="wb-dispatch-text",L.rows=1,L.placeholder="发一句话任务给这个节点…",L.setAttribute("aria-label","发送消息");const z=ve("button","wb-dispatch-submit");z.type="submit",z.textContent="发送",z.setAttribute("aria-label","发送");const Y=ve("div","wb-dispatch-note");Y.setAttribute("aria-live","polite");const me=ve("div","wb-chat-composer-row");me.append(L,z),A.append(me,Y);const ce={team:c,form:A,text:L,note:Y,submit:z};return L.addEventListener("input",()=>{gt(L),Ye(ce)}),L.addEventListener("keydown",ye=>{ye.key!=="Enter"||ye.shiftKey||ye.ctrlKey||ye.altKey||ye.metaKey||ye.isComposing||(ye.preventDefault(),A.requestSubmit())}),A.addEventListener("submit",ye=>{ye.preventDefault();const oe=L.value.trim();if(oe===""||oe.length>Mt||e.dispatchQuick===void 0)return;const $e={text:oe,at:e.now(),state:"sending"},Je=u.get(c)??[];Je.push($e),u.set(c,Je),L.value="",gt(L),Ye(ce),L.focus({preventScroll:!0}),je(),G(),e.dispatchQuick(c,oe).then(De=>De,De=>({ok:!1,error:De instanceof Error?De.message:String(De)})).then(De=>{De.ok===!0?($e.state="sent",$e.taskId=De.task_id,Y.classList.remove("is-error"),Y.textContent=`已派发${De.task_id!==void 0?` · ${De.task_id}`:""} · 回执将入台账`):($e.state="failed",$e.error=De.error??"未知原因",L.value===""&&(L.value=oe,gt(L)),Y.classList.add("is-error"),Y.textContent=`失败:${$e.error}`,z.disabled=L.value.trim()===""),t!==null&&tn(t)===c&&je()})}),Ye(ce),ce}function Ee(){const c=t;if(B.replaceChildren(),c===null)return;const A=tn(c);if(A!==void 0&&e.dispatchQuick!==void 0){let z=h.get(A);z===void 0&&(z=mt(A),h.set(A,z)),B.appendChild(z.form),s&&(s=!1,z.text.focus({preventScroll:!0}));return}s=!1;const L=ve("div","wb-chat-readonly");L.textContent=c.kind==="log"?"只读日志:此会话不在网络目录,不能从这里派发。":c.kind==="peer"?"对端主机:选择会话阅读;要派发请打开它的远端会话节点。":"此节点没有可派发的路由。",B.appendChild(L)}function Pe(){Me(),q(),Te(),Ee()}function Ze(c){const A=t!==null&&Nn(t)===Nn(c);t=c,A||(s=!0),Pe(),M.classList.add("is-open")}function vt(){t=null,M.classList.remove("is-open")}function lt(c){n=c;for(const L of(c==null?void 0:c.tasks)??[])m.add(L.taskId),d.set(L.taskId,L.direction==="inbound"?"inbound":"outbound");const A=t;if(A!==null){if(A.kind==="session"&&c!==null){const L=(c.sessions??[]).find(z=>z.id===A.id);L!==void 0&&(A.title=ot(L),A.live=L.live)}Me(),je()}}return{root:M,open:Ze,close:vt,isOpen:()=>t!==null,update:lt}}const to="dsh-a2a.rail.tab";function Io(){try{return window.localStorage.getItem(to)}catch{return null}}function To(e){try{window.localStorage.setItem(to,e)}catch{}}function _o(e,t={}){var Q;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 i=new Map,r=new Map,l=new Map,u=new Set;for(const E of e){const k=document.createElement("button");k.type="button",k.className="wb-tab",k.id=`wb-tab-${E.key}`,k.dataset.sec=E.key,k.setAttribute("role","tab"),k.setAttribute("aria-controls",`wb-panel-${E.key}`);const I=document.createElement("span");I.className="wb-tab-label",I.textContent=E.label;const x=document.createElement("span");x.className="wb-tab-badge",k.append(I,x),k.addEventListener("click",()=>$(E.key)),s.appendChild(k);const T=document.createElement("section");T.className="wb-tabpanel",T.id=`wb-panel-${E.key}`,T.dataset.sec=E.key,T.setAttribute("role","tabpanel"),T.setAttribute("aria-labelledby",k.id),T.tabIndex=-1,o.appendChild(T),i.set(E.key,k),r.set(E.key,T),l.set(E.key,x)}const m=()=>e.map(E=>E.key).filter(E=>!u.has(E)),d=Io();let h=((Q=e.find(E=>E.key===d))==null?void 0:Q.key)??e[0].key;s.addEventListener("keydown",E=>{const k=m(),I=k.indexOf(h);let x;E.key==="ArrowRight"?x=k[(I+1)%k.length]:E.key==="ArrowLeft"?x=k[(I-1+k.length)%k.length]:E.key==="Home"?x=k[0]:E.key==="End"&&(x=k[k.length-1]),x!==void 0&&(E.preventDefault(),$(x,{focus:!0}))});function M(){for(const E of e){const k=E.key===h,I=i.get(E.key);I.setAttribute("aria-selected",String(k)),I.tabIndex=k?0:-1,I.classList.toggle("is-active",k),I.hidden=u.has(E.key),r.get(E.key).hidden=!k}}function $(E,k={}){var x;if(u.has(E))return;const I=E!==h;h=E,To(E),M(),k.focus===!0&&i.get(E).focus(),I&&((x=t.onChange)==null||x.call(t,E))}function J(E,k,I){const x=l.get(E);x.textContent=k,x.className=`wb-tab-badge${I!==void 0?` is-${I}`:""}`}function he(E,k){k?u.add(E):u.delete(E),u.has(h)&&(h=m()[0]??e[0].key),M()}return M(),{root:n,panel:E=>r.get(E),select:$,selected:()=>h,setBadge:J,setHidden:he}}const Oo=[{key:"all",label:"全部",hint:"不过滤:目录全部条目"},{key:"local",label:"本机",hint:"本机会话节点(现场 + 冷启动)"},{key:"canvas",label:"队",hint:"画布队(人类手工分配的组队)"},{key:"remote",label:"远端",hint:"远端会话队(来自对端卡片)"},{key:"logs",label:"日志",hint:"本机日志:不在网络目录里的会话档案"}];function Qe(e,t){const n=document.createElement(e);return t!==void 0&&(n.className=t),n}function Pt(...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 Fo(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 Mn(e){return e>=1e6?`${(e/1e6).toFixed(1)} MB`:e>=1e3?`${Math.round(e/1e3)} KB`:`${e} B`}function Po(e,t){const n=new Date(t);n.setHours(0,0,0,0);const s=n.getTime();return e>=s?"今天":e>=s-864e5?"昨天":"更早"}function Do(e,t){var I,x,T;e.replaceChildren();const{state:n,search:s,filter:o}=t,i=s!==""||o!=="all",r=(y,p)=>(o==="all"||o===y)&&(s===""||p.includes(s)),l=(y,p,_)=>{const b=Qe("div","wb-dir-group"),D=Qe("div","wb-dir-head");return D.appendChild(Qe("span","wb-dir-head-label")).textContent=`${y} · ${p}`,_!==void 0&&(D.appendChild(Qe("span","wb-dir-head-note")).textContent=_),b.appendChild(D),e.appendChild(b),b},u=(y,p,_,b,D,B,se)=>{const pe=Qe("button","wb-item");pe.type="button",pe.appendChild(Qe("span",`wb-dot ${p}`)).textContent=_;const Me=Qe("span","wb-item-text");return Me.appendChild(Qe("span","wb-item-label")).textContent=b,D!==""&&(Me.appendChild(Qe("span","wb-item-sub")).textContent=D),pe.appendChild(Me),se!==void 0&&(pe.title=se),pe.addEventListener("click",B),y.appendChild(pe),pe},m=(y,p)=>{if(p===void 0||p.length===0)return;const _=Qe("span","wb-item-badge"),b=p.map(D=>D.slice(D.lastIndexOf("/")+1));_.textContent=`▤ ${b.slice(0,2).join(" ")}${b.length>2?` +${b.length-2}`:""}`,_.title=`画布队:${p.join(" · ")}`,y.appendChild(_)},d=(n.sessions??[]).filter(y=>r("local",Pt(ot(y),y.team,y.label,y.id,y.canvasTeams))),h=d.filter(y=>y.live===!0),M=d.filter(y=>y.live!==!0);if(d.length>0){const y=l("本机会话",d.length,M.length>0?`${h.length} 在线 · ${M.length} 冷`:void 0);for(const p of[...h,...M]){const _=p.live===!0,b=p.nodePromptMissing===!0,D=u(y,_?"wb-dot-live":"wb-dot-cold",_?"●":"○",ot(p),_?p.team:`冷 · ${p.team}`,()=>t.openChat({kind:"session",id:p.id,title:ot(p),sub:p.team,team:p.team,live:p.live}),p.id);if(b){D.classList.add("is-node-prompt-missing");const B=Qe("span","wb-node-warning");B.textContent="本会话的组装不含节点段",(I=D.querySelector(".wb-item-text"))==null||I.appendChild(B)}m(D,p.canvasTeams)}}const $=(((x=n.canvas)==null?void 0:x.teams)??[]).filter(y=>r("canvas",Pt(y.name,y.team,y.members.map(p=>p.team??p.id))));if($.length>0){const y=l("画布队",$.length);for(const p of $){const _=p.members.filter(b=>b.remote===!0).length;u(y,"wb-dot-canvas","▤",p.name,`${p.members.length} 成员${_>0?` · ${_} 远端`:""}`,()=>t.selectCanvas(p),p.team)}}const J=(n.remote??[]).filter(y=>r("remote",Pt(ot(y),y.team,y.origin,y.workspace,y.canvasTeams)));if(J.length>0){const y=l("远端节点",J.length);for(const p of J){const _=u(y,"wb-dot-remote","◇",ot(p),p.origin!==void 0&&p.origin!==""?p.origin:p.team,()=>t.openChat({kind:"remote",team:p.team,title:ot(p),sub:p.team,row:p}),p.team);if(p.unreachable===!0){_.classList.add("is-unreachable");const b=Qe("span","wb-unreachable-note");b.textContent="对端未应答(显示的是最后已知状态)",(T=_.querySelector(".wb-item-text"))==null||T.appendChild(b)}m(_,p.canvasTeams)}}const he=new Set((n.sessions??[]).map(y=>y.id)),Q=t.logs.filter(y=>!he.has(y.id)&&r("logs",Pt(y.id,t.titles.get(y.id))));if(Q.length>0){const y=t.logTotal!==void 0&&t.logTotal>t.logs.length,p=l("本机日志",Q.length,y?`显示 ${t.logs.length} / 共 ${t.logTotal}`:void 0);let _="";for(const b of[...Q].sort((D,B)=>B.mtimeMs-D.mtimeMs)){const D=Po(b.mtimeMs,t.now);D!==_&&(_=D,p.appendChild(Qe("div","wb-dir-day")).textContent=D);const B=t.titles.get(b.id),se=u(p,"wb-dot-log","❐",B??`会话 …${b.id.slice(-12)}`,`${Fo(b.mtimeMs,t.now)} · ${Mn(b.sizeBytes)}`,()=>t.openChat({kind:"log",id:b.id,title:B??`…${b.id.slice(-12)}`,sub:"本机日志"}),`${b.id}
3
- ${new Date(b.mtimeMs).toLocaleString()} · ${Mn(b.sizeBytes)}`);B===void 0&&se.classList.add("is-untitled")}}d.length+$.length+J.length+Q.length===0&&(e.appendChild(Qe("div","wb-dir-empty")).textContent=i?"无匹配条目":"目录为空");const E=n.sessions??[];return`${E.filter(y=>y.live===!0).length}/${E.length}`}const no="dsh-a2a.logtitles",Ro=300,Sn=60;function Bo(){try{const e=window.localStorage.getItem(no),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 Ho(e,t,n){const s=n.find(r=>r.role==="user"&&r.text.trim()!=="")??n.find(r=>r.text.trim()!=="");if(s===void 0)return!1;const o=s.text.trim().split(`
4
- `)[0].trim(),i=o.length>Sn?`${o.slice(0,Sn-1)}…`:o;if(e.get(t)===i)return!1;for(e.delete(t),e.set(t,i);e.size>Ro;)e.delete(e.keys().next().value);try{window.localStorage.setItem(no,JSON.stringify(Object.fromEntries(e)))}catch{}return!0}function dt(e){return e.name??e.team??e.label??""}function St(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 O(e,t){const n=document.createElement(e);return t!==void 0&&(n.className=t),n}function An(e,t,n){const s=O("div","wb-kv");s.appendChild(O("span","wb-kv-k")).textContent=t,s.appendChild(O("span","wb-kv-v")).textContent=n,e.appendChild(s)}function jo(e){try{return new URL(e).host}catch{return e}}const Yo=[{key:"directory",label:"目录"},{key:"hosts",label:"主机"},{key:"ledger",label:"台账"},{key:"activity",label:"活动"},{key:"plan",label:"规划"}];function Wo(e){const t=e.board;let n="data",s,o=null,i="",r="all",l=null,u=null,m=[],d;const h=Bo();let M=!1;const $=O("div","wb");$.setAttribute("data-testid","wb-root");const J=O("header","wb-header"),he=O("button","wb-icon-btn wb-menu");he.type="button",he.dataset.testid="wb-menu",he.setAttribute("aria-label","打开目录抽屉"),he.textContent="☰",he.addEventListener("click",()=>$.classList.toggle("is-rail-open")),J.appendChild(he);const Q=O("div","wb-title");Q.appendChild(O("span","wb-title-main")).textContent="A2A 工作台";const E=O("span","wb-badge");Q.appendChild(E),J.appendChild(Q);const k=O("button","wb-icon-btn wb-owner-btn");k.type="button",k.dataset.testid="wb-owner-btn",k.setAttribute("aria-label","主人设置(三键面板)"),k.title="主人设置:入网白名单 / 可见性 / 发布",k.textContent="⚙",k.addEventListener("click",()=>{lt=!lt,A()}),J.appendChild(k);const I=O("div","wb-header-stats");J.appendChild(I);const x=O("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",()=>{$.classList.toggle("is-rail-collapsed"),n==="canvas"&&t!==void 0&&t.activate()}),J.appendChild(x);const T=O("div","wb-body"),y=_o(Yo),p=y.root,_=O("div","wb-directory"),b=O("div","wb-dir-tools"),D=document.createElement("input");D.className="wb-search",D.type="search",D.placeholder="搜索:名称 / 队 / 会话 / 节点",D.setAttribute("aria-label","统一搜索目录"),D.addEventListener("input",()=>{i=D.value.trim().toLowerCase(),He()}),b.appendChild(D);const B=O("div","wb-filters");for(const C of Oo){const w=O("button","wb-filter");w.type="button",w.textContent=C.label,w.dataset.filter=C.key,w.title=C.hint,w.addEventListener("click",()=>{r=C.key,He()}),B.appendChild(w)}b.appendChild(B),y.panel("directory").appendChild(b),y.panel("directory").appendChild(_);const se=O("section","wb-pane"),pe=O("section","wb-pane"),Me=O("section","wb-pane"),P=O("section","wb-pane"),q=[["ledger",se],["activity",pe],["plan",Me],["hosts",P]],ie=O("main","wb-stage"),Se=O("section","wb-stage-board");t!==void 0&&(Se.appendChild(t.root),ie.appendChild(Se));const G=O("div","wb-data"),j=O("aside","wb-inspector"),xe=O("div","wb-inspector-head");xe.appendChild(O("span","wb-inspector-title")).textContent="详情";const ue=O("button","wb-icon-btn");ue.type="button",ue.setAttribute("aria-label","关闭详情"),ue.textContent="✕",ue.addEventListener("click",()=>ht(void 0)),xe.appendChild(ue),j.appendChild(xe);const ke=O("div","wb-inspector-body");j.appendChild(ke);const Te=Lo({now:e.now,sessionLog:e.sessionLog,remoteSessionLog:e.remoteSessionLog,dispatchQuick:e.dispatchQuick,onTranscript:(C,w)=>{C.kind!=="log"&&C.kind!=="session"||Ho(h,C.id,w)&&He()}});ie.appendChild(G),T.appendChild(p),T.appendChild(ie),T.appendChild(j),T.appendChild(Te.root),$.appendChild(J),$.appendChild(T);function et(C){for(const[w,H]of q){const S=C==="canvas"?y.panel(w):G;y.setHidden(w,C!=="canvas"),H.parentElement!==S&&S.appendChild(H)}}function qe(){const w=t!==void 0&&t.available()?"canvas":"data";$.dataset.mode=w,Se.classList.toggle("is-hidden",w!=="canvas"),G.classList.toggle("is-hidden",w==="canvas"),et(w),w!==n&&(t!==void 0&&(w==="canvas"?t.activate():t.deactivate()),n=w)}function Ke(C){for(;C.firstChild!==null;)C.removeChild(C.firstChild);return C}function ht(C){s=C,((C==null?void 0:C.kind)!=="canvas"||(l==null?void 0:l.name)!==C.row.name)&&(l=null),(C==null?void 0:C.kind)!=="canvas"&&(u=null),z(),$.classList.remove("is-rail-open")}function He(){for(let w=0;w<B.children.length;w++){const H=B.children[w];H.classList.toggle("is-active",H.dataset.filter===r)}if(o===null){_.replaceChildren(O("div","wb-muted")),_.firstElementChild.textContent="载入中…",y.setBadge("directory","");return}const C=Do(_,{state:o,logs:m,logTotal:d,titles:h,search:i,filter:r,now:e.now(),openChat:ce,selectCanvas:w=>ht({kind:"canvas",row:w})});y.setBadge("directory",C)}function Ve(){const C=Ke(P);if(o===null){y.setBadge("hosts","");return}const w=e.now(),H=[...o.peers??[]].sort((S,R)=>{const F=te=>te.link==="linked"?0:1;return F(S)-F(R)||(R.score??0)-(S.score??0)});if(y.setBadge("hosts",H.length>0?`${H.filter(S=>S.link==="linked").length}/${H.length}`:""),H.length===0){C.appendChild(O("div","wb-nodelist-empty")).textContent="暂无 tracked peer——配 peers 种子或等 referral 到达";return}for(const S of H){const R=jo(S.url),F=O("div","wb-host-row"),te=O("span","wb-host-lamp"),re=S.lastContactAt,V=re===void 0?void 0:w-re,we=S.lastContactOk;V===void 0?te.classList.add("is-unknown"):we===!1&&V<=5*6e4?te.classList.add("is-fail"):V<=6e4?te.classList.add("is-live"):V<=5*6e4?te.classList.add("is-warm"):te.classList.add("is-cold"),te.title=re===void 0?"尚无接触记录":`最近接触 ${St(re,w)}${we===!1?"(失败)":we===!0?"(成功)":""}`,F.appendChild(te),F.appendChild(O("span","wb-host-name")).textContent=S.name!==void 0&&S.name!==""?S.name:R;const Ie=O("span",`wb-host-badge ${S.link==="linked"?"is-linked":"is-stranger"}`);Ie.textContent=`${S.link==="linked"?"linked":"stranger"} ${S.verified===!0?"✓":"✗"}`,Ie.title=S.link==="linked"?`已建立运营者链接(互种或 canvas 引用);${S.verified===!0?"验签有效":"尚未持有验签通过的卡片"}`:"无运营者关系(验签 ≠ 关系)",F.appendChild(Ie),S.version!==void 0&&S.version!==""&&(F.appendChild(O("span","wb-host-ver")).textContent=S.version),F.appendChild(O("span","wb-host-url mono")).textContent=R,F.setAttribute("role","button"),F.tabIndex=0,F.title=`${S.url} · score ${String(S.score??0)}`;const ee=()=>{ce({kind:"peer",id:`peer-${R}`,title:S.name!==void 0&&S.name!==""?S.name:R,sub:R,url:S.url})};F.addEventListener("click",ee),F.addEventListener("keydown",_e=>{(_e.key==="Enter"||_e.key===" ")&&(_e.preventDefault(),ee())}),C.appendChild(F)}}function at(){if(o===null){se.replaceChildren(),y.setBadge("ledger","");return}const C=o,w=S=>{const R=(C.sessions??[]).find(te=>te.team===S);if(R!==void 0)return{kind:"session",id:R.id,title:dt(R),sub:R.team,team:R.team,live:R.live};const F=(C.remote??[]).find(te=>te.team===S);if(F!==void 0)return{kind:"remote",team:F.team,title:dt(F),sub:F.team,row:F}},H=Mo(se,{state:C,now:e.now(),abandon:(S,R)=>e.abandon(S,R),canOpenTeam:S=>w(S)!==void 0,openTeam:S=>{const R=w(S);return R===void 0?!1:(ce(R),!0)}});y.setBadge("ledger",H.badge,H.tone)}function bt(C,w,H){jt(C.appendChild(O("span","wb-row-team")),w,H)}function je(){var te;const C=Ke(pe);if(o===null)return;const w=e.now(),H=o.inFlight??[];y.setBadge("activity",H.length>0?String(H.length):"",H.length>0?"accent":void 0);const S=O("div","wb-pane-head");if(S.textContent=`在途 ${H.length} · 活动 ${((te=o.activity)==null?void 0:te.length)??0}`,C.appendChild(S),H.length>0){const re=O("div","wb-pane-subhead");re.textContent="在途路由",C.appendChild(re);for(const V of H){const we=O("div","wb-row");we.appendChild(O("span","wb-row-dir")).textContent="→",bt(we,o,V.team),we.appendChild(O("span","wb-row-meta")).textContent=`${V.peer} · ${St(V.startedAt,w)}`,C.appendChild(we)}}const R=O("div","wb-pane-subhead");R.textContent="活动环(最新在前)",C.appendChild(R);const F=o.activity??[];if(F.length===0){C.appendChild(O("div","wb-muted")).textContent="暂无活动";return}for(const re of F){const V=O("div","wb-row"),we=O("span","wb-row-dir");we.textContent=re.dir==="out"?"→":"←",re.ok!==!0&&we.classList.add("is-fail"),V.appendChild(we),bt(V,o,re.team),V.appendChild(O("span","wb-row-meta")).textContent=`${re.peer} · ${St(re.ts,w)}`,V.appendChild(O("span","wb-row-badges")).textContent=re.ok===!0?"":"失败",C.appendChild(V)}}function Ye(C){var te,re;const w=e.now(),H=[],S=rn(C,w);S.deadLetters.length>0&&H.push({severity:"high",text:`清账 ${S.deadLetters.length} 条死信(目标早已离开或死信化,无回执可期)`});for(const V of S.stale){const we=V.brief===void 0||V.brief===""?"":`「${V.brief}」`;H.push({severity:"normal",text:`催办 ${V.taskId} → ${Eo(C,V.team)}(等待 ${St(V.startedAt,w)} 无回执)${we}`,brief:`a2a_route 催收回执:task ${V.taskId}(team ${V.team})${we===""?"":`原任务「${V.brief}」`}已派发 ${St(V.startedAt,w)},请回报结果或回执。`})}const R=(C.sessions??[]).filter(V=>V.live!==!0).map(V=>dt(V));if(R.length>0){const V=R.slice(0,3).join("、")+(R.length>3?` 等 ${R.length} 个`:"");H.push({severity:"normal",text:`冷会话 ${R.length} 个(${V}):在 GUI 打开即可唤醒加入面`})}for(const V of((te=C.reconcile)==null?void 0:te.rows)??[])if(V.needsRepair===!0){const we=(C.sessions??[]).find(ee=>ee.id===V.id),Ie=we!==void 0?`${dt(we)}(${V.id})`:V.id;H.push({severity:"high",text:`reconcile 需修复:${Ie} ${V.error}`})}const F=((re=C.idempotency)==null?void 0:re.conflicts)??0;return F>0&&H.push({severity:"high",text:`幂等冲突 ${F} 例:人工核查 UNIQUE-ization 流量`}),H}function gt(){const C=Ke(Me);if(o===null)return;const w=Ye(o);y.setBadge("plan",w.length>0?String(w.length):"",w.some(R=>R.severity==="high")?"danger":void 0);const H=O("div","wb-pane-head");H.textContent=w.length===0?"网络健康——无待办行动":`待办行动 ${w.length}`,C.appendChild(H);for(const R of w){const F=O("div",`wb-action${R.severity==="high"?" wb-action-high":""}`);if(F.appendChild(O("span","wb-action-text")).textContent=R.text,R.brief!==void 0){const te=O("button","wb-btn");te.type="button",te.textContent="复制催办",te.addEventListener("click",()=>e.copy(R.brief??"")),F.appendChild(te)}C.appendChild(F)}const S=O("div","wb-pane-subhead");S.textContent="派单起草(复制后在任一会话粘贴执行)",C.appendChild(S),C.appendChild(mt)}const mt=O("div","wb-draft"),Ee=document.createElement("select");Ee.className="wb-select";const Pe=document.createElement("textarea");Pe.className="wb-textarea",Pe.rows=3,Pe.placeholder="任务正文:目标、验收、期限…";const Ze=O("button","wb-btn wb-btn-primary");Ze.type="button",Ze.textContent="复制任务书",Ze.addEventListener("click",()=>{const C=Ee.value,w=Pe.value.trim();C===""||w===""||e.copy(`a2a_route 派单 → ${C}:
5
- ${w}`)}),mt.appendChild(Ee),mt.appendChild(Pe),mt.appendChild(Ze);function vt(){var R;const C=Ee.value;Ke(Ee);const w=document.createElement("option");if(w.value="",w.textContent="选择目标队…",Ee.appendChild(w),o===null)return;const H=o,S=new Map;for(const F of H.sessions??[])F.team!==void 0&&F.team!==""&&S.set(F.team,`${dt(F)}(会话队)`);for(const F of((R=H.canvas)==null?void 0:R.teams)??[])S.set(F.team,`${F.name}(canvas 队)`);for(const F of H.remote??[])S.set(F.team,`${dt(F)}(远端)`);for(const[F,te]of S){const re=document.createElement("option");re.value=F,re.textContent=`${te} · ${F}`,Ee.appendChild(re)}C!==""&&S.has(C)&&(Ee.value=C)}let lt=!1,c=null;function A(){var C;z(),lt&&((C=e.ownerSettingsRead)==null||C.call(e).then(w=>{if(lt){if(w.ok!==!0){c=null,z();return}c={teamJoinAllowlist:w.teamJoinAllowlist??[],teamScopeInfo:w.teamScopeInfo!==!1,announce:w.announce===!0,announceRestartPending:w.announceRestartPending===!0},z()}}))}function L(C){const w=O("div","wb-card"),H=O("div","wb-inspector-head");H.appendChild(O("span","wb-inspector-title")).textContent="主人设置";const S=O("button","wb-icon-btn");if(S.type="button",S.setAttribute("aria-label","关闭主人设置"),S.textContent="✕",S.addEventListener("click",()=>{lt=!1,z()}),H.appendChild(S),w.appendChild(H),e.ownerSettingsRead===void 0){const Ce=O("div","wb-hint");Ce.textContent="此宿主未提供主人设置面(旧版本)——升级后可用。",w.appendChild(Ce),C.appendChild(w);return}if(c===null){const Ce=O("div","wb-hint");Ce.textContent="读取中…",w.appendChild(Ce),C.appendChild(w);return}const R=c,F=O("div","wb-side-head");F.textContent="入网白名单(精确团队名)",w.appendChild(F);for(const Ce of R.teamJoinAllowlist){const nt=O("div","wb-member-row");nt.appendChild(O("span","wb-member-label")).textContent=Ce;const yt=O("button","wb-member-remove");yt.type="button",yt.textContent="移除",yt.addEventListener("click",()=>{var Nt;(Nt=e.ownerSettingsWrite)==null||Nt.call(e,{teamJoinAllowlist:R.teamJoinAllowlist.filter(Qt=>Qt!==Ce)}).then(()=>A())}),nt.appendChild(yt),w.appendChild(nt)}const te=O("div","wb-member-add"),re=O("input","wb-member-manual");re.type="text",re.placeholder="dsh/团队名(精确,无通配)",re.setAttribute("aria-label","新增白名单团队名");const V=O("button","wb-member-submit");V.type="button",V.textContent="加入";const we=()=>{var nt;const Ce=re.value.trim();Ce===""||R.teamJoinAllowlist.includes(Ce)||(nt=e.ownerSettingsWrite)==null||nt.call(e,{teamJoinAllowlist:[...R.teamJoinAllowlist,Ce]}).then(()=>A())};V.addEventListener("click",we),re.addEventListener("keydown",Ce=>{Ce.key==="Enter"&&we()}),te.append(re,V),w.appendChild(te);const Ie=O("div","wb-side-head");Ie.textContent="目录可见性(teamScopeInfo)",w.appendChild(Ie);const ee=O("div","wb-member-row"),_e=O("button","wb-member-submit");_e.type="button",_e.textContent=R.teamScopeInfo?"已开:仅显示已加入团队(点击放开为全舰队可见)":"已关:全舰队可见(点击收窄为已加入团队)",_e.addEventListener("click",()=>{var Ce;(Ce=e.ownerSettingsWrite)==null||Ce.call(e,{teamScopeInfo:!R.teamScopeInfo}).then(()=>A())}),ee.appendChild(_e),w.appendChild(ee);const We=O("div","wb-hint");We.textContent="精度说明:teamScopeInfo 只管「目录显示范围」。关上它不会解锁任何通信准入——会话入网(S3)与目标级路由(F5)规则原样生效。",w.appendChild(We);const Ue=O("div","wb-side-head");Ue.textContent="节点发布(announce)",w.appendChild(Ue);const ct=O("div","wb-member-row"),Be=O("button","wb-member-submit");if(Be.type="button",Be.textContent=R.announce?"已开:本节点发布签名卡(点击关闭)":"已关:本节点不发布(点击开启——重启宿主后生效)",Be.addEventListener("click",()=>{var Ce;(Ce=e.ownerSettingsWrite)==null||Ce.call(e,{announce:!R.announce}).then(()=>A())}),ct.appendChild(Be),w.appendChild(ct),R.announceRestartPending){const Ce=O("div","wb-hint");Ce.textContent="有 announce 变更待生效:重启宿主后按新配置发布。",w.appendChild(Ce)}C.appendChild(w)}function z(){var S;const C=Ke(ke);if(lt){j.classList.add("is-open"),L(C);return}if(j.classList.toggle("is-open",s!==void 0),s===void 0)return;const w=s,H=O("div","wb-card");if(w.kind==="canvas"){const R=(((S=o==null?void 0:o.canvas)==null?void 0:S.teams)??[]).find(ee=>ee.name===w.row.name)??w.row;An(H,"Canvas 队",R.name),An(H,"路由队",R.team);const F=O("div","wb-side-head");if(F.textContent=`成员 · ${R.members.length}`,H.appendChild(F),R.members.length===0){const ee=O("div","wb-muted");ee.textContent="空队——用下方表单添加成员",H.appendChild(ee)}for(const ee of R.members){const _e=O("div","wb-member-row"),We=ee.remote===!0?"◇ 远端":ee.live===!0?"● 现场":ee.joined===!0?"○ 冷启":"· 未入网";_e.appendChild(O("span","wb-member-dot")).textContent=We;const Ue=O("span","wb-member-label"),ct=((o==null?void 0:o.sessions)??[]).find(Ce=>Ce.id===ee.id);Ue.textContent=ee.remote===!0?ee.id:ct!==void 0?dt(ct):ee.id,Ue.title=ee.team??ee.id,_e.appendChild(Ue);const Be=O("button","wb-member-remove");Be.type="button",Be.textContent="移除",Be.addEventListener("click",async()=>{Be.disabled=!0,await e.canvasOp("remove-member",R.name,ee.id)||(Be.disabled=!1)}),_e.appendChild(Be),H.appendChild(_e)}if((l==null?void 0:l.name)!==R.name){const ee=O("form","wb-member-add"),_e=document.createElement("select");_e.className="wb-member-pick",_e.setAttribute("aria-label","选择成员");const We=document.createElement("input");We.type="text",We.className="wb-member-manual",We.placeholder="或输入远端句柄 zone/id8",We.setAttribute("aria-label","远端成员句柄");const Ue=O("button","wb-member-submit");Ue.type="submit",Ue.textContent="添加",ee.appendChild(_e),ee.appendChild(We),ee.appendChild(Ue),ee.addEventListener("submit",async ct=>{ct.preventDefault();const Be=We.value.trim(),Ce=Be!==""?Be:_e.value;if(Ce==="")return;Ue.disabled=!0;const nt=await e.canvasOp("add-member",R.name,Ce);Ue.disabled=!1,nt&&(We.value="")}),l={name:R.name,form:ee,pick:_e,manual:We}}const te=l.pick,re=te.value;Ke(te),te.appendChild(new Option("本机会话(现场/冷启动)…","",!0,!0));const V=new Set(R.members.map(ee=>ee.id));for(const ee of(o==null?void 0:o.sessions)??[])V.has(ee.id)||te.appendChild(new Option(`${dt(ee)} — 本机`,ee.id));let we=!1;for(const ee of(o==null?void 0:o.remote)??[])ee.team.includes("/")&&(V.has(ee.team)||(we||(te.appendChild(new Option("远端会话队(目录卡片)…","",!0,!1)),we=!0),te.appendChild(new Option(`${dt(ee)} — 远端`,ee.team))));we||te.appendChild(new Option("(暂无可拉入的远端会话队——见下方说明)","",!0,!1)),re!==""&&Array.from(te.options).some(ee=>ee.value===re)&&(te.value=re),H.appendChild(l.form);const Ie=O("div","wb-hint");Ie.textContent="成员由人类在此手工分配(agent 不可自组队)。远端成员走对端目录路由,不做本机冷唤醒;地址由目录在派发时重解析。远端下拉只列 zone/id8 会话句柄——若为空,说明目录里还没有已链接对端的会话队(未链接的对端只给最小卡);此时可在输入框手输句柄(如 dsh/xxxxxxxx)先把人拉进来,句柄本身即链接手势。",H.appendChild(Ie),e.dispatchQuick!==void 0&&H.appendChild(me(R.team))}C.appendChild(H)}function Y(C){const w=O("form","wb-dispatch-form"),H=document.createElement("textarea");H.className="wb-dispatch-text",H.placeholder="一句话任务…(≤4000 字符,异步送达,回执进台账)",H.setAttribute("aria-label","快派消息");const S=O("button","wb-dispatch-submit");S.type="submit",S.textContent="发送";const R=O("div","wb-dispatch-note");return w.appendChild(H),w.appendChild(S),w.appendChild(R),H.addEventListener("keydown",F=>{F.key!=="Enter"||F.shiftKey||F.ctrlKey||F.altKey||F.metaKey||F.isComposing||(F.preventDefault(),S.disabled||w.requestSubmit())}),w.addEventListener("submit",async F=>{var V;F.preventDefault();const te=H.value.trim();if(te===""||S.disabled)return;S.disabled=!0,R.textContent="派发中…";let re;try{re=await(((V=e.dispatchQuick)==null?void 0:V.call(e,C,te))??Promise.resolve({ok:!1,error:"dispatch unavailable"}))}catch(we){re={ok:!1,error:we instanceof Error?we.message:String(we)}}S.disabled=!1,re.ok===!0&&(H.value=""),H.focus({preventScroll:!0}),R.textContent=re.ok===!0?`已派发${re.task_id!==void 0?` · ${re.task_id}`:""} · 回执将入台账(待回执)`:`失败:${re.error??"未知原因"}`}),{form:w,text:H,note:R}}function me(C){const w=O("div","wb-dispatch"),H=O("div","wb-side-head");return H.textContent="快派",w.appendChild(H),(u==null?void 0:u.team)!==C&&(u={team:C,...Y(C)}),w.appendChild(u.form),w}function ce(C){Te.open(C),$.classList.remove("is-rail-open")}function ye(C){if(o===null)return;const w=(o.sessions??[]).find(S=>S.id===C);if(w!==void 0){ce({kind:"session",id:C,title:dt(w),sub:w.team,team:w.team,live:w.live});return}if(C.startsWith("peer-")){const S=C.slice(5),R=(o.peers??[]).find(F=>F.url.includes(S));ce({kind:"peer",id:C,title:R!==void 0?R.url:S,sub:S,url:R==null?void 0:R.url});return}m.find(S=>S.id===C)!==void 0&&ce({kind:"log",id:C,title:`…${C.slice(-12)}`,sub:"档案"})}function oe(){var V,we;E.textContent=(o==null?void 0:o.version)!==void 0?`v${o.version}`:"",E.hidden=(o==null?void 0:o.version)===void 0;const C=Ke(I);if(o===null)return;const w=[],H=rn(o,e.now()),S=H.deadLetters.length;S>0&&w.push({text:`死信 ${S}`,tone:"danger",title:"超过 24h TTL 仍未结算的任务(unconsumed),需在台账清账",tab:"ledger",group:"死信"});const R=H.stale.length;R>0&&w.push({text:`陈旧 ${R}`,tone:"warn",title:"我方派发、要回执、已等待 ≥1h 仍未回执(可催办;免回执行不算)",tab:"ledger",group:"陈旧"});const F=H.owedOverdue.length;F>0&&w.push({text:`欠回执 ${F}`,tone:"warn",title:"对方投递给本机、已等待本机回执超过 1 小时",tab:"ledger",group:"待本机回执"});const te=((V=o.idempotency)==null?void 0:V.conflicts)??0;te>0&&w.push({text:`幂等冲突 ${te}`,tone:"danger",title:"同一幂等键对应了不同载荷,需人工核查",tab:"ledger",group:"取证"});const re=(((we=o.reconcile)==null?void 0:we.rows)??[]).filter(Ie=>Ie.needsRepair===!0).length;if(re>0&&w.push({text:`需修复 ${re}`,tone:"danger",title:"reconcile 无法自动恢复的会话,见行动计划",tab:"plan"}),w.length===0){C.appendChild(O("span","wb-header-ok")).textContent="● 无异常";return}for(const Ie of w){const ee=O("button",`wb-alert wb-alert-${Ie.tone}`);ee.type="button",ee.textContent=Ie.text,ee.title=`${Ie.title}(点击查看)`,ee.addEventListener("click",()=>$e(Ie.tab,Ie.group)),C.appendChild(ee)}}function $e(C,w){var R;const H=q.find(([F])=>F===C)[1];n==="canvas"&&($.classList.add("is-rail-open"),y.select(C,{focus:!1}));const S=w===void 0?H:w==="取证"?H.querySelector("details.wb-led-forensics"):Array.from(H.querySelectorAll(".wb-led-group")).find(F=>F.dataset.group===w)??null;S!==null&&(S instanceof HTMLDetailsElement&&(S.open=!0),(R=S.scrollIntoView)==null||R.call(S,{block:"start",behavior:"smooth"}))}function Je(C){o=C,e.sessionLogList!==void 0&&!M&&(M=!0,e.sessionLogList().then(w=>{m=w.ok&&w.sessions!==void 0?w.sessions:[],d=w.ok?w.count:void 0}).catch(()=>{}).finally(()=>{M=!1,He()})),oe(),He(),vt(),Ve(),at(),Te.update(C),je(),gt(),z(),qe()}function De(C){if(C==="board"){qe();return}y.select(C)}return Je(null),{root:$,update:Je,mode:()=>n,selectTab:De,openNodeChat:ye}}const ft=1e6,fn=.25,pn=3,oo=256,so=96;function $t(e){const t=typeof e=="number"?e:Number.NaN;if(Number.isFinite(t))return Math.max(-ft,Math.min(ft,Math.round(t)))}function io(e){if(e===null||typeof e!="object")return;const t=e,n=$t(t.x),s=$t(t.y);return n===void 0||s===void 0?void 0:{x:n,y:s}}function Xo(e){const t=io(e);if(t===void 0)return;const n=e,s=$t(n.w),o=$t(n.h);if(!(s===void 0||o===void 0||s<=0||o<=0))return{...t,w:Math.min(s,ft),h:Math.min(o,ft)}}function ro(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=$t(s.x),i=$t(s.y),r=s.scale,l=typeof r=="number"?r:Number.NaN;if(o===void 0||i===void 0||!Number.isFinite(l))return;const u=Math.max(fn,Math.min(pn,l)),m={};if(t.nodes!==null&&typeof t.nodes=="object")for(const[h,M]of Object.entries(t.nodes)){if(typeof h!="string"||h===""||h.length>128)continue;const $=io(M);if($!==void 0&&(m[h]=$),Object.keys(m).length>=oo)break}const d={};if(t.frames!==null&&typeof t.frames=="object")for(const[h,M]of Object.entries(t.frames)){if(typeof h!="string"||h===""||h.includes("/")||h.length>40)continue;const $=Xo(M);if($!==void 0&&(d[h]=$),Object.keys(d).length>=so)break}return{version:1,viewport:{x:o,y:i,scale:u},nodes:m,frames:d}}function Ko(e,t,n){const s=r=>Math.max(-ft,Math.min(ft,Math.round(r))),o={};for(const[r,l]of t)if(!(typeof r!="string"||r===""||r.length>128)&&(o[r]={x:s(l.x),y:s(l.y)},Object.keys(o).length>=oo))break;const i={};for(const[r,l]of n){if(typeof r!="string"||r===""||r.includes("/")||r.length>40)continue;const u=s(l.w),m=s(l.h);if(!(u<=0||m<=0)&&(i[r]={x:s(l.x),y:s(l.y),w:Math.min(u,ft),h:Math.min(m,ft)},Object.keys(i).length>=so))break}return{version:1,viewport:{x:s(e.x),y:s(e.y),scale:Math.max(fn,Math.min(pn,e.scale))},nodes:o,frames:i}}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 Re=172,Fe=56,wt=[150,290,430],tt=16;function Uo(e){const t=ao(e),n=Math.floor(t/tt)%wt.length,o=t%tt/tt*Math.PI*2+n*(Math.PI/tt),i=wt[n];return{x:Math.round(Math.cos(o)*i),y:Math.round(Math.sin(o)*i*.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 Ln=64,In=24,Tn=20,zo=4,_n=24,On=44,qo=24;function Vo(e,t,n=Number.POSITIVE_INFINITY){const s=new Set(t),o=lo(e),i=e.map(h=>[...new Set(h.members.map(M=>M.id))].filter(M=>s.has(M)&&o.get(M)===h.name));i.push(t.filter(h=>!o.has(h)));const r=new Map;let l=0,u=0,m=0,d=0;for(const h of i){if(h.length===0)continue;const M=Math.min(3,Math.max(h.length>1?2:1,Math.ceil(Math.sqrt(h.length)))),$=Math.ceil(h.length/M),J=Math.max(260,M*Re+(M-1)*In+_n*2),he=Math.max(160,$*Fe+($-1)*Tn+On+qo);d>0&&(d%zo===0||l+J>n)&&(l=0,u+=m+Ln,m=0),h.forEach((Q,E)=>{const k=E%M,I=Math.floor(E/M);r.set(Q,{x:l+_n+Re/2+k*(Re+In),y:u+On+Fe/2+I*(Fe+Tn)})}),l+=J+Ln,m=Math.max(m,he),d+=1}return r}const Dt=12;function co(e,t){const n=u=>t.every(m=>Math.abs(m.x-u.x)>=Re+Dt||Math.abs(m.y-u.y)>=Fe+Dt),s=Uo(e);if(n(s))return s;const o=ao(e),i=tt*wt.length,r=Math.floor(o/tt)%wt.length*tt+o%tt;for(let u=1;u<i;u++){const m=(r+u)%i,d=Math.floor(m/tt),h=m%tt/tt*Math.PI*2+d*(Math.PI/tt),M=wt[d],$={x:Math.round(Math.cos(h)*M),y:Math.round(Math.sin(h)*M*.6)};if(n($))return $}const l=wt[wt.length-1];for(let u=0;;u++)for(let m=0;m<6;m++){const d={x:Math.round(-l+m*(Re+Dt)),y:Math.round(l*.6+Fe*2+u*(Fe+Dt))};if(n(d))return d}}function it(e){return{x:e.x-Re/2,y:e.y-Fe/2,w:Re,h:Fe}}function hn(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 d of e)t=Math.min(t,d.x),n=Math.min(n,d.y),s=Math.max(s,d.x+d.w),o=Math.max(o,d.y+d.h);const i=24,r=44,l=24,u=Math.max(260,Math.round(s-t+i*2)),m=Math.max(160,Math.round(o-n+r+l));return{x:Math.round(t-i),y:Math.round(n-r),w:u,h:m}}class bn{constructor(){Ct(this,"revisionCounter",0);Ct(this,"nodes",new Map);Ct(this,"frames",new Map);Ct(this,"selection",new Set);Ct(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 i of t){const r=this.nodes.get(i);r!==void 0&&(r.x+=n,r.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=it(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(i=>i.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(r=>r.team!==t),i=n.indexOf(s.id);i>=0&&o.push({team:t,index:i}),s.memberships=o}this.bump()}contentBounds(){let t=Number.POSITIVE_INFINITY,n=Number.POSITIVE_INFINITY,s=Number.NEGATIVE_INFINITY,o=Number.NEGATIVE_INFINITY;const i=r=>{t=Math.min(t,r.x),n=Math.min(n,r.y),s=Math.max(s,r.x+r.w),o=Math.max(o,r.y+r.h)};for(const r of this.nodes.values())r.remote!==!0&&i(it(r));for(const r of this.frames.values())i(r);return t===Number.POSITIVE_INFINITY?null:{minX:t,minY:n,maxX:s,maxY:o}}static fromState(t){const n=new bn,s=ro(t.layout),o=new Map;for(const i of t.teams)for(let r=0;r<i.members.length;r++){const l=i.members[r].id,u=o.get(l)??[];u.push({team:i.name,index:r}),o.set(l,u)}for(const i of t.sessions){if(i.joined!==!0)continue;const r=s==null?void 0:s.nodes[i.id];let l,u;if(r!==void 0&&typeof r.x=="number"&&typeof r.y=="number")l=r.x,u=r.y;else{const m=co(i.id,[...n.nodes.values()]);l=m.x,u=m.y}n.nodes.set(i.id,{id:i.id,x:l,y:u,label:i.label,team:i.team,name:i.name,description:i.description,live:i.live!==!1,memberships:o.get(i.id)??[]})}for(const i of t.teams){const r=s==null?void 0:s.frames[i.name];if(r!==void 0){n.frames.set(i.name,{x:r.x,y:r.y,w:r.w,h:r.h});continue}const l=[];for(const u of i.members){const m=n.nodes.get(u.id);m!==void 0&&l.push(it(m))}l.length>0&&n.frames.set(i.name,hn(l))}return n.viewport=s!==void 0?{...s.viewport}:{x:0,y:0,scale:1},n}}const Jo=24,uo=-13,Go=uo+Jo;function Qo(e,t,n){const s=[],o=new Set;for(const i of e){const r=t.get(i.name);if(r===void 0)continue;const l=r.x+r.w/2,u=r.y+Go;for(const m of i.members){const d=n.get(m.id);if(d===void 0)continue;const h=o.has(m.id);o.add(m.id),s.push({x1:l,y1:u,x2:d.x,y2:d.y-Fe/2,dashed:h,team:i.name,id:m.id})}}return s}function Zo(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 Qo(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 es(e){return`peer-${st(e).replace(/[^A-Za-z0-9.:\[\]-]/g,"-")}`}function st(e){try{return new URL(e).host}catch{return e}}function ts(e){const t=new Map;for(const n of e){const s=n.via!==void 0&&n.via!==""?st(n.via):"",o=t.get(s)??[];o.push(n),t.set(s,o)}return t}const ns=140,os=200,ss=90,is=20,Rt=60;function rs(e,t){const n=t!==null?t.maxX+ns:os,s=t!==null?t.minY:0;return e.map((o,i)=>({url:o.url,score:o.score,x:n,y:s+i*ss}))}function as(e,t,n,s){const o=new Map;for(const r of e){if(!t.has(r.team))continue;const l=`${r.team}\0${r.peer}`,u=o.get(l);u===void 0?o.set(l,{team:r.team,peer:r.peer,startedAt:r.startedAt,count:1}):(u.startedAt=Math.min(u.startedAt,r.startedAt),u.count+=1)}const i=[];for(const r of o.values()){const l=t.get(r.team);if(l===void 0)continue;const u=n.find(d=>{try{return new URL(d.url).host===r.peer}catch{return!1}});if(u===void 0)continue;const m=Math.max(0,Math.round((s-r.startedAt)/1e3));i.push({x1:l.x,y1:l.y,x2:u.x,y2:u.y,label:`a2a_route · ${r.peer} · ${m}s`+(r.count>1?` ×${r.count}`:"")})}return i}function ls(e,t){const n=t!==null?{x:t.maxX+is,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 cs(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,i=e!==null?e.maxY:Number.NEGATIVE_INFINITY;for(const r of t)n=Math.min(n,r.x-Rt),s=Math.min(s,r.y-Rt),o=Math.max(o,r.x+Rt),i=Math.max(i,r.y+Rt);return{minX:n,minY:s,maxX:o,maxY:i}}const ds=11;function us(e,t){let n=[],s=[],o=[];function i(l){for(const d of n)d.remove();n=[];const u=t.allNodes().filter(d=>d.remote===!0).map(d=>({url:d.peerUrl??d.id.slice(5),score:d.score,x:d.x,y:d.y}));s=u;const m=t.contentBounds();if(m!==null){const d=new Map;for(const[h,M]of t.allFrames())d.set(h,{name:h,x:M.x+M.w/2,y:M.y+ds});for(const h of as(o,d,u,l))n.push(...r(h,"e-activity",h.label));for(const h of ls(u,m))n.push(...r(h,"e-federal",h.label))}}function r(l,u,m){const d=document.createElementNS("http://www.w3.org/2000/svg","line");d.setAttribute("class",u),d.setAttribute("x1",String(l.x1)),d.setAttribute("y1",String(l.y1)),d.setAttribute("x2",String(l.x2)),d.setAttribute("y2",String(l.y2)),e.appendChild(d);const h=[d];if(m!==""){const M=document.createElementNS("http://www.w3.org/2000/svg","text");M.setAttribute("class","edge-label mono"),M.setAttribute("x",String((l.x1+l.x2)/2+14)),M.setAttribute("y",String((l.y1+l.y2)/2+18)),M.textContent=m,e.appendChild(M),h.push(M)}return h}return{render:i,flyTo(l){return l(),s},placements:()=>s,setInFlight:l=>{o=l}}}function ms(e,t){const n=new Map,s=new Set;for(const o of e){if(o.joined!==!0)continue;const i=o.team.lastIndexOf("/");if(i<=0||o.team.slice(i+1)!==o.id.replace(/^session-/,"").slice(0,8))continue;const r=o.team;t.has(r)||s.has(r)||(n.has(r)?(n.delete(r),s.add(r)):n.set(r,o.id))}return n}function fs(e,t,n,s){var r;const o=t.get(e);return o!==void 0?o:e.includes("/")?`member-${e.replace(/[^a-z0-9-]/gi,"-")}`:`member-${((r=n==null?void 0:n.find(l=>l.via===s))==null?void 0:r.team.split("/")[0])??"dsh"}-${e.replace(/^session-/,"").slice(0,8)}`}const Fn={x:0,y:0,scale:1};function Ut(e){return Math.max(fn,Math.min(pn,e))}function kt(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:Ut(t)}}function ut(e,t,n){return{x:e.x+t/e.scale,y:e.y+n/e.scale}}function nn(e,t,n){return{x:e.x+t/e.scale,y:e.y+n/e.scale,scale:e.scale}}function Pn(e,t,n,s){const o=Ut(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 ps=680,hs=.8,bs=.6,Dn=16;function gn(e,t,n,s=Number.POSITIVE_INFINITY){if(e===null||t<=0||n<=0)return Fn;const o=e.maxX-e.minX,i=e.maxY-e.minY;if(!(o>0)||!(i>0))return Fn;const r=.9*Math.min(t/o,n/i),l=Math.min(s,r),u=t<ps?hs:bs;if(r<u){const d=Ut(Math.min(s,u));return{x:e.minX-Dn/d,y:e.minY-Dn/d,scale:d}}const m=Ut(l);return{x:(e.minX+e.maxX)/2-t/(2*m),y:(e.minY+e.maxY)/2-n/(2*m),scale:m}}function gs(e){return`translate(${-e.x*e.scale}px, ${-e.y*e.scale}px) scale(${e.scale})`}function Rn(e,t){let n=e===null?null:{...e,minY:e.minY+uo};for(const s of t){if(s.remote!==!0)continue;const o=it(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 Bn(e,t,n,s){const o=s>0&&s<n/2?s:0,i=gn(e,t,n-o,1);return o===0||e===null?i:{...i,y:i.y-o/i.scale}}function Hn(...e){const t=Math.max(0,...e.map(n=>n.offsetHeight>0?n.offsetTop+n.offsetHeight:0));return t>0?t+8:0}function ln(e){return e.type==="join-network"||e.type==="leave-network"?"$network":e.type==="create-team"||e.type==="remove-team"?e.name:e.team}function vs(e,t){if(t.type==="create-team"){const o=t.ids.map(i=>e.getNode(i)).filter(i=>i!==void 0).map(i=>it(i));return o.length>0&&e.setFrame(t.name,hn(o)),e.setTeamMembers(t.name,t.ids),()=>{e.setTeamMembers(t.name,e.teamMemberIds(t.name).filter(i=>!t.ids.includes(i))),e.removeFrame(t.name)}}if(t.type==="add-member"){const o=e.teamMemberIds(t.team),i=t.ids.filter(r=>!o.includes(r));return e.setTeamMembers(t.team,[...o,...i]),()=>{e.setTeamMembers(t.team,e.teamMemberIds(t.team).filter(r=>!i.includes(r)))}}if(t.type==="remove-member"){const o=e.teamMemberIds(t.team);return e.setTeamMembers(t.team,o.filter(i=>!t.ids.includes(i))),()=>{const i=e.teamMemberIds(t.team);e.setTeamMembers(t.team,[...i,...t.ids.filter(r=>!i.includes(r))])}}if(t.type==="remove-team"){const o=e.teamMemberIds(t.name),i=e.getFrame(t.name),r=i!==void 0?{...i}:void 0;return e.setTeamMembers(t.name,[]),e.removeFrame(t.name),()=>{r!==void 0&&e.setFrame(t.name,r),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(i=>i!==o.id):s.push(o.id);return e.setTeamMembers(t.team,s),()=>{let o=e.teamMemberIds(t.team);for(let i=0;i<n.length;i++){const r=n[i];o[i]!==r&&o.includes(r)&&(o=o.filter(l=>l!==r),o.push(r))}e.setTeamMembers(t.team,o)}}function jn(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(ln(t))!==void 0)return o;const r={...o.frames};return delete r[ln(t)],{...o,frames:r}}function cn(e,t){const n=[...e],s=[];for(let o=0;o<t.length;o++){const i=t[o];n[o]!==i&&n.includes(i)&&(s.push({op:"remove",id:i}),s.push({op:"add",id:i}),n.splice(n.indexOf(i),1),n.push(i))}return s}function ys(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 Yn(e,t){let n,s=Number.POSITIVE_INFINITY;for(const[o,i]of e){if(t.x<i.x||t.x>i.x+i.w||t.y<i.y||t.y>i.y+i.h)continue;const r=i.w*i.h;r<s&&(n=o,s=r)}return n}const Wn=[9133302,3900150,1357990,16096779,15485081,8702998];function ws(e){const{root:t,netBtn:n,signal:s,model:o}=e;function i(){return o.selectedIds().map(T=>{var y;return{id:T,y:((y=o.getNode(T))==null?void 0:y.y)??0}}).sort((T,y)=>T.y-y.y).map(T=>T.id)}function r(){if(l!==null)return;const T=i().filter(y=>{const p=o.getNode(y);return p===void 0?!1:p.remote!==!0||p.remoteHandle!==void 0&&p.remoteHandle!==""});if(T.length<2){e.notice("info","框选至少 2 个会话节点");return}u(T)}let l=null;function u(T){const y=document.createElement("div");y.className="p-dialog";const p=document.createElement("div");p.className="p-dialog-panel",p.setAttribute("role","dialog"),p.setAttribute("aria-modal","true"),p.setAttribute("aria-labelledby","p-dialog-title");const _=document.createElement("div");_.id="p-dialog-title",_.className="p-dialog-title",_.textContent=`组建团队(${T.length} 个节点,自上而下即优先级)`;const b=document.createElement("input");b.className="p-dialog-input",b.maxLength=40,b.setAttribute("aria-label","团队名");const D=document.createElement("div");D.className="p-dialog-err",D.setAttribute("aria-live","polite");const B=document.createElement("div");B.className="p-dialog-row";const se=document.createElement("button");se.type="button",se.textContent="组建";const pe=document.createElement("button");pe.type="button",pe.textContent="取消",B.append(se,pe),p.append(_,b,D,B),y.appendChild(p),t.appendChild(y);const Me=document.activeElement,P=()=>{y.remove(),l=null,Me==null||Me.focus()},q=()=>{const Se=b.value.trim();return Se===""||Se.length>40||Se.includes("/")||/^\d+$/.test(Se)?"队名需 1..40 字,不含“/”,不为纯数字":null},ie=()=>{const Se=q();if(Se!==null){D.textContent=Se,b.focus();return}const G=b.value.trim();if(P(),o.getFrame(G)!==void 0){e.notice("info",`已加入现有团队「${G}」`),e.emit({type:"add-member",team:G,ids:T});return}e.emit({type:"create-team",name:G,ids:T,created:!0})};se.addEventListener("click",ie),pe.addEventListener("click",P),b.addEventListener("keydown",Se=>{const G=Se;G.key==="Enter"&&(G.preventDefault(),ie()),G.key==="Escape"&&(G.preventDefault(),P())}),y.addEventListener("keydown",Se=>{const G=Se;if(G.key==="Escape"){G.preventDefault(),G.stopPropagation(),P();return}if(G.key!=="Tab")return;G.preventDefault();const j=Array.from(p.querySelectorAll("input, button")),xe=j.indexOf(document.activeElement),ue=G.shiftKey?j[(xe-1+j.length)%j.length]:j[(xe+1)%j.length];ue==null||ue.focus()},s),l={wrap:y,restoreFocus:Me},b.focus()}let m=null,d="root",h=null,M=null,$=[];function J(){M==null||M.remove(),M=null}function he(){var p;if(M!==null){J();return}if($.length===0)return;const T=document.createElement("div");T.className="p-menu p-netmenu",T.setAttribute("role","menu"),T.setAttribute("aria-label","未入网会话");for(const _ of $)T.appendChild(E(`${_.name!==void 0&&_.name!==""?_.name:_.label} — 入网`,!0,()=>{J(),e.emit({type:"join-network",id:_.id})}));M=T,t.appendChild(T);const y=n.getBoundingClientRect();T.style.left=`${String(Math.min(y.left,window.innerWidth-220))}px`,T.style.top=`${String(Math.max(8,y.top-($.length*30+10)))}px`,T.addEventListener("keydown",_=>{_.key==="Escape"&&(_.stopPropagation(),J(),n.focus())}),(p=T.querySelector("button"))==null||p.focus(),document.addEventListener("pointerdown",_=>{if(M===null)return;const b=_.target;b!==null&&(b.closest(".p-netmenu")!==null||b===n||n.contains(b))||J()},s)}function Q(){m==null||m.remove(),m=null,d="root",h!==null&&h.isConnected?h.focus():t.focus(),h=null}function E(T,y,p){const _=document.createElement("button");return _.type="button",_.setAttribute("role","menuitem"),_.textContent=T,y?_.addEventListener("click",()=>{Q(),p()}):(_.disabled=!0,_.setAttribute("aria-disabled","true")),_}function k(T,y,p,_="root",b){var pe,Me,P,q,ie,Se;b!==void 0&&(h=b),h===null&&(h=e.anchorFor(p)),m==null||m.remove(),d=_;const D=document.createElement("div");D.className="p-menu",D.setAttribute("role","menu"),D.setAttribute("aria-label","团队操作");let B=[];if(p.kind==="frame")B=[E(`解散团队「${p.name}」`,!0,()=>e.emit({type:"remove-team",name:p.name}))];else{const G=p.id;if(_==="root"){const j=E("组成团队…",o.selectedIds().length>=2,()=>u(i()));j.title="先框选或 Shift 加选至少 2 个节点",B.push(j),e.teams().length>0&&(B.push(E("加入团队 ▸",!0,()=>k(T,y,p,"join"))),(((pe=o.getNode(G))==null?void 0:pe.memberships.map(ue=>ue.team))??[]).length>0&&(B.push(E("置顶路由 ▸",!0,()=>k(T,y,p,"promote"))),B.push(E("离队 ▸",!0,()=>k(T,y,p,"leave"))))),((Me=o.getNode(G))==null?void 0:Me.remote)!==!0&&B.push(E("退网",!0,()=>e.emit({type:"leave-network",id:G})))}else{B.push(E("‹ 返回",!0,()=>k(T,y,p,"root")));for(const j of e.teams())if(_==="join"){const xe=((P=o.getNode(G))==null?void 0:P.memberships.some(ue=>ue.team===j.name))??!0;B.push(E(xe?`${j.name}(已加入)`:j.name,!xe,()=>e.emit({type:"add-member",team:j.name,ids:[G]})))}else if(_==="leave"){const xe=((q=o.getNode(G))==null?void 0:q.memberships.some(ue=>ue.team===j.name))??!1;B.push(E(j.name,xe,()=>e.emit({type:"remove-member",team:j.name,ids:[G]})))}else{const xe=((ie=o.getNode(G))==null?void 0:ie.memberships.some(ue=>ue.team===j.name))??!1;B.push(E(j.name,xe,()=>{const ue=o.teamMemberIds(j.name),ke=[G,...ue.filter(Te=>Te!==G)];e.emit({type:"reorder",team:j.name,ops:cn(ue,ke)})}))}}}D.append(...B),D.style.left=`${Math.min(T,window.innerWidth-200)}px`;const se=B.length*30+8;D.style.top=`${Math.max(8,Math.min(y,window.innerHeight-se-8))}px`,D.addEventListener("keydown",G=>{var ke,Te,et,qe;const j=G,xe=Array.from(D.querySelectorAll("[role=menuitem]")),ue=xe.indexOf(document.activeElement);j.key==="ArrowDown"?(j.preventDefault(),(ke=xe[(ue+1+xe.length)%xe.length])==null||ke.focus()):j.key==="ArrowUp"?(j.preventDefault(),(Te=xe[(ue-1+xe.length)%xe.length])==null||Te.focus()):j.key==="Home"?(j.preventDefault(),(et=xe[0])==null||et.focus()):j.key==="End"?(j.preventDefault(),(qe=xe[xe.length-1])==null||qe.focus()):j.key==="Escape"&&(j.preventDefault(),j.stopPropagation(),d!=="root"?k(T,y,p,"root"):Q())}),t.appendChild(D),m=D,(Se=B[0])==null||Se.focus()}function I(T,y,p){if(l!==null)return;const _=(p==null?void 0:p.closest(".p-node"))??null;if(_!==null){const B=o.getNode(_.dataset.id??"");if((B==null?void 0:B.remote)===!0&&(B.remoteHandle===void 0||B.remoteHandle===""))return}const b=_,D=(p==null?void 0:p.closest(".p-frame-head"))??null;if(b!==null){const B=b.dataset.id??"";o.isSelected(B)||o.setSelection([B]),h=b,k(T,y,{kind:"node",id:B})}else D!==null&&(h=D,k(T,y,{kind:"frame",name:D.dataset.frame??""}))}function x(T){$=T,n.textContent=`未入网${$.length>0?`(${String($.length)})`:""}`,n.disabled=$.length===0,n.setAttribute("aria-disabled",String($.length===0)),$.length===0&&J()}return{menuItem:E,isMenuOpen:()=>m!==null,isDialogOpen:()=>l!==null,closeMenu:Q,openMenu:k,contextMenuAt:I,openNameDialog:u,startCreateFromSelection:r,toggleNetMenu:he,setUnjoined:x}}function xs(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 Cs(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 ks(e,t=1200){e!==void 0&&(e.classList.add("pulse"),setTimeout(()=>e.classList.remove("pulse"),t))}function Es(e){return t=>{const n=e.model.getNode(t);if(n===void 0)return;const s=e.viewSize();e.setVp(gn({minX:n.x,minY:n.y,maxX:n.x+Re,maxY:n.y+Fe},s.w,s.h,1)),e.applyViewport(),e.markDirty(),ks(e.cardEl(t))}}function $s(e,t,n,s){const o=Ns({onPick:s});return e.appendChild(o.root),{...o,refresh:()=>o.setIndex(Cs(t,n))}}function Ns(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=[],i=[],r=0;const l=()=>{s.style.display="none",s.textContent=""},u=()=>{if(s.textContent="",i.length===0){l();return}i.forEach((h,M)=>{const $=document.createElement("div");$.className="p-search-hit"+(M===r?" active":""),$.dataset.id=h.id,$.textContent=h.name===h.team?h.name:`${h.name} · ${h.team}`,$.addEventListener("mousedown",J=>{J.preventDefault(),e.onPick(h.id),m()}),s.appendChild($)}),s.style.display="block"},m=()=>{n.value="",i=[],l()},d=()=>{i=xs(o,n.value),r=0,u()};return n.addEventListener("input",d),n.addEventListener("keydown",h=>{if(h.key==="Escape"){m(),n.blur(),h.stopPropagation();return}if(h.key==="ArrowDown"||h.key==="ArrowUp"){if(i.length===0)return;h.preventDefault(),r=(r+(h.key==="ArrowDown"?1:i.length-1))%i.length,u();return}h.key==="Enter"&&i.length>0&&(h.preventDefault(),e.onPick(i[r].id),m())}),t.append(n,s),{root:t,setIndex(h){o=h,n.value!==""&&d()},focus(){n.focus(),n.select()},clear(){m()}}}const Bt=28,Xn=16,Kn=14,Un=48,Ms=4,Ss=180,As=90,Ls=1600;function Is(e){const t=e.wrapWidth??Ls,n=e.frames.map(u=>{const m=Math.max(u.soleIds.length,1),d=Math.min(Ms,Math.max(1,Math.ceil(Math.sqrt(m)))),h=Math.ceil(m/d),M=Math.max(Ss,Bt*2+d*Re+(d-1)*Xn),$=Math.max(As,Bt*2+h*Fe+(h-1)*Kn);return{name:u.name,w:M,h:$,rows:h,perRow:d,soleIds:u.soleIds}}),s=[],o=[];let i=0,r=0,l=0;for(const u of n){i>0&&i+u.w>t&&(i=0,r+=l+Un,l=0);const m={x:i,y:r,w:u.w,h:u.h};s.push({name:u.name,rect:m});const d=m.x+Bt+Re/2;let h=m.y+Bt+Fe/2;u.soleIds.forEach((M,$)=>{const J=$%u.perRow;$>0&&J===0&&(h+=Fe+Kn),o.push({id:M,x:d+J*(Re+Xn),y:h})}),i+=u.w+Un,l=Math.max(l,u.h)}return{frames:s,seats:o}}function Ts(e,t){const n=[];for(const[o,i]of e.allFrames()){if(t.has(o))continue;const r=e.teamMemberIds(o).map(l=>e.getNode(l)).filter(l=>l!==void 0).filter(l=>l.memberships.length===1).map(l=>l.id);n.push({name:o,rect:i,soleIds:r})}if(n.length===0)return!1;const s=Is({frames:n});for(const o of s.frames)e.setFrame(o.name,o.rect);for(const o of s.seats){const i=e.getNode(o.id);i!==void 0&&e.dragNodes([o.id],o.x-i.x,o.y-i.y)}return!0}function _s(e,t){if(e===void 0)return;const n=st(e);return{text:t?`同步中… · ${n}`:`镜像 · ${n}`,title:t?`已把改动交给属主 ${n},等待它确认`:`这个团队属于 ${n},这里显示的是它的镜像;拖入或移出成员会经中继交给 ${n} 执行`,syncing:t}}const Os=1e4;function Fs(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 i=n.get(t(s.fleetPeer,s.name));i!==void 0&&(o?i.acceptedAt=e():n.delete(t(s.fleetPeer,s.name)))},hides(s,o){return n.has(t(o,s))},sweep(s){var o;for(const[i,r]of n)(!(((o=s.find(u=>u.url===r.url))==null?void 0:o.org.some(u=>u.name===r.name))===!0)||r.acceptedAt!==void 0&&e()-r.acceptedAt>Os)&&n.delete(i)}}}const xt=24,Ps=200,Yt=(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 Ds(e,t){const n=t.x+t.w+xt-e.x,s=t.x-xt-(e.x+e.w),o=t.y+t.h+xt-e.y,i=t.y-xt-(e.y+e.h),r=Math.abs(n)<=Math.abs(s)?n:s,l=Math.abs(o)<=Math.abs(i)?o:i;return Math.abs(r)<=Math.abs(l)?{dx:r,dy:0}:{dx:0,dy:l}}function Rs(e,t,n,s){const o=e.beginFrameDrag(t);o!==void 0&&e.applyFrameDrag(o,n,s)}function Bs(e,t,n){let s=!1;for(let o=0;o<Ps;o++){const i=e.allFrames();let r;for(let E=0;E<i.length&&r===void 0;E++)for(let k=E+1;k<i.length;k++){const[I,x]=i[E],[T,y]=i[k];if(!(t.has(I)&&t.has(T))&&Yt(x,y)){r=[I,x,T,y];break}}if(r===void 0)return s;const[l,u,m,d]=r,h=E=>t.has(E)?2:E===n?1:0,[M,$,J]=h(l)<h(m)?[l,u,d]:[m,d,u],{dx:he,dy:Q}=Ds($,J);Rs(e,M,he,Q),s=!0}return s}const pt=28,Wt=16,zt=14;function Hs(e){const t=[];for(let n=e.y+pt;n+Fe<=e.y+e.h-pt;n+=Fe+zt)for(let s=e.x+pt;s+Re<=e.x+e.w-pt;s+=Re+Wt)t.push({x:s+Re/2,y:n+Fe/2});return t}function js(e){let t=!1;const n=e.allFrames(),s=new Map(n);for(const o of e.allNodes()){const i=new Set(o.memberships.map(Q=>Q.team)),r=n.find(([Q,E])=>!i.has(Q)&&Yt(it(o),E));if(r===void 0)continue;const l=r[1],u=Q=>{const E=it(Q);return n.every(([k,I])=>i.has(k)||!Yt(E,I))&&e.allNodes().every(k=>k.id===o.id||!Yt(E,it(k)))},d=o.memberships.map(Q=>s.get(Q.team)).filter(Q=>Q!==void 0).flatMap(Hs).find(u),h={x:l.x+l.w+xt+Re/2,y:o.y},M={x:o.x,y:l.y+l.h+xt+Fe/2},$=Math.max(...n.map(([,Q])=>Q.x+Q.w))+xt+Re/2,J=Array.from({length:2*e.allNodes().length+1},(Q,E)=>({x:$,y:l.y+Fe/2+E*(Fe+zt)})),he=d??[h,M,...J].find(u)??J[J.length-1];e.dragNodes([o.id],he.x-o.x,he.y-o.y),t=!0}return t}function Ht(e,t,n){const s=Bs(e,t,n),o=js(e);return s||o}function Ys(e){for(const[t,n]of e.allFrames()){const s=e.teamMemberIds(t).map(m=>e.getNode(m)).filter(m=>m!==void 0).filter(m=>m.memberships.length===1);if(s.length===0)continue;const o=Math.max(1,Math.floor((n.w-2*pt+Wt)/(Re+Wt))),i=Math.ceil(s.length/o),r=pt*2+i*Fe+(i-1)*zt;r>n.h&&e.setFrame(t,{...n,h:Math.min(r,n.h+400)});const l=n.x+pt+Re/2;let u=n.y+pt+Fe/2;s.forEach((m,d)=>{const h=d%o;d>0&&h===0&&(u+=Fe+zt);const M=l+h*(Re+Wt);e.dragNodes([m.id],M-m.x,u-m.y)})}}const Ws=30;function Xs(e){const t=[],n=()=>({nodes:new Map(e.allNodes().map(i=>[i.id,{x:i.x,y:i.y}])),frames:new Map(e.allFrames().map(([i,r])=>[i,{...r}]))}),s=i=>e.allNodes().some(r=>{const l=i.nodes.get(r.id);return l!==void 0&&(l.x!==r.x||l.y!==r.y)})||e.allFrames().some(([r,l])=>{const u=i.frames.get(r);return u!==void 0&&(u.x!==l.x||u.y!==l.y||u.w!==l.w||u.h!==l.h)}),o=i=>{for(const r of e.allNodes()){const l=i.nodes.get(r.id);l!==void 0&&(l.x!==r.x||l.y!==r.y)&&e.dragNodes([r.id],l.x-r.x,l.y-r.y)}for(const[r,l]of e.allFrames()){const u=i.frames.get(r);u!==void 0&&(u.x!==l.x||u.y!==l.y||u.w!==l.w||u.h!==l.h)&&e.setFrame(r,{...u})}};return{capture:n,commit(i){s(i)&&(t.push(i),t.length>Ws&&t.shift())},undo(){const i=t.pop();return i===void 0?!1:(o(i),!0)},revert(i){return s(i)?(o(i),!0):!1},get depth(){return t.length}}}function Ks(e){const{root:t,trigger:n,signal:s,model:o}=e;let i=null,r="",l=null;function u(){l==null||l.remove(),l=null}function m(){u(),i==null||i.remove(),i=null}function d(){if(i!==null){m();return}const k=document.createElement("div");k.className="p-menu p-nodelist",k.setAttribute("role","dialog"),k.setAttribute("aria-label","节点清单"),i=k,t.appendChild(k);const I=n.getBoundingClientRect();k.style.left=`${String(Math.min(I.left,window.innerWidth-340))}px`,k.style.top=`${String(Math.max(8,I.top-320))}px`,k.addEventListener("keydown",x=>{x.key==="Escape"&&(x.stopPropagation(),m(),n.focus())}),h()}function h(){var _;const k=i;if(k===null)return;u(),k.textContent="";const I=document.createElement("div");I.className="p-nodelist-head";const x=document.createElement("span");x.className="p-nodelist-title",x.textContent="节点";const T=document.createElement("select");T.className="p-nodesel",T.setAttribute("aria-label","选择 host 或对等节点");const y=document.createElement("option");y.value="",y.textContent="本机",T.appendChild(y);for(const[b,D]of e.facts().remoteTeams){if(b==="")continue;const B=document.createElement("option");B.value=b,B.textContent=((_=D[0])==null?void 0:_.origin)!==void 0&&D[0].origin!==""?`${D[0].origin}(${b})`:b,T.appendChild(B)}r!==""&&!e.facts().remoteTeams.has(r)&&(r=""),T.value=r,T.addEventListener("change",()=>{r=T.value,h()}),I.append(x,T);const p=document.createElement("div");p.className="p-nodelist-body",k.append(I,p),r===""?Q(p):E(p,e.facts().remoteTeams.get(r)??[])}function M(k,I){const x=document.createElement("span");return x.className="p-nodedot"+(I!==!0?" off":k===!1?" cold":""),x}function $(k,I){const x=document.createElement("button");return x.type="button",x.className="p-listbtn",x.textContent=k,x.addEventListener("click",T=>{T.stopPropagation(),I()}),x}function J(k,I){const x=document.createElement("div");if(x.className="p-nodelist-group",x.textContent=k,I!==void 0){const T=document.createElement("span");T.className="p-nodelist-note",T.textContent=I,x.appendChild(T)}return x}function he(k,I){var y,p;u();const x=document.createElement("div");x.className="p-menu",x.setAttribute("role","menu"),x.setAttribute("aria-label","加入团队");for(const _ of e.facts().teams){const b=((y=o.getNode(I))==null?void 0:y.memberships.some(D=>D.team===_.name))??!1;x.appendChild(e.menuItem(b?`${_.name}(已加入)`:_.name,!b,()=>{m(),e.emit({type:"add-member",team:_.name,ids:[I]})}))}x.appendChild(e.menuItem("新团队…",!0,()=>{m(),e.openNameDialog([I])})),l=x,t.appendChild(x);const T=k.getBoundingClientRect();x.style.left=`${String(Math.min(T.right+4,window.innerWidth-180))}px`,x.style.top=`${String(Math.max(8,T.top-60))}px`,x.addEventListener("keydown",_=>{_.key==="Escape"&&(_.stopPropagation(),u(),k.focus())}),(p=x.querySelector("button"))==null||p.focus()}function Q(k){var p,_;const I=new Set(e.facts().canvasMemberIds);for(const b of e.facts().sessions)b.teams!==void 0&&b.teams.length>0&&I.add(b.id);const x=e.facts().sessions.filter(b=>b.joined===!0&&!I.has(b.id)),T=e.facts().sessions.filter(b=>b.joined!==!0),y=e.facts().sessions.filter(b=>b.joined===!0&&I.has(b.id));k.appendChild(J(`未组队 (${String(x.length)})`,"无网络能力"));for(const b of x){const D=document.createElement("div");D.className="p-noderow";const B=document.createElement("span");B.className="p-nodename",B.textContent=b.name!==void 0&&b.name!==""?b.name:b.label,B.title=b.team;const se=document.createElement("span");se.className="p-nonet",se.textContent="无网络能力";const pe=$("入队▸",()=>he(pe,b.id));D.append(M(b.live,!0),B,se,pe,$("退网",()=>{m(),e.emit({type:"leave-network",id:b.id})})),k.appendChild(D)}k.appendChild(J(`未入网 (${String(T.length)})`));for(const b of T){const D=document.createElement("div");D.className="p-noderow";const B=document.createElement("span");B.className="p-nodename",B.textContent=b.name!==void 0&&b.name!==""?b.name:b.label,B.title=b.id,D.append(M(b.live,!1),B,$("入网",()=>{m(),e.emit({type:"join-network",id:b.id})})),k.appendChild(D)}k.appendChild(J(`已组队 (${String(y.length)})`,"画布展示"));for(const b of y){const D=document.createElement("div");D.className="p-noderow";const B=document.createElement("span");B.className="p-nodename",B.textContent=b.name!==void 0&&b.name!==""?b.name:b.label,B.title=b.team;const se=((p=o.getNode(b.id))==null?void 0:p.memberships.length)??0,pe=((_=b.teams)==null?void 0:_.length)??0,Me=document.createElement("span");Me.className="p-teamcount",Me.textContent=`队×${String(Math.max(se,0)+pe)}`,D.append(M(b.live,!0),B,Me,$("定位",()=>{e.locate(b.id)})),k.appendChild(D)}if(e.facts().sessions.length===0){const b=document.createElement("div");b.className="p-nodelist-empty",b.textContent="无会话节点",k.appendChild(b)}}function E(k,I){var y;const x=I.filter(p=>p.teams===void 0||p.teams.length===0),T=I.filter(p=>p.teams!==void 0&&p.teams.length>0);k.appendChild(J(`未组队 (${String(x.length)})`,"无网络能力 · 只读"));for(const p of x){const _=document.createElement("div");_.className="p-noderow";const b=document.createElement("span");b.className="p-nodename",b.textContent=p.name!==void 0&&p.name!==""?p.name:p.team,b.title=p.team;const D=document.createElement("span");D.className="p-nonet",D.textContent="无网络能力",_.append(M(!0,!0),b,D),k.appendChild(_)}k.appendChild(J(`已组队 (${String(T.length)})`,"只读"));for(const p of T){const _=document.createElement("div");_.className="p-noderow";const b=document.createElement("span");b.className="p-nodename",b.textContent=p.name!==void 0&&p.name!==""?p.name:p.team,b.title=p.team;const D=document.createElement("span");D.className="p-teamcount",D.textContent=`队×${String(((y=p.teams)==null?void 0:y.length)??0)}`,_.append(M(!0,!0),b,D),k.appendChild(_)}if(I.length===0){const p=document.createElement("div");p.className="p-nodelist-empty",p.textContent="该节点未发布会话",k.appendChild(p)}}return document.addEventListener("pointerdown",k=>{if(i===null)return;const I=k.target;if(I===null){m();return}I.closest(".p-nodelist")!==null||I.closest(".p-menu")!==null||I===n||n.contains(I)||m()},s),{toggle:d,close:m,refresh:()=>{i!==null&&h()}}}function Us(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 zs(e,t){const n=e.map(i=>i.name!==void 0&&i.name!==""?i.name:i.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 qs(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 u=e.id.slice(5),m=t.length===1&&t[0].name!==void 0&&t[0].name!==""?t[0].name:void 0,d=zs(t,n);return m!==void 0?{title:m,sub:`${u} · ${d}`,tip:`${m}
6
- ${u}
7
- ${d}`}:{title:u,sub:d,tip:`${u}
8
- ${d}`}}const s=ot(e),o=e.team+(e.name!==void 0&&e.name!==""?" · "+e.name:""),i=Us(e.description??""),r=i!==""?i:o===s?"":e.team,l=(e.memberships.length>1?` · 跨队×${e.memberships.length}`:"")+(e.teams!==void 0&&e.teams.length>0?` · 网络队×${e.teams.length}`:"");return{title:s,sub:r+l,tip:i!==""?`${o}
9
- ${i}`:o}}const zn="dsh-a2a.board.legend";function Vs(){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,i,r)=>{const l=document.createElement("span"),u=document.createElement("i");o&&(u.className="dashed"),r!==void 0&&(u.style.borderTopColor=r),l.append(u,document.createTextNode(i)),n.appendChild(l)};s(!1,"成员边(星形,框→成员)"),s(!0,"跨队多属(虚线)"),s(!1,"活动边(inFlight 路由,瞬时)","var(--accent)"),s(!0,"联邦线(→peer)","var(--federal)"),e.append(t,n);try{e.open=window.localStorage.getItem(zn)==="open"}catch{}return e.addEventListener("toggle",()=>{try{window.localStorage.setItem(zn,e.open?"open":"closed")}catch{}}),e}const Xt="对端未应答(显示的是最后已知状态)";function qn(e){const t=new Set;for(const s of e.remoteTeams??[])s.unreachable===!0&&s.via&&t.add(st(s.via));for(const s of e.peerOrg??[])s.unreachable===!0&&t.add(st(s.url));const n=new Set;for(const s of e.remoteTeams??[])s.via&&t.has(st(s.via))&&n.add(`member-${s.team.replace(/[^a-z0-9-]/gi,"-")}`);return{hosts:t,members:n}}function Js(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=Xt,e.appendChild(s)}else t||n==null||n.remove()}function Gs(e){return e<680?"narrow":e<1024?"medium":"wide"}function Qs(e){let t=0;for(let l=0;l<e.length;l++)t=(t*31+e.charCodeAt(l)&268435455)>>>0;const n=Wn[t%Wn.length],s="#"+n.toString(16).padStart(6,"0"),o=n>>16&255,i=n>>8&255,r=n&255;return{line:s,bg:`rgba(${o},${i},${r},0.05)`}}function Zs(e){const t=new bn;let n,s={...t.viewport},o={kind:"none"},i=!1,r=-1,l=!0,u=!1;const m=Xs(t);let d,h=!1;const M=()=>Gs(globalThis.innerWidth||Ve),$=()=>{var a;(a=e.viewportStore)==null||a.set(M(),s),e.onDirty()},J=e.now??Date.now,he=new AbortController,Q=[];let E=null,k=!1;const I={signal:he.signal},x=document.createElement("section");x.id="dsh-plan",x.setAttribute("role","tabpanel"),x.setAttribute("aria-label","A2A 规划画布"),x.tabIndex=0,x.style.display="none";const T=document.createElement("div");T.className="p-grid";const y=document.createElement("div");y.className="p-world";const p=document.createElementNS("http://www.w3.org/2000/svg","svg");p.setAttribute("class","p-edges");const _=document.createElement("div");_.className="p-layer p-frames";let b;const D=a=>{var f,v;b!==void 0&&((f=Pe.get(b))==null||f.classList.remove("selected")),b=a,a!==void 0&&((v=Pe.get(a))==null||v.classList.add("selected"))},B=document.createElement("div");B.className="p-layer p-nodes",B.setAttribute("role","listbox"),B.setAttribute("aria-multiselectable","true"),B.setAttribute("aria-label","会话节点"),y.append(p,_,B);const se=document.createElement("div");se.className="p-marquee";const pe=document.createElement("div");pe.className="p-toolbar";const Me=document.createElement("span");Me.className="p-zoom mono",Me.textContent="100%";const P=(a,f,v)=>{const N=document.createElement("button");return N.type="button",N.textContent=a,N.title=f,N.addEventListener("click",v,I),N},q=()=>{const a=document.createElement("span");return a.className="p-sep",a.setAttribute("role","separator"),a.setAttribute("aria-orientation","vertical"),a};pe.append(P("适配","适配视图(快捷键 0)",()=>yt()),P("-","缩小",()=>Ce(1/1.2)),Me,P("+","放大",()=>Ce(1.2)),q(),P("建队","组成团队(G):先框选至少 2 个节点",()=>F.startCreateFromSelection()),P("整理成员","每队框内仅属一队的成员自动排齐(多队成员不动)",()=>gt()),P("一键重排","全板队框+成员重排:框尺寸随内容自适应、框位行流式平铺(远端队框与多归属成员不动)",()=>mt()),P("撤销","撤销上一次布局改动:拖动、缩放、整理、重排、载入时避让(Ctrl+Z;入队离队不撤销)",()=>nt()));const ie=P("未入网","未入网会话(点击选择入网)",()=>F.toggleNetMenu());ie.className="p-netbtn",ie.setAttribute("aria-haspopup","menu"),pe.append(q(),ie);const Se=$s(pe,t,ot,a=>ye(a)),G=P("节点","节点清单:本机与对等节点(未组队/未入网在此管理)",()=>V.toggle());G.className="p-nodebtn",G.setAttribute("aria-haspopup","dialog"),pe.appendChild(G);const j=document.createElement("span");j.setAttribute("aria-live","polite"),j.className="p-lamp";const xe=document.createElement("i"),ue=document.createElement("span");ue.textContent="布局",j.append(xe,ue),j.addEventListener("click",()=>{j.classList.contains("error")&&e.onLampClick()},I),j.addEventListener("keydown",a=>{const f=a;(f.key==="Enter"||f.key===" ")&&j.classList.contains("error")&&(f.preventDefault(),e.onLampClick())},I),pe.appendChild(j);const ke=document.createElement("div");ke.className="p-status";const Te=document.createElement("span"),et=document.createElement("span"),qe=document.createElement("span");qe.className="mut";const Ke=document.createElement("span");Ke.className="mut",ke.append(Te,et,qe,Ke),ke.tabIndex=0,ke.setAttribute("role","button"),ke.setAttribute("aria-label","定位在途路由与联邦对端"),ke.title="定位在途与联邦(回车)",ke.addEventListener("click",()=>ce(),I),ke.addEventListener("keydown",a=>{const f=a;(f.key==="Enter"||f.key===" ")&&(f.preventDefault(),ce())},I);const ht=Vs(),He=document.createElement("div");He.className="p-notice-stack",He.setAttribute("role","log"),He.setAttribute("aria-live","polite"),x.append(T,y,se,pe,ke,ht,He);let Ve=0,at=0;const bt=()=>e.viewSize?e.viewSize():{w:x.clientWidth,h:x.clientHeight},je=()=>{const a=bt();Ve=a.w,at=a.h};function Ye(){y.style.transform=gs(s);const a=24*s.scale;T.style.backgroundSize=`${a}px ${a}px`,T.style.backgroundPosition=`${-s.x*s.scale}px ${-s.y*s.scale}px`,Me.textContent=`${Math.round(s.scale*100)}%`}function gt(){const a=m.capture();Ys(t),Ht(t,new Set(C.keys())),m.commit(a),$(),Ee()}function mt(){const a=m.capture();Ts(t,new Set(C.keys()))&&(Ht(t,new Set(C.keys())),m.commit(a),$(),Ee())}function Ee(){Ye(),t.revision!==r&&(r=t.revision,vt(),c(),Zo(p,t)),me()}const Pe=new Map,Ze=new Map;function vt(){const a=new Set;for(const[f,v]of t.allFrames()){a.add(f);let N=Pe.get(f);if(N===void 0){N=document.createElement("div"),N.className="p-frame",N.dataset.name=f;const ge=document.createElement("div");ge.className="p-frame-head",ge.dataset.frame=f,ge.tabIndex=0,ge.setAttribute("role","button"),ge.setAttribute("aria-haspopup","menu"),ge.setAttribute("aria-label",`团队框 ${f}(拖动整组,回车菜单)`);const Ae=document.createElement("span");Ae.className="ttl";const le=document.createElement("span");le.className="cnt mono";const Oe=document.createElement("span");Oe.className="route mono",ge.append(Ae,le,Oe),N.appendChild(ge);for(const ze of["n","s","e","w","ne","nw","se","sw"]){const Ge=document.createElement("div");Ge.className=`p-frame-handle p-h-${ze}`,Ge.dataset.frame=f,Ge.dataset.dir=ze,N.appendChild(Ge)}_.appendChild(N),Pe.set(f,N)}const X=Qs(f);N.style.setProperty("--frame-line",X.line),N.style.setProperty("--frame-bg",X.bg),N.style.left=`${v.x}px`,N.style.top=`${v.y}px`,N.style.width=`${v.w}px`,N.style.height=`${v.h}px`;const U=N.querySelector(".ttl"),K=N.querySelector(".cnt"),W=N.querySelector(".route");U.textContent!==f&&(U.textContent=f);let Z=0,be=0;for(const ge of t.allNodes())ge.memberships.find(le=>le.team===f)!==void 0&&(Z+=1,ge.memberships.length>1&&(be+=1));const Le=`${Z} 成员`+(be>0?` +${be} 跨队`:"");K.textContent!==Le&&(K.textContent=Le);const fe=_s(C.get(f),$e.has(f)),de=fe!==void 0&&w.hosts.has(st(C.get(f))),g=(fe==null?void 0:fe.text)??lt(f);W.textContent!==g&&(W.textContent=g),W.title=`${(fe==null?void 0:fe.title)??""}${de?` · ${Xt}`:""}`,Js(N,de),N.classList.toggle("is-mirror",fe!==void 0),N.classList.toggle("is-syncing",(fe==null?void 0:fe.syncing)===!0);const ae=`团队框 ${f}${fe!==void 0?`(${fe.text})`:""}${de?`(${Xt})`:""}(拖动整组,回车菜单)`,ne=N.querySelector(".p-frame-head");ne.getAttribute("aria-label")!==ae&&ne.setAttribute("aria-label",ae)}for(const[f,v]of[...Pe])a.has(f)||(v.remove(),Pe.delete(f))}function lt(a){const f=Tt.find(v=>v.name===a);return(f==null?void 0:f.team)??a}function c(){const a=new Set;for(const f of t.allNodes()){a.add(f.id);let v=Ze.get(f.id);if(v===void 0){v=document.createElement("div"),v.className="p-node",v.dataset.id=f.id,v.tabIndex=0;const de=document.createElement("div");de.className="nm";const g=document.createElement("span");g.className="dot";const ae=document.createElement("span");ae.className="nm-text",de.append(g,ae);const ne=document.createElement("div");ne.className="sub mono";const ge=document.createElement("span");ge.className="prio mono",v.append(de,ne,ge),B.appendChild(v),Ze.set(f.id,v)}const N=it(f);v.style.left=`${N.x}px`,v.style.top=`${N.y}px`,v.classList.toggle("cold",!f.live),v.classList.toggle("remote",f.remote===!0),v.classList.toggle("selected",t.isSelected(f.id)),v.setAttribute("aria-selected",String(t.isSelected(f.id)));const X=f.id.slice(5),U=qs(f,f.remote===!0?L.get(X)??[]:[],z.get(X)),K=f.remote===!0&&(f.id.startsWith("member-")?w.members.has(f.id):w.hosts.has(X));v.classList.toggle("is-unreachable",K);const W=v.querySelector(".nm-text");W.textContent!==U.title&&(W.textContent=U.title);const Z=v.querySelector(".sub"),be=K?`未应答 · ${U.sub}`:U.sub;Z.textContent!==be&&(Z.textContent=be);const Le=K?`${U.tip} · ${Xt}`:U.tip;v.title!==Le&&(v.title=Le);const fe=v.querySelector(".prio");if(f.remote===!0){const de=Y.get(X),g=(de==null?void 0:de.link)==="linked"?"lnk-linked":(de==null?void 0:de.link)==="stranger"?"lnk-stranger":"";fe.className!==`prio mono ${g}`.trim()&&(fe.className=`prio mono ${g}`.trim());const ae=de===void 0?"":de.verified===!0?"✓":"✗",ne=((de==null?void 0:de.link)??"peer")+ae;fe.textContent!==ne&&(fe.textContent=ne)}else{fe.className!=="prio mono"&&(fe.className="prio mono");const de=f.memberships[0]!==void 0?`P${f.memberships[0].index}`:"";fe.textContent!==de&&(fe.textContent=de)}}for(const[f,v]of[...Ze])a.has(f)||(v.remove(),Ze.delete(f));Se.refresh()}const A=us(p,t);let L=new Map;const z=new Map,Y=new Map;function me(){A.render(J())}function ce(){s=gn(cs(t.contentBounds(),A.placements()),x.clientWidth||Ve,x.clientHeight||at),Ye(),$()}const ye=Es({model:t,viewSize:bt,setVp:a=>{s=a},applyViewport:Ye,markDirty:$,cardEl:a=>Ze.get(a)});function oe(a){var N;const f=a.sessions.filter(X=>X.live!==!1).length,v=(X,U,K)=>{const W=document.createElement("b");W.className=U,W.textContent=K,X.replaceChildren(W)};v(Te,"ok",`● ${f} live`),v(et,"warn",`● ${a.sessions.length-f} cold`),qe.textContent=`${((N=a.inFlight)==null?void 0:N.length)??0} inFlight`,Ke.className="mut",Ke.textContent=`${a.teams.length} 队 · ${a.peerCount} peer`}const $e=new Map,Je=a=>{$e.set(a,($e.get(a)??0)+1),r=-1},De=a=>{r=-1;const f=($e.get(a)??0)-1;f<=0?$e.delete(a):$e.set(a,f)};let C=new Map,w=qn({});const H=Fs(e.now);function S(a){function f(U){const K=W=>{var be;const Z=[];for(const Le of W){if(!Le.startsWith("peer-")&&!Le.startsWith("member-")){Z.push(Le);continue}const fe=(be=t.getNode(Le))==null?void 0:be.remoteHandle;fe!==void 0&&fe!==""&&Z.push(fe)}return Z};if(U.type==="add-member"||U.type==="remove-member"||U.type==="create-team"){const W=K(U.ids),Z=U.type!=="create-team"?C.get(U.team):void 0;return W.length>0||Z!==void 0?{...U,ids:W,...Z!==void 0?{fleetPeer:Z}:{}}:U}return U.type==="remove-team"&&C.has(U.name)?H.fork(U,C.get(U.name)):U}if(a.type==="add-member"||a.type==="remove-member"||a.type==="reorder"||a.type==="create-team"){const U=a.type==="reorder"?a.ops.map(K=>K.id):[...a.ids];for(const K of U){if(K===""||K.startsWith("peer-")||K.startsWith("member-")||t.getNode(K)!==void 0)continue;const W=te.find(Le=>Le.id===K);if(W===void 0)continue;const Z=n==null?void 0:n.nodes[K],be=Z!==void 0?{x:Z.x,y:Z.y}:yn(K);t.upsertNode({id:K,x:be.x,y:be.y,label:W.label,team:W.team,name:W.name,description:W.description,live:W.live!==!1,memberships:[],...W.teams!==void 0&&W.teams.length>0?{teams:W.teams}:{}})}}const v=vs(t,a),N=ln(a);Je(N),Ee();const X=f(a);e.onCanvasAction(X).then(U=>{De(N),n=jn(t,a,U,v,n),$(),H.settled(X,U),Ee()},()=>{De(N),n=jn(t,a,!1,v,n),$(),H.settled(X,!1),R("error","操作通道异常,已回滚"),Ee()})}function R(a,f){var N;for(;He.childElementCount>=3;)(N=He.firstElementChild)==null||N.remove();const v=document.createElement("div");v.className="p-notice"+(a==="error"?" error":""),v.setAttribute("role",a==="error"?"alert":"status"),v.textContent=f,He.appendChild(v),Q.push(setTimeout(()=>v.remove(),4e3))}const F=ws({root:x,netBtn:ie,signal:I,model:t,teams:()=>Tt,anchorFor:a=>(a.kind==="node"?Ze.get(a.id):Pe.get(a.name))??null,emit:S,notice:R});let te=[],re=new Set;const V=Ks({root:x,trigger:G,signal:I,model:t,facts:()=>({sessions:te,canvasMemberIds:re,remoteTeams:L,teams:Tt}),menuItem:F.menuItem,emit:S,openNameDialog:F.openNameDialog,locate:we});function we(a){var N;const f=t.getNode(a);if(f===void 0)return;V.close();const v=((N=e.viewSize)==null?void 0:N.call(e))??{w:x.clientWidth>0?x.clientWidth:800,h:x.clientHeight>0?x.clientHeight:600};s=kt({scale:s.scale,x:f.x-v.w/(2*s.scale),y:f.y-v.h/(2*s.scale)}),Ye(),r=-1,Ee()}function Ie(a){const f=x.getBoundingClientRect();return{x:a.clientX-f.left,y:a.clientY-f.top}}function ee(a,f){var K;const v=Ie(f),N=ut(s,v.x,v.y),X=Yn(new Map(t.allFrames()),N),U=a.ids.filter(W=>{const Z=t.getNode(W);return Z===void 0?!1:Z.remote!==!0?!0:Z.remoteHandle!==void 0&&Z.remoteHandle!==""});if(X!==void 0){const W=U.filter(Z=>{var be;return!((be=t.getNode(Z))!=null&&be.memberships.some(Le=>Le.team===X))});if(W.length>0){S({type:"add-member",team:X,ids:W});return}if(a.ids.length===1&&((K=t.getNode(a.clicked))==null?void 0:K.remote)!==!0){const Z=t.teamMemberIds(X),be=ys(t,X);be.join("\0")!==Z.join("\0")&&S({type:"reorder",team:X,ops:cn(Z,be)})}}}function _e(a){if(Ve===0&&je(),F.isDialogOpen()){a.preventDefault();return}const f=a.target;if(F.isMenuOpen()){if(f!==null&&f.closest(".p-menu")!==null)return;F.closeMenu(),a.preventDefault();return}if(f!==null&&f.closest("button, input, textarea, select, .p-toolbar, .p-search, .p-lamp, .p-status, .p-legend")!==null)return;d=m.capture();const v=Ie(a);if(a.button===2){E={x:v.x,y:v.y,target:a.target,moved:!1},a.preventDefault();try{x.setPointerCapture(a.pointerId??0)}catch{}return}const N=f!==null?f.closest(".p-node"):null,X=f!==null?f.closest(".p-frame-head"):null;if((N!==null||X!==null)&&a.button===1){o={kind:"pan",last:v,moved:!1},a.preventDefault();try{x.setPointerCapture(a.pointerId??0)}catch{}return}const U=f!==null?f.closest(".p-frame-handle"):null;if(b!==void 0){const K=Pe.get(b),W=f!==null&&K!==void 0&&(K.contains(f)||K===f),Z=X!==null&&X.dataset.frame===b;!W&&!Z&&D(void 0)}if(U!==null&&a.button===0){const K=U.dataset.frame??"";D(K);const W=t.getFrame(K);if(W===void 0)return;o={kind:"frame-resize",name:K,dir:U.dataset.dir??"se",startRect:{...W},origin:ut(s,v.x,v.y),moved:!1},a.preventDefault();try{x.setPointerCapture(a.pointerId??0)}catch{}return}if(N!==null){if(a.button!==0)return;const K=N.dataset.id??"",W=t.isSelected(K);!W&&!a.shiftKey&&t.setSelection([K]);const Z=a.shiftKey||W?t.isSelected(K)?t.selectedIds():[...t.selectedIds(),K]:[K];o={kind:"node",clicked:K,ids:Z,last:ut(s,v.x,v.y),moved:!1,el:N},N.classList.add("dragging")}else if(X!==null){if(a.button!==0)return;const K=X.dataset.frame??"";D(K);const W=t.beginFrameDrag(K);if(W===void 0)return;o={kind:"frame",name:K,snap:W,origin:ut(s,v.x,v.y),moved:!1}}else if(a.button===1||a.button===0&&i)o={kind:"pan",last:v,moved:!1};else if(a.button===0)o={kind:"marquee",origin:v,last:v,additive:a.shiftKey},se.style.display="block",se.style.left=`${v.x}px`,se.style.top=`${v.y}px`,se.style.width="0px",se.style.height="0px";else return;a.preventDefault();try{x.setPointerCapture(a.pointerId??0)}catch{}}function We(a){const f=Ie(a);if(E!==null){const v=f.x-E.x,N=f.y-E.y;Math.hypot(v,N)>4&&(E.moved=!0,s=kt(nn(s,-v,-N)),E.x=f.x,E.y=f.y,Ye());return}if(o.kind==="node"){const v=ut(s,f.x,f.y),N=v.x-o.last.x,X=v.y-o.last.y;if(N===0&&X===0)return;o.moved=!0,o.last=v,t.dragNodes(o.ids,N,X);const U=Yn(new Map(t.allFrames()),v),K=o.ids.filter(Z=>{const be=t.getNode(Z);return be===void 0?!1:be.remote!==!0||be.remoteHandle!==void 0&&be.remoteHandle!==""}),W=U!==void 0&&K.length>0;for(const[Z,be]of Pe)be.classList.toggle("drop-target",W&&Z===U);Ee()}else if(o.kind==="frame"){const v=ut(s,f.x,f.y),N=v.x-o.origin.x,X=v.y-o.origin.y;if(!o.moved&&N===0&&X===0)return;o.moved=!0,t.applyFrameDrag(o.snap,N,X),Ee()}else if(o.kind==="frame-resize"){const v=ut(s,f.x,f.y),N=v.x-o.origin.x,X=v.y-o.origin.y;if(!o.moved&&N===0&&X===0)return;o.moved=!0;const U=220,K=120,W={...o.startRect};let{x:Z,y:be,w:Le,h:fe}=W;o.dir.includes("e")&&(Le=Math.max(U,W.w+N)),o.dir.includes("s")&&(fe=Math.max(K,W.h+X)),o.dir.includes("w")&&(Le=Math.max(U,W.w-N),Z=W.x+(W.w-Le)),o.dir.includes("n")&&(fe=Math.max(K,W.h-X),be=W.y+(W.h-fe)),t.setFrame(o.name,{x:Math.round(Z),y:Math.round(be),w:Math.round(Le),h:Math.round(fe)}),Ee()}else if(o.kind==="pan")s=nn(s,f.x-o.last.x,f.y-o.last.y),o.last=f,o.moved=!0,Ye();else if(o.kind==="marquee"){const v=Math.min(o.origin.x,f.x),N=Math.min(o.origin.y,f.y);se.style.left=`${v}px`,se.style.top=`${N}px`,se.style.width=`${Math.abs(f.x-o.origin.x)}px`,se.style.height=`${Math.abs(f.y-o.origin.y)}px`,o.last=f}}function Ue(a){var f,v;if(E!==null){const N=E.moved,X=E.target,U=E.x,K=E.y;E=null,N?(k=!0,$()):X!==null&&F.contextMenuAt(U,K,X);return}if(o.kind==="node"){const N=o.clicked;if(o.moved)ee(o,a),$();else if(a.shiftKey){const X=t.selectedIds();t.setSelection(X.includes(N)?X.filter(U=>U!==N):[...X,N])}else t.setSelection([N]),(f=e.onNodePick)==null||f.call(e,N);for(const X of Pe.values())X.classList.remove("drop-target");(v=o.el)==null||v.classList.remove("dragging"),Ee()}else if(o.kind==="frame"||o.kind==="frame-resize")o.moved&&(Ht(t,new Set(C.keys()),o.name),$(),Ee());else if(o.kind==="pan")o.moved&&$();else if(o.kind==="marquee"){const N=o.last,X=ut(s,Math.min(o.origin.x,N.x),Math.min(o.origin.y,N.y)),U=ut(s,Math.max(o.origin.x,N.x),Math.max(o.origin.y,N.y));t.marqueeSelect({x:X.x,y:X.y,w:U.x-X.x,h:U.y-X.y},o.additive),se.style.display="none",Ee()}o={kind:"none"},d!==void 0&&(m.commit(d),d=void 0);try{x.releasePointerCapture(a.pointerId??0)}catch{}}function ct(a){var v;for(const N of Pe.values())N.classList.remove("drop-target");o.kind==="node"&&((v=o.el)==null||v.classList.remove("dragging"));const f=o.kind==="pan"&&o.moved||(E==null?void 0:E.moved)===!0;se.style.display="none",E=null,o={kind:"none"},d!==void 0&&m.revert(d)&&Ee(),f&&$(),d=void 0;try{x.releasePointerCapture(a.pointerId??0)}catch{}}function Be(a){F.isMenuOpen()&&F.closeMenu();const f=Ie(a);if(a.shiftKey&&!a.ctrlKey){const v=a.deltaMode===1?16:1;s=kt(nn(s,(a.deltaX??0)*v,(a.deltaY??0)*v))}else{const v=a.deltaMode===1?16:1,N=Math.exp(-((a.deltaY??0)*v)*.0015);s=Pn(s,N,f.x,f.y)}a.preventDefault(),Ye(),$()}function Ce(a){je(),s=Pn(s,a,Ve/2,at/2),Ye(),$()}function nt(){m.undo()?($(),Ee()):R("info","没有可撤销的布局改动")}function yt(){je(),s=Bn(Rn(t.contentBounds(),t.allNodes()),Ve,at,Hn(pe,ke)),Ye(),$()}function Nt(a){var U,K,W,Z,be,Le,fe;if(F.isDialogOpen()||((K=(U=a.target)==null?void 0:U.closest)==null?void 0:K.call(U,".p-search"))!==null)return;if((a.ctrlKey||a.metaKey)&&a.key.toLowerCase()==="k"){a.preventDefault(),Se.focus();return}if((a.ctrlKey||a.metaKey)&&!a.shiftKey&&a.key.toLowerCase()==="z"){a.preventDefault(),nt();return}if(a.ctrlKey||a.metaKey)return;if(F.isMenuOpen()){a.key==="Escape"&&(F.closeMenu(),a.preventDefault());return}if(a.key===" "&&a.target===x){i=!0,a.preventDefault();return}const f=((Z=(W=a.target)==null?void 0:W.closest)==null?void 0:Z.call(W,".p-frame-head"))??null;if((a.key==="Enter"||a.key===" ")&&f!==null){a.preventDefault();const de=f.getBoundingClientRect();F.contextMenuAt(de.left+de.width/2,de.top+de.height/2,f);return}if(a.key===" "&&((Le=(be=a.target)==null?void 0:be.classList)!=null&&Le.contains("p-node"))){const g=a.target.dataset.id??"",ae=t.selectedIds();t.setSelection(ae.includes(g)?ae.filter(ne=>ne!==g):[...ae,g]),Ee(),a.preventDefault();return}if(a.key==="F10"&&a.shiftKey||a.key==="ContextMenu"){a.preventDefault();const de=document.activeElement??null,g=((fe=de==null?void 0:de.getBoundingClientRect)==null?void 0:fe.call(de))??{left:0,top:0,width:0,height:0};F.contextMenuAt(g.left+g.width/2,g.top+g.height/2,de);return}if(a.key==="Delete"||a.key==="Backspace"){a.preventDefault(),Qt();return}if(a.altKey&&(a.key==="ArrowUp"||a.key==="ArrowDown")){a.preventDefault(),fo(a.key==="ArrowUp");return}if(a.key==="g"||a.key==="G"){F.startCreateFromSelection();return}if(a.key==="0"){yt();return}if(a.key==="="||a.key==="+"){Ce(1.2);return}if(a.key==="-"){Ce(1/1.2);return}if(a.key==="Escape"){if(F.isMenuOpen()){F.closeMenu(),Ee();return}t.setSelection([]),Ee();return}const v=a.shiftKey?40:8,X={ArrowLeft:[-v,0],ArrowRight:[v,0],ArrowUp:[0,-v],ArrowDown:[0,v]}[a.key];if(X!==void 0){a.preventDefault();const de=t.selectedIds();if(de.length>0){const g=m.capture();t.nudge(de,X[0],X[1]),m.commit(g),Ee(),$()}}}function Qt(){var N,X,U;const a=document.activeElement,f=((N=a==null?void 0:a.closest)==null?void 0:N.call(a,".p-frame-head"))??null,v=((X=a==null?void 0:a.closest)==null?void 0:X.call(a,".p-node"))??null;if(f!==null){S({type:"remove-team",name:f.dataset.frame??""});return}if(v!==null){const K=v.dataset.id??"",W=((U=t.getNode(K))==null?void 0:U.memberships.map(Z=>Z.team))??[];if(W.length===0){R("info","该节点未加入任何团队");return}if(W.length===1){S({type:"remove-member",team:W[0],ids:[K]});return}F.openMenu(window.innerWidth/2,window.innerHeight/2,{kind:"node",id:K},"leave",v);return}R("info","焦点不在节点或团队框上")}function fo(a){var Le,fe;const f=document.activeElement,v=((Le=f==null?void 0:f.closest)==null?void 0:Le.call(f,".p-node"))??null;if(v===null)return;const N=v.dataset.id??"",X=((fe=t.getNode(N))==null?void 0:fe.memberships)??[];if(X.length!==1)return;const U=X[0].team,K=t.teamMemberIds(U),W=K.indexOf(N),Z=a?Math.max(0,W-1):Math.min(K.length-1,W+1);if(Z===W)return;const be=[...K];be.splice(W,1),be.splice(Z,0,N),S({type:"reorder",team:U,ops:cn(K,be)})}function vn(a){a.key===" "&&(i=!1)}x.addEventListener("pointerdown",a=>_e(a),I),x.addEventListener("pointermove",a=>We(a),I),x.addEventListener("pointerup",a=>Ue(a),I),x.addEventListener("pointercancel",a=>ct(a),I),x.addEventListener("wheel",a=>Be(a),{...I,passive:!1}),x.addEventListener("keydown",a=>Nt(a),I),x.addEventListener("keyup",a=>vn(a),I),x.addEventListener("contextmenu",a=>{var v,N;const f=a;if(((N=(v=f.target)==null?void 0:v.closest)==null?void 0:N.call(v,"input, textarea, .p-search"))==null){if(f.preventDefault(),k){k=!1;return}F.contextMenuAt(f.clientX,f.clientY,f.target)}},I);let Tt=[];function po(a){var de;Tt=a.teams,a.peers,A.setInFlight(a.inFlight??[]),te=a.sessions,F.setUnjoined(a.sessions.filter(g=>g.joined!==!0&&!g.id.startsWith("peer-")));const f=new Map;for(const g of a.teams)for(let ae=0;ae<g.members.length;ae++){const ne=g.members[ae].id,ge=f.get(ne)??[];ge.push({team:g.name,index:ae}),f.set(ne,ge)}re=new Set(f.keys());const v=new Set,N=g=>{const ae=f.get(g)??[];if($e.size===0)return ae;const ne=ae.filter(Ae=>!$e.has(Ae.team)),ge=[];for(const[Ae]of $e){const Oe=t.teamMemberIds(Ae).indexOf(g);Oe>=0&&ge.push({team:Ae,index:Oe})}return[...ne,...ge]};let X;if(n===void 0&&!t.allNodes().some(g=>g.remote!==!0)){const g=a.sessions.filter(ae=>{var ne;return ae.joined===!0&&(N(ae.id).length>0||(((ne=ae.teams)==null?void 0:ne.length)??0)>0)}).map(ae=>ae.id);je(),X=Vo(a.teams,g,Ve>0?Ve:void 0)}for(const g of a.sessions){if(g.joined!==!0)continue;const ae=N(g.id);if(!(ae.length===0&&(g.teams===void 0||g.teams.length===0)))if(v.add(g.id),t.getNode(g.id)!==void 0)t.upsertNode({id:g.id,x:t.getNode(g.id).x,y:t.getNode(g.id).y,label:g.label,team:g.team,name:g.name,description:g.description,live:g.live!==!1,memberships:ae,...g.teams!==void 0&&g.teams.length>0?{teams:g.teams}:{}});else{const ne=n==null?void 0:n.nodes[g.id];let ge,Ae;if(ne!==void 0)ge=ne.x,Ae=ne.y;else{const le=(X==null?void 0:X.get(g.id))??yn(g.id);ge=le.x,Ae=le.y}t.upsertNode({id:g.id,x:ge,y:Ae,label:g.label,team:g.team,name:g.name,description:g.description,live:g.live!==!1,memberships:ae,...g.teams!==void 0&&g.teams.length>0?{teams:g.teams}:{}})}}for(const g of t.nodeIds())!v.has(g)&&!g.startsWith("peer-")&&!g.startsWith("member-")&&t.removeNode(g);const U=new Set;L=ts(a.remoteTeams??[]),w=qn(a),z.clear();for(const g of a.peers??[])z.set(st(g.url),g.score),Y.set(st(g.url),{link:g.link,verified:g.verified});if(a.peers!==void 0){const g=t.contentBounds(),ae=rs(a.peers,g);a.peers.forEach((ne,ge)=>{var wn,xn,Cn,kn;const Ae=es(ne.url);U.add(Ae);const le=n==null?void 0:n.nodes[Ae],Oe=t.getNode(Ae),ze=Oe!==void 0?{x:Oe.x,y:Oe.y}:le!==void 0?{x:le.x,y:le.y}:{x:((wn=ae[ge])==null?void 0:wn.x)??200,y:((xn=ae[ge])==null?void 0:xn.y)??0},Ge=st(ne.url),_t=(kn=(Cn=L.get(Ge))==null?void 0:Cn[0])==null?void 0:kn.team;t.upsertNode({id:Ae,x:ze.x,y:ze.y,label:ne.url,team:"",name:ne.url,peerUrl:ne.url,remoteHandle:_t,live:!0,remote:!0,memberships:[]}),t.upsertScore(Ae,ne.score)})}for(const g of t.nodeIds())g.startsWith("peer-")&&!U.has(g)&&t.removeNode(g);const K=new Set;for(const[g,ae]of L){const ne=t.allNodes().find(le=>le.remote===!0&&st(le.peerUrl??"")===g&&!le.id.startsWith("member-")),ge=((ne==null?void 0:ne.x)??400)+190;let Ae=(ne==null?void 0:ne.y)??0;for(const le of ae){if(!le.team.includes("/"))continue;const Oe=`member-${le.team.replace(/[^a-z0-9-]/gi,"-")}`;if(K.has(Oe))continue;K.add(Oe);const ze=n==null?void 0:n.nodes[Oe],Ge=t.getNode(Oe),_t=Ge!==void 0?{x:Ge.x,y:Ge.y}:ze!==void 0?{x:ze.x,y:ze.y}:{x:ge,y:Ae};Ae+=92,t.upsertNode({id:Oe,x:_t.x,y:_t.y,label:le.team,team:le.team,name:le.name!==void 0&&le.name!==""?le.name:le.team,remoteHandle:le.team,live:!0,remote:!0,memberships:[]})}}for(const g of t.nodeIds())g.startsWith("member-")&&!K.has(g)&&t.removeNode(g);const W=new Map;for(const g of t.allNodes())g.remote!==!0||g.remoteHandle===void 0||g.remoteHandle===""||(!W.has(g.remoteHandle)||g.id.startsWith("member-"))&&W.set(g.remoteHandle,g.id);for(const g of a.teams){if($e.has(g.name))continue;const ae=[];for(const Ae of g.members){const le=W.get(Ae.id)??Ae.id;t.getNode(le)!==void 0&&ae.push(le)}const ne=[...t.teamMemberIds(g.name)].sort().join("|"),ge=[...ae].sort().join("|");ne!==ge&&t.setTeamMembers(g.name,ae)}const Z=new Map,be=C;if(C=Z,a.peerOrg!==void 0){let g=0;const ae=new Set(a.teams.map(ne=>ne.name));H.sweep(a.peerOrg);for(const ne of a.peerOrg){const ge=new Set((a.remoteTeams??[]).map(le=>le.team)),Ae=ms(a.sessions,ge);for(const le of ne.org){if(le.name===""||ae.has(le.name)||H.hides(le.name,ne.url))continue;const Oe=le.members.map(Ge=>fs(Ge,Ae,a.remoteTeams,ne.url)).filter(Ge=>t.getNode(Ge)!==void 0),ze=(de=n==null?void 0:n.frames)==null?void 0:de[le.name];t.getFrame(le.name)===void 0&&t.setFrame(le.name,ze!==void 0?{x:ze.x,y:ze.y,w:ze.w,h:ze.h}:{x:200+g%4*280,y:940+Math.floor(g/4)*160,w:250,h:130}),t.setTeamMembers(le.name,Oe),Z.set(le.name,ne.url),g+=1}}}for(const[g,ae]of be)Z.has(g)||t.removeFrame(g);const Le=new Map;for(const g of t.allNodes())g.remote===!0&&g.remoteHandle!==void 0&&g.remoteHandle!==""&&Le.set(g.remoteHandle,g.id);const fe=lo(a.teams);for(const g of a.teams){if(t.getFrame(g.name)!==void 0||$e.has(g.name))continue;const ae=n==null?void 0:n.frames[g.name];if(ae!==void 0){t.setFrame(g.name,{...ae});continue}const ne=[],ge=[];for(const le of g.members){const Oe=t.getNode(Le.get(le.id)??le.id);Oe!==void 0&&(ge.push(it(Oe)),fe.get(Oe.id)===g.name&&ne.push(it(Oe)))}const Ae=ne.length>0?ne:ge;Ae.length>0&&t.setFrame(g.name,hn(Ae))}for(const[g]of t.allFrames())$e.has(g)||!a.teams.some(ae=>ae.name===g)&&!Z.has(g)&&t.removeFrame(g);if(V.refresh(),oe(a),!u&&o.kind==="none"&&t.nodeIds().length>0){u=!0;const g=m.capture();Ht(t,new Set(C.keys())),m.commit(g)}l&&o.kind==="none"&&t.nodeIds().length>0&&(je(),Ve>0&&at>0&&(l=!1,s=Bn(Rn(t.contentBounds(),t.allNodes()),Ve,at,Hn(pe,ke)))),Ee()}function yn(a){return co(a,t.allNodes().filter(f=>f.remote!==!0))}function ho(a){const f=ro(a);if(f===void 0)return;n=f;const v=e.viewportStore;if(v===void 0)l=!1,o.kind==="none"&&(s=kt({...f.viewport}));else if(!h&&o.kind==="none"){h=!0;const N=v.get(M());N!=null&&Number.isFinite(N.x)&&Number.isFinite(N.y)&&Number.isFinite(N.scale)?(s=kt({x:N.x,y:N.y,scale:N.scale}),l=!1):M()==="wide"&&(s=kt({...f.viewport}),l=!1)}r=-1,Ee()}function bo(){return Ko(s,t.positions(),t.frameRects())}function go(a,f){j.classList.remove("pending","saved","error"),a==="pending"&&j.classList.add("pending"),a==="saved"&&j.classList.add("saved"),a==="error"&&j.classList.add("error"),a==="error"?(j.tabIndex=0,j.setAttribute("role","button"),j.setAttribute("aria-label","布局保存失败,按回车重试")):(j.removeAttribute("tabindex"),j.removeAttribute("role"),j.removeAttribute("aria-label"));const v=a==="pending"?"布局待保存…":a==="saved"?`布局已保存 ${f??""}`.trimEnd():a==="error"?"保存失败 · 回车重试":"布局";ue.textContent=v}function vo(){x.style.display="block",je(),Ye(),x.focus()}function yo(){x.style.display="none"}function wo(){he.abort();for(const a of Q)clearTimeout(a)}return{root:x,reconcile:po,activate:vo,deactivate:yo,adoptExternalLayout:ho,snapshotDoc:bo,setLamp:go,notice:R,destroy:wo,seam:{pointerDown:_e,pointerMove:We,pointerUp:Ue,pointerCancel:ct,wheel:Be,key:Nt,keyUp:vn,contextMenu(a){a.preventDefault(),F.contextMenuAt(a.clientX,a.clientY,a.target)}}}}const ei=800;function ti(e){let t,n=!1,s=!1,o=!1,i="idle";function r(d){d!==i&&(i=d,e.onLamp(d))}function l(){t!==void 0&&(t(),t=void 0)}function u(){l(),t=e.schedule(()=>{t=void 0,m(!1)},ei)}async function m(d){if(n){s=!0;return}n=!0,l();const h=e.snapshot();let M;try{M=JSON.stringify(h)}catch{n=!1,r("error"),e.onHttpError("layout document is not JSON-serializable");return}try{const $=await e.send(h,{keepalive:d});if($===null||typeof $!="object"||$.ok!==!0){r("error");const J=$!==null&&typeof $=="object"&&typeof $.error=="string"?$.error:"layout save refused";e.onHttpError(`layout save: ${J}`)}else JSON.stringify(e.snapshot())===M&&(e.onAdopt($.layout),r("saved"))}catch($){r("error"),e.onHttpError(`layout save unreachable: ${String(($==null?void 0:$.message)??$).slice(0,80)}`)}if(n=!1,i==="error"){o=!1;return}if(o){o=!1,m(!0);return}s&&(s=!1,r("pending"),u())}return{markDirty(){if(s=!1,r("pending"),n){s=!0;return}u()},retry(){i!=="error"||n||(r("pending"),m(!1))},flush(){if(n){o=!0,s=!0;return}l(),m(!0)},isBusy(){return n},dispose(){l()}}}function Vn(e){return e!=null&&typeof e.error=="string"?e.error:void 0}function ni(e){const t=new Map;let n=0;function s(r,l){n+=1;const u=t.get(r)??Promise.resolve(),m=async()=>{try{return await l()}finally{n-=1}},d=u.then(m,m);return t.set(r,d.then(()=>{},()=>{})),d}async function o(r){var he,Q,E,k;let l;try{l=await e.send(r)}catch(I){const x=String((I==null?void 0:I.message)??I).slice(0,80);return e.onNotice("error",`画布不可达:${x}`),!1}if(l.status>=400)return e.onNotice("error",Vn(l.body)??`HTTP ${l.status}`),!1;if(((he=l.body)==null?void 0:he.ok)===!0)return!0;const u=l.body!=null&&typeof l.body=="object"?Vn(l.body):void 0;if(u!==void 0)return e.onNotice("error",u),!1;const m=String(r.name??""),d=String(r.id??""),h=(Q=l.body)==null?void 0:Q.members,M=(E=l.body)==null?void 0:E.teams,$=Array.isArray(h)&&h.every(I=>typeof I=="string"),J=Array.isArray(M)&&M.every(I=>typeof I=="string");return((k=l.body)==null?void 0:k.ok)===!1&&(r.action==="add-member"&&$&&h.includes(d)||r.action==="remove-member"&&$&&!h.includes(d)||r.action==="remove"&&J&&!M.includes(m))?!0:(e.onNotice("error","画布操作未确认:"+String(r.action)+"(可能队伍/成员已达上限,请重试)"),!1)}async function i(r,l){for(const u of l)if(!await o({...r,id:u}))return!1;return!0}return{createTeam(r,l){return s(r,async()=>{if(!await o({action:"create",name:r}))return!1;for(let u=0;u<l.length;u++)if(!await o({action:"add-member",name:r,id:l[u]}))return!1;return!0})},addMembers(r,l){return s(r,()=>i({action:"add-member",name:r},l))},removeMembers(r,l){return s(r,()=>i({action:"remove-member",name:r},l))},runRosterOps(r,l){return s(r,async()=>{for(const u of l){const m=u.op==="remove"?{action:"remove-member",name:r,id:u.id}:{action:"add-member",name:r,id:u.id};if(!await o(m))return!1}return!0})},removeTeam(r){return s(r,()=>o({action:"remove",name:r}))},hasPending(){return n>0}}}const mo=document.getElementById("app"),oi=(()=>{try{return window.sessionStorage.getItem("dsh_a2a_key")??""}catch{return""}})(),dn=window.__DSH_A2A_KEY__??oi,Xe=(e,t={})=>fetch(e,{...t,headers:{...t.headers??{},...dn!==""?{"X-API-Key":dn}:{}}});dn===""&&Xe("/__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 i=document.createElement("div");i.style.color="#b00";const r=()=>{const l=s.value.trim();l!==""&&fetch("/__dsh_a2a/owner-settings",{headers:{"X-API-Key":l}}).then(u=>{if(u.status===401){i.textContent="密钥不对,再试一次";return}try{window.sessionStorage.setItem("dsh_a2a_key",l)}catch{}window.location.reload()})};o.addEventListener("click",r),s.addEventListener("keydown",l=>{l.key==="Enter"&&r()}),t.append(n,s,o,i),document.body.appendChild(t)});const Lt=document.createElement("div");Lt.className="nexus-fault";mo.appendChild(Lt);const{fault:un,clear:si}=ko({show(e){Lt.textContent=e,Lt.style.display="block"},hide(){Lt.style.display="none"}},e=>console.error(e));let Kt;const Jn="dsh-a2a.viewport.",ii={get(e){try{const t=window.localStorage.getItem(Jn+e);return t===null?void 0:JSON.parse(t)}catch{return}},set(e,t){try{window.localStorage.setItem(Jn+e,JSON.stringify({x:t.x,y:t.y,scale:t.scale}))}catch{}}},rt=Zs({viewportStore:ii,onDirty:()=>qt.markDirty(),onLampClick:()=>qt.retry(),onNodePick:e=>{Kt==null||Kt(e)},onCanvasAction:async e=>{const t=await ri(e);return Gt(),t}}),qt=ti({snapshot:()=>rt.snapshotDoc(),send:(e,t)=>Xe("/__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=>{mn=e;const t=new Date,n=String(t.getHours()).padStart(2,"0")+":"+String(t.getMinutes()).padStart(2,"0");rt.setLamp(e,n)},onAdopt:e=>{rt.adoptExternalLayout(e)},onHttpError:e=>un(e)});window.addEventListener("pagehide",()=>qt.flush());const At=ni({send:async e=>{const t=await Xe("/__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)=>rt.notice(e,t)});async function Gn(e,t,n,s){const o=await Xe("/__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(()=>{}),i=o!==void 0?await o.json().catch(()=>{}):void 0;return(i==null?void 0:i.ok)===!0&&t==="remove"&&i.removed===!1&&rt.notice("info",`属主那边已没有「${n}」,无需解散`),(i==null?void 0:i.ok)===!0?!0:(rt.notice("error",`跨主机团队操作失败:${String((i==null?void 0:i.error)??"对端无响应")}`),!1)}function ri(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 Gn(t,e.type,e.team,n))return!1;return!0})()}if(e.type==="remove-team"&&e.fleetPeer!==void 0)return Gn(e.fleetPeer,"remove",e.name);switch(e.type){case"create-team":return At.createTeam(e.name,e.ids,e.created);case"add-member":return At.addMembers(e.team,e.ids);case"remove-member":return At.removeMembers(e.team,e.ids);case"remove-team":return At.removeTeam(e.name);case"reorder":return At.runRosterOps(e.team,e.ops);case"join-network":case"leave-network":return ai(e.type==="join-network"?"join":"leave",e.id)}}async function ai(e,t){const n=await Xe(`/__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 mn="idle",on=new Set,Qn=0,Vt=!1,Zn,sn=!1;async function li(){const e=await Xe("/__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 Jt=Wo({now:()=>Date.now(),async ownerSettingsRead(){try{return await(await Xe("/__dsh_a2a/owner-settings")).json()}catch{return{ok:!1,error:"unreachable"}}},async ownerSettingsWrite(e){try{return await(await Xe("/__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 Xe("/__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 canvasOp(e,t,n){try{const s=await Xe("/__dsh_a2a/canvas",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({action:e,name:t,id:n})}),o=await s.json().catch(()=>({}));return s.ok&&o.ok!==!1?!0:(console.warn(`canvas ${e} ${t}: ${o.error??`HTTP ${s.status}`}`),!1)}catch{return!1}},async dispatchQuick(e,t){try{const n=await Xe("/__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 Xe(`/__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 Xe("/__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 Xe(`/__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:rt.root,activate:()=>rt.activate(),deactivate:()=>rt.deactivate(),available:()=>Vt}});mo.appendChild(Jt.root);Kt=e=>{Jt.openNodeChat(e)};if(new URLSearchParams(window.location.search).get("mode")==="plan"){const e=window.setInterval(()=>{Vt&&(Jt.selectTab("board"),window.clearInterval(e))},300);window.setTimeout(()=>window.clearInterval(e),3e4)}async function Gt(){var e;try{const t=await Xe("/__dsh_a2a/state",{cache:"no-store"});if(!t.ok)throw new Error(`/__dsh_a2a/state ${t.status}`);const n=await t.json();if(Date.now()-Qn>=15e3){Qn=Date.now();try{const d=await Xe("/__dsh_a2a/nodes",{cache:"no-store"});if(!d.ok)throw new Error(`nodes ${d.status}`);const h=await d.json();on=new Set((h.bindings??[]).filter(M=>M.mounted!==null&&M.effective!==null&&(M.effective.core===!1||M.effective.mutable===!1)).map(M=>M.session))}catch{on.clear()}}const s={...n,sessions:(n.sessions??[]).map(d=>({...d,...on.has(d.id)?{nodePromptMissing:!0}:{}}))};if(si(),Vt=n.canvas!==void 0,Jt.update(s),Vt)try{const d=await li(),h=JSON.stringify(d??null);h!==Zn&&(Zn=h,(mn==="idle"||mn==="saved")&&!qt.isBusy()&&rt.adoptExternalLayout(d)),sn=!0}catch(d){if(!sn){un(`canvas layout 获取失败:${String(d)}`);return}}else sn=!0;const o=(n.sessions??[]).map(d=>({...d,joined:d.joined===!0})),i=((e=n.canvas)==null?void 0:e.teams)??[],r=(n.peers??[]).filter(d=>d!==null&&typeof d=="object"&&typeof d.url=="string"),l=(n.inFlight??[]).filter(d=>d!==null&&typeof d=="object"&&typeof d.team=="string"&&typeof d.peer=="string"&&Number.isFinite(d.startedAt)),u=(n.remote??[]).filter(d=>d!==null&&typeof d=="object"&&typeof d.team=="string"&&typeof d.via=="string").map(d=>({team:d.team,name:d.name,via:d.via,workspace:d.workspace,...d.unreachable===!0?{unreachable:!0}:{},...typeof d.origin=="string"&&d.origin!==""?{origin:d.origin}:{},...Array.isArray(d.teams)&&d.teams.length>0?{teams:d.teams.filter(h=>typeof h=="string"&&h!=="")}:{}})),m=(n.peerOrg??[]).filter(d=>d!==null&&typeof d=="object").filter(d=>typeof d.url=="string"&&Array.isArray(d.org)).map(d=>({url:d.url,...d.unreachable===!0?{unreachable:!0}:{},org:d.org.filter(h=>h!==null&&typeof h=="object").filter(h=>typeof h.team=="string"&&h.team!=="").map(h=>({name:typeof h.name=="string"?h.name:"",team:h.team,members:Array.isArray(h.members)?h.members.filter(M=>typeof M=="string"):[]}))}));rt.reconcile({sessions:o,teams:i,peerCount:r.length,peers:r,inFlight:l,remoteTeams:u,peerOrg:m})}catch(t){un(`state 轮询失败:${String(t)}`)}}Gt();window.setInterval(()=>{document.hidden||Gt()},3e3);document.addEventListener("visibilitychange",()=>{document.hidden||Gt()});
@@ -1 +0,0 @@
1
- #dsh-plan *,#dsh-plan *:before,#dsh-plan *:after{box-sizing:border-box}#dsh-plan{--uupm-ink-0:var(--n-ink,#dde3f0);--uupm-ink-1:var(--n-ink-muted,#7a86a0);--uupm-bg-0:var(--n-bg,#060a12);--uupm-bg-1:var(--n-panel,#0d1322);--uupm-bg-2:var(--n-raised,#131b2e);--uupm-accent:var(--n-accent,#9673f7);--uupm-live:var(--n-live,#4ade80);--uupm-cold:var(--n-cold,#7a86a0);--uupm-edge-member:var(--n-canvas,#22d3ee);--uupm-warn:var(--n-act,#f59e0b);--uupm-error:var(--n-danger,#f87171);--uupm-indigo:var(--n-federal,#6366f1);--uupm-wash-5:color-mix(in srgb,var(--uupm-accent) 5%,transparent);--uupm-wash-8:color-mix(in srgb,var(--uupm-accent) 8%,transparent);--uupm-wash-12:color-mix(in srgb,var(--uupm-accent) 12%,transparent);--uupm-wash-15:color-mix(in srgb,var(--uupm-accent) 15%,transparent);--uupm-wash-18:color-mix(in srgb,var(--uupm-accent) 18%,transparent);--surface:var(--uupm-bg-1);--ink:var(--uupm-ink-0);--ink-muted:var(--uupm-ink-1);--accent:var(--uupm-accent);--edge-live:var(--uupm-live);--edge-cold:var(--uupm-cold);--federal:var(--uupm-indigo);--card-bg:var(--surface);--card-line:var(--n-card-line,#5c6680);--card-line-hover:var(--uupm-ink-1);--toolbar-bg:color-mix(in srgb,var(--uupm-bg-1) 92%,transparent);--grid-dot:color-mix(in srgb,var(--uupm-ink-1) 22%,transparent);--scrim:color-mix(in srgb,var(--uupm-bg-0) 60%,transparent);--error-ink:var(--n-error-ink,#fecaca);--error-panel:var(--n-error-panel,#2a0d10f2)}#dsh-plan{position:absolute;top:0;right:0;bottom:0;left:0;overflow:hidden;background:var(--uupm-bg-0);color:var(--ink);font-size:13px;line-height:1.5;outline:none}#dsh-plan .mono{font-family:ui-monospace,Cascadia,Consolas,monospace}#dsh-plan:focus-visible{outline:2px solid var(--accent);outline-offset:-2px}#dsh-plan .p-grid{position:absolute;top:0;right:0;bottom:0;left:0;z-index:0;pointer-events:none;background-image:radial-gradient(circle,var(--grid-dot) 1px,transparent 1px);background-size:24px 24px;background-position:0 0}#dsh-plan .p-world{position:absolute;top:0;right:0;bottom:0;left:0;z-index:1;transform-origin:0 0}#dsh-plan .p-layer{position:absolute;top:0;right:0;bottom:0;left:0;pointer-events:none}#dsh-plan .p-edges{position:absolute;overflow:visible;width:100%;height:100%;pointer-events:none}#dsh-plan .p-frame{pointer-events:none}#dsh-plan .p-frame-head,#dsh-plan .p-node{pointer-events:auto}#dsh-plan .e-member{stroke:var(--uupm-edge-member);stroke-opacity:.38;stroke-width:1.5}#dsh-plan .e-member.dashed{stroke-dasharray:3 4}#dsh-plan .p-frame{--frame-ink:var(--frame-line,#8B5CF6)}@media (prefers-color-scheme: light){#dsh-plan .p-frame{--frame-ink:color-mix(in srgb,var(--frame-line,#8B5CF6) 72%,black)}}#dsh-plan .p-frame{position:absolute;border:1px solid var(--frame-ink);border-radius:10px;background:var(--frame-bg,var(--uupm-wash-5));min-width:120px;min-height:60px}#dsh-plan .p-frame-head{position:absolute;top:-13px;left:50%;transform:translate(-50%);height:24px;padding:0 10px;border-radius:6px;display:flex;gap:8px;align-items:center;background:var(--uupm-bg-2);border:1px solid var(--frame-ink);font-size:12px;font-weight:600;letter-spacing:.02em;white-space:nowrap;cursor:grab}#dsh-plan .p-frame-head:active{cursor:grabbing}#dsh-plan .p-frame-head:hover{border-color:var(--card-line-hover)}#dsh-plan .p-frame-head .cnt{color:var(--ink-muted);font-weight:400}#dsh-plan .p-frame-head .route{font-size:10.5px;color:var(--ink-muted)}#dsh-plan .p-frame.is-mirror{border-style:dashed}#dsh-plan .p-frame.is-syncing .p-frame-head .route{color:var(--accent)}#dsh-plan .p-frame.is-unreachable{opacity:.76;border-style:dashed}#dsh-plan .p-frame-unreachable{position:absolute;left:8px;top:20px;max-width:calc(100% - 16px);color:var(--uupm-error);font-size:11px;pointer-events:none}#dsh-plan .p-node.remote.is-unreachable{opacity:.72;border-left-color:var(--uupm-error)}#dsh-plan .p-node.remote.is-unreachable .sub{color:var(--uupm-error)}#dsh-plan .p-node{position:absolute;width:172px;height:56px;padding:8px 26px 8px 14px;background:var(--card-bg);border:1px solid var(--card-line);border-left:3px solid var(--edge-live);border-radius:8px;cursor:grab;-webkit-user-select:none;user-select:none;transition:border-color .12s cubic-bezier(.2,0,0,1),transform .12s cubic-bezier(.2,0,0,1)}#dsh-plan .p-node:hover{border-color:var(--card-line-hover)}#dsh-plan .p-node:active{cursor:grabbing}#dsh-plan .p-node:focus-visible{outline:2px solid var(--accent);outline-offset:2px}#dsh-plan .p-node.selected{outline:2px solid var(--accent);outline-offset:1px}#dsh-plan .p-node.dragging{transform:scale(1.02);border-color:var(--accent)}#dsh-plan .p-node.cold{border-left-color:var(--edge-cold)}#dsh-plan .p-node .nm{font-weight:600;display:flex;align-items:center;gap:7px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}#dsh-plan .p-node .nm-text{min-width:0;overflow:hidden;white-space:normal;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;line-height:1.25}#dsh-plan .p-node.remote .nm-text{overflow-wrap:anywhere}#dsh-plan .p-node .dot{width:8px;height:8px;border-radius:50%;background:var(--edge-live);flex:none}#dsh-plan .p-node.cold .dot{background:transparent;border:1.5px solid var(--edge-cold)}#dsh-plan .p-node .sub{font-size:11px;color:var(--ink-muted);margin-top:2px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}#dsh-plan .p-node.pulse{box-shadow:0 0 0 2px var(--accent),0 0 14px 4px var(--uupm-wash-15);border-color:var(--accent)}#dsh-plan .p-search{position:relative}#dsh-plan .p-search-input{width:170px;min-height:28px;padding:2px 8px;font-size:12px;background:transparent;color:var(--ink);border:1px solid var(--card-line);border-radius:6px}#dsh-plan .p-search-input:focus-visible{outline:2px solid var(--accent);outline-offset:1px}#dsh-plan .p-search-list{position:absolute;top:100%;left:0;margin-top:4px;display:none;min-width:240px;max-height:220px;overflow:auto;z-index:9;background:var(--toolbar-bg);border:1px solid var(--card-line);border-radius:6px}#dsh-plan .p-search-hit{padding:5px 10px;font-size:12px;color:var(--ink);cursor:pointer;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}#dsh-plan .p-search-hit:hover,#dsh-plan .p-search-hit.active{background:var(--uupm-wash-15)}#dsh-plan .p-node .prio{position:absolute;top:6px;right:8px;font-size:10px;color:var(--ink-muted);border:1px solid var(--card-line);border-radius:4px;padding:0 5px}#dsh-plan .p-marquee{position:absolute;z-index:2;display:none;pointer-events:none;border:1px solid var(--accent);background:var(--uupm-wash-8)}#dsh-plan .p-toolbar{position:absolute;top:16px;left:16px;z-index:3;display:flex;gap:6px;align-items:center;background:var(--toolbar-bg);border:1px solid var(--card-line);border-radius:8px;padding:6px 8px}#dsh-plan .p-tabs{position:absolute;top:16px;left:50%;transform:translate(-50%);z-index:3;display:flex;gap:4px;background:var(--toolbar-bg);border:1px solid var(--card-line);border-radius:8px;padding:4px}#dsh-plan .p-tabs [role=tab]{background:transparent;color:var(--ink-muted);border:1px solid transparent;border-radius:6px;padding:4px 12px;font:inherit;cursor:pointer}#dsh-plan .p-tabs [role=tab]:hover{color:var(--ink);border-color:var(--card-line)}#dsh-plan .p-tabs [role=tab][aria-selected=true]{color:var(--ink);border-color:var(--accent);background:var(--uupm-wash-12)}#dsh-plan .p-tabs [role=tab]:focus-visible{outline:2px solid var(--accent);outline-offset:1px}#dsh-plan .p-toolbar button{background:transparent;color:var(--ink);border:1px solid var(--card-line);border-radius:6px;padding:4px 10px;font:inherit;cursor:pointer;white-space:nowrap}#dsh-plan .p-toolbar button:hover{border-color:var(--accent)}#dsh-plan .p-toolbar button:active{background:var(--uupm-wash-15)}#dsh-plan .p-toolbar button:focus-visible{outline:2px solid var(--accent);outline-offset:1px}#dsh-plan .p-zoom{min-width:44px;text-align:center;font-size:11px;color:var(--ink-muted)}#dsh-plan .p-sep{align-self:stretch;width:1px;margin:2px 4px;background:var(--card-line)}#dsh-plan .p-lamp{display:flex;align-items:center;gap:6px;font-size:11px;color:var(--ink-muted);padding:0 6px}#dsh-plan .p-lamp i{width:7px;height:7px;border-radius:50%;background:var(--ink-muted);transition:background .14s ease}#dsh-plan .p-lamp.saved i{background:var(--edge-live)}#dsh-plan .p-lamp.pending i{background:var(--uupm-warn)}#dsh-plan .p-lamp.error{color:var(--uupm-error);cursor:pointer}#dsh-plan .p-lamp.error i{background:var(--uupm-error)}#dsh-plan .p-lamp.error:hover{border:1px solid var(--uupm-error);border-radius:4px}#dsh-plan .p-status{position:absolute;top:16px;right:16px;z-index:3;display:flex;gap:14px;background:var(--toolbar-bg);border:1px solid var(--card-line);border-radius:8px;padding:8px 14px;font-size:12px}#dsh-plan .p-status b{font-weight:600}#dsh-plan .ok{color:var(--edge-live)}#dsh-plan .warn{color:var(--uupm-warn)}#dsh-plan .mut{color:var(--ink-muted)}#dsh-plan .p-legend{position:absolute;bottom:16px;left:16px;z-index:3;font-size:11px;color:var(--ink-muted);background:var(--toolbar-bg);border:1px solid var(--card-line);border-radius:8px;padding:4px 10px}#dsh-plan .p-legend summary{cursor:pointer;padding:2px 0;-webkit-user-select:none;user-select:none}#dsh-plan .p-legend summary:focus-visible{outline:2px solid var(--accent);outline-offset:2px}#dsh-plan .p-legend[open]{padding-bottom:8px}#dsh-plan .p-legend-rows{display:grid;gap:4px;margin-top:4px}#dsh-plan .p-legend i{display:inline-block;width:18px;border-top:2px solid var(--uupm-edge-member);vertical-align:middle;margin-right:6px}#dsh-plan .p-legend i.dashed{border-top-style:dashed}@media (max-width:680px){#dsh-plan .p-toolbar{position:relative;top:auto;left:auto;margin:8px 8px 0;flex-wrap:wrap;row-gap:6px}#dsh-plan .p-toolbar>*{flex:none}#dsh-plan .p-toolbar .p-search{order:-1;flex:1 1 100%}#dsh-plan .p-toolbar .p-sep{display:none}#dsh-plan .p-toolbar .p-search-input{width:100%;box-sizing:border-box}#dsh-plan .p-status{position:relative;top:auto;right:auto;left:auto;width:fit-content;margin:6px 8px 0;padding:6px 10px;gap:10px;flex-wrap:wrap}#dsh-plan .p-legend{display:none}}@media (pointer:coarse){#dsh-plan .p-toolbar button{min-height:36px;min-width:36px}}@media (prefers-reduced-motion: reduce){#dsh-plan *{transition:none!important;animation:none!important}}#dsh-plan .p-frame.drop-target{border-color:var(--accent);border-width:2px;background:var(--uupm-wash-12)}#dsh-plan .p-frame-head:focus-visible{outline:2px solid var(--accent);outline-offset:1px}#dsh-plan .p-node.remote{border-left-color:var(--federal);padding-right:46px}#dsh-plan .p-node.remote .dot{background:var(--federal)}#dsh-plan .p-node.remote .prio{color:var(--ink)}#dsh-plan .p-node .prio.lnk-linked{color:var(--live, #2e9e5b);border-color:var(--live, #2e9e5b)}#dsh-plan .p-node .prio.lnk-stranger{color:var(--ink-muted);border-color:var(--card-line)}#dsh-plan .e-activity{stroke:var(--accent);stroke-width:2;stroke-dasharray:8 6;stroke-opacity:.9}#dsh-plan .e-federal{stroke:var(--federal);stroke-width:1.5;stroke-dasharray:6 5;stroke-opacity:.5}#dsh-plan .edge-label{font-size:10.5px;fill:var(--ink-muted)}@media (prefers-reduced-motion: no-preference){#dsh-plan .e-activity{animation:p-activity-flow 1.1s linear infinite}}@keyframes p-activity-flow{to{stroke-dashoffset:-28}}#dsh-plan .p-status{cursor:pointer}#dsh-plan .p-status:hover{border-color:var(--accent)}#dsh-plan .p-status:active{background:var(--uupm-wash-12)}#dsh-plan .p-status:focus-visible{outline:2px solid var(--accent);outline-offset:2px}#dsh-plan .p-menu{position:fixed;z-index:5;min-width:170px;display:grid;padding:4px;gap:2px;background:var(--toolbar-bg);border:1px solid var(--card-line);border-radius:8px}#dsh-plan .p-menu [role=menuitem]{background:transparent;color:var(--ink);border:1px solid transparent;border-radius:6px;padding:6px 10px;font:inherit;text-align:left;cursor:pointer;white-space:nowrap}#dsh-plan .p-menu [role=menuitem]:hover{border-color:var(--card-line);background:var(--uupm-wash-8)}#dsh-plan .p-menu [role=menuitem]:active{background:var(--uupm-wash-18)}#dsh-plan .p-menu [role=menuitem]:focus-visible{outline:2px solid var(--accent);outline-offset:1px}#dsh-plan .p-menu [role=menuitem][aria-disabled=true]{color:var(--ink-muted);cursor:not-allowed}#dsh-plan .p-dialog{position:absolute;top:0;right:0;bottom:0;left:0;z-index:6;display:grid;place-items:center;background:var(--scrim)}#dsh-plan .p-dialog-panel{min-width:300px;padding:14px 16px;display:grid;gap:10px;background:var(--uupm-bg-2);border:1px solid var(--card-line);border-radius:10px}#dsh-plan .p-dialog-title{font-weight:600;font-size:12.5px;color:var(--ink)}#dsh-plan .p-dialog-input{font:inherit;color:var(--ink);background:var(--uupm-bg-0);border:1px solid var(--card-line);border-radius:6px;padding:7px 10px}#dsh-plan .p-dialog-input:hover{border-color:color-mix(in srgb,var(--uupm-ink-1) 55%,transparent)}#dsh-plan .p-dialog-input:focus-visible{outline:2px solid var(--accent);outline-offset:1px;border-color:var(--accent)}#dsh-plan .p-dialog-err{min-height:1.2em;font-size:11px;color:var(--uupm-error)}#dsh-plan .p-dialog-row{display:flex;gap:8px;justify-content:flex-end}#dsh-plan .p-dialog-row button{background:transparent;color:var(--ink);border:1px solid var(--card-line);border-radius:6px;padding:5px 12px;font:inherit;cursor:pointer}#dsh-plan .p-dialog-row button:hover{border-color:var(--accent)}#dsh-plan .p-dialog-row button:active{background:var(--uupm-wash-15)}#dsh-plan .p-dialog-row button:focus-visible{outline:2px solid var(--accent);outline-offset:1px}#dsh-plan .p-notice-stack{position:absolute;bottom:52px;left:50%;transform:translate(-50%);z-index:5;display:grid;gap:6px;justify-items:center;pointer-events:none}#dsh-plan .p-notice{max-width:60ch;padding:7px 12px;font-size:12px;color:var(--ink);background:var(--toolbar-bg);border:1px solid var(--card-line);border-radius:8px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}#dsh-plan .p-notice.error{color:var(--error-ink);border-color:var(--uupm-error);background:var(--error-panel)}#dsh-plan .p-netbtn{color:var(--ink-muted)}#dsh-plan .p-netbtn:not([disabled]){color:var(--ink)}#dsh-plan .p-netmenu{max-height:240px;overflow:auto}#dsh-plan .p-nodebtn{color:var(--ink)}#dsh-plan .p-nodelist{min-width:300px;max-width:340px;max-height:420px;overflow:auto;padding:6px}#dsh-plan .p-nodelist-head{display:flex;align-items:center;justify-content:space-between;gap:8px;padding:2px 4px 6px;border-bottom:1px solid var(--card-line)}#dsh-plan .p-nodelist-title{font-size:12px;font-weight:600;color:var(--ink)}#dsh-plan .p-nodesel{font:inherit;font-size:11.5px;color:var(--ink);background:var(--uupm-bg-0);border:1px solid var(--card-line);border-radius:6px;padding:2px 6px;max-width:220px}#dsh-plan .p-nodesel:focus-visible{outline:2px solid var(--accent);outline-offset:1px}#dsh-plan .p-nodelist-group{font-size:11px;color:var(--ink-muted);padding:8px 4px 3px;display:flex;align-items:baseline;gap:8px}#dsh-plan .p-nodelist-note{font-size:10px;color:var(--ink-muted);opacity:.8}#dsh-plan .p-noderow{display:flex;align-items:center;gap:6px;padding:3px 4px;border-radius:6px;font-size:12px;color:var(--ink)}#dsh-plan .p-noderow:hover{background:var(--uupm-wash-8)}#dsh-plan .p-nodedot{flex:none;width:7px;height:7px;border-radius:50%;background:var(--edge-live)}#dsh-plan .p-nodedot.cold{background:var(--ink-muted)}#dsh-plan .p-nodedot.off{background:transparent;border:1px solid var(--ink-muted)}#dsh-plan .p-nodename{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}#dsh-plan .p-nonet{flex:none;font-size:10px;color:var(--uupm-warn);border:1px solid var(--uupm-warn);border-radius:4px;padding:0 4px}#dsh-plan .p-teamcount{flex:none;font-size:10px;color:var(--ink-muted);border:1px solid var(--card-line);border-radius:4px;padding:0 4px}#dsh-plan .p-listbtn{flex:none;background:transparent;color:var(--ink);border:1px solid var(--card-line);border-radius:5px;padding:1px 7px;font:inherit;font-size:11px;cursor:pointer}#dsh-plan .p-listbtn:hover{border-color:var(--card-line-hover);background:var(--uupm-wash-8)}#dsh-plan .p-listbtn:focus-visible{outline:2px solid var(--accent);outline-offset:1px}#dsh-plan .p-nodelist-empty{padding:10px 4px;font-size:11.5px;color:var(--ink-muted)}#dsh-plan .p-frame{position:absolute}#dsh-plan .p-frame-handle{position:absolute;pointer-events:auto;width:10px;height:10px;z-index:2;opacity:0;transition:opacity .12s ease}#dsh-plan .p-frame:hover .p-frame-handle{opacity:1}#dsh-plan .p-frame-handle:after{content:"";position:absolute;top:2px;right:2px;bottom:2px;left:2px;background:var(--frame-ink);border-radius:2px}#dsh-plan .p-h-n{top:-5px;left:calc(50% - 12px);width:24px;height:8px;cursor:ns-resize}#dsh-plan .p-h-s{bottom:-5px;left:calc(50% - 12px);width:24px;height:8px;cursor:ns-resize}#dsh-plan .p-h-e{right:-5px;top:calc(50% - 12px);width:8px;height:24px;cursor:ew-resize}#dsh-plan .p-h-w{left:-5px;top:calc(50% - 12px);width:8px;height:24px;cursor:ew-resize}#dsh-plan .p-h-ne{top:-5px;right:-5px;cursor:nesw-resize}#dsh-plan .p-h-nw{top:-5px;left:-5px;cursor:nwse-resize}#dsh-plan .p-h-se{bottom:-5px;right:-5px;cursor:nwse-resize}#dsh-plan .p-h-sw{bottom:-5px;left:-5px;cursor:nesw-resize}#dsh-plan .p-h-ne:after,#dsh-plan .p-h-sw:after{transform:rotate(45deg)}#dsh-plan .p-h-nw:after,#dsh-plan .p-h-se:after{transform:rotate(-45deg)}#dsh-plan .p-frame.selected .p-frame-handle{opacity:1}#dsh-plan .p-frame.selected{outline:1px solid var(--frame-ink)}:root{color-scheme:dark;--n-bg:#060a12;--n-ink:#dde3f0;--n-ink-muted:#7a86a0;--n-panel:#0d1322;--n-live:#4ade80;--n-cold:#7a86a0;--n-border:#223052;--n-act:#f59e0b;--n-danger:#f87171;--n-accent:#9673f7;--n-rail-w:300px;--n-canvas:#22d3ee;--n-line:var(--n-border);--n-raised:#131b2e;--n-federal:#6366f1;--n-card-line:#5c6680;--n-error-ink:#fecaca;--n-error-panel:#2a0d10f2;--n-shadow:rgba(0,0,0,.35)}@media (prefers-color-scheme: light){:root{--n-bg:#eef2fa;--n-ink:#1a2438;--n-ink-muted:#5a6580;--n-panel:#ffffff;--n-live:#157a37;--n-border:#c6d0e6;--n-act:#a84d08;--n-danger:#b91c1c;--n-accent:#6d28d9;--n-cold:#636c81;--n-canvas:#0e7490;--n-raised:#ffffff;--n-federal:#4f46e5;--n-card-line:#8a95ae;--n-error-ink:#b91c1c;--n-error-panel:#fef2f2f2;--n-shadow:rgba(26,36,56,.16)}}@media (min-width:1440px){:root{--n-rail-w:340px }}html,body,#app{height:100%;margin:0}body{background:var(--n-bg);color:var(--n-ink);font:13px/1.45 system-ui,Segoe UI,Roboto,PingFang SC,Microsoft YaHei,sans-serif}.wb{display:flex;flex-direction:column;height:100%}.wb-header{display:flex;align-items:center;gap:12px;padding:8px 14px;border-bottom:1px solid var(--n-border);background:var(--n-panel)}.wb-title{display:flex;align-items:center;gap:10px;font-weight:600;font-size:14px;white-space:nowrap}.wb-badge{font-size:11px;font-weight:400;color:var(--n-ink-muted);border:1px solid var(--n-border);border-radius:99px;padding:1px 8px}.wb-badge[hidden]{display:none}.wb-row-remote{margin-left:6px;padding:0 6px;border:1px solid currentColor;border-radius:99px;font-size:10.5px;color:var(--n-ink-muted);vertical-align:1px}.wb-header-stats{display:flex;gap:16px;font-size:12px;color:var(--n-ink-muted);flex-wrap:wrap;min-width:0}.wb-header-stats .wb-kv{display:flex;gap:6px}.wb-header-stats .wb-kv-k{color:var(--n-ink-muted)}.wb-header-stats .wb-kv-v{color:var(--n-ink)}.wb-header-ok{color:var(--n-ink-muted)}.wb-alert{border:1px solid currentColor;border-radius:99px;padding:0 9px;line-height:20px;white-space:nowrap;cursor:pointer;background:transparent;font:inherit}.wb-alert:hover{background:color-mix(in srgb,currentColor 12%,transparent)}.wb-alert:focus-visible{outline:2px solid currentColor;outline-offset:2px}.wb-alert-danger{color:var(--n-danger)}.wb-alert-warn{color:var(--n-act)}.wb-forensics{font-family:ui-monospace,Consolas,monospace;font-size:11px}.wb-icon-btn{background:none;border:1px solid var(--n-border);color:var(--n-ink);border-radius:8px;width:30px;height:30px;display:none;align-items:center;justify-content:center;font:inherit;font-size:14px;cursor:pointer;flex:none}.wb-icon-btn:hover{border-color:var(--n-accent)}.wb-menu{margin-left:0}.wb-rail-toggle{margin-left:auto}.wb.is-rail-collapsed .wb-rail{display:none}.wb-body{position:relative;display:grid;grid-template-columns:minmax(0,var(--n-rail-w)) minmax(0,1fr);flex:1;min-height:0}.wb-rail{border-right:1px solid var(--n-border);min-width:0;min-height:0;display:flex;flex-direction:column;overflow:hidden;background:color-mix(in srgb,var(--n-panel) 60%,var(--n-bg))}.wb-side-head{font-size:11px;text-transform:uppercase;letter-spacing:.06em;color:var(--n-ink-muted);margin:10px 2px 4px}.wb-item{display:flex;gap:7px;align-items:center;width:100%;text-align:left;background:none;border:none;color:var(--n-ink);font:inherit;padding:3px 6px;border-radius:6px;cursor:pointer}.wb-item:hover{background:color-mix(in srgb,var(--n-accent) 14%,transparent)}.wb-dot{font-size:10px}.wb-dot-live{color:var(--n-live)}.wb-dot-cold{color:var(--n-cold)}.wb-dot-canvas{color:var(--n-canvas)}.wb-dot-remote{color:var(--n-act)}.wb-dir-tools{display:flex;flex-direction:column;gap:6px;padding:8px 6px 4px}.wb-search{background:var(--n-panel);border:1px solid var(--n-border);color:var(--n-ink);border-radius:6px;padding:4px 8px;font:inherit;font-size:12.5px;min-width:0}.wb-search:focus{outline:1px solid var(--n-accent)}.wb-filters{display:flex;flex-wrap:wrap;gap:4px}.wb-filter{background:none;border:1px solid var(--n-border);color:var(--n-ink-muted);border-radius:99px;padding:0 10px;min-height:24px;font:inherit;font-size:11.5px;cursor:pointer}.wb-filter:hover{border-color:var(--n-accent);color:var(--n-ink)}.wb-filter.is-active{border-color:var(--n-accent);color:var(--n-ink);background:color-mix(in srgb,var(--n-accent) 16%,transparent)}.wb-item-badge{flex:none;font-size:10.5px;color:var(--n-canvas);border:1px solid color-mix(in srgb,var(--n-canvas) 45%,transparent);border-radius:99px;padding:0 6px;line-height:17px;white-space:nowrap}.wb-item-label{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.wb-member-row{display:flex;align-items:center;gap:8px;padding:3px 2px;border-radius:6px}.wb-member-row:hover{background:color-mix(in srgb,var(--n-accent) 10%,transparent)}.wb-member-dot{flex:none;font-size:11px;color:var(--n-ink-muted);min-width:44px}.wb-member-label{flex:1 1 auto;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.wb-member-remove,.wb-member-submit{background:none;border:1px solid var(--n-border);color:var(--n-ink);border-radius:6px;padding:1px 8px;font:inherit;font-size:11.5px;cursor:pointer;flex:none}.wb-member-remove:hover:not(:disabled),.wb-member-submit:hover:not(:disabled){border-color:var(--n-danger)}.wb-member-submit:hover:not(:disabled){border-color:var(--n-accent)}.wb-member-add{display:flex;flex-wrap:wrap;gap:6px;margin-top:6px}.wb-member-pick,.wb-member-manual{background:var(--n-panel);border:1px solid var(--n-border);color:var(--n-ink);border-radius:6px;padding:3px 8px;font:inherit;font-size:12px;min-width:0}.wb-member-pick{flex:1 1 150px}.wb-member-manual{flex:1 1 130px}.wb-member-pick:focus,.wb-member-manual:focus{outline:1px solid var(--n-accent)}.wb-hint{margin-top:10px;font-size:11px;color:var(--n-ink-muted);line-height:1.5}.wb-dispatch{margin-top:12px;border-top:1px dashed var(--n-border);padding-top:8px}.wb-dispatch-form{display:flex;flex-direction:column;gap:6px;margin-top:6px}.wb-dispatch-text{background:var(--n-panel);border:1px solid var(--n-border);color:var(--n-ink);border-radius:6px;padding:5px 8px;font:inherit;font-size:12px;min-height:52px;resize:vertical}.wb-dispatch-text:focus{outline:1px solid var(--n-accent)}.wb-dispatch-submit{align-self:flex-end;background:none;border:1px solid var(--n-border);color:var(--n-ink);border-radius:6px;padding:2px 14px;font:inherit;font-size:11.5px;cursor:pointer}.wb-dispatch-submit:hover:not(:disabled){border-color:var(--n-accent)}.wb-dispatch-note{font-size:11px;color:var(--n-ink-muted);line-height:1.4;min-height:0}.wb-stage{position:relative;min-width:0;min-height:0;display:flex;flex-direction:column}.wb-stage-board{position:absolute;top:0;right:0;bottom:0;left:0;overflow:hidden}.wb-stage-board.is-hidden{display:none}.wb-data{display:flex;flex-direction:column;gap:14px;padding:10px 14px;overflow-y:auto;min-height:0}.wb-data.is-hidden{display:none}.wb-pane-head{font-size:12px;color:var(--n-ink-muted);margin:4px 0 8px}.wb-pane-subhead{font-size:11px;text-transform:uppercase;letter-spacing:.06em;color:var(--n-ink-muted);margin:12px 0 6px}.wb-table,.wb-row{display:flex;gap:10px;align-items:baseline}.wb-row{font-family:ui-monospace,Consolas,monospace;font-size:12px;background:color-mix(in srgb,var(--n-panel) 55%,transparent);border:1px solid var(--n-border);border-radius:6px;padding:3px 8px;flex-wrap:wrap}.wb-row-team{color:var(--n-accent);min-width:150px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.wb-row-meta{color:var(--n-ink-muted)}.wb-row-badges{color:var(--n-live)}.wb-row-dir{min-width:16px}.wb-row-dir.is-fail{color:var(--n-danger)}.wb-btn{background:none;border:1px solid var(--n-border);color:var(--n-ink);border-radius:6px;padding:2px 10px;font:inherit;font-size:12px;cursor:pointer;margin-left:auto}.wb-btn:hover:not(:disabled){border-color:var(--n-accent)}.wb-btn:disabled{opacity:.5;cursor:default}.wb-btn-primary{border-color:var(--n-accent);color:var(--n-ink)}.wb-action{display:flex;gap:10px;align-items:baseline;font-size:12.5px;padding:5px 8px;border-radius:6px;border:1px solid var(--n-border);margin-bottom:4px}.wb-action-high{border-color:var(--n-danger)}.wb-action-text{flex:1}.wb-draft{display:flex;flex-direction:column;gap:8px;max-width:560px;margin-top:6px}.wb-select,.wb-textarea{background:var(--n-panel);border:1px solid var(--n-border);color:var(--n-ink);border-radius:8px;padding:6px 9px;font:inherit}.wb-textarea{resize:vertical}.wb-select:focus,.wb-textarea:focus{outline:1px solid var(--n-accent)}.wb-inspector{position:absolute;top:8px;right:8px;width:280px;max-height:calc(100% - 16px);overflow-y:auto;background:var(--n-panel);border:1px solid var(--n-border);border-radius:10px;padding:10px;z-index:20;box-shadow:0 8px 24px var(--n-shadow);display:none}.wb-inspector.is-open{display:block}.wb-inspector-head{display:flex;justify-content:space-between;align-items:center;margin-bottom:6px}.wb-inspector-title{font-weight:600;font-size:12.5px}.wb-inspector .wb-icon-btn{display:inline-flex;width:24px;height:24px;font-size:12px}.wb-card{display:flex;flex-direction:column;gap:6px}.wb-kv{display:flex;gap:8px;font-size:12px}.wb-kv-k{color:var(--n-ink-muted);min-width:58px;flex:none}.wb-kv-v{word-break:break-all}.wb-muted{color:var(--n-ink-muted)}.wb-chat{position:absolute;top:8px;right:8px;bottom:8px;width:400px;max-width:calc(100% - 16px);display:flex;flex-direction:column;background:var(--n-panel);border:1px solid var(--n-border);border-radius:12px;z-index:22;box-shadow:0 8px 24px var(--n-shadow);overflow:hidden;transform:translate(calc(100% + 12px));transition:transform .18s ease;pointer-events:none}.wb-chat.is-open{transform:translate(0);pointer-events:auto}.wb-chat-head{display:flex;align-items:center;gap:8px;padding:10px 10px 10px 12px;border-bottom:1px solid var(--n-border);flex:none}.wb-chat-dot{flex:none;width:8px;height:8px;border-radius:50%;background:var(--n-ink-muted)}.wb-chat-dot.is-live{background:var(--n-live)}.wb-chat-dot.is-cold{background:transparent;border:1.5px solid var(--n-ink-muted)}.wb-chat-dot.is-peer{background:var(--n-federal)}.wb-chat-titles{display:flex;flex-direction:column;flex:1 1 auto;min-width:0;line-height:1.3}.wb-chat-title{font-weight:600;font-size:13.5px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.wb-chat-sub{font:11px/1.4 ui-monospace,Consolas,monospace;color:var(--n-ink-muted);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.wb-chat .wb-icon-btn{display:inline-flex;width:28px;height:28px;font-size:13px;flex:none;border-color:transparent}.wb-chat .wb-icon-btn:hover{border-color:var(--n-border)}.wb-chat .wb-icon-btn:focus-visible{outline:2px solid var(--n-accent);outline-offset:1px}.wb-chat .wb-chat-back[hidden]{display:none}.wb-chat-info-btn[aria-expanded=true]{border-color:var(--n-accent);color:var(--n-accent)}.wb-chat-info{flex:none;display:flex;flex-direction:column;gap:4px;padding:8px 12px;font-size:12px;border-bottom:1px solid var(--n-border);background:color-mix(in srgb,var(--n-bg) 55%,var(--n-panel))}.wb-chat-info[hidden]{display:none}.wb-chat-info .wb-kv-v{font-family:ui-monospace,Consolas,monospace;font-size:11.5px}.wb-chat-thread{flex:1 1 auto;min-height:0;overflow-y:auto;overscroll-behavior:contain;display:flex;flex-direction:column;gap:10px;padding:12px}.wb-chat-thread:focus-visible{outline:2px solid var(--n-accent);outline-offset:-2px}.wb-chat-log,.wb-chat-sent{display:flex;flex-direction:column;gap:10px}.wb-chat-notice{align-self:center;max-width:92%;text-align:center;font-size:11.5px;line-height:1.5;color:var(--n-ink-muted);border:1px dashed var(--n-border);border-radius:8px;padding:6px 10px}.wb-chat-notice[hidden]{display:none}.wb-chat-empty{align-self:center;padding:24px 8px;font-size:12px;color:var(--n-ink-muted);text-align:center}.wb-chat-empty.is-error{color:var(--n-danger)}.wb-msg{display:flex;flex-direction:column;gap:4px;max-width:86%;padding:8px 11px;border-radius:12px;font-size:13px;line-height:1.55}.wb-msg-assistant{align-self:flex-start;background:var(--n-raised);border:1px solid var(--n-border);border-bottom-left-radius:4px}.wb-msg-user{align-self:flex-end;background:color-mix(in srgb,var(--n-accent) 16%,var(--n-panel));border:1px solid color-mix(in srgb,var(--n-accent) 35%,transparent);border-bottom-right-radius:4px}.wb-msg-ledger{align-self:center;max-width:92%;background:transparent;border:1px dashed var(--n-border);font-size:12px}.wb-msg-ledger .wb-msg-text{color:var(--n-ink-muted)}.wb-msg-ledger .wb-msg-meta{justify-content:center}.wb-msg-in .wb-msg-meta{justify-content:flex-start}.wb-msg-who{position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap}.wb-msg-text{color:var(--n-ink);white-space:pre-wrap;word-break:break-word;overflow-wrap:anywhere}.wb-msg-meta{display:flex;flex-wrap:wrap;justify-content:flex-end;align-items:center;gap:6px;font-size:11px}.wb-msg-task{font-family:ui-monospace,Consolas,monospace;color:var(--n-ink-muted)}.wb-msg-status{border:1px solid currentColor;border-radius:99px;padding:0 7px;line-height:18px;white-space:nowrap}.wb-msg-status.is-wait,.wb-msg-status.is-muted{color:var(--n-ink-muted)}.wb-msg-status.is-ok{color:var(--n-live)}.wb-msg-status.is-warn{color:var(--n-act)}.wb-msg-status.is-danger{color:var(--n-danger)}.wb-chat-divider{display:flex;align-items:center;gap:8px;font-size:11px;color:var(--n-ink-muted);margin-top:4px}.wb-chat-divider:before,.wb-chat-divider:after{content:"";flex:1;border-top:1px solid var(--n-border)}.wb-chat-sessions{display:flex;flex-direction:column;gap:6px}.wb-chat-session{display:flex;flex-direction:column;align-items:flex-start;gap:2px;width:100%;text-align:left;background:var(--n-raised);border:1px solid var(--n-border);border-radius:8px;padding:7px 10px;color:var(--n-ink);font:inherit;cursor:pointer}.wb-chat-session:hover{border-color:var(--n-accent)}.wb-chat-session:focus-visible{outline:2px solid var(--n-accent);outline-offset:1px}.wb-chat-session-id{font:12px ui-monospace,Consolas,monospace}.wb-chat-session-meta{font-size:11px;color:var(--n-ink-muted)}.wb-chat-foot{flex:none;border-top:1px solid var(--n-border);padding:8px 10px 10px;background:var(--n-panel)}.wb-chat-composer{display:flex;flex-direction:column;gap:4px}.wb-chat-composer-row{display:flex;align-items:flex-end;gap:8px}.wb-chat-composer .wb-dispatch-text{flex:1 1 auto;min-height:38px;max-height:160px;resize:none;border-radius:10px;padding:8px 10px;font-size:13px;line-height:1.5}.wb-chat-composer .wb-dispatch-submit{align-self:auto;height:38px;padding:0 16px;border-radius:10px;background:var(--n-accent);border-color:var(--n-accent);color:var(--n-bg);font-size:13px;font-weight:600}.wb-chat-composer .wb-dispatch-submit:hover:not(:disabled){border-color:var(--n-accent);filter:brightness(1.08)}.wb-chat-composer .wb-dispatch-submit:disabled{opacity:.45;cursor:default}.wb-chat-composer .wb-dispatch-note{font-size:11px;padding-left:2px}.wb-chat-composer .wb-dispatch-note.is-error{color:var(--n-danger)}.wb-chat-readonly{font-size:12px;color:var(--n-ink-muted);text-align:center;padding:4px 0}.nexus-fault{display:none;position:fixed;top:10px;right:12px;z-index:50;max-width:420px;font:12px/1.5 ui-monospace,Consolas,monospace;color:var(--n-error-ink);background:var(--n-error-panel);border:1px solid var(--n-danger);border-radius:8px;padding:6px 10px;pointer-events:none}@media (max-width:1023px){.wb-menu{display:inline-flex}.wb-rail-toggle{display:none}.wb-body{grid-template-columns:minmax(0,1fr)}.wb-rail{position:fixed;left:0;top:0;bottom:0;width:min(86vw,320px);z-index:40;background:var(--n-panel);border-right:1px solid var(--n-border);transform:translate(-102%);transition:transform .18s ease;box-shadow:8px 0 24px var(--n-shadow)}.wb.is-rail-open .wb-rail{transform:translate(0)}.wb-inspector{left:8px;right:8px;width:auto;top:auto;bottom:8px;max-height:45%}.wb-chat{left:8px;right:8px;width:auto;top:auto;bottom:8px;height:85%;max-height:85%;transform:translateY(102%)}.wb-chat.is-open{transform:translateY(0)}}@media (pointer:coarse){.wb-filter,.wb-item,.wb-tab{min-height:36px}.wb-icon-btn,.wb-inspector .wb-icon-btn,.wb-chat .wb-icon-btn{width:36px;height:36px}}@media (max-width:680px){.wb-header{flex-wrap:wrap;row-gap:4px}.wb-header-stats{order:3;width:100%}.wb-row-team{min-width:0;flex:1 1 auto}.wb-data{padding:8px}}.wb-host-row{display:flex;align-items:center;gap:7px;padding:4px 6px;border:1px solid var(--n-border);border-radius:7px;margin-bottom:4px;cursor:pointer;font-size:12px}.wb-host-row:hover{border-color:var(--n-accent);background:color-mix(in srgb,var(--n-accent) 8%,transparent)}.wb-host-row:focus-visible{outline:2px solid var(--n-accent);outline-offset:1px}.wb-host-lamp{flex:none;width:8px;height:8px;border-radius:50%;background:var(--n-ink-muted)}.wb-host-lamp.is-live{background:var(--n-live)}.wb-host-lamp.is-warm{background:var(--n-act)}.wb-host-lamp.is-cold{background:var(--n-ink-muted)}.wb-host-lamp.is-fail{background:var(--n-danger)}.wb-host-lamp.is-unknown{background:transparent;border:1px solid var(--n-ink-muted)}.wb-host-name{flex:1 1 auto;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--n-ink)}.wb-host-badge{flex:none;font-size:10.5px;border-radius:99px;padding:0 7px;line-height:17px;border:1px solid var(--n-border)}.wb-host-badge.is-linked{color:var(--n-live);border-color:var(--n-live)}.wb-host-badge.is-stranger{color:var(--n-ink-muted);border-color:var(--n-border)}.wb-host-ver{flex:none;font-size:10px;color:var(--n-ink-muted);border:1px solid var(--n-border);border-radius:4px;padding:0 4px}.wb-host-url{flex:none;max-width:40%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--n-ink-muted);font-size:10.5px}.wb-tabs{flex:none;display:flex;gap:2px;padding:6px 6px 0;border-bottom:1px solid var(--n-border);overflow-x:auto;scrollbar-width:none}.wb-tab{flex:1 1 auto;display:inline-flex;align-items:center;justify-content:center;gap:5px;min-width:0;background:none;border:none;border-bottom:2px solid transparent;color:var(--n-ink-muted);font:inherit;font-size:12.5px;padding:6px 6px 7px;cursor:pointer;white-space:nowrap}.wb-tab:hover{color:var(--n-ink)}.wb-tab.is-active{color:var(--n-ink);border-bottom-color:var(--n-accent);font-weight:600}.wb-tab:focus-visible{outline:2px solid var(--n-accent);outline-offset:-2px;border-radius:6px 6px 0 0}.wb-tab[hidden]{display:none}.wb-tab-badge{font:10.5px/16px ui-monospace,Consolas,monospace;color:var(--n-ink-muted);font-weight:400}.wb-tab-badge:empty{display:none}.wb-tab-badge.is-danger,.wb-tab-badge.is-warn,.wb-tab-badge.is-accent{padding:0 6px;border-radius:99px;border:1px solid currentColor}.wb-tab-badge.is-danger{color:var(--n-danger)}.wb-tab-badge.is-warn{color:var(--n-act)}.wb-tab-badge.is-accent{color:var(--n-accent)}.wb-tabpanels{flex:1 1 auto;min-height:0;display:flex;flex-direction:column}.wb-tabpanel{flex:1 1 auto;min-height:0;overflow-y:auto;overscroll-behavior:contain;padding:8px 10px 16px}.wb-tabpanel[hidden]{display:none}.wb-tabpanel:focus-visible{outline:2px solid var(--n-accent);outline-offset:-2px}.wb-tabpanel .wb-pane{display:flex;flex-direction:column;gap:8px}.wb-tabpanel .wb-dir-tools{padding:0 0 6px}.wb-dir-group{display:flex;flex-direction:column;gap:1px;margin-top:10px}.wb-dir-group:first-child{margin-top:2px}.wb-dir-head{display:flex;align-items:baseline;justify-content:space-between;gap:8px;padding:0 6px 4px;font-size:11px;letter-spacing:.04em;color:var(--n-ink-muted)}.wb-dir-head-label{font-weight:600;color:var(--n-ink)}.wb-dir-head-note{font-size:10.5px}.wb-dir-day{padding:6px 6px 2px;font-size:10.5px;color:var(--n-ink-muted)}.wb-dir-empty{padding:24px 8px;text-align:center;font-size:12px;color:var(--n-ink-muted)}.wb-directory .wb-item{gap:9px;padding:5px 6px;border-radius:8px}.wb-directory .wb-item:focus-visible{outline:2px solid var(--n-accent);outline-offset:-2px}.wb-item-text{display:flex;flex-direction:column;flex:1 1 auto;min-width:0;line-height:1.35}.wb-item-sub{font:11px/1.35 ui-monospace,Consolas,monospace;color:var(--n-ink-muted);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.wb-item.is-untitled .wb-item-label{color:var(--n-ink-muted);font-family:ui-monospace,Consolas,monospace;font-size:12px}.wb-directory .wb-item.is-unreachable{opacity:.78}.wb-unreachable-note,.wb-node-warning{font-size:11px;line-height:1.35;color:var(--n-danger);white-space:normal;overflow-wrap:anywhere}.wb-dot-log{color:var(--n-ink-muted)}.wb-led-tiles{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:6px}.wb-led-tile{display:flex;flex-direction:column;align-items:flex-start;gap:1px;padding:7px 8px;border-radius:8px;border:1px solid var(--n-border);background:var(--n-raised);cursor:help;min-width:0}.wb-led-tile-v{font:600 17px/1.15 ui-monospace,Consolas,monospace;color:var(--n-ink)}.wb-led-tile-k{font-size:11px;color:var(--n-ink-muted)}.wb-led-tile.is-warn{border-color:var(--n-act)}.wb-led-tile.is-warn .wb-led-tile-v{color:var(--n-act)}.wb-led-tile.is-danger{border-color:var(--n-danger)}.wb-led-tile.is-danger .wb-led-tile-v{color:var(--n-danger)}.wb-led-split{display:flex;flex-direction:column;gap:4px}.wb-led-split-bar{display:flex;height:6px;border-radius:99px;overflow:hidden;background:var(--n-border)}.wb-led-seg{display:block;height:100%}.wb-led-split-legend{display:flex;flex-wrap:wrap;gap:4px 10px;font-size:11px;color:var(--n-ink-muted)}.wb-led-split-item{display:inline-flex;align-items:center;gap:4px}.wb-led-swatch{display:inline-block;width:8px;height:8px;border-radius:2px}.wb-led-seg.is-completed,.wb-led-swatch.is-completed{background:var(--n-live)}.wb-led-seg.is-rejected,.wb-led-swatch.is-rejected{background:var(--n-act)}.wb-led-seg.is-failed,.wb-led-swatch.is-failed{background:var(--n-danger)}.wb-led-seg.is-abandoned,.wb-led-swatch.is-abandoned{background:var(--n-ink-muted)}.wb-led-seg.is-unclassified,.wb-led-swatch.is-unclassified,.wb-led-seg.is-other,.wb-led-swatch.is-other{background:color-mix(in srgb,var(--n-ink-muted) 45%,var(--n-border))}.wb-led-group{display:flex;flex-direction:column;gap:6px;margin-top:4px}.wb-led-group-head{display:flex;align-items:baseline;justify-content:space-between;gap:8px;font-size:11.5px;font-weight:600;color:var(--n-ink)}.wb-led-group-hint{font-size:10.5px;font-weight:400;color:var(--n-ink-muted)}.wb-led-group.is-danger .wb-led-group-head{color:var(--n-danger)}.wb-led-group.is-warn .wb-led-group-head{color:var(--n-act)}.wb-led-card{position:relative;display:flex;flex-direction:column;gap:3px;padding:7px 9px;border-radius:8px;border:1px solid var(--n-border);background:var(--n-raised);min-width:0}.wb-led-card.is-danger{border-color:var(--n-danger)}.wb-led-card.is-warn{border-left:3px solid var(--n-act)}.wb-led-card.is-muted,.wb-led-card.is-quiet{background:transparent}.wb-led-card.is-link{cursor:pointer}.wb-led-card.is-link:hover{border-color:var(--n-accent)}.wb-led-card.is-link:focus-visible{outline:2px solid var(--n-accent);outline-offset:1px}.wb-led-card-head{display:flex;align-items:flex-start;gap:6px;min-width:0}.wb-led-dir{flex:none;font-size:12px;color:var(--n-ink-muted);line-height:1.45}.wb-led-dir.is-in{color:var(--n-federal)}.wb-led-brief{flex:1 1 auto;min-width:0;font-size:12.5px;line-height:1.45;color:var(--n-ink);display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;overflow-wrap:anywhere}.wb-led-card.is-muted .wb-led-brief,.wb-led-card.is-quiet .wb-led-brief{color:var(--n-ink-muted)}.wb-led-card.is-danger .wb-led-brief{color:var(--n-danger)}.wb-led-brief.is-missing{font-style:italic}.wb-led-meta{display:flex;flex-wrap:wrap;gap:2px 8px;font:11px/1.45 ui-monospace,Consolas,monospace;color:var(--n-ink-muted);min-width:0}.wb-led-meta>span{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:100%}.wb-led-chip{border:1px solid var(--n-border);border-radius:99px;padding:0 6px;font-family:inherit}.wb-led-abandon{position:absolute;top:6px;right:6px;margin-left:0;padding:1px 9px;font-size:11.5px}.wb-led-abandon.is-quiet{border-color:transparent;background:transparent;color:var(--n-ink-muted)}.wb-led-abandon.is-quiet:hover{border-color:var(--n-border);color:var(--n-ink)}.wb-led-card:has(.wb-led-abandon) .wb-led-card-head{padding-right:52px}.wb-led-empty{padding:24px 8px;text-align:center;font-size:12px;color:var(--n-ink-muted)}.wb-led-forensics{font-size:11px;color:var(--n-ink-muted);border-top:1px dashed var(--n-border);padding-top:6px;margin-top:4px}.wb-led-forensics summary{cursor:pointer}.wb-led-forensics summary:focus-visible{outline:2px solid var(--n-accent);outline-offset:1px}.wb-led-forensics-body{display:flex;flex-direction:column;gap:2px;padding:4px 0 0 12px;font-family:ui-monospace,Consolas,monospace}