tmux-weblink 2.0.23 → 2.0.24

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,38 +1,38 @@
1
- var Yt=/\x1b\](?:10|11|110|111|104)(?:;[^\x07\x1b]*)?\x1b?(?:\\|\x07)/g;function ee(e){return e.replace(Yt,"")}var ge;function jt(){return ge||(document.querySelector("link[data-tmux-web-xterm-css]")?ge=Promise.resolve():(ge=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)}),ge))}var Ft=class yt{terminal;fitAddon;container;constructor(t,s,i){this.container=t,this.terminal=s,this.fitAddon=i,this.terminal.loadAddon(this.fitAddon),this.terminal.open(t)}static async create(t,s,i){let[{Terminal:o},{FitAddon:r}]=await Promise.all([import("./xterm-BXEES47M.js"),import("./addon-fit-D5N335P2.js"),jt()]),c=new o({fontSize:14,fontFamily:"'JetBrains Mono', 'SF Mono', 'Menlo', monospace",cursorBlink:!0,cursorStyle:"bar",scrollback:s,convertEol:!1,theme:i});return new yt(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){this.terminal.scrollToLine(Math.max(0,t))}isNearScrollbackTop(){return this.terminal.buffer.active.viewportY<=1}viewportY(){return this.terminal.buffer.active.viewportY}baseY(){return this.terminal.buffer.active.baseY}fit(){let t=Wt(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 i=this.terminal.buffer.active,[o,r]=t<=s?[t,s]:[s,t],c=i.viewportY,l=[];for(let p=o;p<=r;p++){let u=i.getLine(c+p);l.push(u?u.translateToString(!0):"")}return l.join(`
2
- `)}selectRows(t,s){let i=this.terminal.buffer.active,[o,r]=t<=s?[t,s]:[s,t];this.terminal.selectLines(i.viewportY+o,i.viewportY+r)}selectCells(t,s,i,o){let r=this.terminal.buffer.active,c=Math.min(s,o),l=Math.max(s,o);if(c===l){let p=Math.min(t,i),u=Math.max(t,i);this.terminal.select(p,r.viewportY+c,u-p+1)}else this.terminal.selectLines(r.viewportY+c,r.viewportY+l)}getCellsText(t,s,i,o){let r=this.terminal.buffer.active,c=Math.min(s,o),l=Math.max(s,o),p=s<o?t:s>o?i:Math.min(t,i),u=s<o?i:s>o?t:Math.max(t,i),M=r.viewportY,R=[];for(let B=c;B<=l;B++){let D=r.getLine(M+B);if(!D){R.push("");continue}let H=B===c?p:0,z=B===l?u:this.terminal.cols-1,de="";for(let q=H;q<=z;q++){let pe=D.getCell(q);pe&&(de+=pe.getChars())}R.push(de.replace(/\s+$/,""))}return R.join(`
3
- `)}getSelection(){return this.terminal.getSelection()}clearSelection(){this.terminal.clearSelection()}hasSelectionSupport(){return!0}};function Wt(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 Ut(e,t,s){return e.innerHTML="",e.classList.add("terminal-pending"),(async()=>{let i=await Ft.create(e,s.scrollback,s.theme),o,r=0,c,l=null,p=0,u="connecting",M=0,R=!1,B=[],D="",H=!1,z=1e3,de=location.protocol==="https:"?"wss:":"ws:",q=s.wsBase||"/ws",pe=de+"//"+location.host+q+"/"+encodeURIComponent(t),gt="/api/session/"+encodeURIComponent(t)+"/upload",wt=/^((?!chrome|android|crios|fxios|edgios).)*safari/i.test(navigator.userAgent);function bt(){return B.join("")+D}async function Lt(n,a=0){let d=n?i.viewportY():0,h=n?i.baseY():0,C=ee(bt());if(i.reset(),!C){n||i.scrollToBottom();return}await i.write(C),n?i.scrollToLine(h+d+a):i.scrollToBottom()}function _(n){o?.readyState===WebSocket.OPEN&&o.send(JSON.stringify(n))}function Et(n){let a;try{a=JSON.parse(n)}catch{u==="live"&&(D+=n,i.write(ee(n)));return}if(a.type==="auth.required"){let d=localStorage.getItem("tmux-web-token");d?_({type:"auth.token",token:d}):location.href="/login?returnTo="+encodeURIComponent(location.pathname+location.search);return}if(a.type==="attach_failed"&&typeof a.message=="string"){ue=!0,u="dead",i.reset(),i.write(`\r
4
- \x1B[31m`+ee(a.message)+`\x1B[0m\r
5
- `).then(()=>{me();try{o?.close()}catch{}});return}if(a.type==="auth.ok"){a.token&&localStorage.setItem("tmux-web-token",a.token),z=1e3,Y(),_({type:"resize",cols:i.cols,rows:i.rows}),k();return}if(a.type==="auth.failed"){if(a.permanentLock||a.retryAfterMs&&a.retryAfterMs>6e4){localStorage.removeItem("tmux-web-token"),location.href="/login?error="+encodeURIComponent(a.message);return}return}if(a.type==="snapshot"&&typeof a.data=="string"){let d=ee(a.data);B=[d],D="",M=typeof a.lines=="number"?a.lines:s.terminal.initialLines,u="live",i.reset(),Y(),_({type:"resize",cols:i.cols,rows:i.rows}),i.write(d).then(()=>i.scrollToBottom());return}if(a.type==="window_changed"&&typeof a.activeIndex=="number"){let d=new URL(location.href);d.searchParams.get("window")!==String(a.activeIndex)&&(d.searchParams.set("window",String(a.activeIndex)),history.replaceState(history.state,"",d)),window.dispatchEvent(new CustomEvent("tmux:windows",{detail:a.windows}));return}if(a.type==="history"&&typeof a.data=="string"){R=!1,a.lines>0&&a.data&&(B.unshift(a.data),M+=a.lines,Lt(!0,a.lines));return}if(a.type==="data"&&typeof a.data=="string"){let d=ee(a.data);if(u==="connecting"){u="live",D=d,i.write(d);return}u==="live"&&(D+=d,i.write(d))}}let ue=!1;function Ye(){if(ue)return;let n=pe,a=localStorage.getItem("tmux-web-token");a&&(n+=(n.includes("?")?"&":"?")+"token="+encodeURIComponent(a)),n+=(n.includes("?")?"&":"?")+"cols="+i.cols+"&rows="+i.rows,o=new WebSocket(n),o.onopen=()=>{u="connecting",M=0,R=!1,B=[],D="",i.reset(),z=1e3},o.onmessage=d=>{typeof d.data=="string"&&Et(d.data)},o.onclose=()=>{H||(u="connecting",!ue&&setTimeout(()=>{z=Math.min(z*2,1e4),!H&&!ue&&Ye()},z))},o.onerror=()=>o?.close()}function fe(n){_({type:"input",data:n})}function Y(){return i.fit()}function me(){e.classList.remove("terminal-pending")}function k(){r&&cancelAnimationFrame(r),c&&clearTimeout(c),Y(),r=requestAnimationFrame(()=>{r=0,Y()&&me()}),c=setTimeout(()=>{Y()&&me()},120)}function kt(){k(),setTimeout(k,50),setTimeout(k,150),setTimeout(k,300)}function je(n){return typeof n=="string"&&n.startsWith("image/")}function Fe(n){return n?.files?.length?n.files[0]??null:null}function xt(n){if(!n?.items)return null;for(let a=0;a<n.items.length;a++){let d=n.items[a];if(d?.kind==="file"&&je(d.type))return d.getAsFile()}return null}async function Ct(n){let a=new FormData,d=n instanceof File&&n.name?n.name:"upload";a.append("file",n,d);let h=localStorage.getItem("tmux-web-token"),C={};h&&(C.Authorization="Bearer "+h);let G=await fetch(gt,{method:"POST",body:a,headers:C});if(!G.ok){let Je="upload failed";try{let Qe=await G.json();Qe.error&&(Je=Qe.error)}catch{}throw new Error(Je)}let Ve=await G.json();if(!Ve.path)throw new Error("no path in response");return Ve.path}async function Se(n){try{let a=await Ct(n);fe(a)}catch{}}i.onData(n=>fe(n)),i.onResize(({cols:n,rows:a})=>_({type:"resize",cols:n,rows:a})),i.onScroll(()=>{u!=="live"||R||!i.isNearScrollbackTop()||(R=!0,_({type:"load_history",before:M}))});let X=!1,V=!1,w=null,b=null,J=document.createElement("div");J.className="terminal-copy-banner",J.innerHTML='<strong>Copy mode</strong><span class="hint">drag to copy \xB7 Esc exits</span>',J.hidden=!0,e.appendChild(J);let A=document.createElement("div");A.className="terminal-copy-banner terminal-copy-toast",A.textContent="Copied",A.hidden=!0,e.appendChild(A);function We(n,a){let d=e.querySelector(".xterm-screen, canvas"),h=(d&&d.getBoundingClientRect().width>0?d:e).getBoundingClientRect(),C=h.height>0&&i.rows>0?h.height/i.rows:18,G=h.width>0&&i.cols>0?h.width/i.cols:9;return{row:Math.max(0,Math.min(i.rows-1,Math.floor((a-h.top)/C))),col:Math.max(0,Math.min(i.cols-1,Math.floor((n-h.left)/G)))}}async function ve(n){if(!n)return;try{if(navigator.clipboard?.writeText){await navigator.clipboard.writeText(n);return}}catch{}let a=document.createElement("textarea");a.value=n,a.style.position="fixed",a.style.opacity="0",a.style.pointerEvents="none",document.body.appendChild(a),a.focus(),a.select();try{document.execCommand("copy")}catch{}a.remove()}let Q;function he(){A.hidden=!1,Q&&clearTimeout(Q),Q=setTimeout(()=>{A.hidden=!0},1e3)}function U(n){X=n,J.hidden=!n,e.classList.toggle("terminal-copy-mode-active",n),n&&i.focus()}function Ue(){U(!X)}function Tt(n){H||n.button!==0||V||(X||n.shiftKey)&&(n.preventDefault(),n.stopPropagation(),V=!0,w=We(n.clientX,n.clientY),b=w,i.selectCells(w.col,w.row,b.col,b.row),document.addEventListener("mousemove",De,!0),document.addEventListener("mouseup",He,!0))}function De(n){H||!V||!w||(n.preventDefault(),n.stopPropagation(),b=We(n.clientX,n.clientY),i.selectCells(w.col,w.row,b.col,b.row))}function He(n){if(H||!V||!w||!b)return;n.preventDefault(),n.stopPropagation(),document.removeEventListener("mousemove",De,!0),document.removeEventListener("mouseup",He,!0),V=!1;let a=i.getCellsText(w.col,w.row,b.col,b.row);w=null,b=null,i.clearSelection(),U(!1),a&&(A.textContent="\u5DF2\u590D\u5236",ve(a).then(he)),i.focus()}e.addEventListener("mousedown",Tt,!0),document.addEventListener("keydown",Mt,!0);function Mt(n){if(!(H||!i.isFocused()||n.defaultPrevented||n.isComposing)){if(X){if(n.key==="Escape"){n.preventDefault(),n.stopPropagation(),w=null,b=null,i.clearSelection(),U(!1);return}if(n.key==="Enter"||(n.ctrlKey||n.metaKey)&&n.code==="KeyC"){n.preventDefault(),n.stopPropagation(),ve(i.getScreenText()).then(he),U(!1);return}}if(n.altKey&&n.code==="KeyC"&&!n.ctrlKey&&!n.metaKey){if(n.preventDefault(),n.stopPropagation(),w&&b){let a=i.getCellsText(w.col,w.row,b.col,b.row);w=null,b=null,i.clearSelection(),U(!1),a&&(A.textContent="Copied",ve(a).then(he))}else{let a=i.getSelection();a?(i.clearSelection(),A.textContent="Copied",ve(a).then(he)):Ue()}return}if((n.ctrlKey||n.metaKey)&&n.code==="KeyV"){n.preventDefault(),n.stopPropagation(),(async()=>{try{if(navigator.clipboard?.read){let a=await navigator.clipboard.read();for(let d of a)for(let h of d.types)if(je(h)){let C=await d.getType(h);await Se(C);return}}}catch{}try{let a=await navigator.clipboard?.readText();a&&i.pasteText(Oe(a))}catch{}})();return}}}let ye=0;function Oe(n){return n.split(`\r
1
+ var Jt=/\x1b\](?:10|11|110|111|104)(?:;[^\x07\x1b]*)?\x1b?(?:\\|\x07)/g;function je(e){return e.replace(/\x1b\[\?1049[hl]/g,"")}function ie(e){return e.replace(Jt,"")}var ke;function Zt(){return ke||(document.querySelector("link[data-tmux-web-xterm-css]")?ke=Promise.resolve():(ke=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)}),ke))}var Gt=class Ct{terminal;fitAddon;container;constructor(t,s,i){this.container=t,this.terminal=s,this.fitAddon=i,this.terminal.loadAddon(this.fitAddon),this.terminal.open(t)}static async create(t,s,i){let[{Terminal:o},{FitAddon:r}]=await Promise.all([import("./xterm-BXEES47M.js"),import("./addon-fit-D5N335P2.js"),Zt()]),d=new o({fontSize:14,fontFamily:"'JetBrains Mono', 'SF Mono', 'Menlo', monospace",cursorBlink:!0,cursorStyle:"bar",scrollback:s,convertEol:!1,smoothScrollDuration:120,theme:i});return new Ct(t,d,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){this.terminal.scrollToLine(Math.max(0,t))}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}fit(){let t=Qt(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 i=this.terminal.buffer.active,[o,r]=t<=s?[t,s]:[s,t],d=i.viewportY,l=[];for(let u=o;u<=r;u++){let v=i.getLine(d+u);l.push(v?v.translateToString(!0):"")}return l.join(`
2
+ `)}selectRows(t,s){let i=this.terminal.buffer.active,[o,r]=t<=s?[t,s]:[s,t];this.terminal.selectLines(i.viewportY+o,i.viewportY+r)}selectCells(t,s,i,o){let r=this.terminal.buffer.active,d=Math.min(s,o),l=Math.max(s,o);if(d===l){let u=Math.min(t,i),v=Math.max(t,i);this.terminal.select(u,r.viewportY+d,v-u+1)}else this.terminal.selectLines(r.viewportY+d,r.viewportY+l)}getCellsText(t,s,i,o){let r=this.terminal.buffer.active,d=Math.min(s,o),l=Math.max(s,o),u=s<o?t:s>o?i:Math.min(t,i),v=s<o?i:s>o?t:Math.max(t,i),I=r.viewportY,X=[];for(let A=d;A<=l;A++){let fe=r.getLine(I+A);if(!fe){X.push("");continue}let Pe=A===d?u:0,U=A===l?v:this.terminal.cols-1,me="";for(let F=Pe;F<=U;F++){let T=fe.getCell(F);T&&(me+=T.getChars())}X.push(me.replace(/\s+$/,""))}return X.join(`
3
+ `)}getSelection(){return this.terminal.getSelection()}clearSelection(){this.terminal.clearSelection()}hasSelectionSupport(){return!0}};function Qt(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 en(e,t,s){return e.innerHTML="",e.classList.add("terminal-pending"),(async()=>{let i=await Gt.create(e,s.scrollback,s.theme),o,r=0,d,l=null,u=0,v=0,I=0,X=.2,A=5,fe=.94,Pe=.04;function U(){u&&(cancelAnimationFrame(u),u=0),v=0,I=0}function me(n){if(U(),Math.abs(n)<X)return;v=Math.max(-A,Math.min(A,n));let a=()=>{if(R){u=0;return}let c=i.viewportY();tt(v*16);let p=i.viewportY();if(v*=fe,p===c){if(++I>=2){u=0;return}}else I=0;if(Math.abs(v)<Pe){u=0;return}u=requestAnimationFrame(a)};u=requestAnimationFrame(a)}let F=0,T="connecting",ve=0,he=!1,ge=[],O="",R=!1,J=1e3,Tt=location.protocol==="https:"?"wss:":"ws:",Mt=s.wsBase||"/ws",Bt=Tt+"//"+location.host+Mt+"/"+encodeURIComponent(t),It="/api/session/"+encodeURIComponent(t)+"/upload",St=/^((?!chrome|android|crios|fxios|edgios).)*safari/i.test(navigator.userAgent);function Dt(){return ge.join("")+O}async function Ht(n,a=0){let c=n?i.viewportY():0,p=n?i.baseY():0,L=ie(Dt());if(i.reset(),!L){n||i.scrollToBottom();return}await i.write(L),n?i.scrollToLine(p+c+a):i.scrollToBottom()}function z(n){o?.readyState===WebSocket.OPEN&&o.send(JSON.stringify(n))}function At(n){let a;try{a=JSON.parse(n)}catch{T==="live"&&(O+=n,i.write(ie(n)));return}if(a.type==="auth.required"){let c=localStorage.getItem("tmux-web-token");c?z({type:"auth.token",token:c}):location.href="/login?returnTo="+encodeURIComponent(location.pathname+location.search);return}if(a.type==="attach_failed"&&typeof a.message=="string"){ye=!0,T="dead",i.reset(),i.write(`\r
4
+ \x1B[31m`+ie(a.message)+`\x1B[0m\r
5
+ `).then(()=>{be();try{o?.close()}catch{}});return}if(a.type==="auth.ok"){a.token&&localStorage.setItem("tmux-web-token",a.token),J=1e3,j(),z({type:"resize",cols:i.cols,rows:i.rows}),k();return}if(a.type==="auth.failed"){if(a.permanentLock||a.retryAfterMs&&a.retryAfterMs>6e4){localStorage.removeItem("tmux-web-token"),location.href="/login?error="+encodeURIComponent(a.message);return}return}if(a.type==="snapshot"&&typeof a.data=="string"){let c=je(ie(a.data));ge=[c],O="",ve=typeof a.lines=="number"?a.lines:s.terminal.initialLines,T="live",i.reset(),j(),z({type:"resize",cols:i.cols,rows:i.rows}),i.write(c).then(()=>i.scrollToBottom());return}if(a.type==="window_changed"&&typeof a.activeIndex=="number"){let c=new URL(location.href);c.searchParams.get("window")!==String(a.activeIndex)&&(c.searchParams.set("window",String(a.activeIndex)),history.replaceState(history.state,"",c)),window.dispatchEvent(new CustomEvent("tmux:windows",{detail:a.windows}));return}if(a.type==="history"&&typeof a.data=="string"){he=!1,a.lines>0&&a.data&&(ge.unshift(je(a.data)),ve+=a.lines,Ht(!0,a.lines));return}if(a.type==="data"&&typeof a.data=="string"){let c=je(ie(a.data));if(T==="connecting"){T="live",O=c,i.write(c);return}T==="live"&&(O+=c,i.write(c))}}let ye=!1;function Ve(){if(ye)return;let n=Bt,a=localStorage.getItem("tmux-web-token");a&&(n+=(n.includes("?")?"&":"?")+"token="+encodeURIComponent(a)),n+=(n.includes("?")?"&":"?")+"cols="+i.cols+"&rows="+i.rows,o=new WebSocket(n),o.onopen=()=>{T="connecting",ve=0,he=!1,ge=[],O="",i.reset(),J=1e3},o.onmessage=c=>{typeof c.data=="string"&&At(c.data)},o.onclose=()=>{R||(T="connecting",!ye&&setTimeout(()=>{J=Math.min(J*2,1e4),!R&&!ye&&Ve()},J))},o.onerror=()=>o?.close()}function we(n){z({type:"input",data:n})}function j(){return i.fit()}function be(){e.classList.remove("terminal-pending")}function k(){r&&cancelAnimationFrame(r),d&&clearTimeout(d),j(),r=requestAnimationFrame(()=>{r=0,j()&&be()}),d=setTimeout(()=>{j()&&be()},120)}function Rt(){k(),setTimeout(k,50),setTimeout(k,150),setTimeout(k,300)}function Xe(n){return typeof n=="string"&&n.startsWith("image/")}function Je(n){return n?.files?.length?n.files[0]??null:null}function $t(n){if(!n?.items)return null;for(let a=0;a<n.items.length;a++){let c=n.items[a];if(c?.kind==="file"&&Xe(c.type))return c.getAsFile()}return null}async function Pt(n){let a=new FormData,c=n instanceof File&&n.name?n.name:"upload";a.append("file",n,c);let p=localStorage.getItem("tmux-web-token"),L={};p&&(L.Authorization="Bearer "+p);let $=await fetch(It,{method:"POST",body:a,headers:L});if(!$.ok){let st="upload failed";try{let at=await $.json();at.error&&(st=at.error)}catch{}throw new Error(st)}let ne=await $.json();if(!ne.path)throw new Error("no path in response");return ne.path}async function Ne(n){try{let a=await Pt(n);we(a)}catch{}}i.onData(n=>we(n)),i.onResize(({cols:n,rows:a})=>z({type:"resize",cols:n,rows:a})),i.onScroll(()=>{T!=="live"||he||!i.isNearScrollbackTop()||(he=!0,z({type:"load_history",before:ve}))});let Z=!1,G=!1,w=null,b=null,Q=document.createElement("div");Q.className="terminal-copy-banner",Q.innerHTML='<strong>Copy mode</strong><span class="hint">drag to copy \xB7 Esc exits</span>',Q.hidden=!0,e.appendChild(Q);let D=document.createElement("div");D.className="terminal-copy-banner terminal-copy-toast",D.textContent="Copied",D.hidden=!0,e.appendChild(D);function Ze(n,a){let c=e.querySelector(".xterm-screen, canvas"),p=(c&&c.getBoundingClientRect().width>0?c:e).getBoundingClientRect(),L=p.height>0&&i.rows>0?p.height/i.rows:18,$=p.width>0&&i.cols>0?p.width/i.cols:9;return{row:Math.max(0,Math.min(i.rows-1,Math.floor((a-p.top)/L))),col:Math.max(0,Math.min(i.cols-1,Math.floor((n-p.left)/$)))}}async function Le(n){if(!n)return;try{if(navigator.clipboard?.writeText){await navigator.clipboard.writeText(n);return}}catch{}let a=document.createElement("textarea");a.value=n,a.style.position="fixed",a.style.opacity="0",a.style.pointerEvents="none",document.body.appendChild(a),a.focus(),a.select();try{document.execCommand("copy")}catch{}a.remove()}let ee;function Ee(){D.hidden=!1,ee&&clearTimeout(ee),ee=setTimeout(()=>{D.hidden=!0},1e3)}function q(n){Z=n,Q.hidden=!n,e.classList.toggle("terminal-copy-mode-active",n),n&&i.focus()}function Ge(){q(!Z)}function Nt(n){R||n.button!==0||G||(Z||n.shiftKey)&&(n.preventDefault(),n.stopPropagation(),G=!0,w=Ze(n.clientX,n.clientY),b=w,i.selectCells(w.col,w.row,b.col,b.row),document.addEventListener("mousemove",Fe,!0),document.addEventListener("mouseup",ze,!0))}function Fe(n){R||!G||!w||(n.preventDefault(),n.stopPropagation(),b=Ze(n.clientX,n.clientY),i.selectCells(w.col,w.row,b.col,b.row))}function ze(n){if(R||!G||!w||!b)return;n.preventDefault(),n.stopPropagation(),document.removeEventListener("mousemove",Fe,!0),document.removeEventListener("mouseup",ze,!0),G=!1;let a=i.getCellsText(w.col,w.row,b.col,b.row);w=null,b=null,i.clearSelection(),q(!1),a&&(D.textContent="\u5DF2\u590D\u5236",Le(a).then(Ee)),i.focus()}e.addEventListener("mousedown",Nt,!0),document.addEventListener("keydown",Ft,!0);function Ft(n){if(!(R||!i.isFocused()||n.defaultPrevented||n.isComposing)){if(Z){if(n.key==="Escape"){n.preventDefault(),n.stopPropagation(),w=null,b=null,i.clearSelection(),q(!1);return}if(n.key==="Enter"||(n.ctrlKey||n.metaKey)&&n.code==="KeyC"){n.preventDefault(),n.stopPropagation(),Le(i.getScreenText()).then(Ee),q(!1);return}}if(n.altKey&&n.code==="KeyC"&&!n.ctrlKey&&!n.metaKey){if(n.preventDefault(),n.stopPropagation(),w&&b){let a=i.getCellsText(w.col,w.row,b.col,b.row);w=null,b=null,i.clearSelection(),q(!1),a&&(D.textContent="Copied",Le(a).then(Ee))}else{let a=i.getSelection();a?(i.clearSelection(),D.textContent="Copied",Le(a).then(Ee)):Ge()}return}if((n.ctrlKey||n.metaKey)&&n.code==="KeyV"){n.preventDefault(),n.stopPropagation(),(async()=>{try{if(navigator.clipboard?.read){let a=await navigator.clipboard.read();for(let c of a)for(let p of c.types)if(Xe(p)){let L=await c.getType(p);await Ne(L);return}}}catch{}try{let a=await navigator.clipboard?.readText();a&&i.pasteText(Qe(a))}catch{}})();return}}}let xe=0;function Qe(n){return n.split(`\r
6
6
  `).join(`
7
7
  `).split(`
8
- `).join("\r")}async function It(n){let a=xt(n.clipboardData);if(a){n.preventDefault(),n.stopPropagation();let C=Date.now();if(C-ye<50)return;ye=C,await Se(a);return}let d=n.clipboardData?.getData("text/plain");if(!d)return;n.preventDefault(),n.stopPropagation();let h=Date.now();h-ye<50||(ye=h,i.pasteText(Oe(d)))}let Z=0;function Bt(n){n.preventDefault(),Z++,Fe(n.dataTransfer)&&e.classList.add("terminal-drag-over")}function St(n){n.preventDefault(),n.dataTransfer&&(n.dataTransfer.dropEffect="copy")}function Dt(n){n.preventDefault(),Z--,Z<=0&&(Z=0,e.classList.remove("terminal-drag-over"))}async function Ht(n){n.preventDefault(),Z=0,e.classList.remove("terminal-drag-over");let a=Fe(n.dataTransfer);a&&await Se(a)}function Ke(n){!wt||n.key!=="Escape"||X||n.defaultPrevented||n.repeat||n.metaKey||n.ctrlKey||n.altKey||i.isFocused()&&(n.preventDefault(),n.stopPropagation(),fe("\x1B"))}e.addEventListener("paste",It),e.addEventListener("dragenter",Bt),e.addEventListener("dragover",St),e.addEventListener("dragleave",Dt),e.addEventListener("drop",Ht),document.addEventListener("keydown",Ke,!0);function At(n){if(n.touches.length!==1){l=null;return}let a=n.touches[0];a&&(l={startX:a.clientX,startY:a.clientY,lastX:a.clientX,lastY:a.clientY,scrolling:!1},n.stopPropagation())}function Pt(n){if(!l||n.touches.length!==1)return;let a=n.touches[0];if(!a)return;let d=a.clientY-l.startY,h=a.clientX-l.startX;if(!l.scrolling){if(Math.abs(d)<8||Math.abs(d)<Math.abs(h))return;l.scrolling=!0,p=Date.now()+500}n.preventDefault(),n.stopPropagation(),zt(-(a.clientY-l.lastY),a.clientX,a.clientY),l.lastX=a.clientX,l.lastY=a.clientY}function Rt(n){if(!l)return;let a=l.scrolling;l=null,n.stopPropagation(),a?(p=Date.now()+500,n.preventDefault()):i.focus()}function $t(n){l=null,n.stopPropagation()}function Nt(n){n.pointerType==="touch"&&Date.now()<p&&(n.preventDefault(),n.stopPropagation())}function zt(n,a,d){(e.querySelector(".xterm-screen")??e).dispatchEvent(new WheelEvent("wheel",{deltaY:n,deltaMode:WheelEvent.DOM_DELTA_PIXEL,clientX:a,clientY:d,bubbles:!0,cancelable:!0}))}e.addEventListener("touchstart",At,{passive:!0,capture:!0}),e.addEventListener("touchmove",Pt,{passive:!1,capture:!0}),e.addEventListener("touchend",Rt,{passive:!1,capture:!0}),e.addEventListener("touchcancel",$t,{passive:!0,capture:!0}),e.addEventListener("pointerup",Nt,!0);function qe(){k()}window.addEventListener("resize",qe),window.visualViewport?.addEventListener("resize",k),window.visualViewport?.addEventListener("scroll",k);let Xe=new ResizeObserver(()=>k());Xe.observe(e),document.fonts?.ready.then(()=>{k(),setTimeout(k,50),setTimeout(k,200)}),e.addEventListener("focusin",kt,!0);async function _t(){if(document.fonts?.ready)try{await Promise.race([document.fonts.ready,new Promise(n=>setTimeout(n,1e3))])}catch{}}return requestAnimationFrame(()=>{Y()&&me(),(async()=>(await _t(),Y()&&_({type:"resize",cols:i.cols,rows:i.rows}),Ye(),k()))()}),{destroy(){if(H=!0,U(!1),Q&&clearTimeout(Q),document.removeEventListener("mousemove",De,!0),document.removeEventListener("mouseup",He,!0),o){try{o.close(1e3,"session switch")}catch{}o=void 0}e.innerHTML="",e.classList.remove("terminal-pending"),window.removeEventListener("resize",qe),Xe.disconnect(),document.removeEventListener("keydown",Ke,!0)},focus(){i.focus()},sendInput(n){fe(n)},toggleCopyMode(){Ue()}}})()}var te=window.__TMUX_WEB_SHELL__,v=null,g=null,Ze=typeof window.__TMUX_WEB_SCOPE__?.agentId=="string"?window.__TMUX_WEB_SCOPE__.agentId:null,E=Ze;window.__tmuxWebScopeAgent=Ze;var Ae="sessions",$="",we="",be="",Ge="";function x(e){return E?"/a/"+encodeURIComponent(E)+e:e}var m=document.getElementById("sidebar-content"),j=document.getElementById("main-placeholder"),T=document.getElementById("terminal-container"),ne=document.getElementById("file-editor"),Ot=document.getElementById("fe-path"),I=document.getElementById("fe-status"),ie=document.getElementById("fe-content"),F=document.getElementById("fe-save"),Kt=document.getElementById("fe-delete"),qt=document.getElementById("fe-back"),et=document.getElementById("fe-new-name"),Xt=document.getElementById("fe-new-btn"),Pe=document.getElementById("settings-backdrop"),tt=document.getElementById("settings-popover"),nt=document.querySelector(".sidebar");function Vt(){return window.matchMedia("(max-width: 640px)").matches}function Re(){Vt()&&nt.classList.add("collapsed")}function it(){nt.classList.remove("collapsed")}document.getElementById("mode-sessions").addEventListener("click",()=>{it(),st("sessions")}),document.getElementById("mode-files").addEventListener("click",()=>{it(),st("files")});function st(e){Ae=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"?($e="",O()):on()}var $e="";async function O(){if(Ae!=="sessions")return;try{let t=await(await fetch("/api/sidebar/sessions")).json(),s=JSON.stringify({recent:t.recent,agents:t.agents});if(s===$e)return;$e=s,Jt(t)}catch{m.innerHTML+='<div class="file-tree-empty">Failed to load sessions</div>'}let e=document.getElementById("ns-btn");e&&e.addEventListener("click",()=>document.getElementById("new-session-modal")?.classList.add("open"))}function Jt(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"+(E?" clickable":""),s.textContent=E?"\u2190 \u8FD4\u56DE\u672C\u673A":"\u672C\u673A",E&&(s.title="Back to hub",s.addEventListener("click",()=>{window.location.href="/"})),m.appendChild(s);for(let o of t){let r=document.createElement("div");r.className="session-item"+(o.name===g&&!E?" active":""),r.setAttribute("data-session",o.name),r.innerHTML=`<svg viewBox="0 0 24 24" fill="currentColor"><path d="${o.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 zt(n){let a=$t(n.clipboardData);if(a){n.preventDefault(),n.stopPropagation();let L=Date.now();if(L-xe<50)return;xe=L,await Ne(a);return}let c=n.clipboardData?.getData("text/plain");if(!c)return;n.preventDefault(),n.stopPropagation();let p=Date.now();p-xe<50||(xe=p,i.pasteText(Qe(c)))}let te=0;function jt(n){n.preventDefault(),te++,Je(n.dataTransfer)&&e.classList.add("terminal-drag-over")}function Yt(n){n.preventDefault(),n.dataTransfer&&(n.dataTransfer.dropEffect="copy")}function _t(n){n.preventDefault(),te--,te<=0&&(te=0,e.classList.remove("terminal-drag-over"))}async function Wt(n){n.preventDefault(),te=0,e.classList.remove("terminal-drag-over");let a=Je(n.dataTransfer);a&&await Ne(a)}function et(n){!St||n.key!=="Escape"||Z||n.defaultPrevented||n.repeat||n.metaKey||n.ctrlKey||n.altKey||i.isFocused()&&(n.preventDefault(),n.stopPropagation(),we("\x1B"))}e.addEventListener("paste",zt),e.addEventListener("dragenter",jt),e.addEventListener("dragover",Yt),e.addEventListener("dragleave",_t),e.addEventListener("drop",Wt),document.addEventListener("keydown",et,!0);function Ut(n){if(n.touches.length!==1){l=null;return}let a=n.touches[0];a&&(U(),l={startX:a.clientX,startY:a.clientY,lastX:a.clientX,lastY:a.clientY,lastT:performance.now(),velocity:0,scrolling:!1},n.stopPropagation())}function Ot(n){if(!l||n.touches.length!==1)return;let a=n.touches[0];if(!a)return;let c=a.clientY-l.startY,p=a.clientX-l.startX;if(!l.scrolling){if(Math.abs(c)<8||Math.abs(c)<Math.abs(p))return;l.scrolling=!0,F=Date.now()+500}n.preventDefault(),n.stopPropagation();let L=performance.now(),$=a.clientY-l.lastY,ne=L-l.lastT;ne>0&&(l.velocity=$/ne),tt($),l.lastX=a.clientX,l.lastY=a.clientY,l.lastT=L}function qt(n){if(!l)return;let a=l.scrolling,c=l.velocity;if(l=null,n.stopPropagation(),!a){i.focus();return}F=Date.now()+500,n.preventDefault(),c&&me(c)}function Kt(n){l=null,U(),n.stopPropagation()}function Vt(n){n.pointerType==="touch"&&Date.now()<F&&(n.preventDefault(),n.stopPropagation())}function tt(n){let a=e.querySelector(".xterm-rows > div"),c=a?a.getBoundingClientRect().height:16,p=c>0?Math.round(n/c):n>0?1:-1;p===0&&(p=n>0?1:-1),i.scrollLines(p)}e.addEventListener("touchstart",Ut,{passive:!0,capture:!0}),e.addEventListener("touchmove",Ot,{passive:!1,capture:!0}),e.addEventListener("touchend",qt,{passive:!1,capture:!0}),e.addEventListener("touchcancel",Kt,{passive:!0,capture:!0}),e.addEventListener("pointerup",Vt,!0);function nt(){k()}window.addEventListener("resize",nt),window.visualViewport?.addEventListener("resize",k),window.visualViewport?.addEventListener("scroll",k);let it=new ResizeObserver(()=>k());it.observe(e),document.fonts?.ready.then(()=>{k(),setTimeout(k,50),setTimeout(k,200)}),e.addEventListener("focusin",Rt,!0);async function Xt(){if(document.fonts?.ready)try{await Promise.race([document.fonts.ready,new Promise(n=>setTimeout(n,1e3))])}catch{}}return requestAnimationFrame(()=>{j()&&be(),(async()=>(await Xt(),j()&&z({type:"resize",cols:i.cols,rows:i.rows}),Ve(),k()))()}),{destroy(){if(R=!0,U(),q(!1),ee&&clearTimeout(ee),document.removeEventListener("mousemove",Fe,!0),document.removeEventListener("mouseup",ze,!0),o){try{o.close(1e3,"session switch")}catch{}o=void 0}e.innerHTML="",e.classList.remove("terminal-pending"),window.removeEventListener("resize",nt),it.disconnect(),document.removeEventListener("keydown",et,!0)},focus(){i.focus()},sendInput(n){we(n)},toggleCopyMode(){Ge()}}})()}var se=window.__TMUX_WEB_SHELL__,h=null,y=null,ot=typeof window.__TMUX_WEB_SCOPE__?.agentId=="string"?window.__TMUX_WEB_SCOPE__.agentId:null,x=ot;window.__tmuxWebScopeAgent=ot;var Ye="sessions",P="",Ce="",Te="",lt="";function C(e){return x?"/a/"+encodeURIComponent(x)+e:e}var m=document.getElementById("sidebar-content"),Y=document.getElementById("main-placeholder"),M=document.getElementById("terminal-container"),ae=document.getElementById("file-editor"),tn=document.getElementById("fe-path"),B=document.getElementById("fe-status"),oe=document.getElementById("fe-content"),_=document.getElementById("fe-save"),nn=document.getElementById("fe-delete"),sn=document.getElementById("fe-back"),rt=document.getElementById("fe-new-name"),an=document.getElementById("fe-new-btn"),_e=document.getElementById("settings-backdrop"),ct=document.getElementById("settings-popover"),dt=document.querySelector(".sidebar");function on(){return window.matchMedia("(max-width: 640px)").matches}function We(){on()&&dt.classList.add("collapsed")}function ut(){dt.classList.remove("collapsed")}document.getElementById("mode-sessions").addEventListener("click",()=>{ut(),pt("sessions")}),document.getElementById("mode-files").addEventListener("click",()=>{ut(),pt("files")});function pt(e){Ye=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"?(Ue="",K()):hn()}var Ue="";async function K(){if(Ye!=="sessions")return;try{let t=await(await fetch("/api/sidebar/sessions")).json(),s=JSON.stringify({recent:t.recent,agents:t.agents});if(s===Ue)return;Ue=s,ln(t)}catch{m.innerHTML+='<div class="file-tree-empty">Failed to load sessions</div>'}let e=document.getElementById("ns-btn");e&&e.addEventListener("click",()=>document.getElementById("new-session-modal")?.classList.add("open"))}function ln(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"+(x?" clickable":""),s.textContent=x?"\u2190 \u8FD4\u56DE\u672C\u673A":"\u672C\u673A",x&&(s.title="Back to hub",s.addEventListener("click",()=>{window.location.href="/"})),m.appendChild(s);for(let o of t){let r=document.createElement("div");r.className="session-item"+(o.name===y&&!x?" active":""),r.setAttribute("data-session",o.name),r.innerHTML=`<svg viewBox="0 0 24 24" fill="currentColor"><path d="${o.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>${f(o.name)}</span>
10
10
  <button class="session-edit-btn" data-session="${f(o.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>
11
- `,r.addEventListener("click",l=>{l.target.closest(".session-edit-btn")||se(o.name)}),m.appendChild(r);let c=r.querySelector(".session-edit-btn");c&&c.addEventListener("click",l=>{l.stopPropagation(),pn(o.name,c)})}let i=e.agents||[];for(let o of i){if(!o.sessions||o.sessions.length===0)continue;let r=o.agentId===E,c=document.createElement("div");c.className="sidebar-section-label machine-label"+(o.online?"":" agent-offline-label")+(!r&&o.online?" clickable":""),c.textContent=o.agentName+(o.online?"":" (offline)"),!r&&o.online&&(c.title="\u6253\u5F00 "+o.agentName,c.addEventListener("click",()=>{window.location.href="/a/"+encodeURIComponent(o.agentId)+"/"})),m.appendChild(c);for(let l of o.sessions){let p=document.createElement("div");p.className="session-item"+(l.name===g&&E===o.agentId?" active":"")+(o.online?"":" session-offline"),p.setAttribute("data-session",l.name),p.setAttribute("data-agent",o.agentId),p.innerHTML=`<svg viewBox="0 0 24 24" fill="currentColor"><path d="${l.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>
12
- <span>${f(l.name)}</span><span class="meta">${o.online?"":"offline"}</span>`,o.online&&p.addEventListener("click",u=>{u.target.closest(".session-edit-btn")||se(l.name,o.agentId)}),m.appendChild(p)}}}function f(e){return e.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;")}async function se(e,t){if(!(g===e&&v&&E===(t||null))){ne.style.display="none",j.style.display="none",T.style.display="",T.classList.add("terminal-pending"),Re(),v&&(Ie(),v.destroy(),v=null),g=e,E=t||null,window.__tmuxWebScopeAgent=E;for(let s of m.querySelectorAll(".session-item"))s.classList.toggle("active",s.getAttribute("data-session")===e&&(s.getAttribute("data-agent")||null)===E);try{v=await Ut(T,e,{terminal:te.terminal,scrollback:te.scrollback,theme:te.theme,wsBase:E?"/ws/a/"+encodeURIComponent(E):te.wsBase||"/ws"}),mt()}catch(s){console.error("[shell] terminal init failed:",s);let i=s&&typeof s=="object"&&"message"in s?s.message:String(s);T.textContent="Failed to open terminal for "+e+": "+i,T.classList.remove("terminal-pending")}}}var Le=[],y=null,at=!1;function Qt(e){if(!y||!y.files.length)return null;let t=y.repoRoot;if(!t||!e.startsWith(t))return null;let s=e.slice(t.length+1);for(let i of y.files)if(i.path===s)return i.status;return null}async function Zt(e){at=!0;try{let t=await fetch(x("/api/git/status?path="+encodeURIComponent(e)));t.ok?y=await t.json():y=null}catch{y=null}finally{at=!1}}function Gt(){if(!y||!y.branch)return"";let{branch:e,linesAdded:t,linesRemoved:s}=y,i=`<div class="sidebar-git"><div class="git-branch-badge">
11
+ `,r.addEventListener("click",l=>{l.target.closest(".session-edit-btn")||le(o.name)}),m.appendChild(r);let d=r.querySelector(".session-edit-btn");d&&d.addEventListener("click",l=>{l.stopPropagation(),Ln(o.name,d)})}let i=e.agents||[];for(let o of i){if(!o.sessions||o.sessions.length===0)continue;let r=o.agentId===x,d=document.createElement("div");d.className="sidebar-section-label machine-label"+(o.online?"":" agent-offline-label")+(!r&&o.online?" clickable":""),d.textContent=o.agentName+(o.online?"":" (offline)"),!r&&o.online&&(d.title="\u6253\u5F00 "+o.agentName,d.addEventListener("click",()=>{window.location.href="/a/"+encodeURIComponent(o.agentId)+"/"})),m.appendChild(d);for(let l of o.sessions){let u=document.createElement("div");u.className="session-item"+(l.name===y&&x===o.agentId?" active":"")+(o.online?"":" session-offline"),u.setAttribute("data-session",l.name),u.setAttribute("data-agent",o.agentId),u.innerHTML=`<svg viewBox="0 0 24 24" fill="currentColor"><path d="${l.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>
12
+ <span>${f(l.name)}</span><span class="meta">${o.online?"":"offline"}</span>`,o.online&&u.addEventListener("click",v=>{v.target.closest(".session-edit-btn")||le(l.name,o.agentId)}),m.appendChild(u)}}}function f(e){return e.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;")}async function le(e,t){if(!(y===e&&h&&x===(t||null))){ae.style.display="none",Y.style.display="none",M.style.display="",M.classList.add("terminal-pending"),We(),h&&(Re(),h.destroy(),h=null),y=e,x=t||null,window.__tmuxWebScopeAgent=x;for(let s of m.querySelectorAll(".session-item"))s.classList.toggle("active",s.getAttribute("data-session")===e&&(s.getAttribute("data-agent")||null)===x);try{h=await en(M,e,{terminal:se.terminal,scrollback:se.scrollback,theme:se.theme,wsBase:x?"/ws/a/"+encodeURIComponent(x):se.wsBase||"/ws"}),Et()}catch(s){console.error("[shell] terminal init failed:",s);let i=s&&typeof s=="object"&&"message"in s?s.message:String(s);M.textContent="Failed to open terminal for "+e+": "+i,M.classList.remove("terminal-pending")}}}var Me=[],g=null,ft=!1;function rn(e){if(!g||!g.files.length)return null;let t=g.repoRoot;if(!t||!e.startsWith(t))return null;let s=e.slice(t.length+1);for(let i of g.files)if(i.path===s)return i.status;return null}async function cn(e){ft=!0;try{let t=await fetch(C("/api/git/status?path="+encodeURIComponent(e)));t.ok?g=await t.json():g=null}catch{g=null}finally{ft=!1}}function dn(){if(!g||!g.branch)return"";let{branch:e,linesAdded:t,linesRemoved:s}=g,i=`<div class="sidebar-git"><div class="git-branch-badge">
13
13
  <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>
14
- ${f(e)}</div>`;return(t>0||s>0)&&(i+=`<div class="git-diff-stats">+<span class="add">${t}</span> <span class="del">-${s}</span></div>`),i+"</div>"}m.addEventListener("click",e=>{e.target.closest(".sidebar-git")&&K&&y&&(e.stopPropagation(),dt())});var ae=document.getElementById("header-git"),ot=document.getElementById("git-diff-view"),lt=document.getElementById("gd-path"),Ee=document.getElementById("gd-status"),ke=document.getElementById("gd-content"),en=document.getElementById("gd-back"),K=null;function oe(e){if(!e||!e.branch){ae.style.display="none",K=null;return}K=e.repoRoot;let{branch:t,linesAdded:s,linesRemoved:i}=e,o=`<span class="branch">${f(t)}</span>`;(s>0||i>0)&&(o+=`<span class="sep">\xB7</span>+<span class="diff-add">${s}</span> <span class="diff-del">-${i}</span>`),ae.innerHTML=o,ae.style.display="block"}ae.addEventListener("click",e=>{K&&y&&(e.stopPropagation(),dt())});var L=document.getElementById("git-popover"),xe=document.getElementById("git-popover-backdrop");function Ne(){let e=ae.getBoundingClientRect();L.style.top=e.bottom+4+"px",L.style.left=Math.max(8,Math.min(e.left,window.innerWidth-400))+"px"}function rt(){let e=K,t=document.getElementById("git-popover-browse");t&&t.addEventListener("click",()=>{if(Te(),e){Ae="files",document.querySelectorAll(".mode-btn").forEach(i=>i.classList.remove("active"));let s=document.getElementById("mode-files");s&&s.classList.add("active"),N(e)}})}var ct="";function dt(){if(!y)return;let e=y.files||[];if(!e.length)L.innerHTML=`<div class="git-popover-header">No changes \u2014 clean working tree</div>
15
- <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 i=e[s],o=i.additions||0,r=i.deletions||0,c="";switch(i.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}">
16
- ${c}<span class="file-path">${f(i.path)}</span>
14
+ ${f(e)}</div>`;return(t>0||s>0)&&(i+=`<div class="git-diff-stats">+<span class="add">${t}</span> <span class="del">-${s}</span></div>`),i+"</div>"}m.addEventListener("click",e=>{e.target.closest(".sidebar-git")&&V&&g&&(e.stopPropagation(),yt())});var re=document.getElementById("header-git"),mt=document.getElementById("git-diff-view"),vt=document.getElementById("gd-path"),Be=document.getElementById("gd-status"),Ie=document.getElementById("gd-content"),un=document.getElementById("gd-back"),V=null;function ce(e){if(!e||!e.branch){re.style.display="none",V=null;return}V=e.repoRoot;let{branch:t,linesAdded:s,linesRemoved:i}=e,o=`<span class="branch">${f(t)}</span>`;(s>0||i>0)&&(o+=`<span class="sep">\xB7</span>+<span class="diff-add">${s}</span> <span class="diff-del">-${i}</span>`),re.innerHTML=o,re.style.display="block"}re.addEventListener("click",e=>{V&&g&&(e.stopPropagation(),yt())});var E=document.getElementById("git-popover"),Se=document.getElementById("git-popover-backdrop");function Oe(){let e=re.getBoundingClientRect();E.style.top=e.bottom+4+"px",E.style.left=Math.max(8,Math.min(e.left,window.innerWidth-400))+"px"}function ht(){let e=V,t=document.getElementById("git-popover-browse");t&&t.addEventListener("click",()=>{if(He(),e){Ye="files",document.querySelectorAll(".mode-btn").forEach(i=>i.classList.remove("active"));let s=document.getElementById("mode-files");s&&s.classList.add("active"),N(e)}})}var gt="";function yt(){if(!g)return;let e=g.files||[];if(!e.length)E.innerHTML=`<div class="git-popover-header">No changes \u2014 clean working tree</div>
15
+ <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 i=e[s],o=i.additions||0,r=i.deletions||0,d="";switch(i.status){case"M":d='<span class="git-file-status M">M</span>';break;case"A":d='<span class="git-file-status A">A</span>';break;case"D":d='<span class="git-file-status D">D</span>';break;case"?":d='<span class="git-file-status ?">?</span>';break;case"R":d='<span class="git-file-status R">R</span>';break}t+=`<div class="git-popover-item" data-idx="${s}">
16
+ ${d}<span class="file-path">${f(i.path)}</span>
17
17
  <span class="file-add">${o>0?"+"+o:""}</span>
18
18
  <span class="file-del">${r>0?"-"+r:""}</span>
19
- </div>`}t+='<div class="git-popover-footer"><button id="git-popover-browse">Browse repository \u2192</button></div>',ct=t,L.innerHTML=t,L.querySelectorAll(".git-popover-item").forEach(s=>{let i=parseInt(s.dataset.idx||"0",10),o=e[i];!o||o.status==="D"||(s.classList.add("clickable"),s.style.cursor="pointer",s.addEventListener("click",()=>ut(o.path)))})}Ne(),L.classList.add("open"),xe.classList.add("open"),rt()}function tn(){return window.innerWidth>=1024}function pt(e,t){let s=(e+(t&&e?`
19
+ </div>`}t+='<div class="git-popover-footer"><button id="git-popover-browse">Browse repository \u2192</button></div>',gt=t,E.innerHTML=t,E.querySelectorAll(".git-popover-item").forEach(s=>{let i=parseInt(s.dataset.idx||"0",10),o=e[i];!o||o.status==="D"||(s.classList.add("clickable"),s.style.cursor="pointer",s.addEventListener("click",()=>bt(o.path)))})}Oe(),E.classList.add("open"),Se.classList.add("open"),ht()}function pn(){return window.innerWidth>=1024}function wt(e,t){let s=(e+(t&&e?`
20
20
  `:"")+t).split(`
21
- `),i="",o=0,r=0;for(let c of s){let l=c;if(l.startsWith("@@")){let p=l.match(/@@\s+-(\d+)[^+]*\+(\d+)/);p&&(o=parseInt(p[1],10)-1,r=parseInt(p[2],10)-1),i+=`<div class="diff-line hunk"><span class="ln-body">${f(l)}</span></div>`;continue}if(l.startsWith("diff --git")||l.startsWith("index ")||l.startsWith("--- ")||l.startsWith("+++ ")||l.startsWith("new file")||l.startsWith("deleted file")){l.startsWith("diff --git")&&(i+=`<div class="diff-line header"><span class="ln-body">${f(l)}</span></div>`);continue}if(l.startsWith("+"))r++,i+=`<div class="diff-line add"><span class="ln-no">${r}</span><span class="ln-body">${f(l)}</span></div>`;else if(l.startsWith("-"))o++,i+=`<div class="diff-line del"><span class="ln-no">${o}</span><span class="ln-body">${f(l)}</span></div>`;else if(l.startsWith("\\"))i+=`<div class="diff-line"><span class="ln-body">${f(l)}</span></div>`;else{if(!l&&!o&&!r)continue;o++,r++,i+=`<div class="diff-line"><span class="ln-no">${o}</span><span class="ln-no" style="margin-right:12px">${r}</span><span class="ln-body">${f(l)}</span></div>`}}return{html:i,lineCount:s.length}}var Ce=null;async function ut(e){let t=K;if(t)if(Te(),tn()){T.style.display="none",v&&(Ie(),v.destroy(),v=null,Ce=g,g=null),oe(null),ne.style.display="none",j.style.display="none",ot.style.display="flex",lt.textContent=e,Ee.textContent="Loading\u2026",ke.innerHTML="";try{let s=await fetch(x("/api/git/diff?path="+encodeURIComponent(t)+"&file="+encodeURIComponent(e)));if(!s.ok)throw new Error(await s.text());let i=await s.json();sn(e,i.diff,i.stagedDiff)}catch(s){let i=s instanceof Error?s.message:String(s);Ee.textContent="Error",ke.innerHTML=`<div class="diff-empty" style="padding:24px;text-align:center;color:var(--panel-muted)">Error: ${f(i)}</div>`}}else{L.innerHTML=`<div class="git-diff-view"><div class="diff-header">
21
+ `),i="",o=0,r=0;for(let d of s){let l=d;if(l.startsWith("@@")){let u=l.match(/@@\s+-(\d+)[^+]*\+(\d+)/);u&&(o=parseInt(u[1],10)-1,r=parseInt(u[2],10)-1),i+=`<div class="diff-line hunk"><span class="ln-body">${f(l)}</span></div>`;continue}if(l.startsWith("diff --git")||l.startsWith("index ")||l.startsWith("--- ")||l.startsWith("+++ ")||l.startsWith("new file")||l.startsWith("deleted file")){l.startsWith("diff --git")&&(i+=`<div class="diff-line header"><span class="ln-body">${f(l)}</span></div>`);continue}if(l.startsWith("+"))r++,i+=`<div class="diff-line add"><span class="ln-no">${r}</span><span class="ln-body">${f(l)}</span></div>`;else if(l.startsWith("-"))o++,i+=`<div class="diff-line del"><span class="ln-no">${o}</span><span class="ln-body">${f(l)}</span></div>`;else if(l.startsWith("\\"))i+=`<div class="diff-line"><span class="ln-body">${f(l)}</span></div>`;else{if(!l&&!o&&!r)continue;o++,r++,i+=`<div class="diff-line"><span class="ln-no">${o}</span><span class="ln-no" style="margin-right:12px">${r}</span><span class="ln-body">${f(l)}</span></div>`}}return{html:i,lineCount:s.length}}var De=null;async function bt(e){let t=V;if(t)if(He(),pn()){M.style.display="none",h&&(Re(),h.destroy(),h=null,De=y,y=null),ce(null),ae.style.display="none",Y.style.display="none",mt.style.display="flex",vt.textContent=e,Be.textContent="Loading\u2026",Ie.innerHTML="";try{let s=await fetch(C("/api/git/diff?path="+encodeURIComponent(t)+"&file="+encodeURIComponent(e)));if(!s.ok)throw new Error(await s.text());let i=await s.json();mn(e,i.diff,i.stagedDiff)}catch(s){let i=s instanceof Error?s.message:String(s);Be.textContent="Error",Ie.innerHTML=`<div class="diff-empty" style="padding:24px;text-align:center;color:var(--panel-muted)">Error: ${f(i)}</div>`}}else{E.innerHTML=`<div class="git-diff-view"><div class="diff-header">
22
22
  <button class="diff-back">\u2190 Back</button>
23
23
  <span class="diff-filename">${f(e)}</span>
24
24
  <span class="diff-loading">Loading\u2026</span>
25
- </div></div>`,Ne(),L.classList.add("open"),xe.classList.add("open");try{let s=await fetch(x("/api/git/diff?path="+encodeURIComponent(t)+"&file="+encodeURIComponent(e)));if(!s.ok)throw new Error(await s.text());let i=await s.json();nn(e,i.diff,i.stagedDiff)}catch(s){let i=s instanceof Error?s.message:String(s);L.innerHTML=`<div class="git-diff-view"><div class="diff-header">
25
+ </div></div>`,Oe(),E.classList.add("open"),Se.classList.add("open");try{let s=await fetch(C("/api/git/diff?path="+encodeURIComponent(t)+"&file="+encodeURIComponent(e)));if(!s.ok)throw new Error(await s.text());let i=await s.json();fn(e,i.diff,i.stagedDiff)}catch(s){let i=s instanceof Error?s.message:String(s);E.innerHTML=`<div class="git-diff-view"><div class="diff-header">
26
26
  <button class="diff-back">\u2190 Back</button>
27
27
  <span class="diff-filename">${f(e)}</span>
28
- </div><div class="diff-empty">Error loading diff: ${f(i)}</div></div>`}}}function nn(e,t,s){if(!t&&!s){L.innerHTML=`<div class="git-diff-view"><div class="diff-header">
28
+ </div><div class="diff-empty">Error loading diff: ${f(i)}</div></div>`}}}function fn(e,t,s){if(!t&&!s){E.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">${f(e)}</span>
31
- </div><div class="diff-empty">No diff content available</div></div>`;return}let{html:i,lineCount:o}=pt(t,s);L.innerHTML=`<div class="git-diff-view"><div class="diff-header">
31
+ </div><div class="diff-empty">No diff content available</div></div>`;return}let{html:i,lineCount:o}=wt(t,s);E.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">${f(e)}</span>
34
34
  <span class="diff-filesize">${o} lines</span>
35
- </div><div class="diff-content">${i}</div></div>`,L.querySelector(".diff-back")?.addEventListener("click",()=>{L.innerHTML=ct,Ne(),y&&L.querySelectorAll(".git-popover-item").forEach(r=>{let c=parseInt(r.dataset.idx||"0",10),l=y.files[c];!l||l.status==="D"||(r.style.cursor="pointer",r.addEventListener("click",()=>ut(l.path)))}),rt()})}function sn(e,t,s){if(!t&&!s){Ee.textContent="No diff",ke.innerHTML='<div class="diff-empty" style="padding:24px;text-align:center;color:var(--panel-muted)">No diff content available</div>';return}let{html:i,lineCount:o}=pt(t,s);lt.textContent=e,Ee.textContent=o+" lines",ke.innerHTML=i}function an(){ot.style.display="none",Ce?(T.style.display="",T.classList.add("terminal-pending"),se(Ce),Ce=null):g?(T.style.display="",T.classList.add("terminal-pending"),mt()):j.style.display="flex"}en.addEventListener("click",an);function Te(){L.classList.remove("open"),xe.classList.remove("open")}xe.addEventListener("click",Te),document.addEventListener("keydown",e=>{e.key==="Escape"&&(Te(),Be())});async function ft(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 i=await s.json();y=i,oe(i);return}}}catch{}y=null,oe(null)}var Me=null;function mt(){Ie(),g&&(ft(g),Me=setInterval(()=>{g&&ft(g)},3e4))}function Ie(){Me&&(clearInterval(Me),Me=null)}function on(){if(Le=te.fsRoots||[],Le.length===0){if(g){ln(g);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 Le){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> ${f(e)}`,t.addEventListener("click",()=>N(e)),m.appendChild(t)}}async function ln(e){m.innerHTML='<div class="file-tree-empty">Loading...</div>';try{let t=await(await fetch(x("/api/fs/session-path?session="+encodeURIComponent(e)))).json();t.path?N(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 N(e){$=e,m.innerHTML='<div class="file-tree-empty">Loading...</div>';let t=Zt(e);try{let s=await(await fetch(x("/api/fs/list?path="+encodeURIComponent(e)))).json();await t,m.innerHTML="",oe(y),m.innerHTML+=Gt();let i=rn(e);if(i&&!Le.some(r=>e===r)){let r=document.createElement("div");r.className="file-tree-item",r.innerHTML="..",r.addEventListener("click",()=>N(i)),m.appendChild(r)}if(s.dirs)for(let r of s.dirs){let c=r.split("/").pop()||r.split("\\").pop(),l=document.createElement("div");l.className="file-tree-item",l.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> ${f(c)}`,l.addEventListener("click",()=>N(r)),m.appendChild(l)}else m.innerHTML="";let o=s.files||[];for(let r of o){let c=r.split("/").pop()||r.split("\\").pop(),l=Qt(r),p="",u="";if(l)switch(l){case"M":p="git-mod",u='<span class="git-file-status M">M</span>';break;case"A":p="git-add",u='<span class="git-file-status A">A</span>';break;case"D":p="git-del",u='<span class="git-file-status D">D</span>';break;case"?":p="git-untracked",u='<span class="git-file-status ?">?</span>';break;case"R":p="git-mod",u='<span class="git-file-status R">R</span>';break}let M=document.createElement("div");M.className="file-tree-item file"+(p?" "+p:""),M.innerHTML=`<span class="file-icon">\u{1F4C4}</span> ${u}${f(c)}`,M.addEventListener("click",()=>cn(r)),m.appendChild(M)}}catch{m.innerHTML='<div class="file-tree-error">Failed to load directory</div>'}}function rn(e){let t=e.lastIndexOf("/");return t<=0?null:e.substring(0,t)}async function cn(e){we=e,T.style.display="none",v&&(Ie(),v.destroy(),v=null,g=null),oe(null),Re(),j.style.display="none",ne.style.display="flex",Ot.textContent=e,I.textContent="Loading...",F.style.display="none";try{let t=await fetch(x("/api/file?path="+encodeURIComponent(e)));if(!t.ok){let i=await t.json();I.textContent=i.error||"Failed to load",ie.value="";return}let s=await t.json();ie.value=s.content,be=s.content,Ge=s.content,I.textContent=s.size+" bytes",F.style.display=""}catch{I.textContent="Failed to load",ie.value=""}}ie.addEventListener("input",()=>{be=ie.value}),F.addEventListener("click",async()=>{F.textContent="Saving...",F.disabled=!0;try{let e=await fetch(x("/api/file"),{method:"PUT",headers:{"Content-Type":"application/json"},body:JSON.stringify({path:we,content:be})});if(!e.ok){let t=await e.json();I.textContent=t.error||"Save failed";return}Ge=be,I.textContent="Saved"}catch{I.textContent="Save failed"}finally{F.disabled=!1,F.textContent="Save"}}),Kt.addEventListener("click",async()=>{if(confirm("Delete "+we+"?"))try{let e=await fetch(x("/api/file/delete"),{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({path:we})});if(!e.ok){let t=await e.json();I.textContent=t.error||"Delete failed";return}ne.style.display="none",j.style.display="flex",$&&N($)}catch{I.textContent="Delete failed"}}),qt.addEventListener("click",()=>{ne.style.display="none",j.style.display="flex",$&&N($)}),Xt.addEventListener("click",async()=>{let e=et.value.trim();if(!e)return;let t=$+"/"+e;try{let s=await fetch(x("/api/file/touch"),{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({path:t})});if(!s.ok){let i=await s.json();I.textContent=i.error||"Create failed";return}et.value="",$&&N($)}catch{I.textContent="Create failed"}}),document.getElementById("mode-settings").addEventListener("click",()=>{let e=tt.classList.toggle("open");Pe.classList.toggle("open",e)}),Pe.addEventListener("click",()=>{tt.classList.remove("open"),Pe.classList.remove("open")});var W="",le=document.createElement("div");le.className="session-popover-backdrop",document.body.appendChild(le);var P=document.createElement("div");P.id="session-popover",P.className="session-popover",P.style.display="none",P.innerHTML=`<div class="sp-field">
35
+ </div><div class="diff-content">${i}</div></div>`,E.querySelector(".diff-back")?.addEventListener("click",()=>{E.innerHTML=gt,Oe(),g&&E.querySelectorAll(".git-popover-item").forEach(r=>{let d=parseInt(r.dataset.idx||"0",10),l=g.files[d];!l||l.status==="D"||(r.style.cursor="pointer",r.addEventListener("click",()=>bt(l.path)))}),ht()})}function mn(e,t,s){if(!t&&!s){Be.textContent="No diff",Ie.innerHTML='<div class="diff-empty" style="padding:24px;text-align:center;color:var(--panel-muted)">No diff content available</div>';return}let{html:i,lineCount:o}=wt(t,s);vt.textContent=e,Be.textContent=o+" lines",Ie.innerHTML=i}function vn(){mt.style.display="none",De?(M.style.display="",M.classList.add("terminal-pending"),le(De),De=null):y?(M.style.display="",M.classList.add("terminal-pending"),Et()):Y.style.display="flex"}un.addEventListener("click",vn);function He(){E.classList.remove("open"),Se.classList.remove("open")}Se.addEventListener("click",He),document.addEventListener("keydown",e=>{e.key==="Escape"&&(He(),$e())});async function Lt(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 i=await s.json();g=i,ce(i);return}}}catch{}g=null,ce(null)}var Ae=null;function Et(){Re(),y&&(Lt(y),Ae=setInterval(()=>{y&&Lt(y)},3e4))}function Re(){Ae&&(clearInterval(Ae),Ae=null)}function hn(){if(Me=se.fsRoots||[],Me.length===0){if(y){gn(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 Me){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> ${f(e)}`,t.addEventListener("click",()=>N(e)),m.appendChild(t)}}async function gn(e){m.innerHTML='<div class="file-tree-empty">Loading...</div>';try{let t=await(await fetch(C("/api/fs/session-path?session="+encodeURIComponent(e)))).json();t.path?N(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 N(e){P=e,m.innerHTML='<div class="file-tree-empty">Loading...</div>';let t=cn(e);try{let s=await(await fetch(C("/api/fs/list?path="+encodeURIComponent(e)))).json();await t,m.innerHTML="",ce(g),m.innerHTML+=dn();let i=yn(e);if(i&&!Me.some(r=>e===r)){let r=document.createElement("div");r.className="file-tree-item",r.innerHTML="..",r.addEventListener("click",()=>N(i)),m.appendChild(r)}if(s.dirs)for(let r of s.dirs){let d=r.split("/").pop()||r.split("\\").pop(),l=document.createElement("div");l.className="file-tree-item",l.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> ${f(d)}`,l.addEventListener("click",()=>N(r)),m.appendChild(l)}else m.innerHTML="";let o=s.files||[];for(let r of o){let d=r.split("/").pop()||r.split("\\").pop(),l=rn(r),u="",v="";if(l)switch(l){case"M":u="git-mod",v='<span class="git-file-status M">M</span>';break;case"A":u="git-add",v='<span class="git-file-status A">A</span>';break;case"D":u="git-del",v='<span class="git-file-status D">D</span>';break;case"?":u="git-untracked",v='<span class="git-file-status ?">?</span>';break;case"R":u="git-mod",v='<span class="git-file-status R">R</span>';break}let I=document.createElement("div");I.className="file-tree-item file"+(u?" "+u:""),I.innerHTML=`<span class="file-icon">\u{1F4C4}</span> ${v}${f(d)}`,I.addEventListener("click",()=>wn(r)),m.appendChild(I)}}catch{m.innerHTML='<div class="file-tree-error">Failed to load directory</div>'}}function yn(e){let t=e.lastIndexOf("/");return t<=0?null:e.substring(0,t)}async function wn(e){Ce=e,M.style.display="none",h&&(Re(),h.destroy(),h=null,y=null),ce(null),We(),Y.style.display="none",ae.style.display="flex",tn.textContent=e,B.textContent="Loading...",_.style.display="none";try{let t=await fetch(C("/api/file?path="+encodeURIComponent(e)));if(!t.ok){let i=await t.json();B.textContent=i.error||"Failed to load",oe.value="";return}let s=await t.json();oe.value=s.content,Te=s.content,lt=s.content,B.textContent=s.size+" bytes",_.style.display=""}catch{B.textContent="Failed to load",oe.value=""}}oe.addEventListener("input",()=>{Te=oe.value}),_.addEventListener("click",async()=>{_.textContent="Saving...",_.disabled=!0;try{let e=await fetch(C("/api/file"),{method:"PUT",headers:{"Content-Type":"application/json"},body:JSON.stringify({path:Ce,content:Te})});if(!e.ok){let t=await e.json();B.textContent=t.error||"Save failed";return}lt=Te,B.textContent="Saved"}catch{B.textContent="Save failed"}finally{_.disabled=!1,_.textContent="Save"}}),nn.addEventListener("click",async()=>{if(confirm("Delete "+Ce+"?"))try{let e=await fetch(C("/api/file/delete"),{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({path:Ce})});if(!e.ok){let t=await e.json();B.textContent=t.error||"Delete failed";return}ae.style.display="none",Y.style.display="flex",P&&N(P)}catch{B.textContent="Delete failed"}}),sn.addEventListener("click",()=>{ae.style.display="none",Y.style.display="flex",P&&N(P)}),an.addEventListener("click",async()=>{let e=rt.value.trim();if(!e)return;let t=P+"/"+e;try{let s=await fetch(C("/api/file/touch"),{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({path:t})});if(!s.ok){let i=await s.json();B.textContent=i.error||"Create failed";return}rt.value="",P&&N(P)}catch{B.textContent="Create failed"}}),document.getElementById("mode-settings").addEventListener("click",()=>{let e=ct.classList.toggle("open");_e.classList.toggle("open",e)}),_e.addEventListener("click",()=>{ct.classList.remove("open"),_e.classList.remove("open")});var W="",de=document.createElement("div");de.className="session-popover-backdrop",document.body.appendChild(de);var H=document.createElement("div");H.id="session-popover",H.className="session-popover",H.style.display="none",H.innerHTML=`<div class="sp-field">
36
36
  <label>Rename session</label>
37
37
  <input type="text" id="sp-name" />
38
38
  </div>
@@ -41,5 +41,5 @@ var Yt=/\x1b\](?:10|11|110|111|104)(?:;[^\x07\x1b]*)?\x1b?(?:\\|\x07)/g;function
41
41
  <button class="btn" id="sp-cancel">Cancel</button>
42
42
  </div>
43
43
  <hr class="sp-divider" />
44
- <button class="btn danger" id="sp-delete">Delete session</button>`,document.body.appendChild(P);function dn(e){let t=e.getBoundingClientRect();P.style.top=t.bottom+4+"px",P.style.left=Math.max(8,Math.min(t.left,window.innerWidth-240))+"px"}function pn(e,t){W=e;let s=document.getElementById("sp-name");s.value=e,le.classList.add("open"),P.style.display="block",dn(t),setTimeout(()=>s.focus(),50)}function re(){le.classList.remove("open"),P.style.display="none"}le.addEventListener("click",re),document.getElementById("sp-save").addEventListener("click",async()=>{let e=document.getElementById("sp-name").value.trim();if(!e||e===W){re();return}try{if(!(await fetch(x("/api/sessions/rename"),{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({oldName:W,newName:e})})).ok)return;re(),O(),g===W&&se(e)}catch{}}),document.getElementById("sp-delete").addEventListener("click",async()=>{if(confirm('Delete session "'+W+'"?'))try{if(!(await fetch(x("/api/sessions/kill"),{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({name:W})})).ok)return;re(),g===W&&(v&&(v.destroy(),v=null),g=null,T.style.display="none",j.style.display="flex"),O()}catch{}}),document.getElementById("sp-cancel").addEventListener("click",re);var un={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=un[t.dataset.key];s&&(v.sendInput(s),v.focus())});var S=document.getElementById("mk-input"),vt=document.getElementById("mk-send");function ht(){if(!S||!v)return;let e=S.value;e&&(v.sendInput(e+"\r"),S.value="",S.rows=1,v.focus())}if(S&&(S.addEventListener("input",()=>{S.rows=1;let e=S.value.split(`
45
- `).length;S.rows=Math.min(e,4)}),S.addEventListener("keydown",e=>{e.key==="Enter"&&!e.shiftKey&&(e.preventDefault(),ht())})),vt&&vt.addEventListener("click",ht),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 ze=document.getElementById("process-panel"),ce=document.getElementById("proc-list"),fn=document.getElementById("proc-close"),_e=document.getElementById("proc-backdrop"),mn=document.getElementById("header-ram");function vn(){ce.innerHTML='<div class="proc-empty">Loading\u2026</div>',fetch(x("/api/system/processes")).then(e=>e.json()).then(e=>{if(!Array.isArray(e)||!e.length){ce.innerHTML='<div class="proc-empty">No processes</div>';return}let t="";for(let s of e){let i=s.rss,o=i<1048576?(i/1024).toFixed(0)+"K":(i/1048576).toFixed(1)+"M";t+='<div class="proc-row" data-pid="'+s.pid+'"><span class="proc-mem">'+s.mem+'%</span><span class="proc-rss">'+o+'</span><span class="proc-cmd" title="'+f(s.command)+'">'+f(s.command)+'</span><button class="proc-kill" title="Kill PID '+s.pid+'">&times;</button></div>'}ce.innerHTML=t;for(let s of ce.querySelectorAll(".proc-row")){let i=s.querySelector(".proc-kill");i&&i.addEventListener("click",o=>{let r=o.target.closest(".proc-row");!r||!confirm("Kill PID "+r.dataset.pid+"?")||fetch(x("/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(()=>{ce.innerHTML='<div class="proc-empty">Failed to load</div>'})}function hn(){ze.classList.add("open"),_e.classList.add("open"),vn()}function Be(){ze.classList.remove("open"),_e.classList.remove("open")}mn.addEventListener("click",e=>{e.stopPropagation(),ze.classList.contains("open")?Be():hn()}),fn.addEventListener("click",Be),_e.addEventListener("click",Be),window.__openSession=se,window.__refreshSidebar=O,O(),Re(),setInterval(()=>{document.visibilityState==="visible"&&O()},1e4);
44
+ <button class="btn danger" id="sp-delete">Delete session</button>`,document.body.appendChild(H);function bn(e){let t=e.getBoundingClientRect();H.style.top=t.bottom+4+"px",H.style.left=Math.max(8,Math.min(t.left,window.innerWidth-240))+"px"}function Ln(e,t){W=e;let s=document.getElementById("sp-name");s.value=e,de.classList.add("open"),H.style.display="block",bn(t),setTimeout(()=>s.focus(),50)}function ue(){de.classList.remove("open"),H.style.display="none"}de.addEventListener("click",ue),document.getElementById("sp-save").addEventListener("click",async()=>{let e=document.getElementById("sp-name").value.trim();if(!e||e===W){ue();return}try{if(!(await fetch(C("/api/sessions/rename"),{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({oldName:W,newName:e})})).ok)return;ue(),K(),y===W&&le(e)}catch{}}),document.getElementById("sp-delete").addEventListener("click",async()=>{if(confirm('Delete session "'+W+'"?'))try{if(!(await fetch(C("/api/sessions/kill"),{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({name:W})})).ok)return;ue(),y===W&&(h&&(h.destroy(),h=null),y=null,M.style.display="none",Y.style.display="flex"),K()}catch{}}),document.getElementById("sp-cancel").addEventListener("click",ue);var En={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||!h)return;let s=En[t.dataset.key];s&&(h.sendInput(s),h.focus())});var S=document.getElementById("mk-input"),xt=document.getElementById("mk-send");function kt(){if(!S||!h)return;let e=S.value;e&&(h.sendInput(e+"\r"),S.value="",S.rows=1,h.focus())}if(S&&(S.addEventListener("input",()=>{S.rows=1;let e=S.value.split(`
45
+ `).length;S.rows=Math.min(e,4)}),S.addEventListener("keydown",e=>{e.key==="Enter"&&!e.shiftKey&&(e.preventDefault(),kt())})),xt&&xt.addEventListener("click",kt),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 qe=document.getElementById("process-panel"),pe=document.getElementById("proc-list"),xn=document.getElementById("proc-close"),Ke=document.getElementById("proc-backdrop"),kn=document.getElementById("header-ram");function Cn(){pe.innerHTML='<div class="proc-empty">Loading\u2026</div>',fetch(C("/api/system/processes")).then(e=>e.json()).then(e=>{if(!Array.isArray(e)||!e.length){pe.innerHTML='<div class="proc-empty">No processes</div>';return}let t="";for(let s of e){let i=s.rss,o=i<1048576?(i/1024).toFixed(0)+"K":(i/1048576).toFixed(1)+"M";t+='<div class="proc-row" data-pid="'+s.pid+'"><span class="proc-mem">'+s.mem+'%</span><span class="proc-rss">'+o+'</span><span class="proc-cmd" title="'+f(s.command)+'">'+f(s.command)+'</span><button class="proc-kill" title="Kill PID '+s.pid+'">&times;</button></div>'}pe.innerHTML=t;for(let s of pe.querySelectorAll(".proc-row")){let i=s.querySelector(".proc-kill");i&&i.addEventListener("click",o=>{let r=o.target.closest(".proc-row");!r||!confirm("Kill PID "+r.dataset.pid+"?")||fetch(C("/api/system/kill"),{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({pid:parseInt(r.dataset.pid,10)})}).then(d=>d.json()).then(d=>{d.ok?r.style.opacity="0.3":alert("Failed: "+(d.error||"unknown"))}).catch(()=>alert("Network error"))})}}).catch(()=>{pe.innerHTML='<div class="proc-empty">Failed to load</div>'})}function Tn(){qe.classList.add("open"),Ke.classList.add("open"),Cn()}function $e(){qe.classList.remove("open"),Ke.classList.remove("open")}kn.addEventListener("click",e=>{e.stopPropagation(),qe.classList.contains("open")?$e():Tn()}),xn.addEventListener("click",$e),Ke.addEventListener("click",$e),window.__openSession=le,window.__refreshSidebar=K,K(),We(),setInterval(()=>{document.visibilityState==="visible"&&K()},1e4);
@@ -1,8 +1,8 @@
1
- const Pe=/\x1b\](?:10|11|110|111|104)(?:;[^\x07\x1b]*)?\x1b?(?:\\|\x07)/g;function A(s){return s.replace(Pe,"")}let B;function ke(){return B||(document.querySelector("link[data-tmux-web-xterm-css]")?B=Promise.resolve():(B=new Promise(o=>{const i=document.createElement("link");i.rel="stylesheet",i.href="/assets/xterm.css",i.setAttribute("data-tmux-web-xterm-css",""),i.addEventListener("load",()=>o(),{once:!0}),i.addEventListener("error",()=>o(),{once:!0}),document.head.appendChild(i)}),B))}class J{terminal;fitAddon;container;constructor(o,i,n){this.container=o,this.terminal=i,this.fitAddon=n,this.terminal.loadAddon(this.fitAddon),this.terminal.open(o)}static async create(o,i,n){const[{Terminal:a},{FitAddon:c}]=await Promise.all([import("@xterm/xterm"),import("@xterm/addon-fit"),ke()]),p=new a({fontSize:14,fontFamily:"'JetBrains Mono', 'SF Mono', 'Menlo', monospace",cursorBlink:!0,cursorStyle:"bar",scrollback:i,convertEol:!1,theme:n});return new J(o,p,new c)}get cols(){return this.terminal.cols}get rows(){return this.terminal.rows}write(o){return new Promise(i=>this.terminal.write(o,i))}reset(){this.terminal.reset()}scrollToBottom(){this.terminal.scrollToBottom()}scrollToLine(o){this.terminal.scrollToLine(Math.max(0,o))}isNearScrollbackTop(){return this.terminal.buffer.active.viewportY<=1}viewportY(){return this.terminal.buffer.active.viewportY}baseY(){return this.terminal.buffer.active.baseY}fit(){const o=Ye(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,i){const n=this.terminal.buffer.active,[a,c]=o<=i?[o,i]:[i,o],p=n.viewportY,l=[];for(let w=a;w<=c;w++){const f=n.getLine(p+w);l.push(f?f.translateToString(!0):"")}return l.join(`
2
- `)}selectRows(o,i){const n=this.terminal.buffer.active,[a,c]=o<=i?[o,i]:[i,o];this.terminal.selectLines(n.viewportY+a,n.viewportY+c)}selectCells(o,i,n,a){const c=this.terminal.buffer.active,p=Math.min(i,a),l=Math.max(i,a);if(p===l){const w=Math.min(o,n),f=Math.max(o,n);this.terminal.select(w,c.viewportY+p,f-w+1)}else this.terminal.selectLines(c.viewportY+p,c.viewportY+l)}getCellsText(o,i,n,a){const c=this.terminal.buffer.active,p=Math.min(i,a),l=Math.max(i,a),w=i<a?o:i>a?n:Math.min(o,n),f=i<a?n:i>a?o:Math.max(o,n),S=c.viewportY,b=[];for(let y=p;y<=l;y++){const v=c.getLine(S+y);if(!v){b.push("");continue}const T=y===p?w:0,E=y===l?f:this.terminal.cols-1;let z="";for(let M=T;M<=E;M++){const X=v.getCell(M);X&&(z+=X.getChars())}b.push(z.replace(/\s+$/,""))}return b.join(`
3
- `)}getSelection(){return this.terminal.getSelection()}clearSelection(){this.terminal.clearSelection()}hasSelectionSupport(){return!0}}function Ye(s){const o=s.getBoundingClientRect(),i=window.visualViewport;return i?{width:Math.min(o.width,i.width),height:Math.max(0,Math.min(o.height,i.height-Math.max(0,o.top)))}:o}function Fe(s,o,i){return s.innerHTML="",s.classList.add("terminal-pending"),(async()=>{const n=await J.create(s,i.scrollback,i.theme);let a,c=0,p,l=null,w=0,f="connecting",S=0,b=!1,y=[],v="",T=!1,E=1e3;const z=location.protocol==="https:"?"wss:":"ws:",M=i.wsBase||"/ws",X=z+"//"+location.host+M+"/"+encodeURIComponent(o),ae="/api/session/"+encodeURIComponent(o)+"/upload",le=/^((?!chrome|android|crios|fxios|edgios).)*safari/i.test(navigator.userAgent);function ce(){return y.join("")+v}async function ue(e,t=0){const r=e?n.viewportY():0,h=e?n.baseY():0,u=A(ce());if(n.reset(),!u){e||n.scrollToBottom();return}await n.write(u),e?n.scrollToLine(h+r+t):n.scrollToBottom()}function L(e){a?.readyState===WebSocket.OPEN&&a.send(JSON.stringify(e))}function fe(e){let t;try{t=JSON.parse(e)}catch{f==="live"&&(v+=e,n.write(A(e)));return}if(t.type==="auth.required"){const r=localStorage.getItem("tmux-web-token");r?L({type:"auth.token",token:r}):location.href="/login?returnTo="+encodeURIComponent(location.pathname+location.search);return}if(t.type==="attach_failed"&&typeof t.message=="string"){O=!0,f="dead",n.reset(),n.write(`\r
4
- \x1B[31m`+A(t.message)+`\x1B[0m\r
5
- `).then(()=>{j();try{a?.close()}catch{}});return}if(t.type==="auth.ok"){t.token&&localStorage.setItem("tmux-web-token",t.token),E=1e3,C(),L({type:"resize",cols:n.cols,rows:n.rows}),g();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 r=A(t.data);y=[r],v="",S=typeof t.lines=="number"?t.lines:i.terminal.initialLines,f="live",n.reset(),C(),L({type:"resize",cols:n.cols,rows:n.rows}),n.write(r).then(()=>n.scrollToBottom());return}if(t.type==="window_changed"&&typeof t.activeIndex=="number"){const r=new URL(location.href);r.searchParams.get("window")!==String(t.activeIndex)&&(r.searchParams.set("window",String(t.activeIndex)),history.replaceState(history.state,"",r)),window.dispatchEvent(new CustomEvent("tmux:windows",{detail:t.windows}));return}if(t.type==="history"&&typeof t.data=="string"){b=!1,t.lines>0&&t.data&&(y.unshift(t.data),S+=t.lines,ue(!0,t.lines));return}if(t.type==="data"&&typeof t.data=="string"){const r=A(t.data);if(f==="connecting"){f="live",v=r,n.write(r);return}f==="live"&&(v+=r,n.write(r))}}let O=!1;function G(){if(O)return;let e=X;const t=localStorage.getItem("tmux-web-token");t&&(e+=(e.includes("?")?"&":"?")+"token="+encodeURIComponent(t)),e+=(e.includes("?")?"&":"?")+"cols="+n.cols+"&rows="+n.rows,a=new WebSocket(e),a.onopen=()=>{f="connecting",S=0,b=!1,y=[],v="",n.reset(),E=1e3},a.onmessage=r=>{typeof r.data=="string"&&fe(r.data)},a.onclose=()=>{T||(f="connecting",!O&&setTimeout(()=>{E=Math.min(E*2,1e4),!T&&!O&&G()},E))},a.onerror=()=>a?.close()}function U(e){L({type:"input",data:e})}function C(){return n.fit()}function j(){s.classList.remove("terminal-pending")}function g(){c&&cancelAnimationFrame(c),p&&clearTimeout(p),C(),c=requestAnimationFrame(()=>{c=0,C()&&j()}),p=setTimeout(()=>{C()&&j()},120)}function de(){g(),setTimeout(g,50),setTimeout(g,150),setTimeout(g,300)}function $(e){return typeof e=="string"&&e.startsWith("image/")}function Q(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 r=e.items[t];if(r?.kind==="file"&&$(r.type))return r.getAsFile()}return null}async function pe(e){const t=new FormData,r=e instanceof File&&e.name?e.name:"upload";t.append("file",e,r);const h=localStorage.getItem("tmux-web-token"),u={};h&&(u.Authorization="Bearer "+h);const K=await fetch(ae,{method:"POST",body:t,headers:u});if(!K.ok){let ie="upload failed";try{const se=await K.json();se.error&&(ie=se.error)}catch{}throw new Error(ie)}const H=await K.json();if(!H.path)throw new Error("no path in response");return H.path}async function W(e){try{const t=await pe(e);U(t)}catch{}}n.onData(e=>U(e)),n.onResize(({cols:e,rows:t})=>L({type:"resize",cols:e,rows:t})),n.onScroll(()=>{f!=="live"||b||!n.isNearScrollbackTop()||(b=!0,L({type:"load_history",before:S}))});let P=!1,k=!1,d=null,m=null;const Y=document.createElement("div");Y.className="terminal-copy-banner",Y.innerHTML='<strong>Copy mode</strong><span class="hint">drag to copy \xB7 Esc exits</span>',Y.hidden=!0,s.appendChild(Y);const x=document.createElement("div");x.className="terminal-copy-banner terminal-copy-toast",x.textContent="Copied",x.hidden=!0,s.appendChild(x);function Z(e,t){const r=s.querySelector(".xterm-screen, canvas"),u=(r&&r.getBoundingClientRect().width>0?r:s).getBoundingClientRect(),K=u.height>0&&n.rows>0?u.height/n.rows:18,H=u.width>0&&n.cols>0?u.width/n.cols:9;return{row:Math.max(0,Math.min(n.rows-1,Math.floor((t-u.top)/K))),col:Math.max(0,Math.min(n.cols-1,Math.floor((e-u.left)/H)))}}async function q(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 F;function N(){x.hidden=!1,F&&clearTimeout(F),F=setTimeout(()=>{x.hidden=!0},1e3)}function D(e){P=e,Y.hidden=!e,s.classList.toggle("terminal-copy-mode-active",e),e&&n.focus()}function ee(){D(!P)}function he(e){T||e.button!==0||k||(P||e.shiftKey)&&(e.preventDefault(),e.stopPropagation(),k=!0,d=Z(e.clientX,e.clientY),m=d,n.selectCells(d.col,d.row,m.col,m.row),document.addEventListener("mousemove",R,!0),document.addEventListener("mouseup",V,!0))}function R(e){T||!k||!d||(e.preventDefault(),e.stopPropagation(),m=Z(e.clientX,e.clientY),n.selectCells(d.col,d.row,m.col,m.row))}function V(e){if(T||!k||!d||!m)return;e.preventDefault(),e.stopPropagation(),document.removeEventListener("mousemove",R,!0),document.removeEventListener("mouseup",V,!0),k=!1;const t=n.getCellsText(d.col,d.row,m.col,m.row);d=null,m=null,n.clearSelection(),D(!1),t&&(x.textContent="\u5DF2\u590D\u5236",q(t).then(N)),n.focus()}s.addEventListener("mousedown",he,!0),document.addEventListener("keydown",ge,!0);function ge(e){if(!(T||!n.isFocused()||e.defaultPrevented||e.isComposing)){if(P){if(e.key==="Escape"){e.preventDefault(),e.stopPropagation(),d=null,m=null,n.clearSelection(),D(!1);return}if(e.key==="Enter"||(e.ctrlKey||e.metaKey)&&e.code==="KeyC"){e.preventDefault(),e.stopPropagation(),q(n.getScreenText()).then(N),D(!1);return}}if(e.altKey&&e.code==="KeyC"&&!e.ctrlKey&&!e.metaKey){if(e.preventDefault(),e.stopPropagation(),d&&m){const t=n.getCellsText(d.col,d.row,m.col,m.row);d=null,m=null,n.clearSelection(),D(!1),t&&(x.textContent="Copied",q(t).then(N))}else{const t=n.getSelection();t?(n.clearSelection(),x.textContent="Copied",q(t).then(N)):ee()}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 r of t)for(const h of r.types)if($(h)){const u=await r.getType(h);await W(u);return}}}catch{}try{const t=await navigator.clipboard?.readText();t&&n.pasteText(te(t))}catch{}})();return}}}let _=0;function te(e){return e.split(`\r
1
+ const Ne=/\x1b\](?:10|11|110|111|104)(?:;[^\x07\x1b]*)?\x1b?(?:\\|\x07)/g;function te(s){return s.replace(/\x1b\[\?1049[hl]/g,"")}function O(s){return s.replace(Ne,"")}let N;function Xe(){return N||(document.querySelector("link[data-tmux-web-xterm-css]")?N=Promise.resolve():(N=new Promise(o=>{const i=document.createElement("link");i.rel="stylesheet",i.href="/assets/xterm.css",i.setAttribute("data-tmux-web-xterm-css",""),i.addEventListener("load",()=>o(),{once:!0}),i.addEventListener("error",()=>o(),{once:!0}),document.head.appendChild(i)}),N))}class ne{terminal;fitAddon;container;constructor(o,i,n){this.container=o,this.terminal=i,this.fitAddon=n,this.terminal.loadAddon(this.fitAddon),this.terminal.open(o)}static async create(o,i,n){const[{Terminal:a},{FitAddon:f}]=await Promise.all([import("@xterm/xterm"),import("@xterm/addon-fit"),Xe()]),h=new a({fontSize:14,fontFamily:"'JetBrains Mono', 'SF Mono', 'Menlo', monospace",cursorBlink:!0,cursorStyle:"bar",scrollback:i,convertEol:!1,smoothScrollDuration:120,theme:n});return new ne(o,h,new f)}get cols(){return this.terminal.cols}get rows(){return this.terminal.rows}write(o){return new Promise(i=>this.terminal.write(o,i))}reset(){this.terminal.reset()}scrollToBottom(){this.terminal.scrollToBottom()}scrollToLine(o){this.terminal.scrollToLine(Math.max(0,o))}scrollLines(o){const i=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}fit(){const o=Re(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,i){const n=this.terminal.buffer.active,[a,f]=o<=i?[o,i]:[i,o],h=n.viewportY,l=[];for(let d=a;d<=f;d++){const g=n.getLine(h+d);l.push(g?g.translateToString(!0):"")}return l.join(`
2
+ `)}selectRows(o,i){const n=this.terminal.buffer.active,[a,f]=o<=i?[o,i]:[i,o];this.terminal.selectLines(n.viewportY+a,n.viewportY+f)}selectCells(o,i,n,a){const f=this.terminal.buffer.active,h=Math.min(i,a),l=Math.max(i,a);if(h===l){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+l)}getCellsText(o,i,n,a){const f=this.terminal.buffer.active,h=Math.min(i,a),l=Math.max(i,a),d=i<a?o:i>a?n:Math.min(o,n),g=i<a?n:i>a?o:Math.max(o,n),I=f.viewportY,k=[];for(let T=h;T<=l;T++){const X=f.getLine(I+T);if(!X){k.push("");continue}const $=T===h?d:0,M=T===l?g:this.terminal.cols-1;let R="";for(let E=$;E<=M;E++){const y=X.getCell(E);y&&(R+=y.getChars())}k.push(R.replace(/\s+$/,""))}return k.join(`
3
+ `)}getSelection(){return this.terminal.getSelection()}clearSelection(){this.terminal.clearSelection()}hasSelectionSupport(){return!0}}function Re(s){const o=s.getBoundingClientRect(),i=window.visualViewport;return i?{width:Math.min(o.width,i.width),height:Math.max(0,Math.min(o.height,i.height-Math.max(0,o.top)))}:o}function Ue(s,o,i){return s.innerHTML="",s.classList.add("terminal-pending"),(async()=>{const n=await ne.create(s,i.scrollback,i.theme);let a,f=0,h,l=null,d=0,g=0,I=0;const k=.2,T=5,X=.94,$=.04;function M(){d&&(cancelAnimationFrame(d),d=0),g=0,I=0}function R(e){if(M(),Math.abs(e)<k)return;g=Math.max(-T,Math.min(T,e));const t=()=>{if(x){d=0;return}const r=n.viewportY();ue(g*16);const u=n.viewportY();if(g*=X,u===r){if(++I>=2){d=0;return}}else I=0;if(Math.abs(g)<$){d=0;return}d=requestAnimationFrame(t)};d=requestAnimationFrame(t)}let E=0,y="connecting",U=0,_=!1,q=[],D="",x=!1,Y=1e3;const he=location.protocol==="https:"?"wss:":"ws:",we=i.wsBase||"/ws",ge=he+"//"+location.host+we+"/"+encodeURIComponent(o),ye="/api/session/"+encodeURIComponent(o)+"/upload",ve=/^((?!chrome|android|crios|fxios|edgios).)*safari/i.test(navigator.userAgent);function Te(){return q.join("")+D}async function xe(e,t=0){const r=e?n.viewportY():0,u=e?n.baseY():0,c=O(Te());if(n.reset(),!c){e||n.scrollToBottom();return}await n.write(c),e?n.scrollToLine(u+r+t):n.scrollToBottom()}function L(e){a?.readyState===WebSocket.OPEN&&a.send(JSON.stringify(e))}function be(e){let t;try{t=JSON.parse(e)}catch{y==="live"&&(D+=e,n.write(O(e)));return}if(t.type==="auth.required"){const r=localStorage.getItem("tmux-web-token");r?L({type:"auth.token",token:r}):location.href="/login?returnTo="+encodeURIComponent(location.pathname+location.search);return}if(t.type==="attach_failed"&&typeof t.message=="string"){j=!0,y="dead",n.reset(),n.write(`\r
4
+ \x1B[31m`+O(t.message)+`\x1B[0m\r
5
+ `).then(()=>{H();try{a?.close()}catch{}});return}if(t.type==="auth.ok"){t.token&&localStorage.setItem("tmux-web-token",t.token),Y=1e3,C(),L({type:"resize",cols:n.cols,rows:n.rows}),w();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 r=te(O(t.data));q=[r],D="",U=typeof t.lines=="number"?t.lines:i.terminal.initialLines,y="live",n.reset(),C(),L({type:"resize",cols:n.cols,rows:n.rows}),n.write(r).then(()=>n.scrollToBottom());return}if(t.type==="window_changed"&&typeof t.activeIndex=="number"){const r=new URL(location.href);r.searchParams.get("window")!==String(t.activeIndex)&&(r.searchParams.set("window",String(t.activeIndex)),history.replaceState(history.state,"",r)),window.dispatchEvent(new CustomEvent("tmux:windows",{detail:t.windows}));return}if(t.type==="history"&&typeof t.data=="string"){_=!1,t.lines>0&&t.data&&(q.unshift(te(t.data)),U+=t.lines,xe(!0,t.lines));return}if(t.type==="data"&&typeof t.data=="string"){const r=te(O(t.data));if(y==="connecting"){y="live",D=r,n.write(r);return}y==="live"&&(D+=r,n.write(r))}}let j=!1;function oe(){if(j)return;let e=ge;const t=localStorage.getItem("tmux-web-token");t&&(e+=(e.includes("?")?"&":"?")+"token="+encodeURIComponent(t)),e+=(e.includes("?")?"&":"?")+"cols="+n.cols+"&rows="+n.rows,a=new WebSocket(e),a.onopen=()=>{y="connecting",U=0,_=!1,q=[],D="",n.reset(),Y=1e3},a.onmessage=r=>{typeof r.data=="string"&&be(r.data)},a.onclose=()=>{x||(y="connecting",!j&&setTimeout(()=>{Y=Math.min(Y*2,1e4),!x&&!j&&oe()},Y))},a.onerror=()=>a?.close()}function V(e){L({type:"input",data:e})}function C(){return n.fit()}function H(){s.classList.remove("terminal-pending")}function w(){f&&cancelAnimationFrame(f),h&&clearTimeout(h),C(),f=requestAnimationFrame(()=>{f=0,C()&&H()}),h=setTimeout(()=>{C()&&H()},120)}function Ee(){w(),setTimeout(w,50),setTimeout(w,150),setTimeout(w,300)}function re(e){return typeof e=="string"&&e.startsWith("image/")}function ie(e){return e?.files?.length?e.files[0]??null:null}function Le(e){if(!e?.items)return null;for(let t=0;t<e.items.length;t++){const r=e.items[t];if(r?.kind==="file"&&re(r.type))return r.getAsFile()}return null}async function Ce(e){const t=new FormData,r=e instanceof File&&e.name?e.name:"upload";t.append("file",e,r);const u=localStorage.getItem("tmux-web-token"),c={};u&&(c.Authorization="Bearer "+u);const b=await fetch(ye,{method:"POST",body:t,headers:c});if(!b.ok){let me="upload failed";try{const pe=await b.json();pe.error&&(me=pe.error)}catch{}throw new Error(me)}const S=await b.json();if(!S.path)throw new Error("no path in response");return S.path}async function Q(e){try{const t=await Ce(e);V(t)}catch{}}n.onData(e=>V(e)),n.onResize(({cols:e,rows:t})=>L({type:"resize",cols:e,rows:t})),n.onScroll(()=>{y!=="live"||_||!n.isNearScrollbackTop()||(_=!0,L({type:"load_history",before:U}))});let F=!1,A=!1,m=null,p=null;const K=document.createElement("div");K.className="terminal-copy-banner",K.innerHTML='<strong>Copy mode</strong><span class="hint">drag to copy \xB7 Esc exits</span>',K.hidden=!0,s.appendChild(K);const v=document.createElement("div");v.className="terminal-copy-banner terminal-copy-toast",v.textContent="Copied",v.hidden=!0,s.appendChild(v);function se(e,t){const r=s.querySelector(".xterm-screen, canvas"),c=(r&&r.getBoundingClientRect().width>0?r:s).getBoundingClientRect(),b=c.height>0&&n.rows>0?c.height/n.rows:18,S=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)/b))),col:Math.max(0,Math.min(n.cols-1,Math.floor((e-c.left)/S)))}}async function J(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 B;function W(){v.hidden=!1,B&&clearTimeout(B),B=setTimeout(()=>{v.hidden=!0},1e3)}function P(e){F=e,K.hidden=!e,s.classList.toggle("terminal-copy-mode-active",e),e&&n.focus()}function ae(){P(!F)}function Se(e){x||e.button!==0||A||(F||e.shiftKey)&&(e.preventDefault(),e.stopPropagation(),A=!0,m=se(e.clientX,e.clientY),p=m,n.selectCells(m.col,m.row,p.col,p.row),document.addEventListener("mousemove",Z,!0),document.addEventListener("mouseup",ee,!0))}function Z(e){x||!A||!m||(e.preventDefault(),e.stopPropagation(),p=se(e.clientX,e.clientY),n.selectCells(m.col,m.row,p.col,p.row))}function ee(e){if(x||!A||!m||!p)return;e.preventDefault(),e.stopPropagation(),document.removeEventListener("mousemove",Z,!0),document.removeEventListener("mouseup",ee,!0),A=!1;const t=n.getCellsText(m.col,m.row,p.col,p.row);m=null,p=null,n.clearSelection(),P(!1),t&&(v.textContent="\u5DF2\u590D\u5236",J(t).then(W)),n.focus()}s.addEventListener("mousedown",Se,!0),document.addEventListener("keydown",Me,!0);function Me(e){if(!(x||!n.isFocused()||e.defaultPrevented||e.isComposing)){if(F){if(e.key==="Escape"){e.preventDefault(),e.stopPropagation(),m=null,p=null,n.clearSelection(),P(!1);return}if(e.key==="Enter"||(e.ctrlKey||e.metaKey)&&e.code==="KeyC"){e.preventDefault(),e.stopPropagation(),J(n.getScreenText()).then(W),P(!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(),P(!1),t&&(v.textContent="Copied",J(t).then(W))}else{const t=n.getSelection();t?(n.clearSelection(),v.textContent="Copied",J(t).then(W)):ae()}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 r of t)for(const u of r.types)if(re(u)){const c=await r.getType(u);await Q(c);return}}}catch{}try{const t=await navigator.clipboard?.readText();t&&n.pasteText(le(t))}catch{}})();return}}}let G=0;function le(e){return e.split(`\r
6
6
  `).join(`
7
7
  `).split(`
8
- `).join("\r")}async function we(e){const t=me(e.clipboardData);if(t){e.preventDefault(),e.stopPropagation();const u=Date.now();if(u-_<50)return;_=u,await W(t);return}const r=e.clipboardData?.getData("text/plain");if(!r)return;e.preventDefault(),e.stopPropagation();const h=Date.now();h-_<50||(_=h,n.pasteText(te(r)))}let I=0;function ye(e){e.preventDefault(),I++,Q(e.dataTransfer)&&s.classList.add("terminal-drag-over")}function ve(e){e.preventDefault(),e.dataTransfer&&(e.dataTransfer.dropEffect="copy")}function Te(e){e.preventDefault(),I--,I<=0&&(I=0,s.classList.remove("terminal-drag-over"))}async function xe(e){e.preventDefault(),I=0,s.classList.remove("terminal-drag-over");const t=Q(e.dataTransfer);t&&await W(t)}function ne(e){!le||e.key!=="Escape"||P||e.defaultPrevented||e.repeat||e.metaKey||e.ctrlKey||e.altKey||n.isFocused()&&(e.preventDefault(),e.stopPropagation(),U("\x1B"))}s.addEventListener("paste",we),s.addEventListener("dragenter",ye),s.addEventListener("dragover",ve),s.addEventListener("dragleave",Te),s.addEventListener("drop",xe),document.addEventListener("keydown",ne,!0);function be(e){if(e.touches.length!==1){l=null;return}const t=e.touches[0];t&&(l={startX:t.clientX,startY:t.clientY,lastX:t.clientX,lastY:t.clientY,scrolling:!1},e.stopPropagation())}function Ee(e){if(!l||e.touches.length!==1)return;const t=e.touches[0];if(!t)return;const r=t.clientY-l.startY,h=t.clientX-l.startX;if(!l.scrolling){if(Math.abs(r)<8||Math.abs(r)<Math.abs(h))return;l.scrolling=!0,w=Date.now()+500}e.preventDefault(),e.stopPropagation(),De(-(t.clientY-l.lastY),t.clientX,t.clientY),l.lastX=t.clientX,l.lastY=t.clientY}function Le(e){if(!l)return;const t=l.scrolling;l=null,e.stopPropagation(),t?(w=Date.now()+500,e.preventDefault()):n.focus()}function Ce(e){l=null,e.stopPropagation()}function Se(e){e.pointerType==="touch"&&Date.now()<w&&(e.preventDefault(),e.stopPropagation())}function De(e,t,r){(s.querySelector(".xterm-screen")??s).dispatchEvent(new WheelEvent("wheel",{deltaY:e,deltaMode:WheelEvent.DOM_DELTA_PIXEL,clientX:t,clientY:r,bubbles:!0,cancelable:!0}))}s.addEventListener("touchstart",be,{passive:!0,capture:!0}),s.addEventListener("touchmove",Ee,{passive:!1,capture:!0}),s.addEventListener("touchend",Le,{passive:!1,capture:!0}),s.addEventListener("touchcancel",Ce,{passive:!0,capture:!0}),s.addEventListener("pointerup",Se,!0);function oe(){g()}window.addEventListener("resize",oe),window.visualViewport?.addEventListener("resize",g),window.visualViewport?.addEventListener("scroll",g);const re=new ResizeObserver(()=>g());re.observe(s),document.fonts?.ready.then(()=>{g(),setTimeout(g,50),setTimeout(g,200)}),s.addEventListener("focusin",de,!0);async function Me(){if(document.fonts?.ready)try{await Promise.race([document.fonts.ready,new Promise(e=>setTimeout(e,1e3))])}catch{}}return requestAnimationFrame(()=>{C()&&j(),(async()=>(await Me(),C()&&L({type:"resize",cols:n.cols,rows:n.rows}),G(),g()))()}),{destroy(){if(T=!0,D(!1),F&&clearTimeout(F),document.removeEventListener("mousemove",R,!0),document.removeEventListener("mouseup",V,!0),a){try{a.close(1e3,"session switch")}catch{}a=void 0}s.innerHTML="",s.classList.remove("terminal-pending"),window.removeEventListener("resize",oe),re.disconnect(),document.removeEventListener("keydown",ne,!0)},focus(){n.focus()},sendInput(e){U(e)},toggleCopyMode(){ee()}}})()}export{Fe as initTerminal};
8
+ `).join("\r")}async function De(e){const t=Le(e.clipboardData);if(t){e.preventDefault(),e.stopPropagation();const c=Date.now();if(c-G<50)return;G=c,await Q(t);return}const r=e.clipboardData?.getData("text/plain");if(!r)return;e.preventDefault(),e.stopPropagation();const u=Date.now();u-G<50||(G=u,n.pasteText(le(r)))}let z=0;function Pe(e){e.preventDefault(),z++,ie(e.dataTransfer)&&s.classList.add("terminal-drag-over")}function Ie(e){e.preventDefault(),e.dataTransfer&&(e.dataTransfer.dropEffect="copy")}function ke(e){e.preventDefault(),z--,z<=0&&(z=0,s.classList.remove("terminal-drag-over"))}async function Ye(e){e.preventDefault(),z=0,s.classList.remove("terminal-drag-over");const t=ie(e.dataTransfer);t&&await Q(t)}function ce(e){!ve||e.key!=="Escape"||F||e.defaultPrevented||e.repeat||e.metaKey||e.ctrlKey||e.altKey||n.isFocused()&&(e.preventDefault(),e.stopPropagation(),V("\x1B"))}s.addEventListener("paste",De),s.addEventListener("dragenter",Pe),s.addEventListener("dragover",Ie),s.addEventListener("dragleave",ke),s.addEventListener("drop",Ye),document.addEventListener("keydown",ce,!0);function Fe(e){if(e.touches.length!==1){l=null;return}const t=e.touches[0];t&&(M(),l={startX:t.clientX,startY:t.clientY,lastX:t.clientX,lastY:t.clientY,lastT:performance.now(),velocity:0,scrolling:!1},e.stopPropagation())}function Ae(e){if(!l||e.touches.length!==1)return;const t=e.touches[0];if(!t)return;const r=t.clientY-l.startY,u=t.clientX-l.startX;if(!l.scrolling){if(Math.abs(r)<8||Math.abs(r)<Math.abs(u))return;l.scrolling=!0,E=Date.now()+500}e.preventDefault(),e.stopPropagation();const c=performance.now(),b=t.clientY-l.lastY,S=c-l.lastT;S>0&&(l.velocity=b/S),ue(b),l.lastX=t.clientX,l.lastY=t.clientY,l.lastT=c}function Ke(e){if(!l)return;const t=l.scrolling,r=l.velocity;if(l=null,e.stopPropagation(),!t){n.focus();return}E=Date.now()+500,e.preventDefault(),r&&R(r)}function Be(e){l=null,M(),e.stopPropagation()}function ze(e){e.pointerType==="touch"&&Date.now()<E&&(e.preventDefault(),e.stopPropagation())}function ue(e){const t=s.querySelector(".xterm-rows > div"),r=t?t.getBoundingClientRect().height:16;let u=r>0?Math.round(e/r):e>0?1:-1;u===0&&(u=e>0?1:-1),n.scrollLines(u)}s.addEventListener("touchstart",Fe,{passive:!0,capture:!0}),s.addEventListener("touchmove",Ae,{passive:!1,capture:!0}),s.addEventListener("touchend",Ke,{passive:!1,capture:!0}),s.addEventListener("touchcancel",Be,{passive:!0,capture:!0}),s.addEventListener("pointerup",ze,!0);function fe(){w()}window.addEventListener("resize",fe),window.visualViewport?.addEventListener("resize",w),window.visualViewport?.addEventListener("scroll",w);const de=new ResizeObserver(()=>w());de.observe(s),document.fonts?.ready.then(()=>{w(),setTimeout(w,50),setTimeout(w,200)}),s.addEventListener("focusin",Ee,!0);async function Oe(){if(document.fonts?.ready)try{await Promise.race([document.fonts.ready,new Promise(e=>setTimeout(e,1e3))])}catch{}}return requestAnimationFrame(()=>{C()&&H(),(async()=>(await Oe(),C()&&L({type:"resize",cols:n.cols,rows:n.rows}),oe(),w()))()}),{destroy(){if(x=!0,M(),P(!1),B&&clearTimeout(B),document.removeEventListener("mousemove",Z,!0),document.removeEventListener("mouseup",ee,!0),a){try{a.close(1e3,"session switch")}catch{}a=void 0}s.innerHTML="",s.classList.remove("terminal-pending"),window.removeEventListener("resize",fe),de.disconnect(),document.removeEventListener("keydown",ce,!0)},focus(){n.focus()},sendInput(e){V(e)},toggleCopyMode(){ae()}}})()}export{Ue as initTerminal,te as stripAltScreenSequences};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tmux-weblink",
3
- "version": "2.0.23",
3
+ "version": "2.0.24",
4
4
  "description": "Access your tmux sessions from the browser. A continuation of tmux-web and persalink.",
5
5
  "type": "module",
6
6
  "bin": {