@preventive/triage 1.0.0-alpha.37 → 1.0.0-alpha.39
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/README.md +16 -0
- package/common/bundle-compare-diff.d.ts +3 -0
- package/common/bundle-compare-diff.js +522 -0
- package/common/bundle-compare-inputs.d.ts +2 -0
- package/common/bundle-compare-inputs.js +65 -0
- package/common/bundle-metadata.d.ts +6 -2
- package/common/bundle-metadata.js +63 -20
- package/common/bundle-pkg-of.d.ts +1 -0
- package/common/bundle-pkg-of.js +90 -0
- package/common/bundle-source-links.js +7 -0
- package/common/bundle-sourcemap.d.ts +10 -0
- package/common/bundle-sourcemap.js +100 -0
- package/common/bundle-sources.d.ts +3 -1
- package/common/bundle-sources.js +47 -19
- package/common/code-language.js +16 -2
- package/common/default-scan-models.ts +2 -1
- package/common/dependency-reviews.d.ts +23 -0
- package/common/dependency-reviews.js +81 -0
- package/common/finding-duplicates.js +58 -0
- package/common/finding-filters.js +274 -0
- package/common/github-pr.ts +1 -1
- package/common/gzip.js +59 -0
- package/common/line-diff.d.ts +8 -0
- package/common/line-diff.js +56 -0
- package/common/linked-workspace-groups.js +63 -0
- package/common/managed/npm-packages.d.ts +5 -0
- package/common/managed/npm-packages.js +34 -0
- package/common/managed/permissions.ts +1 -5
- package/common/managed/routes.js +123 -12
- package/common/managed/team-app.d.ts +2 -0
- package/common/managed/team-app.js +31 -0
- package/common/managed/triage.ts +1 -1
- package/common/managed/upload-seal.ts +126 -0
- package/common/pretty-print.d.ts +5 -0
- package/common/pretty-print.js +24 -0
- package/common/revalidation-conflicts.js +48 -0
- package/common/revalidation-input-groups.js +56 -0
- package/common/workspace-app.js +23 -0
- package/common/workspace-groups.js +176 -0
- package/out/brotli-fallback.js +3 -3
- package/out/chunk-2KBF5TZ7.js +2 -0
- package/out/chunk-2XUEZHIP.js +28 -0
- package/out/chunk-35VE6CDH.js +2 -0
- package/out/chunk-3BZ7JERB.js +1 -0
- package/out/chunk-45WIN3SW.js +1 -0
- package/out/chunk-4XCDFGDP.js +10 -0
- package/out/chunk-6C76GAXK.js +1 -0
- package/out/chunk-7ZKDKGAH.js +1 -0
- package/out/chunk-ABW5FVSN.js +1 -0
- package/out/chunk-C4Z6ZBXV.js +10 -0
- package/out/chunk-CMQA4DM6.js +1 -0
- package/out/chunk-CVVJAXVY.js +2 -0
- package/out/chunk-DIJJNTRH.js +10 -0
- package/out/chunk-F4OMDNEY.js +1 -0
- package/out/chunk-GJ4IUCNS.js +1 -0
- package/out/chunk-GMFXFEUA.js +2 -0
- package/out/chunk-GNXOKIGP.js +80 -0
- package/out/chunk-GZ4MS3TE.js +13 -0
- package/out/chunk-HIV7SVI7.js +1 -0
- package/out/chunk-IU3CCINR.js +3 -0
- package/out/chunk-JVBB4LZX.js +1 -0
- package/out/chunk-K3X5EJBQ.js +2 -0
- package/out/chunk-KEX2ATEW.js +2 -0
- package/out/chunk-KYCNJVB7.js +1 -0
- package/out/chunk-NRPC74AM.js +1 -0
- package/out/chunk-OOJM4CTU.js +1 -0
- package/out/chunk-PNHBZGDD.js +1 -0
- package/out/chunk-QSLWGJBQ.js +223 -0
- package/out/chunk-R5O6FAW4.js +2 -0
- package/out/chunk-RFZQQXSG.js +17 -0
- package/out/chunk-TINZZKP5.js +33 -0
- package/out/chunk-TUII34K2.js +1 -0
- package/out/chunk-TZ5KB2Y5.js +10 -0
- package/out/chunk-UNTRGE26.js +2 -0
- package/out/chunk-UYAXVRVL.js +1 -0
- package/out/chunk-V3ME6FI5.js +2 -0
- package/out/chunk-V5O7M2YT.js +1 -0
- package/out/chunk-VIHGO77Y.js +1 -0
- package/out/chunk-W4J3MGLB.js +1 -0
- package/out/chunk-WGG7KQUH.js +1 -0
- package/out/chunk-XNGEQO7Y.js +2 -0
- package/out/chunk-XRWAV3DX.js +7 -0
- package/out/chunk-XYDGU6BM.js +51 -0
- package/out/chunk-XYFXXB2G.js +10 -0
- package/out/chunk-YVZH5SHP.js +1 -0
- package/out/chunk-ZPD5R5RP.js +3 -0
- package/out/client-managed-import.js +3 -87
- package/out/client-managed.js +26 -338
- package/out/client-sync.js +8 -14
- package/out/graph.js +17 -30
- package/out/index.html +34 -0
- package/out/prism.js +6 -2
- package/out/terminal.js +241 -257
- package/out/view.css +1 -1
- package/out/view.js +76 -520
- package/package.json +89 -7
- package/risk/files/characters.js +196 -0
- package/risk/files/hosts.js +205 -0
- package/risk/files/readability.js +171 -0
- package/risk/files/runs-code.js +358 -0
- package/risk/files/script.js +114 -0
- package/risk/files/stamps.js +46 -0
- package/risk/index.d.ts +142 -0
- package/risk/index.js +7 -0
- package/risk/npm/assess.js +219 -0
- package/risk/npm/combined.js +65 -0
- package/risk/npm/compare.js +228 -0
- package/risk/npm/dependencies.js +153 -0
- package/risk/npm/diff.js +43 -0
- package/risk/npm/downloads.js +84 -0
- package/risk/npm/files.js +34 -0
- package/risk/npm/held.js +60 -0
- package/risk/npm/install-scripts.js +34 -0
- package/risk/npm/malware.js +36 -0
- package/risk/npm/manifest.js +65 -0
- package/risk/npm/new-dependency.js +30 -0
- package/risk/npm/old-version.js +108 -0
- package/risk/npm/registry.js +282 -0
- package/risk/npm/release.js +85 -0
- package/risk/npm/specs.js +124 -0
- package/risk/npm/tarball.js +113 -0
- package/server-e2e/http.ts +7 -7
- package/server-e2e/npm-proxy.ts +1 -1
- package/server-e2e/objstore/fetch-mint-guard.ts +2 -2
- package/server-e2e/objstore/handlers.ts +1 -1
- package/server-e2e/objstore/tokens.ts +1 -1
- package/server-e2e/sign.ts +1 -1
- package/server-managed/bundle-advisories.ts +74 -12
- package/server-managed/bundle-cache.ts +37 -4
- package/server-managed/bundle-commits.ts +140 -0
- package/server-managed/bundle-summary-cache.ts +24 -10
- package/server-managed/config.ts +4 -0
- package/server-managed/db-methods.ts +98 -11
- package/server-managed/db-neon.ts +39 -4
- package/server-managed/db-schema.ts +14 -2
- package/server-managed/db-table-names.ts +1 -1
- package/server-managed/db.ts +7 -3
- package/server-managed/dependency-reviews.ts +248 -0
- package/server-managed/github-app.ts +9 -3
- package/server-managed/github-errors.ts +21 -2
- package/server-managed/github-issue-oauth.ts +5 -6
- package/server-managed/github-metadata.ts +115 -0
- package/server-managed/github-oauth.ts +38 -2
- package/server-managed/http-response.ts +26 -0
- package/server-managed/http.ts +952 -53
- package/server-managed/index.ts +11 -5
- package/server-managed/kept.ts +28 -0
- package/server-managed/locked-packages.ts +85 -0
- package/server-managed/lru.ts +30 -0
- package/server-managed/npm-insights.ts +440 -0
- package/server-managed/npm-kept.ts +65 -0
- package/server-managed/npm-loads.ts +167 -0
- package/server-managed/npm-manifest.ts +115 -0
- package/server-managed/npm-packages.ts +378 -0
- package/server-managed/npm-provenance.ts +123 -0
- package/server-managed/npm-risk.ts +177 -0
- package/server-managed/pretty-print.ts +352 -0
- package/server-managed/public-workspace.ts +78 -7
- package/server-managed/rename-diff-worker.js +26 -0
- package/server-managed/rename-diff.ts +270 -0
- package/server-managed/report-sources.ts +13 -2
- package/server-managed/repository-browser.ts +19 -5
- package/server-managed/repository-risk.ts +418 -0
- package/server-managed/session.ts +16 -2
- package/server-managed/sql.ts +5 -2
- package/server-managed/storage-encryption.ts +5 -3
- package/server-managed/storage-payload.ts +4 -0
- package/server-managed/storage-stores.ts +2 -0
- package/server-managed/storage.ts +6 -3
- package/server-managed/team-app.ts +94 -0
- package/server-managed/team-feed.ts +1 -1
- package/server-managed/team-npm-scopes.ts +77 -0
- package/server-managed/type-only-worker.js +19 -0
- package/server-managed/type-only.ts +103 -0
- package/server-managed/uploads.ts +25 -4
- package/server-managed/upstream-cache.ts +147 -5
- package/server-managed/view-as.ts +58 -0
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import{h as _}from"./chunk-2XUEZHIP.js";var{I:c}=_,o=e=>e;var v=e=>e.strings===void 0,A=()=>document.createComment(""),u=(e,s,t)=>{let a=e._$AA.parentNode,l=s===void 0?e._$AB:s._$AA;if(t===void 0){let r=a.insertBefore(A(),l),$=a.insertBefore(A(),l);t=new c(r,$,e,e.options)}else{let r=t._$AB.nextSibling,$=t._$AM,n=$!==e;if(n){let i;t._$AQ?.(e),t._$AM=e,t._$AP!==void 0&&(i=e._$AU)!==$._$AU&&t._$AP(i)}if(r!==l||n){let i=t._$AA;for(;i!==r;){let m=o(i).nextSibling;o(a).insertBefore(i,l),i=m}}}return t},f=(e,s,t=e)=>(e._$AI(s,t),e),p={},T=(e,s=p)=>e._$AH=s,P=e=>e._$AH,g=e=>{e._$AR(),e._$AA.remove()};export{v as a,u as b,f as c,T as d,P as e,g as f};
|
|
2
|
+
/*! Bundled license information:
|
|
3
|
+
|
|
4
|
+
lit-html/directive-helpers.js:
|
|
5
|
+
(**
|
|
6
|
+
* @license
|
|
7
|
+
* Copyright 2020 Google LLC
|
|
8
|
+
* SPDX-License-Identifier: BSD-3-Clause
|
|
9
|
+
*)
|
|
10
|
+
*/
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
function c(e){return!Number.isFinite(e)||e<0?"\u2014":e<1024?`${e} B`:e<1048576?`${(e/1024).toFixed(1)} KiB`:e<1073741824?`${(e/1048576).toFixed(1)} MiB`:`${(e/1073741824).toFixed(1)} GiB`}function s(e){return Array.isArray(e)?e.reduce((n,r)=>({bytes:n.bytes!=null&&Number.isFinite(r.bytes)?n.bytes+r.bytes:null,lines:n.lines!=null&&Number.isFinite(r.lines)?n.lines+r.lines:null}),{bytes:0,lines:0}):{bytes:null,lines:null}}function f(e,n,r){if(Array.isArray(e?.files))return{files:n.length,lines:s(n).lines,packages:new Set(n.map(o=>o.module)).size};let t=o=>Number.isSafeInteger(o)&&o>=0?o:null,u=e?.summary;return{files:t(u?.[r==="code"?"codeFiles":"files"]),lines:t(u?.lines),packages:null}}function _(e){return(e??[]).filter(n=>!["resource:base64","directory"].includes(n.format))}function i(e,{packageDir:n=null}={}){if(n){if(n!=="."){let r=n.match(/(?:^|\/)node_modules\/(@[^/]+\/[^/]+|[^/]+)$/u);return r&&r[1]!==".pnpm"?r[1]:n}}else{let r=/\.sol$/iu.test(e)?/(?:^|\/)(?:node_modules\/(@[^/]+\/[^/]+|[^/]+)|dependencies\/(@[^/]+\/[^/]+|[^/]+)\/)/gu:/(?:^|\/)node_modules\/(@[^/]+\/[^/]+|[^/]+)/gu,t;for(;(t=r.exec(e))!==null;){let u=t[1]??t[2];if(u!==".pnpm")return u}}return"__own__"}function l(e,n=null){return i(e,{packageDir:n})==="__own__"||!!n&&!/(?:^|\/)(?:node_modules|dependencies|vendor)(?:\/|$)/u.test(n)}function m(e,n=null){let r=[],t=[];for(let u of e)(l(u,n?.get(u))?r:t).push(u);return[...r,...t]}function p(e){return e==="__own__"?"Own source":typeof e!="string"?e:e.match(/^(?:.*\/)?vendor\/(.+)$/u)?.[1]??e}export{c as a,s as b,f as c,_ as d,i as e,l as f,m as g,p as h};
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import{b as w,c as f,j as m,l as k}from"./chunk-HIV7SVI7.js";import{a as h}from"./chunk-TUII34K2.js";var x=3,y=4,H=/^[\w-]{4}$/u,_=/^[\w-]{8}$/u,u="AAAA",R={report:`deepview/finding-link/report/v1
|
|
2
|
+
`,workspace:`deepview/finding-link/workspace/v1
|
|
3
|
+
`},p=new Map;function $(t,e){return`${t}\0${e}`}function I(t){return typeof t=="string"&&H.test(t)}async function T(t,e){let n=R[t];if(!n||typeof e!="string"||!e)return null;let i=$(t,e),o=p.get(i);if(o!==void 0)return o;let r;try{let s=await crypto.subtle.digest("SHA-256",h(n+e));r=new Uint8Array(s).slice(0,x).toBase64({alphabet:"base64url",omitPadding:!0})}catch{return null}return p.set(i,r),r}function E(t,e){return typeof e!="string"||!e?null:p.get($(t,e))??null}function N(t,e){let n=[];for(let[i,o]of[["report",t],["workspace",e]]){if(o==null||o===""){n.push(u);continue}if(!I(o))throw new TypeError(`encodeFindingRef: ${i} must be a link hint token, not a name`);n.push(o)}return n.every(i=>i===u)?null:n[0]===u?`w${n[1]}`:n.join("")}function b(t){let e=[t.slice(0,y),t.slice(y)].map(n=>n===u?null:n);return{report:e[0],workspace:e[1]}}function a({id:t,report:e,workspace:n}={}){if(!f(t))throw new TypeError("encodeFindingRef: a persistent finding id is required");let i=[`finding=${encodeURIComponent(t)}`],o=N(e,n);return o&&i.push(`v=${o}`),i.join("&")}function O(t,e){let n=a(t);return typeof location>"u"?`${e??""}#${n}`:`${location.origin}${e??location.pathname}#${n}`}function A(t){let e=typeof t=="string"?t:typeof location>"u"?"":location.hash;if(!e)return null;let n=e.replace(/^#/u,"");if(!n)return null;let i={id:null,report:null,workspace:null};for(let o of n.split("&")){let r=o.indexOf("=");if(r<0)continue;let s=o.slice(0,r),c=o.slice(r+1);if(!c)continue;if(s==="v"){if(c.length===5&&c[0]==="w"&&I(c.slice(1))){let g=c.slice(1);Object.assign(i,{report:null,workspace:g===u?null:g});continue}if(!_.test(c))continue;Object.assign(i,b(c));continue}if(s!=="finding"||c.length>w*3)continue;let d;try{d=decodeURIComponent(c)}catch{continue}f(d)&&(i.id=d)}return i.id?i:null}function U(t,{managed:e=!1}={}){if(typeof location>"u")return null;let n;try{n=new URL(t)}catch{return null}if(n.href!==t||n.protocol!==location.protocol||n.host!==location.host||n.username||n.password)return null;let i=k(n);if(i?.finding)return{id:i.finding.id,fragment:a(i.finding),path:m(i)};if(e&&i?.view!=="home"&&!/\/(?:index|view)\.html$/u.test(n.pathname))return null;let o=A(n.hash);if(!o)return null;let r=a(o);return{id:o.id,fragment:r,path:`/#${r}`}}function l(t,e){if(typeof t!="string")return!1;let n=t.replaceAll("\\","/");return n.startsWith(`${e}/`)||n.includes(`/${e}/`)}function C(t){let e=!1;for(let n of t){for(let i of n.groups??[])for(let o of i){if(l(o.file,"node_modules"))return"node_modules";l(o.file,"vendor")&&(e=!0)}for(let i of Object.keys(n.tree??{})){if(l(i,"node_modules"))return"node_modules";l(i,"vendor")&&(e=!0)}}return e?"vendor":"dependencies"}export{l as a,C as b,T as c,E as d,a as e,O as f,A as g,U as h};
|
|
@@ -1,88 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
\f\r"'\`<>=]|("|')|))|$)`,"g"),nn=/'/g,rn=/"/g,cn=/^(?:script|style|textarea|title)$/i,dt=t=>(e,...n)=>({_$litType$:t,strings:e,values:n}),x=dt(1),Cs=dt(2),Ts=dt(3),R=Symbol.for("lit-noChange"),w=Symbol.for("lit-nothing"),on=new WeakMap,U=F.createTreeWalker(F,129);function ln(t,e){if(!lt(t)||!t.hasOwnProperty("raw"))throw Error("invalid template strings array");return Qt!==void 0?Qt.createHTML(e):e}var no=(t,e)=>{let n=t.length-1,o=[],r,i=e===2?"<svg>":e===3?"<math>":"",s=ie;for(let c=0;c<n;c++){let a=t[c],l,d,p=-1,u=0;for(;u<a.length&&(s.lastIndex=u,d=s.exec(a),d!==null);)u=s.lastIndex,s===ie?d[1]==="!--"?s=en:d[1]!==void 0?s=tn:d[2]!==void 0?(cn.test(d[2])&&(r=RegExp("</"+d[2],"g")),s=D):d[3]!==void 0&&(s=D):s===D?d[0]===">"?(s=r??ie,p=-1):d[1]===void 0?p=-2:(p=s.lastIndex-d[2].length,l=d[1],s=d[3]===void 0?D:d[3]==='"'?rn:nn):s===rn||s===nn?s=D:s===en||s===tn?s=ie:(s=D,r=void 0);let f=s===D&&t[c+1].startsWith("/>")?" ":"";i+=s===ie?a+eo:p>=0?(o.push(l),a.slice(0,p)+sn+a.slice(p)+T+f):a+T+(p===-2?c:f)}return[ln(t,i+(t[n]||"<?>")+(e===2?"</svg>":e===3?"</math>":"")),o]},ce=class t{constructor({strings:e,_$litType$:n},o){let r;this.parts=[];let i=0,s=0,c=e.length-1,a=this.parts,[l,d]=no(e,n);if(this.el=t.createElement(l,o),U.currentNode=this.el.content,n===2||n===3){let p=this.el.content.firstChild;p.replaceWith(...p.childNodes)}for(;(r=U.nextNode())!==null&&a.length<c;){if(r.nodeType===1){if(r.hasAttributes())for(let p of r.getAttributeNames())if(p.endsWith(sn)){let u=d[s++],f=r.getAttribute(p).split(T),m=/([.?@])?(.*)/.exec(u);a.push({type:1,index:i,name:m[2],strings:f,ctor:m[1]==="."?ot:m[1]==="?"?it:m[1]==="@"?st:q}),r.removeAttribute(p)}else p.startsWith(T)&&(a.push({type:6,index:i}),r.removeAttribute(p));if(cn.test(r.tagName)){let p=r.textContent.split(T),u=p.length-1;if(u>0){r.textContent=Se?Se.emptyScript:"";for(let f=0;f<u;f++)r.append(p[f],se()),U.nextNode(),a.push({type:2,index:++i});r.append(p[u],se())}}}else if(r.nodeType===8)if(r.data===an)a.push({type:2,index:i});else{let p=-1;for(;(p=r.data.indexOf(T,p+1))!==-1;)a.push({type:7,index:i}),p+=T.length-1}i++}}static createElement(e,n){let o=F.createElement("template");return o.innerHTML=e,o}};function Z(t,e,n=t,o){if(e===R)return e;let r=o!==void 0?n._$Co?.[o]:n._$Cl,i=ae(e)?void 0:e._$litDirective$;return r?.constructor!==i&&(r?._$AO?.(!1),i===void 0?r=void 0:(r=new i(t),r._$AT(t,n,o)),o!==void 0?(n._$Co??=[])[o]=r:n._$Cl=r),r!==void 0&&(e=Z(t,r._$AS(t,e.values),r,o)),e}var rt=class{constructor(e,n){this._$AV=[],this._$AN=void 0,this._$AD=e,this._$AM=n}get parentNode(){return this._$AM.parentNode}get _$AU(){return this._$AM._$AU}u(e){let{el:{content:n},parts:o}=this._$AD,r=(e?.creationScope??F).importNode(n,!0);U.currentNode=r;let i=U.nextNode(),s=0,c=0,a=o[0];for(;a!==void 0;){if(s===a.index){let l;a.type===2?l=new le(i,i.nextSibling,this,e):a.type===1?l=new a.ctor(i,a.name,a.strings,this,e):a.type===6&&(l=new at(i,this,e)),this._$AV.push(l),a=o[++c]}s!==a?.index&&(i=U.nextNode(),s++)}return U.currentNode=F,r}p(e){let n=0;for(let o of this._$AV)o!==void 0&&(o.strings!==void 0?(o._$AI(e,o,n),n+=o.strings.length-2):o._$AI(e[n])),n++}},le=class t{get _$AU(){return this._$AM?._$AU??this._$Cv}constructor(e,n,o,r){this.type=2,this._$AH=w,this._$AN=void 0,this._$AA=e,this._$AB=n,this._$AM=o,this.options=r,this._$Cv=r?.isConnected??!0}get parentNode(){let e=this._$AA.parentNode,n=this._$AM;return n!==void 0&&e?.nodeType===11&&(e=n.parentNode),e}get startNode(){return this._$AA}get endNode(){return this._$AB}_$AI(e,n=this){e=Z(this,e,n),ae(e)?e===w||e==null||e===""?(this._$AH!==w&&this._$AR(),this._$AH=w):e!==this._$AH&&e!==R&&this._(e):e._$litType$!==void 0?this.$(e):e.nodeType!==void 0?this.T(e):to(e)?this.k(e):this._(e)}O(e){return this._$AA.parentNode.insertBefore(e,this._$AB)}T(e){this._$AH!==e&&(this._$AR(),this._$AH=this.O(e))}_(e){this._$AH!==w&&ae(this._$AH)?this._$AA.nextSibling.data=e:this.T(F.createTextNode(e)),this._$AH=e}$(e){let{values:n,_$litType$:o}=e,r=typeof o=="number"?this._$AC(e):(o.el===void 0&&(o.el=ce.createElement(ln(o.h,o.h[0]),this.options)),o);if(this._$AH?._$AD===r)this._$AH.p(n);else{let i=new rt(r,this),s=i.u(this.options);i.p(n),this.T(s),this._$AH=i}}_$AC(e){let n=on.get(e.strings);return n===void 0&&on.set(e.strings,n=new ce(e)),n}k(e){lt(this._$AH)||(this._$AH=[],this._$AR());let n=this._$AH,o,r=0;for(let i of e)r===n.length?n.push(o=new t(this.O(se()),this.O(se()),this,this.options)):o=n[r],o._$AI(i),r++;r<n.length&&(this._$AR(o&&o._$AB.nextSibling,r),n.length=r)}_$AR(e=this._$AA.nextSibling,n){for(this._$AP?.(!1,!0,n);e!==this._$AB;){let o=Jt(e).nextSibling;Jt(e).remove(),e=o}}setConnected(e){this._$AM===void 0&&(this._$Cv=e,this._$AP?.(e))}},q=class{get tagName(){return this.element.tagName}get _$AU(){return this._$AM._$AU}constructor(e,n,o,r,i){this.type=1,this._$AH=w,this._$AN=void 0,this.element=e,this.name=n,this._$AM=r,this.options=i,o.length>2||o[0]!==""||o[1]!==""?(this._$AH=Array(o.length-1).fill(new String),this.strings=o):this._$AH=w}_$AI(e,n=this,o,r){let i=this.strings,s=!1;if(i===void 0)e=Z(this,e,n,0),s=!ae(e)||e!==this._$AH&&e!==R,s&&(this._$AH=e);else{let c=e,a,l;for(e=i[0],a=0;a<i.length-1;a++)l=Z(this,c[o+a],n,a),l===R&&(l=this._$AH[a]),s||=!ae(l)||l!==this._$AH[a],l===w?e=w:e!==w&&(e+=(l??"")+i[a+1]),this._$AH[a]=l}s&&!r&&this.j(e)}j(e){e===w?this.element.removeAttribute(this.name):this.element.setAttribute(this.name,e??"")}},ot=class extends q{constructor(){super(...arguments),this.type=3}j(e){this.element[this.name]=e===w?void 0:e}},it=class extends q{constructor(){super(...arguments),this.type=4}j(e){this.element.toggleAttribute(this.name,!!e&&e!==w)}},st=class extends q{constructor(e,n,o,r,i){super(e,n,o,r,i),this.type=5}_$AI(e,n=this){if((e=Z(this,e,n,0)??w)===R)return;let o=this._$AH,r=e===w&&o!==w||e.capture!==o.capture||e.once!==o.once||e.passive!==o.passive,i=e!==w&&(o===w||r);r&&this.element.removeEventListener(this.name,this,o),i&&this.element.addEventListener(this.name,this,e),this._$AH=e}handleEvent(e){typeof this._$AH=="function"?this._$AH.call(this.options?.host??this.element,e):this._$AH.handleEvent(e)}},at=class{constructor(e,n,o){this.element=e,this.type=6,this._$AN=void 0,this._$AM=n,this.options=o}get _$AU(){return this._$AM._$AU}_$AI(e){Z(this,e)}};var ro=ct.litHtmlPolyfillSupport;ro?.(ce,le),(ct.litHtmlVersions??=[]).push("3.3.3");var dn=(t,e,n)=>{let o=n?.renderBefore??e,r=o._$litPart$;if(r===void 0){let i=n?.renderBefore??null;o._$litPart$=r=new le(e.insertBefore(se(),i),i,void 0,n??{})}return r._$AI(t),r};var ut=globalThis,Y=class extends I{constructor(){super(...arguments),this.renderOptions={host:this},this._$Do=void 0}createRenderRoot(){let e=super.createRenderRoot();return this.renderOptions.renderBefore??=e.firstChild,e}update(e){let n=this.render();this.hasUpdated||(this.renderOptions.isConnected=this.isConnected),super.update(e),this._$Do=dn(n,this.renderRoot,this.renderOptions)}connectedCallback(){super.connectedCallback(),this._$Do?.setConnected(!0)}disconnectedCallback(){super.disconnectedCallback(),this._$Do?.setConnected(!1)}render(){return R}};Y._$litElement$=!0,Y.finalized=!0,ut.litElementHydrateSupport?.({LitElement:Y});var oo=ut.litElementPolyfillSupport;oo?.({LitElement:Y});(ut.litElementVersions??=[]).push("4.2.2");var un={ATTRIBUTE:1,CHILD:2,PROPERTY:3,BOOLEAN_ATTRIBUTE:4,EVENT:5,ELEMENT:6},pn=t=>(...e)=>({_$litDirective$:t,values:e}),Ie=class{constructor(e){}get _$AU(){return this._$AM._$AU}_$AT(e,n,o){this._$Ct=e,this._$AM=n,this._$Ci=o}_$AS(e,n){return this.update(e,n)}update(e,n){return this.render(...n)}};var de=class extends Ie{constructor(e){if(super(e),this.it=w,e.type!==un.CHILD)throw Error(this.constructor.directiveName+"() can only be used in child bindings")}render(e){if(e===w||e==null)return this._t=void 0,this.it=e;if(e===R)return e;if(typeof e!="string")throw Error(this.constructor.directiveName+"() called with a non-string value");if(e===this.it)return this._t;this.it=e;let n=[e];return n.raw=n,this._t={_$litType$:this.constructor.resultType,strings:n,values:[]}}};de.directiveName="unsafeHTML",de.resultType=1;var io=pn(de);var so=[["manage","Overview"],["manage-bundles","Bundles"],["manage-scans","Scans"],["manage-reports","Reports"],["manage-deduplication","Deduplication","admin"],["manage-repos","Repositories","admin"],["admin-users","Users","admin"],["manage-teams","Teams","admin"],["manage-import","Import","admin"],["manage-links","Links"],["manage-history","History"]];function fn(t,e,n=!1){return x`<header class="manage-header"><nav class="manage-nav" aria-label="Management pages">${so.filter(([o,,r])=>(r==null||r===e)&&(o!=="manage-links"||n)).map(([o,r])=>x`<button type="button" aria-current="${t===o?"page":w}" @click="${()=>{document.dispatchEvent(new CustomEvent("managed-admin-navigate",{detail:{view:o},bubbles:!0,composed:!0}))}}">${r}</button>`)}</nav></header>`}var mn=`:host{display:flex;flex-direction:column;position:relative;padding:0 clamp(1rem,3vw,3rem) 3rem;color:var(--text);container-type:inline-size;font-family:var(--sans, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif);font-size:.875rem;line-height:1.5;--panel:color-mix(in srgb, var(--bg) 50%, var(--surface));--panel-hover:color-mix(in srgb, var(--text) 3%, var(--panel))}*,*:before,*:after{box-sizing:border-box}button,summary,select,label,legend,h1,h2,h3,.section-heading,.ui-hint,.page-intro>.intro,.count,.result-count,.repository-count,.breadcrumb-separator,.list-head,.report-list-head,.history-head,.drop-copy,.local-import-copy,.location-field>span,.empty:not(.error,[role=alert]),.msg:not(.error,[role=alert]),.local-import-message:not(.error,[role=status]),.data-empty,.revision-empty{cursor:default;user-select:none;-webkit-user-select:none}input:not([type=checkbox],[type=radio]),textarea,[contenteditable],pre,code,.mono{cursor:text;user-select:text;-webkit-user-select:text}.wrap{width:100%;max-width:76rem;margin:0 auto;flex:1;min-height:0;overflow-y:auto;overscroll-behavior:none;scrollbar-gutter:stable}.manage-header{position:sticky;top:0;z-index:2}.wrap:has(>.manage-list){display:flex;flex-direction:column;overflow:hidden;scrollbar-gutter:auto}.wrap:has(>.manage-list)>:not(.manage-list){flex:none}.manage-list{position:relative;flex:1;min-height:0;overflow:auto;overscroll-behavior:contain;scrollbar-gutter:stable}.manage-nav button{flex:0 0 auto;position:relative;min-height:3.7rem;padding:.9rem 0;border:0;border-radius:0;color:var(--muted);background:none;font-size:.8rem;font-weight:500;white-space:nowrap}.manage-nav button:hover,.manage-nav button[aria-current=page]{color:var(--text)}.manage-nav button[aria-current=page]:after{content:"";position:absolute;bottom:.6rem;inset-inline:0;height:2px;background:var(--accent);border-radius:var(--ui-radius, 2px)}.manage-nav button:focus-visible{outline-offset:-3px}.head{display:flex;align-items:center;flex-wrap:wrap;gap:.7rem;margin:0 0 .5rem}h1,.head h1{margin:0;font-size:1.9rem;font-weight:600;letter-spacing:-.045em;line-height:1.2}.count{display:inline-flex;align-items:center;justify-content:center;min-width:1.6rem;padding:.12rem .5rem;border:1px solid var(--border);border-radius:6px;color:var(--muted);background:var(--surface);font-size:.73rem;font-weight:500;font-variant-numeric:tabular-nums}button,input,select{font:inherit}button,select,input[type=checkbox]{cursor:default}button,a,input,select{-webkit-app-region:no-drag}button,a{transition:background .15s,color .15s,border-color .15s}button:focus-visible,a:focus-visible,input:focus-visible,select:focus-visible{outline:2px solid var(--accent);outline-offset:3px}button:disabled,select:disabled{opacity:.45}input:not([type=checkbox]),select{min-width:0;min-height:2.25rem;padding:.45rem .65rem;border:1px solid var(--border);border-radius:var(--ui-radius, 7px);background:var(--bg);color:var(--text);font-size:.8rem}input::placeholder{color:var(--muted)}input[type=checkbox]{accent-color:var(--accent)}.btn,.drop-browse{display:inline-flex;align-items:center;justify-content:center;gap:.45rem;min-height:2.25rem;height:auto;padding:.45rem .8rem;border:1px solid var(--border);border-radius:var(--ui-radius, 7px);background:var(--surface);color:var(--text);font-size:.8rem;font-weight:500;text-decoration:none;white-space:nowrap}.btn:hover:not(:disabled),.drop-browse:hover:not(:disabled){background:var(--surface-active);border-color:var(--muted)}.btn.primary,.drop-browse{color:var(--bg);background:var(--accent);border-color:var(--accent)}.btn.primary:hover:not(:disabled),.drop-browse:hover:not(:disabled){background:var(--accent);filter:brightness(1.08)}.btn svg,.icon-btn svg{width:1rem;height:1rem}.icon-btn{width:2rem;height:2rem}.avatar{color:var(--accent);background:color-mix(in srgb,var(--accent) 12%,var(--bg));border:1px solid color-mix(in srgb,var(--accent) 16%,var(--border))}.breadcrumb{display:flex;align-items:center;flex-basis:100%;gap:.4rem;margin-bottom:.8rem}.breadcrumb-manage{padding:.1rem 0;border:0;background:transparent;color:var(--muted);font-size:.78rem}.breadcrumb-manage:hover{color:var(--text)}.breadcrumb-separator{color:var(--muted)}.msg{margin:1rem 0;padding:1.1rem 1.25rem;border:1px solid var(--border);border-radius:var(--ui-radius, 9px);color:var(--muted);font-size:.85rem}.msg.error{color:var(--critical);border-color:color-mix(in srgb,var(--critical) 35%,var(--border))}.empty{padding:3.5rem 1.5rem;border:1px dashed var(--border);border-radius:var(--ui-radius, 10px);color:var(--muted);text-align:center}.empty strong{display:block;margin-bottom:.4rem;color:var(--text);font-size:.95rem;font-weight:500}.empty p{margin:0;font-size:.85rem}.sr-only{position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap}@container (max-width: 35rem){.drop-copy>span{display:none}.manage-nav{gap:1.2rem;margin-bottom:1.75rem}.manage-nav button{min-height:3.25rem}h1,.head h1{font-size:1.65rem}.intro{margin-bottom:1.5rem}}@media(prefers-reduced-motion:reduce){button,a{transition:none}}.collection-toolbar input{flex:1;max-width:26rem;min-width:10rem}.collection-toolbar select{min-width:10rem}.result-count{text-align:right;white-space:nowrap;margin-left:auto;color:var(--muted);font-size:.75rem;font-variant-numeric:tabular-nums}@container (max-width: 35rem){.collection-toolbar input{flex-basis:100%;max-width:none}}.manage-nav{display:flex;gap:1.35rem;align-items:stretch;overflow-x:auto;scrollbar-width:thin;border-bottom:1px solid var(--border);margin-bottom:1.5rem;padding:0 .1rem}.wrap>:not(.manage-header),.manage-nav{-webkit-app-region:no-drag;app-region:no-drag}@media(display-mode:window-controls-overlay){.manage-header{display:flow-root}.manage-header:before{content:"";float:right;width:var(--wco-right-toolbar, 0px);height:var(--wco-titlebar-height)}.manage-nav{width:max-content;max-width:100%;border-bottom:0}.manage-nav button{min-height:var(--wco-titlebar-height);padding-block:.35rem}.manage-nav button[aria-current=page]:after{bottom:0}}.intro{margin:0 0 1.25rem;max-width:46rem;color:var(--muted);font-size:.875rem;line-height:1.65}.collection-toolbar{display:flex;align-items:center;flex-wrap:wrap;gap:.75rem;margin-bottom:.85rem}.page-intro{display:flex;align-items:center;justify-content:space-between;flex-wrap:wrap;gap:.5rem 1rem;margin-bottom:1.25rem}.page-intro .intro{margin:0}a{cursor:default}.loading-rows{border:1px solid var(--border);border-radius:var(--ui-radius, 10px);overflow:hidden}.loading-row{display:grid;align-content:center;gap:.6rem;min-height:4.25rem;padding:.85rem 1rem}.loading-row+.loading-row{border-top:1px solid var(--border)}.loading-row span{width:40%;height:.65rem;border-radius:3px;background:color-mix(in srgb,var(--muted) 15%,transparent)}.loading-row span+span{width:65%;height:.5rem}.drop-card{display:flex;align-items:center;gap:.75rem;margin-bottom:1rem;padding:.7rem .85rem;border:1px dashed color-mix(in srgb,var(--muted) 35%,var(--border));border-radius:var(--ui-radius, 8px);background:var(--panel)}.drop-icon{display:grid;place-items:center;flex-shrink:0;width:1.8rem;height:1.8rem;color:var(--muted)}.drop-icon svg{width:1.1rem;height:1.1rem}.drop-copy{min-width:0;display:flex;align-items:baseline;flex-wrap:wrap;gap:.2rem .6rem}.drop-copy strong{font-size:.8rem;font-weight:500}.drop-copy>span{color:var(--muted);font-size:.75rem}.drop-browse{min-width:7rem;margin-left:auto;flex-shrink:0}.content-hidden .filename,.content-hidden .report-name,.content-hidden .report-uploader{color:var(--muted)}.status{display:inline-flex;align-items:center;gap:.3rem;width:fit-content;padding:.1rem .4rem;border:1px solid var(--border);border-radius:5px;color:var(--muted);font-size:.65rem}.status:before{content:"";width:.25rem;height:.25rem;border-radius:50%;background:currentcolor}.status.visible{color:var(--green);border-color:rgb(from var(--green) r g b / .2);background:rgb(from var(--green) r g b / .06)}
|
|
4
|
-
`;var hn=`h1{font-size:1.35rem;margin-bottom:.5rem}h2{font-size:1.1rem;margin-bottom:.5rem}.triage-import{display:flex;gap:1rem;align-items:center;margin:1.5rem 0 2rem}.triage-import .btn{flex-shrink:0}.triage-import p{margin:0}.workspace-drop{display:grid;gap:.8rem;padding:2rem;margin:1.5rem 0;border:1px dashed var(--border);border-radius:var(--ui-radius, 8px)}.workspace-drop.dragging{border-color:var(--accent);background:rgb(from var(--accent) r g b / .08)}.workspace-drop span,p,li span{color:var(--muted);line-height:1.5}.actions,.local-choice{display:flex;gap:.8rem;flex-wrap:wrap;align-items:center}.local-choice{margin-bottom:1.5rem}.import-preview{display:grid;gap:.8rem}input:not([type=radio]),select{padding:.55rem;border:1px solid var(--border);border-radius:var(--ui-radius, 5px);color:var(--text);background:var(--bg);font:inherit}.import-preview input:not([type=radio]),.import-preview select{width:100%;box-sizing:border-box}fieldset{display:grid;gap:.8rem;padding:1rem;border:1px solid var(--border);border-radius:var(--ui-radius, 5px)}fieldset label{display:flex;gap:.5rem;align-items:center}li{padding:.4rem 0;overflow-wrap:anywhere}li span{display:block;font-size:.8rem}ul{padding-left:1.2rem}.primary{justify-self:start;color:var(--accent)}.error{color:var(--critical)}button:disabled{opacity:.5}input:focus-visible,select:focus-visible,button:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
|
|
5
|
-
`;var lo=new TextEncoder;function gn(t){if(typeof t!="string")throw new TypeError(`encodeUtf8 expects a string, got ${typeof t}`);if(!t.isWellFormed())throw new TypeError("encodeUtf8: input contains lone surrogates");return lo.encode(t)}async function uo(t){let e=gn(JSON.stringify(t)),n=await crypto.subtle.digest("SHA-256",e),o=new Uint8Array(n,0,16);o[6]=o[6]&15|64,o[8]=o[8]&63|128;let r=Array.from(o,i=>i.toString(16).padStart(2,"0")).join("");return`${r.slice(0,8)}-${r.slice(8,12)}-${r.slice(12,16)}-${r.slice(16,20)}-${r.slice(20,32)}`}async function yn(t){if(typeof crypto?.subtle?.digest!="function")return null;let e=ue(t);try{return await uo(e)}catch{return null}}function ue(t){if(t._idBasis)return t._idBasis;let{severity:e,description:n}=t;return t.fileHash?{severity:e,description:n,fileHash:t.fileHash}:t.location?{severity:e,description:n,location:t.location}:{severity:e,description:n,file:t.file,line:t.line}}var bn=/^( *)(`{3,}|~{3,})(.*)$/u,po=/^ {0,3}(?:#{1,6}(?:[ \t]|$)|>|([-*_])(?:[ \t]*\1){2,}[ \t]*$)/u,wn=/^ {0,3}([-*_])(?:[ \t]*\1){2,}[ \t]*$/u,fo=/^ {0,3}(?:=+|-+)[ \t]*$/u,P=/^( *)(?:[-*+]|\d{1,9}[.)]) +(?=\S)/u,mo=/^ *(?:[-*+]|\d{1,9}[.)])[ \t]*$/u,vn=/^\s*$/u,ho=[[/^<(script|pre|textarea|style)(?:\s|>|$)/iu,/<\/(?:script|pre|textarea|style)>/iu,t=>`</${t[1].toLowerCase()}>`],[/^<!--/u,/-->/u,"-->"],[/^<\?/u,/\?>/u,"?>"],[/^<![A-Za-z]/u,/>/u,"<!-- -->"],[/^<!\[CDATA\[/u,/\]\]>/u,"]]>"],[/^<\/?(?:address|article|aside|base|basefont|blockquote|body|caption|center|col|colgroup|dd|details|dialog|dir|div|dl|dt|fieldset|figcaption|figure|footer|form|frame|frameset|h[1-6]|head|header|hr|html|iframe|legend|li|link|main|menu|menuitem|nav|noframes|ol|optgroup|option|p|param|section|search|summary|table|tbody|td|tfoot|th|thead|title|tr|track|ul)(?:\s|\/?>|$)/iu,vn,null]],go=/^(?:<[A-Za-z][\dA-Za-z-]*(?:\s+[:A-Z_a-z][\w.:-]*(?:\s*=\s*(?:[^\s"'<=>`]+|'[^']*'|"[^"]*"))?)*\s*\/?>|<\/[A-Za-z][\dA-Za-z-]*\s*>)\s*$/u;function Re(t,e,n=e){let o=/^ */u.exec(t)[0].length;if(o>3)return null;if(e&&n&&fo.test(t))return!0;let r=bn.exec(t);if(r&&!(r[2][0]==="`"&&r[3].includes("`")))return{fence:r[2]};let i=t.slice(o);for(let[a,l,d]of ho){let p=a.exec(i);if(p)return{html:l,close:typeof d=="function"?d(p):d}}if(!e&&go.test(i))return{html:vn,close:null};let s=wn.test(t)?null:P.exec(t);if(s&&!(e&&n&&/^ *(?:\d*[02-9]|\d+\d)[.)]/u.test(s[0]))){let a=/ +$/u.exec(s[0])[0].length;return{item:a>4?s[0].length-a+1:s[0].length}}let c=wn.test(t)||e&&n?null:mo.exec(t);return c?{item:c[0].trimEnd().length+1}:po.test(t)||null}function z(t){return pt(t).ranges}function yo(t,e){let n=t.replace(/^(?: {0,3}> ?)+/u,""),o=Re(n,e);for(;o?.item;)n=n.slice(o.item),o=Re(n,!1);return n.trim()!==""&&!o&&/^ */u.exec(n)[0].length<4}function pt(t){let e=[],n=-1,o="",r=null,i=0,s=[],c=!1,a=!1,l=!1,d=0;for(let u of t.split(`
|
|
6
|
-
`)){let f=d;d+=u.length+1;let m=/^ */u.exec(u)[0].length;if(n!==-1||r){let k=i>0&&u.trim()!==""&&m<i,$=!k&&(r?r.ends.test(u):m<=i+3&&_n(o,u));if((k||$)&&(n!==-1&&e.push([n,k?f-1:f+u.length]),n=-1,r=null),!k)continue}if(!u.trim()){l&&s.pop(),l=!1,c=!1;continue}let h=s.length;for(;h>0&&m<s[h-1];)h--;let g=h>0?s[h-1]:0,y=u.slice(g),v=Re(y,c,h===s.length&&!a);if(c&&!v)continue;for(s.length=h;v?.item;)g+=v.item,y=y.slice(v.item),s.push(g),v=Re(y,!1);l=y.trim()==="",v?.fence?[n,o,i]=[f,v.fence,g]:v?.html&&([r,i]=[v.html.test(y)?null:{ends:v.html,close:v.close},g]);let b=c&&a;a=/^ {0,3}>/u.test(y),c=a?yo(y,b):!v&&!l&&/^ */u.exec(y)[0].length<4}n!==-1&&e.push([n,t.length]);let p=n===-1?r?.close:o;return{ranges:e,closer:p?" ".repeat(i)+p:null}}function _n(t,e){let n=bn.exec(e);return n!==null&&n[2][0]===t[0]&&n[2].length>=t.length&&!n[3].trim()}function H(t,e){let n=0,o=t.length;for(;n<o;){let r=n+o>>>1;t[r][1]<=e?n=r+1:o=r}return n<t.length&&e>=t[n][0]}function S(t){return String(t??"").replaceAll(/\r\n?/gu,`
|
|
7
|
-
`)}var Ce=/^## +(.*)$/gmu,pe=/^### +(.*)$/gmu,L=/^#### +(.*)$/gmu,xn=/^##### +(.*)$/gmu,ft=/^(.+):(\d+(?:-\d+)?)$/u;function J(t){return/^[0-9a-f]{7,64}$/iu.test(t)}function $n(t,e){let n=z(t);return[...t.matchAll(e)].filter(o=>!H(n,o.index))}function Te(t,e){let n=$n(t,e);return[t.slice(0,n[0]?.index),...n.map((o,r)=>t.slice(o.index+o[0].length,n[r+1]?.index))]}function M(t,e){let n=$n(t,e);return{head:t.slice(0,n[0]?.index),subs:n.map((o,r)=>({heading:o[1],body:t.slice(o.index+o[0].length+1,n[r+1]?.index)}))}}function O(t,e){return M(t,e).subs}function fe(t){let e=t.indexOf(`
|
|
8
|
-
`);return e===-1?{title:t.trim(),body:""}:{title:t.slice(0,e).trim(),body:t.slice(e+1)}}function me(t){let e=t.split(`
|
|
9
|
-
`).map(o=>o.trim()).filter(o=>o.startsWith("|")&&!(/^[\s:|-]+$/u.test(o)&&o.includes("-"))).map(o=>o.replace(/^\|/u,"").replace(/\|$/u,"").split("|").map(r=>r.trim()));if(e.length<2)return[];let n=e[0].map(o=>o.toLowerCase());return e.slice(1).filter(o=>o.length!==n.length||o.some((r,i)=>r.toLowerCase()!==n[i])).map(o=>Object.fromEntries(n.flatMap((r,i)=>r?[[r,o[i]??""]]:[])))}function En(t){let e=Object.create(null),n=Object.create(null),o=[],r=null,i="",s=[],c="",a=(p,u,f)=>{!p||p in e||(e[p]=f.trim(),n[p]=u)},l=()=>{r&&a(r,i,s.join(`
|
|
10
|
-
`)),r=null,i="",s=[]},d=p=>{(r?s:o).push(p)};for(let p of t.split(`
|
|
11
|
-
`)){let u=/^ {0,3}(```|~~~)/u.exec(p),f=u!==null&&(!c||u[1]===c);if(f&&(c=c?"":u[1]),f||c){d(p);continue}if(!p.trim()){r?l():o.push(p);continue}let m=/^\s*(?:[-*] +)?\*\*([^:*]+):\*\*\s*(.*)$/u.exec(p);if(m){l();let h=m[1].trim(),g=m[2],y;for(;(y=/\s+[·•]\s+\*\*([^:*]+):\*\*\s*/u.exec(g))!==null;)a(h.toLowerCase(),h,g.slice(0,y.index)),h=y[1].trim(),g=g.slice(y.index+y[0].length);r=h.toLowerCase(),i=h,s=[g];continue}if(/^\s*(?:#{1,6} |\||[-=*_]{3,}\s*$)/u.test(p)){l();continue}d(p)}return l(),{fields:e,labels:n,prose:o.join(`
|
|
12
|
-
`).trim()}}function kn(t){let e=(t||"").trim(),n="",o=Q(e);o&&(e=o.label.trim(),n=o.url.trim());let r=/#L(\d+)/u.exec(n)?.[1]??"",c=[...e.matchAll(/`([^`]+)`/gu)].map(d=>d[1].trim()).find(d=>!d.includes("(")&&(d.includes("/")||/\.\w/u.test(d)))??(e.replaceAll("`","").trim().split(/[\s,]+/u).find(Boolean)||""),a=/^(.*?)#L(\d+)(?:-L?\d+)?$/u.exec(c);a&&(c=a[1],r||(r=a[2]));let l=ft.exec(c);return l?(r||(r=l[2]),{file:l[1],line:r,locationLink:n}):{file:c,line:r||"?",locationLink:n}}function mt(t){return t.replaceAll("**","")}function Q(t){let e=String(t??""),n=wo(e,bo(e)),o=vo(e),r=e.indexOf("]");for(let i=e.indexOf("[");i!==-1;i=e.indexOf("[",i+1)){for(;r!==-1&&r<=i;)r=e.indexOf("]",r+1);for(let s of[r,n.get(i)??-1]){if(s===-1||s===i+1||e[s+1]!=="(")continue;let c=_o(e,s+1,o);if(c!==null)return{label:e.slice(i+1,s),url:c,index:i}}}return null}function wo(t,e){let n=new Map,o=[];for(let r=0;r<t.length;r++){let i=t[r];An(t,r)?r++:i==="`"?r=e.get(r)??r:i==="["?o.push(r):i==="]"&&o.length>0&&n.set(o.pop(),r)}return n}function bo(t){let e=[];for(let r=t.indexOf("`");r!==-1;r=t.indexOf("`",r)){let i=1;for(;t[r+i]==="`";)i++;e.push([r,i]),r+=i}let n=new Map,o=new Map;for(let r=e.length-1;r>=0;r--){let[i,s]=e[r],c=o.get(s);c!==void 0&&n.set(i,c+s-1),o.set(s,i)}return n}function vo(t){let e=t.length,n=new Int32Array(e+1).fill(-1),o=new Int32Array(e+1).fill(-1),r=new Int32Array(e+1).fill(-1),i=new Int32Array(e+1).fill(-1);for(let a=e-1;a>=0;a--)n[a]=t[a]===")"?a:n[a+1],o[a]=/\s/u.test(t[a])?a:o[a+1],r[a]=t[a]===">"?a:r[a+1],i[a]=t[a]===`
|
|
13
|
-
`?a:i[a+1];let s=new Map,c=[];for(let a=0;a<e;a++){let l=t[a];An(t,a)?a++:o[a]===a?c.length=0:l==="("?c.push(a):l===")"&&c.length>0&&s.set(c.pop(),a)}return{balanced:s,nextClose:n,nextSpace:o,nextAngle:r,nextLine:i}}function _o(t,e,n){let o=xo(t,e,n);if(o)return o;let r=n.balanced.get(e);if(r!==void 0)return r>e+1?t.slice(e+1,r):null;let i=n.nextClose[e+1],s=n.nextSpace[e+1];return i===-1||i===e+1||s!==-1&&s<i?null:t.slice(e+1,i)}function xo(t,e,n){if(t[e+1]!=="<")return"";let o=n.nextAngle[e+2],r=n.nextLine[e+2];return o===-1||r!==-1&&r<o||t[o+1]!==")"?"":t.slice(e+2,o)}var $o=/\\([!-/:-@[-`{-~])/gu,Eo=/[!-/:-@[-`{-~]/u;function An(t,e){return t[e]==="\\"&&Eo.test(t[e+1]??"")}function Sn(t){return typeof t=="string"?t.replace($o,"$1"):t}function In(t){let e=/^\[(.+)\]$/u.exec(t.trim());return e?e[1].trim():t.trim()}function j(t){let e=(t||"").trim();return/^[-–—]+$/u.test(e)?"":e}var Le=new Map([["CRITICAL","critical"],["HIGH","high"],["MEDIUM","medium"],["LOW","low"],["INFO","informational"],["INFORMATIONAL","informational"],["INFORMATIVE","informative"]]);function Rn(t){return typeof t=="string"&&t.trim().toLowerCase()==="informative"?"informational":t}function E(t,e=t.severity){let n=Rn(t.severity);return n!==t.severity&&(!t.id&&!t._idBasis&&(t._idBasis=ue({...t,severity:e})),t.severity=n),t.correctedSeverity!==void 0&&(t.correctedSeverity=Rn(t.correctedSeverity)),t}var ko=/^## ([A-Z][A-Z_]*)\s*\(\d+\)\s*\n/mu,Ao=new Map([...Le,["HIGH_BUG","high_bug"],["BUG","bug"]]),Ln=t=>String(t??"").toLowerCase().replaceAll(/[^a-z]+/gu,""),Cn=new Map([["high",8],["medium",6],["low",4]]);function So(t){if(t!==void 0)return Cn.get(Ln(t))??Cn.get("medium")}var Io=new Map([["confirmed","confirmed"],["falsepositive","refuted"],["uncertain","unknown"]]);function Mn(t){let n=S(t).trim().split(ko);if(n.length===1)return null;let o=[];for(let r=1;r<n.length;r+=2){let i=Ao.get(n[r].toUpperCase())??"medium";for(let s of Te(n[r+1],/^### /gmu).slice(1)){let c=Tn(s,i);if(!c)continue;let a=s.indexOf(`
|
|
14
|
-
### `);a!==-1&&(c._idBasis=ue(Tn(s.slice(0,a+1),i))),o.push(c)}}return o.length===0?null:{type:"security",source:"deepsec",findings:o}}function Tn(t,e){let{title:n,body:o}=fe(t);if(!n)return null;let r=o.replace(/\n---\s*$/u,"").trim(),i=Object.fromEntries([...r.matchAll(/^- \*\*([^:*]+):\*\*\s*(.+)$/gmu)].map(g=>[g[1].trim().toLowerCase(),g[2].trim()])),s=/^\*\*Recommendation:\*\*\s*/mu.exec(r),c=s?r.slice(0,s.index):r,a=s?r.slice(s.index+s[0].length).trim():"",l=c.split(`
|
|
15
|
-
`).filter(g=>!/^\s*- \*\*/u.test(g)).join(`
|
|
16
|
-
`).replaceAll("**","").trim(),d=[n,l].filter(Boolean).join(`
|
|
1
|
+
import{g as z,j as B,n as O,o as M,t as k,u as A,v as W,w as G,x}from"./chunk-F4OMDNEY.js";import{a as U,c as F}from"./chunk-35VE6CDH.js";import{a as P}from"./chunk-NRPC74AM.js";import{e as y}from"./chunk-W4J3MGLB.js";import{a as H}from"./chunk-GJ4IUCNS.js";import"./chunk-PNHBZGDD.js";import"./chunk-ZPD5R5RP.js";import"./chunk-DIJJNTRH.js";import"./chunk-HIV7SVI7.js";import{D as C}from"./chunk-GNXOKIGP.js";import"./chunk-C4Z6ZBXV.js";import{a as R,c as g,g as w}from"./chunk-2XUEZHIP.js";import"./chunk-TUII34K2.js";import"./chunk-V5O7M2YT.js";import"./chunk-OOJM4CTU.js";var J=`h1{font-size:1.35rem;margin-bottom:.5rem}h2{font-size:1.1rem;margin-bottom:.5rem}.triage-import{display:flex;gap:1rem;align-items:center;margin:1.5rem 0 2rem}.triage-import .btn{flex-shrink:0}.triage-import p{margin:0}.workspace-drop{display:grid;gap:.8rem;padding:2rem;margin:1.5rem 0;border:1px dashed var(--border);border-radius:var(--ui-radius, 8px)}.workspace-drop.dragging{border-color:var(--accent);background:rgb(from var(--accent) r g b / .08)}.workspace-drop span,p,li span{color:var(--muted);line-height:1.5}.actions,.local-choice{display:flex;gap:.8rem;flex-wrap:wrap;align-items:center}.local-choice{margin-bottom:1.5rem}.import-preview{display:grid;gap:.8rem}input:not([type=radio]),select{padding:.55rem;border:1px solid var(--border);border-radius:var(--ui-radius, 5px);color:var(--text);background:var(--bg);font:inherit}.import-preview input:not([type=radio]),.import-preview select{width:100%;box-sizing:border-box}fieldset{display:grid;gap:.8rem;padding:1rem;border:1px solid var(--border);border-radius:var(--ui-radius, 5px)}fieldset label{display:flex;gap:.5rem;align-items:center}li{padding:.4rem 0;overflow-wrap:anywhere}li span{display:block;font-size:.8rem}ul{padding-left:1.2rem}.primary{justify-self:start;color:var(--accent)}.error{color:var(--critical)}button:disabled{opacity:.5}input:focus-visible,select:focus-visible,button:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
|
|
2
|
+
`;async function X(t,{session:p,confirmImport:n,...a}){if(p?.role!=="admin"||!p.csrfToken)throw new Error("An administrator session is required.");if(t!=null&&(typeof t!="object"||Array.isArray(t)))throw new Error("Invalid local triage.");let e=Object.create(null);for(let[l,h]of Object.entries(t??{})){let{ignoredReports:m,scopedIgnoredReports:d,...f}=y(h)??{};Object.keys(f).length!==0&&(e[l]=f)}let i=Object.keys(e).length,o=new Set,c=[],s;if(i>0)do{a.signal?.throwIfAborted();let l="/api/admin/reports/finding-ids"+(s?`?after=${encodeURIComponent(s)}`:""),{reports:h,nextCursor:m}=await a.api.send(l);a.signal?.throwIfAborted();for(let d of h){let f=d.findingIds.filter(u=>Object.hasOwn(e,u)&&!o.has(u));f.length>0&&c.push({id:d.id,ids:f});for(let u of f)o.add(u)}s=m}while(s);for(let l of o){if(!l||l.length>100)throw new Error(`Triage finding IDs must be between 1 and ${100} characters.`);if(x(e[l])==="invalid")throw new Error(`Triage for ${l} exceeds the managed server limits.`)}if(a.signal?.throwIfAborted(),n){let l=await n({matched:o.size,available:i});if(a.signal?.throwIfAborted(),!l)return null}let r=a.importedIds??new Set;for(let l of c)await j(e,{...a,importedIds:r,ids:l.ids,path:`/api/admin/reports/${encodeURIComponent(l.id)}/import-triage`});return o.size}function ae(t,p){let n=[],a=Object.create(null);for(let[e,i]of Object.entries(t)){let o=p[e];if(!o)throw new Error("The server did not return the requested triage snapshot.");let c=o.entry??{},s=a[e]={...c};delete s.comment;for(let[r,l]of Object.entries(i))if(r==="comment"){if(o.comments.some(h=>h.body===l))continue;o.comments.length>0?n.push({id:e,property:r,local:o.comments.map(h=>h.body).join(`
|
|
17
3
|
|
|
18
|
-
`),p=(i.file||"unknown").replace(/^`(.*)`$/u,"$1"),u=(i.lines||"").split(",").map(g=>g.trim()).find(Boolean)||"?",f={file:p,line:u,severity:e,description:d};a&&(f.recommendation=a.replaceAll("**",""));let m=So(i.confidence);m!==void 0&&(f.confidence=m);let h=Io.get(Ln(i.revalidation));return h&&(f.revalidate=h,f.revalidateSource="deepsec",i.reasoning&&(f.revalidateVerdict=i.reasoning.replaceAll("**",""))),i.slug&&(f.slug=i.slug),E(f,e==="informative"?"medium":e)}var On={critical:"Critical",high:"High",medium:"Medium",low:"Low",high_bug:"High bug",bug:"Bug",informational:"Informational"};var Me={"claude-security":"Claude Security","codex-security":"Codex Security",deepsec:"DeepSec",piolium:"Piolium","markdown-generic":"Markdown (generic)"};var ht=["critical","high","medium","low","high_bug","bug","informational"];var Oe=["revalidation","refuted","unreachable","confirmed","partial","unknown"],Ro=new Set(Oe);function Nn(t){return Ro.has(t?.revalidate)?t.revalidate:""}function gt(t,e=t?.source){return Object.hasOwn(Me,e)||Nn(t)==="revalidation"}function yt(t){return t?t.split(`
|
|
19
|
-
`).find(e=>e.trim())?.trim()??"":""}function wt(t){return Number.isFinite(parseInt(t?.line,10))?`${t.file}:${t.line}`:t?.file??""}function bt(t){if(typeof t!="string"||t.length===0)return!1;try{let e=new URL(t);return e.protocol==="http:"||e.protocol==="https:"}catch{return!1}}function Co(t,e){let n=z(t),o=0;return t.split(`
|
|
20
|
-
`).map(r=>{let i=o;return o+=r.length+1,H(n,i)?r:e(r)}).join(`
|
|
21
|
-
`)}function V(t){return Co(String(t??""),e=>e.replace(/^( {0,3})\\(\\*#)/u,"$1$2"))}var To=/^(?:https?:\/\/)?(?:www\.)?github\.com\/([^/?#]+)\/([^/?#]+?)(?:\.git)?(?:[/?#].*)?$/iu,Lo=/^[\w.-]+\/[\w.-]+$/u;function vt(t){return Lo.test(t)}function G(t){let e=t?.repo?.github;if(typeof e!="string")return null;let n=e.trim().replace(/\/+$/u,"");if(!n)return null;let o=To.exec(n),r=(o?`${o[1]}/${o[2]}`:n).replace(/\.git$/u,"");return vt(r)?r:null}var Bn=[["Impact","impact",!1],["Reproduction","reproduction",!1],["Recommendation","recommendation",!1],["Confidence reasoning","confidenceReason",!1],["Revalidation verdict","revalidateVerdict",!0],["Revalidation recommendation","revalidateRecommendation",!0]],Dn=[["Status","status"],["Branch","branch"],["Date created","dateCreated"],["Detected at","detectedAt"],["Committed at","committedAt"],["PoC status","pocStatus"],["Variant of","parent"],["Slug","slug"],["Priority","priority"]],Un=[["Detailed report","reportPath"],["Commit audited","auditedCommit"],["ID","id"]];var Mo=new Map(Object.entries(On).map(([t,e])=>[e.toLowerCase(),t])),Pn=new Map(Object.entries(Me).map(([t,e])=>[e.toLowerCase(),t]));function W(t){let e=/(`+)(.+?)\1(?!`)/u.exec(String(t??""));if(!e)return null;let n=e[2];if(n.length>2&&n.startsWith(" ")&&n.endsWith(" ")){let o=n.slice(1,-1);if(o.startsWith("`")||o.endsWith("`"))return o}return n}function Be(t){let e=Q(String(t??""));return e?.index===0?{label:e.label,url:e.url}:null}function zn(t){let e=/^<(https?:[^>\s]*)>$/u.exec(t.trim());return e?e[1]:null}function Hn(t){let e=ft.exec(t);return e?{file:e[1],line:e[2]}:{file:t,line:"?"}}function Oo(t){let e=t.indexOf(".");return e>0?{exportName:t.slice(0,e),methodName:t.slice(e+1)}:{exportName:t}}function Ne(t){let e=String(t??"").trim();return Mo.get(e.toLowerCase())??e}function No(t){let e={},n=t.trim(),o=/ · (`+)(.+?)\1$/u.exec(n);o&&(Object.assign(e,Oo(W(o[0]))),n=n.slice(0,o.index));let r=Be(n),i=W(r?r.label:n);return i!==null&&Object.assign(e,Hn(i)),r&&bt(r.url)&&(e.location=r.url),e}var Fn=" \xB7 flagged critical by the analyzer",Bo=" (varies across reports \u2014 ";function Do(t){let e={},n=t.trim();n.endsWith(Fn)&&(e.critical=!0,n=n.slice(0,-Fn.length));let o=n.indexOf(Bo);o!==-1&&(n=n.slice(0,o));let r=/^(.*?) — corrected (from|to) (.*)$/u.exec(n);return r?[e.severity,e.correctedSeverity]=(r[2]==="from"?[r[3],r[1]]:[r[1],r[3]]).map(Ne):e.severity=Ne(n),e}var Uo=new Set(["max","xhigh","high","medium","low","minimal"]),Fo=new Set(["list","isolate"]);function Po(t){return/\d/u.test(t)||/^(?:opus|sonnet|haiku|gpt|gemini|fable|mythos|llama|mistral)\b/iu.test(t)}function De(t){let e=t.trim(),n=Pn.get(e.toLowerCase());if(n)return{source:n};let o={},r=[];for(let i of e.split(" \xB7 ").map(s=>s.trim()).filter(Boolean))i==="revalidate"&&!o.revalidate?o.revalidate="revalidation":Fo.has(i)&&!o.exportsMode?o.exportsMode=i:Uo.has(i)&&!o.effort?o.effort=i:r.push(i);return r.length>1?[o.type,o.model]=r:r.length===1&&(o[Po(r[0])?"model":"type"]=r[0]),{run:o}}function _t(t){let e=t.trim(),n=Be(e);return n?n.label.trim():zn(e)??e}function zo(t){let e=Be(t.trim());if(e){let n=e.url.split("/").at(-1)??"";return J(n)?n:W(e.label)??n}return W(t)??t.trim()}function Ho(t){let e=W(t)??t.trim(),n=e.lastIndexOf("@");return{npm:n>0?{name:e.slice(0,n),version:e.slice(n+1)}:{name:e}}}function jo(t){let e=t.trim().toLowerCase();return e==="the revalidation pass itself"?"revalidation":Oe.includes(e)?e:void 0}var Vo=new Map([...[["Category","category"],...Dn].map(([t,e])=>[t.toLowerCase(),(n,o)=>{n[e]=o}]),...[...Un,["Found while analyzing","discoveredIn"]].map(([t,e])=>[t.toLowerCase(),(n,o)=>{n[e]=W(o)??o}]),["location",(t,e)=>Object.assign(t,No(e))],["severity",(t,e)=>Object.assign(t,Do(e))],["confidence",(t,e)=>{let n=/^(\d+(?:\.\d+)?)\/10$/u.exec(e);n&&(t.confidence=Number(n[1]))}],["revalidation",(t,e)=>{let n=jo(e);n&&(t.revalidate=n)}],["revalidated by",(t,e)=>{let n=e.trim();n&&(t.revalidateSource=Pn.get(n.toLowerCase())??n)}],["repository",(t,e)=>{t.repo={github:_t(e)}}],["introduced in",(t,e)=>{t.commitHash=zo(e)}],["package",(t,e)=>{t.package=Ho(e)}],["priority",(t,e)=>{t.priority=/^-?\d+(?:\.\d+)?$/u.test(e)?Number(e):e}]]);function jn(t,e,n){let o=Vo.get(e.trim().toLowerCase());o&&o(t,n.trim())}var Go=/^- \*\*([^*\n]+?):\*\* ?(.*)$/u;function Vn(t){let e=t.split(`
|
|
22
|
-
`),n=0,o=()=>{for(;n<e.length&&!e[n].trim();)n++},r=()=>{let c=[];for(let a;(a=Go.exec(e[n]??""))!==null;n++)c.push([a[1].trim(),a[2].trim()]);return c};o();let i=r();if(i.length>0)return{title:"",facts:i,rest:e.slice(n).join(`
|
|
23
|
-
`)};let s=[];for(;n<e.length&&e[n].trim();)s.push(e[n++]);return o(),i=r(),i.length===0?{title:"",facts:i,rest:t}:{title:V(s.join(`
|
|
24
|
-
`).trim()),facts:i,rest:e.slice(n).join(`
|
|
25
|
-
`)}}var Wo=/^(\d+)\. (.*)$/u;function Gn(t){let e=[],n=z(t),o=0;for(let r of t.split(`
|
|
26
|
-
`)){let i=H(n,o)?null:Wo.exec(r);o+=r.length+1,i?e.push({ref:i[2].trim(),indent:i[1].length+2,note:[]}):e.length>0&&e.at(-1).note.push(r)}return e.map(r=>Ko(r))}function Ko({ref:t,indent:e,note:n}){let o={},r=Be(t),i=zn(t),s=i===null?W(r?r.label:t):null;s!==null&&Object.assign(o,Hn(s));let c=r?r.url:i;bt(c)&&(o.url=c);let a=V(n.map(l=>l.slice(Math.min(e,/^ */u.exec(l)[0].length))).join(`
|
|
27
|
-
`).trim());return a&&(o.text=a),o}var Wn=new Map(Bn.map(([t,e])=>[t.toLowerCase(),e])),Xo=[...Wn.keys()];function Kn(t){let e=t.length,n=1/0;for(let o=t.length-1;o>=0;o--){let r=Xo.indexOf(t[o].label.toLowerCase());if(r===-1||r>=n)break;n=r,e=o}return{paragraphs:t.slice(0,e),fields:t.slice(e).map(o=>[Wn.get(o.label.toLowerCase()),o.body])}}function Xn(t,e,n){let o=[],r=yt(e),i=t.endsWith("\u2026")?t.slice(0,-1).trimEnd():"";!t||r===t||i&&r.startsWith(i)?o.push(e):o.push(t,e);for(let{label:s,body:c}of n)o.push(c?`**${s}:** ${c}`:`**${s}:**`);return o.filter(Boolean).join(`
|
|
28
|
-
|
|
29
|
-
`)}var Zo=/^<!--\s*DeepView findings export\b[^>]*-->/u,qo=/^Case \d+ of \d+(?:\s|$)/u,Yo=/^- \*\*([^*\n]+?):\*\* ?(.*)$/gmu,Jo=new Set(["evidence","severity correction","comment"]);function qn(t){let e=S(t).trim();if(!Zo.test(e))return null;let{head:n,subs:o}=M(e,Ce),r=[];for(let{heading:i,body:s}of o){if(i.trim().toLowerCase()==="summary")continue;let c=Qo(i);for(let a of O(s,pe))r.push(ti(a,c))}return ri(ei(n),r)}function Qo(t){let e=/^(.*?)\s*\(\d+\)\s*$/u.exec(t.trim());return Ne(e?e[1]:t)}function ei(t){let e=new Map;for(let n of t.matchAll(Yo)){let o=n[1].trim().toLowerCase();e.has(o)||e.set(o,n[2].trim())}return{sources:(e.get("source")??"").split(",").map(n=>De(n).source).filter(Boolean),analyzers:(e.get("analyzer")??e.get("analyzers")??"").split(";").map(n=>n.trim()).filter(Boolean),repo:e.has("repository")?_t(e.get("repository")):""}}function ti({heading:t,body:e},n){let o=t.trim().replace(/^\d+\.\s+/u,""),r=O(e,L).filter(i=>qo.test(i.heading.trim()));return r.length===0?[Zn(e,L,o,n)]:r.map(i=>Zn(i.body,xn,o,n))}function Zn(t,e,n,o){let{title:r,facts:i,rest:s}=Vn(t),{head:c,subs:a}=M(s,e),l=a.map(b=>({label:b.heading.trim(),body:b.body.trim()})),d={file:"unknown",line:"?"},p=null;for(let[b,k]of i)b.trim().toLowerCase()==="analyzer"?p=De(k):jn(d,b,k);d.severity||(d.severity=o||"medium");let u=r||n,f=u!=="Untitled finding"&&u!==wt(d),m=l.filter(b=>!Jo.has(b.label.toLowerCase())).map(b=>({label:b.label,body:V(b.body)})),{paragraphs:h,fields:g}=Kn(m);d.description=Xn(f?u:"",V(c.trim()),h);let y=l.filter(b=>b.label.toLowerCase()==="evidence").flatMap(b=>Gn(b.body));y.length>0&&(d.evidence=y);for(let[b,k]of g)d[b]=k;let v=l.find(b=>b.label.toLowerCase()==="severity correction");return v?.body&&(d.correctedSeverityReason=V(v.body)),{finding:E(d),analyzer:p}}function ni(t,e){let n={source:null,run:{}};if(e.some(r=>r.analyzer!==null)){let r=new Set(e.map(i=>i.analyzer?.source??null));r.size===1&&!r.has(null)&&([n.source]=r);for(let i of e)i.analyzer?.run?Object.assign(i.finding,i.analyzer.run):i.analyzer?.source&&!n.source&&(i.finding.source=i.analyzer.source);return n}let o=t.analyzers.length===1?De(t.analyzers[0]):null;return o?.source?n.source=o.source:o?.run?n.run=o.run:t.analyzers.length===0&&t.sources.length===1&&([n.source]=t.sources),n}function ri(t,e){let n=e.flat(),{source:o,run:r}=ni(t,n),i={},s=new Set(n.map(l=>l.finding.type).filter(Boolean)),c=r.type??(s.size===1?[...s][0]:null)??(o?"security":null);c&&(i.type=c),o&&(i.source=o);for(let l of["model","effort","exportsMode"])r[l]&&(i[l]=r[l]);t.repo&&(i.repo={github:t.repo});let a=e.map(l=>l.map(d=>d.finding));return a.every(l=>l.length===1)?i.findings=a.flat():i.groups=a,i}var xt="markdown-generic",oi=["#","id","product","priority","vulnerability"],ii=["title","description","root cause","code references","attack scenario","steps to reproduce","impact","patch"],si=/^(?:#{3,6}[ \t]+)?(?:\*\*)?(Title|Description|Root Cause|Code references|Attack Scenario|Steps to Reproduce(?:[ \t]+.*?)?|Impact|Patch):?(?:\*\*)?(?:[ \t]+#+)?[ \t]*$/gimu,Yn={P0:"critical",P1:"high",P2:"medium",P3:"low",P4:"informational"},ee=t=>t.trim().slice(1,-1).split("|").map(e=>e.trim());function _(t,e){if(!t)throw new Error(`Markdown (generic): unsupported ${e}`)}function ai(t){return[...new Set(t.split(`
|
|
30
|
-
`).map(e=>e.trim()).filter(Boolean))].map(e=>{_(/^https?:\/\/[^\s()[\]{}"'<>`\\]+$/iu.test(e)&&!/[.,;!?]$/u.test(e),"link syntax; use bare URLs on separate lines");let n;try{n=new URL(e)}catch{_(!1,"URL")}let[o,r,i,s,...c]=n.pathname.slice(1).split("/");_(["github.com","www.github.com"].includes(n.hostname)&&!n.username&&!n.password&&!n.port&&[o,r].every(p=>p&&/^[\w-][\w.-]*$/u.test(p)),"repository URL"),_(c.every(Boolean),"repository path; empty components");let a=`${o}/${r.replace(/\.git$/iu,"")}`.toLowerCase(),l=/^#L(\d+)(?:-L?(\d+))?$/u.exec(n.hash),d=i==="blob"?c.slice(0,-1):i==="tree"?c:[];try{d=d.map(decodeURIComponent)}catch{_(!1,"repository directory encoding")}return _(d.every(p=>p===p.trim()&&!/[\\/:?#\p{Cc}]/u.test(p)),"repository directory"),{repo:a,ref:s,directory:d,...i==="blob"&&c.length&&{evidence:{file:c.join("/"),line:l?l.slice(1).filter(Boolean).join("-"):"?",url:e}}}})}function ci(t,e,n,o){let r=ai(n),i=r[0]?.repo;_(i&&r.every(a=>a.repo===i),`repository set for finding ${t.id}; expected exactly one repository`),_(!t.group.github||t.group.github===i,`repository set for product ${t.product}; expected exactly one repository`);let s=o.get(i);_(s===void 0||s===t.prefix,`repository ID prefixes for ${i}; expected ${s}, got ${t.prefix} (${t.id})`),o.set(i,t.prefix),t.group.github=i,t.group.directories.push(...r.map(a=>a.directory));let c=r.flatMap(a=>a.evidence??[]);if(c.length){Object.assign(e,{file:c[0].file,line:c[0].line,location:c[0].url,evidence:c});let a=r.find(l=>l.evidence).ref;J(a)&&(e.commitHash=a)}}function li(t){let e=t[0];for(let n of t.slice(1)){let o=0;for(;o<e.length&&e[o]===n[o];)o++;e=e.slice(0,o)}return e.join("/")}function di(t){let e=S(t).trim(),n=[...e.matchAll(/^## +(.*)$/gmu)];if(!n.some(d=>/^\d+\.\s+\S+/u.test(d[1]))&&(n.length||e.startsWith("# ")))return null;let o=[...e.matchAll(/^\|[^\n]*\|$/gmu)].find(([d])=>ee(d).map(p=>p.toLowerCase()).join()===oi.join());if(!o)return null;let r=e.slice(0,o.index).trim();_(!r||/^# [^\n]+$/u.test(r),"summary preamble"),_(o.index<(n[0]?.index??e.length),"summary position");let i=e.slice(o.index,n[0]?.index).trim().split(`
|
|
31
|
-
`),s=new Set(ee(i[0]).map(d=>d.toLowerCase()));_(i[1]&&ee(i[1]).length===5&&ee(i[1]).every(d=>/^:?-{3,}:?$/u.test(d)),"summary separator");let c=new Map,a=new Map,l=new Map;for(let d of i.slice(2).filter(p=>p.trim())){_(/^\|.*\|$/u.test(d)&&ee(d).length===5,"summary row");let[p,u,f,m]=ee(d),h=/^(.+-)\d+$/u.exec(u)?.[1];_(/^\d+$/u.test(p)&&h&&f&&Object.hasOwn(Yn,m)&&!l.has(u),`summary values for ${u}`);let g=c.get(f)??{directories:[],rows:[]},y={raw:d,id:u,prefix:h,product:f,priority:m,group:g};l.set(u,y),g.rows.push(y),c.set(f,g)}_(l.size,"empty summary");for(let[d,p]of n.entries()){let u=/^\d+\.\s+(\S+)\s*$/u.exec(p[1])?.[1],f=l.get(u);_(f&&!f.finding,`finding section ${p[1]}`);let m=e.slice(p.index,n[d+1]?.index),h=m.slice(p[0].length+1),g=new Map,y=[...h.matchAll(si)];for(let[$,A]of y.entries()){let Qe=A[1],Gt=Qe.toLowerCase().replace(/^steps to reproduce\b.*$/u,"steps to reproduce");_(!g.has(Gt),`duplicate section ${Qe}`),g.set(Gt,{heading:Qe,body:h.slice(A.index+A[0].length,y[$+1]?.index).trim()})}_(ii.every($=>g.has($)),`missing required headers for ${u}`),_(!h.slice(0,y[0].index).trim(),`text before field headers for ${u}`);let v=g.get("title")?.body;_(v,`missing Title for ${u}`);let b={sourceId:u,_idBasis:{source:xt,row:f.raw.trim(),section:m.trim()},product:f.product,priority:f.priority,severity:Yn[f.priority],file:"unknown",line:"?"};s.has("vulnerability")&&(b.security=!0);let k=[v];for(let[$,A]of g)$==="title"||$==="code references"||($==="steps to reproduce"?b.reproduction=A.body:$==="patch"?b.recommendation=A.body:k.push($==="description"?A.body:`**${A.heading}:**
|
|
32
|
-
${A.body}`));b.description=k.join(`
|
|
33
|
-
|
|
34
|
-
`),ci(f,b,g.get("code references").body,a),f.finding=b}return _([...l.values()].every(d=>d.finding),"missing finding sections"),[...c].map(([d,p])=>{let u={github:p.github,directory:li(p.directories)},f=p.rows.map(({finding:m})=>({...m,repo:{github:p.github}}));return{displayName:d,data:{type:"security",source:xt,product:d,repo:u,findings:f}}})}function Jn(t){let e=di(t);return e===null?null:e.length===1?e[0].data:{type:"security",source:xt,findings:e.flatMap(({data:n})=>n.findings)}}var ui=new Set(["critical","high","medium","low","high_bug","bug","informational"]);function Qn(t){let e=pi(t);if(!e)return null;let{severity:n,description:o,location:r,file:i,line:s}=e;return r?{severity:n,description:o,location:r}:{severity:n,description:o,file:i,line:s}}function pi(t){let e=t.indexOf(`
|
|
35
|
-
`),n=(e===-1?t:t.slice(0,e)).trim();if(!n)return null;let o=e===-1?"":t.slice(e+1),{sectionsText:r,metaText:i}=fi(o),s=mi(r),c=hi(i),{file:a,line:l,locationLink:d}=gi(s.location||""),p=(c.severity||"").toLowerCase();return{severity:ui.has(p)?p:"medium",description:yi(n,s),location:d,file:a||"unknown",line:l}}function fi(t){let e=/^---\s*$/mu,n=e.exec(t);if(!n)return{sectionsText:t,metaText:""};let o=t.slice(0,n.index).trim(),r=t.slice(n.index+n[0].length).replace(/^\n/u,""),i=e.exec(r),s=i?r.slice(0,i.index):r;return{sectionsText:o,metaText:s}}function mi(t){let e={},n=t.split(/^## /mu);for(let o=1;o<n.length;o++){let r=n[o],i=r.indexOf(`
|
|
36
|
-
`),s=(i===-1?r:r.slice(0,i)).trim().toLowerCase(),c=(i===-1?"":r.slice(i+1)).trim();s&&(e[s]=c)}return e}function hi(t){let e={};for(let n of t.matchAll(/\*\*([^:]+):\*\*\s*(.+)/gu))e[n[1].trim().toLowerCase()]=n[2].trim();return e}function gi(t){let e="",n="?",o="",r=t.match(/\[([^\]]+)\]\(([^)]+)\)/u);if(r){e=r[1].trim(),o=r[2];let s=r[2].match(/#L(\d+)/u);s&&(n=s[1])}else e=t.trim(),o=t.trim();let i=e.match(/^(.+):(\d+)$/u);return i&&(e=i[1],n==="?"&&(n=i[2])),{file:e,line:n,locationLink:o}}function yi(t,e){let n=[t];return e.details&&n.push(e.details),e.impact&&n.push(`Impact: ${e.impact}`),e["reproduction steps"]&&n.push(`Reproduction: ${e["reproduction steps"]}`),wi(n.join(`
|
|
37
|
-
|
|
38
|
-
`))}function wi(t){return t.replaceAll("**","")}var bi=new Set([...ht,"informative"]);function nr(t){let e=S(t).trim();if(!e.startsWith("# "))return null;let o=Te(e,/^# /gmu).slice(1).filter(r=>r.trim().length>0).map(r=>vi(r)).filter(Boolean);return o.length===0?null:{type:"security",source:"claude-security",findings:o}}function vi(t){let{title:e,body:n}=fe(t);if(!e)return null;let{sectionsText:o,metaText:r}=_i(n),i=xi(o),s=Object.fromEntries([...r.matchAll(/\*\*([^:]+):\*\*\s*(.+)/gu)].map(y=>[y[1].trim().toLowerCase(),y[2].trim()])),c=Ai(i.evidence||""),{file:a,line:l,locationLink:d}=rr(i.location||c[0]?.ref||""),p=(s.severity||"").toLowerCase(),u=bi.has(p)?p:"medium",f=Ii(e,i,c.length>0),m={file:a||"unknown",line:l,severity:u,description:f};d&&(m.location=d),c.length>0&&(m.evidence=c.map(Si)),i["reproduction steps"]&&(m.reproduction=$i(i["reproduction steps"])),i["recommended fix"]&&(m.recommendation=i["recommended fix"]),s.repository&&(m.repo={github:s.repository}),s.branch&&(m.branch=s.branch),s["date created"]&&(m.dateCreated=s["date created"]),s.status&&(m.status=s.status),s.category&&(m.category=s.category);let h=t.indexOf(`
|
|
39
|
-
# `),g=Qn(h===-1?t:t.slice(0,h+1));return g&&(m._idBasis=g),E(m)}function _i(t){let e=/^---\s*$/mu,n=e.exec(t);if(!n)return{sectionsText:t,metaText:""};let o=t.slice(0,n.index).trim(),r=t.slice(n.index+n[0].length).replace(/^\n/u,""),i=e.exec(r),s=i?r.slice(0,i.index):r;return{sectionsText:o,metaText:s}}function xi(t){let e=t.split(/^## /mu).slice(1).map(n=>fe(n));return Object.fromEntries(e.filter(n=>n.title).map(n=>[n.title.toLowerCase(),n.body.trim()]))}function rr(t){let e="",n="?",o="",r=Q(t);if(r){e=r.label.trim(),o=r.url.trim();let s=o.match(/#L(\d+)(?:-L?(\d+))?/u);s&&(n=s[2]?`${s[1]}-${s[2]}`:s[1])}else e=t.trim(),o=t.trim();e=Sn(e.replaceAll("`","")).trim();let i=e.match(/^(.+):(\d+)(?:\s*[-–—]\s*L?(\d+))?$/u);return i&&(e=i[1],n==="?"&&(n=i[3]?`${i[2]}-${i[3]}`:i[2])),{file:e,line:n,locationLink:o,linked:r!==null}}function $i(t){let e=t.split(`
|
|
40
|
-
`),n=e.findIndex(c=>c.trim());if(n===-1||!P.test(e[n])||e.some((c,a)=>a!==n&&P.test(c)))return t;let o=e[n].replace(/^ */u,""),r=o.replace(P,"");if(!r.trim())return t;let i=er(r)??er(o);if(i===null&&(P.test(r)||ki.test(o)))return t;let s=i===null?[r]:i.length===1?[i[0].step]:i.map(({number:c,step:a})=>`${c}. ${a}`);return e.splice(n,1,...s),e.join(`
|
|
41
|
-
`)}var Ei=/(?:^|[ \t])(\d{1,9})\)(?=[ \t]|$)/gu,ki=/^\d{1,9}\)(?=[ \t]|$)/u;function er(t){let e=[...t.matchAll(Ei)];if(e.length===0||e[0].index!==0)return null;let n=[];for(let[o,r]of e.entries()){let i=Number(r[1]);if(o>0&&i<=n[o-1].number)return null;let s=t.slice(r.index+r[0].length,e[o+1]?.index).trim();if(!s)return null;n.push({number:i,step:s})}return n}var tr=/^[ \t]*(?:\d+[.)]|[-*+])\s+/u;function Ai(t){let e=[];for(let n of t.split(`
|
|
42
|
-
`))tr.test(n)?e.push({ref:n.replace(tr,"").trim(),note:[]}):e.length>0&&n.trim()&&e.at(-1).note.push(n.trim());if(e.length===0){let n=t.split(`
|
|
43
|
-
`).map(i=>i.trim()).filter(Boolean),o=n.findIndex(i=>Q(i)!==null);if(o===-1&&n.length!==1)return[];let r=o===-1?0:o;e.push({ref:n[r],note:n.filter((i,s)=>s!==r)})}return e.filter(n=>n.ref)}function Si({ref:t,note:e}){let{file:n,line:o,locationLink:r,linked:i}=rr(t),s={file:n||"unknown",line:o};r&&i&&(s.url=r);let c=e.join(`
|
|
44
|
-
`);return c&&(s.text=c),s}function Ii(t,e,n){let o=[t];return e.details&&o.push(e.details),e.evidence&&!n&&o.push(`**Evidence:**
|
|
45
|
-
${e.evidence}`),e.impact&&o.push(`**Impact:** ${e.impact}`),o.join(`
|
|
46
|
-
|
|
47
|
-
`)}function Ri(t){let e=(t||"").trim(),n="",o=/\[([^\]]+)\]\(([^)]+)\)/u.exec(e);o&&(e=o[1].trim(),n=o[2].trim());let r="",i=/#L(\d+)/u.exec(n);i&&(r=i[1]);let a=[...e.matchAll(/`([^`]+)`/gu)].map(p=>p[1].trim()).find(p=>!p.includes("(")&&(p.includes("/")||/\.\w/u.test(p)))??(e.replaceAll("`","").trim().split(/[\s,]+/u).find(Boolean)||""),l=/^(.*?)#L(\d+)(?:-L?\d+)?$/u.exec(a);l&&(a=l[1],r||(r=l[2]));let d=/^(.+):(\d+(?:-\d+)?)$/u.exec(a);return d?(r||(r=d[2]),{file:d[1],line:r,locationLink:n}):{file:a,line:r||"?",locationLink:n}}function or({severity:t,description:e,ref:n,lineBullet:o="",id:r=""}){let i=Ri(n),s=i.file||"unknown",c=i.line==="?"&&o?o:i.line,a=i.locationLink||(s==="unknown"&&r?`piolium:${r}`:"");return a?{severity:t,description:e,location:a}:{severity:t,description:e,file:s,line:c}}function N(t){let e=((t||"").trim().split(/\s+/u)[0]||"").replaceAll(/[`*]+/gu,"");return Le.get(e.toUpperCase())??""}function he(...t){return{severity:t.find(Boolean)||"medium",identitySeverity:t.find(e=>e&&e!=="informative")||"medium"}}function ge(t){let e=/^([CHML])-?\d+$/iu.exec((t||"").trim());return e?{C:"critical",H:"high",M:"medium",L:"low"}[e[1].toUpperCase()]:""}function $t(t){return N(/^(critical|high|medium|low|informational|informative|info)(?:[ -](?:severity|risk))?(?:[ -]findings?)?(?:\s*\(\d+\))?$/iu.exec((t||"").trim())?.[1])}function ir(t){return N(/^(critical|high|medium|low|informational|informative|info)\b/iu.exec((t||"").trim())?.[1])}function Fe(t){return/^variants?\s*(?:\(\d+\))?\s*:?$/iu.test((t||"").trim())}function Pe(t){let e=/^([CHML]-?\d{1,4}|(?:p|q|b|r|m|l|x|diff)\d{0,4}-\d{2,4})(?:-([A-Za-z0-9][\w-]*))?$/iu.exec(t||"");return e?{id:e[1].toUpperCase(),slug:e[2]||""}:null}function Ue(t){return(t||"").replaceAll("-"," ")}function ye(t){let e=(t||"").trim(),n=/^\[([^\]]+)\]\([^)]*\)$/u.exec(e);return In(n?n[1]:e).toUpperCase()}function Et(t){let e=/^\[([^\]]+)\]\(([^)]+)\)\s*[:—–-]*\s*(.*)$/u.exec(t);return e?{text:e[3]?`${e[1].trim()} ${e[3].trim()}`:e[1].trim(),link:e[2].trim()}:null}function kt(t){let e=t.search(/\s/u),n=(e===-1?t:t.slice(0,e)).replace(/[:.,—–-]+$/u,""),o=Pe(n);if(!o)return null;let r=(e===-1?"":t.slice(e+1)).replace(/^[:—–-]+\s*/u,"").trim();return{id:o.id,slug:o.slug,rest:r}}function At(t){let{text:e,link:n}=Et(t)??{text:t,link:""},o=/^\[([^\]]+)\] *(.*)$/u.exec(e);if(o){let i=Pe(o[1].trim());return i?{id:i.id,title:o[2].trim()||Ue(i.slug)||i.id,link:n}:{id:o[1].trim().toUpperCase(),title:o[2].trim(),link:n}}let r=kt(e);return r?{id:r.id,title:r.rest||Ue(r.slug)||r.id,link:n}:{id:"",title:e.trim(),link:n}}function sr(t){let e={},n=i=>{let s=i.exec(t||"")?.[1];return s===void 0?"":(/`([^`]+)`/u.exec(s)?.[1]??s.split(/\s+/u)[0]??"").trim()},o=n(/^\s*(?:[-*] +)?\*\*Target:?\*\*\s*(.*)$/imu);vt(o)&&(e.repo=o);let r=n(/^\s*(?:[-*] +)?\*\*Commit[^:*]*:?\*\*\s*(.*)$/imu);return J(r)&&(e.commitHash=r),e}var St=["key code reference","key code","code reference","location","affected file","file","path"];function ze(t){return{id:ye(t.id||""),title:j(t.title),severity:j(t.severity),pocStatus:j(t["poc status"]||t.poc),status:j(t.status),parent:ye(j(t.parent||"")),location:j(t.location)}}function He(t,e=""){let{severity:n,identitySeverity:o}=he(N(t.severity),e,ge(t.id)),r=It({ref:t.location||"",id:t.id,severity:n,identitySeverity:o,description:mt(t.title||t.id)});for(let i of["pocStatus","status","parent"])t[i]&&(r[i]=t[i]);return E(r)}function It({ref:t,lineBullet:e="",id:n,severity:o,identitySeverity:r,description:i}){let{file:s,line:c,locationLink:a}=kn(t),l={file:s||"unknown",line:c==="?"&&e?e:c,severity:o,description:i};return a?l.location=a:l.file==="unknown"&&n&&(l.location=`piolium:${n}`),l._idBasis=or({severity:r,description:i,ref:t,lineBullet:e,id:n}),l}function Rt(t,e,n){let o=[];for(let r of t.split(`
|
|
48
|
-
`)){let i=/^\s{0,3}(?:[-*+]|\d{1,3}[.)])\s+(.+)$/u.exec(r);if(!i)continue;let s=i[1].trim();if(/^\*\*[^:*]+:\*\*/u.test(s))continue;let c=Et(s),a=c?.link??"";if(c)s=c.text;else{let g=/^\*\*([^*]+)\*\*\s*[:—–-]*\s*(.*)$/u.exec(s);g&&(s=g[2]?`${g[1].trim()} ${g[2].trim()}`:g[1].trim())}if(/^(?:none\b|no |n\/a\b)/iu.test(s))continue;let l=kt(s),d=l?.id??"",p=s;if(l){let g=Ue(l.slug);p=g&&l.rest?`${g}
|
|
49
|
-
|
|
50
|
-
${l.rest}`:l.rest||g||l.id}let u=n.get(d),{severity:f,identitySeverity:m}=he(N(u?.severity),e,ge(d)),h={file:"unknown",line:"?",severity:f,description:mt(p)};d?h.location=`piolium:${d}`:a&&(h.location=a),a.endsWith("report.md")&&(h.reportPath=a);for(let g of["pocStatus","status","parent"])u?.[g]&&(h[g]=u[g]);o.push({id:d,finding:E(h,m)})}return o}function Ct(t,e,n,o=""){let r=[];for(let s of me(t)){let c=ze(s);!c.id&&!c.title||(!c.parent&&n&&(c.parent=n),c.id&&!e.has(c.id)&&e.set(c.id,c),r.push({id:c.id,finding:He(c,o)}))}if(r.length>0)return r;let i=Rt(t,o,e);for(let s of i)n&&!s.finding.parent&&(s.finding.parent=n);return i}var Ci=new Set(["technical findings detail","technical findings","detailed findings","findings detail","findings"]),Ti=/^(?:summary of findings\b|deferred|methodolog|executive|conclusion|attack surface|coverage|discoveries|scope\b|table of contents|contents\b|appendix|recommendation|remediation)/u;function ar(t){let{id:e}=At(t);return!!(e&&Pe(e))}function Li(t){let e=O(t,pe);return(e.length>0?e:O(t,L)).some(({heading:o})=>ar(o))}function cr(t){let e=S(t).trim();if(!/^# +Security Audit Report\b/mu.test(e)&&!/^## +Technical Findings Detail\s*$/imu.test(e)&&!/^## +Findings by Severity\b/imu.test(e))return null;let{head:n,subs:o}=M(e,Ce),r=Bi(o),i=new Map(me(r["summary of findings"]||"").map(ze).filter(u=>u.id).map(u=>[u.id,u])),s=sr(n),c=[],a=new Set,l=[],d=({id:u,finding:f})=>{c.push(f),u&&a.add(u)},p=u=>{for(let f of u)d(f)};for(let[u,f]of Object.entries(r)){let m=$t(u);m||Ci.has(u)||u.startsWith("findings by severity")?p(Tt(f,m,i,l)):!Ti.test(u)&&Li(f)&&p(Tt(f,ir(u),i,l))}for(let u of l)(!u.id||!a.has(u.id))&&d(u);for(let u of i.values())a.has(u.id)||d({id:u.id,finding:He(u)});if(c.length===0)return null;for(let u of c)s.repo&&(u.repo={github:s.repo}),s.commitHash&&!u.auditedCommit&&(u.auditedCommit=s.commitHash);return{type:"security",source:"piolium",findings:c}}function Mi(t,e,n,o){let r=[],i="";for(let{heading:s,body:c}of t){let a=$t(s);if(a)r.push(...Tt(c,a,e,n)),i="";else if(Fe(s))r.push(...Ni(c,e,i,n,o));else{let l=Oi(s,c,e,n,o);r.push(...l),i=l[0]?.id||i}}return r}function Oi(t,e,n,o,r){let{head:i,subs:s}=M(e,L),c=lr(t,i,n,r),a=c!==null&&!c.id&&s.some(d=>!Fe(d.heading)&&ar(d.heading)),l=c&&!a?[c]:[];return l.push(...Lt(s,n,o,r,c?.id||"")),l}function Ni(t,e,n,o,r){let{head:i,subs:s}=M(t,L);return o.push(...Ct(i,e,n,r)),Lt(s,e,o,r,"")}function Lt(t,e,n,o,r){let i=[],s="";for(let{heading:c,body:a}of t){if(Fe(c)){n.push(...Ct(a,e,r??s,o));continue}let l=lr(c,a,e,o);l&&(i.push(l),s=l.id||s)}return i}function Tt(t,e,n,o){let r=O(t,pe);if(r.length>0)return Mi(r,n,o,e);let i=Lt(O(t,L),n,o,e,null);if(i.length>0)return i;let s=me(t).map(ze).filter(c=>c.id||c.title);for(let c of s)!c.severity&&e&&(c.severity=e),c.id&&!n.has(c.id)?n.set(c.id,c):c.id||o.push({id:"",finding:He(c,e)});return s.length===0&&o.push(...Rt(t,e,n)),[]}function lr(t,e,n,o=""){let r=t.trim();if(!r)return null;let{id:i,title:s,link:c}=At(r),a=n.get(i);if(!i&&s){let $=s.toLowerCase();a=[...n.values()].find(A=>A.title.toLowerCase()===$),i=a?.id??""}let{fields:l,labels:d,prose:p}=En(e),{severity:u,identitySeverity:f}=he(N(l.severity),N(a?.severity),o,ge(i)),m=/\d+/u.exec(l.line||l.lines||"")?.[0]??"",h=/\*\*Variant of:?\*\*\s*\[?([^\]\s)]+)/iu.exec(e),g=p.split(`
|
|
51
|
-
`).filter($=>!/^\s*<a\s[^>]*>\s*<\/a>\s*$/iu.test($)&&!/\*\*Variant of:?\*\*/iu.test($)).join(`
|
|
52
|
-
`).trim(),y=It({ref:St.map($=>l[$]).find(Boolean)??"",lineBullet:m,id:i,severity:u,identitySeverity:f,description:Ui(s||i,l,d,g)}),v=l["poc status"]||l.poc||a?.pocStatus;v&&(y.pocStatus=v);let b=l["detailed report"]||(c.endsWith("report.md")?c:"");b&&(y.reportPath=b),a?.status&&(y.status=a.status);let k=a?.parent||(h?ye(h[1]):"");return k&&(y.parent=k),{id:i,finding:E(y)}}function Bi(t){let e=Object.create(null);for(let{heading:n,body:o}of t){let r=n.trim().toLowerCase();r&&(e[r]=r in e?`${e[r]}
|
|
53
|
-
${o}`:o)}return e}var Di=new Set([...St,"severity","summary","files","poc","poc status","line","lines","detailed report","proof of concept","evidence","variant of","pattern","status","id","title"]);function Ui(t,e,n,o){let r=[t];e.summary&&r.push(e.summary),o&&r.push(o);for(let[i,s]of Object.entries(e))!s||Di.has(i)||r.push(`**${n[i]||i}:** ${s}`);return r.filter(Boolean).join(`
|
|
54
|
-
|
|
55
|
-
`)}var Fi=["finding_url","repository","title","description","severity","configured_scan_id","relevant_paths"];function Pi(t){let e=[],n=[],o="",r=!1;for(let i=0;i<t.length;i++){let s=t[i];r?s==='"'?t[i+1]==='"'?(o+='"',i++):r=!1:o+=s:s==='"'?r=!0:s===","?(n.push(o),o=""):s===`
|
|
56
|
-
`||s==="\r"?(n.push(o),e.push(n),n=[],o="",s==="\r"&&t[i+1]===`
|
|
57
|
-
`&&i++):o+=s}for((o!==""||n.length>0)&&(n.push(o),e.push(n));e.length>0&&e.at(-1).length===1&&e.at(-1)[0]==="";)e.pop();return e}function zi(t,e){return e.map(n=>{let o=Object.create(null);return t.forEach((r,i)=>{o[r]=n[i]??""}),o})}function Mt(t){let e=Pi(t);if(e.length<2)throw new Error("Codex CSV: empty or missing header row");let[n,...o]=e;for(let s of Fi)if(!n.includes(s))throw new Error(`Codex CSV: missing required column "${s}"`);let r=Map.groupBy(zi(n,o).filter(s=>s.configured_scan_id),s=>s.configured_scan_id);if(r.size===0)throw new Error("Codex CSV: no rows with a configured_scan_id");let i=[];for(let[s,c]of r){let a=new Set(c.map(p=>p.repository).filter(Boolean));if(a.size>1)throw new Error(`Codex CSV: scan ${s} contains multiple repositories: ${[...a].join(", ")}`);let d=`${[...a][0]||"unknown-repo"}:${s.replace(/^[^:]+:/u,"")}`;i.push({displayName:d,data:{type:"security",source:"codex-security",findings:c.map(Hi)}})}return i}function Hi(t){let e=t.relevant_paths.split(" | ").map(r=>r.trim()).find(Boolean)||"unknown",n=[t.title,t.description].filter(Boolean).join(`
|
|
58
|
-
|
|
59
|
-
`),o={id:t.finding_url,file:e,line:"?",severity:(t.severity||"medium").toLowerCase(),description:n,repo:{github:t.repository}};return t.commit_hash&&(o.commitHash=t.commit_hash),t.detected_at&&(o.detectedAt=t.detected_at),t.committed_at&&(o.committedAt=t.committed_at),E(o)}var Vi=[["deepview-md",qn],["markdown-generic",Jn],["deepsec",Mn],["piolium",cr],["claude-security",nr]];function we(t){return Array.isArray(t?.findings)?t.findings:Array.isArray(t?.groups)?t.groups:null}function dr(t,e){return typeof e=="string"&&/\.csv$/iu.test(e)?"codex":je(t).format}function je(t){let e;try{let n=JSON.parse(t);if(we(n)){for(let o of ur(we(n)))E(o);return{data:n,format:"json",reason:null}}return{data:null,format:null,reason:"JSON, but not a report: no findings array"}}catch(n){e=n}for(let[n,o]of Vi)try{let r=o(t);if(r)return{data:r,format:n,reason:null}}catch(r){if(n!=="markdown-generic")throw r;return{data:null,format:n,reason:r.message}}return{data:null,format:null,reason:`Not JSON, and not a recognized markdown format. (JSON error: ${e.message})`}}function ur(t){return t.flat().filter(e=>e&&typeof e=="object")}async function Gi(t){for(let o of t)E(o);let e=t.filter(o=>!o.id);if(e.length===0)return;let n=await Promise.all(e.map(yn));e.forEach((o,r)=>{n[r]&&(o.id=n[r])})}async function Ve(t){let{data:e,format:n}=je(t);if(!e)return null;let o=ur(we(e));return await Gi(o),{format:n,data:e,findings:o}}function C(t,e){if(typeof t!="string")return!1;let n=t.replaceAll("\\","/");return n.startsWith(`${e}/`)||n.includes(`/${e}/`)}function be(t){let e=!1;for(let n of t){for(let o of n.groups??[])for(let r of o){if(C(r.file,"node_modules"))return"node_modules";C(r.file,"vendor")&&(e=!0)}for(let o of Object.keys(n.tree??{})){if(C(o,"node_modules"))return"node_modules";C(o,"vendor")&&(e=!0)}}return e?"vendor":"dependencies"}function fr(t){return t==="inprogress"||t==="fixed"||t==="invalid"||t==="deleted"||t==="ignored"?t:void 0}function ve(t){if(t)return fr(t.triage)??(t.deleted?"deleted":void 0)}function Wi(t){return t?!t.color&&!ve(t)&&!t.comment&&!t.fix&&!(t.ignoredReports&&t.ignoredReports.length>0)&&t.flagged===void 0:!0}function Ot(t,e){return Array.isArray(t?.scopedIgnoredReports)&&t.scopedIgnoredReports.includes(e)}function B(t){if(!t||typeof t!="object")return;let e=t,n={};typeof e.color=="string"&&e.color&&(n.color=e.color);let o=fr(e.triage)??(e.deleted?"deleted":void 0);if(o&&(n.triage=o),typeof e.comment=="string"&&e.comment&&(n.comment=e.comment),typeof e.fix=="string"&&e.fix&&(n.fix=e.fix),typeof e.flagged=="boolean"&&(n.flagged=e.flagged),Array.isArray(e.ignoredReports)){let r=e.ignoredReports.filter(i=>typeof i=="string"&&i.length>0);r.length>0&&(n.ignoredReports=r)}if(Array.isArray(e.scopedIgnoredReports)&&n.ignoredReports){let r=[...new Set(e.scopedIgnoredReports.filter(i=>typeof i=="string"&&n.ignoredReports.includes(i)))];r.length>0&&(n.scopedIgnoredReports=r)}return Wi(n)?void 0:n}function pr(t,e){let n=t??[],o=e??[];if(n.length!==o.length)return!1;if(n.length===0)return!0;let r=new Set(n);for(let i of o)if(!r.has(i))return!1;return!0}function Ki(t,e){let n=t??{},o=e??{};return(n.color??"")===(o.color??"")&&(ve(n)??"")===(ve(o)??"")&&(n.comment??"")===(o.comment??"")&&(n.fix??"")===(o.fix??"")&&n.flagged===o.flagged&&pr(n.ignoredReports,o.ignoredReports)&&pr(n.scopedIgnoredReports,o.scopedIgnoredReports)}function Nt(t,e,n){let o=t.get(e),r=B({...o,...n});return r===void 0?t.delete(e):Ki(o,r)?!1:(t.set(e,r),!0)}function Bt(t,e,n,o,r=!1){let i=new Set(t.get(e)?.ignoredReports??[]);o?i.add(n):i.delete(n);let s=new Set(t.get(e)?.scopedIgnoredReports??[]);return o&&r&&s.add(n),Nt(t,e,{ignoredReports:i.size>0?[...i]:void 0,scopedIgnoredReports:[...s]})}function Dt(t,e){return!(t.isApp??gt(t,t._source??t.source))&&C(t.file,t._depsDirectory??e??be([{groups:[[t]]}]))}function Xi(t,e){if(![...t.values()].some(o=>o?.ignoredReports?.length))return!1;let n=!1;for(let o of e){let r=be([o]),i=(o.groups??[]).flat(),s=a=>({...a,_source:a._source??a.source??o.source}),c=new Set(i.filter(a=>Dt(s(a),r)).map(a=>a.id??String(a._id)));for(let a of i){let l=a.id??String(a._id),d=a._reportName??o.name??o.fileName??"",p=t.get(l);p?.ignoredReports?.includes(d)&&(Ot(p,d)||Dt(s(a),r)||(ve(p)||(n=Nt(t,l,{triage:"ignored"})||n),c.has(l)||(n=Bt(t,l,d,!1)||n)))}for(let a of i){if(!Dt(s(a),r))continue;let l=a.id??String(a._id),d=a._reportName??o.name??o.fileName??"";t.get(l)?.ignoredReports?.includes(d)&&(n=Bt(t,l,d,!0,!0)||n)}}return n}async function Zi(t,e){let n=new Set(Object.values(t??{}).flatMap(r=>Array.isArray(r?.ignoredReports)?r.ignoredReports.filter(i=>typeof i=="string"&&!Ot(r,i)):[])),o=[];for(let r of n){let i;try{let s=await e(r);if(typeof s!="string")continue;i=await Ve(s)}catch{continue}i&&o.push({...i.data,name:r,groups:[i.findings]})}return o}async function mr(t,e){if(t!=null&&(typeof t!="object"||Array.isArray(t)))return{entries:t,changed:!1};let n=new Map(Object.entries(t??{})),o=await Zi(t,e),r=Xi(n,o);return{entries:Object.fromEntries(n),changed:r}}var qi=new TextEncoder,Yi=new TextDecoder("utf-8",{fatal:!0,ignoreBOM:!0});function Ge(t){if(typeof t!="string")throw new TypeError(`encodeUtf8 expects a string, got ${typeof t}`);if(!t.isWellFormed())throw new TypeError("encodeUtf8: input contains lone surrogates");return qi.encode(t)}function hr(t){if(!ArrayBuffer.isView(t)&&!(t instanceof ArrayBuffer))throw new TypeError(`decodeUtf8 expects a BufferSource, got ${t===null?"null":typeof t}`);return Yi.decode(t)}async function Ji(t,{maxBytes:e}={}){let n=new Blob([t]).stream().pipeThrough(new DecompressionStream("gzip"));if(e==null)return new Uint8Array(await new Response(n).arrayBuffer());let o=n.getReader(),r=[],i=0;for(;;){let{value:a,done:l}=await o.read();if(l)break;if(i+=a.length,i>e){try{await o.cancel()}catch{}throw new Error(`gunzipBytes: decompressed size exceeds ${e}-byte cap`)}r.push(a)}let s=new Uint8Array(i),c=0;for(let a of r)s.set(a,c),c+=a.length;return s}async function Ut(t){return hr(await Ji(t))}var gr=1,We=16,yr=12,wr=1+We+yr+16,Ft=1+We+yr;async function es(t,e){let n=await crypto.subtle.importKey("raw",Ge(t),"PBKDF2",!1,["deriveKey"]);return crypto.subtle.deriveKey({name:"PBKDF2",hash:"SHA-256",salt:e,iterations:3e6},n,{name:"AES-GCM",length:256},!1,["encrypt","decrypt"])}function br(t){return!(t instanceof Uint8Array)||t.length<wr?!1:t[0]===gr}async function ts(t,e){if(typeof e!="string"||!e)throw new TypeError("tryDecryptWithPassword: password required");if(!(t instanceof Uint8Array)||t.length<wr)return{ok:!1,reason:"malformed"};if(t[0]!==gr)return{ok:!1,reason:"malformed"};let n=t.subarray(1,1+We),o=t.subarray(1+We,Ft),r=t.subarray(Ft),i=await es(e,n),s;try{s=new Uint8Array(await crypto.subtle.decrypt({name:"AES-GCM",iv:o,additionalData:t.subarray(0,Ft)},i,r))}catch{return{ok:!1,reason:"wrong-password"}}return{ok:!0,plaintext:s}}async function vr(t,e,n){if(!n||typeof n.malformedMsg!="string"||typeof n.wrongPasswordMsg!="string")throw new TypeError("decryptWithPasswordOrThrow: { malformedMsg, wrongPasswordMsg } strings required");let o=await ts(t,e);if(o.ok)return o.plaintext;throw o.reason==="wrong-password"?new Error(n.wrongPasswordMsg):new Error(n.malformedMsg)}var Ke=br;function _r(t,e){return vr(t,e,{malformedMsg:"malformed encrypted bundle",wrongPasswordMsg:"wrong password or corrupt bundle"})}var ns=1,xr=1024,$r=1024,Xe=200,Ar=100*1024*1024,rs=Math.ceil(Ar*4/3)+16,Er=512,kr=64;function os(t){if(!t||typeof t!="object")return"payload is not an object";if(t.version!==ns)return`unsupported export version: ${t.version}`;if(!t.workspace||typeof t.workspace!="object")return"workspace metadata missing";if(typeof t.workspace.id!="string")return"workspace.id must be a string";if(typeof t.workspace.name!="string")return"workspace.name must be a string";if(typeof t.workspace.privateKey!="string")return"workspace.privateKey must be a string";if(t.workspace.createdAt!==void 0&&!Number.isFinite(t.workspace.createdAt))return"workspace.createdAt must be a finite number or omitted";if(!Array.isArray(t.reports))return"reports field must be an array";if(t.reports.length>$r)return`reports count (${t.reports.length}) exceeds cap (${$r})`;if(t.bundles!==void 0){if(!Array.isArray(t.bundles))return"bundles field must be an array when present";if(t.bundles.length>xr)return`bundles count (${t.bundles.length}) exceeds cap (${xr})`;for(let e of t.bundles){if(typeof e!="string")return"bundles entries must be strings";if(e.length>Xe)return`bundle integrity exceeds per-entry length cap (${Xe})`}}if(t.bundleBlobs!==void 0){if(!Array.isArray(t.bundleBlobs))return"bundleBlobs field must be an array when present";if(t.bundleBlobs.length>kr)return`bundleBlobs count (${t.bundleBlobs.length}) exceeds cap (${kr})`;for(let e of t.bundleBlobs){if(!e||typeof e!="object"||Array.isArray(e))return"bundleBlobs entries must be objects";if(typeof e.integrity!="string"||e.integrity.length===0)return"bundleBlobs.integrity must be a non-empty string";if(e.integrity.length>Xe)return`bundleBlobs.integrity exceeds per-entry length cap (${Xe})`;if(typeof e.name!="string"||e.name.length===0)return"bundleBlobs.name must be a non-empty string";if(e.name.length>Er)return`bundleBlobs.name exceeds per-entry length cap (${Er})`;if(e.name.includes("\0"))return"bundleBlobs.name cannot contain NUL";if(typeof e.data!="string")return"bundleBlobs.data must be a base64 string";if(e.data.length>rs)return`bundleBlobs.data exceeds per-blob size cap (${Ar} bytes raw)`}}return null}async function Pt(t,e){if(Ke(t)){if(typeof e!="string"||!e)throw new TypeError("parseWorkspaceBundleBytes: password required for encrypted bundle");let o=await _r(t,e);try{return Ze(await Ut(o))}catch(r){throw new Error("wrong password or corrupt bundle",{cause:r})}}let n;try{n=await Ut(t)}catch(o){throw new Error(`gzip decompression failed: ${o.message}`,{cause:o})}return Ze(n)}function Ze(t){let e;try{e=JSON.parse(t)}catch(r){throw new Error(`payload is not JSON: ${r.message}`,{cause:r})}let n=os(e);if(n===null)return e;let o=n.includes("exceeds cap");throw new Error(o?n:`not a deepview workspace export: ${n}`)}var is=/^\d+$/u;function ss(t){for(let e=0;e<t.length;e++){let n=t.codePointAt(e);if(n<32||n===127)return!0}return!1}var zt=512;function as(t){return typeof t=="string"&&t.length>0&&t.length<=zt&&!ss(t)}function _e(t){return as(t)&&!is.test(t)}var al=Object.freeze({manage:"/manage","manage-bundles":"/manage/bundle","manage-scans":"/manage/scans","manage-reports":"/manage/report","manage-repos":"/manage/repositories","admin-users":"/manage/users","manage-teams":"/manage/team","manage-import":"/manage/import","manage-links":"/manage/links","manage-deduplication":"/manage/deduplication","manage-history":"/manage/history"});function cs(t){if(typeof t=="string")return t.length>0?t:null;if(!t||typeof t!="object"||Array.isArray(t))return null;let{id:e}=t;return typeof e=="string"&&e.length>0?e:null}function Sr(t){let e;try{e=JSON.parse(t)}catch{return null}if(!Array.isArray(e)||e.length===0)return null;let n=[],o=0;for(let r of e){if(!Array.isArray(r))return null;let i=new Set;for(let s of r){let c=cs(s);if(c===null)return null;_e(c)?i.add(c):o++}i.size>1&&n.push([...i])}return{groups:n,skipped:o}}function Ht(t,e){return!t||e===t||e.startsWith(`${t}/`)}function ls(t,e){if(Ht(t.oldPath,e)){let o=e.slice(t.oldPath.length).replace(/^\//u,"");return{directory:[t.newPath,o].filter(Boolean).join("/"),filePrefix:""}}if(!Ht(e,t.oldPath))return null;let n=t.oldPath.slice(e.length).replace(/^\//u,"");return t.newPath===n?{directory:"",filePrefix:n}:t.newPath.endsWith(`/${n}`)?{directory:t.newPath.slice(0,-n.length-1),filePrefix:n}:null}function Ir(t,e,n,o=""){let r=null,i=-1;for(let s of n){if(s.oldRepo.toLowerCase()!==t.toLowerCase())continue;let c=ls(s,e);!c||!Ht(c.filePrefix,o)||s.oldPath.length<=i||(r={repoId:s.repoId,directory:c.directory},i=s.oldPath.length)}return r}function Rr(t){let e;for(let n of t){let o=n.split("/");if(o.some(r=>!r||r==="."||r==="..")||n.includes("\\"))return"";if(o.pop(),e===void 0)e=o;else{let r=0;for(;r<e.length&&r<o.length&&e[r]===o[r];)r++;e.length=r}if(e.length===0)return""}return e?.join("/")??""}function K(t,e){let n=t.trimStart().startsWith("[")?Sr(t):null;if(n)return{data:{source:"links",findings:[],links:n.groups},format:"links",reason:null};let o=je(t);if(o.data!=null||dr(t,e)!=="codex")return o;try{return{data:{type:"security",source:"codex-security",findings:Mt(t).flatMap(i=>i.data.findings)},format:"codex",reason:null}}catch(r){return{data:null,format:null,reason:r instanceof Error?r.message:"Invalid Codex CSV"}}}function qe(t,e){let n=K(t,e);return n.data==null?Promise.resolve(null):Ve(JSON.stringify(n.data))}function ds(t){let e=new Set;for(let n of t){if(!n||typeof n!="object")continue;let o=n;typeof o.file=="string"&&o.file&&e.add(o.file);for(let r of Array.isArray(o.evidence)?o.evidence:[])typeof r?.file=="string"&&r.file&&e.add(r.file)}return e}function Cr(t){let e=(we(t)??[]).flat().filter(o=>o!=null&&typeof o=="object"),n=be([{groups:[e],tree:t?.tree}]);return{directory:n,own:e.filter(o=>!C(o.file,n))}}function Tr(t){let e=new Map;for(let n of Cr(t).own){let o=G(n);o&&e.set(o.toLowerCase(),o)}return e.size===1?[...e.values()][0]:null}function Lr(t){let{directory:e,own:n}=Cr(t);return Rr([...ds(n)].filter(o=>!C(o,e)))}var us=["inprogress","fixed","invalid","deleted","ignored"];function ps(t){return typeof t=="string"&&us.includes(t)}function Ye(t){if(t===null)return null;if(typeof t!="object"||Array.isArray(t))return"invalid";let e=t,n={},o=e.color;if(o!=null){if(typeof o!="string"||o.length>50)return"invalid";o!==""&&(n.color=o)}let r=e.triage;if(r!=null){if(!ps(r))return"invalid";n.triage=r}for(let s of["comment","fix"]){let c=e[s];if(c!=null){if(typeof c!="string"||c.length>1e4)return"invalid";c!==""&&(n[s]=c)}}let i=e.flagged;if(i!=null){if(typeof i!="boolean")return"invalid";n.flagged=i}return n}async function Mr(t,{session:e,confirmImport:n,...o}){if(e?.role!=="admin"||!e.csrfToken)throw new Error("An administrator session is required.");if(t!=null&&(typeof t!="object"||Array.isArray(t)))throw new Error("Invalid local triage.");let r=Object.create(null);for(let[d,p]of Object.entries(t??{})){let{ignoredReports:u,scopedIgnoredReports:f,...m}=B(p)??{};Object.keys(m).length!==0&&(r[d]=m)}let i=Object.keys(r).length,s=new Set,c=[],a;if(i>0)do{o.signal?.throwIfAborted();let d="/api/admin/reports/finding-ids"+(a?`?after=${encodeURIComponent(a)}`:""),{reports:p,nextCursor:u}=await o.api.send(d);o.signal?.throwIfAborted();for(let f of p){let m=f.findingIds.filter(h=>Object.hasOwn(r,h)&&!s.has(h));m.length>0&&c.push({id:f.id,ids:m});for(let h of m)s.add(h)}a=u}while(a);for(let d of s){if(!d||d.length>100)throw new Error(`Triage finding IDs must be between 1 and ${100} characters.`);if(Ye(r[d])==="invalid")throw new Error(`Triage for ${d} exceeds the managed server limits.`)}if(o.signal?.throwIfAborted(),n){let d=await n({matched:s.size,available:i});if(o.signal?.throwIfAborted(),!d)return null}let l=o.importedIds??new Set;for(let d of c)await jt(r,{...o,importedIds:l,ids:d.ids,path:`/api/admin/reports/${encodeURIComponent(d.id)}/import-triage`});return s.size}function ms(t,e){let n=[],o=Object.create(null);for(let[r,i]of Object.entries(t)){let s=e[r];if(!s)throw new Error("The server did not return the requested triage snapshot.");let c=s.entry??{},a=o[r]={...c};delete a.comment;for(let[l,d]of Object.entries(i))if(l==="comment"){if(s.comments.some(p=>p.body===d))continue;s.comments.length>0?n.push({id:r,property:l,local:s.comments.map(p=>p.body).join(`
|
|
60
|
-
|
|
61
|
-
`),imported:d}):a.comment=d}else if(c[l]!==void 0&&c[l]!==d){let p=u=>l==="flagged"?u?"flagged":"not flagged":u;n.push({id:r,property:l,local:p(c[l]),imported:p(d)})}else a[l]=d}return{entries:o,conflicts:n}}async function hs(t,e,n,o,r){r?.throwIfAborted();let{entries:i,conflicts:s}=ms(t,e);if(s.length===0)return i;let c=await o(s,n,{title:"Triage conflicts on import",intro:"disagree with stored triage on",trailingNote:"Imported comments are added alongside existing comments. Other choices apply to these finding IDs across all teams.",importedSideLabel:"Apply imported"});if(r?.throwIfAborted(),!c)throw new Error("Triage conflict resolution was cancelled.");for(let a of s){let l=c[`${a.id}:${a.property}`];if(!["local","imported"].includes(l))throw new Error("Resolve every triage conflict before importing.");l==="imported"&&(i[a.id][a.property]=t[a.id][a.property])}return i}function gs(t,e){let n=[],o={entries:{},expected:{}};for(let[r,i]of Object.entries(t)){let s={entries:{...o.entries,[r]:i},expected:{...o.expected,[r]:e[r].version}};if(new TextEncoder().encode(JSON.stringify(s)).length<=262144){o=s;continue}if(Object.keys(o.entries).length===0)throw new Error("This triage entry is too large to import.");n.push(o),o={entries:{[r]:i},expected:{[r]:e[r].version}}}return Object.keys(o.entries).length>0&&n.push(o),n}async function jt(t,{api:e,path:n,ids:o=Object.keys(t),importedIds:r=new Set,lookup:i=new Map,resolveConflicts:s,signal:c}){o=o.filter(a=>Object.hasOwn(t,a)&&!r.has(a));for(let a=0;a<o.length;a+=200){let l=o.slice(a,a+200);for(let d=0;d<5&&l.length>0;d++){c?.throwIfAborted();let{snapshots:p}=await e.send(n,{findingIds:l}),u=Object.fromEntries(l.map(m=>[m,t[m]])),f=await hs(u,p,i,s,c);for(let m of gs(f,p)){if(c?.throwIfAborted(),(await e.send(n,m)).conflict)break;Object.keys(m.entries).forEach(h=>r.add(h))}l=l.filter(m=>!r.has(m))}if(l.length>0)throw new Error("Stored triage keeps changing. Retry to resolve it against the latest values.")}}function Or(t){if(typeof t!="string")return{ok:!0,path:null};if(/\p{Cc}/u.test(t)||t.includes("\\")||t!==t.trim())return{ok:!1};let e=[];for(let o of t.split("/"))if(!(o===""||o===".")){if(o===".."||o!==o.trim())return{ok:!1};e.push(o)}let n=e.join("/");return n.length>500?{ok:!1}:{ok:!0,path:n===""?null:n}}async function Nr(t,e){let n=new Uint8Array(await t.arrayBuffer());return Ke(n)?e({tryPassword:o=>Pt(n,o)}):n[0]===31&&n[1]===139?Pt(n):Ze(new TextDecoder("utf-8",{fatal:!0}).decode(n))}function Br(t,e,n,o,r=""){let i=t?Ir(t,e,o,r):null,s=n.find(c=>i?c.repoId===i.repoId:c.fullName.toLowerCase()===t?.toLowerCase());return{repoId:s?.repoId??null,directory:i?.directory??e,github:s?.fullName??t}}async function Dr(t,e,n=[]){let o=new Map,r=[];for(let a of t.reports){if(typeof a?.name!="string"||!a.name||typeof a.content!="string")throw new Error("Every report must have a name and content.");let l=K(a.content,a.name);if(!l.data)throw new Error(`${a.name}: ${l.reason??"Unsupported report"}`);let d=G(l.data),u=d??G(a)??G({repo:{github:t.repoUrls?.[a.name]}})??Tr(l.data),f=d?"":Lr(l.data),m=Or(l.data.repo?.directory);if(!m.ok)throw new Error(`${a.name}: invalid repository directory`);let h=l.format==="links"?[]:(await qe(a.content,a.name))?.findings??[];for(let y of h)y.id&&o.set(y.id,y);let g=m.path??"";r.push({...a,links:l.format==="links",...Br(u,g,e,n,f),declaredGithub:u,declaredDirectory:g,filePrefix:f,embedded:d,ids:[...new Set(h.map(y=>y.id).filter(Boolean))],uploaded:null})}let i=Object.create(null);if(t.triage!=null&&(typeof t.triage!="object"||Array.isArray(t.triage)))throw new Error("Invalid workspace triage.");let s=await mr(t.triage,a=>t.reports.find(l=>l.name===a)?.content);for(let[a,l]of Object.entries(s.entries)){if(!o.has(a))continue;let d=B(l);if(!d)continue;let{ignoredReports:p,scopedIgnoredReports:u,...f}=d;Object.keys(f).length!==0&&(i[a]=f)}let c=[];for(let a of t.bundleBlobs??[]){let l=Uint8Array.fromBase64(a.data),d=`sha512-${new Uint8Array(await crypto.subtle.digest("SHA-512",l)).toBase64()}`;if(d!==a.integrity)throw new Error(`${a.name}: bundle integrity mismatch`);c.push({name:a.name,integrity:d,bytes:l,uploaded:null})}return{name:t.workspace.name.slice(0,100),reports:r,bundles:c,triage:i,lookup:o,references:t.bundles??[],team:null,completed:new Set,importedIds:new Set}}function te(t,e,n){async function o(r,i,s={}){n?.throwIfAborted();let c=await t(r,{credentials:"same-origin",signal:n,...i===void 0?{}:{method:"POST",body:i instanceof File?i:JSON.stringify(i)},headers:{...i instanceof File?{}:{"content-type":"application/json"},"x-csrf-token":e.csrfToken,...s}});if(n?.throwIfAborted(),c.status===409)return{conflict:!0};if(!c.ok)throw new Error(`Import request failed (HTTP ${c.status}). You can retry the remaining steps.`);let a=await c.json();return n?.throwIfAborted(),a}return{send:o}}async function ys(t,e,n,o,r,i){if(t.bundles.length===0&&t.references.length===0)return;let s=r??(await n.send("/api/admin/bundles")).bundles,c=new Set(t.bundles.map(l=>l.uploaded.id));if([...c].some(l=>!s.some(d=>d.id===l)))throw new Error("Could not verify the uploaded source bundles. Retry the import.");let a=new Set(t.references);for(let l of s){if(!c.has(l.id)&&!a.has(l.integrity))continue;let d=!i.has(l.repoId),p=d?e:l.repoId;d&&await o(`bundle-repo:${l.id}:${p}`,()=>n.send("/api/admin/bundles/set-repo",{bundleId:l.id,repoId:p}));let u=d?"":l.repoDirectory??"";await o(`repo:${p}:${u}`,()=>n.send("/api/admin/teams/set-repo",{teamId:t.team.id,repoId:p,path:u}))}}async function ws(t,e){t.uploaded||(t.uploaded=await e.send("/api/admin/deduplication",new File([t.content],t.name),{"x-report-filename":encodeURIComponent(t.name)}))}async function bs(t,e){let n=(await e.send("/api/admin/repositories/browsable")).repos,o=t.reports.filter(r=>!r.links&&r.declaredGithub&&!r.uploaded);if(o.length>0){let{aliases:r=[]}=await e.send("/api/admin/repositories/aliases");for(let i of o)Object.assign(i,Br(i.declaredGithub,i.declaredDirectory,n,r,i.filePrefix))}return new Set(n.map(r=>r.repoId))}async function Ur(t,{api:e,session:n,defaultRepo:o,includeTriage:r,resolveConflicts:i,signal:s,progress:c=()=>{}}){if(n?.role!=="admin"||!n.csrfToken)throw new Error("An administrator session is required.");if(!t.name.trim()||t.name.trim().length>100)throw new Error("Enter a team name of up to 100 characters.");if(r)for(let[u,f]of Object.entries(t.triage)){if(!u||u.length>100)throw new Error(`Triage finding IDs must be between 1 and ${100} characters. Choose Skip triage to import the files without it.`);if(Ye(f)==="invalid")throw new Error(`Triage for ${u} exceeds the managed server limits. Choose Skip triage to import the files without it.`)}s?.throwIfAborted();let a=null;if(t.bundles.length===0){let u=new Set(t.references);a=u.size>0?(await e.send("/api/admin/bundles")).bundles.filter(f=>u.has(f.integrity)):[]}if(t.reports.length===0&&t.bundles.length===0&&a.length===0)throw new Error(t.references.length>0?"None of the referenced source bundles are available on the server. Export with bundle bytes included and try again.":"This workspace contains no report or bundle files.");let l=await bs(t,e);for(let u of t.reports.filter(f=>!f.links)){if(u.embedded&&!l.has(u.repoId))throw new Error(`Connect ${u.embedded} in Repositories before importing ${u.name}.`);if(!l.has(u.repoId)&&!l.has(o))throw new Error(`Choose an active repository for ${u.name}.`)}if((t.bundles.length>0||a.some(u=>!l.has(u.repoId)))&&!l.has(o))throw new Error("Choose an active repository for the source bundles.");let d=()=>s?.throwIfAborted(),p=async(u,f)=>{d(),t.completed.has(u)||(await f(),t.completed.add(u))};if(d(),!t.team){let u=await e.send("/api/admin/teams",{name:t.name.trim()});if(u.conflict)throw new Error("A team already has this name. Choose another name.");t.team=u}await p("member",()=>e.send("/api/admin/teams/set-member",{teamId:t.team.id,userId:n.id,security:!0,dependencies:!0}));for(let u of t.bundles)d(),c(`Importing ${u.name}\u2026`),u.uploaded||(u.uploaded=await e.send("/api/admin/bundles",new File([u.bytes],u.name),{"x-bundle-filename":encodeURIComponent(u.name)}));await ys(t,o,e,p,a,l);for(let u of t.reports){if(d(),c(`Importing ${u.name}\u2026`),u.links){await ws(u,e);continue}let f=l.has(u.repoId)?u.repoId:o;if(!u.uploaded){let g=await e.send("/api/admin/reports",new File([u.content],u.name),{"x-report-filename":encodeURIComponent(u.name),"x-repo-id":String(f),"x-repo-directory":encodeURIComponent(u.directory)});if(g.conflict)throw new Error(`Could not reuse the stored report ${u.name}. Retry the import.`);u.uploaded=g}let m=u.uploaded;l.has(m.repoId)||await p(`report-repo:${m.id}:${f}:${u.directory}`,async()=>{if((await e.send("/api/admin/reports/set-repo",{reportId:m.id,repoId:f,directory:u.directory})).conflict)throw new Error(`Could not assign the stored report ${u.name} to its repository.`);m.repoId=f,m.repoDirectory=u.directory});let h=m.repoDirectory??"";await p(`repo:${m.repoId}:${h}`,()=>e.send("/api/admin/teams/set-repo",{teamId:t.team.id,repoId:m.repoId,path:h})),r&&await jt(t.triage,{api:e,resolveConflicts:i,signal:s,ids:u.ids,importedIds:t.importedIds,lookup:t.lookup,path:`/api/admin/reports/${encodeURIComponent(u.uploaded.id)}/import-triage`}),await p(`publish:${u.uploaded.id}`,()=>e.send("/api/admin/reports/set-visible",{reportId:u.uploaded.id,visible:!0}))}return t.team}function Vt(t){let e=()=>t.isEncryptionEnabled()&&!t.isUnlocked();return{get locked(){return e()},unlock:n=>t.unlockEncryption(n),async read({signal:n}={}){let o=!1,r=t.onVaultStateChange(()=>{o=!0}),i=()=>{if(n?.throwIfAborted(),e()||o)throw new Error("Local data was locked or changed. Unlock it and import triage again.")};try{i();let s=await t.readTriageBlob();return i(),s}finally{r()}}}}function Je(t){let e=()=>t.isEncryptionEnabled()&&!t.isUnlocked();async function n(){let r=JSON.parse(await t.hydrateKey("deepview.workspaces")||"[]");return(Array.isArray(r)?r:r.workspaces??[]).filter(i=>typeof i.id=="string"&&typeof i.name=="string")}async function o(r,i){let s=!1,c=[t.onVaultStateChange,t.onFileMutated,t.onBundleMutated].map(l=>l(()=>{s=!0})),a=()=>{if(i?.throwIfAborted(),e()||s)throw new Error("Local data was locked or changed. Unlock it and select the workspace again.")};try{a();let l=await r(a);return a(),l}finally{c.forEach(l=>l())}}return{get locked(){return e()},unlock:r=>t.unlockEncryption(r),list:({signal:r}={})=>o(async()=>(await n()).map(i=>({id:i.id,name:i.name})),r),read:(r,{signal:i}={})=>o(async s=>{let c=(await n()).find(m=>m.id===r);if(!c)throw new Error("This local workspace no longer exists.");let a=JSON.stringify(c),l=JSON.parse(await t.hydrateKey("deepview.repoUrls")||"{}"),d=[];for(let m of c.reports??[]){s();let h=await t.withStoredItem("report",m,()=>t.readFile(m));s(),d.push({name:m,content:h,...l[m]?{repo:{github:l[m]}}:{}})}let p=await t.listBundles(),u=[];for(let m of c.bundles??[]){s();let h=p.find(y=>y.integrity===m);if(!h)continue;let g=await t.withStoredItem("bundle",m,()=>t.readBundle(m));s(),u.push({integrity:m,name:h.name,data:g.toBase64()})}let f=await t.readTriageBlob()??{};if(JSON.stringify((await n()).find(m=>m.id===r))!==a)throw new Error("The local workspace changed. Select it again.");return{version:1,workspace:{id:r,name:c.name,privateKey:""},reports:d,bundles:c.bundles??[],bundleBlobs:u,triage:f,repoUrls:l}},i)}}async function Fr(t){let e=await crypto.subtle.digest("SHA-512",t);return`sha512-${new Uint8Array(e).toBase64()}`}var ne=t=>t==="bundle"?"bundles":"reports",Pr=(t,e)=>JSON.stringify([t,e||""]),zr=(t,e)=>new Set(e.map(n=>t==="bundle"?n.integrity:Pr(n.sha256,n.analyzer)));async function Hr(t){let e=new Uint8Array(await t.arrayBuffer()),n=K(new TextDecoder().decode(e),t.name);if(!n.data)throw new Error(n.reason??"Not a recognized report");let o=new Uint8Array(await crypto.subtle.digest("SHA-256",e)).toBase64({alphabet:"base64url",omitPadding:!0});return{hash:o,key:Pr(o,typeof n.data.source=="string"?n.data.source:null)}}async function jr(t,{source:e,deps:n,api:o,signal:r}){let i=JSON.parse(await n.hydrateKey("deepview.workspaces")||"[]"),s=(Array.isArray(i)?i:i.workspaces??[]).filter(u=>typeof u.id=="string"&&typeof u.name=="string");r.throwIfAborted();let c=await e.list(t),a=zr(t,(await o.send(`/api/admin/${ne(t)}`))[ne(t)]),l=s.map(u=>({id:u.id,name:u.name,items:[]})),d={id:null,name:"Not in a workspace",items:[]},p=[];for(let u of c){r.throwIfAborted();let f={value:u.value,name:u.label,key:u.value,synced:!1,present:!1,error:""};if(t==="report")try{Object.assign(f,await e.importItem(t,f.value,Hr,{signal:r})),f.syncHash=await n.reportSyncHash(f.value)}catch(h){r.throwIfAborted(),f.error=String(h?.message??h)}r.throwIfAborted(),f.present=a.has(f.key);let m=!1;s.forEach((h,g)=>{if(!h[ne(t)]?.includes(f.value))return;let y=n.localContentSyncStatus(h.id,t,f.value,f.syncHash);f.synced||=y.synced,l[g].items.push({item:f,...y}),m=!0}),m||d.items.push({item:f,synced:!1,cached:!1}),p.push(f)}return{kind:t,items:p,groups:[...l,d].filter(u=>u.items.length>0)}}async function Vr(t,e,{source:n,api:o,signal:r,progress:i=()=>{},imported:s=new Set}){let{kind:c}=t,a=zr(c,(await o.send(`/api/admin/${ne(c)}`))[ne(c)]),l=new Set(e);for(let d of t.items)if(r.throwIfAborted(),!(!l.has(d.value)||d.error||d.present)){if(a.has(d.key)){d.present=!0;continue}i(`Importing ${d.name}\u2026`),await n.importItem(c,d.value,async p=>{let u=c==="report"?(await Hr(p)).key:await Fr(new Uint8Array(await p.arrayBuffer()));if(r.throwIfAborted(),u!==d.key)throw new Error(`${d.name} changed. Choose files again before importing.`);if((await o.send(`/api/admin/${ne(c)}`,p,{[`x-${c}-filename`]:encodeURIComponent(p.name)})).conflict)throw new Error(`Could not import ${d.name}. Try again.`)},{signal:r}),a.add(d.key),d.present=!0,s.add(d.value)}return s.size}var vs=(t,e)=>t===void 0?"managed-only":e===void 0?"local-only":"mismatch";function _s(t,e){let n=e.slice(),o=t.map(s=>{let c=n.indexOf(s);return c!==-1&&n.splice(c,1),{text:s,different:c===-1}}),r=t.slice(),i=e.map(s=>{let c=r.indexOf(s);return c!==-1&&r.splice(c,1),{text:s,different:c===-1}});return!o.some(s=>s.different)&&!i.some(s=>s.different)?null:{property:"comment",local:o,managed:i,kind:o.some(s=>s.different)?i.some(s=>s.different)?"mismatch":"local-only":"managed-only"}}function xs(t,e){let n=B(t)??{},o=B(e.entry)??{},r=[];for(let s of["triage","color","fix","flagged"])n[s]!==o[s]&&r.push({property:s,local:n[s],managed:o[s],kind:vs(n[s],o[s])});let i=_s(n.comment?[n.comment]:[],e.comments.map(s=>s.body));return i&&r.push(i),n.ignoredReports?.length&&r.push({property:"ignoredReports",local:[...new Set(n.ignoredReports)],managed:void 0,kind:"local-only"}),r}async function $s(t,{lookup:e,triage:n,matched:o,findings:r,api:i,signal:s}){let c=[...new Set(t.findingIds)].filter(a=>e.has(a)&&!o.has(a));for(let a=0;a<c.length;a+=200){let l=c.slice(a,a+200);if(l.some(p=>p.length>100))throw new Error("A shared finding ID exceeds the managed triage limit.");s.throwIfAborted();let{snapshots:d}=await i.send(`/api/admin/reports/${encodeURIComponent(t.id)}/import-triage`,{findingIds:l});s.throwIfAborted();for(let p of l){if(!d?.[p])throw new Error("The server did not return the requested triage snapshot.");let u=xs(n[p],d[p]);u.length>0&&r.push({id:p,finding:e.get(p),differences:u}),o.add(p)}}}async function Gr({source:t,readTriage:e,api:n,signal:o,progress:r=()=>{}}){let i=new Map,s=[];for(let p of await t.list("report")){o.throwIfAborted(),r(`Reading ${p.label}\u2026`);try{let u=await t.importItem("report",p.value,async f=>{let m=await f.text(),h=K(m,f.name);if(!h.data)throw new Error(h.reason??"Not a recognized report");return h.format==="links"?[]:(await qe(m,f.name))?.findings??[]},{signal:o});o.throwIfAborted();for(let f of u)typeof f.id!="string"||!f.id||(i.has(f.id)||i.set(f.id,{...f,reports:[]}),i.get(f.id).reports.push(p.label))}catch(u){o.throwIfAborted(),s.push({name:p.label,reason:String(u?.message??u)})}}let c=await e()??{};if(o.throwIfAborted(),typeof c!="object"||Array.isArray(c))throw new Error("Invalid local triage.");let a=[],l=new Set;if(i.size===0)return{matched:0,localFindings:0,findings:a,skipped:s};let d;do{o.throwIfAborted(),r("Comparing local and managed triage\u2026");let p=await n.send("/api/admin/reports/finding-ids"+(d?`?after=${encodeURIComponent(d)}`:""));o.throwIfAborted();for(let u of p.reports)await $s(u,{lookup:i,triage:c,matched:l,findings:a,api:n,signal:o});d=p.nextCursor}while(d);return o.throwIfAborted(),{matched:l.size,localFindings:i.size,findings:a,skipped:s}}function Es(t,e){if(customElements.get("managed-admin-import"))return;class n extends t{static styles=[re(mn),re(hn)];static properties={localDeps:{attribute:!1},_busy:{state:!0},_error:{state:!0},_message:{state:!0},_plan:{state:!0},_catalog:{state:!0},_localOpen:{state:!0},_workspaces:{state:!0},_localId:{state:!0},_triage:{state:!0},_repo:{state:!0},_drag:{state:!0}};constructor(){super(),this._busy=!1,this._error="",this._message="",this._plan=null,this._catalog=null,this._workspaces=[],this._localOpen=!1,this._localId="",this._triage="",this._repo=null,this._files=[],this._drag=!1,this._local=!1,this._over=r=>{r.dataTransfer?.types?.includes("Files")&&(r.preventDefault(),this._drag=!0)},this._drop=r=>{r.dataTransfer?.types?.includes("Files")&&(r.preventDefault(),r.stopPropagation(),this._drag=!1,this._busy||(this._files.push(...r.dataTransfer.files),this._nextFile()))},this._localChanged=()=>{this._workspaces=[],this._localId="",!this._unlocking&&(this._local&&(this._plan=null),(this._local||this._importingTriage||this._importingContent||this._comparingTriage)&&(this._operation?.abort(),this._message="",this._error=this._comparingTriage?"Local data changed or was locked. Compare triage again to continue.":this._importingContent?"Local data changed or was locked. Choose files again to continue.":this._importingTriage?"Local data changed or was locked. Import triage again to continue.":"Local data changed or was locked. Choose the workspace again."))},this._blur=()=>{this._readingLocal&&this._localChanged()}}connectedCallback(){super.connectedCallback(),this.addEventListener("dragover",this._over),this.addEventListener("drop",this._drop),globalThis.addEventListener("blur",this._blur),globalThis.addEventListener("storage",this._localChanged),this._offVault=this.localDeps?.onVaultStateChange(this._localChanged),this._loadCatalog()}disconnectedCallback(){this._operation?.abort(),this._offVault?.(),this._plan=null,this._files=[],this.removeEventListener("dragover",this._over),this.removeEventListener("drop",this._drop),globalThis.removeEventListener("blur",this._blur),globalThis.removeEventListener("storage",this._localChanged),super.disconnectedCallback()}updated(r){r.has("session")&&(this._role!=="admin"||r.get("session")?.id!==this.session?.id)&&(this._operation?.abort(),this._plan=null,this._files=[])}async _action(r){if(this._busy||this._role!=="admin")return;let i=this._operation=new AbortController,s=AbortSignal.any([i.signal,this.appState.sessionController.signal]);this._busy=!0,this._error="";try{await r(s),s.throwIfAborted()}catch(c){s.aborted||(this._error=String(c?.message??c))}finally{this._operation===i&&(this._busy=!1)}}async _loadCatalog(){if(this._role==="admin")try{await this._loadCollection("workspace-import:catalog","import options",async r=>{let i=te(e,this.session,r),[s,c,a,l]=await Promise.all([i.send("/api/admin/reports"),i.send("/api/admin/teams"),i.send("/api/admin/bundles"),i.send("/api/admin/repositories/aliases")]);return{repos:s.repos,teams:c.teams,bundles:a.bundles,aliases:l.aliases}},r=>{this._catalog=r})}catch(r){this._error=String(r?.message??r)}}_browse(){let r=document.createElement("input");r.type="file",r.multiple=!0,r.accept=".enc,.gz,.json",r.addEventListener("change",()=>{this._files.push(...r.files),this._nextFile()},{once:!0}),r.click()}async _prepare(r,i){if(!r)return;if(this._catalog||await this._loadCatalog(),i.throwIfAborted(),!this._catalog)throw new Error("Could not load repositories. Try again.");let s=await Dr(r,this._catalog.repos,this._catalog.aliases);i.throwIfAborted();let c=new Set(this._catalog.teams.map(p=>p.name)),a=s.name||"Imported workspace",l=2;for(;c.has(s.name);){let p=` (${l++})`;s.name=a.slice(0,100-p.length)+p}let d=new Set(s.reports.map(p=>p.repoId).filter(p=>p!=null));this._repo=d.size===1?[...d][0]:null,this._triage=Object.keys(s.triage).length>0?"":"skip",this._plan=s,this._message=""}async _nextFile(){if(this._files.length===0||this._busy)return;let r=this._files.shift();this._local=!1,this._plan=null,await this._action(async i=>{let s=await Nr(r,this.promptPassword);i.throwIfAborted(),await this._prepare(s,i)})}async _unlock(r,i){this._unlocking=!0;try{return!r.locked||await r.unlock({signal:i})}finally{this._unlocking=!1}}async _chooseLocal(){this._localOpen=!0,await this._action(async r=>{let i=Je(this.localDeps);await this._unlock(i,r)&&(r.throwIfAborted(),this._workspaces=await i.list({signal:r}))})}async _readLocal(){if(!this._localId)return;let r=this._localId;this._local=!0,this._plan=null,await this._action(async i=>{let s=Je(this.localDeps);if(await this._unlock(s,i)){this._readingLocal=!0;try{await this._prepare(await s.read(r,{signal:i}),i)}finally{this._readingLocal=!1}}})}async _import(){!this._plan||!this._triage||!this._csrf||(await this._action(async r=>{if(this._local&&Je(this.localDeps).locked)throw new Error("Unlock local data and choose the workspace again.");let i=this._plan,s=["teams","reports","bundles","history","workspace-import","scan-sources","repo-impact"];try{let c=await this.appState.mutate(()=>Ur(i,{api:te(e,this.session,r),session:this.session,defaultRepo:this._repo,includeTriage:this._triage==="include",resolveConflicts:this.resolveConflicts,signal:r,progress:a=>{this._message=a}}),s);this._catalog.teams.push(c),this._message=`Imported into ${c.name}.`,this._plan=null}finally{this.appState.invalidate(s),i.team&&this.dispatchEvent(new CustomEvent("managed-import-complete",{bubbles:!0,composed:!0}))}}),!this._plan&&!this._error&&await this._nextFile())}async _importLocalTriage(){this._csrf&&await this._action(async r=>{this._importingTriage=!0,this._message="";let i=new Set,s=["reports","history"];try{let c=Vt(this.localDeps);if(!await this._unlock(c,r))return;this._readingLocal=!0;let a;try{a=await c.read({signal:r})}finally{this._readingLocal=!1}let l=await Mr(a,{api:te(e,this.session,r),session:this.session,resolveConflicts:this.resolveConflicts,signal:r,importedIds:i,confirmImport:async d=>(await this.confirmTriageImport({...d,signal:r}))?.confirmed===!0});if(r.throwIfAborted(),l===null)return;this._message=l?`Imported triage for ${l} finding${l===1?"":"s"}.`:"No local triage matches findings in managed reports."}finally{this._importingTriage=!1,this.appState.invalidate(s),i.size>0&&this.dispatchEvent(new CustomEvent("managed-import-complete",{bubbles:!0,composed:!0}))}})}async _compareLocalTriage(){this._csrf&&await this._action(async r=>{this._comparingTriage=!0,this._message="";let i=this.localImportSource,s=i.subscribe(this._localChanged);try{if(!await this._unlock(i,r))return;r.throwIfAborted(),this._readingLocal=!0;let c=Vt(this.localDeps),a=await Gr({source:i,signal:r,readTriage:()=>c.read({signal:r}),api:te(e,this.session,r),progress:l=>{this._message=l}});r.throwIfAborted(),this._message="",await this.showTriageComparison({comparison:a,signal:r})}finally{s(),this._readingLocal=!1,this._comparingTriage=!1,this._message=""}})}async _importLocalContent(r){this._csrf&&await this._action(async i=>{this._importingContent=!0,this._message="";let s=this.localImportSource,c=["reports","bundles","bundle-metadata","history","workspace-import","scan-sources","repo-impact"],a=new Set,l=s.subscribe(this._localChanged);try{if(!await this._unlock(s,i))return;i.throwIfAborted(),this._readingLocal=!0;let d=te(e,this.session,i),p=await jr(r,{source:s,deps:this.localDeps,api:d,signal:i}),u=await this.confirmContentImport({plan:p,signal:i});if(i.throwIfAborted(),!u?.confirmed)return;let f=await Vr(p,u.selected,{source:s,api:d,signal:i,imported:a,progress:m=>{this._message=m}});this._message=`Imported ${f} ${r}${f===1?"":"s"}.`}finally{l(),this._readingLocal=!1,this._importingContent=!1,this.appState.invalidate(c),a.size>0&&this.dispatchEvent(new CustomEvent("managed-import-complete",{bubbles:!0,composed:!0}))}})}render(){if(this._role!=="admin")return w;let r=this._plan,i=r?Object.keys(r.triage).length:0,s=new Set([...r?.references??[],...r?.bundles.map(l=>l.integrity)??[]]),c=(this._catalog?.bundles??[]).filter(l=>s.has(l.integrity)),a=r?.references.filter(l=>!r.bundles.some(d=>d.integrity===l)).length??0;return x`<div class="wrap" @dragleave="${()=>{this._drag=!1}}">${fn("manage-import",this._role,this.allowShare)}<h1>Import</h1><section class="triage-import" aria-label="Import local files"><div class="actions"><button type="button" class="btn" ?disabled="${this._busy||!this._csrf}" @click="${()=>this._importLocalContent("bundle")}">Import bundles</button> <button type="button" class="btn" ?disabled="${this._busy||!this._csrf}" @click="${()=>this._importLocalContent("report")}">Import reports</button></div><p>Choose files from this browser, grouped by workspace. Import files without teams or triage.</p></section><section class="triage-import" aria-label="Local triage"><div class="actions"><button type="button" class="btn" ?disabled="${this._busy||!this._csrf}" @click="${()=>this._importLocalTriage()}">Import triage</button> <button type="button" class="btn" ?disabled="${this._busy||!this._csrf}" @click="${()=>this._compareLocalTriage()}">Compare triage</button></div><p>Import saved triage and comments for findings already in managed reports.<br>Unmatched data stays in this browser.<br>Conflicting values prompt for resolution; per-report ignores are skipped.</p></section><h2>Import workspace</h2><p class="intro ui-hint">Create a new team from a workspace export or a workspace stored in this browser.</p><section class="${`workspace-drop ${this._drag?"dragging":""}`}" aria-label="Workspace files"><strong>Drop workspace files here</strong><span>Encrypted exports, JSON, or compressed JSON. Encrypted files prompt for a password.</span><div class="actions"><button type="button" class="btn" ?disabled="${this._busy||!this._catalog}" @click="${()=>this._browse()}">Choose files</button> <button type="button" class="btn" ?disabled="${this._busy}" @click="${()=>this._chooseLocal()}">Choose local workspace</button></div></section>${this._localOpen?x`<section class="local-choice"><label for="local-workspace">Local workspace</label> <select id="local-workspace" .value="${this._localId}" ?disabled="${this._busy}" @change="${l=>{this._localId=l.target.value}}"><option value="">Choose a workspace…</option>${this._workspaces.map(l=>x`<option value="${l.id}">${l.name}</option>`)}</select> <button type="button" class="btn" ?disabled="${this._busy||!this._localId}" @click="${()=>this._readLocal()}">Select workspace</button> ${!this._busy&&this._workspaces.length===0?x`<p class="ui-hint">No unlocked local workspaces. Choose local workspace to unlock or refresh.</p>`:w}</section>`:w} ${r?x`<section class="import-preview" aria-label="Import options">${r.team?x`<p>Team ${r.team.name} has been created. Retry continues its remaining import steps.</p>`:w} <label for="import-team">New team name</label><input id="import-team" maxlength="100" .value="${r.name}" ?disabled="${this._busy||!!r.team}" @input="${l=>{r.name=l.target.value,this.requestUpdate()}}"><p>${r.reports.length} reports / links · ${s.size} source bundles · ${i} triaged findings</p><label for="import-repo">Repository for files and source bundles without an active repository</label> <select id="import-repo" .value="${String(this._repo??"")}" ?disabled="${this._busy||!!r.team}" @change="${l=>{this._repo=l.target.value?Number(l.target.value):null}}"><option value="" ?selected="${this._repo==null}">Choose a repository…</option>${(this._catalog?.repos??[]).map(l=>x`<option value="${String(l.repoId)}" ?selected="${this._repo===l.repoId}">${l.fullName}</option>`)}</select><p>Declared report repositories and directories are preserved. Stored reports without an active repository use the selected repository. The new team receives those repository paths; other published reports in the same paths are also visible to that team.</p><ul>${r.reports.map(l=>x`<li>${l.name}<span>${l.links?"Global deduplication \u2014 enabled for all teams":l.github??"Uses selected repository"}${l.links||l.github==null||l.repoId!=null?"":l.embedded?" \u2014 connect this repository first":" \u2014 not connected; uses selected repository"}</span></li>`)}</ul>${c.length>0?x`<p>Existing source bundles in active repositories keep their locations. The new team also receives access to those directories. Unassigned bundles and bundles in inactive repositories use the selected repository.</p><ul>${c.map(l=>x`<li>${l.filename}<span>${l.repoFullName?`${l.repoFullName}${l.repoDirectory?`/${l.repoDirectory}`:""}`:"Uses selected repository"}</span></li>`)}</ul>`:w} ${a?x`<p>${a} referenced source bundles have no bytes in this export. Reports can use matching bundles already on the server.</p>`:w} ${i?x`<fieldset ?disabled="${this._busy||!!r.team}"><legend>Import triage?</legend><label><input type="radio" name="import-triage" value="include" ?checked="${this._triage==="include"}" @change="${()=>{this._triage="include"}}"> Include triage and comments</label> <label><input type="radio" name="import-triage" value="skip" ?checked="${this._triage==="skip"}" @change="${()=>{this._triage="skip"}}"> Skip triage</label><p>Conflicting values prompt for resolution. Triage stays shared by finding ID across teams. Per-report local ignores are not imported.</p></fieldset>`:w} <button type="button" class="btn primary" ?disabled="${this._busy||!this._triage||!this._csrf}" @click="${()=>this._import()}">${this._busy?"Importing\u2026":r.team?"Retry remaining import":"Import workspace"}</button></section>`:w} ${this._message?x`<p role="status">${this._message}</p>`:w} ${this._error?x`<p class="error" role="alert">${this._error}${this._catalog?w:x`<button class="btn" @click="${()=>this._loadCatalog()}">Retry</button>`}</p>`:w} ${this._files.length>0&&!this._busy?x`<button class="btn" @click="${()=>this._nextFile()}">Next workspace file (${this._files.length} waiting)</button>`:w}</div>`}}customElements.define("managed-admin-import",n)}export{Es as registerWorkspaceImport};
|
|
62
|
-
/*! Bundled license information:
|
|
63
|
-
|
|
64
|
-
@lit/reactive-element/css-tag.js:
|
|
65
|
-
(**
|
|
66
|
-
* @license
|
|
67
|
-
* Copyright 2019 Google LLC
|
|
68
|
-
* SPDX-License-Identifier: BSD-3-Clause
|
|
69
|
-
*)
|
|
70
|
-
|
|
71
|
-
@lit/reactive-element/reactive-element.js:
|
|
72
|
-
lit-html/lit-html.js:
|
|
73
|
-
lit-element/lit-element.js:
|
|
74
|
-
lit-html/directive.js:
|
|
75
|
-
lit-html/directives/unsafe-html.js:
|
|
76
|
-
(**
|
|
77
|
-
* @license
|
|
78
|
-
* Copyright 2017 Google LLC
|
|
79
|
-
* SPDX-License-Identifier: BSD-3-Clause
|
|
80
|
-
*)
|
|
81
|
-
|
|
82
|
-
lit-html/is-server.js:
|
|
83
|
-
(**
|
|
84
|
-
* @license
|
|
85
|
-
* Copyright 2022 Google LLC
|
|
86
|
-
* SPDX-License-Identifier: BSD-3-Clause
|
|
87
|
-
*)
|
|
88
|
-
*/
|
|
4
|
+
`),imported:l}):s.comment=l}else if(c[r]!==void 0&&c[r]!==l){let h=m=>r==="flagged"?m?"flagged":"not flagged":m;n.push({id:e,property:r,local:h(c[r]),imported:h(l)})}else s[r]=l}return{entries:a,conflicts:n}}async function ce(t,p,n,a,e){e?.throwIfAborted();let{entries:i,conflicts:o}=ae(t,p);if(o.length===0)return i;let c=await a(o,n,{title:"Triage conflicts on import",intro:"disagree with stored triage on",trailingNote:"Imported comments are added alongside existing comments. Other choices apply to these finding IDs across all teams.",importedSideLabel:"Apply imported"});if(e?.throwIfAborted(),!c)throw Object.assign(new Error("Triage conflict resolution was cancelled."),{cancelled:!0});for(let s of o){let r=c[`${s.id}:${s.property}`];if(!["local","imported"].includes(r))throw new Error("Resolve every triage conflict before importing.");r==="imported"&&(i[s.id][s.property]=t[s.id][s.property])}return i}function le(t,p){let n=[],a={entries:{},expected:{}};for(let[e,i]of Object.entries(t)){let o={entries:{...a.entries,[e]:i},expected:{...a.expected,[e]:p[e].version}};if(new TextEncoder().encode(JSON.stringify(o)).length<=262144){a=o;continue}if(Object.keys(a.entries).length===0)throw new Error("This triage entry is too large to import.");n.push(a),a={entries:{[e]:i},expected:{[e]:p[e].version}}}return Object.keys(a.entries).length>0&&n.push(a),n}async function j(t,{api:p,path:n,ids:a=Object.keys(t),importedIds:e=new Set,lookup:i=new Map,resolveConflicts:o,signal:c}){a=a.filter(s=>Object.hasOwn(t,s)&&!e.has(s));for(let s=0;s<a.length;s+=200){let r=a.slice(s,s+200);for(let l=0;l<5&&r.length>0;l++){c?.throwIfAborted();let{snapshots:h}=await p.send(n,{findingIds:r}),m=Object.fromEntries(r.map(f=>[f,t[f]])),d=await ce(m,h,i,o,c);for(let f of le(d,h)){if(c?.throwIfAborted(),(await p.send(n,f)).conflict)break;Object.keys(f.entries).forEach(u=>e.add(u))}r=r.filter(f=>!e.has(f))}if(r.length>0)throw new Error("Stored triage keeps changing. Retry to resolve it against the latest values.")}}var N="You can retry the remaining steps.";function T(t){return String(t?.detail??t?.message??t).replace(/\.$/u,"")}function S(t,p){return p?.aborted===!0||t?.name==="AbortError"||t?.cancelled===!0}function K(t){if(typeof t!="string")return{ok:!0,path:null};if(/\p{Cc}/u.test(t)||t.includes("\\")||t!==t.trim())return{ok:!1};let p=[];for(let a of t.split("/"))if(!(a===""||a===".")){if(a===".."||a!==a.trim())return{ok:!1};p.push(a)}let n=p.join("/");return n.length>500?{ok:!1}:{ok:!0,path:n===""?null:n}}async function V(t,p){let n=new Uint8Array(await t.arrayBuffer());return B(n)?p({tryPassword:a=>O(n,a)}):n[0]===31&&n[1]===139?O(n):M(new TextDecoder("utf-8",{fatal:!0}).decode(n))}function Y(t,p,n,a,e=""){let i=t?P(t,p,a,e):null,o=n.find(c=>i?c.repoId===i.repoId:c.fullName.toLowerCase()===t?.toLowerCase());return{repoId:o?.repoId??null,directory:i?.directory??p,github:o?.fullName??t}}async function q(t,p,n=[]){let a=new Map,e=[];for(let s of t.reports){if(typeof s?.name!="string"||!s.name||typeof s.content!="string")throw new Error("Every report must have a name and content.");let r=k(s.content,s.name);if(!r.data)throw new Error(`${s.name}: ${r.reason??"Unsupported report"}`);let l=C(r.data),m=l??C(s)??C({repo:{github:t.repoUrls?.[s.name]}})??W(r.data),d=l?"":G(r.data),f=K(r.data.repo?.directory);if(!f.ok)throw new Error(`${s.name}: invalid repository directory`);let u=r.format==="links"?[]:(await A(s.content,s.name))?.findings??[];for(let b of u)b.id&&a.set(b.id,b);let I=f.path??"";e.push({...s,links:r.format==="links",...Y(m,I,p,n,d),declaredGithub:m,declaredDirectory:I,filePrefix:d,embedded:l,ids:[...new Set(u.map(b=>b.id).filter(Boolean))],uploaded:null})}let i=Object.create(null);if(t.triage!=null&&(typeof t.triage!="object"||Array.isArray(t.triage)))throw new Error("Invalid workspace triage.");let o=await z(t.triage,s=>t.reports.find(r=>r.name===s)?.content);for(let[s,r]of Object.entries(o.entries)){if(!a.has(s))continue;let l=y(r);if(!l)continue;let{ignoredReports:h,scopedIgnoredReports:m,...d}=l;Object.keys(d).length!==0&&(i[s]=d)}let c=[];for(let s of t.bundleBlobs??[]){let r=Uint8Array.fromBase64(s.data),l=`sha512-${new Uint8Array(await crypto.subtle.digest("SHA-512",r)).toBase64()}`;if(l!==s.integrity)throw new Error(`${s.name}: bundle integrity mismatch`);c.push({name:s.name,integrity:l,bytes:r,uploaded:null})}return{name:t.workspace.name.slice(0,100),reports:e,bundles:c,triage:i,lookup:a,references:t.bundles??[],team:null,completed:new Set,importedIds:new Set}}function $(t,p,n){async function a(e,i,o={}){n?.throwIfAborted();let c=await t(e,{credentials:"same-origin",signal:n,...i===void 0?{}:{method:"POST",body:i instanceof File?i:JSON.stringify(i)},headers:{...i instanceof File?{}:{"content-type":"application/json"},"x-csrf-token":p.csrfToken,...o}});if(n?.throwIfAborted(),c.status===409)return{conflict:!0};if(!c.ok){let r=await c.json().then(h=>typeof h?.error=="string"?h.error:"",()=>"");n?.throwIfAborted();let l=`Import request failed (HTTP ${c.status}${r?`: ${r}`:""}).`;throw Object.assign(new Error(`${l} ${N}`),{detail:l})}let s=await c.json();return n?.throwIfAborted(),s}return{send:a}}async function de(t,p,n,a,e,i){if(t.bundles.length===0&&t.references.length===0)return;let o=e??(await n.send("/api/admin/bundles")).bundles,c=new Set(t.bundles.map(r=>r.uploaded.id));if([...c].some(r=>!o.some(l=>l.id===r)))throw new Error("Could not verify the uploaded source bundles. Retry the import.");let s=new Set(t.references);for(let r of o){if(!c.has(r.id)&&!s.has(r.integrity))continue;let l=!i.has(r.repoId),h=l?p:r.repoId;l&&await a(`bundle-repo:${r.id}:${h}`,()=>n.send("/api/admin/bundles/set-repo",{bundleId:r.id,repoId:h}));let m=l?"":r.repoDirectory??"";await a(`repo:${h}:${m}`,()=>n.send("/api/admin/teams/set-repo",{teamId:t.team.id,repoId:h,path:m}))}}async function pe(t,p){t.uploaded||(t.uploaded=await p.send("/api/admin/deduplication",new File([t.content],t.name),{"x-report-filename":encodeURIComponent(t.name)}))}async function he(t,p){let n=(await p.send("/api/admin/repositories/browsable")).repos,a=t.reports.filter(e=>!e.links&&e.declaredGithub&&!e.uploaded);if(a.length>0){let{aliases:e=[]}=await p.send("/api/admin/repositories/aliases");for(let i of a)Object.assign(i,Y(i.declaredGithub,i.declaredDirectory,n,e,i.filePrefix))}return new Set(n.map(e=>e.repoId))}async function me(t,{plan:p,api:n,step:a,activeRepos:e,defaultRepo:i,includeTriage:o,resolveConflicts:c,signal:s}){if(t.links){await pe(t,n);return}let r=e.has(t.repoId)?t.repoId:i;if(!t.uploaded){let m=await n.send("/api/admin/reports",new File([t.content],t.name),{"x-report-filename":encodeURIComponent(t.name),"x-repo-id":String(r),"x-repo-directory":encodeURIComponent(t.directory)});if(m.conflict)throw new Error(`Could not reuse the stored report ${t.name}. Retry the import.`);t.uploaded=m}let l=t.uploaded;e.has(l.repoId)||await a(`report-repo:${l.id}:${r}:${t.directory}`,async()=>{if((await n.send("/api/admin/reports/set-repo",{reportId:l.id,repoId:r,directory:t.directory})).conflict)throw new Error(`Could not assign the stored report ${t.name} to its repository.`);l.repoId=r,l.repoDirectory=t.directory});let h=l.repoDirectory??"";await a(`repo:${l.repoId}:${h}`,()=>n.send("/api/admin/teams/set-repo",{teamId:p.team.id,repoId:l.repoId,path:h})),o&&await j(p.triage,{api:n,resolveConflicts:c,signal:s,ids:t.ids,importedIds:p.importedIds,lookup:p.lookup,path:`/api/admin/reports/${encodeURIComponent(t.uploaded.id)}/import-triage`}),await a(`publish:${t.uploaded.id}`,()=>n.send("/api/admin/reports/set-visible",{reportId:t.uploaded.id,visible:!0}))}async function Q(t,{api:p,session:n,defaultRepo:a,includeTriage:e,resolveConflicts:i,signal:o,progress:c=()=>{}}){if(n?.role!=="admin"||!n.csrfToken)throw new Error("An administrator session is required.");if(!t.name.trim()||t.name.trim().length>100)throw new Error("Enter a team name of up to 100 characters.");if(e)for(let[d,f]of Object.entries(t.triage)){if(!d||d.length>100)throw new Error(`Triage finding IDs must be between 1 and ${100} characters. Choose Skip triage to import the files without it.`);if(x(f)==="invalid")throw new Error(`Triage for ${d} exceeds the managed server limits. Choose Skip triage to import the files without it.`)}o?.throwIfAborted();let s=null;if(t.bundles.length===0){let d=new Set(t.references);s=d.size>0?(await p.send("/api/admin/bundles")).bundles.filter(f=>d.has(f.integrity)):[]}if(t.reports.length===0&&t.bundles.length===0&&s.length===0)throw new Error(t.references.length>0?"None of the referenced source bundles are available on the server. Export with bundle bytes included and try again.":"This workspace contains no report or bundle files.");let r=await he(t,p);for(let d of t.reports.filter(f=>!f.links)){if(d.embedded&&!r.has(d.repoId))throw new Error(`Connect ${d.embedded} in Repositories before importing ${d.name}.`);if(!r.has(d.repoId)&&!r.has(a))throw new Error(`Choose an active repository for ${d.name}.`)}if((t.bundles.length>0||s.some(d=>!r.has(d.repoId)))&&!r.has(a))throw new Error("Choose an active repository for the source bundles.");let l=()=>o?.throwIfAborted(),h=async(d,f)=>{l(),t.completed.has(d)||(await f(),t.completed.add(d))};if(l(),!t.team){let d=await p.send("/api/admin/teams",{name:t.name.trim()});if(d.conflict)throw new Error("A team already has this name. Choose another name.");t.team=d}await h("member",()=>p.send("/api/admin/teams/set-member",{teamId:t.team.id,userId:n.id,security:!0,dependencies:!0}));for(let d of t.bundles)l(),c(`Importing ${d.name}\u2026`),d.uploaded||(d.uploaded=await p.send("/api/admin/bundles",new File([d.bytes],d.name),{"x-bundle-filename":encodeURIComponent(d.name)}));await de(t,a,p,h,s,r);let m=[];for(let d of t.reports){l(),c(`Importing ${d.name}\u2026`);try{await me(d,{plan:t,api:p,step:h,activeRepos:r,defaultRepo:a,includeTriage:e,resolveConflicts:i,signal:o})}catch(f){if(S(f,o))throw f;m.push(`${d.name}: ${T(f)}`)}}if(m.length>0)throw new Error(`Could not import ${m.length} of ${t.reports.length} files: ${m.join("; ")}. ${N}`);return t.team}function D(t){let p=()=>t.isEncryptionEnabled()&&!t.isUnlocked();return{get locked(){return p()},unlock:n=>t.unlockEncryption(n),async read({signal:n}={}){let a=!1,e=t.onVaultStateChange(()=>{a=!0}),i=()=>{if(n?.throwIfAborted(),p()||a)throw new Error("Local data was locked or changed. Unlock it and import triage again.")};try{i();let o=await t.readTriageBlob();return i(),o}finally{e()}}}}function L(t){let p=()=>t.isEncryptionEnabled()&&!t.isUnlocked();async function n(){let e=JSON.parse(await t.hydrateKey("deepview.workspaces")||"[]");return(Array.isArray(e)?e:e.workspaces??[]).filter(i=>typeof i.id=="string"&&typeof i.name=="string")}async function a(e,i){let o=!1,c=[t.onVaultStateChange,t.onFileMutated,t.onBundleMutated].map(r=>r(()=>{o=!0})),s=()=>{if(i?.throwIfAborted(),p()||o)throw new Error("Local data was locked or changed. Unlock it and select the workspace again.")};try{s();let r=await e(s);return s(),r}finally{c.forEach(r=>r())}}return{get locked(){return p()},unlock:e=>t.unlockEncryption(e),list:({signal:e}={})=>a(async()=>(await n()).map(i=>({id:i.id,name:i.name})),e),read:(e,{signal:i}={})=>a(async o=>{let c=(await n()).find(f=>f.id===e);if(!c)throw new Error("This local workspace no longer exists.");let s=JSON.stringify(c),r=JSON.parse(await t.hydrateKey("deepview.repoUrls")||"{}"),l=[];for(let f of c.reports??[]){o();let u=await t.withStoredItem("report",f,()=>t.readFile(f));o(),l.push({name:f,content:u,...r[f]?{repo:{github:r[f]}}:{}})}let h=await t.listBundles(),m=[];for(let f of c.bundles??[]){o();let u=h.find(b=>b.integrity===f);if(!u)continue;let I=await t.withStoredItem("bundle",f,()=>t.readBundle(f));o(),m.push({integrity:f,name:u.name,data:I.toBase64()})}let d=await t.readTriageBlob()??{};if(JSON.stringify((await n()).find(f=>f.id===e))!==s)throw new Error("The local workspace changed. Select it again.");return{version:1,workspace:{id:e,name:c.name,privateKey:""},reports:l,bundles:c.bundles??[],bundleBlobs:m,triage:d,repoUrls:r}},i)}}var v=t=>t==="bundle"?"bundles":"reports",Z=(t,p)=>JSON.stringify([t,p||""]),ee=(t,p)=>new Set(p.map(n=>t==="bundle"?n.integrity:Z(n.sha256,n.analyzer)));async function te(t){let p=new Uint8Array(await t.arrayBuffer()),n=k(new TextDecoder().decode(p),t.name);if(!n.data)throw new Error(n.reason??"Not a recognized report");let a=new Uint8Array(await crypto.subtle.digest("SHA-256",p)).toBase64({alphabet:"base64url",omitPadding:!0});return{hash:a,key:Z(a,typeof n.data.source=="string"?n.data.source:null)}}async function re(t,{source:p,deps:n,api:a,signal:e}){let i=JSON.parse(await n.hydrateKey("deepview.workspaces")||"[]"),o=(Array.isArray(i)?i:i.workspaces??[]).filter(m=>typeof m.id=="string"&&typeof m.name=="string");e.throwIfAborted();let c=await p.list(t),s=ee(t,(await a.send(`/api/admin/${v(t)}`))[v(t)]),r=o.map(m=>({id:m.id,name:m.name,items:[]})),l={id:null,name:"Not in a workspace",items:[]},h=[];for(let m of c){e.throwIfAborted();let d={value:m.value,name:m.label,key:m.value,synced:!1,present:!1,error:""};if(t==="report")try{Object.assign(d,await p.importItem(t,d.value,te,{signal:e})),d.syncHash=await n.reportSyncHash(d.value)}catch(u){e.throwIfAborted(),d.error=String(u?.message??u)}e.throwIfAborted(),d.present=s.has(d.key);let f=!1;o.forEach((u,I)=>{if(!u[v(t)]?.includes(d.value))return;let b=n.localContentSyncStatus(u.id,t,d.value,d.syncHash);d.synced||=b.synced,r[I].items.push({item:d,...b}),f=!0}),f||l.items.push({item:d,synced:!1,cached:!1}),h.push(d)}return{kind:t,items:h,groups:[...r,l].filter(m=>m.items.length>0)}}async function oe(t,p,{source:n,api:a,signal:e,progress:i=()=>{},imported:o=new Set}){let{kind:c}=t,s=ee(c,(await a.send(`/api/admin/${v(c)}`))[v(c)]),r=new Set(p),l=[],h=0;for(let m of t.items)if(e.throwIfAborted(),!(!r.has(m.value)||m.error||m.present)){if(s.has(m.key)){m.present=!0;continue}i(`Importing ${m.name}\u2026`),h++;try{await n.importItem(c,m.value,async d=>{let f=c==="report"?(await te(d)).key:await H(new Uint8Array(await d.arrayBuffer()));if(e.throwIfAborted(),f!==m.key)throw new Error(`${m.name} changed. Choose files again before importing.`);if((await a.send(`/api/admin/${v(c)}`,d,{[`x-${c}-filename`]:encodeURIComponent(d.name)})).conflict)throw new Error(`Could not import ${m.name}. Try again.`)},{signal:e})}catch(d){if(S(d,e))throw d;l.push(`${m.name}: ${T(d)}`);continue}s.add(m.key),m.present=!0,o.add(m.value)}if(l.length>0)throw new Error(`Imported ${h-l.length} of ${h} ${c}s. Could not import ${l.join("; ")}. Import again to retry them.`);return o.size}var fe=(t,p)=>t===void 0?"managed-only":p===void 0?"local-only":"mismatch";function ue(t,p){let n=p.slice(),a=t.map(o=>{let c=n.indexOf(o);return c!==-1&&n.splice(c,1),{text:o,different:c===-1}}),e=t.slice(),i=p.map(o=>{let c=e.indexOf(o);return c!==-1&&e.splice(c,1),{text:o,different:c===-1}});return!a.some(o=>o.different)&&!i.some(o=>o.different)?null:{property:"comment",local:a,managed:i,kind:a.some(o=>o.different)?i.some(o=>o.different)?"mismatch":"local-only":"managed-only"}}function ge(t,p){let n=y(t)??{},a=y(p.entry)??{},e=[];for(let o of["triage","color","fix","flagged"])n[o]!==a[o]&&e.push({property:o,local:n[o],managed:a[o],kind:fe(n[o],a[o])});let i=ue(n.comment?[n.comment]:[],p.comments.map(o=>o.body));return i&&e.push(i),n.ignoredReports?.length&&e.push({property:"ignoredReports",local:[...new Set(n.ignoredReports)],managed:void 0,kind:"local-only"}),e}async function we(t,{lookup:p,triage:n,matched:a,findings:e,api:i,signal:o}){let c=[...new Set(t.findingIds)].filter(s=>p.has(s)&&!a.has(s));for(let s=0;s<c.length;s+=200){let r=c.slice(s,s+200);if(r.some(h=>h.length>100))throw new Error("A shared finding ID exceeds the managed triage limit.");o.throwIfAborted();let{snapshots:l}=await i.send(`/api/admin/reports/${encodeURIComponent(t.id)}/import-triage`,{findingIds:r});o.throwIfAborted();for(let h of r){if(!l?.[h])throw new Error("The server did not return the requested triage snapshot.");let m=ge(n[h],l[h]);m.length>0&&e.push({id:h,finding:p.get(h),differences:m}),a.add(h)}}}async function ie({source:t,readTriage:p,api:n,signal:a,progress:e=()=>{}}){let i=new Map,o=[];for(let h of await t.list("report")){a.throwIfAborted(),e(`Reading ${h.label}\u2026`);try{let m=await t.importItem("report",h.value,async d=>{let f=await d.text(),u=k(f,d.name);if(!u.data)throw new Error(u.reason??"Not a recognized report");return u.format==="links"?[]:(await A(f,d.name))?.findings??[]},{signal:a});a.throwIfAborted();for(let d of m)typeof d.id!="string"||!d.id||(i.has(d.id)||i.set(d.id,{...d,reports:[]}),i.get(d.id).reports.push(h.label))}catch(m){a.throwIfAborted(),o.push({name:h.label,reason:String(m?.message??m)})}}let c=await p()??{};if(a.throwIfAborted(),typeof c!="object"||Array.isArray(c))throw new Error("Invalid local triage.");let s=[],r=new Set;if(i.size===0)return{matched:0,localFindings:0,findings:s,skipped:o};let l;do{a.throwIfAborted(),e("Comparing local and managed triage\u2026");let h=await n.send("/api/admin/reports/finding-ids"+(l?`?after=${encodeURIComponent(l)}`:""));a.throwIfAborted();for(let m of h.reports)await we(m,{lookup:i,triage:c,matched:r,findings:s,api:n,signal:a});l=h.nextCursor}while(l);return a.throwIfAborted(),{matched:r.size,localFindings:i.size,findings:s,skipped:o}}function be(t,p){if(customElements.get("managed-admin-import"))return;class n extends t{static styles=[R(F),R(J)];static properties={localDeps:{attribute:!1},_busy:{state:!0},_error:{state:!0},_message:{state:!0},_plan:{state:!0},_catalog:{state:!0},_localOpen:{state:!0},_workspaces:{state:!0},_localId:{state:!0},_triage:{state:!0},_repo:{state:!0},_drag:{state:!0}};constructor(){super(),this._busy=!1,this._error="",this._message="",this._plan=null,this._catalog=null,this._workspaces=[],this._localOpen=!1,this._localId="",this._triage="",this._repo=null,this._files=[],this._drag=!1,this._local=!1,this._over=e=>{e.dataTransfer?.types?.includes("Files")&&(e.preventDefault(),this._drag=!0)},this._drop=e=>{e.dataTransfer?.types?.includes("Files")&&(e.preventDefault(),e.stopPropagation(),this._drag=!1,this._busy||(this._files.push(...e.dataTransfer.files),this._nextFile()))},this._localChanged=()=>{this._workspaces=[],this._localId="",!this._unlocking&&(this._local&&(this._plan=null),(this._local||this._importingTriage||this._importingContent||this._comparingTriage)&&(this._operation?.abort(),this._message="",this._error=this._comparingTriage?"Local data changed or was locked. Compare triage again to continue.":this._importingContent?"Local data changed or was locked. Choose files again to continue.":this._importingTriage?"Local data changed or was locked. Import triage again to continue.":"Local data changed or was locked. Choose the workspace again."))},this._blur=()=>{this._readingLocal&&this._localChanged()}}connectedCallback(){super.connectedCallback(),this.addEventListener("dragover",this._over),this.addEventListener("drop",this._drop),globalThis.addEventListener("blur",this._blur),globalThis.addEventListener("storage",this._localChanged),this._offVault=this.localDeps?.onVaultStateChange(this._localChanged),this._loadCatalog()}disconnectedCallback(){this._operation?.abort(),this._offVault?.(),this._plan=null,this._files=[],this.removeEventListener("dragover",this._over),this.removeEventListener("drop",this._drop),globalThis.removeEventListener("blur",this._blur),globalThis.removeEventListener("storage",this._localChanged),super.disconnectedCallback()}updated(e){e.has("session")&&(this._role!=="admin"||e.get("session")?.id!==this.session?.id)&&(this._operation?.abort(),this._plan=null,this._files=[])}async _action(e){if(this._busy||this._role!=="admin")return;let i=this._operation=new AbortController,o=AbortSignal.any([i.signal,this.appState.sessionController.signal]);this._busy=!0,this._error="";try{await e(o),o.throwIfAborted()}catch(c){o.aborted||(this._error=String(c?.message??c))}finally{this._operation===i&&(this._busy=!1)}}async _loadCatalog(){if(this._role==="admin")try{await this._loadCollection("workspace-import:catalog","import options",async e=>{let i=$(p,this.session,e),[o,c,s,r]=await Promise.all([i.send("/api/admin/reports"),i.send("/api/admin/teams"),i.send("/api/admin/bundles"),i.send("/api/admin/repositories/aliases")]);return{repos:o.repos,teams:c.teams,bundles:s.bundles,aliases:r.aliases}},e=>{this._catalog=e})}catch(e){this._error=String(e?.message??e)}}_browse(){let e=document.createElement("input");e.type="file",e.multiple=!0,e.accept=".enc,.gz,.json",e.addEventListener("change",()=>{this._files.push(...e.files),this._nextFile()},{once:!0}),e.click()}async _prepare(e,i){if(!e)return;if(this._catalog||await this._loadCatalog(),i.throwIfAborted(),!this._catalog)throw new Error("Could not load repositories. Try again.");let o=await q(e,this._catalog.repos,this._catalog.aliases);i.throwIfAborted();let c=new Set(this._catalog.teams.map(h=>h.name)),s=o.name||"Imported workspace",r=2;for(;c.has(o.name);){let h=` (${r++})`;o.name=s.slice(0,100-h.length)+h}let l=new Set(o.reports.map(h=>h.repoId).filter(h=>h!=null));this._repo=l.size===1?[...l][0]:null,this._triage=Object.keys(o.triage).length>0?"":"skip",this._plan=o,this._message=""}async _nextFile(){if(this._files.length===0||this._busy)return;let e=this._files.shift();this._local=!1,this._plan=null,await this._action(async i=>{let o=await V(e,this.promptPassword);i.throwIfAborted(),await this._prepare(o,i)})}async _unlock(e,i){this._unlocking=!0;try{return!e.locked||await e.unlock({signal:i})}finally{this._unlocking=!1}}async _chooseLocal(){this._localOpen=!0,await this._action(async e=>{let i=L(this.localDeps);await this._unlock(i,e)&&(e.throwIfAborted(),this._workspaces=await i.list({signal:e}))})}async _readLocal(){if(!this._localId)return;let e=this._localId;this._local=!0,this._plan=null,await this._action(async i=>{let o=L(this.localDeps);if(await this._unlock(o,i)){this._readingLocal=!0;try{await this._prepare(await o.read(e,{signal:i}),i)}finally{this._readingLocal=!1}}})}async _import(){!this._plan||!this._triage||!this._csrf||(await this._action(async e=>{if(this._local&&L(this.localDeps).locked)throw new Error("Unlock local data and choose the workspace again.");let i=this._plan,o=["teams","reports","bundles","history","workspace-import","scan-sources","repo-impact"];try{let c=await this.appState.mutate(()=>Q(i,{api:$(p,this.session,e),session:this.session,defaultRepo:this._repo,includeTriage:this._triage==="include",resolveConflicts:this.resolveConflicts,signal:e,progress:s=>{this._message=s}}),o);this._catalog.teams.push(c),this._message=`Imported into ${c.name}.`,this._plan=null}finally{this.appState.invalidate(o),i.team&&this.dispatchEvent(new CustomEvent("managed-import-complete",{bubbles:!0,composed:!0}))}}),!this._plan&&!this._error&&await this._nextFile())}async _importLocalTriage(){this._csrf&&await this._action(async e=>{this._importingTriage=!0,this._message="";let i=new Set,o=["reports","history"];try{let c=D(this.localDeps);if(!await this._unlock(c,e))return;this._readingLocal=!0;let s;try{s=await c.read({signal:e})}finally{this._readingLocal=!1}let r=await X(s,{api:$(p,this.session,e),session:this.session,resolveConflicts:this.resolveConflicts,signal:e,importedIds:i,confirmImport:async l=>(await this.confirmTriageImport({...l,signal:e}))?.confirmed===!0});if(e.throwIfAborted(),r===null)return;this._message=r?`Imported triage for ${r} finding${r===1?"":"s"}.`:"No local triage matches findings in managed reports."}finally{this._importingTriage=!1,this.appState.invalidate(o),i.size>0&&this.dispatchEvent(new CustomEvent("managed-import-complete",{bubbles:!0,composed:!0}))}})}async _compareLocalTriage(){this._csrf&&await this._action(async e=>{this._comparingTriage=!0,this._message="";let i=this.localImportSource,o=i.subscribe(this._localChanged);try{if(!await this._unlock(i,e))return;e.throwIfAborted(),this._readingLocal=!0;let c=D(this.localDeps),s=await ie({source:i,signal:e,readTriage:()=>c.read({signal:e}),api:$(p,this.session,e),progress:r=>{this._message=r}});e.throwIfAborted(),this._message="",await this.showTriageComparison({comparison:s,signal:e})}finally{o(),this._readingLocal=!1,this._comparingTriage=!1,this._message=""}})}async _importLocalContent(e){this._csrf&&await this._action(async i=>{this._importingContent=!0,this._message="";let o=this.localImportSource,c=["reports","bundles","bundle-metadata","history","workspace-import","scan-sources","repo-impact"],s=new Set,r=o.subscribe(this._localChanged);try{if(!await this._unlock(o,i))return;i.throwIfAborted(),this._readingLocal=!0;let l=$(p,this.session,i),h=await re(e,{source:o,deps:this.localDeps,api:l,signal:i}),m=await this.confirmContentImport({plan:h,signal:i});if(i.throwIfAborted(),!m?.confirmed)return;let d=await oe(h,m.selected,{source:o,api:l,signal:i,imported:s,progress:f=>{this._message=f}});this._message=`Imported ${d} ${e}${d===1?"":"s"}.`}finally{r(),this._readingLocal=!1,this._importingContent=!1,this.appState.invalidate(c),s.size>0&&this.dispatchEvent(new CustomEvent("managed-import-complete",{bubbles:!0,composed:!0}))}})}render(){if(this._role!=="admin")return w;let e=this._plan,i=e?Object.keys(e.triage).length:0,o=new Set([...e?.references??[],...e?.bundles.map(r=>r.integrity)??[]]),c=(this._catalog?.bundles??[]).filter(r=>o.has(r.integrity)),s=e?.references.filter(r=>!e.bundles.some(l=>l.integrity===r)).length??0;return g`<div class="wrap" @dragleave="${()=>{this._drag=!1}}">${U("manage-import",this._role,this.allowShare)}<h1>Import</h1><section class="triage-import" aria-label="Import local files"><div class="actions"><button type="button" class="btn" ?disabled="${this._busy||!this._csrf}" @click="${()=>this._importLocalContent("bundle")}">Import bundles</button> <button type="button" class="btn" ?disabled="${this._busy||!this._csrf}" @click="${()=>this._importLocalContent("report")}">Import reports</button></div><p>Choose files from this browser, grouped by workspace. Import files without teams or triage.</p></section><section class="triage-import" aria-label="Local triage"><div class="actions"><button type="button" class="btn" ?disabled="${this._busy||!this._csrf}" @click="${()=>this._importLocalTriage()}">Import triage</button> <button type="button" class="btn" ?disabled="${this._busy||!this._csrf}" @click="${()=>this._compareLocalTriage()}">Compare triage</button></div><p>Import saved triage and comments for findings already in managed reports.<br>Unmatched data stays in this browser.<br>Conflicting values prompt for resolution; per-report ignores are skipped.</p></section><h2>Import workspace</h2><p class="intro ui-hint">Create a new team from a workspace export or a workspace stored in this browser.</p><section class="${`workspace-drop ${this._drag?"dragging":""}`}" aria-label="Workspace files"><strong>Drop workspace files here</strong><span>Encrypted exports, JSON, or compressed JSON. Encrypted files prompt for a password.</span><div class="actions"><button type="button" class="btn" ?disabled="${this._busy||!this._catalog}" @click="${()=>this._browse()}">Choose files</button> <button type="button" class="btn" ?disabled="${this._busy}" @click="${()=>this._chooseLocal()}">Choose local workspace</button></div></section>${this._localOpen?g`<section class="local-choice"><label for="local-workspace">Local workspace</label> <select id="local-workspace" .value="${this._localId}" ?disabled="${this._busy}" @change="${r=>{this._localId=r.target.value}}"><option value="">Choose a workspace…</option>${this._workspaces.map(r=>g`<option value="${r.id}">${r.name}</option>`)}</select> <button type="button" class="btn" ?disabled="${this._busy||!this._localId}" @click="${()=>this._readLocal()}">Select workspace</button> ${!this._busy&&this._workspaces.length===0?g`<p class="ui-hint">No unlocked local workspaces. Choose local workspace to unlock or refresh.</p>`:w}</section>`:w} ${e?g`<section class="import-preview" aria-label="Import options">${e.team?g`<p>Team ${e.team.name} has been created. Retry continues its remaining import steps.</p>`:w} <label for="import-team">New team name</label><input id="import-team" maxlength="100" .value="${e.name}" ?disabled="${this._busy||!!e.team}" @input="${r=>{e.name=r.target.value,this.requestUpdate()}}"><p>${e.reports.length} reports / links · ${o.size} source bundles · ${i} triaged findings</p><label for="import-repo">Repository for files and source bundles without an active repository</label> <select id="import-repo" .value="${String(this._repo??"")}" ?disabled="${this._busy||!!e.team}" @change="${r=>{this._repo=r.target.value?Number(r.target.value):null}}"><option value="" ?selected="${this._repo==null}">Choose a repository…</option>${(this._catalog?.repos??[]).map(r=>g`<option value="${String(r.repoId)}" ?selected="${this._repo===r.repoId}">${r.fullName}</option>`)}</select><p>Declared report repositories and directories are preserved. Stored reports without an active repository use the selected repository. The new team receives those repository paths; other published reports in the same paths are also visible to that team.</p><ul>${e.reports.map(r=>g`<li>${r.name}<span>${r.links?"Global deduplication \u2014 enabled for all teams":r.github??"Uses selected repository"}${r.links||r.github==null||r.repoId!=null?"":r.embedded?" \u2014 connect this repository first":" \u2014 not connected; uses selected repository"}</span></li>`)}</ul>${c.length>0?g`<p>Existing source bundles in active repositories keep their locations. The new team also receives access to those directories. Unassigned bundles and bundles in inactive repositories use the selected repository.</p><ul>${c.map(r=>g`<li>${r.filename}<span>${r.repoFullName?`${r.repoFullName}${r.repoDirectory?`/${r.repoDirectory}`:""}`:"Uses selected repository"}</span></li>`)}</ul>`:w} ${s?g`<p>${s} referenced source bundles have no bytes in this export. Reports can use matching bundles already on the server.</p>`:w} ${i?g`<fieldset ?disabled="${this._busy||!!e.team}"><legend>Import triage?</legend><label><input type="radio" name="import-triage" value="include" ?checked="${this._triage==="include"}" @change="${()=>{this._triage="include"}}"> Include triage and comments</label> <label><input type="radio" name="import-triage" value="skip" ?checked="${this._triage==="skip"}" @change="${()=>{this._triage="skip"}}"> Skip triage</label><p>Conflicting values prompt for resolution. Triage stays shared by finding ID across teams. Per-report local ignores are not imported.</p></fieldset>`:w} <button type="button" class="btn primary" ?disabled="${this._busy||!this._triage||!this._csrf}" @click="${()=>this._import()}">${this._busy?"Importing\u2026":e.team?"Retry remaining import":"Import workspace"}</button></section>`:w} ${this._message?g`<p role="status">${this._message}</p>`:w} ${this._error?g`<p class="error" role="alert">${this._error}${this._catalog?w:g`<button class="btn" @click="${()=>this._loadCatalog()}">Retry</button>`}</p>`:w} ${this._files.length>0&&!this._busy?g`<button class="btn" @click="${()=>this._nextFile()}">Next workspace file (${this._files.length} waiting)</button>`:w}</div>`}}customElements.define("managed-admin-import",n)}export{be as registerWorkspaceImport};
|