tmux-weblink 2.2.31 → 2.2.33

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.
@@ -1,41 +1,41 @@
1
- var bn=/\x1b\](?:10|11|110|111|104)(?:;[^\x07\x1b]*)?\x1b?(?:\\|\x07)/g;function Qe(e){return e.replace(/\x1b\[\?1049[hl]/g,"")}function me(e){return e.replace(bn,"")}var Fe;function Ln(){return Fe||(document.querySelector("link[data-tmux-web-xterm-css]")?Fe=Promise.resolve():(Fe=new Promise(e=>{let t=document.createElement("link");t.rel="stylesheet",t.href="/assets/xterm.css",t.setAttribute("data-tmux-web-xterm-css",""),t.addEventListener("load",()=>e(),{once:!0}),t.addEventListener("error",()=>e(),{once:!0}),document.head.appendChild(t)}),Fe))}var En=class Kt{terminal;fitAddon;container;verifyRaf=0;verifyRounds=0;shrinkCols=0;lastLimit=0;lastCheckAt=0;webglActive=!1;webglAddon=null;constructor(t,s,n){this.container=t,this.terminal=s,this.fitAddon=n,this.terminal.loadAddon(this.fitAddon),this.terminal.open(t),this.enableWebglRenderer()}enableWebglRenderer(){import("./addon-webgl-B45EJ6AW.js").then(({WebglAddon:t})=>{let s=new t;s.onContextLoss(()=>{this.webglActive=!1,this.webglAddon=null;try{s.dispose()}catch{}this.lastLimit>0&&this.scheduleColumnCheck(this.lastLimit,!0)});try{this.terminal.loadAddon(s)}catch{return}this.webglAddon=s,this.webglActive=!0,this.fit()}).catch(()=>{})}static async create(t,s,n){let[{Terminal:a},{FitAddon:r}]=await Promise.all([import("./xterm-BXEES47M.js"),import("./addon-fit-D5N335P2.js"),Ln()]),c=new a({fontSize:14,fontFamily:"'JetBrains Mono', 'SF Mono', 'Menlo', monospace",cursorBlink:!0,cursorStyle:"bar",scrollback:s,convertEol:!1,smoothScrollDuration:120,theme:n});return new Kt(t,c,new r)}get cols(){return this.terminal.cols}get rows(){return this.terminal.rows}write(t){return new Promise(s=>this.terminal.write(t,()=>{this.lastLimit>0&&this.scheduleColumnCheck(this.lastLimit),s()}))}reset(){this.terminal.reset()}scrollToBottom(){this.terminal.scrollToBottom()}scrollToLine(t,s=!1){this.terminal.scrollToLine(Math.max(0,t),s)}scrollLines(t){let s=this.terminal.buffer?.active;this.terminal.scrollLines(t)}isNearScrollbackTop(){return this.terminal.buffer.active.viewportY<=1}viewportY(){return this.terminal.buffer.active.viewportY}baseY(){return this.terminal.buffer.active.baseY}cellHeight(){let t=this.terminal.element?.querySelector(".xterm-screen")?.getBoundingClientRect().height??0,s=this.terminal.rows;return t>0&&s>0?t/s:16}fit(){let t=Cn(this.container);if(t.width<=0||t.height<=0)return!1;this.fitAddon.fit();let s=this.terminal.element?.querySelector(".xterm-viewport"),n=s?Math.max(0,s.offsetWidth-s.clientWidth):0,a=this.terminal.element?.querySelector(".vertical.scrollbar"),r=a?Math.max(0,Math.round(a.getBoundingClientRect().width)):0,c=this.container.getBoundingClientRect().left+t.width-n-r-1;if(this.lastLimit=c,this.webglActive){if(this.shrinkCols>0){let o=Math.max(10,this.terminal.cols-this.shrinkCols);o!==this.terminal.cols&&this.terminal.resize(o,this.terminal.rows)}return!0}return this.shrinkCols=0,this.verifyRounds=0,this.scheduleColumnCheck(c,!0),!0}scheduleColumnCheck(t,s=!1){if(this.lastLimit=t,this.verifyRaf)return;let n=Date.now();!s&&n-this.lastCheckAt<250||(this.lastCheckAt=n,this.verifyRaf=requestAnimationFrame(()=>{this.verifyRaf=0;try{this.recheckColumns(this.lastLimit)&&this.verifyRounds<8?(this.verifyRounds++,this.scheduleColumnCheck(this.lastLimit,!0)):this.verifyRounds=0}catch{}}))}recheckColumns(t){let s=this.terminal.element?.querySelector(".xterm-rows");if(!s)return!1;let n=0;for(let o of Array.from(s.children)){let u=o.children;for(let p=u.length-1;p>=0;p--){let E=u[p];if(!E.textContent)continue;let b=E.getBoundingClientRect().right;b>n&&(n=b);break}}if(n===0)return!1;let a=this.terminal.cols,r=this.terminal.element?.querySelector(".xterm-screen")?.getBoundingClientRect().width??0,c=a>0&&r>0?r/a:0;if(n>t){let o=n-t,u=c>0?Math.min(8,Math.ceil(o/c)):1,p=Math.max(10,a-Math.max(1,u));return p>=a?!1:(this.shrinkCols+=a-p,this.terminal.resize(p,this.terminal.rows),!0)}return!1}focus(){this.terminal.focus()}pasteText(t){this.terminal.paste(t)}input(t){this.terminal.input(t,!1)}onData(t){this.terminal.onData(t),this.terminal.onBinary(t)}onResize(t){this.terminal.onResize(t)}onScroll(t){this.terminal.onScroll(t)}attachCustomKeyEventHandler(t){this.terminal.attachCustomKeyEventHandler(t)}isFocused(){let t=document.activeElement;return t?t===this.container||t===this.terminal.textarea||this.container.contains(t)||!!t.closest?.(".xterm"):!1}getScreenText(){return this.getRowsText(0,this.terminal.rows-1)}getRowsText(t,s){let n=this.terminal.buffer.active,[a,r]=t<=s?[t,s]:[s,t],c=n.viewportY,o=[];for(let u=a;u<=r;u++){let p=n.getLine(c+u);o.push(p?p.translateToString(!0):"")}return o.join(`
2
- `)}selectRows(t,s){let n=this.terminal.buffer.active,[a,r]=t<=s?[t,s]:[s,t];this.terminal.selectLines(n.viewportY+a,n.viewportY+r)}selectCells(t,s,n,a){let r=this.terminal.buffer.active,c=Math.min(s,a),o=Math.max(s,a);if(c===o){let u=Math.min(t,n),p=Math.max(t,n);this.terminal.select(u,r.viewportY+c,p-u+1)}else this.terminal.selectLines(r.viewportY+c,r.viewportY+o)}getCellsText(t,s,n,a){let r=this.terminal.buffer.active,c=Math.min(s,a),o=Math.max(s,a),u=s<a?t:s>a?n:Math.min(t,n),p=s<a?n:s>a?t:Math.max(t,n),E=r.viewportY,b=[];for(let A=c;A<=o;A++){let M=r.getLine(E+A);if(!M){b.push("");continue}let L=A===c?u:0,O=A===o?p:this.terminal.cols-1,ae="";for(let xe=L;xe<=O;xe++){let K=M.getCell(xe);K&&(ae+=K.getChars())}b.push(ae.replace(/\s+$/,""))}return b.join(`
3
- `)}getSelection(){return this.terminal.getSelection()}clearSelection(){this.terminal.clearSelection()}hasSelectionSupport(){return!0}};function Cn(e){let t=e.getBoundingClientRect(),s=window.visualViewport;return s?{width:Math.min(t.width,s.width),height:Math.max(0,Math.min(t.height,s.height-Math.max(0,t.top)))}:t}function xn(e,t,s){return e.innerHTML="",e.classList.add("terminal-pending"),(async()=>{let n=await En.create(e,s.scrollback,s.theme),a,r=0,c,o=null,u=0,p=0,E=.2,b=10,A=.95,M=.04,L=null,O=null;function ae(i){L||(L=document.createElement("div"),L.style.cssText=["position:absolute","left:0","width:40%","padding:10px 0","text-align:center","font:600 14px/1.4 system-ui, -apple-system, sans-serif","color:rgba(255,255,255,0.95)","background:rgba(20,30,50,0.55)","border:1px solid rgba(255,255,255,0.25)","border-radius:10px","pointer-events:none","opacity:0","transition:opacity 0.15s ease","z-index:6"].join(";"),e.appendChild(L)),L.textContent=i?"\u2191 \u4E0A\u7FFB\u4E00\u9875 (PgUp)":"\u2193 \u4E0B\u7FFB\u4E00\u9875 (PgDn)",L.style.top=i?"10%":"auto",L.style.bottom=i?"auto":"10%",L.style.opacity="1",O&&clearTimeout(O),O=setTimeout(()=>{L&&(L.style.opacity="0")},900)}function xe(){O&&clearTimeout(O),L&&(L.style.opacity="0")}function K(){u&&(cancelAnimationFrame(u),u=0),p=0}function Vt(i){if(K(),Math.abs(i)<E)return;p=Math.max(-b,Math.min(b,i));let l=()=>{if(q){u=0;return}let d=n.cellHeight(),m=d>0?Math.round(p*16/d):p>0?1:-1;m===0&&(m=p>0?1:-1);let v=n.viewportY()-m,N=n.baseY(),W=Math.max(0,Math.min(v,N));if(n.scrollToLine(W,!0),p*=A,W!==v){u=0;return}if(Math.abs(p)<M){u=0;return}u=requestAnimationFrame(l)};u=requestAnimationFrame(l)}let ke=0,$="connecting",Se=0,oe=!1,Be=[],Q="",q=!1,le=1e3,Xt=location.protocol==="https:"?"wss:":"ws:",ct=s.wsBase||"/ws",Jt=Xt+"//"+location.host+ct+"/"+encodeURIComponent(t),Zt=(ct.replace(/^\/ws/,"")||"")+"/api/session/"+encodeURIComponent(t)+"/upload",Gt=/^((?!chrome|android|crios|fxios|edgios).)*safari/i.test(navigator.userAgent);function Qt(){return Be.join("")+Q}async function en(i,l=0){let d=i?n.viewportY():0,m=me(Qt());if(n.reset(),!m){i||n.scrollToBottom();return}await n.write(m),i?n.scrollToLine(l+d):n.scrollToBottom()}function V(i){a?.readyState===WebSocket.OPEN&&a.send(JSON.stringify(i))}function tn(i){let l;try{l=JSON.parse(i)}catch{$==="live"&&(Q+=i,n.write(me(i)));return}if(l.type==="auth.required"){let d=localStorage.getItem("tmux-web-token");d?V({type:"auth.token",token:d}):location.href="/login?returnTo="+encodeURIComponent(location.pathname+location.search);return}if(l.type==="attach_failed"&&typeof l.message=="string"){Te=!0,$="dead",n.reset(),n.write(`\r
4
- \x1B[31m`+me(l.message)+`\x1B[0m\r
5
- `).then(()=>{Me();try{a?.close()}catch{}});return}if(l.type==="auth.ok"){l.token&&localStorage.setItem("tmux-web-token",l.token),le=1e3,X(),V({type:"resize",cols:n.cols,rows:n.rows}),T();return}if(l.type==="auth.failed"){if(l.permanentLock||l.retryAfterMs&&l.retryAfterMs>6e4){localStorage.removeItem("tmux-web-token"),location.href="/login?error="+encodeURIComponent(l.message);return}return}if(l.type==="snapshot"&&typeof l.data=="string"){let d=Qe(me(l.data));Be=[d],Q="",Se=typeof l.lines=="number"?l.lines:s.terminal.initialLines,$="live",n.reset(),X(),V({type:"resize",cols:n.cols,rows:n.rows}),n.write(d).then(()=>n.scrollToBottom());return}if(l.type==="window_changed"&&typeof l.activeIndex=="number"){let d=new URL(location.href);d.searchParams.get("window")!==String(l.activeIndex)&&(d.searchParams.set("window",String(l.activeIndex)),history.replaceState(history.state,"",d)),window.dispatchEvent(new CustomEvent("tmux:windows",{detail:l.windows}));return}if(l.type==="history"&&typeof l.data=="string"){l.lines>0&&l.data?(Be.unshift(Qe(l.data)),Se+=l.lines,en(!0,l.lines).finally(()=>{oe=!1})):oe=!1;return}if(l.type==="data"&&typeof l.data=="string"){let d=Qe(me(l.data));if($==="connecting"){$="live",Q=d,n.write(d);return}$==="live"&&(Q+=d,n.write(d))}}let Te=!1;function dt(){if(Te)return;let i=Jt,l=localStorage.getItem("tmux-web-token");l&&(i+=(i.includes("?")?"&":"?")+"token="+encodeURIComponent(l)),i+=(i.includes("?")?"&":"?")+"cols="+n.cols+"&rows="+n.rows,a=new WebSocket(i),a.onopen=()=>{$="connecting",Se=0,oe=!1,Be=[],Q="",n.reset(),le=1e3},a.onmessage=d=>{typeof d.data=="string"&&tn(d.data)},a.onclose=()=>{q||($="connecting",!Te&&setTimeout(()=>{le=Math.min(le*2,1e4),!q&&!Te&&dt()},le))},a.onerror=()=>a?.close()}function ee(i){V({type:"input",data:i})}function X(){return n.fit()}function Me(){e.classList.remove("terminal-pending")}function T(){r&&cancelAnimationFrame(r),c&&clearTimeout(c),X(),r=requestAnimationFrame(()=>{r=0,X()&&Me()}),c=setTimeout(()=>{X()&&Me()},120)}function nn(){T(),setTimeout(T,50),setTimeout(T,150),setTimeout(T,300)}function ut(i){return typeof i=="string"&&i.startsWith("image/")}function pt(i){return i?.files?.length?i.files[0]??null:null}function sn(i){if(!i?.items)return null;for(let l=0;l<i.items.length;l++){let d=i.items[l];if(d?.kind==="file"&&ut(d.type))return d.getAsFile()}return null}async function an(i){let l=new FormData,d=i instanceof File&&i.name?i.name:"upload";l.append("file",i,d);let m=localStorage.getItem("tmux-web-token"),v={};m&&(v.Authorization="Bearer "+m);let N=await fetch(Zt,{method:"POST",body:l,headers:v});if(!N.ok){let wt="upload failed";try{let bt=await N.json();bt.error&&(wt=bt.error)}catch{}throw new Error(wt)}let W=await N.json();if(!W.path)throw new Error("no path in response");return W.path}async function Je(i){try{let l=await an(i);ee(l)}catch{}}n.onData(i=>ee(i)),n.onResize(({cols:i,rows:l})=>V({type:"resize",cols:i,rows:l})),n.onScroll(()=>{$!=="live"||oe||!n.isNearScrollbackTop()||(oe=!0,V({type:"load_history",before:Se}))});let re=!1,ce=!1,C=null,x=null,de=document.createElement("div");de.className="terminal-copy-banner",de.innerHTML='<strong>Copy mode</strong><span class="hint">drag to copy \xB7 Esc exits</span>',de.hidden=!0,e.appendChild(de);let z=document.createElement("div");z.className="terminal-copy-banner terminal-copy-toast",z.textContent="Copied",z.hidden=!0,e.appendChild(z);function mt(i,l){let d=e.querySelector(".xterm-screen, canvas"),m=(d&&d.getBoundingClientRect().width>0?d:e).getBoundingClientRect(),v=m.height>0&&n.rows>0?m.height/n.rows:18,N=m.width>0&&n.cols>0?m.width/n.cols:9;return{row:Math.max(0,Math.min(n.rows-1,Math.floor((l-m.top)/v))),col:Math.max(0,Math.min(n.cols-1,Math.floor((i-m.left)/N)))}}async function Ie(i){if(!i)return;try{if(navigator.clipboard?.writeText){await navigator.clipboard.writeText(i);return}}catch{}let l=document.createElement("textarea");l.value=i,l.style.position="fixed",l.style.opacity="0",l.style.pointerEvents="none",document.body.appendChild(l),l.focus(),l.select();try{document.execCommand("copy")}catch{}l.remove()}let ue;function De(){z.hidden=!1,ue&&clearTimeout(ue),ue=setTimeout(()=>{z.hidden=!0},1e3)}function te(i){re=i,de.hidden=!i,e.classList.toggle("terminal-copy-mode-active",i),i&&n.focus()}function ft(){te(!re)}function on(i){q||i.button!==0||ce||(re||i.shiftKey)&&(i.preventDefault(),i.stopPropagation(),ce=!0,C=mt(i.clientX,i.clientY),x=C,n.selectCells(C.col,C.row,x.col,x.row),document.addEventListener("mousemove",Ze,!0),document.addEventListener("mouseup",Ge,!0))}function Ze(i){q||!ce||!C||(i.preventDefault(),i.stopPropagation(),x=mt(i.clientX,i.clientY),n.selectCells(C.col,C.row,x.col,x.row))}function Ge(i){if(q||!ce||!C||!x)return;i.preventDefault(),i.stopPropagation(),document.removeEventListener("mousemove",Ze,!0),document.removeEventListener("mouseup",Ge,!0),ce=!1;let l=n.getCellsText(C.col,C.row,x.col,x.row);C=null,x=null,n.clearSelection(),te(!1),l&&(z.textContent="\u5DF2\u590D\u5236",Ie(l).then(De)),n.focus()}e.addEventListener("mousedown",on,!0),document.addEventListener("keydown",ln,!0);function ln(i){if(!(q||!n.isFocused()||i.defaultPrevented||i.isComposing)){if(re){if(i.key==="Escape"){i.preventDefault(),i.stopPropagation(),C=null,x=null,n.clearSelection(),te(!1);return}if(i.key==="Enter"||(i.ctrlKey||i.metaKey)&&i.code==="KeyC"){i.preventDefault(),i.stopPropagation(),Ie(n.getScreenText()).then(De),te(!1);return}}if(i.altKey&&i.code==="KeyC"&&!i.ctrlKey&&!i.metaKey){if(i.preventDefault(),i.stopPropagation(),C&&x){let l=n.getCellsText(C.col,C.row,x.col,x.row);C=null,x=null,n.clearSelection(),te(!1),l&&(z.textContent="Copied",Ie(l).then(De))}else{let l=n.getSelection();l?(n.clearSelection(),z.textContent="Copied",Ie(l).then(De)):ft()}return}if((i.ctrlKey||i.metaKey)&&i.code==="KeyV"){i.preventDefault(),i.stopPropagation(),(async()=>{try{if(navigator.clipboard?.read){let l=await navigator.clipboard.read();for(let d of l)for(let m of d.types)if(ut(m)){let v=await d.getType(m);await Je(v);return}}}catch{}try{let l=await navigator.clipboard?.readText();l&&n.pasteText(ht(l))}catch{}})();return}}}let Ae=0;function ht(i){return i.split(`\r
1
+ var bn=/\x1b\](?:10|11|110|111|104)(?:;[^\x07\x1b]*)?\x1b?(?:\\|\x07)/g;function Qe(e){return e.replace(/\x1b\[\?1049[hl]/g,"")}function fe(e){return e.replace(bn,"")}var Fe;function En(){return Fe||(document.querySelector("link[data-tmux-web-xterm-css]")?Fe=Promise.resolve():(Fe=new Promise(e=>{let t=document.createElement("link");t.rel="stylesheet",t.href="/assets/xterm.css",t.setAttribute("data-tmux-web-xterm-css",""),t.addEventListener("load",()=>e(),{once:!0}),t.addEventListener("error",()=>e(),{once:!0}),document.head.appendChild(t)}),Fe))}var Ln=class Kt{terminal;fitAddon;container;webglActive=!1;webglAddon=null;constructor(t,s,n){this.container=t,this.terminal=s,this.fitAddon=n,this.terminal.loadAddon(this.fitAddon),this.terminal.open(t),this.enableWebglRenderer()}enableWebglRenderer(){import("./addon-webgl-B45EJ6AW.js").then(({WebglAddon:t})=>{let s=new t;s.onContextLoss(()=>{this.webglActive=!1,this.webglAddon=null;try{s.dispose()}catch{}this.fit()});try{this.terminal.loadAddon(s)}catch{return}this.webglAddon=s,this.webglActive=!0,this.fit()}).catch(()=>{})}static async create(t,s,n){let[{Terminal:i},{FitAddon:r}]=await Promise.all([import("./xterm-BXEES47M.js"),import("./addon-fit-D5N335P2.js"),En()]),c=new i({fontSize:14,fontFamily:"'JetBrains Mono', 'SF Mono', 'Menlo', monospace",cursorBlink:!0,cursorStyle:"bar",scrollback:s,convertEol:!1,smoothScrollDuration:120,theme:n});return new Kt(t,c,new r)}get cols(){return this.terminal.cols}get rows(){return this.terminal.rows}write(t){return new Promise(s=>this.terminal.write(t,s))}reset(){this.terminal.reset()}scrollToBottom(){this.terminal.scrollToBottom()}scrollToLine(t,s=!1){this.terminal.scrollToLine(Math.max(0,t),s)}scrollLines(t){let s=this.terminal.buffer?.active;this.terminal.scrollLines(t)}isNearScrollbackTop(){return this.terminal.buffer.active.viewportY<=1}viewportY(){return this.terminal.buffer.active.viewportY}baseY(){return this.terminal.buffer.active.baseY}cellHeight(){let t=this.terminal.element?.querySelector(".xterm-screen")?.getBoundingClientRect().height??0,s=this.terminal.rows;return t>0&&s>0?t/s:16}fit(){let t=xn(this.container);return t.width<=0||t.height<=0?!1:(this.fitAddon.fit(),!0)}focus(){this.terminal.focus()}pasteText(t){this.terminal.paste(t)}input(t){this.terminal.input(t,!1)}onData(t){this.terminal.onData(t),this.terminal.onBinary(t)}onResize(t){this.terminal.onResize(t)}onScroll(t){this.terminal.onScroll(t)}attachCustomKeyEventHandler(t){this.terminal.attachCustomKeyEventHandler(t)}isFocused(){let t=document.activeElement;return t?t===this.container||t===this.terminal.textarea||this.container.contains(t)||!!t.closest?.(".xterm"):!1}getScreenText(){return this.getRowsText(0,this.terminal.rows-1)}getRowsText(t,s){let n=this.terminal.buffer.active,[i,r]=t<=s?[t,s]:[s,t],c=n.viewportY,o=[];for(let u=i;u<=r;u++){let p=n.getLine(c+u);o.push(p?p.translateToString(!0):"")}return o.join(`
2
+ `)}selectRows(t,s){let n=this.terminal.buffer.active,[i,r]=t<=s?[t,s]:[s,t];this.terminal.selectLines(n.viewportY+i,n.viewportY+r)}selectCells(t,s,n,i){let r=this.terminal.buffer.active,c=Math.min(s,i),o=Math.max(s,i);if(c===o){let u=Math.min(t,n),p=Math.max(t,n);this.terminal.select(u,r.viewportY+c,p-u+1)}else this.terminal.selectLines(r.viewportY+c,r.viewportY+o)}getCellsText(t,s,n,i){let r=this.terminal.buffer.active,c=Math.min(s,i),o=Math.max(s,i),u=s<i?t:s>i?n:Math.min(t,n),p=s<i?n:s>i?t:Math.max(t,n),T=r.viewportY,L=[];for(let A=c;A<=o;A++){let I=r.getLine(T+A);if(!I){L.push("");continue}let b=A===c?u:0,q=A===o?p:this.terminal.cols-1,ie="";for(let Ce=b;Ce<=q;Ce++){let K=I.getCell(Ce);K&&(ie+=K.getChars())}L.push(ie.replace(/\s+$/,""))}return L.join(`
3
+ `)}getSelection(){return this.terminal.getSelection()}clearSelection(){this.terminal.clearSelection()}hasSelectionSupport(){return!0}};function xn(e){let t=e.getBoundingClientRect(),s=window.visualViewport;return s?{width:Math.min(t.width,s.width),height:Math.max(0,Math.min(t.height,s.height-Math.max(0,t.top)))}:t}function Cn(e,t,s){return e.innerHTML="",e.classList.add("terminal-pending"),(async()=>{let n=await Ln.create(e,s.scrollback,s.theme),i,r=0,c,o=null,u=0,p=0,T=.2,L=10,A=.95,I=.04,b=null,q=null;function ie(a){b||(b=document.createElement("div"),b.style.cssText=["position:absolute","left:0","width:40%","padding:10px 0","text-align:center","font:600 14px/1.4 system-ui, -apple-system, sans-serif","color:rgba(255,255,255,0.95)","background:rgba(20,30,50,0.55)","border:1px solid rgba(255,255,255,0.25)","border-radius:10px","pointer-events:none","opacity:0","transition:opacity 0.15s ease","z-index:6"].join(";"),e.appendChild(b)),b.textContent=a?"\u2191 \u4E0A\u7FFB\u4E00\u9875 (PgUp)":"\u2193 \u4E0B\u7FFB\u4E00\u9875 (PgDn)",b.style.top=a?"10%":"auto",b.style.bottom=a?"auto":"10%",b.style.opacity="1",q&&clearTimeout(q),q=setTimeout(()=>{b&&(b.style.opacity="0")},900)}function Ce(){q&&clearTimeout(q),b&&(b.style.opacity="0")}function K(){u&&(cancelAnimationFrame(u),u=0),p=0}function Vt(a){if(K(),Math.abs(a)<T)return;p=Math.max(-L,Math.min(L,a));let l=()=>{if(_){u=0;return}let d=n.cellHeight(),f=d>0?Math.round(p*16/d):p>0?1:-1;f===0&&(f=p>0?1:-1);let g=n.viewportY()-f,N=n.baseY(),Y=Math.max(0,Math.min(g,N));if(n.scrollToLine(Y,!0),p*=A,Y!==g){u=0;return}if(Math.abs(p)<I){u=0;return}u=requestAnimationFrame(l)};u=requestAnimationFrame(l)}let ke=0,$="connecting",Se=0,oe=!1,Te=[],Q="",_=!1,le=1e3,Xt=location.protocol==="https:"?"wss:":"ws:",ct=s.wsBase||"/ws",Jt=Xt+"//"+location.host+ct+"/"+encodeURIComponent(t),Zt=(ct.replace(/^\/ws/,"")||"")+"/api/session/"+encodeURIComponent(t)+"/upload",Gt=/^((?!chrome|android|crios|fxios|edgios).)*safari/i.test(navigator.userAgent);function Qt(){return Te.join("")+Q}async function en(a,l=0){let d=a?n.viewportY():0,f=fe(Qt());if(n.reset(),!f){a||n.scrollToBottom();return}await n.write(f),a?n.scrollToLine(l+d):n.scrollToBottom()}function V(a){i?.readyState===WebSocket.OPEN&&i.send(JSON.stringify(a))}function tn(a){let l;try{l=JSON.parse(a)}catch{$==="live"&&(Q+=a,n.write(fe(a)));return}if(l.type==="auth.required"){let d=localStorage.getItem("tmux-web-token");d?V({type:"auth.token",token:d}):location.href="/login?returnTo="+encodeURIComponent(location.pathname+location.search);return}if(l.type==="attach_failed"&&typeof l.message=="string"){Be=!0,$="dead",n.reset(),n.write(`\r
4
+ \x1B[31m`+fe(l.message)+`\x1B[0m\r
5
+ `).then(()=>{Ie();try{i?.close()}catch{}});return}if(l.type==="auth.ok"){l.token&&localStorage.setItem("tmux-web-token",l.token),le=1e3,X(),V({type:"resize",cols:n.cols,rows:n.rows}),B();return}if(l.type==="auth.failed"){if(l.permanentLock||l.retryAfterMs&&l.retryAfterMs>6e4){localStorage.removeItem("tmux-web-token"),location.href="/login?error="+encodeURIComponent(l.message);return}return}if(l.type==="snapshot"&&typeof l.data=="string"){let d=Qe(fe(l.data));Te=[d],Q="",Se=typeof l.lines=="number"?l.lines:s.terminal.initialLines,$="live",n.reset(),X(),V({type:"resize",cols:n.cols,rows:n.rows}),n.write(d).then(()=>n.scrollToBottom());return}if(l.type==="window_changed"&&typeof l.activeIndex=="number"){let d=new URL(location.href);d.searchParams.get("window")!==String(l.activeIndex)&&(d.searchParams.set("window",String(l.activeIndex)),history.replaceState(history.state,"",d)),window.dispatchEvent(new CustomEvent("tmux:windows",{detail:l.windows}));return}if(l.type==="history"&&typeof l.data=="string"){l.lines>0&&l.data?(Te.unshift(Qe(l.data)),Se+=l.lines,en(!0,l.lines).finally(()=>{oe=!1})):oe=!1;return}if(l.type==="data"&&typeof l.data=="string"){let d=Qe(fe(l.data));if($==="connecting"){$="live",Q=d,n.write(d);return}$==="live"&&(Q+=d,n.write(d))}}let Be=!1;function dt(){if(Be)return;let a=Jt,l=localStorage.getItem("tmux-web-token");l&&(a+=(a.includes("?")?"&":"?")+"token="+encodeURIComponent(l)),a+=(a.includes("?")?"&":"?")+"cols="+n.cols+"&rows="+n.rows,i=new WebSocket(a),i.onopen=()=>{$="connecting",Se=0,oe=!1,Te=[],Q="",n.reset(),le=1e3},i.onmessage=d=>{typeof d.data=="string"&&tn(d.data)},i.onclose=()=>{_||($="connecting",!Be&&setTimeout(()=>{le=Math.min(le*2,1e4),!_&&!Be&&dt()},le))},i.onerror=()=>i?.close()}function ee(a){V({type:"input",data:a})}function X(){return n.fit()}function Ie(){e.classList.remove("terminal-pending")}function B(){r&&cancelAnimationFrame(r),c&&clearTimeout(c),X(),r=requestAnimationFrame(()=>{r=0,X()&&Ie()}),c=setTimeout(()=>{X()&&Ie()},120)}function nn(){B(),setTimeout(B,50),setTimeout(B,150),setTimeout(B,300)}function ut(a){return typeof a=="string"&&a.startsWith("image/")}function pt(a){return a?.files?.length?a.files[0]??null:null}function sn(a){if(!a?.items)return null;for(let l=0;l<a.items.length;l++){let d=a.items[l];if(d?.kind==="file"&&ut(d.type))return d.getAsFile()}return null}async function an(a){let l=new FormData,d=a instanceof File&&a.name?a.name:"upload";l.append("file",a,d);let f=localStorage.getItem("tmux-web-token"),g={};f&&(g.Authorization="Bearer "+f);let N=await fetch(Zt,{method:"POST",body:l,headers:g});if(!N.ok){let wt="upload failed";try{let bt=await N.json();bt.error&&(wt=bt.error)}catch{}throw new Error(wt)}let Y=await N.json();if(!Y.path)throw new Error("no path in response");return Y.path}async function Je(a){try{let l=await an(a);ee(l)}catch{}}n.onData(a=>ee(a)),n.onResize(({cols:a,rows:l})=>V({type:"resize",cols:a,rows:l})),n.onScroll(()=>{$!=="live"||oe||!n.isNearScrollbackTop()||(oe=!0,V({type:"load_history",before:Se}))});let re=!1,ce=!1,E=null,x=null,de=document.createElement("div");de.className="terminal-copy-banner",de.innerHTML='<strong>Copy mode</strong><span class="hint">drag to copy \xB7 Esc exits</span>',de.hidden=!0,e.appendChild(de);let z=document.createElement("div");z.className="terminal-copy-banner terminal-copy-toast",z.textContent="Copied",z.hidden=!0,e.appendChild(z);function ft(a,l){let d=e.querySelector(".xterm-screen, canvas"),f=(d&&d.getBoundingClientRect().width>0?d:e).getBoundingClientRect(),g=f.height>0&&n.rows>0?f.height/n.rows:18,N=f.width>0&&n.cols>0?f.width/n.cols:9;return{row:Math.max(0,Math.min(n.rows-1,Math.floor((l-f.top)/g))),col:Math.max(0,Math.min(n.cols-1,Math.floor((a-f.left)/N)))}}async function Me(a){if(!a)return;try{if(navigator.clipboard?.writeText){await navigator.clipboard.writeText(a);return}}catch{}let l=document.createElement("textarea");l.value=a,l.style.position="fixed",l.style.opacity="0",l.style.pointerEvents="none",document.body.appendChild(l),l.focus(),l.select();try{document.execCommand("copy")}catch{}l.remove()}let ue;function De(){z.hidden=!1,ue&&clearTimeout(ue),ue=setTimeout(()=>{z.hidden=!0},1e3)}function te(a){re=a,de.hidden=!a,e.classList.toggle("terminal-copy-mode-active",a),a&&n.focus()}function mt(){te(!re)}function on(a){_||a.button!==0||ce||(re||a.shiftKey)&&(a.preventDefault(),a.stopPropagation(),ce=!0,E=ft(a.clientX,a.clientY),x=E,n.selectCells(E.col,E.row,x.col,x.row),document.addEventListener("mousemove",Ze,!0),document.addEventListener("mouseup",Ge,!0))}function Ze(a){_||!ce||!E||(a.preventDefault(),a.stopPropagation(),x=ft(a.clientX,a.clientY),n.selectCells(E.col,E.row,x.col,x.row))}function Ge(a){if(_||!ce||!E||!x)return;a.preventDefault(),a.stopPropagation(),document.removeEventListener("mousemove",Ze,!0),document.removeEventListener("mouseup",Ge,!0),ce=!1;let l=n.getCellsText(E.col,E.row,x.col,x.row);E=null,x=null,n.clearSelection(),te(!1),l&&(z.textContent="\u5DF2\u590D\u5236",Me(l).then(De)),n.focus()}e.addEventListener("mousedown",on,!0),document.addEventListener("keydown",ln,!0);function ln(a){if(!(_||!n.isFocused()||a.defaultPrevented||a.isComposing)){if(re){if(a.key==="Escape"){a.preventDefault(),a.stopPropagation(),E=null,x=null,n.clearSelection(),te(!1);return}if(a.key==="Enter"||(a.ctrlKey||a.metaKey)&&a.code==="KeyC"){a.preventDefault(),a.stopPropagation(),Me(n.getScreenText()).then(De),te(!1);return}}if(a.altKey&&a.code==="KeyC"&&!a.ctrlKey&&!a.metaKey){if(a.preventDefault(),a.stopPropagation(),E&&x){let l=n.getCellsText(E.col,E.row,x.col,x.row);E=null,x=null,n.clearSelection(),te(!1),l&&(z.textContent="Copied",Me(l).then(De))}else{let l=n.getSelection();l?(n.clearSelection(),z.textContent="Copied",Me(l).then(De)):mt()}return}if((a.ctrlKey||a.metaKey)&&a.code==="KeyV"){a.preventDefault(),a.stopPropagation(),(async()=>{try{if(navigator.clipboard?.read){let l=await navigator.clipboard.read();for(let d of l)for(let f of d.types)if(ut(f)){let g=await d.getType(f);await Je(g);return}}}catch{}try{let l=await navigator.clipboard?.readText();l&&n.pasteText(ht(l))}catch{}})();return}}}let Ae=0;function ht(a){return a.split(`\r
6
6
  `).join(`
7
7
  `).split(`
8
- `).join("\r")}async function rn(i){let l=sn(i.clipboardData);if(l){i.preventDefault(),i.stopPropagation();let v=Date.now();if(v-Ae<50)return;Ae=v,await Je(l);return}let d=i.clipboardData?.getData("text/plain");if(!d)return;i.preventDefault(),i.stopPropagation();let m=Date.now();m-Ae<50||(Ae=m,n.pasteText(ht(d)))}let pe=0;function cn(i){i.preventDefault(),pe++,pt(i.dataTransfer)&&e.classList.add("terminal-drag-over")}function dn(i){i.preventDefault(),i.dataTransfer&&(i.dataTransfer.dropEffect="copy")}function un(i){i.preventDefault(),pe--,pe<=0&&(pe=0,e.classList.remove("terminal-drag-over"))}async function pn(i){i.preventDefault(),pe=0,e.classList.remove("terminal-drag-over");let l=pt(i.dataTransfer);l&&await Je(l)}function vt(i){!Gt||i.key!=="Escape"||re||i.defaultPrevented||i.repeat||i.metaKey||i.ctrlKey||i.altKey||n.isFocused()&&(i.preventDefault(),i.stopPropagation(),ee("\x1B"))}e.addEventListener("paste",rn),e.addEventListener("dragenter",cn),e.addEventListener("dragover",dn),e.addEventListener("dragleave",un),e.addEventListener("drop",pn),document.addEventListener("keydown",vt,!0);function mn(i){if(i.touches.length!==1){o=null;return}let l=i.touches[0];if(!l)return;K();let d=e.getBoundingClientRect(),m=l.clientX-d.left<d.width*.4?"tui":"history",v=l.clientY-d.top<d.height*.5;o={startX:l.clientX,startY:l.clientY,lastX:l.clientX,lastY:l.clientY,lastT:performance.now(),velocity:0,scrolling:!1,zone:m,tuiUp:v,sent:!1},i.stopPropagation()}function fn(i){if(!o||i.touches.length!==1)return;let l=i.touches[0];if(!l)return;let d=l.clientY-o.startY,m=l.clientX-o.startX;if(!o.scrolling){if(Math.abs(d)<8||Math.abs(d)<Math.abs(m))return;o.scrolling=!0,ke=Date.now()+500}i.preventDefault(),i.stopPropagation();let v=performance.now(),N=l.clientY-o.lastY;if(o.zone==="tui"){o.sent||(o.sent=!0,ee(o.tuiUp?"\x1B[5~":"\x1B[6~"),ae(o.tuiUp)),o.lastX=l.clientX,o.lastY=l.clientY,o.lastT=v;return}let W=v-o.lastT;W>0&&(o.velocity=N/W),yn(-N),o.lastX=l.clientX,o.lastY=l.clientY,o.lastT=v}function hn(i){if(!o)return;let l=o.scrolling,d=o.zone,m=o.tuiUp,v=o.velocity;if(o=null,i.stopPropagation(),d==="tui"){l||(ee(m?"\x1B[5~":"\x1B[6~"),ae(m),ke=Date.now()+500,i.preventDefault());return}if(!l){n.focus();return}ke=Date.now()+500,i.preventDefault(),v&&Vt(v)}function vn(i){o=null,K(),i.stopPropagation()}function gn(i){i.pointerType==="touch"&&Date.now()<ke&&(i.preventDefault(),i.stopPropagation())}function yn(i){let l=n.cellHeight(),d=l>0?Math.round(i/l):i>0?1:-1;d===0&&(d=i>0?1:-1),n.scrollLines(d)}e.addEventListener("touchstart",mn,{passive:!0,capture:!0}),e.addEventListener("touchmove",fn,{passive:!1,capture:!0}),e.addEventListener("touchend",hn,{passive:!1,capture:!0}),e.addEventListener("touchcancel",vn,{passive:!0,capture:!0}),e.addEventListener("pointerup",gn,!0);function gt(){T()}window.addEventListener("resize",gt),window.visualViewport?.addEventListener("resize",T),window.visualViewport?.addEventListener("scroll",T);let yt=new ResizeObserver(()=>T());yt.observe(e),document.fonts?.ready.then(()=>{T(),setTimeout(T,50),setTimeout(T,200)}),e.addEventListener("focusin",nn,!0);async function wn(){if(document.fonts?.ready)try{await Promise.race([document.fonts.ready,new Promise(i=>setTimeout(i,1e3))])}catch{}}return requestAnimationFrame(()=>{X()&&Me(),(async()=>(await wn(),X()&&V({type:"resize",cols:n.cols,rows:n.rows}),dt(),T()))()}),{destroy(){if(q=!0,K(),te(!1),ue&&clearTimeout(ue),document.removeEventListener("mousemove",Ze,!0),document.removeEventListener("mouseup",Ge,!0),a){try{a.close(1e3,"session switch")}catch{}a=void 0}e.innerHTML="",e.classList.remove("terminal-pending"),window.removeEventListener("resize",gt),yt.disconnect(),document.removeEventListener("keydown",vt,!0)},focus(){n.focus()},sendInput(i){ee(i)},toggleCopyMode(){ft()}}})()}var fe=window.__TMUX_WEB_SHELL__,g=null,y=null,he=typeof window.__TMUX_WEB_SCOPE__?.agentId=="string"?window.__TMUX_WEB_SCOPE__.agentId:null,k=he;window.__tmuxWebScopeAgent=he;var et="sessions",_="",He="",Re="",Lt="";function S(e){return k?"/a/"+encodeURIComponent(k)+e:e}var f=document.getElementById("sidebar-content"),J=document.getElementById("main-placeholder"),I=document.getElementById("terminal-container"),ve=document.getElementById("file-editor"),kn=document.getElementById("fe-path"),F=document.getElementById("fe-status"),ge=document.getElementById("fe-content"),Z=document.getElementById("fe-save"),Sn=document.getElementById("fe-delete"),Bn=document.getElementById("fe-back"),Et=document.getElementById("fe-new-name"),Tn=document.getElementById("fe-new-btn"),tt=document.getElementById("settings-backdrop"),Ct=document.getElementById("settings-popover"),xt=document.querySelector(".sidebar"),kt="tmux-web-force-narrow";function Ne(){try{return localStorage.getItem(kt)==="1"}catch{return!1}}function St(){document.documentElement.classList.toggle("force-narrow",Ne()),Ne()&&Bt()&&Pe()}function Bt(){return Ne()?!0:window.matchMedia("(max-width: 640px)").matches}function Pe(){Bt()&&xt.classList.add("collapsed")}function Tt(){xt.classList.remove("collapsed")}document.getElementById("mode-sessions").addEventListener("click",()=>{Tt(),Mt("sessions")}),document.getElementById("mode-files").addEventListener("click",()=>{Tt(),Mt("files")});function Mt(e){et=e,document.querySelectorAll(".mode-btn").forEach(s=>s.classList.remove("active"));let t=document.getElementById(e==="sessions"?"mode-sessions":"mode-files");t&&t.classList.add("active"),e==="sessions"?(nt="",j()):qn()}var nt="";async function j(){if(et!=="sessions")return;try{let t=await(await fetch("/api/sidebar/sessions")).json(),s=JSON.stringify({recent:t.recent,agents:t.agents,tombstones:t.tombstones});if(s===nt)return;nt=s,Fn(t)}catch{f.innerHTML+='<div class="file-tree-empty">Failed to load sessions</div>'}let e=document.getElementById("ns-btn");e&&e.addEventListener("click",()=>{let t=window.__openNewSessionModal;typeof t=="function"?t():document.getElementById("new-session-modal")?.classList.add("open")}),rt()}var It="tmux-web-sidebar-group-collapsed";function Dt(){try{return new Set(JSON.parse(localStorage.getItem(It)||"[]"))}catch{return new Set}}function Mn(e){try{localStorage.setItem(It,JSON.stringify([...e]))}catch{}}function In(e,t,s){if(!e)return"\u2026";let n=s&&(e===s||e.startsWith(s+"/"))?"~"+e.slice(s.length):e,a=n.split("/").filter(Boolean);if(a.length===0)return e;for(let r=1;r<=a.length;r++){let c=a.slice(-r).join("/");if(!t.some(o=>!o||o===e?!1:(s&&(o===s||o.startsWith(s+"/"))?"~"+o.slice(s.length):o).split("/").filter(Boolean).slice(-r).join("/")===c))return c}return n}function At(e,t,s,n=!0){let a=new Map;for(let o of e){let u=o.path||"";a.has(u)||a.set(u,[]),a.get(u).push(o)}let r=[...a.keys()],c=Dt();for(let[o,u]of a){let p=In(o,r,t),E=c.has(o),b=document.createElement("div");b.className="session-group-header"+(E?" collapsed":""),b.title=o||"No working directory",b.innerHTML=`<span class="sg-folder">&#128193;</span><span class="sg-label">${h(p)}</span>`,b.addEventListener("click",()=>{let M=Dt(),L=b.nextElementSibling;M.has(o)?(M.delete(o),b.classList.remove("collapsed"),L?.classList.remove("collapsed")):(M.add(o),b.classList.add("collapsed"),L?.classList.add("collapsed")),Mn(M)});let A=document.createElement("div");A.className="session-group-body"+(E?" collapsed":"");for(let M of u)A.appendChild(s?Dn(M,s,n):An(M));f.appendChild(b),f.appendChild(A)}}function Dn(e,t,s){let n=document.createElement("div");n.className="session-item"+(e.name===y&&k===t?" active":"")+(s?"":" session-offline"),n.setAttribute("data-session",e.name),n.setAttribute("data-agent",t),n.innerHTML=`<svg viewBox="0 0 24 24" fill="currentColor"><path d="${e.attached?"M19 4H5a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V6a2 2 0 0 0-2-2zm0 14H5V6h14v12z":"M4 6h16v2H4V6zm0 5h16v2H4v-2zm0 5h16v2H4v-2z"}"></svg>
8
+ `).join("\r")}async function rn(a){let l=sn(a.clipboardData);if(l){a.preventDefault(),a.stopPropagation();let g=Date.now();if(g-Ae<50)return;Ae=g,await Je(l);return}let d=a.clipboardData?.getData("text/plain");if(!d)return;a.preventDefault(),a.stopPropagation();let f=Date.now();f-Ae<50||(Ae=f,n.pasteText(ht(d)))}let pe=0;function cn(a){a.preventDefault(),pe++,pt(a.dataTransfer)&&e.classList.add("terminal-drag-over")}function dn(a){a.preventDefault(),a.dataTransfer&&(a.dataTransfer.dropEffect="copy")}function un(a){a.preventDefault(),pe--,pe<=0&&(pe=0,e.classList.remove("terminal-drag-over"))}async function pn(a){a.preventDefault(),pe=0,e.classList.remove("terminal-drag-over");let l=pt(a.dataTransfer);l&&await Je(l)}function gt(a){!Gt||a.key!=="Escape"||re||a.defaultPrevented||a.repeat||a.metaKey||a.ctrlKey||a.altKey||n.isFocused()&&(a.preventDefault(),a.stopPropagation(),ee("\x1B"))}e.addEventListener("paste",rn),e.addEventListener("dragenter",cn),e.addEventListener("dragover",dn),e.addEventListener("dragleave",un),e.addEventListener("drop",pn),document.addEventListener("keydown",gt,!0);function fn(a){if(a.touches.length!==1){o=null;return}let l=a.touches[0];if(!l)return;K();let d=e.getBoundingClientRect(),f=l.clientX-d.left<d.width*.4?"tui":"history",g=l.clientY-d.top<d.height*.5;o={startX:l.clientX,startY:l.clientY,lastX:l.clientX,lastY:l.clientY,lastT:performance.now(),velocity:0,scrolling:!1,zone:f,tuiUp:g,sent:!1},a.stopPropagation()}function mn(a){if(!o||a.touches.length!==1)return;let l=a.touches[0];if(!l)return;let d=l.clientY-o.startY,f=l.clientX-o.startX;if(!o.scrolling){if(Math.abs(d)<8||Math.abs(d)<Math.abs(f))return;o.scrolling=!0,ke=Date.now()+500}a.preventDefault(),a.stopPropagation();let g=performance.now(),N=l.clientY-o.lastY;if(o.zone==="tui"){o.sent||(o.sent=!0,ee(o.tuiUp?"\x1B[5~":"\x1B[6~"),ie(o.tuiUp)),o.lastX=l.clientX,o.lastY=l.clientY,o.lastT=g;return}let Y=g-o.lastT;Y>0&&(o.velocity=N/Y),yn(-N),o.lastX=l.clientX,o.lastY=l.clientY,o.lastT=g}function hn(a){if(!o)return;let l=o.scrolling,d=o.zone,f=o.tuiUp,g=o.velocity;if(o=null,a.stopPropagation(),d==="tui"){l||(ee(f?"\x1B[5~":"\x1B[6~"),ie(f),ke=Date.now()+500,a.preventDefault());return}if(!l){n.focus();return}ke=Date.now()+500,a.preventDefault(),g&&Vt(g)}function gn(a){o=null,K(),a.stopPropagation()}function vn(a){a.pointerType==="touch"&&Date.now()<ke&&(a.preventDefault(),a.stopPropagation())}function yn(a){let l=n.cellHeight(),d=l>0?Math.round(a/l):a>0?1:-1;d===0&&(d=a>0?1:-1),n.scrollLines(d)}e.addEventListener("touchstart",fn,{passive:!0,capture:!0}),e.addEventListener("touchmove",mn,{passive:!1,capture:!0}),e.addEventListener("touchend",hn,{passive:!1,capture:!0}),e.addEventListener("touchcancel",gn,{passive:!0,capture:!0}),e.addEventListener("pointerup",vn,!0);function vt(){B()}window.addEventListener("resize",vt),window.visualViewport?.addEventListener("resize",B),window.visualViewport?.addEventListener("scroll",B);let yt=new ResizeObserver(()=>B());yt.observe(e),document.fonts?.ready.then(()=>{B(),setTimeout(B,50),setTimeout(B,200)}),e.addEventListener("focusin",nn,!0);async function wn(){if(document.fonts?.ready)try{await Promise.race([document.fonts.ready,new Promise(a=>setTimeout(a,1e3))])}catch{}}return requestAnimationFrame(()=>{X()&&Ie(),(async()=>(await wn(),X()&&V({type:"resize",cols:n.cols,rows:n.rows}),dt(),B()))()}),{destroy(){if(_=!0,K(),te(!1),ue&&clearTimeout(ue),document.removeEventListener("mousemove",Ze,!0),document.removeEventListener("mouseup",Ge,!0),i){try{i.close(1e3,"session switch")}catch{}i=void 0}e.innerHTML="",e.classList.remove("terminal-pending"),window.removeEventListener("resize",vt),yt.disconnect(),document.removeEventListener("keydown",gt,!0)},focus(){n.focus()},sendInput(a){ee(a)},toggleCopyMode(){mt()}}})()}var me=window.__TMUX_WEB_SHELL__,v=null,y=null,he=typeof window.__TMUX_WEB_SCOPE__?.agentId=="string"?window.__TMUX_WEB_SCOPE__.agentId:null,C=he;window.__tmuxWebScopeAgent=he;var et="sessions",W="",He="",Re="",Et="";function k(e){return C?"/a/"+encodeURIComponent(C)+e:e}var m=document.getElementById("sidebar-content"),J=document.getElementById("main-placeholder"),M=document.getElementById("terminal-container"),ge=document.getElementById("file-editor"),kn=document.getElementById("fe-path"),F=document.getElementById("fe-status"),ve=document.getElementById("fe-content"),Z=document.getElementById("fe-save"),Sn=document.getElementById("fe-delete"),Tn=document.getElementById("fe-back"),Lt=document.getElementById("fe-new-name"),Bn=document.getElementById("fe-new-btn"),tt=document.getElementById("settings-backdrop"),xt=document.getElementById("settings-popover"),Ct=document.querySelector(".sidebar"),kt="tmux-web-force-narrow";function Ne(){try{return localStorage.getItem(kt)==="1"}catch{return!1}}function St(){document.documentElement.classList.toggle("force-narrow",Ne()),Ne()&&Tt()&&Pe()}function Tt(){return Ne()?!0:window.matchMedia("(max-width: 640px)").matches}function Pe(){Tt()&&Ct.classList.add("collapsed")}function Bt(){Ct.classList.remove("collapsed")}document.getElementById("mode-sessions").addEventListener("click",()=>{Bt(),It("sessions")}),document.getElementById("mode-files").addEventListener("click",()=>{Bt(),It("files")});function It(e){et=e,document.querySelectorAll(".mode-btn").forEach(s=>s.classList.remove("active"));let t=document.getElementById(e==="sessions"?"mode-sessions":"mode-files");t&&t.classList.add("active"),e==="sessions"?(nt="",j()):_n()}var nt="";async function j(){if(et!=="sessions")return;try{let t=await(await fetch("/api/sidebar/sessions")).json(),s=JSON.stringify({recent:t.recent,agents:t.agents,tombstones:t.tombstones});if(s===nt)return;nt=s,Fn(t)}catch{m.innerHTML+='<div class="file-tree-empty">Failed to load sessions</div>'}let e=document.getElementById("ns-btn");e&&e.addEventListener("click",()=>{let t=window.__openNewSessionModal;typeof t=="function"?t():document.getElementById("new-session-modal")?.classList.add("open")}),rt()}var Mt="tmux-web-sidebar-group-collapsed";function Dt(){try{return new Set(JSON.parse(localStorage.getItem(Mt)||"[]"))}catch{return new Set}}function In(e){try{localStorage.setItem(Mt,JSON.stringify([...e]))}catch{}}function Mn(e,t,s){if(!e)return"\u2026";let n=s&&(e===s||e.startsWith(s+"/"))?"~"+e.slice(s.length):e,i=n.split("/").filter(Boolean);if(i.length===0)return e;for(let r=1;r<=i.length;r++){let c=i.slice(-r).join("/");if(!t.some(o=>!o||o===e?!1:(s&&(o===s||o.startsWith(s+"/"))?"~"+o.slice(s.length):o).split("/").filter(Boolean).slice(-r).join("/")===c))return c}return n}function At(e,t,s,n=!0){let i=new Map;for(let o of e){let u=o.path||"";i.has(u)||i.set(u,[]),i.get(u).push(o)}let r=[...i.keys()],c=Dt();for(let[o,u]of i){let p=Mn(o,r,t),T=c.has(o),L=document.createElement("div");L.className="session-group-header"+(T?" collapsed":""),L.title=o||"No working directory",L.innerHTML=`<span class="sg-folder">&#128193;</span><span class="sg-label">${h(p)}</span>`,L.addEventListener("click",()=>{let I=Dt(),b=L.nextElementSibling;I.has(o)?(I.delete(o),L.classList.remove("collapsed"),b?.classList.remove("collapsed")):(I.add(o),L.classList.add("collapsed"),b?.classList.add("collapsed")),In(I)});let A=document.createElement("div");A.className="session-group-body"+(T?" collapsed":"");for(let I of u)A.appendChild(s?Dn(I,s,n):An(I));m.appendChild(L),m.appendChild(A)}}function Dn(e,t,s){let n=document.createElement("div");n.className="session-item"+(e.name===y&&C===t?" active":"")+(s?"":" session-offline"),n.setAttribute("data-session",e.name),n.setAttribute("data-agent",t),n.innerHTML=`<svg viewBox="0 0 24 24" fill="currentColor"><path d="${e.attached?"M19 4H5a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V6a2 2 0 0 0-2-2zm0 14H5V6h14v12z":"M4 6h16v2H4V6zm0 5h16v2H4v-2zm0 5h16v2H4v-2z"}"></svg>
9
9
  <span>${h(e.name)}</span>${s?"":'<span class="meta">offline</span>'}
10
- <button class="session-edit-btn" data-session="${h(e.name)}" title="Edit session"><svg viewBox="0 0 24 24" fill="currentColor" width="14" height="14"><path d="M3 17.25V21h3.75L17.81 9.94l-3.75-3.75L3 17.25zM20.71 7.04a1 1 0 000-1.41l-2.34-2.34a1 1 0 00-1.41 0l-1.83 1.83 3.75 3.75 1.83-1.83z"/></svg></button>`,s&&n.addEventListener("click",r=>{r.target.closest(".session-edit-btn")||ye(e.name,t)});let a=n.querySelector(".session-edit-btn");return a&&a.addEventListener("click",r=>{r.stopPropagation(),Ke(e.name,a,{agentId:t})}),n}function An(e){let t=document.createElement("div");t.className="session-item"+(e.name===y&&!k?" active":""),t.setAttribute("data-session",e.name),t.innerHTML=`<svg viewBox="0 0 24 24" fill="currentColor"><path d="${e.attached?"M19 4H5a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V6a2 2 0 0 0-2-2zm0 14H5V6h14v12z":"M4 6h16v2H4V6zm0 5h16v2H4v-2zm0 5h16v2H4v-2z"}"></svg>
10
+ <button class="session-edit-btn" data-session="${h(e.name)}" title="Edit session"><svg viewBox="0 0 24 24" fill="currentColor" width="14" height="14"><path d="M3 17.25V21h3.75L17.81 9.94l-3.75-3.75L3 17.25zM20.71 7.04a1 1 0 000-1.41l-2.34-2.34a1 1 0 00-1.41 0l-1.83 1.83 3.75 3.75 1.83-1.83z"/></svg></button>`,s&&n.addEventListener("click",r=>{r.target.closest(".session-edit-btn")||ye(e.name,t)});let i=n.querySelector(".session-edit-btn");return i&&i.addEventListener("click",r=>{r.stopPropagation(),Ke(e.name,i,{agentId:t})}),n}function An(e){let t=document.createElement("div");t.className="session-item"+(e.name===y&&!C?" active":""),t.setAttribute("data-session",e.name),t.innerHTML=`<svg viewBox="0 0 24 24" fill="currentColor"><path d="${e.attached?"M19 4H5a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V6a2 2 0 0 0-2-2zm0 14H5V6h14v12z":"M4 6h16v2H4V6zm0 5h16v2H4v-2zm0 5h16v2H4v-2z"}"></svg>
11
11
  <span>${h(e.name)}</span>
12
12
  <button class="session-edit-btn" data-session="${h(e.name)}" title="Edit session"><svg viewBox="0 0 24 24" fill="currentColor" width="14" height="14"><path d="M3 17.25V21h3.75L17.81 9.94l-3.75-3.75L3 17.25zM20.71 7.04a1 1 0 000-1.41l-2.34-2.34a1 1 0 00-1.41 0l-1.83 1.83 3.75 3.75 1.83-1.83z"/></svg></button>
13
- `,t.addEventListener("click",n=>{n.target.closest(".session-edit-btn")||ye(e.name)});let s=t.querySelector(".session-edit-btn");return s&&s.addEventListener("click",n=>{n.stopPropagation(),Ke(e.name,s)}),t}function Fn(e){f.innerHTML='<button class="new-session-sidebar-btn" id="ns-btn">+ New Session</button>';let t=e.recent||[],s=document.createElement("div");s.className="sidebar-section-label"+(he?" clickable":""),s.textContent=he?"\u2190 \u8FD4\u56DE\u672C\u673A":"\u672C\u673A",he&&(s.title="Back to hub",s.addEventListener("click",()=>{window.location.href="/"})),f.appendChild(s),At(t,e.home);let n=e.agents||[];for(let r of n){if(!r.sessions||r.sessions.length===0)continue;let c=r.agentId===k,o=document.createElement("div");o.className="sidebar-section-label machine-label"+(r.online?"":" agent-offline-label")+(!c&&r.online?" clickable":""),o.textContent=r.agentName+(r.online?"":" (offline)"),!c&&r.online&&(o.title="\u6253\u5F00 "+r.agentName,o.addEventListener("click",()=>{window.location.href="/a/"+encodeURIComponent(r.agentId)+"/"})),f.appendChild(o),At(r.sessions,e.home,r.agentId,r.online)}let a=e.tombstones||[];if(a.length>0){let r=document.createElement("div");r.className="sidebar-section-label tombstone-label",r.textContent="\u5931\u6548\u4F1A\u8BDD",f.appendChild(r);for(let c of a){let o=document.createElement("div");o.className="session-item session-tombstone",o.setAttribute("data-session",c.name),c.agentId&&o.setAttribute("data-agent",c.agentId);let u=c.agentId?c.agentOnline?" (agent)":" (agent \u79BB\u7EBF)":"";o.innerHTML=`<svg viewBox="0 0 24 24" fill="currentColor"><path d="M4 6h16v2H4V6zm0 5h16v2H4v-2zm0 5h16v2H4v-2z"></svg>
13
+ `,t.addEventListener("click",n=>{n.target.closest(".session-edit-btn")||ye(e.name)});let s=t.querySelector(".session-edit-btn");return s&&s.addEventListener("click",n=>{n.stopPropagation(),Ke(e.name,s)}),t}function Fn(e){m.innerHTML='<button class="new-session-sidebar-btn" id="ns-btn">+ New Session</button>';let t=e.recent||[],s=document.createElement("div");s.className="sidebar-section-label"+(he?" clickable":""),s.textContent=he?"\u2190 \u8FD4\u56DE\u672C\u673A":"\u672C\u673A",he&&(s.title="Back to hub",s.addEventListener("click",()=>{window.location.href="/"})),m.appendChild(s),At(t,e.home);let n=e.agents||[];for(let r of n){if(!r.sessions||r.sessions.length===0)continue;let c=r.agentId===C,o=document.createElement("div");o.className="sidebar-section-label machine-label"+(r.online?"":" agent-offline-label")+(!c&&r.online?" clickable":""),o.textContent=r.agentName+(r.online?"":" (offline)"),!c&&r.online&&(o.title="\u6253\u5F00 "+r.agentName,o.addEventListener("click",()=>{window.location.href="/a/"+encodeURIComponent(r.agentId)+"/"})),m.appendChild(o),At(r.sessions,e.home,r.agentId,r.online)}let i=e.tombstones||[];if(i.length>0){let r=document.createElement("div");r.className="sidebar-section-label tombstone-label",r.textContent="\u5931\u6548\u4F1A\u8BDD",m.appendChild(r);for(let c of i){let o=document.createElement("div");o.className="session-item session-tombstone",o.setAttribute("data-session",c.name),c.agentId&&o.setAttribute("data-agent",c.agentId);let u=c.agentId?c.agentOnline?" (agent)":" (agent \u79BB\u7EBF)":"";o.innerHTML=`<svg viewBox="0 0 24 24" fill="currentColor"><path d="M4 6h16v2H4V6zm0 5h16v2H4v-2zm0 5h16v2H4v-2z"></svg>
14
14
  <span>${h(c.name)}</span><span class="meta">\u5931\u6548${u}</span>
15
- <button class="session-edit-btn" data-session="${h(c.name)}" title="\u6062\u590D\u4F1A\u8BDD"><svg viewBox="0 0 24 24" fill="currentColor" width="14" height="14"><path d="M3 17.25V21h3.75L17.81 9.94l-3.75-3.75L3 17.25zM20.71 7.04a1 1 0 000-1.41l-2.34-2.34a1 1 0 00-1.41 0l-1.83 1.83 3.75 3.75 1.83-1.83z"/></svg></button>`,o.title="\u5931\u6548\u4F1A\u8BDD\uFF1A\u70B9\u51FB\u7BA1\u7406\uFF08\u91CD\u5EFA/\u91CD\u547D\u540D/\u5220\u9664\uFF09",o.addEventListener("click",()=>{Ke(c.name,o,{tombstone:!0,agentId:c.agentId})});let p=o.querySelector(".session-edit-btn");p&&p.addEventListener("click",E=>{E.stopPropagation(),Ke(c.name,p,{tombstone:!0,agentId:c.agentId})}),f.appendChild(o)}}}function h(e){return e.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;")}async function ye(e,t){if(y===e&&g&&k===(t||null))return;ve.style.display="none",J.style.display="none",I.style.display="",I.classList.add("terminal-pending"),Pe(),g&&(Ye(),g.destroy(),g=null),y=e,k=t||null,window.__tmuxWebScopeAgent=k,window.__tmuxWebCurrentSession=y,ts(e,t);let s=lt(e,t);Yt.set(s,Date.now()+Qn);let n=ie.get(s);if(n&&n.state==="working"){n.state="idle",n.doneUntil=void 0,n.unread=!1;let a=f.querySelector(t?'.session-item[data-agent="'+CSS.escape(t)+'"][data-session="'+CSS.escape(e)+'"]':'.session-item[data-session="'+CSS.escape(e)+'"]:not([data-agent])');a&&Xe(a,s,n)}for(let a of f.querySelectorAll(".session-item"))a.classList.toggle("active",a.getAttribute("data-session")===e&&(a.getAttribute("data-agent")||null)===k);try{g=await xn(I,e,{terminal:fe.terminal,scrollback:fe.scrollback,theme:fe.theme,wsBase:k?"/ws/a/"+encodeURIComponent(k):fe.wsBase||"/ws"}),qt()}catch(a){console.error("[shell] terminal init failed:",a);let r=a&&typeof a=="object"&&"message"in a?a.message:String(a);I.textContent="Failed to open terminal for "+e+": "+r,I.classList.remove("terminal-pending")}}var $e=[],w=null,Ft=!1;function Hn(e){if(!w||!w.files.length)return null;let t=w.repoRoot;if(!t||!e.startsWith(t))return null;let s=e.slice(t.length+1);for(let n of w.files)if(n.path===s)return n.status;return null}async function Rn(e){Ft=!0;try{let t=await fetch(S("/api/git/status?path="+encodeURIComponent(e)));t.ok?w=await t.json():w=null}catch{w=null}finally{Ft=!1}}function Nn(){if(!w||!w.branch)return"";let{branch:e,linesAdded:t,linesRemoved:s}=w,n=`<div class="sidebar-git"><div class="git-branch-badge">
15
+ <button class="session-edit-btn" data-session="${h(c.name)}" title="\u6062\u590D\u4F1A\u8BDD"><svg viewBox="0 0 24 24" fill="currentColor" width="14" height="14"><path d="M3 17.25V21h3.75L17.81 9.94l-3.75-3.75L3 17.25zM20.71 7.04a1 1 0 000-1.41l-2.34-2.34a1 1 0 00-1.41 0l-1.83 1.83 3.75 3.75 1.83-1.83z"/></svg></button>`,o.title="\u5931\u6548\u4F1A\u8BDD\uFF1A\u70B9\u51FB\u7BA1\u7406\uFF08\u91CD\u5EFA/\u91CD\u547D\u540D/\u5220\u9664\uFF09",o.addEventListener("click",()=>{Ke(c.name,o,{tombstone:!0,agentId:c.agentId})});let p=o.querySelector(".session-edit-btn");p&&p.addEventListener("click",T=>{T.stopPropagation(),Ke(c.name,p,{tombstone:!0,agentId:c.agentId})}),m.appendChild(o)}}}function h(e){return e.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;")}async function ye(e,t){if(y===e&&v&&C===(t||null))return;ge.style.display="none",J.style.display="none",M.style.display="",M.classList.add("terminal-pending"),Pe(),v&&(Oe(),v.destroy(),v=null),y=e,C=t||null,window.__tmuxWebScopeAgent=C,window.__tmuxWebCurrentSession=y,ts(e,t);let s=lt(e,t);Ot.set(s,Date.now()+Qn);let n=ae.get(s);if(n&&n.state==="working"){n.state="idle",n.doneUntil=void 0,n.unread=!1;let i=m.querySelector(t?'.session-item[data-agent="'+CSS.escape(t)+'"][data-session="'+CSS.escape(e)+'"]':'.session-item[data-session="'+CSS.escape(e)+'"]:not([data-agent])');i&&Xe(i,s,n)}for(let i of m.querySelectorAll(".session-item"))i.classList.toggle("active",i.getAttribute("data-session")===e&&(i.getAttribute("data-agent")||null)===C);try{v=await Cn(M,e,{terminal:me.terminal,scrollback:me.scrollback,theme:me.theme,wsBase:C?"/ws/a/"+encodeURIComponent(C):me.wsBase||"/ws"}),_t()}catch(i){console.error("[shell] terminal init failed:",i);let r=i&&typeof i=="object"&&"message"in i?i.message:String(i);M.textContent="Failed to open terminal for "+e+": "+r,M.classList.remove("terminal-pending")}}var $e=[],w=null,Ft=!1;function Hn(e){if(!w||!w.files.length)return null;let t=w.repoRoot;if(!t||!e.startsWith(t))return null;let s=e.slice(t.length+1);for(let n of w.files)if(n.path===s)return n.status;return null}async function Rn(e){Ft=!0;try{let t=await fetch(k("/api/git/status?path="+encodeURIComponent(e)));t.ok?w=await t.json():w=null}catch{w=null}finally{Ft=!1}}function Nn(){if(!w||!w.branch)return"";let{branch:e,linesAdded:t,linesRemoved:s}=w,n=`<div class="sidebar-git"><div class="git-branch-badge">
16
16
  <svg viewBox="0 0 16 16" fill="currentColor"><path d="M11.63 1.22a.75.75 0 00-1.06 0L5.99 5.8 4.12 3.93a.75.75 0 10-1.06 1.06L4.93 6.87A3.5 3.5 0 003 10.09v3.16a.75.75 0 001 0v-3.16a2.5 2.5 0 012.5-2.5h.27l-1.06 1.06a.75.75 0 001.06 1.06l2.37-2.38a.75.75 0 000-1.06L7.59 5.27l4.04-4.05a.75.75 0 000-1.06L11.63 1.22zM3.25 13.94a.75.75 0 01-.75-.75v-.69a.75.75 0 011.5 0v.69c0 .414-.336.75-.75.75z"/></svg>
17
- ${h(e)}</div>`;return(t>0||s>0)&&(n+=`<div class="git-diff-stats">+<span class="add">${t}</span> <span class="del">-${s}</span></div>`),n+"</div>"}f.addEventListener("click",e=>{e.target.closest(".sidebar-git")&&ne&&w&&(e.stopPropagation(),$t())});var we=document.getElementById("header-git"),Ht=document.getElementById("git-diff-view"),Rt=document.getElementById("gd-path"),ze=document.getElementById("gd-status"),je=document.getElementById("gd-content"),Pn=document.getElementById("gd-back"),ne=null;function be(e){if(!e||!e.branch){we.style.display="none",ne=null;return}ne=e.repoRoot;let{branch:t,linesAdded:s,linesRemoved:n}=e,a=`<span class="branch">${h(t)}</span>`;(s>0||n>0)&&(a+=`<span class="sep">\xB7</span>+<span class="diff-add">${s}</span> <span class="diff-del">-${n}</span>`),we.innerHTML=a,we.style.display="block"}we.addEventListener("click",e=>{ne&&w&&(e.stopPropagation(),$t())});var B=document.getElementById("git-popover"),Ue=document.getElementById("git-popover-backdrop");function st(){let e=we.getBoundingClientRect();B.style.top=e.bottom+4+"px",B.style.left=Math.max(8,Math.min(e.left,window.innerWidth-400))+"px"}function Nt(){let e=ne,t=document.getElementById("git-popover-browse");t&&t.addEventListener("click",()=>{if(We(),e){et="files",document.querySelectorAll(".mode-btn").forEach(n=>n.classList.remove("active"));let s=document.getElementById("mode-files");s&&s.classList.add("active"),Y(e)}})}var Pt="";function $t(){if(!w)return;let e=w.files||[];if(!e.length)B.innerHTML=`<div class="git-popover-header">No changes \u2014 clean working tree</div>
18
- <div class="git-popover-footer"><button id="git-popover-browse">Browse repository \u2192</button></div>`;else{let t=`<div class="git-popover-header">${e.length} file${e.length>1?"s":""} changed</div>`;for(let s=0;s<e.length;s++){let n=e[s],a=n.additions||0,r=n.deletions||0,c="";switch(n.status){case"M":c='<span class="git-file-status M">M</span>';break;case"A":c='<span class="git-file-status A">A</span>';break;case"D":c='<span class="git-file-status D">D</span>';break;case"?":c='<span class="git-file-status ?">?</span>';break;case"R":c='<span class="git-file-status R">R</span>';break}t+=`<div class="git-popover-item" data-idx="${s}">
17
+ ${h(e)}</div>`;return(t>0||s>0)&&(n+=`<div class="git-diff-stats">+<span class="add">${t}</span> <span class="del">-${s}</span></div>`),n+"</div>"}m.addEventListener("click",e=>{e.target.closest(".sidebar-git")&&ne&&w&&(e.stopPropagation(),$t())});var we=document.getElementById("header-git"),Ht=document.getElementById("git-diff-view"),Rt=document.getElementById("gd-path"),ze=document.getElementById("gd-status"),je=document.getElementById("gd-content"),Pn=document.getElementById("gd-back"),ne=null;function be(e){if(!e||!e.branch){we.style.display="none",ne=null;return}ne=e.repoRoot;let{branch:t,linesAdded:s,linesRemoved:n}=e,i=`<span class="branch">${h(t)}</span>`;(s>0||n>0)&&(i+=`<span class="sep">\xB7</span>+<span class="diff-add">${s}</span> <span class="diff-del">-${n}</span>`),we.innerHTML=i,we.style.display="block"}we.addEventListener("click",e=>{ne&&w&&(e.stopPropagation(),$t())});var S=document.getElementById("git-popover"),Ue=document.getElementById("git-popover-backdrop");function st(){let e=we.getBoundingClientRect();S.style.top=e.bottom+4+"px",S.style.left=Math.max(8,Math.min(e.left,window.innerWidth-400))+"px"}function Nt(){let e=ne,t=document.getElementById("git-popover-browse");t&&t.addEventListener("click",()=>{if(Ye(),e){et="files",document.querySelectorAll(".mode-btn").forEach(n=>n.classList.remove("active"));let s=document.getElementById("mode-files");s&&s.classList.add("active"),O(e)}})}var Pt="";function $t(){if(!w)return;let e=w.files||[];if(!e.length)S.innerHTML=`<div class="git-popover-header">No changes \u2014 clean working tree</div>
18
+ <div class="git-popover-footer"><button id="git-popover-browse">Browse repository \u2192</button></div>`;else{let t=`<div class="git-popover-header">${e.length} file${e.length>1?"s":""} changed</div>`;for(let s=0;s<e.length;s++){let n=e[s],i=n.additions||0,r=n.deletions||0,c="";switch(n.status){case"M":c='<span class="git-file-status M">M</span>';break;case"A":c='<span class="git-file-status A">A</span>';break;case"D":c='<span class="git-file-status D">D</span>';break;case"?":c='<span class="git-file-status ?">?</span>';break;case"R":c='<span class="git-file-status R">R</span>';break}t+=`<div class="git-popover-item" data-idx="${s}">
19
19
  ${c}<span class="file-path">${h(n.path)}</span>
20
- <span class="file-add">${a>0?"+"+a:""}</span>
20
+ <span class="file-add">${i>0?"+"+i:""}</span>
21
21
  <span class="file-del">${r>0?"-"+r:""}</span>
22
- </div>`}t+='<div class="git-popover-footer"><button id="git-popover-browse">Browse repository \u2192</button></div>',Pt=t,B.innerHTML=t,B.querySelectorAll(".git-popover-item").forEach(s=>{let n=parseInt(s.dataset.idx||"0",10),a=e[n];!a||a.status==="D"||(s.classList.add("clickable"),s.style.cursor="pointer",s.addEventListener("click",()=>jt(a.path)))})}st(),B.classList.add("open"),Ue.classList.add("open"),Nt()}function $n(){return window.innerWidth>=1024}function zt(e,t){let s=(e+(t&&e?`
22
+ </div>`}t+='<div class="git-popover-footer"><button id="git-popover-browse">Browse repository \u2192</button></div>',Pt=t,S.innerHTML=t,S.querySelectorAll(".git-popover-item").forEach(s=>{let n=parseInt(s.dataset.idx||"0",10),i=e[n];!i||i.status==="D"||(s.classList.add("clickable"),s.style.cursor="pointer",s.addEventListener("click",()=>jt(i.path)))})}st(),S.classList.add("open"),Ue.classList.add("open"),Nt()}function $n(){return window.innerWidth>=1024}function zt(e,t){let s=(e+(t&&e?`
23
23
  `:"")+t).split(`
24
- `),n="",a=0,r=0;for(let c of s){let o=c;if(o.startsWith("@@")){let u=o.match(/@@\s+-(\d+)[^+]*\+(\d+)/);u&&(a=parseInt(u[1],10)-1,r=parseInt(u[2],10)-1),n+=`<div class="diff-line hunk"><span class="ln-body">${h(o)}</span></div>`;continue}if(o.startsWith("diff --git")||o.startsWith("index ")||o.startsWith("--- ")||o.startsWith("+++ ")||o.startsWith("new file")||o.startsWith("deleted file")){o.startsWith("diff --git")&&(n+=`<div class="diff-line header"><span class="ln-body">${h(o)}</span></div>`);continue}if(o.startsWith("+"))r++,n+=`<div class="diff-line add"><span class="ln-no">${r}</span><span class="ln-body">${h(o)}</span></div>`;else if(o.startsWith("-"))a++,n+=`<div class="diff-line del"><span class="ln-no">${a}</span><span class="ln-body">${h(o)}</span></div>`;else if(o.startsWith("\\"))n+=`<div class="diff-line"><span class="ln-body">${h(o)}</span></div>`;else{if(!o&&!a&&!r)continue;a++,r++,n+=`<div class="diff-line"><span class="ln-no">${a}</span><span class="ln-no" style="margin-right:12px">${r}</span><span class="ln-body">${h(o)}</span></div>`}}return{html:n,lineCount:s.length}}var qe=null;async function jt(e){let t=ne;if(t)if(We(),$n()){I.style.display="none",g&&(Ye(),g.destroy(),g=null,qe=y,y=null),be(null),ve.style.display="none",J.style.display="none",Ht.style.display="flex",Rt.textContent=e,ze.textContent="Loading\u2026",je.innerHTML="";try{let s=await fetch(S("/api/git/diff?path="+encodeURIComponent(t)+"&file="+encodeURIComponent(e)));if(!s.ok)throw new Error(await s.text());let n=await s.json();jn(e,n.diff,n.stagedDiff)}catch(s){let n=s instanceof Error?s.message:String(s);ze.textContent="Error",je.innerHTML=`<div class="diff-empty" style="padding:24px;text-align:center;color:var(--panel-muted)">Error: ${h(n)}</div>`}}else{B.innerHTML=`<div class="git-diff-view"><div class="diff-header">
24
+ `),n="",i=0,r=0;for(let c of s){let o=c;if(o.startsWith("@@")){let u=o.match(/@@\s+-(\d+)[^+]*\+(\d+)/);u&&(i=parseInt(u[1],10)-1,r=parseInt(u[2],10)-1),n+=`<div class="diff-line hunk"><span class="ln-body">${h(o)}</span></div>`;continue}if(o.startsWith("diff --git")||o.startsWith("index ")||o.startsWith("--- ")||o.startsWith("+++ ")||o.startsWith("new file")||o.startsWith("deleted file")){o.startsWith("diff --git")&&(n+=`<div class="diff-line header"><span class="ln-body">${h(o)}</span></div>`);continue}if(o.startsWith("+"))r++,n+=`<div class="diff-line add"><span class="ln-no">${r}</span><span class="ln-body">${h(o)}</span></div>`;else if(o.startsWith("-"))i++,n+=`<div class="diff-line del"><span class="ln-no">${i}</span><span class="ln-body">${h(o)}</span></div>`;else if(o.startsWith("\\"))n+=`<div class="diff-line"><span class="ln-body">${h(o)}</span></div>`;else{if(!o&&!i&&!r)continue;i++,r++,n+=`<div class="diff-line"><span class="ln-no">${i}</span><span class="ln-no" style="margin-right:12px">${r}</span><span class="ln-body">${h(o)}</span></div>`}}return{html:n,lineCount:s.length}}var _e=null;async function jt(e){let t=ne;if(t)if(Ye(),$n()){M.style.display="none",v&&(Oe(),v.destroy(),v=null,_e=y,y=null),be(null),ge.style.display="none",J.style.display="none",Ht.style.display="flex",Rt.textContent=e,ze.textContent="Loading\u2026",je.innerHTML="";try{let s=await fetch(k("/api/git/diff?path="+encodeURIComponent(t)+"&file="+encodeURIComponent(e)));if(!s.ok)throw new Error(await s.text());let n=await s.json();jn(e,n.diff,n.stagedDiff)}catch(s){let n=s instanceof Error?s.message:String(s);ze.textContent="Error",je.innerHTML=`<div class="diff-empty" style="padding:24px;text-align:center;color:var(--panel-muted)">Error: ${h(n)}</div>`}}else{S.innerHTML=`<div class="git-diff-view"><div class="diff-header">
25
25
  <button class="diff-back">\u2190 Back</button>
26
26
  <span class="diff-filename">${h(e)}</span>
27
27
  <span class="diff-loading">Loading\u2026</span>
28
- </div></div>`,st(),B.classList.add("open"),Ue.classList.add("open");try{let s=await fetch(S("/api/git/diff?path="+encodeURIComponent(t)+"&file="+encodeURIComponent(e)));if(!s.ok)throw new Error(await s.text());let n=await s.json();zn(e,n.diff,n.stagedDiff)}catch(s){let n=s instanceof Error?s.message:String(s);B.innerHTML=`<div class="git-diff-view"><div class="diff-header">
28
+ </div></div>`,st(),S.classList.add("open"),Ue.classList.add("open");try{let s=await fetch(k("/api/git/diff?path="+encodeURIComponent(t)+"&file="+encodeURIComponent(e)));if(!s.ok)throw new Error(await s.text());let n=await s.json();zn(e,n.diff,n.stagedDiff)}catch(s){let n=s instanceof Error?s.message:String(s);S.innerHTML=`<div class="git-diff-view"><div class="diff-header">
29
29
  <button class="diff-back">\u2190 Back</button>
30
30
  <span class="diff-filename">${h(e)}</span>
31
- </div><div class="diff-empty">Error loading diff: ${h(n)}</div></div>`}}}function zn(e,t,s){if(!t&&!s){B.innerHTML=`<div class="git-diff-view"><div class="diff-header">
31
+ </div><div class="diff-empty">Error loading diff: ${h(n)}</div></div>`}}}function zn(e,t,s){if(!t&&!s){S.innerHTML=`<div class="git-diff-view"><div class="diff-header">
32
32
  <button class="diff-back">\u2190 Back</button>
33
33
  <span class="diff-filename">${h(e)}</span>
34
- </div><div class="diff-empty">No diff content available</div></div>`;return}let{html:n,lineCount:a}=zt(t,s);B.innerHTML=`<div class="git-diff-view"><div class="diff-header">
34
+ </div><div class="diff-empty">No diff content available</div></div>`;return}let{html:n,lineCount:i}=zt(t,s);S.innerHTML=`<div class="git-diff-view"><div class="diff-header">
35
35
  <button class="diff-back">\u2190 Back</button>
36
36
  <span class="diff-filename">${h(e)}</span>
37
- <span class="diff-filesize">${a} lines</span>
38
- </div><div class="diff-content">${n}</div></div>`,B.querySelector(".diff-back")?.addEventListener("click",()=>{B.innerHTML=Pt,st(),w&&B.querySelectorAll(".git-popover-item").forEach(r=>{let c=parseInt(r.dataset.idx||"0",10),o=w.files[c];!o||o.status==="D"||(r.style.cursor="pointer",r.addEventListener("click",()=>jt(o.path)))}),Nt()})}function jn(e,t,s){if(!t&&!s){ze.textContent="No diff",je.innerHTML='<div class="diff-empty" style="padding:24px;text-align:center;color:var(--panel-muted)">No diff content available</div>';return}let{html:n,lineCount:a}=zt(t,s);Rt.textContent=e,ze.textContent=a+" lines",je.innerHTML=n}function Un(){Ht.style.display="none",qe?(I.style.display="",I.classList.add("terminal-pending"),ye(qe),qe=null):y?(I.style.display="",I.classList.add("terminal-pending"),qt()):J.style.display="flex"}Pn.addEventListener("click",Un);function We(){B.classList.remove("open"),Ue.classList.remove("open")}Ue.addEventListener("click",We),document.addEventListener("keydown",e=>{e.key==="Escape"&&(We(),Ve())});async function Ut(e){try{let t=await(await fetch("/api/fs/session-path?session="+encodeURIComponent(e))).json();if(t.path){let s=await fetch("/api/git/status?path="+encodeURIComponent(t.path));if(s.ok){let n=await s.json();w=n,be(n);return}}}catch{}w=null,be(null)}var _e=null;function qt(){Ye(),y&&(Ut(y),_e=setInterval(()=>{y&&Ut(y)},3e4))}function Ye(){_e&&(clearInterval(_e),_e=null)}function qn(){if($e=fe.fsRoots||[],$e.length===0){if(y){Wn(y);return}f.innerHTML='<div class="file-tree-info">Open a session first, then switch to Files to browse its directory.</div>';return}f.innerHTML="";for(let e of $e){let t=document.createElement("div");t.className="file-tree-item",t.innerHTML=`<svg viewBox="0 0 24 24" fill="currentColor" class="file-icon"><path d="M10 4H4c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V8c0-1.1-.9-2-2-2h-8l-2-2z"/></svg> ${h(e)}`,t.addEventListener("click",()=>Y(e)),f.appendChild(t)}}async function Wn(e){f.innerHTML='<div class="file-tree-empty">Loading...</div>';try{let t=await(await fetch(S("/api/fs/session-path?session="+encodeURIComponent(e)))).json();t.path?Y(t.path):f.innerHTML='<div class="file-tree-info">Could not determine session directory.</div>'}catch{f.innerHTML='<div class="file-tree-error">Failed to get session directory</div>'}}async function Y(e){_=e,f.innerHTML='<div class="file-tree-empty">Loading...</div>';let t=Rn(e);try{let s=await(await fetch(S("/api/fs/list?path="+encodeURIComponent(e)))).json();await t,f.innerHTML="",be(w),f.innerHTML+=Nn();let n=_n(e);if(n&&!$e.some(r=>e===r)){let r=document.createElement("div");r.className="file-tree-item",r.innerHTML="..",r.addEventListener("click",()=>Y(n)),f.appendChild(r)}if(s.dirs)for(let r of s.dirs){let c=r.split("/").pop()||r.split("\\").pop(),o=document.createElement("div");o.className="file-tree-item",o.innerHTML=`<svg viewBox="0 0 24 24" fill="currentColor" class="file-icon"><path d="M10 4H4c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V8c0-1.1-.9-2-2-2h-8l-2-2z"/></svg> ${h(c)}`,o.addEventListener("click",()=>Y(r)),f.appendChild(o)}else f.innerHTML="";let a=s.files||[];for(let r of a){let c=r.split("/").pop()||r.split("\\").pop(),o=Hn(r),u="",p="";if(o)switch(o){case"M":u="git-mod",p='<span class="git-file-status M">M</span>';break;case"A":u="git-add",p='<span class="git-file-status A">A</span>';break;case"D":u="git-del",p='<span class="git-file-status D">D</span>';break;case"?":u="git-untracked",p='<span class="git-file-status ?">?</span>';break;case"R":u="git-mod",p='<span class="git-file-status R">R</span>';break}let E=document.createElement("div");E.className="file-tree-item file"+(u?" "+u:""),E.innerHTML=`<span class="file-icon">\u{1F4C4}</span> ${p}${h(c)}`,E.addEventListener("click",()=>Yn(r)),f.appendChild(E)}}catch{f.innerHTML='<div class="file-tree-error">Failed to load directory</div>'}}function _n(e){let t=e.lastIndexOf("/");return t<=0?null:e.substring(0,t)}async function Yn(e){He=e,I.style.display="none",g&&(Ye(),g.destroy(),g=null,y=null),be(null),Pe(),J.style.display="none",ve.style.display="flex",kn.textContent=e,F.textContent="Loading...",Z.style.display="none";try{let t=await fetch(S("/api/file?path="+encodeURIComponent(e)));if(!t.ok){let n=await t.json();F.textContent=n.error||"Failed to load",ge.value="";return}let s=await t.json();ge.value=s.content,Re=s.content,Lt=s.content,F.textContent=s.size+" bytes",Z.style.display=""}catch{F.textContent="Failed to load",ge.value=""}}ge.addEventListener("input",()=>{Re=ge.value}),Z.addEventListener("click",async()=>{Z.textContent="Saving...",Z.disabled=!0;try{let e=await fetch(S("/api/file"),{method:"PUT",headers:{"Content-Type":"application/json"},body:JSON.stringify({path:He,content:Re})});if(!e.ok){let t=await e.json();F.textContent=t.error||"Save failed";return}Lt=Re,F.textContent="Saved"}catch{F.textContent="Save failed"}finally{Z.disabled=!1,Z.textContent="Save"}}),Sn.addEventListener("click",async()=>{if(confirm("Delete "+He+"?"))try{let e=await fetch(S("/api/file/delete"),{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({path:He})});if(!e.ok){let t=await e.json();F.textContent=t.error||"Delete failed";return}ve.style.display="none",J.style.display="flex",_&&Y(_)}catch{F.textContent="Delete failed"}}),Bn.addEventListener("click",()=>{ve.style.display="none",J.style.display="flex",_&&Y(_)}),Tn.addEventListener("click",async()=>{let e=Et.value.trim();if(!e)return;let t=_+"/"+e;try{let s=await fetch(S("/api/file/touch"),{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({path:t})});if(!s.ok){let n=await s.json();F.textContent=n.error||"Create failed";return}Et.value="",_&&Y(_)}catch{F.textContent="Create failed"}});var Oe=document.getElementById("force-narrow-toggle");Oe&&(Oe.checked=Ne(),Oe.addEventListener("change",()=>{try{localStorage.setItem(kt,Oe.checked?"1":"0")}catch{}St(),j()})),St(),document.getElementById("mode-settings").addEventListener("click",()=>{let e=Ct.classList.toggle("open");tt.classList.toggle("open",e)}),tt.addEventListener("click",()=>{Ct.classList.remove("open"),tt.classList.remove("open")});var D="",U=!1,H,Le=document.createElement("div");Le.className="session-popover-backdrop",document.body.appendChild(Le);var R=document.createElement("div");R.id="session-popover",R.className="session-popover",R.style.display="none",R.innerHTML=`<div class="sp-field">
37
+ <span class="diff-filesize">${i} lines</span>
38
+ </div><div class="diff-content">${n}</div></div>`,S.querySelector(".diff-back")?.addEventListener("click",()=>{S.innerHTML=Pt,st(),w&&S.querySelectorAll(".git-popover-item").forEach(r=>{let c=parseInt(r.dataset.idx||"0",10),o=w.files[c];!o||o.status==="D"||(r.style.cursor="pointer",r.addEventListener("click",()=>jt(o.path)))}),Nt()})}function jn(e,t,s){if(!t&&!s){ze.textContent="No diff",je.innerHTML='<div class="diff-empty" style="padding:24px;text-align:center;color:var(--panel-muted)">No diff content available</div>';return}let{html:n,lineCount:i}=zt(t,s);Rt.textContent=e,ze.textContent=i+" lines",je.innerHTML=n}function Un(){Ht.style.display="none",_e?(M.style.display="",M.classList.add("terminal-pending"),ye(_e),_e=null):y?(M.style.display="",M.classList.add("terminal-pending"),_t()):J.style.display="flex"}Pn.addEventListener("click",Un);function Ye(){S.classList.remove("open"),Ue.classList.remove("open")}Ue.addEventListener("click",Ye),document.addEventListener("keydown",e=>{e.key==="Escape"&&(Ye(),Ve())});async function Ut(e){try{let t=await(await fetch("/api/fs/session-path?session="+encodeURIComponent(e))).json();if(t.path){let s=await fetch("/api/git/status?path="+encodeURIComponent(t.path));if(s.ok){let n=await s.json();w=n,be(n);return}}}catch{}w=null,be(null)}var We=null;function _t(){Oe(),y&&(Ut(y),We=setInterval(()=>{y&&Ut(y)},3e4))}function Oe(){We&&(clearInterval(We),We=null)}function _n(){if($e=me.fsRoots||[],$e.length===0){if(y){Yn(y);return}m.innerHTML='<div class="file-tree-info">Open a session first, then switch to Files to browse its directory.</div>';return}m.innerHTML="";for(let e of $e){let t=document.createElement("div");t.className="file-tree-item",t.innerHTML=`<svg viewBox="0 0 24 24" fill="currentColor" class="file-icon"><path d="M10 4H4c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V8c0-1.1-.9-2-2-2h-8l-2-2z"/></svg> ${h(e)}`,t.addEventListener("click",()=>O(e)),m.appendChild(t)}}async function Yn(e){m.innerHTML='<div class="file-tree-empty">Loading...</div>';try{let t=await(await fetch(k("/api/fs/session-path?session="+encodeURIComponent(e)))).json();t.path?O(t.path):m.innerHTML='<div class="file-tree-info">Could not determine session directory.</div>'}catch{m.innerHTML='<div class="file-tree-error">Failed to get session directory</div>'}}async function O(e){W=e,m.innerHTML='<div class="file-tree-empty">Loading...</div>';let t=Rn(e);try{let s=await(await fetch(k("/api/fs/list?path="+encodeURIComponent(e)))).json();await t,m.innerHTML="",be(w),m.innerHTML+=Nn();let n=Wn(e);if(n&&!$e.some(r=>e===r)){let r=document.createElement("div");r.className="file-tree-item",r.innerHTML="..",r.addEventListener("click",()=>O(n)),m.appendChild(r)}if(s.dirs)for(let r of s.dirs){let c=r.split("/").pop()||r.split("\\").pop(),o=document.createElement("div");o.className="file-tree-item",o.innerHTML=`<svg viewBox="0 0 24 24" fill="currentColor" class="file-icon"><path d="M10 4H4c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V8c0-1.1-.9-2-2-2h-8l-2-2z"/></svg> ${h(c)}`,o.addEventListener("click",()=>O(r)),m.appendChild(o)}else m.innerHTML="";let i=s.files||[];for(let r of i){let c=r.split("/").pop()||r.split("\\").pop(),o=Hn(r),u="",p="";if(o)switch(o){case"M":u="git-mod",p='<span class="git-file-status M">M</span>';break;case"A":u="git-add",p='<span class="git-file-status A">A</span>';break;case"D":u="git-del",p='<span class="git-file-status D">D</span>';break;case"?":u="git-untracked",p='<span class="git-file-status ?">?</span>';break;case"R":u="git-mod",p='<span class="git-file-status R">R</span>';break}let T=document.createElement("div");T.className="file-tree-item file"+(u?" "+u:""),T.innerHTML=`<span class="file-icon">\u{1F4C4}</span> ${p}${h(c)}`,T.addEventListener("click",()=>On(r)),m.appendChild(T)}}catch{m.innerHTML='<div class="file-tree-error">Failed to load directory</div>'}}function Wn(e){let t=e.lastIndexOf("/");return t<=0?null:e.substring(0,t)}async function On(e){He=e,M.style.display="none",v&&(Oe(),v.destroy(),v=null,y=null),be(null),Pe(),J.style.display="none",ge.style.display="flex",kn.textContent=e,F.textContent="Loading...",Z.style.display="none";try{let t=await fetch(k("/api/file?path="+encodeURIComponent(e)));if(!t.ok){let n=await t.json();F.textContent=n.error||"Failed to load",ve.value="";return}let s=await t.json();ve.value=s.content,Re=s.content,Et=s.content,F.textContent=s.size+" bytes",Z.style.display=""}catch{F.textContent="Failed to load",ve.value=""}}ve.addEventListener("input",()=>{Re=ve.value}),Z.addEventListener("click",async()=>{Z.textContent="Saving...",Z.disabled=!0;try{let e=await fetch(k("/api/file"),{method:"PUT",headers:{"Content-Type":"application/json"},body:JSON.stringify({path:He,content:Re})});if(!e.ok){let t=await e.json();F.textContent=t.error||"Save failed";return}Et=Re,F.textContent="Saved"}catch{F.textContent="Save failed"}finally{Z.disabled=!1,Z.textContent="Save"}}),Sn.addEventListener("click",async()=>{if(confirm("Delete "+He+"?"))try{let e=await fetch(k("/api/file/delete"),{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({path:He})});if(!e.ok){let t=await e.json();F.textContent=t.error||"Delete failed";return}ge.style.display="none",J.style.display="flex",W&&O(W)}catch{F.textContent="Delete failed"}}),Tn.addEventListener("click",()=>{ge.style.display="none",J.style.display="flex",W&&O(W)}),Bn.addEventListener("click",async()=>{let e=Lt.value.trim();if(!e)return;let t=W+"/"+e;try{let s=await fetch(k("/api/file/touch"),{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({path:t})});if(!s.ok){let n=await s.json();F.textContent=n.error||"Create failed";return}Lt.value="",W&&O(W)}catch{F.textContent="Create failed"}});var qe=document.getElementById("force-narrow-toggle");qe&&(qe.checked=Ne(),qe.addEventListener("change",()=>{try{localStorage.setItem(kt,qe.checked?"1":"0")}catch{}St(),j()})),St(),document.getElementById("mode-settings").addEventListener("click",()=>{let e=xt.classList.toggle("open");tt.classList.toggle("open",e)}),tt.addEventListener("click",()=>{xt.classList.remove("open"),tt.classList.remove("open")});var D="",U=!1,H,Ee=document.createElement("div");Ee.className="session-popover-backdrop",document.body.appendChild(Ee);var R=document.createElement("div");R.id="session-popover",R.className="session-popover",R.style.display="none",R.innerHTML=`<div class="sp-field">
39
39
  <label>Rename session</label>
40
40
  <input type="text" id="sp-name" />
41
41
  </div>
@@ -45,5 +45,5 @@ var bn=/\x1b\](?:10|11|110|111|104)(?:;[^\x07\x1b]*)?\x1b?(?:\\|\x07)/g;function
45
45
  </div>
46
46
  <hr class="sp-divider" />
47
47
  <button class="btn primary" id="sp-rebuild" style="display:none">\u91CD\u5EFA\u540C\u540D\u540C\u8DEF\u5F84 session</button>
48
- <button class="btn danger" id="sp-delete">Delete session</button>`,document.body.appendChild(R);function On(e){let t=e.getBoundingClientRect(),s=window.innerHeight,n=R.offsetHeight||240,a=t.bottom+4;a+n>s-8&&(a=Math.max(8,t.top-n-4)),R.style.top=a+"px",R.style.left=Math.max(8,Math.min(t.left,window.innerWidth-240))+"px"}function Ke(e,t,s){D=e,U=!!s?.tombstone,H=s?.agentId;let n=document.getElementById("sp-name");n.value=e;let a=R.querySelector(".sp-field label");a.textContent=U?"\u91CD\u547D\u540D (\u4EC5\u8BB0\u5F55\uFF0C\u4E0D\u91CD\u5EFA)":"Rename session";let r=document.getElementById("sp-rebuild");r.style.display=U?"":"none";let c=document.getElementById("sp-delete");c.textContent=U?"\u5220\u9664\u5931\u6548\u8BB0\u5F55 (\u5893\u7891\u6D88\u5931)":"Delete session";let o=document.getElementById("sp-save");o.textContent=U?"\u91CD\u547D\u540D":"Save",Le.classList.add("open"),R.style.display="block",On(t),setTimeout(()=>n.focus(),50)}function G(){Le.classList.remove("open"),R.style.display="none"}Le.addEventListener("click",G),document.getElementById("sp-save").addEventListener("click",async()=>{let e=document.getElementById("sp-name").value.trim();if(!e||e===D){G();return}try{let t=U?{oldName:D,newName:e,agentId:H}:{oldName:D,newName:e,...H?{agentId:H}:{}};if(!(await fetch(S(U?"/api/sessions/rename-tombstone":"/api/sessions/rename"),{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(t)})).ok)return;G(),j(),!U&&y===D&&(H??null)===k&&ye(e,H)}catch{}}),document.getElementById("sp-rebuild").addEventListener("click",async()=>{if(confirm('\u91CD\u5EFA\u4F1A\u8BDD "'+D+'" (\u540C\u540D\u540C\u8DEF\u5F84\uFF0C\u5185\u5BB9\u4E3A\u7A7A)\uFF1F'))try{let e=await fetch(S("/api/sessions/rebuild"),{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({name:D,agentId:H})});if(!e.ok){let t=await e.json();alert(t.error||"\u91CD\u5EFA\u5931\u8D25");return}G(),j()}catch{}}),document.getElementById("sp-delete").addEventListener("click",async()=>{if(U){if(!confirm('\u5220\u9664\u5931\u6548\u8BB0\u5F55 "'+D+'"\uFF1F'))return;try{if(!(await fetch(S("/api/sessions/dismiss"),{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({name:D,agentId:H})})).ok)return;G(),j()}catch{}return}if(confirm('Delete session "'+D+'"?'))try{if(!(await fetch(S("/api/sessions/kill"),{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({name:D,...H?{agentId:H}:{}})})).ok)return;G(),y===D&&(H??null)===k&&(g&&(g.destroy(),g=null),y=null,I.style.display="none",J.style.display="flex"),j()}catch{}}),document.getElementById("sp-cancel").addEventListener("click",G);var Kn={esc:"\x1B",tab:" ","s-tab":"\x1B[Z",up:"\x1B[A",down:"\x1B[B",left:"\x1B[D",right:"\x1B[C",space:" ",enter:"\r","ctrl-r":"","ctrl-c":"",btw:"/btw ",yes:"yes\r"};document.getElementById("mobile-keys").addEventListener("click",e=>{let t=e.target.closest("button[data-key]");if(!t||!g)return;let s=Kn[t.dataset.key];s&&(g.sendInput(s),g.focus())});var P=document.getElementById("mk-input"),Wt=document.getElementById("mk-send");function _t(){if(!P||!g)return;let e=P.value;e&&(g.sendInput(e+"\r"),P.value="",P.rows=1,g.focus())}if(P&&(P.addEventListener("input",()=>{P.rows=1;let e=P.value.split(`
49
- `).length;P.rows=Math.min(e,4)}),P.addEventListener("keydown",e=>{e.key==="Enter"&&!e.shiftKey&&(e.preventDefault(),_t())})),Wt&&Wt.addEventListener("click",_t),window.visualViewport){let e=document.querySelector(".app-layout"),t=()=>{e&&(e.style.height=window.visualViewport.height+"px"),window.scrollTo(0,0),document.documentElement.scrollTop=0,document.body.scrollTop=0};window.visualViewport.addEventListener("resize",t),window.addEventListener("orientationchange",()=>setTimeout(t,100)),document.addEventListener("touchstart",()=>{(window.scrollY>0||document.documentElement.scrollTop>0)&&window.scrollTo(0,0)},{passive:!0})}var it=document.getElementById("process-panel"),Ee=document.getElementById("proc-list"),Vn=document.getElementById("proc-close"),at=document.getElementById("proc-backdrop"),Xn=document.getElementById("header-ram");function Jn(){Ee.innerHTML='<div class="proc-empty">Loading\u2026</div>',fetch(S("/api/system/processes")).then(e=>e.json()).then(e=>{if(!Array.isArray(e)||!e.length){Ee.innerHTML='<div class="proc-empty">No processes</div>';return}let t="";for(let s of e){let n=s.rss,a=n<1048576?(n/1024).toFixed(0)+"K":(n/1048576).toFixed(1)+"M";t+='<div class="proc-row" data-pid="'+s.pid+'"><span class="proc-mem">'+s.mem+'%</span><span class="proc-rss">'+a+'</span><span class="proc-cmd" title="'+h(s.command)+'">'+h(s.command)+'</span><button class="proc-kill" title="Kill PID '+s.pid+'">&times;</button></div>'}Ee.innerHTML=t;for(let s of Ee.querySelectorAll(".proc-row")){let n=s.querySelector(".proc-kill");n&&n.addEventListener("click",a=>{let r=a.target.closest(".proc-row");!r||!confirm("Kill PID "+r.dataset.pid+"?")||fetch(S("/api/system/kill"),{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({pid:parseInt(r.dataset.pid,10)})}).then(c=>c.json()).then(c=>{c.ok?r.style.opacity="0.3":alert("Failed: "+(c.error||"unknown"))}).catch(()=>alert("Network error"))})}}).catch(()=>{Ee.innerHTML='<div class="proc-empty">Failed to load</div>'})}function Zn(){it.classList.add("open"),at.classList.add("open"),Jn()}function Ve(){it.classList.remove("open"),at.classList.remove("open")}Xn.addEventListener("click",e=>{e.stopPropagation(),it.classList.contains("open")?Ve():Zn()}),Vn.addEventListener("click",Ve),at.addEventListener("click",Ve);var Gn=2e3,Ce=null,ot=null,se=new Map,ie=new Map,Qn=5e3,Yt=new Map;function lt(e,t){return(t?"a:"+t+":":"l:")+e}function es(e,t,s){let n=lt(e,t);if(s==="working"){let p=Yt.get(n);if(p&&Date.now()<p)return}let a=ie.get(n),r=e===y&&(t??null)===k,c=s==="idle"&&a?.state==="working";ie.set(n,{session:e,agentId:t,state:s,doneUntil:c?Date.now()+Gn:void 0,unread:c?!r:!1});let o=t?'.session-item[data-agent="'+CSS.escape(t)+'"][data-session="'+CSS.escape(e)+'"]':'.session-item[data-session="'+CSS.escape(e)+'"]:not([data-agent])',u=f.querySelector(o);u&&Xe(u,n,ie.get(n))}function Xe(e,t,s){let n=se.get(t);n&&(clearTimeout(n),se.delete(t)),e.classList.remove("working","just-done");let a=s.session===y&&(s.agentId??null)===k;s.state==="working"?e.classList.add("working"):a&&s.doneUntil&&Date.now()<s.doneUntil?(e.classList.add("just-done"),se.set(t,setTimeout(()=>{e.classList.remove("just-done"),se.delete(t)},Math.max(0,s.doneUntil-Date.now())))):!a&&s.unread&&e.classList.add("just-done")}function rt(){for(let[e,t]of ie){let s=t.agentId?'.session-item[data-agent="'+CSS.escape(t.agentId)+'"][data-session="'+CSS.escape(t.session)+'"]':'.session-item[data-session="'+CSS.escape(t.session)+'"]:not([data-agent])',n=f.querySelector(s);n&&Xe(n,e,t)}}function ts(e,t){let s=lt(e,t),n=ie.get(s);if(!n)return;let a=se.get(s);a&&(clearTimeout(a),se.delete(s)),n.doneUntil=void 0,n.unread=!1;let r=t?'.session-item[data-agent="'+CSS.escape(t)+'"][data-session="'+CSS.escape(e)+'"]':'.session-item[data-session="'+CSS.escape(e)+'"]:not([data-agent])',c=f.querySelector(r);c&&Xe(c,s,n)}function Ot(){if(Ce||ot)return;let e=localStorage.getItem("tmux-web-token"),t=(location.protocol==="https:"?"wss:":"ws:")+"//"+location.host+"/ws/activity";e&&(t+="?token="+encodeURIComponent(e));try{let s=new WebSocket(t);Ce=s,s.onmessage=n=>{try{let a=JSON.parse(String(n.data));a&&a.type==="session.activity"&&typeof a.session=="string"&&es(a.session,a.agentId||void 0,a.state==="working"?"working":"idle")}catch{}},s.onclose=()=>{Ce===s&&(Ce=null,ot=setTimeout(()=>{ot=null,Ot()},5e3))},s.onerror=()=>{try{s.close()}catch{}}}catch{Ce=null}}window.__openSession=ye,window.__refreshSidebar=j,j(),Pe(),rt(),Ot(),document.addEventListener("visibilitychange",()=>{document.visibilityState==="visible"&&rt()}),setInterval(()=>{document.visibilityState==="visible"&&j()},1e4);
48
+ <button class="btn danger" id="sp-delete">Delete session</button>`,document.body.appendChild(R);function qn(e){let t=e.getBoundingClientRect(),s=window.innerHeight,n=R.offsetHeight||240,i=t.bottom+4;i+n>s-8&&(i=Math.max(8,t.top-n-4)),R.style.top=i+"px",R.style.left=Math.max(8,Math.min(t.left,window.innerWidth-240))+"px"}function Ke(e,t,s){D=e,U=!!s?.tombstone,H=s?.agentId;let n=document.getElementById("sp-name");n.value=e;let i=R.querySelector(".sp-field label");i.textContent=U?"\u91CD\u547D\u540D (\u4EC5\u8BB0\u5F55\uFF0C\u4E0D\u91CD\u5EFA)":"Rename session";let r=document.getElementById("sp-rebuild");r.style.display=U?"":"none";let c=document.getElementById("sp-delete");c.textContent=U?"\u5220\u9664\u5931\u6548\u8BB0\u5F55 (\u5893\u7891\u6D88\u5931)":"Delete session";let o=document.getElementById("sp-save");o.textContent=U?"\u91CD\u547D\u540D":"Save",Ee.classList.add("open"),R.style.display="block",qn(t),setTimeout(()=>n.focus(),50)}function G(){Ee.classList.remove("open"),R.style.display="none"}Ee.addEventListener("click",G),document.getElementById("sp-save").addEventListener("click",async()=>{let e=document.getElementById("sp-name").value.trim();if(!e||e===D){G();return}try{let t=U?{oldName:D,newName:e,agentId:H}:{oldName:D,newName:e,...H?{agentId:H}:{}};if(!(await fetch(k(U?"/api/sessions/rename-tombstone":"/api/sessions/rename"),{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(t)})).ok)return;G(),j(),!U&&y===D&&(H??null)===C&&ye(e,H)}catch{}}),document.getElementById("sp-rebuild").addEventListener("click",async()=>{if(confirm('\u91CD\u5EFA\u4F1A\u8BDD "'+D+'" (\u540C\u540D\u540C\u8DEF\u5F84\uFF0C\u5185\u5BB9\u4E3A\u7A7A)\uFF1F'))try{let e=await fetch(k("/api/sessions/rebuild"),{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({name:D,agentId:H})});if(!e.ok){let t=await e.json();alert(t.error||"\u91CD\u5EFA\u5931\u8D25");return}G(),j()}catch{}}),document.getElementById("sp-delete").addEventListener("click",async()=>{if(U){if(!confirm('\u5220\u9664\u5931\u6548\u8BB0\u5F55 "'+D+'"\uFF1F'))return;try{if(!(await fetch(k("/api/sessions/dismiss"),{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({name:D,agentId:H})})).ok)return;G(),j()}catch{}return}if(confirm('Delete session "'+D+'"?'))try{if(!(await fetch(k("/api/sessions/kill"),{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({name:D,...H?{agentId:H}:{}})})).ok)return;G(),y===D&&(H??null)===C&&(v&&(v.destroy(),v=null),y=null,M.style.display="none",J.style.display="flex"),j()}catch{}}),document.getElementById("sp-cancel").addEventListener("click",G);var Kn={esc:"\x1B",tab:" ","s-tab":"\x1B[Z",up:"\x1B[A",down:"\x1B[B",left:"\x1B[D",right:"\x1B[C",space:" ",enter:"\r","ctrl-r":"","ctrl-c":"",btw:"/btw ",yes:"yes\r"};document.getElementById("mobile-keys").addEventListener("click",e=>{let t=e.target.closest("button[data-key]");if(!t||!v)return;let s=Kn[t.dataset.key];s&&(v.sendInput(s),v.focus())});var P=document.getElementById("mk-input"),Yt=document.getElementById("mk-send");function Wt(){if(!P||!v)return;let e=P.value;e&&(v.sendInput(e+"\r"),P.value="",P.rows=1,v.focus())}if(P&&(P.addEventListener("input",()=>{P.rows=1;let e=P.value.split(`
49
+ `).length;P.rows=Math.min(e,4)}),P.addEventListener("keydown",e=>{e.key==="Enter"&&!e.shiftKey&&(e.preventDefault(),Wt())})),Yt&&Yt.addEventListener("click",Wt),window.visualViewport){let e=document.querySelector(".app-layout"),t=()=>{e&&(e.style.height=window.visualViewport.height+"px"),window.scrollTo(0,0),document.documentElement.scrollTop=0,document.body.scrollTop=0};window.visualViewport.addEventListener("resize",t),window.addEventListener("orientationchange",()=>setTimeout(t,100)),document.addEventListener("touchstart",()=>{(window.scrollY>0||document.documentElement.scrollTop>0)&&window.scrollTo(0,0)},{passive:!0})}var at=document.getElementById("process-panel"),Le=document.getElementById("proc-list"),Vn=document.getElementById("proc-close"),it=document.getElementById("proc-backdrop"),Xn=document.getElementById("header-ram");function Jn(){Le.innerHTML='<div class="proc-empty">Loading\u2026</div>',fetch(k("/api/system/processes")).then(e=>e.json()).then(e=>{if(!Array.isArray(e)||!e.length){Le.innerHTML='<div class="proc-empty">No processes</div>';return}let t="";for(let s of e){let n=s.rss,i=n<1048576?(n/1024).toFixed(0)+"K":(n/1048576).toFixed(1)+"M";t+='<div class="proc-row" data-pid="'+s.pid+'"><span class="proc-mem">'+s.mem+'%</span><span class="proc-rss">'+i+'</span><span class="proc-cmd" title="'+h(s.command)+'">'+h(s.command)+'</span><button class="proc-kill" title="Kill PID '+s.pid+'">&times;</button></div>'}Le.innerHTML=t;for(let s of Le.querySelectorAll(".proc-row")){let n=s.querySelector(".proc-kill");n&&n.addEventListener("click",i=>{let r=i.target.closest(".proc-row");!r||!confirm("Kill PID "+r.dataset.pid+"?")||fetch(k("/api/system/kill"),{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({pid:parseInt(r.dataset.pid,10)})}).then(c=>c.json()).then(c=>{c.ok?r.style.opacity="0.3":alert("Failed: "+(c.error||"unknown"))}).catch(()=>alert("Network error"))})}}).catch(()=>{Le.innerHTML='<div class="proc-empty">Failed to load</div>'})}function Zn(){at.classList.add("open"),it.classList.add("open"),Jn()}function Ve(){at.classList.remove("open"),it.classList.remove("open")}Xn.addEventListener("click",e=>{e.stopPropagation(),at.classList.contains("open")?Ve():Zn()}),Vn.addEventListener("click",Ve),it.addEventListener("click",Ve);var Gn=2e3,xe=null,ot=null,se=new Map,ae=new Map,Qn=5e3,Ot=new Map;function lt(e,t){return(t?"a:"+t+":":"l:")+e}function es(e,t,s){let n=lt(e,t);if(s==="working"){let p=Ot.get(n);if(p&&Date.now()<p)return}let i=ae.get(n),r=e===y&&(t??null)===C,c=s==="idle"&&i?.state==="working";ae.set(n,{session:e,agentId:t,state:s,doneUntil:c?Date.now()+Gn:void 0,unread:c?!r:!1});let o=t?'.session-item[data-agent="'+CSS.escape(t)+'"][data-session="'+CSS.escape(e)+'"]':'.session-item[data-session="'+CSS.escape(e)+'"]:not([data-agent])',u=m.querySelector(o);u&&Xe(u,n,ae.get(n))}function Xe(e,t,s){let n=se.get(t);n&&(clearTimeout(n),se.delete(t)),e.classList.remove("working","just-done");let i=s.session===y&&(s.agentId??null)===C;s.state==="working"?e.classList.add("working"):i&&s.doneUntil&&Date.now()<s.doneUntil?(e.classList.add("just-done"),se.set(t,setTimeout(()=>{e.classList.remove("just-done"),se.delete(t)},Math.max(0,s.doneUntil-Date.now())))):!i&&s.unread&&e.classList.add("just-done")}function rt(){for(let[e,t]of ae){let s=t.agentId?'.session-item[data-agent="'+CSS.escape(t.agentId)+'"][data-session="'+CSS.escape(t.session)+'"]':'.session-item[data-session="'+CSS.escape(t.session)+'"]:not([data-agent])',n=m.querySelector(s);n&&Xe(n,e,t)}}function ts(e,t){let s=lt(e,t),n=ae.get(s);if(!n)return;let i=se.get(s);i&&(clearTimeout(i),se.delete(s)),n.doneUntil=void 0,n.unread=!1;let r=t?'.session-item[data-agent="'+CSS.escape(t)+'"][data-session="'+CSS.escape(e)+'"]':'.session-item[data-session="'+CSS.escape(e)+'"]:not([data-agent])',c=m.querySelector(r);c&&Xe(c,s,n)}function qt(){if(xe||ot)return;let e=localStorage.getItem("tmux-web-token"),t=(location.protocol==="https:"?"wss:":"ws:")+"//"+location.host+"/ws/activity";e&&(t+="?token="+encodeURIComponent(e));try{let s=new WebSocket(t);xe=s,s.onmessage=n=>{try{let i=JSON.parse(String(n.data));i&&i.type==="session.activity"&&typeof i.session=="string"&&es(i.session,i.agentId||void 0,i.state==="working"?"working":"idle")}catch{}},s.onclose=()=>{xe===s&&(xe=null,ot=setTimeout(()=>{ot=null,qt()},5e3))},s.onerror=()=>{try{s.close()}catch{}}}catch{xe=null}}window.__openSession=ye,window.__refreshSidebar=j,j(),Pe(),rt(),qt(),document.addEventListener("visibilitychange",()=>{document.visibilityState==="visible"&&rt()}),setInterval(()=>{document.visibilityState==="visible"&&j()},1e4);
@@ -1,8 +1,8 @@
1
- const Ht=/\x1b\](?:10|11|110|111|104)(?:;[^\x07\x1b]*)?\x1b?(?:\\|\x07)/g;function ot(l){return l.replace(/\x1b\[\?1049[hl]/g,"")}function O(l){return l.replace(Ht,"")}let N;function Ot(){return N||(document.querySelector("link[data-tmux-web-xterm-css]")?N=Promise.resolve():(N=new Promise(i=>{const o=document.createElement("link");o.rel="stylesheet",o.href="/assets/xterm.css",o.setAttribute("data-tmux-web-xterm-css",""),o.addEventListener("load",()=>i(),{once:!0}),o.addEventListener("error",()=>i(),{once:!0}),document.head.appendChild(o)}),N))}class rt{terminal;fitAddon;container;verifyRaf=0;verifyRounds=0;shrinkCols=0;lastLimit=0;lastCheckAt=0;webglActive=!1;webglAddon=null;constructor(i,o,n){this.container=i,this.terminal=o,this.fitAddon=n,this.terminal.loadAddon(this.fitAddon),this.terminal.open(i),this.enableWebglRenderer()}enableWebglRenderer(){import("@xterm/addon-webgl").then(({WebglAddon:i})=>{const o=new i;o.onContextLoss(()=>{this.webglActive=!1,this.webglAddon=null;try{o.dispose()}catch{}this.lastLimit>0&&this.scheduleColumnCheck(this.lastLimit,!0)});try{this.terminal.loadAddon(o)}catch{return}this.webglAddon=o,this.webglActive=!0,this.fit()}).catch(()=>{})}static async create(i,o,n){const[{Terminal:a},{FitAddon:d}]=await Promise.all([import("@xterm/xterm"),import("@xterm/addon-fit"),Ot()]),h=new a({fontSize:14,fontFamily:"'JetBrains Mono', 'SF Mono', 'Menlo', monospace",cursorBlink:!0,cursorStyle:"bar",scrollback:o,convertEol:!1,smoothScrollDuration:120,theme:n});return new rt(i,h,new d)}get cols(){return this.terminal.cols}get rows(){return this.terminal.rows}write(i){return new Promise(o=>this.terminal.write(i,()=>{this.lastLimit>0&&this.scheduleColumnCheck(this.lastLimit),o()}))}reset(){this.terminal.reset()}scrollToBottom(){this.terminal.scrollToBottom()}scrollToLine(i,o=!1){this.terminal.scrollToLine(Math.max(0,i),o)}scrollLines(i){const o=this.terminal.buffer?.active;this.terminal.scrollLines(i)}isNearScrollbackTop(){return this.terminal.buffer.active.viewportY<=1}viewportY(){return this.terminal.buffer.active.viewportY}baseY(){return this.terminal.buffer.active.baseY}cellHeight(){const o=this.terminal.element?.querySelector(".xterm-screen")?.getBoundingClientRect().height??0,n=this.terminal.rows;return o>0&&n>0?o/n:16}fit(){const i=Nt(this.container);if(i.width<=0||i.height<=0)return!1;this.fitAddon.fit();const o=this.terminal.element?.querySelector(".xterm-viewport"),n=o?Math.max(0,o.offsetWidth-o.clientWidth):0,a=this.terminal.element?.querySelector(".vertical.scrollbar"),d=a?Math.max(0,Math.round(a.getBoundingClientRect().width)):0,h=this.container.getBoundingClientRect().left+i.width-n-d-1;if(this.lastLimit=h,this.webglActive){if(this.shrinkCols>0){const s=Math.max(10,this.terminal.cols-this.shrinkCols);s!==this.terminal.cols&&this.terminal.resize(s,this.terminal.rows)}return!0}return this.shrinkCols=0,this.verifyRounds=0,this.scheduleColumnCheck(h,!0),!0}scheduleColumnCheck(i,o=!1){if(this.lastLimit=i,this.verifyRaf)return;const n=Date.now();!o&&n-this.lastCheckAt<250||(this.lastCheckAt=n,this.verifyRaf=requestAnimationFrame(()=>{this.verifyRaf=0;try{this.recheckColumns(this.lastLimit)&&this.verifyRounds<8?(this.verifyRounds++,this.scheduleColumnCheck(this.lastLimit,!0)):this.verifyRounds=0}catch{}}))}recheckColumns(i){const o=this.terminal.element?.querySelector(".xterm-rows");if(!o)return!1;let n=0;for(const f of Array.from(o.children)){const m=f.children;for(let v=m.length-1;v>=0;v--){const T=m[v];if(!T.textContent)continue;const b=T.getBoundingClientRect().right;b>n&&(n=b);break}}if(n===0)return!1;const a=this.terminal.cols,h=this.terminal.element?.querySelector(".xterm-screen")?.getBoundingClientRect().width??0,s=a>0&&h>0?h/a:0;if(n>i){const f=n-i,m=s>0?Math.min(8,Math.ceil(f/s)):1,v=Math.max(10,a-Math.max(1,m));return v>=a?!1:(this.shrinkCols+=a-v,this.terminal.resize(v,this.terminal.rows),!0)}return!1}focus(){this.terminal.focus()}pasteText(i){this.terminal.paste(i)}input(i){this.terminal.input(i,!1)}onData(i){this.terminal.onData(i),this.terminal.onBinary(i)}onResize(i){this.terminal.onResize(i)}onScroll(i){this.terminal.onScroll(i)}attachCustomKeyEventHandler(i){this.terminal.attachCustomKeyEventHandler(i)}isFocused(){const i=document.activeElement;return i?i===this.container||i===this.terminal.textarea||this.container.contains(i)||!!i.closest?.(".xterm"):!1}getScreenText(){return this.getRowsText(0,this.terminal.rows-1)}getRowsText(i,o){const n=this.terminal.buffer.active,[a,d]=i<=o?[i,o]:[o,i],h=n.viewportY,s=[];for(let f=a;f<=d;f++){const m=n.getLine(h+f);s.push(m?m.translateToString(!0):"")}return s.join(`
2
- `)}selectRows(i,o){const n=this.terminal.buffer.active,[a,d]=i<=o?[i,o]:[o,i];this.terminal.selectLines(n.viewportY+a,n.viewportY+d)}selectCells(i,o,n,a){const d=this.terminal.buffer.active,h=Math.min(o,a),s=Math.max(o,a);if(h===s){const f=Math.min(i,n),m=Math.max(i,n);this.terminal.select(f,d.viewportY+h,m-f+1)}else this.terminal.selectLines(d.viewportY+h,d.viewportY+s)}getCellsText(i,o,n,a){const d=this.terminal.buffer.active,h=Math.min(o,a),s=Math.max(o,a),f=o<a?i:o>a?n:Math.min(i,n),m=o<a?n:o>a?i:Math.max(i,n),v=d.viewportY,T=[];for(let b=h;b<=s;b++){const W=d.getLine(v+b);if(!W){T.push("");continue}const y=b===h?f:0,S=b===s?m:this.terminal.cols-1;let R="";for(let _=y;_<=S;_++){const k=W.getCell(_);k&&(R+=k.getChars())}T.push(R.replace(/\s+$/,""))}return T.join(`
3
- `)}getSelection(){return this.terminal.getSelection()}clearSelection(){this.terminal.clearSelection()}hasSelectionSupport(){return!0}}function Nt(l){const i=l.getBoundingClientRect(),o=window.visualViewport;return o?{width:Math.min(i.width,o.width),height:Math.max(0,Math.min(i.height,o.height-Math.max(0,i.top)))}:i}function _t(l,i,o){return l.innerHTML="",l.classList.add("terminal-pending"),(async()=>{const n=await rt.create(l,o.scrollback,o.theme);let a,d=0,h,s=null,f=0,m=0;const v=.2,T=10,b=.95,W=.04;let y=null,S=null;function R(t){y||(y=document.createElement("div"),y.style.cssText=["position:absolute","left:0","width:40%","padding:10px 0","text-align:center","font:600 14px/1.4 system-ui, -apple-system, sans-serif","color:rgba(255,255,255,0.95)","background:rgba(20,30,50,0.55)","border:1px solid rgba(255,255,255,0.25)","border-radius:10px","pointer-events:none","opacity:0","transition:opacity 0.15s ease","z-index:6"].join(";"),l.appendChild(y)),y.textContent=t?"\u2191 \u4E0A\u7FFB\u4E00\u9875 (PgUp)":"\u2193 \u4E0B\u7FFB\u4E00\u9875 (PgDn)",y.style.top=t?"10%":"auto",y.style.bottom=t?"auto":"10%",y.style.opacity="1",S&&clearTimeout(S),S=setTimeout(()=>{y&&(y.style.opacity="0")},900)}function _(){S&&clearTimeout(S),y&&(y.style.opacity="0")}function k(){f&&(cancelAnimationFrame(f),f=0),m=0}function yt(t){if(k(),Math.abs(t)<v)return;m=Math.max(-T,Math.min(T,t));const e=()=>{if(M){f=0;return}const r=n.cellHeight();let u=r>0?Math.round(m*16/r):m>0?1:-1;u===0&&(u=m>0?1:-1);const x=n.viewportY()-u,E=n.baseY(),H=Math.max(0,Math.min(x,E));if(n.scrollToLine(H,!0),m*=b,H!==x){f=0;return}if(Math.abs(m)<W){f=0;return}f=requestAnimationFrame(e)};f=requestAnimationFrame(e)}let j=0,C="connecting",V=0,F=!1,J=[],P="",M=!1,B=1e3;const wt=location.protocol==="https:"?"wss:":"ws:",st=o.wsBase||"/ws",vt=wt+"//"+location.host+st+"/"+encodeURIComponent(i),xt=(st.replace(/^\/ws/,"")||"")+"/api/session/"+encodeURIComponent(i)+"/upload",bt=/^((?!chrome|android|crios|fxios|edgios).)*safari/i.test(navigator.userAgent);function Tt(){return J.join("")+P}async function Ct(t,e=0){const r=t?n.viewportY():0,u=O(Tt());if(n.reset(),!u){t||n.scrollToBottom();return}await n.write(u),t?n.scrollToLine(e+r):n.scrollToBottom()}function D(t){a?.readyState===WebSocket.OPEN&&a.send(JSON.stringify(t))}function Lt(t){let e;try{e=JSON.parse(t)}catch{C==="live"&&(P+=t,n.write(O(t)));return}if(e.type==="auth.required"){const r=localStorage.getItem("tmux-web-token");r?D({type:"auth.token",token:r}):location.href="/login?returnTo="+encodeURIComponent(location.pathname+location.search);return}if(e.type==="attach_failed"&&typeof e.message=="string"){G=!0,C="dead",n.reset(),n.write(`\r
4
- \x1B[31m`+O(e.message)+`\x1B[0m\r
5
- `).then(()=>{$();try{a?.close()}catch{}});return}if(e.type==="auth.ok"){e.token&&localStorage.setItem("tmux-web-token",e.token),B=1e3,A(),D({type:"resize",cols:n.cols,rows:n.rows}),w();return}if(e.type==="auth.failed"){if(e.permanentLock||e.retryAfterMs&&e.retryAfterMs>6e4){localStorage.removeItem("tmux-web-token"),location.href="/login?error="+encodeURIComponent(e.message);return}return}if(e.type==="snapshot"&&typeof e.data=="string"){const r=ot(O(e.data));J=[r],P="",V=typeof e.lines=="number"?e.lines:o.terminal.initialLines,C="live",n.reset(),A(),D({type:"resize",cols:n.cols,rows:n.rows}),n.write(r).then(()=>n.scrollToBottom());return}if(e.type==="window_changed"&&typeof e.activeIndex=="number"){const r=new URL(location.href);r.searchParams.get("window")!==String(e.activeIndex)&&(r.searchParams.set("window",String(e.activeIndex)),history.replaceState(history.state,"",r)),window.dispatchEvent(new CustomEvent("tmux:windows",{detail:e.windows}));return}if(e.type==="history"&&typeof e.data=="string"){e.lines>0&&e.data?(J.unshift(ot(e.data)),V+=e.lines,Ct(!0,e.lines).finally(()=>{F=!1})):F=!1;return}if(e.type==="data"&&typeof e.data=="string"){const r=ot(O(e.data));if(C==="connecting"){C="live",P=r,n.write(r);return}C==="live"&&(P+=r,n.write(r))}}let G=!1;function at(){if(G)return;let t=vt;const e=localStorage.getItem("tmux-web-token");e&&(t+=(t.includes("?")?"&":"?")+"token="+encodeURIComponent(e)),t+=(t.includes("?")?"&":"?")+"cols="+n.cols+"&rows="+n.rows,a=new WebSocket(t),a.onopen=()=>{C="connecting",V=0,F=!1,J=[],P="",n.reset(),B=1e3},a.onmessage=r=>{typeof r.data=="string"&&Lt(r.data)},a.onclose=()=>{M||(C="connecting",!G&&setTimeout(()=>{B=Math.min(B*2,1e4),!M&&!G&&at()},B))},a.onerror=()=>a?.close()}function I(t){D({type:"input",data:t})}function A(){return n.fit()}function $(){l.classList.remove("terminal-pending")}function w(){d&&cancelAnimationFrame(d),h&&clearTimeout(h),A(),d=requestAnimationFrame(()=>{d=0,A()&&$()}),h=setTimeout(()=>{A()&&$()},120)}function Et(){w(),setTimeout(w,50),setTimeout(w,150),setTimeout(w,300)}function lt(t){return typeof t=="string"&&t.startsWith("image/")}function ct(t){return t?.files?.length?t.files[0]??null:null}function Mt(t){if(!t?.items)return null;for(let e=0;e<t.items.length;e++){const r=t.items[e];if(r?.kind==="file"&&lt(r.type))return r.getAsFile()}return null}async function St(t){const e=new FormData,r=t instanceof File&&t.name?t.name:"upload";e.append("file",t,r);const u=localStorage.getItem("tmux-web-token"),c={};u&&(c.Authorization="Bearer "+u);const x=await fetch(xt,{method:"POST",body:e,headers:c});if(!x.ok){let H="upload failed";try{const gt=await x.json();gt.error&&(H=gt.error)}catch{}throw new Error(H)}const E=await x.json();if(!E.path)throw new Error("no path in response");return E.path}async function et(t){try{const e=await St(t);I(e)}catch{}}n.onData(t=>I(t)),n.onResize(({cols:t,rows:e})=>D({type:"resize",cols:t,rows:e})),n.onScroll(()=>{C!=="live"||F||!n.isNearScrollbackTop()||(F=!0,D({type:"load_history",before:V}))});let z=!1,K=!1,p=null,g=null;const U=document.createElement("div");U.className="terminal-copy-banner",U.innerHTML='<strong>Copy mode</strong><span class="hint">drag to copy \xB7 Esc exits</span>',U.hidden=!0,l.appendChild(U);const L=document.createElement("div");L.className="terminal-copy-banner terminal-copy-toast",L.textContent="Copied",L.hidden=!0,l.appendChild(L);function ut(t,e){const r=l.querySelector(".xterm-screen, canvas"),c=(r&&r.getBoundingClientRect().width>0?r:l).getBoundingClientRect(),x=c.height>0&&n.rows>0?c.height/n.rows:18,E=c.width>0&&n.cols>0?c.width/n.cols:9;return{row:Math.max(0,Math.min(n.rows-1,Math.floor((e-c.top)/x))),col:Math.max(0,Math.min(n.cols-1,Math.floor((t-c.left)/E)))}}async function Q(t){if(!t)return;try{if(navigator.clipboard?.writeText){await navigator.clipboard.writeText(t);return}}catch{}const e=document.createElement("textarea");e.value=t,e.style.position="fixed",e.style.opacity="0",e.style.pointerEvents="none",document.body.appendChild(e),e.focus(),e.select();try{document.execCommand("copy")}catch{}e.remove()}let X;function Z(){L.hidden=!1,X&&clearTimeout(X),X=setTimeout(()=>{L.hidden=!0},1e3)}function Y(t){z=t,U.hidden=!t,l.classList.toggle("terminal-copy-mode-active",t),t&&n.focus()}function ft(){Y(!z)}function kt(t){M||t.button!==0||K||(z||t.shiftKey)&&(t.preventDefault(),t.stopPropagation(),K=!0,p=ut(t.clientX,t.clientY),g=p,n.selectCells(p.col,p.row,g.col,g.row),document.addEventListener("mousemove",nt,!0),document.addEventListener("mouseup",it,!0))}function nt(t){M||!K||!p||(t.preventDefault(),t.stopPropagation(),g=ut(t.clientX,t.clientY),n.selectCells(p.col,p.row,g.col,g.row))}function it(t){if(M||!K||!p||!g)return;t.preventDefault(),t.stopPropagation(),document.removeEventListener("mousemove",nt,!0),document.removeEventListener("mouseup",it,!0),K=!1;const e=n.getCellsText(p.col,p.row,g.col,g.row);p=null,g=null,n.clearSelection(),Y(!1),e&&(L.textContent="\u5DF2\u590D\u5236",Q(e).then(Z)),n.focus()}l.addEventListener("mousedown",kt,!0),document.addEventListener("keydown",Dt,!0);function Dt(t){if(!(M||!n.isFocused()||t.defaultPrevented||t.isComposing)){if(z){if(t.key==="Escape"){t.preventDefault(),t.stopPropagation(),p=null,g=null,n.clearSelection(),Y(!1);return}if(t.key==="Enter"||(t.ctrlKey||t.metaKey)&&t.code==="KeyC"){t.preventDefault(),t.stopPropagation(),Q(n.getScreenText()).then(Z),Y(!1);return}}if(t.altKey&&t.code==="KeyC"&&!t.ctrlKey&&!t.metaKey){if(t.preventDefault(),t.stopPropagation(),p&&g){const e=n.getCellsText(p.col,p.row,g.col,g.row);p=null,g=null,n.clearSelection(),Y(!1),e&&(L.textContent="Copied",Q(e).then(Z))}else{const e=n.getSelection();e?(n.clearSelection(),L.textContent="Copied",Q(e).then(Z)):ft()}return}if((t.ctrlKey||t.metaKey)&&t.code==="KeyV"){t.preventDefault(),t.stopPropagation(),(async()=>{try{if(navigator.clipboard?.read){const e=await navigator.clipboard.read();for(const r of e)for(const u of r.types)if(lt(u)){const c=await r.getType(u);await et(c);return}}}catch{}try{const e=await navigator.clipboard?.readText();e&&n.pasteText(dt(e))}catch{}})();return}}}let tt=0;function dt(t){return t.split(`\r
1
+ const Oe=/\x1b\](?:10|11|110|111|104)(?:;[^\x07\x1b]*)?\x1b?(?:\\|\x07)/g;function ie(a){return a.replace(/\x1b\[\?1049[hl]/g,"")}function O(a){return a.replace(Oe,"")}let N;function Ne(){return N||(document.querySelector("link[data-tmux-web-xterm-css]")?N=Promise.resolve():(N=new Promise(o=>{const r=document.createElement("link");r.rel="stylesheet",r.href="/assets/xterm.css",r.setAttribute("data-tmux-web-xterm-css",""),r.addEventListener("load",()=>o(),{once:!0}),r.addEventListener("error",()=>o(),{once:!0}),document.head.appendChild(r)}),N))}class re{terminal;fitAddon;container;webglActive=!1;webglAddon=null;constructor(o,r,n){this.container=o,this.terminal=r,this.fitAddon=n,this.terminal.loadAddon(this.fitAddon),this.terminal.open(o),this.enableWebglRenderer()}enableWebglRenderer(){import("@xterm/addon-webgl").then(({WebglAddon:o})=>{const r=new o;r.onContextLoss(()=>{this.webglActive=!1,this.webglAddon=null;try{r.dispose()}catch{}this.fit()});try{this.terminal.loadAddon(r)}catch{return}this.webglAddon=r,this.webglActive=!0,this.fit()}).catch(()=>{})}static async create(o,r,n){const[{Terminal:l},{FitAddon:f}]=await Promise.all([import("@xterm/xterm"),import("@xterm/addon-fit"),Ne()]),h=new l({fontSize:14,fontFamily:"'JetBrains Mono', 'SF Mono', 'Menlo', monospace",cursorBlink:!0,cursorStyle:"bar",scrollback:r,convertEol:!1,smoothScrollDuration:120,theme:n});return new re(o,h,new f)}get cols(){return this.terminal.cols}get rows(){return this.terminal.rows}write(o){return new Promise(r=>this.terminal.write(o,r))}reset(){this.terminal.reset()}scrollToBottom(){this.terminal.scrollToBottom()}scrollToLine(o,r=!1){this.terminal.scrollToLine(Math.max(0,o),r)}scrollLines(o){const r=this.terminal.buffer?.active;this.terminal.scrollLines(o)}isNearScrollbackTop(){return this.terminal.buffer.active.viewportY<=1}viewportY(){return this.terminal.buffer.active.viewportY}baseY(){return this.terminal.buffer.active.baseY}cellHeight(){const r=this.terminal.element?.querySelector(".xterm-screen")?.getBoundingClientRect().height??0,n=this.terminal.rows;return r>0&&n>0?r/n:16}fit(){const o=_e(this.container);return o.width<=0||o.height<=0?!1:(this.fitAddon.fit(),!0)}focus(){this.terminal.focus()}pasteText(o){this.terminal.paste(o)}input(o){this.terminal.input(o,!1)}onData(o){this.terminal.onData(o),this.terminal.onBinary(o)}onResize(o){this.terminal.onResize(o)}onScroll(o){this.terminal.onScroll(o)}attachCustomKeyEventHandler(o){this.terminal.attachCustomKeyEventHandler(o)}isFocused(){const o=document.activeElement;return o?o===this.container||o===this.terminal.textarea||this.container.contains(o)||!!o.closest?.(".xterm"):!1}getScreenText(){return this.getRowsText(0,this.terminal.rows-1)}getRowsText(o,r){const n=this.terminal.buffer.active,[l,f]=o<=r?[o,r]:[r,o],h=n.viewportY,s=[];for(let d=l;d<=f;d++){const g=n.getLine(h+d);s.push(g?g.translateToString(!0):"")}return s.join(`
2
+ `)}selectRows(o,r){const n=this.terminal.buffer.active,[l,f]=o<=r?[o,r]:[r,o];this.terminal.selectLines(n.viewportY+l,n.viewportY+f)}selectCells(o,r,n,l){const f=this.terminal.buffer.active,h=Math.min(r,l),s=Math.max(r,l);if(h===s){const d=Math.min(o,n),g=Math.max(o,n);this.terminal.select(d,f.viewportY+h,g-d+1)}else this.terminal.selectLines(f.viewportY+h,f.viewportY+s)}getCellsText(o,r,n,l){const f=this.terminal.buffer.active,h=Math.min(r,l),s=Math.max(r,l),d=r<l?o:r>l?n:Math.min(o,n),g=r<l?n:r>l?o:Math.max(o,n),ee=f.viewportY,P=[];for(let L=h;L<=s;L++){const _=f.getLine(ee+L);if(!_){P.push("");continue}const w=L===h?d:0,C=L===s?g:this.terminal.cols-1;let Y="";for(let j=w;j<=C;j++){const M=_.getCell(j);M&&(Y+=M.getChars())}P.push(Y.replace(/\s+$/,""))}return P.join(`
3
+ `)}getSelection(){return this.terminal.getSelection()}clearSelection(){this.terminal.clearSelection()}hasSelectionSupport(){return!0}}function _e(a){const o=a.getBoundingClientRect(),r=window.visualViewport;return r?{width:Math.min(o.width,r.width),height:Math.max(0,Math.min(o.height,r.height-Math.max(0,o.top)))}:o}function qe(a,o,r){return a.innerHTML="",a.classList.add("terminal-pending"),(async()=>{const n=await re.create(a,r.scrollback,r.theme);let l,f=0,h,s=null,d=0,g=0;const ee=.2,P=10,L=.95,_=.04;let w=null,C=null;function Y(e){w||(w=document.createElement("div"),w.style.cssText=["position:absolute","left:0","width:40%","padding:10px 0","text-align:center","font:600 14px/1.4 system-ui, -apple-system, sans-serif","color:rgba(255,255,255,0.95)","background:rgba(20,30,50,0.55)","border:1px solid rgba(255,255,255,0.25)","border-radius:10px","pointer-events:none","opacity:0","transition:opacity 0.15s ease","z-index:6"].join(";"),a.appendChild(w)),w.textContent=e?"\u2191 \u4E0A\u7FFB\u4E00\u9875 (PgUp)":"\u2193 \u4E0B\u7FFB\u4E00\u9875 (PgDn)",w.style.top=e?"10%":"auto",w.style.bottom=e?"auto":"10%",w.style.opacity="1",C&&clearTimeout(C),C=setTimeout(()=>{w&&(w.style.opacity="0")},900)}function j(){C&&clearTimeout(C),w&&(w.style.opacity="0")}function M(){d&&(cancelAnimationFrame(d),d=0),g=0}function we(e){if(M(),Math.abs(e)<ee)return;g=Math.max(-P,Math.min(P,e));const t=()=>{if(E){d=0;return}const i=n.cellHeight();let u=i>0?Math.round(g*16/i):g>0?1:-1;u===0&&(u=g>0?1:-1);const v=n.viewportY()-u,x=n.baseY(),R=Math.max(0,Math.min(v,x));if(n.scrollToLine(R,!0),g*=L,R!==v){d=0;return}if(Math.abs(g)<_){d=0;return}d=requestAnimationFrame(t)};d=requestAnimationFrame(t)}let q=0,b="connecting",V=0,F=!1,W=[],k="",E=!1,z=1e3;const ye=location.protocol==="https:"?"wss:":"ws:",se=r.wsBase||"/ws",ve=ye+"//"+location.host+se+"/"+encodeURIComponent(o),be=(se.replace(/^\/ws/,"")||"")+"/api/session/"+encodeURIComponent(o)+"/upload",Te=/^((?!chrome|android|crios|fxios|edgios).)*safari/i.test(navigator.userAgent);function xe(){return W.join("")+k}async function Ee(e,t=0){const i=e?n.viewportY():0,u=O(xe());if(n.reset(),!u){e||n.scrollToBottom();return}await n.write(u),e?n.scrollToLine(t+i):n.scrollToBottom()}function S(e){l?.readyState===WebSocket.OPEN&&l.send(JSON.stringify(e))}function Le(e){let t;try{t=JSON.parse(e)}catch{b==="live"&&(k+=e,n.write(O(e)));return}if(t.type==="auth.required"){const i=localStorage.getItem("tmux-web-token");i?S({type:"auth.token",token:i}):location.href="/login?returnTo="+encodeURIComponent(location.pathname+location.search);return}if(t.type==="attach_failed"&&typeof t.message=="string"){J=!0,b="dead",n.reset(),n.write(`\r
4
+ \x1B[31m`+O(t.message)+`\x1B[0m\r
5
+ `).then(()=>{G();try{l?.close()}catch{}});return}if(t.type==="auth.ok"){t.token&&localStorage.setItem("tmux-web-token",t.token),z=1e3,D(),S({type:"resize",cols:n.cols,rows:n.rows}),y();return}if(t.type==="auth.failed"){if(t.permanentLock||t.retryAfterMs&&t.retryAfterMs>6e4){localStorage.removeItem("tmux-web-token"),location.href="/login?error="+encodeURIComponent(t.message);return}return}if(t.type==="snapshot"&&typeof t.data=="string"){const i=ie(O(t.data));W=[i],k="",V=typeof t.lines=="number"?t.lines:r.terminal.initialLines,b="live",n.reset(),D(),S({type:"resize",cols:n.cols,rows:n.rows}),n.write(i).then(()=>n.scrollToBottom());return}if(t.type==="window_changed"&&typeof t.activeIndex=="number"){const i=new URL(location.href);i.searchParams.get("window")!==String(t.activeIndex)&&(i.searchParams.set("window",String(t.activeIndex)),history.replaceState(history.state,"",i)),window.dispatchEvent(new CustomEvent("tmux:windows",{detail:t.windows}));return}if(t.type==="history"&&typeof t.data=="string"){t.lines>0&&t.data?(W.unshift(ie(t.data)),V+=t.lines,Ee(!0,t.lines).finally(()=>{F=!1})):F=!1;return}if(t.type==="data"&&typeof t.data=="string"){const i=ie(O(t.data));if(b==="connecting"){b="live",k=i,n.write(i);return}b==="live"&&(k+=i,n.write(i))}}let J=!1;function ae(){if(J)return;let e=ve;const t=localStorage.getItem("tmux-web-token");t&&(e+=(e.includes("?")?"&":"?")+"token="+encodeURIComponent(t)),e+=(e.includes("?")?"&":"?")+"cols="+n.cols+"&rows="+n.rows,l=new WebSocket(e),l.onopen=()=>{b="connecting",V=0,F=!1,W=[],k="",n.reset(),z=1e3},l.onmessage=i=>{typeof i.data=="string"&&Le(i.data)},l.onclose=()=>{E||(b="connecting",!J&&setTimeout(()=>{z=Math.min(z*2,1e4),!E&&!J&&ae()},z))},l.onerror=()=>l?.close()}function I(e){S({type:"input",data:e})}function D(){return n.fit()}function G(){a.classList.remove("terminal-pending")}function y(){f&&cancelAnimationFrame(f),h&&clearTimeout(h),D(),f=requestAnimationFrame(()=>{f=0,D()&&G()}),h=setTimeout(()=>{D()&&G()},120)}function Ce(){y(),setTimeout(y,50),setTimeout(y,150),setTimeout(y,300)}function le(e){return typeof e=="string"&&e.startsWith("image/")}function ce(e){return e?.files?.length?e.files[0]??null:null}function Me(e){if(!e?.items)return null;for(let t=0;t<e.items.length;t++){const i=e.items[t];if(i?.kind==="file"&&le(i.type))return i.getAsFile()}return null}async function Se(e){const t=new FormData,i=e instanceof File&&e.name?e.name:"upload";t.append("file",e,i);const u=localStorage.getItem("tmux-web-token"),c={};u&&(c.Authorization="Bearer "+u);const v=await fetch(be,{method:"POST",body:t,headers:c});if(!v.ok){let R="upload failed";try{const ge=await v.json();ge.error&&(R=ge.error)}catch{}throw new Error(R)}const x=await v.json();if(!x.path)throw new Error("no path in response");return x.path}async function te(e){try{const t=await Se(e);I(t)}catch{}}n.onData(e=>I(e)),n.onResize(({cols:e,rows:t})=>S({type:"resize",cols:e,rows:t})),n.onScroll(()=>{b!=="live"||F||!n.isNearScrollbackTop()||(F=!0,S({type:"load_history",before:V}))});let B=!1,K=!1,m=null,p=null;const U=document.createElement("div");U.className="terminal-copy-banner",U.innerHTML='<strong>Copy mode</strong><span class="hint">drag to copy \xB7 Esc exits</span>',U.hidden=!0,a.appendChild(U);const T=document.createElement("div");T.className="terminal-copy-banner terminal-copy-toast",T.textContent="Copied",T.hidden=!0,a.appendChild(T);function ue(e,t){const i=a.querySelector(".xterm-screen, canvas"),c=(i&&i.getBoundingClientRect().width>0?i:a).getBoundingClientRect(),v=c.height>0&&n.rows>0?c.height/n.rows:18,x=c.width>0&&n.cols>0?c.width/n.cols:9;return{row:Math.max(0,Math.min(n.rows-1,Math.floor((t-c.top)/v))),col:Math.max(0,Math.min(n.cols-1,Math.floor((e-c.left)/x)))}}async function $(e){if(!e)return;try{if(navigator.clipboard?.writeText){await navigator.clipboard.writeText(e);return}}catch{}const t=document.createElement("textarea");t.value=e,t.style.position="fixed",t.style.opacity="0",t.style.pointerEvents="none",document.body.appendChild(t),t.focus(),t.select();try{document.execCommand("copy")}catch{}t.remove()}let X;function Q(){T.hidden=!1,X&&clearTimeout(X),X=setTimeout(()=>{T.hidden=!0},1e3)}function A(e){B=e,U.hidden=!e,a.classList.toggle("terminal-copy-mode-active",e),e&&n.focus()}function fe(){A(!B)}function De(e){E||e.button!==0||K||(B||e.shiftKey)&&(e.preventDefault(),e.stopPropagation(),K=!0,m=ue(e.clientX,e.clientY),p=m,n.selectCells(m.col,m.row,p.col,p.row),document.addEventListener("mousemove",ne,!0),document.addEventListener("mouseup",oe,!0))}function ne(e){E||!K||!m||(e.preventDefault(),e.stopPropagation(),p=ue(e.clientX,e.clientY),n.selectCells(m.col,m.row,p.col,p.row))}function oe(e){if(E||!K||!m||!p)return;e.preventDefault(),e.stopPropagation(),document.removeEventListener("mousemove",ne,!0),document.removeEventListener("mouseup",oe,!0),K=!1;const t=n.getCellsText(m.col,m.row,p.col,p.row);m=null,p=null,n.clearSelection(),A(!1),t&&(T.textContent="\u5DF2\u590D\u5236",$(t).then(Q)),n.focus()}a.addEventListener("mousedown",De,!0),document.addEventListener("keydown",Pe,!0);function Pe(e){if(!(E||!n.isFocused()||e.defaultPrevented||e.isComposing)){if(B){if(e.key==="Escape"){e.preventDefault(),e.stopPropagation(),m=null,p=null,n.clearSelection(),A(!1);return}if(e.key==="Enter"||(e.ctrlKey||e.metaKey)&&e.code==="KeyC"){e.preventDefault(),e.stopPropagation(),$(n.getScreenText()).then(Q),A(!1);return}}if(e.altKey&&e.code==="KeyC"&&!e.ctrlKey&&!e.metaKey){if(e.preventDefault(),e.stopPropagation(),m&&p){const t=n.getCellsText(m.col,m.row,p.col,p.row);m=null,p=null,n.clearSelection(),A(!1),t&&(T.textContent="Copied",$(t).then(Q))}else{const t=n.getSelection();t?(n.clearSelection(),T.textContent="Copied",$(t).then(Q)):fe()}return}if((e.ctrlKey||e.metaKey)&&e.code==="KeyV"){e.preventDefault(),e.stopPropagation(),(async()=>{try{if(navigator.clipboard?.read){const t=await navigator.clipboard.read();for(const i of t)for(const u of i.types)if(le(u)){const c=await i.getType(u);await te(c);return}}}catch{}try{const t=await navigator.clipboard?.readText();t&&n.pasteText(de(t))}catch{}})();return}}}let Z=0;function de(e){return e.split(`\r
6
6
  `).join(`
7
7
  `).split(`
8
- `).join("\r")}async function At(t){const e=Mt(t.clipboardData);if(e){t.preventDefault(),t.stopPropagation();const c=Date.now();if(c-tt<50)return;tt=c,await et(e);return}const r=t.clipboardData?.getData("text/plain");if(!r)return;t.preventDefault(),t.stopPropagation();const u=Date.now();u-tt<50||(tt=u,n.pasteText(dt(r)))}let q=0;function Pt(t){t.preventDefault(),q++,ct(t.dataTransfer)&&l.classList.add("terminal-drag-over")}function It(t){t.preventDefault(),t.dataTransfer&&(t.dataTransfer.dropEffect="copy")}function Yt(t){t.preventDefault(),q--,q<=0&&(q=0,l.classList.remove("terminal-drag-over"))}async function Rt(t){t.preventDefault(),q=0,l.classList.remove("terminal-drag-over");const e=ct(t.dataTransfer);e&&await et(e)}function ht(t){!bt||t.key!=="Escape"||z||t.defaultPrevented||t.repeat||t.metaKey||t.ctrlKey||t.altKey||n.isFocused()&&(t.preventDefault(),t.stopPropagation(),I("\x1B"))}l.addEventListener("paste",At),l.addEventListener("dragenter",Pt),l.addEventListener("dragover",It),l.addEventListener("dragleave",Yt),l.addEventListener("drop",Rt),document.addEventListener("keydown",ht,!0);function Ft(t){if(t.touches.length!==1){s=null;return}const e=t.touches[0];if(!e)return;k();const r=l.getBoundingClientRect(),u=e.clientX-r.left<r.width*.4?"tui":"history",c=e.clientY-r.top<r.height*.5;s={startX:e.clientX,startY:e.clientY,lastX:e.clientX,lastY:e.clientY,lastT:performance.now(),velocity:0,scrolling:!1,zone:u,tuiUp:c,sent:!1},t.stopPropagation()}function Bt(t){if(!s||t.touches.length!==1)return;const e=t.touches[0];if(!e)return;const r=e.clientY-s.startY,u=e.clientX-s.startX;if(!s.scrolling){if(Math.abs(r)<8||Math.abs(r)<Math.abs(u))return;s.scrolling=!0,j=Date.now()+500}t.preventDefault(),t.stopPropagation();const c=performance.now(),x=e.clientY-s.lastY;if(s.zone==="tui"){s.sent||(s.sent=!0,I(s.tuiUp?"\x1B[5~":"\x1B[6~"),R(s.tuiUp)),s.lastX=e.clientX,s.lastY=e.clientY,s.lastT=c;return}const E=c-s.lastT;E>0&&(s.velocity=x/E),Xt(-x),s.lastX=e.clientX,s.lastY=e.clientY,s.lastT=c}function zt(t){if(!s)return;const e=s.scrolling,r=s.zone,u=s.tuiUp,c=s.velocity;if(s=null,t.stopPropagation(),r==="tui"){e||(I(u?"\x1B[5~":"\x1B[6~"),R(u),j=Date.now()+500,t.preventDefault());return}if(!e){n.focus();return}j=Date.now()+500,t.preventDefault(),c&&yt(c)}function Kt(t){s=null,k(),t.stopPropagation()}function Ut(t){t.pointerType==="touch"&&Date.now()<j&&(t.preventDefault(),t.stopPropagation())}function Xt(t){const e=n.cellHeight();let r=e>0?Math.round(t/e):t>0?1:-1;r===0&&(r=t>0?1:-1),n.scrollLines(r)}l.addEventListener("touchstart",Ft,{passive:!0,capture:!0}),l.addEventListener("touchmove",Bt,{passive:!1,capture:!0}),l.addEventListener("touchend",zt,{passive:!1,capture:!0}),l.addEventListener("touchcancel",Kt,{passive:!0,capture:!0}),l.addEventListener("pointerup",Ut,!0);function mt(){w()}window.addEventListener("resize",mt),window.visualViewport?.addEventListener("resize",w),window.visualViewport?.addEventListener("scroll",w);const pt=new ResizeObserver(()=>w());pt.observe(l),document.fonts?.ready.then(()=>{w(),setTimeout(w,50),setTimeout(w,200)}),l.addEventListener("focusin",Et,!0);async function qt(){if(document.fonts?.ready)try{await Promise.race([document.fonts.ready,new Promise(t=>setTimeout(t,1e3))])}catch{}}return requestAnimationFrame(()=>{A()&&$(),(async()=>(await qt(),A()&&D({type:"resize",cols:n.cols,rows:n.rows}),at(),w()))()}),{destroy(){if(M=!0,k(),Y(!1),X&&clearTimeout(X),document.removeEventListener("mousemove",nt,!0),document.removeEventListener("mouseup",it,!0),a){try{a.close(1e3,"session switch")}catch{}a=void 0}l.innerHTML="",l.classList.remove("terminal-pending"),window.removeEventListener("resize",mt),pt.disconnect(),document.removeEventListener("keydown",ht,!0)},focus(){n.focus()},sendInput(t){I(t)},toggleCopyMode(){ft()}}})()}export{_t as initTerminal,ot as stripAltScreenSequences};
8
+ `).join("\r")}async function ke(e){const t=Me(e.clipboardData);if(t){e.preventDefault(),e.stopPropagation();const c=Date.now();if(c-Z<50)return;Z=c,await te(t);return}const i=e.clipboardData?.getData("text/plain");if(!i)return;e.preventDefault(),e.stopPropagation();const u=Date.now();u-Z<50||(Z=u,n.pasteText(de(i)))}let H=0;function Ie(e){e.preventDefault(),H++,ce(e.dataTransfer)&&a.classList.add("terminal-drag-over")}function Ae(e){e.preventDefault(),e.dataTransfer&&(e.dataTransfer.dropEffect="copy")}function Ye(e){e.preventDefault(),H--,H<=0&&(H=0,a.classList.remove("terminal-drag-over"))}async function Fe(e){e.preventDefault(),H=0,a.classList.remove("terminal-drag-over");const t=ce(e.dataTransfer);t&&await te(t)}function me(e){!Te||e.key!=="Escape"||B||e.defaultPrevented||e.repeat||e.metaKey||e.ctrlKey||e.altKey||n.isFocused()&&(e.preventDefault(),e.stopPropagation(),I("\x1B"))}a.addEventListener("paste",ke),a.addEventListener("dragenter",Ie),a.addEventListener("dragover",Ae),a.addEventListener("dragleave",Ye),a.addEventListener("drop",Fe),document.addEventListener("keydown",me,!0);function ze(e){if(e.touches.length!==1){s=null;return}const t=e.touches[0];if(!t)return;M();const i=a.getBoundingClientRect(),u=t.clientX-i.left<i.width*.4?"tui":"history",c=t.clientY-i.top<i.height*.5;s={startX:t.clientX,startY:t.clientY,lastX:t.clientX,lastY:t.clientY,lastT:performance.now(),velocity:0,scrolling:!1,zone:u,tuiUp:c,sent:!1},e.stopPropagation()}function Be(e){if(!s||e.touches.length!==1)return;const t=e.touches[0];if(!t)return;const i=t.clientY-s.startY,u=t.clientX-s.startX;if(!s.scrolling){if(Math.abs(i)<8||Math.abs(i)<Math.abs(u))return;s.scrolling=!0,q=Date.now()+500}e.preventDefault(),e.stopPropagation();const c=performance.now(),v=t.clientY-s.lastY;if(s.zone==="tui"){s.sent||(s.sent=!0,I(s.tuiUp?"\x1B[5~":"\x1B[6~"),Y(s.tuiUp)),s.lastX=t.clientX,s.lastY=t.clientY,s.lastT=c;return}const x=c-s.lastT;x>0&&(s.velocity=v/x),He(-v),s.lastX=t.clientX,s.lastY=t.clientY,s.lastT=c}function Ke(e){if(!s)return;const t=s.scrolling,i=s.zone,u=s.tuiUp,c=s.velocity;if(s=null,e.stopPropagation(),i==="tui"){t||(I(u?"\x1B[5~":"\x1B[6~"),Y(u),q=Date.now()+500,e.preventDefault());return}if(!t){n.focus();return}q=Date.now()+500,e.preventDefault(),c&&we(c)}function Ue(e){s=null,M(),e.stopPropagation()}function Xe(e){e.pointerType==="touch"&&Date.now()<q&&(e.preventDefault(),e.stopPropagation())}function He(e){const t=n.cellHeight();let i=t>0?Math.round(e/t):e>0?1:-1;i===0&&(i=e>0?1:-1),n.scrollLines(i)}a.addEventListener("touchstart",ze,{passive:!0,capture:!0}),a.addEventListener("touchmove",Be,{passive:!1,capture:!0}),a.addEventListener("touchend",Ke,{passive:!1,capture:!0}),a.addEventListener("touchcancel",Ue,{passive:!0,capture:!0}),a.addEventListener("pointerup",Xe,!0);function pe(){y()}window.addEventListener("resize",pe),window.visualViewport?.addEventListener("resize",y),window.visualViewport?.addEventListener("scroll",y);const he=new ResizeObserver(()=>y());he.observe(a),document.fonts?.ready.then(()=>{y(),setTimeout(y,50),setTimeout(y,200)}),a.addEventListener("focusin",Ce,!0);async function Re(){if(document.fonts?.ready)try{await Promise.race([document.fonts.ready,new Promise(e=>setTimeout(e,1e3))])}catch{}}return requestAnimationFrame(()=>{D()&&G(),(async()=>(await Re(),D()&&S({type:"resize",cols:n.cols,rows:n.rows}),ae(),y()))()}),{destroy(){if(E=!0,M(),A(!1),X&&clearTimeout(X),document.removeEventListener("mousemove",ne,!0),document.removeEventListener("mouseup",oe,!0),l){try{l.close(1e3,"session switch")}catch{}l=void 0}a.innerHTML="",a.classList.remove("terminal-pending"),window.removeEventListener("resize",pe),he.disconnect(),document.removeEventListener("keydown",me,!0)},focus(){n.focus()},sendInput(e){I(e)},toggleCopyMode(){fe()}}})()}export{qe as initTerminal,ie as stripAltScreenSequences};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tmux-weblink",
3
- "version": "2.2.31",
3
+ "version": "2.2.33",
4
4
  "description": "Access your tmux sessions from the browser. A continuation of tmux-web and persalink.",
5
5
  "type": "module",
6
6
  "bin": {