hanoman 0.2.6 → 0.3.0

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.
@@ -0,0 +1,9 @@
1
+ import{j as t,d as at,e as F,A as Xt,M as $e,S as me,G as Vt,J as zt,f as it,B as et,I as ve,w as Jt,D as Qt,a as ee,K as Zt,N as en,O as mt,Q as ht,c as Ye,U as tn,V as nn,W as rn,X as an,Y as sn,Z as Me,_ as At,$ as st,a0 as on,h as De,a1 as Lt,a2 as ln,a3 as cn,g as Xe,a4 as Nt,l as un,x as dn,a5 as Ve,p as pn,a6 as fn,a7 as Be,a8 as mn,a9 as gt,aa as hn,ab as gn}from"./index-DSFIYjSl.js";import{R as l,r as _}from"./react-DfGhg7ZW.js";import"./markdown-CWEY34jk.js";import{D as xn,o as bn}from"./xterm-3VOAfa_q.js";function ot(e){return e.endedAt?e.endedReason==="reconciled"?"interrupted":e.exitCode===null||e.exitCode===0?"completed":"failed":"running"}const vn=new RegExp(["\\x1b\\[[?>][0-9;]*c","\\x1b\\[\\??[0-9]+;[0-9]+R","\\x1b\\[\\??[0-9;]*n","\\x1b\\[\\??[0-9;]*\\$y","\\x1b\\][0-9][0-9;]*;[^\\x07\\x1b]*(?:\\x07|\\x1b\\\\)","\\x1bP[0-9]*[$+>][a-z|][^\\x1b]*\\x1b\\\\"].join("|"),"g"),yn=e=>e.length>0&&e.replace(vn,"")==="";function kn(e,n){if(e.type!=="keydown")return null;const a=e.key.toLowerCase();return e.metaKey||e.ctrlKey&&e.shiftKey?a==="c"?n?"copy":null:a==="v"?"paste":null:null}const jn=new Set(["image/png","image/jpeg","image/webp"]);function xt(e){return(e!=null&&e.files?Array.from(e.files):[]).filter(a=>jn.has(a.type))}function wn(e){return e!=null&&e.types?Array.from(e.types).includes("Files"):!1}const Sn=96,Cn=50,In=2,En=2;function Tn(e,n,a){if(!Number.isFinite(e)||e<=0)return n;const i=a+In,s=Math.floor((e-Sn-Cn-En*i)/i);return s>=n?n:Math.max(0,s-1)}const Rn=/enter to select/i,zn=/to navigate/i,An=/^\s*[❯>*]?\s*(\d)\.\s/;function Ln(e,n){var s;const a=e.join(`
2
+ `);if(!Rn.test(a)||!zn.test(a))return null;const i=e[n];return i?((s=An.exec(i))==null?void 0:s[1])??null:null}const Dt=10,Bt=24,lt=13,Nn=15;function tt(e){return Number.isFinite(e)?Math.min(Bt,Math.max(Dt,Math.round(e))):lt}const Dn=[{id:"esc",label:"Esc",seq:"\x1B",aria:"Kirim Escape ke terminal"},{id:"tab",label:"Tab",seq:" ",aria:"Kirim Tab ke terminal"},{id:"up",label:"↑",seq:"\x1B[A",aria:"Kirim panah atas ke terminal"},{id:"down",label:"↓",seq:"\x1B[B",aria:"Kirim panah bawah ke terminal"},{id:"left",label:"←",seq:"\x1B[D",aria:"Kirim panah kiri ke terminal"},{id:"right",label:"→",seq:"\x1B[C",aria:"Kirim panah kanan ke terminal"},{id:"enter",label:"Enter",seq:"\r",aria:"Kirim Enter ke terminal"}],Bn=/[\x00-\x1f\x7f]/;function ct(e){return!e||Bn.test(e)?"control":[...e].length>1?"bulk":"text"}function $t(e){return e?`\x1B[4m${e}\x1B[24m`:""}function Ge(e){return e>0?`\x1B[${e}D\x1B[K`:""}const $n=500,Mn=5e3,Pn=64,Fn=2;function Mt(){return{pending:"",since:null,altScreen:!1,suspendedUntil:0,typed:"",unechoed:"",gen:0,parsed:0}}const On=e=>e.gen!==e.parsed;function Wn(e,n){return{...e,altScreen:n}}const _n=/(password|passphrase|pass|pin)\s*(?:for\s+\S+\s*)?:\s*$/i;function Kn(e){return _n.test(e)}function Pt(e,n,a,i,s){return!s||!a.deliverable||e.altScreen||i<e.suspendedUntil||ct(n)!=="text"||a.cursorX+Fn+1>a.cols||a.line.slice(a.cursorX).trim().length>0?!1:!Kn(a.line.trimEnd())}function Hn(e,n){for(let a=n.length;a>0;a-=1)if(e.endsWith(n.slice(0,a)))return a;return 0}function qn(e,n,a,i,s){const d=ct(n);if(d==="text"&&On(e)&&s&&a.deliverable&&!e.altScreen&&i>=e.suspendedUntil)return e.unechoed.length>=Pn?{state:e,write:""}:{state:{...e,unechoed:e.unechoed+n,typed:""},write:"",deferred:!0};if(!Pt(e,n,a,i,s)){const h=i<e.suspendedUntil&&d==="text"?(e.typed+n).slice(-32):"";return h===e.typed&&!e.unechoed?{state:e,write:""}:{state:{...e,typed:h,unechoed:""},write:""}}return{state:{...e,pending:e.pending+n,unechoed:e.unechoed+n,since:null,typed:""},write:$t(n)}}function Gn(e,n){if(!n)return!1;const a=n.slice(-Math.min(2,n.length));return e.endsWith(a)}function Un(e,n,a){return a>=e.suspendedUntil?e.typed?{...e,typed:""}:e:Gn(n,e.typed)?{...e,suspendedUntil:0,typed:""}:e}function Yn(e,n,a){return{state:{...e,pending:"",since:null,gen:e.gen+1},write:Ge(e.pending.length)+n}}function Xn(e,n,a,i,s){if(n!==e.gen)return{state:e,write:""};const d=a.line.slice(0,a.cursorX),v=Un({...e,parsed:n},d,i);if(!v.unechoed)return{state:v,write:""};const h=v.unechoed.slice(Hn(d,v.unechoed));if(!h)return{state:{...v,unechoed:""},write:""};const I=Jn({...v,pending:""},h,a,i,s);return I.write?{state:{...I.state,unechoed:h},write:I.write}:{state:{...v,pending:"",unechoed:""},write:""}}function Vn(e,n){return!e.pending||e.since!==null?e:{...e,since:n}}function Jn(e,n,a,i,s){if(!n)return{state:e,write:""};const d=[...n];for(let v=0;v<d.length;v+=1){const h={...a,cursorX:a.cursorX+v};if(!Pt({...e},d[v],h,i,s))return{state:e,write:""}}return{state:{...e,pending:n,since:null},write:$t(n)}}function Qn(e,n){return!e.pending||e.since===null||n<e.since+$n?{state:e,write:"",missed:!1}:{state:{...e,pending:"",since:null,suspendedUntil:n+Mn,typed:"",unechoed:""},write:Ge(e.pending.length),missed:!0}}function bt(e){const n=((e==null?void 0:e.gen)??0)+1;return{...Mt(),gen:n,parsed:n}}const Zn=16;function er(e){let n="",a;const i=()=>{if(a&&(clearTimeout(a),a=void 0),!n)return;const s=n;n="",e(s)};return{push(s,d){if(!d||ct(s)!=="text"){i(),s&&e(s);return}n+=s,a||(a=setTimeout(i,Zn))},flush:i,dispose(){i()}}}const tr=250,nr=512,rr={"\x1B":"\\e","\r":"\\r","\n":"\\n"," ":"\\t","\b":"\\b","":"\\x7f"};function vt(e){let n="";for(const a of e){const i=rr[a];if(i){n+=i;continue}const s=a.codePointAt(0);n+=s<32||s===127?`\\x${s.toString(16).padStart(2,"0")}`:a}return n}function ar(e){const n=e.batchMs??tr,a=e.max??nr;let i=null,s=[],d,v=!1;const h=()=>{if(d&&(clearTimeout(d),d=void 0),!s.length)return;const I=s;s=[],e.send(I)};return{record(I,T,g){if(v)return;const b=e.now();i===null&&(i=b);const N={t:b-i,k:I,v:T};g!==void 0&&(N.n=g),s.push(N),s.length>a&&(s=s.slice(s.length-a)),d||(d=setTimeout(h,n))},flush:h,dispose(){h(),v=!0}}}const ir="",sr=350,or=1e3;function ut(){return{text:"",sentPrefix:""}}function lr(e,n){const a=[...e],i=[...n];let s=0;for(;s<a.length&&s<i.length&&a[s]===i[s];)s+=1;return s}function dt(e,n){const a=lr(e,n);return ir.repeat([...e].length-a)+[...n].slice(a).join("")}function cr(e,n){return{...e,text:n}}function ur(e){return{state:{...e,sentPrefix:e.text},send:dt(e.sentPrefix,e.text)}}function dr(e){return{state:ut(),send:dt(e.sentPrefix,e.text)+"\r"}}function pr(e){return{state:ut(),send:dt(e.sentPrefix,e.text)}}function fr(e,n){return n.held?{kind:"held",text:"tertahan — Kirim di atas"}:n.n>0?{kind:"queued",text:`diantre ${n.n}`}:e==="open"?{kind:"sent",text:"terkirim"}:null}function mr({sessionId:e,send:n,external:a,linkState:i,queue:s}){const[d,v]=l.useState(""),h=l.useRef(ut()),I=l.useRef(n);I.current=n;const T=l.useRef(void 0),g=l.useRef(void 0),b=()=>{clearTimeout(T.current),T.current=void 0,clearTimeout(g.current),g.current=void 0},N=C=>{b(),h.current=C.state,C.send&&I.current(C.send)},z=()=>N(ur(h.current));a.current=()=>{N(pr(h.current)),v("")},l.useEffect(()=>()=>{a.current=()=>{}},[a]),l.useEffect(()=>b,[]);const E=C=>{h.current=cr(h.current,C),v(C),clearTimeout(T.current),T.current=setTimeout(z,sr),g.current||(g.current=setTimeout(z,or))},j=()=>{N(dr(h.current)),v("")},f=fr(i,s);return t.jsxs("div",{className:"hn-terminal-composer",children:[t.jsx(at,{size:"lg",mono:!0,value:d,"data-testid":"terminal-composer","aria-label":`Ketik untuk sesi ${e}`,placeholder:"mis. pnpm vitest --run",autoCapitalize:"off",autoCorrect:"off",spellCheck:!1,autoComplete:"off",enterKeyHint:"send",style:{flex:"1 1 160px",minWidth:0},onChange:C=>E(C.target.value),onBlur:()=>z(),onKeyDown:C=>{C.key!=="Enter"||C.nativeEvent.isComposing||(C.preventDefault(),j())}}),f&&t.jsx("span",{"data-testid":"terminal-composer-status",className:`hn-terminal-composer-status hn-terminal-composer-status--${f.kind}`,children:f.text})]})}const Ft=[500,1e3,2e3,4e3,8e3,8e3,8e3,8e3,8e3,8e3,8e3,8e3],yt=Ft.length,hr=4096,gr=/[\r\n]/;function Ot({sessionId:e,onExit:n,onPhases:a,fontSize:i=lt,showKeys:s=!1,predict:d=!0,diag:v=!1}){const h=l.useRef(null),I=l.useRef(i);I.current=i;const T=l.useRef(d);T.current=d;const g=l.useRef(v);g.current=v;const b=l.useRef(null),N=l.useRef(n);N.current=n;const z=l.useRef(a);z.current=a;const[E,j]=l.useState({state:"connecting"}),[f,C]=l.useState({n:0,held:!1,full:!1}),S=l.useRef(()=>{}),k=l.useRef(()=>{}),M=l.useRef(()=>{}),w=l.useRef(()=>{}),D=l.useRef(()=>{}),p=l.useRef(()=>{});return l.useEffect(()=>{const c=h.current;if(!c)return;const L=getComputedStyle(document.documentElement),B=(u,r)=>L.getPropertyValue(u).trim()||r,x=new xn({fontFamily:B("--font-mono","monospace"),fontSize:tt(I.current),cursorBlink:!0,macOptionClickForcesSelection:!0,theme:{background:B("--term-bg","#1c1810"),foreground:B("--term-fg","#e9e0cd")}}),H=new bn;x.loadAddon(H),x.open(c);const q=()=>{const u=c.getBoundingClientRect();return u.width>0&&u.height>0?u:null};q()&&H.fit();let A,G=!1,te=0,ne,U=!1;const le=u=>{(A==null?void 0:A.readyState)===WebSocket.OPEN&&A.send(JSON.stringify(u))};b.current={term:x,fit:H,send:le};const V=ar({now:()=>Date.now(),send:u=>le({t:"diag",ev:u})}),J=(u,r,o)=>{g.current&&V.record(u,r,o)};let Y="",X=!1,Q=!1,re=0,ce=0,he=!1;const ue=new Map,O=u=>{if(re+=1,ce+=1,g.current){if(ue.size>256)for(const r of[...ue.keys()].slice(0,128))ue.delete(r);ue.set(re,Date.now())}le({t:"in",d:u,seq:re})},W=()=>C({n:Y.length,held:X,full:Q}),K=u=>{if(!X&&!Y&&(A==null?void 0:A.readyState)===WebSocket.OPEN){O(u);return}if(!(he||yn(u))){if(Y.length+u.length>hr){Q=!0,W();return}Y+=u,W()}};let R=Mt();const ae=er(K),ie=u=>ae.push(u,!1);k.current=ie;const se=u=>{D.current(),ie(u)};p.current=se;const we=()=>{var r;const u=x.buffer.active;return{cursorX:u.cursorX,cols:x.cols,deliverable:!he&&!Q,line:((r=u.getLine(u.viewportY+u.cursorY))==null?void 0:r.translateToString(!0))??""}},ge=()=>{ce===0&&(A==null?void 0:A.readyState)===WebSocket.OPEN&&(R=Vn(R,Date.now()))},Fe=()=>{if(!Y||(A==null?void 0:A.readyState)!==WebSocket.OPEN){W();return}const u=Y;Y="",Q=!1,W(),O(u)},Re=()=>{if(ae.flush(),!Y){W();return}if(gr.test(Y)){X=!0,W();return}Fe()};M.current=()=>{X=!1,Fe()},w.current=()=>{Y="",X=!1,Q=!1,W()};const Se=u=>{D.current();const r=R.pending.length>0;J("data",vt(u));const o=we(),m=qn(R,u,o,Date.now(),T.current);R=m.state,m.write?x.write(m.write):m.deferred?J("pred","tangguh: frame server in flight"):J("pred",`tolak cx=${o.cursorX}/${o.cols} alt=${R.altScreen?1:0} deliverable=${o.deliverable?1:0} suspend=${Math.max(0,R.suspendedUntil-Date.now())}`),ae.push(u,r||m.write.length>0||m.deferred===!0)},ye=setInterval(()=>{const u=Qn(R,Date.now());R=u.state,u.write&&x.write(u.write)},100),ze=()=>{F.issueWsTicket(`terminal:${e}`).then(({ticket:u})=>{if(G)return;const r=location.protocol==="https:"?"wss:":"ws:",o=new WebSocket(`${r}//${location.host}${Xt.terminalWs(e)}`,[`hanoman-ticket.${u}`]);A=o,o.onopen=()=>{te=0,re=0,ce=0;const m=Ge(R.pending.length);m&&x.write(m),R=bt(R),j({state:"open"}),q()&&((typeof window.matchMedia!="function"||window.matchMedia("(hover: hover) and (pointer: fine)").matches)&&x.focus(),le({t:"resize",cols:x.cols,rows:x.rows})),Re()},o.onmessage=m=>{var Z;const y=JSON.parse(m.data);if(y.t==="data"){const de=Yn(R,y.d??"");R=de.state;const oe=R.gen;x.write(de.write,()=>{if(G)return;const fe=Xn(R,oe,we(),Date.now(),T.current);R=fe.state,fe.write&&x.write(fe.write),ge()}),ge()}else if(y.t==="ack"){if(ce=Math.max(0,ce-1),typeof y.seq=="number"){const de=ue.get(y.seq);de!==void 0&&(ue.delete(y.seq),J("ack",String(y.seq),Date.now()-de))}ge()}else y.t==="phase"?(Z=z.current)==null||Z.call(z,y.phases??[],y.complete===!0):y.t==="alt"?R=Wn(R,y.on===!0):y.t==="exit"&&(U=!0,x.write(`\r
3
+ \x1B[33m— sesi berakhir (exit ${y.code}) —\x1B[0m\r
4
+ `),N.current(y.code??0))},o.onclose=m=>{if(!(G||U)){if(m.code===4004){he=!0;const y=Ge(R.pending.length);y&&x.write(y),R=bt(R),Y="",X=!1,Q=!1,W(),j({state:"gone"});return}Ae()}},o.onerror=()=>{}}).catch(()=>{G||(x.write(`\r
5
+ \x1B[31mWebSocket admission gagal\x1B[0m\r
6
+ `),Ae())})},Ae=()=>{if(te>=yt){j({state:"lost"});return}const u=Ft[te];te+=1,j({state:"retrying",attempt:te}),ne=setTimeout(ze,u)};S.current=()=>{G||(clearTimeout(ne),te=0,j({state:"retrying",attempt:1}),ze())},ze(),x.attachCustomKeyEventHandler(u=>{var o,m;const r=kn(u,x.hasSelection());return r==="copy"?((o=navigator.clipboard)==null||o.writeText(x.getSelection()),!1):r==="paste"?((m=navigator.clipboard)==null||m.readText().then(y=>{y&&se(y)}),!1):!0}),x.attachCustomWheelEventHandler(u=>{if(!u.shiftKey)return!0;const r=q();if(!r||x.rows<=0)return!0;const o=r.height/x.rows,m=Math.trunc(u.deltaY/o)||Math.sign(u.deltaY);return m&&x.scrollLines(m),!1});const Ue=x.onData(Se),$=x.textarea,Le=u=>J("key",u.key,u.keyCode),xe=u=>J("comp",`${u.type}:${vt(u.data??"")}`);$==null||$.addEventListener("keydown",Le),$==null||$.addEventListener("compositionstart",xe),$==null||$.addEventListener("compositionupdate",xe),$==null||$.addEventListener("compositionend",xe);let pe=null,ke=0,Ce=!1;const je=()=>{pe=null,ke=0,Ce=!1},Oe=u=>{if(u.touches.length!==1){je();return}pe=u.touches[0].clientY,ke=0,Ce=!1},We=u=>{if(pe===null||u.touches.length!==1){je();return}const r=q();if(!r||x.rows<=0)return;const o=u.touches[0].clientY;ke+=pe-o,pe=o;const m=r.height/x.rows,y=Math.trunc(ke/m);y!==0&&(x.scrollLines(y),ke-=y*m,Ce=!0),u.preventDefault()},Ie=u=>{var fe,pt;const r=pe!==null&&!Ce,o=((pt=(fe=u.changedTouches)==null?void 0:fe[0])==null?void 0:pt.clientY)??pe;if(je(),!r||o===null||o===void 0)return;const m=q();if(!m||x.rows<=0)return;const y=Math.floor((o-m.top)/(m.height/x.rows)),Z=x.buffer.active,de=Array.from({length:x.rows},(_r,Yt)=>{var ft;return((ft=Z.getLine(Z.viewportY+Yt))==null?void 0:ft.translateToString(!0))??""}),oe=Ln(de,y);oe&&se(oe)},P=async u=>{for(const r of u)try{const{path:o}=await F.uploadTerminalAttachment(e,r);se(`${o} `)}catch(o){x.write(`\r
7
+ \x1B[31mlampiran gagal: ${o.message}\x1B[0m\r
8
+ `)}},Ne=u=>{const r=xt(u.clipboardData);r.length&&(u.preventDefault(),P(r))},_e=u=>{wn(u.dataTransfer)&&u.preventDefault()},Ke=u=>{const r=xt(u.dataTransfer);r.length&&(u.preventDefault(),P(r))};c.addEventListener("paste",Ne),c.addEventListener("dragover",_e),c.addEventListener("drop",Ke),c.addEventListener("touchstart",Oe,{passive:!0}),c.addEventListener("touchmove",We,{passive:!1}),c.addEventListener("touchend",Ie,{passive:!0}),c.addEventListener("touchcancel",je,{passive:!0});const He=new ResizeObserver(u=>{var o;const r=((o=u[0])==null?void 0:o.contentRect)??c.getBoundingClientRect();r.width<=0||r.height<=0||(H.fit(),le({t:"resize",cols:x.cols,rows:x.rows}))});return He.observe(c),()=>{G=!0,clearTimeout(ne),S.current=()=>{},k.current=()=>{},p.current=()=>{},M.current=()=>{},w.current=()=>{},b.current=null,c.removeEventListener("paste",Ne),c.removeEventListener("dragover",_e),c.removeEventListener("drop",Ke),c.removeEventListener("touchstart",Oe),c.removeEventListener("touchmove",We),c.removeEventListener("touchend",Ie),c.removeEventListener("touchcancel",je),He.disconnect(),clearInterval(ye),ae.dispose(),V.dispose(),$==null||$.removeEventListener("keydown",Le),$==null||$.removeEventListener("compositionstart",xe),$==null||$.removeEventListener("compositionupdate",xe),$==null||$.removeEventListener("compositionend",xe),Ue.dispose(),A==null||A.close(),x.dispose()}},[e]),l.useEffect(()=>{const c=b.current,L=h.current;if(!c||!L)return;const B=tt(i);if(c.term.options.fontSize===B)return;c.term.options.fontSize=B;const x=L.getBoundingClientRect();x.width<=0||x.height<=0||(c.fit.fit(),c.send({t:"resize",cols:c.term.cols,rows:c.term.rows}))},[i]),l.useEffect(()=>{const c=b.current,L=h.current;if(!c||!L)return;const B=L.getBoundingClientRect();B.width<=0||B.height<=0||(c.fit.fit(),c.send({t:"resize",cols:c.term.cols,rows:c.term.rows}))},[s]),t.jsxs("div",{style:{display:"flex",flexDirection:"column",height:"100%",minHeight:0},children:[(E.state!=="open"&&E.state!=="connecting"||f.held||f.full)&&t.jsxs("div",{"data-testid":"terminal-link",style:{display:"flex",alignItems:"center",gap:8,flex:"0 0 auto",flexWrap:"wrap",padding:"3px 8px",fontFamily:"var(--font-mono)",fontSize:11,background:E.state==="retrying"||f.held?"var(--status-warn-tint)":"var(--status-err-tint)",color:"var(--text-body)"},children:[E.state==="retrying"&&t.jsxs("span",{children:["menyambung ulang… (",E.attempt,"/",yt,")"]}),E.state==="gone"&&t.jsx("span",{children:"sesi tidak ditemukan di tmux"}),E.state==="lost"&&t.jsxs(t.Fragment,{children:[t.jsx("span",{children:"terputus"}),t.jsx("button",{type:"button",className:"hn-terminal-action hn-terminal-action--text",onClick:()=>S.current(),children:"Sambungkan lagi"})]}),f.n>0&&!f.held&&t.jsxs("span",{"data-testid":"terminal-queue",children:[f.n," ketikan diantre"]}),f.held&&t.jsxs(t.Fragment,{children:[t.jsxs("span",{"data-testid":"terminal-held",children:[f.n," ketikan tertahan — belum dikirim"]}),t.jsx("button",{type:"button",className:"hn-terminal-action hn-terminal-action--text",onClick:()=>M.current(),children:"Kirim"}),t.jsx("button",{type:"button",className:"hn-terminal-action hn-terminal-action--text",onClick:()=>w.current(),children:"Buang"})]}),f.full&&t.jsx("span",{"data-testid":"terminal-queue-full",children:"antrean penuh"})]}),t.jsx("div",{ref:h,"data-testid":"terminal-host",style:{flex:1,minHeight:0,width:"100%",background:"var(--term-bg)",padding:8,borderRadius:"var(--radius-sm)",touchAction:"pan-x pinch-zoom",overscrollBehavior:"contain"}}),s&&t.jsx(mr,{sessionId:e,send:c=>k.current(c),external:D,linkState:E.state,queue:f}),s&&t.jsx(xr,{onKey:c=>p.current(c)})]})}function xr({onKey:e}){return t.jsx("div",{className:"hn-terminal-keys",role:"group","aria-label":"Tombol terminal",children:Dn.map(n=>t.jsx("button",{type:"button",className:"hn-terminal-key","aria-label":n.aria,title:n.aria,onClick:()=>e(n.seq),children:n.label},n.id))})}const kt=20;function br(e,n){if(!n)return"—";const a=new Date(n).getTime()-new Date(e).getTime();if(!Number.isFinite(a)||a<0)return"—";const i=Math.round(a/1e3);if(i<60)return`${i} dtk`;const s=Math.round(i/60);return s<60?`${s} mnt`:`${Math.floor(s/60)} jam ${s%60} mnt`}function vr(e){switch(ot(e)){case"running":return{label:"berjalan",tone:"neutral"};case"interrupted":return{label:"terputus",tone:"warn"};case"failed":return{label:`exit ${e.exitCode}`,tone:"err"};default:return{label:"selesai",tone:"ok"}}}const Wt=e=>ot(e)==="interrupted"?"—":br(e.startedAt,e.endedAt),_t=e=>zt[e]??e;function yr({projects:e,onClose:n,onRestart:a}){const[i,s]=l.useState([]),[d,v]=l.useState(0),[h,I]=l.useState(1),[T,g]=l.useState(!1),[b,N]=l.useState(""),[z,E]=l.useState(""),[j,f]=l.useState(""),[C,S]=l.useState(""),[k,M]=l.useState(null);l.useEffect(()=>{const p=setTimeout(()=>S(j.trim()),250);return()=>clearTimeout(p)},[j]),l.useEffect(()=>{I(1)},[b,z,C]),l.useEffect(()=>{let p=!0;return g(!0),F.listSessionHistory({projectId:b||void 0,kind:z||void 0,q:C||void 0,page:h,limit:kt}).then(c=>{p&&(v(c.total),s(c.items))}).catch(()=>{p&&(s([]),v(0))}).finally(()=>{p&&g(!1)}),()=>{p=!1}},[b,z,C,h]);const w=Qt(d,h,kt),D=p=>{var c;return((c=e.find(L=>L.id===p))==null?void 0:c.name)??p};return t.jsxs($e,{open:!0,title:"Riwayat sesi",icon:"history",onClose:n,width:900,children:[t.jsxs("div",{style:{display:"flex",alignItems:"center",gap:10,flexWrap:"wrap",marginBottom:10},children:[t.jsx(at,{size:"sm",leftIcon:"search",placeholder:"mis. spec-412 atau reverse","aria-label":"Cari riwayat sesi",value:j,onChange:p=>f(p.target.value),style:{flex:"1 1 200px"}}),t.jsx(me,{size:"sm","aria-label":"Filter project",value:b,onChange:p=>N(p.target.value),options:[{value:"",label:"Semua project"}].concat(e.map(p=>({value:p.id,label:p.name})))}),t.jsx(me,{size:"sm","aria-label":"Filter jenis",value:z,onChange:p=>E(p.target.value),options:[{value:"",label:"Semua jenis"}].concat(Vt.map(p=>({value:p,label:zt[p]})))})]}),i.length===0&&!T?t.jsx(it,{kind:"empty",icon:"history",title:"Belum ada riwayat sesi",hint:"Riwayat terisi sendiri saat sesi terminal dibuka lalu ditutup — termasuk sesi backlog, terminal biasa, dan sesi project-level."}):t.jsxs("div",{style:{display:"flex",flexDirection:"column",maxHeight:"60vh",overflowY:"auto"},children:[i.map(p=>{const c=vr(p);return t.jsx("button",{onClick:()=>M(p),style:{cursor:"pointer",display:"block",width:"100%",flex:"0 0 auto",font:"inherit",color:"inherit",textAlign:"left",background:"transparent",padding:"9px 8px",border:"none",borderBottom:"1px solid var(--border-hair)"},children:t.jsxs("span",{className:"hn-dense-row hn-picker-row",style:{display:"flex",alignItems:"center",gap:10,width:"100%"},children:[t.jsx("span",{style:{fontFamily:"var(--font-mono)",fontSize:11,color:"var(--text-subtle)",flex:"0 0 132px"},children:new Date(p.startedAt).toLocaleString("id-ID")}),t.jsx(et,{size:"sm",tone:"neutral",children:_t(p.kind)}),t.jsx("span",{className:"hn-picker-title",style:{flex:1,minWidth:0,fontSize:13,color:"var(--text-strong)",overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"},children:p.title??p.specId??D(p.projectId)}),p.transcriptBytes!==null&&t.jsx(ve,{name:"file-text",size:12,color:"var(--text-subtle)"}),t.jsx("span",{style:{fontFamily:"var(--font-mono)",fontSize:11,color:"var(--text-muted)",flex:"0 0 72px"},children:Wt(p)}),t.jsx(et,{size:"sm",tone:c.tone,children:c.label})]})},p.id)}),T&&t.jsx("div",{style:{padding:"10px 8px",textAlign:"center",fontSize:11,color:"var(--text-subtle)"},children:"memuat…"})]}),t.jsx(Jt,{page:w.page,pageCount:w.pageCount,total:d,from:w.from,to:w.to,onPage:I,unit:"sesi"}),k&&t.jsx(kr,{row:k,projectName:D(k.projectId),onBack:()=>M(null),onRestart:a})]})}function kr({row:e,projectName:n,onBack:a,onRestart:i}){const[s,d]=l.useState(null),[v,h]=l.useState("idle");l.useEffect(()=>{if(e.transcriptBytes===null){h("none"),d(null);return}let g=!0;return h("loading"),F.sessionTranscript(e.id).then(b=>{g&&(d(b.text),h("idle"))}).catch(()=>{g&&(d(null),h("error"))}),()=>{g=!1}},[e.id,e.transcriptBytes]);const I=ot(e)==="interrupted",T=[["Project",n],["Sesi",e.sessionId],["Jenis",_t(e.kind)],["Agen",[e.agent,e.model,e.effort].filter(Boolean).join(" · ")],["Mulai",new Date(e.startedAt).toLocaleString("id-ID")],[I?"Terakhir terlihat hidup":"Selesai",e.endedAt?new Date(e.endedAt).toLocaleString("id-ID"):"berjalan"],...I&&e.reconciledAt?[["Terdeteksi mati",new Date(e.reconciledAt).toLocaleString("id-ID")]]:[],["Durasi",Wt(e)],["Direktori",e.cwd]];return e.specId&&T.splice(1,0,["Backlog",`${e.specId}${e.title?` · ${e.title}`:""}`]),e.branch&&T.push(["Branch",e.branch]),t.jsxs($e,{open:!0,title:e.title??e.specId??e.sessionId,icon:"history",onClose:a,width:1e3,children:[t.jsxs("div",{style:{display:"flex",gap:8,alignItems:"center",marginBottom:10},children:[t.jsx(ee,{size:"sm",variant:"ghost",leftIcon:"arrow-left",onClick:a,children:"Kembali"}),t.jsx("div",{style:{flex:1}}),s&&t.jsx(ee,{size:"sm",variant:"secondary",leftIcon:"copy",onClick:()=>{var g;return void((g=navigator.clipboard)==null?void 0:g.writeText(s))},children:"Salin transkrip"}),Zt(e.kind)&&t.jsx(ee,{size:"sm",leftIcon:"play",onClick:()=>i(e),children:"Mulai lagi"})]}),I&&t.jsxs(en,{tone:"warn",title:"Sesi terputus — hasilnya tak diketahui",style:{marginBottom:12},children:["Panenya sudah lenyap saat hanoman menyala lagi (reboot, ",t.jsx("code",{children:"tmux kill-server"}),", atau host mati), jadi sesi ini tak meninggalkan exit code dan transkripnya kemungkinan besar tak sempat diambil — capture berjalan tepat sebelum pane dibunuh, dan di jalur ini sudah tak ada pane untuk dibaca. Periksa worktree & branch sesi ini sebelum menganggapnya selesai, lalu mulai lagi bila pekerjaannya belum tuntas."]}),t.jsx("div",{style:{display:"grid",gridTemplateColumns:"auto 1fr",gap:"4px 12px",marginBottom:12,fontSize:12},children:T.map(([g,b])=>t.jsxs(l.Fragment,{children:[t.jsx("span",{style:{color:"var(--text-subtle)"},children:g}),t.jsx("span",{style:{fontFamily:"var(--font-mono)",color:"var(--text-body)",wordBreak:"break-all"},children:b})]},g))}),v==="loading"&&t.jsx("div",{style:{fontSize:12,color:"var(--text-subtle)"},children:"memuat transkrip…"}),v==="none"&&t.jsx("div",{style:{fontSize:12,color:"var(--text-subtle)"},children:I?"Tanpa transkrip — panenya sudah lenyap sebelum hanoman sempat mengambilnya.":"Tanpa transkrip — sesi ini ditutup sebelum fitur riwayat ada, atau panenya tak menyisakan keluaran."}),v==="error"&&t.jsx("div",{style:{fontSize:12,color:"var(--clay-600)"},children:"Transkrip tak terbaca lagi di server."}),s!==null&&t.jsx("pre",{style:{maxHeight:"52vh",overflow:"auto",margin:0,padding:10,background:"var(--bone-200)",border:"1px solid var(--border-hair)",borderRadius:"var(--radius-sm)",fontFamily:"var(--font-mono)",fontSize:11,whiteSpace:"pre-wrap",wordBreak:"break-word",color:"var(--text-body)"},children:s})]})}function jr({open:e,projectId:n,projectName:a,onClose:i,onCreated:s}){var M;const[d,v]=l.useState("claude"),[h,I]=l.useState("claude-opus-5"),[T,g]=l.useState("xhigh"),[b,N]=l.useState({claude:{model:"claude-opus-5",effort:"xhigh"},codex:{...mt}}),[z,E]=l.useState(!1),[j,f]=l.useState(null);l.useEffect(()=>{e&&(F.getSettings().then(w=>{const D={claude:{model:w.model,effort:w.effort},codex:{...mt,...w.codex??{}}},p=w.agent==="codex"?"codex":"claude",c=ht(D,p);N(D),v(p),I(c.model),g(c.effort)}).catch(()=>{}),F.getCodexVersion().then(w=>f(w.version)).catch(()=>{}))},[e]);const C=w=>{v(w);const D=ht(b,w);I(D.model),g(D.effort)},S=w=>{I(w),d==="codex"&&g(D=>sn(w,D))};async function k(){E(!0);try{const{id:w}=await F.createTerminal(n,{agent:d,model:h,effort:T});s(w),i()}catch{}finally{E(!1)}}return t.jsxs($e,{open:e,onClose:i,icon:"plus",eyebrow:a,title:"Sesi baru",footer:t.jsxs(t.Fragment,{children:[t.jsx(ee,{variant:"ghost",onClick:i,children:"Batal"}),t.jsx(ee,{leftIcon:"play",disabled:z,onClick:()=>void k(),children:"Buka sesi"})]}),children:[t.jsxs("div",{style:{fontSize:12.5,color:"var(--text-muted)",marginBottom:12,lineHeight:1.5},children:["Runtime untuk sesi ini. Default dari setelan global; ubah bila perlu. Sesi lahir dengan pilihan ini untuk seluruh hidupnya — ",t.jsx("code",{children:"/model"})," di terminal tetap bisa mengubahnya."]}),t.jsx(Ye,{label:"Agen",hint:"Mesin yang menjalankan sesi ini. Perilaku sesi sama; hanya CLI-nya berbeda.",children:t.jsx(me,{"aria-label":"Agen",value:d,style:{width:"100%"},options:[{value:"claude",label:"Claude Code"},{value:"codex",label:"Codex CLI"}],onChange:w=>C(w.target.value)})}),t.jsx(Ye,{label:"Model",children:t.jsx(me,{"aria-label":"Model",value:h,style:{width:"100%"},options:tn(d).map(w=>({value:w.id,label:w.label})),onChange:w=>S(w.target.value)})}),t.jsx(Ye,{label:"Effort",children:t.jsx(me,{"aria-label":"Effort",value:T,style:{width:"100%"},options:nn(d,h).map(w=>({value:w,label:w})),onChange:w=>g(w.target.value)})}),d==="codex"&&rn(h,j)&&t.jsxs("div",{"data-testid":"codex-version-note",style:{fontSize:12,lineHeight:1.5,marginBottom:12,padding:"8px 10px",borderRadius:8,background:"var(--warn-bg, #fdf6e3)",color:"var(--text-muted)"},children:["Codex CLI terpasang ",t.jsx("b",{children:j}),", sedangkan ",t.jsx("b",{children:h})," butuh ",t.jsx("b",{children:(M=an(h))==null?void 0:M.minClient}),". Sesi tetap boleh dijalankan, tapi modelnya belum tentu dikenali CLI ini."]})]})}const wr=()=>({rows:1,cols:1,cells:[null]}),jt=e=>({...e,rows:e.rows+1,cells:[...e.cells,...Array(e.cols).fill(null)]});function wt(e){const n=e.cols+1,a=[];for(let i=0;i<e.rows;i++)for(let s=0;s<n;s++)a.push(s<e.cols?e.cells[i*e.cols+s]??null:null);return{rows:e.rows,cols:n,cells:a}}function St(e,n){if(e.rows===1||n<0||n>=e.rows)return e;const a=[...e.cells];return a.splice(n*e.cols,e.cols),{...e,rows:e.rows-1,cells:a}}function Ct(e,n){if(e.cols===1||n<0||n>=e.cols)return e;const a=e.cols-1,i=[];for(let s=0;s<e.rows;s++)for(let d=0;d<e.cols;d++)d!==n&&i.push(e.cells[s*e.cols+d]??null);return{rows:e.rows,cols:a,cells:i}}function nt(e,n,a){if(n<0||n>=e.cells.length)return e;const i=e.cells.map(s=>a!==null&&s===a?null:s);return i[n]=a,{...e,cells:i}}const Sr=(e,n)=>({...e,cells:e.cells.map(a=>a&&n.has(a)?a:null)}),Kt=e=>({id:crypto.randomUUID(),name:e,layout:wr()});function It(){const e=Kt("Utama");return{groups:[e],active:e.id}}const Pe=e=>e.groups.find(n=>n.id===e.active)??e.groups[0];function Cr(e,n){const a=Kt(n);return{groups:[...e.groups,a],active:a.id}}const Ir=(e,n,a)=>({...e,groups:e.groups.map(i=>i.id===n?{...i,name:a}:i)});function Er(e,n){if(e.groups.length===1)return e;const a=e.groups.filter(i=>i.id!==n);return a.length===e.groups.length?e:{groups:a,active:e.active===n?a[0].id:e.active}}const Tr=(e,n)=>e.groups.some(a=>a.id===n)?{...e,active:n}:e;function be(e,n){const a=Pe(e);return{...e,groups:e.groups.map(i=>i.id===a.id?{...i,layout:n(i.layout)}:i)}}function rt(e,n,a){const i=Pe(e),s=a===null?e.groups:e.groups.map(d=>d.id===i.id?d:{...d,layout:nt(d.layout,d.layout.cells.indexOf(a),null)});return{...e,groups:s.map(d=>d.id===i.id?{...d,layout:nt(d.layout,n,a)}:d)}}function Ee(e,n){const a=Pe(e).layout.cells.indexOf(null);return a===-1?e:rt(e,a,n)}const Rr=(e,n)=>({...e,groups:e.groups.map(a=>({...a,layout:nt(a.layout,a.layout.cells.indexOf(n),null)}))}),Et=e=>new Set(e.groups.flatMap(n=>n.layout.cells.filter(a=>a!==null))),Tt=(e,n)=>({...e,groups:e.groups.map(a=>({...a,layout:Sr(a.layout,n)}))}),Ht="hanoman.terminal.workspace",qt="hanoman.terminal.layout",Te=e=>Me.parse({version:1,groups:e.groups});function qe(e,n){const a=e.groups,i=n&&a.some(s=>s.id===n)?n:a[0].id;return{groups:a,active:i}}function zr(e){try{const n=JSON.parse(e);if(!n||typeof n!="object")return null;const a=n,i=Me.parse({version:1,groups:a.groups});return{workspace:i,active:typeof a.active=="string"&&i.groups.some(s=>s.id===a.active)?a.active:i.groups[0].id}}catch{return null}}function Ar(){try{const e=localStorage.getItem(Ht);if(e)return zr(e);const n=localStorage.getItem(qt);if(!n)return null;const a=JSON.parse(n),i={id:crypto.randomUUID(),name:"Utama",layout:a};return{workspace:Me.parse({version:1,groups:[i]}),active:i.id}}catch{return null}}function Je(){try{localStorage.removeItem(Ht),localStorage.removeItem(qt)}catch{}}const Gt=e=>`hanoman.terminal.workspace.v2.${encodeURIComponent(e)}`;function Lr(e){try{const n=localStorage.getItem(Gt(e));if(!n)return null;const a=JSON.parse(n),i=Me.parse(a.workspace);if(!Number.isInteger(a.revision)||(a.revision??-1)<0)return null;const s=typeof a.active=="string"&&i.groups.some(d=>d.id===a.active)?a.active:i.groups[0].id;return{workspace:i,revision:a.revision,active:s}}catch{return null}}function Qe(e,n){try{const a=Me.parse(n.workspace);if(!Number.isInteger(n.revision)||n.revision<0)return;const i=a.groups.some(s=>s.id===n.active)?n.active:a.groups[0].id;localStorage.setItem(Gt(e),JSON.stringify({workspace:a,revision:n.revision,active:i}))}catch{}}function Ze(e){if(!(e instanceof st)||e.status!==409)return null;const n=e.detail;if((n==null?void 0:n.code)!=="revision-conflict")return null;const a=on.safeParse(n.current);return a.success?a.data:null}function Nr(e){const n=_.useRef(null);n.current||(n.current=It());const[a,i]=_.useState(n.current),[s,d]=_.useState("loading"),[v,h]=_.useState(null),[I,T]=_.useState(!1),g=_.useRef(a),b=_.useRef(0),N=_.useRef(!1),z=_.useRef(Promise.resolve()),E=_.useRef(0),j=_.useCallback(p=>{g.current=p,i(p)},[]),f=_.useCallback(p=>{N.current=p,T(p)},[]),C=_.useCallback(p=>{const c=z.current.then(p,p);return z.current=c.then(()=>{},()=>{}),c},[]),S=_.useCallback((p,c="ready",L=null,B=g.current.active)=>{const x=p.workspace?qe(p.workspace,B):It();b.current=p.revision,j(x),d(c),h(L),f(!0),p.workspace&&Qe(e,{workspace:p.workspace,revision:p.revision,active:x.active})},[j,f,e]),k=_.useCallback(p=>{const c=Lr(e);c&&(b.current=c.revision,j(qe(c.workspace,c.active))),f(!1),d("recovering"),h(p instanceof Error?p.message:"Layout server belum tersambung")},[j,f,e]),M=_.useCallback(()=>C(async()=>{try{S(await F.getTerminalWorkspace())}catch(p){k(p)}}),[S,C,k]);_.useEffect(()=>{const p=++E.current;return d("loading"),h(null),f(!1),C(async()=>{try{const c=await F.getTerminalWorkspace();if(p!==E.current)return;if(c.workspace){S(c),Je();return}const L=Ar();if(!L){S(c);return}try{const B=await F.putTerminalWorkspace({baseRevision:c.revision,workspace:L.workspace});if(p!==E.current)return;j(qe(B.workspace,L.active)),b.current=B.revision,Qe(e,{workspace:B.workspace,revision:B.revision,active:L.active}),Je(),d("ready"),h(null),f(!0)}catch(B){const x=Ze(B);x!=null&&x.workspace?(S(x,"conflict","Layout server lebih baru; layout lokal lama tidak diunggah"),Je()):k(B)}}catch(c){p===E.current&&k(c)}}),()=>{E.current+=1}},[S,C,k,j,f,e]),_.useEffect(()=>{const p=()=>{M()},c=()=>{document.visibilityState==="visible"&&M()};return window.addEventListener("focus",p),document.addEventListener("visibilitychange",c),()=>{window.removeEventListener("focus",p),document.removeEventListener("visibilitychange",c)}},[M]);const w=_.useCallback(p=>C(async()=>{if(!N.current)return!1;const c=p(g.current);let L,B;try{L=Te(c),B=Te(g.current)}catch{return d("conflict"),h("Layout tidak valid dan tidak disimpan"),!1}if(At(L,B))return!0;try{return S(await F.putTerminalWorkspace({baseRevision:b.current,workspace:L}),"ready",null,c.active),!0}catch(x){const H=Ze(x);if(!(H!=null&&H.workspace))return k(x),!1;const q=p(qe(H.workspace,g.current.active));try{const A=await F.putTerminalWorkspace({baseRevision:H.revision,workspace:Te(q)});return S(A,"conflict","Layout berubah di perangkat lain; perubahan ini diterapkan ulang",q.active),!0}catch(A){if(!Ze(A)&&!(A instanceof st&&A.status===409))return k(A),!1;try{S(await F.getTerminalWorkspace(),"conflict","Layout berubah lagi di perangkat lain; state terbaru dimuat")}catch(G){k(G)}return!1}}}),[S,C,k]),D=_.useCallback(p=>{const c=Tr(g.current,p);j(c);const L=Te(c);Qe(e,{workspace:L,revision:b.current,active:c.active})},[j,e]);return{workspace:a,status:s,message:v,writable:I,mutate:w,setActive:D,refresh:M}}function Ur({userId:e="test-user",projects:n,backlog:a=[],focusSession:i,onOpenReview:s,onOpenSessionReview:d,titleOf:v,onIntegrate:h,onIntegrateSession:I,specOf:T}){var u;const[g,b]=l.useState([]),[N,z]=l.useState([]),E=Nr(e),{workspace:j,status:f,message:C,writable:S,mutate:k,setActive:M,refresh:w}=E,[D,p]=De("terminal","project",((u=n[0])==null?void 0:u.id)??"",pn),c=Lt(),[L,B]=De("terminal","fontSize",c?Nn:lt,dn),[x,H]=De("terminal","keys",c,Ve),[q,A]=De("terminal","predict",!0,Ve),[G,te]=De("terminal","diag",!1,Ve),ne=r=>B(o=>tt(o+r)),[U,le]=l.useState(!1),[V,J]=l.useState(null),[Y,X]=l.useState(!1),[Q,re]=l.useState(null),[ce,he]=l.useState(!1),[ue,O]=l.useState(!1),K=ln()==="mobile",[R,ae]=l.useState(0),[ie,se]=l.useState(null),we=l.useRef(null),[ge,Fe]=l.useState(!1);l.useEffect(()=>{F.listTerminals().then(r=>{b(r),Fe(!0)}).catch(()=>{})},[]),l.useEffect(()=>cn(r=>{r.t==="sessions"?b(r.sessions):r.t==="cleanups"&&z(r.cleanups)}),[]),l.useEffect(()=>{if(!ge||!S)return;const r=new Set(g.map(m=>m.id)),o=Tt(j,r);At(Te(o),Te(j))||k(m=>Tt(m,r))},[k,g,ge,S,j]),l.useEffect(()=>{if(!i){we.current=null;return}!ge||we.current===i||g.some(r=>r.id===i&&!r.exited)&&(we.current=i,se(i))},[i,g,ge]),l.useEffect(()=>{if(!ie)return;const r=j.groups.find(o=>o.layout.cells.includes(ie));if(r){r.id!==j.active&&M(r.id);return}S&&k(o=>{if(Et(o).has(ie))return o;const m=Ee(o,ie);return m!==o||!K?m:rt(o,R,ie)})},[R,K,k,ie,M,S,j]),l.useEffect(()=>{V&&!g.some(r=>r.id===V)&&J(null)},[V,g]);const Re=N.filter(r=>r.error),Se=r=>g.find(o=>o.id===r)??null,ye=r=>{var o;return((o=n.find(m=>m.id===r))==null?void 0:o.name)??r};function ze(r){b(o=>o.some(m=>m.id===r)?o:[...o,{id:r,projectId:D,cwd:"",exited:!1}]),k(o=>Ee(o,r)),se(r)}async function Ae(){if(!D)return;const{id:r}=await F.createShell(D);b(o=>[...o,{id:r,projectId:D,cwd:"",exited:!1}]),k(o=>Ee(o,r)),se(r)}async function Ue(r){const o=gn(r.source);try{const{id:m}=await F.startSession({spec:r.id,flow:o});b(y=>y.some(Z=>Z.id===m)?y:[...y,{id:m,projectId:r.projectId,specId:r.id,flow:o,cwd:"",exited:!1}]),k(y=>Ee(y,m)),se(m),X(!1),re(null)}catch(m){const y=m instanceof st&&(m.status===400||m.status===422);re(`${r.id} · gagal mulai${y?" · project belum punya repoDir":""}`)}}async function $(r){try{const o=r.specId?await F.startSession({spec:r.specId,flow:r.flow??"feature"}):r.kind==="shell"?await F.createShell(r.projectId):r.kind==="terminal"?await F.createTerminal(r.projectId,{agent:r.agent==="codex"?"codex":"claude",...r.model?{model:r.model}:{},...r.effort?{effort:r.effort}:{}}):await F.createTerminalFlow(r.projectId,r.kind);b(m=>m.some(y=>y.id===o.id)?m:[...m,{id:o.id,projectId:r.projectId,specId:r.specId??void 0,cwd:"",exited:!1}]),k(m=>Ee(m,o.id)),se(o.id),O(!1)}catch{}}const Le=new Set(g.filter(r=>r.specId&&!r.exited).map(r=>r.specId)),xe=a.filter(r=>r.stage!=="done"&&!Le.has(r.id));function pe(r){b(o=>o.filter(m=>m.id!==r)),F.deleteTerminal(r).catch(()=>{})}const ke=l.useCallback((r,o)=>{b(m=>m.map(y=>y.id===r?{...y,exited:!0,exitCode:o}:y))},[]),Ce=(r,o)=>{ae(r),k(m=>rt(m,r,o))},je=r=>{se(r),k(o=>Ee(o,r))},Oe=r=>{k(o=>Rr(o,r))},We=Et(j),Ie=g.filter(r=>!We.has(r.id)),P=Pe(j).layout;l.useEffect(()=>{if(!ie)return;const r=P.cells.indexOf(ie);r<0||(ae(r),se(null))},[P.cells,ie]),l.useEffect(()=>{R>=P.cells.length&&ae(Math.max(0,P.cells.length-1))},[R,P.cells.length]);const Ne=P.rows===1&&P.cols===1&&!P.cells[0]&&g.length===0,_e=t.jsxs("div",{style:{display:"flex",flexDirection:"column",gap:10,marginBottom:10},children:[t.jsxs("div",{className:"hn-dense-row",style:{display:"flex",alignItems:"center",gap:8},children:[t.jsx("span",{style:{flex:1,minWidth:0,fontSize:12,color:"var(--text-muted)"},children:"Ukuran teks terminal"}),t.jsx(Xe,{size:"sm",icon:"minus",label:"Perkecil teks terminal",disabled:L<=Dt,onClick:()=>ne(-1)}),t.jsxs("span",{style:{fontFamily:"var(--font-mono)",fontSize:12,minWidth:44,textAlign:"center"},children:[L,"px"]}),t.jsx(Xe,{size:"sm",icon:"plus",label:"Perbesar teks terminal",disabled:L>=Bt,onClick:()=>ne(1)})]}),t.jsxs("div",{className:"hn-dense-row",style:{display:"flex",alignItems:"center",gap:8},children:[t.jsx("span",{style:{flex:1,minWidth:0,fontSize:12,color:"var(--text-muted)"},children:"Papan tombol layar (Esc · panah · Enter)"}),t.jsx(ee,{size:"sm",variant:"secondary","aria-pressed":x,onClick:()=>H(r=>!r),children:x?"Sembunyikan":"Tampilkan"})]}),t.jsxs("div",{className:"hn-dense-row",style:{display:"flex",alignItems:"center",gap:8},children:[t.jsx("span",{style:{flex:1,minWidth:0,fontSize:12,color:"var(--text-muted)"},children:"Ketik responsif (huruf tampil sebelum echo server)"}),t.jsx(ee,{size:"sm",variant:"secondary","aria-pressed":q,"aria-label":`${q?"Matikan":"Nyalakan"} ketik responsif`,onClick:()=>A(r=>!r),children:q?"Matikan":"Nyalakan"})]}),t.jsxs("div",{className:"hn-dense-row",style:{display:"flex",alignItems:"center",gap:8},children:[t.jsx("span",{style:{flex:1,minWidth:0,fontSize:12,color:"var(--text-muted)"},children:"Rekam jalur ketik (diagnostik — merekam setiap tombol)"}),t.jsx(ee,{size:"sm",variant:"secondary","aria-pressed":G,"aria-label":`${G?"Matikan":"Nyalakan"} rekam jalur ketik`,onClick:()=>te(r=>!r),children:G?"Matikan":"Nyalakan"})]}),K&&t.jsx(me,{size:"sm","aria-label":"Project sesi baru",value:D,onChange:r=>p(r.target.value),options:n.map(r=>({value:r.id,label:r.name}))})]}),Ke=[{key:"backlog",label:"Ambil backlog",icon:"inbox",onSelect:()=>{re(null),X(!0)}},{key:"history",label:"Riwayat sesi",icon:"history",onSelect:()=>O(!0)},{key:"shell",label:"Terminal biasa",icon:"terminal",onSelect:()=>void Ae()},{key:"col+",label:"+ Kolom",icon:"columns-2",disabled:!S,onSelect:()=>void k(r=>be(r,wt))},{key:"row+",label:"+ Baris",icon:"rows-2",disabled:!S,onSelect:()=>void k(r=>be(r,jt))},{key:"col-",label:"Hapus kolom aktif",icon:"columns-2",disabled:!S||P.cols===1,onSelect:()=>void k(r=>be(r,o=>Ct(o,R%o.cols)))},{key:"row-",label:"Hapus baris aktif",icon:"rows-2",disabled:!S||P.rows===1,onSelect:()=>void k(r=>be(r,o=>St(o,Math.floor(R/o.cols))))}],He={display:"flex",flexDirection:"column",gap:U?8:12,...U?{position:"fixed",inset:0,zIndex:100,background:"var(--surface-page)",paddingTop:"max(12px, var(--safe-top))",paddingRight:"max(12px, var(--safe-right))",paddingBottom:"max(12px, var(--safe-bottom))",paddingLeft:"max(12px, var(--safe-left))"}:{flex:"1 1 0",minHeight:640}};return t.jsxs("div",{"data-testid":"terminal-root",style:He,children:[t.jsxs("div",{style:{display:"flex",gap:8,flexDirection:U?"row":"column",alignItems:U?"center":"stretch"},children:[t.jsx(Br,{compact:U,ws:j,writable:S,onSelect:M,onAdd:()=>void k(r=>Cr(r,`Grup ${r.groups.length+1}`)),onRename:(r,o)=>void k(m=>Ir(m,r,o)),onRemove:r=>void k(o=>Er(o,r))}),t.jsxs("div",{style:{display:"flex",alignItems:"center",gap:8,flexWrap:"wrap",...U?{flex:1,minWidth:0}:{}},children:[!K&&t.jsxs(t.Fragment,{children:[t.jsx(ee,{size:"sm",variant:"ghost",disabled:!S,onClick:()=>void k(r=>be(r,wt)),children:"+ Kolom"}),t.jsx(ee,{size:"sm",variant:"ghost",disabled:!S,onClick:()=>void k(r=>be(r,jt)),children:"+ Baris"})]}),t.jsx("div",{style:{flex:1,minWidth:0}}),f!=="ready"&&t.jsx("span",{"data-testid":"terminal-workspace-status",title:C??void 0,style:{fontSize:12,color:f==="conflict"?"var(--status-warn)":"var(--text-muted)"},children:f==="loading"?"Memuat layout server…":f==="recovering"?t.jsxs(t.Fragment,{children:[t.jsx("span",{children:"Layout server belum tersambung"})," ",t.jsx("button",{type:"button",onClick:()=>void w(),children:"Retry"})]}):C??"Layout berubah di perangkat lain"}),N.length>0&&t.jsx("span",{"data-testid":"worktree-cleanups",title:N.map(r=>`${r.sessionId}${r.error?` — ${r.error}`:""}`).join(`
9
+ `),style:{fontSize:12,color:Re.length?"var(--status-err)":"var(--text-muted)"},children:Re.length?`${Re.length} worktree gagal dibersihkan`:`membersihkan ${N.length} worktree…`}),!K&&t.jsxs(t.Fragment,{children:[t.jsx(me,{size:"sm",value:D,onChange:r=>p(r.target.value),options:n.map(r=>({value:r.id,label:r.name}))}),t.jsx(ee,{size:"sm",variant:"secondary",leftIcon:"inbox",onClick:()=>{re(null),X(!0)},children:"Ambil backlog"}),t.jsx(ee,{size:"sm",variant:"secondary",leftIcon:"history",title:"Riwayat sesi yang sudah berlalu — buka kembali atau baca transkripnya",onClick:()=>O(!0),children:"Riwayat"}),t.jsx(ee,{size:"sm",variant:"secondary",leftIcon:"terminal",title:"Buka shell tmux tanpa Claude di project terpilih — jalankan command di project",onClick:()=>void Ae(),children:"Terminal biasa"})]}),t.jsx(ee,{size:"sm",leftIcon:"plus",onClick:()=>he(!0),children:"Sesi baru"}),t.jsx(Nt,{label:K?"Aksi terminal lain":"Tampilan terminal",items:K?Ke:[],children:_e}),t.jsx(Xe,{size:"sm",icon:U?"minimize-2":"maximize-2",label:U?"Keluar layar penuh":"Layar penuh","aria-pressed":U,onClick:()=>le(r=>!r)})]})]}),Ie.length>0&&t.jsxs("div",{style:{display:"flex",gap:6,flexWrap:"wrap",alignItems:"center"},children:[t.jsx("span",{style:{fontSize:11,color:"var(--text-subtle)"},children:"Belum di grid:"}),Ie.map(r=>t.jsxs("span",{style:{display:"inline-flex",alignItems:"center",gap:6,padding:"4px 8px",borderRadius:"var(--radius-sm)",background:"var(--bone-200)",border:"1px solid var(--border-hair)",fontFamily:"var(--font-mono)",fontSize:11},children:[t.jsxs("button",{className:"hn-terminal-unplaced-action",disabled:!S,onClick:()=>je(r.id),title:"Taruh di sel kosong pertama grup ini",style:{all:"unset",cursor:"pointer"},children:[r.specId??ye(r.projectId)," · ",r.id.slice(0,6)]}),t.jsx("button",{type:"button",className:"hn-terminal-action","aria-label":`Tutup sesi ${r.id}`,onClick:()=>void pe(r.id),children:"×"})]},r.id))]}),K&&!Ne&&t.jsx("div",{className:"hn-stack-mobile",style:{display:"flex",alignItems:"center",gap:8},children:t.jsx(un,{"aria-label":"Panel terminal",variant:"pill",value:String(R),onChange:r=>ae(Number(r)),tabs:P.cells.map((r,o)=>({value:String(o),label:`Panel ${o+1}${r?` · ${r.slice(0,6)}`:" · kosong"}`}))})}),Ne?t.jsx(it,{kind:"empty",icon:"terminal",title:"Belum ada sesi terminal",hint:"Pilih project lalu buka sesi — 'Sesi baru' menjalankan claude --dangerously-skip-permissions di direktori project; 'Terminal biasa' membuka shell tmux polos untuk menjalankan command."}):t.jsxs("div",{style:{flex:1,minHeight:0,display:"grid",gap:8,gridTemplateColumns:K?"minmax(0, 1fr)":`18px repeat(${P.cols}, minmax(0, 1fr))`,gridTemplateRows:K?"minmax(0, 1fr)":`16px repeat(${P.rows}, minmax(0, 1fr))`},children:[!K&&t.jsx("div",{}),!K&&Array.from({length:P.cols},(r,o)=>t.jsx(Rt,{label:`Tutup kolom ${o+1}`,disabled:!S||P.cols===1,onClick:()=>void k(m=>be(m,y=>Ct(y,o)))},`col-${o}`)),Array.from({length:P.rows},(r,o)=>t.jsxs(l.Fragment,{children:[!K&&t.jsx(Rt,{label:`Tutup baris ${o+1}`,disabled:!S||P.rows===1,onClick:()=>void k(m=>be(m,y=>St(y,o)))}),Array.from({length:P.cols},(m,y)=>{const Z=o*P.cols+y,de=P.cells[Z]??null,oe=de?Se(de):null;return t.jsx("div",{"data-terminal-cell-index":Z,"aria-hidden":K&&R!==Z?"true":"false",style:{minHeight:0,minWidth:0,display:K&&R!==Z?"none":"flex",flexDirection:"column",border:"1px solid var(--border-hair)",borderRadius:"var(--radius-sm)",overflow:"hidden"},children:oe?t.jsx(Fr,{session:oe,nameOf:ye,onClose:()=>void pe(oe.id),canArrange:S,onDetach:()=>Oe(oe.id),onExit:fe=>ke(oe.id,fe),onReview:s,onSessionReview:d,titleOf:v,onIntegrate:h,onIntegrateSession:I,specOf:T,fontSize:L,showKeys:x,predict:q,diag:G,fullscreen:V===oe.id,onFullscreen:()=>J(oe.id)}):t.jsx(Wr,{disabled:!S,unplaced:Ie,nameOf:ye,onPick:fe=>Ce(Z,fe)})},de??`empty-${Z}`)})]},`row-${o}`))]}),Y&&t.jsx(Dr,{seed:xe,activeIds:Le,error:Q,onPick:r=>void Ue(r),onClose:()=>X(!1)}),ce&&t.jsx(jr,{open:!0,projectId:D,projectName:ye(D),onClose:()=>he(!1),onCreated:ze}),ue&&t.jsx(yr,{projects:n,onClose:()=>O(!1),onRestart:r=>void $(r)}),V&&Se(V)&&t.jsx(Or,{session:Se(V),label:Ut(Se(V),ye,v),fontSize:L,showKeys:x,predict:q,diag:G,onClose:()=>J(null)})]})}function Ut(e,n,a){const i=n(e.projectId),s=e.specId?a==null?void 0:a(e.specId):void 0;return e.specId?`${i} · ${e.specId}${s?` · ${s}`:""}`:e.id.startsWith("xaudit-")?`${i} · audit lintas`:i}function Dr({seed:e,activeIds:n,error:a,onPick:i,onClose:s}){const[d,v]=l.useState(""),[h,I]=l.useState("all"),[T,g]=l.useState("all"),[b,N]=l.useState(e),[z,E]=l.useState("");l.useEffect(()=>{const f=setTimeout(()=>E(d.trim()),250);return()=>clearTimeout(f)},[d]),l.useEffect(()=>{var S,k;let f=!0;const C=(k=(S=F).listSpecs)==null?void 0:k.call(S,{startable:!0,q:z||void 0,stage:h==="all"?void 0:h,priority:T==="all"?void 0:T});return C==null||C.then(M=>{f&&N(M.items)}).catch(()=>{}),()=>{f=!1}},[z,h,T]);const j=b.filter(f=>!n.has(f.id));return t.jsxs($e,{open:!0,title:"Ambil backlog",icon:"inbox",onClose:s,width:760,children:[a&&t.jsx("div",{style:{marginBottom:10,padding:"8px 10px",borderRadius:"var(--radius-sm)",background:"var(--clay-100)",color:"var(--clay-600)",fontSize:12},children:a}),t.jsxs("div",{style:{display:"flex",alignItems:"center",gap:10,flexWrap:"wrap",marginBottom:10},children:[t.jsx(at,{size:"sm",leftIcon:"search",placeholder:"mis. invoice atau SPEC-412","aria-label":"Cari backlog",value:d,onChange:f=>v(f.target.value),style:{flex:"1 1 220px"}}),t.jsx(me,{size:"sm","aria-label":"Filter stage",value:h,onChange:f=>I(f.target.value),options:[{value:"all",label:"Semua stage"}].concat(hn.filter(f=>f.key!=="done").map(f=>({value:f.key,label:f.label})))}),t.jsx(me,{size:"sm","aria-label":"Filter prioritas",value:T,onChange:f=>g(f.target.value),options:[{value:"all",label:"Semua prioritas"},{value:"tinggi",label:"Tinggi"},{value:"sedang",label:"Sedang"},{value:"rendah",label:"Rendah"}]})]}),j.length===0?t.jsx(it,{kind:"empty",icon:"inbox",title:"Tak ada backlog untuk diambil",hint:"Semua item sudah selesai/aktif atau tak cocok filter — buat brief baru di halaman Backlog."}):t.jsx("div",{style:{display:"flex",flexDirection:"column",maxHeight:"62vh",overflowY:"auto"},children:j.map(f=>t.jsx("button",{onClick:()=>i(f),style:{cursor:"pointer",display:"block",width:"100%",flex:"0 0 auto",font:"inherit",color:"inherit",textAlign:"left",background:"transparent",padding:"9px 8px",border:"none",borderBottom:"1px solid var(--border-hair)"},children:t.jsxs("span",{className:"hn-dense-row hn-picker-row",style:{display:"flex",alignItems:"center",gap:10,width:"100%"},children:[t.jsx(ve,{name:f.source==="qa"?"bug":f.source==="audit"?"search":"lightbulb",size:14,color:f.source==="qa"?"var(--clay-500)":f.source==="audit"?"var(--wind-600)":"var(--brass-500)"}),t.jsx("span",{style:{fontFamily:"var(--font-mono)",fontSize:12,color:"var(--text-subtle)",flex:"0 0 78px"},children:f.id}),t.jsx("span",{className:"hn-picker-title",style:{flex:1,minWidth:0,fontSize:13,color:"var(--text-strong)",overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"},children:f.title}),t.jsx(et,{tone:f.priority==="tinggi"?"err":"neutral",size:"sm",children:f.priority}),t.jsx("span",{style:{fontFamily:"var(--font-mono)",fontSize:11,flex:"0 1 auto",minWidth:0,overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap",color:"var(--text-muted)"},children:f.projectId})]})},f.id))})]})}function Br({ws:e,compact:n=!1,writable:a,onSelect:i,onAdd:s,onRename:d,onRemove:v}){const[h,I]=l.useState(null),T=Pe(e),g=e.groups.length===1;return t.jsxs("div",{role:"tablist","aria-label":"Grup terminal",style:{display:"flex",alignItems:"center",gap:4,flexWrap:"wrap",...n?{}:{borderBottom:"1px solid var(--border-hair)",paddingBottom:4}},children:[e.groups.map((b,N)=>{const z=b.id===T.id;return h===b.id?t.jsx($r,{initial:b.name,onCommit:E=>{E.trim()&&d(b.id,E.trim()),I(null)},onCancel:()=>I(null)},b.id):t.jsxs("span",{style:{display:"inline-flex",alignItems:"center",gap:4,padding:"3px 6px",borderRadius:"var(--radius-sm)",fontSize:12,background:z?"var(--bone-200)":"transparent",border:`1px solid ${z?"var(--border-hair)":"transparent"}`},children:[t.jsx("button",{className:"hn-terminal-group-control",role:"tab","aria-selected":z,tabIndex:z?0:-1,onClick:()=>i(b.id),onKeyDown:E=>{var f,C;let j=null;E.key==="ArrowRight"?j=(N+1)%e.groups.length:E.key==="ArrowLeft"?j=(N-1+e.groups.length)%e.groups.length:E.key==="Home"?j=0:E.key==="End"&&(j=e.groups.length-1),j!==null&&(E.preventDefault(),i(e.groups[j].id),(C=(f=E.currentTarget.closest('[role="tablist"]'))==null?void 0:f.querySelectorAll('[role="tab"]')[j])==null||C.focus())},style:{border:0,padding:0,background:"transparent",font:"inherit",cursor:"pointer",color:z?"var(--text-strong)":"var(--text-muted)"},children:b.name}),z&&a&&t.jsxs(t.Fragment,{children:[t.jsx("button",{className:"hn-terminal-group-control","aria-label":`Ganti nama grup ${b.name}`,title:"Ganti nama",onClick:()=>I(b.id),style:{border:0,padding:0,background:"transparent",cursor:"pointer",color:"var(--text-subtle)",fontSize:10},children:"✎"}),t.jsx("button",{className:"hn-terminal-group-control","aria-label":`Hapus grup ${b.name}`,title:g?"Grup terakhir tak bisa dihapus":"Hapus grup (sesi tetap hidup)",disabled:g,onClick:()=>v(b.id),style:{border:0,padding:0,background:"transparent",cursor:g?"not-allowed":"pointer",color:"var(--text-subtle)",opacity:g?.35:1},children:"×"})]})]},b.id)}),t.jsx("button",{className:"hn-terminal-group-control","aria-label":"Grup baru",title:"Grup baru",disabled:!a,onClick:s,style:{border:0,background:"transparent",cursor:"pointer",padding:"3px 8px",color:"var(--text-subtle)",fontSize:12},children:"+"})]})}function Rt({label:e,disabled:n,onClick:a}){return t.jsx("button",{type:"button","aria-label":e,title:n?"Grid tak boleh menyusut ke nol":e,disabled:n,onClick:a,style:{all:"unset",display:"grid",placeItems:"center",fontSize:11,lineHeight:1,color:"var(--text-subtle)",opacity:n?.3:1,cursor:n?"not-allowed":"pointer"},children:"×"})}function $r({initial:e,onCommit:n,onCancel:a}){const[i,s]=l.useState(e);return t.jsx("input",{autoFocus:!0,"aria-label":"Nama grup",value:i,placeholder:"mis. Rilis",onChange:d=>s(d.target.value),onBlur:()=>n(i),onKeyDown:d=>{d.key==="Enter"?n(i):d.key==="Escape"&&a()},style:{width:100,padding:"3px 6px",fontSize:12,fontFamily:"var(--font-ui)",border:"1px solid var(--border-strong)",borderRadius:"var(--radius-sm)",background:"var(--surface-card)",color:"var(--text-strong)"}})}const Mr={done:"var(--brass)",active:"var(--text-strong)",skipped:"var(--text-subtle)",pending:"var(--text-subtle)"};function Pr({phases:e}){return e!=null&&e.length?t.jsx("div",{style:{display:"flex",alignItems:"center",gap:8,padding:"3px 8px",flex:"0 0 auto",borderBottom:"1px solid var(--border-hair)",fontSize:10,fontFamily:"var(--font-mono)"},children:e.map(n=>t.jsx("span",{"data-state":n.state,title:n.state,style:{color:Mr[n.state],fontWeight:n.state==="active"?600:400,textDecoration:n.state==="skipped"?"line-through":"none",opacity:n.state==="pending"?.5:1},children:n.name},n.name))}):null}function Fr({session:e,nameOf:n,onClose:a,canArrange:i,onDetach:s,onExit:d,onReview:v,onSessionReview:h,titleOf:I,onIntegrate:T,onIntegrateSession:g,specOf:b,fontSize:N,showKeys:z,predict:E,diag:j,fullscreen:f,onFullscreen:C}){const[S,k]=l.useState(null),M=l.useRef(null),[w,D]=l.useState(Number.POSITIVE_INFINITY),p=Lt();l.useEffect(()=>{const O=M.current;if(!O||typeof ResizeObserver!="function")return;const W=new ResizeObserver(K=>{var ae;const R=((ae=K[0])==null?void 0:ae.contentRect.width)??O.getBoundingClientRect().width;R>0&&D(R)});return W.observe(O),()=>W.disconnect()},[]);const[c,L]=l.useState(!1),B=l.useCallback((O,W)=>{k(O),L(W)},[]),[x,H]=l.useState(!1),[q,A]=l.useState(!1),[G,te]=l.useState(!1),ne=e.specId?b==null?void 0:b(e.specId):void 0,U=!e.specId&&!!e.branch,le=Ut(e,n,I),V=!e.exited&&!!e.decision,J=!e.exited&&!!e.deciding,Y=V||J,X=e.exited&&!!e.exitCode,Q=!e.exited&&c,re=X?null:e.exited||Q?"PST-005":Y?"PST-004":"PST-003",ce=[...e.specId?[{key:"docs",label:"Lihat dokumen",icon:"file-text",title:"Lihat dokumen (audit/spec/plan)",onSelect:()=>H(!0),render:t.jsx("button",{type:"button",className:"hn-terminal-action",onClick:()=>H(!0),"aria-label":`Lihat dokumen sesi ${e.id}`,title:"Lihat dokumen (audit/spec/plan)",children:t.jsx(ve,{name:"file-text",size:12})},"docs")}]:[],...e.specId&&v?[{key:"review",label:"Review perubahan",icon:"git-compare",title:"Review perubahan (diff worktree)",onSelect:()=>v(e.specId),render:t.jsx("button",{type:"button",className:"hn-terminal-action",onClick:()=>v(e.specId),"aria-label":`Review sesi ${e.id}`,title:"Review perubahan (diff worktree)",children:t.jsx(ve,{name:"git-compare",size:12})},"review")}]:[],...U&&h?[{key:"review-session",label:"Review perubahan",icon:"git-compare",title:"Review perubahan (diff worktree sesi)",onSelect:()=>h(e.id,le),render:t.jsx("button",{type:"button",className:"hn-terminal-action",onClick:()=>h(e.id,le),"aria-label":`Review sesi ${e.id}`,title:"Review perubahan (diff worktree sesi)",children:t.jsx(ve,{name:"git-compare",size:12})},"review-session")}]:[],...ne&&T?[{key:"integrate",label:"Rebase / Merge branch",icon:"git-merge",title:"Rebase / Merge branch spec",onSelect:()=>A(!0),render:t.jsx("button",{type:"button",className:"hn-terminal-action",onClick:()=>A(!0),"aria-label":`Integrasikan sesi ${e.id}`,title:"Rebase / Merge branch spec",children:t.jsx(ve,{name:"git-merge",size:12})},"integrate")}]:[],...U&&g?[{key:"integrate-session",label:"Rebase / Merge branch",icon:"git-merge",title:"Rebase / Merge branch sesi",onSelect:()=>te(!0),render:t.jsx("button",{type:"button",className:"hn-terminal-action",onClick:()=>te(!0),"aria-label":`Integrasikan sesi ${e.id}`,title:"Rebase / Merge branch sesi",children:t.jsx(ve,{name:"git-merge",size:12})},"integrate-session")}]:[],{key:"detach",label:"Lepas dari grid",icon:"unlink",disabled:!i,title:"Lepas dari grid (sesi tetap hidup)",onSelect:s,render:t.jsx("button",{type:"button",className:"hn-terminal-action hn-terminal-action--text",onClick:s,disabled:!i,title:"Lepas dari grid (sesi tetap hidup)",children:"lepas"},"detach")}],he=Tn(w,ce.length,p?44:28),ue=ce.slice(he);return t.jsxs(t.Fragment,{children:[t.jsxs("div",{ref:M,className:"hn-terminal-cell-header",style:{display:"flex",alignItems:"center",gap:8,padding:"4px 8px",flex:"0 0 auto",background:X?"var(--status-err-tint)":e.exited||Q?"var(--status-ok-tint)":Y?"var(--status-warn-tint)":"var(--bone-200)",borderBottom:"1px solid var(--border-hair)",fontFamily:"var(--font-mono)",fontSize:11,color:e.exited?"var(--text-muted)":"var(--text-body)"},children:[re&&t.jsx(fn,{id:re,decorative:!0,style:{width:34,flex:"0 0 auto",borderRadius:"var(--radius-sm)"}}),t.jsxs("span",{style:{flex:1,minWidth:0,overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"},children:[le," · ",e.id.slice(0,6)]}),e.exited&&(X?t.jsx(Be,{status:"failed",size:"sm",children:`Gagal · exit ${e.exitCode}`}):t.jsx(Be,{status:"done",size:"sm",children:"Selesai"})),Q&&t.jsx(Be,{status:"done",size:"sm",children:"Selesai"}),J&&!Q&&t.jsx(Be,{status:"running",size:"sm",children:"Lead memutuskan"}),V&&!J&&!Q&&t.jsx(Be,{status:"awaiting",size:"sm"}),t.jsxs("span",{className:"hn-terminal-actions",children:[ce.slice(0,he).map(O=>O.render),ue.length>0&&t.jsx(Nt,{label:`Aksi lain sesi ${e.id}`,items:ue.map(({render:O,...W})=>W)}),t.jsx("button",{type:"button",className:"hn-terminal-action",onClick:C,title:"Layar penuh — fokus 1 terminal","aria-label":`Layar penuh sesi ${e.id}`,children:t.jsx(ve,{name:"fullscreen",size:12})}),t.jsx("button",{type:"button",className:"hn-terminal-action","aria-label":`Tutup sesi ${e.id}`,onClick:a,children:"×"})]})]}),t.jsxs("div",{style:{display:"flex",flexDirection:"column",flex:1,minHeight:0,opacity:e.exited?.6:1},children:[t.jsx(Pr,{phases:S}),t.jsx("div",{style:{flex:1,minHeight:0},children:f?t.jsx("div",{style:{height:"100%",display:"grid",placeItems:"center",padding:12,color:"var(--text-subtle)",fontSize:12,textAlign:"center"},children:"Terbuka di layar penuh"}):t.jsx(Ot,{sessionId:e.id,onExit:d,onPhases:B,fontSize:N,showKeys:z,predict:E,diag:j},e.id)})]}),x&&e.specId&&t.jsx(mn,{specId:e.specId,onClose:()=>H(!1)}),q&&ne&&T&&t.jsx(gt,{projectId:ne.projectId,ownBranch:`hanoman/${ne.id.toLowerCase().replace(/[^a-z0-9_-]/g,"_")}`,eyebrow:ne.id,onClose:()=>A(!1),onIntegrate:(O,W)=>{A(!1),T(ne,O,W)}}),G&&U&&g&&t.jsx(gt,{projectId:e.projectId,ownBranch:e.branch,eyebrow:e.id.slice(0,16),onClose:()=>te(!1),onIntegrate:(O,W)=>{te(!1),g(e,O,W)}})]})}function Or({session:e,label:n,fontSize:a,showKeys:i,predict:s,diag:d,onClose:v}){return t.jsx($e,{open:!0,icon:"terminal",title:n,onClose:v,closeOnEscape:!1,width:1600,children:t.jsx("div",{style:{height:"min(72vh, calc(100dvh - 180px))",minHeight:0,display:"flex",flexDirection:"column",opacity:e.exited?.6:1},children:t.jsx(Ot,{sessionId:e.id,onExit:()=>{},fontSize:a,showKeys:i,predict:s,diag:d},e.id)})})}function Wr({unplaced:e,nameOf:n,onPick:a,disabled:i}){return t.jsx("div",{style:{flex:1,display:"grid",placeItems:"center",padding:12},children:t.jsx(me,{size:"sm",value:"","aria-label":"Pilih sesi untuk sel",disabled:i||!e.length,onChange:s=>s.target.value&&a(s.target.value),options:[{value:"",label:e.length?"Pilih sesi…":"tidak ada sesi bebas"}].concat(e.map(s=>({value:s.id,label:`${s.specId??n(s.projectId)} · ${s.id.slice(0,6)}`})))})})}export{Pr as PhaseStrip,Ur as TerminalScreen};
@@ -0,0 +1 @@
1
+ import{e as y,j as e,a as d,f as T,B as C,h as H,o as V,r as Y,t as X,q as Z,S as F,d as U,m as ee,R as te,v as ae,w as ie,p as A,x as se,I as le,y as ne,u as re,c as W,H as oe,z as O,A as q,C as ce,D as de}from"./index-DSFIYjSl.js";import{R as l}from"./react-DfGhg7ZW.js";import{L as ue}from"./live-BhsIWS2g.js";import"./markdown-CWEY34jk.js";function pe(s,c){return s==="rejected"?"Ditutup":s!=="accepted"?"Sedang ditinjau":c==="done"?"Selesai":c==="executing"?"Sedang dikerjakan":"Diterima"}const he=5e3,$=20,me=400;function M({total:s,page:c,onPage:j,unit:p="tiket"}){const n=de(s,c,$);return e.jsx(ie,{page:n.page,pageCount:n.pageCount,total:s,from:n.from,to:n.to,onPage:j,unit:p})}function Q(s,c=Date.now()){const j=Math.max(0,c-new Date(s).getTime()),p=Math.floor(j/6e4);if(p<1)return"baru saja";if(p<60)return`${p}m`;const n=Math.floor(p/60);return n<24?`${n}j`:`${Math.floor(n/24)}h`}const K={new:"warn",accepted:"ok",rejected:"neutral"},J={new:"belum ditinjau",accepted:"diterima",rejected:"ditutup"};function ge({t:s,onOpen:c}){return e.jsxs("button",{onClick:()=>c(s.id),className:"hn-dense-row",style:{display:"flex",alignItems:"center",gap:12,width:"100%",textAlign:"left",padding:"12px 14px",border:"1px solid var(--border-hair)",borderRadius:"var(--radius-md)",background:"var(--surface-card)",cursor:"pointer",marginBottom:8},children:[e.jsxs("span",{style:{flex:1,minWidth:0},children:[e.jsxs("span",{style:{display:"flex",alignItems:"center",gap:8},children:[e.jsxs("span",{style:{fontFamily:"var(--font-mono)",fontWeight:600,color:"var(--text-strong)"},children:["#",s.number]}),e.jsx(C,{tone:"neutral",size:"sm",children:s.category}),e.jsx(C,{tone:K[s.status]??"neutral",size:"sm",children:J[s.status]??s.status})]}),e.jsx("span",{style:{display:"block",color:"var(--text-body)",fontSize:"var(--text-sm)",marginTop:2,overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"},children:s.title}),e.jsxs("span",{style:{fontSize:"var(--text-xs)",color:"var(--text-subtle)",marginTop:2,display:"block"},children:[s.projectId," · ",s.reporterEmail," · ",Q(s.createdAt)," lalu",s.attachmentCount>0?` · ${s.attachmentCount} lampiran`:""]})]}),s.specId&&e.jsxs(C,{tone:"ok",icon:"link",children:["→ ",s.specId]}),e.jsx(le,{name:"chevron-right",size:16,color:"var(--text-subtle)"})]})}function xe({id:s,onBack:c,onAccepted:j,onDeleted:p,onToast:n}){var R;const[i,k]=l.useState(null),[h,z]=l.useState("loading"),[m,u]=l.useState(!1),[g,x]=l.useState("sedang"),[P,b]=l.useState(!1),[f,B]=l.useState(!1),{confirm:v,dialog:S}=re(),[r,I]=l.useState({title:"",detail:"",category:"bug",status:"new"}),w=l.useCallback(()=>{y.getTicket(s).then(t=>{k(t),z("ready")}).catch(()=>z("error"))},[s]);if(l.useEffect(()=>{w()},[w]),h==="loading")return e.jsx(T,{kind:"loading"});if(h==="error"||!i)return e.jsx(T,{kind:"error",hint:"Gagal memuat tiket.",action:w,actionLabel:"Coba lagi"});async function L(){u(!0);try{const t=await y.acceptTicket(s,g);j(t.spec,!!t.alreadyPromoted)}catch{n("Gagal menerima tiket","err","x-circle")}finally{u(!1)}}async function E(){if(await v({title:`Tolak & tutup tiket #${i.number}?`,message:`"${i.title}" ditutup tanpa membuat backlog item.`,confirmLabel:"Tolak tiket",icon:"x-circle"})){u(!0);try{await y.rejectTicket(s),k({...i,status:"rejected"}),n("Tiket ditutup","ok","check")}catch{n("Gagal menolak tiket","err","x-circle")}finally{u(!1)}}}async function a(){u(!0);try{const t=await y.unlinkTicket(s);k({...i,specId:t.specId,spec:null,status:t.status}),n("Tautan backlog dilepas","ok","unlink")}catch{n("Gagal melepas tautan","err","x-circle")}finally{u(!1)}}function o(){I({title:i.title,detail:i.detail,category:i.category,status:i.status}),b(!0)}async function D(){u(!0);try{const t=await y.editTicket(s,{title:r.title,detail:r.detail,category:r.category,status:r.status});k(t),b(!1),n("Tiket diperbarui","ok")}catch{n("Gagal menyimpan","err","x-circle")}finally{u(!1)}}async function N(){u(!0);try{await y.deleteTicket(s),n("Tiket dihapus","ok","trash-2"),p()}catch{n("Gagal menghapus","err","x-circle"),u(!1)}}if(P)return e.jsxs("div",{style:{display:"flex",flexDirection:"column",gap:14},children:[e.jsxs("div",{style:{display:"flex",alignItems:"center",gap:10},children:[e.jsx(d,{size:"sm",variant:"ghost",leftIcon:"arrow-left",onClick:()=>b(!1),disabled:m,children:"Batal"}),e.jsx("span",{style:{flex:1}}),e.jsx(d,{size:"sm",variant:"primary",leftIcon:"check",onClick:D,disabled:m,children:"Simpan"})]}),e.jsx(W,{label:"Judul",children:e.jsx(U,{value:r.title,placeholder:"mis. Tombol Simpan tak berfungsi di HP",onChange:t=>I({...r,title:t.target.value})})}),e.jsxs("div",{style:{display:"flex",gap:10,flexWrap:"wrap"},children:[e.jsx(W,{label:"Kategori",children:e.jsx(F,{value:r.category,onChange:t=>I({...r,category:t.target.value}),options:[{value:"bug",label:"bug"},{value:"fitur",label:"fitur"},{value:"pertanyaan",label:"pertanyaan"},{value:"lainnya",label:"lainnya"}]})}),e.jsx(W,{label:"Status",children:e.jsx(F,{value:r.status,onChange:t=>I({...r,status:t.target.value}),options:[{value:"new",label:"belum ditinjau"},{value:"accepted",label:"diterima"},{value:"rejected",label:"ditutup"}]})})]}),e.jsx(W,{label:"Detail keluhan",children:e.jsx(oe,{value:r.detail,rows:6,placeholder:"mis. Buka halaman Pesanan di HP, tekan Simpan — layar diam dan datanya tak tersimpan.",onChange:t=>I({...r,detail:t.target.value})})})]});const _=i.status!=="new";return e.jsxs("div",{style:{display:"flex",flexDirection:"column",gap:14},children:[e.jsxs("div",{style:{display:"flex",alignItems:"center",gap:10,flexWrap:"wrap"},children:[e.jsx(d,{size:"sm",variant:"ghost",leftIcon:"arrow-left",onClick:c,children:"Kembali"}),e.jsx(C,{tone:K[i.status]??"neutral",children:J[i.status]??i.status}),e.jsx("span",{style:{flex:1}}),e.jsx(d,{size:"sm",variant:"ghost",leftIcon:"pencil",onClick:o,disabled:m,children:"Ubah"}),e.jsx(d,{size:"sm",variant:"ghost",leftIcon:"trash-2",onClick:()=>B(!0),disabled:m,children:"Hapus"}),i.publicStatusUrl&&e.jsxs(e.Fragment,{children:[e.jsx(d,{size:"sm",variant:"ghost",leftIcon:"share-2",onClick:()=>window.open(i.publicStatusUrl,"_blank","noreferrer"),children:"Buka status publik"}),e.jsx(d,{size:"sm",variant:"ghost",leftIcon:"link-2",onClick:()=>{var t;(t=navigator.clipboard)==null||t.writeText(i.publicStatusUrl),n("Link publik disalin","ok","copy")},children:"Salin link publik"})]}),i.specId?e.jsxs(e.Fragment,{children:[e.jsxs(C,{tone:"ok",icon:"link",children:["→ ",i.specId]}),e.jsx(C,{tone:"neutral",size:"sm",children:pe(i.status,(R=i.spec)==null?void 0:R.stage)}),e.jsx(d,{size:"sm",variant:"ghost",leftIcon:"external-link",onClick:()=>window.open(O(i.specId),"_blank","noreferrer"),children:"Buka backlog"}),e.jsx(d,{size:"sm",variant:"ghost",leftIcon:"copy",onClick:()=>{var t;(t=navigator.clipboard)==null||t.writeText(O(i.specId)),n("Link backlog disalin","ok","copy")},children:"Salin link"}),e.jsx(d,{size:"sm",variant:"ghost",leftIcon:"unlink",onClick:a,disabled:m,children:"Lepas tautan"})]}):!_&&e.jsxs(e.Fragment,{children:[e.jsx(F,{size:"sm",value:g,onChange:t=>x(t.target.value),options:[{value:"tinggi",label:"Prioritas tinggi"},{value:"sedang",label:"Prioritas sedang"},{value:"rendah",label:"Prioritas rendah"}]}),e.jsx(d,{size:"sm",leftIcon:"arrow-up-right",onClick:L,disabled:m,children:"Terima → backlog"}),e.jsx(d,{size:"sm",variant:"ghost",leftIcon:"ban",onClick:E,disabled:m,children:"Tolak"})]})]}),e.jsxs("div",{children:[e.jsxs("div",{style:{display:"flex",alignItems:"center",gap:8},children:[e.jsxs("span",{style:{fontFamily:"var(--font-mono)",fontWeight:600,color:"var(--text-strong)"},children:["#",i.number]}),e.jsx(C,{tone:"neutral",size:"sm",children:i.category})]}),e.jsx("div",{style:{fontWeight:600,fontSize:"var(--text-lg)",color:"var(--text-strong)",marginTop:4},children:i.title})]}),e.jsxs("div",{style:{display:"flex",gap:18,flexWrap:"wrap",fontSize:"var(--text-sm)",color:"var(--text-muted)"},children:[e.jsxs("span",{children:["pelapor: ",e.jsx("b",{style:{color:"var(--text-body)"},children:i.reporterEmail})]}),e.jsxs("span",{children:["project: ",e.jsx("b",{style:{color:"var(--text-body)"},children:i.projectId})]}),e.jsxs("span",{children:["masuk: ",Q(i.createdAt)," lalu"]})]}),e.jsxs("div",{children:[e.jsx("div",{className:"hn-eyebrow",style:{marginBottom:6},children:"Detail keluhan"}),e.jsx("div",{style:{whiteSpace:"pre-wrap",color:"var(--text-body)",fontSize:"var(--text-sm)",lineHeight:1.55},children:i.detail})]}),i.attachments.length>0&&e.jsxs("div",{children:[e.jsx("div",{className:"hn-eyebrow",style:{marginBottom:6},children:"Lampiran"}),e.jsx("div",{style:{display:"flex",gap:10,flexWrap:"wrap"},children:i.attachments.map(t=>e.jsx("a",{href:q.ticketAttachment(i.id,t.id),target:"_blank",rel:"noreferrer",style:{display:"block",border:"1px solid var(--border-hair)",borderRadius:"var(--radius-sm)",overflow:"hidden"},children:e.jsx("img",{src:q.ticketAttachment(i.id,t.id),alt:t.filename,style:{display:"block",maxWidth:180,maxHeight:140,objectFit:"cover"}})},t.id))})]}),e.jsx(ce,{open:f,title:"Hapus tiket?",eyebrow:`#${i.number}`,message:`Tiket "${i.title}" dan seluruh lampirannya akan dihapus permanen. Tindakan ini tak bisa dibatalkan.`,busy:m,onCancel:()=>B(!1),onConfirm:N}),S]})}function fe({projectId:s,onAccepted:c}){const[j,p]=l.useState([]),[n,i]=l.useState("loading"),[k,h]=l.useState(!1),[z,m]=l.useState(null),[u,g]=l.useState(null),[x,P]=l.useState([]),[b,f]=l.useState(0),[B,v]=l.useState(1),S=l.useCallback(async()=>{try{const a=await y.listGithubIssues(s,{page:B,limit:$});p(a.items),f(a.total),i("ready")}catch{i("error")}},[s,B]);l.useEffect(()=>{S()},[S]);const r=a=>{var D;const o=(D=a.detail)==null?void 0:D.error;return typeof o=="string"?o:a.message};async function I(){h(!0),g(null),m(null);try{const a=await y.pullGithubIssues(s);m(`${a.repo}: ${a.created} baru, ${a.updated} diperbarui`+(a.skippedPullRequests?` · ${a.skippedPullRequests} pull request dilewati`:"")),await S()}catch(a){g(r(a))}finally{h(!1)}}async function w(){h(!0),g(null);try{const a=await y.acceptGithubIssues(x,void 0);P([]),c==null||c(a.created),await S()}catch(a){g(r(a))}finally{h(!1)}}async function L(a){h(!0),g(null);try{await y.rejectGithubIssue(a),await S()}catch(o){g(r(o))}finally{h(!1)}}const E=a=>P(o=>o.includes(a)?o.filter(D=>D!==a):[...o,a]);return e.jsxs("div",{style:{display:"flex",flexDirection:"column",gap:12,minHeight:0,flex:1},children:[e.jsxs("div",{style:{display:"flex",gap:8,alignItems:"center",flexWrap:"wrap"},children:[e.jsx(d,{size:"sm",onClick:I,disabled:k,children:"Tarik issue"}),e.jsxs(d,{size:"sm",variant:"primary",onClick:w,disabled:k||x.length===0,children:["Terima terpilih",x.length?` (${x.length})`:""]}),z&&e.jsx("span",{style:{fontSize:12,color:"var(--text-muted)"},children:z})]}),u&&e.jsx("div",{role:"alert",style:{fontSize:12,color:"var(--danger, #b00)"},children:u}),n==="loading"?e.jsx(T,{kind:"loading"}):n==="error"?e.jsx(T,{kind:"error",hint:"Gagal memuat daftar issue.",action:()=>void S(),actionLabel:"Coba lagi"}):j.length===0?e.jsx(T,{kind:"empty",icon:"inbox",title:"Belum ada issue tertarik",hint:"Tekan “Tarik issue” untuk menariknya dari repo GitHub project ini."}):e.jsxs(e.Fragment,{children:[e.jsx("div",{style:{overflowY:"auto",minHeight:0},children:j.map(a=>e.jsxs("div",{className:"hn-dense-row",style:{display:"flex",gap:8,alignItems:"baseline",padding:"8px 0",borderBottom:"1px solid var(--border-hair)"},children:[a.status==="new"&&e.jsx("input",{type:"checkbox","aria-label":`Pilih issue ${a.number}`,checked:x.includes(a.id),onChange:()=>E(a.id)}),e.jsxs("span",{style:{fontFamily:"var(--font-mono)",fontSize:12,color:"var(--text-muted)"},children:["#",a.number]}),e.jsx("a",{href:a.url,target:"_blank",rel:"noreferrer",style:{flex:1,minWidth:0},children:a.title}),e.jsxs("span",{style:{fontSize:12,color:"var(--text-muted)"},children:["@",a.authorLogin]}),a.labels.map(o=>e.jsx(C,{children:o},o)),a.status==="rejected"&&e.jsx(C,{tone:"neutral",children:"ditutup"}),a.specId&&e.jsx("span",{style:{fontFamily:"var(--font-mono)",fontSize:12},children:a.specId}),a.status==="new"&&e.jsx(d,{size:"sm",variant:"ghost",onClick:()=>L(a.id),disabled:k,children:"Tolak"})]},a.id))}),e.jsx(M,{total:b,page:B,onPage:v,unit:"issue"})]})]})}function ve({projects:s,onAccepted:c,onToast:j}){const[p,n]=l.useState([]),[i,k]=l.useState(0),[h,z]=H("triage","page",1,se),[m,u]=l.useState(0),[g,x]=l.useState("loading"),[P,b]=H("triage","openId",null,ne),[f,B]=H("triage","project","",A),[v,S]=H("triage","status","",A),[r,I]=H("triage","q","",A),[w,L]=H("triage","tab","tiket",V("tiket","issue")),E=[f!=="",v!=="",r.trim()!==""].filter(Boolean).length,a=Y("triage","scroll",p.length>0),o=l.useCallback((t=!1)=>{t||x("loading"),y.listTickets({project:f||void 0,status:v||void 0,q:r||void 0,page:String(h),limit:String($)}).then(G=>{n(G.items),k(G.total),u(G.unreviewed),x("ready")}).catch(()=>{t||x("error")})},[f,v,r,h]);l.useEffect(()=>{o()},[o]),X(JSON.stringify([f,v,r]),()=>z(1));const[D,N]=l.useState(r);l.useEffect(()=>{const t=setTimeout(()=>N(r),me);return()=>clearTimeout(t)},[r]),Z({topic:"tickets",params:{project:f||void 0,status:v||void 0,q:D||void 0,page:h,limit:$},apply:t=>{n(t.data.items),k(t.data.total),u(t.data.unreviewed),x("ready")},refetch:()=>o(!0),pollMs:he});const _=e.jsx("div",{style:{display:"flex",flexDirection:"column",gap:12,minHeight:0,flex:1},children:f?e.jsx(fe,{projectId:f,onAccepted:t=>t.forEach(G=>c(G,!1))}):e.jsx(T,{kind:"empty",icon:"inbox",title:"Pilih satu project",hint:"Issue GitHub milik satu repo, jadi pilih project-nya lebih dulu di penyaring di atas."})}),R=e.jsx("div",{style:{display:"flex",flexDirection:"column",flex:1,minHeight:0},children:g==="loading"?e.jsx(T,{kind:"loading"}):g==="error"?e.jsx(T,{kind:"error",hint:"Gagal memuat tiket.",action:()=>o(),actionLabel:"Coba lagi"}):p.length===0?e.jsx(T,{kind:"empty",icon:"inbox",title:"Belum ada keluhan",hint:"Aktifkan Help Center di detail project, lalu sebar link publiknya agar keluhan mulai masuk."}):e.jsxs(e.Fragment,{children:[e.jsx("div",{ref:a,"data-testid":"triage-scroll",style:{overflowY:"auto",minHeight:0,flex:"1 1 auto"},children:p.map(t=>e.jsx(ge,{t,onOpen:b},t.id))}),e.jsx(M,{total:i,page:h,onPage:z})]})});return e.jsxs("div",{style:{display:"flex",flexDirection:"column",gap:14,minHeight:0,flex:1},children:[e.jsxs("div",{className:"hn-wrap-mobile",style:{display:"flex",gap:8,alignItems:"center"},children:[e.jsx(d,{size:"sm",variant:w==="tiket"?"primary":"ghost",onClick:()=>L("tiket"),children:"Tiket Help Center"}),e.jsx(d,{size:"sm",variant:w==="issue"?"primary":"ghost",onClick:()=>L("issue"),children:"Issue GitHub"})]}),e.jsxs("div",{style:{display:"flex",gap:10,flexWrap:"wrap",alignItems:"center"},children:[e.jsx(F,{size:"sm",value:f,"aria-label":"Project triase",onChange:t=>B(t.target.value),options:[{value:"",label:"Semua project"},...s.map(t=>({value:t.id,label:t.name}))]}),w==="tiket"&&e.jsxs(e.Fragment,{children:[e.jsx(F,{size:"sm",value:v,"aria-label":"Status tiket",onChange:t=>S(t.target.value),options:[{value:"",label:"Semua status"},{value:"new",label:"belum ditinjau"},{value:"accepted",label:"diterima"},{value:"rejected",label:"ditutup"}]}),e.jsx(U,{size:"sm",value:r,"aria-label":"Cari tiket",onChange:t=>I(t.target.value),placeholder:"mis. gagal login atau budi@contoh.id",style:{flex:1,minWidth:160}}),m>0&&e.jsxs(C,{tone:"warn",children:[m," belum ditinjau"]}),e.jsx(ee,{onDone:()=>o(!0),onToast:j}),e.jsx(te,{screen:"triage",active:E}),e.jsx(ue,{})]})]}),w==="issue"?_:e.jsx(ae,{ariaLabel:"Panel triase",active:P?"detail":"list",onActiveChange:t=>{t==="list"&&b(null)},splitAt:"tablet",masterWidth:360,panels:[{id:"list",label:"Daftar",content:R,className:"hn-panel-flex"},...P?[{id:"detail",label:"Detail",className:"hn-panel-flex",content:e.jsx(xe,{id:P,onBack:()=>{b(null),o(!0)},onAccepted:c,onDeleted:()=>{b(null),o(!0)},onToast:j})}]:[]]})]})}export{fe as GithubIssuesPanel,ve as TriageScreen};
@@ -0,0 +1,2 @@
1
+ import{e as v,u as te,j as e,M as oe,f as U,I as W,a as f,h as de,o as fe,ak as be,ad as ke,c as O,d as T,a3 as ye,a7 as se,y as ve}from"./index-DSFIYjSl.js";import{R as p}from"./react-DfGhg7ZW.js";import"./markdown-CWEY34jk.js";const je={pass:"check",fail:"x",warn:"alert-triangle",na:"minus",unknown:"circle"},we={pass:"var(--leaf-600)",fail:"var(--clay-600)",warn:"var(--amber-600)",na:"var(--text-subtle)",unknown:"var(--text-subtle)"},Se={AUTO:"var(--brass-700)",AUDIT:"var(--amber-600)",INFO:"var(--text-subtle)"},Ce={critical:"var(--clay-600)",high:"var(--amber-600)",medium:"var(--text-subtle)",low:"var(--text-subtle)"};function K({text:a,color:s}){return e.jsx("span",{style:{fontSize:10,textTransform:"uppercase",letterSpacing:"0.04em",color:s,border:`1px solid ${s}`,borderRadius:3,padding:"0 4px",whiteSpace:"nowrap"},children:a})}function ce({score:a}){const s=a>=90?"var(--leaf-600)":a>=50?"var(--amber-600)":"var(--clay-600)";return e.jsxs("div",{style:{display:"flex",alignItems:"center",gap:6,minWidth:90},children:[e.jsx("div",{style:{flex:1,height:6,background:"var(--bone-200)",borderRadius:3,overflow:"hidden"},children:e.jsx("div",{style:{width:`${a}%`,height:"100%",background:s}})}),e.jsxs("span",{style:{fontSize:11,fontFamily:"var(--font-mono)",color:"var(--text-subtle)",minWidth:28,textAlign:"right"},children:[a,"%"]})]})}function Pe({item:a,busy:s,selected:l,onToggle:o,onNa:u,onAttest:c}){const n=a.mode==="AUTO"&&!a.na;return e.jsxs("div",{"data-testid":`item-${a.id}`,style:{display:"flex",alignItems:"center",gap:8,padding:"5px 0",borderBottom:"1px solid var(--border-hair)",fontSize:13,opacity:a.na?.55:1},children:[n?e.jsx("input",{type:"checkbox","aria-label":`pilih ${a.id}`,checked:l,onChange:()=>o(a)}):e.jsx("span",{style:{display:"inline-block",width:13}}),e.jsx(W,{name:je[a.status],size:14,color:we[a.status]}),e.jsx("span",{style:{flex:1,minWidth:0},children:a.title}),a.drifted&&e.jsx(K,{text:"drift",color:"var(--clay-600)"}),e.jsx(K,{text:a.mode,color:Se[a.mode]}),e.jsx(K,{text:a.severity,color:Ce[a.severity]}),a.mode==="INFO"&&!a.attested&&e.jsx(f,{size:"sm",variant:"ghost",leftIcon:"check-circle",loading:s,onClick:()=>c(a),children:"Attest"}),e.jsx(f,{size:"sm",variant:"ghost",leftIcon:a.na?"rotate-ccw":"minus-circle",loading:s,onClick:()=>u(a,!a.na),children:a.na?"Batal N/A":"N/A"})]})}const ee={section:"",mode:"",status:"",severity:""};function J({value:a,onChange:s,options:l,label:o}){return e.jsxs("select",{"aria-label":o,value:a,onChange:u=>s(u.target.value),style:{fontSize:12,padding:"3px 6px",border:"1px solid var(--border-hair)",borderRadius:"var(--radius-sm)",background:"var(--bone-50)",color:"var(--text)"},children:[e.jsxs("option",{value:"",children:[o,": semua"]}),l.map(([u,c])=>e.jsx("option",{value:u,children:c},u))]})}function ze(a){let s=0,l=0,o=0,u=0;for(const n of a)n.status==="fail"?s++:n.status==="warn"?l++:n.status==="unknown"&&o++,n.drifted&&u++;const c=[s&&`${s} fail`,l&&`${l} warn`,o&&`${o} unknown`].filter(Boolean);return{text:c.length?c.join(" "):"semua pass",drift:u}}function $e({section:a,items:s,expanded:l,onToggle:o,busy:u,selected:c,onToggleItem:n,onNa:b,onAttest:g,onSectionNa:k}){const S=ze(a.items),h=!!a.suggestion&&!a.suggestion.applicable;return e.jsxs("div",{style:{marginBottom:8,border:"1px solid var(--border-hair)",borderRadius:"var(--radius-sm)",overflow:"hidden"},children:[e.jsxs("button",{"data-testid":`section-${a.id}`,"aria-expanded":l,onClick:()=>o(a.id),style:{display:"flex",alignItems:"center",gap:8,width:"100%",padding:"8px 10px",textAlign:"left",background:l?"var(--bone-100)":"transparent",border:"none",cursor:"pointer"},children:[e.jsx(W,{name:l?"chevron-down":"chevron-right",size:15,color:"var(--text-subtle)"}),e.jsx("span",{style:{fontSize:14},children:a.icon}),e.jsx("span",{style:{fontSize:13,fontWeight:600,flex:1,minWidth:0},children:a.title}),e.jsx("span",{style:{fontSize:11,color:"var(--text-subtle)",whiteSpace:"nowrap"},children:S.text}),S.drift>0&&e.jsx(K,{text:"drift",color:"var(--clay-600)"}),h&&e.jsx(K,{text:"saran N/A",color:"var(--brass-700)"}),e.jsx(ce,{score:a.score})]}),l&&e.jsxs("div",{style:{padding:"2px 10px 8px"},children:[h&&e.jsxs("div",{"data-testid":`suggestion-${a.id}`,style:{display:"flex",alignItems:"center",gap:8,margin:"6px 0",padding:"6px 10px",fontSize:12,color:"var(--text-subtle)",background:"var(--bone-50)",border:"1px dashed var(--border-hair)",borderRadius:"var(--radius-sm)"},children:[e.jsx(W,{name:"info",size:13,color:"var(--brass-700)"}),e.jsxs("span",{style:{flex:1},children:["Stack tak terdeteksi (",a.suggestion.detail,") — kemungkinan N/A. Cek Docker manual bila ragu."]}),e.jsx(f,{size:"sm",variant:"ghost",leftIcon:"minus-circle",loading:u===`section:${a.id}`,onClick:()=>k(a),children:"Tandai seksi N/A"})]}),s.map(y=>e.jsx(Pe,{item:y,busy:u===y.id,selected:c.has(y.id),onToggle:n,onNa:b,onAttest:g},y.id))]})]})}function Ae({vpsId:a,vpsName:s,lastAuditAt:l,health:o,provisioning:u,onClose:c,onToast:n}){const[b,g]=p.useState(null),[k,S]=p.useState("loading"),[h,y]=p.useState(ee),[P,w]=p.useState(""),[B,E]=p.useState(new Set),[$,C]=p.useState(null),[R,V]=p.useState(new Set),[F,D]=p.useState(null),[A,L]=p.useState(""),I=p.useCallback(()=>{S("loading"),v.vpsChecklist(a).then(r=>{g(r),S("ready")}).catch(()=>S("error"))},[a]);p.useEffect(()=>{I(),V(new Set),D(null),E(new Set),w(""),y(ee)},[I]);const t=r=>V(j=>{const d=new Set(j);return d.has(r.id)?d.delete(r.id):d.add(r.id),d}),x=()=>{V(new Set),D(null)},m=r=>E(j=>{const d=new Set(j);return d.has(r)?d.delete(r):d.add(r),d}),{confirm:H,dialog:X}=te();async function M(){L("preview");try{D((await v.remediatePreview(a,[...R])).steps)}catch{n("Preview remediasi gagal","err","x-circle")}finally{L("")}}async function Y(){if(await H({title:`Terapkan ${R.size} item AUTO ke VPS ini?`,message:"Remediasi dijalankan langsung di server yang terdaftar.",impact:["Langkahnya idempoten dan anti-lockout.","Checklist diaudit ulang setelah selesai."],confirmLabel:"Terapkan",icon:"shield"})){L("apply");try{await v.remediate(a,[...R]),x(),I(),n("Remediasi diterapkan · audit ulang","ok","shield")}catch{n("Remediasi gagal","err","x-circle")}finally{L("")}}}async function _(r,j,d){C(r.id);try{await j(),I(),n(d,"ok","shield")}catch{n(`Gagal memperbarui ${r.id}`,"err","x-circle")}finally{C(null)}}const i=(r,j)=>_(r,()=>v.markNa(a,r.id,j,j?"ditandai dari checklist":void 0),j?`${r.id} ditandai N/A`:`${r.id} kembali applicable`),z=r=>_(r,()=>v.attestItem(a,r.id),`${r.id} di-attest`);async function N(r){const j=r.items.map(d=>d.id);if(await H({title:`Tandai ${j.length} item seksi "${r.title}" sebagai N/A?`,message:"Stack-nya tak terdeteksi — cek Docker manual bila ragu.",confirmLabel:"Tandai N/A",icon:"shield"})){C(`section:${r.id}`);try{await v.markNaBulk(a,j,!0,"app-layer: stack tak terdeteksi"),I(),n(`Seksi ${r.title} ditandai N/A`,"ok","shield")}catch{n("Gagal tandai seksi N/A","err","x-circle")}finally{C(null)}}}const G=P.trim().toLowerCase(),q=!!(h.section||h.mode||h.status||h.severity)||G!=="",me=r=>(!h.section||r.section===h.section)&&(!h.mode||r.mode===h.mode)&&(!h.status||r.status===h.status)&&(!h.severity||r.severity===h.severity)&&(!G||r.title.toLowerCase().includes(G)||r.id.toLowerCase().includes(G)||(r.code??"").toLowerCase().includes(G)),Q=r=>j=>y(d=>({...d,[r]:j}));function ge(){if(k==="loading")return e.jsx(U,{kind:"loading",compact:!0,title:"Memuat checklist…"});if(k==="error"||!b)return e.jsx(U,{kind:"error",compact:!0,title:"Gagal memuat checklist",action:I});const r=b.sections.reduce((d,Z)=>d+Z.items.filter(xe=>xe.drifted).length,0),j=b.sections.map(d=>({section:d,matched:d.items.filter(me)})).filter(d=>!q||d.matched.length>0);return e.jsxs("div",{children:[e.jsxs("div",{style:{position:"sticky",top:0,zIndex:1,background:"var(--surface-card)",paddingBottom:10},children:[e.jsxs("div",{style:{display:"flex",alignItems:"center",gap:10,marginBottom:10},children:[e.jsxs("div",{"data-testid":"score-total",style:{fontSize:22,fontWeight:700,fontFamily:"var(--font-mono)"},children:[b.scoreTotal,"%"]}),e.jsx("div",{style:{flex:1},children:e.jsx(ce,{score:b.scoreTotal})}),e.jsx("span",{style:{fontSize:11,color:"var(--text-subtle)"},children:"skor kepatuhan"})]}),r>0&&e.jsxs("div",{"data-testid":"drift-summary",style:{display:"flex",alignItems:"center",gap:6,marginBottom:10,padding:"6px 10px",fontSize:12,color:"var(--clay-700)",background:"var(--clay-50, var(--bone-100))",border:"1px solid var(--clay-600)",borderRadius:"var(--radius-sm)"},children:[e.jsx(W,{name:"alert-triangle",size:14,color:"var(--clay-600)"}),r," item drift (regresi) sejak audit sebelumnya"]}),e.jsxs("div",{style:{display:"flex",flexWrap:"wrap",gap:6,alignItems:"center"},children:[e.jsxs("div",{style:{display:"flex",alignItems:"center",gap:4,flex:"1 1 180px",border:"1px solid var(--border-hair)",borderRadius:"var(--radius-sm)",padding:"2px 8px",background:"var(--bone-50)"},children:[e.jsx(W,{name:"search",size:13,color:"var(--text-subtle)"}),e.jsx("input",{"aria-label":"cari item",value:P,onChange:d=>w(d.target.value),placeholder:"mis. ssh atau 5.2.1",style:{flex:1,border:"none",background:"transparent",fontSize:12,color:"var(--text)",outline:"none"}})]}),e.jsx(J,{label:"seksi",value:h.section,onChange:Q("section"),options:b.sections.map(d=>[d.id,d.title])}),e.jsx(J,{label:"mode",value:h.mode,onChange:Q("mode"),options:[["AUTO","AUTO"],["AUDIT","AUDIT"],["INFO","INFO"]]}),e.jsx(J,{label:"status",value:h.status,onChange:Q("status"),options:[["pass","pass"],["fail","fail"],["warn","warn"],["na","na"],["unknown","unknown"]]}),e.jsx(J,{label:"severity",value:h.severity,onChange:Q("severity"),options:[["critical","critical"],["high","high"],["medium","medium"],["low","low"]]}),q&&e.jsx(f,{size:"sm",variant:"ghost",onClick:()=>{y(ee),w("")},children:"Reset"})]}),R.size>0&&e.jsxs("div",{style:{display:"flex",alignItems:"center",gap:8,marginTop:10,padding:"8px 10px",background:"var(--bone-100)",border:"1px solid var(--brass-300)",borderRadius:"var(--radius-sm)"},children:[e.jsxs("span",{style:{fontSize:12,flex:1},children:[R.size," item AUTO dipilih"]}),e.jsx(f,{size:"sm",variant:"secondary",leftIcon:"eye",loading:A==="preview",onClick:M,children:"Preview"}),e.jsx(f,{size:"sm",leftIcon:"shield",loading:A==="apply",onClick:Y,children:"Apply"}),e.jsx(f,{size:"sm",variant:"ghost",onClick:x,children:"Batal"})]}),F&&e.jsxs("div",{"data-testid":"remediate-preview",style:{marginTop:10,padding:"8px 10px",fontSize:12,fontFamily:"var(--font-mono)",background:"var(--bone-50)",border:"1px solid var(--border-hair)",borderRadius:"var(--radius-sm)"},children:[e.jsx("div",{style:{fontWeight:600,marginBottom:4},children:"Pratinjau (dry-run) — belum diterapkan:"}),F.map(d=>e.jsxs("div",{style:{color:"var(--text-subtle)"},children:[d.item," · ",d.status," ",d.detail]},d.item))]})]}),j.length===0?e.jsx(U,{kind:"empty",compact:!0,title:"Tak ada item cocok",hint:"Ubah kata kunci atau reset filter."}):j.map(({section:d,matched:Z})=>e.jsx($e,{section:d,items:q?Z:d.items,expanded:q?!0:B.has(d.id),onToggle:m,busy:$,selected:R,onToggleItem:t,onNa:i,onAttest:z,onSectionNa:N},d.id))]})}return e.jsxs(oe,{open:!0,width:960,icon:"clipboard-list",eyebrow:s??"VPS",title:"Checklist kepatuhan",onClose:c,children:[e.jsxs("div",{"data-testid":"vps-detail",style:{fontSize:12,color:"var(--text-subtle)",marginBottom:12,paddingBottom:10,borderBottom:"1px solid var(--border-hair)"},children:[l?`Audit terakhir ${new Date(l).toLocaleString()}`:"Belum pernah diaudit",o&&` · disk ${o.disk} · mem ${o.mem} · load ${o.load}`]}),u&&e.jsx("div",{"data-testid":"vps-provisioning",style:{marginBottom:12,paddingBottom:10,borderBottom:"1px solid var(--border-hair)"},children:u}),ge(),X]})}const ne={ok:"terpasang",partial:"belum siap",absent:"belum ada"},ue={ok:"var(--leaf-600)",partial:"var(--amber-600)",absent:"var(--text-subtle)"};function pe(a,s){if(s.status==="partial"&&s.detail.startsWith("not-logged-in"))return`${a} · belum login`;if(s.status==="partial")return`${a} · ${s.detail||ne.partial}`;const l=s.status==="ok"&&s.detail?` ${s.detail}`:"";return`${a} · ${ne[s.status]??s.status}${l}`}const Ie={ok:"terpasang",partial:"belum siap",absent:"belum ada"};function he({status:a,children:s,title:l}){const o=ue[a]??"var(--text-subtle)";return e.jsxs("span",{title:l,style:{display:"inline-flex",alignItems:"center",gap:5,fontSize:11,lineHeight:"18px",color:"var(--text-primary)",background:"var(--surface-sunken)",border:"1px solid var(--border-hair)",borderRadius:999,padding:"0 8px",whiteSpace:"nowrap"},children:[e.jsx("span",{"aria-hidden":!0,style:{width:6,height:6,borderRadius:"50%",background:o,flex:"0 0 auto"}}),s]})}function Be({components:a,checkedAt:s}){return!a||!s?e.jsx("span",{style:{fontSize:11,color:"var(--text-subtle)"},children:"Komponen belum diperiksa"}):e.jsxs("div",{style:{display:"flex",flexWrap:"wrap",gap:6,alignItems:"center"},children:[Object.entries(a).map(([l,o])=>e.jsx(he,{status:o.status,children:pe(l,o)},l)),e.jsxs("span",{style:{fontSize:11,color:"var(--text-subtle)"},children:["diperiksa ",new Date(s).toLocaleString("id-ID")]})]})}const Re=a=>new Date(a).toLocaleString("id-ID",{day:"numeric",month:"short",hour:"2-digit",minute:"2-digit"});function Le({components:a,checkedAt:s}){if(!a||!s)return e.jsx("span",{style:{fontSize:11,color:"var(--text-subtle)"},children:"Komponen belum diperiksa — buka detail untuk memeriksa"});const l=Object.entries(a),o=l.filter(([,c])=>c.status!=="ok"),u=l.length-o.length;return e.jsxs("div",{style:{display:"flex",flexWrap:"wrap",gap:8,alignItems:"center",minWidth:0},children:[e.jsx("span",{"aria-hidden":!0,style:{display:"flex",gap:2,alignItems:"center"},children:l.map(([c,n])=>e.jsx("span",{style:{width:12,height:4,borderRadius:2,background:n.status==="absent"?"var(--border-strong)":ue[n.status]}},c))}),e.jsxs("span",{style:{fontSize:11,color:"var(--text-subtle)",whiteSpace:"nowrap"},children:[e.jsxs("strong",{style:{color:"var(--text-primary)",fontWeight:600},children:[u,"/",l.length]})," terpasang"]}),o.map(([c,n])=>e.jsxs(he,{status:n.status,title:pe(c,n),children:[c," · ",n.status==="partial"&&n.detail.startsWith("not-logged-in")?"belum login":Ie[n.status]??n.status]},c)),e.jsxs("span",{style:{fontSize:11,color:"var(--text-subtle)",whiteSpace:"nowrap"},children:["diperiksa ",Re(s)]})]})}function Ne(a,s,l){const o=new Map(s.map(n=>[n.id,n])),u=new Set,c=n=>{var b;if(!u.has(n)){u.add(n);for(const g of((b=o.get(n))==null?void 0:b.requires[l])??[])c(g)}};for(const n of a)c(n);return u}function De({vps:a,onToast:s,onGotoTerminal:l}){const[o,u]=p.useState([]),[c,n]=de("vps",`provisionProfile@${a.id}`,"lab",fe("lab","production")),[b,g]=p.useState(new Set),[k,S]=p.useState(""),[h,y]=p.useState(null),[P,w]=p.useState(null),[B,E]=p.useState(null),[$,C]=p.useState(null),{confirm:R,dialog:V}=te();p.useEffect(()=>{v.listVpsComponents().then(i=>u(i.components)).catch(()=>u([]))},[]);const F=o.filter(i=>i.profiles.includes(c)),D=Ne(b,o,c),A=[...D],L=A.some(i=>{var z;return(z=o.find(N=>N.id===i))==null?void 0:z.needsDomain}),I=A.length>0&&(!L||k.trim().length>0);function t(i){g(z=>{const N=new Set(z);return N.has(i)?N.delete(i):N.add(i),N})}async function x(){C("probe");try{w(await v.probeVps(a.id)),s("Komponen diperiksa","ok","server")}catch{s("Probe gagal","err","x-circle")}finally{C(null)}}async function m(){C("preview");try{y((await v.provisionPreview(a.id,{items:A,profile:c,domain:k||void 0})).steps)}catch{s("Pratinjau gagal","err","x-circle")}finally{C(null)}}async function H(){if(await R({title:`Pasang ${A.length} komponen di "${a.name}"?`,message:`Profil ${c}. Langkah dijalankan lewat SSH dan bisa memakan beberapa menit.`,impact:A.map(i=>{var z;return((z=o.find(N=>N.id===i))==null?void 0:z.label)??i}),confirmLabel:"Pasang",icon:"server"})){C("apply");try{const i=await v.provisionVps(a.id,{items:A,profile:c,domain:k||void 0,confirm:!0});y(i.steps),w({components:i.components,checkedAt:i.checkedAt}),E(i.setup),s("Provisioning selesai","ok","server")}catch{s("Provisioning gagal","err","x-circle")}finally{C(null)}}}const X=async()=>{try{const{id:i}=await v.vpsConsole(a.id);l(i)}catch{s("Gagal membuka console","err","x-circle")}},M=P?Object.fromEntries(P.components.map(i=>[i.id,{status:i.status,detail:i.detail}])):a.components??null,Y=(P==null?void 0:P.checkedAt)??a.componentsCheckedAt??null,_=M?Object.entries(M).filter(([,i])=>i.status==="partial"&&i.detail.startsWith("not-logged-in")):[];return e.jsxs("div",{style:{display:"grid",gap:12},children:[e.jsxs("div",{style:{display:"flex",gap:8,alignItems:"center",flexWrap:"wrap"},children:[e.jsx(Be,{components:M,checkedAt:Y}),e.jsx(f,{size:"sm",variant:"ghost",onClick:x,disabled:$!==null,children:"Periksa"})]}),e.jsx("div",{style:{display:"flex",gap:16},children:["lab","production"].map(i=>e.jsx(be,{"aria-label":i,label:i,checked:c===i,onChange:()=>n(i)},i))}),e.jsx("div",{style:{display:"grid",gap:6},children:F.map(i=>{const z=D.has(i.id)&&!b.has(i.id);return e.jsxs("div",{style:{display:"flex",gap:6,alignItems:"center"},children:[e.jsx(ke,{"aria-label":i.label,label:i.label,checked:D.has(i.id),disabled:z,onChange:()=>t(i.id)}),z&&e.jsx("span",{style:{fontSize:10,color:"var(--text-subtle)"},children:"prasyarat"})]},i.id)})}),L&&e.jsx(O,{label:"Domain",hint:"A record harus sudah menunjuk ke IP VPS ini",children:e.jsx(T,{"aria-label":"Domain",value:k,onChange:i=>S(i.currentTarget.value),placeholder:"hanoman.contoh.id"})}),e.jsxs("div",{style:{display:"flex",gap:8},children:[e.jsx(f,{variant:"ghost",onClick:m,disabled:!I||$!==null,children:"Pratinjau"}),e.jsx(f,{onClick:H,disabled:!I||$!==null,children:"Pasang"})]}),h&&e.jsx("pre",{style:{fontSize:11,fontFamily:"var(--font-mono)",maxHeight:220,overflow:"auto",background:"var(--surface-sunken)",padding:8,borderRadius:4},children:h.map(i=>`${i.item.padEnd(14)} ${i.status.padEnd(6)} ${i.detail}`).join(`
2
+ `)}),B&&e.jsxs("div",{style:{display:"grid",gap:4,border:"1px solid var(--border-strong)",borderRadius:4,padding:8},children:[e.jsx("strong",{style:{fontSize:12},children:"Buat admin pertama"}),e.jsx("a",{href:B.url,target:"_blank",rel:"noreferrer",style:{fontSize:12,wordBreak:"break-all"},children:B.url}),e.jsxs("span",{style:{fontSize:11,color:"var(--text-subtle)"},children:["berlaku sampai ",new Date(B.expiresAt).toLocaleTimeString("id-ID")]}),e.jsx("div",{children:e.jsx(f,{size:"sm",variant:"ghost",onClick:()=>{var i;return void((i=navigator.clipboard)==null?void 0:i.writeText(B.url))},children:"Salin"})})]}),_.length>0&&e.jsxs("div",{style:{display:"flex",gap:8,alignItems:"center",fontSize:12},children:[e.jsx(W,{name:"alert-triangle"}),e.jsxs("span",{children:[_.map(([i])=>i).join(", ")," terpasang tapi belum login."]}),e.jsx(f,{size:"sm",variant:"ghost",onClick:X,children:"Login lewat Console"})]}),V]})}const ie=(a,s=Date.now())=>!!a.lastSeenAt&&s-new Date(a.lastSeenAt).getTime()<10*6e4,Ve=a=>a.lastAuditAt?a.hardened?"hardened":"belum":"unknown",Oe={hardened:{status:"ok",label:"hardened"},belum:{status:"broken",label:"belum hardened"},unknown:{status:"idle",label:"belum diaudit"}};function re(a){const s={name:a.name.trim(),host:a.host.trim(),user:a.user.trim(),port:Number(a.port)||22};return a.keyPath.trim()&&(s.keyPath=a.keyPath.trim()),a.password&&(s.password=a.password),s}const Te="opsional — dipakai sekali untuk memasang key hanoman, tidak disimpan";function ae({open:a,title:s,submitLabel:l,initial:o,onClose:u,onSubmit:c}){const[n,b]=p.useState(o);p.useEffect(()=>{a&&b(o)},[a,o]);const g=S=>h=>b(y=>({...y,[S]:h.target.value})),k=!!(n.name.trim()&&n.host.trim()&&n.user.trim());return e.jsxs(oe,{open:a,onClose:u,icon:"server",eyebrow:"infra",title:s,footer:e.jsxs(e.Fragment,{children:[e.jsx(f,{variant:"ghost",size:"sm",onClick:u,children:"Batal"}),e.jsx(f,{size:"sm",leftIcon:"check",onClick:()=>k&&c(n),children:l})]}),children:[e.jsx(O,{label:"Nama",children:e.jsx(T,{value:n.name,onChange:g("name"),placeholder:"mis. web-1",style:{width:"100%"}})}),e.jsx(O,{label:"Host",hint:"hostname atau IP — tanpa user@",children:e.jsx(T,{value:n.host,onChange:g("host"),mono:!0,placeholder:"203.0.113.10",style:{width:"100%"}})}),e.jsxs("div",{className:"hn-grid-mobile",style:{display:"grid",gridTemplateColumns:"1.4fr 1fr",gap:12},children:[e.jsx(O,{label:"User SSH",hint:"root atau user ber-passwordless-sudo",children:e.jsx(T,{value:n.user,onChange:g("user"),mono:!0,placeholder:"deploy",style:{width:"100%"}})}),e.jsx(O,{label:"Port",children:e.jsx(T,{value:n.port,onChange:g("port"),mono:!0,placeholder:"22",style:{width:"100%"}})})]}),e.jsx(O,{label:"Password SSH",hint:Te,children:e.jsx(T,{type:"password",value:n.password,onChange:g("password"),placeholder:"••••••••",style:{width:"100%"}})}),e.jsx(O,{label:"Key path",hint:"kosongkan bila memakai password di atas, atau key default mesin server",children:e.jsx(T,{value:n.keyPath,onChange:g("keyPath"),mono:!0,placeholder:"~/.ssh/id_ed25519",style:{width:"100%"}})})]})}const le={name:"",host:"",user:"",port:"22",keyPath:"",password:""},We=a=>({name:a.name,host:a.host,user:a.user,port:String(a.port),keyPath:a.keyPath??"",password:""});function Me({onToast:a,onGotoTerminal:s}){const[l,o]=p.useState([]),[u,c]=p.useState("loading"),[n,b]=p.useState(null),[g,k]=p.useState(null),[S,h]=de("vps","detailId",null,ve),y=p.useMemo(()=>l.find(t=>t.id===S)??null,[l,S]),P=p.useCallback(t=>h(t?t.id:null),[h]),w=p.useCallback(()=>{v.listVps().then(t=>{o(t),c("ready")}).catch(()=>c("error"))},[]);p.useEffect(()=>(w(),ye(t=>{t.t==="vps"&&(o(t.vps),c("ready"))})),[w]);const{confirm:B,dialog:E}=te();async function $(t,x,m,H){b(`${t}:${x}`);try{await m(),w(),a(H,"ok","server")}catch{a(`Gagal ${t}`,"err","x-circle")}finally{b(null)}}const C=t=>$("audit",t.id,()=>v.auditVps(t.id),`${t.name} · audit selesai`);async function R(t){await B({title:`Harden "${t.name}"?`,message:"Pastikan akses key SSH non-password kamu sudah bekerja sebelum melanjutkan.",impact:[`Firewall: izinkan ${t.port}/80/443.`,"fail2ban & auto security update dipasang.","PermitRootLogin & PasswordAuthentication dimatikan.","NTP disinkronkan."],confirmLabel:"Harden",icon:"shield"})&&$("harden",t.id,()=>v.hardenVps(t.id),`${t.name} · harden selesai`)}const V=t=>$("sesi",t.id,async()=>{const{id:x}=await v.vpsSession(t.id);s(x)},`${t.name} · sesi Claude dibuka`),F=t=>$("test",t.id,async()=>{const x=await v.testVps(t.id);if(!x.ok)throw new Error(x.out)},`${t.name} · koneksi ok`),D=t=>$("console",t.id,async()=>{const{id:x}=await v.vpsConsole(t.id);s(x)},`${t.name} · console dibuka`);async function A(t){try{if(!await B({title:`Hapus registrasi VPS "${t.name}"?`,message:"Server-nya sendiri tak disentuh — hanya pendaftarannya di dashboard ini yang dihapus.",confirmLabel:"Hapus registrasi",run:()=>v.deleteVps(t.id)}))return;w()}catch{a("Gagal hapus","err","x-circle")}}async function L(t){try{const x=await v.createVps(re(t));k(null),w(),a(t.password?`${x.name} terdaftar · key hanoman terpasang · password dibuang`:`${x.name} terdaftar · jalankan audit`,"ok","server")}catch{a("Gagal mendaftarkan VPS — cek host/user, atau password SSH-nya","err","x-circle")}}async function I(t,x){try{const m=await v.updateVps(t.id,re(x));k(null),w(),a(x.password?`${m.name} diperbarui · key hanoman terpasang · password dibuang`:`${m.name} diperbarui`,"ok","server")}catch{a("Gagal memperbarui VPS","err","x-circle")}}return u==="loading"?e.jsx(U,{kind:"loading",title:"Memuat daftar VPS…"}):u==="error"?e.jsx(U,{kind:"error",title:"Gagal memuat daftar VPS",hint:"Pastikan server hanoman berjalan.",action:w}):l.length===0?e.jsxs(e.Fragment,{children:[e.jsx(U,{kind:"empty",icon:"server",title:"Belum ada VPS",hint:"Daftarkan VPS untuk mulai audit & hardening.",action:()=>k("new"),actionLabel:"Daftarkan VPS"}),e.jsx(ae,{open:g==="new",title:"Daftarkan VPS",submitLabel:"Daftarkan",initial:le,onClose:()=>k(null),onSubmit:L})]}):e.jsxs("div",{children:[e.jsxs("div",{children:[e.jsx("div",{style:{display:"flex",justifyContent:"flex-end",marginBottom:10},children:e.jsx(f,{size:"sm",leftIcon:"plus",onClick:()=>k("new"),children:"Daftarkan VPS"})}),l.map(t=>{const x=Oe[Ve(t)];return e.jsxs("div",{className:"hn-vps-row",onClick:()=>P(t),style:{padding:"10px 12px",cursor:"pointer",border:"1px solid var(--border-hair)",borderRadius:"var(--radius-sm)",marginBottom:8},children:[e.jsxs("div",{className:"hn-vps-main",children:[e.jsxs("button",{type:"button","aria-label":`Buka detail ${t.name}`,onClick:m=>{m.stopPropagation(),P(t)},style:{display:"flex",alignItems:"center",gap:10,flex:"1 1 220px",minWidth:0,cursor:"pointer",font:"inherit",color:"inherit",textAlign:"left",background:"transparent",padding:0,border:"none"},children:[e.jsx(W,{name:"server",size:16,color:"var(--brass-700)"}),e.jsxs("span",{style:{minWidth:0},children:[e.jsx("span",{style:{display:"block",fontSize:13,fontWeight:600,overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"},children:t.name}),e.jsxs("span",{style:{display:"block",fontSize:12,fontFamily:"var(--font-mono)",color:"var(--text-subtle)",overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"},children:[t.user,"@",t.host,t.port!==22?`:${t.port}`:""]})]})]}),e.jsxs("div",{className:"hn-vps-pills",style:{display:"flex",gap:6,alignItems:"center",flexShrink:0},children:[e.jsx(se,{size:"sm",status:ie(t)?"ok":"broken",children:ie(t)?"reachable":"unreachable"}),e.jsx(se,{size:"sm",status:x.status,children:x.label})]}),e.jsxs("div",{className:"hn-vps-actions",children:[e.jsx(f,{size:"sm",variant:"ghost",leftIcon:"plug-zap",loading:n===`test:${t.id}`,onClick:m=>{m.stopPropagation(),F(t)},children:"Test"}),e.jsx(f,{size:"sm",variant:"ghost",leftIcon:"terminal-square",loading:n===`console:${t.id}`,onClick:m=>{m.stopPropagation(),D(t)},children:"Console"}),e.jsx(f,{size:"sm",variant:"ghost",leftIcon:"terminal",loading:n===`sesi:${t.id}`,onClick:m=>{m.stopPropagation(),V(t)},children:"Sesi Claude"}),e.jsx(f,{size:"sm",variant:"secondary",leftIcon:"radar",loading:n===`audit:${t.id}`,onClick:m=>{m.stopPropagation(),C(t)},children:"Audit"}),e.jsx(f,{size:"sm",leftIcon:"shield",loading:n===`harden:${t.id}`,onClick:m=>{m.stopPropagation(),R(t)},children:"Harden"}),e.jsx("span",{"aria-hidden":!0,className:"hn-vps-sep"}),e.jsx(f,{size:"sm",variant:"ghost",leftIcon:"pencil",title:`Edit ${t.name}`,onClick:m=>{m.stopPropagation(),k(t)}}),e.jsx(f,{size:"sm",variant:"ghost",leftIcon:"trash-2",title:`Hapus ${t.name}`,onClick:m=>{m.stopPropagation(),A(t)}})]})]}),e.jsx("div",{style:{marginTop:8,paddingTop:8,borderTop:"1px solid var(--border-hair)"},children:e.jsx(Le,{components:t.components??null,checkedAt:t.componentsCheckedAt??null})})]},t.id)})]}),y&&e.jsx(Ae,{vpsId:y.id,vpsName:y.name,lastAuditAt:y.lastAuditAt,health:y.health,provisioning:e.jsx(De,{vps:y,onToast:a,onGotoTerminal:s}),onClose:()=>{P(null),w()},onToast:a}),e.jsx(ae,{open:g==="new",title:"Daftarkan VPS",submitLabel:"Daftarkan",initial:le,onClose:()=>k(null),onSubmit:L}),g&&g!=="new"&&e.jsx(ae,{open:!0,title:`Edit ${g.name}`,submitLabel:"Simpan",initial:We(g),onClose:()=>k(null),onSubmit:t=>I(g,t)}),E]})}export{Me as VpsScreen,Ve as hardenedLabel,ie as isReachable,re as vpsFormToBody};
@@ -0,0 +1,2 @@
1
+ import{j as t,I as v,f as W}from"./index-DSFIYjSl.js";import{R as g}from"./react-DfGhg7ZW.js";import"./markdown-CWEY34jk.js";function F(s,n=[]){const i={path:"",kids:[]},r=(o,p)=>{let e=i;const c=o.split("/").filter(Boolean);c.forEach((a,x)=>{const y=p&&x===c.length-1,m=e.path?e.path+"/"+a:a;let d=e.kids.find(u=>u.name===a&&u.leaf===y);d||(d={name:a,path:m,kids:[],leaf:y},e.kids.push(d)),e=d})};for(const o of s)r(o,!0);for(const o of n)r(o,!1);const l=o=>{o.kids.sort((p,e)=>p.leaf===e.leaf?p.name.localeCompare(e.name):p.leaf?1:-1),o.kids.forEach(l)};return l(i),i.kids}const j={A:"var(--leaf-600)",M:"var(--brass-600)",D:"var(--clay-500)"};function k({node:s,selected:n,onSelect:i,depth:r=0,meta:l,defaultOpen:o=!1,dirSelected:p,onSelectDir:e,ignored:c,onExpand:a}){const[x,y]=g.useState(o),[m,d]=g.useState(!1),u=c!=null&&c.has(s.path)?.62:1;if(s.leaf){const f=s.path===n,h=l==null?void 0:l[s.path];return t.jsxs("button",{onClick:()=>i(s.path),style:{display:"flex",alignItems:"center",gap:8,width:"100%",padding:"5px 8px",paddingLeft:22+r*12,border:"none",cursor:"pointer",textAlign:"left",background:f?"var(--brass-100)":"transparent",opacity:u},children:[h?t.jsx("span",{style:{fontFamily:"var(--font-mono)",fontSize:12,fontWeight:700,color:j[h.status]},children:h.status}):t.jsx(v,{name:"file-text",size:13,color:f?"var(--brass-700)":"var(--text-subtle)"}),t.jsx("span",{style:{flex:1,minWidth:0,fontFamily:"var(--font-mono)",fontSize:12,overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap",color:f?"var(--brass-700)":"var(--text-body)",fontWeight:f?600:400},children:s.name}),h&&!h.binary&&t.jsxs("span",{style:{fontFamily:"var(--font-mono)",fontSize:11},children:[t.jsxs("span",{style:{color:"var(--leaf-600)"},children:["+",h.add]})," ",t.jsxs("span",{style:{color:"var(--clay-500)"},children:["−",h.del]})]})]})}const b=!!e&&s.path===p,w=!!a&&s.kids.length===0;async function z(){e==null||e(s.path);const f=!x;if(y(f),f&&w&&!m){d(!0);try{await(a==null?void 0:a(s.path))}finally{d(!1)}}}return t.jsxs("div",{children:[t.jsxs("button",{onClick:()=>void z(),style:{display:"flex",alignItems:"center",gap:8,width:"100%",padding:"5px 6px",paddingLeft:6+r*12,border:"none",background:b?"var(--brass-100)":"transparent",cursor:"pointer",textAlign:"left",opacity:u},children:[t.jsx(v,{name:x?"chevron-down":"chevron-right",size:14,color:"var(--text-subtle)"}),t.jsx(v,{name:"folder",size:15,color:b?"var(--brass-700)":"var(--brass-500)"}),t.jsxs("span",{style:{fontFamily:"var(--font-mono)",fontSize:12.5,color:b?"var(--brass-700)":"var(--text-strong)",fontWeight:b?700:500},children:[s.name,"/"]}),m&&t.jsx("span",{style:{fontSize:11,color:"var(--text-subtle)"},children:"memuat…"})]}),x&&s.kids.map(f=>t.jsx(k,{node:f,selected:n,onSelect:i,depth:r+1,meta:l,defaultOpen:o,dirSelected:p,onSelectDir:e,ignored:c,onExpand:a},f.path)),x&&!m&&s.kids.length===0&&t.jsx("div",{style:{padding:"4px 8px",paddingLeft:28+r*12,fontSize:11.5,color:"var(--text-subtle)"},children:"kosong"})]})}function S({cf:s,selected:n,onSelect:i}){const r=s.path===n;return t.jsxs("button",{onClick:()=>i(s.path),style:{display:"flex",alignItems:"center",gap:8,width:"100%",padding:"5px 10px",border:"none",cursor:"pointer",textAlign:"left",background:r?"var(--brass-100)":"transparent"},children:[t.jsx("span",{style:{fontFamily:"var(--font-mono)",fontSize:12,fontWeight:700,color:j[s.status]},children:s.status}),t.jsx("span",{style:{flex:1,minWidth:0,fontFamily:"var(--font-mono)",fontSize:12,overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap",color:r?"var(--brass-700)":"var(--text-body)"},children:s.path}),!s.binary&&t.jsxs("span",{style:{fontFamily:"var(--font-mono)",fontSize:11},children:[t.jsxs("span",{style:{color:"var(--leaf-600)"},children:["+",s.add]})," ",t.jsxs("span",{style:{color:"var(--clay-500)"},children:["−",s.del]})]})]})}function T({label:s,changed:n,selected:i,onSelect:r,view:l,onView:o,emptyText:p="Tak ada file berubah."}){const e=g.useMemo(()=>F(n.map(a=>a.path)),[n]),c=g.useMemo(()=>Object.fromEntries(n.map(a=>[a.path,a])),[n]);return t.jsxs(t.Fragment,{children:[t.jsxs("div",{className:"hn-eyebrow",style:{display:"flex",alignItems:"center",gap:6,padding:"6px 8px"},children:[t.jsxs("span",{style:{flex:1},children:[s," · ",n.length]}),n.length>0&&["list","tree"].map(a=>t.jsx("button",{"aria-label":`${a==="list"?"List":"Tree"} ${s}`,onClick:()=>o(a),style:{display:"flex",padding:3,border:"none",cursor:"pointer",borderRadius:4,background:l===a?"var(--brass-100)":"transparent"},children:t.jsx(v,{name:a==="list"?"list":"folder-tree",size:14,color:l===a?"var(--brass-700)":"var(--text-subtle)"})},a))]}),n.length===0?t.jsx("div",{style:{padding:"4px 10px",fontSize:12,color:"var(--text-subtle)"},children:p}):l==="tree"?e.map(a=>t.jsx(k,{node:a,selected:i,onSelect:r,meta:c,defaultOpen:!0},a.path)):n.map(a=>t.jsx(S,{cf:a,selected:i,onSelect:r},a.path))]})}function I({diff:s,emptyTitle:n="Tidak ada perubahan pada file ini",emptyHint:i}){return s?t.jsx("pre",{style:{margin:0,fontFamily:"var(--font-mono)",fontSize:12.5,lineHeight:1.6},children:s.split(`
2
+ `).map((r,l)=>{const o=r.startsWith("+")&&!r.startsWith("+++"),p=r.startsWith("-")&&!r.startsWith("---"),e=r.startsWith("@@"),c=o?"var(--leaf-600)":p?"var(--clay-600)":e?"var(--brass-700)":"var(--text-body)",a=o?"color-mix(in srgb, var(--leaf-500) 10%, transparent)":p?"color-mix(in srgb, var(--clay-500) 10%, transparent)":"transparent";return t.jsx("div",{style:{color:c,background:a,padding:"0 12px",whiteSpace:"pre-wrap",wordBreak:"break-word"},children:r||" "},l)})}):t.jsx(W,{kind:"empty",icon:"check",title:n,hint:i})}export{T as C,I as D,k as T,F as b};
@@ -0,0 +1,3 @@
1
+ import{g as Ve}from"./react-DfGhg7ZW.js";function xe(e){return e instanceof Map?e.clear=e.delete=e.set=function(){throw new Error("map is read-only")}:e instanceof Set&&(e.add=e.clear=e.delete=function(){throw new Error("set is read-only")}),Object.freeze(e),Object.getOwnPropertyNames(e).forEach(t=>{const i=e[t],u=typeof i;(u==="object"||u==="function")&&!Object.isFrozen(i)&&xe(i)}),e}class he{constructor(t){t.data===void 0&&(t.data={}),this.data=t.data,this.isMatchIgnored=!1}ignoreMatch(){this.isMatchIgnored=!0}}function we(e){return e.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&#x27;")}function B(e,...t){const i=Object.create(null);for(const u in e)i[u]=e[u];return t.forEach(function(u){for(const b in u)i[b]=u[b]}),i}const qe="</span>",pe=e=>!!e.scope,Qe=(e,{prefix:t})=>{if(e.startsWith("language:"))return e.replace("language:","language-");if(e.includes(".")){const i=e.split(".");return[`${t}${i.shift()}`,...i.map((u,b)=>`${u}${"_".repeat(b+1)}`)].join(" ")}return`${t}${e}`};class me{constructor(t,i){this.buffer="",this.classPrefix=i.classPrefix,t.walk(this)}addText(t){this.buffer+=we(t)}openNode(t){if(!pe(t))return;const i=Qe(t.scope,{prefix:this.classPrefix});this.span(i)}closeNode(t){pe(t)&&(this.buffer+=qe)}value(){return this.buffer}span(t){this.buffer+=`<span class="${t}">`}}const de=(e={})=>{const t={children:[]};return Object.assign(t,e),t};class te{constructor(){this.rootNode=de(),this.stack=[this.rootNode]}get top(){return this.stack[this.stack.length-1]}get root(){return this.rootNode}add(t){this.top.children.push(t)}openNode(t){const i=de({scope:t});this.add(i),this.stack.push(i)}closeNode(){if(this.stack.length>1)return this.stack.pop()}closeAllNodes(){for(;this.closeNode(););}toJSON(){return JSON.stringify(this.rootNode,null,4)}walk(t){return this.constructor._walk(t,this.rootNode)}static _walk(t,i){return typeof i=="string"?t.addText(i):i.children&&(t.openNode(i),i.children.forEach(u=>this._walk(t,u)),t.closeNode(i)),t}static _collapse(t){typeof t!="string"&&t.children&&(t.children.every(i=>typeof i=="string")?t.children=[t.children.join("")]:t.children.forEach(i=>{te._collapse(i)}))}}class et extends te{constructor(t){super(),this.options=t}addText(t){t!==""&&this.add(t)}startScope(t){this.openNode(t)}endScope(){this.closeNode()}__addSublanguage(t,i){const u=t.root;i&&(u.scope=`language:${i}`),this.add(u)}toHTML(){return new me(this,this.options).value()}finalize(){return this.closeAllNodes(),!0}}function P(e){return e?typeof e=="string"?e:e.source:null}function Oe(e){return C("(?=",e,")")}function tt(e){return C("(?:",e,")*")}function nt(e){return C("(?:",e,")?")}function C(...e){return e.map(i=>P(i)).join("")}function it(e){const t=e[e.length-1];return typeof t=="object"&&t.constructor===Object?(e.splice(e.length-1,1),t):{}}function ne(...e){return"("+(it(e).capture?"":"?:")+e.map(u=>P(u)).join("|")+")"}function Re(e){return new RegExp(e.toString()+"|").exec("").length-1}function st(e,t){const i=e&&e.exec(t);return i&&i.index===0}const rt=/\[(?:[^\\\]]|\\.)*\]|\(\??|\\([1-9][0-9]*)|\\./;function ie(e,{joinWith:t}){let i=0;return e.map(u=>{i+=1;const b=i;let _=P(u),c="";for(;_.length>0;){const r=rt.exec(_);if(!r){c+=_;break}c+=_.substring(0,r.index),_=_.substring(r.index+r[0].length),r[0][0]==="\\"&&r[1]?c+="\\"+String(Number(r[1])+b):(c+=r[0],r[0]==="("&&i++)}return c}).map(u=>`(${u})`).join(t)}const ct=/\b\B/,ye="[a-zA-Z]\\w*",se="[a-zA-Z_]\\w*",Se="\\b\\d+(\\.\\d+)?",Ne="(-?)(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)",Ae="\\b(0b[01]+)",ot="!|!=|!==|%|%=|&|&&|&=|\\*|\\*=|\\+|\\+=|,|-|-=|/=|/|:|;|<<|<<=|<=|<|===|==|=|>>>=|>>=|>=|>>>|>>|>|\\?|\\[|\\{|\\(|\\^|\\^=|\\||\\|=|\\|\\||~",at=(e={})=>{const t=/^#![ ]*\//;return e.binary&&(e.begin=C(t,/.*\b/,e.binary,/\b.*/)),B({scope:"meta",begin:t,end:/$/,relevance:0,"on:begin":(i,u)=>{i.index!==0&&u.ignoreMatch()}},e)},U={begin:"\\\\[\\s\\S]",relevance:0},lt={scope:"string",begin:"'",end:"'",illegal:"\\n",contains:[U]},ut={scope:"string",begin:'"',end:'"',illegal:"\\n",contains:[U]},ft={begin:/\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\b/},Y=function(e,t,i={}){const u=B({scope:"comment",begin:e,end:t,contains:[]},i);u.contains.push({scope:"doctag",begin:"[ ]*(?=(TODO|FIXME|NOTE|BUG|OPTIMIZE|HACK|XXX):)",end:/(TODO|FIXME|NOTE|BUG|OPTIMIZE|HACK|XXX):/,excludeBegin:!0,relevance:0});const b=ne("I","a","is","so","us","to","at","if","in","it","on",/[A-Za-z]+['](d|ve|re|ll|t|s|n)/,/[A-Za-z]+[-][a-z]+/,/[A-Za-z][a-z]{2,}/);return u.contains.push({begin:C(/[ ]+/,"(",b,/[.]?[:]?([.][ ]|[ ])/,"){3}")}),u},gt=Y("//","$"),ht=Y("/\\*","\\*/"),pt=Y("#","$"),dt={scope:"number",begin:Se,relevance:0},Et={scope:"number",begin:Ne,relevance:0},bt={scope:"number",begin:Ae,relevance:0},_t={scope:"regexp",begin:/\/(?=[^/\n]*\/)/,end:/\/[gimuy]*/,contains:[U,{begin:/\[/,end:/\]/,relevance:0,contains:[U]}]},Mt={scope:"title",begin:ye,relevance:0},xt={scope:"title",begin:se,relevance:0},wt={begin:"\\.\\s*"+se,relevance:0},Ot=function(e){return Object.assign(e,{"on:begin":(t,i)=>{i.data._beginMatch=t[1]},"on:end":(t,i)=>{i.data._beginMatch!==t[1]&&i.ignoreMatch()}})};var z=Object.freeze({__proto__:null,APOS_STRING_MODE:lt,BACKSLASH_ESCAPE:U,BINARY_NUMBER_MODE:bt,BINARY_NUMBER_RE:Ae,COMMENT:Y,C_BLOCK_COMMENT_MODE:ht,C_LINE_COMMENT_MODE:gt,C_NUMBER_MODE:Et,C_NUMBER_RE:Ne,END_SAME_AS_BEGIN:Ot,HASH_COMMENT_MODE:pt,IDENT_RE:ye,MATCH_NOTHING_RE:ct,METHOD_GUARD:wt,NUMBER_MODE:dt,NUMBER_RE:Se,PHRASAL_WORDS_MODE:ft,QUOTE_STRING_MODE:ut,REGEXP_MODE:_t,RE_STARTERS_RE:ot,SHEBANG:at,TITLE_MODE:Mt,UNDERSCORE_IDENT_RE:se,UNDERSCORE_TITLE_MODE:xt});function Rt(e,t){e.input[e.index-1]==="."&&t.ignoreMatch()}function yt(e,t){e.className!==void 0&&(e.scope=e.className,delete e.className)}function St(e,t){t&&e.beginKeywords&&(e.begin="\\b("+e.beginKeywords.split(" ").join("|")+")(?!\\.)(?=\\b|\\s)",e.__beforeBegin=Rt,e.keywords=e.keywords||e.beginKeywords,delete e.beginKeywords,e.relevance===void 0&&(e.relevance=0))}function Nt(e,t){Array.isArray(e.illegal)&&(e.illegal=ne(...e.illegal))}function At(e,t){if(e.match){if(e.begin||e.end)throw new Error("begin & end are not supported with match");e.begin=e.match,delete e.match}}function kt(e,t){e.relevance===void 0&&(e.relevance=1)}const Tt=(e,t)=>{if(!e.beforeMatch)return;if(e.starts)throw new Error("beforeMatch cannot be used with starts");const i=Object.assign({},e);Object.keys(e).forEach(u=>{delete e[u]}),e.keywords=i.keywords,e.begin=C(i.beforeMatch,Oe(i.begin)),e.starts={relevance:0,contains:[Object.assign(i,{endsParent:!0})]},e.relevance=0,delete i.beforeMatch},It=["of","and","for","in","not","or","if","then","parent","list","value"],Bt="keyword";function ke(e,t,i=Bt){const u=Object.create(null);return typeof e=="string"?b(i,e.split(" ")):Array.isArray(e)?b(i,e):Object.keys(e).forEach(function(_){Object.assign(u,ke(e[_],t,_))}),u;function b(_,c){t&&(c=c.map(r=>r.toLowerCase())),c.forEach(function(r){const l=r.split("|");u[l[0]]=[_,Dt(l[0],l[1])]})}}function Dt(e,t){return t?Number(t):vt(e)?0:1}function vt(e){return It.includes(e.toLowerCase())}const Ee={},v=e=>{console.error(e)},be=(e,...t)=>{console.log(`WARN: ${e}`,...t)},L=(e,t)=>{Ee[`${e}/${t}`]||(console.log(`Deprecated as of ${e}. ${t}`),Ee[`${e}/${t}`]=!0)},X=new Error;function Te(e,t,{key:i}){let u=0;const b=e[i],_={},c={};for(let r=1;r<=t.length;r++)c[r+u]=b[r],_[r+u]=!0,u+=Re(t[r-1]);e[i]=c,e[i]._emit=_,e[i]._multi=!0}function Ct(e){if(Array.isArray(e.begin)){if(e.skip||e.excludeBegin||e.returnBegin)throw v("skip, excludeBegin, returnBegin not compatible with beginScope: {}"),X;if(typeof e.beginScope!="object"||e.beginScope===null)throw v("beginScope must be object"),X;Te(e,e.begin,{key:"beginScope"}),e.begin=ie(e.begin,{joinWith:""})}}function Lt(e){if(Array.isArray(e.end)){if(e.skip||e.excludeEnd||e.returnEnd)throw v("skip, excludeEnd, returnEnd not compatible with endScope: {}"),X;if(typeof e.endScope!="object"||e.endScope===null)throw v("endScope must be object"),X;Te(e,e.end,{key:"endScope"}),e.end=ie(e.end,{joinWith:""})}}function Ht(e){e.scope&&typeof e.scope=="object"&&e.scope!==null&&(e.beginScope=e.scope,delete e.scope)}function jt(e){Ht(e),typeof e.beginScope=="string"&&(e.beginScope={_wrap:e.beginScope}),typeof e.endScope=="string"&&(e.endScope={_wrap:e.endScope}),Ct(e),Lt(e)}function Pt(e){function t(c,r){return new RegExp(P(c),"m"+(e.case_insensitive?"i":"")+(e.unicodeRegex?"u":"")+(r?"g":""))}class i{constructor(){this.matchIndexes={},this.regexes=[],this.matchAt=1,this.position=0}addRule(r,l){l.position=this.position++,this.matchIndexes[this.matchAt]=l,this.regexes.push([l,r]),this.matchAt+=Re(r)+1}compile(){this.regexes.length===0&&(this.exec=()=>null);const r=this.regexes.map(l=>l[1]);this.matcherRe=t(ie(r,{joinWith:"|"}),!0),this.lastIndex=0}exec(r){this.matcherRe.lastIndex=this.lastIndex;const l=this.matcherRe.exec(r);if(!l)return null;const w=l.findIndex((j,Z)=>Z>0&&j!==void 0),M=this.matchIndexes[w];return l.splice(0,w),Object.assign(l,M)}}class u{constructor(){this.rules=[],this.multiRegexes=[],this.count=0,this.lastIndex=0,this.regexIndex=0}getMatcher(r){if(this.multiRegexes[r])return this.multiRegexes[r];const l=new i;return this.rules.slice(r).forEach(([w,M])=>l.addRule(w,M)),l.compile(),this.multiRegexes[r]=l,l}resumingScanAtSamePosition(){return this.regexIndex!==0}considerAll(){this.regexIndex=0}addRule(r,l){this.rules.push([r,l]),l.type==="begin"&&this.count++}exec(r){const l=this.getMatcher(this.regexIndex);l.lastIndex=this.lastIndex;let w=l.exec(r);if(this.resumingScanAtSamePosition()&&!(w&&w.index===this.lastIndex)){const M=this.getMatcher(0);M.lastIndex=this.lastIndex+1,w=M.exec(r)}return w&&(this.regexIndex+=w.position+1,this.regexIndex===this.count&&this.considerAll()),w}}function b(c){const r=new u;return c.contains.forEach(l=>r.addRule(l.begin,{rule:l,type:"begin"})),c.terminatorEnd&&r.addRule(c.terminatorEnd,{type:"end"}),c.illegal&&r.addRule(c.illegal,{type:"illegal"}),r}function _(c,r){const l=c;if(c.isCompiled)return l;[yt,At,jt,Tt].forEach(M=>M(c,r)),e.compilerExtensions.forEach(M=>M(c,r)),c.__beforeBegin=null,[St,Nt,kt].forEach(M=>M(c,r)),c.isCompiled=!0;let w=null;return typeof c.keywords=="object"&&c.keywords.$pattern&&(c.keywords=Object.assign({},c.keywords),w=c.keywords.$pattern,delete c.keywords.$pattern),w=w||/\w+/,c.keywords&&(c.keywords=ke(c.keywords,e.case_insensitive)),l.keywordPatternRe=t(w,!0),r&&(c.begin||(c.begin=/\B|\b/),l.beginRe=t(l.begin),!c.end&&!c.endsWithParent&&(c.end=/\B|\b/),c.end&&(l.endRe=t(l.end)),l.terminatorEnd=P(l.end)||"",c.endsWithParent&&r.terminatorEnd&&(l.terminatorEnd+=(c.end?"|":"")+r.terminatorEnd)),c.illegal&&(l.illegalRe=t(c.illegal)),c.contains||(c.contains=[]),c.contains=[].concat(...c.contains.map(function(M){return Ut(M==="self"?c:M)})),c.contains.forEach(function(M){_(M,l)}),c.starts&&_(c.starts,r),l.matcher=b(l),l}if(e.compilerExtensions||(e.compilerExtensions=[]),e.contains&&e.contains.includes("self"))throw new Error("ERR: contains `self` is not supported at the top-level of a language. See documentation.");return e.classNameAliases=B(e.classNameAliases||{}),_(e)}function Ie(e){return e?e.endsWithParent||Ie(e.starts):!1}function Ut(e){return e.variants&&!e.cachedVariants&&(e.cachedVariants=e.variants.map(function(t){return B(e,{variants:null},t)})),e.cachedVariants?e.cachedVariants:Ie(e)?B(e,{starts:e.starts?B(e.starts):null}):Object.isFrozen(e)?B(e):e}var $t="11.11.1";class Gt extends Error{constructor(t,i){super(t),this.name="HTMLInjectionError",this.html=i}}const ee=we,_e=B,Me=Symbol("nomatch"),Wt=7,Be=function(e){const t=Object.create(null),i=Object.create(null),u=[];let b=!0;const _="Could not find the language '{}', did you forget to load/include a language module?",c={disableAutodetect:!0,name:"Plain text",contains:[]};let r={ignoreUnescapedHTML:!1,throwUnescapedHTML:!1,noHighlightRe:/^(no-?highlight)$/i,languageDetectRe:/\blang(?:uage)?-([\w-]+)\b/i,classPrefix:"hljs-",cssSelector:"pre code",languages:null,__emitter:et};function l(n){return r.noHighlightRe.test(n)}function w(n){let a=n.className+" ";a+=n.parentNode?n.parentNode.className:"";const h=r.languageDetectRe.exec(a);if(h){const d=T(h[1]);return d||(be(_.replace("{}",h[1])),be("Falling back to no-highlight mode for this block.",n)),d?h[1]:"no-highlight"}return a.split(/\s+/).find(d=>l(d)||T(d))}function M(n,a,h){let d="",x="";typeof a=="object"?(d=n,h=a.ignoreIllegals,x=a.language):(L("10.7.0","highlight(lang, code, ...args) has been deprecated."),L("10.7.0",`Please use highlight(code, options) instead.
2
+ https://github.com/highlightjs/highlight.js/issues/2277`),x=n,d=a),h===void 0&&(h=!0);const S={code:d,language:x};G("before:highlight",S);const I=S.result?S.result:j(S.language,S.code,h);return I.code=S.code,G("after:highlight",I),I}function j(n,a,h,d){const x=Object.create(null);function S(s,o){return s.keywords[o]}function I(){if(!f.keywords){O.addText(E);return}let s=0;f.keywordPatternRe.lastIndex=0;let o=f.keywordPatternRe.exec(E),g="";for(;o;){g+=E.substring(s,o.index);const p=A.case_insensitive?o[0].toLowerCase():o[0],R=S(f,p);if(R){const[k,Ze]=R;if(O.addText(g),g="",x[p]=(x[p]||0)+1,x[p]<=Wt&&(F+=Ze),k.startsWith("_"))g+=o[0];else{const Je=A.classNameAliases[k]||k;N(o[0],Je)}}else g+=o[0];s=f.keywordPatternRe.lastIndex,o=f.keywordPatternRe.exec(E)}g+=E.substring(s),O.addText(g)}function W(){if(E==="")return;let s=null;if(typeof f.subLanguage=="string"){if(!t[f.subLanguage]){O.addText(E);return}s=j(f.subLanguage,E,!0,ge[f.subLanguage]),ge[f.subLanguage]=s._top}else s=J(E,f.subLanguage.length?f.subLanguage:null);f.relevance>0&&(F+=s.relevance),O.__addSublanguage(s._emitter,s.language)}function y(){f.subLanguage!=null?W():I(),E=""}function N(s,o){s!==""&&(O.startScope(o),O.addText(s),O.endScope())}function ae(s,o){let g=1;const p=o.length-1;for(;g<=p;){if(!s._emit[g]){g++;continue}const R=A.classNameAliases[s[g]]||s[g],k=o[g];R?N(k,R):(E=k,I(),E=""),g++}}function le(s,o){return s.scope&&typeof s.scope=="string"&&O.openNode(A.classNameAliases[s.scope]||s.scope),s.beginScope&&(s.beginScope._wrap?(N(E,A.classNameAliases[s.beginScope._wrap]||s.beginScope._wrap),E=""):s.beginScope._multi&&(ae(s.beginScope,o),E="")),f=Object.create(s,{parent:{value:f}}),f}function ue(s,o,g){let p=st(s.endRe,g);if(p){if(s["on:end"]){const R=new he(s);s["on:end"](o,R),R.isMatchIgnored&&(p=!1)}if(p){for(;s.endsParent&&s.parent;)s=s.parent;return s}}if(s.endsWithParent)return ue(s.parent,o,g)}function Ke(s){return f.matcher.regexIndex===0?(E+=s[0],1):(m=!0,0)}function Fe(s){const o=s[0],g=s.rule,p=new he(g),R=[g.__beforeBegin,g["on:begin"]];for(const k of R)if(k&&(k(s,p),p.isMatchIgnored))return Ke(o);return g.skip?E+=o:(g.excludeBegin&&(E+=o),y(),!g.returnBegin&&!g.excludeBegin&&(E=o)),le(g,s),g.returnBegin?0:o.length}function ze(s){const o=s[0],g=a.substring(s.index),p=ue(f,s,g);if(!p)return Me;const R=f;f.endScope&&f.endScope._wrap?(y(),N(o,f.endScope._wrap)):f.endScope&&f.endScope._multi?(y(),ae(f.endScope,s)):R.skip?E+=o:(R.returnEnd||R.excludeEnd||(E+=o),y(),R.excludeEnd&&(E=o));do f.scope&&O.closeNode(),!f.skip&&!f.subLanguage&&(F+=f.relevance),f=f.parent;while(f!==p.parent);return p.starts&&le(p.starts,s),R.returnEnd?0:o.length}function Xe(){const s=[];for(let o=f;o!==A;o=o.parent)o.scope&&s.unshift(o.scope);s.forEach(o=>O.openNode(o))}let K={};function fe(s,o){const g=o&&o[0];if(E+=s,g==null)return y(),0;if(K.type==="begin"&&o.type==="end"&&K.index===o.index&&g===""){if(E+=a.slice(o.index,o.index+1),!b){const p=new Error(`0 width match regex (${n})`);throw p.languageName=n,p.badRule=K.rule,p}return 1}if(K=o,o.type==="begin")return Fe(o);if(o.type==="illegal"&&!h){const p=new Error('Illegal lexeme "'+g+'" for mode "'+(f.scope||"<unnamed>")+'"');throw p.mode=f,p}else if(o.type==="end"){const p=ze(o);if(p!==Me)return p}if(o.type==="illegal"&&g==="")return E+=`
3
+ `,1;if(Q>1e5&&Q>o.index*3)throw new Error("potential infinite loop, way more iterations than matches");return E+=g,g.length}const A=T(n);if(!A)throw v(_.replace("{}",n)),new Error('Unknown language: "'+n+'"');const Ye=Pt(A);let q="",f=d||Ye;const ge={},O=new r.__emitter(r);Xe();let E="",F=0,D=0,Q=0,m=!1;try{if(A.__emitTokens)A.__emitTokens(a,O);else{for(f.matcher.considerAll();;){Q++,m?m=!1:f.matcher.considerAll(),f.matcher.lastIndex=D;const s=f.matcher.exec(a);if(!s)break;const o=a.substring(D,s.index),g=fe(o,s);D=s.index+g}fe(a.substring(D))}return O.finalize(),q=O.toHTML(),{language:n,value:q,relevance:F,illegal:!1,_emitter:O,_top:f}}catch(s){if(s.message&&s.message.includes("Illegal"))return{language:n,value:ee(a),illegal:!0,relevance:0,_illegalBy:{message:s.message,index:D,context:a.slice(D-100,D+100),mode:s.mode,resultSoFar:q},_emitter:O};if(b)return{language:n,value:ee(a),illegal:!1,relevance:0,errorRaised:s,_emitter:O,_top:f};throw s}}function Z(n){const a={value:ee(n),illegal:!1,relevance:0,_top:c,_emitter:new r.__emitter(r)};return a._emitter.addText(n),a}function J(n,a){a=a||r.languages||Object.keys(t);const h=Z(n),d=a.filter(T).filter(oe).map(y=>j(y,n,!1));d.unshift(h);const x=d.sort((y,N)=>{if(y.relevance!==N.relevance)return N.relevance-y.relevance;if(y.language&&N.language){if(T(y.language).supersetOf===N.language)return 1;if(T(N.language).supersetOf===y.language)return-1}return 0}),[S,I]=x,W=S;return W.secondBest=I,W}function De(n,a,h){const d=a&&i[a]||h;n.classList.add("hljs"),n.classList.add(`language-${d}`)}function V(n){let a=null;const h=w(n);if(l(h))return;if(G("before:highlightElement",{el:n,language:h}),n.dataset.highlighted){console.log("Element previously highlighted. To highlight again, first unset `dataset.highlighted`.",n);return}if(n.children.length>0&&(r.ignoreUnescapedHTML||(console.warn("One of your code blocks includes unescaped HTML. This is a potentially serious security risk."),console.warn("https://github.com/highlightjs/highlight.js/wiki/security"),console.warn("The element with unescaped HTML:"),console.warn(n)),r.throwUnescapedHTML))throw new Gt("One of your code blocks includes unescaped HTML.",n.innerHTML);a=n;const d=a.textContent,x=h?M(d,{language:h,ignoreIllegals:!0}):J(d);n.innerHTML=x.value,n.dataset.highlighted="yes",De(n,h,x.language),n.result={language:x.language,re:x.relevance,relevance:x.relevance},x.secondBest&&(n.secondBest={language:x.secondBest.language,relevance:x.secondBest.relevance}),G("after:highlightElement",{el:n,result:x,text:d})}function ve(n){r=_e(r,n)}const Ce=()=>{$(),L("10.6.0","initHighlighting() deprecated. Use highlightAll() now.")};function Le(){$(),L("10.6.0","initHighlightingOnLoad() deprecated. Use highlightAll() now.")}let re=!1;function $(){function n(){$()}if(document.readyState==="loading"){re||window.addEventListener("DOMContentLoaded",n,!1),re=!0;return}document.querySelectorAll(r.cssSelector).forEach(V)}function He(n,a){let h=null;try{h=a(e)}catch(d){if(v("Language definition for '{}' could not be registered.".replace("{}",n)),b)v(d);else throw d;h=c}h.name||(h.name=n),t[n]=h,h.rawDefinition=a.bind(null,e),h.aliases&&ce(h.aliases,{languageName:n})}function je(n){delete t[n];for(const a of Object.keys(i))i[a]===n&&delete i[a]}function Pe(){return Object.keys(t)}function T(n){return n=(n||"").toLowerCase(),t[n]||t[i[n]]}function ce(n,{languageName:a}){typeof n=="string"&&(n=[n]),n.forEach(h=>{i[h.toLowerCase()]=a})}function oe(n){const a=T(n);return a&&!a.disableAutodetect}function Ue(n){n["before:highlightBlock"]&&!n["before:highlightElement"]&&(n["before:highlightElement"]=a=>{n["before:highlightBlock"](Object.assign({block:a.el},a))}),n["after:highlightBlock"]&&!n["after:highlightElement"]&&(n["after:highlightElement"]=a=>{n["after:highlightBlock"](Object.assign({block:a.el},a))})}function $e(n){Ue(n),u.push(n)}function Ge(n){const a=u.indexOf(n);a!==-1&&u.splice(a,1)}function G(n,a){const h=n;u.forEach(function(d){d[h]&&d[h](a)})}function We(n){return L("10.7.0","highlightBlock will be removed entirely in v12.0"),L("10.7.0","Please use highlightElement now."),V(n)}Object.assign(e,{highlight:M,highlightAuto:J,highlightAll:$,highlightElement:V,highlightBlock:We,configure:ve,initHighlighting:Ce,initHighlightingOnLoad:Le,registerLanguage:He,unregisterLanguage:je,listLanguages:Pe,getLanguage:T,registerAliases:ce,autoDetection:oe,inherit:_e,addPlugin:$e,removePlugin:Ge}),e.debugMode=function(){b=!1},e.safeMode=function(){b=!0},e.versionString=$t,e.regex={concat:C,lookahead:Oe,either:ne,optional:nt,anyNumberOfTimes:tt};for(const n in z)typeof z[n]=="object"&&xe(z[n]);return Object.assign(e,z),e},H=Be({});H.newInstance=()=>Be({});var Kt=H;H.HighlightJS=H;H.default=H;const zt=Ve(Kt);export{zt as H};