var be=window.location.origin;async function h(e,t){let n=await fetch(`${be}${e}`,{...t,headers:{"Content-Type":"application/json",...t?.headers}});if(!n.ok){let r=await n.text();throw new Error(`API ${n.status}: ${r}`)}return n.json()}async function ee(){return h("/api/me")}async function M(){return h("/api/config")}async function v(e){let t=e?.length?`?authors=${encodeURIComponent(e.join(","))}`:"";return h(`/api/prs${t}`)}async function te(e,t,n){return h(`/api/prs/${encodeURIComponent(e)}/${encodeURIComponent(t)}/${n}`)}async function se(){await h("/api/sync",{method:"POST"})}async function K(e){return h("/api/prs/merge",{method:"POST",body:JSON.stringify({targets:e})})}async function X(e){return h("/api/prs/close",{method:"POST",body:JSON.stringify({targets:e})})}async function Z(e){return h("/api/prs/approve",{method:"POST",body:JSON.stringify({targets:e})})}async function ne(e){let t=e?.length?`?authors=${encodeURIComponent(e.join(","))}`:"";return h(`/api/issues${t}`)}async function ae(e,t,n){return h(`/api/issues/${encodeURIComponent(e)}/${encodeURIComponent(t)}/${n}`)}function o(e){let t=document.createElement("span");return t.textContent=e,t.innerHTML}function f(e){let t=new Date(e),r=Math.floor((new Date().getTime()-t.getTime())/1e3);if(r<60)return"just now";let s=Math.floor(r/60);if(s<60)return`${s}m ago`;let a=Math.floor(s/60);if(a<24)return`${a}h ago`;let i=Math.floor(a/24);return i<30?`${i}d ago`:`${Math.floor(i/30)}mo ago`}function x(e){if(!e)return"";let t=e.toUpperCase();return t==="SUCCESS"?'<span class="badge badge-success">&#x2713; CI passed</span>':t==="FAILURE"||t==="ERROR"?'<span class="badge badge-failure">&#x2717; CI failed</span>':t==="PENDING"||t==="EXPECTED"?'<span class="badge badge-pending">&#x25cf; CI pending</span>':`<span class="badge badge-pending">${o(e)}</span>`}function A(e){if(!e)return"";let t=e.toUpperCase();return t==="MERGEABLE"?'<span class="badge badge-mergeable">&#x2713; No conflicts</span>':t==="CONFLICTING"?'<span class="badge badge-conflict">&#x2717; Conflicts</span>':t==="UNKNOWN"?'<span class="badge badge-pending">? Merge status unknown</span>':""}function B(e){if(!e)return"";let t=e.toUpperCase();return t==="APPROVED"?'<span class="badge badge-success">&#x2713; Approved</span>':t==="CHANGES_REQUESTED"?'<span class="badge badge-failure">&#x270e; Changes requested</span>':t==="REVIEW_REQUIRED"?'<span class="badge badge-review">&#x25cb; Review required</span>':""}function $(e){let t=`#${e.color}`,n=parseInt(e.color.substring(0,2),16),r=parseInt(e.color.substring(2,4),16),s=parseInt(e.color.substring(4,6),16),i=(.299*n+.587*r+.114*s)/255>.5?"#000":"#fff";return`<span class="label-tag" style="background:${t};color:${i}">${o(e.name)}</span>`}var re=[];function R(e,t){re.push({pattern:e,handler:t})}function b(e){window.location.hash=e}async function H(){let e=window.location.hash.replace(/^#/,"")||"/",t=document.getElementById("view-container");if(t){for(let n of re){let r=e.match(n.pattern);if(r){await n.handler(t,...r.slice(1));return}}b("/")}}async function oe(e,t,n,r){e.innerHTML='<div class="loading">Loading issue&hellip;</div>';let s;try{s=await ae(t,n,r)}catch(l){e.innerHTML=`<div class="empty-state"><h3>Failed to load issue</h3><p>${o(String(l))}</p></div>`;return}let a=(s.labels||[]).map($).join(" "),i=(s.assignees||[]).map(l=>o(l)).join(", ")||"Unassigned";e.innerHTML=`
    <button class="pr-detail-back" id="back-btn">&larr; All Issues</button>

    <div class="pr-detail-header">
      <div class="pr-detail-title">${o(s.title)}</div>
      <div class="pr-detail-subtitle">
        ${o(t)}/${o(n)}#${r}
        &middot; <span class="pr-author">
          ${s.author_avatar?`<img src="${o(s.author_avatar)}&s=32" alt="" />`:""}
          ${o(s.author)}
        </span>
        &middot; updated ${f(s.updated_at)}
        &middot; <a class="external-link" href="${o(s.url)}" target="_blank" rel="noopener">View on GitHub &nearr;</a>
      </div>
      <div class="pr-detail-badges">
        ${a}
      </div>
      <div class="pr-stats" style="margin-top:8px">
        <span>Assignees: ${i}</span>
        &middot;
        <span>&#x1F4AC; ${s.comment_count} comment${s.comment_count!==1?"s":""}</span>
      </div>
    </div>

    ${s.body?`<div class="section"><h3>Description</h3><div class="issue-body">${o(s.body)}</div></div>`:""}
  `,document.getElementById("back-btn")?.addEventListener("click",()=>b("/issues"))}var E=[],U="",w=new Set,L="none",N="updated",I=!1,y=null;async function le(e){e.innerHTML='<div class="loading">Loading issues&hellip;</div>';try{E=await ne()}catch(t){e.innerHTML=`<div class="empty-state"><h3>Failed to load issues</h3><p>${o(String(t))}</p></div>`;return}_(e)}function _(e){let t=e||document.getElementById("view-container");if(!t)return;let n=ve(),r=E.length,s=new Set(E.map(d=>`${d.repo_owner}/${d.repo_name}`)).size,a=E.filter(d=>d.comment_count>0).length,i=E.filter(d=>!d.assignees||d.assignees.length===0).length,l=new Set;E.forEach(d=>(d.labels||[]).forEach(J=>l.add(J.name)));let p=[...l].sort(),c=p.length?`<div class="multi-select" id="label-select">
        <button class="multi-select-btn" id="label-select-btn">Labels${w.size?` <span class="ms-count">(${w.size})</span>`:""} <span class="ms-caret">&#x25BE;</span></button>
        <div class="multi-select-dropdown hidden" id="label-dropdown">
          ${p.map(d=>`<label class="ms-option"><input type="checkbox" value="${o(d)}" ${w.has(d)?"checked":""} /> ${o(d)}</label>`).join("")}
        </div>
      </div>`:"";t.innerHTML=`
    <div class="dashboard-stats">
      <div class="stat-card stat-total${y===null?" active":""}" data-filter="">
        <div class="stat-value">${r}</div>
        <div class="stat-label">Open</div>
      </div>
      <div class="stat-card stat-repos${y==="repos"?" active":""}" data-filter="repos">
        <div class="stat-value">${s}</div>
        <div class="stat-label">Repos</div>
      </div>
      <div class="stat-card stat-comments${y==="comments"?" active":""}" data-filter="comments">
        <div class="stat-value">${a}</div>
        <div class="stat-label">With Comments</div>
      </div>
      <div class="stat-card stat-unassigned${y==="unassigned"?" active":""}" data-filter="unassigned">
        <div class="stat-value">${i}</div>
        <div class="stat-label">Unassigned</div>
      </div>
    </div>

    <div class="filter-bar">
      <input id="filter-input" type="text" placeholder="Filter issues&hellip;" value="${o(U)}" />
      <select id="group-select">
        <option value="none"${L==="none"?" selected":""}>No grouping</option>
        <option value="repo"${L==="repo"?" selected":""}>Group by repo</option>
        <option value="author"${L==="author"?" selected":""}>Group by author</option>
      </select>
      ${c}
    </div>

    <div id="issue-list-container">
      ${n.length?$e(n):'<div class="empty-state"><h3>No issues found</h3></div>'}
    </div>
  `,ye(t)}function ve(){let e=[...E];if(y==="comments"?e=e.filter(t=>t.comment_count>0):y==="unassigned"&&(e=e.filter(t=>!t.assignees||t.assignees.length===0)),U){let t=U.toLowerCase();e=e.filter(n=>n.title.toLowerCase().includes(t)||n.author.toLowerCase().includes(t)||`${n.repo_owner}/${n.repo_name}`.toLowerCase().includes(t)||`#${n.number}`.includes(t))}return w.size>0&&(e=e.filter(t=>{let n=(t.labels||[]).map(r=>r.name);return[...w].every(r=>n.includes(r))})),e.sort((t,n)=>{let r=0;switch(N){case"number":r=t.number-n.number;break;case"author":r=t.author.localeCompare(n.author);break;case"created":r=t.created_at.localeCompare(n.created_at);break;case"updated":r=t.updated_at.localeCompare(n.updated_at);break}return I?r:-r}),e}function $e(e){if(L==="none")return ie(e,null);let t=new Map;for(let n of e){let r=L==="repo"?`${n.repo_owner}/${n.repo_name}`:n.author;t.has(r)||t.set(r,[]),t.get(r).push(n)}return[...t.entries()].map(([n,r])=>ie(r,n)).join("")}function q(e){return N!==e?"":I?" &#x25B4;":" &#x25BE;"}function ie(e,t){let n=t?`<div class="group-header">
        <span class="group-name">${o(t)}</span>
        <span class="group-count">${e.length}</span>
       </div>`:"",r=e.map(s=>{let a=(s.labels||[]).map($).join(" "),i=(s.assignees||[]).map(l=>o(l)).join(", ");return`<tr class="issue-row">
      <td class="td-title">
        <span class="issue-row-link" data-owner="${o(s.repo_owner)}" data-repo="${o(s.repo_name)}" data-number="${s.number}">
          ${o(s.title)}
        </span>
        <span class="issue-row-ref">${L!=="repo"?o(`${s.repo_owner}/${s.repo_name}`)+" ":""}#${s.number}</span>
        ${a?`<span class="issue-row-labels">${a}</span>`:""}
      </td>
      <td class="td-author">
        ${s.author_avatar?`<img class="avatar-sm" src="${o(s.author_avatar)}&s=32" alt="" />`:""}
        ${o(s.author)}
      </td>
      <td class="td-assignees">${i||'<span class="text-muted">\u2014</span>'}</td>
      <td class="td-comments">${s.comment_count>0?`&#x1F4AC; ${s.comment_count}`:""}</td>
      <td class="td-time" title="${o(s.created_at)}">${f(s.created_at)}</td>
      <td class="td-time" title="${o(s.updated_at)}">${f(s.updated_at)}</td>
      <td class="td-actions"><a class="external-link" href="${o(s.url)}" target="_blank" rel="noopener">&#x2197;</a></td>
    </tr>`}).join("");return`
    ${n}
    <table class="issue-table">
      <thead>
        <tr>
          <th class="th-title sortable-th" data-sort="number">Issue${q("number")}</th>
          <th class="th-author sortable-th" data-sort="author">Author${q("author")}</th>
          <th class="th-assignees">Assignees</th>
          <th class="th-comments">Comments</th>
          <th class="th-time sortable-th" data-sort="created">Created${q("created")}</th>
          <th class="th-time sortable-th" data-sort="updated">Updated${q("updated")}</th>
          <th class="th-actions"></th>
        </tr>
      </thead>
      <tbody>${r}</tbody>
    </table>
  `}function ye(e){let t=e.querySelector("#filter-input");t&&t.addEventListener("input",()=>{U=t.value,_()});let n=e.querySelector("#group-select");n&&n.addEventListener("change",()=>{L=n.value,_()}),e.querySelectorAll(".stat-card").forEach(a=>{a.addEventListener("click",()=>{let i=a.dataset.filter??null;y=y===i?null:i||null,_()})}),e.querySelectorAll(".sortable-th").forEach(a=>{a.addEventListener("click",()=>{let i=a.dataset.sort;N===i?I=!I:(N=i,I=!1),_()})});let r=e.querySelector("#label-select-btn"),s=e.querySelector("#label-dropdown");r&&s&&(r.addEventListener("click",a=>{a.stopPropagation(),s.classList.toggle("hidden")}),s.querySelectorAll("input[type=checkbox]").forEach(a=>{a.addEventListener("change",()=>{a.checked?w.add(a.value):w.delete(a.value),_()})}),document.addEventListener("click",()=>s.classList.add("hidden"))),e.querySelectorAll(".issue-row-link").forEach(a=>{a.addEventListener("click",()=>{let{owner:i,repo:l,number:p}=a.dataset;b(`/issue/${i}/${l}/${p}`)})})}var m=[],Ee=null,P="",O=new Set,j=new Set,G=new Set,F=new Set,z=new Set,g=new Set,W="repo",V="number",T=!1,C=null;function ue(e){return`${e.repo_owner}/${e.repo_name}#${e.number}`}function k(e,t,n,r,s){return`<div class="multi-select" id="${e}-ms"><button class="multi-select-btn" id="${e}-btn">${t}<span class="ms-count" id="${e}-count"></span> <span class="ms-caret">&#x25BE;</span></button><div class="multi-select-dropdown hidden" id="${e}-dropdown"></div></div>`}function S(e,t,n,r,s){let a=document.getElementById(`${e}-btn`),i=document.getElementById(`${e}-dropdown`),l=document.getElementById(`${e}-count`);i.innerHTML=t.map(c=>{let d=n.has(c)?"checked":"";return`<label class="ms-option"><input type="checkbox" value="${o(c)}" ${d} /> ${o(r(c))}</label>`}).join("");let p=()=>{l.textContent=n.size>0?` (${n.size})`:""};p(),a.addEventListener("click",c=>{c.stopPropagation(),document.querySelectorAll(".multi-select-dropdown").forEach(d=>{d!==i&&d.classList.add("hidden")}),i.classList.toggle("hidden")}),i.querySelectorAll("input[type=checkbox]").forEach(c=>{c.addEventListener("change",()=>{c.checked?n.add(c.value):n.delete(c.value),p(),s()})})}document.addEventListener("click",()=>{document.querySelectorAll(".multi-select-dropdown").forEach(e=>e.classList.add("hidden"))});async function pe(e){e.innerHTML=`
    <div id="dashboard-stats" class="dashboard-stats"></div>
    <div class="filter-bar">
      <input id="filter-search" type="text" placeholder="Search PRs..." />
      <div id="ms-author-placeholder"></div>
      <div id="ms-repo-placeholder"></div>
      <div id="ms-ci-placeholder"></div>
      <div id="ms-label-placeholder"></div>
      <div id="ms-review-placeholder"></div>
      <select id="group-by">
        <option value="repo">Group by repo</option>
        <option value="author">Group by author</option>
        <option value="none">No grouping</option>
      </select>
    </div>
    <div id="batch-bar" class="batch-bar hidden">
      <span id="batch-count">0 selected</span>
      <button id="batch-merge" class="batch-btn batch-btn-merge" disabled>Merge selected</button>
      <button id="batch-approve" class="batch-btn batch-btn-approve">Approve selected</button>
      <button id="batch-close" class="batch-btn batch-btn-close">Close selected</button>
      <button id="batch-clear" class="batch-btn batch-btn-clear">Clear selection</button>
    </div>
    <div id="pr-table-container"></div>
  `;try{Ee=await M(),m=await v()}catch(c){e.innerHTML=`<div class="empty-state"><h3>Failed to load</h3><p>${o(String(c))}</p></div>`;return}if(m.length===0){e.innerHTML='<div class="empty-state"><h3>No open PRs</h3><p>Waiting for background sync to complete. Try clicking the sync button.</p></div>';return}let t=[...new Set(m.map(c=>c.author))].sort(),n=[...new Set(m.map(c=>`${c.repo_owner}/${c.repo_name}`))].sort(),r=["SUCCESS","FAILURE","PENDING","NONE"],s={SUCCESS:"CI passing",FAILURE:"CI failing",PENDING:"CI pending",NONE:"No CI"},a=[...new Set(m.flatMap(c=>(c.labels||[]).map(d=>d.name)))].sort(),i=["APPROVED","CHANGES_REQUESTED","REVIEW_REQUIRED","NONE"],l={APPROVED:"Approved",CHANGES_REQUESTED:"Changes requested",REVIEW_REQUIRED:"Review required",NONE:"No review"};document.getElementById("ms-author-placeholder").outerHTML=k("ms-author","Authors",t,O,u),document.getElementById("ms-repo-placeholder").outerHTML=k("ms-repo","Repos",n,j,u),document.getElementById("ms-ci-placeholder").outerHTML=k("ms-ci","CI Status",r,G,u),document.getElementById("ms-label-placeholder").outerHTML=k("ms-label","Labels",a,F,u),document.getElementById("ms-review-placeholder").outerHTML=k("ms-review","Review",i,z,u),S("ms-author",t,O,c=>c,u),S("ms-repo",n,j,c=>c,u),S("ms-ci",r,G,c=>s[c]||c,u),S("ms-label",a,F,c=>c,u),S("ms-review",i,z,c=>l[c]||c,u);let p=document.getElementById("filter-search");p.addEventListener("input",()=>{P=p.value.toLowerCase(),u()}),document.getElementById("group-by").addEventListener("change",c=>{W=c.target.value,u()}),document.getElementById("batch-merge").addEventListener("click",Ce),document.getElementById("batch-approve").addEventListener("click",Re),document.getElementById("batch-close").addEventListener("click",Ie),document.getElementById("batch-clear").addEventListener("click",()=>{g.clear(),u()}),g.clear(),u()}function me(e,t){switch(t){case"total":return!0;case"ready":return e.ci_status?.toUpperCase()==="SUCCESS"&&e.mergeable?.toUpperCase()==="MERGEABLE"&&!e.draft;case"pass":return e.ci_status?.toUpperCase()==="SUCCESS";case"fail":return e.ci_status?.toUpperCase()==="FAILURE"||e.ci_status?.toUpperCase()==="ERROR";case"pending":return e.ci_status?.toUpperCase()==="PENDING"||e.ci_status?.toUpperCase()==="EXPECTED";case"mergeable":return e.mergeable?.toUpperCase()==="MERGEABLE";case"conflicts":return e.mergeable?.toUpperCase()==="CONFLICTING";case"approved":return e.review_decision?.toUpperCase()==="APPROVED";case"drafts":return!!e.draft;default:return!0}}function we(){let e=m;return C&&C!=="total"&&(e=e.filter(t=>me(t,C))),P&&(e=e.filter(t=>t.title.toLowerCase().includes(P)||`${t.repo_owner}/${t.repo_name}`.toLowerCase().includes(P)||t.author.toLowerCase().includes(P))),O.size>0&&(e=e.filter(t=>O.has(t.author))),j.size>0&&(e=e.filter(t=>j.has(`${t.repo_owner}/${t.repo_name}`))),G.size>0&&(e=e.filter(t=>{let n=t.ci_status?.toUpperCase()||"NONE";for(let r of G)if(r==="NONE"&&!t.ci_status||n===r)return!0;return!1})),F.size>0&&(e=e.filter(t=>(t.labels||[]).some(n=>F.has(n.name)))),z.size>0&&(e=e.filter(t=>{let n=t.review_decision?.toUpperCase()||"NONE";for(let r of z)if(r==="NONE"&&!t.review_decision||n===r)return!0;return!1})),e}function ce(e){let t=(r,s)=>{switch(V){case"number":return r.number-s.number;case"author":return r.author.localeCompare(s.author);case"created":return new Date(r.created_at).getTime()-new Date(s.created_at).getTime();case"updated":return new Date(r.updated_at).getTime()-new Date(s.updated_at).getTime();default:return 0}},n=[...e].sort(t);return T?n:n.reverse()}function Le(){let e=document.getElementById("dashboard-stats");if(!e)return;let t=[{key:"total",cls:"stat-total",label:"Open PRs"},{key:"ready",cls:"stat-ready",label:"Ready to merge"},{key:"pass",cls:"stat-pass",label:"CI passing"},{key:"fail",cls:"stat-fail",label:"CI failing"},{key:"pending",cls:"stat-pending-stat",label:"CI pending"},{key:"mergeable",cls:"stat-mergeable",label:"No conflicts"},{key:"conflicts",cls:"stat-conflicts",label:"Conflicts"},{key:"approved",cls:"stat-approved",label:"Approved"},{key:"drafts",cls:"stat-drafts",label:"Drafts"}];e.innerHTML=t.map(n=>{let r=m.filter(a=>me(a,n.key)).length,s=C===n.key?" active":"";return`<div class="stat-card ${n.cls}${s}" data-stat="${n.key}"><div class="stat-value">${r}</div><div class="stat-label">${n.label}</div></div>`}).join(""),e.querySelectorAll(".stat-card").forEach(n=>{n.addEventListener("click",()=>{let r=n.dataset.stat;C=C===r?null:r,u()})})}function u(){let e=we();Le(),Y();let t=document.getElementById("pr-table-container");if(t){if(e.length===0){t.innerHTML='<div class="empty-state"><p>No PRs match the current filters.</p></div>';return}if(W==="none")t.innerHTML=de(ce(e),null);else{let n=new Map;for(let s of e){let a=W==="repo"?`${s.repo_owner}/${s.repo_name}`:s.author;n.has(a)||n.set(a,[]),n.get(a).push(s)}let r=[...n.entries()].sort((s,a)=>a[1].length-s[1].length);t.innerHTML=r.map(([s,a])=>de(ce(a),s)).join("")}t.querySelectorAll(".pr-checkbox").forEach(n=>{n.checked=g.has(n.value),n.addEventListener("change",()=>{n.checked?g.add(n.value):g.delete(n.value),Y(),_e(t)})}),t.querySelectorAll(".group-select-all").forEach(n=>{n.addEventListener("change",()=>{let r=n.getAttribute("data-group");t.querySelectorAll(`.pr-checkbox[data-group="${r}"]`).forEach(a=>{a.checked=n.checked,n.checked?g.add(a.value):g.delete(a.value)}),Y()})}),t.querySelectorAll(".pr-row-link").forEach(n=>{n.addEventListener("click",()=>{b(`/pr/${n.dataset.owner}/${n.dataset.repo}/${n.dataset.number}`)})}),t.querySelectorAll(".sortable-th").forEach(n=>{n.addEventListener("click",()=>{let r=n.dataset.sort;V===r?T=!T:(V=r,T=r==="author"),u()})}),t.querySelectorAll(".inline-merge").forEach(n=>{n.addEventListener("click",async r=>{r.stopPropagation();let{owner:s,repo:a,number:i}=n.dataset;n.classList.add("working");try{let l=await K([{owner:s,repo:a,number:parseInt(i)}]);l[0]&&!l[0].success&&alert(`Merge failed: ${l[0].error}`),m=await v(),u()}catch(l){alert(`Merge failed: ${l}`)}})}),t.querySelectorAll(".inline-approve").forEach(n=>{n.addEventListener("click",async r=>{r.stopPropagation();let{owner:s,repo:a,number:i}=n.dataset;n.classList.add("working");try{let l=await Z([{owner:s,repo:a,number:parseInt(i)}]);l[0]&&!l[0].success&&alert(`Approve failed: ${l[0].error}`),m=await v(),u()}catch(l){alert(`Approve failed: ${l}`)}})}),t.querySelectorAll(".inline-close").forEach(n=>{n.addEventListener("click",async r=>{r.stopPropagation();let{owner:s,repo:a,number:i}=n.dataset;n.classList.add("working");try{let l=await X([{owner:s,repo:a,number:parseInt(i)}]);l[0]&&!l[0].success&&alert(`Close failed: ${l[0].error}`),m=await v(),u()}catch(l){alert(`Close failed: ${l}`)}})})}}function D(e){return V!==e?"":T?" &#x25B4;":" &#x25BE;"}function de(e,t){let n=t?t.replace(/[^a-zA-Z0-9]/g,"_"):"all",r=t?`<div class="group-header">
        <label class="group-select-label"><input type="checkbox" class="group-select-all" data-group="${o(n)}" /> </label>
        <span class="group-name">${o(t)}</span>
        <span class="group-count">${e.length}</span>
       </div>`:"",s=e.map(a=>{let i=ue(a),l=g.has(i)?"checked":"",p=[];a.draft&&p.push('<span class="badge badge-draft">Draft</span>'),p.push(x(a.ci_status)),p.push(A(a.mergeable)),p.push(B(a.review_decision));let c=(a.labels||[]).map($).join(" "),d=a.ci_status?.toUpperCase()==="SUCCESS"&&a.mergeable?.toUpperCase()==="MERGEABLE"&&!a.draft,J=`<span class="inline-actions">${d?`<button class="inline-btn inline-merge" data-owner="${o(a.repo_owner)}" data-repo="${o(a.repo_name)}" data-number="${a.number}" title="Merge">&#x2714;</button>`:""}<button class="inline-btn inline-approve" data-owner="${o(a.repo_owner)}" data-repo="${o(a.repo_name)}" data-number="${a.number}" title="Approve">&#x1F44D;</button><button class="inline-btn inline-close" data-owner="${o(a.repo_owner)}" data-repo="${o(a.repo_name)}" data-number="${a.number}" title="Close">&#x2716;</button></span>`;return`<tr class="pr-row ${d?"pr-row-ready":""}">
      <td class="td-check"><input type="checkbox" class="pr-checkbox" value="${o(i)}" data-group="${o(n)}" data-owner="${o(a.repo_owner)}" data-repo="${o(a.repo_name)}" data-number="${a.number}" ${l} /></td>
      <td class="td-status">${p.filter(Boolean).join(" ")}</td>
      <td class="td-title">
        <span class="pr-row-link" data-owner="${o(a.repo_owner)}" data-repo="${o(a.repo_name)}" data-number="${a.number}">
          ${o(a.title)}
        </span>
        <span class="pr-row-ref">${W!=="repo"?o(`${a.repo_owner}/${a.repo_name}`)+" ":""}#${a.number} ${o(a.head_ref||"")} &rarr; ${o(a.base_ref||"")}</span>
        ${c?`<span class="pr-row-labels">${c}</span>`:""}
      </td>
      <td class="td-author">
        ${a.author_avatar?`<img class="avatar-sm" src="${o(a.author_avatar)}&s=32" alt="" />`:""}
        ${o(a.author)}
      </td>
      <td class="td-stats"><span class="stat-add">+${a.additions}</span> <span class="stat-del">-${a.deletions}</span></td>
      <td class="td-time" title="${o(a.created_at)}">${f(a.created_at)}</td>
      <td class="td-time" title="${o(a.updated_at)}">${f(a.updated_at)}</td>
      <td class="td-actions">${J}</td>
    </tr>`}).join("");return`
    ${r}
    <table class="pr-table">
      <thead>
        <tr>
          <th class="th-check"></th>
          <th class="th-status">Status</th>
          <th class="th-title sortable-th" data-sort="number">PR${D("number")}</th>
          <th class="th-author sortable-th" data-sort="author">Author${D("author")}</th>
          <th class="th-stats">Changes</th>
          <th class="th-time sortable-th" data-sort="created">Created${D("created")}</th>
          <th class="th-time sortable-th" data-sort="updated">Updated${D("updated")}</th>
          <th class="th-actions">Actions</th>
        </tr>
      </thead>
      <tbody>${s}</tbody>
    </table>
  `}function Y(){let e=document.getElementById("batch-bar"),t=document.getElementById("batch-count");if(!(!e||!t))if(g.size>0){e.classList.remove("hidden"),t.textContent=`${g.size} selected`;let n=document.getElementById("batch-merge"),r=Q().every(s=>s.ci_status?.toUpperCase()==="SUCCESS"&&s.mergeable?.toUpperCase()==="MERGEABLE"&&!s.draft);n.disabled=!r,n.title=r?"Merge all selected PRs":"Some selected PRs have failing CI, conflicts, or are drafts"}else e.classList.add("hidden")}function _e(e){e.querySelectorAll(".group-select-all").forEach(t=>{let n=t.getAttribute("data-group"),r=e.querySelectorAll(`.pr-checkbox[data-group="${n}"]`),s=r.length>0&&[...r].every(a=>a.checked);t.checked=s,t.indeterminate=!s&&[...r].some(a=>a.checked)})}function Q(){return m.filter(e=>g.has(ue(e)))}async function Ce(){let e=Q();if(e.filter(s=>s.ci_status?.toUpperCase()!=="SUCCESS"||s.mergeable?.toUpperCase()!=="MERGEABLE"||s.draft).length>0)return;let n=e.map(s=>({owner:s.repo_owner,repo:s.repo_name,number:s.number})),r=document.getElementById("batch-bar");r.classList.add("batch-working");try{let s=await K(n),a=s.filter(i=>!i.success);a.length>0&&alert(`Merged ${s.length-a.length} PRs. ${a.length} failed:
${a.map(i=>i.error||"Unknown error").join(`
`)}`),g.clear(),m=await v(),u()}catch(s){alert(`Batch merge failed: ${s}`)}finally{r.classList.remove("batch-working")}}async function Re(){let t=Q().map(r=>({owner:r.repo_owner,repo:r.repo_name,number:r.number})),n=document.getElementById("batch-bar");n.classList.add("batch-working");try{let r=await Z(t),s=r.filter(a=>!a.success);s.length>0&&alert(`Approved ${r.length-s.length} PRs. ${s.length} failed:
${s.map(a=>a.error||"Unknown error").join(`
`)}`),g.clear(),m=await v(),u()}catch(r){alert(`Batch approve failed: ${r}`)}finally{n.classList.remove("batch-working")}}async function Ie(){let t=Q().map(r=>({owner:r.repo_owner,repo:r.repo_name,number:r.number})),n=document.getElementById("batch-bar");n.classList.add("batch-working");try{let r=await X(t),s=r.filter(a=>!a.success);s.length>0&&alert(`Closed ${r.length-s.length} PRs. ${s.length} failed:
${s.map(a=>a.error||"Unknown error").join(`
`)}`),g.clear(),m=await v(),u()}catch(r){alert(`Batch close failed: ${r}`)}finally{n.classList.remove("batch-working")}}async function ge(e,t,n,r){e.innerHTML='<div class="loading">Loading PR&hellip;</div>';let s;try{s=await te(t,n,r)}catch(l){e.innerHTML=`<div class="empty-state"><h3>Failed to load PR</h3><p>${o(String(l))}</p></div>`;return}let a=[];s.draft&&a.push('<span class="badge badge-draft">Draft</span>'),a.push(x(s.ci_status)),a.push(A(s.mergeable)),a.push(B(s.review_decision));let i=(s.labels||[]).map($).join(" ");e.innerHTML=`
    <button class="pr-detail-back" id="back-btn">&larr; All PRs</button>

    <div class="pr-detail-header">
      <div class="pr-detail-title">${o(s.title)}</div>
      <div class="pr-detail-subtitle">
        ${o(t)}/${o(n)}#${r}
        &middot; ${o(s.head_ref||"")} &rarr; ${o(s.base_ref||"")}
        &middot; <span class="pr-author">
          ${s.author_avatar?`<img src="${o(s.author_avatar)}&s=32" alt="" />`:""}
          ${o(s.author)}
        </span>
        &middot; updated ${f(s.updated_at)}
        &middot; <a class="external-link" href="${o(s.url)}" target="_blank" rel="noopener">View on GitHub &nearr;</a>
      </div>
      <div class="pr-detail-badges">
        ${a.filter(Boolean).join(" ")} ${i}
      </div>
      <div class="pr-stats" style="margin-top:8px">
        <span class="stat-add">+${s.additions}</span>
        <span class="stat-del">-${s.deletions}</span>
        <span class="stat-files">${s.changed_files} file${s.changed_files!==1?"s":""}</span>
      </div>
    </div>

    ${ke(s.checks)}
    ${Se(s.commits)}
    ${Pe(s.files)}
  `,document.getElementById("back-btn")?.addEventListener("click",()=>b("/")),e.querySelectorAll(".file-header").forEach(l=>{l.addEventListener("click",()=>{let p=l.nextElementSibling;p&&p.classList.toggle("open")})})}function ke(e){if(!e.length)return"";let t=e.filter(s=>s.conclusion==="success").length,n=e.filter(s=>s.conclusion==="failure"||s.conclusion==="action_required").length,r=e.filter(s=>!s.conclusion||s.conclusion==="neutral"||s.status==="in_progress"||s.status==="queued").length;return`
    <div class="section">
      <h3>Checks (${t} passed, ${n} failed, ${r} pending)</h3>
      <div class="check-list">
        ${e.map(s=>{let a="pending",i="&#x25cf;";return s.conclusion==="success"?(a="success",i="&#x2713;"):(s.conclusion==="failure"||s.conclusion==="action_required")&&(a="failure",i="&#x2717;"),`
            <div class="check-item">
              <span class="check-icon ${a}">${i}</span>
              <span class="check-name">${o(s.name)}</span>
              ${s.url?`<a class="external-link" href="${o(s.url)}" target="_blank" rel="noopener">&nearr;</a>`:""}
            </div>
          `}).join("")}
      </div>
    </div>
  `}function Se(e){return e.length?`
    <div class="section">
      <h3>Commits (${e.length})</h3>
      <div class="commit-list">
        ${e.map(t=>{let n=t.sha.substring(0,7),r=t.message.split(`
`)[0];return`
            <div class="commit-item">
              <span class="commit-sha">${t.url?`<a class="external-link" href="${o(t.url)}" target="_blank" rel="noopener">${n}</a>`:n}</span>
              <span class="commit-msg">${o(r)}</span>
              ${t.author?`<span class="commit-author">${o(t.author)}</span>`:""}
            </div>
          `}).join("")}
      </div>
    </div>
  `:""}function Pe(e){return e.length?`
    <div class="section">
      <h3>Files changed (${e.length})</h3>
      <div class="file-list">
        ${e.map(t=>{let n=t.status?`file-status-${t.status}`:"",r=t.patch?Te(t.patch):"<pre>(no diff available)</pre>";return`
            <div class="file-item">
              <div class="file-header">
                <span class="file-status ${n}">${o(t.status||"")}</span>
                <span class="file-name">${o(t.filename)}</span>
                <span class="file-stats">
                  <span class="stat-add">+${t.additions}</span>
                  <span class="stat-del">-${t.deletions}</span>
                </span>
              </div>
              <div class="file-patch">${r}</div>
            </div>
          `}).join("")}
      </div>
    </div>
  `:""}function Te(e){return`<pre>${e.split(`
`).map(r=>{let s=o(r);return r.startsWith("@@")?`<span class="diff-hunk">${s}</span>`:r.startsWith("+")?`<span class="diff-add">${s}</span>`:r.startsWith("-")?`<span class="diff-del">${s}</span>`:s}).join(`
`)}</pre>`}R(/^\/$/,async e=>{await pe(e)});R(/^\/pr\/([^/]+)\/([^/]+)\/(\d+)$/,async(e,t,n,r)=>{await ge(e,t,n,parseInt(r,10))});R(/^\/issues$/,async e=>{await le(e)});R(/^\/issue\/([^/]+)\/([^/]+)\/(\d+)$/,async(e,t,n,r)=>{await oe(e,t,n,parseInt(r,10))});function he(){let e=window.location.hash.replace(/^#/,"")||"/";document.querySelectorAll(".nav-link").forEach(t=>{let n=t.dataset.view,r=n==="pr-list"&&(e==="/"||e.startsWith("/pr/"))||n==="issue-list"&&(e==="/issues"||e.startsWith("/issue/"));t.classList.toggle("active",r)})}async function fe(){let e=document.getElementById("loading");try{let s=await ee(),a=document.getElementById("user-info");a&&(a.textContent=s.login)}catch{}let t=document.getElementById("sync-btn"),n=!1;async function r(){if(!n){n=!0,t?.classList.add("syncing");try{await se(),await H()}catch(s){console.error("Sync failed:",s)}finally{n=!1,t?.classList.remove("syncing")}}}t&&t.addEventListener("click",r);try{let a=(await M()).sync_interval_seconds;a&&a>0&&setInterval(r,a*1e3)}catch{}window.addEventListener("hashchange",()=>{he(),H()}),e&&e.classList.add("hidden"),he(),await H()}document.readyState==="loading"?document.addEventListener("DOMContentLoaded",fe):fe();
//# sourceMappingURL=index.js.map
