@preventive/triage 1.0.0-alpha.41 → 1.0.0-alpha.42

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.
package/out/view.js CHANGED
@@ -1,4 +1,4 @@
1
- import{a as xt,b as Le,c as zd,d as Tn}from"./chunk-XL35ZV6R.js";import{a as Hd}from"./chunk-KEX2ATEW.js";import{$ as Di,$a as et,$b as zc,$c as Xi,A as fl,Aa as Bi,Ab as Gt,Ac as ed,Ad as Fd,B as gl,Ba as Zl,Bb as $c,Bc as td,Bd as Dd,C as bl,Ca as ec,Cb as xc,Cc as id,D as vl,Da as tc,Db as Sc,Dc as kt,Dd as Zt,E as yl,Ea as an,Eb as Cc,Ec as rd,Ed as Od,F as _l,Fa as ic,Fb as Vi,Fc as nd,Fd as Qi,G as wl,Ga as Vt,Gb as Ki,Gc as sd,Gd as Bd,H as kl,Ha as ln,Hb as Ec,Hc as od,Hd as $t,I as $l,Ia as rc,Ib as Tc,Ic as ad,Id as Nd,J as xl,Ja as de,Jb as Rc,Jc as ld,Jd as fe,K as Fi,Ka as D,Kb as Lc,Kc as Xt,Kd as qd,L as me,La as yt,Lb as Mc,Lc as cd,Ld as St,M as Sl,Ma as Ni,Mb as Wt,Mc as dd,N as Cl,Na as cn,Nb as pn,Nc as ud,O as El,Oa as nc,Ob as Pc,Oc as Sn,P as Tl,Pa as sc,Pb as Ac,Pc as pd,Q as Rl,Qa as oc,Qb as Gi,Qc as hd,R as Je,Ra as ac,Rb as Wi,Rc as Oe,S as Ll,Sa as Kt,Sb as Ic,Sc as md,T as Ml,Ta as _t,Tb as Fc,U as bt,Ua as lc,Ub as hn,V as Pl,Va as wt,Vb as Dc,W as vt,Wa as zi,Wb as mn,X as Al,Xa as dn,Xb as fn,Y as Il,Ya as cc,Yb as Oc,Yc as fd,Z as Fl,Za as dc,Zb as Bc,Zc as Be,_ as Dl,_a as qi,_b as Nc,_c as tt,a as Ja,aa as Ol,ab as uc,ac as qc,ad as Cn,b as Xa,ba as Bl,bb as pc,bc as Yt,bd as it,c as Qa,ca as Nl,cb as hc,cc as gn,cd as gd,d as Za,da as qt,dc as Hc,dd as bd,e as el,ea as Ht,ec as Uc,ed as vd,f as on,fa as zl,fc as jc,fd as yd,g as Ai,ga as ql,gb as mc,gc as bn,gd as _d,h as l,ha as Hl,hb as fc,hc as vn,hd as wd,i as H,ia as Ul,ic as Vc,id as kd,j as nl,ja as Oi,jc as Kc,jd as $d,k as sl,ka as jl,kc as yn,kd as xd,l as ol,la as Vl,lc as _n,ld as Qt,m as al,ma as Xe,mc as Gc,md as En,n as he,na as Kl,nc as Wc,nd as Sd,o as Ii,oa as Gl,ob as un,oc as Yc,od as Cd,p as ll,pa as Qe,pb as Hi,pc as Jt,pd as $,qa as Wl,qb as gc,qc as Yi,ra as Yl,rb as xe,rc as Jc,sa as Ut,sb as bc,sc as Xc,sd as Ed,t as cl,ta as De,tb as Ui,tc as Qc,td as Td,u as dl,ua as Ze,ub as ji,uc as Ji,ud as Rd,v as ul,va as Jl,vb as vc,vc as wn,vd as Ld,w as pl,wa as Xl,wb as yc,wc as kn,wd as Md,x as ke,xa as $e,xb as _c,xc as $n,xd as Pd,y as hl,ya as jt,yb as wc,yc as Zc,yd as Ad,z as ml,za as Ql,zb as kc,zc as xn,zd as Id}from"./chunk-TY4RZD3Z.js";import{a as Ei}from"./chunk-2KBF5TZ7.js";import{b as Ta}from"./chunk-K3X5EJBQ.js";import{a as $a,b as R,c as xa,d as Ge,g as q,h as Y,i as Ca}from"./chunk-CVVJAXVY.js";import{B as gt,D as tl,K as il,O as rl,c as ja,d as we,e as Ye,f as Va,j as Pi,k as Ka,n as Ga,r as Wa,u as Ya}from"./chunk-VIHGO77Y.js";import{u as Ha,z as Ua}from"./chunk-RFZQQXSG.js";import{d as ca,p as ma,q as fa}from"./chunk-RSHMVYNS.js";import{A as _a,B as wa,D as Nt,E as tn,I as rn,M as ka,b as Xr,ba as Ci,c as Qr,d as j,ea as Ea,k as xi,l as ba,m as Zr,n as Ve,q as va,t as en,v as Si,w as ya,y as K,z as Re}from"./chunk-2AFQKRAM.js";import{f as ga}from"./chunk-UYAXVRVL.js";import"./chunk-NRPC74AM.js";import"./chunk-VQJCXGIY.js";import{f as X}from"./chunk-W4J3MGLB.js";import"./chunk-GJ4IUCNS.js";import"./chunk-PNHBZGDD.js";import{$ as E,A as Ri,C as G,D as ft,G as zt,H as We,J as Li,O as Fe,P as Aa,R as Ia,S as Fa,V as Da,W as Oa,Y as Ba,a as I,aa as oe,b as _e,c as mt,da as Na,e as Ra,ea as za,f as nn,fa as Mi,g as Ti,ga as qa,o as sn,p as La,r as Ma,z as Pa}from"./chunk-UXNUAIIC.js";import"./chunk-R5O6FAW4.js";import{b as Sa,d as ht}from"./chunk-CMQA4DM6.js";import{g as ha}from"./chunk-4F6JSF57.js";import"./chunk-V3ME6FI5.js";import{e as pt,h as Ke}from"./chunk-YVZH5SHP.js";import"./chunk-4XCDFGDP.js";import"./chunk-3BZ7JERB.js";import{a as le}from"./chunk-TZ5KB2Y5.js";import"./chunk-XYFXXB2G.js";import{a as J}from"./chunk-DIJJNTRH.js";import{a as ki,g as $i,h as ua,j as Yr,l as pa,n as Jr}from"./chunk-WZDTZE64.js";import{B as wi,I as oa,J as aa,L as la,a as yi,b as Qo,e as Zo,f as ea,g as ta,j as ia,k as ra,l as na,m as _i,p as sa,v as Bt}from"./chunk-GNXOKIGP.js";import"./chunk-C4Z6ZBXV.js";import{a as M,b as ut,c as a,d as ye,e as Go,g as m,i as Wo,j as U}from"./chunk-2XUEZHIP.js";import{b as da}from"./chunk-TUII34K2.js";import{c as Yo,e as Jo,f as Xo,k as gi,p as bi,t as vi}from"./chunk-V5O7M2YT.js";import"./chunk-OOJM4CTU.js";var Ud={attach:{title:"Synced triage on report attach",intro:"have triage from your workspace that disagrees with your local view on",trailingNote:"Other findings in this report whose chain value didn't conflict were applied automatically; this list only covers disagreements. Pick which side to keep.",importedSideLabel:"Apply from chain",applyButton:"Apply"},chain:{title:"Triage conflict from peer update",intro:"were changed by a peer (or by another tab) in a way that disagrees with your local triage on",trailingNote:`Other findings whose remote value didn't conflict were applied automatically; this list only covers disagreements. Pick which side to keep for each \u2014 a "keep current" pick re-publishes your local value to the chain on your next save.`,importedSideLabel:"Apply from chain",applyButton:"Apply"}};function jd(){xl(async(i,e,t)=>{let r=cl(i);try{return await Al(i,r,Ud[t]??Ud.attach)}catch{let n=i.length;return alert(`${t==="attach"?"A report attach":"A workspace sync"} had ${n} triage disagreement${n===1?"":"s"} with your local view. Kept your local values because another dialog is open. ${t==="attach"?"Detach and re-attach the report to pick again.":"Your local values will re-publish to the chain on the next change."}`),null}})}var Rn=class extends q{static properties={retry:{type:Boolean},_value:{state:!0}};constructor(){super(),this.retry=!1,this._value=""}_finish(e){this._value="",super._finish(e)}_onCancel=()=>this._finish(null);_onInput=e=>{this._value=e.target.value};_onSubmit=()=>{let e=this._value??"";e&&this._finish(e)};_onKeydown=e=>{e.key==="Enter"&&(e.preventDefault(),this._onSubmit())};render(){let e=(this._value??"").length>0,t=this.retry?"That password didn't match. Try again, or cancel to leave the workspace unsynced for now.":"This sync server requires a password before it accepts a new workspace. Enter it to create the workspace on the server.";return a`<dialog @close="${this._onClose}"><header><h3>Sync server password</h3></header><p class="nwd-intro">${t}</p><input type="password" class="nwd-input" placeholder="Password" autocomplete="off" data-1p-ignore="true" data-lpignore="true" data-bwignore="true" data-form-type="other" name="dv-sync-auth" maxlength="4096" .value="${this._value}" @input="${this._onInput}" @keydown="${this._onKeydown}"><footer class="nwd-actions"><span class="nwd-spacer"></span> <button type="button" @click="${this._onCancel}">Cancel</button> <button type="button" class="primary" ?disabled="${!e}" @click="${this._onSubmit}">${this.retry?"Retry":"Authenticate"}</button></footer></dialog>`}};customElements.define("sync-auth-dialog",Rn);function Vd({retry:i=!1}={}){return Y("sync-auth-dialog",{retry:!!i})}function Kd(){$l(async({retry:i})=>{try{return await Vd({retry:i})}catch(e){return console.warn("Sync auth dialog failed to open:",e),null}})}var Zi="https://triage.space/",Nh=[{hostname:"deepaudit.dev",pathPrefix:"/",supportsSync:!0},{hostname:"chalker.github.io",pathPrefix:"/deepview/",supportsSync:!1}];function zh(){for(let i of Nh)if(location.hostname===i.hostname&&location.pathname.startsWith(i.pathPrefix))return i;return null}var qh=["deepview.triage","deepview.triage.pending"],Hh="deepview.repoUrls";function Uh(){try{for(let i of qh)if(localStorage.getItem(i))return!0}catch{return!0}try{let i=localStorage.getItem(Hh);if(i){let e=JSON.parse(i);if(e&&typeof e=="object"&&Object.keys(e).length>0)return!0}}catch{return!0}return!1}async function jh(){if(Uh())return!0;let i=[];try{i=await gt()}catch{return!0}if(i.length>0)return!0;try{if(he().length>0)return!0}catch{return!0}try{return await il()}catch{return!0}}var Ln=class extends U{static properties={supportsSync:{attribute:!1}};createRenderRoot(){return this}constructor(){super(),this.supportsSync=!1}firstUpdated(){let e=this.querySelector("dialog");e&&e.showModal();let t=this.querySelector("button.om-stay");t&&t.focus()}_finish(e){if(this._settled)return;this._settled=!0;let t=this.querySelector("dialog");t&&t.close(),this.dispatchEvent(new CustomEvent("resolve",{detail:e}))}_onClose=()=>this._finish(!1);_onStay=()=>this._finish(!1);_onMigrate=()=>this._finish(!0);render(){let e=()=>a`<a class="om-link" href="${Zi}" target="_blank" rel="noopener noreferrer">${Zi}</a>`;return a`<dialog class="origin-migration-dialog" @close="${this._onClose}"><header class="om-head"><h3>This deepview build has moved</h3><p><code>${location.host}${location.pathname}</code> has moved to ${e()}.</p></header><section class="om-body"><p>Workspaces and reports don't migrate automatically — they live in this origin's browser storage (OPFS where available, localStorage as a fallback) and have to be re-imported on ${e()}.</p>${this.supportsSync?a`<p>For each workspace, use the <strong>Export workspace</strong> button in the sidebar to download a <code>.gz</code> bundle (workspace + its reports + its triage), then drop that file on ${e()}. Workspaces that had sync configured will pick their triage state back up from the sync server once you re-import them with the same key.</p><p>For triage attached to loose reports (or as a top-up after re-importing workspaces), call <code>DeepView.export()</code> in the browser console — that downloads just the triage entries plus saved repo URLs, no reports or workspaces.</p>`:a`<p>This build has no sync layer. For each workspace, use the <strong>Export workspace</strong> button in the sidebar to download a <code>.gz</code> bundle (workspace + its reports + its triage), then drop that file on ${e()}.</p><p>For triage attached to loose reports, call <code>DeepView.export()</code> in the browser console — that downloads just the triage entries plus saved repo URLs, no reports or workspaces. Reports themselves need to be re-dropped from their original JSON on the new origin.</p>`}</section><footer class="om-actions"><button type="button" class="om-stay" @click="${this._onStay}">Keep editing on ${location.host}</button> <button type="button" class="primary om-go" @click="${this._onMigrate}">Switch to triage.space</button></footer></dialog>`}};customElements.define("origin-migration-dialog",Ln);function Vh(i){return new Promise(e=>{let t=document.createElement("origin-migration-dialog");t.supportsSync=i.supportsSync,t.addEventListener("resolve",r=>{t.remove(),e(!!r.detail)}),document.body.append(t)})}async function Gd(){let i=zh();return i?await jh()?await Vh(i)?(location.assign(Zi),!0):!1:(location.replace(Zi),!0):!1}var Mn=class extends q{static styles=[...q.styles,M(Ml)];static properties={encoded:{type:String},_stage:{state:!0},_password:{state:!0},_name:{state:!0},_decoded:{state:!0},_existingById:{state:!0},_busy:{state:!0},_error:{state:!0},_settled:{state:!0}};constructor(){super(),this.encoded="",this._stage="password",this._password="",this._name="",this._decoded=null,this._existingById=null,this._busy=!1,this._error="",this._settled=!1}focusInitial(){this._focusActiveInput()}updated(e){e.has("_stage")&&this._focusActiveInput()}_focusActiveInput(){if(this._stage==="password")this.renderRoot.querySelector('input[type="password"]')?.focus();else if(this._stage==="name"){let e=this.renderRoot.querySelector('input[data-role="name"]');e&&(e.focus(),e.select())}}_finish(e){this._settled||(this._decoded=null,this._password="",this.encoded="",super._finish(e))}_onClose=()=>this._finish(null);_onCancel=()=>this._finish(null);_onPasswordInput=e=>{this._password=e.target.value,this._error=""};_onNameInput=e=>{this._name=e.target.value};_onUnlock=async()=>{if(!(!this._password||this._busy)){this._busy=!0,this._error="";try{let e=await bl({encoded:this.encoded,password:this._password});if(this._settled)return;let t=he().find(r=>r.id===e.id)??null;this._decoded=e,this._existingById=t,this._name=e.name,this._password="",this._stage="name"}catch(e){if(this._settled)return;this._error=e?.message??String(e)}finally{this._busy=!1}}};_onAttach=()=>{if(!this._decoded)return;let e=Ii(this._name);if(!e)return;let t=he().find(r=>r.id===this._decoded.id)??null;if(t){this._existingById=t;return}this._nameCollision(e)||this._finish({id:this._decoded.id,name:e,privateKeyBase64:this._decoded.privateKeyBase64})};_nameCollision(e){if(!e||!this._decoded)return null;for(let t of he())if(t.id!==this._decoded.id&&Ii(t.name)===e)return t;return null}_onKeydown=e=>{e.key==="Enter"&&(e.preventDefault(),this._stage==="password"?this._onUnlock():this._stage==="name"&&this._onAttach())};_passwordStage(){return a`<p class="nwd-note ui-hint">Someone shared a workspace with you. Enter the password they sent separately to attach it to this browser.</p><label class="wsl-field"><span>Password</span> <input type="password" class="nwd-input" autocomplete="off" data-1p-ignore="true" data-lpignore="true" data-bwignore="true" data-form-type="other" name="dv-share-link-unlock" maxlength="1024" .value="${this._password}" @input="${this._onPasswordInput}" @keydown="${this._onKeydown}"></label> ${this._error?a`<p class="wsl-error" role="alert">${this._error}</p>`:m}<footer class="nwd-actions"><span class="nwd-spacer"></span> <button type="button" @click="${this._onCancel}">Cancel</button> <button type="button" class="primary" ?disabled="${!this._password||this._busy}" @click="${this._onUnlock}">${this._busy?"Unlocking\u2026":"Unlock"}</button></footer>`}_alreadyAttachedStage(){let e=this._existingById;return a`<p class="nwd-note">This workspace is already attached as <strong>"${e?.name??""}"</strong>. Open it from the sidebar.</p><footer class="nwd-actions"><span class="nwd-spacer"></span> <button type="button" class="primary" @click="${this._onCancel}">Close</button></footer>`}_nameStage(){if(this._existingById)return this._alreadyAttachedStage();let e=Ii(this._name),t=this._nameCollision(e),r=!!e&&!t;return a`<p class="nwd-note ui-hint">Pick a name for the workspace on this device. The shared identity is preserved either way — only the visible label changes.</p><label class="wsl-field"><span>Workspace name</span> <input type="text" class="nwd-input" data-role="name" placeholder="Workspace name" maxlength="200" .value="${this._name}" @input="${this._onNameInput}" @keydown="${this._onKeydown}"></label> ${t?a`<p class="wsl-error" role="alert">A workspace named "${e}" already exists on this device. Pick a different name.</p>`:m}<footer class="nwd-actions"><span class="nwd-spacer"></span> <button type="button" @click="${this._onCancel}">Cancel</button> <button type="button" class="primary" ?disabled="${!r}" @click="${this._onAttach}">Attach</button></footer>`}render(){let e=this._stage==="password"?"Attach shared workspace":this._existingById?"Workspace already attached":"Name the workspace";return a`<dialog @close="${this._onClose}"><header><h3>${e}</h3></header>${this._stage==="password"?this._passwordStage():this._nameStage()}</dialog>`}};customElements.define("workspace-unlock-link-dialog",Mn);function Wd({encoded:i}={}){return Ca("workspace-unlock-link-dialog",{encoded:i??""},e=>{e.encoded=""})}var ee=null,er=!1,ei=null;function Kh(i){if(!i)return"Could not unlock. Try again.";switch(i.name??""){case"NotAllowedError":case"AbortError":return"";case"SecurityError":return"The site identity does not match the one this passkey was registered for. If you opened DeepView through a different URL (different subdomain, different port), reload via the original URL.";case"InvalidStateError":return"The passkey state on this device is inconsistent. Try reloading the page or removing and re-creating the passkey.";case"NotSupportedError":return"This browser does not support the WebAuthn PRF extension this site needs. Try a recent Chrome, Safari, or Edge with a platform authenticator.";case"NetworkError":return"A network error prevented the passkey from completing. Check your connection and try again.";case"UnknownError":return"The authenticator returned an unknown error. Try again, or use a different passkey.";default:{let t=i.message??String(i);return t.length>200?t.slice(0,197)+"\u2026":t}}}function Gh(){if(ee)return ee;ee=document.createElement("div"),ee.id="lock-overlay",ee.setAttribute("role","dialog"),ee.setAttribute("aria-modal","true"),ee.setAttribute("aria-label","Unlock DeepView"),ee.innerHTML=`
1
+ import{a as xt,b as Le,c as zd,d as Tn}from"./chunk-D7AF2JXL.js";import{a as Hd}from"./chunk-KEX2ATEW.js";import{$ as Di,$a as et,$b as zc,$c as Xi,A as fl,Aa as Bi,Ab as Gt,Ac as ed,Ad as Fd,B as gl,Ba as Zl,Bb as $c,Bc as td,Bd as Dd,C as bl,Ca as ec,Cb as xc,Cc as id,D as vl,Da as tc,Db as Sc,Dc as kt,Dd as Zt,E as yl,Ea as an,Eb as Cc,Ec as rd,Ed as Od,F as _l,Fa as ic,Fb as Vi,Fc as nd,Fd as Qi,G as wl,Ga as Vt,Gb as Ki,Gc as sd,Gd as Bd,H as kl,Ha as ln,Hb as Ec,Hc as od,Hd as $t,I as $l,Ia as rc,Ib as Tc,Ic as ad,Id as Nd,J as xl,Ja as de,Jb as Rc,Jc as ld,Jd as fe,K as Fi,Ka as D,Kb as Lc,Kc as Xt,Kd as qd,L as me,La as yt,Lb as Mc,Lc as cd,Ld as St,M as Sl,Ma as Ni,Mb as Wt,Mc as dd,N as Cl,Na as cn,Nb as pn,Nc as ud,O as El,Oa as nc,Ob as Pc,Oc as Sn,P as Tl,Pa as sc,Pb as Ac,Pc as pd,Q as Rl,Qa as oc,Qb as Gi,Qc as hd,R as Je,Ra as ac,Rb as Wi,Rc as Oe,S as Ll,Sa as Kt,Sb as Ic,Sc as md,T as Ml,Ta as _t,Tb as Fc,U as bt,Ua as lc,Ub as hn,V as Pl,Va as wt,Vb as Dc,W as vt,Wa as zi,Wb as mn,X as Al,Xa as dn,Xb as fn,Y as Il,Ya as cc,Yb as Oc,Yc as fd,Z as Fl,Za as dc,Zb as Bc,Zc as Be,_ as Dl,_a as qi,_b as Nc,_c as tt,a as Ja,aa as Ol,ab as uc,ac as qc,ad as Cn,b as Xa,ba as Bl,bb as pc,bc as Yt,bd as it,c as Qa,ca as Nl,cb as hc,cc as gn,cd as gd,d as Za,da as qt,dc as Hc,dd as bd,e as el,ea as Ht,ec as Uc,ed as vd,f as on,fa as zl,fc as jc,fd as yd,g as Ai,ga as ql,gb as mc,gc as bn,gd as _d,h as l,ha as Hl,hb as fc,hc as vn,hd as wd,i as H,ia as Ul,ic as Vc,id as kd,j as nl,ja as Oi,jc as Kc,jd as $d,k as sl,ka as jl,kc as yn,kd as xd,l as ol,la as Vl,lc as _n,ld as Qt,m as al,ma as Xe,mc as Gc,md as En,n as he,na as Kl,nc as Wc,nd as Sd,o as Ii,oa as Gl,ob as un,oc as Yc,od as Cd,p as ll,pa as Qe,pb as Hi,pc as Jt,pd as $,qa as Wl,qb as gc,qc as Yi,ra as Yl,rb as xe,rc as Jc,sa as Ut,sb as bc,sc as Xc,sd as Ed,t as cl,ta as De,tb as Ui,tc as Qc,td as Td,u as dl,ua as Ze,ub as ji,uc as Ji,ud as Rd,v as ul,va as Jl,vb as vc,vc as wn,vd as Ld,w as pl,wa as Xl,wb as yc,wc as kn,wd as Md,x as ke,xa as $e,xb as _c,xc as $n,xd as Pd,y as hl,ya as jt,yb as wc,yc as Zc,yd as Ad,z as ml,za as Ql,zb as kc,zc as xn,zd as Id}from"./chunk-WOTMRDM3.js";import{a as Ei}from"./chunk-2KBF5TZ7.js";import{b as Ta}from"./chunk-K3X5EJBQ.js";import{a as $a,b as R,c as xa,d as Ge,g as q,h as Y,i as Ca}from"./chunk-CVVJAXVY.js";import{B as gt,D as tl,K as il,O as rl,c as ja,d as we,e as Ye,f as Va,j as Pi,k as Ka,n as Ga,r as Wa,u as Ya}from"./chunk-VIHGO77Y.js";import{u as Ha,z as Ua}from"./chunk-RFZQQXSG.js";import{d as ca,p as ma,q as fa}from"./chunk-RSHMVYNS.js";import{A as _a,B as wa,D as Nt,E as tn,I as rn,M as ka,b as Xr,ba as Ci,c as Qr,d as j,ea as Ea,k as xi,l as ba,m as Zr,n as Ve,q as va,t as en,v as Si,w as ya,y as K,z as Re}from"./chunk-CLPKNNC7.js";import{f as ga}from"./chunk-UYAXVRVL.js";import"./chunk-NRPC74AM.js";import"./chunk-VQJCXGIY.js";import{f as X}from"./chunk-W4J3MGLB.js";import"./chunk-GJ4IUCNS.js";import"./chunk-PNHBZGDD.js";import{$ as E,A as Ri,C as G,D as ft,G as zt,H as We,J as Li,O as Fe,P as Aa,R as Ia,S as Fa,V as Da,W as Oa,Y as Ba,a as I,aa as oe,b as _e,c as mt,da as Na,e as Ra,ea as za,f as nn,fa as Mi,g as Ti,ga as qa,o as sn,p as La,r as Ma,z as Pa}from"./chunk-UXNUAIIC.js";import"./chunk-R5O6FAW4.js";import{b as Sa,d as ht}from"./chunk-CMQA4DM6.js";import{g as ha}from"./chunk-4F6JSF57.js";import"./chunk-V3ME6FI5.js";import{e as pt,h as Ke}from"./chunk-YVZH5SHP.js";import"./chunk-4XCDFGDP.js";import"./chunk-3BZ7JERB.js";import{a as le}from"./chunk-TZ5KB2Y5.js";import"./chunk-XYFXXB2G.js";import{a as J}from"./chunk-DIJJNTRH.js";import{a as ki,g as $i,h as ua,j as Yr,l as pa,n as Jr}from"./chunk-WZDTZE64.js";import{B as wi,I as oa,J as aa,L as la,a as yi,b as Qo,e as Zo,f as ea,g as ta,j as ia,k as ra,l as na,m as _i,p as sa,v as Bt}from"./chunk-GNXOKIGP.js";import"./chunk-C4Z6ZBXV.js";import{a as M,b as ut,c as a,d as ye,e as Go,g as m,i as Wo,j as U}from"./chunk-2XUEZHIP.js";import{b as da}from"./chunk-TUII34K2.js";import{c as Yo,e as Jo,f as Xo,k as gi,p as bi,t as vi}from"./chunk-V5O7M2YT.js";import"./chunk-OOJM4CTU.js";var Ud={attach:{title:"Synced triage on report attach",intro:"have triage from your workspace that disagrees with your local view on",trailingNote:"Other findings in this report whose chain value didn't conflict were applied automatically; this list only covers disagreements. Pick which side to keep.",importedSideLabel:"Apply from chain",applyButton:"Apply"},chain:{title:"Triage conflict from peer update",intro:"were changed by a peer (or by another tab) in a way that disagrees with your local triage on",trailingNote:`Other findings whose remote value didn't conflict were applied automatically; this list only covers disagreements. Pick which side to keep for each \u2014 a "keep current" pick re-publishes your local value to the chain on your next save.`,importedSideLabel:"Apply from chain",applyButton:"Apply"}};function jd(){xl(async(i,e,t)=>{let r=cl(i);try{return await Al(i,r,Ud[t]??Ud.attach)}catch{let n=i.length;return alert(`${t==="attach"?"A report attach":"A workspace sync"} had ${n} triage disagreement${n===1?"":"s"} with your local view. Kept your local values because another dialog is open. ${t==="attach"?"Detach and re-attach the report to pick again.":"Your local values will re-publish to the chain on the next change."}`),null}})}var Rn=class extends q{static properties={retry:{type:Boolean},_value:{state:!0}};constructor(){super(),this.retry=!1,this._value=""}_finish(e){this._value="",super._finish(e)}_onCancel=()=>this._finish(null);_onInput=e=>{this._value=e.target.value};_onSubmit=()=>{let e=this._value??"";e&&this._finish(e)};_onKeydown=e=>{e.key==="Enter"&&(e.preventDefault(),this._onSubmit())};render(){let e=(this._value??"").length>0,t=this.retry?"That password didn't match. Try again, or cancel to leave the workspace unsynced for now.":"This sync server requires a password before it accepts a new workspace. Enter it to create the workspace on the server.";return a`<dialog @close="${this._onClose}"><header><h3>Sync server password</h3></header><p class="nwd-intro">${t}</p><input type="password" class="nwd-input" placeholder="Password" autocomplete="off" data-1p-ignore="true" data-lpignore="true" data-bwignore="true" data-form-type="other" name="dv-sync-auth" maxlength="4096" .value="${this._value}" @input="${this._onInput}" @keydown="${this._onKeydown}"><footer class="nwd-actions"><span class="nwd-spacer"></span> <button type="button" @click="${this._onCancel}">Cancel</button> <button type="button" class="primary" ?disabled="${!e}" @click="${this._onSubmit}">${this.retry?"Retry":"Authenticate"}</button></footer></dialog>`}};customElements.define("sync-auth-dialog",Rn);function Vd({retry:i=!1}={}){return Y("sync-auth-dialog",{retry:!!i})}function Kd(){$l(async({retry:i})=>{try{return await Vd({retry:i})}catch(e){return console.warn("Sync auth dialog failed to open:",e),null}})}var Zi="https://triage.space/",Nh=[{hostname:"deepaudit.dev",pathPrefix:"/",supportsSync:!0},{hostname:"chalker.github.io",pathPrefix:"/deepview/",supportsSync:!1}];function zh(){for(let i of Nh)if(location.hostname===i.hostname&&location.pathname.startsWith(i.pathPrefix))return i;return null}var qh=["deepview.triage","deepview.triage.pending"],Hh="deepview.repoUrls";function Uh(){try{for(let i of qh)if(localStorage.getItem(i))return!0}catch{return!0}try{let i=localStorage.getItem(Hh);if(i){let e=JSON.parse(i);if(e&&typeof e=="object"&&Object.keys(e).length>0)return!0}}catch{return!0}return!1}async function jh(){if(Uh())return!0;let i=[];try{i=await gt()}catch{return!0}if(i.length>0)return!0;try{if(he().length>0)return!0}catch{return!0}try{return await il()}catch{return!0}}var Ln=class extends U{static properties={supportsSync:{attribute:!1}};createRenderRoot(){return this}constructor(){super(),this.supportsSync=!1}firstUpdated(){let e=this.querySelector("dialog");e&&e.showModal();let t=this.querySelector("button.om-stay");t&&t.focus()}_finish(e){if(this._settled)return;this._settled=!0;let t=this.querySelector("dialog");t&&t.close(),this.dispatchEvent(new CustomEvent("resolve",{detail:e}))}_onClose=()=>this._finish(!1);_onStay=()=>this._finish(!1);_onMigrate=()=>this._finish(!0);render(){let e=()=>a`<a class="om-link" href="${Zi}" target="_blank" rel="noopener noreferrer">${Zi}</a>`;return a`<dialog class="origin-migration-dialog" @close="${this._onClose}"><header class="om-head"><h3>This deepview build has moved</h3><p><code>${location.host}${location.pathname}</code> has moved to ${e()}.</p></header><section class="om-body"><p>Workspaces and reports don't migrate automatically — they live in this origin's browser storage (OPFS where available, localStorage as a fallback) and have to be re-imported on ${e()}.</p>${this.supportsSync?a`<p>For each workspace, use the <strong>Export workspace</strong> button in the sidebar to download a <code>.gz</code> bundle (workspace + its reports + its triage), then drop that file on ${e()}. Workspaces that had sync configured will pick their triage state back up from the sync server once you re-import them with the same key.</p><p>For triage attached to loose reports (or as a top-up after re-importing workspaces), call <code>DeepView.export()</code> in the browser console — that downloads just the triage entries plus saved repo URLs, no reports or workspaces.</p>`:a`<p>This build has no sync layer. For each workspace, use the <strong>Export workspace</strong> button in the sidebar to download a <code>.gz</code> bundle (workspace + its reports + its triage), then drop that file on ${e()}.</p><p>For triage attached to loose reports, call <code>DeepView.export()</code> in the browser console — that downloads just the triage entries plus saved repo URLs, no reports or workspaces. Reports themselves need to be re-dropped from their original JSON on the new origin.</p>`}</section><footer class="om-actions"><button type="button" class="om-stay" @click="${this._onStay}">Keep editing on ${location.host}</button> <button type="button" class="primary om-go" @click="${this._onMigrate}">Switch to triage.space</button></footer></dialog>`}};customElements.define("origin-migration-dialog",Ln);function Vh(i){return new Promise(e=>{let t=document.createElement("origin-migration-dialog");t.supportsSync=i.supportsSync,t.addEventListener("resolve",r=>{t.remove(),e(!!r.detail)}),document.body.append(t)})}async function Gd(){let i=zh();return i?await jh()?await Vh(i)?(location.assign(Zi),!0):!1:(location.replace(Zi),!0):!1}var Mn=class extends q{static styles=[...q.styles,M(Ml)];static properties={encoded:{type:String},_stage:{state:!0},_password:{state:!0},_name:{state:!0},_decoded:{state:!0},_existingById:{state:!0},_busy:{state:!0},_error:{state:!0},_settled:{state:!0}};constructor(){super(),this.encoded="",this._stage="password",this._password="",this._name="",this._decoded=null,this._existingById=null,this._busy=!1,this._error="",this._settled=!1}focusInitial(){this._focusActiveInput()}updated(e){e.has("_stage")&&this._focusActiveInput()}_focusActiveInput(){if(this._stage==="password")this.renderRoot.querySelector('input[type="password"]')?.focus();else if(this._stage==="name"){let e=this.renderRoot.querySelector('input[data-role="name"]');e&&(e.focus(),e.select())}}_finish(e){this._settled||(this._decoded=null,this._password="",this.encoded="",super._finish(e))}_onClose=()=>this._finish(null);_onCancel=()=>this._finish(null);_onPasswordInput=e=>{this._password=e.target.value,this._error=""};_onNameInput=e=>{this._name=e.target.value};_onUnlock=async()=>{if(!(!this._password||this._busy)){this._busy=!0,this._error="";try{let e=await bl({encoded:this.encoded,password:this._password});if(this._settled)return;let t=he().find(r=>r.id===e.id)??null;this._decoded=e,this._existingById=t,this._name=e.name,this._password="",this._stage="name"}catch(e){if(this._settled)return;this._error=e?.message??String(e)}finally{this._busy=!1}}};_onAttach=()=>{if(!this._decoded)return;let e=Ii(this._name);if(!e)return;let t=he().find(r=>r.id===this._decoded.id)??null;if(t){this._existingById=t;return}this._nameCollision(e)||this._finish({id:this._decoded.id,name:e,privateKeyBase64:this._decoded.privateKeyBase64})};_nameCollision(e){if(!e||!this._decoded)return null;for(let t of he())if(t.id!==this._decoded.id&&Ii(t.name)===e)return t;return null}_onKeydown=e=>{e.key==="Enter"&&(e.preventDefault(),this._stage==="password"?this._onUnlock():this._stage==="name"&&this._onAttach())};_passwordStage(){return a`<p class="nwd-note ui-hint">Someone shared a workspace with you. Enter the password they sent separately to attach it to this browser.</p><label class="wsl-field"><span>Password</span> <input type="password" class="nwd-input" autocomplete="off" data-1p-ignore="true" data-lpignore="true" data-bwignore="true" data-form-type="other" name="dv-share-link-unlock" maxlength="1024" .value="${this._password}" @input="${this._onPasswordInput}" @keydown="${this._onKeydown}"></label> ${this._error?a`<p class="wsl-error" role="alert">${this._error}</p>`:m}<footer class="nwd-actions"><span class="nwd-spacer"></span> <button type="button" @click="${this._onCancel}">Cancel</button> <button type="button" class="primary" ?disabled="${!this._password||this._busy}" @click="${this._onUnlock}">${this._busy?"Unlocking\u2026":"Unlock"}</button></footer>`}_alreadyAttachedStage(){let e=this._existingById;return a`<p class="nwd-note">This workspace is already attached as <strong>"${e?.name??""}"</strong>. Open it from the sidebar.</p><footer class="nwd-actions"><span class="nwd-spacer"></span> <button type="button" class="primary" @click="${this._onCancel}">Close</button></footer>`}_nameStage(){if(this._existingById)return this._alreadyAttachedStage();let e=Ii(this._name),t=this._nameCollision(e),r=!!e&&!t;return a`<p class="nwd-note ui-hint">Pick a name for the workspace on this device. The shared identity is preserved either way — only the visible label changes.</p><label class="wsl-field"><span>Workspace name</span> <input type="text" class="nwd-input" data-role="name" placeholder="Workspace name" maxlength="200" .value="${this._name}" @input="${this._onNameInput}" @keydown="${this._onKeydown}"></label> ${t?a`<p class="wsl-error" role="alert">A workspace named "${e}" already exists on this device. Pick a different name.</p>`:m}<footer class="nwd-actions"><span class="nwd-spacer"></span> <button type="button" @click="${this._onCancel}">Cancel</button> <button type="button" class="primary" ?disabled="${!r}" @click="${this._onAttach}">Attach</button></footer>`}render(){let e=this._stage==="password"?"Attach shared workspace":this._existingById?"Workspace already attached":"Name the workspace";return a`<dialog @close="${this._onClose}"><header><h3>${e}</h3></header>${this._stage==="password"?this._passwordStage():this._nameStage()}</dialog>`}};customElements.define("workspace-unlock-link-dialog",Mn);function Wd({encoded:i}={}){return Ca("workspace-unlock-link-dialog",{encoded:i??""},e=>{e.encoded=""})}var ee=null,er=!1,ei=null;function Kh(i){if(!i)return"Could not unlock. Try again.";switch(i.name??""){case"NotAllowedError":case"AbortError":return"";case"SecurityError":return"The site identity does not match the one this passkey was registered for. If you opened DeepView through a different URL (different subdomain, different port), reload via the original URL.";case"InvalidStateError":return"The passkey state on this device is inconsistent. Try reloading the page or removing and re-creating the passkey.";case"NotSupportedError":return"This browser does not support the WebAuthn PRF extension this site needs. Try a recent Chrome, Safari, or Edge with a platform authenticator.";case"NetworkError":return"A network error prevented the passkey from completing. Check your connection and try again.";case"UnknownError":return"The authenticator returned an unknown error. Try again, or use a different passkey.";default:{let t=i.message??String(i);return t.length>200?t.slice(0,197)+"\u2026":t}}}function Gh(){if(ee)return ee;ee=document.createElement("div"),ee.id="lock-overlay",ee.setAttribute("role","dialog"),ee.setAttribute("aria-modal","true"),ee.setAttribute("aria-label","Unlock DeepView"),ee.innerHTML=`
2
2
  <div class="lock-overlay-card">
3
3
  <div class="lock-overlay-icon" aria-hidden="true">
4
4
  <svg viewBox="0 0 32 32" width="40" height="40" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="7" y="15" width="18" height="12" rx="1.5"/><path d="M11 15v-4a5 5 0 0 1 10 0v4"/></svg>
@@ -31,7 +31,7 @@ Use this only if you have lost access to your passkey and have no other way to u
31
31
  `,xt(e,n=>{n&&(Le(e),this._paint(e,t))})}}disconnectedCallback(){for(let e of this.renderRoot.querySelectorAll(".evd-chunk[data-watched]"))Le(e);clearTimeout(this._copiedTimer),super.disconnectedCallback()}_onCopy=async()=>{let e="done";try{await navigator.clipboard.writeText(this.markdown)}catch{e="failed"}this.isConnected&&(this._copied=e,clearTimeout(this._copiedTimer),this._copiedTimer=setTimeout(()=>{this._copied="",this._copiedTimer=null},1500))};async _paint(e,t){let r=this._chunks[t];if(!r||r.asked)return;r.asked=!0;let n=ou(this._lines,r.start),s=[...n?this._lines.slice(n[0],n[1]):[],...this._lines.slice(r.start,r.end)].join(`
32
32
  `),o=await yt(s,"markdown");if(!this.isConnected)return;let c=o===null?null:Ni(o).slice(n?n[1]-n[0]:0);e.innerHTML=sm(this._lines,r.start,r.end,c?.length===r.end-r.start?c:null),e.classList.remove("evd-pending")}};customElements.define("export-view-dialog",qn);function cu(i){return new Promise(e=>{let t=document.createElement("export-view-dialog");t.markdown=i;let r=()=>{t.remove(),e()};t.addEventListener("resolve",r),t.addEventListener("modal-conflict",r),document.body.append(t)})}var du=`dialog{max-width:560px;width:min(94vw,560px)}header h3{margin:0 0 .4rem}.finding{display:flex;align-items:center;gap:.5rem;flex-wrap:wrap;margin-bottom:.35rem}.loc{font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:.76rem;color:var(--text);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:0;flex:1}.desc{font-size:.78rem;color:var(--muted);margin:0 0 .7rem;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}.input-row{display:flex;align-items:stretch;gap:.4rem}input{flex:1;min-width:0;padding:.5rem .65rem;border:1px solid var(--border);border-radius:var(--ui-radius, 6px);background:var(--bg, var(--surface));color:var(--text);font:inherit;font-size:.88rem;font-family:ui-monospace,SFMono-Regular,Menlo,monospace;&:focus{outline:none;border-color:var(--accent);box-shadow:0 0 0 3px rgb(from var(--accent) r g b / .18)}&::placeholder{color:var(--muted);font-family:inherit}}.open{display:inline-flex;align-items:center;padding:0 .7rem;border:1px solid var(--accent);border-radius:var(--ui-radius, 6px);color:var(--accent);text-decoration:none;font-size:.8rem;font-weight:600;white-space:nowrap;&:hover{background:rgb(from var(--accent) r g b / .1)}}.hint{margin:.45rem 0 0;color:var(--muted);font-size:.74rem}
33
33
  `;var Hn=class extends q{static styles=[...q.styles,M(bt),M(du)];static properties={initial:{attribute:!1},finding:{attribute:!1},canApplyToGroup:{attribute:!1},_value:{state:!0}};constructor(){super(),this.initial="",this.finding=null,this.canApplyToGroup=!1,this._value=""}beforeOpen(){this._value=this.initial??""}focusInitial(){let e=this.renderRoot.querySelector('input[type="url"]');if(e){e.focus();try{e.select()}catch{}}}_onInput=e=>{this._value=e.target.value};get _trimmed(){return(this._value??"").trim()}_onSave=()=>{let e=(this.initial??"").trim();if(this._trimmed===e){this._finish(null);return}this._finish({value:this._trimmed,scope:"finding"})};_onApplyToGroup=()=>{this._trimmed&&this._finish({value:this._trimmed,scope:"group"})};_onClear=()=>this._finish({value:"",scope:"finding"});_onCancel=()=>this._finish(null);_onKeydown=e=>{e.key==="Enter"&&(e.preventDefault(),this._onSave())};render(){let e=this.finding??{},t=e.file?e.line?`${e.file}:${e.line}`:e.file:"",r=(this.initial??"").length>0,n=this._trimmed,s=wi(n);return a`<dialog @close="${this._onClose}"><header><h3>${r?"Edit fix link":"Add fix link"}</h3><div class="finding">${vt(_i(e,l.severityMode))} ${t?a`<span class="loc" data-tooltip-truncated data-tooltip="${t}">${t}</span>`:m}</div>${e.description?a`<div class="desc" data-tooltip-truncated data-tooltip="${e.description}">${e.description}</div>`:m}</header><div class="input-row"><input type="url" inputmode="url" autocomplete="off" spellcheck="false" placeholder="https://github.com/owner/repo/pull/123" .value="${this._value}" @input="${this._onInput}" @keydown="${this._onKeydown}"> ${s?a`<a class="open" href="${n}" target="_blank" rel="noopener noreferrer">Open ↗</a>`:m}</div><p class="hint">PR URL, issue link, commit, or any free-form reference. Enter to save, Esc to cancel.</p><footer class="nwd-actions">${r?a`<button type="button" class="danger" @click="${this._onClear}">Clear</button>`:m} <span class="nwd-spacer"></span> ${this.canApplyToGroup?a`<button type="button" class="quiet" ?disabled="${!n}" @click="${this._onApplyToGroup}">Apply to whole group</button> <span class="nwd-spacer"></span>`:m} <button type="button" @click="${this._onCancel}">Cancel</button> <button type="button" class="primary" @click="${this._onSave}">Save</button></footer></dialog>`}};customElements.define("fix-link-dialog",Hn);function uu({initial:i="",finding:e=null,canApplyToGroup:t=!1}={}){return Y("fix-link-dialog",{initial:i,finding:e,canApplyToGroup:t})}var pu=`dialog{width:min(94vw,880px);max-width:880px}.conflicts-list{list-style:none;display:flex;flex-direction:column;gap:.6rem;max-height:65vh;overflow-y:auto;overscroll-behavior:contain}.conflict-card{padding:.6rem .7rem;border:1px solid var(--border);border-radius:var(--ui-radius, 6px)}.finding-meta{display:flex;flex-wrap:wrap;align-items:center;gap:.4rem;color:var(--muted);font-size:.72rem}.location,code{font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;overflow-wrap:anywhere}.location{flex:1}h4{margin:.4rem 0 .55rem;font-size:.88rem;font-weight:600;overflow-wrap:anywhere}dt{margin-top:.5rem;color:var(--muted);font-size:.72rem}.variant{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,15rem);gap:.65rem;padding:.4rem 0;font-size:.8rem;+&{border-top:1px solid var(--border)}}.value{white-space:pre-wrap;overflow-wrap:anywhere}.reports{display:flex;flex-wrap:wrap;place-content:start flex-end;gap:.3rem}.report-button{display:inline-flex;align-items:center;gap:.4rem;max-width:100%;min-height:22px;padding:0 .4rem 0 0;border:1px solid var(--border);border-radius:var(--ui-radius, 4px);overflow:hidden;background:var(--bg);color:var(--text);font:inherit;font-size:.72rem;cursor:default;text-align:left;>span:last-child{min-width:0;overflow-wrap:anywhere}&:hover{border-color:var(--accent)}}
34
- `;var lm={revalidate:"Outcome",revalidateVerdict:"Explanation",revalidateRecommendation:"Recommendation"},Un=class extends q{static styles=[...q.styles,M(bt),M($t),M(pu)];static properties={conflicts:{attribute:!1}};constructor(){super(),this.conflicts=[]}render(){return a`<dialog aria-labelledby="revalidation-conflicts-title" @close="${this._onClose}"><header><h3 id="revalidation-conflicts-title">Revalidation conflicts</h3><p class="nwd-intro">Reports disagree about ${this.conflicts.length} finding${this.conflicts.length===1?"":"s"}. App view is unavailable until the conflicting reports are separated or updated.</p></header><ul class="conflicts-list">${this.conflicts.map(({finding:e,copies:t})=>a`<li class="conflict-card"><div class="finding-meta">${vt(e.severity)} ${e.file?a`<span class="location">${e.file}${Fe(e.line)?`:${Aa(Fe(e.line))}`:""}</span>`:m} <code>${Ba(e.id)??e.id}</code></div><h4>${Bt(e)}</h4><dl>${Vl(t).map(({field:r,variants:n})=>a`<dt>${lm[r]??r}</dt>${n.map(({value:s,reports:o})=>a`<dd class="variant"><div class="value">${s||a`<em>Empty</em>`}</div><div class="reports">${o.map(c=>c?a`<button type="button" class="report-button" aria-label="${`Open ${Qr(c)} at this finding`}" @click="${()=>this._finish({id:e.id,reportName:c})}">${J(Xr[Ll(c)]??Xr.default)}<span>${Qr(c)}</span></button>`:a`<span>Loaded report</span>`)}</div></dd>`)}`)}</dl></li>`)}</ul><footer class="nwd-actions"><span class="nwd-spacer"></span><button type="button" @click="${this._onClose}">Close</button></footer></dialog>`}};customElements.define("revalidation-conflicts-dialog",Un);function hu(i){return Y("revalidation-conflicts-dialog",{conflicts:[...i.values()]})}var mu=2;function fu(i,e){l.focusSplit=e,i.closest(".focus-main")?.style.setProperty("--focus-split",String(e)),i.setAttribute("aria-valuenow",String(Math.round(e)))}function gu(){try{localStorage.setItem(Xa,String(l.focusSplit))}catch{}}function bu(i,e){fu(i,on(e)),gu()}function vu(i,e){bu(i,l.focusSplit+e)}function yu(i){bu(i,el)}function _u(i,e){let t=i.closest(".focus-main");if(!t)return;e.preventDefault(),i.classList.add("dragging");try{i.setPointerCapture(e.pointerId)}catch{}let r=s=>{let o=t.getBoundingClientRect();o.width!==0&&fu(i,on((s.clientX-o.left)/o.width*100))},n=()=>{i.removeEventListener("pointermove",r),i.removeEventListener("pointerup",n),i.removeEventListener("pointercancel",n),i.classList.remove("dragging"),gu()};i.addEventListener("pointermove",r),i.addEventListener("pointerup",n),i.addEventListener("pointercancel",n)}function cm(i,e){return jl(Oi(i)).map(t=>e?[$e(t)]:Xl(t))}var dm={annotation(i){let e=Ze(i),t=Jl(i);return!e&&!t?null:{triage:e?.triage,color:e?.color,comment:e?.comment,fix:e?.fix,flagged:e?.flagged===!0,ignored:t}},location:i=>Li(i,jt(i)),evidence:(i,e,t)=>Ia(i,e,jt(e),t),commit:i=>Da(i.repo?.github,i.commitHash),report:i=>i._reportName??null};function um(i,e){let t=new Set(i.map(s=>s.repo??null)),r=t.size===1?[...t][0]:null;if(r)return r;let n=new Set;for(let s of e)for(let o of s)o.repo?.github&&!Ri(o.file)&&n.add(o.repo.github);return n.size===1?[...n][0]:n.size===0&&!l.currentWorkspace&&l.repoUrl?l.repoUrl:null}function jn(i){return i.replace(/\.(?:json|md|codex)$/iu,"")}function wu(){return l.currentWorkspace?he().find(i=>i.id===l.currentWorkspace)??null:null}function pm(i,e){if(e)return e.name;let t=i.map(n=>n.fileName);return t.length===1?jn(t[0]):zt(t).replace(/[-_. ]+$/u,"")||`${t.length} reports`}function Vn({oneSamplePerGroup:i=!1}={}){let e=l.reports,t=zl(),r=Bn(),n=cm(r,i),s=wu(),o=e.flatMap(d=>d.groups??[]),c=o.some(d=>d.some(na)),u=o.some(d=>d.some(Ma));return oa({title:pm(e,s),workspace:s?.name??null,reports:e.map(d=>({name:d.fileName,source:d.source})),repo:um(e,n),generatedAt:new Date,view:{bucket:Nn(),severityMode:c?l.severityMode:null,revalidation:u?l.showRevalidation:null,revalidationDetail:u&&l.showRevalidation!==!1?Wl():null},filters:On(t),counts:{included:n.length,total:r.length},groups:n},dm)}function hm(){let i=wu(),e=l.reports.map(r=>r.fileName),t="";return i?t=i.name:e.length===1?t=jn(e[0]):e.length>1&&(t=jn(zt(e))),t=t.replaceAll(/[\\/:*?"<>|\p{Cc}]/gu,"-").trim(),`${t||"deepview-report"}.md`}function ku(i){if(l.reports.length===0)return;let e=new Blob([Vn(i)],{type:"text/markdown;charset=utf-8"});Ge(e,hm())}function rr(i){return!H()||!me.active||!l.currentManagedTeam?null:me.navigate(Jr({view:i,teamId:l.currentManagedTeam,reportId:l.currentManagedReport},l.managedTeams))}var Xn=!1;nl(()=>{if(Xn)return;Xn=!0;let i=2;function e(){--i===0&&mm()}requestAnimationFrame(e),setTimeout(e,350)});function mm(){Xn=!1,l.findingIndexTick++,l.currentView==="bundles"&&l.selectedBundle?$():l.currentView==="packages"?$():l.currentView==="repositories"?$():l.currentView==="links"?$():(l.currentView==="findings"||l.currentView==="files")&&(fe().catch(()=>{}),$())}var Kn=!1;sl(()=>{l.currentView!=="findings"&&l.currentView!=="files"&&!Xe()||Kn||(Kn=!0,queueMicrotask(()=>{Kn=!1,!(l.currentView!=="findings"&&l.currentView!=="files"&&!Xe())&&(l.bundleHashTick++,$())}))});dl(()=>{l.linksTick++,$()});function $u(){l.currentView==="bundles"&&l.bundleDetailsTab==="graph"?$d():Sd()}function lr(){l.currentView==="bundles"&&l.bundleDetailsTab==="graph"?xd():Cd()}function ti(){let i=document.querySelector(".bundle-source-code-wrap"),e=i?.scrollTop??0,t=i?.scrollLeft??0;$();let r=document.querySelector(".bundle-source-code-wrap");r&&(r.scrollTop=e,r.scrollLeft=t)}function rt(i){let t=document.querySelector(i)?.scrollTop??0;$();let r=document.querySelector(i);r&&(r.scrollTop=t)}function Me(){l.viewMode==="table"?rt(".findings-table-list"):$()}var Gn=0;function xu(){Gn||(Gn=requestAnimationFrame(()=>{Gn=0,$()}))}function B(i,e){for(let t of i.composedPath())if(t?.matches?.(e))return t;return null}function or(i,e){queueMicrotask(()=>{let t=document.querySelector(`.bundle-source-lineno-row[data-line="${i}"]`);t&&t.scrollIntoView(e)})}function Ru(i){i.classList.add("copied"),setTimeout(()=>i.classList.remove("copied"),1e3)}function nr(i,e){try{navigator.clipboard.writeText(e).then(()=>(Ru(i),null)).catch(()=>{})}catch{}}function Lu(i){let e=gn(l.bundleCodeHistory,l.bundleDetails?.integrity??null,l.bundleSourceFile);l.bundleCodeHistory=Hc(e,i),l.bundleSourceFile=i}function Wn(i=!1){queueMicrotask(()=>{let e=document.querySelector(".bundle-source-code-wrap");e&&(e.scrollTop=0,e.scrollLeft=0),i&&e?.querySelector(".bundle-source-code")?.focus({preventScroll:!0})})}window.addEventListener("hashchange",()=>{if(!H()||ga()||l.currentView!=="bundles"||l.bundleDetailsTab!=="code")return;let i=pa(new URL(location.href));if(i?.bundleTab!=="code"||i.file==null||i.file!==xc(l)?.file)return;let e=l.bundleSourceFile,t=i.endLine??i.line;l.bundleSourceTargetLine=i.line&&t<=ya(Si(l.bundleDetails).get(e)??"")?{bundle:l.bundleDetails?.integrity??null,path:e,line:i.line,...i.endLine?{end:i.endLine}:{}}:null,$(),l.bundleSourceTargetLine&&or(i.line,{block:"center"})});function Mu(i){let e=i.target.closest("[data-bundle-source-line]");if(e){let o=Number(e.dataset.bundleSourceLine),c=l.bundleDetails?.integrity??null,u=l.bundleSourceFile,d=l.bundleSourceTargetLine,p=d?.bundle===c&&d.path===u?d:null;if(i.shiftKey&&p){let h=p.anchor??p.line;l.bundleSourceTargetLine={bundle:c,path:u,line:Math.min(h,o),end:Math.max(h,o),anchor:h}}else p?.line===o&&!(p.end>o)?l.bundleSourceTargetLine=null:l.bundleSourceTargetLine={bundle:c,path:u,line:o};return ti(),!0}let t=i.target.closest("[data-bundle-source-wrap]");if(t){let o=Ac(t);l.bundleSourceWrap=!l.bundleSourceWrap;try{localStorage.setItem(Za,String(l.bundleSourceWrap))}catch{}return $(),queueMicrotask(o),!0}if(i.target.closest("[data-bundle-source-pretty]"))return Yt(),$(),Wn(),!0;let r=i.target.closest("[data-bundle-code-history]");if(r){let o=gn(l.bundleCodeHistory,l.bundleDetails?.integrity??null,l.bundleSourceFile),c=Uc(o,r.dataset.bundleCodeHistory==="back"?-1:1),u=c.files[c.at];return c.at===o.at||!Si(l.bundleDetails).has(u)||(l.bundleCodeHistory=c,l.bundleSourceFile=u,l.bundleSourceFindingIdx=null,l.bundleCodeSearchMode="files",l.bundleCodeSearchQuery="",rt(".bundle-code-rail-body"),Qt(),Wn()),!0}let n=i.target.closest("[data-bundle-source-link]");if(n){let o=n.dataset.bundleSourceLink,c=n.closest(".focus-pane-code");if(c){let u=ii(i),d=pc(u,c.dataset.focusCodeIntegrity,c.dataset.focusCodeFile,o);return d&&(ts(u,d),queueMicrotask(()=>c.querySelector(".focus-code-source")?.focus({preventScroll:!0}))),!0}return Si(l.bundleDetails).has(o)&&(l.currentView==="bundles"&&l.bundleDetailsTab==="search"&&(_t("code",{preserveSource:!0}),l.selectedBundle&&Be(l.selectedBundle,"code",{push:!0})),Lu(o),l.bundleSourceFindingIdx=null,l.bundleDetailsTab==="code"&&(l.bundleCodeSearchMode="files",l.bundleCodeSearchQuery=""),rt(".bundle-code-rail-body"),Qt(),Wn(!0)),!0}if(i.target.classList?.contains("bundle-source-overlay")||i.target.closest('[data-action="bundle-source-close"]'))return l.bundleSourceFile&&(_t(l.bundleDetailsTab),$()),!0;if(i.target.closest('[data-action="bundle-source-panel-close"]'))return l.bundleSourceFindingIdx!=null&&(l.bundleSourceFindingIdx=null,ti()),!0;let s=i.target.closest("[data-bundle-source-finding]");if(s){let o=parseInt(s.dataset.bundleSourceFinding,10);return Number.isFinite(o)&&(l.bundleSourceFindingIdx=l.bundleSourceFindingIdx===o?null:o,ti()),!0}return!1}function Su(i){let e=ii(i);if(!e)return null;let t=$e(e);return Oa(t,Ql(t))}R.addEventListener("click",i=>{if(B(i,"[data-finding-history]")){let w=ii(i),C=w&&$e(w);Sl(C)&&Dd(C);return}let e=B(i,"[data-code-nav-file]");if(e){ts(ii(i),{integrity:e.dataset.codeNavIntegrity,file:e.dataset.codeNavFile,range:Fe(e.dataset.codeNavLine)});return}let t=B(i,"[data-code-history]");if(t){gm(t.dataset.codeHistory==="forward"?1:-1);return}let r=B(i,"[data-code-preview]");if(r){let w=r.dataset.codePreview,C=new Set(l.codePreviews);C.delete(w)||C.add(w),l.codePreviews=C,$();return}let n=B(i,"[data-finding-code-report]");if(n&&H()){Xd({reportId:n.dataset.findingCodeReport,file:n.dataset.findingCodeFile,line:n.dataset.findingCodeLine});return}let s=B(i,"[data-finding-code-bundle]");if(s){let w=s.dataset.findingCodeBundle,C=s.dataset.findingCodeFile,P=s.dataset.findingCodeLine,L=P?parseInt(P,10):null;l.bundleSourceFile=C||null,l.bundleCodeHistory=null,l.bundleSourceFindingIdx=null,(l.bundleDetailsTab==="code"||l.bundleDetailsTab==="search")&&(l.bundleDetailsTab="overview");let V=()=>{Number.isFinite(L)&&or(L,{block:"start",behavior:"instant"})};if(l.selectedBundle===w&&l.bundleDetails?.integrity===w){$(),zi().then(()=>(l.selectedBundle===w&&l.bundleSourceFile===C&&V(),null));return}l.selectedBundle=w,l.selectedBundleWorkspace=null,l.bundleDetails=null,$(),(async()=>(await wt(w),V()))();return}let o=i.target.closest("[data-package-expand]");if(o){let w=o.dataset.packageExpand;l.expandedPackages.has(w)?l.expandedPackages.delete(w):l.expandedPackages.add(w),$();return}let c=i.target.closest("[data-package-row-issues]");if(c){let w=c.dataset.packageRowIssues,C=c.dataset.packageRowIssuesVersion;l.selectedPackage=w,l.selectedPackageVersion=C||null,l.packageDetailsTab="issues",l.packageSlideTriage=null,l.packageSlideTransient=!0,$();return}let u=i.target.closest("[data-repository-row-issues]");if(u){let w=u.dataset.repositoryRowIssues;l.selectedRepository=w,l.repositoryDetailsTab="issues",l.repositorySlideTriage=null,l.repositorySlideTransient=!0,$();return}let d=i.target.closest("[data-select-package]");if(d){let w=d.dataset.selectPackage,C=d.dataset.selectPackageVersion??"",P=C===""?null:C;if(l.selectedPackage===w&&l.selectedPackageVersion===P)return;l.selectedPackage=w,l.selectedPackageVersion=P,l.packageDetailsTab="overview",l.packageSlideTriage=null,l.packageSlideTransient=!1,$();return}if(i.target.closest("[data-deselect-package]")){l.selectedPackage=null,l.selectedPackageVersion=null,$();return}let p=i.target.closest("[data-package-tab]");if(p){let w=p.dataset.packageTab;(w==="overview"||w==="issues")&&l.packageDetailsTab!==w&&(l.packageDetailsTab=w,$());return}if(i.target.closest('[data-action="package-slide-back"]')){l.packageDetailsTab="overview",l.packageSlideTriage=null,l.packageSlideTransient&&(l.selectedPackage=null,l.selectedPackageVersion=null,l.packageSlideTransient=!1),$();return}let h=B(i,"[data-links-report][data-links-finding]");if(h){i.preventDefault();let{linksReport:w,linksFinding:C,managedReport:P}=h.dataset;w&&C&&(async()=>{let L=await Tn(C,w,P);L.ok||alert(L.reason)})().catch(L=>console.warn("links: reveal in report failed:",L));return}let f=i.target.closest("[data-package-report]");if(f){let w=f.dataset.packageReport;w&&tt(w);return}let b=i.target.closest("[data-select-repository]");if(b){let w=b.dataset.selectRepository;if(l.selectedRepository===w)return;l.selectedRepository=w,l.repositoryDetailsTab="overview",l.repositorySlideTriage=null,l.repositorySlideTransient=!1,$();return}if(i.target.closest("[data-deselect-repository]")){l.selectedRepository=null,$();return}let v=i.target.closest("[data-repository-tab]");if(v){let w=v.dataset.repositoryTab;(w==="overview"||w==="issues")&&l.repositoryDetailsTab!==w&&(l.repositoryDetailsTab=w,$());return}if(i.target.closest('[data-action="repository-slide-back"]')){l.repositoryDetailsTab="overview",l.repositorySlideTriage=null,l.repositorySlideTransient&&(l.selectedRepository=null,l.repositorySlideTransient=!1),$();return}let g=i.target.closest("[data-bundle-tab]");if(g){let w=g.dataset.bundleTab;if(ki.has(w)||w==="review"&&l.bundleDetails?.npm){if(w===l.bundleDetailsTab){l.selectedBundle&&Be(l.selectedBundle,w);return}l.bundleDetailsTab==="graph"&&w!=="graph"&&(oe(),document.body.classList.remove("report-fullscreen")),Sc(l,w,C=>Kc(C)?.oldVersion??null),_t(w),l.selectedBundle&&Be(l.selectedBundle,w,{push:!0}),$(),w==="code"&&zi().then(()=>(l.bundleDetailsTab==="code"&&Qt(),null))}return}if(i.target.closest("[data-bundle-retry-sources]")){l.bundleDetails&&delete l.bundleDetails.sourceError,$();return}let y=i.target.closest("[data-bundle-download]");if(y){let w=y.dataset.bundleDownload,C=(l.bundles??[]).find(P=>P.integrity===w);if(!C)return;(async()=>{let{confirmed:P}=await Qd({name:C.name,encrypted:we()});if(P)try{let L=await rl(w);Ge(new Blob([L],{type:"application/octet-stream"}),C.name)}catch(L){alert(`Failed to download bundle: ${L.message}`)}})();return}let k=i.target.closest("[data-bundle-export-sbom]");if(k){let w=k.dataset.bundleExportSbom,C=l.bundleDetails,P=(l.bundles??[]).find(L=>L.integrity===l.selectedBundle);if(!P||!C||C.integrity!==P.integrity)return;try{let L=w==="cyclonedx",V=L?bd(C,P):vd(C,P),ae=`${gd(P.name)}.${L?"cdx":"spdx"}.json`;Ge(new Blob([V],{type:"application/json"}),ae)}catch(L){alert(`Failed to export ${w==="cyclonedx"?"CycloneDX":"SPDX"}: ${L.message}`)}return}if(B(i,"[data-bundle-search-context]")){l.bundleSearchContext=!l.bundleSearchContext,rt(".bundle-search-results");return}if(i.target.closest("[data-advisories-consent]")){wd(),$();return}if(i.target.closest("[data-advisories-retry]")){kd(l.bundleDetails,$).catch(()=>{}),$();return}let x=i.target.closest("[data-bundle-issue-report]");if(x){let w=x.dataset.bundleIssueReport;w&&tt(w);return}if(Mu(i))return;let S=i.target.closest("[data-bundle-code-issue-step]");if(S){let w=S.closest("[data-bundle-code-issue-order]"),C=null;try{C=JSON.parse(w?.dataset.bundleCodeIssueOrder??"null")}catch{}if(Array.isArray(C)&&C.length>0){let P=S.dataset.bundleCodeIssueStep==="-1"?-1:1,L=C.findIndex(ae=>ae.idx===l.bundleSourceFindingIdx),V=L===-1?P>0?C[0]:C.at(-1):C[(L+P+C.length)%C.length];l.bundleSourceFindingIdx=V.idx,ti(),V.line>0&&or(V.line,{block:"center",behavior:"smooth"})}return}let T=B(i,"[data-bundle-view-source]");if(T){let w=T.dataset.bundleViewSource;if(!w)return;let C=T.dataset.bundleViewFindingIdx,P=C===void 0?null:parseInt(C,10),L=T.dataset.bundleViewLine,V=L?parseInt(L,10):null;Number.isFinite(V)&&(l.bundleSourcePretty=!1);let ae=l.bundleSourceFile!==w;if(Lu(w),Number.isFinite(P)?l.bundleSourceFindingIdx=P:ae&&(l.bundleSourceFindingIdx=null),l.bundleSourceTargetLine=Number.isFinite(V)?{bundle:l.bundleDetails?.integrity??null,path:w,line:V}:null,T.closest(".bundle-code-rail")?rt(".bundle-code-rail-body"):T.closest(".bundle-search-results")?rt(".bundle-search-results"):T.closest(".bundles-slide-body")?rt(".bundles-slide-body"):$(),Number.isFinite(V)){let ve=T.dataset.bundleViewScrollBlock||"center";zi().then(()=>(l.bundleSourceFile===w&&or(V,{block:ve,behavior:"smooth"}),null))}return}let F=i.target.closest('[data-action="workspace-reports"], [data-action="workspace-bundles"]');if(F){let w=F.dataset.action.slice(10);l.currentView!==`workspace-${w}`&&Xi(l.currentManagedTeam??l.currentWorkspace,w);return}if(i.target.closest('[data-action="workspace-findings"]')){if(l.currentView==="findings")return;if(l.currentView==="files"){if(rr("findings"))return;l.currentView="findings",l.filesSelectedFile=null,document.body.classList.remove("report-fullscreen"),$()}else H()?Cn(l.managedTeams.find(w=>w.id===l.currentManagedTeam)):it(l.currentWorkspace);return}let O=i.target.closest("[data-workspace-report]");if(O){H()?Cn(l.managedTeams.find(w=>w.id===l.currentManagedTeam),O.dataset.workspaceReport):tt(O.dataset.workspaceReport,void 0,{workspaceId:l.currentWorkspace});return}let A=i.target.closest("[data-workspace-bundle]");if(A){if(H())me.navigate(Jr({view:"bundles",teamId:l.currentManagedTeam,bundleId:A.dataset.workspaceBundle,bundleTab:"overview"},l.managedTeams));else{let w=A.dataset.workspaceBundle;Kt(w,"overview",{workspaceId:l.currentWorkspace}),Be(w,"overview"),$(),fe(),wt(w)}return}if(i.target.closest('[data-action="toggle-files"]')){if(rr(l.currentView==="files"?"findings":"files"))return;if(l.currentView==="workspace-reports"||l.currentView==="workspace-bundles"){l.currentView="files",it(l.currentWorkspace);return}l.currentView==="files"?l.currentView="findings":(l.viewMode==="graph"&&oe(),l.currentView="files"),document.body.classList.remove("report-fullscreen"),$();return}let Z=B(i,"[data-g2-pkg]");if(Z){let w=Z.dataset.g2Pkg;E.solo=E.solo===w?null:w,E.solo&&(E.selected=null),$u(),lr(),E.graphState?.requestDraw?.();return}let re=B(i,"[data-g2-select]");if(re){E.selected=re.dataset.g2Select,$u(),E.graphState?.requestDraw?.();return}let ne=B(i,"[data-g2-top-pkgs]");if(ne){E.topPkgsTab=ne.dataset.g2TopPkgs,lr();return}let jr=B(i,"[data-g2-jump-findings]");if(jr){if(l.currentView==="bundles"){l.bundleDetailsTab==="graph"&&oe(),_t("issues"),l.selectedBundle&&Be(l.selectedBundle,"issues",{push:!0}),$();return}if(Bl(),l.filterConfMin=0,l.filterInclude=jr.dataset.g2JumpFindings,l.currentView="findings",l.viewMode==="graph"&&(l.viewMode="table"),oe(),rr("findings"))return;$();return}let se=B(i,"[data-g2-jump-file]");if(se){let w=se.dataset.g2JumpFile;oe();let C=()=>requestAnimationFrame(()=>{let L=document.querySelector(`#${qa(w)}`);L&&L.scrollIntoView({behavior:"smooth",block:"start"})}),P=rr("files");if(P){P.then(L=>L?C():void 0);return}l.currentView="files",$(),C();return}if(B(i,"#g2-path-filter-clear")){E.pathFilter="";let w=document.querySelector("graph-layout")?.shadowRoot?.querySelector("#g2-path-filter");w&&(w.value=""),E.graphState?.requestDraw?.();return}if(B(i,"#g2-fullscreen")){document.body.classList.toggle("report-fullscreen");return}if(B(i,"[data-g2-show-all]")){E.showAll=!E.showAll,E.layoutCache=null,E.selected=null,oe(),$();return}if(B(i,"[data-g2-packages-view]")){E.bundleLayout==="flow"?E.flowPackagesView=!E.flowPackagesView:E.bundleLayout==="dependencies"?(E.dependencyPackagesView=!E.dependencyPackagesView,E.solo=null):E.packagesView=!E.packagesView,E.layoutCache=null,E.selected=null,E.focusedPkg=null,oe(),$();return}if(B(i,"[data-g2-bundle-issues]")){E.bundleIssues=!E.bundleIssues,oe({keepViewport:!0}),$();return}let Dt=B(i,"[data-g2-layout]");if(Dt){let w=Dt.dataset.g2Layout;if(!["graph","layers","matrix","dependencies","flow"].includes(w)||E.bundleLayout===w&&!E.focusedPkg)return;E.bundleLayout=w,w==="dependencies"&&(E.dependencyPackagesView=!1),E.layoutCache=null,E.selected=null,E.solo=null,E.focusedPkg=null,oe(),$();return}let hi=B(i,".graph2-triage-selector [data-triage-show]");if(hi){let w=hi.dataset.triageShow;l.shownTriage=l.shownTriage===w?null:w,E.layoutCache=null,E.selected=null,oe(),$();return}let mi=B(i,"[data-g2-focus-pkg]");if(mi){E.focusedPkg=mi.dataset.g2FocusPkg,E.layoutCache=null,oe(),$();return}if(B(i,"#g2-back-to-full")){E.focusedPkg=null,E.layoutCache=null,(E.packagesView||E.bundleLayout==="layers")&&(E.selected=null),oe(),$();return}let dt=B(i,".tab");if(dt&&B(i,".tabs")){let C=B(i,"[data-gid]").dataset.gid,P=dt.dataset.tid;l.activeTabByGroup.set(C,P),Me();return}let je=B(i,"[data-triage-action]");if(je){let w=je.closest(".triage-menu"),C=w?.dataset.gid;if(!C)return;let P=de(C);if(!P)return;let L=je.dataset.triageAction;if(!["inprogress","fixed","invalid","deleted","ignored","restore"].includes(L))return;let{targets:V,clearing:ae}=tc(P,L);if(V.length===0)return;Pu(V,ae?"untriaged":L);try{w.hidePopover()}catch{}ke(),Me();return}if(B(i,".mark-comment")){let C=B(i,"[data-gid]").dataset.gid,P=de(C);if(!P)return;let L=$e(P);if(!Yl(L))return;if(H()){import("./chunk-UZAZM2SX.js").then(({openManagedCommentsDialog:ve})=>ve(L,Me)).catch(()=>Oe("Could not open comments. Please retry."));return}let V=mt(L),ae=Ze(L)?.comment??"";Yd({initial:ae,finding:L}).then(ve=>(ve===null||!De(L)||(X(l.triage,V,{comment:ve||void 0}),ke(),Me()),null)).catch(()=>{});return}let fi=B(i,".mark-copy");if(fi){let w=Su(i);if(w===null)return;nr(fi,w);return}let zo=B(i,".mark-link");if(zo){let w=B(i,"[data-gid]"),C=w?de(w.dataset.gid):null;if(!C)return;let P=hc($e(C));if(!P)return;nr(zo,P);return}let Kr=B(i,"[data-copy-report]");if(Kr){nr(Kr,Kr.dataset.copyReport);return}let Gr=B(i,"[data-copy-path]");if(Gr){nr(Gr,Gr.dataset.copyPath);return}let qo=B(i,".mark-issue");if(qo&&H()&&l.managedSession&&!l.managedSession.publicShare&&l.currentManagedTeam){let w=B(i,"[data-gid]"),C=w?de(w.dataset.gid):null,P=C?$e(C):null;if(P?._managedReportId&&P.id){i.preventDefault();let L=new URL(qo.dataset.issueForm);Fd({teamId:l.currentManagedTeam,session:{...l.managedSession},context:{reportId:P._managedReportId,findingId:P.id,repository:L.pathname.split("/").slice(1,3).join("/")},formUrl:L.href,title:L.searchParams.get("title")??"",body:L.searchParams.get("body")??"",finding:P,draftOptions:{sourceUrl:Li(P,jt(P)),evidence:Fa(P),showRevalidation:La()},renderBody:vc}).catch(()=>Oe("Could not open issue creation. Please retry."));return}}let Ho=B(i,".mark-claude");if(Ho){let w=Su(i);if(w===null)return;let C=`claude://code/new?q=${encodeURIComponent(`Confirm and fix:
34
+ `;var lm={revalidate:"Outcome",revalidateVerdict:"Explanation",revalidateRecommendation:"Recommendation"},Un=class extends q{static styles=[...q.styles,M(bt),M($t),M(pu)];static properties={conflicts:{attribute:!1}};constructor(){super(),this.conflicts=[]}render(){return a`<dialog aria-labelledby="revalidation-conflicts-title" @close="${this._onClose}"><header><h3 id="revalidation-conflicts-title">Revalidation conflicts</h3><p class="nwd-intro">Reports disagree about ${this.conflicts.length} finding${this.conflicts.length===1?"":"s"}. App view is unavailable until the conflicting reports are separated or updated.</p></header><ul class="conflicts-list">${this.conflicts.map(({finding:e,copies:t})=>a`<li class="conflict-card"><div class="finding-meta">${vt(e.severity)} ${e.file?a`<span class="location">${e.file}${Fe(e.line)?`:${Aa(Fe(e.line))}`:""}</span>`:m} <code>${Ba(e.id)??e.id}</code></div><h4>${Bt(e)}</h4><dl>${Vl(t).map(({field:r,variants:n})=>a`<dt>${lm[r]??r}</dt>${n.map(({value:s,reports:o})=>a`<dd class="variant"><div class="value">${s||a`<em>Empty</em>`}</div><div class="reports">${o.map(c=>c?a`<button type="button" class="report-button" aria-label="${`Open ${Qr(c)} at this finding`}" @click="${()=>this._finish({id:e.id,reportName:c})}">${J(Xr[Ll(c)]??Xr.default)}<span>${Qr(c)}</span></button>`:a`<span>Loaded report</span>`)}</div></dd>`)}`)}</dl></li>`)}</ul><footer class="nwd-actions"><span class="nwd-spacer"></span><button type="button" @click="${this._onClose}">Close</button></footer></dialog>`}};customElements.define("revalidation-conflicts-dialog",Un);function hu(i){return Y("revalidation-conflicts-dialog",{conflicts:[...i.values()]})}var mu=2;function fu(i,e){l.focusSplit=e,i.closest(".focus-main")?.style.setProperty("--focus-split",String(e)),i.setAttribute("aria-valuenow",String(Math.round(e)))}function gu(){try{localStorage.setItem(Xa,String(l.focusSplit))}catch{}}function bu(i,e){fu(i,on(e)),gu()}function vu(i,e){bu(i,l.focusSplit+e)}function yu(i){bu(i,el)}function _u(i,e){let t=i.closest(".focus-main");if(!t)return;e.preventDefault(),i.classList.add("dragging");try{i.setPointerCapture(e.pointerId)}catch{}let r=s=>{let o=t.getBoundingClientRect();o.width!==0&&fu(i,on((s.clientX-o.left)/o.width*100))},n=()=>{i.removeEventListener("pointermove",r),i.removeEventListener("pointerup",n),i.removeEventListener("pointercancel",n),i.classList.remove("dragging"),gu()};i.addEventListener("pointermove",r),i.addEventListener("pointerup",n),i.addEventListener("pointercancel",n)}function cm(i,e){return jl(Oi(i)).map(t=>e?[$e(t)]:Xl(t))}var dm={annotation(i){let e=Ze(i),t=Jl(i);return!e&&!t?null:{triage:e?.triage,color:e?.color,comment:e?.comment,fix:e?.fix,flagged:e?.flagged===!0,ignored:t}},location:i=>Li(i,jt(i)),evidence:(i,e,t)=>Ia(i,e,jt(e),t),commit:i=>Da(i.repo?.github,i.commitHash),report:i=>i._reportName??null};function um(i,e){let t=new Set(i.map(s=>s.repo??null)),r=t.size===1?[...t][0]:null;if(r)return r;let n=new Set;for(let s of e)for(let o of s)o.repo?.github&&!Ri(o.file)&&n.add(o.repo.github);return n.size===1?[...n][0]:n.size===0&&!l.currentWorkspace&&l.repoUrl?l.repoUrl:null}function jn(i){return i.replace(/\.(?:json|md|codex)$/iu,"")}function wu(){return l.currentWorkspace?he().find(i=>i.id===l.currentWorkspace)??null:null}function pm(i,e){if(e)return e.name;let t=i.map(n=>n.fileName);return t.length===1?jn(t[0]):zt(t).replace(/[-_. ]+$/u,"")||`${t.length} reports`}function Vn({oneSamplePerGroup:i=!1}={}){let e=l.reports,t=zl(),r=Bn(),n=cm(r,i),s=wu(),o=e.flatMap(d=>d.groups??[]),c=o.some(d=>d.some(na)),u=o.some(d=>d.some(Ma));return oa({title:pm(e,s),workspace:s?.name??null,reports:e.map(d=>({name:d.fileName,source:d.source})),repo:um(e,n),generatedAt:new Date,view:{bucket:Nn(),severityMode:c?l.severityMode:null,revalidation:u?l.showRevalidation:null,revalidationDetail:u&&l.showRevalidation!==!1?Wl():null},filters:On(t),counts:{included:n.length,total:r.length},groups:n},dm)}function hm(){let i=wu(),e=l.reports.map(r=>r.fileName),t="";return i?t=i.name:e.length===1?t=jn(e[0]):e.length>1&&(t=jn(zt(e))),t=t.replaceAll(/[\\/:*?"<>|\p{Cc}]/gu,"-").trim(),`${t||"deepview-report"}.md`}function ku(i){if(l.reports.length===0)return;let e=new Blob([Vn(i)],{type:"text/markdown;charset=utf-8"});Ge(e,hm())}function rr(i){return!H()||!me.active||!l.currentManagedTeam?null:me.navigate(Jr({view:i,teamId:l.currentManagedTeam,reportId:l.currentManagedReport},l.managedTeams))}var Xn=!1;nl(()=>{if(Xn)return;Xn=!0;let i=2;function e(){--i===0&&mm()}requestAnimationFrame(e),setTimeout(e,350)});function mm(){Xn=!1,l.findingIndexTick++,l.currentView==="bundles"&&l.selectedBundle?$():l.currentView==="packages"?$():l.currentView==="repositories"?$():l.currentView==="links"?$():(l.currentView==="findings"||l.currentView==="files")&&(fe().catch(()=>{}),$())}var Kn=!1;sl(()=>{l.currentView!=="findings"&&l.currentView!=="files"&&!Xe()||Kn||(Kn=!0,queueMicrotask(()=>{Kn=!1,!(l.currentView!=="findings"&&l.currentView!=="files"&&!Xe())&&(l.bundleHashTick++,$())}))});dl(()=>{l.linksTick++,$()});function $u(){l.currentView==="bundles"&&l.bundleDetailsTab==="graph"?$d():Sd()}function lr(){l.currentView==="bundles"&&l.bundleDetailsTab==="graph"?xd():Cd()}function ti(){let i=document.querySelector(".bundle-source-code-wrap"),e=i?.scrollTop??0,t=i?.scrollLeft??0;$();let r=document.querySelector(".bundle-source-code-wrap");r&&(r.scrollTop=e,r.scrollLeft=t)}function rt(i){let t=document.querySelector(i)?.scrollTop??0;$();let r=document.querySelector(i);r&&(r.scrollTop=t)}function Me(){l.viewMode==="table"?rt(".findings-table-list"):$()}var Gn=0;function xu(){Gn||(Gn=requestAnimationFrame(()=>{Gn=0,$()}))}function B(i,e){for(let t of i.composedPath())if(t?.matches?.(e))return t;return null}function or(i,e){queueMicrotask(()=>{let t=document.querySelector(`.bundle-source-lineno-row[data-line="${i}"]`);t&&t.scrollIntoView(e)})}function Ru(i){i.classList.add("copied"),setTimeout(()=>i.classList.remove("copied"),1e3)}function nr(i,e){try{navigator.clipboard.writeText(e).then(()=>(Ru(i),null)).catch(()=>{})}catch{}}function Lu(i){let e=gn(l.bundleCodeHistory,l.bundleDetails?.integrity??null,l.bundleSourceFile);l.bundleCodeHistory=Hc(e,i),l.bundleSourceFile=i}function Wn(i=!1){queueMicrotask(()=>{let e=document.querySelector(".bundle-source-code-wrap");e&&(e.scrollTop=0,e.scrollLeft=0),i&&e?.querySelector(".bundle-source-code")?.focus({preventScroll:!0})})}window.addEventListener("hashchange",()=>{if(!H()||ga()||l.currentView!=="bundles"||l.bundleDetailsTab!=="code")return;let i=pa(new URL(location.href));if(i?.bundleTab!=="code"||i.file==null||i.file!==xc(l)?.file)return;let e=l.bundleSourceFile,t=i.endLine??i.line;l.bundleSourceTargetLine=i.line&&t<=ya(Si(l.bundleDetails).get(e)??"")?{bundle:l.bundleDetails?.integrity??null,path:e,line:i.line,...i.endLine?{end:i.endLine}:{}}:null,$(),l.bundleSourceTargetLine&&or(i.line,{block:"center"})});function Mu(i){let e=i.target.closest("[data-bundle-source-line]");if(e){let o=Number(e.dataset.bundleSourceLine),c=l.bundleDetails?.integrity??null,u=l.bundleSourceFile,d=l.bundleSourceTargetLine,p=d?.bundle===c&&d.path===u?d:null;if(i.shiftKey&&p){let h=p.anchor??p.line;l.bundleSourceTargetLine={bundle:c,path:u,line:Math.min(h,o),end:Math.max(h,o),anchor:h}}else p?.line===o&&!(p.end>o)?l.bundleSourceTargetLine=null:l.bundleSourceTargetLine={bundle:c,path:u,line:o};return ti(),!0}let t=i.target.closest("[data-bundle-source-wrap]");if(t){let o=Ac(t);l.bundleSourceWrap=!l.bundleSourceWrap;try{localStorage.setItem(Za,String(l.bundleSourceWrap))}catch{}return $(),queueMicrotask(o),!0}if(i.target.closest("[data-bundle-source-pretty]"))return Yt(),$(),Wn(),!0;let r=i.target.closest("[data-bundle-code-history]");if(r){let o=gn(l.bundleCodeHistory,l.bundleDetails?.integrity??null,l.bundleSourceFile),c=Uc(o,r.dataset.bundleCodeHistory==="back"?-1:1),u=c.files[c.at];return c.at===o.at||!Si(l.bundleDetails).has(u)||(l.bundleCodeHistory=c,l.bundleSourceFile=u,l.bundleSourceFindingIdx=null,l.bundleCodeSearchMode="files",l.bundleCodeSearchQuery="",rt(".bundle-code-rail-body"),Qt(),Wn()),!0}let n=i.target.closest("[data-bundle-source-link]");if(n){let o=n.dataset.bundleSourceLink,c=n.closest(".focus-pane-code");if(c){let u=ii(i),d=pc(u,c.dataset.focusCodeIntegrity,c.dataset.focusCodeFile,o);return d&&(ts(u,d),queueMicrotask(()=>c.querySelector(".focus-code-source")?.focus({preventScroll:!0}))),!0}return Si(l.bundleDetails).has(o)&&(l.currentView==="bundles"&&l.bundleDetailsTab==="search"&&(_t("code",{preserveSource:!0}),l.selectedBundle&&Be(l.selectedBundle,"code",{push:!0})),Lu(o),l.bundleSourceFindingIdx=null,l.bundleDetailsTab==="code"&&(l.bundleCodeSearchMode="files",l.bundleCodeSearchQuery=""),rt(".bundle-code-rail-body"),Qt(),Wn(!0)),!0}if(i.target.classList?.contains("bundle-source-overlay")||i.target.closest('[data-action="bundle-source-close"]'))return l.bundleSourceFile&&(_t(l.bundleDetailsTab),$()),!0;if(i.target.closest('[data-action="bundle-source-panel-close"]'))return l.bundleSourceFindingIdx!=null&&(l.bundleSourceFindingIdx=null,ti()),!0;let s=i.target.closest("[data-bundle-source-finding]");if(s){let o=parseInt(s.dataset.bundleSourceFinding,10);return Number.isFinite(o)&&(l.bundleSourceFindingIdx=l.bundleSourceFindingIdx===o?null:o,ti()),!0}return!1}function Su(i){let e=ii(i);if(!e)return null;let t=$e(e);return Oa(t,Ql(t))}R.addEventListener("click",i=>{if(B(i,"[data-finding-history]")){let w=ii(i),C=w&&$e(w);Sl(C)&&Dd(C);return}let e=B(i,"[data-code-nav-file]");if(e){ts(ii(i),{integrity:e.dataset.codeNavIntegrity,file:e.dataset.codeNavFile,range:Fe(e.dataset.codeNavLine)});return}let t=B(i,"[data-code-history]");if(t){gm(t.dataset.codeHistory==="forward"?1:-1);return}let r=B(i,"[data-code-preview]");if(r){let w=r.dataset.codePreview,C=new Set(l.codePreviews);C.delete(w)||C.add(w),l.codePreviews=C,$();return}let n=B(i,"[data-finding-code-report]");if(n&&H()){Xd({reportId:n.dataset.findingCodeReport,file:n.dataset.findingCodeFile,line:n.dataset.findingCodeLine});return}let s=B(i,"[data-finding-code-bundle]");if(s){let w=s.dataset.findingCodeBundle,C=s.dataset.findingCodeFile,P=s.dataset.findingCodeLine,L=P?parseInt(P,10):null;l.bundleSourceFile=C||null,l.bundleCodeHistory=null,l.bundleSourceFindingIdx=null,(l.bundleDetailsTab==="code"||l.bundleDetailsTab==="search")&&(l.bundleDetailsTab="overview");let V=()=>{Number.isFinite(L)&&or(L,{block:"start",behavior:"instant"})};if(l.selectedBundle===w&&l.bundleDetails?.integrity===w){$(),zi().then(()=>(l.selectedBundle===w&&l.bundleSourceFile===C&&V(),null));return}l.selectedBundle=w,l.selectedBundleWorkspace=null,l.bundleDetails=null,$(),(async()=>(await wt(w),V()))();return}let o=i.target.closest("[data-package-expand]");if(o){let w=o.dataset.packageExpand;l.expandedPackages.has(w)?l.expandedPackages.delete(w):l.expandedPackages.add(w),$();return}let c=i.target.closest("[data-package-row-issues]");if(c){let w=c.dataset.packageRowIssues,C=c.dataset.packageRowIssuesVersion;l.selectedPackage=w,l.selectedPackageVersion=C||null,l.packageDetailsTab="issues",l.packageSlideTriage=null,l.packageSlideTransient=!0,$();return}let u=i.target.closest("[data-repository-row-issues]");if(u){let w=u.dataset.repositoryRowIssues;l.selectedRepository=w,l.repositoryDetailsTab="issues",l.repositorySlideTriage=null,l.repositorySlideTransient=!0,$();return}let d=i.target.closest("[data-select-package]");if(d){let w=d.dataset.selectPackage,C=d.dataset.selectPackageVersion??"",P=C===""?null:C;if(l.selectedPackage===w&&l.selectedPackageVersion===P)return;l.selectedPackage=w,l.selectedPackageVersion=P,l.packageDetailsTab="overview",l.packageSlideTriage=null,l.packageSlideTransient=!1,$();return}if(i.target.closest("[data-deselect-package]")){l.selectedPackage=null,l.selectedPackageVersion=null,$();return}let p=i.target.closest("[data-package-tab]");if(p){let w=p.dataset.packageTab;(w==="overview"||w==="issues")&&l.packageDetailsTab!==w&&(l.packageDetailsTab=w,$());return}if(i.target.closest('[data-action="package-slide-back"]')){l.packageDetailsTab="overview",l.packageSlideTriage=null,l.packageSlideTransient&&(l.selectedPackage=null,l.selectedPackageVersion=null,l.packageSlideTransient=!1),$();return}let h=B(i,"[data-links-report][data-links-finding]");if(h){i.preventDefault();let{linksReport:w,linksFinding:C,managedReport:P}=h.dataset;w&&C&&(async()=>{let L=await Tn(C,w,P);L.ok||alert(L.reason)})().catch(L=>console.warn("links: reveal in report failed:",L));return}let f=i.target.closest("[data-package-report]");if(f){let w=f.dataset.packageReport;w&&tt(w);return}let b=i.target.closest("[data-select-repository]");if(b){let w=b.dataset.selectRepository;if(l.selectedRepository===w)return;l.selectedRepository=w,l.repositoryDetailsTab="overview",l.repositorySlideTriage=null,l.repositorySlideTransient=!1,$();return}if(i.target.closest("[data-deselect-repository]")){l.selectedRepository=null,$();return}let v=i.target.closest("[data-repository-tab]");if(v){let w=v.dataset.repositoryTab;(w==="overview"||w==="issues")&&l.repositoryDetailsTab!==w&&(l.repositoryDetailsTab=w,$());return}if(i.target.closest('[data-action="repository-slide-back"]')){l.repositoryDetailsTab="overview",l.repositorySlideTriage=null,l.repositorySlideTransient&&(l.selectedRepository=null,l.repositorySlideTransient=!1),$();return}let g=i.target.closest("[data-bundle-tab]");if(g){let w=g.dataset.bundleTab;if(ki.has(w)||w==="review"&&l.bundleDetails?.npm){if(w===l.bundleDetailsTab){l.selectedBundle&&Be(l.selectedBundle,w);return}l.bundleDetailsTab==="graph"&&w!=="graph"&&(oe(),document.body.classList.remove("report-fullscreen")),Sc(l,w,C=>Kc(C)?.oldVersion??null),_t(w),l.selectedBundle&&Be(l.selectedBundle,w,{push:!0}),$(),w==="code"&&zi().then(()=>(l.bundleDetailsTab==="code"&&Qt(),null))}return}if(i.target.closest("[data-bundle-retry-sources]")){l.bundleDetails&&delete l.bundleDetails.sourceError,$();return}let y=i.target.closest("[data-bundle-download]");if(y){let w=y.dataset.bundleDownload,C=(l.bundles??[]).find(P=>P.integrity===w);if(!C)return;(async()=>{let{confirmed:P}=await Qd({name:C.name,encrypted:we()});if(P)try{let L=await rl(w);Ge(new Blob([L],{type:"application/octet-stream"}),C.name)}catch(L){alert(`Failed to download bundle: ${L.message}`)}})();return}let k=i.target.closest("[data-bundle-export-sbom]");if(k){let w=k.dataset.bundleExportSbom,C=l.bundleDetails,P=(l.bundles??[]).find(L=>L.integrity===l.selectedBundle);if(!P||!C||C.integrity!==P.integrity)return;try{let L=w==="cyclonedx",V=L?bd(C,P):vd(C,P),ae=`${gd(P.name)}.${L?"cdx":"spdx"}.json`;Ge(new Blob([V],{type:"application/json"}),ae)}catch(L){alert(`Failed to export ${w==="cyclonedx"?"CycloneDX":"SPDX"}: ${L.message}`)}return}if(B(i,"[data-bundle-search-context]")){l.bundleSearchContext=!l.bundleSearchContext,rt(".bundle-search-results");return}if(i.target.closest("[data-advisories-consent]")){wd(),$();return}if(i.target.closest("[data-advisories-retry]")){kd(l.bundleDetails,$).catch(()=>{}),$();return}let x=i.target.closest("[data-bundle-issue-report]");if(x){let w=x.dataset.bundleIssueReport;w&&tt(w);return}if(Mu(i))return;let S=i.target.closest("[data-bundle-code-issue-step]");if(S){let w=S.closest("[data-bundle-code-issue-order]"),C=null;try{C=JSON.parse(w?.dataset.bundleCodeIssueOrder??"null")}catch{}if(Array.isArray(C)&&C.length>0){let P=S.dataset.bundleCodeIssueStep==="-1"?-1:1,L=C.findIndex(ae=>ae.idx===l.bundleSourceFindingIdx),V=L===-1?P>0?C[0]:C.at(-1):C[(L+P+C.length)%C.length];l.bundleSourceFindingIdx=V.idx,ti(),V.line>0&&or(V.line,{block:"center",behavior:"smooth"})}return}let T=B(i,"[data-bundle-view-source]");if(T){let w=T.dataset.bundleViewSource;if(!w)return;let C=T.dataset.bundleViewFindingIdx,P=C===void 0?null:parseInt(C,10),L=T.dataset.bundleViewLine,V=L?parseInt(L,10):null;Number.isFinite(V)&&(l.bundleSourcePretty=!1);let ae=l.bundleSourceFile!==w;if(Lu(w),Number.isFinite(P)?l.bundleSourceFindingIdx=P:ae&&(l.bundleSourceFindingIdx=null),l.bundleSourceTargetLine=Number.isFinite(V)?{bundle:l.bundleDetails?.integrity??null,path:w,line:V}:null,T.closest(".bundle-code-rail")?rt(".bundle-code-rail-body"):T.closest(".bundle-search-results")?rt(".bundle-search-results"):T.closest(".bundles-slide-body")?rt(".bundles-slide-body"):$(),Number.isFinite(V)){let ve=T.dataset.bundleViewScrollBlock||"center";zi().then(()=>(l.bundleSourceFile===w&&or(V,{block:ve,behavior:"smooth"}),null))}return}let F=i.target.closest('[data-action="workspace-reports"], [data-action="workspace-bundles"]');if(F){let w=F.dataset.action.slice(10);l.currentView!==`workspace-${w}`&&Xi(l.currentManagedTeam??l.currentWorkspace,w);return}if(i.target.closest('[data-action="workspace-findings"]')){if(l.currentView==="findings")return;if(l.currentView==="files"){if(rr("findings"))return;l.currentView="findings",l.filesSelectedFile=null,document.body.classList.remove("report-fullscreen"),$()}else H()?Cn(l.managedTeams.find(w=>w.id===l.currentManagedTeam)):it(l.currentWorkspace);return}let O=i.target.closest("[data-workspace-report]");if(O){H()?Cn(l.managedTeams.find(w=>w.id===l.currentManagedTeam),O.dataset.workspaceReport):tt(O.dataset.workspaceReport,void 0,{workspaceId:l.currentWorkspace});return}let A=i.target.closest("[data-workspace-bundle]");if(A){if(H())me.navigate(Jr({view:"bundles",teamId:l.currentManagedTeam,bundleId:A.dataset.workspaceBundle,bundleTab:"overview"},l.managedTeams));else{let w=A.dataset.workspaceBundle;Kt(w,"overview",{workspaceId:l.currentWorkspace}),Be(w,"overview"),$(),fe(),wt(w)}return}if(i.target.closest('[data-action="toggle-files"]')){if(rr(l.currentView==="files"?"findings":"files"))return;if(l.currentView==="workspace-reports"||l.currentView==="workspace-bundles"){l.currentView="files",it(l.currentWorkspace);return}l.currentView==="files"?l.currentView="findings":(l.viewMode==="graph"&&oe(),l.currentView="files"),document.body.classList.remove("report-fullscreen"),$();return}let Z=B(i,"[data-g2-pkg]");if(Z){let w=Z.dataset.g2Pkg;E.solo=E.solo===w?null:w,E.solo&&(E.selected=null),$u(),lr(),E.graphState?.requestDraw?.();return}let re=B(i,"[data-g2-select]");if(re){E.selected=re.dataset.g2Select,$u(),E.graphState?.requestDraw?.();return}let ne=B(i,"[data-g2-top-pkgs]");if(ne){E.topPkgsTab=ne.dataset.g2TopPkgs,lr();return}let jr=B(i,"[data-g2-jump-findings]");if(jr){if(l.currentView==="bundles"){l.bundleDetailsTab==="graph"&&oe(),_t("issues"),l.selectedBundle&&Be(l.selectedBundle,"issues",{push:!0}),$();return}if(Bl(),l.filterConfMin=0,l.filterInclude=jr.dataset.g2JumpFindings,l.currentView="findings",l.viewMode==="graph"&&(l.viewMode="table"),oe(),rr("findings"))return;$();return}let se=B(i,"[data-g2-jump-file]");if(se){let w=se.dataset.g2JumpFile;oe();let C=()=>requestAnimationFrame(()=>{let L=document.querySelector(`#${qa(w)}`);L&&L.scrollIntoView({behavior:"smooth",block:"start"})}),P=rr("files");if(P){P.then(L=>L?C():void 0);return}l.currentView="files",$(),C();return}if(B(i,"#g2-path-filter-clear")){E.pathFilter="";let w=document.querySelector("graph-layout")?.shadowRoot?.querySelector("#g2-path-filter");w&&(w.value=""),E.graphState?.requestDraw?.();return}if(B(i,"#g2-fullscreen")){document.body.classList.toggle("report-fullscreen");return}if(B(i,"[data-g2-show-all]")){E.showAll=!E.showAll,E.layoutCache=null,E.selected=null,oe(),$();return}if(B(i,"[data-g2-packages-view]")){E.bundleLayout==="flow"?E.flowPackagesView=!E.flowPackagesView:E.bundleLayout==="dependencies"?(E.dependencyPackagesView=!E.dependencyPackagesView,E.solo=null):E.packagesView=!E.packagesView,E.layoutCache=null,E.selected=null,E.focusedPkg=null,oe(),$();return}if(B(i,"[data-g2-bundle-issues]")){E.bundleIssues=!E.bundleIssues,oe({keepViewport:!0}),$();return}let Dt=B(i,"[data-g2-layout]");if(Dt){let w=Dt.dataset.g2Layout;if(!["graph","layers","matrix","dependencies","flow"].includes(w)||E.bundleLayout===w&&!E.focusedPkg)return;E.bundleLayout=w,w==="dependencies"&&(E.dependencyPackagesView=!1),E.layoutCache=null,E.selected=null,E.solo=null,E.focusedPkg=null,oe(),$();return}let hi=B(i,".graph2-triage-selector [data-triage-show]");if(hi){let w=hi.dataset.triageShow;l.shownTriage=l.shownTriage===w?null:w,E.layoutCache=null,E.selected=null,oe(),$();return}let mi=B(i,"[data-g2-focus-pkg]");if(mi){E.focusedPkg=mi.dataset.g2FocusPkg,E.layoutCache=null,oe(),$();return}if(B(i,"#g2-back-to-full")){E.focusedPkg=null,E.layoutCache=null,(E.packagesView||E.bundleLayout==="layers")&&(E.selected=null),oe(),$();return}let dt=B(i,".tab");if(dt&&B(i,".tabs")){let C=B(i,"[data-gid]").dataset.gid,P=dt.dataset.tid;l.activeTabByGroup.set(C,P),Me();return}let je=B(i,"[data-triage-action]");if(je){let w=je.closest(".triage-menu"),C=w?.dataset.gid;if(!C)return;let P=de(C);if(!P)return;let L=je.dataset.triageAction;if(!["inprogress","fixed","invalid","deleted","ignored","restore"].includes(L))return;let{targets:V,clearing:ae}=tc(P,L);if(V.length===0)return;Pu(V,ae?"untriaged":L);try{w.hidePopover()}catch{}ke(),Me();return}if(B(i,".mark-comment")){let C=B(i,"[data-gid]").dataset.gid,P=de(C);if(!P)return;let L=$e(P);if(!Yl(L))return;if(H()){import("./chunk-DGVQPIYB.js").then(({openManagedCommentsDialog:ve})=>ve(L,Me)).catch(()=>Oe("Could not open comments. Please retry."));return}let V=mt(L),ae=Ze(L)?.comment??"";Yd({initial:ae,finding:L}).then(ve=>(ve===null||!De(L)||(X(l.triage,V,{comment:ve||void 0}),ke(),Me()),null)).catch(()=>{});return}let fi=B(i,".mark-copy");if(fi){let w=Su(i);if(w===null)return;nr(fi,w);return}let zo=B(i,".mark-link");if(zo){let w=B(i,"[data-gid]"),C=w?de(w.dataset.gid):null;if(!C)return;let P=hc($e(C));if(!P)return;nr(zo,P);return}let Kr=B(i,"[data-copy-report]");if(Kr){nr(Kr,Kr.dataset.copyReport);return}let Gr=B(i,"[data-copy-path]");if(Gr){nr(Gr,Gr.dataset.copyPath);return}let qo=B(i,".mark-issue");if(qo&&H()&&l.managedSession&&!l.managedSession.publicShare&&l.currentManagedTeam){let w=B(i,"[data-gid]"),C=w?de(w.dataset.gid):null,P=C?$e(C):null;if(P?._managedReportId&&P.id){i.preventDefault();let L=new URL(qo.dataset.issueForm);Fd({teamId:l.currentManagedTeam,session:{...l.managedSession},context:{reportId:P._managedReportId,findingId:P.id,repository:L.pathname.split("/").slice(1,3).join("/")},formUrl:L.href,title:L.searchParams.get("title")??"",body:L.searchParams.get("body")??"",finding:P,draftOptions:{sourceUrl:Li(P,jt(P)),evidence:Fa(P),showRevalidation:La()},renderBody:vc}).catch(()=>Oe("Could not open issue creation. Please retry."));return}}let Ho=B(i,".mark-claude");if(Ho){let w=Su(i);if(w===null)return;let C=`claude://code/new?q=${encodeURIComponent(`Confirm and fix:
35
35
 
36
36
  ${w}`)}`;try{window.location.href=C,Ru(Ho)}catch{}return}if(B(i,".mark-fix")){let C=B(i,"[data-gid]")?.dataset.gid,P=C?de(C):null;if(!P)return;let L=$e(P);if(!De(L))return;let V=rc(P),ae=Ze(L)?.fix??"";uu({initial:ae,finding:L,canApplyToGroup:Zl(V,ae)}).then(ve=>{if(ve===null||!De(L))return null;let Vo=ve.scope==="group"?V.filter(Ot=>De(Ot)&&(Ot===L||ec(Ot,ae))):[L],Ko=!1;for(let Ot of Vo)X(l.triage,mt(Ot),{fix:ve.value||void 0})&&(Ko=!0);return Ko&&(Vo.length>1&&l.activeTabByGroup.set(C,mt(L)),Me(),queueMicrotask(ke)),null}).catch(()=>{});return}let Uo=B(i,"[data-flag-toggle]");if(Uo){let w=Uo.dataset.flagToggle,C=B(i,"[data-gid]")?.dataset.gid,P=(C?de(C):null)?.find(V=>mt(V)===w);if(!P||!De(P))return;let L=Ze(P)?.flagged;X(l.triage,w,{flagged:L!==!0}),ke(),Me();return}let Wr=i.target.closest("[data-triage-show]");if(Wr&&!Wr.closest(".graph2-triage-selector")){let w=Wr.dataset.triageShow;l.shownTriage=l.shownTriage===w?null:w,$();return}if(i.target.closest("[data-table-deselect]")){l.tableSelectedGid=null,Me();return}let jo=i.target.closest("[data-tree-select]");if(jo){let w=jo.dataset.treeSelect;l.filesSelectedFile=l.filesSelectedFile===w?null:w,$();return}i.target.closest("[data-tree-deselect]")&&(l.filesSelectedFile=null,$())});var Cu=document.querySelector("#bundle-source-overlay-slot");Cu&&Cu.addEventListener("click",Mu);function cr(i){let e=i?de(i):null;e&&ic(e)&&queueMicrotask(ke)}R.addEventListener("row-select",i=>{let e=i.detail?.gid;if(!e)return;let t=l.tableSelectedGid!==e;l.tableSelectedGid=t?e:null,t&&cr(e),Me()});var dr="application/x-deepview-kanban-gid";function Pu(i,e){for(let t of i)De(t)&&ca(l.triage,t,e,Pa())}function Qn(){for(let i of R.querySelectorAll(".kanban-card.dragging"))i.classList.remove("dragging");for(let i of R.querySelectorAll(".kanban-column.drag-over"))i.classList.remove("drag-over")}R.addEventListener("dragstart",i=>{let e=i.target.closest?.(".kanban-card[data-kanban-source]");if(!e||!i.dataTransfer)return;let t=e.dataset.gid;if(!t)return;let r=de(t);if(!r||an(r).length===0){i.preventDefault();return}i.dataTransfer.setData(dr,t),i.dataTransfer.setData("text/plain",t),i.dataTransfer.effectAllowed="move",e.classList.add("dragging")});R.addEventListener("dragend",Qn);R.addEventListener("dragover",i=>{if(!i.dataTransfer?.types.includes(dr))return;let e=i.target.closest?.(".kanban-column[data-kanban-target]");if(e&&(i.preventDefault(),i.dataTransfer.dropEffect="move",!e.classList.contains("drag-over"))){for(let t of R.querySelectorAll(".kanban-column.drag-over"))t!==e&&t.classList.remove("drag-over");e.classList.add("drag-over")}});R.addEventListener("dragleave",i=>{let e=i.target.closest?.(".kanban-column[data-kanban-target]");e&&(e.contains(i.relatedTarget)||e.classList.remove("drag-over"))});R.addEventListener("drop",i=>{if(!i.dataTransfer?.types.includes(dr))return;let e=i.target.closest?.(".kanban-column[data-kanban-target]");if(!e){Qn();return}i.preventDefault();let t=i.dataTransfer.getData(dr),r=e.dataset.kanbanTarget;if(Qn(),!t||!r)return;let n=de(t);if(!n||(Bi(n).commonTriage??"untriaged")===r)return;let o=an(n);o.length!==0&&(Pu(o,r),$(),queueMicrotask(ke))});var Yn=!1;function nt(i){return i?R.querySelector(`.kanban-card[data-gid="${CSS.escape(i)}"]`):null}function sr(i){let e=i??R.querySelector(".kanban-card");if(!e)return;let t=e.getBoundingClientRect();t.width<=0||t.height<=0||(document.documentElement.style.setProperty("--kanban-clip-card-w",`${Math.floor(t.width)}px`),document.documentElement.style.setProperty("--kanban-clip-card-h",`${Math.floor(t.height)}px`),document.documentElement.style.setProperty("--kanban-return-card-bg",getComputedStyle(e).backgroundColor))}function fm(){let i=R.querySelector(".kanban-detail-side [data-kanban-select].active");i&&i.scrollIntoView({block:"nearest",behavior:"instant"})}function Jn(i){l.kanbanPopoverGid=i,l.focusCodeStack=[],l.focusCodeAt=0}function Eu(){fm(),et()}function st(i){let e=l.kanbanPopoverGid;if(e===i)return;let t=e===null&&i!==null,r=e!==null&&i===null;if(!document.startViewTransition||!t&&!r){cr(i),Jn(i),$(),Eu();return}if(Yn)return;cr(i),Yn=!0;let n=t?"kanban-opening":"kanban-closing";document.documentElement.classList.add(n);let s=d=>{d&&(d.style.viewTransitionName=""),document.documentElement.classList.remove(n),Yn=!1};if(t){let d=nt(i);d?(sr(d),d.style.viewTransitionName="kanban-detail-modal",d.getBoundingClientRect()):sr(),Jn(i);let p=En(()=>{$(),Eu(),d&&(d.style.viewTransitionName="")}),h=setTimeout(()=>s(d),600);(async()=>{try{await p.finished}catch{}clearTimeout(h),s(d)})();return}sr(),Jn(i);let o=null,c=En(()=>{$(),o=nt(e),o&&(sr(o),o.style.viewTransitionName="kanban-detail-modal")}),u=setTimeout(()=>s(o??nt(e)),600);(async()=>{try{await c.finished}catch{}clearTimeout(u),s(o??nt(e))})()}function Au(i){let e=nt(l.kanbanPopoverGid),t=e?.closest(".kanban-column");if(!t)return;let r=[...t.querySelectorAll(".kanban-card[data-kanban-source]")],n=r.indexOf(e);if(n<0)return;let s=Math.min(Math.max(n+i,0),r.length-1);if(s===n)return;let o=r[s].dataset.gid;if(!o)return;st(o);let c=nt(o);c&&(c.focus({preventScroll:!0}),c.scrollIntoView({block:"nearest",behavior:"instant"}))}var ar=null;function Zn(){Kl(),l.focusCodeStack=[],l.focusCodeAt=0,$(),ar?.isConnected&&ar.focus({preventScroll:!0}),ar=null}R.addEventListener("click",i=>{let e=B(i,"[data-links-preview]");if(e){i.preventDefault(),ar=e;let o=e.dataset.previewRow,c=Gl(e.dataset.linksPreview,e.dataset.previewReport,o===void 0?void 0:Number(o),e.dataset.previewManagedReport);$(),R.querySelector(".kanban-detail-close")?.focus({preventScroll:!0}),c.then(()=>{$(),et();let u=Xe()?.group?.[0]._bundleHashes;if(Array.isArray(u))for(let d of u)lc(d).catch(()=>{});return null});return}if(i.target.closest?.(".kanban-detail-close")){if(Xe()){Zn();return}st(null);return}if(i.target.closest?.("[data-kanban-detail-fullscreen]")){l.kanbanDetailFullscreen=!l.kanbanDetailFullscreen;try{localStorage.setItem(Qa,String(l.kanbanDetailFullscreen))}catch{}$(),et();return}let t=i.target.closest?.("[data-kanban-expand]");if(t){let o=t.dataset.kanbanExpand,c=l.kanbanExpandedColumn===o?null:o;l.kanbanExpandedColumn=c,c&&l.kanbanPopoverGid&&nt(l.kanbanPopoverGid)?.closest(".kanban-column")?.dataset.kanbanTarget!==c&&(l.kanbanPopoverGid=null),$();return}let r=i.target.closest?.("[data-kanban-nav]");if(r){Au(r.dataset.kanbanNav==="next"?1:-1);return}let n=i.target.closest?.("[data-kanban-select]");if(n){if(window.getSelection?.()?.toString())return;let o=n.dataset.gid;o&&st(o);return}if(i.target.closest?.(".kanban-action:not(.kanban-fix-note)"))return;let s=i.target.closest?.(".kanban-card[data-kanban-source]");if(s){if(window.getSelection?.()?.toString())return;let o=s.dataset.gid;if(!o)return;st(l.kanbanPopoverGid===o?null:o);return}if(!B(i,".kanban-detail-modal, .kanban-detail-side")){if(Xe()){Zn();return}l.kanbanPopoverGid&&st(null)}});R.addEventListener("change",i=>{let e=i.target.closest?.("[data-kanban-column]");if(!e)return;let t=e.selectedOptions[0]?.dataset.gid;t&&st(t)});document.addEventListener("keydown",i=>{if(i.key==="Escape"){if(Xe()){!i.defaultPrevented&&!Ou(i)&&!document.querySelector(":popover-open:not(#styled-tooltip)")&&Zn();return}if(l.kanbanPopoverGid){st(null);return}l.viewMode!=="kanban"||l.kanbanExpandedColumn===null||(l.kanbanExpandedColumn=null,$())}});function ii(i){let t=B(i,"[data-gid]")?.dataset?.gid;return t?de(t):null}function ts(i,e){if(!e.integrity||!e.file)return;let t=uc(i);if(!t)return;let r=cc(t,e);r&&(l.focusCodeStack=r.stack,l.focusCodeAt=r.at,$()),e.range||Iu(),et()}function Iu(){for(let i of R.querySelectorAll(".focus-code-body"))i.scrollTop=0,i.scrollLeft=0}R.addEventListener("keydown",i=>{if(i.key!=="Enter"&&i.key!==" ")return;let e=B(i,"[data-code-nav-file]");e&&(i.preventDefault(),ts(ii(i),{integrity:e.dataset.codeNavIntegrity,file:e.dataset.codeNavFile,range:Fe(e.dataset.codeNavLine)}))});function gm(i){let e=dc(l.focusCodeStack,l.focusCodeAt,i);e!==l.focusCodeAt&&(l.focusCodeAt=e,$(),l.focusCodeStack[e]?.range||Iu(),et())}function Fu(i){if(!i||l.focusGid===i)return;cr(i),l.focusGid=i,l.focusCodeStack=[],l.focusCodeAt=0,$();let e=R.querySelector(".focus-side-card.active");e&&e.scrollIntoView({block:"nearest",behavior:"instant"}),et()}function Du(i){let e=[...R.querySelectorAll(".focus-side-card[data-focus-select]")];if(e.length===0)return;let t=e.findIndex(s=>s.classList.contains("active")),r=t<0?i>0?0:e.length-1:Math.min(Math.max(t+i,0),e.length-1);if(r===t)return;let n=e[r].dataset.gid;n&&Fu(n)}R.addEventListener("click",i=>{let e=i.target.closest?.("[data-focus-nav]");if(e){Du(e.dataset.focusNav==="next"?1:-1);return}let t=i.target.closest?.(".focus-side-card[data-focus-select]");if(!t||window.getSelection?.()?.toString())return;let r=t.dataset.gid;r&&Fu(r)});R.addEventListener("pointerdown",i=>{if(i.button!==0)return;let e=i.target.closest?.("[data-focus-splitter]");e&&_u(e,i)});R.addEventListener("dblclick",i=>{let e=i.target.closest?.("[data-focus-splitter]");e&&yu(e)});function Ou(i){if(document.querySelector("dialog[open]"))return!0;for(let e of i.composedPath()){if(!e||e.nodeType!==1)continue;let t=e.tagName;if(t==="INPUT"||t==="TEXTAREA"||t==="SELECT"||t==="DIALOG"&&e.open||e.isContentEditable)return!0}return!1}document.addEventListener("keydown",i=>{if(l.currentView!=="findings")return;let e=l.viewMode==="focus",t=l.viewMode==="kanban"&&l.kanbanPopoverGid!==null;if(!e&&!t||i.metaKey||i.ctrlKey||i.altKey||i.shiftKey||Ou(i))return;let r=0;if(i.key==="ArrowRight")r=1;else if(i.key==="ArrowLeft")r=-1;else return;i.preventDefault();let n=i.target?.closest?.("[data-focus-splitter]");if(n){vu(n,r*mu);return}e?Du(r):Au(r)});R.addEventListener("mark-color",i=>{let e=B(i,"[data-gid]");if(!e)return;let t=e.dataset.gid,r=de(t);if(!r)return;let n=$e(r);if(!De(n))return;let s=mt(n),o=i.detail?.color;if(!o)return;Ze(n)?.color===o?X(l.triage,s,{color:void 0}):X(l.triage,s,{color:o}),ke(),Me()});var ot=null,es=null,Ct=null,ur=!1;function Bu(){if(ot!==null)return;if(l.reports.length===0){Ct=null,ur=!1;return}ot=l.viewMode,es=document.title;let i=!1;l.viewMode==="table"&&(l.viewMode="list",i=!0),Ct&&(qt(Ct),i=!0),i&&$();for(let r of R.querySelectorAll("finding-card"))r.toggleAttribute("print-one-sample",ur),r.ensureRendered({sync:!0});let e=l.reports.map(r=>r.fileName),t="";e.length===1?t=e[0]:e.length>1&&(t=zt(e)),t=t.replace(/\.json$/u,""),t&&(document.title=t)}function Nu(){if(ot===null)return;for(let e of R.querySelectorAll("finding-card"))e.removeAttribute("print-one-sample");ur=!1;let i=!1;l.viewMode!==ot&&(l.viewMode=ot,i=!0),Ct&&(Ht(),Ct=null,i=!0),i&&$(),document.title=es,ot=null,es=null}window.addEventListener("beforeprint",Bu);window.addEventListener("afterprint",Nu);async function bm(i,{oneSamplePerGroup:e=!1}={}){if(ot===null){Ct=i,ur=e;try{Bu(),await Promise.all([...R.querySelectorAll("finding-card")].map(t=>t.ensureRendered())),window.print()}catch(t){throw Nu(),t}}}function Tu(i,e){if(!i)return e();qt(i);try{return e()}finally{Ht()}}document.addEventListener("download-requested",async()=>{if(l.reports.length===0)return;let{confirmed:i,view:e,fields:t,mode:r,oneSamplePerGroup:n}=await ru("download");if(e){await cu(Tu(t,()=>Vn({oneSamplePerGroup:n})));return}if(i){if(r==="print"){await bm(t,{oneSamplePerGroup:n});return}Tu(t,()=>ku({oneSamplePerGroup:n}))}});R.addEventListener("analyzer-change",i=>{l.filterAnalyzer=i.detail.analyzer,l.filterModel=i.detail.model,$()});R.addEventListener("repo-change",i=>{l.filterRepo=i.detail.value,$()});R.addEventListener("revalidate-change",i=>{l.filterRevalidate=i.detail.value,$()});R.addEventListener("partial-change",i=>{l.filterPartial=i.detail.value,$()});R.addEventListener("revalidation-change",i=>{l.showRevalidation=i.detail.on,!i.detail.on&&l.reports.some(t=>(t.groups??[]).some(r=>r.some(n=>!n.isApp&&(n.isUpstream||Ri(n.file)))))?Oe("App mode off is not recommended; it can conflate triage for issues in dependencies.",{kind:"warning"}):i.detail.on&&md(),sn(l.showRevalidation,l.upstreamOnly),Ul(ln(),{resetSort:!1}),$()});R.addEventListener("revalidation-conflicts-open",()=>{(async()=>{let i=await hu(l.revalidateConflicts);if(!i)return;let e=await Tn(i.id,i.reportName);e.ok||alert(e.reason)})().catch(i=>console.warn("revalidation: open conflicting finding failed:",i))});R.addEventListener("revalidation-detail-change",i=>{l.revalidationDetailed=i.detail.on===!0,$()});R.addEventListener("upstream-only-change",i=>{if(l.upstreamOnly=i.detail.on===!0,sn(l.showRevalidation,l.upstreamOnly),!l.upstreamOnly){let e=ln();ql(e,Hl(e))==="confirmed"&&(l.filterRevalidate="confirmed",l.filterPartial="")}$()});R.addEventListener("bundle-search-mode-change",i=>{let e=i.detail?.mode;if(["files","code","issues","largest"].includes(e)){if(l.bundleCodeSearchMode=e,$(),e==="files")Qt();else if(e==="largest"){let t=document.querySelector(".bundle-code-rail-body");t&&(t.scrollTop=0)}}});R.addEventListener("bundle-graph-reason-change",i=>{let e=i.detail?.reason;e!==null&&typeof e!="string"||(E.bundleReason=e,E.layoutCache=null,E.selected=null,E.solo=null,E.focusedPkg=null,oe(),$())});R.addEventListener("bundle-search-regex-toggle",()=>{l.bundleSearchRegex=!l.bundleSearchRegex,$()});R.addEventListener("bundle-search-case-toggle",()=>{l.bundleSearchCase=!l.bundleSearchCase,$()});R.addEventListener("bundle-swap",i=>{let e=i.detail?.integrity;if(!e||!(l.bundles??[]).some(s=>s.integrity===e))return;let t=l.bundles.find(s=>s.integrity===e),r=nc(i.detail.bundles??[]),n=()=>{setTimeout(()=>sc(r))};if(t.managedId){let s=i.detail.target===void 0?l.selectedBundle:i.detail.target,o=l.bundles.find(u=>u.integrity===s),c=o?.managedId?{compareId:o.managedId,...ua(i.detail.mode)}:null;me.navigate($c(l.managedTeams,t,l.currentManagedTeam,"compare",c,l.bundles)).finally(n);return}Kt(e,"compare"),Be(e,"compare"),$(),fe(),wt(e).finally(n)});R.addEventListener("bundle-compare-change",i=>{let{base:e,target:t,mode:r}=i.detail??{};!H()||!e||e!==l.selectedBundle||l.bundleDetailsTab!=="compare"||(l.bundleCompare=t?{bundle:e,target:t,mode:$i(r)}:null,Be(e,"compare"))});R.addEventListener("sort-change",i=>{let{kind:e,value:t}=i.detail;if(e==="findings")l.sortBy=t;else if(e==="packages")l.packagesSortBy=t;else if(e==="repositories")l.repositoriesSortBy=t;else return;$()});R.addEventListener("range-change",i=>{i.target.id==="conf-range"&&(l.filterConfMin=i.detail.low,l.filterConfMax=i.detail.high,$())});R.addEventListener("input",i=>{let e=i.composedPath()[0],t=e?.id,r=e?.value;t==="g2-path-filter"&&(E.pathFilter=r,E.graphState?.requestDraw?.())});R.addEventListener("search-input",i=>{if(!i.detail)return;let{kind:e,value:t}=i.detail;if(e==="findings"){l.filterInclude=t,t||(l.filterIncludeNegate=!1),xu();return}else if(e==="files")l.filesSearch=t;else if(e==="packages")l.packagesSearchQuery=t;else if(e==="repositories")l.repositoriesSearchQuery=t;else if(e==="bundle-code")l.bundleCodeSearchQuery=t;else if(e==="bundle-search"){l.bundleSearchQuery=t,xu();return}else return;$()});R.addEventListener("search-negate-toggle",()=>{l.filterIncludeNegate=!l.filterIncludeNegate,$()});R.addEventListener("severity-toggle",i=>{let e=i.detail.severity;if(i.detail.kind==="graph"){E.selectedSeverities.has(e)?E.selectedSeverities.delete(e):E.selectedSeverities.add(e),i.composedPath()[0].selected=[...E.selectedSeverities],E.graphState?.requestDraw?.(),lr();return}l.filterSeverities.has(e)?l.filterSeverities.delete(e):l.filterSeverities.add(e),$()});R.addEventListener("color-toggle",i=>{let e=i.detail.color;if(i.detail.kind==="graph"){E.selectedColors.has(e)?E.selectedColors.delete(e):E.selectedColors.add(e),i.composedPath()[0].selected=[...E.selectedColors],E.graphState?.requestDraw?.(),lr();return}l.filterColors.has(e)?l.filterColors.delete(e):l.filterColors.add(e),$()});R.addEventListener("source-toggle",i=>{let e=i.detail.source,t=l.filterSources.has(e);l.filterSources.clear(),t||l.filterSources.add(e),$()});R.addEventListener("annotation-filter-toggle",i=>{let e=i.detail?.key,t=r=>r===""?"with":r==="with"?"without":"";if(e==="comment")l.filterComment=t(l.filterComment);else if(e==="fix")l.filterFix=t(l.filterFix);else if(e==="flag")l.filterFlagged=t(l.filterFlagged);else if(e==="duplicates"&&!l.currentWorkspace)l.filterDuplicates=t(l.filterDuplicates);else if(e==="cross-context")l.filterCrossContext=t(l.filterCrossContext);else if(e==="app-stacked")l.filterAppStacked=t(l.filterAppStacked);else if(e==="security")l.filterSecurity=t(l.filterSecurity);else return;$()});R.addEventListener("slide-triage-toggle",i=>{let{kind:e,value:t}=i.detail;if(e==="package")l.packageSlideTriage=l.packageSlideTriage===t?null:t;else if(e==="repository")l.repositorySlideTriage=l.repositorySlideTriage===t?null:t;else return;$()});R.addEventListener("view-mode-change",i=>{if(i.detail.kind==="files"){l.filesViewMode=i.detail.mode,$();return}l.viewMode=i.detail.mode,l.viewMode!=="kanban"&&(l.kanbanPopoverGid=null),l.viewMode!=="focus"&&(l.focusGid=null),$()});R.addEventListener("severity-mode-change",i=>{let e=i.detail?.mode;if(!(e!=="corrected"&&e!=="original")){l.severityMode=e;try{localStorage.setItem(Ja,e)}catch{}$()}});R.addEventListener("repo-edit-start",()=>{H()||(l.repoEditing=!0,$())});R.addEventListener("repo-input",i=>{H()||(l.repoUrl=i.detail.url,Ai(l.currentFile,l.repoUrl))});R.addEventListener("repo-commit",i=>{H()||(l.repoUrl=i.detail.url,Ai(l.currentFile,l.repoUrl),l.repoEditing=!1,$())});R.addEventListener("repo-cancel",i=>{H()||(l.repoUrl=i.detail.url,Ai(l.currentFile,l.repoUrl),l.repoEditing=!1,$())});document.addEventListener("keydown",i=>{if(i.key==="Escape"){if(l.bundleSourceFindingIdx!=null){l.bundleSourceFindingIdx=null,ti();return}if(l.bundleSourceFile){if(l.currentView==="bundles"&&l.bundleDetailsTab==="code")return;_t(l.bundleDetailsTab),$()}}});function W(i,e){for(let[t,r]of Object.entries(e))i.hasAttribute(t)||i.setAttribute(t,r)}var Pe=Math.PI*2;function vm(i){return()=>{i=i+1831565813|0;let e=i;return e=Math.imul(e^e>>>15,e|1),e^=e+Math.imul(e^e>>>7,e|61),((e^e>>>14)>>>0)/4294967296}}function zu(i,e,t,r){let n=Math.cos(e),s=Math.sin(e);return Math.min(n>0?(t-i.x)/n:n<0?-i.x/n:1/0,s>0?(r-i.y)/s:s<0?-i.y/s:1/0)}function ym(i){return Math.abs(i.reduce((e,t,r)=>{let n=i[(r+1)%i.length];return e+t.x*n.y-n.x*t.y},0))/2}function is(i){return i.slice(1).reduce((e,t,r)=>e+Math.hypot(t.x-i[r].x,t.y-i[r].y),0)}function _m(i,e,t,r){let n=i.map(d=>d.x),s=i.map(d=>d.y),o={x:(Math.min(...n)+Math.max(...n))/2,y:(Math.min(...s)+Math.max(...s))/2},c=Math.max(...i.map(d=>Math.hypot(d.x-o.x,d.y-o.y))),u=Math.atan2(o.y-e.y,o.x-e.x);return{center:o,distance:Math.hypot(o.x-e.x,o.y-e.y),dx:Math.cos(u)*(80+r()*200)+(r()-.5)*90,dy:t-o.y+c+40,rotation:(r()-.5)*160,delay:r()*120}}function qu(i,e,t=7){let r=vm(t),n={x:i*1820/1920,y:e*90/1080},s=Math.hypot(i,e),o=(_,x)=>_<1e-8?0:_>x-1e-8?x:_,c=_=>({x:o(_.x,i),y:o(_.y,e)}),u=Array.from({length:20},(_,x)=>((x+(r()-.5)*.35)*Pe/20+Pe)%Pe);for(let[_,x]of[[0,0],[i,0],[i,e],[0,e]])u.push((Math.atan2(x-n.y,_-n.x)+Pe)%Pe);u.sort((_,x)=>_-x);let p=[.045,.29,.58].map(_=>_*Math.min(i,e)).map(_=>u.map(x=>{let S=Math.min(_*(.92+r()*.16),zu(n,x,i,e));return c({x:n.x+Math.cos(x)*S,y:n.y+Math.sin(x)*S})}));p.push(u.map(_=>{let x=zu(n,_,i,e);return c({x:n.x+Math.cos(_)*x,y:n.y+Math.sin(_)*x})}));let h=p.map((_,x)=>_.map((S,T)=>{let F=_[(T+1)%_.length],O={x:(S.x+F.x)/2,y:(S.y+F.y)/2},A=Math.hypot(F.x-S.x,F.y-S.y),z=S.x===F.x&&(S.x===0||S.x===i)||S.y===F.y&&(S.y===0||S.y===e),Z=x===p.length-1||z?0:(r()-.5)*A*.08,re=Math.atan2(O.y-n.y,O.x-n.x);return[S,c({x:O.x+Math.cos(re)*Z,y:O.y+Math.sin(re)*Z}),F]})),f=p.slice(1).map((_,x)=>_.map((S,T)=>{let F=p[x][T],O=Math.hypot(S.x-F.x,S.y-F.y),A={x:(F.x+S.x)/2,y:(F.y+S.y)/2},z=(u[T]-u[(T+u.length-1)%u.length]+Pe)%Pe,Z=(u[(T+1)%u.length]-u[T]+Pe)%Pe,re=Math.min(z,Z)*Math.hypot(A.x-n.x,A.y-n.y),ne=(r()-.5)*Math.min(O*.12,re*.14);return[F,c({x:A.x-Math.sin(u[T])*ne,y:A.y+Math.cos(u[T])*ne}),S]})),b=[],v=_=>{ym(_)>.01&&b.push({points:_,..._m(_,n,e,r)})};v(h[0].flatMap(_=>_.slice(0,-1)));for(let _=0;_<p.length-1;_++)for(let x=0;x<u.length;x++){let S=(x+1)%u.length;v([...f[_][x],...h[_+1][x].slice(1),...f[_][S].toReversed().slice(1),...h[_][x].toReversed().slice(1)])}let g=Math.max(...b.map(_=>_.distance));for(let _ of b)_.delay+=_.distance/g*400;let y=[],k=(_,x,S,T)=>{let F=is(_);F>.1&&y.push({points:_,length:F,delay:x,duration:S,width:T})};for(let _=0;_<u.length;_++){let x=[n,p[0][_],...f.flatMap(S=>S[_].slice(1))];k(x,0,200+is(x)/s*1e3,1.1)}for(let _ of h.slice(0,-1))for(let x of _){let S=Math.hypot(x[0].x-n.x,x[0].y-n.y);k(x,S/s*1e3,220+is(x)/s*400,.7)}for(let _ of p[1]){let x=Math.atan2(_.y-n.y,_.x-n.x)+(r()-.5)*1.4,S=Math.min(i,e)*(.07+r()*.12),T=[_];for(let F=1;F<=3;F++)T.push(c({x:_.x+Math.cos(x+(r()-.5)*.3)*S*F/3,y:_.y+Math.sin(x+(r()-.5)*.3)*S*F/3}));k(T,Math.hypot(_.x-n.x,_.y-n.y)/s*1e3+80,220,.5)}return{width:i,height:e,impact:n,pieces:b,cracks:y}}var Hu=`.screen-crack{position:fixed;inset:0;z-index:2147483646;overflow:hidden;pointer-events:none;user-select:none}.screen-crack-svg{position:absolute;inset:0;width:100%;height:100%;overflow:hidden}.screen-crack-glass{position:absolute;inset:0;backdrop-filter:blur(9px) brightness(1.06) saturate(.85);background:linear-gradient(135deg,#dcebff0f,#dcebff00 55%);mask-mode:luminance;opacity:0}.screen-crack-shard{transform-box:fill-box;transform-origin:center}.screen-crack-outline{opacity:0}.screen-crack-flash{position:absolute;width:18vmin;height:18vmin;border-radius:50%;background:radial-gradient(circle,rgb(255 255 255 / .85),rgb(200 230 255 / .15) 55%,transparent 75%);transform:translate(-50%,-50%);opacity:0}@media print{.screen-crack{display:none}}
37
37
  `;var km="http://www.w3.org/2000/svg",rs=1.5,$m=0;function ge(i,e={}){let t=document.createElementNS(km,i);for(let[r,n]of Object.entries(e))t.setAttribute(r,String(n));return t}function xm(i){let e=document.createElement("div");e.className="screen-crack",e.setAttribute("aria-hidden","true");let t=document.createElement("style");t.textContent=Hu;let r=ge("svg",{viewBox:`0 0 ${i.width} ${i.height}`,preserveAspectRatio:"none"});r.classList.add("screen-crack-svg");let n=ge("defs"),s=`screen-crack-mask-${++$m}`,o=ge("mask",{id:s,maskUnits:"userSpaceOnUse",maskContentUnits:"userSpaceOnUse",x:0,y:0,width:i.width,height:i.height});o.append(ge("rect",{width:i.width,height:i.height,fill:"black"})),n.append(o);let c=ge("g"),u=ge("g"),d=i.pieces.map(b=>{let v=b.points.map(_=>`${_.x},${_.y}`).join(" "),g=ge("g"),y=ge("g");g.classList.add("screen-crack-shard"),y.classList.add("screen-crack-shard"),g.append(ge("polygon",{points:v,fill:"white"}));let k=ge("polygon",{points:v,fill:"none",stroke:"rgb(240 248 255 / .8)","stroke-width":1.1,"stroke-linejoin":"round"});return k.classList.add("screen-crack-outline"),y.append(k),o.append(g),u.append(y),{masked:g,outlined:y,outline:k,piece:b}});r.append(n,c,u);let p=document.createElement("div");p.className="screen-crack-glass";let h=`${document.URL.split("#")[0]}#${s}`;p.style.maskImage=`url("${h}")`,p.style.webkitMaskImage=`url("${h}")`;let f=document.createElement("div");return f.className="screen-crack-flash",f.style.left=`${i.impact.x}px`,f.style.top=`${i.impact.y}px`,e.append(t,p,r,f),{overlay:e,glass:p,cracks:c,shards:d,flash:f}}function Sm(i,e,t){for(let r of e.cracks){let n=r.points.map((s,o)=>`${o===0?"M":"L"}${s.x} ${s.y}`).join(" ");for(let s of[!0,!1]){let o=ge("path",{d:n,fill:"none",stroke:s?"rgb(0 0 0 / .55)":"rgb(232 244 255 / .95)","stroke-width":r.width+(s?.8:0),"stroke-linecap":"round","stroke-linejoin":"round"});s&&o.setAttribute("transform","translate(.5 .7)"),o.style.strokeDasharray=`${r.length} ${r.length}`,o.style.strokeDashoffset=String(r.length),i.append(o),t(o,[{strokeDashoffset:String(r.length)},{strokeDashoffset:"0"}],{duration:r.duration*rs,delay:r.delay*rs,easing:"cubic-bezier(.2,.7,.2,1)"})}}}function Uu(i){let e=window.innerHeight,t=window.innerWidth;if(window.matchMedia("(prefers-reduced-motion: reduce)").matches||!t||!e||!Element.prototype.animate)return i(),Promise.resolve();let r=qu(t,e),{overlay:n,glass:s,cracks:o,shards:c,flash:u}=xm(r);document.body.append(n);let d=document.timeline.currentTime,p=[],h=(T,F,O)=>{let A=T.animate(F,{fill:"both",...O});return A.playbackRate=2,A.startTime=d,p.push(A),A},f=!1,b=!1,v=()=>{b||(b=!0,i())},g=()=>{if(!f){f=!0,window.removeEventListener("resize",g),window.removeEventListener("beforeprint",g),document.removeEventListener("visibilitychange",y),n.remove();for(let T of p)T.cancel();v()}},y=()=>{document.hidden&&g()};window.addEventListener("resize",g,{once:!0}),window.addEventListener("beforeprint",g,{once:!0}),document.addEventListener("visibilitychange",y),Sm(o,r,h),h(u,[{opacity:0,transform:"translate(-50%, -50%) scale(0)"},{opacity:.85,transform:"translate(-50%, -50%) scale(.8)",offset:.08},{opacity:0,transform:"translate(-50%, -50%) scale(2.4)"}],{duration:600,easing:"ease-out"}),h(o,[{transform:"translate(0, 0)"},{transform:"translate(-3px, 2px)"},{transform:"translate(3px, -2px)"},{transform:"translate(-2px, -2px)"},{transform:"translate(2px, 2px)"},{transform:"translate(0, 0)"}],{duration:450});let k=Math.max(...r.cracks.map(T=>T.delay+T.duration))*rs,_=500,x=Math.max(_,k*.8);h(s,[{opacity:0},{opacity:1}],{duration:_,easing:"ease-out"}),h(u,[{visibility:"visible"},{visibility:"visible"}],{duration:1,delay:x-1}).finished.then(v,()=>{}),h(o,[{opacity:1},{opacity:0}],{duration:450,delay:x,easing:"ease-out"});for(let{masked:T,outlined:F,outline:O,piece:A}of c){let z=x+A.delay,Z=[{transform:"translate(0, 0) rotate(0deg)"},{transform:`translate(${A.dx}px, ${A.dy}px) rotate(${A.rotation}deg)`}];for(let re of[T,F])h(re,Z,{duration:1700,delay:z,easing:"cubic-bezier(.32,0,.82,.94)"});h(O,[{opacity:0},{opacity:1}],{duration:250,delay:z})}return Promise.all(p.map(T=>T.finished)).then(g,g)}var ju=`:host{position:absolute;top:.5rem;right:.5rem;z-index:1000;width:30px;height:30px;background:var(--theme-toggle-bg, transparent);color:var(--muted);border:var(--theme-toggle-border, 0);border-radius:var(--ui-radius, 6px);font-size:1rem;line-height:1;font-family:inherit;display:flex;align-items:center;justify-content:center;transition:color .12s,background .12s;cursor:default;user-select:none}:host(:hover){color:var(--text);background:var(--theme-toggle-hover-bg, rgb(from var(--text) r g b / .06))}:host(:focus-visible){outline:2px solid var(--accent);outline-offset:2px}@media print{:host{display:none!important}}@media(display-mode:window-controls-overlay){:host{-webkit-app-region:no-drag;app-region:no-drag}}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@preventive/triage",
3
- "version": "1.0.0-alpha.41",
3
+ "version": "1.0.0-alpha.42",
4
4
  "description": "Client & relay server for triaging of automated reports",
5
5
  "license": "MIT OR Apache-2.0",
6
6
  "author": {
@@ -346,7 +346,7 @@
346
346
  "dependencies": {
347
347
  "@exodus/stasis": "1.0.0-beta.9",
348
348
  "@exodus/stasis-core": "1.0.0-beta.9",
349
- "@preventive/compare": "^1.2.0",
349
+ "@preventive/compare": "^1.2.3",
350
350
  "@preventive/diff": "^1.0.2",
351
351
  "@preventive/lockfile": "1.0.0",
352
352
  "@preventive/publishers": "^1.1.0",
@@ -581,12 +581,20 @@ export function npmFoundAdded(found, was) {
581
581
  // a tag kinds share once: `eval, child_process`.
582
582
  export const npmRunsCodeKinds = founds => [...new Set([...RUNS_CODE].filter(([kind]) => founds.some(found => found.has(kind))).map(([, { tag }]) => tag))].join(', ')
583
583
 
584
- // What `found` holds (npmRunsCode's) but the kinds whose tags `tags` names,
585
- // each with its lines; null for none.
586
- export function npmRunsCodeWithout(found, tags) {
587
- const kept = new Map([...found ?? []].filter(([kind]) => !tags.has(RUNS_CODE.get(kind).tag)))
588
- return kept.size > 0 ? kept : null
584
+ // What `found` holds (npmRunsCode's) but the kinds whose tags `tags` names
585
+ // (npmRunsCodeWithout), or of those kinds alone (npmRunsCodeTagged), each
586
+ // with its lines; null for none.
587
+ function npmRunsCodeOf(found, kept) {
588
+ const of = new Map([...found ?? []].filter(([kind]) => kept(RUNS_CODE.get(kind).tag)))
589
+ return of.size > 0 ? of : null
589
590
  }
591
+ export const npmRunsCodeWithout = (found, tags) => npmRunsCodeOf(found, tag => !tags.has(tag))
592
+ export const npmRunsCodeTagged = (found, tags) => npmRunsCodeOf(found, tag => tags.has(tag))
593
+
594
+ // The kinds that reach for credentials, by their tag: a version's finding of
595
+ // their own (risk/npm/held.js `held-credentials`), apart from the code its
596
+ // files run beyond themselves.
597
+ export const CREDENTIAL_TAGS = new Set([CREDENTIALS.tag])
590
598
 
591
599
  // Its tags as a file's flags (file-flags.js), in their order, each once: a
592
600
  // warning's (`high`), or for one marked worse, `critical`; none for none.
@@ -18,7 +18,7 @@ import { npmRiskScore } from './score.js'
18
18
  // Which reading of a version an assessment kept (`risk/npm/assessments`) is:
19
19
  // one more whenever a heuristic changes what it finds, so one kept by an
20
20
  // older reading is read anew.
21
- const RISK_VERSION = 14
21
+ const RISK_VERSION = 16
22
22
 
23
23
  // How long an assessment kept may be as JSON, and what risk reads of either
24
24
  // version's files: a package past it, whose files name thousands of hosts or
@@ -25,12 +25,15 @@ const higher = (a, b) => SEVERITIES[Math.min(SEVERITIES.indexOf(a), SEVERITIES.i
25
25
  // scripts added or changed and what each version ran (`flagged`, `was`); a
26
26
  // dependency taken from elsewhere than npm's registry anew, its spec before
27
27
  // (`was`), or added that nothing imports (`added`). Code kept running beyond
28
- // itself (`kept-runs-code`) marks nothing, its files held already.
28
+ // itself or reaching for credentials (`kept-runs-code`, `kept-credentials`)
29
+ // marks nothing, its files held already.
29
30
  const byPath = (rows, key) => new Map(rows.map(row => [row.path, row[key]]))
30
31
  const marked = (held, rows) => ({ ...held, files: held.files.map(row => rows.has(row.path) ? { ...row, added: rows.get(row.path) } : row) })
31
32
  const FOLDS = {
32
33
  'runs-code': ['held-runs-code', (held, change) => marked(held, byPath(change.files, 'added'))],
33
34
  'kept-runs-code': ['held-runs-code', held => held],
35
+ credentials: ['held-credentials', (held, change) => marked(held, byPath(change.files, 'added'))],
36
+ 'kept-credentials': ['held-credentials', held => held],
34
37
  obfuscated: ['held-obfuscated', (held, change) => marked(held, byPath(change.files, 'obfuscation'))],
35
38
  'install-scripts': ['held-install-scripts', (held, change) => ({ ...held, flagged: change.flagged, was: [...change.was] })],
36
39
  'non-registry-deps': ['held-non-registry-deps', (held, change) => {
@@ -13,7 +13,7 @@ import { npmHostFinding } from './held.js'
13
13
  import { HOST_TAGS, npmHostSeverity, npmHostsTagged } from '../files/hosts.js'
14
14
  import { npmBecameUnreadable, npmBinaryCode, npmLargeCode, npmUnreadable } from '../files/readability.js'
15
15
  import { SEVERITIES } from '../files/stamps.js'
16
- import { npmFoundAdded, npmRunsCodeFlags, npmRunsCodeWithout } from '../files/runs-code.js'
16
+ import { CREDENTIAL_TAGS, npmFoundAdded, npmRunsCodeFlags, npmRunsCodeTagged, npmRunsCodeWithout } from '../files/runs-code.js'
17
17
  import { npmDependencySpecs } from './dependencies.js'
18
18
  import { npmFilesDiff } from './diff.js'
19
19
  import { npmInstallScripts } from './install-scripts.js'
@@ -21,7 +21,8 @@ import { npmInstallScriptsChange, npmProvenanceLost, npmPublisherChange } from '
21
21
 
22
22
  // What the open version does to its files that calls for a look, as red
23
23
  // findings: code that runs beyond itself (runs-code.js), new to a file it
24
- // adds or changes, the kinds with their lines (`runs-code`); a service under
24
+ // adds or changes, the kinds with their lines (`runs-code`), those reaching
25
+ // for credentials apart (CREDENTIAL_TAGS, `credentials`); a service under
25
26
  // one of the hosts' tags new to a file it adds or changes (hosts.js
26
27
  // npmExfiltration), a finding a tag a level higher than its own
27
28
  // (npmHostSeverity: `exfiltration` and `remote` red, `ip-lookup` orange); a
@@ -33,7 +34,7 @@ import { npmInstallScriptsChange, npmProvenanceLost, npmPublisherChange } from '
33
34
  // the one compared with's was text, or no code, or none (npmBinaryCode,
34
35
  // `binary-code`). Then in orange what any of its files runs beyond itself that
35
36
  // `runs-code` doesn't name, kept from the version compared with
36
- // (`kept-runs-code`). A renamed file by its old path; one renamed alone,
37
+ // (`kept-runs-code`, `kept-credentials`). A renamed file by its old path; one renamed alone,
37
38
  // unchanged, holds what it held. A file become unreadable calls for less
38
39
  // where its source map was rebuilt with it (`rebuilt`, rebuiltWithMap), as a
39
40
  // build minifies a file and writes its map together, and in a `major`
@@ -51,8 +52,11 @@ function npmFileFindings(base, other, files, major) {
51
52
  const exfiltration = gained('exfiltration'), runsCode = gained('runsCode')
52
53
  const flagged = new Set(runsCode.flatMap(row => npmRunsCodeFlags(row.added).map(({ name }) => name)))
53
54
  const kept = [...bundleFilesAsMap(other).keys()].map(path => ({ path, found: npmRunsCodeWithout(npmVersionFileRisk(other, path).runsCode, flagged) })).filter(row => row.found)
55
+ // Code that runs beyond itself, or of the kinds reaching for credentials.
56
+ const ofKinds = (rows, key, of) => rows.map(row => ({ ...row, [key]: of(row[key], CREDENTIAL_TAGS) })).filter(row => row[key])
54
57
  return [
55
- { id: 'runs-code', severity: 'critical', files: runsCode },
58
+ { id: 'runs-code', severity: 'critical', files: ofKinds(runsCode, 'added', npmRunsCodeWithout) },
59
+ { id: 'credentials', severity: 'critical', files: ofKinds(runsCode, 'added', npmRunsCodeTagged) },
56
60
  ...[...HOST_TAGS.keys()].map(tag => {
57
61
  const rows = exfiltration.map(row => ({ path: row.path, added: npmHostsTagged(row.added, tag) })).filter(row => row.added)
58
62
  return { id: npmHostFinding(tag), severity: rows.length > 0 ? npmHostSeverity(tag, rows[0].added, null) : HOST_TAGS.get(tag), files: rows }
@@ -65,7 +69,8 @@ function npmFileFindings(base, other, files, major) {
65
69
  .map(row => ({ path: row.path, obfuscation: after(row).readability.obfuscation })) },
66
70
  { id: 'binary-code', severity: 'critical', files: touched.filter(row => npmBinaryCode(row.path, after(row).readability) && !npmBinaryCode(row.renamedFrom ?? row.path, before(row)?.readability))
67
71
  .map(row => ({ path: row.path, bytes: sizes.get(row.path) })) },
68
- { id: 'kept-runs-code', severity: 'high', files: kept },
72
+ { id: 'kept-runs-code', severity: 'high', files: ofKinds(kept, 'found', npmRunsCodeWithout) },
73
+ { id: 'kept-credentials', severity: 'high', files: ofKinds(kept, 'found', npmRunsCodeTagged) },
69
74
  ].filter(finding => finding.files.length > 0)
70
75
  }
71
76
 
package/risk/npm/diff.js CHANGED
@@ -1,8 +1,9 @@
1
1
  // How two versions' files differ, as Compare's diff has them
2
2
  // (ui/view/bundle-compare-diff.js computeBundleDiff), for risk's findings
3
- // (compare.js): the files the open version adds, and those it changes, a file
4
- // moved to another path paired with its old one by content, as git diff -M
5
- // pairs them (@preventive/compare compareTrees).
3
+ // (compare.js): the files the open version adds, and those it changes, a
4
+ // build's content-hashed file paired with the one it replaces by its name
5
+ // (hashedKey), and a file moved to another path with its old one by content,
6
+ // as git diff -M pairs them (@preventive/compare compareTrees).
6
7
  import { compareTrees } from '@preventive/compare'
7
8
  import { bundleFilesAsMap } from '../../common/bundle-sources.js'
8
9
 
@@ -21,6 +22,25 @@ const same = (a, b) => a === b || (a?.format === 'digest' && b?.format === 'dige
21
22
  const treeData = (content, at) => typeof content === 'string' ? `\0text\0${content.toWellFormed()}`
22
23
  : content?.format === 'digest' ? `\0digest\0${content.digest}` : `\0none\0${at}`
23
24
 
25
+ // A build's content-hashed file (`assets/index-CyWAfh-p.js`, Vite's and
26
+ // Rollup's `[name]-[hash]`, webpack's `[name].[contenthash].js`) by its name
27
+ // but its hash, `assets/index\0.js`: a release renames it as its content
28
+ // changes, the same file. Null for a name whose last part before its
29
+ // extension is no hash: 8 to 32 of base64url's characters with a letter, and
30
+ // a digit or a capital, as neither a lowercase word (`index-client.js`,
31
+ // `lodash.debounce.js`) nor a number (a date, `migration-20240101.js`) is. Its hash its last 8 or more such characters, so that chunks named
32
+ // after a module (`vendor-react-DQ4mN2sx.js`) pair each with its own; a
33
+ // longer hash holding a `-` (Rollup's `[hash:16]`) is cut there, so that a
34
+ // rebuild pairs by its content alone, as its parts aren't told from a
35
+ // chunk's name's (`vendor-ui-…`) without it.
36
+ const HASHED_NAME = /^(.+)[-.]([\w-]{8,32})((?:\.[A-Za-z\d]+)+)$/u
37
+ function hashedKey(path) {
38
+ const at = path.lastIndexOf('/') + 1
39
+ const [, stem, hash, extension] = HASHED_NAME.exec(path.slice(at)) ?? []
40
+ if (!hash || !/[A-Za-z]/u.test(hash) || !/[\dA-Z]/u.test(hash)) return null
41
+ return `${path.slice(0, at)}${stem}\0${extension}`
42
+ }
43
+
24
44
  // `onlyOther`, the files the open version (`other`) adds, `{ path }` each, and
25
45
  // `changed`, those it changes, `{ path, modified }`, or moves, `{ path,
26
46
  // renamedFrom, modified }`, `modified` whether its content changed too; each
@@ -34,10 +54,26 @@ export function npmFilesDiff(base, other) {
34
54
  else if (!same(before.get(path), text)) changed.push({ path, modified: true })
35
55
  }
36
56
  for (const path of before.keys()) if (!after.has(path)) onlyBase.push(path)
57
+ // A content-hashed file added where one by the same name but its hash
58
+ // (hashedKey) is removed, one each, is that file changed, as a build
59
+ // renames it: what it runs, how it reads and how large it is told against
60
+ // it, not all of it new.
61
+ const hashed = paths => Map.groupBy(paths.filter(hashedKey), hashedKey)
62
+ const moved = new Set(), removed = hashed(onlyBase)
63
+ for (const [key, paths] of hashed(onlyOther)) {
64
+ const was = removed.get(key)
65
+ if (paths.length !== 1 || was?.length !== 1) continue
66
+ changed.push({ path: paths[0], renamedFrom: was[0], modified: !same(before.get(was[0]), after.get(paths[0])) })
67
+ moved.add(paths[0])
68
+ }
69
+ // The rest by content, against every file removed: one paired by its name
70
+ // may be another's too, a build's copy of it elsewhere.
37
71
  const entries = (paths, files, side) => paths.filter(path => path.isWellFormed()).map((path, at) => ({ name: path, data: treeData(files.get(path), `${side}${at}`) }))
38
- const renames = compareTrees(entries(onlyBase, before, 'a'), entries(onlyOther, after, 'b'), { paths: 'keys', renameLimit: RENAME_LIMIT, lines: false })
72
+ const renames = compareTrees(entries(onlyBase, before, 'a'), entries(onlyOther.filter(path => !moved.has(path)), after, 'b'), { paths: 'keys', renameLimit: RENAME_LIMIT, lines: false })
39
73
  .filter(change => change.status === 'renamed')
40
- const moved = new Set(renames.map(change => change.new.path))
41
- for (const change of renames) changed.push({ path: change.new.path, renamedFrom: change.old.path, modified: change.similarity !== 100 })
74
+ for (const change of renames) {
75
+ changed.push({ path: change.new.path, renamedFrom: change.old.path, modified: change.similarity !== 100 })
76
+ moved.add(change.new.path)
77
+ }
42
78
  return { onlyOther: onlyOther.filter(path => !moved.has(path)).map(path => ({ path })), changed }
43
79
  }
package/risk/npm/held.js CHANGED
@@ -7,6 +7,7 @@ import { npmDownloadTier, npmTierLevel, npmTierLow } from './downloads.js'
7
7
  import { npmInstallScripts } from './install-scripts.js'
8
8
  import { npmTooNew } from './release.js'
9
9
  import { HOST_TAGS, npmHostsTagged } from '../files/hosts.js'
10
+ import { CREDENTIAL_TAGS, npmRunsCodeTagged, npmRunsCodeWithout } from '../files/runs-code.js'
10
11
  import { npmVersionFileRisk } from './files.js'
11
12
 
12
13
  // What npm says of a version and of its package, told fresh as it changes in
@@ -39,7 +40,8 @@ export function npmVersionFindings({ deprecated, published, minimumReleaseAge, n
39
40
  // orange, as its files' tags are: the scripts npm runs installing it
40
41
  // (install-scripts.js, `held-install-scripts`, `[script, command]` each); and
41
42
  // its files, each with what it holds, that run code beyond themselves
42
- // (`held-runs-code`), name a service under one of the hosts' tags, at the
43
+ // (`held-runs-code`), reach for credentials (runs-code.js CREDENTIAL_TAGS,
44
+ // `held-credentials`), name a service under one of the hosts' tags, at the
43
45
  // tag's severity (hosts.js HOST_TAGS: `held-exfiltration` red, `held-remote`
44
46
  // orange, `held-ip-lookup` yellow), or bear an obfuscator's fingerprint
45
47
  // (`held-obfuscated`).
@@ -49,7 +51,8 @@ export function npmHeldFindings(version) {
49
51
  const holding = of => reads.map(({ path, read }) => ({ path, found: of(read) })).filter(row => row.found)
50
52
  return [
51
53
  ...scripts.length > 0 ? [{ id: 'held-install-scripts', severity: 'high', scripts }] : [],
52
- { id: 'held-runs-code', severity: 'high', files: holding(read => read.runsCode) },
54
+ { id: 'held-runs-code', severity: 'high', files: holding(read => npmRunsCodeWithout(read.runsCode, CREDENTIAL_TAGS)) },
55
+ { id: 'held-credentials', severity: 'high', files: holding(read => npmRunsCodeTagged(read.runsCode, CREDENTIAL_TAGS)) },
53
56
  ...[...HOST_TAGS].map(([tag, severity]) => ({ id: `held-${npmHostFinding(tag)}`, severity, files: holding(read => npmHostsTagged(read.exfiltration, tag)) })),
54
57
  { id: 'held-obfuscated', severity: 'high', files: holding(read => read.readability.obfuscation) },
55
58
  ].filter(finding => !finding.files || finding.files.length > 0)
@@ -28,7 +28,7 @@ import { type NpmVersionDocument, npmFileText } from './npm-packages.ts'
28
28
  // Part of every kept copy's name; bumped when what the formatter writes for
29
29
  // the same file changes, or what its check lets through, so copies written
30
30
  // before are no longer read.
31
- const PRETTY_VERSION = 3
31
+ const PRETTY_VERSION = 4
32
32
  // Formats running at once per process, each holding its file's syntax tree,
33
33
  // and those waiting their turn past them (a version's files are formatted one
34
34
  // after another, beside other readers'), any more refused.
@@ -3,9 +3,9 @@
3
3
  // server's event loop: each pair a tree of a file a side, a side not there
4
4
  // none, its paths as they are, which say what a file is. Two paths pair as one
5
5
  // change wherever compareTrees takes them for a rename at all; where it
6
- // doesn't, the pair is types only where each of its two changes is, as each
7
- // side holds types alone and neither keeps an `export {}`, which is what it
8
- // would stamp of them paired. `[true, false, ...]` by pair.
6
+ // doesn't, the pair is types only where each of its two changes is: the file
7
+ // gone erasing whole, and the one come erasing whole or leaving a single bare
8
+ // `export {}`, which nothing loaded before. `[true, false, ...]` by pair.
9
9
  import { parentPort, workerData } from 'node:worker_threads'
10
10
  import { compareTrees } from '@preventive/compare'
11
11
 
@@ -4,8 +4,10 @@
4
4
  // paired as its viewer pairs them (rename-diff.ts comparedFiles), whose
5
5
  // change @preventive/compare's compareTrees stamps
6
6
  // `typeOnly` -- each side there a file named as a declaration file and
7
- // proven to hold types alone, so that it runs nothing (proveTypeOnly) --
8
- // and nothing else. Proven in a worker, off the event loop, a comparison at a
7
+ // proven to hold types alone but for a runtime, the module loads and
8
+ // `export {}` its stripping leaves, that the change leaves as it was, an
9
+ // added one's empty or a single bare `export {}` (proveTypeOnly) -- and
10
+ // nothing else. Proven in a worker, off the event loop, a comparison at a
9
11
  // time per process, for at most a minute; told a line each, `{ path, hash,
10
12
  // otherPath, otherHash }`, a side not there null, which the viewer checks
11
13
  // name the files it shows. Access is the caller's to check.